@adhdev/daemon-core 0.9.82-rc.532 → 0.9.82-rc.533

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.532",
3
+ "version": "0.9.82-rc.533",
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",
@@ -47,8 +47,8 @@
47
47
  "author": "vilmire",
48
48
  "license": "AGPL-3.0-or-later",
49
49
  "dependencies": {
50
- "@adhdev/mesh-shared": "0.9.82-rc.532",
51
- "@adhdev/session-host-core": "0.9.82-rc.532",
50
+ "@adhdev/mesh-shared": "0.9.82-rc.533",
51
+ "@adhdev/session-host-core": "0.9.82-rc.533",
52
52
  "@agentclientprotocol/sdk": "^0.16.1",
53
53
  "ajv": "^8.20.0",
54
54
  "ajv-formats": "^3.0.1",
@@ -787,8 +787,8 @@ export class ProviderCliAdapter implements CliAdapter {
787
787
  if (stableMs < 2000) return;
788
788
 
789
789
  const startupModal = this.runParseApproval(this.recentOutputBuffer);
790
- const startupStatus = this.runDetectStatus(screenText || this.recentOutputBuffer);
791
- if (!startupModal && startupStatus !== 'idle') {
790
+ const startupIdle = this.detectIdleHonoringOnNoMatch(screenText || this.recentOutputBuffer);
791
+ if (!startupModal && !startupIdle) {
792
792
  this.scheduleStartupSettleCheck();
793
793
  return;
794
794
  }
@@ -937,6 +937,43 @@ export class ProviderCliAdapter implements CliAdapter {
937
937
  });
938
938
  }
939
939
 
940
+ /**
941
+ * WRITE-READINESS ONNOMATCH (opencode): resolve whether the session is
942
+ * genuinely idle *for the purpose of opening the PTY write gate*, honoring
943
+ * the manifest's `dispatchOrder.onNoMatch` policy.
944
+ *
945
+ * The split-brain this closes: the engine's settled evaluation runs
946
+ * detectStatus through parseSession, whose builder collapses a null verdict
947
+ * to `'idle'` (buildParseSessionFromTui: `detectStatus(input) ?? 'idle'`),
948
+ * so the dashboard status flips to idle via `script_detect`. But the
949
+ * write-readiness gates (resolveStartupState / sendMessage recovery) call
950
+ * `runDetectStatus` *directly* and require the literal `=== 'idle'` return —
951
+ * they never apply the `onNoMatch` policy. opencode's only idle cue is the
952
+ * `Ask anything` composer placeholder in the last-8-lines scope with
953
+ * `onNoMatch: preserve-last`; when that placeholder is momentarily out of
954
+ * frame the raw detector returns null, the gate stays shut, `this.ready`
955
+ * never flips, and the first queued prompt sits in `not_ready_pending_prompt`
956
+ * forever (no turn ever starts, so no turn-completion drain fires).
957
+ *
958
+ * The fix keeps the raw detector as the primary signal (unchanged behavior
959
+ * for providers whose detector returns a literal idle) and only falls back
960
+ * when BOTH (a) the manifest policy is idle-preserving (`preserve-last` or
961
+ * `idle`) AND (b) the engine has *durably* settled to idle (no in-flight
962
+ * turn, no modal, no parse error). That guard makes the fallback safe: it
963
+ * cannot open the gate mid-turn or while a modal is up.
964
+ */
965
+ private detectIdleHonoringOnNoMatch(text: string): boolean {
966
+ if (this.runDetectStatus(text) === 'idle') return true;
967
+ const dispatchOrder = (this.provider.tui as { dispatchOrder?: { onNoMatch?: unknown } } | undefined)?.dispatchOrder;
968
+ const onNoMatch = dispatchOrder?.onNoMatch;
969
+ if (onNoMatch !== 'preserve-last' && onNoMatch !== 'idle') return false;
970
+ return this.engine.currentStatus === 'idle'
971
+ && !this.engine.isWaitingForResponse
972
+ && !this.engine.currentTurnScope
973
+ && !this.engine.activeModal
974
+ && !this.parseErrorMessage;
975
+ }
976
+
940
977
  runParseApproval(tail: string): { message: string; buttons: string[] } | null {
941
978
  const screenText = this.terminalScreen.getText();
942
979
  const buffer = screenText || this.accumulatedBuffer;
@@ -1706,7 +1743,7 @@ export class ProviderCliAdapter implements CliAdapter {
1706
1743
  }
1707
1744
  if (!this.ready) {
1708
1745
  this.resolveStartupState('send_precheck');
1709
- if (this.runDetectStatus(this.recentOutputBuffer) === 'idle') {
1746
+ if (!this.ready && this.detectIdleHonoringOnNoMatch(this.recentOutputBuffer)) {
1710
1747
  this.ready = true;
1711
1748
  this.startupParseGate = false;
1712
1749
  this.engine.setStatus('idle', 'send_message_idle_prompt_recovery');