@adhdev/daemon-core 0.9.82-rc.482 → 0.9.82-rc.483

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.mjs CHANGED
@@ -183,7 +183,7 @@ var init_repo_mesh_types = __esm({
183
183
  "checkpoint_then_continue"
184
184
  ]);
185
185
  MESH_MAX_PARALLEL_TASKS_MIN = 1;
186
- MESH_MAX_PARALLEL_TASKS_MAX = 8;
186
+ MESH_MAX_PARALLEL_TASKS_MAX = 64;
187
187
  DEFAULT_MESH_READONLY_MULTIPLIER = 2;
188
188
  }
189
189
  });
@@ -404,10 +404,10 @@ function readInjected(value) {
404
404
  }
405
405
  function getDaemonBuildInfo() {
406
406
  if (cached) return cached;
407
- const commit = readInjected(true ? "5c311ee659d4fe9b1638a1bb325b681ef6ecc24e" : void 0) ?? "unknown";
408
- const commitShort = readInjected(true ? "5c311ee6" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
409
- const version = readInjected(true ? "0.9.82-rc.482" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
410
- const builtAt = readInjected(true ? "2026-07-08T00:15:56.441Z" : void 0);
407
+ const commit = readInjected(true ? "0862a3f10fa9de60a46591c0894a7209534db2e2" : void 0) ?? "unknown";
408
+ const commitShort = readInjected(true ? "0862a3f1" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
409
+ const version = readInjected(true ? "0.9.82-rc.483" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
410
+ const builtAt = readInjected(true ? "2026-07-08T04:27:00.139Z" : void 0);
411
411
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
412
412
  return cached;
413
413
  }
@@ -3306,6 +3306,11 @@ function updateNode(meshId, nodeId, opts) {
3306
3306
  node.reportedDaemonBuildVersion = opts.reportedDaemonBuildVersion.trim();
3307
3307
  }
3308
3308
  if (opts.policy) node.policy = { ...node.policy, ...opts.policy };
3309
+ if (Object.prototype.hasOwnProperty.call(opts, "capabilities")) {
3310
+ const tags = normalizeCapabilityTags(opts.capabilities);
3311
+ if (tags && tags.length) node.capabilities = tags;
3312
+ else delete node.capabilities;
3313
+ }
3309
3314
  if (opts.worktreeBootstrap) node.worktreeBootstrap = opts.worktreeBootstrap;
3310
3315
  if (Object.prototype.hasOwnProperty.call(opts, "systemPrompt")) {
3311
3316
  if (opts.systemPrompt && opts.systemPrompt.trim()) {
@@ -3598,6 +3603,21 @@ function buildNodeConfigSection(mesh) {
3598
3603
  }).filter(Boolean) : [];
3599
3604
  const providerRolesSuffix = providerRoles.length ? ` | caps: ${providerRoles.join(", ")}` : "";
3600
3605
  lines.push(`- ${explicitLabel} nodeId: \`${n.id}\` | workspace: \`${n.workspace}\`${n.daemonId ? ` | daemon: \`${n.daemonId}\`` : ""}${providerPriority}${providerRolesSuffix}${suffix}`);
3606
+ const routingTags = [];
3607
+ const custom = Array.isArray(n.capabilities) ? n.capabilities : [];
3608
+ for (const t of custom) {
3609
+ const s2 = typeof t === "string" ? t.trim() : "";
3610
+ if (s2) routingTags.push(s2);
3611
+ }
3612
+ const tagOs = (n.userOverrides?.platform || n.reportedPlatform || "").toString().trim();
3613
+ const tagArch = (n.userOverrides?.arch || n.reportedArch || "").toString().trim();
3614
+ if (tagOs) routingTags.push(`os=${tagOs}`);
3615
+ if (tagArch) routingTags.push(`arch=${tagArch}`);
3616
+ const wtBranch = typeof n.worktreeBranch === "string" ? n.worktreeBranch.trim() : "";
3617
+ if (n.isLocalWorktree && wtBranch) routingTags.push(`worktree=${wtBranch}`);
3618
+ if (routingTags.length) {
3619
+ lines.push(` \u{1F3F7}\uFE0F routing tags: ${routingTags.map((t) => `\`${t}\``).join(", ")}`);
3620
+ }
3601
3621
  const nodePrompt = typeof n.systemPrompt === "string" ? n.systemPrompt.trim() : "";
3602
3622
  if (nodePrompt) {
3603
3623
  lines.push(` \u{1F4CC} Node instruction: ${indentFollowing(nodePrompt, " ")}`);
@@ -3699,6 +3719,7 @@ function buildRulesSection(coordinatorCliType) {
3699
3719
  - **Route, don't implement.** Delegate all code reading, analysis, and execution to node agents. Never read source files or run commands in the coordinator \u2014 keep context lean.
3700
3720
  - **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\`.
3701
3721
  - **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 fresh only for independent work, provider mismatch, transcript contamination, or required worktree isolation.
3722
+ - **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 by targeting \`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.
3702
3723
  - **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.
3703
3724
  - **Verify via git, not source.** Use \`mesh_git_status\` to confirm side effects. Treat agent summaries as self-reports, not verification.
3704
3725
  - **Limit parallelism.** Start with 1\u20132 tasks; scale only on success. Never duplicate a session because \`mesh_read_chat\` shows no final message while tool/terminal activity is ongoing. This caps *concurrent* load \u2014 it does not mean serialize independent work: when a new, independent request arrives and there is headroom under \`maxParallelTasks\`, dispatch it right away rather than waiting for an in-flight task or a user nudge (read-only diagnosis especially, since it has no merge cost).
@@ -3785,6 +3806,7 @@ Before doing any coordinator work, confirm that the actual callable tool list in
3785
3806
  3. **Queue / Delegate** \u2014 The Mesh uses an autonomous pull-based Work Queue:
3786
3807
  a. **General Tasks**: Enqueue tasks using \`mesh_enqueue_task\`. Idle node agents will automatically pull tasks from the queue and begin working.
3787
3808
  b. **Node Preparation**: Reuse an existing idle session on the correct node/provider before launching a new chat/session. Call \`mesh_launch_session\` only when no suitable session exists, when the user explicitly asks for a fresh provider/session, or when branch/worktree isolation requires it. If you need branch isolation for parallel work, call \`mesh_clone_node\` to create a worktree node first.
3809
+ b1. **Keep a branch's work on its worktree (worktree affinity).** A worktree node is a durable per-branch workspace, not a one-task throwaway \u2014 implement, review, and fix for the same branch all belong on the SAME worktree, and it lives until its work is converged (merged/pushed) and it is cleaned up. So once you clone a worktree for a branch, route every subsequent \`code_change\`/\`validation\`/fix task for that branch back to that same node: pass \`required_tags: ["worktree=<branch>"]\` or \`target_node_id: <that worktree node's id>\`. **Where to get the node id / tag:** the \`mesh_clone_node\` result returns the new node's \`id\` and \`worktreeBranch\` directly \u2014 use them immediately. The Configured Nodes list in this prompt is a launch-time snapshot and will NOT list a worktree you cloned after this session started, so do not rely on it for freshly-cloned worktrees; take the id/branch from the \`mesh_clone_node\` result, or call \`mesh_status\` to re-list the live nodes (each worktree there advertises its \`worktree=<branch>\` tag). Do NOT leave same-branch follow-ups untargeted \u2014 an untargeted task is claimed by whichever node polls first (usually the base machine node), which strands the work off the branch's worktree. The ONE exception is a \`convergence\` task (merge/push): that is base-only and must NOT be pinned to the worktree.
3788
3810
  c. **Targeted Tasks**: Use \`mesh_send_task\` only when you need to bypass the queue and force a specific node to execute a task immediately.
3789
3811
  d. For the first dispatch of a new task, provide a **complete, self-contained** instruction that includes all context the agent needs (file paths, line numbers, what to change, why). Do not send partial instructions expecting future follow-up.
3790
3812
  e. For a continuation of the same issue in an existing session, send a concise **delta instruction**: current verified state, the exact failed/blocked step, the newly approved action, and final reporting requirements. Do not resend the full original task or open a new chat solely to continue the same work; that wastes coordinator and worker context.
@@ -4234,6 +4256,9 @@ function shouldDeliverPendingEventToCoordinator(event, drainer) {
4234
4256
  if (!event.intendedFor) return false;
4235
4257
  return coordinatorIdentityEquals(event.intendedFor, drainer);
4236
4258
  }
4259
+ function isTerminalTaskEvent(eventName) {
4260
+ return TERMINAL_TASK_EVENTS.has(eventName);
4261
+ }
4237
4262
  function defaultScopeForEvent(eventName) {
4238
4263
  if (TERMINAL_TASK_EVENTS.has(eventName) || COORDINATOR_ALERT_EVENTS.has(eventName)) return "unicast";
4239
4264
  return "broadcast";
@@ -4250,7 +4275,11 @@ function buildPendingEventEmitStamp(opts) {
4250
4275
  let scope = opts.scope ?? defaultScopeForEvent(opts.eventName);
4251
4276
  let intendedFor = opts.intendedFor;
4252
4277
  if (scope === "unicast" && !intendedFor) {
4253
- scope = "broadcast";
4278
+ if (isTerminalTaskEvent(opts.eventName)) {
4279
+ intendedFor = opts.dispatchedBy;
4280
+ } else {
4281
+ scope = "broadcast";
4282
+ }
4254
4283
  }
4255
4284
  if (scope !== "unicast") intendedFor = void 0;
4256
4285
  return {
@@ -8408,6 +8437,16 @@ function routeV2EventsForDrainer(events, drainer, ctx) {
8408
8437
  continue;
8409
8438
  }
8410
8439
  if (validated.scope !== "unicast") {
8440
+ if (validated.scope === "broadcast" && isTerminalTaskEvent(validated.event)) {
8441
+ if (identityDeliversTo(validated.dispatchedBy, drainer)) {
8442
+ ctx.batchSeen.add(eventId);
8443
+ bump("v2Delivered");
8444
+ kept.push(event);
8445
+ } else {
8446
+ bump("v2RoutedAway");
8447
+ }
8448
+ continue;
8449
+ }
8411
8450
  if (shouldDeliverPendingEventToCoordinator(validated, drainer)) {
8412
8451
  ctx.batchSeen.add(eventId);
8413
8452
  bump("v2Delivered");
@@ -39760,6 +39799,53 @@ var statusMetaHandlers = {
39760
39799
 
39761
39800
  // src/commands/low-family/coordinator-prompt.ts
39762
39801
  var coordinatorPromptHandlers = {
39802
+ /**
39803
+ * Render the coordinator system prompt for a mesh + CLI type, so the
39804
+ * dashboard can show the operator exactly what a coordinator session
39805
+ * receives by default. This resolves the mesh, applies its repo-mesh
39806
+ * config, and runs the SAME buildCoordinatorSystemPrompt the launch path
39807
+ * uses — minus the runtime-only best-effort sections (mission / recent
39808
+ * activity / operating notes), which are launch-scope and not part of the
39809
+ * static "default base" an operator is trying to preview here.
39810
+ *
39811
+ * It respects mesh-level and user-file override/append layering, so the
39812
+ * preview reflects the effective prompt: with no overrides configured it
39813
+ * shows the pure daemon default; with an override set it shows that.
39814
+ */
39815
+ coordinator_prompt_preview: async (ctx, args) => {
39816
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
39817
+ const cliType = typeof args?.cliType === "string" && args.cliType.trim() ? args.cliType.trim() : "claude-cli";
39818
+ if (!meshId) return { success: false, error: "meshId required" };
39819
+ try {
39820
+ let mesh = null;
39821
+ if (ctx.getMeshForCommand) {
39822
+ const resolved = await ctx.getMeshForCommand(meshId);
39823
+ mesh = resolved?.mesh ?? null;
39824
+ }
39825
+ if (!mesh) {
39826
+ const { getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
39827
+ mesh = getMesh2(meshId);
39828
+ }
39829
+ if (!mesh) return { success: false, error: `mesh not found: ${meshId}` };
39830
+ let effectiveMesh = mesh;
39831
+ try {
39832
+ const { loadRepoMeshJsonConfig: loadRepoMeshJsonConfig2, applyRepoMeshConfig: applyRepoMeshConfig2 } = await Promise.resolve().then(() => (init_mesh_json_config(), mesh_json_config_exports));
39833
+ const workspace = typeof mesh?.workspace === "string" ? mesh.workspace : void 0;
39834
+ if (workspace) {
39835
+ const loaded = loadRepoMeshJsonConfig2(workspace);
39836
+ if (loaded?.sourceType !== "invalid") {
39837
+ effectiveMesh = applyRepoMeshConfig2(mesh, loaded?.config);
39838
+ }
39839
+ }
39840
+ } catch {
39841
+ }
39842
+ const { buildCoordinatorSystemPrompt: buildCoordinatorSystemPrompt2 } = await Promise.resolve().then(() => (init_coordinator_prompt(), coordinator_prompt_exports));
39843
+ const prompt = buildCoordinatorSystemPrompt2({ mesh: effectiveMesh, coordinatorCliType: cliType });
39844
+ return { success: true, prompt, cliType, meshId, bytes: Buffer.byteLength(prompt, "utf8") };
39845
+ } catch (error) {
39846
+ return { success: false, error: error?.message || String(error) };
39847
+ }
39848
+ },
39763
39849
  list_coordinator_prompts: async (_ctx, _args) => {
39764
39850
  const fs41 = await import("fs");
39765
39851
  const path45 = await import("path");
@@ -54402,13 +54488,15 @@ var meshCrudHandlers = {
54402
54488
  const daemonId = typeof args?.daemonId === "string" && args.daemonId.trim() ? args.daemonId.trim() : void 0;
54403
54489
  const machineId = typeof args?.machineId === "string" && args.machineId.trim() ? args.machineId.trim() : void 0;
54404
54490
  const repoRoot = typeof args?.repoRoot === "string" && args.repoRoot.trim() ? args.repoRoot.trim() : void 0;
54491
+ const capabilities = Array.isArray(args?.capabilities) ? args.capabilities.map((t) => typeof t === "string" ? t.trim() : "").filter(Boolean) : void 0;
54405
54492
  const node = addNode2(meshId, {
54406
54493
  workspace,
54407
54494
  ...repoRoot ? { repoRoot } : {},
54408
54495
  ...daemonId ? { daemonId } : {},
54409
54496
  ...machineId ? { machineId } : {},
54410
54497
  ...policy ? { policy } : {},
54411
- ...role ? { role } : {}
54498
+ ...role ? { role } : {},
54499
+ ...capabilities && capabilities.length ? { capabilities } : {}
54412
54500
  });
54413
54501
  if (!node) return { success: false, error: "Mesh not found" };
54414
54502
  ctx.invalidateAggregateMeshStatus(meshId);
@@ -54450,6 +54538,9 @@ var meshCrudHandlers = {
54450
54538
  } else if (args?.systemPrompt === null) {
54451
54539
  patch.systemPrompt = void 0;
54452
54540
  }
54541
+ if (Array.isArray(args?.capabilities)) {
54542
+ patch.capabilities = args.capabilities.map((t) => typeof t === "string" ? t.trim() : "").filter(Boolean);
54543
+ }
54453
54544
  const node = updateNode2(meshId, nodeId, patch);
54454
54545
  if (!node) return { success: false, error: "Mesh node not found" };
54455
54546
  ctx.invalidateAggregateMeshStatus(meshId);