@skillit/client 0.2.0 → 0.3.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.
Files changed (77) hide show
  1. package/README.md +40 -0
  2. package/dist/bin.d.ts +2 -1
  3. package/dist/bin.d.ts.map +1 -1
  4. package/dist/bin.js +21 -13
  5. package/dist/bin.js.map +1 -1
  6. package/dist/commands/audit.d.ts +34 -0
  7. package/dist/commands/audit.d.ts.map +1 -0
  8. package/dist/commands/audit.js +139 -0
  9. package/dist/commands/audit.js.map +1 -0
  10. package/dist/commands/gen.d.ts +20 -0
  11. package/dist/commands/gen.d.ts.map +1 -0
  12. package/dist/commands/gen.js +108 -0
  13. package/dist/commands/gen.js.map +1 -0
  14. package/dist/commands/init.d.ts +3 -22
  15. package/dist/commands/init.d.ts.map +1 -1
  16. package/dist/commands/init.js +23 -84
  17. package/dist/commands/init.js.map +1 -1
  18. package/dist/commands/refine.d.ts +34 -2
  19. package/dist/commands/refine.d.ts.map +1 -1
  20. package/dist/commands/refine.js +61 -29
  21. package/dist/commands/refine.js.map +1 -1
  22. package/dist/generate.d.ts +67 -0
  23. package/dist/generate.d.ts.map +1 -0
  24. package/dist/generate.js +55 -0
  25. package/dist/generate.js.map +1 -0
  26. package/dist/mcp-mode.d.ts +22 -0
  27. package/dist/mcp-mode.d.ts.map +1 -0
  28. package/dist/mcp-mode.js +27 -0
  29. package/dist/mcp-mode.js.map +1 -0
  30. package/dist/model/anthropic.d.ts +11 -0
  31. package/dist/model/anthropic.d.ts.map +1 -1
  32. package/dist/model/anthropic.js +16 -2
  33. package/dist/model/anthropic.js.map +1 -1
  34. package/dist/model/cli/adapters.d.ts.map +1 -1
  35. package/dist/model/cli/adapters.js +35 -2
  36. package/dist/model/cli/adapters.js.map +1 -1
  37. package/dist/model/cli/cli-client.d.ts.map +1 -1
  38. package/dist/model/cli/cli-client.js +4 -2
  39. package/dist/model/cli/cli-client.js.map +1 -1
  40. package/dist/program.d.ts +12 -0
  41. package/dist/program.d.ts.map +1 -0
  42. package/dist/program.js +42 -0
  43. package/dist/program.js.map +1 -0
  44. package/dist/typedoc-entry.d.ts +6 -0
  45. package/dist/typedoc-entry.d.ts.map +1 -0
  46. package/dist/typedoc-entry.js +14 -0
  47. package/dist/typedoc-entry.js.map +1 -0
  48. package/package.json +18 -7
  49. package/skills/skillit-bootstrap/SKILL.md +115 -0
  50. package/skills/skillit-bootstrap/references/surface-routing.md +97 -0
  51. package/CHANGELOG.md +0 -32
  52. package/scripts/gen-refine-cli-skill.mjs +0 -48
  53. package/src/__tests__/anthropic-model.test.ts +0 -45
  54. package/src/__tests__/anthropic-prompt.test.ts +0 -102
  55. package/src/__tests__/cli-adapters.test.ts +0 -119
  56. package/src/__tests__/cli-client.test.ts +0 -58
  57. package/src/__tests__/cli-run.test.ts +0 -52
  58. package/src/__tests__/detect-mode.test.ts +0 -114
  59. package/src/__tests__/detect-source.test.ts +0 -158
  60. package/src/__tests__/fixtures/bin-with-program.mjs +0 -6
  61. package/src/__tests__/init.test.ts +0 -218
  62. package/src/__tests__/model-client-factory.test.ts +0 -28
  63. package/src/__tests__/refine-resolve.test.ts +0 -72
  64. package/src/bin.ts +0 -18
  65. package/src/commands/init.ts +0 -207
  66. package/src/commands/refine.ts +0 -261
  67. package/src/detect-mode.ts +0 -94
  68. package/src/detect-source.ts +0 -123
  69. package/src/index.ts +0 -3
  70. package/src/model/anthropic.ts +0 -116
  71. package/src/model/cli/adapters.ts +0 -178
  72. package/src/model/cli/cli-client.ts +0 -52
  73. package/src/model/cli/run.ts +0 -83
  74. package/src/model/model-client-factory.ts +0 -62
  75. package/src/model/models.ts +0 -7
  76. package/tsconfig.build.json +0 -9
  77. package/tsconfig.json +0 -4
