@adhdev/daemon-core 0.9.82-rc.373 → 0.9.82-rc.375

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
@@ -316,10 +316,10 @@ function readInjected(value) {
316
316
  }
317
317
  function getDaemonBuildInfo() {
318
318
  if (cached) return cached;
319
- const commit = readInjected(true ? "f16b5e6cdf653b4258f8f44cb11fb6ad8c13329f" : void 0) ?? "unknown";
320
- const commitShort = readInjected(true ? "f16b5e6c" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
321
- const version = readInjected(true ? "0.9.82-rc.373" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
322
- const builtAt = readInjected(true ? "2026-06-24T16:28:52.547Z" : void 0);
319
+ const commit = readInjected(true ? "b17fb9165bd52c9e2ab8cccf2ce80734e2165680" : void 0) ?? "unknown";
320
+ const commitShort = readInjected(true ? "b17fb916" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
321
+ const version = readInjected(true ? "0.9.82-rc.375" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
322
+ const builtAt = readInjected(true ? "2026-06-25T02:21:59.111Z" : void 0);
323
323
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
324
324
  return cached;
325
325
  }
@@ -3042,6 +3042,10 @@ Default branch: \`${mesh.defaultBranch}\`` : ""}`);
3042
3042
  if (ctx.missionSection?.trim()) {
3043
3043
  sections.push(ctx.missionSection.trim());
3044
3044
  }
3045
+ const recentActivity = buildRecentActivitySection(ctx.recentActivity);
3046
+ if (recentActivity) sections.push(recentActivity);
3047
+ const operatingNotes = buildOperatingNotesSection(ctx.operatingNotes);
3048
+ if (operatingNotes) sections.push(operatingNotes);
3045
3049
  sections.push(buildPolicySection({ ...DEFAULT_MESH_POLICY, ...mesh.policy || {} }));
3046
3050
  sections.push(TOOLS_SECTION);
3047
3051
  sections.push(TOOL_EXPOSURE_PREFLIGHT_SECTION);
@@ -3073,6 +3077,8 @@ function expandPromptPlaceholders(template, ctx) {
3073
3077
  cliType: coordinatorCliType || "",
3074
3078
  nodes: nodesSection,
3075
3079
  mission: ctx.missionSection?.trim() || "",
3080
+ recentActivity: buildRecentActivitySection(ctx.recentActivity) || "",
3081
+ operatingNotes: buildOperatingNotesSection(ctx.operatingNotes) || "",
3076
3082
  policy: buildPolicySection({ ...DEFAULT_MESH_POLICY, ...mesh.policy || {} }),
3077
3083
  tools: TOOLS_SECTION,
3078
3084
  workflow: WORKFLOW_SECTION,
@@ -3144,6 +3150,56 @@ function indentFollowing(text, pad) {
3144
3150
  if (lines.length === 1) return lines[0];
3145
3151
  return [lines[0], ...lines.slice(1).map((l) => pad + l)].join("\n");
3146
3152
  }
3153
+ function buildRecentActivitySection(activity) {
3154
+ if (!activity) return "";
3155
+ const failures = Array.isArray(activity.recentFailures) ? activity.recentFailures : [];
3156
+ const pending = Number.isFinite(activity.pendingTasks) ? Number(activity.pendingTasks) : 0;
3157
+ const assigned = Number.isFinite(activity.assignedTasks) ? Number(activity.assignedTasks) : 0;
3158
+ const stalled = Number.isFinite(activity.stalledTasks) ? Number(activity.stalledTasks) : 0;
3159
+ const recentFailureCount = Number.isFinite(activity.recentFailureCount) ? Number(activity.recentFailureCount) : failures.length;
3160
+ if (failures.length === 0 && pending === 0 && assigned === 0 && stalled === 0 && recentFailureCount === 0) {
3161
+ return "";
3162
+ }
3163
+ const lines = ["## Recent Activity", ""];
3164
+ lines.push("A snapshot of this mesh's recent ledger/queue state at launch. Use it to decide what needs attention first; call `mesh_task_history` / `mesh_view_queue` for full detail.");
3165
+ lines.push("");
3166
+ const counts = [];
3167
+ if (pending > 0) counts.push(`**${pending}** pending`);
3168
+ if (assigned > 0) counts.push(`**${assigned}** assigned`);
3169
+ if (stalled > 0) counts.push(`**${stalled}** stalled`);
3170
+ if (recentFailureCount > 0) counts.push(`**${recentFailureCount}** failed in the last 30 min`);
3171
+ if (counts.length) lines.push(`- Queue/ledger: ${counts.join(", ")}.`);
3172
+ if (activity.lastActivityAt) lines.push(`- Last ledger activity: ${activity.lastActivityAt}.`);
3173
+ if (failures.length > 0) {
3174
+ const recent = failures.slice(-5).reverse();
3175
+ lines.push("", "Recent failures (newest first):");
3176
+ for (const f of recent) {
3177
+ const when = f.timestamp ? `${f.timestamp} ` : "";
3178
+ const node = f.nodeId ? `node \`${f.nodeId}\`` : "unknown node";
3179
+ const summary = (f.summary || "").trim();
3180
+ lines.push(`- ${when}${node}${summary ? ` \u2014 ${summary}` : ""}`);
3181
+ }
3182
+ lines.push("", "_Check `mesh_task_history` before retrying; repeated failures on the same node mean reassign or escalate, not retry._");
3183
+ }
3184
+ return lines.join("\n");
3185
+ }
3186
+ function buildOperatingNotesSection(notes) {
3187
+ const valid = Array.isArray(notes) ? notes.filter((n) => n && typeof n.text === "string" && n.text.trim()) : [];
3188
+ if (valid.length === 0) return "";
3189
+ const categoryLabel = {
3190
+ provider_quirk: "provider quirk",
3191
+ pattern_to_avoid: "pattern to avoid",
3192
+ recovery_lesson: "recovery lesson"
3193
+ };
3194
+ const lines = ["## Operating Notes", ""];
3195
+ lines.push("Lessons earlier coordinators on this mesh recorded via `mesh_record_note`. Treat them as accumulated operating knowledge \u2014 apply them. When you learn a durable lesson (a provider quirk, a pattern to avoid, a recovery lesson), record it with `mesh_record_note` so future coordinators inherit it.");
3196
+ lines.push("");
3197
+ for (const n of valid) {
3198
+ const cat = n.category && categoryLabel[n.category] ? `[${categoryLabel[n.category]}] ` : "";
3199
+ lines.push(`- ${cat}${n.text.trim()}`);
3200
+ }
3201
+ return lines.join("\n");
3202
+ }
3147
3203
  function buildPolicySection(policy) {
3148
3204
  const rules = [];
3149
3205
  if (policy.requirePreTaskCheckpoint) rules.push("- Create a git checkpoint **before** starting each task");
@@ -3207,6 +3263,7 @@ var init_coordinator_prompt = __esm({
3207
3263
  | \`mesh_read_chat\` | Read recent chat messages from a delegated agent session |
3208
3264
  | \`mesh_read_debug\` | Collect a daemon-side chat/parser debug bundle for a session |
3209
3265
  | \`mesh_task_history\` | Read the task ledger \u2014 dispatches, completions, failures. Use to understand what has been done before deciding next steps |
3266
+ | \`mesh_record_note\` | Record a durable, provider-neutral operating note (provider quirk / pattern to avoid / recovery lesson). Future coordinators see it under "## Operating Notes" at launch |
3210
3267
  | \`mesh_git_status\` | Check git status on a specific node |
3211
3268
  | \`mesh_read_node_logs\` | Fetch a remote node's daemon log tail directly over P2P (grep/since/byte-bounded, secrets redacted) \u2014 no session/PowerShell needed to debug a node's daemon |
3212
3269
  | \`mesh_fast_forward_node\` | Safely dry-run or explicitly execute an obvious clean fast-forward without launching an agent session |
@@ -8749,7 +8806,7 @@ var init_mesh_events_utils = __esm({
8749
8806
  "src/mesh/mesh-events-utils.ts"() {
8750
8807
  "use strict";
8751
8808
  MESH_SURFACED_PREVIEW_MAX_CHARS = 512;
8752
- MESH_COMPLETION_SURFACE_MAX_CHARS = 4e3;
8809
+ MESH_COMPLETION_SURFACE_MAX_CHARS = 16e3;
8753
8810
  }
8754
8811
  });
8755
8812
 
@@ -9389,6 +9446,22 @@ function isWeakCompletionLedgerPayload(payload) {
9389
9446
  const diag = readRecord4(payload.completionDiagnostic);
9390
9447
  return diag?.finalAssistantPresent === false || diag?.blockReason === "missing_final_assistant";
9391
9448
  }
9449
+ function findTerminalLedgerEvidenceForTask(args) {
9450
+ const taskId = readNonEmptyString2(args.taskId);
9451
+ if (!taskId) return null;
9452
+ const entries = readLedgerEntries(args.meshId, { tail: args.tail ?? 500 });
9453
+ for (let i = entries.length - 1; i >= 0; i--) {
9454
+ const entry = entries[i];
9455
+ if (entry.kind !== "task_completed" && entry.kind !== "task_failed" && entry.kind !== "task_stalled") continue;
9456
+ const terminalTaskId = readNonEmptyString2(entry.payload?.taskId);
9457
+ if (terminalTaskId !== taskId) continue;
9458
+ if (entry.kind === "task_completed" && isWeakCompletionLedgerPayload(entry.payload)) continue;
9459
+ if (args.sessionId && entry.sessionId && entry.sessionId !== args.sessionId) continue;
9460
+ if (!args.sessionId && args.nodeId && entry.nodeId && !meshNodeIdMatches(entry, args.nodeId)) continue;
9461
+ return { id: entry.id, kind: entry.kind, payload: entry.payload || {}, timestamp: entry.timestamp };
9462
+ }
9463
+ return null;
9464
+ }
9392
9465
  function findDirectDispatchLedgerEntry(args) {
9393
9466
  const entries = readLedgerEntries(args.meshId, { tail: 500 });
9394
9467
  for (let i = entries.length - 1; i >= 0; i--) {
@@ -11517,7 +11590,7 @@ var init_chat_message_normalization = __esm({
11517
11590
  "src/providers/chat-message-normalization.ts"() {
11518
11591
  "use strict";
11519
11592
  init_contracts();
11520
- DEFAULT_FINAL_SUMMARY_MAX_CHARS = 4e3;
11593
+ DEFAULT_FINAL_SUMMARY_MAX_CHARS = 16e3;
11521
11594
  BUILTIN_CHAT_MESSAGE_KINDS = ["standard", "thought", "tool", "terminal", "system"];
11522
11595
  CHAT_MESSAGE_VISIBILITIES = ["user", "debug", "internal", "hidden"];
11523
11596
  CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES = ["visible", "chat", "user", "debug", "internal", "hidden"];
@@ -12924,6 +12997,18 @@ function isWeakTerminalLedgerPayload(payload) {
12924
12997
  const diag = readRecord4(payload.completionDiagnostic);
12925
12998
  return diag?.finalAssistantPresent === false || diag?.blockReason === "missing_final_assistant";
12926
12999
  }
13000
+ function supersedesTruncatedTerminalSummary(args) {
13001
+ if (!args.terminalTaskId || !args.eventTaskId || args.terminalTaskId !== args.eventTaskId) return false;
13002
+ if (!isGenuineCompletionEvidence(args.metadataEvent)) return false;
13003
+ const terminalSummary = readNonEmptyString2(args.terminalPayload.finalSummary);
13004
+ const eventSummary = readNonEmptyString2(args.metadataEvent.finalSummary);
13005
+ if (!eventSummary) return false;
13006
+ if (terminalSummary === eventSummary) return false;
13007
+ if (isWeakTerminalLedgerPayload(args.terminalPayload)) return false;
13008
+ if (!terminalSummary) return true;
13009
+ if (eventSummary.startsWith(terminalSummary)) return true;
13010
+ return eventSummary.length > terminalSummary.length + 32;
13011
+ }
12927
13012
  function resolveActiveDirectDispatchTaskId(meshId, sessionId) {
12928
13013
  try {
12929
13014
  const matches = getActiveDirectDispatches(meshId).filter((d) => d.sessionId === sessionId);
@@ -13033,6 +13118,23 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
13033
13118
  if (!task) {
13034
13119
  return false;
13035
13120
  }
13121
+ const terminal = findTerminalLedgerEvidenceForTask({
13122
+ meshId,
13123
+ taskId: task.id
13124
+ });
13125
+ if (terminal) {
13126
+ const status = terminal.kind === "task_completed" ? "completed" : "failed";
13127
+ updateTaskStatus(meshId, task.id, status);
13128
+ LOG.info("MeshQueue", `Skipped dispatch for terminal task ${task.id} on mesh ${meshId}; ${terminal.kind} ledger evidence already exists`);
13129
+ traceMeshEventDrop("dispatch_terminal_ledger", {
13130
+ taskId: task.id,
13131
+ sessionId,
13132
+ nodeId,
13133
+ meshId,
13134
+ event: "agent_command"
13135
+ }, terminal.kind);
13136
+ return false;
13137
+ }
13036
13138
  LOG.info("MeshQueue", `Node ${nodeId} (${sessionId}) pulled task ${task.id}`);
13037
13139
  if (node?.daemonId && components.dispatchMeshCommand) {
13038
13140
  const isLocalNode = components.cliManager.adapters.has(sessionId);
@@ -13823,7 +13925,13 @@ function evaluateMeshEventSuppression(args, ctx) {
13823
13925
  const terminalTaskId = readNonEmptyString2(terminal.payload.taskId);
13824
13926
  const eventTaskId = readNonEmptyString2(args.metadataEvent.taskId);
13825
13927
  const distinctTaskCompletion = !!eventTaskId && !!terminalTaskId && eventTaskId !== terminalTaskId;
13826
- if (!newDispatchAfterTerminal && !supersedesWeakTerminal && !distinctTaskCompletion) {
13928
+ const supersedesTruncatedTerminal = supersedesTruncatedTerminalSummary({
13929
+ terminalPayload: terminal.payload,
13930
+ metadataEvent: args.metadataEvent,
13931
+ terminalTaskId,
13932
+ eventTaskId
13933
+ });
13934
+ if (!newDispatchAfterTerminal && !supersedesWeakTerminal && !distinctTaskCompletion && !supersedesTruncatedTerminal) {
13827
13935
  const terminalProviderSessionId = readNonEmptyString2(terminal.payload.providerSessionId);
13828
13936
  const terminalFinalSummary = readNonEmptyString2(terminal.payload.finalSummary);
13829
13937
  const eventProviderSessionId = readNonEmptyString2(args.metadataEvent.providerSessionId);
@@ -14570,20 +14678,24 @@ function daemonHostsMesh(mesh, daemonIds) {
14570
14678
  if (host.role && host.role !== "host") return false;
14571
14679
  const hostDaemonId = readNonEmptyString2(host.hostDaemonId);
14572
14680
  if (!hostDaemonId) return true;
14573
- return daemonIds.includes(hostDaemonId);
14681
+ return daemonIdListIncludes(daemonIds, hostDaemonId);
14682
+ }
14683
+ function daemonIdListIncludes(ids, id) {
14684
+ if (!id) return false;
14685
+ return ids.some((candidate) => candidate === id || daemonIdsEquivalent(candidate, id));
14574
14686
  }
14575
14687
  function resolveCoordinatorSelfIds(mesh, drainDaemonIds) {
14576
14688
  const ids = new Set(drainDaemonIds);
14577
14689
  for (const node of mesh.nodes) {
14578
14690
  const nodeDaemonId = readNonEmptyString2(node.daemonId);
14579
14691
  const nodeMachineId = readNonEmptyString2(node.machineId);
14580
- const isSelf = nodeDaemonId && drainDaemonIds.includes(nodeDaemonId) || nodeMachineId && drainDaemonIds.includes(nodeMachineId);
14692
+ const isSelf = nodeDaemonId && daemonIdListIncludes(drainDaemonIds, nodeDaemonId) || nodeMachineId && daemonIdListIncludes(drainDaemonIds, nodeMachineId);
14581
14693
  if (!isSelf) continue;
14582
14694
  if (nodeDaemonId) ids.add(nodeDaemonId);
14583
14695
  if (nodeMachineId) ids.add(nodeMachineId);
14584
14696
  }
14585
14697
  const hostDaemonId = readNonEmptyString2(mesh.meshHost?.hostDaemonId);
14586
- if (hostDaemonId && ids.has(hostDaemonId)) ids.add(hostDaemonId);
14698
+ if (hostDaemonId && daemonIdListIncludes([...ids], hostDaemonId)) ids.add(hostDaemonId);
14587
14699
  return [...ids];
14588
14700
  }
14589
14701
  function findLiveCoordinators(components) {
@@ -14596,6 +14708,16 @@ function findLiveCoordinators(components) {
14596
14708
  const status = readNonEmptyString2(state.status).toLowerCase();
14597
14709
  const modalParked = status === "waiting_choice" || status === "waiting_approval";
14598
14710
  const sessionId = readNonEmptyString2(state.instanceId);
14711
+ const stateKey = `${meshId}::${sessionId || "?"}`;
14712
+ const prevParked = coordinatorModalParkState.get(stateKey);
14713
+ if (prevParked !== modalParked) {
14714
+ coordinatorModalParkState.set(stateKey, modalParked);
14715
+ if (modalParked) {
14716
+ LOG.info("MeshReconcile", `Coordinator ${sessionId || "?"} (mesh ${meshId}) entered modal-park (status=${status}) \u2014 terminal events for it will be held until the modal is answered`);
14717
+ } else if (prevParked === true) {
14718
+ LOG.info("MeshReconcile", `Coordinator ${sessionId || "?"} (mesh ${meshId}) left modal-park (status=${status}) \u2014 held events will drain on this/next tick`);
14719
+ }
14720
+ }
14599
14721
  out.push({ meshId, instance: inst, sessionId, idle: status === "idle", modalParked });
14600
14722
  }
14601
14723
  return out;
@@ -14661,6 +14783,23 @@ function recoverStrandedAssignedDispatches(meshId, store) {
14661
14783
  const dispatchedAtMs = Date.parse(row.dispatchTimestamp ?? "");
14662
14784
  if (!Number.isFinite(dispatchedAtMs)) continue;
14663
14785
  if (nowMs - dispatchedAtMs < ASSIGNED_STRANDED_DEADLINE_MS) continue;
14786
+ const terminal = findTerminalLedgerEvidenceForTask({
14787
+ meshId,
14788
+ taskId: row.id
14789
+ });
14790
+ if (terminal) {
14791
+ const status = terminal.kind === "task_completed" ? "completed" : "failed";
14792
+ updateTaskStatus(meshId, row.id, status);
14793
+ LOG.warn("MeshReconcile", `Skipped stranded reclaim redispatch for terminal task ${row.id} on mesh ${meshId}; ${terminal.kind} ledger evidence already exists`);
14794
+ traceMeshEventDrop("assigned_stranded_terminal_ledger", {
14795
+ taskId: row.id,
14796
+ sessionId: row.assignedSessionId,
14797
+ nodeId: row.assignedNodeId,
14798
+ meshId,
14799
+ event: "agent:generating_completed"
14800
+ }, terminal.kind);
14801
+ continue;
14802
+ }
14664
14803
  if (store.taskHasConfirmedDelivery(meshId, row.id)) continue;
14665
14804
  const reclaimed = reclaimStrandedAssignedTask(meshId, row.id, {
14666
14805
  reason: "assigned_stranded_dispatch_unconfirmed",
@@ -14772,7 +14911,55 @@ async function runMeshReconcileTick(components) {
14772
14911
  const forceOnly = idleCoordinators.length === 0;
14773
14912
  if (targetCoordinators.length === 0) {
14774
14913
  if (modalParkedCoordinators.length > 0) {
14775
- LOG.info("MeshReconcile", `Reconcile skip \u2192 modal-parked: holding pending event(s) for mesh ${meshId} (${modalParkedCoordinators.length} coordinator(s) awaiting a modal answer; events left queued)`);
14914
+ const liveSessionIds = new Set(
14915
+ meshCoordinators.map((c) => readNonEmptyString2(c.sessionId)).filter(Boolean)
14916
+ );
14917
+ let orphanEscaped = 0;
14918
+ const hasPendingForOrphanPeek = !store || (() => {
14919
+ try {
14920
+ return store.pendingEventCount(meshId) > 0;
14921
+ } catch {
14922
+ return true;
14923
+ }
14924
+ })();
14925
+ if (hasPendingForOrphanPeek) {
14926
+ let peeked = [];
14927
+ try {
14928
+ peeked = getPendingMeshCoordinatorEvents(meshId, drainDaemonIds.length > 0 ? drainDaemonIds : void 0);
14929
+ } catch {
14930
+ peeked = [];
14931
+ }
14932
+ const isOrphan = (e) => {
14933
+ const want = readNonEmptyString2(e.targetCoordinatorSessionId);
14934
+ return !!want && !liveSessionIds.has(want);
14935
+ };
14936
+ const orphanEventNames = new Set(peeked.filter(isOrphan).map((e) => e.event));
14937
+ if (orphanEventNames.size > 0) {
14938
+ let drained = [];
14939
+ try {
14940
+ drained = drainPendingMeshCoordinatorEvents(
14941
+ meshId,
14942
+ drainDaemonIds.length > 0 ? drainDaemonIds : localDaemonId,
14943
+ { onlyEvents: orphanEventNames }
14944
+ );
14945
+ } catch (e) {
14946
+ LOG.warn("MeshReconcile", `Orphan-escape drain failed for mesh ${meshId}: ${e?.message || e}`);
14947
+ drained = [];
14948
+ }
14949
+ for (const pending of drained) {
14950
+ if (isOrphan(pending)) {
14951
+ holdOrExpireStrictUnmatchedEvent(pending, readNonEmptyString2(pending.targetCoordinatorSessionId), meshId);
14952
+ orphanEscaped++;
14953
+ } else {
14954
+ try {
14955
+ queuePendingMeshCoordinatorEvent(pending);
14956
+ } catch {
14957
+ }
14958
+ }
14959
+ }
14960
+ }
14961
+ }
14962
+ LOG.info("MeshReconcile", `Reconcile skip \u2192 modal-parked: holding pending event(s) for mesh ${meshId} (${modalParkedCoordinators.length} coordinator(s) awaiting a modal answer; events left queued${orphanEscaped > 0 ? `; ${orphanEscaped} orphan-targeted event(s) routed to strict-route TTL` : ""})`);
14776
14963
  let hasPending = true;
14777
14964
  if (store) {
14778
14965
  try {
@@ -14957,7 +15144,7 @@ async function pullRemoteNodeQueues(components, mesh, localDaemonId, candidateDa
14957
15144
  const nodeDaemonId = readNonEmptyString2(node.daemonId);
14958
15145
  if (!nodeDaemonId) continue;
14959
15146
  if (daemonIdsEquivalent(nodeDaemonId, localDaemonId)) continue;
14960
- if (candidateDaemonIds.includes(nodeDaemonId)) continue;
15147
+ if (daemonIdListIncludes(candidateDaemonIds, nodeDaemonId)) continue;
14961
15148
  for (const pendingEventArgs of pulls) {
14962
15149
  let events;
14963
15150
  try {
@@ -15013,7 +15200,7 @@ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds,
15013
15200
  if (!sessionId || !nodeId || !taskId) continue;
15014
15201
  const node = nodeById.get(nodeId);
15015
15202
  const nodeDaemonId = readNonEmptyString2(node?.daemonId);
15016
- const isLocalNode = !nodeDaemonId || selfIds.includes(nodeDaemonId) || daemonIdsEquivalent(nodeDaemonId, localDaemonId) || !!components.instanceManager.getInstance(sessionId);
15203
+ const isLocalNode = !nodeDaemonId || daemonIdListIncludes(selfIds, nodeDaemonId) || daemonIdsEquivalent(nodeDaemonId, localDaemonId) || !!components.instanceManager.getInstance(sessionId);
15017
15204
  const providerType = readNonEmptyString2(dispatch.providerType);
15018
15205
  const readArgs = {
15019
15206
  sessionId,
@@ -15043,6 +15230,19 @@ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds,
15043
15230
  const messages = Array.isArray(payload.messages) ? payload.messages : [];
15044
15231
  const evidence = extractFinalAssistantSummaryEvidence(messages);
15045
15232
  if (!evidence.finalSummary) continue;
15233
+ const dispatchedAtMs = Date.parse(readNonEmptyString2(dispatch.dispatchedAt));
15234
+ const transcriptAtMs = Date.parse(evidence.transcriptMessageAt ?? "");
15235
+ if (Number.isFinite(dispatchedAtMs) && Number.isFinite(transcriptAtMs) && transcriptAtMs < dispatchedAtMs) {
15236
+ LOG.info("MeshReconcile", `Stale-summary guard: skipping transcript reconcile for task ${taskId} on node ${nodeId} (mesh ${mesh.id}) \u2014 final assistant message (${evidence.transcriptMessageAt}) predates this task's dispatch (${dispatch.dispatchedAt}); it is a prior task's summary`);
15237
+ traceMeshEventDrop("reconcile_stale_summary_before_dispatch", {
15238
+ taskId,
15239
+ sessionId,
15240
+ nodeId,
15241
+ meshId: mesh.id,
15242
+ event: "agent:generating_completed"
15243
+ }, `transcriptAt=${evidence.transcriptMessageAt} < dispatchedAt=${dispatch.dispatchedAt}`);
15244
+ continue;
15245
+ }
15046
15246
  const providerSessionId = readNonEmptyString2(payload.providerSessionId);
15047
15247
  const coordinatorDaemonId = selfIds.find((id) => !!id);
15048
15248
  try {
@@ -15088,7 +15288,7 @@ async function collectLiveNodesWithSessions(components, mesh, selfIds, localDaem
15088
15288
  const dispatchMeshCommand = components.dispatchMeshCommand;
15089
15289
  return Promise.all(mesh.nodes.map(async (node) => {
15090
15290
  const nodeDaemonId = readNonEmptyString2(node.daemonId);
15091
- const isLocalNode = !nodeDaemonId || selfIds.includes(nodeDaemonId) || daemonIdsEquivalent(nodeDaemonId, localDaemonId);
15291
+ const isLocalNode = !nodeDaemonId || daemonIdListIncludes(selfIds, nodeDaemonId) || daemonIdsEquivalent(nodeDaemonId, localDaemonId);
15092
15292
  let statusResult;
15093
15293
  try {
15094
15294
  if (isLocalNode) {
@@ -15170,7 +15370,7 @@ function setupMeshReconcileLoop(components) {
15170
15370
  }
15171
15371
  };
15172
15372
  }
15173
- var DEFAULT_RECONCILE_INTERVAL_MS, DEFAULT_AUTO_PRUNE_MIN_AGE_MS, heldEventLedgerRecorded, ASSIGNED_STRANDED_DEADLINE_MS, STRICT_SESSION_MATCH_TTL_MS, unresolvedForwardRejectionCounts, MAX_FORWARD_REJECTIONS;
15373
+ var DEFAULT_RECONCILE_INTERVAL_MS, DEFAULT_AUTO_PRUNE_MIN_AGE_MS, coordinatorModalParkState, heldEventLedgerRecorded, ASSIGNED_STRANDED_DEADLINE_MS, STRICT_SESSION_MATCH_TTL_MS, unresolvedForwardRejectionCounts, MAX_FORWARD_REJECTIONS;
15174
15374
  var init_mesh_reconcile_loop = __esm({
15175
15375
  "src/mesh/mesh-reconcile-loop.ts"() {
15176
15376
  "use strict";
@@ -15192,6 +15392,7 @@ var init_mesh_reconcile_loop = __esm({
15192
15392
  init_chat_message_normalization();
15193
15393
  DEFAULT_RECONCILE_INTERVAL_MS = 4e3;
15194
15394
  DEFAULT_AUTO_PRUNE_MIN_AGE_MS = 24 * 60 * 6e4;
15395
+ coordinatorModalParkState = /* @__PURE__ */ new Map();
15195
15396
  heldEventLedgerRecorded = /* @__PURE__ */ new Set();
15196
15397
  ASSIGNED_STRANDED_DEADLINE_MS = 5 * 6e4;
15197
15398
  STRICT_SESSION_MATCH_TTL_MS = 6e4;
@@ -38130,6 +38331,8 @@ function getMessageTime(message) {
38130
38331
  }
38131
38332
  var COMPLETED_FINALIZATION_RETRY_MS = 1e3;
38132
38333
  var COMPLETED_FINALIZATION_MAX_WAIT_MS = 3e4;
38334
+ var NATIVE_HISTORY_MESH_IDLE_SETTLE_MS = 1500;
38335
+ var USER_INPUT_ACK_DEDUP_WINDOW_MS = 6e4;
38133
38336
  var TERMINAL_MESH_EVENTS = /* @__PURE__ */ new Set([
38134
38337
  "agent:generating_completed",
38135
38338
  "agent:stopped",
@@ -38401,6 +38604,14 @@ var CliProviderInstance = class _CliProviderInstance {
38401
38604
  runtimeMessages = [];
38402
38605
  lastPersistedHistoryMessages = [];
38403
38606
  lastAcknowledgedUserInputAt = 0;
38607
+ // TASKBUBBLE-DUP: per-content last-ack timestamps so the same dispatched
38608
+ // prompt acked twice in quick succession (the worker buffers the first
38609
+ // send during bootstrap/busy, then a redelivery — dispatch-confirm-timeout
38610
+ // requeue or a reconcile re-dispatch — fires a SECOND send_chat before the
38611
+ // outbound queue drains) collapses to ONE user bubble. Keyed on the trimmed
38612
+ // content; an entry older than USER_INPUT_ACK_DEDUP_WINDOW_MS is treated as
38613
+ // a fresh, intentional resend and is NOT suppressed.
38614
+ recentUserInputAcks = /* @__PURE__ */ new Map();
38404
38615
  lastNativeSourceCanonicalCheckAt = 0;
38405
38616
  lastNativeSourceCanonicalCacheKey = void 0;
38406
38617
  cachedSqliteDb = null;
@@ -38835,6 +39046,15 @@ var CliProviderInstance = class _CliProviderInstance {
38835
39046
  const content = typeof input === "string" ? input.trim() : buildCliStructuredInputPrompt(input).trim();
38836
39047
  if (!content) return;
38837
39048
  const receivedAt = Date.now();
39049
+ const ackContentKey = shortHash(`${this.instanceId}:${content}`, 24);
39050
+ const lastAckAt = this.recentUserInputAcks.get(ackContentKey);
39051
+ if (lastAckAt !== void 0 && receivedAt - lastAckAt <= USER_INPUT_ACK_DEDUP_WINDOW_MS) {
39052
+ this.recentUserInputAcks.set(ackContentKey, receivedAt);
39053
+ this.pruneRecentUserInputAcks(receivedAt);
39054
+ return;
39055
+ }
39056
+ this.recentUserInputAcks.set(ackContentKey, receivedAt);
39057
+ this.pruneRecentUserInputAcks(receivedAt);
38838
39058
  this.lastAcknowledgedUserInputAt = receivedAt;
38839
39059
  const dedupKey = `user_input_ack:${shortHash(`${this.instanceId}:${content}:${receivedAt}`, 24)}`;
38840
39060
  this.appendRuntimeMessage(buildChatMessage({
@@ -38852,6 +39072,13 @@ var CliProviderInstance = class _CliProviderInstance {
38852
39072
  }
38853
39073
  }), dedupKey);
38854
39074
  }
39075
+ /** Drop user-input ack entries older than the dedup window so the map can't grow unbounded. */
39076
+ pruneRecentUserInputAcks(now) {
39077
+ if (this.recentUserInputAcks.size <= 1) return;
39078
+ for (const [key, at] of this.recentUserInputAcks) {
39079
+ if (now - at > USER_INPUT_ACK_DEDUP_WINDOW_MS) this.recentUserInputAcks.delete(key);
39080
+ }
39081
+ }
38855
39082
  dispose() {
38856
39083
  this.adapter.shutdown();
38857
39084
  this.monitor.reset();
@@ -39541,8 +39768,9 @@ var CliProviderInstance = class _CliProviderInstance {
39541
39768
  previousStatus: this.lastStatus
39542
39769
  };
39543
39770
  const ownsExternalHistory = !!this.adapter?.chatMessagesOwnedExternally;
39544
- const flushDelay = ownsExternalHistory ? 0 : 3e3;
39545
- LOG.debug("CLI", `[${this.type}] set completedDebouncePending duration=${duration}s ownsExternalHistory=${ownsExternalHistory} flushDelay=${flushDelay}ms generatingStartedAt=${this.generatingStartedAt}`);
39771
+ const meshWorkerSession = this.isMeshWorkerSession();
39772
+ const flushDelay = ownsExternalHistory ? meshWorkerSession ? NATIVE_HISTORY_MESH_IDLE_SETTLE_MS : 0 : 3e3;
39773
+ LOG.debug("CLI", `[${this.type}] set completedDebouncePending duration=${duration}s ownsExternalHistory=${ownsExternalHistory} meshWorker=${meshWorkerSession} flushDelay=${flushDelay}ms generatingStartedAt=${this.generatingStartedAt}`);
39546
39774
  this.scheduleCompletedDebounceFlush(flushDelay);
39547
39775
  }
39548
39776
  } else if (newStatus === "idle" && this.lastStatus === "starting") {
@@ -42597,11 +42825,11 @@ var cliAgentHandlers = {
42597
42825
  }
42598
42826
  }
42599
42827
  }
42600
- const agentResult = await ctx.deps.cliManager.handleCliCommand("agent_command", args);
42601
42828
  const meshCtx = args?.meshContext;
42602
42829
  const dispatchNodeId = readStringValue(meshCtx?.nodeId);
42603
42830
  const dispatchMeshId = readStringValue(meshCtx?.meshId);
42604
- if (dispatchNodeId && dispatchMeshId && agentResult?.success !== false) {
42831
+ const isSendChat = args?.action === "send_chat";
42832
+ if (isSendChat && dispatchNodeId && dispatchMeshId) {
42605
42833
  try {
42606
42834
  const { getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
42607
42835
  const meshObj = getMesh2(dispatchMeshId) ?? ctx.getCachedInlineMesh(dispatchMeshId);
@@ -42609,17 +42837,22 @@ var cliAgentHandlers = {
42609
42837
  const bootstrapStatus = readStringValue(nodeObj?.worktreeBootstrap?.status);
42610
42838
  if (bootstrapStatus === "running") {
42611
42839
  return {
42612
- success: true,
42613
- ...agentResult,
42614
- dispatchAcknowledgementRisk: true,
42615
- dispatchAcknowledgementRiskReason: "bootstrap_still_running",
42616
- nextAction: "Wait for worktree_bootstrap_complete event before dispatching work to this node."
42840
+ success: false,
42841
+ recoverable: true,
42842
+ dispatched: false,
42843
+ code: "mesh_node_bootstrap_pending",
42844
+ reason: "bootstrap_still_running",
42845
+ nodeId: dispatchNodeId,
42846
+ meshId: dispatchMeshId,
42847
+ ...readStringValue(meshCtx?.taskId) ? { taskId: readStringValue(meshCtx?.taskId) } : {},
42848
+ 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.`,
42849
+ 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."
42617
42850
  };
42618
42851
  }
42619
42852
  } catch {
42620
42853
  }
