@vibgrate/cli 2026.807.1 → 2026.814.1

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 (127) hide show
  1. package/NOTICE +7 -0
  2. package/dist/agent-2ZISYEQF.js +26 -0
  3. package/dist/{agent-K3J6EHLI.js.map → agent-2ZISYEQF.js.map} +1 -1
  4. package/dist/approvals-DOZ5RWJP.js +9 -0
  5. package/dist/approvals-DOZ5RWJP.js.map +1 -0
  6. package/dist/baseline-AGX42TZM.js +9 -0
  7. package/dist/{baseline-IAFWF2ET.js.map → baseline-AGX42TZM.js.map} +1 -1
  8. package/dist/{checkpoint-4WFZMKEO.js → checkpoint-UYMYMMQO.js} +6 -3
  9. package/dist/checkpoint-UYMYMMQO.js.map +1 -0
  10. package/dist/{chunk-N5EP5ZR2.js → chunk-2HNPL4OB.js} +5 -5
  11. package/dist/{chunk-N5EP5ZR2.js.map → chunk-2HNPL4OB.js.map} +1 -1
  12. package/dist/{chunk-2HAJCW7Z.js → chunk-2W3GBKSV.js} +5 -5
  13. package/dist/{chunk-2HAJCW7Z.js.map → chunk-2W3GBKSV.js.map} +1 -1
  14. package/dist/{chunk-XSHGXGVJ.js → chunk-5KY5UCDJ.js} +4 -4
  15. package/dist/{chunk-XSHGXGVJ.js.map → chunk-5KY5UCDJ.js.map} +1 -1
  16. package/dist/{chunk-NWX4VUFS.js → chunk-6OP5U55G.js} +8 -8
  17. package/dist/{chunk-NWX4VUFS.js.map → chunk-6OP5U55G.js.map} +1 -1
  18. package/dist/{chunk-KEIMMCS5.js → chunk-7CDW25VY.js} +4 -4
  19. package/dist/{chunk-KEIMMCS5.js.map → chunk-7CDW25VY.js.map} +1 -1
  20. package/dist/chunk-A4F7ESUR.js +174 -0
  21. package/dist/chunk-A4F7ESUR.js.map +1 -0
  22. package/dist/chunk-AJS4EL2C.js +266 -0
  23. package/dist/chunk-AJS4EL2C.js.map +1 -0
  24. package/dist/{chunk-5ESL76CM.js → chunk-BTYFZ3NM.js} +9 -8
  25. package/dist/chunk-BTYFZ3NM.js.map +1 -0
  26. package/dist/{chunk-JFCCJWXD.js → chunk-BXPWVTGS.js} +4 -3
  27. package/dist/chunk-BXPWVTGS.js.map +1 -0
  28. package/dist/{chunk-7CYFCSY2.js → chunk-EBUTRJHX.js} +24 -6
  29. package/dist/chunk-EBUTRJHX.js.map +1 -0
  30. package/dist/{chunk-EXOYSXH6.js → chunk-HYC3A2AT.js} +3 -3
  31. package/dist/{chunk-EXOYSXH6.js.map → chunk-HYC3A2AT.js.map} +1 -1
  32. package/dist/{chunk-G4KO5W6H.js → chunk-J3IDTLF4.js} +19 -9
  33. package/dist/chunk-J3IDTLF4.js.map +1 -0
  34. package/dist/chunk-JYY6G46J.js +64 -0
  35. package/dist/chunk-JYY6G46J.js.map +1 -0
  36. package/dist/{chunk-2M6B5V2U.js → chunk-K7MONYIM.js} +30 -66
  37. package/dist/chunk-K7MONYIM.js.map +1 -0
  38. package/dist/{chunk-ADP6ITGF.js → chunk-N3XFY3PX.js} +68 -11
  39. package/dist/chunk-N3XFY3PX.js.map +1 -0
  40. package/dist/{chunk-INIULQEP.js → chunk-N6ZMZ5AI.js} +11 -2
  41. package/dist/chunk-N6ZMZ5AI.js.map +1 -0
  42. package/dist/{chunk-QXIWQ2WG.js → chunk-NXDYWBZB.js} +4 -4
  43. package/dist/{chunk-QXIWQ2WG.js.map → chunk-NXDYWBZB.js.map} +1 -1
  44. package/dist/{chunk-GQ2EQXBG.js → chunk-QFCJY6FQ.js} +6 -5
  45. package/dist/chunk-QFCJY6FQ.js.map +1 -0
  46. package/dist/chunk-QIUQH2ND.js +6 -0
  47. package/dist/{chunk-ITY2NPIQ.js.map → chunk-QIUQH2ND.js.map} +1 -1
  48. package/dist/{chunk-FOKURZL3.js → chunk-RBBP4SP7.js} +12 -10
  49. package/dist/chunk-RBBP4SP7.js.map +1 -0
  50. package/dist/{chunk-VNAOFA6X.js → chunk-RNZP2XAL.js} +8 -8
  51. package/dist/chunk-RNZP2XAL.js.map +1 -0
  52. package/dist/{chunk-Y4JO6LYP.js → chunk-TFAXW7VM.js} +302 -11
  53. package/dist/chunk-TFAXW7VM.js.map +1 -0
  54. package/dist/{chunk-LS7GZBKP.js → chunk-UJAOCFQQ.js} +19 -9
  55. package/dist/chunk-UJAOCFQQ.js.map +1 -0
  56. package/dist/{chunk-PT2XQTSK.js → chunk-VD6TVFGA.js} +7 -6
  57. package/dist/chunk-VD6TVFGA.js.map +1 -0
  58. package/dist/{chunk-VQVLY63G.js → chunk-WN2AAB5O.js} +212 -59
  59. package/dist/chunk-WN2AAB5O.js.map +1 -0
  60. package/dist/{chunk-EJUMV5HU.js → chunk-XEI7UU6G.js} +3 -3
  61. package/dist/{chunk-EJUMV5HU.js.map → chunk-XEI7UU6G.js.map} +1 -1
  62. package/dist/cli.js +1179 -511
  63. package/dist/cli.js.map +1 -1
  64. package/dist/embed-worker-main.js +4 -3
  65. package/dist/embed-worker-main.js.map +1 -1
  66. package/dist/{ensure-map-TYMYYIJE.js → ensure-map-EURJPSAK.js} +15 -14
  67. package/dist/{ensure-map-TYMYYIJE.js.map → ensure-map-EURJPSAK.js.map} +1 -1
  68. package/dist/fastembed-S6YEJYQV.js +292 -0
  69. package/dist/fastembed-S6YEJYQV.js.map +1 -0
  70. package/dist/graph-backend-VUW2QWPI.js +14 -0
  71. package/dist/{graph-backend-5YOWNHHG.js.map → graph-backend-VUW2QWPI.js.map} +1 -1
  72. package/dist/index.d.ts +4 -3
  73. package/dist/index.js +14 -13
  74. package/dist/index.js.map +1 -1
  75. package/dist/{interactive-YEMXHGBO.js → interactive-WRA477OW.js} +32 -30
  76. package/dist/interactive-WRA477OW.js.map +1 -0
  77. package/dist/load-XZV5LEGA.js +10 -0
  78. package/dist/{load-IIWVYUN7.js.map → load-XZV5LEGA.js.map} +1 -1
  79. package/dist/{run-outcome-2JO55QCC.js → run-outcome-X5KS6AUE.js} +6 -5
  80. package/dist/run-outcome-X5KS6AUE.js.map +1 -0
  81. package/dist/runtime-session-J7GDVRFU.js +21 -0
  82. package/dist/{runtime-session-HFKGKQV7.js.map → runtime-session-J7GDVRFU.js.map} +1 -1
  83. package/dist/session-3R34WA5S.js +16 -0
  84. package/dist/{session-5LFX4U2E.js.map → session-3R34WA5S.js.map} +1 -1
  85. package/dist/session-store-AQUORKWB.js +4 -0
  86. package/dist/{session-store-KGONLWHN.js.map → session-store-AQUORKWB.js.map} +1 -1
  87. package/dist/{stream-json-DUCFTBUF.js → stream-json-LKVPDKXP.js} +76 -24
  88. package/dist/stream-json-LKVPDKXP.js.map +1 -0
  89. package/dist/version-55TOTJTF.js +4 -0
  90. package/dist/version-55TOTJTF.js.map +1 -0
  91. package/dist/{vg-mcp-bridge-4KPDQUFN.js → vg-mcp-bridge-ZPJAHP7T.js} +11 -10
  92. package/dist/vg-mcp-bridge-ZPJAHP7T.js.map +1 -0
  93. package/dist/{vgd-LFHQ4GWC.js → vgd-UIFH5TTW.js} +12 -11
  94. package/dist/vgd-UIFH5TTW.js.map +1 -0
  95. package/dist/worktree-session-D575IQWM.js +82 -0
  96. package/dist/worktree-session-D575IQWM.js.map +1 -0
  97. package/package.json +9 -7
  98. package/dist/agent-K3J6EHLI.js +0 -24
  99. package/dist/baseline-IAFWF2ET.js +0 -9
  100. package/dist/checkpoint-4WFZMKEO.js.map +0 -1
  101. package/dist/chunk-2M6B5V2U.js.map +0 -1
  102. package/dist/chunk-5ESL76CM.js.map +0 -1
  103. package/dist/chunk-7CYFCSY2.js.map +0 -1
  104. package/dist/chunk-ADP6ITGF.js.map +0 -1
  105. package/dist/chunk-FOKURZL3.js.map +0 -1
  106. package/dist/chunk-G4KO5W6H.js.map +0 -1
  107. package/dist/chunk-GQ2EQXBG.js.map +0 -1
  108. package/dist/chunk-INIULQEP.js.map +0 -1
  109. package/dist/chunk-ITY2NPIQ.js +0 -6
  110. package/dist/chunk-JFCCJWXD.js.map +0 -1
  111. package/dist/chunk-LS7GZBKP.js.map +0 -1
  112. package/dist/chunk-PT2XQTSK.js.map +0 -1
  113. package/dist/chunk-VNAOFA6X.js.map +0 -1
  114. package/dist/chunk-VQVLY63G.js.map +0 -1
  115. package/dist/chunk-Y4JO6LYP.js.map +0 -1
  116. package/dist/chunk-Z7FM3ETS.js +0 -126
  117. package/dist/chunk-Z7FM3ETS.js.map +0 -1
  118. package/dist/graph-backend-5YOWNHHG.js +0 -13
  119. package/dist/interactive-YEMXHGBO.js.map +0 -1
  120. package/dist/load-IIWVYUN7.js +0 -9
  121. package/dist/run-outcome-2JO55QCC.js.map +0 -1
  122. package/dist/runtime-session-HFKGKQV7.js +0 -20
  123. package/dist/session-5LFX4U2E.js +0 -15
  124. package/dist/session-store-KGONLWHN.js +0 -4
  125. package/dist/stream-json-DUCFTBUF.js.map +0 -1
  126. package/dist/vg-mcp-bridge-4KPDQUFN.js.map +0 -1
  127. package/dist/vgd-LFHQ4GWC.js.map +0 -1
