jobs: Stop now cancels queued jobs; add remove/stop button on list rows

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-23 16:14:49 +00:00
co-authored by Claude Opus 4.8
parent a4b56a3b6e
commit c5d79085cb
3 changed files with 59 additions and 27 deletions
@@ -288,6 +288,17 @@ export function stopJob(jobId: string): boolean {
return true;
}
// Stop a running job (cooperative abort) OR cancel a queued one (mark stopped so it won't promote).
export async function requestStop(jobId: string): Promise<'stopped' | 'cancelled' | 'noop'> {
if (stopJob(jobId)) return 'stopped';
const job = await getPipelineJob(jobId);
if (job && job.status === 'pending') {
await updatePipelineJob(jobId, { status: 'stopped', completedAt: new Date() });
return 'cancelled';
}
return 'noop';
}
export function isJobLive(jobId: string): boolean {
return liveJobs.has(jobId);
}
@@ -98,13 +98,13 @@ pipelineJobsRouter.get('/:id/log', async (c) => {
}
});
// POST /:id/stop — request cancellation (cooperative abort).
// POST /:id/stop — stop a running job or cancel a queued one.
pipelineJobsRouter.post('/:id/stop', async (c) => {
const user = c.get('user');
const job = await getPipelineJob(c.req.param('id'));
if (!job || job.userId !== user.id) return c.json({ error: 'Not found' }, 404);
const stopped = jobManager.stopJob(job.id);
return c.json({ ok: true, wasLive: stopped });
const result = await jobManager.requestStop(job.id);
return c.json({ ok: true, result });
});
// GET /:id — single job detail (full row).