@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.js CHANGED
@@ -275,10 +275,10 @@ function readInjected(value) {
275
275
  }
276
276
  function getDaemonBuildInfo() {
277
277
  if (cached) return cached;
278
- const commit = readInjected(true ? "7b5b620e2df42c7c3beb8a2983e3cc076c25f832" : void 0) ?? "unknown";
279
- const commitShort = readInjected(true ? "7b5b620e" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
280
- const version = readInjected(true ? "0.9.82-rc.292" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
281
- const builtAt = readInjected(true ? "2026-06-16T09:16:23.646Z" : void 0);
278
+ const commit = readInjected(true ? "88f97abcc85d83fe5d5313b229d32a7d76b1208a" : void 0) ?? "unknown";
279
+ const commitShort = readInjected(true ? "88f97abc" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
280
+ const version = readInjected(true ? "0.9.82-rc.293" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
281
+ const builtAt = readInjected(true ? "2026-06-16T11:13:51.625Z" : void 0);
282
282
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
283
283
  return cached;
284
284
  }
@@ -349,6 +349,15 @@ async function getGitRepoStatus(workspace, options = {}) {
349
349
  );
350
350
  }
351
351
  }
352
+ function isNonRuntimeRootFile(file) {
353
+ const base = file.slice(file.lastIndexOf("/") + 1);
354
+ if (/^\.(?:verify|marker|converge|ff-verify|patch-equiv|live-verify)\b/i.test(base)) return true;
355
+ if (/(?:^|\/)docs\//i.test(file)) return true;
356
+ if (/^(?:README|CHANGELOG|LICENSE|NOTICE|AUTHORS|CONTRIBUTING|CODEOWNERS)(?:\.[A-Za-z0-9]+)?$/i.test(base)) {
357
+ return true;
358
+ }
359
+ return false;
360
+ }
352
361
  async function classifyDaemonBuildChange(repoPath, buildCommit, options) {
353
362
  try {
354
363
  const diff = await runGit(repoPath, ["diff", "--name-only", `${buildCommit}..HEAD`], options);
@@ -357,18 +366,18 @@ async function classifyDaemonBuildChange(repoPath, buildCommit, options) {
357
366
  return { isDaemonAffecting: true, affectedPackages: [] };
358
367
  }
359
368
  const pkgs = /* @__PURE__ */ new Set();
360
- let sawNonPackageOrUnknown = false;
369
+ let sawRuntimeAmbiguousNonPackage = false;
361
370
  for (const file of files) {
362
371
  const match = file.match(/(?:^|\/)packages\/([^/]+)\//);
363
372
  if (!match) {
364
- sawNonPackageOrUnknown = true;
373
+ if (!isNonRuntimeRootFile(file)) sawRuntimeAmbiguousNonPackage = true;
365
374
  continue;
366
375
  }
367
376
  pkgs.add(match[1]);
368
377
  }
369
378
  const affectedPackages = [...pkgs].sort();
370
- const allWebOnly = !sawNonPackageOrUnknown && affectedPackages.length > 0 && affectedPackages.every((p) => WEB_ONLY_PACKAGES.has(p) && !DAEMON_RUNTIME_PACKAGES.has(p));
371
- return { isDaemonAffecting: !allWebOnly, affectedPackages };
379
+ const allBenign = !sawRuntimeAmbiguousNonPackage && affectedPackages.every((p) => WEB_ONLY_PACKAGES.has(p) && !DAEMON_RUNTIME_PACKAGES.has(p));
380
+ return { isDaemonAffecting: !allBenign, affectedPackages };
372
381
  } catch {
373
382
  return { isDaemonAffecting: true, affectedPackages: [] };
374
383
  }
@@ -395,7 +404,8 @@ async function detectDaemonBuildBehind(repo, submodules, options) {
395
404
  options
396
405
  );
397
406
  const scopeLabel = scope === "root" ? "workspace" : scope;
398
- 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.`;
407
+ const benignDetail = affectedPackages.length > 0 ? `only web packages changed (${affectedPackages.join(", ")})` : "only non-runtime files changed (markers/docs)";
408
+ 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.`;
399
409
  return {
400
410
  buildCommit: build.commit,
401
411
  buildCommitShort: build.commitShort,
@@ -1997,7 +2007,7 @@ function buildRulesSection(coordinatorCliType) {
1997
2007
  - **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.
1998
2008
  - **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.
1999
2009
  - **Verify via git, not source.** Use \`mesh_git_status\` to confirm side effects. Treat agent summaries as self-reports, not verification.
2000
- - **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.
2010
+ - **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).
2001
2011
  - **Check history first.** Call \`mesh_task_history\` at session start to avoid duplicate work and inform recovery. On failure, read task history before retrying.
2002
2012
  - **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\`.
2003
2013
  - **Refinery is config-driven.** \`mesh_refine_node\` must run validation from \`.adhdev/refine.{json,yaml,yml}\` or \`repo-mesh.refine.*\`. Heuristics are scaffolding only.
@@ -2051,7 +2061,7 @@ Before doing any coordinator work, confirm that the actual callable tool list in
2051
2061
  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.
2052
2062
  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.
2053
2063
  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.
2054
- 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\`.
2064
+ 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.
2055
2065
  5. **Verify** \u2014 When a task reports completion or git work is visible, call \`mesh_git_status\` to verify changes were made.
2056
2066
  6. **Checkpoint** \u2014 Call \`mesh_checkpoint\` to save the work.
2057
2067
  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.
@@ -4395,6 +4405,34 @@ var init_mesh_runtime_store = __esm({
4395
4405
  ).get(meshId);
4396
4406
  return row?.cnt ?? 0;
4397
4407
  }
4408
+ /**
4409
+ * Mark specific pending-event rows drained by id (ack). Used by the
4410
+ * unresolved-delegate durable-forward outbox: an event is peeked (not drained)
4411
+ * while its push to the coordinator is unconfirmed, then marked drained ONLY
4412
+ * after the push is acked. A failed push leaves the row undrained so the next
4413
+ * reconcile tick retries it. Returns the number of rows newly marked drained.
4414
+ */
4415
+ markPendingEventsDrainedById(ids) {
4416
+ const idList = ids.filter((id) => typeof id === "string" && id.length > 0);
4417
+ if (idList.length === 0) return 0;
4418
+ const now = Date.now();
4419
+ return this.db.prepare(
4420
+ `UPDATE mesh_pending_events SET drained = 1, drained_at = ? WHERE drained = 0 AND id IN (${idList.map(() => "?").join(",")})`
4421
+ ).run(now, ...idList).changes;
4422
+ }
4423
+ /**
4424
+ * Hard-delete pending-event rows by id (including the dedup fingerprint history).
4425
+ * Used to expire an unresolved-delegate outbox entry that has exhausted its retry
4426
+ * budget — fully removing it frees the fingerprint so a genuinely new completion
4427
+ * for the same task could be re-queued later. Returns the number of rows deleted.
4428
+ */
4429
+ deletePendingEventsById(ids) {
4430
+ const idList = ids.filter((id) => typeof id === "string" && id.length > 0);
4431
+ if (idList.length === 0) return 0;
4432
+ return this.db.prepare(
4433
+ `DELETE FROM mesh_pending_events WHERE id IN (${idList.map(() => "?").join(",")})`
4434
+ ).run(...idList).changes;
4435
+ }
4398
4436
  };
4399
4437
  }
4400
4438
  });
@@ -4402,6 +4440,7 @@ var init_mesh_runtime_store = __esm({
4402
4440
  // src/mesh/mesh-missions.ts
4403
4441
  var mesh_missions_exports = {};
4404
4442
  __export(mesh_missions_exports, {
4443
+ GOAL_PREVIEW_MAX: () => GOAL_PREVIEW_MAX,
4405
4444
  MESH_MISSION_STATUSES: () => MESH_MISSION_STATUSES,
4406
4445
  buildMissionPromptSection: () => buildMissionPromptSection,
4407
4446
  getActiveMeshMissionSummaries: () => getActiveMeshMissionSummaries,
@@ -4473,12 +4512,23 @@ function summarizeMeshMission(meshId, mission) {
4473
4512
  function getActiveMeshMissionSummaries(meshId) {
4474
4513
  return getMeshMissions(meshId, ["active"]).map((mission) => summarizeMeshMission(meshId, mission));
4475
4514
  }
4515
+ function slimMissionSummary(summary) {
4516
+ const goal = typeof summary.goal === "string" ? summary.goal : "";
4517
+ const goalTruncated = goal.length > GOAL_PREVIEW_MAX;
4518
+ const { goal: _omitGoal, ...rest } = summary;
4519
+ return {
4520
+ ...rest,
4521
+ goalPreview: goalTruncated ? goal.slice(0, GOAL_PREVIEW_MAX) : goal,
4522
+ goalTruncated
4523
+ };
4524
+ }
4476
4525
  function getMeshStatusMissionSummaries(meshId, options) {
4477
4526
  const historyLimit = Math.max(0, options?.historyLimit ?? 10);
4478
4527
  const all = getMeshMissions(meshId);
4479
4528
  const live = all.filter((m) => m.status === "active" || m.status === "paused");
4480
4529
  const history = all.filter((m) => m.status === "completed" || m.status === "abandoned").sort((a, b) => (b.updatedAt || "").localeCompare(a.updatedAt || "")).slice(0, historyLimit);
4481
- return [...live, ...history].map((mission) => summarizeMeshMission(meshId, mission));
4530
+ const full = [...live, ...history].map((mission) => summarizeMeshMission(meshId, mission));
4531
+ return options?.verbose ? full : full.map(slimMissionSummary);
4482
4532
  }
4483
4533
  function buildMissionPromptSection(meshId) {
4484
4534
  const summaries = getActiveMeshMissionSummaries(meshId);
@@ -4498,7 +4548,7 @@ function buildMissionPromptSection(meshId) {
4498
4548
  );
4499
4549
  return lines.join("\n");
4500
4550
  }
4501
- var import_crypto6, MESH_MISSION_STATUSES;
4551
+ var import_crypto6, MESH_MISSION_STATUSES, GOAL_PREVIEW_MAX;
4502
4552
  var init_mesh_missions = __esm({
4503
4553
  "src/mesh/mesh-missions.ts"() {
4504
4554
  "use strict";
@@ -4506,6 +4556,7 @@ var init_mesh_missions = __esm({
4506
4556
  init_mesh_runtime_store();
4507
4557
  init_mesh_work_queue();
4508
4558
  MESH_MISSION_STATUSES = ["active", "paused", "completed", "abandoned"];
4559
+ GOAL_PREVIEW_MAX = 120;
4509
4560
  }
4510
4561
  });
4511
4562
 
@@ -7604,6 +7655,111 @@ var init_mesh_routing = __esm({
7604
7655
  }
7605
7656
  });
7606
7657
 
7658
+ // src/mesh/mesh-unresolved-forward-outbox.ts
7659
+ function getStore() {
7660
+ try {
7661
+ return MeshRuntimeStore.getInstance();
7662
+ } catch {
7663
+ return void 0;
7664
+ }
7665
+ }
7666
+ function enqueueUnresolvedDelegateForward(coordinatorDaemonId, eventName, forwardPayload) {
7667
+ const target = readNonEmptyString2(coordinatorDaemonId);
7668
+ const event = readNonEmptyString2(eventName);
7669
+ if (!target || !event) return false;
7670
+ const store = getStore();
7671
+ if (!store) return false;
7672
+ const queuedAt = Date.now();
7673
+ const fingerprintSource = {
7674
+ event,
7675
+ meshId: UNRESOLVED_FORWARD_OUTBOX_MESH_ID,
7676
+ nodeLabel: readNonEmptyString2(forwardPayload.nodeId) || readNonEmptyString2(forwardPayload.workspace) || "unresolved-delegate",
7677
+ nodeId: readNonEmptyString2(forwardPayload.nodeId) || void 0,
7678
+ workspace: readNonEmptyString2(forwardPayload.workspace) || void 0,
7679
+ metadataEvent: forwardPayload,
7680
+ queuedAt,
7681
+ targetCoordinatorDaemonId: target
7682
+ };
7683
+ const fingerprint = `${target}::${buildPendingEventFingerprint(fingerprintSource)}`;
7684
+ try {
7685
+ const inserted = store.insertPendingEvent({
7686
+ id: (0, import_crypto9.randomUUID)(),
7687
+ meshId: UNRESOLVED_FORWARD_OUTBOX_MESH_ID,
7688
+ coordinatorDaemonId: target,
7689
+ event,
7690
+ // Store the flat forward payload + the queue timestamp so the retry tick can
7691
+ // rebuild the push args and apply age-based expiry without a schema change.
7692
+ payload: { forwardPayload, coordinatorDaemonId: target, queuedAt },
7693
+ fingerprint,
7694
+ queuedAt
7695
+ });
7696
+ if (inserted) {
7697
+ LOG.info("MeshEvents", `Durably queued unresolved-delegate ${event} for coordinator ${target} (outbox)`);
7698
+ }
7699
+ return true;
7700
+ } catch (e) {
7701
+ LOG.warn("MeshEvents", `Failed to persist unresolved-delegate forward to outbox: ${e?.message || e}`);
7702
+ return false;
7703
+ }
7704
+ }
7705
+ function peekUnresolvedDelegateForwards() {
7706
+ const store = getStore();
7707
+ if (!store) return [];
7708
+ let rows;
7709
+ try {
7710
+ rows = store.peekPendingEvents(UNRESOLVED_FORWARD_OUTBOX_MESH_ID);
7711
+ } catch {
7712
+ return [];
7713
+ }
7714
+ const out = [];
7715
+ for (const row of rows) {
7716
+ const stored = row.payload && typeof row.payload === "object" ? row.payload : {};
7717
+ const coordinatorDaemonId = readNonEmptyString2(stored.coordinatorDaemonId);
7718
+ const forwardPayload = stored.forwardPayload && typeof stored.forwardPayload === "object" ? stored.forwardPayload : void 0;
7719
+ if (!coordinatorDaemonId || !forwardPayload) continue;
7720
+ const queuedAt = typeof stored.queuedAt === "number" ? stored.queuedAt : 0;
7721
+ out.push({ id: row.id, coordinatorDaemonId, payload: forwardPayload, queuedAt });
7722
+ }
7723
+ return out;
7724
+ }
7725
+ function ackUnresolvedDelegateForward(id) {
7726
+ const store = getStore();
7727
+ if (!store) return;
7728
+ try {
7729
+ store.markPendingEventsDrainedById([id]);
7730
+ } catch {
7731
+ }
7732
+ }
7733
+ function expireStaleUnresolvedDelegateForwards(nowMs = Date.now()) {
7734
+ const entries = peekUnresolvedDelegateForwards();
7735
+ const staleIds = entries.filter((e) => e.queuedAt > 0 && nowMs - e.queuedAt >= UNRESOLVED_FORWARD_MAX_AGE_MS).map((e) => e.id);
7736
+ if (staleIds.length === 0) return 0;
7737
+ const store = getStore();
7738
+ if (!store) return 0;
7739
+ try {
7740
+ const removed = store.deletePendingEventsById(staleIds);
7741
+ if (removed > 0) {
7742
+ 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`);
7743
+ }
7744
+ return removed;
7745
+ } catch {
7746
+ return 0;
7747
+ }
7748
+ }
7749
+ var import_crypto9, UNRESOLVED_FORWARD_OUTBOX_MESH_ID, UNRESOLVED_FORWARD_MAX_AGE_MS;
7750
+ var init_mesh_unresolved_forward_outbox = __esm({
7751
+ "src/mesh/mesh-unresolved-forward-outbox.ts"() {
7752
+ "use strict";
7753
+ import_crypto9 = require("crypto");
7754
+ init_logger();
7755
+ init_mesh_runtime_store();
7756
+ init_mesh_events_pending();
7757
+ init_mesh_events_utils();
7758
+ UNRESOLVED_FORWARD_OUTBOX_MESH_ID = "__unresolved_forward_outbox__";
7759
+ UNRESOLVED_FORWARD_MAX_AGE_MS = 30 * 60 * 1e3;
7760
+ }
7761
+ });
7762
+
7607
7763
  // src/mesh/mesh-events-coordinator.ts
7608
7764
  function resolveCoordinatorDrainDaemonIds(components) {
7609
7765
  const ids = /* @__PURE__ */ new Set();
@@ -8738,12 +8894,25 @@ function forwardUnresolvedDelegateEvent(components, routing, event) {
8738
8894
  nodeId: readNonEmptyString2(routing.nodeId) || readNonEmptyString2(event.meshNodeId) || void 0,
8739
8895
  workspace: readNonEmptyString2(routing.workspace) || readNonEmptyString2(event.workspace) || void 0
8740
8896
  };
8741
- Promise.resolve(components.dispatchMeshCommand(coordinatorDaemonId, "mesh_forward_event", payload)).catch((e) => {
8742
- LOG.warn("MeshEvents", `Fallback forward of ${eventName} to coordinator ${coordinatorDaemonId} failed: ${e?.message || e}`);
8897
+ const persisted = enqueueUnresolvedDelegateForward(coordinatorDaemonId, eventName, payload);
8898
+ Promise.resolve(components.dispatchMeshCommand(coordinatorDaemonId, "mesh_forward_event", payload)).then((result) => {
8899
+ if (result && result.success === false) {
8900
+ LOG.warn("MeshEvents", `Immediate forward of ${eventName} to coordinator ${coordinatorDaemonId} rejected (${readNonEmptyString2(result.error) || "no reason"}) \u2014 left queued for retry`);
8901
+ return;
8902
+ }
8903
+ if (persisted) ackUnresolvedDelegateForwardByFingerprint(coordinatorDaemonId, eventName, payload);
8904
+ }).catch((e) => {
8905
+ LOG.warn("MeshEvents", `Immediate forward of ${eventName} to coordinator ${coordinatorDaemonId} failed: ${e?.message || e} \u2014 left queued for retry`);
8743
8906
  });
8744
- LOG.info("MeshEvents", `Fallback-forwarded ${eventName} for unresolved-mesh worker at ${routing.workspace || "(no workspace)"} to coordinator daemon ${coordinatorDaemonId}`);
8907
+ LOG.info("MeshEvents", `Durably forwarded ${eventName} for unresolved-mesh worker at ${routing.workspace || "(no workspace)"} to coordinator daemon ${coordinatorDaemonId}`);
8745
8908
  return true;
8746
8909
  }
8910
+ function ackUnresolvedDelegateForwardByFingerprint(coordinatorDaemonId, eventName, payload) {
8911
+ const match = peekUnresolvedDelegateForwards().find(
8912
+ (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)
8913
+ );
8914
+ if (match) ackUnresolvedDelegateForward(match.id);
8915
+ }
8747
8916
  function setupMeshEventForwarding(components) {
8748
8917
  components.instanceManager.onEvent((event) => {
8749
8918
  if (event.event === "agent:ready" || event.event === "agent:generating_completed") {
@@ -8825,6 +8994,7 @@ var init_mesh_events_coordinator = __esm({
8825
8994
  init_mesh_runtime_store();
8826
8995
  init_mesh_events_pending();
8827
8996
  init_mesh_routing();
8997
+ init_mesh_unresolved_forward_outbox();
8828
8998
  init_repo_mesh_types();
8829
8999
  init_dist();
8830
9000
  init_mesh_events_stale();
@@ -8940,6 +9110,13 @@ async function runMeshReconcileTick(components) {
8940
9110
  return void 0;
8941
9111
  }
8942
9112
  })();
9113
+ if (dispatchMeshCommand) {
9114
+ try {
9115
+ await retryUnresolvedDelegateForwards(components);
9116
+ } catch (e) {
9117
+ LOG.warn("MeshReconcile", `Unresolved-delegate forward retry failed: ${e?.message || e}`);
9118
+ }
9119
+ }
8943
9120
  if (dispatchMeshCommand) {
8944
9121
  for (const mesh of listMeshes()) {
8945
9122
  const selfIds = resolveCoordinatorSelfIds(mesh, drainDaemonIds);
@@ -8993,6 +9170,28 @@ async function runMeshReconcileTick(components) {
8993
9170
  }
8994
9171
  }
8995
9172
  }
9173
+ async function retryUnresolvedDelegateForwards(components) {
9174
+ const dispatchMeshCommand = components.dispatchMeshCommand;
9175
+ if (!dispatchMeshCommand) return;
9176
+ expireStaleUnresolvedDelegateForwards();
9177
+ const entries = peekUnresolvedDelegateForwards();
9178
+ if (entries.length === 0) return;
9179
+ for (const entry of entries) {
9180
+ let result;
9181
+ try {
9182
+ result = await dispatchMeshCommand(entry.coordinatorDaemonId, "mesh_forward_event", entry.payload);
9183
+ } catch (e) {
9184
+ LOG.warn("MeshReconcile", `Retry forward to coordinator ${entry.coordinatorDaemonId} failed: ${e?.message || e} \u2014 left queued`);
9185
+ continue;
9186
+ }
9187
+ if (result && result.success === false) {
9188
+ LOG.warn("MeshReconcile", `Retry forward to coordinator ${entry.coordinatorDaemonId} rejected (${readNonEmptyString2(result.error) || "no reason"}) \u2014 left queued`);
9189
+ continue;
9190
+ }
9191
+ ackUnresolvedDelegateForward(entry.id);
9192
+ LOG.info("MeshReconcile", `Retried+delivered unresolved-delegate ${readNonEmptyString2(entry.payload.event)} to coordinator ${entry.coordinatorDaemonId}`);
9193
+ }
9194
+ }
8996
9195
  async function pullRemoteNodeQueues(components, mesh, localDaemonId, candidateDaemonIds) {
8997
9196
  const dispatchMeshCommand = components.dispatchMeshCommand;
8998
9197
  if (!dispatchMeshCommand) return;
@@ -9069,6 +9268,7 @@ var init_mesh_reconcile_loop = __esm({
9069
9268
  init_mesh_events_pending();
9070
9269
  init_mesh_runtime_store();
9071
9270
  init_mesh_events_coordinator();
9271
+ init_mesh_unresolved_forward_outbox();
9072
9272
  init_mesh_events_utils();
9073
9273
  DEFAULT_RECONCILE_INTERVAL_MS = 4e3;
9074
9274
  }
@@ -22340,7 +22540,7 @@ var ExtensionProviderInstance = class {
22340
22540
  this.runtimeMessages = [];
22341
22541
  }
22342
22542
  updateSettings(newSettings) {
22343
- this.settings = { ...newSettings };
22543
+ this.settings = { ...this.settings, ...newSettings };
22344
22544
  this.monitor.updateConfig({
22345
22545
  approvalAlert: this.settings.approvalAlert !== false,
22346
22546
  longGeneratingAlert: this.settings.longGeneratingAlert !== false,
@@ -23007,7 +23207,7 @@ var IdeProviderInstance = class {
23007
23207
  this.extensions.clear();
23008
23208
  }
23009
23209
  updateSettings(newSettings) {
23010
- this.settings = { ...newSettings };
23210
+ this.settings = { ...this.settings, ...newSettings };
23011
23211
  this.monitor.updateConfig({
23012
23212
  approvalAlert: this.settings.approvalAlert !== false,
23013
23213
  longGeneratingAlert: this.settings.longGeneratingAlert !== false,
@@ -32555,22 +32755,7 @@ var CliProviderInstance = class _CliProviderInstance {
32555
32755
  };
32556
32756
  }
32557
32757
  updateSettings(newSettings) {
32558
- const runtimeMeshSettings = {};
32559
- for (const key of [
32560
- "meshNodeFor",
32561
- "meshNodeId",
32562
- "meshActiveTaskId",
32563
- "meshCoordinatorFor",
32564
- "meshCoordinatorDaemonId",
32565
- "meshCoordinatorNodeId",
32566
- "spawnedSessionVisibility",
32567
- "launchedByCoordinator"
32568
- ]) {
32569
- if (this.settings[key] !== void 0 && newSettings[key] === void 0) {
32570
- runtimeMeshSettings[key] = this.settings[key];
32571
- }
32572
- }
32573
- this.settings = { ...newSettings, ...runtimeMeshSettings };
32758
+ this.settings = { ...this.settings, ...newSettings };
32574
32759
  this.adapter.updateRuntimeSettings?.(this.settings);
32575
32760
  this.monitor.updateConfig({
32576
32761
  approvalAlert: this.settings.approvalAlert !== false,
@@ -46628,9 +46813,9 @@ ${hintLines.join("\n")}` : "",
46628
46813
  });
46629
46814
  let node;
46630
46815
  if (meshRecord.inline) {
46631
- const { randomUUID: randomUUID14 } = await import("crypto");
46816
+ const { randomUUID: randomUUID15 } = await import("crypto");
46632
46817
  node = {
46633
- id: `node_${randomUUID14().replace(/-/g, "")}`,
46818
+ id: `node_${randomUUID15().replace(/-/g, "")}`,
46634
46819
  workspace: result.worktreePath,
46635
46820
  repoRoot: result.worktreePath,
46636
46821
  daemonId: sourceNode.daemonId,
@@ -47404,10 +47589,11 @@ ${ptyResult.output.slice(-2e3)}`);
47404
47589
  if (!mesh) return { success: false, error: "Mesh not found" };
47405
47590
  const meshHost = resolveMeshHostStatus(mesh);
47406
47591
  const refreshRequested = args?.refresh === true || args?.forceRefresh === true;
47592
+ const verboseMissions = args?.verbose === true || args?.compact === false;
47407
47593
  const peekScope = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
47408
47594
  const pendingCoordinatorEventCount = getPendingMeshCoordinatorEvents(meshId, peekScope).length;
47409
47595
  const hadAggregateCache = this.aggregateMeshStatusCache.has(meshId);
47410
- if (!refreshRequested && pendingCoordinatorEventCount === 0) {
47596
+ if (!refreshRequested && !verboseMissions && pendingCoordinatorEventCount === 0) {
47411
47597
  const cachedStatus = this.getCachedAggregateMeshStatus(meshId, mesh, { requireDirectPeerTruth: args?.requireDirectPeerTruth === true });
47412
47598
  if (cachedStatus) {
47413
47599
  logRepoMeshStatusDebug("return_cached", {
@@ -47710,7 +47896,7 @@ ${ptyResult.output.slice(-2e3)}`);
47710
47896
  liveSessionRecords: liveMeshSessions
47711
47897
  });
47712
47898
  const { getMeshStatusMissionSummaries: getMeshStatusMissionSummaries2 } = await Promise.resolve().then(() => (init_mesh_missions(), mesh_missions_exports));
47713
- const missions = getMeshStatusMissionSummaries2(meshId);
47899
+ const missions = getMeshStatusMissionSummaries2(meshId, { verbose: verboseMissions });
47714
47900
  const statusResult = {
47715
47901
  success: true,
47716
47902
  meshId: mesh.id,
@@ -47764,7 +47950,7 @@ ${ptyResult.output.slice(-2e3)}`);
47764
47950
  }))
47765
47951
  };
47766
47952
  const { pendingCoordinatorEvents: _pendingCoordinatorEvents, unroutableDeliveries: _unroutableDeliveries, ...cacheableStatusResult } = statusResult;
47767
- const rememberedStatus = this.rememberAggregateMeshStatus(meshId, cacheableStatusResult, refreshReason);
47953
+ const rememberedStatus = verboseMissions ? cacheableStatusResult : this.rememberAggregateMeshStatus(meshId, cacheableStatusResult, refreshReason);
47768
47954
  const returnedStatus = {
47769
47955
  ...rememberedStatus,
47770
47956
  ...pendingCoordinatorEvents.length > 0 ? { pendingCoordinatorEvents } : {},
@@ -55318,7 +55504,7 @@ var SessionHostPtyTransportFactory = class {
55318
55504
  };
55319
55505
 
55320
55506
  // src/cli-adapters/raw-terminal-io.ts
55321
- var import_crypto9 = require("crypto");
55507
+ var import_crypto10 = require("crypto");
55322
55508
  var import_session_host_core10 = require("@adhdev/session-host-core");
55323
55509
  var BASE_KEY_SEQUENCES = {
55324
55510
  enter: "\r",
@@ -55416,7 +55602,7 @@ var RawTerminalAttachment = class _RawTerminalAttachment {
55416
55602
  const sessionId = String(options.sessionId || "").trim();
55417
55603
  if (!sessionId) throw new Error("sessionId is required");
55418
55604
  const mode = options.mode || "read";
55419
- const clientId = options.clientId || `raw-terminal-${process.pid}-${(0, import_crypto9.randomUUID)().slice(0, 8)}`;
55605
+ const clientId = options.clientId || `raw-terminal-${process.pid}-${(0, import_crypto10.randomUUID)().slice(0, 8)}`;
55420
55606
  const client = options.client || new import_session_host_core10.SessionHostClient({ endpoint: options.endpoint });
55421
55607
  await client.connect();
55422
55608
  const attachResponse = await client.request({