fix(workflows): prompt for confirmation before quitting with active runs - #1381
fix(workflows): prompt for confirmation before quitting with active runs#1381flora131 wants to merge 9 commits into
Conversation
Add a cancellable session_before_shutdown lifecycle event for interactive quit requests and use it from workflows to show a cancel-default quit confirmation when runs are still in flight. Also route graph q kills through the shared destructive confirmation path, harden custom overlay failure handling, and expand lifecycle/TUI coverage. AI-Assisted-By: GPT-5.5 # Conflicts: # packages/workflows/CHANGELOG.md
Implementation NotesTask: compleete issue #1378 Running Notes
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
Review:
|
…uit-confirm # Conflicts: # packages/coding-agent/docs/extensions.md # packages/coding-agent/src/core/extensions/loader.ts # packages/coding-agent/src/core/extensions/runner.ts # packages/coding-agent/src/core/extensions/types.ts # packages/coding-agent/src/index.ts # packages/coding-agent/src/modes/interactive/interactive-mode.ts # packages/coding-agent/test/extensions-runner.test.ts # packages/workflows/src/extension/index.ts # packages/workflows/src/tui/graph-view.ts # packages/workflows/src/tui/workflow-attach-pane.ts # test/integration/overlay-entrypoints.test.ts # test/unit/overlay-graph.test.ts # test/unit/workflow-attach-pane.test.ts
Review:
|
Review:
|
Mark workflow-created sessions as internal so standard resume history excludes them while workflow resume can still reopen them. Polish the active-workflow quit confirmation UI, host theme handling, footer labels, and regression coverage. Assistant-model: GPT-5.5
…uit-confirm # Conflicts: # packages/workflows/CHANGELOG.md # packages/workflows/src/tui/graph-view-input.ts # packages/workflows/src/tui/graph-view-types.ts # packages/workflows/src/tui/overlay-adapter.ts # packages/workflows/src/tui/workflow-attach-pane-types.ts # test/integration/overlay-entrypoints-hide-keys.test.ts # test/unit/workflow-attach-pane-09.test.ts
Review: fix(workflows): confirm quit with active runsThorough, well-tested change. The cancellable Bugs / behavior worth confirming
Tests
Minor / nits
Style / conventions
Overall: solid, mergeable once the double-Ctrl+C behavior in (1) is confirmed intentional. 🤖 Automated review — flag anything that misreads intent. |
PR Review:
|
…uit-confirm # Conflicts: # packages/coding-agent/CHANGELOG.md # packages/workflows/CHANGELOG.md # packages/workflows/src/tui/workflow-attach-pane.ts
Code Review — PR #1381
|
Exclude graph-quit resumable workflow runs from the app shutdown blocker check while preserving their unfinished state for resume/restart behavior. Add regression coverage and the manual TUI validation report for the exit-confirmation flow. Assistant-model: GPT-5.5
Review:
|
Assistant-model: GPT-5.5
|
PR Review: fix(workflows): confirm quit with active runs Thorough, well-tested change. The core design — a cancellable session_before_shutdown lifecycle event fired only on interactive quit and bypassed on signal exits — is clean, and the separation between core (coding-agent) and the workflows extension is correct. Docs, changelog (both packages), and the lifecycle diagram are all updated, files stay under the 500-line gate, and test coverage is genuinely strong (unit + integration + regression + manual E2E). Nice work. I reviewed the full diff against CLAUDE.md conventions. A few notes, mostly minor. Correctness — looks solid
Minor: dead field Consistency observation: inFlightRunCount vs blocksAppShutdown Nit: settle() duplication Tests Overall: approve-leaning. The dead confirm? field and the inFlightRunCount consistency note are the only items I would ask you to address or explicitly defer. |
|
Closing and deleting this exit confirmation feature branch/worktree per request. |
Summary
Introduces a cancellable
session_before_shutdownextension lifecycle event and wires the workflows extension to show a default-cancel confirmation dialog before killing active runs on interactive quit. Also fixes a bug where graph-quit resumable runs were incorrectly counted as active blockers, causing a spurious confirmation on a subsequent `/quit`.Closes #1378
Changes
Core: cancellable pre-shutdown lifecycle hook
SessionBeforeShutdownEvent/SessionBeforeShutdownResulttypes and thesession_before_shutdownextension event, fired only on interactive quit (Ctrl+C / Ctrl+D //quit//exit), not onSIGHUP/SIGTERMsignal exits.emitSessionBeforeShutdownEventhelper fromExtensionRunnerand wired it intoInteractiveModeBase.shutdown()so extensions can cancel quit before UI/runtime teardown begins.shutdownConfirmationPendingguard to suppress duplicate pre-shutdown prompts while one is already in progress, withtry/finallycleanup so a thrown handler always releases the guard.Workflows extension: quit confirmation UI
openWorkflowQuitConfirm()overlay showing a"Quit with active workflows?"dialog with in-flight run count, stage progress, oldest run elapsed time, and run names. Cancel is focused by default.blocksAppShutdownpredicate that correctly excludes graph-quit/resumable paused runs (paused+resumable+exitReason=quit+ noendedAt) from the active-blocker count — fixing the spurious confirmation bug after graphq.session_before_shutdownhandler: skips when no runs are in flight, fails open (undefined) in headless or degraded-UI contexts so automation cannot wedge on a prompt, and cancels quit with an info notification when the user declines.openKillConfirm(graphq) now routes throughopenWorkflowQuitConfirm's shared confirmation path: the graph pane stays open until the kill is confirmed, then closes — no speculative close onq.Graph view fixes
GraphViewqno longer closes the pane speculatively: firesonQuitfor live runs and lets the host close after confirmation; falls through (return false) when there is no live run so the outer overlay can handleq.handleKillConfirmInputalongside Escape.Overlay hardening
observeCustomMount()helper so custom UI hosts that reject or never invoke the factory settle the confirmation promise safely instead of hanging.openKillConfirmrefactored to use the samesettle()guard pattern, eliminating an earlier race wheredisposecould double-resolve.Tests
packages/coding-agent/test/extensions-runner/session-shutdown.suite.ts: cancellation and no-handler cases foremitSessionBeforeShutdownEvent.packages/coding-agent/test/suite/regressions/5080-signal-shutdown-extension-cleanup.test.ts: cancelled shutdown clearsshutdownRequested, duplicate confirmation suppression, failed handler guard release.test/unit/extension.test.ts: quit confirm with active workflows cancels by default; headless /hasUI: falsefail-open; confirmed quit path.test/unit/extension-shutdown.test.ts:session_before_shutdowndoes not prompt for graph-quit resumable runs; prompts and allows cancellation for genuinely active runs.test/unit/workflow-attach-pane-09.test.ts:qdoes not close before host confirms kill;qcloses/falls through for completed runs.test/unit/session-confirm-list.test.ts:renderWorkflowQuitConfirmdefault-cancel rendering; fail-open when custom UI rejects or never mounts; Ctrl+C cancel variants.test/unit/session-overlays.test.ts: quit confirm overlay cancel/confirm flows, notification on cancel.test/integration/overlay-entrypoints.test.ts:qon a real custom mount mounts the confirmation overlay first, then kills ony.Breaking changes
None. The new
session_before_shutdownevent is opt-in for extensions; existing extension code is unaffected.Validation
273 pass, 0 fail).AGENT=1 bun run typecheckpassed.bun run lintandbun run test:unitsuccessfully.exit-confirmation-manual-test-report.md).