adhdev 0.8.87 → 0.8.89

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.
package/dist/index.js CHANGED
@@ -5847,6 +5847,25 @@ var init_setup = __esm({
5847
5847
  }
5848
5848
  });
5849
5849
 
5850
+ // ../../oss/packages/daemon-core/src/runtime-defaults.ts
5851
+ var DEFAULT_CDP_SCAN_INTERVAL_MS, DEFAULT_CDP_DISCOVERY_INTERVAL_MS, DEFAULT_STATUS_INITIAL_REPORT_DELAY_MS, DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS, DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS, MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS, DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS, MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS, DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS, DEFAULT_SESSION_HOST_READY_TIMEOUT_MS, STANDALONE_CDP_SCAN_INTERVAL_MS;
5852
+ var init_runtime_defaults = __esm({
5853
+ "../../oss/packages/daemon-core/src/runtime-defaults.ts"() {
5854
+ "use strict";
5855
+ DEFAULT_CDP_SCAN_INTERVAL_MS = 3e4;
5856
+ DEFAULT_CDP_DISCOVERY_INTERVAL_MS = 3e4;
5857
+ DEFAULT_STATUS_INITIAL_REPORT_DELAY_MS = 2e3;
5858
+ DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS = 3e4;
5859
+ DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS = 5e3;
5860
+ MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS = 5e3;
5861
+ DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS = 15e3;
5862
+ MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS = 5e3;
5863
+ DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS = 1e4;
5864
+ DEFAULT_SESSION_HOST_READY_TIMEOUT_MS = 15e3;
5865
+ STANDALONE_CDP_SCAN_INTERVAL_MS = 15e3;
5866
+ }
5867
+ });
5868
+
5850
5869
  // ../../oss/packages/daemon-core/src/cdp/scanner.ts
5851
5870
  var DaemonCdpScanner;