package/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # @skillit/client
2
+
3
+ > The `skillit` command-line interface: generate, audit, and refine AI-agent
4
+ > skills from a TypeScript codebase, plus the Anthropic model client that powers
5
+ > the headless refine loop.
6
+
7
+ `@skillit/client` ships the `skillit` binary. It ties together the skillit
8
+ source extractors (`@skillit/cli`, `@skillit/mcp`, `@skillit/core`) behind one
9
+ CLI, and provides the Anthropic-backed `ModelClient` used by `skillit refine`
10
+ when run without an agent.
11
+
12
+ ## Commands
13
+
14
+ | Command | What it does |
15
+ | ---------------- | ---------------------------------------------------------------------------------------------------- |
16
+ | `skillit gen` | Deterministically (re)generate the skill from current source — no model, no install. |
17
+ | `skillit audit` | Audit + judge the generated skill; `--json` emits the full report with per-finding source locations. |
18
+ | `skillit init` | Detect the project and install the matching `@skillit/*` package (install/wire only). |
19
+ | `skillit refine` | Headless audit → draft → review loop that writes routing annotations back into source. |
20
+ | `skillit mcp` | Extract / bundle skills from a live MCP server. |
21
+
22
+ ## Quick start
23
+
24
+ ```bash
25
+ # Install
26
+ npm install --save-dev @skillit/client
27
+
28
+ # Generate a skill from a Commander CLI
29
+ skillit gen --source cli --program ./dist/cli.js#program
30
+
31
+ # Check its grade and findings as JSON
32
+ skillit audit --source cli --program ./dist/cli.js#program --json
33
+ ```
34
+
35
+ For the agent-driven workflow (recommended), use the bundled
36
+ `/skillit-bootstrap` skill — see the repository README.
37
+
38
+ ## License
39
+
40
+ MIT
package/dist/bin.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  #!/usr/bin/env node
2
- export {};
2
+ import { buildProgram } from './program.js';
3
+ export { buildProgram };
3
4
  //# sourceMappingURL=bin.d.ts.map
package/dist/bin.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAM5C,OAAO,EAAE,YAAY,EAAE,CAAC"}
package/dist/bin.js CHANGED
@@ -1,16 +1,24 @@
1
1
  #!/usr/bin/env node
2
2
  // packages/client/src/bin.ts
