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/index.js CHANGED
@@ -7162,6 +7162,7 @@ function normalizeReadChatCommandStatus(status, activeModal) {
7162
7162
  }
7163
7163
  function buildReadChatCommandResult(payload, args) {
7164
7164
  let validatedPayload;
7165
+ const debugReadChat = payload?.debugReadChat && typeof payload.debugReadChat === "object" ? payload.debugReadChat : void 0;
7165
7166
  try {
7166
7167
  validatedPayload = validateReadChatResultPayload({
7167
7168
  ...payload,
@@ -7182,7 +7183,8 @@ function buildReadChatCommandResult(payload, args) {
7182
7183
  syncMode: "full",
7183
7184
  replaceFrom: 0,
7184
7185
  totalMessages: messages.length,
7185
- lastMessageSignature
7186
+ lastMessageSignature,
7187
+ ...debugReadChat ? { debugReadChat } : {}
7186
7188
  };
7187
7189
  }
7188
7190
  const sync = computeReadChatSync(messages, cursor);
@@ -7193,7 +7195,8 @@ function buildReadChatCommandResult(payload, args) {
7193
7195
  syncMode: sync.syncMode,
7194
7196
  replaceFrom: sync.replaceFrom,
7195
7197
  totalMessages: sync.totalMessages,
7196
- lastMessageSignature: sync.lastMessageSignature
7198
+ lastMessageSignature: sync.lastMessageSignature,
7199
+ ...debugReadChat ? { debugReadChat } : {}
7197
7200
  };
7198
7201
  }
7199
7202
  function didProviderConfirmSend(result) {
@@ -7284,14 +7287,33 @@ async function handleReadChat(h, args) {
7284
7287
  }
7285
7288
  }
7286
7289
  const parsedRecord = parsedStatus && typeof parsedStatus === "object" ? parsedStatus : null;
7287
- const status = parsedRecord || adapter.getStatus();
7290
+ const adapterStatus = adapter.getStatus();
7291
+ const shouldPreferAdapterMessages = Array.isArray(adapterStatus.messages) && adapterStatus.messages.length > 0 && Array.isArray(parsedRecord?.messages) && adapterStatus.messages.length > parsedRecord.messages.length;
7292
+ const status = parsedRecord ? {
7293
+ ...parsedRecord,
7294
+ messages: shouldPreferAdapterMessages ? adapterStatus.messages : parsedRecord.messages,
7295
+ status: adapterStatus.status !== "idle" ? adapterStatus.status : parsedRecord.status || adapterStatus.status,
7296
+ activeModal: parsedRecord.activeModal || adapterStatus.activeModal
7297
+ } : adapterStatus;
7288
7298
  const title = typeof parsedRecord?.title === "string" ? parsedRecord.title : void 0;
7289
7299
  const providerSessionId = typeof parsedRecord?.providerSessionId === "string" ? parsedRecord.providerSessionId : void 0;
7290
7300
  if (status) {
7301
+ 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}`);
7291
7302
  return buildReadChatCommandResult({
7292
7303
  messages: status.messages || [],
7293
7304
  status: status.status,
7294
7305
  activeModal: status.activeModal,
7306
+ debugReadChat: {
7307
+ provider: adapter.cliType,
7308
+ targetSessionId: String(args?.targetSessionId || ""),
7309
+ adapterStatus: String(adapterStatus.status || ""),
7310
+ parsedStatus: String(parsedRecord?.status || ""),
7311
+ returnedStatus: String(status.status || ""),
7312
+ shouldPreferAdapterMessages,
7313
+ adapterMsgCount: Array.isArray(adapterStatus.messages) ? adapterStatus.messages.length : 0,
7314
+ parsedMsgCount: Array.isArray(parsedRecord?.messages) ? parsedRecord.messages.length : 0,
7315
+ returnedMsgCount: Array.isArray(status.messages) ? status.messages.length : 0
7316
+ },
7295
7317
  ...title ? { title } : {},
7296
7318
  ...providerSessionId ? { providerSessionId } : {}
7297
7319
  }, args);
@@ -11793,6 +11815,58 @@ var init_provider_cli_adapter = __esm({
11793
11815
  `[${this.cliType}] Interactive prompt wait timed out after ${maxWaitMs}ms; proceeding with screen=${JSON.stringify(summarizeCliTraceText(finalScreenText, 240)).slice(0, 280)}`
11794
11816
  );
11795
11817
  }
11818
+ clearStaleIdleResponseGuard(reason) {
11819
+ const screenText = this.terminalScreen.getText() || "";
11820
+ const visibleIdlePrompt = this.looksLikeVisibleIdlePrompt(screenText);
11821
+ const blockingModal = this.activeModal || this.getStartupConfirmationModal(screenText);
11822
+ if (!this.isWaitingForResponse || this.currentStatus !== "idle" || !visibleIdlePrompt || !!blockingModal) {
11823
+ return false;
11824
+ }
11825
+ if (this.responseTimeout) {
11826
+ clearTimeout(this.responseTimeout);
11827
+ this.responseTimeout = null;
11828
+ }
11829
+ if (this.idleTimeout) {
11830
+ clearTimeout(this.idleTimeout);
11831
+ this.idleTimeout = null;
11832
+ }
11833
+ if (this.approvalExitTimeout) {
11834
+ clearTimeout(this.approvalExitTimeout);
11835
+ this.approvalExitTimeout = null;
11836
+ }
11837
+ if (this.finishRetryTimer) {
11838
+ clearTimeout(this.finishRetryTimer);
11839
+ this.finishRetryTimer = null;
11840
+ }
11841
+ this.clearIdleFinishCandidate(reason);
11842
+ this.responseBuffer = "";
11843
+ this.isWaitingForResponse = false;
11844
+ this.responseSettleIgnoreUntil = 0;
11845
+ this.submitRetryUsed = false;
11846
+ this.submitRetryPromptSnippet = "";
11847
+ this.finishRetryCount = 0;
11848
+ this.currentTurnScope = null;
11849
+ this.activeModal = null;
11850
+ this.recordTrace("stale_idle_response_cleared", {
11851
+ reason,
11852
+ screenText: summarizeCliTraceText(screenText, 240)
11853
+ });
11854
+ return true;
11855
+ }
11856
+ hasMeaningfulResponseBuffer(promptSnippet) {
11857
+ const raw = String(this.responseBuffer || "").trim();
11858
+ if (!raw) return false;
11859
+ const normalizedPrompt = compactPromptText(promptSnippet);
11860
+ if (!normalizedPrompt) return true;
11861
+ const normalizedBuffer = compactPromptText(raw);
11862
+ if (!normalizedBuffer) return false;
11863
+ if (normalizedBuffer === normalizedPrompt) return false;
11864
+ if (normalizedBuffer.startsWith(normalizedPrompt)) {
11865
+ 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();
11866
+ return remainder.length > 0;
11867
+ }
11868
+ return true;
11869
+ }
11796
11870
  evaluateSettled() {
11797
11871
  const now = Date.now();
11798
11872
  if (this.submitPendingUntil > now || this.responseSettleIgnoreUntil > now) {
@@ -11825,7 +11899,11 @@ var init_provider_cli_adapter = __esm({
11825
11899
  scope: this.currentTurnScope,
11826
11900
  lastOutputAt: this.lastOutputAt
11827
11901
  }) : [];
11902
+ if (this.maybeCommitVisibleIdleTranscript(parsedTranscript)) {
11903
+ return;
11904
+ }
11828
11905
  const lastParsedAssistant = [...parsedMessages].reverse().find((message) => message.role === "assistant");
11906
+ const normalizedPromptSnippet = normalizePromptText(this.submitRetryPromptSnippet || this.currentTurnScope?.prompt || "");
11829
11907
  this.recordTrace("settled", {
11830
11908
  tail: summarizeCliTraceText(tail, 500),
11831
11909
  screenText: summarizeCliTraceText(screenText, 1200),
@@ -11843,6 +11921,24 @@ var init_provider_cli_adapter = __esm({
11843
11921
  scope: this.currentTurnScope
11844
11922
  })
11845
11923
  });
11924
+ if (this.currentTurnScope && !lastParsedAssistant && !this.submitRetryUsed && this.ptyProcess && this.currentStatus !== "waiting_approval" && promptLikelyVisible(screenText, normalizedPromptSnippet) && !this.hasMeaningfulResponseBuffer(normalizedPromptSnippet)) {
11925
+ this.submitRetryUsed = true;
11926
+ this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
11927
+ LOG.info("CLI", `[${this.cliType}] Retrying submit key from settled parser (no assistant yet)`);
11928
+ this.recordTrace("submit_write", {
11929
+ mode: "settled_retry",
11930
+ sendKey: this.sendKey,
11931
+ screenText: summarizeCliTraceText(screenText, 500)
11932
+ });
11933
+ this.ptyProcess.write(this.sendKey);
11934
+ if (this.settleTimer) clearTimeout(this.settleTimer);
11935
+ this.settleTimer = setTimeout(() => {
11936
+ this.settleTimer = null;
11937
+ this.settledBuffer = this.recentOutputBuffer;
11938
+ this.evaluateSettled();
11939
+ }, this.timeouts.outputSettle + 150);
11940
+ return;
11941
+ }
11846
11942
  if (this.currentTurnScope && !lastParsedAssistant) {
11847
11943
  LOG.info(
11848
11944
  "CLI",
@@ -11885,7 +11981,15 @@ var init_provider_cli_adapter = __esm({
11885
11981
  }
11886
11982
  const recentInteractiveActivity = this.hasRecentInteractiveActivity(now);
11887
11983
  const statusActivityHoldMs = this.getStatusActivityHoldMs();
11888
- const shouldHoldGenerating = scriptStatus === "idle" && this.isWaitingForResponse && !modal && recentInteractiveActivity;
11984
+ const visibleIdlePrompt = this.looksLikeVisibleIdlePrompt(screenText);
11985
+ const visibleAssistantCandidate = this.looksLikeVisibleAssistantCandidate(screenText);
11986
+ if (this.currentTurnScope && this.cliType === "claude-cli") {
11987
+ LOG.info(
11988
+ "CLI",
11989
+ `[${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)}`
11990
+ );
11991
+ }
11992
+ const shouldHoldGenerating = scriptStatus === "idle" && this.isWaitingForResponse && !modal && recentInteractiveActivity && !(visibleIdlePrompt && visibleAssistantCandidate);
11889
11993
  if (shouldHoldGenerating) {
11890
11994
  this.clearIdleFinishCandidate("hold_generating_recent_activity");
11891
11995
  this.setStatus("generating", "recent_activity_hold");
@@ -11916,8 +12020,8 @@ var init_provider_cli_adapter = __esm({
11916
12020
  if (scriptStatus === "waiting_approval") {
11917
12021
  this.clearIdleFinishCandidate("waiting_approval");
11918
12022
  const inCooldown = this.lastApprovalResolvedAt && Date.now() - this.lastApprovalResolvedAt < this.timeouts.approvalCooldown;
11919
- const visibleIdlePrompt = this.looksLikeVisibleIdlePrompt(screenText);
11920
- if ((inCooldown || visibleIdlePrompt) && !modal) {
12023
+ const visibleIdlePrompt2 = this.looksLikeVisibleIdlePrompt(screenText);
12024
+ if ((inCooldown || visibleIdlePrompt2) && !modal) {
11921
12025
  if (this.approvalExitTimeout) {
11922
12026
  clearTimeout(this.approvalExitTimeout);
11923
12027
  this.approvalExitTimeout = null;
@@ -11989,7 +12093,7 @@ var init_provider_cli_adapter = __esm({
11989
12093
  this.lastApprovalResolvedAt = Date.now();
11990
12094
  }
11991
12095
  if (this.isWaitingForResponse) {
11992
- const visibleIdlePrompt = this.looksLikeVisibleIdlePrompt(screenText);
12096
+ const visibleIdlePrompt2 = this.looksLikeVisibleIdlePrompt(screenText);
11993
12097
  const quietForMs = this.lastNonEmptyOutputAt ? now - this.lastNonEmptyOutputAt : Number.MAX_SAFE_INTEGER;
11994
12098
  const screenStableMs = this.lastScreenChangeAt ? now - this.lastScreenChangeAt : 0;
11995
12099
  const hasAssistantTurn = !!lastParsedAssistant;
@@ -11997,12 +12101,12 @@ var init_provider_cli_adapter = __esm({
11997
12101
  const idleFinishConfirmMs = this.getIdleFinishConfirmMs();
11998
12102
  const idleQuietThresholdMs = Math.max(idleFinishConfirmMs, this.timeouts.outputSettle);
11999
12103
  const idleStableThresholdMs = idleFinishConfirmMs;
12000
- const idleReady = visibleIdlePrompt && !modal && hasAssistantTurn && quietForMs >= idleQuietThresholdMs && screenStableMs >= idleStableThresholdMs;
12104
+ const idleReady = visibleIdlePrompt2 && !modal && hasAssistantTurn && quietForMs >= idleQuietThresholdMs && screenStableMs >= idleStableThresholdMs;
12001
12105
  const candidate = this.idleFinishCandidate;
12002
12106
  const candidateQuiet = !!candidate && candidate.responseEpoch === this.responseEpoch && candidate.lastOutputAt === this.lastOutputAt && candidate.lastScreenChangeAt === this.lastScreenChangeAt && assistantLength >= candidate.assistantLength && now - candidate.armedAt >= idleFinishConfirmMs;
12003
12107
  const canFinishImmediately = idleReady && candidateQuiet;
12004
12108
  this.recordTrace("idle_decision", {
12005
- visibleIdlePrompt,
12109
+ visibleIdlePrompt: visibleIdlePrompt2,
12006
12110
  quietForMs,
12007
12111
  screenStableMs,
12008
12112
  hasAssistantTurn,
@@ -12122,6 +12226,70 @@ var init_provider_cli_adapter = __esm({
12122
12226
  this.setStatus("idle", "response_finished");
12123
12227
  this.onStatusChange?.();
12124
12228
  }
12229
+ maybeCommitVisibleIdleTranscript(parsed, options) {
12230
+ const allowImmediateScriptIdleCommit = this.provider.allowInputDuringGeneration === true;
12231
+ if (!allowImmediateScriptIdleCommit) return false;
12232
+ if (!parsed || !Array.isArray(parsed.messages) || parsed.status !== "idle" || !this.isWaitingForResponse || !this.currentTurnScope || this.activeModal || parsed.activeModal) {
12233
+ return false;
12234
+ }
12235
+ if (options?.requireVisibleAssistantCandidate) {
12236
+ const candidateText = options.screenText || this.terminalScreen.getText() || "";
12237
+ if (!this.looksLikeVisibleAssistantCandidate(candidateText)) {
12238
+ return false;
12239
+ }
12240
+ }
12241
+ const hydratedForIdleCommit = normalizeCliParsedMessages(parsed.messages, {
12242
+ committedMessages: this.committedMessages,
12243
+ scope: this.currentTurnScope,
12244
+ lastOutputAt: this.lastOutputAt
12245
+ });
12246
+ const visibleAssistant = [...hydratedForIdleCommit].reverse().find((message) => message.role === "assistant" && message.content.trim());
12247
+ if (!visibleAssistant) return false;
12248
+ this.committedMessages = hydratedForIdleCommit;
12249
+ const promptForTrim = this.currentTurnScope?.prompt || getLastUserPromptText(this.committedMessages);
12250
+ if (promptForTrim) {
12251
+ const lastAssistantForTrim = [...this.committedMessages].reverse().find((message) => message.role === "assistant");
12252
+ if (lastAssistantForTrim) {
12253
+ lastAssistantForTrim.content = trimPromptEchoPrefix(lastAssistantForTrim.content, promptForTrim);
12254
+ }
12255
+ }
12256
+ if (this.responseTimeout) {
12257
+ clearTimeout(this.responseTimeout);
12258
+ this.responseTimeout = null;
12259
+ }
12260
+ if (this.idleTimeout) {
12261
+ clearTimeout(this.idleTimeout);
12262
+ this.idleTimeout = null;
12263
+ }
12264
+ if (this.approvalExitTimeout) {
12265
+ clearTimeout(this.approvalExitTimeout);
12266
+ this.approvalExitTimeout = null;
12267
+ }
12268
+ if (this.submitRetryTimer) {
12269
+ clearTimeout(this.submitRetryTimer);
12270
+ this.submitRetryTimer = null;
12271
+ }
12272
+ if (this.finishRetryTimer) {
12273
+ clearTimeout(this.finishRetryTimer);
12274
+ this.finishRetryTimer = null;
12275
+ }
12276
+ this.syncMessageViews();
12277
+ this.responseBuffer = "";
12278
+ this.isWaitingForResponse = false;
12279
+ this.responseSettleIgnoreUntil = 0;
12280
+ this.submitRetryUsed = false;
12281
+ this.submitRetryPromptSnippet = "";
12282
+ this.finishRetryCount = 0;
12283
+ this.currentTurnScope = null;
12284
+ this.activeModal = null;
12285
+ this.setStatus("idle", "script_idle_commit");
12286
+ this.onStatusChange?.();
12287
+ this.recordTrace("script_idle_commit", {
12288
+ messageCount: this.committedMessages.length,
12289
+ lastAssistant: summarizeCliTraceText(visibleAssistant.content, 320)
12290
+ });
12291
+ return true;
12292
+ }
12125
12293
  commitCurrentTranscript() {
12126
12294
  const parsed = this.parseCurrentTranscript(
12127
12295
  this.committedMessages,
@@ -12143,6 +12311,12 @@ var init_provider_cli_adapter = __esm({
12143
12311
  }
12144
12312
  this.syncMessageViews();
12145
12313
  const lastAssistant = [...this.committedMessages].reverse().find((message) => message.role === "assistant");
12314
+ if (this.currentTurnScope) {
12315
+ LOG.info(
12316
+ "CLI",
12317
+ `[${this.cliType}] commitCurrentTranscript committedMessages=${this.committedMessages.length} finalLastAssistant=${JSON.stringify(summarizeCliTraceText(lastAssistant?.content || "", 220)).slice(0, 260)}`
12318
+ );
12319
+ }
12146
12320
  this.recordTrace("commit_transcript", {
12147
12321
  parsedStatus: parsed.status || null,
12148
12322
  messageCount: this.committedMessages.length,
@@ -12162,11 +12336,18 @@ var init_provider_cli_adapter = __esm({
12162
12336
  `[${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 || "-"}`
12163
12337
  );
12164
12338
  }
12339
+ const hasAssistant = !!lastAssistant;
12165
12340
  return {
12166
- hasAssistant: !!lastAssistant,
12341
+ hasAssistant,
12167
12342
  assistantContent: lastAssistant?.content || ""
12168
12343
  };
12169
12344
  }
12345
+ if (this.currentTurnScope) {
12346
+ LOG.info(
12347
+ "CLI",
12348
+ `[${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 || "-"}`
12349
+ );
12350
+ }
12170
12351
  return {
12171
12352
  hasAssistant: false,
12172
12353
  assistantContent: ""
@@ -12252,19 +12433,25 @@ var init_provider_cli_adapter = __esm({
12252
12433
  this.currentTurnScope,
12253
12434
  screenText
12254
12435
  );
12255
- const shouldPreferCommittedMessages = !this.currentTurnScope && this.currentStatus === "idle" && !this.activeModal;
12436
+ if (this.maybeCommitVisibleIdleTranscript(parsed)) {
12437
+ return this.getScriptParsedStatus();
12438
+ }
12439
+ const shouldPreferCommittedMessages = !this.currentTurnScope && !this.activeModal && this.currentStatus === "idle";
12256
12440
  let result;
12257
12441
  if (parsed && Array.isArray(parsed.messages)) {
12258
- const hydratedMessages = shouldPreferCommittedMessages ? this.committedMessages.map((message, index) => buildChatMessage({
12259
- ...message,
12260
- id: message.id || `msg_${index}`,
12261
- index: typeof message.index === "number" ? message.index : index,
12262
- receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
12263
- })) : hydrateCliParsedMessages(parsed.messages, {
12442
+ const parsedHydratedMessages = hydrateCliParsedMessages(parsed.messages, {
12264
12443
  committedMessages: this.committedMessages,
12265
12444
  scope: this.currentTurnScope,
12266
12445
  lastOutputAt: this.lastOutputAt
12267
12446
  });
12447
+ const committedHydratedMessages = this.committedMessages.map((message, index) => buildChatMessage({
12448
+ ...message,
12449
+ id: message.id || `msg_${index}`,
12450
+ index: typeof message.index === "number" ? message.index : index,
12451
+ receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
12452
+ }));
12453
+ const shouldPreferCommittedHistoryReplay = !this.currentTurnScope && !this.activeModal && committedHydratedMessages.length > parsedHydratedMessages.length;
12454
+ const hydratedMessages = shouldPreferCommittedMessages || shouldPreferCommittedHistoryReplay ? committedHydratedMessages : parsedHydratedMessages;
12268
12455
  result = {
12269
12456
  id: parsed.id || "cli_session",
12270
12457
  status: parsed.status || this.currentStatus,
@@ -12288,6 +12475,23 @@ var init_provider_cli_adapter = __esm({
12288
12475
  activeModal: this.activeModal
12289
12476
  };
12290
12477
  }
12478
+ const hasVisibleAssistantMessage = Array.isArray(result?.messages) && result.messages.some((message) => message?.role === "assistant" && typeof message?.content === "string" && message.content.trim());
12479
+ const shouldClampStaleGeneratingToIdle = result?.status === "generating" && this.currentStatus === "idle" && !this.currentTurnScope && !result?.activeModal && hasVisibleAssistantMessage;
12480
+ if (shouldClampStaleGeneratingToIdle) {
12481
+ result = {
12482
+ ...result,
12483
+ status: "idle",
12484
+ messages: Array.isArray(result.messages) ? result.messages.map((message) => {
12485
+ if (message?.role !== "assistant" || !message?.meta?.streaming) return message;
12486
+ const nextMeta = { ...message.meta || {} };
12487
+ delete nextMeta.streaming;
12488
+ return {
12489
+ ...message,
12490
+ ...Object.keys(nextMeta).length > 0 ? { meta: nextMeta } : { meta: void 0 }
12491
+ };
12492
+ }) : result.messages
12493
+ };
12494
+ }
12291
12495
  this.parsedStatusCache = {
12292
12496
  committedMessagesRef: this.committedMessages,
12293
12497
  responseBuffer: this.responseBuffer,
@@ -12420,9 +12624,27 @@ ${data.message || ""}`.trim();
12420
12624
  }
12421
12625
  }
12422
12626
  if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
12423
- if (this.isWaitingForResponse && !allowInputDuringGeneration) {
12627
+ const parsedStatusBeforeSend = !allowInputDuringGeneration ? (() => {
12628
+ try {
12629
+ return this.getScriptParsedStatus?.() || null;
12630
+ } catch {
12631
+ return null;
12632
+ }
12633
+ })() : null;
12634
+ const parsedSessionStatus = typeof parsedStatusBeforeSend?.status === "string" ? String(parsedStatusBeforeSend.status) : "";
12635
+ const parsedMessagesBeforeSend = Array.isArray(parsedStatusBeforeSend?.messages) ? parsedStatusBeforeSend.messages.filter((message) => message && (message.role === "user" || message.role === "assistant")) : [];
12636
+ const shouldCommitParsedIdleBeforeSend = !allowInputDuringGeneration && parsedSessionStatus === "idle" && parsedMessagesBeforeSend.length > this.committedMessages.length && parsedMessagesBeforeSend.some((message) => message?.role === "assistant" && typeof message?.content === "string" && message.content.trim());
12637
+ if (shouldCommitParsedIdleBeforeSend) {
12638
+ this.commitCurrentTranscript();
12639
+ }
12640
+ if (!allowInputDuringGeneration && (parsedSessionStatus === "generating" || parsedSessionStatus === "long_generating")) {
12424
12641
  throw new Error(`${this.cliName} is still processing the previous prompt`);
12425
12642
  }
12643
+ if (this.isWaitingForResponse && !allowInputDuringGeneration) {
12644
+ if (!this.clearStaleIdleResponseGuard("send_message_guard")) {
12645
+ throw new Error(`${this.cliName} is still processing the previous prompt`);
12646
+ }
12647
+ }
12426
12648
  const blockingModal = this.activeModal || this.getStartupConfirmationModal(this.terminalScreen.getText() || "");
12427
12649
  if (blockingModal || this.currentStatus === "waiting_approval") {
12428
12650
  throw new Error(`${this.cliName} is awaiting confirmation before it can accept a prompt`);
@@ -12502,7 +12724,7 @@ ${data.message || ""}`.trim();
12502
12724
  this.submitRetryTimer = null;
12503
12725
  if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
12504
12726
  if (this.currentStatus === "waiting_approval") return;
12505
- if ((this.responseBuffer || "").trim()) return;
12727
+ if (this.hasMeaningfulResponseBuffer(normalizedPromptSnippet)) return;
12506
12728
  const screenText2 = this.terminalScreen.getText();
12507
12729
  if (!promptLikelyVisible(screenText2, normalizedPromptSnippet)) return;
12508
12730
  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;
@@ -12539,7 +12761,7 @@ ${data.message || ""}`.trim();
12539
12761
  this.submitRetryTimer = null;
12540
12762
  if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
12541
12763
  if (this.currentStatus === "waiting_approval") return;
12542
- if ((this.responseBuffer || "").trim()) return;
12764
+ if (this.hasMeaningfulResponseBuffer(normalizedPromptSnippet)) return;
12543
12765
  const screenText = this.terminalScreen.getText();
12544
12766
  if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
12545
12767
  LOG.info("CLI", `[${this.cliType}] Retrying submit key for stuck prompt (attempt 1)`);
@@ -13272,7 +13494,7 @@ var init_cli_provider_instance = __esm({
13272
13494
  activeChat: {
13273
13495
  id: `${this.type}_${this.workingDir}`,
13274
13496
  title: parsedStatus?.title || dirName,
13275
- status: parseErrorMessage ? "error" : autoApproveActive && parsedStatus?.status === "waiting_approval" ? "generating" : parsedStatus?.status || visibleStatus,
13497
+ status: parseErrorMessage ? "error" : autoApproveActive && parsedStatus?.status === "waiting_approval" ? "generating" : adapterStatus.status !== "idle" ? visibleStatus : parsedStatus?.status || visibleStatus,
13276
13498
  messages: mergedMessages,
13277
13499
  activeModal: autoApproveActive ? null : parsedStatus?.activeModal ?? adapterStatus.activeModal,
13278
13500
  inputContent: ""
@@ -43966,6 +44188,13 @@ data: ${JSON.stringify(msg.data)}
43966
44188
  });
43967
44189
 
43968
44190
  // ../../oss/packages/daemon-core/src/cli-adapters/session-host-transport.ts
44191
+ function shouldResumeAttachedSession(record2) {
44192
+ if (!record2) return false;
44193
+ if (record2.lifecycle === "interrupted") return true;
44194
+ if (record2.lifecycle !== "stopped") return false;
44195
+ if (record2.meta?.restoredFromStorage === true) return true;
44196
+ return typeof record2.meta?.runtimeRecoveryState === "string" && String(record2.meta.runtimeRecoveryState).trim().length > 0;
44197
+ }
43969
44198
  var SessionHostRuntimeTransport, SessionHostPtyTransportFactory;
43970
44199
  var init_session_host_transport = __esm({
43971
44200
  "../../oss/packages/daemon-core/src/cli-adapters/session-host-transport.ts"() {
@@ -44145,7 +44374,7 @@ var init_session_host_transport = __esm({
44145
44374
  payload: {}
44146
44375
  });
44147
44376
  const existingRecord = existingRecords.success && existingRecords.result ? existingRecords.result.find((item) => item.sessionId === this.options.runtimeId) || null : null;
44148
- if (existingRecord?.lifecycle === "interrupted") {
44377
+ if (shouldResumeAttachedSession(existingRecord)) {
44149
44378
  const resumeResponse = await this.client.request({
44150
44379
  type: "resume_session",
44151
44380
  payload: {
@@ -44455,6 +44684,8 @@ var init_runtime_support = __esm({
44455
44684
  // ../../oss/packages/daemon-core/src/session-host/startup-restore-policy.js
44456
44685
  function shouldAutoRestoreHostedSessionsOnStartup(env3 = process.env) {
44457
44686
  const raw = typeof env3.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP === "string" ? env3.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP.trim().toLowerCase() : "";
44687
+ if (!raw) return true;
44688
+ if (raw === "0" || raw === "false" || raw === "no") return false;
44458
44689
  return raw === "1" || raw === "true" || raw === "yes";
44459
44690
  }
44460
44691
  var init_startup_restore_policy = __esm({
@@ -45422,8 +45653,6 @@ var init_server_connection = __esm({
45422
45653
  if (misses >= 3 && this.ws) {
45423
45654
  LOG.warn("Server", `[ServerConn] Pong timeout (${misses}x) \u2014 closing stale WS`);
45424
45655
  this.ws.terminate();
45425
- } else if (misses === 1) {
45426
- LOG.info("Server", `[ServerConn] Pong timeout (${misses}x) \u2014 keeping WS open and retrying`);
45427
45656
  } else {
45428
45657
  LOG.warn("Server", `[ServerConn] Pong timeout (${misses}x) \u2014 keeping WS open and retrying`);
45429
45658
  }
@@ -54446,7 +54675,7 @@ var init_adhdev_daemon = __esm({
54446
54675
  init_source2();
54447
54676
  init_version();
54448
54677
  init_src();
54449
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.84" });
54678
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.86" });
54450
54679
  AdhdevDaemon = class _AdhdevDaemon {
54451
54680
  localHttpServer = null;
54452
54681
  localWss = null;