tix/cli/cli_workflow.rs
1#[allow(clippy::wildcard_imports)]
2use super::*;
3
4/// The `tix parent` subcommands.
5///
6/// A **required** subcommand, unlike `tix link`'s three optional verbs. `tix link`
7/// has a meaningful bare form (create); `tix parent` with no argument is a user
8/// mistake, and guessing which of three reports they wanted is worse than asking.
9#[derive(Debug, Clone, Subcommand)]
10pub enum ParentAction {
11 /// Report the parent, direct children, child count and rollup for one issue
12 Show {
13 /// Issue number, filename fragment or unique title fragment
14 issue: String,
15 },
16 /// List an issue's direct children, ordered by issue number
17 Children {
18 /// Issue number, filename fragment or unique title fragment
19 issue: String,
20 },
21 /// List every issue that has children, with a child count
22 List,
23}
24
25/// The `tix workflow` verbs, per `contracts/cli-surface.md` §1.
26///
27/// A real `#[command(subcommand)]` tree rather than an optional-verb enum like
28/// [`LinkAction`]: the three verbs share nothing but the prefix, and there is no
29/// sensible bare `tix workflow`. Making the verb **required** means `tix workflow`
30/// alone is a usage error rather than an empty success — printing the vocabulary
31/// when the user asked for the policy would be guessing at their intent.
32#[derive(Subcommand)]
33pub enum WorkflowAction {
34 /// The global category vocabulary, in order
35 Categories,
36 /// A board's columns, resolved categories, and where each resolution came from
37 Show {
38 /// Board name; omitted means the active board (`default`, or the first
39 /// declared). A name that is not configured is an error listing the boards
40 /// that are.
41 board: Option<String>,
42 },
43 /// The effective transition policy and its override escape hatch
44 Transitions,
45}
46
47/// `tix layout` subcommands.
48#[derive(Subcommand)]
49pub enum LayoutAction {
50 /// Print the effective `[layout]` template and a worked example
51 Show,
52 /// Relocate every issue to the configured layout (dry run unless `--apply`)
53 Migrate {
54 /// Write the moves; without it the command only prints the plan
55 #[arg(long)]
56 apply: bool,
57 },
58}
59
60/// `tix migrate` subcommands.
61#[derive(Subcommand)]
62pub enum MigrateAction {
63 /// Backfill issue ids and rewrite parent/relationship endpoints as ids
64 IssueGraph {
65 /// Write the migration; without it the command only prints the plan
66 #[arg(long)]
67 apply: bool,
68 },
69}
70
71/// The `tix link` subcommands.
72///
73/// `tix link <from> <to> --type <kind>` is the create form and carries no
74/// subcommand, so the three verbs below are optional rather than required
75/// (C-001 removes the old untyped symmetric form, not the bare create form the
76/// CLI surface contract specifies).
77#[derive(Subcommand)]
78pub enum LinkAction {
79 /// Retarget and/or re-kind an existing relationship, keeping its id
80 Edit {
81 /// Relationship id, as printed by `tix link list`
82 id: String,
83 /// New target issue number, filename fragment or unique title fragment
84 #[arg(long)]
85 to: Option<String>,
86 /// New relationship kind: `blocks`, `blocked_by`, `duplicates`, `related`
87 #[arg(long, value_name = "KIND")]
88 r#type: Option<String>,
89 },
90 /// Remove a relationship by id. An absent id is an idempotent no-op
91 Remove {
92 /// Relationship id, as printed by `tix link list`
93 id: String,
94 },
95 /// List relationships for one issue, or for the whole board
96 List {
97 /// Issue number, filename fragment or unique title fragment. Omit for every issue.
98 issue: Option<String>,
99 /// Only relationships of this kind
100 #[arg(long, value_name = "KIND")]
101 kind: Option<String>,
102 },
103}