happy-imou-cloud 2.1.4 → 2.1.6

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 (28) hide show
  1. package/bin/happy-cloud.mjs +38 -38
  2. package/dist/{BaseReasoningProcessor-DgdsExMH.cjs → BaseReasoningProcessor-C3oDrA4i.cjs} +17 -4
  3. package/dist/{BaseReasoningProcessor-lTsZVuAU.mjs → BaseReasoningProcessor-CRXr7Axk.mjs} +16 -3
  4. package/dist/{ProviderSelectionHandler-CGTnB7ba.mjs → ProviderSelectionHandler-C3kHFqeq.mjs} +2 -2
  5. package/dist/{ProviderSelectionHandler-Bavm9TDG.cjs → ProviderSelectionHandler-Drg2Pp1-.cjs} +2 -2
  6. package/dist/{api-B6ESNpGB.cjs → api-CvtU4DI-.cjs} +2 -2
  7. package/dist/{api-l8X03rs-.mjs → api-DF9A136-.mjs} +3 -3
  8. package/dist/{command-DPLKOzMr.cjs → command-UZr1nodh.cjs} +3 -3
  9. package/dist/{command-BVCkEMtp.mjs → command-hO52qTzQ.mjs} +3 -3
  10. package/dist/{index-D72RMo5Z.mjs → index-B5e-MA1d.mjs} +268 -32
  11. package/dist/{index-D1BP-fEm.cjs → index-DA-K28E3.cjs} +264 -24
  12. package/dist/index.cjs +3 -3
  13. package/dist/index.mjs +3 -3
  14. package/dist/lib.cjs +1 -1
  15. package/dist/lib.d.cts +36 -36
  16. package/dist/lib.d.mts +36 -36
  17. package/dist/lib.mjs +1 -1
  18. package/dist/{persistence-CyFjFOlN.mjs → persistence-BsWBBi7E.mjs} +1 -1
  19. package/dist/{persistence-EDmI-c8T.cjs → persistence-CKgPuZRR.cjs} +1 -1
  20. package/dist/{registerKillSessionHandler-71xCO8e_.cjs → registerKillSessionHandler-3ytO-yBI.cjs} +72 -79
  21. package/dist/{registerKillSessionHandler-DAVhkb-l.mjs → registerKillSessionHandler-DmG1p8l7.mjs} +73 -78
  22. package/dist/{runClaude-BRhQLKjh.mjs → runClaude-MF34EsCp.mjs} +103 -40
  23. package/dist/{runClaude-DjnTGJGC.cjs → runClaude-bAlUdUGw.cjs} +106 -43
  24. package/dist/{runCodex-DUs_jBE-.mjs → runCodex-B31D_imZ.mjs} +10 -8
  25. package/dist/{runCodex-BHq7Rnq7.cjs → runCodex-CiIbJ1wa.cjs} +12 -10
  26. package/dist/{runGemini-pmvBZ6qU.mjs → runGemini-BJ7PxLyl.mjs} +5 -5
  27. package/dist/{runGemini-hkZeOnA_.cjs → runGemini-BZJR84o-.cjs} +7 -7
  28. package/package.json +2 -2
@@ -1,11 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-D1BP-fEm.cjs');
4
- var persistence = require('./persistence-EDmI-c8T.cjs');
5
- var os = require('node:os');
6
- var path = require('node:path');
7
- var api = require('./api-B6ESNpGB.cjs');
3
+ var index = require('./index-DA-K28E3.cjs');
4
+ var persistence = require('./persistence-CKgPuZRR.cjs');
8
5
  var node_crypto = require('node:crypto');
6
+ var api = require('./api-CvtU4DI-.cjs');
9
7
  var crypto = require('crypto');
10
8
  require('axios');
11
9
  require('node:events');
@@ -37,30 +35,6 @@ async function ensureManagedProviderMachine(opts) {
37
35
  return machineId;
38
36
  }
39
37
 
40
- function createSessionMetadata(opts) {
41
- const state = {
42
- controlledByUser: false
43
- };
44
- const metadata = {
45
- path: process.cwd(),
46
- host: os.hostname(),
47
- version: api.packageJson.version,
48
- os: os.platform(),
49
- machineId: opts.machineId,
50
- homeDir: os.homedir(),
51
- happyHomeDir: api.configuration.happyCloudHomeDir,
52
- happyLibDir: index.projectPath(),
53
- happyToolsDir: path.resolve(index.projectPath(), "tools", "unpacked"),
54
- startedFromDaemon: opts.startedBy === "daemon",
55
- hostPid: process.pid,
56
- startedBy: opts.startedBy || "terminal",
57
- lifecycleState: "running",
58
- lifecycleStateSince: Date.now(),
59
- flavor: opts.flavor
60
- };
61
- return { state, metadata };
62
- }
63
-
64
38
  async function launchRuntimeHandleWithFactoryResult(opts) {
65
39
  const shell = opts.shell ?? new index.RuntimeShell();
66
40
  let factoryResult;
@@ -116,6 +90,62 @@ function attachToolHappierMetaV2(value, meta) {
116
90
  };
117
91
  }
