Skip to main content

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}