@vibgrate/cli 2026.819.3 → 2026.824.3

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 (103) hide show
  1. package/dist/{agent-AFMDB4GM.js → agent-6SJVWFPV.js} +12 -12
  2. package/dist/{agent-AFMDB4GM.js.map → agent-6SJVWFPV.js.map} +1 -1
  3. package/dist/{approvals-F2DJGPU7.js → approvals-5UBLBNJF.js} +5 -5
  4. package/dist/{approvals-F2DJGPU7.js.map → approvals-5UBLBNJF.js.map} +1 -1
  5. package/dist/{attach-XTX2Q3AD.js → attach-PSGCCJMA.js} +3 -3
  6. package/dist/{attach-XTX2Q3AD.js.map → attach-PSGCCJMA.js.map} +1 -1
  7. package/dist/{baseline-KTE2C3LW.js → baseline-HPXACNFU.js} +3 -3
  8. package/dist/{baseline-KTE2C3LW.js.map → baseline-HPXACNFU.js.map} +1 -1
  9. package/dist/{chunk-PQISIPYP.js → chunk-2IY24TTR.js} +3 -3
  10. package/dist/{chunk-PQISIPYP.js.map → chunk-2IY24TTR.js.map} +1 -1
  11. package/dist/{chunk-DMI4BMUL.js → chunk-3PNAQUZM.js} +3 -3
  12. package/dist/{chunk-DMI4BMUL.js.map → chunk-3PNAQUZM.js.map} +1 -1
  13. package/dist/{chunk-HVJHFTIV.js → chunk-4PDWV4AE.js} +10 -12
  14. package/dist/chunk-4PDWV4AE.js.map +1 -0
  15. package/dist/{chunk-SOAEPTSW.js → chunk-5QO2GFAE.js} +27 -23
  16. package/dist/chunk-5QO2GFAE.js.map +1 -0
  17. package/dist/chunk-AGOKTI77.js +6 -0
  18. package/dist/{chunk-MQJY4EQV.js.map → chunk-AGOKTI77.js.map} +1 -1
  19. package/dist/{chunk-UP2BR6TV.js → chunk-B5GOCQFB.js} +8 -8
  20. package/dist/{chunk-UP2BR6TV.js.map → chunk-B5GOCQFB.js.map} +1 -1
  21. package/dist/{chunk-5R4HYDTC.js → chunk-CJ2R3LVX.js} +4 -4
  22. package/dist/{chunk-5R4HYDTC.js.map → chunk-CJ2R3LVX.js.map} +1 -1
  23. package/dist/{chunk-C5AOLTQS.js → chunk-III7S75O.js} +53 -463
  24. package/dist/chunk-III7S75O.js.map +1 -0
  25. package/dist/{chunk-3SOJZ3VV.js → chunk-IKB5U3AH.js} +3 -3
  26. package/dist/{chunk-3SOJZ3VV.js.map → chunk-IKB5U3AH.js.map} +1 -1
  27. package/dist/{chunk-QOU2Q5L4.js → chunk-JL66EPZ4.js} +221 -10
  28. package/dist/chunk-JL66EPZ4.js.map +1 -0
  29. package/dist/{chunk-5RMME7PT.js → chunk-KBLKNR3V.js} +3 -3
  30. package/dist/{chunk-5RMME7PT.js.map → chunk-KBLKNR3V.js.map} +1 -1
  31. package/dist/{chunk-XAS45W3G.js → chunk-KRE7SXSA.js} +11 -12
  32. package/dist/chunk-KRE7SXSA.js.map +1 -0
  33. package/dist/{chunk-XZDI2N7M.js → chunk-LA4CETXN.js} +3 -3
  34. package/dist/{chunk-XZDI2N7M.js.map → chunk-LA4CETXN.js.map} +1 -1
  35. package/dist/{chunk-UEXDSWKN.js → chunk-LMHKIQA5.js} +3 -3
  36. package/dist/{chunk-UEXDSWKN.js.map → chunk-LMHKIQA5.js.map} +1 -1
  37. package/dist/{chunk-WI66PODG.js → chunk-M5QSBXA6.js} +17 -4
  38. package/dist/chunk-M5QSBXA6.js.map +1 -0
  39. package/dist/{chunk-EXFA7QFC.js → chunk-QP3P4V4I.js} +10 -8
  40. package/dist/chunk-QP3P4V4I.js.map +1 -0
  41. package/dist/{chunk-CEJIX3O7.js → chunk-RAEHWCN6.js} +6 -6
  42. package/dist/{chunk-CEJIX3O7.js.map → chunk-RAEHWCN6.js.map} +1 -1
  43. package/dist/{chunk-ARGYMFST.js → chunk-SGIFJIII.js} +3 -3
  44. package/dist/{chunk-ARGYMFST.js.map → chunk-SGIFJIII.js.map} +1 -1
  45. package/dist/{chunk-UAPA5AHX.js → chunk-TWWVTKA7.js} +35 -14
  46. package/dist/chunk-TWWVTKA7.js.map +1 -0
  47. package/dist/chunk-USW5WHUG.js +605 -0
  48. package/dist/chunk-USW5WHUG.js.map +1 -0
  49. package/dist/{chunk-3XMTRK24.js → chunk-UUNEUEPQ.js} +6 -6
  50. package/dist/{chunk-3XMTRK24.js.map → chunk-UUNEUEPQ.js.map} +1 -1
  51. package/dist/{chunk-HRYF4PWE.js → chunk-WATYIYWP.js} +3 -3
  52. package/dist/{chunk-HRYF4PWE.js.map → chunk-WATYIYWP.js.map} +1 -1
  53. package/dist/{chunk-TD4JAEMH.js → chunk-XHIWQGRE.js} +5 -5
  54. package/dist/{chunk-TD4JAEMH.js.map → chunk-XHIWQGRE.js.map} +1 -1
  55. package/dist/{chunk-HB3SONYP.js → chunk-YJ23GGAJ.js} +3 -3
  56. package/dist/{chunk-HB3SONYP.js.map → chunk-YJ23GGAJ.js.map} +1 -1
  57. package/dist/cli.js +377 -542
  58. package/dist/cli.js.map +1 -1
  59. package/dist/{daemon-VMQKIIYP.js → daemon-AEL5N4SJ.js} +9 -9
  60. package/dist/{daemon-VMQKIIYP.js.map → daemon-AEL5N4SJ.js.map} +1 -1
  61. package/dist/embed-worker-main.js +3 -3
  62. package/dist/{ensure-map-YIUJWMBK.js → ensure-map-YL5NR6UH.js} +14 -14
  63. package/dist/{ensure-map-YIUJWMBK.js.map → ensure-map-YL5NR6UH.js.map} +1 -1
  64. package/dist/{graph-backend-FDZUY4TR.js → graph-backend-LEPXFPXQ.js} +7 -7
  65. package/dist/{graph-backend-FDZUY4TR.js.map → graph-backend-LEPXFPXQ.js.map} +1 -1
  66. package/dist/index.d.ts +72 -130
  67. package/dist/index.js +14 -14
  68. package/dist/{interactive-CS4PGZPK.js → interactive-YJ37ZWTA.js} +26 -25
  69. package/dist/interactive-YJ37ZWTA.js.map +1 -0
  70. package/dist/load-LT6R73IZ.js +11 -0
  71. package/dist/{load-4EY64JJO.js.map → load-LT6R73IZ.js.map} +1 -1
  72. package/dist/parse-worker.js +3 -2
  73. package/dist/parse-worker.js.map +1 -1
  74. package/dist/{run-outcome-T7VDBNWB.js → run-outcome-YQBPYNEY.js} +5 -5
  75. package/dist/{run-outcome-T7VDBNWB.js.map → run-outcome-YQBPYNEY.js.map} +1 -1
  76. package/dist/{runtime-session-WZLVADPQ.js → runtime-session-JSH5UL7Z.js} +9 -9
  77. package/dist/{runtime-session-WZLVADPQ.js.map → runtime-session-JSH5UL7Z.js.map} +1 -1
  78. package/dist/{session-VPP2VGUN.js → session-3FLVZRMM.js} +8 -8
  79. package/dist/{session-VPP2VGUN.js.map → session-3FLVZRMM.js.map} +1 -1
  80. package/dist/{stream-json-XXCFN4MF.js → stream-json-VJ2O52CR.js} +12 -12
  81. package/dist/{stream-json-XXCFN4MF.js.map → stream-json-VJ2O52CR.js.map} +1 -1
  82. package/dist/version-VUTM46C5.js +4 -0
  83. package/dist/{version-2UBJ7N2I.js.map → version-VUTM46C5.js.map} +1 -1
  84. package/dist/{vg-mcp-bridge-H6GXYNKV.js → vg-mcp-bridge-UUMEOJSO.js} +8 -8
  85. package/dist/{vg-mcp-bridge-H6GXYNKV.js.map → vg-mcp-bridge-UUMEOJSO.js.map} +1 -1
  86. package/dist/{vgd-SBZO4ONQ.js → vgd-XFT574U6.js} +8 -8
  87. package/dist/vgd-XFT574U6.js.map +1 -0
  88. package/package.json +2 -1
  89. package/dist/chunk-C5AOLTQS.js.map +0 -1
  90. package/dist/chunk-EXFA7QFC.js.map +0 -1
  91. package/dist/chunk-HVJHFTIV.js.map +0 -1
  92. package/dist/chunk-MQJY4EQV.js +0 -6
  93. package/dist/chunk-QOU2Q5L4.js.map +0 -1
  94. package/dist/chunk-SOAEPTSW.js.map +0 -1
  95. package/dist/chunk-UAPA5AHX.js.map +0 -1
  96. package/dist/chunk-VEQA2FSM.js +0 -699
  97. package/dist/chunk-VEQA2FSM.js.map +0 -1
  98. package/dist/chunk-WI66PODG.js.map +0 -1
  99. package/dist/chunk-XAS45W3G.js.map +0 -1
  100. package/dist/interactive-CS4PGZPK.js.map +0 -1
  101. package/dist/load-4EY64JJO.js +0 -11
  102. package/dist/version-2UBJ7N2I.js +0 -4
  103. package/dist/vgd-SBZO4ONQ.js.map +0 -1
@@ -1,30 +1,30 @@
1
- export { CONTEXT_POLICY_VERSION, DISCOVERY_TOOLS, MUTATION_TOOLS, compact, compactWithModel, runAgent } from './chunk-SOAEPTSW.js';
1
+ export { CONTEXT_POLICY_VERSION, DISCOVERY_TOOLS, MUTATION_TOOLS, compact, compactWithModel, runAgent } from './chunk-5QO2GFAE.js';
2
2
  import './chunk-543E6WDJ.js';
3
- import './chunk-3SOJZ3VV.js';
4
- import './chunk-HB3SONYP.js';
3
+ import './chunk-IKB5U3AH.js';
4
+ import './chunk-YJ23GGAJ.js';
5
5
  import './chunk-SHD5TCZ5.js';
6
6
  import './chunk-3HNPVXUK.js';
7
7
  import './chunk-5HYCB55P.js';
8
8
  import './chunk-VIWZ4QT7.js';
9
- import './chunk-HRYF4PWE.js';
10
- export { summarizeCapsule } from './chunk-UAPA5AHX.js';
9
+ import './chunk-WATYIYWP.js';
10
+ export { summarizeCapsule } from './chunk-TWWVTKA7.js';
11
11
  import './chunk-EZ7UC5Y5.js';
12
12
  import './chunk-6BEBJCK4.js';
13
13
  import './chunk-J7LKEB2R.js';
14
- import './chunk-VEQA2FSM.js';
14
+ import './chunk-USW5WHUG.js';
15
15
  import './chunk-VHRSG6CF.js';
16
16
  import './chunk-6H2QV5DR.js';
17
- import './chunk-WI66PODG.js';
17
+ import './chunk-M5QSBXA6.js';
18
18
  import './chunk-T7RSQ5WD.js';
19
19
  import './chunk-6WRG7VDO.js';
20
- import './chunk-DMI4BMUL.js';
21
- import './chunk-C5AOLTQS.js';
20
+ import './chunk-3PNAQUZM.js';
21
+ import './chunk-III7S75O.js';
22
22
  import './chunk-MVPRPSXU.js';
23
23
  import './chunk-O3LABX6I.js';
24
- import './chunk-MQJY4EQV.js';
24
+ import './chunk-AGOKTI77.js';
25
25
  import './chunk-XP6UUCZZ.js';
26
26
  import './chunk-JFGYT6BI.js';
27
27
  import './chunk-XQNKCA2J.js';
28
28
  import './chunk-Z6ZWNWWR.js';
29
- //# sourceMappingURL=agent-AFMDB4GM.js.map
30
- //# sourceMappingURL=agent-AFMDB4GM.js.map
29
+ //# sourceMappingURL=agent-6SJVWFPV.js.map
30
+ //# sourceMappingURL=agent-6SJVWFPV.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-AFMDB4GM.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-6SJVWFPV.js"}
@@ -1,10 +1,10 @@
1
- export { addApprovalRule, approvalsPath, findMatchingRule, globMatch, loadApprovalRules, normalizeCommandPrefix, removeApprovalRule, ruleForAction, ruleKey, ruleLabel, saveApprovalRules } from './chunk-3SOJZ3VV.js';
2
- import './chunk-C5AOLTQS.js';
1
+ export { addApprovalRule, approvalsPath, findMatchingRule, globMatch, loadApprovalRules, normalizeCommandPrefix, removeApprovalRule, ruleForAction, ruleKey, ruleLabel, saveApprovalRules } from './chunk-IKB5U3AH.js';
2
+ import './chunk-III7S75O.js';
3
3
  import './chunk-O3LABX6I.js';
4
- import './chunk-MQJY4EQV.js';
4
+ import './chunk-AGOKTI77.js';
5
5
  import './chunk-XP6UUCZZ.js';
6
6
  import './chunk-JFGYT6BI.js';
7
7
  import './chunk-XQNKCA2J.js';
8
8
  import './chunk-Z6ZWNWWR.js';
9
- //# sourceMappingURL=approvals-F2DJGPU7.js.map
10
- //# sourceMappingURL=approvals-F2DJGPU7.js.map
9
+ //# sourceMappingURL=approvals-5UBLBNJF.js.map
10
+ //# sourceMappingURL=approvals-5UBLBNJF.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"approvals-F2DJGPU7.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"approvals-5UBLBNJF.js"}
@@ -1,4 +1,4 @@
1
- export { attachVgd, daemonDisabledReason } from './chunk-UEXDSWKN.js';
1
+ export { attachVgd, daemonDisabledReason } from './chunk-LMHKIQA5.js';
2
2
  import './chunk-A3WWRW7U.js';
3
3
  import './chunk-VHRSG6CF.js';
4
4
  import './chunk-6H2QV5DR.js';
@@ -6,5 +6,5 @@ import './chunk-XP6UUCZZ.js';
6
6
  import './chunk-JFGYT6BI.js';
7
7
  import './chunk-XQNKCA2J.js';
8
8
  import './chunk-Z6ZWNWWR.js';
