@adhdev/daemon-core 0.9.82-rc.291 → 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 ? "396cb9c4084ea658cd3606b76948987cd875f138" : void 0) ?? "unknown";
274
- const commitShort = readInjected(true ? "396cb9c4" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
275
- const version = readInjected(true ? "0.9.82-rc.291" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
276
- const builtAt = readInjected(true ? "2026-06-16T06:42:37.821Z" : 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
 
@@ -6178,11 +6229,225 @@ var init_mesh_fast_forward = __esm({
6178
6229
  }
6179
6230
  });
6180
6231
 
6232
+ // ../mesh-shared/dist/index.mjs
6233
+ function readRecord3(value) {
6234
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
6235
+ }
6236
+ function readString5(...values) {
6237
+ for (const value of values) {
6238
+ if (typeof value !== "string") continue;
6239
+ const trimmed = value.trim();
6240
+ if (trimmed) return trimmed;
6241
+ }
6242
+ return void 0;
6243
+ }
6244
+ function readNumber(...values) {
6245
+ for (const value of values) {
6246
+ if (typeof value === "number" && Number.isFinite(value)) return value;
6247
+ }
6248
+ return void 0;
6249
+ }
6250
+ function readBoolean(...values) {
6251
+ for (const value of values) {
6252
+ if (typeof value === "boolean") return value;
6253
+ }
6254
+ return void 0;
6255
+ }
6256
+ function joinRepoPath(root, relativePath) {
6257
+ const normalizedRoot = typeof root === "string" ? root.trim().replace(/[\\/]+$/, "") : "";
6258
+ const normalizedPath = typeof relativePath === "string" ? relativePath.trim() : "";
6259
+ if (!normalizedPath) return void 0;
6260
+ if (/^(?:[A-Za-z]:[\\/]|\/)/.test(normalizedPath)) return normalizedPath;
6261
+ if (!normalizedRoot) return void 0;
6262
+ return `${normalizedRoot}/${normalizedPath.replace(/^[\\/]+/, "")}`;
6263
+ }
6264
+ function scoreGitUpstreamFreshness(status) {
6265
+ switch (status) {
6266
+ case "fresh":
6267
+ return 30;
6268
+ case "no_upstream":
6269
+ return 4;
6270
+ case "unchecked":
6271
+ case void 0:
6272
+ return 0;
6273
+ case "stale":
6274
+ return -10;
6275
+ case "unavailable":
6276
+ return -15;
6277
+ default:
6278
+ return 0;
6279
+ }
6280
+ }
6281
+ function readGitSubmodules(value, parentRepoRoot) {
6282
+ if (!Array.isArray(value)) return void 0;
6283
+ const submodules = value.map((entry) => {
6284
+ const submodule = readRecord3(entry);
6285
+ const path40 = readString5(submodule.path);
6286
+ const commit = readString5(submodule.commit);
6287
+ const repoPath = readString5(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot, path40);
6288
+ if (!path40 || !commit) return null;
6289
+ const result = {
6290
+ path: path40,
6291
+ commit,
6292
+ dirty: readBoolean(submodule.dirty) ?? false,
6293
+ outOfSync: readBoolean(submodule.outOfSync, submodule.out_of_sync) ?? false,
6294
+ lastCheckedAt: readNumber(submodule.lastCheckedAt, submodule.last_checked_at) ?? Date.now()
6295
+ };
6296
+ if (repoPath) result.repoPath = repoPath;
6297
+ const error = readString5(submodule.error);
6298
+ if (error) result.error = error;
6299
+ return result;
6300
+ }).filter((entry) => entry !== null);
6301
+ return submodules.length > 0 ? submodules : void 0;
6302
+ }
6303
+ function hasGitStatusEvidence(status) {
6304
+ return readBoolean(status.isGitRepo) !== void 0 || Boolean(readString5(status.branch, status.upstream, status.upstreamStatus, status.upstream_status, status.headCommit)) || Boolean(readString5(status.repoRoot, status.repo_root, status.workspace)) || readNumber(
6305
+ status.ahead,
6306
+ status.behind,
6307
+ status.staged,
6308
+ status.modified,
6309
+ status.untracked,
6310
+ status.deleted,
6311
+ status.renamed,
6312
+ status.lastCheckedAt,
6313
+ status.last_checked_at
6314
+ ) !== void 0 || Array.isArray(status.submodules) && status.submodules.length > 0;
6315
+ }
6316
+ function normalizeGitStatus(status, node, options) {
6317
+ const explicitIsGitRepo = readBoolean(status.isGitRepo);
6318
+ if (!Object.keys(status).length || !hasGitStatusEvidence(status)) return void 0;
6319
+ const isGitRepo = explicitIsGitRepo ?? true;
6320
+ const conflictFiles = Array.isArray(status.conflictFiles) ? status.conflictFiles.filter((entry) => typeof entry === "string") : [];
6321
+ const conflictCount = readNumber(status.conflicts) ?? conflictFiles.length;
6322
+ const hasConflicts = readBoolean(status.hasConflicts) ?? conflictCount > 0;
6323
+ const repoRoot = readString5(status.repoRoot, status.repo_root, node.repoRoot, node.repo_root, status.workspace, node.workspace) || void 0;
6324
+ const submodules = readGitSubmodules(status.submodules, repoRoot);
6325
+ const upstreamStatus = readString5(status.upstreamStatus, status.upstream_status);
6326
+ const upstreamFetchedAt = readNumber(status.upstreamFetchedAt, status.upstream_fetched_at);
6327
+ const upstreamFetchError = readString5(status.upstreamFetchError, status.upstream_fetch_error);
6328
+ const error = readString5(status.error);
6329
+ const staged = readNumber(status.staged) ?? 0;
6330
+ const modified = readNumber(status.modified) ?? 0;
6331
+ const untracked = readNumber(status.untracked) ?? 0;
6332
+ const deleted = readNumber(status.deleted) ?? 0;
6333
+ const renamed = readNumber(status.renamed) ?? 0;
6334
+ return {
6335
+ workspace: readString5(status.workspace, node.workspace) || "",
6336
+ repoRoot: repoRoot ?? null,
6337
+ isGitRepo,
6338
+ branch: readString5(status.branch) ?? null,
6339
+ headCommit: readString5(status.headCommit) ?? null,
6340
+ headMessage: readString5(status.headMessage) ?? null,
6341
+ upstream: readString5(status.upstream) ?? null,
6342
+ upstreamStatus: upstreamStatus ?? "unchecked",
6343
+ ...upstreamFetchedAt !== void 0 ? { upstreamFetchedAt } : {},
6344
+ ...upstreamFetchError ? { upstreamFetchError } : {},
6345
+ ahead: readNumber(status.ahead) ?? 0,
6346
+ behind: readNumber(status.behind) ?? 0,
6347
+ staged,
6348
+ modified,
6349
+ untracked,
6350
+ deleted,
6351
+ renamed,
6352
+ dirty: readBoolean(status.dirty, status.isDirty, status.is_dirty) ?? (staged + modified + untracked + deleted + renamed > 0 || hasConflicts),
6353
+ hasConflicts,
6354
+ conflictFiles,
6355
+ stashCount: readNumber(status.stashCount, status.stash_count) ?? 0,
6356
+ lastCheckedAt: options?.lastCheckedAt ?? readNumber(status.lastCheckedAt, status.last_checked_at) ?? Date.now(),
6357
+ ...submodules ? { submodules } : {},
6358
+ ...error ? { error } : {}
6359
+ };
6360
+ }
6361
+ function scoreGitStatusCandidate(git) {
6362
+ if (!git) return Number.NEGATIVE_INFINITY;
6363
+ let score = 0;
6364
+ if (git.isGitRepo === true) score += 50;
6365
+ if (git.isGitRepo === false) score -= 10;
6366
+ if (git.branch) score += 20;
6367
+ if (git.headCommit) score += 20;
6368
+ if (git.upstream) score += 10;
6369
+ score += scoreGitUpstreamFreshness(git.upstreamStatus);
6370
+ if (typeof git.ahead === "number") score += 2;
6371
+ if (typeof git.behind === "number") score += 2;
6372
+ if (Array.isArray(git.submodules) && git.submodules.length > 0) score += 4 + git.submodules.length;
6373
+ if (git.error) score -= 20;
6374
+ return score;
6375
+ }
6376
+ function pickBestTransitGitStatus(node, options) {
6377
+ const rawGit = readRecord3(node.lastGit ?? node.last_git);
6378
+ const gitResult = readRecord3(rawGit.result);
6379
+ const directStatus = readRecord3(rawGit.status);
6380
+ const nestedStatus = readRecord3(gitResult.status);
6381
+ const rawProbe = readRecord3(node.lastProbe ?? node.last_probe);
6382
+ const probeGit = readRecord3(rawProbe.git);
6383
+ const probeGitResult = readRecord3(probeGit.result);
6384
+ const probeDirectStatus = readRecord3(probeGit.status);
6385
+ const probeNestedStatus = readRecord3(probeGitResult.status);
6386
+ const lastCheckedAt = options?.lastCheckedAt;
6387
+ let best = null;
6388
+ for (const status of [directStatus, nestedStatus, probeDirectStatus, probeNestedStatus]) {
6389
+ const normalized = normalizeGitStatus(status, node, { lastCheckedAt: lastCheckedAt ?? Date.now() });
6390
+ if (!normalized) continue;
6391
+ const score = scoreGitStatusCandidate(normalized);
6392
+ if (!best || score > best.score) best = { git: normalized, score };
6393
+ }
6394
+ return best?.git;
6395
+ }
6396
+ function normalizeMeshNodeId(node) {
6397
+ const record = node && typeof node === "object" ? node : {};
6398
+ return readString5(record.id, record.nodeId, record.node_id);
6399
+ }
6400
+ function meshNodeIdMatches(node, candidateId) {
6401
+ if (!candidateId) return false;
6402
+ const trimmed = candidateId.trim();
6403
+ if (!trimmed) return false;
6404
+ return normalizeMeshNodeId(node) === trimmed;
6405
+ }
6406
+ function summarizeGitShape(status) {
6407
+ const record = readRecord3(status);
6408
+ if (!Object.keys(record).length) return null;
6409
+ const submodules = Array.isArray(record.submodules) ? record.submodules.map((entry) => {
6410
+ const sub = readRecord3(entry);
6411
+ return {
6412
+ path: readString5(sub.path) ?? null,
6413
+ commit: readString5(sub.commit)?.slice(0, 12) ?? null,
6414
+ dirty: readBoolean(sub.dirty) ?? false,
6415
+ outOfSync: readBoolean(sub.outOfSync, sub.out_of_sync) ?? false
6416
+ };
6417
+ }) : [];
6418
+ return {
6419
+ isGitRepo: readBoolean(record.isGitRepo),
6420
+ workspace: readString5(record.workspace) ?? null,
6421
+ repoRoot: readString5(record.repoRoot, record.repo_root) ?? null,
6422
+ branch: readString5(record.branch) ?? null,
6423
+ upstream: readString5(record.upstream) ?? null,
6424
+ upstreamStatus: readString5(record.upstreamStatus, record.upstream_status) ?? null,
6425
+ headCommit: readString5(record.headCommit, record.head_commit)?.slice(0, 12) ?? null,
6426
+ ahead: readNumber(record.ahead) ?? null,
6427
+ behind: readNumber(record.behind) ?? null,
6428
+ dirtyCounts: {
6429
+ staged: readNumber(record.staged) ?? 0,
6430
+ modified: readNumber(record.modified) ?? 0,
6431
+ untracked: readNumber(record.untracked) ?? 0,
6432
+ deleted: readNumber(record.deleted) ?? 0,
6433
+ renamed: readNumber(record.renamed) ?? 0
6434
+ },
6435
+ lastCheckedAt: readNumber(record.lastCheckedAt, record.last_checked_at) ?? null,
6436
+ submoduleCount: submodules.length,
6437
+ submodules
6438
+ };
6439
+ }
6440
+ var init_dist = __esm({
6441
+ "../mesh-shared/dist/index.mjs"() {
6442
+ "use strict";
6443
+ }
6444
+ });
6445
+
6181
6446
  // src/mesh/mesh-events-utils.ts
6182
6447
  function readNonEmptyString2(value) {
6183
6448
  return typeof value === "string" && value.trim() ? value.trim() : "";
6184
6449
  }
6185
- function readRecord3(value) {
6450
+ function readRecord4(value) {
6186
6451
  return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
6187
6452
  }
6188
6453
  function buildMeshWorkerRelayStamp(currentSettings, meshContext) {
@@ -6206,13 +6471,13 @@ function resolveEventSessionId(event, fallback) {
6206
6471
  return readNonEmptyString2(event.targetSessionId) || readNonEmptyString2(event.sessionId) || readNonEmptyString2(event.instanceId) || readNonEmptyString2(fallback);
6207
6472
  }
6208
6473
  function readRefineJobId(event) {
6209
- const metadata = readRecord3(event.metadataEvent) || event;
6210
- const result = readRecord3(metadata.result);
6211
- const refineJob = readRecord3(result?.refineJob);
6474
+ const metadata = readRecord4(event.metadataEvent) || event;
6475
+ const result = readRecord4(metadata.result);
6476
+ const refineJob = readRecord4(result?.refineJob);
6212
6477
  return readNonEmptyString2(metadata.jobId) || readNonEmptyString2(refineJob?.jobId);
6213
6478
  }
6214
6479
  function readWorkerResultMetadata(event) {
6215
- return readRecord3(event.workerResult) || readRecord3(event.meshWorkerResult) || readRecord3(event.structuredResult);
6480
+ return readRecord4(event.workerResult) || readRecord4(event.meshWorkerResult) || readRecord4(event.structuredResult);
6216
6481
  }
6217
6482
  function formatCompletionMetadata(event) {
6218
6483
  const completionDiagnostic = event.completionDiagnostic && typeof event.completionDiagnostic === "object" ? event.completionDiagnostic : null;
@@ -6290,10 +6555,10 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
6290
6555
  }
6291
6556
  if (args.event === "refine:completed") {
6292
6557
  const jobId = readRefineJobId({ metadataEvent: args.metadataEvent });
6293
- const result = readRecord3(args.metadataEvent.result);
6294
- const validationSummary = readRecord3(result?.validationSummary);
6295
- const patchEquivalence = readRecord3(result?.patchEquivalence);
6296
- const finalConvergence = readRecord3(result?.finalBranchConvergenceState);
6558
+ const result = readRecord4(args.metadataEvent.result);
6559
+ const validationSummary = readRecord4(result?.validationSummary);
6560
+ const patchEquivalence = readRecord4(result?.patchEquivalence);
6561
+ const finalConvergence = readRecord4(result?.finalBranchConvergenceState);
6297
6562
  const validationStatus = readNonEmptyString2(validationSummary?.status);
6298
6563
  const patchStatus = readNonEmptyString2(patchEquivalence?.status) || (patchEquivalence?.equivalent === true ? "passed" : "");
6299
6564
  const into = readNonEmptyString2(result?.into);
@@ -6314,10 +6579,10 @@ Next step: ${nextStep}`;
6314
6579
  }
6315
6580
  if (args.event === "refine:failed") {
6316
6581
  const jobId = readRefineJobId({ metadataEvent: args.metadataEvent });
6317
- const result = readRecord3(args.metadataEvent.result);
6318
- const validationSummary = readRecord3(result?.validationSummary);
6319
- const patchEquivalence = readRecord3(result?.patchEquivalence);
6320
- const finalConvergence = readRecord3(result?.finalBranchConvergenceState);
6582
+ const result = readRecord4(args.metadataEvent.result);
6583
+ const validationSummary = readRecord4(result?.validationSummary);
6584
+ const patchEquivalence = readRecord4(result?.patchEquivalence);
6585
+ const finalConvergence = readRecord4(result?.finalBranchConvergenceState);
6321
6586
  const code = readNonEmptyString2(result?.code);
6322
6587
  const error = readNonEmptyString2(result?.error);
6323
6588
  const validationStatus = readNonEmptyString2(validationSummary?.status);
@@ -6367,9 +6632,9 @@ function normalizeCoordinatorDaemonIds(coordinatorDaemonId) {
6367
6632
  return out;
6368
6633
  }
6369
6634
  function readRefineJobId2(event) {
6370
- const metadata = readRecord3(event.metadataEvent) || event;
6371
- const result = readRecord3(metadata.result);
6372
- const refineJob = readRecord3(result?.refineJob);
6635
+ const metadata = readRecord4(event.metadataEvent) || event;
6636
+ const result = readRecord4(metadata.result);
6637
+ const refineJob = readRecord4(result?.refineJob);
6373
6638
  return readNonEmptyString2(metadata.jobId) || readNonEmptyString2(refineJob?.jobId);
6374
6639
  }
6375
6640
  function hasPendingRefineTerminalEventDuplicate(event) {
@@ -6381,13 +6646,13 @@ function hasPendingRefineTerminalEventDuplicate(event) {
6381
6646
  );
6382
6647
  }
6383
6648
  function buildPendingEventFingerprint(event) {
6384
- const metadata = readRecord3(event.metadataEvent) || {};
6649
+ const metadata = readRecord4(event.metadataEvent) || {};
6385
6650
  if (event.event === "worktree_bootstrap_complete" || event.event === "worktree_bootstrap_failed") {
6386
6651
  return [event.meshId, event.event, event.nodeId || ""].join("::");
6387
6652
  }
6388
6653
  const sessionId = resolveEventSessionId(metadata);
6389
6654
  const providerSessionId = readNonEmptyString2(metadata.providerSessionId);
6390
- const taskId = readNonEmptyString2(metadata.taskId) || readNonEmptyString2(readRecord3(metadata.payload)?.taskId);
6655
+ const taskId = readNonEmptyString2(metadata.taskId) || readNonEmptyString2(readRecord4(metadata.payload)?.taskId);
6391
6656
  const jobId = readRefineJobId2(event);
6392
6657
  const timestamp = metadata.timestamp !== void 0 && metadata.timestamp !== null ? String(metadata.timestamp) : "";
6393
6658
  return [
@@ -6455,15 +6720,15 @@ function refineTerminalEventFromLedger(meshId, pending) {
6455
6720
  for (let i = entries.length - 1; i >= 0; i--) {
6456
6721
  const entry = entries[i];
6457
6722
  if (entry.kind !== "task_completed" && entry.kind !== "task_failed") continue;
6458
- const payload = readRecord3(entry.payload);
6723
+ const payload = readRecord4(entry.payload);
6459
6724
  if (payload?.source !== "refine_mesh_node_async_job") continue;
6460
- const refineJob = readRecord3(payload.refineJob);
6725
+ const refineJob = readRecord4(payload.refineJob);
6461
6726
  const jobId = readNonEmptyString2(refineJob?.jobId);
6462
6727
  if (!jobId || !acceptedJobIds.has(jobId)) continue;
6463
6728
  const eventName = entry.kind === "task_completed" ? "refine:completed" : "refine:failed";
6464
6729
  if (existingTerminalJobIds.has(`${eventName}:${jobId}`)) continue;
6465
6730
  existingTerminalJobIds.add(`${eventName}:${jobId}`);
6466
- const result = readRecord3(payload.result);
6731
+ const result = readRecord4(payload.result);
6467
6732
  const metadataEvent = {
6468
6733
  source: "refine_mesh_node_async_job",
6469
6734
  jobId,
@@ -7068,7 +7333,7 @@ function buildLongGeneratingCompletionReconciliation(args) {
7068
7333
  const providerType = readNonEmptyString2(args.metadataEvent.providerType);
7069
7334
  const providerSessionId = readNonEmptyString2(args.metadataEvent.providerSessionId);
7070
7335
  const workerResult = readWorkerResultMetadata(args.metadataEvent);
7071
- const completionDiagnostic = readRecord3(args.metadataEvent.completionDiagnostic);
7336
+ const completionDiagnostic = readRecord4(args.metadataEvent.completionDiagnostic);
7072
7337
  const finalSummary = readNonEmptyString2(args.metadataEvent.finalSummary);
7073
7338
  const status = readNonEmptyString2(args.metadataEvent.status).toLowerCase();
7074
7339
  const explicitCompletionEvidence = Boolean(
@@ -7383,6 +7648,111 @@ var init_mesh_routing = __esm({
7383
7648
  }
7384
7649
  });
7385
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
+
7386
7756
  // src/mesh/mesh-events-coordinator.ts
7387
7757
  import { existsSync as existsSync14 } from "fs";
7388
7758
  function resolveCoordinatorDrainDaemonIds(components) {
@@ -7788,7 +8158,7 @@ async function resolveUsableProvider(components, nodeId, node, requiredTags) {
7788
8158
  return { reason: `provider_priority_unusable: ${failed.join("; ") || nodeId}` };
7789
8159
  }
7790
8160
  function readMeshNodeId(node) {
7791
- return readNonEmptyString2(node?.id) || readNonEmptyString2(node?.nodeId) || readNonEmptyString2(node?.node_id);
8161
+ return normalizeMeshNodeId(node) ?? "";
7792
8162
  }
7793
8163
  async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
7794
8164
  const queue = getQueue(meshId);
@@ -8017,7 +8387,7 @@ async function triggerMeshQueue(components, meshId) {
8017
8387
  }
8018
8388
  async function maybeAutoFastForwardIdleNode(components, args) {
8019
8389
  const mesh = getMeshWithCache(components, args.meshId);
8020
- const node = mesh?.nodes?.find((candidate) => candidate?.id === args.nodeId || candidate?.nodeId === args.nodeId);
8390
+ const node = mesh?.nodes?.find((candidate) => meshNodeIdMatches(candidate, args.nodeId));
8021
8391
  const workspace = readNonEmptyString2(node?.workspace);
8022
8392
  if (!workspace) return;
8023
8393
  if (!existsSync14(workspace)) return;
@@ -8518,12 +8888,25 @@ function forwardUnresolvedDelegateEvent(components, routing, event) {
8518
8888
  nodeId: readNonEmptyString2(routing.nodeId) || readNonEmptyString2(event.meshNodeId) || void 0,
8519
8889
  workspace: readNonEmptyString2(routing.workspace) || readNonEmptyString2(event.workspace) || void 0
8520
8890
  };
8521
- Promise.resolve(components.dispatchMeshCommand(coordinatorDaemonId, "mesh_forward_event", payload)).catch((e) => {
8522
- 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`);
8523
8900
  });
8524
- 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}`);
8525
8902
  return true;
8526
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
+ }
8527
8910
  function setupMeshEventForwarding(components) {
8528
8911
  components.instanceManager.onEvent((event) => {
8529
8912
  if (event.event === "agent:ready" || event.event === "agent:generating_completed") {
@@ -8604,7 +8987,9 @@ var init_mesh_events_coordinator = __esm({
8604
8987
  init_mesh_runtime_store();
8605
8988
  init_mesh_events_pending();
8606
8989
  init_mesh_routing();
8990
+ init_mesh_unresolved_forward_outbox();
8607
8991
  init_repo_mesh_types();
8992
+ init_dist();
8608
8993
  init_mesh_events_stale();
8609
8994
  init_mesh_events_utils();
8610
8995
  REMOTE_IDLE_SESSION_TTL_MS = 5 * 60 * 1e3;
@@ -8718,6 +9103,13 @@ async function runMeshReconcileTick(components) {
8718
9103
  return void 0;
8719
9104
  }
8720
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
+ }
8721
9113
  if (dispatchMeshCommand) {
8722
9114
  for (const mesh of listMeshes()) {
8723
9115
  const selfIds = resolveCoordinatorSelfIds(mesh, drainDaemonIds);
@@ -8771,6 +9163,28 @@ async function runMeshReconcileTick(components) {
8771
9163
  }
8772
9164
  }
8773
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
+ }
8774
9188
  async function pullRemoteNodeQueues(components, mesh, localDaemonId, candidateDaemonIds) {
8775
9189
  const dispatchMeshCommand = components.dispatchMeshCommand;
8776
9190
  if (!dispatchMeshCommand) return;
@@ -8847,6 +9261,7 @@ var init_mesh_reconcile_loop = __esm({
8847
9261
  init_mesh_events_pending();
8848
9262
  init_mesh_runtime_store();
8849
9263
  init_mesh_events_coordinator();
9264
+ init_mesh_unresolved_forward_outbox();
8850
9265
  init_mesh_events_utils();
8851
9266
  DEFAULT_RECONCILE_INTERVAL_MS = 4e3;
8852
9267
  }
@@ -17191,9 +17606,10 @@ function buildMeshLedgerReconciliationEvidence(meshId, replicas) {
17191
17606
  init_mesh_work_queue();
17192
17607
 
17193
17608
  // src/mesh/mesh-active-work.ts
17609
+ init_dist();
17194
17610
  var DIRECT_DISPATCH_VIA = /* @__PURE__ */ new Set(["p2p_direct", "local_direct", "mesh_send_task"]);
17195
17611
  var TERMINAL_LEDGER_KINDS = /* @__PURE__ */ new Set(["task_completed", "task_failed", "task_stalled"]);
17196
- function readString5(value) {
17612
+ function readString6(value) {
17197
17613
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
17198
17614
  }
17199
17615
  function summarizeMessage(message) {
@@ -17208,7 +17624,7 @@ function elapsedSince(value, now) {
17208
17624
  function sessionStatusFromNodes(nodes, nodeId, sessionId) {
17209
17625
  if (!Array.isArray(nodes)) return {};
17210
17626
  if (!nodeId) return { staleReason: "direct task has no node id" };
17211
- const node = nodes.find((item) => readString5(item?.id) === nodeId || readString5(item?.nodeId) === nodeId || readString5(item?.node_id) === nodeId);
17627
+ const node = nodes.find((item) => meshNodeIdMatches(item, nodeId));
17212
17628
  if (!node) return { staleReason: "direct task node is no longer in the live mesh" };
17213
17629
  if (!sessionId) return {};
17214
17630
  const candidates = [];
@@ -17232,12 +17648,12 @@ function sessionStatusFromNodes(nodes, nodeId, sessionId) {
17232
17648
  }
17233
17649
  const session = candidates.find((item) => {
17234
17650
  if (typeof item === "string") return item === sessionId;
17235
- const id = readString5(item?.id) || readString5(item?.sessionId) || readString5(item?.session_id) || readString5(item?.runtimeSessionId) || readString5(item?.instanceId);
17651
+ const id = readString6(item?.id) || readString6(item?.sessionId) || readString6(item?.session_id) || readString6(item?.runtimeSessionId) || readString6(item?.instanceId);
17236
17652
  return id === sessionId;
17237
17653
  });
17238
17654
  if (!session) return { staleReason: "direct task session is not present in live session records" };
17239
17655
  if (typeof session === "string") return {};
17240
- const raw = `${readString5(session.status) || ""} ${readString5(session.lifecycle) || ""} ${readString5(session.state) || ""} ${readString5(session.activeChat?.status) || ""}`.toLowerCase();
17656
+ const raw = `${readString6(session.status) || ""} ${readString6(session.lifecycle) || ""} ${readString6(session.state) || ""} ${readString6(session.activeChat?.status) || ""}`.toLowerCase();
17241
17657
  if (raw.includes("approval")) return { status: "awaiting_approval" };
17242
17658
  if (raw.includes("generating") || raw.includes("running") || raw.includes("busy")) return { status: "generating" };
17243
17659
  if (raw.includes("failed") || raw.includes("stopped") || raw.includes("terminated") || raw.includes("exited")) return { status: "failed" };
@@ -17248,14 +17664,14 @@ function isDirectDispatch(entry) {
17248
17664
  if (entry.kind !== "task_dispatched") return false;
17249
17665
  const payload = entry.payload || {};
17250
17666
  if (payload.source === "direct") return true;
17251
- const via = readString5(payload.via);
17667
+ const via = readString6(payload.via);
17252
17668
  return Boolean(via && DIRECT_DISPATCH_VIA.has(via) && payload.source !== "queue");
17253
17669
  }
17254
17670
  function directDispatchTaskId(entry) {
17255
- return readString5(entry.payload?.taskId) || entry.id;
17671
+ return readString6(entry.payload?.taskId) || entry.id;
17256
17672
  }
17257
17673
  function terminalMatchesDispatch(terminal, dispatch, taskId) {
17258
- const terminalTaskId = readString5(terminal.payload?.taskId);
17674
+ const terminalTaskId = readString6(terminal.payload?.taskId);
17259
17675
  if (terminalTaskId && terminalTaskId === taskId) return true;
17260
17676
  if (terminalTaskId && terminalTaskId !== taskId) return false;
17261
17677
  if (dispatch.sessionId && terminal.sessionId === dispatch.sessionId) return true;
@@ -17378,7 +17794,7 @@ function buildMeshActiveWork(opts) {
17378
17794
  const isNoTransition = !terminalStatus && !live.status;
17379
17795
  const isIdleUnacknowledged = status === "idle";
17380
17796
  const ledgerOnlyStaleReason = !terminalRow && (isIdleUnacknowledged || isNoTransition || dispatchedToIdleSession && isIdleUnacknowledged) ? "direct task dispatch has no provider acknowledgement, transcript append, or active runtime transition" : void 0;
17381
- const message = readString5(dispatch.payload?.message) || readString5(dispatch.payload?.summary) || "";
17797
+ const message = readString6(dispatch.payload?.message) || readString6(dispatch.payload?.summary) || "";
17382
17798
  const { title, summary: summary2 } = summarizeMessage(message);
17383
17799
  const isFreshUnacknowledged = Boolean(ledgerOnlyStaleReason && !live.staleReason);
17384
17800
  const record = {
@@ -17387,11 +17803,11 @@ function buildMeshActiveWork(opts) {
17387
17803
  status,
17388
17804
  nodeId: dispatch.nodeId,
17389
17805
  sessionId: dispatch.sessionId,
17390
- providerType: dispatch.providerType || readString5(dispatch.payload?.providerType),
17391
- taskTitle: readString5(dispatch.payload?.taskTitle) || title,
17392
- taskSummary: readString5(dispatch.payload?.taskSummary) || summary2,
17806
+ providerType: dispatch.providerType || readString6(dispatch.payload?.providerType),
17807
+ taskTitle: readString6(dispatch.payload?.taskTitle) || title,
17808
+ taskSummary: readString6(dispatch.payload?.taskSummary) || summary2,
17393
17809
  message,
17394
- taskMode: readString5(dispatch.payload?.taskMode),
17810
+ taskMode: readString6(dispatch.payload?.taskMode),
17395
17811
  createdAt: dispatch.timestamp,
17396
17812
  updatedAt: terminal?.timestamp || dispatch.timestamp,
17397
17813
  dispatchedAt: dispatch.timestamp,
@@ -17426,7 +17842,7 @@ function buildMeshActiveWork(opts) {
17426
17842
  const isNoTransition = !terminalStatus && !live.status;
17427
17843
  const isIdleUnacknowledged = status === "idle";
17428
17844
  const ledgerOnlyStaleReason = !terminalRow && (isIdleUnacknowledged || isNoTransition || dispatchedToIdleSession && isIdleUnacknowledged) ? "direct task dispatch has no provider acknowledgement, transcript append, or active runtime transition" : void 0;
17429
- const message = readString5(dispatch.payload?.message) || readString5(dispatch.payload?.summary) || "";
17845
+ const message = readString6(dispatch.payload?.message) || readString6(dispatch.payload?.summary) || "";
17430
17846
  const { title, summary: summary2 } = summarizeMessage(message);
17431
17847
  const isFreshUnacknowledged = Boolean(ledgerOnlyStaleReason && !live.staleReason);
17432
17848
  const record = {
@@ -17435,11 +17851,11 @@ function buildMeshActiveWork(opts) {
17435
17851
  status,
17436
17852
  nodeId: dispatch.nodeId,
17437
17853
  sessionId: dispatch.sessionId,
17438
- providerType: dispatch.providerType || readString5(dispatch.payload?.providerType),
17439
- taskTitle: readString5(dispatch.payload?.taskTitle) || title,
17440
- taskSummary: readString5(dispatch.payload?.taskSummary) || summary2,
17854
+ providerType: dispatch.providerType || readString6(dispatch.payload?.providerType),
17855
+ taskTitle: readString6(dispatch.payload?.taskTitle) || title,
17856
+ taskSummary: readString6(dispatch.payload?.taskSummary) || summary2,
17441
17857
  message,
17442
- taskMode: readString5(dispatch.payload?.taskMode),
17858
+ taskMode: readString6(dispatch.payload?.taskMode),
17443
17859
  createdAt: dispatch.timestamp,
17444
17860
  updatedAt: terminal?.timestamp || dispatch.timestamp,
17445
17861
  dispatchedAt: dispatch.timestamp,
@@ -21783,7 +22199,7 @@ var ExtensionProviderInstance = class {
21783
22199
  this.runtimeMessages = [];
21784
22200
  }
21785
22201
  updateSettings(newSettings) {
21786
- this.settings = { ...newSettings };
22202
+ this.settings = { ...this.settings, ...newSettings };
21787
22203
  this.monitor.updateConfig({
21788
22204
  approvalAlert: this.settings.approvalAlert !== false,
21789
22205
  longGeneratingAlert: this.settings.longGeneratingAlert !== false,
@@ -22450,7 +22866,7 @@ var IdeProviderInstance = class {
22450
22866
  this.extensions.clear();
22451
22867
  }
22452
22868
  updateSettings(newSettings) {
22453
- this.settings = { ...newSettings };
22869
+ this.settings = { ...this.settings, ...newSettings };
22454
22870
  this.monitor.updateConfig({
22455
22871
  approvalAlert: this.settings.approvalAlert !== false,
22456
22872
  longGeneratingAlert: this.settings.longGeneratingAlert !== false,
@@ -23929,7 +24345,7 @@ function resolveLegacyProviderScript(fn, scriptName, params) {
23929
24345
  import * as fs6 from "fs";
23930
24346
  import * as os8 from "os";
23931
24347
  import * as path13 from "path";
23932
- import { randomUUID as randomUUID10 } from "crypto";
24348
+ import { randomUUID as randomUUID11 } from "crypto";
23933
24349
  init_logger();
23934
24350
 
23935
24351
  // src/logging/debug-trace.ts
@@ -25470,7 +25886,7 @@ function safeBundleIdSegment(value, fallback) {
25470
25886
  function createChatDebugBundleId(targetSessionId) {
25471
25887
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:.]/g, "").replace("T", "T").replace("Z", "Z");
25472
25888
  const sessionSegment = safeBundleIdSegment(targetSessionId, "unknown-session");
25473
- return `chat-debug-${timestamp}-${sessionSegment}-${randomUUID10().slice(0, 8)}`;
25889
+ return `chat-debug-${timestamp}-${sessionSegment}-${randomUUID11().slice(0, 8)}`;
25474
25890
  }
25475
25891
  function buildChatDebugBundleSummary(bundle) {
25476
25892
  const target = bundle.target && typeof bundle.target === "object" ? bundle.target : {};
@@ -31998,22 +32414,7 @@ var CliProviderInstance = class _CliProviderInstance {
31998
32414
  };
31999
32415
  }
32000
32416
  updateSettings(newSettings) {
32001
- const runtimeMeshSettings = {};
32002
- for (const key of [
32003
- "meshNodeFor",
32004
- "meshNodeId",
32005
- "meshActiveTaskId",
32006
- "meshCoordinatorFor",
32007
- "meshCoordinatorDaemonId",
32008
- "meshCoordinatorNodeId",
32009
- "spawnedSessionVisibility",
32010
- "launchedByCoordinator"
32011
- ]) {
32012
- if (this.settings[key] !== void 0 && newSettings[key] === void 0) {
32013
- runtimeMeshSettings[key] = this.settings[key];
32014
- }
32015
- }
32016
- this.settings = { ...newSettings, ...runtimeMeshSettings };
32417
+ this.settings = { ...this.settings, ...newSettings };
32017
32418
  this.adapter.updateRuntimeSettings?.(this.settings);
32018
32419
  this.monitor.updateConfig({
32019
32420
  approvalAlert: this.settings.approvalAlert !== false,
@@ -39345,207 +39746,7 @@ function getAvailableIdeIds() {
39345
39746
  init_config();
39346
39747
  init_cli_detector();
39347
39748
  init_git_status();
39348
-
39349
- // ../mesh-shared/dist/index.mjs
39350
- function readRecord5(value) {
39351
- return value && typeof value === "object" && !Array.isArray(value) ? value : {};
39352
- }
39353
- function readString6(...values) {
39354
- for (const value of values) {
39355
- if (typeof value !== "string") continue;
39356
- const trimmed = value.trim();
39357
- if (trimmed) return trimmed;
39358
- }
39359
- return void 0;
39360
- }
39361
- function readNumber(...values) {
39362
- for (const value of values) {
39363
- if (typeof value === "number" && Number.isFinite(value)) return value;
39364
- }
39365
- return void 0;
39366
- }
39367
- function readBoolean(...values) {
39368
- for (const value of values) {
39369
- if (typeof value === "boolean") return value;
39370
- }
39371
- return void 0;
39372
- }
39373
- function joinRepoPath(root, relativePath) {
39374
- const normalizedRoot = typeof root === "string" ? root.trim().replace(/[\\/]+$/, "") : "";
39375
- const normalizedPath = typeof relativePath === "string" ? relativePath.trim() : "";
39376
- if (!normalizedPath) return void 0;
39377
- if (/^(?:[A-Za-z]:[\\/]|\/)/.test(normalizedPath)) return normalizedPath;
39378
- if (!normalizedRoot) return void 0;
39379
- return `${normalizedRoot}/${normalizedPath.replace(/^[\\/]+/, "")}`;
39380
- }
39381
- function scoreGitUpstreamFreshness(status) {
39382
- switch (status) {
39383
- case "fresh":
39384
- return 30;
39385
- case "no_upstream":
39386
- return 4;
39387
- case "unchecked":
39388
- case void 0:
39389
- return 0;
39390
- case "stale":
39391
- return -10;
39392
- case "unavailable":
39393
- return -15;
39394
- default:
39395
- return 0;
39396
- }
39397
- }
39398
- function readGitSubmodules(value, parentRepoRoot) {
39399
- if (!Array.isArray(value)) return void 0;
39400
- const submodules = value.map((entry) => {
39401
- const submodule = readRecord5(entry);
39402
- const path40 = readString6(submodule.path);
39403
- const commit = readString6(submodule.commit);
39404
- const repoPath = readString6(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot, path40);
39405
- if (!path40 || !commit) return null;
39406
- const result = {
39407
- path: path40,
39408
- commit,
39409
- dirty: readBoolean(submodule.dirty) ?? false,
39410
- outOfSync: readBoolean(submodule.outOfSync, submodule.out_of_sync) ?? false,
39411
- lastCheckedAt: readNumber(submodule.lastCheckedAt, submodule.last_checked_at) ?? Date.now()
39412
- };
39413
- if (repoPath) result.repoPath = repoPath;
39414
- const error = readString6(submodule.error);
39415
- if (error) result.error = error;
39416
- return result;
39417
- }).filter((entry) => entry !== null);
39418
- return submodules.length > 0 ? submodules : void 0;
39419
- }
39420
- function hasGitStatusEvidence(status) {
39421
- return readBoolean(status.isGitRepo) !== void 0 || Boolean(readString6(status.branch, status.upstream, status.upstreamStatus, status.upstream_status, status.headCommit)) || Boolean(readString6(status.repoRoot, status.repo_root, status.workspace)) || readNumber(
39422
- status.ahead,
39423
- status.behind,
39424
- status.staged,
39425
- status.modified,
39426
- status.untracked,
39427
- status.deleted,
39428
- status.renamed,
39429
- status.lastCheckedAt,
39430
- status.last_checked_at
39431
- ) !== void 0 || Array.isArray(status.submodules) && status.submodules.length > 0;
39432
- }
39433
- function normalizeGitStatus(status, node, options) {
39434
- const explicitIsGitRepo = readBoolean(status.isGitRepo);
39435
- if (!Object.keys(status).length || !hasGitStatusEvidence(status)) return void 0;
39436
- const isGitRepo = explicitIsGitRepo ?? true;
39437
- const conflictFiles = Array.isArray(status.conflictFiles) ? status.conflictFiles.filter((entry) => typeof entry === "string") : [];
39438
- const conflictCount = readNumber(status.conflicts) ?? conflictFiles.length;
39439
- const hasConflicts = readBoolean(status.hasConflicts) ?? conflictCount > 0;
39440
- const repoRoot = readString6(status.repoRoot, status.repo_root, node.repoRoot, node.repo_root, status.workspace, node.workspace) || void 0;
39441
- const submodules = readGitSubmodules(status.submodules, repoRoot);
39442
- const upstreamStatus = readString6(status.upstreamStatus, status.upstream_status);
39443
- const upstreamFetchedAt = readNumber(status.upstreamFetchedAt, status.upstream_fetched_at);
39444
- const upstreamFetchError = readString6(status.upstreamFetchError, status.upstream_fetch_error);
39445
- const error = readString6(status.error);
39446
- const staged = readNumber(status.staged) ?? 0;
39447
- const modified = readNumber(status.modified) ?? 0;
39448
- const untracked = readNumber(status.untracked) ?? 0;
39449
- const deleted = readNumber(status.deleted) ?? 0;
39450
- const renamed = readNumber(status.renamed) ?? 0;
39451
- return {
39452
- workspace: readString6(status.workspace, node.workspace) || "",
39453
- repoRoot: repoRoot ?? null,
39454
- isGitRepo,
39455
- branch: readString6(status.branch) ?? null,
39456
- headCommit: readString6(status.headCommit) ?? null,
39457
- headMessage: readString6(status.headMessage) ?? null,
39458
- upstream: readString6(status.upstream) ?? null,
39459
- upstreamStatus: upstreamStatus ?? "unchecked",
39460
- ...upstreamFetchedAt !== void 0 ? { upstreamFetchedAt } : {},
39461
- ...upstreamFetchError ? { upstreamFetchError } : {},
39462
- ahead: readNumber(status.ahead) ?? 0,
39463
- behind: readNumber(status.behind) ?? 0,
39464
- staged,
39465
- modified,
39466
- untracked,
39467
- deleted,
39468
- renamed,
39469
- dirty: readBoolean(status.dirty, status.isDirty, status.is_dirty) ?? (staged + modified + untracked + deleted + renamed > 0 || hasConflicts),
39470
- hasConflicts,
39471
- conflictFiles,
39472
- stashCount: readNumber(status.stashCount, status.stash_count) ?? 0,
39473
- lastCheckedAt: options?.lastCheckedAt ?? readNumber(status.lastCheckedAt, status.last_checked_at) ?? Date.now(),
39474
- ...submodules ? { submodules } : {},
39475
- ...error ? { error } : {}
39476
- };
39477
- }
39478
- function scoreGitStatusCandidate(git) {
39479
- if (!git) return Number.NEGATIVE_INFINITY;
39480
- let score = 0;
39481
- if (git.isGitRepo === true) score += 50;
39482
- if (git.isGitRepo === false) score -= 10;
39483
- if (git.branch) score += 20;
39484
- if (git.headCommit) score += 20;
39485
- if (git.upstream) score += 10;
39486
- score += scoreGitUpstreamFreshness(git.upstreamStatus);
39487
- if (typeof git.ahead === "number") score += 2;
39488
- if (typeof git.behind === "number") score += 2;
39489
- if (Array.isArray(git.submodules) && git.submodules.length > 0) score += 4 + git.submodules.length;
39490
- if (git.error) score -= 20;
39491
- return score;
39492
- }
39493
- function pickBestTransitGitStatus(node, options) {
39494
- const rawGit = readRecord5(node.lastGit ?? node.last_git);
39495
- const gitResult = readRecord5(rawGit.result);
39496
- const directStatus = readRecord5(rawGit.status);
39497
- const nestedStatus = readRecord5(gitResult.status);
39498
- const rawProbe = readRecord5(node.lastProbe ?? node.last_probe);
39499
- const probeGit = readRecord5(rawProbe.git);
39500
- const probeGitResult = readRecord5(probeGit.result);
39501
- const probeDirectStatus = readRecord5(probeGit.status);
39502
- const probeNestedStatus = readRecord5(probeGitResult.status);
39503
- const lastCheckedAt = options?.lastCheckedAt;
39504
- let best = null;
39505
- for (const status of [directStatus, nestedStatus, probeDirectStatus, probeNestedStatus]) {
39506
- const normalized = normalizeGitStatus(status, node, { lastCheckedAt: lastCheckedAt ?? Date.now() });
39507
- if (!normalized) continue;
39508
- const score = scoreGitStatusCandidate(normalized);
39509
- if (!best || score > best.score) best = { git: normalized, score };
39510
- }
39511
- return best?.git;
39512
- }
39513
- function summarizeGitShape(status) {
39514
- const record = readRecord5(status);
39515
- if (!Object.keys(record).length) return null;
39516
- const submodules = Array.isArray(record.submodules) ? record.submodules.map((entry) => {
39517
- const sub = readRecord5(entry);
39518
- return {
39519
- path: readString6(sub.path) ?? null,
39520
- commit: readString6(sub.commit)?.slice(0, 12) ?? null,
39521
- dirty: readBoolean(sub.dirty) ?? false,
39522
- outOfSync: readBoolean(sub.outOfSync, sub.out_of_sync) ?? false
39523
- };
39524
- }) : [];
39525
- return {
39526
- isGitRepo: readBoolean(record.isGitRepo),
39527
- workspace: readString6(record.workspace) ?? null,
39528
- repoRoot: readString6(record.repoRoot, record.repo_root) ?? null,
39529
- branch: readString6(record.branch) ?? null,
39530
- upstream: readString6(record.upstream) ?? null,
39531
- upstreamStatus: readString6(record.upstreamStatus, record.upstream_status) ?? null,
39532
- headCommit: readString6(record.headCommit, record.head_commit)?.slice(0, 12) ?? null,
39533
- ahead: readNumber(record.ahead) ?? null,
39534
- behind: readNumber(record.behind) ?? null,
39535
- dirtyCounts: {
39536
- staged: readNumber(record.staged) ?? 0,
39537
- modified: readNumber(record.modified) ?? 0,
39538
- untracked: readNumber(record.untracked) ?? 0,
39539
- deleted: readNumber(record.deleted) ?? 0,
39540
- renamed: readNumber(record.renamed) ?? 0
39541
- },
39542
- lastCheckedAt: readNumber(record.lastCheckedAt, record.last_checked_at) ?? null,
39543
- submoduleCount: submodules.length,
39544
- submodules
39545
- };
39546
- }
39547
-
39548
- // src/commands/router.ts
39749
+ init_dist();
39549
39750
  init_logger();
39550
39751
 
39551
39752
  // src/logging/command-log.ts
@@ -40625,7 +40826,10 @@ function summarizeRepoMeshStatusDebug(status) {
40625
40826
  branchConvergenceSummary: status?.branchConvergenceSummary ?? status?.branch_convergence_summary ?? null,
40626
40827
  nodeCount: nodes.length,
40627
40828
  nodes: nodes.map((node) => ({
40628
- nodeId: readStringValue(node?.nodeId, node?.id) ?? null,
40829
+ // Status emits the id under `nodeId` (3-way input absorbed). The
40830
+ // inline cache keeps `id` and `nodeId` equal, so this serialized form
40831
+ // round-trips back through the cache without flipping shape.
40832
+ nodeId: normalizeMeshNodeId(node) ?? null,
40629
40833
  daemonId: readStringValue(node?.daemonId, node?.daemon_id) ?? null,
40630
40834
  workspace: readStringValue(node?.workspace, node?.git?.workspace) ?? null,
40631
40835
  health: readStringValue(node?.health) ?? null,
@@ -40870,7 +41074,23 @@ function inlineMeshCarriesTransientNodeTruth(inlineMesh) {
40870
41074
  return inlineMesh.nodes.some((node) => hasInlineMeshTransientNodeState(node));
40871
41075
  }
40872
41076
  function readInlineMeshNodeId(node) {
40873
- return readStringValue(node?.id, node?.nodeId) || "";
41077
+ return normalizeMeshNodeId(node) ?? "";
41078
+ }
41079
+ function foldMeshNodeIdentityToCanonical(node) {
41080
+ if (!node || typeof node !== "object" || Array.isArray(node)) return node;
41081
+ const canonical = normalizeMeshNodeId(node);
41082
+ if (canonical === void 0) return node;
41083
+ if (node.id === canonical && node.nodeId === canonical && node.node_id === void 0) return node;
41084
+ node.id = canonical;
41085
+ node.nodeId = canonical;
41086
+ if ("node_id" in node) delete node.node_id;
41087
+ return node;
41088
+ }
41089
+ function normalizeInlineMeshNodeIdentity(inlineMesh) {
41090
+ if (!inlineMesh || typeof inlineMesh !== "object" || Array.isArray(inlineMesh)) return inlineMesh;
41091
+ if (!Array.isArray(inlineMesh.nodes) || inlineMesh.nodes.length === 0) return inlineMesh;
41092
+ for (const node of inlineMesh.nodes) foldMeshNodeIdentityToCanonical(node);
41093
+ return inlineMesh;
40874
41094
  }
40875
41095
  function sanitizeInlineMesh(inlineMesh) {
40876
41096
  if (!inlineMesh || typeof inlineMesh !== "object" || Array.isArray(inlineMesh)) return inlineMesh;
@@ -40972,7 +41192,7 @@ function deriveMeshNodeHealthFromGit(git) {
40972
41192
  return "online";
40973
41193
  }
40974
41194
  function readMeshNodeLabel(status, node) {
40975
- return readStringValue(status.nodeId, node?.id, node?.nodeId) ?? "unknown";
41195
+ return readStringValue(status.nodeId, normalizeMeshNodeId(node)) ?? "unknown";
40976
41196
  }
40977
41197
  function buildInlineMeshBranchConvergence(args) {
40978
41198
  const git = readObjectRecord(args.status.git);
@@ -41251,7 +41471,7 @@ async function hydrateInlineMeshDirectTruth(args) {
41251
41471
  let peerConfirmedCount = 0;
41252
41472
  const unavailableNodeIds = [];
41253
41473
  for (const [nodeIndex, node] of nodes.entries()) {
41254
- const nodeId = readStringValue(node?.id, node?.nodeId) || `node_${nodeIndex}`;
41474
+ const nodeId = normalizeMeshNodeId(node) || `node_${nodeIndex}`;
41255
41475
  const workspace = readStringValue(node?.workspace);
41256
41476
  const daemonId = readStringValue(node?.daemonId);
41257
41477
  const isSelfNode = Boolean(
@@ -41382,7 +41602,7 @@ function buildHistoricalMeshSessions(args) {
41382
41602
  const liveWorkspaces = /* @__PURE__ */ new Set();
41383
41603
  const missingLocalWorktreeNodeIds = /* @__PURE__ */ new Set();
41384
41604
  for (const node of args.nodes || []) {
41385
- const nodeId = readStringValue(node?.id, node?.nodeId);
41605
+ const nodeId = normalizeMeshNodeId(node);
41386
41606
  const workspace = readStringValue(node?.workspace);
41387
41607
  if (nodeId) liveNodeIds.add(nodeId);
41388
41608
  if (workspace) liveWorkspaces.add(workspace);
@@ -41507,9 +41727,13 @@ function resolveRefineryAutoPublishSubmoduleMainCommits(mesh, workspace) {
41507
41727
  }
41508
41728
  return { enabled: false };
41509
41729
  }
41510
- async function computeGitPatchId(cwd, fromRef, toRef) {
41730
+ async function computeGitPatchId(cwd, fromRef, toRef, excludePaths = []) {
41511
41731
  const { execFileSync: execFileSync6 } = await import("child_process");
41512
- const diff = execFileSync6("git", ["diff", "--patch", "--full-index", fromRef, toRef], {
41732
+ const diffArgs = ["diff", "--patch", "--full-index", fromRef, toRef];
41733
+ if (excludePaths.length > 0) {
41734
+ diffArgs.push("--", ".", ...excludePaths.map((path40) => `:(exclude)${path40}`));
41735
+ }
41736
+ const diff = execFileSync6("git", diffArgs, {
41513
41737
  cwd,
41514
41738
  encoding: "utf8",
41515
41739
  maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
@@ -41578,8 +41802,9 @@ ${mergeTreeErr?.stderr || ""}`;
41578
41802
  gitlinkTrivialFastForward
41579
41803
  };
