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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
//! `ebman <verb>` non-interactive subcommands.
//!
//! Pre-0.15 every `run_*_cli` lived as an inline `async fn` in
//! `src/main.rs`, which ballooned to 2,600+ lines as the CLI surface
//! grew (audit/explain/lint --fix all landed in 0.14). The 0.14
//! architecture review's #1 finding was the resulting grab-bag.
//!
//! Each verb now lives in its own file under `src/cli/`, exposing
//! `pub async fn run(args: &[String]) -> Result<()>`. `main.rs`
//! dispatches by `argv[1]` and calls the matching `cli::<verb>::run`.
//! Shared CLI-only helpers (the `decide_poll` state machine, the
//! `--fix` dispatch-failure flag, the JSON-string escaper, the
//! cli-arg escaper) live here in `mod.rs`.
//!
//! Convention:
//! - Each module is named after the subcommand (`audit.rs`,
//! `explain.rs`, ...) and exports exactly one public function:
//! `pub async fn run(args: &[String]) -> Result<()>`. `args` is
//! the full `std::env::args()` vector so callers can index from
//! `args[1]` onwards uniformly.
//! - Exit codes follow the 0.13 CLI charter (locked in
//! `BACKLOG.md`): 0 ok, 1 aws err, 2 usage err, 3 issues / drift,
//! 4 wait-for-green timeout, 5 auto-rollback fired.
//! - No `println!` inside the TUI alternate screen — these
//! subcommands run before / outside TUI lifecycle, so plain
//! stdout/stderr is fine.
/// The canonical list of top-level `ebman <subcommand>` names — the
/// single source of truth for the CLI-subcommand *name* axis. `main.rs`
/// dispatches these (and lists them on an unknown-subcommand error);
/// `cli::completions` renders them, and a test pins its `SUBS` to this
/// list so the shell-completion subcommand set can't drift from the real
/// CLI. Per-subcommand flags / sub-verbs aren't mechanically derivable
/// and stay hand-maintained in `completions::SUBS`.
pub const SUBCOMMANDS: & = &;
/// Re-exports from the shared deploy-poll module. CLI subcommand
/// modules import via `crate::cli::{decide_poll, PollDecision}`;
/// the actual implementations live in `src/deploy_poll.rs` and are
/// shared with the TUI's `spawn_rollout_dispatch`.
pub use crate;
/// Re-exports of the canonical JSON helpers from `crate::util`. CLI
/// subcommand modules import these via `crate::cli::{json_string,
/// cli_esc}` so call-site rewrites are unnecessary; the actual
/// implementations live in `util.rs` and are shared across the
/// crate (lib + bin).
pub use crate;
/// Cross-process freeze gate for CLI write paths (0.28): refuse when
/// a live TUI session holds `:freeze-deploys` / `:incident START`
/// (pid-scoped marker — see `crate::freeze`). Exit 3, same class as
/// the pin refusal. These paths had the same blind spot the MCP
/// write tools would have had: a fleet frozen mid-incident could
/// still be written from a second terminal.
pub
/// Shared value-flag guard: reject a missing value or a following
/// flag consumed as one. Class fix from the 0.26 max-review — a
/// swallowed value silently changed semantics (`lint --fix --yes
/// --env` widened to the whole fleet; `--rules --json` disabled a CI
/// gate and ate the JSON flag).
pub
/// Exit a CLI command after draining in-flight audit-webhook POSTs —
/// `std::process::exit` (and returning from `#[tokio::main]`) cancels
/// spawned tasks, so a fire-and-forget outcome POST written just
/// before exit usually never left the machine. No-op when nothing is
/// in flight; bounded at slightly over the POST timeout.
pub async !
/// Drain in-flight webhook POSTs before a CLI command's Ok return —
/// same rationale as [`exit_after_drain`], for the success paths.
pub async