@skillit/cli 0.4.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 +44 -0
- package/dist/audit.d.ts +14 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +101 -0
- package/dist/audit.js.map +1 -0
- package/dist/correlator.d.ts +21 -0
- package/dist/correlator.d.ts.map +1 -0
- package/dist/correlator.js +69 -0
- package/dist/correlator.js.map +1 -0
- package/dist/extract.d.ts +37 -0
- package/dist/extract.d.ts.map +1 -0
- package/dist/extract.js +133 -0
- package/dist/extract.js.map +1 -0
- package/dist/help-parser.d.ts +17 -0
- package/dist/help-parser.d.ts.map +1 -0
- package/dist/help-parser.js +314 -0
- package/dist/help-parser.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/introspect-commander.d.ts +18 -0
- package/dist/introspect-commander.d.ts.map +1 -0
- package/dist/introspect-commander.js +96 -0
- package/dist/introspect-commander.js.map +1 -0
- package/dist/options-jsdoc.d.ts +10 -0
- package/dist/options-jsdoc.d.ts.map +1 -0
- package/dist/options-jsdoc.js +12 -0
- package/dist/options-jsdoc.js.map +1 -0
- package/dist/program-loader.d.ts +20 -0
- package/dist/program-loader.d.ts.map +1 -0
- package/dist/program-loader.js +90 -0
- package/dist/program-loader.js.map +1 -0
- package/dist/refine-source.d.ts +32 -0
- package/dist/refine-source.d.ts.map +1 -0
- package/dist/refine-source.js +147 -0
- package/dist/refine-source.js.map +1 -0
- package/package.json +61 -0
- package/skills/skillit-cli-docs/SKILL.md +26 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse standard `--help` text output into an {@link ExtractedConfigSurface}.
|
|
3
|
+
*
|
|
4
|
+
* This is the framework-agnostic fallback used when runtime introspection of a
|
|
5
|
+
* commander/yargs program is not available.
|
|
6
|
+
*
|
|
7
|
+
* @param text Raw text emitted by `program --help`
|
|
8
|
+
* @param commandName Canonical name for this surface (e.g. `"generate"`)
|
|
9
|
+
*
|
|
10
|
+
* @category Fallback
|
|
11
|
+
* @useWhen
|
|
12
|
+
* - Runtime introspection is unavailable (no access to the program object)
|
|
13
|
+
* - The CLI uses a framework other than Commander (yargs, oclif, custom)
|
|
14
|
+
*/
|
|
15
|
+
export function parseHelpOutput(text, commandName) {
|
|
16
|
+
if (!text.trim()) {
|
|
17
|
+
return {
|
|
18
|
+
name: commandName,
|
|
19
|
+
description: '',
|
|
20
|
+
sourceType: 'cli',
|
|
21
|
+
options: [],
|
|
22
|
+
arguments: []
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const lines = text.split('\n');
|
|
26
|
+
let usageString;
|
|
27
|
+
let description = '';
|
|
28
|
+
let inOptionsBlock = false;
|
|
29
|
+
let inArgumentsBlock = false;
|
|
30
|
+
const options = [];
|
|
31
|
+
const args = [];
|
|
32
|
+
const argumentDescriptions = new Map();
|
|
33
|
+
// Track whether we have seen the first non-usage, non-blank line for
|
|
34
|
+
// the description. We stop collecting description lines once we hit an
|
|
35
|
+
// options block or another section header.
|
|
36
|
+
let descriptionCandidateIndex = -1;
|
|
37
|
+
for (let i = 0; i < lines.length; i++) {
|
|
38
|
+
const raw = lines[i] ?? '';
|
|
39
|
+
const trimmed = raw.trim();
|
|
40
|
+
// -----------------------------------------------------------------------
|
|
41
|
+
// Usage line
|
|
42
|
+
// -----------------------------------------------------------------------
|
|
43
|
+
if (trimmed.startsWith('Usage:')) {
|
|
44
|
+
usageString = trimmed.slice('Usage:'.length).trim();
|
|
45
|
+
args.push(...parsePositionalArgs(usageString));
|
|
46
|
+
inOptionsBlock = false;
|
|
47
|
+
descriptionCandidateIndex = i + 1; // description may follow
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
// -----------------------------------------------------------------------
|
|
51
|
+
// Options block header
|
|
52
|
+
// -----------------------------------------------------------------------
|
|
53
|
+
if (/^Options\s*:/i.test(trimmed) || trimmed === 'Options') {
|
|
54
|
+
inOptionsBlock = true;
|
|
55
|
+
inArgumentsBlock = false;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (/^Arguments\s*:/i.test(trimmed) || trimmed === 'Arguments') {
|
|
59
|
+
inOptionsBlock = false;
|
|
60
|
+
inArgumentsBlock = true;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
// -----------------------------------------------------------------------
|
|
64
|
+
// Any other section header (Arguments:, Commands:, Examples:, …) ends
|
|
65
|
+
// the options block and description collection.
|
|
66
|
+
// -----------------------------------------------------------------------
|
|
67
|
+
if (/^[A-Z][A-Za-z ]+:/.test(trimmed) && !trimmed.startsWith('-')) {
|
|
68
|
+
inOptionsBlock = false;
|
|
69
|
+
inArgumentsBlock = false;
|
|
70
|
+
descriptionCandidateIndex = -1;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
// -----------------------------------------------------------------------
|
|
74
|
+
// Description: first non-empty line after Usage that is not a section
|
|
75
|
+
// -----------------------------------------------------------------------
|
|
76
|
+
if (!inOptionsBlock &&
|
|
77
|
+
description === '' &&
|
|
78
|
+
descriptionCandidateIndex >= 0 &&
|
|
79
|
+
i === descriptionCandidateIndex &&
|
|
80
|
+
trimmed !== '' &&
|
|
81
|
+
!trimmed.startsWith('-')) {
|
|
82
|
+
description = trimmed;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
// Advance the candidate index over blank lines between Usage and desc
|
|
86
|
+
if (!inOptionsBlock &&
|
|
87
|
+
description === '' &&
|
|
88
|
+
descriptionCandidateIndex >= 0 &&
|
|
89
|
+
i === descriptionCandidateIndex &&
|
|
90
|
+
trimmed === '') {
|
|
91
|
+
descriptionCandidateIndex++;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
// -----------------------------------------------------------------------
|
|
95
|
+
// Option line inside Options block
|
|
96
|
+
// -----------------------------------------------------------------------
|
|
97
|
+
if (inOptionsBlock && trimmed.startsWith('-')) {
|
|
98
|
+
const opt = parseOptionLine(raw);
|
|
99
|
+
if (opt) {
|
|
100
|
+
options.push(opt);
|
|
101
|
+
}
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (inArgumentsBlock) {
|
|
105
|
+
const arg = parseArgumentLine(raw);
|
|
106
|
+
if (arg) {
|
|
107
|
+
argumentDescriptions.set(normalizeArgumentName(arg.name), arg.description);
|
|
108
|
+
if (!args.some((existing) => normalizeArgumentName(existing.name) === normalizeArgumentName(arg.name))) {
|
|
109
|
+
args.push({
|
|
110
|
+
name: arg.name,
|
|
111
|
+
description: arg.description,
|
|
112
|
+
required: arg.required,
|
|
113
|
+
variadic: arg.variadic
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
for (const arg of args) {
|
|
120
|
+
const descriptionForArg = argumentDescriptions.get(normalizeArgumentName(arg.name));
|
|
121
|
+
if (descriptionForArg) {
|
|
122
|
+
arg.description = descriptionForArg;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
name: commandName,
|
|
127
|
+
description,
|
|
128
|
+
sourceType: 'cli',
|
|
129
|
+
...(usageString !== undefined ? { usage: usageString } : {}),
|
|
130
|
+
options,
|
|
131
|
+
arguments: args
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
// Internal helpers
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
/**
|
|
138
|
+
* Parse positional arguments from a usage string.
|
|
139
|
+
*
|
|
140
|
+
* Recognises:
|
|
141
|
+
* `<required-arg>` → required, non-variadic
|
|
142
|
+
* `[optional-arg]` → optional, non-variadic
|
|
143
|
+
* `<arg...>` / `<...arg>` / `[arg...]` → variadic variants
|
|
144
|
+
*
|
|
145
|
+
* Flags (`-f` / `--flag`) and meta-tokens like `[options]` / `[command]` are
|
|
146
|
+
* ignored.
|
|
147
|
+
*/
|
|
148
|
+
function parsePositionalArgs(usage) {
|
|
149
|
+
const result = [];
|
|
150
|
+
// Match <name> or [name] tokens, capturing the inner text
|
|
151
|
+
const re = /(<([^>]+)>|\[([^\]]+)\])/g;
|
|
152
|
+
let match;
|
|
153
|
+
while ((match = re.exec(usage)) !== null) {
|
|
154
|
+
const full = match[0];
|
|
155
|
+
const inner = (match[2] ?? match[3] ?? '').trim();
|
|
156
|
+
// Skip meta-placeholders that aren't real positional args
|
|
157
|
+
if (/^options?$/i.test(inner) || /^commands?$/i.test(inner)) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
// Skip flag-like tokens (shouldn't appear here, but be defensive)
|
|
161
|
+
if (inner.startsWith('-')) {
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
const required = full.startsWith('<');
|
|
165
|
+
const variadic = inner.endsWith('...') || inner.startsWith('...');
|
|
166
|
+
const name = inner.replace(/\.{3}/g, '').trim();
|
|
167
|
+
result.push({
|
|
168
|
+
name,
|
|
169
|
+
description: '',
|
|
170
|
+
required,
|
|
171
|
+
variadic
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
return result;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Parse a single option line from a `--help` block.
|
|
178
|
+
*
|
|
179
|
+
* Handles formats:
|
|
180
|
+
* `-c, --config <path> Description text (required)`
|
|
181
|
+
* `--dry-run Preview mode (default: false)`
|
|
182
|
+
* ` --verbose Verbose output`
|
|
183
|
+
*
|
|
184
|
+
* Returns `null` if the line should be skipped (e.g. `-h, --help` or
|
|
185
|
+
* `--version`).
|
|
186
|
+
*/
|
|
187
|
+
function parseOptionLine(raw) {
|
|
188
|
+
const trimmed = raw.trim();
|
|
189
|
+
// -------------------------------------------------------------------------
|
|
190
|
+
// Extract flags portion vs description portion.
|
|
191
|
+
//
|
|
192
|
+
// Flags appear at the start; description follows after ≥2 spaces (or a tab).
|
|
193
|
+
// We split on the first run of 2+ spaces after the flags/arg portion.
|
|
194
|
+
// -------------------------------------------------------------------------
|
|
195
|
+
// 1. Strip leading whitespace
|
|
196
|
+
// 2. Match the flags+arg group: everything up to 2+ spaces or tab
|
|
197
|
+
const flagsAndRest = trimmed.match(/^(-[^\s].*?)(?:\s{2,}|\t)(.*)$/) ?? null;
|
|
198
|
+
let flagsPart;
|
|
199
|
+
let descPart;
|
|
200
|
+
if (flagsAndRest) {
|
|
201
|
+
flagsPart = (flagsAndRest[1] ?? '').trim();
|
|
202
|
+
descPart = (flagsAndRest[2] ?? '').trim();
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
// No description separator found — the whole trimmed line is the flags
|
|
206
|
+
flagsPart = trimmed;
|
|
207
|
+
descPart = '';
|
|
208
|
+
}
|
|
209
|
+
// -------------------------------------------------------------------------
|
|
210
|
+
// Parse flags: optional short flag, long flag, optional argument
|
|
211
|
+
// -c, --config <path>
|
|
212
|
+
// --dry-run
|
|
213
|
+
// -o, --out <dir>
|
|
214
|
+
// -------------------------------------------------------------------------
|
|
215
|
+
let cliShort;
|
|
216
|
+
let cliFlag;
|
|
217
|
+
let argName; // <arg> after the flag
|
|
218
|
+
// Match short flag
|
|
219
|
+
const shortMatch = flagsPart.match(/^(-[a-zA-Z]),?\s*/);
|
|
220
|
+
if (shortMatch) {
|
|
221
|
+
cliShort = shortMatch[1];
|
|
222
|
+
flagsPart = flagsPart.slice(shortMatch[0].length);
|
|
223
|
+
}
|
|
224
|
+
// Match long flag with optional required/optional value:
|
|
225
|
+
// --config <path>
|
|
226
|
+
// --config [path]
|
|
227
|
+
const longMatch = flagsPart.match(/^(--[a-zA-Z][\w-]*)(?:\s+(?:<([^>]+)>|\[([^\]]+)\]))?/);
|
|
228
|
+
if (!longMatch) {
|
|
229
|
+
// No long flag found — not a valid option line
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
cliFlag = longMatch[1];
|
|
233
|
+
argName = longMatch[2] ?? longMatch[3]; // undefined when flag is boolean
|
|
234
|
+
// -------------------------------------------------------------------------
|
|
235
|
+
// Skip internal / noise flags
|
|
236
|
+
// -------------------------------------------------------------------------
|
|
237
|
+
if (cliFlag === '--help' || cliFlag === '--version') {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
if (cliShort === '-h' || cliShort === '-V') {
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
// -------------------------------------------------------------------------
|
|
244
|
+
// Extract default value from description: (default: value)
|
|
245
|
+
// -------------------------------------------------------------------------
|
|
246
|
+
let defaultValue;
|
|
247
|
+
const defaultMatch = descPart.match(/\(default:\s*([^)]+)\)/i);
|
|
248
|
+
if (defaultMatch) {
|
|
249
|
+
defaultValue = defaultMatch[1]?.trim();
|
|
250
|
+
descPart = descPart.replace(defaultMatch[0], '').trim();
|
|
251
|
+
}
|
|
252
|
+
// -------------------------------------------------------------------------
|
|
253
|
+
// Detect required flag from description: (required)
|
|
254
|
+
// -------------------------------------------------------------------------
|
|
255
|
+
let required = false;
|
|
256
|
+
const requiredMatch = descPart.match(/\(required\)/i);
|
|
257
|
+
if (requiredMatch) {
|
|
258
|
+
required = true;
|
|
259
|
+
descPart = descPart.replace(requiredMatch[0], '').trim();
|
|
260
|
+
}
|
|
261
|
+
// Clean up any trailing punctuation left after stripping annotations
|
|
262
|
+
descPart = descPart.replace(/\s+$/, '');
|
|
263
|
+
// -------------------------------------------------------------------------
|
|
264
|
+
// Infer type: boolean when no <arg>, string otherwise
|
|
265
|
+
// -------------------------------------------------------------------------
|
|
266
|
+
const type = argName ? 'string' : 'boolean';
|
|
267
|
+
// -------------------------------------------------------------------------
|
|
268
|
+
// Derive canonical name from long flag (strip leading --)
|
|
269
|
+
// -------------------------------------------------------------------------
|
|
270
|
+
const name = cliFlag ? cliFlag.replace(/^--/, '') : '';
|
|
271
|
+
const option = {
|
|
272
|
+
name,
|
|
273
|
+
cliFlag,
|
|
274
|
+
type,
|
|
275
|
+
description: descPart,
|
|
276
|
+
required
|
|
277
|
+
};
|
|
278
|
+
if (cliShort !== undefined) {
|
|
279
|
+
option.cliShort = cliShort;
|
|
280
|
+
}
|
|
281
|
+
if (defaultValue !== undefined) {
|
|
282
|
+
option.defaultValue = defaultValue;
|
|
283
|
+
}
|
|
284
|
+
return option;
|
|
285
|
+
}
|
|
286
|
+
function parseArgumentLine(raw) {
|
|
287
|
+
const trimmed = raw.trim();
|
|
288
|
+
if (trimmed.length === 0 || trimmed.startsWith('-')) {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
const match = trimmed.match(/^([<[.\]>\w-]+)\s{2,}(.*)$/);
|
|
292
|
+
if (!match) {
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
const token = (match[1] ?? '').trim();
|
|
296
|
+
const name = normalizeArgumentName(token);
|
|
297
|
+
const description = (match[2] ?? '').trim();
|
|
298
|
+
if (name.length === 0) {
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
301
|
+
return {
|
|
302
|
+
name,
|
|
303
|
+
description,
|
|
304
|
+
required: token.startsWith('<'),
|
|
305
|
+
variadic: token.includes('...')
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
function normalizeArgumentName(name) {
|
|
309
|
+
return name
|
|
310
|
+
.replace(/[<>[\]]/g, '')
|
|
311
|
+
.replace(/\.{3}/g, '')
|
|
312
|
+
.trim();
|
|
313
|
+
}
|
|
314
|
+
//# sourceMappingURL=help-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help-parser.js","sourceRoot":"","sources":["../src/help-parser.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI extraction for commander/yargs programs.
|
|
3
|
+
*
|
|
4
|
+
* Provides a three-phase pipeline for extracting structured skill data from CLI tools:
|
|
5
|
+
* 1. **Introspect** — walk a Commander program tree to extract commands, options, and arguments
|
|
6
|
+
* 2. **Parse** — fallback: parse `--help` text output when runtime introspection is unavailable
|
|
7
|
+
* 3. **Correlate** — merge JSDoc metadata from typed config interfaces into CLI option metadata
|
|
8
|
+
*
|
|
9
|
+
* The result is an `ExtractedSkill` that can be rendered by `@skillit/core`.
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* Commander introspection is preferred over help-text parsing because it captures
|
|
13
|
+
* default values, variadic arguments, and required/optional distinctions precisely.
|
|
14
|
+
* Help-text parsing is a best-effort fallback with known limitations around multi-line
|
|
15
|
+
* descriptions and non-standard help formatting.
|
|
16
|
+
*
|
|
17
|
+
* @packageDocumentation
|
|
18
|
+
*/
|
|
19
|
+
export { introspectCommander } from './introspect-commander.js';
|
|
20
|
+
export { parseHelpOutput } from './help-parser.js';
|
|
21
|
+
export { correlateFlags } from './correlator.js';
|
|
22
|
+
export { runCliAudit } from './audit.js';
|
|
23
|
+
export { extractCliSkill, writeCliSkill } from './extract.js';
|
|
24
|
+
export type { CliExtractionOptions, CliWriteOptions } from './extract.js';
|
|
25
|
+
export type { CliAuditIssue } from './audit.js';
|
|
26
|
+
export { loadProgram } from './program-loader.js';
|
|
27
|
+
export type { LoadProgramOptions } from './program-loader.js';
|
|
28
|
+
export { readOptionsTags } from './options-jsdoc.js';
|
|
29
|
+
export { CliRefineSource } from './refine-source.js';
|
|
30
|
+
export type { CliRefineSourceOptions } from './refine-source.js';
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC9D,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC1E,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI extraction for commander/yargs programs.
|
|
3
|
+
*
|
|
4
|
+
* Provides a three-phase pipeline for extracting structured skill data from CLI tools:
|
|
5
|
+
* 1. **Introspect** — walk a Commander program tree to extract commands, options, and arguments
|
|
6
|
+
* 2. **Parse** — fallback: parse `--help` text output when runtime introspection is unavailable
|
|
7
|
+
* 3. **Correlate** — merge JSDoc metadata from typed config interfaces into CLI option metadata
|
|
8
|
+
*
|
|
9
|
+
* The result is an `ExtractedSkill` that can be rendered by `@skillit/core`.
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* Commander introspection is preferred over help-text parsing because it captures
|
|
13
|
+
* default values, variadic arguments, and required/optional distinctions precisely.
|
|
14
|
+
* Help-text parsing is a best-effort fallback with known limitations around multi-line
|
|
15
|
+
* descriptions and non-standard help formatting.
|
|
16
|
+
*
|
|
17
|
+
* @packageDocumentation
|
|
18
|
+
*/
|
|
19
|
+
export { introspectCommander } from './introspect-commander.js';
|
|
20
|
+
export { parseHelpOutput } from './help-parser.js';
|
|
21
|
+
export { correlateFlags } from './correlator.js';
|
|
22
|
+
export { runCliAudit } from './audit.js';
|
|
23
|
+
export { extractCliSkill, writeCliSkill } from './extract.js';
|
|
24
|
+
export { loadProgram } from './program-loader.js';
|
|
25
|
+
export { readOptionsTags } from './options-jsdoc.js';
|
|
26
|
+
export { CliRefineSource } from './refine-source.js';
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG9D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ExtractedConfigSurface } from '@skillit/core';
|
|
2
|
+
/**
|
|
3
|
+
* Introspects a commander Program object and extracts all top-level command
|
|
4
|
+
* definitions as ExtractedConfigSurface[].
|
|
5
|
+
*
|
|
6
|
+
* @param program - A commander `Command` instance (typed as `any` to avoid
|
|
7
|
+
* a hard dependency on the commander package at the call site).
|
|
8
|
+
* @returns An array of extracted config surfaces, one per top-level command.
|
|
9
|
+
* Returns an empty array if the program has no subcommands.
|
|
10
|
+
*
|
|
11
|
+
* @category Commander
|
|
12
|
+
* @useWhen
|
|
13
|
+
* - You have a Commander program and want structured option/argument extraction with full fidelity
|
|
14
|
+
* @avoidWhen
|
|
15
|
+
* - Your CLI uses yargs, oclif, or another framework — use parseHelpOutput as a fallback instead
|
|
16
|
+
*/
|
|
17
|
+
export declare function introspectCommander(program: any): ExtractedConfigSurface[];
|
|
18
|
+
//# sourceMappingURL=introspect-commander.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"introspect-commander.d.ts","sourceRoot":"","sources":["../src/introspect-commander.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EAGvB,MAAM,eAAe,CAAC;AA8FvB;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,GAAG,GAAG,sBAAsB,EAAE,CAI1E"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a kebab-case string to camelCase.
|
|
3
|
+
* e.g. "output-dir" → "outputDir"
|
|
4
|
+
*/
|
|
5
|
+
function kebabToCamelCase(str) {
|
|
6
|
+
return str.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Infers the type of a CLI option from its flags string.
|
|
10
|
+
* If the flags contain `<` or `[`, it accepts a value → 'string'.
|
|
11
|
+
* Otherwise it is a boolean toggle.
|
|
12
|
+
*/
|
|
13
|
+
function inferType(flags) {
|
|
14
|
+
return flags.includes('<') || flags.includes('[') ? 'string' : 'boolean';
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Extracts a single commander Command into an ExtractedConfigSurface.
|
|
18
|
+
*/
|
|
19
|
+
function extractCommand(cmd, parentName) {
|
|
20
|
+
const name = cmd.name?.() ?? '';
|
|
21
|
+
const fullName = parentName ? `${parentName} ${name}` : name;
|
|
22
|
+
const options = (cmd.options ?? []).map((opt) => {
|
|
23
|
+
const longFlag = opt.long ?? '';
|
|
24
|
+
const canonicalName = kebabToCamelCase(longFlag.replace(/^--/, ''));
|
|
25
|
+
const result = {
|
|
26
|
+
name: canonicalName,
|
|
27
|
+
cliFlag: longFlag || undefined,
|
|
28
|
+
cliShort: opt.short ?? undefined,
|
|
29
|
+
type: inferType(opt.flags ?? ''),
|
|
30
|
+
description: opt.description ?? '',
|
|
31
|
+
// commander's `opt.required` only describes the VALUE syntax: it is true for
|
|
32
|
+
// `--flag <x>` (value required when the flag is present) and false for
|
|
33
|
+
// `--flag [x]` (value optional). It says nothing about whether the option
|
|
34
|
+
// itself must be supplied — that is `opt.mandatory`, set only by
|
|
35
|
+
// `.requiredOption()`. Use mandatory so optional `--flag <value>` opts are
|
|
36
|
+
// not mismarked as required.
|
|
37
|
+
required: !!opt.mandatory
|
|
38
|
+
};
|
|
39
|
+
if (opt.defaultValue !== undefined) {
|
|
40
|
+
result.defaultValue = String(opt.defaultValue);
|
|
41
|
+
}
|
|
42
|
+
if (opt.envVar) {
|
|
43
|
+
result.envVar = opt.envVar;
|
|
44
|
+
}
|
|
45
|
+
return result;
|
|
46
|
+
});
|
|
47
|
+
const args = (cmd.registeredArguments ?? []).map((arg) => {
|
|
48
|
+
const result = {
|
|
49
|
+
name: arg.name?.() ?? '',
|
|
50
|
+
description: arg.description ?? '',
|
|
51
|
+
required: !!arg.required,
|
|
52
|
+
variadic: !!arg.variadic
|
|
53
|
+
};
|
|
54
|
+
if (arg.defaultValue !== undefined) {
|
|
55
|
+
result.defaultValue = String(arg.defaultValue);
|
|
56
|
+
}
|
|
57
|
+
return result;
|
|
58
|
+
});
|
|
59
|
+
const subcommands = (cmd.commands ?? []).map((sub) => extractCommand(sub, fullName));
|
|
60
|
+
const surface = {
|
|
61
|
+
name,
|
|
62
|
+
description: cmd.description?.() ?? '',
|
|
63
|
+
sourceType: 'cli',
|
|
64
|
+
usage: cmd.usage?.() ?? undefined,
|
|
65
|
+
options
|
|
66
|
+
};
|
|
67
|
+
if (args.length > 0) {
|
|
68
|
+
surface.arguments = args;
|
|
69
|
+
}
|
|
70
|
+
if (subcommands.length > 0) {
|
|
71
|
+
surface.subcommands = subcommands;
|
|
72
|
+
}
|
|
73
|
+
return surface;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Introspects a commander Program object and extracts all top-level command
|
|
77
|
+
* definitions as ExtractedConfigSurface[].
|
|
78
|
+
*
|
|
79
|
+
* @param program - A commander `Command` instance (typed as `any` to avoid
|
|
80
|
+
* a hard dependency on the commander package at the call site).
|
|
81
|
+
* @returns An array of extracted config surfaces, one per top-level command.
|
|
82
|
+
* Returns an empty array if the program has no subcommands.
|
|
83
|
+
*
|
|
84
|
+
* @category Commander
|
|
85
|
+
* @useWhen
|
|
86
|
+
* - You have a Commander program and want structured option/argument extraction with full fidelity
|
|
87
|
+
* @avoidWhen
|
|
88
|
+
* - Your CLI uses yargs, oclif, or another framework — use parseHelpOutput as a fallback instead
|
|
89
|
+
*/
|
|
90
|
+
export function introspectCommander(program) {
|
|
91
|
+
const commands = program.commands ?? [];
|
|
92
|
+
if (commands.length === 0)
|
|
93
|
+
return [];
|
|
94
|
+
return commands.map((cmd) => extractCommand(cmd, program.name?.() ?? ''));
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=introspect-commander.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"introspect-commander.js","sourceRoot":"","sources":["../src/introspect-commander.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type RefineTag } from '@skillit/core';
|
|
2
|
+
/**
|
|
3
|
+
* Reads routing tags (`@useWhen`/`@avoidWhen`/`@pitfalls`/`@remarks`/`@example`)
|
|
4
|
+
* from the JSDoc attached to a `<Command>Options` interface.
|
|
5
|
+
*
|
|
6
|
+
* Thin wrapper over core's {@link readJsDocTags} that keeps the CLI package's
|
|
7
|
+
* call-site intent explicit and provides a seam for CLI-specific behavior.
|
|
8
|
+
*/
|
|
9
|
+
export declare function readOptionsTags(interfaceName: string, source: string): Partial<Record<RefineTag, string>>;
|
|
10
|
+
//# sourceMappingURL=options-jsdoc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options-jsdoc.d.ts","sourceRoot":"","sources":["../src/options-jsdoc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAE9D;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAEpC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { readJsDocTags } from '@skillit/core';
|
|
2
|
+
/**
|
|
3
|
+
* Reads routing tags (`@useWhen`/`@avoidWhen`/`@pitfalls`/`@remarks`/`@example`)
|
|
4
|
+
* from the JSDoc attached to a `<Command>Options` interface.
|
|
5
|
+
*
|
|
6
|
+
* Thin wrapper over core's {@link readJsDocTags} that keeps the CLI package's
|
|
7
|
+
* call-site intent explicit and provides a seam for CLI-specific behavior.
|
|
8
|
+
*/
|
|
9
|
+
export function readOptionsTags(interfaceName, source) {
|
|
10
|
+
return readJsDocTags(source, interfaceName);
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=options-jsdoc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options-jsdoc.js","sourceRoot":"","sources":["../src/options-jsdoc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAkB,MAAM,eAAe,CAAC;AAE9D;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,aAAqB,EACrB,MAAc;IAEd,OAAO,aAAa,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
export interface LoadProgramOptions {
|
|
3
|
+
/** Explicit `file#export` reference to a Command or zero-arg factory. */
|
|
4
|
+
program?: string;
|
|
5
|
+
/** Directory to resolve relative paths and `package.json` against. */
|
|
6
|
+
cwd: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Loads a commander program for refinement.
|
|
10
|
+
*
|
|
11
|
+
* When `opts.program` is provided as `file#export`, the file is resolved
|
|
12
|
+
* against `cwd`, imported, and the named export is used (a `Command` or a
|
|
13
|
+
* zero-arg factory). Otherwise the program is auto-discovered from the
|
|
14
|
+
* consumer's `package.json` `bin` entry, probing the exports `buildProgram`,
|
|
15
|
+
* `createProgram`, `program`, then `default`.
|
|
16
|
+
*
|
|
17
|
+
* @throws Error advising `--program <file#export>` when no program can be loaded.
|
|
18
|
+
*/
|
|
19
|
+
export declare function loadProgram(opts: LoadProgramOptions): Promise<Command>;
|
|
20
|
+
//# sourceMappingURL=program-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program-loader.d.ts","sourceRoot":"","sources":["../src/program-loader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,GAAG,EAAE,MAAM,CAAC;CACb;AAkCD;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAuD5E"}
|