fix pipeline stop, jobs link navigation, and seed quote stripping

- Fix stop: abort poll now rejects the promise after killing the agent process
- Fix jobs link: close modal before navigating, use react-router navigate
- Fix seed parser: strip quotes from step input values (delete_source: "true")

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-10 05:32:35 +00:00
co-authored by Claude Opus 4.6
parent 53c78c76cb
commit ef6402a827
3 changed files with 11 additions and 12 deletions
+2 -1
View File
@@ -140,7 +140,8 @@ function parseFrontmatter(content: string) {
// Step input entries (6 spaces) // Step input entries (6 spaces)
const inputMatch = line.match(/^\s{6}(\w[\w_-]*):\s*(.+)$/); const inputMatch = line.match(/^\s{6}(\w[\w_-]*):\s*(.+)$/);
if (inputMatch && inInputs) { if (inputMatch && inInputs) {
stepInputs[inputMatch[1]!] = inputMatch[2]!.trim(); const raw = inputMatch[2]!.trim();
stepInputs[inputMatch[1]!] = raw.replace(/^["'](.*)["']$/, '$1');
} }
} }
if (currentStep) { if (currentStep) {
+3 -7
View File
@@ -124,9 +124,10 @@ async function runAgenticStep({ userId, email, username, role, taskDirName, prom
// Poll for abort signal to kill the running agent // Poll for abort signal to kill the running agent
const abortPoll = setInterval(() => { const abortPoll = setInterval(() => {
if (abortSignal.aborted && cleanup) { if (abortSignal.aborted) {
clearInterval(abortPoll); clearInterval(abortPoll);
cleanup(); cleanup?.();
reject(new Error('Pipeline was stopped'));
} }
}, 500); }, 500);
@@ -157,11 +158,6 @@ async function runAgenticStep({ userId, email, username, role, taskDirName, prom
sidecar.sendPiPrompt(sessionId, prompt, randomUUID()); sidecar.sendPiPrompt(sessionId, prompt, randomUUID());
} }
// If already aborted while setting up, kill immediately
if (abortSignal.aborted) {
clearInterval(abortPoll);
cleanup?.();
}
} catch (err) { } catch (err) {
clearInterval(abortPoll); clearInterval(abortPoll);
cleanup?.(); cleanup?.();
@@ -1,4 +1,5 @@
import { useState, useEffect, useRef } from 'react'; import { useState, useEffect, useRef } from 'react';
import { useNavigate } from 'react-router';
import { X, Play, Square, CircleCheck, CircleX, Copy, Check, Loader2, AlertCircle, ExternalLink } from 'lucide-react'; import { X, Play, Square, CircleCheck, CircleX, Copy, Check, Loader2, AlertCircle, ExternalLink } from 'lucide-react';
import { Dialog, DialogOverlay, DialogPortal } from '@/components/ui/dialog'; import { Dialog, DialogOverlay, DialogPortal } from '@/components/ui/dialog';
import * as DialogPrimitive from '@radix-ui/react-dialog'; import * as DialogPrimitive from '@radix-ui/react-dialog';
@@ -697,13 +698,13 @@ const PipelineRunner = ({ taskDirName, context, cwd }: PipelineRunnerProps) => {
</span> </span>
)} )}
{pipeline.jobId && ( {pipeline.jobId && (
<a <button
href={`/jobs/${pipeline.jobId}`} onClick={() => { onOpenChange(false); navigate(`/jobs/${pipeline.jobId}`); }}
className="flex items-center gap-1.5 text-xs text-duck-teal hover:text-duck-teal/80 transition-colors mt-1" className="flex items-center gap-1.5 text-xs text-duck-teal hover:text-duck-teal/80 transition-colors mt-1 cursor-pointer"
> >
<ExternalLink className="h-3 w-3" /> <ExternalLink className="h-3 w-3" />
View in Jobs View in Jobs
</a> </button>
)} )}
</div> </div>
</div> </div>
@@ -724,6 +725,7 @@ type TaskRunnerModalProps = {
}; };
export const TaskRunnerModal = ({ open, onOpenChange, task, entryName, entryFullPath, entryType, cwd = { path: '' }, promptOverride, description, sandboxed }: TaskRunnerModalProps) => { export const TaskRunnerModal = ({ open, onOpenChange, task, entryName, entryFullPath, entryType, cwd = { path: '' }, promptOverride, description, sandboxed }: TaskRunnerModalProps) => {
const navigate = useNavigate();
const { settings } = useSettings(); const { settings } = useSettings();
const taskSettings = settings.tasks; const taskSettings = settings.tasks;
const entryRef = entryFullPath ?? entryName; const entryRef = entryFullPath ?? entryName;