9
- //# sourceMappingURL=attach-XTX2Q3AD.js.map
10
- //# sourceMappingURL=attach-XTX2Q3AD.js.map
9
+ //# sourceMappingURL=attach-PSGCCJMA.js.map
10
+ //# sourceMappingURL=attach-PSGCCJMA.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"attach-XTX2Q3AD.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"attach-PSGCCJMA.js"}
@@ -3,7 +3,7 @@ import './chunk-5UG4UHKU.js';
3
3
  import './chunk-PVNALGTG.js';
4
4
  import './chunk-CRAMOEBE.js';
5
5
  import './chunk-T7RSQ5WD.js';
6
- import './chunk-MQJY4EQV.js';
6
+ import './chunk-AGOKTI77.js';
7
7
  import './chunk-Z6ZWNWWR.js';
8
- //# sourceMappingURL=baseline-KTE2C3LW.js.map
9
- //# sourceMappingURL=baseline-KTE2C3LW.js.map
8
+ //# sourceMappingURL=baseline-HPXACNFU.js.map
9
+ //# sourceMappingURL=baseline-HPXACNFU.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"baseline-KTE2C3LW.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"baseline-HPXACNFU.js"}
@@ -3,7 +3,7 @@ import { vgdSocketPath } from './chunk-6H2QV5DR.js';
3
3
 
4
4
  // src/code/runtime-session.ts
5
5
  async function defaultEnsure(socketPath) {
6
- const { ensureVgd } = await import('./daemon-VMQKIIYP.js');
6
+ const { ensureVgd } = await import('./daemon-AEL5N4SJ.js');
7
7
  await ensureVgd(socketPath ?? vgdSocketPath());
8
8
  }
9
9
  async function startCodeRuntimeSession(options) {
@@ -56,5 +56,5 @@ function noneSession() {
56
56
  }
57
57
 
58
58
  export { startCodeRuntimeSession };
59
- //# sourceMappingURL=chunk-PQISIPYP.js.map
60
- //# sourceMappingURL=chunk-PQISIPYP.js.map
59
+ //# sourceMappingURL=chunk-2IY24TTR.js.map
60
+ //# sourceMappingURL=chunk-2IY24TTR.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/code/runtime-session.ts"],"names":[],"mappings":";;;;AA2CA,eAAe,cAAc,UAAA,EAAoC;AAC/D,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,MAAM,OAAO,sBAAuB,CAAA;AAC1D,EAAA,MAAM,SAAA,CAAU,UAAA,IAAc,aAAA,EAAe,CAAA;AAC/C;AAMA,eAAsB,wBAAwB,OAAA,EAA6D;AACzG,EAAA,MAAM,aAAa,OAAA,CAAQ,UAAA;AAC3B,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,KAAc,CAAC,OAAgB,YAAA,CAAa,EAAE,UAAA,EAAY,EAAA,EAAI,CAAA,CAAA;AACxF,EAAA,MAAM,OAAA,GAAU,QAAQ,OAAA,IAAW,UAAA;AACnC,EAAA,MAAM,MAAA,GAAS,QAAQ,YAAA,IAAgB,aAAA;AAEvC,EAAA,IAAI;AACF,IAAA,IAAI,CAAE,MAAM,SAAA,CAAU,UAAU,CAAA,EAAI;AAClC,MAAA,MAAM,OAAO,UAAU,CAAA;AAAA,IACzB;AACA,IAAA,OAAO,MAAM,cAAA,CAAe,OAAA,CAAQ,IAAA,EAAM,YAAY,OAAO,CAAA;AAAA,EAC/D,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,WAAA,EAAY;AAAA,EACrB;AACF;AAEA,eAAe,cAAA,CACb,IAAA,EACA,UAAA,EACA,OAAA,EAC6B;AAC7B,EAAA,MAAM,UAAA,GAAa,EAAE,UAAA,EAAW;AAChC,EAAA,MAAM,GAAA,GAAM,MAAM,OAAA,CAAQ,EAAE,IAAI,UAAA,EAAY,IAAA,IAAQ,UAAU,CAAA;AAC9D,EAAA,IAAI,CAAC,GAAA,CAAI,EAAA,IAAM,EAAE,WAAA,IAAe,GAAA,CAAA,SAAa,WAAA,EAAY;AACzD,EAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,EAAE,EAAA,EAAI,QAAA,EAAS,EAAG,UAAU,CAAA,CAAE,KAAA,CAAM,MAAM,IAAI,CAAA;AAC3E,EAAA,MAAM,MAAM,MAAA,IAAU,MAAA,CAAO,MAAM,KAAA,IAAS,MAAA,GAAS,OAAO,GAAA,GAAM,MAAA;AAClE,EAAA,IAAI,QAAA,GAAW,KAAA;AACf,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,UAAA;AAAA,IACN,GAAA;AAAA,IACA,WAAW,GAAA,CAAI,SAAA;AAAA,IACf,YAAY,MAAA,IAAU,MAAA,CAAO,MAAM,YAAA,IAAgB,MAAA,GAAS,OAAO,UAAA,GAAa,UAAA;AAAA,IAChF,KAAA,EAAO,GAAA,IAAO,IAAA,GAAO,CAAA,IAAA,EAAO,GAAG,CAAA,CAAA,GAAK,KAAA;AAAA,IACpC,MAAM,OAAA,GAAU;AACd,MAAA,IAAI,QAAA,EAAU;AACd,MAAA,QAAA,GAAW,IAAA;AACX,MAAA,IAAI;AACF,QAAA,MAAM,QAAQ,EAAE,EAAA,EAAI,YAAA,EAAc,IAAA,IAAQ,UAAU,CAAA;AAAA,MACtD,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,GACF;AACF;AAEA,SAAS,WAAA,GAAkC;AACzC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,MAAA;AAAA,IACN,GAAA,EAAK,MAAA;AAAA,IACL,SAAA,EAAW,MAAA;AAAA,IACX,UAAA,EAAY,MAAA;AAAA,IACZ,KAAA,EAAO,EAAA;AAAA,IACP,MAAM,OAAA,GAAU;AAAA,IAEhB;AAAA,GACF;AACF","file":"chunk-PQISIPYP.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. There is one standalone daemon:\n *\n * 1. If a local vgd is already running — register this workspace.\n * 2. Otherwise — `vg daemon ensure` (detached `daemon start`) and attach.\n *\n * The session never owns vgd. Dispose unregisters the workspace and leaves the\n * daemon running for other clients (VS Code, `vg`, the next `vg code`).\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 { vgdIsRunning, vgdRequest, vgdSocketPath } from '../runtime/vgd/index.js';\nimport type { WorkspaceRecord } from '../runtime/vgd/protocol.js';\n\nexport type RuntimeSessionKind = 'attached' | '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 /** Start the standalone daemon if needed (tests). Default: `ensureVgd`. */\n ensureDaemon?: (socketPath?: string) => Promise<void>;\n}\n\nexport interface CodeRuntimeSession {\n readonly kind: RuntimeSessionKind;\n /** Daemon pid when known. */\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\nasync function defaultEnsure(socketPath?: string): Promise<void> {\n const { ensureVgd } = await import('../commands/daemon.js');\n await ensureVgd(socketPath ?? vgdSocketPath());\n}\n\n/**\n * Attach VG Code to the standalone vgd for one coding session.\n * 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 ensure = options.ensureDaemon ?? defaultEnsure;\n\n try {\n if (!(await isRunning(socketPath))) {\n await ensure(socketPath);\n }\n return await attachExisting(options.root, socketPath, 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\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"]}
1
+ {"version":3,"sources":["../src/code/runtime-session.ts"],"names":[],"mappings":";;;;AA2CA,eAAe,cAAc,UAAA,EAAoC;AAC/D,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,MAAM,OAAO,sBAAuB,CAAA;AAC1D,EAAA,MAAM,SAAA,CAAU,UAAA,IAAc,aAAA,EAAe,CAAA;AAC/C;AAMA,eAAsB,wBAAwB,OAAA,EAA6D;AACzG,EAAA,MAAM,aAAa,OAAA,CAAQ,UAAA;AAC3B,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,KAAc,CAAC,OAAgB,YAAA,CAAa,EAAE,UAAA,EAAY,EAAA,EAAI,CAAA,CAAA;AACxF,EAAA,MAAM,OAAA,GAAU,QAAQ,OAAA,IAAW,UAAA;AACnC,EAAA,MAAM,MAAA,GAAS,QAAQ,YAAA,IAAgB,aAAA;AAEvC,EAAA,IAAI;AACF,IAAA,IAAI,CAAE,MAAM,SAAA,CAAU,UAAU,CAAA,EAAI;AAClC,MAAA,MAAM,OAAO,UAAU,CAAA;AAAA,IACzB;AACA,IAAA,OAAO,MAAM,cAAA,CAAe,OAAA,CAAQ,IAAA,EAAM,YAAY,OAAO,CAAA;AAAA,EAC/D,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,WAAA,EAAY;AAAA,EACrB;AACF;AAEA,eAAe,cAAA,CACb,IAAA,EACA,UAAA,EACA,OAAA,EAC6B;AAC7B,EAAA,MAAM,UAAA,GAAa,EAAE,UAAA,EAAW;AAChC,EAAA,MAAM,GAAA,GAAM,MAAM,OAAA,CAAQ,EAAE,IAAI,UAAA,EAAY,IAAA,IAAQ,UAAU,CAAA;AAC9D,EAAA,IAAI,CAAC,GAAA,CAAI,EAAA,IAAM,EAAE,WAAA,IAAe,GAAA,CAAA,SAAa,WAAA,EAAY;AACzD,EAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,EAAE,EAAA,EAAI,QAAA,EAAS,EAAG,UAAU,CAAA,CAAE,KAAA,CAAM,MAAM,IAAI,CAAA;AAC3E,EAAA,MAAM,MAAM,MAAA,IAAU,MAAA,CAAO,MAAM,KAAA,IAAS,MAAA,GAAS,OAAO,GAAA,GAAM,MAAA;AAClE,EAAA,IAAI,QAAA,GAAW,KAAA;AACf,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,UAAA;AAAA,IACN,GAAA;AAAA,IACA,WAAW,GAAA,CAAI,SAAA;AAAA,IACf,YAAY,MAAA,IAAU,MAAA,CAAO,MAAM,YAAA,IAAgB,MAAA,GAAS,OAAO,UAAA,GAAa,UAAA;AAAA,IAChF,KAAA,EAAO,GAAA,IAAO,IAAA,GAAO,CAAA,IAAA,EAAO,GAAG,CAAA,CAAA,GAAK,KAAA;AAAA,IACpC,MAAM,OAAA,GAAU;AACd,MAAA,IAAI,QAAA,EAAU;AACd,MAAA,QAAA,GAAW,IAAA;AACX,MAAA,IAAI;AACF,QAAA,MAAM,QAAQ,EAAE,EAAA,EAAI,YAAA,EAAc,IAAA,IAAQ,UAAU,CAAA;AAAA,MACtD,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,GACF;AACF;AAEA,SAAS,WAAA,GAAkC;AACzC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,MAAA;AAAA,IACN,GAAA,EAAK,MAAA;AAAA,IACL,SAAA,EAAW,MAAA;AAAA,IACX,UAAA,EAAY,MAAA;AAAA,IACZ,KAAA,EAAO,EAAA;AAAA,IACP,MAAM,OAAA,GAAU;AAAA,IAEhB;AAAA,GACF;AACF","file":"chunk-2IY24TTR.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. There is one standalone daemon:\n *\n * 1. If a local vgd is already running — register this workspace.\n * 2. Otherwise — `vg daemon ensure` (detached `daemon start`) and attach.\n *\n * The session never owns vgd. Dispose unregisters the workspace and leaves the\n * daemon running for other clients (VS Code, `vg`, the next `vg code`).\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 { vgdIsRunning, vgdRequest, vgdSocketPath } from '../runtime/vgd/index.js';\nimport type { WorkspaceRecord } from '../runtime/vgd/protocol.js';\n\nexport type RuntimeSessionKind = 'attached' | '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 /** Start the standalone daemon if needed (tests). Default: `ensureVgd`. */\n ensureDaemon?: (socketPath?: string) => Promise<void>;\n}\n\nexport interface CodeRuntimeSession {\n readonly kind: RuntimeSessionKind;\n /** Daemon pid when known. */\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\nasync function defaultEnsure(socketPath?: string): Promise<void> {\n const { ensureVgd } = await import('../commands/daemon.js');\n await ensureVgd(socketPath ?? vgdSocketPath());\n}\n\n/**\n * Attach VG Code to the standalone vgd for one coding session.\n * 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 ensure = options.ensureDaemon ?? defaultEnsure;\n\n try {\n if (!(await isRunning(socketPath))) {\n await ensure(socketPath);\n }\n return await attachExisting(options.root, socketPath, 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\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"]}
@@ -1,4 +1,4 @@
1
- import { resolveGraphPath } from './chunk-C5AOLTQS.js';
1
+ import { resolveGraphPath } from './chunk-III7S75O.js';
2
2
  import { cacheDir } from './chunk-MVPRPSXU.js';
3
3
  import { hashString } from './chunk-JFGYT6BI.js';
4
4
  import * as fs2 from 'fs';
@@ -614,5 +614,5 @@ function safe(id) {
614
614
  }
615
615
 
616
616
  export { acquireLock, clearModelCache, cosine, countPending, embedTargets, embeddingsCached, embeddingsPath, embeddingsPathFor, getNodeEmbeddings, isModelReady, loadEmbedder, modelCacheInfo, nodeEmbedText, readCachedVectors, releaseLock, resolveEmbedModel, unavailableMessage, withTimeout };
