happy-imou-cloud 2.0.4 → 2.0.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 (24) hide show
  1. package/dist/{BaseReasoningProcessor-Di1yEMMv.mjs → BaseReasoningProcessor-1EzrE03x.mjs} +2 -2
  2. package/dist/{BaseReasoningProcessor-DEEfNi5Y.cjs → BaseReasoningProcessor-BMyfwx3p.cjs} +2 -2
  3. package/dist/{api-CyJG1mr6.cjs → api-DccDghmF.cjs} +5 -3
  4. package/dist/{api-CIHTNilH.mjs → api-Emo3rSZH.mjs} +5 -3
  5. package/dist/{command-CPlJKXDn.cjs → command-C2v0VkPq.cjs} +3 -3
  6. package/dist/{command-BERqmFB0.mjs → command-D8Zz6B4t.mjs} +3 -3
  7. package/dist/{index-1zlH6s7a.cjs → index-Buq7nurH.cjs} +368 -131
  8. package/dist/{index-vNYxNqVZ.mjs → index-Dh8UTgm4.mjs} +366 -129
  9. package/dist/index.cjs +5 -5
  10. package/dist/index.mjs +5 -5
  11. package/dist/lib.cjs +1 -1
  12. package/dist/lib.mjs +1 -1
  13. package/dist/{persistence-sLEqV8vk.mjs → persistence-Blm1hTQA.mjs} +1 -1
  14. package/dist/{persistence-BeFVx6kI.cjs → persistence-BrTyBuT7.cjs} +1 -1
  15. package/dist/{registerKillSessionHandler-uVHqIC4h.mjs → registerKillSessionHandler-Bm7E-03E.mjs} +2 -2
  16. package/dist/{registerKillSessionHandler-CCxqGFjZ.cjs → registerKillSessionHandler-EFAsOnR_.cjs} +2 -2
  17. package/dist/{runClaude-Dz-PCSvb.cjs → runClaude-COy1pLhn.cjs} +5 -5
  18. package/dist/{runClaude-Dl9nIRIg.mjs → runClaude-CwA5UCO-.mjs} +4 -4
  19. package/dist/{runCodex-BtZplK1R.cjs → runCodex-BRMOT2dJ.cjs} +53 -17
  20. package/dist/{runCodex-DgKKw3IU.mjs → runCodex-DTPmqCyS.mjs} +53 -17
  21. package/dist/{runGemini-DUyH311Z.cjs → runGemini-BVPmTGxQ.cjs} +51 -19
  22. package/dist/{runGemini-CM1v3I24.mjs → runGemini-DDSR8BtO.mjs} +51 -19
  23. package/package.json +3 -2
  24. package/scripts/release-smoke.mjs +4 -0
@@ -1,6 +1,6 @@
1
1
  import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import chalk from 'chalk';
2
- import { l as logger, e as encodeBase64, c as configuration, h as buildAuthenticatedHeaders, S as SigningBootstrapRequiredError, j as SIGNING_BOOTSTRAP_REQUIRED_MESSAGE, k as encodeBase64Url, f as delay, m as buildClientHeaders, n as decodeBase64, H as HAPPY_CLOUD_DAEMON_PORT, p as packageJson, A as ApiClient, o as getLatestDaemonLog } from './api-CIHTNilH.mjs';
3
- import { writeCredentialsLegacy, writeCredentialsDataKey, readCredentials, readSettings, updateSettings, readDaemonState, clearDaemonState, acquireDaemonLock, writeDaemonState, releaseDaemonLock, validateProfileForAgent, getProfileEnvironmentVariables, clearCredentials, clearMachineId } from './persistence-sLEqV8vk.mjs';
2
+ import { l as logger, e as encodeBase64, c as configuration, h as buildAuthenticatedHeaders, S as SigningBootstrapRequiredError, j as SIGNING_BOOTSTRAP_REQUIRED_MESSAGE, k as encodeBase64Url, f as delay, m as buildClientHeaders, n as decodeBase64, H as HAPPY_CLOUD_DAEMON_PORT, p as packageJson, A as ApiClient, o as getLatestDaemonLog } from './api-Emo3rSZH.mjs';
3
+ import { writeCredentialsLegacy, writeCredentialsDataKey, readCredentials, readSettings, updateSettings, readDaemonState, clearDaemonState, acquireDaemonLock, writeDaemonState, releaseDaemonLock, validateProfileForAgent, getProfileEnvironmentVariables, clearCredentials, clearMachineId } from './persistence-Blm1hTQA.mjs';
4
4
  import { z } from 'zod';
