build: approve better-sqlite3 install script (npm install-scripts policy)
npm >=11 on node 24 skips non-approved dependency install scripts, so fresh clones/worktrees never build the better-sqlite3 native bindings and every build fails with "Could not locate the bindings file". Approving it in package.json makes the approval travel with the repo. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
4ca532b873
commit
4ea12b1299
@@ -38,5 +38,8 @@
|
||||
"node-fetch": "^3.3.2",
|
||||
"web-push": "^3.6.7",
|
||||
"youtube-transcript": "^1.3.1"
|
||||
},
|
||||
"allowScripts": {
|
||||
"better-sqlite3@12.9.0": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
import { getDisplayJobProgress, getJobStatusColor, getJobStatusLabel, isTerminalJobStatus } from '$lib/job-progress.js';
|
||||
import SourceIcon from '$lib/components/SourceIcon.svelte';
|
||||
import Waveform from '$lib/components/Waveform.svelte';
|
||||
import JobErrorLine from '$lib/components/JobErrorLine.svelte';
|
||||
import { accent } from '$lib/accent.js';
|
||||
|
||||
const ACCENT = $derived($accent.value);
|
||||
@@ -34,27 +33,23 @@
|
||||
loading = false;
|
||||
});
|
||||
|
||||
async function deleteJobById(jobId: string) {
|
||||
const job = jobs.find((j) => j.id === jobId);
|
||||
if (!job) return;
|
||||
if (!confirm(`Delete "${job.title || job.id}"?`)) return;
|
||||
const res = await fetch(`/api/jobs/${jobId}`, { method: 'DELETE' });
|
||||
if (res.ok) jobs = jobs.filter((j) => j.id !== jobId);
|
||||
}
|
||||
|
||||
async function deleteJob(e: MouseEvent, job: Job) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
await deleteJobById(job.id);
|
||||
if (!confirm(`Delete "${job.title || job.id}"?`)) return;
|
||||
const res = await fetch(`/api/jobs/${job.id}`, { method: 'DELETE' });
|
||||
if (res.ok) jobs = jobs.filter((j) => j.id !== job.id);
|
||||
}
|
||||
|
||||
async function retryJobById(jobId: string) {
|
||||
const res = await fetch(`/api/jobs/${jobId}/retry`, { method: 'POST' });
|
||||
async function retryJob(e: MouseEvent, job: Job) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const res = await fetch(`/api/jobs/${job.id}/retry`, { method: 'POST' });
|
||||
if (res.ok) {
|
||||
const updated = await fetch(`/api/jobs/${jobId}`);
|
||||
const updated = await fetch(`/api/jobs/${job.id}`);
|
||||
if (updated.ok) {
|
||||
const j = await updated.json();
|
||||
jobs = jobs.map((x) => (x.id === jobId ? j : x));
|
||||
jobs = jobs.map((x) => (x.id === job.id ? j : x));
|
||||
}
|
||||
} else {
|
||||
const body = await res.json().catch(() => ({}));
|
||||
@@ -104,16 +99,12 @@
|
||||
<span>·</span>
|
||||
<span>{job.audioMode}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{#if ['failed', 'cancelled'].includes(job.status)}
|
||||
<JobErrorLine
|
||||
{job}
|
||||
accentColor={ACCENT}
|
||||
onRetry={retryJobById}
|
||||
onDelete={deleteJobById}
|
||||
/>
|
||||
{#if ['failed', 'cancelled'].includes(job.status) && job.error}
|
||||
<span>·</span>
|
||||
<span class="job-err-inline" title={job.error}>{job.error}</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if !isTerminalJobStatus(job.status)}
|
||||
<div class="job-wave">
|
||||
@@ -129,11 +120,27 @@
|
||||
<div class="job-pct mono" style="color: {ACCENT}">
|
||||
{getDisplayJobProgress(job, { hasTranscript: Boolean(job.segmentsJson) })}%
|
||||
</div>
|
||||
{:else}
|
||||
<div class="job-pct mono" style="color: {getJobStatusColor(job.status)}">
|
||||
{getJobStatusLabel(job.status)}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Row actions (hover-revealed, delete for done jobs) -->
|
||||
<!-- Retry slot (always visible) -->
|
||||
{#if ['failed', 'cancelled'].includes(job.status)}
|
||||
<div class="row-retry-slot">
|
||||
<button
|
||||
class="row-btn accent"
|
||||
onclick={(e) => retryJob(e, job)}
|
||||
aria-label="Retry"
|
||||
title="Retry"
|
||||
>↺</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Row actions (hover-revealed, delete only) -->
|
||||
<div class="row-actions">
|
||||
{#if job.status === 'done'}
|
||||
{#if isTerminalJobStatus(job.status)}
|
||||
<button
|
||||
class="row-btn danger"
|
||||
onclick={(e) => deleteJob(e, job)}
|
||||
@@ -191,64 +198,7 @@
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.job-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
padding: 16px 20px;
|
||||
text-decoration: none;
|
||||
color: var(--text);
|
||||
transition: background 0.15s;
|
||||
}
|
||||
|
||||
.job-row:hover {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
.job-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.job-name {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.job-meta {
|
||||
font-size: 11.5px;
|
||||
color: var(--text-muted);
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.job-wave {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.job-pct {
|
||||
font-size: 12.5px;
|
||||
font-weight: 600;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.row-actions {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
flex-shrink: 0;
|
||||
opacity: 0;
|
||||
transition: opacity 0.15s;
|
||||
}
|
||||
|
||||
.job-row:hover .row-actions {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
…[rtk: elided 73 of 313 lines]…
|
||||
.job-row[data-status="failed"] .job-name {
|
||||
color: var(--error-text);
|
||||
}
|
||||
@@ -274,6 +224,14 @@
|
||||
.row-btn.danger:hover {
|
||||
background: rgba(255, 90, 90, 0.2);
|
||||
}
|
||||
.row-btn.accent {
|
||||
border-color: color-mix(in oklab, var(--accent) 40%, transparent);
|
||||
background: color-mix(in oklab, var(--accent) 10%, transparent);
|
||||
color: var(--accent);
|
||||
}
|
||||
.row-btn.accent:hover {
|
||||
background: color-mix(in oklab, var(--accent) 20%, transparent);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.page {
|
||||
|
||||
Reference in New Issue
Block a user