@tanstack/intent 0.0.32 → 0.0.34
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 +248 -99
- package/dist/{display-DCRCp4-C.mjs → display-B3vkG99D.mjs} +1 -1
- package/dist/index.d.mts +22 -4
- package/dist/index.mjs +10 -8
- package/dist/{install-BmVqcbEi.mjs → install-QjryhQtg.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-alYMNoNa.mjs} +1 -1
- package/dist/{resolver-aFigTqXi.mjs → resolver-Whd12ksO.mjs} +1 -1
- package/dist/scanner-BAZxWeUk.mjs +6 -0
- package/dist/{scanner-DKL8v8is.mjs → scanner-Dav1tzQK.mjs} +79 -4
- package/dist/{setup-JJvjiGkM.mjs → setup-Dp-W8y0Y.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-DT7Y6TFz.d.mts} +48 -1
- package/dist/workflow-review-CwkPVIQf.mjs +153 -0
- package/dist/workflow-review-Dz_ofcYQ.mjs +3 -0
- 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 +58 -96
- 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/meta/templates/workflows/validate-skills.yml +0 -52
- /package/dist/{display-DUgtRJkt.mjs → display-CAof6doy.mjs} +0 -0
- /package/dist/{library-scanner-DFFreLjW.mjs → library-scanner-fexXlPXb.mjs} +0 -0
- /package/dist/{setup-DDoOLriA.d.mts → setup-t1i2o2-h.d.mts} +0 -0
- /package/dist/{skill-use-CXOnncWK.mjs → skill-use-BzuuvLM7.mjs} +0 -0
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
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 { r as
|
|
3
|
+
import { t as scanForIntents } from "./scanner-Dav1tzQK.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 { n as collectStaleReviewItems, r as createFailedStaleReviewItem, t as buildStaleReviewBody } from "./workflow-review-CwkPVIQf.mjs";
|
|
8
|
+
import { i as parseSkillUse, n as formatSkillUse, r as isSkillUseParseError, t as SkillUseParseError } from "./skill-use-BzuuvLM7.mjs";
|
|
9
|
+
import { n as isResolveSkillUseError, r as resolveSkillUse, t as ResolveSkillUseError } from "./resolver-Whd12ksO.mjs";
|
|
10
|
+
import "./project-context-alYMNoNa.mjs";
|
|
11
|
+
import { r as runSetupGithubActions, t as runEditPackageJson } from "./setup-Dp-W8y0Y.mjs";
|
|
10
12
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
11
13
|
import { join } from "node:path";
|
|
12
14
|
import { execFileSync, execSync } from "node:child_process";
|
|
@@ -274,4 +276,4 @@ function submitMetaFeedback(payload, opts) {
|
|
|
274
276
|
}
|
|
275
277
|
|
|
276
278
|
//#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 };
|
|
279
|
+
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-BzuuvLM7.mjs";
|
|
2
|
+
import { t as resolveProjectContext } from "./project-context-alYMNoNa.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 = 3;
|
|
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-BAZxWeUk.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-alYMNoNa.mjs";
|
|
6
|
+
import { t as INSTALL_PROMPT } from "./install-QjryhQtg.mjs";
|
|
7
|
+
import { n as printSkillTree, r as printTable, t as computeSkillNameWidth } from "./display-CAof6doy.mjs";
|
|
8
|
+
import { t as scanLibrary } from "./library-scanner-fexXlPXb.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,8 +1,9 @@
|
|
|
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
|
+
import { createRequire } from "node:module";
|
|
4
5
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
5
|
-
import { join, relative, sep } from "node:path";
|
|
6
|
+
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
6
7
|
|
|
7
8
|
//#region src/discovery/register.ts
|
|
8
9
|
function isLocalToProject(dirPath, projectRoot) {
|
|
@@ -132,13 +133,31 @@ function createDependencyWalker(opts) {
|
|
|
132
133
|
|
|
133
134
|
//#endregion
|
|
134
135
|
//#region src/scanner.ts
|
|
135
|
-
|
|
136
|
-
|
|
136
|
+
const requireFromHere = createRequire(import.meta.url);
|
|
137
|
+
function findPnpFile(start) {
|
|
138
|
+
let dir = resolve(start);
|
|
139
|
+
while (true) {
|
|
140
|
+
for (const fileName of [".pnp.cjs", ".pnp.js"]) {
|
|
141
|
+
const pnpPath = join(dir, fileName);
|
|
142
|
+
if (existsSync(pnpPath)) return pnpPath;
|
|
143
|
+
}
|
|
144
|
+
const next = dirname(dir);
|
|
145
|
+
if (next === dir) return null;
|
|
146
|
+
dir = next;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function isYarnPnpProject(root) {
|
|
150
|
+
return findPnpFile(root) !== null;
|
|
151
|
+
}
|
|
152
|
+
function assertLocalNodeModulesSupported(root) {
|
|
137
153
|
if (existsSync(join(root, "deno.json")) && !existsSync(join(root, "node_modules"))) throw new Error("Deno without node_modules is not yet supported. Add `\"nodeModulesDir\": \"auto\"` to your deno.json to use intent.");
|
|
154
|
+
}
|
|
155
|
+
function detectPackageManager(root) {
|
|
138
156
|
const dirsToCheck = [root];
|
|
139
157
|
const wsRoot = findWorkspaceRoot(root);
|
|
140
158
|
if (wsRoot && wsRoot !== root) dirsToCheck.push(wsRoot);
|
|
141
159
|
for (const dir of dirsToCheck) {
|
|
160
|
+
if (isYarnPnpProject(dir)) return "yarn";
|
|
142
161
|
if (existsSync(join(dir, "pnpm-lock.yaml"))) return "pnpm";
|
|
143
162
|
if (existsSync(join(dir, "bun.lockb")) || existsSync(join(dir, "bun.lock"))) return "bun";
|
|
144
163
|
if (existsSync(join(dir, "yarn.lock"))) return "yarn";
|
|
@@ -146,6 +165,35 @@ function detectPackageManager(root) {
|
|
|
146
165
|
}
|
|
147
166
|
return "unknown";
|
|
148
167
|
}
|
|
168
|
+
function loadPnpApi(root) {
|
|
169
|
+
const pnpPath = findPnpFile(root);
|
|
170
|
+
if (!pnpPath) return null;
|
|
171
|
+
try {
|
|
172
|
+
const foundApi = requireFromHere("node:module").findPnpApi?.(root);
|
|
173
|
+
if (foundApi) return foundApi;
|
|
174
|
+
const pnpModule = requireFromHere(pnpPath);
|
|
175
|
+
if (typeof pnpModule.setup === "function") pnpModule.setup();
|
|
176
|
+
if (typeof pnpModule.getDependencyTreeRoots === "function" && typeof pnpModule.getPackageInformation === "function") return pnpModule;
|
|
177
|
+
return createRequire(join(dirname(pnpPath), "package.json"))("pnpapi");
|
|
178
|
+
} catch (err) {
|
|
179
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
180
|
+
throw new Error(`Yarn PnP project detected, but Intent could not load Yarn's PnP API from ${pnpPath}: ${msg}`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function getPnpLocatorKey(locator) {
|
|
184
|
+
return `${locator.name ?? "<top>"}@${locator.reference ?? "<top>"}`;
|
|
185
|
+
}
|
|
186
|
+
function getPnpDependencyLocator(dependencyName, target) {
|
|
187
|
+
if (target === null) return null;
|
|
188
|
+
if (Array.isArray(target)) return {
|
|
189
|
+
name: target[0],
|
|
190
|
+
reference: target[1]
|
|
191
|
+
};
|
|
192
|
+
return {
|
|
193
|
+
name: dependencyName,
|
|
194
|
+
reference: target
|
|
195
|
+
};
|
|
196
|
+
}
|
|
149
197
|
function validateIntentField(_pkgName, intent) {
|
|
150
198
|
if (!intent || typeof intent !== "object") return null;
|
|
151
199
|
const pb = intent;
|
|
@@ -304,6 +352,7 @@ function scanForIntents(root, options = {}) {
|
|
|
304
352
|
const projectRoot = root ?? process.cwd();
|
|
305
353
|
const scanScope = getScanScope(options);
|
|
306
354
|
const packageManager = detectPackageManager(projectRoot);
|
|
355
|
+
const pnpApi = scanScope === "global" ? null : loadPnpApi(projectRoot);
|
|
307
356
|
const nodeModulesDir = join(projectRoot, "node_modules");
|
|
308
357
|
const explicitGlobalNodeModules = process.env.INTENT_GLOBAL_NODE_MODULES?.trim() || null;
|
|
309
358
|
const packages = [];
|
|
@@ -378,7 +427,33 @@ function scanForIntents(root, options = {}) {
|
|
|
378
427
|
tryRegister,
|
|
379
428
|
warnings
|
|
380
429
|
});
|
|
430
|
+
function scanPnpPackages() {
|
|
431
|
+
if (!pnpApi) return;
|
|
432
|
+
const api = pnpApi;
|
|
433
|
+
const visited = /* @__PURE__ */ new Set();
|
|
434
|
+
const workspaceRoot = findWorkspaceRoot(projectRoot);
|
|
435
|
+
const projectLocator = api.findPackageLocator?.(projectRoot.endsWith(sep) ? projectRoot : `${projectRoot}${sep}`);
|
|
436
|
+
const roots = workspaceRoot && workspaceRoot !== projectRoot && projectLocator ? [projectLocator] : api.getDependencyTreeRoots?.() ?? (api.topLevel ? [api.topLevel] : []);
|
|
437
|
+
function visit(locator) {
|
|
438
|
+
const key = getPnpLocatorKey(locator);
|
|
439
|
+
if (visited.has(key)) return;
|
|
440
|
+
visited.add(key);
|
|
441
|
+
const info = api.getPackageInformation(locator);
|
|
442
|
+
if (!info) return;
|
|
443
|
+
tryRegister(info.packageLocation.replace(/[\\/]$/, ""), locator.name ?? "unknown");
|
|
444
|
+
for (const [dependencyName, target] of info.packageDependencies) {
|
|
445
|
+
const dependencyLocator = getPnpDependencyLocator(dependencyName, target);
|
|
446
|
+
if (dependencyLocator) visit(dependencyLocator);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
for (const locator of roots) visit(locator);
|
|
450
|
+
}
|
|
381
451
|
function scanLocalPackages() {
|
|
452
|
+
if (pnpApi && !nodeModules.local.exists) {
|
|
453
|
+
scanPnpPackages();
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
assertLocalNodeModulesSupported(projectRoot);
|
|
382
457
|
scanTarget(nodeModules.local);
|
|
383
458
|
walkWorkspacePackages();
|
|
384
459
|
walkKnownPackages();
|
|
@@ -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-alYMNoNa.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-t1i2o2-h.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-alYMNoNa.mjs";
|
|
4
|
+
import { n as runEditPackageJsonAll, r as runSetupGithubActions, t as runEditPackageJson } from "./setup-Dp-W8y0Y.mjs";
|
|
5
5
|
|
|
6
6
|
export { findPackagesWithSkills, findWorkspaceRoot, readWorkspacePatterns, resolveWorkspacePackages, runEditPackageJson, runEditPackageJsonAll, runSetupGithubActions };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import "./utils-COlDcU72.mjs";
|
|
2
|
+
import "./artifact-coverage-wLNVX8yC.mjs";
|
|
3
|
+
import { n as checkStaleness, r as readPackageName, t as buildWorkspaceCoverageSignals } from "./staleness-PdgakrCQ.mjs";
|
|
4
|
+
|
|
5
|
+
export { buildWorkspaceCoverageSignals, checkStaleness, readPackageName };
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { a as parseFrontmatter, n as findSkillFiles } from "./utils-COlDcU72.mjs";
|
|
2
|
+
import { t as readIntentArtifacts } from "./artifact-coverage-wLNVX8yC.mjs";
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
|
+
import { isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
5
|
+
|
|
6
|
+
//#region src/staleness.ts
|
|
7
|
+
function classifyVersionDrift(oldVer, newVer) {
|
|
8
|
+
if (oldVer === newVer) return null;
|
|
9
|
+
const oldParts = oldVer.replace(/[^0-9.]/g, "").split(".").map(Number);
|
|
10
|
+
const newParts = newVer.replace(/[^0-9.]/g, "").split(".").map(Number);
|
|
11
|
+
if ((newParts[0] ?? 0) > (oldParts[0] ?? 0)) return "major";
|
|
12
|
+
if ((newParts[1] ?? 0) > (oldParts[1] ?? 0)) return "minor";
|
|
13
|
+
if ((newParts[2] ?? 0) > (oldParts[2] ?? 0)) return "patch";
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
function readLocalVersion(packageDir) {
|
|
17
|
+
try {
|
|
18
|
+
const pkgJson = JSON.parse(readFileSync(join(packageDir, "package.json"), "utf8"));
|
|
19
|
+
return typeof pkgJson.version === "string" ? pkgJson.version : null;
|
|
20
|
+
} catch {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async function fetchNpmVersion(packageName) {
|
|
25
|
+
try {
|
|
26
|
+
const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`);
|
|
27
|
+
if (!res.ok) return null;
|
|
28
|
+
const data = await res.json();
|
|
29
|
+
return typeof data.version === "string" ? data.version : null;
|
|
30
|
+
} catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async function fetchCurrentVersion(packageDir, packageName) {
|
|
35
|
+
return readLocalVersion(packageDir) ?? await fetchNpmVersion(packageName);
|
|
36
|
+
}
|
|
37
|
+
function isStringRecord(value) {
|
|
38
|
+
return !!value && typeof value === "object" && !Array.isArray(value) && Object.values(value).every((entry) => typeof entry === "string");
|
|
39
|
+
}
|
|
40
|
+
function parseSyncState(value) {
|
|
41
|
+
if (!value || typeof value !== "object") return null;
|
|
42
|
+
const raw = value;
|
|
43
|
+
const parsed = {};
|
|
44
|
+
if (typeof raw.library_version === "string") parsed.library_version = raw.library_version;
|
|
45
|
+
if (raw.skills && typeof raw.skills === "object") {
|
|
46
|
+
const skills = {};
|
|
47
|
+
for (const [skillName, skillValue] of Object.entries(raw.skills)) {
|
|
48
|
+
if (!skillValue || typeof skillValue !== "object") continue;
|
|
49
|
+
const sourcesSha = skillValue.sources_sha;
|
|
50
|
+
if (sourcesSha !== void 0 && !isStringRecord(sourcesSha)) continue;
|
|
51
|
+
skills[skillName] = {};
|
|
52
|
+
if (sourcesSha) skills[skillName].sources_sha = sourcesSha;
|
|
53
|
+
}
|
|
54
|
+
parsed.skills = skills;
|
|
55
|
+
}
|
|
56
|
+
return parsed;
|
|
57
|
+
}
|
|
58
|
+
function readSyncState(packageDir) {
|
|
59
|
+
const statePath = join(packageDir, "skills", "sync-state.json");
|
|
60
|
+
try {
|
|
61
|
+
return parseSyncState(JSON.parse(readFileSync(statePath, "utf8")));
|
|
62
|
+
} catch {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function readPackageName(packageDir) {
|
|
67
|
+
const packageJson = readPackageJson(packageDir);
|
|
68
|
+
return typeof packageJson?.name === "string" ? packageJson.name : relative(process.cwd(), packageDir) || "unknown";
|
|
69
|
+
}
|
|
70
|
+
function readPackageJson(packageDir) {
|
|
71
|
+
try {
|
|
72
|
+
return JSON.parse(readFileSync(join(packageDir, "package.json"), "utf8"));
|
|
73
|
+
} catch {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function normalizeFilePath(path) {
|
|
78
|
+
return resolve(path).split(sep).join("/");
|
|
79
|
+
}
|
|
80
|
+
function normalizeList(values) {
|
|
81
|
+
return [...new Set(values ?? [])].sort((a, b) => a.localeCompare(b));
|
|
82
|
+
}
|
|
83
|
+
function sameStringList(a, b) {
|
|
84
|
+
const left = normalizeList(a);
|
|
85
|
+
const right = normalizeList(b);
|
|
86
|
+
return left.length === right.length && left.every((value, index) => value === right[index]);
|
|
87
|
+
}
|
|
88
|
+
function artifactPackageMatches(artifact, packageDir, packageName, artifactRoot) {
|
|
89
|
+
const relPackageDir = relative(artifactRoot, packageDir).split(sep).join("/");
|
|
90
|
+
if (!relPackageDir) return true;
|
|
91
|
+
if (artifact.packages.includes(packageName)) return true;
|
|
92
|
+
if (artifact.packages.includes(relPackageDir)) return true;
|
|
93
|
+
if (artifact.path?.startsWith(`${relPackageDir}/`)) return true;
|
|
94
|
+
return artifact.packages.length === 0 && artifact.path === void 0;
|
|
95
|
+
}
|
|
96
|
+
function resolveArtifactSkillPaths(artifact, packageDir, artifactRoot) {
|
|
97
|
+
if (!artifact.path) return [];
|
|
98
|
+
const candidatePaths = [isAbsolute(artifact.path) ? artifact.path : join(artifactRoot, artifact.path), isAbsolute(artifact.path) ? artifact.path : join(packageDir, artifact.path)];
|
|
99
|
+
if (artifact.package && artifact.path.startsWith("skills/")) candidatePaths.push(join(artifactRoot, artifact.package, artifact.path));
|
|
100
|
+
return [...new Set(candidatePaths.map(normalizeFilePath))];
|
|
101
|
+
}
|
|
102
|
+
function findMatchingSkill(artifact, skillMetas, packageDir, artifactRoot) {
|
|
103
|
+
const skillsByPath = new Map(skillMetas.map((skill) => [normalizeFilePath(skill.filePath), skill]));
|
|
104
|
+
for (const candidatePath of resolveArtifactSkillPaths(artifact, packageDir, artifactRoot)) {
|
|
105
|
+
const match = skillsByPath.get(candidatePath);
|
|
106
|
+
if (match) return match;
|
|
107
|
+
}
|
|
108
|
+
const skillsByName = /* @__PURE__ */ new Map();
|
|
109
|
+
for (const skill of skillMetas) {
|
|
110
|
+
skillsByName.set(skill.name, skill);
|
|
111
|
+
skillsByName.set(skill.relName, skill);
|
|
112
|
+
}
|
|
113
|
+
return (artifact.slug ? skillsByName.get(artifact.slug) : void 0) ?? (artifact.name ? skillsByName.get(artifact.name) : void 0) ?? null;
|
|
114
|
+
}
|
|
115
|
+
function buildArtifactSignals({ artifactRoot, artifacts, library, packageDir, skillMetas }) {
|
|
116
|
+
if (!artifacts) return [];
|
|
117
|
+
const artifactFiles = new Map([...artifacts.skillTrees, ...artifacts.domainMaps].map((file) => [file.path, file]));
|
|
118
|
+
const signals = artifacts.warnings.map((warning) => ({
|
|
119
|
+
type: "artifact-parse-warning",
|
|
120
|
+
library,
|
|
121
|
+
subject: warning.artifactPath,
|
|
122
|
+
reasons: [warning.message],
|
|
123
|
+
needsReview: true,
|
|
124
|
+
artifactPath: warning.artifactPath
|
|
125
|
+
}));
|
|
126
|
+
for (const artifact of artifacts.skills) {
|
|
127
|
+
if (!artifactPackageMatches(artifact, packageDir, library, artifactRoot)) continue;
|
|
128
|
+
const subject = artifact.slug ?? artifact.name ?? artifact.path;
|
|
129
|
+
const matchingSkill = findMatchingSkill(artifact, skillMetas, packageDir, artifactRoot);
|
|
130
|
+
if (artifact.path && !matchingSkill) {
|
|
131
|
+
signals.push({
|
|
132
|
+
type: "artifact-skill-missing",
|
|
133
|
+
library,
|
|
134
|
+
subject,
|
|
135
|
+
reasons: [`artifact skill path does not resolve to a generated SKILL.md (${artifact.path})`],
|
|
136
|
+
needsReview: true,
|
|
137
|
+
artifactPath: artifact.artifactPath,
|
|
138
|
+
skill: artifact.slug ?? artifact.name
|
|
139
|
+
});
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (!matchingSkill) continue;
|
|
143
|
+
if (matchingSkill.sources !== void 0 && artifact.sources.length > 0 && !sameStringList(matchingSkill.sources, artifact.sources)) signals.push({
|
|
144
|
+
type: "artifact-source-drift",
|
|
145
|
+
library,
|
|
146
|
+
subject,
|
|
147
|
+
reasons: ["artifact sources differ from SKILL.md frontmatter sources"],
|
|
148
|
+
needsReview: true,
|
|
149
|
+
artifactPath: artifact.artifactPath,
|
|
150
|
+
skill: matchingSkill.name
|
|
151
|
+
});
|
|
152
|
+
const artifactVersion = artifactFiles.get(artifact.artifactPath)?.libraryVersion;
|
|
153
|
+
if (artifactVersion && matchingSkill.libraryVersion && artifactVersion !== matchingSkill.libraryVersion) signals.push({
|
|
154
|
+
type: "artifact-library-version-drift",
|
|
155
|
+
library,
|
|
156
|
+
subject,
|
|
157
|
+
reasons: [`artifact library.version (${artifactVersion}) differs from SKILL.md library_version (${matchingSkill.libraryVersion})`],
|
|
158
|
+
needsReview: true,
|
|
159
|
+
artifactPath: artifact.artifactPath,
|
|
160
|
+
skill: matchingSkill.name
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
return signals;
|
|
164
|
+
}
|
|
165
|
+
function artifactCoversPackage(artifact, packageDir, packageName, artifactRoot) {
|
|
166
|
+
const relPackageDir = relative(artifactRoot, packageDir).split(sep).join("/");
|
|
167
|
+
return artifact.packages.includes(packageName) || artifact.packages.includes(relPackageDir) || artifact.package === packageName || artifact.package === relPackageDir || artifact.path?.startsWith(`${relPackageDir}/`) === true;
|
|
168
|
+
}
|
|
169
|
+
function artifactIgnoresPackage(artifacts, packageDir, packageName, artifactRoot) {
|
|
170
|
+
const relPackageDir = relative(artifactRoot, packageDir).split(sep).join("/");
|
|
171
|
+
return artifacts.ignoredPackages.some((ignored) => ignored.packageName === packageName || ignored.packageName === relPackageDir);
|
|
172
|
+
}
|
|
173
|
+
function buildWorkspaceCoverageSignals({ artifactRoot, artifacts, packageDirs }) {
|
|
174
|
+
if (!artifacts) return [];
|
|
175
|
+
const signals = [];
|
|
176
|
+
for (const packageDir of packageDirs) {
|
|
177
|
+
if (readPackageJson(packageDir)?.private === true) continue;
|
|
178
|
+
const packageName = readPackageName(packageDir);
|
|
179
|
+
if (artifactIgnoresPackage(artifacts, packageDir, packageName, artifactRoot)) continue;
|
|
180
|
+
const hasGeneratedSkill = findSkillFiles(join(packageDir, "skills")).length > 0;
|
|
181
|
+
const hasArtifactCoverage = artifacts.skills.some((artifact) => artifactCoversPackage(artifact, packageDir, packageName, artifactRoot));
|
|
182
|
+
if (hasGeneratedSkill || hasArtifactCoverage) continue;
|
|
183
|
+
signals.push({
|
|
184
|
+
type: "missing-package-coverage",
|
|
185
|
+
library: packageName,
|
|
186
|
+
subject: packageName,
|
|
187
|
+
reasons: ["workspace package is not represented by generated skills or _artifacts coverage"],
|
|
188
|
+
needsReview: true,
|
|
189
|
+
packageName,
|
|
190
|
+
packageRoot: relative(artifactRoot, packageDir).split(sep).join("/")
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
return signals;
|
|
194
|
+
}
|
|
195
|
+
async function checkStaleness(packageDir, packageName, artifactRoot = packageDir) {
|
|
196
|
+
const skillsDir = join(packageDir, "skills");
|
|
197
|
+
const library = packageName ?? "unknown";
|
|
198
|
+
const skillMetas = findSkillFiles(skillsDir).map((filePath) => {
|
|
199
|
+
const fm = parseFrontmatter(filePath);
|
|
200
|
+
const relName = relative(skillsDir, filePath).replace(/[/\\]SKILL\.md$/, "").split(sep).join("/");
|
|
201
|
+
return {
|
|
202
|
+
name: typeof fm?.name === "string" ? fm.name : relName,
|
|
203
|
+
relName,
|
|
204
|
+
filePath,
|
|
205
|
+
libraryVersion: fm?.library_version,
|
|
206
|
+
sources: Array.isArray(fm?.sources) ? fm.sources : void 0
|
|
207
|
+
};
|
|
208
|
+
});
|
|
209
|
+
const artifacts = existsSync(join(artifactRoot, "_artifacts")) ? readIntentArtifacts(artifactRoot) : null;
|
|
210
|
+
const skillVersion = skillMetas.find((s) => s.libraryVersion)?.libraryVersion ?? null;
|
|
211
|
+
const currentVersion = await fetchCurrentVersion(packageDir, library);
|
|
212
|
+
const versionDrift = skillVersion && currentVersion ? classifyVersionDrift(skillVersion, currentVersion) : null;
|
|
213
|
+
const syncState = readSyncState(packageDir);
|
|
214
|
+
return {
|
|
215
|
+
library,
|
|
216
|
+
currentVersion,
|
|
217
|
+
skillVersion,
|
|
218
|
+
versionDrift,
|
|
219
|
+
skills: skillMetas.map((skill) => {
|
|
220
|
+
const reasons = [];
|
|
221
|
+
if (currentVersion && skill.libraryVersion && skill.libraryVersion !== currentVersion) reasons.push(`version drift (${skill.libraryVersion} → ${currentVersion})`);
|
|
222
|
+
const storedShas = syncState?.skills?.[skill.name]?.sources_sha ?? {};
|
|
223
|
+
if (skill.sources && Object.keys(storedShas).length > 0) {
|
|
224
|
+
for (const source of skill.sources) if (!storedShas[source]) reasons.push(`new source (${source})`);
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
name: skill.name,
|
|
228
|
+
reasons,
|
|
229
|
+
needsReview: reasons.length > 0
|
|
230
|
+
};
|
|
231
|
+
}),
|
|
232
|
+
signals: buildArtifactSignals({
|
|
233
|
+
artifactRoot,
|
|
234
|
+
artifacts,
|
|
235
|
+
library,
|
|
236
|
+
packageDir,
|
|
237
|
+
skillMetas
|
|
238
|
+
})
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
//#endregion
|
|
243
|
+
export { checkStaleness as n, readPackageName as r, buildWorkspaceCoverageSignals as t };
|
|
@@ -57,12 +57,59 @@ interface StalenessReport {
|
|
|
57
57
|
skillVersion: string | null;
|
|
58
58
|
versionDrift: 'major' | 'minor' | 'patch' | null;
|
|
59
59
|
skills: Array<SkillStaleness>;
|
|
60
|
+
signals: Array<StalenessSignal>;
|
|
60
61
|
}
|
|
61
62
|
interface SkillStaleness {
|
|
62
63
|
name: string;
|
|
63
64
|
reasons: Array<string>;
|
|
64
65
|
needsReview: boolean;
|
|
65
66
|
}
|
|
67
|
+
interface StalenessSignal {
|
|
68
|
+
type: string;
|
|
69
|
+
library?: string;
|
|
70
|
+
subject?: string;
|
|
71
|
+
reasons: Array<string>;
|
|
72
|
+
needsReview: boolean;
|
|
73
|
+
artifactPath?: string;
|
|
74
|
+
packageName?: string;
|
|
75
|
+
packageRoot?: string;
|
|
76
|
+
skill?: string;
|
|
77
|
+
}
|
|
78
|
+
interface IntentArtifactSet {
|
|
79
|
+
root: string;
|
|
80
|
+
artifactsDir: string;
|
|
81
|
+
skillTrees: Array<IntentArtifactFile>;
|
|
82
|
+
domainMaps: Array<IntentArtifactFile>;
|
|
83
|
+
skills: Array<IntentArtifactSkill>;
|
|
84
|
+
ignoredPackages: Array<IntentArtifactCoverageIgnore>;
|
|
85
|
+
warnings: Array<IntentArtifactWarning>;
|
|
86
|
+
}
|
|
87
|
+
interface IntentArtifactFile {
|
|
88
|
+
path: string;
|
|
89
|
+
kind: 'skill-tree' | 'domain-map';
|
|
90
|
+
libraryName?: string;
|
|
91
|
+
libraryVersion?: string;
|
|
92
|
+
}
|
|
93
|
+
interface IntentArtifactSkill {
|
|
94
|
+
artifactPath: string;
|
|
95
|
+
artifactKind: 'skill-tree' | 'domain-map';
|
|
96
|
+
name?: string;
|
|
97
|
+
slug?: string;
|
|
98
|
+
path?: string;
|
|
99
|
+
package?: string;
|
|
100
|
+
packages: Array<string>;
|
|
101
|
+
sources: Array<string>;
|
|
102
|
+
covers: Array<string>;
|
|
103
|
+
}
|
|
104
|
+
interface IntentArtifactCoverageIgnore {
|
|
105
|
+
packageName: string;
|
|
106
|
+
reason?: string;
|
|
107
|
+
artifactPath: string;
|
|
108
|
+
}
|
|
109
|
+
interface IntentArtifactWarning {
|
|
110
|
+
artifactPath: string;
|
|
111
|
+
message: string;
|
|
112
|
+
}
|
|
66
113
|
interface FeedbackPayload {
|
|
67
114
|
skill: string;
|
|
68
115
|
package: string;
|
|
@@ -96,4 +143,4 @@ interface IntentProjectConfig {
|
|
|
96
143
|
};
|
|
97
144
|
}
|
|
98
145
|
//#endregion
|
|
99
|
-
export {
|
|
146
|
+
export { StalenessReport as _, IntentArtifactSet as a, IntentConfig as c, MetaFeedbackPayload as d, MetaSkillName as f, SkillStaleness as g, SkillEntry as h, IntentArtifactFile as i, IntentPackage as l, ScanResult as m, FeedbackPayload as n, IntentArtifactSkill as o, ScanOptions as p, IntentArtifactCoverageIgnore as r, IntentArtifactWarning as s, AgentName as t, IntentProjectConfig as u, StalenessSignal as v, VersionConflict as y };
|