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
//! `degenbot-cli` - the degenbot console binary (ADR-051 D2).
//!
//! One argv facade, one command model. This crate owns exactly the things
//! [`degenbot_cli_core`] cannot own by charter:
//!
//! - **argv declaration** ([`argv`]): the clap v4 derive tree for the whole
//! command vocabulary, and the argv -> [`Command`](degenbot_cli_core::Command)
//! mapping. See `argv`'s module docs for where clap's shape differs from the
//! retired Python click tree.
//! - **rendering** ([`render`]): typed [`CommandReport`](degenbot_cli_core::CommandReport)
//! lines to stdout, typed [`CliError`](degenbot_cli_core::CliError) to stderr
//! with its `ExitCode`.
//! - **interaction** ([`prompt`]): the stdin/stdout [`Prompter`](degenbot_cli_core::Prompter)
//! the arms ask; the prompt *policy* stays declared data in cli-core (D4).
//! - **sinks** ([`sinks`]): the tracing registry + console fmt layer, booted in
//! the same order as the Python driver (typed config first, then the
//! subscriber), and **progress** ([`progress`]): the `indicatif` bar, which
//! exists only here (D9).
//! - **SIGINT ownership** ([`signal`], D7): first Ctrl+C feeds cli-core's
//! [`CancelHandle`](degenbot_cli_core::CancelHandle); a second aborts.
//!
//! cli-core stays clap-free and indicatif-free (asserted by
//! `just check-cli-core-purity`); this crate stays free of every domain-engine
//! dependency (asserted by `just check-cli-shell-purity`).
pub use ;
use Write as _;
use CancelHandle;
use ProcessEnv;
/// The banner `--version` prints: the workspace version (ADR-009 lockstep) plus
/// the shared build receipt, embedded by `build.rs`.
///
/// The fingerprint half is byte-identical to the Python FFI's
/// `degenbot._ffi.build_fingerprint()`, so the two entry surfaces can be
/// compared directly rather than trusted.
pub const VERSION_LINE: &str = concat!;
/// Parse `args` (argv WITHOUT the program name), boot the sinks, resolve the
/// argv into a [`Command`](degenbot_cli_core::Command), run it and render the
/// result. This is the ONE console composition root: the `degenbot` binary and
/// the Python `cli_main` passthrough both land here, so their sequences cannot
/// drift apart.
///
/// Returns the process exit code and never exits the process, so an embedded
/// host can drive the console directly: clap owns `--help`/`--version`/usage
/// errors (its own exit codes apply), a refused typed config is `2` (the same
/// refusal exit the Python module init uses), and every command outcome maps
/// through cli-core's single `CliError -> ExitCode` site.
///
/// There is deliberately no host parameter here. The native and Python hosts
/// are not abstracted behind a flag: their genuine difference lives upstream
/// of this function — the Python `#[pymodule]` init has already installed the
/// typed config and the driver's log forwarder by the time this runs, while
/// the native path gets both from `sinks::boot()` below — and `boot`'s
/// first-wins installs keep that difference in place. A switch would hide the
/// difference it cannot actually remove.
/// The binary entry: collect the process argv (minus the program name) and
/// delegate to the console composition root.