@vibgrate/cli 2026.722.2 → 2026.727.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.
Files changed (145) hide show
  1. package/DOCS.md +418 -213
  2. package/README.md +34 -8
  3. package/dist/baseline-TG4ATZGZ.js +8 -0
  4. package/dist/{baseline-BD3A7EXD.js.map → baseline-TG4ATZGZ.js.map} +1 -1
  5. package/dist/chunk-2MBL43EJ.js +82 -0
  6. package/dist/chunk-2MBL43EJ.js.map +1 -0
  7. package/dist/chunk-2XQDMLKB.js +465 -0
  8. package/dist/chunk-2XQDMLKB.js.map +1 -0
  9. package/dist/{chunk-PY3DNX5H.js → chunk-3Q7QBWFW.js} +13 -2
  10. package/dist/chunk-3Q7QBWFW.js.map +1 -0
  11. package/dist/chunk-3V24O47U.js +478 -0
  12. package/dist/chunk-3V24O47U.js.map +1 -0
  13. package/dist/chunk-5I4VSBWQ.js +764 -0
  14. package/dist/chunk-5I4VSBWQ.js.map +1 -0
  15. package/dist/{chunk-WNIIKCNF.js → chunk-6ABXHZRN.js} +59 -311
  16. package/dist/chunk-6ABXHZRN.js.map +1 -0
  17. package/dist/chunk-6AYDFFP5.js +136 -0
  18. package/dist/chunk-6AYDFFP5.js.map +1 -0
  19. package/dist/chunk-6UQMXIAG.js +122 -0
  20. package/dist/chunk-6UQMXIAG.js.map +1 -0
  21. package/dist/chunk-7N4Y3E47.js +108 -0
  22. package/dist/chunk-7N4Y3E47.js.map +1 -0
  23. package/dist/chunk-BPF3YX2U.js +64 -0
  24. package/dist/chunk-BPF3YX2U.js.map +1 -0
  25. package/dist/chunk-BWPBB45M.js +88 -0
  26. package/dist/chunk-BWPBB45M.js.map +1 -0
  27. package/dist/{chunk-6CXTPC74.js → chunk-CY4WKXB2.js} +27 -6
  28. package/dist/chunk-CY4WKXB2.js.map +1 -0
  29. package/dist/chunk-DGUM43GV.js +10 -0
  30. package/dist/chunk-DGUM43GV.js.map +1 -0
  31. package/dist/{chunk-NONYJLOJ.js → chunk-EX4PQT6W.js} +3 -3
  32. package/dist/{chunk-NONYJLOJ.js.map → chunk-EX4PQT6W.js.map} +1 -1
  33. package/dist/chunk-IS7VTH2Q.js +627 -0
  34. package/dist/chunk-IS7VTH2Q.js.map +1 -0
  35. package/dist/chunk-IZDH67DX.js +289 -0
  36. package/dist/chunk-IZDH67DX.js.map +1 -0
  37. package/dist/chunk-J4RFRKZH.js +2496 -0
  38. package/dist/chunk-J4RFRKZH.js.map +1 -0
  39. package/dist/chunk-J7LKEB2R.js +51 -0
  40. package/dist/chunk-J7LKEB2R.js.map +1 -0
  41. package/dist/chunk-JIBOJTGS.js +313 -0
  42. package/dist/chunk-JIBOJTGS.js.map +1 -0
  43. package/dist/chunk-K3MZIVZW.js +88 -0
  44. package/dist/chunk-K3MZIVZW.js.map +1 -0
  45. package/dist/chunk-K7REHDQS.js +776 -0
  46. package/dist/chunk-K7REHDQS.js.map +1 -0
  47. package/dist/{chunk-2O5YZVZV.js → chunk-KCKYKDMS.js} +23 -19
  48. package/dist/chunk-KCKYKDMS.js.map +1 -0
  49. package/dist/{chunk-3MXNNBLI.js → chunk-KNELIQJO.js} +1647 -2042
  50. package/dist/chunk-KNELIQJO.js.map +1 -0
  51. package/dist/chunk-KSBHGWRV.js +613 -0
  52. package/dist/chunk-KSBHGWRV.js.map +1 -0
  53. package/dist/chunk-LKVMI67M.js +1695 -0
  54. package/dist/chunk-LKVMI67M.js.map +1 -0
  55. package/dist/chunk-NDMDSPFX.js +69 -0
  56. package/dist/chunk-NDMDSPFX.js.map +1 -0
  57. package/dist/{chunk-CS37OBE3.js → chunk-OFUC6RYN.js} +791 -783
  58. package/dist/chunk-OFUC6RYN.js.map +1 -0
  59. package/dist/chunk-OOIG3RUM.js +276 -0
  60. package/dist/chunk-OOIG3RUM.js.map +1 -0
  61. package/dist/chunk-PMYWZRRS.js +62 -0
  62. package/dist/chunk-PMYWZRRS.js.map +1 -0
  63. package/dist/chunk-PXHNTC6D.js +382 -0
  64. package/dist/chunk-PXHNTC6D.js.map +1 -0
  65. package/dist/{chunk-I7GY7MVN.js → chunk-RNP3SMTV.js} +60 -12
  66. package/dist/chunk-RNP3SMTV.js.map +1 -0
  67. package/dist/chunk-TCDAZZNP.js +843 -0
  68. package/dist/chunk-TCDAZZNP.js.map +1 -0
  69. package/dist/{chunk-5BDHQ7DD.js → chunk-WGUL45AV.js} +24 -17
  70. package/dist/chunk-WGUL45AV.js.map +1 -0
  71. package/dist/cli.d.ts +3 -0
  72. package/dist/cli.js +3373 -617
  73. package/dist/cli.js.map +1 -1
  74. package/dist/execution-env-ZU45JZ4G.js +4 -0
  75. package/dist/execution-env-ZU45JZ4G.js.map +1 -0
  76. package/dist/federation-SZWZIFZ7.js +7 -0
  77. package/dist/federation-SZWZIFZ7.js.map +1 -0
  78. package/dist/{fs-IPY4FJKH.js → fs-B5HZ2MIU.js} +3 -2
  79. package/dist/fs-B5HZ2MIU.js.map +1 -0
  80. package/dist/{fs-KCABDURV.js → fs-O5IQYXHO.js} +3 -2
  81. package/dist/fs-O5IQYXHO.js.map +1 -0
  82. package/dist/git-ref-XDXB6JP5.js +4 -0
  83. package/dist/git-ref-XDXB6JP5.js.map +1 -0
  84. package/dist/graph-backend-73URGTFY.js +11 -0
  85. package/dist/graph-backend-73URGTFY.js.map +1 -0
  86. package/dist/index.d.ts +472 -137
  87. package/dist/index.js +15 -7
  88. package/dist/index.js.map +1 -1
  89. package/dist/{interactive-A4DISSIW.js → interactive-372NLI5C.js} +186 -226
  90. package/dist/interactive-372NLI5C.js.map +1 -0
  91. package/dist/llm-host-7GWDO6IX.js +9 -0
  92. package/dist/llm-host-7GWDO6IX.js.map +1 -0
  93. package/dist/load-I333TGNI.js +8 -0
  94. package/dist/load-I333TGNI.js.map +1 -0
  95. package/dist/local-runtime-5O2NN3GA.js +5 -0
  96. package/dist/local-runtime-5O2NN3GA.js.map +1 -0
  97. package/dist/mcp-tools-I7JK3S2M.js +4 -0
  98. package/dist/{mcp-tools-I6PME3AV.js.map → mcp-tools-I7JK3S2M.js.map} +1 -1
  99. package/dist/model-execution-profile-TFBKCNJG.js +4 -0
  100. package/dist/model-execution-profile-TFBKCNJG.js.map +1 -0
  101. package/dist/model-orchestrator-TVONAUPS.js +9 -0
  102. package/dist/model-orchestrator-TVONAUPS.js.map +1 -0
  103. package/dist/parse-worker.d.ts +1 -1
  104. package/dist/parse-worker.js +2 -1
  105. package/dist/parse-worker.js.map +1 -1
  106. package/dist/paths-2RAH3GME.js +6 -0
  107. package/dist/paths-2RAH3GME.js.map +1 -0
  108. package/dist/resolve-gguf-VPL4YQ6J.js +8 -0
  109. package/dist/resolve-gguf-VPL4YQ6J.js.map +1 -0
  110. package/dist/runtime-session-JRKCQUHY.js +18 -0
  111. package/dist/runtime-session-JRKCQUHY.js.map +1 -0
  112. package/dist/session-ITPYQ5XI.js +11 -0
  113. package/dist/{session-POJUDFPH.js.map → session-ITPYQ5XI.js.map} +1 -1
  114. package/dist/session-store-WFBX7HXL.js +4 -0
  115. package/dist/{session-store-W5RZZHA3.js.map → session-store-WFBX7HXL.js.map} +1 -1
  116. package/dist/{stream-json-Q2JGWPHB.js → stream-json-SLMDKLXP.js} +17 -6
  117. package/dist/stream-json-SLMDKLXP.js.map +1 -0
  118. package/dist/{types-Jl6RJ175.d.ts → types-7AHBUbFm.d.ts} +8 -2
  119. package/dist/ui-Q6DJ3GCU.js +5 -0
  120. package/dist/ui-Q6DJ3GCU.js.map +1 -0
  121. package/dist/vgd-7JV5KCNJ.js +17 -0
  122. package/dist/vgd-7JV5KCNJ.js.map +1 -0
  123. package/package.json +9 -6
  124. package/dist/baseline-BD3A7EXD.js +0 -7
  125. package/dist/chunk-2O5YZVZV.js.map +0 -1
  126. package/dist/chunk-3MXNNBLI.js.map +0 -1
  127. package/dist/chunk-5BDHQ7DD.js.map +0 -1
  128. package/dist/chunk-6CXTPC74.js.map +0 -1
  129. package/dist/chunk-CS37OBE3.js.map +0 -1
  130. package/dist/chunk-GGJZA3Q6.js +0 -961
  131. package/dist/chunk-GGJZA3Q6.js.map +0 -1
  132. package/dist/chunk-I7GY7MVN.js.map +0 -1
  133. package/dist/chunk-JBXNQCGE.js +0 -484
  134. package/dist/chunk-JBXNQCGE.js.map +0 -1
  135. package/dist/chunk-PY3DNX5H.js.map +0 -1
  136. package/dist/chunk-WNIIKCNF.js.map +0 -1
  137. package/dist/fs-IPY4FJKH.js.map +0 -1
  138. package/dist/fs-KCABDURV.js.map +0 -1
  139. package/dist/interactive-A4DISSIW.js.map +0 -1
  140. package/dist/mcp-tools-I6PME3AV.js +0 -3
  141. package/dist/session-POJUDFPH.js +0 -6
  142. package/dist/session-store-W5RZZHA3.js +0 -3
  143. package/dist/stream-json-Q2JGWPHB.js.map +0 -1
  144. package/dist/ui-HOVOPWMX.js +0 -4
  145. package/dist/ui-HOVOPWMX.js.map +0 -1
