@tanstack/intent 0.0.5 → 0.0.7
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 +11 -12
- package/dist/cli.mjs +161 -135
- package/dist/display-D_XzuGnu.mjs +54 -0
- package/dist/index.d.mts +3 -17
- package/dist/index.mjs +248 -7
- package/dist/intent-library.mjs +7 -51
- package/dist/{library-scanner-BrznE00j.mjs → library-scanner-V9sTOhrb.mjs} +5 -2
- package/dist/library-scanner.d.mts +1 -1
- package/dist/library-scanner.mjs +2 -2
- package/dist/scanner-DkShtCWX.mjs +4 -0
- package/dist/{scanner-CpsJAHXT.mjs → scanner-OmHt14bs.mjs} +41 -8
- package/dist/{setup-N5dttGp_.d.mts → setup-BJ4giTKA.d.mts} +0 -1
- package/dist/{setup-CNGz26qL.mjs → setup-DGvdyKEq.mjs} +31 -22
- package/dist/setup.d.mts +1 -1
- package/dist/setup.mjs +1 -1
- package/dist/staleness-B5gUj7FR.mjs +4 -0
- package/dist/{staleness-CnomT9Hm.mjs → staleness-lP6B0O4z.mjs} +1 -1
- package/dist/{types-kbQfN_is.d.mts → types-BmnI8kFB.d.mts} +1 -1
- package/dist/{utils-DjkEPBxu.mjs → utils-DH3jY3CI.mjs} +1 -1
- package/meta/domain-discovery/SKILL.md +90 -7
- package/meta/feedback-collection/SKILL.md +73 -62
- package/meta/generate-skill/SKILL.md +9 -0
- package/meta/tree-generator/SKILL.md +16 -2
- package/package.json +1 -1
- package/dist/feedback-DKreHfB1.mjs +0 -300
- package/dist/feedback-FIUBOL0g.mjs +0 -3
- package/dist/init-DEzzXm9j.mjs +0 -3
- package/dist/init-DNxmjQfU.mjs +0 -70
- package/dist/scanner-BuWPDJ4P.mjs +0 -4
- package/dist/staleness-DyhsrqQ5.mjs +0 -4
package/README.md
CHANGED
|
@@ -16,10 +16,10 @@ pnpm add -D @tanstack/intent
|
|
|
16
16
|
|
|
17
17
|
### For library consumers
|
|
18
18
|
|
|
19
|
-
Set up
|
|
19
|
+
Set up skill-to-task mappings in your project's agent config files (CLAUDE.md, .cursorrules, etc.):
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
npx intent
|
|
22
|
+
npx intent install
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
List available skills from installed packages:
|
|
@@ -50,16 +50,15 @@ npx intent setup
|
|
|
50
50
|
|
|
51
51
|
## CLI Commands
|
|
52
52
|
|
|
53
|
-
| Command | Description
|
|
54
|
-
| ----------------------- |
|
|
55
|
-
| `intent
|
|
56
|
-
| `intent list [--json]` | Discover intent-enabled packages
|
|
57
|
-
| `intent meta` | List meta-skills for library maintainers
|
|
58
|
-
| `intent scaffold` | Print the guided skill generation prompt
|
|
59
|
-
| `intent validate [dir]` | Validate SKILL.md files
|
|
60
|
-
| `intent setup` | Copy CI
|
|
61
|
-
| `intent stale [--json]` | Check skills for version drift
|
|
62
|
-
| `intent feedback` | Submit skill feedback |
|
|
53
|
+
| Command | Description |
|
|
54
|
+
| ----------------------- | --------------------------------------------------- |
|
|
55
|
+
| `intent install` | Set up skill-to-task mappings in agent config files |
|
|
56
|
+
| `intent list [--json]` | Discover intent-enabled packages |
|
|
57
|
+
| `intent meta` | List meta-skills for library maintainers |
|
|
58
|
+
| `intent scaffold` | Print the guided skill generation prompt |
|
|
59
|
+
| `intent validate [dir]` | Validate SKILL.md files |
|
|
60
|
+
| `intent setup` | Copy CI templates, generate shim, create labels |
|
|
61
|
+
| `intent stale [--json]` | Check skills for version drift |
|
|
63
62
|
|
|
64
63
|
## License
|
|
65
64
|
|
package/dist/cli.mjs
CHANGED
|
@@ -1,66 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as parseFrontmatter, t as findSkillFiles } from "./utils-
|
|
3
|
-
import { t as scanForIntents } from "./scanner-
|
|
2
|
+
import { n as parseFrontmatter, t as findSkillFiles } from "./utils-DH3jY3CI.mjs";
|
|
3
|
+
import { t as scanForIntents } from "./scanner-OmHt14bs.mjs";
|
|
4
|
+
import { n as printSkillTree, r as printTable, t as computeSkillNameWidth } from "./display-D_XzuGnu.mjs";
|
|
4
5
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
5
6
|
import { dirname, join, relative, sep } from "node:path";
|
|
6
7
|
import { parse } from "yaml";
|
|
7
|
-
import { spawnSync } from "node:child_process";
|
|
8
|
-
import { release } from "node:os";
|
|
9
8
|
import { fileURLToPath } from "node:url";
|
|
10
9
|
|
|
11
10
|
//#region src/cli.ts
|
|
12
11
|
function getMetaDir() {
|
|
13
12
|
return join(dirname(fileURLToPath(import.meta.url)), "..", "meta");
|
|
14
13
|
}
|
|
15
|
-
function padColumn(text, width) {
|
|
16
|
-
return text.length >= width ? text + " " : text.padEnd(width);
|
|
17
|
-
}
|
|
18
|
-
function printTable(headers, rows) {
|
|
19
|
-
const widths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => (r[i] ?? "").length)) + 2);
|
|
20
|
-
const headerLine = headers.map((h, i) => padColumn(h, widths[i])).join("");
|
|
21
|
-
const separator = widths.map((w) => "─".repeat(w)).join("");
|
|
22
|
-
console.log(headerLine);
|
|
23
|
-
console.log(separator);
|
|
24
|
-
for (const row of rows) console.log(row.map((cell, i) => padColumn(cell, widths[i])).join(""));
|
|
25
|
-
}
|
|
26
|
-
function printSkillTree(skills, opts) {
|
|
27
|
-
const roots = [];
|
|
28
|
-
const children = /* @__PURE__ */ new Map();
|
|
29
|
-
for (const skill of skills) {
|
|
30
|
-
const slashIdx = skill.name.indexOf("/");
|
|
31
|
-
if (slashIdx === -1) roots.push(skill.name);
|
|
32
|
-
else {
|
|
33
|
-
const parent = skill.name.slice(0, slashIdx);
|
|
34
|
-
if (!children.has(parent)) children.set(parent, []);
|
|
35
|
-
children.get(parent).push(skill);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
if (roots.length === 0) {
|
|
39
|
-
for (const skill of skills) if (!roots.includes(skill.name)) roots.push(skill.name);
|
|
40
|
-
}
|
|
41
|
-
for (const rootName of roots) {
|
|
42
|
-
const rootSkill = skills.find((s) => s.name === rootName);
|
|
43
|
-
if (!rootSkill) continue;
|
|
44
|
-
printSkillLine(rootName, rootSkill, 4, opts);
|
|
45
|
-
for (const sub of children.get(rootName) ?? []) printSkillLine(sub.name.slice(sub.name.indexOf("/") + 1), sub, 6, opts);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
function printSkillLine(displayName, skill, indent, opts) {
|
|
49
|
-
const nameStr = " ".repeat(indent) + displayName;
|
|
50
|
-
const padding = " ".repeat(Math.max(2, opts.nameWidth - nameStr.length));
|
|
51
|
-
const typeCol = opts.showTypes ? (skill.type ? `[${skill.type}]` : "").padEnd(14) : "";
|
|
52
|
-
console.log(`${nameStr}${padding}${typeCol}${skill.description}`);
|
|
53
|
-
}
|
|
54
|
-
function computeSkillNameWidth(allPackageSkills) {
|
|
55
|
-
let max = 0;
|
|
56
|
-
for (const skills of allPackageSkills) for (const s of skills) {
|
|
57
|
-
const slashIdx = s.name.indexOf("/");
|
|
58
|
-
const displayName = slashIdx === -1 ? s.name : s.name.slice(slashIdx + 1);
|
|
59
|
-
const indent = slashIdx === -1 ? 4 : 6;
|
|
60
|
-
max = Math.max(max, indent + displayName.length);
|
|
61
|
-
}
|
|
62
|
-
return max + 2;
|
|
63
|
-
}
|
|
64
14
|
async function cmdList(args) {
|
|
65
15
|
const jsonOutput = args.includes("--json");
|
|
66
16
|
let result;
|
|
@@ -106,6 +56,10 @@ async function cmdList(args) {
|
|
|
106
56
|
});
|
|
107
57
|
console.log();
|
|
108
58
|
}
|
|
59
|
+
console.log(`Feedback:`);
|
|
60
|
+
console.log(` After completing your task, collect feedback on skill usage.`);
|
|
61
|
+
console.log(` Load: node_modules/@tanstack/intent/meta/feedback-collection/SKILL.md`);
|
|
62
|
+
console.log();
|
|
109
63
|
if (result.warnings.length > 0) {
|
|
110
64
|
console.log(`Warnings:`);
|
|
111
65
|
for (const w of result.warnings) console.log(` ⚠ ${w}`);
|
|
@@ -133,6 +87,29 @@ function cmdMeta() {
|
|
|
133
87
|
console.log(`\nUsage: load the SKILL.md into your AI agent conversation.`);
|
|
134
88
|
console.log(`Path: node_modules/@tanstack/intent/meta/<name>/SKILL.md`);
|
|
135
89
|
}
|
|
90
|
+
function collectPackagingWarnings(root) {
|
|
91
|
+
const pkgJsonPath = join(root, "package.json");
|
|
92
|
+
if (!existsSync(pkgJsonPath)) return [];
|
|
93
|
+
let pkgJson;
|
|
94
|
+
try {
|
|
95
|
+
pkgJson = JSON.parse(readFileSync(pkgJsonPath, "utf8"));
|
|
96
|
+
} catch (err) {
|
|
97
|
+
return [`Could not parse package.json: ${err instanceof Error ? err.message : String(err)}`];
|
|
98
|
+
}
|
|
99
|
+
const warnings = [];
|
|
100
|
+
if (!pkgJson.devDependencies?.["@tanstack/intent"]) warnings.push("@tanstack/intent is not in devDependencies");
|
|
101
|
+
if (!pkgJson.bin?.intent) warnings.push("Missing \"bin\": { \"intent\": ... } entry in package.json");
|
|
102
|
+
const shimJs = join(root, "bin", "intent.js");
|
|
103
|
+
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 setup --shim)");
|
|
105
|
+
const files = pkgJson.files;
|
|
106
|
+
if (Array.isArray(files)) {
|
|
107
|
+
if (!files.includes("skills")) warnings.push("\"skills\" is not in the \"files\" array — skills won't be published");
|
|
108
|
+
if (!files.includes("bin")) warnings.push("\"bin\" is not in the \"files\" array — shim won't be published");
|
|
109
|
+
if (!files.includes("!skills/_artifacts")) warnings.push("\"!skills/_artifacts\" is not in the \"files\" array — artifacts will be published unnecessarily");
|
|
110
|
+
}
|
|
111
|
+
return warnings;
|
|
112
|
+
}
|
|
136
113
|
function cmdValidate(args) {
|
|
137
114
|
const targetDir = args[0] ?? "skills";
|
|
138
115
|
const skillsDir = join(process.cwd(), targetDir);
|
|
@@ -189,6 +166,10 @@ function cmdValidate(args) {
|
|
|
189
166
|
message: `name "${fm.name}" does not match directory path "${expectedPath}"`
|
|
190
167
|
});
|
|
191
168
|
}
|
|
169
|
+
if (typeof fm.description === "string" && fm.description.length > 1024) errors.push({
|
|
170
|
+
file: rel,
|
|
171
|
+
message: `Description exceeds 1024 character limit (${fm.description.length} chars)`
|
|
172
|
+
});
|
|
192
173
|
if (fm.type === "framework" && !Array.isArray(fm.requires)) errors.push({
|
|
193
174
|
file: rel,
|
|
194
175
|
message: "Framework skills must have a \"requires\" field"
|
|
@@ -196,7 +177,7 @@ function cmdValidate(args) {
|
|
|
196
177
|
const lineCount = content.split(/\r?\n/).length;
|
|
197
178
|
if (lineCount > 500) errors.push({
|
|
198
179
|
file: rel,
|
|
199
|
-
message: `Exceeds 500 line limit (${lineCount} lines)
|
|
180
|
+
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
181
|
});
|
|
201
182
|
}
|
|
202
183
|
const artifactsDir = join(skillsDir, "_artifacts");
|
|
@@ -230,70 +211,90 @@ function cmdValidate(args) {
|
|
|
230
211
|
});
|
|
231
212
|
}
|
|
232
213
|
}
|
|
214
|
+
const warnings = collectPackagingWarnings(process.cwd());
|
|
215
|
+
const printWarnings = (log) => {
|
|
216
|
+
if (warnings.length === 0) return;
|
|
217
|
+
log(`\n⚠ Packaging warnings:`);
|
|
218
|
+
for (const w of warnings) log(` ${w}`);
|
|
219
|
+
};
|
|
233
220
|
if (errors.length > 0) {
|
|
234
221
|
console.error(`\n❌ Validation failed with ${errors.length} error(s):\n`);
|
|
235
222
|
for (const { file, message } of errors) console.error(` ${file}: ${message}`);
|
|
223
|
+
printWarnings(console.error);
|
|
236
224
|
process.exit(1);
|
|
237
225
|
}
|
|
238
226
|
console.log(`✅ Validated ${skillFiles.length} skill files — all passed`);
|
|
227
|
+
printWarnings(console.log);
|
|
239
228
|
}
|
|
240
229
|
function cmdScaffold() {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
-
|
|
261
|
-
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
230
|
+
const metaDir = getMetaDir();
|
|
231
|
+
const metaSkillPath = (name) => join(metaDir, name, "SKILL.md");
|
|
232
|
+
const prompt = `You are helping a library maintainer scaffold Intent skills.
|
|
233
|
+
|
|
234
|
+
Run the three meta skills below **one at a time, in order**. For each step:
|
|
235
|
+
1. Load the SKILL.md file specified
|
|
236
|
+
2. Follow its instructions completely
|
|
237
|
+
3. Present outputs to the maintainer for review
|
|
238
|
+
4. Do NOT proceed to the next step until the maintainer confirms
|
|
239
|
+
|
|
240
|
+
## Before you start
|
|
241
|
+
|
|
242
|
+
Gather this context yourself (do not ask the maintainer — agents should never
|
|
243
|
+
ask for information they can discover):
|
|
244
|
+
1. Read package.json for library name, repository URL, and homepage/docs URL
|
|
245
|
+
2. Detect if this is a monorepo (look for workspaces field, packages/ directory, lerna.json)
|
|
246
|
+
3. Use skills/ as the default skills root
|
|
247
|
+
4. For monorepos:
|
|
248
|
+
- Domain map artifacts go at the REPO ROOT: _artifacts/
|
|
249
|
+
- Skills go INSIDE EACH PACKAGE: packages/<pkg>/skills/
|
|
250
|
+
- Identify which packages are client-facing (usually client SDKs and primary framework adapters)
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Step 1 — Domain Discovery
|
|
255
|
+
|
|
256
|
+
Load and follow: ${metaSkillPath("domain-discovery")}
|
|
257
|
+
|
|
258
|
+
This produces: domain_map.yaml and skill_spec.md in the artifacts directory.
|
|
259
|
+
Domain discovery covers the WHOLE library (one domain map even for monorepos).
|
|
260
|
+
|
|
261
|
+
**STOP. Review outputs with the maintainer before continuing.**
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Step 2 — Tree Generator
|
|
266
|
+
|
|
267
|
+
Load and follow: ${metaSkillPath("tree-generator")}
|
|
268
|
+
|
|
269
|
+
This produces: skill_tree.yaml in the artifacts directory.
|
|
270
|
+
For monorepos, each skill entry should include a \`package\` field.
|
|
271
|
+
|
|
272
|
+
**STOP. Review outputs with the maintainer before continuing.**
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## Step 3 — Generate Skills
|
|
277
|
+
|
|
278
|
+
Load and follow: ${metaSkillPath("generate-skill")}
|
|
279
|
+
|
|
280
|
+
This produces: individual SKILL.md files.
|
|
281
|
+
- Single-repo: skills/<domain>/<skill>/SKILL.md
|
|
282
|
+
- Monorepo: packages/<pkg>/skills/<domain>/<skill>/SKILL.md
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## After all skills are generated
|
|
287
|
+
|
|
288
|
+
1. Run \`npx @tanstack/intent validate\` in each package directory
|
|
289
|
+
2. Commit skills/ and artifacts
|
|
290
|
+
3. For each publishable package, run: \`npx @tanstack/intent setup --shim\`
|
|
291
|
+
4. Ensure each package has \`@tanstack/intent\` as a devDependency
|
|
292
|
+
5. Add \`"skills"\`, \`"bin"\` to the \`"files"\` array in each package.json
|
|
293
|
+
6. Add \`"!skills/_artifacts"\` to exclude artifacts from publishing
|
|
294
|
+
7. Create a \`feedback:<skill-name>\` label on the GitHub repo for each skill (use \`gh label create\`)
|
|
295
|
+
8. Add a README note: "If you use an AI agent, run \`npx @tanstack/intent install\`"
|
|
291
296
|
`;
|
|
292
|
-
console.log("🚀 Intent Scaffold Prompt");
|
|
293
|
-
console.log("✨ Copy the prompt below into your AI agent:\n");
|
|
294
297
|
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");
|
|
297
298
|
}
|
|
298
299
|
const USAGE = `TanStack Intent CLI
|
|
299
300
|
|
|
@@ -301,12 +302,10 @@ Usage:
|
|
|
301
302
|
intent list [--json] Discover intent-enabled packages
|
|
302
303
|
intent meta List meta-skills for maintainers
|
|
303
304
|
intent validate [<dir>] Validate skill files (default: skills/)
|
|
304
|
-
intent
|
|
305
|
+
intent install Print a skill that guides your coding agent to set up skill-to-task mappings
|
|
305
306
|
intent scaffold Print maintainer scaffold prompt
|
|
306
|
-
intent setup [--workflows] [--
|
|
307
|
-
intent stale Check skills for staleness
|
|
308
|
-
intent feedback --submit --file <path> Submit skill feedback
|
|
309
|
-
intent feedback --meta --submit --file <path> Submit meta-skill feedback`;
|
|
307
|
+
intent setup [--workflows] [--shim] [--all] Copy CI templates and generate shim
|
|
308
|
+
intent stale Check skills for staleness`;
|
|
310
309
|
const command = process.argv[2];
|
|
311
310
|
const commandArgs = process.argv.slice(3);
|
|
312
311
|
switch (command) {
|
|
@@ -319,28 +318,60 @@ switch (command) {
|
|
|
319
318
|
case "validate":
|
|
320
319
|
cmdValidate(commandArgs);
|
|
321
320
|
break;
|
|
322
|
-
case "
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
321
|
+
case "install":
|
|
322
|
+
console.log(`You are an AI assistant helping a developer set up skill-to-task mappings for their project.
|
|
323
|
+
|
|
324
|
+
Follow these steps in order:
|
|
325
|
+
|
|
326
|
+
1. CHECK FOR EXISTING MAPPINGS
|
|
327
|
+
Search the project's agent config files (CLAUDE.md, AGENTS.md, .cursorrules,
|
|
328
|
+
.github/copilot-instructions.md) for a block delimited by:
|
|
329
|
+
<!-- intent-skills:start -->
|
|
330
|
+
<!-- intent-skills:end -->
|
|
331
|
+
- If found: show the user the current mappings and ask "What would you like to update?"
|
|
332
|
+
Then skip to step 4 with their requested changes.
|
|
333
|
+
- If not found: continue to step 2.
|
|
334
|
+
|
|
335
|
+
2. DISCOVER AVAILABLE SKILLS
|
|
336
|
+
Run: intent list
|
|
337
|
+
This outputs each skill's name, description, and full path — grouped by package.
|
|
338
|
+
|
|
339
|
+
3. SCAN THE REPOSITORY
|
|
340
|
+
Build a picture of the project's structure and patterns:
|
|
341
|
+
- Read package.json for library dependencies
|
|
342
|
+
- Survey the directory layout (src/, app/, routes/, components/, api/, etc.)
|
|
343
|
+
- Note recurring patterns (routing, data fetching, auth, UI components, etc.)
|
|
344
|
+
|
|
345
|
+
Based on this, propose 3–5 skill-to-task mappings. For each one explain:
|
|
346
|
+
- The task or code area (in plain language the user would recognise)
|
|
347
|
+
- Which skill applies and why
|
|
348
|
+
|
|
349
|
+
Then ask: "What other tasks do you commonly use AI coding agents for?
|
|
350
|
+
I'll create mappings for those too."
|
|
351
|
+
|
|
352
|
+
4. WRITE THE MAPPINGS BLOCK
|
|
353
|
+
Once you have the full set of mappings, write or update the agent config file
|
|
354
|
+
(prefer CLAUDE.md; create it if none exists) with this exact block:
|
|
355
|
+
|
|
356
|
+
<!-- intent-skills:start -->
|
|
357
|
+
# Skill mappings — when working in these areas, load the linked skill file into context.
|
|
358
|
+
skills:
|
|
359
|
+
- task: "describe the task or code area here"
|
|
360
|
+
load: "node_modules/package-name/skills/skill-name/SKILL.md"
|
|
361
|
+
<!-- intent-skills:end -->
|
|
362
|
+
|
|
363
|
+
Rules:
|
|
364
|
+
- Use the user's own words for task descriptions
|
|
365
|
+
- Include the exact path from \`intent list\` output so agents can load it directly
|
|
366
|
+
- Keep entries concise — this block is read on every agent task
|
|
367
|
+
- Preserve all content outside the block tags unchanged`);
|
|
336
368
|
break;
|
|
337
|
-
}
|
|
338
369
|
case "scaffold":
|
|
339
370
|
cmdScaffold();
|
|
340
371
|
break;
|
|
341
372
|
case "stale": {
|
|
342
|
-
const { checkStaleness } = await import("./staleness-
|
|
343
|
-
const { scanForIntents: scanStale } = await import("./scanner-
|
|
373
|
+
const { checkStaleness } = await import("./staleness-B5gUj7FR.mjs");
|
|
374
|
+
const { scanForIntents: scanStale } = await import("./scanner-DkShtCWX.mjs");
|
|
344
375
|
let staleResult;
|
|
345
376
|
try {
|
|
346
377
|
staleResult = await scanStale();
|
|
@@ -371,11 +402,6 @@ switch (command) {
|
|
|
371
402
|
}
|
|
372
403
|
break;
|
|
373
404
|
}
|
|
374
|
-
case "feedback": {
|
|
375
|
-
const { runFeedback } = await import("./feedback-FIUBOL0g.mjs");
|
|
376
|
-
runFeedback(commandArgs);
|
|
377
|
-
break;
|
|
378
|
-
}
|
|
379
405
|
case "setup": {
|
|
380
406
|
const { runSetup } = await import("./setup.mjs");
|
|
381
407
|
runSetup(process.cwd(), getMetaDir(), commandArgs);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
//#region src/display.ts
|
|
2
|
+
function padColumn(text, width) {
|
|
3
|
+
return text.length >= width ? text + " " : text.padEnd(width);
|
|
4
|
+
}
|
|
5
|
+
function printTable(headers, rows) {
|
|
6
|
+
const widths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => (r[i] ?? "").length)) + 2);
|
|
7
|
+
const headerLine = headers.map((h, i) => padColumn(h, widths[i])).join("");
|
|
8
|
+
const separator = widths.map((w) => "─".repeat(w)).join("");
|
|
9
|
+
console.log(headerLine);
|
|
10
|
+
console.log(separator);
|
|
11
|
+
for (const row of rows) console.log(row.map((cell, i) => padColumn(cell, widths[i])).join(""));
|
|
12
|
+
}
|
|
13
|
+
function printSkillLine(displayName, skill, indent, opts) {
|
|
14
|
+
const nameStr = " ".repeat(indent) + displayName;
|
|
15
|
+
const padding = " ".repeat(Math.max(2, opts.nameWidth - nameStr.length));
|
|
16
|
+
const typeCol = opts.showTypes ? (skill.type ? `[${skill.type}]` : "").padEnd(14) : "";
|
|
17
|
+
console.log(`${nameStr}${padding}${typeCol}${skill.description}`);
|
|
18
|
+
if (skill.path) console.log(`${" ".repeat(indent + 2)}${skill.path}`);
|
|
19
|
+
}
|
|
20
|
+
function printSkillTree(skills, opts) {
|
|
21
|
+
const roots = [];
|
|
22
|
+
const children = /* @__PURE__ */ new Map();
|
|
23
|
+
for (const skill of skills) {
|
|
24
|
+
const slashIdx = skill.name.indexOf("/");
|
|
25
|
+
if (slashIdx === -1) roots.push(skill.name);
|
|
26
|
+
else {
|
|
27
|
+
const parent = skill.name.slice(0, slashIdx);
|
|
28
|
+
if (!children.has(parent)) children.set(parent, []);
|
|
29
|
+
children.get(parent).push(skill);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (roots.length === 0) {
|
|
33
|
+
for (const skill of skills) if (!roots.includes(skill.name)) roots.push(skill.name);
|
|
34
|
+
}
|
|
35
|
+
for (const rootName of roots) {
|
|
36
|
+
const rootSkill = skills.find((s) => s.name === rootName);
|
|
37
|
+
if (!rootSkill) continue;
|
|
38
|
+
printSkillLine(rootName, rootSkill, 4, opts);
|
|
39
|
+
for (const sub of children.get(rootName) ?? []) printSkillLine(sub.name.slice(sub.name.indexOf("/") + 1), sub, 6, opts);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function computeSkillNameWidth(allPackageSkills) {
|
|
43
|
+
let max = 0;
|
|
44
|
+
for (const skills of allPackageSkills) for (const s of skills) {
|
|
45
|
+
const slashIdx = s.name.indexOf("/");
|
|
46
|
+
const displayName = slashIdx === -1 ? s.name : s.name.slice(slashIdx + 1);
|
|
47
|
+
const indent = slashIdx === -1 ? 4 : 6;
|
|
48
|
+
max = Math.max(max, indent + displayName.length);
|
|
49
|
+
}
|
|
50
|
+
return max + 2;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
//#endregion
|
|
54
|
+
export { printSkillTree as n, printTable as r, computeSkillNameWidth as t };
|
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-BmnI8kFB.mjs";
|
|
2
|
+
import { n as runSetup } from "./setup-BJ4giTKA.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/scanner.d.ts
|
|
5
5
|
declare function scanForIntents(root?: string): Promise<ScanResult>;
|
|
@@ -34,20 +34,6 @@ declare function submitMetaFeedback(payload: MetaFeedbackPayload, opts: {
|
|
|
34
34
|
outputPath?: string;
|
|
35
35
|
}): SubmitResult;
|
|
36
36
|
//#endregion
|
|
37
|
-
//#region src/init.d.ts
|
|
38
|
-
declare function detectAgentConfigs(root: string): string[];
|
|
39
|
-
declare function hasIntentBlock(filePath: string): boolean;
|
|
40
|
-
declare function injectIntentBlock(filePath: string): boolean;
|
|
41
|
-
declare function writeProjectConfig(root: string): string;
|
|
42
|
-
declare function readProjectConfig(root: string): IntentProjectConfig | null;
|
|
43
|
-
interface InitResult {
|
|
44
|
-
injected: string[];
|
|
45
|
-
skipped: string[];
|
|
46
|
-
created: string[];
|
|
47
|
-
configPath: string;
|
|
48
|
-
}
|
|
49
|
-
declare function runInit(root: string): InitResult;
|
|
50
|
-
//#endregion
|
|
51
37
|
//#region src/utils.d.ts
|
|
52
38
|
/**
|
|
53
39
|
* Recursively find all SKILL.md files under a directory.
|
|
@@ -58,4 +44,4 @@ declare function findSkillFiles(dir: string): string[];
|
|
|
58
44
|
*/
|
|
59
45
|
declare function parseFrontmatter(filePath: string): Record<string, unknown> | null;
|
|
60
46
|
//#endregion
|
|
61
|
-
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,
|
|
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, runSetup, scanForIntents, submitFeedback, submitMetaFeedback, toMarkdown, validateMetaPayload, validatePayload };
|