12 KiB
Created
Created by tickets.sh create.
Plan
Delegation intent: yoi ticket CLI parity
Intent
Add yoi ticket ... CLI operations over the Rust Ticket backend so direct Ticket mutation is owned by the yoi binary rather than tickets.sh.
This is the first step in the Yoi-local Ticket backend migration. tickets.sh remains in place for this ticket only as transitional compatibility and validation reference.
Worktree / branch
- worktree:
/home/hare/Projects/yoi/.worktree/yoi-ticket-cli-parity - branch:
work/yoi-ticket-cli-parity
Requirements
Implement these subcommands in the top-level yoi binary crate:
yoi ticket create --title "..." [--slug slug] [--kind task] [--priority P2] [--label a,b]yoi ticket list [--status open|pending|closed|all]yoi ticket show <id-or-slug>yoi ticket comment <id-or-slug> [--role comment|plan|decision|implementation_report] [--file path|--message text]yoi ticket review <id-or-slug> --approve|--request-changes [--file path|--message text]yoi ticket status <id-or-slug> open|pending|closedyoi ticket close <id-or-slug> [--resolution text|--file path]yoi ticket doctor
Use crates/ticket backend APIs directly. Do not shell out to tickets.sh.
Current code map
crates/yoi/src/main.rs- Owns top-level CLI parsing and dispatch.
- Existing subcommands include
pod,keys, andmemory lint. - Add
ticketparsing/dispatch here or in a new module such ascrates/yoi/src/ticket_cli.rs.
crates/yoi/Cargo.toml- Add dependency on
ticketif needed.
- Add dependency on
crates/ticket/src/lib.rs- Ticket domain/backend APIs:
LocalTicketBackend,TicketBackend,NewTicket,NewTicketEvent,TicketReview, status/review/event types, doctor reports.
- Ticket domain/backend APIs:
crates/ticket/src/config.rs- Workspace ticket config and backend root defaults. Use if it helps locate backend root; otherwise current active storage is still
work-items/for this ticket.
- Workspace ticket config and backend root defaults. Use if it helps locate backend root; otherwise current active storage is still
tickets.sh- Compatibility/reference only. Do not invoke it from Rust code.
Scope notes
- Active storage stays where it is for this ticket (
work-items/unless config already directs otherwise). - Keep
tickets.shin place. - CLI output does not need exact
tickets.shformatting, but should be understandable and stable enough for tests. - Prefer concise plain text output for human CLI; JSON is not required unless already easy.
yoi ticket doctorshould be usable as the future validation command.
Non-goals
- Moving storage to
.yoi/tickets/. - Removing
tickets.sh. - Adding external tracker backends.
- TUI changes.
- Scheduler/lease/queue.
- Broad CLI framework refactor.
Edge cases / validation expectations
comment/reviewshould accept exactly one body source:--fileor--message, or provide a clear error.reviewrequires exactly one of--approve/--request-changes.closerequires resolution text/file or a clear error if the backend cannot close without a resolution.status closedshould preserve backend semantics. If direct status-to-closed cannot write a resolution, either reject it with guidance to usecloseor keep parity only if existing backend supports it safely.doctorshould print diagnostics and return non-zero on failures.--helpforyoi ticketshould document subcommands.
Validation
Run at least:
- focused
cargo test -p yoi tickettests; cargo test -p ticket;cargo check --workspace --all-targets;cargo fmt --check;git diff --check;./tickets.sh doctor;- built binary
yoi ticket doctoragainst the repository if possible.
Run nix build .#yoi --no-link if feasible.
Completion report
Report:
- worktree path / branch;
- commit hash;
- implemented command surface;
- backend root resolution behavior;
- tests/validation results;
- known compatibility gaps from
tickets.sh, if any; - whether ready for external review.
Review: approve
External review: yoi-ticket-cli-parity
1. Result
approve
2. Summary of implementation
The implementation adds a new yoi ticket ... command surface in the product yoi binary crate, with parsing and dispatch in crates/yoi/src/main.rs and the command implementation in crates/yoi/src/ticket_cli.rs.
The CLI resolves the local Ticket backend through ticket::config::TicketConfig::load_workspace, defaults to <cwd>/work-items when no .yoi/ticket.config.toml is present, and then calls LocalTicketBackend / TicketBackend operations directly. I found no production-path shell-out to tickets.sh; the only tickets.sh process invocations found are in crates/ticket compatibility tests.
The changed files are scoped to the yoi CLI crate, the ticket backend doctor reporting shape, and necessary dependency/package hash updates. I did not find storage migration, tickets.sh removal, TUI changes, scheduler/lease work, or broad refactoring.
3. Requirement-by-requirement assessment
yoi ticketsubcommands cover create/list/show/comment/review/status/close/doctor: satisfied.TicketCommandcontains all requested operations andhelp_text()documents them.- Product CLI ownership in the
yoibinary crate: satisfied.main.rsaddsMode::Ticketand dispatchesticketbefore normal TUI argument handling. - Uses Rust Ticket backend APIs directly, no
tickets.shshell-out: satisfied for the product CLI path.ticket_cli.rscallsLocalTicketBackendandTicketBackendmethods directly. - Backend root resolution and active storage: satisfied for this ticket. The CLI uses
.yoi/ticket.config.tomlwhen present and otherwise defaults to<cwd>/work-items, preserving current local storage rather than moving to.yoi/tickets. status closedsafety: satisfied.status closedis rejected with guidance to useyoi ticket close <ticket> --resolution <text>.comment,review, andclosebody source validation: satisfied. The parser requires exactly one body source and rejects conflicting/missing inputs;reviewalso requires exactly one result flag.- Doctor success/failure behavior: satisfied for errors.
TicketCliStatus::Failuremaps to a failing process exit code, and diagnostics are printed when errors are present. - Human-useful output: broadly satisfied. Output is concise tabular/plain text for create/list/status and readable Markdown-like output for show.
- Bounded output: partially satisfied only by the natural size of the local backend;
show,list, and doctor diagnostics do not impose explicit limits. I classify this as a follow-up because the requested CLI parity is still implemented and the current compatibility CLI is also not explicitly bounded. - Tests in temp roots/fixtures: satisfied in implementation.
ticket_cli.rsexercises core operations inTempDir, including configured backend root behavior and validation edge cases;crates/ticketkeeps compatibility tests. Cargo.lock/package.nix: necessary and safe on inspection. Addingticketto theyoicrate requires the lockfile package dependency update, and the Nix cargo hash update is expected from the Cargo metadata/source change.- Non-goals: satisfied. I found no
.yoi/ticketsmigration,tickets.shremoval, TUI change, scheduler/lease addition, or broad refactor.
4. Blockers
None.
5. Non-blockers / follow-ups
yoi ticket doctorsuppresses warning-only diagnostics becausedoctor()returns early withdoctor: okwhenreport.error_count() == 0. If backend warnings are intended to be user-visible, the CLI should print warnings while still exiting successfully. This is not a merge blocker because the oldtickets.sh doctoronly had errors and the required failure behavior for errors is present.- The CLI does not explicitly bound
show,list, or diagnostic output. Consider adding limits later if this command is expected to be safe for very large Ticket stores or oversized thread bodies. - The generic body-source error text says
--message/--resolutionfor all commands, so comment/review errors mention--resolutioneven though that flag is only for close. The validation is correct; the wording can be improved in follow-up.
6. Validation assessed or rerun
Rerun/read-only validation:
git diff --check develop...HEAD— passed with no output../tickets.sh doctor— passed:doctor: ok.git status --short && git branch --show-current && git rev-parse --short=12 HEAD— confirmed branchwork/yoi-ticket-cli-parityat4d5068ba3baf; no worktree dirt was reported before this review artifact was written.git grep -n "tickets.sh\|std::process::Command\|Command::new" -- crates/yoi crates/ticket— no production CLI shell-out found; onlycrates/ticketcompatibility tests invoketickets.sh.
Inspected:
- Ticket and delegation intent.
crates/yoi/src/ticket_cli.rs.crates/yoi/src/main.rs.crates/ticket/src/lib.rsdiff.crates/ticket/src/config.rsbackend default/config behavior.crates/yoi/Cargo.toml,Cargo.lockdiff, andpackage.nixhash change.
Not rerun: cargo test, cargo check, cargo fmt --check, built yoi ticket doctor, or nix build .#yoi; I stayed to read-only validation commands as requested for this external sibling review.
7. Residual risk
The main residual risk is not semantic parity but operational validation: I did not rerun the Rust or Nix builds, so the final merge owner should rely on the coder's validation evidence or rerun the full acceptance suite before merging. There is also minor UX risk around unbounded show/list output and warning-only doctor output being hidden.
Implementation report
Implementation report: yoi-ticket-cli-parity
Worktree / branch
- Worktree:
/home/hare/Projects/yoi/.worktree/yoi-ticket-cli-parity - Branch:
work/yoi-ticket-cli-parity
Commit
4d5068b feat: add yoi ticket CLI
Summary
Added yoi ticket ... subcommands to the product yoi binary crate, backed directly by the Rust Ticket backend APIs.
The implementation does not shell out to tickets.sh. Active storage remains unchanged for this ticket: when .yoi/ticket.config.toml is absent, the CLI uses the current default <workspace>/work-items.
Implemented command surface
yoi ticket create --title <title> [--slug <slug>] [--kind <kind>] [--priority P2] [--label a,b]yoi ticket list [--status open|pending|closed|all]yoi ticket show <id-or-slug>yoi ticket comment <id-or-slug> [--role comment|plan|decision|implementation_report] (--file <path>|--message <text>)yoi ticket review <id-or-slug> (--approve|--request-changes) (--file <path>|--message <text>)yoi ticket status <id-or-slug> <open|pending|closed>yoi ticket close <id-or-slug> (--resolution <text>|--file <path>)yoi ticket doctor
yoi ticket status ... closed is intentionally rejected with guidance to use yoi ticket close, because status-only close would not write resolution.md.
Backend behavior
- Uses
ticket::config::TicketConfig::load_workspace(<cwd>)to resolve backend root. - Missing
.yoi/ticket.config.tomldefaults to<cwd>/work-items. - Relative configured roots resolve against the workspace.
- Malformed config fails through the existing config loader.
- No storage migration to
.yoi/ticketsis included.
Changed files
Cargo.lockcrates/ticket/src/lib.rscrates/yoi/Cargo.tomlcrates/yoi/src/main.rscrates/yoi/src/ticket_cli.rspackage.nix
Review status
External sibling reviewer approved with no blockers.
Non-blocker follow-ups:
yoi ticket doctorcurrently hides warning-only diagnostics because it printsdoctor: okwhenerror_count() == 0.show,list, and doctor diagnostic output are not explicitly bounded.- Body-source error text is generic and can mention
--resolutionfor comment/review commands.
Validation
Coder-reported validation passed:
cargo test -p yoi ticketcargo test -p ticketcargo check --workspace --all-targetscargo fmt --checkgit diff --checkgit diff --cached --check./tickets.sh doctorcargo build -p yoitarget/debug/yoi ticket doctornix build .#yoi --no-link
Reviewer-rerun validation passed:
git diff --check develop...HEAD./tickets.sh doctor- production CLI grep found no shell-out to
tickets.sh.
Ready for merge
Yes.