@adhdev/daemon-core 0.9.82-rc.292 → 0.9.82-rc.293

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
@@ -270,10 +270,10 @@ function readInjected(value) {
270
270
  }
271
271
  function getDaemonBuildInfo() {
272
272
  if (cached) return cached;
273
- const commit = readInjected(true ? "7b5b620e2df42c7c3beb8a2983e3cc076c25f832" : void 0) ?? "unknown";
274
- const commitShort = readInjected(true ? "7b5b620e" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
275
- const version = readInjected(true ? "0.9.82-rc.292" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
276
- const builtAt = readInjected(true ? "2026-06-16T09:16:23.646Z" : void 0);
273
+ const commit = readInjected(true ? "88f97abcc85d83fe5d5313b229d32a7d76b1208a" : void 0) ?? "unknown";
274
+ const commitShort = readInjected(true ? "88f97abc" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
275
+ const version = readInjected(true ? "0.9.82-rc.293" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
276
+ const builtAt = readInjected(true ? "2026-06-16T11:13:51.625Z" : void 0);
277
277
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
278
278
  return cached;
279
279
  }
@@ -344,6 +344,15 @@ async function getGitRepoStatus(workspace, options = {}) {
344
344
  );
345
345
  }
346
346
  }
347
+ function isNonRuntimeRootFile(file) {
348
+ const base = file.slice(file.lastIndexOf("/") + 1);
349
+ if (/^\.(?:verify|marker|converge|ff-verify|patch-equiv|live-verify)\b/i.test(base)) return true;
350
+ if (/(?:^|\/)docs\//i.test(file)) return true;
351
+ if (/^(?:README|CHANGELOG|LICENSE|NOTICE|AUTHORS|CONTRIBUTING|CODEOWNERS)(?:\.[A-Za-z0-9]+)?$/i.test(base)) {
352
+ return true;
353
+ }
354
+ return false;
355
+ }
347
356
  async function classifyDaemonBuildChange(repoPath, buildCommit, options) {
348
357
  try {
349
358
  const diff = await runGit(repoPath, ["diff", "--name-only", `${buildCommit}..HEAD`], options);
@@ -352,18 +361,18 @@ async function classifyDaemonBuildChange(repoPath, buildCommit, options) {
352
361
  return { isDaemonAffecting: true, affectedPackages: [] };
353
362
  }
354
363
  const pkgs = /* @__PURE__ */ new Set();
355
- let sawNonPackageOrUnknown = false;
364
+ let sawRuntimeAmbiguousNonPackage = false;
356
365
  for (const file of files) {
357
366
  const match = file.match(/(?:^|\/)packages\/([^/]+)\//);
358
367
  if (!match) {
359
- sawNonPackageOrUnknown = true;
368
+ if (!isNonRuntimeRootFile(file)) sawRuntimeAmbiguousNonPackage = true;
360
369
  continue;
361
370
  }
362
371
  pkgs.add(match[1]);
363
372
  }
364
373
  const affectedPackages = [...pkgs].sort();
365
- const allWebOnly = !sawNonPackageOrUnknown && affectedPackages.length > 0 && affectedPackages.every((p) => WEB_ONLY_PACKAGES.has(p) && !DAEMON_RUNTIME_PACKAGES.has(p));
366
- return { isDaemonAffecting: !allWebOnly, affectedPackages };
374
+ const allBenign = !sawRuntimeAmbiguousNonPackage && affectedPackages.every((p) => WEB_ONLY_PACKAGES.has(p) && !DAEMON_RUNTIME_PACKAGES.has(p));
375
+ return { isDaemonAffecting: !allBenign, affectedPackages };
367
376
  } catch {
368
377
  return { isDaemonAffecting: true, affectedPackages: [] };
369
378
  }
@@ -390,7 +399,8 @@ async function detectDaemonBuildBehind(repo, submodules, options) {
390
399
  options
391
400
  );
392
401
  const scopeLabel = scope === "root" ? "workspace" : scope;
393
- const warning = isDaemonAffecting ? `Live daemon was built from ${build.commitShort} which is behind ${scopeLabel} HEAD ${head.slice(0, 7)}. Merged code is NOT live until the daemon is rebuilt/redeployed and restarted \u2014 a local dist rebuild alone does not update a cloud daemon.` : `Live daemon was built from ${build.commitShort} which is behind ${scopeLabel} HEAD ${head.slice(0, 7)}, but only web packages changed (${(affectedPackages || []).join(", ") || "web"}). Daemon restart NOT required \u2014 redeploy the web app to reflect the change.`;
402
+ const benignDetail = affectedPackages.length > 0 ? `only web packages changed (${affectedPackages.join(", ")})` : "only non-runtime files changed (markers/docs)";
403
+ const warning = isDaemonAffecting ? `Live daemon was built from ${build.commitShort} which is behind ${scopeLabel} HEAD ${head.slice(0, 7)}. Merged code is NOT live until the daemon is rebuilt/redeployed and restarted \u2014 a local dist rebuild alone does not update a cloud daemon.` : `Live daemon was built from ${build.commitShort} which is behind ${scopeLabel} HEAD ${head.slice(0, 7)}, but ${benignDetail}. Daemon restart NOT required \u2014 redeploy the web app to reflect the change.`;
394
404
  return {
395
405
  buildCommit: build.commit,
396
406
  buildCommitShort: build.commitShort,
@@ -1995,7 +2005,7 @@ function buildRulesSection(coordinatorCliType) {
1995
2005
  - **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.
1996
2006
  - **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.
1997
2007
  - **Verify via git, not source.** Use \`mesh_git_status\` to confirm side effects. Treat agent summaries as self-reports, not verification.
1998
- - **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.
2008
+ - **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).
1999
2009
  - **Check history first.** Call \`mesh_task_history\` at session start to avoid duplicate work and inform recovery. On failure, read task history before retrying.
2000
2010
  - **Converge branches.** After worktree tasks: refine/fast-forward, or classify as \`pushed_feature_branch_needs_merge\` / \`blocked_review\` / \`cleanup_candidate\` / \`not_mergeable\`. Clean up with \`mesh_remove_node\`.
2001
2011
  - **Refinery is config-driven.** \`mesh_refine_node\` must run validation from \`.adhdev/refine.{json,yaml,yml}\` or \`repo-mesh.refine.*\`. Heuristics are scaffolding only.
@@ -2046,7 +2056,7 @@ Before doing any coordinator work, confirm that the actual callable tool list in
2046
2056
  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.
2047
2057
  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.
2048
2058
  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.
2049
- 4. **Monitor** \u2014 Prefer event-driven completion/status notifications. Do **not** poll \`mesh_read_chat\` repeatedly. Do **not** repeatedly call \`mesh_status\` or \`mesh_view_queue\` just to wait for assigned/generating work. After dispatching a direct or queued task, send one progress update with the task/session handle, then stop. Wait for \`pendingCoordinatorEvents\` or another completion/approval/status signal, an explicit user status request, or a real timeout/stall signal before reading status/chat/queue again. Use at most one compact \`mesh_read_chat\` check after a terminal signal. Handle approvals via \`mesh_approve\`.
2059
+ 4. **Monitor** \u2014 Prefer event-driven completion/status notifications. Do **not** poll \`mesh_read_chat\` repeatedly. Do **not** repeatedly call \`mesh_status\` or \`mesh_view_queue\` just to wait for assigned/generating work. After dispatching a direct or queued task, send one progress update with the task/session handle, then stop. Wait for \`pendingCoordinatorEvents\` or another completion/approval/status signal, an explicit user status request, or a real timeout/stall signal before reading status/chat/queue again. Use at most one compact \`mesh_read_chat\` check after a terminal signal. Handle approvals via \`mesh_approve\`. **Proactively parallelize new work.** When the user reports a new bug or asks for new work, start it immediately if it is independent of in-flight tasks and there is headroom under \`maxParallelTasks\` \u2014 do not wait for a current task to finish or for the user to prompt you to parallelize. Read-only diagnosis (\`live_debug_readonly\`) has no isolation or merge cost, so dispatch it in parallel right away. The no-polling / concurrency-limit rules constrain *re-checking or duplicating already-dispatched work*; they are **not** a reason to defer starting a new, independent task.
2050
2060
  5. **Verify** \u2014 When a task reports completion or git work is visible, call \`mesh_git_status\` to verify changes were made.
2051
2061
  6. **Checkpoint** \u2014 Call \`mesh_checkpoint\` to save the work.
2052
2062
  7. **Converge branches** \u2014 Before marking any task complete, classify every touched node/branch into exactly one final state: \`merged_to_main\`, \`pushed_feature_branch_needs_merge\`, \`blocked_review\`, \`cleanup_candidate\`, or \`not_mergeable\`. Use \`mesh_status\` branchConvergenceSummary. For obvious clean branch catch-up (ahead 0, behind > 0, upstream fresh, no dirty/stash/submodule issues), use \`mesh_fast_forward_node\` dry-run first and execute only when explicitly safe/approved; this avoids consuming an agent session. Use \`mesh_refine_node\` for clean worktree branches when safe. Before/refine merging root commits that contain submodule gitlink changes, require each submodule commit to be reachable from the configured submodule remote main branch, not merely present on a feature ref or local checkout. If \`mesh_refine_node\` returns \`submodule_reachability_failed\` or publish-required evidence, keep the public convergence bucket as \`blocked_review\`; unless \`allowAutoPublishSubmoduleMainCommits\` is explicitly enabled and Refinery reports successful non-force publish plus post-publish verification, ask the user for explicit approval to push/publish the unreachable submodule commit(s) to submodule main, then rerun \`mesh_refine_node\`. Do not merge the root branch until the submodule commit(s) are reachable from submodule origin/main. A task that remains on a non-main branch is not fully complete unless the final report names the follow-up state and next step.
@@ -4389,6 +4399,34 @@ var init_mesh_runtime_store = __esm({
4389
4399
  ).get(meshId);
4390
4400
  return row?.cnt ?? 0;
4391
4401
  }
4402
+ /**
4403
+ * Mark specific pending-event rows drained by id (ack). Used by the
4404
+ * unresolved-delegate durable-forward outbox: an event is peeked (not drained)
4405
+ * while its push to the coordinator is unconfirmed, then marked drained ONLY
4406
+ * after the push is acked. A failed push leaves the row undrained so the next
4407
+ * reconcile tick retries it. Returns the number of rows newly marked drained.
4408
+ */
4409
+ markPendingEventsDrainedById(ids) {
4410
+ const idList = ids.filter((id) => typeof id === "string" && id.length > 0);
4411
+ if (idList.length === 0) return 0;
4412
+ const now = Date.now();
4413
+ return this.db.prepare(
4414
+ `UPDATE mesh_pending_events SET drained = 1, drained_at = ? WHERE drained = 0 AND id IN (${idList.map(() => "?").join(",")})`
4415
+ ).run(now, ...idList).changes;
4416
+ }
4417
+ /**
4418
+ * Hard-delete pending-event rows by id (including the dedup fingerprint history).
4419
+ * Used to expire an unresolved-delegate outbox entry that has exhausted its retry
4420
+ * budget — fully removing it frees the fingerprint so a genuinely new completion
4421
+ * for the same task could be re-queued later. Returns the number of rows deleted.
4422
+ */
4423
+ deletePendingEventsById(ids) {
4424
+ const idList = ids.filter((id) => typeof id === "string" && id.length > 0);
4425
+ if (idList.length === 0) return 0;
4426
+ return this.db.prepare(
4427
+ `DELETE FROM mesh_pending_events WHERE id IN (${idList.map(() => "?").join(",")})`
4428
+ ).run(...idList).changes;
4429
+ }
4392
4430
  };
4393
4431
  }
4394
4432
  });
@@ -4396,6 +4434,7 @@ var init_mesh_runtime_store = __esm({
4396
4434
  // src/mesh/mesh-missions.ts
4397
4435
  var mesh_missions_exports = {};
4398
4436
  __export(mesh_missions_exports, {
4437
+ GOAL_PREVIEW_MAX: () => GOAL_PREVIEW_MAX,
4399
4438
  MESH_MISSION_STATUSES: () => MESH_MISSION_STATUSES,
4400
4439
  buildMissionPromptSection: () => buildMissionPromptSection,
4401
4440
  getActiveMeshMissionSummaries: () => getActiveMeshMissionSummaries,
@@ -4468,12 +4507,23 @@ function summarizeMeshMission(meshId, mission) {
4468
4507
  function getActiveMeshMissionSummaries(meshId) {
4469
4508
  return getMeshMissions(meshId, ["active"]).map((mission) => summarizeMeshMission(meshId, mission));
4470
4509
  }
4510
+ function slimMissionSummary(summary) {
4511
+ const goal = typeof summary.goal === "string" ? summary.goal : "";
4512
+ const goalTruncated = goal.length > GOAL_PREVIEW_MAX;
4513
+ const { goal: _omitGoal, ...rest } = summary;
4514
+ return {
4515
+ ...rest,
4516
+ goalPreview: goalTruncated ? goal.slice(0, GOAL_PREVIEW_MAX) : goal,
4517
+ goalTruncated
4518
+ };
4519
+ }
4471
4520
  function getMeshStatusMissionSummaries(meshId, options) {
4472
4521
  const historyLimit = Math.max(0, options?.historyLimit ?? 10);
4473
4522
  const all = getMeshMissions(meshId);
4474
4523
  const live = all.filter((m) => m.status === "active" || m.status === "paused");
4475
4524
  const history = all.filter((m) => m.status === "completed" || m.status === "abandoned").sort((a, b) => (b.updatedAt || "").localeCompare(a.updatedAt || "")).slice(0, historyLimit);
4476
- return [...live, ...history].map((mission) => summarizeMeshMission(meshId, mission));
4525
+ const full = [...live, ...history].map((mission) => summarizeMeshMission(meshId, mission));
4526
+ return options?.verbose ? full : full.map(slimMissionSummary);
4477
4527
  }
4478
4528
  function buildMissionPromptSection(meshId) {
4479
4529
  const summaries = getActiveMeshMissionSummaries(meshId);
@@ -4493,13 +4543,14 @@ function buildMissionPromptSection(meshId) {
4493
4543
  );
4494
4544
  return lines.join("\n");
4495
4545
  }
4496
- var MESH_MISSION_STATUSES;
4546
+ var MESH_MISSION_STATUSES, GOAL_PREVIEW_MAX;
4497
4547
  var init_mesh_missions = __esm({
4498
4548
  "src/mesh/mesh-missions.ts"() {
4499
4549
  "use strict";
4500
4550
  init_mesh_runtime_store();
4501
4551
  init_mesh_work_queue();
4502
4552
  MESH_MISSION_STATUSES = ["active", "paused", "completed", "abandoned"];
4553
+ GOAL_PREVIEW_MAX = 120;
4503
4554
  }
4504
4555
  });
4505
4556
 
@@ -7597,6 +7648,111 @@ var init_mesh_routing = __esm({
7597
7648
  }
7598
7649
  });
7599
7650
 
7651
+ // src/mesh/mesh-unresolved-forward-outbox.ts
7652
+ import { randomUUID as randomUUID9 } from "crypto";
7653
+ function getStore() {
7654
+ try {
7655
+ return MeshRuntimeStore.getInstance();
7656
+ } catch {
7657
+ return void 0;
7658
+ }
7659
+ }
7660
+ function enqueueUnresolvedDelegateForward(coordinatorDaemonId, eventName, forwardPayload) {
7661
+ const target = readNonEmptyString2(coordinatorDaemonId);
7662
+ const event = readNonEmptyString2(eventName);
7663
+ if (!target || !event) return false;
7664
+ const store = getStore();
7665
+ if (!store) return false;
7666
+ const queuedAt = Date.now();
7667
+ const fingerprintSource = {
7668
+ event,
7669
+ meshId: UNRESOLVED_FORWARD_OUTBOX_MESH_ID,
7670
+ nodeLabel: readNonEmptyString2(forwardPayload.nodeId) || readNonEmptyString2(forwardPayload.workspace) || "unresolved-delegate",
7671
+ nodeId: readNonEmptyString2(forwardPayload.nodeId) || void 0,
7672
+ workspace: readNonEmptyString2(forwardPayload.workspace) || void 0,
7673
+ metadataEvent: forwardPayload,
7674
+ queuedAt,
7675
+ targetCoordinatorDaemonId: target
7676
+ };
7677
+ const fingerprint = `${target}::${buildPendingEventFingerprint(fingerprintSource)}`;
7678
+ try {
7679
+ const inserted = store.insertPendingEvent({
7680
+ id: randomUUID9(),
7681
+ meshId: UNRESOLVED_FORWARD_OUTBOX_MESH_ID,
7682
+ coordinatorDaemonId: target,
7683
+ event,
7684
+ // Store the flat forward payload + the queue timestamp so the retry tick can
7685
+ // rebuild the push args and apply age-based expiry without a schema change.
7686
+ payload: { forwardPayload, coordinatorDaemonId: target, queuedAt },
7687
+ fingerprint,
7688
+ queuedAt
7689
+ });
7690
+ if (inserted) {
7691
+ LOG.info("MeshEvents", `Durably queued unresolved-delegate ${event} for coordinator ${target} (outbox)`);
7692
+ }
7693
+ return true;
7694
+ } catch (e) {
7695
+ LOG.warn("MeshEvents", `Failed to persist unresolved-delegate forward to outbox: ${e?.message || e}`);
7696
+ return false;
7697
+ }
7698
+ }
7699
+ function peekUnresolvedDelegateForwards() {
7700
+ const store = getStore();
7701
+ if (!store) return [];
7702
+ let rows;
7703
+ try {
7704
+ rows = store.peekPendingEvents(UNRESOLVED_FORWARD_OUTBOX_MESH_ID);
7705
+ } catch {
7706
+ return [];
7707
+ }
7708
+ const out = [];
7709
+ for (const row of rows) {
7710
+ const stored = row.payload && typeof row.payload === "object" ? row.payload : {};
7711
+ const coordinatorDaemonId = readNonEmptyString2(stored.coordinatorDaemonId);
7712
+ const forwardPayload = stored.forwardPayload && typeof stored.forwardPayload === "object" ? stored.forwardPayload : void 0;
7713
+ if (!coordinatorDaemonId || !forwardPayload) continue;
7714
+ const queuedAt = typeof stored.queuedAt === "number" ? stored.queuedAt : 0;
7715
+ out.push({ id: row.id, coordinatorDaemonId, payload: forwardPayload, queuedAt });
7716
+ }
7717
+ return out;
7718
+ }
7719
+ function ackUnresolvedDelegateForward(id) {
7720
+ const store = getStore();
7721
+ if (!store) return;
7722
+ try {
7723
+ store.markPendingEventsDrainedById([id]);
7724
+ } catch {
7725
+ }
7726
+ }
7727
+ function expireStaleUnresolvedDelegateForwards(nowMs = Date.now()) {
7728
+ const entries = peekUnresolvedDelegateForwards();
7729
+ const staleIds = entries.filter((e) => e.queuedAt > 0 && nowMs - e.queuedAt >= UNRESOLVED_FORWARD_MAX_AGE_MS).map((e) => e.id);
7730
+ if (staleIds.length === 0) return 0;
7731
+ const store = getStore();
7732
+ if (!store) return 0;
7733
+ try {
7734
+ const removed = store.deletePendingEventsById(staleIds);
7735
+ if (removed > 0) {
7736
+ LOG.warn("MeshEvents", `Expired ${removed} unresolved-delegate forward(s) after ${Math.round(UNRESOLVED_FORWARD_MAX_AGE_MS / 6e4)}m of failed retries \u2014 coordinator unreachable, completion dropped`);
7737
+ }
7738
+ return removed;
7739
+ } catch {
7740
+ return 0;
7741
+ }
7742
+ }
7743
+ var UNRESOLVED_FORWARD_OUTBOX_MESH_ID, UNRESOLVED_FORWARD_MAX_AGE_MS;
7744
+ var init_mesh_unresolved_forward_outbox = __esm({
7745
+ "src/mesh/mesh-unresolved-forward-outbox.ts"() {
7746
+ "use strict";
7747
+ init_logger();
7748
+ init_mesh_runtime_store();
7749
+ init_mesh_events_pending();
7750
+ init_mesh_events_utils();
7751
+ UNRESOLVED_FORWARD_OUTBOX_MESH_ID = "__unresolved_forward_outbox__";
7752
+ UNRESOLVED_FORWARD_MAX_AGE_MS = 30 * 60 * 1e3;
7753
+ }
7754
+ });
7755
+
7600
7756
  // src/mesh/mesh-events-coordinator.ts
7601
7757
  import { existsSync as existsSync14 } from "fs";
7602
7758
  function resolveCoordinatorDrainDaemonIds(components) {
@@ -8732,12 +8888,25 @@ function forwardUnresolvedDelegateEvent(components, routing, event) {
8732
8888
  nodeId: readNonEmptyString2(routing.nodeId) || readNonEmptyString2(event.meshNodeId) || void 0,
8733
8889
  workspace: readNonEmptyString2(routing.workspace) || readNonEmptyString2(event.workspace) || void 0
8734
8890
  };
8735
- Promise.resolve(components.dispatchMeshCommand(coordinatorDaemonId, "mesh_forward_event", payload)).catch((e) => {
8736
- LOG.warn("MeshEvents", `Fallback forward of ${eventName} to coordinator ${coordinatorDaemonId} failed: ${e?.message || e}`);
8891
+ const persisted = enqueueUnresolvedDelegateForward(coordinatorDaemonId, eventName, payload);
8892
+ Promise.resolve(components.dispatchMeshCommand(coordinatorDaemonId, "mesh_forward_event", payload)).then((result) => {
8893
+ if (result && result.success === false) {
8894
+ LOG.warn("MeshEvents", `Immediate forward of ${eventName} to coordinator ${coordinatorDaemonId} rejected (${readNonEmptyString2(result.error) || "no reason"}) \u2014 left queued for retry`);
8895
+ return;
8896
+ }
8897
+ if (persisted) ackUnresolvedDelegateForwardByFingerprint(coordinatorDaemonId, eventName, payload);
8898
+ }).catch((e) => {
8899
+ LOG.warn("MeshEvents", `Immediate forward of ${eventName} to coordinator ${coordinatorDaemonId} failed: ${e?.message || e} \u2014 left queued for retry`);
8737
8900
  });
8738
- LOG.info("MeshEvents", `Fallback-forwarded ${eventName} for unresolved-mesh worker at ${routing.workspace || "(no workspace)"} to coordinator daemon ${coordinatorDaemonId}`);
8901
+ LOG.info("MeshEvents", `Durably forwarded ${eventName} for unresolved-mesh worker at ${routing.workspace || "(no workspace)"} to coordinator daemon ${coordinatorDaemonId}`);
8739
8902
  return true;
8740
8903
  }
8904
+ function ackUnresolvedDelegateForwardByFingerprint(coordinatorDaemonId, eventName, payload) {
8905
+ const match = peekUnresolvedDelegateForwards().find(
8906
+ (entry) => entry.coordinatorDaemonId === coordinatorDaemonId && readNonEmptyString2(entry.payload.event) === eventName && readNonEmptyString2(entry.payload.targetSessionId || entry.payload.sessionId || entry.payload.instanceId) === readNonEmptyString2(payload.targetSessionId || payload.sessionId || payload.instanceId) && readNonEmptyString2(entry.payload.workspace) === readNonEmptyString2(payload.workspace)
8907
+ );
8908
+ if (match) ackUnresolvedDelegateForward(match.id);
8909
+ }
8741
8910
  function setupMeshEventForwarding(components) {
8742
8911
  components.instanceManager.onEvent((event) => {
8743
8912
  if (event.event === "agent:ready" || event.event === "agent:generating_completed") {
@@ -8818,6 +8987,7 @@ var init_mesh_events_coordinator = __esm({
8818
8987
  init_mesh_runtime_store();
8819
8988
  init_mesh_events_pending();
8820
8989
  init_mesh_routing();
8990
+ init_mesh_unresolved_forward_outbox();
8821
8991
  init_repo_mesh_types();
8822
8992
  init_dist();
8823
8993
  init_mesh_events_stale();
@@ -8933,6 +9103,13 @@ async function runMeshReconcileTick(components) {
8933
9103
  return void 0;
8934
9104
  }
8935
9105
  })();
9106
+ if (dispatchMeshCommand) {
9107
+ try {
9108
+ await retryUnresolvedDelegateForwards(components);
9109
+ } catch (e) {
9110
+ LOG.warn("MeshReconcile", `Unresolved-delegate forward retry failed: ${e?.message || e}`);
9111
+ }
9112
+ }
8936
9113
  if (dispatchMeshCommand) {
8937
9114
  for (const mesh of listMeshes()) {
8938
9115
  const selfIds = resolveCoordinatorSelfIds(mesh, drainDaemonIds);
@@ -8986,6 +9163,28 @@ async function runMeshReconcileTick(components) {
8986
9163
  }
8987
9164
  }
8988
9165
  }
9166
+ async function retryUnresolvedDelegateForwards(components) {
9167
+ const dispatchMeshCommand = components.dispatchMeshCommand;
9168
+ if (!dispatchMeshCommand) return;
9169
+ expireStaleUnresolvedDelegateForwards();
9170
+ const entries = peekUnresolvedDelegateForwards();
9171
+ if (entries.length === 0) return;
9172
+ for (const entry of entries) {
9173
+ let result;
9174
+ try {
9175
+ result = await dispatchMeshCommand(entry.coordinatorDaemonId, "mesh_forward_event", entry.payload);
9176
+ } catch (e) {
9177
+ LOG.warn("MeshReconcile", `Retry forward to coordinator ${entry.coordinatorDaemonId} failed: ${e?.message || e} \u2014 left queued`);
9178
+ continue;
9179
+ }
9180
+ if (result && result.success === false) {
9181
+ LOG.warn("MeshReconcile", `Retry forward to coordinator ${entry.coordinatorDaemonId} rejected (${readNonEmptyString2(result.error) || "no reason"}) \u2014 left queued`);
9182
+ continue;
9183
+ }
9184
+ ackUnresolvedDelegateForward(entry.id);
9185
+ LOG.info("MeshReconcile", `Retried+delivered unresolved-delegate ${readNonEmptyString2(entry.payload.event)} to coordinator ${entry.coordinatorDaemonId}`);
9186
+ }
9187
+ }
8989
9188
  async function pullRemoteNodeQueues(components, mesh, localDaemonId, candidateDaemonIds) {
8990
9189
  const dispatchMeshCommand = components.dispatchMeshCommand;
8991
9190
  if (!dispatchMeshCommand) return;
@@ -9062,6 +9261,7 @@ var init_mesh_reconcile_loop = __esm({
9062
9261
  init_mesh_events_pending();
9063
9262
  init_mesh_runtime_store();
9064
9263
  init_mesh_events_coordinator();
9264
+ init_mesh_unresolved_forward_outbox();
9065
9265
  init_mesh_events_utils();
9066
9266
  DEFAULT_RECONCILE_INTERVAL_MS = 4e3;
9067
9267
  }
@@ -21999,7 +22199,7 @@ var ExtensionProviderInstance = class {
21999
22199
  this.runtimeMessages = [];
22000
22200
  }
22001
22201
  updateSettings(newSettings) {
22002
- this.settings = { ...newSettings };
22202
+ this.settings = { ...this.settings, ...newSettings };
22003
22203
  this.monitor.updateConfig({
22004
22204
  approvalAlert: this.settings.approvalAlert !== false,
22005
22205
  longGeneratingAlert: this.settings.longGeneratingAlert !== false,
@@ -22666,7 +22866,7 @@ var IdeProviderInstance = class {
22666
22866
  this.extensions.clear();
22667
22867
  }
22668
22868
  updateSettings(newSettings) {
22669
- this.settings = { ...newSettings };
22869
+ this.settings = { ...this.settings, ...newSettings };
22670
22870
  this.monitor.updateConfig({
22671
22871
  approvalAlert: this.settings.approvalAlert !== false,
22672
22872
  longGeneratingAlert: this.settings.longGeneratingAlert !== false,
@@ -24145,7 +24345,7 @@ function resolveLegacyProviderScript(fn, scriptName, params) {
24145
24345
  import * as fs6 from "fs";
24146
24346
  import * as os8 from "os";
24147
24347
  import * as path13 from "path";
24148
- import { randomUUID as randomUUID10 } from "crypto";
24348
+ import { randomUUID as randomUUID11 } from "crypto";
24149
24349
  init_logger();
24150
24350
 
24151
24351
  // src/logging/debug-trace.ts
@@ -25686,7 +25886,7 @@ function safeBundleIdSegment(value, fallback) {
25686
25886
  function createChatDebugBundleId(targetSessionId) {
25687
25887
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:.]/g, "").replace("T", "T").replace("Z", "Z");
25688
25888
  const sessionSegment = safeBundleIdSegment(targetSessionId, "unknown-session");
25689
- return `chat-debug-${timestamp}-${sessionSegment}-${randomUUID10().slice(0, 8)}`;
25889
+ return `chat-debug-${timestamp}-${sessionSegment}-${randomUUID11().slice(0, 8)}`;
25690
25890
  }
25691
25891
  function buildChatDebugBundleSummary(bundle) {
25692
25892
  const target = bundle.target && typeof bundle.target === "object" ? bundle.target : {};
@@ -32214,22 +32414,7 @@ var CliProviderInstance = class _CliProviderInstance {
32214
32414
  };
32215
32415
  }
32216
32416
  updateSettings(newSettings) {
32217
- const runtimeMeshSettings = {};
32218
- for (const key of [
32219
- "meshNodeFor",
32220
- "meshNodeId",
32221
- "meshActiveTaskId",
32222
- "meshCoordinatorFor",
32223
- "meshCoordinatorDaemonId",
32224
- "meshCoordinatorNodeId",
32225
- "spawnedSessionVisibility",
32226
- "launchedByCoordinator"
32227
- ]) {
32228
- if (this.settings[key] !== void 0 && newSettings[key] === void 0) {
32229
- runtimeMeshSettings[key] = this.settings[key];
32230
- }
32231
- }
32232
- this.settings = { ...newSettings, ...runtimeMeshSettings };
32417
+ this.settings = { ...this.settings, ...newSettings };
32233
32418
  this.adapter.updateRuntimeSettings?.(this.settings);
32234
32419
  this.monitor.updateConfig({
32235
32420
  approvalAlert: this.settings.approvalAlert !== false,
@@ -46292,9 +46477,9 @@ ${hintLines.join("\n")}` : "",
46292
46477
  });
46293
46478
  let node;
46294
46479
  if (meshRecord.inline) {
46295
- const { randomUUID: randomUUID14 } = await import("crypto");
46480
+ const { randomUUID: randomUUID15 } = await import("crypto");
46296
46481
  node = {
46297
- id: `node_${randomUUID14().replace(/-/g, "")}`,
46482
+ id: `node_${randomUUID15().replace(/-/g, "")}`,
46298
46483
  workspace: result.worktreePath,
46299
46484
  repoRoot: result.worktreePath,
46300
46485
  daemonId: sourceNode.daemonId,
@@ -47068,10 +47253,11 @@ ${ptyResult.output.slice(-2e3)}`);
47068
47253
  if (!mesh) return { success: false, error: "Mesh not found" };
47069
47254
  const meshHost = resolveMeshHostStatus(mesh);
47070
47255
  const refreshRequested = args?.refresh === true || args?.forceRefresh === true;
47256
+ const verboseMissions = args?.verbose === true || args?.compact === false;
47071
47257
  const peekScope = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
47072
47258
  const pendingCoordinatorEventCount = getPendingMeshCoordinatorEvents(meshId, peekScope).length;
47073
47259
  const hadAggregateCache = this.aggregateMeshStatusCache.has(meshId);
47074
- if (!refreshRequested && pendingCoordinatorEventCount === 0) {
47260
+ if (!refreshRequested && !verboseMissions && pendingCoordinatorEventCount === 0) {
47075
47261
  const cachedStatus = this.getCachedAggregateMeshStatus(meshId, mesh, { requireDirectPeerTruth: args?.requireDirectPeerTruth === true });
47076
47262
  if (cachedStatus) {
47077
47263
  logRepoMeshStatusDebug("return_cached", {
@@ -47374,7 +47560,7 @@ ${ptyResult.output.slice(-2e3)}`);
47374
47560
  liveSessionRecords: liveMeshSessions
47375
47561
  });
47376
47562
  const { getMeshStatusMissionSummaries: getMeshStatusMissionSummaries2 } = await Promise.resolve().then(() => (init_mesh_missions(), mesh_missions_exports));
47377
- const missions = getMeshStatusMissionSummaries2(meshId);
47563
+ const missions = getMeshStatusMissionSummaries2(meshId, { verbose: verboseMissions });
47378
47564
  const statusResult = {
47379
47565
  success: true,
47380
47566
  meshId: mesh.id,
@@ -47428,7 +47614,7 @@ ${ptyResult.output.slice(-2e3)}`);
47428
47614
  }))
47429
47615
  };
47430
47616
  const { pendingCoordinatorEvents: _pendingCoordinatorEvents, unroutableDeliveries: _unroutableDeliveries, ...cacheableStatusResult } = statusResult;
47431
- const rememberedStatus = this.rememberAggregateMeshStatus(meshId, cacheableStatusResult, refreshReason);
47617
+ const rememberedStatus = verboseMissions ? cacheableStatusResult : this.rememberAggregateMeshStatus(meshId, cacheableStatusResult, refreshReason);
47432
47618
  const returnedStatus = {
47433
47619
  ...rememberedStatus,
47434
47620
  ...pendingCoordinatorEvents.length > 0 ? { pendingCoordinatorEvents } : {},
@@ -54984,7 +55170,7 @@ var SessionHostPtyTransportFactory = class {
54984
55170
  };
54985
55171
 
54986
55172
  // src/cli-adapters/raw-terminal-io.ts
54987
- import { randomUUID as randomUUID13 } from "crypto";
55173
+ import { randomUUID as randomUUID14 } from "crypto";
54988
55174
  import {
54989
55175
  SessionHostClient as SessionHostClient2
54990
55176
  } from "@adhdev/session-host-core";
@@ -55084,7 +55270,7 @@ var RawTerminalAttachment = class _RawTerminalAttachment {
55084
55270
  const sessionId = String(options.sessionId || "").trim();
55085
55271
  if (!sessionId) throw new Error("sessionId is required");
55086
55272
  const mode = options.mode || "read";
55087
- const clientId = options.clientId || `raw-terminal-${process.pid}-${randomUUID13().slice(0, 8)}`;
55273
+ const clientId = options.clientId || `raw-terminal-${process.pid}-${randomUUID14().slice(0, 8)}`;
55088
55274
  const client = options.client || new SessionHostClient2({ endpoint: options.endpoint });
55089
55275
  await client.connect();
55090
55276
  const attachResponse = await client.request({