@tanstack/intent 0.0.40 → 0.0.42

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 (49) hide show
  1. package/dist/{cli-support-Cb9lNXhL.mjs → cli-support-B26oUGbf.mjs} +4 -4
  2. package/dist/{cli-support-DtqVDiJv.mjs → cli-support-C-t4xQw0.mjs} +4 -4
  3. package/dist/cli.d.mts +2 -1
  4. package/dist/cli.mjs +20 -16
  5. package/dist/command-runner-C0yCOHLi.mjs +16 -0
  6. package/dist/{core-BOSjgetf.mjs → core-CEeo37aT.mjs} +26 -23
  7. package/dist/core.d.mts +2 -1
  8. package/dist/core.mjs +7 -7
  9. package/dist/{display-DHNuzSqR.mjs → display-BdSvrwWJ.mjs} +14 -3
  10. package/dist/index.d.mts +2 -2
  11. package/dist/index.mjs +9 -9
  12. package/dist/{install-CLkmoPOY.mjs → install-t4jkDdD0.mjs} +16 -9
  13. package/dist/{list-CxSm8YYl.mjs → list-DQxqa1AT.mjs} +16 -10
  14. package/dist/{load-DF-zIT3-.mjs → load-3ACx3170.mjs} +8 -8
  15. package/dist/{meta-BNSVXFQu.mjs → meta-DZgsju5x.mjs} +1 -1
  16. package/dist/package-manager-BUgTjW9Q.mjs +48 -0
  17. package/dist/{project-context-Bv9BDh8B.mjs → project-context-4wzbLY9c.mjs} +6 -5
  18. package/dist/{resolver-BDsZ3kWg.mjs → resolver-D8sX72Lg.mjs} +5 -6
  19. package/dist/scanner-BK8rIEA3.mjs +6 -0
  20. package/dist/{scanner-BGyQTQ3U.mjs → scanner-QujEINYm.mjs} +44 -44
  21. package/dist/{setup-DQMKxEoA.mjs → setup-BElEzHxS.mjs} +2 -2
  22. package/dist/setup.d.mts +1 -1
  23. package/dist/setup.mjs +4 -4
  24. package/dist/{skill-paths-BHbdWniB.mjs → skill-paths-Cc0-Y331.mjs} +1 -1
  25. package/dist/{stale-flPZnWfI.mjs → stale-C6dPKQ98.mjs} +1 -1
  26. package/dist/{staleness-CGLs-swr.mjs → staleness-BwcLygsY.mjs} +1 -1
  27. package/dist/{staleness-Dl-m8JWM.mjs → staleness-Dd1kWwCz.mjs} +2 -2
  28. package/dist/{types-Cq5cY9h9.d.mts → types-CIha6LtJ.d.mts} +3 -2
  29. package/dist/{utils-BPDvfmcd.mjs → utils-CF7OL__5.mjs} +64 -7
  30. package/dist/utils-DTvYXAsM.mjs +3 -0
  31. package/dist/{validate-Divq4AiV.mjs → validate-D0n-rBpp.mjs} +5 -5
  32. package/dist/{workflow-review-CIdJXmKP.mjs → workflow-review-CrWkP7Hc.mjs} +1 -1
  33. package/dist/{workflow-review-CwcR2ge4.mjs → workflow-review-D9Fg1G0P.mjs} +15 -15
  34. package/dist/{workspace-patterns-Diy5gtz_.mjs → workspace-patterns-CnGMcicG.mjs} +2 -2
  35. package/dist/{workspace-patterns-CIJQCwbJ.mjs → workspace-patterns-FljtM2Xb.mjs} +7 -8
  36. package/package.json +3 -8
  37. package/dist/display-CmLzVAae.mjs +0 -5
  38. package/dist/install-ChddjnhO.mjs +0 -7
  39. package/dist/intent-library.d.mts +0 -1
  40. package/dist/intent-library.mjs +0 -84
  41. package/dist/library-scanner-BAJ7bXtW.mjs +0 -116
  42. package/dist/library-scanner.d.mts +0 -16
  43. package/dist/library-scanner.mjs +0 -5
  44. package/dist/scanner-Ix6MmxfB.mjs +0 -6
  45. package/dist/utils-DqdIC3RY.mjs +0 -3
  46. /package/dist/{edit-package-json-CzWlMXOf.mjs → edit-package-json-CtuelQ_q.mjs} +0 -0
  47. /package/dist/{scaffold-D2vwv9ls.mjs → scaffold-CLM6bt3c.mjs} +0 -0
  48. /package/dist/{setup-2SE9zYJk.d.mts → setup-DhMqESd3.d.mts} +0 -0
  49. /package/dist/{setup-github-actions-emXSyGy3.mjs → setup-github-actions-CUd1oncY.mjs} +0 -0
