@adhdev/daemon-core 0.9.82-rc.253 → 0.9.82-rc.255

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.js CHANGED
@@ -2670,6 +2670,30 @@ __export(mesh_work_queue_exports, {
2670
2670
  updateTaskStatus: () => updateTaskStatus,
2671
2671
  validateMeshTaskModeRequest: () => validateMeshTaskModeRequest
2672
2672
  });
2673
+ function detectGitMutation(message) {
2674
+ const re = /\bgit\s+([a-z][a-z0-9-]*)/gi;
2675
+ let match;
2676
+ while ((match = re.exec(message)) !== null) {
2677
+ const sub = match[1].toLowerCase();
2678
+ if (GIT_MUTATION_SUBCOMMANDS.has(sub)) return true;
2679
+ if (sub === "stash") {
2680
+ const after = message.slice(re.lastIndex).match(/^\s+([a-z][a-z0-9-]*)/i);
2681
+ const next = after ? after[1].toLowerCase() : "";
2682
+ if (!GIT_STASH_READONLY_SUBCOMMANDS.has(next)) return true;
2683
+ } else if (sub === "checkout") {
2684
+ return true;
2685
+ } else if (sub === "submodule") {
2686
+ const after = message.slice(re.lastIndex).match(/^\s+([a-z][a-z0-9-]*)/i);
2687
+ const next = after ? after[1].toLowerCase() : "";
2688
+ if (next === "update" || next === "add" || next === "sync" || next === "deinit") return true;
2689
+ } else if (sub === "worktree") {
2690
+ const after = message.slice(re.lastIndex).match(/^\s+([a-z][a-z0-9-]*)/i);
2691
+ const next = after ? after[1].toLowerCase() : "";
2692
+ if (next === "add" || next === "remove" || next === "move" || next === "prune") return true;
2693
+ }
2694
+ }
2695
+ return false;
2696
+ }
2673
2697
  function normalizeMeshTaskMode(value) {
2674
2698
  if (typeof value !== "string") return void 0;
2675
2699
  const normalized = value.trim();
@@ -2683,7 +2707,11 @@ function validateMeshTaskModeRequest(mode, message) {
2683
2707
  if (taskMode !== "live_debug_readonly") {
2684
2708
  return { valid: true, taskMode, violations: [] };
2685
2709
  }
2686
- const violations = LIVE_DEBUG_READONLY_FORBIDDEN.filter((rule) => rule.pattern.test(message || "")).map((rule) => rule.label);
2710
+ const text = message || "";
2711
+ const violations = LIVE_DEBUG_READONLY_FORBIDDEN.filter((rule) => rule.pattern.test(text)).map((rule) => rule.label);
2712
+ if (detectGitMutation(text)) {
2713
+ violations.push("git_mutation");
2714
+ }
2687
2715
  return {
2688
2716
  valid: violations.length === 0,
2689
2717
  taskMode,
@@ -3005,7 +3033,7 @@ function recordMeshToolCall(opts) {
3005
3033
  return { rateLimitExceeded: false, callsInWindow: 0, advisory: null };
3006
3034
  }
3007
3035
  }
3008
- var import_crypto5, ACTIVE_MESH_QUEUE_STATUSES, HISTORICAL_MESH_QUEUE_STATUSES, MESH_TASK_MODES, LIVE_DEBUG_READONLY_FORBIDDEN, DEPENDENCY_FAILURE_TERMINALS;
3036
+ var import_crypto5, ACTIVE_MESH_QUEUE_STATUSES, HISTORICAL_MESH_QUEUE_STATUSES, MESH_TASK_MODES, LIVE_DEBUG_READONLY_FORBIDDEN, GIT_MUTATION_SUBCOMMANDS, GIT_STASH_READONLY_SUBCOMMANDS, DEPENDENCY_FAILURE_TERMINALS;
3009
3037
  var init_mesh_work_queue = __esm({
3010
3038
  "src/mesh/mesh-work-queue.ts"() {
3011
3039
  "use strict";
@@ -3018,13 +3046,35 @@ var init_mesh_work_queue = __esm({
3018
3046
  MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
3019
3047
  LIVE_DEBUG_READONLY_FORBIDDEN = [
3020
3048
  { label: "source_edit", pattern: /\b(edit|modify|patch|apply\s+patch|write\s+(?:to\s+)?(?:file|source)|overwrite|delete\s+file|remove\s+file|create\s+file|touch\s+file)\b/i },
3021
- { label: "git_mutation", pattern: /\b(?:git\s+(?:add|commit|push|reset|rebase|clean|checkout|switch|merge|tag|restore|rm|mv|stash|worktree\s+(?:add|remove|move))|push\b)/i },
3022
3049
  { label: "checkpoint", pattern: /\b(checkpoint|mesh_checkpoint)\b/i },
3023
3050
  { label: "deploy_or_version_bump", pattern: /\b(deploy|wrangler\s+deploy|version[-\s]?bump|npm\s+version|release|npm\s+publish|yarn\s+publish|pnpm\s+publish)\b/i },
3024
3051
  { label: "destructive_shell", pattern: /\b(rm\s+-rf|mv\s+\S+\s+\S+|truncate\s|tee\s+\S+|sed\s+-i|shred\b)\b/i },
3025
3052
  { label: "package_install", pattern: /\b(npm\s+(?:install|i|add|link|uninstall|remove)|yarn\s+(?:add|remove|link)|pnpm\s+(?:add|remove|link)|pip\s+install|brew\s+install|apt\s+install|cargo\s+install)\b/i },
3026
3053
  { label: "container_mutation", pattern: /\b(docker\s+(?:build|run|exec|push|tag|rmi|rm|create|start|stop|kill)|kubectl\s+(?:apply|delete|patch|replace|create|scale))\b/i }
3027
3054
  ];
3055
+ GIT_MUTATION_SUBCOMMANDS = /* @__PURE__ */ new Set([
3056
+ "add",
3057
+ "commit",
3058
+ "push",
3059
+ "reset",
3060
+ "rebase",
3061
+ "clean",
3062
+ "switch",
3063
+ "merge",
3064
+ "tag",
3065
+ "restore",
3066
+ "rm",
3067
+ "mv",
3068
+ "cherry-pick",
3069
+ "revert",
3070
+ "pull",
3071
+ "fetch",
3072
+ "am",
3073
+ "apply",
3074
+ "gc",
3075
+ "prune"
3076
+ ]);
3077
+ GIT_STASH_READONLY_SUBCOMMANDS = /* @__PURE__ */ new Set(["list", "show"]);
3028
3078
  DEPENDENCY_FAILURE_TERMINALS = /* @__PURE__ */ new Set(["failed", "cancelled"]);
3029
3079
  }
3030
3080
  });
@@ -5839,12 +5889,11 @@ function refineTerminalEventFromLedger(meshId, pending) {
5839
5889
  }
5840
5890
  function reconcilePendingMeshCoordinatorEvents(meshId, events) {
5841
5891
  const backfilled = refineTerminalEventFromLedger(meshId, events);
5842
- if (backfilled.length === 0) return events;
5843
- const terminalJobIds = new Set(backfilled.map((event) => readRefineJobId2(event)).filter(Boolean));
5844
- return [
5845
- ...events.filter((event) => !(event.event === "refine:accepted" && terminalJobIds.has(readRefineJobId2(event)))),
5846
- ...backfilled
5847
- ];
5892
+ const terminalJobIds = new Set(
5893
+ [...events.filter((event) => REFINE_TERMINAL_EVENTS.has(event.event)), ...backfilled].map((event) => readRefineJobId2(event)).filter(Boolean)
5894
+ );
5895
+ const reconciled = terminalJobIds.size === 0 ? events : events.filter((event) => !(event.event === "refine:accepted" && terminalJobIds.has(readRefineJobId2(event))));
5896
+ return backfilled.length === 0 ? reconciled : [...reconciled, ...backfilled];
5848
5897
  }
5849
5898
  function trimPendingEventsIfNeeded(path39) {
5850
5899
  try {
@@ -6830,7 +6879,15 @@ function nodeHasActiveAssignment(meshId, nodeId) {
6830
6879
  return getQueue(meshId, { status: ["assigned"] }).some((task) => task.assignedNodeId === nodeId);
6831
6880
  }
6832
6881
  function sessionHasActiveAssignment(meshId, sessionId) {
6833
- return getQueue(meshId, { status: ["assigned"] }).some((task) => task.assignedSessionId === sessionId);
6882
+ if (getQueue(meshId, { status: ["assigned"] }).some((task) => task.assignedSessionId === sessionId)) {
6883
+ return true;
6884
+ }
6885
+ try {
6886
+ if (getActiveDirectDispatches(meshId).some((d) => d.sessionId === sessionId)) return true;
6887
+ if (hasUnterminalDirectDispatchLedgerEntry(meshId, sessionId)) return true;
6888
+ } catch {
6889
+ }
6890
+ return false;
6834
6891
  }
6835
6892
  function liveSessionCountForNode(components, meshId, nodeId) {
6836
6893
  return components.instanceManager.getByCategory("cli").filter((inst) => {
@@ -7197,6 +7254,9 @@ function runIdleMaintenanceThenAssignQueue(components, args) {
7197
7254
  function isMeshCoordinatorEvent(eventName) {
7198
7255
  return typeof eventName === "string" && MESH_COORDINATOR_EVENTS.has(eventName);
7199
7256
  }
7257
+ function shouldForceInjectMeshEvent(eventName) {
7258
+ return typeof eventName === "string" && MESH_FORCE_INJECT_EVENTS.has(eventName);
7259
+ }
7200
7260
  function injectMeshSystemMessage(components, args) {
7201
7261
  const eventSessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
7202
7262
  const eventNodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
@@ -7587,10 +7647,14 @@ function injectMeshSystemMessage(components, args) {
7587
7647
  })) {
7588
7648
  LOG.info("MeshEvents", `Queued ${args.event} for MCP coordinator (mesh ${args.meshId})`);
7589
7649
  }
7650
+ const forceInject = shouldForceInjectMeshEvent(args.event);
7590
7651
  for (const coord of coordinatorInstances) {
7591
7652
  const coordState = coord.getState();
7592
- LOG.info("MeshEvents", `Forwarding mesh event to coordinator ${coordState.instanceId}`);
7593
- coord.onEvent("send_message", { input: { text: messageText, textFallback: messageText } });
7653
+ LOG.info("MeshEvents", `Forwarding mesh event to coordinator ${coordState.instanceId}${forceInject ? " (force)" : ""}`);
7654
+ coord.onEvent("send_message", {
7655
+ input: { text: messageText, textFallback: messageText },
7656
+ ...forceInject ? { force: true } : {}
7657
+ });
7594
7658
  }
7595
7659
  return { success: true, forwarded: coordinatorInstances.length };
7596
7660
  }
@@ -7643,6 +7707,45 @@ function handleMeshForwardEvent(components, payload) {
7643
7707
  }
7644
7708
  function setupMeshEventForwarding(components) {
7645
7709
  components.instanceManager.onEvent((event) => {
7710
+ if (event.event === "agent:ready" || event.event === "agent:generating_completed") {
7711
+ const flushInstanceId = readNonEmptyString2(event.instanceId);
7712
+ if (flushInstanceId) {
7713
+ const flushSource = components.instanceManager.getInstance(flushInstanceId);
7714
+ if (flushSource && flushSource.category === "cli") {
7715
+ const flushState = flushSource.getState();
7716
+ const flushSettings = flushState.settings && typeof flushState.settings === "object" ? flushState.settings : {};
7717
+ const coordinatorMeshId2 = readNonEmptyString2(flushSettings.meshCoordinatorFor);
7718
+ if (coordinatorMeshId2) {
7719
+ const status = readNonEmptyString2(flushState.status).toLowerCase();
7720
+ if (status === "idle") {
7721
+ try {
7722
+ const localDaemonId = readNonEmptyString2(loadConfig().machineId) || void 0;
7723
+ const pendingEvents = drainPendingMeshCoordinatorEvents(coordinatorMeshId2, localDaemonId);
7724
+ if (pendingEvents.length > 0) {
7725
+ LOG.info("MeshEvents", `Auto-flushing ${pendingEvents.length} pending coordinator event(s) for mesh ${coordinatorMeshId2} on coordinator idle`);
7726
+ for (const pending of pendingEvents) {
7727
+ if (!pending.coordinatorMessage) continue;
7728
+ const forcePending = shouldForceInjectMeshEvent(pending.event);
7729
+ flushSource.onEvent("send_message", {
7730
+ input: { text: pending.coordinatorMessage, textFallback: pending.coordinatorMessage },
7731
+ ...forcePending ? { force: true } : {}
7732
+ });
7733
+ }
7734
+ }
7735
+ } catch (e) {
7736
+ LOG.warn("MeshEvents", `Failed to auto-flush pending coordinator events: ${e?.message || e}`);
7737
+ }
7738
+ }
7739
+ let hasDirectDispatch = false;
7740
+ try {
7741
+ hasDirectDispatch = getActiveDirectDispatches(coordinatorMeshId2).some((d) => d.sessionId === flushInstanceId) || hasUnterminalDirectDispatchLedgerEntry(coordinatorMeshId2, flushInstanceId);
7742
+ } catch {
7743
+ }
7744
+ if (!hasDirectDispatch) return;
7745
+ }
7746
+ }
7747
+ }
7748
+ }
7646
7749
  if (!isMeshCoordinatorEvent(event.event)) return;
7647
7750
  const instanceId = readNonEmptyString2(event.instanceId);
7648
7751
  if (!instanceId) return;
@@ -7681,33 +7784,8 @@ function setupMeshEventForwarding(components) {
7681
7784
  metadataEvent: event
7682
7785
  });
7683
7786
  });
7684
- components.instanceManager.onEvent((event) => {
7685
- if (event.event !== "agent:ready" && event.event !== "agent:generating_completed") return;
7686
- const instanceId = readNonEmptyString2(event.instanceId);
7687
- if (!instanceId) return;
7688
- const sourceInstance = components.instanceManager.getInstance(instanceId);
7689
- if (!sourceInstance || sourceInstance.category !== "cli") return;
7690
- const state = sourceInstance.getState();
7691
- const settings = state.settings && typeof state.settings === "object" ? state.settings : {};
7692
- const coordinatorMeshId = readNonEmptyString2(settings.meshCoordinatorFor);
7693
- if (!coordinatorMeshId) return;
7694
- const status = readNonEmptyString2(state.status).toLowerCase();
7695
- if (status !== "idle") return;
7696
- try {
7697
- const localDaemonId = readNonEmptyString2(loadConfig().machineId) || void 0;
7698
- const pendingEvents = drainPendingMeshCoordinatorEvents(coordinatorMeshId, localDaemonId);
7699
- if (pendingEvents.length === 0) return;
7700
- LOG.info("MeshEvents", `Auto-flushing ${pendingEvents.length} pending coordinator event(s) for mesh ${coordinatorMeshId} on coordinator idle`);
7701
- for (const pending of pendingEvents) {
7702
- if (!pending.coordinatorMessage) continue;
7703
- sourceInstance.onEvent("send_message", { input: { text: pending.coordinatorMessage, textFallback: pending.coordinatorMessage } });
7704
- }
7705
- } catch (e) {
7706
- LOG.warn("MeshEvents", `Failed to auto-flush pending coordinator events: ${e?.message || e}`);
7707
- }
7708
- });
7709
7787
  }
7710
- var import_fs10, REMOTE_IDLE_SESSION_TTL_MS, meshByWorkspaceCache, MESH_WORKSPACE_CACHE_TTL_MS, IDLE_AUTO_FAST_FORWARD_THROTTLE_MS, idleAutoFastForwardLastAttempt, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, RECENT_COMPLETION_FINGERPRINT_TTL_MS, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND;
7788
+ var import_fs10, REMOTE_IDLE_SESSION_TTL_MS, meshByWorkspaceCache, MESH_WORKSPACE_CACHE_TTL_MS, IDLE_AUTO_FAST_FORWARD_THROTTLE_MS, idleAutoFastForwardLastAttempt, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, RECENT_COMPLETION_FINGERPRINT_TTL_MS, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, MESH_FORCE_INJECT_EVENTS;
7711
7789
  var init_mesh_events_coordinator = __esm({
7712
7790
  "src/mesh/mesh-events-coordinator.ts"() {
7713
7791
  "use strict";
@@ -7753,6 +7831,15 @@ var init_mesh_events_coordinator = __esm({
7753
7831
  "agent:stopped": "task_failed",
7754
7832
  "monitor:long_generating": "task_stalled"
7755
7833
  };
7834
+ MESH_FORCE_INJECT_EVENTS = /* @__PURE__ */ new Set([
7835
+ "agent:generating_completed",
7836
+ "agent:stopped",
7837
+ "agent:waiting_approval",
7838
+ "refine:completed",
7839
+ "refine:failed",
7840
+ "worktree_bootstrap_complete",
7841
+ "worktree_bootstrap_failed"
7842
+ ]);
7756
7843
  }
7757
7844
  });
7758
7845
 
@@ -28697,7 +28784,12 @@ var FsmDriver = class {
28697
28784
  const controls = this.deriveControls(state.id);
28698
28785
  const title = modal?.title ?? this.deriveTitle(state, sections, lines.join("\n"));
28699
28786
  const next = {
28700
- state: { id: state.id, label: state.label, title },
28787
+ // status is derived from the FSM state itself (statusForState), NOT from
28788
+ // whether a modal was parsed this frame. A modal state whose buttons briefly
28789
+ // fail to parse (PTY repaint → deriveModal returns null) must still report
28790
+ // its authoritative status (e.g. 'approval'), so the adapter never collapses
28791
+ // an approval/busy state to idle on a transient modal-parse miss.
28792
+ state: { id: state.id, label: state.label, title, status: statusForState(state) },
28701
28793
  modal,
28702
28794
  controls
28703
28795
  };
@@ -29798,20 +29890,18 @@ var SpecCliAdapter = class {
29798
29890
  const state = this.latestState;
29799
29891
  if (!state) return { status: "starting", messages: [], activeModal: null, activeInteractivePrompt: this.activeInteractivePrompt, ...sessionFields };
29800
29892
  const modal = this.latestModal;
29801
- const lc = state.id.toLowerCase();
29802
- if (modal) {
29893
+ if (state.status === "approval") {
29803
29894
  return {
29804
29895
  status: "waiting_approval",
29805
29896
  messages: [],
29806
- activeModal: {
29807
- message: modal.title ?? state.label,
29808
- buttons: modal.buttons.map((b) => b.label)
29809
- },
29897
+ // Surface buttons when we have them; an approval state with no parsed
29898
+ // modal this frame still stays waiting_approval (no activeModal yet).
29899
+ activeModal: modal ? { message: modal.title ?? state.label, buttons: modal.buttons.map((b) => b.label) } : null,
29810
29900
  activeInteractivePrompt: this.activeInteractivePrompt,
29811
29901
  ...sessionFields
29812
29902
  };
29813
29903
  }
29814
- if (lc === "busy" || lc === "generating") {
29904
+ if (state.status === "generating") {
29815
29905
  return { status: "generating", messages: [], activeModal: null, activeInteractivePrompt: this.activeInteractivePrompt, ...sessionFields };
29816
29906
  }
29817
29907
  return { status: "idle", messages: [], activeModal: null, activeInteractivePrompt: this.activeInteractivePrompt, ...sessionFields };
@@ -30532,7 +30622,6 @@ var CliProviderInstance = class {
30532
30622
  runtimeMessages = [];
30533
30623
  lastPersistedHistoryMessages = [];
30534
30624
  lastAcknowledgedUserInputAt = 0;
30535
- externalBusyIdleFingerprint = "";
30536
30625
  lastNativeSourceCanonicalCheckAt = 0;
30537
30626
  lastNativeSourceCanonicalCacheKey = void 0;
30538
30627
  cachedSqliteDb = null;
@@ -30663,10 +30752,6 @@ var CliProviderInstance = class {
30663
30752
  const autoApproveActive = this.maybeAutoApproveStatus(adapterStatus, Date.now());
30664
30753
  const autoApproveHoldIdle = this.autoApproveBusy && adapterStatus.status === "idle";
30665
30754
  let visibleStatus = parseErrorMessage || parsedStatus?.status === "error" ? "error" : autoApproveActive || autoApproveHoldIdle ? "generating" : adapterStatus.status;
30666
- const externalNativeFinal = this.getExternalNativeFinalReconciliation(parsedStatus?.messages, adapterStatus);
30667
- if (externalNativeFinal && isCliGeneratingLikeStatus(visibleStatus)) {
30668
- visibleStatus = "idle";
30669
- }
30670
30755
  if (isCliGeneratingLikeStatus(visibleStatus) && this.lastStatus === "idle") {
30671
30756
  visibleStatus = "idle";
30672
30757
  }
@@ -30899,7 +30984,8 @@ var CliProviderInstance = class {
30899
30984
  assertProviderSupportsDeclaredInput(this.provider, input);
30900
30985
  const promptText = buildCliStructuredInputPrompt(input);
30901
30986
  if (promptText) {
30902
- void this.adapter.sendMessage(promptText).catch((e) => {
30987
+ const force = data?.force === true;
30988
+ void this.adapter.sendMessage(promptText, force ? { force: true } : {}).catch((e) => {
30903
30989
  LOG.warn("CLI", `[${this.type}] send_message failed: ${e?.message || e}`);
30904
30990
  });
30905
30991
  }
@@ -30944,7 +31030,6 @@ var CliProviderInstance = class {
30944
31030
  if (!content) return;
30945
31031
  const receivedAt = Date.now();
30946
31032
  this.lastAcknowledgedUserInputAt = receivedAt;
30947
- this.externalBusyIdleFingerprint = "";
30948
31033
  const dedupKey = `user_input_ack:${crypto4.createHash("sha256").update(`${this.instanceId}:${content}:${receivedAt}`).digest("hex").slice(0, 24)}`;
30949
31034
  this.appendRuntimeMessage(buildChatMessage({
30950
31035
  role: "user",
@@ -31093,50 +31178,6 @@ var CliProviderInstance = class {
31093
31178
  const evidence = this.completionFinalAssistantEvidence(parsedMessages);
31094
31179
  return extractFinalSummaryFromMessages(evidence.messages);
31095
31180
  }
31096
- externalNativeFinalFingerprint(evidence) {
31097
- const messages = Array.isArray(evidence.messages) ? evidence.messages : [];
31098
- const visibleMessages = messages.filter((message) => isUserFacingChatMessage(message));
31099
- const lastVisible = visibleMessages[visibleMessages.length - 1];
31100
- const content = lastVisible ? flattenContent(lastVisible.content).trim() : "";
31101
- const receivedAt = lastVisible ? getMessageTime(lastVisible) : 0;
31102
- const probe = this.lastExternalCompletionProbe;
31103
- return crypto4.createHash("sha256").update([
31104
- this.type,
31105
- this.providerSessionId || "",
31106
- probe?.sourcePath || "",
31107
- String(probe?.sourceMtimeMs || 0),
31108
- String(receivedAt || 0),
31109
- content.slice(-500)
31110
- ].join("\0")).digest("hex").slice(0, 24);
31111
- }
31112
- getExternalNativeFinalReconciliation(parsedMessages, adapterStatus) {
31113
- const rawStatus = typeof adapterStatus?.status === "string" ? adapterStatus.status.trim() : "";
31114
- if (!isCliGeneratingLikeStatus(rawStatus)) return null;
31115
- if (hasNonEmptyCliModalButtons(adapterStatus?.activeModal ?? adapterStatus?.modal)) return null;
31116
- const evidence = this.completionFinalAssistantEvidence(parsedMessages);
31117
- if (evidence.source !== "external-native" || !evidence.present) return null;
31118
- const messages = Array.isArray(evidence.messages) ? evidence.messages : [];
31119
- const visibleMessages = messages.filter((message) => isUserFacingChatMessage(message));
31120
- const lastVisible = visibleMessages[visibleMessages.length - 1];
31121
- const lastMessageAt = lastVisible ? getMessageTime(lastVisible) : 0;
31122
- const sourceMtimeMs = Number(this.lastExternalCompletionProbe?.sourceMtimeMs || 0);
31123
- const minEvidenceAt = Math.max(
31124
- this.startedAt > 0 ? this.startedAt - 5e3 : 0,
31125
- this.generatingStartedAt > 0 ? this.generatingStartedAt - 5e3 : 0,
31126
- this.lastAcknowledgedUserInputAt > 0 ? this.lastAcknowledgedUserInputAt - 1e3 : 0
31127
- );
31128
- if (minEvidenceAt > 0 && lastMessageAt > 0 && lastMessageAt < minEvidenceAt && sourceMtimeMs < minEvidenceAt) {
31129
- return null;
31130
- }
31131
- const finalSummary = extractFinalSummaryFromMessages(evidence.messages);
31132
- if (!finalSummary) return null;
31133
- const fingerprint = this.externalNativeFinalFingerprint(evidence);
31134
- if (fingerprint === this.externalBusyIdleFingerprint) {
31135
- return { fingerprint, finalSummary, evidence };
31136
- }
31137
- this.externalBusyIdleFingerprint = fingerprint;
31138
- return { fingerprint, finalSummary, evidence };
31139
- }
31140
31181
  buildCompletedFinalizationDiagnostic(args) {
31141
31182
  let parsed = null;
31142
31183
  let parseError;
@@ -31207,18 +31248,17 @@ var CliProviderInstance = class {
31207
31248
  if (typeof adapterAny?.responseBuffer === "string" && adapterAny.responseBuffer.trim()) return false;
31208
31249
  return true;
31209
31250
  }
31210
- getCompletedFinalizationBlock(latestVisibleStatus, pending, opts) {
31251
+ getCompletedFinalizationBlock(latestVisibleStatus, pending) {
31211
31252
  if (latestVisibleStatus !== "idle") return { reason: `status:${latestVisibleStatus}`, terminal: true };
31212
31253
  const adapterAny = this.adapter;
31213
31254
  const approvalResolvedIdle = pending.previousStatus === "waiting_approval";
31214
- const externalNativeFinal = opts?.externalNativeFinal || null;
31215
- if (!approvalResolvedIdle && !externalNativeFinal) {
31255
+ if (!approvalResolvedIdle) {
31216
31256
  if (adapterAny?.isWaitingForResponse === true) return { reason: "adapter_waiting_for_response", terminal: true };
31217
31257
  if (adapterAny?.currentTurnScope) return { reason: "adapter_turn_scope_active", terminal: true };
31218
31258
  if (this.hasAdapterPendingResponse()) return { reason: "adapter_pending_response", terminal: true };
31219
31259
  }
31220
31260
  const partial = typeof this.adapter.getPartialResponse === "function" ? this.adapter.getPartialResponse() : "";
31221
- if (!externalNativeFinal && typeof partial === "string" && partial.trim()) return { reason: "partial_response_pending", terminal: true };
31261
+ if (typeof partial === "string" && partial.trim()) return { reason: "partial_response_pending", terminal: true };
31222
31262
  let parsed;
31223
31263
  try {
31224
31264
  parsed = this.adapter.getScriptParsedStatus();
@@ -31228,7 +31268,6 @@ var CliProviderInstance = class {
31228
31268
  const parsedStatus = typeof parsed?.status === "string" ? parsed.status : "unknown";
31229
31269
  if (parsedStatus !== "idle") {
31230
31270
  const adapterStatus = this.adapter.getStatus({ allowParse: false });
31231
- if (externalNativeFinal && isCliGeneratingLikeStatus(parsedStatus)) return null;
31232
31271
  if (this.shouldSuppressStaleParsedBusyStatus(parsed, adapterStatus)) return null;
31233
31272
  return { reason: `parsed_status:${parsedStatus}`, terminal: isCliGeneratingLikeStatus(parsedStatus) };
31234
31273
  }
@@ -31236,6 +31275,20 @@ var CliProviderInstance = class {
31236
31275
  const adapterOwnsMessagesElsewhere = this.adapter?.chatMessagesOwnedExternally === true;
31237
31276
  const finalAssistantEvidence = this.completionFinalAssistantEvidence(parsed?.messages);
31238
31277
  const allowMissingAssistantTimeout = !!(this.settings.meshNodeFor || this.settings.meshActiveTaskId || this.settings.launchedByCoordinator);
31278
+ if (adapterOwnsMessagesElsewhere && finalAssistantEvidence.source === "external-native") {
31279
+ const prevProbe = (pending.transcriptProbeHistory || [])[(pending.transcriptProbeHistory?.length ?? 0) - 1];
31280
+ this.readExternalCompletionMessages();
31281
+ const settleProbe = this.lastExternalCompletionProbe;
31282
+ if (settleProbe && prevProbe) {
31283
+ const stillGrowing = settleProbe.msgCount > prevProbe.msgCount || settleProbe.lastRole === "assistant" && settleProbe.contentLen > prevProbe.contentLen;
31284
+ if (stillGrowing) {
31285
+ this.recordPendingTranscriptProbe(pending);
31286
+ return { reason: `transcript_settling:${prevProbe.contentLen}->${settleProbe.contentLen}`, terminal: false };
31287
+ }
31288
+ } else if (settleProbe) {
31289
+ this.recordPendingTranscriptProbe(pending);
31290
+ }
31291
+ }
31239
31292
  LOG.debug("CLI", `[${this.type}] finalAssistantEvidence: present=${finalAssistantEvidence.present} source=${finalAssistantEvidence.source} adapterOwnsMessagesElsewhere=${adapterOwnsMessagesElsewhere} parsedStatus=${parsedStatus}`);
31240
31293
  if (!finalAssistantEvidence.present) {
31241
31294
  if (adapterOwnsMessagesElsewhere) {
@@ -31290,16 +31343,15 @@ var CliProviderInstance = class {
31290
31343
  }
31291
31344
  const latestStatus = this.adapter.getStatus({ allowParse: false });
31292
31345
  const latestAutoApproveActive = latestStatus.status === "waiting_approval" && this.shouldAutoApprove();
31293
- const externalNativeFinal = this.getExternalNativeFinalReconciliation(void 0, latestStatus);
31294
- const latestVisibleStatus = externalNativeFinal && isCliGeneratingLikeStatus(latestStatus.status) ? "idle" : latestAutoApproveActive || this.autoApproveBusy ? "generating" : latestStatus.status;
31295
- LOG.debug("CLI", `[${this.type}] flush attempt: adapterStatus=${latestStatus.status} latestVisible=${latestVisibleStatus} externalNativeFinal=${!!externalNativeFinal} generatingStartedAt=${this.generatingStartedAt} isWaitingForResponse=${!!this.adapter?.isWaitingForResponse} hasPartial=${!!this.adapter.getPartialResponse?.()}`);
31346
+ const latestVisibleStatus = latestAutoApproveActive || this.autoApproveBusy ? "generating" : latestStatus.status;
31347
+ LOG.debug("CLI", `[${this.type}] flush attempt: adapterStatus=${latestStatus.status} latestVisible=${latestVisibleStatus} generatingStartedAt=${this.generatingStartedAt} isWaitingForResponse=${!!this.adapter?.isWaitingForResponse} hasPartial=${!!this.adapter.getPartialResponse?.()}`);
31296
31348
  if (latestVisibleStatus !== "idle") {
31297
31349
  LOG.info("CLI", `[${this.type}] cancelled pending completed (resumed ${latestVisibleStatus})`);
31298
31350
  this.completedDebouncePending = null;
31299
31351
  this.completedDebounceTimer = null;
31300
31352
  return;
31301
31353
  }
31302
- const block2 = this.getCompletedFinalizationBlock(latestVisibleStatus, pending, { externalNativeFinal });
31354
+ const block2 = this.getCompletedFinalizationBlock(latestVisibleStatus, pending);
31303
31355
  if (block2) {
31304
31356
  const blockReason = block2.reason;
31305
31357
  const waitedMs = Date.now() - pending.firstObservedAt;
@@ -31341,18 +31393,7 @@ var CliProviderInstance = class {
31341
31393
  chatTitle: pending.chatTitle,
31342
31394
  duration: pending.duration,
31343
31395
  timestamp: pending.timestamp,
31344
- finalSummary: externalNativeFinal?.finalSummary || this.completionFinalSummary(this.adapter?.getScriptParsedStatus()?.messages),
31345
- ...externalNativeFinal ? {
31346
- completionDiagnostic: {
31347
- providerType: this.type,
31348
- sessionId: this.instanceId,
31349
- providerSessionId: this.providerSessionId || null,
31350
- reconciliationReason: "external_native_final_assistant_while_adapter_busy",
31351
- finalAssistantPresent: true,
31352
- finalAssistantEvidenceSource: externalNativeFinal.evidence.source,
31353
- externalFinalFingerprint: externalNativeFinal.fingerprint
31354
- }
31355
- } : {}
31396
+ finalSummary: this.completionFinalSummary(this.adapter?.getScriptParsedStatus()?.messages)
31356
31397
  });
31357
31398
  this.completedDebouncePending = null;
31358
31399
  this.completedDebounceTimer = null;
@@ -31408,9 +31449,8 @@ var CliProviderInstance = class {
31408
31449
  const parsedStatus = null;
31409
31450
  const rawStatus = adapterStatus.status;
31410
31451
  const autoApproveActive = this.maybeAutoApproveStatus(adapterStatus, now);
31411
- const externalNativeFinal = this.getExternalNativeFinalReconciliation(void 0, adapterStatus);
31412
31452
  const autoApproveHoldIdle = this.autoApproveBusy && rawStatus === "idle";
31413
- const newStatus = externalNativeFinal && isCliGeneratingLikeStatus(rawStatus) ? "idle" : autoApproveActive || autoApproveHoldIdle ? "generating" : rawStatus;
31453
+ const newStatus = autoApproveActive || autoApproveHoldIdle ? "generating" : rawStatus;
31414
31454
  const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
31415
31455
  const chatTitle = `${this.provider.name} \xB7 ${dirName}`;
31416
31456
  const partial = this.adapter.getPartialResponse();
@@ -39557,16 +39597,26 @@ function reconcileInlineMeshCache(cached, incoming) {
39557
39597
  const nodeId = readInlineMeshNodeId(node);
39558
39598
  if (nodeId) cachedById.set(nodeId, node);
39559
39599
  }
39600
+ const mergedIncomingIds = /* @__PURE__ */ new Set();
39560
39601
  const nodes = incomingNodes.map((incomingNode) => {
39561
39602
  const nodeId = readInlineMeshNodeId(incomingNode);
39562
39603
  const cachedNode = nodeId ? cachedById.get(nodeId) : void 0;
39563
39604
  if (!cachedNode && preserveCachedMembership) return null;
39605
+ if (nodeId) mergedIncomingIds.add(nodeId);
39564
39606
  if (!cachedNode) return incomingNode;
39565
39607
  if (hasInlineMeshTransientNodeState(incomingNode)) {
39566
39608
  return { ...cachedNode, ...incomingNode };
39567
39609
  }
39568
39610
  return { ...stripInlineMeshTransientNodeState(cachedNode), ...incomingNode };
39569
39611
  }).filter(Boolean);
39612
+ if (preserveCachedMembership) {
39613
+ for (const cachedNode of cachedNodes) {
39614
+ const nodeId = readInlineMeshNodeId(cachedNode);
39615
+ if (nodeId && !mergedIncomingIds.has(nodeId)) {
39616
+ nodes.push(cachedNode);
39617
+ }
39618
+ }
39619
+ }
39570
39620
  return {
39571
39621
  ...cached,
39572
39622
  ...incoming,
@@ -42481,6 +42531,18 @@ ${tail}` : ""
42481
42531
  return { success: true };
42482
42532
  }
42483
42533
  case "launch_cli": {
42534
+ {
42535
+ const launchSettings = args?.settings && typeof args.settings === "object" ? args.settings : void 0;
42536
+ const isMeshWorkerLaunch = !!launchSettings && (readStringValue(launchSettings.meshNodeFor) || launchSettings.launchedByCoordinator === true);
42537
+ const hasCoordinatorDaemonId = !!launchSettings && !!readStringValue(launchSettings.meshCoordinatorDaemonId);
42538
+ if (launchSettings && isMeshWorkerLaunch && !hasCoordinatorDaemonId) {
42539
+ try {
42540
+ const localDaemonId = readStringValue(loadConfig().machineId);
42541
+ if (localDaemonId) launchSettings.meshCoordinatorDaemonId = localDaemonId;
42542
+ } catch {
42543
+ }
42544
+ }
42545
+ }
42484
42546
  const launchResult = await this.deps.cliManager.handleCliCommand(cmd, args);
42485
42547
  const meshNodeId = readStringValue(args?.settings?.meshNodeId);
42486
42548
  const meshId = readStringValue(args?.settings?.meshNodeFor);
@@ -43978,7 +44040,7 @@ ${tail}` : ""
43978
44040
  const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "worktree clone");
43979
44041
  if (ownerFailure) return ownerFailure;
43980
44042
  try {
43981
- const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
44043
+ const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
43982
44044
  const mesh = meshRecord?.mesh;
43983
44045
  if (!mesh) return { success: false, error: "Mesh not found" };
43984
44046
  const sourceNode = mesh.nodes?.find((n) => n.id === sourceNodeId || n.nodeId === sourceNodeId);
@@ -44029,6 +44091,8 @@ ${tail}` : ""
44029
44091
  policy: { ...sourceNode.policy || {} }
44030
44092
  });
44031
44093
  if (!node) return { success: false, error: "Failed to register worktree node" };
44094
+ const inlineForReconcile = this.getCachedInlineMesh(meshId);
44095
+ if (inlineForReconcile) this.updateInlineMeshNode(meshId, inlineForReconcile, node);
44032
44096
  this.invalidateAggregateMeshStatus(meshId);
44033
44097
  }
44034
44098
  const persistWorktreeSetupState = async (bootstrapState2) => {