@tanstack/intent 0.0.14 → 0.0.20

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 (36) hide show
  1. package/README.md +42 -5
  2. package/dist/cli.d.mts +6 -1
  3. package/dist/cli.mjs +253 -170
  4. package/dist/display-CuCDLPP_.mjs +3 -0
  5. package/dist/index.d.mts +10 -11
  6. package/dist/index.mjs +37 -14
  7. package/dist/install-prompt-C0M-U3WZ.mjs +59 -0
  8. package/dist/intent-library.mjs +5 -49
  9. package/dist/{library-scanner-B1tmOzwf.mjs → library-scanner-DBOEhfm8.mjs} +4 -5
  10. package/dist/library-scanner.d.mts +5 -5
  11. package/dist/library-scanner.mjs +2 -2
  12. package/dist/scanner-BHPl60jH.mjs +5 -0
  13. package/dist/scanner-DVepyEwz.mjs +365 -0
  14. package/dist/setup-B-zdCBu4.d.mts +36 -0
  15. package/dist/setup-mGV2dZrq.mjs +367 -0
  16. package/dist/setup.d.mts +2 -2
  17. package/dist/setup.mjs +3 -2
  18. package/dist/{staleness-DJfMKH62.mjs → staleness-DZKvsLVq.mjs} +24 -3
  19. package/dist/staleness-Dr5-5wj5.mjs +4 -0
  20. package/dist/{types-BmnI8kFB.d.mts → types-ddLtccfV.d.mts} +30 -7
  21. package/dist/utils-BfjM1mQe.mjs +152 -0
  22. package/dist/utils-D7OKi0Rn.mjs +3 -0
  23. package/meta/domain-discovery/SKILL.md +95 -20
  24. package/meta/feedback-collection/SKILL.md +20 -1
  25. package/meta/generate-skill/SKILL.md +56 -5
  26. package/meta/templates/workflows/check-skills.yml +4 -4
  27. package/meta/templates/workflows/{notify-playbooks.yml → notify-intent.yml} +4 -4
  28. package/meta/tree-generator/SKILL.md +2 -2
  29. package/package.json +9 -5
  30. package/dist/scanner-CECGXgox.mjs +0 -4
  31. package/dist/scanner-CY40iozO.mjs +0 -218
  32. package/dist/setup-CANkTz55.d.mts +0 -18
  33. package/dist/setup-Nif1-nhS.mjs +0 -211
  34. package/dist/staleness-C1h7RuZ9.mjs +0 -4
  35. package/dist/utils-CDJzAdjD.mjs +0 -79
  36. /package/dist/{display-D_XzuGnu.mjs → display-DhsUxNJW.mjs} +0 -0
package/README.md CHANGED
@@ -10,9 +10,9 @@ Docs target humans who browse. Types check individual API calls but can't encode
10
10
 
11
11
  The ecosystem already moves toward agent-readable knowledge — Cursor rules, CLAUDE.md files, skills directories. But delivery is stuck in copy-paste: hunt for a community-maintained rules file, paste it into your config, repeat for every tool. No versioning, no update path, no staleness signal.
12
12
 
13
- ## Skills: versioned knowledge in npm
13
+ ## Skills: versioned knowledge in your package manager
14
14
 
15
- A skill is a short, versioned document that tells agents how to use a specific capability of your library — correct patterns, common mistakes, and when to apply them. Skills ship inside your npm package and travel with the tool via `npm update` — not the model's training cutoff, not community-maintained rules files, not prompt snippets in READMEs. Versioned knowledge the maintainer owns, updated when the package updates.
15
+ A skill is a short, versioned document that tells agents how to use a specific capability of your library — correct patterns, common mistakes, and when to apply them. Skills ship inside your package and travel with the tool via your normal package manager update flow — not the model's training cutoff, not community-maintained rules files, not prompt snippets in READMEs. Versioned knowledge the maintainer owns, updated when the package updates.
16
16
 
17
17
  Each skill declares its source docs. When those docs change, the CLI flags the skill for review. One source of truth, one derived artifact that stays in sync.
18
18
 
