happy-imou-cloud 2.0.16 → 2.0.17

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 (31) hide show
  1. package/bin/happy-cloud.mjs +1 -1
  2. package/dist/{BaseReasoningProcessor-BqMAZlIw.cjs → BaseReasoningProcessor-BdbyUAZR.cjs} +3 -3
  3. package/dist/{BaseReasoningProcessor-C04_LHjN.mjs → BaseReasoningProcessor-wqWUBiEJ.mjs} +3 -3
  4. package/dist/{ProviderSelectionHandler-CO9NkAt6.cjs → ProviderSelectionHandler-GuW6S0tQ.cjs} +2 -2
  5. package/dist/{ProviderSelectionHandler-DDWyn9Lo.mjs → ProviderSelectionHandler-oz9NjR_r.mjs} +2 -2
  6. package/dist/{api-Db1SQcP_.cjs → api-BZ2U3k-r.cjs} +90 -37
  7. package/dist/{api-sRF6xXi-.mjs → api-D7DleJYY.mjs} +90 -38
  8. package/dist/{command-eRjSBm2C.cjs → command-D-GEzmAl.cjs} +3 -3
  9. package/dist/{command-WcgGTRnG.mjs → command-DsMlcxQd.mjs} +3 -3
  10. package/dist/{index-DpWeKfvS.mjs → index-Cdi5KxhK.mjs} +77 -25
  11. package/dist/{index-B6ID1zDR.cjs → index-sJfKgN1y.cjs} +80 -28
  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.mjs +1 -1
  16. package/dist/{persistence-B89V4xY5.mjs → persistence-C0nC4mEU.mjs} +1 -1
  17. package/dist/{persistence-Btu2VPXI.cjs → persistence-JEXs_kBA.cjs} +1 -1
  18. package/dist/{registerKillSessionHandler-CwmYlUfS.mjs → registerKillSessionHandler-BRfDcq3x.mjs} +3 -3
  19. package/dist/{registerKillSessionHandler-eZ2TsHqx.cjs → registerKillSessionHandler-Qw8jZB2x.cjs} +3 -3
  20. package/dist/{runClaude-kRPXCaBj.mjs → runClaude-B6fsu9Sl.mjs} +5 -5
  21. package/dist/{runClaude-C9-ylbQh.cjs → runClaude-pSj5zGWV.cjs} +5 -5
  22. package/dist/{runCodex-CRNBxY5f.cjs → runCodex-ClpKXo66.cjs} +27 -8
  23. package/dist/{runCodex-B1xN0wAU.mjs → runCodex-DJrzw9x8.mjs} +27 -8
  24. package/dist/{runGemini-Xn2VwS88.mjs → runGemini-C7xlDIfO.mjs} +5 -5
  25. package/dist/{runGemini-BZ5hqJyl.cjs → runGemini-DA5v_0X_.cjs} +5 -5
  26. package/package.json +1 -1
  27. package/scripts/build.mjs +66 -66
  28. package/scripts/devtools/README.md +9 -9
  29. package/scripts/e2e/fake-codex-acp-agent.mjs +139 -139
  30. package/scripts/e2e/local-server-session-roundtrip.mjs +1063 -1063
  31. package/scripts/release-smoke.mjs +20 -17
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  import { execFileSync } from 'child_process';
4
4
  import { fileURLToPath } from 'url';
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-B6ID1zDR.cjs');
4
- var api = require('./api-Db1SQcP_.cjs');
5
- var registerKillSessionHandler = require('./registerKillSessionHandler-eZ2TsHqx.cjs');
3
+ var index = require('./index-sJfKgN1y.cjs');
4
+ var api = require('./api-BZ2U3k-r.cjs');
5
+ var registerKillSessionHandler = require('./registerKillSessionHandler-Qw8jZB2x.cjs');
6
6
  var node_events = require('node:events');
7
7
  var node_crypto = require('node:crypto');
8
8
 
@@ -1,6 +1,6 @@
1
- import { p as publishSessionRegistration } from './index-DpWeKfvS.mjs';
2
- import { s as startOfflineReconnection, c as configuration, i as isAuthenticationRequiredError, l as logger } from './api-sRF6xXi-.mjs';
3
- import { c as createSessionMetadata } from './registerKillSessionHandler-CwmYlUfS.mjs';
1
+ import { p as publishSessionRegistration } from './index-Cdi5KxhK.mjs';
2
+ import { s as startOfflineReconnection, c as configuration, i as isAuthenticationRequiredError, l as logger } from './api-D7DleJYY.mjs';
3
+ import { c as createSessionMetadata } from './registerKillSessionHandler-BRfDcq3x.mjs';
4
4
  import { EventEmitter } from 'node:events';
5
5
  import { randomUUID } from 'node:crypto';
