@vibgrate/cli 2026.819.1 → 2026.819.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 (171) hide show
  1. package/DOCS.md +3 -3
  2. package/dist/agent-AFMDB4GM.js +30 -0
  3. package/dist/{agent-3CKNTCRX.js.map → agent-AFMDB4GM.js.map} +1 -1
  4. package/dist/{approvals-DHTG3HI4.js → approvals-F2DJGPU7.js} +7 -7
  5. package/dist/{approvals-DHTG3HI4.js.map → approvals-F2DJGPU7.js.map} +1 -1
  6. package/dist/attach-XTX2Q3AD.js +10 -0
  7. package/dist/{attach-OCQ3I76L.js.map → attach-XTX2Q3AD.js.map} +1 -1
  8. package/dist/baseline-KTE2C3LW.js +9 -0
  9. package/dist/{baseline-QDC6OQ2X.js.map → baseline-KTE2C3LW.js.map} +1 -1
  10. package/dist/{chunk-D33M2ARL.js → chunk-3SOJZ3VV.js} +3 -3
  11. package/dist/{chunk-D33M2ARL.js.map → chunk-3SOJZ3VV.js.map} +1 -1
  12. package/dist/{chunk-JGBOYZAF.js → chunk-3XMTRK24.js} +99 -19
  13. package/dist/chunk-3XMTRK24.js.map +1 -0
  14. package/dist/{chunk-OV4KGXPD.js → chunk-57ZRSCHY.js} +3 -3
  15. package/dist/{chunk-OV4KGXPD.js.map → chunk-57ZRSCHY.js.map} +1 -1
  16. package/dist/{chunk-KFEM6FWP.js → chunk-5R4HYDTC.js} +4 -4
  17. package/dist/{chunk-KFEM6FWP.js.map → chunk-5R4HYDTC.js.map} +1 -1
  18. package/dist/{chunk-EI5AKDSC.js → chunk-5RMME7PT.js} +3 -3
  19. package/dist/{chunk-EI5AKDSC.js.map → chunk-5RMME7PT.js.map} +1 -1
  20. package/dist/{chunk-OQT3JBWW.js → chunk-5UG4UHKU.js} +205 -36
  21. package/dist/chunk-5UG4UHKU.js.map +1 -0
  22. package/dist/{chunk-NDNNOAS6.js → chunk-6H2QV5DR.js} +3 -3
  23. package/dist/{chunk-NDNNOAS6.js.map → chunk-6H2QV5DR.js.map} +1 -1
  24. package/dist/{chunk-LJSJX6U4.js → chunk-A3WWRW7U.js} +3 -3
  25. package/dist/{chunk-LJSJX6U4.js.map → chunk-A3WWRW7U.js.map} +1 -1
  26. package/dist/{chunk-O5ASXWKF.js → chunk-ARGYMFST.js} +3 -3
  27. package/dist/{chunk-O5ASXWKF.js.map → chunk-ARGYMFST.js.map} +1 -1
  28. package/dist/{chunk-FFY6NW7P.js → chunk-C5AOLTQS.js} +5 -5
  29. package/dist/{chunk-FFY6NW7P.js.map → chunk-C5AOLTQS.js.map} +1 -1
  30. package/dist/{chunk-F46Q3AEI.js → chunk-CEJIX3O7.js} +44 -15
  31. package/dist/chunk-CEJIX3O7.js.map +1 -0
  32. package/dist/{chunk-QMRSCJUN.js → chunk-DMI4BMUL.js} +3 -3
  33. package/dist/{chunk-QMRSCJUN.js.map → chunk-DMI4BMUL.js.map} +1 -1
  34. package/dist/{chunk-TS25WFAT.js → chunk-EXFA7QFC.js} +9 -9
  35. package/dist/{chunk-TS25WFAT.js.map → chunk-EXFA7QFC.js.map} +1 -1
  36. package/dist/{chunk-VYSDR2QE.js → chunk-HB3SONYP.js} +4 -4
  37. package/dist/{chunk-VYSDR2QE.js.map → chunk-HB3SONYP.js.map} +1 -1
  38. package/dist/{chunk-KKQX3F5F.js → chunk-HRYF4PWE.js} +7 -5
  39. package/dist/chunk-HRYF4PWE.js.map +1 -0
  40. package/dist/{chunk-EIESBKLW.js → chunk-HVJHFTIV.js} +7 -7
  41. package/dist/{chunk-EIESBKLW.js.map → chunk-HVJHFTIV.js.map} +1 -1
  42. package/dist/{chunk-JFE7XCAE.js → chunk-IASO2HCI.js} +3 -3
  43. package/dist/{chunk-JFE7XCAE.js.map → chunk-IASO2HCI.js.map} +1 -1
  44. package/dist/chunk-MQJY4EQV.js +6 -0
  45. package/dist/{chunk-DHU3OOEI.js.map → chunk-MQJY4EQV.js.map} +1 -1
  46. package/dist/{chunk-7AVYKZEM.js → chunk-NV7XNBX4.js} +4 -4
  47. package/dist/{chunk-7AVYKZEM.js.map → chunk-NV7XNBX4.js.map} +1 -1
  48. package/dist/{chunk-NZELMYT4.js → chunk-OLIMW4PQ.js} +8 -56
  49. package/dist/chunk-OLIMW4PQ.js.map +1 -0
  50. package/dist/{chunk-NWWLUFN5.js → chunk-PQISIPYP.js} +5 -5
  51. package/dist/{chunk-NWWLUFN5.js.map → chunk-PQISIPYP.js.map} +1 -1
  52. package/dist/{chunk-5XY4EFR7.js → chunk-QLNJ3VWO.js} +3 -3
  53. package/dist/{chunk-5XY4EFR7.js.map → chunk-QLNJ3VWO.js.map} +1 -1
  54. package/dist/{chunk-D44PGMH7.js → chunk-QOU2Q5L4.js} +12 -12
  55. package/dist/{chunk-D44PGMH7.js.map → chunk-QOU2Q5L4.js.map} +1 -1
  56. package/dist/{chunk-TS7STRMI.js → chunk-RTURQXQL.js} +4 -4
  57. package/dist/{chunk-TS7STRMI.js.map → chunk-RTURQXQL.js.map} +1 -1
  58. package/dist/{chunk-74UBGF4P.js → chunk-SHD5TCZ5.js} +3 -3
  59. package/dist/{chunk-74UBGF4P.js.map → chunk-SHD5TCZ5.js.map} +1 -1
  60. package/dist/{chunk-WJYJCDNY.js → chunk-SOAEPTSW.js} +13 -13
  61. package/dist/{chunk-WJYJCDNY.js.map → chunk-SOAEPTSW.js.map} +1 -1
  62. package/dist/{chunk-EMEMHNE3.js → chunk-TD4JAEMH.js} +6 -6
  63. package/dist/{chunk-EMEMHNE3.js.map → chunk-TD4JAEMH.js.map} +1 -1
  64. package/dist/{chunk-5O6O7DJH.js → chunk-UAPA5AHX.js} +3 -3
  65. package/dist/{chunk-5O6O7DJH.js.map → chunk-UAPA5AHX.js.map} +1 -1
  66. package/dist/{chunk-4VAA2XSM.js → chunk-UEXDSWKN.js} +6 -6
  67. package/dist/{chunk-4VAA2XSM.js.map → chunk-UEXDSWKN.js.map} +1 -1
  68. package/dist/{chunk-YIEP5GK5.js → chunk-UP2BR6TV.js} +15 -11
  69. package/dist/chunk-UP2BR6TV.js.map +1 -0
  70. package/dist/{chunk-6F52QR6F.js → chunk-VEQA2FSM.js} +4 -4
  71. package/dist/{chunk-6F52QR6F.js.map → chunk-VEQA2FSM.js.map} +1 -1
  72. package/dist/{chunk-E53WBVUQ.js → chunk-VHRSG6CF.js} +3 -3
  73. package/dist/{chunk-E53WBVUQ.js.map → chunk-VHRSG6CF.js.map} +1 -1
  74. package/dist/{chunk-I5LP55B6.js → chunk-W44THEXF.js} +3 -3
  75. package/dist/{chunk-I5LP55B6.js.map → chunk-W44THEXF.js.map} +1 -1
  76. package/dist/{chunk-FQVAQVJV.js → chunk-WI66PODG.js} +3 -3
  77. package/dist/{chunk-FQVAQVJV.js.map → chunk-WI66PODG.js.map} +1 -1
  78. package/dist/{chunk-CQDUBAQY.js → chunk-WNKGRXUA.js} +3 -3
  79. package/dist/{chunk-CQDUBAQY.js.map → chunk-WNKGRXUA.js.map} +1 -1
  80. package/dist/{chunk-FJG5AXKZ.js → chunk-WUFIXAEJ.js} +22 -6
  81. package/dist/chunk-WUFIXAEJ.js.map +1 -0
  82. package/dist/{chunk-QSLVOVNZ.js → chunk-XAS45W3G.js} +10 -10
  83. package/dist/{chunk-QSLVOVNZ.js.map → chunk-XAS45W3G.js.map} +1 -1
  84. package/dist/{chunk-BWPBB45M.js → chunk-XP6UUCZZ.js} +3 -3
  85. package/dist/{chunk-BWPBB45M.js.map → chunk-XP6UUCZZ.js.map} +1 -1
  86. package/dist/{chunk-BPF3YX2U.js → chunk-XQNKCA2J.js} +6 -3
  87. package/dist/chunk-XQNKCA2J.js.map +1 -0
  88. package/dist/{chunk-U7A7D2HP.js → chunk-XZDI2N7M.js} +7 -7
  89. package/dist/{chunk-U7A7D2HP.js.map → chunk-XZDI2N7M.js.map} +1 -1
  90. package/dist/{chunk-7N4Y3E47.js → chunk-YJYEPYB2.js} +13 -18
  91. package/dist/chunk-YJYEPYB2.js.map +1 -0
  92. package/dist/cli.js +104 -94
  93. package/dist/cli.js.map +1 -1
  94. package/dist/client-P5XSRFV4.js +8 -0
  95. package/dist/{client-UQIELEEZ.js.map → client-P5XSRFV4.js.map} +1 -1
  96. package/dist/daemon-VMQKIIYP.js +30 -0
  97. package/dist/{daemon-UNL65PTP.js.map → daemon-VMQKIIYP.js.map} +1 -1
  98. package/dist/embed-worker-main.js +5 -5
  99. package/dist/ensure-map-YIUJWMBK.js +40 -0
  100. package/dist/{ensure-map-4D2HJ6MA.js.map → ensure-map-YIUJWMBK.js.map} +1 -1
  101. package/dist/{federation-SZYVHYB2.js → federation-M4ZNXOPX.js} +5 -5
  102. package/dist/{federation-SZYVHYB2.js.map → federation-M4ZNXOPX.js.map} +1 -1
  103. package/dist/git-ref-LMT3EXYY.js +4 -0
  104. package/dist/{git-ref-RSRAN4OH.js.map → git-ref-LMT3EXYY.js.map} +1 -1
  105. package/dist/graph-backend-FDZUY4TR.js +16 -0
  106. package/dist/{graph-backend-36EIAAPQ.js.map → graph-backend-FDZUY4TR.js.map} +1 -1
  107. package/dist/index.d.ts +1 -1
  108. package/dist/index.js +23 -23
  109. package/dist/{interactive-ZZMHSZ3W.js → interactive-CS4PGZPK.js} +40 -40
  110. package/dist/{interactive-ZZMHSZ3W.js.map → interactive-CS4PGZPK.js.map} +1 -1
  111. package/dist/{llm-host-XFYFOAAX.js → llm-host-QVTJJVER.js} +5 -5
  112. package/dist/{llm-host-XFYFOAAX.js.map → llm-host-QVTJJVER.js.map} +1 -1
  113. package/dist/load-4EY64JJO.js +11 -0
  114. package/dist/{load-6CYLMUT5.js.map → load-4EY64JJO.js.map} +1 -1
  115. package/dist/local-runtime-GA43KYS5.js +6 -0
  116. package/dist/{local-runtime-6SNWKSA7.js.map → local-runtime-GA43KYS5.js.map} +1 -1
  117. package/dist/model-manager-6H3TMZKK.js +10 -0
  118. package/dist/{model-manager-SXHZ5VD4.js.map → model-manager-6H3TMZKK.js.map} +1 -1
  119. package/dist/{model-orchestrator-LHYPJBFH.js → model-orchestrator-X3NE3Y2G.js} +6 -6
  120. package/dist/{model-orchestrator-LHYPJBFH.js.map → model-orchestrator-X3NE3Y2G.js.map} +1 -1
  121. package/dist/parse-worker.js +2 -2
  122. package/dist/{paths-62AKTFSR.js → paths-RVK6FKRN.js} +4 -4
  123. package/dist/{paths-62AKTFSR.js.map → paths-RVK6FKRN.js.map} +1 -1
  124. package/dist/publish-27S66NOW.js +9 -0
  125. package/dist/{publish-7YHRTBRA.js.map → publish-27S66NOW.js.map} +1 -1
  126. package/dist/resolve-gguf-WVKVDN45.js +9 -0
  127. package/dist/{resolve-gguf-SDIYGGI6.js.map → resolve-gguf-WVKVDN45.js.map} +1 -1
  128. package/dist/{run-outcome-ADEAKXHH.js → run-outcome-T7VDBNWB.js} +7 -7
  129. package/dist/{run-outcome-ADEAKXHH.js.map → run-outcome-T7VDBNWB.js.map} +1 -1
  130. package/dist/runtime-session-WZLVADPQ.js +26 -0
  131. package/dist/{runtime-session-VNSXQAEO.js.map → runtime-session-WZLVADPQ.js.map} +1 -1
  132. package/dist/session-VPP2VGUN.js +17 -0
  133. package/dist/{session-3A6LKJHD.js.map → session-VPP2VGUN.js.map} +1 -1
  134. package/dist/{slot-subscription-25GOARW5.js → slot-subscription-C2ZUJED6.js} +5 -5
  135. package/dist/{slot-subscription-25GOARW5.js.map → slot-subscription-C2ZUJED6.js.map} +1 -1
  136. package/dist/{stream-json-S2TP2VPU.js → stream-json-XXCFN4MF.js} +17 -17
  137. package/dist/{stream-json-S2TP2VPU.js.map → stream-json-XXCFN4MF.js.map} +1 -1
  138. package/dist/version-2UBJ7N2I.js +4 -0
  139. package/dist/{version-SZI6I3A2.js.map → version-2UBJ7N2I.js.map} +1 -1
  140. package/dist/{vg-mcp-bridge-IIBEAOEB.js → vg-mcp-bridge-H6GXYNKV.js} +14 -14
  141. package/dist/{vg-mcp-bridge-IIBEAOEB.js.map → vg-mcp-bridge-H6GXYNKV.js.map} +1 -1
  142. package/dist/{vgd-KGXIKGOS.js → vgd-SBZO4ONQ.js} +13 -13
  143. package/dist/vgd-SBZO4ONQ.js.map +1 -0
  144. package/package.json +1 -1
  145. package/dist/agent-3CKNTCRX.js +0 -30
  146. package/dist/attach-OCQ3I76L.js +0 -10
  147. package/dist/baseline-QDC6OQ2X.js +0 -9
  148. package/dist/chunk-7N4Y3E47.js.map +0 -1
  149. package/dist/chunk-BPF3YX2U.js.map +0 -1
  150. package/dist/chunk-DHU3OOEI.js +0 -6
  151. package/dist/chunk-F46Q3AEI.js.map +0 -1
  152. package/dist/chunk-FJG5AXKZ.js.map +0 -1
  153. package/dist/chunk-JGBOYZAF.js.map +0 -1
  154. package/dist/chunk-KKQX3F5F.js.map +0 -1
  155. package/dist/chunk-NZELMYT4.js.map +0 -1
  156. package/dist/chunk-OQT3JBWW.js.map +0 -1
  157. package/dist/chunk-YIEP5GK5.js.map +0 -1
  158. package/dist/client-UQIELEEZ.js +0 -8
  159. package/dist/daemon-UNL65PTP.js +0 -30
  160. package/dist/ensure-map-4D2HJ6MA.js +0 -40
  161. package/dist/git-ref-RSRAN4OH.js +0 -4
  162. package/dist/graph-backend-36EIAAPQ.js +0 -16
  163. package/dist/load-6CYLMUT5.js +0 -11
  164. package/dist/local-runtime-6SNWKSA7.js +0 -6
  165. package/dist/model-manager-SXHZ5VD4.js +0 -10
  166. package/dist/publish-7YHRTBRA.js +0 -9
  167. package/dist/resolve-gguf-SDIYGGI6.js +0 -9
  168. package/dist/runtime-session-VNSXQAEO.js +0 -26
  169. package/dist/session-3A6LKJHD.js +0 -17
  170. package/dist/version-SZI6I3A2.js +0 -4
  171. package/dist/vgd-KGXIKGOS.js.map +0 -1
