@adhdev/daemon-core 0.9.82-rc.100 → 0.9.82-rc.101

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.9.82-rc.100",
3
+ "version": "0.9.82-rc.101",
4
4
  "description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1372,6 +1372,11 @@ export class ProviderCliAdapter implements CliAdapter {
1372
1372
  this.idleTimeout = setTimeout(() => {
1373
1373
  if (this.isWaitingForResponse && !this.hasActionableApproval()) {
1374
1374
  if (this.shouldDeferIdleTimeoutFinish()) return;
1375
+ const parsed = this.runParseSession();
1376
+ if (this.shouldKeepCodexTurnOpenForFinish(parsed)) {
1377
+ this.rescheduleCodexFinishCheck('codex_idle_timeout_not_final');
1378
+ return;
1379
+ }
1375
1380
  this.clearIdleFinishCandidate('idle_timeout_finish');
1376
1381
  this.finishResponse();
1377
1382
  }
@@ -1381,6 +1386,11 @@ export class ProviderCliAdapter implements CliAdapter {
1381
1386
  private finishResponse(): void {
1382
1387
  if (this.submitPendingUntil > Date.now()) return;
1383
1388
  if (this.responseSettleIgnoreUntil > Date.now()) return;
1389
+ const parsedBeforeFinish = this.runParseSession();
1390
+ if (this.shouldKeepCodexTurnOpenForFinish(parsedBeforeFinish)) {
1391
+ this.rescheduleCodexFinishCheck('codex_finish_not_final');
1392
+ return;
1393
+ }
1384
1394
  this.clearIdleFinishCandidate('finish_response_enter');
1385
1395
  this.recordTrace('finish_response', {
1386
1396
  ...buildCliTraceParseSnapshot({
@@ -1618,6 +1628,49 @@ export class ProviderCliAdapter implements CliAdapter {
1618
1628
  return !!lastAssistant;
1619
1629
  }
1620
1630
 
1631
+ private parsedStatusHasFinalStandardAssistantMessage(parsed: any): boolean {
1632
+ const messages = Array.isArray(parsed?.messages) ? parsed.messages : [];
1633
+ const lastAssistant = [...messages].reverse().find((message: any) => {
1634
+ if (!message || message.role !== 'assistant') return false;
1635
+ return typeof message.content === 'string' && message.content.trim().length > 0;
1636
+ });
1637
+ if (!lastAssistant) return false;
1638
+ const kind = typeof lastAssistant.kind === 'string' && lastAssistant.kind.trim()
1639
+ ? lastAssistant.kind.trim()
1640
+ : 'standard';
1641
+ return kind === 'standard' && lastAssistant.meta?.streaming !== true;
1642
+ }
1643
+
1644
+ private shouldKeepCodexTurnOpenForFinish(parsed: any): boolean {
1645
+ if (this.cliType !== 'codex-cli') return false;
1646
+ if (!this.isWaitingForResponse || !this.currentTurnScope || this.hasActionableApproval()) return false;
1647
+ const parsedStatus = typeof parsed?.status === 'string' ? parsed.status.trim() : '';
1648
+ if (parsedStatus !== 'idle') return true;
1649
+ if (parsed?.activeModal || parsed?.modal) return true;
1650
+ return !this.parsedStatusHasFinalStandardAssistantMessage(parsed);
1651
+ }
1652
+
1653
+ private rescheduleCodexFinishCheck(reason: string): void {
1654
+ this.clearIdleFinishCandidate(reason);
1655
+ this.setStatus('generating', reason);
1656
+ if (this.idleTimeout) clearTimeout(this.idleTimeout);
1657
+ this.idleTimeout = setTimeout(() => {
1658
+ if (!this.isWaitingForResponse || this.hasActionableApproval()) return;
1659
+ this.settledBuffer = this.recentOutputBuffer;
1660
+ this.evaluateSettled();
1661
+ }, this.getIdleFinishConfirmMs());
1662
+ this.recordTrace('codex_finish_deferred', {
1663
+ reason,
1664
+ ...buildCliTraceParseSnapshot({
1665
+ accumulatedBuffer: this.accumulatedBuffer,
1666
+ accumulatedRawBuffer: this.accumulatedRawBuffer,
1667
+ responseBuffer: this.responseBuffer,
1668
+ partialResponse: this.responseBuffer,
1669
+ scope: this.currentTurnScope,
1670
+ }),
1671
+ });
1672
+ }
1673
+
1621
1674
  private projectEffectiveStatus(startupModal: { message: string; buttons: string[] } | null = null): CliSessionStatus['status'] {
1622
1675
  if (this.parseErrorMessage) return 'error';
1623
1676
  if (this.hasActionableApproval(startupModal)) return 'waiting_approval';
@@ -1726,6 +1779,12 @@ export class ProviderCliAdapter implements CliAdapter {
1726
1779
  }),
1727
1780
  activeModal,
1728
1781
  providerSessionId: typeof (parsed as any).providerSessionId === 'string' ? (parsed as any).providerSessionId : undefined,
1782
+ errorMessage: typeof (parsed as any).errorMessage === 'string' && (parsed as any).errorMessage.trim()
1783
+ ? (parsed as any).errorMessage.trim()
1784
+ : undefined,
1785
+ errorReason: typeof (parsed as any).errorReason === 'string' && (parsed as any).errorReason.trim()
1786
+ ? (parsed as any).errorReason.trim()
1787
+ : undefined,
1729
1788
  ...(bufferState ? { bufferState } : {}),
1730
1789
  ...((parsed as any).transcriptAuthority === 'provider' || (parsed as any).transcriptAuthority === 'daemon'
1731
1790
  ? { transcriptAuthority: (parsed as any).transcriptAuthority }
@@ -2596,6 +2655,9 @@ export class ProviderCliAdapter implements CliAdapter {
2596
2655
  const parsedDebugState = this.getParsedDebugState();
2597
2656
  const parsedMessages = Array.isArray(parsedDebugState?.messages) ? parsedDebugState.messages : [];
2598
2657
  let effectiveStatus = this.projectEffectiveStatus(startupModal);
2658
+ if (parsedDebugState?.status === 'error') {
2659
+ effectiveStatus = 'error';
2660
+ }
2599
2661
  if (startupDetectedStatus === 'waiting_approval') {
2600
2662
  effectiveStatus = 'waiting_approval';
2601
2663
  }
@@ -2627,6 +2689,8 @@ export class ProviderCliAdapter implements CliAdapter {
2627
2689
  providerSessionId: parsedDebugState.providerSessionId,
2628
2690
  transcriptAuthority: parsedDebugState.transcriptAuthority,
2629
2691
  coverage: parsedDebugState.coverage,
2692
+ errorMessage: parsedDebugState.errorMessage,
2693
+ errorReason: parsedDebugState.errorReason,
2630
2694
  activeModal: parsedDebugState.activeModal,
2631
2695
  messageCount: parsedMessages.length,
2632
2696
  } : null,
@@ -497,8 +497,14 @@ export class CliProviderInstance implements ProviderInstance {
497
497
  if (typeof this.adapter.getScriptParsedStatus === 'function') {
498
498
  try {
499
499
  parsedStatus = this.adapter.getScriptParsedStatus() || null;
500
- this.errorMessage = undefined;
501
- this.errorReason = undefined;
500
+ const parsedErrorMessage = typeof parsedStatus?.errorMessage === 'string' && parsedStatus.errorMessage.trim()
501
+ ? parsedStatus.errorMessage.trim()
502
+ : undefined;
503
+ const parsedErrorReason = typeof parsedStatus?.errorReason === 'string' && parsedStatus.errorReason.trim()
504
+ ? parsedStatus.errorReason.trim() as ProviderErrorReason
505
+ : undefined;
506
+ this.errorMessage = parsedErrorMessage;
507
+ this.errorReason = parsedErrorReason;
502
508
  } catch (error: any) {
503
509
  parseErrorMessage = error?.message || String(error);
504
510
  this.errorMessage = parseErrorMessage;
@@ -509,7 +515,7 @@ export class CliProviderInstance implements ProviderInstance {
509
515
  this.errorReason = undefined;
510
516
  }
511
517
  const autoApproveActive = this.maybeAutoApproveStatus(adapterStatus, Date.now());
512
- const visibleStatus = parseErrorMessage
518
+ const visibleStatus = parseErrorMessage || parsedStatus?.status === 'error'
513
519
  ? 'error'
514
520
  : (autoApproveActive ? 'generating' : adapterStatus.status);
515
521
  const parsedProviderSessionId = normalizeProviderSessionId(