@adhdev/daemon-standalone 0.8.15 → 0.8.17

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
@@ -28699,6 +28699,40 @@ var require_dist2 = __commonJS({
28699
28699
  function normalizeComparableMessageContent(text) {
28700
28700
  return String(text || "").replace(/\s+/g, " ").trim();
28701
28701
  }
28702
+ function trimPromptEchoPrefix(text, promptText) {
28703
+ const prompt = normalizeComparableMessageContent(String(promptText || ""));
28704
+ if (!prompt) return String(text || "");
28705
+ const lines = String(text || "").split(/\r\n|\n|\r/g);
28706
+ let dropCount = 0;
28707
+ for (let index = 0; index < Math.min(lines.length, 6); index += 1) {
28708
+ const fragment = normalizeComparableMessageContent(lines[index].replace(/^[.…]+\s*/, ""));
28709
+ if (!fragment) {
28710
+ if (dropCount === index) dropCount = index + 1;
28711
+ continue;
28712
+ }
28713
+ const fragmentWordCount = fragment ? fragment.split(/\s+/).filter(Boolean).length : 0;
28714
+ const canBePromptEcho = fragment.length >= 16 || fragmentWordCount >= 4;
28715
+ if (canBePromptEcho && prompt.includes(fragment)) {
28716
+ dropCount = index + 1;
28717
+ continue;
28718
+ }
28719
+ break;
28720
+ }
28721
+ return lines.slice(dropCount).join("\n").trim();
28722
+ }
28723
+ function getLastUserPromptText(messages) {
28724
+ const items = Array.isArray(messages) ? messages : [];
28725
+ for (let index = items.length - 1; index >= 0; index -= 1) {
28726
+ const message = items[index];
28727
+ if (message?.role === "user" && typeof message.content === "string" && message.content.trim()) {
28728
+ return message.content;
28729
+ }
28730
+ }
28731
+ return "";
28732
+ }
28733
+ function looksLikeConfirmOnlyLabel(label) {
28734
+ return /^(?:continue|confirm|ok|yes|trust|proceed|enter)$/i.test(String(label || "").trim());
28735
+ }
28702
28736
  function parsePatternEntry(x) {
28703
28737
  if (x instanceof RegExp) return x;
28704
28738
  if (x && typeof x === "object" && typeof x.source === "string") {
@@ -28839,6 +28873,8 @@ var require_dist2 = __commonJS({
28839
28873
  submitRetryUsed = false;
28840
28874
  submitRetryPromptSnippet = "";
28841
28875
  idleFinishCandidate = null;
28876
+ finishRetryTimer = null;
28877
+ finishRetryCount = 0;
28842
28878
  // Resize redraw suppression
28843
28879
  resizeSuppressUntil = 0;
28844
28880
  // Debug: status transition history
@@ -28860,6 +28896,8 @@ var require_dist2 = __commonJS({
28860
28896
  static MAX_TRACE_ENTRIES = 250;
28861
28897
  providerResolutionMeta;
28862
28898
  static IDLE_FINISH_CONFIRM_MS = 900;
28899
+ static FINISH_RETRY_DELAY_MS = 300;
28900
+ static MAX_FINISH_RETRIES = 2;
28863
28901
  syncMessageViews() {
28864
28902
  this.messages = [...this.committedMessages];
28865
28903
  this.structuredMessages = [...this.committedMessages];
@@ -28919,7 +28957,8 @@ var require_dist2 = __commonJS({
28919
28957
  recentBuffer: buffer.slice(-1e3) || this.recentOutputBuffer,
28920
28958
  screenText: this.terminalScreen.getText(),
28921
28959
  messages: [...baseMessages],
28922
- partialResponse
28960
+ partialResponse,
28961
+ promptText: scope?.prompt || ""
28923
28962
  };
28924
28963
  }
28925
28964
  setStatus(status, trigger) {
@@ -29162,6 +29201,11 @@ var require_dist2 = __commonJS({
29162
29201
  this.terminalScreen.reset(24, 80);
29163
29202
  this.pendingTerminalQueryTail = "";
29164
29203
  this.currentTurnScope = null;
29204
+ this.finishRetryCount = 0;
29205
+ if (this.finishRetryTimer) {
29206
+ clearTimeout(this.finishRetryTimer);
29207
+ this.finishRetryTimer = null;
29208
+ }
29165
29209
  this.ready = false;
29166
29210
  await this.ptyProcess.ready;
29167
29211
  this.recordTrace("ready", {
@@ -29208,11 +29252,12 @@ var require_dist2 = __commonJS({
29208
29252
  if (this.startupParseGate) {
29209
29253
  this.startupBuffer += cleanData;
29210
29254
  const elapsed = Date.now() - this.spawnAt;
29211
- const scriptStatus = this.runDetectStatus(this.startupBuffer);
29212
29255
  const screenText = this.terminalScreen.getText() || "";
29256
+ const startupModal = this.getStartupConfirmationModal(screenText);
29257
+ const scriptStatus = startupModal ? "waiting_approval" : this.runDetectStatus(this.startupBuffer);
29213
29258
  const hasInteractivePrompt = this.looksLikeVisibleIdlePrompt(screenText);
29214
29259
  const startupStableMs = this.lastScreenChangeAt ? now - this.lastScreenChangeAt : 0;
29215
- const isReady = (scriptStatus === "idle" || scriptStatus === "waiting_approval") && hasInteractivePrompt && startupStableMs >= 700 || elapsed > 8e3 || this.startupBuffer.length > 12e3;
29260
+ const isReady = (scriptStatus === "idle" || scriptStatus === "waiting_approval") && hasInteractivePrompt && startupStableMs >= 700 || !!startupModal && startupStableMs >= 700 || elapsed > 8e3 || this.startupBuffer.length > 12e3;
29216
29261
  if (isReady) {
29217
29262
  this.startupParseGate = false;
29218
29263
  this.ready = true;
@@ -29244,7 +29289,9 @@ var require_dist2 = __commonJS({
29244
29289
  this.approvalExitTimeout = setTimeout(() => {
29245
29290
  if (this.currentStatus !== "waiting_approval") return;
29246
29291
  const tail = this.recentOutputBuffer;
29247
- const modal = this.runParseApproval(tail);
29292
+ const screenText = this.terminalScreen.getText() || "";
29293
+ const startupModal = this.getStartupConfirmationModal(screenText);
29294
+ const modal = this.runParseApproval(tail) || startupModal;
29248
29295
  const stillWaiting = this.runDetectStatus(tail) === "waiting_approval" || !!modal;
29249
29296
  if (stillWaiting) {
29250
29297
  this.activeModal = modal || this.activeModal || { message: "Approval required", buttons: ["Allow", "Deny"] };
@@ -29264,6 +29311,63 @@ var require_dist2 = __commonJS({
29264
29311
  if (!text.trim()) return false;
29265
29312
  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);
29266
29313
  }
29314
+ looksLikeVisibleAssistantCandidate(screenText) {
29315
+ const lines = sanitizeTerminalText(String(screenText || "")).split(/\r\n|\n|\r/g);
29316
+ for (const line of lines) {
29317
+ const trimmed = String(line || "").trim();
29318
+ if (!trimmed) continue;
29319
+ if (/^➜\s+\S+/.test(trimmed)) continue;
29320
+ if (/^Update available!/i.test(trimmed)) continue;
29321
+ if (/Claude Code v\d/i.test(trimmed)) continue;
29322
+ if (/^⏵⏵\s+accept edits on/i.test(trimmed)) continue;
29323
+ if (/^[◐◑◒◓◴◵◶◷◸◹◺◿].*\/effort/i.test(trimmed)) continue;
29324
+ if (/^[✻✶✳✢✽⠂⠐⠒⠓⠦⠴⠶⠷⠿]+$/.test(trimmed)) continue;
29325
+ if (/esc to (cancel|interrupt|stop)/i.test(trimmed)) continue;
29326
+ const assistantMatch = trimmed.match(/^⏺\s+(.+)$/);
29327
+ if (!assistantMatch) continue;
29328
+ const content = assistantMatch[1].trim();
29329
+ if (!content) continue;
29330
+ if (/^(?:Bash|Read|Write|Edit|MultiEdit|Task|Glob|Grep|LS|NotebookEdit)\(/.test(content)) continue;
29331
+ if (/This command requires approval|Do you want to proceed|Allow once|Always allow/i.test(content)) continue;
29332
+ return true;
29333
+ }
29334
+ return false;
29335
+ }
29336
+ shouldRetryFinishResponse(commitResult) {
29337
+ if (!this.currentTurnScope) return false;
29338
+ if (this.currentStatus === "waiting_approval" || this.activeModal) return false;
29339
+ if (this.finishRetryCount >= _ProviderCliAdapter.MAX_FINISH_RETRIES) return false;
29340
+ if (commitResult.hasAssistant && commitResult.assistantContent.trim()) return false;
29341
+ const screenText = this.terminalScreen.getText() || "";
29342
+ if (!this.looksLikeVisibleAssistantCandidate(screenText)) return false;
29343
+ const now = Date.now();
29344
+ const quietForMs = this.lastNonEmptyOutputAt ? now - this.lastNonEmptyOutputAt : Number.MAX_SAFE_INTEGER;
29345
+ const screenStableMs = this.lastScreenChangeAt ? now - this.lastScreenChangeAt : 0;
29346
+ return quietForMs < 1200 || screenStableMs < 1200 || !commitResult.hasAssistant;
29347
+ }
29348
+ getStartupConfirmationModal(screenText) {
29349
+ const text = sanitizeTerminalText(String(screenText || ""));
29350
+ if (!text.trim()) return null;
29351
+ if (this.cliType === "claude-cli") {
29352
+ 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);
29353
+ const hasConfirmFooter = /Press Enter to (?:continue|confirm)/i.test(text) || /Enter to confirm/i.test(text) || /Esc to (?:cancel|exit)/i.test(text);
29354
+ if (hasTrustPrompt || hasConfirmFooter && /trust/i.test(text)) {
29355
+ return {
29356
+ message: "Confirm Claude Code project trust",
29357
+ buttons: ["Continue"]
29358
+ };
29359
+ }
29360
+ }
29361
+ return null;
29362
+ }
29363
+ shouldResolveModalWithEnter(modal, buttonIndex) {
29364
+ if (!modal || buttonIndex !== 0) return false;
29365
+ const buttons = Array.isArray(modal.buttons) ? modal.buttons : [];
29366
+ if (buttons.length !== 1) return false;
29367
+ const buttonLabel = String(buttons[0] || "").trim();
29368
+ const modalText = `${modal.message || ""} ${buttonLabel}`.trim();
29369
+ return looksLikeConfirmOnlyLabel(buttonLabel) || /Quick safety check|project trust|trust (?:this project|the contents of this directory|the files in this folder)|Enter to confirm/i.test(modalText);
29370
+ }
29267
29371
  async waitForInteractivePrompt(maxWaitMs = 5e3) {
29268
29372
  const startedAt = Date.now();
29269
29373
  let loggedWait = false;
@@ -29313,9 +29417,10 @@ var require_dist2 = __commonJS({
29313
29417
  }
29314
29418
  const tail = this.settledBuffer;
29315
29419
  const screenText = this.terminalScreen.getText() || "";
29316
- const modal = this.runParseApproval(tail);
29420
+ const startupModal = this.getStartupConfirmationModal(screenText);
29421
+ const modal = this.runParseApproval(tail) || startupModal;
29317
29422
  const rawScriptStatus = this.runDetectStatus(tail);
29318
- const scriptStatus = rawScriptStatus;
29423
+ const scriptStatus = startupModal ? "waiting_approval" : rawScriptStatus;
29319
29424
  const parsedTranscript = this.parseCurrentTranscript(
29320
29425
  this.committedMessages,
29321
29426
  this.responseBuffer,
@@ -29510,7 +29615,24 @@ var require_dist2 = __commonJS({
29510
29615
  this.recordTrace("finish_response", {
29511
29616
  ...this.buildTraceParseSnapshot(this.currentTurnScope, this.responseBuffer)
29512
29617
  });
29513
- this.commitCurrentTranscript();
29618
+ const commitResult = this.commitCurrentTranscript();
29619
+ if (this.shouldRetryFinishResponse(commitResult)) {
29620
+ this.finishRetryCount += 1;
29621
+ this.recordTrace("finish_response_retry", {
29622
+ retryCount: this.finishRetryCount,
29623
+ retryDelayMs: _ProviderCliAdapter.FINISH_RETRY_DELAY_MS,
29624
+ assistantContent: this.summarizeTraceText(commitResult.assistantContent, 220),
29625
+ ...this.buildTraceParseSnapshot(this.currentTurnScope, this.responseBuffer)
29626
+ });
29627
+ if (this.finishRetryTimer) clearTimeout(this.finishRetryTimer);
29628
+ this.finishRetryTimer = setTimeout(() => {
29629
+ this.finishRetryTimer = null;
29630
+ if (this.isWaitingForResponse && this.currentStatus !== "waiting_approval") {
29631
+ this.finishResponse();
29632
+ }
29633
+ }, _ProviderCliAdapter.FINISH_RETRY_DELAY_MS);
29634
+ return;
29635
+ }
29514
29636
  if (this.responseTimeout) {
29515
29637
  clearTimeout(this.responseTimeout);
29516
29638
  this.responseTimeout = null;
@@ -29527,11 +29649,16 @@ var require_dist2 = __commonJS({
29527
29649
  clearTimeout(this.submitRetryTimer);
29528
29650
  this.submitRetryTimer = null;
29529
29651
  }
29652
+ if (this.finishRetryTimer) {
29653
+ clearTimeout(this.finishRetryTimer);
29654
+ this.finishRetryTimer = null;
29655
+ }
29530
29656
  this.responseBuffer = "";
29531
29657
  this.isWaitingForResponse = false;
29532
29658
  this.responseSettleIgnoreUntil = 0;
29533
29659
  this.submitRetryUsed = false;
29534
29660
  this.submitRetryPromptSnippet = "";
29661
+ this.finishRetryCount = 0;
29535
29662
  this.currentTurnScope = null;
29536
29663
  this.activeModal = null;
29537
29664
  this.setStatus("idle", "response_finished");
@@ -29545,6 +29672,13 @@ var require_dist2 = __commonJS({
29545
29672
  );
29546
29673
  if (parsed && Array.isArray(parsed.messages)) {
29547
29674
  this.committedMessages = this.normalizeParsedMessages(parsed.messages);
29675
+ const promptForTrim = this.currentTurnScope?.prompt || getLastUserPromptText(this.committedMessages);
29676
+ if (promptForTrim) {
29677
+ const lastAssistantForTrim = [...this.committedMessages].reverse().find((message) => message.role === "assistant");
29678
+ if (lastAssistantForTrim) {
29679
+ lastAssistantForTrim.content = trimPromptEchoPrefix(lastAssistantForTrim.content, promptForTrim);
29680
+ }
29681
+ }
29548
29682
  this.syncMessageViews();
29549
29683
  const lastAssistant = [...this.committedMessages].reverse().find((message) => message.role === "assistant");
29550
29684
  this.recordTrace("commit_transcript", {
@@ -29560,7 +29694,15 @@ var require_dist2 = __commonJS({
29560
29694
  `[${this.cliType}] Commit without assistant turn: prompt=${JSON.stringify(this.currentTurnScope.prompt).slice(0, 140)} responseBuffer=${JSON.stringify(this.summarizeTraceText(this.responseBuffer, 220)).slice(0, 260)} providerDir=${this.providerResolutionMeta.providerDir || "-"} scriptDir=${this.providerResolutionMeta.scriptDir || "-"} scriptsPath=${this.providerResolutionMeta.scriptsPath || "-"}`
29561
29695
  );
29562
29696
  }
29697
+ return {
29698
+ hasAssistant: !!lastAssistant,
29699
+ assistantContent: lastAssistant?.content || ""
29700
+ };
29563
29701
  }
29702
+ return {
29703
+ hasAssistant: false,
29704
+ assistantContent: ""
29705
+ };
29564
29706
  }
29565
29707
  // ─── Script Execution ──────────────────────────
29566
29708
  runDetectStatus(text) {
@@ -29639,7 +29781,15 @@ var require_dist2 = __commonJS({
29639
29781
  if (!this.cliScripts?.parseOutput) return null;
29640
29782
  try {
29641
29783
  const input = this.buildParseInput(baseMessages, partialResponse, scope);
29642
- return this.cliScripts.parseOutput(input);
29784
+ const parsed = this.cliScripts.parseOutput(input);
29785
+ const promptForTrim = scope?.prompt || getLastUserPromptText(baseMessages);
29786
+ if (parsed && Array.isArray(parsed.messages) && promptForTrim) {
29787
+ const lastAssistant = [...parsed.messages].reverse().find((message) => message?.role === "assistant" && typeof message.content === "string");
29788
+ if (lastAssistant) {
29789
+ lastAssistant.content = trimPromptEchoPrefix(lastAssistant.content, promptForTrim);
29790
+ }
29791
+ }
29792
+ return parsed;
29643
29793
  } catch (e) {
29644
29794
  LOG2.warn("CLI", `[${this.cliType}] parseOutput error: ${e.message}`);
29645
29795
  return null;
@@ -29684,10 +29834,19 @@ ${data.message || ""}`.trim();
29684
29834
  if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
29685
29835
  if (this.isWaitingForResponse) return;
29686
29836
  await this.waitForInteractivePrompt();
29837
+ const blockingModal = this.activeModal || this.getStartupConfirmationModal(this.terminalScreen.getText() || "");
29838
+ if (blockingModal || this.currentStatus === "waiting_approval") {
29839
+ throw new Error(`${this.cliName} is awaiting confirmation before it can accept a prompt`);
29840
+ }
29687
29841
  this.committedMessages.push({ role: "user", content: text, timestamp: Date.now() });
29688
29842
  this.syncMessageViews();
29689
29843
  this.isWaitingForResponse = true;
29690
29844
  this.responseBuffer = "";
29845
+ this.finishRetryCount = 0;
29846
+ if (this.finishRetryTimer) {
29847
+ clearTimeout(this.finishRetryTimer);
29848
+ this.finishRetryTimer = null;
29849
+ }
29691
29850
  this.clearIdleFinishCandidate("send_message");
29692
29851
  this.currentTurnScope = {
29693
29852
  prompt: text,
@@ -29915,6 +30074,10 @@ ${data.message || ""}`.trim();
29915
30074
  clearTimeout(this.submitRetryTimer);
29916
30075
  this.submitRetryTimer = null;
29917
30076
  }
30077
+ if (this.finishRetryTimer) {
30078
+ clearTimeout(this.finishRetryTimer);
30079
+ this.finishRetryTimer = null;
30080
+ }
29918
30081
  if (this.responseTimeout) {
29919
30082
  clearTimeout(this.responseTimeout);
29920
30083
  this.responseTimeout = null;
@@ -29938,6 +30101,7 @@ ${data.message || ""}`.trim();
29938
30101
  this.ptyOutputFlushTimer = null;
29939
30102
  }
29940
30103
  this.ptyOutputBuffer = "";
30104
+ this.finishRetryCount = 0;
29941
30105
  if (this.ptyProcess) {
29942
30106
  this.ptyProcess.write("");
29943
30107
  setTimeout(() => {
@@ -29968,6 +30132,10 @@ ${data.message || ""}`.trim();
29968
30132
  clearTimeout(this.submitRetryTimer);
29969
30133
  this.submitRetryTimer = null;
29970
30134
  }
30135
+ if (this.finishRetryTimer) {
30136
+ clearTimeout(this.finishRetryTimer);
30137
+ this.finishRetryTimer = null;
30138
+ }
29971
30139
  if (this.responseTimeout) {
29972
30140
  clearTimeout(this.responseTimeout);
29973
30141
  this.responseTimeout = null;
@@ -29991,6 +30159,7 @@ ${data.message || ""}`.trim();
29991
30159
  this.ptyOutputFlushTimer = null;
29992
30160
  }
29993
30161
  this.ptyOutputBuffer = "";
30162
+ this.finishRetryCount = 0;
29994
30163
  if (this.ptyProcess) {
29995
30164
  try {
29996
30165
  if (typeof this.ptyProcess.detach === "function") {
@@ -30027,6 +30196,11 @@ ${data.message || ""}`.trim();
30027
30196
  this.ptyOutputFlushTimer = null;
30028
30197
  }
30029
30198
  this.ptyOutputBuffer = "";
30199
+ if (this.finishRetryTimer) {
30200
+ clearTimeout(this.finishRetryTimer);
30201
+ this.finishRetryTimer = null;
30202
+ }
30203
+ this.finishRetryCount = 0;
30030
30204
  this.terminalScreen.reset();
30031
30205
  this.ptyProcess?.clearBuffer?.();
30032
30206
  this.onStatusChange?.();
@@ -30046,10 +30220,11 @@ ${data.message || ""}`.trim();
30046
30220
  }
30047
30221
  resolveModal(buttonIndex) {
30048
30222
  if (!this.ptyProcess || this.currentStatus !== "waiting_approval" && !this.activeModal) return;
30223
+ const modal = this.activeModal;
30049
30224
  this.clearIdleFinishCandidate("resolve_modal");
30050
30225
  this.recordTrace("resolve_modal", {
30051
30226
  buttonIndex,
30052
- activeModal: this.activeModal
30227
+ activeModal: modal
30053
30228
  });
30054
30229
  this.activeModal = null;
30055
30230
  this.lastApprovalResolvedAt = Date.now();
@@ -30060,7 +30235,9 @@ ${data.message || ""}`.trim();
30060
30235
  }
30061
30236
  this.setStatus("generating", "approval_resolved");
30062
30237
  this.onStatusChange?.();
30063
- if (buttonIndex in this.approvalKeys) {
30238
+ if (this.shouldResolveModalWithEnter(modal, buttonIndex)) {
30239
+ this.ptyProcess.write("\r");
30240
+ } else if (buttonIndex in this.approvalKeys) {
30064
30241
  this.ptyProcess.write(this.approvalKeys[buttonIndex]);
30065
30242
  } else {
30066
30243
  const DOWN = "\x1B[B";
@@ -30236,6 +30413,7 @@ ${data.message || ""}`.trim();
30236
30413
  setLogLevel: () => setLogLevel,
30237
30414
  setupIdeInstance: () => setupIdeInstance,
30238
30415
  shutdownDaemonComponents: () => shutdownDaemonComponents2,
30416
+ spawnDetachedDaemonUpgradeHelper: () => spawnDetachedDaemonUpgradeHelper,
30239
30417
  startDaemonDevSupport: () => startDaemonDevSupport2,
30240
30418
  updateConfig: () => updateConfig,
30241
30419
  upsertSavedProviderSession: () => upsertSavedProviderSession
@@ -39394,7 +39572,10 @@ Run 'adhdev doctor' for detailed diagnostics.`
39394
39572
  }
39395
39573
  }
39396
39574
  function getNpmExecutable() {
39397
- return process.platform === "win32" ? "npm.cmd" : "npm";
39575
+ return "npm";
39576
+ }
39577
+ function getNpmExecOptions() {
39578
+ return { shell: process.platform === "win32" };
39398
39579
  }
39399
39580
  function killPid2(pid) {
39400
39581
  try {
@@ -39456,9 +39637,10 @@ Run 'adhdev doctor' for detailed diagnostics.`
39456
39637
  }
39457
39638
  }
39458
39639
  function cleanupStaleGlobalInstallDirs(pkgName) {
39459
- const npmRoot = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["root", "-g"], { encoding: "utf8" }).trim();
39640
+ const npmExecOpts = getNpmExecOptions();
39641
+ const npmRoot = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["root", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
39460
39642
  if (!npmRoot) return;
39461
- const npmPrefix = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["prefix", "-g"], { encoding: "utf8" }).trim();
39643
+ const npmPrefix = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["prefix", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
39462
39644
  const binDir = process.platform === "win32" ? npmPrefix : path13.join(npmPrefix, "bin");
39463
39645
  const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
39464
39646
  const binNames = /* @__PURE__ */ new Set([packageBaseName]);
@@ -39519,7 +39701,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
39519
39701
  {
39520
39702
  encoding: "utf8",
39521
39703
  stdio: "pipe",
39522
- maxBuffer: 20 * 1024 * 1024
39704
+ maxBuffer: 20 * 1024 * 1024,
39705
+ ...getNpmExecOptions()
39523
39706
  }
39524
39707
  );
39525
39708
  if (installOutput.trim()) {
@@ -42711,6 +42894,53 @@ async (params) => {
42711
42894
  let lastModalKey = "";
42712
42895
  let idleSince = 0;
42713
42896
  let sawBusy = false;
42897
+ const noteStatus = (status) => {
42898
+ if (status !== lastStatus) {
42899
+ statusesSeen.push(status);
42900
+ lastStatus = status;
42901
+ }
42902
+ };
42903
+ const resolveActiveModalIfNeeded = (status, modal) => {
42904
+ if (!autoResolveApprovals || status !== "waiting_approval" || !modal || !Array.isArray(modal.buttons) || modal.buttons.length === 0) {
42905
+ return false;
42906
+ }
42907
+ const clampedIndex = Math.max(0, Math.min(Number(approvalButtonIndex) || 0, modal.buttons.length - 1));
42908
+ const modalKey = JSON.stringify({
42909
+ message: modal.message || "",
42910
+ buttons: modal.buttons,
42911
+ index: clampedIndex
42912
+ });
42913
+ if (modalKey === lastModalKey || typeof bundle?.adapter?.resolveModal !== "function") {
42914
+ return false;
42915
+ }
42916
+ lastModalKey = modalKey;
42917
+ approvalsResolved.push({
42918
+ at: Date.now(),
42919
+ buttonIndex: clampedIndex,
42920
+ label: modal.buttons[clampedIndex] || null
42921
+ });
42922
+ bundle.adapter.resolveModal(clampedIndex);
42923
+ return true;
42924
+ };
42925
+ const preflightStartedAt = Date.now();
42926
+ while (Date.now() - preflightStartedAt < Math.max(1e3, readyTimeoutMs)) {
42927
+ bundle = getCliTargetBundle(ctx, type, bundle.target.instanceId);
42928
+ if (!bundle) {
42929
+ throw new Error("CLI instance disappeared before exercise send");
42930
+ }
42931
+ const debug = typeof bundle.adapter.getDebugState === "function" ? bundle.adapter.getDebugState() : null;
42932
+ const trace = typeof bundle.adapter.getTraceState === "function" ? bundle.adapter.getTraceState(traceLimit) : null;
42933
+ const status = String(debug?.status || bundle.target.status || "unknown");
42934
+ const modal = debug?.activeModal || trace?.activeModal || null;
42935
+ noteStatus(status);
42936
+ if (resolveActiveModalIfNeeded(status, modal)) {
42937
+ await sleep(150);
42938
+ continue;
42939
+ }
42940
+ const startupParseGate = !!debug?.startupParseGate;
42941
+ if (status === "idle" && !startupParseGate) break;
42942
+ await sleep(150);
42943
+ }
42714
42944
  ctx.instanceManager.sendEvent(bundle.target.instanceId, "send_message", { text });
42715
42945
  while (Date.now() - startAt < Math.max(1e3, timeoutMs)) {
42716
42946
  await sleep(150);
@@ -42725,32 +42955,14 @@ async (params) => {
42725
42955
  const sawSendMessage = traceEntries.some((entry) => entry?.type === "send_message");
42726
42956
  const sawSubmitWrite = traceEntries.some((entry) => entry?.type === "submit_write");
42727
42957
  const hasTurnStarted = sawSendMessage || sawSubmitWrite || !!debug?.currentTurnScope;
42728
- if (status !== lastStatus) {
42729
- statusesSeen.push(status);
42730
- lastStatus = status;
42731
- }
42958
+ noteStatus(status);
42732
42959
  if (status === "generating" || status === "waiting_approval") {
42733
42960
  sawBusy = true;
42734
42961
  idleSince = 0;
42735
42962
  }
42736
42963
  const modal = debug?.activeModal || trace?.activeModal || null;
42737
- if (autoResolveApprovals && status === "waiting_approval" && modal && Array.isArray(modal.buttons) && modal.buttons.length > 0) {
42738
- const clampedIndex = Math.max(0, Math.min(Number(approvalButtonIndex) || 0, modal.buttons.length - 1));
42739
- const modalKey = JSON.stringify({
42740
- message: modal.message || "",
42741
- buttons: modal.buttons,
42742
- index: clampedIndex
42743
- });
42744
- if (modalKey !== lastModalKey && typeof bundle.adapter.resolveModal === "function") {
42745
- lastModalKey = modalKey;
42746
- approvalsResolved.push({
42747
- at: Date.now(),
42748
- buttonIndex: clampedIndex,
42749
- label: modal.buttons[clampedIndex] || null
42750
- });
42751
- bundle.adapter.resolveModal(clampedIndex);
42752
- continue;
42753
- }
42964
+ if (resolveActiveModalIfNeeded(status, modal)) {
42965
+ continue;
42754
42966
  }
42755
42967
  const traceCount = Number(trace?.entryCount || 0);
42756
42968
  const hasProgress = hasTurnStarted && (traceCount > preTraceCount || statusesSeen.length > 1 || approvalsResolved.length > 0);
@@ -44403,6 +44615,13 @@ async (params) => {
44403
44615
  lines.push("19. Literal string checks are allowed only for stable proper nouns or exact product chrome that cannot be expressed safely as a broader pattern. Everything else should generalize.");
44404
44616
  lines.push("20. When a bug comes from noisy PTY text, first normalize and classify the line family; do NOT just append another special-case substring to the parser.");
44405
44617
  lines.push("");
44618
+ if (verification?.focusAreas?.length) {
44619
+ lines.push("## Provider-Specific Focus Areas");
44620
+ for (const area of verification.focusAreas) {
44621
+ lines.push(`- ${area}`);
44622
+ }
44623
+ lines.push("");
44624
+ }
44406
44625
  lines.push("## Task");
44407
44626
  lines.push(`Edit files in \`${providerDir}\` to implement: **${functions.join(", ")}**`);
44408
44627
  lines.push("");