5
5
  import fs from 'fs/promises';
6
6
  import os, { homedir } from 'os';
@@ -4906,6 +4906,205 @@ function handleThinkingUpdate(update, ctx) {
4906
4906
  return { handled: true };
4907
4907
  }
4908
4908
 
4909
+ function buildAcpSpawnSpec(params) {
4910
+ return {
4911
+ command: params.command,
4912
+ args: (params.args ?? []).map((arg) => String(arg)),
4913
+ options: {
4914
+ cwd: params.cwd,
4915
+ env: params.env,
4916
+ stdio: ["pipe", "pipe", "pipe"],
4917
+ windowsHide: process.platform === "win32"
4918
+ }
4919
+ };
4920
+ }
4921
+
4922
+ function createAcpFilteredStdoutReadable(params) {
4923
+ const maxMultilineBytes = typeof params.maxMultilineBytes === "number" && Number.isFinite(params.maxMultilineBytes) && params.maxMultilineBytes > 0 ? Math.trunc(params.maxMultilineBytes) : 1e6;
4924
+ const decoder = new TextDecoder();
4925
+ const encoder = new TextEncoder();
4926
+ return new ReadableStream({
4927
+ async start(controller) {
4928
+ const reader = params.readable.getReader();
4929
+ let buffer = "";
4930
+ let multiline = null;
4931
+ let controllerErrored = false;
4932
+ const drop = (reason, line) => {
4933
+ params.onDroppedLine?.({ reason, line });
4934
+ };
4935
+ const enqueueLine = (line) => {
4936
+ if (!line.trim()) {
4937
+ return;
4938
+ }
4939
+ const filtered = params.transport.filterStdoutLine?.(line);
4940
+ if (filtered === void 0) {
4941
+ controller.enqueue(encoder.encode(line + "\n"));
4942
+ return;
4943
+ }
4944
+ if (filtered === null) {
4945
+ drop("transport_filter_null", line);
4946
+ return;
4947
+ }
4948
+ controller.enqueue(encoder.encode(filtered + "\n"));
4949
+ };
4950
+ const tryFlushMultiline = (candidate) => {
4951
+ const trimmed = candidate.trim();
4952
+ if (!trimmed) {
4953
+ return false;
4954
+ }
4955
+ if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
4956
+ return false;
4957
+ }
4958
+ try {
4959
+ const parsed = JSON.parse(trimmed);
4960
+ if (typeof parsed !== "object" || parsed === null) {
4961
+ return false;
4962
+ }
4963
+ enqueueLine(JSON.stringify(parsed));
4964
+ return true;
4965
+ } catch {
4966
+ return false;
4967
+ }
4968
+ };
4969
+ try {
4970
+ while (true) {
4971
+ const { value, done } = await reader.read();
4972
+ if (done) {
4973
+ break;
4974
+ }
4975
+ if (!value) {
4976
+ continue;
4977
+ }
4978
+ buffer += decoder.decode(value, { stream: true });
4979
+ const lines = buffer.split("\n");
4980
+ buffer = lines.pop() || "";
4981
+ for (const line of lines) {
4982
+ if (multiline) {
4983
+ const nextBuf = multiline.buf.length > 0 ? `${multiline.buf}
4984
+ ${line}` : line;
4985
+ const nextBytes = multiline.bytes + line.length + 1;
4986
+ if (nextBytes > maxMultilineBytes) {
4987
+ drop("multiline_overflow", multiline.buf);
4988
+ multiline = null;
4989
+ enqueueLine(line);
4990
+ continue;
4991
+ }
4992
+ multiline = { buf: nextBuf, bytes: nextBytes };
4993
+ if (tryFlushMultiline(multiline.buf)) {
4994
+ multiline = null;
4995
+ }
4996
+ continue;
4997
+ }
4998
+ const trimmed = line.trim();
4999
+ if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
5000
+ try {
5001
+ const parsed = JSON.parse(trimmed);
5002
+ if (typeof parsed === "object" && parsed !== null) {
5003
+ enqueueLine(line);
5004
+ continue;
5005
+ }
5006
+ } catch {
5007
+ multiline = { buf: line, bytes: line.length };
5008
+ continue;
5009
+ }
5010
+ }
5011
+ enqueueLine(line);
5012
+ }
5013
+ }
5014
+ if (multiline) {
5015
+ if (!tryFlushMultiline(multiline.buf)) {
5016
+ drop("multiline_incomplete", multiline.buf);
5017
+ }
5018
+ multiline = null;
5019
+ }
5020
+ const trailing = buffer.trim();
5021
+ if (trailing) {
5022
+ drop("multiline_incomplete", buffer);
5023
+ }
5024
+ } catch (error) {
5025
+ controllerErrored = true;
5026
+ controller.error(error);
5027
+ } finally {
5028
+ reader.releaseLock();
5029
+ if (!controllerErrored) {
5030
+ controller.close();
5031
+ }
5032
+ }
5033
+ }
5034
+ });
5035
+ }
5036
+
5037
+ function isAlive(pid) {
5038
+ try {
5039
+ process.kill(pid, 0);
5040
+ return true;
5041
+ } catch {
5042
+ return false;
5043
+ }
5044
+ }
5045
+ async function resolveDescendantPids(rootPid) {
5046
+ const processes = await psList();
5047
+ const childrenByParent = /* @__PURE__ */ new Map();
5048
+ for (const proc of processes) {
5049
+ if (typeof proc.pid !== "number" || typeof proc.ppid !== "number") {
5050
+ continue;
5051
+ }
5052
+ const children = childrenByParent.get(proc.ppid) ?? [];
5053
+ children.push(proc.pid);
5054
+ childrenByParent.set(proc.ppid, children);
5055
+ }
5056
+ const descendants = [];
5057
+ const seen = /* @__PURE__ */ new Set();
5058
+ const visit = (pid) => {
5059
+ for (const childPid of childrenByParent.get(pid) ?? []) {
5060
+ if (seen.has(childPid)) {
5061
+ continue;
5062
+ }
5063
+ seen.add(childPid);
5064
+ visit(childPid);
5065
+ descendants.push(childPid);
5066
+ }
5067
+ };
5068
+ visit(rootPid);
5069
+ return descendants;
5070
+ }
5071
+ function bestEffortKillPid(pid, signal) {
5072
+ try {
5073
+ process.kill(pid, signal);
5074
+ } catch {
5075
+ }
5076
+ }
5077
+ async function waitForAllGone(pids, timeoutMs) {
5078
+ const start = Date.now();
5079
+ while (Date.now() - start < timeoutMs) {
5080
+ if (pids.every((pid) => !isAlive(pid))) {
5081
+ return;
5082
+ }
5083
+ await new Promise((resolve) => setTimeout(resolve, 25));
5084
+ }
5085
+ }
5086
+ async function killProcessTree(proc, options) {
5087
+ const pid = proc.pid;
5088
+ if (!pid) {
5089
+ return;
5090
+ }
5091
+ const graceMs = Math.max(1, options?.graceMs);
5092
+ const descendants = await resolveDescendantPids(pid).catch(() => []);
5093
+ const allPids = [...descendants, pid];
5094
+ for (const targetPid of allPids) {
5095
+ bestEffortKillPid(targetPid, "SIGTERM");
5096
+ }
5097
+ await waitForAllGone(allPids, graceMs);
5098
+ const remaining = allPids.filter((targetPid) => isAlive(targetPid));
5099
+ if (remaining.length === 0) {
5100
+ return;
5101
+ }
5102
+ for (const targetPid of remaining) {
5103
+ bestEffortKillPid(targetPid, "SIGKILL");
5104
+ }
5105
+ await waitForAllGone(remaining, Math.min(250, graceMs));
5106
+ }
5107
+
4909
5108
  const RETRY_CONFIG = {
4910
5109
  /** Maximum number of retry attempts for init/newSession */
4911
5110
  maxAttempts: 3,
@@ -5042,15 +5241,17 @@ async function withRetry(operation, options) {
5042
5241
  return await operation();
5043
5242
  } catch (error) {
5044
5243
  lastError = normalizeAcpError(error);
5045
- if (attempt < options.maxAttempts) {
5046
- const delayMs = Math.min(
5047
- options.baseDelayMs * Math.pow(2, attempt - 1),
5048
- options.maxDelayMs
5049
- );
5050
- logger.debug(`[AcpBackend] ${options.operationName} failed (attempt ${attempt}/${options.maxAttempts}): ${lastError.message}. Retrying in ${delayMs}ms...`);
5051
- options.onRetry?.(attempt, lastError);
5052
- await delay(delayMs);
5244
+ const retryable = options.shouldRetry?.(lastError) ?? true;
5245
+ if (!retryable || attempt >= options.maxAttempts) {
5246
+ throw lastError;
5053
5247
  }
5248
+ const delayMs = Math.min(
5249
+ options.baseDelayMs * Math.pow(2, attempt - 1),
5250
+ options.maxDelayMs
5251
+ );
5252
+ logger.debug(`[AcpBackend] ${options.operationName} failed (attempt ${attempt}/${options.maxAttempts}): ${lastError.message}. Retrying in ${delayMs}ms...`);
5253
+ options.onRetry?.(attempt, lastError);
5254
+ await delay(delayMs);
5054
5255
  }
5055
5256
  }
5056
5257
  throw lastError;
@@ -5103,6 +5304,77 @@ function enrichAcpError(error, stderrExcerpt) {
5103
5304
  }
5104
5305
  return normalized;
5105
5306
  }