package/DOCS.md CHANGED
@@ -1191,11 +1191,11 @@ vg llm-host serve --socket /tmp/vg-llm.sock --yes
1191
1191
 
1192
1192
  Default isolation is **embedded** (same process as the agent). Set `VIBGRATE_INFERENCE_ISOLATION=process` to use the host. Management never moves into the host process.
1193
1193
 
1194
- **First-party weights.** For catalogued GGUF refs (e.g. Spark’s llama.cpp fallback), `vg models install` can download into the Vibgrate weight store under the cache directory (HTTPS hosts allowlisted, including Hugging Face LFS/Xet CDNs). Catalog entries carry **sha256 pins**; a download that does not match is rejected. Ollama remains the default pull channel for Code Mode packs that list `ollama` as primary.
1194
+ **First-party weights.** Code Mode packs are first-party GGUF only: `vg models install` downloads the catalogued refs into the Vibgrate weight store under the cache directory (HTTPS hosts allowlisted, including Hugging Face LFS/Xet CDNs). Catalog entries carry **sha256 pins**; a download that does not match is rejected. Ollama is used only for models you select explicitly (`vg models pull <name>`, `--provider ollama`) never for a Code Mode pack.
1195
1195
 
1196
1196
  **Foundry Local.** On Windows (or any host running Microsoft Foundry Local), use `--provider foundry-local --model <id>` with the OpenAI-compatible server (default `http://127.0.0.1:5272/v1`, override with `FOUNDRY_LOCAL_BASE_URL`). `vg models status` lists models when the server responds.
1197
1197
 
1198
- **Warm local inference (Approach B default).** Code Mode packs (channel 2026.07.3) install first-party GGUF weights when fit allows; Ollama is the fallback adapter. When a GGUF is on disk (weight store or `~/models`), `vg code` prefers embedded llama.cpp automatically. Set `VG_PREFER_OLLAMA=1` to force Ollama first. Spark constrained decoding is **fail-closed**: if the binding cannot attach a PatchIR grammar, generation errors instead of free-text (opt-in raw string GBNF only via `VG_ALLOW_GRAMMAR_STRING_FALLBACK=1`).
1198
+ **Warm local inference (Approach B default).** Code Mode packs (channel 2026.08.1) install first-party GGUF weights and run on embedded llama.cpp only — there is no Ollama fallback in a pack. When a GGUF is on disk (weight store or `~/models`), `vg code` prefers embedded llama.cpp automatically. Set `VG_PREFER_OLLAMA=1` to try your own Ollama models first outside Code Modes. Spark constrained decoding is **fail-closed**: if the binding cannot attach a PatchIR grammar, generation errors instead of free-text (opt-in raw string GBNF only via `VG_ALLOW_GRAMMAR_STRING_FALLBACK=1`).
1199
1199
 
1200
1200
  **Identifier enforce (before apply).** Edits and `apply_patch` that invent identifiers not present in the code graph are **blocked** (not merely annotated). Identifiers already in the target file (locals, params, existing helpers) and tokens only in comments/strings are allowed. After an approved edit, the session trie updates so new symbols become legal.
1201
1201
 
@@ -1223,7 +1223,7 @@ Default isolation is **embedded** (same process as the agent). Set `VIBGRATE_INF
1223
1223
 
1224
1224
  **Named install commands run by default** (same polarity as the rest of `vg`: the command does what it says). Pass `--dry-run` to print the plan only. Status/resolve never download. Destructive `rm` confirms on a TTY; non-interactive remove needs `--yes`.
1225
1225
 
1226
- `install` / `pull` install the **full provider dependency closure** for the pack (e.g. runtime npm deps for llama-cpp, then weight download for Ollama). Third-party apps such as Ollama itself are never auto-installed — install them separately if the plan lists them as blocked.
1226
+ `install` / `pull` install the **full provider dependency closure** (e.g. runtime npm deps for llama-cpp, then the pinned GGUF from the first-party weight store; `pull` fetches your named model via Ollama). Third-party apps such as Ollama itself are never auto-installed — install them separately if the plan lists them as blocked.
1227
1227
 
1228
1228
  ```bash
1229
1229
  vg models # Code Modes status + fleet summary
@@ -0,0 +1,30 @@
1
+ export { CONTEXT_POLICY_VERSION, DISCOVERY_TOOLS, MUTATION_TOOLS, compact, compactWithModel, runAgent } from './chunk-SOAEPTSW.js';
2
+ import './chunk-543E6WDJ.js';
3
+ import './chunk-3SOJZ3VV.js';
4
+ import './chunk-HB3SONYP.js';
5
+ import './chunk-SHD5TCZ5.js';
6
+ import './chunk-3HNPVXUK.js';
7
+ import './chunk-5HYCB55P.js';
8
+ import './chunk-VIWZ4QT7.js';
9
+ import './chunk-HRYF4PWE.js';
10
+ export { summarizeCapsule } from './chunk-UAPA5AHX.js';
11
+ import './chunk-EZ7UC5Y5.js';
12
+ import './chunk-6BEBJCK4.js';
13
+ import './chunk-J7LKEB2R.js';
14
+ import './chunk-VEQA2FSM.js';
15
+ import './chunk-VHRSG6CF.js';
16
+ import './chunk-6H2QV5DR.js';
17
+ import './chunk-WI66PODG.js';
18
+ import './chunk-T7RSQ5WD.js';
19
+ import './chunk-6WRG7VDO.js';
20
+ import './chunk-DMI4BMUL.js';
21
+ import './chunk-C5AOLTQS.js';
22
+ import './chunk-MVPRPSXU.js';
23
+ import './chunk-O3LABX6I.js';
24
+ import './chunk-MQJY4EQV.js';
25
+ import './chunk-XP6UUCZZ.js';
26
+ import './chunk-JFGYT6BI.js';
27
+ import './chunk-XQNKCA2J.js';
28
+ import './chunk-Z6ZWNWWR.js';
29
+ //# sourceMappingURL=agent-AFMDB4GM.js.map
30
+ //# sourceMappingURL=agent-AFMDB4GM.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-3CKNTCRX.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-AFMDB4GM.js"}
@@ -1,10 +1,10 @@
1
- export { addApprovalRule, approvalsPath, findMatchingRule, globMatch, loadApprovalRules, normalizeCommandPrefix, removeApprovalRule, ruleForAction, ruleKey, ruleLabel, saveApprovalRules } from './chunk-D33M2ARL.js';
2
- import './chunk-FFY6NW7P.js';
1
+ export { addApprovalRule, approvalsPath, findMatchingRule, globMatch, loadApprovalRules, normalizeCommandPrefix, removeApprovalRule, ruleForAction, ruleKey, ruleLabel, saveApprovalRules } from './chunk-3SOJZ3VV.js';
2
+ import './chunk-C5AOLTQS.js';
3
3
  import './chunk-O3LABX6I.js';
4
- import './chunk-DHU3OOEI.js';
5
- import './chunk-BWPBB45M.js';
4
+ import './chunk-MQJY4EQV.js';
5
+ import './chunk-XP6UUCZZ.js';
6
6
  import './chunk-JFGYT6BI.js';
7
- import './chunk-BPF3YX2U.js';
7
+ import './chunk-XQNKCA2J.js';
8
8
  import './chunk-Z6ZWNWWR.js';
9
- //# sourceMappingURL=approvals-DHTG3HI4.js.map
10
- //# sourceMappingURL=approvals-DHTG3HI4.js.map
9
+ //# sourceMappingURL=approvals-F2DJGPU7.js.map
10
+ //# sourceMappingURL=approvals-F2DJGPU7.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"approvals-DHTG3HI4.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"approvals-F2DJGPU7.js"}
@@ -0,0 +1,10 @@
1
+ export { attachVgd, daemonDisabledReason } from './chunk-UEXDSWKN.js';
2
+ import './chunk-A3WWRW7U.js';
3
+ import './chunk-VHRSG6CF.js';
4
+ import './chunk-6H2QV5DR.js';
5
+ import './chunk-XP6UUCZZ.js';
6
+ import './chunk-JFGYT6BI.js';
7
+ import './chunk-XQNKCA2J.js';
8
+ import './chunk-Z6ZWNWWR.js';
9
+ //# sourceMappingURL=attach-XTX2Q3AD.js.map
10
+ //# sourceMappingURL=attach-XTX2Q3AD.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"attach-OCQ3I76L.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"attach-XTX2Q3AD.js"}
@@ -0,0 +1,9 @@
1
+ export { baselineCommand, runBaseline } from './chunk-QLNJ3VWO.js';
2
+ import './chunk-5UG4UHKU.js';
3
+ import './chunk-PVNALGTG.js';
4
+ import './chunk-CRAMOEBE.js';
5
+ import './chunk-T7RSQ5WD.js';
6
+ import './chunk-MQJY4EQV.js';
7
+ import './chunk-Z6ZWNWWR.js';
8
+ //# sourceMappingURL=baseline-KTE2C3LW.js.map
9
+ //# sourceMappingURL=baseline-KTE2C3LW.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"baseline-QDC6OQ2X.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"baseline-KTE2C3LW.js"}
@@ -1,4 +1,4 @@
1
- import { ensureVibgrateGitignore } from './chunk-FFY6NW7P.js';
1
+ import { ensureVibgrateGitignore } from './chunk-C5AOLTQS.js';
2
2
  import fs from 'fs';
3
3
  import path from 'path';
4
4
 
@@ -170,5 +170,5 @@ function findMatchingRule(action, rules) {
170
170
  }
171
171
 
