@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.
- package/README.md +2 -2
- package/dist/cli.mjs +44 -44
- package/dist/{feedback-DKreHfB1.mjs → feedback-BTSaBAS_.mjs} +2 -3
- package/dist/{feedback-FIUBOL0g.mjs → feedback-PR8JNBfM.mjs} +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +4 -4
- package/dist/{init-DEzzXm9j.mjs → init-BU1ZnUbK.mjs} +1 -1
- package/dist/{init-DNxmjQfU.mjs → init-DUiDMMrN.mjs} +2 -0
- package/dist/intent-library.mjs +5 -0
- package/dist/library-scanner.d.mts +1 -1
- package/dist/scanner-DkShtCWX.mjs +4 -0
- package/dist/{scanner-BwCyu1Jq.mjs → scanner-OmHt14bs.mjs} +26 -2
- package/dist/{setup-CNGz26qL.mjs → setup-BvrZZLsA.mjs} +3 -12
- package/dist/{setup-N5dttGp_.d.mts → setup-D2Bwubpw.d.mts} +0 -1
- package/dist/setup.d.mts +1 -1
- package/dist/setup.mjs +1 -1
- package/dist/{types-kbQfN_is.d.mts → types-B20LP96b.d.mts} +1 -1
- package/meta/domain-discovery/SKILL.md +50 -2
- package/meta/feedback-collection/SKILL.md +156 -0
- package/meta/generate-skill/SKILL.md +9 -0
- package/meta/skill-staleness-check/SKILL.md +9 -9
- package/meta/templates/workflows/check-skills.yml +143 -0
- package/meta/tree-generator/SKILL.md +7 -1
- package/package.json +1 -1
- package/dist/scanner-fAWJUn6Q.mjs +0 -4
- package/meta/templates/oz/domain-discovery.md +0 -53
- package/meta/templates/oz/feedback-collection.md +0 -69
- package/meta/templates/oz/skill-update.md +0 -47
- package/meta/templates/oz/tree-generation.md +0 -48
- package/meta/templates/workflows/generate-skills-oz.yml +0 -86
- 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
|
|
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
|
|
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-
|
|
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
|
-
|
|
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
|
|
256
|
-
|
|
257
|
-
|
|
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
|
|
262
|
-
- skills/_artifacts/domain_map.yaml
|
|
263
|
-
-
|
|
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:
|
|
268
|
-
- Output file (
|
|
269
|
-
|
|
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:
|
|
273
|
-
- Output files
|
|
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
|
|
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
|
|
289
|
-
- Exclude skills/_artifacts
|
|
290
|
-
-
|
|
291
|
-
|
|
292
|
-
|
|
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] [--
|
|
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-
|
|
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-
|
|
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-
|
|
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(`
|
|
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
|
|
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-
|
|
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-
|
|
2
|
-
import { n as runSetup } from "./setup-
|
|
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-
|
|
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-
|
|
5
|
-
import { a as runInit, i as readProjectConfig, n as hasIntentBlock, o as writeProjectConfig, r as injectIntentBlock, t as detectAgentConfigs } from "./init-
|
|
6
|
-
import { t as runSetup } from "./setup-
|
|
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-
|
|
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) {
|
package/dist/intent-library.mjs
CHANGED
|
@@ -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}`);
|
|
@@ -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
|
|
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 && !
|
|
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.
|
|
105
|
-
else if (result.workflows.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}`);
|
package/dist/setup.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as runSetup, t as SetupResult } from "./setup-
|
|
1
|
+
import { n as runSetup, t as SetupResult } from "./setup-D2Bwubpw.mjs";
|
|
2
2
|
export { SetupResult, runSetup };
|
package/dist/setup.mjs
CHANGED
|
@@ -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 = '
|
|
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 —
|
|
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
|
-
|
|
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.
|