happy-imou-cloud 2.0.7 → 2.0.9

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 (26) hide show
  1. package/bin/happy-cloud.mjs +1 -1
  2. package/dist/{api-Dwkm7s_E.cjs → api-CUTdFiFP.cjs} +3 -4
  3. package/dist/{api-dwwHBzLc.mjs → api-CnvyGas2.mjs} +3 -4
  4. package/dist/{command-Cfq3Uc0S.mjs → command-BGA3qCKR.mjs} +3 -3
  5. package/dist/{command-DiAVIsxX.cjs → command-DLAJZsKX.cjs} +3 -3
  6. package/dist/{index-HyqLXzw-.mjs → index-BpZL4RcT.mjs} +208 -32
  7. package/dist/{index-CfqxEoyl.cjs → index-D4OdFq68.cjs} +210 -34
  8. package/dist/index.cjs +3 -3
  9. package/dist/index.mjs +3 -3
  10. package/dist/lib.cjs +1 -1
  11. package/dist/lib.mjs +1 -1
  12. package/dist/{BaseReasoningProcessor-ClrT-x-H.mjs → names-C9iJODqA.mjs} +98 -3
  13. package/dist/{BaseReasoningProcessor-DphULXS-.cjs → names-YEhZwVT0.cjs} +100 -2
  14. package/dist/{persistence-Dg-rxY2a.mjs → persistence-BPV3AmJL.mjs} +100 -4
  15. package/dist/{persistence-hbhwAYIV.cjs → persistence-CxvL0cwp.cjs} +110 -1
  16. package/dist/{registerKillSessionHandler-BAvk4GYO.mjs → registerKillSessionHandler-C2O8b5wH.mjs} +2 -2
  17. package/dist/{registerKillSessionHandler-D1ouN10n.cjs → registerKillSessionHandler-rqd7duc9.cjs} +2 -2
  18. package/dist/{runClaude-OxYbt3ZQ.mjs → runClaude-8inO7C5p.mjs} +4 -4
  19. package/dist/{runClaude-CZmJ7qEP.cjs → runClaude-KwIVwFp1.cjs} +5 -5
  20. package/dist/{runCodex-ByVTEbSY.mjs → runCodex-BQ-fN5E6.mjs} +5 -6
  21. package/dist/{runCodex-CtncAgso.cjs → runCodex-Ba8COxZe.cjs} +24 -25
  22. package/dist/{runGemini-BRO6A2jm.mjs → runGemini-BE0FizuV.mjs} +5 -6
  23. package/dist/{runGemini-ChwjLmhI.cjs → runGemini-DtdLLX9o.cjs} +20 -21
  24. package/package.json +3 -4
  25. package/scripts/build.mjs +66 -0
  26. package/scripts/release-smoke.mjs +166 -30
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var chalk = require('chalk');
4
- var api = require('./api-Dwkm7s_E.cjs');
5
- var persistence = require('./persistence-hbhwAYIV.cjs');
4
+ var api = require('./api-CUTdFiFP.cjs');
5
+ var persistence = require('./persistence-CxvL0cwp.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-CfqxEoyl.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-D4OdFq68.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-CfqxEoyl.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-D4OdFq68.cjs', document.baseURI).href))));
697
697
  function projectPath() {
698
698
  const path$1 = path.resolve(__dirname$1, "..");
699
699
  return path$1;
@@ -1130,6 +1130,21 @@ function getEnvironmentInfo() {
1130
1130
  terminal: process.env.TERM
1131
1131
  };
1132
1132
  }