172
172
  export { addApprovalRule, approvalsPath, findMatchingRule, globMatch, loadApprovalRules, normalizeCommandPrefix, removeApprovalRule, ruleForAction, ruleKey, ruleLabel, saveApprovalRules };
173
- //# sourceMappingURL=chunk-D33M2ARL.js.map
174
- //# sourceMappingURL=chunk-D33M2ARL.js.map
173
+ //# sourceMappingURL=chunk-3SOJZ3VV.js.map
174
+ //# sourceMappingURL=chunk-3SOJZ3VV.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/code/approvals.ts"],"names":[],"mappings":"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","file":"chunk-D33M2ARL.js","sourcesContent":["/**\n * Allow-always approval rules (P2 — permission parity).\n *\n * The approval gate exists to review state changes, but reviewing the *same*\n * change shape every time (`pnpm test`, edits to a scratch dir) is friction\n * without safety. A user can promote an approval to a standing rule\n * (\"Always allow\"); rules live in `.vibgrate/code-approvals.json` at the repo\n * root so the CLI and VS Code honour the same set, and are re-read on every\n * approval so a revocation (from the VG Code manage UI or by editing the\n * file) takes effect immediately — no session restart, no stale cache.\n *\n * Rules never widen safety: {@link dangerousCommand} still screens every rule\n * match, plan mode still denies everything engine-side before rules are\n * consulted, and a rule-approved action is still announced (notice event) and\n * checkpointed like any human-approved change.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ensureVibgrateGitignore } from '../engine/artifacts.js';\nimport type { MutatingAction, PatchFileAction } from './tools.js';\n\n/** One standing approval. Discriminated by `kind`, mirroring MutatingAction. */\nexport type ApprovalRule =\n /** Matches `run` actions whose normalized command starts with these tokens. */\n | { kind: 'run'; prefix: string }\n /** Matches a single-file action of that op when the path matches the glob. */\n | { kind: 'edit' | 'create' | 'delete'; glob: string }\n /** Matches external `tool` calls by tool name. */\n | { kind: 'tool'; tool: string };\n\nexport function approvalsPath(root: string): string {\n return path.join(root, '.vibgrate', 'code-approvals.json');\n}\n\n/**\n * The stable identity of a rule — used for dedupe and for revocation from\n * hosts that only carry the display string.\n */\nexport function ruleKey(rule: ApprovalRule): string {\n if (rule.kind === 'run') return `run:${rule.prefix}`;\n if (rule.kind === 'tool') return `tool:${rule.tool}`;\n return `${rule.kind}:${rule.glob}`;\n}\n\n/** Human-readable label for notices and manage UIs. */\nexport function ruleLabel(rule: ApprovalRule): string {\n if (rule.kind === 'run') return `run \\`${rule.prefix} …\\``;\n if (rule.kind === 'tool') return `call ${rule.tool}`;\n return `${rule.kind} ${rule.glob}`;\n}\n\n/**\n * Load the rule set, tolerating absence and malformed JSON (an unreadable file\n * means \"no rules\", never a crash — same posture as `.vibgrate/code.json`).\n * Unknown shapes are dropped so an untrusted file cannot inject junk.\n */\nexport function loadApprovalRules(root: string): ApprovalRule[] {\n let raw: unknown;\n try {\n raw = JSON.parse(fs.readFileSync(approvalsPath(root), 'utf8'));\n } catch {\n return [];\n }\n const list = Array.isArray(raw)\n ? raw\n : raw && typeof raw === 'object' && Array.isArray((raw as { rules?: unknown }).rules)\n ? ((raw as { rules: unknown[] }).rules)\n : [];\n const out: ApprovalRule[] = [];\n for (const item of list) {\n const rule = sanitizeRule(item);\n if (rule) out.push(rule);\n }\n return dedupe(out);\n}\n\nfunction sanitizeRule(item: unknown): ApprovalRule | null {\n if (!item || typeof item !== 'object') return null;\n const o = item as Record<string, unknown>;\n if (o.kind === 'run' && typeof o.prefix === 'string' && o.prefix.trim()) {\n return { kind: 'run', prefix: normalizeCommandPrefix(o.prefix) };\n }\n if (o.kind === 'tool' && typeof o.tool === 'string' && o.tool.trim()) {\n return { kind: 'tool', tool: o.tool.trim() };\n }\n if ((o.kind === 'edit' || o.kind === 'create' || o.kind === 'delete') && typeof o.glob === 'string' && o.glob.trim()) {\n return { kind: o.kind, glob: o.glob.trim() };\n }\n return null;\n}\n\nfunction dedupe(rules: ApprovalRule[]): ApprovalRule[] {\n const seen = new Set<string>();\n const out: ApprovalRule[] = [];\n for (const r of rules) {\n const key = ruleKey(r);\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(r);\n }\n return out;\n}\n\n/**\n * Persist the rule set, deterministically sorted so identical sets produce an\n * identical file. Best-effort like other `.vibgrate/` writers — a read-only\n * checkout means no standing rules, never a thrown error mid-approval.\n */\nexport function saveApprovalRules(root: string, rules: ApprovalRule[]): boolean {\n try {\n const dir = path.join(root, '.vibgrate');\n fs.mkdirSync(dir, { recursive: true });\n // First writer into .vibgrate/ creates its .gitignore (create-once): one\n // developer's standing consents must not ride into the team's repo.\n ensureVibgrateGitignore(root);\n const sorted = dedupe(rules).slice().sort((a, b) => ruleKey(a).localeCompare(ruleKey(b)));\n fs.writeFileSync(approvalsPath(root), `${JSON.stringify({ rules: sorted }, null, 2)}\\n`);\n return true;\n } catch {\n return false;\n }\n}\n\n/** Add one rule (deduped). Returns the saved rule, or null when nothing was written. */\nexport function addApprovalRule(root: string, rule: ApprovalRule): ApprovalRule | null {\n const rules = loadApprovalRules(root);\n if (rules.some((r) => ruleKey(r) === ruleKey(rule))) return rule;\n rules.push(rule);\n return saveApprovalRules(root, rules) ? rule : null;\n}\n\n/** Remove the rule with this {@link ruleKey}. Returns true when one was removed and saved. */\nexport function removeApprovalRule(root: string, key: string): boolean {\n const rules = loadApprovalRules(root);\n const kept = rules.filter((r) => ruleKey(r) !== key);\n if (kept.length === rules.length) return false;\n return saveApprovalRules(root, kept);\n}\n\n/**\n * Normalize a shell command to its rule prefix: the first two tokens for the\n * `cmd subcommand [flags…]` shape (`git status`, `pnpm test --watch`), the\n * single token for a one-word command, and the *whole* command\n * (whitespace-normalized) in every other case. Collapsing `rm -f temp.log` to\n * bare `rm` — or `rm foo.log secrets.env` to `rm foo.log` — would turn one\n * blessed invocation into a standing grant covering paths the user never saw\n * (2026-08 audit, D2), so a command with a flag second-token or positional\n * arguments beyond the subcommand keeps its exact form.\n */\nexport function normalizeCommandPrefix(command: string): string {\n const tokens = command.trim().split(/\\s+/).filter(Boolean);\n const head = tokens[0] ?? '';\n const second = tokens[1];\n if (!second) return head;\n if (second.startsWith('-')) return tokens.join(' ');\n // Extra positionals after `cmd subcommand` make the rule exact; trailing\n // flags still collapse to the extensible two-token prefix.\n if (tokens.slice(2).some((t) => !t.startsWith('-'))) return tokens.join(' ');\n return `${head} ${second}`;\n}\n\n/** True when a rule prefix is the extensible `cmd [subcommand]` shape (no flags). */\nfunction extensiblePrefix(prefix: string): boolean {\n return !prefix.split(' ').some((t) => t.startsWith('-'));\n}\n\n/**\n * Shell constructs that can smuggle a second command into what looks like a\n * flag: command substitution, redirects, sequencing, backgrounding, subshells.\n * A `pnpm test` rule must not bless `pnpm test --reporter=$(curl … | sh)` —\n * the appended token is flag-shaped, but its *value* is another program the\n * user never saw. Same screen {@link readOnlyCommand} applies; kept local so\n * safety and approvals stay independent modules.\n */\nconst SHELL_METACHARS = /[><;&|`\\n(){}$]/;\n\n/**\n * Derive the standing rule an \"Always allow\" on this action should create.\n * Patch actions return null — an atomic multi-file transaction has no single\n * honest generalisation, so hosts do not offer Always on patch cards.\n */\nexport function ruleForAction(action: MutatingAction): ApprovalRule | null {\n switch (action.kind) {\n case 'run':\n return { kind: 'run', prefix: normalizeCommandPrefix(action.command) };\n case 'tool':\n return { kind: 'tool', tool: action.name };\n case 'edit':\n case 'create':\n case 'delete':\n return { kind: action.kind, glob: action.file };\n case 'patch':\n return null;\n }\n}\n\n/**\n * Minimal glob match for rule paths: `*` matches within a segment, `**`\n * across segments, `?` one character. Deterministic, no dependency, and\n * conservative — a malformed pattern simply never matches.\n */\nexport function globMatch(glob: string, file: string): boolean {\n let re = '';\n for (let i = 0; i < glob.length; i++) {\n const c = glob[i];\n if (c === '*') {\n if (glob[i + 1] === '*') {\n // `**/` or trailing `**` — match across segments.\n re += '.*';\n i += glob[i + 2] === '/' ? 2 : 1;\n } else {\n re += '[^/]*';\n }\n } else if (c === '?') {\n re += '[^/]';\n } else if ('\\\\^$.|+()[]{}'.includes(c)) {\n re += `\\\\${c}`;\n } else {\n re += c;\n }\n }\n try {\n return new RegExp(`^${re}$`).test(file);\n } catch {\n return false;\n }\n}\n\nfunction fileRuleMatches(rules: ApprovalRule[], op: 'edit' | 'create' | 'delete', file: string): ApprovalRule | null {\n for (const r of rules) {\n if (r.kind === op && globMatch(r.glob, file)) return r;\n }\n return null;\n}\n\n/**\n * The first rule matching this action, or null. A `patch` matches only when\n * *every* file in the transaction is covered by a matching file rule — an\n * atomic approval must never be half-earned.\n */\nexport function findMatchingRule(action: MutatingAction, rules: ApprovalRule[]): ApprovalRule | null {\n if (!rules.length) return null;\n switch (action.kind) {\n case 'run': {\n // Match the FULL whitespace-normalized command, never a truncated form:\n // collapsing `rm foo.log secrets.env` to its first two tokens before\n // comparing would silently discard the appended argument and let a rule\n // saved for `rm foo.log` bless it (2026-08 audit, D2).\n const full = action.command.trim().split(/\\s+/).filter(Boolean).join(' ');\n for (const r of rules) {\n if (r.kind !== 'run') continue;\n if (full === r.prefix) return r;\n // A `cmd [subcommand]` prefix extends to longer commands only when\n // every appended token is a flag (`git status --short`). Appended\n // positionals (extra paths, script arguments) are new state the user\n // never blessed — they re-prompt, and can be Always-allowed exactly.\n if (extensiblePrefix(r.prefix) && full.startsWith(`${r.prefix} `)) {\n const tail = full.slice(r.prefix.length + 1);\n // A flag whose value is a subshell is not an extension of the blessed\n // command, it is a different one — screen the appended text before\n // the flag-shape check, never after.\n if (SHELL_METACHARS.test(tail)) continue;\n const extension = tail.split(' ');\n if (extension.every((t) => t.startsWith('-'))) return r;\n }\n }\n return null;\n }\n case 'tool':\n return rules.find((r) => r.kind === 'tool' && r.tool === action.name) ?? null;\n case 'edit':\n case 'create':\n case 'delete':\n return fileRuleMatches(rules, action.kind, action.file);\n case 'patch': {\n const covered = action.files.every((f: PatchFileAction) => fileRuleMatches(rules, f.op, f.file));\n if (!covered) return null;\n return fileRuleMatches(rules, action.files[0]!.op, action.files[0]!.file);\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/code/approvals.ts"],"names":[],"mappings":"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","file":"chunk-3SOJZ3VV.js","sourcesContent":["/**\n * Allow-always approval rules (P2 — permission parity).\n *\n * The approval gate exists to review state changes, but reviewing the *same*\n * change shape every time (`pnpm test`, edits to a scratch dir) is friction\n * without safety. A user can promote an approval to a standing rule\n * (\"Always allow\"); rules live in `.vibgrate/code-approvals.json` at the repo\n * root so the CLI and VS Code honour the same set, and are re-read on every\n * approval so a revocation (from the VG Code manage UI or by editing the\n * file) takes effect immediately — no session restart, no stale cache.\n *\n * Rules never widen safety: {@link dangerousCommand} still screens every rule\n * match, plan mode still denies everything engine-side before rules are\n * consulted, and a rule-approved action is still announced (notice event) and\n * checkpointed like any human-approved change.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { ensureVibgrateGitignore } from '../engine/artifacts.js';\nimport type { MutatingAction, PatchFileAction } from './tools.js';\n\n/** One standing approval. Discriminated by `kind`, mirroring MutatingAction. */\nexport type ApprovalRule =\n /** Matches `run` actions whose normalized command starts with these tokens. */\n | { kind: 'run'; prefix: string }\n /** Matches a single-file action of that op when the path matches the glob. */\n | { kind: 'edit' | 'create' | 'delete'; glob: string }\n /** Matches external `tool` calls by tool name. */\n | { kind: 'tool'; tool: string };\n\nexport function approvalsPath(root: string): string {\n return path.join(root, '.vibgrate', 'code-approvals.json');\n}\n\n/**\n * The stable identity of a rule — used for dedupe and for revocation from\n * hosts that only carry the display string.\n */\nexport function ruleKey(rule: ApprovalRule): string {\n if (rule.kind === 'run') return `run:${rule.prefix}`;\n if (rule.kind === 'tool') return `tool:${rule.tool}`;\n return `${rule.kind}:${rule.glob}`;\n}\n\n/** Human-readable label for notices and manage UIs. */\nexport function ruleLabel(rule: ApprovalRule): string {\n if (rule.kind === 'run') return `run \\`${rule.prefix} …\\``;\n if (rule.kind === 'tool') return `call ${rule.tool}`;\n return `${rule.kind} ${rule.glob}`;\n}\n\n/**\n * Load the rule set, tolerating absence and malformed JSON (an unreadable file\n * means \"no rules\", never a crash — same posture as `.vibgrate/code.json`).\n * Unknown shapes are dropped so an untrusted file cannot inject junk.\n */\nexport function loadApprovalRules(root: string): ApprovalRule[] {\n let raw: unknown;\n try {\n raw = JSON.parse(fs.readFileSync(approvalsPath(root), 'utf8'));\n } catch {\n return [];\n }\n const list = Array.isArray(raw)\n ? raw\n : raw && typeof raw === 'object' && Array.isArray((raw as { rules?: unknown }).rules)\n ? ((raw as { rules: unknown[] }).rules)\n : [];\n const out: ApprovalRule[] = [];\n for (const item of list) {\n const rule = sanitizeRule(item);\n if (rule) out.push(rule);\n }\n return dedupe(out);\n}\n\nfunction sanitizeRule(item: unknown): ApprovalRule | null {\n if (!item || typeof item !== 'object') return null;\n const o = item as Record<string, unknown>;\n if (o.kind === 'run' && typeof o.prefix === 'string' && o.prefix.trim()) {\n return { kind: 'run', prefix: normalizeCommandPrefix(o.prefix) };\n }\n if (o.kind === 'tool' && typeof o.tool === 'string' && o.tool.trim()) {\n return { kind: 'tool', tool: o.tool.trim() };\n }\n if ((o.kind === 'edit' || o.kind === 'create' || o.kind === 'delete') && typeof o.glob === 'string' && o.glob.trim()) {\n return { kind: o.kind, glob: o.glob.trim() };\n }\n return null;\n}\n\nfunction dedupe(rules: ApprovalRule[]): ApprovalRule[] {\n const seen = new Set<string>();\n const out: ApprovalRule[] = [];\n for (const r of rules) {\n const key = ruleKey(r);\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(r);\n }\n return out;\n}\n\n/**\n * Persist the rule set, deterministically sorted so identical sets produce an\n * identical file. Best-effort like other `.vibgrate/` writers — a read-only\n * checkout means no standing rules, never a thrown error mid-approval.\n */\nexport function saveApprovalRules(root: string, rules: ApprovalRule[]): boolean {\n try {\n const dir = path.join(root, '.vibgrate');\n fs.mkdirSync(dir, { recursive: true });\n // First writer into .vibgrate/ creates its .gitignore (create-once): one\n // developer's standing consents must not ride into the team's repo.\n ensureVibgrateGitignore(root);\n const sorted = dedupe(rules).slice().sort((a, b) => ruleKey(a).localeCompare(ruleKey(b)));\n fs.writeFileSync(approvalsPath(root), `${JSON.stringify({ rules: sorted }, null, 2)}\\n`);\n return true;\n } catch {\n return false;\n }\n}\n\n/** Add one rule (deduped). Returns the saved rule, or null when nothing was written. */\nexport function addApprovalRule(root: string, rule: ApprovalRule): ApprovalRule | null {\n const rules = loadApprovalRules(root);\n if (rules.some((r) => ruleKey(r) === ruleKey(rule))) return rule;\n rules.push(rule);\n return saveApprovalRules(root, rules) ? rule : null;\n}\n\n/** Remove the rule with this {@link ruleKey}. Returns true when one was removed and saved. */\nexport function removeApprovalRule(root: string, key: string): boolean {\n const rules = loadApprovalRules(root);\n const kept = rules.filter((r) => ruleKey(r) !== key);\n if (kept.length === rules.length) return false;\n return saveApprovalRules(root, kept);\n}\n\n/**\n * Normalize a shell command to its rule prefix: the first two tokens for the\n * `cmd subcommand [flags…]` shape (`git status`, `pnpm test --watch`), the\n * single token for a one-word command, and the *whole* command\n * (whitespace-normalized) in every other case. Collapsing `rm -f temp.log` to\n * bare `rm` — or `rm foo.log secrets.env` to `rm foo.log` — would turn one\n * blessed invocation into a standing grant covering paths the user never saw\n * (2026-08 audit, D2), so a command with a flag second-token or positional\n * arguments beyond the subcommand keeps its exact form.\n */\nexport function normalizeCommandPrefix(command: string): string {\n const tokens = command.trim().split(/\\s+/).filter(Boolean);\n const head = tokens[0] ?? '';\n const second = tokens[1];\n if (!second) return head;\n if (second.startsWith('-')) return tokens.join(' ');\n // Extra positionals after `cmd subcommand` make the rule exact; trailing\n // flags still collapse to the extensible two-token prefix.\n if (tokens.slice(2).some((t) => !t.startsWith('-'))) return tokens.join(' ');\n return `${head} ${second}`;\n}\n\n/** True when a rule prefix is the extensible `cmd [subcommand]` shape (no flags). */\nfunction extensiblePrefix(prefix: string): boolean {\n return !prefix.split(' ').some((t) => t.startsWith('-'));\n}\n\n/**\n * Shell constructs that can smuggle a second command into what looks like a\n * flag: command substitution, redirects, sequencing, backgrounding, subshells.\n * A `pnpm test` rule must not bless `pnpm test --reporter=$(curl … | sh)` —\n * the appended token is flag-shaped, but its *value* is another program the\n * user never saw. Same screen {@link readOnlyCommand} applies; kept local so\n * safety and approvals stay independent modules.\n */\nconst SHELL_METACHARS = /[><;&|`\\n(){}$]/;\n\n/**\n * Derive the standing rule an \"Always allow\" on this action should create.\n * Patch actions return null — an atomic multi-file transaction has no single\n * honest generalisation, so hosts do not offer Always on patch cards.\n */\nexport function ruleForAction(action: MutatingAction): ApprovalRule | null {\n switch (action.kind) {\n case 'run':\n return { kind: 'run', prefix: normalizeCommandPrefix(action.command) };\n case 'tool':\n return { kind: 'tool', tool: action.name };\n case 'edit':\n case 'create':\n case 'delete':\n return { kind: action.kind, glob: action.file };\n case 'patch':\n return null;\n }\n}\n\n/**\n * Minimal glob match for rule paths: `*` matches within a segment, `**`\n * across segments, `?` one character. Deterministic, no dependency, and\n * conservative — a malformed pattern simply never matches.\n */\nexport function globMatch(glob: string, file: string): boolean {\n let re = '';\n for (let i = 0; i < glob.length; i++) {\n const c = glob[i];\n if (c === '*') {\n if (glob[i + 1] === '*') {\n // `**/` or trailing `**` — match across segments.\n re += '.*';\n i += glob[i + 2] === '/' ? 2 : 1;\n } else {\n re += '[^/]*';\n }\n } else if (c === '?') {\n re += '[^/]';\n } else if ('\\\\^$.|+()[]{}'.includes(c)) {\n re += `\\\\${c}`;\n } else {\n re += c;\n }\n }\n try {\n return new RegExp(`^${re}$`).test(file);\n } catch {\n return false;\n }\n}\n\nfunction fileRuleMatches(rules: ApprovalRule[], op: 'edit' | 'create' | 'delete', file: string): ApprovalRule | null {\n for (const r of rules) {\n if (r.kind === op && globMatch(r.glob, file)) return r;\n }\n return null;\n}\n\n/**\n * The first rule matching this action, or null. A `patch` matches only when\n * *every* file in the transaction is covered by a matching file rule — an\n * atomic approval must never be half-earned.\n */\nexport function findMatchingRule(action: MutatingAction, rules: ApprovalRule[]): ApprovalRule | null {\n if (!rules.length) return null;\n switch (action.kind) {\n case 'run': {\n // Match the FULL whitespace-normalized command, never a truncated form:\n // collapsing `rm foo.log secrets.env` to its first two tokens before\n // comparing would silently discard the appended argument and let a rule\n // saved for `rm foo.log` bless it (2026-08 audit, D2).\n const full = action.command.trim().split(/\\s+/).filter(Boolean).join(' ');\n for (const r of rules) {\n if (r.kind !== 'run') continue;\n if (full === r.prefix) return r;\n // A `cmd [subcommand]` prefix extends to longer commands only when\n // every appended token is a flag (`git status --short`). Appended\n // positionals (extra paths, script arguments) are new state the user\n // never blessed — they re-prompt, and can be Always-allowed exactly.\n if (extensiblePrefix(r.prefix) && full.startsWith(`${r.prefix} `)) {\n const tail = full.slice(r.prefix.length + 1);\n // A flag whose value is a subshell is not an extension of the blessed\n // command, it is a different one — screen the appended text before\n // the flag-shape check, never after.\n if (SHELL_METACHARS.test(tail)) continue;\n const extension = tail.split(' ');\n if (extension.every((t) => t.startsWith('-'))) return r;\n }\n }\n return null;\n }\n case 'tool':\n return rules.find((r) => r.kind === 'tool' && r.tool === action.name) ?? null;\n case 'edit':\n case 'create':\n case 'delete':\n return fileRuleMatches(rules, action.kind, action.file);\n case 'patch': {\n const covered = action.files.every((f: PatchFileAction) => fileRuleMatches(rules, f.op, f.file));\n if (!covered) return null;\n return fileRuleMatches(rules, action.files[0]!.op, action.files[0]!.file);\n }\n }\n}\n"]}
@@ -1,13 +1,14 @@
1
1
  import { readGlobal, applyGlobalOptions } from './chunk-YENM3HT7.js';
