@tanstack/intent 0.0.29 → 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.
Files changed (39) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +25 -12
  3. package/dist/artifact-coverage-BAN2W6aH.mjs +3 -0
  4. package/dist/artifact-coverage-wLNVX8yC.mjs +128 -0
  5. package/dist/cli.d.mts +0 -0
  6. package/dist/cli.mjs +77 -76
  7. package/dist/{display-hdsqb4w-.mjs → display-BTZWCjzT.mjs} +10 -1
  8. package/dist/display-DvLbcWzq.mjs +5 -0
  9. package/dist/index.d.mts +76 -5
  10. package/dist/index.mjs +126 -6
  11. package/dist/install-PUnIfBNC.mjs +542 -0
  12. package/dist/intent-library.mjs +9 -5
  13. package/dist/{library-scanner-B51qV5aX.mjs → library-scanner-Cl-XPEMf.mjs} +10 -3
  14. package/dist/library-scanner.d.mts +2 -2
  15. package/dist/library-scanner.mjs +2 -1
  16. package/dist/{project-context-D6A5sBBO.mjs → project-context-IDLpJU3S.mjs} +1 -1
  17. package/dist/resolver-D2CgIYGg.mjs +70 -0
  18. package/dist/{scanner-B-bbXBLY.mjs → scanner-CW59cxE_.mjs} +176 -117
  19. package/dist/scanner-DlkcbVye.mjs +6 -0
  20. package/dist/{setup-B4ZwN5Hg.mjs → setup-DfLsziXU.mjs} +2 -2
  21. package/dist/setup.d.mts +1 -1
  22. package/dist/setup.mjs +3 -3
  23. package/dist/skill-paths-8k9K9y26.mjs +33 -0
  24. package/dist/skill-use-uwGleSOz.mjs +42 -0
  25. package/dist/staleness-DpbmYod4.mjs +5 -0
  26. package/dist/staleness-PdgakrCQ.mjs +243 -0
  27. package/dist/{types-BTQ9efv-.d.mts → types-_y9b00bI.d.mts} +54 -1
  28. package/dist/{workspace-patterns-Cndd-7vB.mjs → workspace-patterns-BN2A_60g.mjs} +6 -1
  29. package/dist/workspace-patterns-x-dLZxx4.mjs +4 -0
  30. package/meta/templates/workflows/check-skills.yml +199 -91
  31. package/package.json +3 -4
  32. package/dist/display-DdmZXLZm.mjs +0 -3
  33. package/dist/install-BzDmD5yI.mjs +0 -69
  34. package/dist/scanner-CP4U8F_n.mjs +0 -5
  35. package/dist/staleness-LRbiWWZK.mjs +0 -4
  36. package/dist/staleness-SY7-mZMH.mjs +0 -104
  37. package/dist/workspace-patterns-D_y6rlqX.mjs +0 -4
  38. package/meta/templates/workflows/notify-intent.yml +0 -51
  39. /package/dist/{setup-BA9RkENh.d.mts → setup-D2CGdTsx.d.mts} +0 -0
@@ -1,14 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import "./utils-COlDcU72.mjs";
3
- import { t as INSTALL_PROMPT } from "./install-BzDmD5yI.mjs";
4
- import { n as printSkillTree, r as printTable, t as computeSkillNameWidth } from "./display-hdsqb4w-.mjs";
5
- import { t as scanLibrary } from "./library-scanner-B51qV5aX.mjs";
3
+ import "./skill-paths-8k9K9y26.mjs";
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";
6
9
 
7
10
  //#region src/intent-library.ts