42621
42854
  }
42622
- return agentResult;
42855
+ return ctx.deps.cliManager.handleCliCommand("agent_command", args);
42623
42856
  },
42624
42857
  // ─── Logs ───
42625
42858
  list_saved_sessions: async (ctx, args) => {
@@ -46871,7 +47104,7 @@ var meshCrudHandlers = {
46871
47104
  return "";
46872
47105
  }
46873
47106
  })();
46874
- const isCoordinatorBaseNode = !!selfDaemonId && (nodeDaemonId === selfDaemonId || nodeMachineId === selfDaemonId) || !!selfMachineId && (nodeDaemonId === selfMachineId || nodeMachineId === selfMachineId);
47107
+ const isCoordinatorBaseNode = !!selfDaemonId && (daemonIdsEquivalent(nodeDaemonId, selfDaemonId) || daemonIdsEquivalent(nodeMachineId, selfDaemonId)) || !!selfMachineId && (daemonIdsEquivalent(nodeDaemonId, selfMachineId) || daemonIdsEquivalent(nodeMachineId, selfMachineId));
46875
47108
  if (isCoordinatorBaseNode) {
46876
47109
  return {
46877
47110
  success: false,
@@ -47741,49 +47974,72 @@ var fastForwardHandlers = {
47741
47974
  };
47742
47975
  },
47743
47976
  fast_forward_mesh_node: async (ctx, args) => {
47744
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
47745
- const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
47746
- let workspace = typeof args?.workspace === "string" ? args.workspace.trim() : "";
47747
- let submoduleIgnorePaths = Array.isArray(args?.submoduleIgnorePaths) ? args.submoduleIgnorePaths.filter((value) => typeof value === "string") : void 0;
47748
- let nodeDaemonId;
47749
- let allowAutoPublishSubmoduleMainCommits = false;
47750
- if (meshId && nodeId) {
47751
- const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
47752
- const mesh = meshRecord?.mesh;
47753
- const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
47754
- if (!workspace) {
47755
- workspace = typeof node?.workspace === "string" ? node.workspace.trim() : "";
47977
+ const workspaceForError = typeof args?.workspace === "string" ? args.workspace.trim() : "";
47978
+ const meshIdForError = typeof args?.meshId === "string" ? args.meshId.trim() : "";
47979
+ const nodeIdForError = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
47980
+ try {
47981
+ const meshId = meshIdForError;
47982
+ const nodeId = nodeIdForError;
47983
+ let workspace = workspaceForError;
47984
+ let submoduleIgnorePaths = Array.isArray(args?.submoduleIgnorePaths) ? args.submoduleIgnorePaths.filter((value) => typeof value === "string") : void 0;
47985
+ let nodeDaemonId;
47986
+ let allowAutoPublishSubmoduleMainCommits = false;
47987
+ if (meshId && nodeId) {
47988
+ const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
47989
+ const mesh = meshRecord?.mesh;
47990
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
47991
+ if (!workspace) {
47992
+ workspace = typeof node?.workspace === "string" ? node.workspace.trim() : "";
47993
+ }
47994
+ if (!submoduleIgnorePaths && Array.isArray(node?.policy?.submoduleIgnorePaths)) {
47995
+ submoduleIgnorePaths = node.policy.submoduleIgnorePaths.filter((value) => typeof value === "string");
47996
+ }
47997
+ allowAutoPublishSubmoduleMainCommits = mesh?.policy?.allowAutoPublishSubmoduleMainCommits === true;
47998
+ nodeDaemonId = typeof node?.daemonId === "string" ? node.daemonId.trim() : void 0;
47756
47999
  }
47757
- if (!submoduleIgnorePaths && Array.isArray(node?.policy?.submoduleIgnorePaths)) {
47758
- submoduleIgnorePaths = node.policy.submoduleIgnorePaths.filter((value) => typeof value === "string");
48000
+ const selfDaemonId = ctx.deps.statusInstanceId;
48001
+ const isRemote = nodeDaemonId && selfDaemonId && !daemonIdsEquivalent(nodeDaemonId, selfDaemonId);
48002
+ if (isRemote && ctx.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
48003
+ const forwarded = await ctx.deps.dispatchMeshCommand(nodeDaemonId, "fast_forward_mesh_node", {
48004
+ ...typeof args === "object" && args !== null ? args : {},
48005
+ workspace,
48006
+ _meshDirectDispatch: true
48007
+ });
48008
+ return forwarded ?? { success: false, error: "no response from remote node" };
47759
48009
  }
47760
- allowAutoPublishSubmoduleMainCommits = mesh?.policy?.allowAutoPublishSubmoduleMainCommits === true;
47761
- nodeDaemonId = typeof node?.daemonId === "string" ? node.daemonId.trim() : void 0;
47762
- }
47763
- const selfDaemonId = ctx.deps.statusInstanceId;
47764
- const isRemote = nodeDaemonId && selfDaemonId && !daemonIdsEquivalent(nodeDaemonId, selfDaemonId);
47765
- if (isRemote && ctx.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
47766
- const forwarded = await ctx.deps.dispatchMeshCommand(nodeDaemonId, "fast_forward_mesh_node", {
47767
- ...typeof args === "object" && args !== null ? args : {},
48010
+ const result = await fastForwardMeshNode({
48011
+ meshId: meshId || void 0,
48012
+ nodeId: nodeId || void 0,
47768
48013
  workspace,
47769
- _meshDirectDispatch: true
48014
+ branch: typeof args?.branch === "string" ? args.branch : void 0,
48015
+ execute: args?.execute === true,
48016
+ dryRun: args?.dryRun === true,
48017
+ updateSubmodules: args?.updateSubmodules === true,
48018
+ submoduleIgnorePaths,
48019
+ mode: args?.mode === "push" ? "push" : "merge",
48020
+ pushSubmodules: args?.pushSubmodules === true,
48021
+ allowAutoPublishSubmoduleMainCommits
47770
48022
  });
47771
- return forwarded ?? { success: false, error: "no response from remote node" };
48023
+ return result;
48024
+ } catch (e) {
48025
+ const errorMessage = e?.message || String(e);
48026
+ return {
48027
+ success: false,
48028
+ code: "fast_forward_safety_gate_error",
48029
+ ...meshIdForError ? { meshId: meshIdForError } : {},
48030
+ ...nodeIdForError ? { nodeId: nodeIdForError } : {},
48031
+ workspace: workspaceForError,
48032
+ mode: args?.mode === "push" ? "push" : "merge",
48033
+ allowed: false,
48034
+ willRun: false,
48035
+ executed: false,
48036
+ // Surface the throw as a blocking reason instead of an opaque IPC crash
48037
+ // so the coordinator gets the same structured shape a clean node returns.
48038
+ blockingReasons: ["fast_forward_safety_gate_error"],
48039
+ operationError: errorMessage,
48040
+ error: errorMessage
48041
+ };
47772
48042
  }
47773
- const result = await fastForwardMeshNode({
47774
- meshId: meshId || void 0,
47775
- nodeId: nodeId || void 0,
47776
- workspace,
47777
- branch: typeof args?.branch === "string" ? args.branch : void 0,
47778
- execute: args?.execute === true,
47779
- dryRun: args?.dryRun === true,
47780
- updateSubmodules: args?.updateSubmodules === true,
47781
- submoduleIgnorePaths,
47782
- mode: args?.mode === "push" ? "push" : "merge",
47783
- pushSubmodules: args?.pushSubmodules === true,
47784
- allowAutoPublishSubmoduleMainCommits
47785
- });
47786
- return result;
47787
48043
  },
47788
48044
  refine_mesh_node: async (ctx, args) => {
47789
48045
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
@@ -47940,6 +48196,56 @@ var meshCoordinatorLaunchHandlers = {
47940
48196
  return "";
47941
48197
  }
47942
48198
  };
48199
+ const buildRecentActivityBestEffort = async (id) => {
48200
+ try {
48201
+ const { getLedgerSummary: getLedgerSummary2, readLedgerEntries: readLedgerEntries2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
48202
+ const { getMeshQueueStats: getMeshQueueStats2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
48203
+ const summary = getLedgerSummary2(id);
48204
+ const queue = getMeshQueueStats2(id);
48205
+ const failureEntries = readLedgerEntries2(id, { kind: ["task_failed"], tail: 5 });
48206
+ const recentFailures = failureEntries.map((e) => {
48207
+ const p = e.payload || {};
48208
+ const raw = typeof p.taskSummary === "string" ? p.taskSummary : typeof p.message === "string" ? p.message : typeof p.error === "string" ? p.error : "";
48209
+ const summaryText = raw.length > 160 ? `${raw.slice(0, 160)}\u2026` : raw;
48210
+ return {
48211
+ timestamp: e.timestamp,
48212
+ nodeId: e.nodeId,
48213
+ summary: summaryText
48214
+ };
48215
+ });
48216
+ return {
48217
+ recentFailures,
48218
+ recentFailureCount: summary.recentFailures,
48219
+ pendingTasks: queue.pending,
48220
+ assignedTasks: queue.assigned,
48221
+ stalledTasks: summary.taskStalled,
48222
+ lastActivityAt: summary.lastActivityAt
48223
+ };
48224
+ } catch {
48225
+ return void 0;
48226
+ }
48227
+ };
48228
+ const buildOperatingNotesBestEffort = async (id) => {
48229
+ try {
48230
+ const { readLedgerEntries: readLedgerEntries2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
48231
+ const noteEntries = readLedgerEntries2(id, { kind: ["coordinator_operating_note"], tail: 20 });
48232
+ const notes = noteEntries.map((e) => {
48233
+ const p = e.payload || {};
48234
+ const text = typeof p.text === "string" ? p.text.trim() : "";
48235
+ if (!text) return null;
48236
+ const category = p.category === "provider_quirk" || p.category === "pattern_to_avoid" || p.category === "recovery_lesson" ? p.category : void 0;
48237
+ return {
48238
+ text,
48239
+ category,
48240
+ createdAt: typeof p.createdAt === "string" ? p.createdAt : e.timestamp,
48241
+ sourceCoordinator: typeof p.sourceCoordinator === "string" ? p.sourceCoordinator : void 0
48242
+ };
48243
+ }).filter((n) => n !== null);
48244
+ return notes.length ? notes : void 0;
48245
+ } catch {
48246
+ return void 0;
48247
+ }
48248
+ };
47943
48249
  let mesh;
47944
48250
  if (args?.inlineMesh && typeof args.inlineMesh === "object") {
47945
48251
  mesh = args.inlineMesh;
@@ -48030,7 +48336,7 @@ var meshCoordinatorLaunchHandlers = {
48030
48336
  if (coordinatorSetup.kind === "cli_command") {
48031
48337
  let cliCmdSystemPrompt = "";
48032
48338
  try {
48033
- cliCmdSystemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType, userInstruction: extraSystemPrompt || void 0, missionSection: buildMissionSectionBestEffort(mesh.id) });
48339
+ cliCmdSystemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType, userInstruction: extraSystemPrompt || void 0, missionSection: buildMissionSectionBestEffort(mesh.id), recentActivity: await buildRecentActivityBestEffort(mesh.id), operatingNotes: await buildOperatingNotesBestEffort(mesh.id) });
48034
48340
  } catch (error) {
48035
48341
  const message = error?.message || String(error);
48036
48342
  LOG.error("MeshCoordinator", `Failed to build coordinator prompt: ${message}`);
@@ -48207,7 +48513,7 @@ ${ptyResult.output.slice(-2e3)}`);
48207
48513
  }
48208
48514
  let systemPrompt = "";
48209
48515
  try {
48210
- systemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType, userInstruction: extraSystemPrompt || void 0, missionSection: buildMissionSectionBestEffort(mesh.id) });
48516
+ systemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType, userInstruction: extraSystemPrompt || void 0, missionSection: buildMissionSectionBestEffort(mesh.id), recentActivity: await buildRecentActivityBestEffort(mesh.id), operatingNotes: await buildOperatingNotesBestEffort(mesh.id) });
48211
48517
  } catch (error) {
48212
48518
  const message = error?.message || String(error);
48213
48519
  LOG.error("MeshCoordinator", `Failed to build coordinator prompt: ${message}`);