happy-imou-cloud 2.0.3 → 2.0.4

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 (23) hide show
  1. package/dist/{BaseReasoningProcessor-_wxlqKB8.cjs → BaseReasoningProcessor-DEEfNi5Y.cjs} +2 -2
  2. package/dist/{BaseReasoningProcessor-B37yOHxo.mjs → BaseReasoningProcessor-Di1yEMMv.mjs} +2 -2
  3. package/dist/{api-DpQIC-DJ.mjs → api-CIHTNilH.mjs} +2 -2
  4. package/dist/{api-D9dIR956.cjs → api-CyJG1mr6.cjs} +2 -2
  5. package/dist/{command-DRqrBuHM.mjs → command-BERqmFB0.mjs} +3 -3
  6. package/dist/{command-CdXv1zNF.cjs → command-CPlJKXDn.cjs} +3 -3
  7. package/dist/{index-LYPXVO_L.cjs → index-1zlH6s7a.cjs} +228 -33
  8. package/dist/{index-CriPm_z9.mjs → index-vNYxNqVZ.mjs} +226 -31
  9. package/dist/index.cjs +3 -3
  10. package/dist/index.mjs +3 -3
  11. package/dist/lib.cjs +1 -1
  12. package/dist/lib.mjs +1 -1
  13. package/dist/{persistence-PzKU0QCa.cjs → persistence-BeFVx6kI.cjs} +1 -1
  14. package/dist/{persistence-CqgPgbzN.mjs → persistence-sLEqV8vk.mjs} +1 -1
  15. package/dist/{registerKillSessionHandler-BDBPoQSA.cjs → registerKillSessionHandler-CCxqGFjZ.cjs} +2 -2
  16. package/dist/{registerKillSessionHandler-C3M_-4Zg.mjs → registerKillSessionHandler-uVHqIC4h.mjs} +2 -2
  17. package/dist/{runClaude-D6Pdkevn.mjs → runClaude-Dl9nIRIg.mjs} +4 -4
  18. package/dist/{runClaude-IeRSC5qX.cjs → runClaude-Dz-PCSvb.cjs} +5 -5
  19. package/dist/{runCodex-WRmgSK6L.cjs → runCodex-BtZplK1R.cjs} +65 -13
  20. package/dist/{runCodex-CsfUU1Wb.mjs → runCodex-DgKKw3IU.mjs} +63 -14
  21. package/dist/{runGemini-CrH3dQ0Y.mjs → runGemini-CM1v3I24.mjs} +10 -8
  22. package/dist/{runGemini-qBh6zs5G.cjs → runGemini-DUyH311Z.cjs} +10 -8
  23. package/package.json +1 -1
@@ -2,8 +2,8 @@
2
2
 
3
3
  var os = require('node:os');
4
4
  var node_path = require('node:path');
5
- var api = require('./api-D9dIR956.cjs');
6
- var index = require('./index-LYPXVO_L.cjs');
5
+ var api = require('./api-CyJG1mr6.cjs');
6
+ var index = require('./index-1zlH6s7a.cjs');
7
7
  var node_events = require('node:events');
8
8
  var node_crypto = require('node:crypto');
9
9
 
@@ -1,7 +1,7 @@
1
1
  import os from 'node:os';
2
2
  import { resolve } from 'node:path';
3
- import { c as configuration, p as packageJson, s as startOfflineReconnection, l as logger } from './api-DpQIC-DJ.mjs';
4
- import { p as projectPath } from './index-CriPm_z9.mjs';
3
+ import { c as configuration, p as packageJson, s as startOfflineReconnection, l as logger } from './api-CIHTNilH.mjs';
4
+ import { p as projectPath } from './index-vNYxNqVZ.mjs';
5
5
  import { EventEmitter } from 'node:events';
6
6
  import { randomUUID } from 'node:crypto';
7
7
 
@@ -17,7 +17,7 @@ import { resolve, join as join$1 } from 'path';
17
17
  import { Expo } from 'expo-server-sdk';
18
18
 
19
19
  var name = "happy-imou-cloud";
