@tanstack/intent 0.0.10 → 0.0.13
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 +21 -21
- package/dist/cli.mjs +48 -16
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +4 -4
- package/dist/scanner-DQeiZRzp.mjs +4 -0
- package/dist/{scanner-OmHt14bs.mjs → scanner-dIYdkHQ1.mjs} +2 -2
- package/dist/setup-BYOg-Ii-.mjs +197 -0
- package/dist/setup-CANkTz55.d.mts +18 -0
- package/dist/setup.d.mts +2 -2
- package/dist/setup.mjs +2 -2
- package/meta/domain-discovery/SKILL.md +131 -53
- package/meta/feedback-collection/SKILL.md +38 -11
- package/meta/generate-skill/SKILL.md +17 -43
- package/meta/tree-generator/SKILL.md +3 -46
- package/package.json +1 -1
- package/dist/scanner-DkShtCWX.mjs +0 -4
- package/dist/setup-BJ4giTKA.d.mts +0 -9
- package/dist/setup-DGvdyKEq.mjs +0 -125
package/README.md
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
# @tanstack/intent
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A CLI for library maintainers to generate, validate, and ship [Agent Skills](https://agentskills.io) alongside their npm packages.
|
|
4
4
|
|
|
5
5
|
## The problem
|
|
6
6
|
|
|
7
7
|
Your docs are good. Your types are solid. Your agent still gets it wrong.
|
|
8
8
|
|
|
9
|
-
Docs target humans who browse. Types check individual API calls but can't encode intent. Training data snapshots the ecosystem as it _was_, mixing versions
|
|
9
|
+
Docs target humans who browse. Types check individual API calls but can't encode intent. Training data snapshots the ecosystem as it _was_, mixing versions with no way to tell which applies. Once a breaking change ships, models develop a permanent split-brain — training data contains _both_ versions forever with no way to disambiguate.
|
|
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:
|
|
13
|
+
## Skills: versioned knowledge in npm
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Skills are npm packages of knowledge — encoding how tools compose, which patterns fit which goals, and what to avoid. When a library ships skills using `@tanstack/intent`, that knowledge travels with the tool via `npm update` — not the model's training cutoff. 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 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.
|
|
18
16
|
|
|
19
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.
|
|
20
18
|
|
|
19
|
+
The [Agent Skills spec](https://agentskills.io) is an open standard already adopted by VS Code, GitHub Copilot, OpenAI Codex, Cursor, Claude Code, Goose, Amp, and others.
|
|
20
|
+
|
|
21
21
|
## Quick Start
|
|
22
22
|
|
|
23
23
|
### For library consumers
|
|
@@ -28,7 +28,7 @@ Set up skill-to-task mappings in your project's agent config files (CLAUDE.md, .
|
|
|
28
28
|
npx @tanstack/intent install
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
No per-library setup. No hunting for rules files. Install the package, run `intent install`, and the agent understands the tool. Update the package, and skills update too.
|
|
31
|
+
No per-library setup. No hunting for rules files. Install the package, run `npx @tanstack/intent install`, and the agent understands the tool. Update the package, and skills update too.
|
|
32
32
|
|
|
33
33
|
List available skills from installed packages:
|
|
34
34
|
|
|
@@ -44,7 +44,7 @@ Generate skills for your library by telling your AI coding agent to run:
|
|
|
44
44
|
npx @tanstack/intent scaffold
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
This
|
|
47
|
+
This walks the agent through domain discovery, skill tree generation, and skill creation — one step at a time with your review at each stage.
|
|
48
48
|
|
|
49
49
|
Validate your skill files:
|
|
50
50
|
|
|
@@ -61,27 +61,27 @@ npx @tanstack/intent stale
|
|
|
61
61
|
Copy CI workflow templates into your repo so validation and staleness checks run on every push:
|
|
62
62
|
|
|
63
63
|
```bash
|
|
64
|
-
npx @tanstack/intent setup
|
|
64
|
+
npx @tanstack/intent setup-github-actions
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
## Keeping skills current
|
|
68
68
|
|
|
69
|
-
The real risk with any derived artifact is staleness. `intent stale` flags skills whose source docs have changed, and CI templates catch drift before it ships.
|
|
69
|
+
The real risk with any derived artifact is staleness. `npx @tanstack/intent stale` flags skills whose source docs have changed, and CI templates catch drift before it ships.
|
|
70
70
|
|
|
71
|
-
The feedback loop runs both directions. `intent 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`.
|
|
71
|
+
The feedback loop runs both directions. `npx @tanstack/intent 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.
|
|
72
72
|
|
|
73
73
|
## CLI Commands
|
|
74
74
|
|
|
75
|
-
| Command
|
|
76
|
-
|
|
|
77
|
-
| `intent install`
|
|
78
|
-
| `intent list [--json]`
|
|
79
|
-
| `intent meta`
|
|
80
|
-
| `intent scaffold`
|
|
81
|
-
| `intent validate [dir]`
|
|
82
|
-
| `intent setup`
|
|
83
|
-
| `intent stale [--json]`
|
|
84
|
-
| `intent feedback`
|
|
75
|
+
| Command | Description |
|
|
76
|
+
| ------------------------------------------- | --------------------------------------------------- |
|
|
77
|
+
| `npx @tanstack/intent install` | Set up skill-to-task mappings in agent config files |
|
|
78
|
+
| `npx @tanstack/intent list [--json]` | Discover intent-enabled packages |
|
|
79
|
+
| `npx @tanstack/intent meta` | List meta-skills for library maintainers |
|
|
80
|
+
| `npx @tanstack/intent scaffold` | Print the guided skill generation prompt |
|
|
81
|
+
| `npx @tanstack/intent validate [dir]` | Validate SKILL.md files |
|
|
82
|
+
| `npx @tanstack/intent setup-github-actions` | Copy CI templates into your repo |
|
|
83
|
+
| `npx @tanstack/intent stale [--json]` | Check skills for version drift |
|
|
84
|
+
| `npx @tanstack/intent feedback` | Submit skill feedback |
|
|
85
85
|
|
|
86
86
|
## License
|
|
87
87
|
|
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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-dIYdkHQ1.mjs";
|
|
4
4
|
import { n as printSkillTree, r as printTable, t as computeSkillNameWidth } from "./display-D_XzuGnu.mjs";
|
|
5
5
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
6
6
|
import { dirname, join, relative, sep } from "node:path";
|
|
@@ -65,12 +65,33 @@ async function cmdList(args) {
|
|
|
65
65
|
for (const w of result.warnings) console.log(` ⚠ ${w}`);
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
-
function cmdMeta() {
|
|
68
|
+
function cmdMeta(args) {
|
|
69
69
|
const metaDir = getMetaDir();
|
|
70
70
|
if (!existsSync(metaDir)) {
|
|
71
71
|
console.error("Meta-skills directory not found.");
|
|
72
72
|
process.exit(1);
|
|
73
73
|
}
|
|
74
|
+
if (args.length > 0) {
|
|
75
|
+
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
|
+
}
|
|
80
|
+
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
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
console.log(readFileSync(skillFile, "utf8"));
|
|
88
|
+
} 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);
|
|
92
|
+
}
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
74
95
|
const entries = readdirSync(metaDir, { withFileTypes: true }).filter((e) => e.isDirectory()).filter((e) => existsSync(join(metaDir, e.name, "SKILL.md")));
|
|
75
96
|
if (entries.length === 0) {
|
|
76
97
|
console.log("No meta-skills found.");
|
|
@@ -101,7 +122,7 @@ function collectPackagingWarnings(root) {
|
|
|
101
122
|
if (!pkgJson.bin?.intent) warnings.push("Missing \"bin\": { \"intent\": ... } entry in package.json");
|
|
102
123
|
const shimJs = join(root, "bin", "intent.js");
|
|
103
124
|
const shimMjs = join(root, "bin", "intent.mjs");
|
|
104
|
-
if (!existsSync(shimJs) && !existsSync(shimMjs)) warnings.push("No bin/intent.js or bin/intent.mjs shim found (run: npx @tanstack/intent
|
|
125
|
+
if (!existsSync(shimJs) && !existsSync(shimMjs)) warnings.push("No bin/intent.js or bin/intent.mjs shim found (run: npx @tanstack/intent add-library-bin)");
|
|
105
126
|
const files = pkgJson.files;
|
|
106
127
|
if (Array.isArray(files)) {
|
|
107
128
|
if (!files.includes("skills")) warnings.push("\"skills\" is not in the \"files\" array — skills won't be published");
|
|
@@ -287,12 +308,11 @@ This produces: individual SKILL.md files.
|
|
|
287
308
|
|
|
288
309
|
1. Run \`npx @tanstack/intent validate\` in each package directory
|
|
289
310
|
2. Commit skills/ and artifacts
|
|
290
|
-
3. For each publishable package, run: \`npx @tanstack/intent
|
|
291
|
-
4.
|
|
292
|
-
5.
|
|
293
|
-
6.
|
|
294
|
-
7.
|
|
295
|
-
8. Add a README note: "If you use an AI agent, run \`npx @tanstack/intent install\`"
|
|
311
|
+
3. For each publishable package, run: \`npx @tanstack/intent add-library-bin\`
|
|
312
|
+
4. For each publishable package, run: \`npx @tanstack/intent edit-package-json\`
|
|
313
|
+
5. Ensure each package has \`@tanstack/intent\` as a devDependency
|
|
314
|
+
6. Create a \`skill:<skill-name>\` label on the GitHub repo for each skill (use \`gh label create\`)
|
|
315
|
+
7. Add a README note: "If you use an AI agent, run \`npx @tanstack/intent install\`"
|
|
296
316
|
`;
|
|
297
317
|
console.log(prompt);
|
|
298
318
|
}
|
|
@@ -300,11 +320,13 @@ const USAGE = `TanStack Intent CLI
|
|
|
300
320
|
|
|
301
321
|
Usage:
|
|
302
322
|
intent list [--json] Discover intent-enabled packages
|
|
303
|
-
intent meta
|
|
323
|
+
intent meta [name] List meta-skills, or print one by name
|
|
304
324
|
intent validate [<dir>] Validate skill files (default: skills/)
|
|
305
325
|
intent install Print a skill that guides your coding agent to set up skill-to-task mappings
|
|
306
326
|
intent scaffold Print maintainer scaffold prompt
|
|
307
|
-
intent
|
|
327
|
+
intent add-library-bin Generate bin/intent.{js,mjs} bridge file
|
|
328
|
+
intent edit-package-json Wire package.json (files, bin) for skill publishing
|
|
329
|
+
intent setup-github-actions Copy CI workflow templates to .github/workflows/
|
|
308
330
|
intent stale Check skills for staleness`;
|
|
309
331
|
const command = process.argv[2];
|
|
310
332
|
const commandArgs = process.argv.slice(3);
|
|
@@ -313,7 +335,7 @@ switch (command) {
|
|
|
313
335
|
await cmdList(commandArgs);
|
|
314
336
|
break;
|
|
315
337
|
case "meta":
|
|
316
|
-
cmdMeta();
|
|
338
|
+
cmdMeta(commandArgs);
|
|
317
339
|
break;
|
|
318
340
|
case "validate":
|
|
319
341
|
cmdValidate(commandArgs);
|
|
@@ -371,7 +393,7 @@ skills:
|
|
|
371
393
|
break;
|
|
372
394
|
case "stale": {
|
|
373
395
|
const { checkStaleness } = await import("./staleness-B5gUj7FR.mjs");
|
|
374
|
-
const { scanForIntents: scanStale } = await import("./scanner-
|
|
396
|
+
const { scanForIntents: scanStale } = await import("./scanner-DQeiZRzp.mjs");
|
|
375
397
|
let staleResult;
|
|
376
398
|
try {
|
|
377
399
|
staleResult = await scanStale();
|
|
@@ -402,9 +424,19 @@ skills:
|
|
|
402
424
|
}
|
|
403
425
|
break;
|
|
404
426
|
}
|
|
405
|
-
case "
|
|
406
|
-
const {
|
|
407
|
-
|
|
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());
|
|
408
440
|
break;
|
|
409
441
|
}
|
|
410
442
|
default:
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
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-BmnI8kFB.mjs";
|
|
2
|
-
import { n as
|
|
2
|
+
import { a as runEditPackageJson, i as runAddLibraryBin, n as EditPackageJsonResult, o as runSetupGithubActions, r as SetupGithubActionsResult, t as AddLibraryBinResult } from "./setup-CANkTz55.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/scanner.d.ts
|
|
5
5
|
declare function scanForIntents(root?: string): Promise<ScanResult>;
|
|
@@ -44,4 +44,4 @@ declare function findSkillFiles(dir: string): string[];
|
|
|
44
44
|
*/
|
|
45
45
|
declare function parseFrontmatter(filePath: string): Record<string, unknown> | null;
|
|
46
46
|
//#endregion
|
|
47
|
-
export { type AgentName, type FeedbackPayload, type IntentConfig, type IntentPackage, type IntentProjectConfig, type MetaFeedbackPayload, type MetaSkillName, type ScanResult, type SkillEntry, type SkillStaleness, type StalenessReport, checkStaleness, containsSecrets, findSkillFiles, hasGhCli, metaToMarkdown, parseFrontmatter, resolveFrequency,
|
|
47
|
+
export { type AddLibraryBinResult, type AgentName, type EditPackageJsonResult, type FeedbackPayload, type IntentConfig, type IntentPackage, type IntentProjectConfig, type MetaFeedbackPayload, type MetaSkillName, type ScanResult, type SetupGithubActionsResult, type SkillEntry, type SkillStaleness, type StalenessReport, checkStaleness, containsSecrets, findSkillFiles, hasGhCli, metaToMarkdown, parseFrontmatter, resolveFrequency, runAddLibraryBin, runEditPackageJson, runSetupGithubActions, scanForIntents, submitFeedback, submitMetaFeedback, toMarkdown, validateMetaPayload, validatePayload };
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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-dIYdkHQ1.mjs";
|
|
3
3
|
import { t as checkStaleness } from "./staleness-lP6B0O4z.mjs";
|
|
4
|
-
import { t as
|
|
4
|
+
import { n as runEditPackageJson, r as runSetupGithubActions, t as runAddLibraryBin } from "./setup-BYOg-Ii-.mjs";
|
|
5
5
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { join } from "node:path";
|
|
7
7
|
import { execFileSync, execSync } from "node:child_process";
|
|
@@ -212,7 +212,7 @@ function submitMetaFeedback(payload, opts) {
|
|
|
212
212
|
"--title",
|
|
213
213
|
`Meta-Skill Feedback: ${payload.metaSkill} (${payload.userRating})`,
|
|
214
214
|
"--label",
|
|
215
|
-
`
|
|
215
|
+
`skill:${payload.metaSkill}`,
|
|
216
216
|
"--body",
|
|
217
217
|
"-"
|
|
218
218
|
], {
|
|
@@ -246,4 +246,4 @@ function submitMetaFeedback(payload, opts) {
|
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
//#endregion
|
|
249
|
-
export { checkStaleness, containsSecrets, findSkillFiles, hasGhCli, metaToMarkdown, parseFrontmatter, resolveFrequency,
|
|
249
|
+
export { checkStaleness, containsSecrets, findSkillFiles, hasGhCli, metaToMarkdown, parseFrontmatter, resolveFrequency, runAddLibraryBin, runEditPackageJson, runSetupGithubActions, scanForIntents, submitFeedback, submitMetaFeedback, toMarkdown, validateMetaPayload, validatePayload };
|
|
@@ -125,7 +125,7 @@ async function scanForIntents(root) {
|
|
|
125
125
|
};
|
|
126
126
|
}
|
|
127
127
|
for (const entry of topEntries) {
|
|
128
|
-
if (!entry.isDirectory()) continue;
|
|
128
|
+
if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
|
|
129
129
|
const dirPath = join(nodeModulesDir, entry.name);
|
|
130
130
|
if (entry.name.startsWith("@")) {
|
|
131
131
|
let scopedEntries;
|
|
@@ -138,7 +138,7 @@ async function scanForIntents(root) {
|
|
|
138
138
|
continue;
|
|
139
139
|
}
|
|
140
140
|
for (const scoped of scopedEntries) {
|
|
141
|
-
if (!scoped.isDirectory()) continue;
|
|
141
|
+
if (!scoped.isDirectory() && !scoped.isSymbolicLink()) continue;
|
|
142
142
|
packageDirs.push({ dirPath: join(dirPath, scoped.name) });
|
|
143
143
|
}
|
|
144
144
|
} else if (!entry.name.startsWith(".")) packageDirs.push({ dirPath });
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
//#region src/setup.ts
|
|
5
|
+
function detectVars(root) {
|
|
6
|
+
const pkgPath = join(root, "package.json");
|
|
7
|
+
let pkgJson = {};
|
|
8
|
+
try {
|
|
9
|
+
pkgJson = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
10
|
+
} catch (err) {
|
|
11
|
+
if (!(err && typeof err === "object" && "code" in err && err.code === "ENOENT")) console.error(`Warning: could not read ${pkgPath}: ${err instanceof Error ? err.message : err}`);
|
|
12
|
+
}
|
|
13
|
+
const name = typeof pkgJson.name === "string" ? pkgJson.name : "unknown";
|
|
14
|
+
const intent = pkgJson.intent;
|
|
15
|
+
const repo = typeof intent?.repo === "string" ? intent.repo : name.replace(/^@/, "").replace(/\//, "/");
|
|
16
|
+
const docs = typeof intent?.docs === "string" ? intent.docs : "docs/";
|
|
17
|
+
let srcPath = `packages/${name.replace(/^@[^/]+\//, "")}/src/**`;
|
|
18
|
+
if (existsSync(join(root, "src"))) srcPath = "src/**";
|
|
19
|
+
return {
|
|
20
|
+
PACKAGE_NAME: name,
|
|
21
|
+
REPO: repo,
|
|
22
|
+
DOCS_PATH: docs.endsWith("**") ? docs : docs.replace(/\/$/, "") + "/**",
|
|
23
|
+
SRC_PATH: srcPath
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function applyVars(content, vars) {
|
|
27
|
+
return content.replace(/\{\{PACKAGE_NAME\}\}/g, vars.PACKAGE_NAME).replace(/\{\{REPO\}\}/g, vars.REPO).replace(/\{\{DOCS_PATH\}\}/g, vars.DOCS_PATH).replace(/\{\{SRC_PATH\}\}/g, vars.SRC_PATH);
|
|
28
|
+
}
|
|
29
|
+
function copyTemplates(srcDir, destDir, vars) {
|
|
30
|
+
const copied = [];
|
|
31
|
+
const skipped = [];
|
|
32
|
+
if (!existsSync(srcDir)) return {
|
|
33
|
+
copied,
|
|
34
|
+
skipped
|
|
35
|
+
};
|
|
36
|
+
mkdirSync(destDir, { recursive: true });
|
|
37
|
+
for (const entry of readdirSync(srcDir)) {
|
|
38
|
+
const srcPath = join(srcDir, entry);
|
|
39
|
+
const destPath = join(destDir, entry);
|
|
40
|
+
if (existsSync(destPath)) {
|
|
41
|
+
skipped.push(destPath);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
writeFileSync(destPath, applyVars(readFileSync(srcPath, "utf8"), vars));
|
|
45
|
+
copied.push(destPath);
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
copied,
|
|
49
|
+
skipped
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function getShimContent(ext) {
|
|
53
|
+
return `#!/usr/bin/env node
|
|
54
|
+
// Auto-generated by @tanstack/intent setup
|
|
55
|
+
// Exposes the intent end-user CLI for consumers of this library.
|
|
56
|
+
// Commit this file, then add to your package.json:
|
|
57
|
+
// "bin": { "intent": "./bin/intent.${ext}" }
|
|
58
|
+
await import('@tanstack/intent/intent-library')
|
|
59
|
+
`;
|
|
60
|
+
}
|
|
61
|
+
function detectShimExtension(root) {
|
|
62
|
+
try {
|
|
63
|
+
if (JSON.parse(readFileSync(join(root, "package.json"), "utf8")).type === "module") return "js";
|
|
64
|
+
} catch (err) {
|
|
65
|
+
if (!(err && typeof err === "object" && "code" in err && err.code === "ENOENT")) console.error(`Warning: could not read package.json: ${err instanceof Error ? err.message : err}`);
|
|
66
|
+
}
|
|
67
|
+
return "mjs";
|
|
68
|
+
}
|
|
69
|
+
function findExistingShim(root) {
|
|
70
|
+
const shimJs = join(root, "bin", "intent.js");
|
|
71
|
+
if (existsSync(shimJs)) return shimJs;
|
|
72
|
+
const shimMjs = join(root, "bin", "intent.mjs");
|
|
73
|
+
if (existsSync(shimMjs)) return shimMjs;
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
function runAddLibraryBin(root) {
|
|
77
|
+
const result = {
|
|
78
|
+
shim: null,
|
|
79
|
+
skipped: null
|
|
80
|
+
};
|
|
81
|
+
const existingShim = findExistingShim(root);
|
|
82
|
+
if (existingShim) {
|
|
83
|
+
result.skipped = existingShim;
|
|
84
|
+
console.log(` Already exists: ${existingShim}`);
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
const ext = detectShimExtension(root);
|
|
88
|
+
const shimPath = join(root, "bin", `intent.${ext}`);
|
|
89
|
+
mkdirSync(join(root, "bin"), { recursive: true });
|
|
90
|
+
writeFileSync(shimPath, getShimContent(ext));
|
|
91
|
+
result.shim = shimPath;
|
|
92
|
+
console.log(`✓ Generated intent shim: ${shimPath}`);
|
|
93
|
+
console.log(`\n Run \`npx @tanstack/intent edit-package-json\` to wire package.json.`);
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
function runEditPackageJson(root) {
|
|
97
|
+
const result = {
|
|
98
|
+
added: [],
|
|
99
|
+
alreadyPresent: []
|
|
100
|
+
};
|
|
101
|
+
const pkgPath = join(root, "package.json");
|
|
102
|
+
if (!existsSync(pkgPath)) {
|
|
103
|
+
console.error("No package.json found in " + root);
|
|
104
|
+
process.exitCode = 1;
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
const raw = readFileSync(pkgPath, "utf8");
|
|
108
|
+
let pkg;
|
|
109
|
+
try {
|
|
110
|
+
pkg = JSON.parse(raw);
|
|
111
|
+
} catch (err) {
|
|
112
|
+
const detail = err instanceof SyntaxError ? err.message : String(err);
|
|
113
|
+
console.error(`Failed to parse ${pkgPath}: ${detail}`);
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
const indentMatch = raw.match(/^(\s+)"/m);
|
|
117
|
+
const indentSize = indentMatch?.[1] ? indentMatch[1].length : 2;
|
|
118
|
+
if (!Array.isArray(pkg.files)) pkg.files = [];
|
|
119
|
+
const files = pkg.files;
|
|
120
|
+
const requiredFiles = (() => {
|
|
121
|
+
let dir = join(root, "..");
|
|
122
|
+
for (let i = 0; i < 5; i++) {
|
|
123
|
+
const parentPkg = join(dir, "package.json");
|
|
124
|
+
if (existsSync(parentPkg)) {
|
|
125
|
+
try {
|
|
126
|
+
const parent = JSON.parse(readFileSync(parentPkg, "utf8"));
|
|
127
|
+
if (Array.isArray(parent.workspaces) || parent.workspaces?.packages) return true;
|
|
128
|
+
} catch {}
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
const next = join(dir, "..");
|
|
132
|
+
if (next === dir) break;
|
|
133
|
+
dir = next;
|
|
134
|
+
}
|
|
135
|
+
return false;
|
|
136
|
+
})() ? ["skills", "bin"] : [
|
|
137
|
+
"skills",
|
|
138
|
+
"bin",
|
|
139
|
+
"!skills/_artifacts"
|
|
140
|
+
];
|
|
141
|
+
for (const entry of requiredFiles) if (files.includes(entry)) result.alreadyPresent.push(`files: "${entry}"`);
|
|
142
|
+
else {
|
|
143
|
+
files.push(entry);
|
|
144
|
+
result.added.push(`files: "${entry}"`);
|
|
145
|
+
}
|
|
146
|
+
const existingShim = findExistingShim(root);
|
|
147
|
+
let ext;
|
|
148
|
+
if (existingShim) ext = existingShim.endsWith(".mjs") ? "mjs" : "js";
|
|
149
|
+
else ext = pkg.type === "module" ? "js" : "mjs";
|
|
150
|
+
const shimRelative = `./bin/intent.${ext}`;
|
|
151
|
+
if (typeof pkg.bin === "object" && pkg.bin !== null) {
|
|
152
|
+
const binObj = pkg.bin;
|
|
153
|
+
if (binObj.intent) result.alreadyPresent.push(`bin.intent`);
|
|
154
|
+
else {
|
|
155
|
+
binObj.intent = shimRelative;
|
|
156
|
+
result.added.push(`bin.intent: "${shimRelative}"`);
|
|
157
|
+
}
|
|
158
|
+
} else if (!pkg.bin) {
|
|
159
|
+
pkg.bin = { intent: shimRelative };
|
|
160
|
+
result.added.push(`bin.intent: "${shimRelative}"`);
|
|
161
|
+
} else if (typeof pkg.bin === "string") {
|
|
162
|
+
const pkgName = typeof pkg.name === "string" ? pkg.name.replace(/^@[^/]+\//, "") : "unknown";
|
|
163
|
+
pkg.bin = {
|
|
164
|
+
[pkgName]: pkg.bin,
|
|
165
|
+
intent: shimRelative
|
|
166
|
+
};
|
|
167
|
+
result.added.push(`bin.intent: "${shimRelative}" (converted bin from string to object)`);
|
|
168
|
+
}
|
|
169
|
+
writeFileSync(pkgPath, JSON.stringify(pkg, null, indentSize) + "\n");
|
|
170
|
+
for (const a of result.added) console.log(`✓ Added ${a}`);
|
|
171
|
+
for (const a of result.alreadyPresent) console.log(` Already present: ${a}`);
|
|
172
|
+
return result;
|
|
173
|
+
}
|
|
174
|
+
function runSetupGithubActions(root, metaDir) {
|
|
175
|
+
const vars = detectVars(root);
|
|
176
|
+
const result = {
|
|
177
|
+
workflows: [],
|
|
178
|
+
skipped: []
|
|
179
|
+
};
|
|
180
|
+
const { copied, skipped } = copyTemplates(join(metaDir, "templates", "workflows"), join(root, ".github", "workflows"), vars);
|
|
181
|
+
result.workflows = copied;
|
|
182
|
+
result.skipped = skipped;
|
|
183
|
+
for (const f of result.workflows) console.log(`✓ Copied workflow: ${f}`);
|
|
184
|
+
for (const f of result.skipped) console.log(` Already exists: ${f}`);
|
|
185
|
+
if (result.workflows.length === 0 && result.skipped.length === 0) console.log("No templates directory found. Is @tanstack/intent installed?");
|
|
186
|
+
else if (result.workflows.length > 0) {
|
|
187
|
+
console.log(`\nTemplate variables applied:`);
|
|
188
|
+
console.log(` Package: ${vars.PACKAGE_NAME}`);
|
|
189
|
+
console.log(` Repo: ${vars.REPO}`);
|
|
190
|
+
console.log(` Docs: ${vars.DOCS_PATH}`);
|
|
191
|
+
console.log(` Src: ${vars.SRC_PATH}`);
|
|
192
|
+
}
|
|
193
|
+
return result;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
//#endregion
|
|
197
|
+
export { runEditPackageJson as n, runSetupGithubActions as r, runAddLibraryBin as t };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/setup.d.ts
|
|
2
|
+
interface AddLibraryBinResult {
|
|
3
|
+
shim: string | null;
|
|
4
|
+
skipped: string | null;
|
|
5
|
+
}
|
|
6
|
+
interface EditPackageJsonResult {
|
|
7
|
+
added: string[];
|
|
8
|
+
alreadyPresent: string[];
|
|
9
|
+
}
|
|
10
|
+
interface SetupGithubActionsResult {
|
|
11
|
+
workflows: string[];
|
|
12
|
+
skipped: string[];
|
|
13
|
+
}
|
|
14
|
+
declare function runAddLibraryBin(root: string): AddLibraryBinResult;
|
|
15
|
+
declare function runEditPackageJson(root: string): EditPackageJsonResult;
|
|
16
|
+
declare function runSetupGithubActions(root: string, metaDir: string): SetupGithubActionsResult;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { runEditPackageJson as a, runAddLibraryBin as i, EditPackageJsonResult as n, runSetupGithubActions as o, SetupGithubActionsResult as r, AddLibraryBinResult as t };
|
package/dist/setup.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
export {
|
|
1
|
+
import { a as runEditPackageJson, i as runAddLibraryBin, n as EditPackageJsonResult, o as runSetupGithubActions, r as SetupGithubActionsResult, t as AddLibraryBinResult } from "./setup-CANkTz55.mjs";
|
|
2
|
+
export { AddLibraryBinResult, EditPackageJsonResult, SetupGithubActionsResult, runAddLibraryBin, runEditPackageJson, runSetupGithubActions };
|
package/dist/setup.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { t as
|
|
1
|
+
import { n as runEditPackageJson, r as runSetupGithubActions, t as runAddLibraryBin } from "./setup-BYOg-Ii-.mjs";
|
|
2
2
|
|
|
3
|
-
export {
|
|
3
|
+
export { runAddLibraryBin, runEditPackageJson, runSetupGithubActions };
|
|
@@ -42,9 +42,12 @@ path applies (see below).
|
|
|
42
42
|
|
|
43
43
|
### Lightweight path (small libraries)
|
|
44
44
|
|
|
45
|
-
After Phase 1,
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
After Phase 1, decide whether the library warrants the full five-phase
|
|
46
|
+
flow or the compressed flow below. This is a judgment call — lean toward
|
|
47
|
+
full discovery unless the library is obviously small (single-purpose
|
|
48
|
+
utility, 2–3 distinct developer tasks max). Use a compressed flow when
|
|
49
|
+
the skill surface is small enough that two interview rounds would be
|
|
50
|
+
redundant:
|
|
48
51
|
|
|
49
52
|
1. **Phase 1** — Quick scan (same as full flow)
|
|
50
53
|
2. **Phase 2+4 combined** — Single interview round. Combine the
|
|
@@ -59,6 +62,42 @@ The lightweight path produces identical output artifacts (domain_map.yaml
|
|
|
59
62
|
and skill_spec.md). It just avoids two separate interview rounds when the
|
|
60
63
|
library is small enough that one round covers everything.
|
|
61
64
|
|
|
65
|
+
### Hard rules — interview phases are mandatory and interactive
|
|
66
|
+
|
|
67
|
+
These rules override any other reasoning. No exceptions.
|
|
68
|
+
|
|
69
|
+
1. **Phases 2 and 4 are interactive interviews conducted with the
|
|
70
|
+
maintainer.** You must ask the questions specified in each sub-section
|
|
71
|
+
and wait for the maintainer's response before continuing. Documentation,
|
|
72
|
+
source code, and other automated analysis are NOT substitutes for the
|
|
73
|
+
maintainer's answers.
|
|
74
|
+
2. **Every question in Phases 2 and 4 must be asked as an open-ended
|
|
75
|
+
question and sent as a message to the maintainer.** You must then
|
|
76
|
+
STOP and WAIT for their reply. Do not answer your own questions. Do
|
|
77
|
+
not infer answers from documentation. Do not skip questions because
|
|
78
|
+
you believe you already know the answer.
|
|
79
|
+
3. **Do not convert open-ended questions into multiple-choice,
|
|
80
|
+
yes/no, or confirmation prompts.** The question templates in each
|
|
81
|
+
sub-section are open-ended by design. Present them as open-ended
|
|
82
|
+
questions. The maintainer's unprompted answers surface knowledge that
|
|
83
|
+
pre-structured options suppress.
|
|
84
|
+
4. **Minimum question counts are enforced.** Each sub-section specifies
|
|
85
|
+
a question count range (e.g. "2–4 questions"). You must ask at least
|
|
86
|
+
the minimum number. Asking zero questions in any sub-section is a
|
|
87
|
+
protocol violation.
|
|
88
|
+
5. **STOP gates are mandatory.** At the boundaries marked `── STOP ──`
|
|
89
|
+
below, you must halt execution and wait for the maintainer's response
|
|
90
|
+
or acknowledgment before proceeding. Do not continue past a STOP gate
|
|
91
|
+
in the same message.
|
|
92
|
+
6. **If the maintainer asks to skip an interview phase**, explain the
|
|
93
|
+
value of the phase and what will be lost. Proceed with skipping only
|
|
94
|
+
if they confirm a second time.
|
|
95
|
+
7. **Rich documentation makes interviews MORE valuable, not less.**
|
|
96
|
+
When docs are comprehensive, the interview surfaces what docs miss:
|
|
97
|
+
implicit knowledge, AI-specific failure modes, undocumented tradeoffs,
|
|
98
|
+
and the maintainer's prioritization of what matters most. Never
|
|
99
|
+
rationalize skipping interviews because documentation is thorough.
|
|
100
|
+
|
|
62
101
|
---
|
|
63
102
|
|
|
64
103
|
## Phase 1 — Quick scan (autonomous, ~10 minutes)
|
|
@@ -105,20 +144,37 @@ Log (but do not group yet):
|
|
|
105
144
|
- Which frameworks it supports
|
|
106
145
|
- Any existing skill files, agent configs, or intents
|
|
107
146
|
- Whether the library is a monorepo and which packages matter
|
|
147
|
+
- Peer dependency constraints — read `peerDependencies` and
|
|
148
|
+
`peerDependenciesMeta` from each client-facing package.json to
|
|
149
|
+
understand version ranges and optional integrations early
|
|
150
|
+
|
|
151
|
+
Present your initial impressions to the maintainer as a brief summary
|
|
152
|
+
(3–5 bullets). This orients them on what you found and primes them for
|
|
153
|
+
the interview.
|
|
154
|
+
|
|
155
|
+
**── STOP ── Do not proceed to Phase 2 until the maintainer has
|
|
156
|
+
acknowledged your summary or responded.**
|
|
108
157
|
|
|
109
158
|
---
|
|
110
159
|
|
|
111
|
-
## Phase 2 — High-level interview
|
|
160
|
+
## Phase 2 — High-level interview (interactive — requires maintainer)
|
|
112
161
|
|
|
113
162
|
The maintainer's mental model of developer tasks IS the skill map. Your
|
|
114
163
|
job in this phase is to extract it — not to propose your own structure.
|
|
115
164
|
|
|
165
|
+
You must ask the questions below to the maintainer and wait for their
|
|
166
|
+
responses. Do not infer answers from documentation or source code.
|
|
167
|
+
|
|
116
168
|
### Rules for Phase 2
|
|
117
169
|
|
|
118
170
|
1. One topic per message for open-ended questions. You may batch 2–3
|
|
119
171
|
yes/no or short-confirmation questions together.
|
|
120
|
-
2.
|
|
121
|
-
|
|
172
|
+
2. Ask each question as written (you may adapt phrasing to context, but
|
|
173
|
+
keep questions open-ended — never convert to multiple-choice).
|
|
174
|
+
3. Wait for the maintainer's response after each question before asking
|
|
175
|
+
the next.
|
|
176
|
+
4. Take notes silently. Do not summarize back unless asked.
|
|
177
|
+
5. If the maintainer gives a short answer, probe deeper before moving on.
|
|
122
178
|
|
|
123
179
|
### 2a — Developer tasks (2–4 questions)
|
|
124
180
|
|
|
@@ -135,6 +191,13 @@ Follow up to enumerate distinct tasks:
|
|
|
135
191
|
> things like 'set up the client', 'implement auth', 'debug sync issues'
|
|
136
192
|
> — each one a separate moment where they'd want focused guidance."
|
|
137
193
|
|
|
194
|
+
For monorepo libraries, also ask about cross-package tasks:
|
|
195
|
+
|
|
196
|
+
> "Are there tasks that touch multiple packages in your monorepo? For
|
|
197
|
+
> example, a getting-started flow that requires imports from both the
|
|
198
|
+
> client and server packages? I want to make sure skills that span
|
|
199
|
+
> package boundaries are captured correctly."
|
|
200
|
+
|
|
138
201
|
### 2b — Developer journeys (1–2 questions)
|
|
139
202
|
|
|
140
203
|
Surface lifecycle/journey skills that cross-cut task areas:
|
|
@@ -144,13 +207,22 @@ Surface lifecycle/journey skills that cross-cut task areas:
|
|
|
144
207
|
> a migrate-from-v4 walkthrough. Which of these exist in your docs
|
|
145
208
|
> or would be valuable as standalone skills?"
|
|
146
209
|
|
|
147
|
-
### 2c — Composition and ecosystem (1–
|
|
210
|
+
### 2c — Composition and ecosystem (1–3 questions)
|
|
148
211
|
|
|
149
212
|
> "Which other libraries does yours compose with most often? Are there
|
|
150
213
|
> integration patterns important enough to warrant their own skill —
|
|
151
214
|
> for example, using your library with [framework/ORM/router]?"
|
|
152
215
|
|
|
153
|
-
|
|
216
|
+
> "Are there tasks that developers might expect your library to handle,
|
|
217
|
+
> but that are actually handled by a companion library? Which tasks
|
|
218
|
+
> should we explicitly exclude from your library's skills?"
|
|
219
|
+
|
|
220
|
+
### 2d — Exclude experimental features (1 question)
|
|
221
|
+
|
|
222
|
+
> "Are there any features that are experimental, unstable, or not yet
|
|
223
|
+
> ready to document for agents? We'll exclude these from the skill set."
|
|
224
|
+
|
|
225
|
+
### 2e — Confirm initial skill map
|
|
154
226
|
|
|
155
227
|
Synthesize what you heard into a proposed skill list and present it:
|
|
156
228
|
|
|
@@ -158,6 +230,9 @@ Synthesize what you heard into a proposed skill list and present it:
|
|
|
158
230
|
> [enumerate skills with one-line descriptions]. Does this match how
|
|
159
231
|
> you think about your library? What would you add, remove, or rename?"
|
|
160
232
|
|
|
233
|
+
**── STOP ── Do not proceed to Phase 3 until the maintainer has
|
|
234
|
+
reviewed and confirmed (or corrected) the skill list.**
|
|
235
|
+
|
|
161
236
|
---
|
|
162
237
|
|
|
163
238
|
## Phase 3 — Deep read (autonomous)
|
|
@@ -170,7 +245,14 @@ gotchas.
|
|
|
170
245
|
|
|
171
246
|
Read in this order. Each step builds context for the next.
|
|
172
247
|
|
|
173
|
-
|
|
248
|
+
Before starting, list every file in the docs directory (and subdirectories).
|
|
249
|
+
Use this list as a checklist — every narrative file must be read. Do not
|
|
250
|
+
sample a subset and extrapolate.
|
|
251
|
+
|
|
252
|
+
1. **Narrative guides** — read as many as needed to build confidence in
|
|
253
|
+
your understanding. Prioritize getting-started, migration, and guides
|
|
254
|
+
covering the skill areas from Phase 2. Skip exhaustive reading of large
|
|
255
|
+
online-only doc sets.
|
|
174
256
|
2. **Migration guides** — highest-yield source for failure modes; every
|
|
175
257
|
breaking change is exactly what agents trained on older versions produce
|
|
176
258
|
3. **API reference** — scan for exports, type signatures, option shapes
|
|
@@ -417,20 +499,35 @@ Present the draft to the maintainer before starting Phase 4:
|
|
|
417
499
|
> [N] skills and [M] failure modes. I've flagged [K] specific gaps where
|
|
418
500
|
> I need your input."
|
|
419
501
|
|
|
502
|
+
Include the full draft domain_map.yaml in your message so the maintainer
|
|
503
|
+
can review it. Also include a checklist of all docs files you read.
|
|
504
|
+
|
|
505
|
+
**── STOP ── Do not proceed to Phase 4 until the maintainer has
|
|
506
|
+
reviewed the draft and responded. Their feedback on the draft informs
|
|
507
|
+
the detail interview questions.**
|
|
508
|
+
|
|
420
509
|
---
|
|
421
510
|
|
|
422
|
-
## Phase 4 — Detail interview (
|
|
511
|
+
## Phase 4 — Detail interview (interactive — requires maintainer)
|
|
423
512
|
|
|
424
513
|
You have the maintainer's task map and a deep read. The interview now
|
|
425
514
|
fills gaps, validates your understanding, and surfaces implicit knowledge.
|
|
426
515
|
|
|
516
|
+
You must ask the questions below to the maintainer and wait for their
|
|
517
|
+
responses. Do not infer answers from documentation or source code —
|
|
518
|
+
even for gaps you think you can answer from your reading.
|
|
519
|
+
|
|
427
520
|
### Rules for Phase 4
|
|
428
521
|
|
|
429
522
|
1. One topic per message for open-ended questions. You may batch 2–3
|
|
430
523
|
yes/no or short-confirmation questions together.
|
|
431
|
-
2.
|
|
432
|
-
|
|
433
|
-
|
|
524
|
+
2. Ask each question as written (you may adapt phrasing to context, but
|
|
525
|
+
keep questions open-ended — never convert to multiple-choice).
|
|
526
|
+
3. Each question must reference something specific from your reading.
|
|
527
|
+
4. Wait for the maintainer's response after each question before asking
|
|
528
|
+
the next.
|
|
529
|
+
5. If the maintainer gives a short answer, probe deeper before moving on.
|
|
530
|
+
6. Take notes silently. Do not summarize back unless asked.
|
|
434
531
|
|
|
435
532
|
### 4a — Draft review (2–3 questions)
|
|
436
533
|
|
|
@@ -538,6 +635,10 @@ Merge interview findings into the draft. For each interview answer:
|
|
|
538
635
|
4. If it reveals a new skill — add it
|
|
539
636
|
5. If it fills a gap — remove from gaps section
|
|
540
637
|
|
|
638
|
+
Validate the domain_map.yaml by parsing it with a YAML parser. Check for
|
|
639
|
+
duplicate keys, invalid syntax, and structural correctness. Fix any issues
|
|
640
|
+
before presenting the final artifact.
|
|
641
|
+
|
|
541
642
|
Update `status: draft` to `status: reviewed`.
|
|
542
643
|
|
|
543
644
|
---
|
|
@@ -580,6 +681,9 @@ skills:
|
|
|
580
681
|
domain: '[parent domain slug]'
|
|
581
682
|
description: '[what a developer is doing — matches a specific task/moment]'
|
|
582
683
|
type: '[core | framework | lifecycle | composition]'
|
|
684
|
+
packages: # required for monorepo; omit for single-package libraries
|
|
685
|
+
- '[primary package name]'
|
|
686
|
+
- '[secondary package name, if skill spans multiple packages]'
|
|
583
687
|
covers:
|
|
584
688
|
- '[API/hook/concept 1]'
|
|
585
689
|
- '[API/hook/concept 2]'
|
|
@@ -710,6 +814,11 @@ not promotional.]
|
|
|
710
814
|
| ------------------------------------- | -------------------------------------------------------------------------- |
|
|
711
815
|
| Quick scan before interview | Never interview without at least reading README and package structure |
|
|
712
816
|
| High-level interview before deep read | The maintainer's task map informs what you read deeply |
|
|
817
|
+
| **Interview phases are interactive** | Phases 2 and 4 require sending questions to the maintainer and waiting |
|
|
818
|
+
| **Docs are not a substitute** | Documentation cannot replace maintainer answers — even comprehensive docs |
|
|
819
|
+
| **Open-ended questions stay open** | Never convert interview questions to multiple-choice or yes/no |
|
|
820
|
+
| **Minimum question counts enforced** | Each sub-section's minimum count must be met; zero questions = violation |
|
|
821
|
+
| **STOP gates are mandatory** | Do not proceed past a STOP gate without maintainer response |
|
|
713
822
|
| Batch only confirmations | Yes/no questions may batch 2–3; open-ended questions get their own message |
|
|
714
823
|
| Questions reference findings | No generic questions — cite what you found |
|
|
715
824
|
| Skills are task-focused | Each skill matches a developer moment, not a conceptual area |
|
|
@@ -719,6 +828,7 @@ not promotional.]
|
|
|
719
828
|
| No marketing prose | Library description is factual, not promotional |
|
|
720
829
|
| domain_map.yaml is valid YAML | Parseable by any YAML parser |
|
|
721
830
|
| Draft before detail interview | Present draft for review before Phase 4 |
|
|
831
|
+
| **Draft reviewed before Phase 4** | Maintainer must acknowledge or respond to draft before detail interview |
|
|
722
832
|
| Agent-specific failures probed | Always ask AI-agent-specific questions in Phase 4c |
|
|
723
833
|
| Compositions discovered from code | Scan peer deps and examples before asking composition questions |
|
|
724
834
|
| Cross-skill failure modes tagged | Failure modes spanning skills list all relevant slugs |
|
|
@@ -727,6 +837,7 @@ not promotional.]
|
|
|
727
837
|
| Dense surfaces flagged | Topics with >10 patterns noted as reference_candidates |
|
|
728
838
|
| Lifecycle skills considered | Suggest journey skills when docs have the material |
|
|
729
839
|
| Cross-references mapped | Skills that illuminate each other get "See also" pointers |
|
|
840
|
+
| **All docs files read** | List docs directory contents and read every narrative file — no sampling |
|
|
730
841
|
|
|
731
842
|
---
|
|
732
843
|
|
|
@@ -736,49 +847,16 @@ This skill is designed to produce consistent results across Claude, GPT-4+,
|
|
|
736
847
|
Gemini, and open-source models. To achieve this:
|
|
737
848
|
|
|
738
849
|
- All instructions use imperative sentences, not suggestions
|
|
850
|
+
- Interview phases use explicit STOP gates to prevent models from
|
|
851
|
+
continuing autonomously past interactive checkpoints
|
|
852
|
+
- Hard rules at the top override any model tendency to rationalize
|
|
853
|
+
skipping interactive phases when documentation is available
|
|
854
|
+
- Open-ended questions are explicitly protected from conversion to
|
|
855
|
+
multiple-choice or confirmation prompts, which models default to
|
|
856
|
+
when they have enough context to pre-populate answers
|
|
739
857
|
- Output formats use YAML (universally parsed) and Markdown tables
|
|
740
858
|
(universally rendered)
|
|
741
859
|
- Examples use concrete values, not placeholders like "[your value here]"
|
|
742
860
|
- Section boundaries use Markdown headers (##) for navigation and --- for
|
|
743
861
|
phase separation
|
|
744
862
|
- No model-specific features (no XML tags in output, no tool_use assumptions)
|
|
745
|
-
|
|
746
|
-
---
|
|
747
|
-
|
|
748
|
-
## Meta-skill feedback (alpha default)
|
|
749
|
-
|
|
750
|
-
After finalizing artifacts, create or update a single Markdown feedback draft
|
|
751
|
-
for all three meta skills used in scaffolding. Use this exact template and
|
|
752
|
-
fill only the **Domain Discovery** section now. Leave the other sections in
|
|
753
|
-
place for later steps to complete.
|
|
754
|
-
|
|
755
|
-
```
|
|
756
|
-
# Intent Meta Skill Feedback
|
|
757
|
-
|
|
758
|
-
## Domain Discovery
|
|
759
|
-
- What worked well:
|
|
760
|
-
- What was confusing or missing:
|
|
761
|
-
- Suggestions for improvement:
|
|
762
|
-
- Overall rating: good | mixed | bad
|
|
763
|
-
|
|
764
|
-
## Tree Generator
|
|
765
|
-
- What worked well:
|
|
766
|
-
- What was confusing or missing:
|
|
767
|
-
- Suggestions for improvement:
|
|
768
|
-
- Overall rating: good | mixed | bad
|
|
769
|
-
|
|
770
|
-
## Generate Skill
|
|
771
|
-
- What worked well:
|
|
772
|
-
- What was confusing or missing:
|
|
773
|
-
- Suggestions for improvement:
|
|
774
|
-
- Overall rating: good | mixed | bad
|
|
775
|
-
|
|
776
|
-
## Context (optional)
|
|
777
|
-
- Library:
|
|
778
|
-
- Repo:
|
|
779
|
-
- Docs:
|
|
780
|
-
- Notes:
|
|
781
|
-
```
|
|
782
|
-
|
|
783
|
-
Do not submit feedback yet. Tell the maintainer to carry this draft forward
|
|
784
|
-
to the next meta skill step.
|
|
@@ -17,13 +17,29 @@ Run this at the end of any session where you loaded one or more SKILL.md files.
|
|
|
17
17
|
The goal is to capture what worked, what didn't, and what was missing — so skill
|
|
18
18
|
maintainers can improve future versions.
|
|
19
19
|
|
|
20
|
+
This skill also covers **meta-skill feedback** — feedback about the scaffolding
|
|
21
|
+
process itself. When invoked after running domain-discovery, tree-generator, and
|
|
22
|
+
generate-skill, treat those three meta skills as the "skills" being evaluated.
|
|
23
|
+
Capture what worked and what didn't in each scaffolding phase so the meta skills
|
|
24
|
+
can be improved.
|
|
25
|
+
|
|
20
26
|
---
|
|
21
27
|
|
|
22
28
|
## Phase 1 — Automated Signal Collection
|
|
23
29
|
|
|
24
30
|
Review your own session transcript. No human interaction needed yet.
|
|
25
31
|
|
|
26
|
-
### 1a:
|
|
32
|
+
### 1a: Skills inventory
|
|
33
|
+
|
|
34
|
+
Before analyzing gaps and errors, inventory all skills that were available
|
|
35
|
+
during the session:
|
|
36
|
+
|
|
37
|
+
- **Loaded and used:** Skills you read and actively followed.
|
|
38
|
+
- **Available but not loaded:** Skills that were installed (discoverable via
|
|
39
|
+
`intent list`) but you never read. This is important — many issues stem from
|
|
40
|
+
the agent not loading the right skill, not from the skill itself being wrong.
|
|
41
|
+
|
|
42
|
+
### 1b: Gap detection
|
|
27
43
|
|
|
28
44
|
Identify moments where the skill was silent and you had to bridge the gap
|
|
29
45
|
yourself — via code reading, search, trial-and-error, or general knowledge.
|
|
@@ -34,7 +50,7 @@ For each gap, note:
|
|
|
34
50
|
- What the skill should have told you
|
|
35
51
|
- How you solved it (code reading, web search, guessing)
|
|
36
52
|
|
|
37
|
-
###
|
|
53
|
+
### 1c: Error/correction tracking
|
|
38
54
|
|
|
39
55
|
Identify moments where the skill prescribed an approach that produced an error.
|
|
40
56
|
|
|
@@ -44,7 +60,7 @@ For each error, note:
|
|
|
44
60
|
- The error or incorrect behavior that resulted
|
|
45
61
|
- The fix you applied
|
|
46
62
|
|
|
47
|
-
###
|
|
63
|
+
### 1d: Human intervention events
|
|
48
64
|
|
|
49
65
|
Identify moments where the human clarified, corrected, or overrode your approach.
|
|
50
66
|
|
|
@@ -54,7 +70,7 @@ For each intervention, note:
|
|
|
54
70
|
- What the human said or changed
|
|
55
71
|
- Whether the skill could have prevented this
|
|
56
72
|
|
|
57
|
-
###
|
|
73
|
+
### 1e: Step duration anomalies
|
|
58
74
|
|
|
59
75
|
Identify steps that consumed disproportionate effort compared to their apparent
|
|
60
76
|
complexity. These signal that the skill should provide a template, snippet, or
|
|
@@ -101,21 +117,31 @@ referenced.
|
|
|
101
117
|
|
|
102
118
|
[one-sentence summary of what the human asked you to do]
|
|
103
119
|
|
|
120
|
+
## Skills Inventory
|
|
121
|
+
|
|
122
|
+
**Loaded and used:**
|
|
123
|
+
|
|
124
|
+
- [list each skill the agent read and actively followed during the session]
|
|
125
|
+
|
|
126
|
+
**Available but not loaded:**
|
|
127
|
+
|
|
128
|
+
- [list skills that were installed/available but the agent never read]
|
|
129
|
+
|
|
104
130
|
## What Worked
|
|
105
131
|
|
|
106
132
|
[patterns/instructions from the skill that were accurate and helpful]
|
|
107
133
|
|
|
108
134
|
## What Failed
|
|
109
135
|
|
|
110
|
-
[from
|
|
136
|
+
[from 1c — skill instructions that produced errors]
|
|
111
137
|
|
|
112
138
|
## Missing
|
|
113
139
|
|
|
114
|
-
[from
|
|
140
|
+
[from 1b — gaps where the skill should have covered]
|
|
115
141
|
|
|
116
142
|
## Self-Corrections
|
|
117
143
|
|
|
118
|
-
[from
|
|
144
|
+
[from 1c fixes + 1d human interventions, combined]
|
|
119
145
|
|
|
120
146
|
## User Comments
|
|
121
147
|
|
|
@@ -130,10 +156,11 @@ referenced.
|
|
|
130
156
|
| Package | The npm package the skill lives in (e.g. `@tanstack/query-intent`) |
|
|
131
157
|
| Skill version | Frontmatter `metadata.version` or `library_version` |
|
|
132
158
|
| Task | Summarize the human's original request in one sentence |
|
|
159
|
+
| Skills Inventory | Which skills were loaded vs. available but not loaded (see below) |
|
|
133
160
|
| What Worked | List skill sections/patterns that were correct and useful |
|
|
134
|
-
| What Failed | From
|
|
135
|
-
| Missing | From
|
|
136
|
-
| Self-Corrections | From
|
|
161
|
+
| What Failed | From 1c — skill instructions that produced errors |
|
|
162
|
+
| Missing | From 1b — gaps where the skill was silent |
|
|
163
|
+
| Self-Corrections | From 1c fixes + 1d human interventions, combined |
|
|
137
164
|
| Rating | From Phase 2 sentiment analysis or explicit rating |
|
|
138
165
|
| User Comments | From Phase 2 answers, keep brief |
|
|
139
166
|
|
|
@@ -171,7 +198,7 @@ not contain project-specific details. Before submission:
|
|
|
171
198
|
Submit directly as a GitHub issue:
|
|
172
199
|
|
|
173
200
|
```bash
|
|
174
|
-
gh issue create --repo [owner/repo] --title "Skill Feedback: [skill-name] ([rating])" --label "
|
|
201
|
+
gh issue create --repo [owner/repo] --title "Skill Feedback: [skill-name] ([rating])" --label "skill:[skill-name]" --body-file intent-feedback.md
|
|
175
202
|
```
|
|
176
203
|
|
|
177
204
|
If the label doesn't exist, omit the `--label` flag — don't let a missing
|
|
@@ -79,6 +79,15 @@ skill-tree-generator for the full spec of each type.
|
|
|
79
79
|
|
|
80
80
|
---
|
|
81
81
|
|
|
82
|
+
### Subagent guidance for batch generation
|
|
83
|
+
|
|
84
|
+
When generating multiple skills, spawn a separate subagent for each skill
|
|
85
|
+
(or per-package group). Each subagent receives the domain_map.yaml,
|
|
86
|
+
skill_tree.yaml, and the source docs relevant to its skill. This prevents
|
|
87
|
+
context bleed between skills and allows parallel generation.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
82
91
|
## Step 2 — Extract content from sources
|
|
83
92
|
|
|
84
93
|
**Line budget:** Each SKILL.md must stay under 500 lines. Before writing,
|
|
@@ -319,6 +328,10 @@ Run every check before outputting. Fix any failures.
|
|
|
319
328
|
|
|
320
329
|
## Step 6 — Output
|
|
321
330
|
|
|
331
|
+
Before generating, ask the maintainer: "Would you like to review each skill
|
|
332
|
+
individually before I generate the next one, or should I generate all skills
|
|
333
|
+
and you review them together?" Respect their preference.
|
|
334
|
+
|
|
322
335
|
Output the complete SKILL.md file content. If reference files are needed,
|
|
323
336
|
output those as well with their relative paths.
|
|
324
337
|
|
|
@@ -381,48 +394,9 @@ Output is consumed by all major AI coding agents. To ensure consistency:
|
|
|
381
394
|
|
|
382
395
|
---
|
|
383
396
|
|
|
384
|
-
## Meta-skill feedback
|
|
385
|
-
|
|
386
|
-
After generating the first iteration of skills, complete a single Markdown
|
|
387
|
-
feedback draft for all three meta skills used in scaffolding. If a draft
|
|
388
|
-
exists from previous steps, keep it and fill the **Generate Skill** section.
|
|
389
|
-
If no draft exists, create it using this exact template.
|
|
390
|
-
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
# Intent Meta Skill Feedback
|
|
394
|
-
|
|
395
|
-
## Domain Discovery
|
|
396
|
-
|
|
397
|
-
- What worked well:
|
|
398
|
-
- What was confusing or missing:
|
|
399
|
-
- Suggestions for improvement:
|
|
400
|
-
- Overall rating: good | mixed | bad
|
|
401
|
-
|
|
402
|
-
## Tree Generator
|
|
403
|
-
|
|
404
|
-
- What worked well:
|
|
405
|
-
- What was confusing or missing:
|
|
406
|
-
- Suggestions for improvement:
|
|
407
|
-
- Overall rating: good | mixed | bad
|
|
408
|
-
|
|
409
|
-
## Generate Skill
|
|
410
|
-
|
|
411
|
-
- What worked well:
|
|
412
|
-
- What was confusing or missing:
|
|
413
|
-
- Suggestions for improvement:
|
|
414
|
-
- Overall rating: good | mixed | bad
|
|
415
|
-
|
|
416
|
-
## Context (optional)
|
|
417
|
-
|
|
418
|
-
- Library:
|
|
419
|
-
- Repo:
|
|
420
|
-
- Docs:
|
|
421
|
-
- Notes:
|
|
422
|
-
|
|
423
|
-
```
|
|
397
|
+
## Meta-skill feedback
|
|
424
398
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
399
|
+
After generating all skills, run the `skill-feedback-collection` skill to
|
|
400
|
+
capture feedback about the scaffolding process (domain-discovery,
|
|
401
|
+
tree-generator, and generate-skill).
|
|
428
402
|
```
|
|
@@ -274,14 +274,9 @@ packages/
|
|
|
274
274
|
│ └── package.json # Add "skills" to files array
|
|
275
275
|
```
|
|
276
276
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
```json
|
|
281
|
-
{
|
|
282
|
-
"files": ["dist", "src", "skills"]
|
|
283
|
-
}
|
|
284
|
-
```
|
|
277
|
+
Run `intent edit-package-json` to wire each package's `package.json`
|
|
278
|
+
automatically (adds `"skills"`, `"bin"`, and `"!skills/_artifacts"` to the
|
|
279
|
+
`files` array, and adds the `bin` entry if missing).
|
|
285
280
|
|
|
286
281
|
### Step 2 — Write the core skill
|
|
287
282
|
|
|
@@ -852,41 +847,3 @@ When updating:
|
|
|
852
847
|
3. CHANGELOG.md entry
|
|
853
848
|
|
|
854
849
|
---
|
|
855
|
-
|
|
856
|
-
## Meta-skill feedback (alpha default)
|
|
857
|
-
|
|
858
|
-
After producing the skill tree artifact, update a single Markdown feedback
|
|
859
|
-
draft for all three meta skills used in scaffolding. If a draft exists from
|
|
860
|
-
Domain Discovery, keep it and fill only the **Tree Generator** section. If
|
|
861
|
-
no draft exists, create it using this exact template.
|
|
862
|
-
|
|
863
|
-
```
|
|
864
|
-
# Intent Meta Skill Feedback
|
|
865
|
-
|
|
866
|
-
## Domain Discovery
|
|
867
|
-
- What worked well:
|
|
868
|
-
- What was confusing or missing:
|
|
869
|
-
- Suggestions for improvement:
|
|
870
|
-
- Overall rating: good | mixed | bad
|
|
871
|
-
|
|
872
|
-
## Tree Generator
|
|
873
|
-
- What worked well:
|
|
874
|
-
- What was confusing or missing:
|
|
875
|
-
- Suggestions for improvement:
|
|
876
|
-
- Overall rating: good | mixed | bad
|
|
877
|
-
|
|
878
|
-
## Generate Skill
|
|
879
|
-
- What worked well:
|
|
880
|
-
- What was confusing or missing:
|
|
881
|
-
- Suggestions for improvement:
|
|
882
|
-
- Overall rating: good | mixed | bad
|
|
883
|
-
|
|
884
|
-
## Context (optional)
|
|
885
|
-
- Library:
|
|
886
|
-
- Repo:
|
|
887
|
-
- Docs:
|
|
888
|
-
- Notes:
|
|
889
|
-
```
|
|
890
|
-
|
|
891
|
-
Do not submit feedback yet. Carry this draft forward to the generate-skill
|
|
892
|
-
step.
|
package/package.json
CHANGED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
//#region src/setup.d.ts
|
|
2
|
-
interface SetupResult {
|
|
3
|
-
workflows: string[];
|
|
4
|
-
skipped: string[];
|
|
5
|
-
shim: string | null;
|
|
6
|
-
}
|
|
7
|
-
declare function runSetup(root: string, metaDir: string, args: string[]): SetupResult;
|
|
8
|
-
//#endregion
|
|
9
|
-
export { runSetup as n, SetupResult as t };
|
package/dist/setup-DGvdyKEq.mjs
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
|
|
4
|
-
//#region src/setup.ts
|
|
5
|
-
function detectVars(root) {
|
|
6
|
-
const pkgPath = join(root, "package.json");
|
|
7
|
-
let pkgJson = {};
|
|
8
|
-
try {
|
|
9
|
-
pkgJson = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
10
|
-
} catch {}
|
|
11
|
-
const name = typeof pkgJson.name === "string" ? pkgJson.name : "unknown";
|
|
12
|
-
const intent = pkgJson.intent;
|
|
13
|
-
const repo = typeof intent?.repo === "string" ? intent.repo : name.replace(/^@/, "").replace(/\//, "/");
|
|
14
|
-
const docs = typeof intent?.docs === "string" ? intent.docs : "docs/";
|
|
15
|
-
let srcPath = `packages/${name.replace(/^@[^/]+\//, "")}/src/**`;
|
|
16
|
-
if (existsSync(join(root, "src"))) srcPath = "src/**";
|
|
17
|
-
return {
|
|
18
|
-
PACKAGE_NAME: name,
|
|
19
|
-
REPO: repo,
|
|
20
|
-
DOCS_PATH: docs.endsWith("**") ? docs : docs.replace(/\/$/, "") + "/**",
|
|
21
|
-
SRC_PATH: srcPath
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
function applyVars(content, vars) {
|
|
25
|
-
return content.replace(/\{\{PACKAGE_NAME\}\}/g, vars.PACKAGE_NAME).replace(/\{\{REPO\}\}/g, vars.REPO).replace(/\{\{DOCS_PATH\}\}/g, vars.DOCS_PATH).replace(/\{\{SRC_PATH\}\}/g, vars.SRC_PATH);
|
|
26
|
-
}
|
|
27
|
-
function copyTemplates(srcDir, destDir, vars) {
|
|
28
|
-
const copied = [];
|
|
29
|
-
const skipped = [];
|
|
30
|
-
if (!existsSync(srcDir)) return {
|
|
31
|
-
copied,
|
|
32
|
-
skipped
|
|
33
|
-
};
|
|
34
|
-
mkdirSync(destDir, { recursive: true });
|
|
35
|
-
for (const entry of readdirSync(srcDir)) {
|
|
36
|
-
const srcPath = join(srcDir, entry);
|
|
37
|
-
const destPath = join(destDir, entry);
|
|
38
|
-
if (existsSync(destPath)) {
|
|
39
|
-
skipped.push(destPath);
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
writeFileSync(destPath, applyVars(readFileSync(srcPath, "utf8"), vars));
|
|
43
|
-
copied.push(destPath);
|
|
44
|
-
}
|
|
45
|
-
return {
|
|
46
|
-
copied,
|
|
47
|
-
skipped
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
function getShimContent(ext) {
|
|
51
|
-
return `#!/usr/bin/env node
|
|
52
|
-
// Auto-generated by @tanstack/intent setup
|
|
53
|
-
// Exposes the intent end-user CLI for consumers of this library.
|
|
54
|
-
// Commit this file, then add to your package.json:
|
|
55
|
-
// "bin": { "intent": "./bin/intent.${ext}" }
|
|
56
|
-
await import('@tanstack/intent/intent-library')
|
|
57
|
-
`;
|
|
58
|
-
}
|
|
59
|
-
function detectShimExtension(root) {
|
|
60
|
-
try {
|
|
61
|
-
if (JSON.parse(readFileSync(join(root, "package.json"), "utf8")).type === "module") return "js";
|
|
62
|
-
} catch {}
|
|
63
|
-
return "mjs";
|
|
64
|
-
}
|
|
65
|
-
function findExistingShim(root) {
|
|
66
|
-
const shimJs = join(root, "bin", "intent.js");
|
|
67
|
-
if (existsSync(shimJs)) return shimJs;
|
|
68
|
-
const shimMjs = join(root, "bin", "intent.mjs");
|
|
69
|
-
if (existsSync(shimMjs)) return shimMjs;
|
|
70
|
-
return null;
|
|
71
|
-
}
|
|
72
|
-
function generateShim(root, result) {
|
|
73
|
-
const existingShim = findExistingShim(root);
|
|
74
|
-
if (existingShim) {
|
|
75
|
-
result.skipped.push(existingShim);
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
const ext = detectShimExtension(root);
|
|
79
|
-
const shimPath = join(root, "bin", `intent.${ext}`);
|
|
80
|
-
mkdirSync(join(root, "bin"), { recursive: true });
|
|
81
|
-
writeFileSync(shimPath, getShimContent(ext));
|
|
82
|
-
result.shim = shimPath;
|
|
83
|
-
}
|
|
84
|
-
function runSetup(root, metaDir, args) {
|
|
85
|
-
const doAll = args.includes("--all");
|
|
86
|
-
const doWorkflows = doAll || args.includes("--workflows");
|
|
87
|
-
const doShim = doAll || args.includes("--shim");
|
|
88
|
-
const noFlagsGiven = !doWorkflows && !doShim;
|
|
89
|
-
const installWorkflows = doWorkflows || noFlagsGiven;
|
|
90
|
-
const installShim = doShim || noFlagsGiven;
|
|
91
|
-
const vars = detectVars(root);
|
|
92
|
-
const result = {
|
|
93
|
-
workflows: [],
|
|
94
|
-
skipped: [],
|
|
95
|
-
shim: null
|
|
96
|
-
};
|
|
97
|
-
const templatesDir = join(metaDir, "templates");
|
|
98
|
-
if (installWorkflows) {
|
|
99
|
-
const { copied, skipped } = copyTemplates(join(templatesDir, "workflows"), join(root, ".github", "workflows"), vars);
|
|
100
|
-
result.workflows = copied;
|
|
101
|
-
result.skipped.push(...skipped);
|
|
102
|
-
}
|
|
103
|
-
if (installShim) generateShim(root, result);
|
|
104
|
-
for (const f of result.workflows) console.log(`✓ Copied workflow: ${f}`);
|
|
105
|
-
for (const f of result.skipped) console.log(` Already exists: ${f}`);
|
|
106
|
-
if (result.shim) {
|
|
107
|
-
const shimRelative = result.shim.replace(root + "/", "./");
|
|
108
|
-
console.log(`✓ Generated intent shim: ${result.shim}`);
|
|
109
|
-
console.log(`\n Add to your package.json:`);
|
|
110
|
-
console.log(` "bin": { "intent": "${shimRelative}" }`);
|
|
111
|
-
console.log(`\n Add "bin" to your package.json "files" array.`);
|
|
112
|
-
}
|
|
113
|
-
if (result.workflows.length === 0 && result.shim === null && result.skipped.length === 0) console.log("No templates directory found. Is @tanstack/intent installed?");
|
|
114
|
-
else if (result.workflows.length > 0) {
|
|
115
|
-
console.log(`\nTemplate variables applied:`);
|
|
116
|
-
console.log(` Package: ${vars.PACKAGE_NAME}`);
|
|
117
|
-
console.log(` Repo: ${vars.REPO}`);
|
|
118
|
-
console.log(` Docs: ${vars.DOCS_PATH}`);
|
|
119
|
-
console.log(` Src: ${vars.SRC_PATH}`);
|
|
120
|
-
}
|
|
121
|
-
return result;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
//#endregion
|
|
125
|
-
export { runSetup as t };
|