@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.mjs CHANGED
@@ -311,10 +311,10 @@ function readInjected(value) {
311
311
  }
312
312
  function getDaemonBuildInfo() {
313
313
  if (cached) return cached;
314
- const commit = readInjected(true ? "f16b5e6cdf653b4258f8f44cb11fb6ad8c13329f" : void 0) ?? "unknown";
315
- const commitShort = readInjected(true ? "f16b5e6c" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
316
- const version = readInjected(true ? "0.9.82-rc.373" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
317
- const builtAt = readInjected(true ? "2026-06-24T16:28:52.547Z" : void 0);
314
+ const commit = readInjected(true ? "b17fb9165bd52c9e2ab8cccf2ce80734e2165680" : void 0) ?? "unknown";
315
+ const commitShort = readInjected(true ? "b17fb916" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
316
+ const version = readInjected(true ? "0.9.82-rc.375" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
317
+ const builtAt = readInjected(true ? "2026-06-25T02:21:59.111Z" : void 0);
318
318
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
319
319
  return cached;
320
320
  }
@@ -3039,6 +3039,10 @@ Default branch: \`${mesh.defaultBranch}\`` : ""}`);
3039
3039
  if (ctx.missionSection?.trim()) {
3040
3040
  sections.push(ctx.missionSection.trim());
3041
3041
  }
3042
+ const recentActivity = buildRecentActivitySection(ctx.recentActivity);
3043
+ if (recentActivity) sections.push(recentActivity);
3044
+ const operatingNotes = buildOperatingNotesSection(ctx.operatingNotes);
3045
+ if (operatingNotes) sections.push(operatingNotes);
3042
3046
  sections.push(buildPolicySection({ ...DEFAULT_MESH_POLICY, ...mesh.policy || {} }));
3043
3047
  sections.push(TOOLS_SECTION);
3044
3048
  sections.push(TOOL_EXPOSURE_PREFLIGHT_SECTION);
@@ -3070,6 +3074,8 @@ function expandPromptPlaceholders(template, ctx) {
3070
3074
  cliType: coordinatorCliType || "",
3071
3075
  nodes: nodesSection,
3072
3076
  mission: ctx.missionSection?.trim() || "",
3077
+ recentActivity: buildRecentActivitySection(ctx.recentActivity) || "",
3078
+ operatingNotes: buildOperatingNotesSection(ctx.operatingNotes) || "",
3073
3079
  policy: buildPolicySection({ ...DEFAULT_MESH_POLICY, ...mesh.policy || {} }),
3074
3080
  tools: TOOLS_SECTION,
3075
3081
  workflow: WORKFLOW_SECTION,
@@ -3141,6 +3147,56 @@ function indentFollowing(text, pad) {
3141
3147
  if (lines.length === 1) return lines[0];
3142
3148
  return [lines[0], ...lines.slice(1).map((l) => pad + l)].join("\n");
3143
3149
  }
3150
+ function buildRecentActivitySection(activity) {
3151
+ if (!activity) return "";
3152
+ const failures = Array.isArray(activity.recentFailures) ? activity.recentFailures : [];
3153
+ const pending = Number.isFinite(activity.pendingTasks) ? Number(activity.pendingTasks) : 0;
3154
+ const assigned = Number.isFinite(activity.assignedTasks) ? Number(activity.assignedTasks) : 0;
3155
+ const stalled = Number.isFinite(activity.stalledTasks) ? Number(activity.stalledTasks) : 0;
3156
+ const recentFailureCount = Number.isFinite(activity.recentFailureCount) ? Number(activity.recentFailureCount) : failures.length;
3157
+ if (failures.length === 0 && pending === 0 && assigned === 0 && stalled === 0 && recentFailureCount === 0) {
3158
+ return "";
3159
+ }
3160
+ const lines = ["## Recent Activity", ""];
3161
+ 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.");
3162
+ lines.push("");
3163
+ const counts = [];
3164
+ if (pending > 0) counts.push(`**${pending}** pending`);
3165
+ if (assigned > 0) counts.push(`**${assigned}** assigned`);
3166
+ if (stalled > 0) counts.push(`**${stalled}** stalled`);
3167
+ if (recentFailureCount > 0) counts.push(`**${recentFailureCount}** failed in the last 30 min`);
3168
+ if (counts.length) lines.push(`- Queue/ledger: ${counts.join(", ")}.`);
3169
+ if (activity.lastActivityAt) lines.push(`- Last ledger activity: ${activity.lastActivityAt}.`);
3170
+ if (failures.length > 0) {
3171
+ const recent = failures.slice(-5).reverse();
3172
+ lines.push("", "Recent failures (newest first):");
3173
+ for (const f of recent) {
3174
+ const when = f.timestamp ? `${f.timestamp} ` : "";
3175
+ const node = f.nodeId ? `node \`${f.nodeId}\`` : "unknown node";
3176
+ const summary = (f.summary || "").trim();
3177
+ lines.push(`- ${when}${node}${summary ? ` \u2014 ${summary}` : ""}`);
3178
+ }
3179
+ lines.push("", "_Check `mesh_task_history` before retrying; repeated failures on the same node mean reassign or escalate, not retry._");
3180
+ }
3181
+ return lines.join("\n");
3182
+ }
3183
+ function buildOperatingNotesSection(notes) {
3184
+ const valid = Array.isArray(notes) ? notes.filter((n) => n && typeof n.text === "string" && n.text.trim()) : [];
3185
+ if (valid.length === 0) return "";
3186
+ const categoryLabel = {
3187
+ provider_quirk: "provider quirk",
3188
+ pattern_to_avoid: "pattern to avoid",
3189
+ recovery_lesson: "recovery lesson"
3190
+ };
3191
+ const lines = ["## Operating Notes", ""];
3192
+ 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.");
3193
+ lines.push("");
3194
+ for (const n of valid) {
3195
+ const cat = n.category && categoryLabel[n.category] ? `[${categoryLabel[n.category]}] ` : "";
3196
+ lines.push(`- ${cat}${n.text.trim()}`);
3197
+ }
3198
+ return lines.join("\n");
3199
+ }
3144
3200
  function buildPolicySection(policy) {
3145
3201
  const rules = [];
3146
3202
  if (policy.requirePreTaskCheckpoint) rules.push("- Create a git checkpoint **before** starting each task");
@@ -3201,6 +3257,7 @@ var init_coordinator_prompt = __esm({
3201
3257
  | \`mesh_read_chat\` | Read recent chat messages from a delegated agent session |
3202
3258
  | \`mesh_read_debug\` | Collect a daemon-side chat/parser debug bundle for a session |
3203
3259
  | \`mesh_task_history\` | Read the task ledger \u2014 dispatches, completions, failures. Use to understand what has been done before deciding next steps |
3260
+ | \`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 |
3204
3261
  | \`mesh_git_status\` | Check git status on a specific node |
3205
3262
  | \`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 |
3206
3263
  | \`mesh_fast_forward_node\` | Safely dry-run or explicitly execute an obvious clean fast-forward without launching an agent session |
@@ -8742,7 +8799,7 @@ var init_mesh_events_utils = __esm({
8742
8799
  "src/mesh/mesh-events-utils.ts"() {
8743
8800
  "use strict";
8744
8801
  MESH_SURFACED_PREVIEW_MAX_CHARS = 512;
8745
- MESH_COMPLETION_SURFACE_MAX_CHARS = 4e3;
8802
+ MESH_COMPLETION_SURFACE_MAX_CHARS = 16e3;
8746
8803
  }
8747
8804
  });
8748
8805
 
@@ -9382,6 +9439,22 @@ function isWeakCompletionLedgerPayload(payload) {
9382
9439
  const diag = readRecord4(payload.completionDiagnostic);
9383
9440
  return diag?.finalAssistantPresent === false || diag?.blockReason === "missing_final_assistant";
9384
9441
  }
9442
+ function findTerminalLedgerEvidenceForTask(args) {
9443
+ const taskId = readNonEmptyString2(args.taskId);
9444
+ if (!taskId) return null;
9445
+ const entries = readLedgerEntries(args.meshId, { tail: args.tail ?? 500 });
9446
+ for (let i = entries.length - 1; i >= 0; i--) {
9447
+ const entry = entries[i];
9448
+ if (entry.kind !== "task_completed" && entry.kind !== "task_failed" && entry.kind !== "task_stalled") continue;
9449
+ const terminalTaskId = readNonEmptyString2(entry.payload?.taskId);
9450
+ if (terminalTaskId !== taskId) continue;
9451
+ if (entry.kind === "task_completed" && isWeakCompletionLedgerPayload(entry.payload)) continue;
9452
+ if (args.sessionId && entry.sessionId && entry.sessionId !== args.sessionId) continue;
9453
+ if (!args.sessionId && args.nodeId && entry.nodeId && !meshNodeIdMatches(entry, args.nodeId)) continue;
9454
+ return { id: entry.id, kind: entry.kind, payload: entry.payload || {}, timestamp: entry.timestamp };
9455
+ }
9456
+ return null;
9457
+ }
9385
9458
  function findDirectDispatchLedgerEntry(args) {
9386
9459
  const entries = readLedgerEntries(args.meshId, { tail: 500 });
9387
9460
  for (let i = entries.length - 1; i >= 0; i--) {
@@ -11512,7 +11585,7 @@ var init_chat_message_normalization = __esm({
11512
11585
  "src/providers/chat-message-normalization.ts"() {
11513
11586
  "use strict";
11514
11587
  init_contracts();
11515
- DEFAULT_FINAL_SUMMARY_MAX_CHARS = 4e3;
11588
+ DEFAULT_FINAL_SUMMARY_MAX_CHARS = 16e3;
11516
11589
  BUILTIN_CHAT_MESSAGE_KINDS = ["standard", "thought", "tool", "terminal", "system"];
11517
11590
  CHAT_MESSAGE_VISIBILITIES = ["user", "debug", "internal", "hidden"];
11518
11591
  CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES = ["visible", "chat", "user", "debug", "internal", "hidden"];
@@ -12920,6 +12993,18 @@ function isWeakTerminalLedgerPayload(payload) {
12920
12993
  const diag = readRecord4(payload.completionDiagnostic);
12921
12994
  return diag?.finalAssistantPresent === false || diag?.blockReason === "missing_final_assistant";
12922
12995
  }
12996
+ function supersedesTruncatedTerminalSummary(args) {
12997
+ if (!args.terminalTaskId || !args.eventTaskId || args.terminalTaskId !== args.eventTaskId) return false;
12998
+ if (!isGenuineCompletionEvidence(args.metadataEvent)) return false;
12999
+ const terminalSummary = readNonEmptyString2(args.terminalPayload.finalSummary);
13000
+ const eventSummary = readNonEmptyString2(args.metadataEvent.finalSummary);
13001
+ if (!eventSummary) return false;
13002
+ if (terminalSummary === eventSummary) return false;
13003
+ if (isWeakTerminalLedgerPayload(args.terminalPayload)) return false;
13004
+ if (!terminalSummary) return true;
13005
+ if (eventSummary.startsWith(terminalSummary)) return true;
13006
+ return eventSummary.length > terminalSummary.length + 32;
13007
+ }
12923
13008
  function resolveActiveDirectDispatchTaskId(meshId, sessionId) {
12924
13009
  try {
12925
13010
  const matches = getActiveDirectDispatches(meshId).filter((d) => d.sessionId === sessionId);
@@ -13029,6 +13114,23 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
13029
13114
  if (!task) {
13030
13115
  return false;
13031
13116
  }
13117
+ const terminal = findTerminalLedgerEvidenceForTask({
13118
+ meshId,
13119
+ taskId: task.id
13120
+ });
13121
+ if (terminal) {
13122
+ const status = terminal.kind === "task_completed" ? "completed" : "failed";
13123
+ updateTaskStatus(meshId, task.id, status);
13124
+ LOG.info("MeshQueue", `Skipped dispatch for terminal task ${task.id} on mesh ${meshId}; ${terminal.kind} ledger evidence already exists`);
13125
+ traceMeshEventDrop("dispatch_terminal_ledger", {
13126
+ taskId: task.id,
13127
+ sessionId,
13128
+ nodeId,
13129
+ meshId,
13130
+ event: "agent_command"
13131
+ }, terminal.kind);
13132
+ return false;
13133
+ }
13032
13134
  LOG.info("MeshQueue", `Node ${nodeId} (${sessionId}) pulled task ${task.id}`);
13033
13135
  if (node?.daemonId && components.dispatchMeshCommand) {
13034
13136
  const isLocalNode = components.cliManager.adapters.has(sessionId);
@@ -13819,7 +13921,13 @@ function evaluateMeshEventSuppression(args, ctx) {
13819
13921
  const terminalTaskId = readNonEmptyString2(terminal.payload.taskId);
13820
13922
  const eventTaskId = readNonEmptyString2(args.metadataEvent.taskId);
13821
13923
  const distinctTaskCompletion = !!eventTaskId && !!terminalTaskId && eventTaskId !== terminalTaskId;
13822
- if (!newDispatchAfterTerminal && !supersedesWeakTerminal && !distinctTaskCompletion) {
13924
+ const supersedesTruncatedTerminal = supersedesTruncatedTerminalSummary({
13925
+ terminalPayload: terminal.payload,
13926
+ metadataEvent: args.metadataEvent,
13927
+ terminalTaskId,
13928
+ eventTaskId
13929
+ });
13930
+ if (!newDispatchAfterTerminal && !supersedesWeakTerminal && !distinctTaskCompletion && !supersedesTruncatedTerminal) {
13823
13931
  const terminalProviderSessionId = readNonEmptyString2(terminal.payload.providerSessionId);
13824
13932
  const terminalFinalSummary = readNonEmptyString2(terminal.payload.finalSummary);
13825
13933
  const eventProviderSessionId = readNonEmptyString2(args.metadataEvent.providerSessionId);
@@ -14565,20 +14673,24 @@ function daemonHostsMesh(mesh, daemonIds) {
14565
14673
  if (host.role && host.role !== "host") return false;
14566
14674
  const hostDaemonId = readNonEmptyString2(host.hostDaemonId);
14567
14675
  if (!hostDaemonId) return true;
14568
- return daemonIds.includes(hostDaemonId);
14676
+ return daemonIdListIncludes(daemonIds, hostDaemonId);
14677
+ }
14678
+ function daemonIdListIncludes(ids, id) {
14679
+ if (!id) return false;
14680
+ return ids.some((candidate) => candidate === id || daemonIdsEquivalent(candidate, id));
14569
14681
  }
14570
14682
  function resolveCoordinatorSelfIds(mesh, drainDaemonIds) {
14571
14683
  const ids = new Set(drainDaemonIds);
14572
14684
  for (const node of mesh.nodes) {
14573
14685
  const nodeDaemonId = readNonEmptyString2(node.daemonId);
14574
14686
  const nodeMachineId = readNonEmptyString2(node.machineId);
14575
- const isSelf = nodeDaemonId && drainDaemonIds.includes(nodeDaemonId) || nodeMachineId && drainDaemonIds.includes(nodeMachineId);
14687
+ const isSelf = nodeDaemonId && daemonIdListIncludes(drainDaemonIds, nodeDaemonId) || nodeMachineId && daemonIdListIncludes(drainDaemonIds, nodeMachineId);
14576
14688
  if (!isSelf) continue;
14577
14689
  if (nodeDaemonId) ids.add(nodeDaemonId);
14578
14690
  if (nodeMachineId) ids.add(nodeMachineId);
14579
14691
  }
14580
14692
  const hostDaemonId = readNonEmptyString2(mesh.meshHost?.hostDaemonId);
14581
- if (hostDaemonId && ids.has(hostDaemonId)) ids.add(hostDaemonId);
14693
+ if (hostDaemonId && daemonIdListIncludes([...ids], hostDaemonId)) ids.add(hostDaemonId);
14582
14694
  return [...ids];
14583
14695
  }
14584
14696
  function findLiveCoordinators(components) {
@@ -14591,6 +14703,16 @@ function findLiveCoordinators(components) {
14591
14703
  const status = readNonEmptyString2(state.status).toLowerCase();
14592
14704
  const modalParked = status === "waiting_choice" || status === "waiting_approval";
14593
14705
  const sessionId = readNonEmptyString2(state.instanceId);
14706
+ const stateKey = `${meshId}::${sessionId || "?"}`;
14707
+ const prevParked = coordinatorModalParkState.get(stateKey);
14708
+ if (prevParked !== modalParked) {
14709
+ coordinatorModalParkState.set(stateKey, modalParked);
14710
+ if (modalParked) {
14711
+ 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`);
14712
+ } else if (prevParked === true) {
14713
+ LOG.info("MeshReconcile", `Coordinator ${sessionId || "?"} (mesh ${meshId}) left modal-park (status=${status}) \u2014 held events will drain on this/next tick`);
14714
+ }
14715
+ }
14594
14716
  out.push({ meshId, instance: inst, sessionId, idle: status === "idle", modalParked });
