@tanstack/intent 0.0.39 → 0.0.41

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 (55) hide show
  1. package/dist/artifact-coverage-CbZALe7Q.mjs +3 -0
  2. package/dist/{cli-support-Dmpj1iyQ.mjs → cli-support-BHoEb9y1.mjs} +6 -6
  3. package/dist/{cli-support-OrWuIzI3.mjs → cli-support-BxF1HIpw.mjs} +4 -4
  4. package/dist/cli.mjs +11 -11
  5. package/dist/command-runner-DJTliSTc.mjs +16 -0
  6. package/dist/{core-0H8zUKIh.mjs → core-DEiRgUqe.mjs} +50 -34
  7. package/dist/core.d.mts +5 -1
  8. package/dist/core.mjs +7 -7
  9. package/dist/{display-CVeoAwBd.mjs → display-BPM-AJGc.mjs} +12 -2
  10. package/dist/display-lWCJg5Bo.mjs +5 -0
  11. package/dist/index.d.mts +2 -2
  12. package/dist/index.mjs +11 -11
  13. package/dist/{install-7BAmUZFB.mjs → install-DCiBBx55.mjs} +14 -10
  14. package/dist/install-EVdqAy8f.mjs +7 -0
  15. package/dist/intent-library.mjs +8 -8
  16. package/dist/{library-scanner-CHepLJQJ.mjs → library-scanner-BpEuR__1.mjs} +2 -2
  17. package/dist/library-scanner.d.mts +1 -1
  18. package/dist/library-scanner.mjs +3 -3
  19. package/dist/{list-DNPHxYpR.mjs → list-CpOcnLWv.mjs} +19 -11
  20. package/dist/{load-CK7vr50h.mjs → load-BxmN8f0E.mjs} +12 -10
  21. package/dist/{meta-CYV9EzM8.mjs → meta-Dstclm2x.mjs} +2 -2
  22. package/dist/package-manager-DDZck142.mjs +48 -0
  23. package/dist/{project-context-Dx6XIJJo.mjs → project-context-D4mFnCs7.mjs} +1 -1
  24. package/dist/{resolver-CP0S8UjZ.mjs → resolver-B36uOK8c.mjs} +3 -3
  25. package/dist/{scanner-BaOA18pn.mjs → scanner-B6nnctK4.mjs} +139 -89
  26. package/dist/scanner-BWd4mS25.mjs +6 -0
  27. package/dist/{setup-kvWN4xCr.mjs → setup-J4A9UfBB.mjs} +2 -2
  28. package/dist/setup.d.mts +1 -1
  29. package/dist/setup.mjs +4 -4
  30. package/dist/{skill-paths-DNOHrvL5.mjs → skill-paths-4kQXfQXo.mjs} +1 -1
  31. package/dist/{stale-flPZnWfI.mjs → stale-BD77r7KR.mjs} +1 -1
  32. package/dist/{staleness-V-nwqFUh.mjs → staleness-DChVhbCN.mjs} +2 -2
  33. package/dist/staleness-Dm4laJFc.mjs +5 -0
  34. package/dist/{types-S2zpibHp.d.mts → types-DU_Z0qNT.d.mts} +8 -2
  35. package/dist/{utils-mdb4i6VA.mjs → utils-Chn-30vI.mjs} +70 -4
  36. package/dist/utils-Ctlz_JG-.mjs +3 -0
  37. package/dist/{validate-BYUd0qb8.mjs → validate-CTSG3eDc.mjs} +6 -6
  38. package/dist/{workflow-review-CIdJXmKP.mjs → workflow-review-DcFipeG0.mjs} +1 -1
  39. package/dist/{workspace-patterns-BZLEaMcS.mjs → workspace-patterns-C5O4Dfpl.mjs} +1 -1
  40. package/dist/{workspace-patterns-BWMz7TsI.mjs → workspace-patterns-CA-UGM5C.mjs} +2 -2
  41. package/package.json +1 -1
  42. package/dist/artifact-coverage-DA26utB1.mjs +0 -3
  43. package/dist/display-COlw5FaB.mjs +0 -5
  44. package/dist/install-Brf5PORN.mjs +0 -7
  45. package/dist/scanner-BoB20xOF.mjs +0 -6
  46. package/dist/staleness-IIyVmUxU.mjs +0 -5
  47. package/dist/utils-BHzSyNeJ.mjs +0 -3
  48. /package/dist/{artifact-coverage-DgWuVqUp.mjs → artifact-coverage-Cqphhpfo.mjs} +0 -0
  49. /package/dist/{cli-error-BrMXlbtx.mjs → cli-error-DOO5bLIG.mjs} +0 -0
  50. /package/dist/{edit-package-json-CzWlMXOf.mjs → edit-package-json-cPClxVZZ.mjs} +0 -0
  51. /package/dist/{scaffold-D2vwv9ls.mjs → scaffold-CaShIIUY.mjs} +0 -0
  52. /package/dist/{setup-2SE9zYJk.d.mts → setup-DL7qX_F-.d.mts} +0 -0
  53. /package/dist/{setup-github-actions-emXSyGy3.mjs → setup-github-actions-zzLUbyAL.mjs} +0 -0
  54. /package/dist/{skill-use-umYvZl94.mjs → skill-use-C0q2MEEX.mjs} +0 -0
  55. /package/dist/{workflow-review-CwcR2ge4.mjs → workflow-review--Gc_yplP.mjs} +0 -0