3
- import { Command } from 'commander';
4
- import { buildMcpCommand, reportMcpErrorAndExit } from '@skillit/mcp';
5
- import { buildInitCommand } from './commands/init.js';
6
- import { buildRefineCommand } from './commands/refine.js';
7
- const program = new Command('skillit').description('skillit CLI').version('0.1.0');
8
- program.addCommand(buildRefineCommand());
9
- program.addCommand(buildInitCommand());
10
- program.addCommand(buildMcpCommand());
11
- program.parseAsync(process.argv).catch((err) => {
12
- // Preserve the mcp exit-code contract for the `skillit mcp …` path; other
13
- // errors keep the prior generic behavior (stderr message + exit 1).
14
- reportMcpErrorAndExit(err);
15
- });
3
+ import { pathToFileURL } from 'node:url';
4
+ import { reportMcpErrorAndExit } from '@skillit/mcp';
5
+ import { buildProgram } from './program.js';
6
+ // Re-export the factory so `@skillit/cli`'s program loader can auto-discover
7
+ // the skillit program from this package's `bin` entry (it probes `buildProgram`
8
+ // / `createProgram` / `program` / `default`) when `skillit init/refine --source
9
+ // cli` is run without an explicit `--program`.
10
+ export { buildProgram };
11
+ // Only parse argv when this file is the executed entry — NOT when it is
12
+ // imported for introspection (auto-discovery does `import(bin)`). Parsing on
13
+ // import would consume `process.argv` and could exit the host process.
14
+ const argv1 = process.argv[1];
15
+ if (argv1 !== undefined && import.meta.url === pathToFileURL(argv1).href) {
16
+ buildProgram()
17
+ .parseAsync(process.argv)
18
+ .catch((err) => {
19
+ // Preserve the mcp exit-code contract for the `skillit mcp …` path; other
20
+ // errors keep the prior generic behavior (stderr message + exit 1).
21
+ reportMcpErrorAndExit(err);
22
+ });
23
+ }
16
24
  //# sourceMappingURL=bin.js.map
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,6BAA6B;AAC7B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAEnF,OAAO,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,CAAC;AACzC,OAAO,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC;AACvC,OAAO,CAAC,UAAU,CAAC,eAAe,EAAE,CAAC,CAAC;AAEtC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IACtD,0EAA0E;IAC1E,oEAAoE;IACpE,qBAAqB,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,6BAA6B;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,6EAA6E;AAC7E,gFAAgF;AAChF,gFAAgF;AAChF,+CAA+C;AAC/C,OAAO,EAAE,YAAY,EAAE,CAAC;AAExB,wEAAwE;AACxE,6EAA6E;AAC7E,uEAAuE;AACvE,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC9B,IAAI,KAAK,KAAK,SAAS,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IACzE,YAAY,EAAE;SACX,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC;SACxB,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;QACtB,0EAA0E;QAC1E,oEAAoE;QACpE,qBAAqB,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { Command } from 'commander';
2
+ import { type ActionableImprovement, type AuditResult, type ExtractedSkill, type RefineSource, type SkillJudgeEstimate, type TargetLocation } from '@skillit/core';
3
+ import { type RefineSourceKind } from '../detect-source.js';
4
+ /** An improvement with each of its targets resolved to a concrete location (or null). */
5
+ export interface AuditReportImprovement extends ActionableImprovement {
6
+ /** One entry per `targets[]`, in order; `null` when the source can't resolve it. */
7
+ resolvedLocations: Array<TargetLocation | null>;
8
+ }
9
+ /** The full JSON report emitted by `skillit audit --json`. */
10
+ export interface AuditReport {
11
+ audit: AuditResult;
12
+ estimate: SkillJudgeEstimate;
13
+ improvements: AuditReportImprovement[];
14
+ }
15
+ /**
16
+ * Pure report builder: audit + score the skill, then resolve every improvement
17
+ * target to its on-disk location via the source's optional resolveTargetLocation.
18
+ */
19
+ export declare function buildAuditReport(source: RefineSource, skill: ExtractedSkill): Promise<AuditReport>;
20
+ /** Parsed options for the `audit` action. */
21
+ export interface AuditCommandOpts {
22
+ source?: string;
23
+ program?: string;
24
+ configType?: string;
25
+ mcp?: string;
26
+ server?: string;
27
+ mode?: string;
28
+ overlay?: string;
29
+ json?: boolean;
30
+ }
31
+ export declare function runAuditCommand(opts: AuditCommandOpts): Promise<void>;
32
+ export declare function buildAuditCommand(): Command;
33
+ export type { RefineSourceKind };
34
+ //# sourceMappingURL=audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAIL,KAAK,qBAAqB,EAC1B,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,qBAAqB,CAAC;AAK7B,yFAAyF;AACzF,MAAM,WAAW,sBAAuB,SAAQ,qBAAqB;IACnE,oFAAoF;IACpF,iBAAiB,EAAE,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;CACjD;AAED,8DAA8D;AAC9D,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,YAAY,EAAE,sBAAsB,EAAE,CAAC;CACxC;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,WAAW,CAAC,CAkBtB;AAED,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqG3E;AAED,wBAAgB,iBAAiB,IAAI,OAAO,CAY3C;AAGD,YAAY,EAAE,gBAAgB,EAAE,CAAC"}
@@ -0,0 +1,139 @@
1
+ // packages/client/src/commands/audit.ts
2
+ import { isAbsolute, join } from 'node:path';
3
+ import { Command } from 'commander';
4
+ import { auditSkill, ConfigRefineSource, estimateSkillJudgeScore } from '@skillit/core';
5
+ import { CliRefineSource, loadProgram } from '@skillit/cli';
6
+ import { classifyRefineSources, detectInstalledSources, detectProjectNature } from '../detect-source.js';
7
+ import { parseConfigTypeSpec, resolveRefineSource } from './refine.js';
8
+ import { resolveTypeDocEntry } from '../typedoc-entry.js';
9
+ import { resolveMcpMode } from '../mcp-mode.js';
10
+ /**
11
+ * Pure report builder: audit + score the skill, then resolve every improvement
12
+ * target to its on-disk location via the source's optional resolveTargetLocation.
13
+ */
14
+ export async function buildAuditReport(source, skill) {
15
+ const audit = auditSkill(skill);
16
+ const estimate = estimateSkillJudgeScore(audit, skill);
17
+ const improvements = [];
18
+ for (const imp of estimate.improvements) {
19
+ const targets = imp.targets ?? [];
20
+ const resolvedLocations = [];
21
+ for (const target of targets) {
22
+ const loc = source.resolveTargetLocation
23
+ ? await source.resolveTargetLocation(target)
24
+ : undefined;
25
+ resolvedLocations.push(loc ?? null);
26
+ }
27
+ improvements.push({ ...imp, resolvedLocations });
28
+ }
29
+ return { audit, estimate, improvements };
30
+ }
31
+ export async function runAuditCommand(opts) {
32
+ const cwd = process.cwd();
33
+ // Auto-detect the project nature once when no explicit --source is given;
34
+ // reuse it for both the typedoc and mcp branches below.
35
+ const nature = opts.source === undefined ? await detectProjectNature(cwd) : undefined;
36
+ // mcp: explicit --source, an explicit --mcp path (which only the mcp source
37
+ // consumes), or auto-detected via @modelcontextprotocol/sdk.
38
+ const isMcp = opts.source === 'mcp' ||
39
+ (opts.source === undefined && (opts.mcp !== undefined || nature === 'mcp'));
40
+ // typedoc: explicit, or auto-detected as a plain TS library — but never when
41
+ // an explicit --mcp path was given (that routes to mcp above).
42
+ const isTypedoc = opts.source === 'typedoc' ||
43
+ (opts.source === undefined && opts.mcp === undefined && nature === 'typedoc');
44
+ let source;
45
+ if (isTypedoc) {
46
+ // Lazy import: keeps `@skillit/typedoc` (and its `typedoc` peer) off the CLI
47
+ // startup path so non-typedoc commands run without TypeDoc installed.
48
+ const { createTypeDocRefineSource } = await import('@skillit/typedoc');
49
+ const { entryPoints, tsconfig } = resolveTypeDocEntry(cwd);
50
+ source = createTypeDocRefineSource({ entryPoints, tsconfig, cwd });
51
+ }
52
+ else if (isMcp) {
53
+ if (opts.mcp === undefined) {
54
+ console.error('The mcp source requires --mcp <path> (path to mcp.json or MCP config file).');
55
+ process.exitCode = 1;
56
+ return;
57
+ }
58
+ const resolved = await resolveMcpMode(cwd, opts);
59
+ if ('error' in resolved) {
60
+ console.error(resolved.error);
61
+ process.exitCode = 1;
62
+ return;
63
+ }
64
+ // Lazy import: keeps `@skillit/mcp` (and its SDK peer) off the CLI startup
65
+ // path so non-mcp commands run without the MCP SDK installed.
66
+ const { createMcpRefineSource } = await import('@skillit/mcp');
67
+ source = await createMcpRefineSource({
68
+ mcpPath: isAbsolute(opts.mcp) ? opts.mcp : join(cwd, opts.mcp),
69
+ mode: resolved.mode,
70
+ cwd,
71
+ ...(opts.server !== undefined ? { serverName: opts.server } : {}),
72
+ overlayPath: opts.overlay
73
+ ? isAbsolute(opts.overlay)
74
+ ? opts.overlay
75
+ : join(cwd, opts.overlay)
76
+ : join(cwd, '.skillit-overlay.json'),
77
+ sourceGlob: join(cwd, '**', '*.ts')
78
+ });
79
+ }
80
+ else {
81
+ const candidates = await detectInstalledSources(cwd);
82
+ const detected = classifyRefineSources(candidates);
83
+ const resolution = resolveRefineSource(opts, detected, candidates);
84
+ if ('error' in resolution) {
85
+ console.error(resolution.error);
86
+ process.exitCode = 1;
87
+ return;
88
+ }
89
+ if (resolution.kind === 'cli') {
90
+ const program = await loadProgram({ program: opts.program, cwd });
91
+ source = new CliRefineSource({ program, sourceGlob: join(cwd, '**', '*.ts'), cwd });
92
+ }
93
+ else if (resolution.kind === 'config') {
94
+ const parsed = parseConfigTypeSpec(opts.configType, cwd);
95
+ if ('error' in parsed) {
96
+ console.error(parsed.error);
97
+ process.exitCode = 1;
98
+ return;
99
+ }
100
+ // No explicit name: ConfigRefineSource derives it from the package nearest
101
+ // the config file (→ typeName), matching what `skillit gen` writes for the
102
+ // same source.
103
+ source = new ConfigRefineSource({
104
+ configFile: isAbsolute(parsed.configFile)
105
+ ? parsed.configFile
106
+ : join(cwd, parsed.configFile),
107
+ typeName: parsed.typeName
108
+ });
109
+ }
110
+ else {
111
+ console.error(`skillit audit does not yet support the ${resolution.kind} source; cli, config, and typedoc are supported in this release.`);
112
+ process.exitCode = 1;
113
+ return;
114
+ }
115
+ }
116
+ const skill = await source.extract();
117
+ const report = await buildAuditReport(source, skill);
118
+ if (opts.json) {
119
+ process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
120
+ }
121
+ else {
122
+ console.log(`Grade ${report.estimate.grade} (${report.estimate.total}/120)`);
123
+ console.log(`Fatal ${report.audit.summary.fatal}, Error ${report.audit.summary.error}, Warning ${report.audit.summary.warning}, Alert ${report.audit.summary.alert}`);
124
+ }
125
+ }
126
+ export function buildAuditCommand() {
127
+ return new Command('audit')
128
+ .description('Audit + judge the generated skill; emit findings (with target locations) as JSON')
129
+ .option('--source <kind>', 'cli | mcp | typedoc | config (auto-detected if omitted)')
130
+ .option('--program <file#export>', 'commander program entry (cli source)')
131
+ .option('--config-type <file#export>', 'config type entry (config source)')
132
+ .option('--mcp <path>', 'path to mcp.json or MCP config file')
133
+ .option('--server <name>', 'MCP server entry to select (mcp source)')
134
+ .option('--mode <build|runtime>', 'MCP refine mode (auto-detected if omitted)')
135
+ .option('--overlay <path>', 'overlay JSON path (mcp runtime mode)')
136
+ .option('--json', 'emit the full AuditResult + SkillJudgeEstimate as JSON')
137
+ .action((opts) => runAuditCommand(opts));
138
+ }
139
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { Command } from 'commander';
2
+ import { type GenerateConfigSkillOpts, type GenerateMcpSkillOpts, type GenerateSkillOpts, type GenerateTypeDocSkillOpts } from '../generate.js';
3
+ /** Injectable generators (test seam, mirrors InitDeps). */
4
+ export interface GenDeps {
5
+ generateCliSkill?(opts: GenerateSkillOpts): Promise<void>;
6
+ generateConfigSkill?(opts: GenerateConfigSkillOpts): Promise<void>;
7
+ generateTypeDocSkill?(opts: GenerateTypeDocSkillOpts): Promise<void>;
8
+ generateMcpSkill?(opts: GenerateMcpSkillOpts): Promise<void>;
9
+ }
10
+ /** Parsed options for the `gen` action. */
11
+ export interface GenCommandOpts {
12
+ source?: string;
13
+ program?: string;
14
+ configType?: string;
15
+ mcp?: string;
16
+ server?: string;
17
+ out: string;
18
+ }
19
+ export declare function buildGenCommand(deps?: GenDeps): Command;
20
+ //# sourceMappingURL=gen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gen.d.ts","sourceRoot":"","sources":["../../src/commands/gen.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,OAAO,EAKL,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC9B,MAAM,gBAAgB,CAAC;AAIxB,2DAA2D;AAC3D,MAAM,WAAW,OAAO;IACtB,gBAAgB,CAAC,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,mBAAmB,CAAC,CAAC,IAAI,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,oBAAoB,CAAC,CAAC,IAAI,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,gBAAgB,CAAC,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AAED,2CAA2C;AAC3C,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb;AAmBD,wBAAgB,eAAe,CAAC,IAAI,GAAE,OAAY,GAAG,OAAO,CAgG3D"}
@@ -0,0 +1,108 @@
1
+ // packages/client/src/commands/gen.ts
2
+ import { isAbsolute, join } from 'node:path';
3
+ import { readFile } from 'node:fs/promises';
4
+ import { Command } from 'commander';
5
+ import { classifyRefineSources, detectInstalledSources, detectProjectNature } from '../detect-source.js';
6
+ import { generateCliSkill as defaultGenerateCliSkill, generateConfigSkill as defaultGenerateConfigSkill, generateMcpSkill as defaultGenerateMcpSkill, generateTypeDocSkill as defaultGenerateTypeDocSkill } from '../generate.js';
7
+ import { parseConfigTypeSpec, resolveRefineSource } from './refine.js';
8
+ import { resolveTypeDocEntry } from '../typedoc-entry.js';
9
+ /** Strip a leading `@scope/` from a package name for a skill dir name. */
10
+ function skillNameFrom(packageName) {
11
+ const slash = packageName.indexOf('/');
12
+ if (packageName.startsWith('@') && slash !== -1)
13
+ return packageName.slice(slash + 1);
14
+ return packageName;
15
+ }
16
+ async function readPackageName(cwd) {
17
+ try {
18
+ const raw = await readFile(join(cwd, 'package.json'), 'utf8');
19
+ const pkg = JSON.parse(raw);
20
+ return pkg.name ?? 'skill';
21
+ }
22
+ catch {
23
+ return 'skill';
24
+ }
25
+ }
26
+ export function buildGenCommand(deps = {}) {
27
+ const generateCliSkill = deps.generateCliSkill ?? defaultGenerateCliSkill;
28
+ const generateConfigSkill = deps.generateConfigSkill ?? defaultGenerateConfigSkill;
29
+ const generateTypeDocSkill = deps.generateTypeDocSkill ?? defaultGenerateTypeDocSkill;
30
+ const generateMcpSkill = deps.generateMcpSkill ?? defaultGenerateMcpSkill;
31
+ return new Command('gen')
32
+ .description('Deterministically (re)generate the skill from current source — no model, no install')
33
+ .option('--source <kind>', 'cli | mcp | typedoc | config (auto-detected if omitted)')
34
+ .option('--program <file#export>', 'commander program entry (cli source)')
35
+ .option('--config-type <file#export>', 'config type entry (config source)')
36
+ .option('--mcp <path>', 'path to mcp.json or MCP config file (mcp source)')
37
+ .option('--server <name>', 'MCP server entry to select (mcp source)')
38
+ .option('--out <dir>', 'output directory for the generated skill', 'skills')
39
+ .action(async (opts) => {
40
+ const cwd = process.cwd();
41
+ const outDir = join(cwd, opts.out);
42
+ // Detect the project nature at most once (it can spawn the project's CLI
43
+ // bin). Only needed to auto-route when --source is omitted.
44
+ const nature = opts.source === undefined ? await detectProjectNature(cwd) : undefined;
45
+ if (opts.source === 'config') {
46
+ if (opts.configType === undefined) {
47
+ throw new Error('The config source requires --config-type <file#export> (e.g. ./src/config.ts#MyConfig).');
48
+ }
49
+ const parsed = parseConfigTypeSpec(opts.configType, cwd);
50
+ if ('error' in parsed)
51
+ throw new Error(parsed.error);
52
+ // No explicit name: ConfigRefineSource derives it from the package
53
+ // nearest the config file (→ typeName), which is more correct in a
54
+ // monorepo than this command's cwd.
55
+ await generateConfigSkill({
56
+ configFile: parsed.configFile,
57
+ typeName: parsed.typeName,
58
+ outDir
59
+ });
60
+ return;
61
+ }
62
+ // mcp: explicit --source, an explicit --mcp path (which only the mcp
63
+ // source consumes), or auto-detected via @modelcontextprotocol/sdk.
64
+ const isMcp = opts.source === 'mcp' ||
65
+ (opts.source === undefined && (opts.mcp !== undefined || nature === 'mcp'));
66
+ if (isMcp) {
67
+ if (opts.mcp === undefined) {
68
+ throw new Error('The mcp source requires --mcp <path> (path to mcp.json or MCP config file).');
69
+ }
70
+ const mcpPath = isAbsolute(opts.mcp) ? opts.mcp : join(cwd, opts.mcp);
71
+ await generateMcpSkill({
72
+ mcpPath,
73
+ ...(opts.server !== undefined ? { server: opts.server } : {}),
74
+ outDir
75
+ });
76
+ return;
77
+ }
78
+ // typedoc: explicit, or auto-detected as a plain TS library.
79
+ const isTypedoc = opts.source === 'typedoc' || nature === 'typedoc';
80
+ if (isTypedoc) {
81
+ const { entryPoints, tsconfig } = resolveTypeDocEntry(cwd);
82
+ await generateTypeDocSkill({ cwd, entryPoints, tsconfig, outDir });
83
+ return;
84
+ }
85
+ // Resolve the cli source the same way refine does (handles auto-detection
86
+ // and the ambiguous/none guidance).
87
+ const candidates = await detectInstalledSources(cwd);
88
+ const detected = classifyRefineSources(candidates);
89
+ const resolution = resolveRefineSource(opts, detected, candidates);
90
+ if ('error' in resolution)
91
+ throw new Error(resolution.error);
92
+ if (resolution.kind === 'cli') {
93
+ const name = skillNameFrom(await readPackageName(cwd));
94
+ const nature = 'cli';
95
+ await generateCliSkill({
96
+ cwd,
97
+ nature,
98
+ name,
99
+ outDir,
100
+ ...(opts.program !== undefined ? { program: opts.program } : {})
101
+ });
102
+ return;
103
+ }
104
+ // Auto-detection resolved to a source gen can't generate yet (e.g. mcp).
105
+ throw new Error(`skillit gen does not yet support the ${resolution.kind} source; cli and config are supported in this release.`);
106
+ });
107
+ }
108
+ //# sourceMappingURL=gen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gen.js","sourceRoot":"","sources":["../../src/commands/gen.ts"],"names":[],"mappings":"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"}
@@ -1,32 +1,13 @@
1
1
  import { Command } from 'commander';
