@minniexcode/codex-switch 0.0.5 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.AI.md +5 -2
- package/README.md +44 -100
- package/dist/app/add-provider.js +28 -4
- package/dist/app/edit-provider.js +47 -19
- package/dist/app/export-providers.js +2 -2
- package/dist/app/get-current-profile.js +1 -1
- package/dist/app/get-status.js +10 -3
- package/dist/app/import-providers.js +15 -7
- package/dist/app/init-codex.js +68 -0
- package/dist/app/list-backups.js +1 -1
- package/dist/app/list-config-profiles.js +3 -2
- package/dist/app/list-providers.js +2 -1
- package/dist/app/remove-provider.js +2 -2
- package/dist/app/rollback-backup.js +1 -1
- package/dist/app/rollback-latest.js +1 -1
- package/dist/app/run-doctor.js +83 -6
- package/dist/app/run-mutation.js +2 -2
- package/dist/app/setup-codex.js +21 -12
- package/dist/app/show-config.js +11 -3
- package/dist/app/show-provider.js +1 -1
- package/dist/app/switch-provider.js +16 -9
- package/dist/cli/add-interactive.js +7 -104
- package/dist/cli/args.js +6 -135
- package/dist/cli/help.js +8 -313
- package/dist/cli/interactive.js +17 -225
- package/dist/cli/output.js +21 -6
- package/dist/cli/prompt.js +4 -106
- package/dist/cli.js +10 -404
- package/dist/commands/args.js +132 -0
- package/dist/commands/dispatch.js +16 -0
- package/dist/commands/handlers.js +460 -0
- package/dist/commands/help.js +120 -0
- package/dist/commands/registry.js +351 -0
- package/dist/commands/types.js +2 -0
- package/dist/domain/config.js +235 -21
- package/dist/domain/providers.js +16 -2
- package/dist/domain/setup.js +1 -0
- package/dist/infra/backup-repo.js +9 -206
- package/dist/infra/codex-cli.js +9 -126
- package/dist/infra/codex-paths.js +6 -67
- package/dist/infra/config-repo.js +59 -0
- package/dist/infra/fs-utils.js +8 -93
- package/dist/infra/lock-repo.js +4 -95
- package/dist/infra/providers-repo.js +8 -94
- package/dist/interaction/add-interactive.js +99 -0
- package/dist/interaction/interactive.js +289 -0
- package/dist/interaction/prompt.js +110 -0
- package/dist/runtime/codex-cli.js +130 -0
- package/dist/runtime/codex-probe.js +57 -0
- package/dist/runtime/types.js +2 -0
- package/dist/storage/auth-repo.js +160 -0
- package/dist/storage/backup-repo.js +210 -0
- package/dist/storage/codex-paths.js +71 -0
- package/dist/storage/config-repo.js +266 -0
- package/dist/storage/fs-utils.js +97 -0
- package/dist/storage/lock-repo.js +99 -0
- package/dist/storage/providers-repo.js +98 -0
- package/docs/Design/codex-switch-v0.0.5-design.md +32 -22
- package/docs/Design/codex-switch-v0.0.6-design.md +708 -0
- package/docs/Design/codex-switch-v0.0.7-design.md +862 -0
- package/docs/PRD/codex-switch-prd-v0.0.5-to-v0.1.0.md +227 -89
- package/docs/PRD/codex-switch-prd-v0.1.0.md +200 -226
- package/docs/PRD/codex-switch-prd.md +1 -1
- package/docs/Reference/codex-config-reference.md +604 -0
- package/docs/Reference/codex-config-reference.zh-CN.md +633 -0
- package/docs/cli-usage.md +78 -29
- package/docs/codex-switch-technical-architecture.md +73 -4
- package/docs/test-report-0.0.5.md +163 -0
- package/docs/test-report-0.0.7.md +118 -0
- package/docs/testing.md +151 -0
- package/package.json +1 -1
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.COMMANDS = void 0;
|
|
4
|
+
exports.getCommandDefinitions = getCommandDefinitions;
|
|
5
|
+
exports.getKnownCommandIds = getKnownCommandIds;
|
|
6
|
+
exports.findCommandDefinition = findCommandDefinition;
|
|
7
|
+
exports.findCommandDefinitionByTokens = findCommandDefinitionByTokens;
|
|
8
|
+
exports.resolveCommandFromArgv = resolveCommandFromArgv;
|
|
9
|
+
exports.isKnownCommandName = isKnownCommandName;
|
|
10
|
+
exports.isKnownHelpTopic = isKnownHelpTopic;
|
|
11
|
+
exports.getPublicCommandNames = getPublicCommandNames;
|
|
12
|
+
exports.getNestedCommandTokens = getNestedCommandTokens;
|
|
13
|
+
const handlers_1 = require("./handlers");
|
|
14
|
+
/**
|
|
15
|
+
* Canonical command registry used by parsing, help rendering, and dispatch.
|
|
16
|
+
*/
|
|
17
|
+
exports.COMMANDS = [
|
|
18
|
+
{
|
|
19
|
+
id: "config-show",
|
|
20
|
+
tokens: ["config", "show"],
|
|
21
|
+
handler: handlers_1.handleRegisteredCommand,
|
|
22
|
+
group: "read",
|
|
23
|
+
summary: "Show the structured config profile view.",
|
|
24
|
+
usage: ["codexs config show [profile] [--json] [--codex-dir <path>]"],
|
|
25
|
+
details: [
|
|
26
|
+
"Returns all recognizable config profiles by default, including unmanaged and orphaned references.",
|
|
27
|
+
"Passing [profile] narrows the response to one profile while preserving the same shape.",
|
|
28
|
+
],
|
|
29
|
+
examples: ["codexs config show", "codexs config show packycode --json"],
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: "config-list-profiles",
|
|
33
|
+
tokens: ["config", "list-profiles"],
|
|
34
|
+
handler: handlers_1.handleRegisteredCommand,
|
|
35
|
+
group: "read",
|
|
36
|
+
summary: "List recognizable config profiles with managed-state hints.",
|
|
37
|
+
usage: ["codexs config list-profiles [--json] [--codex-dir <path>]"],
|
|
38
|
+
details: [
|
|
39
|
+
"Lists managed, unmanaged, and orphaned config profiles in one stable view.",
|
|
40
|
+
"Use config show for richer single-profile details.",
|
|
41
|
+
],
|
|
42
|
+
examples: ["codexs config list-profiles", "codexs config list-profiles --json"],
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "init",
|
|
46
|
+
tokens: ["init"],
|
|
47
|
+
handler: handlers_1.handleRegisteredCommand,
|
|
48
|
+
group: "write",
|
|
49
|
+
summary: "Initialize a Codex directory with an empty managed providers registry.",
|
|
50
|
+
usage: ["codexs init [--json] [--codex-dir <path>]"],
|
|
51
|
+
details: [
|
|
52
|
+
"Creates providers.json with an empty providers object when it does not exist yet.",
|
|
53
|
+
"Does not require codex CLI, config.toml, or auth.json, and does not run doctor.",
|
|
54
|
+
"TTY mode can resolve ambiguous Codex directories and confirm creating a missing directory.",
|
|
55
|
+
"Non-TTY and --json runs never prompt and fail when the target directory is missing.",
|
|
56
|
+
],
|
|
57
|
+
examples: ["codexs init", "codexs init --json --codex-dir ~/.codex"],
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: "migrate",
|
|
61
|
+
tokens: ["migrate"],
|
|
62
|
+
handler: handlers_1.handleRegisteredCommand,
|
|
63
|
+
group: "write",
|
|
64
|
+
summary: "Adopt unmanaged Codex config profiles into providers.json.",
|
|
65
|
+
usage: ["codexs migrate [--json] [--codex-dir <path>] [--merge|--overwrite]"],
|
|
66
|
+
details: [
|
|
67
|
+
"Reads config.toml profiles, collects complete provider records, then writes providers.json under managed backup flow.",
|
|
68
|
+
"TTY mode can collect missing provider details and choose merge or overwrite when providers.json already exists.",
|
|
69
|
+
"Migrate adopts only runtime profiles that already expose model, model_provider, matching base_url, and env_key.",
|
|
70
|
+
"Non-TTY and --json runs still fail fast because migrate profile selection and provider details remain interactive in this release.",
|
|
71
|
+
],
|
|
72
|
+
examples: ["codexs migrate", "codexs migrate --overwrite --json --codex-dir ~/.codex"],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
id: "setup",
|
|
76
|
+
tokens: ["setup"],
|
|
77
|
+
handler: handlers_1.handleRegisteredCommand,
|
|
78
|
+
group: "write",
|
|
79
|
+
summary: "Deprecated. Use init or migrate instead.",
|
|
80
|
+
usage: ["codexs setup"],
|
|
81
|
+
details: [
|
|
82
|
+
"setup no longer performs initialization or migration work.",
|
|
83
|
+
"Use init for AI-friendly idempotent providers.json initialization.",
|
|
84
|
+
"Use migrate for interactive adoption from existing config.toml profiles.",
|
|
85
|
+
],
|
|
86
|
+
examples: ["codexs help init", "codexs help migrate"],
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: "list",
|
|
90
|
+
tokens: ["list"],
|
|
91
|
+
handler: handlers_1.handleRegisteredCommand,
|
|
92
|
+
group: "read",
|
|
93
|
+
summary: "List configured providers from providers.json.",
|
|
94
|
+
usage: ["codexs list [--json] [--codex-dir <path>]"],
|
|
95
|
+
details: ["Reads providers.json and prints provider-to-profile mappings.", "Use --json for machine-readable automation output."],
|
|
96
|
+
examples: ["codexs list", "codexs list --json"],
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: "show",
|
|
100
|
+
tokens: ["show"],
|
|
101
|
+
handler: handlers_1.handleRegisteredCommand,
|
|
102
|
+
group: "read",
|
|
103
|
+
summary: "Show one provider record from providers.json.",
|
|
104
|
+
usage: ["codexs show <provider> [--json] [--codex-dir <path>]"],
|
|
105
|
+
details: [
|
|
106
|
+
"Human-readable output masks apiKey by default.",
|
|
107
|
+
"TTY mode can select a missing provider interactively before showing its record.",
|
|
108
|
+
"JSON mode returns the full provider payload for local automation.",
|
|
109
|
+
],
|
|
110
|
+
examples: ["codexs show packycode", "codexs show packycode --json"],
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: "current",
|
|
114
|
+
tokens: ["current"],
|
|
115
|
+
handler: handlers_1.handleRegisteredCommand,
|
|
116
|
+
group: "read",
|
|
117
|
+
summary: "Show the active top-level profile from config.toml.",
|
|
118
|
+
usage: ["codexs current [--json] [--codex-dir <path>]"],
|
|
119
|
+
details: ["Reads the currently active top-level profile.", "Fails when config.toml is missing or has no top-level profile."],
|
|
120
|
+
examples: ["codexs current", "codexs current --json"],
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
id: "status",
|
|
124
|
+
tokens: ["status"],
|
|
125
|
+
handler: handlers_1.handleRegisteredCommand,
|
|
126
|
+
group: "read",
|
|
127
|
+
summary: "Show a quick status summary for the local Codex directory.",
|
|
128
|
+
usage: ["codexs status [--json] [--codex-dir <path>]"],
|
|
129
|
+
details: [
|
|
130
|
+
"Reports file presence, current profile, and whether the live profile is mapped.",
|
|
131
|
+
"Surfaces config consistency signals without mutating any files.",
|
|
132
|
+
"Use doctor for deeper diagnostics.",
|
|
133
|
+
],
|
|
134
|
+
examples: ["codexs status", "codexs status --json --codex-dir ./.tmp-codex"],
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
id: "edit",
|
|
138
|
+
tokens: ["edit"],
|
|
139
|
+
handler: handlers_1.handleRegisteredCommand,
|
|
140
|
+
group: "write",
|
|
141
|
+
summary: "Update fields on a single provider record.",
|
|
142
|
+
usage: [
|
|
143
|
+
"codexs edit <provider> [--profile <name>] [--api-key <key>] [--base-url <url>] [--note <text>] [--tag <tag> ...] [--json] [--codex-dir <path>]",
|
|
144
|
+
"codexs edit <provider> --profile <name> --create-profile --model <name> --base-url <url>",
|
|
145
|
+
],
|
|
146
|
+
details: [
|
|
147
|
+
"Passed flags replace only the selected fields and keep the rest unchanged.",
|
|
148
|
+
"TTY mode can first select a provider, then prompt for fields when no editable options were provided.",
|
|
149
|
+
"Interactive tags use preset multi-select only.",
|
|
150
|
+
"When rebinding to a missing profile, --create-profile requires both --model and --base-url.",
|
|
151
|
+
"Backs up providers.json and config.toml before writing.",
|
|
152
|
+
],
|
|
153
|
+
examples: ["codexs edit packycode --note primary", "codexs edit packycode --tag daily --tag paid --json"],
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
id: "add",
|
|
157
|
+
tokens: ["add"],
|
|
158
|
+
handler: handlers_1.handleRegisteredCommand,
|
|
159
|
+
group: "write",
|
|
160
|
+
summary: "Add a provider with explicit flags or progressive TTY prompts.",
|
|
161
|
+
usage: [
|
|
162
|
+
"codexs add <provider> --profile <name> --api-key <key> [--base-url <url>] [--note <text>] [--tag <tag> ...]",
|
|
163
|
+
"codexs add <provider> --profile <name> --api-key <key> --create-profile --model <name> --base-url <url>",
|
|
164
|
+
"codexs add [--profile <name>] [--api-key <key>] [--base-url <url>] [--note <text>] [--tag <tag> ...]",
|
|
165
|
+
],
|
|
166
|
+
details: [
|
|
167
|
+
"Prompts only for missing required values when stdin/stdout are TTYs and --json is not set.",
|
|
168
|
+
"Interactive add collects provider name, profile, and apiKey progressively as plain text inputs.",
|
|
169
|
+
"Confirm API key when prompted interactively because the hidden prompt asks twice before writing.",
|
|
170
|
+
"Interactive tags use preset multi-select only.",
|
|
171
|
+
"Automation and non-TTY environments must pass all required values explicitly.",
|
|
172
|
+
"Creating a missing profile section requires --create-profile together with --model and --base-url.",
|
|
173
|
+
],
|
|
174
|
+
examples: ["codexs add packycode --profile packycode --api-key sk-xxx", "codexs add packycode --profile packycode", "codexs add"],
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
id: "switch",
|
|
178
|
+
tokens: ["switch"],
|
|
179
|
+
handler: handlers_1.handleRegisteredCommand,
|
|
180
|
+
group: "write",
|
|
181
|
+
summary: "Switch to a provider and rewrite the managed auth mirror.",
|
|
182
|
+
usage: ["codexs switch <provider> [--json] [--codex-dir <path>]"],
|
|
183
|
+
details: [
|
|
184
|
+
"When <provider> is omitted in a TTY, an interactive provider selector is shown.",
|
|
185
|
+
"When <provider> is passed explicitly, switch proceeds directly without extra confirmation.",
|
|
186
|
+
"Switch updates the active config profile and rewrites auth.json from the provider envKey/apiKey pair.",
|
|
187
|
+
"Backs up config.toml and auth.json, then rolls back on failure.",
|
|
188
|
+
],
|
|
189
|
+
examples: ["codexs switch freemodel", "codexs switch packycode --json"],
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
id: "remove",
|
|
193
|
+
tokens: ["remove"],
|
|
194
|
+
handler: handlers_1.handleRegisteredCommand,
|
|
195
|
+
group: "write",
|
|
196
|
+
summary: "Remove a provider from providers.json.",
|
|
197
|
+
usage: ["codexs remove <provider> [--force] [--switch-to <profile>] [--json] [--codex-dir <path>]"],
|
|
198
|
+
details: [
|
|
199
|
+
"TTY mode can select a missing provider interactively and always asks for deletion confirmation.",
|
|
200
|
+
"Non-TTY and --json automation still require both <provider> and --force.",
|
|
201
|
+
"The confirmation prompt includes the provider name and cancels without writing when declined.",
|
|
202
|
+
"When removing the last provider linked to the active profile, pass --switch-to first.",
|
|
203
|
+
"Backs up providers.json and config.toml before removing the record.",
|
|
204
|
+
],
|
|
205
|
+
examples: ["codexs remove freemodel", "codexs remove freemodel --force --json"],
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
id: "import",
|
|
209
|
+
tokens: ["import"],
|
|
210
|
+
handler: handlers_1.handleRegisteredCommand,
|
|
211
|
+
group: "write",
|
|
212
|
+
summary: "Replace providers.json with an external JSON file.",
|
|
213
|
+
usage: ["codexs import <file> [--json] [--codex-dir <path>]"],
|
|
214
|
+
details: [
|
|
215
|
+
"The file path is always explicit; there is no path wizard in this release.",
|
|
216
|
+
"TTY mode asks for confirmation before replacing or merging into the current providers registry.",
|
|
217
|
+
"Non-TTY and --json runs stay non-interactive and validate the file before writing.",
|
|
218
|
+
],
|
|
219
|
+
examples: ["codexs import ./providers.json", "codexs import ./providers.json --merge --json"],
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
id: "export",
|
|
223
|
+
tokens: ["export"],
|
|
224
|
+
handler: handlers_1.handleRegisteredCommand,
|
|
225
|
+
group: "write",
|
|
226
|
+
summary: "Export the current providers.json to another file.",
|
|
227
|
+
usage: ["codexs export <file> [--force] [--json] [--codex-dir <path>]"],
|
|
228
|
+
details: [
|
|
229
|
+
"The file path is always explicit; there is no path wizard in this release.",
|
|
230
|
+
"TTY mode asks before overwriting an existing target when --force is not supplied.",
|
|
231
|
+
"Non-TTY and --json automation require --force to overwrite an existing file.",
|
|
232
|
+
],
|
|
233
|
+
examples: ["codexs export ./providers-backup.json", "codexs export ./providers-backup.json --force"],
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
id: "backups-list",
|
|
237
|
+
tokens: ["backups", "list"],
|
|
238
|
+
handler: handlers_1.handleRegisteredCommand,
|
|
239
|
+
group: "recovery",
|
|
240
|
+
summary: "List historical backup entries.",
|
|
241
|
+
usage: ["codexs backups list [--json] [--codex-dir <path>]"],
|
|
242
|
+
details: [
|
|
243
|
+
"Enumerates backups/ manifests and returns them newest first.",
|
|
244
|
+
"Corrupt backup manifests are skipped with warnings instead of failing the whole command.",
|
|
245
|
+
],
|
|
246
|
+
examples: ["codexs backups list", "codexs backups list --json"],
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
id: "doctor",
|
|
250
|
+
tokens: ["doctor"],
|
|
251
|
+
handler: handlers_1.handleRegisteredCommand,
|
|
252
|
+
group: "recovery",
|
|
253
|
+
summary: "Run configuration and environment diagnostics.",
|
|
254
|
+
usage: ["codexs doctor [--json] [--codex-dir <path>]"],
|
|
255
|
+
details: ["Checks the expected config files, provider/profile consistency, and Codex CLI availability.", "Returns structured issues so users and AI agents can act on them."],
|
|
256
|
+
examples: ["codexs doctor", "codexs doctor --json"],
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
id: "rollback",
|
|
260
|
+
tokens: ["rollback"],
|
|
261
|
+
handler: handlers_1.handleRegisteredCommand,
|
|
262
|
+
group: "recovery",
|
|
263
|
+
summary: "Restore the latest managed backup or a specific backup id.",
|
|
264
|
+
usage: ["codexs rollback [<backup-id>] [--json] [--codex-dir <path>]"],
|
|
265
|
+
details: [
|
|
266
|
+
"TTY mode previews the target backup path and affected files, then asks for confirmation.",
|
|
267
|
+
"Non-TTY and --json runs stay non-interactive and execute immediately.",
|
|
268
|
+
"Use after a failed or undesired managed mutation.",
|
|
269
|
+
],
|
|
270
|
+
examples: ["codexs rollback", "codexs rollback 20260511-221457-switch --json"],
|
|
271
|
+
},
|
|
272
|
+
];
|
|
273
|
+
const COMMAND_NAME_SET = new Set(exports.COMMANDS.flatMap((command) => [command.id, command.tokens.join(" ")]));
|
|
274
|
+
const HELP_TOPIC_SET = new Set([
|
|
275
|
+
...exports.COMMANDS.map((command) => command.tokens.join(" ")),
|
|
276
|
+
...new Set(exports.COMMANDS.filter((command) => command.tokens.length > 1).map((command) => command.tokens[0])),
|
|
277
|
+
]);
|
|
278
|
+
/**
|
|
279
|
+
* Returns a defensive copy of the public command registry.
|
|
280
|
+
*/
|
|
281
|
+
function getCommandDefinitions() {
|
|
282
|
+
return exports.COMMANDS.slice();
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Returns stable internal command ids in registry order.
|
|
286
|
+
*/
|
|
287
|
+
function getKnownCommandIds() {
|
|
288
|
+
return exports.COMMANDS.map((command) => command.id);
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Resolves one command definition by its canonical internal id.
|
|
292
|
+
*/
|
|
293
|
+
function findCommandDefinition(commandId) {
|
|
294
|
+
if (commandId === "help" || commandId === "version") {
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
return exports.COMMANDS.find((command) => command.id === commandId) ?? null;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Resolves a command definition from its tokenized CLI spelling.
|
|
301
|
+
*/
|
|
302
|
+
function findCommandDefinitionByTokens(tokens) {
|
|
303
|
+
return exports.COMMANDS.find((command) => command.tokens.join(" ") === tokens.join(" ")) ?? null;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Matches argv against the longest registered token sequence first.
|
|
307
|
+
*/
|
|
308
|
+
function resolveCommandFromArgv(argv) {
|
|
309
|
+
// Nested commands such as "config show" must win over their shorter root tokens.
|
|
310
|
+
for (const command of exports.COMMANDS
|
|
311
|
+
.slice()
|
|
312
|
+
.sort((left, right) => right.tokens.length - left.tokens.length)) {
|
|
313
|
+
const candidate = argv.slice(0, command.tokens.length);
|
|
314
|
+
if (candidate.length === command.tokens.length && candidate.join(" ") === command.tokens.join(" ")) {
|
|
315
|
+
return {
|
|
316
|
+
definition: command,
|
|
317
|
+
consumedTokens: command.tokens.length,
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return {
|
|
322
|
+
definition: null,
|
|
323
|
+
consumedTokens: 0,
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Reports whether a name is reserved by either a command id or its public token form.
|
|
328
|
+
*/
|
|
329
|
+
function isKnownCommandName(commandName) {
|
|
330
|
+
return COMMAND_NAME_SET.has(commandName);
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Reports whether a help topic is recognized by the help renderer.
|
|
334
|
+
*/
|
|
335
|
+
function isKnownHelpTopic(topic) {
|
|
336
|
+
return HELP_TOPIC_SET.has(topic);
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Returns public command names exactly as they appear in help and examples.
|
|
340
|
+
*/
|
|
341
|
+
function getPublicCommandNames() {
|
|
342
|
+
return exports.COMMANDS.map((command) => command.tokens.join(" "));
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Returns nested command spellings for one root token such as "config" or "backups".
|
|
346
|
+
*/
|
|
347
|
+
function getNestedCommandTokens(rootToken) {
|
|
348
|
+
return exports.COMMANDS
|
|
349
|
+
.filter((command) => command.tokens.length > 1 && command.tokens[0] === rootToken)
|
|
350
|
+
.map((command) => command.tokens.join(" "));
|
|
351
|
+
}
|