@adhdev/daemon-core 0.8.89 → 0.8.91

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.mjs CHANGED
@@ -1662,8 +1662,8 @@ function buildCliParseInput(options) {
1662
1662
  scope,
1663
1663
  runtimeSettings
1664
1664
  } = options;
1665
- const buffer = scope ? sliceFromOffset(accumulatedBuffer, scope.bufferStart) || accumulatedBuffer : accumulatedBuffer;
1666
- const rawBuffer = scope ? sliceFromOffset(accumulatedRawBuffer, scope.rawBufferStart) || accumulatedRawBuffer : accumulatedRawBuffer;
1665
+ const buffer = scope ? sliceFromOffset(accumulatedBuffer, scope.bufferStart) : accumulatedBuffer;
1666
+ const rawBuffer = scope ? sliceFromOffset(accumulatedRawBuffer, scope.rawBufferStart) : accumulatedRawBuffer;
1667
1667
  const screenText = terminalScreenText;
1668
1668
  const recentBuffer = buffer.slice(-1e3) || recentOutputBuffer;
1669
1669
  return {
@@ -1695,8 +1695,8 @@ function summarizeCliTraceMessages(messages, limit = 3) {
1695
1695
  }
1696
1696
  function buildCliTraceParseSnapshot(options) {
1697
1697
  const { accumulatedBuffer, accumulatedRawBuffer, responseBuffer, partialResponse, scope } = options;
1698
- const scopedBuffer = scope ? sliceFromOffset(accumulatedBuffer, scope.bufferStart) || accumulatedBuffer : accumulatedBuffer;
1699
- const scopedRawBuffer = scope ? sliceFromOffset(accumulatedRawBuffer, scope.rawBufferStart) || accumulatedRawBuffer : accumulatedRawBuffer;
1698
+ const scopedBuffer = scope ? sliceFromOffset(accumulatedBuffer, scope.bufferStart) : accumulatedBuffer;
1699
+ const scopedRawBuffer = scope ? sliceFromOffset(accumulatedRawBuffer, scope.rawBufferStart) : accumulatedRawBuffer;
1700
1700
  return {
1701
1701
  currentTurnScope: scope || null,
1702
1702
  responseBuffer: summarizeCliTraceText(responseBuffer, 1200),
@@ -2359,6 +2359,7 @@ var init_provider_cli_adapter = __esm({
2359
2359
  looksLikeClaudeGeneratingLine(line) {
2360
2360
  const trimmed = String(line || "").trim();
2361
2361
  if (!trimmed) return false;
2362
+ if (/^⏵⏵\s+accept edits on/i.test(trimmed)) return false;
2362
2363
  if (/esc to (cancel|interrupt|stop)/i.test(trimmed)) return true;
2363
2364
  if (/^[✻✶✳✢✽⠂⠐⠒⠓⠦⠴⠶⠷⠿]+\s+\S+.*\b(?:thinking|thought for \d+s?)\b/i.test(trimmed)) return true;
2364
2365
  if (/^[✻✶✳✢✽⠂⠐⠒⠓⠦⠴⠶⠷⠿]+\s+[A-Z][A-Za-z-]{3,}ing\b.*(?:…|\.{3})/u.test(trimmed)) return true;
@@ -2568,14 +2569,15 @@ var init_provider_cli_adapter = __esm({
2568
2569
  return;
2569
2570
  }
2570
2571
  const startupModal = this.getStartupConfirmationModal(screenText);
2571
- const modal = this.runParseApproval(tail) || startupModal;
2572
- const rawScriptStatus = this.runDetectStatus(tail);
2573
- const scriptStatus = startupModal ? "waiting_approval" : rawScriptStatus;
2574
2572
  const parsedTranscript = this.parseCurrentTranscript(
2575
2573
  this.committedMessages,
2576
2574
  this.responseBuffer,
2577
2575
  this.currentTurnScope
2578
2576
  );
2577
+ const parsedModal = parsedTranscript?.activeModal && Array.isArray(parsedTranscript.activeModal.buttons) && parsedTranscript.activeModal.buttons.some((button) => typeof button === "string" && button.trim()) ? parsedTranscript.activeModal : null;
2578
+ const modal = this.runParseApproval(tail) || parsedModal || startupModal;
2579
+ const rawScriptStatus = this.runDetectStatus(tail);
2580
+ const scriptStatus = startupModal ? "waiting_approval" : parsedModal && parsedTranscript?.status === "waiting_approval" ? "waiting_approval" : rawScriptStatus;
2579
2581
  const parsedMessages = Array.isArray(parsedTranscript?.messages) ? normalizeCliParsedMessages(parsedTranscript.messages, {
2580
2582
  committedMessages: this.committedMessages,
2581
2583
  scope: this.currentTurnScope,
@@ -2585,6 +2587,7 @@ var init_provider_cli_adapter = __esm({
2585
2587
  return;
2586
2588
  }
2587
2589
  const lastParsedAssistant = [...parsedMessages].reverse().find((message) => message.role === "assistant");
2590
+ const parsedShowsLiveAssistantProgress = parsedTranscript?.status === "generating" && !!lastParsedAssistant && parsedMessages.length > this.committedMessages.length;
2588
2591
  const normalizedPromptSnippet = normalizePromptText(this.submitRetryPromptSnippet || this.currentTurnScope?.prompt || "");
2589
2592
  this.recordTrace("settled", {
2590
2593
  tail: summarizeCliTraceText(tail, 500),
@@ -2671,7 +2674,7 @@ var init_provider_cli_adapter = __esm({
2671
2674
  `[${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)}`
2672
2675
  );
2673
2676
  }
2674
- const shouldHoldGenerating = scriptStatus === "idle" && this.isWaitingForResponse && !modal && recentInteractiveActivity && !(visibleIdlePrompt && visibleAssistantCandidate);
2677
+ const shouldHoldGenerating = scriptStatus === "idle" && this.isWaitingForResponse && !modal && recentInteractiveActivity && !(visibleIdlePrompt && visibleAssistantCandidate) && !(parsedTranscript?.status === "idle" && !!lastParsedAssistant);
2675
2678
  if (shouldHoldGenerating) {
2676
2679
  this.clearIdleFinishCandidate("hold_generating_recent_activity");
2677
2680
  this.setStatus("generating", "recent_activity_hold");
@@ -2739,7 +2742,7 @@ var init_provider_cli_adapter = __esm({
2739
2742
  const effectiveScreenText = screenText || this.accumulatedBuffer;
2740
2743
  const noActiveTurn = !this.currentTurnScope;
2741
2744
  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));
2742
- if (prevStatus === "idle" && !this.isWaitingForResponse && noActiveTurn && !modal && looksIdleChrome) {
2745
+ if (prevStatus === "idle" && !this.isWaitingForResponse && noActiveTurn && !modal && looksIdleChrome && !parsedShowsLiveAssistantProgress) {
2743
2746
  return;
2744
2747
  }
2745
2748
  if (prevStatus === "waiting_approval") {
@@ -3073,11 +3076,17 @@ var init_provider_cli_adapter = __esm({
3073
3076
  return null;
3074
3077
  }
3075
3078
  }
3079
+ projectEffectiveStatus(startupModal = null) {
3080
+ if (this.parseErrorMessage) return "error";
3081
+ if (startupModal) return "waiting_approval";
3082
+ if (this.isWaitingForResponse && this.currentTurnScope && this.currentStatus === "idle") return "generating";
3083
+ return this.currentStatus;
3084
+ }
3076
3085
  // ─── Public API (CliAdapter) ───────────────────
3077
3086
  getStatus() {
3078
3087
  const screenText = this.terminalScreen.getText() || "";
3079
3088
  const startupModal = this.startupParseGate ? this.getStartupConfirmationModal(screenText) : null;
3080
- const effectiveStatus = this.parseErrorMessage ? "error" : startupModal ? "waiting_approval" : this.currentStatus;
3089
+ const effectiveStatus = this.projectEffectiveStatus(startupModal);
3081
3090
  return {
3082
3091
  status: effectiveStatus,
3083
3092
  messages: [...this.committedMessages],
@@ -3784,7 +3793,7 @@ ${data.message || ""}`.trim();
3784
3793
  }
3785
3794
  this.setStatus("generating", "approval_resolved");
3786
3795
  this.onStatusChange?.();
3787
- const startupTrustModal = /Quick safety check|project trust|trust (?:this project|the contents of this directory|the files in this folder)/i.test(String(modal?.message || ""));
3796
+ 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 || ""));
3788
3797
  if (startupTrustModal && buttonIndex in this.approvalKeys) {
3789
3798
  this.ptyProcess.write(`${this.approvalKeys[buttonIndex]}\r`);
3790
3799
  } else if (this.shouldResolveModalWithEnter(modal, buttonIndex)) {
@@ -3810,7 +3819,7 @@ ${data.message || ""}`.trim();
3810
3819
  getDebugState() {
3811
3820
  const screenText = sanitizeTerminalText(this.terminalScreen.getText());
3812
3821
  const startupModal = this.startupParseGate ? this.getStartupConfirmationModal(screenText) : null;
3813
- const effectiveStatus = startupModal ? "waiting_approval" : this.currentStatus;
3822
+ const effectiveStatus = this.projectEffectiveStatus(startupModal);
3814
3823
  const effectiveReady = this.ready || !!startupModal;
3815
3824
  return {
3816
3825
  type: this.cliType,
@@ -9991,10 +10000,11 @@ async function handleReadChat(h, args) {
9991
10000
  const parsedRecord = parsedStatus && typeof parsedStatus === "object" ? parsedStatus : null;
9992
10001
  const adapterStatus = adapter.getStatus();
9993
10002
  const shouldPreferAdapterMessages = Array.isArray(adapterStatus.messages) && adapterStatus.messages.length > 0 && Array.isArray(parsedRecord?.messages) && adapterStatus.messages.length > parsedRecord.messages.length;
10003
+ const parsedShowsApproval = hasNonEmptyModalButtons(parsedRecord?.activeModal) && parsedRecord?.status === "waiting_approval";
9994
10004
  const status = parsedRecord ? {
9995
10005
  ...parsedRecord,
9996
10006
  messages: shouldPreferAdapterMessages ? adapterStatus.messages : parsedRecord.messages,
9997
- status: adapterStatus.status !== "idle" ? adapterStatus.status : parsedRecord.status || adapterStatus.status,
10007
+ status: parsedShowsApproval ? parsedRecord.status : adapterStatus.status !== "idle" ? adapterStatus.status : parsedRecord.status || adapterStatus.status,
9998
10008
  activeModal: parsedRecord.activeModal || adapterStatus.activeModal
9999
10009
  } : adapterStatus;
10000
10010
  const title = typeof parsedRecord?.title === "string" ? parsedRecord.title : void 0;
@@ -18169,6 +18179,10 @@ var DaemonStatusReporter = class {
18169
18179
  }
18170
18180
  }
18171
18181
  onStatusChange() {
18182
+ if (this.deps.p2p?.isConnected) {
18183
+ this.resetP2PHash();
18184
+ this.sendUnifiedStatusReport({ p2pOnly: true, reason: "status-change" }).catch((e) => LOG.warn("Status", `Immediate P2P status send failed: ${e?.message}`));
18185
+ }
18172
18186
  this.throttledReport();
18173
18187
  }
18174
18188
  throttledReport() {
@@ -18266,10 +18280,12 @@ var DaemonStatusReporter = class {
18266
18280
  }
18267
18281
  async sendUnifiedStatusReport(opts) {
18268
18282
  const { serverConn, p2p } = this.deps;
18269
- if (!serverConn?.isConnected()) return;
18283
+ const serverConnected = !!serverConn?.isConnected();
18284
+ const p2pConnected = !!p2p?.isConnected;
18285
+ if (!serverConnected && !p2pConnected) return;
18270
18286
  this.lastStatusSentAt = Date.now();
18271
18287
  const now = this.lastStatusSentAt;
18272
- const target = opts?.p2pOnly ? "P2P" : "P2P+Server";
18288
+ const target = opts?.p2pOnly ? "P2P" : serverConnected ? "P2P+Server" : "P2P";
18273
18289
  const allStates = this.deps.instanceManager.collectAllStates();
18274
18290
  const ideStates = allStates.filter((s) => s.category === "ide");
18275
18291
  const cliStates = allStates.filter((s) => s.category === "cli");
@@ -18348,6 +18364,7 @@ var DaemonStatusReporter = class {
18348
18364
  ...wsPayload,
18349
18365
  timestamp: void 0
18350
18366
  }));
18367
+ if (!serverConnected || !serverConn) return;
18351
18368
  if (!opts?.forceServer && wsHash === this.lastServerStatusHash) {
18352
18369
  LOG.debug("Server", `skip duplicate status_report${opts?.reason ? ` (${opts.reason})` : ""}`);
18353
18370
  return;