16 KiB
Created
Created by tickets.sh create.
Plan
Plan: implement after ticket-role-pod-launcher lands.
TUI should expose explicit user-triggered Ticket role actions/commands and call the shared launcher. It should not duplicate profile/config/prompt/workflow launch construction, introduce automatic scheduling, or add a spawned-Pod panel in this ticket.
Plan
Delegation intent: TUI Ticket role actions
Intent
Add explicit TUI commands/actions that launch fixed Ticket-role Pods through the shared client Ticket role launcher.
TUI should not duplicate role/profile/workflow/prompt construction. It should parse user commands, build a typed launcher context, call the client launcher, and surface success/failure diagnostics in the TUI.
Worktree / branch
- worktree:
/home/hare/Projects/yoi/.worktree/tui-ticket-role-actions - branch:
work/tui-ticket-role-actions
Dependencies
ticket-role-pod-launcher is complete and merged. Use the client API added there:
client::TicketRoleLaunchContextclient::TicketRefclient::launch_ticket_role_pod- related launch errors/result types
Requirements
- Add user-triggered TUI commands for fixed Ticket roles.
- Prefer a single
:ticket <action> ...command if it fits the current command parser. - Support at least these actions:
:ticket intake <context...>:ticket route <ticket-id-or-slug> [instruction...]:ticket investigate <ticket-id-or-slug> [instruction...]:ticket implement <ticket-id-or-slug> [instruction...]:ticket review <ticket-id-or-slug> [instruction...]
- Map actions to roles:
- intake ->
TicketRole::Intake - route ->
TicketRole::Orchestrator - investigate ->
TicketRole::Investigator - implement ->
TicketRole::Coder - review ->
TicketRole::Reviewer
- intake ->
- Use the shared launcher; do not build
SpawnConfig, Profile selectors, Workflow segments, or first-run prompt content directly in TUI. - Make command parsing/test behavior deterministic.
- Surface launcher failures as TUI command/actionbar diagnostics without crashing.
- Make
UnsupportedInheritProfileespecially clear: the user must configure a concrete role profile in.yoi/ticket.config.tomlfor top-level TUI launches. - Keep actions explicit and user-triggered; no scheduler/automation.
- Do not add spawned-Pod panel or dashboard redesign.
- Do not add arbitrary role registry UI.
Current code map
crates/tui/src/command.rs- Current command registry is synchronous and returns
CommandExecution { method: Option<Method>, diagnostics, ... }. - Existing commands are
help,noop,compact,rewind, andpeer. - Add a command action variant or equivalent so command parsing can request a Ticket role launch without overloading
protocol::Method.
- Current command registry is synchronous and returns
crates/tui/src/app.rssubmit_command/apply_command_executioncurrently returnOption<Method>.- May need a small result enum to carry either a Pod
Methodor a TUI-local action.
crates/tui/src/single_pod.rs- Has
PodRuntimeCommandat launch entrypoints, butrun_loopcurrently only receivesApp+PodClient. - To execute role launch commands, pass
PodRuntimeCommandinto the loop/handler where needed. - Command execution can call
client::launch_ticket_role_pod(...)asynchronously and then show success/error notice.
- Has
crates/client/src/ticket_role.rs- Shared launcher API; use this instead of duplicating launch construction.
Command semantics
MVP command syntax:
:ticket intake <context...>
:ticket route <ticket-id-or-slug> [instruction...]
:ticket investigate <ticket-id-or-slug> [instruction...]
:ticket implement <ticket-id-or-slug> [instruction...]
:ticket review <ticket-id-or-slug> [instruction...]
For non-intake actions, treat the first argument as a Ticket id/slug. It is acceptable to use TicketRef::slug(value) in the MVP unless a clear id/slug parser already exists.
For intake, allow freeform context and no Ticket id.
Pod name may use the launcher default unless command syntax for --name is easy; do not overbuild CLI parsing.
Non-goals
- Implementing the role launcher.
- Prompt resource resolution.
- Stateful workflow engine.
- Worktree creation automation.
- Multi-Pod dashboard redesign.
- Spawned-Pod panel.
- Scheduler/lease/queue automation.
- Generic role registry/UI.
- Arbitrary filesystem Ticket edits.
Validation
Run at least:
- focused command parsing/action tests;
cargo test -p tui ticket --libor relevant focused TUI tests;cargo test -p client ticket;cargo check --workspace --all-targets;cargo fmt --check;git diff --check;./tickets.sh doctor.
Run nix build .#yoi --no-link if feasible.
Completion report
Report:
- worktree path / branch;
- commit hash;
- command syntax implemented;
- how command execution calls the shared launcher;
- how diagnostics are surfaced;
- validation results;
- unresolved risks/follow-ups;
- whether ready for external review.
Review: approve
External review: tui-ticket-role-actions
1. Result: approve after blocker fix
Initial review requested changes because :ticket intake accepted missing context. Re-review of commit d288fa590188bb700257e3cfa386b168661d9613 confirms that blocker is resolved and no new blocker was introduced.
2. Summary of implementation
The commit adds a new :ticket <action> ... TUI command in crates/tui/src/command.rs, carries successful parses as a TUI-local CommandAction::TicketRole, stores the pending local action on App, and handles it from the single-Pod event loop in crates/tui/src/single_pod.rs.
Execution builds a TicketRoleLaunchContext with the current working directory, fixed TicketRole, optional TicketRef::slug(...), and optional freeform instruction, then calls client::launch_ticket_role_pod(...). The TUI does not construct SpawnConfig, profile selectors, workflow invocation segments, or prompt contents directly. crates/client/src/ticket_role.rs only reexports TicketRole for this TUI-facing use.
3. Requirement-by-requirement assessment
- Command syntax: Met after
d288fa590188bb700257e3cfa386b168661d9613. Implemented nested syntax close to the requested surface::ticket intake <context...>parses when context is present, and:ticket intake/ whitespace-only context now reject withInvalid arguments. Usage: ticket intake <context...>.:ticket route <ticket-id-or-slug> [instruction...],investigate,implement, andreviewrequire a first ticket reference and preserve remaining text as instruction.
- Role mapping: Met. Mappings are
intake -> Intake,route -> Orchestrator,investigate -> Investigator,implement -> Coder,review -> Reviewer. - Shared launcher use: Met.
single_pod.rsbuilds onlyTicketRoleLaunchContextand callslaunch_ticket_role_pod(...); no TUI-sideSpawnConfig, profile semantics, workflow segments, or prompt construction were introduced. - Command action plumbing locality: Met. The new
CommandActionpath is local, and existingcompact,rewind,peer, help, and completion behavior remains structurally unchanged. Fullcargo test -p tui --libalso passed. PodRuntimeCommandthreading: Met. The value is passed narrowly into the single-Pod run loop and command-action handler so the shared launcher can spawn the role Pod.- Diagnostics: Met for the reviewed command requirements. Success and failure are surfaced through actionbar notices,
UnsupportedInheritProfilegets a clear TUI-specific message, missing non-intake ticket references are diagnosed, and missing intake context is now diagnosed. - Unsupported inherit profile explanation: Met. The special-case message clearly tells the user to configure concrete role profiles in
.yoi/ticket.config.tomlfor top-level TUI ticket launches. - Non-goals / scope control: Met. I did not find scheduler/automation, spawned-Pod panel, dashboard redesign, generic role UI, prompt resolution, worktree automation, or arbitrary Ticket filesystem edits.
- Tests: Met for the blocker fix. Parsing and context construction tests exist, an inherit-profile diagnostic formatting test exists, and focused parser coverage now rejects missing/whitespace-only intake context. The launcher execution path is still covered indirectly by context construction rather than by a mocked launcher call/actionbar transition.
- Validation: Met for the commands I reran; see section 6.
4. Blockers
No blockers remain after d288fa590188bb700257e3cfa386b168661d9613.
- Resolved:
:ticket intakepreviously accepted an empty context; it now rejects missing or whitespace-only context withInvalid arguments. Usage: ticket intake <context...>, and focused parser coverage was added.
5. Non-blockers / follow-ups
- The
Launching ticket ... Pod...actionbar notice is set immediately before awaitinglaunch_ticket_role_pod(...)(crates/tui/src/single_pod.rs:563-589). Because the event loop does not redraw between setting that notice and awaiting the launch, users may only see the final success/failure notice for slow launches. This is acceptable for this MVP, but a follow-up could force a draw or move launch work to an async task if start-progress visibility matters. - Help text for
:ticketnames the fixed actions but does not explain each role individually. The behavior is discoverable enough for MVP, but richer:help tickettext would better satisfy the acceptance criterion that command/action help makes clear what each role does. - Execution-path tests stop at context construction and error formatting. A future small seam around the launcher call would allow direct tests for actionbar success/failure plumbing without spawning real Pods.
6. Validation assessed or rerun
Reran from /home/hare/Projects/yoi/.worktree/tui-ticket-role-actions:
git diff --check— passed.cargo test -p tui ticket --lib— passed, 5 tests.cargo test -p client ticket— passed, 6 tests.cargo fmt --check— passed.cargo check --workspace --all-targets— passed../tickets.sh doctor— passed (doctor: ok).cargo test -p tui --lib— passed, 224 tests.cargo test -p client— passed, 11 tests plus doc-tests.nix build .#yoi— passed; Nix emitted a dirty-tree warning for the worktree. The transientresultsymlink created by Nix was removed afterward;git status --shortshowed no tracked changes.
7. Residual risk
After the intake-context diagnostic is fixed, residual risk is low. The implementation stays within the intended TUI-command surface and delegates launch semantics to the client launcher. The remaining risks are mostly UX/test-depth issues around live launch progress visibility and lack of a direct mocked launcher execution test.
8. Re-review of blocker fix (d288fa590188bb700257e3cfa386b168661d9613)
Result: approve
The blocker is resolved. The fix updates ticket_args so intake now requires at least one non-whitespace argument and returns Invalid arguments. Usage: ticket intake <context...> when context is missing. The existing ticket_command path then continues to pass the non-empty intake context as instruction, with no Ticket reference, preserving the intended Intake launch behavior.
Focused parser coverage was added for both :ticket intake and whitespace-only :ticket intake rejection. The change is limited to crates/tui/src/command.rs; I did not find any new blocker or source-scope expansion in this fix.
Validation rerun from /home/hare/Projects/yoi/.worktree/tui-ticket-role-actions:
cargo test -p tui ticket_intake --lib— passed.cargo test -p tui ticket --lib— passed.
No additional full-build validation was rerun for this narrow parser-only fix.
Implementation report
Implementation report: tui-ticket-role-actions
Worktree / branch
- Worktree:
/home/hare/Projects/yoi/.worktree/tui-ticket-role-actions - Branch:
work/tui-ticket-role-actions
Commits
e125ebb feat: add TUI ticket role commandsd288fa5 fix: require TUI ticket intake context
Summary
Added explicit TUI :ticket commands that launch fixed Ticket-role Pods through the shared client Ticket role launcher.
TUI now parses role actions, builds a TicketRoleLaunchContext, and calls client::launch_ticket_role_pod(...). TUI does not construct SpawnConfig, profile selector semantics, workflow invocation segments, or first-run prompt content directly.
Command syntax
Implemented commands:
:ticket intake <context...>
:ticket route <ticket-id-or-slug> [instruction...]
:ticket investigate <ticket-id-or-slug> [instruction...]
:ticket implement <ticket-id-or-slug> [instruction...]
:ticket review <ticket-id-or-slug> [instruction...]
Role mapping:
intake->TicketRole::Intakeroute->TicketRole::Orchestratorinvestigate->TicketRole::Investigatorimplement->TicketRole::Coderreview->TicketRole::Reviewer
intake requires non-empty context. Non-intake actions require a Ticket id/slug and preserve remaining text as the instruction.
Changed files
crates/client/src/ticket_role.rscrates/tui/src/app.rscrates/tui/src/command.rscrates/tui/src/single_pod.rs
TUI plumbing
- Added
CommandAction::TicketRole(...)as a TUI-local command action. CommandExecutioncan now carry either a Pod protocol method or local command action.Appstores a pending command action after command submission.single_pod.rshandles the pending Ticket role action asynchronously and calls the shared client launcher.PodRuntimeCommandis passed narrowly into the single-Pod run loop/command-action handler so the launcher can start the role Pod.
Diagnostics
- Launch start/success/failure are surfaced through actionbar notices.
UnsupportedInheritProfilehas a TUI-specific message explaining that top-level TUI Ticket launches require concrete role profiles in.yoi/ticket.config.tomluntil an inheritance-aware launch path exists.- Missing non-intake Ticket refs and missing intake context return command diagnostics.
Review status
External sibling review initially requested one blocker fix:
:ticket intakeaccepted missing/whitespace-only context.
The blocker was fixed in d288fa5, and re-review approved with no blockers.
Remaining non-blocker follow-ups:
- Start-progress actionbar notice may be overwritten by final success/failure before a redraw during slow launches.
:help ticketcould describe each role in more detail.- Execution-path tests stop at context construction/error formatting; a future launcher seam could test success/failure actionbar plumbing without spawning real Pods.
Validation
Coder-reported validation for the initial implementation passed:
cargo test -p tui ticket --libcargo test -p client ticketcargo check --workspace --all-targetscargo fmt --checkgit diff --check./tickets.sh doctornix build .#yoi --no-link
Reviewer-rerun validation passed:
git diff --checkcargo test -p tui ticket --libcargo test -p client ticketcargo fmt --checkcargo check --workspace --all-targets./tickets.sh doctorcargo test -p tui --libcargo test -p clientnix build .#yoi
Coder-reported validation for blocker fix passed:
cargo test -p tui ticket --libcargo fmt --checkgit diff --check./tickets.sh doctor
Reviewer re-ran focused blocker validation:
cargo test -p tui ticket_intake --libcargo test -p tui ticket --lib
Ready for merge
Yes.