very-happy-cli 0.2.116 → 0.2.118

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 (37) hide show
  1. package/dist/{AcpBackend-CfKPvoTU.mjs → AcpBackend-Bk9b823B.mjs} +116 -12
  2. package/dist/{AcpBackend-CauAQpC1.cjs → AcpBackend-p_KNJkHc.cjs} +116 -12
  3. package/dist/{AcpSessionManager-CA6xeET_.cjs → AcpSessionManager-B9FTbpGQ.cjs} +15 -2
  4. package/dist/{AcpSessionManager-BQ6pBRW4.mjs → AcpSessionManager-CDvqVHKf.mjs} +15 -2
  5. package/dist/{config-BpR_CwZu.mjs → config-CIpgmGLR.mjs} +2 -2
  6. package/dist/{config-BoteFn-v.cjs → config-CkUn1dI4.cjs} +2 -2
  7. package/dist/{index-C45xN8s0.mjs → index-B6cpyG_G.mjs} +78 -8
  8. package/dist/{index-D7azxfcs.mjs → index-BUVQf9PI.mjs} +2 -2
  9. package/dist/{index-4jiUeiUz.cjs → index-BXOXRblP.cjs} +513 -47
  10. package/dist/{index-DWmhmji9.cjs → index-BzgtwTxC.cjs} +77 -7
  11. package/dist/{index-lX1UliOs.cjs → index-CxjX8DGz.cjs} +2 -2
  12. package/dist/{index-Dq-eFp89.mjs → index-DIXjhnV1.mjs} +502 -45
  13. package/dist/index.cjs +2 -2
  14. package/dist/index.mjs +2 -2
  15. package/dist/{installTerminalHooks-k3TrBHD0.mjs → installTerminalHooks-BAa6LaQQ.mjs} +2 -2
  16. package/dist/{installTerminalHooks-DnaFkrTF.cjs → installTerminalHooks-lXQa6bQU.cjs} +2 -2
  17. package/dist/lib.cjs +1 -1
  18. package/dist/lib.d.cts +43 -1
  19. package/dist/lib.d.mts +43 -1
  20. package/dist/lib.mjs +1 -1
  21. package/dist/{mcp-DSpEpM_2.cjs → mcp-DMD7FxBI.cjs} +62 -16
  22. package/dist/{mcp-DRePTOap.mjs → mcp-Dwc299mU.mjs} +62 -17
  23. package/dist/{runGemini-_9-a7duU.mjs → runGemini-BaxGXE9w.mjs} +4 -4
  24. package/dist/{runGemini-IWHyBq0A.cjs → runGemini-Bj4Egq7j.cjs} +4 -4
  25. package/dist/{runOpenClaw-0myYIz1U.cjs → runOpenClaw-BJhSvXYy.cjs} +3 -3
  26. package/dist/{runOpenClaw-Boq6LQ9a.mjs → runOpenClaw-BwJhbIKU.mjs} +3 -3
  27. package/dist/{send-CwWvFfay.cjs → send-BWGUkWhi.cjs} +2 -2
  28. package/dist/{send-Cyo6mgMl.mjs → send-DX13svrS.mjs} +2 -2
  29. package/dist/sessions-CGhpBNqn.cjs +322 -0
  30. package/dist/sessions-L7O3ypda.mjs +317 -0
  31. package/dist/{spawn-DQ6FTUK9.cjs → spawn-CbY233Eg.cjs} +6 -7
  32. package/dist/{spawn-CU0DMauA.mjs → spawn-DPDWZdoW.mjs} +3 -4
  33. package/dist/{types-Ds0SiQ1D.mjs → types-BtuOM9lw.mjs} +52 -19
  34. package/dist/{types-C5kEpkcZ.cjs → types-ClvvHves.cjs} +54 -19
  35. package/package.json +7 -7
  36. package/dist/sessions-CbzqYiAy.cjs +0 -204
  37. package/dist/sessions-lvfTH_ql.mjs +0 -200
@@ -1,7 +1,7 @@
1
1
  import { spawn } from 'node:child_process';
2
2
  import { ndJsonStream, ClientSideConnection } from '@agentclientprotocol/sdk';
3
3
  import { randomUUID } from 'node:crypto';