2
- import { type RefineSourceKind } from '../detect-source.js';
3
- import { type RefineCommandOpts } from './refine.js';
4
2
  type PackageManager = 'pnpm' | 'yarn' | 'npm';
5
- /** Options passed to the (CLI-path) skill generator. */
6
- export interface GenerateSkillOpts {
7
- /** Project root being initialized. */
8
- cwd: string;
9
- /** Resolved project nature. */
10
- nature: RefineSourceKind;
11
- /** Skill name (consumer package name, scope stripped). */
12
- name: string;
13
- /** Absolute output directory (`<cwd>/<out>`). */
14
- outDir: string;
15
- /** `--program <file#export>` entry, if provided. */
16
- program?: string;
17
- }
18
3
  /**
19
- * Injectable side-effecting steps for {@link buildInitCommand}. All optional;
20
- * real defaults run install / generate / refine. Tests inject stubs so no real
21
- * install, network, or model call runs.
4
+ * Injectable side-effecting steps for {@link buildInitCommand}. Phase 0 init is
5
+ * install/wire ONLY it no longer generates or refines (those are `skillit
6
+ * gen` and `skillit refine`), so the only injectable step is the install.
22
7
  */
23
8
  export interface InitDeps {
24
9
  /** Install `pkg` as a dev dependency in `cwd` using package manager `pm`. */
25
10
  runInstall?(pkg: string, pm: PackageManager, cwd: string): Promise<void>;
26
- /** Generate the initial skill (CLI path only). */
27
- generateSkill?(opts: GenerateSkillOpts): Promise<void>;
28
- /** Dispatch the refine loop for the resolved source. */
29
- runRefine?(opts: RefineCommandOpts): Promise<void>;
30
11
  }
