@tanstack/intent 0.0.41 → 0.0.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/artifact-coverage-DA26utB1.mjs +3 -0
  2. package/dist/{cli-support-BxF1HIpw.mjs → cli-support-DV41R1Re.mjs} +4 -4
  3. package/dist/{cli-support-BHoEb9y1.mjs → cli-support-DzDBzS3-.mjs} +6 -6
  4. package/dist/cli.d.mts +2 -1
  5. package/dist/cli.mjs +21 -17
  6. package/dist/{core-DEiRgUqe.mjs → core-C7hpf0Tt.mjs} +20 -18
  7. package/dist/core.d.mts +1 -1
  8. package/dist/core.mjs +7 -7
  9. package/dist/{display-BPM-AJGc.mjs → display-0FnzlKRq.mjs} +3 -2
  10. package/dist/index.d.mts +42 -23
  11. package/dist/index.mjs +11 -11
  12. package/dist/{install-DCiBBx55.mjs → install-BW__b6st.mjs} +9 -6
  13. package/dist/{list-CpOcnLWv.mjs → list-DQvWxgPM.mjs} +10 -10
  14. package/dist/{load-BxmN8f0E.mjs → load-D5MM8OW9.mjs} +9 -9
  15. package/dist/{meta-Dstclm2x.mjs → meta-BEJIfnPG.mjs} +2 -2
  16. package/dist/{project-context-D4mFnCs7.mjs → project-context-BRIMzhi4.mjs} +6 -5
  17. package/dist/{resolver-B36uOK8c.mjs → resolver-D9cjsz11.mjs} +6 -7
  18. package/dist/{scanner-B6nnctK4.mjs → scanner-D3tAqvbj.mjs} +54 -26
  19. package/dist/scanner-DNM8orwt.mjs +6 -0
  20. package/dist/{setup-J4A9UfBB.mjs → setup-BklJkH_6.mjs} +2 -2
  21. package/dist/setup.d.mts +1 -1
  22. package/dist/setup.mjs +4 -4
  23. package/dist/{skill-paths-4kQXfQXo.mjs → skill-paths-B-j0dWDA.mjs} +1 -1
  24. package/dist/{stale-BD77r7KR.mjs → stale-C6dPKQ98.mjs} +1 -1
  25. package/dist/{staleness-DChVhbCN.mjs → staleness-BGFfic-Y.mjs} +2 -2
  26. package/dist/staleness-CB3qpVCq.mjs +5 -0
  27. package/dist/{utils-Chn-30vI.mjs → utils-9fhWAVua.mjs} +80 -22
  28. package/dist/utils-CSPzvaFu.mjs +3 -0
  29. package/dist/{validate-CTSG3eDc.mjs → validate-CZ65_6Li.mjs} +6 -6
  30. package/dist/{workflow-review-DcFipeG0.mjs → workflow-review-CrWkP7Hc.mjs} +1 -1
  31. package/dist/{workflow-review--Gc_yplP.mjs → workflow-review-D9Fg1G0P.mjs} +15 -15
  32. package/dist/{workspace-patterns-C5O4Dfpl.mjs → workspace-patterns-BffPlZ1D.mjs} +7 -8
  33. package/dist/{workspace-patterns-CA-UGM5C.mjs → workspace-patterns-Bjq_cXww.mjs} +2 -2
  34. package/package.json +3 -8
  35. package/dist/artifact-coverage-CbZALe7Q.mjs +0 -3
  36. package/dist/display-lWCJg5Bo.mjs +0 -5
  37. package/dist/install-EVdqAy8f.mjs +0 -7
  38. package/dist/intent-library.d.mts +0 -1
  39. package/dist/intent-library.mjs +0 -84
  40. package/dist/library-scanner-BpEuR__1.mjs +0 -116
  41. package/dist/library-scanner.d.mts +0 -16
  42. package/dist/library-scanner.mjs +0 -5
  43. package/dist/scanner-BWd4mS25.mjs +0 -6
  44. package/dist/staleness-Dm4laJFc.mjs +0 -5
  45. package/dist/utils-Ctlz_JG-.mjs +0 -3
  46. /package/dist/{artifact-coverage-Cqphhpfo.mjs → artifact-coverage-DgWuVqUp.mjs} +0 -0
  47. /package/dist/{cli-error-DOO5bLIG.mjs → cli-error-BrMXlbtx.mjs} +0 -0
  48. /package/dist/{command-runner-DJTliSTc.mjs → command-runner-C0yCOHLi.mjs} +0 -0
  49. /package/dist/{edit-package-json-cPClxVZZ.mjs → edit-package-json-CtuelQ_q.mjs} +0 -0
  50. /package/dist/{package-manager-DDZck142.mjs → package-manager-BUgTjW9Q.mjs} +0 -0
  51. /package/dist/{scaffold-CaShIIUY.mjs → scaffold-CLM6bt3c.mjs} +0 -0
  52. /package/dist/{setup-DL7qX_F-.d.mts → setup-DhMqESd3.d.mts} +0 -0
  53. /package/dist/{setup-github-actions-zzLUbyAL.mjs → setup-github-actions-CUd1oncY.mjs} +0 -0
  54. /package/dist/{skill-use-C0q2MEEX.mjs → skill-use-umYvZl94.mjs} +0 -0
  55. /package/dist/{types-DU_Z0qNT.d.mts → types-CIha6LtJ.d.mts} +0 -0