@@ -1,27 +1,31 @@
1
- import { runAgent } from './chunk-VQVLY63G.js';
1
+ import { sanitizeAttachments } from './chunk-AJS4EL2C.js';
2
+ import { runAgent } from './chunk-WN2AAB5O.js';
2
3
  import './chunk-543E6WDJ.js';
3
- import './chunk-ADP6ITGF.js';
4
- import './chunk-REIGWTTH.js';
5
- import './chunk-EXOYSXH6.js';
4
+ import './chunk-A4F7ESUR.js';
5
+ import './chunk-HYC3A2AT.js';
6
6
  import './chunk-RBIRXQR6.js';
7
7
  import './chunk-5HYCB55P.js';
8
- import './chunk-FOKURZL3.js';
8
+ import './chunk-N3XFY3PX.js';
9
+ import './chunk-REIGWTTH.js';
9
10
  import './chunk-VIWZ4QT7.js';
10
- import './chunk-QXIWQ2WG.js';
11
- import './chunk-3LSG7Z4I.js';
11
+ import './chunk-NXDYWBZB.js';
12
12
  import './chunk-J7LKEB2R.js';
13
- import './chunk-7CYFCSY2.js';
13
+ import './chunk-RBBP4SP7.js';
14
+ import './chunk-EBUTRJHX.js';
15
+ import './chunk-3LSG7Z4I.js';
14
16
  import './chunk-UTNNGKKX.js';
15
17
  import './chunk-RXP66R2E.js';
16
- import './chunk-LS7GZBKP.js';
17
- import './chunk-2M6B5V2U.js';
18
- import './chunk-ITY2NPIQ.js';
18
+ import './chunk-UJAOCFQQ.js';
19
+ import './chunk-JYY6G46J.js';
20
+ import './chunk-K7MONYIM.js';
21
+ import './chunk-QIUQH2ND.js';
19
22
  import './chunk-BWPBB45M.js';
20
23
  import './chunk-JFGYT6BI.js';
21
24
  import './chunk-BPF3YX2U.js';
22
25
  import './chunk-Z6ZWNWWR.js';
23
26
 
24
27
  // src/code/stream-json.ts
