@nanonets/graft 0.8.2 → 0.9.0

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 (120) hide show
  1. package/README.md +74 -32
  2. package/dist/ai/llm/openai.d.ts +11 -0
  3. package/dist/ai/llm/openai.d.ts.map +1 -1
  4. package/dist/ai/llm/openai.js +33 -1
  5. package/dist/ai/llm/openai.js.map +1 -1
  6. package/dist/ask/ask.d.ts.map +1 -1
  7. package/dist/ask/ask.js +22 -15
  8. package/dist/ask/ask.js.map +1 -1
  9. package/dist/ask/fuse.d.ts +4 -0
  10. package/dist/ask/fuse.d.ts.map +1 -1
  11. package/dist/ask/fuse.js +2 -1
  12. package/dist/ask/fuse.js.map +1 -1
  13. package/dist/ask/index-file.d.ts +1 -0
  14. package/dist/ask/index-file.d.ts.map +1 -1
  15. package/dist/ask/index-file.js +1 -1
  16. package/dist/ask/index-file.js.map +1 -1
  17. package/dist/cli-meta.d.ts +6 -1
  18. package/dist/cli-meta.d.ts.map +1 -1
  19. package/dist/cli-meta.js +8 -2
  20. package/dist/cli-meta.js.map +1 -1
  21. package/dist/cli-picker.d.ts.map +1 -1
  22. package/dist/cli-picker.js +3 -1
  23. package/dist/cli-picker.js.map +1 -1
  24. package/dist/cli.js +30 -2
  25. package/dist/cli.js.map +1 -1
  26. package/dist/context/build.d.ts.map +1 -1
  27. package/dist/context/build.js +13 -4
  28. package/dist/context/build.js.map +1 -1
  29. package/dist/context/check.d.ts.map +1 -1
  30. package/dist/context/check.js +14 -5
  31. package/dist/context/check.js.map +1 -1
  32. package/dist/context/node-file.d.ts.map +1 -1
  33. package/dist/context/node-file.js +4 -18
  34. package/dist/context/node-file.js.map +1 -1
  35. package/dist/graph/build.d.ts +3 -0
  36. package/dist/graph/build.d.ts.map +1 -1
  37. package/dist/graph/build.js +41 -12
  38. package/dist/graph/build.js.map +1 -1
  39. package/dist/graph/cards.d.ts.map +1 -1
  40. package/dist/graph/cards.js +3 -2
  41. package/dist/graph/cards.js.map +1 -1
  42. package/dist/graph/check.d.ts.map +1 -1
  43. package/dist/graph/check.js +7 -4
  44. package/dist/graph/check.js.map +1 -1
  45. package/dist/graph/extract-cache.d.ts +1 -0
  46. package/dist/graph/extract-cache.d.ts.map +1 -1
  47. package/dist/graph/extract-cache.js +1 -1
  48. package/dist/graph/extract-cache.js.map +1 -1
  49. package/dist/graph/extract.d.ts +17 -0
  50. package/dist/graph/extract.d.ts.map +1 -1
  51. package/dist/graph/extract.js +188 -17
  52. package/dist/graph/extract.js.map +1 -1
  53. package/dist/graph/fingerprint.d.ts +1 -0
  54. package/dist/graph/fingerprint.d.ts.map +1 -1
  55. package/dist/graph/fingerprint.js +15 -6
  56. package/dist/graph/fingerprint.js.map +1 -1
  57. package/dist/graph/map.d.ts.map +1 -1
  58. package/dist/graph/map.js +6 -4
  59. package/dist/graph/map.js.map +1 -1
  60. package/dist/graph/refresh.d.ts.map +1 -1
  61. package/dist/graph/refresh.js +61 -13
  62. package/dist/graph/refresh.js.map +1 -1
  63. package/dist/graph/resolve.d.ts.map +1 -1
  64. package/dist/graph/resolve.js +36 -43
  65. package/dist/graph/resolve.js.map +1 -1
  66. package/dist/graph/scopes.d.ts +14 -2
  67. package/dist/graph/scopes.d.ts.map +1 -1
  68. package/dist/graph/scopes.js +51 -81
  69. package/dist/graph/scopes.js.map +1 -1
  70. package/dist/graph/seed.d.ts +38 -0
  71. package/dist/graph/seed.d.ts.map +1 -0
  72. package/dist/graph/seed.js +226 -0
  73. package/dist/graph/seed.js.map +1 -0
  74. package/dist/graph/source-files.d.ts +13 -5
  75. package/dist/graph/source-files.d.ts.map +1 -1
  76. package/dist/graph/source-files.js +16 -7
  77. package/dist/graph/source-files.js.map +1 -1
  78. package/dist/graph/traverse-cli.d.ts +8 -2
  79. package/dist/graph/traverse-cli.d.ts.map +1 -1
  80. package/dist/graph/traverse-cli.js +26 -6
  81. package/dist/graph/traverse-cli.js.map +1 -1
  82. package/dist/graph/traverse.d.ts +3 -1
  83. package/dist/graph/traverse.d.ts.map +1 -1
  84. package/dist/graph/traverse.js +22 -3
  85. package/dist/graph/traverse.js.map +1 -1
  86. package/dist/graph/types.d.ts +1 -0
  87. package/dist/graph/types.d.ts.map +1 -1
  88. package/dist/graph/workspace-cli.d.ts +5 -0
  89. package/dist/graph/workspace-cli.d.ts.map +1 -1
  90. package/dist/graph/workspace-cli.js +7 -0
  91. package/dist/graph/workspace-cli.js.map +1 -1
  92. package/dist/graph/workspace.js +1 -1
  93. package/dist/graph/workspace.js.map +1 -1
  94. package/dist/ingest/fs.d.ts +30 -2
  95. package/dist/ingest/fs.d.ts.map +1 -1
  96. package/dist/ingest/fs.js +84 -8
  97. package/dist/ingest/fs.js.map +1 -1
  98. package/dist/mcp/tools.js +3 -3
  99. package/dist/mcp/tools.js.map +1 -1
  100. package/dist/search/grep-cli.d.ts.map +1 -1
  101. package/dist/search/grep-cli.js +4 -1
  102. package/dist/search/grep-cli.js.map +1 -1
  103. package/dist/search/grep.d.ts +2 -1
  104. package/dist/search/grep.d.ts.map +1 -1
  105. package/dist/search/grep.js +16 -3
  106. package/dist/search/grep.js.map +1 -1
  107. package/dist/util/paths.d.ts +29 -0
  108. package/dist/util/paths.d.ts.map +1 -0
  109. package/dist/util/paths.js +71 -0
  110. package/dist/util/paths.js.map +1 -0
  111. package/dist/util/source.d.ts +4 -0
  112. package/dist/util/source.d.ts.map +1 -0
  113. package/dist/util/source.js +12 -0
  114. package/dist/util/source.js.map +1 -0
  115. package/dist/util/state.d.ts +25 -0
  116. package/dist/util/state.d.ts.map +1 -1
  117. package/dist/util/state.js +41 -0
  118. package/dist/util/state.js.map +1 -1
  119. package/package.json +2 -2
  120. package/scripts/run-tests.mjs +43 -0