@@ -1,9 +1,9 @@
1
- import { a as listNestedNodeModulesPackageDirs, c as resolveDepDir, i as getDeps, l as toPosixPath, n as detectGlobalNodeModules, o as listNodeModulesPackageDirs, r as findSkillFiles, s as parseFrontmatter, t as createFsIdentityCache } from "./utils-Chn-30vI.mjs";
2
- import { r as rewriteSkillLoadPaths } from "./skill-paths-4kQXfQXo.mjs";
3
- import { n as findWorkspacePackages, r as findWorkspaceRoot } from "./workspace-patterns-C5O4Dfpl.mjs";
4
- import { t as detectPackageManager } from "./package-manager-DDZck142.mjs";
1
+ import { a as listNestedNodeModulesPackageDirs, c as parseFrontmatter, i as getDeps, l as resolveDepDir, n as detectGlobalNodeModules, o as listNodeModulesPackageDirs, r as findSkillFiles, s as nodeReadFs, t as createFsIdentityCache, u as toPosixPath } from "./utils-9fhWAVua.mjs";
2
+ import { r as rewriteSkillLoadPaths } from "./skill-paths-B-j0dWDA.mjs";
3
+ import { n as findWorkspacePackages, r as findWorkspaceRoot } from "./workspace-patterns-BffPlZ1D.mjs";
4
+ import { t as detectPackageManager } from "./package-manager-BUgTjW9Q.mjs";
5
5
  import { createRequire } from "node:module";
6
- import { existsSync, readFileSync } from "node:fs";
6
+ import { existsSync } from "node:fs";
7
7
  import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
8
8
  import semver from "semver";
9
9
 
