feat(tui): flash banner for blocked actions + Shift+R clone & rerun#11
feat(tui): flash banner for blocked actions + Shift+R clone & rerun#11superbusinesstools wants to merge 2 commits intooxgeneral:mainfrom
Conversation
Pressing R on a done/failed/cancelled task previously did nothing visible — the block message was buried in the activity feed. Adds a transient flash banner above the command bar so blocked actions produce unmissable feedback, and introduces Shift+R to clone a terminal task into a fresh todo and dispatch it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Really nice PR — the reasoning for cloning vs a Two should-fixes and a couple of nits. Nothing blocking. 🟡 Should-fix 1 — shallow-copy aliasing in
|
|
One more follow-up from a second pass — mostly architectural, not blockers: Flash banner duplicates
|
…rror clarity, flash→toast - task-service: spread review_criteria, scope, and depends_on arrays in clone() to prevent shared-reference mutation between clone and source - tui.ts: wrap runTask in try/catch and attach `cloned` to dispatch errors so App can distinguish "clone failed" from "cloned but dispatch failed" - App.tsx: replace parallel flash state with showInfoToast() routed through the existing ToastBanner queue; fixes duplicate addMessage+flash on blocked R; Shift+R error handler now shows accurate "dispatch failed" vs "clone failed" messages - ToastBanner: add 'info' type (amber, 4s) with optional message override field so info toasts can carry arbitrary text alongside the existing done/failed/review types Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
Fixes two related TUI papercuts around the R (run) action:
Ron a done/failed/cancelled task did add a "Cannot run — status is done" message, but it went into the activity feed (bottom-right, high-frequency scroll, filter-dependent) where it was effectively invisible. Users would press R repeatedly and see nothing happen.doneas terminal — nodone → todotransition exists, andorch task retryonly handlesfailed/cancelled. There was no TUI path to run a completed task again.Changes
src/tui/App.tsx): transient 4s, bold, colored banner rendered directly above the command bar. Triggered on blockedr, and on clone start/success/failure. Impossible to miss — sits where your eyes already are after pressing a key.TaskService.clone()method copies title, description, priority, assignee, labels, goalId, workspace_mode, review_criteria, scope, and max_attempts into a freshtodotask (attempts reset to 0). A newonCloneTaskcallback wires it through the TUI and dispatches the clone via the orchestrator. Works on any task status, including terminal ones — history of the original task is preserved.rkeeps its existing run-only behavior; when blocked it now flashes the reason and hintspress Shift+R to clone & rerun.Why clone instead of allowing
done → todo?Mutating a done task in place would destroy its history (stats, timestamps, prior attempts) and contradict the state machine's
terminal-status invariant. Cloning is auditable, reversible, and matches how most task systems handle "run it again."
Test plan
npm run typecheck— cleannpm test -- test/unit/application/task-service.test.ts— 28 passed (2 newclonetests)main, no regressionsorch tui, pressron a done task → yellow flash with Shift+R hintShift+Ron a done task → amber "Cloning…" then green "Cloned & dispatched"; new todo appears and gets picked upron a todo task → existing run behavior still works