package/README.md CHANGED
@@ -293,12 +293,15 @@ See [docs/QUICKSTART-PROMPT.md](./docs/QUICKSTART-PROMPT.md) for the full prompt
293
293
 
294
294
  ## Command reference
295
295
 
296
+ Under each set, commands are listed A–Z. A short **typical path** (usual order) is called out where it helps.
297
+
296
298
  ### Code graph
297
299
 
300
+ **Typical path:** `vg build` → `vg status` → `vg ask` → `vg impact` → `vg share`
301
+
298
302
  | Command | Description |
299
303
  | --- | --- |
300
304
  | `vg ask "<question>"` | Query the map in natural language |
301
- | `vg benchmark` | Reproducible build + memory + token-reduction benchmark (honest estimates) |
302
305
  | `vg build [path]` | Build / update the code map (incremental, deterministic) |
303
306
  | `vg bundle` | Build an air-gapped bundle (grammars + graph + library catalog) |
304
307
  | `vg code "<instruction>"` | Propose a graph-grounded code edit (dry-run by default; `--apply --yes` to write) |
@@ -307,10 +310,10 @@ See [docs/QUICKSTART-PROMPT.md](./docs/QUICKSTART-PROMPT.md) for the full prompt
307
310
  | `vg facts <file>` | Deterministic facts for a node (contracts, invariants) |
308
311
  | `vg guide <file>` | Cited standards / practices for a node (free pack) |
309
312
  | `vg impact <file>` | What breaks if you change it — and the tests to run |
