@adhdev/daemon-core 0.8.34 → 0.8.36

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 (109) hide show
  1. package/dist/boot/daemon-lifecycle.d.ts +4 -0
  2. package/dist/commands/router.d.ts +3 -0
  3. package/dist/config/config.d.ts +5 -0
  4. package/dist/index.d.ts +2 -2
  5. package/dist/index.js +585 -256
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +584 -256
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/shared-types.d.ts +286 -16
  10. package/dist/status/builders.d.ts +5 -1
  11. package/dist/status/normalize.d.ts +11 -1
  12. package/dist/status/normalize.js +36 -16
  13. package/dist/status/normalize.js.map +1 -1
  14. package/dist/status/normalize.mjs +35 -16
  15. package/dist/status/normalize.mjs.map +1 -1
  16. package/dist/status/reporter.d.ts +7 -0
  17. package/dist/status/snapshot.d.ts +5 -5
  18. package/dist/types.d.ts +1 -1
  19. package/node_modules/@adhdev/session-host-core/package.json +1 -1
  20. package/package.json +1 -1
  21. package/src/agent-stream/forward.d.ts +8 -0
  22. package/src/agent-stream/index.d.ts +6 -0
  23. package/src/agent-stream/manager.d.ts +60 -0
  24. package/src/agent-stream/poller.d.ts +41 -0
  25. package/src/agent-stream/provider-adapter.d.ts +36 -0
  26. package/src/agent-stream/types.d.ts +68 -0
  27. package/src/boot/daemon-lifecycle.d.ts +100 -0
  28. package/src/boot/daemon-lifecycle.ts +7 -0
  29. package/src/cdp/devtools.d.ts +51 -0
  30. package/src/cdp/initializer.d.ts +50 -0
  31. package/src/cdp/manager.d.ts +147 -0
  32. package/src/cdp/scanner.d.ts +58 -0
  33. package/src/cdp/setup.d.ts +58 -0
  34. package/src/cli-adapter-types.d.ts +57 -0
  35. package/src/cli-adapters/provider-cli-adapter.d.ts +177 -0
  36. package/src/cli-adapters/provider-cli-adapter.ts +115 -91
  37. package/src/cli-adapters/provider-cli-config.d.ts +30 -0
  38. package/src/cli-adapters/provider-cli-parse.d.ts +42 -0
  39. package/src/cli-adapters/provider-cli-runtime.d.ts +29 -0
  40. package/src/cli-adapters/provider-cli-shared.d.ts +158 -0
  41. package/src/cli-adapters/pty-transport.d.ts +48 -0
  42. package/src/cli-adapters/session-host-transport.d.ts +20 -0
  43. package/src/cli-adapters/spawn-env.d.ts +8 -0
  44. package/src/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +16 -0
  45. package/src/cli-adapters/terminal-backends/types.d.ts +18 -0
  46. package/src/cli-adapters/terminal-backends/xterm-backend.d.ts +17 -0
  47. package/src/cli-adapters/terminal-screen.d.ts +33 -0
  48. package/src/commands/cdp-commands.d.ts +15 -0
  49. package/src/commands/chat-commands.d.ts +15 -0
  50. package/src/commands/chat-commands.ts +192 -17
  51. package/src/commands/cli-manager.d.ts +94 -0
  52. package/src/commands/handler.d.ts +103 -0
  53. package/src/commands/router.d.ts +98 -0
  54. package/src/commands/router.ts +25 -0
  55. package/src/commands/stream-commands.d.ts +14 -0
  56. package/src/commands/stream-commands.ts +14 -10
  57. package/src/commands/upgrade-helper.d.ts +10 -0
  58. package/src/commands/workspace-commands.d.ts +11 -0
  59. package/src/config/chat-history.d.ts +99 -0
  60. package/src/config/config.d.ts +14 -0
  61. package/src/config/config.ts +8 -0
  62. package/src/config/recent-activity.d.ts +29 -0
  63. package/src/config/saved-sessions.d.ts +22 -0
  64. package/src/config/state-store.d.ts +32 -0
  65. package/src/config/workspaces.d.ts +0 -1
  66. package/src/daemon/dev-auto-implement.d.ts +43 -0
  67. package/src/daemon/dev-cdp-handlers.d.ts +22 -0
  68. package/src/daemon/dev-cli-debug.d.ts +106 -0
  69. package/src/daemon/dev-server-types.d.ts +43 -0
  70. package/src/daemon/dev-server.d.ts +140 -0
  71. package/src/daemon/scaffold-template.d.ts +32 -0
  72. package/src/daemon-core.d.ts +36 -0
  73. package/src/detection/cli-detector.d.ts +31 -0
  74. package/src/detection/ide-detector.d.ts +35 -0
  75. package/src/index.d.ts +83 -0
  76. package/src/index.ts +34 -1
  77. package/src/installer.d.ts +50 -0
  78. package/src/ipc-protocol.d.ts +111 -0
  79. package/src/launch.d.ts +46 -0
  80. package/src/logging/command-log.d.ts +31 -0
  81. package/src/logging/logger.d.ts +89 -0
  82. package/src/providers/acp-provider-instance.d.ts +102 -0
  83. package/src/providers/approval-utils.d.ts +7 -0
  84. package/src/providers/cli-provider-instance.d.ts +86 -0
  85. package/src/providers/contracts.d.ts +193 -1
  86. package/src/providers/control-effects.d.ts +4 -0
  87. package/src/providers/extension-provider-instance.d.ts +61 -0
  88. package/src/providers/ide-provider-instance.d.ts +70 -0
  89. package/src/providers/provider-instance-manager.d.ts +84 -0
  90. package/src/providers/provider-instance.d.ts +7 -1
  91. package/src/providers/provider-loader.d.ts +299 -0
  92. package/src/providers/status-monitor.d.ts +48 -0
  93. package/src/providers/version-archive.d.ts +52 -0
  94. package/src/session-host/runtime-support.d.ts +8 -0
  95. package/src/sessions/reconcile.d.ts +22 -0
  96. package/src/sessions/registry.d.ts +24 -0
  97. package/src/shared-types-extra.d.ts +29 -0
  98. package/src/shared-types.d.ts +204 -38
  99. package/src/shared-types.ts +319 -16
  100. package/src/status/builders.d.ts +33 -0
  101. package/src/status/builders.ts +110 -54
  102. package/src/status/normalize.ts +54 -19
  103. package/src/status/reporter.d.ts +69 -0
  104. package/src/status/reporter.ts +104 -26
  105. package/src/status/snapshot.d.ts +58 -0
  106. package/src/status/snapshot.ts +79 -41
  107. package/src/system/host-memory.d.ts +19 -0
  108. package/src/types.d.ts +3 -7
  109. package/src/types.ts +1 -1