31
12
  export declare function buildInitCommand(deps?: InitDeps): Command;
32
13
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEvE,KAAK,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAE9C,wDAAwD;AACxD,MAAM,WAAW,iBAAiB;IAChC,sCAAsC;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,+BAA+B;IAC/B,MAAM,EAAE,gBAAgB,CAAC;IACzB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,6EAA6E;IAC7E,UAAU,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,kDAAkD;IAClD,aAAa,CAAC,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,wDAAwD;IACxD,SAAS,CAAC,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpD;AAuED,wBAAgB,gBAAgB,CAAC,IAAI,GAAE,QAAa,GAAG,OAAO,CA8F7D"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,KAAK,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAE9C;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,6EAA6E;IAC7E,UAAU,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1E;AAqCD,wBAAgB,gBAAgB,CAAC,IAAI,GAAE,QAAa,GAAG,OAAO,CAkE7D"}
@@ -1,11 +1,7 @@
1
1
  // packages/client/src/commands/init.ts
2
2
  import { spawn } from 'node:child_process';
3
- import { readFile } from 'node:fs/promises';
4
- import { join } from 'node:path';
5
3
  import { Command } from 'commander';
6
- import { extractCliSkill, loadProgram, writeCliSkill } from '@skillit/cli';
7
4
  import { detectPackageManager, detectProjectNature } from '../detect-source.js';