@@ -35,7 +35,7 @@ function createPackageRegistrar(opts) {
35
35
  function tryRegister(dirPath, fallbackName, source = "local") {
36
36
  if (!shouldAttemptPackageRoot(dirPath)) return false;
37
37
  const skillsDir = join(dirPath, "skills");
38
- if (!existsSync(skillsDir)) return false;
38
+ if (!opts.exists(skillsDir)) return false;
39
39
  const pkgJson = opts.readPkgJson(dirPath);
40
40
  if (!pkgJson) {
41
41
  opts.warnings.push(`Could not read package.json for ${dirPath}`);
@@ -165,7 +165,8 @@ function isRecord(value) {
165
165
  function createIntentFsCache() {
166
166
  const packageJsonCache = /* @__PURE__ */ new Map();
167
167
  const skillFilesCache = /* @__PURE__ */ new Map();
168
- const getFsIdentity = createFsIdentityCache();
168
+ let activeFs = nodeReadFs;
169
+ const getFsIdentity = createFsIdentityCache(() => activeFs);
169
170
  const stats = {
170
171
  packageJsonReadCount: 0,
171
172
  packageJsonCacheHits: 0
@@ -179,7 +180,7 @@ function createIntentFsCache() {
179
180
  }
180
181
  stats.packageJsonReadCount += 1;
181
182
  try {
182
- const parsed = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
183
+ const parsed = JSON.parse(activeFs.readFileSync(join(dir, "package.json"), "utf8"));
183
184
  const result = {
184
185
  packageJson: isRecord(parsed) ? parsed : null,
185
186
  error: null
@@ -202,7 +203,7 @@ function createIntentFsCache() {
202
203
  const key = getFsIdentity(dir);
203
204
  const cached = skillFilesCache.get(key);
204
205
  if (cached) return [...cached];
205
- const files = findSkillFiles(dir);
206
+ const files = findSkillFiles(dir, activeFs);
206
207
  skillFilesCache.set(key, files);
207
208
  return [...files];
208
209
  }
@@ -211,7 +212,12 @@ function createIntentFsCache() {
211
212
  readPackageJsonResult,
212
213
  findSkillFiles: findSkillFiles$1,
213
214
  getFsIdentity,
214
- getStats: () => ({ ...stats })
215
+ getStats: () => ({ ...stats }),
216
+ useFs: (fs) => {
217
+ activeFs = fs;
218
+ },
219
+ getReadFs: () => activeFs,
220
+ exists: (path) => activeFs.existsSync(path)
215
221
  };
216
222
  }
217
223
 
@@ -220,15 +226,16 @@ function createIntentFsCache() {
220
226
  const requireFromHere = createRequire(import.meta.url);
221
227
  function findPnpFile(start) {
222
228
  let dir = resolve(start);
223
- while (true) {
229
+ let prev;
230
+ while (dir !== prev) {
224
231
  for (const fileName of [".pnp.cjs", ".pnp.js"]) {
225
232
  const pnpPath = join(dir, fileName);
226
233
  if (existsSync(pnpPath)) return pnpPath;
227
234
  }
228
- const next = dirname(dir);
229
- if (next === dir) return null;
230
- dir = next;
235
+ prev = dir;
236
+ dir = dirname(dir);
231
237
  }
238
+ return null;
232
239
  }
233
240
  function assertLocalNodeModulesSupported(root) {
234
241
  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.");
@@ -236,15 +243,29 @@ function assertLocalNodeModulesSupported(root) {
236
243
  function loadPnpApi(root) {
237
244
  const pnpPath = findPnpFile(root);
238
245
  if (!pnpPath) return null;
246
+ const moduleApi = requireFromHere("node:module");
247
+ const originalResolveFilename = moduleApi._resolveFilename;
248
+ const readFs = requireFromHere("node:fs");
239
249
  try {
240
250
  const pnpModule = requireFromHere(pnpPath);
241
251
  if (typeof pnpModule.setup === "function") pnpModule.setup();
242
- if (typeof pnpModule.getDependencyTreeRoots === "function" && typeof pnpModule.getPackageInformation === "function") return pnpModule;
243
- return createRequire(join(dirname(pnpPath), "package.json"))("pnpapi");
252
+ moduleApi._resolveFilename = originalResolveFilename;
253
+ if (typeof pnpModule.getDependencyTreeRoots === "function" && typeof pnpModule.getPackageInformation === "function") return {
254
+ api: pnpModule,
255
+ readFs
256
+ };
257
+ return {
258
+ api: createRequire(join(dirname(pnpPath), "package.json"))("pnpapi"),
259
+ readFs
260
+ };
244
261
  } catch (err) {
262
+ moduleApi._resolveFilename = originalResolveFilename;
245
263
  try {
246
- const foundApi = requireFromHere("node:module").findPnpApi?.(root);
247
- if (foundApi) return foundApi;
264
+ const foundApi = moduleApi.findPnpApi?.(root);
265
+ if (foundApi) return {
266
+ api: foundApi,
267
+ readFs
268
+ };
248
269
  } catch {}
249
270
  const msg = err instanceof Error ? err.message : String(err);
250
271
  throw new Error(`Yarn PnP project detected, but Intent could not load Yarn's PnP API from ${pnpPath}: ${msg}`);
@@ -302,8 +323,8 @@ function deriveIntentConfig(pkgJson) {
302
323
  requires
303
324
  };
304
325
  }
305
- function readSkillEntry(skillsDir, childDir, skillFile) {
306
- const fm = parseFrontmatter(skillFile);
326
+ function readSkillEntry(skillsDir, childDir, skillFile, readFs = nodeReadFs) {
327
+ const fm = parseFrontmatter(skillFile, readFs);
307
328
  const relName = toPosixPath(relative(skillsDir, childDir));
308
329
  const desc = typeof fm?.description === "string" ? fm.description.replace(/\s+/g, " ").trim() : "";
309
330
  return {
@@ -314,7 +335,7 @@ function readSkillEntry(skillsDir, childDir, skillFile) {
314
335
  framework: typeof fm?.framework === "string" ? fm.framework : void 0
315
336
  };
316
337
  }
317
- function discoverSkillByNameHint(skillsDir, packageName, skillNameHint) {
338
+ function discoverSkillByNameHint(skillsDir, packageName, skillNameHint, readFs = nodeReadFs) {
318
339
  const skills = [];
319
340
  const seen = /* @__PURE__ */ new Set();
320
341
  const skillNameHints = getSkillNameHints(packageName, skillNameHint);
@@ -322,8 +343,8 @@ function discoverSkillByNameHint(skillsDir, packageName, skillNameHint) {
322
343
  const resolvedHint = resolveSkillNameHintPath(skillsDir, hint);
323
344
  if (!resolvedHint) continue;
324
345
  const { childDir, skillFile } = resolvedHint;
325
- if (!existsSync(skillFile)) continue;
326
- const skill = readSkillEntry(skillsDir, childDir, skillFile);
346
+ if (!readFs.existsSync(skillFile)) continue;
347
+ const skill = readSkillEntry(skillsDir, childDir, skillFile, readFs);
327
348
  if (skill.name !== hint || seen.has(skill.name)) continue;
328
349
  seen.add(skill.name);
329
350
  skills.push(skill);
@@ -331,10 +352,11 @@ function discoverSkillByNameHint(skillsDir, packageName, skillNameHint) {
331
352
  return skills;
332
353
  }
333
354
  function discoverSkills(skillsDir, fsCache) {
355
+ const readFs = fsCache.getReadFs();
334
356
  return fsCache.findSkillFiles(skillsDir).flatMap((skillFile) => {
335
357
  const childDir = dirname(skillFile);
336
358
  if (childDir === skillsDir) return [];
337
- return [readSkillEntry(skillsDir, childDir, skillFile)];
359
+ return [readSkillEntry(skillsDir, childDir, skillFile, readFs)];
338
360
  });
339
361
  }
340
362
  function getPackageShortName(packageName) {
@@ -445,7 +467,11 @@ function scanForIntents(root, options = {}) {
445
467
  let pnpApi;
446
468
  function getPnpApi() {
447
469
  if (scanScope === "global") return null;
448
- if (pnpApi === void 0) pnpApi = loadPnpApi(projectRoot);
470
+ if (pnpApi === void 0) {
471
+ const loaded = loadPnpApi(projectRoot);
472
+ pnpApi = loaded?.api ?? null;
473
+ if (loaded) fsCache.useFs(loaded.readFs);
474
+ }
449
475
  return pnpApi;
450
476
  }
451
477
  function getStats() {
@@ -480,6 +506,7 @@ function scanForIntents(root, options = {}) {
480
506
  discoverSkills: (skillsDir) => discoverSkills(skillsDir, fsCache),
481
507
  getPackageDepth,
482
508
  getFsIdentity: fsCache.getFsIdentity,
509
+ exists: fsCache.exists,
483
510
  packageIndexes,
484
511
  packages,
485
512
  projectRoot,
@@ -593,9 +620,10 @@ function scanIntentPackageAtRoot(packageRoot, options = {}) {
593
620
  const { tryRegister } = createPackageRegistrar({
594
621
  comparePackageVersions,
595
622
  deriveIntentConfig,
596
- discoverSkills: options.skillNameHint ? (skillsDir, packageName) => discoverSkillByNameHint(skillsDir, packageName, options.skillNameHint) : (skillsDir) => discoverSkills(skillsDir, fsCache),
623
+ discoverSkills: options.skillNameHint ? (skillsDir, packageName) => discoverSkillByNameHint(skillsDir, packageName, options.skillNameHint, fsCache.getReadFs()) : (skillsDir) => discoverSkills(skillsDir, fsCache),
597
624
  getPackageDepth,
598
625
  getFsIdentity: fsCache.getFsIdentity,
626
+ exists: fsCache.exists,
599
627
  packageIndexes,
600
628
  packages,
601
629
  projectRoot,
@@ -0,0 +1,6 @@
1
+ import "./utils-9fhWAVua.mjs";
2
+ import "./skill-paths-B-j0dWDA.mjs";
3
+ import { n as scanIntentPackageAtRoot, t as scanForIntents } from "./scanner-D3tAqvbj.mjs";
4
+ import "./workspace-patterns-BffPlZ1D.mjs";
5
+
6
+ export { scanForIntents };
@@ -1,5 +1,5 @@
1
- import { a as readWorkspacePatterns, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-C5O4Dfpl.mjs";
2
- import { t as resolveProjectContext } from "./project-context-D4mFnCs7.mjs";
1
+ import { a as readWorkspacePatterns, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-BffPlZ1D.mjs";
2
+ import { t as resolveProjectContext } from "./project-context-BRIMzhi4.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-DL7qX_F-.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-Chn-30vI.mjs";
2
- import { a as readWorkspacePatterns, o as resolveWorkspacePackages, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-C5O4Dfpl.mjs";
3
- import "./project-context-D4mFnCs7.mjs";
4
- import { n as runEditPackageJsonAll, r as runSetupGithubActions, t as runEditPackageJson } from "./setup-J4A9UfBB.mjs";
1
+ import "./utils-9fhWAVua.mjs";
2
+ import { a as readWorkspacePatterns, o as resolveWorkspacePackages, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-BffPlZ1D.mjs";
3
+ import "./project-context-BRIMzhi4.mjs";
4
+ import { n as runEditPackageJsonAll, r as runSetupGithubActions, t as runEditPackageJson } from "./setup-BklJkH_6.mjs";
5
5
 
6
6
  export { findPackagesWithSkills, findWorkspaceRoot, readWorkspacePatterns, resolveWorkspacePackages, runEditPackageJson, runEditPackageJsonAll, runSetupGithubActions };
@@ -1,4 +1,4 @@
1
- import { l as toPosixPath } from "./utils-Chn-30vI.mjs";
1
+ import { u as toPosixPath } from "./utils-9fhWAVua.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-DcFipeG0.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,5 +1,5 @@
1
- import { l as toPosixPath, r as findSkillFiles, s as parseFrontmatter } from "./utils-Chn-30vI.mjs";
2
- import { t as readIntentArtifacts } from "./artifact-coverage-Cqphhpfo.mjs";
1
+ import { c as parseFrontmatter, r as findSkillFiles, u as toPosixPath } from "./utils-9fhWAVua.mjs";
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";
5
5
  import semver from "semver";
@@ -0,0 +1,5 @@
1
+ import "./utils-9fhWAVua.mjs";
2
+ import "./artifact-coverage-DgWuVqUp.mjs";
3
+ import { n as checkStaleness, r as readPackageName, t as buildWorkspaceCoverageSignals } from "./staleness-BGFfic-Y.mjs";
4
+
5
+ export { buildWorkspaceCoverageSignals, checkStaleness, readPackageName };
@@ -1,25 +1,36 @@
1
1
  import { createRequire } from "node:module";
2
- import { existsSync, lstatSync, readFileSync, readdirSync, realpathSync } from "node:fs";
2
+ import { closeSync, existsSync, lstatSync, openSync, readFileSync, readSync, readdirSync, realpathSync } from "node:fs";
3
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
 
7
7
  //#region src/utils.ts
8
+ const nodeReadFs = {
9
+ existsSync,
10
+ lstatSync,
11
+ readFileSync,
12
+ readdirSync,
13
+ realpathSync,
14
+ openSync,
15
+ readSync,
16
+ closeSync
17
+ };
8
18
  /**
9
19
  * Convert a path to use forward slashes (for cross-platform consistency).
10
20
  */
11
21
  function toPosixPath(p) {
12
22
  return p.split(sep).join("/");
13
23
  }
14
- function createFsIdentityCache() {
24
+ function createFsIdentityCache(getFs = () => nodeReadFs) {
15
25
  const cache = /* @__PURE__ */ new Map();
16
26
  return (path) => {
17
27
  const resolved = resolve(path);
18
28
  const cached = cache.get(resolved);
19
29
  if (cached) return cached;
30
+ const fs = getFs();
20
31
  let identity;
21
32
  try {
22
- identity = lstatSync(resolved).isSymbolicLink() ? realpathSync(resolved) : resolved;
33
+ identity = fs.lstatSync(resolved).isSymbolicLink() ? fs.realpathSync(resolved) : resolved;
23
34
  } catch {
24
35
  identity = resolved;
25
36
  }
@@ -30,24 +41,26 @@ function createFsIdentityCache() {
30
41
  /**
31
42
  * Recursively find all SKILL.md files under a directory.
32
43
  */
33
- function findSkillFiles(dir) {
44
+ function findSkillFiles(dir, fs = nodeReadFs) {
34
45
  const files = [];
35
- if (!existsSync(dir)) return files;
46
+ collectSkillFiles(dir, fs, files);
47
+ return files;
48
+ }
49
+ function collectSkillFiles(dir, fs, files) {
36
50
  let entries;
37
51
  try {
38
- entries = readdirSync(dir, {
52
+ entries = fs.readdirSync(dir, {
39
53
  withFileTypes: true,
40
54
  encoding: "utf8"
41
55
  });
42
56
  } catch {
43
- return files;
57
+ return;
44
58
  }
45
59
  for (const entry of entries) {
46
60
  const fullPath = join(dir, entry.name);
47
- if (entry.isDirectory()) files.push(...findSkillFiles(fullPath));
61
+ if (entry.isDirectory()) collectSkillFiles(fullPath, fs, files);
48
62
  else if (entry.name === "SKILL.md") files.push(fullPath);
49
63
  }
50
- return files;
51
64
  }
52
65
  /**
53
66
  * Read dependencies and peerDependencies (and optionally devDependencies) from
@@ -67,7 +80,6 @@ function getDeps(pkgJson, includeDevDeps = false) {
67
80
  return [...deps];
68
81
  }
69
82
  function listNodeModulesPackageDirs(nodeModulesDir) {
70
- if (!existsSync(nodeModulesDir)) return [];
71
83
  let topEntries;
72
84
  try {
73
85
  topEntries = readdirSync(nodeModulesDir, {
@@ -184,41 +196,87 @@ function detectGlobalNodeModules(packageManager) {
184
196
  * (handles pnpm symlinks), then falls back to walking up node_modules
185
197
  * directories (handles packages with export maps that block ./package.json).
186
198
  */
199
+ /**
200
+ * `createRequire` builds a full module-resolution context; constructing it is
201
+ * non-trivial and `resolveDepDir` is called once per dependency, often many
202
+ * times from the same `parentDir` (every sibling dep of one package). Cache the
203
+ * require function by its base `package.json` path. `req.resolve` still hits the
204
+ * live filesystem on each call, so cached entries never go stale.
205
+ */
206
+ const requireForBaseCache = /* @__PURE__ */ new Map();
207
+ function getRequireForBase(basePackageJson) {
208
+ let req = requireForBaseCache.get(basePackageJson);
209
+ if (!req) {
210
+ req = createRequire(basePackageJson);
211
+ requireForBaseCache.set(basePackageJson, req);
212
+ }
213
+ return req;
214
+ }
187
215
  function resolveDepDir(depName, parentDir) {
188
216
  try {
189
- return dirname(createRequire(join(parentDir, "package.json")).resolve(join(depName, "package.json")));
217
+ return dirname(getRequireForBase(join(parentDir, "package.json")).resolve(join(depName, "package.json")));
190
218
  } catch (err) {
191
219
  const code = err && typeof err === "object" && "code" in err ? err.code : void 0;
192
220
  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)}`);
193
221
  }
194
222
  let dir = parentDir;
195
- while (true) {
223
+ let prev;
224
+ while (dir !== prev) {
196
225
  const candidate = join(dir, "node_modules", depName);
197
226
  if (existsSync(join(candidate, "package.json"))) return candidate;
198
- const parent = dirname(dir);
199
- if (parent === dir) break;
200
- dir = parent;
227
+ prev = dir;
228
+ dir = dirname(dir);
201
229
  }
202
230
  return null;
203
231
  }
204
232
  /**
205
233
  * Parse YAML frontmatter from a file. Returns null if no frontmatter or on error.
206
234
  */
207
- function parseFrontmatter(filePath) {
208
- let content;
235
+ function parseFrontmatter(filePath, fs = nodeReadFs) {
236
+ const content = readFrontmatterRegion(filePath, fs);
237
+ if (content === null) return null;
238
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
239
+ if (!match?.[1]) return null;
209
240
  try {
210
- content = readFileSync(filePath, "utf8");
241
+ return parse(match[1]);
211
242
  } catch {
212
243
  return null;
213
244
  }
214
- const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
215
- if (!match?.[1]) return null;
245
+ }
246
+ /** Max bytes read when probing a file's leading frontmatter region. */
247
+ const FRONTMATTER_READ_LIMIT = 16 * 1024;
248
+ /** Reused across calls; safe because reads are synchronous and single-threaded. */
249
+ const frontmatterBuffer = Buffer.allocUnsafe(FRONTMATTER_READ_LIMIT);
250
+ /**
251
+ * Read just the leading region of a file, enough to cover its frontmatter,
252
+ * instead of its whole body. Falls back to a full read when the bounded read
253
+ * primitives are unavailable or the frontmatter exceeds the probe limit.
254
+ */
255
+ function readFrontmatterRegion(filePath, fs) {
256
+ if (fs.openSync && fs.readSync && fs.closeSync) {
257
+ let region = null;
258
+ let truncated = false;
259
+ let fd;
260
+ try {
261
+ fd = fs.openSync(filePath, "r");
262
+ } catch {
263
+ return null;
264
+ }
265
+ try {
266
+ const bytesRead = fs.readSync(fd, frontmatterBuffer, 0, FRONTMATTER_READ_LIMIT, 0);
267
+ region = frontmatterBuffer.toString("utf8", 0, bytesRead);
268
+ truncated = bytesRead === FRONTMATTER_READ_LIMIT && !/\r?\n---/.test(region.slice(3));
269
+ } finally {
270
+ fs.closeSync(fd);
271
+ }
272
+ if (!truncated) return region;
273
+ }
216
274
  try {
217
- return parse(match[1]);
275
+ return fs.readFileSync(filePath, "utf8");
218
276
  } catch {
219
277
  return null;
220
278
  }
221
279
  }
222
280
 
223
281
  //#endregion
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 };
282
+ export { listNestedNodeModulesPackageDirs as a, parseFrontmatter as c, getDeps as i, resolveDepDir as l, detectGlobalNodeModules as n, listNodeModulesPackageDirs as o, findSkillFiles as r, nodeReadFs as s, createFsIdentityCache as t, toPosixPath as u };
@@ -0,0 +1,3 @@
1
+ import { a as listNestedNodeModulesPackageDirs, c as parseFrontmatter, i as getDeps, l as resolveDepDir, n as detectGlobalNodeModules, o as listNodeModulesPackageDirs, r as findSkillFiles, s as nodeReadFs, t as createFsIdentityCache, u as toPosixPath } from "./utils-9fhWAVua.mjs";
2
+
3
+ export { createFsIdentityCache, detectGlobalNodeModules, findSkillFiles, getDeps, listNestedNodeModulesPackageDirs, listNodeModulesPackageDirs, nodeReadFs, parseFrontmatter, resolveDepDir, toPosixPath };
@@ -1,8 +1,8 @@
1
- import "./utils-Chn-30vI.mjs";
2
- import { n as findWorkspacePackages } from "./workspace-patterns-C5O4Dfpl.mjs";
3
- import { t as resolveProjectContext } from "./project-context-D4mFnCs7.mjs";
4
- import { n as isCliFailure, t as fail } from "./cli-error-DOO5bLIG.mjs";
5
- import { l as printWarnings } from "./cli-support-BHoEb9y1.mjs";
1
+ import "./utils-9fhWAVua.mjs";
2
+ import { n as findWorkspacePackages } from "./workspace-patterns-BffPlZ1D.mjs";
3
+ import { t as resolveProjectContext } from "./project-context-BRIMzhi4.mjs";
4
+ import { n as isCliFailure, t as fail } from "./cli-error-BrMXlbtx.mjs";
5
+ import { l as printWarnings } from "./cli-support-DzDBzS3-.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-Ctlz_JG-.mjs")]);
118
+ const [{ parse: parseYaml }, { findSkillFiles }] = await Promise.all([import("yaml"), import("./utils-CSPzvaFu.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--Gc_yplP.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 { r as findSkillFiles } from "./utils-Chn-30vI.mjs";
1
+ import { r as findSkillFiles } from "./utils-9fhWAVua.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 ?? [];
@@ -1,4 +1,4 @@
1
- import "./utils-Chn-30vI.mjs";
2
- import { a as readWorkspacePatterns, i as getWorkspaceInfo, n as findWorkspacePackages, o as resolveWorkspacePackages, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-C5O4Dfpl.mjs";
1
+ import "./utils-9fhWAVua.mjs";
2
+ import { a as readWorkspacePatterns, i as getWorkspaceInfo, n as findWorkspacePackages, o as resolveWorkspacePackages, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-BffPlZ1D.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.41",
3
+ "version": "0.0.43",
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,3 +0,0 @@
1
- import { t as readIntentArtifacts } from "./artifact-coverage-Cqphhpfo.mjs";
2
-
3
- export { readIntentArtifacts };
@@ -1,5 +0,0 @@
1
- import "./utils-Chn-30vI.mjs";
2
- import "./skill-paths-4kQXfQXo.mjs";
3
- import { n as printSkillTree, r as printTable, t as computeSkillNameWidth } from "./display-BPM-AJGc.mjs";
4
-
5
- export { computeSkillNameWidth, printSkillTree, printTable };
@@ -1,7 +0,0 @@
1
- import "./utils-Chn-30vI.mjs";
2
- import "./workspace-patterns-C5O4Dfpl.mjs";
3
- import "./project-context-D4mFnCs7.mjs";
4
- import "./cli-support-BHoEb9y1.mjs";
5
- import { n as runInstallCommand, t as INSTALL_PROMPT } from "./install-DCiBBx55.mjs";
6
-
7
- export { INSTALL_PROMPT, runInstallCommand };
@@ -1 +0,0 @@
1
- export { };