@tanstack/intent 0.0.13 → 0.0.19
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 +58 -21
- package/dist/cli.d.mts +6 -1
- package/dist/cli.mjs +250 -171
- package/dist/display-CuCDLPP_.mjs +3 -0
- package/dist/index.d.mts +18 -6
- package/dist/index.mjs +38 -15
- package/dist/install-prompt-C0M-U3WZ.mjs +59 -0
- package/dist/intent-library.mjs +5 -49
- package/dist/{library-scanner-V9sTOhrb.mjs → library-scanner-CU0OozQE.mjs} +4 -12
- package/dist/library-scanner.d.mts +4 -4
- package/dist/library-scanner.mjs +2 -2
- package/dist/scanner-B1UvuEBQ.mjs +4 -0
- package/dist/scanner-f82qRq7h.mjs +338 -0
- package/dist/setup-6m3IfxyO.d.mts +30 -0
- package/dist/setup-CncHbQlb.mjs +360 -0
- package/dist/setup.d.mts +2 -2
- package/dist/setup.mjs +3 -2
- package/dist/staleness-CWWuoPop.mjs +4 -0
- package/dist/{staleness-lP6B0O4z.mjs → staleness-D_ZiK4Tf.mjs} +24 -3
- package/dist/{types-BmnI8kFB.d.mts → types-ddLtccfV.d.mts} +30 -7
- package/dist/utils-DY1eH2E_.mjs +157 -0
- package/dist/utils-XSyO19J6.mjs +3 -0
- package/meta/domain-discovery/SKILL.md +95 -20
- package/meta/feedback-collection/SKILL.md +20 -1
- package/meta/generate-skill/SKILL.md +56 -5
- package/meta/templates/workflows/check-skills.yml +4 -4
- package/meta/templates/workflows/{notify-playbooks.yml → notify-intent.yml} +4 -4
- package/meta/tree-generator/SKILL.md +2 -2
- package/package.json +4 -3
- package/dist/scanner-DQeiZRzp.mjs +0 -4
- package/dist/scanner-dIYdkHQ1.mjs +0 -180
- package/dist/setup-BYOg-Ii-.mjs +0 -197
- package/dist/setup-CANkTz55.d.mts +0 -18
- package/dist/staleness-B5gUj7FR.mjs +0 -4
- package/dist/utils-DH3jY3CI.mjs +0 -39
- /package/dist/{display-D_XzuGnu.mjs → display-DhsUxNJW.mjs} +0 -0
package/dist/cli.mjs
CHANGED
|
@@ -1,39 +1,88 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { t as scanForIntents } from "./scanner-dIYdkHQ1.mjs";
|
|
4
|
-
import { n as printSkillTree, r as printTable, t as computeSkillNameWidth } from "./display-D_XzuGnu.mjs";
|
|
2
|
+
import { t as INSTALL_PROMPT } from "./install-prompt-C0M-U3WZ.mjs";
|
|
5
3
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
6
4
|
import { dirname, join, relative, sep } from "node:path";
|
|
7
|
-
import {
|
|
8
|
-
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
9
6
|
|
|
10
7
|
//#region src/cli.ts
|
|
11
8
|
function getMetaDir() {
|
|
12
9
|
return join(dirname(fileURLToPath(import.meta.url)), "..", "meta");
|
|
13
10
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
function fail(message, exitCode = 1) {
|
|
12
|
+
throw {
|
|
13
|
+
message,
|
|
14
|
+
exitCode
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function isCliFailure(value) {
|
|
18
|
+
return !!value && typeof value === "object" && "message" in value && typeof value.message === "string" && "exitCode" in value && typeof value.exitCode === "number";
|
|
19
|
+
}
|
|
20
|
+
async function scanIntentsOrFail() {
|
|
21
|
+
const { scanForIntents } = await import("./scanner-B1UvuEBQ.mjs");
|
|
17
22
|
try {
|
|
18
|
-
|
|
23
|
+
return await scanForIntents();
|
|
19
24
|
} catch (err) {
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
fail(err.message);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function printWarnings(warnings) {
|
|
29
|
+
if (warnings.length === 0) return;
|
|
30
|
+
console.log("Warnings:");
|
|
31
|
+
for (const warning of warnings) console.log(` ⚠ ${warning}`);
|
|
32
|
+
}
|
|
33
|
+
function formatScanCoverage(result) {
|
|
34
|
+
const coverage = [];
|
|
35
|
+
if (result.nodeModules.local.scanned) coverage.push("project node_modules");
|
|
36
|
+
if (result.nodeModules.global.scanned) coverage.push("global node_modules");
|
|
37
|
+
return coverage.join(", ");
|
|
38
|
+
}
|
|
39
|
+
function printVersionConflicts(result) {
|
|
40
|
+
if (result.conflicts.length === 0) return;
|
|
41
|
+
console.log("\nVersion conflicts:\n");
|
|
42
|
+
for (const conflict of result.conflicts) {
|
|
43
|
+
console.log(` ${conflict.packageName} -> using ${conflict.chosen.version}`);
|
|
44
|
+
console.log(` chosen: ${conflict.chosen.packageRoot}`);
|
|
45
|
+
for (const variant of conflict.variants) {
|
|
46
|
+
if (variant.packageRoot === conflict.chosen.packageRoot) continue;
|
|
47
|
+
console.log(` also found: ${variant.version} at ${variant.packageRoot}`);
|
|
48
|
+
}
|
|
49
|
+
console.log();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function buildValidationFailure(errors, warnings) {
|
|
53
|
+
const lines = [
|
|
54
|
+
"",
|
|
55
|
+
`❌ Validation failed with ${errors.length} error(s):`,
|
|
56
|
+
""
|
|
57
|
+
];
|
|
58
|
+
for (const { file, message } of errors) lines.push(` ${file}: ${message}`);
|
|
59
|
+
if (warnings.length > 0) {
|
|
60
|
+
lines.push("", "⚠ Packaging warnings:");
|
|
61
|
+
for (const warning of warnings) lines.push(` ${warning}`);
|
|
22
62
|
}
|
|
63
|
+
return lines.join("\n");
|
|
64
|
+
}
|
|
65
|
+
async function cmdList(args) {
|
|
66
|
+
const { computeSkillNameWidth, printSkillTree, printTable } = await import("./display-CuCDLPP_.mjs");
|
|
67
|
+
const jsonOutput = args.includes("--json");
|
|
68
|
+
const result = await scanIntentsOrFail();
|
|
23
69
|
if (jsonOutput) {
|
|
24
70
|
console.log(JSON.stringify(result, null, 2));
|
|
25
71
|
return;
|
|
26
72
|
}
|
|
73
|
+
const scanCoverage = formatScanCoverage(result);
|
|
27
74
|
if (result.packages.length === 0) {
|
|
28
75
|
console.log("No intent-enabled packages found.");
|
|
76
|
+
if (scanCoverage) console.log(`Scanned: ${scanCoverage}`);
|
|
29
77
|
if (result.warnings.length > 0) {
|
|
30
|
-
console.log(
|
|
31
|
-
|
|
78
|
+
console.log();
|
|
79
|
+
printWarnings(result.warnings);
|
|
32
80
|
}
|
|
33
81
|
return;
|
|
34
82
|
}
|
|
35
83
|
const totalSkills = result.packages.reduce((sum, p) => sum + p.skills.length, 0);
|
|
36
84
|
console.log(`\n${result.packages.length} intent-enabled packages, ${totalSkills} skills (${result.packageManager})\n`);
|
|
85
|
+
if (scanCoverage) console.log(`Scanned: ${scanCoverage}${result.nodeModules.global.scanned ? " (local packages take precedence)" : ""}\n`);
|
|
37
86
|
printTable([
|
|
38
87
|
"PACKAGE",
|
|
39
88
|
"VERSION",
|
|
@@ -45,6 +94,7 @@ async function cmdList(args) {
|
|
|
45
94
|
String(pkg.skills.length),
|
|
46
95
|
pkg.intent.requires?.join(", ") || "–"
|
|
47
96
|
]));
|
|
97
|
+
printVersionConflicts(result);
|
|
48
98
|
const nameWidth = computeSkillNameWidth(result.packages.map((p) => p.skills));
|
|
49
99
|
const showTypes = result.packages.some((p) => p.skills.some((s) => s.type));
|
|
50
100
|
console.log(`\nSkills:\n`);
|
|
@@ -60,35 +110,21 @@ async function cmdList(args) {
|
|
|
60
110
|
console.log(` Submit feedback on skill usage to help maintainers improve the skills.`);
|
|
61
111
|
console.log(` Load: node_modules/@tanstack/intent/meta/feedback-collection/SKILL.md`);
|
|
62
112
|
console.log();
|
|
63
|
-
|
|
64
|
-
console.log(`Warnings:`);
|
|
65
|
-
for (const w of result.warnings) console.log(` ⚠ ${w}`);
|
|
66
|
-
}
|
|
113
|
+
printWarnings(result.warnings);
|
|
67
114
|
}
|
|
68
|
-
function cmdMeta(args) {
|
|
115
|
+
async function cmdMeta(args) {
|
|
116
|
+
const { parseFrontmatter } = await import("./utils-XSyO19J6.mjs");
|
|
69
117
|
const metaDir = getMetaDir();
|
|
70
|
-
if (!existsSync(metaDir))
|
|
71
|
-
console.error("Meta-skills directory not found.");
|
|
72
|
-
process.exit(1);
|
|
73
|
-
}
|
|
118
|
+
if (!existsSync(metaDir)) fail("Meta-skills directory not found.");
|
|
74
119
|
if (args.length > 0) {
|
|
75
120
|
const name = args[0];
|
|
76
|
-
if (name.includes("..") || name.includes("/") || name.includes("\\")) {
|
|
77
|
-
console.error(`Invalid meta-skill name: "${name}"`);
|
|
78
|
-
process.exit(1);
|
|
79
|
-
}
|
|
121
|
+
if (name.includes("..") || name.includes("/") || name.includes("\\")) fail(`Invalid meta-skill name: "${name}"`);
|
|
80
122
|
const skillFile = join(metaDir, name, "SKILL.md");
|
|
81
|
-
if (!existsSync(skillFile)) {
|
|
82
|
-
console.error(`Meta-skill "${name}" not found.`);
|
|
83
|
-
console.error(`Run \`npx @tanstack/intent meta\` to list available meta-skills.`);
|
|
84
|
-
process.exit(1);
|
|
85
|
-
}
|
|
123
|
+
if (!existsSync(skillFile)) fail(`Meta-skill "${name}" not found. Run \`intent meta\` to list available meta-skills.`);
|
|
86
124
|
try {
|
|
87
125
|
console.log(readFileSync(skillFile, "utf8"));
|
|
88
126
|
} catch (err) {
|
|
89
|
-
|
|
90
|
-
console.error(`Failed to read meta-skill "${name}": ${msg}`);
|
|
91
|
-
process.exit(1);
|
|
127
|
+
fail(`Failed to read meta-skill "${name}": ${err instanceof Error ? err.message : String(err)}`);
|
|
92
128
|
}
|
|
93
129
|
return;
|
|
94
130
|
}
|
|
@@ -131,19 +167,45 @@ function collectPackagingWarnings(root) {
|
|
|
131
167
|
}
|
|
132
168
|
return warnings;
|
|
133
169
|
}
|
|
134
|
-
function
|
|
170
|
+
function resolvePackageRoot(startDir) {
|
|
171
|
+
let dir = startDir;
|
|
172
|
+
while (true) {
|
|
173
|
+
if (existsSync(join(dir, "package.json"))) return dir;
|
|
174
|
+
const next = dirname(dir);
|
|
175
|
+
if (next === dir) return startDir;
|
|
176
|
+
dir = next;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function readPackageName(root) {
|
|
180
|
+
try {
|
|
181
|
+
const pkgJson = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
|
|
182
|
+
return typeof pkgJson.name === "string" ? pkgJson.name : relative(process.cwd(), root) || "unknown";
|
|
183
|
+
} catch {
|
|
184
|
+
return relative(process.cwd(), root) || "unknown";
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
async function resolveStaleTargets(targetDir) {
|
|
188
|
+
const resolvedRoot = targetDir ? join(process.cwd(), targetDir) : process.cwd();
|
|
189
|
+
const { checkStaleness } = await import("./staleness-CWWuoPop.mjs");
|
|
190
|
+
if (existsSync(join(resolvedRoot, "skills"))) return { reports: [await checkStaleness(resolvedRoot, readPackageName(resolvedRoot))] };
|
|
191
|
+
const { findPackagesWithSkills, findWorkspaceRoot } = await import("./setup.mjs");
|
|
192
|
+
const workspaceRoot = findWorkspaceRoot(resolvedRoot);
|
|
193
|
+
if (workspaceRoot) {
|
|
194
|
+
const packageDirs = findPackagesWithSkills(workspaceRoot);
|
|
195
|
+
if (packageDirs.length > 0) return { reports: await Promise.all(packageDirs.map((packageDir) => checkStaleness(packageDir, readPackageName(packageDir)))) };
|
|
196
|
+
}
|
|
197
|
+
const staleResult = await scanIntentsOrFail();
|
|
198
|
+
return { reports: await Promise.all(staleResult.packages.map((pkg) => checkStaleness(pkg.packageRoot, pkg.name))) };
|
|
199
|
+
}
|
|
200
|
+
async function cmdValidate(args) {
|
|
201
|
+
const [{ parse: parseYaml }, { findSkillFiles }] = await Promise.all([import("yaml"), import("./utils-XSyO19J6.mjs")]);
|
|
135
202
|
const targetDir = args[0] ?? "skills";
|
|
136
203
|
const skillsDir = join(process.cwd(), targetDir);
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
process.exit(1);
|
|
140
|
-
}
|
|
204
|
+
const packageRoot = resolvePackageRoot(skillsDir);
|
|
205
|
+
if (!existsSync(skillsDir)) fail(`Skills directory not found: ${skillsDir}`);
|
|
141
206
|
const errors = [];
|
|
142
207
|
const skillFiles = findSkillFiles(skillsDir);
|
|
143
|
-
if (skillFiles.length === 0)
|
|
144
|
-
console.error("No SKILL.md files found");
|
|
145
|
-
process.exit(1);
|
|
146
|
-
}
|
|
208
|
+
if (skillFiles.length === 0) fail("No SKILL.md files found");
|
|
147
209
|
for (const filePath of skillFiles) {
|
|
148
210
|
const rel = relative(process.cwd(), filePath);
|
|
149
211
|
const content = readFileSync(filePath, "utf8");
|
|
@@ -164,7 +226,7 @@ function cmdValidate(args) {
|
|
|
164
226
|
}
|
|
165
227
|
let fm;
|
|
166
228
|
try {
|
|
167
|
-
fm =
|
|
229
|
+
fm = parseYaml(match[1]);
|
|
168
230
|
} catch {
|
|
169
231
|
errors.push({
|
|
170
232
|
file: rel,
|
|
@@ -224,7 +286,7 @@ function cmdValidate(args) {
|
|
|
224
286
|
continue;
|
|
225
287
|
}
|
|
226
288
|
if (fileName.endsWith(".yaml")) try {
|
|
227
|
-
|
|
289
|
+
parseYaml(content);
|
|
228
290
|
} catch {
|
|
229
291
|
errors.push({
|
|
230
292
|
file: relative(process.cwd(), artifactPath),
|
|
@@ -232,20 +294,11 @@ function cmdValidate(args) {
|
|
|
232
294
|
});
|
|
233
295
|
}
|
|
234
296
|
}
|
|
235
|
-
const warnings = collectPackagingWarnings(
|
|
236
|
-
|
|
237
|
-
if (warnings.length === 0) return;
|
|
238
|
-
log(`\n⚠ Packaging warnings:`);
|
|
239
|
-
for (const w of warnings) log(` ${w}`);
|
|
240
|
-
};
|
|
241
|
-
if (errors.length > 0) {
|
|
242
|
-
console.error(`\n❌ Validation failed with ${errors.length} error(s):\n`);
|
|
243
|
-
for (const { file, message } of errors) console.error(` ${file}: ${message}`);
|
|
244
|
-
printWarnings(console.error);
|
|
245
|
-
process.exit(1);
|
|
246
|
-
}
|
|
297
|
+
const warnings = collectPackagingWarnings(packageRoot);
|
|
298
|
+
if (errors.length > 0) fail(buildValidationFailure(errors, warnings));
|
|
247
299
|
console.log(`✅ Validated ${skillFiles.length} skill files — all passed`);
|
|
248
|
-
|
|
300
|
+
if (warnings.length > 0) console.log();
|
|
301
|
+
printWarnings(warnings);
|
|
249
302
|
}
|
|
250
303
|
function cmdScaffold() {
|
|
251
304
|
const metaDir = getMetaDir();
|
|
@@ -306,13 +359,13 @@ This produces: individual SKILL.md files.
|
|
|
306
359
|
|
|
307
360
|
## After all skills are generated
|
|
308
361
|
|
|
309
|
-
1. Run \`
|
|
362
|
+
1. Run \`intent validate\` in each package directory
|
|
310
363
|
2. Commit skills/ and artifacts
|
|
311
364
|
3. For each publishable package, run: \`npx @tanstack/intent add-library-bin\`
|
|
312
365
|
4. For each publishable package, run: \`npx @tanstack/intent edit-package-json\`
|
|
313
366
|
5. Ensure each package has \`@tanstack/intent\` as a devDependency
|
|
314
367
|
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\`"
|
|
368
|
+
7. Add a README note: "If you use an AI agent, run \`npx @tanstack/intent@latest install\`"
|
|
316
369
|
`;
|
|
317
370
|
console.log(prompt);
|
|
318
371
|
}
|
|
@@ -327,122 +380,148 @@ Usage:
|
|
|
327
380
|
intent add-library-bin Generate bin/intent.{js,mjs} bridge file
|
|
328
381
|
intent edit-package-json Wire package.json (files, bin) for skill publishing
|
|
329
382
|
intent setup-github-actions Copy CI workflow templates to .github/workflows/
|
|
330
|
-
intent stale
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
case "stale": {
|
|
395
|
-
const { checkStaleness } = await import("./staleness-B5gUj7FR.mjs");
|
|
396
|
-
const { scanForIntents: scanStale } = await import("./scanner-DQeiZRzp.mjs");
|
|
397
|
-
let staleResult;
|
|
398
|
-
try {
|
|
399
|
-
staleResult = await scanStale();
|
|
400
|
-
} catch (err) {
|
|
401
|
-
console.error(err.message);
|
|
402
|
-
process.exit(1);
|
|
383
|
+
intent stale [dir] [--json] Check skills for staleness`;
|
|
384
|
+
const HELP_BY_COMMAND = {
|
|
385
|
+
list: `${USAGE}
|
|
386
|
+
|
|
387
|
+
Examples:
|
|
388
|
+
intent list
|
|
389
|
+
intent list --json`,
|
|
390
|
+
meta: `intent meta [name]
|
|
391
|
+
|
|
392
|
+
List shipped meta-skills, or print a single meta-skill by name.
|
|
393
|
+
|
|
394
|
+
Examples:
|
|
395
|
+
intent meta
|
|
396
|
+
intent meta domain-discovery`,
|
|
397
|
+
validate: `intent validate [dir]
|
|
398
|
+
|
|
399
|
+
Validate SKILL.md files in the target directory.
|
|
400
|
+
|
|
401
|
+
Examples:
|
|
402
|
+
intent validate
|
|
403
|
+
intent validate packages/query/skills`,
|
|
404
|
+
install: `intent install
|
|
405
|
+
|
|
406
|
+
Print the install prompt used to set up skill-to-task mappings.`,
|
|
407
|
+
scaffold: `intent scaffold
|
|
408
|
+
|
|
409
|
+
Print the guided maintainer prompt for generating skills.`,
|
|
410
|
+
stale: `intent stale [dir] [--json]
|
|
411
|
+
|
|
412
|
+
Check installed skills for version and source drift.
|
|
413
|
+
|
|
414
|
+
Examples:
|
|
415
|
+
intent stale
|
|
416
|
+
intent stale packages/query
|
|
417
|
+
intent stale --json`,
|
|
418
|
+
"add-library-bin": `intent add-library-bin
|
|
419
|
+
|
|
420
|
+
Generate bin/intent.{js,mjs} bridge files for publishable packages.`,
|
|
421
|
+
"edit-package-json": `intent edit-package-json
|
|
422
|
+
|
|
423
|
+
Update package.json files so skills and shims are published.`,
|
|
424
|
+
"setup-github-actions": `intent setup-github-actions
|
|
425
|
+
|
|
426
|
+
Copy Intent CI workflow templates into .github/workflows/.`
|
|
427
|
+
};
|
|
428
|
+
function isHelpFlag(arg) {
|
|
429
|
+
return arg === "-h" || arg === "--help";
|
|
430
|
+
}
|
|
431
|
+
function printHelp(command) {
|
|
432
|
+
if (!command) {
|
|
433
|
+
console.log(`${USAGE}
|
|
434
|
+
|
|
435
|
+
Run \`intent help <command>\` for details on a specific command.`);
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
console.log(HELP_BY_COMMAND[command] ?? USAGE);
|
|
439
|
+
}
|
|
440
|
+
async function main(argv = process.argv.slice(2)) {
|
|
441
|
+
const command = argv[0];
|
|
442
|
+
const commandArgs = argv.slice(1);
|
|
443
|
+
try {
|
|
444
|
+
if (!command || isHelpFlag(command)) {
|
|
445
|
+
printHelp();
|
|
446
|
+
return 0;
|
|
403
447
|
}
|
|
404
|
-
if (
|
|
405
|
-
|
|
406
|
-
|
|
448
|
+
if (command === "help") {
|
|
449
|
+
printHelp(commandArgs[0]);
|
|
450
|
+
return 0;
|
|
407
451
|
}
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
return
|
|
411
|
-
}));
|
|
412
|
-
if (jsonStale) {
|
|
413
|
-
console.log(JSON.stringify(reports, null, 2));
|
|
414
|
-
break;
|
|
452
|
+
if (isHelpFlag(commandArgs[0])) {
|
|
453
|
+
printHelp(command);
|
|
454
|
+
return 0;
|
|
415
455
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
456
|
+
switch (command) {
|
|
457
|
+
case "list":
|
|
458
|
+
await cmdList(commandArgs);
|
|
459
|
+
return 0;
|
|
460
|
+
case "meta":
|
|
461
|
+
await cmdMeta(commandArgs);
|
|
462
|
+
return 0;
|
|
463
|
+
case "validate":
|
|
464
|
+
await cmdValidate(commandArgs);
|
|
465
|
+
return 0;
|
|
466
|
+
case "install":
|
|
467
|
+
console.log(INSTALL_PROMPT);
|
|
468
|
+
return 0;
|
|
469
|
+
case "scaffold":
|
|
470
|
+
cmdScaffold();
|
|
471
|
+
return 0;
|
|
472
|
+
case "stale": {
|
|
473
|
+
const jsonStale = commandArgs.includes("--json");
|
|
474
|
+
const { reports } = await resolveStaleTargets(commandArgs.find((arg) => !arg.startsWith("-")));
|
|
475
|
+
if (reports.length === 0) {
|
|
476
|
+
console.log("No intent-enabled packages found.");
|
|
477
|
+
return 0;
|
|
478
|
+
}
|
|
479
|
+
if (jsonStale) {
|
|
480
|
+
console.log(JSON.stringify(reports, null, 2));
|
|
481
|
+
return 0;
|
|
482
|
+
}
|
|
483
|
+
for (const report of reports) {
|
|
484
|
+
const driftLabel = report.versionDrift ? ` [${report.versionDrift} drift]` : "";
|
|
485
|
+
const vLabel = report.skillVersion && report.currentVersion ? ` (${report.skillVersion} → ${report.currentVersion})` : "";
|
|
486
|
+
console.log(`${report.library}${vLabel}${driftLabel}`);
|
|
487
|
+
const stale = report.skills.filter((s) => s.needsReview);
|
|
488
|
+
if (stale.length === 0) console.log(" All skills up-to-date");
|
|
489
|
+
else for (const skill of stale) console.log(` ⚠ ${skill.name}: ${skill.reasons.join(", ")}`);
|
|
490
|
+
console.log();
|
|
491
|
+
}
|
|
492
|
+
return 0;
|
|
493
|
+
}
|
|
494
|
+
case "add-library-bin": {
|
|
495
|
+
const { runAddLibraryBinAll } = await import("./setup.mjs");
|
|
496
|
+
runAddLibraryBinAll(process.cwd());
|
|
497
|
+
return 0;
|
|
498
|
+
}
|
|
499
|
+
case "edit-package-json": {
|
|
500
|
+
const { runEditPackageJsonAll } = await import("./setup.mjs");
|
|
501
|
+
runEditPackageJsonAll(process.cwd());
|
|
502
|
+
return 0;
|
|
503
|
+
}
|
|
504
|
+
case "setup-github-actions": {
|
|
505
|
+
const { runSetupGithubActions } = await import("./setup.mjs");
|
|
506
|
+
runSetupGithubActions(process.cwd(), getMetaDir());
|
|
507
|
+
return 0;
|
|
508
|
+
}
|
|
509
|
+
default:
|
|
510
|
+
printHelp();
|
|
511
|
+
return command ? 1 : 0;
|
|
424
512
|
}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
}
|
|
432
|
-
case "edit-package-json": {
|
|
433
|
-
const { runEditPackageJson } = await import("./setup.mjs");
|
|
434
|
-
runEditPackageJson(process.cwd());
|
|
435
|
-
break;
|
|
436
|
-
}
|
|
437
|
-
case "setup-github-actions": {
|
|
438
|
-
const { runSetupGithubActions } = await import("./setup.mjs");
|
|
439
|
-
runSetupGithubActions(process.cwd(), getMetaDir());
|
|
440
|
-
break;
|
|
513
|
+
} catch (err) {
|
|
514
|
+
if (isCliFailure(err)) {
|
|
515
|
+
console.error(err.message);
|
|
516
|
+
return err.exitCode;
|
|
517
|
+
}
|
|
518
|
+
throw err;
|
|
441
519
|
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
520
|
+
}
|
|
521
|
+
if (process.argv[1] !== void 0 && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
522
|
+
const exitCode = await main();
|
|
523
|
+
process.exit(exitCode);
|
|
445
524
|
}
|
|
446
525
|
|
|
447
526
|
//#endregion
|
|
448
|
-
export {
|
|
527
|
+
export { USAGE, main };
|
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 {
|
|
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-ddLtccfV.mjs";
|
|
2
|
+
import { c as runAddLibraryBin, f as runSetupGithubActions, i as SetupGithubActionsResult, n as EditPackageJsonResult, t as AddLibraryBinResult, u as runEditPackageJson } from "./setup-6m3IfxyO.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/scanner.d.ts
|
|
5
5
|
declare function scanForIntents(root?: string): Promise<ScanResult>;
|
|
@@ -13,11 +13,11 @@ declare function hasGhCli(): boolean;
|
|
|
13
13
|
declare function resolveFrequency(root: string): string;
|
|
14
14
|
declare function validatePayload(payload: unknown): {
|
|
15
15
|
valid: boolean;
|
|
16
|
-
errors: string
|
|
16
|
+
errors: Array<string>;
|
|
17
17
|
};
|
|
18
18
|
declare function validateMetaPayload(payload: unknown): {
|
|
19
19
|
valid: boolean;
|
|
20
|
-
errors: string
|
|
20
|
+
errors: Array<string>;
|
|
21
21
|
};
|
|
22
22
|
declare function metaToMarkdown(payload: MetaFeedbackPayload): string;
|
|
23
23
|
declare function toMarkdown(payload: FeedbackPayload): string;
|
|
@@ -38,10 +38,22 @@ declare function submitMetaFeedback(payload: MetaFeedbackPayload, opts: {
|
|
|
38
38
|
/**
|
|
39
39
|
* Recursively find all SKILL.md files under a directory.
|
|
40
40
|
*/
|
|
41
|
-
declare function findSkillFiles(dir: string): string
|
|
41
|
+
declare function findSkillFiles(dir: string): Array<string>;
|
|
42
|
+
/**
|
|
43
|
+
* Read dependencies and peerDependencies (and optionally devDependencies) from
|
|
44
|
+
* a parsed package.json object.
|
|
45
|
+
*/
|
|
46
|
+
declare function getDeps(pkgJson: Record<string, unknown>, includeDevDeps?: boolean): Array<string>;
|
|
47
|
+
/**
|
|
48
|
+
* Resolve the directory of a dependency by name. First checks the top-level
|
|
49
|
+
* node_modules (hoisted layout — npm, yarn, bun), then resolves through the
|
|
50
|
+
* parent package's real path to handle pnpm's virtual store layout where
|
|
51
|
+
* transitive deps are siblings in the .pnpm virtual store node_modules.
|
|
52
|
+
*/
|
|
53
|
+
declare function resolveDepDir(depName: string, parentDir: string, parentName: string, nodeModulesDirs: string | Array<string>): string | null;
|
|
42
54
|
/**
|
|
43
55
|
* Parse YAML frontmatter from a file. Returns null if no frontmatter or on error.
|
|
44
56
|
*/
|
|
45
57
|
declare function parseFrontmatter(filePath: string): Record<string, unknown> | null;
|
|
46
58
|
//#endregion
|
|
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 };
|
|
59
|
+
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, getDeps, hasGhCli, metaToMarkdown, parseFrontmatter, resolveDepDir, resolveFrequency, runAddLibraryBin, runEditPackageJson, runSetupGithubActions, scanForIntents, submitFeedback, submitMetaFeedback, toMarkdown, validateMetaPayload, validatePayload };
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as scanForIntents } from "./scanner-
|
|
3
|
-
import { t as checkStaleness } from "./staleness-
|
|
4
|
-
import {
|
|
1
|
+
import { a as parseFrontmatter, n as findSkillFiles, o as resolveDepDir, r as getDeps } from "./utils-DY1eH2E_.mjs";
|
|
2
|
+
import { t as scanForIntents } from "./scanner-f82qRq7h.mjs";
|
|
3
|
+
import { t as checkStaleness } from "./staleness-D_ZiK4Tf.mjs";
|
|
4
|
+
import { c as runSetupGithubActions, i as runAddLibraryBin, o as runEditPackageJson } from "./setup-CncHbQlb.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";
|
|
@@ -31,17 +31,26 @@ function hasGhCli() {
|
|
|
31
31
|
function getHomeConfigDir() {
|
|
32
32
|
return process.env.XDG_CONFIG_HOME ?? join(process.env.HOME ?? process.env.USERPROFILE ?? "", ".config");
|
|
33
33
|
}
|
|
34
|
-
function
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
function parseFrequency(value) {
|
|
35
|
+
if (value === "always" || value === "never") return value;
|
|
36
|
+
if (typeof value !== "string") return null;
|
|
37
|
+
const match = /^every-(\d+)$/.exec(value);
|
|
38
|
+
if (!match) return null;
|
|
39
|
+
const count = Number(match[1]);
|
|
40
|
+
return Number.isInteger(count) && count > 0 ? `every-${count}` : null;
|
|
41
|
+
}
|
|
42
|
+
function readFrequency(filePath) {
|
|
41
43
|
try {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
return parseFrequency(JSON.parse(readFileSync(filePath, "utf8")).feedback?.frequency);
|
|
45
|
+
} catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function resolveFrequency(root) {
|
|
50
|
+
const userFrequency = readFrequency(join(getHomeConfigDir(), "intent", "config.json"));
|
|
51
|
+
if (userFrequency) return userFrequency;
|
|
52
|
+
const projectFrequency = readFrequency(join(root, "intent.config.json"));
|
|
53
|
+
if (projectFrequency) return projectFrequency;
|
|
45
54
|
return "every-5";
|
|
46
55
|
}
|
|
47
56
|
const REQUIRED_FIELDS = [
|
|
@@ -102,6 +111,18 @@ const VALID_QUALITY_RATINGS = [
|
|
|
102
111
|
"mixed",
|
|
103
112
|
"bad"
|
|
104
113
|
];
|
|
114
|
+
const VALID_INTERVIEW_QUALITY_RATINGS = [
|
|
115
|
+
"good",
|
|
116
|
+
"mixed",
|
|
117
|
+
"bad",
|
|
118
|
+
"skipped"
|
|
119
|
+
];
|
|
120
|
+
const VALID_FAILURE_MODE_QUALITY_RATINGS = [
|
|
121
|
+
"good",
|
|
122
|
+
"mixed",
|
|
123
|
+
"bad",
|
|
124
|
+
"not-applicable"
|
|
125
|
+
];
|
|
105
126
|
function validateMetaPayload(payload) {
|
|
106
127
|
const errors = [];
|
|
107
128
|
if (!payload || typeof payload !== "object") return {
|
|
@@ -114,6 +135,8 @@ function validateMetaPayload(payload) {
|
|
|
114
135
|
if (obj.agentUsed && !VALID_AGENTS.includes(obj.agentUsed)) errors.push(`agentUsed must be one of: ${VALID_AGENTS.join(", ")}`);
|
|
115
136
|
if (obj.artifactQuality && !VALID_QUALITY_RATINGS.includes(obj.artifactQuality)) errors.push("artifactQuality must be one of: good, mixed, bad");
|
|
116
137
|
if (obj.userRating && !VALID_QUALITY_RATINGS.includes(obj.userRating)) errors.push("userRating must be one of: good, mixed, bad");
|
|
138
|
+
if (obj.interviewQuality && !VALID_INTERVIEW_QUALITY_RATINGS.includes(obj.interviewQuality)) errors.push("interviewQuality must be one of: good, mixed, bad, skipped");
|
|
139
|
+
if (obj.failureModeQuality && !VALID_FAILURE_MODE_QUALITY_RATINGS.includes(obj.failureModeQuality)) errors.push("failureModeQuality must be one of: good, mixed, bad, not-applicable");
|
|
117
140
|
if (containsSecrets(Object.values(obj).filter((v) => typeof v === "string").join("\n"))) errors.push("Payload appears to contain secrets or tokens — submission rejected");
|
|
118
141
|
return {
|
|
119
142
|
valid: errors.length === 0,
|
|
@@ -246,4 +269,4 @@ function submitMetaFeedback(payload, opts) {
|
|
|
246
269
|
}
|
|
247
270
|
|
|
248
271
|
//#endregion
|
|
249
|
-
export { checkStaleness, containsSecrets, findSkillFiles, hasGhCli, metaToMarkdown, parseFrontmatter, resolveFrequency, runAddLibraryBin, runEditPackageJson, runSetupGithubActions, scanForIntents, submitFeedback, submitMetaFeedback, toMarkdown, validateMetaPayload, validatePayload };
|
|
272
|
+
export { checkStaleness, containsSecrets, findSkillFiles, getDeps, hasGhCli, metaToMarkdown, parseFrontmatter, resolveDepDir, resolveFrequency, runAddLibraryBin, runEditPackageJson, runSetupGithubActions, scanForIntents, submitFeedback, submitMetaFeedback, toMarkdown, validateMetaPayload, validatePayload };
|