Phase 3: pausable command lifecycle (pause / resume / cancel)#2732
Phase 3: pausable command lifecycle (pause / resume / cancel)#2732aboimpinto wants to merge 62 commits into
Conversation
…d, clear on turn end
…nel, works during active turns)
…ing...' initially
…ssage flow through as normal user message
… non-'continue' messages
…the user retypes fresh
…s model from trying alternatives)
…ally stops the turn
…of separate line)
…roke); other messages cancel + consume
…tale 100% from previous command)
…ded (pausable/paused flags extend the cancel window)
… prevent 'Command resumed' event overriding cancel status
… sync in dispatch_user_message; direct flag clear in cancel path
… app.pausable is true (new pausable command after cancel)
…x mock engine handle missing shared_paused
…Paused / Request was Resumed / Request was Cancelled
…ds race where late engine status overwrites cancel/resume; add guard in Event::Status handler; update test to verify guard
…in next turn; add test
…prompted to continue the goal
…stead of continuing
… manual_pattern_char_comparison, unnecessary_cast)
aboimpinto
left a comment
There was a problem hiding this comment.
All clippy warnings resolved (collapsible_if, unnecessary_map_or, manual_pattern_char_comparison, unnecessary_cast in shell.rs). The git stash snapshot mechanism is acknowledged as a best-effort prototype with known limitations (no restore, sync call). Resume detection was hardened with word-boundary checks (contains " continue "). Manual lock handling in CancelRequest uses direct flag set to avoid Op race. The try_lock for todos/plan clearing is best-effort (logs and continues on failure).
…ore on explicit resume
|
this is such a smart update @aboimpinto - wow. thank you for your time and effort! |
|
@Hmbown almost finished ... |
…mark on pause-cancelled turns
There was a problem hiding this comment.
aboimpinto has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.
…andles model intent
There was a problem hiding this comment.
aboimpinto has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.
…sed) like dispatch_user_message
There was a problem hiding this comment.
aboimpinto has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
aboimpinto has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.
…and-mvp Harvest pausable custom command MVP from #2732
|
Thanks @aboimpinto for the thoughtful lifecycle work here. We landed the safe pausable-command MVP as #2803, merged in The slice that landed keeps I am closing this PR as superseded by #2803 so the release train can keep moving, but the broader hook-layer lifecycle intent is still useful future work. Thanks again for pushing this direction forward. |
Harvested from PR Hmbown#2732 by @aboimpinto. Parse pausable frontmatter for custom slash commands, add a narrow engine pause gate before tool execution, and preserve paused command state across separate messages until explicit resume, cancel, terminal completion, or a new command. Also centralize strict resume-message detection with negative coverage for deferred or negated phrases, and keep rollback/stash/worktree mutation behavior out of this slice. Co-authored-by: aboimpinto <1231687+aboimpinto@users.noreply.github.com>
Phase 3 — Pausable Command Lifecycle (Pause / Resume / Cancel)
This PR builds on the custom slash command frontmatter from Phase 1 (PR #2326) and the hook gate from Phase 2. It adds
pausable: truelifecycle support for custom slash commands: pause with ESC, type other messages while paused, resume with "continue"/"resume", and cancel with ESC twice.Architecture
Model behavior is handled by centralized LLM evaluation. A single
add_paused_evaluation_note()helper appends an evaluation note to every message sent while a paused command exists. The LLM reads the note and decides whether to continue the paused command based on the user's message — no fragile keyword matching for model decisions.UI icon state uses minimal keyword detection in one place.
submit_or_steer_messagedetects "continue"/"resume" to consume thepaused_quarryso the WorkBench icon changes from⏸to▶and the checkmark✓appears on completion. This is a pure UI concern — the model behavior is driven entirely by the LLM note.add_paused_evaluation_note()(centralized)dispatch_user_messagesteer_user_messagesubmit_or_steer_messageWhat It Does
Frontmatter
pausable: truein~/.codewhale/commands/<name>.mdenables the pause lifecycle.Pause / Resume / Cancel
pausablecommand. A sharedArc<Mutex<bool>>flag blocks all further tool calls at the engine's pause gate (turn loop).⏸(viapaused_quarry) so the user remembers the paused command.submit_or_steer_messageconsumespaused_quarry(icon changes to▶). The LLM evaluation note is still appended so the model understands the intent.WorkBench lifecycle indicators
▶Play — command is running (yellow)⏳Pausing — transitioning to paused (tools still draining)⏸Paused — command is on hold, waiting for resume or cancel✘Cancelled — command was cancelled by the user✓Finished — command completed successfully (green, viaHuntVerdict::Hunted)Files Changed
How to Test
Create
~/.codewhale/commands/<name>.mdwithpausable: truein the frontmatter.To cancel: while paused, press ESC again → WorkBench shows ✘
Test Results
Issue Alignment
Builds On
Paulo Aboim Pinto