310
- | `vg install` / `vg uninstall` | Wire (or remove) **Vibgrate AI Context** + skill in your AI assistant |
313
+ | `vg install` / `vg uninstall` | Wire (or remove) **Vibgrate AI Context** + skill in your AI assistant (`--detect`, `--all`, `--list`) |
311
314
  | `vg lib <package>` | Version-correct, drift-annotated library docs |
312
315
  | `vg map` / `vg hubs` / `vg areas` / `vg oddities` | Map insights: overview, most-depended-on code, natural groupings, cross-area smells |
313
- | `vg models` / `vg models pull` | The local model fleet (Ollama / LM Studio / gguf), discovered offline; `pull` fetches one (needs `--yes`) |
316
+ | `vg models` | Code Modes (Spark / Flow / Forge) + local fleet (Ollama / LM Studio / gguf); `install` / `pull` by default (`--dry-run` to preview) |
314
317
  | `vg path <from> <to>` | How A connects to B (shortest path) |
315
318
  | `vg savings` | Local report of tokens/$ saved vs a grep baseline (estimates) |
316
319
  | `vg serve` | Start **Vibgrate AI Context** (local-first MCP: code map + drift + version-correct docs) |
@@ -321,27 +324,50 @@ See [docs/QUICKSTART-PROMPT.md](./docs/QUICKSTART-PROMPT.md) for the full prompt
321
324
  | `vg tree <file>` | Call tree rooted at a node |
322
325
  | `vg unknowns` | What the graph cannot resolve, ranked by blast radius |
323
326
 
324
- ### Drift reporting
327
+ ### Diagnostics, IDE & runtime
328
+
329
+ **Typical path:** `vg doctor` → `vg lsp` → `vg daemon`
330
+
331
+ | Command | Description |
332
+ | --- | --- |
333
+ | `vg daemon` | Local workspace daemon for multi-root graph sessions (IDE / agents): `status`, `ensure`, `publish`, `query`, `impact`, … |
334
+ | `vg doctor` | Read-only diagnosis: config, credentials (redacted), map freshness, hosted reachability, MCP launch |
335
+ | `vg lsp` | Language server (stdio) — engine behind Vibgrate for VS Code and other thin IDE clients |
336
+ | `vg policy` | Show production context-policy pin; `vg policy verify <file>` for signed learning patches |
337
+
338
+ ### Drift scoring & supply chain
339
+
340
+ **Typical path:** `vg init` → `vg scan` → `vg baseline` → `vg report` → `vg fix`
325
341
 
326
342
  | Command | Description |
327
343
  | --- | --- |
328
344
  | `vg baseline [path]` | Create a drift baseline |
329
345
  | `vg bisect <package> <constraint>` | The commit where a dependency crossed a version line (`--assert` to gate CI) |
330
346
  | `vg drift` | What is outdated across dependencies (offline; `--online` for currency) |
331
- | `vg dsn create` | Generate a DSN token |
347
+ | `vg evidence` | Signed, reproducible regulatory evidence (regime-neutral; CRA first) |
332
348
  | `vg fix` | Ranked, risk-tiered upgrade plans from the hosted planner — then apply the one you choose |
333
349
  | `vg init [path]` | Initialise config and `.vibgrate/` |
334
- | `vg login` / `vg logout` | Authenticate the CLI with your Vibgrate workspace (or clear stored credentials) |
335
- | `vg push` | Upload scan results to Vibgrate Cloud |
336
350
  | `vg report` | Generate a report from a scan artifact |
337
351
  | `vg sbom export` / `delta` / `vex` | Export CycloneDX/SPDX SBOM, diff two artifacts, or emit an OpenVEX document |
338
352
  | `vg scan [path]` | Scan for upgrade drift |
339
- | `vg scan --vulns` | Also detect known vulnerabilities (OSV; offline via `--package-manifest`) |
340
353
  | `vg scan --full` | Comprehensive scan: drift + vulnerabilities + a banned-dependency report |
341
354
  | `vg scan --push` | Scan and push results to Vibgrate Cloud |
355
+ | `vg scan --vulns` | Also detect known vulnerabilities (OSV; offline via `--package-manifest`) |
342
356
  | `vg update` | Check for and install updates |
343
357
  | `vg why <package>` | Who introduced a dependency, its version history, and any open vulnerabilities |
344
358
 
