1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//! Subcommand and value enums split out of `cli.rs` to keep that file
//! under the 300-line cap. Re-exported from `cli` so `main.rs`'s
//! `use cli::{...}` is unaffected.
use balls::participant_config::InvocationOverrides;
use clap::{Args, Subcommand, ValueEnum};
/// SPEC §11 per-invocation participant overrides, flattened into every
/// lifecycle command. `--sync`/`--no-sync` stay per-command (they
/// predate this and are git-remote-specific); these two cover the
/// plugin participants. Repeatable. Applied tokens are logged in the
/// state-branch commit message via `participant_config::override_log`.
#[derive(Args, Debug, Default, Clone)]
pub struct ParticipantFlags {
/// Drop participant NAME from this event's negotiation (SPEC §11).
#[arg(long = "skip", value_name = "NAME")]
pub skip: Vec<String>,
/// Force participant NAME to required for this event (SPEC §11).
#[arg(long = "required", value_name = "NAME")]
pub required: Vec<String>,
}
impl ParticipantFlags {
pub fn overrides(&self) -> InvocationOverrides {
InvocationOverrides {
skip: self.skip.iter().cloned().collect(),
required: self.required.iter().cloned().collect(),
}
}
}
/// `bl close` arguments, split here so `cli.rs`'s `Command` enum stays
/// under the 300-line cap (mirrors `CreateArgs`/`SyncArgs`). Flattened
/// into `Command::Close`.
#[derive(Args, Debug)]
pub struct CloseArgs {
/// Reviewer message, embedded in the state-branch close commit
/// body. Repeatable, like `git commit -m … -m …`: each value
/// becomes its own paragraph.
#[arg(short = 'm', long = "message")]
pub message: Vec<String>,
#[arg(long = "as")]
pub identity: Option<String>,
/// Override the delivering commit instead of tag-scanning the
/// target branch (SPEC §6; bl-87ea). Use when the forge produced a
/// rebase-merge with several commits and you want a specific one.
#[arg(long = "delivered", value_name = "SHA")]
pub delivered: Option<String>,
/// Force a remote round-trip on this close. Mirrors `bl claim --sync`.
#[arg(long, conflicts_with = "no_sync")]
pub sync: bool,
/// Skip any configured remote round-trip on this close.
#[arg(long, conflicts_with = "sync")]
pub no_sync: bool,
#[command(flatten)]
pub participant: ParticipantFlags,
}
#[derive(Clone, Debug, ValueEnum)]
pub enum ShellArg {
Bash,
Zsh,
Fish,
}
#[derive(Subcommand, Debug)]
pub enum DepCmd {
/// Add a dependency: TASK depends on DEPENDS_ON.
Add { task: String, depends_on: String },
/// Remove a dependency.
Rm { task: String, depends_on: String },
/// Print parent/child tree with box-drawing. Deps and gates show
/// as inline annotations, never as nesting. Without ID, prints
/// every parentless task as its own root.
Tree {
id: Option<String>,
/// Emit a nested JSON tree instead of the box-drawn text.
#[arg(long)]
json: bool,
},
}
#[derive(Subcommand, Debug)]
pub enum LinkCmd {
/// Add a typed link: relates_to, duplicates, supersedes, replies_to, gates.
/// `gates` blocks the source task from closing until the target closes.
Add {
task: String,
link_type: String,
target: String,
},
/// Remove a typed link.
Rm {
task: String,
link_type: String,
target: String,
},
}