@adhdev/daemon-core 0.9.82-rc.80 → 0.9.82-rc.82

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
@@ -2560,6 +2560,29 @@ function hasPendingRefineTerminalEventDuplicate(event) {
2560
2560
  (pending) => pending.event === event.event && readRefineJobId(pending) === jobId
2561
2561
  );
2562
2562
  }
2563
+ function buildPendingEventFingerprint(event) {
2564
+ const metadata = readRecord(event.metadataEvent) || {};
2565
+ const sessionId = resolveEventSessionId(metadata);
2566
+ const providerSessionId = readNonEmptyString2(metadata.providerSessionId);
2567
+ const taskId = readNonEmptyString2(metadata.taskId) || readNonEmptyString2(readRecord(metadata.payload)?.taskId);
2568
+ const jobId = readRefineJobId(event);
2569
+ const timestamp = metadata.timestamp !== void 0 && metadata.timestamp !== null ? String(metadata.timestamp) : "";
2570
+ return [
2571
+ event.meshId,
2572
+ event.event,
2573
+ event.nodeId || "",
2574
+ sessionId || "",
2575
+ providerSessionId || "",
2576
+ taskId || "",
2577
+ jobId || "",
2578
+ timestamp || ""
2579
+ ].join("::");
2580
+ }
2581
+ function hasPendingCoordinatorEventDuplicate(event) {
2582
+ const fingerprint = buildPendingEventFingerprint(event);
2583
+ if (!fingerprint.trim()) return false;
2584
+ return getPendingMeshCoordinatorEvents(event.meshId).some((pending) => buildPendingEventFingerprint(pending) === fingerprint);
2585
+ }
2563
2586
  function getPendingEventsPath(meshId) {
2564
2587
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
2565
2588
  return (0, import_path6.join)(getLedgerDir(), `${safe}.pending-events.jsonl`);
@@ -2570,6 +2593,10 @@ function queuePendingMeshCoordinatorEvent(event) {
2570
2593
  LOG.info("MeshEvents", `Suppressed duplicate pending ${event.event} for refine job ${readRefineJobId(event)}`);
2571
2594
  return true;
2572
2595
  }
2596
+ if (hasPendingCoordinatorEventDuplicate(event)) {
2597
+ LOG.info("MeshEvents", `Suppressed duplicate pending ${event.event} for mesh ${event.meshId}`);
2598
+ return true;
2599
+ }
2573
2600
  (0, import_fs7.appendFileSync)(getPendingEventsPath(event.meshId), JSON.stringify(event) + "\n", "utf-8");
2574
2601
  return true;
2575
2602
  } catch (e) {
@@ -3346,6 +3373,7 @@ function injectMeshSystemMessage(components, args) {
3346
3373
  if (args.sourceInstanceId && instState.instanceId === args.sourceInstanceId) return false;
3347
3374
  return true;
3348
3375
  });
