@tanstack/intent 0.0.32 → 0.0.33
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 +7 -7
- package/dist/artifact-coverage-BAN2W6aH.mjs +3 -0
- package/dist/artifact-coverage-wLNVX8yC.mjs +128 -0
- package/dist/cli.mjs +21 -9
- package/dist/{display-DCRCp4-C.mjs → display-DvLbcWzq.mjs} +1 -1
- package/dist/index.d.mts +22 -4
- package/dist/index.mjs +125 -8
- package/dist/{install-BmVqcbEi.mjs → install-PUnIfBNC.mjs} +54 -18
- package/dist/intent-library.mjs +5 -5
- package/dist/library-scanner.d.mts +1 -1
- package/dist/library-scanner.mjs +1 -1
- package/dist/{project-context-CKG-q4rD.mjs → project-context-IDLpJU3S.mjs} +1 -1
- package/dist/{resolver-aFigTqXi.mjs → resolver-D2CgIYGg.mjs} +1 -1
- package/dist/{scanner-DKL8v8is.mjs → scanner-CW59cxE_.mjs} +1 -1
- package/dist/scanner-DlkcbVye.mjs +6 -0
- package/dist/{setup-JJvjiGkM.mjs → setup-DfLsziXU.mjs} +2 -2
- package/dist/setup.d.mts +1 -1
- package/dist/setup.mjs +3 -3
- package/dist/staleness-DpbmYod4.mjs +5 -0
- package/dist/staleness-PdgakrCQ.mjs +243 -0
- package/dist/{types-CsySN6Vw.d.mts → types-_y9b00bI.d.mts} +48 -1
- package/dist/{workspace-patterns-U35B5AO-.mjs → workspace-patterns-BN2A_60g.mjs} +6 -1
- package/dist/workspace-patterns-x-dLZxx4.mjs +4 -0
- package/meta/templates/workflows/check-skills.yml +199 -91
- package/package.json +1 -1
- package/dist/scanner-CRZITpcY.mjs +0 -6
- package/dist/staleness-DorwfGrf.mjs +0 -104
- package/dist/staleness-NF-lxfXf.mjs +0 -4
- package/dist/workspace-patterns-DbnA0peB.mjs +0 -4
- package/meta/templates/workflows/notify-intent.yml +0 -51
- /package/dist/{display-DUgtRJkt.mjs → display-BTZWCjzT.mjs} +0 -0
- /package/dist/{library-scanner-DFFreLjW.mjs → library-scanner-Cl-XPEMf.mjs} +0 -0
- /package/dist/{setup-DDoOLriA.d.mts → setup-D2CGdTsx.d.mts} +0 -0
- /package/dist/{skill-use-CXOnncWK.mjs → skill-use-uwGleSOz.mjs} +0 -0
package/README.md
CHANGED
|
@@ -90,10 +90,10 @@ npx @tanstack/intent@latest stale
|
|
|
90
90
|
|
|
91
91
|
From a monorepo root, `intent stale` checks every workspace package that ships skills. To scope it to one package, pass a directory like `intent stale packages/router`.
|
|
92
92
|
|
|
93
|
-
Copy CI workflow templates into your repo so validation and staleness checks run
|
|
93
|
+
Copy CI workflow templates into your repo so validation and staleness checks can run in GitHub Actions:
|
|
94
94
|
|
|
95
95
|
```bash
|
|
96
|
-
npx @tanstack/intent@latest setup
|
|
96
|
+
npx @tanstack/intent@latest setup
|
|
97
97
|
```
|
|
98
98
|
|
|
99
99
|
## Compatibility
|
|
@@ -108,14 +108,14 @@ npx @tanstack/intent@latest setup-github-actions
|
|
|
108
108
|
|
|
109
109
|
## Monorepos
|
|
110
110
|
|
|
111
|
-
- Run `npx @tanstack/intent@latest setup
|
|
112
|
-
- Generated workflows are monorepo-aware: validation loops over workspace packages with skills, staleness checks run from the workspace root
|
|
111
|
+
- Run `npx @tanstack/intent@latest setup` from either the repo root or a package directory. Intent detects the workspace root and writes workflows to the repo-level `.github/workflows/` directory.
|
|
112
|
+
- Generated workflows are monorepo-aware: validation loops over workspace packages with skills, and staleness checks run from the workspace root.
|
|
113
113
|
- Run `npx @tanstack/intent@latest validate packages/<pkg>/skills` from the repo root to validate one package without root-level packaging warnings.
|
|
114
|
-
- Run `npx @tanstack/intent@latest stale` from the repo root to check
|
|
114
|
+
- Run `npx @tanstack/intent@latest stale` from the repo root to check workspace packages with skills and public workspace packages missing skill or `_artifacts` coverage, or `intent stale packages/<pkg>` to check one package.
|
|
115
115
|
|
|
116
116
|
## Keeping skills current
|
|
117
117
|
|
|
118
|
-
The real risk with any derived artifact is staleness. `npx @tanstack/intent@latest stale` flags skills whose source docs have changed, and CI templates catch drift before it ships.
|
|
118
|
+
The real risk with any derived artifact is staleness. `npx @tanstack/intent@latest stale` flags skills whose source docs have changed, generated skills that drift from `_artifacts`, and public workspace packages missing coverage. CI templates catch drift before it ships.
|
|
119
119
|
|
|
120
120
|
The feedback loop runs both directions. `npx @tanstack/intent@latest 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 package 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.
|
|
121
121
|
|
|
@@ -129,7 +129,7 @@ The feedback loop runs both directions. `npx @tanstack/intent@latest feedback` l
|
|
|
129
129
|
| `npx @tanstack/intent@latest meta` | List meta-skills for library maintainers |
|
|
130
130
|
| `npx @tanstack/intent@latest scaffold` | Print the guided skill generation prompt |
|
|
131
131
|
| `npx @tanstack/intent@latest validate [dir]` | Validate SKILL.md files |
|
|
132
|
-
| `npx @tanstack/intent@latest setup
|
|
132
|
+
| `npx @tanstack/intent@latest setup` | Copy CI templates into your repo |
|
|
133
133
|
| `npx @tanstack/intent@latest stale [dir] [--json]` | Check skills for version drift |
|
|
134
134
|
| `npx @tanstack/intent@latest feedback` | Submit skill feedback |
|
|
135
135
|
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { parse } from "yaml";
|
|
4
|
+
|
|
5
|
+
//#region src/artifact-coverage.ts
|
|
6
|
+
function isRecord(value) {
|
|
7
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
8
|
+
}
|
|
9
|
+
function stringValue(value) {
|
|
10
|
+
return typeof value === "string" && value.trim() ? value : void 0;
|
|
11
|
+
}
|
|
12
|
+
function stringArray(value) {
|
|
13
|
+
if (!Array.isArray(value)) return [];
|
|
14
|
+
return value.filter((entry) => typeof entry === "string");
|
|
15
|
+
}
|
|
16
|
+
function detectArtifactKind(fileName) {
|
|
17
|
+
if (fileName.endsWith("skill_tree.yaml")) return "skill-tree";
|
|
18
|
+
if (fileName.endsWith("domain_map.yaml")) return "domain-map";
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
function readArtifactYaml(artifactPath, warnings) {
|
|
22
|
+
let parsed;
|
|
23
|
+
try {
|
|
24
|
+
parsed = parse(readFileSync(artifactPath, "utf8"));
|
|
25
|
+
} catch (err) {
|
|
26
|
+
warnings.push({
|
|
27
|
+
artifactPath,
|
|
28
|
+
message: `Invalid YAML: ${err instanceof Error ? err.message : String(err)}`
|
|
29
|
+
});
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
if (!isRecord(parsed)) {
|
|
33
|
+
warnings.push({
|
|
34
|
+
artifactPath,
|
|
35
|
+
message: "Artifact YAML must contain an object at the top level"
|
|
36
|
+
});
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
return parsed;
|
|
40
|
+
}
|
|
41
|
+
function parseArtifactFile(artifactPath, kind, parsed) {
|
|
42
|
+
const library = isRecord(parsed.library) ? parsed.library : {};
|
|
43
|
+
return {
|
|
44
|
+
path: artifactPath,
|
|
45
|
+
kind,
|
|
46
|
+
libraryName: stringValue(library.name),
|
|
47
|
+
libraryVersion: stringValue(library.version)
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function parseSkills(artifactPath, kind, parsed) {
|
|
51
|
+
if (!Array.isArray(parsed.skills)) return [];
|
|
52
|
+
const skills = [];
|
|
53
|
+
for (const skill of parsed.skills) {
|
|
54
|
+
if (!isRecord(skill)) continue;
|
|
55
|
+
const packagePath = stringValue(skill.package);
|
|
56
|
+
const packages = stringArray(skill.packages);
|
|
57
|
+
if (packagePath) packages.push(packagePath);
|
|
58
|
+
skills.push({
|
|
59
|
+
artifactPath,
|
|
60
|
+
artifactKind: kind,
|
|
61
|
+
name: stringValue(skill.name),
|
|
62
|
+
slug: stringValue(skill.slug),
|
|
63
|
+
path: stringValue(skill.path),
|
|
64
|
+
package: packagePath,
|
|
65
|
+
packages: [...new Set(packages)].sort((a, b) => a.localeCompare(b)),
|
|
66
|
+
sources: stringArray(skill.sources),
|
|
67
|
+
covers: stringArray(skill.covers)
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return skills;
|
|
71
|
+
}
|
|
72
|
+
function parseCoverageIgnores(artifactPath, parsed) {
|
|
73
|
+
const ignored = (isRecord(parsed.coverage) ? parsed.coverage : null)?.ignored_packages;
|
|
74
|
+
if (!Array.isArray(ignored)) return [];
|
|
75
|
+
const ignores = [];
|
|
76
|
+
for (const entry of ignored) {
|
|
77
|
+
if (typeof entry === "string") {
|
|
78
|
+
if (entry.trim()) ignores.push({
|
|
79
|
+
packageName: entry,
|
|
80
|
+
artifactPath
|
|
81
|
+
});
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (!isRecord(entry)) continue;
|
|
85
|
+
const packageName = stringValue(entry.name);
|
|
86
|
+
if (!packageName) continue;
|
|
87
|
+
ignores.push({
|
|
88
|
+
packageName,
|
|
89
|
+
reason: stringValue(entry.reason),
|
|
90
|
+
artifactPath
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return ignores;
|
|
94
|
+
}
|
|
95
|
+
function readIntentArtifacts(root) {
|
|
96
|
+
const artifactsDir = join(root, "_artifacts");
|
|
97
|
+
if (!existsSync(artifactsDir)) return null;
|
|
98
|
+
const warnings = [];
|
|
99
|
+
const skillTrees = [];
|
|
100
|
+
const domainMaps = [];
|
|
101
|
+
const skills = [];
|
|
102
|
+
const ignoredPackages = [];
|
|
103
|
+
for (const entry of readdirSync(artifactsDir, { withFileTypes: true })) {
|
|
104
|
+
if (!entry.isFile()) continue;
|
|
105
|
+
const kind = detectArtifactKind(entry.name);
|
|
106
|
+
if (!kind) continue;
|
|
107
|
+
const artifactPath = join(artifactsDir, entry.name);
|
|
108
|
+
const parsed = readArtifactYaml(artifactPath, warnings);
|
|
109
|
+
if (!parsed) continue;
|
|
110
|
+
const artifactFile = parseArtifactFile(artifactPath, kind, parsed);
|
|
111
|
+
if (kind === "skill-tree") skillTrees.push(artifactFile);
|
|
112
|
+
else domainMaps.push(artifactFile);
|
|
113
|
+
skills.push(...parseSkills(artifactPath, kind, parsed));
|
|
114
|
+
ignoredPackages.push(...parseCoverageIgnores(artifactPath, parsed));
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
root,
|
|
118
|
+
artifactsDir,
|
|
119
|
+
skillTrees: skillTrees.sort((a, b) => a.path.localeCompare(b.path)),
|
|
120
|
+
domainMaps: domainMaps.sort((a, b) => a.path.localeCompare(b.path)),
|
|
121
|
+
skills: skills.sort((a, b) => `${a.artifactPath}:${a.slug ?? a.name ?? ""}`.localeCompare(`${b.artifactPath}:${b.slug ?? b.name ?? ""}`)),
|
|
122
|
+
ignoredPackages: ignoredPackages.sort((a, b) => a.packageName.localeCompare(b.packageName)),
|
|
123
|
+
warnings
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
//#endregion
|
|
128
|
+
export { readIntentArtifacts as t };
|
package/dist/cli.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import "./utils-COlDcU72.mjs";
|
|
3
|
-
import "./workspace-patterns-
|
|
4
|
-
import { i as parseSkillUse } from "./skill-use-
|
|
5
|
-
import { r as resolveSkillUse } from "./resolver-
|
|
6
|
-
import { t as resolveProjectContext } from "./project-context-
|
|
7
|
-
import { a as scanIntentsOrFail, c as fail, i as resolveStaleTargets, l as isCliFailure, n as runInstallCommand, o as scanOptionsFromGlobalFlags, r as getMetaDir, s as printWarnings } from "./install-
|
|
3
|
+
import "./workspace-patterns-BN2A_60g.mjs";
|
|
4
|
+
import { i as parseSkillUse } from "./skill-use-uwGleSOz.mjs";
|
|
5
|
+
import { r as resolveSkillUse } from "./resolver-D2CgIYGg.mjs";
|
|
6
|
+
import { t as resolveProjectContext } from "./project-context-IDLpJU3S.mjs";
|
|
7
|
+
import { a as scanIntentsOrFail, c as fail, i as resolveStaleTargets, l as isCliFailure, n as runInstallCommand, o as scanOptionsFromGlobalFlags, r as getMetaDir, s as printWarnings } from "./install-PUnIfBNC.mjs";
|
|
8
8
|
import { existsSync, readFileSync, readdirSync, realpathSync } from "node:fs";
|
|
9
9
|
import { isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
10
10
|
import { fileURLToPath } from "node:url";
|
|
@@ -43,7 +43,7 @@ async function runListCommand(options, scanIntentsOrFail$1) {
|
|
|
43
43
|
console.log(JSON.stringify(result, null, 2));
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
|
-
const { computeSkillNameWidth, printSkillTree, printTable } = await import("./display-
|
|
46
|
+
const { computeSkillNameWidth, printSkillTree, printTable } = await import("./display-DvLbcWzq.mjs");
|
|
47
47
|
const scanCoverage = formatScanCoverage(result);
|
|
48
48
|
if (result.packages.length === 0) {
|
|
49
49
|
console.log("No intent-enabled packages found.");
|
|
@@ -245,11 +245,13 @@ async function runSetupGithubActionsCommand(root, metaDir) {
|
|
|
245
245
|
//#endregion
|
|
246
246
|
//#region src/commands/stale.ts
|
|
247
247
|
async function runStaleCommand(targetDir, options, resolveStaleTargets$1) {
|
|
248
|
-
const { reports } = await resolveStaleTargets$1(targetDir);
|
|
248
|
+
const { reports, workflowAdvisories = [] } = await resolveStaleTargets$1(targetDir);
|
|
249
249
|
if (options.json) {
|
|
250
250
|
console.log(JSON.stringify(reports, null, 2));
|
|
251
251
|
return;
|
|
252
252
|
}
|
|
253
|
+
for (const advisory of workflowAdvisories) console.log(advisory);
|
|
254
|
+
if (workflowAdvisories.length > 0) console.log();
|
|
253
255
|
if (reports.length === 0) {
|
|
254
256
|
console.log("No intent-enabled packages found.");
|
|
255
257
|
return;
|
|
@@ -259,8 +261,15 @@ async function runStaleCommand(targetDir, options, resolveStaleTargets$1) {
|
|
|
259
261
|
const vLabel = report.skillVersion && report.currentVersion ? ` (${report.skillVersion} → ${report.currentVersion})` : "";
|
|
260
262
|
console.log(`${report.library}${vLabel}${driftLabel}`);
|
|
261
263
|
const stale = report.skills.filter((skill) => skill.needsReview);
|
|
262
|
-
|
|
263
|
-
|
|
264
|
+
const signals = report.signals.filter((signal) => signal.needsReview);
|
|
265
|
+
if (stale.length === 0 && signals.length === 0) console.log(" All skills up-to-date");
|
|
266
|
+
else {
|
|
267
|
+
for (const skill of stale) console.log(` ⚠ ${skill.name}: ${skill.reasons.join(", ")}`);
|
|
268
|
+
for (const signal of signals) {
|
|
269
|
+
const subject = signal.packageName ?? signal.packageRoot ?? signal.skill ?? signal.artifactPath ?? signal.subject ?? report.library;
|
|
270
|
+
console.log(` ⚠ ${subject}: ${signal.reasons.join(", ")}`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
264
273
|
console.log();
|
|
265
274
|
}
|
|
266
275
|
}
|
|
@@ -439,6 +448,9 @@ function createCli() {
|
|
|
439
448
|
cli.command("edit-package-json", "Update package.json files so skills are published").usage("edit-package-json").action(async () => {
|
|
440
449
|
await runEditPackageJsonCommand(process.cwd());
|
|
441
450
|
});
|
|
451
|
+
cli.command("setup", "Copy Intent CI workflow templates into .github/workflows/").usage("setup").action(async () => {
|
|
452
|
+
await runSetupGithubActionsCommand(process.cwd(), getMetaDir());
|
|
453
|
+
});
|
|
442
454
|
cli.command("setup-github-actions", "Copy Intent CI workflow templates into .github/workflows/").usage("setup-github-actions").action(async () => {
|
|
443
455
|
await runSetupGithubActionsCommand(process.cwd(), getMetaDir());
|
|
444
456
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./utils-COlDcU72.mjs";
|
|
2
2
|
import "./skill-paths-8k9K9y26.mjs";
|
|
3
|
-
import { n as printSkillTree, r as printTable, t as computeSkillNameWidth } from "./display-
|
|
3
|
+
import { n as printSkillTree, r as printTable, t as computeSkillNameWidth } from "./display-BTZWCjzT.mjs";
|
|
4
4
|
|
|
5
5
|
export { computeSkillNameWidth, printSkillTree, printTable };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,11 +1,29 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import { i as runEditPackageJson, o as runSetupGithubActions, r as SetupGithubActionsResult, t as EditPackageJsonResult } from "./setup-
|
|
1
|
+
import { _ as StalenessReport, a as IntentArtifactSet, c as IntentConfig, d as MetaFeedbackPayload, f as MetaSkillName, g as SkillStaleness, h as SkillEntry, i as IntentArtifactFile, l as IntentPackage, m as ScanResult, n as FeedbackPayload, o as IntentArtifactSkill, p as ScanOptions, r as IntentArtifactCoverageIgnore, s as IntentArtifactWarning, t as AgentName, u as IntentProjectConfig, v as StalenessSignal, y as VersionConflict } from "./types-_y9b00bI.mjs";
|
|
2
|
+
import { i as runEditPackageJson, o as runSetupGithubActions, r as SetupGithubActionsResult, t as EditPackageJsonResult } from "./setup-D2CGdTsx.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/scanner.d.ts
|
|
5
5
|
declare function scanForIntents(root?: string, options?: ScanOptions): ScanResult;
|
|
6
6
|
//#endregion
|
|
7
7
|
//#region src/staleness.d.ts
|
|
8
|
-
declare function checkStaleness(packageDir: string, packageName?: string): Promise<StalenessReport>;
|
|
8
|
+
declare function checkStaleness(packageDir: string, packageName?: string, artifactRoot?: string): Promise<StalenessReport>;
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/artifact-coverage.d.ts
|
|
11
|
+
declare function readIntentArtifacts(root: string): IntentArtifactSet | null;
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/workflow-review.d.ts
|
|
14
|
+
interface StaleReviewItem {
|
|
15
|
+
type: string;
|
|
16
|
+
library: string;
|
|
17
|
+
subject: string;
|
|
18
|
+
reasons: Array<string>;
|
|
19
|
+
artifactPath?: string;
|
|
20
|
+
packageName?: string;
|
|
21
|
+
packageRoot?: string;
|
|
22
|
+
skill?: string;
|
|
23
|
+
}
|
|
24
|
+
declare function collectStaleReviewItems(reports: Array<StalenessReport>): Array<StaleReviewItem>;
|
|
25
|
+
declare function createFailedStaleReviewItem(library: string): StaleReviewItem;
|
|
26
|
+
declare function buildStaleReviewBody(items: Array<StaleReviewItem>): string;
|
|
9
27
|
//#endregion
|
|
10
28
|
//#region src/feedback.d.ts
|
|
11
29
|
declare function containsSecrets(text: string): boolean;
|
|
@@ -108,4 +126,4 @@ declare class ResolveSkillUseError extends Error {
|
|
|
108
126
|
declare function isResolveSkillUseError(error: unknown): error is ResolveSkillUseError;
|
|
109
127
|
declare function resolveSkillUse(use: string, scanResult: ScanResult): ResolveSkillResult;
|
|
110
128
|
//#endregion
|
|
111
|
-
export { type AgentName, type EditPackageJsonResult, type FeedbackPayload, type IntentConfig, type IntentPackage, type IntentProjectConfig, type MetaFeedbackPayload, type MetaSkillName, type ResolveSkillResult, ResolveSkillUseError, type ResolveSkillUseErrorCode, type ScanOptions, type ScanResult, type SetupGithubActionsResult, type SkillEntry, type SkillStaleness, type SkillUse, SkillUseParseError, type SkillUseParseErrorCode, type StalenessReport, checkStaleness, containsSecrets, findSkillFiles, formatSkillUse, getDeps, hasGhCli, isResolveSkillUseError, isSkillUseParseError, metaToMarkdown, parseFrontmatter, parseSkillUse, resolveDepDir, resolveFrequency, resolveSkillUse, runEditPackageJson, runSetupGithubActions, scanForIntents, submitFeedback, submitMetaFeedback, toMarkdown, validateMetaPayload, validatePayload };
|
|
129
|
+
export { type AgentName, type EditPackageJsonResult, type FeedbackPayload, type IntentArtifactCoverageIgnore, type IntentArtifactFile, type IntentArtifactSet, type IntentArtifactSkill, type IntentArtifactWarning, type IntentConfig, type IntentPackage, type IntentProjectConfig, type MetaFeedbackPayload, type MetaSkillName, type ResolveSkillResult, ResolveSkillUseError, type ResolveSkillUseErrorCode, type ScanOptions, type ScanResult, type SetupGithubActionsResult, type SkillEntry, type SkillStaleness, type SkillUse, SkillUseParseError, type SkillUseParseErrorCode, type StaleReviewItem, type StalenessReport, type StalenessSignal, buildStaleReviewBody, checkStaleness, collectStaleReviewItems, containsSecrets, createFailedStaleReviewItem, findSkillFiles, formatSkillUse, getDeps, hasGhCli, isResolveSkillUseError, isSkillUseParseError, metaToMarkdown, parseFrontmatter, parseSkillUse, readIntentArtifacts, resolveDepDir, resolveFrequency, resolveSkillUse, runEditPackageJson, runSetupGithubActions, scanForIntents, submitFeedback, submitMetaFeedback, toMarkdown, validateMetaPayload, validatePayload };
|
package/dist/index.mjs
CHANGED
|
@@ -1,16 +1,133 @@
|
|
|
1
1
|
import { a as parseFrontmatter, n as findSkillFiles, o as resolveDepDir, r as getDeps } from "./utils-COlDcU72.mjs";
|
|
2
2
|
import "./skill-paths-8k9K9y26.mjs";
|
|
3
|
-
import { t as scanForIntents } from "./scanner-
|
|
4
|
-
import "./workspace-patterns-
|
|
5
|
-
import { t as
|
|
6
|
-
import {
|
|
7
|
-
import { n as
|
|
8
|
-
import "./
|
|
9
|
-
import
|
|
3
|
+
import { t as scanForIntents } from "./scanner-CW59cxE_.mjs";
|
|
4
|
+
import "./workspace-patterns-BN2A_60g.mjs";
|
|
5
|
+
import { t as readIntentArtifacts } from "./artifact-coverage-wLNVX8yC.mjs";
|
|
6
|
+
import { n as checkStaleness } from "./staleness-PdgakrCQ.mjs";
|
|
7
|
+
import { i as parseSkillUse, n as formatSkillUse, r as isSkillUseParseError, t as SkillUseParseError } from "./skill-use-uwGleSOz.mjs";
|
|
8
|
+
import { n as isResolveSkillUseError, r as resolveSkillUse, t as ResolveSkillUseError } from "./resolver-D2CgIYGg.mjs";
|
|
9
|
+
import "./project-context-IDLpJU3S.mjs";
|
|
10
|
+
import { r as runSetupGithubActions, t as runEditPackageJson } from "./setup-DfLsziXU.mjs";
|
|
10
11
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
11
12
|
import { join } from "node:path";
|
|
12
13
|
import { execFileSync, execSync } from "node:child_process";
|
|
13
14
|
|
|
15
|
+
//#region src/workflow-review.ts
|
|
16
|
+
function collectStaleReviewItems(reports) {
|
|
17
|
+
const items = [];
|
|
18
|
+
for (const report of reports) {
|
|
19
|
+
for (const skill of report.skills ?? []) {
|
|
20
|
+
if (!skill?.needsReview) continue;
|
|
21
|
+
items.push({
|
|
22
|
+
type: "stale-skill",
|
|
23
|
+
library: report.library,
|
|
24
|
+
subject: skill.name,
|
|
25
|
+
reasons: skill.reasons ?? []
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
for (const signal of report.signals ?? []) {
|
|
29
|
+
if (signal?.needsReview === false) continue;
|
|
30
|
+
items.push({
|
|
31
|
+
type: signal?.type ?? "review-signal",
|
|
32
|
+
library: signal?.library ?? report.library,
|
|
33
|
+
subject: signal?.packageName ?? signal?.packageRoot ?? signal?.skill ?? signal?.artifactPath ?? signal?.subject ?? report.library,
|
|
34
|
+
reasons: signal?.reasons ?? [],
|
|
35
|
+
artifactPath: signal?.artifactPath,
|
|
36
|
+
packageName: signal?.packageName,
|
|
37
|
+
packageRoot: signal?.packageRoot,
|
|
38
|
+
skill: signal?.skill
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return items;
|
|
43
|
+
}
|
|
44
|
+
function createFailedStaleReviewItem(library) {
|
|
45
|
+
return {
|
|
46
|
+
type: "stale-check-failed",
|
|
47
|
+
library,
|
|
48
|
+
subject: "intent stale --json",
|
|
49
|
+
reasons: ["The stale check command failed. Review the workflow logs before updating skills."]
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function buildStaleReviewBody(items) {
|
|
53
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
54
|
+
for (const item of items) grouped.set(item.type, (grouped.get(item.type) ?? 0) + 1);
|
|
55
|
+
const signalRows = [...grouped.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([type, count]) => `| \`${type}\` | ${count} |`);
|
|
56
|
+
const itemRows = items.map((item) => {
|
|
57
|
+
const subject = item.subject ? `\`${item.subject}\`` : "-";
|
|
58
|
+
const reasons = item.reasons?.length ? item.reasons.join("; ") : "-";
|
|
59
|
+
return `| \`${item.type}\` | ${subject} | \`${item.library}\` | ${reasons} |`;
|
|
60
|
+
});
|
|
61
|
+
const prompt = [
|
|
62
|
+
"You are helping maintain Intent skills for this repository.",
|
|
63
|
+
"",
|
|
64
|
+
"Goal:",
|
|
65
|
+
"Resolve the Intent skill review signals below while preserving the existing scope, taxonomy, and maintainer-reviewed artifacts.",
|
|
66
|
+
"",
|
|
67
|
+
"Review signals:",
|
|
68
|
+
JSON.stringify(items, null, 2),
|
|
69
|
+
"",
|
|
70
|
+
"Required workflow:",
|
|
71
|
+
"1. Read the existing `_artifacts/*domain_map.yaml`, `_artifacts/*skill_tree.yaml`, and generated `skills/**/SKILL.md` files.",
|
|
72
|
+
"2. Read each flagged package package.json, public exports, README/docs if present, and source entry points.",
|
|
73
|
+
"3. Compare flagged packages against the existing domains, skills, tasks, packages, covers, sources, tensions, and cross-references in the artifacts.",
|
|
74
|
+
"4. For each signal, decide whether it means existing skill coverage, a missing generated skill, a new skill candidate, out-of-scope coverage, or deferred work.",
|
|
75
|
+
"",
|
|
76
|
+
"Maintainer questions:",
|
|
77
|
+
"Before editing skills or artifacts, ask the maintainer:",
|
|
78
|
+
"1. For each flagged package, is this package user-facing enough to need agent guidance?",
|
|
79
|
+
"2. If yes, should it extend an existing skill or become a new skill?",
|
|
80
|
+
"3. If it extends an existing skill, which current skill should own it?",
|
|
81
|
+
"4. If it is out of scope, what short reason should be recorded in artifact coverage ignores?",
|
|
82
|
+
"5. Are any of these packages experimental or unstable enough to exclude for now?",
|
|
83
|
+
"",
|
|
84
|
+
"Decision rules:",
|
|
85
|
+
"- Do not auto-generate skills.",
|
|
86
|
+
"- Do not create broad new skill areas without maintainer confirmation.",
|
|
87
|
+
"- Prefer adding package coverage to an existing skill when the package is an implementation variant of an existing domain.",
|
|
88
|
+
"- Create a new skill only when the package introduces a distinct developer task or failure mode.",
|
|
89
|
+
"- Preserve current naming, path, and package layout conventions.",
|
|
90
|
+
"- Keep generated skills under the package-local `skills/` directory.",
|
|
91
|
+
"- Keep repo-root `_artifacts` as the reviewed plan.",
|
|
92
|
+
"",
|
|
93
|
+
"If maintainer confirms updates:",
|
|
94
|
+
"1. Update the relevant `_artifacts/*domain_map.yaml` or `_artifacts/*skill_tree.yaml`.",
|
|
95
|
+
"2. Update or create `SKILL.md` files only for confirmed coverage changes.",
|
|
96
|
+
"3. Keep `sources` aligned between artifact skill entries and SKILL frontmatter.",
|
|
97
|
+
"4. Bump `library_version` only for skills whose covered source package version changed.",
|
|
98
|
+
"5. Run `npx @tanstack/intent@latest validate` on touched skill directories.",
|
|
99
|
+
"6. Summarize every package as one of: existing-skill coverage, new skill, ignored, or deferred."
|
|
100
|
+
].join("\n");
|
|
101
|
+
return [
|
|
102
|
+
"## Intent Skill Review Needed",
|
|
103
|
+
"",
|
|
104
|
+
"Intent found skills, artifact coverage, or workspace package coverage that need maintainer review.",
|
|
105
|
+
"",
|
|
106
|
+
"### Summary",
|
|
107
|
+
"",
|
|
108
|
+
"| Signal | Count |",
|
|
109
|
+
"| --- | ---: |",
|
|
110
|
+
...signalRows,
|
|
111
|
+
"",
|
|
112
|
+
"### Review Items",
|
|
113
|
+
"",
|
|
114
|
+
"| Signal | Subject | Library | Reason |",
|
|
115
|
+
"| --- | --- | --- | --- |",
|
|
116
|
+
...itemRows,
|
|
117
|
+
"",
|
|
118
|
+
"### Agent Prompt",
|
|
119
|
+
"",
|
|
120
|
+
"Paste this into your coding agent:",
|
|
121
|
+
"",
|
|
122
|
+
"```text",
|
|
123
|
+
prompt,
|
|
124
|
+
"```",
|
|
125
|
+
"",
|
|
126
|
+
"This PR is a review reminder only. It does not update skills automatically."
|
|
127
|
+
].join("\n");
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
//#endregion
|
|
14
131
|
//#region src/feedback.ts
|
|
15
132
|
const META_FEEDBACK_REPO = "TanStack/intent";
|
|
16
133
|
const SECRET_PATTERNS = [
|
|
@@ -274,4 +391,4 @@ function submitMetaFeedback(payload, opts) {
|
|
|
274
391
|
}
|
|
275
392
|
|
|
276
393
|
//#endregion
|
|
277
|
-
export { ResolveSkillUseError, SkillUseParseError, checkStaleness, containsSecrets, findSkillFiles, formatSkillUse, getDeps, hasGhCli, isResolveSkillUseError, isSkillUseParseError, metaToMarkdown, parseFrontmatter, parseSkillUse, resolveDepDir, resolveFrequency, resolveSkillUse, runEditPackageJson, runSetupGithubActions, scanForIntents, submitFeedback, submitMetaFeedback, toMarkdown, validateMetaPayload, validatePayload };
|
|
394
|
+
export { ResolveSkillUseError, SkillUseParseError, buildStaleReviewBody, checkStaleness, collectStaleReviewItems, containsSecrets, createFailedStaleReviewItem, findSkillFiles, formatSkillUse, getDeps, hasGhCli, isResolveSkillUseError, isSkillUseParseError, metaToMarkdown, parseFrontmatter, parseSkillUse, readIntentArtifacts, resolveDepDir, resolveFrequency, resolveSkillUse, runEditPackageJson, runSetupGithubActions, scanForIntents, submitFeedback, submitMetaFeedback, toMarkdown, validateMetaPayload, validatePayload };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as parseSkillUse, n as formatSkillUse } from "./skill-use-
|
|
2
|
-
import { t as resolveProjectContext } from "./project-context-
|
|
1
|
+
import { i as parseSkillUse, n as formatSkillUse } from "./skill-use-uwGleSOz.mjs";
|
|
2
|
+
import { t as resolveProjectContext } from "./project-context-IDLpJU3S.mjs";
|
|
3
3
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { dirname, join, relative, resolve } from "node:path";
|
|
5
5
|
import { parse } from "yaml";
|
|
@@ -28,11 +28,25 @@ function printWarnings(warnings) {
|
|
|
28
28
|
|
|
29
29
|
//#endregion
|
|
30
30
|
//#region src/cli-support.ts
|
|
31
|
+
const INTENT_CHECK_SKILLS_WORKFLOW_VERSION = 2;
|
|
31
32
|
function getMetaDir() {
|
|
32
33
|
return join(dirname(fileURLToPath(import.meta.url)), "..", "meta");
|
|
33
34
|
}
|
|
35
|
+
function getCheckSkillsWorkflowAdvisories(root) {
|
|
36
|
+
const workflowPath = join(root, ".github", "workflows", "check-skills.yml");
|
|
37
|
+
if (!existsSync(workflowPath)) return [];
|
|
38
|
+
let content;
|
|
39
|
+
try {
|
|
40
|
+
content = readFileSync(workflowPath, "utf8");
|
|
41
|
+
} catch {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
const versionMatch = content.match(/intent-workflow-version:\s*(\d+)/);
|
|
45
|
+
if ((versionMatch ? Number(versionMatch[1]) : 0) >= INTENT_CHECK_SKILLS_WORKFLOW_VERSION) return [];
|
|
46
|
+
return [`Intent workflow update available: run \`npx @tanstack/intent@latest setup\` to refresh ${relative(process.cwd(), workflowPath) || workflowPath}.`];
|
|
47
|
+
}
|
|
34
48
|
async function scanIntentsOrFail(options) {
|
|
35
|
-
const { scanForIntents } = await import("./scanner-
|
|
49
|
+
const { scanForIntents } = await import("./scanner-DlkcbVye.mjs");
|
|
36
50
|
try {
|
|
37
51
|
return scanForIntents(void 0, options);
|
|
38
52
|
} catch (err) {
|
|
@@ -45,31 +59,53 @@ function scanOptionsFromGlobalFlags(options) {
|
|
|
45
59
|
if (options.global) return { scope: "local-and-global" };
|
|
46
60
|
return { scope: "local" };
|
|
47
61
|
}
|
|
48
|
-
function readPackageName(root) {
|
|
49
|
-
try {
|
|
50
|
-
const pkgJson = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
|
|
51
|
-
return typeof pkgJson.name === "string" ? pkgJson.name : relative(process.cwd(), root) || "unknown";
|
|
52
|
-
} catch {
|
|
53
|
-
return relative(process.cwd(), root) || "unknown";
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
62
|
async function resolveStaleTargets(targetDir) {
|
|
57
63
|
const resolvedRoot = targetDir ? resolve(process.cwd(), targetDir) : process.cwd();
|
|
58
64
|
const context = resolveProjectContext({
|
|
59
65
|
cwd: process.cwd(),
|
|
60
66
|
targetPath: targetDir
|
|
61
67
|
});
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
68
|
+
const workflowAdvisories = getCheckSkillsWorkflowAdvisories(context.workspaceRoot ?? context.packageRoot ?? resolvedRoot);
|
|
69
|
+
const { buildWorkspaceCoverageSignals, checkStaleness, readPackageName } = await import("./staleness-DpbmYod4.mjs");
|
|
70
|
+
const isWorkspaceRootTarget = context.workspaceRoot !== null && resolvedRoot === context.workspaceRoot;
|
|
71
|
+
if (context.packageRoot && !isWorkspaceRootTarget && (context.targetSkillsDir !== null || context.workspaceRoot === null)) return {
|
|
72
|
+
reports: [await checkStaleness(context.packageRoot, readPackageName(context.packageRoot), context.workspaceRoot ?? context.packageRoot)],
|
|
73
|
+
workflowAdvisories
|
|
74
|
+
};
|
|
75
|
+
const { findPackagesWithSkills, findWorkspacePackages, findWorkspaceRoot } = await import("./workspace-patterns-x-dLZxx4.mjs");
|
|
66
76
|
const workspaceRoot = findWorkspaceRoot(resolvedRoot);
|
|
67
77
|
if (workspaceRoot) {
|
|
68
|
-
const
|
|
69
|
-
|
|
78
|
+
const packageDirsWithSkills = findPackagesWithSkills(workspaceRoot);
|
|
79
|
+
const allPackageDirs = findWorkspacePackages(workspaceRoot);
|
|
80
|
+
const reports = await Promise.all(packageDirsWithSkills.map((packageDir) => checkStaleness(packageDir, readPackageName(packageDir), workspaceRoot)));
|
|
81
|
+
const { readIntentArtifacts } = await import("./artifact-coverage-BAN2W6aH.mjs");
|
|
82
|
+
const coverageSignals = buildWorkspaceCoverageSignals({
|
|
83
|
+
artifactRoot: workspaceRoot,
|
|
84
|
+
artifacts: existsSync(join(workspaceRoot, "_artifacts")) ? readIntentArtifacts(workspaceRoot) : null,
|
|
85
|
+
packageDirs: allPackageDirs
|
|
86
|
+
});
|
|
87
|
+
if (coverageSignals.length > 0) reports.push({
|
|
88
|
+
library: relative(process.cwd(), workspaceRoot) || "workspace",
|
|
89
|
+
currentVersion: null,
|
|
90
|
+
skillVersion: null,
|
|
91
|
+
versionDrift: null,
|
|
92
|
+
skills: [],
|
|
93
|
+
signals: coverageSignals
|
|
94
|
+
});
|
|
95
|
+
if (reports.length > 0) return {
|
|
96
|
+
reports,
|
|
97
|
+
workflowAdvisories
|
|
98
|
+
};
|
|
70
99
|
}
|
|
100
|
+
if (existsSync(join(resolvedRoot, "skills"))) return {
|
|
101
|
+
reports: [await checkStaleness(resolvedRoot, readPackageName(resolvedRoot))],
|
|
102
|
+
workflowAdvisories
|
|
103
|
+
};
|
|
71
104
|
const staleResult = await scanIntentsOrFail();
|
|
72
|
-
return {
|
|
105
|
+
return {
|
|
106
|
+
reports: await Promise.all(staleResult.packages.map((pkg) => checkStaleness(pkg.packageRoot, pkg.name))),
|
|
107
|
+
workflowAdvisories
|
|
108
|
+
};
|
|
73
109
|
}
|
|
74
110
|
|
|
75
111
|
//#endregion
|
package/dist/intent-library.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import "./utils-COlDcU72.mjs";
|
|
3
3
|
import "./skill-paths-8k9K9y26.mjs";
|
|
4
|
-
import "./workspace-patterns-
|
|
5
|
-
import "./project-context-
|
|
6
|
-
import { t as INSTALL_PROMPT } from "./install-
|
|
7
|
-
import { n as printSkillTree, r as printTable, t as computeSkillNameWidth } from "./display-
|
|
8
|
-
import { t as scanLibrary } from "./library-scanner-
|
|
4
|
+
import "./workspace-patterns-BN2A_60g.mjs";
|
|
5
|
+
import "./project-context-IDLpJU3S.mjs";
|
|
6
|
+
import { t as INSTALL_PROMPT } from "./install-PUnIfBNC.mjs";
|
|
7
|
+
import { n as printSkillTree, r as printTable, t as computeSkillNameWidth } from "./display-BTZWCjzT.mjs";
|
|
8
|
+
import { t as scanLibrary } from "./library-scanner-Cl-XPEMf.mjs";
|
|
9
9
|
|
|
10
10
|
//#region src/intent-library.ts
|
|
11
11
|
function cmdList() {
|
package/dist/library-scanner.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i as readWorkspacePatterns, r as findWorkspaceRoot } from "./workspace-patterns-BN2A_60g.mjs";
|
|
2
2
|
import { existsSync, statSync } from "node:fs";
|
|
3
3
|
import { dirname, join, relative, resolve } from "node:path";
|
|
4
4
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as parseFrontmatter, i as listNodeModulesPackageDirs, o as resolveDepDir, r as getDeps, s as toPosixPath, t as detectGlobalNodeModules } from "./utils-COlDcU72.mjs";
|
|
2
2
|
import { r as rewriteSkillLoadPaths } from "./skill-paths-8k9K9y26.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { a as resolveWorkspacePackages, i as readWorkspacePatterns, r as findWorkspaceRoot } from "./workspace-patterns-BN2A_60g.mjs";
|
|
4
4
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
5
5
|
import { join, relative, sep } from "node:path";
|
|
6
6
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as resolveProjectContext } from "./project-context-
|
|
1
|
+
import { i as readWorkspacePatterns, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-BN2A_60g.mjs";
|
|
2
|
+
import { t as resolveProjectContext } from "./project-context-IDLpJU3S.mjs";
|
|
3
3
|
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { basename, join, relative } from "node:path";
|
|
5
5
|
|
package/dist/setup.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as runEditPackageJsonAll, c as findWorkspaceRoot, i as runEditPackageJson, l as readWorkspacePatterns, n as MonorepoResult, o as runSetupGithubActions, r as SetupGithubActionsResult, s as findPackagesWithSkills, t as EditPackageJsonResult, u as resolveWorkspacePackages } from "./setup-
|
|
1
|
+
import { a as runEditPackageJsonAll, c as findWorkspaceRoot, i as runEditPackageJson, l as readWorkspacePatterns, n as MonorepoResult, o as runSetupGithubActions, r as SetupGithubActionsResult, s as findPackagesWithSkills, t as EditPackageJsonResult, u as resolveWorkspacePackages } from "./setup-D2CGdTsx.mjs";
|
|
2
2
|
export { EditPackageJsonResult, MonorepoResult, SetupGithubActionsResult, findPackagesWithSkills, findWorkspaceRoot, readWorkspacePatterns, resolveWorkspacePackages, runEditPackageJson, runEditPackageJsonAll, runSetupGithubActions };
|
package/dist/setup.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "./utils-COlDcU72.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import "./project-context-
|
|
4
|
-
import { n as runEditPackageJsonAll, r as runSetupGithubActions, t as runEditPackageJson } from "./setup-
|
|
2
|
+
import { a as resolveWorkspacePackages, i as readWorkspacePatterns, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-BN2A_60g.mjs";
|
|
3
|
+
import "./project-context-IDLpJU3S.mjs";
|
|
4
|
+
import { n as runEditPackageJsonAll, r as runSetupGithubActions, t as runEditPackageJson } from "./setup-DfLsziXU.mjs";
|
|
5
5
|
|
|
6
6
|
export { findPackagesWithSkills, findWorkspaceRoot, readWorkspacePatterns, resolveWorkspacePackages, runEditPackageJson, runEditPackageJsonAll, runSetupGithubActions };
|