@tanstack/intent 0.0.4 → 0.0.6

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 (31) hide show
  1. package/README.md +2 -2
  2. package/dist/cli.mjs +44 -44
  3. package/dist/{feedback-DKreHfB1.mjs → feedback-BTSaBAS_.mjs} +2 -3
  4. package/dist/{feedback-FIUBOL0g.mjs → feedback-PR8JNBfM.mjs} +1 -1
  5. package/dist/index.d.mts +2 -2
  6. package/dist/index.mjs +4 -4
  7. package/dist/{init-DEzzXm9j.mjs → init-BU1ZnUbK.mjs} +1 -1
  8. package/dist/{init-DNxmjQfU.mjs → init-DUiDMMrN.mjs} +2 -0
  9. package/dist/intent-library.mjs +5 -0
  10. package/dist/library-scanner.d.mts +1 -1
  11. package/dist/scanner-DkShtCWX.mjs +4 -0
  12. package/dist/{scanner-BwCyu1Jq.mjs → scanner-OmHt14bs.mjs} +26 -2
  13. package/dist/{setup-CNGz26qL.mjs → setup-BvrZZLsA.mjs} +3 -12
  14. package/dist/{setup-N5dttGp_.d.mts → setup-D2Bwubpw.d.mts} +0 -1
  15. package/dist/setup.d.mts +1 -1
  16. package/dist/setup.mjs +1 -1
  17. package/dist/{types-kbQfN_is.d.mts → types-B20LP96b.d.mts} +1 -1
  18. package/meta/domain-discovery/SKILL.md +50 -2
  19. package/meta/feedback-collection/SKILL.md +156 -0
  20. package/meta/generate-skill/SKILL.md +9 -0
  21. package/meta/skill-staleness-check/SKILL.md +9 -9
  22. package/meta/templates/workflows/check-skills.yml +143 -0
  23. package/meta/tree-generator/SKILL.md +7 -1
  24. package/package.json +1 -1
  25. package/dist/scanner-fAWJUn6Q.mjs +0 -4
  26. package/meta/templates/oz/domain-discovery.md +0 -53
  27. package/meta/templates/oz/feedback-collection.md +0 -69
  28. package/meta/templates/oz/skill-update.md +0 -47
  29. package/meta/templates/oz/tree-generation.md +0 -48
  30. package/meta/templates/workflows/generate-skills-oz.yml +0 -86
  31. package/meta/templates/workflows/update-skills-oz.yml +0 -98
package/README.md CHANGED
@@ -42,7 +42,7 @@ Validate your skill files:
42
42
  npx intent validate
43
43
  ```
44
44
 
45
- Copy CI and Oz workflow templates into your repo:
45
+ Copy CI workflow templates into your repo:
46
46
 
47
47
  ```bash
48
48
  npx intent setup
@@ -57,7 +57,7 @@ npx intent setup
57
57
  | `intent meta` | List meta-skills for library maintainers |
58
58
  | `intent scaffold` | Print the guided skill generation prompt |
59
59
  | `intent validate [dir]` | Validate SKILL.md files |
60
- | `intent setup` | Copy CI/Oz workflow templates |
60
+ | `intent setup` | Copy CI workflow templates |
61
61
  | `intent stale [--json]` | Check skills for version drift |
62
62
  | `intent feedback` | Submit skill feedback |
63
63
 
package/dist/cli.mjs CHANGED
@@ -1,11 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { n as parseFrontmatter, t as findSkillFiles } from "./utils-DH3jY3CI.mjs";
3
- import { t as scanForIntents } from "./scanner-BwCyu1Jq.mjs";
3
+ import { t as scanForIntents } from "./scanner-OmHt14bs.mjs";
4
4
  import { existsSync, readFileSync, readdirSync } from "node:fs";
5
5
  import { dirname, join, relative, sep } from "node:path";
6
6
  import { parse } from "yaml";
7
- import { spawnSync } from "node:child_process";
8
- import { release } from "node:os";
9
7
  import { fileURLToPath } from "node:url";
10
8
 
11
9
  //#region src/cli.ts
@@ -106,6 +104,11 @@ async function cmdList(args) {
106
104
  });
107
105
  console.log();
108
106
  }
