@tanstack/intent 0.0.27 → 0.0.32
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/LICENSE +21 -0
- package/README.md +18 -5
- package/dist/cli.d.mts +0 -0
- package/dist/cli.mjs +62 -68
- package/dist/display-DCRCp4-C.mjs +5 -0
- package/dist/{display-hdsqb4w-.mjs → display-DUgtRJkt.mjs} +10 -1
- package/dist/index.d.mts +57 -4
- package/dist/index.mjs +9 -6
- package/dist/install-BmVqcbEi.mjs +506 -0
- package/dist/intent-library.mjs +9 -5
- package/dist/{library-scanner-B51qV5aX.mjs → library-scanner-DFFreLjW.mjs} +10 -3
- package/dist/library-scanner.d.mts +2 -2
- package/dist/library-scanner.mjs +2 -1
- package/dist/{project-context-B7UXTA9F.mjs → project-context-CKG-q4rD.mjs} +1 -1
- package/dist/resolver-aFigTqXi.mjs +70 -0
- package/dist/scanner-CRZITpcY.mjs +6 -0
- package/dist/{scanner-1ZGYK3Qm.mjs → scanner-DKL8v8is.mjs} +176 -117
- package/dist/{setup-BzhEoOBi.mjs → setup-JJvjiGkM.mjs} +2 -2
- package/dist/setup.d.mts +1 -1
- package/dist/setup.mjs +3 -3
- package/dist/skill-paths-8k9K9y26.mjs +33 -0
- package/dist/skill-use-CXOnncWK.mjs +42 -0
- package/dist/{staleness-BtmJtMpz.mjs → staleness-DorwfGrf.mjs} +12 -1
- package/dist/staleness-NF-lxfXf.mjs +4 -0
- package/dist/{types-BTQ9efv-.d.mts → types-CsySN6Vw.d.mts} +7 -1
- package/dist/{workspace-patterns-Boa5mAbf.mjs → workspace-patterns-DbnA0peB.mjs} +1 -1
- package/dist/{workspace-patterns-BuJMfudb.mjs → workspace-patterns-U35B5AO-.mjs} +73 -4
- package/package.json +3 -4
- package/dist/display-DdmZXLZm.mjs +0 -3
- package/dist/install-BzDmD5yI.mjs +0 -69
- package/dist/scanner-CERQgrRN.mjs +0 -5
- package/dist/staleness-SRims-ZP.mjs +0 -4
- /package/dist/{setup-BA9RkENh.d.mts → setup-DDoOLriA.d.mts} +0 -0
|
@@ -1,8 +1,136 @@
|
|
|
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
|
-
import {
|
|
2
|
+
import { r as rewriteSkillLoadPaths } from "./skill-paths-8k9K9y26.mjs";
|
|
3
|
+
import { i as resolveWorkspacePackages, n as findWorkspaceRoot, r as readWorkspacePatterns } from "./workspace-patterns-U35B5AO-.mjs";
|
|
3
4
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
4
5
|
import { join, relative, sep } from "node:path";
|
|
5
6
|
|
|
7
|
+
//#region src/discovery/register.ts
|
|
8
|
+
function isLocalToProject(dirPath, projectRoot) {
|
|
9
|
+
return dirPath.startsWith(projectRoot + sep) || dirPath.startsWith(projectRoot + "/");
|
|
10
|
+
}
|
|
11
|
+
function createPackageRegistrar(opts) {
|
|
12
|
+
function scanTarget(target, source = "local") {
|
|
13
|
+
if (!target.path || !target.exists || target.scanned) return;
|
|
14
|
+
target.scanned = true;
|
|
15
|
+
for (const dirPath of listNodeModulesPackageDirs(target.path)) tryRegister(dirPath, "unknown", source);
|
|
16
|
+
}
|
|
17
|
+
function tryRegister(dirPath, fallbackName, source = "local") {
|
|
18
|
+
const skillsDir = join(dirPath, "skills");
|
|
19
|
+
if (!existsSync(skillsDir)) return false;
|
|
20
|
+
const pkgJson = opts.readPkgJson(dirPath);
|
|
21
|
+
if (!pkgJson) {
|
|
22
|
+
opts.warnings.push(`Could not read package.json for ${dirPath}`);
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
const name = typeof pkgJson.name === "string" ? pkgJson.name : fallbackName;
|
|
26
|
+
const version = typeof pkgJson.version === "string" ? pkgJson.version : "0.0.0";
|
|
27
|
+
const intent = opts.validateIntentField(name, pkgJson.intent) ?? opts.deriveIntentConfig(pkgJson);
|
|
28
|
+
if (!intent) {
|
|
29
|
+
opts.warnings.push(`${name} has a skills/ directory but could not determine repo/docs from package.json (add a "repository" field or explicit "intent" config)`);
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
const skills = opts.discoverSkills(skillsDir, name);
|
|
33
|
+
if (isLocalToProject(dirPath, opts.projectRoot)) rewriteSkillLoadPaths({
|
|
34
|
+
packageName: name,
|
|
35
|
+
packageRoot: dirPath,
|
|
36
|
+
projectRoot: opts.projectRoot,
|
|
37
|
+
skills
|
|
38
|
+
});
|
|
39
|
+
const candidate = {
|
|
40
|
+
name,
|
|
41
|
+
version,
|
|
42
|
+
intent,
|
|
43
|
+
skills,
|
|
44
|
+
packageRoot: dirPath,
|
|
45
|
+
source
|
|
46
|
+
};
|
|
47
|
+
const existingIndex = opts.packageIndexes.get(name);
|
|
48
|
+
if (existingIndex === void 0) {
|
|
49
|
+
opts.rememberVariant(candidate);
|
|
50
|
+
opts.packageIndexes.set(name, opts.packages.push(candidate) - 1);
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
const existing = opts.packages[existingIndex];
|
|
54
|
+
if (existing.packageRoot === candidate.packageRoot) return false;
|
|
55
|
+
opts.rememberVariant(existing);
|
|
56
|
+
opts.rememberVariant(candidate);
|
|
57
|
+
const existingDepth = opts.getPackageDepth(existing.packageRoot, opts.projectRoot);
|
|
58
|
+
const candidateDepth = opts.getPackageDepth(candidate.packageRoot, opts.projectRoot);
|
|
59
|
+
if (candidateDepth < existingDepth || candidateDepth === existingDepth && opts.comparePackageVersions(candidate.version, existing.version) > 0) opts.packages[existingIndex] = candidate;
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
scanTarget,
|
|
64
|
+
tryRegister
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
//#endregion
|
|
69
|
+
//#region src/discovery/walk.ts
|
|
70
|
+
function createDependencyWalker(opts) {
|
|
71
|
+
const walkVisited = /* @__PURE__ */ new Set();
|
|
72
|
+
const depDirCache = /* @__PURE__ */ new Map();
|
|
73
|
+
function resolveDepDirCached(depName, fromDir) {
|
|
74
|
+
let byDepName = depDirCache.get(fromDir);
|
|
75
|
+
if (!byDepName) {
|
|
76
|
+
byDepName = /* @__PURE__ */ new Map();
|
|
77
|
+
depDirCache.set(fromDir, byDepName);
|
|
78
|
+
}
|
|
79
|
+
if (!byDepName.has(depName)) byDepName.set(depName, resolveDepDir(depName, fromDir));
|
|
80
|
+
return byDepName.get(depName) ?? null;
|
|
81
|
+
}
|
|
82
|
+
function walkDepsOf(pkgJson, fromDir, includeDevDeps = false) {
|
|
83
|
+
for (const depName of getDeps(pkgJson, includeDevDeps)) {
|
|
84
|
+
const depDir = resolveDepDirCached(depName, fromDir);
|
|
85
|
+
if (!depDir || walkVisited.has(depDir)) continue;
|
|
86
|
+
opts.tryRegister(depDir, depName);
|
|
87
|
+
walkDeps(depDir, depName);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function walkDeps(pkgDir, pkgName) {
|
|
91
|
+
if (walkVisited.has(pkgDir)) return;
|
|
92
|
+
walkVisited.add(pkgDir);
|
|
93
|
+
const pkgJson = opts.readPkgJson(pkgDir);
|
|
94
|
+
if (!pkgJson) {
|
|
95
|
+
opts.warnings.push(`Could not read package.json for ${pkgName} (skipping dependency walk)`);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
walkDepsOf(pkgJson, pkgDir);
|
|
99
|
+
}
|
|
100
|
+
function walkKnownPackages() {
|
|
101
|
+
for (const pkg of [...opts.packages]) walkDeps(pkg.packageRoot, pkg.name);
|
|
102
|
+
}
|
|
103
|
+
function walkProjectDeps() {
|
|
104
|
+
const projectPkg = readPkgJsonWithWarning(opts.projectRoot, "project");
|
|
105
|
+
if (!projectPkg) return;
|
|
106
|
+
walkDepsOf(projectPkg, opts.projectRoot, true);
|
|
107
|
+
}
|
|
108
|
+
function readPkgJsonWithWarning(dirPath, label) {
|
|
109
|
+
try {
|
|
110
|
+
return JSON.parse(readFileSync(join(dirPath, "package.json"), "utf8"));
|
|
111
|
+
} catch (err) {
|
|
112
|
+
if (err.code !== "ENOENT") opts.warnings.push(`Could not read ${label} package.json at ${dirPath}: ${err.message}`);
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function walkWorkspacePackages() {
|
|
117
|
+
const workspacePatterns = readWorkspacePatterns(opts.projectRoot);
|
|
118
|
+
if (!workspacePatterns) return;
|
|
119
|
+
for (const wsDir of resolveWorkspacePackages(opts.projectRoot, workspacePatterns)) {
|
|
120
|
+
const wsNodeModules = join(wsDir, "node_modules");
|
|
121
|
+
if (existsSync(wsNodeModules)) for (const dirPath of listNodeModulesPackageDirs(wsNodeModules)) opts.tryRegister(dirPath, "unknown");
|
|
122
|
+
const wsPkg = readPkgJsonWithWarning(wsDir, "workspace");
|
|
123
|
+
if (wsPkg) walkDepsOf(wsPkg, wsDir);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
walkKnownPackages,
|
|
128
|
+
walkProjectDeps,
|
|
129
|
+
walkWorkspacePackages
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
//#endregion
|
|
6
134
|
//#region src/scanner.ts
|
|
7
135
|
function detectPackageManager(root) {
|
|
8
136
|
if (existsSync(join(root, ".pnp.cjs")) || existsSync(join(root, ".pnp.js"))) throw new Error("Yarn PnP is not yet supported. Add `nodeLinker: node-modules` to your .yarnrc.yml to use intent.");
|
|
@@ -83,8 +211,8 @@ function discoverSkills(skillsDir, _baseName) {
|
|
|
83
211
|
type: typeof fm?.type === "string" ? fm.type : void 0,
|
|
84
212
|
framework: typeof fm?.framework === "string" ? fm.framework : void 0
|
|
85
213
|
});
|
|
86
|
-
walk(childDir);
|
|
87
214
|
}
|
|
215
|
+
walk(childDir);
|
|
88
216
|
}
|
|
89
217
|
}
|
|
90
218
|
walk(skillsDir);
|
|
@@ -169,8 +297,12 @@ function toVersionConflict(packageName, variants, chosen) {
|
|
|
169
297
|
variants
|
|
170
298
|
};
|
|
171
299
|
}
|
|
172
|
-
function
|
|
300
|
+
function getScanScope(options) {
|
|
301
|
+
return options.scope ?? (options.includeGlobal ? "local-and-global" : "local");
|
|
302
|
+
}
|
|
303
|
+
function scanForIntents(root, options = {}) {
|
|
173
304
|
const projectRoot = root ?? process.cwd();
|
|
305
|
+
const scanScope = getScanScope(options);
|
|
174
306
|
const packageManager = detectPackageManager(projectRoot);
|
|
175
307
|
const nodeModulesDir = join(projectRoot, "node_modules");
|
|
176
308
|
const explicitGlobalNodeModules = process.env.INTENT_GLOBAL_NODE_MODULES?.trim() || null;
|
|
@@ -226,123 +358,50 @@ function scanForIntents(root) {
|
|
|
226
358
|
return null;
|
|
227
359
|
}
|
|
228
360
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
return false;
|
|
253
|
-
}
|
|
254
|
-
const skills = discoverSkills(skillsDir, name);
|
|
255
|
-
if (dirPath.startsWith(projectRoot + sep) || dirPath.startsWith(projectRoot + "/")) {
|
|
256
|
-
const hasStableSymlink = name !== "" && existsSync(join(projectRoot, "node_modules", name));
|
|
257
|
-
for (const skill of skills) if (hasStableSymlink) skill.path = `node_modules/${name}/${toPosixPath(relative(dirPath, skill.path))}`;
|
|
258
|
-
else skill.path = toPosixPath(relative(projectRoot, skill.path));
|
|
259
|
-
}
|
|
260
|
-
const candidate = {
|
|
261
|
-
name,
|
|
262
|
-
version,
|
|
263
|
-
intent,
|
|
264
|
-
skills,
|
|
265
|
-
packageRoot: dirPath
|
|
266
|
-
};
|
|
267
|
-
const existingIndex = packageIndexes.get(name);
|
|
268
|
-
if (existingIndex === void 0) {
|
|
269
|
-
rememberVariant(candidate);
|
|
270
|
-
packageIndexes.set(name, packages.push(candidate) - 1);
|
|
271
|
-
return true;
|
|
272
|
-
}
|
|
273
|
-
const existing = packages[existingIndex];
|
|
274
|
-
if (existing.packageRoot === candidate.packageRoot) return false;
|
|
275
|
-
rememberVariant(existing);
|
|
276
|
-
rememberVariant(candidate);
|
|
277
|
-
const existingDepth = getPackageDepth(existing.packageRoot, projectRoot);
|
|
278
|
-
const candidateDepth = getPackageDepth(candidate.packageRoot, projectRoot);
|
|
279
|
-
if (candidateDepth < existingDepth || candidateDepth === existingDepth && comparePackageVersions(candidate.version, existing.version) > 0) packages[existingIndex] = candidate;
|
|
280
|
-
return true;
|
|
281
|
-
}
|
|
282
|
-
scanTarget(nodeModules.local);
|
|
283
|
-
const walkVisited = /* @__PURE__ */ new Set();
|
|
284
|
-
function walkDeps(pkgDir, pkgName) {
|
|
285
|
-
if (walkVisited.has(pkgDir)) return;
|
|
286
|
-
walkVisited.add(pkgDir);
|
|
287
|
-
const pkgJson = readPkgJson(pkgDir);
|
|
288
|
-
if (!pkgJson) {
|
|
289
|
-
warnings.push(`Could not read package.json for ${pkgName} (skipping dependency walk)`);
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
for (const depName of getDeps(pkgJson)) {
|
|
293
|
-
const depDir = resolveDepDir(depName, pkgDir);
|
|
294
|
-
if (!depDir || walkVisited.has(depDir)) continue;
|
|
295
|
-
tryRegister(depDir, depName);
|
|
296
|
-
walkDeps(depDir, depName);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
function walkKnownPackages() {
|
|
300
|
-
for (const pkg of [...packages]) walkDeps(pkg.packageRoot, pkg.name);
|
|
301
|
-
}
|
|
302
|
-
function walkProjectDeps() {
|
|
303
|
-
let projectPkg = null;
|
|
304
|
-
try {
|
|
305
|
-
projectPkg = JSON.parse(readFileSync(join(projectRoot, "package.json"), "utf8"));
|
|
306
|
-
} catch (err) {
|
|
307
|
-
if (!(err && typeof err === "object" && "code" in err && err.code === "ENOENT")) warnings.push(`Could not read project package.json: ${err instanceof Error ? err.message : String(err)}`);
|
|
308
|
-
}
|
|
309
|
-
if (!projectPkg) return;
|
|
310
|
-
walkDepsFromPkgJson(projectPkg, projectRoot, true);
|
|
311
|
-
}
|
|
312
|
-
/** Resolve and walk deps listed in a package.json. */
|
|
313
|
-
function walkDepsFromPkgJson(pkgJson, fromDir, includeDevDeps = false) {
|
|
314
|
-
for (const depName of getDeps(pkgJson, includeDevDeps)) {
|
|
315
|
-
const depDir = resolveDepDir(depName, fromDir);
|
|
316
|
-
if (depDir && !walkVisited.has(depDir)) {
|
|
317
|
-
tryRegister(depDir, depName);
|
|
318
|
-
walkDeps(depDir, depName);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* In monorepos, discover workspace packages and walk their deps.
|
|
324
|
-
* Handles pnpm monorepos (workspace-specific node_modules) and ensures
|
|
325
|
-
* transitive skills packages are found through workspace package dependencies.
|
|
326
|
-
*/
|
|
327
|
-
function walkWorkspacePackages() {
|
|
328
|
-
const workspacePatterns = readWorkspacePatterns(projectRoot);
|
|
329
|
-
if (!workspacePatterns) return;
|
|
330
|
-
for (const wsDir of resolveWorkspacePackages(projectRoot, workspacePatterns)) {
|
|
331
|
-
const wsNodeModules = join(wsDir, "node_modules");
|
|
332
|
-
if (existsSync(wsNodeModules)) for (const dirPath of listNodeModulesPackageDirs(wsNodeModules)) tryRegister(dirPath, "unknown");
|
|
333
|
-
const wsPkg = readPkgJson(wsDir);
|
|
334
|
-
if (wsPkg) walkDepsFromPkgJson(wsPkg, wsDir);
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
walkWorkspacePackages();
|
|
338
|
-
walkKnownPackages();
|
|
339
|
-
walkProjectDeps();
|
|
340
|
-
if (explicitGlobalNodeModules || packages.length === 0 || !nodeModules.local.exists) {
|
|
341
|
-
ensureGlobalNodeModules();
|
|
342
|
-
scanTarget(nodeModules.global);
|
|
361
|
+
const { scanTarget, tryRegister } = createPackageRegistrar({
|
|
362
|
+
comparePackageVersions,
|
|
363
|
+
deriveIntentConfig,
|
|
364
|
+
discoverSkills,
|
|
365
|
+
getPackageDepth,
|
|
366
|
+
packageIndexes,
|
|
367
|
+
packages,
|
|
368
|
+
projectRoot,
|
|
369
|
+
readPkgJson,
|
|
370
|
+
rememberVariant,
|
|
371
|
+
validateIntentField,
|
|
372
|
+
warnings
|
|
373
|
+
});
|
|
374
|
+
const { walkKnownPackages, walkProjectDeps, walkWorkspacePackages } = createDependencyWalker({
|
|
375
|
+
packages,
|
|
376
|
+
projectRoot,
|
|
377
|
+
readPkgJson,
|
|
378
|
+
tryRegister,
|
|
379
|
+
warnings
|
|
380
|
+
});
|
|
381
|
+
function scanLocalPackages() {
|
|
382
|
+
scanTarget(nodeModules.local);
|
|
383
|
+
walkWorkspacePackages();
|
|
343
384
|
walkKnownPackages();
|
|
344
385
|
walkProjectDeps();
|
|
345
386
|
}
|
|
387
|
+
function scanGlobalPackages() {
|
|
388
|
+
ensureGlobalNodeModules();
|
|
389
|
+
scanTarget(nodeModules.global, "global");
|
|
390
|
+
}
|
|
391
|
+
switch (scanScope) {
|
|
392
|
+
case "local":
|
|
393
|
+
scanLocalPackages();
|
|
394
|
+
break;
|
|
395
|
+
case "local-and-global":
|
|
396
|
+
scanLocalPackages();
|
|
397
|
+
scanGlobalPackages();
|
|
398
|
+
walkKnownPackages();
|
|
399
|
+
walkProjectDeps();
|
|
400
|
+
break;
|
|
401
|
+
case "global":
|
|
402
|
+
scanGlobalPackages();
|
|
403
|
+
break;
|
|
404
|
+
}
|
|
346
405
|
if (!nodeModules.local.exists && !nodeModules.global.exists) return {
|
|
347
406
|
packageManager,
|
|
348
407
|
packages,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as findWorkspaceRoot, r as readWorkspacePatterns, t as findPackagesWithSkills } from "./workspace-patterns-
|
|
2
|
-
import { t as resolveProjectContext } from "./project-context-
|
|
1
|
+
import { n as findWorkspaceRoot, r as readWorkspacePatterns, t as findPackagesWithSkills } from "./workspace-patterns-U35B5AO-.mjs";
|
|
2
|
+
import { t as resolveProjectContext } from "./project-context-CKG-q4rD.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-DDoOLriA.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 { i as resolveWorkspacePackages, n as findWorkspaceRoot, r as readWorkspacePatterns, t as findPackagesWithSkills } from "./workspace-patterns-
|
|
3
|
-
import "./project-context-
|
|
4
|
-
import { n as runEditPackageJsonAll, r as runSetupGithubActions, t as runEditPackageJson } from "./setup-
|
|
2
|
+
import { i as resolveWorkspacePackages, n as findWorkspaceRoot, r as readWorkspacePatterns, t as findPackagesWithSkills } from "./workspace-patterns-U35B5AO-.mjs";
|
|
3
|
+
import "./project-context-CKG-q4rD.mjs";
|
|
4
|
+
import { n as runEditPackageJsonAll, r as runSetupGithubActions, t as runEditPackageJson } from "./setup-JJvjiGkM.mjs";
|
|
5
5
|
|
|
6
6
|
export { findPackagesWithSkills, findWorkspaceRoot, readWorkspacePatterns, resolveWorkspacePackages, runEditPackageJson, runEditPackageJsonAll, runSetupGithubActions };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { s as toPosixPath } from "./utils-COlDcU72.mjs";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { join, relative } from "node:path";
|
|
4
|
+
|
|
5
|
+
//#region src/skill-paths.ts
|
|
6
|
+
function isAbsolutePath(path) {
|
|
7
|
+
return path.startsWith("/") || path.startsWith("\\") || /^[A-Za-z]:[\\/]/.test(path);
|
|
8
|
+
}
|
|
9
|
+
function getPathSegments(path) {
|
|
10
|
+
return path.replace(/\\/g, "/").split("/");
|
|
11
|
+
}
|
|
12
|
+
function isPackageManagerInternalSegment(segment) {
|
|
13
|
+
return segment === ".pnpm" || segment === ".bun" || segment === ".yarn";
|
|
14
|
+
}
|
|
15
|
+
function isStableLoadPath(path) {
|
|
16
|
+
const normalized = path.trim();
|
|
17
|
+
const segments = getPathSegments(normalized);
|
|
18
|
+
return normalized !== "" && !isAbsolutePath(normalized) && !segments.includes("..") && !segments.some(isPackageManagerInternalSegment);
|
|
19
|
+
}
|
|
20
|
+
function rewriteSkillLoadPaths({ packageName, packageRoot, projectRoot, skills }) {
|
|
21
|
+
const hasStableSymlink = packageName !== "" && existsSync(join(projectRoot, "node_modules", packageName));
|
|
22
|
+
for (const skill of skills) if (hasStableSymlink) skill.path = `node_modules/${packageName}/${toPosixPath(relative(packageRoot, skill.path))}`;
|
|
23
|
+
else skill.path = toPosixPath(relative(projectRoot, skill.path));
|
|
24
|
+
}
|
|
25
|
+
function formatRuntimeSkillLookupComment(target) {
|
|
26
|
+
return `Runtime lookup only: run \`npx @tanstack/intent@latest load ${target.packageName}#${target.skillName} --path\`, and load its reported path for this session. Do not copy the resolved path into this file.`;
|
|
27
|
+
}
|
|
28
|
+
function formatRuntimeSkillLookupHint(target) {
|
|
29
|
+
return `Lookup: ${formatRuntimeSkillLookupComment(target)}`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
//#endregion
|
|
33
|
+
export { isStableLoadPath as n, rewriteSkillLoadPaths as r, formatRuntimeSkillLookupHint as t };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
//#region src/skill-use.ts
|
|
2
|
+
var SkillUseParseError = class extends Error {
|
|
3
|
+
constructor(code, value) {
|
|
4
|
+
super(formatSkillUseParseErrorMessage(code, value));
|
|
5
|
+
this.name = "SkillUseParseError";
|
|
6
|
+
this.code = code;
|
|
7
|
+
this.value = value;
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
function isSkillUseParseError(error) {
|
|
11
|
+
return error instanceof SkillUseParseError;
|
|
12
|
+
}
|
|
13
|
+
function formatSkillUse(packageName, skillName) {
|
|
14
|
+
const pkg = packageName.trim();
|
|
15
|
+
const skill = skillName.trim();
|
|
16
|
+
if (pkg === "") throw new SkillUseParseError("empty-package", `${packageName}#${skillName}`);
|
|
17
|
+
if (skill === "") throw new SkillUseParseError("empty-skill", `${packageName}#${skillName}`);
|
|
18
|
+
return `${pkg}#${skill}`;
|
|
19
|
+
}
|
|
20
|
+
function parseSkillUse(value) {
|
|
21
|
+
const trimmed = value.trim();
|
|
22
|
+
const separatorIndex = trimmed.indexOf("#");
|
|
23
|
+
if (separatorIndex === -1) throw new SkillUseParseError("missing-separator", value);
|
|
24
|
+
const packageName = trimmed.slice(0, separatorIndex).trim();
|
|
25
|
+
const skillName = trimmed.slice(separatorIndex + 1).trim();
|
|
26
|
+
if (packageName === "") throw new SkillUseParseError("empty-package", value);
|
|
27
|
+
if (skillName === "") throw new SkillUseParseError("empty-skill", value);
|
|
28
|
+
return {
|
|
29
|
+
packageName,
|
|
30
|
+
skillName
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function formatSkillUseParseErrorMessage(code, value) {
|
|
34
|
+
switch (code) {
|
|
35
|
+
case "missing-separator": return `Invalid skill use "${value}": expected <package>#<skill>.`;
|
|
36
|
+
case "empty-package": return `Invalid skill use "${value}": package is required.`;
|
|
37
|
+
case "empty-skill": return `Invalid skill use "${value}": skill is required.`;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
//#endregion
|
|
42
|
+
export { parseSkillUse as i, formatSkillUse as n, isSkillUseParseError as r, SkillUseParseError as t };
|
|
@@ -12,6 +12,14 @@ function classifyVersionDrift(oldVer, newVer) {
|
|
|
12
12
|
if ((newParts[2] ?? 0) > (oldParts[2] ?? 0)) return "patch";
|
|
13
13
|
return null;
|
|
14
14
|
}
|
|
15
|
+
function readLocalVersion(packageDir) {
|
|
16
|
+
try {
|
|
17
|
+
const pkgJson = JSON.parse(readFileSync(join(packageDir, "package.json"), "utf8"));
|
|
18
|
+
return typeof pkgJson.version === "string" ? pkgJson.version : null;
|
|
19
|
+
} catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
15
23
|
async function fetchNpmVersion(packageName) {
|
|
16
24
|
try {
|
|
17
25
|
const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`);
|
|
@@ -22,6 +30,9 @@ async function fetchNpmVersion(packageName) {
|
|
|
22
30
|
return null;
|
|
23
31
|
}
|
|
24
32
|
}
|
|
33
|
+
async function fetchCurrentVersion(packageDir, packageName) {
|
|
34
|
+
return readLocalVersion(packageDir) ?? await fetchNpmVersion(packageName);
|
|
35
|
+
}
|
|
25
36
|
function isStringRecord(value) {
|
|
26
37
|
return !!value && typeof value === "object" && !Array.isArray(value) && Object.values(value).every((entry) => typeof entry === "string");
|
|
27
38
|
}
|
|
@@ -65,7 +76,7 @@ async function checkStaleness(packageDir, packageName) {
|
|
|
65
76
|
};
|
|
66
77
|
});
|
|
67
78
|
const skillVersion = skillMetas.find((s) => s.libraryVersion)?.libraryVersion ?? null;
|
|
68
|
-
const currentVersion = await
|
|
79
|
+
const currentVersion = await fetchCurrentVersion(packageDir, library);
|
|
69
80
|
const versionDrift = skillVersion && currentVersion ? classifyVersionDrift(skillVersion, currentVersion) : null;
|
|
70
81
|
const syncState = readSyncState(packageDir);
|
|
71
82
|
return {
|
|
@@ -15,6 +15,11 @@ interface ScanResult {
|
|
|
15
15
|
global: NodeModulesScanTarget;
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
|
+
type ScanScope = 'local' | 'local-and-global' | 'global';
|
|
19
|
+
interface ScanOptions {
|
|
20
|
+
includeGlobal?: boolean;
|
|
21
|
+
scope?: ScanScope;
|
|
22
|
+
}
|
|
18
23
|
interface NodeModulesScanTarget {
|
|
19
24
|
path: string | null;
|
|
20
25
|
detected: boolean;
|
|
@@ -28,6 +33,7 @@ interface IntentPackage {
|
|
|
28
33
|
intent: IntentConfig;
|
|
29
34
|
skills: Array<SkillEntry>;
|
|
30
35
|
packageRoot: string;
|
|
36
|
+
source: 'local' | 'global';
|
|
31
37
|
}
|
|
32
38
|
interface InstalledVariant {
|
|
33
39
|
version: string;
|
|
@@ -90,4 +96,4 @@ interface IntentProjectConfig {
|
|
|
90
96
|
};
|
|
91
97
|
}
|
|
92
98
|
//#endregion
|
|
93
|
-
export { IntentProjectConfig as a,
|
|
99
|
+
export { IntentProjectConfig as a, ScanOptions as c, SkillStaleness as d, StalenessReport as f, IntentPackage as i, ScanResult as l, FeedbackPayload as n, MetaFeedbackPayload as o, VersionConflict as p, IntentConfig as r, MetaSkillName as s, AgentName as t, SkillEntry as u };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import "./utils-COlDcU72.mjs";
|
|
2
|
-
import { i as resolveWorkspacePackages, n as findWorkspaceRoot, r as readWorkspacePatterns, t as findPackagesWithSkills } from "./workspace-patterns-
|
|
2
|
+
import { i as resolveWorkspacePackages, n as findWorkspaceRoot, r as readWorkspacePatterns, t as findPackagesWithSkills } from "./workspace-patterns-U35B5AO-.mjs";
|
|
3
3
|
|
|
4
4
|
export { findPackagesWithSkills, findWorkspaceRoot };
|
|
@@ -17,21 +17,90 @@ function parseWorkspacePatterns(value) {
|
|
|
17
17
|
function hasPackageJson(dir) {
|
|
18
18
|
return existsSync(join(dir, "package.json"));
|
|
19
19
|
}
|
|
20
|
+
function stripJsonCommentsAndTrailingCommas(source) {
|
|
21
|
+
let result = "";
|
|
22
|
+
let inString = false;
|
|
23
|
+
let escaped = false;
|
|
24
|
+
for (let index = 0; index < source.length; index += 1) {
|
|
25
|
+
const char = source[index];
|
|
26
|
+
const next = source[index + 1];
|
|
27
|
+
if (inString) {
|
|
28
|
+
result += char;
|
|
29
|
+
if (escaped) escaped = false;
|
|
30
|
+
else if (char === "\\") escaped = true;
|
|
31
|
+
else if (char === "\"") inString = false;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (char === "\"") {
|
|
35
|
+
inString = true;
|
|
36
|
+
result += char;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (char === "/" && next === "/") {
|
|
40
|
+
while (index < source.length && source[index] !== "\n") index += 1;
|
|
41
|
+
if (index < source.length) result += source[index];
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (char === "/" && next === "*") {
|
|
45
|
+
const commentStart = index;
|
|
46
|
+
index += 2;
|
|
47
|
+
while (index < source.length && !(source[index] === "*" && source[index + 1] === "/")) index += 1;
|
|
48
|
+
if (index >= source.length) throw new SyntaxError(`Unterminated block comment starting at position ${commentStart}`);
|
|
49
|
+
index += 1;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (char === ",") {
|
|
53
|
+
let lookahead = index + 1;
|
|
54
|
+
while (lookahead < source.length) {
|
|
55
|
+
const la = source[lookahead];
|
|
56
|
+
if (/\s/.test(la)) lookahead += 1;
|
|
57
|
+
else if (la === "/" && source[lookahead + 1] === "/") {
|
|
58
|
+
lookahead += 2;
|
|
59
|
+
while (lookahead < source.length && source[lookahead] !== "\n") lookahead += 1;
|
|
60
|
+
} else if (la === "/" && source[lookahead + 1] === "*") {
|
|
61
|
+
lookahead += 2;
|
|
62
|
+
while (lookahead < source.length && !(source[lookahead] === "*" && source[lookahead + 1] === "/")) lookahead += 1;
|
|
63
|
+
lookahead += 2;
|
|
64
|
+
} else break;
|
|
65
|
+
}
|
|
66
|
+
if (source[lookahead] === "}" || source[lookahead] === "]") continue;
|
|
67
|
+
}
|
|
68
|
+
result += char;
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
function readJsonFile(path, jsonc = false) {
|
|
73
|
+
const source = readFileSync(path, "utf8");
|
|
74
|
+
return JSON.parse(jsonc ? stripJsonCommentsAndTrailingCommas(source) : source);
|
|
75
|
+
}
|
|
20
76
|
function readWorkspacePatterns(root) {
|
|
21
77
|
const pnpmWs = join(root, "pnpm-workspace.yaml");
|
|
22
78
|
if (existsSync(pnpmWs)) try {
|
|
23
79
|
const patterns = parseWorkspacePatterns(parse(readFileSync(pnpmWs, "utf8")).packages);
|
|
24
80
|
if (patterns) return patterns;
|
|
25
81
|
} catch (err) {
|
|
26
|
-
|
|
82
|
+
const verb = err instanceof SyntaxError ? "parse" : "read";
|
|
83
|
+
console.error(`Warning: failed to ${verb} ${pnpmWs}: ${err instanceof Error ? err.message : err}`);
|
|
27
84
|
}
|
|
28
85
|
const pkgPath = join(root, "package.json");
|
|
29
86
|
if (existsSync(pkgPath)) try {
|
|
30
|
-
const
|
|
31
|
-
const patterns = parseWorkspacePatterns(
|
|
87
|
+
const workspaces = readJsonFile(pkgPath).workspaces;
|
|
88
|
+
const patterns = parseWorkspacePatterns(workspaces) ?? parseWorkspacePatterns(workspaces?.packages);
|
|
32
89
|
if (patterns) return patterns;
|
|
33
90
|
} catch (err) {
|
|
34
|
-
|
|
91
|
+
const verb = err instanceof SyntaxError ? "parse" : "read";
|
|
92
|
+
console.error(`Warning: failed to ${verb} ${pkgPath}: ${err instanceof Error ? err.message : err}`);
|
|
93
|
+
}
|
|
94
|
+
for (const denoConfigName of ["deno.json", "deno.jsonc"]) {
|
|
95
|
+
const denoConfigPath = join(root, denoConfigName);
|
|
96
|
+
if (!existsSync(denoConfigPath)) continue;
|
|
97
|
+
try {
|
|
98
|
+
const patterns = parseWorkspacePatterns(readJsonFile(denoConfigPath, true).workspace);
|
|
99
|
+
if (patterns) return patterns;
|
|
100
|
+
} catch (err) {
|
|
101
|
+
const verb = err instanceof SyntaxError ? "parse" : "read";
|
|
102
|
+
console.error(`Warning: failed to ${verb} ${denoConfigPath}: ${err instanceof Error ? err.message : err}`);
|
|
103
|
+
}
|
|
35
104
|
}
|
|
36
105
|
return null;
|
|
37
106
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/intent",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.32",
|
|
4
4
|
"description": "Ship compositional knowledge for AI coding agents alongside your npm packages",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/
|
|
9
|
+
"url": "https://github.com/TanStack/intent"
|
|
10
10
|
},
|
|
11
11
|
"exports": {
|
|
12
12
|
".": {
|
|
@@ -36,11 +36,10 @@
|
|
|
36
36
|
"verdaccio": "^6.3.2"
|
|
37
37
|
},
|
|
38
38
|
"scripts": {
|
|
39
|
-
"prepack": "npm run build",
|
|
40
39
|
"build": "tsdown src/index.ts src/cli.ts src/setup.ts src/intent-library.ts src/library-scanner.ts --format esm --dts",
|
|
41
40
|
"test:smoke": "pnpm run build && node dist/cli.mjs --help > /dev/null",
|
|
42
41
|
"test:lib": "vitest run --exclude 'tests/integration/**'",
|
|
43
42
|
"test:integration": "vitest run tests/integration/",
|
|
44
43
|
"test:types": "tsc --noEmit"
|
|
45
44
|
}
|
|
46
|
-
}
|
|
45
|
+
}
|