28
+ var STREAM_JSON_PROTOCOL_VERSION = 5;
25
29
  function parseHostMessage(raw) {
26
30
  let msg;
27
31
  try {
@@ -31,7 +35,12 @@ function parseHostMessage(raw) {
31
35
  }
32
36
  if (!msg || typeof msg !== "object") return null;
33
37
  if (typeof msg.approveId === "number") {
34
- return { kind: "approve", id: msg.approveId, approve: !!msg.approve };
38
+ return {
39
+ kind: "approve",
40
+ id: msg.approveId,
41
+ approve: !!msg.approve,
42
+ ...msg.always === true && msg.approve ? { always: true } : {}
43
+ };
35
44
  }
36
45
  if (typeof msg.answerId === "number") {
37
46
  return { kind: "answer", id: msg.answerId, answer: String(msg.answer ?? "") };
@@ -41,11 +50,15 @@ function parseHostMessage(raw) {
41
50
  const images = Array.isArray(msg.images) ? msg.images.filter(
42
51
  (a) => !!a && typeof a === "object" && typeof a.name === "string" && typeof a.mediaType === "string" && typeof a.dataBase64 === "string"
43
52
  ).slice(0, 8) : void 0;
53
+ const reasoningEffort = msg.reasoningEffort === "low" || msg.reasoningEffort === "medium" || msg.reasoningEffort === "high" ? msg.reasoningEffort : void 0;
54
+ const attachments = sanitizeAttachments(msg.attachments);
44
55
  return {
45
56
  kind: "submit",
46
57
  instruction: msg.submit.trim(),
47
58
  ...agentMode ? { agentMode } : {},
48
- ...images?.length ? { images } : {}
59
+ ...images?.length ? { images } : {},
60
+ ...reasoningEffort ? { reasoningEffort } : {},
61
+ ...attachments.length ? { attachments } : {}
49
62
  };
50
63
  }
51
64
  if (msg.restore && typeof msg.restore === "object" && typeof msg.restore.commit === "string") {
@@ -55,6 +68,12 @@ function parseHostMessage(raw) {
55
68
  return null;
56
69
  }
57
70
  if (msg.compactSession === true) return { kind: "compact" };
71
+ if (typeof msg.inject === "string" && msg.inject.trim()) {
72
+ return { kind: "inject", text: msg.inject.trim() };
73
+ }
74
+ if (typeof msg.renameSession === "string") {
75
+ return { kind: "rename", title: msg.renameSession.trim() };
76
+ }
58
77
  if (msg.cancel === true) return { kind: "cancel" };
59
78
  if (msg.end === true) return { kind: "end" };
60
79
  return null;
@@ -71,6 +90,18 @@ var StreamJsonSession = class {
71
90
  pendingAnswer = /* @__PURE__ */ new Map();
72
91
  /** Cancellation for the turn currently running (session mode). */
73
92
  turnSignal = { aborted: false };
93
+ /**
94
+ * v4 steer: user content injected mid-turn, drained by the agent loop at its
95
+ * next step boundary. Deliberately NOT cleared between turns — an inject that
96
+ * races the turn's end should land at the start of the next turn, not vanish.
97
+ */
98
+ injected = [];
99
+ /**
100
+ * v3: called when the host approved with `always: true` — the owner persists
101
+ * a standing rule derived from the approved action. Injected (not imported)
102
+ * so this protocol class stays free of filesystem concerns.
103
+ */
104
+ onAlwaysRule;
74
105
  /**
75
106
  * Per-turn approval posture (session mode): a host `submit` can flip auto on
76
107
  * or off for the coming turn without respawning the process.
@@ -90,7 +121,7 @@ var StreamJsonSession = class {
90
121
  return Promise.resolve(true);
91
122
  }
92
123
  return new Promise((resolve) => {
93
- this.pendingApprove.set(id, resolve);
124
+ this.pendingApprove.set(id, { resolve, action });
94
125
  this.emit({ event: "approve-request", id, action });
95
126
  });
96
127
  };
@@ -111,11 +142,12 @@ var StreamJsonSession = class {
111
142
  });
112
143
  };
113
144
  /** Host → agent: resolve a pending approval. Unknown ids are ignored. */
114
- submitDecision(id, approve) {
115
- const resolve = this.pendingApprove.get(id);
116
- if (resolve) {
145
+ submitDecision(id, approve, always = false) {
146
+ const pending = this.pendingApprove.get(id);
147
+ if (pending) {
117
148
  this.pendingApprove.delete(id);
118
- resolve(approve);
149
+ if (approve && always) this.onAlwaysRule?.(pending.action);
150
+ pending.resolve(approve);
119
151
  }
120
152
  }
121
153
  /** Host → agent: resolve a pending user-question. Unknown ids are ignored. */
@@ -126,6 +158,21 @@ var StreamJsonSession = class {
126
158
  resolve(answer ?? "");
127
159
  }
128
160
  }
161
+ /** Host → agent (v4): steer the running turn with more user content. */
162
+ inject(text) {
163
+ const t = text.trim();
164
+ if (t) this.injected.push(t);
165
+ }
166
+ /**
167
+ * Drain pending steer content (joined, oldest first) for the agent loop's
168
+ * next step. Null when nothing is pending.
169
+ */
170
+ drainInjected() {
171
+ if (!this.injected.length) return null;
172
+ const text = this.injected.join("\n\n");
173
+ this.injected = [];
174
+ return text;
175
+ }
129
176
  /** Start a turn: fresh cancellation signal, handed to the agent loop. */
130
177
  beginTurn() {
131
178
  this.turnSignal = { aborted: false };
@@ -142,7 +189,7 @@ var StreamJsonSession = class {
142
189
  }
143
190
  /** Reject any still-pending approvals/questions (e.g. the host disconnected). */
144
191
  cancelPending() {
145
- for (const resolve of this.pendingApprove.values()) resolve(false);
192
+ for (const pending of this.pendingApprove.values()) pending.resolve(false);
146
193
  this.pendingApprove.clear();
147
194
  for (const resolve of this.pendingAnswer.values()) resolve("");
148
195
  this.pendingAnswer.clear();
@@ -153,7 +200,7 @@ async function runCodeStreamJsonSession(options) {
153
200
  const spawnAuto = options.spawnAuto ?? !!auto;
154
201
  const session = new StreamJsonSession(emit, spawnAuto);
155
202
  bindDecisions?.(session);
156
- emit({ event: "session-start", sessionId, resumed });
203
+ emit({ event: "session-start", sessionId, resumed, ...options.sessionInfo ?? {} });
157
204
  const turns = [];
158
205
  let priorSummary;
159
206
  const first = options.instruction?.trim();
@@ -172,7 +219,9 @@ async function runCodeStreamJsonSession(options) {
172
219
  session,
173
220
  agentMode: request.agentMode,
174
221
  auto: turnAuto && request.agentMode !== "plan",
175
- images: request.images
222
+ images: request.images,
223
+ reasoningEffort: request.reasoningEffort,
224
+ attachments: request.attachments
176
225
  });
177
226
  emit({ event: "done", result });
178
227
  turn = { instruction, result };
@@ -184,6 +233,9 @@ async function runCodeStreamJsonSession(options) {
184
233
  }
185
234
  turns.push(turn);
186
235
  priorSummary = onTurnEnd?.(turn) ?? priorSummary;
236
+ if (request.agentMode === "plan" && turn.result) {
237
+ emit({ event: "plan-ready", turns: turns.length });
238
+ }
187
239
  emit({ event: "idle", turns: turns.length });
188
240
  request = await nextTurn();
189
241
  }
@@ -211,6 +263,6 @@ async function runCodeStreamJson(options) {
211
263
  }
212
264
  }
213
265
 
214
- export { StreamJsonSession, parseHostMessage, runCodeStreamJson, runCodeStreamJsonSession };
215
- //# sourceMappingURL=stream-json-DUCFTBUF.js.map
216
- //# sourceMappingURL=stream-json-DUCFTBUF.js.map
266
+ export { STREAM_JSON_PROTOCOL_VERSION, StreamJsonSession, parseHostMessage, runCodeStreamJson, runCodeStreamJsonSession };
267
+ //# sourceMappingURL=stream-json-LKVPDKXP.js.map
268
+ //# sourceMappingURL=stream-json-LKVPDKXP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/code/stream-json.ts"],"names":[],"mappings":"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","file":"stream-json-LKVPDKXP.js","sourcesContent":["/**\n * Machine-readable event protocol for `vg code --stream-json` (VG-CLI-CODE §18).\n *\n * A host UI (the VS Code VG Code panel) can't drive the agent through the human\n * TTY renderer, so this exposes the agent as a line protocol: every\n * {@link AgentEvent} is emitted as one NDJSON object on stdout, and each\n * approval / user question is a round-trip — an event out, a decision/answer\n * line in. This keeps the governance gate intact across the process boundary\n * (the host's Approve/Reject and question UI fulfil the same contracts the CLI\n * would — no quick-apply back-door), while the host stays a pure relay.\n *\n * Pure over an injected `emit` + the decision channel, so the protocol is\n * unit-tested without a process, model, or socket.\n */\n\nimport { runAgent, type AgentEvent, type AgentOptions, type AgentResult } from './agent.js';\nimport type { AskUserRequest, MutatingAction } from './tools.js';\nimport { sanitizeAttachments, type SessionAttachment } from './session-store.js';\nimport type { ImageAttachment, ReasoningEffort } from './types.js';\n\n/**\n * Version of this NDJSON protocol, carried on `session-start`. Hosts use it to\n * fail closed (e.g. disable features that need a newer engine) instead of\n * silently assuming the engine honours frames it may not know. Bump when a\n * frame is added or its meaning changes.\n *\n * - 1 (implicit): the original protocol; `session-start` had no version field.\n * - 2: `session-start` reports sessionDir/engineVersion/protocolVersion/\n * provider/model; `--continue` accepts an explicit session id; checkpoint\n * restore is available out-of-band via `vg code --restore-checkpoint`.\n * - 3: approvals accept `always: true` (persist a standing allow rule from\n * `.vibgrate/code-approvals.json`); a completed plan turn emits\n * `plan-ready` before `idle` so hosts can offer Approve plan / Keep\n * planning; read-only commands auto-approve engine-side.\n * - 4: `inject` steers the running turn (content lands at the next step\n * boundary, announced by an `injected` event); `rename` titles the live\n * session; the session store keeps an `index.json` (list without parsing\n * every session) and supports rename/delete/fork/rewind out-of-band;\n * `session-start` reports `worktree` when the run is rooted in one.\n * - 5: reasoning models are visible — a `thinking` event streams the model's\n * reasoning channel separately from its answer, and `submit` carries an\n * optional `reasoningEffort`. The `usage` event reports\n * `cachedPromptTokens` when the provider says how much of the prompt it\n * served from cache, so a host can price a turn instead of guessing.\n * `submit` also carries `attachments` metadata, so a restored chat can\n * show what was attached to a turn (names and sizes, never the bytes).\n */\nexport const STREAM_JSON_PROTOCOL_VERSION = 5;\n\n/** Environment facts a `session-start` frame reports to the host (all optional for older callers). */\nexport interface SessionStartInfo {\n /** Absolute directory session files live in — the single source of truth for history UIs. */\n sessionDir?: string;\n /** Engine (CLI) version string, for host version reports. */\n engineVersion?: string;\n protocolVersion?: number;\n provider?: string;\n model?: string;\n /** v4: set when this session runs inside an isolated git worktree. */\n worktree?: { path: string; base: string };\n}\n\n/** Per-turn approval posture a host can send with `submit` (session mode). */\nexport type TurnAgentMode = 'agent' | 'plan' | 'auto';\n\n/** One queued task from the host: instruction plus optional mode/attachments. */\nexport interface TurnRequest {\n instruction: string;\n /** Overrides the spawn-time posture for this turn only (plan blocks writes engine-side). */\n agentMode?: TurnAgentMode;\n /** Images attached to this turn (multimodal providers encode them). */\n images?: ImageAttachment[];\n /** v5: reasoning budget for this turn (ignored by models without the knob). */\n reasoningEffort?: ReasoningEffort;\n /**\n * v5: what the user attached, as metadata only (name/kind/size). The bytes\n * travel separately on `images` (or already folded into the instruction for\n * text); this exists so the stored session can show a restored chat what was\n * attached without carrying the payload.\n */\n attachments?: SessionAttachment[];\n}\n\n/** A single line written to the host. Discriminated by `event`. */\nexport type StreamJsonOut =\n | ({ event: 'event' } & AgentEvent)\n | { event: 'approve-request'; id: number; action: MutatingAction }\n /** Clarifying question for the human — host shows a prompt and answers via stdin. */\n | { event: 'user-question'; id: number; question: string; options?: string[] }\n | { event: 'done'; result: AgentResult }\n | { event: 'error'; message: string }\n /** Session mode only: the process is up and owns this session id. */\n | ({ event: 'session-start'; sessionId: string; resumed: boolean } & SessionStartInfo)\n /** Session mode only: the turn ended; send another `submit` or `end`. */\n | { event: 'idle'; turns: number }\n /**\n * Session mode only (v3): a plan-mode turn just completed. Emitted before\n * `idle` so a host can paint an Approve plan / Keep planning affordance;\n * hosts that don't know the frame ignore it and see `idle` as before.\n */\n | { event: 'plan-ready'; turns: number }\n /** Outcome of a checkpoint restore the host asked for. */\n | {\n event: 'checkpoint-restored';\n commit: string;\n restored: string[];\n removed: string[];\n failed: string[];\n };\n\n/**\n * A line read from the host. Approvals and answers fulfil an open round-trip;\n * `submit` starts the next turn in a session; `cancel` stops the running turn\n * without killing the process; `end` closes the session.\n */\nexport type HostMessage =\n | { kind: 'approve'; id: number; approve: boolean; always?: boolean }\n | { kind: 'answer'; id: number; answer: string }\n | {\n kind: 'submit';\n instruction: string;\n agentMode?: TurnAgentMode;\n images?: ImageAttachment[];\n /** v5: reasoning budget for this turn (ignored by models without the knob). */\n reasoningEffort?: ReasoningEffort;\n /** v5: attachment metadata for the session record (never the bytes). */\n attachments?: SessionAttachment[];\n }\n | { kind: 'restore'; commit: string; files: string[] }\n /** Manual compaction: condense the stored session so the recap shrinks. */\n | { kind: 'compact' }\n /**\n * v4 steer: mid-turn user content for the *running* turn, applied at the next\n * step boundary (unlike `submit`, which queues a whole next turn). Buffered —\n * an inject racing the turn's end is delivered at the start of the next turn\n * rather than dropped.\n */\n | { kind: 'inject'; text: string }\n /** v4: title the live session (empty text clears back to the derived name). */\n | { kind: 'rename'; title: string }\n | { kind: 'cancel' }\n | { kind: 'end' };\n\n/**\n * Parse one host line. Returns null for malformed input or an unknown shape, so\n * a garbled line is ignored rather than taking the session down.\n */\nexport function parseHostMessage(raw: string): HostMessage | null {\n let msg: Record<string, unknown>;\n try {\n msg = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return null;\n }\n if (!msg || typeof msg !== 'object') return null;\n if (typeof msg.approveId === 'number') {\n // v3: `always: true` on an approval asks the engine to persist a standing\n // allow rule for this action shape. Only meaningful with approve: true.\n return {\n kind: 'approve',\n id: msg.approveId,\n approve: !!msg.approve,\n ...(msg.always === true && msg.approve ? { always: true } : {}),\n };\n }\n if (typeof msg.answerId === 'number') {\n return { kind: 'answer', id: msg.answerId, answer: String(msg.answer ?? '') };\n }\n if (typeof msg.submit === 'string' && msg.submit.trim()) {\n const agentMode =\n msg.agentMode === 'plan' || msg.agentMode === 'auto' || msg.agentMode === 'agent'\n ? msg.agentMode\n : undefined;\n const images = Array.isArray(msg.images)\n ? (msg.images as unknown[])\n .filter(\n (a): a is ImageAttachment =>\n !!a &&\n typeof a === 'object' &&\n typeof (a as ImageAttachment).name === 'string' &&\n typeof (a as ImageAttachment).mediaType === 'string' &&\n typeof (a as ImageAttachment).dataBase64 === 'string',\n )\n .slice(0, 8)\n : undefined;\n const reasoningEffort =\n msg.reasoningEffort === 'low' || msg.reasoningEffort === 'medium' || msg.reasoningEffort === 'high'\n ? msg.reasoningEffort\n : undefined;\n const attachments = sanitizeAttachments(msg.attachments);\n return {\n kind: 'submit',\n instruction: msg.submit.trim(),\n ...(agentMode ? { agentMode } : {}),\n ...(images?.length ? { images } : {}),\n ...(reasoningEffort ? { reasoningEffort } : {}),\n ...(attachments.length ? { attachments } : {}),\n };\n }\n if (\n msg.restore &&\n typeof msg.restore === 'object' &&\n typeof (msg.restore as Record<string, unknown>).commit === 'string'\n ) {\n const r = msg.restore as { commit: string; files?: unknown };\n const files = Array.isArray(r.files) ? r.files.filter((f): f is string => typeof f === 'string') : [];\n if (files.length) return { kind: 'restore', commit: r.commit, files };\n return null;\n }\n if (msg.compactSession === true) return { kind: 'compact' };\n if (typeof msg.inject === 'string' && msg.inject.trim()) {\n return { kind: 'inject', text: msg.inject.trim() };\n }\n if (typeof msg.renameSession === 'string') {\n return { kind: 'rename', title: msg.renameSession.trim() };\n }\n if (msg.cancel === true) return { kind: 'cancel' };\n if (msg.end === true) return { kind: 'end' };\n return null;\n}\n\n/**\n * Owns the NDJSON protocol for one run: serializes agent events, and turns each\n * approval / user question into a host round-trip via {@link submitDecision} /\n * {@link submitAnswer}. Under `auto`, approvals resolve true immediately (still\n * announced, for the log); user questions get a default \"proceed\" answer.\n */\nexport class StreamJsonSession {\n private nextId = 1;\n private readonly pendingApprove = new Map<\n number,\n { resolve: (approve: boolean) => void; action: MutatingAction }\n >();\n private readonly pendingAnswer = new Map<number, (answer: string) => void>();\n /** Cancellation for the turn currently running (session mode). */\n private turnSignal: { aborted: boolean } = { aborted: false };\n /**\n * v4 steer: user content injected mid-turn, drained by the agent loop at its\n * next step boundary. Deliberately NOT cleared between turns — an inject that\n * races the turn's end should land at the start of the next turn, not vanish.\n */\n private injected: string[] = [];\n /**\n * v3: called when the host approved with `always: true` — the owner persists\n * a standing rule derived from the approved action. Injected (not imported)\n * so this protocol class stays free of filesystem concerns.\n */\n onAlwaysRule?: (action: MutatingAction) => void;\n\n constructor(\n private readonly emit: (line: StreamJsonOut) => void,\n private auto = false,\n ) {}\n\n /**\n * Per-turn approval posture (session mode): a host `submit` can flip auto on\n * or off for the coming turn without respawning the process.\n */\n setAuto(auto: boolean): void {\n this.auto = auto;\n }\n\n /** The agent's onEvent → one NDJSON line per event. */\n readonly onEvent = (e: AgentEvent): void => {\n this.emit({ event: 'event', ...e });\n };\n\n /** The agent's approval gate → an approve-request the host answers. */\n readonly approve = (action: MutatingAction): Promise<boolean> => {\n const id = this.nextId++;\n if (this.auto) {\n this.emit({ event: 'approve-request', id, action });\n return Promise.resolve(true);\n }\n return new Promise<boolean>((resolve) => {\n this.pendingApprove.set(id, { resolve, action });\n this.emit({ event: 'approve-request', id, action });\n });\n };\n\n /** Clarifying question → user-question the host answers with free text. */\n readonly askUser = (req: AskUserRequest): Promise<string> => {\n const id = this.nextId++;\n const question = req.question.trim();\n const options = req.options?.filter(Boolean);\n if (this.auto) {\n this.emit({ event: 'user-question', id, question, options });\n return Promise.resolve(\n 'Autonomous mode: no human. Proceed with safest defaults and state assumptions.',\n );\n }\n return new Promise<string>((resolve) => {\n this.pendingAnswer.set(id, resolve);\n this.emit({ event: 'user-question', id, question, options });\n });\n };\n\n /** Host → agent: resolve a pending approval. Unknown ids are ignored. */\n submitDecision(id: number, approve: boolean, always = false): void {\n const pending = this.pendingApprove.get(id);\n if (pending) {\n this.pendingApprove.delete(id);\n // Persist the standing rule before resolving, so the rule exists by the\n // time the approved action (and any follow-up like it) executes.\n if (approve && always) this.onAlwaysRule?.(pending.action);\n pending.resolve(approve);\n }\n }\n\n /** Host → agent: resolve a pending user-question. Unknown ids are ignored. */\n submitAnswer(id: number, answer: string): void {\n const resolve = this.pendingAnswer.get(id);\n if (resolve) {\n this.pendingAnswer.delete(id);\n resolve(answer ?? '');\n }\n }\n\n /** Host → agent (v4): steer the running turn with more user content. */\n inject(text: string): void {\n const t = text.trim();\n if (t) this.injected.push(t);\n }\n\n /**\n * Drain pending steer content (joined, oldest first) for the agent loop's\n * next step. Null when nothing is pending.\n */\n drainInjected(): string | null {\n if (!this.injected.length) return null;\n const text = this.injected.join('\\n\\n');\n this.injected = [];\n return text;\n }\n\n /** Start a turn: fresh cancellation signal, handed to the agent loop. */\n beginTurn(): { aborted: boolean } {\n this.turnSignal = { aborted: false };\n return this.turnSignal;\n }\n\n /**\n * Host → agent: stop the running turn. Sets the cooperative signal *and*\n * rejects anything the turn is blocked on, so a turn waiting at an approval\n * gate unblocks instead of hanging until the process dies.\n */\n cancelTurn(): void {\n this.turnSignal.aborted = true;\n this.cancelPending();\n }\n\n /** Reject any still-pending approvals/questions (e.g. the host disconnected). */\n cancelPending(): void {\n for (const pending of this.pendingApprove.values()) pending.resolve(false);\n this.pendingApprove.clear();\n for (const resolve of this.pendingAnswer.values()) resolve('');\n this.pendingAnswer.clear();\n }\n}\n\nexport interface StreamJsonOptions extends Omit<AgentOptions, 'approve' | 'onEvent' | 'askUser'> {\n emit: (line: StreamJsonOut) => void;\n /** Register the stdin decision reader; the returned session accepts decisions. */\n bindDecisions?: (session: StreamJsonSession) => void;\n}\n\n/** One turn of a session: what the host asked, and how it ended. */\nexport interface StreamJsonTurn {\n instruction: string;\n result: AgentResult | null;\n}\n\nexport interface StreamJsonSessionRunOptions {\n emit: (line: StreamJsonOut) => void;\n /** Bound once for the whole session, not per turn. */\n bindDecisions?: (session: StreamJsonSession) => void;\n auto?: boolean;\n sessionId: string;\n /** True when this session was reloaded from disk (`--continue`). */\n resumed: boolean;\n /** Environment facts to report on `session-start` (dir, versions, model). */\n sessionInfo?: SessionStartInfo;\n /** Instruction for the first turn. Omit to wait for the host's first `submit`. */\n instruction?: string;\n /** Spawn-time approval posture; per-turn `agentMode` on `submit` overrides it. */\n spawnAuto?: boolean;\n /** Await the host's next task; resolve null to end the session. */\n nextTurn: () => Promise<TurnRequest | null>;\n /**\n * Run one turn. Injected so the heavy agent wiring (graph, providers, MCP,\n * sandbox) is built once by the caller and reused across turns — the whole\n * point of session mode.\n */\n runTurn: (turn: {\n instruction: string;\n priorSummary?: string;\n signal: { aborted: boolean };\n session: StreamJsonSession;\n /** Per-turn posture from the host (plan blocks writes engine-side). */\n agentMode?: TurnAgentMode;\n /** Effective auto for this turn (spawn flag overridden by agentMode). */\n auto: boolean;\n images?: ImageAttachment[];\n /** v5: per-turn reasoning budget, straight from the host's `submit`. */\n reasoningEffort?: ReasoningEffort;\n /** v5: attachment metadata for the session record (never the bytes). */\n attachments?: SessionAttachment[];\n }) => Promise<AgentResult>;\n /**\n * Record a finished turn. Returns the recap to seed the next turn, so\n * continuity is the caller's policy (session store, summarizer) not ours.\n */\n onTurnEnd?: (turn: StreamJsonTurn) => string | undefined;\n}\n\n/**\n * Session mode for `vg code --stream-json --session`: hold the process open and\n * run turn after turn against warm state, instead of paying a cold start (graph\n * load, overlay rebuild, MCP connect, model warm-up) on every message.\n *\n * Each turn still emits exactly the frames a single-shot run does, so a host\n * that already speaks the one-shot protocol only needs to learn `idle`. A turn\n * that throws is reported and the session stays up — one bad task should not\n * cost the user their conversation.\n */\nexport async function runCodeStreamJsonSession(\n options: StreamJsonSessionRunOptions,\n): Promise<StreamJsonTurn[]> {\n const { emit, bindDecisions, auto, sessionId, resumed, nextTurn, runTurn, onTurnEnd } = options;\n const spawnAuto = options.spawnAuto ?? !!auto;\n const session = new StreamJsonSession(emit, spawnAuto);\n bindDecisions?.(session);\n emit({ event: 'session-start', sessionId, resumed, ...(options.sessionInfo ?? {}) });\n\n const turns: StreamJsonTurn[] = [];\n let priorSummary: string | undefined;\n const first = options.instruction?.trim();\n let request: TurnRequest | null = first ? { instruction: first } : await nextTurn();\n\n while (request) {\n const signal = session.beginTurn();\n // Per-turn posture: an explicit agentMode overrides the spawn flag; plan\n // never auto-approves. First turn without a mode keeps the spawn posture.\n const turnAuto = request.agentMode ? request.agentMode === 'auto' : spawnAuto;\n session.setAuto(turnAuto && request.agentMode !== 'plan');\n const instruction = request.instruction;\n let turn: StreamJsonTurn;\n try {\n const result = await runTurn({\n instruction,\n priorSummary,\n signal,\n session,\n agentMode: request.agentMode,\n auto: turnAuto && request.agentMode !== 'plan',\n images: request.images,\n reasoningEffort: request.reasoningEffort,\n attachments: request.attachments,\n });\n emit({ event: 'done', result });\n turn = { instruction, result };\n } catch (e) {\n emit({ event: 'error', message: (e as Error).message });\n turn = { instruction, result: null };\n } finally {\n session.cancelPending();\n }\n turns.push(turn);\n priorSummary = onTurnEnd?.(turn) ?? priorSummary;\n // v3: a completed plan turn announces itself so hosts can offer\n // Approve plan / Keep planning. A failed turn is not a ready plan.\n if (request.agentMode === 'plan' && turn.result) {\n emit({ event: 'plan-ready', turns: turns.length });\n }\n emit({ event: 'idle', turns: turns.length });\n request = await nextTurn();\n }\n return turns;\n}\n\n/** Run the agent under the NDJSON protocol; always emits a terminal `done`/`error`. */\nexport async function runCodeStreamJson(options: StreamJsonOptions): Promise<AgentResult | null> {\n const { emit, bindDecisions, auto, ...agentOptions } = options;\n const session = new StreamJsonSession(emit, !!auto);\n bindDecisions?.(session);\n try {\n const result = await runAgent({\n ...agentOptions,\n auto,\n approve: session.approve,\n askUser: session.askUser,\n onEvent: session.onEvent,\n });\n emit({ event: 'done', result });\n return result;\n } catch (e) {\n emit({ event: 'error', message: (e as Error).message });\n return null;\n } finally {\n session.cancelPending();\n }\n}\n"]}
@@ -0,0 +1,4 @@
1
+ export { VERSION } from './chunk-QIUQH2ND.js';
2
+ import './chunk-Z6ZWNWWR.js';
3
+ //# sourceMappingURL=version-55TOTJTF.js.map
4
+ //# sourceMappingURL=version-55TOTJTF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"version-55TOTJTF.js"}
@@ -1,18 +1,19 @@
1
- import { TOOLS } from './chunk-5ESL76CM.js';
2
- import './chunk-INIULQEP.js';
1
+ import { TOOLS } from './chunk-BTYFZ3NM.js';
3
2
  import './chunk-HTLDXEHW.js';
4
- import './chunk-QXIWQ2WG.js';
3
+ import './chunk-N6ZMZ5AI.js';
4
+ import './chunk-NXDYWBZB.js';
5
+ import './chunk-J7LKEB2R.js';
6
+ import './chunk-EBUTRJHX.js';
5
7
  import './chunk-CQDUBAQY.js';
6
8
  import './chunk-OV4KGXPD.js';
7
9
  import './chunk-5I4VSBWQ.js';
8
10
  import './chunk-DT4KIVRI.js';
9
11
  import './chunk-CRAMOEBE.js';
10
- import './chunk-J7LKEB2R.js';
11
- import './chunk-7CYFCSY2.js';
12
12
  import './chunk-RXP66R2E.js';
13
- import './chunk-LS7GZBKP.js';
14
- import './chunk-2M6B5V2U.js';
15
- import './chunk-ITY2NPIQ.js';
13
+ import './chunk-UJAOCFQQ.js';
14
+ import './chunk-JYY6G46J.js';
15
+ import './chunk-K7MONYIM.js';
16
+ import './chunk-QIUQH2ND.js';
16
17
  import './chunk-BWPBB45M.js';
17
18
  import './chunk-JFGYT6BI.js';
18
19
  import './chunk-BPF3YX2U.js';
@@ -75,5 +76,5 @@ function vgMcpToolNames() {
75
76
  }
76
77
 
77
78
  export { VG_MCP_SERVER_ID, createVgBuiltinMcpTools, mergeExternalToolsets, vgMcpToolNames };
78
- //# sourceMappingURL=vg-mcp-bridge-4KPDQUFN.js.map
79
- //# sourceMappingURL=vg-mcp-bridge-4KPDQUFN.js.map
79
+ //# sourceMappingURL=vg-mcp-bridge-ZPJAHP7T.js.map
80
+ //# sourceMappingURL=vg-mcp-bridge-ZPJAHP7T.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/code/vg-mcp-bridge.ts"],"names":[],"mappings":"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","file":"vg-mcp-bridge-ZPJAHP7T.js","sourcesContent":["/**\n * Always-on bridge from local `vg serve` (Vibgrate AI Context) tools into the\n * VG Code agent tool list.\n *\n * External project MCP servers (`.mcp.json`, etc.) remain optional. The tools\n * shipped by the installed `vg` CLI — `search_symbols`, `query_graph`,\n * `impact_of`, `library_docs`, … — are available on every run without spawning\n * a separate MCP process: same handlers as stdio `vg serve`, in-process over\n * the session graph.\n *\n * Namespaced as `mcp__vibgrate__<tool>` so they sit next to third-party\n * `mcp__<server>__*` tools without collisions.\n */\n\nimport { TOOLS, type VgTool } from '../mcp/tools.js';\nimport type { VgGraph } from '../schema.js';\nimport type { ToolCall, ToolSpec } from './types.js';\nimport type { ToolResult } from './tools.js';\n\nexport const VG_MCP_SERVER_ID = 'vibgrate' as const;\nconst NS = `mcp__${VG_MCP_SERVER_ID}__`;\n\nexport type ExternalToolset = {\n specs: ToolSpec[];\n owns: (name: string) => boolean;\n execute: (call: ToolCall, live?: { graph: VgGraph }) => Promise<ToolResult>;\n};\n\nexport interface VgBuiltinMcpOptions {\n /** Live graph accessor (session overlay may refresh symbols mid-run). */\n getGraph: () => VgGraph;\n root: string;\n /** Air-gap: no network in library/docs/embedder paths. */\n local?: boolean;\n}\n\n/** In-process toolset matching the local `vg serve` MCP surface. */\nexport function createVgBuiltinMcpTools(opts: VgBuiltinMcpOptions): ExternalToolset {\n const byName = new Map<string, VgTool>();\n for (const t of TOOLS) byName.set(`${NS}${t.name}`, t);\n\n const specs: ToolSpec[] = TOOLS.map((t) => ({\n name: `${NS}${t.name}`,\n description: `[${VG_MCP_SERVER_ID}] ${t.description}`,\n parameters: t.inputSchema && typeof t.inputSchema === 'object' ? t.inputSchema : { type: 'object', properties: {} },\n })).sort((a, b) => a.name.localeCompare(b.name));\n\n return {\n specs,\n owns: (name) => byName.has(name),\n async execute(call, live) {\n const tool = byName.get(call.name);\n if (!tool) return { content: `unknown MCP tool ${call.name}`, mutated: false };\n try {\n const graph = live?.graph ?? opts.getGraph();\n const raw = await tool.handler(graph, call.arguments ?? {}, {\n root: opts.root,\n local: opts.local,\n dedup: false,\n });\n const text = typeof raw === 'string' ? raw : JSON.stringify(raw, null, 2);\n return { content: text.slice(0, 12_000), mutated: false };\n } catch (e) {\n return { content: `MCP tool ${call.name} failed: ${(e as Error).message}`, mutated: false };\n }\n },\n };\n}\n\n/** Merge toolsets; later sets win on name clashes. */\nexport function mergeExternalToolsets(...sets: Array<ExternalToolset | undefined | null>): ExternalToolset | undefined {\n const active = sets.filter((s): s is ExternalToolset => !!s && s.specs.length > 0);\n if (active.length === 0) return undefined;\n if (active.length === 1) return active[0];\n\n const byName = new Map<string, { set: ExternalToolset; spec: ToolSpec }>();\n for (const set of active) {\n for (const spec of set.specs) byName.set(spec.name, { set, spec });\n }\n const specs = [...byName.values()].map((v) => v.spec).sort((a, b) => a.name.localeCompare(b.name));\n return {\n specs,\n owns: (name) => active.some((s) => s.owns(name)),\n async execute(call, live) {\n for (let i = active.length - 1; i >= 0; i--) {\n if (active[i]!.owns(call.name)) return active[i]!.execute(call, live);\n }\n return { content: `unknown external tool ${call.name}`, mutated: false };\n },\n };\n}\n\n/** Namespaced vibgrate tool names for tests / prompts. */\nexport function vgMcpToolNames(): string[] {\n return TOOLS.map((t) => `${NS}${t.name}`);\n}\n"]}
@@ -1,19 +1,20 @@
1
- export { ActiveGraphCache, BranchGraphSession, DEFAULT_ACTIVE_GRAPH_IDLE_MS, VGD_PROTOCOL_VERSION, WorkspaceRegistry, parseRequest, startVgdServer } from './chunk-2HAJCW7Z.js';
1
+ export { ActiveGraphCache, BranchGraphSession, DEFAULT_ACTIVE_GRAPH_IDLE_MS, VGD_PROTOCOL_VERSION, WorkspaceRegistry, parseRequest, startVgdServer } from './chunk-2W3GBKSV.js';
2
2
  export { createHostExecutionEnv, detectSandboxCapabilities, detectSecurityCapabilities, firejailArgv, resolveExecutionEnv, selectSandboxBackend } from './chunk-IS7VTH2Q.js';
3
- export { MODEL_EXECUTION_PROFILE_SCHEMA_VERSION, defaultModelExecutionProfile, mergeModelExecutionProfile, resolveModelExecutionProfile } from './chunk-IZDH67DX.js';
4
- export { vgdIsRunning, vgdPidPath, vgdRequest, vgdSocketPath } from './chunk-RBIRXQR6.js';
5
3
  import './chunk-3LOWJSAF.js';
4
+ export { vgdIsRunning, vgdPidPath, vgdRequest, vgdSocketPath } from './chunk-RBIRXQR6.js';
6
5
  import './chunk-5HYCB55P.js';
7
- export { FEDERATION_SCHEMA_VERSION, federationFromWorkspaceRoots, federationPath, highConfidenceBridges, loadFederation, loadOrDiscoverFederation, writeFederationFile } from './chunk-5I4VSBWQ.js';
6
+ export { MODEL_EXECUTION_PROFILE_SCHEMA_VERSION, defaultModelExecutionProfile, mergeModelExecutionProfile, resolveModelExecutionProfile } from './chunk-IZDH67DX.js';
8
7
  import './chunk-J7LKEB2R.js';
9
- import './chunk-7CYFCSY2.js';
10
- import './chunk-LS7GZBKP.js';
11
- import './chunk-JFCCJWXD.js';
12
- import './chunk-2M6B5V2U.js';
13
- import './chunk-ITY2NPIQ.js';
8
+ import './chunk-EBUTRJHX.js';
9
+ import './chunk-BXPWVTGS.js';
10
+ export { FEDERATION_SCHEMA_VERSION, federationFromWorkspaceRoots, federationPath, highConfidenceBridges, loadFederation, loadOrDiscoverFederation, writeFederationFile } from './chunk-5I4VSBWQ.js';
11
+ import './chunk-UJAOCFQQ.js';
12
+ import './chunk-JYY6G46J.js';
13
+ import './chunk-K7MONYIM.js';
14
+ import './chunk-QIUQH2ND.js';
14
15
  import './chunk-BWPBB45M.js';
15
16
  import './chunk-JFGYT6BI.js';
16
17
  export { activeGraphSlotKey, branchGraphSnapshotId, detectGitRef } from './chunk-BPF3YX2U.js';
17
18
  import './chunk-Z6ZWNWWR.js';
18
- //# sourceMappingURL=vgd-LFHQ4GWC.js.map
19
- //# sourceMappingURL=vgd-LFHQ4GWC.js.map
19
+ //# sourceMappingURL=vgd-UIFH5TTW.js.map
20
+ //# sourceMappingURL=vgd-UIFH5TTW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"vgd-UIFH5TTW.js"}
@@ -0,0 +1,82 @@
1
+ import './chunk-Z6ZWNWWR.js';
2
+ import * as path from 'path';
3
+
4
+ function worktreesDir(root) {
5
+ return path.join(root, ".vibgrate", "worktrees");
6
+ }
7
+ function looksLikeWorktreeId(v) {
8
+ return /^wt[a-z0-9]{4,16}$/.test(v);
9
+ }
10
+ function createSessionWorktree(git, root, id) {
11
+ if (!looksLikeWorktreeId(id)) return { error: `invalid worktree id: ${id}` };
12
+ const head = git(["rev-parse", "HEAD"]);
13
+ if (head.exitCode !== 0 || !head.stdout.trim()) {
14
+ return { error: "worktree sessions need a git repository with at least one commit" };
15
+ }
16
+ const base = head.stdout.trim();
17
+ const wtPath = path.join(worktreesDir(root), id);
18
+ const add = git(["worktree", "add", "--detach", wtPath, base]);
19
+ if (add.exitCode !== 0) {
20
+ return { error: `git worktree add failed: ${add.stdout.trim() || "see git output"}` };
21
+ }
22
+ git(["-C", wtPath, "config", "vibgrate.worktreeBase", base]);
23
+ return { id, path: wtPath, base };
24
+ }
25
+ function slashed(p) {
26
+ return p.replace(/\\/g, "/");
27
+ }
28
+ function listSessionWorktrees(git, root) {
29
+ const res = git(["worktree", "list", "--porcelain"]);
30
+ if (res.exitCode !== 0) return [];
31
+ const out = [];
32
+ const prefix = slashed(worktreesDir(root)) + "/";
33
+ let current = {};
34
+ for (const line of `${res.stdout}
35
+ `.split("\n")) {
36
+ if (line.startsWith("worktree ")) current = { path: line.slice("worktree ".length).trim() };
37
+ else if (line.startsWith("HEAD ")) current.head = line.slice("HEAD ".length).trim();
38
+ else if (!line.trim() && current.path) {
39
+ if (slashed(current.path).startsWith(prefix)) {
40
+ const id = path.basename(current.path);
41
+ if (looksLikeWorktreeId(id)) {
42
+ const recorded = git(["-C", current.path, "config", "vibgrate.worktreeBase"]);
43
+ const base = recorded.exitCode === 0 && recorded.stdout.trim() ? recorded.stdout.trim() : current.head ?? "";
44
+ out.push({ id, path: current.path, base });
45
+ }
46
+ }
47
+ current = {};
48
+ }
49
+ }
50
+ return out;
51
+ }
52
+ function worktreeDiffToBase(git, wtPath, base) {
53
+ const stage = git(["-C", wtPath, "add", "-A"]);
54
+ if (stage.exitCode !== 0) return { error: `could not stage the worktree: ${stage.stdout.trim()}` };
55
+ const names = git(["-C", wtPath, "diff", "--cached", "--name-only", base]);
56
+ if (names.exitCode !== 0) return { error: `could not diff the worktree: ${names.stdout.trim()}` };
57
+ const files = names.stdout.split("\n").map((l) => l.trim()).filter(Boolean);
58
+ if (!files.length) return { patch: "", files: [] };
59
+ const diff = git(["-C", wtPath, "diff", "--cached", "--binary", base]);
60
+ if (diff.exitCode !== 0) return { error: `could not diff the worktree: ${diff.stdout.trim()}` };
61
+ return { patch: diff.stdout, files };
62
+ }
63
+ function applyWorktreePatch(git, root, patchFile, files) {
64
+ const res = git(["-C", root, "apply", "--3way", "--whitespace=nowarn", patchFile]);
65
+ if (res.exitCode !== 0) {
66
+ return { applied: false, files, error: res.stdout.trim() || "git apply failed" };
67
+ }
68
+ return { applied: true, files };
69
+ }
70
+ function removeSessionWorktree(git, root, id) {
71
+ if (!looksLikeWorktreeId(id)) return { removed: false, error: `invalid worktree id: ${id}` };
72
+ const wtPath = path.join(worktreesDir(root), id);
73
+ const res = git(["worktree", "remove", "--force", wtPath]);
74
+ if (res.exitCode !== 0) {
75
+ return { removed: false, error: res.stdout.trim() || "git worktree remove failed" };
76
+ }
77
+ return { removed: true };
78
+ }
79
+
80
+ export { applyWorktreePatch, createSessionWorktree, listSessionWorktrees, looksLikeWorktreeId, removeSessionWorktree, worktreeDiffToBase, worktreesDir };
81
+ //# sourceMappingURL=worktree-session-D575IQWM.js.map
82
+ //# sourceMappingURL=worktree-session-D575IQWM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/code/worktree-session.ts"],"names":[],"mappings":"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","file":"worktree-session-D575IQWM.js","sourcesContent":["/**\n * Isolated worktree sessions for VG Code (P3 — session power features).\n *\n * A worktree session runs the agent in its own git worktree under\n * `.vibgrate/worktrees/<id>`, so parallel agents (or one risky experiment)\n * never fight the user's working tree. The flow is: create (detached at the\n * current HEAD) → agent edits inside the worktree → diff-to-base reviewed as\n * one patch → apply to the main tree (an approval-shaped decision made by the\n * host) → remove. The worktree shares the repository's object store, so\n * checkpoint refs and the diff/apply round-trip all stay plain git.\n *\n * Pure over an injected git runner, so every path is unit-tested without a\n * repository. All functions are conservative: a failed git call returns an\n * error outcome, never a throw mid-session.\n */\n\nimport * as path from 'node:path';\n\n/** Minimal git runner (same contract as checkpoint.ts). */\nexport type GitRunner = (\n args: string[],\n env?: Record<string, string>,\n) => { stdout: string; exitCode: number };\n\n/** Where worktree checkouts live, relative to the main repository root. */\nexport function worktreesDir(root: string): string {\n return path.join(root, '.vibgrate', 'worktrees');\n}\n\n/** True for a string shaped like a minted worktree id (`wt` + base36). */\nexport function looksLikeWorktreeId(v: string): boolean {\n return /^wt[a-z0-9]{4,16}$/.test(v);\n}\n\nexport interface WorktreeInfo {\n id: string;\n /** Absolute path of the checkout. */\n path: string;\n /** The commit the worktree was created from (diff base). */\n base: string;\n}\n\n/**\n * Create a detached worktree at the current HEAD. Returns the info the\n * session reports on `session-start` (and stores with the chat), or an error\n * string when the repository cannot host one (no commits, bare, git absent).\n */\nexport function createSessionWorktree(\n git: GitRunner,\n root: string,\n id: string,\n): WorktreeInfo | { error: string } {\n if (!looksLikeWorktreeId(id)) return { error: `invalid worktree id: ${id}` };\n const head = git(['rev-parse', 'HEAD']);\n if (head.exitCode !== 0 || !head.stdout.trim()) {\n return { error: 'worktree sessions need a git repository with at least one commit' };\n }\n const base = head.stdout.trim();\n const wtPath = path.join(worktreesDir(root), id);\n const add = git(['worktree', 'add', '--detach', wtPath, base]);\n if (add.exitCode !== 0) {\n return { error: `git worktree add failed: ${add.stdout.trim() || 'see git output'}` };\n }\n // Record the creation base in the worktree's own config: commits made\n // INSIDE the worktree move its HEAD, and the diff/apply delta must stay\n // anchored to where the worktree branched off — otherwise committed work\n // silently vanishes from the applied result.\n git(['-C', wtPath, 'config', 'vibgrate.worktreeBase', base]);\n return { id, path: wtPath, base };\n}\n\n/** Normalize to forward slashes for comparisons (git porcelain always uses /). */\nfunction slashed(p: string): string {\n return p.replace(/\\\\/g, '/');\n}\n\n/** Worktrees currently checked out under `.vibgrate/worktrees/` (best-effort). */\nexport function listSessionWorktrees(git: GitRunner, root: string): WorktreeInfo[] {\n const res = git(['worktree', 'list', '--porcelain']);\n if (res.exitCode !== 0) return [];\n const out: WorktreeInfo[] = [];\n // git prints forward-slash paths on every platform — compare normalized,\n // or Windows never matches its own worktrees.\n const prefix = slashed(worktreesDir(root)) + '/';\n let current: { path?: string; head?: string } = {};\n for (const line of `${res.stdout}\\n`.split('\\n')) {\n if (line.startsWith('worktree ')) current = { path: line.slice('worktree '.length).trim() };\n else if (line.startsWith('HEAD ')) current.head = line.slice('HEAD '.length).trim();\n else if (!line.trim() && current.path) {\n if (slashed(current.path).startsWith(prefix)) {\n const id = path.basename(current.path);\n if (looksLikeWorktreeId(id)) {\n // The diff base is the recorded creation point, never the current\n // HEAD — commits inside the worktree must stay in the delta.\n const recorded = git(['-C', current.path, 'config', 'vibgrate.worktreeBase']);\n const base = recorded.exitCode === 0 && recorded.stdout.trim()\n ? recorded.stdout.trim()\n : (current.head ?? '');\n out.push({ id, path: current.path, base });\n }\n }\n current = {};\n }\n }\n return out;\n}\n\nexport interface WorktreeDiff {\n /** Unified patch of everything the worktree changed vs its base (may be ''). */\n patch: string;\n /** Files touched, repo-relative. */\n files: string[];\n}\n\n/**\n * The worktree's full delta against a base commit, staged first so untracked\n * files are included. Staging happens in the worktree's own index — the main\n * tree's index is untouched by construction (separate worktree).\n */\nexport function worktreeDiffToBase(\n git: GitRunner,\n wtPath: string,\n base: string,\n): WorktreeDiff | { error: string } {\n const stage = git(['-C', wtPath, 'add', '-A']);\n if (stage.exitCode !== 0) return { error: `could not stage the worktree: ${stage.stdout.trim()}` };\n const names = git(['-C', wtPath, 'diff', '--cached', '--name-only', base]);\n if (names.exitCode !== 0) return { error: `could not diff the worktree: ${names.stdout.trim()}` };\n const files = names.stdout.split('\\n').map((l) => l.trim()).filter(Boolean);\n if (!files.length) return { patch: '', files: [] };\n const diff = git(['-C', wtPath, 'diff', '--cached', '--binary', base]);\n if (diff.exitCode !== 0) return { error: `could not diff the worktree: ${diff.stdout.trim()}` };\n return { patch: diff.stdout, files };\n}\n\nexport interface WorktreeApplyOutcome {\n applied: boolean;\n files: string[];\n error?: string;\n}\n\n/**\n * Apply a worktree's delta onto the main tree via `git apply --3way` (three-way\n * falls back to conflict markers instead of refusing when the main tree moved).\n * The patch travels through a file (`patchFile`) written by the caller, because\n * the runner contract has no stdin. Never commits — the user reviews the\n * applied changes like any other edit.\n */\nexport function applyWorktreePatch(\n git: GitRunner,\n root: string,\n patchFile: string,\n files: string[],\n): WorktreeApplyOutcome {\n const res = git(['-C', root, 'apply', '--3way', '--whitespace=nowarn', patchFile]);\n if (res.exitCode !== 0) {\n return { applied: false, files, error: res.stdout.trim() || 'git apply failed' };\n }\n return { applied: true, files };\n}\n\n/** Remove a session worktree (its checkout and git's bookkeeping). */\nexport function removeSessionWorktree(\n git: GitRunner,\n root: string,\n id: string,\n): { removed: boolean; error?: string } {\n if (!looksLikeWorktreeId(id)) return { removed: false, error: `invalid worktree id: ${id}` };\n const wtPath = path.join(worktreesDir(root), id);\n const res = git(['worktree', 'remove', '--force', wtPath]);\n if (res.exitCode !== 0) {\n return { removed: false, error: res.stdout.trim() || 'git worktree remove failed' };\n }\n return { removed: true };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibgrate/cli",
3
- "version": "2026.807.1",
3
+ "version": "2026.814.1",
4
4
  "description": "vg — local codebase intelligence CLI + MCP server for AI coding agents: deterministic code graph, drift reporting, and version-correct library docs (Apache-2.0)",
5
5
  "//mcpName": "Official MCP registry ownership proof: the registry fetches the published npm package and requires this field to match the com.vibgrate/ai-context server entry (see docs/marketing/mcp-registry/README.md). Must ship in the published @vibgrate/cli package.json.",
6
6
  "mcpName": "com.vibgrate/ai-context",
@@ -75,7 +75,7 @@
75
75
  ],
76
76
  "dependencies": {
77
77
  "@modelcontextprotocol/sdk": "^1.26.0",
78
- "@noble/hashes": "^2.2.0",
78
+ "@noble/hashes": "^2.3.0",
79
79
  "chalk": "^6.0.0",
80
80
  "commander": "^15.0.0",
81
81
  "fast-xml-parser": "^5.10.1",
@@ -96,17 +96,19 @@
96
96
  "yaml": "^2.8.3"
97
97
  },
98
98
  "optionalDependencies": {
99
- "fastembed": "^2.1.0"
99
+ "@anush008/tokenizers": "^0.6.0",
100
+ "onnxruntime-node": "^1.27.0",
101
+ "tar": "^7.5.19"
100
102
  },
101
103
  "devDependencies": {
102
- "@types/node": "^26.1.1",
103
- "@types/semver": "^7.5.0",
104
+ "@types/node": "^26.1.2",
105
+ "@types/semver": "^7.8.0",
104
106
  "@typescript-eslint/eslint-plugin": "^8.64.0",
105
- "@typescript-eslint/parser": "^8.65.0",
107
+ "@typescript-eslint/parser": "^8.66.0",
106
108
  "eslint": "^10.8.0",
107
109
  "graphology-types": "^0.24.8",
108
110
  "tsup": "^8.0.0",
109
- "tsx": "^4.23.1",
111
+ "tsx": "^4.23.10",
110
112
  "vitest": "^4.1.10"
111
113
  },
112
114
  "engines": {
@@ -1,24 +0,0 @@
1
- export { CONTEXT_POLICY_VERSION, DISCOVERY_TOOLS, MUTATION_TOOLS, compact, compactWithModel, runAgent } from './chunk-VQVLY63G.js';
2
- import './chunk-543E6WDJ.js';
3
- import './chunk-ADP6ITGF.js';
4
- import './chunk-REIGWTTH.js';
5
- import './chunk-EXOYSXH6.js';
6
- import './chunk-RBIRXQR6.js';
7
- import './chunk-5HYCB55P.js';
8
- export { summarizeCapsule } from './chunk-FOKURZL3.js';
9
- import './chunk-VIWZ4QT7.js';
10
- import './chunk-QXIWQ2WG.js';
11
- import './chunk-3LSG7Z4I.js';
12
- import './chunk-J7LKEB2R.js';
13
- import './chunk-7CYFCSY2.js';
14
- import './chunk-UTNNGKKX.js';
15
- import './chunk-RXP66R2E.js';
16
- import './chunk-LS7GZBKP.js';
17
- import './chunk-2M6B5V2U.js';
18
- import './chunk-ITY2NPIQ.js';
19
- import './chunk-BWPBB45M.js';
20
- import './chunk-JFGYT6BI.js';
21
- import './chunk-BPF3YX2U.js';
22
- import './chunk-Z6ZWNWWR.js';
23
- //# sourceMappingURL=agent-K3J6EHLI.js.map
24
- //# sourceMappingURL=agent-K3J6EHLI.js.map
@@ -1,9 +0,0 @@
1
- export { baselineCommand, runBaseline } from './chunk-Y4JO6LYP.js';
2
- import './chunk-INIULQEP.js';
3
- import './chunk-DT4KIVRI.js';
4
- import './chunk-CRAMOEBE.js';
5
- import './chunk-RXP66R2E.js';
6
- import './chunk-ITY2NPIQ.js';
7
- import './chunk-Z6ZWNWWR.js';
8
- //# sourceMappingURL=baseline-IAFWF2ET.js.map
9
- //# sourceMappingURL=baseline-IAFWF2ET.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/code/checkpoint.ts"],"names":[],"mappings":"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","file":"checkpoint-4WFZMKEO.js","sourcesContent":["/**\n * Checkpoints for VG Code (VG-CLI-CODE §18.4).\n *\n * A checkpoint is a snapshot of the working tree taken when the user approves a\n * change, so an approved edit can be undone after the fact. Two design choices\n * matter:\n *\n * - **Per approval, not per tool call.** A snapshot costs a tree write; taking\n * one for every read or search makes large repositories crawl. Approvals are\n * the points a user would actually want to return to.\n * - **Out of the way.** Snapshots are commits under `refs/vibgrate/checkpoints/`,\n * written with a private index file. The user's own index, staged changes,\n * branch, and HEAD are never touched, and nothing appears in `git log`.\n * Ignored files stay ignored — a checkpoint captures the project, not\n * `node_modules`.\n *\n * A checkpoint id is also recorded in run provenance, so the audit record of a\n * run points at the exact tree the agent produced: an auditor can check out\n * what happened rather than take the record's word for it.\n *\n * Pure over an injected git runner, so every path is unit-tested without a\n * repository.\n */\n\n/** Result of running a git command. */\nexport interface GitResult {\n stdout: string;\n exitCode: number;\n}\n\n/** Runs a git command with an optional private index file. */\nexport type GitRunner = (args: string[], env?: Record<string, string>) => GitResult;\n\nexport interface Checkpoint {\n /** Full ref name, e.g. `refs/vibgrate/checkpoints/s7a/2`. */\n ref: string;\n /** Commit id the ref points at. */\n commit: string;\n /** Sequence within the session, starting at 1. */\n seq: number;\n /** Repo-relative files the approved change touched. */\n files: string[];\n}\n\nexport function checkpointRef(sessionId: string, seq: number): string {\n // Session ids are engine-generated (`s<base36>`); keep the ref path safe anyway.\n const safe = sessionId.replace(/[^A-Za-z0-9_-]/g, '') || 'session';\n return `refs/vibgrate/checkpoints/${safe}/${seq}`;\n}\n\n/** True when the root is inside a git work tree. */\nexport function isGitRepo(git: GitRunner): boolean {\n return git(['rev-parse', '--is-inside-work-tree']).exitCode === 0;\n}\n\n/**\n * Snapshot the current working tree.\n *\n * Returns null when the repository isn't usable for snapshots (no git, or a\n * fresh repo with no objects yet) — a checkpoint is a convenience, and failing\n * to take one must never block an approved change from being applied.\n */\nexport function createCheckpoint(\n git: GitRunner,\n opts: { sessionId: string; seq: number; files: string[]; indexFile: string; message?: string },\n): Checkpoint | null {\n if (!isGitRepo(git)) return null;\n const env = { GIT_INDEX_FILE: opts.indexFile };\n\n // Stage everything into a *private* index: the user's staged work is untouched.\n if (git(['add', '-A'], env).exitCode !== 0) return null;\n const tree = git(['write-tree'], env);\n if (tree.exitCode !== 0) return null;\n const treeId = tree.stdout.trim();\n if (!treeId) return null;\n\n // Parent the snapshot on HEAD when there is one, so the commit is inspectable\n // with ordinary git tooling. A repo with no commits yet simply has no parent.\n const head = git(['rev-parse', 'HEAD']);\n const parent = head.exitCode === 0 && head.stdout.trim() ? ['-p', head.stdout.trim()] : [];\n const message = opts.message ?? `vg code checkpoint ${opts.seq}`;\n const commit = git(['commit-tree', treeId, ...parent, '-m', message], env);\n if (commit.exitCode !== 0) return null;\n const commitId = commit.stdout.trim();\n if (!commitId) return null;\n\n const ref = checkpointRef(opts.sessionId, opts.seq);\n if (git(['update-ref', ref, commitId]).exitCode !== 0) return null;\n return { ref, commit: commitId, seq: opts.seq, files: [...opts.files] };\n}\n\nexport interface RestoreOutcome {\n restored: string[];\n /** Files that did not exist in the checkpoint and were removed. */\n removed: string[];\n failed: string[];\n}\n\n/**\n * Restore files from a checkpoint.\n *\n * Scoped deliberately: only the paths given are touched, never the whole tree.\n * A checkpoint records which files a change wrote, so restoring undoes that\n * change without reverting unrelated work the user did in the meantime — the\n * behaviour someone expects from \"undo this edit\", and the safe default when\n * the alternative is silently discarding their own edits.\n *\n * A file that the checkpoint does not contain was created after it, so undoing\n * means deleting it.\n */\nexport function restoreCheckpoint(\n git: GitRunner,\n opts: { commit: string; files: string[] },\n): RestoreOutcome {\n const restored: string[] = [];\n const removed: string[] = [];\n const failed: string[] = [];\n\n for (const file of opts.files) {\n // Did this path exist in the snapshot?\n const probe = git(['cat-file', '-e', `${opts.commit}:${file}`]);\n if (probe.exitCode === 0) {\n const res = git(['checkout', opts.commit, '--', file]);\n if (res.exitCode === 0) restored.push(file);\n else failed.push(file);\n continue;\n }\n // Absent from the snapshot → it was created after; undo means removing it.\n const rm = git(['rm', '-f', '--ignore-unmatch', '--', file]);\n if (rm.exitCode === 0) removed.push(file);\n else failed.push(file);\n }\n return { restored, removed, failed };\n}\n\n/** Delete a session's checkpoint refs (e.g. when the session is discarded). */\nexport function deleteCheckpoints(git: GitRunner, sessionId: string, upTo: number): void {\n for (let seq = 1; seq <= upTo; seq++) {\n git(['update-ref', '-d', checkpointRef(sessionId, seq)]);\n }\n}\n"]}