@adhdev/daemon-standalone 0.9.82-rc.370 → 0.9.82-rc.371
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 +52 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/vendor/mcp-server/index.js +60 -1
- package/vendor/mcp-server/index.js.map +1 -1
package/package.json
CHANGED
|
@@ -1249,7 +1249,7 @@ function compactMeshStatusNode(entry) {
|
|
|
1249
1249
|
}
|
|
1250
1250
|
delete next.capabilityTagsByProvider;
|
|
1251
1251
|
for (const k of Object.keys(next)) {
|
|
1252
|
-
if (k === "git" || k === "machine" || k === "branchConvergence" || k === "staleDaemonBuild" || k === "sessions") continue;
|
|
1252
|
+
if (k === "git" || k === "machine" || k === "branchConvergence" || k === "staleDaemonBuild" || k === "sessions" || k === "dataFreshness") continue;
|
|
1253
1253
|
next[k] = elideLargeNestedValue(k, next[k]);
|
|
1254
1254
|
}
|
|
1255
1255
|
return next;
|
|
@@ -1303,6 +1303,10 @@ function minimalCompactNode(entry) {
|
|
|
1303
1303
|
...entry.launchBlockedReason !== void 0 ? { launchBlockedReason: entry.launchBlockedReason } : {},
|
|
1304
1304
|
...bc ? { branchConvergence: bc } : {},
|
|
1305
1305
|
...entry.sessionSummary ? { sessionSummary: entry.sessionSummary } : {},
|
|
1306
|
+
// The freshness/reachability marker is exactly the signal a coordinator needs
|
|
1307
|
+
// on a QUIET node — is this idle peer live, cached, or unreachable? — and it is
|
|
1308
|
+
// tiny (6 scalar fields), so keep it even on the minimal stub.
|
|
1309
|
+
...entry.dataFreshness !== void 0 ? { dataFreshness: entry.dataFreshness } : {},
|
|
1306
1310
|
folded: true
|
|
1307
1311
|
};
|
|
1308
1312
|
}
|
|
@@ -2492,6 +2496,18 @@ var MESH_FAST_FORWARD_NODE_TOOL = {
|
|
|
2492
2496
|
required: ["node_id"]
|
|
2493
2497
|
}
|
|
2494
2498
|
};
|
|
2499
|
+
var MESH_RESTART_DAEMON_TOOL = {
|
|
2500
|
+
name: "mesh_restart_daemon",
|
|
2501
|
+
description: `Update a mesh node's daemon to the latest published version on its release channel and restart it \u2014 the same path as the dashboard "preview update" button, exposed as a mesh command so a coordinator can roll a worker daemon onto a freshly deployed version without a manual restart round-trip. No agent session is launched. Idle-gated: a node whose daemon has an active session (generating / waiting_approval / starting) is refused with code "blocking_sessions" so an in-flight turn is never interrupted. If the node is already on the latest version it is a no-op (no restart), matching the dashboard button (returns alreadyLatest:true). Targets a single node \u2014 call other (idle) nodes first; restarting the coordinator's OWN daemon is naturally refused while its calling turn is active. Passing channel switches the daemon's release channel (and server URL) before restarting; omit it to keep the daemon on its configured channel.`,
|
|
2502
|
+
inputSchema: {
|
|
2503
|
+
type: "object",
|
|
2504
|
+
properties: {
|
|
2505
|
+
node_id: { type: "string", description: "Target node ID \u2014 the daemon that owns this node is updated and restarted." },
|
|
2506
|
+
channel: { type: "string", enum: ["stable", "preview"], description: "Optional release channel to update from. Defaults to the daemon's configured updateChannel. Setting it also repoints the daemon's server URL to that channel." }
|
|
2507
|
+
},
|
|
2508
|
+
required: ["node_id"]
|
|
2509
|
+
}
|
|
2510
|
+
};
|
|
2495
2511
|
var MESH_CHECKPOINT_TOOL = {
|
|
2496
2512
|
name: "mesh_checkpoint",
|
|
2497
2513
|
description: "Create a git checkpoint (commit) on a mesh node workspace.",
|
|
@@ -2767,6 +2783,7 @@ var ALL_MESH_TOOLS = [
|
|
|
2767
2783
|
MESH_GIT_STATUS_TOOL,
|
|
2768
2784
|
MESH_READ_NODE_LOGS_TOOL,
|
|
2769
2785
|
MESH_FAST_FORWARD_NODE_TOOL,
|
|
2786
|
+
MESH_RESTART_DAEMON_TOOL,
|
|
2770
2787
|
MESH_CHECKPOINT_TOOL,
|
|
2771
2788
|
MESH_APPROVE_TOOL,
|
|
2772
2789
|
MESH_CLONE_NODE_TOOL,
|
|
@@ -2805,6 +2822,7 @@ async function meshStatus(ctx, args = {}) {
|
|
|
2805
2822
|
...getNodeLaunchReadiness(node),
|
|
2806
2823
|
...buildNodeCapabilityExposure(node)
|
|
2807
2824
|
};
|
|
2825
|
+
let liveTruthProbed = false;
|
|
2808
2826
|
try {
|
|
2809
2827
|
const autoDiscover = node.policy?.autoDiscoverSubmodules !== false;
|
|
2810
2828
|
const statusResult = await commandForNode(ctx, node, "git_status", {
|
|
@@ -2813,6 +2831,7 @@ async function meshStatus(ctx, args = {}) {
|
|
|
2813
2831
|
includeSubmodules: autoDiscover,
|
|
2814
2832
|
submoduleIgnorePaths: node.policy?.submoduleIgnorePaths || void 0
|
|
2815
2833
|
});
|
|
2834
|
+
liveTruthProbed = true;
|
|
2816
2835
|
const status = extractGitStatus(statusResult);
|
|
2817
2836
|
const uncommittedChanges = countUncommittedChanges(status);
|
|
2818
2837
|
const dirty = isGitStatusDirty(status);
|
|
@@ -2848,6 +2867,23 @@ async function meshStatus(ctx, args = {}) {
|
|
|
2848
2867
|
noFallbackReason: failure.noFallbackReason
|
|
2849
2868
|
});
|
|
2850
2869
|
}
|
|
2870
|
+
const freshnessDaemonId = readNodeDaemonId(node);
|
|
2871
|
+
const freshnessStatus = {
|
|
2872
|
+
git: entry.git,
|
|
2873
|
+
connection: { state: liveTruthProbed ? "connected" : "disconnected" }
|
|
2874
|
+
};
|
|
2875
|
+
if (liveTruthProbed) freshnessStatus[import_daemon_core.MESH_NODE_LIVE_TRUTH_MARKER] = true;
|
|
2876
|
+
entry.dataFreshness = (0, import_daemon_core.buildMeshNodeDataFreshness)({
|
|
2877
|
+
status: freshnessStatus,
|
|
2878
|
+
node,
|
|
2879
|
+
isSelfNode: entry.machine?.sameMachine === true,
|
|
2880
|
+
daemonId: freshnessDaemonId,
|
|
2881
|
+
liveTruthProbed,
|
|
2882
|
+
// A probe that threw against a configured (daemonId-bearing) peer is an
|
|
2883
|
+
// unreachable peer; an unconfigured node (no daemonId) falls through to
|
|
2884
|
+
// the classifier's `unconfigured` branch instead of being mislabeled.
|
|
2885
|
+
directTruthUnavailable: !liveTruthProbed && !!freshnessDaemonId
|
|
2886
|
+
});
|
|
2851
2887
|
const recoveryContext = (0, import_daemon_core.getSessionRecoveryContext)(mesh.id, { nodeId: node.id });
|
|
2852
2888
|
if (recoveryContext.consecutiveNodeFailures > 0) {
|
|
2853
2889
|
entry.recoveryHints = {
|
|
@@ -4420,6 +4456,26 @@ async function meshFastForwardNode(ctx, args) {
|
|
|
4420
4456
|
}, null, 2);
|
|
4421
4457
|
}
|
|
4422
4458
|
}
|
|
4459
|
+
async function meshRestartDaemon(ctx, args) {
|
|
4460
|
+
await refreshMeshFromDaemon(ctx);
|
|
4461
|
+
const node = await findNodeWithRefresh(ctx, args.node_id);
|
|
4462
|
+
try {
|
|
4463
|
+
const result = await commandForNode(ctx, node, "restart_daemon_node", {
|
|
4464
|
+
meshId: ctx.mesh.id,
|
|
4465
|
+
nodeId: node.id,
|
|
4466
|
+
inlineMesh: ctx.mesh,
|
|
4467
|
+
...args.channel ? { channel: args.channel } : {}
|
|
4468
|
+
});
|
|
4469
|
+
return JSON.stringify(unwrapCommandPayload(result), null, 2);
|
|
4470
|
+
} catch (e) {
|
|
4471
|
+
const failure = buildCoordinatorP2pRelayFailure(e, {
|
|
4472
|
+
command: "restart_daemon_node",
|
|
4473
|
+
targetDaemonId: node.daemonId,
|
|
4474
|
+
nodeId: args.node_id
|
|
4475
|
+
});
|
|
4476
|
+
return JSON.stringify(failure, null, 2);
|
|
4477
|
+
}
|
|
4478
|
+
}
|
|
4423
4479
|
async function meshCheckpoint(ctx, args) {
|
|
4424
4480
|
const node = await findNodeWithRefresh(ctx, args.node_id);
|
|
4425
4481
|
if (node.policy?.readOnly) {
|
|
@@ -5842,6 +5898,9 @@ async function startMcpServer(opts) {
|
|
|
5842
5898
|
case "mesh_fast_forward_node":
|
|
5843
5899
|
text = await meshFastForwardNode(meshCtx, a);
|
|
5844
5900
|
break;
|
|
5901
|
+
case "mesh_restart_daemon":
|
|
5902
|
+
text = await meshRestartDaemon(meshCtx, a);
|
|
5903
|
+
break;
|
|
5845
5904
|
case "mesh_checkpoint":
|
|
5846
5905
|
text = await meshCheckpoint(meshCtx, a);
|
|
5847
5906
|
break;
|