8
- import { runRefineCommand } from './refine.js';
9
5
  const VALID_SOURCES = ['cli', 'mcp', 'typedoc'];
10
6
  /** Map a project nature to the `@skillit/*` package that handles it. */
11
7
  function natureToPackage(nature) {
@@ -23,24 +19,6 @@ function addDevCommand(pm, pkg) {
23
19
  return `yarn add -D ${pkg}`;
24
20
  return `npm install -D ${pkg}`;
25
21
  }
26
- /** Strip a leading `@scope/` from a package name for use as a skill dir name. */
27
- function skillNameFrom(packageName) {
28
- const slash = packageName.indexOf('/');
29
- if (packageName.startsWith('@') && slash !== -1) {
30
- return packageName.slice(slash + 1);
31
- }
32
- return packageName;
33
- }
34
- async function readPackageName(cwd) {
35
- try {
36
- const raw = await readFile(join(cwd, 'package.json'), 'utf8');
37
- const pkg = JSON.parse(raw);
38
- return pkg.name ?? 'skill';
39
- }
40
- catch {
41
- return 'skill';
42
- }
43
- }
44
22
  /** Default install: spawn the package manager's add-dev command, cwd-scoped. */
45
23
  function defaultRunInstall(pkg, pm, cwd) {
46
24
  const command = addDevCommand(pm, pkg);
@@ -56,30 +34,24 @@ function defaultRunInstall(pkg, pm, cwd) {
56
34
  });
57
35
  });