@@ -1,6 +1,7 @@
1
- import { a as parseFrontmatter, i as listNodeModulesPackageDirs, n as findSkillFiles, o as resolveDepDir, r as getDeps, s as toPosixPath, t as detectGlobalNodeModules } from "./utils-BPDvfmcd.mjs";
2
- import { r as rewriteSkillLoadPaths } from "./skill-paths-BHbdWniB.mjs";
3
- import { n as findWorkspacePackages, r as findWorkspaceRoot } from "./workspace-patterns-CIJQCwbJ.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-CF7OL__5.mjs";
2
+ import { r as rewriteSkillLoadPaths } from "./skill-paths-Cc0-Y331.mjs";
3
+ import { n as findWorkspacePackages, r as findWorkspaceRoot } from "./workspace-patterns-FljtM2Xb.mjs";
4
+ import { t as detectPackageManager } from "./package-manager-BUgTjW9Q.mjs";
4
5
  import { createRequire } from "node:module";
5
6
  import { existsSync, readFileSync } from "node:fs";
6
7
  import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
@@ -10,21 +11,18 @@ import semver from "semver";
10
11
  function isLocalToProject(dirPath, projectRoot) {
11
12
  return dirPath.startsWith(projectRoot + sep) || dirPath.startsWith(projectRoot + "/");
12
13
  }
