@adhdev/daemon-standalone 0.9.82-rc.288 → 0.9.82-rc.290
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 +994 -894
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/index-77wzVjtD.css +1 -0
- package/public/assets/index-BDCYuVjC.js +113 -0
- package/public/assets/index-Bp_R6Vha.js +113 -0
- package/public/index.html +2 -2
- package/vendor/mcp-server/index.js +25 -5
- package/vendor/mcp-server/index.js.map +1 -1
package/public/index.html
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
<meta name="description" content="ADHDev self-hosted dashboard for controlling AI agents" />
|
|
8
8
|
<link rel="icon" href="/otter-logo.png" />
|
|
9
9
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet" />
|
|
10
|
-
<script type="module" crossorigin src="/assets/index-
|
|
10
|
+
<script type="module" crossorigin src="/assets/index-Bp_R6Vha.js"></script>
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/vendor-BHUMCOj6.js">
|
|
12
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
12
|
+
<link rel="stylesheet" crossorigin href="/assets/index-77wzVjtD.css">
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|
|
15
15
|
<!-- Apply theme immediately to prevent FOIT (Flash of Incorrect Theme) -->
|
|
@@ -1684,6 +1684,12 @@ function findClonedFromNode(ctx, node) {
|
|
|
1684
1684
|
if (!clonedFromNodeId) return void 0;
|
|
1685
1685
|
return ctx.mesh.nodes.find((n) => n.id === clonedFromNodeId || n.nodeId === clonedFromNodeId || n.node_id === clonedFromNodeId);
|
|
1686
1686
|
}
|
|
1687
|
+
function resolvePreferredWorktreeNodeId(ctx) {
|
|
1688
|
+
const worktreeNodes = (ctx.mesh.nodes || []).filter((n) => n.isLocalWorktree === true);
|
|
1689
|
+
if (worktreeNodes.length === 0) return void 0;
|
|
1690
|
+
const chosen = worktreeNodes[worktreeNodes.length - 1];
|
|
1691
|
+
return readString(chosen?.id) || readString(chosen?.nodeId) || readString(chosen?.node_id);
|
|
1692
|
+
}
|
|
1687
1693
|
function isLocalControlPlaneNode(ctx, node) {
|
|
1688
1694
|
return !!getLocalControlPlaneMatchReason(ctx, node);
|
|
1689
1695
|
}
|
|
@@ -2203,11 +2209,12 @@ async function drainCoordinatorPendingEvents(ctx, opts) {
|
|
|
2203
2209
|
function isP2pTransportUnavailableError(error) {
|
|
2204
2210
|
return (0, import_daemon_core.isP2pRelayTransportFailure)(error);
|
|
2205
2211
|
}
|
|
2206
|
-
function buildRemoveNodeArgs(ctx, nodeId, sessionCleanupMode) {
|
|
2212
|
+
function buildRemoveNodeArgs(ctx, nodeId, sessionCleanupMode, force) {
|
|
2207
2213
|
return {
|
|
2208
2214
|
meshId: ctx.mesh.id,
|
|
2209
2215
|
nodeId,
|
|
2210
2216
|
...sessionCleanupMode ? { sessionCleanupMode } : {},
|
|
2217
|
+
...force === true ? { force: true } : {},
|
|
2211
2218
|
inlineMesh: ctx.mesh
|
|
2212
2219
|
};
|
|
2213
2220
|
}
|
|
@@ -2246,6 +2253,10 @@ var MESH_ENQUEUE_TASK_TOOL = {
|
|
|
2246
2253
|
taskMode: { type: "string", enum: ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"], description: "CamelCase alias for task_mode." },
|
|
2247
2254
|
requiredTags: { type: "array", items: { type: "string" }, description: "Optional capability tags that every eligible node must have, e.g. os=darwin, provider=codex-cli, gpu." },
|
|
2248
2255
|
required_tags: { type: "array", items: { type: "string" }, description: "Snake_case alias for requiredTags." },
|
|
2256
|
+
target_node_id: { type: "string", description: "Optional: only this node may claim the task. 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." },
|
|
2257
|
+
targetNodeId: { type: "string", description: "CamelCase alias for target_node_id." },
|
|
2258
|
+
prefer_worktree: { type: "boolean", description: "Optional: when true, route this task to the most recently cloned idle worktree node (avoids the main/base workspace preemptively claiming an isolated task). No-op if no worktree node exists; resolves to a target_node_id when one does." },
|
|
2259
|
+
preferWorktree: { type: "boolean", description: "CamelCase alias for prefer_worktree." },
|
|
2249
2260
|
depends_on: { type: "array", items: { type: "string" }, description: "Task ids that must complete before this task becomes claimable. Cycles are rejected at enqueue." },
|
|
2250
2261
|
dependsOn: { type: "array", items: { type: "string" }, description: "CamelCase alias for depends_on." },
|
|
2251
2262
|
mission_id: { type: "string", description: "Mission this task belongs to (mesh_mission record id)." },
|
|
@@ -2445,7 +2456,7 @@ var MESH_CLONE_NODE_TOOL = {
|
|
|
2445
2456
|
};
|
|
2446
2457
|
var MESH_REMOVE_NODE_TOOL = {
|
|
2447
2458
|
name: "mesh_remove_node",
|
|
2448
|
-
description: "Remove a node from the mesh. If the node is a worktree, also cleans up the git worktree and directory. Session cleanup is controlled by mesh policy sessionCleanupOnNodeRemove unless session_cleanup_mode overrides it for this call.",
|
|
2459
|
+
description: "Remove a node from the mesh. If the node is a worktree, also cleans up the git worktree and directory. Session cleanup is controlled by mesh policy sessionCleanupOnNodeRemove unless session_cleanup_mode overrides it for this call. The coordinator's own local base node (same machine, NOT a worktree) is protected \u2014 removing it breaks live mesh membership and is rejected unless force:true is passed.",
|
|
2449
2460
|
inputSchema: {
|
|
2450
2461
|
type: "object",
|
|
2451
2462
|
properties: {
|
|
@@ -2454,7 +2465,8 @@ var MESH_REMOVE_NODE_TOOL = {
|
|
|
2454
2465
|
type: "string",
|
|
2455
2466
|
enum: ["preserve", "stop", "delete_stopped", "stop_and_delete"],
|
|
2456
2467
|
description: "Optional override for cleanup of delegated sessions attached to this node. preserve keeps history/processes; stop stops live runtimes only; delete_stopped removes completed transcripts only; stop_and_delete stops live runtimes and deletes records."
|
|
2457
|
-
}
|
|
2468
|
+
},
|
|
2469
|
+
force: { type: "boolean", description: "Override the coordinator-base-node guard. Only set true to intentionally tear down this mesh; the coordinator must then be re-registered/restarted. Worktree nodes never need force." }
|
|
2458
2470
|
},
|
|
2459
2471
|
required: ["node_id"]
|
|
2460
2472
|
}
|
|
@@ -3225,8 +3237,11 @@ async function meshEnqueueTask(ctx, args) {
|
|
|
3225
3237
|
const requiredTags = (0, import_daemon_core.normalizeMeshCapabilityTags)(Array.isArray(args.requiredTags) ? args.requiredTags : args.required_tags);
|
|
3226
3238
|
const dependsOn = Array.isArray(args.dependsOn) ? args.dependsOn : Array.isArray(args.depends_on) ? args.depends_on : void 0;
|
|
3227
3239
|
const missionId = readString(args.missionId) || readString(args.mission_id) || void 0;
|
|
3240
|
+
const explicitTarget = readString(args.targetNodeId) || readString(args.target_node_id) || void 0;
|
|
3241
|
+
const preferWorktree = args.preferWorktree === true || args.prefer_worktree === true;
|
|
3242
|
+
const targetNodeId = explicitTarget || (preferWorktree ? resolvePreferredWorktreeNodeId(ctx) : void 0);
|
|
3228
3243
|
try {
|
|
3229
|
-
const task = (0, import_daemon_core.enqueueTask)(ctx.mesh.id, args.message, { taskMode, requiredTags, dependsOn, missionId });
|
|
3244
|
+
const task = (0, import_daemon_core.enqueueTask)(ctx.mesh.id, args.message, { taskMode, requiredTags, dependsOn, missionId, targetNodeId });
|
|
3230
3245
|
if (!(ctx.transport instanceof IpcTransport)) {
|
|
3231
3246
|
const queueTrigger = await triggerMeshQueueAndReport(ctx);
|
|
3232
3247
|
return JSON.stringify({
|
|
@@ -3236,6 +3251,8 @@ async function meshEnqueueTask(ctx, args) {
|
|
|
3236
3251
|
status: task.status,
|
|
3237
3252
|
taskMode: task.taskMode,
|
|
3238
3253
|
requiredTags: task.requiredTags,
|
|
3254
|
+
...targetNodeId ? { targetNodeId } : {},
|
|
3255
|
+
...preferWorktree && !explicitTarget && !targetNodeId ? { preferWorktreeNoOp: true } : {},
|
|
3239
3256
|
queueTrigger,
|
|
3240
3257
|
...buildQueueTriggerGuidance(queueTrigger)
|
|
3241
3258
|
});
|
|
@@ -3246,6 +3263,7 @@ async function meshEnqueueTask(ctx, args) {
|
|
|
3246
3263
|
for (const node of ctx.mesh.nodes) {
|
|
3247
3264
|
const isLocalNode = isLocalControlPlaneNode(ctx, node);
|
|
3248
3265
|
if (isLocalNode || !node.daemonId) continue;
|
|
3266
|
+
if (targetNodeId && node.id !== targetNodeId) continue;
|
|
3249
3267
|
if (!(0, import_daemon_core.nodeSatisfiesRequiredTags)(requiredTags, (0, import_daemon_core.buildMeshNodeCapabilityTags)(node))) continue;
|
|
3250
3268
|
dispatchPromises.push(
|
|
3251
3269
|
ipcDispatchToRemoteAgent(ctx, node, { message: args.message }).then((result) => {
|
|
@@ -3300,6 +3318,8 @@ async function meshEnqueueTask(ctx, args) {
|
|
|
3300
3318
|
status: task.status,
|
|
3301
3319
|
taskMode: task.taskMode,
|
|
3302
3320
|
requiredTags: task.requiredTags,
|
|
3321
|
+
...targetNodeId ? { targetNodeId } : {},
|
|
3322
|
+
...preferWorktree && !explicitTarget && !targetNodeId ? { preferWorktreeNoOp: true } : {},
|
|
3303
3323
|
queueTrigger,
|
|
3304
3324
|
...buildQueueTriggerGuidance(queueTrigger)
|
|
3305
3325
|
});
|
|
@@ -4163,7 +4183,7 @@ async function meshCleanupSessions(ctx, args) {
|
|
|
4163
4183
|
}
|
|
4164
4184
|
async function meshRemoveNode(ctx, args) {
|
|
4165
4185
|
const node = await findNodeWithRefresh(ctx, args.node_id);
|
|
4166
|
-
const removeArgs = buildRemoveNodeArgs(ctx, args.node_id, args.session_cleanup_mode);
|
|
4186
|
+
const removeArgs = buildRemoveNodeArgs(ctx, args.node_id, args.session_cleanup_mode, args.force === true);
|
|
4167
4187
|
let result;
|
|
4168
4188
|
let transportFallback;
|
|
4169
4189
|
try {
|