107
+ console.log(`Feedback:`);
108
+ console.log(` After completing your task, collect feedback on skill usage.`);
109
+ console.log(` Instructions: node_modules/@tanstack/intent/meta/feedback-collection/SKILL.md`);
110
+ console.log(` Submit: npx intent feedback --submit --file intent-feedback.json`);
111
+ console.log();
109
112
  if (result.warnings.length > 0) {
110
113
  console.log(`Warnings:`);
111
114
  for (const w of result.warnings) console.log(` ⚠ ${w}`);
@@ -196,7 +199,7 @@ function cmdValidate(args) {
196
199
  const lineCount = content.split(/\r?\n/).length;
197
200
  if (lineCount > 500) errors.push({
198
201
  file: rel,
199
- message: `Exceeds 500 line limit (${lineCount} lines)`
202
+ message: `Exceeds 500 line limit (${lineCount} lines). Rewrite for conciseness: move API tables to references/, trim verbose examples, and remove content an agent already knows. Do not simply raise the limit.`
200
203
  });
201
204
  }
202
205
  const artifactsDir = join(skillsDir, "_artifacts");
@@ -238,40 +241,42 @@ function cmdValidate(args) {
238
241
  console.log(`✅ Validated ${skillFiles.length} skill files — all passed`);
239
242
  }
240
243
  function cmdScaffold() {
241
- function tryCopyToClipboard(text) {
242
- const platform = process.platform;
243
- const isWsl = platform === "linux" && (Boolean(process.env.WSL_DISTRO_NAME) || Boolean(process.env.WSL_INTEROP) || release().toLowerCase().includes("microsoft"));
244
- const tryCommand = (command$1, args = []) => {
245
- return spawnSync(command$1, args, { input: text }).status === 0;
246
- };
247
- if (platform === "darwin") return tryCommand("pbcopy");
248
- if (platform === "win32") return tryCommand("clip");
249
- if (isWsl) return tryCommand("clip.exe");
250
- return tryCommand("wl-copy") || tryCommand("xclip", ["-selection", "clipboard"]) || tryCommand("xsel", ["--clipboard", "--input"]);
251
- }
252
- const prompt = `You are an AI assistant helping a library maintainer scaffold Intent skills.
244
+ console.log(`You are an AI assistant helping a library maintainer scaffold Intent skills.
253
245
  You MUST use the Intent meta skills in this exact order and follow their output requirements.
254
246
 
255
- Before you start, ask the maintainer for their skills root path.
256
- - Default: skills/
257
- - If they choose a different path, replace "skills/" in all output paths below.
247
+ Before you start, ask the maintainer:
248
+ 1. Skills root path (default: skills/). If custom, replace "skills/" in all paths below.
249
+ 2. Is this a monorepo? If yes, you need the following layout:
250
+ - Domain map artifacts live at the REPO ROOT: _artifacts/domain_map.yaml, _artifacts/skill_spec.md, _artifacts/skill_tree.yaml
251
+ - Skills live INSIDE EACH PACKAGE: packages/<pkg>/skills/<domain>/<skill>/SKILL.md
252
+ - Each publishable package needs:
253
+ a. @tanstack/intent as a devDependency
254
+ b. A bin entry: "bin": { "intent": "./bin/intent.js" }
255
+ c. The shim file at bin/intent.js (run npx @tanstack/intent setup --shim in each package)
256
+ d. "skills" and "bin" in the package.json "files" array, with "!skills/_artifacts" to exclude artifacts
257
+ - Ask the maintainer which packages should get skills (usually client SDKs and primary framework adapters)
258
258
 
259
259
  1) Meta skill: domain-discovery
260
260
  - Input: library name, repo URL, docs URL(s), scope constraints, target audience.
261
- - Output files (exact paths):
262
- - skills/_artifacts/domain_map.yaml
263
- - skills/_artifacts/skill_spec.md
261
+ - Output files:
262
+ - Single-repo: skills/_artifacts/domain_map.yaml, skills/_artifacts/skill_spec.md
263
+ - Monorepo: _artifacts/domain_map.yaml, _artifacts/skill_spec.md (at repo root)
264
+ - Domain discovery covers the WHOLE library. One domain map for the entire monorepo.
264
265
  - These artifacts are maintainer-owned and should be committed to the repo.
265
266
 
266
267
  2) Meta skill: tree-generator
267
- - Input: skills/_artifacts/domain_map.yaml + skills/_artifacts/skill_spec.md
268
- - Output file (exact path):
269
- - skills/_artifacts/skill_tree.yaml
268
+ - Input: domain map + skill spec artifacts
269
+ - Output file: _artifacts/skill_tree.yaml (same location as domain map)
270
+ - The skill tree must specify which PACKAGE each skill belongs to.
271
+ - For monorepos, the tree maps skills to packages: each skill entry should include
272
+ a "package" field (e.g. packages/client, packages/react-client).
270
273
 
271
274
  3) Meta skill: generate-skill
272
- - Input: skills/_artifacts/skill_tree.yaml
273
- - Output files (exact path pattern):
274
- - skills/<domain>/<skill>/SKILL.md
275
+ - Input: skill tree
276
+ - Output files:
277
+ - Single-repo: skills/<domain>/<skill>/SKILL.md
278
+ - Monorepo: packages/<pkg>/skills/<domain>/<skill>/SKILL.md
279
+ - Skills are written into the package they describe, not a shared root.
275
280
 