@@ -1,11 +1,12 @@
1
- import "./utils-mdb4i6VA.mjs";
2
- import "./skill-paths-DNOHrvL5.mjs";
3
- import "./scanner-BaOA18pn.mjs";
4
- import "./workspace-patterns-BZLEaMcS.mjs";
5
- import "./project-context-Dx6XIJJo.mjs";
6
- import "./resolver-CP0S8UjZ.mjs";
7
- import { a as printDebugInfo, l as printWarnings, n as coreOptionsFromGlobalFlags } from "./cli-support-Dmpj1iyQ.mjs";
8
- import { n as listIntentSkills } from "./core-0H8zUKIh.mjs";
1
+ import "./utils-Chn-30vI.mjs";
2
+ import "./skill-paths-4kQXfQXo.mjs";
3
+ import "./scanner-B6nnctK4.mjs";
4
+ import "./workspace-patterns-C5O4Dfpl.mjs";
5
+ import "./project-context-D4mFnCs7.mjs";
6
+ import "./resolver-B36uOK8c.mjs";
7
+ import { t as formatIntentCommand } from "./command-runner-DJTliSTc.mjs";
8
+ import { a as printDebugInfo, l as printWarnings, n as coreOptionsFromGlobalFlags } from "./cli-support-BHoEb9y1.mjs";
9
+ import { n as listIntentSkills } from "./core-DEiRgUqe.mjs";
9
10
 
10
11
  //#region src/commands/list.ts
11
12
  function printListDebug(result) {
@@ -17,7 +18,9 @@ function printListDebug(result) {
17
18
  ["packages", result.debug.packageCount],
18
19
  ["skills", result.debug.skillCount],
19
20
  ["warnings", result.debug.warningCount],
20
- ["conflicts", result.debug.conflictCount]
21
+ ["conflicts", result.debug.conflictCount],
22
+ ["packageJsonReadCount", result.debug.scan.packageJsonReadCount],
23
+ ["packageJsonCacheHits", result.debug.scan.packageJsonCacheHits]
21
24
  ]);
22
25
  }
