@adhdev/daemon-standalone 0.9.5 → 0.9.7

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
@@ -29378,8 +29378,35 @@ var require_dist2 = __commonJS({
29378
29378
  function normalizeScreenSnapshot(text) {
29379
29379
  return sanitizeTerminalText(String(text || "")).replace(/\s+/g, " ").trim();
29380
29380
  }
29381
+ function shouldReflowComparableMessageLines(lines) {
29382
+ return Array.isArray(lines) && lines.length > 1 && lines.slice(0, -1).every((line) => String(line || "").trim().length >= 48) && !lines.some((line) => /^```/.test(line)) && !lines.some((line) => /^\|/.test(line)) && !lines.some((line) => /^\s*(?:[-*+] |\d+\.\s)/.test(line));
29383
+ }
29384
+ function joinComparableMessageLines(lines) {
29385
+ return lines.reduce((acc, line) => {
29386
+ const next = String(line || "").trim();
29387
+ if (!next) return acc;
29388
+ if (!acc) return next;
29389
+ if (/[,\d]$/.test(acc) && /^\d/.test(next)) {
29390
+ return `${acc}${next}`;
29391
+ }
29392
+ if (/[A-Za-z]$/.test(acc) && /^\d/.test(next)) {
29393
+ return `${acc}${next}`;
29394
+ }
29395
+ const fragmentMatch = acc.match(/([A-Za-z]{1,4})$/);
29396
+ const fragment = fragmentMatch ? fragmentMatch[1].toLowerCase() : "";
29397
+ if (/^[a-z]/.test(next) && fragment && !COMMON_COMPARABLE_WRAP_WORDS.has(fragment)) {
29398
+ return `${acc}${next}`;
29399
+ }
29400
+ return `${acc} ${next}`;
29401
+ }, "").replace(/\s+([,.;:!?])/g, "$1").replace(/(\d)\s+,/g, "$1,").replace(/\s+/g, " ").trim();
29402
+ }
29381
29403
  function normalizeComparableMessageContent(text) {
29382
- return String(text || "").replace(/\s+/g, " ").trim();
29404
+ const lines = String(text || "").split(/\r\n|\n|\r/g).map((line) => line.trim()).filter(Boolean);
29405
+ if (lines.length === 0) return "";
29406
+ if (shouldReflowComparableMessageLines(lines)) {
29407
+ return joinComparableMessageLines(lines);
29408
+ }
29409
+ return lines.join(" ").replace(/\s+/g, " ").trim();
29383
29410
  }
29384
29411
  function trimPromptEchoPrefix(text, promptText) {
29385
29412
  const prompt = normalizeComparableMessageContent(String(promptText || ""));
@@ -29412,9 +29439,6 @@ var require_dist2 = __commonJS({
29412
29439
  }
29413
29440
  return "";
29414
29441
  }
29415
- function looksLikeConfirmOnlyLabel(label) {
29416
- return /^(?:continue|confirm|ok|yes|trust|proceed|enter)$/i.test(String(label || "").trim());
29417
- }
29418
29442
  function parsePatternEntry(x) {
29419
29443
  if (x instanceof RegExp) return x;
29420
29444
  if (x && typeof x === "object" && typeof x.source === "string") {
@@ -29445,6 +29469,7 @@ var require_dist2 = __commonJS({
29445
29469
  var path9;
29446
29470
  var import_child_process4;
29447
29471
  var buildCliSpawnEnv;
29472
+ var COMMON_COMPARABLE_WRAP_WORDS;
29448
29473
  var init_provider_cli_shared = __esm2({
29449
29474
  "src/cli-adapters/provider-cli-shared.ts"() {
29450
29475
  "use strict";
@@ -29453,6 +29478,32 @@ var require_dist2 = __commonJS({
29453
29478
  import_child_process4 = require("child_process");
29454
29479
  init_spawn_env();
29455
29480
  buildCliSpawnEnv = import_session_host_core3.sanitizeSpawnEnv;
29481
+ COMMON_COMPARABLE_WRAP_WORDS = /* @__PURE__ */ new Set([
29482
+ "a",
29483
+ "an",
29484
+ "and",
29485
+ "as",
29486
+ "at",
29487
+ "but",
29488
+ "by",
29489
+ "for",
29490
+ "from",
29491
+ "in",
29492
+ "into",
29493
+ "is",
29494
+ "it",
29495
+ "of",
29496
+ "on",
29497
+ "or",
29498
+ "that",
29499
+ "the",
29500
+ "their",
29501
+ "then",
29502
+ "this",
29503
+ "to",
29504
+ "was",
29505
+ "with"
29506
+ ]);
29456
29507
  }
29457
29508
  });
29458
29509
  function sliceFromOffset(text, start) {
@@ -29506,8 +29557,44 @@ var require_dist2 = __commonJS({
29506
29557
  };
29507
29558
  });
29508
29559
  }
29560
+ function chooseMoreComparableCliMessage(left, right) {
29561
+ const leftComparable = normalizeComparableMessageContent(left.content || "");
29562
+ const rightComparable = normalizeComparableMessageContent(right.content || "");
29563
+ if (leftComparable && leftComparable === rightComparable) {
29564
+ const leftNewlines = String(left.content || "").split(/\r\n|\n|\r/g).length - 1;
29565
+ const rightNewlines = String(right.content || "").split(/\r\n|\n|\r/g).length - 1;
29566
+ return rightNewlines < leftNewlines ? right : left;
29567
+ }
29568
+ return rightComparable.length > leftComparable.length ? right : left;
29569
+ }
29570
+ function dedupeConsecutiveComparableCliMessages(messages) {
29571
+ const deduped = [];
29572
+ for (const message of messages) {
29573
+ const current = {
29574
+ ...message,
29575
+ content: typeof message.content === "string" ? message.content : String(message.content || "")
29576
+ };
29577
+ const previous = deduped[deduped.length - 1];
29578
+ if (!previous) {
29579
+ deduped.push(current);
29580
+ continue;
29581
+ }
29582
+ const previousComparable = normalizeComparableMessageContent(previous.content || "");
29583
+ const currentComparable = normalizeComparableMessageContent(current.content || "");
29584
+ const sameRole = previous.role === current.role;
29585
+ const sameKind = (previous.kind || "standard") === (current.kind || "standard");
29586
+ const sameSender = (previous.senderName || "") === (current.senderName || "");
29587
+ const comparableMatch = previousComparable && previousComparable === currentComparable;
29588
+ if (sameRole && sameKind && sameSender && comparableMatch) {
29589
+ deduped[deduped.length - 1] = chooseMoreComparableCliMessage(previous, current);
29590
+ continue;
29591
+ }
29592
+ deduped.push(current);
29593
+ }
29594
+ return deduped;
29595
+ }
29509
29596
  function normalizeCliParsedMessages(parsedMessages, options) {
29510
- return hydrateCliParsedMessages(parsedMessages, options).map((message) => ({
29597
+ return dedupeConsecutiveComparableCliMessages(hydrateCliParsedMessages(parsedMessages, options).map((message) => ({
29511
29598
  role: message.role,
29512
29599
  content: message.content,
29513
29600
  timestamp: message.timestamp,
@@ -29517,7 +29604,7 @@ var require_dist2 = __commonJS({
29517
29604
  index: message.index,
29518
29605
  meta: message.meta,
29519
29606
  senderName: message.senderName
29520
- }));
29607
+ })));
29521
29608
  }
29522
29609
  function buildCliParseInput(options) {
29523
29610
  const {
@@ -30177,7 +30264,7 @@ var require_dist2 = __commonJS({
30177
30264
  if (!hasStartupOutput) return;
30178
30265
  const stableMs = this.lastScreenChangeAt ? now - this.lastScreenChangeAt : 0;
30179
30266
  if (stableMs < 2e3) return;
30180
- const startupModal = this.getStartupConfirmationModal(screenText);
30267
+ const startupModal = this.runParseApproval(this.recentOutputBuffer);
30181
30268
  this.startupParseGate = false;
30182
30269
  if (this.startupSettleTimer) {
30183
30270
  clearTimeout(this.startupSettleTimer);
@@ -30234,11 +30321,17 @@ var require_dist2 = __commonJS({
30234
30321
  if (this.currentStatus !== "waiting_approval") return;
30235
30322
  const tail = this.recentOutputBuffer;
30236
30323
  const screenText = this.terminalScreen.getText() || "";
30237
- const startupModal = this.getStartupConfirmationModal(screenText);
30238
- const modal = this.runParseApproval(tail) || startupModal;
30324
+ const modal = this.runParseApproval(tail);
30239
30325
  const stillWaiting = this.runDetectStatus(tail) === "waiting_approval" || !!modal;
30240
30326
  if (stillWaiting) {
30241
- this.activeModal = modal || this.activeModal || { message: "Approval required", buttons: ["Allow", "Deny"] };
30327
+ if (!modal) {
30328
+ LOG2.warn("CLI", `[${this.cliType}] approval timeout check found no actionable modal; keeping approval state fail-closed`);
30329
+ this.activeModal = null;
30330
+ this.onStatusChange?.();
30331
+ this.armApprovalExitTimeout();
30332
+ return;
30333
+ }
30334
+ this.activeModal = modal;
30242
30335
  this.onStatusChange?.();
30243
30336
  this.armApprovalExitTimeout();
30244
30337
  return;
@@ -30250,81 +30343,12 @@ var require_dist2 = __commonJS({
30250
30343
  this.onStatusChange?.();
30251
30344
  }, 6e4);
30252
30345
  }
30253
- looksLikeVisibleIdlePrompt(screenText) {
30254
- const text = String(screenText || "");
30255
- if (!text.trim()) return false;
30256
- if (this.cliType === "codex-cli" && /(^|\n)\s*[❯›>]\s+(?:Find and fix a bug in @filename|Improve documentation in @filename|Use \/skills|Write tests for @filename|Explain this codebase|Summarize recent commits|Implement \{feature\}|Run \/review on my current changes)(?:\n|$)/im.test(text)) {
30257
- return true;
30258
- }
30259
- return /(^|\n)\s*[❯›>]\s*(?:\n|$)/m.test(text) || /⏎\s+send/i.test(text) || /\?\s*for\s*shortcuts/i.test(text) || /Type your message(?:\s+or\s+@path\/to\/file)?/i.test(text) || /workspace\s*\(\/directory\)/i.test(text) || /for\s*shortcuts/i.test(text);
30260
- }
30261
- findLastMatchingLineIndex(lines, predicate) {
30262
- for (let index = lines.length - 1; index >= 0; index -= 1) {
30263
- if (predicate(lines[index])) return index;
30264
- }
30265
- return -1;
30266
- }
30267
- looksLikeClaudeGeneratingLine(line) {
30268
- const trimmed = String(line || "").trim();
30269
- if (!trimmed) return false;
30270
- if (/^⏵⏵\s+accept edits on/i.test(trimmed)) return false;
30271
- if (/esc to (cancel|interrupt|stop)/i.test(trimmed)) return true;
30272
- if (/^[✻✶✳✢✽⠂⠐⠒⠓⠦⠴⠶⠷⠿]+\s+\S+.*\b(?:thinking|thought for \d+s?)\b/i.test(trimmed)) return true;
30273
- if (/^[✻✶✳✢✽⠂⠐⠒⠓⠦⠴⠶⠷⠿]+\s+[A-Z][A-Za-z-]{3,}ing\b.*(?:…|\.{3})/u.test(trimmed)) return true;
30274
- if (/^[⏺•]\s+(?:Reading|Writing|Editing|Searching|Inspecting|Planning|Analyzing|Synthesizing|Drafting|Running|Listing|Scanning|Matching)\b.*(?:…|\.{3})/i.test(trimmed)) {
30275
- return /ctrl\+o to expand/i.test(trimmed) || /\b\d+\s+(?:file|files|pattern|patterns|director(?:y|ies)|match|matches|result|results)\b/i.test(trimmed);
30276
- }
30277
- return false;
30278
- }
30279
- detectClaudeGeneratingOverride(screenText, tail) {
30280
- if (this.cliType !== "claude-cli") return false;
30281
- const source = sanitizeTerminalText(screenText || tail || "");
30282
- if (!source.trim()) return false;
30283
- const allLines = source.split(/\r\n|\n|\r/g).map((line) => line.trim()).filter(Boolean);
30284
- if (allLines.length === 0) return false;
30285
- const recentLines = allLines.slice(-12);
30286
- const promptIndex = this.findLastMatchingLineIndex(recentLines, (line) => /^[❯›>]\s*$/.test(line));
30287
- const activeRegion = promptIndex >= 0 ? recentLines.slice(Math.max(0, promptIndex - 2), promptIndex) : recentLines;
30288
- if (activeRegion.length === 0) return false;
30289
- return activeRegion.some((line) => this.looksLikeClaudeGeneratingLine(line));
30290
- }
30291
- refineDetectedStatus(status, tail, screenText) {
30292
- if (this.startupParseGate) {
30293
- return this.getStartupConfirmationModal(screenText || "") ? "waiting_approval" : "starting";
30294
- }
30295
- if (status === "waiting_approval") return status;
30296
- if (this.detectClaudeGeneratingOverride(screenText || "", tail)) return "generating";
30297
- return status;
30298
- }
30299
- looksLikeVisibleAssistantCandidate(screenText) {
30300
- const lines = sanitizeTerminalText(String(screenText || "")).split(/\r\n|\n|\r/g);
30301
- for (const line of lines) {
30302
- const trimmed = String(line || "").trim();
30303
- if (!trimmed) continue;
30304
- if (/^➜\s+\S+/.test(trimmed)) continue;
30305
- if (/^Update available!/i.test(trimmed)) continue;
30306
- if (/Claude Code v\d/i.test(trimmed)) continue;
30307
- if (/^⏵⏵\s+accept edits on/i.test(trimmed)) continue;
30308
- if (/^[◐◑◒◓◴◵◶◷◸◹◺◿].*\/effort/i.test(trimmed)) continue;
30309
- if (/^[✻✶✳✢✽⠂⠐⠒⠓⠦⠴⠶⠷⠿]+$/.test(trimmed)) continue;
30310
- if (/esc to (cancel|interrupt|stop)/i.test(trimmed)) continue;
30311
- const assistantMatch = trimmed.match(/^⏺\s+(.+)$/);
30312
- if (!assistantMatch) continue;
30313
- const content = assistantMatch[1].trim();
30314
- if (!content) continue;
30315
- if (/^(?:Bash|Read|Write|Edit|MultiEdit|Task|Glob|Grep|LS|NotebookEdit)\(/.test(content)) continue;
30316
- if (/This command requires approval|Do you want to proceed|Allow once|Always allow/i.test(content)) continue;
30317
- return true;
30318
- }
30319
- return false;
30320
- }
30321
30346
  shouldRetryFinishResponse(commitResult) {
30322
30347
  if (!this.currentTurnScope) return false;
30323
30348
  if (this.currentStatus === "waiting_approval" || this.activeModal) return false;
30324
30349
  if (this.finishRetryCount >= _ProviderCliAdapter.MAX_FINISH_RETRIES) return false;
30325
30350
  if (commitResult.hasAssistant && commitResult.assistantContent.trim()) return false;
30326
- const screenText = this.terminalScreen.getText() || "";
30327
- if (!this.looksLikeVisibleAssistantCandidate(screenText)) return false;
30351
+ if (this.runDetectStatus(this.recentOutputBuffer) !== "idle") return false;
30328
30352
  const now = Date.now();
30329
30353
  const quietForMs = this.lastNonEmptyOutputAt ? now - this.lastNonEmptyOutputAt : Number.MAX_SAFE_INTEGER;
30330
30354
  const screenStableMs = this.lastScreenChangeAt ? now - this.lastScreenChangeAt : 0;
@@ -30348,45 +30372,21 @@ var require_dist2 = __commonJS({
30348
30372
  }
30349
30373
  return false;
30350
30374
  }
30351
- getStartupConfirmationModal(screenText) {
30352
- const text = sanitizeTerminalText(String(screenText || ""));
30353
- if (!text.trim()) return null;
30354
- if (this.cliType === "claude-cli") {
30355
- const hasTrustPrompt = /Quick safety check/i.test(text) || /Is this a project you trust/i.test(text) || /Do you trust (?:this project|the contents of this directory|the files in this folder)/i.test(text);
30356
- const hasConfirmFooter = /Press Enter to (?:continue|confirm)/i.test(text) || /Enter to confirm/i.test(text) || /Esc to (?:cancel|exit)/i.test(text);
30357
- if (hasTrustPrompt || hasConfirmFooter && /trust/i.test(text)) {
30358
- return {
30359
- message: "Confirm Claude Code project trust",
30360
- buttons: ["Continue"]
30361
- };
30362
- }
30363
- }
30364
- return null;
30365
- }
30366
- shouldResolveModalWithEnter(modal, buttonIndex) {
30367
- if (!modal || buttonIndex !== 0) return false;
30368
- const buttons = Array.isArray(modal.buttons) ? modal.buttons : [];
30369
- if (buttons.length !== 1) return false;
30370
- const buttonLabel = String(buttons[0] || "").trim();
30371
- return looksLikeConfirmOnlyLabel(buttonLabel);
30372
- }
30373
30375
  async waitForInteractivePrompt(maxWaitMs = 5e3) {
30374
30376
  const startedAt = Date.now();
30375
30377
  let loggedWait = false;
30376
30378
  while (Date.now() - startedAt < maxWaitMs) {
30377
30379
  this.resolveStartupState("interactive_wait");
30378
30380
  const screenText = this.terminalScreen.getText() || "";
30379
- const hasPrompt = this.looksLikeVisibleIdlePrompt(screenText);
30380
30381
  const stableMs = this.lastScreenChangeAt ? Date.now() - this.lastScreenChangeAt : 0;
30381
30382
  const recentlyOutput = this.lastNonEmptyOutputAt ? Date.now() - this.lastNonEmptyOutputAt : Number.MAX_SAFE_INTEGER;
30382
30383
  const status = this.runDetectStatus(this.recentOutputBuffer) || this.currentStatus;
30383
- const startupLikelyActive = /Welcome back|Tips for getting|Recent activity|Claude Code v\d/i.test(screenText);
30384
- const interactiveReady = hasPrompt && stableMs >= 700 && recentlyOutput >= 350 && status !== "generating";
30384
+ const interactiveReady = status === "idle" && stableMs >= 700 && recentlyOutput >= 350;
30385
30385
  if (interactiveReady) {
30386
30386
  if (loggedWait) {
30387
30387
  LOG2.info(
30388
30388
  "CLI",
30389
- `[${this.cliType}] Interactive prompt ready after ${Date.now() - startedAt}ms (stableMs=${stableMs}, recentOutputMs=${recentlyOutput}, startup=${startupLikelyActive})`
30389
+ `[${this.cliType}] Interactive prompt ready after ${Date.now() - startedAt}ms (stableMs=${stableMs}, recentOutputMs=${recentlyOutput})`
30390
30390
  );
30391
30391
  }
30392
30392
  return;
@@ -30395,7 +30395,7 @@ var require_dist2 = __commonJS({
30395
30395
  loggedWait = true;
30396
30396
  LOG2.info(
30397
30397
  "CLI",
30398
- `[${this.cliType}] Waiting for interactive prompt: hasPrompt=${hasPrompt} stableMs=${stableMs} recentOutputMs=${recentlyOutput} status=${status} startup=${startupLikelyActive} screen=${JSON.stringify(summarizeCliTraceText(screenText, 220)).slice(0, 260)}`
30398
+ `[${this.cliType}] Waiting for interactive prompt: status=${status} stableMs=${stableMs} recentOutputMs=${recentlyOutput} screen=${JSON.stringify(summarizeCliTraceText(screenText, 220)).slice(0, 260)}`
30399
30399
  );
30400
30400
  }
30401
30401
  await new Promise((resolve12) => setTimeout(resolve12, 50));
@@ -30406,13 +30406,12 @@ var require_dist2 = __commonJS({
30406
30406
  `[${this.cliType}] Interactive prompt wait timed out after ${maxWaitMs}ms; proceeding with screen=${JSON.stringify(summarizeCliTraceText(finalScreenText, 240)).slice(0, 280)}`
30407
30407
  );
30408
30408
  }
30409
- clearStaleIdleResponseGuard(reason) {
30410
- const screenText = this.terminalScreen.getText() || "";
30411
- const visibleIdlePrompt = this.looksLikeVisibleIdlePrompt(screenText);
30412
- const blockingModal = this.activeModal || this.getStartupConfirmationModal(screenText);
30413
- if (!this.isWaitingForResponse || this.currentStatus !== "idle" || !visibleIdlePrompt || !!blockingModal) {
30414
- return false;
30415
- }
30409
+ trimLastAssistantEcho(messages, prompt) {
30410
+ if (!prompt) return;
30411
+ const last = [...messages].reverse().find((m) => m.role === "assistant" && typeof m.content === "string");
30412
+ if (last) last.content = trimPromptEchoPrefix(last.content, prompt);
30413
+ }
30414
+ clearAllTimers() {
30416
30415
  if (this.responseTimeout) {
30417
30416
  clearTimeout(this.responseTimeout);
30418
30417
  this.responseTimeout = null;
@@ -30425,10 +30424,38 @@ var require_dist2 = __commonJS({
30425
30424
  clearTimeout(this.approvalExitTimeout);
30426
30425
  this.approvalExitTimeout = null;
30427
30426
  }
30427
+ if (this.submitRetryTimer) {
30428
+ clearTimeout(this.submitRetryTimer);
30429
+ this.submitRetryTimer = null;
30430
+ }
30428
30431
  if (this.finishRetryTimer) {
30429
30432
  clearTimeout(this.finishRetryTimer);
30430
30433
  this.finishRetryTimer = null;
30431
30434
  }
30435
+ if (this.settleTimer) {
30436
+ clearTimeout(this.settleTimer);
30437
+ this.settleTimer = null;
30438
+ }
30439
+ if (this.pendingScriptStatusTimer) {
30440
+ clearTimeout(this.pendingScriptStatusTimer);
30441
+ this.pendingScriptStatusTimer = null;
30442
+ }
30443
+ if (this.pendingOutputParseTimer) {
30444
+ clearTimeout(this.pendingOutputParseTimer);
30445
+ this.pendingOutputParseTimer = null;
30446
+ }
30447
+ if (this.ptyOutputFlushTimer) {
30448
+ clearTimeout(this.ptyOutputFlushTimer);
30449
+ this.ptyOutputFlushTimer = null;
30450
+ }
30451
+ }
30452
+ clearStaleIdleResponseGuard(reason) {
30453
+ const blockingModal = this.activeModal || this.runParseApproval(this.recentOutputBuffer);
30454
+ const isIdle = this.runDetectStatus(this.recentOutputBuffer) === "idle";
30455
+ if (!this.isWaitingForResponse || this.currentStatus !== "idle" || !isIdle || !!blockingModal) {
30456
+ return false;
30457
+ }
30458
+ this.clearAllTimers();
30432
30459
  this.clearIdleFinishCandidate(reason);
30433
30460
  this.responseBuffer = "";
30434
30461
  this.isWaitingForResponse = false;
@@ -30438,10 +30465,7 @@ var require_dist2 = __commonJS({
30438
30465
  this.finishRetryCount = 0;
30439
30466
  this.currentTurnScope = null;
30440
30467
  this.activeModal = null;
30441
- this.recordTrace("stale_idle_response_cleared", {
30442
- reason,
30443
- screenText: summarizeCliTraceText(screenText, 240)
30444
- });
30468
+ this.recordTrace("stale_idle_response_cleared", { reason });
30445
30469
  return true;
30446
30470
  }
30447
30471
  hasMeaningfulResponseBuffer(promptSnippet) {
@@ -30476,16 +30500,14 @@ var require_dist2 = __commonJS({
30476
30500
  if (this.startupParseGate) {
30477
30501
  return;
30478
30502
  }
30479
- const startupModal = this.getStartupConfirmationModal(screenText);
30480
30503
  const parsedTranscript = this.parseCurrentTranscript(
30481
30504
  this.committedMessages,
30482
30505
  this.responseBuffer,
30483
30506
  this.currentTurnScope
30484
30507
  );
30485
30508
  const parsedModal = parsedTranscript?.activeModal && Array.isArray(parsedTranscript.activeModal.buttons) && parsedTranscript.activeModal.buttons.some((button) => typeof button === "string" && button.trim()) ? parsedTranscript.activeModal : null;
30486
- const modal = this.runParseApproval(tail) || parsedModal || startupModal;
30487
- const rawScriptStatus = this.runDetectStatus(tail);
30488
- const scriptStatus = startupModal ? "waiting_approval" : parsedModal && parsedTranscript?.status === "waiting_approval" ? "waiting_approval" : rawScriptStatus;
30509
+ const modal = this.runParseApproval(tail) || parsedModal;
30510
+ const scriptStatus = this.runDetectStatus(tail);
30489
30511
  const parsedMessages = Array.isArray(parsedTranscript?.messages) ? normalizeCliParsedMessages(parsedTranscript.messages, {
30490
30512
  committedMessages: this.committedMessages,
30491
30513
  scope: this.currentTurnScope,
@@ -30540,15 +30562,44 @@ var require_dist2 = __commonJS({
30540
30562
  }
30541
30563
  if (!scriptStatus) return;
30542
30564
  const prevStatus = this.currentStatus;
30543
- const clearPendingScriptStatus = () => {
30565
+ const ctx = { now, screenText, modal, scriptStatus, parsedTranscript, parsedMessages, lastParsedAssistant, parsedShowsLiveAssistantProgress, prevStatus };
30566
+ if (!this.applyPendingScriptStatusDebounce(ctx)) return;
30567
+ const recentInteractiveActivity = this.hasRecentInteractiveActivity(now);
30568
+ LOG2.info(
30569
+ "CLI",
30570
+ `[${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)} responseBuffer=${JSON.stringify(summarizeCliTraceText(this.responseBuffer, 160)).slice(0, 220)} screen=${JSON.stringify(summarizeCliTraceText(screenText, 160)).slice(0, 220)}`
30571
+ );
30572
+ const shouldHoldGenerating = scriptStatus === "idle" && this.isWaitingForResponse && !modal && recentInteractiveActivity && !(parsedTranscript?.status === "idle" && !!lastParsedAssistant);
30573
+ if (shouldHoldGenerating) {
30574
+ this.applyHoldGenerating(ctx, recentInteractiveActivity);
30575
+ return;
30576
+ }
30577
+ if (scriptStatus === "waiting_approval") {
30578
+ this.applyWaitingApproval(ctx);
30579
+ return;
30580
+ }
30581
+ if (scriptStatus === "generating") {
30582
+ this.applyGenerating(ctx);
30583
+ return;
30584
+ }
30585
+ if (scriptStatus === "idle") {
30586
+ this.applyIdle(ctx, now);
30587
+ }
30588
+ }
30589
+ // Returns false if the caller should bail out (debounce pending).
30590
+ applyPendingScriptStatusDebounce(ctx) {
30591
+ const { now, scriptStatus, prevStatus } = ctx;
30592
+ const shouldDebounce = prevStatus === "idle" && !this.isWaitingForResponse && !this.currentTurnScope && (scriptStatus === "generating" || scriptStatus === "waiting_approval");
30593
+ if (!shouldDebounce) {
30544
30594
  this.pendingScriptStatus = null;
30545
30595
  this.pendingScriptStatusSince = 0;
30546
30596
  if (this.pendingScriptStatusTimer) {
30547
30597
  clearTimeout(this.pendingScriptStatusTimer);
30548
30598
  this.pendingScriptStatusTimer = null;
30549
30599
  }
30550
- };
30551
- const armPendingScriptStatus = (delayMs) => {
30600
+ return true;
30601
+ }
30602
+ const armPending = (delayMs) => {
30552
30603
  if (this.pendingScriptStatusTimer) clearTimeout(this.pendingScriptStatusTimer);
30553
30604
  this.pendingScriptStatusTimer = setTimeout(() => {
30554
30605
  this.pendingScriptStatusTimer = null;
@@ -30556,200 +30607,187 @@ var require_dist2 = __commonJS({
30556
30607
  this.evaluateSettled();
30557
30608
  }, delayMs);
30558
30609
  };
30559
- const shouldDebouncePromotion = (status) => prevStatus === "idle" && !this.isWaitingForResponse && !this.currentTurnScope && (status === "generating" || status === "waiting_approval");
30560
- if (shouldDebouncePromotion(scriptStatus)) {
30561
- if (this.pendingScriptStatus !== scriptStatus) {
30562
- this.pendingScriptStatus = scriptStatus;
30563
- this.pendingScriptStatusSince = now;
30564
- armPendingScriptStatus(_ProviderCliAdapter.SCRIPT_STATUS_DEBOUNCE_MS);
30565
- return;
30566
- }
30567
- const elapsed = now - this.pendingScriptStatusSince;
30568
- if (elapsed < _ProviderCliAdapter.SCRIPT_STATUS_DEBOUNCE_MS) {
30569
- armPendingScriptStatus(_ProviderCliAdapter.SCRIPT_STATUS_DEBOUNCE_MS - elapsed);
30570
- return;
30571
- }
30572
- } else {
30573
- clearPendingScriptStatus();
30574
- }
30575
- const recentInteractiveActivity = this.hasRecentInteractiveActivity(now);
30576
- const statusActivityHoldMs = this.getStatusActivityHoldMs();
30577
- const visibleIdlePrompt = this.looksLikeVisibleIdlePrompt(screenText);
30578
- const visibleAssistantCandidate = this.looksLikeVisibleAssistantCandidate(screenText);
30579
- if (this.currentTurnScope && this.cliType === "claude-cli") {
30580
- LOG2.info(
30581
- "CLI",
30582
- `[${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)}`
30583
- );
30610
+ if (this.pendingScriptStatus !== scriptStatus) {
30611
+ this.pendingScriptStatus = scriptStatus;
30612
+ this.pendingScriptStatusSince = now;
30613
+ armPending(_ProviderCliAdapter.SCRIPT_STATUS_DEBOUNCE_MS);
30614
+ return false;
30584
30615
  }
30585
- const shouldHoldGenerating = scriptStatus === "idle" && this.isWaitingForResponse && !modal && recentInteractiveActivity && !(visibleIdlePrompt && visibleAssistantCandidate) && !(parsedTranscript?.status === "idle" && !!lastParsedAssistant);
30586
- if (shouldHoldGenerating) {
30587
- this.clearIdleFinishCandidate("hold_generating_recent_activity");
30588
- this.setStatus("generating", "recent_activity_hold");
30589
- if (this.idleTimeout) clearTimeout(this.idleTimeout);
30590
- this.idleTimeout = setTimeout(() => {
30591
- if (this.isWaitingForResponse && this.currentStatus !== "waiting_approval") {
30592
- if (this.shouldDeferIdleTimeoutFinish()) return;
30593
- this.finishResponse();
30594
- }
30595
- }, this.timeouts.generatingIdle);
30596
- this.recordTrace("hold_generating_recent_activity", {
30597
- scriptStatus,
30598
- recentInteractiveActivity,
30599
- lastNonEmptyOutputAt: this.lastNonEmptyOutputAt,
30600
- lastScreenChangeAt: this.lastScreenChangeAt,
30601
- holdMs: statusActivityHoldMs,
30602
- ...buildCliTraceParseSnapshot({
30603
- accumulatedBuffer: this.accumulatedBuffer,
30604
- accumulatedRawBuffer: this.accumulatedRawBuffer,
30605
- responseBuffer: this.responseBuffer,
30606
- partialResponse: this.responseBuffer,
30607
- scope: this.currentTurnScope
30608
- })
30609
- });
30610
- this.onStatusChange?.();
30611
- return;
30616
+ const elapsed = now - this.pendingScriptStatusSince;
30617
+ if (elapsed < _ProviderCliAdapter.SCRIPT_STATUS_DEBOUNCE_MS) {
30618
+ armPending(_ProviderCliAdapter.SCRIPT_STATUS_DEBOUNCE_MS - elapsed);
30619
+ return false;
30612
30620
  }
30613
- if (scriptStatus === "waiting_approval") {
30614
- this.clearIdleFinishCandidate("waiting_approval");
30615
- const inCooldown = this.lastApprovalResolvedAt && Date.now() - this.lastApprovalResolvedAt < this.timeouts.approvalCooldown;
30616
- const visibleIdlePrompt2 = this.looksLikeVisibleIdlePrompt(screenText);
30617
- if ((inCooldown || visibleIdlePrompt2) && !modal) {
30618
- if (this.approvalExitTimeout) {
30619
- clearTimeout(this.approvalExitTimeout);
30620
- this.approvalExitTimeout = null;
30621
- }
30622
- this.activeModal = null;
30623
- if (this.isWaitingForResponse) {
30624
- this.setStatus("generating", inCooldown ? "approval_cooldown_ignore" : "approval_prompt_gone");
30625
- if (this.idleTimeout) clearTimeout(this.idleTimeout);
30626
- this.idleTimeout = setTimeout(() => {
30627
- if (this.isWaitingForResponse && this.currentStatus !== "waiting_approval") {
30628
- if (this.shouldDeferIdleTimeoutFinish()) return;
30629
- this.finishResponse();
30630
- }
30631
- }, this.timeouts.generatingIdle);
30632
- } else {
30633
- this.setStatus("idle", inCooldown ? "approval_cooldown_ignore" : "approval_prompt_gone");
30634
- }
30635
- this.onStatusChange?.();
30636
- return;
30621
+ return true;
30622
+ }
30623
+ applyHoldGenerating(ctx, recentInteractiveActivity) {
30624
+ const { scriptStatus } = ctx;
30625
+ this.clearIdleFinishCandidate("hold_generating_recent_activity");
30626
+ this.setStatus("generating", "recent_activity_hold");
30627
+ if (this.idleTimeout) clearTimeout(this.idleTimeout);
30628
+ this.idleTimeout = setTimeout(() => {
30629
+ if (this.isWaitingForResponse && this.currentStatus !== "waiting_approval") {
30630
+ if (this.shouldDeferIdleTimeoutFinish()) return;
30631
+ this.finishResponse();
30637
30632
  }
30638
- if (!inCooldown) {
30639
- this.isWaitingForResponse = true;
30640
- this.setStatus("waiting_approval", "script_detect");
30641
- this.activeModal = modal || { message: "Approval required", buttons: ["Allow", "Deny"] };
30633
+ }, this.timeouts.generatingIdle);
30634
+ this.recordTrace("hold_generating_recent_activity", {
30635
+ scriptStatus,
30636
+ recentInteractiveActivity,
30637
+ lastNonEmptyOutputAt: this.lastNonEmptyOutputAt,
30638
+ lastScreenChangeAt: this.lastScreenChangeAt,
30639
+ holdMs: this.getStatusActivityHoldMs(),
30640
+ ...buildCliTraceParseSnapshot({
30641
+ accumulatedBuffer: this.accumulatedBuffer,
30642
+ accumulatedRawBuffer: this.accumulatedRawBuffer,
30643
+ responseBuffer: this.responseBuffer,
30644
+ partialResponse: this.responseBuffer,
30645
+ scope: this.currentTurnScope
30646
+ })
30647
+ });
30648
+ this.onStatusChange?.();
30649
+ }
30650
+ applyWaitingApproval(ctx) {
30651
+ const { modal } = ctx;
30652
+ this.clearIdleFinishCandidate("waiting_approval");
30653
+ const inCooldown = this.lastApprovalResolvedAt && Date.now() - this.lastApprovalResolvedAt < this.timeouts.approvalCooldown;
30654
+ if (inCooldown && !modal) {
30655
+ if (this.approvalExitTimeout) {
30656
+ clearTimeout(this.approvalExitTimeout);
30657
+ this.approvalExitTimeout = null;
30658
+ }
30659
+ this.activeModal = null;
30660
+ if (this.isWaitingForResponse) {
30661
+ this.setStatus("generating", inCooldown ? "approval_cooldown_ignore" : "approval_prompt_gone");
30642
30662
  if (this.idleTimeout) clearTimeout(this.idleTimeout);
30643
- this.armApprovalExitTimeout();
30644
- this.onStatusChange?.();
30645
- return;
30663
+ this.idleTimeout = setTimeout(() => {
30664
+ if (this.isWaitingForResponse && this.currentStatus !== "waiting_approval") {
30665
+ if (this.shouldDeferIdleTimeoutFinish()) return;
30666
+ this.finishResponse();
30667
+ }
30668
+ }, this.timeouts.generatingIdle);
30669
+ } else {
30670
+ this.setStatus("idle", inCooldown ? "approval_cooldown_ignore" : "approval_prompt_gone");
30646
30671
  }
30672
+ this.onStatusChange?.();
30673
+ return;
30647
30674
  }
30648
- if (scriptStatus === "generating") {
30649
- this.clearIdleFinishCandidate("generating");
30650
- const effectiveScreenText = screenText || this.accumulatedBuffer;
30651
- const noActiveTurn = !this.currentTurnScope;
30652
- const looksIdleChrome = /(^|\n)\s*[❯›>]\s*(?:\n|$)/m.test(effectiveScreenText) || /accept edits on/i.test(effectiveScreenText) && (/Update available!/i.test(screenText) || /\/effort/i.test(screenText) || /^.*➜\s+\S+/m.test(effectiveScreenText));
30653
- if (prevStatus === "idle" && !this.isWaitingForResponse && noActiveTurn && !modal && looksIdleChrome && !parsedShowsLiveAssistantProgress) {
30675
+ if (!inCooldown) {
30676
+ if (!modal) {
30677
+ LOG2.warn("CLI", `[${this.cliType}] detectStatus reported waiting_approval without parseApproval modal; ignoring non-actionable approval state`);
30654
30678
  return;
30655
30679
  }
30656
- if (prevStatus === "waiting_approval") {
30657
- if (this.approvalExitTimeout) {
30658
- clearTimeout(this.approvalExitTimeout);
30659
- this.approvalExitTimeout = null;
30660
- }
30661
- this.activeModal = null;
30662
- this.lastApprovalResolvedAt = Date.now();
30663
- }
30664
- if (!this.isWaitingForResponse) {
30665
- this.isWaitingForResponse = true;
30666
- this.responseBuffer = "";
30667
- }
30668
- this.setStatus("generating", "script_detect");
30680
+ this.isWaitingForResponse = true;
30681
+ this.setStatus("waiting_approval", "script_detect");
30682
+ this.activeModal = modal;
30669
30683
  if (this.idleTimeout) clearTimeout(this.idleTimeout);
30670
- this.idleTimeout = setTimeout(() => {
30671
- if (this.isWaitingForResponse) {
30672
- if (this.shouldDeferIdleTimeoutFinish()) return;
30673
- this.finishResponse();
30674
- }
30675
- }, this.timeouts.generatingIdle);
30684
+ this.armApprovalExitTimeout();
30676
30685
  this.onStatusChange?.();
30686
+ }
30687
+ }
30688
+ applyGenerating(ctx) {
30689
+ const { screenText, modal, parsedShowsLiveAssistantProgress, prevStatus } = ctx;
30690
+ this.clearIdleFinishCandidate("generating");
30691
+ const effectiveScreenText = screenText || this.accumulatedBuffer;
30692
+ const noActiveTurn = !this.currentTurnScope;
30693
+ const looksIdleChrome = /(^|\n)\s*[❯›>]\s*(?:\n|$)/m.test(effectiveScreenText) || /accept edits on/i.test(effectiveScreenText) && (/Update available!/i.test(screenText) || /\/effort/i.test(screenText) || /^.*➜\s+\S+/m.test(effectiveScreenText));
30694
+ if (prevStatus === "idle" && !this.isWaitingForResponse && noActiveTurn && !modal && looksIdleChrome && !parsedShowsLiveAssistantProgress) {
30677
30695
  return;
30678
30696
  }
30679
- if (scriptStatus === "idle") {
30680
- if (prevStatus === "waiting_approval") {
30681
- if (this.approvalExitTimeout) {
30682
- clearTimeout(this.approvalExitTimeout);
30683
- this.approvalExitTimeout = null;
30684
- }
30685
- this.activeModal = null;
30686
- this.lastApprovalResolvedAt = Date.now();
30697
+ if (prevStatus === "waiting_approval") {
30698
+ if (this.approvalExitTimeout) {
30699
+ clearTimeout(this.approvalExitTimeout);
30700
+ this.approvalExitTimeout = null;
30687
30701
  }
30702
+ this.activeModal = null;
30703
+ this.lastApprovalResolvedAt = Date.now();
30704
+ }
30705
+ if (!this.isWaitingForResponse) {
30706
+ this.isWaitingForResponse = true;
30707
+ this.responseBuffer = "";
30708
+ }
30709
+ this.setStatus("generating", "script_detect");
30710
+ if (this.idleTimeout) clearTimeout(this.idleTimeout);
30711
+ this.idleTimeout = setTimeout(() => {
30688
30712
  if (this.isWaitingForResponse) {
30689
- const visibleIdlePrompt2 = this.looksLikeVisibleIdlePrompt(screenText);
30690
- const quietForMs = this.lastNonEmptyOutputAt ? now - this.lastNonEmptyOutputAt : Number.MAX_SAFE_INTEGER;
30691
- const screenStableMs = this.lastScreenChangeAt ? now - this.lastScreenChangeAt : 0;
30692
- const hasAssistantTurn = !!lastParsedAssistant;
30693
- const assistantLength = lastParsedAssistant?.content?.length || 0;
30694
- const idleFinishConfirmMs = this.getIdleFinishConfirmMs();
30695
- const idleQuietThresholdMs = Math.max(idleFinishConfirmMs, this.timeouts.outputSettle);
30696
- const idleStableThresholdMs = idleFinishConfirmMs;
30697
- const idleReady = visibleIdlePrompt2 && !modal && hasAssistantTurn && quietForMs >= idleQuietThresholdMs && screenStableMs >= idleStableThresholdMs;
30698
- const candidate = this.idleFinishCandidate;
30699
- const candidateQuiet = !!candidate && candidate.responseEpoch === this.responseEpoch && candidate.lastOutputAt === this.lastOutputAt && candidate.lastScreenChangeAt === this.lastScreenChangeAt && assistantLength >= candidate.assistantLength && now - candidate.armedAt >= idleFinishConfirmMs;
30700
- const canFinishImmediately = idleReady && candidateQuiet;
30701
- this.recordTrace("idle_decision", {
30702
- visibleIdlePrompt: visibleIdlePrompt2,
30703
- quietForMs,
30704
- screenStableMs,
30705
- hasAssistantTurn,
30706
- assistantLength,
30707
- hasModal: !!modal,
30708
- idleQuietThresholdMs,
30709
- idleStableThresholdMs,
30710
- idleReady,
30711
- idleFinishConfirmMs,
30712
- idleFinishCandidate: candidate,
30713
- candidateQuiet,
30714
- canFinishImmediately,
30715
- submitPendingUntil: this.submitPendingUntil,
30716
- responseSettleIgnoreUntil: this.responseSettleIgnoreUntil,
30717
- ...buildCliTraceParseSnapshot({
30718
- accumulatedBuffer: this.accumulatedBuffer,
30719
- accumulatedRawBuffer: this.accumulatedRawBuffer,
30720
- responseBuffer: this.responseBuffer,
30721
- partialResponse: this.responseBuffer,
30722
- scope: this.currentTurnScope
30723
- })
30724
- });
30725
- if (canFinishImmediately) {
30726
- this.clearIdleFinishCandidate("finish_response");
30727
- if (this.idleTimeout) clearTimeout(this.idleTimeout);
30728
- this.finishResponse();
30729
- return;
30730
- }
30731
- if (idleReady) {
30732
- if (!candidate) {
30733
- this.armIdleFinishCandidate(assistantLength);
30734
- return;
30735
- }
30736
- } else {
30737
- this.clearIdleFinishCandidate("idle_not_ready");
30738
- }
30739
- if (this.idleTimeout) clearTimeout(this.idleTimeout);
30740
- this.idleTimeout = setTimeout(() => {
30741
- if (this.isWaitingForResponse && this.currentStatus !== "waiting_approval") {
30742
- if (this.shouldDeferIdleTimeoutFinish()) return;
30743
- this.clearIdleFinishCandidate("idle_timeout_finish");
30744
- this.finishResponse();
30745
- }
30746
- }, this.timeouts.idleFinish);
30747
- } else if (prevStatus !== "idle") {
30713
+ if (this.shouldDeferIdleTimeoutFinish()) return;
30714
+ this.finishResponse();
30715
+ }
30716
+ }, this.timeouts.generatingIdle);
30717
+ this.onStatusChange?.();
30718
+ }
30719
+ applyIdle(ctx, now) {
30720
+ const { screenText, modal, lastParsedAssistant, prevStatus } = ctx;
30721
+ if (prevStatus === "waiting_approval") {
30722
+ if (this.approvalExitTimeout) {
30723
+ clearTimeout(this.approvalExitTimeout);
30724
+ this.approvalExitTimeout = null;
30725
+ }
30726
+ this.activeModal = null;
30727
+ this.lastApprovalResolvedAt = Date.now();
30728
+ }
30729
+ if (!this.isWaitingForResponse) {
30730
+ if (prevStatus !== "idle") {
30748
30731
  this.clearIdleFinishCandidate("idle_without_response");
30749
30732
  this.setStatus("idle", "script_detect");
30750
30733
  this.onStatusChange?.();
30751
30734
  }
30735
+ return;
30752
30736
  }
30737
+ const quietForMs = this.lastNonEmptyOutputAt ? now - this.lastNonEmptyOutputAt : Number.MAX_SAFE_INTEGER;
30738
+ const screenStableMs = this.lastScreenChangeAt ? now - this.lastScreenChangeAt : 0;
30739
+ const hasAssistantTurn = !!lastParsedAssistant;
30740
+ const assistantLength = lastParsedAssistant?.content?.length || 0;
30741
+ const idleFinishConfirmMs = this.getIdleFinishConfirmMs();
30742
+ const idleQuietThresholdMs = Math.max(idleFinishConfirmMs, this.timeouts.outputSettle);
30743
+ const idleReady = !modal && hasAssistantTurn && quietForMs >= idleQuietThresholdMs && screenStableMs >= idleFinishConfirmMs;
30744
+ const candidate = this.idleFinishCandidate;
30745
+ const candidateQuiet = !!candidate && candidate.responseEpoch === this.responseEpoch && candidate.lastOutputAt === this.lastOutputAt && candidate.lastScreenChangeAt === this.lastScreenChangeAt && assistantLength >= candidate.assistantLength && now - candidate.armedAt >= idleFinishConfirmMs;
30746
+ this.recordTrace("idle_decision", {
30747
+ quietForMs,
30748
+ screenStableMs,
30749
+ hasAssistantTurn,
30750
+ assistantLength,
30751
+ hasModal: !!modal,
30752
+ idleQuietThresholdMs,
30753
+ idleStableThresholdMs: idleFinishConfirmMs,
30754
+ idleReady,
30755
+ idleFinishConfirmMs,
30756
+ idleFinishCandidate: candidate,
30757
+ candidateQuiet,
30758
+ canFinishImmediately: idleReady && candidateQuiet,
30759
+ submitPendingUntil: this.submitPendingUntil,
30760
+ responseSettleIgnoreUntil: this.responseSettleIgnoreUntil,
30761
+ ...buildCliTraceParseSnapshot({
30762
+ accumulatedBuffer: this.accumulatedBuffer,
30763
+ accumulatedRawBuffer: this.accumulatedRawBuffer,
30764
+ responseBuffer: this.responseBuffer,
30765
+ partialResponse: this.responseBuffer,
30766
+ scope: this.currentTurnScope
30767
+ })
30768
+ });
30769
+ if (idleReady && candidateQuiet) {
30770
+ this.clearIdleFinishCandidate("finish_response");
30771
+ if (this.idleTimeout) clearTimeout(this.idleTimeout);
30772
+ this.finishResponse();
30773
+ return;
30774
+ }
30775
+ if (idleReady) {
30776
+ if (!candidate) {
30777
+ this.armIdleFinishCandidate(assistantLength);
30778
+ return;
30779
+ }
30780
+ } else {
30781
+ this.clearIdleFinishCandidate("idle_not_ready");
30782
+ }
30783
+ if (this.idleTimeout) clearTimeout(this.idleTimeout);
30784
+ this.idleTimeout = setTimeout(() => {
30785
+ if (this.isWaitingForResponse && this.currentStatus !== "waiting_approval") {
30786
+ if (this.shouldDeferIdleTimeoutFinish()) return;
30787
+ this.clearIdleFinishCandidate("idle_timeout_finish");
30788
+ this.finishResponse();
30789
+ }
30790
+ }, this.timeouts.idleFinish);
30753
30791
  }
30754
30792
  finishResponse() {
30755
30793
  if (this.submitPendingUntil > Date.now()) return;
@@ -30788,26 +30826,7 @@ var require_dist2 = __commonJS({
30788
30826
  }, _ProviderCliAdapter.FINISH_RETRY_DELAY_MS);
30789
30827
  return;
30790
30828
  }
30791
- if (this.responseTimeout) {
30792
- clearTimeout(this.responseTimeout);
30793
- this.responseTimeout = null;
30794
- }
30795
- if (this.idleTimeout) {
30796
- clearTimeout(this.idleTimeout);
30797
- this.idleTimeout = null;
30798
- }
30799
- if (this.approvalExitTimeout) {
30800
- clearTimeout(this.approvalExitTimeout);
30801
- this.approvalExitTimeout = null;
30802
- }
30803
- if (this.submitRetryTimer) {
30804
- clearTimeout(this.submitRetryTimer);
30805
- this.submitRetryTimer = null;
30806
- }
30807
- if (this.finishRetryTimer) {
30808
- clearTimeout(this.finishRetryTimer);
30809
- this.finishRetryTimer = null;
30810
- }
30829
+ this.clearAllTimers();
30811
30830
  this.responseBuffer = "";
30812
30831
  this.isWaitingForResponse = false;
30813
30832
  this.responseSettleIgnoreUntil = 0;
@@ -30819,18 +30838,12 @@ var require_dist2 = __commonJS({
30819
30838
  this.setStatus("idle", "response_finished");
30820
30839
  this.onStatusChange?.();
30821
30840
  }
30822
- maybeCommitVisibleIdleTranscript(parsed, options) {
30841
+ maybeCommitVisibleIdleTranscript(parsed) {
30823
30842
  const allowImmediateScriptIdleCommit = this.provider.allowInputDuringGeneration === true;
30824
30843
  if (!allowImmediateScriptIdleCommit) return false;
30825
30844
  if (!parsed || !Array.isArray(parsed.messages) || parsed.status !== "idle" || !this.isWaitingForResponse || !this.currentTurnScope || this.activeModal || parsed.activeModal) {
30826
30845
  return false;
30827
30846
  }
30828
- if (options?.requireVisibleAssistantCandidate) {
30829
- const candidateText = options.screenText || this.terminalScreen.getText() || "";
30830
- if (!this.looksLikeVisibleAssistantCandidate(candidateText)) {
30831
- return false;
30832
- }
30833
- }
30834
30847
  const hydratedForIdleCommit = normalizeCliParsedMessages(parsed.messages, {
30835
30848
  committedMessages: this.committedMessages,
30836
30849
  scope: this.currentTurnScope,
@@ -30839,33 +30852,8 @@ var require_dist2 = __commonJS({
30839
30852
  const visibleAssistant = [...hydratedForIdleCommit].reverse().find((message) => message.role === "assistant" && message.content.trim());
30840
30853
  if (!visibleAssistant) return false;
30841
30854
  this.committedMessages = hydratedForIdleCommit;
30842
- const promptForTrim = this.currentTurnScope?.prompt || getLastUserPromptText(this.committedMessages);
30843
- if (promptForTrim) {
30844
- const lastAssistantForTrim = [...this.committedMessages].reverse().find((message) => message.role === "assistant");
30845
- if (lastAssistantForTrim) {
30846
- lastAssistantForTrim.content = trimPromptEchoPrefix(lastAssistantForTrim.content, promptForTrim);
30847
- }
30848
- }
30849
- if (this.responseTimeout) {
30850
- clearTimeout(this.responseTimeout);
30851
- this.responseTimeout = null;
30852
- }
30853
- if (this.idleTimeout) {
30854
- clearTimeout(this.idleTimeout);
30855
- this.idleTimeout = null;
30856
- }
30857
- if (this.approvalExitTimeout) {
30858
- clearTimeout(this.approvalExitTimeout);
30859
- this.approvalExitTimeout = null;
30860
- }
30861
- if (this.submitRetryTimer) {
30862
- clearTimeout(this.submitRetryTimer);
30863
- this.submitRetryTimer = null;
30864
- }
30865
- if (this.finishRetryTimer) {
30866
- clearTimeout(this.finishRetryTimer);
30867
- this.finishRetryTimer = null;
30868
- }
30855
+ this.trimLastAssistantEcho(this.committedMessages, this.currentTurnScope?.prompt || getLastUserPromptText(this.committedMessages));
30856
+ this.clearAllTimers();
30869
30857
  this.syncMessageViews();
30870
30858
  this.responseBuffer = "";
30871
30859
  this.isWaitingForResponse = false;
@@ -30895,13 +30883,7 @@ var require_dist2 = __commonJS({
30895
30883
  scope: this.currentTurnScope,
30896
30884
  lastOutputAt: this.lastOutputAt
30897
30885
  });
30898
- const promptForTrim = this.currentTurnScope?.prompt || getLastUserPromptText(this.committedMessages);
30899
- if (promptForTrim) {
30900
- const lastAssistantForTrim = [...this.committedMessages].reverse().find((message) => message.role === "assistant");
30901
- if (lastAssistantForTrim) {
30902
- lastAssistantForTrim.content = trimPromptEchoPrefix(lastAssistantForTrim.content, promptForTrim);
30903
- }
30904
- }
30886
+ this.trimLastAssistantEcho(this.committedMessages, this.currentTurnScope?.prompt || getLastUserPromptText(this.committedMessages));
30905
30887
  this.syncMessageViews();
30906
30888
  const lastAssistant = [...this.committedMessages].reverse().find((message) => message.role === "assistant");
30907
30889
  if (this.currentTurnScope) {
@@ -30959,7 +30941,7 @@ var require_dist2 = __commonJS({
30959
30941
  screen: buildCliScreenSnapshot(screenText),
30960
30942
  tailScreen: buildCliScreenSnapshot(text.slice(-500))
30961
30943
  });
30962
- return this.refineDetectedStatus(status, text, screenText || "");
30944
+ return status;
30963
30945
  } catch (e) {
30964
30946
  LOG2.warn("CLI", `[${this.cliType}] detectStatus error: ${e.message}`);
30965
30947
  return null;
@@ -30999,23 +30981,21 @@ var require_dist2 = __commonJS({
30999
30981
  if (!inApprovalCooldown) {
31000
30982
  return parsed;
31001
30983
  }
31002
- const startupModal = this.getStartupConfirmationModal(screenText || "");
31003
- const visibleModal = this.runParseApproval(recentBuffer) || startupModal;
30984
+ const visibleModal = this.runParseApproval(recentBuffer);
31004
30985
  if (visibleModal) {
31005
30986
  return parsed;
31006
30987
  }
31007
30988
  const detectedStatus = this.runDetectStatus(recentBuffer);
31008
- const fallbackStatus = detectedStatus && detectedStatus !== "waiting_approval" ? detectedStatus : this.isWaitingForResponse || this.currentTurnScope ? "generating" : this.currentStatus === "waiting_approval" ? "idle" : this.currentStatus;
30989
+ const resolvedStatus = detectedStatus && detectedStatus !== "waiting_approval" ? detectedStatus : this.isWaitingForResponse || this.currentTurnScope ? "generating" : this.currentStatus === "waiting_approval" ? "idle" : this.currentStatus;
31009
30990
  return {
31010
30991
  ...parsed,
31011
- status: fallbackStatus,
30992
+ status: resolvedStatus,
31012
30993
  activeModal: null
31013
30994
  };
31014
30995
  }
31015
30996
  // ─── Public API (CliAdapter) ───────────────────
31016
30997
  getStatus() {
31017
- const screenText = this.terminalScreen.getText() || "";
31018
- const startupModal = this.startupParseGate ? this.getStartupConfirmationModal(screenText) : null;
30998
+ const startupModal = this.startupParseGate ? this.runParseApproval(this.recentOutputBuffer) : null;
31019
30999
  let effectiveStatus = this.projectEffectiveStatus(startupModal);
31020
31000
  let effectiveModal = startupModal || this.activeModal;
31021
31001
  if (!startupModal && !effectiveModal && typeof this.cliScripts?.parseOutput === "function") {
@@ -31096,8 +31076,7 @@ var require_dist2 = __commonJS({
31096
31076
  receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
31097
31077
  }));
31098
31078
  const parsedLastAssistant = [...parsedHydratedMessages].reverse().find((message) => message.role === "assistant" && typeof message.content === "string" && message.content.trim());
31099
- const visibleIdlePrompt = this.looksLikeVisibleIdlePrompt(screenText);
31100
- const shouldAdoptParsedIdleReplay = !this.currentTurnScope && !this.activeModal && !!parsedLastAssistant && parsedTranscriptIsRicherThanCommitted(parsedHydratedMessages, committedHydratedMessages) && (this.currentStatus === "idle" || this.currentStatus === "generating" && this.isWaitingForResponse && parsed.status === "idle" && visibleIdlePrompt);
31079
+ const shouldAdoptParsedIdleReplay = !this.currentTurnScope && !this.activeModal && !!parsedLastAssistant && parsedTranscriptIsRicherThanCommitted(parsedHydratedMessages, committedHydratedMessages) && (this.currentStatus === "idle" || this.currentStatus === "generating" && this.isWaitingForResponse && parsed.status === "idle" && this.runDetectStatus(this.recentOutputBuffer) === "idle");
31101
31080
  if (shouldAdoptParsedIdleReplay) {
31102
31081
  this.committedMessages = normalizeCliParsedMessages(parsed.messages, {
31103
31082
  committedMessages: this.committedMessages,
@@ -31226,17 +31205,9 @@ var require_dist2 = __commonJS({
31226
31205
  if (parsed && typeof parsed === "object") {
31227
31206
  Object.assign(parsed, validateReadChatResultPayload(parsed, `${this.cliType} parseOutput`));
31228
31207
  }
31229
- const refinedStatus = this.refineDetectedStatus(typeof parsed?.status === "string" ? parsed.status : null, input.recentBuffer, input.screenText);
31230
- if (parsed && refinedStatus && parsed.status !== refinedStatus) {
31231
- parsed.status = refinedStatus;
31232
- }
31233
31208
  const normalizedParsed = this.suppressStaleParsedApproval(parsed, input.recentBuffer, input.screenText);
31234
- const promptForTrim = scope?.prompt || getLastUserPromptText(baseMessages);
31235
- if (normalizedParsed && Array.isArray(normalizedParsed.messages) && promptForTrim) {
31236
- const lastAssistant = [...normalizedParsed.messages].reverse().find((message) => message?.role === "assistant" && typeof message.content === "string");
31237
- if (lastAssistant) {
31238
- lastAssistant.content = trimPromptEchoPrefix(lastAssistant.content, promptForTrim);
31239
- }
31209
+ if (normalizedParsed && Array.isArray(normalizedParsed.messages)) {
31210
+ this.trimLastAssistantEcho(normalizedParsed.messages, scope?.prompt || getLastUserPromptText(baseMessages));
31240
31211
  }
31241
31212
  this.parseErrorMessage = null;
31242
31213
  return normalizedParsed;
@@ -31264,16 +31235,11 @@ var require_dist2 = __commonJS({
31264
31235
  LOG2.warn("CLI", `[${this.cliType}] resolveAction error: ${e.message}`);
31265
31236
  }
31266
31237
  }
31267
- if (!promptText && data) {
31268
- promptText = `Please fix the following issue:
31269
- ${data.title || ""}
31270
- ${data.explanation || ""}
31271
-
31272
- ${data.message || ""}`.trim();
31273
- }
31274
- if (promptText) {
31275
- await this.sendMessage(promptText);
31238
+ if (!promptText) {
31239
+ LOG2.warn("CLI", `[${this.cliType}] resolveAction skipped: provider script did not supply a prompt`);
31240
+ return;
31276
31241
  }
31242
+ await this.sendMessage(promptText);
31277
31243
  }
31278
31244
  async sendMessage(text) {
31279
31245
  if (!this.ptyProcess) throw new Error(`${this.cliName} is not running`);
@@ -31291,9 +31257,7 @@ ${data.message || ""}`.trim();
31291
31257
  }
31292
31258
  if (!this.ready) {
31293
31259
  this.resolveStartupState("send_precheck");
31294
- const screenText = this.terminalScreen.getText() || "";
31295
- const hasPrompt = this.looksLikeVisibleIdlePrompt(screenText);
31296
- if (hasPrompt && this.currentStatus === "idle") {
31260
+ if (this.runDetectStatus(this.recentOutputBuffer) === "idle" && this.currentStatus === "idle") {
31297
31261
  this.ready = true;
31298
31262
  this.startupParseGate = false;
31299
31263
  LOG2.info("CLI", `[${this.cliType}] sendMessage recovered idle prompt readiness`);
@@ -31399,7 +31363,10 @@ ${data.message || ""}`.trim();
31399
31363
  if (this.hasMeaningfulResponseBuffer(normalizedPromptSnippet)) return;
31400
31364
  const screenText2 = this.terminalScreen.getText();
31401
31365
  if (!promptLikelyVisible(screenText2, normalizedPromptSnippet)) return;
31402
- 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;
31366
+ const liveApproval = this.runParseApproval(screenText2) || this.runParseApproval(this.recentOutputBuffer);
31367
+ if (liveApproval) return;
31368
+ const liveStatus = this.runDetectStatus(screenText2) || this.runDetectStatus(this.recentOutputBuffer);
31369
+ if (liveStatus === "generating" || liveStatus === "waiting_approval") return;
31403
31370
  this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
31404
31371
  LOG2.info("CLI", `[${this.cliType}] Retrying submit key for stuck prompt (attempt ${attempt})`);
31405
31372
  this.recordTrace("submit_write", {
@@ -31436,6 +31403,10 @@ ${data.message || ""}`.trim();
31436
31403
  if (this.hasMeaningfulResponseBuffer(normalizedPromptSnippet)) return;
31437
31404
  const screenText = this.terminalScreen.getText();
31438
31405
  if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
31406
+ const liveApproval = this.runParseApproval(screenText) || this.runParseApproval(this.recentOutputBuffer);
31407
+ if (liveApproval) return;
31408
+ const liveStatus = this.runDetectStatus(screenText) || this.runDetectStatus(this.recentOutputBuffer);
31409
+ if (liveStatus === "generating" || liveStatus === "waiting_approval") return;
31439
31410
  LOG2.info("CLI", `[${this.cliType}] Retrying submit key for stuck prompt (attempt 1)`);
31440
31411
  this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
31441
31412
  this.recordTrace("submit_write", {
@@ -31567,44 +31538,9 @@ ${data.message || ""}`.trim();
31567
31538
  }
31568
31539
  shutdown() {
31569
31540
  this.clearIdleFinishCandidate("shutdown");
31570
- if (this.settleTimer) {
31571
- clearTimeout(this.settleTimer);
31572
- this.settleTimer = null;
31573
- }
31574
- if (this.approvalExitTimeout) {
31575
- clearTimeout(this.approvalExitTimeout);
31576
- this.approvalExitTimeout = null;
31577
- }
31578
- if (this.submitRetryTimer) {
31579
- clearTimeout(this.submitRetryTimer);
31580
- this.submitRetryTimer = null;
31581
- }
31582
- if (this.finishRetryTimer) {
31583
- clearTimeout(this.finishRetryTimer);
31584
- this.finishRetryTimer = null;
31585
- }
31586
- if (this.responseTimeout) {
31587
- clearTimeout(this.responseTimeout);
31588
- this.responseTimeout = null;
31589
- }
31590
- if (this.idleTimeout) {
31591
- clearTimeout(this.idleTimeout);
31592
- this.idleTimeout = null;
31593
- }
31594
- if (this.pendingScriptStatusTimer) {
31595
- clearTimeout(this.pendingScriptStatusTimer);
31596
- this.pendingScriptStatusTimer = null;
31597
- }
31598
- if (this.pendingOutputParseTimer) {
31599
- clearTimeout(this.pendingOutputParseTimer);
31600
- this.pendingOutputParseTimer = null;
31601
- }
31541
+ this.clearAllTimers();
31602
31542
  this.pendingOutputParseBuffer = "";
31603
31543
  this.pendingTerminalQueryTail = "";
31604
- if (this.ptyOutputFlushTimer) {
31605
- clearTimeout(this.ptyOutputFlushTimer);
31606
- this.ptyOutputFlushTimer = null;
31607
- }
31608
31544
  this.ptyOutputBuffer = "";
31609
31545
  this.finishRetryCount = 0;
31610
31546
  if (this.ptyProcess) {
@@ -31625,44 +31561,9 @@ ${data.message || ""}`.trim();
31625
31561
  }
31626
31562
  detach() {
31627
31563
  this.clearIdleFinishCandidate("detach");
31628
- if (this.settleTimer) {
31629
- clearTimeout(this.settleTimer);
31630
- this.settleTimer = null;
31631
- }
31632
- if (this.approvalExitTimeout) {
31633
- clearTimeout(this.approvalExitTimeout);
31634
- this.approvalExitTimeout = null;
31635
- }
31636
- if (this.submitRetryTimer) {
31637
- clearTimeout(this.submitRetryTimer);
31638
- this.submitRetryTimer = null;
31639
- }
31640
- if (this.finishRetryTimer) {
31641
- clearTimeout(this.finishRetryTimer);
31642
- this.finishRetryTimer = null;
31643
- }
31644
- if (this.responseTimeout) {
31645
- clearTimeout(this.responseTimeout);
31646
- this.responseTimeout = null;
31647
- }
31648
- if (this.idleTimeout) {
31649
- clearTimeout(this.idleTimeout);
31650
- this.idleTimeout = null;
31651
- }
31652
- if (this.pendingScriptStatusTimer) {
31653
- clearTimeout(this.pendingScriptStatusTimer);
31654
- this.pendingScriptStatusTimer = null;
31655
- }
31656
- if (this.pendingOutputParseTimer) {
31657
- clearTimeout(this.pendingOutputParseTimer);
31658
- this.pendingOutputParseTimer = null;
31659
- }
31564
+ this.clearAllTimers();
31660
31565
  this.pendingOutputParseBuffer = "";
31661
31566
  this.pendingTerminalQueryTail = "";
31662
- if (this.ptyOutputFlushTimer) {
31663
- clearTimeout(this.ptyOutputFlushTimer);
31664
- this.ptyOutputFlushTimer = null;
31665
- }
31666
31567
  this.ptyOutputBuffer = "";
31667
31568
  this.finishRetryCount = 0;
31668
31569
  if (this.ptyProcess) {
@@ -31724,8 +31625,7 @@ ${data.message || ""}`.trim();
31724
31625
  this.ptyProcess?.write(data);
31725
31626
  }
31726
31627
  resolveModal(buttonIndex) {
31727
- const screenText = this.terminalScreen.getText() || "";
31728
- let modal = this.activeModal || this.getStartupConfirmationModal(screenText);
31628
+ let modal = this.activeModal || this.runParseApproval(this.recentOutputBuffer);
31729
31629
  if (!modal && typeof this.cliScripts?.parseOutput === "function") {
31730
31630
  try {
31731
31631
  const parsed = this.getScriptParsedStatus();
@@ -31756,12 +31656,7 @@ ${data.message || ""}`.trim();
31756
31656
  }
31757
31657
  this.setStatus("generating", "approval_resolved");
31758
31658
  this.onStatusChange?.();
31759
- const startupTrustModal = /Quick safety check|project trust|Confirm Claude Code project trust|trust (?:this project|the contents of this directory|the files in this folder)/i.test(String(modal?.message || ""));
31760
- if (startupTrustModal && buttonIndex in this.approvalKeys) {
31761
- this.ptyProcess.write(`${this.approvalKeys[buttonIndex]}\r`);
31762
- } else if (this.shouldResolveModalWithEnter(modal, buttonIndex)) {
31763
- this.ptyProcess.write("\r");
31764
- } else if (buttonIndex in this.approvalKeys) {
31659
+ if (buttonIndex in this.approvalKeys) {
31765
31660
  this.ptyProcess.write(this.approvalKeys[buttonIndex]);
31766
31661
  } else {
31767
31662
  const DOWN = "\x1B[B";
@@ -31781,7 +31676,7 @@ ${data.message || ""}`.trim();
31781
31676
  }
31782
31677
  getDebugState() {
31783
31678
  const screenText = sanitizeTerminalText(this.terminalScreen.getText());
31784
- const startupModal = this.startupParseGate ? this.getStartupConfirmationModal(screenText) : null;
31679
+ const startupModal = this.startupParseGate ? this.runParseApproval(this.recentOutputBuffer) : null;
31785
31680
  const effectiveStatus = this.projectEffectiveStatus(startupModal);
31786
31681
  const effectiveReady = this.ready || !!startupModal;
31787
31682
  return {
@@ -39030,25 +38925,23 @@ ${effect.notification.body || ""}`.trim();
39030
38925
  const effectiveModal = statusModal || surfacedModal;
39031
38926
  const effectiveStatus = status?.status === "waiting_approval" || targetState?.activeChat?.status === "waiting_approval" ? "waiting_approval" : status?.status;
39032
38927
  LOG2.info("Command", `[resolveAction] CLI PTY gate target=${String(args?.targetSessionId || "")} rawStatus=${String(status?.status || "")} effectiveStatus=${String(effectiveStatus || "")} statusModal=${statusModal ? "yes" : "no"} surfacedModal=${surfacedModal ? "yes" : "no"} instance=${targetInstance ? "yes" : "no"}`);
39033
- if (effectiveStatus !== "waiting_approval" && !effectiveModal) {
38928
+ if (!effectiveModal) {
39034
38929
  return { success: false, error: "Not in approval state" };
39035
38930
  }
39036
- const buttons = effectiveModal?.buttons || ["Allow once", "Always allow", "Deny"];
38931
+ const buttons = Array.isArray(effectiveModal.buttons) ? effectiveModal.buttons : [];
39037
38932
  let buttonIndex = typeof args?.buttonIndex === "number" ? args.buttonIndex : -1;
39038
- if (buttonIndex < 0) {
38933
+ if (buttonIndex < 0 && button) {
39039
38934
  const btnLower = button.toLowerCase();
39040
38935
  buttonIndex = buttons.findIndex((b2) => b2.toLowerCase().includes(btnLower));
39041
38936
  }
38937
+ if (buttonIndex < 0 && (action === "reject" || action === "deny")) {
38938
+ buttonIndex = buttons.findIndex((b2) => /deny|reject|no/i.test(b2));
38939
+ }
38940
+ if (buttonIndex < 0 && (action === "always" || /always/i.test(button))) {
38941
+ buttonIndex = buttons.findIndex((b2) => /always/i.test(b2));
38942
+ }
39042
38943
  if (buttonIndex < 0) {
39043
- if (action === "reject" || action === "deny") {
39044
- buttonIndex = buttons.findIndex((b2) => /deny|reject|no/i.test(b2));
39045
- if (buttonIndex < 0) buttonIndex = buttons.length - 1;
39046
- } else if (action === "always" || /always/i.test(button)) {
39047
- buttonIndex = buttons.findIndex((b2) => /always/i.test(b2));
39048
- if (buttonIndex < 0) buttonIndex = 1;
39049
- } else {
39050
- buttonIndex = 0;
39051
- }
38944
+ return { success: false, error: "Approval action did not match any visible button" };
39052
38945
  }
39053
38946
  if (typeof adapter.resolveModal === "function") {
39054
38947
  adapter.resolveModal(buttonIndex);
@@ -40690,6 +40583,13 @@ ${effect.notification.body || ""}`.trim();
40690
40583
  runtimeMessages = [];
40691
40584
  lastPersistedHistoryMessages = [];
40692
40585
  lastCanonicalHermesSyncMtimeMs = 0;
40586
+ lastCanonicalHermesExistCheckAt = 0;
40587
+ lastCanonicalHermesWatchPath = void 0;
40588
+ lastCanonicalClaudeRebuildMtimeMs = 0;
40589
+ lastCanonicalClaudeCheckAt = 0;
40590
+ cachedSqliteDb = null;
40591
+ cachedSqliteDbPath = null;
40592
+ cachedSqliteDbMissingUntil = 0;
40693
40593
  instanceId;
40694
40594
  suppressIdleHistoryReplay = false;
40695
40595
  errorMessage = void 0;
@@ -40754,7 +40654,12 @@ ${effect.notification.body || ""}`.trim();
40754
40654
  */
40755
40655
  probeSessionIdFromConfig(probe) {
40756
40656
  const resolvedDbPath = probe.dbPath.replace(/^~/, os11.homedir());
40757
- if (!fs52.existsSync(resolvedDbPath)) return null;
40657
+ const now = Date.now();
40658
+ if (this.cachedSqliteDbMissingUntil > now) return null;
40659
+ if (!fs52.existsSync(resolvedDbPath)) {
40660
+ this.cachedSqliteDbMissingUntil = now + 1e4;
40661
+ return null;
40662
+ }
40758
40663
  const directories = this.getProbeDirectories();
40759
40664
  const minCreatedAt = Math.max(0, this.startedAt - 6e4);
40760
40665
  const tsFormat = probe.timestampFormat || "unix_ms";
@@ -40925,6 +40830,12 @@ ${effect.notification.body || ""}`.trim();
40925
40830
  this.adapter.shutdown();
40926
40831
  this.monitor.reset();
40927
40832
  this.appliedEffectKeys.clear();
40833
+ try {
40834
+ this.cachedSqliteDb?.close();
40835
+ } catch {
40836
+ }
40837
+ this.cachedSqliteDb = null;
40838
+ this.cachedSqliteDbPath = null;
40928
40839
  }
40929
40840
  completedDebounceTimer = null;
40930
40841
  completedDebouncePending = null;
@@ -41329,13 +41240,35 @@ ${effect.notification.body || ""}`.trim();
41329
41240
  let rebuilt = false;
41330
41241
  if (canonicalHistory.format === "hermes-json") {
41331
41242
  const watchPath = canonicalHistory.watchPath.replace(/^~/, os11.homedir()).replace("{{sessionId}}", this.providerSessionId);
41332
- if (!fs52.existsSync(watchPath)) return false;
41243
+ const now = Date.now();
41244
+ if (watchPath !== this.lastCanonicalHermesWatchPath || now - this.lastCanonicalHermesExistCheckAt >= 2e3) {
41245
+ this.lastCanonicalHermesWatchPath = watchPath;
41246
+ this.lastCanonicalHermesExistCheckAt = now;
41247
+ if (!fs52.existsSync(watchPath)) return false;
41248
+ } else if (this.lastCanonicalHermesSyncMtimeMs === 0) {
41249
+ if (!fs52.existsSync(watchPath)) return false;
41250
+ }
41333
41251
  const stat4 = fs52.statSync(watchPath);
41334
41252
  if (stat4.mtimeMs <= this.lastCanonicalHermesSyncMtimeMs) return true;
41335
41253
  rebuilt = rebuildHermesSavedHistoryFromCanonicalSession(this.providerSessionId);
41336
41254
  if (rebuilt) this.lastCanonicalHermesSyncMtimeMs = stat4.mtimeMs;
41337
41255
  } else if (canonicalHistory.format === "claude-jsonl") {
41256
+ const now = Date.now();
41257
+ if (now - this.lastCanonicalClaudeCheckAt < 2e3 && this.lastCanonicalClaudeRebuildMtimeMs !== 0) {
41258
+ return true;
41259
+ }
41260
+ this.lastCanonicalClaudeCheckAt = now;
41261
+ const claudeProjectsDir = path11.join(os11.homedir(), ".claude", "projects");
41262
+ const workspaceSegment = typeof this.workingDir === "string" ? this.workingDir.replace(/[\\/]/g, "-").replace(/^-+/, "") : "";
41263
+ const transcriptFile = path11.join(claudeProjectsDir, workspaceSegment, `${this.providerSessionId}.jsonl`);
41264
+ let transcriptMtime = 0;
41265
+ try {
41266
+ transcriptMtime = fs52.statSync(transcriptFile).mtimeMs;
41267
+ } catch {
41268
+ }
41269
+ if (transcriptMtime > 0 && transcriptMtime <= this.lastCanonicalClaudeRebuildMtimeMs) return true;
41338
41270
  rebuilt = rebuildClaudeSavedHistoryFromNativeProject(this.providerSessionId, this.workingDir);
41271
+ if (rebuilt) this.lastCanonicalClaudeRebuildMtimeMs = transcriptMtime || Date.now();
41339
41272
  }
41340
41273
  if (!rebuilt) return false;
41341
41274
  const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
@@ -41400,20 +41333,29 @@ ${effect.notification.body || ""}`.trim();
41400
41333
  return Array.from({ length: count }, () => "?").join(", ");
41401
41334
  }
41402
41335
  querySqliteText(dbPath, query, params) {
41403
- let db = null;
41404
41336
  try {
41405
- const DatabaseSync = getDatabaseSync();
41406
- db = new DatabaseSync(dbPath, { readOnly: true });
41407
- const row = db.prepare(query).get(...params);
41337
+ if (this.cachedSqliteDb === null || this.cachedSqliteDbPath !== dbPath) {
41338
+ try {
41339
+ this.cachedSqliteDb?.close();
41340
+ } catch {
41341
+ }
41342
+ this.cachedSqliteDb = null;
41343
+ this.cachedSqliteDbPath = null;
41344
+ const DatabaseSync = getDatabaseSync();
41345
+ this.cachedSqliteDb = new DatabaseSync(dbPath, { readOnly: true });
41346
+ this.cachedSqliteDbPath = dbPath;
41347
+ }
41348
+ const row = this.cachedSqliteDb.prepare(query).get(...params);
41408
41349
  const sessionId = typeof row?.id === "string" ? row.id.trim() : "";
41409
41350
  return sessionId || null;
41410
41351
  } catch {
41411
- return null;
41412
- } finally {
41413
41352
  try {
41414
- db?.close();
41353
+ this.cachedSqliteDb?.close();
41415
41354
  } catch {
41416
41355
  }
41356
+ this.cachedSqliteDb = null;
41357
+ this.cachedSqliteDbPath = null;
41358
+ return null;
41417
41359
  }
41418
41360
  }
41419
41361
  };
@@ -43357,6 +43299,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
43357
43299
  "canonicalHistory",
43358
43300
  "autoFixProfile",
43359
43301
  "ideLevelScripts",
43302
+ "allowInputDuringGeneration",
43360
43303
  "scripts",
43361
43304
  "vscodeCommands",
43362
43305
  "inputMethod",