@@ -20,6 +20,18 @@ The [Agent Skills spec](https://agentskills.io) is an open standard already adop
20
20
 
21
21
  ## Quick Start
22
22
 
23
+ ### Command runners
24
+
25
+ Use whichever command runner matches your environment:
26
+
27
+ | Tool | Pattern |
28
+ | ---- | -------------------------------------------- |
29
+ | npm | `npx @tanstack/intent@latest <command>` |
30
+ | pnpm | `pnpm dlx @tanstack/intent@latest <command>` |
31
+ | bun | `bunx @tanstack/intent@latest <command>` |
32
+
33
+ If you use Deno, support is best-effort today via `npm:` interop with `node_modules` enabled. First-class Deno runtime support is not implemented yet.
34
+
23
35
  ### For library consumers
24
36
 
25
37
  Set up skill-to-task mappings in your project's agent config files (CLAUDE.md, .cursorrules, etc.):
@@ -28,7 +40,7 @@ Set up skill-to-task mappings in your project's agent config files (CLAUDE.md, .
28
40
  npx @tanstack/intent@latest install
29
41
  ```
30
42
 
31
- No per-library setup. No hunting for rules files. Install the package, run `npx @tanstack/intent@latest install`, and the agent understands the tool. Update the package, and skills update too.
43
+ No per-library setup. No hunting for rules files. Install the package, run `npx @tanstack/intent@latest install` through your preferred command runner, and the agent understands the tool. Update the package, and skills update too.
32
44
 
33
45
  List available skills from installed packages:
34
46
 
@@ -52,23 +64,48 @@ Validate your skill files:
52
64
  npx @tanstack/intent@latest validate
53
65
  ```
54
66
 
67
+ In a monorepo, you can validate a package from the repo root:
68
+
69
+ ```bash
70
+ npx @tanstack/intent@latest validate packages/router/skills
71
+ ```
72
+
55
73
  Check for skills that have fallen behind their sources:
56
74
 
57
75
  ```bash
58
76
  npx @tanstack/intent@latest stale
59
77
  ```
60
78
 
79
+ From a monorepo root, `intent stale` checks every workspace package that ships skills. To scope it to one package, pass a directory like `intent stale packages/router`.
80
+
61
81
  Copy CI workflow templates into your repo so validation and staleness checks run on every push:
62
82
 
63
83
  ```bash
64
84
  npx @tanstack/intent@latest setup-github-actions
65
85
  ```
66
86
 
87
+ ## Compatibility
88
+
89
+ | Environment | Status | Notes |
90
+ | -------------- | ----------- | -------------------------------------------------- |
91
+ | Node.js + npm | Supported | Use `npx @tanstack/intent@latest <command>` |
92
+ | Node.js + pnpm | Supported | Use `pnpm dlx @tanstack/intent@latest <command>` |
93
+ | Node.js + Bun | Supported | Use `bunx @tanstack/intent@latest <command>` |
94
+ | Deno | Best-effort | Requires `npm:` interop and `node_modules` support |
95
+ | Yarn PnP | Unsupported | `@tanstack/intent` scans `node_modules` |
96
+
97
+ ## Monorepos
98
+
99
+ - Run `npx @tanstack/intent@latest setup-github-actions` from either the repo root or a package directory. Intent detects the workspace root and writes workflows to the repo-level `.github/workflows/` directory.
100
+ - Generated workflows are monorepo-aware: validation loops over workspace packages with skills, staleness checks run from the workspace root, and notify workflows watch package `src/` and docs paths.
101
+ - Run `npx @tanstack/intent@latest validate packages/<pkg>/skills` from the repo root to validate one package without root-level packaging warnings.
102
+ - Run `npx @tanstack/intent@latest stale` from the repo root to check all workspace packages with skills, or `intent stale packages/<pkg>` to check one package.
103
+
67
104
  ## Keeping skills current
68
105
 
69
106
  The real risk with any derived artifact is staleness. `npx @tanstack/intent@latest stale` flags skills whose source docs have changed, and CI templates catch drift before it ships.
70
107
 
71
- The feedback loop runs both directions. `npx @tanstack/intent@latest feedback` lets users submit structured reports when a skill produces wrong output — which skill, which version, what broke. That context flows back to the maintainer, and the fix ships to everyone on the next `npm update`. Every support interaction produces an artifact that prevents the same class of problem for all future users — not just the one who reported it.
108
+ The feedback loop runs both directions. `npx @tanstack/intent@latest feedback` lets users submit structured reports when a skill produces wrong output — which skill, which version, what broke. That context flows back to the maintainer, and the fix ships to everyone on the next package update. Every support interaction produces an artifact that prevents the same class of problem for all future users — not just the one who reported it.
72
109
 
73
110
  ## CLI Commands
74
111
 
@@ -80,7 +117,7 @@ The feedback loop runs both directions. `npx @tanstack/intent@latest feedback` l
80
117
  | `npx @tanstack/intent@latest scaffold` | Print the guided skill generation prompt |
81
118
  | `npx @tanstack/intent@latest validate [dir]` | Validate SKILL.md files |
82
119
  | `npx @tanstack/intent@latest setup-github-actions` | Copy CI templates into your repo |
83
- | `npx @tanstack/intent@latest stale [--json]` | Check skills for version drift |
120
+ | `npx @tanstack/intent@latest stale [dir] [--json]` | Check skills for version drift |
84
121
  | `npx @tanstack/intent@latest feedback` | Submit skill feedback |
85
122
 
86
123
  ## License
package/dist/cli.d.mts CHANGED
@@ -1 +1,6 @@
1
- export { };
1
+ #!/usr/bin/env node
2
+ //#region src/cli.d.ts
3
+ declare const USAGE = "TanStack Intent CLI\n\nUsage:\n intent list [--json] Discover intent-enabled packages\n intent meta [name] List meta-skills, or print one by name\n intent validate [<dir>] Validate skill files (default: skills/)\n intent install Print a skill that guides your coding agent to set up skill-to-task mappings\n intent scaffold Print maintainer scaffold prompt\n intent add-library-bin Generate bin/intent.{js,mjs} bridge file\n intent edit-package-json Wire package.json (files, bin) for skill publishing\n intent setup-github-actions Copy CI workflow templates to .github/workflows/\n intent stale [dir] [--json] Check skills for staleness";
4
+ declare function main(argv?: Array<string>): Promise<number>;
5
+ //#endregion
6
+ export { USAGE, main };
package/dist/cli.mjs CHANGED
@@ -1,39 +1,88 @@
1
1
  #!/usr/bin/env node
2
- import { r as parseFrontmatter, t as findSkillFiles } from "./utils-CDJzAdjD.mjs";
3
- import { t as scanForIntents } from "./scanner-CY40iozO.mjs";
4
- import { n as printSkillTree, r as printTable, t as computeSkillNameWidth } from "./display-D_XzuGnu.mjs";
5
- import { existsSync, readFileSync, readdirSync } from "node:fs";
2
+ import { t as INSTALL_PROMPT } from "./install-prompt-C0M-U3WZ.mjs";
3
+ import { existsSync, readFileSync, readdirSync, realpathSync } from "node:fs";
6
4
  import { dirname, join, relative, sep } from "node:path";
7
- import { parse } from "yaml";
8
5
  import { fileURLToPath } from "node:url";
9
6
 
10
7
  //#region src/cli.ts
11
8
  function getMetaDir() {
12
9
  return join(dirname(fileURLToPath(import.meta.url)), "..", "meta");
13
10
  }
14
- async function cmdList(args) {
15
- const jsonOutput = args.includes("--json");
16
- let result;
11
+ function fail(message, exitCode = 1) {
12
+ throw {
13
+ message,
14
+ exitCode
15
+ };
16
+ }
17
+ function isCliFailure(value) {
18
+ return !!value && typeof value === "object" && "message" in value && typeof value.message === "string" && "exitCode" in value && typeof value.exitCode === "number";
19
+ }
20
+ async function scanIntentsOrFail() {
21
+ const { scanForIntents } = await import("./scanner-BHPl60jH.mjs");
17
22
  try {
18
- result = await scanForIntents();
23
+ return await scanForIntents();
19
24
  } catch (err) {
20
- console.error(err.message);
21
- process.exit(1);
25
+ fail(err.message);
26
+ }
27
+ }
28
+ function printWarnings(warnings) {
29
+ if (warnings.length === 0) return;
30
+ console.log("Warnings:");
31
+ for (const warning of warnings) console.log(` ⚠ ${warning}`);
32
+ }
33
+ function formatScanCoverage(result) {
34
+ const coverage = [];
35
+ if (result.nodeModules.local.scanned) coverage.push("project node_modules");
36
+ if (result.nodeModules.global.scanned) coverage.push("global node_modules");
37
+ return coverage.join(", ");
38
+ }
39
+ function printVersionConflicts(result) {
40
+ if (result.conflicts.length === 0) return;
41
+ console.log("\nVersion conflicts:\n");
42
+ for (const conflict of result.conflicts) {
43
+ console.log(` ${conflict.packageName} -> using ${conflict.chosen.version}`);
44
+ console.log(` chosen: ${conflict.chosen.packageRoot}`);
45
+ for (const variant of conflict.variants) {
46
+ if (variant.packageRoot === conflict.chosen.packageRoot) continue;
47
+ console.log(` also found: ${variant.version} at ${variant.packageRoot}`);
48
+ }
49
+ console.log();
50
+ }
51
+ }
52
+ function buildValidationFailure(errors, warnings) {
53
+ const lines = [
54
+ "",
55
+ `❌ Validation failed with ${errors.length} error(s):`,
56
+ ""
57
+ ];
58
+ for (const { file, message } of errors) lines.push(` ${file}: ${message}`);
59
+ if (warnings.length > 0) {
60
+ lines.push("", "⚠ Packaging warnings:");
61
+ for (const warning of warnings) lines.push(` ${warning}`);
22
62
  }
63
+ return lines.join("\n");
64
+ }
65
+ async function cmdList(args) {
66
+ const { computeSkillNameWidth, printSkillTree, printTable } = await import("./display-CuCDLPP_.mjs");
67
+ const jsonOutput = args.includes("--json");
68
+ const result = await scanIntentsOrFail();
23
69
  if (jsonOutput) {
24
70
  console.log(JSON.stringify(result, null, 2));
25
71
  return;
26
72
  }
73
+ const scanCoverage = formatScanCoverage(result);
27
74
  if (result.packages.length === 0) {
28
75
  console.log("No intent-enabled packages found.");
76
+ if (scanCoverage) console.log(`Scanned: ${scanCoverage}`);
29
77
  if (result.warnings.length > 0) {
30
- console.log(`\nWarnings:`);
31
- for (const w of result.warnings) console.log(` ⚠ ${w}`);
78
+ console.log();
79
+ printWarnings(result.warnings);
32
80
  }
33
81
  return;
34
82
  }
35
83
  const totalSkills = result.packages.reduce((sum, p) => sum + p.skills.length, 0);
36
84
  console.log(`\n${result.packages.length} intent-enabled packages, ${totalSkills} skills (${result.packageManager})\n`);
85
+ if (scanCoverage) console.log(`Scanned: ${scanCoverage}${result.nodeModules.global.scanned ? " (local packages take precedence)" : ""}\n`);
37
86
  printTable([
38
87
  "PACKAGE",
39
88
  "VERSION",
@@ -45,6 +94,7 @@ async function cmdList(args) {
45
94
  String(pkg.skills.length),
46
95
  pkg.intent.requires?.join(", ") || "–"
47
96
  ]));
97
+ printVersionConflicts(result);
48
98
  const nameWidth = computeSkillNameWidth(result.packages.map((p) => p.skills));
49
99
  const showTypes = result.packages.some((p) => p.skills.some((s) => s.type));
50
100
  console.log(`\nSkills:\n`);
@@ -60,35 +110,21 @@ async function cmdList(args) {
60
110
  console.log(` Submit feedback on skill usage to help maintainers improve the skills.`);
61
111
  console.log(` Load: node_modules/@tanstack/intent/meta/feedback-collection/SKILL.md`);
62
112
  console.log();
63
- if (result.warnings.length > 0) {
64
- console.log(`Warnings:`);
65
- for (const w of result.warnings) console.log(` ⚠ ${w}`);
66
- }
113
+ printWarnings(result.warnings);
67
114
  }
68
- function cmdMeta(args) {
115
+ async function cmdMeta(args) {
116
+ const { parseFrontmatter } = await import("./utils-D7OKi0Rn.mjs");
69
117
  const metaDir = getMetaDir();
70
- if (!existsSync(metaDir)) {
71
- console.error("Meta-skills directory not found.");
72
- process.exit(1);
73
- }
118
+ if (!existsSync(metaDir)) fail("Meta-skills directory not found.");
74
119
  if (args.length > 0) {
75
120
  const name = args[0];
76
- if (name.includes("..") || name.includes("/") || name.includes("\\")) {
77
- console.error(`Invalid meta-skill name: "${name}"`);
78
- process.exit(1);
79
- }
121
+ if (name.includes("..") || name.includes("/") || name.includes("\\")) fail(`Invalid meta-skill name: "${name}"`);
80
122
  const skillFile = join(metaDir, name, "SKILL.md");
81
- if (!existsSync(skillFile)) {
82
- console.error(`Meta-skill "${name}" not found.`);
83
- console.error(`Run \`npx @tanstack/intent meta\` to list available meta-skills.`);
84
- process.exit(1);
85
- }
123
+ if (!existsSync(skillFile)) fail(`Meta-skill "${name}" not found. Run \`intent meta\` to list available meta-skills.`);
86
124
  try {
87
125
  console.log(readFileSync(skillFile, "utf8"));
88
126
  } catch (err) {
89
- const msg = err instanceof Error ? err.message : String(err);
90
- console.error(`Failed to read meta-skill "${name}": ${msg}`);
91
- process.exit(1);
127
+ fail(`Failed to read meta-skill "${name}": ${err instanceof Error ? err.message : String(err)}`);
92
128
  }
93
129
  return;
94
130
  }
@@ -131,19 +167,45 @@ function collectPackagingWarnings(root) {
131
167
  }
132
168
  return warnings;
133
169
  }
134
- function cmdValidate(args) {
170
+ function resolvePackageRoot(startDir) {
171
+ let dir = startDir;
172
+ while (true) {
173
+ if (existsSync(join(dir, "package.json"))) return dir;
174
+ const next = dirname(dir);
175
+ if (next === dir) return startDir;
176
+ dir = next;
177
+ }
178
+ }
179
+ function readPackageName(root) {
180
+ try {
181
+ const pkgJson = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
182
+ return typeof pkgJson.name === "string" ? pkgJson.name : relative(process.cwd(), root) || "unknown";
183
+ } catch {
184
+ return relative(process.cwd(), root) || "unknown";
185
+ }
186
+ }
187
+ async function resolveStaleTargets(targetDir) {
188
+ const resolvedRoot = targetDir ? join(process.cwd(), targetDir) : process.cwd();
189
+ const { checkStaleness } = await import("./staleness-Dr5-5wj5.mjs");
190
+ if (existsSync(join(resolvedRoot, "skills"))) return { reports: [await checkStaleness(resolvedRoot, readPackageName(resolvedRoot))] };
191
+ const { findPackagesWithSkills, findWorkspaceRoot } = await import("./setup.mjs");
192
+ const workspaceRoot = findWorkspaceRoot(resolvedRoot);
193
+ if (workspaceRoot) {
194
+ const packageDirs = findPackagesWithSkills(workspaceRoot);
195
+ if (packageDirs.length > 0) return { reports: await Promise.all(packageDirs.map((packageDir) => checkStaleness(packageDir, readPackageName(packageDir)))) };
196
+ }
197
+ const staleResult = await scanIntentsOrFail();
198
+ return { reports: await Promise.all(staleResult.packages.map((pkg) => checkStaleness(pkg.packageRoot, pkg.name))) };
199
+ }
200
+ async function cmdValidate(args) {
201
+ const [{ parse: parseYaml }, { findSkillFiles }] = await Promise.all([import("yaml"), import("./utils-D7OKi0Rn.mjs")]);
135
202
  const targetDir = args[0] ?? "skills";
136
203
  const skillsDir = join(process.cwd(), targetDir);
137
- if (!existsSync(skillsDir)) {
138
- console.error(`Skills directory not found: ${skillsDir}`);
139
- process.exit(1);
140
- }
204
+ const packageRoot = resolvePackageRoot(skillsDir);
205
+ if (!existsSync(skillsDir)) fail(`Skills directory not found: ${skillsDir}`);
141
206
  const errors = [];
142
207
  const skillFiles = findSkillFiles(skillsDir);
143
- if (skillFiles.length === 0) {
144
- console.error("No SKILL.md files found");
145
- process.exit(1);
146
- }
208
+ if (skillFiles.length === 0) fail("No SKILL.md files found");
147
209
  for (const filePath of skillFiles) {
148
210
  const rel = relative(process.cwd(), filePath);
149
211
  const content = readFileSync(filePath, "utf8");
@@ -164,7 +226,7 @@ function cmdValidate(args) {
164
226
  }
165
227
  let fm;
166
228
  try {
167
- fm = parse(match[1]);
229
+ fm = parseYaml(match[1]);
168
230
  } catch {
169
231
  errors.push({
170
232
  file: rel,
@@ -224,7 +286,7 @@ function cmdValidate(args) {
224
286
  continue;
225
287
  }
226
288
  if (fileName.endsWith(".yaml")) try {
227
- parse(content);
289
+ parseYaml(content);
228
290
  } catch {
229
291
  errors.push({
230
292
  file: relative(process.cwd(), artifactPath),
@@ -232,20 +294,11 @@ function cmdValidate(args) {
232
294
  });
233
295
  }
234
296
  }
235
- const warnings = collectPackagingWarnings(process.cwd());
236
- const printWarnings = (log) => {
237
- if (warnings.length === 0) return;
238
- log(`\n⚠ Packaging warnings:`);
239
- for (const w of warnings) log(` ${w}`);
240
- };
241
- if (errors.length > 0) {
242
- console.error(`\n❌ Validation failed with ${errors.length} error(s):\n`);
243
- for (const { file, message } of errors) console.error(` ${file}: ${message}`);
244
- printWarnings(console.error);
245
- process.exit(1);
246
- }
297
+ const warnings = collectPackagingWarnings(packageRoot);
298
+ if (errors.length > 0) fail(buildValidationFailure(errors, warnings));
247
299
  console.log(`✅ Validated ${skillFiles.length} skill files — all passed`);
248
- printWarnings(console.log);
300
+ if (warnings.length > 0) console.log();
301
+ printWarnings(warnings);
249
302
  }
250
303
  function cmdScaffold() {
251
304
  const metaDir = getMetaDir();
@@ -306,7 +359,7 @@ This produces: individual SKILL.md files.
306
359
 
307
360
  ## After all skills are generated
308
361
 
309
- 1. Run \`npx @tanstack/intent validate\` in each package directory
362
+ 1. Run \`intent validate\` in each package directory
310
363
  2. Commit skills/ and artifacts
311
364
  3. For each publishable package, run: \`npx @tanstack/intent add-library-bin\`
312
365
  4. For each publishable package, run: \`npx @tanstack/intent edit-package-json\`
@@ -327,122 +380,152 @@ Usage:
327
380
  intent add-library-bin Generate bin/intent.{js,mjs} bridge file
328
381
  intent edit-package-json Wire package.json (files, bin) for skill publishing
329
382
  intent setup-github-actions Copy CI workflow templates to .github/workflows/
330
- intent stale Check skills for staleness`;
331
- const command = process.argv[2];
332
- const commandArgs = process.argv.slice(3);
333
- switch (command) {
334
- case "list":
335
- await cmdList(commandArgs);
336
- break;
337
- case "meta":
338
- cmdMeta(commandArgs);
339
- break;
340
- case "validate":
341
- cmdValidate(commandArgs);
342
- break;
343
- case "install":
344
- console.log(`You are an AI assistant helping a developer set up skill-to-task mappings for their project.
345
-
346
- Follow these steps in order:
347
-
348
- 1. CHECK FOR EXISTING MAPPINGS
349
- Search the project's agent config files (CLAUDE.md, AGENTS.md, .cursorrules,
350
- .github/copilot-instructions.md) for a block delimited by:
351
- <!-- intent-skills:start -->
352
- <!-- intent-skills:end -->
353
- - If found: show the user the current mappings and ask "What would you like to update?"
354
- Then skip to step 4 with their requested changes.
355
- - If not found: continue to step 2.
356
-
357
- 2. DISCOVER AVAILABLE SKILLS
358
- Run: intent list
359
- This outputs each skill's name, description, and full path — grouped by package.
360
-
361
- 3. SCAN THE REPOSITORY
362
- Build a picture of the project's structure and patterns:
363
- - Read package.json for library dependencies
364
- - Survey the directory layout (src/, app/, routes/, components/, api/, etc.)
365
- - Note recurring patterns (routing, data fetching, auth, UI components, etc.)
366
-
367
- Based on this, propose 3–5 skill-to-task mappings. For each one explain:
368
- - The task or code area (in plain language the user would recognise)
369
- - Which skill applies and why
370
-
371
- Then ask: "What other tasks do you commonly use AI coding agents for?
372
- I'll create mappings for those too."
373
-
374
- 4. WRITE THE MAPPINGS BLOCK
375
- Once you have the full set of mappings, write or update the agent config file
376
- (prefer CLAUDE.md; create it if none exists) with this exact block:
377
-
378
- <!-- intent-skills:start -->
379
- # Skill mappings — when working in these areas, load the linked skill file into context.
380
- skills:
381
- - task: "describe the task or code area here"
382
- load: "node_modules/package-name/skills/skill-name/SKILL.md"
383
- <!-- intent-skills:end -->
384
-
385
- Rules:
386
- - Use the user's own words for task descriptions
387
- - Include the exact path from \`intent list\` output so agents can load it directly
388
- - Keep entries concise — this block is read on every agent task
389
- - Preserve all content outside the block tags unchanged`);
390
- break;
391
- case "scaffold":
392
- cmdScaffold();
393
- break;
394
- case "stale": {
395
- const { checkStaleness } = await import("./staleness-C1h7RuZ9.mjs");
396
- const { scanForIntents: scanStale } = await import("./scanner-CECGXgox.mjs");
397
- let staleResult;
398
- try {
399
- staleResult = await scanStale();
400
- } catch (err) {
401
- console.error(err.message);
402
- process.exit(1);
383
+ intent stale [dir] [--json] Check skills for staleness`;
384
+ const HELP_BY_COMMAND = {
385
+ list: `${USAGE}
386
+
387
+ Examples:
388
+ intent list
389
+ intent list --json`,
390
+ meta: `intent meta [name]
391
+
392
+ List shipped meta-skills, or print a single meta-skill by name.
393
+
394
+ Examples:
395
+ intent meta
396
+ intent meta domain-discovery`,
397
+ validate: `intent validate [dir]
398
+
399
+ Validate SKILL.md files in the target directory.
400
+
401
+ Examples:
402
+ intent validate
403
+ intent validate packages/query/skills`,
404
+ install: `intent install
405
+
406
+ Print the install prompt used to set up skill-to-task mappings.`,
407
+ scaffold: `intent scaffold
408
+
409
+ Print the guided maintainer prompt for generating skills.`,
410
+ stale: `intent stale [dir] [--json]
411
+
412
+ Check installed skills for version and source drift.
413
+
414
+ Examples:
415
+ intent stale
416
+ intent stale packages/query
417
+ intent stale --json`,
418
+ "add-library-bin": `intent add-library-bin
419
+
420
+ Generate bin/intent.{js,mjs} bridge files for publishable packages.`,
421
+ "edit-package-json": `intent edit-package-json
422
+
423
+ Update package.json files so skills and shims are published.`,
424
+ "setup-github-actions": `intent setup-github-actions
425
+
426
+ Copy Intent CI workflow templates into .github/workflows/.`
427
+ };
428
+ function isHelpFlag(arg) {
429
+ return arg === "-h" || arg === "--help";
430
+ }
431
+ function printHelp(command) {
432
+ if (!command) {
433
+ console.log(`${USAGE}
434
+
435
+ Run \`intent help <command>\` for details on a specific command.`);
436
+ return;
437
+ }
438
+ console.log(HELP_BY_COMMAND[command] ?? USAGE);
439
+ }
440
+ async function main(argv = process.argv.slice(2)) {
441
+ const command = argv[0];
442
+ const commandArgs = argv.slice(1);
443
+ try {
444
+ if (!command || isHelpFlag(command)) {
445
+ printHelp();
446
+ return 0;
403
447
  }
404
- if (staleResult.packages.length === 0) {
405
- console.log("No intent-enabled packages found.");
406
- break;
448
+ if (command === "help") {
449
+ printHelp(commandArgs[0]);
450
+ return 0;
407
451
  }
408
- const jsonStale = commandArgs.includes("--json");
409
- const reports = await Promise.all(staleResult.packages.map((pkg) => {
410
- return checkStaleness(join(process.cwd(), "node_modules", pkg.name), pkg.name);
411
- }));
412
- if (jsonStale) {
413
- console.log(JSON.stringify(reports, null, 2));
414
- break;
452
+ if (isHelpFlag(commandArgs[0])) {
453
+ printHelp(command);
454
+ return 0;
415
455
  }
416
- for (const report of reports) {
417
- const driftLabel = report.versionDrift ? ` [${report.versionDrift} drift]` : "";
418
- const vLabel = report.skillVersion && report.currentVersion ? ` (${report.skillVersion} → ${report.currentVersion})` : "";
419
- console.log(`${report.library}${vLabel}${driftLabel}`);
420
- const stale = report.skills.filter((s) => s.needsReview);
421
- if (stale.length === 0) console.log(" All skills up-to-date");
422
- else for (const skill of stale) console.log(` ⚠ ${skill.name}: ${skill.reasons.join(", ")}`);
423
- console.log();
456
+ switch (command) {
457
+ case "list":
458
+ await cmdList(commandArgs);
459
+ return 0;
460
+ case "meta":
461
+ await cmdMeta(commandArgs);
462
+ return 0;
463
+ case "validate":
464
+ await cmdValidate(commandArgs);
465
+ return 0;
466
+ case "install":
467
+ console.log(INSTALL_PROMPT);
468
+ return 0;
469
+ case "scaffold":
470
+ cmdScaffold();
471
+ return 0;
472
+ case "stale": {
473
+ const jsonStale = commandArgs.includes("--json");
474
+ const { reports } = await resolveStaleTargets(commandArgs.find((arg) => !arg.startsWith("-")));
475
+ if (reports.length === 0) {
476
+ console.log("No intent-enabled packages found.");
477
+ return 0;
478
+ }
479
+ if (jsonStale) {
480
+ console.log(JSON.stringify(reports, null, 2));
481
+ return 0;
482
+ }
483
+ for (const report of reports) {
484
+ const driftLabel = report.versionDrift ? ` [${report.versionDrift} drift]` : "";
485
+ const vLabel = report.skillVersion && report.currentVersion ? ` (${report.skillVersion} → ${report.currentVersion})` : "";
486
+ console.log(`${report.library}${vLabel}${driftLabel}`);
487
+ const stale = report.skills.filter((s) => s.needsReview);
488
+ if (stale.length === 0) console.log(" All skills up-to-date");
489
+ else for (const skill of stale) console.log(` ⚠ ${skill.name}: ${skill.reasons.join(", ")}`);
490
+ console.log();
491
+ }
492
+ return 0;
493
+ }
494
+ case "add-library-bin": {
495
+ const { runAddLibraryBinAll } = await import("./setup.mjs");
496
+ runAddLibraryBinAll(process.cwd());
497
+ return 0;
498
+ }
499
+ case "edit-package-json": {
500
+ const { runEditPackageJsonAll } = await import("./setup.mjs");
501
+ runEditPackageJsonAll(process.cwd());
502
+ return 0;
503
+ }
504
+ case "setup-github-actions": {
505
+ const { runSetupGithubActions } = await import("./setup.mjs");
506
+ runSetupGithubActions(process.cwd(), getMetaDir());
507
+ return 0;
508
+ }
509
+ default:
510
+ printHelp();
511
+ return command ? 1 : 0;
424
512
  }
425
- break;
426
- }
427
- case "add-library-bin": {
428
- const { runAddLibraryBin } = await import("./setup.mjs");
429
- runAddLibraryBin(process.cwd());
430
- break;
431
- }
432
- case "edit-package-json": {
433
- const { runEditPackageJson } = await import("./setup.mjs");
434
- runEditPackageJson(process.cwd());
435
- break;
436
- }
437
- case "setup-github-actions": {
438
- const { runSetupGithubActions } = await import("./setup.mjs");
439
- runSetupGithubActions(process.cwd(), getMetaDir());
440
- break;
513
+ } catch (err) {
514
+ if (isCliFailure(err)) {
515
+ console.error(err.message);
516
+ return err.exitCode;
517
+ }
518
+ throw err;
441
519
  }
442
- default:
443
- console.log(USAGE);
444
- process.exit(command ? 1 : 0);
520
+ }
521
+ let isMain = false;
522
+ try {
523
+ isMain = process.argv[1] !== void 0 && fileURLToPath(import.meta.url) === realpathSync(process.argv[1]);
524
+ } catch {}
525
+ if (isMain) {
526
+ const exitCode = await main();
527
+ process.exit(exitCode);
445
528
  }
446
529
 
447
530
  //#endregion
448
- export { };
531
+ export { USAGE, main };
@@ -0,0 +1,3 @@
1
+ import { n as printSkillTree, r as printTable, t as computeSkillNameWidth } from "./display-DhsUxNJW.mjs";
2
+
3
+ export { computeSkillNameWidth, printSkillTree, printTable };