5852
5871
  var init_scanner = __esm({
@@ -5855,6 +5874,7 @@ var init_scanner = __esm({
5855
5874
  init_manager();
5856
5875
  init_setup();
5857
5876
  init_logger();
5877
+ init_runtime_defaults();
5858
5878
  DaemonCdpScanner = class {
5859
5879
  ctx;
5860
5880
  opts;
@@ -5888,7 +5908,7 @@ var init_scanner = __esm({
5888
5908
  */
5889
5909
  startPeriodicScan() {
5890
5910
  if (this.scanTimer) return;
5891
- const interval = this.opts.scanIntervalMs || 3e4;
5911
+ const interval = this.opts.scanIntervalMs || DEFAULT_CDP_SCAN_INTERVAL_MS;
5892
5912
  this.scanTimer = setInterval(async () => {
5893
5913
  const portMap = this.ctx.providerLoader.getCdpPortMap();
5894
5914
  for (const [ide, ports] of Object.entries(portMap)) {
@@ -5908,7 +5928,7 @@ var init_scanner = __esm({
5908
5928
  /**
5909
5929
  * Start periodic agent webview discovery on all connected CDPs.
5910
5930
  */
5911
- startWebviewDiscovery(intervalMs = 3e4) {
5931
+ startWebviewDiscovery(intervalMs = DEFAULT_CDP_DISCOVERY_INTERVAL_MS) {
5912
5932
  if (this.discoveryTimer) return;
5913
5933
  this.discoveryTimer = setInterval(async () => {
5914
5934
  for (const m of this.ctx.cdpManagers.values()) {
@@ -6008,6 +6028,7 @@ var init_initializer = __esm({
6008
6028
  init_setup();
6009
6029
  init_setup();
6010
6030
  init_logger();
6031
+ init_runtime_defaults();
6011
6032
  DaemonCdpInitializer = class {
6012
6033
  config;
6013
6034
  scanTimer = null;
@@ -6139,7 +6160,7 @@ var init_initializer = __esm({
6139
6160
  * Start periodic scanning for newly opened IDEs.
6140
6161
  * Idempotent — ignored if already started.
6141
6162
  */
6142
- startPeriodicScan(intervalMs = 3e4) {
6163
+ startPeriodicScan(intervalMs = DEFAULT_CDP_SCAN_INTERVAL_MS) {
6143
6164
  if (this.scanTimer) return;
6144
6165
  this.scanTimer = setInterval(async () => {
6145
6166
  const { providerLoader, cdpManagers } = this.config;
@@ -6153,7 +6174,7 @@ var init_initializer = __esm({
6153
6174
  /**
6154
6175
  * Start periodic agent webview discovery.
6155
6176
  */
6156
- startDiscovery(intervalMs = 3e4) {
6177
+ startDiscovery(intervalMs = DEFAULT_CDP_DISCOVERY_INTERVAL_MS) {
6157
6178
  if (this.discoveryTimer) return;
6158
6179
  this.discoveryTimer = setInterval(async () => {
6159
6180
  for (const m of this.config.cdpManagers.values()) {
@@ -11776,8 +11797,7 @@ var init_provider_cli_adapter = __esm({
11776
11797
  const buttons = Array.isArray(modal.buttons) ? modal.buttons : [];
11777
11798
  if (buttons.length !== 1) return false;
11778
11799
  const buttonLabel = String(buttons[0] || "").trim();
11779
- const modalText = `${modal.message || ""} ${buttonLabel}`.trim();
11780
- return looksLikeConfirmOnlyLabel(buttonLabel) || /Quick safety check|project trust|trust (?:this project|the contents of this directory|the files in this folder)|Enter to confirm/i.test(modalText);
11800
+ return looksLikeConfirmOnlyLabel(buttonLabel);
11781
11801
  }
11782
11802
  async waitForInteractivePrompt(maxWaitMs = 5e3) {
11783
11803
  const startedAt = Date.now();
@@ -12393,11 +12413,14 @@ var init_provider_cli_adapter = __esm({
12393
12413
  }
12394
12414
  // ─── Public API (CliAdapter) ───────────────────
12395
12415
  getStatus() {
12416
+ const screenText = this.terminalScreen.getText() || "";
12417
+ const startupModal = this.startupParseGate ? this.getStartupConfirmationModal(screenText) : null;
12418
+ const effectiveStatus = this.parseErrorMessage ? "error" : startupModal ? "waiting_approval" : this.currentStatus;
12396
12419
  return {
12397
- status: this.parseErrorMessage ? "error" : this.currentStatus,
12420
+ status: effectiveStatus,
12398
12421
  messages: [...this.committedMessages],
12399
12422
  workingDir: this.workingDir,
12400
- activeModal: this.activeModal,
12423
+ activeModal: startupModal || this.activeModal,
12401
12424
  errorMessage: this.parseErrorMessage || void 0,
12402
12425
  errorReason: this.parseErrorMessage ? "parse_error" : void 0
12403
12426
  };
@@ -12450,8 +12473,38 @@ var init_provider_cli_adapter = __esm({
12450
12473
  index: typeof message.index === "number" ? message.index : index,
12451
12474
  receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
12452
12475
  }));
12453
- const shouldPreferCommittedHistoryReplay = !this.currentTurnScope && !this.activeModal && committedHydratedMessages.length > parsedHydratedMessages.length;
12454
- const hydratedMessages = shouldPreferCommittedMessages || shouldPreferCommittedHistoryReplay ? committedHydratedMessages : parsedHydratedMessages;
12476
+ const parsedLastAssistant = [...parsedHydratedMessages].reverse().find((message) => message.role === "assistant" && typeof message.content === "string" && message.content.trim());
12477
+ const visibleIdlePrompt = this.looksLikeVisibleIdlePrompt(screenText);
12478
+ const shouldAdoptParsedIdleReplay = !this.currentTurnScope && !this.activeModal && !!parsedLastAssistant && parsedHydratedMessages.length > committedHydratedMessages.length && (this.currentStatus === "idle" || this.currentStatus === "generating" && this.isWaitingForResponse && parsed.status === "idle" && visibleIdlePrompt);
12479
+ if (shouldAdoptParsedIdleReplay) {
12480
+ this.committedMessages = normalizeCliParsedMessages(parsed.messages, {
12481
+ committedMessages: this.committedMessages,
12482
+ scope: this.currentTurnScope,
12483
+ lastOutputAt: this.lastOutputAt
12484
+ });
12485
+ this.syncMessageViews();
12486
+ if (this.currentStatus !== "idle" || this.isWaitingForResponse) {
12487
+ this.responseBuffer = "";
12488
+ this.isWaitingForResponse = false;
12489
+ this.responseSettleIgnoreUntil = 0;
12490
+ this.submitRetryUsed = false;
12491
+ this.submitRetryPromptSnippet = "";
12492
+ this.finishRetryCount = 0;
12493
+ this.currentTurnScope = null;
12494
+ this.activeModal = null;
12495
+ this.setStatus("idle", "parsed_idle_replay_commit");
12496
+ this.onStatusChange?.();
12497
+ }
12498
+ }
12499
+ const effectiveCommittedHydratedMessages = shouldAdoptParsedIdleReplay ? this.committedMessages.map((message, index) => buildChatMessage({
12500
+ ...message,
12501
+ id: message.id || `msg_${index}`,
12502
+ index: typeof message.index === "number" ? message.index : index,
12503
+ receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
12504
+ })) : committedHydratedMessages;
12505
+ const shouldPreferCommittedHistoryReplay = !this.currentTurnScope && !this.activeModal && effectiveCommittedHydratedMessages.length > parsedHydratedMessages.length;
12506
+ const shouldPreferCommittedIdleReplay = shouldPreferCommittedMessages && !shouldAdoptParsedIdleReplay;
12507
+ const hydratedMessages = shouldPreferCommittedIdleReplay || shouldPreferCommittedHistoryReplay ? effectiveCommittedHydratedMessages : parsedHydratedMessages;
12455
12508
  result = {
12456
12509
  id: parsed.id || "cli_session",
12457
12510
  status: parsed.status || this.currentStatus,
@@ -13052,8 +13105,9 @@ ${data.message || ""}`.trim();
13052
13105
  this.ptyProcess?.write(data);
13053
13106
  }
13054
13107
  resolveModal(buttonIndex) {
13055
- if (!this.ptyProcess || this.currentStatus !== "waiting_approval" && !this.activeModal) return;
13056
- const modal = this.activeModal;
13108
+ const screenText = this.terminalScreen.getText() || "";
13109
+ const modal = this.activeModal || this.getStartupConfirmationModal(screenText);
13110
+ if (!this.ptyProcess || this.currentStatus !== "waiting_approval" && !modal) return;
13057
13111
  this.clearIdleFinishCandidate("resolve_modal");
13058
13112
  this.recordTrace("resolve_modal", {
13059
13113
  buttonIndex,
@@ -13068,7 +13122,10 @@ ${data.message || ""}`.trim();
13068
13122
  }
13069
13123
  this.setStatus("generating", "approval_resolved");
13070
13124
  this.onStatusChange?.();
13071
- if (this.shouldResolveModalWithEnter(modal, buttonIndex)) {
13125
+ const startupTrustModal = /Quick safety check|project trust|trust (?:this project|the contents of this directory|the files in this folder)/i.test(String(modal?.message || ""));
13126
+ if (startupTrustModal && buttonIndex in this.approvalKeys) {
13127
+ this.ptyProcess.write(`${this.approvalKeys[buttonIndex]}\r`);
13128
+ } else if (this.shouldResolveModalWithEnter(modal, buttonIndex)) {
13072
13129
  this.ptyProcess.write("\r");
13073
13130
  } else if (buttonIndex in this.approvalKeys) {
13074
13131
  this.ptyProcess.write(this.approvalKeys[buttonIndex]);
@@ -13089,20 +13146,24 @@ ${data.message || ""}`.trim();
13089
13146
  }
13090
13147
  }
13091
13148
  getDebugState() {
13149
+ const screenText = sanitizeTerminalText(this.terminalScreen.getText());
13150
+ const startupModal = this.startupParseGate ? this.getStartupConfirmationModal(screenText) : null;
13151
+ const effectiveStatus = startupModal ? "waiting_approval" : this.currentStatus;
13152
+ const effectiveReady = this.ready || !!startupModal;
13092
13153
  return {
13093
13154
  type: this.cliType,
13094
13155
  name: this.cliName,
13095
13156
  providerResolution: this.providerResolutionMeta,
13096
- status: this.currentStatus,
13097
- ready: this.ready,
13157
+ status: effectiveStatus,
13158
+ ready: effectiveReady,
13098
13159
  startupParseGate: this.startupParseGate,
13099
13160
  spawnAt: this.spawnAt,
13100
13161
  workingDir: this.workingDir,
13101
- messages: this.messages.slice(-20),
13102
- committedMessages: this.committedMessages.slice(-20),
13103
- structuredMessages: this.structuredMessages.slice(-20),
13162
+ messages: this.messages,
13163
+ committedMessages: this.committedMessages,
13164
+ structuredMessages: this.structuredMessages,
13104
13165
  messageCount: this.committedMessages.length,
13105
- screenText: sanitizeTerminalText(this.terminalScreen.getText()).slice(-4e3),
13166
+ screenText: screenText.slice(-4e3),
13106
13167
  currentTurnScope: this.currentTurnScope,
13107
13168
  startupBuffer: this.startupBuffer.slice(-4e3),
13108
13169
  recentOutputBuffer: this.recentOutputBuffer.slice(-500),
@@ -13117,7 +13178,7 @@ ${data.message || ""}`.trim();
13117
13178
  lastScreenChangeAt: this.lastScreenChangeAt,
13118
13179
  lastScreenSnapshot: this.lastScreenSnapshot.slice(-500),
13119
13180
  isWaitingForResponse: this.isWaitingForResponse,
13120
- activeModal: this.activeModal,
13181
+ activeModal: startupModal || this.activeModal,
13121
13182
  lastApprovalResolvedAt: this.lastApprovalResolvedAt,
13122
13183
  sendDelayMs: this.sendDelayMs,
13123
13184
  sendKey: this.sendKey,
@@ -37193,6 +37254,7 @@ var init_reporter = __esm({
37193
37254
  "../../oss/packages/daemon-core/src/status/reporter.ts"() {
37194
37255
  "use strict";
37195
37256
  init_logger();
37257
+ init_runtime_defaults();
37196
37258
  init_builders();
37197
37259
  init_snapshot();
37198
37260
  DaemonStatusReporter = class {
@@ -37213,19 +37275,19 @@ var init_reporter = __esm({
37213
37275
  startReporting() {
37214
37276
  setTimeout(() => {
37215
37277
  this.sendUnifiedStatusReport({ forceServer: true, reason: "initial" }).catch((e) => LOG.warn("Status", `Initial report failed: ${e?.message}`));
37216
- }, 2e3);
37278
+ }, DEFAULT_STATUS_INITIAL_REPORT_DELAY_MS);
37217
37279
  const scheduleServerReport = () => {
37218
37280
  this.statusTimer = setTimeout(() => {
37219
37281
  this.sendUnifiedStatusReport({ forceServer: true, reason: "periodic" }).catch((e) => LOG.warn("Status", `Periodic report failed: ${e?.message}`));
37220
37282
  scheduleServerReport();
37221
- }, 3e4);
37283
+ }, DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS);
37222
37284
  };
37223
37285
  scheduleServerReport();
37224
37286
  this.p2pTimer = setInterval(() => {
37225
37287
  if (this.deps.p2p?.isConnected) {
37226
37288
  this.sendUnifiedStatusReport({ p2pOnly: true }).catch((e) => LOG.warn("Status", `P2P status send failed: ${e?.message}`));
37227
37289
  }
37228
- }, 5e3);
37290
+ }, DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS);
37229
37291
  }
37230
37292
  stopReporting() {
37231
37293
  if (this.statusTimer) {
@@ -37243,14 +37305,14 @@ var init_reporter = __esm({
37243
37305
  throttledReport() {
37244
37306
  const now = Date.now();
37245
37307
  const elapsed = now - this.lastStatusSentAt;
37246
- if (elapsed >= 5e3) {
37308
+ if (elapsed >= DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS) {
37247
37309
  this.sendUnifiedStatusReport().catch((e) => LOG.warn("Status", `Throttled report failed: ${e?.message}`));
37248
37310
  } else if (!this.statusPendingThrottle) {
37249
37311
  this.statusPendingThrottle = true;
37250
37312
  setTimeout(() => {
37251
37313
  this.statusPendingThrottle = false;
37252
37314
  this.sendUnifiedStatusReport().catch((e) => LOG.warn("Status", `Deferred report failed: ${e?.message}`));
37253
- }, 5e3 - elapsed);
37315
+ }, DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS - elapsed);
37254
37316
  }
37255
37317
  }
37256
37318
  toDaemonStatusEventName(value) {
@@ -44676,7 +44738,8 @@ var init_runtime_support = __esm({
44676
44738
  "../../oss/packages/daemon-core/src/session-host/runtime-support.ts"() {
44677
44739
  "use strict";
44678
44740
  init_dist();
44679
- STARTUP_TIMEOUT_MS = 8e3;
44741
+ init_runtime_defaults();
44742
+ STARTUP_TIMEOUT_MS = DEFAULT_SESSION_HOST_READY_TIMEOUT_MS;
44680
44743
  STARTUP_POLL_MS = 200;
44681
44744
  }
44682
44745
  });
@@ -45056,8 +45119,8 @@ async function initDaemonComponents(config2) {
45056
45119
  }
45057
45120
  });
45058
45121
  await cdpInitializer.connectAll(detectedIdesRef.value);
45059
- cdpInitializer.startPeriodicScan(config2.cdpScanIntervalMs ?? 3e4);
45060
- cdpInitializer.startDiscovery(3e4);
45122
+ cdpInitializer.startPeriodicScan(config2.cdpScanIntervalMs ?? DEFAULT_CDP_SCAN_INTERVAL_MS);
45123
+ cdpInitializer.startDiscovery(DEFAULT_CDP_DISCOVERY_INTERVAL_MS);
45061
45124
  const commandHandler = new DaemonCommandHandler({
45062
45125
  cdpManagers,
45063
45126
  ideType: "unknown",
@@ -45196,6 +45259,7 @@ var init_daemon_lifecycle = __esm({
45196
45259
  init_cli_detector();
45197
45260
  init_registry();
45198
45261
  init_logger();
45262
+ init_runtime_defaults();
45199
45263
  init_config();
45200
45264
  }
45201
45265
  });
@@ -45210,10 +45274,19 @@ __export(src_exports, {
45210
45274
  CliProviderInstance: () => CliProviderInstance,
45211
45275
  DAEMON_WS_PATH: () => DAEMON_WS_PATH,
45212
45276
  DEFAULT_ACTIVE_CHAT_POLL_STATUSES: () => DEFAULT_ACTIVE_CHAT_POLL_STATUSES,
45277
+ DEFAULT_CDP_DISCOVERY_INTERVAL_MS: () => DEFAULT_CDP_DISCOVERY_INTERVAL_MS,
45278
+ DEFAULT_CDP_SCAN_INTERVAL_MS: () => DEFAULT_CDP_SCAN_INTERVAL_MS,
45213
45279
  DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS: () => DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS,
45214
45280
  DEFAULT_DAEMON_PORT: () => DEFAULT_DAEMON_PORT,
45281
+ DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS: () => DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS,
45215
45282
  DEFAULT_SESSION_HOST_APP_NAME: () => DEFAULT_SESSION_HOST_APP_NAME,
45283
+ DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS: () => DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS,
45284
+ DEFAULT_SESSION_HOST_READY_TIMEOUT_MS: () => DEFAULT_SESSION_HOST_READY_TIMEOUT_MS,
45216
45285
  DEFAULT_STANDALONE_SESSION_HOST_APP_NAME: () => DEFAULT_STANDALONE_SESSION_HOST_APP_NAME,
45286
+ DEFAULT_STATUS_INITIAL_REPORT_DELAY_MS: () => DEFAULT_STATUS_INITIAL_REPORT_DELAY_MS,
45287
+ DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS: () => DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS,
45288
+ DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS: () => DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS,
45289
+ DEV_SERVER_PORT: () => DEV_SERVER_PORT,
45217
45290
  DaemonAgentStreamManager: () => DaemonAgentStreamManager,
45218
45291
  DaemonCdpInitializer: () => DaemonCdpInitializer,
45219
45292
  DaemonCdpManager: () => DaemonCdpManager,
@@ -45225,10 +45298,13 @@ __export(src_exports, {
45225
45298
  DevServer: () => DevServer,
45226
45299
  IdeProviderInstance: () => IdeProviderInstance,
45227
45300
  LOG: () => LOG,
45301
+ MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS: () => MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS,
45302
+ MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS: () => MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS,
45228
45303
  NodePtyTransportFactory: () => NodePtyTransportFactory,
45229
45304
  ProviderCliAdapter: () => ProviderCliAdapter,
45230
45305
  ProviderInstanceManager: () => ProviderInstanceManager,
45231
45306
  ProviderLoader: () => ProviderLoader,
45307
+ STANDALONE_CDP_SCAN_INTERVAL_MS: () => STANDALONE_CDP_SCAN_INTERVAL_MS,
45232
45308
  SessionHostPtyTransportFactory: () => SessionHostPtyTransportFactory,
45233
45309
  VersionArchive: () => VersionArchive,
45234
45310
  appendRecentActivity: () => appendRecentActivity,
@@ -45367,6 +45443,7 @@ var init_src = __esm({
45367
45443
  init_cli_manager();
45368
45444
  init_launch();
45369
45445
  init_ipc_protocol();
45446
+ init_runtime_defaults();
45370
45447
  init_chat_history();
45371
45448
  init_chat_signatures();
45372
45449
  init_subscription_updates();
@@ -45626,6 +45703,10 @@ var init_server_connection = __esm({
45626
45703
  }
45627
45704
  }
45628
45705
  scheduleReconnect() {
45706
+ if (this.reconnectTimer) {
45707
+ clearTimeout(this.reconnectTimer);
45708
+ this.reconnectTimer = null;
45709
+ }
45629
45710
  const delay = Math.min(2e3 * Math.pow(1.5, this.reconnectAttempts), 6e4);
45630
45711
  this.reconnectAttempts++;
45631
45712
  LOG.info("Server", `[ServerConn] Reconnecting in ${(delay / 1e3).toFixed(1)}s (attempt ${this.reconnectAttempts})...`);
@@ -46273,9 +46354,44 @@ async function initiateConnection(deps, peerId, sharePermission) {
46273
46354
  clearTimeout(peer.failedCleanupTimer);
46274
46355
  peer.failedCleanupTimer = void 0;
46275
46356
  }
46357
+ if (peer.disconnectTimer) {
46358
+ clearTimeout(peer.disconnectTimer);
46359
+ peer.disconnectTimer = void 0;
46360
+ }
46276
46361
  deps.notifyStateChange();
46362
+ } else if (pcState === "disconnected") {
46363
+ log(`Peer ${pid} ICE disconnected \u2014 waiting 3s for recovery`);
46364
+ if (peer.disconnectTimer) clearTimeout(peer.disconnectTimer);
46365
+ peer.disconnectTimer = setTimeout(() => {
46366
+ const p = deps.peers.get(pid);
46367
+ if (!p) return;
46368
+ p.disconnectTimer = void 0;
46369
+ let currentState;
46370
+ try {
46371
+ currentState = pc.state?.();
46372
+ } catch {
46373
+ }
46374
+ if (currentState !== "connected") {
46375
+ log(`Peer ${pid} ICE recovery timeout (state=${currentState ?? "unknown"}) \u2014 marking failed`);
46376
+ p.state = "failed";
46377
+ deps.notifyStateChange();
46378
+ if (!p.failedCleanupTimer) {
46379
+ p.failedCleanupTimer = setTimeout(() => {
46380
+ const pp = deps.peers.get(pid);
46381
+ if (pp?.state === "failed") {
46382
+ log(`Auto-cleanup stale failed peer ${pid}`);
46383
+ disconnectPeer(deps.peers, pid, deps.notifyStateChange);
46384
+ }
46385
+ }, 3e4);
46386
+ }
46387
+ }
46388
+ }, 3e3);
46277
46389
  } else if (pcState === "failed" || pcState === "closed") {
46278
46390
  peer.state = "failed";
46391
+ if (peer.disconnectTimer) {
46392
+ clearTimeout(peer.disconnectTimer);
46393
+ peer.disconnectTimer = void 0;
46394
+ }
46279
46395
  deps.notifyStateChange();
46280
46396
  if (!peer.failedCleanupTimer) {
46281
46397
  peer.failedCleanupTimer = setTimeout(() => {
@@ -46433,6 +46549,7 @@ function disconnectPeer(peers, peerId, notifyStateChange) {
46433
46549
  if (peer.failedCleanupTimer) clearTimeout(peer.failedCleanupTimer);
46434
46550
  if (peer.heartbeatTimer) clearInterval(peer.heartbeatTimer);
46435
46551
  if (peer.connectionTimeout) clearTimeout(peer.connectionTimeout);
46552
+ if (peer.disconnectTimer) clearTimeout(peer.disconnectTimer);
46436
46553
  if (peer.dataChannel) try {
46437
46554
  peer.dataChannel.close();
46438
46555
  } catch {
@@ -53834,8 +53951,9 @@ var init_session_host = __esm({
53834
53951
  init_src();
53835
53952
  init_dist();
53836
53953
  init_session_host_hygiene();
53954
+ init_runtime_defaults();
53837
53955
  SESSION_HOST_APP_NAME = process.env.ADHDEV_SESSION_HOST_NAME || DEFAULT_SESSION_HOST_APP_NAME;
53838
- SESSION_HOST_START_TIMEOUT_MS = 15e3;
53956
+ SESSION_HOST_START_TIMEOUT_MS = DEFAULT_SESSION_HOST_READY_TIMEOUT_MS;
53839
53957
  }
53840
53958
  });
53841
53959
 
@@ -54677,7 +54795,8 @@ var init_adhdev_daemon = __esm({
54677
54795
  init_source2();
54678
54796
  init_version();
54679
54797
  init_src();
54680
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.87" });
54798
+ init_runtime_defaults();
54799
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.89" });
54681
54800
  AdhdevDaemon = class _AdhdevDaemon {
54682
54801
  localHttpServer = null;
54683
54802
  localWss = null;
@@ -54709,7 +54828,7 @@ var init_adhdev_daemon = __esm({
54709
54828
  "session_host_restart_session"
54710
54829
  ]);
54711
54830
  constructor() {
54712
- this.localPort = 19222;
54831
+ this.localPort = DEFAULT_DAEMON_PORT;
54713
54832
  }
54714
54833
  applyDebugRuntime(options) {
54715
54834
  this.debugConfig = resolveDebugRuntimeConfig({
@@ -54900,7 +55019,10 @@ var init_adhdev_daemon = __esm({
54900
55019
  }
54901
55020
  }
54902
55021
  buildMachineRuntimeUpdateForSubscription(subscription) {
54903
- const intervalMs = Math.max(5e3, Number(subscription.params.intervalMs || 15e3));
55022
+ const intervalMs = Math.max(
55023
+ MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS,
55024
+ Number(subscription.params.intervalMs || DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS)
55025
+ );
54904
55026
  const now = Date.now();
54905
55027
  if (subscription.lastSentAt > 0 && now - subscription.lastSentAt < intervalMs) {
54906
55028
  return null;
@@ -54921,7 +55043,10 @@ var init_adhdev_daemon = __esm({
54921
55043
  }
54922
55044
  async buildSessionHostDiagnosticsUpdateForSubscription(subscription) {
54923
55045
  if (!this.sessionHostController) return null;
54924
- const intervalMs = Math.max(5e3, Number(subscription.params.intervalMs || 1e4));
55046
+ const intervalMs = Math.max(
55047
+ MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS,
55048
+ Number(subscription.params.intervalMs || DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS)
55049
+ );
54925
55050
  const now = Date.now();
54926
55051
  if (subscription.lastSentAt > 0 && now - subscription.lastSentAt < intervalMs) {
54927
55052
  return null;
@@ -87044,7 +87169,7 @@ async function startDaemonFlow() {
87044
87169
  });
87045
87170
  }
87046
87171
  } catch {
87047
- daemon.start({ localPort: 19222, foreground: false }).catch(() => {
87172
+ daemon.start({ localPort: DEFAULT_DAEMON_PORT, foreground: false }).catch(() => {
87048
87173
  });
87049
87174
  }
87050
87175
  let started = false;