@@ -25,6 +25,11 @@
25
25
  * at the end of a turn — so retrieval stays cheap and a read stays a read. It
26
26
  * also leaves `stats.json` alone, so that same `Stop` hook still sees `dirty` and
27
27
  * still rebuilds the passive surface.
28
+ *
29
+ * One case is not drift but absence: inside a git worktree there is no graph at all,
30
+ * because `graft/` is gitignored and so was never checked out. The gate covers that
31
+ * too — it copies the parent checkout's graph in (`./seed.ts`) and then treats the
32
+ * difference between the two checkouts as ordinary drift, which is exactly what it is.
28
33
  */
29
34
  import { existsSync } from "node:fs";
30
35
  import { join, resolve } from "node:path";
@@ -34,6 +39,7 @@ import { CACHE_DIR } from "../context/node-file.js";
34
39
  import { buildGraph } from "./build.js";
35
40
  import { driftCount, isClean, probeDrift } from "./fingerprint.js";
36
41
  import { invalidateGraphCaches } from "./load.js";
42
+ import { seedGraph } from "./seed.js";
37
43
  import { wiringPath } from "./write.js";
38
44
  /** How long to wait for another process's in-flight rebuild before giving up and
39
45
  * answering from the current graph. Long enough to ride out a small repo's build,
@@ -90,6 +96,30 @@ async function waitForLock(cache) {
90
96
  await sleep(LOCK_POLL_MS);
91
97
  }
92
98
  }
99
+ /**
100
+ * Copy a parent checkout's graph in, holding the same lock a rebuild would.
101
+ *
102
+ * Two MCP tool calls in a fresh worktree arrive here at the same moment, and an 8 MB
103
+ * copy is long enough for both to start one. The loser waits, then finds the graph
104
+ * already there and reports nothing — which is why the caller re-checks the file
105
+ * rather than trusting this return value.
106
+ */
107
+ async function seedUnderLock(dir, outDir, contextDir) {
108
+ const lockCache = join(outDir, CACHE_DIR);
109
+ // `busy` matters: with no graph on disk there is nothing to fall back to, so a
110
+ // caller that stayed silent here would emit the bare "no matching nodes" this whole
111
+ // mechanism exists to remove. Say what happened instead.
112
+ if (!(await waitForLock(lockCache)))
113
+ return { seeded: false, busy: true };
114
+ const unhook = releaseOnSignal(lockCache);
115
+ try {
116
+ return seedGraph(dir, { contextDir });
117
+ }
118
+ finally {
119
+ unhook();
120
+ releaseLockIn(lockCache);
121
+ }
122
+ }
93
123
  /**
94
124
  * Rebuild `root`'s structural graph if the working tree has moved since the last
95
125
  * build. Cheap and side-effect-free when nothing changed, which is the usual case.
@@ -103,26 +133,42 @@ export async function ensureFreshGraph(root, opts = {}) {
103
133
  try {
104
134
  const dir = resolve(root);
105
135
  const outDir = contextDirFor(dir, opts.contextDir);
106
- // Nothing built yet: the caller's own "no graph — run graft build" message is
107
- // the right answer. Auto-building a whole repo under a query is a surprise,
108
- // and it's the one case where the user hasn't opted into graft at all yet.
109
- if (!existsSync(wiringPath(outDir)))
110
- return CLEAN;
136
+ let seededFrom;
137
+ if (!existsSync(wiringPath(outDir))) {
138
+ // One case has a graph to work with even though this checkout has none: a git
139
+ // worktree, whose parent checkout's `graft/` git could not check out. Copy it
140
+ // in and carry on — the drift below is then exactly the diff between the two
141
+ // checkouts, and repairing it is what makes the copied graph honest here.
142
+ const seed = await seedUnderLock(dir, outDir, opts.contextDir);
143
+ seededFrom = seed.from;
144
+ // Still nothing (not a worktree, parent never built, or a concurrent seed we
145
+ // lost the race for and which we now re-check for): the caller's own "no graph
146
+ // — run graft build" message is the right answer. Auto-building a whole repo
147
+ // under a query is a surprise, and it's the one case where the user hasn't
148
+ // opted into graft at all yet.
149
+ if (!existsSync(wiringPath(outDir))) {
150
+ return seed.busy
151
+ ? { refreshed: false, note: "another process is still copying the graph into this worktree — retry the query in a moment" }
152
+ : CLEAN;
153
+ }
154
+ }
155
+ const seedNote = seededFrom ? `copied the graph from the main checkout (${seededFrom})` : undefined;
111
156
  // null = no fingerprint at all: a graph built before this mechanism existed,
112
157
  // or by a different extractor build. Rebuild once — that lays the fingerprint
113
158
  // down, so it costs exactly one build, not one per query.
114
159
  const drift = probeDrift(dir, outDir);
115
160
  if (drift && isClean(drift))
116
- return CLEAN;
161
+ return seedNote ? { refreshed: false, note: seedNote } : CLEAN;
117
162
  // On the default layout this is `<root>/graft/.cache/.sync.lock`, the very file
118
163
  // the Claude Code hooks lock — so this refresh and the background sync can
119
164
  // never rebuild at the same time.
120
165
  const lockCache = join(outDir, CACHE_DIR);
121
166
  if (!(await waitForLock(lockCache))) {
167
+ const busy = "a graph rebuild is already in flight — answering from the current graph";
122
168
  return {
123
169
  refreshed: false,
124
170
  drift: drift ?? undefined,
125
- note: "a graph rebuild is already in flight — answering from the current graph",
171
+ note: seedNote ? `${seedNote}; ${busy}` : busy,
126
172
  };
127
173
  }
128
174
  const unhook = releaseOnSignal(lockCache);
@@ -136,7 +182,7 @@ export async function ensureFreshGraph(root, opts = {}) {
136
182
  const now = drift ? probeDrift(dir, outDir) : null;
137
183
  if (now && isClean(now)) {
138
184
  invalidateGraphCaches(outDir);
139
- return CLEAN;
185
+ return seedNote ? { refreshed: false, note: seedNote } : CLEAN;
140
186
  }
141
187
  // Tier-1 only: no summarizer, so no LLM call and no network, ever. And
142
188
  // `graphOnly`: write the graph, the ask sidecar and the fingerprint, nothing
@@ -145,7 +191,7 @@ export async function ensureFreshGraph(root, opts = {}) {
145
191
  // card's mtime, and skipping them is most of what keeps this cheap.
146
192
  await buildGraph(dir, { contextDir: opts.contextDir, graphOnly: true });
147
193
  invalidateGraphCaches(outDir);
148
- return { refreshed: true, drift: drift ?? undefined };
194
+ return { refreshed: true, drift: drift ?? undefined, note: seedNote };
149
195
  }
150
196
  finally {
151
197
  unhook();
@@ -192,11 +238,13 @@ export async function ensureFreshChildren(root, children, opts = {}) {
192
238
  /** The one-line note a CLI/MCP surface prints when a refresh actually happened.
193
239
  * Null when there's nothing to say (the overwhelmingly common case). */
