@adhdev/daemon-standalone 1.0.18-rc.20 → 1.0.18-rc.4
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 +7152 -11920
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/public/assets/index-Be0j0_PU.js +121 -0
- package/public/assets/index-CQVaCclg.css +1 -0
- package/public/index.html +2 -2
- package/vendor/mcp-server/index.js +4 -117
- package/vendor/mcp-server/index.js.map +1 -1
- package/vendor/mcp-server/package.json +1 -1
- package/public/assets/index-BeWlq-WP.js +0 -121
- package/public/assets/index-CXZe3Zxn.css +0 -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-Be0j0_PU.js"></script>
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/vendor-DyCWA2YZ.js">
|
|
12
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
12
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CQVaCclg.css">
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|
|
15
15
|
<!-- Apply theme immediately to prevent FOIT (Flash of Incorrect Theme) -->
|
|
@@ -391,7 +391,6 @@ var CANONICAL_MESH_TOOL_NAMES = [
|
|
|
391
391
|
"mesh_restart_daemon",
|
|
392
392
|
"mesh_checkpoint",
|
|
393
393
|
"mesh_approve",
|
|
394
|
-
"mesh_answer_question",
|
|
395
394
|
"mesh_list_pending_approvals",
|
|
396
395
|
"mesh_clone_node",
|
|
397
396
|
"mesh_remove_node",
|
|
@@ -1076,38 +1075,6 @@ var MESH_APPROVE_TOOL = {
|
|
|
1076
1075
|
required: ["node_id", "session_id", "action"]
|
|
1077
1076
|
}
|
|
1078
1077
|
};
|
|
1079
|
-
var MESH_ANSWER_QUESTION_TOOL = {
|
|
1080
|
-
name: "mesh_answer_question",
|
|
1081
|
-
description: 'Answer a multi-choice QUESTION (AskUserQuestion) a delegated agent session is waiting on. This is the counterpart to mesh_approve: a QUESTION (surfaced as an agent:waiting_choice event / status "awaiting_choice") is NOT a yes/no approval \u2014 it offers labelled options (optionally multi-select, optionally a freeform "Type something") and must be answered here, never with mesh_approve. Supply the promptId from the waiting_choice event and one answer per question. Each answer selects option(s) by their exact label OR 1-based index; for a multi-select question pass an array of selections; a freeform answer passes text instead. The daemon drives the correct keystrokes into the provider TUI to submit the selection.',
|
|
1082
|
-
inputSchema: {
|
|
1083
|
-
type: "object",
|
|
1084
|
-
properties: {
|
|
1085
|
-
node_id: { type: "string", description: "Target node ID (from the waiting_choice event / mesh_list_nodes)." },
|
|
1086
|
-
session_id: { type: "string", description: "Agent session ID that is awaiting the question answer." },
|
|
1087
|
-
promptId: { type: "string", description: "The InteractivePrompt promptId from the agent:waiting_choice event. Ensures the answer matches the active prompt." },
|
|
1088
|
-
answers: {
|
|
1089
|
-
type: "array",
|
|
1090
|
-
description: "One entry per question in the prompt (in question order). Each entry answers a single question by selecting option label(s)/index(es), or by supplying freeform text.",
|
|
1091
|
-
items: {
|
|
1092
|
-
type: "object",
|
|
1093
|
-
properties: {
|
|
1094
|
-
questionId: { type: "string", description: "Optional question id from the prompt payload. When omitted, entries are matched to the prompt questions by array position." },
|
|
1095
|
-
select: {
|
|
1096
|
-
description: "The chosen option(s): an option label (string), a 1-based option index (number), or an array of labels/indices for a multi-select question.",
|
|
1097
|
-
oneOf: [
|
|
1098
|
-
{ type: "string" },
|
|
1099
|
-
{ type: "number" },
|
|
1100
|
-
{ type: "array", items: { type: ["string", "number"] } }
|
|
1101
|
-
]
|
|
1102
|
-
},
|
|
1103
|
-
freeform: { type: "string", description: 'Freeform text answer (for a "Type something" option). Mutually exclusive with select.' }
|
|
1104
|
-
}
|
|
1105
|
-
}
|
|
1106
|
-
}
|
|
1107
|
-
},
|
|
1108
|
-
required: ["node_id", "session_id", "promptId", "answers"]
|
|
1109
|
-
}
|
|
1110
|
-
};
|
|
1111
1078
|
var MESH_LIST_PENDING_APPROVALS_TOOL = {
|
|
1112
1079
|
name: "mesh_list_pending_approvals",
|
|
1113
1080
|
description: "List every session across the mesh that is currently awaiting an approval decision (status awaiting_approval) \u2014 the mesh-wide approval inbox. mesh_approve resolves ONE (node_id, session_id) at a time; this read-only tool enumerates the full pending set so you can see all blocked sessions at once and drive a mesh_approve for each. Each row carries nodeId, sessionId, providerType, taskTitle, and how long it has been waiting (waitingSince/waitingMs), longest-waiting first. Does not mutate anything.",
|
|
@@ -1204,23 +1171,7 @@ var MESH_RECORD_NOTE_TOOL = {
|
|
|
1204
1171
|
category: {
|
|
1205
1172
|
type: "string",
|
|
1206
1173
|
enum: ["provider_quirk", "pattern_to_avoid", "recovery_lesson"],
|
|
1207
|
-
description: "Optional classification: provider_quirk (a provider/runtime behaves unexpectedly), pattern_to_avoid (an approach that caused problems), recovery_lesson (how a failure was recovered).
|
|
1208
|
-
},
|
|
1209
|
-
pinned: {
|
|
1210
|
-
type: "boolean",
|
|
1211
|
-
description: "Pin this note so it ALWAYS rides into every coordinator prompt: never dropped by TTL expiry and kept ahead of unpinned notes when the injection cap is hit. Use for durable, high-value operating knowledge you never want to lose from the prompt."
|
|
1212
|
-
},
|
|
1213
|
-
ttl_days: {
|
|
1214
|
-
type: "number",
|
|
1215
|
-
description: "Optional explicit read-side lifespan in days. Resolved to an absolute expiry at record time; after it passes an UNPINNED note is hidden from the injected prompt (but retained in the ledger for audit). Overrides the category default TTL. Ignored when pinned is true."
|
|
1216
|
-
},
|
|
1217
|
-
supersedes: {
|
|
1218
|
-
type: "string",
|
|
1219
|
-
description: "Optional version-supersede: the note_id of an earlier note this one replaces, OR a subject_key shared with earlier notes. At injection any earlier LIVE note matching this id/subject is hidden from the prompt (its ledger entry is retained for audit). Use when you record an updated lesson that makes a prior one obsolete. Pinned notes are never hidden by supersede."
|
|
1220
|
-
},
|
|
1221
|
-
subject_key: {
|
|
1222
|
-
type: "string",
|
|
1223
|
-
description: "Optional stable subject key grouping notes about the same subject. Drives version-supersede targeting and read-side same-class folding (multiple live notes with the same category AND subject_key collapse to one injected entry, newest kept, older ids listed). When omitted, folding falls back to a leading [tag] bracket in the text."
|
|
1174
|
+
description: "Optional classification: provider_quirk (a provider/runtime behaves unexpectedly), pattern_to_avoid (an approach that caused problems), recovery_lesson (how a failure was recovered)."
|
|
1224
1175
|
}
|
|
1225
1176
|
},
|
|
1226
1177
|
required: ["text"]
|
|
@@ -1541,7 +1492,6 @@ var ALL_MESH_TOOLS = [
|
|
|
1541
1492
|
MESH_RESTART_DAEMON_TOOL,
|
|
1542
1493
|
MESH_CHECKPOINT_TOOL,
|
|
1543
1494
|
MESH_APPROVE_TOOL,
|
|
1544
|
-
MESH_ANSWER_QUESTION_TOOL,
|
|
1545
1495
|
MESH_LIST_PENDING_APPROVALS_TOOL,
|
|
1546
1496
|
MESH_CLONE_NODE_TOOL,
|
|
1547
1497
|
MESH_REMOVE_NODE_TOOL,
|
|
@@ -4403,15 +4353,6 @@ async function meshRecordNote(ctx, args) {
|
|
|
4403
4353
|
}
|
|
4404
4354
|
const category = args.category === "provider_quirk" || args.category === "pattern_to_avoid" || args.category === "recovery_lesson" ? args.category : void 0;
|
|
4405
4355
|
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4406
|
-
const pinned = args.pinned === true ? true : void 0;
|
|
4407
|
-
let expiresAt;
|
|
4408
|
-
if (typeof args.expiresAt === "string" && !Number.isNaN(new Date(args.expiresAt).getTime())) {
|
|
4409
|
-
expiresAt = new Date(args.expiresAt).toISOString();
|
|
4410
|
-
} else if (typeof args.ttl_days === "number" && Number.isFinite(args.ttl_days) && args.ttl_days > 0) {
|
|
4411
|
-
expiresAt = new Date(new Date(createdAt).getTime() + args.ttl_days * 24 * 60 * 60 * 1e3).toISOString();
|
|
4412
|
-
}
|
|
4413
|
-
const supersedes = typeof args.supersedes === "string" && args.supersedes.trim() ? args.supersedes.trim() : void 0;
|
|
4414
|
-
const subjectKey = typeof args.subject_key === "string" && args.subject_key.trim() ? args.subject_key.trim() : void 0;
|
|
4415
4356
|
const sourceCoordinator = ctx.coordinatorSessionId || ctx.localDaemonId || ctx.coordinatorHostname || void 0;
|
|
4416
4357
|
const entry = (0, import_daemon_core4.appendLedgerEntry)(mesh.id, {
|
|
4417
4358
|
kind: "coordinator_operating_note",
|
|
@@ -4420,26 +4361,14 @@ async function meshRecordNote(ctx, args) {
|
|
|
4420
4361
|
text,
|
|
4421
4362
|
...category ? { category } : {},
|
|
4422
4363
|
createdAt,
|
|
4423
|
-
...sourceCoordinator ? { sourceCoordinator } : {}
|
|
4424
|
-
...pinned ? { pinned } : {},
|
|
4425
|
-
...expiresAt ? { expiresAt } : {},
|
|
4426
|
-
...supersedes ? { supersedes } : {},
|
|
4427
|
-
...subjectKey ? { subjectKey } : {}
|
|
4364
|
+
...sourceCoordinator ? { sourceCoordinator } : {}
|
|
4428
4365
|
}
|
|
4429
4366
|
});
|
|
4430
4367
|
return JSON.stringify({
|
|
4431
4368
|
success: true,
|
|
4432
4369
|
meshId: mesh.id,
|
|
4433
4370
|
noteId: entry.id,
|
|
4434
|
-
recorded: {
|
|
4435
|
-
text,
|
|
4436
|
-
category: category ?? null,
|
|
4437
|
-
createdAt,
|
|
4438
|
-
pinned: pinned ?? false,
|
|
4439
|
-
expiresAt: expiresAt ?? null,
|
|
4440
|
-
supersedes: supersedes ?? null,
|
|
4441
|
-
subjectKey: subjectKey ?? null
|
|
4442
|
-
},
|
|
4371
|
+
recorded: { text, category: category ?? null, createdAt },
|
|
4443
4372
|
note: 'Recorded to the mesh ledger. Future coordinators on this mesh will see it under "## Operating Notes" at launch.'
|
|
4444
4373
|
}, null, 2);
|
|
4445
4374
|
}
|
|
@@ -6993,19 +6922,6 @@ async function meshLaunchSession(ctx, args) {
|
|
|
6993
6922
|
const coordinatorDaemonId = resolveCoordinatorDaemonId(ctx);
|
|
6994
6923
|
const spawnedSessionVisibility = readSpawnedSessionVisibility(ctx.mesh.policy);
|
|
6995
6924
|
const delegatedWorkerAutoApprove = (0, import_daemon_core4.resolveDelegatedWorkerAutoApprove)(ctx.mesh.policy, node.policy);
|
|
6996
|
-
let requestedAutoApproveMode;
|
|
6997
|
-
const delegatedWorkerDangerousModeAllow = (0, import_daemon_core4.resolveDelegatedWorkerDangerousModeAllow)(ctx.mesh.policy, node.policy);
|
|
6998
|
-
if (delegatedWorkerAutoApprove !== false) {
|
|
6999
|
-
try {
|
|
7000
|
-
const ws = typeof node.workspace === "string" && node.workspace.trim() ? node.workspace.trim() : "";
|
|
7001
|
-
if (ws) {
|
|
7002
|
-
const repo = (0, import_daemon_core4.loadRepoMeshJsonConfig)(ws);
|
|
7003
|
-
const repoMode = repo.sourceType === "repo_file" ? repo.config?.providerDefaults?.autoApproveModes?.[resolvedProviderType] : void 0;
|
|
7004
|
-
if (typeof repoMode === "string" && repoMode.trim()) requestedAutoApproveMode = repoMode.trim();
|
|
7005
|
-
}
|
|
7006
|
-
} catch {
|
|
7007
|
-
}
|
|
7008
|
-
}
|
|
7009
6925
|
const isLocalNode = isLocalControlPlaneNode(ctx, node);
|
|
7010
6926
|
if (node.daemonId && !isLocalNode && !coordinatorDaemonId) {
|
|
7011
6927
|
return JSON.stringify(buildMissingCoordinatorDaemonIdFailure(ctx, node, resolvedProviderType), null, 2);
|
|
@@ -7061,14 +6977,7 @@ async function meshLaunchSession(ctx, args) {
|
|
|
7061
6977
|
spawnedSessionVisibility,
|
|
7062
6978
|
// Delegated worker auto-approval (see resolveDelegatedWorkerAutoApprove).
|
|
7063
6979
|
// Lands in settingsOverride and beats the global per-provider autoApprove.
|
|
7064
|
-
// When a repo-requested mode ID is present AND auto-approve is enabled,
|
|
7065
|
-
// stamp the mode ID (validated daemon-side) alongside the boolean; the
|
|
7066
|
-
// adapter's resolveProviderAutoApproveMode prefers the mode and fails
|
|
7067
|
-
// closed on an unknown ID. delegatedWorkerDangerousModeAllow rides along
|
|
7068
|
-
// so the adapter can honor/deny a dangerous requested mode.
|
|
7069
6980
|
autoApprove: delegatedWorkerAutoApprove,
|
|
7070
|
-
...requestedAutoApproveMode ? { autoApproveMode: requestedAutoApproveMode } : {},
|
|
7071
|
-
delegatedWorkerDangerousModeAllow,
|
|
7072
6981
|
...coordinatorDaemonId ? { meshCoordinatorDaemonId: coordinatorDaemonId } : {},
|
|
7073
6982
|
// (3) Stamp the originating coordinator SESSION at launch too, so a worker
|
|
7074
6983
|
// launched via mesh_launch_session routes its completions back to the exact
|
|
@@ -7129,25 +7038,6 @@ async function meshApprove(ctx, args) {
|
|
|
7129
7038
|
});
|
|
7130
7039
|
return JSON.stringify(result, null, 2);
|
|
7131
7040
|
}
|
|
7132
|
-
async function meshAnswerQuestion(ctx, args) {
|
|
7133
|
-
const node = await findNodeWithRefresh(ctx, args.node_id);
|
|
7134
|
-
if (!args.promptId || typeof args.promptId !== "string") {
|
|
7135
|
-
return JSON.stringify({ success: false, error: "promptId is required (from the agent:waiting_choice event)." }, null, 2);
|
|
7136
|
-
}
|
|
7137
|
-
if (!Array.isArray(args.answers)) {
|
|
7138
|
-
return JSON.stringify({ success: false, error: "answers must be an array (one entry per question)." }, null, 2);
|
|
7139
|
-
}
|
|
7140
|
-
const result = await commandForNode(ctx, node, "interactive_prompt_response", {
|
|
7141
|
-
targetSessionId: args.session_id,
|
|
7142
|
-
sessionId: args.session_id,
|
|
7143
|
-
workspace: node.workspace,
|
|
7144
|
-
response: {
|
|
7145
|
-
promptId: args.promptId,
|
|
7146
|
-
answers: args.answers
|
|
7147
|
-
}
|
|
7148
|
-
});
|
|
7149
|
-
return JSON.stringify(result, null, 2);
|
|
7150
|
-
}
|
|
7151
7041
|
async function meshListPendingApprovals(ctx, _args = {}) {
|
|
7152
7042
|
(0, import_daemon_core4.recordMeshToolCall)({ meshId: ctx.mesh.id, tool: "mesh_list_pending_approvals" });
|
|
7153
7043
|
await refreshMeshFromDaemon(ctx);
|
|
@@ -8685,7 +8575,7 @@ async function startMcpServer(opts) {
|
|
|
8685
8575
|
const meshCtx = { mesh, transport, ...localDaemonId ? { localDaemonId } : {}, ...localMachineId ? { localMachineId } : {}, ...coordinatorHostname ? { coordinatorHostname } : {}, ...coordinatorSessionId ? { coordinatorSessionId } : {} };
|
|
8686
8576
|
const coordinatorPrompt = await buildMeshModeCoordinatorPrompt(mesh);
|
|
8687
8577
|
const server2 = new import_server.Server(
|
|
8688
|
-
{ name: "adhdev-mcp-server", version: "1.0.
|
|
8578
|
+
{ name: "adhdev-mcp-server", version: "1.0.17" },
|
|
8689
8579
|
{ capabilities: { tools: {}, resources: {} } }
|
|
8690
8580
|
);
|
|
8691
8581
|
const { ListResourcesRequestSchema, ReadResourceRequestSchema } = await import("@modelcontextprotocol/sdk/types.js");
|
|
@@ -8764,9 +8654,6 @@ async function startMcpServer(opts) {
|
|
|
8764
8654
|
case "mesh_approve":
|
|
8765
8655
|
text = await meshApprove(meshCtx, a);
|
|
8766
8656
|
break;
|
|
8767
|
-
case "mesh_answer_question":
|
|
8768
|
-
text = await meshAnswerQuestion(meshCtx, a);
|
|
8769
|
-
break;
|
|
8770
8657
|
case "mesh_list_pending_approvals":
|
|
8771
8658
|
text = await meshListPendingApprovals(meshCtx, a);
|
|
8772
8659
|
break;
|