@adhdev/daemon-standalone 1.0.51 → 1.0.53

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 CHANGED
@@ -37075,10 +37075,10 @@ var require_dist3 = __commonJS({
37075
37075
  }
37076
37076
  function getDaemonBuildInfo() {
37077
37077
  if (cached2) return cached2;
37078
- const commit = readInjected(true ? "f642e48fd7f7e878c97e7a7fd932c62447e41f33" : void 0) ?? "unknown";
37079
- const commitShort = readInjected(true ? "f642e48" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
37080
- const version2 = readInjected(true ? "1.0.51" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
37081
- const builtAt = readInjected(true ? "2026-08-16T15:50:59.470Z" : void 0);
37078
+ const commit = readInjected(true ? "6f71d20f96226b37956caec6b2cd7952dbbe01d9" : void 0) ?? "unknown";
37079
+ const commitShort = readInjected(true ? "6f71d20" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
37080
+ const version2 = readInjected(true ? "1.0.53" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
37081
+ const builtAt = readInjected(true ? "2026-08-17T01:10:49.969Z" : void 0);
37082
37082
  cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
37083
37083
  return cached2;
37084
37084
  }
@@ -52909,13 +52909,19 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
52909
52909
  if (byteLength2(prompt) <= PROMPT_SOFT_CAP_BYTES) return prompt;
52910
52910
  if (usesOverrideBase(ctx)) return prompt;
52911
52911
  const shed = [];
52912
- prompt = assembleCoordinatorPrompt(ctx, { dropOperatingNotes: true });
52913
- shed.push("operating notes");
52912
+ const hasPinnedNotes = (ctx.operatingNotes ?? []).some((note) => note?.pinned === true);
52913
+ prompt = assembleCoordinatorPrompt(ctx, { dropUnpinnedNotes: true });
52914
+ shed.push(hasPinnedNotes ? "unpinned operating notes" : "operating notes");
52914
52915
  if (byteLength2(prompt) <= PROMPT_SOFT_CAP_BYTES) {
52915
52916
  return appendTruncationNotice(prompt, shed);
52916
52917
  }
52917
- prompt = assembleCoordinatorPrompt(ctx, { dropOperatingNotes: true, dropRecentActivity: true });
52918
+ prompt = assembleCoordinatorPrompt(ctx, { dropUnpinnedNotes: true, dropRecentActivity: true });
52918
52919
  shed.push("recent activity");
52920
+ if (byteLength2(prompt) <= PROMPT_SOFT_CAP_BYTES || !hasPinnedNotes) {
52921
+ return appendTruncationNotice(prompt, shed);
52922
+ }
52923
+ prompt = assembleCoordinatorPrompt(ctx, { dropOperatingNotes: true, dropRecentActivity: true });
52924
+ shed.push("pinned operating notes");
52919
52925
  return appendTruncationNotice(prompt, shed);
52920
52926
  }
52921
52927
  function usesOverrideBase(ctx) {
@@ -52979,11 +52985,20 @@ Default branch: \`${mesh.defaultBranch}\`` : ""}`);
52979
52985
  sections.push(ctx.missionSection.trim());
52980
52986
  }
52981
52987
  if (!drop.dropRecentActivity) {
52982
- const recentActivity = buildRecentActivitySection(ctx.recentActivity);
52988
+ const nodeLabelById = /* @__PURE__ */ new Map();
52989
+ for (const n of mesh.nodes) {
52990
+ const explicit = typeof n.machineLabel === "string" ? n.machineLabel.trim() : "";
52991
+ const wtBranch = typeof n.worktreeBranch === "string" ? n.worktreeBranch.trim() : "";
52992
+ const wsBase = typeof n.workspace === "string" ? n.workspace.replace(/[\\/]+$/, "").split(/[\\/]/).pop() ?? "" : "";
52993
+ const label = explicit || wtBranch || wsBase;
52994
+ if (label) nodeLabelById.set(n.id, label);
52995
+ }
52996
+ const recentActivity = buildRecentActivitySection(ctx.recentActivity, nodeLabelById);
52983
52997
  if (recentActivity) sections.push(recentActivity);
52984
52998
  }
52985
52999
  if (!drop.dropOperatingNotes) {
52986
- const operatingNotes = buildOperatingNotesSection(ctx.operatingNotes);
53000
+ const notes = drop.dropUnpinnedNotes ? (ctx.operatingNotes ?? []).filter((note) => note?.pinned === true) : ctx.operatingNotes;
53001
+ const operatingNotes = buildOperatingNotesSection(notes);
52987
53002
  if (operatingNotes) sections.push(operatingNotes);
52988
53003
  }
52989
53004
  sections.push(buildPolicySection(mergeAndNormalizePolicy(void 0, mesh.policy)));
@@ -53092,10 +53107,12 @@ Default branch: \`${mesh.defaultBranch}\`` : ""}`);
53092
53107
  seenCapProvider.add(key2);
53093
53108
  const cap = resolveProviderMaxParallel(nodeSlots, type2);
53094
53109
  if (cap === void 0) continue;
53095
- providerCaps.push(`${type2} (max ${cap})`);
53110
+ providerCaps.push(`${type2}\xD7${cap}`);
53096
53111
  }
53097
53112
  const providerRolesSuffix = providerCaps.length ? ` | caps: ${providerCaps.join(", ")}` : "";
53098
- lines.push(`- ${explicitLabel} nodeId: \`${n.id}\` | workspace: \`${n.workspace}\`${n.daemonId ? ` | daemon: \`${n.daemonId}\`` : ""}${providerPriority}${providerRolesSuffix}${suffix}`);
53113
+ const capsCoverPriority = providerCaps.length > 0 && (n.policy?.providerPriority ?? []).every((pv) => seenCapProvider.has(String(pv).trim().toLowerCase()));
53114
+ const providerSuffix = capsCoverPriority ? "" : providerPriority;
53115
+ lines.push(`- ${explicitLabel} nodeId: \`${n.id}\` | workspace: \`${n.workspace}\`${n.daemonId ? ` | daemon: \`${n.daemonId}\`` : ""}${providerSuffix}${providerRolesSuffix}${suffix}`);
53099
53116
  const routingTags = [];
53100
53117
  const custom2 = Array.isArray(n.capabilities) ? n.capabilities : [];
53101
53118
  for (const t of custom2) {
@@ -53124,7 +53141,7 @@ Default branch: \`${mesh.defaultBranch}\`` : ""}`);
53124
53141
  if (lines.length === 1) return lines[0];
53125
53142
  return [lines[0], ...lines.slice(1).map((l) => pad + l)].join("\n");
53126
53143
  }
53127
- function buildRecentActivitySection(activity) {
53144
+ function buildRecentActivitySection(activity, nodeLabelById) {
53128
53145
  if (!activity) return "";
53129
53146
  const failures = Array.isArray(activity.recentFailures) ? activity.recentFailures : [];
53130
53147
  const pending = Number.isFinite(activity.pendingTasks) ? Number(activity.pendingTasks) : 0;
@@ -53141,7 +53158,7 @@ Default branch: \`${mesh.defaultBranch}\`` : ""}`);
53141
53158
  const counts = [];
53142
53159
  if (pending > 0) counts.push(`**${pending}** pending`);
53143
53160
  if (assigned > 0) counts.push(`**${assigned}** assigned`);
53144
- if (stalled > 0) counts.push(`**${stalled}** stalled`);
53161
+ if (stalled > 0) counts.push(`**${stalled}** stalled (all-time ledger total, not current backlog)`);
53145
53162
  if (recentFailureCount > 0) counts.push(`**${recentFailureCount}** failed in the last ${windowMinutes3} min`);
53146
53163
  if (counts.length) lines.push(`- Queue/ledger: ${counts.join(", ")}.`);
53147
53164
  if (activity.lastActivityAt) lines.push(`- Last ledger activity: ${activity.lastActivityAt}.`);
@@ -53150,7 +53167,8 @@ Default branch: \`${mesh.defaultBranch}\`` : ""}`);
53150
53167
  lines.push("", "Recent failures (newest first):");
53151
53168
  for (const f of recent) {
53152
53169
  const when = f.timestamp ? `${f.timestamp} ` : "";
53153
- const node = f.nodeId ? `node \`${f.nodeId}\`` : "unknown node";
53170
+ const label = f.nodeId ? nodeLabelById?.get(f.nodeId) : void 0;
53171
+ const node = f.nodeId ? `node \`${f.nodeId}\`${label ? ` (${label})` : ""}` : "unknown node";
53154
53172
  const summary = (f.summary || "").trim();