41580
41804
  }
41581
- const expectedPatchId = await computeGitPatchId(repoRoot, mergeBase, branchHead);
41582
- const actualPatchId = await computeGitPatchId(repoRoot, baseHead, mergedTree);
41805
+ const ffGitlinkExcludePaths = collectFastForwardGitlinkPaths(repoRoot, baseHead, branchHead);
41806
+ const expectedPatchId = await computeGitPatchId(repoRoot, mergeBase, branchHead, ffGitlinkExcludePaths);
41807
+ const actualPatchId = await computeGitPatchId(repoRoot, baseHead, mergedTree, ffGitlinkExcludePaths);
41583
41808
  const equivalent = expectedPatchId === actualPatchId;
41584
41809
  return {
41585
41810
  status: equivalent ? "passed" : "failed",
@@ -41775,6 +42000,14 @@ function readChangedPathKinds(repoRoot, fromRef, toRef) {
41775
42000
  return [];
41776
42001
  }
41777
42002
  }
42003
+ function collectFastForwardGitlinkPaths(repoRoot, baseHead, branchHead) {
42004
+ return readChangedGitlinkPaths(repoRoot, baseHead, branchHead).filter((path40) => {
42005
+ const baseCommit = readTreeObject(repoRoot, baseHead, path40);
42006
+ const branchCommit = readTreeObject(repoRoot, branchHead, path40);
42007
+ if (!baseCommit || !branchCommit) return false;
42008
+ return isSubmoduleFastForward(pathResolve2(repoRoot, path40), baseCommit, branchCommit);
42009
+ });
42010
+ }
41778
42011
  function evaluateGitlinkTrivialFastForward(repoRoot, baseHead, branchHead) {
41779
42012
  const changedGitlinks = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((path40) => {
41780
42013
  const baseCommit = readTreeObject(repoRoot, baseHead, path40);
@@ -41824,20 +42057,95 @@ function evaluateGitlinkTrivialFastForward(repoRoot, baseHead, branchHead) {
41824
42057
  }
41825
42058
  return { trivial: true, gitlinks: changedGitlinks };
41826
42059
  }
42060
+ function buildTreeWithGitlinksEqualized(repoRoot, commitish, paths, placeholderCommit) {
42061
+ try {
42062
+ const tree = execFileSync5("git", ["rev-parse", `${commitish}^{tree}`], {
42063
+ cwd: repoRoot,
42064
+ encoding: "utf8",
42065
+ maxBuffer: 1024 * 1024
42066
+ }).trim();
42067
+ if (!tree) return void 0;
42068
+ const updates = paths.map((path40) => `160000 commit ${placeholderCommit} ${path40}`).join("\n");
42069
+ if (!updates) return tree;
42070
+ const tmpIndex = pathJoin(resolveGitDir(repoRoot), `adhdev-refine-eq-${commitish.slice(0, 12)}.index`);
42071
+ const env = { ...process.env, GIT_INDEX_FILE: tmpIndex };
42072
+ try {
42073
+ execFileSync5("git", ["read-tree", tree], { cwd: repoRoot, env, stdio: "ignore" });
42074
+ execFileSync5("git", ["update-index", "--index-info"], {
42075
+ cwd: repoRoot,
42076
+ env,
42077
+ input: `${updates}
42078
+ `,
42079
+ encoding: "utf8",
42080
+ stdio: ["pipe", "ignore", "ignore"]
42081
+ });
42082
+ const newTree = execFileSync5("git", ["write-tree"], { cwd: repoRoot, env, encoding: "utf8" }).trim();
42083
+ return newTree || void 0;
42084
+ } finally {
42085
+ try {
42086
+ fs24.rmSync(tmpIndex, { force: true });
42087
+ } catch {
42088
+ }
42089
+ }
42090
+ } catch {
42091
+ return void 0;
42092
+ }
42093
+ }
41827
42094
  function synthesizeTrivialFastForwardMergeTree(repoRoot, baseHead, branchHead, gitlinks) {
41828
42095
  try {
41829
- const baseTree = execFileSync5("git", ["rev-parse", `${baseHead}^{tree}`], {
42096
+ const branchGitlinks = gitlinks.filter((entry) => entry.branchCommit);
42097
+ const gitlinkPaths = branchGitlinks.map((entry) => entry.path);
42098
+ const mergeBase = execFileSync5("git", ["merge-base", baseHead, branchHead], {
42099
+ cwd: repoRoot,
42100
+ encoding: "utf8",
42101
+ maxBuffer: 1024 * 1024
42102
+ }).trim();
42103
+ let mergedContentTree;
42104
+ if (mergeBase && gitlinkPaths.length > 0) {
42105
+ const placeholder = readTreeObject(repoRoot, mergeBase, gitlinkPaths[0]) || branchGitlinks[0].branchCommit;
42106
+ const baseEqTree = buildTreeWithGitlinksEqualized(repoRoot, mergeBase, gitlinkPaths, placeholder);
42107
+ const oursEqTree = buildTreeWithGitlinksEqualized(repoRoot, baseHead, gitlinkPaths, placeholder);
42108
+ const theirsEqTree = buildTreeWithGitlinksEqualized(repoRoot, branchHead, gitlinkPaths, placeholder);
42109
+ if (baseEqTree && oursEqTree && theirsEqTree) {
42110
+ try {
42111
+ const baseEqCommit = execFileSync5("git", ["commit-tree", baseEqTree, "-m", "refine-ff-base"], {
42112
+ cwd: repoRoot,
42113
+ encoding: "utf8",
42114
+ maxBuffer: 1024 * 1024
42115
+ }).trim();
42116
+ const oursEqCommit = execFileSync5("git", ["commit-tree", oursEqTree, "-p", baseEqCommit, "-m", "refine-ff-ours"], {
42117
+ cwd: repoRoot,
42118
+ encoding: "utf8",
42119
+ maxBuffer: 1024 * 1024
42120
+ }).trim();
42121
+ const theirsEqCommit = execFileSync5("git", ["commit-tree", theirsEqTree, "-p", baseEqCommit, "-m", "refine-ff-theirs"], {
42122
+ cwd: repoRoot,
42123
+ encoding: "utf8",
42124
+ maxBuffer: 1024 * 1024
42125
+ }).trim();
42126
+ const mergeOut = execFileSync5("git", ["merge-tree", "--write-tree", oursEqCommit, theirsEqCommit], {
42127
+ cwd: repoRoot,
42128
+ encoding: "utf8",
42129
+ maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
42130
+ }).trim();
42131
+ mergedContentTree = mergeOut.split(/\s+/)[0] || void 0;
42132
+ } catch {
42133
+ mergedContentTree = void 0;
42134
+ }
42135
+ }
42136
+ }
42137
+ const contentTree = mergedContentTree || execFileSync5("git", ["rev-parse", `${baseHead}^{tree}`], {
41830
42138
  cwd: repoRoot,
41831
42139
  encoding: "utf8",
41832
42140
  maxBuffer: 1024 * 1024
41833
42141
  }).trim();
41834
- if (!baseTree) return void 0;
41835
- const updates = gitlinks.filter((entry) => entry.branchCommit).map((entry) => `160000 commit ${entry.branchCommit} ${entry.path}`).join("\n");
41836
- if (!updates) return baseTree;
42142
+ if (!contentTree) return void 0;
42143
+ const updates = branchGitlinks.map((entry) => `160000 commit ${entry.branchCommit} ${entry.path}`).join("\n");
42144
+ if (!updates) return contentTree;
41837
42145
  const tmpIndex = pathJoin(resolveGitDir(repoRoot), `adhdev-refine-ff-${baseHead.slice(0, 12)}-${branchHead.slice(0, 12)}.index`);
41838
42146
  const env = { ...process.env, GIT_INDEX_FILE: tmpIndex };
41839
42147
  try {
41840
- execFileSync5("git", ["read-tree", baseTree], { cwd: repoRoot, env, stdio: "ignore" });
42148
+ execFileSync5("git", ["read-tree", contentTree], { cwd: repoRoot, env, stdio: "ignore" });
41841
42149
  execFileSync5("git", ["update-index", "--index-info"], {
41842
42150
  cwd: repoRoot,
41843
42151
  env,
@@ -42497,7 +42805,7 @@ function normalizeStandaloneHostCommandUrl(hostAddress) {
42497
42805
  function buildMemberJoinNode(mesh, args, fallbackDaemonId) {
42498
42806
  const requestedNodeId = typeof args?.memberNodeId === "string" ? args.memberNodeId.trim() : "";
42499
42807
  const explicit = args?.memberNode && typeof args.memberNode === "object" && !Array.isArray(args.memberNode) ? args.memberNode : null;
42500
- const configured = Array.isArray(mesh?.nodes) ? requestedNodeId ? mesh.nodes.find((node) => node?.id === requestedNodeId || node?.nodeId === requestedNodeId) : mesh.nodes[0] : null;
42808
+ const configured = Array.isArray(mesh?.nodes) ? requestedNodeId ? mesh.nodes.find((node) => meshNodeIdMatches(node, requestedNodeId)) : mesh.nodes[0] : null;
42501
42809
  const source = explicit || configured;
42502
42810
  const workspace = typeof source?.workspace === "string" && source.workspace.trim() ? source.workspace.trim() : typeof args?.workspace === "string" && args.workspace.trim() ? args.workspace.trim() : process.cwd();
42503
42811
  if (!workspace) return null;
@@ -42553,7 +42861,7 @@ var DaemonCommandRouter = class {
42553
42861
  if (nodeId) unavailableNodeIds.add(nodeId);
42554
42862
  }
42555
42863
  const nodes = snapshot.nodes.map((statusNode) => {
42556
- const nodeId = readStringValue(statusNode?.nodeId, statusNode?.id);
42864
+ const nodeId = normalizeMeshNodeId(statusNode);
42557
42865
  const inlineNode = nodeId ? inlineNodesById.get(nodeId) : void 0;
42558
42866
  if (!inlineNode) return statusNode;
42559
42867
  const liveGit = buildInlineMeshTransitGitStatus(inlineNode);
@@ -42666,7 +42974,7 @@ var DaemonCommandRouter = class {
42666
42974
  }
42667
42975
  warmInlineMeshCache(meshId, inlineMesh) {
42668
42976
  if (!inlineMesh || typeof inlineMesh !== "object") return void 0;
42669
- const sanitizedInlineMesh = sanitizeInlineMesh(inlineMesh);
42977
+ const sanitizedInlineMesh = sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(inlineMesh));
42670
42978
  const cached2 = this.inlineMeshCache.get(meshId);
42671
42979
  if (cached2) {
42672
42980
  const merged = reconcileInlineMeshCache(cached2, sanitizedInlineMesh);
@@ -42683,7 +42991,7 @@ var DaemonCommandRouter = class {
42683
42991
  if (cached3) {
42684
42992
  if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
42685
42993
  const merged = reconcileInlineMeshCache(cached3, inlineMesh);
42686
- this.inlineMeshCache.set(meshId, sanitizeInlineMesh(merged));
42994
+ this.inlineMeshCache.set(meshId, sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(merged)));
42687
42995
  return { mesh: merged, inline: true, source: "inline_cache" };
42688
42996
  }
42689
42997
  return { mesh: cached3, inline: true, source: "inline_cache" };
@@ -42719,17 +43027,19 @@ var DaemonCommandRouter = class {
42719
43027
  return null;
42720
43028
  }
42721
43029
  updateInlineMeshNode(meshId, mesh, node) {
42722
- if (!mesh || !Array.isArray(mesh.nodes) || !node?.id) return;
42723
- const idx = mesh.nodes.findIndex((entry) => entry?.id === node.id || entry?.nodeId === node.id);
43030
+ const incomingId = normalizeMeshNodeId(node);
43031
+ if (!mesh || !Array.isArray(mesh.nodes) || !incomingId) return;
43032
+ const idx = mesh.nodes.findIndex((entry) => meshNodeIdMatches(entry, incomingId));
42724
43033
  if (idx >= 0) mesh.nodes[idx] = node;
42725
43034
  else mesh.nodes.push(node);
42726
43035
  mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
43036
+ for (const entry of mesh.nodes) foldMeshNodeIdentityToCanonical(entry);
42727
43037
  this.inlineMeshCache.set(meshId, mesh);
42728
43038
  this.invalidateAggregateMeshStatus(meshId);
42729
43039
  }
42730
43040
  removeInlineMeshNode(meshId, mesh, nodeId) {
42731
43041
  if (!mesh || !Array.isArray(mesh.nodes)) return false;
42732
- const idx = mesh.nodes.findIndex((entry) => entry?.id === nodeId || entry?.nodeId === nodeId);
43042
+ const idx = mesh.nodes.findIndex((entry) => meshNodeIdMatches(entry, nodeId));
42733
43043
  if (idx === -1) return false;
42734
43044
  mesh.nodes.splice(idx, 1);
42735
43045
  mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -42760,7 +43070,7 @@ var DaemonCommandRouter = class {
42760
43070
  };
42761
43071
  }
42762
43072
  const worktreeExists = fs24.existsSync(workspace);
42763
- const sourceNode = args.node?.clonedFromNodeId ? args.mesh?.nodes?.find((n) => n.id === args.node.clonedFromNodeId || n.nodeId === args.node.clonedFromNodeId) : args.mesh?.nodes?.find((n) => !n.isLocalWorktree);
43073
+ const sourceNode = args.node?.clonedFromNodeId ? args.mesh?.nodes?.find((n) => meshNodeIdMatches(n, args.node.clonedFromNodeId)) : args.mesh?.nodes?.find((n) => !n.isLocalWorktree);
42764
43074
  const repoRoot = typeof sourceNode?.repoRoot === "string" && sourceNode.repoRoot.trim() ? sourceNode.repoRoot.trim() : typeof sourceNode?.workspace === "string" && sourceNode.workspace.trim() ? sourceNode.workspace.trim() : "";
42765
43075
  if (!worktreeExists) {
42766
43076
  return { success: true, skipped: true, removedPath: workspace, repoRoot: repoRoot || void 0, reason: "worktree_path_missing" };
@@ -43403,12 +43713,12 @@ var DaemonCommandRouter = class {
43403
43713
  try {
43404
43714
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
43405
43715
  const mesh = meshRecord?.mesh;
43406
- const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
43716
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
43407
43717
  if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh`, refineStages };
43408
43718
  if (!node.isLocalWorktree || !node.workspace) {
43409
43719
  return { success: false, error: `Refinery requires a local worktree node`, refineStages };
43410
43720
  }
43411
- const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => n.id === node.clonedFromNodeId || n.nodeId === node.clonedFromNodeId) : mesh?.nodes.find((n) => !n.isLocalWorktree);
43721
+ const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => meshNodeIdMatches(n, node.clonedFromNodeId)) : mesh?.nodes.find((n) => !n.isLocalWorktree);
43412
43722
  const repoRoot = sourceNode?.repoRoot || sourceNode?.workspace;
43413
43723
  if (!repoRoot) return { success: false, error: "Source node repoRoot not found", refineStages };
43414
43724
  const { execFile: execFile5 } = await import("child_process");
@@ -44043,7 +44353,7 @@ ${hintLines.join("\n")}` : "",
44043
44353
  const missing = [];
44044
44354
  const nonWorktree = [];
44045
44355
  for (const nodeId of requestedNodeIds) {
44046
- const node = allNodes.find((n) => n.id === nodeId || n.nodeId === nodeId);
44356
+ const node = allNodes.find((n) => meshNodeIdMatches(n, nodeId));
44047
44357
  if (!node) {
44048
44358
  missing.push(nodeId);
44049
44359
  continue;
@@ -44072,7 +44382,7 @@ ${hintLines.join("\n")}` : "",
44072
44382
  const { promisify: promisify8 } = await import("util");
44073
44383
  const execFileAsync4 = promisify8(execFile5);
44074
44384
  const resolveRepoRootFor = (node) => {
44075
- const sourceNode = node.clonedFromNodeId ? allNodes.find((n) => n.id === node.clonedFromNodeId || n.nodeId === node.clonedFromNodeId) : allNodes.find((n) => !n.isLocalWorktree);
44385
+ const sourceNode = node.clonedFromNodeId ? allNodes.find((n) => meshNodeIdMatches(n, node.clonedFromNodeId)) : allNodes.find((n) => !n.isLocalWorktree);
44076
44386
  return sourceNode?.repoRoot || sourceNode?.workspace;
44077
44387
  };
44078
44388
  const repoRootBaseRef = /* @__PURE__ */ new Map();
@@ -44161,7 +44471,7 @@ ${hintLines.join("\n")}` : "",
44161
44471
  }));
44162
44472
  }
44163
44473
  const ordering = orderMeshRefineBatchNodes(changeAreas);
44164
- const orderedNodes = ordering.order.map((nodeId) => targetNodes.find((n) => n.id === nodeId || n.nodeId === nodeId)).filter((n) => !!n);
44474
+ const orderedNodes = ordering.order.map((nodeId) => targetNodes.find((n) => meshNodeIdMatches(n, nodeId))).filter((n) => !!n);
44165
44475
  const dryRun = args?.dryRun !== false && args?.execute !== true;
44166
44476
  if (dryRun) {
44167
44477
  return {
@@ -44420,7 +44730,7 @@ ${hintLines.join("\n")}` : "",
44420
44730
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
44421
44731
  const mesh = meshRecord?.mesh;
44422
44732
  const allNodes = Array.isArray(mesh?.nodes) ? mesh.nodes : [];
44423
- const orderedNodes = nodeIds.map((id) => allNodes.find((n) => n.id === id || n.nodeId === id)).filter((n) => !!n);
44733
+ const orderedNodes = nodeIds.map((id) => allNodes.find((n) => meshNodeIdMatches(n, id))).filter((n) => !!n);
44424
44734
  if (orderedNodes.length === 0) {
44425
44735
  return { success: false, error: "Batch nodes no longer resolvable in mesh", batch: true };
44426
44736
  }
@@ -44526,7 +44836,7 @@ ${hintLines.join("\n")}` : "",
44526
44836
  const terminal = this.terminalRefineJobs.get(key);
44527
44837
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
44528
44838
  const mesh = meshRecord?.mesh;
44529
- const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
44839
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
44530
44840
  if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
44531
44841
  if (!node.isLocalWorktree || !node.workspace) return { success: false, error: `Refinery requires a local worktree node` };
44532
44842
  const coordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
@@ -44573,7 +44883,7 @@ ${hintLines.join("\n")}` : "",
44573
44883
  try {
44574
44884
  const { getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
44575
44885
  const meshObj = getMesh2(meshId) ?? this.getCachedInlineMesh(meshId);
44576
- const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => n.id === meshNodeId || n.nodeId === meshNodeId) : void 0;
44886
+ const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => meshNodeIdMatches(n, meshNodeId)) : void 0;
44577
44887
  const bootstrapStatus = readStringValue(nodeObj?.worktreeBootstrap?.status);
44578
44888
  if (bootstrapStatus === "running") {
44579
44889
  return { success: true, ...launchResult, bootstrapPending: true };
@@ -44618,7 +44928,7 @@ ${hintLines.join("\n")}` : "",
44618
44928
  try {
44619
44929
  const { getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
44620
44930
  const meshObj = getMesh2(dispatchMeshId) ?? this.getCachedInlineMesh(dispatchMeshId);
44621
- const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => n.id === dispatchNodeId || n.nodeId === dispatchNodeId) : void 0;
44931
+ const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => meshNodeIdMatches(n, dispatchNodeId)) : void 0;
44622
44932
  const bootstrapStatus = readStringValue(nodeObj?.worktreeBootstrap?.status);
44623
44933
  if (bootstrapStatus === "running") {
44624
44934
  return {
@@ -45883,7 +46193,7 @@ ${hintLines.join("\n")}` : "",
45883
46193
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
45884
46194
  const mesh = meshRecord?.mesh;
45885
46195
  if (!mesh) return { success: false, error: "Mesh not found" };
45886
- const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
46196
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
45887
46197
  if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
45888
46198
  const mode = this.normalizeMeshSessionCleanupMode(args?.mode ?? mesh?.policy?.sessionCleanupOnNodeRemove);
45889
46199
  const sessionIds = Array.isArray(args?.sessionIds) ? args.sessionIds.map((id) => typeof id === "string" ? id.trim() : "").filter(Boolean) : void 0;
@@ -45938,7 +46248,7 @@ ${hintLines.join("\n")}` : "",
45938
46248
  if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
45939
46249
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
45940
46250
  const mesh = meshRecord?.mesh;
45941
- const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
46251
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
45942
46252
  if (!node?.workspace) return { success: false, error: `Node '${nodeId}' workspace not found` };
45943
46253
  return {
45944
46254
  success: true,
@@ -45960,7 +46270,7 @@ ${hintLines.join("\n")}` : "",
45960
46270
  if (meshId && nodeId) {
45961
46271
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
45962
46272
  const mesh = meshRecord?.mesh;
45963
- const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
46273
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
45964
46274
  if (!workspace) {
45965
46275
  workspace = typeof node?.workspace === "string" ? node.workspace.trim() : "";
45966
46276
  }
@@ -46003,7 +46313,7 @@ ${hintLines.join("\n")}` : "",
46003
46313
  if (isDryRun) {
46004
46314
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
46005
46315
  const mesh = meshRecord?.mesh;
46006
- const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
46316
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
46007
46317
  if (!node?.workspace) return { success: false, error: `Node '${nodeId}' workspace not found` };
46008
46318
  return {
46009
46319
  success: true,
@@ -46033,7 +46343,7 @@ ${hintLines.join("\n")}` : "",
46033
46343
  try {
46034
46344
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
46035
46345
  const mesh = meshRecord?.mesh;
46036
- const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
46346
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
46037
46347
  if (node && !args?._meshDirectDispatch && node.isLocalWorktree !== true && args?.force !== true) {
46038
46348
  const nodeDaemonId = typeof node.daemonId === "string" ? node.daemonId.trim() : "";
46039
46349
  const nodeMachineId = readMeshNodeMachineId(node) || "";
@@ -46147,7 +46457,7 @@ ${hintLines.join("\n")}` : "",
46147
46457
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
46148
46458
  const mesh = meshRecord?.mesh;
46149
46459
  if (!mesh) return { success: false, error: "Mesh not found" };
46150
- const sourceNode = mesh.nodes?.find((n) => n.id === sourceNodeId || n.nodeId === sourceNodeId);
46460
+ const sourceNode = mesh.nodes?.find((n) => meshNodeIdMatches(n, sourceNodeId));
46151
46461
  if (!sourceNode) return { success: false, error: `Source node '${sourceNodeId}' not found in mesh` };
46152
46462
  const sourceDaemonId = typeof sourceNode.daemonId === "string" ? sourceNode.daemonId.trim() : void 0;
46153
46463
  if (sourceDaemonId && sourceDaemonId !== this.deps.statusInstanceId && this.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
@@ -46167,9 +46477,9 @@ ${hintLines.join("\n")}` : "",
46167
46477
  });
46168
46478
  let node;
46169
46479
  if (meshRecord.inline) {
46170
- const { randomUUID: randomUUID14 } = await import("crypto");
46480
+ const { randomUUID: randomUUID15 } = await import("crypto");
46171
46481
  node = {
46172
- id: `node_${randomUUID14().replace(/-/g, "")}`,
46482
+ id: `node_${randomUUID15().replace(/-/g, "")}`,
46173
46483
  workspace: result.worktreePath,
46174
46484
  repoRoot: result.worktreePath,
46175
46485
  daemonId: sourceNode.daemonId,
@@ -46388,7 +46698,7 @@ ${hintLines.join("\n")}` : "",
46388
46698
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
46389
46699
  const mesh = meshRecord?.mesh;
46390
46700
  if (!mesh) return { success: false, error: "Mesh not found" };
46391
- const node = mesh.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
46701
+ const node = mesh.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
46392
46702
  if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
46393
46703
  if (!node.isLocalWorktree) return { success: false, error: "Node is not a local worktree node" };
46394
46704
  const nodeDaemonId = typeof node.daemonId === "string" ? node.daemonId.trim() : void 0;
@@ -46525,14 +46835,14 @@ ${hintLines.join("\n")}` : "",
46525
46835
  const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
46526
46836
  const workspace = readLiveMeshNodeWorkspace({
46527
46837
  meshId,
46528
- nodeId: String(coordinatorNode.id || coordinatorNode.nodeId || preferredCoordinatorNodeId || ""),
46838
+ nodeId: String(normalizeMeshNodeId(coordinatorNode) || preferredCoordinatorNodeId || ""),
46529
46839
  liveSessionRecords: liveMeshSessions,
46530
46840
  allowCoordinatorSession: true
46531
46841
  }) || (typeof coordinatorNode.workspace === "string" ? coordinatorNode.workspace.trim() : "");
46532
46842
  if (!workspace) return { success: false, error: "Coordinator node workspace required", meshId, cliType };
46533
46843
  if (!cliType) {
46534
46844
  const resolved = await resolveProviderTypeFromPriority({
46535
- nodeId: String(coordinatorNode.id || coordinatorNode.nodeId || preferredCoordinatorNodeId || "coordinator"),
46845
+ nodeId: String(normalizeMeshNodeId(coordinatorNode) || preferredCoordinatorNodeId || "coordinator"),
46536
46846
  providerPriority: readProviderPriorityFromPolicy(coordinatorNode.policy),
46537
46847
  providerLoader: this.deps.providerLoader,
46538
46848
  onStatusChange: this.deps.onStatusChange
@@ -46943,10 +47253,11 @@ ${ptyResult.output.slice(-2e3)}`);
46943
47253
  if (!mesh) return { success: false, error: "Mesh not found" };
46944
47254
  const meshHost = resolveMeshHostStatus(mesh);
46945
47255
  const refreshRequested = args?.refresh === true || args?.forceRefresh === true;
47256
+ const verboseMissions = args?.verbose === true || args?.compact === false;
46946
47257
  const peekScope = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
46947
47258
  const pendingCoordinatorEventCount = getPendingMeshCoordinatorEvents(meshId, peekScope).length;
46948
47259
  const hadAggregateCache = this.aggregateMeshStatusCache.has(meshId);
46949
- if (!refreshRequested && pendingCoordinatorEventCount === 0) {
47260
+ if (!refreshRequested && !verboseMissions && pendingCoordinatorEventCount === 0) {
46950
47261
  const cachedStatus = this.getCachedAggregateMeshStatus(meshId, mesh, { requireDirectPeerTruth: args?.requireDirectPeerTruth === true });
46951
47262
  if (cachedStatus) {
46952
47263
  logRepoMeshStatusDebug("return_cached", {
@@ -46986,7 +47297,7 @@ ${ptyResult.output.slice(-2e3)}`);
46986
47297
  const passivePeerTruthNotAttempted = requireDirectPeerTruth && !refreshRequested && directTruth.directEvidenceCount > 0 && directTruth.peerAttemptedCount === 0;
46987
47298
  const effectiveDirectTruth = passivePeerTruthNotAttempted ? { ...directTruth, unavailableNodeIds: [] } : directTruth;
46988
47299
  const unavailableDirectTruthNodeIds = new Set(effectiveDirectTruth.unavailableNodeIds);
46989
- const unavailableNodesAreOnlyRemovedWorktrees = unavailableDirectTruthNodeIds.size > 0 && Array.isArray(mesh.nodes) && mesh.nodes.filter((node) => unavailableDirectTruthNodeIds.has(String(node.id || node.nodeId || ""))).every((node) => node?.isLocalWorktree === true);
47300
+ const unavailableNodesAreOnlyRemovedWorktrees = unavailableDirectTruthNodeIds.size > 0 && Array.isArray(mesh.nodes) && mesh.nodes.filter((node) => unavailableDirectTruthNodeIds.has(normalizeMeshNodeId(node) ?? "")).every((node) => node?.isLocalWorktree === true);
46990
47301
  const directTruthSatisfied = !requireDirectPeerTruth || effectiveDirectTruth.directEvidenceCount > 0 && (effectiveDirectTruth.unavailableNodeIds.length === 0 || unavailableNodesAreOnlyRemovedWorktrees);
46991
47302
  if (requireDirectPeerTruth && !directTruthSatisfied) {
46992
47303
  const failureResult = {
@@ -47021,14 +47332,13 @@ ${ptyResult.output.slice(-2e3)}`);
47021
47332
  const coordinatorHostname = osHostname();
47022
47333
  const selectedCoordinatorNodeId = readStringValue(
47023
47334
  mesh.coordinator?.preferredNodeId,
47024
- mesh.nodes?.[0]?.id,
47025
- mesh.nodes?.[0]?.nodeId
47335
+ normalizeMeshNodeId(mesh.nodes?.[0])
47026
47336
  );
47027
47337
  const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes) ? selectedCoordinatorNodeId : void 0;
47028
47338
  const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
47029
47339
  const nodeStatuses = [];
47030
47340
  for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
47031
- const nodeId = String(node.id || node.nodeId || "");
47341
+ const nodeId = normalizeMeshNodeId(node) ?? "";
47032
47342
  const daemonId = readStringValue(node.daemonId);
47033
47343
  const nodeMachineId = readMeshNodeMachineId(node);
47034
47344
  const nodeHostname = readMeshNodeHostname(node);
@@ -47250,7 +47560,7 @@ ${ptyResult.output.slice(-2e3)}`);
47250
47560
  liveSessionRecords: liveMeshSessions
47251
47561
  });
47252
47562
  const { getMeshStatusMissionSummaries: getMeshStatusMissionSummaries2 } = await Promise.resolve().then(() => (init_mesh_missions(), mesh_missions_exports));
47253
- const missions = getMeshStatusMissionSummaries2(meshId);
47563
+ const missions = getMeshStatusMissionSummaries2(meshId, { verbose: verboseMissions });
47254
47564
  const statusResult = {
47255
47565
  success: true,
47256
47566
  meshId: mesh.id,
@@ -47304,7 +47614,7 @@ ${ptyResult.output.slice(-2e3)}`);
47304
47614
  }))
47305
47615
  };
47306
47616
  const { pendingCoordinatorEvents: _pendingCoordinatorEvents, unroutableDeliveries: _unroutableDeliveries, ...cacheableStatusResult } = statusResult;
47307
- const rememberedStatus = this.rememberAggregateMeshStatus(meshId, cacheableStatusResult, refreshReason);
47617
+ const rememberedStatus = verboseMissions ? cacheableStatusResult : this.rememberAggregateMeshStatus(meshId, cacheableStatusResult, refreshReason);
47308
47618
  const returnedStatus = {
47309
47619
  ...rememberedStatus,
47310
47620
  ...pendingCoordinatorEvents.length > 0 ? { pendingCoordinatorEvents } : {},
@@ -54860,7 +55170,7 @@ var SessionHostPtyTransportFactory = class {
54860
55170
  };
54861
55171
 
54862
55172
  // src/cli-adapters/raw-terminal-io.ts
54863
- import { randomUUID as randomUUID13 } from "crypto";
55173
+ import { randomUUID as randomUUID14 } from "crypto";
54864
55174
  import {
54865
55175
  SessionHostClient as SessionHostClient2
54866
55176
  } from "@adhdev/session-host-core";
@@ -54960,7 +55270,7 @@ var RawTerminalAttachment = class _RawTerminalAttachment {
54960
55270
  const sessionId = String(options.sessionId || "").trim();
54961
55271
  if (!sessionId) throw new Error("sessionId is required");
54962
55272
  const mode = options.mode || "read";
54963
- 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)}`;
54964
55274
  const client = options.client || new SessionHostClient2({ endpoint: options.endpoint });
54965
55275
  await client.connect();
54966
55276
  const attachResponse = await client.request({