20
- var version = "2.0.3";
20
+ var version = "2.0.4";
21
21
  var description = "hicloud - Imou 企业定制版。关键是 happy!移动端远程 AI 编程工具,支持 Claude Code、Codex 和 Gemini CLI";
22
22
  var author = "long.zhu";
23
23
  var license = "MIT";
@@ -430,7 +430,7 @@ async function listDaemonLogFiles(limit = 50) {
430
430
  return { file, path: fullPath, modified: stats.mtime };
431
431
  }).sort((a, b) => b.modified.getTime() - a.modified.getTime());
432
432
  try {
433
- const { readDaemonState } = await import('./persistence-CqgPgbzN.mjs');
433
+ const { readDaemonState } = await import('./persistence-sLEqV8vk.mjs');
434
434
  const state = await readDaemonState();
435
435
  if (!state) {
436
436
  return logs;
@@ -19,7 +19,7 @@ var path = require('path');
19
19
  var expoServerSdk = require('expo-server-sdk');
20
20
 
21
21
  var name = "happy-imou-cloud";
22
- var version = "2.0.3";
22
+ var version = "2.0.4";
23
23
  var description = "hicloud - Imou 企业定制版。关键是 happy!移动端远程 AI 编程工具,支持 Claude Code、Codex 和 Gemini CLI";
24
24
  var author = "long.zhu";
25
25
  var license = "MIT";
@@ -432,7 +432,7 @@ async function listDaemonLogFiles(limit = 50) {
432
432
  return { file, path: fullPath, modified: stats.mtime };
433
433
  }).sort((a, b) => b.modified.getTime() - a.modified.getTime());
434
434
  try {
435
- const { readDaemonState } = await Promise.resolve().then(function () { return require('./persistence-PzKU0QCa.cjs'); });
435
+ const { readDaemonState } = await Promise.resolve().then(function () { return require('./persistence-BeFVx6kI.cjs'); });
436
436
  const state = await readDaemonState();
437
437
  if (!state) {
438
438
  return logs;
@@ -1,6 +1,6 @@
1
- import { c as createDefaultRuntimeShell } from './index-CriPm_z9.mjs';
1
+ import { c as createDefaultRuntimeShell } from './index-vNYxNqVZ.mjs';
2
2
  import 'chalk';
3
- import './api-DpQIC-DJ.mjs';
3
+ import './api-CIHTNilH.mjs';
4
4
  import 'axios';
5
5
  import 'fs';
6
6
  import 'node:fs';
@@ -17,7 +17,7 @@ import 'fs/promises';
17
17
  import 'crypto';
18
18
  import 'path';
19
19
  import 'expo-server-sdk';
20
- import './persistence-CqgPgbzN.mjs';
20
+ import './persistence-sLEqV8vk.mjs';
21
21
  import 'node:fs/promises';
22
22
  import 'os';
23
23
  import 'tmp';
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-LYPXVO_L.cjs');
3
+ var index = require('./index-1zlH6s7a.cjs');
4
4
  require('chalk');
5
- require('./api-D9dIR956.cjs');
5
+ require('./api-CyJG1mr6.cjs');
6
6
  require('axios');
7
7
  require('fs');
8
8
  require('node:fs');
@@ -19,7 +19,7 @@ require('fs/promises');
19
19
  require('crypto');
20
20
  require('path');
21
21
  require('expo-server-sdk');
22
- require('./persistence-PzKU0QCa.cjs');
22
+ require('./persistence-BeFVx6kI.cjs');
23
23
  require('node:fs/promises');
24
24
  require('os');
25
25
  require('tmp');
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var chalk = require('chalk');
4
- var api = require('./api-D9dIR956.cjs');
5
- var persistence = require('./persistence-PzKU0QCa.cjs');
4
+ var api = require('./api-CyJG1mr6.cjs');
5
+ var persistence = require('./persistence-BeFVx6kI.cjs');
6
6
  var z = require('zod');
7
7
  var fs$1 = require('fs/promises');
8
8
  var os$1 = require('os');
@@ -70,7 +70,7 @@ async function openBrowser(url) {
70
70
  }
71
71
  }
72
72
 
73
- const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-LYPXVO_L.cjs', document.baseURI).href)));
73
+ const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-1zlH6s7a.cjs', document.baseURI).href)));
74
74
  const QRCode = require$1("qrcode-terminal/vendor/QRCode");
75
75
  const QRErrorCorrectLevel = require$1("qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel");
76
76
  const pendingTempFiles = /* @__PURE__ */ new Set();
@@ -693,7 +693,7 @@ function setupCleanupHandlers() {
693
693
  });
694
694
  }
