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
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
//! apcore-cli — Command-line interface for apcore modules.
//!
//! Automatic MCP Server & OpenAI Tools Bridge for apcore — zero code changes required.
//!
//! Library root: re-exports the user-facing public API items.
//! Protocol spec: FE-01 through FE-13 plus SEC-01 through SEC-04.
//!
//! See the apcore-cli docs repo for the authoritative feature spec and tech design.
// `ModuleExecutionError` carries `apcore::errors::ModuleError` by value on its
// passthrough variant, deliberately: `cli::map_module_error_to_exit_code` reads
// the underlying `ErrorCode` to keep the exit-code taxonomy identical between
// the `--sandbox` and direct execution paths, and stringifying or boxing it
// would either lose that or change a public enum. apcore-rust suppresses the
// same lint at its own crate root for the same reason ("ModuleError is
// intentionally large (rich structured error for an SDK); boxing it everywhere
// would change the public API"), so this mirrors the decision of the crate that
// owns the type rather than making a different one downstream.
// Internal sandbox runner — not part of the public API surface, but must be
// pub so the binary entry point (main.rs) can invoke run_sandbox_subprocess().
// Exit codes as defined in the API contract.
pub const EXIT_SUCCESS: i32 = 0;
pub const EXIT_MODULE_EXECUTE_ERROR: i32 = 1;
pub const EXIT_INVALID_INPUT: i32 = 2;
pub const EXIT_MODULE_NOT_FOUND: i32 = 44;
// A dependency that cannot be found or whose version does not satisfy the
// declared range is a module-resolution failure, so it shares 44 with
// MODULE_NOT_FOUND. Named separately to mirror `EXIT_DEPENDENCY_*` in
// apcore-cli-python and `DEPENDENCY_*` in apcore-cli-typescript.
pub const EXIT_DEPENDENCY_NOT_FOUND: i32 = 44;
pub const EXIT_DEPENDENCY_VERSION_MISMATCH: i32 = 44;
pub const EXIT_SCHEMA_VALIDATION_ERROR: i32 = 45;
pub const EXIT_APPROVAL_DENIED: i32 = 46;
pub const EXIT_CONFIG_NOT_FOUND: i32 = 47;
pub const EXIT_SCHEMA_CIRCULAR_REF: i32 = 48;
pub const EXIT_ACL_DENIED: i32 = 77;
// Config Bus errors (apcore >= 0.15.0)
// All four namespace/env errors share exit code 78 per protocol spec —
// the spec groups them into a single "config namespace error" category.
pub const EXIT_CONFIG_NAMESPACE_RESERVED: i32 = 78;
pub const EXIT_CONFIG_MOUNT_ERROR: i32 = 66;
pub const EXIT_CONFIG_BIND_ERROR: i32 = 65;
pub const EXIT_ERROR_FORMATTER_DUPLICATE: i32 = 70;
pub const EXIT_SIGINT: i32 = 130;
// ---------------------------------------------------------------------------
// FE-13 apcli subcommand dispatcher (§4.9)
// ---------------------------------------------------------------------------
/// Subcommand names that are registered regardless of the resolved visibility
/// mode's include/exclude filter. `exec` is the documented always-registered
/// escape hatch (spec §4.9) so downstream callers can always invoke modules
/// by ID even when the apcli group is configured with a minimal surface.
pub const APCLI_ALWAYS_REGISTERED: & = &;
/// Central dispatcher for the 13 canonical apcli subcommands. Walks a fixed
/// registration table and honors [`ApcliGroup::resolve_visibility`] for
/// include/exclude modes. Under `"all"` or `"none"` all 13 subcommands are
/// registered (spec §4.9 registration rules table); under `"include"` only
/// listed subcommands + [`APCLI_ALWAYS_REGISTERED`]; under `"exclude"` all
/// except listed + [`APCLI_ALWAYS_REGISTERED`].
///
/// * `apcli_group` — the `apcli` clap [`Command`](clap::Command) to receive
/// subcommands.
/// * `cfg` — the resolved apcli visibility configuration.
/// * `prog_name` — kept for source-level Python/TS parity. Audit D9-W5
/// (2026-05-08) dropped the `prog_name` argument from
/// `register_completion_command` — the static clap-derived builder has no
/// place to thread it; the program name is consumed at dispatch time by
/// `cmd_completion` instead. The argument is retained on this outer
/// function so call sites do not break and so future per-subcommand
/// registrars that DO take `prog_name` (e.g. for help-text customisation)
/// can pick it up without another signature churn.
///
/// Returns the updated command with registered subcommands attached.
// ---------------------------------------------------------------------------
// Crate-root re-exports (USER-FACING API only)
// ---------------------------------------------------------------------------
//
// Per audit D9-005, the crate-root pub-use surface was trimmed from ~110 → ~40
// items in v0.6.x. Internal command-builder helpers (register_*,
// describe_pipeline_command, validate_command, generate_grouped_*_completion,
// build_synopsis, generate_man_page) are now `pub(crate)` at the module level
// — they are only consumed by lib.rs's per-subcommand registrar table and the
// in-crate test suite. The dispatch_* fns in `system_cmd` and `strategy`
// remain `pub` because the binary entry-point in main.rs calls them via the
// full path (`apcore_cli::system_cmd::dispatch_health`, etc.) and main.rs is
// a separate binary crate.
//
// **No `create_cli` / `run_with_config` factory in Rust** (cross-SDK parity
// note from audit D1-005, 2026-04-26; updated D1-006 follow-up 2026-05-07):
// Python exposes `apcore_cli.create_cli` and TypeScript exposes `createCli`
// from `apcore-cli`; Rust intentionally has no equivalent factory. The
// high-level `CliConfig` / `run_with_config` embedding API was removed in
// v0.7.0 (D9-001/002) — it never had a working dispatch loop. An embedding
// API will be reintroduced when actually implemented; until then,
// downstream Rust users invoke the binary directly or compose the
// per-subcommand registrars (e.g., `register_completion_command`) onto a
// `clap::Command` they own.
//
// Cross-SDK parity gap (tracked, not a bug): Python `create_cli` and
// TypeScript `createCli` both accept an `allowed_prefixes` / `allowedPrefixes`
// safety knob (toolkit RegistryWriter prefix allowlist). Rust currently has
// no equivalent because the entry point that would host it does not exist.
// When the Rust embedding API is reintroduced, `allowed_prefixes` should be
// added at the same time (mirror the Python `factory.py:78` and TypeScript
// `CreateCliOptions.allowedPrefixes` semantics). Recorded in
// `apcore-cli/docs/features/core-dispatcher.md` Cross-SDK API surface
// appendix as a known parity gap.
//
// Cross-SDK parity gap (tracked, not a bug; 2026-05-08): Python
// `create_cli(builtin_group_name="apcli")` and TypeScript `createCli({
// builtinGroupName: "apcli" })` both accept a kwarg/option to rename the
// built-in command group from the default "apcli" to a custom namespace
// (e.g. downstream branded CLIs that prefer `mycorp-cli admin health` over
// `mycorp-cli apcli health`). Rust currently has no equivalent because the
// entry point that would host it does not exist. When the Rust embedding
// API is reintroduced, an equivalent should be added at the same time:
// either as a builder method on the future `CliConfig` (e.g.
// `with_builtin_group_name("admin")`) or as a parameter on the future
// factory function. Implementation requirements: validate the name against
// `^[a-z][a-z0-9_-]*$`, plumb it through the apcli sub-group construction,
// and surface it via a `builtin_group_name()` accessor on the resulting
// `CliConfig` so collision checks at the registry-driven dispatch layer
// see the resolved name. The static `BUILTIN_GROUP_NAME = "apcli"` const
// in `cli.rs` and `RESERVED_FLAG_NAMES` should become per-instance state
// once the API exists.
// Approval gate (FE-04 + FE-11 §3.5)
pub use ;
// Built-in command group (FE-13)
pub use ;
// Core dispatcher (FE-01)
pub use ;
// FE-13 retires `cli::BUILTIN_COMMANDS`. Downstream consumers that pinned to
// the old symbol continue to compile via the deprecated alias on `cli::` for
// one MINOR cycle; the re-export at the crate root is dropped.
pub use ;
// Config resolution (FE-07)
pub use ConfigResolver;
// Discovery + Registry providers (FE-03 / FE-09)
//
// Audit D9-W3 (2026-05-08): `register_discovery_commands` was deleted (zero
// production callers; FE-13 routes attach `list`/`describe`/`exec`
// individually under the `apcli` group). `cmd_list` was demoted to
// `pub(crate)` since it is a thin in-tree wrapper over `cmd_list_enhanced`.
pub use ;
// Test utilities — available behind the `test-support` feature.
// Gated behind cfg(test) for unit tests and the test-support feature for
// integration tests. Excluded from production builds.
pub use ;
// Display overlay helpers (FE-09)
pub use ;
// Module exposure filtering (FE-12)
pub use ExposureFilter;
// Filesystem discoverer (FE-03)
pub use FsDiscoverer;
// Init command (FE-10)
pub use ;
// Output formatting (FE-08)
pub use ;
// Schema $ref resolver (FE-02)
pub use resolve_refs;
// JSON Schema → clap argument generator (FE-02)
pub use ;
// Security primitives (SEC-01..04)
pub use ;
// Shell integration (FE-06): completion + man page builders.
// build_program_man_page is the user-facing full-program man entry point;
// per-command builders (cmd_completion, cmd_man, has_man_flag, completion_command)
// are kept for downstream embedders that build their own root command tree.
// Embedders compose them directly: each registers the corresponding subcommand
// onto a clap Command. The previous register_shell_commands wrapper was a
// 2-line passthrough with no production callers and was removed in v0.7.0
// (D9-003) — embedders should call register_completion_command and
// register_man_command directly.
pub use ;
// FE-11 system commands constant (used by downstream consumers to inspect
// which command names are reserved by the system-management subset).
pub use SYSTEM_COMMANDS;
// Per-subcommand registrars (FE-13). Demoted from `pub(crate)` to `pub` so
// downstream embedders that compose their own root command tree can attach
// individual built-in subcommands without re-implementing them. The
// `register_apcli_subcommands` umbrella above is the high-level composer;
// these entries are the building blocks Python/TS expose as
// `register_*_command` factories on the public API.
pub use register_pipeline_command;
pub use ;
pub use register_validate_command;