@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.
Files changed (40) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +44 -0
  3. package/dist/audit.d.ts +14 -0
  4. package/dist/audit.d.ts.map +1 -0
  5. package/dist/audit.js +101 -0
  6. package/dist/audit.js.map +1 -0
  7. package/dist/correlator.d.ts +21 -0
  8. package/dist/correlator.d.ts.map +1 -0
  9. package/dist/correlator.js +69 -0
  10. package/dist/correlator.js.map +1 -0
  11. package/dist/extract.d.ts +37 -0
  12. package/dist/extract.d.ts.map +1 -0
  13. package/dist/extract.js +133 -0
  14. package/dist/extract.js.map +1 -0
  15. package/dist/help-parser.d.ts +17 -0
  16. package/dist/help-parser.d.ts.map +1 -0
  17. package/dist/help-parser.js +314 -0
  18. package/dist/help-parser.js.map +1 -0
  19. package/dist/index.d.ts +31 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +27 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/introspect-commander.d.ts +18 -0
  24. package/dist/introspect-commander.d.ts.map +1 -0
  25. package/dist/introspect-commander.js +96 -0
  26. package/dist/introspect-commander.js.map +1 -0
  27. package/dist/options-jsdoc.d.ts +10 -0
  28. package/dist/options-jsdoc.d.ts.map +1 -0
  29. package/dist/options-jsdoc.js +12 -0
  30. package/dist/options-jsdoc.js.map +1 -0
  31. package/dist/program-loader.d.ts +20 -0
  32. package/dist/program-loader.d.ts.map +1 -0
  33. package/dist/program-loader.js +90 -0
  34. package/dist/program-loader.js.map +1 -0
  35. package/dist/refine-source.d.ts +32 -0
  36. package/dist/refine-source.d.ts.map +1 -0
  37. package/dist/refine-source.js +147 -0
  38. package/dist/refine-source.js.map +1 -0
  39. package/package.json +61 -0
  40. 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":"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"}
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