359
+ ### Workspace auth & cloud upload
360
+
361
+ Local scoring does not require this — nothing leaves your machine until you push.
362
+
363
+ **Typical path:** `vg login` → `vg dsn create` → `vg push` → `vg logout`
364
+
365
+ | Command | Description |
366
+ | --- | --- |
367
+ | `vg dsn create` | Generate a DSN token |
368
+ | `vg login` / `vg logout` | Authenticate the CLI with your Vibgrate workspace (or clear stored credentials) |
369
+ | `vg push` | Upload scan results to Vibgrate Cloud |
370
+
345
371
  ```bash
346
372
  vg scan [path] [--vulns] [--full] [--format text|json|sarif|md] [--out <file>] [--fail-on warn|error] \
347
373
  [--offline] [--package-manifest <file>] [--no-local-artifacts] [--max-privacy] \
@@ -0,0 +1,8 @@
1
+ export { baselineCommand, runBaseline } from './chunk-EX4PQT6W.js';
2
+ import './chunk-WGUL45AV.js';
3
+ import './chunk-RXP66R2E.js';
4
+ import './chunk-GI6W53LM.js';
5
+ import './chunk-CRAMOEBE.js';
6
+ import './chunk-DGUM43GV.js';
7
+ //# sourceMappingURL=baseline-TG4ATZGZ.js.map
8
+ //# sourceMappingURL=baseline-TG4ATZGZ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"baseline-BD3A7EXD.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"baseline-TG4ATZGZ.js"}
@@ -0,0 +1,82 @@
1
+ import { startVgdServer } from './chunk-TCDAZZNP.js';
2
+ import { vgdIsRunning, vgdRequest } from './chunk-PMYWZRRS.js';
3
+
4
+ // src/code/runtime-session.ts
5
+ async function startCodeRuntimeSession(options) {
6
+ const socketPath = options.socketPath;
7
+ const isRunning = options.isRunning ?? ((sp) => vgdIsRunning({ socketPath: sp }));
8
+ const request = options.request ?? vgdRequest;
9
+ const startServer = options.startServer ?? ((opts) => startVgdServer(opts));
10
+ try {
11
+ if (await isRunning(socketPath)) {
12
+ return await attachExisting(options.root, socketPath, request);
13
+ }
14
+ return await startOwned(options.root, socketPath, startServer, request);
15
+ } catch {
16
+ return noneSession();
17
+ }
18
+ }
19
+ async function attachExisting(root, socketPath, request) {
20
+ const clientOpts = { socketPath };
21
+ const reg = await request({ op: "register", root }, clientOpts);
22
+ if (!reg.ok || !("workspace" in reg)) return noneSession();
23
+ const status = await request({ op: "status" }, clientOpts).catch(() => null);
24
+ const pid = status && status.ok && "pid" in status ? status.pid : void 0;
25
+ let disposed = false;
26
+ return {
27
+ kind: "attached",
28
+ pid,
29
+ workspace: reg.workspace,
30
+ socketPath: status && status.ok && "socketPath" in status ? status.socketPath : socketPath,
31
+ label: pid != null ? `vgd ${pid}` : "vgd",
32
+ async dispose() {
33
+ if (disposed) return;
34
+ disposed = true;
35
+ try {
36
+ await request({ op: "unregister", root }, clientOpts);
37
+ } catch {
38
+ }
39
+ }
40
+ };
41
+ }
42
+ async function startOwned(root, socketPath, startServer, request) {
43
+ const server = await startServer({ socketPath });
44
+ const clientOpts = { socketPath: server.socketPath };
45
+ let workspace;
46
+ try {
47
+ const reg = await request({ op: "register", root }, clientOpts);
48
+ if (reg.ok && "workspace" in reg) workspace = reg.workspace;
49
+ } catch {
50
+ }
51
+ let disposed = false;
52
+ return {
53
+ kind: "owned",
54
+ pid: process.pid,
55
+ workspace,
56
+ socketPath: server.socketPath,
57
+ label: `vgd (session)`,
58
+ async dispose() {
59
+ if (disposed) return;
60
+ disposed = true;
61
+ try {
62
+ await server.close();
63
+ } catch {
64
+ }
65
+ }
66
+ };
67
+ }
68
+ function noneSession() {
69
+ return {
70
+ kind: "none",
71
+ pid: void 0,
72
+ workspace: void 0,
73
+ socketPath: void 0,
74
+ label: "",
75
+ async dispose() {
76
+ }
77
+ };
78
+ }
79
+
80
+ export { startCodeRuntimeSession };
81
+ //# sourceMappingURL=chunk-2MBL43EJ.js.map
82
+ //# sourceMappingURL=chunk-2MBL43EJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/code/runtime-session.ts"],"names":[],"mappings":"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","file":"chunk-2MBL43EJ.js","sourcesContent":["/**\n * Session boundary between VG Code and the Fusion Runtime daemon (`vgd`).\n *\n * Replaces the old {@link GraphProcess} (`vg serve` child) for the interactive\n * coding REPL. Behaviour:\n *\n * 1. If a local vgd is already running — register this workspace and leave the\n * daemon running when the session ends (unregister only).\n * 2. Otherwise — start an **in-process** vgd for the life of the session and\n * tear it down on dispose. No second OS process, no `vg serve` spawn.\n *\n * Never throws: a failure to attach degrades to “no runtime session” and the\n * agent continues with the in-process graph only (same safety as GraphProcess).\n */\n\nimport { startVgdServer, vgdIsRunning, vgdRequest, type VgdServer } from '../runtime/vgd/index.js';\nimport type { WorkspaceRecord } from '../runtime/vgd/protocol.js';\n\nexport type RuntimeSessionKind = 'attached' | 'owned' | 'none';\n\nexport interface RuntimeSessionOptions {\n root: string;\n /** Override socket path (tests). */\n socketPath?: string;\n /** Injectable connect/start hooks (tests). */\n isRunning?: (socketPath?: string) => Promise<boolean>;\n request?: typeof vgdRequest;\n startServer?: (opts: { socketPath?: string }) => Promise<VgdServer>;\n}\n\nexport interface CodeRuntimeSession {\n readonly kind: RuntimeSessionKind;\n /** Daemon pid when known (attached status or owned process). */\n readonly pid: number | undefined;\n readonly workspace: WorkspaceRecord | undefined;\n readonly socketPath: string | undefined;\n /** Human label for the REPL intro line. */\n readonly label: string;\n dispose(): Promise<void>;\n}\n\n/**\n * Attach VG Code to vgd for one coding session. Always resolves (never throws).\n */\nexport async function startCodeRuntimeSession(options: RuntimeSessionOptions): Promise<CodeRuntimeSession> {\n const socketPath = options.socketPath;\n const isRunning = options.isRunning ?? ((sp?: string) => vgdIsRunning({ socketPath: sp }));\n const request = options.request ?? vgdRequest;\n const startServer = options.startServer ?? ((opts: { socketPath?: string }) => startVgdServer(opts));\n\n try {\n if (await isRunning(socketPath)) {\n return await attachExisting(options.root, socketPath, request);\n }\n return await startOwned(options.root, socketPath, startServer, request);\n } catch {\n return noneSession();\n }\n}\n\nasync function attachExisting(\n root: string,\n socketPath: string | undefined,\n request: typeof vgdRequest,\n): Promise<CodeRuntimeSession> {\n const clientOpts = { socketPath };\n const reg = await request({ op: 'register', root }, clientOpts);\n if (!reg.ok || !('workspace' in reg)) return noneSession();\n const status = await request({ op: 'status' }, clientOpts).catch(() => null);\n const pid = status && status.ok && 'pid' in status ? status.pid : undefined;\n let disposed = false;\n return {\n kind: 'attached',\n pid,\n workspace: reg.workspace,\n socketPath: status && status.ok && 'socketPath' in status ? status.socketPath : socketPath,\n label: pid != null ? `vgd ${pid}` : 'vgd',\n async dispose() {\n if (disposed) return;\n disposed = true;\n try {\n await request({ op: 'unregister', root }, clientOpts);\n } catch {\n /* best-effort */\n }\n },\n };\n}\n\nasync function startOwned(\n root: string,\n socketPath: string | undefined,\n startServer: (opts: { socketPath?: string }) => Promise<VgdServer>,\n request: typeof vgdRequest,\n): Promise<CodeRuntimeSession> {\n const server = await startServer({ socketPath });\n const clientOpts = { socketPath: server.socketPath };\n let workspace: WorkspaceRecord | undefined;\n try {\n const reg = await request({ op: 'register', root }, clientOpts);\n if (reg.ok && 'workspace' in reg) workspace = reg.workspace;\n } catch {\n /* registry optional for an empty session */\n }\n let disposed = false;\n return {\n kind: 'owned',\n pid: process.pid,\n workspace,\n socketPath: server.socketPath,\n label: `vgd (session)`,\n async dispose() {\n if (disposed) return;\n disposed = true;\n try {\n await server.close();\n } catch {\n /* best-effort */\n }\n },\n };\n}\n\nfunction noneSession(): CodeRuntimeSession {\n return {\n kind: 'none',\n pid: undefined,\n workspace: undefined,\n socketPath: undefined,\n label: '',\n async dispose() {\n /* no-op */\n },\n };\n}\n"]}
@@ -0,0 +1,465 @@
1
+ import { stableStringify, serializeGraph, parseGraph, cacheDir } from './chunk-K3MZIVZW.js';
2
+ import { globalGraphPathForRef, globalGraphPath, repositoryStoreDir } from './chunk-BWPBB45M.js';
3
+ import { detectGitRef } from './chunk-BPF3YX2U.js';
4
+ import { __require } from './chunk-DGUM43GV.js';
5
+ import * as fs from 'fs';
6
+ import * as path from 'path';
7
+
8
+ // src/engine/report.ts
9
+ function renderReport(graph) {
10
+ const { meta, provenance, nodes, edges } = graph;
11
+ const lines = [];
12
+ lines.push("# Code Graph Report");
13
+ lines.push("");
14
+ lines.push(`Generated by \`vg\` ${provenance.version} \xB7 schema \`${graph.schemaVersion}\``);
15
+ lines.push("");
16
+ lines.push("## Summary");
17
+ lines.push("");
18
+ lines.push(`- **Nodes:** ${meta.counts.nodes.toLocaleString("en-US")}`);
19
+ lines.push(`- **Edges:** ${meta.counts.edges.toLocaleString("en-US")}`);
20
+ lines.push(`- **Areas:** ${meta.counts.areas.toLocaleString("en-US")}`);
21
+ lines.push(`- **Languages:** ${meta.languages.join(", ") || "\u2014"}`);
22
+ lines.push(`- **Clustering:** ${meta.cluster}`);
23
+ lines.push(`- **Resolvers:** ${provenance.resolver.join(", ")}`);
24
+ lines.push(`- **Edge kinds:** ${meta.edgeKinds.join(", ") || "\u2014"}`);
25
+ lines.push("");
26
+ const fileNodes = nodes.filter((n) => n.kind === "file");
27
+ const defsByFile = /* @__PURE__ */ new Map();
28
+ for (const n of nodes) {
29
+ if (n.kind === "file" || n.kind === "external") continue;
30
+ defsByFile.set(n.file, (defsByFile.get(n.file) ?? 0) + 1);
31
+ }
32
+ const topFiles = [...defsByFile.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).slice(0, 15);
33
+ if (topFiles.length) {
34
+ lines.push("## Largest files (by definitions)");
35
+ lines.push("");
36
+ lines.push("| File | Definitions |");
37
+ lines.push("| --- | ---: |");
38
+ for (const [file, count] of topFiles) lines.push(`| \`${file}\` | ${count} |`);
39
+ lines.push("");
40
+ }
41
+ const topNodes = nodes.filter((n) => n.kind !== "file" && n.kind !== "external").sort((a, b) => b.importance - a.importance || a.qualifiedName.localeCompare(b.qualifiedName)).slice(0, 15);
42
+ if (topNodes.length) {
43
+ lines.push("## Most-connected definitions");
44
+ lines.push("");
45
+ lines.push("| Symbol | Kind | File | Importance |");
46
+ lines.push("| --- | --- | --- | ---: |");
47
+ for (const n of topNodes) {
48
+ lines.push(
49
+ `| \`${n.qualifiedName}\` | ${n.kind} | \`${n.file}\`:${n.span.start} | ${n.importance.toFixed(3)} |`
50
+ );
51
+ }
52
+ lines.push("");
53
+ }
54
+ const byKind = /* @__PURE__ */ new Map();
55
+ for (const e of edges) byKind.set(e.kind, (byKind.get(e.kind) ?? 0) + 1);
56
+ if (byKind.size) {
57
+ lines.push("## Edges by kind");
58
+ lines.push("");
59
+ lines.push("| Kind | Count |");
60
+ lines.push("| --- | ---: |");
61
+ for (const [kind, count] of [...byKind.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {
62
+ lines.push(`| ${kind} | ${count} |`);
63
+ }
64
+ lines.push("");
65
+ }
66
+ lines.push("---");
67
+ lines.push("");
68
+ lines.push(`_Files: ${fileNodes.length} \xB7 Corpus: \`${provenance.corpusHash.slice(0, 16)}\u2026\`_`);
69
+ lines.push("");
70
+ return lines.join("\n");
71
+ }
72
+
73
+ // src/engine/html.ts
74
+ var EMBED_NODE_LIMIT = 5e3;
75
+ function renderHtml(graph) {
76
+ const top = graph.nodes.filter((n) => n.kind !== "file" && n.kind !== "external").sort((a, b) => b.importance - a.importance || a.qualifiedName.localeCompare(b.qualifiedName)).slice(0, 50);
77
+ const areas = [...graph.areas].sort((a, b) => b.size - a.size || a.id - b.id).slice(0, 40);
78
+ const rows = top.map(
79
+ (n) => `<tr><td><code>${esc(n.qualifiedName)}</code></td><td>${esc(n.kind)}</td><td><code>${esc(n.file)}</code>:${n.span.start}</td><td>${n.importance.toFixed(3)}</td></tr>`
80
+ ).join("\n");
81
+ const areaRows = areas.map(
82
+ (a) => `<tr><td>${a.id}</td><td><code>${esc(a.label)}</code></td><td>${a.size}</td><td>${a.cohesion.toFixed(3)}</td><td>${a.externalEdges}</td></tr>`
83
+ ).join("\n");
84
+ const large = graph.meta.counts.nodes > EMBED_NODE_LIMIT;
85
+ const embedPayload = large ? {
86
+ schemaVersion: graph.schemaVersion,
87
+ generatedAt: graph.generatedAt,
88
+ provenance: graph.provenance,
89
+ meta: graph.meta,
90
+ hubs: top.map((n) => ({
91
+ id: n.id,
92
+ name: n.qualifiedName,
93
+ kind: n.kind,
94
+ file: n.file,
95
+ line: n.span.start,
96
+ importance: n.importance,
97
+ area: n.area
98
+ })),
99
+ areas: areas.map((a) => ({
100
+ id: a.id,
101
+ label: a.label,
102
+ size: a.size,
103
+ cohesion: a.cohesion,
104
+ externalEdges: a.externalEdges
105
+ })),
106
+ note: `Full graph omitted (${graph.meta.counts.nodes} nodes > ${EMBED_NODE_LIMIT}). Use graph.json or .vibgrate/cache/graph.db.`
107
+ } : graph;
108
+ const embedded = stableStringify(embedPayload, 0);
109
+ const tier = graph.meta.analysisTier ?? "full";
110
+ return `<!doctype html>
111
+ <html lang="en">
112
+ <head>
113
+ <meta charset="utf-8">
114
+ <meta name="viewport" content="width=device-width, initial-scale=1">
115
+ <title>vg \xB7 code graph</title>
116
+ <style>
117
+ :root { color-scheme: light dark; }
118
+ body { font: 14px/1.5 system-ui, sans-serif; margin: 2rem auto; max-width: 60rem; padding: 0 1rem; }
119
+ h1 { font-size: 1.4rem; } h2 { font-size: 1.1rem; margin-top: 2rem; }
120
+ table { border-collapse: collapse; width: 100%; }
121
+ th, td { text-align: left; padding: 4px 8px; border-bottom: 1px solid #8884; }
122
+ td:last-child, th:last-child { text-align: right; }
123
+ .meta { color: #888; } code { font-size: 0.9em; }
124
+ .banner { background: #8882; padding: 0.6rem 0.8rem; border-radius: 6px; margin: 1rem 0; }
125
+ </style>
126
+ </head>
127
+ <body>
128
+ <h1>vg \xB7 code graph</h1>
129
+ <p class="meta">${graph.meta.counts.nodes} nodes \xB7 ${graph.meta.counts.edges} edges \xB7
130
+ ${graph.meta.counts.areas} areas \xB7 ${esc(graph.meta.languages.join(", ") || "\u2014")} \xB7
131
+ clustering: ${esc(graph.meta.cluster)} \xB7 tier: ${esc(tier)} \xB7 vg ${esc(graph.provenance.version)}</p>
132
+ ${large ? `<p class="banner">Large map (${graph.meta.counts.nodes} nodes): HTML shows hubs + areas only.
133
+ Full graph remains in <code>graph.json</code> / <code>.vibgrate/cache/graph.db</code> (query via <code>vg serve</code>).</p>` : ""}
134
+ <h2>Areas (subsystems)</h2>
135
+ <table>
136
+ <thead><tr><th>Id</th><th>Label</th><th>Size</th><th>Cohesion</th><th>External</th></tr></thead>
137
+ <tbody>
138
+ ${areaRows || '<tr><td colspan="5" class="meta">no areas</td></tr>'}
139
+ </tbody>
140
+ </table>
141
+ <h2>Most-connected definitions (hubs)</h2>
142
+ <table>
143
+ <thead><tr><th>Symbol</th><th>Kind</th><th>Location</th><th>Importance</th></tr></thead>
144
+ <tbody>
145
+ ${rows}
146
+ </tbody>
147
+ </table>
148
+ <p class="meta">${large ? "Summary payload" : "Full graph"} embedded below for tooling.</p>
149
+ <script type="application/json" id="vg-graph">
150
+ ${embedded}
151
+ </script>
152
+ </body>
153
+ </html>
154
+ `;
155
+ }
156
+ function esc(s) {
157
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
158
+ }
159
+
160
+ // src/engine/artifacts.ts
161
+ function vibgrateDir(root) {
162
+ return path.join(root, ".vibgrate");
163
+ }
164
+ function legacyGraphPath(root) {
165
+ return path.join(vibgrateDir(root), "graph.json");
166
+ }
167
+ function preferInRepoGraph(env = process.env) {
168
+ const v = env.VIBGRATE_GRAPH_IN_REPO?.trim().toLowerCase();
169
+ return v === "1" || v === "true" || v === "yes";
170
+ }
171
+ function defaultGraphPath(root, env = process.env) {
172
+ if (preferInRepoGraph(env)) return legacyGraphPath(root);
173
+ const { ref, kind } = detectGitRef(root);
174
+ if (kind !== "none" && ref) return globalGraphPathForRef(root, ref, env);
175
+ return globalGraphPath(root, "current", env);
176
+ }
177
+ function resolveGraphPath(root, override, env = process.env) {
178
+ if (override?.trim()) return path.resolve(override.trim());
179
+ if (preferInRepoGraph(env)) {
180
+ const legacy2 = legacyGraphPath(root);
181
+ if (fs.existsSync(legacy2)) return legacy2;
182
+ return legacy2;
183
+ }
184
+ const { ref, kind } = detectGitRef(root);
185
+ if (kind !== "none" && ref) {
186
+ const branchPath = globalGraphPathForRef(root, ref, env);
187
+ if (fs.existsSync(branchPath)) return branchPath;
188
+ }
189
+ const globalPath = globalGraphPath(root, "current", env);
190
+ if (fs.existsSync(globalPath)) return globalPath;
191
+ const legacy = legacyGraphPath(root);
192
+ if (fs.existsSync(legacy)) return legacy;
193
+ return defaultGraphPath(root, env);
194
+ }
195
+ var DEFAULT_GITIGNORE = [
196
+ "# Created once by vg \u2014 local graph artifacts stay out of git by default.",
197
+ "# Run `vg share` to commit the map for your team (it rewrites this file).",
198
+ "# vg never touches an existing .vibgrate/.gitignore: edit it (or leave it",
199
+ "# empty) to manage these ignores yourself.",
200
+ ".gitignore",
201
+ "cache/",
202
+ "graph.json",
203
+ "graph.html",
204
+ "GRAPH_REPORT.md",
205
+ "facts.jsonl",
206
+ "mcp-navigation.json"
207
+ ];
208
+ function ensureVibgrateGitignore(root) {
209
+ const file = path.join(vibgrateDir(root), ".gitignore");
210
+ if (fs.existsSync(file)) return;
211
+ fs.mkdirSync(vibgrateDir(root), { recursive: true });
212
+ fs.writeFileSync(file, `${DEFAULT_GITIGNORE.join("\n")}
213
+ `);
214
+ }
215
+ function companionArtifactDir(root, graphPath, env = process.env) {
216
+ const resolved = path.resolve(graphPath);
217
+ const legacy = path.resolve(legacyGraphPath(root));
218
+ if (resolved === legacy) return vibgrateDir(root);
219
+ const globalDefault = path.resolve(globalGraphPath(root, "current", env));
220
+ if (resolved === globalDefault) return repositoryStoreDir(root, env);
221
+ return path.dirname(resolved);
222
+ }
223
+ function writeArtifacts(graph, options) {
224
+ const graphPath = options.graphPath ?? defaultGraphPath(options.root);
225
+ const companions = companionArtifactDir(options.root, graphPath);
226
+ const inRepo = isPathInside(companions, options.root) || isPathInside(graphPath, options.root);
227
+ fs.mkdirSync(path.dirname(graphPath), { recursive: true });
228
+ fs.mkdirSync(companions, { recursive: true });
229
+ if (inRepo && isPathInside(companions, vibgrateDir(options.root))) {
230
+ ensureVibgrateGitignore(options.root);
231
+ } else if (path.resolve(graphPath) === path.resolve(legacyGraphPath(options.root))) {
232
+ ensureVibgrateGitignore(options.root);
233
+ }
234
+ const tmp = `${graphPath}.${process.pid}.tmp`;
235
+ try {
236
+ fs.writeFileSync(tmp, serializeGraph(graph));
237
+ fs.renameSync(tmp, graphPath);
238
+ } catch (err) {
239
+ fs.rmSync(tmp, { force: true });
240
+ throw err;
241
+ }
242
+ const written = { graphPath };
243
+ if (options.report !== false) {
244
+ const reportPath = path.join(companions, "GRAPH_REPORT.md");
245
+ fs.writeFileSync(reportPath, renderReport(graph));
246
+ written.reportPath = reportPath;
247
+ }
248
+ if (options.html !== false) {
249
+ const htmlPath = path.join(companions, "graph.html");
250
+ fs.writeFileSync(htmlPath, renderHtml(graph));
251
+ written.htmlPath = htmlPath;
252
+ }
253
+ if (graph.facts && graph.facts.length) {
254
+ const factsPath = path.join(companions, "facts.jsonl");
255
+ fs.writeFileSync(factsPath, graph.facts.map((f) => JSON.stringify(f)).join("\n") + "\n");
256
+ written.factsPath = factsPath;
257
+ }
258
+ return written;
259
+ }
260
+ function isPathInside(child, parent) {
261
+ const rel = path.relative(path.resolve(parent), path.resolve(child));
262
+ return rel === "" || !rel.startsWith("..") && !path.isAbsolute(rel);
263
+ }
264
+
265
+ // src/schema.ts
266
+ var SCHEMA_VERSION = "vg-graph/1.0";
267
+
268
+ // src/engine/index-db.ts
269
+ function indexDbPath(root) {
270
+ return path.join(cacheDir(root), "graph.db");
271
+ }
272
+ function writeGraphIndex(root, graph) {
273
+ const file = indexDbPath(root);
274
+ try {
275
+ const { DatabaseSync } = __require("sqlite");
276
+ fs.mkdirSync(path.dirname(file), { recursive: true });
277
+ const tmp = `${file}.${process.pid}.tmp`;
278
+ try {
279
+ if (fs.existsSync(tmp)) fs.unlinkSync(tmp);
280
+ } catch {
281
+ }
282
+ const db = new DatabaseSync(tmp);
283
+ db.exec(`
284
+ PRAGMA journal_mode = OFF;
285
+ PRAGMA synchronous = OFF;
286
+ CREATE TABLE meta (
287
+ key TEXT PRIMARY KEY,
288
+ value TEXT NOT NULL
289
+ );
290
+ CREATE TABLE nodes (
291
+ id TEXT PRIMARY KEY,
292
+ name TEXT NOT NULL,
293
+ qualified_name TEXT NOT NULL,
294
+ kind TEXT NOT NULL,
295
+ file TEXT NOT NULL,
296
+ line INTEGER NOT NULL,
297
+ importance REAL NOT NULL,
298
+ area INTEGER NOT NULL,
299
+ is_hub INTEGER NOT NULL,
300
+ lang TEXT NOT NULL,
301
+ json TEXT NOT NULL
302
+ );
303
+ CREATE TABLE edges (
304
+ id TEXT PRIMARY KEY,
305
+ kind TEXT NOT NULL,
306
+ src TEXT NOT NULL,
307
+ dst TEXT NOT NULL,
308
+ resolution TEXT NOT NULL,
309
+ confidence REAL NOT NULL,
310
+ epistemic TEXT NOT NULL,
311
+ json TEXT NOT NULL
312
+ );
313
+ CREATE TABLE areas (
314
+ id INTEGER PRIMARY KEY,
315
+ json TEXT NOT NULL
316
+ );
317
+ CREATE INDEX idx_nodes_name ON nodes(name);
318
+ CREATE INDEX idx_nodes_qn ON nodes(qualified_name);
319
+ CREATE INDEX idx_nodes_file ON nodes(file);
320
+ CREATE INDEX idx_edges_src ON edges(src);
321
+ CREATE INDEX idx_edges_dst ON edges(dst);
322
+ CREATE INDEX idx_edges_kind ON edges(kind);
323
+ `);
324
+ const insMeta = db.prepare("INSERT INTO meta(key, value) VALUES (?, ?)");
325
+ insMeta.run("corpusHash", graph.provenance.corpusHash);
326
+ insMeta.run("schemaVersion", graph.schemaVersion);
327
+ insMeta.run("generatedAt", graph.generatedAt);
328
+ insMeta.run("nodeCount", String(graph.nodes.length));
329
+ insMeta.run("edgeCount", String(graph.edges.length));
330
+ insMeta.run("analysisTier", graph.meta.analysisTier ?? "full");
331
+ insMeta.run("indexVersion", "vg-graph-index/2");
332
+ insMeta.run("graphMeta", JSON.stringify(graph.meta));
333
+ insMeta.run("graphProvenance", JSON.stringify(graph.provenance));
334
+ if (graph.facts) insMeta.run("factsJson", JSON.stringify(graph.facts));
335
+ if (graph.grounding) insMeta.run("groundingJson", JSON.stringify(graph.grounding));
336
+ const insNode = db.prepare(
337
+ `INSERT INTO nodes(id, name, qualified_name, kind, file, line, importance, area, is_hub, lang, json)
338
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
339
+ );
340
+ for (const n of graph.nodes) {
341
+ insNode.run(
342
+ n.id,
343
+ n.name,
344
+ n.qualifiedName,
345
+ n.kind,
346
+ n.file,
347
+ n.span.start,
348
+ n.importance,
349
+ n.area,
350
+ n.isHub ? 1 : 0,
351
+ n.lang,
352
+ JSON.stringify(n)
353
+ );
354
+ }
355
+ const insEdge = db.prepare(
356
+ `INSERT INTO edges(id, kind, src, dst, resolution, confidence, epistemic, json)
357
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
358
+ );
359
+ for (const e of graph.edges) {
360
+ insEdge.run(
361
+ e.id,
362
+ e.kind,
363
+ e.src,
364
+ e.dst,
365
+ e.resolution,
366
+ e.confidence,
367
+ e.epistemic ?? "observed",
368
+ JSON.stringify(e)
369
+ );
370
+ }
371
+ const insArea = db.prepare("INSERT INTO areas(id, json) VALUES (?, ?)");
372
+ for (const a of graph.areas) {
373
+ insArea.run(a.id, JSON.stringify(a));
374
+ }
375
+ db.close();
376
+ fs.renameSync(tmp, file);
377
+ return { path: file, nodes: graph.nodes.length, edges: graph.edges.length, ok: true };
378
+ } catch (err) {
379
+ return {
380
+ path: file,
381
+ nodes: 0,
382
+ edges: 0,
383
+ ok: false,
384
+ reason: err.message
385
+ };
386
+ }
387
+ }
388
+ function loadGraphFromIndex(root) {
389
+ const file = indexDbPath(root);
390
+ if (!fs.existsSync(file)) return null;
391
+ try {
392
+ const { DatabaseSync } = __require("sqlite");
393
+ const db = new DatabaseSync(file, { readOnly: true });
394
+ const metaRows = db.prepare("SELECT key, value FROM meta").all();
395
+ const meta = {};
396
+ for (const r of metaRows) meta[r.key] = r.value;
397
+ if (meta.indexVersion !== "vg-graph-index/2" || !meta.graphMeta || !meta.graphProvenance) {
398
+ db.close();
399
+ return null;
400
+ }
401
+ const nodeRows = db.prepare("SELECT json FROM nodes ORDER BY id").all();
402
+ const edgeRows = db.prepare("SELECT json FROM edges ORDER BY id").all();
403
+ const areaRows = db.prepare("SELECT json FROM areas ORDER BY id").all();
404
+ db.close();
405
+ const nodes = nodeRows.map((r) => JSON.parse(r.json));
406
+ const edges = edgeRows.map((r) => JSON.parse(r.json));
407
+ const areas = areaRows.map((r) => JSON.parse(r.json));
408
+ nodes.sort((a, b) => a.id.localeCompare(b.id));
409
+ edges.sort(
410
+ (a, b) => a.kind.localeCompare(b.kind) || a.src.localeCompare(b.src) || a.dst.localeCompare(b.dst)
411
+ );
412
+ areas.sort((a, b) => a.id - b.id);
413
+ const graph = {
414
+ schemaVersion: meta.schemaVersion || SCHEMA_VERSION,
415
+ generatedAt: meta.generatedAt ?? (/* @__PURE__ */ new Date(0)).toISOString(),
416
+ provenance: JSON.parse(meta.graphProvenance),
417
+ meta: JSON.parse(meta.graphMeta),
418
+ nodes,
419
+ edges,
420
+ areas
421
+ };
422
+ if (meta.factsJson) graph.facts = JSON.parse(meta.factsJson);
423
+ if (meta.groundingJson) graph.grounding = JSON.parse(meta.groundingJson);
424
+ for (const e of edges) {
425
+ if (!e.resolution) e.resolution = "heuristic";
426
+ if (!e.epistemic) e.epistemic = "observed";
427
+ }
428
+ return graph;
429
+ } catch {
430
+ return null;
431
+ }
432
+ }
433
+ function loadGraphPreferIndex(root, graphJsonPath) {
434
+ let jsonGraph = null;
435
+ if (fs.existsSync(graphJsonPath)) {
436
+ try {
437
+ jsonGraph = JSON.parse(fs.readFileSync(graphJsonPath, "utf8"));
438
+ } catch {
439
+ jsonGraph = null;
440
+ }
441
+ }
442
+ const fromIndex = loadGraphFromIndex(root);
443
+ if (fromIndex) {
444
+ if (!jsonGraph || fromIndex.provenance.corpusHash === jsonGraph.provenance.corpusHash) {
445
+ return { graph: fromIndex, source: "index" };
446
+ }
447
+ }
448
+ if (jsonGraph) return { graph: jsonGraph, source: "json" };
449
+ return null;
450
+ }
451
+
452
+ // src/engine/load.ts
453
+ function loadGraph(root, graphPath) {
454
+ const file = resolveGraphPath(root, graphPath);
455
+ if (!graphPath) {
456
+ const preferred = loadGraphPreferIndex(root, file);
457
+ if (preferred) return preferred.graph;
458
+ }
459
+ if (!fs.existsSync(file)) return null;
460
+ return parseGraph(fs.readFileSync(file, "utf8"));
461
+ }
462
+
463
+ export { SCHEMA_VERSION, defaultGraphPath, ensureVibgrateGitignore, legacyGraphPath, loadGraph, loadGraphPreferIndex, preferInRepoGraph, renderHtml, renderReport, resolveGraphPath, vibgrateDir, writeArtifacts, writeGraphIndex };
464
+ //# sourceMappingURL=chunk-2XQDMLKB.js.map
465
+ //# sourceMappingURL=chunk-2XQDMLKB.js.map