53155
53173
  lines.push(`- ${when}${node}${summary ? ` \u2014 ${summary}` : ""}`);
53156
53174
  }
@@ -53372,15 +53390,15 @@ ${rules.join("\n")}`;
53372
53390
  - **Front-load task messages.** Include everything the agent needs (files, problem, expected fix) in \`mesh_enqueue_task\` / \`mesh_send_task\`. Append a structured result request at the end: ask the worker to conclude with a JSON block containing \`status\`, \`changedFiles\`, \`gitStatus\`, \`validationResults\`, \`errors\`, \`nextAction\`. The daemon parses this automatically; you can read it from \`mesh_task_history\`.
53373
53391
  - **Reuse idle sessions.** For follow-up, retry, commit/push, or cleanup on the same issue, send only the delta to the existing idle session. Start a fresh session only when: (a) branch/worktree isolation is required, (b) the existing session had a dispatch failure or provider mismatch, (c) the transcript/runtime is contaminated or interrupted, (d) the user explicitly asks for a different provider/session, or (e) **the delta is a genuinely NEW subject rather than a continuation** \u2014 a new topic appended to an existing session can be dropped or re-run as the previous task, so give it its own task even when a session sits idle. Continuation of the same issue in an already-idle session is allowed and preferred \u2014 this rule blocks concurrent unrelated work interleaved into a live (still-generating) session, not sequential same-issue follow-ups. The test is subject continuity, not timing: carrying an investigation forward into its own fix is the SAME subject and belongs in that session (Workflow 3f), while an unrelated bug is a new subject even if the same session just went idle.
53374
53392
  - **Nodes are separate machines with separate checkouts \u2014 not interchangeable execution slots.** Each node is a different physical computer with its own clone of the repo. Work done on another node must be committed, pushed, and pulled back before this machine sees it, and since RELEASE/DEPLOY runs on the coordinator's own machine, sending a code change elsewhere buys a round trip out and another one back. So **default to this coordinator's own machine for code changes** \u2014 its local node (base or a worktree cloned from it). Routing to a DIFFERENT machine is the exception and needs a reason, of which there are exactly two: (a) **platform-specific verification** that cannot be done here \u2014 win32 PATH/registry, a clean install/uninstall on that OS, that machine's package-manager state; or (b) **parallelizing read-only investigation** across machines. "That node is idle" is not a reason. If you catch yourself dispatching a fix to another machine without (a) or (b), route it here instead.
53375
- - **Don't split investigation from the fix.** When a task will plainly end in a code change, dispatch it as \`code_change\` from the start rather than a read-only investigation you hand off afterwards. The session that did the investigating already holds the findings; making a second session redo that context \u2014 especially on a different machine, where the findings have to be rewritten into a new task message \u2014 is pure loss. Carrying an investigation forward into its own fix is the SAME subject and belongs in that session (see the idle-session reuse rule). Split only when the fix genuinely belongs on another machine for reason (a) above.
53376
- - **Base nodes are reserved for environment-specific testing.** Do NOT use a base node for a general code change. If a task does not strictly test OS- or machine-specific physical behavior (win32 PATH/registry, clean install/uninstall on one OS, that machine's package-manager state, OS-dependent runtime behavior), you MUST clone a worktree with \`mesh_clone_node\` and assign the task there; pin genuine environment tasks to the base with \`required_tags\`/\`target_node_id\` instead. Having several nodes available is NOT branch isolation \u2014 every base node is one shared checkout of the same branch \u2014 and cloning is ~10s with auto-launch starting the session, so there is no dispatch-cost reason to skip it.
53377
- - **Worktree affinity.** A worktree is a durable per-branch workspace; keep all of a branch's code_change/fix/review work on its worktree node. Target it with \`required_tags: ["worktree=<branch>"]\` or \`target_node_id\`. Get the id/branch from the \`mesh_clone_node\` result or a live \`mesh_status\` \u2014 the Configured Nodes snapshot won't list a worktree cloned after launch. Untargeted same-branch follow-ups drift to the base node. Only \`convergence\` (merge/push) runs on the base, never pinned to the worktree.
53378
- - **Classify task difficulty honestly.** For each task you enqueue, judge its execution difficulty and pass \`difficulty\`: \`easy\` (extraction, renames, doc tweaks, trivial fixes), \`medium\` (ordinary feature/bugfix work), \`difficult\` (architecture, tricky debugging, multi-file refactors, subtle reasoning), or \`freeform\`. This is a ROUTING HINT matched against node capability slots \u2014 the matched slot's OWN model/thinking is what launches, so difficulty does not name a model. Do NOT inflate or deflate difficulty to reach a model you want: fix the node's slots instead (\`mesh_node_slots_set\`). See the "Task difficulty" section below. You may still pass an explicit \`model\`/\`thinkingLevel\` to override for one task.
53393
+ - **Don't split investigation from the fix.** When a task will plainly end in a code change, dispatch it as \`code_change\` from the start \u2014 the in-session handoff and split criteria live in Workflow 3f. Split only when the fix genuinely belongs on another machine for reason (a) above; redoing an investigator's context in a fresh session (worse, on another machine) is pure loss.
53394
+ - **Base nodes are reserved for environment-specific testing.** Apply Workflow 3.b0: only work that verifies a machine's physical environment runs on a base node (pinned with \`required_tags\`/\`target_node_id\`); every ordinary \`code_change\` gets its own cloned worktree. Node availability is not branch isolation.
53395
+ - **Worktree affinity.** Apply Workflow 3.b1: route a branch's follow-ups back to its own worktree node (\`required_tags: ["worktree=<branch>"]\` or \`target_node_id\`, taken from the \`mesh_clone_node\` result or a live \`mesh_status\`); only \`convergence\` (merge/push) runs base-side.
53396
+ - **Classify task difficulty honestly.** Judge each task's real difficulty (\`easy\`/\`medium\`/\`difficult\`/\`freeform\`) per the Task difficulty section above \u2014 it is a routing hint, and the matched slot's own model/thinking is what launches. Never bend difficulty to chase a model; retune slots instead (\`mesh_node_slots_set\`).
53379
53397
  - **Retune node profiles when routing is a poor fit \u2014 but only with approval.** A node's capability slots (its provider/model/thinking + difficulty range + capability tags, seen via \`mesh_node_slots_list\`) are what task\u2192node fitness routing matches against. If you notice a persistent mismatch \u2014 e.g. every \`difficult\` task lands on a node whose only slot is a cheap model, or a capability a node clearly has isn't declared \u2014 you MAY propose a slot change with \`mesh_node_slots_set\` (write=false). That returns current-vs-proposed; present that diff to the user with a one-line reason and apply (write=true) ONLY after they approve. It is a WHOLESALE replacement of the node's slots, so include the slots you want to keep. Never rewrite a node's profile silently or without a clear routing reason.
53380
53398
  - **Bootstrap a node's slots from what's actually installed.** When a node has NO slots configured (routing then falls back to "first available provider"), or CLI agents were newly installed on it, call \`mesh_node_slots_propose({ node_id })\` instead of hand-writing a profile. It detects the node's installed CLI agents and drafts a slot list from them \u2014 read-only, it never writes. Present its \`proposedSlots\` with the \`droppedSlots\` / \`destructive\` fields it reports (a wholesale write would delete any existing hand-tuned slot the draft doesn't reproduce, including providers not currently on PATH), then apply with \`mesh_node_slots_set({ slots: proposedSlots, write: true })\` after approval. It flags \`unknownProvider\` / \`provisional\` slots whose placement is a conservative guess rather than an attested one \u2014 call those out rather than presenting them as settled.
53381
53399
  - **Respect explicit provider requests.** Map: Hermes \u2192 \`hermes-cli\`, Claude/Claude Code \u2192 \`claude-cli\`, Codex \u2192 \`codex-cli\`, Gemini \u2192 \`gemini-cli\`, Antigravity \u2192 \`antigravity-cli\`. Never substitute the coordinator's own runtime.
53382
53400
  - **Verify via git, not source.** Use \`mesh_git_status\` to confirm side effects. Treat agent summaries as self-reports, not verification.
53383
- - **Match concurrency to task kind.** Read-only investigation (\`live_debug_readonly\`) carries no isolation or merge cost and is exempt from the one-write-per-node limit: dispatch every independent read-only task at once, up to the read-only cap shown in Policy \u2014 they need neither a free node nor a worktree. Write tasks (\`code_change\`) are limited to ONE active task per node and each needs its OWN branch workspace, so clone a worktree per write task rather than queueing them onto one node \u2014 **or spreading them across base nodes, which is NOT a substitute**: a mesh with four base nodes still has zero branch isolation, because each base node is one shared checkout of the same branch. Ramp up cautiously only when tasks share a base branch or a submodule pointer, where landing order actually matters. Never launch a second session onto work already in flight for the same issue, and never duplicate a session because \`mesh_read_chat\` shows no final message while tool/terminal activity is ongoing. All of this is about *unrelated* work running side by side; it does not mean splitting one line of work across sessions \u2014 successive stages of the same investigation belong in the session that already has the context (see Workflow 3f).
53401
+ - **Match concurrency to task kind.** Independent read-only tasks (\`live_debug_readonly\`) dispatch all at once up to the read-only cap \u2014 no worktree, no free node needed. Each write task needs its OWN branch workspace (Workflow 3.b0); spreading writes across base nodes is NOT a substitute: a mesh with four base nodes still has zero branch isolation. Ramp up cautiously only when tasks share a base branch or submodule pointer (landing order matters). Never launch a second session onto in-flight work for the same issue, even when \`mesh_read_chat\` shows no final message yet \u2014 successive stages of one investigation stay in their session (see Workflow 3f).
53384
53402
  - **Check history first.** Call \`mesh_task_history\` at session start to avoid duplicate work and inform recovery. On failure, read task history before retrying.
53385
53403
  - **Don't reopen already-done work after a resume.** Before reopening a reported issue after context compaction or session resume, check current git state and recent session context. If another session has already completed the work, continue from the existing diff/commit instead of starting a duplicate investigation.
53386
53404
  - **Sequence shared-base-moving merges \u2014 use \`mesh_refine_batch\` for two or more.** Merging one worktree advances another in-flight worktree's base \u2014 especially a shared submodule pointer \u2014 turning a clean fast-forward into a diverged rebase. When you have 2+ sibling worktrees to land, pass them to \`mesh_refine_batch\` (dry-run first) instead of calling \`mesh_refine_node\` once per node: it picks a conflict-aware order (non-submodule first, submodule-touching serialized last), and because each node re-resolves the base and auto-rebases before its own gates, siblings that fall behind are rebased for you rather than by hand. It also avoids the \`base_locked\` contention that concurrent single-node refines cause. It is not a conflict solver \u2014 a real content or submodule conflict still lands that node in \`blocked_review\` for manual resolution while the rest of the batch proceeds. Only drop to per-node \`mesh_refine_node\` for a single branch, or to hand-resolve a node the batch reported blocked.
@@ -53422,69 +53440,69 @@ When you compose the task message you dispatch to a node, include this requireme
53422
53440
  init_mesh_node_slots();
53423
53441
  init_mesh_ledger();
53424
53442
  init_dist();
53425
- PROMPT_SOFT_CAP_BYTES = 60 * 1024;
53443
+ PROMPT_SOFT_CAP_BYTES = 96 * 1024;
53426
53444
  OPERATING_NOTES_PROMPT_CAP = 20;
53427
53445
  OPERATING_NOTE_MAX_CHARS = 300;
53428
- OPERATING_NOTE_INJECTION_BYTE_BUDGET = 6 * 1024;
53446
+ OPERATING_NOTE_INJECTION_BYTE_BUDGET = 8 * 1024;
53429
53447
  TOOLS_SECTION = `## Available Tools
