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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
//! Compile-time embedder profile — the binary's identity and embedder-fixed
//! behavior, centralized.
//!
//! aube hardcodes its own name, version, lockfile filename, cache namespace,
//! env-var prefix, and so on across many crates, and bakes in a handful of
//! behavior choices that an embedding host would want to flip. [`Embedder`]
//! gathers those *embedder-fixed* values — branding plus the behavior toggles
//! that are the host's to set, not the user's — into one place, so the
//! binary's identity is selected once, at the entry point, instead of being
//! scattered as literals and policy checks. Standalone aube ships [`AUBE`],
//! which reproduces every value verbatim, and consumers read it through
//! [`embedder`].
//!
//! This struct holds *embedder-fixed* data: branding (pure naming constants)
//! plus the four behavior toggles that an embedder — not an end user — owns
//! (`canonical_lockfile_always_wins`, `runtime_switching`, `self_engines_check`,
//! `self_update_enabled`). Genuinely *user-tunable* knobs do not belong here;
//! those stay settings.
//!
//! An embedder selects its profile by registering it with [`set_embedder`].
//! A host that goes through the library entry point `aube::cli_main` passes
//! its `&'static Embedder` there and `cli_main` registers it; a host that
//! drives the command layer in-process (`aube::commands::*::run`, bypassing
//! `cli_main` — the headline embedding use case) calls [`set_embedder`] itself
//! at startup. Internally the chosen profile is stored once in a private
//! [`OnceLock`]; [`embedder`] returns it, falling back to [`AUBE`] when nothing
//! was registered, so any caller or test that never sets one transparently
//! gets standalone-aube behavior.
use OnceLock;
/// The binary's embedder profile — branding plus embedder-fixed behavior.
///
/// Branding fields are pure naming constants. The behavior toggles
/// (`canonical_lockfile_always_wins`, `runtime_switching`,
/// `self_engines_check`, `self_update_enabled`) are embedder-fixed, not
/// user-tunable: a host that mirrors the project's incumbent package manager,
/// owns Node provisioning, lives outside aube's version namespace, or owns its
/// own self-update flips them. Genuinely user-tunable knobs stay settings.
/// Standalone aube's embedder profile. Reproduces every hardcoded branding
/// constant and behavior default verbatim; this is the fallback whenever no
/// profile is registered.
pub const AUBE: Embedder = Embedder ;
static ACTIVE: = new;
/// Register the active embedder profile.
///
/// Call this **once at startup**, before invoking any `aube::commands`
/// directly. `aube::cli_main` calls it for you, so binaries that go through
/// `cli_main` don't need to; embedders that drive the command layer in-process
/// — calling `aube::commands::*::run` directly, bypassing `cli_main` (the
/// headline embedding use case) — call it themselves to register their
/// profile before the first command runs.
///
/// Set-once / first-wins: the first registration is the active profile for the
/// process; later calls are silently ignored. A process that never registers
/// one transparently gets standalone-aube behavior ([`AUBE`]) — which is also
/// why tests that don't register a profile see `AUBE`.
///
/// Validates the profile's lockfile invariant in debug builds: a profile whose
/// `lockfile_basename` has no extension or aliases a foreign package manager's
/// lockfile would silently corrupt the lockfile-candidate set, so it trips a
/// `debug_assert!` here — at registration, the single choke point — rather than
/// misbehaving deep inside `io.rs` / `clean.rs` / `pack.rs`.
/// Foreign package-manager lockfile names an embedder's `lockfile_basename`
/// must not alias. Aliasing one would make aube's own lockfile collide with
/// the incumbent's in the lockfile-candidate machinery.
const FOREIGN_LOCKFILE_NAMES: & = &;
/// The active embedder profile, or [`AUBE`] when none was registered. Never
/// panics: an unset profile transparently yields standalone-aube behavior.
/// The active tool's program name for *user-facing* output — the proper noun a
/// user types and reads (e.g. `"aube"` under the default profile, the host's
/// brand under an embedder).
///
/// This is the source-branding seam jdx approved over post-processing rendered
/// output: instead of an embedder string-rewriting `"aube"` out of finished
/// banners and error text, user-facing emission sites compose the program name
/// at the source via `prog()` / [`cmd`], so a library consumer (nub) gets its
/// own brand without any post-pass. Use it for bare program-name references in
/// `miette!` / `bail!` / `eprintln!` / `println!` strings (banners, "re-exec
/// into pinned {prog} version", …). For an `aube <verb>` command reference use
/// [`cmd`] instead, which also brands the verb's program prefix.
///
/// Default-preserving: under the default [`AUBE`] profile this returns exactly
/// `"aube"` byte-for-byte, so standalone aube's output is unchanged. Returns
/// [`Embedder::name`] — the command-safe slug, matching what the clap command
/// name and on-disk sidecars already use, so a user reads one consistent name.
/// A *user-facing* `"{prog} <verb>"` command reference, e.g. `cmd("install")`
/// renders `"aube install"` under the default profile and `"nub install"` under
/// a `nub`-branded embedder.
///
/// Use this wherever a user-facing `miette!` / `bail!` / `eprintln!` /
/// `println!` string tells the user to run a command — `"run `{}` first"` with
/// `cmd("install")`, `"`{}`: package has no script"` with `cmd("run")`, help
/// hints, and so on — so the program prefix follows the active brand instead of
/// being hardcoded to `aube`. The `verb` is the command spelling exactly as the
/// CLI accepts it (`"install"`, `"patch-commit"`, `"store prune"`); it is not
/// re-branded, only the leading program name is.
///
/// Default-preserving: under the default [`AUBE`] profile `cmd("install")` is
/// exactly `"aube install"` byte-for-byte, so standalone aube's error and help
/// text is unchanged. Allocates a `String`; for the bare program name with no
/// verb use [`prog`], which borrows.