adhdev 0.8.84 → 0.8.86

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/cli/index.js CHANGED
@@ -7682,6 +7682,7 @@ function normalizeReadChatCommandStatus(status, activeModal) {
7682
7682
  }
7683
7683
  function buildReadChatCommandResult(payload, args) {
7684
7684
  let validatedPayload;
7685
+ const debugReadChat = payload?.debugReadChat && typeof payload.debugReadChat === "object" ? payload.debugReadChat : void 0;
7685
7686
  try {
7686
7687
  validatedPayload = validateReadChatResultPayload({
7687
7688
  ...payload,
@@ -7702,7 +7703,8 @@ function buildReadChatCommandResult(payload, args) {
7702
7703
  syncMode: "full",
7703
7704
  replaceFrom: 0,
7704
7705
  totalMessages: messages.length,
7705
- lastMessageSignature
7706
+ lastMessageSignature,
7707
+ ...debugReadChat ? { debugReadChat } : {}
7706
7708
  };
7707
7709
  }
7708
7710
  const sync = computeReadChatSync(messages, cursor);
@@ -7713,7 +7715,8 @@ function buildReadChatCommandResult(payload, args) {
7713
7715
  syncMode: sync.syncMode,
7714
7716
  replaceFrom: sync.replaceFrom,
7715
7717
  totalMessages: sync.totalMessages,
7716
- lastMessageSignature: sync.lastMessageSignature
7718
+ lastMessageSignature: sync.lastMessageSignature,
7719
+ ...debugReadChat ? { debugReadChat } : {}
7717
7720
  };
7718
7721
  }
7719
7722
  function didProviderConfirmSend(result) {
@@ -7804,14 +7807,33 @@ async function handleReadChat(h, args) {
7804
7807
  }
7805
7808
  }
7806
7809
  const parsedRecord = parsedStatus && typeof parsedStatus === "object" ? parsedStatus : null;
7807
- const status = parsedRecord || adapter.getStatus();
7810
+ const adapterStatus = adapter.getStatus();
7811
+ const shouldPreferAdapterMessages = Array.isArray(adapterStatus.messages) && adapterStatus.messages.length > 0 && Array.isArray(parsedRecord?.messages) && adapterStatus.messages.length > parsedRecord.messages.length;
7812
+ const status = parsedRecord ? {
7813
+ ...parsedRecord,
7814
+ messages: shouldPreferAdapterMessages ? adapterStatus.messages : parsedRecord.messages,
7815
+ status: adapterStatus.status !== "idle" ? adapterStatus.status : parsedRecord.status || adapterStatus.status,
7816
+ activeModal: parsedRecord.activeModal || adapterStatus.activeModal
7817
+ } : adapterStatus;
7808
7818
  const title = typeof parsedRecord?.title === "string" ? parsedRecord.title : void 0;
7809
7819
  const providerSessionId = typeof parsedRecord?.providerSessionId === "string" ? parsedRecord.providerSessionId : void 0;
7810
7820
  if (status) {
7821
+ LOG.info("Command", `[read_chat] cli-like resolved provider=${adapter.cliType} target=${String(args?.targetSessionId || "")} adapterStatus=${String(adapterStatus.status || "")} parsedStatus=${String(parsedRecord?.status || "")} shouldPreferAdapterMessages=${String(shouldPreferAdapterMessages)} adapterMsgCount=${Array.isArray(adapterStatus.messages) ? adapterStatus.messages.length : 0} parsedMsgCount=${Array.isArray(parsedRecord?.messages) ? parsedRecord.messages.length : 0} returnedMsgCount=${Array.isArray(status.messages) ? status.messages.length : 0}`);
7811
7822
  return buildReadChatCommandResult({
7812
7823
  messages: status.messages || [],
7813
7824
  status: status.status,
7814
7825
  activeModal: status.activeModal,
7826
+ debugReadChat: {
7827
+ provider: adapter.cliType,
7828
+ targetSessionId: String(args?.targetSessionId || ""),
7829
+ adapterStatus: String(adapterStatus.status || ""),
7830
+ parsedStatus: String(parsedRecord?.status || ""),
7831
+ returnedStatus: String(status.status || ""),
7832
+ shouldPreferAdapterMessages,
7833
+ adapterMsgCount: Array.isArray(adapterStatus.messages) ? adapterStatus.messages.length : 0,
7834
+ parsedMsgCount: Array.isArray(parsedRecord?.messages) ? parsedRecord.messages.length : 0,
7835
+ returnedMsgCount: Array.isArray(status.messages) ? status.messages.length : 0
7836
+ },
7815
7837
  ...title ? { title } : {},
7816
7838
  ...providerSessionId ? { providerSessionId } : {}
7817
7839
  }, args);
@@ -12734,6 +12756,58 @@ var init_provider_cli_adapter = __esm({
12734
12756
  `[${this.cliType}] Interactive prompt wait timed out after ${maxWaitMs}ms; proceeding with screen=${JSON.stringify(summarizeCliTraceText(finalScreenText, 240)).slice(0, 280)}`
12735
12757
  );
12736
12758
  }
12759
+ clearStaleIdleResponseGuard(reason) {
12760
+ const screenText = this.terminalScreen.getText() || "";
12761
+ const visibleIdlePrompt = this.looksLikeVisibleIdlePrompt(screenText);
12762
+ const blockingModal = this.activeModal || this.getStartupConfirmationModal(screenText);
12763
+ if (!this.isWaitingForResponse || this.currentStatus !== "idle" || !visibleIdlePrompt || !!blockingModal) {
12764
+ return false;
12765
+ }
12766
+ if (this.responseTimeout) {
12767
+ clearTimeout(this.responseTimeout);
12768
+ this.responseTimeout = null;
12769
+ }
12770
+ if (this.idleTimeout) {
12771
+ clearTimeout(this.idleTimeout);
12772
+ this.idleTimeout = null;
12773
+ }
12774
+ if (this.approvalExitTimeout) {
12775
+ clearTimeout(this.approvalExitTimeout);
12776
+ this.approvalExitTimeout = null;
12777
+ }
12778
+ if (this.finishRetryTimer) {
12779
+ clearTimeout(this.finishRetryTimer);
12780
+ this.finishRetryTimer = null;
12781
+ }
12782
+ this.clearIdleFinishCandidate(reason);
12783
+ this.responseBuffer = "";
12784
+ this.isWaitingForResponse = false;
12785
+ this.responseSettleIgnoreUntil = 0;
12786
+ this.submitRetryUsed = false;
12787
+ this.submitRetryPromptSnippet = "";
12788
+ this.finishRetryCount = 0;
12789
+ this.currentTurnScope = null;
12790
+ this.activeModal = null;
12791
+ this.recordTrace("stale_idle_response_cleared", {
12792
+ reason,
12793
+ screenText: summarizeCliTraceText(screenText, 240)
12794
+ });
12795
+ return true;
12796
+ }
12797
+ hasMeaningfulResponseBuffer(promptSnippet) {
12798
+ const raw = String(this.responseBuffer || "").trim();
12799
+ if (!raw) return false;
12800
+ const normalizedPrompt = compactPromptText(promptSnippet);
12801
+ if (!normalizedPrompt) return true;
12802
+ const normalizedBuffer = compactPromptText(raw);
12803
+ if (!normalizedBuffer) return false;
12804
+ if (normalizedBuffer === normalizedPrompt) return false;
12805
+ if (normalizedBuffer.startsWith(normalizedPrompt)) {
12806
+ const remainder = normalizedBuffer.slice(normalizedPrompt.length).replace(/[─═\-]+/g, "").replace(/⏵⏵accepteditson\([^)]*\)/gi, "").replace(/accepteditson\([^)]*\)/gi, "").replace(/(?:◐|◑|◒|◓|◔|◕|◉|●|·)?(?:x?high|medium|low|max)·?\/effort/gi, "").replace(/updateavailable!run:[a-z0-9:._\-/]+/gi, "").replace(/esctointerrupt/gi, "").replace(/❯/g, "").replace(/^[\s\-–—:;,.!/?]+/, "").trim();
12807
+ return remainder.length > 0;
12808
+ }
12809
+ return true;
12810
+ }
12737
12811
  evaluateSettled() {
12738
12812
  const now = Date.now();
12739
12813
  if (this.submitPendingUntil > now || this.responseSettleIgnoreUntil > now) {
@@ -12766,7 +12840,11 @@ var init_provider_cli_adapter = __esm({
12766
12840
  scope: this.currentTurnScope,
12767
12841
  lastOutputAt: this.lastOutputAt
12768
12842
  }) : [];
12843
+ if (this.maybeCommitVisibleIdleTranscript(parsedTranscript)) {
12844
+ return;
12845
+ }
12769
12846
  const lastParsedAssistant = [...parsedMessages].reverse().find((message) => message.role === "assistant");
12847
+ const normalizedPromptSnippet = normalizePromptText(this.submitRetryPromptSnippet || this.currentTurnScope?.prompt || "");
12770
12848
  this.recordTrace("settled", {
12771
12849
  tail: summarizeCliTraceText(tail, 500),
12772
12850
  screenText: summarizeCliTraceText(screenText, 1200),
@@ -12784,6 +12862,24 @@ var init_provider_cli_adapter = __esm({
12784
12862
  scope: this.currentTurnScope
12785
12863
  })
12786
12864
  });
12865
+ if (this.currentTurnScope && !lastParsedAssistant && !this.submitRetryUsed && this.ptyProcess && this.currentStatus !== "waiting_approval" && promptLikelyVisible(screenText, normalizedPromptSnippet) && !this.hasMeaningfulResponseBuffer(normalizedPromptSnippet)) {
12866
+ this.submitRetryUsed = true;
12867
+ this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
12868
+ LOG.info("CLI", `[${this.cliType}] Retrying submit key from settled parser (no assistant yet)`);
12869
+ this.recordTrace("submit_write", {
12870
+ mode: "settled_retry",
12871
+ sendKey: this.sendKey,
12872
+ screenText: summarizeCliTraceText(screenText, 500)
12873
+ });
12874
+ this.ptyProcess.write(this.sendKey);
12875
+ if (this.settleTimer) clearTimeout(this.settleTimer);
12876
+ this.settleTimer = setTimeout(() => {
12877
+ this.settleTimer = null;
12878
+ this.settledBuffer = this.recentOutputBuffer;
12879
+ this.evaluateSettled();
12880
+ }, this.timeouts.outputSettle + 150);
12881
+ return;
12882
+ }
12787
12883
  if (this.currentTurnScope && !lastParsedAssistant) {
12788
12884
  LOG.info(
12789
12885
  "CLI",
@@ -12826,7 +12922,15 @@ var init_provider_cli_adapter = __esm({
12826
12922
  }
12827
12923
  const recentInteractiveActivity = this.hasRecentInteractiveActivity(now);
12828
12924
  const statusActivityHoldMs = this.getStatusActivityHoldMs();
12829
- const shouldHoldGenerating = scriptStatus === "idle" && this.isWaitingForResponse && !modal && recentInteractiveActivity;
12925
+ const visibleIdlePrompt = this.looksLikeVisibleIdlePrompt(screenText);
12926
+ const visibleAssistantCandidate = this.looksLikeVisibleAssistantCandidate(screenText);
12927
+ if (this.currentTurnScope && this.cliType === "claude-cli") {
12928
+ LOG.info(
12929
+ "CLI",
12930
+ `[${this.cliType}] settled diagnostics prompt=${JSON.stringify(this.currentTurnScope.prompt).slice(0, 140)} scriptStatus=${String(scriptStatus || "")} parsedStatus=${String(parsedTranscript?.status || "")} parsedMsgCount=${parsedMessages.length} lastParsedAssistant=${JSON.stringify(summarizeCliTraceText(lastParsedAssistant?.content || "", 120)).slice(0, 160)} visibleIdlePrompt=${String(visibleIdlePrompt)} visibleAssistantCandidate=${String(visibleAssistantCandidate)} responseBuffer=${JSON.stringify(summarizeCliTraceText(this.responseBuffer, 160)).slice(0, 220)} screen=${JSON.stringify(summarizeCliTraceText(screenText, 160)).slice(0, 220)}`
12931
+ );
12932
+ }
12933
+ const shouldHoldGenerating = scriptStatus === "idle" && this.isWaitingForResponse && !modal && recentInteractiveActivity && !(visibleIdlePrompt && visibleAssistantCandidate);
12830
12934
  if (shouldHoldGenerating) {
12831
12935
  this.clearIdleFinishCandidate("hold_generating_recent_activity");
12832
12936
  this.setStatus("generating", "recent_activity_hold");
@@ -12857,8 +12961,8 @@ var init_provider_cli_adapter = __esm({
12857
12961
  if (scriptStatus === "waiting_approval") {
12858
12962
  this.clearIdleFinishCandidate("waiting_approval");
12859
12963
  const inCooldown = this.lastApprovalResolvedAt && Date.now() - this.lastApprovalResolvedAt < this.timeouts.approvalCooldown;
12860
- const visibleIdlePrompt = this.looksLikeVisibleIdlePrompt(screenText);
12861
- if ((inCooldown || visibleIdlePrompt) && !modal) {
12964
+ const visibleIdlePrompt2 = this.looksLikeVisibleIdlePrompt(screenText);
12965
+ if ((inCooldown || visibleIdlePrompt2) && !modal) {
12862
12966
  if (this.approvalExitTimeout) {
12863
12967
  clearTimeout(this.approvalExitTimeout);
12864
12968
  this.approvalExitTimeout = null;
@@ -12930,7 +13034,7 @@ var init_provider_cli_adapter = __esm({
12930
13034
  this.lastApprovalResolvedAt = Date.now();
12931
13035
  }
12932
13036
  if (this.isWaitingForResponse) {
12933
- const visibleIdlePrompt = this.looksLikeVisibleIdlePrompt(screenText);
13037
+ const visibleIdlePrompt2 = this.looksLikeVisibleIdlePrompt(screenText);
12934
13038
  const quietForMs = this.lastNonEmptyOutputAt ? now - this.lastNonEmptyOutputAt : Number.MAX_SAFE_INTEGER;
12935
13039
  const screenStableMs = this.lastScreenChangeAt ? now - this.lastScreenChangeAt : 0;
12936
13040
  const hasAssistantTurn = !!lastParsedAssistant;
@@ -12938,12 +13042,12 @@ var init_provider_cli_adapter = __esm({
12938
13042
  const idleFinishConfirmMs = this.getIdleFinishConfirmMs();
12939
13043
  const idleQuietThresholdMs = Math.max(idleFinishConfirmMs, this.timeouts.outputSettle);
12940
13044
  const idleStableThresholdMs = idleFinishConfirmMs;
12941
- const idleReady = visibleIdlePrompt && !modal && hasAssistantTurn && quietForMs >= idleQuietThresholdMs && screenStableMs >= idleStableThresholdMs;
13045
+ const idleReady = visibleIdlePrompt2 && !modal && hasAssistantTurn && quietForMs >= idleQuietThresholdMs && screenStableMs >= idleStableThresholdMs;
12942
13046
  const candidate = this.idleFinishCandidate;
12943
13047
  const candidateQuiet = !!candidate && candidate.responseEpoch === this.responseEpoch && candidate.lastOutputAt === this.lastOutputAt && candidate.lastScreenChangeAt === this.lastScreenChangeAt && assistantLength >= candidate.assistantLength && now - candidate.armedAt >= idleFinishConfirmMs;
12944
13048
  const canFinishImmediately = idleReady && candidateQuiet;
12945
13049
  this.recordTrace("idle_decision", {
12946
- visibleIdlePrompt,
13050
+ visibleIdlePrompt: visibleIdlePrompt2,
12947
13051
  quietForMs,
12948
13052
  screenStableMs,
12949
13053
  hasAssistantTurn,
@@ -13063,6 +13167,70 @@ var init_provider_cli_adapter = __esm({
13063
13167
  this.setStatus("idle", "response_finished");
13064
13168
  this.onStatusChange?.();
13065
13169
  }
13170
+ maybeCommitVisibleIdleTranscript(parsed, options) {
13171
+ const allowImmediateScriptIdleCommit = this.provider.allowInputDuringGeneration === true;
13172
+ if (!allowImmediateScriptIdleCommit) return false;
13173
+ if (!parsed || !Array.isArray(parsed.messages) || parsed.status !== "idle" || !this.isWaitingForResponse || !this.currentTurnScope || this.activeModal || parsed.activeModal) {
13174
+ return false;
13175
+ }
13176
+ if (options?.requireVisibleAssistantCandidate) {
13177
+ const candidateText = options.screenText || this.terminalScreen.getText() || "";
13178
+ if (!this.looksLikeVisibleAssistantCandidate(candidateText)) {
13179
+ return false;
13180
+ }
13181
+ }
13182
+ const hydratedForIdleCommit = normalizeCliParsedMessages(parsed.messages, {
13183
+ committedMessages: this.committedMessages,
13184
+ scope: this.currentTurnScope,
13185
+ lastOutputAt: this.lastOutputAt
13186
+ });
13187
+ const visibleAssistant = [...hydratedForIdleCommit].reverse().find((message) => message.role === "assistant" && message.content.trim());
13188
+ if (!visibleAssistant) return false;
13189
+ this.committedMessages = hydratedForIdleCommit;
13190
+ const promptForTrim = this.currentTurnScope?.prompt || getLastUserPromptText(this.committedMessages);
13191
+ if (promptForTrim) {
13192
+ const lastAssistantForTrim = [...this.committedMessages].reverse().find((message) => message.role === "assistant");
13193
+ if (lastAssistantForTrim) {
13194
+ lastAssistantForTrim.content = trimPromptEchoPrefix(lastAssistantForTrim.content, promptForTrim);
13195
+ }
13196
+ }
13197
+ if (this.responseTimeout) {
13198
+ clearTimeout(this.responseTimeout);
13199
+ this.responseTimeout = null;
13200
+ }
13201
+ if (this.idleTimeout) {
13202
+ clearTimeout(this.idleTimeout);
13203
+ this.idleTimeout = null;
13204
+ }
13205
+ if (this.approvalExitTimeout) {
13206
+ clearTimeout(this.approvalExitTimeout);
13207
+ this.approvalExitTimeout = null;
13208
+ }
13209
+ if (this.submitRetryTimer) {
13210
+ clearTimeout(this.submitRetryTimer);
13211
+ this.submitRetryTimer = null;
13212
+ }
13213
+ if (this.finishRetryTimer) {
13214
+ clearTimeout(this.finishRetryTimer);
13215
+ this.finishRetryTimer = null;
13216
+ }
13217
+ this.syncMessageViews();
13218
+ this.responseBuffer = "";
13219
+ this.isWaitingForResponse = false;
13220
+ this.responseSettleIgnoreUntil = 0;
13221
+ this.submitRetryUsed = false;
13222
+ this.submitRetryPromptSnippet = "";
13223
+ this.finishRetryCount = 0;
13224
+ this.currentTurnScope = null;
13225
+ this.activeModal = null;
13226
+ this.setStatus("idle", "script_idle_commit");
13227
+ this.onStatusChange?.();
13228
+ this.recordTrace("script_idle_commit", {
13229
+ messageCount: this.committedMessages.length,
13230
+ lastAssistant: summarizeCliTraceText(visibleAssistant.content, 320)
13231
+ });
13232
+ return true;
13233
+ }
13066
13234
  commitCurrentTranscript() {
13067
13235
  const parsed = this.parseCurrentTranscript(
13068
13236
  this.committedMessages,
@@ -13084,6 +13252,12 @@ var init_provider_cli_adapter = __esm({
13084
13252
  }
13085
13253
  this.syncMessageViews();
13086
13254
  const lastAssistant = [...this.committedMessages].reverse().find((message) => message.role === "assistant");
13255
+ if (this.currentTurnScope) {
13256
+ LOG.info(
13257
+ "CLI",
13258
+ `[${this.cliType}] commitCurrentTranscript committedMessages=${this.committedMessages.length} finalLastAssistant=${JSON.stringify(summarizeCliTraceText(lastAssistant?.content || "", 220)).slice(0, 260)}`
13259
+ );
13260
+ }
13087
13261
  this.recordTrace("commit_transcript", {
13088
13262
  parsedStatus: parsed.status || null,
13089
13263
  messageCount: this.committedMessages.length,
@@ -13103,11 +13277,18 @@ var init_provider_cli_adapter = __esm({
13103
13277
  `[${this.cliType}] Commit without assistant turn: prompt=${JSON.stringify(this.currentTurnScope.prompt).slice(0, 140)} responseBuffer=${JSON.stringify(summarizeCliTraceText(this.responseBuffer, 220)).slice(0, 260)} providerDir=${this.providerResolutionMeta.providerDir || "-"} scriptDir=${this.providerResolutionMeta.scriptDir || "-"} scriptsPath=${this.providerResolutionMeta.scriptsPath || "-"}`
13104
13278
  );
13105
13279
  }
13280
+ const hasAssistant = !!lastAssistant;
13106
13281
  return {
13107
- hasAssistant: !!lastAssistant,
13282
+ hasAssistant,
13108
13283
  assistantContent: lastAssistant?.content || ""
13109
13284
  };
13110
13285
  }
13286
+ if (this.currentTurnScope) {
13287
+ LOG.info(
13288
+ "CLI",
13289
+ `[${this.cliType}] commitCurrentTranscript parsed.messages=none responseBufferLen=${this.responseBuffer.length} accumulatedBufferLen=${this.accumulatedBuffer.length} parsedStatus=${parsed?.status || "-"} providerDir=${this.providerResolutionMeta.providerDir || "-"} scriptDir=${this.providerResolutionMeta.scriptDir || "-"}`
13290
+ );
13291
+ }
13111
13292
  return {
13112
13293
  hasAssistant: false,
13113
13294
  assistantContent: ""
@@ -13193,19 +13374,25 @@ var init_provider_cli_adapter = __esm({
13193
13374
  this.currentTurnScope,
13194
13375
  screenText
13195
13376
  );
13196
- const shouldPreferCommittedMessages = !this.currentTurnScope && this.currentStatus === "idle" && !this.activeModal;
13377
+ if (this.maybeCommitVisibleIdleTranscript(parsed)) {
13378
+ return this.getScriptParsedStatus();
13379
+ }
13380
+ const shouldPreferCommittedMessages = !this.currentTurnScope && !this.activeModal && this.currentStatus === "idle";
13197
13381
  let result;
13198
13382
  if (parsed && Array.isArray(parsed.messages)) {
13199
- const hydratedMessages = shouldPreferCommittedMessages ? this.committedMessages.map((message, index) => buildChatMessage({
13200
- ...message,
13201
- id: message.id || `msg_${index}`,
13202
- index: typeof message.index === "number" ? message.index : index,
13203
- receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
13204
- })) : hydrateCliParsedMessages(parsed.messages, {
13383
+ const parsedHydratedMessages = hydrateCliParsedMessages(parsed.messages, {
13205
13384
  committedMessages: this.committedMessages,
13206
13385
  scope: this.currentTurnScope,
13207
13386
  lastOutputAt: this.lastOutputAt
13208
13387
  });
13388
+ const committedHydratedMessages = this.committedMessages.map((message, index) => buildChatMessage({
13389
+ ...message,
13390
+ id: message.id || `msg_${index}`,
13391
+ index: typeof message.index === "number" ? message.index : index,
13392
+ receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
13393
+ }));
13394
+ const shouldPreferCommittedHistoryReplay = !this.currentTurnScope && !this.activeModal && committedHydratedMessages.length > parsedHydratedMessages.length;
13395
+ const hydratedMessages = shouldPreferCommittedMessages || shouldPreferCommittedHistoryReplay ? committedHydratedMessages : parsedHydratedMessages;
13209
13396
  result = {
13210
13397
  id: parsed.id || "cli_session",
13211
13398
  status: parsed.status || this.currentStatus,
@@ -13229,6 +13416,23 @@ var init_provider_cli_adapter = __esm({
13229
13416
  activeModal: this.activeModal
13230
13417
  };
13231
13418
  }
13419
+ const hasVisibleAssistantMessage = Array.isArray(result?.messages) && result.messages.some((message) => message?.role === "assistant" && typeof message?.content === "string" && message.content.trim());
13420
+ const shouldClampStaleGeneratingToIdle = result?.status === "generating" && this.currentStatus === "idle" && !this.currentTurnScope && !result?.activeModal && hasVisibleAssistantMessage;
13421
+ if (shouldClampStaleGeneratingToIdle) {
13422
+ result = {
13423
+ ...result,
13424
+ status: "idle",
13425
+ messages: Array.isArray(result.messages) ? result.messages.map((message) => {
13426
+ if (message?.role !== "assistant" || !message?.meta?.streaming) return message;
13427
+ const nextMeta = { ...message.meta || {} };
13428
+ delete nextMeta.streaming;
13429
+ return {
13430
+ ...message,
13431
+ ...Object.keys(nextMeta).length > 0 ? { meta: nextMeta } : { meta: void 0 }
13432
+ };
13433
+ }) : result.messages
13434
+ };
13435
+ }
13232
13436
  this.parsedStatusCache = {
13233
13437
  committedMessagesRef: this.committedMessages,
13234
13438
  responseBuffer: this.responseBuffer,
@@ -13361,9 +13565,27 @@ ${data.message || ""}`.trim();
13361
13565
  }
13362
13566
  }
13363
13567
  if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
13364
- if (this.isWaitingForResponse && !allowInputDuringGeneration) {
13568
+ const parsedStatusBeforeSend = !allowInputDuringGeneration ? (() => {
13569
+ try {
13570
+ return this.getScriptParsedStatus?.() || null;
13571
+ } catch {
13572
+ return null;
13573
+ }
13574
+ })() : null;
13575
+ const parsedSessionStatus = typeof parsedStatusBeforeSend?.status === "string" ? String(parsedStatusBeforeSend.status) : "";
13576
+ const parsedMessagesBeforeSend = Array.isArray(parsedStatusBeforeSend?.messages) ? parsedStatusBeforeSend.messages.filter((message) => message && (message.role === "user" || message.role === "assistant")) : [];
13577
+ const shouldCommitParsedIdleBeforeSend = !allowInputDuringGeneration && parsedSessionStatus === "idle" && parsedMessagesBeforeSend.length > this.committedMessages.length && parsedMessagesBeforeSend.some((message) => message?.role === "assistant" && typeof message?.content === "string" && message.content.trim());
13578
+ if (shouldCommitParsedIdleBeforeSend) {
13579
+ this.commitCurrentTranscript();
13580
+ }
13581
+ if (!allowInputDuringGeneration && (parsedSessionStatus === "generating" || parsedSessionStatus === "long_generating")) {
13365
13582
  throw new Error(`${this.cliName} is still processing the previous prompt`);
13366
13583
  }
13584
+ if (this.isWaitingForResponse && !allowInputDuringGeneration) {
13585
+ if (!this.clearStaleIdleResponseGuard("send_message_guard")) {
13586
+ throw new Error(`${this.cliName} is still processing the previous prompt`);
13587
+ }
13588
+ }
13367
13589
  const blockingModal = this.activeModal || this.getStartupConfirmationModal(this.terminalScreen.getText() || "");
13368
13590
  if (blockingModal || this.currentStatus === "waiting_approval") {
13369
13591
  throw new Error(`${this.cliName} is awaiting confirmation before it can accept a prompt`);
@@ -13443,7 +13665,7 @@ ${data.message || ""}`.trim();
13443
13665
  this.submitRetryTimer = null;
13444
13666
  if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
13445
13667
  if (this.currentStatus === "waiting_approval") return;
13446
- if ((this.responseBuffer || "").trim()) return;
13668
+ if (this.hasMeaningfulResponseBuffer(normalizedPromptSnippet)) return;
13447
13669
  const screenText2 = this.terminalScreen.getText();
13448
13670
  if (!promptLikelyVisible(screenText2, normalizedPromptSnippet)) return;
13449
13671
  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;
@@ -13480,7 +13702,7 @@ ${data.message || ""}`.trim();
13480
13702
  this.submitRetryTimer = null;
13481
13703
  if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
13482
13704
  if (this.currentStatus === "waiting_approval") return;
13483
- if ((this.responseBuffer || "").trim()) return;
13705
+ if (this.hasMeaningfulResponseBuffer(normalizedPromptSnippet)) return;
13484
13706
  const screenText = this.terminalScreen.getText();
13485
13707
  if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
13486
13708
  LOG.info("CLI", `[${this.cliType}] Retrying submit key for stuck prompt (attempt 1)`);
@@ -14213,7 +14435,7 @@ var init_cli_provider_instance = __esm({
14213
14435
  activeChat: {
14214
14436
  id: `${this.type}_${this.workingDir}`,
14215
14437
  title: parsedStatus?.title || dirName,
14216
- status: parseErrorMessage ? "error" : autoApproveActive && parsedStatus?.status === "waiting_approval" ? "generating" : parsedStatus?.status || visibleStatus,
14438
+ status: parseErrorMessage ? "error" : autoApproveActive && parsedStatus?.status === "waiting_approval" ? "generating" : adapterStatus.status !== "idle" ? visibleStatus : parsedStatus?.status || visibleStatus,
14217
14439
  messages: mergedMessages,
14218
14440
  activeModal: autoApproveActive ? null : parsedStatus?.activeModal ?? adapterStatus.activeModal,
14219
14441
  inputContent: ""
@@ -44907,6 +45129,13 @@ data: ${JSON.stringify(msg.data)}
44907
45129
  });
44908
45130
 
44909
45131
  // ../../oss/packages/daemon-core/src/cli-adapters/session-host-transport.ts
45132
+ function shouldResumeAttachedSession(record2) {
45133
+ if (!record2) return false;
45134
+ if (record2.lifecycle === "interrupted") return true;
45135
+ if (record2.lifecycle !== "stopped") return false;
45136
+ if (record2.meta?.restoredFromStorage === true) return true;
45137
+ return typeof record2.meta?.runtimeRecoveryState === "string" && String(record2.meta.runtimeRecoveryState).trim().length > 0;
45138
+ }
44910
45139
  var SessionHostRuntimeTransport, SessionHostPtyTransportFactory;
44911
45140
  var init_session_host_transport = __esm({
44912
45141
  "../../oss/packages/daemon-core/src/cli-adapters/session-host-transport.ts"() {
@@ -45086,7 +45315,7 @@ var init_session_host_transport = __esm({
45086
45315
  payload: {}
45087
45316
  });
45088
45317
  const existingRecord = existingRecords.success && existingRecords.result ? existingRecords.result.find((item) => item.sessionId === this.options.runtimeId) || null : null;
45089
- if (existingRecord?.lifecycle === "interrupted") {
45318
+ if (shouldResumeAttachedSession(existingRecord)) {
45090
45319
  const resumeResponse = await this.client.request({
45091
45320
  type: "resume_session",
45092
45321
  payload: {
@@ -45396,6 +45625,8 @@ var init_runtime_support = __esm({
45396
45625
  // ../../oss/packages/daemon-core/src/session-host/startup-restore-policy.js
45397
45626
  function shouldAutoRestoreHostedSessionsOnStartup(env3 = process.env) {
45398
45627
  const raw = typeof env3.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP === "string" ? env3.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP.trim().toLowerCase() : "";
45628
+ if (!raw) return true;
45629
+ if (raw === "0" || raw === "false" || raw === "no") return false;
45399
45630
  return raw === "1" || raw === "true" || raw === "yes";
45400
45631
  }
45401
45632
  var init_startup_restore_policy = __esm({
@@ -77593,8 +77824,6 @@ var init_server_connection = __esm({
77593
77824
  if (misses >= 3 && this.ws) {
77594
77825
  LOG.warn("Server", `[ServerConn] Pong timeout (${misses}x) \u2014 closing stale WS`);
77595
77826
  this.ws.terminate();
77596
- } else if (misses === 1) {
77597
- LOG.info("Server", `[ServerConn] Pong timeout (${misses}x) \u2014 keeping WS open and retrying`);
77598
77827
  } else {
77599
77828
  LOG.warn("Server", `[ServerConn] Pong timeout (${misses}x) \u2014 keeping WS open and retrying`);
77600
77829
  }
@@ -86150,7 +86379,7 @@ var init_adhdev_daemon = __esm({
86150
86379
  init_source();
86151
86380
  init_version();
86152
86381
  init_src();
86153
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.84" });
86382
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.86" });
86154
86383
  AdhdevDaemon = class _AdhdevDaemon {
86155
86384
  localHttpServer = null;
86156
86385
  localWss = null;