118
92
 
93
+ const DISPLAY_FRIENDLY_TOOL_FIELDS = ["stdout", "stderr", "output", "text", "message", "detail", "reason", "data"];
94
+ function isRecord(value) {
95
+ return !!value && typeof value === "object" && !Array.isArray(value);
96
+ }
97
+ function stripInternalToolMeta(value) {
98
+ if (!isRecord(value)) {
99
+ return value;
100
+ }
101
+ const {
102
+ _happier: _ignoredHappier,
103
+ _happy: _ignoredHappy,
104
+ ...rest
105
+ } = value;
106
+ return rest;
107
+ }
108
+ function extractNestedTextContent(value) {
109
+ if (typeof value === "string") {
110
+ return value.trim().length > 0 ? value : null;
111
+ }
112
+ if (Array.isArray(value)) {
113
+ const parts = value.map((item) => extractNestedTextContent(item)).filter((item) => typeof item === "string" && item.length > 0);
114
+ return parts.length > 0 ? parts.join("\n") : null;
115
+ }
116
+ if (!isRecord(value)) {
117
+ return null;
118
+ }
119
+ if (typeof value.text === "string" && value.text.trim().length > 0) {
120
+ return value.text;
121
+ }
122
+ if ("content" in value) {
123
+ return extractNestedTextContent(value.content);
124
+ }
125
+ return null;
126
+ }
127
+ function normalizeCodexToolInput(value) {
128
+ return stripInternalToolMeta(value);
129
+ }
130
+ function normalizeCodexToolOutput(value) {
131
+ const sanitized = stripInternalToolMeta(value);
132
+ if (!isRecord(sanitized)) {
133
+ return sanitized;
134
+ }
135
+ const hasDisplayFriendlyField = DISPLAY_FRIENDLY_TOOL_FIELDS.some((field) => field in sanitized);
136
+ if (hasDisplayFriendlyField || !("content" in sanitized)) {
137
+ return sanitized;
138
+ }
139
+ const flattenedText = extractNestedTextContent(sanitized.content);
140
+ if (!flattenedText) {
141
+ return sanitized;
142
+ }
143
+ const { content: _content, ...rest } = sanitized;
144
+ return {
145
+ ...rest,
146
+ text: flattenedText
147
+ };
148
+ }
119
149
  function getDefaultExecToolName(provider) {
120
150
  switch (provider) {
121
151
  case "claude":
@@ -146,6 +176,14 @@ function attachToolMeta(provider, rawToolName, value) {
146
176
  canonicalToolName
147
177
  });
148
178
  }
179
+ function prepareToolInput(provider, rawToolName, value) {
180
+ const enriched = attachToolMeta(provider, rawToolName, value);
181
+ return provider === "codex" ? normalizeCodexToolInput(enriched) : enriched;
182
+ }
183
+ function prepareToolOutput(provider, rawToolName, value) {
184
+ const enriched = attachToolMeta(provider, rawToolName, value);
185
+ return provider === "codex" ? normalizeCodexToolOutput(enriched) : enriched;
186
+ }
149
187
  function forwardAgentMessageToProviderSession(msg, options) {
150
188
  const createId = options.createId ?? node_crypto.randomUUID;
151
189
  const toolResultType = options.toolResultType ?? "tool-result";
@@ -155,7 +193,7 @@ function forwardAgentMessageToProviderSession(msg, options) {
155
193
  type: "tool-call",
156
194
  name: index.resolveCanonicalToolNameV2(msg.toolName),
157
195
  callId: msg.callId,
158
- input: attachToolMeta(options.provider, msg.toolName, msg.args),
196
+ input: prepareToolInput(options.provider, msg.toolName, msg.args),
159
197
  id: createId()
160
198
  });
161
199
  return true;
@@ -164,7 +202,7 @@ function forwardAgentMessageToProviderSession(msg, options) {
164
202
  options.send({
165
203
  type: toolResultType,
166
204
  callId: msg.callId,
167
- output: attachToolMeta(options.provider, msg.toolName, msg.result),
205
+ output: prepareToolOutput(options.provider, msg.toolName, msg.result),
168
206
  id: createId(),
169
207
  isError: inferToolResultError(msg.result)
170
208
  });
@@ -206,7 +244,7 @@ function forwardAgentMessageToProviderSession(msg, options) {
206
244
  type: "tool-call",
207
245
  name: index.resolveCanonicalToolNameV2(rawToolName),
208
246
  callId: call_id,
209
- input: attachToolMeta(options.provider, rawToolName, inputs),
247
+ input: prepareToolInput(options.provider, rawToolName, inputs),
210
248
  id: createId()
211
249
  });
212
250
  return true;