package/dist/index.js CHANGED
@@ -63,6 +63,7 @@ function normalizeConfig(raw) {
63
63
  const parsed = isPlainObject(raw) ? raw : {};
64
64
  return {
65
65
  serverUrl: typeof parsed.serverUrl === "string" && parsed.serverUrl.trim() ? parsed.serverUrl : DEFAULT_CONFIG.serverUrl,
66
+ allowServerApiProxy: asBoolean(parsed.allowServerApiProxy, DEFAULT_CONFIG.allowServerApiProxy ?? false),
66
67
  selectedIde: asNullableString(parsed.selectedIde),
67
68
  configuredIdes: asStringArray(parsed.configuredIdes),
68
69
  installedExtensions: asStringArray(parsed.installedExtensions),
@@ -211,6 +212,7 @@ var init_config = __esm({
211
212
  import_crypto = require("crypto");
212
213
  DEFAULT_CONFIG = {
213
214
  serverUrl: "https://api.adhf.dev",
215
+ allowServerApiProxy: false,
214
216
  selectedIde: null,
215
217
  configuredIdes: [],
216
218
  installedExtensions: [],
@@ -2488,8 +2490,6 @@ ${data.message || ""}`.trim();
2488
2490
  if (blockingModal || this.currentStatus === "waiting_approval") {
2489
2491
  throw new Error(`${this.cliName} is awaiting confirmation before it can accept a prompt`);
2490
2492
  }
2491
- this.committedMessages.push({ role: "user", content: text, timestamp: Date.now() });
2492
- this.syncMessageViews();
2493
2493
  this.isWaitingForResponse = true;
2494
2494
  this.responseBuffer = "";
2495
2495
  this.finishRetryCount = 0;
@@ -2521,6 +2521,13 @@ ${data.message || ""}`.trim();
2521
2521
  const submitDelayMs = this.sendDelayMs + Math.min(2e3, Math.max(0, estimatedLines - 1) * 350);
2522
2522
  const maxEchoWaitMs = submitDelayMs + Math.max(1500, Math.min(5e3, estimatedLines * 500));
2523
2523
  const retryDelayMs = Math.max(350, Math.min(1500, Math.max(this.sendDelayMs, submitDelayMs)));
2524
+ let didCommitUserTurn = false;
2525
+ const commitUserTurn = () => {
2526
+ if (didCommitUserTurn) return;
2527
+ didCommitUserTurn = true;
2528
+ this.committedMessages.push({ role: "user", content: text, timestamp: Date.now() });
2529
+ this.syncMessageViews();
2530
+ };
2524
2531
  if (this.settleTimer) {
2525
2532
  clearTimeout(this.settleTimer);
2526
2533
  this.settleTimer = null;
@@ -2533,109 +2540,128 @@ ${data.message || ""}`.trim();
2533
2540
  if (this.isWaitingForResponse) this.finishResponse();
2534
2541
  }, this.timeouts.maxResponse);
2535
2542
  };
2536
- const submit = () => {
2537
- if (!this.ptyProcess) return;
2538
- this.submitPendingUntil = 0;
2539
- this.recordTrace("submit_write", {
2540
- mode: "submit_key",
2541
- sendKey: this.sendKey,
2542
- screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500)
2543
- });
2544
- this.ptyProcess.write(this.sendKey);
2545
- const retrySubmitIfStuck = (attempt) => {
2546
- this.submitRetryTimer = null;
2547
- if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
2548
- if (this.currentStatus === "waiting_approval") return;
2549
- if ((this.responseBuffer || "").trim()) return;
2543
+ await new Promise((resolve12) => {
2544
+ let resolved = false;
2545
+ const resolveOnce = () => {
2546
+ if (resolved) return;
2547
+ resolved = true;
2548
+ resolve12();
2549
+ };
2550
+ const submit = () => {
2551
+ if (!this.ptyProcess) {
2552
+ resolveOnce();
2553
+ return;
2554
+ }
2555
+ commitUserTurn();
2556
+ this.submitPendingUntil = 0;
2550
2557
  const screenText = this.terminalScreen.getText();
2551
- if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
2552
- if (/Esc to interrupt|Do you want to proceed|This command requires approval|Allow Codex to|Approve and run now|Always approve this session|Running…|Running\.\.\./i.test(screenText)) return;
2553
- this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
2554
- LOG.info("CLI", `[${this.cliType}] Retrying submit key for stuck prompt (attempt ${attempt})`);
2555
2558
  this.recordTrace("submit_write", {
2556
- mode: "submit_retry",
2557
- attempt,
2559
+ mode: "submit_key",
2558
2560
  sendKey: this.sendKey,
2559
2561
  screenText: summarizeCliTraceText(screenText, 500)
2560
2562
  });
2561
2563
  this.ptyProcess.write(this.sendKey);
2562
- if (attempt >= 3) {
2563
- this.submitRetryUsed = true;
2564
- return;
2565
- }
2566
- this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(attempt + 1), retryDelayMs);
2564
+ const retrySubmitIfStuck = (attempt) => {
2565
+ this.submitRetryTimer = null;
2566
+ if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
2567
+ if (this.currentStatus === "waiting_approval") return;
2568
+ if ((this.responseBuffer || "").trim()) return;
2569
+ const screenText2 = this.terminalScreen.getText();
2570
+ if (!promptLikelyVisible(screenText2, normalizedPromptSnippet)) return;
2571
+ if (/Esc to interrupt|Do you want to proceed|This command requires approval|Allow Codex to|Approve and run now|Always approve this session|Running…|Running\.\.\./i.test(screenText2)) return;
2572
+ this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
2573
+ LOG.info("CLI", `[${this.cliType}] Retrying submit key for stuck prompt (attempt ${attempt})`);
2574
+ this.recordTrace("submit_write", {
2575
+ mode: "submit_retry",
2576
+ attempt,
2577
+ sendKey: this.sendKey,
2578
+ screenText: summarizeCliTraceText(screenText2, 500)
2579
+ });
2580
+ this.ptyProcess.write(this.sendKey);
2581
+ if (attempt >= 3) {
2582
+ this.submitRetryUsed = true;
2583
+ return;
2584
+ }
2585
+ this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(attempt + 1), retryDelayMs);
2586
+ };
2587
+ this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(1), retryDelayMs);
2588
+ startResponseTimeout();
2589
+ resolveOnce();
2567
2590
  };
2568
- this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(1), retryDelayMs);
2569
- startResponseTimeout();
2570
- };
2571
- if (this.submitStrategy === "immediate") {
2572
- this.submitPendingUntil = 0;
2591
+ if (this.submitStrategy === "immediate") {
2592
+ commitUserTurn();
2593
+ this.submitPendingUntil = 0;
2594
+ this.recordTrace("submit_write", {
2595
+ mode: "immediate",
2596
+ text: summarizeCliTraceText(text, 500),
2597
+ sendKey: this.sendKey,
2598
+ screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500)
2599
+ });
2600
+ this.ptyProcess.write(text + this.sendKey);
2601
+ this.submitRetryTimer = setTimeout(() => {
2602
+ this.submitRetryTimer = null;
2603
+ if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
2604
+ if (this.currentStatus === "waiting_approval") return;
2605
+ if ((this.responseBuffer || "").trim()) return;
2606
+ const screenText = this.terminalScreen.getText();
2607
+ if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
2608
+ LOG.info("CLI", `[${this.cliType}] Retrying submit key for stuck prompt (attempt 1)`);
2609
+ this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
2610
+ this.recordTrace("submit_write", {
2611
+ mode: "immediate_retry",
2612
+ attempt: 1,
2613
+ sendKey: this.sendKey,
2614
+ screenText: summarizeCliTraceText(screenText, 500)
2615
+ });
2616
+ this.ptyProcess.write(this.sendKey);
2617
+ this.submitRetryUsed = true;
2618
+ }, retryDelayMs);
2619
+ startResponseTimeout();
2620
+ resolveOnce();
2621
+ return;
2622
+ }
2623
+ if (submitDelayMs > 0) {
2624
+ this.submitPendingUntil = Date.now() + submitDelayMs;
2625
+ }
2626
+ this.ptyProcess.write(text);
2573
2627
  this.recordTrace("submit_write", {
2574
- mode: "immediate",
2628
+ mode: "type_then_submit",
2575
2629
  text: summarizeCliTraceText(text, 500),
2576
2630
  sendKey: this.sendKey,
2577
2631
  screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500)
2578
2632
  });
2579
- this.ptyProcess.write(text + this.sendKey);
2580
- this.submitRetryTimer = setTimeout(() => {
2581
- this.submitRetryTimer = null;
2582
- if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
2583
- if (this.currentStatus === "waiting_approval") return;
2584
- if ((this.responseBuffer || "").trim()) return;
2633
+ const submitStartedAt = Date.now();
2634
+ let lastNormalizedScreen = "";
2635
+ let lastScreenChangeAt = submitStartedAt;
2636
+ const waitForEchoAndSubmit = () => {
2637
+ if (!this.ptyProcess) {
2638
+ resolveOnce();
2639
+ return;
2640
+ }
2641
+ const now = Date.now();
2642
+ const elapsed = now - submitStartedAt;
2585
2643
  const screenText = this.terminalScreen.getText();
2586
- if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
2587
- LOG.info("CLI", `[${this.cliType}] Retrying submit key for stuck prompt (attempt 1)`);
2588
- this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
2589
- this.recordTrace("submit_write", {
2590
- mode: "immediate_retry",
2591
- attempt: 1,
2592
- sendKey: this.sendKey,
2593
- screenText: summarizeCliTraceText(screenText, 500)
2594
- });
2595
- this.ptyProcess.write(this.sendKey);
2596
- this.submitRetryUsed = true;
2597
- }, retryDelayMs);
2598
- startResponseTimeout();
2599
- return;
2600
- }
2601
- if (submitDelayMs > 0) {
2602
- this.submitPendingUntil = Date.now() + submitDelayMs;
2603
- }
2604
- this.ptyProcess.write(text);
2605
- this.recordTrace("submit_write", {
2606
- mode: "type_then_submit",
2607
- text: summarizeCliTraceText(text, 500),
2608
- sendKey: this.sendKey,
2609
- screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500)
2610
- });
2611
- const submitStartedAt = Date.now();
2612
- let lastNormalizedScreen = "";
2613
- let lastScreenChangeAt = submitStartedAt;
2614
- const waitForEchoAndSubmit = () => {
2615
- if (!this.ptyProcess) return;
2616
- const now = Date.now();
2617
- const elapsed = now - submitStartedAt;
2618
- const screenText = this.terminalScreen.getText();
2619
- const normalizedScreen = normalizePromptText(screenText);
2620
- if (normalizedScreen !== lastNormalizedScreen) {
2621
- lastNormalizedScreen = normalizedScreen;
2622
- lastScreenChangeAt = now;
2623
- }
2624
- const echoVisible = !normalizedPromptSnippet || promptLikelyVisible(screenText, normalizedPromptSnippet);
2625
- if (echoVisible) {
2626
- const screenSettled = now - lastScreenChangeAt >= 500;
2627
- if (elapsed >= submitDelayMs && screenSettled) {
2644
+ const normalizedScreen = normalizePromptText(screenText);
2645
+ if (normalizedScreen !== lastNormalizedScreen) {
2646
+ lastNormalizedScreen = normalizedScreen;
2647
+ lastScreenChangeAt = now;
2648
+ }
2649
+ const echoVisible = !normalizedPromptSnippet || promptLikelyVisible(screenText, normalizedPromptSnippet);
2650
+ if (echoVisible) {
2651
+ const screenSettled = now - lastScreenChangeAt >= 500;
2652
+ if (elapsed >= submitDelayMs && screenSettled) {
2653
+ submit();
2654
+ return;
2655
+ }
2656
+ }
2657
+ if (elapsed >= maxEchoWaitMs) {
2628
2658
  submit();
2629
2659
  return;
2630
2660
  }
2631
- }
2632
- if (elapsed >= maxEchoWaitMs) {
2633
- submit();
2634
- return;
2635
- }
2636
- setTimeout(waitForEchoAndSubmit, 50);
2637
- };
2638
- waitForEchoAndSubmit();
2661
+ setTimeout(waitForEchoAndSubmit, 50);
2662
+ };
2663
+ waitForEchoAndSubmit();
2664
+ });
2639
2665
  }
2640
2666
  getPartialResponse() {
2641
2667
  if (!this.isWaitingForResponse) return "";
@@ -3001,6 +3027,7 @@ __export(index_exports, {
3001
3027
  SessionHostPtyTransportFactory: () => SessionHostPtyTransportFactory,
3002
3028
  VersionArchive: () => VersionArchive,
3003
3029
  appendRecentActivity: () => appendRecentActivity,
3030
+ buildMachineInfo: () => buildMachineInfo,
3004
3031
  buildSessionEntries: () => buildSessionEntries,
3005
3032
  buildStatusSnapshot: () => buildStatusSnapshot,
3006
3033
  connectCdpManager: () => connectCdpManager,
@@ -6960,11 +6987,24 @@ var WORKING_STATUSES = /* @__PURE__ */ new Set([
6960
6987
  "thinking",
6961
6988
  "active"
6962
6989
  ]);
6963
- var STATUS_ACTIVE_CHAT_MESSAGE_LIMIT = 60;
6964
- var STATUS_ACTIVE_CHAT_TOTAL_BYTES_LIMIT = 96 * 1024;
6965
- var STATUS_ACTIVE_CHAT_STRING_LIMIT = 4 * 1024;
6966
- var STATUS_ACTIVE_CHAT_FALLBACK_STRING_LIMIT = 1024;
6967
- var STATUS_INPUT_CONTENT_LIMIT = 2 * 1024;
6990
+ var FULL_STATUS_ACTIVE_CHAT_OPTIONS = {
6991
+ includeMessages: true,
6992
+ includeInputContent: true,
6993
+ includeActiveModal: true,
6994
+ messageLimit: 60,
6995
+ totalBytesLimit: 96 * 1024,
6996
+ stringLimit: 4 * 1024,
6997
+ fallbackStringLimit: 1024
6998
+ };
6999
+ var LIVE_STATUS_ACTIVE_CHAT_OPTIONS = {
7000
+ includeMessages: false,
7001
+ includeInputContent: false,
7002
+ includeActiveModal: false,
7003
+ messageLimit: 0,
7004
+ totalBytesLimit: 0,
7005
+ stringLimit: 512,
7006
+ fallbackStringLimit: 256
7007
+ };
6968
7008
  var STATUS_MODAL_MESSAGE_LIMIT = 2 * 1024;
6969
7009
  var STATUS_MODAL_BUTTON_LIMIT = 120;
6970
7010
  function truncateString(value, maxChars) {
@@ -7003,19 +7043,20 @@ function normalizeMessageTime(message) {
7003
7043
  }
7004
7044
  return msg;
7005
7045
  }
7006
- function trimMessagesForStatus(messages) {
7046
+ function trimMessagesForStatus(messages, options) {
7047
+ if (!options.includeMessages || options.messageLimit <= 0 || options.totalBytesLimit <= 0) return [];
7007
7048
  if (!Array.isArray(messages) || messages.length === 0) return [];
7008
- const recent = messages.slice(-STATUS_ACTIVE_CHAT_MESSAGE_LIMIT);
7049
+ const recent = messages.slice(-options.messageLimit);
7009
7050
  const kept = [];
7010
7051
  let totalBytes = 0;
7011
7052
  for (let i = recent.length - 1; i >= 0; i -= 1) {
7012
- let normalized = normalizeMessageTime(trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_STRING_LIMIT));
7053
+ let normalized = normalizeMessageTime(trimMessageForStatus(recent[i], options.stringLimit));
7013
7054
  let size = estimateBytes(normalized);
7014
- if (size > STATUS_ACTIVE_CHAT_TOTAL_BYTES_LIMIT) {
7015
- normalized = normalizeMessageTime(trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_FALLBACK_STRING_LIMIT));
7055
+ if (size > options.totalBytesLimit) {
7056
+ normalized = normalizeMessageTime(trimMessageForStatus(recent[i], options.fallbackStringLimit));
7016
7057
  size = estimateBytes(normalized);
7017
7058
  }
7018
- if (kept.length > 0 && totalBytes + size > STATUS_ACTIVE_CHAT_TOTAL_BYTES_LIMIT) {
7059
+ if (kept.length > 0 && totalBytes + size > options.totalBytesLimit) {
7019
7060
  continue;
7020
7061
  }
7021
7062
  kept.push(normalized);
@@ -7045,23 +7086,40 @@ function isManagedStatusWorking(status) {
7045
7086
  function isManagedStatusWaiting(status, opts) {
7046
7087
  return normalizeManagedStatus(status, opts) === "waiting_approval";
7047
7088
  }
7048
- function normalizeActiveChatData(activeChat) {
7089
+ function normalizeActiveChatData(activeChat, options = FULL_STATUS_ACTIVE_CHAT_OPTIONS) {
7049
7090
  if (!activeChat) return activeChat;
7091
+ const resolvedOptions = {
7092
+ ...FULL_STATUS_ACTIVE_CHAT_OPTIONS,
7093
+ ...options
7094
+ };
7050
7095
  return {
7051
7096
  ...activeChat,
7052
7097
  status: normalizeManagedStatus(activeChat.status, { activeModal: activeChat.activeModal }),
7053
- messages: trimMessagesForStatus(activeChat.messages),
7054
- activeModal: activeChat.activeModal ? {
7098
+ messages: trimMessagesForStatus(activeChat.messages, resolvedOptions),
7099
+ activeModal: resolvedOptions.includeActiveModal && activeChat.activeModal ? {
7055
7100
  message: truncateString(activeChat.activeModal.message || "", STATUS_MODAL_MESSAGE_LIMIT),
7056
7101
  buttons: (activeChat.activeModal.buttons || []).map(
7057
7102
  (button) => truncateString(String(button || ""), STATUS_MODAL_BUTTON_LIMIT)
7058
7103
  )
7059
- } : activeChat.activeModal,
7060
- inputContent: activeChat.inputContent ? truncateString(activeChat.inputContent, STATUS_INPUT_CONTENT_LIMIT) : activeChat.inputContent
7104
+ } : null,
7105
+ inputContent: resolvedOptions.includeInputContent && activeChat.inputContent ? truncateString(activeChat.inputContent, 2 * 1024) : void 0
7061
7106
  };
7062
7107
  }
7063
7108
 
7064
7109
  // src/status/builders.ts
7110
+ function getActiveChatOptions(profile) {
7111
+ if (profile === "full") return {};
7112
+ return LIVE_STATUS_ACTIVE_CHAT_OPTIONS;
7113
+ }
7114
+ function shouldIncludeSessionControls(profile) {
7115
+ return profile !== "live";
7116
+ }
7117
+ function shouldIncludeSessionMetadata(profile) {
7118
+ return profile !== "live";
7119
+ }
7120
+ function shouldIncludeRuntimeMetadata(profile) {
7121
+ return profile !== "live";
7122
+ }
7065
7123
  function findCdpManager(cdpManagers, key) {
7066
7124
  const exact = cdpManagers.get(key);
7067
7125
  if (exact) return exact;
@@ -7169,74 +7227,88 @@ var ACP_SESSION_CAPABILITIES = [
7169
7227
  "set_mode",
7170
7228
  "set_thought_level"
7171
7229
  ];
7172
- function buildIdeWorkspaceSession(state, cdpManagers) {
7173
- const activeChat = normalizeActiveChatData(state.activeChat);
7230
+ function buildIdeWorkspaceSession(state, cdpManagers, options) {
7231
+ const profile = options.profile || "full";
7232
+ const activeChat = normalizeActiveChatData(state.activeChat, getActiveChatOptions(profile));
7233
+ const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
7234
+ const includeSessionControls = shouldIncludeSessionControls(profile);
7174
7235
  const title = activeChat?.title || state.name;
7175
7236
  return {
7176
7237
  id: state.instanceId || state.type,
7177
7238
  parentId: null,
7178
7239
  providerType: state.type,
7179
- providerName: state.name,
7240
+ ...includeSessionMetadata && { providerName: state.name },
7180
7241
  kind: "workspace",
7181
7242
  transport: "cdp-page",
7182
7243
  status: normalizeManagedStatus(activeChat?.status || state.status, {
7183
7244
  activeModal: activeChat?.activeModal || null
7184
7245
  }),
7185
7246
  title,
7186
- workspace: state.workspace || null,
7247
+ ...includeSessionMetadata && { workspace: state.workspace || null },
7187
7248
  activeChat,
7188
- capabilities: IDE_SESSION_CAPABILITIES,
7249
+ ...includeSessionMetadata && { capabilities: IDE_SESSION_CAPABILITIES },
7189
7250
  cdpConnected: state.cdpConnected ?? isCdpConnected(cdpManagers, state.type),
7190
7251
  currentModel: state.currentModel,
7191
7252
  currentPlan: state.currentPlan,
7192
7253
  currentAutoApprove: state.currentAutoApprove,
7193
- controlValues: state.controlValues,
7194
- providerControls: buildFallbackControls(
7195
- state.providerControls,
7196
- state.currentModel,
7197
- state.currentPlan
7198
- ),
7254
+ ...includeSessionControls && {
7255
+ controlValues: state.controlValues,
7256
+ providerControls: buildFallbackControls(
7257
+ state.providerControls,
7258
+ state.currentModel,
7259
+ state.currentPlan
7260
+ )
7261
+ },
7199
7262
  errorMessage: state.errorMessage,
7200
7263
  errorReason: state.errorReason,
7201
7264
  lastUpdated: state.lastUpdated
7202
7265
  };
7203
7266
  }
7204
- function buildExtensionAgentSession(parent, ext) {
7205
- const activeChat = normalizeActiveChatData(ext.activeChat);
7267
+ function buildExtensionAgentSession(parent, ext, options) {
7268
+ const profile = options.profile || "full";
7269
+ const activeChat = normalizeActiveChatData(ext.activeChat, getActiveChatOptions(profile));
7270
+ const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
7271
+ const includeSessionControls = shouldIncludeSessionControls(profile);
7206
7272
  return {
7207
7273
  id: ext.instanceId || `${parent.instanceId}:${ext.type}`,
7208
7274
  parentId: parent.instanceId || parent.type,
7209
7275
  providerType: ext.type,
7210
- providerName: ext.name,
7276
+ ...includeSessionMetadata && { providerName: ext.name },
7211
7277
  kind: "agent",
7212
7278
  transport: "cdp-webview",
7213
7279
  status: normalizeManagedStatus(activeChat?.status || ext.status, {
7214
7280
  activeModal: activeChat?.activeModal || null
7215
7281
  }),
7216
7282
  title: activeChat?.title || ext.name,
7217
- workspace: parent.workspace || null,
7283
+ ...includeSessionMetadata && { workspace: parent.workspace || null },
7218
7284
  activeChat,
7219
- capabilities: EXTENSION_SESSION_CAPABILITIES,
7285
+ ...includeSessionMetadata && { capabilities: EXTENSION_SESSION_CAPABILITIES },
7220
7286
  currentModel: ext.currentModel,
7221
7287
  currentPlan: ext.currentPlan,
7222
- controlValues: ext.controlValues,
7223
- providerControls: buildFallbackControls(
7224
- ext.providerControls,
7225
- ext.currentModel,
7226
- ext.currentPlan
7227
- ),
7288
+ ...includeSessionControls && {
7289
+ controlValues: ext.controlValues,
7290
+ providerControls: buildFallbackControls(
7291
+ ext.providerControls,
7292
+ ext.currentModel,
7293
+ ext.currentPlan
7294
+ )
7295
+ },
7228
7296
  errorMessage: ext.errorMessage,
7229
7297
  errorReason: ext.errorReason,
7230
7298
  lastUpdated: ext.lastUpdated
7231
7299
  };
7232
7300
  }
7233
- function buildCliSession(state) {
7234
- const activeChat = normalizeActiveChatData(state.activeChat);
7301
+ function buildCliSession(state, options) {
7302
+ const profile = options.profile || "full";
7303
+ const activeChat = normalizeActiveChatData(state.activeChat, getActiveChatOptions(profile));
7304
+ const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
7305
+ const includeRuntimeMetadata = shouldIncludeRuntimeMetadata(profile);
7306
+ const includeSessionControls = shouldIncludeSessionControls(profile);
7235
7307
  return {
7236
7308
  id: state.instanceId,
7237
7309
  parentId: null,
7238
7310
  providerType: state.type,
7239
- providerName: state.name,
7311
+ ...includeSessionMetadata && { providerName: state.name },
7240
7312
  providerSessionId: state.providerSessionId,
7241
7313
  kind: "agent",
7242
7314
  transport: "pty",
@@ -7244,74 +7316,85 @@ function buildCliSession(state) {
7244
7316
  activeModal: activeChat?.activeModal || null
7245
7317
  }),
7246
7318
  title: activeChat?.title || state.name,
7247
- workspace: state.workspace || null,
7248
- runtimeKey: state.runtime?.runtimeKey,
7249
- runtimeDisplayName: state.runtime?.displayName,
7250
- runtimeWorkspaceLabel: state.runtime?.workspaceLabel,
7251
- runtimeWriteOwner: state.runtime?.writeOwner || null,
7252
- runtimeAttachedClients: state.runtime?.attachedClients || [],
7319
+ ...includeSessionMetadata && { workspace: state.workspace || null },
7320
+ ...includeRuntimeMetadata && {
7321
+ runtimeKey: state.runtime?.runtimeKey,
7322
+ runtimeDisplayName: state.runtime?.displayName,
7323
+ runtimeWorkspaceLabel: state.runtime?.workspaceLabel,
7324
+ runtimeWriteOwner: state.runtime?.writeOwner || null,
7325
+ runtimeAttachedClients: state.runtime?.attachedClients || []
7326
+ },
7253
7327
  mode: state.mode,
7254
7328
  resume: state.resume,
7255
7329
  activeChat,
7256
- capabilities: state.mode === "terminal" ? PTY_SESSION_CAPABILITIES : CLI_CHAT_SESSION_CAPABILITIES,
7257
- controlValues: state.controlValues,
7258
- providerControls: buildFallbackControls(
7259
- state.providerControls
7260
- ),
7330
+ ...includeSessionMetadata && {
7331
+ capabilities: state.mode === "terminal" ? PTY_SESSION_CAPABILITIES : CLI_CHAT_SESSION_CAPABILITIES
7332
+ },
7333
+ ...includeSessionControls && {
7334
+ controlValues: state.controlValues,
7335
+ providerControls: buildFallbackControls(
7336
+ state.providerControls
7337
+ )
7338
+ },
7261
7339
  errorMessage: state.errorMessage,
7262
7340
  errorReason: state.errorReason,
7263
7341
  lastUpdated: state.lastUpdated
7264
7342
  };
7265
7343
  }
7266
- function buildAcpSession(state) {
7267
- const activeChat = normalizeActiveChatData(state.activeChat);
7344
+ function buildAcpSession(state, options) {
7345
+ const profile = options.profile || "full";
7346
+ const activeChat = normalizeActiveChatData(state.activeChat, getActiveChatOptions(profile));
7347
+ const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
7348
+ const includeSessionControls = shouldIncludeSessionControls(profile);
7268
7349
  return {
7269
7350
  id: state.instanceId,
7270
7351
  parentId: null,
7271
7352
  providerType: state.type,
7272
- providerName: state.name,
7353
+ ...includeSessionMetadata && { providerName: state.name },
7273
7354
  kind: "agent",
7274
7355
  transport: "acp",
7275
7356
  status: normalizeManagedStatus(activeChat?.status || state.status, {
7276
7357
  activeModal: activeChat?.activeModal || null
7277
7358
  }),
7278
7359
  title: activeChat?.title || state.name,
7279
- workspace: state.workspace || null,
7360
+ ...includeSessionMetadata && { workspace: state.workspace || null },
7280
7361
  activeChat,
7281
- capabilities: ACP_SESSION_CAPABILITIES,
7362
+ ...includeSessionMetadata && { capabilities: ACP_SESSION_CAPABILITIES },
7282
7363
  currentModel: state.currentModel,
7283
7364
  currentPlan: state.currentPlan,
7284
- acpConfigOptions: state.acpConfigOptions,
7285
- acpModes: state.acpModes,
7286
- controlValues: state.controlValues,
7287
- providerControls: buildFallbackControls(
7288
- state.providerControls,
7289
- state.currentModel,
7290
- state.currentPlan,
7291
- state.acpConfigOptions,
7292
- state.acpModes
7293
- ),
7365
+ ...includeSessionControls && {
7366
+ acpConfigOptions: state.acpConfigOptions,
7367
+ acpModes: state.acpModes,
7368
+ controlValues: state.controlValues,
7369
+ providerControls: buildFallbackControls(
7370
+ state.providerControls,
7371
+ state.currentModel,
7372
+ state.currentPlan,
7373
+ state.acpConfigOptions,
7374
+ state.acpModes
7375
+ )
7376
+ },
7294
7377
  errorMessage: state.errorMessage,
7295
7378
  errorReason: state.errorReason,
7296
7379
  lastUpdated: state.lastUpdated
7297
7380
  };
7298
7381
  }
7299
- function buildSessionEntries(allStates, cdpManagers) {
7382
+ function buildSessionEntries(allStates, cdpManagers, options = {}) {
7300
7383
  const sessions = [];
7301
7384
  const ideStates = allStates.filter((s) => s.category === "ide");
7302
7385
  const cliStates = allStates.filter((s) => s.category === "cli");
7303
7386
  const acpStates = allStates.filter((s) => s.category === "acp");
7304
7387
  for (const state of ideStates) {
7305
- sessions.push(buildIdeWorkspaceSession(state, cdpManagers));
7388
+ sessions.push(buildIdeWorkspaceSession(state, cdpManagers, options));
7306
7389
  for (const ext of state.extensions) {
7307
- sessions.push(buildExtensionAgentSession(state, ext));
7390
+ sessions.push(buildExtensionAgentSession(state, ext, options));
7308
7391
  }
7309
7392
  }
7310
7393
  for (const state of cliStates) {
7311
- sessions.push(buildCliSession(state));
7394
+ sessions.push(buildCliSession(state, options));
7312
7395
  }
7313
7396
  for (const state of acpStates) {
7314
- sessions.push(buildAcpSession(state));
7397
+ sessions.push(buildAcpSession(state, options));
7315
7398
  }
7316
7399
  const extensionParentIds = new Set(
7317
7400
  sessions.filter((session) => session.transport === "cdp-webview" && !!session.parentId).map((session) => session.parentId)
@@ -7372,10 +7455,29 @@ function reconcileIdeRuntimeSessions(instanceManager, sessionRegistry) {
7372
7455
  // src/commands/handler.ts
7373
7456
  init_logger();
7374
7457
 
7458
+ // src/providers/contracts.ts
7459
+ function flattenContent(content) {
7460
+ if (typeof content === "string") return content;
7461
+ return content.filter((b) => b.type === "text").map((b) => b.text).join("\n");
7462
+ }
7463
+
7375
7464
  // src/commands/chat-commands.ts
7376
7465
  init_logger();
7377
7466
  var RECENT_SEND_WINDOW_MS = 1200;
7378
7467
  var recentSendByTarget = /* @__PURE__ */ new Map();
7468
+ function hashSignatureParts(parts) {
7469
+ let hash = 2166136261;
7470
+ for (const part of parts) {
7471
+ const text = String(part || "");
7472
+ for (let i = 0; i < text.length; i += 1) {
7473
+ hash ^= text.charCodeAt(i);
7474
+ hash = Math.imul(hash, 16777619) >>> 0;
7475
+ }
7476
+ hash ^= 255;
7477
+ hash = Math.imul(hash, 16777619) >>> 0;
7478
+ }
7479
+ return hash.toString(16).padStart(8, "0");
7480
+ }
7379
7481
  function getCurrentProviderType(h, fallback = "") {
7380
7482
  return h.currentSession?.providerType || h.currentProviderType || fallback;
7381
7483
  }
@@ -7449,6 +7551,134 @@ function parseMaybeJson(value) {
7449
7551
  return value;
7450
7552
  }
7451
7553
  }
7554
+ function getChatMessageSignature(message) {
7555
+ if (!message) return "";
7556
+ let content = "";
7557
+ try {
7558
+ content = JSON.stringify(message.content ?? "");
7559
+ } catch {
7560
+ content = String(message.content ?? "");
7561
+ }
7562
+ return hashSignatureParts([
7563
+ String(message.id || ""),
7564
+ String(message.index ?? ""),
7565
+ String(message.role || ""),
7566
+ String(message.receivedAt ?? message.timestamp ?? ""),
7567
+ content
7568
+ ]);
7569
+ }
7570
+ function normalizeReadChatCursor(args) {
7571
+ const knownMessageCount = Math.max(0, Number(args?.knownMessageCount || 0));
7572
+ const lastMessageSignature = typeof args?.lastMessageSignature === "string" ? args.lastMessageSignature : "";
7573
+ const tailLimit = Math.max(0, Number(args?.tailLimit || 0));
7574
+ return { knownMessageCount, lastMessageSignature, tailLimit };
7575
+ }
7576
+ function normalizeReadChatMessages(payload) {
7577
+ const messages = Array.isArray(payload.messages) ? payload.messages : [];
7578
+ return messages;
7579
+ }
7580
+ function deriveHistoryDedupKey(message) {
7581
+ const unitKey = typeof message._unitKey === "string" ? message._unitKey.trim() : "";
7582
+ if (unitKey) return `read_chat:${unitKey}`;
7583
+ const turnKey = typeof message._turnKey === "string" ? message._turnKey.trim() : "";
7584
+ if (!turnKey) return void 0;
7585
+ let content = "";
7586
+ try {
7587
+ content = JSON.stringify(message.content ?? "");
7588
+ } catch {
7589
+ content = String(message.content ?? "");
7590
+ }
7591
+ return `read_chat:${turnKey}:${String(message.role || "").toLowerCase()}:${content}`;
7592
+ }
7593
+ function toHistoryPersistedMessages(messages) {
7594
+ return messages.map((message) => ({
7595
+ role: message.role,
7596
+ content: flattenContent(message.content),
7597
+ receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : void 0,
7598
+ kind: typeof message.kind === "string" ? message.kind : void 0,
7599
+ senderName: typeof message.senderName === "string" ? message.senderName : void 0,
7600
+ historyDedupKey: deriveHistoryDedupKey(message)
7601
+ }));
7602
+ }
7603
+ function computeReadChatSync(messages, cursor) {
7604
+ const totalMessages = messages.length;
7605
+ const lastMessageSignature = getChatMessageSignature(messages[totalMessages - 1]);
7606
+ const { knownMessageCount, lastMessageSignature: knownSignature } = cursor;
7607
+ if (!knownMessageCount || !knownSignature) {
7608
+ return {
7609
+ syncMode: "full",
7610
+ replaceFrom: 0,
7611
+ messages,
7612
+ totalMessages,
7613
+ lastMessageSignature
7614
+ };
7615
+ }
7616
+ if (knownMessageCount > totalMessages) {
7617
+ return {
7618
+ syncMode: "full",
7619
+ replaceFrom: 0,
7620
+ messages,
7621
+ totalMessages,
7622
+ lastMessageSignature
7623
+ };
7624
+ }
7625
+ if (knownMessageCount === totalMessages && knownSignature === lastMessageSignature) {
7626
+ return {
7627
+ syncMode: "noop",
7628
+ replaceFrom: totalMessages,
7629
+ messages: [],
7630
+ totalMessages,
7631
+ lastMessageSignature
7632
+ };
7633
+ }
7634
+ if (knownMessageCount < totalMessages) {
7635
+ const anchorSignature = getChatMessageSignature(messages[knownMessageCount - 1]);
7636
+ if (anchorSignature === knownSignature) {
7637
+ return {
7638
+ syncMode: "append",
7639
+ replaceFrom: knownMessageCount,
7640
+ messages: messages.slice(knownMessageCount),
7641
+ totalMessages,
7642
+ lastMessageSignature
7643
+ };
7644
+ }
7645
+ }
7646
+ const replaceFrom = Math.max(0, Math.min(knownMessageCount - 1, totalMessages));
7647
+ return {
7648
+ syncMode: replaceFrom === 0 ? "full" : "replace_tail",
7649
+ replaceFrom,
7650
+ messages: replaceFrom === 0 ? messages : messages.slice(replaceFrom),
7651
+ totalMessages,
7652
+ lastMessageSignature
7653
+ };
7654
+ }
7655
+ function buildReadChatCommandResult(payload, args) {
7656
+ const messages = normalizeReadChatMessages(payload);
7657
+ const cursor = normalizeReadChatCursor(args);
7658
+ if (!cursor.knownMessageCount && !cursor.lastMessageSignature && cursor.tailLimit > 0 && messages.length > cursor.tailLimit) {
7659
+ const tailMessages = messages.slice(-cursor.tailLimit);
7660
+ const lastMessageSignature = getChatMessageSignature(tailMessages[tailMessages.length - 1]);
7661
+ return {
7662
+ success: true,
7663
+ ...payload,
7664
+ messages: tailMessages,
7665
+ syncMode: "full",
7666
+ replaceFrom: 0,
7667
+ totalMessages: messages.length,
7668
+ lastMessageSignature
7669
+ };
7670
+ }
7671
+ const sync = computeReadChatSync(messages, cursor);
7672
+ return {
7673
+ success: true,
7674
+ ...payload,
7675
+ messages: sync.messages,
7676
+ syncMode: sync.syncMode,
7677
+ replaceFrom: sync.replaceFrom,
7678
+ totalMessages: sync.totalMessages,
7679
+ lastMessageSignature: sync.lastMessageSignature
7680
+ };
7681
+ }
7452
7682
  function didProviderConfirmSend(result) {
7453
7683
  const parsed = parseMaybeJson(result);
7454
7684
  if (parsed === true) return true;
@@ -7522,12 +7752,11 @@ async function handleReadChat(h, args) {
7522
7752
  _log(`${transport} adapter: ${adapter.cliType}`);
7523
7753
  const status = adapter.getStatus();
7524
7754
  if (status) {
7525
- return {
7526
- success: true,
7755
+ return buildReadChatCommandResult({
7527
7756
  messages: status.messages || [],
7528
7757
  status: status.status,
7529
7758
  activeModal: status.activeModal
7530
- };
7759
+ }, args);
7531
7760
  }
7532
7761
  }
7533
7762
  return { success: false, error: `${transport} adapter not found` };
@@ -7547,12 +7776,12 @@ async function handleReadChat(h, args) {
7547
7776
  _log(`Extension OK: ${parsed.messages?.length || 0} msgs`);
7548
7777
  h.historyWriter.appendNewMessages(
7549
7778
  provider?.type || "unknown_extension",
7550
- parsed.messages || [],
7779
+ toHistoryPersistedMessages(normalizeReadChatMessages(parsed)),
7551
7780
  parsed.title,
7552
7781
  args?.targetSessionId,
7553
7782
  historySessionId
7554
7783
  );
7555
- return { success: true, ...parsed };
7784
+ return buildReadChatCommandResult(parsed, args);
7556
7785
  }
7557
7786
  }
7558
7787
  } catch (e) {
@@ -7564,21 +7793,25 @@ async function handleReadChat(h, args) {
7564
7793
  if (cdp2 && parentSessionId) {
7565
7794
  const stream = await h.agentStream.collectActiveSession(cdp2, parentSessionId);
7566
7795
  if (stream?.agentType !== provider?.type) {
7567
- return { success: true, messages: [], status: "idle" };
7796
+ return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
7568
7797
  }
7569
7798
  if (stream) {
7570
7799
  h.historyWriter.appendNewMessages(
7571
7800
  stream.agentType,
7572
- stream.messages || [],
7801
+ toHistoryPersistedMessages(stream.messages || []),
7573
7802
  void 0,
7574
7803
  args?.targetSessionId,
7575
7804
  historySessionId
7576
7805
  );
7577
- return { success: true, messages: stream.messages || [], status: stream.status, agentType: stream.agentType };
7806
+ return buildReadChatCommandResult({
7807
+ messages: stream.messages || [],
7808
+ status: stream.status,
7809
+ agentType: stream.agentType
7810
+ }, args);
7578
7811
  }
7579
7812
  }
7580
7813
  }
7581
- return { success: true, messages: [], status: "idle" };
7814
+ return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
7582
7815
  }
7583
7816
  const cdp = h.getCdp();
7584
7817
  if (!cdp?.isConnected) return { success: false, error: "CDP not connected" };
@@ -7600,18 +7833,18 @@ async function handleReadChat(h, args) {
7600
7833
  _log(`Webview OK: ${parsed.messages?.length || 0} msgs`);
7601
7834
  h.historyWriter.appendNewMessages(
7602
7835
  provider?.type || getCurrentProviderType(h, "unknown_webview"),
7603
- parsed.messages || [],
7836
+ toHistoryPersistedMessages(normalizeReadChatMessages(parsed)),
7604
7837
  parsed.title,
7605
7838
  args?.targetSessionId,
7606
7839
  historySessionId
7607
7840
  );
7608
- return { success: true, ...parsed };
7841
+ return buildReadChatCommandResult(parsed, args);
7609
7842
  }
7610
7843
  }
7611
7844
  } catch (e) {
7612
7845
  _log(`Webview readChat error: ${e.message}`);
7613
7846
  }
7614
- return { success: true, messages: [], status: "idle" };
7847
+ return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
7615
7848
  }
7616
7849
  const script = h.getProviderScript("readChat") || h.getProviderScript("read_chat");
7617
7850
  if (script) {
@@ -7628,18 +7861,18 @@ async function handleReadChat(h, args) {
7628
7861
  _log(`OK: ${parsed.messages?.length} msgs`);
7629
7862
  h.historyWriter.appendNewMessages(
7630
7863
  provider?.type || getCurrentProviderType(h, "unknown_ide"),
7631
- parsed.messages || [],
7864
+ toHistoryPersistedMessages(normalizeReadChatMessages(parsed)),
7632
7865
  parsed.title,
7633
7866
  args?.targetSessionId,
7634
7867
  historySessionId
7635
7868
  );
7636
- return { success: true, ...parsed };
7869
+ return buildReadChatCommandResult(parsed, args);
7637
7870
  }
7638
7871
  } catch (e) {
7639
7872
  LOG.info("Command", `[read_chat] Script error: ${e.message}`);
7640
7873
  }
7641
7874
  }
7642
- return { success: true, messages: [], status: "idle" };
7875
+ return buildReadChatCommandResult({ messages: [], status: "idle" }, args);
7643
7876
  }
7644
7877
  async function handleSendChat(h, args) {
7645
7878
  const text = args?.text || args?.message;
@@ -8760,21 +8993,21 @@ function applyProviderPatch(h, args, payload) {
8760
8993
  });
8761
8994
  }
8762
8995
  async function executeProviderScript(h, args, scriptName) {
8763
- const { agentType, ideType } = args || {};
8764
- if (!agentType) return { success: false, error: "agentType is required" };
8996
+ const resolvedProviderType = h.currentSession?.providerType || h.currentProviderType || args?.agentType || args?.providerType;
8997
+ if (!resolvedProviderType) return { success: false, error: "targetSessionId or providerType is required" };
8765
8998
  const loader = h.ctx.providerLoader;
8766
8999
  if (!loader) return { success: false, error: "ProviderLoader not initialized" };
8767
- const provider = loader.resolve(agentType);
8768
- if (!provider) return { success: false, error: `Provider not found: ${agentType}` };
9000
+ const provider = loader.resolve(resolvedProviderType);
9001
+ if (!provider) return { success: false, error: `Provider not found: ${resolvedProviderType}` };
8769
9002
  const webviewScriptName = `webview${scriptName.charAt(0).toUpperCase() + scriptName.slice(1)}`;
8770
9003
  const hasWebviewScript = provider.category === "ide" && !!provider.scripts?.[webviewScriptName];
8771
9004
  const actualScriptName = hasWebviewScript ? webviewScriptName : scriptName;
8772
9005
  if (!provider.scripts?.[actualScriptName]) {
8773
- return { success: false, error: `Script '${actualScriptName}' not available for ${agentType}` };
9006
+ return { success: false, error: `Script '${actualScriptName}' not available for ${resolvedProviderType}` };
8774
9007
  }
8775
9008
  const normalizedArgs = normalizeProviderScriptArgs(args);
8776
9009
  if (provider.category === "cli") {
8777
- const adapter = h.getCliAdapter(args?.targetSessionId || agentType);
9010
+ const adapter = h.getCliAdapter(args?.targetSessionId || resolvedProviderType);
8778
9011
  if (!adapter?.invokeScript) {
8779
9012
  return { success: false, error: `CLI adapter does not support script '${actualScriptName}'` };
8780
9013
  }
@@ -8799,7 +9032,7 @@ async function executeProviderScript(h, args, scriptName) {
8799
9032
  const scriptFn = provider.scripts[actualScriptName];
8800
9033
  const scriptCode = scriptFn(normalizedArgs);
8801
9034
  if (!scriptCode) return { success: false, error: `Script '${actualScriptName}' returned null` };
8802
- const cdpKey = provider.category === "ide" ? h.currentSession?.cdpManagerKey || h.currentManagerKey || agentType : h.currentSession?.cdpManagerKey || h.currentManagerKey || ideType;
9035
+ const cdpKey = provider.category === "ide" ? h.currentSession?.cdpManagerKey || h.currentManagerKey || resolvedProviderType : h.currentSession?.cdpManagerKey || h.currentManagerKey;
8803
9036
  LOG.info("Command", `[ExtScript] provider=${provider.type} category=${provider.category} cdpKey=${cdpKey}`);
8804
9037
  const cdp = h.getCdp(cdpKey);
8805
9038
  if (!cdp?.isConnected) return { success: false, error: `No CDP connection for ${cdpKey || "any"}` };
@@ -8807,7 +9040,7 @@ async function executeProviderScript(h, args, scriptName) {
8807
9040
  let result;
8808
9041
  if (provider.category === "extension") {
8809
9042
  const runtimeSessionId = h.currentSession?.sessionId || args?.targetSessionId;
8810
- if (!runtimeSessionId) return { success: false, error: `No target session found for ${agentType}` };
9043
+ if (!runtimeSessionId) return { success: false, error: `No target session found for ${resolvedProviderType}` };
8811
9044
  const parentSessionId = h.currentSession?.parentSessionId;
8812
9045
  if (parentSessionId) {
8813
9046
  await h.agentStream?.setActiveSession(cdp, parentSessionId, runtimeSessionId);
@@ -8836,7 +9069,7 @@ async function executeProviderScript(h, args, scriptName) {
8836
9069
  }
8837
9070
  } else {
8838
9071
  if (!targetSessionId) {
8839
- return { success: false, error: `No active session found for ${agentType}` };
9072
+ return { success: false, error: `No active session found for ${resolvedProviderType}` };
8840
9073
  }
8841
9074
  result = await cdp.evaluateInSessionFrame(targetSessionId, scriptCode);
8842
9075
  }
@@ -10219,14 +10452,6 @@ ${effect.notification.body || ""}`.trim();
10219
10452
  var import_stream = require("stream");
10220
10453
  var import_child_process5 = require("child_process");
10221
10454
  var import_sdk = require("@agentclientprotocol/sdk");
10222
-
10223
- // src/providers/contracts.ts
10224
- function flattenContent(content) {
10225
- if (typeof content === "string") return content;
10226
- return content.filter((b) => b.type === "text").map((b) => b.text).join("\n");
10227
- }
10228
-
10229
- // src/providers/acp-provider-instance.ts
10230
10455
  init_logger();
10231
10456
  var AcpProviderInstance = class {
10232
10457
  constructor(provider, workingDir, cliArgs = []) {
@@ -13592,6 +13817,37 @@ function buildAvailableProviders(providerLoader) {
13592
13817
  ...provider.detectedPath !== void 0 ? { detectedPath: provider.detectedPath } : {}
13593
13818
  }));
13594
13819
  }
13820
+ function buildMachineInfo(profile = "full") {
13821
+ const base = {
13822
+ hostname: os16.hostname(),
13823
+ platform: os16.platform()
13824
+ };
13825
+ if (profile === "live") {
13826
+ return base;
13827
+ }
13828
+ if (profile === "metadata") {
13829
+ const memSnap2 = getHostMemorySnapshot();
13830
+ return {
13831
+ ...base,
13832
+ arch: os16.arch(),
13833
+ cpus: os16.cpus().length,
13834
+ totalMem: memSnap2.totalMem,
13835
+ release: os16.release()
13836
+ };
13837
+ }
13838
+ const memSnap = getHostMemorySnapshot();
13839
+ return {
13840
+ ...base,
13841
+ arch: os16.arch(),
13842
+ cpus: os16.cpus().length,
13843
+ totalMem: memSnap.totalMem,
13844
+ freeMem: memSnap.freeMem,
13845
+ availableMem: memSnap.availableMem,
13846
+ loadavg: os16.loadavg(),
13847
+ uptime: os16.uptime(),
13848
+ release: os16.release()
13849
+ };
13850
+ }
13595
13851
  function parseMessageTime(value) {
13596
13852
  if (typeof value === "number" && Number.isFinite(value)) return value;
13597
13853
  if (typeof value === "string") {
@@ -13647,26 +13903,35 @@ function buildRecentLaunches(recentActivity) {
13647
13903
  })).sort((a, b) => b.lastLaunchedAt - a.lastLaunchedAt).slice(0, 12);
13648
13904
  }
13649
13905
  function buildStatusSnapshot(options) {
13906
+ const profile = options.profile || "full";
13650
13907
  const cfg = loadConfig();
13651
13908
  const state = loadState();
13652
13909
  const wsState = getWorkspaceState(cfg);
13653
- const memSnap = getHostMemorySnapshot();
13654
13910
  const recentActivity = getRecentActivity(state, 20);
13655
- const sessions = buildSessionEntries(
13911
+ const unreadSourceSessions = buildSessionEntries(
13656
13912
  options.allStates,
13657
- options.cdpManagers
13913
+ options.cdpManagers,
13914
+ { profile: "full" }
13658
13915
  );
13659
- for (const session of sessions) {
13660
- const lastSeenAt = getSessionSeenAt(state, session.id);
13661
- const seenCompletionMarker = getSessionSeenMarker(state, session.id);
13662
- const lastUsedAt = getSessionLastUsedAt(session);
13663
- const completionMarker = getSessionCompletionMarker(session);
13664
- const { unread, inboxBucket } = session.surfaceHidden ? { unread: false, inboxBucket: "idle" } : getUnreadState(
13665
- getSessionMessageUpdatedAt(session) > 0,
13666
- session.status,
13916
+ const sessions = profile === "full" ? unreadSourceSessions : buildSessionEntries(
13917
+ options.allStates,
13918
+ options.cdpManagers,
13919
+ { profile }
13920
+ );
13921
+ const sessionsById = new Map(sessions.map((session) => [session.id, session]));
13922
+ for (const sourceSession of unreadSourceSessions) {
13923
+ const session = sessionsById.get(sourceSession.id);
13924
+ if (!session) continue;
13925
+ const lastSeenAt = getSessionSeenAt(state, sourceSession.id);
13926
+ const seenCompletionMarker = getSessionSeenMarker(state, sourceSession.id);
13927
+ const lastUsedAt = getSessionLastUsedAt(sourceSession);
13928
+ const completionMarker = getSessionCompletionMarker(sourceSession);
13929
+ const { unread, inboxBucket } = sourceSession.surfaceHidden ? { unread: false, inboxBucket: "idle" } : getUnreadState(
13930
+ getSessionMessageUpdatedAt(sourceSession) > 0,
13931
+ sourceSession.status,
13667
13932
  lastUsedAt,
13668
13933
  lastSeenAt,
13669
- getLastMessageRole(session),
13934
+ getLastMessageRole(sourceSession),
13670
13935
  completionMarker,
13671
13936
  seenCompletionMarker
13672
13937
  );
@@ -13676,39 +13941,30 @@ function buildStatusSnapshot(options) {
13676
13941
  if (READ_DEBUG_ENABLED && (session.unread || session.inboxBucket !== "idle" || session.providerType.includes("codex"))) {
13677
13942
  LOG.info(
13678
13943
  "RecentRead",
13679
- `snapshot session id=${session.id} provider=${session.providerType} status=${String(session.status || "")} bucket=${inboxBucket} unread=${String(unread)} lastSeenAt=${lastSeenAt} completionMarker=${completionMarker || "-"} seenMarker=${seenCompletionMarker || "-"} lastUpdated=${String(session.lastUpdated || 0)} lastUsedAt=${lastUsedAt} lastRole=${getLastMessageRole(session)} msgUpdatedAt=${getSessionMessageUpdatedAt(session)}`
13944
+ `snapshot session id=${session.id} provider=${session.providerType} status=${String(session.status || "")} bucket=${inboxBucket} unread=${String(unread)} lastSeenAt=${lastSeenAt} completionMarker=${completionMarker || "-"} seenMarker=${seenCompletionMarker || "-"} lastUpdated=${String(session.lastUpdated || 0)} lastUsedAt=${lastUsedAt} lastRole=${getLastMessageRole(sourceSession)} msgUpdatedAt=${getSessionMessageUpdatedAt(sourceSession)}`
13680
13945
  );
13681
13946
  }
13682
13947
  }
13683
- const terminalBackend = getTerminalBackendRuntimeStatus();
13948
+ const includeMachineMetadata = profile !== "live";
13949
+ const terminalBackend = includeMachineMetadata ? getTerminalBackendRuntimeStatus() : void 0;
13684
13950
  return {
13685
13951
  instanceId: options.instanceId,
13686
- version: options.version,
13687
- daemonMode: options.daemonMode,
13688
- machine: {
13689
- hostname: os16.hostname(),
13690
- platform: os16.platform(),
13691
- arch: os16.arch(),
13692
- cpus: os16.cpus().length,
13693
- totalMem: memSnap.totalMem,
13694
- freeMem: memSnap.freeMem,
13695
- availableMem: memSnap.availableMem,
13696
- loadavg: os16.loadavg(),
13697
- uptime: os16.uptime(),
13698
- release: os16.release()
13699
- },
13700
- machineNickname: options.machineNickname ?? cfg.machineNickname ?? null,
13952
+ ...includeMachineMetadata ? { version: options.version } : {},
13953
+ machine: buildMachineInfo(profile),
13954
+ ...includeMachineMetadata ? { machineNickname: options.machineNickname ?? cfg.machineNickname ?? null } : {},
13701
13955
  timestamp: options.timestamp ?? Date.now(),
13702
- detectedIdes: buildDetectedIdeInfos(options.detectedIdes, options.cdpManagers),
13703
13956
  ...options.p2p ? { p2p: options.p2p } : {},
13704
13957
  sessions,
13705
- workspaces: wsState.workspaces,
13706
- defaultWorkspaceId: wsState.defaultWorkspaceId,
13707
- defaultWorkspacePath: wsState.defaultWorkspacePath,
13708
- terminalSizingMode: cfg.terminalSizingMode || "measured",
13709
- recentLaunches: buildRecentLaunches(recentActivity),
13710
- terminalBackend,
13711
- availableProviders: buildAvailableProviders(options.providerLoader)
13958
+ ...terminalBackend ? { terminalBackend } : {},
13959
+ ...includeMachineMetadata && {
13960
+ detectedIdes: buildDetectedIdeInfos(options.detectedIdes, options.cdpManagers),
13961
+ workspaces: wsState.workspaces,
13962
+ defaultWorkspaceId: wsState.defaultWorkspaceId,
13963
+ defaultWorkspacePath: wsState.defaultWorkspacePath,
13964
+ terminalSizingMode: cfg.terminalSizingMode || "measured",
13965
+ recentLaunches: buildRecentLaunches(recentActivity),
13966
+ availableProviders: buildAvailableProviders(options.providerLoader)
13967
+ }
13712
13968
  };
13713
13969
  }
13714
13970
 
@@ -14264,6 +14520,25 @@ var DaemonCommandRouter = class {
14264
14520
  updateConfig({ userName: name });
14265
14521
  return { success: true, userName: name };
14266
14522
  }
14523
+ case "get_status_metadata": {
14524
+ const snapshot = buildStatusSnapshot({
14525
+ allStates: this.deps.instanceManager.collectAllStates(),
14526
+ cdpManagers: this.deps.cdpManagers,
14527
+ providerLoader: this.deps.providerLoader,
14528
+ detectedIdes: this.deps.detectedIdes.value,
14529
+ instanceId: this.deps.statusInstanceId || loadConfig().machineId || "daemon",
14530
+ version: this.deps.statusVersion || "unknown",
14531
+ profile: "metadata"
14532
+ });
14533
+ return { success: true, status: snapshot };
14534
+ }
14535
+ case "get_machine_runtime_stats": {
14536
+ return {
14537
+ success: true,
14538
+ machine: buildMachineInfo("full"),
14539
+ timestamp: Date.now()
14540
+ };
14541
+ }
14267
14542
  case "mark_session_seen": {
14268
14543
  const sessionId = args?.sessionId;
14269
14544
  if (!sessionId || typeof sessionId !== "string") {
@@ -14417,6 +14692,7 @@ var DaemonStatusReporter = class {
14417
14692
  lastStatusSentAt = 0;
14418
14693
  statusPendingThrottle = false;
14419
14694
  lastP2PStatusHash = "";
14695
+ lastServerStatusHash = "";
14420
14696
  lastStatusSummary = "";
14421
14697
  statusTimer = null;
14422
14698
  p2pTimer = null;
@@ -14427,11 +14703,11 @@ var DaemonStatusReporter = class {
14427
14703
  // ─── Lifecycle ───────────────────────────────────
14428
14704
  startReporting() {
14429
14705
  setTimeout(() => {
14430
- this.sendUnifiedStatusReport().catch((e) => LOG.warn("Status", `Initial report failed: ${e?.message}`));
14706
+ this.sendUnifiedStatusReport({ forceServer: true, reason: "initial" }).catch((e) => LOG.warn("Status", `Initial report failed: ${e?.message}`));
14431
14707
  }, 2e3);
14432
14708
  const scheduleServerReport = () => {
14433
14709
  this.statusTimer = setTimeout(() => {
14434
- this.sendUnifiedStatusReport().catch((e) => LOG.warn("Status", `Periodic report failed: ${e?.message}`));
14710
+ this.sendUnifiedStatusReport({ forceServer: true, reason: "periodic" }).catch((e) => LOG.warn("Status", `Periodic report failed: ${e?.message}`));
14435
14711
  scheduleServerReport();
14436
14712
  }, 3e4);
14437
14713
  };
@@ -14468,9 +14744,58 @@ var DaemonStatusReporter = class {
14468
14744
  }, 5e3 - elapsed);
14469
14745
  }
14470
14746
  }
14747
+ toDaemonStatusEventName(value) {
14748
+ switch (value) {
14749
+ case "agent:generating_started":
14750
+ case "agent:waiting_approval":
14751
+ case "agent:generating_completed":
14752
+ case "agent:stopped":
14753
+ case "monitor:long_generating":
14754
+ return value;
14755
+ default:
14756
+ return null;
14757
+ }
14758
+ }
14759
+ buildServerStatusEvent(event) {
14760
+ const eventName = this.toDaemonStatusEventName(event.event);
14761
+ if (!eventName) return null;
14762
+ if (eventName.startsWith("provider:")) {
14763
+ return null;
14764
+ }
14765
+ const payload = {
14766
+ event: eventName,
14767
+ timestamp: typeof event.timestamp === "number" && Number.isFinite(event.timestamp) ? event.timestamp : Date.now()
14768
+ };
14769
+ if (typeof event.targetSessionId === "string" && event.targetSessionId.trim()) {
14770
+ payload.targetSessionId = event.targetSessionId.trim();
14771
+ }
14772
+ const providerType = typeof event.providerType === "string" && event.providerType.trim() ? event.providerType.trim() : typeof event.ideType === "string" && event.ideType.trim() ? event.ideType.trim() : "";
14773
+ if (providerType) {
14774
+ payload.providerType = providerType;
14775
+ }
14776
+ if (typeof event.duration === "number" && Number.isFinite(event.duration)) {
14777
+ payload.duration = event.duration;
14778
+ }
14779
+ if (typeof event.elapsedSec === "number" && Number.isFinite(event.elapsedSec)) {
14780
+ payload.elapsedSec = event.elapsedSec;
14781
+ }
14782
+ if (typeof event.modalMessage === "string" && event.modalMessage.trim()) {
14783
+ payload.modalMessage = event.modalMessage;
14784
+ }
14785
+ if (Array.isArray(event.modalButtons)) {
14786
+ const modalButtons = event.modalButtons.filter((button) => typeof button === "string" && button.trim().length > 0);
14787
+ if (modalButtons.length > 0) {
14788
+ payload.modalButtons = modalButtons;
14789
+ }
14790
+ }
14791
+ return payload;
14792
+ }
14471
14793
  emitStatusEvent(event) {
14472
14794
  LOG.info("StatusEvent", `${event.event} (${event.providerType || event.ideType || ""})`);
14473
- this.deps.serverConn?.sendMessage("status_event", event);
14795
+ const serverEvent = this.buildServerStatusEvent(event);
14796
+ if (!serverEvent) return;
14797
+ this.deps.p2p?.sendStatusEvent(serverEvent);
14798
+ this.deps.serverConn?.sendMessage("status_event", serverEvent);
14474
14799
  }
14475
14800
  removeAgentTracking(_key) {
14476
14801
  }
@@ -14539,17 +14864,16 @@ var DaemonStatusReporter = class {
14539
14864
  detectedIdes: this.deps.detectedIdes || [],
14540
14865
  instanceId: this.deps.instanceId,
14541
14866
  version: this.deps.daemonVersion || "unknown",
14542
- daemonMode: true,
14543
14867
  timestamp: now,
14544
14868
  p2p: {
14545
14869
  available: p2p?.isAvailable || false,
14546
14870
  state: p2p?.connectionState || "unavailable",
14547
14871
  peers: p2p?.connectedPeerCount || 0,
14548
14872
  screenshotActive: p2p?.screenshotActive || false
14549
- }
14873
+ },
14874
+ profile: "live"
14550
14875
  }),
14551
- screenshotUsage: this.deps.getScreenshotUsage?.() || null,
14552
- connectedExtensions: []
14876
+ screenshotUsage: this.deps.getScreenshotUsage?.() || null
14553
14877
  };
14554
14878
  const payloadBytes = JSON.stringify(payload).length;
14555
14879
  const p2pSent = this.sendP2PPayload(payload);
@@ -14564,46 +14888,48 @@ var DaemonStatusReporter = class {
14564
14888
  }
14565
14889
  if (opts?.p2pOnly) return;
14566
14890
  const wsPayload = {
14567
- daemonMode: true,
14568
14891
  sessions: sessions.map((session) => ({
14569
14892
  id: session.id,
14570
14893
  parentId: session.parentId,
14571
14894
  providerType: session.providerType,
14572
- providerName: session.providerName,
14895
+ providerName: session.providerName || session.providerType,
14573
14896
  kind: session.kind,
14574
14897
  transport: session.transport,
14575
14898
  status: session.status,
14576
- workspace: session.workspace,
14899
+ workspace: session.workspace ?? null,
14577
14900
  title: session.title,
14578
14901
  cdpConnected: session.cdpConnected,
14579
14902
  currentModel: session.currentModel,
14580
14903
  currentPlan: session.currentPlan,
14581
- currentAutoApprove: session.currentAutoApprove,
14582
- lastUpdated: session.lastUpdated,
14583
- unread: session.unread,
14584
- lastSeenAt: session.lastSeenAt,
14585
- inboxBucket: session.inboxBucket,
14586
- surfaceHidden: session.surfaceHidden,
14587
- controlValues: session.controlValues,
14588
- providerControls: session.providerControls,
14589
- acpConfigOptions: session.acpConfigOptions,
14590
- acpModes: session.acpModes
14904
+ currentAutoApprove: session.currentAutoApprove
14591
14905
  })),
14592
14906
  p2p: payload.p2p,
14593
- timestamp: now,
14594
- detectedIdes: payload.detectedIdes,
14595
- availableProviders: payload.availableProviders
14907
+ timestamp: now
14596
14908
  };
14909
+ const wsHash = this.simpleHash(JSON.stringify({
14910
+ ...wsPayload,
14911
+ timestamp: void 0
14912
+ }));
14913
+ if (!opts?.forceServer && wsHash === this.lastServerStatusHash) {
14914
+ LOG.debug("Server", `skip duplicate status_report${opts?.reason ? ` (${opts.reason})` : ""}`);
14915
+ return;
14916
+ }
14917
+ this.lastServerStatusHash = wsHash;
14597
14918
  serverConn.sendMessage("status_report", wsPayload);
14598
- LOG.debug("Server", `sent status_report (${JSON.stringify(wsPayload).length} bytes)`);
14919
+ LOG.debug("Server", `sent status_report (${JSON.stringify(wsPayload).length} bytes)${opts?.reason ? ` [${opts.reason}]` : ""}`);
14599
14920
  }
14600
14921
  // ─── P2P ─────────────────────────────────────────
14601
14922
  sendP2PPayload(payload) {
14602
14923
  const { timestamp: _ts, system: _sys, ...hashTarget } = payload;
14924
+ const sessions = Array.isArray(hashTarget.sessions) ? hashTarget.sessions.map((session) => {
14925
+ if (!session || typeof session !== "object") return session;
14926
+ const { lastUpdated: _lu, ...stableSession } = session;
14927
+ return stableSession;
14928
+ }) : hashTarget.sessions;
14603
14929
  const hashPayload = hashTarget.machine ? (() => {
14604
14930
  const { freeMem: _f, availableMem: _a, loadavg: _l, uptime: _u, ...stableMachine } = hashTarget.machine;
14605
- return { ...hashTarget, machine: stableMachine };
14606
- })() : hashTarget;
14931
+ return { ...hashTarget, sessions, machine: stableMachine };
14932
+ })() : { ...hashTarget, sessions };
14607
14933
  const h = this.simpleHash(JSON.stringify(hashPayload));
14608
14934
  if (h !== this.lastP2PStatusHash) {
14609
14935
  this.lastP2PStatusHash = h;
@@ -21701,6 +22027,8 @@ async function initDaemonComponents(config) {
21701
22027
  onStatusChange: config.onStatusChange,
21702
22028
  onPostChatCommand: config.onPostChatCommand,
21703
22029
  sessionHostControl: config.sessionHostControl,
22030
+ statusInstanceId: config.statusInstanceId,
22031
+ statusVersion: config.statusVersion,
21704
22032
  getCdpLogFn: config.getCdpLogFn || ((ideType) => LOG.forComponent(`CDP:${ideType}`).asLogFn())
21705
22033
  });
21706
22034
  poller = new AgentStreamPoller({
@@ -21803,6 +22131,7 @@ async function shutdownDaemonComponents(components) {
21803
22131
  SessionHostPtyTransportFactory,
21804
22132
  VersionArchive,
21805
22133
  appendRecentActivity,
22134
+ buildMachineInfo,
21806
22135
  buildSessionEntries,
21807
22136
  buildStatusSnapshot,
21808
22137
  connectCdpManager,