23
26
  function printVersionConflicts(result) {
@@ -45,15 +48,18 @@ function groupSkillsByPackageRoot(skills) {
45
48
  function getPackageSkills(pkg, skillsByPackageRoot) {
46
49
  return skillsByPackageRoot.get(pkg.packageRoot) ?? [];
47
50
  }
51
+ function formatLoadCommand(skill, packageManager, scopeFlag) {
52
+ return formatIntentCommand(packageManager, `load ${skill.use}${scopeFlag}`);
53
+ }
48
54
  async function runListCommand(options, _scanIntentsOrFail) {
49
55
  const result = listIntentSkills(coreOptionsFromGlobalFlags(options));
50
56
  printListDebug(result);
51
57
  if (options.json) {
52
- const { debug: _debug, ...jsonResult } = result;
58
+ const { debug: _debug, packageManager: _packageManager, ...jsonResult } = result;
53
59
  console.log(JSON.stringify(jsonResult, null, 2));
54
60
  return;
55
61
  }
56
- const { computeSkillNameWidth, printSkillTree, printTable } = await import("./display-COlw5FaB.mjs");
62
+ const { computeSkillNameWidth, printSkillTree, printTable } = await import("./display-lWCJg5Bo.mjs");
57
63
  if (result.packages.length === 0) {
58
64
  console.log("No intent-enabled packages found.");
59
65
  if (result.warnings.length > 0) {
@@ -82,12 +88,14 @@ async function runListCommand(options, _scanIntentsOrFail) {
82
88
  type: skill.type
83
89
  }))));
84
90
  const showTypes = result.skills.some((skill) => skill.type);
91
+ const scopeFlag = options.globalOnly ? " --global-only" : options.global ? " --global" : "";
85
92
  console.log(`\nSkills:\n`);
86
93
  for (const pkg of result.packages) {
87
94
  console.log(` ${pkg.name}`);
88
95
  printSkillTree(getPackageSkills(pkg, skillsByPackageRoot).map((skill) => ({
89
96
  name: skill.skillName,
90
97
  description: skill.description,
98
+ loadCommand: formatLoadCommand(skill, result.packageManager, scopeFlag),
91
99
  type: skill.type
92
100
  })), {
93
101
  nameWidth,
@@ -1,12 +1,12 @@
1
- import "./utils-mdb4i6VA.mjs";
2
- import "./skill-paths-DNOHrvL5.mjs";
3
- import "./scanner-BaOA18pn.mjs";
4
- import "./workspace-patterns-BZLEaMcS.mjs";
5
- import "./project-context-Dx6XIJJo.mjs";
6
- import "./resolver-CP0S8UjZ.mjs";
7
- import { t as fail } from "./cli-error-BrMXlbtx.mjs";
8
- import { a as printDebugInfo, n as coreOptionsFromGlobalFlags } from "./cli-support-Dmpj1iyQ.mjs";
9
- import { i as resolveIntentSkill, r as loadIntentSkill, t as IntentCoreError } from "./core-0H8zUKIh.mjs";
1
+ import "./utils-Chn-30vI.mjs";
2
+ import "./skill-paths-4kQXfQXo.mjs";
3
+ import "./scanner-B6nnctK4.mjs";
4
+ import "./workspace-patterns-C5O4Dfpl.mjs";
5
+ import "./project-context-D4mFnCs7.mjs";
6
+ import "./resolver-B36uOK8c.mjs";
7
+ import { t as fail } from "./cli-error-DOO5bLIG.mjs";
8
+ import { a as printDebugInfo, n as coreOptionsFromGlobalFlags } from "./cli-support-BHoEb9y1.mjs";
9
+ import { i as resolveIntentSkill, r as loadIntentSkill, t as IntentCoreError } from "./core-DEiRgUqe.mjs";
10
10
 
11
11
  //#region src/commands/load.ts
12
12
  function printLoadDebug(loaded) {
@@ -21,7 +21,9 @@ function printLoadDebug(loaded) {
21
21
  ["source", loaded.debug.source],
22
22
  ["skill", loaded.debug.skillName],
23
23
  ["path", loaded.debug.path],
24
- ["warnings", loaded.debug.warningCount]
24
+ ["warnings", loaded.debug.warningCount],
25
+ ["packageJsonReadCount", loaded.debug.scan.packageJsonReadCount],
26
+ ["packageJsonCacheHits", loaded.debug.scan.packageJsonCacheHits]
25
27
  ]);
26
28
  }
27
29
  async function runLoadCommand(use, options, _scanIntentsOrFail) {
@@ -1,4 +1,4 @@
1
- import { t as fail } from "./cli-error-BrMXlbtx.mjs";
1
+ import { t as fail } from "./cli-error-DOO5bLIG.mjs";
2
2
  import { existsSync, readFileSync, readdirSync } from "node:fs";
3
3
  import { join } from "node:path";
4
4
 
@@ -16,7 +16,7 @@ async function runMetaCommand(name, metaDir) {
16
16
  }
17
17
  return;
18
18
  }
19
- const { parseFrontmatter } = await import("./utils-BHzSyNeJ.mjs");
19
+ const { parseFrontmatter } = await import("./utils-Ctlz_JG-.mjs");
20
20
  const entries = readdirSync(metaDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).filter((entry) => existsSync(join(metaDir, entry.name, "SKILL.md")));
21
21
  if (entries.length === 0) {
22
22
  console.log("No meta-skills found.");
@@ -0,0 +1,48 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { dirname, join, resolve } from "node:path";
3
+
4
+ //#region src/package-manager.ts
5
+ function readPackageManagerField(dir) {
6
+ try {
7
+ const parsed = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
8
+ if (!parsed || typeof parsed !== "object") return null;
9
+ const value = parsed.packageManager;
10
+ if (typeof value !== "string") return null;
11
+ if (value.startsWith("pnpm@")) return "pnpm";
12
+ if (value.startsWith("yarn@")) return "yarn";
13
+ if (value.startsWith("bun@")) return "bun";
14
+ if (value.startsWith("npm@")) return "npm";
15
+ } catch {
16
+ return null;
17
+ }
18
+ return null;
19
+ }
20
+ function detectPackageManagerInDir(dir) {
21
+ const packageManager = readPackageManagerField(dir);
22
+ if (packageManager) return packageManager;
23
+ if (existsSync(join(dir, ".pnp.cjs")) || existsSync(join(dir, ".pnp.js"))) return "yarn";
24
+ if (existsSync(join(dir, "pnpm-lock.yaml"))) return "pnpm";
25
+ if (existsSync(join(dir, "bun.lockb")) || existsSync(join(dir, "bun.lock"))) return "bun";
26
+ if (existsSync(join(dir, "yarn.lock"))) return "yarn";
27
+ if (existsSync(join(dir, "package-lock.json"))) return "npm";
28
+ return null;
29
+ }
30
+ function detectPackageManager(cwd = process.cwd(), extraDirs = []) {
31
+ const seen = /* @__PURE__ */ new Set();
32
+ const startDirs = [cwd, ...extraDirs].filter((dir) => Boolean(dir));
33
+ for (const startDir of startDirs) {
34
+ let dir = resolve(startDir);
35
+ while (!seen.has(dir)) {
36
+ seen.add(dir);
37
+ const packageManager = detectPackageManagerInDir(dir);
38
+ if (packageManager) return packageManager;
39
+ const next = dirname(dir);
40
+ if (next === dir) break;
41
+ dir = next;
42
+ }
43
+ }
44
+ return "unknown";
45
+ }
46
+
47
+ //#endregion
48
+ export { detectPackageManager as t };
@@ -1,4 +1,4 @@
1
- import { a as readWorkspacePatterns, r as findWorkspaceRoot } from "./workspace-patterns-BZLEaMcS.mjs";
1
+ import { a as readWorkspacePatterns, r as findWorkspaceRoot } from "./workspace-patterns-C5O4Dfpl.mjs";
2
2
  import { existsSync, statSync } from "node:fs";
3
3
  import { dirname, join, relative, resolve } from "node:path";
4
4
 
@@ -1,5 +1,5 @@
1
- import { i as parseSkillUse } from "./skill-use-umYvZl94.mjs";
2
- import { t as resolveProjectContext } from "./project-context-Dx6XIJJo.mjs";
1
+ import { i as parseSkillUse } from "./skill-use-C0q2MEEX.mjs";
2
+ import { t as resolveProjectContext } from "./project-context-D4mFnCs7.mjs";
3
3
  import { readFileSync } from "node:fs";
4
4
  import { dirname, isAbsolute, join, relative, resolve } from "node:path";
5
5
 
@@ -193,4 +193,4 @@ function formatSkillSuggestions(packageName, skillNames) {
193
193
  }
194
194
 
195
195
  //#endregion
196
- export { compileExcludePatterns as a, warningMentionsPackage as c, resolveSkillUse as i, readPackageJson as l, isResolveSkillUseError as n, getEffectiveExcludePatterns as o, resolveSkillEntry as r, isPackageExcluded as s, ResolveSkillUseError as t };
196
+ export { compileExcludePatterns as a, warningMentionsPackage as c, resolveSkillUse as i, isResolveSkillUseError as n, getEffectiveExcludePatterns as o, resolveSkillEntry as r, isPackageExcluded as s, ResolveSkillUseError as t };
@@ -1,8 +1,9 @@
1
- import { a as parseFrontmatter, i as listNodeModulesPackageDirs, o as resolveDepDir, r as getDeps, s as toPosixPath, t as detectGlobalNodeModules } from "./utils-mdb4i6VA.mjs";
2
- import { r as rewriteSkillLoadPaths } from "./skill-paths-DNOHrvL5.mjs";
3
- import { a as readWorkspacePatterns, o as resolveWorkspacePackages, r as findWorkspaceRoot } from "./workspace-patterns-BZLEaMcS.mjs";
1
+ import { a as listNestedNodeModulesPackageDirs, c as resolveDepDir, i as getDeps, l as toPosixPath, n as detectGlobalNodeModules, o as listNodeModulesPackageDirs, r as findSkillFiles, s as parseFrontmatter, t as createFsIdentityCache } from "./utils-Chn-30vI.mjs";
2
+ import { r as rewriteSkillLoadPaths } from "./skill-paths-4kQXfQXo.mjs";
3
+ import { n as findWorkspacePackages, r as findWorkspaceRoot } from "./workspace-patterns-C5O4Dfpl.mjs";
4
+ import { t as detectPackageManager } from "./package-manager-DDZck142.mjs";
4
5
  import { createRequire } from "node:module";
5
- import { existsSync, readFileSync, readdirSync } from "node:fs";
6
+ import { existsSync, readFileSync } from "node:fs";
6
7
  import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
7
8
  import semver from "semver";
8
9
 
@@ -11,12 +12,28 @@ function isLocalToProject(dirPath, projectRoot) {
11
12
  return dirPath.startsWith(projectRoot + sep) || dirPath.startsWith(projectRoot + "/");
12
13
  }
13
14
  function createPackageRegistrar(opts) {
15
+ const attemptedPackageRoots = /* @__PURE__ */ new Set();
16
+ const scannedNodeModulesDirs = /* @__PURE__ */ new Set();
17
+ function shouldAttemptPackageRoot(dirPath) {
18
+ const key = opts.getFsIdentity(dirPath);
19
+ if (attemptedPackageRoots.has(key)) return false;
20
+ attemptedPackageRoots.add(key);
21
+ return true;
22
+ }
23
+ function scanNodeModulesDir(nodeModulesDir, source = "local") {
24
+ if (!existsSync(nodeModulesDir)) return;
25
+ const key = opts.getFsIdentity(nodeModulesDir);
26
+ if (scannedNodeModulesDirs.has(key)) return;
27
+ scannedNodeModulesDirs.add(key);
28
+ for (const dirPath of listNodeModulesPackageDirs(nodeModulesDir)) tryRegister(dirPath, "unknown", source);
29
+ }
14
30
  function scanTarget(target, source = "local") {
15
31
  if (!target.path || !target.exists || target.scanned) return;
16
32
  target.scanned = true;
17
- for (const dirPath of listNodeModulesPackageDirs(target.path)) tryRegister(dirPath, "unknown", source);
33
+ scanNodeModulesDir(target.path, source);
18
34
  }
19
35
  function tryRegister(dirPath, fallbackName, source = "local") {
36
+ if (!shouldAttemptPackageRoot(dirPath)) return false;
20
37
  const skillsDir = join(dirPath, "skills");
21
38
  if (!existsSync(skillsDir)) return false;
22
39
  const pkgJson = opts.readPkgJson(dirPath);
@@ -62,6 +79,7 @@ function createPackageRegistrar(opts) {
62
79
  return true;
63
80
  }
64
81
  return {
82
+ scanNodeModulesDir,
65
83
  scanTarget,
66
84
  tryRegister
67
85
  };
@@ -73,10 +91,11 @@ function createDependencyWalker(opts) {
73
91
  const walkVisited = /* @__PURE__ */ new Set();
74
92
  const depDirCache = /* @__PURE__ */ new Map();
75
93
  function resolveDepDirCached(depName, fromDir) {
76
- let byDepName = depDirCache.get(fromDir);
94
+ const fromKey = opts.getFsIdentity(fromDir);
95
+ let byDepName = depDirCache.get(fromKey);
77
96
  if (!byDepName) {
78
97
  byDepName = /* @__PURE__ */ new Map();
79
- depDirCache.set(fromDir, byDepName);
98
+ depDirCache.set(fromKey, byDepName);
80
99
  }
81
100
  if (!byDepName.has(depName)) byDepName.set(depName, resolveDepDir(depName, fromDir));
82
101
  return byDepName.get(depName) ?? null;
@@ -84,14 +103,15 @@ function createDependencyWalker(opts) {
84
103
  function walkDepsOf(pkgJson, fromDir, includeDevDeps = false) {
85
104
  for (const depName of getDeps(pkgJson, includeDevDeps)) {
86
105
  const depDir = resolveDepDirCached(depName, fromDir);
87
- if (!depDir || walkVisited.has(depDir)) continue;
106
+ if (!depDir) continue;
88
107
  opts.tryRegister(depDir, depName);
89
108
  walkDeps(depDir, depName);
90
109
  }
91
110
  }
92
111
  function walkDeps(pkgDir, pkgName) {
93
- if (walkVisited.has(pkgDir)) return;
94
- walkVisited.add(pkgDir);
112
+ const pkgKey = opts.getFsIdentity(pkgDir);
113
+ if (walkVisited.has(pkgKey)) return;
114
+ walkVisited.add(pkgKey);
95
115
  const pkgJson = opts.readPkgJson(pkgDir);
96
116
  if (!pkgJson) {
97
117
  opts.warnings.push(`Could not read package.json for ${pkgName} (skipping dependency walk)`);
@@ -108,30 +128,93 @@ function createDependencyWalker(opts) {
108
128
  walkDepsOf(projectPkg, opts.projectRoot, true);
109
129
  }
110
130
  function readPkgJsonWithWarning(dirPath, label) {
111
- try {
112
- return JSON.parse(readFileSync(join(dirPath, "package.json"), "utf8"));
113
- } catch (err) {
114
- if (err.code !== "ENOENT") opts.warnings.push(`Could not read ${label} package.json at ${dirPath}: ${err.message}`);
131
+ const result = opts.fsCache.readPackageJsonResult(dirPath);
132
+ if (!result.packageJson) {
133
+ if (result.error?.code !== "ENOENT") opts.warnings.push(`Could not read ${label} package.json at ${dirPath}: ${result.error instanceof Error ? result.error.message : "invalid package.json"}`);
115
134
  return null;
116
135
  }
136
+ return result.packageJson;
117
137
  }
118
138
  function walkWorkspacePackages() {
119
- const workspacePatterns = readWorkspacePatterns(opts.projectRoot);
120
- if (!workspacePatterns) return;
121
- for (const wsDir of resolveWorkspacePackages(opts.projectRoot, workspacePatterns)) {
122
- const wsNodeModules = join(wsDir, "node_modules");
123
- if (existsSync(wsNodeModules)) for (const dirPath of listNodeModulesPackageDirs(wsNodeModules)) opts.tryRegister(dirPath, "unknown");
139
+ for (const wsDir of findWorkspacePackages(opts.projectRoot)) {
140
+ opts.scanNodeModulesDir(join(wsDir, "node_modules"));
124
141
  const wsPkg = readPkgJsonWithWarning(wsDir, "workspace");
125
142
  if (wsPkg) walkDepsOf(wsPkg, wsDir);
126
143
  }
127
144
  }
145
+ function scanNestedNodeModulesDir(nodeModulesDir) {
146
+ for (const dirPath of listNestedNodeModulesPackageDirs(nodeModulesDir, opts.getFsIdentity)) {
147
+ if (!opts.tryRegister(dirPath, "unknown")) continue;
148
+ const pkgJson = opts.readPkgJson(dirPath);
149
+ walkDeps(dirPath, typeof pkgJson?.name === "string" ? pkgJson.name : "unknown");
150
+ }
151
+ }
128
152
  return {
153
+ scanNestedNodeModulesDir,
129
154
  walkKnownPackages,
130
155
  walkProjectDeps,
131
156
  walkWorkspacePackages
132
157
  };
133
158
  }
134
159
 
160
+ //#endregion
161
+ //#region src/fs-cache.ts
162
+ function isRecord(value) {
163
+ return typeof value === "object" && value !== null && !Array.isArray(value);
164
+ }
165
+ function createIntentFsCache() {
166
+ const packageJsonCache = /* @__PURE__ */ new Map();
167
+ const skillFilesCache = /* @__PURE__ */ new Map();
168
+ const getFsIdentity = createFsIdentityCache();
169
+ const stats = {
170
+ packageJsonReadCount: 0,
171
+ packageJsonCacheHits: 0
172
+ };
173
+ function readPackageJsonResult(dir) {
174
+ const key = getFsIdentity(dir);
175
+ const cached = packageJsonCache.get(key);
176
+ if (cached) {
177
+ stats.packageJsonCacheHits += 1;
178
+ return cached;
179
+ }
180
+ stats.packageJsonReadCount += 1;
181
+ try {
182
+ const parsed = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
183
+ const result = {
184
+ packageJson: isRecord(parsed) ? parsed : null,
185
+ error: null
186
+ };
187
+ packageJsonCache.set(key, result);
188
+ return result;
189
+ } catch (error) {
190
+ const result = {
191
+ packageJson: null,
192
+ error
193
+ };
194
+ packageJsonCache.set(key, result);
195
+ return result;
196
+ }
197
+ }
198
+ function readPackageJson(dir) {
199
+ return readPackageJsonResult(dir).packageJson;
200
+ }
201
+ function findSkillFiles$1(dir) {
202
+ const key = getFsIdentity(dir);
203
+ const cached = skillFilesCache.get(key);
204
+ if (cached) return [...cached];
205
+ const files = findSkillFiles(dir);
206
+ skillFilesCache.set(key, files);
207
+ return [...files];
208
+ }
209
+ return {
210
+ readPackageJson,
211
+ readPackageJsonResult,
212
+ findSkillFiles: findSkillFiles$1,
213
+ getFsIdentity,
214
+ getStats: () => ({ ...stats })
215
+ };
216
+ }
217
+
135
218
  //#endregion
136
219
  //#region src/scanner.ts
137
220
  const requireFromHere = createRequire(import.meta.url);
@@ -147,36 +230,22 @@ function findPnpFile(start) {
147
230
  dir = next;
148
231
  }
149
232
  }
150
- function isYarnPnpProject(root) {
151
- return findPnpFile(root) !== null;
152
- }
153
233
  function assertLocalNodeModulesSupported(root) {
154
234
  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.");
155
235
  }
156
- function detectPackageManager(root) {
157
- const dirsToCheck = [root];
158
- const wsRoot = findWorkspaceRoot(root);
159
- if (wsRoot && wsRoot !== root) dirsToCheck.push(wsRoot);
160
- for (const dir of dirsToCheck) {
161
- if (isYarnPnpProject(dir)) return "yarn";
162
- if (existsSync(join(dir, "pnpm-lock.yaml"))) return "pnpm";
163
- if (existsSync(join(dir, "bun.lockb")) || existsSync(join(dir, "bun.lock"))) return "bun";
164
- if (existsSync(join(dir, "yarn.lock"))) return "yarn";
165
- if (existsSync(join(dir, "package-lock.json"))) return "npm";
166
- }
167
- return "unknown";
168
- }
169
236
  function loadPnpApi(root) {
170
237
  const pnpPath = findPnpFile(root);
171
238
  if (!pnpPath) return null;
172
239
  try {
173
- const foundApi = requireFromHere("node:module").findPnpApi?.(root);
174
- if (foundApi) return foundApi;
175
240
  const pnpModule = requireFromHere(pnpPath);
176
241
  if (typeof pnpModule.setup === "function") pnpModule.setup();
177
242
  if (typeof pnpModule.getDependencyTreeRoots === "function" && typeof pnpModule.getPackageInformation === "function") return pnpModule;
178
243
  return createRequire(join(dirname(pnpPath), "package.json"))("pnpapi");
179
244
  } catch (err) {
245
+ try {
246
+ const foundApi = requireFromHere("node:module").findPnpApi?.(root);
247
+ if (foundApi) return foundApi;
248
+ } catch {}
180
249
  const msg = err instanceof Error ? err.message : String(err);
181
250
  throw new Error(`Yarn PnP project detected, but Intent could not load Yarn's PnP API from ${pnpPath}: ${msg}`);
182
251
  }
@@ -261,28 +330,12 @@ function discoverSkillByNameHint(skillsDir, packageName, skillNameHint) {
261
330
  }
262
331
  return skills;
263
332
  }
264
- function discoverSkills(skillsDir) {
265
- const skills = [];
266
- function walk(dir) {
267
- let entries;
268
- try {
269
- entries = readdirSync(dir, {
270
- withFileTypes: true,
271
- encoding: "utf8"
272
- });
273
- } catch {
274
- return;
275
- }
276
- for (const entry of entries) {
277
- if (!entry.isDirectory()) continue;
278
- const childDir = join(dir, entry.name);
279
- const skillFile = join(childDir, "SKILL.md");
280
- if (existsSync(skillFile)) skills.push(readSkillEntry(skillsDir, childDir, skillFile));
281
- walk(childDir);
282
- }
283
- }
284
- walk(skillsDir);
285
- return skills;
333
+ function discoverSkills(skillsDir, fsCache) {
334
+ return fsCache.findSkillFiles(skillsDir).flatMap((skillFile) => {
335
+ const childDir = dirname(skillFile);
336
+ if (childDir === skillsDir) return [];
337
+ return [readSkillEntry(skillsDir, childDir, skillFile)];
338
+ });
286
339
  }
287
340
  function getPackageShortName(packageName) {
288
341
  return packageName.split("/").pop() ?? packageName;
@@ -364,7 +417,9 @@ function getScanScope(options) {
364
417
  function scanForIntents(root, options = {}) {
365
418
  const projectRoot = root ?? process.cwd();
366
419
  const scanScope = getScanScope(options);
367
- const packageManager = detectPackageManager(projectRoot);
420
+ const fsCache = options.fsCache ?? createIntentFsCache();
421
+ const workspaceRoot = findWorkspaceRoot(projectRoot);
422
+ const packageManager = detectPackageManager(projectRoot, [workspaceRoot]);
368
423
  const nodeModulesDir = join(projectRoot, "node_modules");
369
424
  const explicitGlobalNodeModules = process.env.INTENT_GLOBAL_NODE_MODULES?.trim() || null;
370
425
  const packages = [];
@@ -386,7 +441,6 @@ function scanForIntents(root, options = {}) {
386
441
  }
387
442
  };
388
443
  const packageIndexes = /* @__PURE__ */ new Map();
389
- const packageJsonCache = /* @__PURE__ */ new Map();
390
444
  const packageVariants = /* @__PURE__ */ new Map();
391
445
  let pnpApi;
392
446
  function getPnpApi() {
@@ -394,6 +448,9 @@ function scanForIntents(root, options = {}) {
394
448
  if (pnpApi === void 0) pnpApi = loadPnpApi(projectRoot);
395
449
  return pnpApi;
396
450
  }
451
+ function getStats() {
452
+ return fsCache.getStats();
453
+ }
397
454
  function rememberVariant(pkg) {
398
455
  let variants = packageVariants.get(pkg.name);
399
456
  if (!variants) {
@@ -415,21 +472,14 @@ function scanForIntents(root, options = {}) {
415
472
  }
416
473
  }
417
474
  function readPkgJson(dirPath) {
418
- if (packageJsonCache.has(dirPath)) return packageJsonCache.get(dirPath) ?? null;
419
- try {
420
- const pkgJson = JSON.parse(readFileSync(join(dirPath, "package.json"), "utf8"));
421
- packageJsonCache.set(dirPath, pkgJson);
422
- return pkgJson;
423
- } catch {
424
- packageJsonCache.set(dirPath, null);
425
- return null;
426
- }
475
+ return fsCache.readPackageJson(dirPath);
427
476
  }
428
- const { scanTarget, tryRegister } = createPackageRegistrar({
477
+ const { scanNodeModulesDir, scanTarget, tryRegister } = createPackageRegistrar({
429
478
  comparePackageVersions,
430
479
  deriveIntentConfig,
431
- discoverSkills,
480
+ discoverSkills: (skillsDir) => discoverSkills(skillsDir, fsCache),
432
481
  getPackageDepth,
482
+ getFsIdentity: fsCache.getFsIdentity,
433
483
  packageIndexes,
434
484
  packages,
435
485
  projectRoot,
@@ -438,16 +488,18 @@ function scanForIntents(root, options = {}) {
438
488
  validateIntentField,
439
489
  warnings
440
490
  });
441
- const { walkKnownPackages, walkProjectDeps, walkWorkspacePackages } = createDependencyWalker({
491
+ const { scanNestedNodeModulesDir, walkKnownPackages, walkProjectDeps, walkWorkspacePackages } = createDependencyWalker({
492
+ fsCache,
493
+ getFsIdentity: fsCache.getFsIdentity,
442
494
  packages,
443
495
  projectRoot,
444
496
  readPkgJson,
497
+ scanNodeModulesDir,
445
498
  tryRegister,
446
499
  warnings
447
500
  });
448
501
  function scanPnpPackages(api) {
449
502
  const visited = /* @__PURE__ */ new Set();
450
- const workspaceRoot = findWorkspaceRoot(projectRoot);
451
503
  const projectLocator = api.findPackageLocator?.(projectRoot.endsWith(sep) ? projectRoot : `${projectRoot}${sep}`);
452
504
  const roots = workspaceRoot && workspaceRoot !== projectRoot && projectLocator ? [projectLocator] : api.getDependencyTreeRoots?.() ?? (api.topLevel ? [api.topLevel] : []);
453
505
  function visit(locator) {
@@ -473,12 +525,15 @@ function scanForIntents(root, options = {}) {
473
525
  }
474
526
  }
475
527
  assertLocalNodeModulesSupported(projectRoot);
528
+ const packageCountBeforeLocalDiscovery = packages.length;
476
529
  walkWorkspacePackages();
477
530
  const packageCountBeforeDependencyDiscovery = packages.length;
478
531
  scanTarget(nodeModules.local);
479
532
  walkKnownPackages();
480
533
  walkProjectDeps();
481
- if (packages.length === packageCountBeforeDependencyDiscovery) {
534
+ const shouldTryPnpFallback = packages.length === packageCountBeforeDependencyDiscovery;
535
+ if (nodeModules.local.path && nodeModules.local.exists && packages.length === packageCountBeforeLocalDiscovery) scanNestedNodeModulesDir(nodeModules.local.path);
536
+ if (shouldTryPnpFallback) {
482
537
  const api = getPnpApi();
483
538
  if (api) scanPnpPackages(api);
484
539
  }
@@ -506,7 +561,8 @@ function scanForIntents(root, options = {}) {
506
561
  packages,
507
562
  warnings,
508
563
  conflicts,
509
- nodeModules
564
+ nodeModules,
565
+ stats: getStats()
510
566
  };
511
567
  for (const pkg of packages) {
512
568
  const variants = packageVariants.get(pkg.name);
@@ -521,7 +577,8 @@ function scanForIntents(root, options = {}) {
521
577
  packages: topoSort(packages),
522
578
  warnings,
523
579
  conflicts,
524
- nodeModules
580
+ nodeModules,
581
+ stats: getStats()
525
582
  };
526
583
  }
527
584
  function scanIntentPackageAtRoot(packageRoot, options = {}) {
@@ -529,23 +586,16 @@ function scanIntentPackageAtRoot(packageRoot, options = {}) {
529
586
  const packages = [];
530
587
  const warnings = [];
531
588
  const packageIndexes = /* @__PURE__ */ new Map();
532
- const packageJsonCache = /* @__PURE__ */ new Map();
589
+ const fsCache = options.fsCache ?? createIntentFsCache();
533
590
  function readPkgJson(dirPath) {
534
- if (packageJsonCache.has(dirPath)) return packageJsonCache.get(dirPath) ?? null;
535
- try {
536
- const pkgJson = JSON.parse(readFileSync(join(dirPath, "package.json"), "utf8"));
537
- packageJsonCache.set(dirPath, pkgJson);
538
- return pkgJson;
539
- } catch {
540
- packageJsonCache.set(dirPath, null);
541
- return null;
542
- }
591
+ return fsCache.readPackageJson(dirPath);
543
592
  }
544
593
  const { tryRegister } = createPackageRegistrar({
545
594
  comparePackageVersions,
546
595
  deriveIntentConfig,
547
- discoverSkills: options.skillNameHint ? (skillsDir, packageName) => discoverSkillByNameHint(skillsDir, packageName, options.skillNameHint) : discoverSkills,
596
+ discoverSkills: options.skillNameHint ? (skillsDir, packageName) => discoverSkillByNameHint(skillsDir, packageName, options.skillNameHint) : (skillsDir) => discoverSkills(skillsDir, fsCache),
548
597
  getPackageDepth,
598
+ getFsIdentity: fsCache.getFsIdentity,
549
599
  packageIndexes,
550
600
  packages,
551
601
  projectRoot,
@@ -562,4 +612,4 @@ function scanIntentPackageAtRoot(packageRoot, options = {}) {
562
612
  }
563
613
 
564
614
  //#endregion
565
- export { scanIntentPackageAtRoot as n, scanForIntents as t };
615
+ export { scanIntentPackageAtRoot as n, createIntentFsCache as r, scanForIntents as t };
@@ -0,0 +1,6 @@
1
+ import "./utils-Chn-30vI.mjs";
2
+ import "./skill-paths-4kQXfQXo.mjs";
3
+ import { n as scanIntentPackageAtRoot, t as scanForIntents } from "./scanner-B6nnctK4.mjs";
4
+ import "./workspace-patterns-C5O4Dfpl.mjs";
5
+
6
+ export { scanForIntents };
@@ -1,5 +1,5 @@
1
- import { a as readWorkspacePatterns, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-BZLEaMcS.mjs";
2
- import { t as resolveProjectContext } from "./project-context-Dx6XIJJo.mjs";
1
+ import { a as readWorkspacePatterns, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-C5O4Dfpl.mjs";
2
+ import { t as resolveProjectContext } from "./project-context-D4mFnCs7.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-2SE9zYJk.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-DL7qX_F-.mjs";
2
2
  export { EditPackageJsonResult, MonorepoResult, SetupGithubActionsResult, findPackagesWithSkills, findWorkspaceRoot, readWorkspacePatterns, resolveWorkspacePackages, runEditPackageJson, runEditPackageJsonAll, runSetupGithubActions };
package/dist/setup.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import "./utils-mdb4i6VA.mjs";
2
- import { a as readWorkspacePatterns, o as resolveWorkspacePackages, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-BZLEaMcS.mjs";
3
- import "./project-context-Dx6XIJJo.mjs";
4
- import { n as runEditPackageJsonAll, r as runSetupGithubActions, t as runEditPackageJson } from "./setup-kvWN4xCr.mjs";
1
+ import "./utils-Chn-30vI.mjs";
2
+ import { a as readWorkspacePatterns, o as resolveWorkspacePackages, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-C5O4Dfpl.mjs";
3
+ import "./project-context-D4mFnCs7.mjs";
4
+ import { n as runEditPackageJsonAll, r as runSetupGithubActions, t as runEditPackageJson } from "./setup-J4A9UfBB.mjs";
5
5
 
6
6
  export { findPackagesWithSkills, findWorkspaceRoot, readWorkspacePatterns, resolveWorkspacePackages, runEditPackageJson, runEditPackageJsonAll, runSetupGithubActions };
@@ -1,4 +1,4 @@
1
- import { s as toPosixPath } from "./utils-mdb4i6VA.mjs";
1
+ import { l as toPosixPath } from "./utils-Chn-30vI.mjs";
2
2
  import { existsSync } from "node:fs";
3
3
  import { join, relative } from "node:path";
4
4
 
@@ -33,7 +33,7 @@ async function runStaleCommand(targetDir, options, resolveStaleTargets) {
33
33
  }
34
34
  }
35
35
  async function runGithubReview(targetDir, options, resolveStaleTargets) {
36
- const { collectStaleReviewItems, createFailedStaleReviewItem, createWorkflowAdvisoryReviewItems, writeStaleReviewWorkflowFiles } = await import("./workflow-review-CIdJXmKP.mjs");
36
+ const { collectStaleReviewItems, createFailedStaleReviewItem, createWorkflowAdvisoryReviewItems, writeStaleReviewWorkflowFiles } = await import("./workflow-review-DcFipeG0.mjs");
37
37
  const packageLabel = options.packageLabel ?? "workspace";
38
38
  try {
39
39
  const { reports, workflowAdvisories = [] } = await resolveStaleTargets(targetDir);
@@ -1,5 +1,5 @@
1
- import { a as parseFrontmatter, n as findSkillFiles, s as toPosixPath } from "./utils-mdb4i6VA.mjs";
2
- import { t as readIntentArtifacts } from "./artifact-coverage-DgWuVqUp.mjs";
1
+ import { l as toPosixPath, r as findSkillFiles, s as parseFrontmatter } from "./utils-Chn-30vI.mjs";
2
+ import { t as readIntentArtifacts } from "./artifact-coverage-Cqphhpfo.mjs";
3
3
  import { existsSync, readFileSync } from "node:fs";
4
4
  import { isAbsolute, join, relative, resolve } from "node:path";
5
5
  import semver from "semver";
@@ -0,0 +1,5 @@
1
+ import "./utils-Chn-30vI.mjs";
2
+ import "./artifact-coverage-Cqphhpfo.mjs";
3
+ import { n as checkStaleness, r as readPackageName, t as buildWorkspaceCoverageSignals } from "./staleness-DChVhbCN.mjs";
4
+
5
+ export { buildWorkspaceCoverageSignals, checkStaleness, readPackageName };