695
695
 
696
- const __dirname$1 = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-LYPXVO_L.cjs', document.baseURI).href))));
696
+ const __dirname$1 = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-1zlH6s7a.cjs', document.baseURI).href))));
697
697
  function projectPath() {
698
698
  const path$1 = path.resolve(__dirname$1, "..");
699
699
  return path$1;
@@ -4527,6 +4527,107 @@ function parseArgsFromContent(content) {
4527
4527
  }
4528
4528
  return {};
4529
4529
  }
4530
+ function appendToolOutput(existing, next) {
4531
+ if (!existing || existing.length === 0) {
4532
+ return next;
4533
+ }
4534
+ if (next === existing || existing.endsWith(next)) {
4535
+ return existing;
4536
+ }
4537
+ if (next.startsWith(existing)) {
4538
+ return next;
4539
+ }
4540
+ return `${existing}${next}`;
4541
+ }
4542
+ function isRecord(value) {
4543
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4544
+ }
4545
+ function hasMeaningfulContent(value) {
4546
+ if (value === null || value === void 0) {
4547
+ return false;
4548
+ }
4549
+ if (typeof value === "string") {
4550
+ return value.length > 0;
4551
+ }
4552
+ if (Array.isArray(value)) {
4553
+ return value.length > 0;
4554
+ }
4555
+ if (isRecord(value)) {
4556
+ return Object.keys(value).length > 0;
4557
+ }
4558
+ return true;
4559
+ }
4560
+ function looksLikeToolMetadata(record) {
4561
+ const metadataKeys = [
4562
+ "command",
4563
+ "cmd",
4564
+ "script",
4565
+ "argv",
4566
+ "cwd",
4567
+ "workingDirectory",
4568
+ "description",
4569
+ "title",
4570
+ "parsed_cmd"
4571
+ ];
4572
+ if (metadataKeys.some((key) => key in record)) {
4573
+ return true;
4574
+ }
4575
+ const nestedKeys = ["input", "toolCall", "arguments", "content"];
4576
+ for (const key of nestedKeys) {
4577
+ const nested = record[key];
4578
+ if (isRecord(nested) && looksLikeToolMetadata(nested)) {
4579
+ return true;
4580
+ }
4581
+ }
4582
+ return false;
4583
+ }
4584
+ function extractToolOutputChunk(content) {
4585
+ if (typeof content === "string") {
4586
+ return content.length > 0 ? content : null;
4587
+ }
4588
+ if (Array.isArray(content)) {
4589
+ const parts = content.map((item) => extractToolOutputChunk(item)).filter((item) => Boolean(item));
4590
+ return parts.length > 0 ? parts.join("") : null;
4591
+ }
4592
+ if (!isRecord(content)) {
4593
+ return null;
4594
+ }
4595
+ const outputKeys = ["stdout", "stderr", "output", "text", "message", "data", "error", "reason"];
4596
+ const hasOutputKey = outputKeys.some((key) => key in content);
4597
+ if (!hasOutputKey && looksLikeToolMetadata(content)) {
4598
+ return null;
4599
+ }
4600
+ for (const key of outputKeys) {
4601
+ if (!(key in content)) {
4602
+ continue;
4603
+ }
4604
+ const value = content[key];
4605
+ const formatted2 = typeof value === "string" ? value : formatDisplayMessage(value);
4606
+ if (formatted2.length > 0) {
4607
+ return formatted2;
4608
+ }
4609
+ }
4610
+ const formatted = formatDisplayMessage(content);
4611
+ return formatted.length > 0 ? formatted : null;
4612
+ }
4613
+ function mergeStreamedOutputWithResult(content, streamedOutput) {
4614
+ if (!streamedOutput || streamedOutput.length === 0) {
4615
+ return content;
4616
+ }
4617
+ if (!hasMeaningfulContent(content)) {
4618
+ return streamedOutput;
4619
+ }
4620
+ if (isRecord(content)) {
4621
+ const hasStructuredOutput = ["stdout", "stderr", "output", "text", "message", "data"].some((key) => key in content);
4622
+ if (!hasStructuredOutput) {
4623
+ return {
4624
+ ...content,
4625
+ stdout: streamedOutput
4626
+ };
4627
+ }
4628
+ }
4629
+ return content;
4630
+ }
4530
4631
  function extractErrorDetail(content) {
4531
4632
  if (!content) return void 0;
4532
4633
  if (typeof content === "string") {
@@ -4674,11 +4775,13 @@ function completeToolCall(toolCallId, toolKind, content, ctx) {
4674
4775
  clearTimeout(timeout);
4675
4776
  ctx.toolCallTimeouts.delete(toolCallId);
4676
4777
  }
4778
+ const streamedOutput = ctx.toolCallOutputs.get(toolCallId);
4779
+ ctx.toolCallOutputs.delete(toolCallId);
4677
4780
  api.logger.debug(`[AcpBackend] \u2705 Tool call COMPLETED: ${toolCallId} (${toolKindStr}) - Duration: ${duration}. Active tool calls: ${ctx.activeToolCalls.size}`);
4678
4781
  ctx.emit({
4679
4782
  type: "tool-result",
4680
4783
  toolName: toolKindStr,
4681
- result: content,
4784
+ result: mergeStreamedOutputWithResult(content, streamedOutput),
4682
4785
  callId: toolCallId
4683
4786
  });
4684
4787
  if (ctx.activeToolCalls.size === 0) {
@@ -4720,6 +4823,8 @@ function failToolCall(toolCallId, status, toolKind, content, ctx) {
4720
4823
  }
4721
4824
  const durationStr = formatDuration(startTime);
4722
4825
  api.logger.debug(`[AcpBackend] \u274C Tool call ${status.toUpperCase()}: ${toolCallId} (${toolKindStr}) - Duration: ${durationStr}. Active tool calls: ${ctx.activeToolCalls.size}`);
4826
+ const streamedOutput = ctx.toolCallOutputs.get(toolCallId);
4827
+ ctx.toolCallOutputs.delete(toolCallId);
4723
4828
  const errorDetail = extractErrorDetail(content);
4724
4829
  if (errorDetail) {
4725
4830
  api.logger.debug(`[AcpBackend] \u274C Tool call error details: ${errorDetail.substring(0, 500)}`);
@@ -4729,7 +4834,11 @@ function failToolCall(toolCallId, status, toolKind, content, ctx) {
4729
4834
  ctx.emit({
4730
4835
  type: "tool-result",
4731
4836
  toolName: toolKindStr,
4732
- result: errorDetail ? { error: errorDetail, status } : { error: `Tool call ${status}`, status },
4837
+ result: streamedOutput ? {
4838
+ stdout: streamedOutput,
4839
+ error: errorDetail || `Tool call ${status}`,
4840
+ status
4841
+ } : errorDetail ? { error: errorDetail, status } : { error: `Tool call ${status}`, status },
4733
4842
  callId: toolCallId
4734
4843
  });
4735
4844
  if (ctx.activeToolCalls.size === 0) {
@@ -4745,8 +4854,13 @@ function handleToolCallUpdate(update, ctx) {
4745
4854
  api.logger.debug("[AcpBackend] Tool call update without toolCallId:", update);
4746
4855
  return { handled: false };
4747
4856
  }
4748
- const toolKind = update.kind || "unknown";
4857
+ const toolKind = update.kind || ctx.toolCallIdToNameMap.get(toolCallId) || "unknown";
4749
4858
  let toolCallCountSincePrompt = ctx.toolCallCountSincePrompt;
4859
+ const outputChunk = extractToolOutputChunk(update.content);
4860
+ if (outputChunk) {
4861
+ const nextOutput = appendToolOutput(ctx.toolCallOutputs.get(toolCallId), outputChunk);
4862
+ ctx.toolCallOutputs.set(toolCallId, nextOutput);
4863
+ }
4750
4864
  if (status === "in_progress" || status === "pending") {
4751
4865
  if (!ctx.activeToolCalls.has(toolCallId)) {
4752
4866
  toolCallCountSincePrompt++;
@@ -4995,6 +5109,11 @@ function normalizeAcpError(error) {
4995
5109
  }
4996
5110
  return normalized;
4997
5111
  }
5112
+ function createAcpAbortError(message) {
5113
+ const error = new Error(message);
5114
+ error.name = "AbortError";
5115
+ return error;
5116
+ }
4998
5117
  function enrichAcpError(error, stderrExcerpt) {
4999
5118
  const normalized = normalizeAcpError(error);
5000
5119
  if (!stderrExcerpt.trim()) {
@@ -5021,6 +5140,8 @@ class AcpBackend {
5021
5140
  toolCallTimeouts = /* @__PURE__ */ new Map();
5022
5141
  /** Track tool call start times for performance monitoring */
5023
5142
  toolCallStartTimes = /* @__PURE__ */ new Map();
5143
+ /** Track streamed tool output between ACP updates and final completion */
5144
+ toolCallOutputs = /* @__PURE__ */ new Map();
5024
5145
  /** Pending permission requests that need response */
5025
5146
  pendingPermissions = /* @__PURE__ */ new Map();
5026
5147
  /** Map from permission request ID to real tool call ID for tracking */
@@ -5031,6 +5152,14 @@ class AcpBackend {
5031
5152
  toolCallCountSincePrompt = 0;
5032
5153
  /** Timeout for emitting 'idle' status after last message chunk */
5033
5154
  idleTimeout = null;
5155
+ /** Promise resolver for waitForResponseComplete */
5156
+ idleResolver = null;
5157
+ /** Promise rejecter for waitForResponseComplete */
5158
+ idleRejecter = null;
5159
+ /** Completion signal captured before waitForResponseComplete is attached */
5160
+ responseCompletionOutcome = null;
5161
+ /** Whether the current prompt is still waiting for completion */
5162
+ waitingForResponse = false;
5034
5163
  /** Transport handler for agent-specific behavior */
5035
5164
  transport;
5036
5165
  /** Keep a short rolling stderr buffer so startup failures can surface the real cause. */
@@ -5048,6 +5177,44 @@ class AcpBackend {
5048
5177
  getRecentStderrExcerpt() {
5049
5178
  return this.recentStderrLines.slice(-6).join("\n");
5050
5179
  }
5180
+ clearIdleTimeoutState() {
5181
+ if (this.idleTimeout) {
5182
+ clearTimeout(this.idleTimeout);
5183
+ this.idleTimeout = null;
5184
+ }
5185
+ }
5186
+ clearToolCallTracking() {
5187
+ this.activeToolCalls.clear();
5188
+ for (const timeout of this.toolCallTimeouts.values()) {
5189
+ clearTimeout(timeout);
5190
+ }
5191
+ this.toolCallTimeouts.clear();
5192
+ this.toolCallStartTimes.clear();
5193
+ this.toolCallIdToNameMap.clear();
5194
+ this.toolCallOutputs.clear();
5195
+ this.toolCallCountSincePrompt = 0;
5196
+ }
5197
+ resetResponseTrackingForNewPrompt() {
5198
+ this.responseCompletionOutcome = null;
5199
+ this.clearIdleTimeoutState();
5200
+ this.clearToolCallTracking();
5201
+ }
5202
+ settleResponseWaiter(outcome) {
5203
+ const hasActiveWaiter = Boolean(this.idleResolver || this.idleRejecter);
5204
+ if (!this.waitingForResponse && !hasActiveWaiter) {
5205
+ return;
5206
+ }
5207
+ if (!hasActiveWaiter) {
5208
+ this.waitingForResponse = false;
5209
+ this.responseCompletionOutcome = outcome;
5210
+ return;
5211
+ }
5212
+ if (outcome.kind === "resolved") {
5213
+ this.idleResolver?.();
5214
+ return;
5215
+ }
5216
+ this.idleRejecter?.(outcome.error);
5217
+ }
5051
5218
  onMessage(handler) {
5052
5219
  this.listeners.push(handler);
5053
5220
  }
@@ -5122,10 +5289,15 @@ class AcpBackend {
5122
5289
  });
5123
5290
  this.process.on("error", (err) => {
5124
5291
  api.logger.debug(`[AcpBackend] Process error:`, err);
5292
+ this.settleResponseWaiter({ kind: "rejected", error: err });
5125
5293
  this.emit({ type: "status", status: "error", detail: err.message });
5126
5294
  });
5127
5295
  this.process.on("exit", (code, signal) => {
5128
5296
  if (!this.disposed && code !== 0 && code !== null) {
5297
+ this.settleResponseWaiter({
5298
+ kind: "rejected",
5299
+ error: new Error(`ACP process exited with code ${code}${signal ? ` (${signal})` : ""}`)
5300
+ });
5129
5301
  api.logger.debug(`[AcpBackend] Process exited with code ${code}, signal ${signal}`);
5130
5302
  this.emit({ type: "status", status: "stopped", detail: `Exit code: ${code}` });
5131
5303
  }
@@ -5456,6 +5628,7 @@ class AcpBackend {
5456
5628
  toolCallStartTimes: this.toolCallStartTimes,
5457
5629
  toolCallTimeouts: this.toolCallTimeouts,
5458
5630
  toolCallIdToNameMap: this.toolCallIdToNameMap,
5631
+ toolCallOutputs: this.toolCallOutputs,
5459
5632
  idleTimeout: this.idleTimeout,
5460
5633
  toolCallCountSincePrompt: this.toolCallCountSincePrompt,
5461
5634
  emit: (msg) => this.emit(msg),
@@ -5532,20 +5705,24 @@ class AcpBackend {
5532
5705
  this.emitUsageTelemetry(update, "acp-usage-update");
5533
5706
  continue;
5534
5707
  }
5708
+ if (sessionUpdateType === "task_complete") {
5709
+ this.emitUsageTelemetry(update.usage, "acp-session-usage");
5710
+ ctx.clearIdleTimeout();
5711
+ api.logger.debug("[AcpBackend] task_complete received, emitting idle status");
5712
+ this.emitIdleStatus();
5713
+ continue;
5714
+ }
5535
5715
  const handledLegacy = handleLegacyMessageChunk(update, ctx).handled;
5536
5716
  const handledPlan = handlePlanUpdate(update, ctx).handled;
5537
5717
  const handledThinking = handleThinkingUpdate(update, ctx).handled;
5538
5718
  const handledUsage = this.emitUsageTelemetry(update.usage, "acp-session-usage");
5539
5719
  const updateTypeStr = sessionUpdateType;
5540
- const handledTypes = ["agent_message_chunk", "tool_call_update", "agent_thought_chunk", "tool_call", "usage_update"];
5720
+ const handledTypes = ["agent_message_chunk", "tool_call_update", "agent_thought_chunk", "tool_call", "usage_update", "task_complete"];
5541
5721
  if (updateTypeStr && !handledTypes.includes(updateTypeStr) && !handledLegacy && !handledPlan && !handledThinking && !handledUsage) {
5542
5722
  api.logger.debug(`[AcpBackend] Unhandled session update type: ${updateTypeStr}`, JSON.stringify(update, null, 2));
5543
5723
  }
5544
5724
  }
5545
5725
  }
5546
- // Promise resolver for waitForIdle - set when waiting for response to complete
5547
- idleResolver = null;
5548
- waitingForResponse = false;
5549
5726
  async sendPrompt(sessionId, prompt) {
5550
5727
  this.toolCallCountSincePrompt = 0;
5551
5728
  if (this.disposed) {
@@ -5554,6 +5731,7 @@ class AcpBackend {
5554
5731
  if (!this.connection || !this.acpSessionId) {
5555
5732
  throw new Error("Session not started");
5556
5733
  }
5734
+ this.resetResponseTrackingForNewPrompt();
5557
5735
  this.emit({ type: "status", status: "running" });
5558
5736
  this.waitingForResponse = true;
5559
5737
  try {
@@ -5572,7 +5750,6 @@ class AcpBackend {
5572
5750
  api.logger.debug("[AcpBackend] Prompt request sent to ACP connection");
5573
5751
  } catch (error) {
5574
5752
  api.logger.debug("[AcpBackend] Error sending prompt:", error);
5575
- this.waitingForResponse = false;
5576
5753
  let errorDetail;
5577
5754
  if (error instanceof Error) {
5578
5755
  errorDetail = error.message;
@@ -5586,6 +5763,10 @@ class AcpBackend {
5586
5763
  status: "error",
5587
5764
  detail: errorDetail
5588
5765
  });
5766
+ this.settleResponseWaiter({
5767
+ kind: "rejected",
5768
+ error: error instanceof Error ? error : normalizeAcpError(error)
5769
+ });
5589
5770
  throw error;
5590
5771
  }
5591
5772
  }
@@ -5594,21 +5775,38 @@ class AcpBackend {
5594
5775
  * Call this after sendPrompt to wait for Gemini to finish responding
5595
5776
  */
5596
5777
  async waitForResponseComplete(timeoutMs = 12e4) {
5778
+ const pendingOutcome = this.responseCompletionOutcome;
5779
+ if (pendingOutcome) {
5780
+ this.responseCompletionOutcome = null;
5781
+ if (pendingOutcome.kind === "rejected") {
5782
+ throw pendingOutcome.error;
5783
+ }
5784
+ return;
5785
+ }
5597
5786
  if (!this.waitingForResponse) {
5598
5787
  return;
5599
5788
  }
5600
5789
  return new Promise((resolve, reject) => {
5601
5790
  const timeout = setTimeout(() => {
5602
5791
  this.idleResolver = null;
5792
+ this.idleRejecter = null;
5603
5793
  this.waitingForResponse = false;
5604
5794
  reject(new Error("Timeout waiting for response to complete"));
5605
5795
  }, timeoutMs);
5606
5796
  this.idleResolver = () => {
5607
5797
  clearTimeout(timeout);
5608
5798
  this.idleResolver = null;
5799
+ this.idleRejecter = null;
5609
5800
  this.waitingForResponse = false;
5610
5801
  resolve();
5611
5802
  };
5803
+ this.idleRejecter = (error) => {
5804
+ clearTimeout(timeout);
5805
+ this.idleResolver = null;
5806
+ this.idleRejecter = null;
5807
+ this.waitingForResponse = false;
5808
+ reject(error);
5809
+ };
5612
5810
  });
5613
5811
  }
5614
5812
  /**
@@ -5616,18 +5814,19 @@ class AcpBackend {
5616
5814
  */
5617
5815
  emitIdleStatus() {
5618
5816
  this.emit({ type: "status", status: "idle" });
5619
- if (this.idleResolver) {
5620
- api.logger.debug("[AcpBackend] Resolving idle waiter");
5621
- this.idleResolver();
5622
- }
5817
+ this.settleResponseWaiter({ kind: "resolved" });
5623
5818
  }
5624
5819
  async cancel(sessionId) {
5820
+ const cancelError = createAcpAbortError("Cancelled by user");
5821
+ this.clearIdleTimeoutState();
5822
+ this.clearToolCallTracking();
5823
+ this.settleResponseWaiter({ kind: "rejected", error: cancelError });
5824
+ this.emit({ type: "status", status: "stopped", detail: "Cancelled by user" });
5625
5825
  if (!this.connection || !this.acpSessionId) {
5626
5826
  return;
5627
5827
  }
5628
5828
  try {
5629
5829
  await this.connection.cancel({ sessionId: this.acpSessionId });
5630
- this.emit({ type: "status", status: "stopped", detail: "Cancelled by user" });
5631
5830
  } catch (error) {
5632
5831
  api.logger.debug("[AcpBackend] Error cancelling:", error);
5633
5832
  }
@@ -5655,6 +5854,10 @@ class AcpBackend {
5655
5854
  if (this.disposed) return;
5656
5855
  api.logger.debug("[AcpBackend] Disposing backend");
5657
5856
  this.disposed = true;
5857
+ this.settleResponseWaiter({
5858
+ kind: "rejected",
5859
+ error: createAcpAbortError("ACP backend disposed")
5860
+ });
5658
5861
  if (this.connection && this.acpSessionId) {
5659
5862
  try {
5660
5863
  await Promise.race([
@@ -5683,19 +5886,11 @@ class AcpBackend {
5683
5886
  });
5684
5887
  this.process = null;
5685
5888
  }
5686
- if (this.idleTimeout) {
5687
- clearTimeout(this.idleTimeout);
5688
- this.idleTimeout = null;
5689
- }
5889
+ this.clearIdleTimeoutState();
5690
5890
  this.listeners = [];
5691
5891
  this.connection = null;
5692
5892
  this.acpSessionId = null;
5693
- this.activeToolCalls.clear();
5694
- for (const timeout of this.toolCallTimeouts.values()) {
5695
- clearTimeout(timeout);
5696
- }
5697
- this.toolCallTimeouts.clear();
5698
- this.toolCallStartTimes.clear();
5893
+ this.clearToolCallTracking();
5699
5894
  this.pendingPermissions.clear();
5700
5895
  }
5701
5896
  }
@@ -6336,12 +6531,12 @@ async function ensureUnifiedDaemonStarted() {
6336
6531
  async function executeUnifiedProvider(opts) {
6337
6532
  const credentials = await ensureUnifiedRuntimePrerequisites(opts.credentials);
6338
6533
  if (opts.provider === "claude") {
6339
- const { runClaude } = await Promise.resolve().then(function () { return require('./runClaude-IeRSC5qX.cjs'); });
6534
+ const { runClaude } = await Promise.resolve().then(function () { return require('./runClaude-Dz-PCSvb.cjs'); });
6340
6535
  await runClaude(credentials, opts.claudeOptions ?? {});
6341
6536
  return;
6342
6537
  }
6343
6538
  if (opts.provider === "codex") {
6344
- const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-WRmgSK6L.cjs'); });
6539
+ const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-BtZplK1R.cjs'); });
6345
6540
  await runCodex({
6346
6541
  credentials,
6347
6542
  startedBy: opts.startedBy,
@@ -6351,7 +6546,7 @@ async function executeUnifiedProvider(opts) {
6351
6546
  return;
6352
6547
  }
6353
6548
  if (opts.provider === "gemini") {
6354
- const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-qBh6zs5G.cjs'); });
6549
+ const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-DUyH311Z.cjs'); });
6355
6550
  await runGemini({
6356
6551
  credentials,
6357
6552
  startedBy: opts.startedBy
@@ -6393,7 +6588,7 @@ function shouldRunMainClaudeFlow(opts) {
6393
6588
  return;
6394
6589
  } else if (subcommand === "runtime") {
6395
6590
  if (args[1] === "providers") {
6396
- const { renderRuntimeProviders } = await Promise.resolve().then(function () { return require('./command-CdXv1zNF.cjs'); });
6591
+ const { renderRuntimeProviders } = await Promise.resolve().then(function () { return require('./command-CPlJKXDn.cjs'); });
6397
6592
  console.log(renderRuntimeProviders());
6398
6593
  return;
6399
6594
  }
@@ -6571,8 +6766,8 @@ function shouldRunMainClaudeFlow(opts) {
6571
6766
  const projectId = args[3];
6572
6767
  try {
6573
6768
  const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return config; });
6574
- const { readCredentials: readCredentials2 } = await Promise.resolve().then(function () { return require('./persistence-PzKU0QCa.cjs'); });
6575
- const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./api-D9dIR956.cjs'); }).then(function (n) { return n.api; });
6769
+ const { readCredentials: readCredentials2 } = await Promise.resolve().then(function () { return require('./persistence-BeFVx6kI.cjs'); });
6770
+ const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./api-CyJG1mr6.cjs'); }).then(function (n) { return n.api; });
6576
6771
  let userEmail = void 0;
6577
6772
  try {
6578
6773
  const credentials = await readCredentials2();