276
281
  Guidance for the maintainer:
277
282
  - If any input is missing, ask for it.
@@ -280,20 +285,15 @@ Guidance for the maintainer:
280
285
  - Use the library's actual terminology from docs and source.
281
286
 
282
287
  At the end, produce a single Markdown feedback doc with three sections (Domain Discovery, Tree Generator, Generate Skill).
283
- Ask if the maintainer wants to edit it, then ask if you should send it as a GitHub issue to TanStack/intent.
284
- Use the issue title: [meta-feedback] intent meta skill.
288
+ Ask if the maintainer wants to edit it, then submit it via: npx @tanstack/intent feedback --meta --submit --file <path>
285
289
 
286
290
  Finish with a short checklist:
287
- - Run npx intent validate
288
- - Commit skills/ and skills/_artifacts/ (artifacts are repo-only)
289
- - Exclude skills/_artifacts/ from package publishing
290
- - Add README snippet: If you use an AI agent, run npx intent init
291
- `;
292
- console.log("🚀 Intent Scaffold Prompt");
293
- console.log("✨ Copy the prompt below into your AI agent:\n");
294
- console.log(prompt);
295
- if (tryCopyToClipboard(prompt)) console.log("\n✅ Copied prompt to clipboard");
296
- else console.log("\n⚠ Tip: Manually copy the prompt above into your agent");
291
+ - Run npx @tanstack/intent validate in each package directory (or for single-repo: at the root)
292
+ - Commit skills/ and artifacts
293
+ - Exclude artifacts from package publishing (add "!skills/_artifacts" to the "files" array in each package.json)
294
+ - For monorepos: ensure each package has @tanstack/intent as devDependency, bin entry, and shim
295
+ - Add README snippet: If you use an AI agent, run npx @tanstack/intent init
296
+ `);
297
297
  }
298
298
  const USAGE = `TanStack Intent CLI
299
299
 
@@ -303,7 +303,7 @@ Usage:
303
303
  intent validate [<dir>] Validate skill files (default: skills/)
304
304
  intent init Set up intent discovery in agent configs
305
305
  intent scaffold Print maintainer scaffold prompt
306
- intent setup [--workflows] [--oz] [--all] Copy CI/Oz templates into your repo
306
+ intent setup [--workflows] [--all] Copy CI templates into your repo
307
307
  intent stale Check skills for staleness
308
308
  intent feedback --submit --file <path> Submit skill feedback
309
309
  intent feedback --meta --submit --file <path> Submit meta-skill feedback`;