53430
53448
 
53431
53449
  | Tool | Purpose |
53432
53450
  |------|---------|
53433
- | \`mesh_status\` | Check all nodes' health, git state, active sessions, and branch convergence |
53451
+ | \`mesh_status\` | Nodes' health, git state, sessions, branch convergence |
53434
53452
  | \`mesh_list_nodes\` | List nodes with workspace paths |
53435
- | \`mesh_enqueue_task\` | Add a task to the pull-based work queue; idle nodes auto-claim |
53436
- | \`mesh_enqueue_batch\` | Atomically enqueue a dependency-wired SET of tasks (all-or-nothing \u2014 a mid-batch error rolls the whole batch back); \`depends_on\` may name batch-local \`ref\` labels, forward references allowed |
53437
- | \`mesh_view_queue\` | View queue status \u2014 pending, assigned, completed, failed, cancelled tasks |
53438
- | \`mesh_queue_cancel\` | Cancel a queue task without deleting audit history |
53439
- | \`mesh_queue_requeue\` | Return a task to pending for retry; clears stale session targets |
53440
- | \`mesh_send_task\` | Legacy push: enqueue a task targeted at a specific node |
53441
- | \`mesh_mission_upsert\` | Create/update a persistent mission so a multi-task plan survives coordinator restarts; set status completed/abandoned when the outcome is decided |
53442
- | \`mesh_mission_list\` | List every mission with goal, status, and live task progress \u2014 the authority for "what work remains" (never hidden by status) |
53453
+ | \`mesh_enqueue_task\` | Add a task to the pull-based queue; idle nodes auto-claim |
53454
+ | \`mesh_enqueue_batch\` | Atomically enqueue a dependency-wired task set; \`depends_on\` may name batch-local \`ref\`s (forward refs OK) |
53455
+ | \`mesh_view_queue\` | Queue status \u2014 pending/assigned/completed/failed/cancelled |
53456
+ | \`mesh_queue_cancel\` | Cancel a queue task (audit history kept) |
53457
+ | \`mesh_queue_requeue\` | Return a task to pending for retry |
53458
+ | \`mesh_send_task\` | Push a task straight to a specific node/session |
53459
+ | \`mesh_mission_upsert\` | Create/update a persistent mission; set completed/abandoned when decided |
53460
+ | \`mesh_mission_list\` | All missions with goal/status/progress \u2014 the authority for "what work remains" |
53443
53461
  | \`mesh_launch_session\` | Start a new agent session on a node |
53444
- | \`mesh_read_chat\` | Read recent chat messages from a delegated agent session |
53445
- | \`mesh_read_debug\` | Collect a daemon-side chat/parser debug bundle for a session |
53446
- | \`mesh_read_terminal\` | Read a worker session's CURRENT raw terminal screen (the live rendered PTY viewport \u2014 prompt/modal/spinner/unparsed output), not the parsed chat. Byte-bounded (32KiB default, 64KiB max; bottom of screen kept). Use to see exactly what a worker is showing when mesh_read_chat is not enough (e.g. after a stall alert). Screen text may contain secrets \u2014 treat as sensitive |
53447
- | \`mesh_send_keys\` | Inject a STRUCTURED key sequence into a worker's live PTY (text + named keys ENTER/ESC/CTRL_C/UP/DOWN/LEFT/RIGHT/TAB/BACKSPACE). For interactions mesh_send_task can't express \u2014 answer a non-approval prompt, navigate a picker, submit a typed line, or interrupt (CTRL_C). Use mesh_approve for approval modals (send_keys is refused on one). Destructive keys (CTRL_C/ESC) need confirm_destructive=true AND mesh policy allowSendKeysDestructive. Refused on a pending submit/echo race. Audited (key enums only) |
53448
- | \`mesh_task_history\` | Read the task ledger \u2014 dispatches, completions, failures. Use to understand what has been done before deciding next steps |
53449
- | \`mesh_ledger_query\` | Read-only ledger query along the kind/time/node axes (complement to task-axis mesh_task_history): filter by kind, since, node, tail \u2014 answer "what happened on node X / what failed since T" without scanning transcripts |
53450
- | \`mesh_reconcile_ledger\` | Reconcile daemon-local ledgers over P2P \u2014 import missing entries from remote nodes into the coordinator local ledger |
53451
- | \`mesh_requeue_held_events\` | Restore recoverable held coordinator events (T6 quarantine / pending-trim) back to the pending queue; lossless, no double-requeue |
53452
- | \`mesh_review_inbox\` | List local worktree nodes needing human review \u2014 merge candidates and Refinery-blocked results with evidence/diff summaries |
53453
- | \`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 |
53454
- | \`mesh_forget_note\` | Retract a stale/wrong operating note by note_id or exact text so it stops riding into future coordinators' prompts (append-only tombstone; history preserved) |
53455
- | \`mesh_git_status\` | Check git status on a specific node |
53456
- | \`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 |
53457
- | \`mesh_fast_forward_node\` | Safely dry-run or explicitly execute an obvious clean fast-forward without launching an agent session |
53458
- | \`mesh_restart_daemon\` | Update a node's daemon to the latest published version on its channel and restart it (the dashboard "preview update" path, as a mesh command) |
53462
+ | \`mesh_read_chat\` | Read recent chat from a delegated session |
53463
+ | \`mesh_read_debug\` | Daemon-side chat/parser debug bundle for a session |
53464
+ | \`mesh_read_terminal\` | Worker's live raw PTY screen (modal/spinner/unparsed) when parsed chat isn't enough; byte-bounded; may contain secrets |
53465
+ | \`mesh_send_keys\` | Inject structured keys (text + ENTER/ESC/CTRL_C/arrows) into a worker PTY for non-approval prompts/pickers; approvals use \`mesh_approve\`; destructive keys are gated |
53466
+ | \`mesh_task_history\` | Task ledger \u2014 dispatches, completions, failures |
53467
+ | \`mesh_ledger_query\` | Ledger query by kind/since/node/tail (kind/time/node axes) |
53468
+ | \`mesh_reconcile_ledger\` | Import missing ledger entries from remote nodes over P2P |
53469
+ | \`mesh_requeue_held_events\` | Restore held coordinator events to the pending queue (lossless) |
53470
+ | \`mesh_review_inbox\` | Local worktree nodes needing human review, with evidence/diff summaries |
53471
+ | \`mesh_record_note\` | Record a durable operating note (quirk / pattern to avoid / recovery lesson) for future coordinators |
53472
+ | \`mesh_forget_note\` | Retract a stale note by id or exact text (tombstone; history kept) |
53473
+ | \`mesh_git_status\` | Git status on a specific node |
53474
+ | \`mesh_read_node_logs\` | Remote node's daemon log tail over P2P (grep/since; secrets redacted) |
53475
+ | \`mesh_fast_forward_node\` | Dry-run / execute an obvious clean fast-forward without an agent session |
53476
+ | \`mesh_restart_daemon\` | Update a node's daemon to its channel's latest and restart |
53459
53477
  | \`mesh_checkpoint\` | Create a git checkpoint on a node |
53460
- | \`mesh_approve\` | Approve/reject a pending agent action (a yes/no tool-consent modal) |
53461
- | \`mesh_answer_question\` | Answer a delegated session's multi-choice QUESTION (AskUserQuestion / status awaiting_choice). NOT an approval \u2014 it offers labelled options (possibly multi-select or freeform). Pass the promptId from the agent:waiting_choice event + one answer per question (select by option label or 1-based index). Use this, never mesh_approve, for a question |
53462
- | \`mesh_list_pending_approvals\` | List every session across the mesh awaiting an approval decision (the approval inbox) \u2014 read-only; enumerate all blocked sessions at once, then drive a mesh_approve for each |
53463
- | \`mesh_plan_onboarding\` | Read-only Git-aware discovery and dry-run plan for creating a mesh, adding an existing checkout/worktree, or cloning a new worktree. Call this before mesh_create/mesh_add_node/mesh_clone_node; it never writes |
53464
- | \`mesh_create\` | Bootstrap a NEW mesh for a repo (name + repo_remote_url/repo_identity); optionally register the current workspace as the first node. The from-scratch entry point when no mesh exists yet |
53465
- | \`mesh_add_node\` | Register a workspace as a node in an existing mesh (workspace + optional read_only/provider_priority). The second bootstrap step after mesh_create; use mesh_clone_node instead to create a fresh git worktree |
53466
- | \`mesh_clone_node\` | Create a worktree node for isolated parallel branch work |
53467
- | \`mesh_refine_node\` | Validate and merge a completed worktree node back into its base branch |
53468
- | \`mesh_refine_batch\` | Batch Refinery: converge multiple sibling worktree nodes onto the base branch in one conflict-aware sequential pipeline |
53469
- | \`mesh_refine_plan\` | Dry-run Refinery plan for a worktree node \u2014 config source, validation commands, merge/cleanup intent \u2014 without executing validation or git merge |
53470
- | \`mesh_refine_config\` | Refinery config helper (read-only) \u2014 unified entry for schema/validate/suggest via a required \`mode\` |
53471
- | \`mesh_change_impact_config\` | Change Impact config helper \u2014 unified entry for schema/validate/suggest via a required \`mode\` |
53472
- | \`mesh_remove_node\` | Remove a node (cleans up worktree if applicable) |
53473
- | \`mesh_cleanup_worktree_nodes\` | Plan (dry-run default) or execute safe removal of CONVERGED local worktree nodes (lifecycle retention) - per-node reason codes always shown; never forces |
53474
- | \`mesh_cleanup_sessions\` | Manually clean up delegated session records for a node |
53475
- | \`mesh_prune_stale_direct\` | Prune orphaned staleDirect dispatch records (dry-run by default); live/pending work and audit history preserved |
53476
- | \`mesh_init\` | Guided onboarding for a fresh repo: dry-run scan \u2192 suggest \`.adhdev/*\` configs (refine/bootstrap/change-impact) + providerPriority + current-config echo; gated write on approval |
53477
- | \`mesh_reinit\` | Re-onboard an already-configured repo: re-suggest with overwrite semantics + current-vs-suggested diff; dry-run preview first, per-section approval before write |
53478
- | \`mesh_write_mesh_json_config\` | Gated write of \`.adhdev/mesh.json\` (repo coordinator-prompt config) from the mesh entry \u2014 dry-run/overwrite like mesh_init |
53479
- | \`mesh_magi_review\` | Cross-verify a read-only investigation across a standing panel of independent mesh agents (different machines/providers) instead of a single worker |
53480
- | \`mesh_magi_collect\` | Collect + synthesize a previously dispatched MAGI fan-out by its consensus group id (async companion to mesh_magi_review wait:false) |
53481
- | \`mesh_magi_kind_panel_set\` | Bind a task_kind \u2192 MAGI kind-panel slots (the SOLE MAGI panel-resolution surface; machine-local, wholesale replacement \u2014 approve current-vs-new first) |
53482
- | \`mesh_magi_kind_panel_list\` | List configured task_kind \u2192 MAGI kind-panel slot bindings (machine-local, read-only) |
53483
- | \`mesh_node_slots_list\` | List a node's capability slots (its AI-tool profile: provider/model/thinking + difficulty range + capability tags), read-only |
53484
- | \`mesh_node_slots_set\` | PROPOSE (dry-run) or APPLY a node's capability slots \u2014 how you autonomously retune a node's tool profile; WHOLESALE replacement, present current-vs-proposed and get user approval before write=true |
53485
- | \`mesh_node_slots_propose\` | AUTO-DETECT a node's installed CLI agents and DRAFT a slot profile from them (read-only, never writes) \u2014 use when a node has no slots yet or new CLIs were installed; reports droppedSlots (what a wholesale write would destroy), then apply via mesh_node_slots_set write=true after approval |
53486
- | \`mesh_coordinator_prompt_append_get\` | Read this daemon's user-level coordinator prompt APPEND text for a CLI type (per-machine file, applies to every mesh this daemon coordinates) |
53487
- | \`mesh_coordinator_prompt_append_set\` | Write or clear this daemon's user-level coordinator prompt APPEND text for a CLI type \u2014 APPEND ONLY, always stacks after the base prompt; there is no tool to replace the base prompt itself |`;
53478
+ | \`mesh_approve\` | Approve/reject a pending yes/no tool-consent modal |
53479
+ | \`mesh_answer_question\` | Answer a session's multi-choice QUESTION (promptId from agent:waiting_choice; one answer per question) \u2014 never \`mesh_approve\` for questions |
53480
+ | \`mesh_list_pending_approvals\` | Approval inbox: every session awaiting a decision (read-only) |
53481
+ | \`mesh_plan_onboarding\` | Read-only discovery/dry-run plan before mesh_create/add_node/clone_node |
53482
+ | \`mesh_create\` | Bootstrap a NEW mesh for a repo |
53483
+ | \`mesh_add_node\` | Register an existing checkout as a node (worktrees: use \`mesh_clone_node\`) |
53484
+ | \`mesh_clone_node\` | Create a worktree node for isolated branch work (auto-launches its session) |
53485
+ | \`mesh_refine_node\` | Validate + merge a completed worktree node into its base branch |
53486
+ | \`mesh_refine_batch\` | Converge multiple sibling worktrees in one conflict-aware sequential pipeline |
53487
+ | \`mesh_refine_plan\` | Dry-run Refinery plan (config source, validation, merge intent) |
53488
+ | \`mesh_refine_config\` | Refinery config helper (read-only; mode=schema/validate/suggest) |
53489
+ | \`mesh_change_impact_config\` | Change Impact config helper (read-only; mode=schema/validate/suggest) |
53490
+ | \`mesh_remove_node\` | Remove a node (cleans up its worktree) |
53491
+ | \`mesh_cleanup_worktree_nodes\` | Plan/execute safe removal of CONVERGED worktree nodes (dry-run default) |
53492
+ | \`mesh_cleanup_sessions\` | Clean up delegated session records for a node |
53493
+ | \`mesh_prune_stale_direct\` | Prune orphaned staleDirect dispatch records (dry-run default) |
53494
+ | \`mesh_init\` | Guided onboarding for a fresh repo (dry-run suggest \u2192 gated write) |
53495
+ | \`mesh_reinit\` | Re-onboard a configured repo (diff preview \u2192 per-section approved overwrite) |
53496
+ | \`mesh_write_mesh_json_config\` | Gated write of \`.adhdev/mesh.json\` (coordinator-prompt config) |
53497
+ | \`mesh_magi_review\` | Cross-verify a read-only investigation across an independent agent panel |
53498
+ | \`mesh_magi_collect\` | Collect + synthesize a dispatched MAGI fan-out by consensus group id |
53499
+ | \`mesh_magi_kind_panel_set\` | Bind task_kind \u2192 MAGI panel slots (machine-local; wholesale replace \u2014 approve diff first) |
53500
+ | \`mesh_magi_kind_panel_list\` | List task_kind \u2192 MAGI panel bindings (read-only) |
53501
+ | \`mesh_node_slots_list\` | List a node's capability slots (provider/model/thinking + difficulty + tags) |
53502
+ | \`mesh_node_slots_set\` | Propose (dry-run) or apply a node's slots \u2014 wholesale replace, approve diff before write=true |
53503
+ | \`mesh_node_slots_propose\` | Auto-detect installed CLIs and draft a slot profile (read-only; reports droppedSlots) |
53504
+ | \`mesh_coordinator_prompt_append_get\` | Read this daemon's per-machine coordinator prompt APPEND for a CLI type |
53505
+ | \`mesh_coordinator_prompt_append_set\` | Write/clear that APPEND (append-only; base prompt is not replaceable) |`;
53488
53506
  TOOL_EXPOSURE_PREFLIGHT_SECTION = `## Tool Exposure Preflight
53489
53507
 
53490
53508
  Before doing any coordinator work, confirm that the actual callable tool list includes \`mesh_status\` and the other \`mesh_*\` tools from the table above. If this Repo Mesh coordinator prompt is present but the callable \`mesh_*\` tools are missing, the MCP server/tool manifest is stale or not injected yet. Do not substitute terminal/file/git tools, do not inspect or edit the repository directly, and do not continue as a non-mesh local coding agent. Stop immediately and tell the user to run \`/reload-mcp\` or start a fresh coordinator session so ADHDev can reconnect \`adhdev-mesh\`.`;