@adhdev/daemon-core 1.0.28-rc.15 → 1.0.28-rc.17

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
@@ -786,10 +786,10 @@ function readInjected(value) {
786
786
  }
787
787
  function getDaemonBuildInfo() {
788
788
  if (cached) return cached;
789
- const commit = readInjected(true ? "3c6684c9e2549bf7ab1508195857595a89ae9ec1" : void 0) ?? "unknown";
790
- const commitShort = readInjected(true ? "3c6684c" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
791
- const version = readInjected(true ? "1.0.28-rc.15" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
792
- const builtAt = readInjected(true ? "2026-07-26T13:11:34.159Z" : void 0);
789
+ const commit = readInjected(true ? "9452bd039720355425e62fc7469808a0dda3ab80" : void 0) ?? "unknown";
790
+ const commitShort = readInjected(true ? "9452bd03" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
791
+ const version = readInjected(true ? "1.0.28-rc.17" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
792
+ const builtAt = readInjected(true ? "2026-07-27T01:42:15.160Z" : void 0);
793
793
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
794
794
  return cached;
795
795
  }
@@ -16439,6 +16439,31 @@ var init_debug_trace = __esm({
16439
16439
  function recordSynthCompletionGateTrace(stage, payload) {
16440
16440
  recordDebugTrace({ category: "completion-gate", stage, level: "debug", payload });
16441
16441
  }
16442
+ function evaluateTranscriptSynthAdmission(admission) {
16443
+ if (!admission) return { admitted: true };
16444
+ if (admission.trailingToolActivityAfterFinalAssistant === true) {
16445
+ return { admitted: false, reason: "trailing_tool_activity_after_final_assistant" };
16446
+ }
16447
+ if (!admission.boundedBackstop && typeof admission.liveTurnPendingEvidence === "function") {
16448
+ let pending = false;
16449
+ try {
16450
+ pending = admission.liveTurnPendingEvidence() === true;
16451
+ } catch {
16452
+ }
16453
+ if (pending) return { admitted: false, reason: "live_turn_pending_evidence" };
16454
+ }
16455
+ return { admitted: true };
16456
+ }
16457
+ function resolveLiveTurnPendingEvidence(components, sessionId) {
16458
+ try {
16459
+ const instance = components?.instanceManager?.getInstance?.(sessionId);
16460
+ if (typeof instance?.hasLiveTurnPendingEvidence !== "function") return void 0;
16461
+ const probe = instance.hasLiveTurnPendingEvidence.bind(instance);
16462
+ return () => probe();
16463
+ } catch {
16464
+ return void 0;
16465
+ }
16466
+ }
16442
16467
  function findRecentTerminalLedgerEvidence(args) {
16443
16468
  if (!args.sessionId && !args.nodeId) return null;
16444
16469
  const entries = readLedgerEntries(args.meshId, { tail: 200 });
@@ -16559,6 +16584,17 @@ function reconcileDirectDispatchCompletionFromTranscript(args) {
16559
16584
  })) {
16560
16585
  return { reconciled: false, alreadyTerminal: true, reason: "terminal_ledger_entry_exists" };
16561
16586
  }
16587
+ const admission = evaluateTranscriptSynthAdmission(args.causalAdmission);
16588
+ if (!admission.admitted) {
16589
+ LOG.info("MeshEvents", `Transcript synth vetoed for task ${args.taskId} session ${args.sessionId} (source ${args.source || "direct_task_transcript_reconciliation"}): ${admission.reason} \u2014 holding the completion; it re-evaluates on the next reconcile pass`);
16590
+ recordSynthCompletionGateTrace("synth-veto", {
16591
+ producer: "transcript_reconcile",
16592
+ source: args.source || "direct_task_transcript_reconciliation",
16593
+ taskId: args.taskId,
16594
+ reason: admission.reason
16595
+ });
16596
+ return { reconciled: false, reason: admission.reason };
16597
+ }
16562
16598
  const nodeId = readNonEmptyString(args.nodeId) || dispatch?.nodeId;
16563
16599
  const providerType = readNonEmptyString(args.providerType) || dispatch?.providerType || readNonEmptyString(dispatch?.payload.providerType);
16564
16600
  const completedAt = args.completedAt || (/* @__PURE__ */ new Date()).toISOString();
@@ -16720,6 +16756,7 @@ var init_mesh_events_stale = __esm({
16720
16756
  init_mesh_events_pending();
16721
16757
  init_mesh_events_utils();
16722
16758
  init_debug_trace();
16759
+ init_logger();
16723
16760
  init_dist();
16724
16761
  DIRECT_DISPATCH_RECONCILE_GRACE_MS = 6e4;
16725
16762
  DIRECT_DISPATCH_IDLE_SESSION_RECONCILE_GRACE_MS = 12e4;
@@ -19751,6 +19788,9 @@ function nodeHasActiveMeshWork(components, meshId, nodeId, currentSessionId) {
19751
19788
  }
19752
19789
  function isLaunchableNode(node) {
19753
19790
  if (!node || node.status === "disabled" || node.status === "removed") return false;
19791
+ if (shouldDeferDispatchForBootstrap(node)) {
19792
+ return false;
19793
+ }
19754
19794
  return isMeshNodeHealthLaunchable(node);
19755
19795
  }
19756
19796
  function isLocalAutoLaunchNode(node) {
@@ -22987,8 +23027,27 @@ function resolveActiveDirectDispatchTaskId(meshId, sessionId) {
22987
23027
  return void 0;
22988
23028
  }
22989
23029
  }
23030
+ function findInWindowUnclaimedAutoLaunchTask(meshId, sessionId, nowMs) {
23031
+ return getQueue(meshId, { status: ["pending"] }).find((task) => {
23032
+ const al = task.autoLaunch;
23033
+ if (!al || al.status !== "completed" || !al.sessionId) return false;
23034
+ if (!sessionIdsEquivalent(al.sessionId, sessionId)) return false;
23035
+ const launchedAtMs = Date.parse(al.updatedAt);
23036
+ return Number.isFinite(launchedAtMs) && nowMs - launchedAtMs < AUTO_LAUNCH_AWAIT_CLAIM_MS;
23037
+ });
23038
+ }
23039
+ function hasMatchingTaskDispatchedLedgerEntry(meshId, taskId, sessionId) {
23040
+ const entries = readLedgerEntries(meshId, { tail: 200 });
23041
+ for (let i = entries.length - 1; i >= 0; i--) {
23042
+ const entry = entries[i];
23043
+ if (entry.kind !== "task_dispatched") continue;
23044
+ if (!sessionIdsEquivalent(entry.sessionId, sessionId)) continue;
23045
+ if (readNonEmptyString(entry.payload?.taskId) === taskId) return true;
23046
+ }
23047
+ return false;
23048
+ }
22990
23049
  function evaluateMeshEventSuppression(args, ctx) {
22991
- const { traceCtx, eventSessionId, eventNodeId, eventTimestamp, workerCoordinatorDaemonId } = ctx;
23050
+ const { traceCtx, eventSessionId, eventNodeId, eventTimestamp, workerCoordinatorDaemonId, components } = ctx;
22992
23051
  const intentionalCleanupStop = shouldSuppressIntentionalCleanupStop({
22993
23052
  event: args.event,
22994
23053
  meshId: args.meshId,
@@ -23055,6 +23114,42 @@ function evaluateMeshEventSuppression(args, ctx) {
23055
23114
  }
23056
23115
  }
23057
23116
  if (args.event === "agent:generating_completed" && eventSessionId) {
23117
+ const liveInstance = components.instanceManager?.getInstance?.(eventSessionId);
23118
+ if (typeof liveInstance?.hasLiveTurnPendingEvidence === "function") {
23119
+ let midTurnPending = false;
23120
+ try {
23121
+ midTurnPending = liveInstance.hasLiveTurnPendingEvidence() === true;
23122
+ } catch {
23123
+ }
23124
+ if (midTurnPending) {
23125
+ LOG.info("MeshEvents", `Suppressed agent:generating_completed for session ${eventSessionId} (mesh ${args.meshId}): live adapter re-check shows the turn is still pending (mid-tool / streaming / modal) \u2014 treating as a premature/redraw-race emit; the adapter's own finalization retry or the reconcile loop's transcript evidence will surface the real completion`);
23126
+ traceMeshEventDrop("mid_turn_live_state_pending", traceCtx);
23127
+ return {
23128
+ kind: "suppress",
23129
+ result: { success: true, forwarded: 0, suppressed: true, midTurnLiveStatePending: true }
23130
+ };
23131
+ }
23132
+ }
23133
+ if (!readNonEmptyString(args.metadataEvent.taskId) && !sessionHasActiveAssignment(args.meshId, eventSessionId) && !findRecentTerminalLedgerEvidence({ meshId: args.meshId, sessionId: eventSessionId, nodeId: eventNodeId || void 0 }) && isWeakCompletionEvidence(args.metadataEvent)) {
23134
+ LOG.info("MeshEvents", `Suppressed agent:generating_completed for session ${eventSessionId} (mesh ${args.meshId}): no taskId, no active assignment, and no prior terminal ledger evidence \u2014 a pre-dispatch startup/greeting artifact, not a real task completion`);
23135
+ traceMeshEventDrop("no_dispatch_native_completion", traceCtx);
23136
+ return {
23137
+ kind: "suppress",
23138
+ result: { success: true, forwarded: 0, suppressed: true, noDispatchNativeCompletion: true }
23139
+ };
23140
+ }
23141
+ const inWindowTask = findInWindowUnclaimedAutoLaunchTask(args.meshId, eventSessionId, Date.now());
23142
+ if (inWindowTask) {
23143
+ const causalEvidence = MeshRuntimeStore.getInstance().taskDeliveryConsumed(args.meshId, inWindowTask.id) || hasMatchingTaskDispatchedLedgerEntry(args.meshId, inWindowTask.id, eventSessionId);
23144
+ if (!causalEvidence) {
23145
+ LOG.warn("MeshEvents", `Suppressed premature agent:generating_completed for auto-launch session ${eventSessionId} (mesh ${args.meshId}): task ${inWindowTask.id} delivery not yet consumed and no turn-start evidence \u2014 likely a boot artifact before the task was ever dispatched`);
23146
+ traceMeshEventDrop("autolaunch_completion_before_causal_evidence", traceCtx, `taskId=${inWindowTask.id}`);
23147
+ return {
23148
+ kind: "suppress",
23149
+ result: { success: true, forwarded: 0, suppressed: true, autoLaunchCausalGateFailed: true, taskId: inWindowTask.id }
23150
+ };
23151
+ }
23152
+ }
23058
23153
  const terminal = findRecentTerminalLedgerEvidence({
23059
23154
  meshId: args.meshId,
23060
23155
  sessionId: eventSessionId,
@@ -23287,7 +23382,8 @@ function injectMeshSystemMessage(components, args) {
23287
23382
  eventSessionId,
23288
23383
  eventNodeId,
23289
23384
  eventTimestamp,
23290
- workerCoordinatorDaemonId
23385
+ workerCoordinatorDaemonId,
23386
+ components
23291
23387
  });
23292
23388
  if (suppression) {
23293
23389
  if (suppression.kind === "reconcile") {
@@ -24798,6 +24894,18 @@ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds,
24798
24894
  }
24799
24895
  const messages = Array.isArray(payload.messages) ? payload.messages : [];
24800
24896
  const evidence = extractFinalAssistantSummaryEvidence(messages);
24897
+ if (hasTrailingToolActivityAfterFinalAssistant(messages)) {
24898
+ setHoldState(synthKey, mesh.id, { liveConfirmedSinceAck: true, consecutiveReadFailures: 0 });
24899
+ LOG.info("MeshReconcile", `Mid-turn causal admission: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) \u2014 the latest final-looking assistant bubble is followed by trailing tool/terminal activity (interim narration; the turn is still executing); holding the transcript synth`);
24900
+ traceMeshEventDrop("reconcile_synth_veto_trailing_tool_activity", {
24901
+ taskId,
24902
+ sessionId,
24903
+ nodeId,
24904
+ meshId: mesh.id,
24905
+ event: "agent:generating_completed"
24906
+ });
24907
+ continue;
24908
+ }
24801
24909
  if (isAcked) {
24802
24910
  const ackedAtMs = Date.parse(readNonEmptyString(dispatch.updatedAt));
24803
24911
  const sinceAckMs = Number.isFinite(ackedAtMs) ? nowMs - ackedAtMs : Number.POSITIVE_INFINITY;
@@ -24872,6 +24980,17 @@ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds,
24872
24980
  // The ledger-recovered dispatching-coordinator daemon (inside the reconcile fn)
24873
24981
  // takes PRIORITY over this arg; this remains the best-available fallback.
24874
24982
  ...coordinatorDaemonId ? { targetCoordinatorDaemonId: coordinatorDaemonId } : {},
24983
+ // MID-TURN-CAUSAL-ADMISSION (rc.16): pass the LOCAL live adapter's synchronous
24984
+ // turn-state probe into the unified choke point — a pending verdict vetoes this
24985
+ // eager synth (never-acked first-idle / acked fast-track). The death-deadline
24986
+ // backstop is the bounded max-wait net and overrides the veto (genuine-final
24987
+ // fail-open preserved); a remote/missing live source resolves to undefined and
24988
+ // fails open onto the bounded transcript evidence above. The trailing-tool veto
24989
+ // already ran at the top of this tick.
24990
+ causalAdmission: {
24991
+ liveTurnPendingEvidence: resolveLiveTurnPendingEvidence(components, sessionId),
24992
+ boundedBackstop: backstopKind === "ackedHoldDeathDeadlineFired"
24993
+ },
24875
24994
  source: "daemon_reconcile_transcript_completion"
24876
24995
  });
24877
24996
  if (result.reconciled) {
@@ -25317,10 +25436,10 @@ async function evaluateEarlyIdleTranscriptArm(components, mesh, store, row, loca
25317
25436
  if (profile) return profile.emitsPtyTurnEvents === false;
25318
25437
  return verdict === "UNKNOWN";
25319
25438
  }
25320
- function propagateWatchdogTranscriptCompletion(meshId, row, evidence, source) {
25439
+ function propagateWatchdogTranscriptCompletion(components, meshId, row, evidence, source, opts) {
25321
25440
  const sessionId = readNonEmptyString(row.assignedSessionId) || evidence.sessionId;
25322
25441
  if (!sessionId || !readNonEmptyString(evidence.finalSummary)) {
25323
- return false;
25442
+ return "unavailable";
25324
25443
  }
25325
25444
  try {
25326
25445
  const result = reconcileDirectDispatchCompletionFromTranscript({
@@ -25336,11 +25455,26 @@ function propagateWatchdogTranscriptCompletion(meshId, row, evidence, source) {
25336
25455
  // The watchdog poll already enforced idle + post-dispatch + no-trailing-tool + streak;
25337
25456
  // skip the reconcile's own grace/transcript_not_proven gates (dedup backstops remain).
25338
25457
  preValidatedTranscriptEvidence: true,
25458
+ // MID-TURN-CAUSAL-ADMISSION (rc.16): the transcript poll's structural evidence can
25459
+ // still straddle a genuinely mid-turn LOCAL worker (the incident shape: transcript
25460
+ // reads idle-with-final-assistant while the raw PTY is mid-tool). Route the live
25461
+ // adapter's synchronous probe through the unified choke point. The EARLY-IDLE
25462
+ // caller is an eager path (no opts) → a pending verdict defers; the redrive-deadline
25463
+ // caller passes boundedBackstop (the max-wait net) → the veto yields, preserving the
25464
+ // genuine-final fail-open semantics.
25465
+ causalAdmission: {
25466
+ liveTurnPendingEvidence: resolveLiveTurnPendingEvidence(components, sessionId),
25467
+ boundedBackstop: opts?.boundedBackstop === true
25468
+ },
25339
25469
  source
25340
25470
  });
25341
- return result.reconciled || result.alreadyTerminal === true;
25471
+ if (result.reconciled || result.alreadyTerminal === true) return "propagated";
25472
+ if (result.reason === "live_turn_pending_evidence" || result.reason === "trailing_tool_activity_after_final_assistant") {
25473
+ return "deferred";
25474
+ }
25475
+ return "unavailable";
25342
25476
  } catch {
25343
- return false;
25477
+ return "unavailable";
25344
25478
  }
25345
25479
  }
25346
25480
  async function recoverStrandedAssignedDispatches(components, mesh, store, localDaemonId, selfIds = []) {
@@ -25374,14 +25508,28 @@ async function recoverStrandedAssignedDispatches(components, mesh, store, localD
25374
25508
  minFinalAssistantAgeMs: ASSIGNED_IDLE_TRANSCRIPT_COMPLETE_MS
25375
25509
  });
25376
25510
  if (terminalEvidence) {
25377
- assignedIdleFinalAssistantSince.delete(idleTranscriptStreakKey);
25378
- updateTaskStatus(meshId, row.id, terminalEvidence.outcome);
25379
- const propagated = propagateWatchdogTranscriptCompletion(
25511
+ const propagation = propagateWatchdogTranscriptCompletion(
25512
+ components,
25380
25513
  meshId,
25381
25514
  row,
25382
25515
  terminalEvidence,
25383
25516
  "early_idle_transcript_evidence"
25384
25517
  );
25518
+ if (propagation === "deferred") {
25519
+ assignedIdleFinalAssistantSince.delete(idleTranscriptStreakKey);
25520
+ LOG.info("MeshReconcile", `Deferred early transcript completion for task ${row.id} on mesh ${meshId} (node=${row.assignedNodeId ?? "?"} session=${row.assignedSessionId ?? "?"}): the live adapter still reports the turn pending (mid-tool / streaming / modal) \u2014 holding; the completion re-evaluates next tick`);
25521
+ traceMeshEventDrop("early_idle_completion_deferred_live_pending", {
25522
+ taskId: row.id,
25523
+ sessionId: row.assignedSessionId,
25524
+ nodeId: row.assignedNodeId,
25525
+ meshId,
25526
+ event: "agent:generating_completed"
25527
+ });
25528
+ continue;
25529
+ }
25530
+ assignedIdleFinalAssistantSince.delete(idleTranscriptStreakKey);
25531
+ updateTaskStatus(meshId, row.id, terminalEvidence.outcome);
25532
+ const propagated = propagation === "propagated";
25385
25533
  if (!propagated && !findTerminalLedgerEvidenceForTask({ meshId, taskId: row.id })) {
25386
25534
  try {
25387
25535
  appendLedgerEntry(meshId, {
@@ -25556,12 +25704,15 @@ async function recoverStrandedAssignedDispatches(components, mesh, store, localD
25556
25704
  if (terminalEvidence) {
25557
25705
  deliveredNoTurnUnknownStreak.delete(streakKey);
25558
25706
  updateTaskStatus(meshId, row.id, terminalEvidence.outcome);
25559
- const propagated = propagateWatchdogTranscriptCompletion(
25707
+ const propagation = propagateWatchdogTranscriptCompletion(
25708
+ components,
25560
25709
  meshId,
25561
25710
  row,
25562
25711
  terminalEvidence,
25563
- "redrive_deadline_transcript_evidence"
25712
+ "redrive_deadline_transcript_evidence",
25713
+ { boundedBackstop: true }
25564
25714
  );
25715
+ const propagated = propagation === "propagated";
25565
25716
  if (!propagated && !findTerminalLedgerEvidenceForTask({ meshId, taskId: row.id })) {
25566
25717
  try {
25567
25718
  appendLedgerEntry(meshId, {
@@ -31100,7 +31251,9 @@ ${lastSnapshot}`;
31100
31251
  const requiredStreak = this.isAutonomousMeshSession() ? _ProviderCliAdapter.STATIC_IDLE_POLL_CONFIRM_COUNT : 1;
31101
31252
  this.staticIdlePollStreak += 1;
31102
31253
  if (this.staticIdlePollStreak >= requiredStreak) {
31103
- this.engine.confirmPollStaticIdle("poll_static_idle");
31254
+ if (this.engine.confirmPollStaticIdle("poll_static_idle")) {
31255
+ this.onStatusChange?.();
31256
+ }
31104
31257
  this.staticIdlePollStreak = 0;
31105
31258
  }
31106
31259
  } else {
@@ -51121,6 +51274,50 @@ var CliProviderInstance = class _CliProviderInstance {
51121
51274
  isModalParked() {
51122
51275
  return this.resolveModalParkStatus() !== null;
51123
51276
  }
51277
+ /**
51278
+ * MID-TURN-LIVE-STATE-GATE (broader false-idle RCA, mid-turn follow-up): a live,
51279
+ * synchronous re-check of whether this session's CURRENT turn genuinely still has
51280
+ * unresolved work. Public wrapper so the coordinator (mesh-event-forwarding) can
51281
+ * independently re-verify an incoming agent:generating_completed for a LOCAL session
51282
+ * before trusting it — defense-in-depth against a race where the completion emit and the
51283
+ * coordinator's receipt straddle a state change (screen-redraw parse artifact, decoupled-
51284
+ * immediate emit). Reuses the EXACT same discriminators this instance's own finalization
51285
+ * gate (getCompletedFinalizationBlock) uses — hasAdapterPendingResponse() (adapter
51286
+ * isWaitingForResponse / currentTurnScope / isProcessing() / a non-empty partial response)
51287
+ * OR isModalParked() (a live approval/choice modal) — so a session this method reports
51288
+ * pending is, by construction, one the local finalization gate would also refuse to
51289
+ * finalize right now.
51290
+ *
51291
+ * NATIVE-TRAILING-TOOL-GATE (rc.16 follow-up): the three adapter-state discriminators
51292
+ * above are blind to a background shell tool that keeps a turn alive without the adapter
51293
+ * reporting a pending response — e.g. a backgrounded `sleep 40 &` between narration
51294
+ * bubbles on a write-lag native-source provider (claude-cli), which is deliberately
51295
+ * un-floored (noExternalTranscriptSource omitted, mission f2f6da1b owner decision) so its
51296
+ * transcript write-lag emits promptly. That un-flooring is correct for the ordinary
51297
+ * fraction-of-a-second trail, but it also means the growth-hold / busy-lease protections
51298
+ * in getCompletedFinalizationBlock never engage for claude-cli, so an interim final-
51299
+ * LOOKING bubble followed by continuing tool calls can still finalize as a completion
51300
+ * while the transcript demonstrably shows the turn still executing. Close that gap here,
51301
+ * narrowly: for a native-source provider only, reuse the SAME bounded transcript read the
51302
+ * class's own completion judgment already performs (probeNativeTranscriptSignals) and
51303
+ * apply the SAME trailing-tool-activity veto the transcript-synth admission choke point
51304
+ * uses (hasTrailingToolActivityAfterFinalAssistant) — the latest final-looking assistant
51305
+ * bubble followed by tool/terminal activity is interim narration, not a turn end. Fail-open
51306
+ * by construction: a non-native-source class (probe returns null), an unresolved
51307
+ * transcript, or a read error never reaches the veto, so a missing/unavailable transcript
51308
+ * can never wedge a session as "pending" forever.
51309
+ */
51310
+ hasLiveTurnPendingEvidence() {
51311
+ if (this.hasAdapterPendingResponse() || this.isModalParked()) return true;
51312
+ try {
51313
+ const probe = this.probeNativeTranscriptSignals();
51314
+ if (probe?.snapshot?.available === true && Array.isArray(probe.messages)) {
51315
+ if (hasTrailingToolActivityAfterFinalAssistant(probe.messages)) return true;
51316
+ }
51317
+ } catch {
51318
+ }
51319
+ return false;
51320
+ }
51124
51321
  /**
51125
51322
  * PTY-OVERTRUST-DRAIN (Defect B). The deliverability/drain status the mesh
51126
51323
  * reconcile loop must consult — the RAW adapter turn-state, with the
@@ -51611,7 +51808,8 @@ var CliProviderInstance = class _CliProviderInstance {
51611
51808
  }
51612
51809
  completionFinalAssistantEvidence(parsedMessages, turnStartedAt) {
51613
51810
  const turnClosed = !this.hasAdapterPendingResponse();
51614
- if (this.completionHasFinalAssistantMessage(parsedMessages, turnStartedAt)) {
51811
+ const preferNativeOverParsed = this.adapter?.chatMessagesOwnedExternally === true && this.busyLeaseGateEnabled();
51812
+ if (!preferNativeOverParsed && this.completionHasFinalAssistantMessage(parsedMessages, turnStartedAt)) {
51615
51813
  return {
51616
51814
  present: turnClosed,
51617
51815
  messages: Array.isArray(parsedMessages) ? parsedMessages : [],
@@ -51621,7 +51819,8 @@ var CliProviderInstance = class _CliProviderInstance {
51621
51819
  const externalMessages = this.readExternalCompletionMessages();
51622
51820
  if (externalMessages) {
51623
51821
  const injectedTaskGenerating = this.injectedTaskHasStartedGenerating();
51624
- const present = injectedTaskGenerating && turnClosed && this.completionHasFinalAssistantMessage(externalMessages, turnStartedAt);
51822
+ const trailingToolActivity = hasTrailingToolActivityAfterFinalAssistant(externalMessages);
51823
+ const present = injectedTaskGenerating && turnClosed && !trailingToolActivity && this.completionHasFinalAssistantMessage(externalMessages, turnStartedAt);
51625
51824
  const lastVisibleAssistant = this.lastVisibleAssistantSummaryDetail(externalMessages);
51626
51825
  if (lastVisibleAssistant.content) {
51627
51826
  this.lastCompletionSummary = { content: lastVisibleAssistant.content, receivedAt: Date.now(), sourceTimestampMs: lastVisibleAssistant.timestampMs };
@@ -51632,6 +51831,13 @@ var CliProviderInstance = class _CliProviderInstance {
51632
51831
  source: "external-native"
51633
51832
  };
51634
51833
  }
51834
+ if (preferNativeOverParsed && this.completionHasFinalAssistantMessage(parsedMessages, turnStartedAt)) {
51835
+ return {
51836
+ present: turnClosed,
51837
+ messages: Array.isArray(parsedMessages) ? parsedMessages : [],
51838
+ source: "parsed"
51839
+ };
51840
+ }
51635
51841
  return {
51636
51842
  present: false,
51637
51843
  messages: Array.isArray(parsedMessages) ? parsedMessages : [],
@@ -51859,6 +52065,18 @@ var CliProviderInstance = class _CliProviderInstance {
51859
52065
  } catch {
51860
52066
  }
51861
52067
  }
52068
+ if (adapterOwnsMessagesElsewhere && finalAssistantEvidence.source === "external-native" && this.busyLeaseGateEnabled()) {
52069
+ try {
52070
+ const snapshot = this.lastTranscriptSignalSnapshot;
52071
+ const transcriptAgeMs = snapshot?.available === true && typeof snapshot.detail?.ageMs === "number" && Number.isFinite(snapshot.detail.ageMs) ? snapshot.detail.ageMs : void 0;
52072
+ if (typeof transcriptAgeMs === "number") {
52073
+ if (transcriptAgeMs < PTY_PARSED_FINAL_ASSISTANT_QUIET_DWELL_MS) {
52074
+ return { reason: "native_source_final_assistant_quiet_dwell", terminal: false };
52075
+ }
52076
+ }
52077
+ } catch {
52078
+ }
52079
+ }
51862
52080
  return null;
51863
52081
  }
51864
52082
  // (FALSEIDLE-a) Positive, structural proof that the latest approval entry was resolved
@@ -52486,7 +52704,7 @@ var CliProviderInstance = class _CliProviderInstance {
52486
52704
  return;
52487
52705
  }
52488
52706
  const latestOutputAt = typeof latestStatus?.lastOutputAt === "number" ? latestStatus.lastOutputAt : void 0;
52489
- if (typeof pending.lastOutputAtArm === "number" && typeof latestOutputAt === "number" && latestOutputAt > pending.lastOutputAtArm) {
52707
+ if (!pending.loggedBlockReason && typeof pending.lastOutputAtArm === "number" && typeof latestOutputAt === "number" && latestOutputAt > pending.lastOutputAtArm) {
52490
52708
  LOG.info("CLI", `[${this.type}] cancelled pending completed (new PTY output during settle: ${pending.lastOutputAtArm}\u2192${latestOutputAt})`);
52491
52709
  if (this.completionTraceOn()) this.recordCompletionGateTrace("cancel", {
52492
52710
  blockReason: "new_pty_output",
@@ -56480,6 +56698,7 @@ init_state_store();
56480
56698
  init_recent_activity();
56481
56699
  init_chat_history();
56482
56700
  init_mesh_events_utils();
56701
+ init_mesh_queue_assignment();
56483
56702
  init_logger();
56484
56703
  async function forwardConversationPrefsToCoordinator(ctx, sessionId, patch) {
56485
56704
  const dispatch = ctx.deps.dispatchMeshCommand;
@@ -56594,8 +56813,8 @@ var cliAgentHandlers = {
56594
56813
  };
56595
56814
  },
56596
56815
  agent_command: async (ctx, args) => {
56816
+ const dispatchSessionId = readStringValue(args?.targetSessionId, args?.sessionId, args?.instanceId);
56597
56817
  {
56598
- const dispatchSessionId = readStringValue(args?.targetSessionId, args?.sessionId, args?.instanceId);
56599
56818
  const dispatchMeshContext = args?.meshContext;
56600
56819
  if (dispatchSessionId && dispatchMeshContext) {
56601
56820
  try {
@@ -56629,18 +56848,23 @@ var cliAgentHandlers = {
56629
56848
  const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => meshNodeIdMatches(n, dispatchNodeId)) : void 0;
56630
56849
  const { shouldDeferDispatchForBootstrap: shouldDeferDispatchForBootstrap2 } = await Promise.resolve().then(() => (init_worktree_bootstrap_config(), worktree_bootstrap_config_exports));
56631
56850
  if (shouldDeferDispatchForBootstrap2(nodeObj)) {
56632
- return {
56633
- success: false,
56634
- recoverable: true,
56635
- dispatched: false,
56636
- code: "mesh_node_bootstrap_pending",
56637
- reason: "bootstrap_still_running",
56638
- nodeId: dispatchNodeId,
56639
- meshId: dispatchMeshId,
56640
- ...readStringValue(meshCtx?.taskId) ? { taskId: readStringValue(meshCtx?.taskId) } : {},
56641
- error: `Node '${dispatchNodeId}' worktree bootstrap is still running; a task injected now would land in the session input buffer before the provider is ready to consume it and be silently lost. Dispatch deferred.`,
56642
- nextAction: "Wait for the worktree_bootstrap_complete event (or poll mesh_status until the node session is ready), then re-send the task with mesh_send_task. Alternatively use mesh_enqueue_task so the queue auto-assigns it once a ready session is available."
56643
- };
56851
+ const dispatchSessionState = dispatchSessionId ? ctx.deps.instanceManager?.getInstance?.(dispatchSessionId)?.getState?.() : void 0;
56852
+ const sessionConfirmedReady = !!dispatchSessionState && isIdleSessionState(dispatchSessionState);
56853
+ if (!sessionConfirmedReady) {
56854
+ return {
56855
+ success: false,
56856
+ recoverable: true,
56857
+ dispatched: false,
56858
+ code: "mesh_node_bootstrap_pending",
56859
+ reason: "bootstrap_still_running",
56860
+ nodeId: dispatchNodeId,
56861
+ meshId: dispatchMeshId,
56862
+ ...readStringValue(meshCtx?.taskId) ? { taskId: readStringValue(meshCtx?.taskId) } : {},
56863
+ error: `Node '${dispatchNodeId}' worktree bootstrap is still running; a task injected now would land in the session input buffer before the provider is ready to consume it and be silently lost. Dispatch deferred.`,
56864
+ nextAction: "Wait for the worktree_bootstrap_complete event (or poll mesh_status until the node session is ready), then re-send the task with mesh_send_task. Alternatively use mesh_enqueue_task so the queue auto-assigns it once a ready session is available."
56865
+ };
56866
+ }
56867
+ LOG.info("MeshQueue", `Overriding stale worktreeBootstrap 'running' flag for node ${dispatchNodeId}: explicit target session ${dispatchSessionId} is independently confirmed idle/ready \u2014 dispatching mesh_send_task directly.`);
56644
56868
  }
56645
56869
  } catch {
56646
56870
  }
@@ -78316,6 +78540,7 @@ export {
78316
78540
  handleGitCommand,
78317
78541
  hasCdpManager,
78318
78542
  hasPendingDependents,
78543
+ hasTrailingToolActivityAfterFinalAssistant,
78319
78544
  hashSignatureParts,
78320
78545
  initDaemonComponents,
78321
78546
  insertDirectDispatch,