@tanstack/intent 0.0.39 → 0.0.40

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 (38) hide show
  1. package/dist/{cli-support-OrWuIzI3.mjs → cli-support-Cb9lNXhL.mjs} +4 -4
  2. package/dist/{cli-support-Dmpj1iyQ.mjs → cli-support-DtqVDiJv.mjs} +4 -4
  3. package/dist/cli.mjs +9 -9
  4. package/dist/{core-0H8zUKIh.mjs → core-BOSjgetf.mjs} +34 -20
  5. package/dist/core.d.mts +4 -1
  6. package/dist/core.mjs +7 -7
  7. package/dist/display-CmLzVAae.mjs +5 -0
  8. package/dist/{display-CVeoAwBd.mjs → display-DHNuzSqR.mjs} +1 -1
  9. package/dist/index.d.mts +1 -1
  10. package/dist/index.mjs +8 -8
  11. package/dist/{install-7BAmUZFB.mjs → install-CLkmoPOY.mjs} +1 -1
  12. package/dist/install-ChddjnhO.mjs +7 -0
  13. package/dist/intent-library.mjs +8 -8
  14. package/dist/{library-scanner-CHepLJQJ.mjs → library-scanner-BAJ7bXtW.mjs} +2 -2
  15. package/dist/library-scanner.d.mts +1 -1
  16. package/dist/library-scanner.mjs +3 -3
  17. package/dist/{list-DNPHxYpR.mjs → list-CxSm8YYl.mjs} +12 -10
  18. package/dist/{load-CK7vr50h.mjs → load-DF-zIT3-.mjs} +11 -9
  19. package/dist/{meta-CYV9EzM8.mjs → meta-BNSVXFQu.mjs} +1 -1
  20. package/dist/{project-context-Dx6XIJJo.mjs → project-context-Bv9BDh8B.mjs} +1 -1
  21. package/dist/{resolver-CP0S8UjZ.mjs → resolver-BDsZ3kWg.mjs} +2 -2
  22. package/dist/{scanner-BaOA18pn.mjs → scanner-BGyQTQ3U.mjs} +113 -62
  23. package/dist/scanner-Ix6MmxfB.mjs +6 -0
  24. package/dist/{setup-kvWN4xCr.mjs → setup-DQMKxEoA.mjs} +2 -2
  25. package/dist/setup.mjs +4 -4
  26. package/dist/{skill-paths-DNOHrvL5.mjs → skill-paths-BHbdWniB.mjs} +1 -1
  27. package/dist/{staleness-V-nwqFUh.mjs → staleness-CGLs-swr.mjs} +1 -1
  28. package/dist/{staleness-IIyVmUxU.mjs → staleness-Dl-m8JWM.mjs} +2 -2
  29. package/dist/{types-S2zpibHp.d.mts → types-Cq5cY9h9.d.mts} +6 -1
  30. package/dist/{utils-mdb4i6VA.mjs → utils-BPDvfmcd.mjs} +10 -1
  31. package/dist/{utils-BHzSyNeJ.mjs → utils-DqdIC3RY.mjs} +1 -1
  32. package/dist/{validate-BYUd0qb8.mjs → validate-Divq4AiV.mjs} +5 -5
  33. package/dist/{workspace-patterns-BZLEaMcS.mjs → workspace-patterns-CIJQCwbJ.mjs} +1 -1
  34. package/dist/{workspace-patterns-BWMz7TsI.mjs → workspace-patterns-Diy5gtz_.mjs} +2 -2
  35. package/package.json +1 -1
  36. package/dist/display-COlw5FaB.mjs +0 -5
  37. package/dist/install-Brf5PORN.mjs +0 -7
  38. package/dist/scanner-BoB20xOF.mjs +0 -6
@@ -1,6 +1,6 @@
1
- import "./utils-mdb4i6VA.mjs";
2
- import "./workspace-patterns-BZLEaMcS.mjs";
3
- import "./project-context-Dx6XIJJo.mjs";
4
- import { a as printDebugInfo, c as scanOptionsFromGlobalFlags, i as getMetaDir, l as printWarnings, n as coreOptionsFromGlobalFlags, o as resolveStaleTargets, r as getCheckSkillsWorkflowAdvisories, s as scanIntentsOrFail, t as INTENT_CHECK_SKILLS_WORKFLOW_VERSION } from "./cli-support-Dmpj1iyQ.mjs";
1
+ import "./utils-BPDvfmcd.mjs";
2
+ import "./workspace-patterns-CIJQCwbJ.mjs";
3
+ import "./project-context-Bv9BDh8B.mjs";
4
+ import { a as printDebugInfo, c as scanOptionsFromGlobalFlags, i as getMetaDir, l as printWarnings, n as coreOptionsFromGlobalFlags, o as resolveStaleTargets, r as getCheckSkillsWorkflowAdvisories, s as scanIntentsOrFail, t as INTENT_CHECK_SKILLS_WORKFLOW_VERSION } from "./cli-support-DtqVDiJv.mjs";
5
5
 
6
6
  export { INTENT_CHECK_SKILLS_WORKFLOW_VERSION, coreOptionsFromGlobalFlags, getCheckSkillsWorkflowAdvisories, getMetaDir, printDebugInfo, printWarnings, resolveStaleTargets, scanIntentsOrFail, scanOptionsFromGlobalFlags };
@@ -1,4 +1,4 @@
1
- import { t as resolveProjectContext } from "./project-context-Dx6XIJJo.mjs";
1
+ import { t as resolveProjectContext } from "./project-context-Bv9BDh8B.mjs";
2
2
  import { t as fail } from "./cli-error-BrMXlbtx.mjs";
3
3
  import { existsSync, readFileSync } from "node:fs";
4
4
  import { dirname, join, relative, resolve } from "node:path";
@@ -31,7 +31,7 @@ function getCheckSkillsWorkflowAdvisories(root) {
31
31
  return [`Intent workflow update available: run \`npx @tanstack/intent@latest setup\` to refresh ${relative(process.cwd(), workflowPath) || workflowPath}.`];
32
32
  }