4
- import { l as logger, d as contentLogMetadata, e as errorLogMetadata, f as packageJson, g as delay } from './types-Ds0SiQ1D.mjs';
4
+ import { l as logger, g as contentLogMetadata, h as errorLogMetadata, j as packageJson, k as delay } from './types-BtuOM9lw.mjs';
5
5
 
6
6
  const DEFAULT_TIMEOUTS = {
7
7
  /** Default initialization timeout: 60 seconds */
@@ -84,6 +84,97 @@ class DefaultTransport {
84
84
  }
85
85
  }
86
86
 
87
+ const ACP_RAW_INPUT_MAX_BYTES = 64 * 1024;
88
+ const ACP_TERMINAL_OUTPUT_MAX_BYTES = 64 * 1024;
89
+ const PI_TOOL_NAME_RE = /^[a-z][a-z0-9_-]{0,63}$/;
90
+ function deriveAcpToolArgs(update, options = {}) {
91
+ const args = {};
92
+ const title = typeof update.title === "string" ? update.title : void 0;
93
+ const kind = typeof update.kind === "string" ? update.kind : void 0;
94
+ if (title !== void 0) args.acpTitle = title;
95
+ if (kind !== void 0) args.acpKind = kind;
96
+ if (update.rawInput && typeof update.rawInput === "object" && !Array.isArray(update.rawInput)) {
97
+ const rawInput = update.rawInput;
98
+ if (serializedSize(rawInput) <= ACP_RAW_INPUT_MAX_BYTES) {
99
+ args.rawInput = rawInput;
100
+ } else {
101
+ args.rawInputTruncated = true;
102
+ }
103
+ }
104
+ if (options.agentName !== "pi") return args;
105
+ if (kind === "execute") {
106
+ args.piTool = "bash";
107
+ if (title !== void 0) args.command = title;
108
+ } else if (title !== void 0 && PI_TOOL_NAME_RE.test(title)) {
109
+ args.piTool = title;
110
+ }
111
+ return args;
112
+ }
113
+ function serializedSize(value) {
114
+ try {
115
+ return Buffer.byteLength(JSON.stringify(value) ?? "", "utf8");
116
+ } catch {
117
+ return Number.POSITIVE_INFINITY;
118
+ }
119
+ }
120
+ function resolveAcpPermissionRequest(params, newId) {
121
+ const toolCall = params.toolCall;
122
+ const toolName = toolCall?.kind || toolCall?.toolName || params.kind || "Unknown tool";
123
+ const toolCallId = toolCall?.id || newId();
124
+ let input;
125
+ if (toolCall) {
126
+ input = toolCall.input || toolCall.arguments || toolCall.rawInput || toolCall.content || {};
127
+ } else {
128
+ input = params.input || params.arguments || params.content || {};
129
+ }
130
+ input = { ...input, ...buildAcpPermissionMeta(toolCall) };
131
+ return { toolCallId, toolName, input };
132
+ }
133
+ function readAcpTerminalMeta(update) {
134
+ const meta = update._meta;
135
+ if (!meta || typeof meta !== "object") return {};
136
+ const record = meta;
137
+ const result = {};
138
+ const output = record.terminal_output;
139
+ if (output && typeof output === "object") {
140
+ const data = output.data;
141
+ if (typeof data === "string" && data.length > 0) result.outputDelta = data;
142
+ }
143
+ const exit = record.terminal_exit;
144
+ if (exit && typeof exit === "object") {
145
+ const code = exit.exit_code;
146
+ if (typeof code === "number" && Number.isFinite(code)) result.exitCode = code;
147
+ }
148
+ return result;
149
+ }
150
+ function appendTerminalOutput(previous, delta) {
151
+ const next = previous + delta;
152
+ if (Buffer.byteLength(next, "utf8") <= ACP_TERMINAL_OUTPUT_MAX_BYTES) return next;
153
+ const buf = Buffer.from(next, "utf8");
154
+ return buf.subarray(buf.length - ACP_TERMINAL_OUTPUT_MAX_BYTES).toString("utf8");
155
+ }
156
+ function buildAcpBashResult(output, exitCode) {
157
+ if (output === void 0 && exitCode === void 0) return void 0;
158
+ const text = output ?? "";
159
+ const truncated = Buffer.byteLength(text, "utf8") >= ACP_TERMINAL_OUTPUT_MAX_BYTES;
160
+ return {
161
+ text,
162
+ exitCode,
163
+ ...truncated ? { truncated: true } : {}
164
+ };
165
+ }
166
+ function buildAcpPermissionMeta(toolCall) {
167
+ if (!toolCall) return {};
168
+ const meta = {};
169
+ if (typeof toolCall.title === "string" && toolCall.title.length > 0) meta.acpTitle = toolCall.title;
170
+ if (typeof toolCall.kind === "string" && toolCall.kind.length > 0) meta.acpKind = toolCall.kind;
171
+ const raw = toolCall.rawInput;
172
+ if (raw && typeof raw === "object" && typeof raw.message === "string") {
173
+ meta.message = raw.message;
174
+ }
175
+ return meta;
176
+ }
177
+
87
178
  const DEFAULT_IDLE_TIMEOUT_MS = 500;
