@adhdev/daemon-standalone 0.9.82-rc.407 → 0.9.82-rc.409
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 +224 -95
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/vendor/mcp-server/index.js +118 -108
- package/vendor/mcp-server/index.js.map +1 -1
|
@@ -339,7 +339,7 @@ function compactChatPayload(payload, opts = {}) {
|
|
|
339
339
|
}
|
|
340
340
|
|
|
341
341
|
// src/tools/mesh-tools-internal.ts
|
|
342
|
-
var
|
|
342
|
+
var import_daemon_core3 = require("@adhdev/daemon-core");
|
|
343
343
|
|
|
344
344
|
// src/tools/mesh-tool-shared.ts
|
|
345
345
|
function readString(value) {
|
|
@@ -390,6 +390,7 @@ function elideLargeNestedValue(key, value) {
|
|
|
390
390
|
}
|
|
391
391
|
|
|
392
392
|
// src/tools/mesh-session-helpers.ts
|
|
393
|
+
var import_daemon_core = require("@adhdev/daemon-core");
|
|
393
394
|
function readSessionRecordId(session) {
|
|
394
395
|
return readString(session?.id) || readString(session?.sessionId) || readString(session?.session_id) || readString(session?.runtimeSessionId) || readString(session?.runtime_session_id) || readString(session?.instanceId) || readString(session?.instance_id);
|
|
395
396
|
}
|
|
@@ -417,8 +418,8 @@ function isUnmanagedSessionRecord(session) {
|
|
|
417
418
|
);
|
|
418
419
|
return !launchedByCoordinator;
|
|
419
420
|
}
|
|
420
|
-
function isWorkerTaskMode(taskMode) {
|
|
421
|
-
return taskMode
|
|
421
|
+
function isWorkerTaskMode(taskMode, readonly) {
|
|
422
|
+
return !(0, import_daemon_core.isTaskReadonly)({ readonly, taskMode });
|
|
422
423
|
}
|
|
423
424
|
function addSessionRecord(target, session) {
|
|
424
425
|
if (!session || typeof session !== "object" || isTerminalSessionRecord(session)) return;
|
|
@@ -483,7 +484,7 @@ function isIdleSessionRecord(session) {
|
|
|
483
484
|
}
|
|
484
485
|
|
|
485
486
|
// src/tools/mesh-node-identity.ts
|
|
486
|
-
var
|
|
487
|
+
var import_daemon_core2 = require("@adhdev/daemon-core");
|
|
487
488
|
function resolveCoordinatorNode(ctx) {
|
|
488
489
|
const preferredNodeId = typeof ctx.mesh.coordinator?.preferredNodeId === "string" ? ctx.mesh.coordinator.preferredNodeId.trim() : "";
|
|
489
490
|
if (preferredNodeId) {
|
|
@@ -567,8 +568,8 @@ function buildNodeMachineIdentity(ctx, node) {
|
|
|
567
568
|
function nodeHasLocalDaemonEvidence(ctx, node) {
|
|
568
569
|
const isLocal = (session) => {
|
|
569
570
|
if (!session || typeof session !== "object") return false;
|
|
570
|
-
if (ctx.localDaemonId && (0,
|
|
571
|
-
if (ctx.localDaemonId && (0,
|
|
571
|
+
if (ctx.localDaemonId && (0, import_daemon_core2.daemonIdsEquivalent)(session.runtime?.owner, ctx.localDaemonId)) return true;
|
|
572
|
+
if (ctx.localDaemonId && (0, import_daemon_core2.daemonIdsEquivalent)(session.daemonClient?.daemonId, ctx.localDaemonId)) return true;
|
|
572
573
|
return false;
|
|
573
574
|
};
|
|
574
575
|
const sessionArrays = [
|
|
@@ -607,7 +608,7 @@ function isDirectLocalNode(ctx, node) {
|
|
|
607
608
|
const machineId = readNodeMachineId(node);
|
|
608
609
|
const daemonId = readNodeDaemonId(node);
|
|
609
610
|
return Boolean(
|
|
610
|
-
ctx.localMachineId && (0,
|
|
611
|
+
ctx.localMachineId && (0, import_daemon_core2.daemonIdsEquivalent)(machineId, ctx.localMachineId) || ctx.localDaemonId && (0, import_daemon_core2.daemonIdsEquivalent)(daemonId, ctx.localDaemonId) || nodeHasLocalDaemonEvidence(ctx, node)
|
|
611
612
|
);
|
|
612
613
|
}
|
|
613
614
|
function isConfiguredCoordinatorNode(ctx, node) {
|
|
@@ -616,8 +617,8 @@ function isConfiguredCoordinatorNode(ctx, node) {
|
|
|
616
617
|
if (!nodeId) return false;
|
|
617
618
|
const nodeDaemonId = readNodeDaemonId(node);
|
|
618
619
|
const nodeMachineId = readNodeMachineId(node);
|
|
619
|
-
if (nodeDaemonId && ctx.localDaemonId && !(0,
|
|
620
|
-
if (nodeMachineId && ctx.localMachineId && !(0,
|
|
620
|
+
if (nodeDaemonId && ctx.localDaemonId && !(0, import_daemon_core2.daemonIdsEquivalent)(nodeDaemonId, ctx.localDaemonId)) return false;
|
|
621
|
+
if (nodeMachineId && ctx.localMachineId && !(0, import_daemon_core2.daemonIdsEquivalent)(nodeMachineId, ctx.localMachineId)) return false;
|
|
621
622
|
const preferredNodeId = readString(ctx.mesh.coordinator?.preferredNodeId) || readString(ctx.mesh.coordinator?.preferred_node_id);
|
|
622
623
|
if (preferredNodeId) return nodeId === preferredNodeId;
|
|
623
624
|
const first = ctx.mesh.nodes?.[0];
|
|
@@ -637,7 +638,7 @@ function getLocalControlPlaneMatchReason(ctx, node) {
|
|
|
637
638
|
function findClonedFromNode(ctx, node) {
|
|
638
639
|
const clonedFromNodeId = readString(node.clonedFromNodeId) || readString(node.cloned_from_node_id);
|
|
639
640
|
if (!clonedFromNodeId) return void 0;
|
|
640
|
-
return ctx.mesh.nodes.find((n) => (0,
|
|
641
|
+
return ctx.mesh.nodes.find((n) => (0, import_daemon_core2.meshNodeIdMatches)(n, clonedFromNodeId));
|
|
641
642
|
}
|
|
642
643
|
function resolvePreferredWorktreeNodeId(ctx) {
|
|
643
644
|
const worktreeNodes = (ctx.mesh.nodes || []).filter((n) => n.isLocalWorktree === true);
|
|
@@ -683,6 +684,8 @@ var MESH_ENQUEUE_TASK_TOOL = {
|
|
|
683
684
|
message: { type: "string", description: "The task instruction for the agent." },
|
|
684
685
|
task_mode: { type: "string", enum: ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"], description: "Optional task-mode contract. live_debug_readonly rejects obvious write/commit/push/deploy/destructive instructions before dispatch." },
|
|
685
686
|
taskMode: { type: "string", enum: ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"], description: "CamelCase alias for task_mode." },
|
|
687
|
+
readonly: { type: "boolean", description: "Optional read-only axis (orthogonal to task_mode). When true the task runs without the one-active-per-node write isolation (N read-only tasks may run in parallel on one node), is counted under the read-only safety cap, and rejects write/commit/push/deploy/destructive instructions like live_debug_readonly. Equivalent to task_mode=live_debug_readonly but composable with any task_mode." },
|
|
688
|
+
read_only: { type: "boolean", description: "Snake-case alias for readonly." },
|
|
686
689
|
requiredTags: { type: "array", items: { type: "string" }, description: "Optional capability tags that every eligible node must have, e.g. os=darwin, provider=codex-cli, gpu." },
|
|
687
690
|
required_tags: { type: "array", items: { type: "string" }, description: "Snake_case alias for requiredTags." },
|
|
688
691
|
target_node_id: { type: "string", description: "Optional HARD constraint: ONLY this node may claim the task. No other node (especially a different machine) will ever claim it \u2014 if the target node has no idle session the task stays pending until it does. Use to route a queued task to a specific (e.g. freshly cloned) worktree node instead of letting the first idle base node claim it. Takes priority over prefer_worktree. An unresolvable target id is rejected at enqueue (no silent unpin)." },
|
|
@@ -760,6 +763,8 @@ var MESH_SEND_TASK_TOOL = {
|
|
|
760
763
|
message: { type: "string", description: "Natural-language task to send to the agent." },
|
|
761
764
|
task_mode: { type: "string", enum: ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"], description: "Optional task-mode contract. live_debug_readonly rejects obvious write/commit/push/deploy/destructive instructions before local or remote direct dispatch." },
|
|
762
765
|
taskMode: { type: "string", enum: ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"], description: "CamelCase alias for task_mode." },
|
|
766
|
+
readonly: { type: "boolean", description: "Optional read-only axis (orthogonal to task_mode). When true the task runs without write isolation, is counted under the read-only cap, and rejects write/commit/push/deploy/destructive instructions like live_debug_readonly. Composable with any task_mode." },
|
|
767
|
+
read_only: { type: "boolean", description: "Snake-case alias for readonly." },
|
|
763
768
|
mission_id: { type: "string", description: "Mission this task belongs to (mesh_mission record id). When set, the directly dispatched task is attributed to the mission task aggregates exactly like mesh_enqueue_task, including terminal completion. Omit for an unattributed direct dispatch." },
|
|
764
769
|
missionId: { type: "string", description: "CamelCase alias for mission_id." }
|
|
765
770
|
},
|
|
@@ -1608,7 +1613,7 @@ function annotateRapidReadChatAdvisory(payload, options) {
|
|
|
1608
1613
|
}
|
|
1609
1614
|
|
|
1610
1615
|
// src/tools/mesh-tools-internal.ts
|
|
1611
|
-
var
|
|
1616
|
+
var import_daemon_core4 = require("@adhdev/daemon-core");
|
|
1612
1617
|
var import_node_crypto = require("crypto");
|
|
1613
1618
|
var SESSION_PROVIDER_METADATA_TTL_MS = 30 * 6e4;
|
|
1614
1619
|
var meshSessionProviderMetadata = /* @__PURE__ */ new Map();
|
|
@@ -1655,7 +1660,7 @@ function buildDirectTaskPayload(message, via, opts) {
|
|
|
1655
1660
|
};
|
|
1656
1661
|
}
|
|
1657
1662
|
function findNode(mesh, nodeId) {
|
|
1658
|
-
const node = mesh.nodes.find((n) => (0,
|
|
1663
|
+
const node = mesh.nodes.find((n) => (0, import_daemon_core3.meshNodeIdMatches)(n, nodeId));
|
|
1659
1664
|
if (!node) throw new Error(`Node '${nodeId}' is not a member of mesh '${mesh.name}'`);
|
|
1660
1665
|
return node;
|
|
1661
1666
|
}
|
|
@@ -1681,23 +1686,23 @@ async function syncCoordinatorDaemonMeshCache(ctx) {
|
|
|
1681
1686
|
}
|
|
1682
1687
|
}
|
|
1683
1688
|
async function findNodeWithRefresh(ctx, nodeId) {
|
|
1684
|
-
const hit = ctx.mesh.nodes.find((n) => (0,
|
|
1689
|
+
const hit = ctx.mesh.nodes.find((n) => (0, import_daemon_core3.meshNodeIdMatches)(n, nodeId));
|
|
1685
1690
|
if (hit && !hit.isLocalWorktree) return hit;
|
|
1686
1691
|
await refreshMeshFromDaemon(ctx);
|
|
1687
|
-
const refreshed = ctx.mesh.nodes.find((n) => (0,
|
|
1692
|
+
const refreshed = ctx.mesh.nodes.find((n) => (0, import_daemon_core3.meshNodeIdMatches)(n, nodeId));
|
|
1688
1693
|
if (!refreshed) throw new Error(`Node '${nodeId}' is not a member of mesh '${ctx.mesh.name}'`);
|
|
1689
1694
|
return refreshed;
|
|
1690
1695
|
}
|
|
1691
1696
|
async function findOptionalNodeWithRefresh(ctx, nodeId) {
|
|
1692
|
-
const hit = ctx.mesh.nodes.find((n) => (0,
|
|
1697
|
+
const hit = ctx.mesh.nodes.find((n) => (0, import_daemon_core3.meshNodeIdMatches)(n, nodeId));
|
|
1693
1698
|
if (hit && !hit.isLocalWorktree) return hit;
|
|
1694
1699
|
await refreshMeshFromDaemon(ctx);
|
|
1695
|
-
return ctx.mesh.nodes.find((n) => (0,
|
|
1700
|
+
return ctx.mesh.nodes.find((n) => (0, import_daemon_core3.meshNodeIdMatches)(n, nodeId)) ?? null;
|
|
1696
1701
|
}
|
|
1697
1702
|
function hasRecentDuplicateDispatch(ctx, args) {
|
|
1698
1703
|
const now = Date.now();
|
|
1699
1704
|
const normalizedMessage = args.message.trim();
|
|
1700
|
-
for (const task of (0,
|
|
1705
|
+
for (const task of (0, import_daemon_core3.getQueue)(ctx.mesh.id)) {
|
|
1701
1706
|
const timestamp = new Date(task.updatedAt || task.createdAt).getTime();
|
|
1702
1707
|
if (!Number.isFinite(timestamp) || now - timestamp > DUPLICATE_DISPATCH_WINDOW_MS) continue;
|
|
1703
1708
|
if (task.targetNodeId && task.targetNodeId !== args.node_id) continue;
|
|
@@ -1707,7 +1712,7 @@ function hasRecentDuplicateDispatch(ctx, args) {
|
|
|
1707
1712
|
return { duplicate: true, entry: task, source: "queue" };
|
|
1708
1713
|
}
|
|
1709
1714
|
}
|
|
1710
|
-
const entries = (0,
|
|
1715
|
+
const entries = (0, import_daemon_core3.readLedgerEntries)(ctx.mesh.id, { tail: 200 });
|
|
1711
1716
|
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
1712
1717
|
const entry = entries[i];
|
|
1713
1718
|
const timestamp = new Date(entry.timestamp).getTime();
|
|
@@ -1723,7 +1728,7 @@ function hasRecentDuplicateDispatch(ctx, args) {
|
|
|
1723
1728
|
return { duplicate: false };
|
|
1724
1729
|
}
|
|
1725
1730
|
function buildMissingNodeReadChatRecovery(ctx, args) {
|
|
1726
|
-
const entries = (0,
|
|
1731
|
+
const entries = (0, import_daemon_core3.readLedgerEntries)(ctx.mesh.id, { tail: 300 });
|
|
1727
1732
|
const relatedEntries = entries.filter((entry) => entry.nodeId === args.node_id || entry.sessionId === args.session_id);
|
|
1728
1733
|
const completedEntries = relatedEntries.filter((entry) => entry.kind === "task_completed");
|
|
1729
1734
|
const lastDispatch = [...relatedEntries].reverse().find((entry) => entry.kind === "task_dispatched");
|
|
@@ -1843,7 +1848,7 @@ function readFinalAssistantTranscriptEvidence(payload) {
|
|
|
1843
1848
|
}
|
|
1844
1849
|
function findNodeSession(nodes, nodeId, sessionId) {
|
|
1845
1850
|
if (!nodeId || !sessionId) return {};
|
|
1846
|
-
const node = nodes.find((candidate) => (0,
|
|
1851
|
+
const node = nodes.find((candidate) => (0, import_daemon_core3.meshNodeIdMatches)(candidate, nodeId));
|
|
1847
1852
|
if (!node) return {};
|
|
1848
1853
|
const sessions = Array.isArray(node.sessions) ? node.sessions : [];
|
|
1849
1854
|
const session = sessions.find((candidate) => readSessionRecordId(candidate) === sessionId);
|
|
@@ -1914,7 +1919,7 @@ async function reconcileDirectDispatchesFromTranscriptEvidence(ctx, liveNodes, d
|
|
|
1914
1919
|
if (payload?.success === false) continue;
|
|
1915
1920
|
const evidence = readFinalAssistantTranscriptEvidence(payload);
|
|
1916
1921
|
if (!evidence.finalSummary) continue;
|
|
1917
|
-
const result = (0,
|
|
1922
|
+
const result = (0, import_daemon_core3.reconcileDirectDispatchCompletionFromTranscript)({
|
|
1918
1923
|
meshId: ctx.mesh.id,
|
|
1919
1924
|
nodeId,
|
|
1920
1925
|
sessionId,
|
|
@@ -2092,7 +2097,7 @@ function extractLaunchPayload(value) {
|
|
|
2092
2097
|
function classifyMeshLaunchFailure(error) {
|
|
2093
2098
|
const message = error instanceof Error ? error.message : String(error || "launch failed");
|
|
2094
2099
|
const lower = message.toLowerCase();
|
|
2095
|
-
const p2pClassification = (0,
|
|
2100
|
+
const p2pClassification = (0, import_daemon_core3.classifyP2pRelayFailure)(error, { command: "launch_cli" });
|
|
2096
2101
|
if (p2pClassification.recoverable) {
|
|
2097
2102
|
return p2pClassification;
|
|
2098
2103
|
}
|
|
@@ -2167,7 +2172,7 @@ function buildRecoverableLaunchFailure(ctx, node, providerType, error) {
|
|
|
2167
2172
|
function recordRecoverableLaunchFailure(ctx, node, providerType, error) {
|
|
2168
2173
|
const failure = buildRecoverableLaunchFailure(ctx, node, providerType, error);
|
|
2169
2174
|
try {
|
|
2170
|
-
(0,
|
|
2175
|
+
(0, import_daemon_core3.appendLedgerEntry)(ctx.mesh.id, {
|
|
2171
2176
|
kind: "recovery_attempted",
|
|
2172
2177
|
nodeId: node.id,
|
|
2173
2178
|
providerType,
|
|
@@ -2181,7 +2186,7 @@ function recordRecoverableLaunchFailure(ctx, node, providerType, error) {
|
|
|
2181
2186
|
return failure;
|
|
2182
2187
|
}
|
|
2183
2188
|
function getLatestActiveLaunchFailure(meshId, nodeId) {
|
|
2184
|
-
const entries = (0,
|
|
2189
|
+
const entries = (0, import_daemon_core3.readLedgerEntries)(meshId, { tail: 200 });
|
|
2185
2190
|
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
2186
2191
|
const entry = entries[i];
|
|
2187
2192
|
if (entry.nodeId !== nodeId) continue;
|
|
@@ -2193,7 +2198,7 @@ function getLatestActiveLaunchFailure(meshId, nodeId) {
|
|
|
2193
2198
|
return null;
|
|
2194
2199
|
}
|
|
2195
2200
|
function buildCoordinatorP2pRelayFailure(error, context) {
|
|
2196
|
-
const payload = (0,
|
|
2201
|
+
const payload = (0, import_daemon_core3.buildP2pRelayFailurePayload)(error, {
|
|
2197
2202
|
command: context.command,
|
|
2198
2203
|
targetDaemonId: context.targetDaemonId
|
|
2199
2204
|
});
|
|
@@ -2374,7 +2379,7 @@ function rememberMeshSessionProviderMetadataFromEvent(event) {
|
|
|
2374
2379
|
});
|
|
2375
2380
|
}
|
|
2376
2381
|
function resolveMeshSessionProviderMetadataFromLedger(ctx, nodeId, runtimeSessionId) {
|
|
2377
|
-
const entries = (0,
|
|
2382
|
+
const entries = (0, import_daemon_core3.readLedgerEntries)(ctx.mesh.id, { tail: 50 });
|
|
2378
2383
|
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
2379
2384
|
const entry = entries[i];
|
|
2380
2385
|
const payload = entry.payload && typeof entry.payload === "object" && !Array.isArray(entry.payload) ? entry.payload : {};
|
|
@@ -2481,12 +2486,12 @@ function readProviderPriority(policy) {
|
|
|
2481
2486
|
}
|
|
2482
2487
|
function buildNodeCapabilityExposure(node) {
|
|
2483
2488
|
const providers = readProviderPriority(node.policy);
|
|
2484
|
-
const capabilityTags = (0,
|
|
2489
|
+
const capabilityTags = (0, import_daemon_core3.buildMeshNodeCapabilityTags)(node);
|
|
2485
2490
|
const exposure = { capabilityTags };
|
|
2486
2491
|
if (providers.length) {
|
|
2487
2492
|
const byProvider = {};
|
|
2488
2493
|
for (const provider of providers) {
|
|
2489
|
-
byProvider[provider] = (0,
|
|
2494
|
+
byProvider[provider] = (0, import_daemon_core3.buildMeshNodeCapabilityTags)(node, provider);
|
|
2490
2495
|
}
|
|
2491
2496
|
exposure.capabilityTagsByProvider = byProvider;
|
|
2492
2497
|
}
|
|
@@ -2827,12 +2832,12 @@ async function drainCoordinatorPendingEvents(ctx, opts) {
|
|
|
2827
2832
|
}
|
|
2828
2833
|
return surfacedEvents;
|
|
2829
2834
|
}
|
|
2830
|
-
const events = (0,
|
|
2835
|
+
const events = (0, import_daemon_core3.drainPendingMeshCoordinatorEvents)(ctx.mesh.id, ctx.localDaemonId).filter(matchesCurrentMesh);
|
|
2831
2836
|
events.forEach(rememberMeshSessionProviderMetadataFromEvent);
|
|
2832
2837
|
return events;
|
|
2833
2838
|
}
|
|
2834
2839
|
function isP2pTransportUnavailableError(error) {
|
|
2835
|
-
return (0,
|
|
2840
|
+
return (0, import_daemon_core3.isP2pRelayTransportFailure)(error);
|
|
2836
2841
|
}
|
|
2837
2842
|
function buildRemoveNodeArgs(ctx, nodeId, sessionCleanupMode, force) {
|
|
2838
2843
|
return {
|
|
@@ -2851,7 +2856,7 @@ function classifyReadChatTransportCause(error) {
|
|
|
2851
2856
|
return "saturated";
|
|
2852
2857
|
}
|
|
2853
2858
|
function resolveCachedMeshSessionPreviewFromLedger(ctx, nodeId, sessionId) {
|
|
2854
|
-
const entries = (0,
|
|
2859
|
+
const entries = (0, import_daemon_core3.readLedgerEntries)(ctx.mesh.id, { tail: 200 });
|
|
2855
2860
|
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
2856
2861
|
const entry = entries[i];
|
|
2857
2862
|
const payload = entry.payload && typeof entry.payload === "object" && !Array.isArray(entry.payload) ? entry.payload : {};
|
|
@@ -2860,7 +2865,7 @@ function resolveCachedMeshSessionPreviewFromLedger(ctx, nodeId, sessionId) {
|
|
|
2860
2865
|
const entrySessionId = readString(entry.sessionId) || readString(payload.targetSessionId) || readString(payload.sessionId) || readString(payload.instanceId);
|
|
2861
2866
|
if (entrySessionId !== sessionId) continue;
|
|
2862
2867
|
const metadataEvent = payload.metadataEvent && typeof payload.metadataEvent === "object" && !Array.isArray(payload.metadataEvent) ? payload.metadataEvent : payload;
|
|
2863
|
-
const preview = (0,
|
|
2868
|
+
const preview = (0, import_daemon_core3.resolveMeshSurfacedSessionPreview)(metadataEvent);
|
|
2864
2869
|
if (preview) {
|
|
2865
2870
|
return { ...preview, ledgerKind: entry.kind, timestamp: entry.timestamp };
|
|
2866
2871
|
}
|
|
@@ -2868,7 +2873,7 @@ function resolveCachedMeshSessionPreviewFromLedger(ctx, nodeId, sessionId) {
|
|
|
2868
2873
|
return void 0;
|
|
2869
2874
|
}
|
|
2870
2875
|
function buildMeshReadChatCacheFallback(ctx, args, node, error) {
|
|
2871
|
-
const classification = (0,
|
|
2876
|
+
const classification = (0, import_daemon_core3.classifyP2pRelayFailure)(error, { command: "read_chat", targetDaemonId: node.daemonId });
|
|
2872
2877
|
const cause = classifyReadChatTransportCause(error);
|
|
2873
2878
|
const errorMessage = error instanceof Error ? error.message : String(error ?? "");
|
|
2874
2879
|
const causeNote = cause === "not_connected" ? "the worker daemon is not currently connected over P2P (no live channel)" : "the worker daemon is connected but saturated \u2014 it acknowledged the request but did not return the transcript within the deadline";
|
|
@@ -2927,12 +2932,12 @@ function resolveRefineConfigNode(ctx, nodeId) {
|
|
|
2927
2932
|
|
|
2928
2933
|
// src/tools/mesh-tools-status.ts
|
|
2929
2934
|
async function meshStatus(ctx, args = {}) {
|
|
2930
|
-
const rateResult = (0,
|
|
2935
|
+
const rateResult = (0, import_daemon_core4.recordMeshToolCall)({ meshId: ctx.mesh.id, tool: "mesh_status" });
|
|
2931
2936
|
const compact = args.verbose === true ? false : args.compact ?? true;
|
|
2932
2937
|
await refreshMeshFromDaemon(ctx);
|
|
2933
2938
|
const { mesh, transport } = ctx;
|
|
2934
|
-
let ledgerSummary = (0,
|
|
2935
|
-
const schedulingRuntime = (0,
|
|
2939
|
+
let ledgerSummary = (0, import_daemon_core4.getLedgerSummary)(mesh.id);
|
|
2940
|
+
const schedulingRuntime = (0, import_daemon_core4.buildMeshSchedulingRuntime)(mesh, (0, import_daemon_core4.getQueue)(mesh.id));
|
|
2936
2941
|
const schedulingByNode = new Map(schedulingRuntime.nodes.map((n) => [n.nodeId, n]));
|
|
2937
2942
|
const results = await Promise.all(mesh.nodes.map(async (node) => {
|
|
2938
2943
|
const entry = {
|
|
@@ -2994,14 +2999,14 @@ async function meshStatus(ctx, args = {}) {
|
|
|
2994
2999
|
noFallbackReason: failure.noFallbackReason
|
|
2995
3000
|
});
|
|
2996
3001
|
}
|
|
2997
|
-
entry.dataFreshness = (0,
|
|
3002
|
+
entry.dataFreshness = (0, import_daemon_core4.buildMeshNodeProbeFreshness)({
|
|
2998
3003
|
git: entry.git,
|
|
2999
3004
|
liveTruthProbed,
|
|
3000
3005
|
isSelfNode: entry.machine?.sameMachine === true,
|
|
3001
3006
|
daemonId: readNodeDaemonId(node),
|
|
3002
3007
|
node
|
|
3003
3008
|
});
|
|
3004
|
-
const recoveryContext = (0,
|
|
3009
|
+
const recoveryContext = (0, import_daemon_core4.getSessionRecoveryContext)(mesh.id, { nodeId: node.id });
|
|
3005
3010
|
if (recoveryContext.consecutiveNodeFailures > 0) {
|
|
3006
3011
|
entry.recoveryHints = {
|
|
3007
3012
|
consecutiveFailures: recoveryContext.consecutiveNodeFailures,
|
|
@@ -3073,23 +3078,23 @@ async function meshStatus(ctx, args = {}) {
|
|
|
3073
3078
|
}
|
|
3074
3079
|
return entry;
|
|
3075
3080
|
}));
|
|
3076
|
-
let ledgerEntries = (0,
|
|
3077
|
-
let directDispatches = (0,
|
|
3081
|
+
let ledgerEntries = (0, import_daemon_core4.readLedgerEntries)(mesh.id, { tail: 200 });
|
|
3082
|
+
let directDispatches = (0, import_daemon_core4.getActiveDirectDispatches)(mesh.id);
|
|
3078
3083
|
const directReconciliation = await reconcileDirectDispatchesFromTranscriptEvidence(ctx, results, directDispatches, ledgerEntries);
|
|
3079
3084
|
if (directReconciliation.reconciled > 0) {
|
|
3080
|
-
ledgerEntries = (0,
|
|
3081
|
-
directDispatches = (0,
|
|
3082
|
-
ledgerSummary = (0,
|
|
3085
|
+
ledgerEntries = (0, import_daemon_core4.readLedgerEntries)(mesh.id, { tail: 200 });
|
|
3086
|
+
directDispatches = (0, import_daemon_core4.getActiveDirectDispatches)(mesh.id);
|
|
3087
|
+
ledgerSummary = (0, import_daemon_core4.getLedgerSummary)(mesh.id);
|
|
3083
3088
|
}
|
|
3084
|
-
const activeWorkEvidence = (0,
|
|
3089
|
+
const activeWorkEvidence = (0, import_daemon_core4.buildMeshActiveWork)({
|
|
3085
3090
|
meshId: mesh.id,
|
|
3086
|
-
queue: (0,
|
|
3091
|
+
queue: (0, import_daemon_core4.getQueue)(mesh.id),
|
|
3087
3092
|
ledgerEntries,
|
|
3088
3093
|
directDispatches,
|
|
3089
3094
|
nodes: results
|
|
3090
3095
|
});
|
|
3091
3096
|
const pollingGuidance = buildActiveWorkPollingGuidance(activeWorkEvidence.summary);
|
|
3092
|
-
const staleDirectWorkSummary = (0,
|
|
3097
|
+
const staleDirectWorkSummary = (0, import_daemon_core4.buildCompactStaleDirectWorkSummary)(activeWorkEvidence.staleDirectWork, {
|
|
3093
3098
|
note: activeWorkEvidence.staleDirectWorkNote,
|
|
3094
3099
|
detailHint: "Full stale direct entries are omitted from mesh_status by default. Call mesh_status with includeStaleDirectWorkDetails=true or inspect mesh_task_history for ledger detail."
|
|
3095
3100
|
});
|
|
@@ -3289,7 +3294,7 @@ async function meshStatus(ctx, args = {}) {
|
|
|
3289
3294
|
}
|
|
3290
3295
|
try {
|
|
3291
3296
|
if (compact) {
|
|
3292
|
-
const { live, historyFold } = (0,
|
|
3297
|
+
const { live, historyFold } = (0, import_daemon_core4.getMeshStatusMissionsCompact)(mesh.id);
|
|
3293
3298
|
const ranked = [...live].sort((a, b) => String(b.tasks?.lastActivityAt ?? "").localeCompare(String(a.tasks?.lastActivityAt ?? "")));
|
|
3294
3299
|
const kept = [];
|
|
3295
3300
|
const overflow = [];
|
|
@@ -3316,11 +3321,11 @@ async function meshStatus(ctx, args = {}) {
|
|
|
3316
3321
|
}
|
|
3317
3322
|
if (historyFold) response.missionsHistory = historyFold;
|
|
3318
3323
|
} else {
|
|
3319
|
-
const missions = (0,
|
|
3324
|
+
const missions = (0, import_daemon_core4.getMeshStatusMissionSummaries)(mesh.id, { verbose: true });
|
|
3320
3325
|
if (missions.length > 0) {
|
|
3321
3326
|
response.missions = missions.map((mission) => {
|
|
3322
3327
|
try {
|
|
3323
|
-
return { ...mission, stats: (0,
|
|
3328
|
+
return { ...mission, stats: (0, import_daemon_core4.computeMeshMissionStats)(mesh.id, mission.id) };
|
|
3324
3329
|
} catch {
|
|
3325
3330
|
return mission;
|
|
3326
3331
|
}
|
|
@@ -3331,14 +3336,14 @@ async function meshStatus(ctx, args = {}) {
|
|
|
3331
3336
|
}
|
|
3332
3337
|
try {
|
|
3333
3338
|
const pendingEvents = await drainCoordinatorPendingEvents(ctx);
|
|
3334
|
-
const asyncRefineJobs = (0,
|
|
3339
|
+
const asyncRefineJobs = (0, import_daemon_core4.buildMeshAsyncRefineJobs)({
|
|
3335
3340
|
meshId: mesh.id,
|
|
3336
3341
|
ledgerEntries,
|
|
3337
3342
|
pendingEvents
|
|
3338
3343
|
});
|
|
3339
3344
|
if (asyncRefineJobs.length > 0) {
|
|
3340
3345
|
if (compact) {
|
|
3341
|
-
const summary = (0,
|
|
3346
|
+
const summary = (0, import_daemon_core4.summarizeMeshAsyncRefineJobs)(asyncRefineJobs);
|
|
3342
3347
|
if (summary.activeJobs.length > 0) response.asyncRefineJobs = summary.activeJobs;
|
|
3343
3348
|
response.asyncRefineJobsSummary = {
|
|
3344
3349
|
total: summary.total,
|
|
@@ -3382,14 +3387,15 @@ async function meshListNodes(ctx) {
|
|
|
3382
3387
|
// src/tools/mesh-tools-queue.ts
|
|
3383
3388
|
async function meshEnqueueTask(ctx, args) {
|
|
3384
3389
|
const taskMode = readString(args.task_mode) || readString(args.taskMode);
|
|
3385
|
-
const
|
|
3390
|
+
const readonly = args.readonly === true || args.read_only === true;
|
|
3391
|
+
const requiredTags = (0, import_daemon_core4.normalizeMeshCapabilityTags)(Array.isArray(args.requiredTags) ? args.requiredTags : args.required_tags);
|
|
3386
3392
|
const dependsOn = Array.isArray(args.dependsOn) ? args.dependsOn : Array.isArray(args.depends_on) ? args.depends_on : void 0;
|
|
3387
3393
|
const missionId = readString(args.missionId) || readString(args.mission_id) || void 0;
|
|
3388
3394
|
const explicitTargetRaw = readString(args.targetNodeId) || readString(args.target_node_id) || readString(args.targetNode) || readString(args.target_node) || void 0;
|
|
3389
3395
|
const preferWorktree = args.preferWorktree === true || args.prefer_worktree === true;
|
|
3390
3396
|
let targetNodeId;
|
|
3391
3397
|
if (explicitTargetRaw) {
|
|
3392
|
-
const matched = ctx.mesh.nodes.find((n) => (0,
|
|
3398
|
+
const matched = ctx.mesh.nodes.find((n) => (0, import_daemon_core4.meshNodeIdMatches)(n, explicitTargetRaw));
|
|
3393
3399
|
if (!matched) {
|
|
3394
3400
|
return JSON.stringify({
|
|
3395
3401
|
success: false,
|
|
@@ -3404,7 +3410,7 @@ async function meshEnqueueTask(ctx, args) {
|
|
|
3404
3410
|
targetNodeId = resolvePreferredWorktreeNodeId(ctx) || void 0;
|
|
3405
3411
|
}
|
|
3406
3412
|
try {
|
|
3407
|
-
const task = (0,
|
|
3413
|
+
const task = (0, import_daemon_core4.enqueueTask)(ctx.mesh.id, args.message, { taskMode, ...readonly ? { readonly: true } : {}, requiredTags, dependsOn, missionId, targetNodeId, ...ctx.coordinatorSessionId ? { sourceCoordinatorSessionId: ctx.coordinatorSessionId } : {} });
|
|
3408
3414
|
if (!(ctx.transport instanceof IpcTransport)) {
|
|
3409
3415
|
const queueTrigger = await triggerMeshQueueAndReport(ctx);
|
|
3410
3416
|
return JSON.stringify({
|
|
@@ -3428,7 +3434,7 @@ async function meshEnqueueTask(ctx, args) {
|
|
|
3428
3434
|
const isLocalNode = isLocalControlPlaneNode(ctx, node);
|
|
3429
3435
|
if (isLocalNode || !node.daemonId) continue;
|
|
3430
3436
|
if (targetNodeId && node.id !== targetNodeId) continue;
|
|
3431
|
-
if (!(0,
|
|
3437
|
+
if (!(0, import_daemon_core4.nodeSatisfiesRequiredTags)(requiredTags, (0, import_daemon_core4.buildMeshNodeCapabilityTags)(node))) continue;
|
|
3432
3438
|
dispatchPromises.push(
|
|
3433
3439
|
ipcDispatchToRemoteAgent(ctx, node, {
|
|
3434
3440
|
message: args.message,
|
|
@@ -3443,7 +3449,7 @@ async function meshEnqueueTask(ctx, args) {
|
|
|
3443
3449
|
try {
|
|
3444
3450
|
const providerType = result.providerType;
|
|
3445
3451
|
const descriptor = summarizeTaskMessage(args.message);
|
|
3446
|
-
(0,
|
|
3452
|
+
(0, import_daemon_core4.appendLedgerEntry)(ctx.mesh.id, {
|
|
3447
3453
|
kind: "task_dispatched",
|
|
3448
3454
|
nodeId: node.id,
|
|
3449
3455
|
sessionId: result.sessionId,
|
|
@@ -3465,7 +3471,7 @@ async function meshEnqueueTask(ctx, args) {
|
|
|
3465
3471
|
}
|
|
3466
3472
|
}).catch((err) => {
|
|
3467
3473
|
try {
|
|
3468
|
-
(0,
|
|
3474
|
+
(0, import_daemon_core4.appendLedgerEntry)(ctx.mesh.id, {
|
|
3469
3475
|
kind: "p2p_dispatch_failed",
|
|
3470
3476
|
nodeId: node.id,
|
|
3471
3477
|
payload: {
|
|
@@ -3508,17 +3514,17 @@ async function meshEnqueueTask(ctx, args) {
|
|
|
3508
3514
|
}
|
|
3509
3515
|
}
|
|
3510
3516
|
async function meshViewQueue(ctx, args) {
|
|
3511
|
-
const rateResult = (0,
|
|
3517
|
+
const rateResult = (0, import_daemon_core4.recordMeshToolCall)({ meshId: ctx.mesh.id, tool: "mesh_view_queue" });
|
|
3512
3518
|
const compact = args.verbose === true ? false : args.compact ?? true;
|
|
3513
3519
|
try {
|
|
3514
3520
|
await refreshMeshFromDaemon(ctx);
|
|
3515
3521
|
const statusFilter = sanitizeQueueStatusFilter(args.status);
|
|
3516
3522
|
const view = normalizeQueueViewMode(args.view);
|
|
3517
|
-
const rawQueue = (0,
|
|
3523
|
+
const rawQueue = (0, import_daemon_core4.getQueue)(ctx.mesh.id);
|
|
3518
3524
|
const statusById = new Map(rawQueue.map((task) => [task.id, task.status]));
|
|
3519
3525
|
const withDependencies = rawQueue.map((task) => {
|
|
3520
3526
|
if (!Array.isArray(task.dependsOn) || task.dependsOn.length === 0) return task;
|
|
3521
|
-
const depState = (0,
|
|
3527
|
+
const depState = (0, import_daemon_core4.describeTaskDependencyState)(task, statusById);
|
|
3522
3528
|
return { ...task, ...depState };
|
|
3523
3529
|
});
|
|
3524
3530
|
const fullQueue = prioritizeActiveQueueRows(annotateQueueStaleness(withDependencies, ctx.mesh));
|
|
@@ -3527,16 +3533,16 @@ async function meshViewQueue(ctx, args) {
|
|
|
3527
3533
|
const visibleSummary = buildQueueStatusSummary(queue);
|
|
3528
3534
|
const maintenance = buildQueueMaintenanceReport(fullQueue);
|
|
3529
3535
|
const liveNodes = await collectMeshViewQueueNodesWithLiveSessions(ctx);
|
|
3530
|
-
let ledgerEntries = (0,
|
|
3531
|
-
let directDispatches = (0,
|
|
3536
|
+
let ledgerEntries = (0, import_daemon_core4.readLedgerEntries)(ctx.mesh.id, { tail: 200 });
|
|
3537
|
+
let directDispatches = (0, import_daemon_core4.getActiveDirectDispatches)(ctx.mesh.id);
|
|
3532
3538
|
const directReconciliation = await reconcileDirectDispatchesFromTranscriptEvidence(ctx, liveNodes, directDispatches, ledgerEntries);
|
|
3533
3539
|
if (directReconciliation.reconciled > 0) {
|
|
3534
|
-
ledgerEntries = (0,
|
|
3535
|
-
directDispatches = (0,
|
|
3540
|
+
ledgerEntries = (0, import_daemon_core4.readLedgerEntries)(ctx.mesh.id, { tail: 200 });
|
|
3541
|
+
directDispatches = (0, import_daemon_core4.getActiveDirectDispatches)(ctx.mesh.id);
|
|
3536
3542
|
}
|
|
3537
|
-
(0,
|
|
3538
|
-
directDispatches = (0,
|
|
3539
|
-
const activeWorkEvidence = (0,
|
|
3543
|
+
(0, import_daemon_core4.markStaleDirectDispatches)(ctx.mesh.id);
|
|
3544
|
+
directDispatches = (0, import_daemon_core4.getActiveDirectDispatches)(ctx.mesh.id);
|
|
3545
|
+
const activeWorkEvidence = (0, import_daemon_core4.buildMeshActiveWork)({
|
|
3540
3546
|
meshId: ctx.mesh.id,
|
|
3541
3547
|
queue: fullQueue,
|
|
3542
3548
|
ledgerEntries,
|
|
@@ -3561,7 +3567,7 @@ async function meshViewQueue(ctx, args) {
|
|
|
3561
3567
|
const wantActiveQueueArray = view === "active" || statusFilter?.some((status) => ACTIVE_QUEUE_STATUSES.has(status));
|
|
3562
3568
|
const wantHistoricalQueueArray = !compact && (view === "historical" || requestedHistoricalRows);
|
|
3563
3569
|
const activeWorkResult = compact ? compactActiveWorkRecords(activeWorkEvidence.activeWork) : { records: activeWorkEvidence.activeWork, omitted: 0 };
|
|
3564
|
-
const staleDirectWorkSummary = (0,
|
|
3570
|
+
const staleDirectWorkSummary = (0, import_daemon_core4.buildCompactStaleDirectWorkSummary)(activeWorkEvidence.staleDirectWork, {
|
|
3565
3571
|
note: activeWorkEvidence.staleDirectWorkNote,
|
|
3566
3572
|
detailHint: "Full stale direct entries are omitted from mesh_view_queue in compact mode. Call mesh_view_queue with verbose=true, or inspect mesh_task_history for ledger detail."
|
|
3567
3573
|
});
|
|
@@ -3636,12 +3642,12 @@ async function meshQueueCancel(ctx, args) {
|
|
|
3636
3642
|
try {
|
|
3637
3643
|
const taskId = (args.task_id || args.taskId || "").trim();
|
|
3638
3644
|
if (!taskId) return JSON.stringify({ success: false, error: "task_id required" });
|
|
3639
|
-
const preCancel = (0,
|
|
3645
|
+
const preCancel = (0, import_daemon_core4.getQueue)(ctx.mesh.id).find((t) => t?.id === taskId);
|
|
3640
3646
|
const wasAssigned = preCancel?.status === "assigned";
|
|
3641
3647
|
const assignedSessionId = readString(preCancel?.assignedSessionId) || void 0;
|
|
3642
3648
|
const assignedNodeId = readString(preCancel?.assignedNodeId) || void 0;
|
|
3643
3649
|
const assignedProviderType = readString(preCancel?.assignedProviderType) || void 0;
|
|
3644
|
-
const task = (0,
|
|
3650
|
+
const task = (0, import_daemon_core4.cancelTask)(ctx.mesh.id, taskId, { reason: args.reason });
|
|
3645
3651
|
if (!task) return JSON.stringify({ success: false, error: `Queue task '${taskId}' not found` });
|
|
3646
3652
|
ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
|
|
3647
3653
|
});
|
|
@@ -3680,7 +3686,7 @@ async function meshQueueRequeue(ctx, args) {
|
|
|
3680
3686
|
const targetNodeId = (args.target_node_id || args.targetNodeId || "").trim() || void 0;
|
|
3681
3687
|
const targetSessionId = (args.target_session_id || args.targetSessionId || "").trim() || void 0;
|
|
3682
3688
|
const keepTargetSession = args.keep_target_session === true || args.keepTargetSession === true;
|
|
3683
|
-
const task = (0,
|
|
3689
|
+
const task = (0, import_daemon_core4.requeueTask)(ctx.mesh.id, taskId, {
|
|
3684
3690
|
reason: args.reason,
|
|
3685
3691
|
targetNodeId,
|
|
3686
3692
|
targetSessionId,
|
|
@@ -3719,17 +3725,17 @@ async function meshTaskHistory(ctx, args) {
|
|
|
3719
3725
|
const compactCap = requestedTail > 50 ? 20 : 30;
|
|
3720
3726
|
const tail = compact ? Math.min(requestedTail, compactCap) : Math.min(requestedTail, 200);
|
|
3721
3727
|
const kind = typeof args.kind === "string" && args.kind.trim() ? [args.kind.trim()] : void 0;
|
|
3722
|
-
const rawEntries = (0,
|
|
3728
|
+
const rawEntries = (0, import_daemon_core4.readLedgerEntries)(mesh.id, { tail, kind });
|
|
3723
3729
|
const entries = compact ? rawEntries.map((e) => ({
|
|
3724
3730
|
...e,
|
|
3725
3731
|
payload: e.payload ? slimLedgerPayload(e.payload) : e.payload
|
|
3726
3732
|
})) : rawEntries;
|
|
3727
|
-
const summary = (0,
|
|
3733
|
+
const summary = (0, import_daemon_core4.getLedgerSummary)(mesh.id);
|
|
3728
3734
|
let taskStats;
|
|
3729
3735
|
try {
|
|
3730
3736
|
const taskIds = [...new Set(rawEntries.map((e) => typeof e.payload?.taskId === "string" ? e.payload.taskId : "").filter(Boolean))];
|
|
3731
3737
|
if (taskIds.length > 0) {
|
|
3732
|
-
const stats = (0,
|
|
3738
|
+
const stats = (0, import_daemon_core4.computeMeshTaskStats)(mesh.id, { taskIds });
|
|
3733
3739
|
if (stats.length > 0) taskStats = stats;
|
|
3734
3740
|
}
|
|
3735
3741
|
} catch {
|
|
@@ -3752,7 +3758,7 @@ async function meshRecordNote(ctx, args) {
|
|
|
3752
3758
|
const category = args.category === "provider_quirk" || args.category === "pattern_to_avoid" || args.category === "recovery_lesson" ? args.category : void 0;
|
|
3753
3759
|
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3754
3760
|
const sourceCoordinator = ctx.coordinatorSessionId || ctx.localDaemonId || ctx.coordinatorHostname || void 0;
|
|
3755
|
-
const entry = (0,
|
|
3761
|
+
const entry = (0, import_daemon_core4.appendLedgerEntry)(mesh.id, {
|
|
3756
3762
|
kind: "coordinator_operating_note",
|
|
3757
3763
|
...sourceCoordinator ? { sessionId: sourceCoordinator } : {},
|
|
3758
3764
|
payload: {
|
|
@@ -3785,8 +3791,8 @@ async function meshReconcileLedger(ctx, args) {
|
|
|
3785
3791
|
for (const node of nodes) {
|
|
3786
3792
|
try {
|
|
3787
3793
|
if (isLocalControlPlaneNode(ctx, node) || !node.daemonId) {
|
|
3788
|
-
const slice2 = (0,
|
|
3789
|
-
replicas.push((0,
|
|
3794
|
+
const slice2 = (0, import_daemon_core4.readLedgerSliceFromStore)(ctx.mesh.id, queryArgs);
|
|
3795
|
+
replicas.push((0, import_daemon_core4.buildMeshLedgerReplicaEvidence)({
|
|
3790
3796
|
nodeId: node.id,
|
|
3791
3797
|
daemonId: node.daemonId,
|
|
3792
3798
|
transport: "local",
|
|
@@ -3804,8 +3810,8 @@ async function meshReconcileLedger(ctx, args) {
|
|
|
3804
3810
|
if (slice?.protocol !== "adhdev.mesh.ledger.slice.v1" || !Array.isArray(slice.entries)) {
|
|
3805
3811
|
throw new Error("remote daemon returned an invalid ledger slice payload");
|
|
3806
3812
|
}
|
|
3807
|
-
const importResult = shouldImport ? (0,
|
|
3808
|
-
replicas.push((0,
|
|
3813
|
+
const importResult = shouldImport ? (0, import_daemon_core4.appendRemoteLedgerEntries)(ctx.mesh.id, slice.entries) : { accepted: 0, skippedDuplicate: 0, rejectedInvalid: 0, entries: [] };
|
|
3814
|
+
replicas.push((0, import_daemon_core4.buildMeshLedgerReplicaEvidence)({
|
|
3809
3815
|
nodeId: node.id,
|
|
3810
3816
|
daemonId: node.daemonId,
|
|
3811
3817
|
transport: "p2p_datachannel",
|
|
@@ -3813,7 +3819,7 @@ async function meshReconcileLedger(ctx, args) {
|
|
|
3813
3819
|
importResult
|
|
3814
3820
|
}));
|
|
3815
3821
|
if (shouldImport && importResult.accepted > 0) {
|
|
3816
|
-
(0,
|
|
3822
|
+
(0, import_daemon_core4.appendLedgerEntry)(ctx.mesh.id, {
|
|
3817
3823
|
kind: "ledger_replicated",
|
|
3818
3824
|
nodeId: node.id,
|
|
3819
3825
|
payload: {
|
|
@@ -3827,7 +3833,7 @@ async function meshReconcileLedger(ctx, args) {
|
|
|
3827
3833
|
});
|
|
3828
3834
|
}
|
|
3829
3835
|
} catch (e) {
|
|
3830
|
-
replicas.push((0,
|
|
3836
|
+
replicas.push((0, import_daemon_core4.buildMeshLedgerReplicaEvidence)({
|
|
3831
3837
|
nodeId: node.id,
|
|
3832
3838
|
daemonId: node.daemonId,
|
|
3833
3839
|
transport: node.daemonId ? "p2p_datachannel" : "local",
|
|
@@ -3836,8 +3842,8 @@ async function meshReconcileLedger(ctx, args) {
|
|
|
3836
3842
|
}));
|
|
3837
3843
|
}
|
|
3838
3844
|
}
|
|
3839
|
-
const evidence = (0,
|
|
3840
|
-
(0,
|
|
3845
|
+
const evidence = (0, import_daemon_core4.buildMeshLedgerReconciliationEvidence)(ctx.mesh.id, replicas);
|
|
3846
|
+
(0, import_daemon_core4.appendLedgerEntry)(ctx.mesh.id, {
|
|
3841
3847
|
kind: "ledger_reconciled",
|
|
3842
3848
|
payload: {
|
|
3843
3849
|
protocol: evidence.protocol,
|
|
@@ -3850,7 +3856,7 @@ async function meshReconcileLedger(ctx, args) {
|
|
|
3850
3856
|
}
|
|
3851
3857
|
async function meshMissionUpsert(ctx, args) {
|
|
3852
3858
|
try {
|
|
3853
|
-
const mission = (0,
|
|
3859
|
+
const mission = (0, import_daemon_core4.upsertMeshMission)(ctx.mesh.id, {
|
|
3854
3860
|
id: readString(args.mission_id) || readString(args.missionId) || void 0,
|
|
3855
3861
|
title: args.title,
|
|
3856
3862
|
goal: typeof args.goal === "string" ? args.goal : void 0,
|
|
@@ -3870,21 +3876,21 @@ async function meshMissionUpsert(ctx, args) {
|
|
|
3870
3876
|
async function meshMissionList(ctx, args = {}) {
|
|
3871
3877
|
try {
|
|
3872
3878
|
const rawStatuses = Array.isArray(args.status) ? args.status : typeof args.status === "string" && args.status.trim() ? [args.status] : [];
|
|
3873
|
-
const invalid = rawStatuses.filter((s) => !
|
|
3879
|
+
const invalid = rawStatuses.filter((s) => !import_daemon_core4.MESH_MISSION_STATUSES.includes(s));
|
|
3874
3880
|
if (invalid.length > 0) {
|
|
3875
3881
|
return JSON.stringify({
|
|
3876
3882
|
success: false,
|
|
3877
3883
|
code: "invalid_mission_status",
|
|
3878
|
-
error: `invalid status filter: ${invalid.join(", ")} (valid: ${
|
|
3884
|
+
error: `invalid status filter: ${invalid.join(", ")} (valid: ${import_daemon_core4.MESH_MISSION_STATUSES.join(", ")})`
|
|
3879
3885
|
});
|
|
3880
3886
|
}
|
|
3881
3887
|
const statuses = rawStatuses.length > 0 ? rawStatuses : void 0;
|
|
3882
|
-
const missions = (0,
|
|
3888
|
+
const missions = (0, import_daemon_core4.listMeshMissionSummaries)(ctx.mesh.id, {
|
|
3883
3889
|
statuses,
|
|
3884
3890
|
verbose: args.verbose === true
|
|
3885
3891
|
}).map((mission) => {
|
|
3886
3892
|
try {
|
|
3887
|
-
return { ...mission, stats: (0,
|
|
3893
|
+
return { ...mission, stats: (0, import_daemon_core4.computeMeshMissionStats)(ctx.mesh.id, mission.id) };
|
|
3888
3894
|
} catch {
|
|
3889
3895
|
return mission;
|
|
3890
3896
|
}
|
|
@@ -3923,11 +3929,11 @@ async function meshPruneStaleDirect(ctx, args = {}) {
|
|
|
3923
3929
|
const execute = args.execute === true && args.dry_run !== true;
|
|
3924
3930
|
const includeTerminal = args.include_terminal === true;
|
|
3925
3931
|
const liveNodes = await collectMeshViewQueueNodesWithLiveSessions(ctx);
|
|
3926
|
-
const ledgerEntries = (0,
|
|
3927
|
-
const directDispatches = (0,
|
|
3928
|
-
const result = (0,
|
|
3932
|
+
const ledgerEntries = (0, import_daemon_core4.readLedgerEntries)(ctx.mesh.id, { tail: 500 });
|
|
3933
|
+
const directDispatches = (0, import_daemon_core4.getActiveDirectDispatches)(ctx.mesh.id);
|
|
3934
|
+
const result = (0, import_daemon_core4.pruneStaleDirectDispatches)({
|
|
3929
3935
|
meshId: ctx.mesh.id,
|
|
3930
|
-
queue: (0,
|
|
3936
|
+
queue: (0, import_daemon_core4.getQueue)(ctx.mesh.id),
|
|
3931
3937
|
ledgerEntries,
|
|
3932
3938
|
directDispatches,
|
|
3933
3939
|
nodes: liveNodes,
|
|
@@ -3968,8 +3974,9 @@ async function meshPruneStaleDirect(ctx, args = {}) {
|
|
|
3968
3974
|
}
|
|
3969
3975
|
async function meshSendTask(ctx, args) {
|
|
3970
3976
|
const requestedTaskMode = readString(args.task_mode) || readString(args.taskMode);
|
|
3977
|
+
const readonly = args.readonly === true || args.read_only === true;
|
|
3971
3978
|
const missionId = readString(args.missionId) || readString(args.mission_id) || void 0;
|
|
3972
|
-
const modeValidation = (0,
|
|
3979
|
+
const modeValidation = (0, import_daemon_core4.validateMeshTaskModeRequest)(requestedTaskMode, args.message, readonly);
|
|
3973
3980
|
if (!modeValidation.valid) {
|
|
3974
3981
|
return JSON.stringify({
|
|
3975
3982
|
success: false,
|
|
@@ -3999,7 +4006,7 @@ async function meshSendTask(ctx, args) {
|
|
|
3999
4006
|
});
|
|
4000
4007
|
}
|
|
4001
4008
|
let explicitTargetSession;
|
|
4002
|
-
if (args.session_id && isWorkerTaskMode(taskMode)) {
|
|
4009
|
+
if (args.session_id && isWorkerTaskMode(taskMode, readonly)) {
|
|
4003
4010
|
try {
|
|
4004
4011
|
const statusResult = await commandForNode(ctx, node, "get_status_metadata", {});
|
|
4005
4012
|
const sessions = extractStatusMetadataSessions(statusResult);
|
|
@@ -4081,7 +4088,7 @@ async function meshSendTask(ctx, args) {
|
|
|
4081
4088
|
const dispatchedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4082
4089
|
try {
|
|
4083
4090
|
const providerType = result2.providerType || cached?.providerType;
|
|
4084
|
-
(0,
|
|
4091
|
+
(0, import_daemon_core4.appendLedgerEntry)(ctx.mesh.id, {
|
|
4085
4092
|
kind: "task_dispatched",
|
|
4086
4093
|
nodeId: args.node_id,
|
|
4087
4094
|
sessionId: dispatchedSessionId,
|
|
@@ -4094,7 +4101,7 @@ async function meshSendTask(ctx, args) {
|
|
|
4094
4101
|
...ctx.coordinatorSessionId ? { coordinatorSessionId: ctx.coordinatorSessionId } : {}
|
|
4095
4102
|
})
|
|
4096
4103
|
});
|
|
4097
|
-
(0,
|
|
4104
|
+
(0, import_daemon_core4.insertDirectDispatch)(ctx.mesh.id, {
|
|
4098
4105
|
taskId,
|
|
4099
4106
|
nodeId: args.node_id,
|
|
4100
4107
|
sessionId: dispatchedSessionId,
|
|
@@ -4105,12 +4112,13 @@ async function meshSendTask(ctx, args) {
|
|
|
4105
4112
|
dispatchedAt
|
|
4106
4113
|
});
|
|
4107
4114
|
if (missionId) {
|
|
4108
|
-
(0,
|
|
4115
|
+
(0, import_daemon_core4.recordDirectDispatchTask)(ctx.mesh.id, args.message, {
|
|
4109
4116
|
id: taskId,
|
|
4110
4117
|
missionId,
|
|
4111
4118
|
assignedNodeId: args.node_id,
|
|
4112
4119
|
assignedSessionId: dispatchedSessionId,
|
|
4113
4120
|
taskMode,
|
|
4121
|
+
...readonly ? { readonly: true } : {},
|
|
4114
4122
|
dispatchedAt
|
|
4115
4123
|
});
|
|
4116
4124
|
}
|
|
@@ -4237,7 +4245,7 @@ async function meshSendTask(ctx, args) {
|
|
|
4237
4245
|
const dispatchedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4238
4246
|
const coordinatorDaemonId = resolveCoordinatorDaemonId(ctx);
|
|
4239
4247
|
try {
|
|
4240
|
-
(0,
|
|
4248
|
+
(0, import_daemon_core4.appendLedgerEntry)(ctx.mesh.id, {
|
|
4241
4249
|
kind: "task_dispatched",
|
|
4242
4250
|
nodeId: args.node_id,
|
|
4243
4251
|
sessionId: args.session_id,
|
|
@@ -4253,7 +4261,7 @@ async function meshSendTask(ctx, args) {
|
|
|
4253
4261
|
});
|
|
4254
4262
|
} catch {
|
|
4255
4263
|
}
|
|
4256
|
-
(0,
|
|
4264
|
+
(0, import_daemon_core4.insertDirectDispatch)(ctx.mesh.id, {
|
|
4257
4265
|
taskId,
|
|
4258
4266
|
nodeId: args.node_id,
|
|
4259
4267
|
sessionId: args.session_id,
|
|
@@ -4266,7 +4274,7 @@ async function meshSendTask(ctx, args) {
|
|
|
4266
4274
|
});
|
|
4267
4275
|
let dispatchPreRecorded = false;
|
|
4268
4276
|
try {
|
|
4269
|
-
dispatchPreRecorded = (0,
|
|
4277
|
+
dispatchPreRecorded = (0, import_daemon_core4.getActiveDirectDispatches)(ctx.mesh.id).some((d) => d.taskId === taskId);
|
|
4270
4278
|
} catch {
|
|
4271
4279
|
}
|
|
4272
4280
|
const dispatchResult = await commandForNode(ctx, node, "agent_command", {
|
|
@@ -4288,7 +4296,7 @@ async function meshSendTask(ctx, args) {
|
|
|
4288
4296
|
const dispatchPayload = unwrapCommandPayload(dispatchResult);
|
|
4289
4297
|
if (dispatchPayload?.success === false || dispatchResult?.success === false) {
|
|
4290
4298
|
try {
|
|
4291
|
-
(0,
|
|
4299
|
+
(0, import_daemon_core4.deleteDirectDispatchesByTaskId)(ctx.mesh.id, [taskId]);
|
|
4292
4300
|
} catch {
|
|
4293
4301
|
}
|
|
4294
4302
|
dispatchPreRecorded = false;
|
|
@@ -4303,12 +4311,13 @@ async function meshSendTask(ctx, args) {
|
|
|
4303
4311
|
}
|
|
4304
4312
|
if (missionId) {
|
|
4305
4313
|
try {
|
|
4306
|
-
(0,
|
|
4314
|
+
(0, import_daemon_core4.recordDirectDispatchTask)(ctx.mesh.id, args.message, {
|
|
4307
4315
|
id: taskId,
|
|
4308
4316
|
missionId,
|
|
4309
4317
|
assignedNodeId: args.node_id,
|
|
4310
4318
|
assignedSessionId: args.session_id,
|
|
4311
4319
|
taskMode,
|
|
4320
|
+
...readonly ? { readonly: true } : {},
|
|
4312
4321
|
dispatchedAt
|
|
4313
4322
|
});
|
|
4314
4323
|
} catch {
|
|
@@ -4347,14 +4356,15 @@ async function meshSendTask(ctx, args) {
|
|
|
4347
4356
|
...computeIdleDispatchAckRisk(sessionWasIdle, dispatchPreRecorded, args.session_id)
|
|
4348
4357
|
});
|
|
4349
4358
|
}
|
|
4350
|
-
const task = (0,
|
|
4359
|
+
const task = (0, import_daemon_core4.enqueueTask)(ctx.mesh.id, args.message, {
|
|
4351
4360
|
targetNodeId: args.node_id,
|
|
4352
4361
|
targetSessionId: args.session_id,
|
|
4353
4362
|
taskMode,
|
|
4363
|
+
...readonly ? { readonly: true } : {},
|
|
4354
4364
|
...missionId ? { missionId } : {}
|
|
4355
4365
|
});
|
|
4356
4366
|
const queueTrigger = await triggerMeshQueueAndReport(ctx);
|
|
4357
|
-
const pendingEvents = (0,
|
|
4367
|
+
const pendingEvents = (0, import_daemon_core4.drainPendingMeshCoordinatorEvents)(ctx.mesh.id, ctx.localDaemonId);
|
|
4358
4368
|
const result = {
|
|
4359
4369
|
success: true,
|
|
4360
4370
|
source: "queue",
|
|
@@ -4399,7 +4409,7 @@ async function meshReadChat(ctx, args) {
|
|
|
4399
4409
|
tailLimit: args.tail ?? 10
|
|
4400
4410
|
});
|
|
4401
4411
|
} catch (e) {
|
|
4402
|
-
if (isLocalNode || !(0,
|
|
4412
|
+
if (isLocalNode || !(0, import_daemon_core4.isP2pRelayTransportFailure)(e)) throw e;
|
|
4403
4413
|
return buildMeshReadChatCacheFallback(ctx, args, node, e);
|
|
4404
4414
|
}
|
|
4405
4415
|
const payload = annotateRapidReadChatAdvisory(unwrapCommandPayload(result), {
|
|
@@ -4467,7 +4477,7 @@ async function meshLaunchSession(ctx, args) {
|
|
|
4467
4477
|
const coordinatorNode = resolveCoordinatorNode(ctx);
|
|
4468
4478
|
const coordinatorDaemonId = resolveCoordinatorDaemonId(ctx);
|
|
4469
4479
|
const spawnedSessionVisibility = readSpawnedSessionVisibility(ctx.mesh.policy);
|
|
4470
|
-
const delegatedWorkerAutoApprove = (0,
|
|
4480
|
+
const delegatedWorkerAutoApprove = (0, import_daemon_core4.resolveDelegatedWorkerAutoApprove)(ctx.mesh.policy, node.policy);
|
|
4471
4481
|
const isLocalNode = isLocalControlPlaneNode(ctx, node);
|
|
4472
4482
|
if (node.daemonId && !isLocalNode && !coordinatorDaemonId) {
|
|
4473
4483
|
return JSON.stringify(buildMissingCoordinatorDaemonIdFailure(ctx, node, resolvedProviderType), null, 2);
|
|
@@ -4543,7 +4553,7 @@ async function meshLaunchSession(ctx, args) {
|
|
|
4543
4553
|
});
|
|
4544
4554
|
}
|
|
4545
4555
|
try {
|
|
4546
|
-
(0,
|
|
4556
|
+
(0, import_daemon_core4.appendLedgerEntry)(ctx.mesh.id, {
|
|
4547
4557
|
kind: "session_launched",
|
|
4548
4558
|
nodeId: args.node_id,
|
|
4549
4559
|
sessionId: runtimeSessionId || void 0,
|
|
@@ -4724,7 +4734,7 @@ async function meshCheckpoint(ctx, args) {
|
|
|
4724
4734
|
includeUntracked: true
|
|
4725
4735
|
});
|
|
4726
4736
|
try {
|
|
4727
|
-
(0,
|
|
4737
|
+
(0, import_daemon_core4.appendLedgerEntry)(ctx.mesh.id, {
|
|
4728
4738
|
kind: "checkpoint_created",
|
|
4729
4739
|
nodeId: args.node_id,
|
|
4730
4740
|
payload: {
|