@tjalve/cube-cli 0.1.0
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/LICENSE +21 -0
- package/README.md +39 -0
- package/dist/errors/index.d.ts +28 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +58 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/fixtures/cli.d.ts +4 -0
- package/dist/fixtures/cli.d.ts.map +1 -0
- package/dist/fixtures/cli.js +195 -0
- package/dist/fixtures/cli.js.map +1 -0
- package/dist/fixtures/metadata.d.ts +347 -0
- package/dist/fixtures/metadata.d.ts.map +1 -0
- package/dist/fixtures/metadata.js +372 -0
- package/dist/fixtures/metadata.js.map +1 -0
- package/dist/help/index.d.ts +24 -0
- package/dist/help/index.d.ts.map +1 -0
- package/dist/help/index.js +254 -0
- package/dist/help/index.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/metadata/define.d.ts +11 -0
- package/dist/metadata/define.d.ts.map +1 -0
- package/dist/metadata/define.js +125 -0
- package/dist/metadata/define.js.map +1 -0
- package/dist/metadata/index.d.ts +3 -0
- package/dist/metadata/index.d.ts.map +1 -0
- package/dist/metadata/index.js +2 -0
- package/dist/metadata/index.js.map +1 -0
- package/dist/metadata/types.d.ts +109 -0
- package/dist/metadata/types.d.ts.map +1 -0
- package/dist/metadata/types.js +2 -0
- package/dist/metadata/types.js.map +1 -0
- package/dist/mutation/index.d.ts +55 -0
- package/dist/mutation/index.d.ts.map +1 -0
- package/dist/mutation/index.js +162 -0
- package/dist/mutation/index.js.map +1 -0
- package/dist/output/index.d.ts +32 -0
- package/dist/output/index.d.ts.map +1 -0
- package/dist/output/index.js +94 -0
- package/dist/output/index.js.map +1 -0
- package/dist/prompts/index.d.ts +37 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +78 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/redaction/index.d.ts +10 -0
- package/dist/redaction/index.d.ts.map +1 -0
- package/dist/redaction/index.js +83 -0
- package/dist/redaction/index.js.map +1 -0
- package/dist/registry/index.d.ts +25 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +286 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/runtime/index.d.ts +69 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +581 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/schema/index.d.ts +122 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +208 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/terminal/index.d.ts +31 -0
- package/dist/terminal/index.d.ts.map +1 -0
- package/dist/terminal/index.js +118 -0
- package/dist/terminal/index.js.map +1 -0
- package/dist/testing/index.d.ts +85 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +293 -0
- package/dist/testing/index.js.map +1 -0
- package/package.json +107 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import { defineArgument, defineCommand, defineExample, defineExtensions, defineFlag, defineTopic } from "../metadata/index.js";
|
|
2
|
+
import { defineMutationMetadata, dryRunSupported, mutationCategories } from "../mutation/index.js";
|
|
3
|
+
import { createCommandRegistry } from "../registry/index.js";
|
|
4
|
+
const fixtureExtensions = defineExtensions({
|
|
5
|
+
fixture: true,
|
|
6
|
+
owner: "toolkit-tests",
|
|
7
|
+
nested: {
|
|
8
|
+
beta: 2,
|
|
9
|
+
alpha: 1
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
export const cacheTopic = defineTopic({
|
|
13
|
+
kind: "topic",
|
|
14
|
+
name: "cache",
|
|
15
|
+
description: "Commands for inspecting and maintaining a local cache.",
|
|
16
|
+
extensions: fixtureExtensions
|
|
17
|
+
});
|
|
18
|
+
export const cacheInspectCommand = defineCommand({
|
|
19
|
+
kind: "command",
|
|
20
|
+
name: "cache inspect",
|
|
21
|
+
description: "Inspect cache entries without changing local state.",
|
|
22
|
+
arguments: [
|
|
23
|
+
defineArgument({
|
|
24
|
+
name: "key",
|
|
25
|
+
description: "Cache key to inspect.",
|
|
26
|
+
required: false,
|
|
27
|
+
extensions: defineExtensions({
|
|
28
|
+
fixtureRole: "lookup-key"
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
],
|
|
32
|
+
flags: [
|
|
33
|
+
defineFlag({
|
|
34
|
+
name: "json",
|
|
35
|
+
description: "Render machine-readable JSON output.",
|
|
36
|
+
type: "boolean"
|
|
37
|
+
}),
|
|
38
|
+
defineFlag({
|
|
39
|
+
name: "output",
|
|
40
|
+
description: "Select the output format.",
|
|
41
|
+
type: "option",
|
|
42
|
+
options: ["human", "json"],
|
|
43
|
+
defaultValue: "human",
|
|
44
|
+
extensions: defineExtensions({
|
|
45
|
+
fixtureRole: "format-selector"
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
],
|
|
49
|
+
examples: [
|
|
50
|
+
defineExample({
|
|
51
|
+
description: "Inspect all cache entries.",
|
|
52
|
+
command: "fixture cache inspect"
|
|
53
|
+
})
|
|
54
|
+
],
|
|
55
|
+
output: {
|
|
56
|
+
formats: ["human", "json"],
|
|
57
|
+
defaultFormat: "human"
|
|
58
|
+
},
|
|
59
|
+
interactions: {
|
|
60
|
+
json: true,
|
|
61
|
+
noColor: true,
|
|
62
|
+
nonInteractive: true,
|
|
63
|
+
ttyPrompt: false
|
|
64
|
+
},
|
|
65
|
+
externalServices: [],
|
|
66
|
+
errors: [
|
|
67
|
+
{
|
|
68
|
+
kind: "cache-read-failed",
|
|
69
|
+
description: "The cache could not be read.",
|
|
70
|
+
exitCode: 2
|
|
71
|
+
}
|
|
72
|
+
],
|
|
73
|
+
exitCodes: [
|
|
74
|
+
{
|
|
75
|
+
code: 0,
|
|
76
|
+
category: "success",
|
|
77
|
+
description: "The command completed successfully."
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
code: 2,
|
|
81
|
+
category: "validation",
|
|
82
|
+
description: "The cache key or cache state was invalid."
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
extensions: fixtureExtensions
|
|
86
|
+
});
|
|
87
|
+
export const cacheClearCommand = defineCommand({
|
|
88
|
+
kind: "command",
|
|
89
|
+
name: "cache clear",
|
|
90
|
+
description: "Clear cache entries after showing the planned local file changes.",
|
|
91
|
+
aliases: ["cc"],
|
|
92
|
+
flags: [
|
|
93
|
+
defineFlag({
|
|
94
|
+
name: "dry-run",
|
|
95
|
+
description: "Show cache entries that would be removed without deleting them.",
|
|
96
|
+
type: "boolean"
|
|
97
|
+
}),
|
|
98
|
+
defineFlag({
|
|
99
|
+
name: "yes",
|
|
100
|
+
description: "Run without interactive confirmation.",
|
|
101
|
+
type: "boolean"
|
|
102
|
+
})
|
|
103
|
+
],
|
|
104
|
+
examples: [
|
|
105
|
+
defineExample({
|
|
106
|
+
description: "Preview cache cleanup.",
|
|
107
|
+
command: "fixture cache clear --dry-run"
|
|
108
|
+
})
|
|
109
|
+
],
|
|
110
|
+
output: {
|
|
111
|
+
formats: ["human", "json"],
|
|
112
|
+
defaultFormat: "human"
|
|
113
|
+
},
|
|
114
|
+
interactions: {
|
|
115
|
+
json: true,
|
|
116
|
+
dryRun: dryRunSupported(),
|
|
117
|
+
noColor: true,
|
|
118
|
+
nonInteractive: true,
|
|
119
|
+
ttyPrompt: true
|
|
120
|
+
},
|
|
121
|
+
mutation: defineMutationMetadata({
|
|
122
|
+
categories: mutationCategories("local-files"),
|
|
123
|
+
extensions: defineExtensions({
|
|
124
|
+
fixtureMutation: "cache-cleanup"
|
|
125
|
+
})
|
|
126
|
+
}),
|
|
127
|
+
exitCodes: [
|
|
128
|
+
{
|
|
129
|
+
code: 0,
|
|
130
|
+
category: "success",
|
|
131
|
+
description: "The command completed successfully."
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
code: 5,
|
|
135
|
+
category: "safety",
|
|
136
|
+
description: "The command was blocked by a safety policy."
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
extensions: fixtureExtensions
|
|
140
|
+
});
|
|
141
|
+
export const cacheInstallCommand = defineCommand({
|
|
142
|
+
kind: "command",
|
|
143
|
+
name: "cache install",
|
|
144
|
+
description: "Prepare dependency cache entries after showing supply-chain-sensitive checks.",
|
|
145
|
+
flags: [
|
|
146
|
+
defineFlag({
|
|
147
|
+
name: "dry-run",
|
|
148
|
+
description: "Show dependency cache changes without writing fixture state.",
|
|
149
|
+
type: "boolean"
|
|
150
|
+
}),
|
|
151
|
+
defineFlag({
|
|
152
|
+
name: "json",
|
|
153
|
+
description: "Render machine-readable JSON output.",
|
|
154
|
+
type: "boolean"
|
|
155
|
+
})
|
|
156
|
+
],
|
|
157
|
+
examples: [
|
|
158
|
+
defineExample({
|
|
159
|
+
description: "Preview dependency cache preparation.",
|
|
160
|
+
command: "fixture cache install --dry-run"
|
|
161
|
+
})
|
|
162
|
+
],
|
|
163
|
+
output: {
|
|
164
|
+
formats: ["human", "json"],
|
|
165
|
+
defaultFormat: "human"
|
|
166
|
+
},
|
|
167
|
+
interactions: {
|
|
168
|
+
json: true,
|
|
169
|
+
dryRun: dryRunSupported(),
|
|
170
|
+
noColor: true,
|
|
171
|
+
nonInteractive: true,
|
|
172
|
+
ttyPrompt: false
|
|
173
|
+
},
|
|
174
|
+
mutation: defineMutationMetadata({
|
|
175
|
+
categories: mutationCategories("dependency", "local-files"),
|
|
176
|
+
extensions: defineExtensions({
|
|
177
|
+
fixtureMutation: "dependency-cache"
|
|
178
|
+
})
|
|
179
|
+
}),
|
|
180
|
+
supplyChain: {
|
|
181
|
+
sensitive: true,
|
|
182
|
+
kinds: ["dependency", "package-manager"],
|
|
183
|
+
reason: "Dependency cache preparation depends on package-manager metadata supplied by the consuming package.",
|
|
184
|
+
extensions: defineExtensions({
|
|
185
|
+
fixtureSupplyChain: "dependency-cache"
|
|
186
|
+
})
|
|
187
|
+
},
|
|
188
|
+
errors: [
|
|
189
|
+
{
|
|
190
|
+
kind: "supply-chain-blocked",
|
|
191
|
+
description: "The dependency cache operation was blocked for supply-chain review.",
|
|
192
|
+
exitCode: 5
|
|
193
|
+
}
|
|
194
|
+
],
|
|
195
|
+
exitCodes: [
|
|
196
|
+
{
|
|
197
|
+
code: 0,
|
|
198
|
+
category: "success",
|
|
199
|
+
description: "The command completed successfully."
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
code: 5,
|
|
203
|
+
category: "safety",
|
|
204
|
+
description: "The command was blocked by supply-chain safety guidance."
|
|
205
|
+
}
|
|
206
|
+
],
|
|
207
|
+
extensions: fixtureExtensions
|
|
208
|
+
});
|
|
209
|
+
export const cacheValidateCommand = defineCommand({
|
|
210
|
+
kind: "command",
|
|
211
|
+
name: "cache validate",
|
|
212
|
+
description: "Validate cache configuration and report actionable failures.",
|
|
213
|
+
flags: [
|
|
214
|
+
defineFlag({
|
|
215
|
+
name: "json",
|
|
216
|
+
description: "Render machine-readable JSON output.",
|
|
217
|
+
type: "boolean"
|
|
218
|
+
})
|
|
219
|
+
],
|
|
220
|
+
examples: [
|
|
221
|
+
defineExample({
|
|
222
|
+
description: "Validate cache configuration.",
|
|
223
|
+
command: "fixture cache validate --json"
|
|
224
|
+
})
|
|
225
|
+
],
|
|
226
|
+
output: {
|
|
227
|
+
formats: ["human", "json"],
|
|
228
|
+
defaultFormat: "human"
|
|
229
|
+
},
|
|
230
|
+
interactions: {
|
|
231
|
+
json: true,
|
|
232
|
+
noColor: true,
|
|
233
|
+
nonInteractive: true,
|
|
234
|
+
ttyPrompt: false
|
|
235
|
+
},
|
|
236
|
+
errors: [
|
|
237
|
+
{
|
|
238
|
+
kind: "cache-config-invalid",
|
|
239
|
+
description: "The cache configuration failed validation.",
|
|
240
|
+
exitCode: 3
|
|
241
|
+
}
|
|
242
|
+
],
|
|
243
|
+
exitCodes: [
|
|
244
|
+
{
|
|
245
|
+
code: 0,
|
|
246
|
+
category: "success",
|
|
247
|
+
description: "The command completed successfully."
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
code: 3,
|
|
251
|
+
category: "validation",
|
|
252
|
+
description: "The cache configuration was invalid."
|
|
253
|
+
}
|
|
254
|
+
],
|
|
255
|
+
extensions: fixtureExtensions
|
|
256
|
+
});
|
|
257
|
+
export const cachePromptCommand = defineCommand({
|
|
258
|
+
kind: "command",
|
|
259
|
+
name: "cache prompt",
|
|
260
|
+
description: "Resolve a cache prompt through flags, defaults, or an interactive TTY.",
|
|
261
|
+
flags: [
|
|
262
|
+
defineFlag({
|
|
263
|
+
name: "value",
|
|
264
|
+
description: "Prompt value supplied by flags or config.",
|
|
265
|
+
type: "string"
|
|
266
|
+
}),
|
|
267
|
+
defineFlag({
|
|
268
|
+
name: "defaults",
|
|
269
|
+
description: "Use deterministic defaults without prompting.",
|
|
270
|
+
type: "boolean"
|
|
271
|
+
}),
|
|
272
|
+
defineFlag({
|
|
273
|
+
name: "yes",
|
|
274
|
+
description: "Accept the deterministic prompt default.",
|
|
275
|
+
type: "boolean"
|
|
276
|
+
}),
|
|
277
|
+
defineFlag({
|
|
278
|
+
name: "json",
|
|
279
|
+
description: "Render machine-readable JSON output.",
|
|
280
|
+
type: "boolean"
|
|
281
|
+
})
|
|
282
|
+
],
|
|
283
|
+
examples: [
|
|
284
|
+
defineExample({
|
|
285
|
+
description: "Resolve a prompt from flags.",
|
|
286
|
+
command: "fixture cache prompt --value alpha"
|
|
287
|
+
})
|
|
288
|
+
],
|
|
289
|
+
output: {
|
|
290
|
+
formats: ["human", "json"],
|
|
291
|
+
defaultFormat: "human"
|
|
292
|
+
},
|
|
293
|
+
interactions: {
|
|
294
|
+
json: true,
|
|
295
|
+
noColor: true,
|
|
296
|
+
nonInteractive: false,
|
|
297
|
+
ttyPrompt: true
|
|
298
|
+
},
|
|
299
|
+
errors: [
|
|
300
|
+
{
|
|
301
|
+
kind: "prompt-blocked",
|
|
302
|
+
description: "The prompt was blocked by non-interactive execution.",
|
|
303
|
+
exitCode: 2
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
kind: "prompt-cancelled",
|
|
307
|
+
description: "The prompt was cancelled before a value was supplied.",
|
|
308
|
+
exitCode: 2
|
|
309
|
+
}
|
|
310
|
+
],
|
|
311
|
+
exitCodes: [
|
|
312
|
+
{
|
|
313
|
+
code: 0,
|
|
314
|
+
category: "success",
|
|
315
|
+
description: "The command completed successfully."
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
code: 2,
|
|
319
|
+
category: "usage",
|
|
320
|
+
description: "The prompt could not run in the current execution mode."
|
|
321
|
+
}
|
|
322
|
+
],
|
|
323
|
+
extensions: fixtureExtensions
|
|
324
|
+
});
|
|
325
|
+
export const cacheExplodeCommand = defineCommand({
|
|
326
|
+
kind: "command",
|
|
327
|
+
name: "cache explode",
|
|
328
|
+
description: "Raise an unexpected fixture failure for runtime error tests.",
|
|
329
|
+
flags: [
|
|
330
|
+
defineFlag({
|
|
331
|
+
name: "json",
|
|
332
|
+
description: "Render machine-readable JSON output.",
|
|
333
|
+
type: "boolean"
|
|
334
|
+
})
|
|
335
|
+
],
|
|
336
|
+
examples: [
|
|
337
|
+
defineExample({
|
|
338
|
+
description: "Raise an unexpected fixture failure.",
|
|
339
|
+
command: "fixture cache explode --json"
|
|
340
|
+
})
|
|
341
|
+
],
|
|
342
|
+
output: {
|
|
343
|
+
formats: ["human", "json"],
|
|
344
|
+
defaultFormat: "human"
|
|
345
|
+
},
|
|
346
|
+
interactions: {
|
|
347
|
+
json: true,
|
|
348
|
+
noColor: true,
|
|
349
|
+
nonInteractive: true,
|
|
350
|
+
ttyPrompt: false
|
|
351
|
+
},
|
|
352
|
+
errors: [
|
|
353
|
+
{
|
|
354
|
+
kind: "unexpected-error",
|
|
355
|
+
description: "The command failed unexpectedly.",
|
|
356
|
+
exitCode: 70
|
|
357
|
+
}
|
|
358
|
+
],
|
|
359
|
+
exitCodes: [
|
|
360
|
+
{
|
|
361
|
+
code: 70,
|
|
362
|
+
category: "unexpected",
|
|
363
|
+
description: "The command failed unexpectedly."
|
|
364
|
+
}
|
|
365
|
+
],
|
|
366
|
+
extensions: fixtureExtensions
|
|
367
|
+
});
|
|
368
|
+
export const fixtureMetadata = createCommandRegistry({
|
|
369
|
+
topics: [cacheTopic],
|
|
370
|
+
commands: [cacheInspectCommand, cacheClearCommand, cacheInstallCommand, cacheValidateCommand, cachePromptCommand, cacheExplodeCommand]
|
|
371
|
+
});
|
|
372
|
+
//# sourceMappingURL=metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/fixtures/metadata.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CommandMetadata, TopicMetadata } from "../metadata/index.js";
|
|
2
|
+
import type { CommandRegistry } from "../registry/index.js";
|
|
3
|
+
export interface HelpRenderOptions {
|
|
4
|
+
readonly bin: string;
|
|
5
|
+
readonly packageVersion?: string | undefined;
|
|
6
|
+
readonly description?: string | undefined;
|
|
7
|
+
}
|
|
8
|
+
export interface HelpRequest {
|
|
9
|
+
readonly kind: "root" | "target";
|
|
10
|
+
readonly targetTokens: readonly string[];
|
|
11
|
+
}
|
|
12
|
+
export interface Suggestion {
|
|
13
|
+
readonly value: string;
|
|
14
|
+
readonly distance: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function normalizeHelpRequest(argv: readonly string[]): HelpRequest | undefined;
|
|
17
|
+
export declare function renderHelp(registry: CommandRegistry, request: HelpRequest, options: HelpRenderOptions): string;
|
|
18
|
+
export declare function renderRootHelp(registry: CommandRegistry, options: HelpRenderOptions): string;
|
|
19
|
+
export declare function renderTopicHelp(registry: CommandRegistry, topic: TopicMetadata, options: HelpRenderOptions): string;
|
|
20
|
+
export declare function renderCommandHelp(command: CommandMetadata, options: HelpRenderOptions): string;
|
|
21
|
+
export declare function suggestCommand(registry: CommandRegistry, input: string): Suggestion | undefined;
|
|
22
|
+
export declare function suggestFlag(command: CommandMetadata, input: string): Suggestion | undefined;
|
|
23
|
+
export declare function suggestValue(input: string, candidates: readonly string[]): Suggestion | undefined;
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/help/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,eAAe,EAAgB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC3G,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG5D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3C;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,WAAW,GAAG,SAAS,CAmBrF;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAgB9G;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAa5F;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAUnH;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAS9F;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAQ/F;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAK3F;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,GAAG,SAAS,CAgBjG"}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { findCommand, findTopic, listCommands, listTopics } from "../registry/index.js";
|
|
2
|
+
export function normalizeHelpRequest(argv) {
|
|
3
|
+
if (argv.length === 0) {
|
|
4
|
+
return { kind: "root", targetTokens: [] };
|
|
5
|
+
}
|
|
6
|
+
if (argv.length === 1 && argv[0] === "--help") {
|
|
7
|
+
return { kind: "root", targetTokens: [] };
|
|
8
|
+
}
|
|
9
|
+
if (argv[0] === "help") {
|
|
10
|
+
return argv.length === 1
|
|
11
|
+
? { kind: "root", targetTokens: [] }
|
|
12
|
+
: { kind: "target", targetTokens: trimAtFirstFlag(argv.slice(1)) };
|
|
13
|
+
}
|
|
14
|
+
if (argv.includes("--help")) {
|
|
15
|
+
return { kind: "target", targetTokens: trimAtFirstFlag(argv.filter((token) => token !== "--help")) };
|
|
16
|
+
}
|
|
17
|
+
if (argv.at(-1) === "help") {
|
|
18
|
+
return { kind: "target", targetTokens: trimAtFirstFlag(argv.slice(0, -1)) };
|
|
19
|
+
}
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
export function renderHelp(registry, request, options) {
|
|
23
|
+
if (request.kind === "root" || request.targetTokens.length === 0) {
|
|
24
|
+
return renderRootHelp(registry, options);
|
|
25
|
+
}
|
|
26
|
+
const target = request.targetTokens.join(" ");
|
|
27
|
+
const command = findCommand(registry, target);
|
|
28
|
+
if (command) {
|
|
29
|
+
return renderCommandHelp(command, options);
|
|
30
|
+
}
|
|
31
|
+
const topic = findTopic(registry, target);
|
|
32
|
+
if (topic) {
|
|
33
|
+
return renderTopicHelp(registry, topic, options);
|
|
34
|
+
}
|
|
35
|
+
const suggestion = suggestCommand(registry, target);
|
|
36
|
+
const hint = suggestion ? `\nDid you mean "${suggestion.value}"?` : "";
|
|
37
|
+
throw new Error(`Unknown help topic or command: ${target}${hint}`);
|
|
38
|
+
}
|
|
39
|
+
export function renderRootHelp(registry, options) {
|
|
40
|
+
return joinSections([
|
|
41
|
+
[options.bin, options.description ?? "Metadata-driven command-line interface."].join("\n"),
|
|
42
|
+
joinLines([
|
|
43
|
+
"Usage:",
|
|
44
|
+
` ${options.bin} <command> [flags]`,
|
|
45
|
+
` ${options.bin} help <command>`,
|
|
46
|
+
...(options.packageVersion ? [` ${options.bin} --version`] : [])
|
|
47
|
+
]),
|
|
48
|
+
renderNameDescriptionSection("Topics:", listTopics(registry)),
|
|
49
|
+
renderNameDescriptionSection("Commands:", listCommands(registry)),
|
|
50
|
+
"Help invocations never execute command handlers."
|
|
51
|
+
]);
|
|
52
|
+
}
|
|
53
|
+
export function renderTopicHelp(registry, topic, options) {
|
|
54
|
+
const prefix = `${topic.name} `;
|
|
55
|
+
const commands = listCommands(registry).filter((command) => command.name.startsWith(prefix));
|
|
56
|
+
return joinSections([
|
|
57
|
+
[topic.name, topic.description].join("\n"),
|
|
58
|
+
joinLines(["Usage:", ` ${options.bin} ${topic.name} <command> [flags]`, ` ${options.bin} help ${topic.name} <command>`]),
|
|
59
|
+
renderNameDescriptionSection("Commands:", commands),
|
|
60
|
+
renderTopicCommandDetails(commands),
|
|
61
|
+
"Help invocations never execute command handlers."
|
|
62
|
+
]);
|
|
63
|
+
}
|
|
64
|
+
export function renderCommandHelp(command, options) {
|
|
65
|
+
return joinSections([
|
|
66
|
+
[command.name, command.description].join("\n"),
|
|
67
|
+
joinLines(["Usage:", ` ${options.bin} ${command.name}${renderUsageSuffix(command)}`]),
|
|
68
|
+
renderArguments(command.arguments ?? []),
|
|
69
|
+
renderFlags(command.flags ?? []),
|
|
70
|
+
renderExamples(command.examples ?? []),
|
|
71
|
+
renderBehavior(command)
|
|
72
|
+
]);
|
|
73
|
+
}
|
|
74
|
+
export function suggestCommand(registry, input) {
|
|
75
|
+
const candidates = [
|
|
76
|
+
...listCommands(registry).map((command) => command.name),
|
|
77
|
+
...listCommands(registry).flatMap((command) => command.aliases ?? []),
|
|
78
|
+
...listTopics(registry).map((topic) => topic.name),
|
|
79
|
+
...listTopics(registry).flatMap((topic) => topic.aliases ?? [])
|
|
80
|
+
];
|
|
81
|
+
return suggestValue(input, candidates);
|
|
82
|
+
}
|
|
83
|
+
export function suggestFlag(command, input) {
|
|
84
|
+
const normalizedInput = input.startsWith("-") ? input : `--${input}`;
|
|
85
|
+
const candidates = (command.flags ?? []).flatMap(renderFlagTokens);
|
|
86
|
+
const suggestion = suggestValue(normalizedInput, candidates);
|
|
87
|
+
return suggestion ? { value: suggestion.value, distance: suggestion.distance } : undefined;
|
|
88
|
+
}
|
|
89
|
+
export function suggestValue(input, candidates) {
|
|
90
|
+
const normalizedInput = input.trim();
|
|
91
|
+
if (normalizedInput.length === 0) {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
const ranked = [...new Set(candidates)]
|
|
95
|
+
.map((candidate) => ({ value: candidate, distance: levenshteinDistance(normalizedInput, candidate) }))
|
|
96
|
+
.sort((left, right) => left.distance - right.distance || compareText(left.value, right.value));
|
|
97
|
+
const [best, secondBest] = ranked;
|
|
98
|
+
if (!best || best.distance > 3 || best.distance > Math.ceil(normalizedInput.length / 2)) {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
if (secondBest && secondBest.distance === best.distance) {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
return best;
|
|
105
|
+
}
|
|
106
|
+
function renderUsageSuffix(command) {
|
|
107
|
+
const args = (command.arguments ?? []).map((argument) => argument.required ? `<${argument.name}>` : `[${argument.name}]`);
|
|
108
|
+
const flags = (command.flags ?? []).map(renderFlagUsage);
|
|
109
|
+
const suffix = [...args, ...flags].join(" ");
|
|
110
|
+
return suffix.length === 0 ? "" : ` ${suffix}`;
|
|
111
|
+
}
|
|
112
|
+
function renderArguments(args) {
|
|
113
|
+
if (args.length === 0) {
|
|
114
|
+
return "Arguments:\n none";
|
|
115
|
+
}
|
|
116
|
+
return renderNameDescriptionSection("Arguments:", args.map((argument) => ({
|
|
117
|
+
name: argument.required ? `<${argument.name}>` : `[${argument.name}]`,
|
|
118
|
+
description: argument.description
|
|
119
|
+
})));
|
|
120
|
+
}
|
|
121
|
+
function renderFlags(flags) {
|
|
122
|
+
if (flags.length === 0) {
|
|
123
|
+
return "Flags:\n none";
|
|
124
|
+
}
|
|
125
|
+
return renderNameDescriptionSection("Flags:", flags.map((flag) => ({
|
|
126
|
+
name: `${renderFlagToken(flag)}${flag.type === "boolean" ? "" : " <value>"}`,
|
|
127
|
+
description: renderFlagDescription(flag)
|
|
128
|
+
})));
|
|
129
|
+
}
|
|
130
|
+
function renderFlagUsage(flag) {
|
|
131
|
+
if (flag.negatable === true) {
|
|
132
|
+
return `[--${flag.name}|--no-${flag.name}]`;
|
|
133
|
+
}
|
|
134
|
+
return `[${renderFlagToken(flag)}${flag.type === "boolean" ? "" : " <value>"}]`;
|
|
135
|
+
}
|
|
136
|
+
function renderFlagToken(flag) {
|
|
137
|
+
const positive = flag.short ? `-${flag.short}, --${flag.name}` : `--${flag.name}`;
|
|
138
|
+
return flag.negatable === true ? `${positive}, --no-${flag.name}` : positive;
|
|
139
|
+
}
|
|
140
|
+
function renderFlagTokens(flag) {
|
|
141
|
+
return [
|
|
142
|
+
`--${flag.name}`,
|
|
143
|
+
...(flag.negatable === true ? [`--no-${flag.name}`] : []),
|
|
144
|
+
...(flag.short ? [`-${flag.short}`] : []),
|
|
145
|
+
...(flag.aliases ?? []).flatMap((alias) => [`--${alias}`, ...(flag.negatable === true ? [`--no-${alias}`] : [])])
|
|
146
|
+
];
|
|
147
|
+
}
|
|
148
|
+
function renderFlagDescription(flag) {
|
|
149
|
+
const pieces = [flag.description];
|
|
150
|
+
if (flag.options && flag.options.length > 0) {
|
|
151
|
+
pieces.push(`options: ${flag.options.join(", ")}`);
|
|
152
|
+
}
|
|
153
|
+
if (flag.aliases && flag.aliases.length > 0) {
|
|
154
|
+
pieces.push(`aliases: ${flag.aliases.map((alias) => `--${alias}`).join(", ")}`);
|
|
155
|
+
}
|
|
156
|
+
return pieces.join("; ");
|
|
157
|
+
}
|
|
158
|
+
function renderExamples(examples) {
|
|
159
|
+
if (examples.length === 0) {
|
|
160
|
+
return "Examples:\n none";
|
|
161
|
+
}
|
|
162
|
+
return joinLines(["Examples:", ...examples.map((example) => ` ${example.command} # ${example.description}`)]);
|
|
163
|
+
}
|
|
164
|
+
function renderBehavior(command) {
|
|
165
|
+
const mutationCategories = command.mutation?.categories ?? [];
|
|
166
|
+
return joinLines([
|
|
167
|
+
"Behavior:",
|
|
168
|
+
` JSON output: ${command.interactions?.json ? "supported" : "not declared"}`,
|
|
169
|
+
` Dry run: ${renderDryRun(command)}`,
|
|
170
|
+
` Mutation: ${mutationCategories.length === 0 ? "none" : mutationCategories.join(", ")}`,
|
|
171
|
+
` Supply chain: ${renderSupplyChain(command)}`
|
|
172
|
+
]);
|
|
173
|
+
}
|
|
174
|
+
function renderTopicCommandDetails(commands) {
|
|
175
|
+
if (commands.length === 0) {
|
|
176
|
+
return "Command details:\n none";
|
|
177
|
+
}
|
|
178
|
+
return joinLines([
|
|
179
|
+
"Command details:",
|
|
180
|
+
...commands.map((command) => {
|
|
181
|
+
const flagCount = command.flags?.length ?? 0;
|
|
182
|
+
const argumentCount = command.arguments?.length ?? 0;
|
|
183
|
+
const exampleCount = command.examples?.length ?? 0;
|
|
184
|
+
const mutationCategories = command.mutation?.categories ?? [];
|
|
185
|
+
const mutation = mutationCategories.length === 0 ? "none" : mutationCategories.join(", ");
|
|
186
|
+
const dryRun = renderDryRun(command);
|
|
187
|
+
const json = command.interactions?.json ? "supported" : "not declared";
|
|
188
|
+
return ` ${command.name}: args=${argumentCount}, flags=${flagCount}, examples=${exampleCount}, json=${json}, dry-run=${dryRun}, mutation=${mutation}, supply-chain=${renderSupplyChain(command)}`;
|
|
189
|
+
})
|
|
190
|
+
]);
|
|
191
|
+
}
|
|
192
|
+
function renderDryRun(command) {
|
|
193
|
+
const dryRun = command.interactions?.dryRun;
|
|
194
|
+
if (!dryRun) {
|
|
195
|
+
return "not declared";
|
|
196
|
+
}
|
|
197
|
+
return dryRun.supported ? "supported" : `unsupported (${dryRun.reason})`;
|
|
198
|
+
}
|
|
199
|
+
function renderSupplyChain(command) {
|
|
200
|
+
const supplyChain = command.supplyChain;
|
|
201
|
+
if (supplyChain?.sensitive !== true) {
|
|
202
|
+
return "standard";
|
|
203
|
+
}
|
|
204
|
+
const kinds = supplyChain.kinds && supplyChain.kinds.length > 0 ? [...new Set(supplyChain.kinds)].sort(compareText).join(", ") : "unspecified";
|
|
205
|
+
return `sensitive (${kinds})${supplyChain.reason ? ` — ${supplyChain.reason}` : ""}`;
|
|
206
|
+
}
|
|
207
|
+
function renderNameDescriptionSection(title, entries) {
|
|
208
|
+
if (entries.length === 0) {
|
|
209
|
+
return `${title}\n none`;
|
|
210
|
+
}
|
|
211
|
+
const width = Math.max(...entries.map((entry) => entry.name.length));
|
|
212
|
+
return joinLines([title, ...entries.map((entry) => ` ${entry.name.padEnd(width)} ${entry.description}`)]);
|
|
213
|
+
}
|
|
214
|
+
function trimAtFirstFlag(tokens) {
|
|
215
|
+
const flagIndex = tokens.findIndex((token) => token.startsWith("-"));
|
|
216
|
+
return flagIndex === -1 ? tokens : tokens.slice(0, flagIndex);
|
|
217
|
+
}
|
|
218
|
+
function levenshteinDistance(left, right) {
|
|
219
|
+
if (left === right) {
|
|
220
|
+
return 0;
|
|
221
|
+
}
|
|
222
|
+
if (left.length < right.length) {
|
|
223
|
+
return levenshteinDistance(right, left);
|
|
224
|
+
}
|
|
225
|
+
if (right.length === 0) {
|
|
226
|
+
return left.length;
|
|
227
|
+
}
|
|
228
|
+
let previousRow = Array.from({ length: right.length + 1 }, (_, index) => index);
|
|
229
|
+
for (let leftIndex = 1; leftIndex <= left.length; leftIndex += 1) {
|
|
230
|
+
const currentRow = [leftIndex];
|
|
231
|
+
for (let rightIndex = 1; rightIndex <= right.length; rightIndex += 1) {
|
|
232
|
+
const substitutionCost = left[leftIndex - 1] === right[rightIndex - 1] ? 0 : 1;
|
|
233
|
+
const insertion = (currentRow[rightIndex - 1] ?? Number.POSITIVE_INFINITY) + 1;
|
|
234
|
+
const deletion = (previousRow[rightIndex] ?? Number.POSITIVE_INFINITY) + 1;
|
|
235
|
+
const substitution = (previousRow[rightIndex - 1] ?? Number.POSITIVE_INFINITY) + substitutionCost;
|
|
236
|
+
currentRow[rightIndex] = Math.min(insertion, deletion, substitution);
|
|
237
|
+
}
|
|
238
|
+
previousRow = currentRow;
|
|
239
|
+
}
|
|
240
|
+
return previousRow[right.length] ?? left.length;
|
|
241
|
+
}
|
|
242
|
+
function compareText(left, right) {
|
|
243
|
+
if (left === right) {
|
|
244
|
+
return 0;
|
|
245
|
+
}
|
|
246
|
+
return left < right ? -1 : 1;
|
|
247
|
+
}
|
|
248
|
+
function joinSections(sections) {
|
|
249
|
+
return `${sections.join("\n\n")}\n`;
|
|
250
|
+
}
|
|
251
|
+
function joinLines(lines) {
|
|
252
|
+
return lines.join("\n");
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=index.js.map
|