58
36
  }
59
- /** Default CLI-path skill generation: loadProgram → extractCliSkill → writeCliSkill. */
60
- async function defaultGenerateSkill(opts) {
61
- const program = await loadProgram({ program: opts.program, cwd: opts.cwd });
62
- const skill = await extractCliSkill({ program, metadata: { name: opts.name } });
63
- writeCliSkill(skill, { outDir: opts.outDir });
64
- }
65
- /** Default refine dispatch: reuse the shared refine command body. */
66
- function defaultRunRefine(opts) {
67
- return runRefineCommand(opts);
68
- }
69
37
  export function buildInitCommand(deps = {}) {
70
38
  const runInstall = deps.runInstall ?? defaultRunInstall;
71
- const generateSkill = deps.generateSkill ?? defaultGenerateSkill;
72
- const runRefine = deps.runRefine ?? defaultRunRefine;
73
39
  return new Command('init')
74
- .description('Detect the project, install the right @skillit package, generate + refine a skill')
75
- .option('--source <kind>', 'cli | mcp | typedoc (auto-detected if omitted)')
76
- .option('--program <file#export>', 'commander program entry (cli source)')
77
- .option('--out <dir>', 'output directory for the generated skill', 'skills')
78
- .option('--model-client <kind>', 'model backend for refine: api | claude | codex | copilot', 'api')
79
- .option('--model-cli-timeout <ms>', 'per-call timeout for cli model backends (ms)')
40
+ .description('Detect the project and install the right @skillit package (then run `skillit gen`)')
41
+ .option('--source <kind>', 'cli | mcp | typedoc | config (auto-detected if omitted)')
42
+ .option('--config-type <file#export>', 'config type entry (config source)')
80
43
  .action(async (opts) => {
81
44
  const cwd = process.cwd();
82
- // 1. Resolve nature: explicit --source wins, else detect.
45
+ // Config source is built into the client — nothing to install. Just point
46
+ // the user at `skillit gen`.
47
+ if (opts.source === 'config') {
48
+ if (opts.configType === undefined) {
49
+ throw new Error('The config source requires --config-type <file#export> (e.g. ./src/config.ts#MyConfig).');
50
+ }
51
+ console.log(`Config source needs no install. Generate the skill with:\n skillit gen --source config --config-type ${opts.configType}`);
52
+ return;
53
+ }
54
+ // Resolve nature: explicit --source wins, else detect.
83
55
  let nature;
84
56
  if (opts.source !== undefined) {
85
57
  if (!VALID_SOURCES.includes(opts.source)) {
@@ -90,7 +62,7 @@ export function buildInitCommand(deps = {}) {
90
62
  else {
91
63
  nature = await detectProjectNature(cwd);
92
64
  }
93
- // 2 + 3. Map nature → package, install via the detected package manager.
65
+ // Map nature → package, install via the detected package manager.
94
66
  const pkg = natureToPackage(nature);
95
67
  const pm = detectPackageManager(cwd);
96
68
  const command = addDevCommand(pm, pkg);
@@ -99,53 +71,20 @@ export function buildInitCommand(deps = {}) {
99
71
  }
100
72
  catch (error) {
101
73
  const reason = error instanceof Error ? error.message : String(error);
102
- // Surface the exact command and STOP — do not generate or refine.
103
74
  throw new Error(`Install failed (${reason}). Run it manually:\n ${command}`);
104
75
  }
105
- // 4 + 5. Generate + refine — CLI-first: only the cli source is fully
106
- // automated this pass. For mcp/typedoc, skip both and print actionable
107
- // next-step guidance rather than silently no-opping (refine needs
108
- // source-specific flags like --mcp that init can't supply yet).
76
+ // Source-aware next step: `skillit gen` generates the cli source today;
77
+ // mcp uses `skillit mcp extract` and typedoc the TypeDoc plugin (gen
78
+ // support for those lands in a later phase). Don't point users at a
79
+ // command that would immediately error for their source.
109
80
  if (nature === 'cli') {
110
- const outDir = join(cwd, opts.out);
111
- const name = skillNameFrom(await readPackageName(cwd));
112
- const generateOpts = {
113
- cwd,
114
- nature,
115
- name,
116
- outDir,
117
- ...(opts.program !== undefined ? { program: opts.program } : {})
118
- };
119
- try {
120
- await generateSkill(generateOpts);
121
- }
122
- catch (error) {
123
- // The cli source only auto-loads a commander program. A yargs/other
124
- // CLI (still classified as 'cli') can't be generated yet — degrade
125
- // gracefully: surface the reason and how to proceed, do NOT crash,
126
- // and do NOT run refine/regenerate on a failed generate.
127
- const reason = error instanceof Error ? error.message : String(error);
128
- console.log(`Installed ${pkg}, but couldn't auto-load a commander program (${reason}). ` +
129
- `If this is a commander CLI, run: skillit refine --source cli --program <file#export>. ` +
130
- `(yargs/other CLIs aren't auto-generated yet.)`);
131
- return;
132
- }
133
- await runRefine({
134
- source: nature,
135
- ...(opts.program !== undefined ? { program: opts.program } : {}),
136
- ...(opts.modelClient !== undefined ? { modelClient: opts.modelClient } : {}),
137
- ...(opts.modelCliTimeout !== undefined ? { modelCliTimeout: opts.modelCliTimeout } : {}),
138
- maxIterations: '5',
139
- items: '5'
140
- });
141
- // refine only writes JSDoc back into source files; regenerate so the
142
- // on-disk skill reflects the freshly-written annotations. Runs only
143
- // after a successful refine (a refine throw propagates above).
144
- await generateSkill(generateOpts);
81
+ console.log(`Installed ${pkg}. Generate the skill with:\n skillit gen --source cli`);
82
+ }
83
+ else if (nature === 'mcp') {
84
+ console.log(`Installed ${pkg}. Generate the skill with:\n skillit mcp extract\n(skillit gen support for the mcp source lands in a later phase.)`);
145
85
  }
146
86
  else {
147
- const extra = nature === 'mcp' ? ' [--mcp <path>]' : '';
148
- console.log(`Installed ${pkg}. Skill generation + refine for the ${nature} source isn't automated yet — run: skillit refine --source ${nature}${extra}`);
87
+ console.log(`Installed ${pkg}. Generate the skill by running TypeDoc with the plugin enabled.\n(skillit gen support for the typedoc source lands in a later phase.)`);
149
88
  }
150
89
  });
151
90
  }