@adhdev/daemon-core 0.8.88 → 0.8.89

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/session-host-core",
3
- "version": "0.8.88",
3
+ "version": "0.8.89",
4
4
  "description": "ADHDev local session host core \u2014 session registry, protocol, buffers",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.8.88",
3
+ "version": "0.8.89",
4
4
  "description": "ADHDev daemon core \u2014 CDP, IDE detection, providers, command execution",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -804,9 +804,7 @@ export class ProviderCliAdapter implements CliAdapter {
804
804
  const buttons = Array.isArray(modal.buttons) ? modal.buttons : [];
805
805
  if (buttons.length !== 1) return false;
806
806
  const buttonLabel = String(buttons[0] || '').trim();
807
- const modalText = `${modal.message || ''} ${buttonLabel}`.trim();
808
- return looksLikeConfirmOnlyLabel(buttonLabel)
809
- || /Quick safety check|project trust|trust (?:this project|the contents of this directory|the files in this folder)|Enter to confirm/i.test(modalText);
807
+ return looksLikeConfirmOnlyLabel(buttonLabel);
810
808
  }
811
809
 
812
810
  private async waitForInteractivePrompt(maxWaitMs = 5000): Promise<void> {
@@ -1466,11 +1464,16 @@ export class ProviderCliAdapter implements CliAdapter {
1466
1464
  // ─── Public API (CliAdapter) ───────────────────
1467
1465
 
1468
1466
  getStatus(): CliSessionStatus {
1467
+ const screenText = this.terminalScreen.getText() || '';
1468
+ const startupModal = this.startupParseGate ? this.getStartupConfirmationModal(screenText) : null;
1469
+ const effectiveStatus = this.parseErrorMessage
1470
+ ? 'error'
1471
+ : (startupModal ? 'waiting_approval' : this.currentStatus);
1469
1472
  return {
1470
- status: this.parseErrorMessage ? 'error' : this.currentStatus,
1473
+ status: effectiveStatus,
1471
1474
  messages: [...this.committedMessages],
1472
1475
  workingDir: this.workingDir,
1473
- activeModal: this.activeModal,
1476
+ activeModal: startupModal || this.activeModal,
1474
1477
  errorMessage: this.parseErrorMessage || undefined,
1475
1478
  errorReason: this.parseErrorMessage ? 'parse_error' : undefined,
1476
1479
  };
@@ -1551,12 +1554,21 @@ export class ProviderCliAdapter implements CliAdapter {
1551
1554
  : message.timestamp,
1552
1555
  }));
1553
1556
  const parsedLastAssistant = [...parsedHydratedMessages].reverse().find((message) => message.role === 'assistant' && typeof message.content === 'string' && message.content.trim());
1557
+ const visibleIdlePrompt = this.looksLikeVisibleIdlePrompt(screenText);
1554
1558
  const shouldAdoptParsedIdleReplay =
1555
1559
  !this.currentTurnScope
1556
1560
  && !this.activeModal
1557
- && this.currentStatus === 'idle'
1561
+ && !!parsedLastAssistant
1558
1562
  && parsedHydratedMessages.length > committedHydratedMessages.length
1559
- && !!parsedLastAssistant;
1563
+ && (
1564
+ this.currentStatus === 'idle'
1565
+ || (
1566
+ this.currentStatus === 'generating'
1567
+ && this.isWaitingForResponse
1568
+ && parsed.status === 'idle'
1569
+ && visibleIdlePrompt
1570
+ )
1571
+ );
1560
1572
  if (shouldAdoptParsedIdleReplay) {
1561
1573
  this.committedMessages = normalizeCliParsedMessages(parsed.messages, {
1562
1574
  committedMessages: this.committedMessages,
@@ -1564,6 +1576,18 @@ export class ProviderCliAdapter implements CliAdapter {
1564
1576
  lastOutputAt: this.lastOutputAt,
1565
1577
  });
1566
1578
  this.syncMessageViews();
1579
+ if (this.currentStatus !== 'idle' || this.isWaitingForResponse) {
1580
+ this.responseBuffer = '';
1581
+ this.isWaitingForResponse = false;
1582
+ this.responseSettleIgnoreUntil = 0;
1583
+ this.submitRetryUsed = false;
1584
+ this.submitRetryPromptSnippet = '';
1585
+ this.finishRetryCount = 0;
1586
+ this.currentTurnScope = null;
1587
+ this.activeModal = null;
1588
+ this.setStatus('idle', 'parsed_idle_replay_commit');
1589
+ this.onStatusChange?.();
1590
+ }
1567
1591
  }
1568
1592
  const effectiveCommittedHydratedMessages = shouldAdoptParsedIdleReplay
1569
1593
  ? this.committedMessages.map((message, index) => buildChatMessage({
@@ -2160,8 +2184,9 @@ export class ProviderCliAdapter implements CliAdapter {
2160
2184
  }
2161
2185
 
2162
2186
  resolveModal(buttonIndex: number): void {
2163
- if (!this.ptyProcess || (this.currentStatus !== 'waiting_approval' && !this.activeModal)) return;
2164
- const modal = this.activeModal;
2187
+ const screenText = this.terminalScreen.getText() || '';
2188
+ const modal = this.activeModal || this.getStartupConfirmationModal(screenText);
2189
+ if (!this.ptyProcess || ((this.currentStatus !== 'waiting_approval') && !modal)) return;
2165
2190
  this.clearIdleFinishCandidate('resolve_modal');
2166
2191
  this.recordTrace('resolve_modal', {
2167
2192
  buttonIndex,
@@ -2176,7 +2201,10 @@ export class ProviderCliAdapter implements CliAdapter {
2176
2201
  }
2177
2202
  this.setStatus('generating', 'approval_resolved');
2178
2203
  this.onStatusChange?.();
2179
- if (this.shouldResolveModalWithEnter(modal, buttonIndex)) {
2204
+ 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 || ''));
2205
+ if (startupTrustModal && buttonIndex in this.approvalKeys) {
2206
+ this.ptyProcess.write(`${this.approvalKeys[buttonIndex]}\r`);
2207
+ } else if (this.shouldResolveModalWithEnter(modal, buttonIndex)) {
2180
2208
  this.ptyProcess.write('\r');
2181
2209
  } else if (buttonIndex in this.approvalKeys) {
2182
2210
  this.ptyProcess.write(this.approvalKeys[buttonIndex]);
@@ -2198,20 +2226,24 @@ export class ProviderCliAdapter implements CliAdapter {
2198
2226
  }
2199
2227
 
2200
2228
  getDebugState(): Record<string, any> {
2229
+ const screenText = sanitizeTerminalText(this.terminalScreen.getText());
2230
+ const startupModal = this.startupParseGate ? this.getStartupConfirmationModal(screenText) : null;
2231
+ const effectiveStatus = startupModal ? 'waiting_approval' : this.currentStatus;
2232
+ const effectiveReady = this.ready || !!startupModal;
2201
2233
  return {
2202
2234
  type: this.cliType,
2203
2235
  name: this.cliName,
2204
2236
  providerResolution: this.providerResolutionMeta,
2205
- status: this.currentStatus,
2206
- ready: this.ready,
2237
+ status: effectiveStatus,
2238
+ ready: effectiveReady,
2207
2239
  startupParseGate: this.startupParseGate,
2208
2240
  spawnAt: this.spawnAt,
2209
2241
  workingDir: this.workingDir,
2210
- messages: this.messages.slice(-20),
2211
- committedMessages: this.committedMessages.slice(-20),
2212
- structuredMessages: this.structuredMessages.slice(-20),
2242
+ messages: this.messages,
2243
+ committedMessages: this.committedMessages,
2244
+ structuredMessages: this.structuredMessages,
2213
2245
  messageCount: this.committedMessages.length,
2214
- screenText: sanitizeTerminalText(this.terminalScreen.getText()).slice(-4000),
2246
+ screenText: screenText.slice(-4000),
2215
2247
  currentTurnScope: this.currentTurnScope,
2216
2248
  startupBuffer: this.startupBuffer.slice(-4000),
2217
2249
  recentOutputBuffer: this.recentOutputBuffer.slice(-500),
@@ -2226,7 +2258,7 @@ export class ProviderCliAdapter implements CliAdapter {
2226
2258
  lastScreenChangeAt: this.lastScreenChangeAt,
2227
2259
  lastScreenSnapshot: this.lastScreenSnapshot.slice(-500),
2228
2260
  isWaitingForResponse: this.isWaitingForResponse,
2229
- activeModal: this.activeModal,
2261
+ activeModal: startupModal || this.activeModal,
2230
2262
  lastApprovalResolvedAt: this.lastApprovalResolvedAt,
2231
2263
  sendDelayMs: this.sendDelayMs,
2232
2264
  sendKey: this.sendKey,