@vibgrate/cli 2026.729.3 → 2026.730.2
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.
- package/dist/{agent-Z4Z66IGM.js → agent-33BMKWJC.js} +4 -4
- package/dist/{agent-Z4Z66IGM.js.map → agent-33BMKWJC.js.map} +1 -1
- package/dist/baseline-536TQZIB.js +9 -0
- package/dist/{baseline-Q3QQF5QF.js.map → baseline-536TQZIB.js.map} +1 -1
- package/dist/{chunk-3FQSBVQD.js → chunk-A5LF4VS4.js} +8 -5
- package/dist/chunk-A5LF4VS4.js.map +1 -0
- package/dist/chunk-BZPZ3OM6.js +6 -0
- package/dist/{chunk-N3HCPBFY.js.map → chunk-BZPZ3OM6.js.map} +1 -1
- package/dist/{chunk-4BOWWYSE.js → chunk-CPX7XP3O.js} +13 -12
- package/dist/chunk-CPX7XP3O.js.map +1 -0
- package/dist/{chunk-KBPNH67Q.js → chunk-EGCB5K3P.js} +3 -3
- package/dist/{chunk-KBPNH67Q.js.map → chunk-EGCB5K3P.js.map} +1 -1
- package/dist/{chunk-G4HTI4ZM.js → chunk-FHJBGPJZ.js} +3 -2
- package/dist/chunk-FHJBGPJZ.js.map +1 -0
- package/dist/chunk-HTLDXEHW.js +60 -0
- package/dist/chunk-HTLDXEHW.js.map +1 -0
- package/dist/chunk-HWN4P64B.js +203 -0
- package/dist/chunk-HWN4P64B.js.map +1 -0
- package/dist/{chunk-GI6W53LM.js → chunk-IDAQV3NQ.js} +4 -2
- package/dist/chunk-IDAQV3NQ.js.map +1 -0
- package/dist/{chunk-42RDYQFF.js → chunk-KGWEBM2J.js} +3 -3
- package/dist/{chunk-42RDYQFF.js.map → chunk-KGWEBM2J.js.map} +1 -1
- package/dist/chunk-LCQILWQL.js +216 -0
- package/dist/chunk-LCQILWQL.js.map +1 -0
- package/dist/{chunk-EQ3IOFIG.js → chunk-NSK25UT2.js} +3 -3
- package/dist/{chunk-EQ3IOFIG.js.map → chunk-NSK25UT2.js.map} +1 -1
- package/dist/{chunk-JXMZCTVZ.js → chunk-PHVVVOW7.js} +14 -204
- package/dist/chunk-PHVVVOW7.js.map +1 -0
- package/dist/{chunk-RIEUPFXO.js → chunk-RV5DTGYT.js} +6 -62
- package/dist/chunk-RV5DTGYT.js.map +1 -0
- package/dist/{chunk-YMSXP6AO.js → chunk-UPH2RJ7L.js} +4 -4
- package/dist/{chunk-YMSXP6AO.js.map → chunk-UPH2RJ7L.js.map} +1 -1
- package/dist/{chunk-HWFVBYX4.js → chunk-WHXVU23K.js} +7 -6
- package/dist/chunk-WHXVU23K.js.map +1 -0
- package/dist/{chunk-5MNX3OLS.js → chunk-ZW5W627G.js} +7 -6
- package/dist/chunk-ZW5W627G.js.map +1 -0
- package/dist/cli.js +459 -532
- package/dist/cli.js.map +1 -1
- package/dist/{fs-6JKZNQ3U.js → fs-HNR6LAI7.js} +3 -3
- package/dist/fs-HNR6LAI7.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +10 -8
- package/dist/index.js.map +1 -1
- package/dist/{interactive-MJVMY5JP.js → interactive-MR7DTVYS.js} +16 -14
- package/dist/interactive-MR7DTVYS.js.map +1 -0
- package/dist/load-RFQFTTIT.js +10 -0
- package/dist/{load-4PARCNMD.js.map → load-RFQFTTIT.js.map} +1 -1
- package/dist/run-outcome-EKB6YQIK.js +253 -0
- package/dist/run-outcome-EKB6YQIK.js.map +1 -0
- package/dist/{runtime-session-AILFASQV.js → runtime-session-23RZLEA4.js} +7 -6
- package/dist/{runtime-session-AILFASQV.js.map → runtime-session-23RZLEA4.js.map} +1 -1
- package/dist/{stream-json-MTPWWVRR.js → stream-json-3YOPU3LF.js} +4 -4
- package/dist/{stream-json-MTPWWVRR.js.map → stream-json-3YOPU3LF.js.map} +1 -1
- package/dist/{vg-mcp-bridge-BLHEIWMT.js → vg-mcp-bridge-UZFHPP2Q.js} +8 -7
- package/dist/vg-mcp-bridge-UZFHPP2Q.js.map +1 -0
- package/dist/{vgd-S7D2SITC.js → vgd-VIPBL7W4.js} +6 -5
- package/dist/vgd-VIPBL7W4.js.map +1 -0
- package/package.json +1 -1
- package/dist/baseline-Q3QQF5QF.js +0 -9
- package/dist/chunk-3FQSBVQD.js.map +0 -1
- package/dist/chunk-4BOWWYSE.js.map +0 -1
- package/dist/chunk-5MNX3OLS.js.map +0 -1
- package/dist/chunk-G4HTI4ZM.js.map +0 -1
- package/dist/chunk-GI6W53LM.js.map +0 -1
- package/dist/chunk-HWFVBYX4.js.map +0 -1
- package/dist/chunk-JXMZCTVZ.js.map +0 -1
- package/dist/chunk-N3HCPBFY.js +0 -6
- package/dist/chunk-RIEUPFXO.js.map +0 -1
- package/dist/fs-6JKZNQ3U.js.map +0 -1
- package/dist/interactive-MJVMY5JP.js.map +0 -1
- package/dist/load-4PARCNMD.js +0 -9
- package/dist/vg-mcp-bridge-BLHEIWMT.js.map +0 -1
- package/dist/vgd-S7D2SITC.js.map +0 -1
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { loadGraphFileWithSnapshot, resolveGraphPath } from './chunk-PHVVVOW7.js';
|
|
2
|
+
import { cacheDir } from './chunk-ZKNB4YH4.js';
|
|
3
|
+
import { __require } from './chunk-Z6ZWNWWR.js';
|
|
4
|
+
import * as fs from 'fs';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
|
|
7
|
+
// src/schema.ts
|
|
8
|
+
var SCHEMA_VERSION = "vg-graph/1.0";
|
|
9
|
+
|
|
10
|
+
// src/engine/index-db.ts
|
|
11
|
+
function indexDbPath(root) {
|
|
12
|
+
return path.join(cacheDir(root), "graph.db");
|
|
13
|
+
}
|
|
14
|
+
function writeGraphIndex(root, graph) {
|
|
15
|
+
const file = indexDbPath(root);
|
|
16
|
+
try {
|
|
17
|
+
const { DatabaseSync } = __require("sqlite");
|
|
18
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
19
|
+
const tmp = `${file}.${process.pid}.tmp`;
|
|
20
|
+
try {
|
|
21
|
+
if (fs.existsSync(tmp)) fs.unlinkSync(tmp);
|
|
22
|
+
} catch {
|
|
23
|
+
}
|
|
24
|
+
const db = new DatabaseSync(tmp);
|
|
25
|
+
db.exec(`
|
|
26
|
+
PRAGMA journal_mode = OFF;
|
|
27
|
+
PRAGMA synchronous = OFF;
|
|
28
|
+
CREATE TABLE meta (
|
|
29
|
+
key TEXT PRIMARY KEY,
|
|
30
|
+
value TEXT NOT NULL
|
|
31
|
+
);
|
|
32
|
+
CREATE TABLE nodes (
|
|
33
|
+
id TEXT PRIMARY KEY,
|
|
34
|
+
name TEXT NOT NULL,
|
|
35
|
+
qualified_name TEXT NOT NULL,
|
|
36
|
+
kind TEXT NOT NULL,
|
|
37
|
+
file TEXT NOT NULL,
|
|
38
|
+
line INTEGER NOT NULL,
|
|
39
|
+
importance REAL NOT NULL,
|
|
40
|
+
area INTEGER NOT NULL,
|
|
41
|
+
is_hub INTEGER NOT NULL,
|
|
42
|
+
lang TEXT NOT NULL,
|
|
43
|
+
json TEXT NOT NULL
|
|
44
|
+
);
|
|
45
|
+
CREATE TABLE edges (
|
|
46
|
+
id TEXT PRIMARY KEY,
|
|
47
|
+
kind TEXT NOT NULL,
|
|
48
|
+
src TEXT NOT NULL,
|
|
49
|
+
dst TEXT NOT NULL,
|
|
50
|
+
resolution TEXT NOT NULL,
|
|
51
|
+
confidence REAL NOT NULL,
|
|
52
|
+
epistemic TEXT NOT NULL,
|
|
53
|
+
json TEXT NOT NULL
|
|
54
|
+
);
|
|
55
|
+
CREATE TABLE areas (
|
|
56
|
+
id INTEGER PRIMARY KEY,
|
|
57
|
+
json TEXT NOT NULL
|
|
58
|
+
);
|
|
59
|
+
CREATE INDEX idx_nodes_name ON nodes(name);
|
|
60
|
+
CREATE INDEX idx_nodes_qn ON nodes(qualified_name);
|
|
61
|
+
CREATE INDEX idx_nodes_file ON nodes(file);
|
|
62
|
+
CREATE INDEX idx_edges_src ON edges(src);
|
|
63
|
+
CREATE INDEX idx_edges_dst ON edges(dst);
|
|
64
|
+
CREATE INDEX idx_edges_kind ON edges(kind);
|
|
65
|
+
`);
|
|
66
|
+
const insMeta = db.prepare("INSERT INTO meta(key, value) VALUES (?, ?)");
|
|
67
|
+
insMeta.run("corpusHash", graph.provenance.corpusHash);
|
|
68
|
+
insMeta.run("schemaVersion", graph.schemaVersion);
|
|
69
|
+
insMeta.run("generatedAt", graph.generatedAt);
|
|
70
|
+
insMeta.run("nodeCount", String(graph.nodes.length));
|
|
71
|
+
insMeta.run("edgeCount", String(graph.edges.length));
|
|
72
|
+
insMeta.run("analysisTier", graph.meta.analysisTier ?? "full");
|
|
73
|
+
insMeta.run("indexVersion", "vg-graph-index/2");
|
|
74
|
+
insMeta.run("graphMeta", JSON.stringify(graph.meta));
|
|
75
|
+
insMeta.run("graphProvenance", JSON.stringify(graph.provenance));
|
|
76
|
+
if (graph.facts) insMeta.run("factsJson", JSON.stringify(graph.facts));
|
|
77
|
+
if (graph.grounding) insMeta.run("groundingJson", JSON.stringify(graph.grounding));
|
|
78
|
+
if (graph.summaries) insMeta.run("summariesJson", JSON.stringify(graph.summaries));
|
|
79
|
+
if (graph.unknowns) insMeta.run("unknownsJson", JSON.stringify(graph.unknowns));
|
|
80
|
+
const insNode = db.prepare(
|
|
81
|
+
`INSERT INTO nodes(id, name, qualified_name, kind, file, line, importance, area, is_hub, lang, json)
|
|
82
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
|
83
|
+
);
|
|
84
|
+
for (const n of graph.nodes) {
|
|
85
|
+
insNode.run(
|
|
86
|
+
n.id,
|
|
87
|
+
n.name,
|
|
88
|
+
n.qualifiedName,
|
|
89
|
+
n.kind,
|
|
90
|
+
n.file,
|
|
91
|
+
n.span.start,
|
|
92
|
+
n.importance,
|
|
93
|
+
n.area,
|
|
94
|
+
n.isHub ? 1 : 0,
|
|
95
|
+
n.lang,
|
|
96
|
+
JSON.stringify(n)
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
const insEdge = db.prepare(
|
|
100
|
+
`INSERT INTO edges(id, kind, src, dst, resolution, confidence, epistemic, json)
|
|
101
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
|
|
102
|
+
);
|
|
103
|
+
for (const e of graph.edges) {
|
|
104
|
+
insEdge.run(
|
|
105
|
+
e.id,
|
|
106
|
+
e.kind,
|
|
107
|
+
e.src,
|
|
108
|
+
e.dst,
|
|
109
|
+
e.resolution,
|
|
110
|
+
e.confidence,
|
|
111
|
+
e.epistemic ?? "observed",
|
|
112
|
+
JSON.stringify(e)
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
const insArea = db.prepare("INSERT INTO areas(id, json) VALUES (?, ?)");
|
|
116
|
+
for (const a of graph.areas) {
|
|
117
|
+
insArea.run(a.id, JSON.stringify(a));
|
|
118
|
+
}
|
|
119
|
+
db.close();
|
|
120
|
+
fs.renameSync(tmp, file);
|
|
121
|
+
return { path: file, nodes: graph.nodes.length, edges: graph.edges.length, ok: true };
|
|
122
|
+
} catch (err) {
|
|
123
|
+
return {
|
|
124
|
+
path: file,
|
|
125
|
+
nodes: 0,
|
|
126
|
+
edges: 0,
|
|
127
|
+
ok: false,
|
|
128
|
+
reason: err.message
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function loadGraphFromIndex(root) {
|
|
133
|
+
const file = indexDbPath(root);
|
|
134
|
+
if (!fs.existsSync(file)) return null;
|
|
135
|
+
try {
|
|
136
|
+
const { DatabaseSync } = __require("sqlite");
|
|
137
|
+
const db = new DatabaseSync(file, { readOnly: true });
|
|
138
|
+
const metaRows = db.prepare("SELECT key, value FROM meta").all();
|
|
139
|
+
const meta = {};
|
|
140
|
+
for (const r of metaRows) meta[r.key] = r.value;
|
|
141
|
+
if (meta.indexVersion !== "vg-graph-index/2" || !meta.graphMeta || !meta.graphProvenance) {
|
|
142
|
+
db.close();
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
const nodeRows = db.prepare("SELECT json FROM nodes ORDER BY id").all();
|
|
146
|
+
const edgeRows = db.prepare("SELECT json FROM edges ORDER BY id").all();
|
|
147
|
+
const areaRows = db.prepare("SELECT json FROM areas ORDER BY id").all();
|
|
148
|
+
db.close();
|
|
149
|
+
const nodes = nodeRows.map((r) => JSON.parse(r.json));
|
|
150
|
+
const edges = edgeRows.map((r) => JSON.parse(r.json));
|
|
151
|
+
const areas = areaRows.map((r) => JSON.parse(r.json));
|
|
152
|
+
nodes.sort((a, b) => a.id.localeCompare(b.id));
|
|
153
|
+
edges.sort(
|
|
154
|
+
(a, b) => a.kind.localeCompare(b.kind) || a.src.localeCompare(b.src) || a.dst.localeCompare(b.dst)
|
|
155
|
+
);
|
|
156
|
+
areas.sort((a, b) => a.id - b.id);
|
|
157
|
+
const graph = {
|
|
158
|
+
schemaVersion: meta.schemaVersion || SCHEMA_VERSION,
|
|
159
|
+
generatedAt: meta.generatedAt ?? (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
160
|
+
provenance: JSON.parse(meta.graphProvenance),
|
|
161
|
+
meta: JSON.parse(meta.graphMeta),
|
|
162
|
+
nodes,
|
|
163
|
+
edges,
|
|
164
|
+
areas
|
|
165
|
+
};
|
|
166
|
+
if (meta.factsJson) graph.facts = JSON.parse(meta.factsJson);
|
|
167
|
+
if (meta.groundingJson) graph.grounding = JSON.parse(meta.groundingJson);
|
|
168
|
+
if (meta.summariesJson) graph.summaries = JSON.parse(meta.summariesJson);
|
|
169
|
+
if (meta.unknownsJson) graph.unknowns = JSON.parse(meta.unknownsJson);
|
|
170
|
+
for (const e of edges) {
|
|
171
|
+
if (!e.resolution) e.resolution = "heuristic";
|
|
172
|
+
if (!e.epistemic) e.epistemic = "observed";
|
|
173
|
+
}
|
|
174
|
+
return graph;
|
|
175
|
+
} catch {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function loadGraphPreferIndex(root, graphJsonPath) {
|
|
180
|
+
const jsonGraph = loadGraphFileWithSnapshot(graphJsonPath);
|
|
181
|
+
const fromIndex = loadGraphFromIndex(root);
|
|
182
|
+
if (fromIndex) {
|
|
183
|
+
if (!jsonGraph || fromIndex.provenance.corpusHash === jsonGraph.provenance.corpusHash) {
|
|
184
|
+
return { graph: fromIndex, source: "index" };
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (jsonGraph) return { graph: jsonGraph, source: "json" };
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// src/engine/load.ts
|
|
192
|
+
function loadGraph(root, graphPath) {
|
|
193
|
+
const file = resolveGraphPath(root, graphPath);
|
|
194
|
+
if (!graphPath) {
|
|
195
|
+
const preferred = loadGraphPreferIndex(root, file);
|
|
196
|
+
if (preferred) return preferred.graph;
|
|
197
|
+
}
|
|
198
|
+
return loadGraphFileWithSnapshot(file);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export { SCHEMA_VERSION, loadGraph, loadGraphPreferIndex, writeGraphIndex };
|
|
202
|
+
//# sourceMappingURL=chunk-HWN4P64B.js.map
|
|
203
|
+
//# sourceMappingURL=chunk-HWN4P64B.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schema.ts","../src/engine/index-db.ts","../src/engine/load.ts"],"names":[],"mappings":";;;;;;;AASO,IAAM,cAAA,GAAiB;;;AC2BvB,SAAS,YAAY,IAAA,EAAsB;AAChD,EAAA,OAAY,IAAA,CAAA,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,EAAG,UAAU,CAAA;AAC7C;AAGO,SAAS,eAAA,CAAgB,MAAc,KAAA,EAAkC;AAC9E,EAAA,MAAM,IAAA,GAAO,YAAY,IAAI,CAAA;AAC7B,EAAA,IAAI;AAEF,IAAA,MAAM,EAAE,YAAA,EAAa,GAAI,SAAA,CAAQ,QAAa,CAAA;AAC9C,IAAG,aAAe,IAAA,CAAA,OAAA,CAAQ,IAAI,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AACpD,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,QAAQ,GAAG,CAAA,IAAA,CAAA;AAClC,IAAA,IAAI;AACF,MAAA,IAAO,EAAA,CAAA,UAAA,CAAW,GAAG,CAAA,EAAM,cAAW,GAAG,CAAA;AAAA,IAC3C,CAAA,CAAA,MAAQ;AAAA,IAER;AAEA,IAAA,MAAM,EAAA,GAAK,IAAI,YAAA,CAAa,GAAG,CAAA;AAC/B,IAAA,EAAA,CAAG,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAwCP,CAAA;AAED,IAAA,MAAM,OAAA,GAAU,EAAA,CAAG,OAAA,CAAQ,4CAA4C,CAAA;AACvE,IAAA,OAAA,CAAQ,GAAA,CAAI,YAAA,EAAc,KAAA,CAAM,UAAA,CAAW,UAAU,CAAA;AACrD,IAAA,OAAA,CAAQ,GAAA,CAAI,eAAA,EAAiB,KAAA,CAAM,aAAa,CAAA;AAChD,IAAA,OAAA,CAAQ,GAAA,CAAI,aAAA,EAAe,KAAA,CAAM,WAAW,CAAA;AAC5C,IAAA,OAAA,CAAQ,IAAI,WAAA,EAAa,MAAA,CAAO,KAAA,CAAM,KAAA,CAAM,MAAM,CAAC,CAAA;AACnD,IAAA,OAAA,CAAQ,IAAI,WAAA,EAAa,MAAA,CAAO,KAAA,CAAM,KAAA,CAAM,MAAM,CAAC,CAAA;AACnD,IAAA,OAAA,CAAQ,GAAA,CAAI,cAAA,EAAgB,KAAA,CAAM,IAAA,CAAK,gBAAgB,MAAM,CAAA;AAC7D,IAAA,OAAA,CAAQ,GAAA,CAAI,gBAAgB,kBAAkB,CAAA;AAE9C,IAAA,OAAA,CAAQ,IAAI,WAAA,EAAa,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,IAAI,CAAC,CAAA;AACnD,IAAA,OAAA,CAAQ,IAAI,iBAAA,EAAmB,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,UAAU,CAAC,CAAA;AAC/D,IAAA,IAAI,KAAA,CAAM,OAAO,OAAA,CAAQ,GAAA,CAAI,aAAa,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,KAAK,CAAC,CAAA;AACrE,IAAA,IAAI,KAAA,CAAM,WAAW,OAAA,CAAQ,GAAA,CAAI,iBAAiB,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,SAAS,CAAC,CAAA;AACjF,IAAA,IAAI,KAAA,CAAM,WAAW,OAAA,CAAQ,GAAA,CAAI,iBAAiB,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,SAAS,CAAC,CAAA;AACjF,IAAA,IAAI,KAAA,CAAM,UAAU,OAAA,CAAQ,GAAA,CAAI,gBAAgB,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,QAAQ,CAAC,CAAA;AAE9E,IAAA,MAAM,UAAU,EAAA,CAAG,OAAA;AAAA,MACjB,CAAA;AAAA,+CAAA;AAAA,KAEF;AACA,IAAA,KAAA,MAAW,CAAA,IAAK,MAAM,KAAA,EAAO;AAC3B,MAAA,OAAA,CAAQ,GAAA;AAAA,QACN,CAAA,CAAE,EAAA;AAAA,QACF,CAAA,CAAE,IAAA;AAAA,QACF,CAAA,CAAE,aAAA;AAAA,QACF,CAAA,CAAE,IAAA;AAAA,QACF,CAAA,CAAE,IAAA;AAAA,QACF,EAAE,IAAA,CAAK,KAAA;AAAA,QACP,CAAA,CAAE,UAAA;AAAA,QACF,CAAA,CAAE,IAAA;AAAA,QACF,CAAA,CAAE,QAAQ,CAAA,GAAI,CAAA;AAAA,QACd,CAAA,CAAE,IAAA;AAAA,QACF,IAAA,CAAK,UAAU,CAAC;AAAA,OAClB;AAAA,IACF;AAEA,IAAA,MAAM,UAAU,EAAA,CAAG,OAAA;AAAA,MACjB,CAAA;AAAA,sCAAA;AAAA,KAEF;AACA,IAAA,KAAA,MAAW,CAAA,IAAK,MAAM,KAAA,EAAO;AAC3B,MAAA,OAAA,CAAQ,GAAA;AAAA,QACN,CAAA,CAAE,EAAA;AAAA,QACF,CAAA,CAAE,IAAA;AAAA,QACF,CAAA,CAAE,GAAA;AAAA,QACF,CAAA,CAAE,GAAA;AAAA,QACF,CAAA,CAAE,UAAA;AAAA,QACF,CAAA,CAAE,UAAA;AAAA,QACF,EAAE,SAAA,IAAa,UAAA;AAAA,QACf,IAAA,CAAK,UAAU,CAAC;AAAA,OAClB;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAAU,EAAA,CAAG,OAAA,CAAQ,2CAA2C,CAAA;AACtE,IAAA,KAAA,MAAW,CAAA,IAAK,MAAM,KAAA,EAAO;AAC3B,MAAA,OAAA,CAAQ,IAAI,CAAA,CAAE,EAAA,EAAI,IAAA,CAAK,SAAA,CAAU,CAAC,CAAC,CAAA;AAAA,IACrC;AAEA,IAAA,EAAA,CAAG,KAAA,EAAM;AACT,IAAG,EAAA,CAAA,UAAA,CAAW,KAAK,IAAI,CAAA;AACvB,IAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,KAAA,EAAO,KAAA,CAAM,KAAA,CAAM,MAAA,EAAQ,KAAA,EAAO,KAAA,CAAM,KAAA,CAAM,MAAA,EAAQ,EAAA,EAAI,IAAA,EAAK;AAAA,EACtF,SAAS,GAAA,EAAK;AACZ,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,IAAA;AAAA,MACN,KAAA,EAAO,CAAA;AAAA,MACP,KAAA,EAAO,CAAA;AAAA,MACP,EAAA,EAAI,KAAA;AAAA,MACJ,QAAS,GAAA,CAAc;AAAA,KACzB;AAAA,EACF;AACF;AAoHO,SAAS,mBAAmB,IAAA,EAA8B;AAC/D,EAAA,MAAM,IAAA,GAAO,YAAY,IAAI,CAAA;AAC7B,EAAA,IAAI,CAAI,EAAA,CAAA,UAAA,CAAW,IAAI,CAAA,EAAG,OAAO,IAAA;AACjC,EAAA,IAAI;AAEF,IAAA,MAAM,EAAE,YAAA,EAAa,GAAI,SAAA,CAAQ,QAAa,CAAA;AAC9C,IAAA,MAAM,KAAK,IAAI,YAAA,CAAa,MAAM,EAAE,QAAA,EAAU,MAAM,CAAA;AACpD,IAAA,MAAM,QAAA,GAAW,EAAA,CAAG,OAAA,CAAQ,6BAA6B,EAAE,GAAA,EAAI;AAI/D,IAAA,MAAM,OAA+B,EAAC;AACtC,IAAA,KAAA,MAAW,KAAK,QAAA,EAAU,IAAA,CAAK,CAAA,CAAE,GAAG,IAAI,CAAA,CAAE,KAAA;AAE1C,IAAA,IAAI,IAAA,CAAK,iBAAiB,kBAAA,IAAsB,CAAC,KAAK,SAAA,IAAa,CAAC,KAAK,eAAA,EAAiB;AACxF,MAAA,EAAA,CAAG,KAAA,EAAM;AACT,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,QAAA,GAAW,EAAA,CAAG,OAAA,CAAQ,oCAAoC,EAAE,GAAA,EAAI;AAGtE,IAAA,MAAM,QAAA,GAAW,EAAA,CAAG,OAAA,CAAQ,oCAAoC,EAAE,GAAA,EAAI;AAGtE,IAAA,MAAM,QAAA,GAAW,EAAA,CAAG,OAAA,CAAQ,oCAAoC,EAAE,GAAA,EAAI;AAGtE,IAAA,EAAA,CAAG,KAAA,EAAM;AAET,IAAA,MAAM,KAAA,GAAQ,SAAS,GAAA,CAAI,CAAC,MAAM,IAAA,CAAK,KAAA,CAAM,CAAA,CAAE,IAAI,CAAc,CAAA;AACjE,IAAA,MAAM,KAAA,GAAQ,SAAS,GAAA,CAAI,CAAC,MAAM,IAAA,CAAK,KAAA,CAAM,CAAA,CAAE,IAAI,CAAc,CAAA;AACjE,IAAA,MAAM,KAAA,GAAQ,SAAS,GAAA,CAAI,CAAC,MAAM,IAAA,CAAK,KAAA,CAAM,CAAA,CAAE,IAAI,CAAS,CAAA;AAG5D,IAAA,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,EAAA,CAAG,aAAA,CAAc,CAAA,CAAE,EAAE,CAAC,CAAA;AAC7C,IAAA,KAAA,CAAM,IAAA;AAAA,MACJ,CAAC,CAAA,EAAG,CAAA,KACF,EAAE,IAAA,CAAK,aAAA,CAAc,EAAE,IAAI,CAAA,IAAK,EAAE,GAAA,CAAI,aAAA,CAAc,EAAE,GAAG,CAAA,IAAK,EAAE,GAAA,CAAI,aAAA,CAAc,EAAE,GAAG;AAAA,KAC3F;AACA,IAAA,KAAA,CAAM,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,EAAA,GAAK,EAAE,EAAE,CAAA;AAEhC,IAAA,MAAM,KAAA,GAAiB;AAAA,MACrB,aAAA,EAAgB,KAAK,aAAA,IAA2C,cAAA;AAAA,MAChE,aAAa,IAAA,CAAK,WAAA,IAAA,qBAAmB,IAAA,CAAK,CAAC,GAAE,WAAA,EAAY;AAAA,MACzD,UAAA,EAAY,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,eAAe,CAAA;AAAA,MAC3C,IAAA,EAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,SAAS,CAAA;AAAA,MAC/B,KAAA;AAAA,MACA,KAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,IAAI,KAAK,SAAA,EAAW,KAAA,CAAM,QAAQ,IAAA,CAAK,KAAA,CAAM,KAAK,SAAS,CAAA;AAC3D,IAAA,IAAI,KAAK,aAAA,EAAe,KAAA,CAAM,YAAY,IAAA,CAAK,KAAA,CAAM,KAAK,aAAa,CAAA;AACvE,IAAA,IAAI,KAAK,aAAA,EAAe,KAAA,CAAM,YAAY,IAAA,CAAK,KAAA,CAAM,KAAK,aAAa,CAAA;AACvE,IAAA,IAAI,KAAK,YAAA,EAAc,KAAA,CAAM,WAAW,IAAA,CAAK,KAAA,CAAM,KAAK,YAAY,CAAA;AAGpE,IAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACrB,MAAA,IAAI,CAAC,CAAA,CAAE,UAAA,EAAY,CAAA,CAAE,UAAA,GAAa,WAAA;AAClC,MAAA,IAAI,CAAC,CAAA,CAAE,SAAA,EAAW,CAAA,CAAE,SAAA,GAAY,UAAA;AAAA,IAClC;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAOO,SAAS,oBAAA,CACd,MACA,aAAA,EACqD;AAIrD,EAAA,MAAM,SAAA,GAA4B,0BAA0B,aAAa,CAAA;AAEzE,EAAA,MAAM,SAAA,GAAY,mBAAmB,IAAI,CAAA;AACzC,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,IAAI,CAAC,SAAA,IAAa,SAAA,CAAU,WAAW,UAAA,KAAe,SAAA,CAAU,WAAW,UAAA,EAAY;AACrF,MAAA,OAAO,EAAE,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,OAAA,EAAQ;AAAA,IAC7C;AAAA,EAEF;AACA,EAAA,IAAI,WAAW,OAAO,EAAE,KAAA,EAAO,SAAA,EAAW,QAAQ,MAAA,EAAO;AACzD,EAAA,OAAO,IAAA;AACT;;;ACvWO,SAAS,SAAA,CAAU,MAAc,SAAA,EAAoC;AAC1E,EAAA,MAAM,IAAA,GAAO,gBAAA,CAAiB,IAAA,EAAM,SAAS,CAAA;AAG7C,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,MAAM,SAAA,GAAY,oBAAA,CAAqB,IAAA,EAAM,IAAI,CAAA;AACjD,IAAA,IAAI,SAAA,SAAkB,SAAA,CAAU,KAAA;AAAA,EAClC;AACA,EAAA,OAAO,0BAA0B,IAAI,CAAA;AACvC","file":"chunk-HWN4P64B.js","sourcesContent":["/**\n * The `vg-graph/1.0` on-disk schema.\n *\n * This is vg's own open schema (VG-PACKAGE-AND-SCHEMA.md §4) — informed by good\n * ideas (content-hashed ids, epistemic typing of facts) but standalone and\n * self-contained. Every collection is deterministically serialized\n * (sorted keys, stable element order). These TypeScript shapes are normative.\n */\n\nexport const SCHEMA_VERSION = 'vg-graph/1.0' as const;\n\nexport type ResolverKind = 'scip' | 'stackgraph' | 'tsc' | 'heuristic';\n\n/** Coarse, honest resolution tier for an edge (see engine/epistemic.ts). */\nexport type EpistemicTier = 'observed' | 'name-matched' | 'declared';\n\n/**\n * The toolchain that produced this graph — the reproducibility fingerprint.\n * Everything here deterministically affects graph *content* (parse trees change\n * between grammar releases; resolvers change which edges resolve), so a CI run\n * and a laptop run that disagree can be caught by comparing `fingerprint`.\n * Deliberately excludes the Node/OS version so the graph stays byte-stable\n * across host runtimes; `fingerprint` pins the parse/resolve toolchain only.\n */\nexport interface Toolchain {\n schema: string; // SCHEMA_VERSION\n tool: string; // vg calendar version\n grammars: string; // tree-sitter grammar set version string\n resolvers: ResolverKind[]; // resolver kinds available, sorted\n fingerprint: string; // shortId over the fields above — the value `vg attest` signs\n}\n\nexport interface Provenance {\n tool: 'vg';\n version: string; // calendar version\n grammars: Record<string, string>; // lang → grammar version (determinism input)\n resolver: ResolverKind[];\n deep: boolean; // did the heavier open passes run\n semanticModel?: string; // embedding model id+version if --deep semantic links\n corpusHash: string; // blake3 over the included file set + hashes\n toolchain?: Toolchain; // reproducibility fingerprint (checked by `vg verify`)\n}\n\n/** Analysis cost tier — auto-selected by node count (or forced). Reported honestly. */\nexport type AnalysisTier = 'full' | 'large' | 'xl';\n\nexport interface GraphMeta {\n root: string; // relative; portable across machines\n languages: string[];\n counts: {\n nodes: number;\n edges: number;\n areas: number;\n tests: number;\n untested: number;\n };\n cluster: 'leiden' | 'louvain' | 'none';\n /** Auto-selected (or forced) analysis tier for large maps. */\n analysisTier?: AnalysisTier;\n edgeKinds: EdgeKind[];\n}\n\nexport type NodeKind =\n | 'file'\n | 'module'\n | 'package'\n | 'class'\n | 'interface'\n | 'function'\n | 'method'\n | 'property'\n | 'test'\n | 'route'\n | 'component'\n /** Documentation / config text ingested for semantic ask (markdown, txt, env examples). */\n | 'document'\n | 'external';\n\nexport interface Span {\n start: number; // 1-based start line\n end: number; // 1-based end line\n}\n\nexport interface Centrality {\n degree: number;\n pagerank: number;\n betweenness: number;\n eigenvector: number;\n}\n\nexport interface GraphNode {\n id: string; // blake3(canonical(kind, qualifiedName, file, signature))\n kind: NodeKind;\n name: string; // short name\n qualifiedName: string;\n file: string; // relative path\n span: Span; // line range (excluded from id hash)\n lang: string;\n visibility?: 'public' | 'private' | 'protected' | 'internal';\n signature?: string;\n doc?: string; // short leading doc-comment / docstring summary (deterministic; not a full body)\n importance: number; // 0..1 blended centrality\n centrality: Centrality;\n area: number; // area id (the node's community); -1 = unassigned (cluster \"none\")\n isHub: boolean; // centrality outlier — surfaced by `vg hubs`\n tested: boolean | null; // null = not analyzable (e.g. external)\n coverage?: number; // 0..1 line coverage if a coverage report was ingested\n changeCoupling?: string[]; // node ids that historically change together\n}\n\nexport type EdgeKind =\n | 'call'\n | 'import'\n | 'contains'\n | 'extends'\n | 'implements'\n | 'references'\n | 'test'\n | 'coverage';\n\nexport interface GraphEdge {\n id: string; // blake3(canonical(kind, src, dst))\n kind: EdgeKind;\n src: string; // node id\n dst: string; // node id\n resolution: ResolverKind; // how the edge was resolved\n confidence: number; // 0..1 (1.0 for scip/declared; lower for heuristic/dynamic)\n epistemic?: EpistemicTier; // coarse honesty tier derived from resolution+kind\n surprise?: number; // 0..1 improbability under the area model (`vg oddities`)\n count?: number; // call-site multiplicity\n}\n\nexport interface Area {\n id: number; // stable across runs (remapped to previous committed map)\n label: string; // most-central member's name (editable via `vg label`)\n size: number;\n members: string[]; // node ids, sorted\n cohesion: number; // 0..1\n externalEdges: number; // cross-area edge count\n}\n\nexport type FactKind = 'contract' | 'invariant' | 'characterization';\nexport type DerivedBy = 'declared' | 'static';\nexport type FactConfidence = 'Observed' | 'Derived';\n\nexport interface Fact {\n id: string; // blake3(canonical(kind, subjectIds, predicate))\n kind: FactKind;\n subjectIds: string[]; // node ids this fact constrains\n predicate: unknown; // the constraint\n derivedBy: DerivedBy;\n confidence: FactConfidence;\n evidence: { file: string; span: Span }[];\n}\n\n/**\n * A reference the graph could not resolve — surfaced by `vg unknowns`. Reporting\n * what it *cannot* connect (ranked by blast radius) is the honest inverse of a\n * scanner that hides its unknowns. Only unknowns the precise rungs (tsc/scip)\n * did not supersede are recorded, so a compiler-resolved file never shows here.\n */\nexport interface Unknown {\n from: string; // node id where the unresolved reference occurs\n name: string; // the callee/type name that could not be resolved\n kind: 'call' | 'extends' | 'implements';\n count: number; // occurrences at this site\n}\n\nexport type GroundingKind = 'should_follow' | 'smells_like' | 'relevant_to';\n\nexport interface GroundingEdge {\n src: string; // node id\n packEntryId: string;\n kind: GroundingKind;\n confidence: number; // 0..1\n rationale: 'recommended' | 'conjectured';\n citation: { title: string; url: string };\n}\n\n/** Precomputed hub blast-radius counts for fast agent answers (optional). */\nexport interface HubBlastSummary {\n id: string;\n name: string;\n kind: string;\n file: string;\n importance: number;\n direct: number;\n depth2: number;\n files: number;\n tested: boolean | null;\n}\n\nexport interface GraphSummaries {\n hubs: HubBlastSummary[];\n}\n\nexport interface VgGraph {\n schemaVersion: typeof SCHEMA_VERSION;\n generatedAt: string; // ISO; the ONLY nondeterministic field (pinned by --generated-at)\n provenance: Provenance;\n meta: GraphMeta;\n nodes: GraphNode[]; // sorted by id\n edges: GraphEdge[]; // sorted by (kind, src, dst)\n areas: Area[]; // sorted by id\n facts?: Fact[]; // open facts (contract/invariant/characterization); sorted by id\n grounding?: GroundingEdge[]; // free-pack grounding (default on; omit with --no-ground)\n unknowns?: Unknown[]; // heuristic references left unresolved; sorted by (from, kind, name)\n /** Build-time hub blast-radius summaries (always on; tiny). */\n summaries?: GraphSummaries;\n}\n","/**\n * SQLite serve index for large maps (scale past flat-JSON-only serve).\n *\n * The canonical artifact remains `graph.json` (determinism / git). The index\n * at `.vibgrate/cache/graph.db` is a derived, gitignored structure built after\n * every successful build:\n * - denormalized name/edge columns for O(log n) lookup\n * - full node/edge/area JSON for reconstructing a `VgGraph` without parsing\n * the pretty-printed graph.json (faster cold serve on XL maps)\n *\n * Uses Node's built-in `node:sqlite` (Node ≥22) — no native npm dependency.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { cacheDir } from './cache.js';\nimport { loadGraphFileWithSnapshot } from './snapshot.js';\nimport type {\n Area,\n EpistemicTier,\n GraphEdge,\n GraphNode,\n ResolverKind,\n VgGraph,\n} from '../schema.js';\nimport { SCHEMA_VERSION } from '../schema.js';\n\nexport interface IndexWriteResult {\n path: string;\n nodes: number;\n edges: number;\n /** False when node:sqlite is unavailable — callers should not fail the build. */\n ok: boolean;\n reason?: string;\n}\n\nexport function indexDbPath(root: string): string {\n return path.join(cacheDir(root), 'graph.db');\n}\n\n/** Write (replace) the SQLite index from a built graph. Never throws to callers. */\nexport function writeGraphIndex(root: string, graph: VgGraph): IndexWriteResult {\n const file = indexDbPath(root);\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { DatabaseSync } = require('node:sqlite') as typeof import('node:sqlite');\n fs.mkdirSync(path.dirname(file), { recursive: true });\n const tmp = `${file}.${process.pid}.tmp`;\n try {\n if (fs.existsSync(tmp)) fs.unlinkSync(tmp);\n } catch {\n /* ignore */\n }\n\n const db = new DatabaseSync(tmp);\n db.exec(`\n PRAGMA journal_mode = OFF;\n PRAGMA synchronous = OFF;\n CREATE TABLE meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n CREATE TABLE nodes (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n qualified_name TEXT NOT NULL,\n kind TEXT NOT NULL,\n file TEXT NOT NULL,\n line INTEGER NOT NULL,\n importance REAL NOT NULL,\n area INTEGER NOT NULL,\n is_hub INTEGER NOT NULL,\n lang TEXT NOT NULL,\n json TEXT NOT NULL\n );\n CREATE TABLE edges (\n id TEXT PRIMARY KEY,\n kind TEXT NOT NULL,\n src TEXT NOT NULL,\n dst TEXT NOT NULL,\n resolution TEXT NOT NULL,\n confidence REAL NOT NULL,\n epistemic TEXT NOT NULL,\n json TEXT NOT NULL\n );\n CREATE TABLE areas (\n id INTEGER PRIMARY KEY,\n json TEXT NOT NULL\n );\n CREATE INDEX idx_nodes_name ON nodes(name);\n CREATE INDEX idx_nodes_qn ON nodes(qualified_name);\n CREATE INDEX idx_nodes_file ON nodes(file);\n CREATE INDEX idx_edges_src ON edges(src);\n CREATE INDEX idx_edges_dst ON edges(dst);\n CREATE INDEX idx_edges_kind ON edges(kind);\n `);\n\n const insMeta = db.prepare('INSERT INTO meta(key, value) VALUES (?, ?)');\n insMeta.run('corpusHash', graph.provenance.corpusHash);\n insMeta.run('schemaVersion', graph.schemaVersion);\n insMeta.run('generatedAt', graph.generatedAt);\n insMeta.run('nodeCount', String(graph.nodes.length));\n insMeta.run('edgeCount', String(graph.edges.length));\n insMeta.run('analysisTier', graph.meta.analysisTier ?? 'full');\n insMeta.run('indexVersion', 'vg-graph-index/2');\n // Full meta + provenance for reconstruct without graph.json parse.\n insMeta.run('graphMeta', JSON.stringify(graph.meta));\n insMeta.run('graphProvenance', JSON.stringify(graph.provenance));\n if (graph.facts) insMeta.run('factsJson', JSON.stringify(graph.facts));\n if (graph.grounding) insMeta.run('groundingJson', JSON.stringify(graph.grounding));\n if (graph.summaries) insMeta.run('summariesJson', JSON.stringify(graph.summaries));\n if (graph.unknowns) insMeta.run('unknownsJson', JSON.stringify(graph.unknowns));\n\n const insNode = db.prepare(\n `INSERT INTO nodes(id, name, qualified_name, kind, file, line, importance, area, is_hub, lang, json)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n );\n for (const n of graph.nodes) {\n insNode.run(\n n.id,\n n.name,\n n.qualifiedName,\n n.kind,\n n.file,\n n.span.start,\n n.importance,\n n.area,\n n.isHub ? 1 : 0,\n n.lang,\n JSON.stringify(n),\n );\n }\n\n const insEdge = db.prepare(\n `INSERT INTO edges(id, kind, src, dst, resolution, confidence, epistemic, json)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n );\n for (const e of graph.edges) {\n insEdge.run(\n e.id,\n e.kind,\n e.src,\n e.dst,\n e.resolution,\n e.confidence,\n e.epistemic ?? 'observed',\n JSON.stringify(e),\n );\n }\n\n const insArea = db.prepare('INSERT INTO areas(id, json) VALUES (?, ?)');\n for (const a of graph.areas) {\n insArea.run(a.id, JSON.stringify(a));\n }\n\n db.close();\n fs.renameSync(tmp, file);\n return { path: file, nodes: graph.nodes.length, edges: graph.edges.length, ok: true };\n } catch (err) {\n return {\n path: file,\n nodes: 0,\n edges: 0,\n ok: false,\n reason: (err as Error).message,\n };\n }\n}\n\nexport interface NameHit {\n id: string;\n name: string;\n qualifiedName: string;\n kind: string;\n file: string;\n line: number;\n importance: number;\n}\n\n/** Fast name / prefix lookup against the index. Empty if index missing. */\nexport function lookupNameIndex(root: string, query: string, limit = 20): NameHit[] {\n const file = indexDbPath(root);\n if (!fs.existsSync(file) || !query.trim()) return [];\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { DatabaseSync } = require('node:sqlite') as typeof import('node:sqlite');\n const db = new DatabaseSync(file, { readOnly: true });\n const q = query.trim();\n const rows = db\n .prepare(\n `SELECT id, name, qualified_name, kind, file, line, importance\n FROM nodes\n WHERE name = ? OR qualified_name = ? OR name LIKE ? OR qualified_name LIKE ?\n ORDER BY\n CASE WHEN name = ? OR qualified_name = ? THEN 0\n WHEN name LIKE ? THEN 1\n ELSE 2 END,\n importance DESC\n LIMIT ?`,\n )\n .all(q, q, `${q}%`, `%${q}%`, q, q, `${q}%`, limit) as Record<string, unknown>[];\n db.close();\n return rows.map((r) => ({\n id: String(r.id),\n name: String(r.name),\n qualifiedName: String(r.qualified_name),\n kind: String(r.kind),\n file: String(r.file),\n line: Number(r.line),\n importance: Number(r.importance),\n }));\n } catch {\n return [];\n }\n}\n\n/** Neighbor edges for a node id (src or dst). Empty if index missing. */\nexport function lookupNeighbors(\n root: string,\n nodeId: string,\n direction: 'out' | 'in' | 'both' = 'both',\n limit = 50,\n): GraphEdge[] {\n const file = indexDbPath(root);\n if (!fs.existsSync(file) || !nodeId) return [];\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { DatabaseSync } = require('node:sqlite') as typeof import('node:sqlite');\n const db = new DatabaseSync(file, { readOnly: true });\n let rows: Record<string, unknown>[] = [];\n if (direction === 'out' || direction === 'both') {\n rows = rows.concat(\n db\n .prepare(`SELECT json FROM edges WHERE src = ? LIMIT ?`)\n .all(nodeId, limit) as Record<string, unknown>[],\n );\n }\n if (direction === 'in' || direction === 'both') {\n rows = rows.concat(\n db\n .prepare(`SELECT json FROM edges WHERE dst = ? LIMIT ?`)\n .all(nodeId, limit) as Record<string, unknown>[],\n );\n }\n db.close();\n const byId = new Map<string, GraphEdge>();\n for (const r of rows) {\n try {\n const e = JSON.parse(String(r.json)) as GraphEdge;\n byId.set(e.id, e);\n } catch {\n /* skip bad row */\n }\n }\n return [...byId.values()];\n } catch {\n return [];\n }\n}\n\n/** Read index meta (corpusHash etc.) or null if missing. */\nexport function readIndexMeta(root: string): Record<string, string> | null {\n const file = indexDbPath(root);\n if (!fs.existsSync(file)) return null;\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { DatabaseSync } = require('node:sqlite') as typeof import('node:sqlite');\n const db = new DatabaseSync(file, { readOnly: true });\n const rows = db.prepare('SELECT key, value FROM meta').all() as { key: string; value: string }[];\n db.close();\n const out: Record<string, string> = {};\n for (const r of rows) out[r.key] = r.value;\n return out;\n } catch {\n return null;\n }\n}\n\n/**\n * Reconstruct a full `VgGraph` from the SQLite index (indexVersion ≥ 2).\n * Returns null if the index is missing, stale schema, or incomplete.\n * Prefer this over JSON.parse of pretty graph.json for cold serve on large maps.\n */\nexport function loadGraphFromIndex(root: string): VgGraph | null {\n const file = indexDbPath(root);\n if (!fs.existsSync(file)) return null;\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { DatabaseSync } = require('node:sqlite') as typeof import('node:sqlite');\n const db = new DatabaseSync(file, { readOnly: true });\n const metaRows = db.prepare('SELECT key, value FROM meta').all() as {\n key: string;\n value: string;\n }[];\n const meta: Record<string, string> = {};\n for (const r of metaRows) meta[r.key] = r.value;\n\n if (meta.indexVersion !== 'vg-graph-index/2' || !meta.graphMeta || !meta.graphProvenance) {\n db.close();\n return null;\n }\n\n const nodeRows = db.prepare('SELECT json FROM nodes ORDER BY id').all() as {\n json: string;\n }[];\n const edgeRows = db.prepare('SELECT json FROM edges ORDER BY id').all() as {\n json: string;\n }[];\n const areaRows = db.prepare('SELECT json FROM areas ORDER BY id').all() as {\n json: string;\n }[];\n db.close();\n\n const nodes = nodeRows.map((r) => JSON.parse(r.json) as GraphNode);\n const edges = edgeRows.map((r) => JSON.parse(r.json) as GraphEdge);\n const areas = areaRows.map((r) => JSON.parse(r.json) as Area);\n\n // Stable sorts match serialize contract (ids already ordered by SQL, re-sort for safety).\n nodes.sort((a, b) => a.id.localeCompare(b.id));\n edges.sort(\n (a, b) =>\n a.kind.localeCompare(b.kind) || a.src.localeCompare(b.src) || a.dst.localeCompare(b.dst),\n );\n areas.sort((a, b) => a.id - b.id);\n\n const graph: VgGraph = {\n schemaVersion: (meta.schemaVersion as typeof SCHEMA_VERSION) || SCHEMA_VERSION,\n generatedAt: meta.generatedAt ?? new Date(0).toISOString(),\n provenance: JSON.parse(meta.graphProvenance),\n meta: JSON.parse(meta.graphMeta),\n nodes,\n edges,\n areas,\n };\n if (meta.factsJson) graph.facts = JSON.parse(meta.factsJson);\n if (meta.groundingJson) graph.grounding = JSON.parse(meta.groundingJson);\n if (meta.summariesJson) graph.summaries = JSON.parse(meta.summariesJson);\n if (meta.unknownsJson) graph.unknowns = JSON.parse(meta.unknownsJson);\n\n // Lightweight integrity: edge resolution types stay valid.\n for (const e of edges) {\n if (!e.resolution) e.resolution = 'heuristic' as ResolverKind;\n if (!e.epistemic) e.epistemic = 'observed' as EpistemicTier;\n }\n return graph;\n } catch {\n return null;\n }\n}\n\n/**\n * Load the graph preferring the SQLite index when its corpusHash matches the\n * committed graph.json provenance (or when only the index exists). Falls back\n * to graph.json. Returns null if neither is usable.\n */\nexport function loadGraphPreferIndex(\n root: string,\n graphJsonPath: string,\n): { graph: VgGraph; source: 'index' | 'json' } | null {\n // Snapshot-first: skips the large-string JSON.parse when a fresh binary\n // snapshot exists (sidecar or store-mode standalone), and self-heals the\n // sidecar when not (see engine/snapshot.ts).\n const jsonGraph: VgGraph | null = loadGraphFileWithSnapshot(graphJsonPath);\n\n const fromIndex = loadGraphFromIndex(root);\n if (fromIndex) {\n if (!jsonGraph || fromIndex.provenance.corpusHash === jsonGraph.provenance.corpusHash) {\n return { graph: fromIndex, source: 'index' };\n }\n // Index stale vs graph.json — prefer canonical JSON and let next build refresh.\n }\n if (jsonGraph) return { graph: jsonGraph, source: 'json' };\n return null;\n}\n","import * as fs from 'node:fs';\nimport { resolveGraphPath } from './artifacts.js';\nimport { loadGraphFileWithSnapshot } from './snapshot.js';\nimport { loadGraphPreferIndex } from './index-db.js';\nimport type { VgGraph } from '../schema.js';\n\n/**\n * Load the code map for a repository.\n *\n * When `graphPath` is omitted, prefers an existing global-store snapshot, then\n * the legacy `.vibgrate/graph.json`, matching {@link resolveGraphPath}.\n * Prefers the SQLite index when its corpusHash matches the committed map\n * (faster cold serve on large repos). Returns null if none exists.\n */\nexport function loadGraph(root: string, graphPath?: string): VgGraph | null {\n const file = resolveGraphPath(root, graphPath);\n // Index is always rooted at the project root; only use it when loading the\n // default map for that root (not an arbitrary --graph path).\n if (!graphPath) {\n const preferred = loadGraphPreferIndex(root, file);\n if (preferred) return preferred.graph;\n }\n return loadGraphFileWithSnapshot(file);\n}\n"]}
|
|
@@ -134,6 +134,8 @@ var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
|
134
134
|
".idea",
|
|
135
135
|
".vscode",
|
|
136
136
|
".vs",
|
|
137
|
+
// Claude Code agent state / worktrees (full monorepo copies under .claude/worktrees/)
|
|
138
|
+
".claude",
|
|
137
139
|
".vibgrate",
|
|
138
140
|
".wrangler",
|
|
139
141
|
".turbo",
|
|
@@ -910,5 +912,5 @@ async function writeTextFile(filePath, content) {
|
|
|
910
912
|
}
|
|
911
913
|
|
|
912
914
|
export { FileCache, SKIP_DIRS, SOURCE_EXCLUDE_FILES, Semaphore, bytesInDir, countFilesInDir, ensureDir, findCsprojFiles, findFiles, findPackageJsonFiles, findSolutionFiles, normalizeGlobForRipgrep, parseExcludePatterns, pathExists, quickTreeCount, readJsonFile, readTextFile, stripBom, writeJsonFile, writeTextFile };
|
|
913
|
-
//# sourceMappingURL=chunk-
|
|
914
|
-
//# sourceMappingURL=chunk-
|
|
915
|
+
//# sourceMappingURL=chunk-IDAQV3NQ.js.map
|
|
916
|
+
//# sourceMappingURL=chunk-IDAQV3NQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core-open/utils/semaphore.ts","../src/core-open/utils/glob.ts","../src/core-open/utils/fs.ts"],"names":["resolve","path","stat"],"mappings":"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","file":"chunk-IDAQV3NQ.js","sourcesContent":["// VENDORED from @vibgrate/core-open (packages/vibgrate-core-open) by\n// scripts/vendor-core-open.mjs. Do not edit here — change the source package\n// and re-run the vendor script. Apache-2.0.\n/** Simple concurrency limiter */\nexport class Semaphore {\n private available: number;\n private queue: Array<() => void> = [];\n\n constructor(max: number) {\n this.available = max;\n }\n\n async run<T>(fn: () => Promise<T>): Promise<T> {\n await this.acquire();\n try {\n return await fn();\n } finally {\n this.release();\n }\n }\n\n private acquire(): Promise<void> {\n if (this.available > 0) {\n this.available--;\n return Promise.resolve();\n }\n return new Promise((resolve) => this.queue.push(resolve));\n }\n\n private release() {\n const next = this.queue.shift();\n if (next) next();\n else this.available++;\n }\n}\n","// VENDORED from @vibgrate/core-open (packages/vibgrate-core-open) by\n// scripts/vendor-core-open.mjs. Do not edit here — change the source package\n// and re-run the vendor script. Apache-2.0.\nimport * as path from 'node:path';\n\n/**\n * Lightweight glob matcher — zero external dependencies.\n *\n * Supports the patterns most commonly used in vibgrate config `exclude`:\n * - `*` matches any sequence of non-separator chars\n * - `**` matches any sequence of chars including separators (recursive)\n * - `?` matches exactly one non-separator char\n * - `{a,b}` alternation\n * - `[abc]` character class\n * - Literal folder names like `legacy` match as a prefix (`legacy/**`)\n *\n * Paths are normalised to forward-slash before matching so patterns\n * work identically on Windows and Unix.\n */\n\n/**\n * Compile an array of glob patterns into a single predicate function\n * that tests a **relative** path (forward-slash separated).\n *\n * Returns `null` if the pattern list is empty (nothing excluded).\n */\n/**\n * Split one or more raw exclude inputs into individual glob patterns.\n *\n * Each input may contain multiple patterns separated by commas or\n * semicolons, e.g. `\"legacy/**, vendor/**; dist\"`. Surrounding\n * whitespace is trimmed and empty entries are dropped. Pass an array\n * (e.g. a repeated `--exclude` flag) and every element is expanded and\n * flattened into a single de-duplicated list.\n */\nexport function parseExcludePatterns(input: string | string[] | undefined): string[] {\n if (input === undefined) return [];\n const raw = Array.isArray(input) ? input : [input];\n const out: string[] = [];\n for (const entry of raw) {\n for (const part of entry.split(/[,;]/)) {\n const trimmed = part.trim();\n if (trimmed) out.push(trimmed);\n }\n }\n return [...new Set(out)];\n}\n\nexport function compileGlobs(patterns: string[]): ((relPath: string) => boolean) | null {\n if (patterns.length === 0) return null;\n\n const matchers = patterns.map((p) => compileOne(normalise(p)));\n\n return (relPath: string) => {\n const norm = normalise(relPath);\n return matchers.some((m) => m(norm));\n };\n}\n\nfunction normalise(p: string): string {\n // Always use forward-slash for matching\n return p.split(path.sep).join('/').replace(/\\/+$/, '');\n}\n\nfunction compileOne(pattern: string): (p: string) => boolean {\n // If the pattern has no glob metacharacters and no path separator,\n // treat it as a directory name prefix match (e.g. \"legacy\" → \"legacy/**\")\n if (!pattern.includes('/') && !hasGlobChars(pattern)) {\n const prefix = pattern + '/';\n return (p) => p === pattern || p.startsWith(prefix);\n }\n\n const re = globToRegex(pattern);\n return (p) => re.test(p);\n}\n\nfunction hasGlobChars(s: string): boolean {\n return /[*?[\\]{}]/.test(s);\n}\n\nfunction globToRegex(pattern: string): RegExp {\n let i = 0;\n let re = '^';\n const len = pattern.length;\n\n while (i < len) {\n const ch = pattern[i]!;\n\n if (ch === '*') {\n if (pattern[i + 1] === '*') {\n // ** — match everything (including separators)\n i += 2;\n if (pattern[i] === '/') {\n // **/ — matches zero or more path segments followed by /\n i++;\n re += '(?:.+/)?';\n } else {\n // ** at end of pattern — matches everything remaining\n re += '.*';\n }\n } else {\n // * — match non-separator chars\n i++;\n re += '[^/]*';\n }\n } else if (ch === '?') {\n i++;\n re += '[^/]';\n } else if (ch === '[') {\n // Character class — pass through until ]\n const start = i;\n i++; // skip [\n while (i < len && pattern[i] !== ']') i++;\n i++; // skip ]\n re += pattern.slice(start, i);\n } else if (ch === '{') {\n // Alternation {a,b,c}\n i++; // skip {\n const alternatives: string[] = [];\n let current = '';\n while (i < len && pattern[i] !== '}') {\n if (pattern[i] === ',') {\n alternatives.push(current);\n current = '';\n } else {\n current += pattern[i];\n }\n i++;\n }\n alternatives.push(current);\n i++; // skip }\n re += '(?:' + alternatives.map(escapeRegex).join('|') + ')';\n } else {\n re += escapeRegex(ch);\n i++;\n }\n }\n\n re += '$';\n return new RegExp(re);\n}\n\nfunction escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n","// VENDORED from @vibgrate/core-open (packages/vibgrate-core-open) by\n// scripts/vendor-core-open.mjs. Do not edit here — change the source package\n// and re-run the vendor script. Apache-2.0.\nimport { execFile } from 'node:child_process';\nimport * as fs from 'node:fs/promises';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { promisify } from 'node:util';\nimport type { Dirent } from 'node:fs';\nimport { Semaphore } from './semaphore.js';\nimport { compileGlobs } from './glob.js';\n\n\nconst execFileAsync = promisify(execFile);\n\n/**\n * Directories pruned entirely from the walk — third-party dependency trees,\n * build/output directories, and VCS/IDE metadata. Skipping them keeps their\n * contents out of BOTH project discovery (no phantom projects) AND the billing\n * source-size signals. Matched by exact directory name at any depth.\n *\n * Correctness is load-bearing for pricing: a *missing* entry lets vendored\n * third-party code inflate the project count and size (over-billing — e.g. a\n * React Native app's `Pods/` minting hundreds of phantom C/Obj-C projects),\n * while a *wrong* entry silently drops real source (under-billing). Every name\n * here must be one that is effectively never hand-written source in its\n * ecosystem. Keep in sync with `docs/DEPENDENCY-EXCLUSIONS.md`.\n *\n * Exported so other walkers (e.g. the graph engine's discovery, which keeps\n * its own self-contained copy) can assert in tests that they cover at least\n * this set — the scanner and the graph must never disagree on what is a\n * dependency/build tree.\n */\nexport const SKIP_DIRS = new Set([\n // ── Version control, IDE & tool metadata (never billable source) ──\n '.git', '.svn', '.hg',\n '.idea', '.vscode', '.vs',\n // Claude Code agent state / worktrees (full monorepo copies under .claude/worktrees/)\n '.claude',\n '.vibgrate', '.wrangler', '.turbo', '.cache',\n\n // ── JavaScript / Node — installed dependency trees ──\n 'node_modules', // npm / pnpm / yarn classic\n 'bower_components', // Bower (legacy)\n 'jspm_packages', // jspm (legacy)\n 'web_modules', // Snowpack (legacy)\n '.pnpm-store', // pnpm content-addressable store\n '.yarn', // Yarn Berry cache / unplugged / releases\n\n // ── JS/TS meta-framework & bundler build output ──\n '.next', '.nuxt', '.output', '.svelte-kit', '.astro',\n '.vercel', '.netlify', '.angular', '.parcel-cache', '.docusaurus',\n 'storybook-static',\n\n // ── Generic build / dist / coverage output ──\n 'dist', 'build', 'out', 'coverage',\n\n // ── Vendored third-party source trees ──\n 'vendor', // Go vendor/, PHP Composer, Rails vendor/bundle\n 'Pods', // CocoaPods (iOS/macOS)\n 'Carthage', // Carthage (iOS/macOS)\n\n // ── Python — virtualenvs & tool caches ──\n '.venv', 'venv', 'virtualenv', '.tox', '.nox',\n '__pycache__', '.mypy_cache', '.pytest_cache', '.ruff_cache',\n '.eggs', '.ipynb_checkpoints',\n\n // ── Ruby ──\n '.bundle', // bundler config / vendored gems\n\n // ── Rust / Maven / sbt / Clojure — all build into target/ ──\n 'target',\n\n // ── JVM (Gradle / Maven) & .NET build output ──\n '.gradle', 'bin', 'obj', 'TestResults',\n\n // ── Swift / Xcode ──\n '.build', '.swiftpm', 'DerivedData',\n\n // ── Dart / Flutter ──\n '.dart_tool',\n\n // ── Elixir / Erlang ──\n '_build', 'deps',\n\n // ── Haskell (Cabal / Stack) ──\n 'dist-newstyle', '.stack-work',\n\n // ── Infrastructure-as-code build/state ──\n '.terraform', '.serverless', 'cdk.out', '.aws-sam',\n]);\n\n/** File extensions skipped during the walk — binary/font/media that no scanner needs to read */\nconst SKIP_EXTENSIONS = new Set([\n // Fonts\n '.woff', '.woff2', '.ttf', '.otf', '.eot',\n // Images & vector\n '.png', '.jpg', '.jpeg', '.gif', '.ico', '.bmp', '.tiff', '.tif', '.webp', '.avif', '.svg',\n '.heic', '.heif', '.jfif', '.psd', '.ai', '.eps', '.raw', '.cr2', '.nef', '.dng',\n // Video\n '.mp4', '.webm', '.avi', '.mov', '.mkv', '.wmv', '.flv', '.m4v', '.mpg', '.mpeg', '.3gp', '.ogv',\n // Audio\n '.mp3', '.wav', '.ogg', '.flac', '.aac', '.wma', '.m4a', '.opus', '.aiff', '.mid', '.midi',\n // Archives\n '.zip', '.tar', '.gz', '.bz2', '.7z', '.rar',\n // Compiled / binary\n '.exe', '.dll', '.so', '.dylib', '.o', '.a', '.class', '.pyc', '.pdb',\n // Source maps & lockfiles (large, not useful for drift analysis)\n '.map',\n]);\n\n// Folded into SKIP_DIRS above (single source of truth). Kept as an empty set\n// so the existing walk/ripgrep call sites that OR-check it stay valid.\nconst EXTRA_SKIP_DIRS = new Set<string>([]);\n\n/**\n * Lockfiles and generated dependency manifests excluded from the billing\n * source-size metrics. They are not hand-written source, and a single one\n * (e.g. a pnpm-lock.yaml) can exceed 1 MB on its own, which would otherwise\n * inflate a genuinely tiny project past the micro/small size thresholds.\n *\n * Unlike {@link SKIP_DIRS}, these files legitimately sit at a project root\n * (next to the manifest that declares the project), so they are filtered\n * per-file rather than by pruning a directory. Manifests that *define* a\n * project (package.json, go.mod, Cargo.toml, *.csproj, …) are deliberately NOT\n * here — they are the source of truth for project discovery. Compared\n * case-insensitively against the basename, so every entry must be lowercase.\n * Keep in sync with `docs/DEPENDENCY-EXCLUSIONS.md`.\n */\nexport const SOURCE_EXCLUDE_FILES = new Set([\n // JavaScript / Node\n 'package-lock.json', 'npm-shrinkwrap.json', 'yarn.lock',\n 'pnpm-lock.yaml', 'bun.lockb', 'bun.lock', 'deno.lock',\n '.pnp.cjs', '.pnp.data.json', // Yarn PnP (generated, can be large)\n // Python\n 'poetry.lock', 'pipfile.lock', 'pdm.lock', 'uv.lock',\n 'pylock.toml', // PEP 751 standard lock\n 'conda-lock.yml',\n // Ruby\n 'gemfile.lock',\n // PHP\n 'composer.lock',\n // Rust\n 'cargo.lock',\n // Go\n 'go.sum', 'go.work.sum', 'gopkg.lock', 'glide.lock',\n // .NET\n 'packages.lock.json',\n // Java / JVM (Gradle)\n 'gradle.lockfile',\n // Swift / Xcode\n 'package.resolved',\n // Dart / Flutter\n 'pubspec.lock',\n // Elixir\n 'mix.lock',\n // Haskell (Cabal / Stack)\n 'cabal.project.freeze', 'stack.yaml.lock',\n // Julia\n 'manifest.toml',\n // R\n 'renv.lock',\n // Perl (Carton)\n 'cpanfile.snapshot',\n // CocoaPods / Carthage\n 'podfile.lock', 'cartfile.resolved',\n // Terraform / IaC\n '.terraform.lock.hcl',\n // Helm\n 'chart.lock',\n // C / C++ (Conan)\n 'conan.lock',\n // Bazel\n 'module.bazel.lock',\n // Nix\n 'flake.lock',\n]);\n\n// ── Directory entry gathered in a single walk ──\n\nexport interface DirEntry {\n /** Absolute path */\n absPath: string;\n /** Path relative to the walk root */\n relPath: string;\n /** Filename (basename) */\n name: string;\n /** Whether this is a regular file */\n isFile: boolean;\n /** Whether this is a directory */\n isDirectory: boolean;\n}\n\n// ── FileCache: walk once, read once ──\n\n/**\n * Maximum file size (in bytes) that will be held in the text cache.\n * Files larger than this are read from disk but NOT stored — this prevents\n * lockfiles (pnpm-lock.yaml, package-lock.json, etc.) from consuming\n * 50-200 MB of heap. Small config files like package.json (~1-5 KB each)\n * are cached normally.\n */\nconst TEXT_CACHE_MAX_BYTES = 1_048_576; // 1 MB\n\n/**\n * Shared cache that ensures the filesystem is walked at most once per root dir\n * and every small file is read at most once across all scanners.\n *\n * Memory-conscious design:\n * - Walk results are stored once; consumers filter in-memory.\n * - File content is only cached when ≤ TEXT_CACHE_MAX_BYTES (1 MB).\n * Large files (lockfiles) pass straight through without caching.\n * - readJsonFile evicts the raw-text entry after parsing so we never\n * hold *both* the string and the parsed object for the same file.\n * - No stat caching — only file-hotspots uses stat and there's no\n * cross-scanner reuse to justify holding thousands of Stats objects.\n * - Call `clear()` after the scan to release all remaining references.\n */\nexport class FileCache {\n /** Directory walk results keyed by rootDir */\n private walkCache = new Map<string, Promise<DirEntry[]>>();\n /** File content keyed by absolute path (only files ≤ TEXT_CACHE_MAX_BYTES) */\n private textCache = new Map<string, Promise<string>>();\n /** Parsed JSON keyed by absolute path */\n private jsonCache = new Map<string, Promise<unknown>>();\n /** pathExists keyed by absolute path */\n private existsCache = new Map<string, Promise<boolean>>();\n /** User-configured exclude predicate (compiled from glob patterns) */\n private excludePredicate: ((relPath: string) => boolean) | null = null;\n /** Directories that were auto-skipped because they were stuck */\n private _stuckPaths: string[] = [];\n /** Files skipped because they exceed maxFileSizeToScan */\n private _skippedLargeFiles: string[] = [];\n /** Maximum file size (bytes) we will read. 0 = unlimited. */\n private _maxFileSize = 0;\n /** Per-project / per-directory scan timeout in ms. */\n private _projectScanTimeout = 180_000;\n /** Whether we have already shown the \"increase projectScanTimeout\" hint */\n private _timeoutHintShown = false;\n /** Root dir for relative-path computation (set by the first walkDir call) */\n private _rootDir: string | null = null;\n /** Cached tree summary captured during the shared walk */\n private walkSummary = new Map<string, TreeCount>();\n /** Fast lookup for exact filename (e.g. package.json) */\n private fileNameIndex = new Map<string, Map<string, string[]>>();\n /** Per-file byte size keyed by absolute path (memoised so nested projects don't re-stat) */\n private sizeCache = new Map<string, Promise<number>>();\n /** Concurrency limiter for size stats */\n private sizeSem = new Semaphore(64);\n\n /** Set exclude patterns from config (call once before the walk) */\n setExcludePatterns(patterns: string[]): void {\n this.excludePredicate = compileGlobs(patterns);\n }\n\n /** Set the maximum file size in bytes that readTextFile / readJsonFile will process */\n setMaxFileSize(bytes: number): void {\n this._maxFileSize = bytes;\n }\n\n /** Set the per-project scan timeout (milliseconds). Scanners use this\n * instead of a hard-coded constant so the user can override it via config. */\n setProjectScanTimeout(ms: number): void {\n this._projectScanTimeout = ms;\n }\n\n /** Current per-project scan timeout in milliseconds */\n get projectScanTimeout(): number {\n return this._projectScanTimeout;\n }\n\n /** Record a path that timed out or was stuck during scanning */\n addStuckPath(relPath: string): void {\n this._stuckPaths.push(relPath);\n }\n\n /**\n * Returns true the first time it is called, false thereafter.\n * Used by scanners to print the \"increase projectScanTimeout\" hint\n * only once per scan run.\n */\n shouldShowTimeoutHint(): boolean {\n if (this._timeoutHintShown) return false;\n this._timeoutHintShown = true;\n return true;\n }\n\n /** Get all paths that were auto-skipped due to being stuck (dirs + scanner files) */\n get stuckPaths(): readonly string[] {\n return this._stuckPaths;\n }\n\n /** @deprecated Use stuckPaths instead */\n get stuckDirs(): readonly string[] {\n return this._stuckPaths;\n }\n\n /** Get files that were skipped because they exceeded maxFileSizeToScan */\n get skippedLargeFiles(): readonly string[] {\n return this._skippedLargeFiles;\n }\n\n // ── Directory walking ──\n\n /**\n * Walk the directory tree from `rootDir` once, skipping SKIP_DIRS plus\n * common framework output dirs (.nuxt, .output, .svelte-kit).\n *\n * The result is memoised so every scanner filters the same array.\n * Consumers that need additional filtering (e.g. SOURCE_EXTENSIONS,\n * SKIP_EXTENSIONS) do so on the returned entries — no separate walk.\n */\n walkDir(rootDir: string, onProgress?: (filesFound: number, currentPath: string) => void): Promise<DirEntry[]> {\n this._rootDir = rootDir;\n const cached = this.walkCache.get(rootDir);\n if (cached) return cached;\n\n const promise = this._doWalk(rootDir, onProgress);\n this.walkCache.set(rootDir, promise);\n return promise;\n }\n\n /** Return tree summary from the cached walk, if available. */\n getWalkSummary(rootDir: string): TreeCount | undefined {\n return this.walkSummary.get(rootDir);\n }\n\n /** Additional dirs skipped only by the cached walk (framework outputs) */\n private static readonly EXTRA_SKIP = EXTRA_SKIP_DIRS;\n\n private async _doWalk(rootDir: string, onProgress?: (filesFound: number, currentPath: string) => void): Promise<DirEntry[]> {\n const results: DirEntry[] = [];\n const cores = typeof os.availableParallelism === 'function' ? os.availableParallelism() : os.cpus().length || 4;\n const maxConcurrentReads = Math.max(8, Math.min(64, cores * 4));\n let foundCount = 0;\n let lastReported = 0;\n const REPORT_INTERVAL = 50; // report every N files\n // Semaphore limits concurrent readdir I/O only — NOT the entire\n // recursive walk. Previously sem.run wrapped the whole walk(),\n // so parent directories held a slot while awaiting children,\n // starving deep trees into near-serial execution.\n const sem = new Semaphore(maxConcurrentReads);\n const STUCK_TIMEOUT_MS = this._projectScanTimeout;\n\n const extraSkip = FileCache.EXTRA_SKIP;\n const isExcluded = this.excludePredicate;\n const stuckDirs = this._stuckPaths;\n\n async function walk(dir: string) {\n const relDir = path.relative(rootDir, dir);\n\n // Report the directory we are ABOUT to read so the UI shows\n // where we are if this readdir gets stuck.\n if (onProgress) {\n onProgress(foundCount, relDir || '.');\n }\n\n // Acquire the semaphore ONLY for the readdir I/O, then release\n // immediately so parent dirs don't hold slots while awaiting children.\n let entries: Dirent[] | null;\n try {\n entries = await sem.run(async () => {\n const readPromise = fs.readdir(dir, { withFileTypes: true });\n let stuckTimer: ReturnType<typeof setTimeout>;\n const result = await Promise.race([\n readPromise.then((e) => ({ ok: true as const, entries: e })),\n new Promise<{ ok: false }>((resolve) => {\n stuckTimer = setTimeout(() => resolve({ ok: false }), STUCK_TIMEOUT_MS);\n stuckTimer.unref();\n }),\n ]);\n clearTimeout(stuckTimer!);\n if (!result.ok) {\n // Directory read timed out — record and skip\n stuckDirs.push(relDir || dir);\n return null;\n }\n return result.entries;\n });\n } catch {\n return;\n }\n if (!entries) return;\n\n const subWalks: Promise<void>[] = [];\n for (const e of entries) {\n const absPath = path.join(dir, e.name);\n const relPath = path.relative(rootDir, absPath);\n\n // Check user-configured excludes\n if (isExcluded && isExcluded(relPath)) continue;\n\n if (e.isDirectory()) {\n if (SKIP_DIRS.has(e.name) || extraSkip.has(e.name)) continue;\n results.push({ absPath, relPath, name: e.name, isFile: false, isDirectory: true });\n // Launch sub-walk WITHOUT wrapping in sem.run — child walks\n // acquire the semaphore independently for their own readdir.\n subWalks.push(walk(absPath));\n } else if (e.isFile()) {\n // Skip binary/font/media files that no scanner needs\n const ext = path.extname(e.name).toLowerCase();\n if (SKIP_EXTENSIONS.has(ext)) continue;\n results.push({ absPath, relPath, name: e.name, isFile: true, isDirectory: false });\n foundCount++;\n if (onProgress && foundCount - lastReported >= REPORT_INTERVAL) {\n lastReported = foundCount;\n onProgress(foundCount, relPath);\n }\n }\n }\n await Promise.all(subWalks);\n }\n\n await walk(rootDir);\n\n let totalDirs = 0;\n const rootNameIndex = new Map<string, string[]>();\n for (const entry of results) {\n if (entry.isDirectory) totalDirs++;\n if (!entry.isFile) continue;\n const bucket = rootNameIndex.get(entry.name);\n if (bucket) {\n bucket.push(entry.absPath);\n } else {\n rootNameIndex.set(entry.name, [entry.absPath]);\n }\n }\n this.walkSummary.set(rootDir, { totalFiles: foundCount, totalDirs });\n this.fileNameIndex.set(rootDir, rootNameIndex);\n\n // Final progress report\n if (onProgress && foundCount !== lastReported) {\n onProgress(foundCount, '');\n }\n return results;\n }\n\n /**\n * Find files matching a predicate from the cached walk.\n * Returns absolute paths (same contract as the standalone `findFiles`).\n */\n async findFiles(rootDir: string, predicate: (name: string) => boolean): Promise<string[]> {\n const entries = await this.walkDir(rootDir);\n return entries.filter((e) => e.isFile && predicate(e.name)).map((e) => e.absPath);\n }\n\n async findPackageJsonFiles(rootDir: string): Promise<string[]> {\n await this.walkDir(rootDir);\n return this.fileNameIndex.get(rootDir)?.get('package.json') ?? [];\n }\n\n async findCsprojFiles(rootDir: string): Promise<string[]> {\n const entries = await this.walkDir(rootDir);\n return entries.filter((e) => e.isFile && e.name.endsWith('.csproj')).map((e) => e.absPath);\n }\n\n async findSolutionFiles(rootDir: string): Promise<string[]> {\n const entries = await this.walkDir(rootDir);\n return entries.filter((e) => e.isFile && e.name.endsWith('.sln')).map((e) => e.absPath);\n }\n\n /**\n * Count files under a given directory using the cached walk data.\n * Avoids a redundant recursive readdir that can be slow on large\n * project trees (the main cause of per-project timeout hits).\n * Falls back to the standalone `countFilesInDir` if the walk hasn't\n * been populated yet.\n */\n async countFilesUnder(rootDir: string, dir: string): Promise<number> {\n const entries = this.walkCache.get(rootDir);\n if (!entries) {\n // Walk not done yet — fall back to standalone count\n return countFilesInDir(dir);\n }\n const resolved = await entries;\n const prefix = dir.endsWith(path.sep) ? dir : dir + path.sep;\n let count = 0;\n for (const e of resolved) {\n if (!e.isFile) continue;\n // File is directly in `dir` or in a subdirectory of `dir`\n if (e.absPath === dir || e.absPath.startsWith(prefix)) {\n count++;\n }\n }\n return count;\n }\n\n /** Stat a single file's byte size, memoised and concurrency-limited. */\n private statSize(absPath: string): Promise<number> {\n const cached = this.sizeCache.get(absPath);\n if (cached) return cached;\n const promise = this.sizeSem.run(async () => {\n try {\n const stat = await fs.stat(absPath);\n return stat.size;\n } catch {\n return 0;\n }\n });\n this.sizeCache.set(absPath, promise);\n return promise;\n }\n\n /**\n * Sum the byte size of every file under `dir` using the cached walk.\n * Mirrors {@link countFilesUnder}; per-file stats are memoised so nested\n * project trees are never stat-ed twice. Falls back to a standalone walk\n * when the cache has not been populated yet.\n */\n async bytesUnder(rootDir: string, dir: string): Promise<number> {\n const entries = this.walkCache.get(rootDir);\n if (!entries) {\n // Walk not done yet — fall back to a standalone size walk\n return bytesInDir(dir);\n }\n const resolved = await entries;\n const prefix = dir.endsWith(path.sep) ? dir : dir + path.sep;\n const sizes = await Promise.all(\n resolved\n .filter((e) => e.isFile && (e.absPath === dir || e.absPath.startsWith(prefix)))\n .map((e) => this.statSize(e.absPath)),\n );\n return sizes.reduce((total, size) => total + size, 0);\n }\n\n /**\n * Source-only file count and byte size under `dir`, used for billing\n * classification. Identical to {@link countFilesUnder} / {@link bytesUnder}\n * but additionally excludes lockfiles and generated dependency manifests\n * (see {@link SOURCE_EXCLUDE_FILES}); vendored and build-output directories\n * are already excluded by the shared walk. Walks the cached entries once so\n * the count and size stay consistent. Falls back to the standalone walks\n * when the cache has not been populated yet.\n */\n async sourceMetricsUnder(rootDir: string, dir: string): Promise<{ fileCount: number; sizeBytes: number }> {\n const entries = this.walkCache.get(rootDir);\n if (!entries) {\n // Walk not done yet — fall back to standalone walks.\n const [fileCount, sizeBytes] = await Promise.all([countFilesInDir(dir), bytesInDir(dir)]);\n return { fileCount, sizeBytes };\n }\n const resolved = await entries;\n const prefix = dir.endsWith(path.sep) ? dir : dir + path.sep;\n const sourceFiles = resolved.filter(\n (e) =>\n e.isFile &&\n (e.absPath === dir || e.absPath.startsWith(prefix)) &&\n !SOURCE_EXCLUDE_FILES.has(e.name.toLowerCase()),\n );\n const sizes = await Promise.all(sourceFiles.map((e) => this.statSize(e.absPath)));\n return {\n fileCount: sourceFiles.length,\n sizeBytes: sizes.reduce((total, size) => total + size, 0),\n };\n }\n\n // ── File content reading ──\n\n /**\n * Read a text file. Files ≤ 1 MB are cached so subsequent calls from\n * different scanners return the same string. Files > 1 MB (lockfiles,\n * large generated files) are read directly and never retained.\n *\n * If maxFileSizeToScan is set and the file exceeds it, the file is\n * recorded as skipped and an empty string is returned.\n */\n readTextFile(filePath: string): Promise<string> {\n const abs = path.resolve(filePath);\n const cached = this.textCache.get(abs);\n if (cached) return cached;\n\n const maxSize = this._maxFileSize;\n const skippedLarge = this._skippedLargeFiles;\n const rootDir = this._rootDir;\n\n // Read file, then decide whether to cache based on size\n const promise = (async () => {\n // Check file size before reading when a limit is configured\n if (maxSize > 0) {\n try {\n const stat = await fs.stat(abs);\n if (stat.size > maxSize) {\n const rel = rootDir ? path.relative(rootDir, abs) : abs;\n skippedLarge.push(rel);\n this.textCache.delete(abs);\n return '';\n }\n } catch {\n // If stat fails, fall through and let readFile handle it\n }\n }\n\n const content = await fs.readFile(abs, 'utf8');\n if (content.length > TEXT_CACHE_MAX_BYTES) {\n // Too large for cache — evict so we don't hold it\n this.textCache.delete(abs);\n }\n return content;\n })();\n\n // Temporarily store the promise so concurrent callers during the same\n // tick await the same read (avoids double-reads even for large files).\n this.textCache.set(abs, promise);\n return promise;\n }\n\n /**\n * Read and parse a JSON file. The parsed object is cached; the raw\n * text is evicted immediately so we never hold both representations.\n */\n readJsonFile<T>(filePath: string): Promise<T> {\n const abs = path.resolve(filePath);\n const cached = this.jsonCache.get(abs);\n if (cached) return cached as Promise<T>;\n\n const promise = this.readTextFile(abs).then((txt) => {\n // Evict raw text — we now have the parsed object\n this.textCache.delete(abs);\n return JSON.parse(stripBom(txt)) as T;\n });\n this.jsonCache.set(abs, promise);\n return promise;\n }\n\n // ── Existence checks ──\n\n pathExists(p: string): Promise<boolean> {\n const abs = path.resolve(p);\n const cached = this.existsCache.get(abs);\n if (cached) return cached;\n const promise = fs.access(abs).then(() => true, () => false);\n this.existsCache.set(abs, promise);\n return promise;\n }\n\n // ── Lifecycle ──\n\n /** Release all cached data. Call after the scan completes. */\n clear(): void {\n this.walkCache.clear();\n this.walkSummary.clear();\n this.fileNameIndex.clear();\n this.textCache.clear();\n this.jsonCache.clear();\n this.existsCache.clear();\n this.sizeCache.clear();\n }\n\n /** Number of file content entries currently held */\n get textCacheSize(): number { return this.textCache.size; }\n /** Number of parsed JSON entries currently held */\n get jsonCacheSize(): number { return this.jsonCache.size; }\n}\n\n// ── Quick tree count (fast pre-scan) ──\n\nexport interface TreeCount {\n /** Total files discovered (excluding skipped dirs) */\n totalFiles: number;\n /** Total subdirectories discovered (excluding skipped dirs) */\n totalDirs: number;\n}\n\n/**\n * Fast, lightweight traversal that only *counts* files and directories\n * without storing entries. Used before the main scan so the progress\n * bar can show an accurate percentage.\n *\n * Respects the same SKIP_DIRS as the full walk.\n */\nexport async function quickTreeCount(rootDir: string, excludePatterns?: string[]): Promise<TreeCount> {\n const native = await quickTreeCountWithRipgrep(rootDir, excludePatterns);\n if (native) return native;\n\n let totalFiles = 0;\n let totalDirs = 0;\n const cores = typeof os.availableParallelism === 'function' ? os.availableParallelism() : os.cpus().length || 4;\n const maxConcurrent = Math.max(8, Math.min(128, cores * 8));\n const sem = new Semaphore(maxConcurrent);\n const extraSkip = EXTRA_SKIP_DIRS;\n const isExcluded = excludePatterns ? compileGlobs(excludePatterns) : null;\n\n async function count(dir: string) {\n let entries: Dirent[];\n try {\n entries = await sem.run(() => fs.readdir(dir, { withFileTypes: true }));\n } catch {\n return;\n }\n const subs: Promise<void>[] = [];\n for (const e of entries) {\n const relPath = path.relative(rootDir, path.join(dir, e.name));\n if (isExcluded && isExcluded(relPath)) continue;\n\n if (e.isDirectory()) {\n if (SKIP_DIRS.has(e.name) || extraSkip.has(e.name)) continue;\n totalDirs++;\n subs.push(count(path.join(dir, e.name)));\n } else if (e.isFile()) {\n const ext = path.extname(e.name).toLowerCase();\n if (!SKIP_EXTENSIONS.has(ext)) totalFiles++;\n }\n }\n await Promise.all(subs);\n }\n\n await count(rootDir);\n return { totalFiles, totalDirs };\n}\n\n\n\nexport function normalizeGlobForRipgrep(pattern: string): string {\n return pattern.replace(/\\\\/g, '/');\n}\n\nasync function quickTreeCountWithRipgrep(rootDir: string, excludePatterns?: string[]): Promise<TreeCount | null> {\n const args = ['--files', '--hidden', '--no-ignore', '--null'];\n\n for (const dir of SKIP_DIRS) {\n args.push('-g', `!**/${dir}/**`);\n }\n for (const dir of EXTRA_SKIP_DIRS) {\n args.push('-g', `!**/${dir}/**`);\n }\n for (const ext of SKIP_EXTENSIONS) {\n args.push('-g', `!**/*${ext}`);\n }\n for (const pattern of (excludePatterns ?? [])) {\n const trimmed = pattern.trim();\n if (!trimmed) continue;\n args.push('-g', `!${normalizeGlobForRipgrep(trimmed)}`);\n }\n\n try {\n const { stdout } = await execFileAsync('rg', args, { cwd: rootDir, maxBuffer: 64 * 1024 * 1024, encoding: 'utf8' });\n if (!stdout) return { totalFiles: 0, totalDirs: 0 };\n\n const files = stdout.split('\\0').filter(Boolean);\n const dirs = new Set<string>();\n for (const file of files) {\n const dir = path.dirname(file);\n if (dir && dir !== '.') dirs.add(dir);\n }\n\n return { totalFiles: files.length, totalDirs: dirs.size };\n } catch {\n return null;\n }\n}\n\n/**\n * Count the number of source files in a directory (non-recursive by default).\n * For project-level file counting, skips binary/media files.\n */\nexport async function countFilesInDir(dir: string, recursive = true): Promise<number> {\n let count = 0;\n const extraSkip = new Set(['obj', 'bin', 'Debug', 'Release', 'TestResults']);\n\n async function walk(currentDir: string): Promise<void> {\n let entries: Dirent[];\n try {\n entries = await fs.readdir(currentDir, { withFileTypes: true });\n } catch {\n return;\n }\n const subs: Promise<void>[] = [];\n for (const e of entries) {\n if (e.isDirectory()) {\n if (!recursive) continue;\n if (SKIP_DIRS.has(e.name) || extraSkip.has(e.name)) continue;\n subs.push(walk(path.join(currentDir, e.name)));\n } else if (e.isFile()) {\n const ext = path.extname(e.name).toLowerCase();\n if (!SKIP_EXTENSIONS.has(ext)) count++;\n }\n }\n await Promise.all(subs);\n }\n\n await walk(dir);\n return count;\n}\n\n/**\n * Sum the byte size of all source files in a directory (recursive),\n * skipping common build/output dirs and binary/media files. Standalone\n * fallback for {@link FileCache.bytesUnder} when the cached walk is cold.\n */\nexport async function bytesInDir(dir: string, recursive = true): Promise<number> {\n let bytes = 0;\n const extraSkip = new Set(['obj', 'bin', 'Debug', 'Release', 'TestResults']);\n\n async function walk(currentDir: string): Promise<void> {\n let entries: Dirent[];\n try {\n entries = await fs.readdir(currentDir, { withFileTypes: true });\n } catch {\n return;\n }\n const subs: Promise<void>[] = [];\n for (const e of entries) {\n if (e.isDirectory()) {\n if (!recursive) continue;\n if (SKIP_DIRS.has(e.name) || extraSkip.has(e.name)) continue;\n subs.push(walk(path.join(currentDir, e.name)));\n } else if (e.isFile()) {\n const ext = path.extname(e.name).toLowerCase();\n if (SKIP_EXTENSIONS.has(ext)) continue;\n try {\n const stat = await fs.stat(path.join(currentDir, e.name));\n bytes += stat.size;\n } catch {\n // ignore unreadable files\n }\n }\n }\n await Promise.all(subs);\n }\n\n await walk(dir);\n return bytes;\n}\n\n/** Recursively find files matching a predicate, skipping common build/output dirs */\nexport async function findFiles(\n rootDir: string,\n predicate: (name: string) => boolean,\n): Promise<string[]> {\n const results: string[] = [];\n const cores = typeof os.availableParallelism === 'function' ? os.availableParallelism() : os.cpus().length || 4;\n const maxConcurrentReads = Math.max(8, Math.min(64, cores * 4));\n const readDirSemaphore = new Semaphore(maxConcurrentReads);\n\n async function walk(dir: string) {\n let entries: Dirent[];\n try {\n entries = await readDirSemaphore.run(() => fs.readdir(dir, { withFileTypes: true }));\n } catch {\n return;\n }\n\n const subDirectoryWalks: Promise<void>[] = [];\n\n for (const e of entries) {\n if (e.isDirectory()) {\n if (SKIP_DIRS.has(e.name)) continue;\n subDirectoryWalks.push(walk(path.join(dir, e.name)));\n } else if (e.isFile() && predicate(e.name)) {\n const ext = path.extname(e.name).toLowerCase();\n if (!SKIP_EXTENSIONS.has(ext)) results.push(path.join(dir, e.name));\n }\n }\n\n await Promise.all(subDirectoryWalks);\n }\n\n await walk(rootDir);\n return results;\n}\n\nexport async function findPackageJsonFiles(rootDir: string): Promise<string[]> {\n return findFiles(rootDir, (name) => name === 'package.json');\n}\n\nexport async function findSolutionFiles(rootDir: string): Promise<string[]> {\n return findFiles(rootDir, (name) => name.endsWith('.sln'));\n}\n\nexport async function findCsprojFiles(rootDir: string): Promise<string[]> {\n return findFiles(rootDir, (name) => name.endsWith('.csproj'));\n}\n\n/**\n * Strip a UTF-8 byte-order mark — editors on Windows commonly save\n * manifests with a BOM, and JSON.parse rejects it, which silently\n * dropped the project from scan results.\n */\nexport function stripBom(text: string): string {\n return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;\n}\n\nexport async function readJsonFile<T>(filePath: string): Promise<T> {\n const txt = await fs.readFile(filePath, 'utf8');\n return JSON.parse(stripBom(txt)) as T;\n}\n\nexport async function readTextFile(filePath: string): Promise<string> {\n return fs.readFile(filePath, 'utf8');\n}\n\nexport async function pathExists(p: string): Promise<boolean> {\n try {\n await fs.access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function ensureDir(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\nexport async function writeJsonFile(filePath: string, data: unknown): Promise<void> {\n await ensureDir(path.dirname(filePath));\n await fs.writeFile(filePath, JSON.stringify(data, null, 2) + '\\n', 'utf8');\n}\n\nexport async function writeTextFile(filePath: string, content: string): Promise<void> {\n await ensureDir(path.dirname(filePath));\n await fs.writeFile(filePath, content, 'utf8');\n}\n"]}
|
|
@@ -3,7 +3,7 @@ import { buildAgentMessages, redactSecrets, unifiedDiff, applyEdit } from './chu
|
|
|
3
3
|
import { localGraphBackend } from './chunk-RGEVBSLK.js';
|
|
4
4
|
import { buildIdentifierTrieFromGraph, KvBlockRegistry, graphDraftCandidates, extractIdentifiers, scanIdentifiersAgainstTrie } from './chunk-5HYCB55P.js';
|
|
5
5
|
import { resolve } from './chunk-IPICO2RV.js';
|
|
6
|
-
import { searchSymbols, resolveLib, loadCatalog, readDoc, localPackageDocs, resolveVersion } from './chunk-
|
|
6
|
+
import { searchSymbols, resolveLib, loadCatalog, readDoc, localPackageDocs, resolveVersion } from './chunk-FHJBGPJZ.js';
|
|
7
7
|
import { summarizeCapsule, CAPSULE_RANKING_VERSION, buildCodeContext, buildTaskCapsule, capsuleToCodeContext, recordCliCall, CLI_TOOL_ALIASES } from './chunk-US2DAKCM.js';
|
|
8
8
|
import { resolveOne } from './chunk-J7LKEB2R.js';
|
|
9
9
|
import { isLocateOnlyInstruction, extractLiteralNeedles, impactOf } from './chunk-EETK7S43.js';
|
|
@@ -2637,5 +2637,5 @@ function buildSpanIndex(graph) {
|
|
|
2637
2637
|
}
|
|
2638
2638
|
|
|
2639
2639
|
export { CONTEXT_POLICY_VERSION, DISCOVERY_TOOLS, MUTATION_TOOLS, compact, computeFcsReport, createTrajectoryCollector, renderFcsReportMarkdown, runAgent };
|
|
2640
|
-
//# sourceMappingURL=chunk-
|
|
2641
|
-
//# sourceMappingURL=chunk-
|
|
2640
|
+
//# sourceMappingURL=chunk-KGWEBM2J.js.map
|
|
2641
|
+
//# sourceMappingURL=chunk-KGWEBM2J.js.map
|