194
240
  export function refreshNote(r) {
195
- if (r.note)
196
- return `[graft] ${r.note}`;
197
241
  if (!r.refreshed)
198
- return null;
242
+ return r.note ? `[graft] ${r.note}` : null;
199
243
  const n = r.drift ? driftCount(r.drift) : 0;
200
- return `[graft] refreshed the graph (${n || "?"} file${n === 1 ? "" : "s"} changed) before answering`;
244
+ const built = `refreshed the graph (${n || "?"} file${n === 1 ? "" : "s"} changed) before answering`;
245
+ // Both facts, when a worktree was seeded *and* the copy needed repairing: the
246
+ // count is the interesting half (it's the branch diff), the provenance explains
247
+ // where a graph came from in a directory the user knows they never built.
248
+ return r.note ? `[graft] ${built} — ${r.note}` : `[graft] ${built}`;
201
249
  }
202
250
  //# sourceMappingURL=refresh.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../src/graph/refresh.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../src/graph/refresh.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/graph/resolve.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,MAAM,EAAQ,MAAM,EAAY,MAAM,YAAY,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAoB5C;;sDAEsD;AACtD,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,cAAc;IAC7B;;6FAEyF;IACzF,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;CACxB;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EAAE,EACf,QAAQ,EAAE,OAAO,EAAE,EACnB,IAAI,GAAE,cAAmB,GACxB,MAAM,EAAE,CAqFV"}
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/graph/resolve.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,MAAM,EAAQ,MAAM,EAAY,MAAM,YAAY,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAI5C;;sDAEsD;AACtD,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,cAAc;IAC7B;;6FAEyF;IACzF,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;CACxB;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EAAE,EACf,QAAQ,EAAE,OAAO,EAAE,EACnB,IAAI,GAAE,cAAmB,GACxB,MAAM,EAAE,CAuFV"}
@@ -5,29 +5,16 @@
5
5
  * Confidence mirrors the SCIP/Graphify model:
