@skillit/cli 1.0.0 → 1.1.1
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/dist/config-surface-correlation.d.ts +44 -0
- package/dist/config-surface-correlation.d.ts.map +1 -0
- package/dist/config-surface-correlation.js +124 -0
- package/dist/config-surface-correlation.js.map +1 -0
- package/dist/correlator.d.ts +1 -1
- package/dist/correlator.js +3 -3
- package/dist/correlator.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/options-jsdoc.d.ts +1 -1
- package/dist/options-jsdoc.js +1 -1
- package/dist/refine-source.d.ts +0 -20
- package/dist/refine-source.d.ts.map +1 -1
- package/dist/refine-source.js +13 -111
- package/dist/refine-source.js.map +1 -1
- package/package.json +4 -4
- package/skills/skillit-cli-docs/SKILL.md +1 -1
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ExtractedConfigSurface } from '@skillit/core';
|
|
2
|
+
/**
|
|
3
|
+
* Candidate option-interface names for a command, in priority order.
|
|
4
|
+
*
|
|
5
|
+
* The documented convention is `<Command>Options` (e.g. `add-remote` →
|
|
6
|
+
* `AddRemoteOptions`, `db:migrate` → `DbMigrateOptions`), but real consumers —
|
|
7
|
+
* including skillit's own CLI — commonly name these `<Command>Opts` or
|
|
8
|
+
* `<Command>CommandOpts` (e.g. `init` → `InitOpts`, `refine` →
|
|
9
|
+
* `RefineCommandOpts`). We probe all three and use the first that a source
|
|
10
|
+
* file actually declares, so a non-conventional consumer still gets matched
|
|
11
|
+
* instead of silently skipped (or colliding with an unrelated `XOptions`).
|
|
12
|
+
*/
|
|
13
|
+
export declare function interfaceNameCandidates(command: string): string[];
|
|
14
|
+
/** Globs the source files once and returns a file → contents map. */
|
|
15
|
+
export declare function readSources(sourceGlob: string): Promise<Map<string, string>>;
|
|
16
|
+
/**
|
|
17
|
+
* Returns whether `src` declares the interface named exactly `iface`.
|
|
18
|
+
*
|
|
19
|
+
* Matches on identifier boundaries so the probe for `GenOptions` does not
|
|
20
|
+
* spuriously match `interface GenOptionsExtra`. Shared by file-selection
|
|
21
|
+
* and tag-reading so both agree on what counts as the interface.
|
|
22
|
+
*/
|
|
23
|
+
export declare function fileDeclaresInterface(src: string, iface: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Correlate JSDoc routing tags (`@useWhen`/`@avoidWhen`/`@never`/`@remarks`/
|
|
26
|
+
* `@example`) from `<Command>Options`-style interfaces in the consumer's TS
|
|
27
|
+
* source onto CLI command surfaces, so they flow into the generated skill's
|
|
28
|
+
* `## When to Use` / `## NEVER` sections.
|
|
29
|
+
*
|
|
30
|
+
* Used by both `skillit gen --source cli` (via `generateCliSkill`) and
|
|
31
|
+
* `skillit refine --source cli` (via `CliRefineSource`) so the two paths
|
|
32
|
+
* produce symmetric output — closes skillit#87.
|
|
33
|
+
*
|
|
34
|
+
* @useWhen
|
|
35
|
+
* - You have introspected CLI command surfaces and a glob of the consumer's
|
|
36
|
+
* TypeScript source, and need `ExtractedConfigSurface[]` with JSDoc-derived
|
|
37
|
+
* routing content correlated onto each command
|
|
38
|
+
* @never
|
|
39
|
+
* - NEVER call this with a glob that resolves zero files and expect a warning — it silently returns empty ExtractedConfigSurface[] for every surface, same as "no JSDoc tags found"
|
|
40
|
+
*/
|
|
41
|
+
export declare function correlateConfigSurfaces(surfaces: readonly {
|
|
42
|
+
name: string;
|
|
43
|
+
}[], sourceGlob: string): Promise<ExtractedConfigSurface[]>;
|
|
44
|
+
//# sourceMappingURL=config-surface-correlation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-surface-correlation.d.ts","sourceRoot":"","sources":["../src/config-surface-correlation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAK5D;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAOjE;AAED,qEAAqE;AACrE,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAQlF;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAIzE;AA0BD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,EACrC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,sBAAsB,EAAE,CAAC,CA8CnC"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { readFile, glob } from 'node:fs/promises';
|
|
2
|
+
import { readOptionsTags } from './options-jsdoc.js';
|
|
3
|
+
const EXCLUDED_DIRS = new Set(['node_modules', 'dist', 'build', '.git', 'coverage', '.cache']);
|
|
4
|
+
/**
|
|
5
|
+
* Candidate option-interface names for a command, in priority order.
|
|
6
|
+
*
|
|
7
|
+
* The documented convention is `<Command>Options` (e.g. `add-remote` →
|
|
8
|
+
* `AddRemoteOptions`, `db:migrate` → `DbMigrateOptions`), but real consumers —
|
|
9
|
+
* including skillit's own CLI — commonly name these `<Command>Opts` or
|
|
10
|
+
* `<Command>CommandOpts` (e.g. `init` → `InitOpts`, `refine` →
|
|
11
|
+
* `RefineCommandOpts`). We probe all three and use the first that a source
|
|
12
|
+
* file actually declares, so a non-conventional consumer still gets matched
|
|
13
|
+
* instead of silently skipped (or colliding with an unrelated `XOptions`).
|
|
14
|
+
*/
|
|
15
|
+
export function interfaceNameCandidates(command) {
|
|
16
|
+
const pascal = command
|
|
17
|
+
.split(/[-_:.\s]+/)
|
|
18
|
+
.filter((part) => part.length > 0)
|
|
19
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
20
|
+
.join('');
|
|
21
|
+
return [`${pascal}Options`, `${pascal}Opts`, `${pascal}CommandOpts`];
|
|
22
|
+
}
|
|
23
|
+
/** Globs the source files once and returns a file → contents map. */
|
|
24
|
+
export async function readSources(sourceGlob) {
|
|
25
|
+
const sources = new Map();
|
|
26
|
+
for await (const file of glob(sourceGlob, {
|
|
27
|
+
exclude: (f) => f.endsWith('.d.ts') || f.split(/[\\/]/).some((seg) => EXCLUDED_DIRS.has(seg))
|
|
28
|
+
})) {
|
|
29
|
+
sources.set(file, await readFile(file, 'utf8'));
|
|
30
|
+
}
|
|
31
|
+
return sources;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Returns whether `src` declares the interface named exactly `iface`.
|
|
35
|
+
*
|
|
36
|
+
* Matches on identifier boundaries so the probe for `GenOptions` does not
|
|
37
|
+
* spuriously match `interface GenOptionsExtra`. Shared by file-selection
|
|
38
|
+
* and tag-reading so both agree on what counts as the interface.
|
|
39
|
+
*/
|
|
40
|
+
export function fileDeclaresInterface(src, iface) {
|
|
41
|
+
const escaped = iface.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
42
|
+
const pattern = new RegExp(`\\binterface\\s+${escaped}\\b`);
|
|
43
|
+
return pattern.test(src);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Reads tags for the first candidate interface that a globbed source file
|
|
47
|
+
* declares with at least one tag. Candidates are tried in priority order so
|
|
48
|
+
* the documented `<Command>Options` name wins over the `Opts`/`CommandOpts`
|
|
49
|
+
* fallbacks when more than one is present.
|
|
50
|
+
*/
|
|
51
|
+
function readTagsAcross(candidates, sources) {
|
|
52
|
+
for (const iface of candidates) {
|
|
53
|
+
for (const src of sources.values()) {
|
|
54
|
+
if (!fileDeclaresInterface(src, iface)) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const tags = readOptionsTags(iface, src);
|
|
58
|
+
if (Object.keys(tags).length > 0) {
|
|
59
|
+
return tags;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return {};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Correlate JSDoc routing tags (`@useWhen`/`@avoidWhen`/`@never`/`@remarks`/
|
|
67
|
+
* `@example`) from `<Command>Options`-style interfaces in the consumer's TS
|
|
68
|
+
* source onto CLI command surfaces, so they flow into the generated skill's
|
|
69
|
+
* `## When to Use` / `## NEVER` sections.
|
|
70
|
+
*
|
|
71
|
+
* Used by both `skillit gen --source cli` (via `generateCliSkill`) and
|
|
72
|
+
* `skillit refine --source cli` (via `CliRefineSource`) so the two paths
|
|
73
|
+
* produce symmetric output — closes skillit#87.
|
|
74
|
+
*
|
|
75
|
+
* @useWhen
|
|
76
|
+
* - You have introspected CLI command surfaces and a glob of the consumer's
|
|
77
|
+
* TypeScript source, and need `ExtractedConfigSurface[]` with JSDoc-derived
|
|
78
|
+
* routing content correlated onto each command
|
|
79
|
+
* @never
|
|
80
|
+
* - NEVER call this with a glob that resolves zero files and expect a warning — it silently returns empty ExtractedConfigSurface[] for every surface, same as "no JSDoc tags found"
|
|
81
|
+
*/
|
|
82
|
+
export async function correlateConfigSurfaces(surfaces, sourceGlob) {
|
|
83
|
+
if (surfaces.length === 0) {
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
const sources = await readSources(sourceGlob);
|
|
87
|
+
const configSurfaces = [];
|
|
88
|
+
for (const surface of surfaces) {
|
|
89
|
+
const candidates = interfaceNameCandidates(surface.name);
|
|
90
|
+
const tags = readTagsAcross(candidates, sources);
|
|
91
|
+
const configSurface = {
|
|
92
|
+
name: surface.name,
|
|
93
|
+
description: '',
|
|
94
|
+
sourceType: 'cli',
|
|
95
|
+
options: []
|
|
96
|
+
};
|
|
97
|
+
let hasContent = false;
|
|
98
|
+
if (tags.useWhen !== undefined) {
|
|
99
|
+
configSurface.useWhen = [tags.useWhen];
|
|
100
|
+
hasContent = true;
|
|
101
|
+
}
|
|
102
|
+
if (tags.avoidWhen !== undefined) {
|
|
103
|
+
configSurface.avoidWhen = [tags.avoidWhen];
|
|
104
|
+
hasContent = true;
|
|
105
|
+
}
|
|
106
|
+
if (tags.never !== undefined) {
|
|
107
|
+
configSurface.never = [tags.never];
|
|
108
|
+
hasContent = true;
|
|
109
|
+
}
|
|
110
|
+
if (tags.remarks !== undefined) {
|
|
111
|
+
configSurface.remarks = tags.remarks;
|
|
112
|
+
hasContent = true;
|
|
113
|
+
}
|
|
114
|
+
if (tags.example !== undefined) {
|
|
115
|
+
configSurface.usage = tags.example;
|
|
116
|
+
hasContent = true;
|
|
117
|
+
}
|
|
118
|
+
if (hasContent) {
|
|
119
|
+
configSurfaces.push(configSurface);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return configSurfaces;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=config-surface-correlation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-surface-correlation.js","sourceRoot":"","sources":["../src/config-surface-correlation.ts"],"names":[],"mappings":"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"}
|
package/dist/correlator.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { ExtractedConfigSurface } from '@skillit/core';
|
|
|
5
5
|
*
|
|
6
6
|
* The CLI surface is treated as authoritative for structural fields (flags,
|
|
7
7
|
* description, required, defaultValue). The config surface contributes rich
|
|
8
|
-
* JSDoc metadata (remarks, useWhen, avoidWhen,
|
|
8
|
+
* JSDoc metadata (remarks, useWhen, avoidWhen, never, category) that the
|
|
9
9
|
* CLI help text does not capture.
|
|
10
10
|
*
|
|
11
11
|
* @param cliSurface - The surface extracted from CLI introspection/help parsing
|
package/dist/correlator.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* The CLI surface is treated as authoritative for structural fields (flags,
|
|
6
6
|
* description, required, defaultValue). The config surface contributes rich
|
|
7
|
-
* JSDoc metadata (remarks, useWhen, avoidWhen,
|
|
7
|
+
* JSDoc metadata (remarks, useWhen, avoidWhen, never, category) that the
|
|
8
8
|
* CLI help text does not capture.
|
|
9
9
|
*
|
|
10
10
|
* @param cliSurface - The surface extracted from CLI introspection/help parsing
|
|
@@ -38,7 +38,7 @@ export function correlateFlags(cliSurface, configSurface) {
|
|
|
38
38
|
remarks: cliOpt.remarks ?? configOpt.remarks,
|
|
39
39
|
useWhen: cliOpt.useWhen ?? configOpt.useWhen,
|
|
40
40
|
avoidWhen: cliOpt.avoidWhen ?? configOpt.avoidWhen,
|
|
41
|
-
|
|
41
|
+
never: cliOpt.never ?? configOpt.never,
|
|
42
42
|
category: cliOpt.category ?? configOpt.category
|
|
43
43
|
};
|
|
44
44
|
});
|
|
@@ -48,7 +48,7 @@ export function correlateFlags(cliSurface, configSurface) {
|
|
|
48
48
|
options: mergedOptions,
|
|
49
49
|
useWhen: cliSurface.useWhen ?? configSurface.useWhen,
|
|
50
50
|
avoidWhen: cliSurface.avoidWhen ?? configSurface.avoidWhen,
|
|
51
|
-
|
|
51
|
+
never: cliSurface.never ?? configSurface.never,
|
|
52
52
|
remarks: cliSurface.remarks ?? configSurface.remarks,
|
|
53
53
|
// A config-provided usage example (e.g. from JSDoc @example) is preferred
|
|
54
54
|
// over commander's synthesized boilerplate (`[options]`, `[options] <args>`).
|
package/dist/correlator.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"correlator.js","sourceRoot":"","sources":["../src/correlator.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,cAAc,CAC5B,UAAkC,EAClC,aAAiD;IAEjD,IAAI,CAAC,aAAa;QAAE,OAAO,UAAU,CAAC;IAEtC,wDAAwD;IACxD,MAAM,YAAY,GAAG,IAAI,GAAG,EAAiC,CAAC;IAC9D,KAAK,MAAM,GAAG,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;QACxC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,GAAG,CAAC,CAAC;IAChD,CAAC;IAED,sDAAsD;IACtD,MAAM,aAAa,GAA4B,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAC/E,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC9D,IAAI,CAAC,SAAS;YAAE,OAAO,MAAM,CAAC;QAE9B,OAAO;YACL,0DAA0D;YAC1D,GAAG,MAAM;YACT,mEAAmE;YACnE,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,SAAS,CAAC,WAAW;YACxD,0CAA0C;YAC1C,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,SAAS,CAAC,OAAO;YAC5C,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,SAAS,CAAC,OAAO;YAC5C,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS;YAClD,
|
|
1
|
+
{"version":3,"file":"correlator.js","sourceRoot":"","sources":["../src/correlator.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,cAAc,CAC5B,UAAkC,EAClC,aAAiD;IAEjD,IAAI,CAAC,aAAa;QAAE,OAAO,UAAU,CAAC;IAEtC,wDAAwD;IACxD,MAAM,YAAY,GAAG,IAAI,GAAG,EAAiC,CAAC;IAC9D,KAAK,MAAM,GAAG,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;QACxC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,GAAG,CAAC,CAAC;IAChD,CAAC;IAED,sDAAsD;IACtD,MAAM,aAAa,GAA4B,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAC/E,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC9D,IAAI,CAAC,SAAS;YAAE,OAAO,MAAM,CAAC;QAE9B,OAAO;YACL,0DAA0D;YAC1D,GAAG,MAAM;YACT,mEAAmE;YACnE,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,SAAS,CAAC,WAAW;YACxD,0CAA0C;YAC1C,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,SAAS,CAAC,OAAO;YAC5C,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,SAAS,CAAC,OAAO;YAC5C,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS;YAClD,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,SAAS,CAAC,KAAK;YACtC,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,SAAS,CAAC,QAAQ;SAChD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,gEAAgE;IAChE,OAAO;QACL,GAAG,UAAU;QACb,OAAO,EAAE,aAAa;QACtB,OAAO,EAAE,UAAU,CAAC,OAAO,IAAI,aAAa,CAAC,OAAO;QACpD,SAAS,EAAE,UAAU,CAAC,SAAS,IAAI,aAAa,CAAC,SAAS;QAC1D,KAAK,EAAE,UAAU,CAAC,KAAK,IAAI,aAAa,CAAC,KAAK;QAC9C,OAAO,EAAE,UAAU,CAAC,OAAO,IAAI,aAAa,CAAC,OAAO;QACpD,0EAA0E;QAC1E,8EAA8E;QAC9E,KAAK,EAAE,kBAAkB,CAAC,UAAU,CAAC,KAAK,CAAC;YACzC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC;YAC3C,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,IAAI,aAAa,CAAC,KAAK,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,kBAAkB,CAAC,KAAyB;IACnD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACrC,OAAO,KAAK,CAAC,KAAK,CAAC,6BAA6B,CAAC,KAAK,IAAI,CAAC;AAC7D,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export type { CliAuditIssue } from './audit.js';
|
|
|
26
26
|
export { loadProgram } from './program-loader.js';
|
|
27
27
|
export type { LoadProgramOptions } from './program-loader.js';
|
|
28
28
|
export { readOptionsTags } from './options-jsdoc.js';
|
|
29
|
+
export { correlateConfigSurfaces } from './config-surface-correlation.js';
|
|
29
30
|
export { CliRefineSource } from './refine-source.js';
|
|
30
31
|
export type { CliRefineSourceOptions } from './refine-source.js';
|
|
31
32
|
export { applyNpxMode, resolveInvocationMode } from './npx-mode.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +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;AACjE,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACpE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
|
|
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,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACpE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -23,6 +23,7 @@ export { runCliAudit } from './audit.js';
|
|
|
23
23
|
export { extractCliSkill, writeCliSkill } from './extract.js';
|
|
24
24
|
export { loadProgram } from './program-loader.js';
|
|
25
25
|
export { readOptionsTags } from './options-jsdoc.js';
|
|
26
|
+
export { correlateConfigSurfaces } from './config-surface-correlation.js';
|
|
26
27
|
export { CliRefineSource } from './refine-source.js';
|
|
27
28
|
export { applyNpxMode, resolveInvocationMode } from './npx-mode.js';
|
|
28
29
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +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;AAErD,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC"}
|
|
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,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/options-jsdoc.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type RefineTag } from '@skillit/core';
|
|
2
2
|
/**
|
|
3
|
-
* Reads routing tags (`@useWhen`/`@avoidWhen`/`@
|
|
3
|
+
* Reads routing tags (`@useWhen`/`@avoidWhen`/`@never`/`@remarks`/`@example`)
|
|
4
4
|
* from the JSDoc attached to a `<Command>Options` interface.
|
|
5
5
|
*
|
|
6
6
|
* Thin wrapper over core's {@link readJsDocTags} that keeps the CLI package's
|
package/dist/options-jsdoc.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readJsDocTags } from '@skillit/core';
|
|
2
2
|
/**
|
|
3
|
-
* Reads routing tags (`@useWhen`/`@avoidWhen`/`@
|
|
3
|
+
* Reads routing tags (`@useWhen`/`@avoidWhen`/`@never`/`@remarks`/`@example`)
|
|
4
4
|
* from the JSDoc attached to a `<Command>Options` interface.
|
|
5
5
|
*
|
|
6
6
|
* Thin wrapper over core's {@link readJsDocTags} that keeps the CLI package's
|
package/dist/refine-source.d.ts
CHANGED
|
@@ -26,18 +26,6 @@ export declare class CliRefineSource implements RefineSource {
|
|
|
26
26
|
/** Cached metadata loaded during {@link extract} (always called first in the audit/refine loop). */
|
|
27
27
|
private cachedMetadata;
|
|
28
28
|
constructor(opts: CliRefineSourceOptions);
|
|
29
|
-
/**
|
|
30
|
-
* Candidate option-interface names for a command, in priority order.
|
|
31
|
-
*
|
|
32
|
-
* The documented convention is `<Command>Options` (e.g. `add-remote` →
|
|
33
|
-
* `AddRemoteOptions`, `db:migrate` → `DbMigrateOptions`), but real consumers —
|
|
34
|
-
* including skillit's own CLI — commonly name these `<Command>Opts` or
|
|
35
|
-
* `<Command>CommandOpts` (e.g. `init` → `InitOpts`, `refine` →
|
|
36
|
-
* `RefineCommandOpts`). We probe all three and use the first that a source
|
|
37
|
-
* file actually declares, so a non-conventional consumer still gets matched
|
|
38
|
-
* instead of silently skipped (or colliding with an unrelated `XOptions`).
|
|
39
|
-
*/
|
|
40
|
-
private interfaceNameCandidates;
|
|
41
29
|
extract(): Promise<ExtractedSkill>;
|
|
42
30
|
guidance(): string;
|
|
43
31
|
resolveTargetLocation(target: {
|
|
@@ -46,14 +34,6 @@ export declare class CliRefineSource implements RefineSource {
|
|
|
46
34
|
file?: string;
|
|
47
35
|
}): Promise<TargetLocation | undefined>;
|
|
48
36
|
applyFixes(fixes: readonly DraftedFix[]): Promise<void>;
|
|
49
|
-
/**
|
|
50
|
-
* Reads tags for the first candidate interface that a globbed source file
|
|
51
|
-
* declares with at least one tag. Candidates are tried in priority order so
|
|
52
|
-
* the documented `<Command>Options` name wins over the `Opts`/`CommandOpts`
|
|
53
|
-
* fallbacks when more than one is present.
|
|
54
|
-
*/
|
|
55
|
-
private readTagsAcross;
|
|
56
|
-
private readSources;
|
|
57
37
|
private findInterfaceFile;
|
|
58
38
|
}
|
|
59
39
|
//# sourceMappingURL=refine-source.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refine-source.d.ts","sourceRoot":"","sources":["../src/refine-source.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"refine-source.d.ts","sourceRoot":"","sources":["../src/refine-source.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,cAAc,EAEnB,KAAK,YAAY,EACjB,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAErE,MAAM,WAAW,sBAAsB;IACrC,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,GAAG,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,cAAc,CAAC,EAAE,iBAAiB,CAAC;CACpC;AAED;;;;;;GAMG;AACH,qBAAa,eAAgB,YAAW,YAAY;IAItC,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHjC,oGAAoG;IACpG,OAAO,CAAC,cAAc,CAAuB;IAE7C,YAA6B,IAAI,EAAE,sBAAsB,EAAI;IAEvD,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC,CAoCvC;IAED,QAAQ,IAAI,MAAM,CAKjB;IAEK,qBAAqB,CAAC,MAAM,EAAE;QAClC,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAQtC;IAEK,UAAU,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA8B5D;IAED,OAAO,CAAC,iBAAiB;CAQ1B"}
|
package/dist/refine-source.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
|
-
import {
|
|
2
|
+
import { writeFile } from 'node:fs/promises';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { findNearestPackageDir, readPackageMetadata, upsertJsDocTag } from '@skillit/core';
|
|
5
|
+
import { correlateConfigSurfaces, fileDeclaresInterface, interfaceNameCandidates, readSources } from './config-surface-correlation.js';
|
|
5
6
|
import { extractCliSkill } from './extract.js';
|
|
6
7
|
import { introspectCommander } from './introspect-commander.js';
|
|
7
8
|
import { applyNpxMode } from './npx-mode.js';
|
|
8
|
-
import { readOptionsTags } from './options-jsdoc.js';
|
|
9
|
-
const EXCLUDED_DIRS = new Set(['node_modules', 'dist', 'build', '.git', 'coverage', '.cache']);
|
|
10
9
|
/**
|
|
11
10
|
* {@link RefineSource} for `@skillit/cli` consumers.
|
|
12
11
|
*
|
|
@@ -21,74 +20,19 @@ export class CliRefineSource {
|
|
|
21
20
|
constructor(opts) {
|
|
22
21
|
this.opts = opts;
|
|
23
22
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Candidate option-interface names for a command, in priority order.
|
|
26
|
-
*
|
|
27
|
-
* The documented convention is `<Command>Options` (e.g. `add-remote` →
|
|
28
|
-
* `AddRemoteOptions`, `db:migrate` → `DbMigrateOptions`), but real consumers —
|
|
29
|
-
* including skillit's own CLI — commonly name these `<Command>Opts` or
|
|
30
|
-
* `<Command>CommandOpts` (e.g. `init` → `InitOpts`, `refine` →
|
|
31
|
-
* `RefineCommandOpts`). We probe all three and use the first that a source
|
|
32
|
-
* file actually declares, so a non-conventional consumer still gets matched
|
|
33
|
-
* instead of silently skipped (or colliding with an unrelated `XOptions`).
|
|
34
|
-
*/
|
|
35
|
-
interfaceNameCandidates(command) {
|
|
36
|
-
const pascal = command
|
|
37
|
-
.split(/[-_:.\s]+/)
|
|
38
|
-
.filter((part) => part.length > 0)
|
|
39
|
-
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
40
|
-
.join('');
|
|
41
|
-
return [`${pascal}Options`, `${pascal}Opts`, `${pascal}CommandOpts`];
|
|
42
|
-
}
|
|
43
23
|
async extract() {
|
|
44
24
|
const surfaces = introspectCommander(this.opts.program);
|
|
45
|
-
const sources = await this.readSources();
|
|
46
25
|
// Load package metadata (package.json + README) from cwd; its fields are
|
|
47
26
|
// written onto the IR below so the audit reads them directly from the skill.
|
|
48
27
|
const pkgDir = await findNearestPackageDir(this.opts.cwd);
|
|
49
28
|
this.cachedMetadata = pkgDir ? await readPackageMetadata(pkgDir) : {};
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
// `cli` so it is correlated onto the command surface rather than emitted
|
|
58
|
-
// as a separate 0-option `config` surface.
|
|
59
|
-
const configSurface = {
|
|
60
|
-
name: surface.name,
|
|
61
|
-
description: '',
|
|
62
|
-
sourceType: 'cli',
|
|
63
|
-
options: []
|
|
64
|
-
};
|
|
65
|
-
let hasContent = false;
|
|
66
|
-
if (tags.useWhen !== undefined) {
|
|
67
|
-
configSurface.useWhen = [tags.useWhen];
|
|
68
|
-
hasContent = true;
|
|
69
|
-
}
|
|
70
|
-
if (tags.avoidWhen !== undefined) {
|
|
71
|
-
configSurface.avoidWhen = [tags.avoidWhen];
|
|
72
|
-
hasContent = true;
|
|
73
|
-
}
|
|
74
|
-
if (tags.pitfalls !== undefined) {
|
|
75
|
-
configSurface.pitfalls = [tags.pitfalls];
|
|
76
|
-
hasContent = true;
|
|
77
|
-
}
|
|
78
|
-
if (tags.remarks !== undefined) {
|
|
79
|
-
configSurface.remarks = tags.remarks;
|
|
80
|
-
hasContent = true;
|
|
81
|
-
}
|
|
82
|
-
if (tags.example !== undefined) {
|
|
83
|
-
configSurface.usage = tags.example;
|
|
84
|
-
hasContent = true;
|
|
85
|
-
}
|
|
86
|
-
// Only emit a surface when at least one consumed field is populated;
|
|
87
|
-
// a truly-empty read contributes nothing but noise.
|
|
88
|
-
if (hasContent) {
|
|
89
|
-
configSurfaces.push(configSurface);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
29
|
+
// Key the correlation-input surfaces by the COMMAND name (not the
|
|
30
|
+
// interface name) so `extractCliSkill`'s `<command>`/`<command>options`
|
|
31
|
+
// lookup matches colon-namespaced commands (e.g. `db:migrate`). Marked
|
|
32
|
+
// `cli` (inside correlateConfigSurfaces) so each is correlated onto the
|
|
33
|
+
// command surface rather than emitted as a separate 0-option `config`
|
|
34
|
+
// surface.
|
|
35
|
+
const configSurfaces = await correlateConfigSurfaces(surfaces, this.opts.sourceGlob);
|
|
92
36
|
const meta = this.cachedMetadata;
|
|
93
37
|
const skill = await extractCliSkill({
|
|
94
38
|
program: this.opts.program,
|
|
@@ -119,8 +63,8 @@ export class CliRefineSource {
|
|
|
119
63
|
return readFileSync(skillPath, 'utf8');
|
|
120
64
|
}
|
|
121
65
|
async resolveTargetLocation(target) {
|
|
122
|
-
const sources = await this.
|
|
123
|
-
const candidates =
|
|
66
|
+
const sources = await readSources(this.opts.sourceGlob);
|
|
67
|
+
const candidates = interfaceNameCandidates(target.name);
|
|
124
68
|
for (const iface of candidates) {
|
|
125
69
|
const file = this.findInterfaceFile(iface, sources);
|
|
126
70
|
if (file)
|
|
@@ -129,9 +73,9 @@ export class CliRefineSource {
|
|
|
129
73
|
return undefined;
|
|
130
74
|
}
|
|
131
75
|
async applyFixes(fixes) {
|
|
132
|
-
const sources = await this.
|
|
76
|
+
const sources = await readSources(this.opts.sourceGlob);
|
|
133
77
|
for (const fix of fixes) {
|
|
134
|
-
const candidates =
|
|
78
|
+
const candidates = interfaceNameCandidates(fix.toolName);
|
|
135
79
|
let iface;
|
|
136
80
|
let file;
|
|
137
81
|
for (const candidate of candidates) {
|
|
@@ -156,36 +100,6 @@ export class CliRefineSource {
|
|
|
156
100
|
}
|
|
157
101
|
}
|
|
158
102
|
}
|
|
159
|
-
/**
|
|
160
|
-
* Reads tags for the first candidate interface that a globbed source file
|
|
161
|
-
* declares with at least one tag. Candidates are tried in priority order so
|
|
162
|
-
* the documented `<Command>Options` name wins over the `Opts`/`CommandOpts`
|
|
163
|
-
* fallbacks when more than one is present.
|
|
164
|
-
*/
|
|
165
|
-
readTagsAcross(candidates, sources) {
|
|
166
|
-
for (const iface of candidates) {
|
|
167
|
-
for (const src of sources.values()) {
|
|
168
|
-
if (!fileDeclaresInterface(src, iface)) {
|
|
169
|
-
continue;
|
|
170
|
-
}
|
|
171
|
-
const tags = readOptionsTags(iface, src);
|
|
172
|
-
if (Object.keys(tags).length > 0) {
|
|
173
|
-
return tags;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
return {};
|
|
178
|
-
}
|
|
179
|
-
/** Globs the source files once and returns a file → contents map. */
|
|
180
|
-
async readSources() {
|
|
181
|
-
const sources = new Map();
|
|
182
|
-
for await (const file of glob(this.opts.sourceGlob, {
|
|
183
|
-
exclude: (f) => f.endsWith('.d.ts') || f.split(/[\\/]/).some((seg) => EXCLUDED_DIRS.has(seg))
|
|
184
|
-
})) {
|
|
185
|
-
sources.set(file, await readFile(file, 'utf8'));
|
|
186
|
-
}
|
|
187
|
-
return sources;
|
|
188
|
-
}
|
|
189
103
|
findInterfaceFile(iface, sources) {
|
|
190
104
|
for (const [file, contents] of sources) {
|
|
191
105
|
if (fileDeclaresInterface(contents, iface)) {
|
|
@@ -195,16 +109,4 @@ export class CliRefineSource {
|
|
|
195
109
|
return undefined;
|
|
196
110
|
}
|
|
197
111
|
}
|
|
198
|
-
/**
|
|
199
|
-
* Returns whether `src` declares the interface named exactly `iface`.
|
|
200
|
-
*
|
|
201
|
-
* Matches on identifier boundaries so the probe for `GenOptions` does not
|
|
202
|
-
* spuriously match `interface GenOptionsExtra`. Shared by file-selection
|
|
203
|
-
* (`findInterfaceFile`) and tag-reading (`readTagsAcross`) so both agree on
|
|
204
|
-
* what counts as the interface.
|
|
205
|
-
*/
|
|
206
|
-
function fileDeclaresInterface(src, iface) {
|
|
207
|
-
const escaped = iface.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
208
|
-
return src.match(new RegExp(String.raw `\binterface\s+${escaped}\b`)) !== null;
|
|
209
|
-
}
|
|
210
112
|
//# sourceMappingURL=refine-source.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refine-source.js","sourceRoot":"","sources":["../src/refine-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"refine-source.js","sourceRoot":"","sources":["../src/refine-source.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skillit/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Extract CLI command structure from commander/yargs for AI agent skill generation",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent-skills",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@skillit/core": "
|
|
44
|
+
"@skillit/core": "4.0.1"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"commander": "^15.0.0"
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
}
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
|
-
"build": "
|
|
59
|
-
"type-check": "
|
|
58
|
+
"build": "tsc -p tsconfig.build.json",
|
|
59
|
+
"type-check": "tsc --noEmit"
|
|
60
60
|
}
|
|
61
61
|
}
|
|
@@ -20,7 +20,7 @@ Use this skill when documenting command-line programs for `@skillit/cli`.
|
|
|
20
20
|
|
|
21
21
|
## Routing Tags via Option Interfaces
|
|
22
22
|
|
|
23
|
-
For routing tags (`@useWhen`, `@avoidWhen`, `@
|
|
23
|
+
For routing tags (`@useWhen`, `@avoidWhen`, `@never`), add them as JSDoc on
|
|
24
24
|
a `<PascalCommandName>Options` interface in a TypeScript source file.
|
|
25
25
|
The interface needs no properties — only the JSDoc block matters:
|
|
26
26
|
|