617
- //# sourceMappingURL=chunk-DMI4BMUL.js.map
618
- //# sourceMappingURL=chunk-DMI4BMUL.js.map
617
+ //# sourceMappingURL=chunk-3PNAQUZM.js.map
618
+ //# sourceMappingURL=chunk-3PNAQUZM.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/engine/lock.ts","../src/engine/embeddings.ts"],"names":["fs","path"],"mappings":"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","file":"chunk-DMI4BMUL.js","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\n/**\n * Cross-process single-writer lock (O_EXCL create), shared by the embedding\n * cache writer and the auto-refresh rebuild so two vg processes never write\n * the same repo-local artifact at once. A lock whose owning process is dead,\n * or that is older than `staleMs`, is presumed abandoned and reclaimed.\n */\n\n/** A lock older than this is presumed dead (crashed process). */\nexport const DEFAULT_LOCK_STALE_MS = 15 * 60 * 1000;\n\nfunction isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (e) {\n return (e as NodeJS.ErrnoException).code === 'EPERM'; // exists, just not ours to signal\n }\n}\n\nfunction lockIsStale(file: string, staleMs: number): boolean {\n try {\n const { pid, at } = JSON.parse(fs.readFileSync(file, 'utf8')) as { pid?: number; at?: number };\n if (typeof at === 'number' && Date.now() - at > staleMs) return true;\n if (typeof pid === 'number' && !isProcessAlive(pid)) return true;\n return false;\n } catch {\n return true; // unreadable/corrupt → reclaim it\n }\n}\n\n/**\n * True when a live process is holding this lock right now. Read-only: it never\n * reclaims, so a caller can politely stand down (the vgd semantic warm does\n * this rather than embedding a repo a `vg embed` child is already embedding).\n */\nexport function lockHeld(file: string, staleMs = DEFAULT_LOCK_STALE_MS): boolean {\n if (!fs.existsSync(file)) return false;\n return !lockIsStale(file, staleMs);\n}\n\n/** Take the lock (O_EXCL), reclaiming a stale/dead one. Returns success. */\nexport function acquireLock(file: string, staleMs = DEFAULT_LOCK_STALE_MS): boolean {\n const write = (): boolean => {\n try {\n fs.mkdirSync(path.dirname(file), { recursive: true });\n const fd = fs.openSync(file, 'wx');\n fs.writeFileSync(fd, JSON.stringify({ pid: process.pid, at: Date.now() }));\n fs.closeSync(fd);\n return true;\n } catch {\n return false;\n }\n };\n if (write()) return true;\n if (lockIsStale(file, staleMs)) {\n try {\n fs.rmSync(file, { force: true });\n } catch {\n /* another process may have reclaimed it */\n }\n return write();\n }\n return false;\n}\n\nexport function releaseLock(file: string): void {\n try {\n fs.rmSync(file, { force: true });\n } catch {\n /* best-effort */\n }\n}\n","import * as fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { hashString } from './hash.js';\nimport { cacheDir } from './cache.js';\nimport { resolveGraphPath } from './artifacts.js';\nimport { acquireLock, lockHeld, releaseLock } from './lock.js';\nimport type { GraphNode, VgGraph } from '../schema.js';\n\n/**\n * Local-embedding semantic search for `vg ask --semantic`/`--deep` (no API key).\n *\n * The embedding backend is OPTIONAL and lazily loaded (the vendored\n * `src/vendor/fastembed` dense backend over `onnxruntime-node`, local ONNX)\n * so the core install stays lean and `ask` never breaks:\n * if the backend or model isn't available it degrades to (prefix-fuzzy) lexical\n * search with a clear note. Per-repo vectors live in a binary `*.embeddings`\n * file **alongside the code map** (global store under Application Support /\n * XDG data, or `.vibgrate/embeddings` in-repo) — never model-named, never under\n * `.vibgrate/cache/`, and NEVER inside the committed `graph.json`, so the map\n * stays byte-deterministic. The model id is recorded inside the file header so\n * a model change still invalidates the cache without putting the name in the\n * path.\n *\n * `--local` disables the model download (semantic is skipped unless already\n * cached via an injected backend), keeping the air-gapped guarantee.\n */\n\nexport interface Embedder {\n /** Stable model id (recorded with cached vectors so a model change invalidates them). */\n id: string;\n /** Embed documents → unit-or-raw vectors (cosine handles normalization). */\n embed(texts: string[]): Promise<number[][]>;\n /** Embed a single query string. */\n embedQuery(text: string): Promise<number[]>;\n}\n\n/** Why semantic fell back to lexical — for calm, specific messaging. */\nexport type EmbedUnavailable = 'not-installed' | 'no-permission' | 'download-failed' | 'init-failed';\n\nexport interface LoadEmbedderOptions {\n local?: boolean; // --local: do not download a model\n model?: string; // override the embedding model id\n noDownload?: boolean; // only load if the model is already cached (never fetch)\n showDownloadProgress?: boolean; // let fastembed print its one-time download progress\n /**\n * Called (not thrown) when the backend can't load. `detail` carries the\n * underlying loader error when there is one, so a host can log something\n * actionable instead of a bare category.\n */\n onUnavailable?: (reason: EmbedUnavailable, detail?: string) => void;\n}\n\n/** The embedding model id in effect (explicit override → default). */\nexport function resolveEmbedModel(model?: string): string {\n return model ?? 'bge-small-en-v1.5';\n}\n\n/**\n * The **central, per-user** model cache — downloaded once per machine and shared\n * across every repo/folder (devs have many repos; the ~tens-of-MB model should\n * not re-download per project). Uses the XDG standard:\n * `$XDG_CACHE_HOME/vibgrate/models` (or `~/.cache/vibgrate/models`); relocate via\n * the standard `XDG_CACHE_HOME`. NB: fastembed's own default is the relative\n * `./local_cache`, i.e. per-CWD — which we override.\n */\nexport function modelCacheDir(): string {\n const base = process.env.XDG_CACHE_HOME || path.join(os.homedir(), '.cache');\n return path.join(base, 'vibgrate', 'models');\n}\n\n/** A machine-global marker written once the model has loaded successfully. */\nfunction modelReadyMarker(modelId: string): string {\n return path.join(modelCacheDir(), `.ready-${safe(modelId)}`);\n}\n\n/**\n * Whether the embedding model is already present on this machine (loaded at least\n * once), so it can be used with **no network**. Lets the background warm-up\n * trigger only when it won't surprise-download.\n */\nexport function isModelReady(modelId = resolveEmbedModel()): boolean {\n return fs.existsSync(modelReadyMarker(modelId));\n}\n\n/**\n * A calm, specific, actionable one-liner for why semantic isn't available right\n * now — built to reassure (lexical still works) and inform, never to alarm. No\n * stack traces, no scary words; always names the off switch and the fix.\n */\nexport function unavailableMessage(reason: EmbedUnavailable): string {\n switch (reason) {\n case 'no-permission':\n return `semantic search couldn't write its model cache at ${modelCacheDir()} — using fast lexical search instead. Relocate it with the standard XDG_CACHE_HOME, or run with --local to stay lexical quietly. (No admin/sudo is ever needed — the cache lives in your home folder.)`;\n case 'download-failed':\n return `the semantic model isn't downloaded yet and couldn't be fetched (offline?) — using fast lexical search. It'll try again next time; run with --local to keep lexical without retrying.`;\n case 'not-installed':\n return `the optional semantic backend isn't available here — using fast lexical search.`;\n case 'init-failed':\n default:\n return `the semantic model couldn't load — using fast lexical search.`;\n }\n}\n\nexport interface ModelCacheInfo {\n dir: string;\n present: boolean;\n bytes: number;\n}\n\n/** Where the shared model lives, whether it's present, and how big it is. */\nexport function modelCacheInfo(modelId = resolveEmbedModel()): ModelCacheInfo {\n const dir = modelCacheDir();\n return { dir, present: isModelReady(modelId) || fs.existsSync(dir), bytes: dirSize(dir) };\n}\n\n/** Remove the shared, re-downloadable model from the central cache. Returns bytes freed. */\nexport function clearModelCache(): number {\n const dir = modelCacheDir();\n const bytes = dirSize(dir);\n try {\n fs.rmSync(dir, { recursive: true, force: true });\n } catch {\n /* best-effort */\n }\n return bytes;\n}\n\nfunction dirSize(dir: string): number {\n let total = 0;\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return 0;\n }\n for (const e of entries) {\n const p = path.join(dir, e.name);\n if (e.isDirectory()) total += dirSize(p);\n else {\n try {\n total += fs.statSync(p).size;\n } catch {\n /* skip unreadable */\n }\n }\n }\n return total;\n}\n\nfunction isPermissionError(e: unknown): boolean {\n const code = (e as NodeJS.ErrnoException | undefined)?.code;\n return code === 'EACCES' || code === 'EPERM' || code === 'EROFS';\n}\n\n/**\n * Whether this repo already has a cached vector set for `modelId` — i.e. semantic\n * search has run here before, so the next run is fast (no first-use download/embed).\n * Lets `ask` show the one-time setup note only when it's actually warranted.\n * Checks the binary sidecar next to the map (and the legacy JSON path once).\n */\nexport function embeddingsCached(root: string, modelId: string): boolean {\n const file = vectorCachePath(root);\n if (fs.existsSync(file) && readCacheHeader(file)?.model === modelId) return true;\n // One-shot legacy: pre-binary caches lived under `.vibgrate/cache/embeddings-<model>.json`.\n return fs.existsSync(legacyVectorCachePath(root, modelId));\n}\n\n/**\n * Path of the binary embeddings file for this repo's current map — always named\n * `embeddings` (or `<snapshot>.embeddings` next to a branch-keyed graph), never\n * after the model. Exported for `vg embed --where` and tests.\n */\nexport function embeddingsPath(root: string): string {\n return vectorCachePath(root);\n}\n\n/** Sidecar path next to a map file: `…/branch-main.graph.json` → `…/branch-main.embeddings`. */\nexport function embeddingsPathFor(graphPath: string): string {\n // Branch-keyed global maps: `…/graphs/branch-main.graph.json` → `…/graphs/branch-main.embeddings`.\n if (graphPath.endsWith('.graph.json')) return `${graphPath.slice(0, -'.graph.json'.length)}.embeddings`;\n if (graphPath.endsWith('.graph.snap')) return `${graphPath.slice(0, -'.graph.snap'.length)}.embeddings`;\n // In-repo map is exactly `…/graph.json` (or `graph.snap`) → plain `…/embeddings`.\n const base = path.basename(graphPath);\n if (base === 'graph.json' || base === 'graph.snap') {\n return path.join(path.dirname(graphPath), 'embeddings');\n }\n if (graphPath.endsWith('.json')) return `${graphPath.slice(0, -5)}.embeddings`;\n if (graphPath.endsWith('.snap')) return `${graphPath.slice(0, -5)}.embeddings`;\n return `${graphPath}.embeddings`;\n}\n\n/**\n * Try to load the optional local embedding backend. Returns null (→ caller falls\n * back to lexical) when running `--local`, when the dependency isn't installed,\n * or when the model can't initialize.\n */\nexport async function loadEmbedder(options: LoadEmbedderOptions = {}): Promise<Embedder | null> {\n // `--local` forces the deterministic lexical floor with no model load/download\n // (air-gapped guarantee; also how tests stay offline).\n if (options.local) return null;\n const modelId = resolveEmbedModel(options.model);\n // noDownload (used by the background warm-up): never fetch — bail if not cached.\n if (options.noDownload && !isModelReady(modelId)) return null;\n const fail = (reason: EmbedUnavailable, detail?: string): null => {\n options.onUnavailable?.(reason, detail);\n return null;\n };\n\n // Lazy, optional dependency (native ONNX): loaded only for `vg ask`/`embed`,\n // never by build/verify, so the graph artifact stays deterministic.\n const backend = await importEmbedBackend();\n const mod: any = backend.mod;\n if (!mod?.FlagEmbedding) return fail('not-installed', backend.error);\n\n const cache = modelCacheDir(); // central, shared across all repos\n try {\n fs.mkdirSync(cache, { recursive: true });\n } catch (e) {\n return fail(isPermissionError(e) ? 'no-permission' : 'init-failed');\n }\n\n try {\n // First use fetches the model. A refused connection fails fast, but a\n // black-holing proxy (common on corporate networks) would hang the first\n // `vg ask` / MCP query_graph forever — bound the wait and fall back to\n // lexical instead. Cached loads are local disk and get the same generous\n // ceiling without ever hitting it.\n const model: any = await withTimeout(\n mod.FlagEmbedding.init({\n model: mapModel(mod, modelId),\n cacheDir: cache,\n showDownloadProgress: options.showDownloadProgress ?? false,\n }) as Promise<unknown>,\n embedInitTimeoutMs(),\n 'embedding model init timed out',\n );\n // Record machine-global readiness so future builds can warm up offline.\n try {\n fs.writeFileSync(modelReadyMarker(modelId), new Date(0).toISOString());\n } catch {\n /* marker is best-effort */\n }\n return {\n id: modelId,\n async embed(texts) {\n const out: number[][] = [];\n for await (const batch of model.embed(texts, 64)) {\n for (const v of batch) out.push(Array.from(v as ArrayLike<number>));\n }\n return out;\n },\n async embedQuery(text) {\n const v = await model.queryEmbed(text);\n return Array.from(v as ArrayLike<number>);\n },\n };\n } catch (e) {\n return fail(isPermissionError(e) ? 'no-permission' : 'download-failed', errText(e));\n }\n}\n\n/**\n * Import the optional embedding backend — the VENDORED dense backend\n * (src/vendor/fastembed). It still needs the optional native deps\n * (`onnxruntime-node`, `@anush008/tokenizers`, `tar`), which a host can supply\n * out-of-tree via `VIBGRATE_EMBEDDER_PATH` — a directory whose `node_modules`\n * contains them. Editor integrations use this when their bundled engine ships\n * without the native optional dependencies (the VS Code extension installs\n * them into its own storage on consent); the host dir wins over this package's\n * own dependency tree so the copies the user consented to are the ones that\n * load (see `ensureNativeDeps` in the vendored module).\n *\n * Legacy host contract: a host dir holding a whole upstream `fastembed`\n * install (what older extension versions set up) is still honored, and wins,\n * so an engine upgrade never breaks a backend the user already consented to.\n * Any resolution failure falls through — never throws.\n */\nasync function importEmbedBackend(): Promise<{ mod: any | null; error?: string }> {\n const hostDir = process.env.VIBGRATE_EMBEDDER_PATH;\n let error: string | undefined;\n if (hostDir) {\n try {\n const req = createRequire(path.join(hostDir, 'package.json'));\n let entry: string | null = null;\n try {\n entry = req.resolve('fastembed');\n } catch {\n // No upstream fastembed in the host dir — the normal state under the\n // current contract (the host supplies only the native deps, resolved\n // by the vendored backend below). Not an error worth reporting.\n }\n if (entry) {\n const mod: any = await import(pathToFileURL(entry).href);\n const resolved = unwrapBackend(mod);\n if (resolved) return { mod: resolved };\n error = `${hostDir}: fastembed loaded but exported no FlagEmbedding`;\n }\n } catch (e) {\n // Keep the reason. A host-supplied backend that resolves but won't load\n // (native binary built for another ABI, a half-extracted tree, a missing\n // transitive dep) is indistinguishable from \"never installed\" once the\n // error is dropped — and that is the one failure a user cannot act on.\n error = `${hostDir}: ${errText(e)}`;\n }\n }\n try {\n const mod: any = await import('../vendor/fastembed/index.js');\n const resolved = unwrapBackend(mod);\n if (!resolved) return { mod: null, error: error ?? 'embed backend exported no FlagEmbedding' };\n // Load the native deps now (host dir first — see the vendored module), so\n // a missing or broken install surfaces here as \"not-installed\" with the\n // real reason instead of failing later mid-init.\n if (typeof resolved.ensureNativeDeps === 'function') await resolved.ensureNativeDeps();\n return { mod: resolved };\n } catch (e) {\n return { mod: null, error: error ?? errText(e) };\n }\n}\n\n/** A CJS entry imported over ESM may nest its exports one or two `default`s deep. */\nfunction unwrapBackend(mod: any): any | null {\n for (const candidate of [mod, mod?.default, mod?.default?.default]) {\n if (candidate?.FlagEmbedding) return candidate;\n }\n return null;\n}\n\nfunction errText(e: unknown): string {\n const msg = e instanceof Error ? e.message : String(e);\n return msg.replace(/\\s+/g, ' ').trim().slice(0, 300);\n}\n\n/** Ceiling for the one-time model fetch/init; override via VG_EMBED_TIMEOUT_MS. */\nfunction embedInitTimeoutMs(): number {\n const n = Number(process.env.VG_EMBED_TIMEOUT_MS);\n return Number.isFinite(n) && n > 0 ? n : 60_000;\n}\n\n/** Reject `promise` if it hasn't settled within `ms` (the work itself is not cancelled). */\nexport async function withTimeout<T>(promise: Promise<T>, ms: number, message: string): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(message)), ms);\n timer.unref?.();\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n}\n\nfunction mapModel(mod: any, id: string): unknown {\n const m = mod.EmbeddingModel ?? {};\n if (/bge-small/i.test(id)) return m.BGESmallENV15 ?? m.BGESmallEN ?? id;\n if (/bge-base/i.test(id)) return m.BGEBaseENV15 ?? id;\n if (/all-minilm/i.test(id)) return m.AllMiniLML6V2 ?? id;\n return id;\n}\n\n/** Path segments that carry no semantic signal — dropped from embed context. */\nconst PATH_NOISE = new Set([\n 'src', 'app', 'apps', 'lib', 'libs', 'dist', 'build', 'out', 'index', 'main',\n 'packages', 'pkg', 'test', 'tests', '__tests__', 'spec', 'node_modules', 'internal',\n 'com', 'example', 'demo', 'java', 'net', 'org', 'www',\n]);\n\n/** Meaningful path context for a node: a couple of parent dirs + the filename stem. */\nfunction pathContext(file: string): string {\n const parts = file.split('/');\n const stem = (parts.pop() ?? '').replace(/\\.[^.]+$/, '');\n const dirs = parts.filter((p) => p && !PATH_NOISE.has(p.toLowerCase()));\n return [...dirs.slice(-2), stem].filter(Boolean).join(' ');\n}\n\n/**\n * The text we embed for a node. Alongside identity + signature we add the\n * strongest available signal — the node's **doc-comment / docstring** summary —\n * plus lightweight context already on the graph (file-path words, area label), so\n * a tersely-named symbol (`Table`, `NotificationJob`) a concept query can reach.\n *\n * `document` nodes (markdown, manifests, Docker, CI, OpenAPI, …) put the\n * scrubbed body in `doc` — that body is the primary embed signal so `vg ask`\n * can answer project-context questions, not only code symbols.\n */\nexport function nodeEmbedText(node: GraphNode, areaLabel?: string): string {\n if (node.kind === 'document') {\n const category = (node.signature ?? 'document').replace(/^document:/, '');\n // Category keywords help ops/config queries land on the right file type.\n const categoryHints: Record<string, string> = {\n manifest: 'package dependencies scripts install dependencies versions',\n docker: 'dockerfile container image build runtime',\n compose: 'docker-compose services containers networking volumes',\n ci: 'continuous integration github actions workflow pipeline test build deploy',\n 'build-config': 'typescript tsconfig bundler vite webpack eslint prettier test',\n 'api-contract': 'openapi swagger graphql protobuf api schema endpoints',\n 'task-runner': 'makefile justfile tasks build test run commands',\n workspace: 'monorepo workspace packages pnpm turbo nx',\n infra: 'deploy infrastructure kubernetes kubernetes terraform helm kubernetes',\n 'env-example': 'environment variables configuration secrets template',\n markdown: 'documentation readme guide',\n };\n const hint = categoryHints[category] ?? category;\n return [\n node.qualifiedName,\n 'document',\n category,\n hint,\n pathContext(node.file),\n (node.doc ?? '').slice(0, 5000),\n ]\n .filter(Boolean)\n .join('\\n');\n }\n return [node.qualifiedName, node.kind, node.signature ?? '', node.doc ?? '', pathContext(node.file), areaLabel ?? '']\n .filter(Boolean)\n .join(' ');\n}\n\nexport function cosine(a: number[], b: number[]): number {\n let dot = 0;\n let na = 0;\n let nb = 0;\n const n = Math.min(a.length, b.length);\n for (let i = 0; i < n; i++) {\n dot += a[i] * b[i];\n na += a[i] * a[i];\n nb += b[i] * b[i];\n }\n if (na === 0 || nb === 0) return 0;\n return dot / (Math.sqrt(na) * Math.sqrt(nb));\n}\n\ninterface EmbedCache {\n model: string;\n entries: Record<string, { hash: string; vec: number[] }>;\n}\n\n/** Reports embedding progress: how many of `total` nodes are done so far. */\nexport type EmbedProgress = (done: number, total: number) => void;\n\n/** Nodes embedded per chunk — bounds memory and gives progress granularity. */\nconst EMBED_CHUNK = 256;\n/** Min gap between incremental cache writes (ms) — caps IO on big repos. */\nconst CACHE_WRITE_INTERVAL_MS = 1500;\n\n/**\n * Binary embeddings format (local cache next to the map, never committed):\n *\n * MAGIC \"VGEMB1\\0\" · u16 version · u16 modelLen · model utf8 ·\n * u32 dims · u32 count ·\n * for each entry: u16 idLen · id · u16 hashLen · hash ·\n * then contiguous Float32LE vectors [count × dims]\n *\n * Why binary: a medium map (~4k nodes × 384 dims) is ~6 MB of floats but was\n * ~30 MB of JSON with full decimal text — slow to parse and noisy in source\n * control if it ever landed under the repo. The filename is always\n * `embeddings` / `<snapshot>.embeddings`; the model id lives only in the header.\n */\n/** 8-byte little-endian-friendly magic (same width as graph `VGSNAP1\\0`). */\nconst EMB_MAGIC = Buffer.from('VGEMB01\\0', 'latin1');\nconst EMB_VERSION = 1;\n\nfunction vectorCachePath(root: string): string {\n return embeddingsPathFor(resolveGraphPath(root));\n}\n\n/** Pre-binary path: `.vibgrate/cache/embeddings-<model>.json` (read once to migrate). */\nfunction legacyVectorCachePath(root: string, modelId: string): string {\n return path.join(cacheDir(root), `embeddings-${safe(modelId)}.json`);\n}\n\n/** One node's contribution to the semantic index: what is embedded, and its hash. */\nexport interface EmbedTarget {\n id: string;\n text: string;\n hash: string;\n}\n\n/**\n * The nodes the semantic index covers, and the exact text embedded for each.\n *\n * This is the single definition of \"what is in the index\", shared by the\n * on-disk cache (`vg embed`, `vg ask`) and vgd's in-memory slot index. They\n * used to compute it separately — vgd embedded *every* node with a shorter\n * text — so the two indexes described different things and vgd re-embedded\n * work the disk cache had already done. Keep them on this one function.\n */\nexport function embedTargets(graph: VgGraph): EmbedTarget[] {\n // Tolerant of a partial graph: vgd indexes whatever a client publishes, and\n // an `areas`-less map is a valid (if unlabelled) one.\n const areaLabel = new Map((graph.areas ?? []).map((a) => [a.id, a.label] as const));\n const targets: EmbedTarget[] = [];\n for (const n of graph.nodes ?? []) {\n // file/external stay out of the index; document (docs/env examples) are in.\n if (n.kind === 'file' || n.kind === 'external') continue;\n const text = nodeEmbedText(n, areaLabel.get(n.area));\n targets.push({ id: n.id, text, hash: hashString(text) });\n }\n return targets;\n}\n\n/**\n * How many searchable nodes still need embedding for `modelId` — cheap (hashes\n * the embed-text, reads only the cache; never loads the model). Lets the embed\n * command / background warm-up exit instantly when nothing changed.\n */\nexport function countPending(graph: VgGraph, root: string, modelId: string): number {\n const entries = loadCache(root, modelId).entries;\n let pending = 0;\n for (const t of embedTargets(graph)) {\n const cached = entries[t.id];\n if (!cached || cached.hash !== t.hash) pending++;\n }\n return pending;\n}\n\n/** What a reader (vgd) finds in this repo's on-disk vector cache. */\nexport interface CachedVectorRead {\n model: string;\n /** nodeId → vector, for every node whose cached hash still matches. */\n vectors: Map<string, number[]>;\n /** Targets the cache does not cover yet. */\n pending: EmbedTarget[];\n /** True while another process holds the cache's single-writer lock. */\n writerBusy: boolean;\n}\n\n/**\n * Read this repo's vector cache without loading the embedding backend.\n *\n * vgd warms its slot index from here first: on a repo `vg embed` has already\n * warmed, a slot goes `ready` in milliseconds with no worker and no duplicated\n * embedding. `writerBusy` reports the single-writer lock so vgd can stand down\n * while the `vg build` warm-up child is mid-run instead of racing it.\n */\nexport function readCachedVectors(\n graph: VgGraph,\n root: string,\n modelId = resolveEmbedModel(),\n): CachedVectorRead {\n const entries = loadCache(root, modelId).entries;\n const vectors = new Map<string, number[]>();\n const pending: EmbedTarget[] = [];\n for (const t of embedTargets(graph)) {\n const cached = entries[t.id];\n if (cached && cached.hash === t.hash && cached.vec.length > 0) vectors.set(t.id, cached.vec);\n else pending.push(t);\n }\n return { model: modelId, vectors, pending, writerBusy: lockHeld(`${vectorCachePath(root)}.lock`) };\n}\n\nfunction loadCache(root: string, modelId: string): EmbedCache {\n const file = vectorCachePath(root);\n const binary = readBinaryCache(file, modelId);\n if (binary) return binary;\n\n // Migrate legacy JSON if present (once) — keep working after upgrade without\n // re-embedding the whole repo.\n const legacy = legacyVectorCachePath(root, modelId);\n if (fs.existsSync(legacy)) {\n try {\n const loaded = JSON.parse(fs.readFileSync(legacy, 'utf8')) as EmbedCache;\n if (loaded.model === modelId && loaded.entries) {\n return { model: modelId, entries: loaded.entries };\n }\n } catch {\n /* treat as empty */\n }\n }\n return { model: modelId, entries: {} };\n}\n\ninterface EmbedHeader {\n model: string;\n dims: number;\n count: number;\n}\n\n/** Cheap header-only peek (no vectors) for `embeddingsCached` / diagnostics. */\nfunction readCacheHeader(file: string): EmbedHeader | null {\n let fd: number | null = null;\n try {\n fd = fs.openSync(file, 'r');\n const prefix = Buffer.alloc(8 + 2 + 2 + 512); // magic + ver + modelLen + model (capped)\n const n = fs.readSync(fd, prefix, 0, prefix.length, 0);\n if (n < EMB_MAGIC.length + 4 || !prefix.subarray(0, EMB_MAGIC.length).equals(EMB_MAGIC)) return null;\n let o = EMB_MAGIC.length;\n const version = prefix.readUInt16LE(o);\n o += 2;\n if (version !== EMB_VERSION) return null;\n const modelLen = prefix.readUInt16LE(o);\n o += 2;\n if (o + modelLen + 8 > n) {\n // model spills past our prefix — re-read exactly\n const full = Buffer.alloc(EMB_MAGIC.length + 2 + 2 + modelLen + 8);\n fs.readSync(fd, full, 0, full.length, 0);\n return parseHeaderPrefix(full);\n }\n return parseHeaderPrefix(prefix);\n } catch {\n return null;\n } finally {\n if (fd !== null) fs.closeSync(fd);\n }\n}\n\nfunction parseHeaderPrefix(buf: Buffer): EmbedHeader | null {\n try {\n if (!buf.subarray(0, EMB_MAGIC.length).equals(EMB_MAGIC)) return null;\n let o = EMB_MAGIC.length;\n if (buf.readUInt16LE(o) !== EMB_VERSION) return null;\n o += 2;\n const modelLen = buf.readUInt16LE(o);\n o += 2;\n if (o + modelLen + 8 > buf.length) return null;\n const model = buf.subarray(o, o + modelLen).toString('utf8');\n o += modelLen;\n const dims = buf.readUInt32LE(o);\n o += 4;\n const count = buf.readUInt32LE(o);\n return { model, dims, count };\n } catch {\n return null;\n }\n}\n\nfunction readBinaryCache(file: string, modelId: string): EmbedCache | null {\n if (!fs.existsSync(file)) return null;\n try {\n const buf = fs.readFileSync(file);\n if (buf.length < EMB_MAGIC.length + 4 || !buf.subarray(0, EMB_MAGIC.length).equals(EMB_MAGIC)) return null;\n let o = EMB_MAGIC.length;\n if (buf.readUInt16LE(o) !== EMB_VERSION) return null;\n o += 2;\n const modelLen = buf.readUInt16LE(o);\n o += 2;\n const model = buf.subarray(o, o + modelLen).toString('utf8');\n o += modelLen;\n if (model !== modelId) return null;\n const dims = buf.readUInt32LE(o);\n o += 4;\n const count = buf.readUInt32LE(o);\n o += 4;\n if (dims === 0 || count === 0) return { model, entries: {} };\n\n const ids: string[] = [];\n const hashes: string[] = [];\n for (let i = 0; i < count; i++) {\n const idLen = buf.readUInt16LE(o);\n o += 2;\n ids.push(buf.subarray(o, o + idLen).toString('utf8'));\n o += idLen;\n const hashLen = buf.readUInt16LE(o);\n o += 2;\n hashes.push(buf.subarray(o, o + hashLen).toString('utf8'));\n o += hashLen;\n }\n const floatsNeeded = count * dims;\n const bytesNeeded = floatsNeeded * 4;\n if (o + bytesNeeded > buf.length) return null;\n // Copy into a standalone ArrayBuffer so Float32Array views are safe after buf is GC'd.\n const floatBuf = Buffer.from(buf.subarray(o, o + bytesNeeded));\n const floats = new Float32Array(floatBuf.buffer, floatBuf.byteOffset, floatsNeeded);\n\n const entries: EmbedCache['entries'] = {};\n for (let i = 0; i < count; i++) {\n const start = i * dims;\n const vec = Array.from(floats.subarray(start, start + dims));\n entries[ids[i]!] = { hash: hashes[i]!, vec };\n }\n return { model, entries };\n } catch {\n return null;\n }\n}\n\nfunction writeBinaryCache(file: string, cache: EmbedCache): void {\n const ids = Object.keys(cache.entries);\n const count = ids.length;\n let dims = 0;\n for (const id of ids) {\n const d = cache.entries[id]!.vec.length;\n if (d > 0) {\n dims = d;\n break;\n }\n }\n // Empty or all-zero-dim cache: still write a valid header so \"cached\" is true.\n const modelBuf = Buffer.from(cache.model, 'utf8');\n if (modelBuf.length > 0xffff) throw new Error('embed model id too long');\n\n // Index size (ids + hashes)\n let indexBytes = 0;\n const idBufs: Buffer[] = [];\n const hashBufs: Buffer[] = [];\n for (const id of ids) {\n const ib = Buffer.from(id, 'utf8');\n const hb = Buffer.from(cache.entries[id]!.hash, 'utf8');\n if (ib.length > 0xffff || hb.length > 0xffff) throw new Error('embed entry key too long');\n idBufs.push(ib);\n hashBufs.push(hb);\n indexBytes += 2 + ib.length + 2 + hb.length;\n }\n\n const headerBytes = EMB_MAGIC.length + 2 + 2 + modelBuf.length + 4 + 4;\n const vecBytes = count * dims * 4;\n const out = Buffer.allocUnsafe(headerBytes + indexBytes + vecBytes);\n let o = 0;\n EMB_MAGIC.copy(out, o);\n o += EMB_MAGIC.length;\n out.writeUInt16LE(EMB_VERSION, o);\n o += 2;\n out.writeUInt16LE(modelBuf.length, o);\n o += 2;\n modelBuf.copy(out, o);\n o += modelBuf.length;\n out.writeUInt32LE(dims, o);\n o += 4;\n out.writeUInt32LE(count, o);\n o += 4;\n\n for (let i = 0; i < count; i++) {\n const ib = idBufs[i]!;\n const hb = hashBufs[i]!;\n out.writeUInt16LE(ib.length, o);\n o += 2;\n ib.copy(out, o);\n o += ib.length;\n out.writeUInt16LE(hb.length, o);\n o += 2;\n hb.copy(out, o);\n o += hb.length;\n }\n\n if (dims > 0 && count > 0) {\n const floats = new Float32Array(count * dims);\n for (let i = 0; i < count; i++) {\n const vec = cache.entries[ids[i]!]!.vec;\n const base = i * dims;\n for (let d = 0; d < dims; d++) floats[base + d] = vec[d] ?? 0;\n }\n Buffer.from(floats.buffer, floats.byteOffset, floats.byteLength).copy(out, o);\n }\n\n fs.mkdirSync(path.dirname(file), { recursive: true });\n const tmp = `${file}.tmp.${process.pid}`;\n fs.writeFileSync(tmp, out);\n fs.renameSync(tmp, file);\n}\n\n/** Best-effort drop of the old model-named JSON caches under `.vibgrate/cache/`. */\nfunction purgeLegacyJsonCaches(root: string): void {\n const dir = cacheDir(root);\n let names: string[];\n try {\n names = fs.readdirSync(dir);\n } catch {\n return;\n }\n for (const name of names) {\n if (/^embeddings-.+\\.json$/.test(name) || /^embeddings-.+\\.json\\.lock$/.test(name)) {\n try {\n fs.rmSync(path.join(dir, name), { force: true });\n } catch {\n /* best-effort */\n }\n }\n }\n}\n\n// Single-writer lock (shared helper — see ./lock.ts) so a foreground `ask`\n// and a background `embed` never both embed the same repo at once (which\n// would race on the cache file).\n\n/**\n * Node embeddings for the searchable (non-file/external) nodes, cache-backed:\n * only nodes whose embed-text changed are re-embedded. The first run embeds in\n * chunks, **persists the cache incrementally** (so an interrupted/timed-out run\n * resumes instead of wasting the work), and reports progress via `onProgress`.\n */\nexport async function getNodeEmbeddings(\n graph: VgGraph,\n embedder: Embedder,\n root: string,\n onProgress?: EmbedProgress,\n): Promise<Map<string, number[]>> {\n const file = vectorCachePath(root);\n const cache = loadCache(root, embedder.id);\n\n // Includes document nodes (markdown/txt/env examples) so ask can retrieve docs.\n const targets = embedTargets(graph);\n const toEmbed: EmbedTarget[] = [];\n const vectors = new Map<string, number[]>();\n for (const t of targets) {\n const cached = cache.entries[t.id];\n if (cached && cached.hash === t.hash) vectors.set(t.id, cached.vec);\n else toEmbed.push(t);\n }\n\n // Atomic write (temp + rename) so a reader never sees a half-written cache.\n const persist = (): void => {\n try {\n writeBinaryCache(file, cache);\n purgeLegacyJsonCaches(root);\n } catch {\n /* cache write best-effort */\n }\n };\n\n if (toEmbed.length) {\n // Single-writer: if another process (e.g. a background warm-up) is already\n // embedding this repo, don't double-work or race the cache — return what's\n // cached so far (lexical floor still applies). It will be complete next run.\n const lock = `${file}.lock`;\n if (!acquireLock(lock)) return vectors;\n try {\n onProgress?.(0, toEmbed.length);\n let lastWrite = Date.now();\n for (let i = 0; i < toEmbed.length; i += EMBED_CHUNK) {\n const slice = toEmbed.slice(i, i + EMBED_CHUNK);\n const vecs = await embedder.embed(slice.map((t) => t.text));\n slice.forEach((t, j) => {\n const vec = vecs[j] ?? [];\n vectors.set(t.id, vec);\n cache.entries[t.id] = { hash: t.hash, vec };\n });\n onProgress?.(Math.min(i + EMBED_CHUNK, toEmbed.length), toEmbed.length);\n // Persist periodically so a crash/timeout resumes from here next run.\n if (Date.now() - lastWrite >= CACHE_WRITE_INTERVAL_MS) {\n persist();\n lastWrite = Date.now();\n }\n }\n // prune entries for nodes no longer present, then a final authoritative write\n const live = new Set(targets.map((t) => t.id));\n for (const id of Object.keys(cache.entries)) if (!live.has(id)) delete cache.entries[id];\n persist();\n } finally {\n releaseLock(lock);\n }\n } else if (!fs.existsSync(file) && Object.keys(cache.entries).length > 0) {\n // Migrating from legacy JSON with a full hit set — rewrite as binary once\n // so the next run never reads the old path again.\n persist();\n }\n\n return vectors;\n}\n\nfunction safe(id: string): string {\n return id.replace(/[^a-z0-9.-]+/gi, '_');\n}\n"]}
1
+ {"version":3,"sources":["../src/engine/lock.ts","../src/engine/embeddings.ts"],"names":["fs","path"],"mappings":"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","file":"chunk-3PNAQUZM.js","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\n/**\n * Cross-process single-writer lock (O_EXCL create), shared by the embedding\n * cache writer and the auto-refresh rebuild so two vg processes never write\n * the same repo-local artifact at once. A lock whose owning process is dead,\n * or that is older than `staleMs`, is presumed abandoned and reclaimed.\n */\n\n/** A lock older than this is presumed dead (crashed process). */\nexport const DEFAULT_LOCK_STALE_MS = 15 * 60 * 1000;\n\nfunction isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (e) {\n return (e as NodeJS.ErrnoException).code === 'EPERM'; // exists, just not ours to signal\n }\n}\n\nfunction lockIsStale(file: string, staleMs: number): boolean {\n try {\n const { pid, at } = JSON.parse(fs.readFileSync(file, 'utf8')) as { pid?: number; at?: number };\n if (typeof at === 'number' && Date.now() - at > staleMs) return true;\n if (typeof pid === 'number' && !isProcessAlive(pid)) return true;\n return false;\n } catch {\n return true; // unreadable/corrupt → reclaim it\n }\n}\n\n/**\n * True when a live process is holding this lock right now. Read-only: it never\n * reclaims, so a caller can politely stand down (the vgd semantic warm does\n * this rather than embedding a repo a `vg embed` child is already embedding).\n */\nexport function lockHeld(file: string, staleMs = DEFAULT_LOCK_STALE_MS): boolean {\n if (!fs.existsSync(file)) return false;\n return !lockIsStale(file, staleMs);\n}\n\n/** Take the lock (O_EXCL), reclaiming a stale/dead one. Returns success. */\nexport function acquireLock(file: string, staleMs = DEFAULT_LOCK_STALE_MS): boolean {\n const write = (): boolean => {\n try {\n fs.mkdirSync(path.dirname(file), { recursive: true });\n const fd = fs.openSync(file, 'wx');\n fs.writeFileSync(fd, JSON.stringify({ pid: process.pid, at: Date.now() }));\n fs.closeSync(fd);\n return true;\n } catch {\n return false;\n }\n };\n if (write()) return true;\n if (lockIsStale(file, staleMs)) {\n try {\n fs.rmSync(file, { force: true });\n } catch {\n /* another process may have reclaimed it */\n }\n return write();\n }\n return false;\n}\n\nexport function releaseLock(file: string): void {\n try {\n fs.rmSync(file, { force: true });\n } catch {\n /* best-effort */\n }\n}\n","import * as fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { hashString } from './hash.js';\nimport { cacheDir } from './cache.js';\nimport { resolveGraphPath } from './artifacts.js';\nimport { acquireLock, lockHeld, releaseLock } from './lock.js';\nimport type { GraphNode, VgGraph } from '../schema.js';\n\n/**\n * Local-embedding semantic search for `vg ask --semantic`/`--deep` (no API key).\n *\n * The embedding backend is OPTIONAL and lazily loaded (the vendored\n * `src/vendor/fastembed` dense backend over `onnxruntime-node`, local ONNX)\n * so the core install stays lean and `ask` never breaks:\n * if the backend or model isn't available it degrades to (prefix-fuzzy) lexical\n * search with a clear note. Per-repo vectors live in a binary `*.embeddings`\n * file **alongside the code map** (global store under Application Support /\n * XDG data, or `.vibgrate/embeddings` in-repo) — never model-named, never under\n * `.vibgrate/cache/`, and NEVER inside the committed `graph.json`, so the map\n * stays byte-deterministic. The model id is recorded inside the file header so\n * a model change still invalidates the cache without putting the name in the\n * path.\n *\n * `--local` disables the model download (semantic is skipped unless already\n * cached via an injected backend), keeping the air-gapped guarantee.\n */\n\nexport interface Embedder {\n /** Stable model id (recorded with cached vectors so a model change invalidates them). */\n id: string;\n /** Embed documents → unit-or-raw vectors (cosine handles normalization). */\n embed(texts: string[]): Promise<number[][]>;\n /** Embed a single query string. */\n embedQuery(text: string): Promise<number[]>;\n}\n\n/** Why semantic fell back to lexical — for calm, specific messaging. */\nexport type EmbedUnavailable = 'not-installed' | 'no-permission' | 'download-failed' | 'init-failed';\n\nexport interface LoadEmbedderOptions {\n local?: boolean; // --local: do not download a model\n model?: string; // override the embedding model id\n noDownload?: boolean; // only load if the model is already cached (never fetch)\n showDownloadProgress?: boolean; // let fastembed print its one-time download progress\n /**\n * Called (not thrown) when the backend can't load. `detail` carries the\n * underlying loader error when there is one, so a host can log something\n * actionable instead of a bare category.\n */\n onUnavailable?: (reason: EmbedUnavailable, detail?: string) => void;\n}\n\n/** The embedding model id in effect (explicit override → default). */\nexport function resolveEmbedModel(model?: string): string {\n return model ?? 'bge-small-en-v1.5';\n}\n\n/**\n * The **central, per-user** model cache — downloaded once per machine and shared\n * across every repo/folder (devs have many repos; the ~tens-of-MB model should\n * not re-download per project). Uses the XDG standard:\n * `$XDG_CACHE_HOME/vibgrate/models` (or `~/.cache/vibgrate/models`); relocate via\n * the standard `XDG_CACHE_HOME`. NB: fastembed's own default is the relative\n * `./local_cache`, i.e. per-CWD — which we override.\n */\nexport function modelCacheDir(): string {\n const base = process.env.XDG_CACHE_HOME || path.join(os.homedir(), '.cache');\n return path.join(base, 'vibgrate', 'models');\n}\n\n/** A machine-global marker written once the model has loaded successfully. */\nfunction modelReadyMarker(modelId: string): string {\n return path.join(modelCacheDir(), `.ready-${safe(modelId)}`);\n}\n\n/**\n * Whether the embedding model is already present on this machine (loaded at least\n * once), so it can be used with **no network**. Lets the background warm-up\n * trigger only when it won't surprise-download.\n */\nexport function isModelReady(modelId = resolveEmbedModel()): boolean {\n return fs.existsSync(modelReadyMarker(modelId));\n}\n\n/**\n * A calm, specific, actionable one-liner for why semantic isn't available right\n * now — built to reassure (lexical still works) and inform, never to alarm. No\n * stack traces, no scary words; always names the off switch and the fix.\n */\nexport function unavailableMessage(reason: EmbedUnavailable): string {\n switch (reason) {\n case 'no-permission':\n return `semantic search couldn't write its model cache at ${modelCacheDir()} — using fast lexical search instead. Relocate it with the standard XDG_CACHE_HOME, or run with --local to stay lexical quietly. (No admin/sudo is ever needed — the cache lives in your home folder.)`;\n case 'download-failed':\n return `the semantic model isn't downloaded yet and couldn't be fetched (offline?) — using fast lexical search. It'll try again next time; run with --local to keep lexical without retrying.`;\n case 'not-installed':\n return `the optional semantic backend isn't available here — using fast lexical search.`;\n case 'init-failed':\n default:\n return `the semantic model couldn't load — using fast lexical search.`;\n }\n}\n\nexport interface ModelCacheInfo {\n dir: string;\n present: boolean;\n bytes: number;\n}\n\n/** Where the shared model lives, whether it's present, and how big it is. */\nexport function modelCacheInfo(modelId = resolveEmbedModel()): ModelCacheInfo {\n const dir = modelCacheDir();\n return { dir, present: isModelReady(modelId) || fs.existsSync(dir), bytes: dirSize(dir) };\n}\n\n/** Remove the shared, re-downloadable model from the central cache. Returns bytes freed. */\nexport function clearModelCache(): number {\n const dir = modelCacheDir();\n const bytes = dirSize(dir);\n try {\n fs.rmSync(dir, { recursive: true, force: true });\n } catch {\n /* best-effort */\n }\n return bytes;\n}\n\nfunction dirSize(dir: string): number {\n let total = 0;\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return 0;\n }\n for (const e of entries) {\n const p = path.join(dir, e.name);\n if (e.isDirectory()) total += dirSize(p);\n else {\n try {\n total += fs.statSync(p).size;\n } catch {\n /* skip unreadable */\n }\n }\n }\n return total;\n}\n\nfunction isPermissionError(e: unknown): boolean {\n const code = (e as NodeJS.ErrnoException | undefined)?.code;\n return code === 'EACCES' || code === 'EPERM' || code === 'EROFS';\n}\n\n/**\n * Whether this repo already has a cached vector set for `modelId` — i.e. semantic\n * search has run here before, so the next run is fast (no first-use download/embed).\n * Lets `ask` show the one-time setup note only when it's actually warranted.\n * Checks the binary sidecar next to the map (and the legacy JSON path once).\n */\nexport function embeddingsCached(root: string, modelId: string): boolean {\n const file = vectorCachePath(root);\n if (fs.existsSync(file) && readCacheHeader(file)?.model === modelId) return true;\n // One-shot legacy: pre-binary caches lived under `.vibgrate/cache/embeddings-<model>.json`.\n return fs.existsSync(legacyVectorCachePath(root, modelId));\n}\n\n/**\n * Path of the binary embeddings file for this repo's current map — always named\n * `embeddings` (or `<snapshot>.embeddings` next to a branch-keyed graph), never\n * after the model. Exported for `vg embed --where` and tests.\n */\nexport function embeddingsPath(root: string): string {\n return vectorCachePath(root);\n}\n\n/** Sidecar path next to a map file: `…/branch-main.graph.json` → `…/branch-main.embeddings`. */\nexport function embeddingsPathFor(graphPath: string): string {\n // Branch-keyed global maps: `…/graphs/branch-main.graph.json` → `…/graphs/branch-main.embeddings`.\n if (graphPath.endsWith('.graph.json')) return `${graphPath.slice(0, -'.graph.json'.length)}.embeddings`;\n if (graphPath.endsWith('.graph.snap')) return `${graphPath.slice(0, -'.graph.snap'.length)}.embeddings`;\n // In-repo map is exactly `…/graph.json` (or `graph.snap`) → plain `…/embeddings`.\n const base = path.basename(graphPath);\n if (base === 'graph.json' || base === 'graph.snap') {\n return path.join(path.dirname(graphPath), 'embeddings');\n }\n if (graphPath.endsWith('.json')) return `${graphPath.slice(0, -5)}.embeddings`;\n if (graphPath.endsWith('.snap')) return `${graphPath.slice(0, -5)}.embeddings`;\n return `${graphPath}.embeddings`;\n}\n\n/**\n * Try to load the optional local embedding backend. Returns null (→ caller falls\n * back to lexical) when running `--local`, when the dependency isn't installed,\n * or when the model can't initialize.\n */\nexport async function loadEmbedder(options: LoadEmbedderOptions = {}): Promise<Embedder | null> {\n // `--local` forces the deterministic lexical floor with no model load/download\n // (air-gapped guarantee; also how tests stay offline).\n if (options.local) return null;\n const modelId = resolveEmbedModel(options.model);\n // noDownload (used by the background warm-up): never fetch — bail if not cached.\n if (options.noDownload && !isModelReady(modelId)) return null;\n const fail = (reason: EmbedUnavailable, detail?: string): null => {\n options.onUnavailable?.(reason, detail);\n return null;\n };\n\n // Lazy, optional dependency (native ONNX): loaded only for `vg ask`/`embed`,\n // never by build/verify, so the graph artifact stays deterministic.\n const backend = await importEmbedBackend();\n const mod: any = backend.mod;\n if (!mod?.FlagEmbedding) return fail('not-installed', backend.error);\n\n const cache = modelCacheDir(); // central, shared across all repos\n try {\n fs.mkdirSync(cache, { recursive: true });\n } catch (e) {\n return fail(isPermissionError(e) ? 'no-permission' : 'init-failed');\n }\n\n try {\n // First use fetches the model. A refused connection fails fast, but a\n // black-holing proxy (common on corporate networks) would hang the first\n // `vg ask` / MCP query_graph forever — bound the wait and fall back to\n // lexical instead. Cached loads are local disk and get the same generous\n // ceiling without ever hitting it.\n const model: any = await withTimeout(\n mod.FlagEmbedding.init({\n model: mapModel(mod, modelId),\n cacheDir: cache,\n showDownloadProgress: options.showDownloadProgress ?? false,\n }) as Promise<unknown>,\n embedInitTimeoutMs(),\n 'embedding model init timed out',\n );\n // Record machine-global readiness so future builds can warm up offline.\n try {\n fs.writeFileSync(modelReadyMarker(modelId), new Date(0).toISOString());\n } catch {\n /* marker is best-effort */\n }\n return {\n id: modelId,\n async embed(texts) {\n const out: number[][] = [];\n for await (const batch of model.embed(texts, 64)) {\n for (const v of batch) out.push(Array.from(v as ArrayLike<number>));\n }\n return out;\n },\n async embedQuery(text) {\n const v = await model.queryEmbed(text);\n return Array.from(v as ArrayLike<number>);\n },\n };\n } catch (e) {\n return fail(isPermissionError(e) ? 'no-permission' : 'download-failed', errText(e));\n }\n}\n\n/**\n * Import the optional embedding backend — the VENDORED dense backend\n * (src/vendor/fastembed). It still needs the optional native deps\n * (`onnxruntime-node`, `@anush008/tokenizers`, `tar`), which a host can supply\n * out-of-tree via `VIBGRATE_EMBEDDER_PATH` — a directory whose `node_modules`\n * contains them. Editor integrations use this when their bundled engine ships\n * without the native optional dependencies (the VS Code extension installs\n * them into its own storage on consent); the host dir wins over this package's\n * own dependency tree so the copies the user consented to are the ones that\n * load (see `ensureNativeDeps` in the vendored module).\n *\n * Legacy host contract: a host dir holding a whole upstream `fastembed`\n * install (what older extension versions set up) is still honored, and wins,\n * so an engine upgrade never breaks a backend the user already consented to.\n * Any resolution failure falls through — never throws.\n */\nasync function importEmbedBackend(): Promise<{ mod: any | null; error?: string }> {\n const hostDir = process.env.VIBGRATE_EMBEDDER_PATH;\n let error: string | undefined;\n if (hostDir) {\n try {\n const req = createRequire(path.join(hostDir, 'package.json'));\n let entry: string | null = null;\n try {\n entry = req.resolve('fastembed');\n } catch {\n // No upstream fastembed in the host dir — the normal state under the\n // current contract (the host supplies only the native deps, resolved\n // by the vendored backend below). Not an error worth reporting.\n }\n if (entry) {\n const mod: any = await import(pathToFileURL(entry).href);\n const resolved = unwrapBackend(mod);\n if (resolved) return { mod: resolved };\n error = `${hostDir}: fastembed loaded but exported no FlagEmbedding`;\n }\n } catch (e) {\n // Keep the reason. A host-supplied backend that resolves but won't load\n // (native binary built for another ABI, a half-extracted tree, a missing\n // transitive dep) is indistinguishable from \"never installed\" once the\n // error is dropped — and that is the one failure a user cannot act on.\n error = `${hostDir}: ${errText(e)}`;\n }\n }\n try {\n const mod: any = await import('../vendor/fastembed/index.js');\n const resolved = unwrapBackend(mod);\n if (!resolved) return { mod: null, error: error ?? 'embed backend exported no FlagEmbedding' };\n // Load the native deps now (host dir first — see the vendored module), so\n // a missing or broken install surfaces here as \"not-installed\" with the\n // real reason instead of failing later mid-init.\n if (typeof resolved.ensureNativeDeps === 'function') await resolved.ensureNativeDeps();\n return { mod: resolved };\n } catch (e) {\n return { mod: null, error: error ?? errText(e) };\n }\n}\n\n/** A CJS entry imported over ESM may nest its exports one or two `default`s deep. */\nfunction unwrapBackend(mod: any): any | null {\n for (const candidate of [mod, mod?.default, mod?.default?.default]) {\n if (candidate?.FlagEmbedding) return candidate;\n }\n return null;\n}\n\nfunction errText(e: unknown): string {\n const msg = e instanceof Error ? e.message : String(e);\n return msg.replace(/\\s+/g, ' ').trim().slice(0, 300);\n}\n\n/** Ceiling for the one-time model fetch/init; override via VG_EMBED_TIMEOUT_MS. */\nfunction embedInitTimeoutMs(): number {\n const n = Number(process.env.VG_EMBED_TIMEOUT_MS);\n return Number.isFinite(n) && n > 0 ? n : 60_000;\n}\n\n/** Reject `promise` if it hasn't settled within `ms` (the work itself is not cancelled). */\nexport async function withTimeout<T>(promise: Promise<T>, ms: number, message: string): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(message)), ms);\n timer.unref?.();\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n}\n\nfunction mapModel(mod: any, id: string): unknown {\n const m = mod.EmbeddingModel ?? {};\n if (/bge-small/i.test(id)) return m.BGESmallENV15 ?? m.BGESmallEN ?? id;\n if (/bge-base/i.test(id)) return m.BGEBaseENV15 ?? id;\n if (/all-minilm/i.test(id)) return m.AllMiniLML6V2 ?? id;\n return id;\n}\n\n/** Path segments that carry no semantic signal — dropped from embed context. */\nconst PATH_NOISE = new Set([\n 'src', 'app', 'apps', 'lib', 'libs', 'dist', 'build', 'out', 'index', 'main',\n 'packages', 'pkg', 'test', 'tests', '__tests__', 'spec', 'node_modules', 'internal',\n 'com', 'example', 'demo', 'java', 'net', 'org', 'www',\n]);\n\n/** Meaningful path context for a node: a couple of parent dirs + the filename stem. */\nfunction pathContext(file: string): string {\n const parts = file.split('/');\n const stem = (parts.pop() ?? '').replace(/\\.[^.]+$/, '');\n const dirs = parts.filter((p) => p && !PATH_NOISE.has(p.toLowerCase()));\n return [...dirs.slice(-2), stem].filter(Boolean).join(' ');\n}\n\n/**\n * The text we embed for a node. Alongside identity + signature we add the\n * strongest available signal — the node's **doc-comment / docstring** summary —\n * plus lightweight context already on the graph (file-path words, area label), so\n * a tersely-named symbol (`Table`, `NotificationJob`) a concept query can reach.\n *\n * `document` nodes (markdown, manifests, Docker, CI, OpenAPI, …) put the\n * scrubbed body in `doc` — that body is the primary embed signal so `vg ask`\n * can answer project-context questions, not only code symbols.\n */\nexport function nodeEmbedText(node: GraphNode, areaLabel?: string): string {\n if (node.kind === 'document') {\n const category = (node.signature ?? 'document').replace(/^document:/, '');\n // Category keywords help ops/config queries land on the right file type.\n const categoryHints: Record<string, string> = {\n manifest: 'package dependencies scripts install dependencies versions',\n docker: 'dockerfile container image build runtime',\n compose: 'docker-compose services containers networking volumes',\n ci: 'continuous integration github actions workflow pipeline test build deploy',\n 'build-config': 'typescript tsconfig bundler vite webpack eslint prettier test',\n 'api-contract': 'openapi swagger graphql protobuf api schema endpoints',\n 'task-runner': 'makefile justfile tasks build test run commands',\n workspace: 'monorepo workspace packages pnpm turbo nx',\n infra: 'deploy infrastructure kubernetes kubernetes terraform helm kubernetes',\n 'env-example': 'environment variables configuration secrets template',\n markdown: 'documentation readme guide',\n };\n const hint = categoryHints[category] ?? category;\n return [\n node.qualifiedName,\n 'document',\n category,\n hint,\n pathContext(node.file),\n (node.doc ?? '').slice(0, 5000),\n ]\n .filter(Boolean)\n .join('\\n');\n }\n return [node.qualifiedName, node.kind, node.signature ?? '', node.doc ?? '', pathContext(node.file), areaLabel ?? '']\n .filter(Boolean)\n .join(' ');\n}\n\nexport function cosine(a: number[], b: number[]): number {\n let dot = 0;\n let na = 0;\n let nb = 0;\n const n = Math.min(a.length, b.length);\n for (let i = 0; i < n; i++) {\n dot += a[i] * b[i];\n na += a[i] * a[i];\n nb += b[i] * b[i];\n }\n if (na === 0 || nb === 0) return 0;\n return dot / (Math.sqrt(na) * Math.sqrt(nb));\n}\n\ninterface EmbedCache {\n model: string;\n entries: Record<string, { hash: string; vec: number[] }>;\n}\n\n/** Reports embedding progress: how many of `total` nodes are done so far. */\nexport type EmbedProgress = (done: number, total: number) => void;\n\n/** Nodes embedded per chunk — bounds memory and gives progress granularity. */\nconst EMBED_CHUNK = 256;\n/** Min gap between incremental cache writes (ms) — caps IO on big repos. */\nconst CACHE_WRITE_INTERVAL_MS = 1500;\n\n/**\n * Binary embeddings format (local cache next to the map, never committed):\n *\n * MAGIC \"VGEMB1\\0\" · u16 version · u16 modelLen · model utf8 ·\n * u32 dims · u32 count ·\n * for each entry: u16 idLen · id · u16 hashLen · hash ·\n * then contiguous Float32LE vectors [count × dims]\n *\n * Why binary: a medium map (~4k nodes × 384 dims) is ~6 MB of floats but was\n * ~30 MB of JSON with full decimal text — slow to parse and noisy in source\n * control if it ever landed under the repo. The filename is always\n * `embeddings` / `<snapshot>.embeddings`; the model id lives only in the header.\n */\n/** 8-byte little-endian-friendly magic (same width as graph `VGSNAP1\\0`). */\nconst EMB_MAGIC = Buffer.from('VGEMB01\\0', 'latin1');\nconst EMB_VERSION = 1;\n\nfunction vectorCachePath(root: string): string {\n return embeddingsPathFor(resolveGraphPath(root));\n}\n\n/** Pre-binary path: `.vibgrate/cache/embeddings-<model>.json` (read once to migrate). */\nfunction legacyVectorCachePath(root: string, modelId: string): string {\n return path.join(cacheDir(root), `embeddings-${safe(modelId)}.json`);\n}\n\n/** One node's contribution to the semantic index: what is embedded, and its hash. */\nexport interface EmbedTarget {\n id: string;\n text: string;\n hash: string;\n}\n\n/**\n * The nodes the semantic index covers, and the exact text embedded for each.\n *\n * This is the single definition of \"what is in the index\", shared by the\n * on-disk cache (`vg embed`, `vg ask`) and vgd's in-memory slot index. They\n * used to compute it separately — vgd embedded *every* node with a shorter\n * text — so the two indexes described different things and vgd re-embedded\n * work the disk cache had already done. Keep them on this one function.\n */\nexport function embedTargets(graph: VgGraph): EmbedTarget[] {\n // Tolerant of a partial graph: vgd indexes whatever a client publishes, and\n // an `areas`-less map is a valid (if unlabelled) one.\n const areaLabel = new Map((graph.areas ?? []).map((a) => [a.id, a.label] as const));\n const targets: EmbedTarget[] = [];\n for (const n of graph.nodes ?? []) {\n // file/external stay out of the index; document (docs/env examples) are in.\n if (n.kind === 'file' || n.kind === 'external') continue;\n const text = nodeEmbedText(n, areaLabel.get(n.area));\n targets.push({ id: n.id, text, hash: hashString(text) });\n }\n return targets;\n}\n\n/**\n * How many searchable nodes still need embedding for `modelId` — cheap (hashes\n * the embed-text, reads only the cache; never loads the model). Lets the embed\n * command / background warm-up exit instantly when nothing changed.\n */\nexport function countPending(graph: VgGraph, root: string, modelId: string): number {\n const entries = loadCache(root, modelId).entries;\n let pending = 0;\n for (const t of embedTargets(graph)) {\n const cached = entries[t.id];\n if (!cached || cached.hash !== t.hash) pending++;\n }\n return pending;\n}\n\n/** What a reader (vgd) finds in this repo's on-disk vector cache. */\nexport interface CachedVectorRead {\n model: string;\n /** nodeId → vector, for every node whose cached hash still matches. */\n vectors: Map<string, number[]>;\n /** Targets the cache does not cover yet. */\n pending: EmbedTarget[];\n /** True while another process holds the cache's single-writer lock. */\n writerBusy: boolean;\n}\n\n/**\n * Read this repo's vector cache without loading the embedding backend.\n *\n * vgd warms its slot index from here first: on a repo `vg embed` has already\n * warmed, a slot goes `ready` in milliseconds with no worker and no duplicated\n * embedding. `writerBusy` reports the single-writer lock so vgd can stand down\n * while the `vg build` warm-up child is mid-run instead of racing it.\n */\nexport function readCachedVectors(\n graph: VgGraph,\n root: string,\n modelId = resolveEmbedModel(),\n): CachedVectorRead {\n const entries = loadCache(root, modelId).entries;\n const vectors = new Map<string, number[]>();\n const pending: EmbedTarget[] = [];\n for (const t of embedTargets(graph)) {\n const cached = entries[t.id];\n if (cached && cached.hash === t.hash && cached.vec.length > 0) vectors.set(t.id, cached.vec);\n else pending.push(t);\n }\n return { model: modelId, vectors, pending, writerBusy: lockHeld(`${vectorCachePath(root)}.lock`) };\n}\n\nfunction loadCache(root: string, modelId: string): EmbedCache {\n const file = vectorCachePath(root);\n const binary = readBinaryCache(file, modelId);\n if (binary) return binary;\n\n // Migrate legacy JSON if present (once) — keep working after upgrade without\n // re-embedding the whole repo.\n const legacy = legacyVectorCachePath(root, modelId);\n if (fs.existsSync(legacy)) {\n try {\n const loaded = JSON.parse(fs.readFileSync(legacy, 'utf8')) as EmbedCache;\n if (loaded.model === modelId && loaded.entries) {\n return { model: modelId, entries: loaded.entries };\n }\n } catch {\n /* treat as empty */\n }\n }\n return { model: modelId, entries: {} };\n}\n\ninterface EmbedHeader {\n model: string;\n dims: number;\n count: number;\n}\n\n/** Cheap header-only peek (no vectors) for `embeddingsCached` / diagnostics. */\nfunction readCacheHeader(file: string): EmbedHeader | null {\n let fd: number | null = null;\n try {\n fd = fs.openSync(file, 'r');\n const prefix = Buffer.alloc(8 + 2 + 2 + 512); // magic + ver + modelLen + model (capped)\n const n = fs.readSync(fd, prefix, 0, prefix.length, 0);\n if (n < EMB_MAGIC.length + 4 || !prefix.subarray(0, EMB_MAGIC.length).equals(EMB_MAGIC)) return null;\n let o = EMB_MAGIC.length;\n const version = prefix.readUInt16LE(o);\n o += 2;\n if (version !== EMB_VERSION) return null;\n const modelLen = prefix.readUInt16LE(o);\n o += 2;\n if (o + modelLen + 8 > n) {\n // model spills past our prefix — re-read exactly\n const full = Buffer.alloc(EMB_MAGIC.length + 2 + 2 + modelLen + 8);\n fs.readSync(fd, full, 0, full.length, 0);\n return parseHeaderPrefix(full);\n }\n return parseHeaderPrefix(prefix);\n } catch {\n return null;\n } finally {\n if (fd !== null) fs.closeSync(fd);\n }\n}\n\nfunction parseHeaderPrefix(buf: Buffer): EmbedHeader | null {\n try {\n if (!buf.subarray(0, EMB_MAGIC.length).equals(EMB_MAGIC)) return null;\n let o = EMB_MAGIC.length;\n if (buf.readUInt16LE(o) !== EMB_VERSION) return null;\n o += 2;\n const modelLen = buf.readUInt16LE(o);\n o += 2;\n if (o + modelLen + 8 > buf.length) return null;\n const model = buf.subarray(o, o + modelLen).toString('utf8');\n o += modelLen;\n const dims = buf.readUInt32LE(o);\n o += 4;\n const count = buf.readUInt32LE(o);\n return { model, dims, count };\n } catch {\n return null;\n }\n}\n\nfunction readBinaryCache(file: string, modelId: string): EmbedCache | null {\n if (!fs.existsSync(file)) return null;\n try {\n const buf = fs.readFileSync(file);\n if (buf.length < EMB_MAGIC.length + 4 || !buf.subarray(0, EMB_MAGIC.length).equals(EMB_MAGIC)) return null;\n let o = EMB_MAGIC.length;\n if (buf.readUInt16LE(o) !== EMB_VERSION) return null;\n o += 2;\n const modelLen = buf.readUInt16LE(o);\n o += 2;\n const model = buf.subarray(o, o + modelLen).toString('utf8');\n o += modelLen;\n if (model !== modelId) return null;\n const dims = buf.readUInt32LE(o);\n o += 4;\n const count = buf.readUInt32LE(o);\n o += 4;\n if (dims === 0 || count === 0) return { model, entries: {} };\n\n const ids: string[] = [];\n const hashes: string[] = [];\n for (let i = 0; i < count; i++) {\n const idLen = buf.readUInt16LE(o);\n o += 2;\n ids.push(buf.subarray(o, o + idLen).toString('utf8'));\n o += idLen;\n const hashLen = buf.readUInt16LE(o);\n o += 2;\n hashes.push(buf.subarray(o, o + hashLen).toString('utf8'));\n o += hashLen;\n }\n const floatsNeeded = count * dims;\n const bytesNeeded = floatsNeeded * 4;\n if (o + bytesNeeded > buf.length) return null;\n // Copy into a standalone ArrayBuffer so Float32Array views are safe after buf is GC'd.\n const floatBuf = Buffer.from(buf.subarray(o, o + bytesNeeded));\n const floats = new Float32Array(floatBuf.buffer, floatBuf.byteOffset, floatsNeeded);\n\n const entries: EmbedCache['entries'] = {};\n for (let i = 0; i < count; i++) {\n const start = i * dims;\n const vec = Array.from(floats.subarray(start, start + dims));\n entries[ids[i]!] = { hash: hashes[i]!, vec };\n }\n return { model, entries };\n } catch {\n return null;\n }\n}\n\nfunction writeBinaryCache(file: string, cache: EmbedCache): void {\n const ids = Object.keys(cache.entries);\n const count = ids.length;\n let dims = 0;\n for (const id of ids) {\n const d = cache.entries[id]!.vec.length;\n if (d > 0) {\n dims = d;\n break;\n }\n }\n // Empty or all-zero-dim cache: still write a valid header so \"cached\" is true.\n const modelBuf = Buffer.from(cache.model, 'utf8');\n if (modelBuf.length > 0xffff) throw new Error('embed model id too long');\n\n // Index size (ids + hashes)\n let indexBytes = 0;\n const idBufs: Buffer[] = [];\n const hashBufs: Buffer[] = [];\n for (const id of ids) {\n const ib = Buffer.from(id, 'utf8');\n const hb = Buffer.from(cache.entries[id]!.hash, 'utf8');\n if (ib.length > 0xffff || hb.length > 0xffff) throw new Error('embed entry key too long');\n idBufs.push(ib);\n hashBufs.push(hb);\n indexBytes += 2 + ib.length + 2 + hb.length;\n }\n\n const headerBytes = EMB_MAGIC.length + 2 + 2 + modelBuf.length + 4 + 4;\n const vecBytes = count * dims * 4;\n const out = Buffer.allocUnsafe(headerBytes + indexBytes + vecBytes);\n let o = 0;\n EMB_MAGIC.copy(out, o);\n o += EMB_MAGIC.length;\n out.writeUInt16LE(EMB_VERSION, o);\n o += 2;\n out.writeUInt16LE(modelBuf.length, o);\n o += 2;\n modelBuf.copy(out, o);\n o += modelBuf.length;\n out.writeUInt32LE(dims, o);\n o += 4;\n out.writeUInt32LE(count, o);\n o += 4;\n\n for (let i = 0; i < count; i++) {\n const ib = idBufs[i]!;\n const hb = hashBufs[i]!;\n out.writeUInt16LE(ib.length, o);\n o += 2;\n ib.copy(out, o);\n o += ib.length;\n out.writeUInt16LE(hb.length, o);\n o += 2;\n hb.copy(out, o);\n o += hb.length;\n }\n\n if (dims > 0 && count > 0) {\n const floats = new Float32Array(count * dims);\n for (let i = 0; i < count; i++) {\n const vec = cache.entries[ids[i]!]!.vec;\n const base = i * dims;\n for (let d = 0; d < dims; d++) floats[base + d] = vec[d] ?? 0;\n }\n Buffer.from(floats.buffer, floats.byteOffset, floats.byteLength).copy(out, o);\n }\n\n fs.mkdirSync(path.dirname(file), { recursive: true });\n const tmp = `${file}.tmp.${process.pid}`;\n fs.writeFileSync(tmp, out);\n fs.renameSync(tmp, file);\n}\n\n/** Best-effort drop of the old model-named JSON caches under `.vibgrate/cache/`. */\nfunction purgeLegacyJsonCaches(root: string): void {\n const dir = cacheDir(root);\n let names: string[];\n try {\n names = fs.readdirSync(dir);\n } catch {\n return;\n }\n for (const name of names) {\n if (/^embeddings-.+\\.json$/.test(name) || /^embeddings-.+\\.json\\.lock$/.test(name)) {\n try {\n fs.rmSync(path.join(dir, name), { force: true });\n } catch {\n /* best-effort */\n }\n }\n }\n}\n\n// Single-writer lock (shared helper — see ./lock.ts) so a foreground `ask`\n// and a background `embed` never both embed the same repo at once (which\n// would race on the cache file).\n\n/**\n * Node embeddings for the searchable (non-file/external) nodes, cache-backed:\n * only nodes whose embed-text changed are re-embedded. The first run embeds in\n * chunks, **persists the cache incrementally** (so an interrupted/timed-out run\n * resumes instead of wasting the work), and reports progress via `onProgress`.\n */\nexport async function getNodeEmbeddings(\n graph: VgGraph,\n embedder: Embedder,\n root: string,\n onProgress?: EmbedProgress,\n): Promise<Map<string, number[]>> {\n const file = vectorCachePath(root);\n const cache = loadCache(root, embedder.id);\n\n // Includes document nodes (markdown/txt/env examples) so ask can retrieve docs.\n const targets = embedTargets(graph);\n const toEmbed: EmbedTarget[] = [];\n const vectors = new Map<string, number[]>();\n for (const t of targets) {\n const cached = cache.entries[t.id];\n if (cached && cached.hash === t.hash) vectors.set(t.id, cached.vec);\n else toEmbed.push(t);\n }\n\n // Atomic write (temp + rename) so a reader never sees a half-written cache.\n const persist = (): void => {\n try {\n writeBinaryCache(file, cache);\n purgeLegacyJsonCaches(root);\n } catch {\n /* cache write best-effort */\n }\n };\n\n if (toEmbed.length) {\n // Single-writer: if another process (e.g. a background warm-up) is already\n // embedding this repo, don't double-work or race the cache — return what's\n // cached so far (lexical floor still applies). It will be complete next run.\n const lock = `${file}.lock`;\n if (!acquireLock(lock)) return vectors;\n try {\n onProgress?.(0, toEmbed.length);\n let lastWrite = Date.now();\n for (let i = 0; i < toEmbed.length; i += EMBED_CHUNK) {\n const slice = toEmbed.slice(i, i + EMBED_CHUNK);\n const vecs = await embedder.embed(slice.map((t) => t.text));\n slice.forEach((t, j) => {\n const vec = vecs[j] ?? [];\n vectors.set(t.id, vec);\n cache.entries[t.id] = { hash: t.hash, vec };\n });\n onProgress?.(Math.min(i + EMBED_CHUNK, toEmbed.length), toEmbed.length);\n // Persist periodically so a crash/timeout resumes from here next run.\n if (Date.now() - lastWrite >= CACHE_WRITE_INTERVAL_MS) {\n persist();\n lastWrite = Date.now();\n }\n }\n // prune entries for nodes no longer present, then a final authoritative write\n const live = new Set(targets.map((t) => t.id));\n for (const id of Object.keys(cache.entries)) if (!live.has(id)) delete cache.entries[id];\n persist();\n } finally {\n releaseLock(lock);\n }\n } else if (!fs.existsSync(file) && Object.keys(cache.entries).length > 0) {\n // Migrating from legacy JSON with a full hit set — rewrite as binary once\n // so the next run never reads the old path again.\n persist();\n }\n\n return vectors;\n}\n\nfunction safe(id: string): string {\n return id.replace(/[^a-z0-9.-]+/gi, '_');\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { buildMessages, parseEdits, applyEdits, unifiedDiff, redactSecrets } from './chunk-SHD5TCZ5.js';
2
- import { recordCliCall, CLI_TOOL_ALIASES, buildCodeContext, buildTaskCapsule, capsuleToCodeContext } from './chunk-UAPA5AHX.js';
3
- import { userAskFromInstruction } from './chunk-VEQA2FSM.js';
4
- import { analyzeQuestion, loadTopicTags } from './chunk-C5AOLTQS.js';
2
+ import { recordCliCall, CLI_TOOL_ALIASES, buildCodeContext, buildTaskCapsule, capsuleToCodeContext } from './chunk-TWWVTKA7.js';
3
+ import { userAskFromInstruction } from './chunk-USW5WHUG.js';
4
+ import { loadTopicTags, rankQuestion } from './chunk-III7S75O.js';
5
5
  import { repositoryIdFromRoot } from './chunk-XP6UUCZZ.js';
6
6
  import * as fs from 'fs';
7
7
  import * as path from 'path';
@@ -29,16 +29,15 @@ async function runCodeSession(options) {
29
29
  onPhase(p, detail);
30
30
  };
31
31
  phase("inspect", options.capsule ? "building source-bearing task capsule" : "building graph-grounded context");
32
- const relevance = await analyzeQuestion(userAskFromInstruction(instruction));
33
- const topicTags = relevance ? await loadTopicTags(graph, root) : null;
32
+ const topicTags = await loadTopicTags(graph, root);
33
+ const ranked = await rankQuestion(graph, userAskFromInstruction(instruction), { limit: 48, topicTags });
34
34
  const context = buildSessionContext(graph, instruction, {
35
35
  budget,
36
36
  files,
37
37
  capsule: options.capsule,
38
38
  root,
39
39
  fsImpl,
40
- relevance,
41
- topicTags
40
+ ranked
42
41
  });
43
42
  if (options.attribution?.client) {
44
43
  const seedFiles = new Set(context.seeds.map((s) => s.node.file).filter(Boolean));
@@ -145,15 +144,14 @@ function buildSessionContext(graph, instruction, opts) {
145
144
  const budget = opts.budget;
146
145
  const files = opts.files;
147
146
  if (!opts.capsule) {
148
- return buildCodeContext(graph, instruction, { budget, files, relevance: opts.relevance, topicTags: opts.topicTags });
147
+ return buildCodeContext(graph, instruction, { budget, files, ranked: opts.ranked });
149
148
  }
150
149
  const capsule = buildTaskCapsule(graph, instruction, {
151
150
  budget,
152
151
  files,
153
152
  readFile: (rel) => opts.fsImpl.read(rel),
154
153
  repositoryId: repositoryIdFromRoot(opts.root),
155
- relevance: opts.relevance,
156
- topicTags: opts.topicTags
154
+ ranked: opts.ranked
157
155
  });
158
156
  return capsuleToCodeContext(capsule);
159
157
  }
@@ -259,5 +257,5 @@ function shortId() {
259
257
  }
260
258
 
261
259
  export { commitChanges, nodeCodeFs, runCodeSession, undoChanges };
262
- //# sourceMappingURL=chunk-HVJHFTIV.js.map
263
- //# sourceMappingURL=chunk-HVJHFTIV.js.map
260
+ //# sourceMappingURL=chunk-4PDWV4AE.js.map
261
+ //# sourceMappingURL=chunk-4PDWV4AE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/code/session.ts"],"names":["resolve"],"mappings":"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","file":"chunk-4PDWV4AE.js","sourcesContent":["/**\n * The `vg code` governance session (VG-CLI-CODE §7).\n *\n * This is the load-bearing rule the whole platform is built on, applied to code\n * edits: a state-altering change goes **through** the lifecycle, never around it\n * (GUARDRAILS §5). One run walks inspect → assess → dry-run → approve → execute\n * → verify → log:\n *\n * inspect build the graph-grounded context for the instruction\n * assess ask the routed model for a terse edit; apply it deterministically\n * (in memory); compute the diff and the blast radius\n * dry-run the DEFAULT terminal state — propose the change, write nothing\n * approve writing requires explicit consent; without it we stop at dry-run\n * execute write the approved changes to disk\n * verify confirm the files on disk match what was approved (+ optional cmd)\n * log append an immutable, secret-free audit record with a correlation id\n *\n * Everything is deterministic except the single model call, which is isolated\n * behind the provider list (tried in order, falling back on transport failure).\n * The filesystem and clock are injectable so the whole session is testable\n * offline with no writes escaping a temp dir.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { buildCodeContext } from './context.js';\nimport { rankQuestion, type SanitizedRank } from '../engine/relevance-provider.js';\nimport { loadTopicTags } from '../engine/relevance-enrich.js';\nimport { userAskFromInstruction } from '../engine/user-ask.js';\nimport { buildTaskCapsule, capsuleToCodeContext } from './capsule.js';\nimport { recordCliCall, CLI_TOOL_ALIASES } from '../engine/savings.js';\nimport { repositoryIdFromRoot } from '../runtime/paths.js';\nimport { parseEdits, applyEdits, type SymbolSpan } from './apply.js';\nimport { unifiedDiff } from './diff.js';\nimport { buildMessages } from './prompt.js';\nimport { redactSecrets } from './providers.js';\nimport type { ChatOptions, CodeContext, CodeSessionResult, FileChange, LifecyclePhase, Provider, ProviderResult } from './types.js';\nimport type { VgGraph } from '../schema.js';\n\n/** Minimal filesystem seam so the session is testable without touching real disk. */\nexport interface CodeFs {\n read(file: string): string | null;\n write(file: string, content: string): void;\n remove(file: string): void;\n appendAudit(line: string): void;\n}\n\nexport interface RunSessionOptions {\n graph: VgGraph;\n root: string;\n instruction: string;\n /** Providers to try in order (from the router); the first that answers wins. */\n providers: Provider[];\n /** Write to disk? Default false — dry-run is the safe default (GUARDRAILS §3.2). */\n apply?: boolean;\n /** Explicit consent for the write (`--yes`); without it, a requested apply stops at dry-run. */\n consent?: boolean;\n /** Restrict the edit surface to these files. */\n files?: string[];\n /** Context token budget. */\n budget?: number;\n chatOptions?: ChatOptions;\n /** Injectable filesystem (defaults to a real, root-scoped fs). */\n fsImpl?: CodeFs;\n /** Injectable clock (ms) for the audit timestamp. */\n now?: () => number;\n /** Injectable correlation id (defaults to a random short id). */\n correlationId?: string;\n /** Progress callback per phase. */\n onPhase?: (phase: LifecyclePhase, detail: string) => void;\n /** Skip appending to the audit log (used by tests/dry programmatic calls). */\n noAudit?: boolean;\n /**\n * Who is making the graph-backed call, for per-model savings auditing. When\n * `client` is set, the context-assembly step (a `query_graph`-equivalent) is\n * recorded to the local savings ledger tagged with the provider + model, so\n * `vg savings` can break usage down per model. VG Code always sets this.\n */\n attribution?: { client: string; provider?: string; model?: string };\n /**\n * Use a source-bearing Task Capsule for the inspect context (Fusion Runtime\n * Phase 0 A/B). Default false keeps the metadata-only path.\n */\n capsule?: boolean;\n}\n\nexport async function runCodeSession(options: RunSessionOptions): Promise<CodeSessionResult> {\n const {\n graph,\n root,\n instruction,\n providers,\n apply = false,\n consent = false,\n files,\n budget,\n chatOptions,\n now = () => 0,\n onPhase = () => {},\n } = options;\n const fsImpl = options.fsImpl ?? nodeCodeFs(root);\n const correlationId = options.correlationId ?? shortId();\n const phasesRun: LifecyclePhase[] = [];\n const phase = (p: LifecyclePhase, detail: string): void => {\n phasesRun.push(p);\n onPhase(p, detail);\n };\n\n // ── inspect ──────────────────────────────────────────────────────────────\n phase('inspect', options.capsule ? 'building source-bearing task capsule' : 'building graph-grounded context');\n // The relevance module ranks the seeds when installed (auto-provisioned);\n // null → the mechanical fallback.\n const topicTags = await loadTopicTags(graph, root);\n const ranked = await rankQuestion(graph, userAskFromInstruction(instruction), { limit: 48, topicTags });\n const context = buildSessionContext(graph, instruction, {\n budget,\n files,\n capsule: options.capsule,\n root,\n fsImpl,\n ranked,\n });\n\n // Per-model savings: the context build is VG Code's `query_graph`-equivalent.\n // Record it (counts only — never code or the instruction) tagged with the\n // model, so `vg savings` audits usage per model. Local-only, best-effort.\n if (options.attribution?.client) {\n const seedFiles = new Set(context.seeds.map((s) => s.node.file).filter(Boolean));\n recordCliCall(\n root,\n {\n tool: CLI_TOOL_ALIASES.ask,\n client: options.attribution.client,\n provider: options.attribution.provider,\n model: options.attribution.model,\n outcome: context.seeds.length ? 'complete' : 'miss',\n vgTokens: context.tokensEstimate,\n baselineFiles: seedFiles.size,\n },\n now(),\n );\n }\n\n // ── assess ──────────────────────────────────────────────────────────────\n phase('assess', 'asking the routed model for a minimal edit');\n const messages = buildMessages(context);\n const { result, provider, fellBack } = await complete(providers, messages, chatOptions, correlationId);\n\n const edits = parseEdits(result.text);\n const spans = spanIndex(graph);\n const applied = applyEdits(\n edits,\n (file) => fsImpl.read(file),\n (file) => spans.get(normalize(file)) ?? [],\n );\n\n const changes: FileChange[] = [];\n for (const [file, entry] of [...applied.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {\n changes.push({\n file,\n before: entry.before,\n after: entry.after,\n outcomes: entry.outcomes,\n diff: unifiedDiff(entry.before, entry.after, file),\n });\n }\n\n // ── dry-run (always produced) ─────────────────────────────────────────────\n phase('dry-run', `${changes.length} file(s) would change`);\n\n const anyApplicable = changes.some((c) => c.diff !== '' && c.outcomes.some((o) => o.status === 'applied'));\n const base: CodeSessionResult = {\n instruction,\n provider: { id: provider.id, model: provider.model, local: provider.local, fellBack },\n phasesRun,\n changes,\n applied: false,\n verification: { ran: false, ok: false, detail: 'dry-run — no changes written' },\n correlationId,\n };\n\n // ── approve ───────────────────────────────────────────────────────────────\n // Writing is opt-in AND consent-gated. A requested apply without consent is\n // not an error — it degrades to a dry-run so the caller can review, then\n // re-run with --yes. This is the \"never destructive-by-default\" guardrail.\n if (!apply) {\n if (!options.noAudit) writeAudit(fsImpl, base, now());\n return base;\n }\n if (!consent) {\n const stopped = { ...base, verification: { ran: false, ok: false, detail: 'apply requested without consent — re-run with --yes to write these changes' } };\n if (!options.noAudit) writeAudit(fsImpl, stopped, now());\n return stopped;\n }\n if (!anyApplicable) {\n const nothing = { ...base, verification: { ran: false, ok: false, detail: 'nothing to write — no edit applied cleanly' } };\n if (!options.noAudit) writeAudit(fsImpl, nothing, now());\n return nothing;\n }\n phase('approve', 'consent given (--yes)');\n\n // ── execute ───────────────────────────────────────────────────────────────\n phase('execute', 'writing approved changes');\n for (const change of changes) {\n if (change.diff === '') continue; // no-op file\n if (!change.outcomes.some((o) => o.status === 'applied')) continue; // nothing applied cleanly here\n if (change.after === null) fsImpl.remove(change.file);\n else fsImpl.write(change.file, change.after);\n }\n\n // ── verify ────────────────────────────────────────────────────────────────\n phase('verify', 'confirming on-disk content matches the approved change');\n const verification = verifyWrites(fsImpl, changes);\n\n // ── log ───────────────────────────────────────────────────────────────────\n phase('log', 'recording an audit entry');\n const final: CodeSessionResult = { ...base, applied: true, verification };\n if (!options.noAudit) writeAudit(fsImpl, final, now());\n return final;\n}\n\n/**\n * Commit an already-computed dry-run result: write the cleanly-applied changes,\n * verify them on disk, and append the audit record — the \"approve → execute →\n * verify → log\" tail of the lifecycle, run against a proposal the caller has\n * already shown and had approved (the interactive REPL uses this so it never\n * calls the model twice or writes something different from what was reviewed).\n */\nexport function commitChanges(result: CodeSessionResult, fsImpl: CodeFs, now: () => number = () => 0): CodeSessionResult {\n const anyApplicable = result.changes.some((c) => c.diff !== '' && c.outcomes.some((o) => o.status === 'applied'));\n if (!anyApplicable) {\n return { ...result, applied: false, verification: { ran: false, ok: false, detail: 'nothing to write — no edit applied cleanly' } };\n }\n for (const change of result.changes) {\n if (change.diff === '' || !change.outcomes.some((o) => o.status === 'applied')) continue;\n if (change.after === null) fsImpl.remove(change.file);\n else fsImpl.write(change.file, change.after);\n }\n const verification = verifyWrites(fsImpl, result.changes);\n const final: CodeSessionResult = { ...result, applied: true, verification, phasesRun: [...result.phasesRun, 'approve', 'execute', 'verify', 'log'] };\n writeAudit(fsImpl, final, now());\n return final;\n}\n\n/**\n * Undo a set of applied changes by restoring each file's prior content — the\n * `/undo` command. A created file (before === null) is removed; an edited or\n * deleted file is restored to its `before`. Only cleanly-applied changes are\n * reverted. Returns the files it restored.\n */\nexport function undoChanges(changes: FileChange[], fsImpl: CodeFs): string[] {\n const restored: string[] = [];\n for (const ch of changes) {\n if (!ch.outcomes.some((o) => o.status === 'applied')) continue;\n if (ch.before === null) fsImpl.remove(ch.file);\n else fsImpl.write(ch.file, ch.before);\n restored.push(ch.file);\n }\n return restored;\n}\n\nfunction buildSessionContext(\n graph: VgGraph,\n instruction: string,\n opts: { budget?: number; files?: string[]; capsule?: boolean; root: string; fsImpl: CodeFs; ranked?: SanitizedRank | null },\n): CodeContext {\n const budget = opts.budget;\n const files = opts.files;\n if (!opts.capsule) {\n return buildCodeContext(graph, instruction, { budget, files, ranked: opts.ranked });\n }\n const capsule = buildTaskCapsule(graph, instruction, {\n budget,\n files,\n readFile: (rel) => opts.fsImpl.read(rel),\n repositoryId: repositoryIdFromRoot(opts.root),\n ranked: opts.ranked,\n });\n return capsuleToCodeContext(capsule);\n}\n\n/** Try each provider in order; fall back on transport failure. Throws the last actionable error. */\nasync function complete(\n providers: Provider[],\n messages: ReturnType<typeof buildMessages>,\n chatOptions: ChatOptions | undefined,\n correlationId: string,\n): Promise<{ result: ProviderResult; provider: Provider; fellBack: boolean }> {\n if (providers.length === 0) throw new Error(`no model provider available (ref ${correlationId})`);\n let lastErr: unknown;\n for (let i = 0; i < providers.length; i++) {\n const provider = providers[i];\n try {\n const result = await provider.chat(messages, { temperature: 0, ...chatOptions });\n return { result, provider, fellBack: i > 0 };\n } catch (e) {\n lastErr = e;\n }\n }\n const message = lastErr instanceof Error ? redactSecrets(lastErr.message) : String(lastErr);\n throw new Error(`${message} (ref ${correlationId})`);\n}\n\n/** Confirm each written file's on-disk content equals what we approved. */\nfunction verifyWrites(fsImpl: CodeFs, changes: FileChange[]): { ran: boolean; ok: boolean; detail: string } {\n let checked = 0;\n const mismatches: string[] = [];\n for (const change of changes) {\n if (change.diff === '' || !change.outcomes.some((o) => o.status === 'applied')) continue;\n checked++;\n const onDisk = fsImpl.read(change.file);\n if (onDisk !== change.after) mismatches.push(change.file);\n }\n if (mismatches.length) return { ran: true, ok: false, detail: `on-disk content differs for: ${mismatches.join(', ')}` };\n return { ran: true, ok: true, detail: `wrote and verified ${checked} file(s)` };\n}\n\n/** An append-only, secret-free audit record (GUARDRAILS §2.6 / §5). No file contents, no keys. */\nfunction writeAudit(fsImpl: CodeFs, r: CodeSessionResult, ts: number): void {\n const record = {\n ts,\n correlationId: r.correlationId,\n instruction: r.instruction.slice(0, 500),\n provider: r.provider.id,\n model: r.provider.model,\n local: r.provider.local,\n applied: r.applied,\n files: r.changes.map((c) => ({ file: c.file, statuses: c.outcomes.map((o) => o.status) })),\n verification: r.verification,\n phases: r.phasesRun,\n };\n try {\n fsImpl.appendAudit(JSON.stringify(record));\n } catch {\n /* audit is best-effort; never fail the run on a logging problem */\n }\n}\n\n/** Build a per-file map of symbol spans for graph-scoped edit disambiguation. */\nfunction spanIndex(graph: VgGraph): Map<string, SymbolSpan[]> {\n const map = new Map<string, SymbolSpan[]>();\n for (const n of graph.nodes) {\n if (n.kind === 'file' || n.kind === 'external') continue;\n const file = normalize(n.file);\n const list = map.get(file) ?? [];\n list.push({ qualifiedName: n.qualifiedName, file, start: n.span.start, end: n.span.end });\n map.set(file, list);\n }\n return map;\n}\n\nfunction normalize(file: string): string {\n return file.replace(/\\\\/g, '/').replace(/^\\.\\//, '');\n}\n\n/** Default filesystem impl, scoped to `root`. Refuses paths that escape the root. */\nexport function nodeCodeFs(root: string): CodeFs {\n const resolve = (file: string): string => {\n const abs = path.resolve(root, file);\n const rel = path.relative(root, abs);\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\n throw new Error(`edit path escapes the project root: ${file} — refusing to touch files outside ${root}`);\n }\n return abs;\n };\n return {\n read(file) {\n try {\n return fs.readFileSync(resolve(file), 'utf8');\n } catch {\n return null;\n }\n },\n write(file, content) {\n const abs = resolve(file);\n fs.mkdirSync(path.dirname(abs), { recursive: true });\n fs.writeFileSync(abs, content);\n },\n remove(file) {\n try {\n fs.rmSync(resolve(file));\n } catch {\n /* already gone */\n }\n },\n appendAudit(line) {\n const dir = path.join(root, '.vibgrate');\n fs.mkdirSync(dir, { recursive: true });\n fs.appendFileSync(path.join(dir, 'code-audit.jsonl'), line + '\\n');\n },\n };\n}\n\n/** Short, URL-safe correlation id. Not a graph artifact, so runtime randomness is fine here. */\nfunction shortId(): string {\n let s = '';\n const alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789';\n for (let i = 0; i < 8; i++) s += alphabet[Math.floor(Math.random() * alphabet.length)];\n return s;\n}\n"]}