33
33
  async function scanIntentsOrFail(options) {
34
- const { scanForIntents } = await import("./scanner-BoB20xOF.mjs");
34
+ const { scanForIntents } = await import("./scanner-Ix6MmxfB.mjs");
35
35
  try {
36
36
  return scanForIntents(void 0, options);
37
37
  } catch (err) {
@@ -68,13 +68,13 @@ async function resolveStaleTargets(targetDir) {
68
68
  targetPath: targetDir
69
69
  });
70
70
  const workflowAdvisories = getCheckSkillsWorkflowAdvisories(context.workspaceRoot ?? context.packageRoot ?? resolvedRoot);
71
- const { buildWorkspaceCoverageSignals, checkStaleness, readPackageName } = await import("./staleness-IIyVmUxU.mjs");
71
+ const { buildWorkspaceCoverageSignals, checkStaleness, readPackageName } = await import("./staleness-Dl-m8JWM.mjs");
72
72
  const isWorkspaceRootTarget = context.workspaceRoot !== null && resolvedRoot === context.workspaceRoot;
73
73
  if (context.packageRoot && !isWorkspaceRootTarget && (context.targetSkillsDir !== null || context.workspaceRoot === null)) return {
74
74
  reports: [await checkStaleness(context.packageRoot, readPackageName(context.packageRoot), context.workspaceRoot ?? context.packageRoot)],
75
75
  workflowAdvisories
76
76
  };
77
- const { findWorkspaceRoot, getWorkspaceInfo } = await import("./workspace-patterns-BWMz7TsI.mjs");
77
+ const { findWorkspaceRoot, getWorkspaceInfo } = await import("./workspace-patterns-Diy5gtz_.mjs");
78
78
  const workspaceRoot = findWorkspaceRoot(resolvedRoot);
79
79
  const workspaceInfo = workspaceRoot ? getWorkspaceInfo(workspaceRoot) : null;
80
80
  if (workspaceInfo) {
package/dist/cli.mjs CHANGED
@@ -9,31 +9,31 @@ function createCli() {
9
9
  const cli = cac("intent");
10
10
  cli.usage("<command> [options]");
11
11
  cli.command("list", "Discover intent-enabled packages from the project or workspace").usage("list [--json] [--debug] [--exclude <pattern>] [--global] [--global-only]").option("--json", "Output JSON").option("--debug", "Print discovery debug details to stderr").option("--exclude <pattern>", "Exclude package name glob").option("--global", "Include global packages after project packages").option("--global-only", "List global packages only").example("list").example("list --json").example("list --global").action(async (options) => {
12
- const { runListCommand } = await import("./list-DNPHxYpR.mjs");
12
+ const { runListCommand } = await import("./list-CxSm8YYl.mjs");
13
13
  await runListCommand(options);
14
14
  });
15
15
  cli.command("load [use]", "Load a compact skill use and print its SKILL.md").usage("load <use> [--path] [--json] [--debug] [--exclude <pattern>] [--global] [--global-only]").option("--path", "Print the resolved skill path instead of file content").option("--json", "Output JSON").option("--debug", "Print resolution debug details to stderr").option("--exclude <pattern>", "Exclude package name glob").option("--global", "Load from project packages, then global packages").option("--global-only", "Load from global packages only").example("load @tanstack/query#core").example("load @tanstack/query#core --path").action(async (use, options) => {
16
- const { runLoadCommand } = await import("./load-CK7vr50h.mjs");
16
+ const { runLoadCommand } = await import("./load-DF-zIT3-.mjs");
17
17
  await runLoadCommand(use, options);
18
18
  });
19
19
  cli.command("meta [name]", "List meta-skills, or print one by name").usage("meta [name]").example("meta").example("meta domain-discovery").action(async (name) => {
20
- const [{ getMetaDir }, { runMetaCommand }] = await Promise.all([import("./cli-support-OrWuIzI3.mjs"), import("./meta-CYV9EzM8.mjs")]);
20
+ const [{ getMetaDir }, { runMetaCommand }] = await Promise.all([import("./cli-support-Cb9lNXhL.mjs"), import("./meta-BNSVXFQu.mjs")]);
21
21
  await runMetaCommand(name, getMetaDir());
22
22
  });
23
23
  cli.command("validate [dir]", "Validate skill files").usage("validate [dir] [--github-summary]").option("--github-summary", "Write a GitHub Actions step summary").example("validate").example("validate packages/query/skills").action(async (dir, options) => {
24
- const { runValidateCommand } = await import("./validate-BYUd0qb8.mjs");
24
+ const { runValidateCommand } = await import("./validate-Divq4AiV.mjs");
25
25
  await runValidateCommand(dir, options);
26
26
  });
27
27
  cli.command("install", "Create or update skill loading guidance in an agent config file").usage("install [--map] [--dry-run] [--print-prompt] [--global] [--global-only]").option("--map", "Write explicit skill-to-task mappings").option("--dry-run", "Print the generated block without writing").option("--print-prompt", "Print the legacy agent setup prompt instead of writing").option("--global", "Include global packages after project packages").option("--global-only", "Install mappings from global packages only").example("install").example("install --map").example("install --dry-run").example("install --print-prompt").example("install --global").action(async (options) => {
28
- const [{ scanIntentsOrFail }, { runInstallCommand }] = await Promise.all([import("./cli-support-OrWuIzI3.mjs"), import("./install-Brf5PORN.mjs")]);
28
+ const [{ scanIntentsOrFail }, { runInstallCommand }] = await Promise.all([import("./cli-support-Cb9lNXhL.mjs"), import("./install-ChddjnhO.mjs")]);
29
29
  await runInstallCommand(options, scanIntentsOrFail);
30
30
  });
31
31
  cli.command("scaffold", "Print maintainer scaffold prompt").usage("scaffold").action(async () => {
32
- const [{ getMetaDir }, { runScaffoldCommand }] = await Promise.all([import("./cli-support-OrWuIzI3.mjs"), import("./scaffold-D2vwv9ls.mjs")]);
32
+ const [{ getMetaDir }, { runScaffoldCommand }] = await Promise.all([import("./cli-support-Cb9lNXhL.mjs"), import("./scaffold-D2vwv9ls.mjs")]);
33
33
  runScaffoldCommand(getMetaDir());
34
34
  });
35
35
  cli.command("stale [dir]", "Check skills for staleness in the current package or workspace").usage("stale [dir] [--json] [--github-review]").option("--json", "Output JSON").option("--github-review", "Write GitHub Actions review PR files").option("--package-label <label>", "Fallback package label for review PRs").example("stale").example("stale packages/query").example("stale --json").action(async (targetDir, options) => {
36
- const [{ resolveStaleTargets }, { runStaleCommand }] = await Promise.all([import("./cli-support-OrWuIzI3.mjs"), import("./stale-flPZnWfI.mjs")]);
36
+ const [{ resolveStaleTargets }, { runStaleCommand }] = await Promise.all([import("./cli-support-Cb9lNXhL.mjs"), import("./stale-flPZnWfI.mjs")]);
37
37
  await runStaleCommand(targetDir, options, resolveStaleTargets);
38
38
  });
39
39
  cli.command("edit-package-json", "Update package.json files so skills are published").usage("edit-package-json").action(async () => {
@@ -41,11 +41,11 @@ function createCli() {
41
41
  await runEditPackageJsonCommand(process.cwd());
42
42
  });
43
43
  cli.command("setup", "Copy Intent CI workflow templates into .github/workflows/").usage("setup").action(async () => {
44
- const [{ getMetaDir }, { runSetupGithubActionsCommand }] = await Promise.all([import("./cli-support-OrWuIzI3.mjs"), import("./setup-github-actions-emXSyGy3.mjs")]);
44
+ const [{ getMetaDir }, { runSetupGithubActionsCommand }] = await Promise.all([import("./cli-support-Cb9lNXhL.mjs"), import("./setup-github-actions-emXSyGy3.mjs")]);
45
45
  await runSetupGithubActionsCommand(process.cwd(), getMetaDir());
46
46
  });
47
47
  cli.command("setup-github-actions", "Copy Intent CI workflow templates into .github/workflows/").usage("setup-github-actions").action(async () => {
48
- const [{ getMetaDir }, { runSetupGithubActionsCommand }] = await Promise.all([import("./cli-support-OrWuIzI3.mjs"), import("./setup-github-actions-emXSyGy3.mjs")]);
48
+ const [{ getMetaDir }, { runSetupGithubActionsCommand }] = await Promise.all([import("./cli-support-Cb9lNXhL.mjs"), import("./setup-github-actions-emXSyGy3.mjs")]);
49
49
  await runSetupGithubActionsCommand(process.cwd(), getMetaDir());
50
50
  });
51
51
  cli.command("help [command]", "Display help for a command").action((commandName) => {
@@ -1,9 +1,9 @@
1
- import { o as resolveDepDir, r as getDeps, s as toPosixPath } from "./utils-mdb4i6VA.mjs";
2
- import { n as scanIntentPackageAtRoot, t as scanForIntents } from "./scanner-BaOA18pn.mjs";
3
- import { o as resolveWorkspacePackages } from "./workspace-patterns-BZLEaMcS.mjs";
1
+ import { o as resolveDepDir, r as getDeps, s as toPosixPath } from "./utils-BPDvfmcd.mjs";
2
+ import { n as scanIntentPackageAtRoot, r as createIntentFsCache, t as scanForIntents } from "./scanner-BGyQTQ3U.mjs";
3
+ import { n as findWorkspacePackages } from "./workspace-patterns-CIJQCwbJ.mjs";
4
4
  import { i as parseSkillUse, n as formatSkillUse } from "./skill-use-umYvZl94.mjs";
5
- import { t as resolveProjectContext } from "./project-context-Dx6XIJJo.mjs";
6
- import { a as compileExcludePatterns, c as warningMentionsPackage, i as resolveSkillUse, l as readPackageJson, o as getEffectiveExcludePatterns, r as resolveSkillEntry, s as isPackageExcluded, t as ResolveSkillUseError } from "./resolver-CP0S8UjZ.mjs";
5
+ import { t as resolveProjectContext } from "./project-context-Bv9BDh8B.mjs";
6
+ import { a as compileExcludePatterns, c as warningMentionsPackage, i as resolveSkillUse, o as getEffectiveExcludePatterns, r as resolveSkillEntry, s as isPackageExcluded, t as ResolveSkillUseError } from "./resolver-BDsZ3kWg.mjs";
7
7
  import { existsSync, readFileSync, realpathSync } from "node:fs";
8
8
  import { dirname, isAbsolute, join, relative, resolve } from "node:path";
9
9
 
@@ -213,15 +213,15 @@ function rewriteLoadedSkillMarkdownDestinations({ content, cwd, packageRoot, ski
213
213
 
214
214
  //#endregion
215
215
  //#region src/core/load-resolution.ts
216
- function readWorkspacePackageInfos(context) {
216
+ function readWorkspacePackageInfos(context, fsCache) {
217
217
  const dirs = /* @__PURE__ */ new Set();
218
218
  if (context.packageRoot) dirs.add(context.packageRoot);
219
219
  if (context.workspaceRoot) {
220
220
  dirs.add(context.workspaceRoot);
221
- for (const dir of resolveWorkspacePackages(context.workspaceRoot, context.workspacePatterns)) dirs.add(dir);
221
+ for (const dir of findWorkspacePackages(context.workspaceRoot)) dirs.add(dir);
222
222
  }
223
223
  return [...dirs].flatMap((dir) => {
224
- const packageJson = readPackageJson(dir);
224
+ const packageJson = fsCache.readPackageJson(dir);
225
225
  if (!packageJson) return [];
226
226
  return [{
227
227
  dir,
@@ -270,10 +270,10 @@ function getDirectLoadFastPathCandidateDirs(packageName, context, cwd) {
270
270
  if (context.workspaceRoot && context.workspaceRoot !== context.packageRoot) addCandidateDir(candidates, seen, resolveDependencyPackageDir(packageName, context.workspaceRoot));
271
271
  return candidates;
272
272
  }
273
- function getWorkspaceLoadFastPathCandidateDirs(packageName, context) {
273
+ function getWorkspaceLoadFastPathCandidateDirs(packageName, context, fsCache) {
274
274
  const candidates = [];
275
275
  const seen = /* @__PURE__ */ new Set();
276
- const workspacePackages = readWorkspacePackageInfos(context);
276
+ const workspacePackages = readWorkspacePackageInfos(context, fsCache);
277
277
  for (const pkg of workspacePackages) if (pkg.name === packageName) addCandidateDir(candidates, seen, pkg.dir);
278
278
  for (const pkg of workspacePackages) {
279
279
  if (!workspacePackageDeclaresDependency(pkg.packageJson, packageName)) continue;
@@ -297,10 +297,11 @@ function resolveScannedPackageSkill(scanned, parsedUse) {
297
297
  conflict: null
298
298
  };
299
299
  }
300
- function resolveFromPackageRoots(packageRoots, parsedUse, cwd) {
300
+ function resolveFromPackageRoots(packageRoots, parsedUse, cwd, fsCache) {
301
301
  for (const packageRoot of packageRoots) {
302
302
  const scanned = scanIntentPackageAtRoot(packageRoot, {
303
303
  fallbackName: parsedUse.packageName,
304
+ fsCache,
304
305
  projectRoot: cwd,
305
306
  skillNameHint: parsedUse.skillName
306
307
  });
@@ -309,6 +310,7 @@ function resolveFromPackageRoots(packageRoots, parsedUse, cwd) {
309
310
  if (scanned.package?.name === parsedUse.packageName) {
310
311
  const fallbackResolved = resolveScannedPackageSkill(scanIntentPackageAtRoot(packageRoot, {
311
312
  fallbackName: parsedUse.packageName,
313
+ fsCache,
312
314
  projectRoot: cwd
313
315
  }), parsedUse);
314
316
  if (fallbackResolved) return fallbackResolved;
@@ -316,13 +318,13 @@ function resolveFromPackageRoots(packageRoots, parsedUse, cwd) {
316
318
  }
317
319
  return null;
318
320
  }
319
- function resolveSkillUseFastPath(parsedUse, options, context = resolveProjectContext({ cwd: process.cwd() }), cwd = context.cwd) {
321
+ function resolveSkillUseFastPath(parsedUse, options, context = resolveProjectContext({ cwd: process.cwd() }), cwd = context.cwd, fsCache = createIntentFsCache()) {
320
322
  if (options.globalOnly) return null;
321
323
  if (shouldSkipFastPathForYarnPnp(context, cwd)) return null;
322
- const directResolved = resolveFromPackageRoots(getDirectLoadFastPathCandidateDirs(parsedUse.packageName, context, cwd), parsedUse, cwd);
324
+ const directResolved = resolveFromPackageRoots(getDirectLoadFastPathCandidateDirs(parsedUse.packageName, context, cwd), parsedUse, cwd, fsCache);
323
325
  if (directResolved) return directResolved;
324
326
  if (!context.workspaceRoot) return null;
325
- return resolveFromPackageRoots(getWorkspaceLoadFastPathCandidateDirs(parsedUse.packageName, context), parsedUse, cwd);
327
+ return resolveFromPackageRoots(getWorkspaceLoadFastPathCandidateDirs(parsedUse.packageName, context, fsCache), parsedUse, cwd, fsCache);
326
328
  }
327
329
 
328
330
  //#endregion
@@ -344,14 +346,21 @@ function toScanOptions(options) {
344
346
  function getScanScope(options) {
345
347
  return options.scope ?? (options.includeGlobal ? "local-and-global" : "local");
346
348
  }
349
+ function withFsCache(options, fsCache) {
350
+ return {
351
+ ...options,
352
+ fsCache
353
+ };
354
+ }
347
355
  function resolveCoreCwd(options) {
348
356
  return resolve(process.cwd(), options.cwd ?? process.cwd());
349
357
  }
350
358
  function listIntentSkills(options = {}) {
351
359
  const cwd = resolveCoreCwd(options);
352
360
  const scanOptions = toScanOptions(options);
361
+ const fsCache = createIntentFsCache();
353
362
  const projectContext = resolveProjectContext({ cwd });
354
- const scanResult = scanForIntents(cwd, scanOptions);
363
+ const scanResult = scanForIntents(cwd, withFsCache(scanOptions, fsCache));
355
364
  const excludePatterns = getEffectiveExcludePatterns(options, projectContext);
356
365
  const excludeMatchers = compileExcludePatterns(excludePatterns);
357
366
  const excludedPackages = scanResult.packages.filter((pkg) => isPackageExcluded(pkg.name, excludeMatchers)).map((pkg) => pkg.name);
@@ -387,7 +396,8 @@ function listIntentSkills(options = {}) {
387
396
  packageCount: result.packages.length,
388
397
  skillCount: result.skills.length,
389
398
  warningCount: result.warnings.length,
390
- conflictCount: result.conflicts.length
399
+ conflictCount: result.conflicts.length,
400
+ scan: scanResult.stats ?? fsCache.getStats()
391
401
  };
392
402
  return result;
393
403
  }
@@ -424,7 +434,7 @@ function toResolvedIntentSkill(cwd, use, resolved, debug) {
424
434
  result
425
435
  };
426
436
  }
427
- function createLoadedSkillDebug({ cwd, excludes, resolution, resolved, scope }) {
437
+ function createLoadedSkillDebug({ cwd, excludes, scan, resolution, resolved, scope }) {
428
438
  return {
429
439
  cwd,
430
440
  scope,
@@ -435,7 +445,8 @@ function createLoadedSkillDebug({ cwd, excludes, resolution, resolved, scope })
435
445
  version: resolved.version,
436
446
  source: resolved.source,
437
447
  path: resolved.path,
438
- warningCount: resolved.warnings.length
448
+ warningCount: resolved.warnings.length,
449
+ scan
439
450
  };
440
451
  }
441
452
  function resolveIntentSkillInCwd(cwd, use, options = {}) {
@@ -445,21 +456,23 @@ function resolveIntentSkillInCwd(cwd, use, options = {}) {
445
456
  } catch (err) {
446
457
  throw new IntentCoreError("invalid-skill-use", err instanceof Error ? err.message : String(err));
447
458
  }
459
+ const fsCache = createIntentFsCache();
448
460
  const projectContext = resolveProjectContext({ cwd });
449
461
  const excludePatterns = getEffectiveExcludePatterns(options, projectContext);
450
462
  const excludeMatchers = compileExcludePatterns(excludePatterns);
451
463
  if (isPackageExcluded(parsedUse.packageName, excludeMatchers)) throw new IntentCoreError("package-excluded", `Cannot load skill use "${use}": package "${parsedUse.packageName}" is excluded by Intent configuration.`);
452
464
  const scanOptions = toScanOptions(options);
453
465
  const scope = getScanScope(scanOptions);
454
- const fastPathResolved = resolveSkillUseFastPath(parsedUse, options, projectContext, cwd);
466
+ const fastPathResolved = resolveSkillUseFastPath(parsedUse, options, projectContext, cwd, fsCache);
455
467
  if (fastPathResolved) return toResolvedIntentSkill(cwd, use, fastPathResolved, options.debug ? createLoadedSkillDebug({
456
468
  cwd,
457
469
  excludes: excludePatterns,
458
470
  resolution: "fast-path",
459
471
  resolved: fastPathResolved,
472
+ scan: fsCache.getStats(),
460
473
  scope
461
474
  }) : void 0);
462
- const scanResult = scanForIntents(cwd, scanOptions);
475
+ const scanResult = scanForIntents(cwd, withFsCache(scanOptions, fsCache));
463
476
  let resolved;
464
477
  try {
465
478
  resolved = resolveSkillUse(use, scanResult);
@@ -472,6 +485,7 @@ function resolveIntentSkillInCwd(cwd, use, options = {}) {
472
485
  excludes: excludePatterns,
473
486
  resolution: "full-scan",
474
487
  resolved,
488
+ scan: scanResult.stats ?? fsCache.getStats(),
475
489
  scope
476
490
  }) : void 0);
477
491
  }
package/dist/core.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { b as VersionConflict, h as ScanScope, l as IntentPackage } from "./types-S2zpibHp.mjs";
1
+ import { g as ScanStats, h as ScanScope, l as IntentPackage, x as VersionConflict } from "./types-Cq5cY9h9.mjs";
2
2
 
3
3
  //#region src/core/types.d.ts
4
4
  interface IntentCoreOptions {
@@ -55,6 +55,7 @@ interface IntentSkillListDebug {
55
55
  skillCount: number;
56
56
  warningCount: number;
57
57
  conflictCount: number;
58
+ scan: IntentScanDebugStats;
58
59
  }
59
60
  interface LoadedIntentSkillDebug {
60
61
  cwd: string;
@@ -67,7 +68,9 @@ interface LoadedIntentSkillDebug {
67
68
  source: IntentPackage['source'];
68
69
  path: string;
69
70
  warningCount: number;
71
+ scan: IntentScanDebugStats;
70
72
  }
73
+ interface IntentScanDebugStats extends ScanStats {}
71
74
  type IntentCoreErrorCode = 'invalid-options' | 'invalid-skill-use' | 'package-not-found' | 'package-excluded' | 'skill-not-found' | 'skill-path-outside-package' | 'skill-file-not-found';
72
75
  //#endregion
73
76
  //#region src/core.d.ts
package/dist/core.mjs CHANGED
@@ -1,9 +1,9 @@
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 { i as resolveIntentSkill, n as listIntentSkills, r as loadIntentSkill, t as IntentCoreError } from "./core-0H8zUKIh.mjs";
1
+ import "./utils-BPDvfmcd.mjs";
2
+ import "./skill-paths-BHbdWniB.mjs";
3
+ import "./scanner-BGyQTQ3U.mjs";
4
+ import "./workspace-patterns-CIJQCwbJ.mjs";
5
+ import "./project-context-Bv9BDh8B.mjs";
6
+ import "./resolver-BDsZ3kWg.mjs";
7
+ import { i as resolveIntentSkill, n as listIntentSkills, r as loadIntentSkill, t as IntentCoreError } from "./core-BOSjgetf.mjs";
8
8
 
9
9
  export { IntentCoreError, listIntentSkills, loadIntentSkill, resolveIntentSkill };
@@ -0,0 +1,5 @@
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,4 +1,4 @@
1
- import { n as isStableLoadPath, t as formatRuntimeSkillLookupHint } from "./skill-paths-DNOHrvL5.mjs";
1
+ import { n as isStableLoadPath, t as formatRuntimeSkillLookupHint } from "./skill-paths-BHbdWniB.mjs";
2
2
 
3
3
  //#region src/display.ts
4
4
  function padColumn(text, width) {
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as SkillStaleness, a as IntentArtifactSet, b as VersionConflict, c as IntentConfig, d as MetaFeedbackPayload, f as MetaSkillName, g as SkillEntry, i as IntentArtifactFile, l as IntentPackage, m as ScanResult, n as FeedbackPayload, o as IntentArtifactSkill, p as ScanOptions, r as IntentArtifactCoverageIgnore, s as IntentArtifactWarning, t as AgentName, u as IntentProjectConfig, v as StalenessReport, y as StalenessSignal } from "./types-S2zpibHp.mjs";
1
+ import { _ as SkillEntry, a as IntentArtifactSet, b as StalenessSignal, c as IntentConfig, d as MetaFeedbackPayload, f as MetaSkillName, i as IntentArtifactFile, l as IntentPackage, m as ScanResult, n as FeedbackPayload, o as IntentArtifactSkill, p as ScanOptions, r as IntentArtifactCoverageIgnore, s as IntentArtifactWarning, t as AgentName, u as IntentProjectConfig, v as SkillStaleness, x as VersionConflict, y as StalenessReport } from "./types-Cq5cY9h9.mjs";
2
2
  import { i as runEditPackageJson, o as runSetupGithubActions, r as SetupGithubActionsResult, t as EditPackageJsonResult } from "./setup-2SE9zYJk.mjs";
3
3
 
4
4
  //#region src/scanner.d.ts
package/dist/index.mjs CHANGED
@@ -1,14 +1,14 @@
1
- import { a as parseFrontmatter, n as findSkillFiles, o as resolveDepDir, r as getDeps } from "./utils-mdb4i6VA.mjs";
2
- import "./skill-paths-DNOHrvL5.mjs";
3
- import { t as scanForIntents } from "./scanner-BaOA18pn.mjs";
4
- import "./workspace-patterns-BZLEaMcS.mjs";
1
+ import { a as parseFrontmatter, n as findSkillFiles, o as resolveDepDir, r as getDeps } from "./utils-BPDvfmcd.mjs";
2
+ import "./skill-paths-BHbdWniB.mjs";
3
+ import { t as scanForIntents } from "./scanner-BGyQTQ3U.mjs";
4
+ import "./workspace-patterns-CIJQCwbJ.mjs";
5
5
  import { t as readIntentArtifacts } from "./artifact-coverage-DgWuVqUp.mjs";
6
- import { n as checkStaleness } from "./staleness-V-nwqFUh.mjs";
6
+ import { n as checkStaleness } from "./staleness-CGLs-swr.mjs";
7
7
  import { n as collectStaleReviewItems, r as createFailedStaleReviewItem, t as buildStaleReviewBody } from "./workflow-review-CwcR2ge4.mjs";
8
8
  import { i as parseSkillUse, n as formatSkillUse, r as isSkillUseParseError, t as SkillUseParseError } from "./skill-use-umYvZl94.mjs";
9
- import "./project-context-Dx6XIJJo.mjs";
10
- import { i as resolveSkillUse, n as isResolveSkillUseError, t as ResolveSkillUseError } from "./resolver-CP0S8UjZ.mjs";
11
- import { r as runSetupGithubActions, t as runEditPackageJson } from "./setup-kvWN4xCr.mjs";
9
+ import "./project-context-Bv9BDh8B.mjs";
10
+ import { i as resolveSkillUse, n as isResolveSkillUseError, t as ResolveSkillUseError } from "./resolver-BDsZ3kWg.mjs";
11
+ import { r as runSetupGithubActions, t as runEditPackageJson } from "./setup-DQMKxEoA.mjs";
12
12
  import { readFileSync, writeFileSync } from "node:fs";
13
13
  import { join } from "node:path";
14
14
  import { execFileSync, execSync } from "node:child_process";
@@ -1,6 +1,6 @@
1
1
  import { i as parseSkillUse, n as formatSkillUse } from "./skill-use-umYvZl94.mjs";
2
2
  import { t as fail } from "./cli-error-BrMXlbtx.mjs";
3
- import { c as scanOptionsFromGlobalFlags, l as printWarnings } from "./cli-support-Dmpj1iyQ.mjs";
3
+ import { c as scanOptionsFromGlobalFlags, l as printWarnings } from "./cli-support-DtqVDiJv.mjs";
4
4
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
5
5
  import { dirname, join, relative } from "node:path";
6
6
  import { parse } from "yaml";
@@ -0,0 +1,7 @@
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,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import "./utils-mdb4i6VA.mjs";
3
- import "./skill-paths-DNOHrvL5.mjs";
4
- import "./workspace-patterns-BZLEaMcS.mjs";
5
- import "./project-context-Dx6XIJJo.mjs";
6
- import { n as printSkillTree, r as printTable, t as computeSkillNameWidth } from "./display-CVeoAwBd.mjs";
7
- import "./cli-support-Dmpj1iyQ.mjs";
8
- import { t as INSTALL_PROMPT } from "./install-7BAmUZFB.mjs";
9
- import { t as scanLibrary } from "./library-scanner-CHepLJQJ.mjs";
2
+ import "./utils-BPDvfmcd.mjs";
3
+ import "./skill-paths-BHbdWniB.mjs";
4
+ import "./workspace-patterns-CIJQCwbJ.mjs";
5
+ import "./project-context-Bv9BDh8B.mjs";
6
+ import { n as printSkillTree, r as printTable, t as computeSkillNameWidth } from "./display-DHNuzSqR.mjs";
7
+ import "./cli-support-DtqVDiJv.mjs";
8
+ import { t as INSTALL_PROMPT } from "./install-CLkmoPOY.mjs";
9
+ import { t as scanLibrary } from "./library-scanner-BAJ7bXtW.mjs";
10
10
 
11
11
  //#region src/intent-library.ts
12
12
  function cmdList() {
@@ -1,5 +1,5 @@
1
- import { a as parseFrontmatter, o as resolveDepDir, r as getDeps, s as toPosixPath } from "./utils-mdb4i6VA.mjs";
2
- import { r as rewriteSkillLoadPaths } from "./skill-paths-DNOHrvL5.mjs";
1
+ import { a as parseFrontmatter, o as resolveDepDir, r as getDeps, s as toPosixPath } from "./utils-BPDvfmcd.mjs";
2
+ import { r as rewriteSkillLoadPaths } from "./skill-paths-BHbdWniB.mjs";
3
3
  import { existsSync, readFileSync, readdirSync } from "node:fs";
4
4
  import { dirname, join, relative } from "node:path";
5
5
 
@@ -1,4 +1,4 @@
1
- import { g as SkillEntry } from "./types-S2zpibHp.mjs";
1
+ import { _ as SkillEntry } from "./types-Cq5cY9h9.mjs";
2
2
 
3
3
  //#region src/library-scanner.d.ts
4
4
  interface LibraryPackage {
@@ -1,5 +1,5 @@
1
- import "./utils-mdb4i6VA.mjs";
2
- import "./skill-paths-DNOHrvL5.mjs";
3
- import { t as scanLibrary } from "./library-scanner-CHepLJQJ.mjs";
1
+ import "./utils-BPDvfmcd.mjs";
2
+ import "./skill-paths-BHbdWniB.mjs";
3
+ import { t as scanLibrary } from "./library-scanner-BAJ7bXtW.mjs";
4
4
 
5
5
  export { scanLibrary };
@@ -1,11 +1,11 @@
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-BPDvfmcd.mjs";
2
+ import "./skill-paths-BHbdWniB.mjs";
3
+ import "./scanner-BGyQTQ3U.mjs";
4
+ import "./workspace-patterns-CIJQCwbJ.mjs";
5
+ import "./project-context-Bv9BDh8B.mjs";
6
+ import "./resolver-BDsZ3kWg.mjs";
7
+ import { a as printDebugInfo, l as printWarnings, n as coreOptionsFromGlobalFlags } from "./cli-support-DtqVDiJv.mjs";
8
+ import { n as listIntentSkills } from "./core-BOSjgetf.mjs";
9
9
 
10
10
  //#region src/commands/list.ts
11
11
  function printListDebug(result) {
@@ -17,7 +17,9 @@ function printListDebug(result) {
17
17
  ["packages", result.debug.packageCount],
18
18
  ["skills", result.debug.skillCount],
19
19
  ["warnings", result.debug.warningCount],
20
- ["conflicts", result.debug.conflictCount]
20
+ ["conflicts", result.debug.conflictCount],
21
+ ["packageJsonReadCount", result.debug.scan.packageJsonReadCount],
22
+ ["packageJsonCacheHits", result.debug.scan.packageJsonCacheHits]
21
23
  ]);
22
24
  }
23
25
  function printVersionConflicts(result) {
@@ -53,7 +55,7 @@ async function runListCommand(options, _scanIntentsOrFail) {
53
55
  console.log(JSON.stringify(jsonResult, null, 2));
54
56
  return;
55
57
  }
56
- const { computeSkillNameWidth, printSkillTree, printTable } = await import("./display-COlw5FaB.mjs");
58
+ const { computeSkillNameWidth, printSkillTree, printTable } = await import("./display-CmLzVAae.mjs");
57
59
  if (result.packages.length === 0) {
58
60
  console.log("No intent-enabled packages found.");
59
61
  if (result.warnings.length > 0) {
@@ -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";
1
+ import "./utils-BPDvfmcd.mjs";
2
+ import "./skill-paths-BHbdWniB.mjs";
3
+ import "./scanner-BGyQTQ3U.mjs";
4
+ import "./workspace-patterns-CIJQCwbJ.mjs";
5
+ import "./project-context-Bv9BDh8B.mjs";
6
+ import "./resolver-BDsZ3kWg.mjs";
7
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";
8
+ import { a as printDebugInfo, n as coreOptionsFromGlobalFlags } from "./cli-support-DtqVDiJv.mjs";
9
+ import { i as resolveIntentSkill, r as loadIntentSkill, t as IntentCoreError } from "./core-BOSjgetf.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) {
@@ -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-DqdIC3RY.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.");
@@ -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-CIJQCwbJ.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
1
  import { i as parseSkillUse } from "./skill-use-umYvZl94.mjs";
2
- import { t as resolveProjectContext } from "./project-context-Dx6XIJJo.mjs";
2
+ import { t as resolveProjectContext } from "./project-context-Bv9BDh8B.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,8 @@
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 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";
4
4
  import { createRequire } from "node:module";
5
- import { existsSync, readFileSync, readdirSync } from "node:fs";
5
+ import { existsSync, readFileSync } from "node:fs";
6
6
  import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
7
7
  import semver from "semver";
8
8
 
@@ -10,13 +10,32 @@ import semver from "semver";
10
10
  function isLocalToProject(dirPath, projectRoot) {
11
11
  return dirPath.startsWith(projectRoot + sep) || dirPath.startsWith(projectRoot + "/");
12
12
  }
13
+ function getFsIdentity(path) {
14
+ return resolve(path);
15
+ }
13
16
  function createPackageRegistrar(opts) {
17
+ const attemptedPackageRoots = /* @__PURE__ */ new Set();
18
+ const scannedNodeModulesDirs = /* @__PURE__ */ new Set();
19
+ function shouldAttemptPackageRoot(dirPath) {
20
+ const key = getFsIdentity(dirPath);
21
+ if (attemptedPackageRoots.has(key)) return false;
22
+ attemptedPackageRoots.add(key);
23
+ return true;
24
+ }
25
+ function scanNodeModulesDir(nodeModulesDir, source = "local") {
26
+ if (!existsSync(nodeModulesDir)) return;
27
+ const key = getFsIdentity(nodeModulesDir);
28
+ if (scannedNodeModulesDirs.has(key)) return;
29
+ scannedNodeModulesDirs.add(key);
30
+ for (const dirPath of listNodeModulesPackageDirs(nodeModulesDir)) tryRegister(dirPath, "unknown", source);
31
+ }
14
32
  function scanTarget(target, source = "local") {
15
33
  if (!target.path || !target.exists || target.scanned) return;
16
34
  target.scanned = true;
17
- for (const dirPath of listNodeModulesPackageDirs(target.path)) tryRegister(dirPath, "unknown", source);
35
+ scanNodeModulesDir(target.path, source);
18
36
  }
19
37
  function tryRegister(dirPath, fallbackName, source = "local") {
38
+ if (!shouldAttemptPackageRoot(dirPath)) return false;
20
39
  const skillsDir = join(dirPath, "skills");
21
40
  if (!existsSync(skillsDir)) return false;
22
41
  const pkgJson = opts.readPkgJson(dirPath);
@@ -62,6 +81,7 @@ function createPackageRegistrar(opts) {
62
81
  return true;
63
82
  }
64
83
  return {
84
+ scanNodeModulesDir,
65
85
  scanTarget,
66
86
  tryRegister
67
87
  };
@@ -108,19 +128,16 @@ 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
  }
@@ -132,6 +149,65 @@ function createDependencyWalker(opts) {
132
149
  };
133
150
  }
134
151
 
152
+ //#endregion
153
+ //#region src/fs-cache.ts
154
+ function normalizeCacheKey(path) {
155
+ return resolve(path);
156
+ }
157
+ function isRecord(value) {
158
+ return typeof value === "object" && value !== null && !Array.isArray(value);
159
+ }
160
+ function createIntentFsCache() {
161
+ const packageJsonCache = /* @__PURE__ */ new Map();
162
+ const skillFilesCache = /* @__PURE__ */ new Map();
163
+ const stats = {
164
+ packageJsonReadCount: 0,
165
+ packageJsonCacheHits: 0
166
+ };
167
+ function readPackageJsonResult(dir) {
168
+ const key = normalizeCacheKey(dir);
169
+ const cached = packageJsonCache.get(key);
170
+ if (cached) {
171
+ stats.packageJsonCacheHits += 1;
172
+ return cached;
173
+ }
174
+ stats.packageJsonReadCount += 1;
175
+ try {
176
+ const parsed = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
177
+ const result = {
178
+ packageJson: isRecord(parsed) ? parsed : null,
179
+ error: null
180
+ };
181
+ packageJsonCache.set(key, result);
182
+ return result;
183
+ } catch (error) {
184
+ const result = {
185
+ packageJson: null,
186
+ error
187
+ };
188
+ packageJsonCache.set(key, result);
189
+ return result;
190
+ }
191
+ }
192
+ function readPackageJson(dir) {
193
+ return readPackageJsonResult(dir).packageJson;
194
+ }
195
+ function findSkillFiles$1(dir) {
196
+ const key = normalizeCacheKey(dir);
197
+ const cached = skillFilesCache.get(key);
198
+ if (cached) return [...cached];
199
+ const files = findSkillFiles(dir);
200
+ skillFilesCache.set(key, files);
201
+ return [...files];
202
+ }
203
+ return {
204
+ readPackageJson,
205
+ readPackageJsonResult,
206
+ findSkillFiles: findSkillFiles$1,
207
+ getStats: () => ({ ...stats })
208
+ };
209
+ }
210
+
135
211
  //#endregion
136
212
  //#region src/scanner.ts
137
213
  const requireFromHere = createRequire(import.meta.url);
@@ -261,28 +337,12 @@ function discoverSkillByNameHint(skillsDir, packageName, skillNameHint) {
261
337
  }
262
338
  return skills;
263
339
  }
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;
340
+ function discoverSkills(skillsDir, fsCache) {
341
+ return fsCache.findSkillFiles(skillsDir).flatMap((skillFile) => {
342
+ const childDir = dirname(skillFile);
343
+ if (childDir === skillsDir) return [];
344
+ return [readSkillEntry(skillsDir, childDir, skillFile)];
345
+ });
286
346
  }
287
347
  function getPackageShortName(packageName) {
288
348
  return packageName.split("/").pop() ?? packageName;
@@ -364,6 +424,7 @@ function getScanScope(options) {
364
424
  function scanForIntents(root, options = {}) {
365
425
  const projectRoot = root ?? process.cwd();
366
426
  const scanScope = getScanScope(options);
427
+ const fsCache = options.fsCache ?? createIntentFsCache();
367
428
  const packageManager = detectPackageManager(projectRoot);
368
429
  const nodeModulesDir = join(projectRoot, "node_modules");
369
430
  const explicitGlobalNodeModules = process.env.INTENT_GLOBAL_NODE_MODULES?.trim() || null;
@@ -386,7 +447,6 @@ function scanForIntents(root, options = {}) {
386
447
  }
387
448
  };
388
449
  const packageIndexes = /* @__PURE__ */ new Map();
389
- const packageJsonCache = /* @__PURE__ */ new Map();
390
450
  const packageVariants = /* @__PURE__ */ new Map();
391
451
  let pnpApi;
392
452
  function getPnpApi() {
@@ -394,6 +454,9 @@ function scanForIntents(root, options = {}) {
394
454
  if (pnpApi === void 0) pnpApi = loadPnpApi(projectRoot);
395
455
  return pnpApi;
396
456
  }
457
+ function getStats() {
458
+ return fsCache.getStats();
459
+ }
397
460
  function rememberVariant(pkg) {
398
461
  let variants = packageVariants.get(pkg.name);
399
462
  if (!variants) {
@@ -415,20 +478,12 @@ function scanForIntents(root, options = {}) {
415
478
  }
416
479
  }
417
480
  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
- }
481
+ return fsCache.readPackageJson(dirPath);
427
482
  }
428
- const { scanTarget, tryRegister } = createPackageRegistrar({
483
+ const { scanNodeModulesDir, scanTarget, tryRegister } = createPackageRegistrar({
429
484
  comparePackageVersions,
430
485
  deriveIntentConfig,
431
- discoverSkills,
486
+ discoverSkills: (skillsDir) => discoverSkills(skillsDir, fsCache),
432
487
  getPackageDepth,
433
488
  packageIndexes,
434
489
  packages,
@@ -439,9 +494,11 @@ function scanForIntents(root, options = {}) {
439
494
  warnings
440
495
  });
441
496
  const { walkKnownPackages, walkProjectDeps, walkWorkspacePackages } = createDependencyWalker({
497
+ fsCache,
442
498
  packages,
443
499
  projectRoot,
444
500
  readPkgJson,
501
+ scanNodeModulesDir,
445
502
  tryRegister,
446
503
  warnings
447
504
  });
@@ -506,7 +563,8 @@ function scanForIntents(root, options = {}) {
506
563
  packages,
507
564
  warnings,
508
565
  conflicts,
509
- nodeModules
566
+ nodeModules,
567
+ stats: getStats()
510
568
  };
511
569
  for (const pkg of packages) {
512
570
  const variants = packageVariants.get(pkg.name);
@@ -521,7 +579,8 @@ function scanForIntents(root, options = {}) {
521
579
  packages: topoSort(packages),
522
580
  warnings,
523
581
  conflicts,
524
- nodeModules
582
+ nodeModules,
583
+ stats: getStats()
525
584
  };
526
585
  }
527
586
  function scanIntentPackageAtRoot(packageRoot, options = {}) {
@@ -529,22 +588,14 @@ function scanIntentPackageAtRoot(packageRoot, options = {}) {
529
588
  const packages = [];
530
589
  const warnings = [];
531
590
  const packageIndexes = /* @__PURE__ */ new Map();
532
- const packageJsonCache = /* @__PURE__ */ new Map();
591
+ const fsCache = options.fsCache ?? createIntentFsCache();
533
592
  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
- }
593
+ return fsCache.readPackageJson(dirPath);
543
594
  }
544
595
  const { tryRegister } = createPackageRegistrar({
545
596
  comparePackageVersions,
546
597
  deriveIntentConfig,
547
- discoverSkills: options.skillNameHint ? (skillsDir, packageName) => discoverSkillByNameHint(skillsDir, packageName, options.skillNameHint) : discoverSkills,
598
+ discoverSkills: options.skillNameHint ? (skillsDir, packageName) => discoverSkillByNameHint(skillsDir, packageName, options.skillNameHint) : (skillsDir) => discoverSkills(skillsDir, fsCache),
548
599
  getPackageDepth,
549
600
  packageIndexes,
550
601
  packages,
@@ -562,4 +613,4 @@ function scanIntentPackageAtRoot(packageRoot, options = {}) {
562
613
  }
563
614
 
564
615
  //#endregion
565
- export { scanIntentPackageAtRoot as n, scanForIntents as t };
616
+ export { scanIntentPackageAtRoot as n, createIntentFsCache as r, scanForIntents as t };
@@ -0,0 +1,6 @@
1
+ import "./utils-BPDvfmcd.mjs";
2
+ import "./skill-paths-BHbdWniB.mjs";
3
+ import { n as scanIntentPackageAtRoot, t as scanForIntents } from "./scanner-BGyQTQ3U.mjs";
4
+ import "./workspace-patterns-CIJQCwbJ.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-CIJQCwbJ.mjs";
2
+ import { t as resolveProjectContext } from "./project-context-Bv9BDh8B.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.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-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";
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 { s as toPosixPath } from "./utils-BPDvfmcd.mjs";
2
2
  import { existsSync } from "node:fs";
3
3
  import { join, relative } from "node:path";
4
4
 
@@ -1,4 +1,4 @@
1
- import { a as parseFrontmatter, n as findSkillFiles, s as toPosixPath } from "./utils-mdb4i6VA.mjs";
1
+ import { a as parseFrontmatter, n as findSkillFiles, s as toPosixPath } from "./utils-BPDvfmcd.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-mdb4i6VA.mjs";
1
+ import "./utils-BPDvfmcd.mjs";
2
2
  import "./artifact-coverage-DgWuVqUp.mjs";
3
- import { n as checkStaleness, r as readPackageName, t as buildWorkspaceCoverageSignals } from "./staleness-V-nwqFUh.mjs";
3
+ import { n as checkStaleness, r as readPackageName, t as buildWorkspaceCoverageSignals } from "./staleness-CGLs-swr.mjs";
4
4
 
5
5
  export { buildWorkspaceCoverageSignals, checkStaleness, readPackageName };
@@ -14,12 +14,17 @@ interface ScanResult {
14
14
  local: NodeModulesScanTarget;
15
15
  global: NodeModulesScanTarget;
16
16
  };
17
+ stats?: ScanStats;
17
18
  }
18
19
  type ScanScope = 'local' | 'local-and-global' | 'global';
19
20
  interface ScanOptions {
20
21
  includeGlobal?: boolean;
21
22
  scope?: ScanScope;
22
23
  }
24
+ interface ScanStats {
25
+ packageJsonReadCount: number;
26
+ packageJsonCacheHits: number;
27
+ }
23
28
  interface NodeModulesScanTarget {
24
29
  path: string | null;
25
30
  detected: boolean;
@@ -143,4 +148,4 @@ interface IntentProjectConfig {
143
148
  };
144
149
  }
145
150
  //#endregion
146
- export { SkillStaleness as _, IntentArtifactSet as a, VersionConflict as b, IntentConfig as c, MetaFeedbackPayload as d, MetaSkillName as f, SkillEntry 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, StalenessReport as v, StalenessSignal as y };
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 };
@@ -17,7 +17,16 @@ function toPosixPath(p) {
17
17
  function findSkillFiles(dir) {
18
18
  const files = [];
19
19
  if (!existsSync(dir)) return files;
20
- for (const entry of readdirSync(dir, { withFileTypes: true })) {
20
+ let entries;
21
+ try {
22
+ entries = readdirSync(dir, {
23
+ withFileTypes: true,
24
+ encoding: "utf8"
25
+ });
26
+ } catch {
27
+ return files;
28
+ }
29
+ for (const entry of entries) {
21
30
  const fullPath = join(dir, entry.name);
22
31
  if (entry.isDirectory()) files.push(...findSkillFiles(fullPath));
23
32
  else if (entry.name === "SKILL.md") files.push(fullPath);
@@ -1,3 +1,3 @@
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-mdb4i6VA.mjs";
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
2
 
3
3
  export { detectGlobalNodeModules, findSkillFiles, getDeps, listNodeModulesPackageDirs, parseFrontmatter, resolveDepDir, toPosixPath };
@@ -1,8 +1,8 @@
1
- import "./utils-mdb4i6VA.mjs";
2
- import { n as findWorkspacePackages } from "./workspace-patterns-BZLEaMcS.mjs";
3
- import { t as resolveProjectContext } from "./project-context-Dx6XIJJo.mjs";
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";
4
4
  import { n as isCliFailure, t as fail } from "./cli-error-BrMXlbtx.mjs";
5
- import { l as printWarnings } from "./cli-support-Dmpj1iyQ.mjs";
5
+ import { l as printWarnings } from "./cli-support-DtqVDiJv.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-BHzSyNeJ.mjs")]);
118
+ const [{ parse: parseYaml }, { findSkillFiles }] = await Promise.all([import("yaml"), import("./utils-DqdIC3RY.mjs")]);
119
119
  const context = resolveProjectContext({
120
120
  cwd: process.cwd(),
121
121
  targetPath: dir
@@ -1,4 +1,4 @@
1
- import { n as findSkillFiles } from "./utils-mdb4i6VA.mjs";
1
+ import { n as findSkillFiles } from "./utils-BPDvfmcd.mjs";
2
2
  import { existsSync, readFileSync, readdirSync } from "node:fs";
3
3
  import { dirname, join } from "node:path";
4
4
  import { parse } from "yaml";
@@ -1,4 +1,4 @@
1
- import "./utils-mdb4i6VA.mjs";
2
- import { a as readWorkspacePatterns, i as getWorkspaceInfo, n as findWorkspacePackages, o as resolveWorkspacePackages, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-BZLEaMcS.mjs";
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";
3
3
 
4
4
  export { findWorkspaceRoot, getWorkspaceInfo };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/intent",
3
- "version": "0.0.39",
3
+ "version": "0.0.40",
4
4
  "description": "Ship compositional knowledge for AI coding agents alongside your npm packages",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,5 +0,0 @@
1
- import "./utils-mdb4i6VA.mjs";
2
- import "./skill-paths-DNOHrvL5.mjs";
3
- import { n as printSkillTree, r as printTable, t as computeSkillNameWidth } from "./display-CVeoAwBd.mjs";
4
-
5
- export { computeSkillNameWidth, printSkillTree, printTable };
@@ -1,7 +0,0 @@
1
- import "./utils-mdb4i6VA.mjs";
2
- import "./workspace-patterns-BZLEaMcS.mjs";
3
- import "./project-context-Dx6XIJJo.mjs";
4
- import "./cli-support-Dmpj1iyQ.mjs";
5
- import { n as runInstallCommand, t as INSTALL_PROMPT } from "./install-7BAmUZFB.mjs";
6
-
7
- export { INSTALL_PROMPT, runInstallCommand };
@@ -1,6 +0,0 @@
1
- import "./utils-mdb4i6VA.mjs";
2
- import "./skill-paths-DNOHrvL5.mjs";
3
- import { n as scanIntentPackageAtRoot, t as scanForIntents } from "./scanner-BaOA18pn.mjs";
4
- import "./workspace-patterns-BZLEaMcS.mjs";
5
-
6
- export { scanForIntents };