88
179
  const DEFAULT_TOOL_CALL_TIMEOUT_MS = 12e4;
89
180
  function parseArgsFromContent(content) {
@@ -207,6 +298,7 @@ function startToolCall(toolCallId, toolKind, update, ctx, source) {
207
298
  ctx.activeToolCalls.delete(toolCallId);
208
299
  ctx.toolCallStartTimes.delete(toolCallId);
209
300
  ctx.toolCallTimeouts.delete(toolCallId);
301
+ ctx.toolCallOutputs.delete(toolCallId);
210
302
  if (ctx.activeToolCalls.size === 0) {
211
303
  logger.debug("[AcpBackend] No more active tool calls after timeout, emitting idle status");
212
304
  ctx.emitIdleStatus();
@@ -223,6 +315,7 @@ function startToolCall(toolCallId, toolKind, update, ctx, source) {
223
315
  if (update.locations && Array.isArray(update.locations)) {
224
316
  args.locations = update.locations;
225
317
  }
318
+ Object.assign(args, deriveAcpToolArgs(update, { agentName: ctx.transport.agentName }));
226
319
  ctx.emit({
227
320
  type: "tool-call",
228
321
  toolName: toolKindStr || "unknown",
@@ -230,7 +323,7 @@ function startToolCall(toolCallId, toolKind, update, ctx, source) {
230
323
  callId: toolCallId
231
324
  });
232
325
  }
233
- function completeToolCall(toolCallId, toolKind, content, ctx) {
326
+ function completeToolCall(toolCallId, toolKind, content, ctx, exitCode) {
234
327
  const startTime = ctx.toolCallStartTimes.get(toolCallId);
235
328
  const duration = formatDuration(startTime);
236
329
  const toolKindStr = typeof toolKind === "string" ? toolKind : "unknown";
@@ -242,10 +335,13 @@ function completeToolCall(toolCallId, toolKind, content, ctx) {
242
335
  ctx.toolCallTimeouts.delete(toolCallId);
243
336
  }
244
337
  logger.debug(`[AcpBackend] Tool call COMPLETED: ${toolCallId} - Duration: ${duration}. Active tool calls: ${ctx.activeToolCalls.size}`);
338
+ const output = ctx.toolCallOutputs.get(toolCallId);
339
+ ctx.toolCallOutputs.delete(toolCallId);
340
+ const bashResult = buildAcpBashResult(output, exitCode);
245
341
  ctx.emit({
246
342
  type: "tool-result",
247
343
  toolName: toolKindStr,
248
- result: content,
344
+ result: bashResult ?? content,
249
345
  callId: toolCallId
250
346
  });
251
347
  if (ctx.activeToolCalls.size === 0) {
@@ -277,6 +373,7 @@ function failToolCall(toolCallId, status, toolKind, content, ctx) {
277
373
  }
278
374
  ctx.activeToolCalls.delete(toolCallId);
279
375
  ctx.toolCallStartTimes.delete(toolCallId);
376
+ ctx.toolCallOutputs.delete(toolCallId);
280
377
  const timeout = ctx.toolCallTimeouts.get(toolCallId);
281
378
  if (timeout) {
282
379
  clearTimeout(timeout);
@@ -314,6 +411,13 @@ function handleToolCallUpdate(update, ctx) {
314
411
  }
315
412
  const toolKind = update.kind || "unknown";
316
413
  let toolCallCountSincePrompt = ctx.toolCallCountSincePrompt;
414
+ const terminalMeta = readAcpTerminalMeta(update);
415
+ if (terminalMeta.outputDelta !== void 0 && ctx.activeToolCalls.has(toolCallId)) {
416
+ ctx.toolCallOutputs.set(
417
+ toolCallId,
418
+ appendTerminalOutput(ctx.toolCallOutputs.get(toolCallId) ?? "", terminalMeta.outputDelta)
419
+ );
420
+ }
317
421
  if (status === "in_progress" || status === "pending") {
318
422
  if (!ctx.activeToolCalls.has(toolCallId)) {
319
423
  toolCallCountSincePrompt++;
@@ -322,7 +426,7 @@ function handleToolCallUpdate(update, ctx) {
322
426
  logger.debug(`[AcpBackend] Tool call ${toolCallId} already tracked, status: ${status}`);
323
427
  }
324
428
  } else if (status === "completed") {
325
- completeToolCall(toolCallId, toolKind, update.content, ctx);
429
+ completeToolCall(toolCallId, toolKind, update.content, ctx, terminalMeta.exitCode);
326
430
  } else if (status === "failed" || status === "cancelled") {
327
431
  failToolCall(toolCallId, status, toolKind, update.content, ctx);
328
432
  }
@@ -509,6 +613,8 @@ class AcpBackend {
509
613
  permissionToToolCallMap = /* @__PURE__ */ new Map();
510
614
  /** Map from real tool call ID to tool name for auto-approval */
511
615
  toolCallIdToNameMap = /* @__PURE__ */ new Map();
616
+ /** Streamed bash output per tool call (pi-acp `_meta.terminal_output`) */
617
+ toolCallOutputs = /* @__PURE__ */ new Map();
512
618
  /** Track if we just sent a prompt with change_title instruction */
513
619
  recentPromptHadChangeTitle = false;
514
620
  /** Track tool calls count since last prompt (to identify first tool call) */
@@ -681,15 +787,11 @@ class AcpBackend {
681
787
  requestPermission: async (params) => {
682
788
  const extendedParams = params;
683
789
  const toolCall = extendedParams.toolCall;
684
- let toolName = toolCall?.kind || toolCall?.toolName || extendedParams.kind || "Unknown tool";
685
- const toolCallId = toolCall?.id || randomUUID();
790
+ const resolved = resolveAcpPermissionRequest(extendedParams, randomUUID);
791
+ let toolName = resolved.toolName;
792
+ const toolCallId = resolved.toolCallId;
686
793
  const permissionId = toolCallId;
687
- let input = {};
688
- if (toolCall) {
689
- input = toolCall.input || toolCall.arguments || toolCall.content || {};
690
- } else {
691
- input = extendedParams.input || extendedParams.arguments || extendedParams.content || {};
692
- }
794
+ const input = resolved.input;
693
795
  const context = {
694
796
  recentPromptHadChangeTitle: this.recentPromptHadChangeTitle,
695
797
  toolCallCountSincePrompt: this.toolCallCountSincePrompt
@@ -927,6 +1029,7 @@ class AcpBackend {
927
1029
  toolCallStartTimes: this.toolCallStartTimes,
928
1030
  toolCallTimeouts: this.toolCallTimeouts,
929
1031
  toolCallIdToNameMap: this.toolCallIdToNameMap,
1032
+ toolCallOutputs: this.toolCallOutputs,
930
1033
  idleTimeout: this.idleTimeout,
931
1034
  toolCallCountSincePrompt: this.toolCallCountSincePrompt,
932
1035
  emit: (msg) => this.emit(msg),
@@ -1310,6 +1413,7 @@ class AcpBackend {
1310
1413
  }
1311
1414
  this.toolCallTimeouts.clear();
1312
1415
  this.toolCallStartTimes.clear();
1416
+ this.toolCallOutputs.clear();
1313
1417
  this.pendingPermissions.clear();
1314
1418
  }
1315
1419
  }
@@ -3,7 +3,7 @@
3
3
  var node_child_process = require('node:child_process');
4
4
  var sdk = require('@agentclientprotocol/sdk');
5
5
  var node_crypto = require('node:crypto');
6
- var persistence = require('./types-C5kEpkcZ.cjs');
6
+ var persistence = require('./types-ClvvHves.cjs');
7
7
 
8
8
  const DEFAULT_TIMEOUTS = {
9
9
  /** Default initialization timeout: 60 seconds */
@@ -86,6 +86,97 @@ class DefaultTransport {
86
86
  }
87
87
  }
88
88
 
89
+ const ACP_RAW_INPUT_MAX_BYTES = 64 * 1024;
90
+ const ACP_TERMINAL_OUTPUT_MAX_BYTES = 64 * 1024;
91
+ const PI_TOOL_NAME_RE = /^[a-z][a-z0-9_-]{0,63}$/;
92
+ function deriveAcpToolArgs(update, options = {}) {
93
+ const args = {};
94
+ const title = typeof update.title === "string" ? update.title : void 0;
95
+ const kind = typeof update.kind === "string" ? update.kind : void 0;
96
+ if (title !== void 0) args.acpTitle = title;
97
+ if (kind !== void 0) args.acpKind = kind;
98
+ if (update.rawInput && typeof update.rawInput === "object" && !Array.isArray(update.rawInput)) {
99
+ const rawInput = update.rawInput;
100
+ if (serializedSize(rawInput) <= ACP_RAW_INPUT_MAX_BYTES) {
101
+ args.rawInput = rawInput;
102
+ } else {
103
+ args.rawInputTruncated = true;
104
+ }
105
+ }
106
+ if (options.agentName !== "pi") return args;
107
+ if (kind === "execute") {
108
+ args.piTool = "bash";
109
+ if (title !== void 0) args.command = title;
110
+ } else if (title !== void 0 && PI_TOOL_NAME_RE.test(title)) {
111
+ args.piTool = title;
112
+ }
113
+ return args;
114
+ }
115
+ function serializedSize(value) {
116
+ try {
117
+ return Buffer.byteLength(JSON.stringify(value) ?? "", "utf8");
118
+ } catch {
119
+ return Number.POSITIVE_INFINITY;
120
+ }
121
+ }
122
+ function resolveAcpPermissionRequest(params, newId) {
123
+ const toolCall = params.toolCall;
124
+ const toolName = toolCall?.kind || toolCall?.toolName || params.kind || "Unknown tool";
125
+ const toolCallId = toolCall?.id || newId();
126
+ let input;
127
+ if (toolCall) {
128
+ input = toolCall.input || toolCall.arguments || toolCall.rawInput || toolCall.content || {};
129
+ } else {
130
+ input = params.input || params.arguments || params.content || {};
131
+ }
132
+ input = { ...input, ...buildAcpPermissionMeta(toolCall) };
133
+ return { toolCallId, toolName, input };
134
+ }
135
+ function readAcpTerminalMeta(update) {
136
+ const meta = update._meta;
137
+ if (!meta || typeof meta !== "object") return {};
138
+ const record = meta;
139
+ const result = {};
140
+ const output = record.terminal_output;
141
+ if (output && typeof output === "object") {
142
+ const data = output.data;
143
+ if (typeof data === "string" && data.length > 0) result.outputDelta = data;
144
+ }
145
+ const exit = record.terminal_exit;
146
+ if (exit && typeof exit === "object") {
147
+ const code = exit.exit_code;
148
+ if (typeof code === "number" && Number.isFinite(code)) result.exitCode = code;
149
+ }
150
+ return result;
151
+ }
152
+ function appendTerminalOutput(previous, delta) {
153
+ const next = previous + delta;
154
+ if (Buffer.byteLength(next, "utf8") <= ACP_TERMINAL_OUTPUT_MAX_BYTES) return next;
155
+ const buf = Buffer.from(next, "utf8");
156
+ return buf.subarray(buf.length - ACP_TERMINAL_OUTPUT_MAX_BYTES).toString("utf8");
157
+ }
158
+ function buildAcpBashResult(output, exitCode) {
159
+ if (output === void 0 && exitCode === void 0) return void 0;
160
+ const text = output ?? "";
161
+ const truncated = Buffer.byteLength(text, "utf8") >= ACP_TERMINAL_OUTPUT_MAX_BYTES;
162
+ return {
163
+ text,
164
+ exitCode,
165
+ ...truncated ? { truncated: true } : {}
166
+ };
167
+ }
168
+ function buildAcpPermissionMeta(toolCall) {
169
+ if (!toolCall) return {};
170
+ const meta = {};
171
+ if (typeof toolCall.title === "string" && toolCall.title.length > 0) meta.acpTitle = toolCall.title;
172
+ if (typeof toolCall.kind === "string" && toolCall.kind.length > 0) meta.acpKind = toolCall.kind;
173
+ const raw = toolCall.rawInput;
174
+ if (raw && typeof raw === "object" && typeof raw.message === "string") {
175
+ meta.message = raw.message;
176
+ }
177
+ return meta;
178
+ }
179
+
89
180
  const DEFAULT_IDLE_TIMEOUT_MS = 500;
90
181
  const DEFAULT_TOOL_CALL_TIMEOUT_MS = 12e4;
91
182
  function parseArgsFromContent(content) {
@@ -209,6 +300,7 @@ function startToolCall(toolCallId, toolKind, update, ctx, source) {
209
300
  ctx.activeToolCalls.delete(toolCallId);
210
301
  ctx.toolCallStartTimes.delete(toolCallId);
211
302
  ctx.toolCallTimeouts.delete(toolCallId);
303
+ ctx.toolCallOutputs.delete(toolCallId);
212
304
  if (ctx.activeToolCalls.size === 0) {
213
305
  persistence.logger.debug("[AcpBackend] No more active tool calls after timeout, emitting idle status");
214
306
  ctx.emitIdleStatus();
@@ -225,6 +317,7 @@ function startToolCall(toolCallId, toolKind, update, ctx, source) {
225
317
  if (update.locations && Array.isArray(update.locations)) {
226
318
  args.locations = update.locations;
227
319
  }
320
+ Object.assign(args, deriveAcpToolArgs(update, { agentName: ctx.transport.agentName }));
228
321
  ctx.emit({
229
322
  type: "tool-call",
230
323
  toolName: toolKindStr || "unknown",
@@ -232,7 +325,7 @@ function startToolCall(toolCallId, toolKind, update, ctx, source) {
232
325
  callId: toolCallId
233
326
  });
234
327
  }
235
- function completeToolCall(toolCallId, toolKind, content, ctx) {
328
+ function completeToolCall(toolCallId, toolKind, content, ctx, exitCode) {
236
329
  const startTime = ctx.toolCallStartTimes.get(toolCallId);
237
330
  const duration = formatDuration(startTime);
238
331
  const toolKindStr = typeof toolKind === "string" ? toolKind : "unknown";
@@ -244,10 +337,13 @@ function completeToolCall(toolCallId, toolKind, content, ctx) {
244
337
  ctx.toolCallTimeouts.delete(toolCallId);
245
338
  }
246
339
  persistence.logger.debug(`[AcpBackend] Tool call COMPLETED: ${toolCallId} - Duration: ${duration}. Active tool calls: ${ctx.activeToolCalls.size}`);
340
+ const output = ctx.toolCallOutputs.get(toolCallId);
341
+ ctx.toolCallOutputs.delete(toolCallId);
342
+ const bashResult = buildAcpBashResult(output, exitCode);
247
343
  ctx.emit({
248
344
  type: "tool-result",
249
345
  toolName: toolKindStr,
250
- result: content,
346
+ result: bashResult ?? content,
251
347
  callId: toolCallId
252
348
  });
253
349
  if (ctx.activeToolCalls.size === 0) {
@@ -279,6 +375,7 @@ function failToolCall(toolCallId, status, toolKind, content, ctx) {
279
375
  }
280
376
  ctx.activeToolCalls.delete(toolCallId);
281
377
  ctx.toolCallStartTimes.delete(toolCallId);
378
+ ctx.toolCallOutputs.delete(toolCallId);
282
379
  const timeout = ctx.toolCallTimeouts.get(toolCallId);
283
380
  if (timeout) {
284
381
  clearTimeout(timeout);
@@ -316,6 +413,13 @@ function handleToolCallUpdate(update, ctx) {
316
413
  }
317
414
  const toolKind = update.kind || "unknown";
318
415
  let toolCallCountSincePrompt = ctx.toolCallCountSincePrompt;
416
+ const terminalMeta = readAcpTerminalMeta(update);
417
+ if (terminalMeta.outputDelta !== void 0 && ctx.activeToolCalls.has(toolCallId)) {
418
+ ctx.toolCallOutputs.set(
419
+ toolCallId,
420
+ appendTerminalOutput(ctx.toolCallOutputs.get(toolCallId) ?? "", terminalMeta.outputDelta)
421
+ );
422
+ }
319
423
  if (status === "in_progress" || status === "pending") {
320
424
  if (!ctx.activeToolCalls.has(toolCallId)) {
321
425
  toolCallCountSincePrompt++;
@@ -324,7 +428,7 @@ function handleToolCallUpdate(update, ctx) {
324
428
  persistence.logger.debug(`[AcpBackend] Tool call ${toolCallId} already tracked, status: ${status}`);
325
429
  }
326
430
  } else if (status === "completed") {
327
- completeToolCall(toolCallId, toolKind, update.content, ctx);
431
+ completeToolCall(toolCallId, toolKind, update.content, ctx, terminalMeta.exitCode);
328
432
  } else if (status === "failed" || status === "cancelled") {
329
433
  failToolCall(toolCallId, status, toolKind, update.content, ctx);
330
434
  }
@@ -511,6 +615,8 @@ class AcpBackend {
511
615
  permissionToToolCallMap = /* @__PURE__ */ new Map();
512
616
  /** Map from real tool call ID to tool name for auto-approval */
513
617
  toolCallIdToNameMap = /* @__PURE__ */ new Map();
618
+ /** Streamed bash output per tool call (pi-acp `_meta.terminal_output`) */
619
+ toolCallOutputs = /* @__PURE__ */ new Map();
514
620
  /** Track if we just sent a prompt with change_title instruction */
515
621
  recentPromptHadChangeTitle = false;
516
622
  /** Track tool calls count since last prompt (to identify first tool call) */
@@ -683,15 +789,11 @@ class AcpBackend {
683
789
  requestPermission: async (params) => {
684
790
  const extendedParams = params;
685
791
  const toolCall = extendedParams.toolCall;
686
- let toolName = toolCall?.kind || toolCall?.toolName || extendedParams.kind || "Unknown tool";
687
- const toolCallId = toolCall?.id || node_crypto.randomUUID();
792
+ const resolved = resolveAcpPermissionRequest(extendedParams, node_crypto.randomUUID);
793
+ let toolName = resolved.toolName;
794
+ const toolCallId = resolved.toolCallId;
688
795
  const permissionId = toolCallId;
689
- let input = {};
690
- if (toolCall) {
691
- input = toolCall.input || toolCall.arguments || toolCall.content || {};
692
- } else {
693
- input = extendedParams.input || extendedParams.arguments || extendedParams.content || {};
694
- }
796
+ const input = resolved.input;
695
797
  const context = {
696
798
  recentPromptHadChangeTitle: this.recentPromptHadChangeTitle,
697
799
  toolCallCountSincePrompt: this.toolCallCountSincePrompt
@@ -929,6 +1031,7 @@ class AcpBackend {
929
1031
  toolCallStartTimes: this.toolCallStartTimes,
930
1032
  toolCallTimeouts: this.toolCallTimeouts,
931
1033
  toolCallIdToNameMap: this.toolCallIdToNameMap,
1034
+ toolCallOutputs: this.toolCallOutputs,
932
1035
  idleTimeout: this.idleTimeout,
933
1036
  toolCallCountSincePrompt: this.toolCallCountSincePrompt,
934
1037
  emit: (msg) => this.emit(msg),
@@ -1312,6 +1415,7 @@ class AcpBackend {
1312
1415
  }
1313
1416
  this.toolCallTimeouts.clear();
1314
1417
  this.toolCallStartTimes.clear();
1418
+ this.toolCallOutputs.clear();
1315
1419
  this.pendingPermissions.clear();
1316
1420
  }
1317
1421
  }
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var cuid2 = require('@paralleldrive/cuid2');
4
- var persistence = require('./types-C5kEpkcZ.cjs');
4
+ var persistence = require('./types-ClvvHves.cjs');
5
5
 
6
6
  function turnOptions(turnId, time) {
7
7
  return turnId ? { turn: turnId, time } : { time };
@@ -12,6 +12,18 @@ function buildToolTitle(toolName) {
12
12
  function buildToolDescription(toolName) {
13
13
  return `Running ${toolName}`;
14
14
  }
15
+ function toolCallEndResult(result) {
16
+ if (!result || typeof result !== "object" || Array.isArray(result)) return void 0;
17
+ const record = result;
18
+ if (typeof record.text !== "string") return void 0;
19
+ const exitCode = typeof record.exitCode === "number" ? record.exitCode : void 0;
20
+ const text = exitCode !== void 0 && exitCode !== 0 ? `${record.text}${record.text.endsWith("\n") || record.text === "" ? "" : "\n"}[exit code ${exitCode}]` : record.text;
21
+ return {
22
+ text,
23
+ ...exitCode !== void 0 && exitCode !== 0 ? { isError: true } : {},
24
+ ...record.truncated === true ? { truncated: true } : {}
25
+ };
26
+ }
15
27
  function parseThinkingPayload(payload) {
16
28
  if (typeof payload === "string") {
17
29
  return { text: payload, streaming: false };
@@ -135,9 +147,10 @@ class AcpSessionManager {
135
147
  if (msg.type === "tool-result") {
136
148
  const flushed = this.flush();
137
149
  const call = this.ensureSessionCallId(msg.callId);
150
+ const result = toolCallEndResult(msg.result);
138
151
  return [
139
152
  ...flushed,
140
- persistence.createEnvelope("agent", { t: "tool-call-end", call }, turnOptions(this.currentTurnId, this.nextTime()))
153
+ persistence.createEnvelope("agent", { t: "tool-call-end", call, ...result ? { result } : {} }, turnOptions(this.currentTurnId, this.nextTime()))
141
154
  ];
142
155
  }
143
156
  return [];
@@ -1,5 +1,5 @@
1
1
  import { createId } from '@paralleldrive/cuid2';
2
- import { b as createEnvelope } from './types-Ds0SiQ1D.mjs';
2
+ import { b as createEnvelope } from './types-BtuOM9lw.mjs';
3
3
 
4
4
  function turnOptions(turnId, time) {
5
5
  return turnId ? { turn: turnId, time } : { time };
@@ -10,6 +10,18 @@ function buildToolTitle(toolName) {
10
10
  function buildToolDescription(toolName) {
11
11
  return `Running ${toolName}`;
12
12
  }
13
+ function toolCallEndResult(result) {
14
+ if (!result || typeof result !== "object" || Array.isArray(result)) return void 0;
15
+ const record = result;
16
+ if (typeof record.text !== "string") return void 0;
17
+ const exitCode = typeof record.exitCode === "number" ? record.exitCode : void 0;
18
+ const text = exitCode !== void 0 && exitCode !== 0 ? `${record.text}${record.text.endsWith("\n") || record.text === "" ? "" : "\n"}[exit code ${exitCode}]` : record.text;
19
+ return {
20
+ text,
21
+ ...exitCode !== void 0 && exitCode !== 0 ? { isError: true } : {},
22
+ ...record.truncated === true ? { truncated: true } : {}
23
+ };
24
+ }
13
25
  function parseThinkingPayload(payload) {
14
26
  if (typeof payload === "string") {
15
27
  return { text: payload, streaming: false };
@@ -133,9 +145,10 @@ class AcpSessionManager {
133
145
  if (msg.type === "tool-result") {
134
146
  const flushed = this.flush();
135
147
  const call = this.ensureSessionCallId(msg.callId);
148
+ const result = toolCallEndResult(msg.result);
136
149
  return [
137
150
  ...flushed,
138
- createEnvelope("agent", { t: "tool-call-end", call }, turnOptions(this.currentTurnId, this.nextTime()))
151
+ createEnvelope("agent", { t: "tool-call-end", call, ...result ? { result } : {} }, turnOptions(this.currentTurnId, this.nextTime()))
139
152
  ];
140
153
  }
141
154
  return [];
@@ -2,8 +2,8 @@ import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
2
2
  import { join } from 'path';
3
3
  import { homedir } from 'os';
4
4
  import { execSync } from 'child_process';
5
- import { l as logger } from './types-Ds0SiQ1D.mjs';
6
- import { g as DEFAULT_GEMINI_MODEL, G as GEMINI_MODEL_ENV } from './index-Dq-eFp89.mjs';
5
+ import { l as logger } from './types-BtuOM9lw.mjs';
6
+ import { j as DEFAULT_GEMINI_MODEL, G as GEMINI_MODEL_ENV } from './index-DIXjhnV1.mjs';
7
7
  import 'axios';
8
8
  import 'chalk';
9
9
  import 'node:util';
@@ -4,8 +4,8 @@ var fs = require('fs');
4
4
  var path = require('path');
5
5
  var os = require('os');
6
6
  var child_process = require('child_process');
7
- var persistence = require('./types-C5kEpkcZ.cjs');
8
- var index = require('./index-4jiUeiUz.cjs');
7
+ var persistence = require('./types-ClvvHves.cjs');
8
+ var index = require('./index-BXOXRblP.cjs');
9
9
  require('axios');
10
10
  require('chalk');
11
11
  require('node:util');