3376
+ const isRefineTerminalEvent = REFINE_TERMINAL_EVENTS.has(args.event);
3349
3377
  if (coordinatorInstances.length === 0) {
3350
3378
  if (queuePendingMeshCoordinatorEvent({
3351
3379
  event: args.event,
@@ -3364,6 +3392,23 @@ function injectMeshSystemMessage(components, args) {
3364
3392
  }
3365
3393
  return { success: true, forwarded: 0 };
3366
3394
  }
3395
+ if (!isRefineTerminalEvent) {
3396
+ if (queuePendingMeshCoordinatorEvent({
3397
+ event: args.event,
3398
+ meshId: args.meshId,
3399
+ nodeLabel: args.nodeLabel,
3400
+ nodeId: args.nodeId || void 0,
3401
+ workspace: readNonEmptyString2(args.metadataEvent.workspace),
3402
+ metadataEvent: {
3403
+ ...args.metadataEvent,
3404
+ ...recoveryContext ? { recoveryContext } : {}
3405
+ },
3406
+ coordinatorMessage: messageText,
3407
+ queuedAt: Date.now()
3408
+ })) {
3409
+ LOG.info("MeshEvents", `Queued ${args.event} for MCP coordinator (mesh ${args.meshId})`);
3410
+ }
3411
+ }
3367
3412
  for (const coord of coordinatorInstances) {
3368
3413
  const coordState = coord.getState();
3369
3414
  LOG.info("MeshEvents", `Forwarding mesh event to coordinator ${coordState.instanceId}`);
@@ -9391,6 +9436,7 @@ function buildMeshActiveWorkSummary(activeWork) {
9391
9436
  sourceCounts[item.source] += 1;
9392
9437
  statusCounts[item.status] += 1;
9393
9438
  }
9439
+ const staleDirectCount = activeWork.filter((item) => item.source === "direct" && item.staleReason).length;
9394
9440
  return {
9395
9441
  totalActiveCount: activeWork.length,
9396
9442
  queueActiveCount: sourceCounts.queue,
@@ -9401,13 +9447,15 @@ function buildMeshActiveWorkSummary(activeWork) {
9401
9447
  idleCount: statusCounts.idle,
9402
9448
  sourceCounts,
9403
9449
  statusCounts,
9404
- staleDirectCount: activeWork.filter((item) => item.source === "direct" && item.staleReason).length
9450
+ staleDirectCount,
9451
+ ...staleDirectCount > 0 ? { staleDirectNote: "Stale direct records are orphaned ledger entries whose node/session no longer exists. They are historical recovery evidence only \u2014 not active or unresolved work. The queue (source: queue) is authoritative for pending/assigned tasks." } : {}
9405
9452
  };
9406
9453
  }
9407
9454
  function buildMeshActiveWork(opts) {
9408
9455
  const now = opts.now ?? Date.now();
9409
9456
  const records = [];
9410
9457
  const staleDirectWork = [];
9458
+ const terminalDirectWork = [];
9411
9459
  for (const task of opts.queue || []) {
9412
9460
  if (task.status !== "pending" && task.status !== "assigned") continue;
9413
9461
  const { title, summary: summary2 } = summarizeMessage(task.message || "");
@@ -9436,7 +9484,6 @@ function buildMeshActiveWork(opts) {
9436
9484
  const live = sessionStatusFromNodes(opts.nodes, dispatch.nodeId, dispatch.sessionId);
9437
9485
  const status = terminalStatus || live.status || "assigned";
9438
9486
  const terminalRow = Boolean(terminal && terminal.kind !== "task_approval_needed");
9439
- if (terminalRow && opts.includeTerminalDirect !== true) continue;
9440
9487
  const message = readString2(dispatch.payload?.message) || readString2(dispatch.payload?.summary) || "";
9441
9488
  const { title, summary: summary2 } = summarizeMessage(message);
9442
9489
  const record = {
@@ -9459,6 +9506,10 @@ function buildMeshActiveWork(opts) {
9459
9506
  terminalAt: terminal?.timestamp,
9460
9507
  staleReason: live.staleReason
9461
9508
  };
9509
+ if (terminalRow) {
9510
+ terminalDirectWork.push(record);
9511
+ if (opts.includeTerminalDirect !== true) continue;
9512
+ }
9462
9513
  if (live.staleReason && !terminalRow) {
9463
9514
  staleDirectWork.push(record);
9464
9515
  continue;
@@ -9467,9 +9518,14 @@ function buildMeshActiveWork(opts) {
9467
9518
  }
9468
9519
  records.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
9469
9520
  staleDirectWork.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
9521
+ terminalDirectWork.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
9470
9522
  const summary = buildMeshActiveWorkSummary(records);
9471
9523
  summary.staleDirectCount = staleDirectWork.length;
9472
- return { activeWork: records, staleDirectWork, summary };
9524
+ const staleDirectWorkNote = staleDirectWork.length > 0 ? "These are orphaned ledger entries whose original node or session no longer exists in the live mesh. They are historical/recovery evidence only \u2014 not active or unresolved work. Do not treat staleDirectCount as a status mismatch; use the queue (source: queue) as authoritative for pending/assigned tasks." : void 0;
9525
+ if (staleDirectWorkNote) {
9526
+ summary.staleDirectNote = staleDirectWorkNote;
9527
+ }
9528
+ return { activeWork: records, staleDirectWork, staleDirectWorkNote, terminalDirectWork, summary };
9473
9529
  }
9474
9530
 
9475
9531
  // src/index.ts
@@ -13912,7 +13968,7 @@ ${effect.notification.body || ""}`.trim();
13912
13968
  init_logger();
13913
13969
 
13914
13970
  // src/providers/read-chat-contract.ts
13915
- var VALID_STATUSES = ["idle", "generating", "waiting_approval", "error", "panel_hidden", "streaming", "long_generating"];
13971
+ var VALID_STATUSES = ["idle", "generating", "waiting_approval", "error", "panel_hidden", "starting", "streaming", "long_generating"];
13916
13972
  var VALID_ROLES = ["user", "assistant", "system", "human"];
13917
13973
  var VALID_BUBBLE_STATES = ["draft", "streaming", "final", "removed"];
13918
13974
  var VALID_TURN_STATUSES = ["open", "waiting_approval", "complete", "error"];
@@ -15885,7 +15941,8 @@ function buildSessionModalDeliverySignature(payload) {
15885
15941
  var RECENT_SEND_WINDOW_MS = 1200;
15886
15942
  var READ_CHAT_PROVIDER_EVAL_TIMEOUT_MS = 25e3;
15887
15943
  var HERMES_CLI_STARTING_SEND_SETTLE_MS = 2e3;
15888
- var CODEX_NATIVE_HISTORY_FRESH_MS = 5 * 6e4;
15944
+ var CLI_NATIVE_HISTORY_FRESH_MS = 5 * 6e4;
15945
+ var CLI_NATIVE_TRANSCRIPT_PROVIDERS = /* @__PURE__ */ new Set(["codex-cli", "claude-cli"]);
15889
15946
  var recentSendByTarget = /* @__PURE__ */ new Map();
15890
15947
  function getCurrentProviderType(h, fallback = "") {
15891
15948
  return h.currentSession?.providerType || h.currentProviderType || fallback;
@@ -15973,7 +16030,13 @@ function getHistorySessionId(h, args) {
15973
16030
  const instance = h.ctx.instanceManager?.getInstance(targetSessionId);
15974
16031
  const state = instance?.getState?.();
15975
16032
  const providerSessionId = typeof state?.providerSessionId === "string" ? state.providerSessionId.trim() : "";
15976
- return providerSessionId || targetSessionId;
16033
+ if (providerSessionId) return providerSessionId;
16034
+ const currentSession = h.currentSession;
16035
+ if (currentSession?.sessionId === targetSessionId) {
16036
+ const currentProviderSessionId = typeof currentSession.providerSessionId === "string" ? currentSession.providerSessionId.trim() : "";
16037
+ if (currentProviderSessionId) return currentProviderSessionId;
16038
+ }
16039
+ return targetSessionId;
15977
16040
  }
15978
16041
  function getInteractionId(args) {
15979
16042
  return typeof args?._interactionId === "string" && args._interactionId.trim() ? args._interactionId.trim() : void 0;
@@ -16036,7 +16099,9 @@ function buildCliMessageSourceProvenance(args) {
16036
16099
  return {
16037
16100
  selected: args.selected,
16038
16101
  provider: args.provider,
16102
+ providerType: args.provider,
16039
16103
  ...args.nativeHandle ? { nativeHandle: args.nativeHandle } : {},
16104
+ ...args.nativeHandle ? { nativeSessionId: args.nativeHandle } : {},
16040
16105
  ...args.fallbackReason ? { fallbackReason: args.fallbackReason } : {},
16041
16106
  ...args.nativeSource ? { nativeSource: args.nativeSource } : {},
16042
16107
  ...args.sourcePath ? { sourcePath: args.sourcePath } : {},
@@ -16057,7 +16122,7 @@ function buildCliMessageSourceProvenance(args) {
16057
16122
  };
16058
16123
  }
16059
16124
  function buildNativeHistoryFallbackReason(args) {
16060
- if (args.providerType !== "codex-cli") return "provider_not_codex_cli";
16125
+ if (!supportsCliNativeTranscript(args.providerType)) return "provider_native_transcript_not_supported";
16061
16126
  if (args.nativeSource === "native-unavailable") return "native_history_unavailable";
16062
16127
  if (args.nativeSource && args.nativeSource !== "provider-native") return `native_history_source_${args.nativeSource}`;
16063
16128
  if (args.nativeMessageCount <= 0) return "native_history_empty";
@@ -16065,8 +16130,8 @@ function buildNativeHistoryFallbackReason(args) {
16065
16130
  if (!args.freshEnough) return "native_history_stale";
16066
16131
  return "native_history_not_selected";
16067
16132
  }
16068
- function isCodexCliProvider(providerType) {
16069
- return providerType === "codex-cli";
16133
+ function supportsCliNativeTranscript(providerType) {
16134
+ return CLI_NATIVE_TRANSCRIPT_PROVIDERS.has(providerType);
16070
16135
  }
16071
16136
  function hasSafeNativeHistoryMapping(args) {
16072
16137
  const explicitSessionId = String(args.historySessionId || args.providerSessionId || "").trim();
@@ -16084,7 +16149,7 @@ function isNativeHistoryFreshEnough(args) {
16084
16149
  const ptyNewest = getMessageNewestReceivedAt(args.ptyMessages);
16085
16150
  if (nativeNewest > 0 && nativeNewest >= ptyNewest) return true;
16086
16151
  const sourceMtimeMs = Number(args.sourceMtimeMs || 0);
16087
- if (sourceMtimeMs > 0 && Date.now() - sourceMtimeMs <= CODEX_NATIVE_HISTORY_FRESH_MS) return true;
16152
+ if (sourceMtimeMs > 0 && Date.now() - sourceMtimeMs <= CLI_NATIVE_HISTORY_FRESH_MS) return true;
16088
16153
  return ptyNewest === 0 && nativeNewest > 0;
16089
16154
  }
16090
16155
  function shouldPreserveReadChatPayloadField(key) {
@@ -16133,7 +16198,7 @@ function normalizeReadChatCommandStatus(status, activeModal) {
16133
16198
  }
16134
16199
  switch (raw) {
16135
16200
  case "starting":
16136
- return hasNonEmptyModalButtons(activeModal) ? "waiting_approval" : "generating";
16201
+ return hasNonEmptyModalButtons(activeModal) ? "waiting_approval" : "starting";
16137
16202
  case "stopped":
16138
16203
  case "disconnected":
16139
16204
  case "not_monitored":
@@ -16153,7 +16218,11 @@ function shouldTrustCliAdapterTerminalStatus(parsedStatus, activeModal, adapter,
16153
16218
  if (typeof adapter.isProcessing === "function" && adapter.isProcessing()) return false;
16154
16219
  return true;
16155
16220
  }
16156
- function normalizeCliReadChatStatus(parsedStatus, activeModal, adapter, adapterStatus) {
16221
+ function normalizeCliReadChatStatus(parsedStatus, activeModal, adapter, adapterStatus, parsedMessages) {
16222
+ const adapterRawStatus = typeof adapterStatus?.status === "string" ? adapterStatus.status.trim() : "";
16223
+ if (adapterRawStatus === "starting" && isGeneratingLikeStatus(parsedStatus) && !hasNonEmptyModalButtons(activeModal) && Array.isArray(parsedMessages) && parsedMessages.length === 0 && Array.isArray(adapterStatus?.messages) && adapterStatus.messages.length === 0 && !(typeof adapter.isProcessing === "function" && adapter.isProcessing())) {
16224
+ return "starting";
16225
+ }
16157
16226
  if (shouldTrustCliAdapterTerminalStatus(parsedStatus, activeModal, adapter, adapterStatus)) return "idle";
16158
16227
  return typeof parsedStatus === "string" && parsedStatus.trim() ? parsedStatus : "idle";
16159
16228
  }
@@ -16644,7 +16713,7 @@ async function handleReadChat(h, args) {
16644
16713
  const transcriptAuthority = parsedRecord.transcriptAuthority === "provider" || parsedRecord.transcriptAuthority === "daemon" ? parsedRecord.transcriptAuthority : void 0;
16645
16714
  const coverage = parsedRecord.coverage === "full" || parsedRecord.coverage === "tail" || parsedRecord.coverage === "current-turn" ? parsedRecord.coverage : void 0;
16646
16715
  const activeModal = parsedRecord.activeModal ?? parsedRecord.modal ?? null;
16647
- const returnedStatus = normalizeCliReadChatStatus(parsedRecord.status, activeModal, adapter, adapterStatus);
16716
+ const returnedStatus = normalizeCliReadChatStatus(parsedRecord.status, activeModal, adapter, adapterStatus, parsedRecord.messages);
16648
16717
  const runtimeMessageMerger = getTargetInstance(h, args);
16649
16718
  const parsedMessages = finalizeStreamingMessagesWhenIdle(parsedRecord.messages, returnedStatus);
16650
16719
  const returnedMessages = runtimeMessageMerger?.category === "cli" && runtimeMessageMerger.type === adapter.cliType && typeof runtimeMessageMerger.mergeRuntimeChatMessages === "function" ? runtimeMessageMerger.mergeRuntimeChatMessages(parsedMessages) : parsedMessages;
@@ -16657,12 +16726,12 @@ async function handleReadChat(h, args) {
16657
16726
  let messageSource = buildCliMessageSourceProvenance({
16658
16727
  selected: "pty-parser",
16659
16728
  provider: adapter.cliType,
16660
- fallbackReason: isCodexCliProvider(providerType) ? "native_history_not_checked" : "provider_not_codex_cli",
16729
+ fallbackReason: supportsCliNativeTranscript(providerType) ? "native_history_not_checked" : "provider_native_transcript_not_supported",
16661
16730
  ptyMessages: returnedMessages,
16662
16731
  returnedMessages,
16663
16732
  ptyStatusApprovalOnly: false
16664
16733
  });
16665
- if (isCodexCliProvider(providerType)) {
16734
+ if (supportsCliNativeTranscript(providerType)) {
16666
16735
  const agentStr = provider?.type || args?.agentType || getCurrentProviderType(h, adapter.cliType);
16667
16736
  const workspace = typeof args?.workspace === "string" ? args.workspace : typeof h.currentSession?.workspace === "string" ? h.currentSession.workspace : typeof adapter.workingDir === "string" ? adapter.workingDir : void 0;
16668
16737
  const nativeHistoryLimit = Math.max(
@@ -16768,7 +16837,7 @@ async function handleReadChat(h, args) {
16768
16837
  returnedStatus: String(returnedStatus || ""),
16769
16838
  selectedMessageSource: messageSource.selected,
16770
16839
  messageSource,
16771
- shouldPreferAdapterMessages: messageSource.selected !== "native-history",
16840
+ shouldPreferAdapterMessages: supportsCliNativeTranscript(providerType) && messageSource.selected !== "native-history",
16772
16841
  parsedMsgCount: parsedRecord.messages.length,
16773
16842
  returnedMsgCount: selectedMessages.length
16774
16843
  },
@@ -16793,9 +16862,39 @@ async function handleReadChat(h, args) {
16793
16862
  scripts: provider?.scripts
16794
16863
  });
16795
16864
  const historyProviderSessionId = typeof history?.providerSessionId === "string" ? history.providerSessionId : historySessionId;
16865
+ const historyMessages = Array.isArray(history?.messages) ? normalizeChatMessages(history.messages) : [];
16866
+ const safeMapping = supportsCliNativeTranscript(agentStr) ? hasSafeNativeHistoryMapping({
16867
+ historySessionId,
16868
+ providerSessionId: historyProviderSessionId,
16869
+ workspace,
16870
+ nativeMessages: historyMessages
16871
+ }) : false;
16872
+ const nativeSelected = supportsCliNativeTranscript(agentStr) && history.source === "provider-native" && historyMessages.length > 0 && safeMapping;
16873
+ const messageSource = buildCliMessageSourceProvenance({
16874
+ selected: nativeSelected ? "native-history" : "pty-parser",
16875
+ provider: agentStr,
16876
+ nativeHandle: historyProviderSessionId || historySessionId,
16877
+ fallbackReason: nativeSelected ? void 0 : buildNativeHistoryFallbackReason({
16878
+ providerType: agentStr,
16879
+ nativeSource: history.source,
16880
+ nativeMessageCount: historyMessages.length,
16881
+ safeMapping,
16882
+ freshEnough: true
16883
+ }),
16884
+ nativeSource: history.source,
16885
+ sourcePath: history.sourcePath,
16886
+ sourceMtimeMs: history.sourceMtimeMs,
16887
+ nativeMessages: historyMessages,
16888
+ returnedMessages: historyMessages,
16889
+ safeMapping,
16890
+ freshEnough: true,
16891
+ ptyStatusApprovalOnly: false
16892
+ });
16796
16893
  return buildReadChatCommandResult({
16797
- messages: Array.isArray(history?.messages) ? history.messages : [],
16894
+ messages: historyMessages,
16798
16895
  status: "idle",
16896
+ messageSource,
16897
+ transcriptProvenance: messageSource,
16799
16898
  ...typeof history?.title === "string" ? { title: history.title } : {},
16800
16899
  ...historyProviderSessionId ? { providerSessionId: historyProviderSessionId } : {},
16801
16900
  ...provider?.historyBehavior?.transcriptAuthority === "provider" || provider?.historyBehavior?.transcriptAuthority === "daemon" ? { transcriptAuthority: (provider?.historyBehavior).transcriptAuthority } : {},
@@ -21664,6 +21763,7 @@ function commandExists(command) {
21664
21763
  }
21665
21764
  }
21666
21765
  var BUSY_AGENT_STATUSES = /* @__PURE__ */ new Set(["generating", "running", "streaming", "starting", "busy", "waiting", "waiting_approval", "long_generating"]);
21766
+ var ZERO_MESSAGE_STARTING_SEND_WAIT_MS = 2e3;
21667
21767
  function normalizeAgentStatus(value) {
21668
21768
  return typeof value === "string" ? value.trim().toLowerCase() : "";
21669
21769
  }
@@ -21685,6 +21785,20 @@ function hasAdapterPendingResponse(adapter) {
21685
21785
  }
21686
21786
  return false;
21687
21787
  }
21788
+ function countMessages(value) {
21789
+ return Array.isArray(value) ? value.length : 0;
21790
+ }
21791
+ function hasZeroMessageStartingLaunch(adapter) {
21792
+ const adapterStatus = adapter?.getStatus?.({ allowParse: false }) ?? adapter?.getStatus?.() ?? {};
21793
+ const parsedStatus = typeof adapter?.getScriptParsedStatus === "function" ? adapter.getScriptParsedStatus() : {};
21794
+ const adapterRawStatus = normalizeAgentStatus(adapterStatus?.status);
21795
+ const parsedRawStatus = normalizeAgentStatus(parsedStatus?.status);
21796
+ if (adapterRawStatus !== "starting") return false;
21797
+ if (parsedRawStatus && parsedRawStatus !== "starting" && parsedRawStatus !== "generating") return false;
21798
+ if (hasNonEmptyModalButtons2(adapterStatus?.activeModal ?? adapterStatus?.modal ?? parsedStatus?.activeModal ?? parsedStatus?.modal)) return false;
21799
+ if (countMessages(adapterStatus?.messages) > 0 || countMessages(parsedStatus?.messages) > 0) return false;
21800
+ return !hasAdapterPendingResponse(adapter);
21801
+ }
21688
21802
  function shouldSuppressStaleParsedBusyStatus(adapterStatus, parsedStatus, adapter) {
21689
21803
  const parsedRawStatus = normalizeAgentStatus(parsedStatus?.status);
21690
21804
  if (!BUSY_AGENT_STATUSES.has(parsedRawStatus)) return false;
@@ -21708,6 +21822,19 @@ function getEffectiveAgentSendStatus(adapter) {
21708
21822
  }
21709
21823
  return adapterStatus;
21710
21824
  }
21825
+ async function waitForZeroMessageStartingLaunch(adapter) {
21826
+ try {
21827
+ if (!hasZeroMessageStartingLaunch(adapter)) return false;
21828
+ } catch {
21829
+ return false;
21830
+ }
21831
+ await new Promise((resolve16) => setTimeout(resolve16, ZERO_MESSAGE_STARTING_SEND_WAIT_MS));
21832
+ try {
21833
+ return hasZeroMessageStartingLaunch(adapter);
21834
+ } catch {
21835
+ return false;
21836
+ }
21837
+ }
21711
21838
  var chalkModule = import_chalk.default;
21712
21839
  var chalkApi = typeof chalkModule.yellow === "function" ? chalkModule : chalkModule.default || null;
21713
21840
  function colorize(color, text) {
@@ -22482,7 +22609,12 @@ Run 'adhdev doctor' for detailed diagnostics.`
22482
22609
  if (!found) throw new Error(`CLI agent not running: ${agentType}`);
22483
22610
  const { adapter, key } = found;
22484
22611
  if (action === "send_chat") {
22485
- const currentStatus = getEffectiveAgentSendStatus(adapter);
22612
+ let currentStatus = getEffectiveAgentSendStatus(adapter);
22613
+ if (currentStatus === "starting" && await waitForZeroMessageStartingLaunch(adapter)) {
22614
+ currentStatus = "idle";
22615
+ } else if (currentStatus === "starting") {
22616
+ currentStatus = getEffectiveAgentSendStatus(adapter);
22617
+ }
22486
22618
  if (BUSY_AGENT_STATUSES.has(currentStatus)) {
22487
22619
  return {
22488
22620
  success: false,