@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,90 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
const LOAD_ERROR = 'Could not load a commander program; pass --program <file#export>';
|
|
6
|
+
function messageOf(error) {
|
|
7
|
+
return error instanceof Error ? error.message : String(error);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Resolves a candidate export into a commander {@link Command}.
|
|
11
|
+
*
|
|
12
|
+
* Accepts either a `Command` instance directly or a zero-argument factory
|
|
13
|
+
* function that returns one. Returns `undefined` for anything else.
|
|
14
|
+
*/
|
|
15
|
+
async function resolveCommand(candidate) {
|
|
16
|
+
if (candidate instanceof Command) {
|
|
17
|
+
return candidate;
|
|
18
|
+
}
|
|
19
|
+
if (typeof candidate === 'function' &&
|
|
20
|
+
candidate.length === 0) {
|
|
21
|
+
const result = await candidate();
|
|
22
|
+
if (result instanceof Command) {
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
async function importModule(absPath) {
|
|
29
|
+
return (await import(pathToFileURL(absPath).href));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Loads a commander program for refinement.
|
|
33
|
+
*
|
|
34
|
+
* When `opts.program` is provided as `file#export`, the file is resolved
|
|
35
|
+
* against `cwd`, imported, and the named export is used (a `Command` or a
|
|
36
|
+
* zero-arg factory). Otherwise the program is auto-discovered from the
|
|
37
|
+
* consumer's `package.json` `bin` entry, probing the exports `buildProgram`,
|
|
38
|
+
* `createProgram`, `program`, then `default`.
|
|
39
|
+
*
|
|
40
|
+
* @throws Error advising `--program <file#export>` when no program can be loaded.
|
|
41
|
+
*/
|
|
42
|
+
export async function loadProgram(opts) {
|
|
43
|
+
if (opts.program !== undefined) {
|
|
44
|
+
const [file, exportName] = opts.program.split('#');
|
|
45
|
+
if (!file || !exportName) {
|
|
46
|
+
throw new Error(LOAD_ERROR);
|
|
47
|
+
}
|
|
48
|
+
const absPath = path.resolve(opts.cwd, file);
|
|
49
|
+
let mod;
|
|
50
|
+
try {
|
|
51
|
+
mod = await importModule(absPath);
|
|
52
|
+
}
|
|
53
|
+
catch (cause) {
|
|
54
|
+
throw new Error(`Could not import '${absPath}'; pass --program <file#export>: ${messageOf(cause)}`, { cause });
|
|
55
|
+
}
|
|
56
|
+
const command = await resolveCommand(mod[exportName]);
|
|
57
|
+
if (!command) {
|
|
58
|
+
throw new Error(`Export '${exportName}' from '${absPath}' is not a commander Command or factory; pass --program <file#export>`);
|
|
59
|
+
}
|
|
60
|
+
return command;
|
|
61
|
+
}
|
|
62
|
+
const pkgPath = path.join(opts.cwd, 'package.json');
|
|
63
|
+
let bin;
|
|
64
|
+
try {
|
|
65
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
66
|
+
bin = typeof pkg.bin === 'string' ? pkg.bin : Object.values(pkg.bin ?? {})[0];
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
throw new Error(LOAD_ERROR);
|
|
70
|
+
}
|
|
71
|
+
if (!bin) {
|
|
72
|
+
throw new Error(LOAD_ERROR);
|
|
73
|
+
}
|
|
74
|
+
const absBin = path.resolve(opts.cwd, bin);
|
|
75
|
+
let mod;
|
|
76
|
+
try {
|
|
77
|
+
mod = await importModule(absBin);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
throw new Error(LOAD_ERROR);
|
|
81
|
+
}
|
|
82
|
+
for (const exportName of ['buildProgram', 'createProgram', 'program', 'default']) {
|
|
83
|
+
const command = await resolveCommand(mod[exportName]);
|
|
84
|
+
if (command) {
|
|
85
|
+
return command;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
throw new Error(LOAD_ERROR);
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=program-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program-loader.js","sourceRoot":"","sources":["../src/program-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type AuditContext, type DraftedFix, type ExtractedSkill, type RefineSource } from '@skillit/core';
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
export interface CliRefineSourceOptions {
|
|
4
|
+
/** Commander program to introspect. */
|
|
5
|
+
program: Command;
|
|
6
|
+
/** Glob for the consumer's TypeScript source files to read/edit. */
|
|
7
|
+
sourceGlob: string;
|
|
8
|
+
/** Working directory (reserved for future relative-path resolution). */
|
|
9
|
+
cwd: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* {@link RefineSource} for `@skillit/cli` consumers.
|
|
13
|
+
*
|
|
14
|
+
* Extracts a skill from a commander program, returns the bundled CLI
|
|
15
|
+
* documentation conventions as guidance, and writes routing tags as JSDoc
|
|
16
|
+
* onto the correlated `<Command>Options` interface.
|
|
17
|
+
*/
|
|
18
|
+
export declare class CliRefineSource implements RefineSource {
|
|
19
|
+
private readonly opts;
|
|
20
|
+
constructor(opts: CliRefineSourceOptions);
|
|
21
|
+
/** Maps a command name to its options-interface name, e.g. `add-remote` → `AddRemoteOptions`, `db:migrate` → `DbMigrateOptions`. */
|
|
22
|
+
private interfaceName;
|
|
23
|
+
extract(): Promise<ExtractedSkill>;
|
|
24
|
+
guidance(): string;
|
|
25
|
+
auditContext(_skill: ExtractedSkill): AuditContext;
|
|
26
|
+
applyFixes(fixes: readonly DraftedFix[]): Promise<void>;
|
|
27
|
+
/** Reads tags for an interface across every globbed source file, first match wins. */
|
|
28
|
+
private readTagsAcross;
|
|
29
|
+
private readSources;
|
|
30
|
+
private findInterfaceFile;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=refine-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refine-source.d.ts","sourceRoot":"","sources":["../src/refine-source.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,UAAU,EAEf,KAAK,cAAc,EACnB,KAAK,YAAY,EAElB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,MAAM,WAAW,sBAAsB;IACrC,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;GAMG;AACH,qBAAa,eAAgB,YAAW,YAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,sBAAsB,EAAI;IAE7D,oIAAoI;IACpI,OAAO,CAAC,aAAa;IASf,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC,CAkDvC;IAED,QAAQ,IAAI,MAAM,CAKjB;IAED,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,YAAY,CAEjD;IAEK,UAAU,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB5D;IAED,sFAAsF;IACtF,OAAO,CAAC,cAAc;YAiBR,WAAW;IAUzB,OAAO,CAAC,iBAAiB;CAQ1B"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { glob, readFile, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { upsertJsDocTag } from '@skillit/core';
|
|
5
|
+
import { extractCliSkill } from './extract.js';
|
|
6
|
+
import { introspectCommander } from './introspect-commander.js';
|
|
7
|
+
import { readOptionsTags } from './options-jsdoc.js';
|
|
8
|
+
const EXCLUDED_DIRS = new Set(['node_modules', 'dist', 'build', '.git', 'coverage', '.cache']);
|
|
9
|
+
/**
|
|
10
|
+
* {@link RefineSource} for `@skillit/cli` consumers.
|
|
11
|
+
*
|
|
12
|
+
* Extracts a skill from a commander program, returns the bundled CLI
|
|
13
|
+
* documentation conventions as guidance, and writes routing tags as JSDoc
|
|
14
|
+
* onto the correlated `<Command>Options` interface.
|
|
15
|
+
*/
|
|
16
|
+
export class CliRefineSource {
|
|
17
|
+
opts;
|
|
18
|
+
constructor(opts) {
|
|
19
|
+
this.opts = opts;
|
|
20
|
+
}
|
|
21
|
+
/** Maps a command name to its options-interface name, e.g. `add-remote` → `AddRemoteOptions`, `db:migrate` → `DbMigrateOptions`. */
|
|
22
|
+
interfaceName(command) {
|
|
23
|
+
const pascal = command
|
|
24
|
+
.split(/[-_:.\s]+/)
|
|
25
|
+
.filter((part) => part.length > 0)
|
|
26
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
27
|
+
.join('');
|
|
28
|
+
return `${pascal}Options`;
|
|
29
|
+
}
|
|
30
|
+
async extract() {
|
|
31
|
+
const surfaces = introspectCommander(this.opts.program);
|
|
32
|
+
const sources = await this.readSources();
|
|
33
|
+
const configSurfaces = [];
|
|
34
|
+
for (const surface of surfaces) {
|
|
35
|
+
const iface = this.interfaceName(surface.name);
|
|
36
|
+
const tags = this.readTagsAcross(iface, sources);
|
|
37
|
+
// Key the correlation-input surface by the COMMAND name (not the
|
|
38
|
+
// interface name) so `extractCliSkill`'s `<command>`/`<command>options`
|
|
39
|
+
// lookup matches colon-namespaced commands (e.g. `db:migrate`). Mark it
|
|
40
|
+
// `cli` so it is correlated onto the command surface rather than emitted
|
|
41
|
+
// as a separate 0-option `config` surface.
|
|
42
|
+
const configSurface = {
|
|
43
|
+
name: surface.name,
|
|
44
|
+
description: '',
|
|
45
|
+
sourceType: 'cli',
|
|
46
|
+
options: []
|
|
47
|
+
};
|
|
48
|
+
let hasContent = false;
|
|
49
|
+
if (tags.useWhen !== undefined) {
|
|
50
|
+
configSurface.useWhen = [tags.useWhen];
|
|
51
|
+
hasContent = true;
|
|
52
|
+
}
|
|
53
|
+
if (tags.avoidWhen !== undefined) {
|
|
54
|
+
configSurface.avoidWhen = [tags.avoidWhen];
|
|
55
|
+
hasContent = true;
|
|
56
|
+
}
|
|
57
|
+
if (tags.pitfalls !== undefined) {
|
|
58
|
+
configSurface.pitfalls = [tags.pitfalls];
|
|
59
|
+
hasContent = true;
|
|
60
|
+
}
|
|
61
|
+
if (tags.remarks !== undefined) {
|
|
62
|
+
configSurface.remarks = tags.remarks;
|
|
63
|
+
hasContent = true;
|
|
64
|
+
}
|
|
65
|
+
if (tags.example !== undefined) {
|
|
66
|
+
configSurface.usage = tags.example;
|
|
67
|
+
hasContent = true;
|
|
68
|
+
}
|
|
69
|
+
// Only emit a surface when at least one consumed field is populated;
|
|
70
|
+
// a truly-empty read contributes nothing but noise.
|
|
71
|
+
if (hasContent) {
|
|
72
|
+
configSurfaces.push(configSurface);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return extractCliSkill({ program: this.opts.program, configSurfaces });
|
|
76
|
+
}
|
|
77
|
+
guidance() {
|
|
78
|
+
const skillPath = fileURLToPath(new URL('../skills/skillit-cli-docs/SKILL.md', import.meta.url));
|
|
79
|
+
return readFileSync(skillPath, 'utf8');
|
|
80
|
+
}
|
|
81
|
+
auditContext(_skill) {
|
|
82
|
+
return {};
|
|
83
|
+
}
|
|
84
|
+
async applyFixes(fixes) {
|
|
85
|
+
const sources = await this.readSources();
|
|
86
|
+
for (const fix of fixes) {
|
|
87
|
+
const iface = this.interfaceName(fix.toolName);
|
|
88
|
+
const file = this.findInterfaceFile(iface, sources);
|
|
89
|
+
if (!file) {
|
|
90
|
+
process.stderr.write(`[skillit] no ${iface} interface for command '${fix.toolName}'; skipped ${fix.tag}\n`);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const src = sources.get(file);
|
|
94
|
+
const next = upsertJsDocTag(src, iface, fix.tag, fix.value);
|
|
95
|
+
if (next !== src) {
|
|
96
|
+
await writeFile(file, next, 'utf8');
|
|
97
|
+
// Keep the in-memory map current so subsequent fixes targeting the
|
|
98
|
+
// same file build on this edit instead of clobbering it.
|
|
99
|
+
sources.set(file, next);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/** Reads tags for an interface across every globbed source file, first match wins. */
|
|
104
|
+
readTagsAcross(iface, sources) {
|
|
105
|
+
for (const src of sources.values()) {
|
|
106
|
+
if (!fileDeclaresInterface(src, iface)) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
const tags = readOptionsTags(iface, src);
|
|
110
|
+
if (Object.keys(tags).length > 0) {
|
|
111
|
+
return tags;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return {};
|
|
115
|
+
}
|
|
116
|
+
/** Globs the source files once and returns a file → contents map. */
|
|
117
|
+
async readSources() {
|
|
118
|
+
const sources = new Map();
|
|
119
|
+
for await (const file of glob(this.opts.sourceGlob, {
|
|
120
|
+
exclude: (f) => f.endsWith('.d.ts') || f.split(/[\\/]/).some((seg) => EXCLUDED_DIRS.has(seg))
|
|
121
|
+
})) {
|
|
122
|
+
sources.set(file, await readFile(file, 'utf8'));
|
|
123
|
+
}
|
|
124
|
+
return sources;
|
|
125
|
+
}
|
|
126
|
+
findInterfaceFile(iface, sources) {
|
|
127
|
+
for (const [file, contents] of sources) {
|
|
128
|
+
if (fileDeclaresInterface(contents, iface)) {
|
|
129
|
+
return file;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Returns whether `src` declares the interface named exactly `iface`.
|
|
137
|
+
*
|
|
138
|
+
* Matches on identifier boundaries so the probe for `GenOptions` does not
|
|
139
|
+
* spuriously match `interface GenOptionsExtra`. Shared by file-selection
|
|
140
|
+
* (`findInterfaceFile`) and tag-reading (`readTagsAcross`) so both agree on
|
|
141
|
+
* what counts as the interface.
|
|
142
|
+
*/
|
|
143
|
+
function fileDeclaresInterface(src, iface) {
|
|
144
|
+
const escaped = iface.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
145
|
+
return src.match(new RegExp(String.raw `\binterface\s+${escaped}\b`)) !== null;
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=refine-source.js.map
|
|
@@ -0,0 +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,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EACL,cAAc,EAOf,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;AAW/F;;;;;;GAMG;AACH,MAAM,OAAO,eAAe;IACG,IAAI;IAAjC,YAA6B,IAA4B;oBAA5B,IAAI;IAA2B,CAAC;IAE7D,oIAAoI;IAC5H,aAAa,CAAC,OAAe;QACnC,MAAM,MAAM,GAAG,OAAO;aACnB,KAAK,CAAC,WAAW,CAAC;aAClB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;aACjC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;aAC3D,IAAI,CAAC,EAAE,CAAC,CAAC;QACZ,OAAO,GAAG,MAAM,SAAS,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,QAAQ,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QAEzC,MAAM,cAAc,GAA6B,EAAE,CAAC;QACpD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAEjD,iEAAiE;YACjE,wEAAwE;YACxE,wEAAwE;YACxE,yEAAyE;YACzE,2CAA2C;YAC3C,MAAM,aAAa,GAA2B;gBAC5C,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,WAAW,EAAE,EAAE;gBACf,UAAU,EAAE,KAAK;gBACjB,OAAO,EAAE,EAAE;aACZ,CAAC;YACF,IAAI,UAAU,GAAG,KAAK,CAAC;YACvB,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC/B,aAAa,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACvC,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;YACD,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBACjC,aAAa,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC3C,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAChC,aAAa,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACzC,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC/B,aAAa,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;gBACrC,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC/B,aAAa,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC;gBACnC,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;YAED,qEAAqE;YACrE,oDAAoD;YACpD,IAAI,UAAU,EAAE,CAAC;gBACf,cAAc,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;QAED,OAAO,eAAe,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,QAAQ;QACN,MAAM,SAAS,GAAG,aAAa,CAC7B,IAAI,GAAG,CAAC,qCAAqC,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAChE,CAAC;QACF,OAAO,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACzC,CAAC;IAED,YAAY,CAAC,MAAsB;QACjC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,KAA4B;QAC3C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QAEzC,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACpD,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,gBAAgB,KAAK,2BAA2B,GAAG,CAAC,QAAQ,cAAc,GAAG,CAAC,GAAG,IAAI,CACtF,CAAC;gBACF,SAAS;YACX,CAAC;YACD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;YAC5D,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACjB,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;gBACpC,mEAAmE;gBACnE,yDAAyD;gBACzD,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;IAED,sFAAsF;IAC9E,cAAc,CACpB,KAAa,EACb,OAA4B;QAE5B,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YACnC,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC;gBACvC,SAAS;YACX,CAAC;YACD,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACzC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACjC,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,qEAAqE;IAC7D,KAAK,CAAC,WAAW;QACvB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC1C,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;YAClD,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;SAC9F,CAAC,EAAE,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QAClD,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,iBAAiB,CAAC,KAAa,EAAE,OAA4B;QACnE,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,OAAO,EAAE,CAAC;YACvC,IAAI,qBAAqB,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC;gBAC3C,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;CACF;AAED;;;;;;;GAOG;AACH,SAAS,qBAAqB,CAAC,GAAW,EAAE,KAAa;IACvD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;IAC7D,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,iBAAiB,OAAO,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC;AAChF,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@skillit/cli",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Extract CLI command structure from commander/yargs for AI agent skill generation",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"agent-skills",
|
|
7
|
+
"ai",
|
|
8
|
+
"cli",
|
|
9
|
+
"commander",
|
|
10
|
+
"documentation",
|
|
11
|
+
"introspection",
|
|
12
|
+
"skill-generation",
|
|
13
|
+
"skill-md",
|
|
14
|
+
"skillit",
|
|
15
|
+
"typescript",
|
|
16
|
+
"yargs"
|
|
17
|
+
],
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"author": "Pradeep Mouli",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/pradeepmouli/skillit.git",
|
|
23
|
+
"directory": "packages/cli"
|
|
24
|
+
},
|
|
25
|
+
"funding": {
|
|
26
|
+
"type": "github",
|
|
27
|
+
"url": "https://github.com/sponsors/pradeepmouli"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist",
|
|
31
|
+
"README.md",
|
|
32
|
+
"skills"
|
|
33
|
+
],
|
|
34
|
+
"type": "module",
|
|
35
|
+
"main": "./dist/index.js",
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"exports": {
|
|
38
|
+
".": {
|
|
39
|
+
"types": "./dist/index.d.ts",
|
|
40
|
+
"import": "./dist/index.js"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@skillit/core": "1.5.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"commander": "^14.0.3"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"commander": ">=12.0.0"
|
|
51
|
+
},
|
|
52
|
+
"peerDependenciesMeta": {
|
|
53
|
+
"commander": {
|
|
54
|
+
"optional": true
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "tsgo -p tsconfig.build.json",
|
|
59
|
+
"type-check": "tsgo --noEmit"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skillit-cli-docs
|
|
3
|
+
description: 'CLI documentation conventions for generated skills. Use when improving Commander descriptions, help text, positional argument docs, and config-surface correlation.'
|
|
4
|
+
version: 0.3.13
|
|
5
|
+
toSkills:
|
|
6
|
+
managed: bundled-guidance
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# CLI Documentation Conventions
|
|
10
|
+
|
|
11
|
+
Use this skill when documenting command-line programs for `@skillit/cli`.
|
|
12
|
+
|
|
13
|
+
## Focus Areas
|
|
14
|
+
|
|
15
|
+
- `.description()` text on commands and subcommands
|
|
16
|
+
- `.option()` and `--help` descriptions for every flag
|
|
17
|
+
- `.argument()` descriptions for positional inputs
|
|
18
|
+
- `.usage()` strings and example help text
|
|
19
|
+
- Environment-variable documentation and config-surface JSDoc correlation
|
|
20
|
+
|
|
21
|
+
## Fix Patterns
|
|
22
|
+
|
|
23
|
+
- Describe command intent in one sentence, not just the verb
|
|
24
|
+
- Explain what each option changes in behavior
|
|
25
|
+
- Document positional arguments with expected format or values
|
|
26
|
+
- Mention env vars explicitly when an option supports them
|