6
6
 
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var api = require('./api-Db1SQcP_.cjs');
4
- var registerKillSessionHandler = require('./registerKillSessionHandler-eZ2TsHqx.cjs');
3
+ var api = require('./api-BZ2U3k-r.cjs');
4
+ var registerKillSessionHandler = require('./registerKillSessionHandler-Qw8jZB2x.cjs');
5
5
 
6
6
  async function runModeLoop(opts) {
7
7
  let currentMode = opts.startingMode;
@@ -1,5 +1,5 @@
1
- import { l as logger } from './api-sRF6xXi-.mjs';
2
- import { g as getPendingInteractionTimeoutMs, I as INTERACTION_SUPERSEDED_ERROR, a as INTERACTION_TIMED_OUT_ERROR } from './registerKillSessionHandler-CwmYlUfS.mjs';
1
+ import { l as logger } from './api-D7DleJYY.mjs';
2
+ import { g as getPendingInteractionTimeoutMs, I as INTERACTION_SUPERSEDED_ERROR, a as INTERACTION_TIMED_OUT_ERROR } from './registerKillSessionHandler-BRfDcq3x.mjs';
3
3
 
4
4
  async function runModeLoop(opts) {
5
5
  let currentMode = opts.startingMode;
@@ -18,7 +18,7 @@ var node_child_process = require('node:child_process');
18
18
  var expoServerSdk = require('expo-server-sdk');
19
19
 
20
20
  var name = "happy-imou-cloud";
21
- var version = "2.0.16";
21
+ var version = "2.0.17";
22
22
  var description = "hicloud - Imou 企业定制版。关键是 happy!移动端远程 AI 编程工具,支持 Claude Code、Codex 和 Gemini CLI";
23
23
  var author = "long.zhu";
24
24
  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-Btu2VPXI.cjs'); });
435
+ const { readDaemonState } = await Promise.resolve().then(function () { return require('./persistence-JEXs_kBA.cjs'); });
436
436
  const state = await readDaemonState();
437
437
  if (!state) {
438
438
  return logs;
@@ -867,51 +867,103 @@ function validatePath(targetPath, workingDirectory) {
867
867
  return { valid: true };
868
868
  }
869
869
 
870
- const DEFAULT_SHELL_COMMAND_TIMEOUT_MS = 3e4;
871
- const DEFAULT_SHELL_OUTPUT_MAX_BYTES = 256 * 1024;
872
- class BoundedTailBuffer {
873
- chunks = [];
874
- maxBytes;
875
- storedBytes = 0;
876
- receivedBytes = 0;
877
- constructor(maxBytes) {
878
- this.maxBytes = Math.max(1, maxBytes);
870
+ class HeadTailPreviewBuffer {
871
+ headBytes;
872
+ tailBytes;
873
+ totalPreviewBytes;
874
+ totalBytes = 0;
875
+ truncated = false;
876
+ fullChunks = [];
877
+ fullBytes = 0;
878
+ head = Buffer.alloc(0);
879
+ tailChunks = [];
880
+ tailStoredBytes = 0;
881
+ constructor(headBytes, tailBytes) {
882
+ this.headBytes = Math.max(0, headBytes);
883
+ this.tailBytes = Math.max(0, tailBytes);
884
+ this.totalPreviewBytes = this.headBytes + this.tailBytes;
879
885
  }
880
886
  append(chunk) {
881
887
  const normalized = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
882
888
  if (normalized.length === 0) {
883
889
  return;
884
890
  }
885
- this.receivedBytes += normalized.length;
886
- this.chunks.push(normalized);
887
- this.storedBytes += normalized.length;
888
- while (this.storedBytes > this.maxBytes && this.chunks.length > 0) {
889
- const overflow = this.storedBytes - this.maxBytes;
890
- const oldest = this.chunks[0];
891
- if (oldest.length <= overflow) {
892
- this.chunks.shift();
893
- this.storedBytes -= oldest.length;
894
- continue;
891
+ this.totalBytes += normalized.length;
892
+ if (!this.truncated) {
893
+ this.fullChunks.push(normalized);
894
+ this.fullBytes += normalized.length;
895
+ if (this.fullBytes > this.totalPreviewBytes) {
896
+ const full = Buffer.concat(this.fullChunks);
897
+ this.truncated = true;
898
+ this.fullChunks = [];
899
+ this.fullBytes = 0;
900
+ this.head = this.headBytes > 0 ? full.subarray(0, this.headBytes) : Buffer.alloc(0);
901
+ this.tailChunks = [];
902
+ this.tailStoredBytes = 0;
903
+ if (this.tailBytes > 0) {
904
+ this.appendTail(full.subarray(Math.max(0, full.length - this.tailBytes)));
905
+ }
895
906
  }
896
- this.chunks[0] = oldest.subarray(overflow);
897
- this.storedBytes -= overflow;
907
+ return;
908
+ }
909
+ this.appendTail(normalized);
910
+ }
911
+ render(label) {
912
+ if (!this.truncated) {
913
+ return Buffer.concat(this.fullChunks).toString("utf8");
914
+ }
915
+ const parts = [
916
+ `...[${label} truncated, showing first ${this.headBytes} bytes and last ${this.tailBytes} bytes of ${this.totalBytes}]`
917
+ ];
918
+ const headText = this.head.toString("utf8");
919
+ const tailText = Buffer.concat(this.tailChunks).toString("utf8");
920
+ if (headText.length > 0) {
921
+ parts.push(headText);
922
+ }
923
+ if (tailText.length > 0) {
924
+ parts.push("...");
925
+ parts.push(tailText);
898
926
  }
927
+ return parts.join("\n");
899
928
  }
900
- toString(label) {
901
- const content = Buffer.concat(this.chunks).toString("utf8");
902
- if (this.receivedBytes <= this.maxBytes) {
903
- return content;
929
+ getTotalBytes() {
930
+ return this.totalBytes;
931
+ }
932
+ isTruncated() {
933
+ return this.truncated;
934
+ }
935
+ appendTail(chunk) {
936
+ if (chunk.length === 0 || this.tailBytes === 0) {
937
+ return;
938
+ }
939
+ this.tailChunks.push(chunk);
940
+ this.tailStoredBytes += chunk.length;
941
+ while (this.tailStoredBytes > this.tailBytes && this.tailChunks.length > 0) {
942
+ const overflow = this.tailStoredBytes - this.tailBytes;
943
+ const oldest = this.tailChunks[0];
944
+ if (oldest.length <= overflow) {
945
+ this.tailChunks.shift();
946
+ this.tailStoredBytes -= oldest.length;
947
+ continue;
948
+ }
949
+ this.tailChunks[0] = oldest.subarray(overflow);
950
+ this.tailStoredBytes -= overflow;
904
951
  }
905
- return `...[${label} truncated, showing last ${this.maxBytes} bytes of ${this.receivedBytes}]
906
- ${content}`;
907
952
  }
908
953
  }
954
+
955
+ const DEFAULT_SHELL_COMMAND_TIMEOUT_MS = 3e4;
956
+ const DEFAULT_SHELL_OUTPUT_PREVIEW_HEAD_BYTES = 2e3;
957
+ const DEFAULT_SHELL_OUTPUT_PREVIEW_TAIL_BYTES = 4e3;
958
+ const DEFAULT_SHELL_OUTPUT_MAX_BYTES = DEFAULT_SHELL_OUTPUT_PREVIEW_HEAD_BYTES + DEFAULT_SHELL_OUTPUT_PREVIEW_TAIL_BYTES;
909
959
  async function runShellCommand(opts) {
910
960
  const timeoutMs = opts.timeoutMs ?? DEFAULT_SHELL_COMMAND_TIMEOUT_MS;
911
961
  const maxOutputBytes = opts.maxOutputBytes ?? DEFAULT_SHELL_OUTPUT_MAX_BYTES;
962
+ const previewHeadBytes = opts.previewHeadBytes ?? Math.min(DEFAULT_SHELL_OUTPUT_PREVIEW_HEAD_BYTES, maxOutputBytes);
963
+ const previewTailBytes = opts.previewTailBytes ?? Math.max(0, maxOutputBytes - previewHeadBytes);
912
964
  return await new Promise((resolve) => {
913
- const stdout = new BoundedTailBuffer(maxOutputBytes);
914
- const stderr = new BoundedTailBuffer(maxOutputBytes);
965
+ const stdout = new HeadTailPreviewBuffer(previewHeadBytes, previewTailBytes);
966
+ const stderr = new HeadTailPreviewBuffer(previewHeadBytes, previewTailBytes);
915
967
  const child = node_child_process.spawn(opts.command, [], {
916
968
  cwd: opts.cwd,
917
969
  shell: true,
@@ -939,15 +991,15 @@ async function runShellCommand(opts) {
939
991
  child.on("error", (error) => {
940
992
  finish({
941
993
  success: false,
942
- stdout: stdout.toString("stdout"),
943
- stderr: stderr.toString("stderr"),
994
+ stdout: stdout.render("stdout"),
995
+ stderr: stderr.render("stderr"),
944
996
  exitCode: 1,
945
997
  error: error.message
946
998
  });
947
999
  });
948
1000
  child.on("close", (code, signal) => {
949
- const stdoutText = stdout.toString("stdout");
950
- const stderrText = stderr.toString("stderr");
1001
+ const stdoutText = stdout.render("stdout");
1002
+ const stderrText = stderr.render("stderr");
951
1003
  if (timedOut) {
952
1004
  finish({
953
1005
  success: false,
@@ -982,8 +1034,8 @@ async function runShellCommand(opts) {
982
1034
  } catch {
983
1035
  finish({
984
1036
  success: false,
985
- stdout: stdout.toString("stdout"),
986
- stderr: stderr.toString("stderr"),
1037
+ stdout: stdout.render("stdout"),
1038
+ stderr: stderr.render("stderr"),
987
1039
  exitCode: -1,
988
1040
  error: "Command timed out"
989
1041
  });
@@ -2787,6 +2839,7 @@ exports.ApiClient = ApiClient;
2787
2839
  exports.ApiSessionClient = ApiSessionClient;
2788
2840
  exports.AsyncLock = AsyncLock;
2789
2841
  exports.HAPPY_CLOUD_DAEMON_PORT = HAPPY_CLOUD_DAEMON_PORT;
2842
+ exports.HeadTailPreviewBuffer = HeadTailPreviewBuffer;
2790
2843
  exports.SIGNING_BOOTSTRAP_REQUIRED_MESSAGE = SIGNING_BOOTSTRAP_REQUIRED_MESSAGE;
2791
2844
  exports.SigningBootstrapRequiredError = SigningBootstrapRequiredError;
2792
2845
  exports.api = api;
@@ -16,7 +16,7 @@ import { spawn } from 'node:child_process';
16
16
  import { Expo } from 'expo-server-sdk';
17
17
 
18
18
  var name = "happy-imou-cloud";
19
- var version = "2.0.16";
19
+ var version = "2.0.17";
20
20
  var description = "hicloud - Imou 企业定制版。关键是 happy!移动端远程 AI 编程工具,支持 Claude Code、Codex 和 Gemini CLI";
21
21
  var author = "long.zhu";
22
22
  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-B89V4xY5.mjs');
433
+ const { readDaemonState } = await import('./persistence-C0nC4mEU.mjs');
434
434
  const state = await readDaemonState();
435
435
  if (!state) {
436
436
  return logs;
@@ -865,51 +865,103 @@ function validatePath(targetPath, workingDirectory) {
865
865
  return { valid: true };
866
866
  }
867
867
 
868
- const DEFAULT_SHELL_COMMAND_TIMEOUT_MS = 3e4;
869
- const DEFAULT_SHELL_OUTPUT_MAX_BYTES = 256 * 1024;
870
- class BoundedTailBuffer {
871
- chunks = [];
872
- maxBytes;
873
- storedBytes = 0;
874
- receivedBytes = 0;
875
- constructor(maxBytes) {
876
- this.maxBytes = Math.max(1, maxBytes);
868
+ class HeadTailPreviewBuffer {
869
+ headBytes;
870
+ tailBytes;
871
+ totalPreviewBytes;
872
+ totalBytes = 0;
873
+ truncated = false;
874
+ fullChunks = [];
875
+ fullBytes = 0;
876
+ head = Buffer.alloc(0);
877
+ tailChunks = [];
878
+ tailStoredBytes = 0;
879
+ constructor(headBytes, tailBytes) {
880
+ this.headBytes = Math.max(0, headBytes);
881
+ this.tailBytes = Math.max(0, tailBytes);
882
+ this.totalPreviewBytes = this.headBytes + this.tailBytes;
877
883
  }
878
884
  append(chunk) {
879
885
  const normalized = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
880
886
  if (normalized.length === 0) {
881
887
  return;
882
888
  }
883
- this.receivedBytes += normalized.length;
884
- this.chunks.push(normalized);
885
- this.storedBytes += normalized.length;
886
- while (this.storedBytes > this.maxBytes && this.chunks.length > 0) {
887
- const overflow = this.storedBytes - this.maxBytes;
888
- const oldest = this.chunks[0];
889
- if (oldest.length <= overflow) {
890
- this.chunks.shift();
891
- this.storedBytes -= oldest.length;
892
- continue;
889
+ this.totalBytes += normalized.length;
890
+ if (!this.truncated) {
891
+ this.fullChunks.push(normalized);
892
+ this.fullBytes += normalized.length;
893
+ if (this.fullBytes > this.totalPreviewBytes) {
894
+ const full = Buffer.concat(this.fullChunks);
895
+ this.truncated = true;
896
+ this.fullChunks = [];
897
+ this.fullBytes = 0;
898
+ this.head = this.headBytes > 0 ? full.subarray(0, this.headBytes) : Buffer.alloc(0);
899
+ this.tailChunks = [];
900
+ this.tailStoredBytes = 0;
901
+ if (this.tailBytes > 0) {
902
+ this.appendTail(full.subarray(Math.max(0, full.length - this.tailBytes)));
903
+ }
893
904
  }
894
- this.chunks[0] = oldest.subarray(overflow);
895
- this.storedBytes -= overflow;
905
+ return;
906
+ }
907
+ this.appendTail(normalized);
908
+ }
909
+ render(label) {
910
+ if (!this.truncated) {
911
+ return Buffer.concat(this.fullChunks).toString("utf8");
912
+ }
913
+ const parts = [
914
+ `...[${label} truncated, showing first ${this.headBytes} bytes and last ${this.tailBytes} bytes of ${this.totalBytes}]`
915
+ ];
916
+ const headText = this.head.toString("utf8");
917
+ const tailText = Buffer.concat(this.tailChunks).toString("utf8");
918
+ if (headText.length > 0) {
919
+ parts.push(headText);
920
+ }
921
+ if (tailText.length > 0) {
922
+ parts.push("...");
923
+ parts.push(tailText);
896
924
  }
925
+ return parts.join("\n");
897
926
  }
898
- toString(label) {
899
- const content = Buffer.concat(this.chunks).toString("utf8");
900
- if (this.receivedBytes <= this.maxBytes) {
901
- return content;
927
+ getTotalBytes() {
928
+ return this.totalBytes;
929
+ }
930
+ isTruncated() {
931
+ return this.truncated;
932
+ }
933
+ appendTail(chunk) {
934
+ if (chunk.length === 0 || this.tailBytes === 0) {
935
+ return;
936
+ }
937
+ this.tailChunks.push(chunk);
938
+ this.tailStoredBytes += chunk.length;
939
+ while (this.tailStoredBytes > this.tailBytes && this.tailChunks.length > 0) {
940
+ const overflow = this.tailStoredBytes - this.tailBytes;
941
+ const oldest = this.tailChunks[0];
942
+ if (oldest.length <= overflow) {
943
+ this.tailChunks.shift();
944
+ this.tailStoredBytes -= oldest.length;
945
+ continue;
946
+ }
947
+ this.tailChunks[0] = oldest.subarray(overflow);
948
+ this.tailStoredBytes -= overflow;
902
949
  }
903
- return `...[${label} truncated, showing last ${this.maxBytes} bytes of ${this.receivedBytes}]
904
- ${content}`;
905
950
  }
906
951
  }
952
+
953
+ const DEFAULT_SHELL_COMMAND_TIMEOUT_MS = 3e4;
954
+ const DEFAULT_SHELL_OUTPUT_PREVIEW_HEAD_BYTES = 2e3;
955
+ const DEFAULT_SHELL_OUTPUT_PREVIEW_TAIL_BYTES = 4e3;
956
+ const DEFAULT_SHELL_OUTPUT_MAX_BYTES = DEFAULT_SHELL_OUTPUT_PREVIEW_HEAD_BYTES + DEFAULT_SHELL_OUTPUT_PREVIEW_TAIL_BYTES;
907
957
  async function runShellCommand(opts) {
908
958
  const timeoutMs = opts.timeoutMs ?? DEFAULT_SHELL_COMMAND_TIMEOUT_MS;
909
959
  const maxOutputBytes = opts.maxOutputBytes ?? DEFAULT_SHELL_OUTPUT_MAX_BYTES;
960
+ const previewHeadBytes = opts.previewHeadBytes ?? Math.min(DEFAULT_SHELL_OUTPUT_PREVIEW_HEAD_BYTES, maxOutputBytes);
961
+ const previewTailBytes = opts.previewTailBytes ?? Math.max(0, maxOutputBytes - previewHeadBytes);
910
962
  return await new Promise((resolve) => {
911
- const stdout = new BoundedTailBuffer(maxOutputBytes);
912
- const stderr = new BoundedTailBuffer(maxOutputBytes);
963
+ const stdout = new HeadTailPreviewBuffer(previewHeadBytes, previewTailBytes);
964
+ const stderr = new HeadTailPreviewBuffer(previewHeadBytes, previewTailBytes);
913
965
  const child = spawn(opts.command, [], {
914
966
  cwd: opts.cwd,
915
967
  shell: true,
@@ -937,15 +989,15 @@ async function runShellCommand(opts) {
937
989
  child.on("error", (error) => {
938
990
  finish({
939
991
  success: false,
940
- stdout: stdout.toString("stdout"),
941
- stderr: stderr.toString("stderr"),
992
+ stdout: stdout.render("stdout"),
993
+ stderr: stderr.render("stderr"),
942
994
  exitCode: 1,
943
995
  error: error.message
944
996
  });
945
997
  });
946
998
  child.on("close", (code, signal) => {
947
- const stdoutText = stdout.toString("stdout");
948
- const stderrText = stderr.toString("stderr");
999
+ const stdoutText = stdout.render("stdout");
1000
+ const stderrText = stderr.render("stderr");
949
1001
  if (timedOut) {
950
1002
  finish({
951
1003
  success: false,
@@ -980,8 +1032,8 @@ async function runShellCommand(opts) {
980
1032
  } catch {
981
1033
  finish({
982
1034
  success: false,
983
- stdout: stdout.toString("stdout"),
984
- stderr: stderr.toString("stderr"),
1035
+ stdout: stdout.render("stdout"),
1036
+ stderr: stderr.render("stderr"),
985
1037
  exitCode: -1,
986
1038
  error: "Command timed out"
987
1039
  });
@@ -2781,4 +2833,4 @@ var api = /*#__PURE__*/Object.freeze({
2781
2833
  ApiClient: ApiClient
2782
2834
  });
2783
2835
 
2784
- export { ApiClient as A, HAPPY_CLOUD_DAEMON_PORT as H, SigningBootstrapRequiredError as S, ApiSessionClient as a, connectionState as b, configuration as c, backoff as d, encodeBase64 as e, delay as f, AsyncLock as g, buildAuthenticatedHeaders as h, isAuthenticationRequiredError as i, SIGNING_BOOTSTRAP_REQUIRED_MESSAGE as j, encodeBase64Url as k, logger as l, buildClientHeaders as m, decodeBase64 as n, getLatestDaemonLog as o, packageJson as p, api as q, startOfflineReconnection as s };
2836
+ export { ApiClient as A, HAPPY_CLOUD_DAEMON_PORT as H, SigningBootstrapRequiredError as S, ApiSessionClient as a, connectionState as b, configuration as c, backoff as d, encodeBase64 as e, delay as f, AsyncLock as g, buildAuthenticatedHeaders as h, isAuthenticationRequiredError as i, SIGNING_BOOTSTRAP_REQUIRED_MESSAGE as j, encodeBase64Url as k, logger as l, buildClientHeaders as m, decodeBase64 as n, HeadTailPreviewBuffer as o, packageJson as p, getLatestDaemonLog as q, api as r, startOfflineReconnection as s };
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-B6ID1zDR.cjs');
3
+ var index = require('./index-sJfKgN1y.cjs');
4
4
  require('chalk');
5
- require('./api-Db1SQcP_.cjs');
5
+ require('./api-BZ2U3k-r.cjs');
6
6
  require('axios');
7
7
  require('fs');
8
8
  require('node:fs');
@@ -18,7 +18,7 @@ require('crypto');
18
18
  require('path');
19
19
  require('node:child_process');
20
20
  require('expo-server-sdk');
21
- require('./persistence-Btu2VPXI.cjs');
21
+ require('./persistence-JEXs_kBA.cjs');
22
22
  require('node:fs/promises');
23
23
  require('os');
24
24
  require('tmp');
@@ -1,6 +1,6 @@
1
- import { c as createDefaultRuntimeShell } from './index-DpWeKfvS.mjs';
1
+ import { c as createDefaultRuntimeShell } from './index-Cdi5KxhK.mjs';
2
2
  import 'chalk';
3
- import './api-sRF6xXi-.mjs';
3
+ import './api-D7DleJYY.mjs';
4
4
  import 'axios';
5
5
  import 'fs';
6
6
  import 'node:fs';
@@ -16,7 +16,7 @@ import 'crypto';
16
16
  import 'path';
17
17
  import 'node:child_process';
18
18
  import 'expo-server-sdk';
19
- import './persistence-B89V4xY5.mjs';
19
+ import './persistence-C0nC4mEU.mjs';
20
20
  import 'node:fs/promises';
21
21
  import 'os';
22
22
  import 'tmp';
@@ -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-sRF6xXi-.mjs';
3
- import { writeCredentialsLegacy, writeCredentialsDataKey, readCredentials, readSettings, updateSettings, readDaemonState, clearDaemonState, acquireDaemonLock, writeDaemonState, releaseDaemonLock, validateProfileForAgent, getProfileEnvironmentVariables, clearCredentials, clearMachineId } from './persistence-B89V4xY5.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 HeadTailPreviewBuffer, q as getLatestDaemonLog } from './api-D7DleJYY.mjs';
3
+ import { writeCredentialsLegacy, writeCredentialsDataKey, readCredentials, readSettings, updateSettings, readDaemonState, clearDaemonState, acquireDaemonLock, writeDaemonState, releaseDaemonLock, validateProfileForAgent, getProfileEnvironmentVariables, clearCredentials, clearMachineId } from './persistence-C0nC4mEU.mjs';
4
4
  import { z } from 'zod';
5
5
  import fs, { writeFile as writeFile$1, rename, unlink as unlink$1 } from 'fs/promises';
6
6
  import os, { homedir } from 'os';
@@ -4964,6 +4964,8 @@ const cursorTransport = new CursorTransport();
4964
4964
 
4965
4965
  const DEFAULT_IDLE_TIMEOUT_MS = 500;
4966
4966
  const DEFAULT_TOOL_CALL_TIMEOUT_MS = 12e4;
4967
+ const DEFAULT_TOOL_CALL_OUTPUT_PREVIEW_HEAD_BYTES = 2e3;
4968
+ const DEFAULT_TOOL_CALL_OUTPUT_PREVIEW_TAIL_BYTES = 4e3;
4967
4969
  function parseArgsFromContent(content) {
4968
4970
  if (Array.isArray(content)) {
4969
4971
  return { items: content };
@@ -4973,17 +4975,54 @@ function parseArgsFromContent(content) {
4973
4975
  }
4974
4976
  return {};
4975
4977
  }
4976
- function appendToolOutput(existing, next) {
4977
- if (!existing || existing.length === 0) {
4978
- return next;
4978
+ const MAX_TOOL_OUTPUT_OVERLAP_CHARS = 4096;
4979
+ function findToolOutputOverlap(previous, next) {
4980
+ const maxOverlap = Math.min(previous.length, next.length, MAX_TOOL_OUTPUT_OVERLAP_CHARS);
4981
+ if (maxOverlap === 0) {
4982
+ return 0;
4979
4983
  }
4980
- if (next === existing || existing.endsWith(next)) {
4981
- return existing;
4984
+ const previousSuffix = previous.slice(-maxOverlap);
4985
+ const nextPrefix = next.slice(0, maxOverlap);
4986
+ for (let overlap = maxOverlap; overlap > 0; overlap--) {
4987
+ if (previousSuffix.endsWith(nextPrefix.slice(0, overlap))) {
4988
+ return overlap;
4989
+ }
4982
4990
  }
4983
- if (next.startsWith(existing)) {
4991
+ return 0;
4992
+ }
4993
+ function getToolOutputDelta(previous, next) {
4994
+ if (!previous || previous.length === 0) {
4984
4995
  return next;
4985
4996
  }
4986
- return `${existing}${next}`;
4997
+ if (next === previous || previous.endsWith(next)) {
4998
+ return "";
4999
+ }
5000
+ if (next.startsWith(previous)) {
5001
+ return next.slice(previous.length);
5002
+ }
5003
+ const overlap = findToolOutputOverlap(previous, next);
5004
+ return overlap > 0 ? next.slice(overlap) : next;
5005
+ }
5006
+ function appendToolOutput(existing, next) {
5007
+ const preview = existing?.preview ?? new HeadTailPreviewBuffer(
5008
+ DEFAULT_TOOL_CALL_OUTPUT_PREVIEW_HEAD_BYTES,
5009
+ DEFAULT_TOOL_CALL_OUTPUT_PREVIEW_TAIL_BYTES
5010
+ );
5011
+ const textToAppend = getToolOutputDelta(existing?.lastRawText, next);
5012
+ if (textToAppend.length > 0) {
5013
+ preview.append(textToAppend);
5014
+ }
5015
+ return {
5016
+ preview,
5017
+ lastRawText: next,
5018
+ updateCount: (existing?.updateCount ?? 0) + 1
5019
+ };
5020
+ }
5021
+ function renderToolOutput(accumulator) {
5022
+ if (!accumulator) {
5023
+ return void 0;
5024
+ }
5025
+ return accumulator.preview.render("tool output");
4987
5026
  }
4988
5027
  function isRecord$1(value) {
4989
5028
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -5221,7 +5260,7 @@ function completeToolCall(toolCallId, toolKind, content, ctx) {
5221
5260
  clearTimeout(timeout);
5222
5261
  ctx.toolCallTimeouts.delete(toolCallId);
5223
5262
  }
5224
- const streamedOutput = ctx.toolCallOutputs.get(toolCallId);
5263
+ const streamedOutput = renderToolOutput(ctx.toolCallOutputs.get(toolCallId));
5225
5264
  ctx.toolCallOutputs.delete(toolCallId);
5226
5265
  logger.debug(`[AcpBackend] \u2705 Tool call COMPLETED: ${toolCallId} (${toolKindStr}) - Duration: ${duration}. Active tool calls: ${ctx.activeToolCalls.size}`);
5227
5266
  ctx.emit({
@@ -5269,7 +5308,7 @@ function failToolCall(toolCallId, status, toolKind, content, ctx) {
5269
5308
  }
5270
5309
  const durationStr = formatDuration(startTime);
5271
5310
  logger.debug(`[AcpBackend] \u274C Tool call ${status.toUpperCase()}: ${toolCallId} (${toolKindStr}) - Duration: ${durationStr}. Active tool calls: ${ctx.activeToolCalls.size}`);
5272
- const streamedOutput = ctx.toolCallOutputs.get(toolCallId);
5311
+ const streamedOutput = renderToolOutput(ctx.toolCallOutputs.get(toolCallId));
5273
5312
  ctx.toolCallOutputs.delete(toolCallId);
5274
5313
  const errorDetail = extractErrorDetail(content);
5275
5314
  if (errorDetail) {
@@ -6105,14 +6144,27 @@ class AcpBackend {
6105
6144
  this.emit({ type: "status", status: "error", detail: err.message });
6106
6145
  });
6107
6146
  this.process.on("exit", (code, signal) => {
6108
- if (!this.disposed && code !== 0 && code !== null) {
6109
- if (this.waitingForResponse) {
6110
- this.failPendingResponseWait(
6111
- new Error(`ACP process exited with code ${code}${signal ? ` (${signal})` : ""}`)
6112
- );
6113
- }
6114
- logger.debug(`[AcpBackend] Process exited with code ${code}, signal ${signal}`);
6147
+ logger.debug(
6148
+ `[AcpBackend] Process exited with code ${code}, signal ${signal}, disposed=${this.disposed}, waitingForResponse=${this.waitingForResponse}`
6149
+ );
6150
+ const recentStderrExcerpt = this.getRecentStderrExcerpt();
6151
+ if (recentStderrExcerpt) {
6152
+ logger.debug(`[AcpBackend] Recent stderr before exit:
6153
+ ${recentStderrExcerpt}`);
6154
+ }
6155
+ if (this.disposed) {
6156
+ return;
6157
+ }
6158
+ if (this.waitingForResponse) {
6159
+ const detail = code !== null ? `ACP process exited with code ${code}${signal ? ` (${signal})` : ""}` : signal ? `ACP process exited with signal ${signal}` : "ACP process exited unexpectedly";
6160
+ this.failPendingResponseWait(new Error(detail));
6161
+ }
6162
+ if (code !== 0 && code !== null) {
6115
6163
  this.emit({ type: "status", status: "stopped", detail: `Exit code: ${code}` });
6164
+ return;
6165
+ }
6166
+ if (signal) {
6167
+ this.emit({ type: "status", status: "stopped", detail: `Signal: ${signal}` });
6116
6168
  }
6117
6169
  });
6118
6170
  const streams = nodeToWebStreams(
@@ -6483,7 +6535,7 @@ class AcpBackend {
6483
6535
  this.clearPostPromptCompletionIdleTimeout();
6484
6536
  for (const update of updates) {
6485
6537
  const sessionUpdateType = update.sessionUpdate;
6486
- if (sessionUpdateType !== "agent_message_chunk") {
6538
+ if (sessionUpdateType !== "agent_message_chunk" && sessionUpdateType !== "tool_call_update") {
6487
6539
  logger.debug(`[AcpBackend] Received session update: ${sessionUpdateType}`, JSON.stringify({
6488
6540
  sessionUpdate: sessionUpdateType,
6489
6541
  toolCallId: update.toolCallId,
@@ -8703,11 +8755,11 @@ var launch = /*#__PURE__*/Object.freeze({
8703
8755
 
8704
8756
  const unifiedProviderExecutors = {
8705
8757
  claude: async (opts) => {
8706
- const { runClaude } = await import('./runClaude-kRPXCaBj.mjs');
8758
+ const { runClaude } = await import('./runClaude-B6fsu9Sl.mjs');
8707
8759
  await runClaude(opts.credentials, opts.claudeOptions ?? {});
8708
8760
  },
8709
8761
  codex: async (opts) => {
8710
- const { runCodex } = await import('./runCodex-B1xN0wAU.mjs');
8762
+ const { runCodex } = await import('./runCodex-DJrzw9x8.mjs');
8711
8763
  await runCodex({
8712
8764
  credentials: opts.credentials,
8713
8765
  startedBy: opts.startedBy,
@@ -8716,7 +8768,7 @@ const unifiedProviderExecutors = {
8716
8768
  });
8717
8769
  },
8718
8770
  gemini: async (opts) => {
8719
- const { runGemini } = await import('./runGemini-Xn2VwS88.mjs');
8771
+ const { runGemini } = await import('./runGemini-C7xlDIfO.mjs');
8720
8772
  await runGemini({
8721
8773
  credentials: opts.credentials,
8722
8774
  startedBy: opts.startedBy
@@ -8792,7 +8844,7 @@ function shouldRunMainClaudeFlow(opts) {
8792
8844
  return;
8793
8845
  } else if (subcommand === "runtime") {
8794
8846
  if (args[1] === "providers") {
8795
- const { renderRuntimeProviders } = await import('./command-WcgGTRnG.mjs');
8847
+ const { renderRuntimeProviders } = await import('./command-DsMlcxQd.mjs');
8796
8848
  console.log(renderRuntimeProviders());
8797
8849
  return;
8798
8850
  }
@@ -8970,8 +9022,8 @@ function shouldRunMainClaudeFlow(opts) {
8970
9022
  const projectId = args[3];
8971
9023
  try {
8972
9024
  const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return config; });
8973
- const { readCredentials: readCredentials2 } = await import('./persistence-B89V4xY5.mjs');
8974
- const { ApiClient: ApiClient2 } = await import('./api-sRF6xXi-.mjs').then(function (n) { return n.q; });
9025
+ const { readCredentials: readCredentials2 } = await import('./persistence-C0nC4mEU.mjs');
9026
+ const { ApiClient: ApiClient2 } = await import('./api-D7DleJYY.mjs').then(function (n) { return n.r; });
8975
9027
  let userEmail = void 0;
8976
9028
  try {
8977
9029
  const credentials = await readCredentials2();