5307
+ class AcpProcessStartupError extends Error {
5308
+ constructor(message, exitCode, signal) {
5309
+ super(message);
5310
+ this.exitCode = exitCode;
5311
+ this.signal = signal;
5312
+ this.name = "AcpProcessStartupError";
5313
+ }
5314
+ }
5315
+ function createProcessStartupError(agentName, operationName, code, signal) {
5316
+ if (code !== null) {
5317
+ return new AcpProcessStartupError(
5318
+ `${agentName} exited with code ${code} during ${operationName}`,
5319
+ code,
5320
+ signal
5321
+ );
5322
+ }
5323
+ if (signal) {
5324
+ return new AcpProcessStartupError(
5325
+ `${agentName} exited due to signal ${signal} during ${operationName}`,
5326
+ code,
5327
+ signal
5328
+ );
5329
+ }
5330
+ return new AcpProcessStartupError(
5331
+ `${agentName} exited unexpectedly during ${operationName}`,
5332
+ code,
5333
+ signal
5334
+ );
5335
+ }
5336
+ async function raceWithProcessExit(childProcess, operation, options) {
5337
+ if (childProcess.exitCode !== null) {
5338
+ throw createProcessStartupError(
5339
+ options.agentName,
5340
+ options.operationName,
5341
+ childProcess.exitCode,
5342
+ childProcess.signalCode ?? null
5343
+ );
5344
+ }
5345
+ return await new Promise((resolve, reject) => {
5346
+ let settled = false;
5347
+ const cleanup = () => {
5348
+ childProcess.off("error", handleError);
5349
+ childProcess.off("exit", handleExit);
5350
+ };
5351
+ const settleResolve = (value) => {
5352
+ if (settled) {
5353
+ return;
5354
+ }
5355
+ settled = true;
5356
+ cleanup();
5357
+ resolve(value);
5358
+ };
5359
+ const settleReject = (error) => {
5360
+ if (settled) {
5361
+ return;
5362
+ }
5363
+ settled = true;
5364
+ cleanup();
5365
+ reject(normalizeAcpError(error));
5366
+ };
5367
+ const handleError = (error) => {
5368
+ settleReject(error);
5369
+ };
5370
+ const handleExit = (code, signal) => {
5371
+ settleReject(createProcessStartupError(options.agentName, options.operationName, code, signal));
5372
+ };
5373
+ childProcess.once("error", handleError);
5374
+ childProcess.once("exit", handleExit);
5375
+ operation.then(settleResolve, settleReject);
5376
+ });
5377
+ }
5106
5378
  class AcpBackend {
5107
5379
  constructor(options) {
5108
5380
  this.options = options;
@@ -5221,24 +5493,13 @@ class AcpBackend {
5221
5493
  try {
5222
5494
  logger.debug(`[AcpBackend] Starting session: ${sessionId}`);
5223
5495
  this.recentStderrLines = [];
5224
- const args = this.options.args || [];
5225
- if (process.platform === "win32") {
5226
- const fullCommand = [this.options.command, ...args].join(" ");
5227
- this.process = spawn$2("cmd.exe", ["/c", fullCommand], {
5228
- cwd: this.options.cwd,
5229
- env: { ...process.env, ...this.options.env },
5230
- stdio: ["pipe", "pipe", "pipe"],
5231
- windowsHide: true
5232
- });
5233
- } else {
5234
- this.process = spawn$2(this.options.command, args, {
5235
- cwd: this.options.cwd,
5236
- env: { ...process.env, ...this.options.env },
5237
- // Use 'pipe' for all stdio to capture output without printing to console
5238
- // stdout and stderr will be handled by our event listeners
5239
- stdio: ["pipe", "pipe", "pipe"]
5240
- });
5241
- }
5496
+ const spawnSpec = buildAcpSpawnSpec({
5497
+ command: this.options.command,
5498
+ args: this.options.args ?? [],
5499
+ cwd: this.options.cwd,
5500
+ env: { ...process.env, ...this.options.env }
5501
+ });
5502
+ this.process = spawn$1(spawnSpec.command, spawnSpec.args, spawnSpec.options);
5242
5503
  if (this.process.stderr) {
5243
5504
  }
5244
5505
  if (!this.process.stdin || !this.process.stdout || !this.process.stderr) {
@@ -5286,57 +5547,20 @@ class AcpBackend {
5286
5547
  );
5287
5548
  const writable = streams.writable;
5288
5549
  const readable = streams.readable;
5289
- const transport = this.transport;
5290
- const filteredReadable = new ReadableStream({
5291
- async start(controller) {
5292
- const reader = readable.getReader();
5293
- const decoder = new TextDecoder();
5294
- const encoder = new TextEncoder();
5295
- let buffer = "";
5296
- let filteredCount = 0;
5297
- try {
5298
- while (true) {
5299
- const { done, value } = await reader.read();
5300
- if (done) {
5301
- if (buffer.trim()) {
5302
- const filtered = transport.filterStdoutLine?.(buffer);
5303
- if (filtered === void 0) {
5304
- controller.enqueue(encoder.encode(buffer));
5305
- } else if (filtered !== null) {
5306
- controller.enqueue(encoder.encode(filtered));
5307
- } else {
5308
- filteredCount++;
5309
- }
5310
- }
5311
- if (filteredCount > 0) {
5312
- logger.debug(`[AcpBackend] Filtered out ${filteredCount} non-JSON lines from ${transport.agentName} stdout`);
5313
- }
5314
- controller.close();
5315
- break;
5316
- }
5317
- buffer += decoder.decode(value, { stream: true });
5318
- const lines = buffer.split("\n");
5319
- buffer = lines.pop() || "";
5320
- for (const line of lines) {
5321
- if (!line.trim()) continue;
5322
- const filtered = transport.filterStdoutLine?.(line);
5323
- if (filtered === void 0) {
5324
- controller.enqueue(encoder.encode(line + "\n"));
5325
- } else if (filtered !== null) {
5326
- controller.enqueue(encoder.encode(filtered + "\n"));
5327
- } else {
5328
- filteredCount++;
5329
- }
5330
- }
5331
- }
5332
- } catch (error) {
5333
- logger.debug(`[AcpBackend] Error filtering stdout stream:`, error);
5334
- controller.error(error);
5335
- } finally {
5336
- reader.releaseLock();
5337
- }
5550
+ const droppedStdoutLines = [];
5551
+ const filteredReadable = createAcpFilteredStdoutReadable({
5552
+ readable,
5553
+ transport: this.transport,
5554
+ onDroppedLine: (entry) => {
5555
+ droppedStdoutLines.push(entry);
5338
5556
  }
5339
5557
  });
5558
+ if (droppedStdoutLines.length > 0) {
5559
+ logger.debug(
5560
+ `[AcpBackend] Filtered out ${droppedStdoutLines.length} stdout lines from ${this.transport.agentName}`,
5561
+ droppedStdoutLines.slice(0, 5)
5562
+ );
5563
+ }
5340
5564
  const stream = ndJsonStream(writable, filteredReadable);
5341
5565
  const client = {
5342
5566
  sessionUpdate: async (params) => {
@@ -5503,20 +5727,27 @@ class AcpBackend {
5503
5727
  async () => {
5504
5728
  let timeoutHandle = null;
5505
5729
  try {
5506
- const result = await Promise.race([
5507
- this.connection.initialize(initRequest).then((res) => {
5508
- if (timeoutHandle) {
5509
- clearTimeout(timeoutHandle);
5510
- timeoutHandle = null;
5511
- }
5512
- return res;
5513
- }),
5514
- new Promise((_, reject) => {
5515
- timeoutHandle = setTimeout(() => {
5516
- reject(new Error(`Initialize timeout after ${initTimeout}ms - ${this.transport.agentName} did not respond`));
5517
- }, initTimeout);
5518
- })
5519
- ]);
5730
+ const result = await raceWithProcessExit(
5731
+ this.process,
5732
+ Promise.race([
5733
+ this.connection.initialize(initRequest).then((res) => {
5734
+ if (timeoutHandle) {
5735
+ clearTimeout(timeoutHandle);
5736
+ timeoutHandle = null;
5737
+ }
5738
+ return res;
5739
+ }),
5740
+ new Promise((_, reject) => {
5741
+ timeoutHandle = setTimeout(() => {
5742
+ reject(new Error(`Initialize timeout after ${initTimeout}ms - ${this.transport.agentName} did not respond`));
5743
+ }, initTimeout);
5744
+ })
5745
+ ]),
5746
+ {
5747
+ agentName: this.transport.agentName,
5748
+ operationName: "initialize"
5749
+ }
5750
+ );
5520
5751
  return result;
5521
5752
  } finally {
5522
5753
  if (timeoutHandle) {
@@ -5528,7 +5759,8 @@ class AcpBackend {
5528
5759
  operationName: "Initialize",
5529
5760
  maxAttempts: RETRY_CONFIG.maxAttempts,
5530
5761
  baseDelayMs: RETRY_CONFIG.baseDelayMs,
5531
- maxDelayMs: RETRY_CONFIG.maxDelayMs
5762
+ maxDelayMs: RETRY_CONFIG.maxDelayMs,
5763
+ shouldRetry: (error) => !(error instanceof AcpProcessStartupError)
5532
5764
  }
5533
5765
  );
5534
5766
  logger.debug(`[AcpBackend] Initialize completed`);
@@ -5547,20 +5779,27 @@ class AcpBackend {
5547
5779
  async () => {
5548
5780
  let timeoutHandle = null;
5549
5781
  try {
5550
- const result = await Promise.race([
5551
- this.connection.newSession(newSessionRequest).then((res) => {
5552
- if (timeoutHandle) {
5553
- clearTimeout(timeoutHandle);
5554
- timeoutHandle = null;
5555
- }
5556
- return res;
5557
- }),
5558
- new Promise((_, reject) => {
5559
- timeoutHandle = setTimeout(() => {
5560
- reject(new Error(`New session timeout after ${initTimeout}ms - ${this.transport.agentName} did not respond`));
5561
- }, initTimeout);
5562
- })
5563
- ]);
5782
+ const result = await raceWithProcessExit(
5783
+ this.process,
5784
+ Promise.race([
5785
+ this.connection.newSession(newSessionRequest).then((res) => {
5786
+ if (timeoutHandle) {
5787
+ clearTimeout(timeoutHandle);
5788
+ timeoutHandle = null;
5789
+ }
5790
+ return res;
5791
+ }),
5792
+ new Promise((_, reject) => {
5793
+ timeoutHandle = setTimeout(() => {
5794
+ reject(new Error(`New session timeout after ${initTimeout}ms - ${this.transport.agentName} did not respond`));
5795
+ }, initTimeout);
5796
+ })
5797
+ ]),
5798
+ {
5799
+ agentName: this.transport.agentName,
5800
+ operationName: "new session"
5801
+ }
5802
+ );
5564
5803
  return result;
5565
5804
  } finally {
5566
5805
  if (timeoutHandle) {
@@ -5572,7 +5811,8 @@ class AcpBackend {
5572
5811
  operationName: "NewSession",
5573
5812
  maxAttempts: RETRY_CONFIG.maxAttempts,
5574
5813
  baseDelayMs: RETRY_CONFIG.baseDelayMs,
5575
- maxDelayMs: RETRY_CONFIG.maxDelayMs
5814
+ maxDelayMs: RETRY_CONFIG.maxDelayMs,
5815
+ shouldRetry: (error) => !(error instanceof AcpProcessStartupError)
5576
5816
  }
5577
5817
  );
5578
5818
  this.acpSessionId = sessionResponse.sessionId;
@@ -5848,21 +6088,13 @@ class AcpBackend {
5848
6088
  }
5849
6089
  }
5850
6090
  if (this.process) {
5851
- this.process.kill("SIGTERM");
5852
- await new Promise((resolve) => {
5853
- const timeout = setTimeout(() => {
5854
- if (this.process) {
5855
- logger.debug("[AcpBackend] Force killing process");
5856
- this.process.kill("SIGKILL");
5857
- }
5858
- resolve();
5859
- }, 1e3);
5860
- this.process?.once("exit", () => {
5861
- clearTimeout(timeout);
5862
- resolve();
5863
- });
5864
- });
5865
- this.process = null;
6091
+ try {
6092
+ await killProcessTree(this.process, { graceMs: 1e3 });
6093
+ } catch (error) {
6094
+ logger.debug("[AcpBackend] Failed to kill ACP process tree:", error);
6095
+ } finally {
6096
+ this.process = null;
6097
+ }
5866
6098
  }
5867
6099
  this.clearIdleTimeoutState();
5868
6100
  this.listeners = [];
@@ -6103,6 +6335,7 @@ function registerGeminiAgent() {
6103
6335
  logger.debug("[Gemini] Registered with agent registry");
6104
6336
  }
6105
6337
 
6338
+ const DEFAULT_CODEX_ACP_NPX_PACKAGE = "@zed-industries/codex-acp@0.9.5";
6106
6339
  function readFirstEnv(...names) {
6107
6340
  for (const name of names) {
6108
6341
  const raw = process.env[name];
@@ -6157,6 +6390,10 @@ function readCodexAcpNpxMode() {
6157
6390
  }
6158
6391
  return "auto";
6159
6392
  }
6393
+ function readCodexAcpNpxPackage() {
6394
+ const configured = readFirstEnv("HAPPY_CODEX_ACP_PACKAGE", "HAPPIER_CODEX_ACP_PACKAGE");
6395
+ return configured || DEFAULT_CODEX_ACP_NPX_PACKAGE;
6396
+ }
6160
6397
  function isBinOnPath(baseName) {
6161
6398
  return resolveCommandOnPath(baseName) !== null;
6162
6399
  }
@@ -6222,7 +6459,7 @@ function resolveCodexAcpSpawn(options = {}) {
6222
6459
  }
6223
6460
  return {
6224
6461
  command: resolveNpxCommand(),
6225
- args: ["--prefer-offline", "-y", "@zed-industries/codex-acp", ...directArgs]
6462
+ args: ["--prefer-offline", "-y", readCodexAcpNpxPackage(), ...directArgs]
6226
6463
  };
6227
6464
  }
6228
6465
  function validateCodexAcpSpawn(options = {}) {
@@ -6509,12 +6746,12 @@ async function ensureUnifiedDaemonStarted() {
6509
6746
  async function executeUnifiedProvider(opts) {
6510
6747
  const credentials = await ensureUnifiedRuntimePrerequisites(opts.credentials);
6511
6748
  if (opts.provider === "claude") {
6512
- const { runClaude } = await import('./runClaude-Dl9nIRIg.mjs');
6749
+ const { runClaude } = await import('./runClaude-CwA5UCO-.mjs');
6513
6750
  await runClaude(credentials, opts.claudeOptions ?? {});
6514
6751
  return;
6515
6752
  }
6516
6753
  if (opts.provider === "codex") {
6517
- const { runCodex } = await import('./runCodex-DgKKw3IU.mjs');
6754
+ const { runCodex } = await import('./runCodex-DTPmqCyS.mjs');
6518
6755
  await runCodex({
6519
6756
  credentials,
6520
6757
  startedBy: opts.startedBy,
@@ -6524,7 +6761,7 @@ async function executeUnifiedProvider(opts) {
6524
6761
  return;
6525
6762
  }
6526
6763
  if (opts.provider === "gemini") {
6527
- const { runGemini } = await import('./runGemini-CM1v3I24.mjs');
6764
+ const { runGemini } = await import('./runGemini-DDSR8BtO.mjs');
6528
6765
  await runGemini({
6529
6766
  credentials,
6530
6767
  startedBy: opts.startedBy
@@ -6566,7 +6803,7 @@ function shouldRunMainClaudeFlow(opts) {
6566
6803
  return;
6567
6804
  } else if (subcommand === "runtime") {
6568
6805
  if (args[1] === "providers") {
6569
- const { renderRuntimeProviders } = await import('./command-BERqmFB0.mjs');
6806
+ const { renderRuntimeProviders } = await import('./command-D8Zz6B4t.mjs');
6570
6807
  console.log(renderRuntimeProviders());
6571
6808
  return;
6572
6809
  }
@@ -6744,8 +6981,8 @@ function shouldRunMainClaudeFlow(opts) {
6744
6981
  const projectId = args[3];
6745
6982
  try {
6746
6983
  const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return config; });
6747
- const { readCredentials: readCredentials2 } = await import('./persistence-sLEqV8vk.mjs');
6748
- const { ApiClient: ApiClient2 } = await import('./api-CIHTNilH.mjs').then(function (n) { return n.q; });
6984
+ const { readCredentials: readCredentials2 } = await import('./persistence-Blm1hTQA.mjs');
6985
+ const { ApiClient: ApiClient2 } = await import('./api-Emo3rSZH.mjs').then(function (n) { return n.q; });
6749
6986
  let userEmail = void 0;
6750
6987
  try {
6751
6988
  const credentials = await readCredentials2();
package/dist/index.cjs CHANGED
@@ -1,14 +1,16 @@
1
1
  'use strict';
2
2
 
3
3
  require('chalk');
4
- require('./api-CyJG1mr6.cjs');
5
- require('./persistence-BeFVx6kI.cjs');
4
+ require('./api-DccDghmF.cjs');
5
+ require('./persistence-BrTyBuT7.cjs');
6
6
  require('zod');
7
- require('./index-1zlH6s7a.cjs');
7
+ require('./index-Buq7nurH.cjs');
8
8
  require('node:child_process');
9
9
  require('node:fs');
10
+ require('cross-spawn');
10
11
  require('@agentclientprotocol/sdk');
11
12
  require('node:crypto');
13
+ require('ps-list');
12
14
  require('fs');
13
15
  require('path');
14
16
  require('os');
@@ -31,8 +33,6 @@ require('open');
31
33
  require('react');
32
34
  require('ink');
33
35
  require('url');
34
- require('ps-list');
35
- require('cross-spawn');
36
36
  require('fastify');
37
37
  require('fastify-type-provider-zod');
38
38
  require('node:readline');
package/dist/index.mjs CHANGED
@@ -1,12 +1,14 @@
1
1
  import 'chalk';
2
- import './api-CIHTNilH.mjs';
3
- import './persistence-sLEqV8vk.mjs';
2
+ import './api-Emo3rSZH.mjs';
3
+ import './persistence-Blm1hTQA.mjs';
4
4
  import 'zod';
5
- import './index-vNYxNqVZ.mjs';
5
+ import './index-Dh8UTgm4.mjs';
6
6
  import 'node:child_process';
7
7
  import 'node:fs';
8
+ import 'cross-spawn';
8
9
  import '@agentclientprotocol/sdk';
9
10
  import 'node:crypto';
11
+ import 'ps-list';
10
12
  import 'fs';
11
13
  import 'path';
12
14
  import 'os';
@@ -29,8 +31,6 @@ import 'open';
29
31
  import 'react';
30
32
  import 'ink';
31
33
  import 'url';
32
- import 'ps-list';
33
- import 'cross-spawn';
34
34
  import 'fastify';
35
35
  import 'fastify-type-provider-zod';
36
36
  import 'node:readline';
package/dist/lib.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var api = require('./api-CyJG1mr6.cjs');
3
+ var api = require('./api-DccDghmF.cjs');
4
4
  var types = require('./types-DVk3crez.cjs');
5
5
  require('axios');
6
6
  require('chalk');