13
- function getFsIdentity(path) {
14
- return resolve(path);
15
- }
16
14
  function createPackageRegistrar(opts) {
17
15
  const attemptedPackageRoots = /* @__PURE__ */ new Set();
18
16
  const scannedNodeModulesDirs = /* @__PURE__ */ new Set();
19
17
  function shouldAttemptPackageRoot(dirPath) {
20
- const key = getFsIdentity(dirPath);
18
+ const key = opts.getFsIdentity(dirPath);
21
19
  if (attemptedPackageRoots.has(key)) return false;
22
20
  attemptedPackageRoots.add(key);
23
21
  return true;
24
22
  }
25
23
  function scanNodeModulesDir(nodeModulesDir, source = "local") {
26
24
  if (!existsSync(nodeModulesDir)) return;
27
- const key = getFsIdentity(nodeModulesDir);
25
+ const key = opts.getFsIdentity(nodeModulesDir);
28
26
  if (scannedNodeModulesDirs.has(key)) return;
29
27
  scannedNodeModulesDirs.add(key);
30
28
  for (const dirPath of listNodeModulesPackageDirs(nodeModulesDir)) tryRegister(dirPath, "unknown", source);
@@ -93,10 +91,11 @@ function createDependencyWalker(opts) {
93
91
  const walkVisited = /* @__PURE__ */ new Set();
94
92
  const depDirCache = /* @__PURE__ */ new Map();
95
93
  function resolveDepDirCached(depName, fromDir) {
96
- let byDepName = depDirCache.get(fromDir);
94
+ const fromKey = opts.getFsIdentity(fromDir);
95
+ let byDepName = depDirCache.get(fromKey);
97
96
  if (!byDepName) {
98
97
  byDepName = /* @__PURE__ */ new Map();
99
- depDirCache.set(fromDir, byDepName);
98
+ depDirCache.set(fromKey, byDepName);
100
99
  }
101
100
  if (!byDepName.has(depName)) byDepName.set(depName, resolveDepDir(depName, fromDir));
102
101
  return byDepName.get(depName) ?? null;
@@ -104,14 +103,15 @@ function createDependencyWalker(opts) {
104
103
  function walkDepsOf(pkgJson, fromDir, includeDevDeps = false) {
105
104
  for (const depName of getDeps(pkgJson, includeDevDeps)) {
106
105
  const depDir = resolveDepDirCached(depName, fromDir);
107
- if (!depDir || walkVisited.has(depDir)) continue;
106
+ if (!depDir) continue;
108
107
  opts.tryRegister(depDir, depName);
109
108
  walkDeps(depDir, depName);
110
109
  }
111
110
  }
112
111
  function walkDeps(pkgDir, pkgName) {
113
- if (walkVisited.has(pkgDir)) return;
114
- walkVisited.add(pkgDir);
112
+ const pkgKey = opts.getFsIdentity(pkgDir);
113
+ if (walkVisited.has(pkgKey)) return;
114
+ walkVisited.add(pkgKey);
115
115
  const pkgJson = opts.readPkgJson(pkgDir);
116
116
  if (!pkgJson) {
117
117
  opts.warnings.push(`Could not read package.json for ${pkgName} (skipping dependency walk)`);
@@ -142,7 +142,15 @@ function createDependencyWalker(opts) {
142
142
  if (wsPkg) walkDepsOf(wsPkg, wsDir);
143
143
  }
144
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
+ }
145
152
  return {
153
+ scanNestedNodeModulesDir,
146
154
  walkKnownPackages,
147
155
  walkProjectDeps,
148
156
  walkWorkspacePackages
@@ -151,21 +159,19 @@ function createDependencyWalker(opts) {
151
159
 
152
160
  //#endregion
153
161
  //#region src/fs-cache.ts
154
- function normalizeCacheKey(path) {
155
- return resolve(path);
156
- }
157
162
  function isRecord(value) {
158
163
  return typeof value === "object" && value !== null && !Array.isArray(value);
159
164
  }
160
165
  function createIntentFsCache() {
161
166
  const packageJsonCache = /* @__PURE__ */ new Map();
162
167
  const skillFilesCache = /* @__PURE__ */ new Map();
168
+ const getFsIdentity = createFsIdentityCache();
163
169
  const stats = {
164
170
  packageJsonReadCount: 0,
165
171
  packageJsonCacheHits: 0
166
172
  };
167
173
  function readPackageJsonResult(dir) {
168
- const key = normalizeCacheKey(dir);
174
+ const key = getFsIdentity(dir);
169
175
  const cached = packageJsonCache.get(key);
170
176
  if (cached) {
171
177
  stats.packageJsonCacheHits += 1;
@@ -193,7 +199,7 @@ function createIntentFsCache() {
193
199
  return readPackageJsonResult(dir).packageJson;
194
200
  }
195
201
  function findSkillFiles$1(dir) {
196
- const key = normalizeCacheKey(dir);
202
+ const key = getFsIdentity(dir);
197
203
  const cached = skillFilesCache.get(key);
198
204
  if (cached) return [...cached];
199
205
  const files = findSkillFiles(dir);
@@ -204,6 +210,7 @@ function createIntentFsCache() {
204
210
  readPackageJson,
205
211
  readPackageJsonResult,
206
212
  findSkillFiles: findSkillFiles$1,
213
+ getFsIdentity,
207
214
  getStats: () => ({ ...stats })
208
215
  };
209
216
  }
@@ -213,46 +220,33 @@ function createIntentFsCache() {
213
220
  const requireFromHere = createRequire(import.meta.url);
214
221
  function findPnpFile(start) {
215
222
  let dir = resolve(start);
216
- while (true) {
223
+ let prev;
224
+ while (dir !== prev) {
217
225
  for (const fileName of [".pnp.cjs", ".pnp.js"]) {
218
226
  const pnpPath = join(dir, fileName);
219
227
  if (existsSync(pnpPath)) return pnpPath;
220
228
  }
221
- const next = dirname(dir);
222
- if (next === dir) return null;
223
- dir = next;
229
+ prev = dir;
230
+ dir = dirname(dir);
224
231
  }
225
- }
226
- function isYarnPnpProject(root) {
227
- return findPnpFile(root) !== null;
232
+ return null;
228
233
  }
229
234
  function assertLocalNodeModulesSupported(root) {
230
235
  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.");
231
236
  }
232
- function detectPackageManager(root) {
233
- const dirsToCheck = [root];
234
- const wsRoot = findWorkspaceRoot(root);
235
- if (wsRoot && wsRoot !== root) dirsToCheck.push(wsRoot);
236
- for (const dir of dirsToCheck) {
237
- if (isYarnPnpProject(dir)) return "yarn";
238
- if (existsSync(join(dir, "pnpm-lock.yaml"))) return "pnpm";
239
- if (existsSync(join(dir, "bun.lockb")) || existsSync(join(dir, "bun.lock"))) return "bun";
240
- if (existsSync(join(dir, "yarn.lock"))) return "yarn";
241
- if (existsSync(join(dir, "package-lock.json"))) return "npm";
242
- }
243
- return "unknown";
244
- }
245
237
  function loadPnpApi(root) {
246
238
  const pnpPath = findPnpFile(root);
247
239
  if (!pnpPath) return null;
248
240
  try {
249
- const foundApi = requireFromHere("node:module").findPnpApi?.(root);
250
- if (foundApi) return foundApi;
251
241
  const pnpModule = requireFromHere(pnpPath);
252
242
  if (typeof pnpModule.setup === "function") pnpModule.setup();
253
243
  if (typeof pnpModule.getDependencyTreeRoots === "function" && typeof pnpModule.getPackageInformation === "function") return pnpModule;
254
244
  return createRequire(join(dirname(pnpPath), "package.json"))("pnpapi");
255
245
  } catch (err) {
246
+ try {
247
+ const foundApi = requireFromHere("node:module").findPnpApi?.(root);
248
+ if (foundApi) return foundApi;
249
+ } catch {}
256
250
  const msg = err instanceof Error ? err.message : String(err);
257
251
  throw new Error(`Yarn PnP project detected, but Intent could not load Yarn's PnP API from ${pnpPath}: ${msg}`);
258
252
  }
@@ -425,7 +419,8 @@ function scanForIntents(root, options = {}) {
425
419
  const projectRoot = root ?? process.cwd();
426
420
  const scanScope = getScanScope(options);
427
421
  const fsCache = options.fsCache ?? createIntentFsCache();
428
- const packageManager = detectPackageManager(projectRoot);
422
+ const workspaceRoot = findWorkspaceRoot(projectRoot);
423
+ const packageManager = detectPackageManager(projectRoot, [workspaceRoot]);
429
424
  const nodeModulesDir = join(projectRoot, "node_modules");
430
425
  const explicitGlobalNodeModules = process.env.INTENT_GLOBAL_NODE_MODULES?.trim() || null;
431
426
  const packages = [];
@@ -485,6 +480,7 @@ function scanForIntents(root, options = {}) {
485
480
  deriveIntentConfig,
486
481
  discoverSkills: (skillsDir) => discoverSkills(skillsDir, fsCache),
487
482
  getPackageDepth,
483
+ getFsIdentity: fsCache.getFsIdentity,
488
484
  packageIndexes,
489
485
  packages,
490
486
  projectRoot,
@@ -493,8 +489,9 @@ function scanForIntents(root, options = {}) {
493
489
  validateIntentField,
494
490
  warnings
495
491
  });
496
- const { walkKnownPackages, walkProjectDeps, walkWorkspacePackages } = createDependencyWalker({
492
+ const { scanNestedNodeModulesDir, walkKnownPackages, walkProjectDeps, walkWorkspacePackages } = createDependencyWalker({
497
493
  fsCache,
494
+ getFsIdentity: fsCache.getFsIdentity,
498
495
  packages,
499
496
  projectRoot,
500
497
  readPkgJson,
@@ -504,7 +501,6 @@ function scanForIntents(root, options = {}) {
504
501
  });
505
502
  function scanPnpPackages(api) {
506
503
  const visited = /* @__PURE__ */ new Set();
507
- const workspaceRoot = findWorkspaceRoot(projectRoot);
508
504
  const projectLocator = api.findPackageLocator?.(projectRoot.endsWith(sep) ? projectRoot : `${projectRoot}${sep}`);
509
505
  const roots = workspaceRoot && workspaceRoot !== projectRoot && projectLocator ? [projectLocator] : api.getDependencyTreeRoots?.() ?? (api.topLevel ? [api.topLevel] : []);
510
506
  function visit(locator) {
@@ -530,12 +526,15 @@ function scanForIntents(root, options = {}) {
530
526
  }
531
527
  }
532
528
  assertLocalNodeModulesSupported(projectRoot);
529
+ const packageCountBeforeLocalDiscovery = packages.length;
533
530
  walkWorkspacePackages();
534
531
  const packageCountBeforeDependencyDiscovery = packages.length;
535
532
  scanTarget(nodeModules.local);
536
533
  walkKnownPackages();
537
534
  walkProjectDeps();
538
- if (packages.length === packageCountBeforeDependencyDiscovery) {
535
+ const shouldTryPnpFallback = packages.length === packageCountBeforeDependencyDiscovery;
536
+ if (nodeModules.local.path && nodeModules.local.exists && packages.length === packageCountBeforeLocalDiscovery) scanNestedNodeModulesDir(nodeModules.local.path);
537
+ if (shouldTryPnpFallback) {
539
538
  const api = getPnpApi();
540
539
  if (api) scanPnpPackages(api);
541
540
  }
@@ -597,6 +596,7 @@ function scanIntentPackageAtRoot(packageRoot, options = {}) {
597
596
  deriveIntentConfig,
598
597
  discoverSkills: options.skillNameHint ? (skillsDir, packageName) => discoverSkillByNameHint(skillsDir, packageName, options.skillNameHint) : (skillsDir) => discoverSkills(skillsDir, fsCache),
599
598
  getPackageDepth,
599
+ getFsIdentity: fsCache.getFsIdentity,
600
600
  packageIndexes,
601
601
  packages,
602
602
  projectRoot,
@@ -1,5 +1,5 @@
1
- import { a as readWorkspacePatterns, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-CIJQCwbJ.mjs";
2
- import { t as resolveProjectContext } from "./project-context-Bv9BDh8B.mjs";
1
+ import { a as readWorkspacePatterns, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-FljtM2Xb.mjs";
2
+ import { t as resolveProjectContext } from "./project-context-4wzbLY9c.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-DhMqESd3.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-BPDvfmcd.mjs";
2
- import { a as readWorkspacePatterns, o as resolveWorkspacePackages, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-CIJQCwbJ.mjs";
3
- import "./project-context-Bv9BDh8B.mjs";
4
- import { n as runEditPackageJsonAll, r as runSetupGithubActions, t as runEditPackageJson } from "./setup-DQMKxEoA.mjs";
1
+ import "./utils-CF7OL__5.mjs";
2
+ import { a as readWorkspacePatterns, o as resolveWorkspacePackages, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-FljtM2Xb.mjs";
3
+ import "./project-context-4wzbLY9c.mjs";
4
+ import { n as runEditPackageJsonAll, r as runSetupGithubActions, t as runEditPackageJson } from "./setup-BElEzHxS.mjs";
5
5
 
6
6
  export { findPackagesWithSkills, findWorkspaceRoot, readWorkspacePatterns, resolveWorkspacePackages, runEditPackageJson, runEditPackageJsonAll, runSetupGithubActions };
@@ -1,4 +1,4 @@
1
- import { s as toPosixPath } from "./utils-BPDvfmcd.mjs";
1
+ import { l as toPosixPath } from "./utils-CF7OL__5.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-CrWkP7Hc.mjs");
37
37
  const packageLabel = options.packageLabel ?? "workspace";
38
38
  try {
39
39
  const { reports, workflowAdvisories = [] } = await resolveStaleTargets(targetDir);
@@ -1,4 +1,4 @@
1
- import { a as parseFrontmatter, n as findSkillFiles, s as toPosixPath } from "./utils-BPDvfmcd.mjs";
1
+ import { l as toPosixPath, r as findSkillFiles, s as parseFrontmatter } from "./utils-CF7OL__5.mjs";
2
2
  import { t as readIntentArtifacts } from "./artifact-coverage-DgWuVqUp.mjs";
3
3
  import { existsSync, readFileSync } from "node:fs";
4
4
  import { isAbsolute, join, relative, resolve } from "node:path";
@@ -1,5 +1,5 @@
1
- import "./utils-BPDvfmcd.mjs";
1
+ import "./utils-CF7OL__5.mjs";
2
2
  import "./artifact-coverage-DgWuVqUp.mjs";
3
- import { n as checkStaleness, r as readPackageName, t as buildWorkspaceCoverageSignals } from "./staleness-CGLs-swr.mjs";
3
+ import { n as checkStaleness, r as readPackageName, t as buildWorkspaceCoverageSignals } from "./staleness-BwcLygsY.mjs";
4
4
 
5
5
  export { buildWorkspaceCoverageSignals, checkStaleness, readPackageName };
@@ -6,7 +6,7 @@ interface IntentConfig {
6
6
  requires?: Array<string>;
7
7
  }
8
8
  interface ScanResult {
9
- packageManager: 'npm' | 'pnpm' | 'yarn' | 'bun' | 'unknown';
9
+ packageManager: PackageManager;
10
10
  packages: Array<IntentPackage>;
11
11
  warnings: Array<string>;
12
12
  conflicts: Array<VersionConflict>;
@@ -16,6 +16,7 @@ interface ScanResult {
16
16
  };
17
17
  stats?: ScanStats;
18
18
  }
19
+ type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun' | 'unknown';
19
20
  type ScanScope = 'local' | 'local-and-global' | 'global';
20
21
  interface ScanOptions {
21
22
  includeGlobal?: boolean;
@@ -148,4 +149,4 @@ interface IntentProjectConfig {
148
149
  };
149
150
  }
150
151
  //#endregion
151
- export { SkillEntry as _, IntentArtifactSet as a, StalenessSignal as b, IntentConfig as c, MetaFeedbackPayload as d, MetaSkillName as f, ScanStats as g, ScanScope as h, IntentArtifactFile as i, IntentPackage as l, ScanResult as m, FeedbackPayload as n, IntentArtifactSkill as o, ScanOptions as p, IntentArtifactCoverageIgnore as r, IntentArtifactWarning as s, AgentName as t, IntentProjectConfig as u, SkillStaleness as v, VersionConflict as x, StalenessReport as y };
152
+ export { VersionConflict as S, ScanStats as _, IntentArtifactSet as a, StalenessReport as b, IntentConfig as c, MetaFeedbackPayload as d, MetaSkillName as f, ScanScope as g, ScanResult as h, IntentArtifactFile as i, IntentPackage as l, ScanOptions as m, FeedbackPayload as n, IntentArtifactSkill as o, PackageManager as p, IntentArtifactCoverageIgnore as r, IntentArtifactWarning as s, AgentName as t, IntentProjectConfig as u, SkillEntry as v, StalenessSignal as x, SkillStaleness as y };
@@ -1,6 +1,6 @@
1
1
  import { createRequire } from "node:module";
2
- import { existsSync, readFileSync, readdirSync } from "node:fs";
3
- import { dirname, join, sep } from "node:path";
2
+ import { existsSync, lstatSync, readFileSync, readdirSync, realpathSync } from "node:fs";
3
+ import { dirname, join, resolve, sep } from "node:path";
4
4
  import { execFileSync } from "node:child_process";
5
5
  import { parse } from "yaml";
6
6
 
@@ -11,6 +11,22 @@ import { parse } from "yaml";
11
11
  function toPosixPath(p) {
12
12
  return p.split(sep).join("/");
13
13
  }
14
+ function createFsIdentityCache() {
15
+ const cache = /* @__PURE__ */ new Map();
16
+ return (path) => {
17
+ const resolved = resolve(path);
18
+ const cached = cache.get(resolved);
19
+ if (cached) return cached;
20
+ let identity;
21
+ try {
22
+ identity = lstatSync(resolved).isSymbolicLink() ? realpathSync(resolved) : resolved;
23
+ } catch {
24
+ identity = resolved;
25
+ }
26
+ cache.set(resolved, identity);
27
+ return identity;
28
+ };
29
+ }
14
30
  /**
15
31
  * Recursively find all SKILL.md files under a directory.
16
32
  */
@@ -83,6 +99,47 @@ function listNodeModulesPackageDirs(nodeModulesDir) {
83
99
  }
84
100
  return packageDirs;
85
101
  }
102
+ function listNestedNodeModulesPackageDirs(nodeModulesDir, getFsIdentity = createFsIdentityCache()) {
103
+ const packageDirs = [];
104
+ const visitedNodeModulesDirs = /* @__PURE__ */ new Set();
105
+ const visitedPackageDirs = /* @__PURE__ */ new Set();
106
+ function readDir(dir) {
107
+ try {
108
+ return readdirSync(dir, {
109
+ withFileTypes: true,
110
+ encoding: "utf8"
111
+ });
112
+ } catch {
113
+ return [];
114
+ }
115
+ }
116
+ function addPackageDir(packageDir) {
117
+ const key = getFsIdentity(packageDir);
118
+ if (visitedPackageDirs.has(key)) return;
119
+ visitedPackageDirs.add(key);
120
+ if (existsSync(join(packageDir, "package.json"))) packageDirs.push(packageDir);
121
+ scanNodeModulesDir(join(packageDir, "node_modules"));
122
+ }
123
+ function scanNodeModulesDir(dir) {
124
+ const key = getFsIdentity(dir);
125
+ if (visitedNodeModulesDirs.has(key)) return;
126
+ visitedNodeModulesDirs.add(key);
127
+ for (const entry of readDir(dir)) {
128
+ if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
129
+ const dirPath = join(dir, entry.name);
130
+ if (entry.name.startsWith("@")) {
131
+ for (const scoped of readDir(dirPath)) {
132
+ if (!scoped.isDirectory() && !scoped.isSymbolicLink()) continue;
133
+ addPackageDir(join(dirPath, scoped.name));
134
+ }
135
+ continue;
136
+ }
137
+ if (!entry.name.startsWith(".")) addPackageDir(dirPath);
138
+ }
139
+ }
140
+ scanNodeModulesDir(nodeModulesDir);
141
+ return packageDirs;
142
+ }
86
143
  function detectGlobalNodeModules(packageManager) {
87
144
  const envPath = process.env.INTENT_GLOBAL_NODE_MODULES?.trim();
88
145
  if (envPath) return {
@@ -135,12 +192,12 @@ function resolveDepDir(depName, parentDir) {
135
192
  if (code && code !== "MODULE_NOT_FOUND" && code !== "ERR_PACKAGE_PATH_NOT_EXPORTED") console.warn(`Warning: could not resolve ${depName} from ${parentDir}: ${err instanceof Error ? err.message : String(err)}`);
136
193
  }
137
194
  let dir = parentDir;
138
- while (true) {
195
+ let prev;
196
+ while (dir !== prev) {
139
197
  const candidate = join(dir, "node_modules", depName);
140
198
  if (existsSync(join(candidate, "package.json"))) return candidate;
141
- const parent = dirname(dir);
142
- if (parent === dir) break;
143
- dir = parent;
199
+ prev = dir;
200
+ dir = dirname(dir);
144
201
  }
145
202
  return null;
146
203
  }
@@ -164,4 +221,4 @@ function parseFrontmatter(filePath) {
164
221
  }
165
222
 
166
223
  //#endregion
167
- export { parseFrontmatter as a, listNodeModulesPackageDirs as i, findSkillFiles as n, resolveDepDir as o, getDeps as r, toPosixPath as s, detectGlobalNodeModules as t };
224
+ export { listNestedNodeModulesPackageDirs as a, resolveDepDir as c, getDeps as i, toPosixPath as l, detectGlobalNodeModules as n, listNodeModulesPackageDirs as o, findSkillFiles as r, parseFrontmatter as s, createFsIdentityCache as t };
@@ -0,0 +1,3 @@
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-CF7OL__5.mjs";
2
+
3
+ export { createFsIdentityCache, detectGlobalNodeModules, findSkillFiles, getDeps, listNestedNodeModulesPackageDirs, listNodeModulesPackageDirs, parseFrontmatter, resolveDepDir, toPosixPath };
@@ -1,8 +1,8 @@
1
- import "./utils-BPDvfmcd.mjs";
2
- import { n as findWorkspacePackages } from "./workspace-patterns-CIJQCwbJ.mjs";
3
- import { t as resolveProjectContext } from "./project-context-Bv9BDh8B.mjs";
1
+ import "./utils-CF7OL__5.mjs";
2
+ import { n as findWorkspacePackages } from "./workspace-patterns-FljtM2Xb.mjs";
3
+ import { t as resolveProjectContext } from "./project-context-4wzbLY9c.mjs";
4
4
  import { n as isCliFailure, t as fail } from "./cli-error-BrMXlbtx.mjs";
5
- import { l as printWarnings } from "./cli-support-DtqVDiJv.mjs";
5
+ import { l as printWarnings } from "./cli-support-C-t4xQw0.mjs";
6
6
  import { appendFileSync, existsSync, readFileSync } from "node:fs";
7
7
  import { basename, dirname, join, relative, resolve, sep } from "node:path";
8
8
 
@@ -115,7 +115,7 @@ async function runValidateCommand(dir, options = {}) {
115
115
  }
116
116
  }
117
117
  async function runValidateCommandInternal(dir) {
118
- const [{ parse: parseYaml }, { findSkillFiles }] = await Promise.all([import("yaml"), import("./utils-DqdIC3RY.mjs")]);
118
+ const [{ parse: parseYaml }, { findSkillFiles }] = await Promise.all([import("yaml"), import("./utils-DTvYXAsM.mjs")]);
119
119
  const context = resolveProjectContext({
120
120
  cwd: process.cwd(),
121
121
  targetPath: dir
@@ -1,3 +1,3 @@
1
- import { a as writeStaleReviewWorkflowFiles, i as createWorkflowAdvisoryReviewItems, n as collectStaleReviewItems, r as createFailedStaleReviewItem, t as buildStaleReviewBody } from "./workflow-review-CwcR2ge4.mjs";
1
+ import { a as writeStaleReviewWorkflowFiles, i as createWorkflowAdvisoryReviewItems, n as collectStaleReviewItems, r as createFailedStaleReviewItem, t as buildStaleReviewBody } from "./workflow-review-D9Fg1G0P.mjs";
2
2
 
3
3
  export { collectStaleReviewItems, createFailedStaleReviewItem, createWorkflowAdvisoryReviewItems, writeStaleReviewWorkflowFiles };
@@ -4,26 +4,26 @@ import { appendFileSync, writeFileSync } from "node:fs";
4
4
  function collectStaleReviewItems(reports) {
5
5
  const items = [];
6
6
  for (const report of reports) {
7
- for (const skill of report.skills ?? []) {
8
- if (!skill?.needsReview) continue;
7
+ for (const skill of report.skills) {
8
+ if (!skill.needsReview) continue;
9
9
  items.push({
10
10
  type: "stale-skill",
11
11
  library: report.library,
12
12
  subject: skill.name,
13
- reasons: skill.reasons ?? []
13
+ reasons: skill.reasons
14
14
  });
15
15
  }
16
- for (const signal of report.signals ?? []) {
17
- if (signal?.needsReview === false) continue;
16
+ for (const signal of report.signals) {
17
+ if (signal.needsReview === false) continue;
18
18
  items.push({
19
- type: signal?.type ?? "review-signal",
20
- library: signal?.library ?? report.library,
21
- subject: signal?.packageName ?? signal?.packageRoot ?? signal?.skill ?? signal?.artifactPath ?? signal?.subject ?? report.library,
22
- reasons: signal?.reasons ?? [],
23
- artifactPath: signal?.artifactPath,
24
- packageName: signal?.packageName,
25
- packageRoot: signal?.packageRoot,
26
- skill: signal?.skill
19
+ type: signal.type,
20
+ library: signal.library ?? report.library,
21
+ subject: signal.packageName ?? signal.packageRoot ?? signal.skill ?? signal.artifactPath ?? signal.subject ?? report.library,
22
+ reasons: signal.reasons,
23
+ artifactPath: signal.artifactPath,
24
+ packageName: signal.packageName,
25
+ packageRoot: signal.packageRoot,
26
+ skill: signal.skill
27
27
  });
28
28
  }
29
29
  }
@@ -51,12 +51,12 @@ function buildStaleReviewBody(items) {
51
51
  const signalRows = [...grouped.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([type, count]) => `| \`${type}\` | ${count} |`);
52
52
  const itemRows = items.map((item) => {
53
53
  const subject = item.subject ? `\`${item.subject}\`` : "-";
54
- const reasons = item.reasons?.length ? item.reasons.join("; ") : "-";
54
+ const reasons = item.reasons.length ? item.reasons.join("; ") : "-";
55
55
  return `| \`${item.type}\` | ${subject} | \`${item.library}\` | ${reasons} |`;
56
56
  });
57
57
  const reasonBullets = items.map((item) => {
58
58
  const subject = item.subject ? `\`${item.subject}\`` : "`unknown`";
59
- const reasons = item.reasons?.length ? item.reasons.join("; ") : "Intent did not emit a detailed reason for this signal.";
59
+ const reasons = item.reasons.length ? item.reasons.join("; ") : "Intent did not emit a detailed reason for this signal.";
60
60
  return `- \`${item.type}\` for ${subject}: ${reasons}`;
61
61
  });
62
62
  const prompt = [
@@ -1,4 +1,4 @@
1
- import "./utils-BPDvfmcd.mjs";
2
- import { a as readWorkspacePatterns, i as getWorkspaceInfo, n as findWorkspacePackages, o as resolveWorkspacePackages, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-CIJQCwbJ.mjs";
1
+ import "./utils-CF7OL__5.mjs";
2
+ import { a as readWorkspacePatterns, i as getWorkspaceInfo, n as findWorkspacePackages, o as resolveWorkspacePackages, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-FljtM2Xb.mjs";
3
3
 
4
4
  export { findWorkspaceRoot, getWorkspaceInfo };
@@ -1,4 +1,4 @@
1
- import { n as findSkillFiles } from "./utils-BPDvfmcd.mjs";
1
+ import { r as findSkillFiles } from "./utils-CF7OL__5.mjs";
2
2
  import { existsSync, readFileSync, readdirSync } from "node:fs";
3
3
  import { dirname, join } from "node:path";
4
4
  import { parse } from "yaml";
@@ -164,8 +164,9 @@ function readChildDirectories(dir) {
164
164
  }
165
165
  function findWorkspaceRoot(start) {
166
166
  let dir = start;
167
+ let prev;
167
168
  const visited = [];
168
- while (true) {
169
+ while (dir !== prev) {
169
170
  const cached = workspaceRootCache.get(dir);
170
171
  if (cached !== void 0) {
171
172
  for (const visitedDir of visited) workspaceRootCache.set(visitedDir, cached);
@@ -176,13 +177,11 @@ function findWorkspaceRoot(start) {
176
177
  for (const visitedDir of visited) workspaceRootCache.set(visitedDir, dir);
177
178
  return dir;
178
179
  }
179
- const next = dirname(dir);
180
- if (next === dir) {
181
- for (const visitedDir of visited) workspaceRootCache.set(visitedDir, null);
182
- return null;
183
- }
184
- dir = next;
180
+ prev = dir;
181
+ dir = dirname(dir);
185
182
  }
183
+ for (const visitedDir of visited) workspaceRootCache.set(visitedDir, null);
184
+ return null;
186
185
  }
187
186
  function findPackagesWithSkills(root) {
188
187
  return getWorkspaceInfo(root)?.packageDirsWithSkills ?? [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/intent",
3
- "version": "0.0.40",
3
+ "version": "0.0.42",
4
4
  "description": "Ship compositional knowledge for AI coding agents alongside your npm packages",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -13,18 +13,13 @@
13
13
  "import": "./dist/index.mjs",
14
14
  "types": "./dist/index.d.mts"
15
15
  },
16
- "./intent-library": {
17
- "import": "./dist/intent-library.mjs",
18
- "types": "./dist/intent-library.d.mts"
19
- },
20
16
  "./core": {
21
17
  "import": "./dist/core.mjs",
22
18
  "types": "./dist/core.d.mts"
23
19
  }
24
20
  },
25
21
  "bin": {
26
- "intent": "dist/cli.mjs",
27
- "intent-library": "dist/intent-library.mjs"
22
+ "intent": "dist/cli.mjs"
28
23
  },
29
24
  "files": [
30
25
  "dist",
@@ -43,7 +38,7 @@
43
38
  "verdaccio": "^6.3.2"
44
39
  },
45
40
  "scripts": {
46
- "build": "tsdown src/index.ts src/cli.ts src/setup.ts src/intent-library.ts src/library-scanner.ts src/core.ts --format esm --dts",
41
+ "build": "tsdown src/index.ts src/cli.ts src/setup.ts src/core.ts --format esm --dts",
47
42
  "test:smoke": "pnpm run build && node dist/cli.mjs --help > /dev/null && node dist/cli.mjs load --help > /dev/null",
48
43
  "test:lib": "vitest run --exclude 'tests/integration/**'",
49
44
  "test:integration": "vitest run tests/integration/",
@@ -1,5 +0,0 @@
1
- import "./utils-BPDvfmcd.mjs";
2
- import "./skill-paths-BHbdWniB.mjs";
3
- import { n as printSkillTree, r as printTable, t as computeSkillNameWidth } from "./display-DHNuzSqR.mjs";
4
-
5
- export { computeSkillNameWidth, printSkillTree, printTable };
@@ -1,7 +0,0 @@
1
- import "./utils-BPDvfmcd.mjs";
2
- import "./workspace-patterns-CIJQCwbJ.mjs";
3
- import "./project-context-Bv9BDh8B.mjs";
4
- import "./cli-support-DtqVDiJv.mjs";
5
- import { n as runInstallCommand, t as INSTALL_PROMPT } from "./install-CLkmoPOY.mjs";
6
-
7
- export { INSTALL_PROMPT, runInstallCommand };
@@ -1 +0,0 @@
1
- export { };