@@ -320,7 +320,7 @@ switch (command) {
320
320
  cmdValidate(commandArgs);
321
321
  break;
322
322
  case "init": {
323
- const { runInit, detectAgentConfigs } = await import("./init-DEzzXm9j.mjs");
323
+ const { runInit, detectAgentConfigs } = await import("./init-BU1ZnUbK.mjs");
324
324
  const initRoot = process.cwd();
325
325
  const result = runInit(initRoot);
326
326
  for (const f of result.injected) console.log(`✓ Added intent block to ${f}`);
@@ -340,7 +340,7 @@ switch (command) {
340
340
  break;
341
341
  case "stale": {
342
342
  const { checkStaleness } = await import("./staleness-B5gUj7FR.mjs");
343
- const { scanForIntents: scanStale } = await import("./scanner-fAWJUn6Q.mjs");
343
+ const { scanForIntents: scanStale } = await import("./scanner-DkShtCWX.mjs");
344
344
  let staleResult;
345
345
  try {
346
346
  staleResult = await scanStale();
@@ -372,7 +372,7 @@ switch (command) {
372
372
  break;
373
373
  }
374
374
  case "feedback": {
375
- const { runFeedback } = await import("./feedback-FIUBOL0g.mjs");
375
+ const { runFeedback } = await import("./feedback-PR8JNBfM.mjs");
376
376
  runFeedback(commandArgs);
377
377
  break;
378
378
  }
@@ -87,7 +87,6 @@ const VALID_META_SKILLS = [
87
87
  "skill-staleness-check"
88
88
  ];
89
89
  const VALID_AGENTS = [
90
- "oz",
91
90
  "claude-code",
92
91
  "cursor",
93
92
  "copilot",
@@ -259,10 +258,10 @@ function runFeedback(args) {
259
258
  break;
260
259
  case "file":
261
260
  console.log(`✓ ${result$1.detail}`);
262
- console.log(`Open a GitHub Discussion at https://github.com/${META_FEEDBACK_REPO}/discussions/new?category=Feedback`);
261
+ console.log(`You can manually open an issue at https://github.com/${META_FEEDBACK_REPO}/issues with this content.`);
263
262
  break;
264
263
  case "stdout":
265
- console.log("--- Meta-feedback markdown (copy/paste to discussion) ---");
264
+ console.log("--- Meta-feedback markdown (copy/paste to issue) ---");
266
265
  console.log(result$1.detail);
267
266
  break;
268
267
  }
@@ -1,3 +1,3 @@
1
- import { a as runFeedback, c as toMarkdown, i as resolveFrequency, l as validateMetaPayload, n as hasGhCli, o as submitFeedback, r as metaToMarkdown, s as submitMetaFeedback, t as containsSecrets, u as validatePayload } from "./feedback-DKreHfB1.mjs";
1
+ import { a as runFeedback, c as toMarkdown, i as resolveFrequency, l as validateMetaPayload, n as hasGhCli, o as submitFeedback, r as metaToMarkdown, s as submitMetaFeedback, t as containsSecrets, u as validatePayload } from "./feedback-BTSaBAS_.mjs";
2
2
 
3
3
  export { runFeedback };
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as IntentProjectConfig, c as ScanResult, d as StalenessReport, i as IntentPackage, l as SkillEntry, n as FeedbackPayload, o as MetaFeedbackPayload, r as IntentConfig, s as MetaSkillName, t as AgentName, u as SkillStaleness } from "./types-kbQfN_is.mjs";
2
- import { n as runSetup } from "./setup-N5dttGp_.mjs";
1
+ import { a as IntentProjectConfig, c as ScanResult, d as StalenessReport, i as IntentPackage, l as SkillEntry, n as FeedbackPayload, o as MetaFeedbackPayload, r as IntentConfig, s as MetaSkillName, t as AgentName, u as SkillStaleness } from "./types-B20LP96b.mjs";
2
+ import { n as runSetup } from "./setup-D2Bwubpw.mjs";
3
3
 
4
4
  //#region src/scanner.d.ts
5
5
  declare function scanForIntents(root?: string): Promise<ScanResult>;
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  import { n as parseFrontmatter, t as findSkillFiles } from "./utils-DH3jY3CI.mjs";
2
- import { t as scanForIntents } from "./scanner-BwCyu1Jq.mjs";
2
+ import { t as scanForIntents } from "./scanner-OmHt14bs.mjs";
3
3
  import { t as checkStaleness } from "./staleness-lP6B0O4z.mjs";
4
- import { c as toMarkdown, i as resolveFrequency, l as validateMetaPayload, n as hasGhCli, o as submitFeedback, r as metaToMarkdown, s as submitMetaFeedback, t as containsSecrets, u as validatePayload } from "./feedback-DKreHfB1.mjs";
5
- import { a as runInit, i as readProjectConfig, n as hasIntentBlock, o as writeProjectConfig, r as injectIntentBlock, t as detectAgentConfigs } from "./init-DNxmjQfU.mjs";
6
- import { t as runSetup } from "./setup-CNGz26qL.mjs";
4
+ import { c as toMarkdown, i as resolveFrequency, l as validateMetaPayload, n as hasGhCli, o as submitFeedback, r as metaToMarkdown, s as submitMetaFeedback, t as containsSecrets, u as validatePayload } from "./feedback-BTSaBAS_.mjs";
5
+ import { a as runInit, i as readProjectConfig, n as hasIntentBlock, o as writeProjectConfig, r as injectIntentBlock, t as detectAgentConfigs } from "./init-DUiDMMrN.mjs";
6
+ import { t as runSetup } from "./setup-BvrZZLsA.mjs";
7
7
 
8
8
  export { checkStaleness, containsSecrets, detectAgentConfigs, findSkillFiles, hasGhCli, hasIntentBlock, injectIntentBlock, metaToMarkdown, parseFrontmatter, readProjectConfig, resolveFrequency, runInit, runSetup, scanForIntents, submitFeedback, submitMetaFeedback, toMarkdown, validateMetaPayload, validatePayload, writeProjectConfig };
@@ -1,3 +1,3 @@
1
- import { a as runInit, i as readProjectConfig, n as hasIntentBlock, o as writeProjectConfig, r as injectIntentBlock, t as detectAgentConfigs } from "./init-DNxmjQfU.mjs";
1
+ import { a as runInit, i as readProjectConfig, n as hasIntentBlock, o as writeProjectConfig, r as injectIntentBlock, t as detectAgentConfigs } from "./init-DUiDMMrN.mjs";
2
2
 
3
3
  export { detectAgentConfigs, runInit };
@@ -14,6 +14,8 @@ const INTENT_BLOCK = `## Intent Skills
14
14
  This project uses TanStack Intent. Run \`npx intent list\` to discover
15
15
  available AI coding skills. Before working with a library that has skills,
16
16
  read the relevant SKILL.md file at the path shown in the list output.
17
+ After completing a task that used skills, collect and submit feedback
18
+ following the instructions in the list output.
17
19
  `;
18
20
  const DEFAULT_CONFIG = { feedback: { frequency: "every-5" } };
19
21
  function detectAgentConfigs(root) {
@@ -90,6 +90,11 @@ async function cmdList() {
90
90
  });
91
91
  console.log();
92
92
  }
93
+ console.log(`Feedback:`);
94
+ console.log(` After completing your task, collect feedback on skill usage.`);
95
+ console.log(` Instructions: node_modules/@tanstack/intent/meta/feedback-collection/SKILL.md`);
96
+ console.log(` Submit: npx intent feedback --submit --file intent-feedback.json`);
97
+ console.log();
93
98
  if (result.warnings.length > 0) {
94
99
  console.log(`Warnings:`);
95
100
  for (const w of result.warnings) console.log(` ⚠ ${w}`);
@@ -1,4 +1,4 @@
1
- import { l as SkillEntry } from "./types-kbQfN_is.mjs";
1
+ import { l as SkillEntry } from "./types-B20LP96b.mjs";
2
2
 
3
3
  //#region src/library-scanner.d.ts
4
4
  interface LibraryPackage {
@@ -0,0 +1,4 @@
1
+ import "./utils-DH3jY3CI.mjs";
2
+ import { t as scanForIntents } from "./scanner-OmHt14bs.mjs";
3
+
4
+ export { scanForIntents };
@@ -26,6 +26,30 @@ function validateIntentField(_pkgName, intent) {
26
26
  requires
27
27
  };
28
28
  }
29
+ /**
30
+ * Derive an IntentConfig from standard package.json fields when no explicit
31
+ * `intent` field is present. A package with a `skills/` directory signals
32
+ * intent support; `repo` and `docs` are derived from `repository` and
33
+ * `homepage`.
34
+ */
35
+ function deriveIntentConfig(pkgJson) {
36
+ let repo = null;
37
+ if (typeof pkgJson.repository === "string") repo = pkgJson.repository;
38
+ else if (pkgJson.repository && typeof pkgJson.repository === "object" && typeof pkgJson.repository.url === "string") {
39
+ repo = pkgJson.repository.url;
40
+ repo = repo.replace(/^git\+/, "").replace(/\.git$/, "").replace(/^https?:\/\/github\.com\//, "");
41
+ }
42
+ const docs = typeof pkgJson.homepage === "string" ? pkgJson.homepage : void 0;
43
+ if (!repo) return null;
44
+ const intentPartial = pkgJson.intent;
45
+ const requires = intentPartial && Array.isArray(intentPartial.requires) ? intentPartial.requires.filter((r) => typeof r === "string") : void 0;
46
+ return {
47
+ version: 1,
48
+ repo,
49
+ docs: docs ?? "",
50
+ requires
51
+ };
52
+ }
29
53
  function discoverSkills(skillsDir, _baseName) {
30
54
  const skills = [];
31
55
  function walk(dir) {
@@ -132,9 +156,9 @@ async function scanForIntents(root) {
132
156
  }
133
157
  const pkgName = typeof pkgJson.name === "string" ? pkgJson.name : "unknown";
134
158
  const pkgVersion = typeof pkgJson.version === "string" ? pkgJson.version : "0.0.0";
135
- const intent = validateIntentField(pkgName, pkgJson.intent);
159
+ const intent = validateIntentField(pkgName, pkgJson.intent) ?? deriveIntentConfig(pkgJson);
136
160
  if (!intent) {
137
- warnings.push(`${pkgName} has a skills/ directory but missing or invalid "intent" field in package.json`);
161
+ warnings.push(`${pkgName} has a skills/ directory but could not determine repo/docs from package.json (add a "repository" field or explicit "intent" config)`);
138
162
  continue;
139
163
  }
140
164
  const skills = discoverSkills(skillsDir, pkgName);
@@ -67,16 +67,13 @@ function generateShim(root, result) {
67
67
  function runSetup(root, metaDir, args) {
68
68
  const doAll = args.includes("--all");
69
69
  const doWorkflows = doAll || args.includes("--workflows");
70
- const doOz = doAll || args.includes("--oz");
71
70
  const doShim = doAll || args.includes("--shim");
72
- const defaultAll = !doWorkflows && !doOz && !doShim;
71
+ const defaultAll = !doWorkflows && !doShim;
73
72
  const installWorkflows = doWorkflows || defaultAll;
74
- const installOz = doOz || defaultAll;
75
73
  const installShim = doShim || defaultAll;
76
74
  const vars = detectVars(root);
77
75
  const result = {
78
76
  workflows: [],
79
- oz: [],
80
77
  skipped: [],
81
78
  shim: null
82
79
  };
@@ -86,14 +83,8 @@ function runSetup(root, metaDir, args) {
86
83
  result.workflows = copied;
87
84
  result.skipped.push(...skipped);
88
85
  }
89
- if (installOz) {
90
- const { copied, skipped } = copyTemplates(join(templatesDir, "oz"), join(root, ".intent", "oz"), vars);
91
- result.oz = copied;
92
- result.skipped.push(...skipped);
93
- }
94
86
  if (installShim) generateShim(root, result);
95
87
  for (const f of result.workflows) console.log(`✓ Copied workflow: ${f}`);
96
- for (const f of result.oz) console.log(`✓ Copied Oz prompt: ${f}`);
97
88
  for (const f of result.skipped) console.log(` Already exists: ${f}`);
98
89
  if (result.shim) {
99
90
  console.log(`✓ Generated intent shim: ${result.shim}`);
@@ -101,8 +92,8 @@ function runSetup(root, metaDir, args) {
101
92
  console.log(` "bin": { "intent": "./bin/intent.js" }`);
102
93
  console.log(`\n Add bin/intent.js to your package.json "files" array.`);
103
94
  }
104
- if (result.workflows.length === 0 && result.oz.length === 0 && result.shim === null && result.skipped.length === 0) console.log("No templates directory found. Is @tanstack/intent installed?");
105
- else if (result.workflows.length > 0 || result.oz.length > 0) {
95
+ if (result.workflows.length === 0 && result.shim === null && result.skipped.length === 0) console.log("No templates directory found. Is @tanstack/intent installed?");
96
+ else if (result.workflows.length > 0) {
106
97
  console.log(`\nTemplate variables applied:`);
107
98
  console.log(` Package: ${vars.PACKAGE_NAME}`);
108
99
  console.log(` Repo: ${vars.REPO}`);
@@ -1,7 +1,6 @@
1
1
  //#region src/setup.d.ts
2
2
  interface SetupResult {
3
3
  workflows: string[];
4
- oz: string[];
5
4
  skipped: string[];
6
5
  shim: string | null;
7
6
  }
package/dist/setup.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { n as runSetup, t as SetupResult } from "./setup-N5dttGp_.mjs";
1
+ import { n as runSetup, t as SetupResult } from "./setup-D2Bwubpw.mjs";
2
2
  export { SetupResult, runSetup };
package/dist/setup.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { t as runSetup } from "./setup-CNGz26qL.mjs";
1
+ import { t as runSetup } from "./setup-BvrZZLsA.mjs";
2
2
 
3
3
  export { runSetup };
@@ -48,7 +48,7 @@ interface FeedbackPayload {
48
48
  userComments?: string;
49
49
  }
50
50
  type MetaSkillName = 'domain-discovery' | 'tree-generator' | 'generate-skill' | 'skill-staleness-check';
51
- type AgentName = 'oz' | 'claude-code' | 'cursor' | 'copilot' | 'codex' | 'other';
51
+ type AgentName = 'claude-code' | 'cursor' | 'copilot' | 'codex' | 'other';
52
52
  interface MetaFeedbackPayload {
53
53
  metaSkill: MetaSkillName;
54
54
  library: string;
@@ -57,7 +57,26 @@ reading exhaustively yet.
57
57
  guidance, read it. This is high-signal for what the maintainer
58
58
  considers important
59
59
 
60
- ### 1b — Note initial impressions
60
+ ### 1b — Read peer dependency constraints
61
+
62
+ Check `package.json` for `peerDependencies` and `peerDependenciesMeta`.
63
+ For each major peer dependency (React, Vue, Svelte, Next.js, etc.):
64
+
65
+ 1. Note the version range required
66
+ 2. Read the peer's docs for integration constraints that affect this
67
+ library: SSR/hydration rules, component lifecycle boundaries,
68
+ browser-only APIs, singleton patterns, connection limits
69
+ 3. Log framework-specific failure modes — these are the highest-impact
70
+ failure modes and cannot be discovered from the library's own source
71
+
72
+ Examples of peer-dependency-driven failure modes:
73
+
74
+ - SSR: calling browser-only APIs during server render
75
+ - React: breaking hook rules in library wrapper components
76
+ - Connection limits: opening multiple WebSocket connections per tab
77
+ - Singleton patterns: creating multiple client instances in dev mode
78
+
79
+ ### 1c — Note initial impressions
61
80
 
62
81
  Log (but do not group yet):
63
82
 
@@ -191,7 +210,11 @@ Move concept inventory items into groups. Two items belong together when:
191
210
  - They share a lifecycle, configuration scope, or architectural tradeoff
192
211
  - Getting one wrong tends to produce bugs in the other
193
212
 
194
- Target 4–7 domains. These are conceptual groupings, not the final skills.
213
+ Let library complexity drive the domain count a focused library may need
214
+ only 2–3 domains, while a large framework may need 7+. Validate by asking:
215
+ "Would a developer working on a single feature need to load skills from
216
+ multiple domains? If so, merge those domains." These are conceptual
217
+ groupings, not the final skills.
195
218
 
196
219
  Do not create a group for:
197
220
 
@@ -202,6 +225,14 @@ Do not create a group for:
202
225
 
203
226
  Name each domain as work being performed, not what the library provides.
204
227
 
228
+ **Validation step:** After grouping, check each domain by asking:
229
+ "Would a developer working on a single feature need to load skills from
230
+ multiple domains?" If yes, merge those domains. Group by developer tasks
231
+ (what they're trying to accomplish), not by architecture (how the library
232
+ is organized internally). For example, prefer "writing data" over
233
+ "producer lifecycle" — the former matches a developer's intent, the latter
234
+ matches the codebase structure.
235
+
205
236
  ### 3b — Map domains × tasks → skills
206
237
 
207
238
  Merge your conceptual domains with the maintainer's task list from
@@ -268,6 +299,14 @@ For each skill, extract failure modes that pass all three tests:
268
299
 
269
300
  Target 3 failure modes per skill minimum. Complex skills target 5–6.
270
301
 
302
+ **Code patterns.** Every failure mode should include `wrong_pattern` and
303
+ `correct_pattern` fields with short code snippets (3–10 lines each).
304
+ The wrong pattern is what an agent would generate; the correct pattern
305
+ is the fix. These feed directly into SKILL.md Common Mistakes sections
306
+ as wrong/correct code pairs. If the failure mode is purely conceptual
307
+ (e.g. an architectural choice) rather than a code pattern, omit both
308
+ fields and explain in `mechanism` instead.
309
+
271
310
  **Cross-skill failure modes.** Some failure modes belong to multiple
272
311
  skills. A developer doing SSR work and a developer doing state management
273
312
  both need to know about "stale state during hydration" — they load
@@ -465,6 +504,11 @@ Update `status: draft` to `status: reviewed`.
465
504
  If the maintainer uses a custom skills root, replace `skills/` in the paths
466
505
  below with their chosen directory.
467
506
 
507
+ **Monorepo layout:** For monorepos, domain map artifacts go at the REPO ROOT
508
+ (e.g. `_artifacts/domain_map.yaml`) since they describe the whole library.
509
+ Skills are generated per-package later by the tree-generator and generate-skill
510
+ steps.
511
+
468
512
  ### 1. skills/\_artifacts/domain_map.yaml
469
513
 
470
514
  ```yaml
@@ -510,6 +554,10 @@ skills:
510
554
  failure_modes:
511
555
  - mistake: '[5-10 word phrase]'
512
556
  mechanism: '[one sentence]'
557
+ wrong_pattern: | # the code an agent would incorrectly generate
558
+ [short code snippet showing the mistake]
559
+ correct_pattern: | # the code that should be generated instead
560
+ [short code snippet showing the fix]
513
561
  source: '[doc page, source file, issue link, or maintainer interview]'
514
562
  priority: '[CRITICAL | HIGH | MEDIUM]'
515
563
  status: '[active | fixed-but-legacy-risk | removed]'
@@ -0,0 +1,156 @@
1
+ ---
2
+ name: skill-feedback-collection
3
+ description: >
4
+ Collect structured feedback about skill usage after completing a coding task.
5
+ Activate at the end of any session where one or more SKILL.md files were
6
+ loaded. Captures agent signals (gaps, errors, corrections, human interventions)
7
+ and brief human input, then submits via the intent feedback CLI.
8
+ metadata:
9
+ version: '1.0'
10
+ category: meta-tooling
11
+ output_artifacts:
12
+ - intent-feedback.json
13
+ ---
14
+
15
+ # Skill Feedback Collection
16
+
17
+ Run this at the end of any session where you loaded one or more SKILL.md files.
18
+ The goal is to capture what worked, what didn't, and what was missing — so skill
19
+ maintainers can improve future versions.
20
+
21
+ ---
22
+
23
+ ## Phase 1 — Automated Signal Collection
24
+
25
+ Review your own session transcript. No human interaction needed yet.
26
+
27
+ ### 1a: Gap detection
28
+
29
+ Identify moments where the skill was silent and you had to bridge the gap
30
+ yourself — via code reading, search, trial-and-error, or general knowledge.
31
+
32
+ For each gap, note:
33
+
34
+ - What you needed to do
35
+ - What the skill should have told you
36
+ - How you solved it (code reading, web search, guessing)
37
+
38
+ ### 1b: Error/correction tracking
39
+
40
+ Identify moments where the skill prescribed an approach that produced an error.
41
+
42
+ For each error, note:
43
+
44
+ - What the skill said to do
45
+ - The error or incorrect behavior that resulted
46
+ - The fix you applied
47
+
48
+ ### 1c: Human intervention events
49
+
50
+ Identify moments where the human clarified, corrected, or overrode your approach.
51
+
52
+ For each intervention, note:
53
+
54
+ - What you were doing when the human intervened
55
+ - What the human said or changed
56
+ - Whether the skill could have prevented this
57
+
58
+ ### 1d: Step duration anomalies
59
+
60
+ Identify steps that consumed disproportionate effort compared to their apparent
61
+ complexity. These signal that the skill should provide a template, snippet, or
62
+ more detailed guidance.
63
+
64
+ ---
65
+
66
+ ## Phase 2 — Human Interview
67
+
68
+ Ask the human up to 4 questions. Keep it brief — skip questions if the session
69
+ already provided clear answers. Respect if they decline.
70
+
71
+ 1. "Was anything unclear about what was happening during the task?"
72
+ 2. "Did anything feel frustrating or take longer than expected?"
73
+ 3. "Were you uncertain about the output quality at any point?"
74
+ 4. "Anything you'd want done differently next time?"
75
+
76
+ Derive `userRating` from overall sentiment:
77
+
78
+ - Mostly positive → `good`
79
+ - Mixed signals → `mixed`
80
+ - Mostly negative → `bad`
81
+
82
+ If the human gives an explicit rating, use that instead.
83
+
84
+ ---
85
+
86
+ ## Phase 3 — Build the Payload
87
+
88
+ Construct one JSON payload per skill used. The schema must match exactly:
89
+
90
+ ```json
91
+ {
92
+ "skill": "<skill name from SKILL.md frontmatter>",
93
+ "package": "<npm package name that contains the skill>",
94
+ "skillVersion": "<metadata.version from SKILL.md frontmatter, or library_version>",
95
+ "task": "<one-sentence summary of what the human asked you to do>",
96
+ "whatWorked": "<patterns/instructions from the skill that were accurate and helpful>",
97
+ "whatFailed": "<errors from 1b — what the skill got wrong>",
98
+ "missing": "<gaps from 1a — what the skill should have covered>",
99
+ "selfCorrections": "<fixes you applied from 1b + interventions from 1c>",
100
+ "userRating": "good | mixed | bad",
101
+ "userComments": "<optional — direct quotes or paraphrased human input from Phase 2>"
102
+ }
103
+ ```
104
+
105
+ ### Field derivation guide
106
+
107
+ | Field | Source |
108
+ | ----------------- | ------------------------------------------------------------------ |
109
+ | `skill` | Frontmatter `name` field of the SKILL.md you loaded |
110
+ | `package` | The npm package the skill lives in (e.g. `@tanstack/query-intent`) |
111
+ | `skillVersion` | Frontmatter `metadata.version` or `library_version` |
112
+ | `task` | Summarize the human's original request in one sentence |
113
+ | `whatWorked` | List skill sections/patterns that were correct and useful |
114
+ | `whatFailed` | From 1b — skill instructions that produced errors |
115
+ | `missing` | From 1a — gaps where the skill was silent |
116
+ | `selfCorrections` | From 1b fixes + 1c human interventions, combined |
117
+ | `userRating` | From Phase 2 sentiment analysis or explicit rating |
118
+ | `userComments` | From Phase 2 answers, keep brief |
119
+
120
+ ### Example
121
+
122
+ ```json
123
+ {
124
+ "skill": "tanstack-query/core",
125
+ "package": "@anthropic/tanstack-query-intent",
126
+ "skillVersion": "1.0",
127
+ "task": "Add optimistic updates to a mutation with rollback on error",
128
+ "whatWorked": "Setup pattern was correct. onMutate/onError/onSettled lifecycle was accurate.",
129
+ "whatFailed": "Cache key format used array syntax that doesn't match v5 — had to switch to queryOptions pattern.",
130
+ "missing": "No guidance on TypeScript generics for mutation variables. Had to read source.",
131
+ "selfCorrections": "Fixed cache key format. Human corrected the rollback type to include undefined.",
132
+ "userRating": "mixed",
133
+ "userComments": "The optimistic update pattern was helpful but the cache key thing wasted 10 minutes."
134
+ }
135
+ ```
136
+
137
+ If multiple skills were loaded, produce one payload per skill. Only include
138
+ skills that were actually used during the session — skip any that were loaded
139
+ but never referenced.
140
+
141
+ ---
142
+
143
+ ## Phase 4 — Submit
144
+
145
+ 1. Save the payload to `intent-feedback.json` in the project root.
146
+ If multiple skills, save as a JSON array.
147
+
148
+ 2. Submit:
149
+
150
+ ```bash
151
+ npx intent feedback --submit --file intent-feedback.json
152
+ ```
153
+
154
+ 3. If the submission succeeds, delete `intent-feedback.json`.
155
+
156
+ 4. If it fails, tell the human and leave the file for manual retry.