6
6
  * - `extracted`: the target is certain — a match within the same file, an
7
7
  * import specifier, or a structural containment.
8
- * - `inferred`: the target was resolved by a unique name match across files,
9
- * which name-shadowing could in principle fool.
8
+ * - `inferred`: a bare function target was resolved by a unique name match
9
+ * across files, which name-shadowing could in principle fool.
10
10
  * Ambiguous cross-file matches (a name defined in several files) are dropped
11
- * rather than guessed, so we never wire an edge to the wrong symbol.
11
+ * rather than guessed. Member calls are stricter: they require a receiver type
12
+ * and owner-qualified method match because a unique bare method name says
13
+ * nothing about the receiver.
12
14
  */
13
15
  import { posix } from "node:path";
14
- import { sep } from "node:path";
16
+ import { toPosixPath } from "../util/paths.js";
15
17
  const IMPORT_EXTS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs", ".py"];
16
- // Builtin container/value types whose methods are never user-defined symbols in the
17
- // repo. A typed member call on one of these receivers (`deg.set(...)` where
18
- // `recvType` is `Map`) must never fall back to the untyped unique-bare-name path —
19
- // doing so wires it to whatever repo symbol happens to share the method's name
20
- // (e.g. a class's own `.set` method), which is always wrong. RawEdge carries no
21
- // language tag, so this is the union of the TS/TSX and Python builtin lists rather
22
- // than a per-language check; a repo class legitimately named e.g. `dict` colliding
23
- // with the Python builtin is vanishingly rare, and the failure mode in that case is
24
- // just a dropped edge (safe), not a wrong one.
25
- const BUILTIN_CONTAINER_TYPES = new Set([
26
- // TS/TSX
27
- "Map", "Set", "WeakMap", "WeakSet", "Array", "Promise", "Object", "Date", "RegExp", "Error",
28
- // Python
29
- "dict", "list", "set", "tuple", "str", "frozenset", "bytes",
30
- ]);
31
18
  export function resolveEdges(nodes, rawEdges, opts = {}) {
32
19
  const byId = new Map(nodes.map((n) => [n.id, n]));
33
20
  const globalName = new Map();
@@ -41,7 +28,7 @@ export function resolveEdges(nodes, rawEdges, opts = {}) {
41
28
  for (const n of nodes) {
42
29
  if (n.kind === "file") {
43
30
  if (hasGoModules && n.path.endsWith(".go")) {
44
- const dir = posix.dirname(n.path.split(sep).join("/"));
31
+ const dir = posix.dirname(toPosixPath(n.path));
45
32
  push(goFilesByDir, dir, n.id);
46
33
  }
47
34
  continue;
@@ -51,11 +38,8 @@ export function resolveEdges(nodes, rawEdges, opts = {}) {
51
38
  if (!fileMap)
52
39
  perFileName.set(n.path, (fileMap = new Map()));
53
40
  push(fileMap, n.name, n);
54
- if (n.kind === "method") {
55
- const post = n.id.slice(n.id.indexOf("#") + 1);
56
- const segs = post.split(".");
57
- if (segs.length >= 2)
58
- push(ownerMethod, `${segs[segs.length - 2]}.${segs[segs.length - 1]}`, n);
41
+ if (n.kind === "method" && n.owner) {
42
+ push(ownerMethod, `${n.owner}.${n.name}`, n);
59
43
  }
60
44
  }
61
45
  // classParents: class/interface name → its declared base-class names, from raw
@@ -65,8 +49,12 @@ export function resolveEdges(nodes, rawEdges, opts = {}) {
65
49
  for (const e of rawEdges) {
66
50
  if (e.relation !== "extends" || !e.name)
67
51
  continue;
68
- const post = e.source.slice(e.source.indexOf("#") + 1);
69
- const ownName = post.split(".").pop();
52
+ // The declaring class's own bare name — read from its node (keyed by n.name, set
53
+ // once at mint time) rather than re-derived by slicing e.source, which breaks once
54
+ // ids can carry a dedup ordinal (A3's `Cache~2`).
55
+ const ownName = byId.get(e.source)?.name;
56
+ if (!ownName)
57
+ continue;
70
58
  push(classParents, ownName, e.name);
71
59
  }
72
60
  const out = [];
@@ -94,27 +82,31 @@ export function resolveEdges(nodes, rawEdges, opts = {}) {
94
82
  // an unresolved base is usually an external/imported type — keep the name.
95
83
  add(e.source, hit?.id ?? e.name, e.relation, hit?.confidence ?? "inferred");
96
84
  }
85
+ else if (e.relation === "references" && e.name && e.specifier) {
86
+ // A named import gives both halves needed for sound resolution: the module
87
+ // it came from and the exported name. Resolve inside that file only, so a
88
+ // same-named symbol elsewhere in the repo cannot become a false edge.
89
+ const targetFile = resolveImport(e.specifier, e.file, byId);
90
+ if (!byId.has(targetFile))
91
+ continue; // external or unresolved module
92
+ const candidates = perFileName.get(targetFile)?.get(e.name) ?? [];
93
+ if (candidates.length === 1)
94
+ add(e.source, candidates[0].id, "references", "extracted");
95
+ }
97
96
  else if (e.relation === "calls") {
98
- if (e.viaMember && e.recvType) {
97
+ if (e.viaMember) {
98
+ if (!e.recvType)
99
+ continue;
99
100
  const hit = resolveTypedMember(e.recvType, e.name, e.file, ownerMethod, classParents);
100
101
  if (hit === "ambiguous")
101
102
  continue; // drop — never guess past an ambiguous owner
102
103
  if (hit)
103
104
  add(e.source, hit.id, "calls", hit.confidence);
104
- else if (!BUILTIN_CONTAINER_TYPES.has(e.recvType)) {
105
- // chain exhausted with zero candidates at every level → fall back to the
106
- // existing untyped path (unique bare-name match), unchanged.
107
- const fallback = resolveName(e.name, e.file, ["method"], perFileName, globalName);
108
- if (fallback)
109
- add(e.source, fallback.id, "calls", fallback.confidence);
110
- }
111
- // else: recvType is a known builtin container (Map/dict/etc) — its methods
112
- // are never user-defined repo symbols, so drop rather than wire a bare-name
113
- // fallback to an unrelated same-named method.
105
+ // No owner-qualified match means the call is unresolved. A unique bare
106
+ // method name is not evidence that this receiver has that method.
114
107
  continue;
115
108
  }
116
- const kinds = e.viaMember ? ["method"] : ["function"];
117
- const hit = resolveName(e.name, e.file, kinds, perFileName, globalName);
109
+ const hit = resolveName(e.name, e.file, ["function"], perFileName, globalName);
118
110
  if (hit)
119
111
  add(e.source, hit.id, "calls", hit.confidence); // drop unresolved calls (too noisy)
120
112
  }
@@ -152,8 +144,7 @@ function resolveName(name, file, kinds, perFileName, globalName) {
152
144
  * per the inviolable philosophy we drop and stop rather than guess, and we do
153
145
  * NOT continue up the chain past this level.
154
146
  * - `null` — the whole chain (recvType + ancestors, breadth-first, depth ≤ 3,
155
- * cycle-guarded) had zero candidates at every level; caller may fall back to
156
- * the untyped bare-name path.
147
+ * cycle-guarded) had zero candidates at every level.
157
148
  */
158
149
  function resolveTypedMember(recvType, name, file, ownerMethod, classParents) {
159
150
  const MAX_DEPTH = 3;
@@ -193,7 +184,9 @@ function resolveTypedMember(recvType, name, file, ownerMethod, classParents) {
193
184
  function resolveImport(spec, file, byId) {
194
185
  if (!spec.startsWith("."))
195
186
  return spec;
196
- const dir = posix.dirname(file.split(sep).join("/"));
187
+ // Belt-and-braces: `node.path` is posix by construction (`../util/paths.ts`),
188
+ // but this also accepts a hand-written or hand-edited graph.
189
+ const dir = posix.dirname(toPosixPath(file));
197
190
  const base = posix.normalize(posix.join(dir, spec));
198
191
  const noExt = base.replace(/\.(js|jsx|mjs|cjs|ts|tsx|py)$/, "");
199
192
  const candidates = [
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/graph/resolve.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/graph/resolve.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import type { GraphV1, ScopeV1 } from "./types.js";
2
- /** Walk the tree (reusing `walkDir`'s skip rules) and find project-marker dirs. */
3
- export declare function discoverScopes(root: string): ScopeV1[];
2
+ /** Walk the tree (reusing `walkDir`'s skip rules, including the repo's persisted
3
+ * `--include-dir` override) and find project-marker dirs. */
4
+ export declare function discoverScopes(root: string, repoFiles?: string[]): ScopeV1[];
4
5
  /** Nearest-prefix owner. `scopes` MUST be sorted prefix-length desc; "" matches all.
5
6
  * Falls back to a synthetic root scope when `scopes` has no explicit "" entry and
6
7
  * nothing else matches — every path resolves to some scope. */
@@ -20,6 +21,17 @@ export declare function scopesHereClause(scopes: ScopeV1[]): string;
20
21
  * (`""`) matches every path. Used to filter ask's doc/node set for
21
22
  * `--in <path-prefix>`. */
22
23
  export declare function pathUnderPrefix(path: string, prefix: string): boolean;
24
+ /**
25
+ * Validate a normalized `--in` prefix against the graph before a query runs. A
26
+ * prefix matching no indexed node is a caller mistake (typo, wrong sub-project,
27
+ * or a mid-path fragment where a prefix is required) rather than a legitimate
28
+ * zero-hit query, so every `--in`-taking command fails loudly and identically
29
+ * instead of printing empty output the caller has to interpret.
30
+ *
31
+ * Pass the prefix through `normalizePathPrefix` first — an un-normalized
32
+ * `src\gpu` or `src/` will not match anything here.
33
+ */
34
+ export declare function assertPrefixIndexed(graph: GraphV1, prefix: string): void;
23
35
  /** Immediate subdirs of `root` that are themselves git repos (have `.git`).
24
36
  * Used by workspace federation (Task 5). */
25
37
  export declare function discoverWorkspaceChildren(root: string): string[];
@@ -1 +1 @@
1
- {"version":3,"file":"scopes.d.ts","sourceRoot":"","sources":["../../src/graph/scopes.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAkJnD,mFAAmF;AACnF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CAqItD;AAED;;+DAE+D;AAC/D,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAMhE;AAED;;+DAE+D;AAC/D,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;sCAGsC;AACtC,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAG1D;AAED;;;;2BAI2B;AAC3B,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAErE;AAED;4CAC4C;AAC5C,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAiBhE;AAED;;2EAE2E;AAC3E,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,EAAE,CAEvD"}
1
+ {"version":3,"file":"scopes.d.ts","sourceRoot":"","sources":["../../src/graph/scopes.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAsGnD;6DAC6D;AAC7D,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,MAAM,EAAkD,GAClE,OAAO,EAAE,CAqIX;AAED;;+DAE+D;AAC/D,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAMhE;AAED;;+DAE+D;AAC/D,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;sCAGsC;AACtC,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAG1D;AAED;;;;2BAI2B;AAC3B,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAErE;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAKxE;AAED;4CAC4C;AAC5C,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAYhE;AAED;;2EAE2E;AAC3E,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,EAAE,CAEvD"}
@@ -21,37 +21,26 @@
21
21
  * 7. `label` = `prefix` (both "" for root); ordering is prefix-length desc,
22
22
  * then lexicographic.
23
23
  */
24
- import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
24
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
25
25
  import { join, resolve } from "node:path";
26
- import { SKIP_DIRS } from "../ingest/fs.js";
26
+ import { shouldSkipDir, walkDir } from "../ingest/fs.js";
27
+ import { relPosix } from "../util/paths.js";
28
+ import { readIncludeDirs } from "../util/state.js";
27
29
  /** Project-marker files, checked in this order (also the order `markers` is built in). */
28
30
  const MARKERS = ["package.json", "go.mod", "pyproject.toml", "setup.py", "Cargo.toml"];
29
31
  const CANONICAL_ROOT = [{ prefix: "", label: "", markers: [] }];
30
- /** Recursively collect every directory under `root` (posix rel path, "" = root itself),
31
- * reusing `walkDir`'s skip rules (dot-dirs, `SKIP_DIRS`) so build-output and dependency
32
- * trees are never scanned for markers. */
33
- function collectDirs(root) {
34
- const out = [""];
35
- const walk = (absDir, relDir) => {
36
- let entries;
37
- try {
38
- entries = readdirSync(absDir, { withFileTypes: true });
39
- }
40
- catch {
41
- return;
42
- }
43
- for (const entry of entries) {
44
- if (!entry.isDirectory())
45
- continue;
46
- if (entry.name.startsWith(".") || SKIP_DIRS.has(entry.name))
47
- continue;
48
- const rel = relDir === "" ? entry.name : `${relDir}/${entry.name}`;
49
- out.push(rel);
50
- walk(join(absDir, entry.name), rel);
51
- }
52
- };
53
- walk(root, "");
54
- return out;
32
+ /** Collect directories represented by the canonical visible file set. Building
33
+ * this from `walkDir` keeps scope discovery aligned with extraction: an ignored
34
+ * generated tree cannot become a marker or workspace scope. */
35
+ function collectDirs(root, repoFiles) {
36
+ const out = new Set([""]);
37
+ for (const abs of repoFiles) {
38
+ const parts = relPosix(root, abs).split("/");
39
+ parts.pop();
40
+ for (let i = 1; i <= parts.length; i++)
41
+ out.add(parts.slice(0, i).join("/"));
42
+ }
43
+ return [...out];
55
44
  }
56
45
  /** Minimal `packages:` list parser for `pnpm-workspace.yaml` — no YAML dependency,
57
46
  * handles the `packages:\n - 'glob'\n - "glob"` form pnpm actually generates. */
@@ -104,10 +93,9 @@ function readWorkspaceGlobs(root) {
104
93
  }
105
94
  return null;
106
95
  }
107
- /** Resolve one workspace glob to matched dir paths (posix, rel to `root`). Supports
108
- * only `dir/*` (immediate subdirs) and `dir/**` (any nested depth) forms, implemented
109
- * with plain `readdir` — no glob dependency, per spec. Unsupported forms resolve empty. */
110
- function resolveGlob(root, pattern) {
96
+ /** Resolve one workspace glob against visible directories only. Supports
97
+ * `dir/*` (immediate subdirs), `dir/**` (any nested depth), and literal dirs. */
98
+ function resolveGlob(dirs, pattern) {
111
99
  const norm = pattern.replace(/\\/g, "/").replace(/\/$/, "");
112
100
  let base;
113
101
  let recursive;
@@ -128,57 +116,26 @@ function resolveGlob(root, pattern) {
128
116
  recursive = false;
129
117
  }
130
118
  else if (!norm.includes("*")) {
131
- // Literal entry (no glob chars), e.g. `packages: ['apps/*', 'docs']` — a plain
132
- // workspace-list entry that names a real directory counts as a workspace match
133
- // in its own right, same as a resolved glob would. Without this, a literal
134
- // entry silently resolves to nothing while Rule 2 still strips its
135
- // `package.json` marker (it's a JS-family dir that never matched the glob
136
- // set), de-scoping a real workspace package.
137
- try {
138
- return existsSync(join(root, norm)) && statSync(join(root, norm)).isDirectory()
139
- ? [norm]
140
- : [];
141
- }
142
- catch {
143
- return [];
144
- }
119
+ return dirs.includes(norm) ? [norm] : [];
145
120
  }
146
121
  else {
147
122
  return []; // unsupported glob form
148
123
  }
149
- const results = [];
150
- const listDirs = (absDir, relDir) => {
151
- let entries;
152
- try {
153
- entries = readdirSync(absDir, { withFileTypes: true });
154
- }
155
- catch {
156
- return [];
157
- }
158
- return entries
159
- .filter((e) => e.isDirectory() && !e.name.startsWith(".") && !SKIP_DIRS.has(e.name))
160
- .map((e) => (relDir === "" ? e.name : `${relDir}/${e.name}`));
161
- };
162
- const baseAbs = base === "" ? root : join(root, base);
163
- if (!recursive) {
164
- results.push(...listDirs(baseAbs, base));
165
- }
166
- else {
167
- const stack = [base];
168
- while (stack.length) {
169
- const relDir = stack.pop();
170
- const absDir = relDir === "" ? root : join(root, relDir);
171
- const children = listDirs(absDir, relDir);
172
- results.push(...children);
173
- stack.push(...children);
174
- }
175
- }
176
- return results;
124
+ return dirs.filter((dir) => {
125
+ if (dir === "")
126
+ return false;
127
+ if (recursive)
128
+ return base === "" || dir.startsWith(`${base}/`);
129
+ const slash = dir.lastIndexOf("/");
130
+ const parent = slash === -1 ? "" : dir.slice(0, slash);
131
+ return parent === base;
132
+ });
177
133
  }
178
- /** Walk the tree (reusing `walkDir`'s skip rules) and find project-marker dirs. */
179
- export function discoverScopes(root) {
134
+ /** Walk the tree (reusing `walkDir`'s skip rules, including the repo's persisted
135
+ * `--include-dir` override) and find project-marker dirs. */
136
+ export function discoverScopes(root, repoFiles = walkDir(root, readIncludeDirs(resolve(root)))) {
180
137
  const absRoot = resolve(root);
181
- const dirs = collectDirs(absRoot);
138
+ const dirs = collectDirs(absRoot, repoFiles);
182
139
  const markerMap = new Map();
183
140
  for (const dir of dirs) {
184
141
  const found = MARKERS.filter((m) => existsSync(join(absRoot, dir, m)));
@@ -189,7 +146,7 @@ export function discoverScopes(root) {
189
146
  const workspaceMatches = new Set();
190
147
  if (workspaceGlobs) {
191
148
  for (const glob of workspaceGlobs) {
192
- for (const dir of resolveGlob(absRoot, glob))
149
+ for (const dir of resolveGlob(dirs, glob))
193
150
  workspaceMatches.add(dir);
194
151
  }
195
152
  }
@@ -342,10 +299,26 @@ export function scopesHereClause(scopes) {
342
299
  export function pathUnderPrefix(path, prefix) {
343
300
  return prefix === "" || path === prefix || path.startsWith(`${prefix}/`);
344
301
  }
302
+ /**
303
+ * Validate a normalized `--in` prefix against the graph before a query runs. A
304
+ * prefix matching no indexed node is a caller mistake (typo, wrong sub-project,
305
+ * or a mid-path fragment where a prefix is required) rather than a legitimate
306
+ * zero-hit query, so every `--in`-taking command fails loudly and identically
307
+ * instead of printing empty output the caller has to interpret.
308
+ *
309
+ * Pass the prefix through `normalizePathPrefix` first — an un-normalized
310
+ * `src\gpu` or `src/` will not match anything here.
311
+ */
312
+ export function assertPrefixIndexed(graph, prefix) {
313
+ if (!prefix || graph.nodes.some((n) => pathUnderPrefix(n.path, prefix)))
314
+ return;
315
+ throw new Error(`nothing indexed under "${prefix}/"${scopesHereClause(scopesOfGraph(graph))} (or any path prefix)`);
316
+ }
345
317
  /** Immediate subdirs of `root` that are themselves git repos (have `.git`).
346
318
  * Used by workspace federation (Task 5). */
347
319
  export function discoverWorkspaceChildren(root) {
348
320
  const absRoot = resolve(root);
321
+ const includes = readIncludeDirs(absRoot);
349
322
  let entries;
350
323
  try {
351
324
  entries = readdirSync(absRoot, { withFileTypes: true });
@@ -354,10 +327,7 @@ export function discoverWorkspaceChildren(root) {
354
327
  return [];
355
328
  }
356
329
  return entries
357
- .filter((e) => e.isDirectory() &&
358
- !e.name.startsWith(".") &&
359
- !SKIP_DIRS.has(e.name) &&
360
- existsSync(join(absRoot, e.name, ".git")))
330
+ .filter((e) => e.isDirectory() && !shouldSkipDir(e.name, includes) && existsSync(join(absRoot, e.name, ".git")))
361
331
  .map((e) => e.name);
362
332
  }
363
333
  /** Every consumer's entry point to a graph's scopes: absent `meta.scopes` (old