@@ -217,7 +255,7 @@ function forwardAgentMessageToProviderSession(msg, options) {
217
255
  type: "tool-call",
218
256
  name: index.resolveCanonicalToolNameV2(rawToolName),
219
257
  callId: msg.call_id,
220
- input: attachToolMeta(options.provider, rawToolName, {
258
+ input: prepareToolInput(options.provider, rawToolName, {
221
259
  auto_approved: msg.auto_approved,
222
260
  changes: msg.changes
223
261
  }),
@@ -230,7 +268,7 @@ function forwardAgentMessageToProviderSession(msg, options) {
230
268
  options.send({
231
269
  type: toolResultType,
232
270
  callId: msg.call_id,
233
- output: attachToolMeta(options.provider, rawToolName, {
271
+ output: prepareToolOutput(options.provider, rawToolName, {
234
272
  stdout: msg.stdout,
235
273
  stderr: msg.stderr,
236
274
  success: msg.success
@@ -254,49 +292,6 @@ function forwardAgentMessageToProviderSession(msg, options) {
254
292
  }
255
293
  }
256
294
 
257
- async function closeProviderSession(session, opts = {}) {
258
- let firstError;
259
- const captureError = (error) => {
260
- if (firstError === void 0) {
261
- firstError = error;
262
- }
263
- };
264
- if (opts.archiveOnClose || opts.archiveReason) {
265
- try {
266
- session.updateMetadata((currentMetadata) => {
267
- const { archiveReason: _existingArchiveReason, ...metadataWithoutArchiveReason } = currentMetadata;
268
- return {
269
- ...metadataWithoutArchiveReason,
270
- lifecycleState: "archived",
271
- lifecycleStateSince: Date.now(),
272
- archivedBy: opts.archivedBy ?? "cli",
273
- ...opts.archiveReason ? { archiveReason: opts.archiveReason } : {}
274
- };
275
- });
276
- } catch (error) {
277
- captureError(error);
278
- }
279
- }
280
- try {
281
- session.sendSessionDeath();
282
- } catch (error) {
283
- captureError(error);
284
- }
285
- try {
286
- await session.flush();
287
- } catch (error) {
288
- captureError(error);
289
- }
290
- try {
291
- await session.close();
292
- } catch (error) {
293
- captureError(error);
294
- }
295
- if (firstError !== void 0) {
296
- throw firstError;
297
- }
298
- }
299
-
300
295
  function createAbortError() {
301
296
  const error = new Error("Operation aborted");
302
297
  error.name = "AbortError";
@@ -1602,8 +1597,6 @@ exports.MessageBuffer = MessageBuffer;
1602
1597
  exports.MessageQueue2 = MessageQueue2;
1603
1598
  exports.MissingMachineIdError = MissingMachineIdError;
1604
1599
  exports.buildHappyOrgTurnPrompt = buildHappyOrgTurnPrompt;
1605
- exports.closeProviderSession = closeProviderSession;
1606
- exports.createSessionMetadata = createSessionMetadata;
1607
1600
  exports.ensureManagedProviderMachine = ensureManagedProviderMachine;
1608
1601
  exports.finalizeHappyOrgTurn = finalizeHappyOrgTurn;
1609
1602
  exports.forwardAgentMessageToProviderSession = forwardAgentMessageToProviderSession;
@@ -1,9 +1,7 @@
1
- import { i as initialMachineMetadata, e as projectPath, R as RuntimeShell, h as resolveCanonicalToolNameV2, f as formatDisplayMessage } from './index-D72RMo5Z.mjs';
2
- import { readSettings } from './persistence-CyFjFOlN.mjs';
3
- import os from 'node:os';
4
- import { resolve } from 'node:path';
5
- import { c as configuration, p as packageJson, H as HAPPY_ORG_TURN_REPORT_TAG, d as HAPPY_ORG_SUMMARY_MAX_LENGTH, f as HAPPY_ORG_REPEAT_THRESHOLD, l as logger } from './api-l8X03rs-.mjs';
1
+ import { k as initialMachineMetadata, R as RuntimeShell, l as resolveCanonicalToolNameV2, f as formatDisplayMessage } from './index-B5e-MA1d.mjs';
2
+ import { readSettings } from './persistence-BsWBBi7E.mjs';
6
3
  import { randomUUID } from 'node:crypto';
4
+ import { H as HAPPY_ORG_TURN_REPORT_TAG, d as HAPPY_ORG_SUMMARY_MAX_LENGTH, f as HAPPY_ORG_REPEAT_THRESHOLD, l as logger } from './api-DF9A136-.mjs';
7
5
  import { createHash } from 'crypto';
8
6
  import 'axios';
9
7
  import 'node:events';
@@ -35,30 +33,6 @@ async function ensureManagedProviderMachine(opts) {
35
33
  return machineId;
36
34
  }
37
35
 
38
- function createSessionMetadata(opts) {
39
- const state = {
40
- controlledByUser: false
41
- };
42
- const metadata = {
43
- path: process.cwd(),
44
- host: os.hostname(),
45
- version: packageJson.version,
46
- os: os.platform(),
47
- machineId: opts.machineId,
48
- homeDir: os.homedir(),
49
- happyHomeDir: configuration.happyCloudHomeDir,
50
- happyLibDir: projectPath(),
51
- happyToolsDir: resolve(projectPath(), "tools", "unpacked"),
52
- startedFromDaemon: opts.startedBy === "daemon",
53
- hostPid: process.pid,
54
- startedBy: opts.startedBy || "terminal",
55
- lifecycleState: "running",
56
- lifecycleStateSince: Date.now(),
57
- flavor: opts.flavor
58
- };
59
- return { state, metadata };
60
- }
61
-
62
36
  async function launchRuntimeHandleWithFactoryResult(opts) {
63
37
  const shell = opts.shell ?? new RuntimeShell();
64
38
  let factoryResult;
@@ -114,6 +88,62 @@ function attachToolHappierMetaV2(value, meta) {
114
88
  };
115
89
  }
116
90
 
91
+ const DISPLAY_FRIENDLY_TOOL_FIELDS = ["stdout", "stderr", "output", "text", "message", "detail", "reason", "data"];
92
+ function isRecord(value) {
93
+ return !!value && typeof value === "object" && !Array.isArray(value);
94
+ }
95
+ function stripInternalToolMeta(value) {
96
+ if (!isRecord(value)) {
97
+ return value;
98
+ }
99
+ const {
100
+ _happier: _ignoredHappier,
101
+ _happy: _ignoredHappy,
102
+ ...rest
103
+ } = value;
104
+ return rest;
105
+ }
106
+ function extractNestedTextContent(value) {
107
+ if (typeof value === "string") {
108
+ return value.trim().length > 0 ? value : null;
109
+ }
110
+ if (Array.isArray(value)) {
111
+ const parts = value.map((item) => extractNestedTextContent(item)).filter((item) => typeof item === "string" && item.length > 0);
112
+ return parts.length > 0 ? parts.join("\n") : null;
113
+ }
114
+ if (!isRecord(value)) {
115
+ return null;
116
+ }
117
+ if (typeof value.text === "string" && value.text.trim().length > 0) {
118
+ return value.text;
119
+ }
120
+ if ("content" in value) {
121
+ return extractNestedTextContent(value.content);
122
+ }
123
+ return null;
124
+ }
125
+ function normalizeCodexToolInput(value) {
126
+ return stripInternalToolMeta(value);
127
+ }
128
+ function normalizeCodexToolOutput(value) {
129
+ const sanitized = stripInternalToolMeta(value);
130
+ if (!isRecord(sanitized)) {
131
+ return sanitized;
132
+ }
133
+ const hasDisplayFriendlyField = DISPLAY_FRIENDLY_TOOL_FIELDS.some((field) => field in sanitized);
134
+ if (hasDisplayFriendlyField || !("content" in sanitized)) {
135
+ return sanitized;
136
+ }
137
+ const flattenedText = extractNestedTextContent(sanitized.content);
138
+ if (!flattenedText) {
139
+ return sanitized;
140
+ }
141
+ const { content: _content, ...rest } = sanitized;
142
+ return {
143
+ ...rest,
144
+ text: flattenedText
145
+ };
146
+ }
117
147
  function getDefaultExecToolName(provider) {
118
148
  switch (provider) {
119
149
  case "claude":
@@ -144,6 +174,14 @@ function attachToolMeta(provider, rawToolName, value) {
144
174
  canonicalToolName
145
175
  });
146
176
  }
177
+ function prepareToolInput(provider, rawToolName, value) {
178
+ const enriched = attachToolMeta(provider, rawToolName, value);
179
+ return provider === "codex" ? normalizeCodexToolInput(enriched) : enriched;
180
+ }
181
+ function prepareToolOutput(provider, rawToolName, value) {
182
+ const enriched = attachToolMeta(provider, rawToolName, value);
183
+ return provider === "codex" ? normalizeCodexToolOutput(enriched) : enriched;
184
+ }
147
185
  function forwardAgentMessageToProviderSession(msg, options) {
148
186
  const createId = options.createId ?? randomUUID;
149
187
  const toolResultType = options.toolResultType ?? "tool-result";
@@ -153,7 +191,7 @@ function forwardAgentMessageToProviderSession(msg, options) {
153
191
  type: "tool-call",
154
192
  name: resolveCanonicalToolNameV2(msg.toolName),
155
193
  callId: msg.callId,
156
- input: attachToolMeta(options.provider, msg.toolName, msg.args),
194
+ input: prepareToolInput(options.provider, msg.toolName, msg.args),
157
195
  id: createId()
158
196
  });
159
197
  return true;
@@ -162,7 +200,7 @@ function forwardAgentMessageToProviderSession(msg, options) {
162
200
  options.send({
163
201
  type: toolResultType,
164
202
  callId: msg.callId,
165
- output: attachToolMeta(options.provider, msg.toolName, msg.result),
203
+ output: prepareToolOutput(options.provider, msg.toolName, msg.result),
166
204
  id: createId(),
167
205
  isError: inferToolResultError(msg.result)
168
206
  });
@@ -204,7 +242,7 @@ function forwardAgentMessageToProviderSession(msg, options) {
204
242
  type: "tool-call",
205
243
  name: resolveCanonicalToolNameV2(rawToolName),
206
244
  callId: call_id,
207
- input: attachToolMeta(options.provider, rawToolName, inputs),
245
+ input: prepareToolInput(options.provider, rawToolName, inputs),
208
246
  id: createId()
209
247
  });
210
248
  return true;
@@ -215,7 +253,7 @@ function forwardAgentMessageToProviderSession(msg, options) {
215
253
  type: "tool-call",
216
254
  name: resolveCanonicalToolNameV2(rawToolName),
217
255
  callId: msg.call_id,
218
- input: attachToolMeta(options.provider, rawToolName, {
256
+ input: prepareToolInput(options.provider, rawToolName, {
219
257
  auto_approved: msg.auto_approved,
220
258
  changes: msg.changes
221
259
  }),
@@ -228,7 +266,7 @@ function forwardAgentMessageToProviderSession(msg, options) {
228
266
  options.send({
229
267
  type: toolResultType,
230
268
  callId: msg.call_id,
231
- output: attachToolMeta(options.provider, rawToolName, {
269
+ output: prepareToolOutput(options.provider, rawToolName, {
232
270
  stdout: msg.stdout,
233
271
  stderr: msg.stderr,
234
272
  success: msg.success
@@ -252,49 +290,6 @@ function forwardAgentMessageToProviderSession(msg, options) {
252
290
  }
253
291
  }
254
292
 
255
- async function closeProviderSession(session, opts = {}) {
256
- let firstError;
257
- const captureError = (error) => {
258
- if (firstError === void 0) {
259
- firstError = error;
260
- }
261
- };
262
- if (opts.archiveOnClose || opts.archiveReason) {
263
- try {
264
- session.updateMetadata((currentMetadata) => {
265
- const { archiveReason: _existingArchiveReason, ...metadataWithoutArchiveReason } = currentMetadata;
266
- return {
267
- ...metadataWithoutArchiveReason,
268
- lifecycleState: "archived",
269
- lifecycleStateSince: Date.now(),
270
- archivedBy: opts.archivedBy ?? "cli",
271
- ...opts.archiveReason ? { archiveReason: opts.archiveReason } : {}
272
- };
273
- });
274
- } catch (error) {
275
- captureError(error);
276
- }
277
- }
278
- try {
279
- session.sendSessionDeath();
280
- } catch (error) {
281
- captureError(error);
282
- }
283
- try {
284
- await session.flush();
285
- } catch (error) {
286
- captureError(error);
287
- }
288
- try {
289
- await session.close();
290
- } catch (error) {
291
- captureError(error);
292
- }
293
- if (firstError !== void 0) {
294
- throw firstError;
295
- }
296
- }
297
-
298
293
  function createAbortError() {
299
294
  const error = new Error("Operation aborted");
300
295
  error.name = "AbortError";
@@ -1592,4 +1587,4 @@ function registerKillSessionHandler(rpcHandlerManager, killThisHappy) {
1592
1587
  });
1593
1588
  }
1594
1589
 
1595
- export { BasePermissionHandler as B, ConversationHistory$1 as C, INTERACTION_SUPERSEDED_ERROR as I, MissingMachineIdError as M, INTERACTION_TIMED_OUT_ERROR as a, MessageQueue2 as b, createSessionMetadata as c, registerKillSessionHandler as d, ensureManagedProviderMachine as e, MessageBuffer as f, getPendingInteractionTimeoutMs as g, hashObject as h, buildHappyOrgTurnPrompt as i, finalizeHappyOrgTurn as j, closeProviderSession as k, launchRuntimeHandleWithFactoryResult as l, inferToolResultError as m, forwardAgentMessageToProviderSession as n, resolveHappyOrgQueuedTurn as r, syncControlledByUserState as s, waitForResponseCompleteWithAbort as w };
1590
+ export { BasePermissionHandler as B, ConversationHistory$1 as C, INTERACTION_SUPERSEDED_ERROR as I, MissingMachineIdError as M, INTERACTION_TIMED_OUT_ERROR as a, MessageQueue2 as b, registerKillSessionHandler as c, MessageBuffer as d, ensureManagedProviderMachine as e, buildHappyOrgTurnPrompt as f, getPendingInteractionTimeoutMs as g, hashObject as h, finalizeHappyOrgTurn as i, inferToolResultError as j, forwardAgentMessageToProviderSession as k, launchRuntimeHandleWithFactoryResult as l, resolveHappyOrgQueuedTurn as r, syncControlledByUserState as s, waitForResponseCompleteWithAbort as w };
@@ -1,8 +1,8 @@
1
1
  import { randomUUID } from 'node:crypto';
2
- import { l as logger, g as backoff, h as delay, j as AsyncLock, c as configuration, s as startOfflineReconnection, b as connectionState, A as ApiClient, i as isAuthenticationRequiredError } from './api-l8X03rs-.mjs';
2
+ import { l as logger, g as backoff, h as delay, j as AsyncLock, c as configuration, s as startOfflineReconnection, b as connectionState, A as ApiClient, i as isAuthenticationRequiredError } from './api-DF9A136-.mjs';
3
3
  import 'cross-spawn';
4
4
  import '@agentclientprotocol/sdk';
5
- import { j as getProjectPath, F as Future, k as claudeLocal, E as ExitCodeError, l as trimIdent, m as createClaudeBackend, f as formatDisplayMessage, t as truncateDisplayMessage, n as claudeCheckSession, e as projectPath, o as mapToClaudeMode, P as PushableAsyncIterable, q as query, A as AbortError, b as stopCaffeinate, p as publishSessionRegistration, u as getEnvironmentInfo, w as startCaffeinate } from './index-D72RMo5Z.mjs';
5
+ import { m as getProjectPath, F as Future, n as claudeLocal, E as ExitCodeError, o as trimIdent, q as createClaudeBackend, f as formatDisplayMessage, t as truncateDisplayMessage, u as claudeCheckSession, w as projectPath, x as mapToClaudeMode, P as PushableAsyncIterable, y as query, A as AbortError, e as stopCaffeinate, p as publishSessionRegistration, z as getEnvironmentInfo, a as createSessionMetadata, B as startCaffeinate, b as closeProviderSession } from './index-B5e-MA1d.mjs';
6
6
  import 'ps-list';
7
7
  import 'fs';
8
8
  import 'path';
@@ -13,7 +13,7 @@ import { dirname, basename, join, resolve } from 'node:path';
13
13
  import { homedir } from 'node:os';
14
14
  import { execSync } from 'node:child_process';
15
15
  import 'node:readline';
16
- import './persistence-CyFjFOlN.mjs';
16
+ import './persistence-BsWBBi7E.mjs';
17
17
  import { readFile } from 'node:fs/promises';
18
18
  import { stat, watch, access } from 'fs/promises';
19
19
  import 'crypto';
@@ -24,9 +24,9 @@ import 'tweetnacl';
24
24
  import 'open';
25
25
  import React, { useState, useRef, useEffect, useCallback } from 'react';
26
26
  import { useStdout, useInput, Box, Text, render } from 'ink';
27
- import { c as createKeepAliveController, P as ProviderSelectionHandler, r as runModeLoop } from './ProviderSelectionHandler-CGTnB7ba.mjs';
27
+ import { c as createKeepAliveController, P as ProviderSelectionHandler, r as runModeLoop } from './ProviderSelectionHandler-C3kHFqeq.mjs';
28
28
  import { R as RawJSONLinesSchema } from './types-CiliQpqS.mjs';
29
- import { B as BasePermissionHandler, f as MessageBuffer, C as ConversationHistory$1, i as buildHappyOrgTurnPrompt, w as waitForResponseCompleteWithAbort, j as finalizeHappyOrgTurn, l as launchRuntimeHandleWithFactoryResult, n as forwardAgentMessageToProviderSession, s as syncControlledByUserState, r as resolveHappyOrgQueuedTurn, e as ensureManagedProviderMachine, M as MissingMachineIdError, c as createSessionMetadata, b as MessageQueue2, h as hashObject, d as registerKillSessionHandler, k as closeProviderSession } from './registerKillSessionHandler-DAVhkb-l.mjs';
29
+ import { B as BasePermissionHandler, d as MessageBuffer, C as ConversationHistory$1, f as buildHappyOrgTurnPrompt, w as waitForResponseCompleteWithAbort, i as finalizeHappyOrgTurn, l as launchRuntimeHandleWithFactoryResult, k as forwardAgentMessageToProviderSession, s as syncControlledByUserState, r as resolveHappyOrgQueuedTurn, e as ensureManagedProviderMachine, M as MissingMachineIdError, b as MessageQueue2, h as hashObject, c as registerKillSessionHandler } from './registerKillSessionHandler-DmG1p8l7.mjs';
30
30
  import 'socket.io-client';
31
31
  import 'expo-server-sdk';
32
32
  import { isDeepStrictEqual } from 'node:util';
@@ -1401,6 +1401,7 @@ ${systemPrompt}` : systemPrompt,
1401
1401
  permissionHandler.setPermissionMode(message.mode.permissionMode);
1402
1402
  messageBuffer.addMessage(message.message, "user");
1403
1403
  let shouldClearHistoryAfterTurn = false;
1404
+ let shouldCommitAccumulatedResponse = false;
1404
1405
  let turnStatus = "task_complete";
1405
1406
  try {
1406
1407
  turnInFlight = true;
@@ -1422,18 +1423,19 @@ ${systemPrompt}` : systemPrompt,
1422
1423
  conversationHistory.addUserMessage(message.message);
1423
1424
  await activeRuntimeHandle.sendPrompt(promptToSend);
1424
1425
  await waitForResponseCompleteWithAbort(activeRuntimeHandle.backend, abortController.signal);
1426
+ shouldCommitAccumulatedResponse = true;
1425
1427
  shouldInjectHistoryOnNextSession = false;
1426
1428
  shouldClearHistoryAfterTurn = specialCommand.type === "compact";
1427
1429
  } catch (error) {
1428
1430
  logger.warn("[ClaudeACP] Error in Claude ACP session:", error);
1429
1431
  const isAbortError = error instanceof Error && error.name === "AbortError";
1430
1432
  const isExpectedInterruption = isAbortError || abortController.signal.aborted || shouldExit;
1433
+ turnStatus = "turn_aborted";
1434
+ session.client.sendAgentMessage("claude", {
1435
+ type: "turn_aborted",
1436
+ id: randomUUID()
1437
+ });
1431
1438
  if (isExpectedInterruption) {
1432
- turnStatus = "turn_aborted";
1433
- session.client.sendAgentMessage("claude", {
1434
- type: "turn_aborted",
1435
- id: randomUUID()
1436
- });
1437
1439
  emitStatusMessage("Aborted by user");
1438
1440
  } else {
1439
1441
  const errorMessage = normalizeClaudeBackendError(error);
@@ -1463,7 +1465,9 @@ ${systemPrompt}` : systemPrompt,
1463
1465
  emitStatusMessage(finalizedTurn.terminateMessage);
1464
1466
  }
1465
1467
  accumulatedResponse = finalizedTurn.cleanedText;
1466
- emitFinalAssistantMessage(finalizedTurn.cleanedText);
1468
+ if (shouldCommitAccumulatedResponse) {
1469
+ emitFinalAssistantMessage(finalizedTurn.cleanedText);
1470
+ }
1467
1471
  if (shouldClearHistoryAfterTurn) {
1468
1472
  conversationHistory.clear();
1469
1473
  emitStatusMessage("Compaction completed");
@@ -1732,6 +1736,7 @@ class PermissionHandler {
1732
1736
  toolCalls = [];
1733
1737
  responses = /* @__PURE__ */ new Map();
1734
1738
  pendingRequests = /* @__PURE__ */ new Map();
1739
+ pendingToolCallResolutions = /* @__PURE__ */ new Set();
1735
1740
  session;
1736
1741
  allowedTools = /* @__PURE__ */ new Set();
1737
1742
  allowedBashLiterals = /* @__PURE__ */ new Set();
@@ -1811,23 +1816,20 @@ class PermissionHandler {
1811
1816
  if (this.permissionMode === "acceptEdits" && descriptor.edit) {
1812
1817
  return { behavior: "allow", updatedInput: input };
1813
1818
  }
1814
- let toolCallId = this.resolveToolCallId(toolName, input);
1815
- if (!toolCallId) {
1816
- await delay(1e3);
1817
- toolCallId = this.resolveToolCallId(toolName, input);
1818
- if (!toolCallId) {
1819
- throw new Error(`Could not resolve tool call ID for ${toolName}`);
1820
- }
1821
- }
1819
+ const toolCallId = await this.waitForToolCallId(toolName, input, options.signal);
1822
1820
  return this.handlePermissionRequest(toolCallId, toolName, input, options.signal);
1823
1821
  };
1824
1822
  /**
1825
1823
  * Handles individual permission requests
1826
1824
  */
1827
1825
  async handlePermissionRequest(id, toolName, input, signal) {
1826
+ if (signal.aborted) {
1827
+ throw new Error("Permission request aborted");
1828
+ }
1828
1829
  return new Promise((resolve, reject) => {
1829
1830
  const abortHandler = () => {
1830
1831
  this.pendingRequests.delete(id);
1832
+ this.moveRequestToCompleted(id, "canceled", "Permission request aborted");
1831
1833
  reject(new Error("Permission request aborted"));
1832
1834
  };
1833
1835
  signal.addEventListener("abort", abortHandler, { once: true });
@@ -1870,6 +1872,31 @@ class PermissionHandler {
1870
1872
  logger.debug(`Permission request sent for tool call ${id}: ${toolName}`);
1871
1873
  });
1872
1874
  }
1875
+ moveRequestToCompleted(id, status, reason, extra = {}) {
1876
+ this.session.client.updateAgentState((currentState) => {
1877
+ const request = currentState.requests?.[id];
1878
+ if (!request) {
1879
+ return currentState;
1880
+ }
1881
+ const requests = { ...currentState.requests || {} };
1882
+ delete requests[id];
1883
+ return {
1884
+ ...currentState,
1885
+ requests,
1886
+ completedRequests: {
1887
+ ...currentState.completedRequests,
1888
+ [id]: {
1889
+ ...request,
1890
+ completedAt: Date.now(),
1891
+ status,
1892
+ reason,
1893
+ mode: extra.mode,
1894
+ allowTools: extra.allowTools
1895
+ }
1896
+ }
1897
+ };
1898
+ });
1899
+ }
1873
1900
  /**
1874
1901
  * Parses Bash permission strings into literal and prefix sets
1875
1902
  */
@@ -1906,6 +1933,49 @@ class PermissionHandler {
1906
1933
  }
1907
1934
  return null;
1908
1935
  }
1936
+ async waitForToolCallId(toolName, input, signal) {
1937
+ const existingToolCallId = this.resolveToolCallId(toolName, input);
1938
+ if (existingToolCallId) {
1939
+ return existingToolCallId;
1940
+ }
1941
+ if (signal.aborted) {
1942
+ throw new Error("Permission request aborted before tool call was observed");
1943
+ }
1944
+ return new Promise((resolve, reject) => {
1945
+ const pendingResolution = {};
1946
+ const cleanup = () => {
1947
+ signal.removeEventListener("abort", pendingResolution.abortHandler);
1948
+ this.pendingToolCallResolutions.delete(pendingResolution);
1949
+ };
1950
+ pendingResolution.toolName = toolName;
1951
+ pendingResolution.input = input;
1952
+ pendingResolution.resolve = (toolCallId) => {
1953
+ cleanup();
1954
+ resolve(toolCallId);
1955
+ };
1956
+ pendingResolution.reject = (error) => {
1957
+ cleanup();
1958
+ reject(error);
1959
+ };
1960
+ pendingResolution.abortHandler = () => {
1961
+ pendingResolution.reject(new Error("Permission request aborted before tool call was observed"));
1962
+ };
1963
+ this.pendingToolCallResolutions.add(pendingResolution);
1964
+ signal.addEventListener("abort", pendingResolution.abortHandler, { once: true });
1965
+ this.resolvePendingToolCallResolutions();
1966
+ });
1967
+ }
1968
+ resolvePendingToolCallResolutions() {
1969
+ if (this.pendingToolCallResolutions.size === 0) {
1970
+ return;
1971
+ }
1972
+ for (const pending of Array.from(this.pendingToolCallResolutions)) {
1973
+ const toolCallId = this.resolveToolCallId(pending.toolName, pending.input);
1974
+ if (toolCallId) {
1975
+ pending.resolve(toolCallId);
1976
+ }
1977
+ }
1978
+ }
1909
1979
  /**
1910
1980
  * Handles messages to track tool calls
1911
1981
  */
@@ -1923,6 +1993,7 @@ class PermissionHandler {
1923
1993
  });
1924
1994
  }
1925
1995
  }
1996
+ this.resolvePendingToolCallResolutions();
1926
1997
  }
1927
1998
  }
1928
1999
  if (message.type === "user") {
@@ -1961,6 +2032,10 @@ class PermissionHandler {
1961
2032
  this.allowedTools.clear();
1962
2033
  this.allowedBashLiterals.clear();
1963
2034
  this.allowedBashPrefixes.clear();
2035
+ for (const pendingResolution of Array.from(this.pendingToolCallResolutions)) {
2036
+ pendingResolution.reject(new Error("Session reset"));
2037
+ }
2038
+ this.pendingToolCallResolutions.clear();
1964
2039
  for (const [, pending] of this.pendingRequests.entries()) {
1965
2040
  pending.reject(new Error("Session reset"));
1966
2041
  }
@@ -1999,27 +2074,15 @@ class PermissionHandler {
1999
2074
  this.responses.set(id, { ...message, receivedAt: Date.now() });
2000
2075
  this.pendingRequests.delete(id);
2001
2076
  this.handlePermissionResponse(message, pending);
2002
- this.session.client.updateAgentState((currentState) => {
2003
- const request = currentState.requests?.[id];
2004
- if (!request) return currentState;
2005
- let r = { ...currentState.requests };
2006
- delete r[id];
2007
- return {
2008
- ...currentState,
2009
- requests: r,
2010
- completedRequests: {
2011
- ...currentState.completedRequests,
2012
- [id]: {
2013
- ...request,
2014
- completedAt: Date.now(),
2015
- status: message.approved ? "approved" : "denied",
2016
- reason: message.reason,
2017
- mode: message.mode,
2018
- allowTools: message.allowTools
2019
- }
2020
- }
2021
- };
2022
- });
2077
+ this.moveRequestToCompleted(
2078
+ id,
2079
+ message.approved ? "approved" : "denied",
2080
+ message.reason,
2081
+ {
2082
+ mode: message.mode,
2083
+ allowTools: message.allowTools
2084
+ }
2085
+ );
2023
2086
  });
2024
2087
  }
2025
2088
  /**