14595
14717
  }
14596
14718
  return out;
@@ -14656,6 +14778,23 @@ function recoverStrandedAssignedDispatches(meshId, store) {
14656
14778
  const dispatchedAtMs = Date.parse(row.dispatchTimestamp ?? "");
14657
14779
  if (!Number.isFinite(dispatchedAtMs)) continue;
14658
14780
  if (nowMs - dispatchedAtMs < ASSIGNED_STRANDED_DEADLINE_MS) continue;
14781
+ const terminal = findTerminalLedgerEvidenceForTask({
14782
+ meshId,
14783
+ taskId: row.id
14784
+ });
14785
+ if (terminal) {
14786
+ const status = terminal.kind === "task_completed" ? "completed" : "failed";
14787
+ updateTaskStatus(meshId, row.id, status);
14788
+ LOG.warn("MeshReconcile", `Skipped stranded reclaim redispatch for terminal task ${row.id} on mesh ${meshId}; ${terminal.kind} ledger evidence already exists`);
14789
+ traceMeshEventDrop("assigned_stranded_terminal_ledger", {
14790
+ taskId: row.id,
14791
+ sessionId: row.assignedSessionId,
14792
+ nodeId: row.assignedNodeId,
14793
+ meshId,
14794
+ event: "agent:generating_completed"
14795
+ }, terminal.kind);
14796
+ continue;
14797
+ }
14659
14798
  if (store.taskHasConfirmedDelivery(meshId, row.id)) continue;
14660
14799
  const reclaimed = reclaimStrandedAssignedTask(meshId, row.id, {
14661
14800
  reason: "assigned_stranded_dispatch_unconfirmed",
@@ -14767,7 +14906,55 @@ async function runMeshReconcileTick(components) {
14767
14906
  const forceOnly = idleCoordinators.length === 0;
14768
14907
  if (targetCoordinators.length === 0) {
14769
14908
  if (modalParkedCoordinators.length > 0) {
14770
- 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)`);
14909
+ const liveSessionIds = new Set(
14910
+ meshCoordinators.map((c) => readNonEmptyString2(c.sessionId)).filter(Boolean)
14911
+ );
14912
+ let orphanEscaped = 0;
14913
+ const hasPendingForOrphanPeek = !store || (() => {
14914
+ try {
14915
+ return store.pendingEventCount(meshId) > 0;
14916
+ } catch {
14917
+ return true;
14918
+ }
14919
+ })();
14920
+ if (hasPendingForOrphanPeek) {
14921
+ let peeked = [];
14922
+ try {
14923
+ peeked = getPendingMeshCoordinatorEvents(meshId, drainDaemonIds.length > 0 ? drainDaemonIds : void 0);
14924
+ } catch {
14925
+ peeked = [];
14926
+ }
14927
+ const isOrphan = (e) => {
14928
+ const want = readNonEmptyString2(e.targetCoordinatorSessionId);
14929
+ return !!want && !liveSessionIds.has(want);
14930
+ };
14931
+ const orphanEventNames = new Set(peeked.filter(isOrphan).map((e) => e.event));
14932
+ if (orphanEventNames.size > 0) {
14933
+ let drained = [];
14934
+ try {
14935
+ drained = drainPendingMeshCoordinatorEvents(
14936
+ meshId,
14937
+ drainDaemonIds.length > 0 ? drainDaemonIds : localDaemonId,
14938
+ { onlyEvents: orphanEventNames }
14939
+ );
14940
+ } catch (e) {
14941
+ LOG.warn("MeshReconcile", `Orphan-escape drain failed for mesh ${meshId}: ${e?.message || e}`);
14942
+ drained = [];
14943
+ }
14944
+ for (const pending of drained) {
14945
+ if (isOrphan(pending)) {
14946
+ holdOrExpireStrictUnmatchedEvent(pending, readNonEmptyString2(pending.targetCoordinatorSessionId), meshId);
14947
+ orphanEscaped++;
14948
+ } else {
14949
+ try {
14950
+ queuePendingMeshCoordinatorEvent(pending);
14951
+ } catch {
14952
+ }
14953
+ }
14954
+ }
14955
+ }
14956
+ }
14957
+ 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` : ""})`);
14771
14958
  let hasPending = true;
14772
14959
  if (store) {
14773
14960
  try {
@@ -14952,7 +15139,7 @@ async function pullRemoteNodeQueues(components, mesh, localDaemonId, candidateDa
14952
15139
  const nodeDaemonId = readNonEmptyString2(node.daemonId);
14953
15140
  if (!nodeDaemonId) continue;
14954
15141
  if (daemonIdsEquivalent(nodeDaemonId, localDaemonId)) continue;
14955
- if (candidateDaemonIds.includes(nodeDaemonId)) continue;
15142
+ if (daemonIdListIncludes(candidateDaemonIds, nodeDaemonId)) continue;
14956
15143
  for (const pendingEventArgs of pulls) {
14957
15144
  let events;
14958
15145
  try {
@@ -15008,7 +15195,7 @@ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds,
15008
15195
  if (!sessionId || !nodeId || !taskId) continue;
15009
15196
  const node = nodeById.get(nodeId);
15010
15197
  const nodeDaemonId = readNonEmptyString2(node?.daemonId);
15011
- const isLocalNode = !nodeDaemonId || selfIds.includes(nodeDaemonId) || daemonIdsEquivalent(nodeDaemonId, localDaemonId) || !!components.instanceManager.getInstance(sessionId);
15198
+ const isLocalNode = !nodeDaemonId || daemonIdListIncludes(selfIds, nodeDaemonId) || daemonIdsEquivalent(nodeDaemonId, localDaemonId) || !!components.instanceManager.getInstance(sessionId);
15012
15199
  const providerType = readNonEmptyString2(dispatch.providerType);
15013
15200
  const readArgs = {
15014
15201
  sessionId,
@@ -15038,6 +15225,19 @@ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds,
15038
15225
  const messages = Array.isArray(payload.messages) ? payload.messages : [];
15039
15226
  const evidence = extractFinalAssistantSummaryEvidence(messages);
15040
15227
  if (!evidence.finalSummary) continue;
15228
+ const dispatchedAtMs = Date.parse(readNonEmptyString2(dispatch.dispatchedAt));
15229
+ const transcriptAtMs = Date.parse(evidence.transcriptMessageAt ?? "");
15230
+ if (Number.isFinite(dispatchedAtMs) && Number.isFinite(transcriptAtMs) && transcriptAtMs < dispatchedAtMs) {
15231
+ 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`);
15232
+ traceMeshEventDrop("reconcile_stale_summary_before_dispatch", {
15233
+ taskId,
15234
+ sessionId,
15235
+ nodeId,
15236
+ meshId: mesh.id,
15237
+ event: "agent:generating_completed"
15238
+ }, `transcriptAt=${evidence.transcriptMessageAt} < dispatchedAt=${dispatch.dispatchedAt}`);
15239
+ continue;
15240
+ }
15041
15241
  const providerSessionId = readNonEmptyString2(payload.providerSessionId);
15042
15242
  const coordinatorDaemonId = selfIds.find((id) => !!id);
15043
15243
  try {
@@ -15083,7 +15283,7 @@ async function collectLiveNodesWithSessions(components, mesh, selfIds, localDaem
15083
15283
  const dispatchMeshCommand = components.dispatchMeshCommand;
15084
15284
  return Promise.all(mesh.nodes.map(async (node) => {
15085
15285
  const nodeDaemonId = readNonEmptyString2(node.daemonId);
15086
- const isLocalNode = !nodeDaemonId || selfIds.includes(nodeDaemonId) || daemonIdsEquivalent(nodeDaemonId, localDaemonId);
15286
+ const isLocalNode = !nodeDaemonId || daemonIdListIncludes(selfIds, nodeDaemonId) || daemonIdsEquivalent(nodeDaemonId, localDaemonId);
15087
15287
  let statusResult;
15088
15288
  try {
15089
15289
  if (isLocalNode) {
@@ -15165,7 +15365,7 @@ function setupMeshReconcileLoop(components) {
15165
15365
  }
15166
15366
  };
15167
15367
  }
15168
- 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;
15368
+ 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;
15169
15369
  var init_mesh_reconcile_loop = __esm({
15170
15370
  "src/mesh/mesh-reconcile-loop.ts"() {
15171
15371
  "use strict";
@@ -15187,6 +15387,7 @@ var init_mesh_reconcile_loop = __esm({
15187
15387
  init_chat_message_normalization();
15188
15388
  DEFAULT_RECONCILE_INTERVAL_MS = 4e3;
15189
15389
  DEFAULT_AUTO_PRUNE_MIN_AGE_MS = 24 * 60 * 6e4;
15390
+ coordinatorModalParkState = /* @__PURE__ */ new Map();
15190
15391
  heldEventLedgerRecorded = /* @__PURE__ */ new Set();
15191
15392
  ASSIGNED_STRANDED_DEADLINE_MS = 5 * 6e4;
15192
15393
  STRICT_SESSION_MATCH_TTL_MS = 6e4;
@@ -37756,6 +37957,8 @@ function getMessageTime(message) {
37756
37957
  }
37757
37958
  var COMPLETED_FINALIZATION_RETRY_MS = 1e3;
37758
37959
  var COMPLETED_FINALIZATION_MAX_WAIT_MS = 3e4;
37960
+ var NATIVE_HISTORY_MESH_IDLE_SETTLE_MS = 1500;
37961
+ var USER_INPUT_ACK_DEDUP_WINDOW_MS = 6e4;
37759
37962
  var TERMINAL_MESH_EVENTS = /* @__PURE__ */ new Set([
37760
37963
  "agent:generating_completed",
37761
37964
  "agent:stopped",
@@ -38027,6 +38230,14 @@ var CliProviderInstance = class _CliProviderInstance {
38027
38230
  runtimeMessages = [];
38028
38231
  lastPersistedHistoryMessages = [];
38029
38232
  lastAcknowledgedUserInputAt = 0;
38233
+ // TASKBUBBLE-DUP: per-content last-ack timestamps so the same dispatched
38234
+ // prompt acked twice in quick succession (the worker buffers the first
38235
+ // send during bootstrap/busy, then a redelivery — dispatch-confirm-timeout
38236
+ // requeue or a reconcile re-dispatch — fires a SECOND send_chat before the
38237
+ // outbound queue drains) collapses to ONE user bubble. Keyed on the trimmed
38238
+ // content; an entry older than USER_INPUT_ACK_DEDUP_WINDOW_MS is treated as
38239
+ // a fresh, intentional resend and is NOT suppressed.
38240
+ recentUserInputAcks = /* @__PURE__ */ new Map();
38030
38241
  lastNativeSourceCanonicalCheckAt = 0;
38031
38242
  lastNativeSourceCanonicalCacheKey = void 0;
38032
38243
  cachedSqliteDb = null;
@@ -38461,6 +38672,15 @@ var CliProviderInstance = class _CliProviderInstance {
38461
38672
  const content = typeof input === "string" ? input.trim() : buildCliStructuredInputPrompt(input).trim();
38462
38673
  if (!content) return;
38463
38674
  const receivedAt = Date.now();
38675
+ const ackContentKey = shortHash(`${this.instanceId}:${content}`, 24);
38676
+ const lastAckAt = this.recentUserInputAcks.get(ackContentKey);
38677
+ if (lastAckAt !== void 0 && receivedAt - lastAckAt <= USER_INPUT_ACK_DEDUP_WINDOW_MS) {
38678
+ this.recentUserInputAcks.set(ackContentKey, receivedAt);
38679
+ this.pruneRecentUserInputAcks(receivedAt);
38680
+ return;
38681
+ }
38682
+ this.recentUserInputAcks.set(ackContentKey, receivedAt);
38683
+ this.pruneRecentUserInputAcks(receivedAt);
38464
38684
  this.lastAcknowledgedUserInputAt = receivedAt;
38465
38685
  const dedupKey = `user_input_ack:${shortHash(`${this.instanceId}:${content}:${receivedAt}`, 24)}`;
38466
38686
  this.appendRuntimeMessage(buildChatMessage({
@@ -38478,6 +38698,13 @@ var CliProviderInstance = class _CliProviderInstance {
38478
38698
  }
38479
38699
  }), dedupKey);
38480
38700
  }
38701
+ /** Drop user-input ack entries older than the dedup window so the map can't grow unbounded. */
38702
+ pruneRecentUserInputAcks(now) {
38703
+ if (this.recentUserInputAcks.size <= 1) return;
38704
+ for (const [key, at] of this.recentUserInputAcks) {
38705
+ if (now - at > USER_INPUT_ACK_DEDUP_WINDOW_MS) this.recentUserInputAcks.delete(key);
38706
+ }
38707
+ }
38481
38708
  dispose() {
38482
38709
  this.adapter.shutdown();
38483
38710
  this.monitor.reset();
@@ -39167,8 +39394,9 @@ var CliProviderInstance = class _CliProviderInstance {
39167
39394
  previousStatus: this.lastStatus
39168
39395
  };
39169
39396
  const ownsExternalHistory = !!this.adapter?.chatMessagesOwnedExternally;
39170
- const flushDelay = ownsExternalHistory ? 0 : 3e3;
39171
- LOG.debug("CLI", `[${this.type}] set completedDebouncePending duration=${duration}s ownsExternalHistory=${ownsExternalHistory} flushDelay=${flushDelay}ms generatingStartedAt=${this.generatingStartedAt}`);
39397
+ const meshWorkerSession = this.isMeshWorkerSession();
39398
+ const flushDelay = ownsExternalHistory ? meshWorkerSession ? NATIVE_HISTORY_MESH_IDLE_SETTLE_MS : 0 : 3e3;
39399
+ LOG.debug("CLI", `[${this.type}] set completedDebouncePending duration=${duration}s ownsExternalHistory=${ownsExternalHistory} meshWorker=${meshWorkerSession} flushDelay=${flushDelay}ms generatingStartedAt=${this.generatingStartedAt}`);
39172
39400
  this.scheduleCompletedDebounceFlush(flushDelay);
39173
39401
  }
39174
39402
  } else if (newStatus === "idle" && this.lastStatus === "starting") {
@@ -42228,11 +42456,11 @@ var cliAgentHandlers = {
42228
42456
  }
42229
42457
  }
42230
42458
  }
42231
- const agentResult = await ctx.deps.cliManager.handleCliCommand("agent_command", args);
42232
42459
  const meshCtx = args?.meshContext;
42233
42460
  const dispatchNodeId = readStringValue(meshCtx?.nodeId);
42234
42461
  const dispatchMeshId = readStringValue(meshCtx?.meshId);
42235
- if (dispatchNodeId && dispatchMeshId && agentResult?.success !== false) {
42462
+ const isSendChat = args?.action === "send_chat";
42463
+ if (isSendChat && dispatchNodeId && dispatchMeshId) {
42236
42464
  try {
42237
42465
  const { getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
42238
42466
  const meshObj = getMesh2(dispatchMeshId) ?? ctx.getCachedInlineMesh(dispatchMeshId);
@@ -42240,17 +42468,22 @@ var cliAgentHandlers = {
42240
42468
  const bootstrapStatus = readStringValue(nodeObj?.worktreeBootstrap?.status);
42241
42469
  if (bootstrapStatus === "running") {
42242
42470
  return {
42243
- success: true,
42244
- ...agentResult,
42245
- dispatchAcknowledgementRisk: true,
42246
- dispatchAcknowledgementRiskReason: "bootstrap_still_running",
42247
- nextAction: "Wait for worktree_bootstrap_complete event before dispatching work to this node."
42471
+ success: false,
42472
+ recoverable: true,
42473
+ dispatched: false,
42474
+ code: "mesh_node_bootstrap_pending",
42475
+ reason: "bootstrap_still_running",
42476
+ nodeId: dispatchNodeId,
42477
+ meshId: dispatchMeshId,
42478
+ ...readStringValue(meshCtx?.taskId) ? { taskId: readStringValue(meshCtx?.taskId) } : {},
42479
+ 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.`,
42480
+ 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."
42248
42481
  };
42249
42482
  }
42250
42483
  } catch {
42251
42484
  }
42252
42485
  }
42253
- return agentResult;
42486
+ return ctx.deps.cliManager.handleCliCommand("agent_command", args);
42254
42487
  },
42255
42488
  // ─── Logs ───
42256
42489
  list_saved_sessions: async (ctx, args) => {
@@ -46502,7 +46735,7 @@ var meshCrudHandlers = {
46502
46735
  return "";
46503
46736
  }
46504
46737
  })();
46505
- const isCoordinatorBaseNode = !!selfDaemonId && (nodeDaemonId === selfDaemonId || nodeMachineId === selfDaemonId) || !!selfMachineId && (nodeDaemonId === selfMachineId || nodeMachineId === selfMachineId);
46738
+ const isCoordinatorBaseNode = !!selfDaemonId && (daemonIdsEquivalent(nodeDaemonId, selfDaemonId) || daemonIdsEquivalent(nodeMachineId, selfDaemonId)) || !!selfMachineId && (daemonIdsEquivalent(nodeDaemonId, selfMachineId) || daemonIdsEquivalent(nodeMachineId, selfMachineId));
46506
46739
  if (isCoordinatorBaseNode) {
46507
46740
  return {
46508
46741
  success: false,
@@ -47372,49 +47605,72 @@ var fastForwardHandlers = {
47372
47605
  };
47373
47606
  },
47374
47607
  fast_forward_mesh_node: async (ctx, args) => {
47375
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
47376
- const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
47377
- let workspace = typeof args?.workspace === "string" ? args.workspace.trim() : "";
47378
- let submoduleIgnorePaths = Array.isArray(args?.submoduleIgnorePaths) ? args.submoduleIgnorePaths.filter((value) => typeof value === "string") : void 0;
47379
- let nodeDaemonId;
47380
- let allowAutoPublishSubmoduleMainCommits = false;
47381
- if (meshId && nodeId) {
47382
- const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
47383
- const mesh = meshRecord?.mesh;
47384
- const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
47385
- if (!workspace) {
47386
- workspace = typeof node?.workspace === "string" ? node.workspace.trim() : "";
47608
+ const workspaceForError = typeof args?.workspace === "string" ? args.workspace.trim() : "";
47609
+ const meshIdForError = typeof args?.meshId === "string" ? args.meshId.trim() : "";
47610
+ const nodeIdForError = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
47611
+ try {
47612
+ const meshId = meshIdForError;
47613
+ const nodeId = nodeIdForError;
47614
+ let workspace = workspaceForError;
47615
+ let submoduleIgnorePaths = Array.isArray(args?.submoduleIgnorePaths) ? args.submoduleIgnorePaths.filter((value) => typeof value === "string") : void 0;
47616
+ let nodeDaemonId;
47617
+ let allowAutoPublishSubmoduleMainCommits = false;
47618
+ if (meshId && nodeId) {
47619
+ const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
47620
+ const mesh = meshRecord?.mesh;
47621
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
47622
+ if (!workspace) {
47623
+ workspace = typeof node?.workspace === "string" ? node.workspace.trim() : "";
47624
+ }
47625
+ if (!submoduleIgnorePaths && Array.isArray(node?.policy?.submoduleIgnorePaths)) {
47626
+ submoduleIgnorePaths = node.policy.submoduleIgnorePaths.filter((value) => typeof value === "string");
47627
+ }
47628
+ allowAutoPublishSubmoduleMainCommits = mesh?.policy?.allowAutoPublishSubmoduleMainCommits === true;
47629
+ nodeDaemonId = typeof node?.daemonId === "string" ? node.daemonId.trim() : void 0;
47387
47630
  }
47388
- if (!submoduleIgnorePaths && Array.isArray(node?.policy?.submoduleIgnorePaths)) {
47389
- submoduleIgnorePaths = node.policy.submoduleIgnorePaths.filter((value) => typeof value === "string");
47631
+ const selfDaemonId = ctx.deps.statusInstanceId;
47632
+ const isRemote = nodeDaemonId && selfDaemonId && !daemonIdsEquivalent(nodeDaemonId, selfDaemonId);
47633
+ if (isRemote && ctx.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
47634
+ const forwarded = await ctx.deps.dispatchMeshCommand(nodeDaemonId, "fast_forward_mesh_node", {
47635
+ ...typeof args === "object" && args !== null ? args : {},
47636
+ workspace,
47637
+ _meshDirectDispatch: true
47638
+ });
47639
+ return forwarded ?? { success: false, error: "no response from remote node" };
47390
47640
  }
47391
- allowAutoPublishSubmoduleMainCommits = mesh?.policy?.allowAutoPublishSubmoduleMainCommits === true;
47392
- nodeDaemonId = typeof node?.daemonId === "string" ? node.daemonId.trim() : void 0;
47393
- }
47394
- const selfDaemonId = ctx.deps.statusInstanceId;
47395
- const isRemote = nodeDaemonId && selfDaemonId && !daemonIdsEquivalent(nodeDaemonId, selfDaemonId);
47396
- if (isRemote && ctx.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
47397
- const forwarded = await ctx.deps.dispatchMeshCommand(nodeDaemonId, "fast_forward_mesh_node", {
47398
- ...typeof args === "object" && args !== null ? args : {},
47641
+ const result = await fastForwardMeshNode({
47642
+ meshId: meshId || void 0,
47643
+ nodeId: nodeId || void 0,
47399
47644
  workspace,
47400
- _meshDirectDispatch: true
47645
+ branch: typeof args?.branch === "string" ? args.branch : void 0,
47646
+ execute: args?.execute === true,
47647
+ dryRun: args?.dryRun === true,
47648
+ updateSubmodules: args?.updateSubmodules === true,
47649
+ submoduleIgnorePaths,
47650
+ mode: args?.mode === "push" ? "push" : "merge",
47651
+ pushSubmodules: args?.pushSubmodules === true,
47652
+ allowAutoPublishSubmoduleMainCommits
47401
47653
  });
47402
- return forwarded ?? { success: false, error: "no response from remote node" };
47654
+ return result;
47655
+ } catch (e) {
47656
+ const errorMessage = e?.message || String(e);
47657
+ return {
47658
+ success: false,
47659
+ code: "fast_forward_safety_gate_error",
47660
+ ...meshIdForError ? { meshId: meshIdForError } : {},
47661
+ ...nodeIdForError ? { nodeId: nodeIdForError } : {},
47662
+ workspace: workspaceForError,
47663
+ mode: args?.mode === "push" ? "push" : "merge",
47664
+ allowed: false,
47665
+ willRun: false,
47666
+ executed: false,
47667
+ // Surface the throw as a blocking reason instead of an opaque IPC crash
47668
+ // so the coordinator gets the same structured shape a clean node returns.
47669
+ blockingReasons: ["fast_forward_safety_gate_error"],
47670
+ operationError: errorMessage,
47671
+ error: errorMessage
47672
+ };
47403
47673
  }
47404
- const result = await fastForwardMeshNode({
47405
- meshId: meshId || void 0,
47406
- nodeId: nodeId || void 0,
47407
- workspace,
47408
- branch: typeof args?.branch === "string" ? args.branch : void 0,
47409
- execute: args?.execute === true,
47410
- dryRun: args?.dryRun === true,
47411
- updateSubmodules: args?.updateSubmodules === true,
47412
- submoduleIgnorePaths,
47413
- mode: args?.mode === "push" ? "push" : "merge",
47414
- pushSubmodules: args?.pushSubmodules === true,
47415
- allowAutoPublishSubmoduleMainCommits
47416
- });
47417
- return result;
47418
47674
  },
47419
47675
  refine_mesh_node: async (ctx, args) => {
47420
47676
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
@@ -47571,6 +47827,56 @@ var meshCoordinatorLaunchHandlers = {
47571
47827
  return "";
47572
47828
  }
47573
47829
  };
47830
+ const buildRecentActivityBestEffort = async (id) => {
47831
+ try {
47832
+ const { getLedgerSummary: getLedgerSummary2, readLedgerEntries: readLedgerEntries2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
47833
+ const { getMeshQueueStats: getMeshQueueStats2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
47834
+ const summary = getLedgerSummary2(id);
47835
+ const queue = getMeshQueueStats2(id);
47836
+ const failureEntries = readLedgerEntries2(id, { kind: ["task_failed"], tail: 5 });
47837
+ const recentFailures = failureEntries.map((e) => {
47838
+ const p = e.payload || {};
47839
+ const raw = typeof p.taskSummary === "string" ? p.taskSummary : typeof p.message === "string" ? p.message : typeof p.error === "string" ? p.error : "";
47840
+ const summaryText = raw.length > 160 ? `${raw.slice(0, 160)}\u2026` : raw;
47841
+ return {
47842
+ timestamp: e.timestamp,
47843
+ nodeId: e.nodeId,
47844
+ summary: summaryText
47845
+ };
47846
+ });
47847
+ return {
47848
+ recentFailures,
47849
+ recentFailureCount: summary.recentFailures,
47850
+ pendingTasks: queue.pending,
47851
+ assignedTasks: queue.assigned,
47852
+ stalledTasks: summary.taskStalled,
47853
+ lastActivityAt: summary.lastActivityAt
47854
+ };
47855
+ } catch {
47856
+ return void 0;
47857
+ }
47858
+ };
47859
+ const buildOperatingNotesBestEffort = async (id) => {
47860
+ try {
47861
+ const { readLedgerEntries: readLedgerEntries2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
47862
+ const noteEntries = readLedgerEntries2(id, { kind: ["coordinator_operating_note"], tail: 20 });
47863
+ const notes = noteEntries.map((e) => {
47864
+ const p = e.payload || {};
47865
+ const text = typeof p.text === "string" ? p.text.trim() : "";
47866
+ if (!text) return null;
47867
+ const category = p.category === "provider_quirk" || p.category === "pattern_to_avoid" || p.category === "recovery_lesson" ? p.category : void 0;
47868
+ return {
47869
+ text,
47870
+ category,
47871
+ createdAt: typeof p.createdAt === "string" ? p.createdAt : e.timestamp,
47872
+ sourceCoordinator: typeof p.sourceCoordinator === "string" ? p.sourceCoordinator : void 0
47873
+ };
47874
+ }).filter((n) => n !== null);
47875
+ return notes.length ? notes : void 0;
47876
+ } catch {
47877
+ return void 0;
47878
+ }
47879
+ };
47574
47880
  let mesh;
47575
47881
  if (args?.inlineMesh && typeof args.inlineMesh === "object") {
47576
47882
  mesh = args.inlineMesh;
@@ -47661,7 +47967,7 @@ var meshCoordinatorLaunchHandlers = {
47661
47967
  if (coordinatorSetup.kind === "cli_command") {
47662
47968
  let cliCmdSystemPrompt = "";
47663
47969
  try {
47664
- cliCmdSystemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType, userInstruction: extraSystemPrompt || void 0, missionSection: buildMissionSectionBestEffort(mesh.id) });
47970
+ cliCmdSystemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType, userInstruction: extraSystemPrompt || void 0, missionSection: buildMissionSectionBestEffort(mesh.id), recentActivity: await buildRecentActivityBestEffort(mesh.id), operatingNotes: await buildOperatingNotesBestEffort(mesh.id) });
47665
47971
  } catch (error) {
47666
47972
  const message = error?.message || String(error);
47667
47973
  LOG.error("MeshCoordinator", `Failed to build coordinator prompt: ${message}`);
@@ -47838,7 +48144,7 @@ ${ptyResult.output.slice(-2e3)}`);
47838
48144
  }
47839
48145
  let systemPrompt = "";
47840
48146
  try {
47841
- systemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType, userInstruction: extraSystemPrompt || void 0, missionSection: buildMissionSectionBestEffort(mesh.id) });
48147
+ systemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType, userInstruction: extraSystemPrompt || void 0, missionSection: buildMissionSectionBestEffort(mesh.id), recentActivity: await buildRecentActivityBestEffort(mesh.id), operatingNotes: await buildOperatingNotesBestEffort(mesh.id) });
47842
48148
  } catch (error) {
47843
48149
  const message = error?.message || String(error);
47844
48150
  LOG.error("MeshCoordinator", `Failed to build coordinator prompt: ${message}`);