2
2
  import { json, info, c } from './chunk-CT5BS56U.js';
3
- import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-F46Q3AEI.js';
3
+ import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-CEJIX3O7.js';
4
4
  import { CliError, ExitCode } from './chunk-MS6V5XKB.js';
5
5
  import { init_cli_invocation, reinvokeCli } from './chunk-EZ7UC5Y5.js';
6
- import { loadGraph } from './chunk-O5ASXWKF.js';
7
- import { vgdIsRunning, vgdRequest } from './chunk-E53WBVUQ.js';
8
- import { vgdSocketPath, vgdPidPath } from './chunk-NDNNOAS6.js';
9
- import { VERSION } from './chunk-DHU3OOEI.js';
6
+ import { loadGraph } from './chunk-ARGYMFST.js';
7
+ import { vgdIsRunning, vgdRequest } from './chunk-VHRSG6CF.js';
8
+ import { vgdSocketPath, vgdPidPath } from './chunk-6H2QV5DR.js';
9
+ import { VERSION } from './chunk-MQJY4EQV.js';
10
10
  import * as fs from 'fs';
11
+ import * as net from 'net';
11
12
  import * as path2 from 'path';
12
13
  import { spawn } from 'child_process';
13
14
  import * as semver from 'semver';
@@ -105,13 +106,33 @@ function registerDaemon(program) {
105
106
  }
106
107
  let requestShutdown = () => {
107
108
  };