1133
+ function resolveDaemonSpawnDiagnostics(projectRoot, fileExists = node_fs.existsSync) {
1134
+ const wrapperCandidates = [
1135
+ node_path.join(projectRoot, "bin", "happy-cloud.mjs"),
1136
+ node_path.join(projectRoot, "bin", "happy.mjs")
1137
+ ];
1138
+ const cliEntrypoint = node_path.join(projectRoot, "dist", "index.mjs");
1139
+ const wrapperPath = wrapperCandidates.find((candidate) => fileExists(candidate)) ?? wrapperCandidates[0];
1140
+ return {
1141
+ projectRoot,
1142
+ wrapperPath,
1143
+ cliEntrypoint,
1144
+ wrapperExists: fileExists(wrapperPath),
1145
+ cliEntrypointExists: fileExists(cliEntrypoint)
1146
+ };
1147
+ }
1133
1148
  function getLogFiles(logDir) {
1134
1149
  if (!node_fs.existsSync(logDir)) {
1135
1150
  return [];
@@ -1156,14 +1171,12 @@ async function runDoctorCommand(filter) {
1156
1171
  console.log(`Node.js Version: ${chalk.green(process.version)}`);
1157
1172
  console.log("");
1158
1173
  console.log(chalk.bold("\u{1F527} Daemon Spawn Diagnostics"));
1159
- const projectRoot = projectPath();
1160
- const wrapperPath = node_path.join(projectRoot, "bin", "happy.mjs");
1161
- const cliEntrypoint = node_path.join(projectRoot, "dist", "index.mjs");
1162
- console.log(`Project Root: ${chalk.blue(projectRoot)}`);
1163
- console.log(`Wrapper Script: ${chalk.blue(wrapperPath)}`);
1164
- console.log(`CLI Entrypoint: ${chalk.blue(cliEntrypoint)}`);
1165
- console.log(`Wrapper Exists: ${node_fs.existsSync(wrapperPath) ? chalk.green("\u2713 Yes") : chalk.red("\u274C No")}`);
1166
- console.log(`CLI Exists: ${node_fs.existsSync(cliEntrypoint) ? chalk.green("\u2713 Yes") : chalk.red("\u274C No")}`);
1174
+ const diagnostics = resolveDaemonSpawnDiagnostics(projectPath());
1175
+ console.log(`Project Root: ${chalk.blue(diagnostics.projectRoot)}`);
1176
+ console.log(`Wrapper Script: ${chalk.blue(diagnostics.wrapperPath)}`);
1177
+ console.log(`CLI Entrypoint: ${chalk.blue(diagnostics.cliEntrypoint)}`);
1178
+ console.log(`Wrapper Exists: ${diagnostics.wrapperExists ? chalk.green("\u2713 Yes") : chalk.red("\u274C No")}`);
1179
+ console.log(`CLI Exists: ${diagnostics.cliEntrypointExists ? chalk.green("\u2713 Yes") : chalk.red("\u274C No")}`);
1167
1180
  console.log("");
1168
1181
  console.log(chalk.bold("\u2699\uFE0F Configuration"));
1169
1182
  console.log(`Happy Home: ${chalk.blue(api.configuration.happyCloudHomeDir)}`);
@@ -4213,6 +4226,9 @@ class DefaultTransport {
4213
4226
  getInitTimeout() {
4214
4227
  return DEFAULT_TIMEOUTS.init;
4215
4228
  }
4229
+ getInitDelayMs() {
4230
+ return 0;
4231
+ }
4216
4232
  /**
4217
4233
  * Default: pass through all lines that are valid JSON objects/arrays
4218
4234
  */
@@ -4273,11 +4289,16 @@ class DefaultTransport {
4273
4289
  determineToolName(toolName, _toolCallId, _input, _context) {
4274
4290
  return toolName;
4275
4291
  }
4292
+ getPostPromptNoUpdatesTimeoutMs() {
4293
+ return 3e4;
4294
+ }
4276
4295
  }
4277
4296
 
4278
4297
  const GEMINI_TIMEOUTS = {
4279
4298
  /** Gemini CLI can be slow on first start (downloading models, etc.) */
4280
4299
  init: 12e4,
4300
+ /** Gemini ACP can swallow an initialize request sent too early after spawn */
4301
+ initDelay: 2500,
4281
4302
  /** Standard tool call timeout */
4282
4303
  toolCall: 12e4,
4283
4304
  /** Investigation tools (codebase_investigator) can run for a long time */
@@ -4312,6 +4333,9 @@ class GeminiTransport {
4312
4333
  getInitTimeout() {
4313
4334
  return GEMINI_TIMEOUTS.init;
4314
4335
  }
4336
+ getInitDelayMs() {
4337
+ return GEMINI_TIMEOUTS.initDelay;
4338
+ }
4315
4339
  /**
4316
4340
  * Filter Gemini CLI debug output from stdout.
4317
4341
  *
@@ -5048,6 +5072,10 @@ ${line}` : line;
5048
5072
  controller.error(error);
5049
5073
  } finally {
5050
5074
  reader.releaseLock();
5075
+ try {
5076
+ params.onDone?.();
5077
+ } catch {
5078
+ }
5051
5079
  if (!controllerErrored) {
5052
5080
  controller.close();
5053
5081
  }
@@ -5110,7 +5138,7 @@ async function killProcessTree(proc, options) {
5110
5138
  if (!pid) {
5111
5139
  return;
5112
5140
  }
5113
- const graceMs = Math.max(1, options?.graceMs);
5141
+ const graceMs = Math.max(1, options?.graceMs ?? 1e3);
5114
5142
  const descendants = await resolveDescendantPids(pid).catch(() => []);
5115
5143
  const allPids = [...descendants, pid];
5116
5144
  for (const targetPid of allPids) {
@@ -5135,6 +5163,29 @@ const RETRY_CONFIG = {
5135
5163
  /** Maximum delay between retries in ms */
5136
5164
  maxDelayMs: 5e3
5137
5165
  };
5166
+ const DEFAULT_POST_PROMPT_NO_UPDATES_TIMEOUT_MS = 3e4;
5167
+ function readPositiveIntegerEnv(name) {
5168
+ const raw = typeof process.env[name] === "string" ? process.env[name].trim() : "";
5169
+ if (!raw) {
5170
+ return null;
5171
+ }
5172
+ const value = Number(raw);
5173
+ if (!Number.isFinite(value) || !Number.isInteger(value) || value <= 0) {
5174
+ return null;
5175
+ }
5176
+ return value;
5177
+ }
5178
+ function resolvePostPromptNoUpdatesTimeoutMs(transport) {
5179
+ const transportValue = transport.getPostPromptNoUpdatesTimeoutMs?.();
5180
+ if (typeof transportValue === "number" && Number.isFinite(transportValue) && transportValue > 0) {
5181
+ return Math.trunc(transportValue);
5182
+ }
5183
+ const envValue = readPositiveIntegerEnv("HAPPY_ACP_POST_PROMPT_NO_UPDATES_TIMEOUT_MS") ?? readPositiveIntegerEnv("HAPPIER_ACP_POST_PROMPT_NO_UPDATES_TIMEOUT_MS");
5184
+ if (envValue != null) {
5185
+ return envValue;
5186
+ }
5187
+ return DEFAULT_POST_PROMPT_NO_UPDATES_TIMEOUT_MS;
5188
+ }
5138
5189
  function getSessionUpdates(params) {
5139
5190
  const notification = params;
5140
5191
  const updates = Array.isArray(notification.updates) ? notification.updates.filter((update) => Boolean(update && typeof update === "object")) : [];
@@ -5310,6 +5361,17 @@ function normalizeAcpError(error) {
5310
5361
  }
5311
5362
  return normalized;
5312
5363
  }
5364
+ function getStatusErrorDetail(message) {
5365
+ if (message.type !== "status" || message.status !== "error") {
5366
+ return null;
5367
+ }
5368
+ const detail = typeof message.detail === "string" ? message.detail.trim() : "";
5369
+ return detail || "Unknown ACP transport error";
5370
+ }
5371
+ function looksLikeDroppedStdoutError(text) {
5372
+ const lower = text.toLowerCase();
5373
+ return lower.startsWith("error") || lower.includes("error:") || lower.includes("exception") || lower.includes("traceback") || lower.includes("invalid request") || lower.includes("invalid_request") || lower.includes("unauthorized") || lower.includes("forbidden") || lower.includes("permission denied") || /\b(4\d\d|5\d\d)\b/.test(lower) && (lower.includes("http") || lower.includes("status") || lower.includes("request"));
5374
+ }
5313
5375
  function createAcpAbortError(message) {
5314
5376
  const error = new Error(message);
5315
5377
  error.name = "AbortError";
@@ -5432,6 +5494,12 @@ class AcpBackend {
5432
5494
  responseCompletionOutcome = null;
5433
5495
  /** Whether the current prompt is still waiting for completion */
5434
5496
  waitingForResponse = false;
5497
+ /** First fatal prompt-level error observed for the current turn */
5498
+ responseCompletionError = null;
5499
+ /** Fallback completion when prompt returns but the agent emits no session updates */
5500
+ postPromptCompletionIdleTimeout = null;
5501
+ /** Whether at least one session/update arrived after the current prompt */
5502
+ sawSessionUpdateSincePrompt = false;
5435
5503
  /** Transport handler for agent-specific behavior */
5436
5504
  transport;
5437
5505
  /** Keep a short rolling stderr buffer so startup failures can surface the real cause. */
@@ -5455,6 +5523,12 @@ class AcpBackend {
5455
5523
  this.idleTimeout = null;
5456
5524
  }
5457
5525
  }
5526
+ clearPostPromptCompletionIdleTimeout() {
5527
+ if (this.postPromptCompletionIdleTimeout) {
5528
+ clearTimeout(this.postPromptCompletionIdleTimeout);
5529
+ this.postPromptCompletionIdleTimeout = null;
5530
+ }
5531
+ }
5458
5532
  clearToolCallTracking() {
5459
5533
  this.activeToolCalls.clear();
5460
5534
  for (const timeout of this.toolCallTimeouts.values()) {
@@ -5468,9 +5542,26 @@ class AcpBackend {
5468
5542
  }
5469
5543
  resetResponseTrackingForNewPrompt() {
5470
5544
  this.responseCompletionOutcome = null;
5545
+ this.responseCompletionError = null;
5546
+ this.sawSessionUpdateSincePrompt = false;
5471
5547
  this.clearIdleTimeoutState();
5548
+ this.clearPostPromptCompletionIdleTimeout();
5472
5549
  this.clearToolCallTracking();
5473
5550
  }
5551
+ failPendingResponseWait(error) {
5552
+ if (this.responseCompletionError) {
5553
+ return;
5554
+ }
5555
+ this.responseCompletionError = error;
5556
+ this.responseCompletionOutcome = null;
5557
+ this.waitingForResponse = false;
5558
+ this.clearPostPromptCompletionIdleTimeout();
5559
+ if (this.idleRejecter) {
5560
+ this.idleRejecter(error);
5561
+ }
5562
+ this.idleResolver = null;
5563
+ this.idleRejecter = null;
5564
+ }
5474
5565
  settleResponseWaiter(outcome) {
5475
5566
  const hasActiveWaiter = Boolean(this.idleResolver || this.idleRejecter);
5476
5567
  if (!this.waitingForResponse && !hasActiveWaiter) {
@@ -5506,6 +5597,38 @@ class AcpBackend {
5506
5597
  }
5507
5598
  }
5508
5599
  }
5600
+ handleDroppedStdoutLine(entry) {
5601
+ if (entry.reason !== "transport_filter_null" || !this.waitingForResponse || this.responseCompletionError) {
5602
+ return;
5603
+ }
5604
+ const raw = entry.line.trim();
5605
+ if (!raw) {
5606
+ return;
5607
+ }
5608
+ const context = {
5609
+ activeToolCalls: this.activeToolCalls,
5610
+ hasActiveInvestigation: this.transport.isInvestigationTool ? Array.from(this.activeToolCalls).some((id) => this.transport.isInvestigationTool(id)) : false
5611
+ };
5612
+ const transportResult = this.transport.handleStderr?.(entry.line, context);
5613
+ const transportMessage = transportResult?.message ?? null;
5614
+ if (transportMessage) {
5615
+ this.emit(transportMessage);
5616
+ const errorDetail = getStatusErrorDetail(transportMessage);
5617
+ if (errorDetail) {
5618
+ this.failPendingResponseWait(new Error(errorDetail));
5619
+ }
5620
+ return;
5621
+ }
5622
+ if (!looksLikeDroppedStdoutError(raw)) {
5623
+ return;
5624
+ }
5625
+ this.emit({
5626
+ type: "status",
5627
+ status: "error",
5628
+ detail: raw
5629
+ });
5630
+ this.failPendingResponseWait(new Error(raw));
5631
+ }
5509
5632
  async startSession(initialPrompt) {
5510
5633
  if (this.disposed) {
5511
5634
  throw new Error("Backend has been disposed");
@@ -5545,20 +5668,27 @@ class AcpBackend {
5545
5668
  const result = this.transport.handleStderr(text, context);
5546
5669
  if (result.message) {
5547
5670
  this.emit(result.message);
5671
+ const errorDetail = getStatusErrorDetail(result.message);
5672
+ if (errorDetail && this.waitingForResponse) {
5673
+ this.failPendingResponseWait(new Error(errorDetail));
5674
+ }
5548
5675
  }
5549
5676
  }
5550
5677
  });
5551
5678
  this.process.on("error", (err) => {
5552
5679
  api.logger.debug(`[AcpBackend] Process error:`, err);
5553
- this.settleResponseWaiter({ kind: "rejected", error: err });
5680
+ if (this.waitingForResponse) {
5681
+ this.failPendingResponseWait(err);
5682
+ }
5554
5683
  this.emit({ type: "status", status: "error", detail: err.message });
5555
5684
  });
5556
5685
  this.process.on("exit", (code, signal) => {
5557
5686
  if (!this.disposed && code !== 0 && code !== null) {
5558
- this.settleResponseWaiter({
5559
- kind: "rejected",
5560
- error: new Error(`ACP process exited with code ${code}${signal ? ` (${signal})` : ""}`)
5561
- });
5687
+ if (this.waitingForResponse) {
5688
+ this.failPendingResponseWait(
5689
+ new Error(`ACP process exited with code ${code}${signal ? ` (${signal})` : ""}`)
5690
+ );
5691
+ }
5562
5692
  api.logger.debug(`[AcpBackend] Process exited with code ${code}, signal ${signal}`);
5563
5693
  this.emit({ type: "status", status: "stopped", detail: `Exit code: ${code}` });
5564
5694
  }
@@ -5575,14 +5705,17 @@ class AcpBackend {
5575
5705
  transport: this.transport,
5576
5706
  onDroppedLine: (entry) => {
5577
5707
  droppedStdoutLines.push(entry);
5708
+ this.handleDroppedStdoutLine(entry);
5709
+ },
5710
+ onDone: () => {
5711
+ if (droppedStdoutLines.length > 0) {
5712
+ api.logger.debug(
5713
+ `[AcpBackend] Filtered out ${droppedStdoutLines.length} stdout lines from ${this.transport.agentName}`,
5714
+ droppedStdoutLines.slice(0, 5)
5715
+ );
5716
+ }
5578
5717
  }
5579
5718
  });
5580
- if (droppedStdoutLines.length > 0) {
5581
- api.logger.debug(
5582
- `[AcpBackend] Filtered out ${droppedStdoutLines.length} stdout lines from ${this.transport.agentName}`,
5583
- droppedStdoutLines.slice(0, 5)
5584
- );
5585
- }
5586
5719
  const stream = sdk.ndJsonStream(writable, filteredReadable);
5587
5720
  const client = {
5588
5721
  sessionUpdate: async (params) => {
@@ -5744,6 +5877,11 @@ class AcpBackend {
5744
5877
  }
5745
5878
  };
5746
5879
  const initTimeout = this.transport.getInitTimeout();
5880
+ const initDelayMs = this.transport.getInitDelayMs?.() ?? 0;
5881
+ if (initDelayMs > 0) {
5882
+ api.logger.debug(`[AcpBackend] Waiting ${initDelayMs}ms before initialize (${this.transport.agentName})...`);
5883
+ await api.delay(initDelayMs);
5884
+ }
5747
5885
  api.logger.debug(`[AcpBackend] Initializing connection (timeout: ${initTimeout}ms)...`);
5748
5886
  await withRetry(
5749
5887
  async () => {
@@ -5849,6 +5987,16 @@ class AcpBackend {
5849
5987
  return { sessionId };
5850
5988
  } catch (error) {
5851
5989
  const enrichedError = enrichAcpError(error, this.getRecentStderrExcerpt());
5990
+ if (this.process) {
5991
+ try {
5992
+ await killProcessTree(this.process, { graceMs: 250 });
5993
+ } catch {
5994
+ } finally {
5995
+ this.process = null;
5996
+ }
5997
+ }
5998
+ this.connection = null;
5999
+ this.acpSessionId = null;
5852
6000
  api.logger.debug("[AcpBackend] Error starting session:", enrichedError);
5853
6001
  this.emit({
5854
6002
  type: "status",
@@ -5909,6 +6057,8 @@ class AcpBackend {
5909
6057
  api.logger.debug("[AcpBackend] Received session update without update field:", params);
5910
6058
  return;
5911
6059
  }
6060
+ this.sawSessionUpdateSincePrompt = true;
6061
+ this.clearPostPromptCompletionIdleTimeout();
5912
6062
  for (const update of updates) {
5913
6063
  const sessionUpdateType = update.sessionUpdate;
5914
6064
  if (sessionUpdateType !== "agent_message_chunk") {
@@ -5988,6 +6138,29 @@ class AcpBackend {
5988
6138
  api.logger.debug(`[AcpBackend] Prompt request:`, JSON.stringify(promptRequest, null, 2));
5989
6139
  await this.connection.prompt(promptRequest);
5990
6140
  api.logger.debug("[AcpBackend] Prompt request sent to ACP connection");
6141
+ if (this.waitingForResponse && this.activeToolCalls.size === 0 && this.sawSessionUpdateSincePrompt === false) {
6142
+ const noUpdatesTimeoutMs = resolvePostPromptNoUpdatesTimeoutMs(this.transport);
6143
+ this.postPromptCompletionIdleTimeout = setTimeout(() => {
6144
+ this.postPromptCompletionIdleTimeout = null;
6145
+ if (this.responseCompletionError || !this.waitingForResponse) {
6146
+ return;
6147
+ }
6148
+ if (this.sawSessionUpdateSincePrompt || this.activeToolCalls.size > 0) {
6149
+ return;
6150
+ }
6151
+ const exitCode = this.process?.exitCode;
6152
+ if (typeof exitCode === "number" && Number.isFinite(exitCode) && exitCode !== 0) {
6153
+ this.failPendingResponseWait(new Error(`Exit code: ${exitCode}`));
6154
+ return;
6155
+ }
6156
+ const signalCode = this.process?.signalCode;
6157
+ if (typeof signalCode === "string" && signalCode.trim().length > 0) {
6158
+ this.failPendingResponseWait(new Error(`Signal: ${signalCode}`));
6159
+ return;
6160
+ }
6161
+ this.emitIdleStatus();
6162
+ }, Math.max(100, noUpdatesTimeoutMs));
6163
+ }
5991
6164
  } catch (error) {
5992
6165
  api.logger.debug("[AcpBackend] Error sending prompt:", error);
5993
6166
  let errorDetail;
@@ -6003,10 +6176,7 @@ class AcpBackend {
6003
6176
  status: "error",
6004
6177
  detail: errorDetail
6005
6178
  });
6006
- this.settleResponseWaiter({
6007
- kind: "rejected",
6008
- error: error instanceof Error ? error : normalizeAcpError(error)
6009
- });
6179
+ this.failPendingResponseWait(error instanceof Error ? error : normalizeAcpError(error));
6010
6180
  throw error;
6011
6181
  }
6012
6182
  }
@@ -6015,6 +6185,9 @@ class AcpBackend {
6015
6185
  * Call this after sendPrompt to wait for Gemini to finish responding
6016
6186
  */
6017
6187
  async waitForResponseComplete(timeoutMs = 12e4) {
6188
+ if (this.responseCompletionError) {
6189
+ throw this.responseCompletionError;
6190
+ }
6018
6191
  const pendingOutcome = this.responseCompletionOutcome;
6019
6192
  if (pendingOutcome) {
6020
6193
  this.responseCompletionOutcome = null;
@@ -6053,12 +6226,14 @@ class AcpBackend {
6053
6226
  * Helper to emit idle status and resolve any waiting promises
6054
6227
  */
6055
6228
  emitIdleStatus() {
6229
+ this.clearPostPromptCompletionIdleTimeout();
6056
6230
  this.emit({ type: "status", status: "idle" });
6057
6231
  this.settleResponseWaiter({ kind: "resolved" });
6058
6232
  }
6059
6233
  async cancel(sessionId) {
6060
6234
  const cancelError = createAcpAbortError("Cancelled by user");
6061
6235
  this.clearIdleTimeoutState();
6236
+ this.clearPostPromptCompletionIdleTimeout();
6062
6237
  this.clearToolCallTracking();
6063
6238
  this.settleResponseWaiter({ kind: "rejected", error: cancelError });
6064
6239
  this.emit({ type: "status", status: "stopped", detail: "Cancelled by user" });
@@ -6119,6 +6294,7 @@ class AcpBackend {
6119
6294
  }
6120
6295
  }
6121
6296
  this.clearIdleTimeoutState();
6297
+ this.clearPostPromptCompletionIdleTimeout();
6122
6298
  this.listeners = [];
6123
6299
  this.connection = null;
6124
6300
  this.acpSessionId = null;
@@ -6767,12 +6943,12 @@ async function ensureUnifiedDaemonStarted() {
6767
6943
  async function executeUnifiedProvider(opts) {
6768
6944
  const credentials = await ensureUnifiedRuntimePrerequisites(opts.credentials);
6769
6945
  if (opts.provider === "claude") {
6770
- const { runClaude } = await Promise.resolve().then(function () { return require('./runClaude-CZmJ7qEP.cjs'); });
6946
+ const { runClaude } = await Promise.resolve().then(function () { return require('./runClaude-KwIVwFp1.cjs'); });
6771
6947
  await runClaude(credentials, opts.claudeOptions ?? {});
6772
6948
  return;
6773
6949
  }
6774
6950
  if (opts.provider === "codex") {
6775
- const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-CtncAgso.cjs'); });
6951
+ const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-Ba8COxZe.cjs'); });
6776
6952
  await runCodex({
6777
6953
  credentials,
6778
6954
  startedBy: opts.startedBy,
@@ -6782,7 +6958,7 @@ async function executeUnifiedProvider(opts) {
6782
6958
  return;
6783
6959
  }
6784
6960
  if (opts.provider === "gemini") {
6785
- const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-ChwjLmhI.cjs'); });
6961
+ const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-DtdLLX9o.cjs'); });
6786
6962
  await runGemini({
6787
6963
  credentials,
6788
6964
  startedBy: opts.startedBy
@@ -6824,7 +7000,7 @@ function shouldRunMainClaudeFlow(opts) {
6824
7000
  return;
6825
7001
  } else if (subcommand === "runtime") {
6826
7002
  if (args[1] === "providers") {
6827
- const { renderRuntimeProviders } = await Promise.resolve().then(function () { return require('./command-DiAVIsxX.cjs'); });
7003
+ const { renderRuntimeProviders } = await Promise.resolve().then(function () { return require('./command-DLAJZsKX.cjs'); });
6828
7004
  console.log(renderRuntimeProviders());
6829
7005
  return;
6830
7006
  }
@@ -7002,8 +7178,8 @@ function shouldRunMainClaudeFlow(opts) {
7002
7178
  const projectId = args[3];
7003
7179
  try {
7004
7180
  const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return config; });
7005
- const { readCredentials: readCredentials2 } = await Promise.resolve().then(function () { return require('./persistence-hbhwAYIV.cjs'); });
7006
- const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./api-Dwkm7s_E.cjs'); }).then(function (n) { return n.api; });
7181
+ const { readCredentials: readCredentials2 } = await Promise.resolve().then(function () { return require('./persistence-CxvL0cwp.cjs'); });
7182
+ const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./api-CUTdFiFP.cjs'); }).then(function (n) { return n.api; });
7007
7183
  let userEmail = void 0;
7008
7184
  try {
7009
7185
  const credentials = await readCredentials2();
package/dist/index.cjs CHANGED
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  require('chalk');
4
- require('./api-Dwkm7s_E.cjs');
5
- require('./persistence-hbhwAYIV.cjs');
4
+ require('./api-CUTdFiFP.cjs');
5
+ require('./persistence-CxvL0cwp.cjs');
6
6
  require('zod');
7
- require('./index-CfqxEoyl.cjs');
7
+ require('./index-D4OdFq68.cjs');
8
8
  require('node:child_process');
9
9
  require('node:fs');
10
10
  require('cross-spawn');
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  import 'chalk';
2
- import './api-dwwHBzLc.mjs';
3
- import './persistence-Dg-rxY2a.mjs';
2
+ import './api-CnvyGas2.mjs';
3
+ import './persistence-BPV3AmJL.mjs';
4
4
  import 'zod';
5
- import './index-HyqLXzw-.mjs';
5
+ import './index-BpZL4RcT.mjs';
6
6
  import 'node:child_process';
7
7
  import 'node:fs';
8
8
  import 'cross-spawn';
package/dist/lib.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var api = require('./api-Dwkm7s_E.cjs');
3
+ var api = require('./api-CUTdFiFP.cjs');
4
4
  var types = require('./types-DVk3crez.cjs');
5
5
  require('axios');
6
6
  require('chalk');
package/dist/lib.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { A as ApiClient, a as ApiSessionClient, c as configuration, l as logger } from './api-dwwHBzLc.mjs';
1
+ export { A as ApiClient, a as ApiSessionClient, c as configuration, l as logger } from './api-CnvyGas2.mjs';
2
2
  export { R as RawJSONLinesSchema } from './types-CiliQpqS.mjs';
3
3
  import 'axios';
4
4
  import 'chalk';
@@ -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-dwwHBzLc.mjs';
4
- import { p as projectPath } from './index-HyqLXzw-.mjs';
3
+ import { c as configuration, p as packageJson, s as startOfflineReconnection, l as logger } from './api-CnvyGas2.mjs';
4
+ import { p as projectPath } from './index-BpZL4RcT.mjs';
5
5
  import { EventEmitter } from 'node:events';
6
6
  import { randomUUID } from 'node:crypto';
7
7
 
@@ -527,4 +527,99 @@ class BaseReasoningProcessor {
527
527
  }
528
528
  }
529
529
 
530
- export { BasePermissionHandler as B, INTERACTION_SUPERSEDED_ERROR as I, BaseReasoningProcessor as a, INTERACTION_TIMED_OUT_ERROR as b, createSessionMetadata as c, getPendingInteractionTimeoutMs as g, setupOfflineReconnection as s };
530
+ function inferToolResultError(result) {
531
+ if (!result || typeof result !== "object") {
532
+ return false;
533
+ }
534
+ const record = result;
535
+ if (record.isError === true || record.is_error === true) {
536
+ return true;
537
+ }
538
+ if (typeof record.error === "string" && record.error.trim().length > 0) {
539
+ return true;
540
+ }
541
+ if (record.success === false) {
542
+ return true;
543
+ }
544
+ const status = typeof record.status === "string" ? record.status.toLowerCase() : "";
545
+ return status === "failed" || status === "cancelled" || status === "error" || status === "denied" || status === "aborted";
546
+ }
547
+
548
+ function buildToolHappierMetaV2(input) {
549
+ return {
550
+ ...input,
551
+ v: 2
552
+ };
553
+ }
554
+ function attachToolHappierMetaV2(value, meta) {
555
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
556
+ return value;
557
+ }
558
+ return {
559
+ ...value,
560
+ _happier: buildToolHappierMetaV2(meta)
561
+ };
562
+ }
563
+
564
+ const KNOWN_CANONICAL_TOOL_NAMES_V2 = [
565
+ "Bash",
566
+ "Read",
567
+ "Write",
568
+ "Edit",
569
+ "MultiEdit",
570
+ "Delete",
571
+ "Patch",
572
+ "Diff",
573
+ "Glob",
574
+ "Grep",
575
+ "LS",
576
+ "CodeSearch",
577
+ "WebFetch",
578
+ "WebSearch",
579
+ "TodoWrite",
580
+ "TodoRead",
581
+ "Task",
582
+ "Reasoning",
583
+ "EnterPlanMode",
584
+ "ExitPlanMode",
585
+ "AskUserQuestion",
586
+ "AcpHistoryImport",
587
+ "WorkspaceIndexingPermission",
588
+ "SubAgentRun",
589
+ "AgentTeamCreate",
590
+ "AgentTeamDelete",
591
+ "AgentTeamSendMessage"
592
+ ];
593
+ const CANONICAL_TOOL_NAME_LOOKUP = new Map(
594
+ KNOWN_CANONICAL_TOOL_NAMES_V2.map((name) => [name.toLowerCase(), name])
595
+ );
596
+ const RAW_TO_CANONICAL_TOOL_NAME_LOOKUP = {
597
+ bash: "Bash",
598
+ shell: "Bash",
599
+ execute: "Bash",
600
+ codexbash: "Bash",
601
+ geminibash: "Bash",
602
+ codexpatch: "Patch",
603
+ geminipatch: "Patch"
604
+ };
605
+ function resolveCanonicalToolNameV2(rawToolName) {
606
+ const normalized = typeof rawToolName === "string" ? rawToolName.trim() : "";
607
+ if (!normalized) {
608
+ return "Bash";
609
+ }
610
+ if (normalized.startsWith("mcp__")) {
611
+ return normalized;
612
+ }
613
+ const lower = normalized.toLowerCase();
614
+ const known = CANONICAL_TOOL_NAME_LOOKUP.get(lower);
615
+ if (known) {
616
+ return known;
617
+ }
618
+ const mapped = RAW_TO_CANONICAL_TOOL_NAME_LOOKUP[lower];
619
+ if (mapped) {
620
+ return mapped;
621
+ }
622
+ return normalized;
623
+ }
624
+
625
+ export { BasePermissionHandler as B, INTERACTION_SUPERSEDED_ERROR as I, BaseReasoningProcessor as a, attachToolHappierMetaV2 as b, createSessionMetadata as c, INTERACTION_TIMED_OUT_ERROR as d, getPendingInteractionTimeoutMs as g, inferToolResultError as i, resolveCanonicalToolNameV2 as r, setupOfflineReconnection as s };