8
11
  function cmdList() {
9
12
  let result;
10
13
  try {
11
- result = scanLibrary(process.argv[1]);
14
+ result = scanLibrary(process.argv[1], process.cwd());
12
15
  } catch (err) {
13
16
  console.error(err.message);
14
17
  process.exit(1);
@@ -39,6 +42,7 @@ function cmdList() {
39
42
  console.log(` ${pkg.name}`);
40
43
  printSkillTree(pkg.skills, {
41
44
  nameWidth,
45
+ packageName: pkg.name,
42
46
  showTypes
43
47
  });
44
48
  console.log();
@@ -60,7 +64,7 @@ const USAGE = `TanStack Intent
60
64
  Usage:
61
65
  intent list List all available skills from this library and its dependencies
62
66
  intent install Print a skill that guides your coding agent to scan the project
63
- and set up skill-to-task mappings in your agent config`;
67
+ and set up skill loading guidance in your agent config`;
64
68
  const command = process.argv[2];
65
69
  switch (command) {
66
70
  case "list":
@@ -1,4 +1,5 @@
1
1
  import { a as parseFrontmatter, o as resolveDepDir, r as getDeps, s as toPosixPath } from "./utils-COlDcU72.mjs";
2
+ import { r as rewriteSkillLoadPaths } from "./skill-paths-8k9K9y26.mjs";
2
3
  import { existsSync, readFileSync, readdirSync } from "node:fs";
3
4
  import { dirname, join, relative } from "node:path";
4
5
 
@@ -52,14 +53,14 @@ function discoverSkills(skillsDir) {
52
53
  type: typeof fm?.type === "string" ? fm.type : void 0,
53
54
  framework: typeof fm?.framework === "string" ? fm.framework : void 0
54
55
  });
55
- walk(childDir);
56
56
  }
57
+ walk(childDir);
57
58
  }
58
59
  }
59
60
  walk(skillsDir);
60
61
  return skills;
61
62
  }
62
- function scanLibrary(scriptPath, _projectRoot) {
63
+ function scanLibrary(scriptPath, projectRoot) {
63
64
  const packages = [];
64
65
  const warnings = [];
65
66
  const visited = /* @__PURE__ */ new Set();
@@ -74,6 +75,7 @@ function scanLibrary(scriptPath, _projectRoot) {
74
75
  warnings: ["Could not read home package.json"]
75
76
  };
76
77
  const homeName = typeof homePkg.name === "string" ? homePkg.name : "";
78
+ const scanRoot = projectRoot ?? homeDir;
77
79
  function processPackage(name, dir) {
78
80
  if (visited.has(name)) return;
79
81
  visited.add(name);
@@ -84,7 +86,12 @@ function scanLibrary(scriptPath, _projectRoot) {
84
86
  }
85
87
  const skillsDir = join(dir, "skills");
86
88
  const skills = existsSync(skillsDir) ? discoverSkills(skillsDir) : [];
87
- if (name) for (const skill of skills) skill.path = `node_modules/${name}/${toPosixPath(relative(dir, skill.path))}`;
89
+ rewriteSkillLoadPaths({
90
+ packageName: name,
91
+ packageRoot: dir,
92
+ projectRoot: scanRoot,
93
+ skills
94
+ });
88
95
  packages.push({
89
96
  name,
90
97
  version: typeof pkg.version === "string" ? pkg.version : "0.0.0",
@@ -1,4 +1,4 @@
1
- import { l as SkillEntry } from "./types-BTQ9efv-.mjs";
1
+ import { h as SkillEntry } from "./types-_y9b00bI.mjs";
2
2
 
3
3
  //#region src/library-scanner.d.ts
4
4
  interface LibraryPackage {
@@ -11,6 +11,6 @@ interface LibraryScanResult {
11
11
  packages: Array<LibraryPackage>;
12
12
  warnings: Array<string>;
13
13
  }
14
- declare function scanLibrary(scriptPath: string, _projectRoot?: string): LibraryScanResult;
14
+ declare function scanLibrary(scriptPath: string, projectRoot?: string): LibraryScanResult;
15
15
  //#endregion
16
16
  export { LibraryPackage, LibraryScanResult, scanLibrary };
@@ -1,4 +1,5 @@
1
1
  import "./utils-COlDcU72.mjs";
2
- import { t as scanLibrary } from "./library-scanner-B51qV5aX.mjs";
2
+ import "./skill-paths-8k9K9y26.mjs";
3
+ import { t as scanLibrary } from "./library-scanner-Cl-XPEMf.mjs";
3
4
 
4
5
  export { scanLibrary };
@@ -1,4 +1,4 @@
1
- import { n as findWorkspaceRoot, r as readWorkspacePatterns } from "./workspace-patterns-Cndd-7vB.mjs";
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
 
@@ -0,0 +1,70 @@
1
+ import { i as parseSkillUse } from "./skill-use-uwGleSOz.mjs";
2
+
3
+ //#region src/resolver.ts
4
+ var ResolveSkillUseError = class extends Error {
5
+ constructor({ availablePackages = [], availableSkills = [], code, packageName, skillName, use }) {
6
+ super(formatResolveSkillUseErrorMessage({
7
+ availablePackages,
8
+ availableSkills,
9
+ code,
10
+ packageName,
11
+ skillName,
12
+ use
13
+ }));
14
+ this.name = "ResolveSkillUseError";
15
+ this.availablePackages = availablePackages;
16
+ this.availableSkills = availableSkills;
17
+ this.code = code;
18
+ this.packageName = packageName;
19
+ this.skillName = skillName;
20
+ this.use = use;
21
+ }
22
+ };
23
+ function isResolveSkillUseError(error) {
24
+ return error instanceof ResolveSkillUseError;
25
+ }
26
+ function resolveSkillUse(use, scanResult) {
27
+ const { packageName, skillName } = parseSkillUse(use);
28
+ const packages = scanResult.packages.filter((pkg$1) => pkg$1.name === packageName);
29
+ const pkg = packages.find((candidate) => candidate.source === "local") ?? packages[0];
30
+ if (!pkg) throw new ResolveSkillUseError({
31
+ availablePackages: scanResult.packages.map((candidate) => candidate.name),
32
+ code: "package-not-found",
33
+ packageName,
34
+ skillName,
35
+ use
36
+ });
37
+ const skill = pkg.skills.find((candidate) => candidate.name === skillName);
38
+ if (!skill) throw new ResolveSkillUseError({
39
+ availableSkills: pkg.skills.map((candidate) => candidate.name),
40
+ code: "skill-not-found",
41
+ packageName,
42
+ skillName,
43
+ use
44
+ });
45
+ const conflict = scanResult.conflicts.find((candidate) => candidate.packageName === packageName) ?? null;
46
+ return {
47
+ packageName,
48
+ skillName,
49
+ path: skill.path,
50
+ source: pkg.source,
51
+ version: pkg.version,
52
+ packageRoot: pkg.packageRoot,
53
+ warnings: scanResult.warnings.filter((warning) => {
54
+ const idx = warning.indexOf(packageName);
55
+ if (idx === -1) return false;
56
+ const after = warning[idx + packageName.length];
57
+ return after === void 0 || /[^a-zA-Z0-9_-]/.test(after);
58
+ }),
59
+ conflict
60
+ };
61
+ }
62
+ function formatResolveSkillUseErrorMessage({ availablePackages, availableSkills, code, packageName, skillName, use }) {
63
+ switch (code) {
64
+ case "package-not-found": return `Cannot resolve skill use "${use}": package "${packageName}" was not found.${availablePackages.length > 0 ? ` Available packages: ${availablePackages.join(", ")}.` : ""}`;
65
+ case "skill-not-found": return `Cannot resolve skill use "${use}": skill "${skillName}" was not found in package "${packageName}".${availableSkills.length > 0 ? ` Available skills: ${availableSkills.join(", ")}.` : ""}`;
66
+ }
67
+ }
68
+
69
+ //#endregion
70
+ export { isResolveSkillUseError as n, resolveSkillUse as r, ResolveSkillUseError as t };
@@ -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 { i as resolveWorkspacePackages, n as findWorkspaceRoot, r as readWorkspacePatterns } from "./workspace-patterns-Cndd-7vB.mjs";
2
+ import { r as rewriteSkillLoadPaths } from "./skill-paths-8k9K9y26.mjs";
3
+ import { a as resolveWorkspacePackages, i as readWorkspacePatterns, r as findWorkspaceRoot } from "./workspace-patterns-BN2A_60g.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 scanForIntents(root) {
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
- function scanTarget(target) {
230
- if (!target.path || !target.exists || target.scanned) return;
231
- target.scanned = true;
232
- for (const dirPath of listNodeModulesPackageDirs(target.path)) tryRegister(dirPath, "unknown");
233
- }
234
- /**
235
- * Try to register a package with a skills/ directory. Reads its
236
- * package.json, validates intent config, discovers skills, and pushes
237
- * to `packages`. Returns true if the package was registered.
238
- */
239
- function tryRegister(dirPath, fallbackName) {
240
- const skillsDir = join(dirPath, "skills");
241
- if (!existsSync(skillsDir)) return false;
242
- const pkgJson = readPkgJson(dirPath);
243
- if (!pkgJson) {
244
- warnings.push(`Could not read package.json for ${dirPath}`);
245
- return false;
246
- }
247
- const name = typeof pkgJson.name === "string" ? pkgJson.name : fallbackName;
248
- const version = typeof pkgJson.version === "string" ? pkgJson.version : "0.0.0";
249
- const intent = validateIntentField(name, pkgJson.intent) ?? deriveIntentConfig(pkgJson);
250
- if (!intent) {
251
- warnings.push(`${name} has a skills/ directory but could not determine repo/docs from package.json (add a "repository" field or explicit "intent" config)`);
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,
@@ -0,0 +1,6 @@
1
+ import "./utils-COlDcU72.mjs";
2
+ import "./skill-paths-8k9K9y26.mjs";
3
+ import { t as scanForIntents } from "./scanner-CW59cxE_.mjs";
4
+ import "./workspace-patterns-BN2A_60g.mjs";
5
+
6
+ export { scanForIntents };
@@ -1,5 +1,5 @@
1
- import { n as findWorkspaceRoot, r as readWorkspacePatterns, t as findPackagesWithSkills } from "./workspace-patterns-Cndd-7vB.mjs";
2
- import { t as resolveProjectContext } from "./project-context-D6A5sBBO.mjs";
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-BA9RkENh.mjs";
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 { i as resolveWorkspacePackages, n as findWorkspaceRoot, r as readWorkspacePatterns, t as findPackagesWithSkills } from "./workspace-patterns-Cndd-7vB.mjs";
3
- import "./project-context-D6A5sBBO.mjs";
4
- import { n as runEditPackageJsonAll, r as runSetupGithubActions, t as runEditPackageJson } from "./setup-B4ZwN5Hg.mjs";
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 };
@@ -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 };
@@ -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 };