108
- const server = await startVgdServer({
109
+ const serverOptions = {
109
110
  socketPath,
110
111
  onShutdownRequest: () => requestShutdown(),
111
112
  // Show the daemon working: graph publishes, branch switches, new repos,
112
113
  // and every semantic index build. Silent under --quiet/--json.
113
114
  log: global.quiet || global.json ? void 0 : (message) => info(c.dim(`vgd \xB7 ${message}`))
114
- });
115
+ };
116
+ let server;
117
+ try {
118
+ server = await startVgdServer(serverOptions);
119
+ } catch (e) {
120
+ if (e?.code !== "EADDRINUSE") throw e;
121
+ const takeover = await retireWedgedVgd(socketPath);
122
+ if (!takeover.ok) {
123
+ if (takeover.live) {
124
+ throw new CliError(`vgd is already running at ${socketPath}`, ExitCode.ERROR);
125
+ }
126
+ throw new CliError(
127
+ `${socketPath} is held by a process that does not answer vgd requests (${takeover.reason}). End the stale daemon (a node/vg process running "daemon start"), then re-run \`vg daemon start\`.`,
128
+ ExitCode.ERROR
129
+ );
130
+ }
131
+ if (!global.quiet && !global.json) {
132
+ info(c.dim(`vgd \xB7 retired a stale daemon (pid ${takeover.pid}) that was holding ${socketPath}`));
133
+ }
134
+ server = await startVgdServer(serverOptions);
135
+ }
115
136
  if (!global.quiet) {
116
137
  info(`vgd \xB7 listening on ${c.dim(server.socketPath)} (${VGD_PROTOCOL_VERSION})`);
117
138
  info(c.dim(" register a workspace: vg daemon register"));
@@ -252,7 +273,7 @@ function registerDaemon(program) {
252
273
  if (!await vgdIsRunning({ socketPath })) {
253
274
  throw new CliError(`vgd is not running \u2014 start it with \`vg daemon start\` (${socketPath})`, ExitCode.NOT_FOUND);
254
275
  }
255
- const { loadFederation } = await import('./federation-SZYVHYB2.js');
276
+ const { loadFederation } = await import('./federation-M4ZNXOPX.js');
256
277
  const fed = loadFederation(primary);
257
278
  if (!fed) throw new CliError(`could not load federation for ${primary}`, ExitCode.ERROR);
258
279
  const res = await vgdRequest(
@@ -290,9 +311,9 @@ function registerDaemon(program) {
290
311
  throw new CliError(loaded.error, ExitCode.NOT_FOUND);
291
312
  }
292
313
  if (!loaded.ok) {
293
- const { loadGraph: loadGraph2 } = await import('./load-6CYLMUT5.js');
294
- const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
295
- const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
314
+ const { loadGraph: loadGraph2 } = await import('./load-4EY64JJO.js');
315
+ const { detectGitRef } = await import('./git-ref-LMT3EXYY.js');
316
+ const { repositoryIdFromRoot } = await import('./paths-RVK6FKRN.js');
296
317
  const graph = loadGraph2(root, global.graph);
297
318
  if (!graph) {
298
319
  throw new CliError(
@@ -413,7 +434,7 @@ function socketOf(cmd) {
413
434
  }
414
435
  function spawnDetachedDaemonStart(socketPath) {
415
436
  const opts = {
416
- detached: true,
437
+ detached: process.platform !== "win32",
417
438
  stdio: "ignore",
418
439
  env: process.env,
419
440
  windowsHide: true
@@ -440,7 +461,25 @@ async function ensureVgdSoft(socketPath = vgdSocketPath(), readyBudgetMs = 1500)
440
461
  return { running: false, started: false };
441
462
  }
442
463
  }
443
- async function startDetachedVgd(socketPath) {
464
+ var START_BIND_ATTEMPTS = 3;
465
+ async function startDetachedVgd(socketPath, deps = {}) {
466
+ const startOnce = deps.startOnce ?? startDetachedVgdOnce;
467
+ const skewOf = deps.skew ?? vgdVersionSkew;
468
+ const stop = deps.stop ?? stopVgd;
469
+ let pid;
470
+ for (let attempt = 1; attempt <= START_BIND_ATTEMPTS; attempt++) {
471
+ pid = await startOnce(socketPath);
472
+ const skew = await skewOf(socketPath);
473
+ if (skew.running && skew.state !== "older") return pid;
474
+ if (!skew.running) continue;
475
+ await stop(socketPath, { force: true });
476
+ }
477
+ throw new CliError(
478
+ `an older vgd keeps re-binding ${socketPath} \u2014 another running client is starting it (commonly a VS Code extension bundling an older engine, or a long-lived \`vg serve\`). Update or restart that client, then run "vg daemon restart --force".`,
479
+ ExitCode.ERROR
480
+ );
481
+ }
482
+ async function startDetachedVgdOnce(socketPath) {
444
483
  const child = spawnDetachedDaemonStart(socketPath);
445
484
  child.unref();
446
485
  const readyMs = 3e4;
@@ -491,6 +530,47 @@ async function ensureVgd(socketPath = vgdSocketPath(), opts = {}) {
491
530
  await stopVgd(socketPath, { force: true });
492
531
  return { started: true, pid: await startDetachedVgd(socketPath), replaced: { version: skew.version } };
493
532
  }
533
+ async function retireWedgedVgd(socketPath, deps = {}) {
534
+ const isRunning = deps.isRunning ?? ((s) => vgdIsRunning({ socketPath: s }));
535
+ const readPid = deps.readPid ?? readVgdPid;
536
+ const signal = deps.signal ?? signalPid;
537
+ const held = deps.held ?? vgdSocketHeld;
538
+ const waitBudgetMs = deps.waitBudgetMs ?? 3e3;
539
+ const selfPid = deps.selfPid ?? process.pid;
540
+ if (await isRunning(socketPath)) return { ok: false, live: true };
541
+ const pid = readPid();
542
+ if (pid == null) return { ok: false, reason: "no pid file identifies the holder" };
543
+ if (pid === selfPid) return { ok: false, reason: "the pid file points at this process" };
544
+ if (!signal(pid, "SIGTERM")) return { ok: false, reason: `pid ${pid} from the pid file is not signalable` };
545
+ if (await waitForSocketFree(socketPath, waitBudgetMs, held)) return { ok: true, pid };
546
+ signal(pid, "SIGKILL");
547
+ if (await waitForSocketFree(socketPath, waitBudgetMs, held)) return { ok: true, pid };
548
+ return { ok: false, reason: `pid ${pid} was signalled but ${socketPath} is still held` };
549
+ }
550
+ async function waitForSocketFree(socketPath, budgetMs, held) {
551
+ const deadline = Date.now() + budgetMs;
552
+ for (; ; ) {
553
+ if (!await held(socketPath)) return true;
554
+ if (Date.now() >= deadline) return false;
555
+ await sleep(100);
556
+ }
557
+ }
558
+ function vgdSocketHeld(socketPath, timeoutMs = 1e3) {
559
+ return new Promise((resolve3) => {
560
+ const socket = net.createConnection(socketPath);
561
+ let settled = false;
562
+ const done = (heldNow) => {
563
+ if (settled) return;
564
+ settled = true;
565
+ clearTimeout(timer);
566
+ socket.destroy();
567
+ resolve3(heldNow);
568
+ };
569
+ const timer = setTimeout(() => done(true), timeoutMs);
570
+ socket.once("connect", () => done(true));
571
+ socket.once("error", () => done(false));
572
+ });
573
+ }
494
574
  async function stopVgd(socketPath, opts = {}) {
495
575
  if (!await vgdIsRunning({ socketPath })) return "not-running";
496
576
  const livePid = opts.force ? await vgdReportedPid(socketPath) : null;
@@ -546,11 +626,11 @@ async function vgdReportedPid(socketPath) {
546
626
  async function restartVgdIfRunning(socketPath = vgdSocketPath(), opts = {}) {
547
627
  try {
548
628
  const stopResult = await stopVgd(socketPath, opts);
549
- if (stopResult === "not-running") return "not-running";
629
+ if (stopResult === "not-running" && !opts.startIfNotRunning) return "not-running";
550
630
  if (stopResult === "refused") return "refused";
551
631
  if (stopResult === "failed") return "failed";
552
632
  await startDetachedVgd(socketPath);
553
- return "restarted";
633
+ return stopResult === "not-running" ? "started" : "restarted";
554
634
  } catch {
555
635
  return "failed";
556
636
  }
@@ -565,12 +645,12 @@ function readVgdPid() {
565
645
  }
566
646
  }
567
647
  async function repositoryIdForCwd(socketPath, root) {
568
- const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
648
+ const { repositoryIdFromRoot } = await import('./paths-RVK6FKRN.js');
569
649
  const reg = await vgdRequest({ op: "register", root }, { socketPath });
570
650
  if (reg.ok && "workspace" in reg) return reg.workspace.id;
571
651
  return repositoryIdFromRoot(root);
572
652
  }
573
653
 
574
- export { compareDaemonVersion, ensureVgd, ensureVgdSoft, registerDaemon, requireGraph, restartVgdIfRunning, rootOf, stopVgd, vgdCliVersion, vgdVersionSkew };
575
- //# sourceMappingURL=chunk-JGBOYZAF.js.map
576
- //# sourceMappingURL=chunk-JGBOYZAF.js.map
654
+ export { compareDaemonVersion, ensureVgd, ensureVgdSoft, registerDaemon, requireGraph, restartVgdIfRunning, retireWedgedVgd, rootOf, startDetachedVgd, stopVgd, vgdCliVersion, vgdVersionSkew };
655
+ //# sourceMappingURL=chunk-3XMTRK24.js.map
656
+ //# sourceMappingURL=chunk-3XMTRK24.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/util.ts","../src/commands/daemon.ts"],"names":["path","loadGraph","c","resolve","pid"],"mappings":"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","file":"chunk-3XMTRK24.js","sourcesContent":["import * as path from 'node:path';\nimport { loadGraph } from '../engine/load.js';\nimport { CliError, ExitCode } from '../util/exit.js';\nimport type { GlobalOpts } from '../cli-options.js';\nimport type { VgGraph } from '../schema.js';\n\nexport function rootOf(global: GlobalOpts): string {\n return path.resolve(global.cwd ?? '.');\n}\n\n/** Load the committed graph, or fail with an actionable NOT_FOUND error. */\nexport function requireGraph(global: GlobalOpts): { root: string; graph: VgGraph } {\n const root = rootOf(global);\n const graph = loadGraph(root, global.graph);\n if (!graph) {\n throw new CliError(\n `no map found — run \\`vg\\` to build one first` +\n (global.graph ? ` (looked at ${global.graph})` : ''),\n ExitCode.NOT_FOUND,\n );\n }\n return { root, graph };\n}\n","import * as fs from 'node:fs';\nimport * as net from 'node:net';\nimport * as path from 'node:path';\nimport { spawn } from 'node:child_process';\nimport { Command } from 'commander';\nimport * as semver from 'semver';\nimport { applyGlobalOptions, readGlobal } from '../cli-options.js';\nimport { VERSION } from '../version.js';\nimport { startVgdServer, vgdIsRunning, vgdPidPath, vgdRequest, vgdSocketPath, VGD_PROTOCOL_VERSION } from '../runtime/vgd/index.js';\nimport { rootOf } from './util.js';\nimport { CliError, ExitCode } from '../util/exit.js';\nimport { reinvokeCli } from '../util/cli-invocation.js';\nimport { c, info, json } from '../util/output.js';\n\n/**\n * `vg daemon` — lightweight local Fusion Runtime daemon (`vgd`) prototype.\n *\n * Phase 2 slice: local socket + workspace registry. Interactive `vg code`\n * attaches via `startCodeRuntimeSession` (ensures this standalone daemon).\n * No overlays yet. Safe to start/stop; does not mutate repos.\n */\nexport function registerDaemon(program: Command): void {\n const cmd = program\n .command('daemon')\n .description('local Fusion Runtime daemon (vgd) — workspace registry prototype')\n .option('--socket <path>', 'override the daemon socket path');\n\n const status = cmd\n .command('status')\n .description('show whether vgd is running and how many workspaces it tracks')\n .action(async function (this: Command) {\n const global = readGlobal(this);\n const socketPath = socketOf(this);\n const running = await vgdIsRunning({ socketPath });\n if (!running) {\n if (global.json) {\n json({ running: false, socketPath, version: VGD_PROTOCOL_VERSION });\n } else {\n info(c.dim(`vgd · not running (${socketPath})`));\n }\n process.exitCode = ExitCode.NOT_FOUND;\n return;\n }\n const res = await vgdRequest({ op: 'status' }, { socketPath });\n if (!res.ok) throw new CliError(res.error, ExitCode.ERROR);\n // \"Warm\" used to mean the code map only, while every client still loaded\n // its own embedder — so the semantic state is reported next to the graph\n // slots rather than left to be inferred.\n const semantic = await vgdRequest({ op: 'embed-status' }, { socketPath }).catch(() => null);\n const semanticPayload = semantic && semantic.ok && 'semantic' in semantic ? semantic.semantic : undefined;\n const skew = await vgdVersionSkew(socketPath);\n if (global.json) json({ running: true, ...res, semantic: semanticPayload, skew });\n else if ('pid' in res) {\n const slots = typeof res.graphSlots === 'number' ? ` · ${res.graphSlots} graph slot(s)` : '';\n // Always print the build, even when the daemon is too old to report one\n // — a blank where the version should be is what made this skew\n // invisible in the first place.\n const cli = ` · cli ${describeVersion(res.cliVersion ?? null)}`;\n info(\n `vgd · running pid ${res.pid}${cli} · ${res.workspaces} workspace(s)${slots} · ${res.uptimeMs}ms up · ${c.dim(res.socketPath)}`,\n );\n if (skew.running && skew.state !== 'match') {\n const verb = skew.state === 'older' ? 'older than' : 'newer than';\n info(\n c.dim(\n ` ⚠ this daemon is ${verb} the CLI you just ran (${VERSION})` +\n (skew.state === 'older' ? ' — run \"vg daemon restart --force\" to bring it up to date' : ''),\n ),\n );\n }\n const fresh = 'freshness' in res && Array.isArray(res.freshness) ? res.freshness : [];\n if (fresh.length) {\n const watching = fresh.filter((f) => f.watching).length;\n const building = fresh.filter((f) => f.building);\n const pending = fresh.reduce((n, f) => n + f.pending, 0);\n const detail = [\n `${watching}/${fresh.length} watched`,\n building.length ? `${building.length} rebuilding` : '',\n pending ? `${pending} change(s) pending` : '',\n ]\n .filter(Boolean)\n .join(' · ');\n info(` freshness · ${detail}`);\n for (const f of fresh) {\n if (f.watching && !f.building && !f.pending) continue;\n const state = f.building ? 'rebuilding' : f.watching ? `${f.pending} pending` : 'not watched (no recursive fs.watch here)';\n info(c.dim(` ${f.repositoryId}@${f.gitRef} · ${state}`));\n }\n }\n if (semanticPayload) {\n const ready = semanticPayload.slots.filter((sl) => sl.state === 'ready');\n const vectors = ready.reduce((n, sl) => n + sl.vectors, 0);\n // \"worker stopped · 0/0 index(es)\" reads like a broken daemon when\n // it usually means nobody has published a map yet — the index is\n // slot-scoped, so no graph slot means there is nothing to index.\n const detail =\n semanticPayload.worker === 'unavailable'\n ? c.dim(semanticPayload.reason ?? 'semantic off — lexical only')\n : semanticPayload.slots.length === 0\n ? c.dim('no map published yet — run `vg build` in a repo (the index follows the graph slot)')\n : `${ready.length}/${semanticPayload.slots.length} index(es) ready · ${vectors} vector(s)` +\n (semanticPayload.model ? ` · ${semanticPayload.model}` : '');\n info(` semantic · worker ${semanticPayload.worker} · ${detail}`);\n for (const sl of semanticPayload.slots) {\n if (sl.state === 'ready') continue;\n const pending = typeof sl.pending === 'number' && sl.pending > 0 ? ` · ${sl.pending} pending` : '';\n info(\n c.dim(` ${sl.repositoryId}@${sl.gitRef} · ${sl.state}${pending}${sl.error ? ` — ${sl.error}` : ''}`),\n );\n }\n }\n }\n });\n applyGlobalOptions(status);\n\n const start = cmd\n .command('start')\n .description('run vgd in the foreground (Ctrl-C to stop)')\n .action(async function (this: Command) {\n const global = readGlobal(this);\n const socketPath = socketOf(this);\n if (await vgdIsRunning({ socketPath })) {\n throw new CliError(`vgd is already running at ${socketPath}`, ExitCode.ERROR);\n }\n // The shutdown closure needs the server; the server needs the hook.\n // Bridge with a mutable ref so `vg daemon stop` can reach us.\n let requestShutdown: () => void = () => {};\n const serverOptions = {\n socketPath,\n onShutdownRequest: () => requestShutdown(),\n // Show the daemon working: graph publishes, branch switches, new repos,\n // and every semantic index build. Silent under --quiet/--json.\n log: global.quiet || global.json ? undefined : (message: string) => info(c.dim(`vgd · ${message}`)),\n };\n let server;\n try {\n server = await startVgdServer(serverOptions);\n } catch (e) {\n if ((e as NodeJS.ErrnoException)?.code !== 'EADDRINUSE') throw e;\n // The address is held, yet nothing answered the liveness check above:\n // a wedged or stale daemon (typically one left behind by an editor\n // extension update) is squatting on the socket. Every `stopVgd` and\n // `ensureVgd` sees \"not running\" for such a holder, so without a\n // takeover here each `daemon ensure` becomes an infinite\n // start → EADDRINUSE → exit-1 loop. Retire the holder via its pid\n // file and bind again rather than surfacing the raw bind error.\n const takeover = await retireWedgedVgd(socketPath);\n if (!takeover.ok) {\n if (takeover.live) {\n // Lost a start race to a healthy daemon — that is the ordinary\n // already-running case, not a wedge.\n throw new CliError(`vgd is already running at ${socketPath}`, ExitCode.ERROR);\n }\n throw new CliError(\n `${socketPath} is held by a process that does not answer vgd requests (${takeover.reason}). ` +\n 'End the stale daemon (a node/vg process running \"daemon start\"), then re-run `vg daemon start`.',\n ExitCode.ERROR,\n );\n }\n if (!global.quiet && !global.json) {\n info(c.dim(`vgd · retired a stale daemon (pid ${takeover.pid}) that was holding ${socketPath}`));\n }\n server = await startVgdServer(serverOptions);\n }\n if (!global.quiet) {\n info(`vgd · listening on ${c.dim(server.socketPath)} (${VGD_PROTOCOL_VERSION})`);\n info(c.dim(' register a workspace: vg daemon register'));\n info(c.dim(' status: vg daemon status'));\n }\n\n const shutdown = async (): Promise<void> => {\n await server.close();\n if (!global.quiet) info(c.dim('vgd · stopped'));\n process.exit(0);\n };\n requestShutdown = () => void shutdown();\n process.on('SIGINT', () => void shutdown());\n process.on('SIGTERM', () => void shutdown());\n // Keep the event loop alive until signal.\n await new Promise(() => {});\n });\n applyGlobalOptions(start);\n\n /**\n * Idempotent start for host UIs (VS Code) and agents: if vgd is already\n * listening, exit 0; otherwise spawn a detached background `daemon start`.\n */\n const ensure = cmd\n .command('ensure')\n .description('ensure vgd is running on this build (start or replace in background if needed)')\n .option('--allow-version-mismatch', 'attach to an older running vgd instead of replacing it')\n .action(async function (this: Command) {\n const global = readGlobal(this);\n const socketPath = socketOf(this);\n const opts = this.opts() as { allowVersionMismatch?: boolean };\n const ensured = await ensureVgd(socketPath, { allowVersionMismatch: opts.allowVersionMismatch });\n const res = await vgdRequest({ op: 'status' }, { socketPath });\n if (!res.ok) {\n throw new CliError(\n ensured.started\n ? `vgd started (pid ${ensured.pid ?? '?'}) but status failed: ${res.error} (${socketPath})`\n : `vgd is running but status failed: ${res.error} (${socketPath})`,\n ExitCode.ERROR,\n );\n }\n if (global.json) {\n json({ running: true, ensured: ensured.started, replaced: ensured.replaced ?? null, ...res });\n } else if (!global.quiet) {\n const pid = 'pid' in res ? res.pid : ensured.pid;\n if (ensured.replaced) {\n info(\n `vgd · replaced ${describeVersion(ensured.replaced.version)} daemon with ${VERSION} · pid ${pid} · ${c.dim(socketPath)}`,\n );\n } else {\n info(\n ensured.started\n ? `vgd · started in background pid ${pid} · ${c.dim(socketPath)}`\n : `vgd · already running pid ${pid} · ${c.dim(socketPath)}`,\n );\n }\n }\n });\n applyGlobalOptions(ensure);\n\n const stop = cmd\n .command('stop')\n .description('stop the running vgd (idempotent — succeeds if none is running)')\n .option('--force', 'escalate to SIGTERM/SIGKILL if it will not stop politely')\n .action(async function (this: Command) {\n const global = readGlobal(this);\n const socketPath = socketOf(this);\n const force = Boolean((this.opts() as { force?: boolean }).force);\n const result = await stopVgd(socketPath, { force });\n if (global.json) {\n json({ stopped: result === 'stopped', result, socketPath });\n } else if (!global.quiet) {\n if (result === 'stopped') info(`vgd · stopped ${c.dim(socketPath)}`);\n else if (result === 'not-running') info(c.dim(`vgd · not running (${socketPath})`));\n }\n if (result === 'refused') {\n throw new CliError(\n 'this vgd cannot be stopped remotely — it is running inside another process; stop that process instead',\n ExitCode.ERROR,\n );\n }\n if (result === 'failed') {\n throw new CliError(\n `vgd did not stop within 5s (${socketPath}) — retry with \\`vg daemon stop --force\\` to escalate to a signal`,\n ExitCode.ERROR,\n );\n }\n });\n applyGlobalOptions(stop);\n\n const restart = cmd\n .command('restart')\n .description('restart vgd (stop if running, then start in the background)')\n .option('--force', 'escalate to SIGTERM/SIGKILL if it will not stop politely')\n .action(async function (this: Command) {\n const global = readGlobal(this);\n const socketPath = socketOf(this);\n const force = Boolean((this.opts() as { force?: boolean }).force);\n const stopResult = await stopVgd(socketPath, { force });\n if (stopResult === 'refused') {\n throw new CliError(\n 'this vgd cannot be stopped remotely — it is running inside another process; stop that process instead',\n ExitCode.ERROR,\n );\n }\n if (stopResult === 'failed') {\n throw new CliError(\n `vgd did not stop within 5s (${socketPath}) — retry with \\`vg daemon restart --force\\` to escalate to a signal`,\n ExitCode.ERROR,\n );\n }\n await startDetachedVgd(socketPath);\n const res = await vgdRequest({ op: 'status' }, { socketPath });\n if (global.json) {\n json({ running: true, restarted: true, ...(res.ok ? res : { socketPath }) });\n } else if (!global.quiet) {\n const pid = res.ok && 'pid' in res ? res.pid : '?';\n info(`vgd · restarted pid ${pid} · ${c.dim(socketPath)}`);\n }\n });\n applyGlobalOptions(restart);\n\n const register = cmd\n .command('register')\n .description('register the current repository with a running vgd')\n .argument('[root]', 'repository root (default: cwd)')\n .action(async function (this: Command, rootArg?: string) {\n const global = readGlobal(this);\n const socketPath = socketOf(this);\n const root = path.resolve(rootArg ?? rootOf(global));\n if (!(await vgdIsRunning({ socketPath }))) {\n throw new CliError(`vgd is not running — start it with \\`vg daemon start\\` (${socketPath})`, ExitCode.NOT_FOUND);\n }\n const res = await vgdRequest({ op: 'register', root }, { socketPath });\n if (!res.ok) throw new CliError(res.error, ExitCode.ERROR);\n if (global.json) json(res);\n else if ('workspace' in res) {\n info(`vgd · registered ${res.workspace.root}`);\n info(c.dim(` id ${res.workspace.id}`));\n info(c.dim(` graph ${res.workspace.graphPath}`));\n }\n });\n applyGlobalOptions(register);\n\n const list = cmd\n .command('list')\n .description('list workspaces registered with the running vgd')\n .action(async function (this: Command) {\n const global = readGlobal(this);\n const socketPath = socketOf(this);\n if (!(await vgdIsRunning({ socketPath }))) {\n throw new CliError(`vgd is not running (${socketPath})`, ExitCode.NOT_FOUND);\n }\n const res = await vgdRequest({ op: 'list' }, { socketPath });\n if (!res.ok) throw new CliError(res.error, ExitCode.ERROR);\n if (global.json) json(res);\n else if ('workspaces' in res && Array.isArray(res.workspaces)) {\n if (res.workspaces.length === 0) info(c.dim('vgd · no workspaces registered'));\n for (const w of res.workspaces) {\n const tag = w.label ? ` (${w.label}${w.role ? `/${w.role}` : ''})` : '';\n info(`${w.root}${tag}`);\n info(c.dim(` id ${w.id} · graph ${w.graphPath}`));\n }\n }\n });\n applyGlobalOptions(list);\n\n const federation = cmd\n .command('federation')\n .description('register a multi-root federation from .vibgrate/federation.json (or primary cwd)')\n .argument('[root]', 'primary repository root (default: cwd)')\n .action(async function (this: Command, rootArg?: string) {\n const global = readGlobal(this);\n const socketPath = socketOf(this);\n const primary = path.resolve(rootArg ?? rootOf(global));\n if (!(await vgdIsRunning({ socketPath }))) {\n throw new CliError(`vgd is not running — start it with \\`vg daemon start\\` (${socketPath})`, ExitCode.NOT_FOUND);\n }\n const { loadFederation } = await import('../runtime/federation.js');\n const fed = loadFederation(primary);\n if (!fed) throw new CliError(`could not load federation for ${primary}`, ExitCode.ERROR);\n const res = await vgdRequest(\n {\n op: 'register-federation',\n primaryRoot: fed.primaryRoot,\n members: fed.members.map((m) => ({ root: m.root, label: m.label, role: m.role })),\n },\n { socketPath },\n );\n if (!res.ok) throw new CliError(res.error, ExitCode.ERROR);\n if (global.json) json(res);\n else if ('workspaces' in res && Array.isArray(res.workspaces)) {\n info(`vgd · federation registered (${res.workspaces.length} workspace(s))`);\n for (const w of res.workspaces) {\n info(c.dim(` ${w.label ?? w.root}${w.role ? ` [${w.role}]` : ''}`));\n }\n }\n });\n applyGlobalOptions(federation);\n\n /**\n * Load the on-disk code map for a workspace into vgd's ActiveGraph cache so\n * query/impact work without an agent put-graph first (VS Code / IDE path).\n */\n const publish = cmd\n .command('publish')\n .description('load the workspace code map into vgd ActiveGraph (from global/legacy store)')\n .argument('[root]', 'repository root (default: cwd)')\n .option('--git-ref <ref>', 'branch or SHA (default: detect HEAD)')\n .action(async function (this: Command, rootArg?: string) {\n const global = readGlobal(this);\n const socketPath = socketOf(this);\n const root = path.resolve(rootArg ?? rootOf(global));\n if (!(await vgdIsRunning({ socketPath }))) {\n throw new CliError(`vgd is not running — start it with \\`vg daemon ensure\\` (${socketPath})`, ExitCode.NOT_FOUND);\n }\n const opts = this.opts() as { gitRef?: string };\n // Fast path: the daemon loads the map from disk itself (binary snapshot\n // first) — nothing heavy crosses the socket.\n const loaded = await vgdRequest(\n { op: 'load-graph', root, gitRef: opts.gitRef?.trim() || undefined, graphPath: global.graph },\n { socketPath },\n );\n let put = loaded;\n if (!loaded.ok && loaded.code === 'no_map') {\n throw new CliError(loaded.error, ExitCode.NOT_FOUND);\n }\n if (!loaded.ok) {\n // Older daemon without load-graph — legacy path: load locally and ship\n // the graph over the socket with put-graph.\n const { loadGraph } = await import('../engine/load.js');\n const { detectGitRef } = await import('../runtime/git-ref.js');\n const { repositoryIdFromRoot } = await import('../runtime/paths.js');\n const graph = loadGraph(root, global.graph);\n if (!graph) {\n throw new CliError(\n `no code map found for ${root} — run \\`vg build\\` (or bare \\`vg\\`) first`,\n ExitCode.NOT_FOUND,\n );\n }\n // Ensure workspace is registered so list shows the root.\n const reg = await vgdRequest({ op: 'register', root }, { socketPath });\n if (!reg.ok) throw new CliError(reg.error, ExitCode.ERROR);\n const git = opts.gitRef?.trim() || detectGitRef(root).ref || 'HEAD';\n const repositoryId =\n reg.ok && 'workspace' in reg ? reg.workspace.id : repositoryIdFromRoot(root);\n put = await vgdRequest(\n { op: 'put-graph', repositoryId, gitRef: git, graph },\n { socketPath },\n );\n if (!put.ok) throw new CliError(put.error, ExitCode.ERROR);\n }\n if (global.json) json(put);\n else if (put.ok && 'stored' in put) {\n info(`vgd · published graph · ${put.nodeCount} node(s) · ref ${put.gitRef}`);\n info(c.dim(` repositoryId ${put.repositoryId}`));\n }\n });\n applyGlobalOptions(publish);\n\n const query = cmd\n .command('query')\n .description('query the ActiveGraph held by vgd (lexical/structural)')\n .option('--repository-id <id>', 'repository id from `vg daemon list` (default: cwd workspace)')\n .argument('<query...>', 'what to find')\n .option('--limit <n>', 'max matches', '12')\n .option('--git-ref <ref>', 'branch or SHA (default: current slot)')\n .action(async function (this: Command, queryParts: string[]) {\n const global = readGlobal(this);\n const socketPath = socketOf(this);\n const opts = this.opts() as { repositoryId?: string; limit?: string; gitRef?: string };\n const q = (queryParts ?? []).join(' ').trim();\n if (!q) throw new CliError('say what to find', ExitCode.USAGE_ERROR);\n if (!(await vgdIsRunning({ socketPath }))) {\n throw new CliError(`vgd is not running (${socketPath})`, ExitCode.NOT_FOUND);\n }\n const repositoryId = opts.repositoryId?.trim() || (await repositoryIdForCwd(socketPath, rootOf(global)));\n const res = await vgdRequest(\n {\n op: 'query-graph',\n repositoryId,\n query: q,\n limit: opts.limit ? Number(opts.limit) : 12,\n gitRef: opts.gitRef,\n },\n { socketPath },\n );\n if (!res.ok) throw new CliError(res.error, ExitCode.ERROR);\n if (global.json) json(res);\n else if ('matches' in res) {\n info(`vgd query · ${res.matches.length} match(es) · ref ${res.gitRef}`);\n for (const m of res.matches) {\n info(`${m.qualifiedName} (${m.kind}) ${m.file}:${m.line}`);\n info(c.dim(` score ${m.score} · ${m.why}`));\n }\n }\n });\n applyGlobalOptions(query);\n\n const impact = cmd\n .command('impact')\n .description('blast radius for a symbol in the vgd ActiveGraph')\n .option('--repository-id <id>', 'repository id (default: cwd workspace)')\n .argument('<symbol>', 'symbol id or qualified name')\n .option('--depth <n>', 'max dependency depth', '4')\n .option('--git-ref <ref>', 'branch or SHA')\n .action(async function (this: Command, symbol: string) {\n const global = readGlobal(this);\n const socketPath = socketOf(this);\n const opts = this.opts() as { repositoryId?: string; depth?: string; gitRef?: string };\n if (!(await vgdIsRunning({ socketPath }))) {\n throw new CliError(`vgd is not running (${socketPath})`, ExitCode.NOT_FOUND);\n }\n const repositoryId = opts.repositoryId?.trim() || (await repositoryIdForCwd(socketPath, rootOf(global)));\n const res = await vgdRequest(\n {\n op: 'impact-of',\n repositoryId,\n symbol: symbol.trim(),\n depth: opts.depth ? Number(opts.depth) : 4,\n gitRef: opts.gitRef,\n },\n { socketPath },\n );\n if (!res.ok) throw new CliError(res.error, ExitCode.ERROR);\n if (global.json) json(res);\n else if ('affected' in res) {\n info(`vgd impact · ${res.root.name} · depth ${res.depth} · ${res.affected.length} affected`);\n for (const a of res.affected.slice(0, 30)) {\n info(`- ${a.name} (${a.file}:${a.line}) d=${a.depth}`);\n }\n }\n });\n applyGlobalOptions(impact);\n\n const graphs = cmd\n .command('graphs')\n .description('list multi-branch ActiveGraph slots resident in the running vgd (Fusion §4.1.1)')\n .option('--repository-id <id>', 'filter slots to one repository id')\n .action(async function (this: Command) {\n const global = readGlobal(this);\n const socketPath = socketOf(this);\n const opts = this.opts() as { repositoryId?: string };\n if (!(await vgdIsRunning({ socketPath }))) {\n throw new CliError(`vgd is not running (${socketPath})`, ExitCode.NOT_FOUND);\n }\n const res = await vgdRequest(\n { op: 'list-graph-slots', repositoryId: opts.repositoryId },\n { socketPath },\n );\n if (!res.ok) throw new CliError(res.error, ExitCode.ERROR);\n if (global.json) json(res);\n else if ('slots' in res) {\n if (!res.slots.length) info(c.dim('vgd · no graph slots resident'));\n for (const s of res.slots) {\n const cur = s.current ? c.green(' current') : '';\n const idle = s.evictable ? c.yellow(' idle') : '';\n info(`${s.repositoryId.slice(0, 8)}… ${s.gitRef}${cur}${idle}`);\n info(c.dim(` nodes ${s.nodeCount} · idle ${Math.round(s.idleMs / 1000)}s · loaded ${new Date(s.loadedAt).toISOString()}`));\n }\n }\n });\n applyGlobalOptions(graphs);\n\n applyGlobalOptions(cmd);\n}\n\nfunction socketOf(cmd: Command): string {\n // Walk parents for --socket on the daemon parent or the leaf.\n let c: Command | null = cmd;\n while (c) {\n const opts = c.opts() as { socket?: string };\n if (opts.socket) return path.resolve(opts.socket);\n c = c.parent;\n }\n return vgdSocketPath();\n}\n\n/**\n * Re-invoke this CLI as a detached background `daemon start`.\n * Handles `node dist/cli.js …`, a global `vg` symlink (npm bin), and a\n * packaged `vg` binary. The symlink case must realpath to cli.js — see\n * {@link reinvokeCli}.\n */\nfunction spawnDetachedDaemonStart(socketPath: string): ReturnType<typeof spawn> {\n // On Windows, `detached` (DETACHED_PROCESS) is the wrong tool for a daemon\n // with descendants: it leaves the process with NO console, so every\n // console-subsystem child it later spawns (embed worker, rebuild `vg build`,\n // git) allocates a brand-new VISIBLE console window on the desktop — and a\n // user closing that stray window kills the child with STATUS_CONTROL_C_EXIT.\n // windowsHide (CREATE_NO_WINDOW, ignored when combined with detached) gives\n // the daemon a windowless console its whole subtree inherits instead.\n // Lifetime is unaffected: Windows never kills children on parent exit, and\n // the separate console keeps the terminal's Ctrl-C/close away from it. On\n // POSIX, detached (its own process group) is still what lets the daemon\n // outlive the terminal.\n const opts = {\n detached: process.platform !== 'win32',\n stdio: 'ignore' as const,\n env: process.env,\n windowsHide: true,\n };\n const { command, argv } = reinvokeCli(['daemon', 'start', '--socket', socketPath]);\n return spawn(command, argv, opts);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n\n/**\n * Start vgd in the background without making the caller wait for it.\n *\n * `ensureVgd` waits up to 30s and throws — right for `vg daemon ensure` and for\n * `vg code`, which cannot proceed without a runtime, and wrong for every\n * ordinary command. An auto-start must never put a cold-start on the front of\n * `vg ask`: we spawn, give the socket a short window in case it binds quickly,\n * and otherwise leave the child coming up on its own. The command runs its\n * in-process path this time and finds a warm daemon the next.\n *\n * Never throws — the caller has a working fallback by construction.\n */\nexport async function ensureVgdSoft(\n socketPath: string = vgdSocketPath(),\n readyBudgetMs = 1500,\n): Promise<{ running: boolean; started: boolean }> {\n try {\n if (await vgdIsRunning({ socketPath })) return { running: true, started: false };\n const child = spawnDetachedDaemonStart(socketPath);\n child.unref();\n const deadline = Date.now() + Math.max(0, readyBudgetMs);\n while (Date.now() < deadline) {\n await sleep(100);\n if (await vgdIsRunning({ socketPath })) return { running: true, started: true };\n if (child.exitCode != null && child.exitCode !== 0) break;\n }\n return { running: false, started: true };\n } catch {\n return { running: false, started: false };\n }\n}\n\n/** Injectable internals of {@link startDetachedVgd} (tests). */\nexport interface StartVgdDeps {\n startOnce: (socketPath: string) => Promise<number | undefined>;\n skew: (socketPath: string) => Promise<VgdSkew>;\n stop: (socketPath: string, opts?: StopVgdOptions) => ReturnType<typeof stopVgd>;\n}\n\n/**\n * How many times a start will retire an older daemon that re-binds the socket\n * before conceding. Each round both stops the interloper and gives our own\n * child another chance to win the bind; a client that keeps spawning an old\n * build faster than we can retire it is a fight to report, not to keep having.\n */\nconst START_BIND_ATTEMPTS = 3;\n\n/**\n * Start vgd in the background and hand back a daemon that is genuinely on this\n * build (or newer). Throws when it cannot.\n *\n * A socket that answers ping is NOT proof the start worked: while the socket\n * is free (mid-update, mid-restart) any other client's `daemon ensure` — a VS\n * Code extension bundling an older engine, a long-lived `vg serve` on an old\n * build — can bind ITS daemon first, and our child then exits \"already\n * running\". Reporting success against that daemon is exactly the \"updated,\n * but the daemon is still stale\" state `vg update` exists to end, so after\n * every ready signal the build on the socket is verified and an older\n * squatter is force-stopped and replaced, a bounded number of times. A newer\n * daemon is left alone (newest wins — see {@link compareDaemonVersion}).\n */\nexport async function startDetachedVgd(\n socketPath: string,\n deps: Partial<StartVgdDeps> = {},\n): Promise<number | undefined> {\n const startOnce = deps.startOnce ?? startDetachedVgdOnce;\n const skewOf = deps.skew ?? vgdVersionSkew;\n const stop = deps.stop ?? stopVgd;\n let pid: number | undefined;\n for (let attempt = 1; attempt <= START_BIND_ATTEMPTS; attempt++) {\n pid = await startOnce(socketPath);\n const skew = await skewOf(socketPath);\n if (skew.running && skew.state !== 'older') return pid;\n if (!skew.running) continue; // gone between ready and the check — spawn again\n await stop(socketPath, { force: true });\n }\n throw new CliError(\n `an older vgd keeps re-binding ${socketPath} — another running client is starting it ` +\n '(commonly a VS Code extension bundling an older engine, or a long-lived `vg serve`). ' +\n 'Update or restart that client, then run \"vg daemon restart --force\".',\n ExitCode.ERROR,\n );\n}\n\n/**\n * Spawn a detached background `daemon start` and wait for the socket to answer\n * ping. Returns the child pid; throws when the socket never becomes ready.\n * The listener is not necessarily our child — {@link startDetachedVgd} owns\n * that verification.\n *\n * Ready budget is long because the detached child pays a full Node + CLI cold\n * start of its own (often >8s under Windows AV). The previous 8s window made\n * `vg daemon ensure` report success only when ping raced ahead of the child\n * exiting, or fail right as the child was about to listen.\n */\nasync function startDetachedVgdOnce(socketPath: string): Promise<number | undefined> {\n const child = spawnDetachedDaemonStart(socketPath);\n child.unref();\n const readyMs = 30_000;\n const deadline = Date.now() + readyMs;\n while (Date.now() < deadline) {\n await sleep(150);\n if (await vgdIsRunning({ socketPath })) return child.pid;\n // If the child already exited without ever answering, fail fast rather\n // than waiting out the full budget for a dead process. Another client\n // (the VS Code extension's `daemon ensure`) may have bound in this\n // tick — treat that as ready rather than reporting a false failure.\n if (child.exitCode != null && child.exitCode !== 0) {\n if (await vgdIsRunning({ socketPath })) return child.pid;\n throw new CliError(\n `vgd child exited ${child.exitCode} before becoming ready at ${socketPath} — run \"vg daemon start\" in the foreground to see the error`,\n ExitCode.ERROR,\n );\n }\n }\n throw new CliError(\n `vgd failed to become ready within ${Math.round(readyMs / 1000)}s at ${socketPath}`,\n ExitCode.ERROR,\n );\n}\n\n/**\n * The build version of the daemon currently on the socket, or `null` when it\n * does not report one.\n *\n * `null` is not \"unknown, leave it alone\": `cliVersion` landed in the status\n * response in 2026.817.x, so its absence dates the process to a build older\n * than that just as surely as a version string would.\n */\nexport async function vgdCliVersion(socketPath: string = vgdSocketPath()): Promise<string | null> {\n try {\n const res = await vgdRequest({ op: 'status' }, { socketPath });\n if (!res.ok || !('cliVersion' in res)) return null;\n return typeof res.cliVersion === 'string' && res.cliVersion ? res.cliVersion : null;\n } catch {\n return null;\n }\n}\n\nexport type VgdSkew =\n | { running: false }\n | { running: true; version: string | null; state: 'match' | 'older' | 'newer' };\n\n/**\n * Compare the daemon holding the socket against this build.\n *\n * vgd owns one machine-wide socket, so whichever process binds it first serves\n * every client — the CLI, `vg serve`, and a VS Code extension running its own\n * bundled engine. Version skew is therefore the normal case, not an edge case,\n * and it is invisible: an old daemon answers every request happily, just with\n * old code.\n */\nexport async function vgdVersionSkew(socketPath: string = vgdSocketPath(), self: string = VERSION): Promise<VgdSkew> {\n if (!(await vgdIsRunning({ socketPath }))) return { running: false };\n const version = await vgdCliVersion(socketPath);\n return { running: true, version, state: compareDaemonVersion(version, self) };\n}\n\n/**\n * Resolution is deliberately monotonic — only a strictly newer daemon survives\n * a mismatch. Two clients on different builds both ensuring the socket would\n * otherwise restart each other forever; with \"newest wins\" they converge on the\n * highest version present and stay there.\n */\nexport function compareDaemonVersion(version: string | null, self: string): 'match' | 'older' | 'newer' {\n if (version === self) return 'match';\n // We cannot judge from an unparseable version of our own — never pick a fight\n // we have no way to win.\n if (!semver.valid(self)) return 'match';\n if (version === null || !semver.valid(version)) return 'older';\n return semver.gt(version, self) ? 'newer' : 'older';\n}\n\n/** Human label for a daemon build, including the pre-2026.817 \"no version\" case. */\nfunction describeVersion(version: string | null): string {\n return version ?? 'unknown (pre-2026.817)';\n}\n\nexport interface EnsureVgdResult {\n started: boolean;\n pid?: number;\n /** Set when an older daemon was retired to make room for this build. */\n replaced?: { version: string | null };\n}\n\nexport interface EnsureVgdOptions {\n /** Attach to whatever is on the socket, even on an older build. */\n allowVersionMismatch?: boolean;\n}\n\n/**\n * Idempotent start used by `vg daemon ensure` and `vg code`: if vgd is already\n * listening on this build, do nothing; otherwise spawn a detached standalone\n * `daemon start`.\n *\n * An older daemon is replaced rather than attached to. Attaching is the quiet\n * failure this exists to prevent: the client reports success, then serves stale\n * answers from a process nobody remembers starting.\n */\nexport async function ensureVgd(\n socketPath: string = vgdSocketPath(),\n opts: EnsureVgdOptions = {},\n): Promise<EnsureVgdResult> {\n const skew = await vgdVersionSkew(socketPath);\n if (!skew.running) return { started: true, pid: await startDetachedVgd(socketPath) };\n if (opts.allowVersionMismatch || skew.state !== 'older') return { started: false };\n await stopVgd(socketPath, { force: true });\n return { started: true, pid: await startDetachedVgd(socketPath), replaced: { version: skew.version } };\n}\n\n/** Injectable internals of {@link retireWedgedVgd} (tests). */\nexport interface RetireWedgedDeps {\n isRunning: (socketPath: string) => Promise<boolean>;\n readPid: () => number | null;\n signal: (pid: number, signal: NodeJS.Signals) => boolean;\n held: (socketPath: string) => Promise<boolean>;\n /** How long to wait for the address to free after each signal. */\n waitBudgetMs: number;\n selfPid: number;\n}\n\nexport type RetireWedgedResult =\n | { ok: true; pid: number }\n | { ok: false; live: true }\n | { ok: false; live?: false; reason: string };\n\n/**\n * Free a vgd socket held by a process that no longer answers vgd requests.\n *\n * The wedge this exists for: a daemon (often from an older extension install)\n * keeps the pipe/socket bound but its event loop is stuck, so `ping` times out\n * everywhere — `vg daemon status` says \"not running\", `stopVgd` returns\n * `not-running` without touching it, `ensureVgd` goes straight to a start that\n * dies on EADDRINUSE, and every client retries that forever. This retires the\n * holder identified by vgd's own pid file (only a successful `startVgdServer`\n * bind ever writes it, so it names the current holder), escalating SIGTERM →\n * SIGKILL, and confirms the address actually freed.\n *\n * Refuses to act when a live daemon answers ping (an ordinary lost start race,\n * not a wedge) or when the pid file is missing or points at this process.\n */\nexport async function retireWedgedVgd(\n socketPath: string,\n deps: Partial<RetireWedgedDeps> = {},\n): Promise<RetireWedgedResult> {\n const isRunning = deps.isRunning ?? ((s: string) => vgdIsRunning({ socketPath: s }));\n const readPid = deps.readPid ?? readVgdPid;\n const signal = deps.signal ?? signalPid;\n const held = deps.held ?? vgdSocketHeld;\n const waitBudgetMs = deps.waitBudgetMs ?? 3_000;\n const selfPid = deps.selfPid ?? process.pid;\n\n if (await isRunning(socketPath)) return { ok: false, live: true };\n const pid = readPid();\n if (pid == null) return { ok: false, reason: 'no pid file identifies the holder' };\n if (pid === selfPid) return { ok: false, reason: 'the pid file points at this process' };\n if (!signal(pid, 'SIGTERM')) return { ok: false, reason: `pid ${pid} from the pid file is not signalable` };\n if (await waitForSocketFree(socketPath, waitBudgetMs, held)) return { ok: true, pid };\n signal(pid, 'SIGKILL');\n if (await waitForSocketFree(socketPath, waitBudgetMs, held)) return { ok: true, pid };\n return { ok: false, reason: `pid ${pid} was signalled but ${socketPath} is still held` };\n}\n\nasync function waitForSocketFree(\n socketPath: string,\n budgetMs: number,\n held: (socketPath: string) => Promise<boolean>,\n): Promise<boolean> {\n const deadline = Date.now() + budgetMs;\n for (;;) {\n if (!(await held(socketPath))) return true;\n if (Date.now() >= deadline) return false;\n await sleep(100);\n }\n}\n\n/**\n * True when something still accepts connections on the address. Distinct from\n * {@link vgdIsRunning}: a wedged daemon accepts the connection but never\n * answers ping. A connect left hanging counts as held — limbo is never \"free\".\n */\nfunction vgdSocketHeld(socketPath: string, timeoutMs = 1_000): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = net.createConnection(socketPath);\n let settled = false;\n const done = (heldNow: boolean): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n socket.destroy();\n resolve(heldNow);\n };\n const timer = setTimeout(() => done(true), timeoutMs);\n socket.once('connect', () => done(true));\n socket.once('error', () => done(false));\n });\n}\n\nexport interface StopVgdOptions {\n /**\n * Escalate past a daemon that will not leave politely: SIGTERM, then SIGKILL.\n *\n * Used wherever a surviving daemon is worse than a killed one — `vg update`\n * above all, where every client on the socket would otherwise keep being\n * served by the build that was just replaced. Safe to escalate because\n * `daemon start` is the only thing that ever hosts a vgd listener, so the pid\n * belongs to a daemon process and not to somebody's editor.\n */\n force?: boolean;\n}\n\n/**\n * Stop a running vgd: polite `shutdown` op first, SIGTERM via the pid for\n * daemons that predate the op, then wait (≤5s) for the socket to go quiet.\n *\n * `refused` means the daemon declined remote shutdown (a listener started\n * without a shutdown hook). Without `force` that is where it ends — the pid\n * file belongs to the owning process and is not ours to kill.\n */\nexport async function stopVgd(\n socketPath: string,\n opts: StopVgdOptions = {},\n): Promise<'stopped' | 'not-running' | 'refused' | 'failed'> {\n if (!(await vgdIsRunning({ socketPath }))) return 'not-running';\n // Ask who is on the socket before shutting it down. The pid the daemon\n // reports is authoritative; the pid file can be left over from an earlier\n // process, and signalling that would kill a stranger.\n const livePid = opts.force ? await vgdReportedPid(socketPath) : null;\n let acknowledged = false;\n try {\n const res = await vgdRequest({ op: 'shutdown' }, { socketPath });\n if (res.ok) acknowledged = true;\n else if (res.code === 'shutdown_unsupported' && !opts.force) return 'refused';\n // Any other refusal (an older daemon answers `unknown op`) → pid fallback.\n } catch {\n /* connection dropped mid-shutdown or slow daemon — fall through to pid */\n }\n if (!acknowledged) {\n const pid = signalTarget(livePid);\n if (pid == null) return 'failed';\n if (!signalPid(pid, 'SIGTERM')) return 'failed';\n }\n if (await waitForVgdStop(socketPath, 5_000)) return 'stopped';\n if (!opts.force) return 'failed';\n\n // Wedged: it acknowledged, or took SIGTERM, and is still holding the socket.\n const pid = signalTarget(livePid);\n if (pid == null) return 'failed';\n if (!signalPid(pid, 'SIGKILL')) return 'failed';\n // A SIGKILLed daemon cannot unlink its own socket, but the next `daemon\n // start` clears a stale path before binding, so nothing is left to clean up.\n return (await waitForVgdStop(socketPath, 3_000)) ? 'stopped' : 'failed';\n}\n\n/**\n * The pid to signal, or null when there is nothing safe to signal.\n *\n * Never our own: a daemon hosted in *this* process (an in-process test server,\n * a future embedded listener) would otherwise be \"stopped\" by killing the\n * caller. Such a daemon has to be shut down through its own handle, so report\n * failure and let the caller say so.\n */\nfunction signalTarget(livePid: number | null): number | null {\n const pid = livePid ?? readVgdPid();\n if (pid == null || pid === process.pid) return null;\n return pid;\n}\n\nfunction signalPid(pid: number, signal: NodeJS.Signals): boolean {\n try {\n process.kill(pid, signal);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function waitForVgdStop(socketPath: string, budgetMs: number): Promise<boolean> {\n const deadline = Date.now() + budgetMs;\n while (Date.now() < deadline) {\n await sleep(100);\n if (!(await vgdIsRunning({ socketPath }))) return true;\n }\n return false;\n}\n\n/** The pid the live daemon reports for itself — trusted over the pid file. */\nasync function vgdReportedPid(socketPath: string): Promise<number | null> {\n try {\n const res = await vgdRequest({ op: 'status' }, { socketPath });\n if (!res.ok || !('pid' in res)) return null;\n return Number.isInteger(res.pid) && res.pid > 0 ? res.pid : null;\n } catch {\n return null;\n }\n}\n\nexport interface RestartVgdOptions extends StopVgdOptions {\n /**\n * Start a daemon even when none is running. `vg update` on Windows stops\n * vgd *before* the install so its files can be replaced; afterwards there is\n * nothing to \"re\"-start, but leaving the socket empty both makes the rewarm\n * a no-op and leaves a window for another client to bind an old build.\n */\n startIfNotRunning?: boolean;\n}\n\n/**\n * Restart the local vgd if one is running — used by `vg update` so a freshly\n * installed CLI does not keep serving from a daemon still running the old\n * build. `restarted`/`started` mean a daemon on this build (or newer) was\n * verified on the socket, not merely that something answered ping.\n * Best-effort: never throws.\n */\nexport async function restartVgdIfRunning(\n socketPath: string = vgdSocketPath(),\n opts: RestartVgdOptions = {},\n): Promise<'restarted' | 'started' | 'not-running' | 'refused' | 'failed'> {\n try {\n const stopResult = await stopVgd(socketPath, opts);\n if (stopResult === 'not-running' && !opts.startIfNotRunning) return 'not-running';\n if (stopResult === 'refused') return 'refused';\n if (stopResult === 'failed') return 'failed';\n await startDetachedVgd(socketPath);\n return stopResult === 'not-running' ? 'started' : 'restarted';\n } catch {\n return 'failed';\n }\n}\n\nfunction readVgdPid(): number | null {\n try {\n const raw = fs.readFileSync(vgdPidPath(), 'utf8').trim();\n const pid = Number.parseInt(raw, 10);\n return Number.isInteger(pid) && pid > 0 ? pid : null;\n } catch {\n return null;\n }\n}\n\n/** Resolve repository id for cwd: register if needed, return workspace id. */\nasync function repositoryIdForCwd(socketPath: string, root: string): Promise<string> {\n const { repositoryIdFromRoot } = await import('../runtime/paths.js');\n const reg = await vgdRequest({ op: 'register', root }, { socketPath });\n if (reg.ok && 'workspace' in reg) return reg.workspace.id;\n return repositoryIdFromRoot(root);\n}\n"]}