@adhdev/daemon-core 0.9.82-rc.431 → 0.9.82-rc.433

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.
@@ -1199,6 +1199,50 @@ export class CliProviderInstance implements ProviderInstance {
1199
1199
  return this.resolveModalParkStatus() !== null;
1200
1200
  }
1201
1201
 
1202
+ /**
1203
+ * PTY-OVERTRUST-DRAIN (Defect B). The deliverability/drain status the mesh
1204
+ * reconcile loop must consult — the RAW adapter turn-state, with the
1205
+ * auto-approve "hold-idle" visual mask STRIPPED.
1206
+ *
1207
+ * getState().status overlays `autoApproveHoldIdle`/`autoApproveActive` to paint a
1208
+ * genuinely-idle adapter as `generating` (a UI-flicker suppression while an
1209
+ * auto-approve key-press settles — see getState() ~:800). That mask is correct
1210
+ * for the dashboard, but the reconcile loop trusts it as "the coordinator is
1211
+ * busy" and therefore HOLDS a worker's completion under
1212
+ * `generating_no_idle_coordinator` even though the coordinator's PTY is at a real
1213
+ * turn end and would accept the inject as a turn — the completion is stranded.
1214
+ *
1215
+ * This accessor reports the drain truth instead:
1216
+ * - 'modal_parked' — a GENUINE human-await modal (AskUserQuestion / a non-
1217
+ * transient tool-consent). Still excluded from drain (a force-inject here
1218
+ * writes raw keystrokes the modal eats → data corruption). Mirrors
1219
+ * isModalParked(), evaluated first so a parked session never reads idle.
1220
+ * - 'idle' — the RAW adapter is at a turn end (adapter.getStatus(allowParse:false)
1221
+ * === 'idle') and the session is not modal-parked. Drain-eligible REGARDLESS
1222
+ * of the auto-approve mask. This is the case the mask used to hide.
1223
+ * - 'generating' — the raw adapter is genuinely mid-turn. Held (a raw PTY write
1224
+ * into a generating claude-cli is not consumed as a turn → data loss). The
1225
+ * intentional removal of force-inject-into-generating is preserved.
1226
+ * - 'other' — any other raw status (error / starting / waiting_choice handled by
1227
+ * modal-park above). Not a drain target.
1228
+ *
1229
+ * Uses allowParse:false (engine.activeModal only, side-effect-free) so it never
1230
+ * mutates the very auto-approve mask state the diagnostics read.
1231
+ */
1232
+ getDrainStatus(): 'idle' | 'generating' | 'modal_parked' | 'other' {
1233
+ if (this.isModalParked()) return 'modal_parked';
1234
+ let rawStatus: string;
1235
+ try {
1236
+ const raw = this.adapter.getStatus({ allowParse: false })?.status;
1237
+ rawStatus = typeof raw === 'string' ? raw.trim() : '';
1238
+ } catch {
1239
+ return 'other';
1240
+ }
1241
+ if (rawStatus === 'idle') return 'idle';
1242
+ if (isCliGeneratingLikeStatus(rawStatus)) return 'generating';
1243
+ return 'other';
1244
+ }
1245
+
1202
1246
  onEvent(event: string, data?: any): void {
1203
1247
  if (event === 'send_message') {
1204
1248
  const input = normalizeInputEnvelope(data);