@adhdev/daemon-standalone 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.js CHANGED
@@ -29983,10 +29983,10 @@ var require_dist3 = __commonJS({
29983
29983
  }
29984
29984
  function getDaemonBuildInfo() {
29985
29985
  if (cached2) return cached2;
29986
- const commit = readInjected(true ? "396cb9c4084ea658cd3606b76948987cd875f138" : void 0) ?? "unknown";
29987
- const commitShort = readInjected(true ? "396cb9c4" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
29988
- const version2 = readInjected(true ? "0.9.82-rc.291" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
29989
- const builtAt = readInjected(true ? "2026-06-16T06:43:03.621Z" : void 0);
29986
+ const commit = readInjected(true ? "88f97abcc85d83fe5d5313b229d32a7d76b1208a" : void 0) ?? "unknown";
29987
+ const commitShort = readInjected(true ? "88f97abc" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
29988
+ const version2 = readInjected(true ? "0.9.82-rc.293" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
29989
+ const builtAt = readInjected(true ? "2026-06-16T11:14:20.929Z" : void 0);
29990
29990
  cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
29991
29991
  return cached2;
29992
29992
  }
@@ -30055,6 +30055,15 @@ var require_dist3 = __commonJS({
30055
30055
  );
30056
30056
  }
30057
30057
  }
30058
+ function isNonRuntimeRootFile(file2) {
30059
+ const base = file2.slice(file2.lastIndexOf("/") + 1);
30060
+ if (/^\.(?:verify|marker|converge|ff-verify|patch-equiv|live-verify)\b/i.test(base)) return true;
30061
+ if (/(?:^|\/)docs\//i.test(file2)) return true;
30062
+ if (/^(?:README|CHANGELOG|LICENSE|NOTICE|AUTHORS|CONTRIBUTING|CODEOWNERS)(?:\.[A-Za-z0-9]+)?$/i.test(base)) {
30063
+ return true;
30064
+ }
30065
+ return false;
30066
+ }
30058
30067
  async function classifyDaemonBuildChange(repoPath, buildCommit, options) {
30059
30068
  try {
30060
30069
  const diff = await runGit(repoPath, ["diff", "--name-only", `${buildCommit}..HEAD`], options);
@@ -30063,18 +30072,18 @@ var require_dist3 = __commonJS({
30063
30072
  return { isDaemonAffecting: true, affectedPackages: [] };
30064
30073
  }
30065
30074
  const pkgs = /* @__PURE__ */ new Set();
30066
- let sawNonPackageOrUnknown = false;
30075
+ let sawRuntimeAmbiguousNonPackage = false;
30067
30076
  for (const file2 of files) {
30068
30077
  const match = file2.match(/(?:^|\/)packages\/([^/]+)\//);
30069
30078
  if (!match) {
30070
- sawNonPackageOrUnknown = true;
30079
+ if (!isNonRuntimeRootFile(file2)) sawRuntimeAmbiguousNonPackage = true;
30071
30080
  continue;
30072
30081
  }
30073
30082
  pkgs.add(match[1]);
30074
30083
  }
30075
30084
  const affectedPackages = [...pkgs].sort();
30076
- const allWebOnly = !sawNonPackageOrUnknown && affectedPackages.length > 0 && affectedPackages.every((p) => WEB_ONLY_PACKAGES.has(p) && !DAEMON_RUNTIME_PACKAGES.has(p));
30077
- return { isDaemonAffecting: !allWebOnly, affectedPackages };
30085
+ const allBenign = !sawRuntimeAmbiguousNonPackage && affectedPackages.every((p) => WEB_ONLY_PACKAGES.has(p) && !DAEMON_RUNTIME_PACKAGES.has(p));
30086
+ return { isDaemonAffecting: !allBenign, affectedPackages };
30078
30087
  } catch {
30079
30088
  return { isDaemonAffecting: true, affectedPackages: [] };
30080
30089
  }
@@ -30101,7 +30110,8 @@ var require_dist3 = __commonJS({
30101
30110
  options
30102
30111
  );
30103
30112
  const scopeLabel = scope === "root" ? "workspace" : scope;
30104
- 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.`;
30113
+ const benignDetail = affectedPackages.length > 0 ? `only web packages changed (${affectedPackages.join(", ")})` : "only non-runtime files changed (markers/docs)";
30114
+ 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.`;
30105
30115
  return {
30106
30116
  buildCommit: build.commit,
30107
30117
  buildCommitShort: build.commitShort,
@@ -31713,7 +31723,7 @@ ${rules.join("\n")}`;
31713
31723
  - **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.
31714
31724
  - **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.
31715
31725
  - **Verify via git, not source.** Use \`mesh_git_status\` to confirm side effects. Treat agent summaries as self-reports, not verification.
31716
- - **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.
31726
+ - **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).
31717
31727
  - **Check history first.** Call \`mesh_task_history\` at session start to avoid duplicate work and inform recovery. On failure, read task history before retrying.
31718
31728
  - **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\`.
31719
31729
  - **Refinery is config-driven.** \`mesh_refine_node\` must run validation from \`.adhdev/refine.{json,yaml,yml}\` or \`repo-mesh.refine.*\`. Heuristics are scaffolding only.
@@ -31772,7 +31782,7 @@ Before doing any coordinator work, confirm that the actual callable tool list in
31772
31782
  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.
31773
31783
  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.
31774
31784
  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.
31775
- 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\`.
31785
+ 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.
31776
31786
  5. **Verify** \u2014 When a task reports completion or git work is visible, call \`mesh_git_status\` to verify changes were made.
31777
31787
  6. **Checkpoint** \u2014 Call \`mesh_checkpoint\` to save the work.
31778
31788
  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.
@@ -34138,11 +34148,40 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
34138
34148
  ).get(meshId);
34139
34149
  return row?.cnt ?? 0;
34140
34150
  }
34151
+ /**
34152
+ * Mark specific pending-event rows drained by id (ack). Used by the
34153
+ * unresolved-delegate durable-forward outbox: an event is peeked (not drained)
34154
+ * while its push to the coordinator is unconfirmed, then marked drained ONLY
34155
+ * after the push is acked. A failed push leaves the row undrained so the next
34156
+ * reconcile tick retries it. Returns the number of rows newly marked drained.
34157
+ */
34158
+ markPendingEventsDrainedById(ids) {
34159
+ const idList = ids.filter((id) => typeof id === "string" && id.length > 0);
34160
+ if (idList.length === 0) return 0;
34161
+ const now = Date.now();
34162
+ return this.db.prepare(
34163
+ `UPDATE mesh_pending_events SET drained = 1, drained_at = ? WHERE drained = 0 AND id IN (${idList.map(() => "?").join(",")})`
34164
+ ).run(now, ...idList).changes;
34165
+ }
34166
+ /**
34167
+ * Hard-delete pending-event rows by id (including the dedup fingerprint history).
34168
+ * Used to expire an unresolved-delegate outbox entry that has exhausted its retry
34169
+ * budget — fully removing it frees the fingerprint so a genuinely new completion
34170
+ * for the same task could be re-queued later. Returns the number of rows deleted.
34171
+ */
34172
+ deletePendingEventsById(ids) {
34173
+ const idList = ids.filter((id) => typeof id === "string" && id.length > 0);
34174
+ if (idList.length === 0) return 0;
34175
+ return this.db.prepare(
34176
+ `DELETE FROM mesh_pending_events WHERE id IN (${idList.map(() => "?").join(",")})`
34177
+ ).run(...idList).changes;
34178
+ }
34141
34179
  };
34142
34180
  }
34143
34181
  });
34144
34182
  var mesh_missions_exports = {};
34145
34183
  __export2(mesh_missions_exports, {
34184
+ GOAL_PREVIEW_MAX: () => GOAL_PREVIEW_MAX,
34146
34185
  MESH_MISSION_STATUSES: () => MESH_MISSION_STATUSES,
34147
34186
  buildMissionPromptSection: () => buildMissionPromptSection,
34148
34187
  getActiveMeshMissionSummaries: () => getActiveMeshMissionSummaries,
@@ -34214,12 +34253,23 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
34214
34253
  function getActiveMeshMissionSummaries(meshId) {
34215
34254
  return getMeshMissions(meshId, ["active"]).map((mission) => summarizeMeshMission(meshId, mission));
34216
34255
  }
34256
+ function slimMissionSummary(summary) {
34257
+ const goal = typeof summary.goal === "string" ? summary.goal : "";
34258
+ const goalTruncated = goal.length > GOAL_PREVIEW_MAX;
34259
+ const { goal: _omitGoal, ...rest } = summary;
34260
+ return {
34261
+ ...rest,
34262
+ goalPreview: goalTruncated ? goal.slice(0, GOAL_PREVIEW_MAX) : goal,
34263
+ goalTruncated
34264
+ };
34265
+ }
34217
34266
  function getMeshStatusMissionSummaries(meshId, options) {
34218
34267
  const historyLimit = Math.max(0, options?.historyLimit ?? 10);
34219
34268
  const all = getMeshMissions(meshId);
34220
34269
  const live = all.filter((m) => m.status === "active" || m.status === "paused");
34221
34270
  const history = all.filter((m) => m.status === "completed" || m.status === "abandoned").sort((a, b) => (b.updatedAt || "").localeCompare(a.updatedAt || "")).slice(0, historyLimit);
34222
- return [...live, ...history].map((mission) => summarizeMeshMission(meshId, mission));
34271
+ const full = [...live, ...history].map((mission) => summarizeMeshMission(meshId, mission));
34272
+ return options?.verbose ? full : full.map(slimMissionSummary);
34223
34273
  }
34224
34274
  function buildMissionPromptSection(meshId) {
34225
34275
  const summaries = getActiveMeshMissionSummaries(meshId);
@@ -34241,6 +34291,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
34241
34291
  }
34242
34292
  var import_crypto6;
34243
34293
  var MESH_MISSION_STATUSES;
34294
+ var GOAL_PREVIEW_MAX;
34244
34295
  var init_mesh_missions = __esm2({
34245
34296
  "src/mesh/mesh-missions.ts"() {
34246
34297
  "use strict";
@@ -34248,6 +34299,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
34248
34299
  init_mesh_runtime_store();
34249
34300
  init_mesh_work_queue();
34250
34301
  MESH_MISSION_STATUSES = ["active", "paused", "completed", "abandoned"];
34302
+ GOAL_PREVIEW_MAX = 120;
34251
34303
  }
34252
34304
  });
34253
34305
  function readString3(value) {
@@ -35944,10 +35996,222 @@ ${rendered}`, "utf-8");
35944
35996
  STATUS_OPTIONS = { refreshUpstream: true, includeSubmodules: true, timeoutMs: 15e3 };
35945
35997
  }
35946
35998
  });
35999
+ function readRecord3(value) {
36000
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
36001
+ }
36002
+ function readString5(...values) {
36003
+ for (const value of values) {
36004
+ if (typeof value !== "string") continue;
36005
+ const trimmed = value.trim();
36006
+ if (trimmed) return trimmed;
36007
+ }
36008
+ return void 0;
36009
+ }
36010
+ function readNumber(...values) {
36011
+ for (const value of values) {
36012
+ if (typeof value === "number" && Number.isFinite(value)) return value;
36013
+ }
36014
+ return void 0;
36015
+ }
36016
+ function readBoolean(...values) {
36017
+ for (const value of values) {
36018
+ if (typeof value === "boolean") return value;
36019
+ }
36020
+ return void 0;
36021
+ }
36022
+ function joinRepoPath(root, relativePath) {
36023
+ const normalizedRoot = typeof root === "string" ? root.trim().replace(/[\\/]+$/, "") : "";
36024
+ const normalizedPath = typeof relativePath === "string" ? relativePath.trim() : "";
36025
+ if (!normalizedPath) return void 0;
36026
+ if (/^(?:[A-Za-z]:[\\/]|\/)/.test(normalizedPath)) return normalizedPath;
36027
+ if (!normalizedRoot) return void 0;
36028
+ return `${normalizedRoot}/${normalizedPath.replace(/^[\\/]+/, "")}`;
36029
+ }
36030
+ function scoreGitUpstreamFreshness(status) {
36031
+ switch (status) {
36032
+ case "fresh":
36033
+ return 30;
36034
+ case "no_upstream":
36035
+ return 4;
36036
+ case "unchecked":
36037
+ case void 0:
36038
+ return 0;
36039
+ case "stale":
36040
+ return -10;
36041
+ case "unavailable":
36042
+ return -15;
36043
+ default:
36044
+ return 0;
36045
+ }
36046
+ }
36047
+ function readGitSubmodules(value, parentRepoRoot) {
36048
+ if (!Array.isArray(value)) return void 0;
36049
+ const submodules = value.map((entry) => {
36050
+ const submodule = readRecord3(entry);
36051
+ const path40 = readString5(submodule.path);
36052
+ const commit = readString5(submodule.commit);
36053
+ const repoPath = readString5(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot, path40);
36054
+ if (!path40 || !commit) return null;
36055
+ const result = {
36056
+ path: path40,
36057
+ commit,
36058
+ dirty: readBoolean(submodule.dirty) ?? false,
36059
+ outOfSync: readBoolean(submodule.outOfSync, submodule.out_of_sync) ?? false,
36060
+ lastCheckedAt: readNumber(submodule.lastCheckedAt, submodule.last_checked_at) ?? Date.now()
36061
+ };
36062
+ if (repoPath) result.repoPath = repoPath;
36063
+ const error48 = readString5(submodule.error);
36064
+ if (error48) result.error = error48;
36065
+ return result;
36066
+ }).filter((entry) => entry !== null);
36067
+ return submodules.length > 0 ? submodules : void 0;
36068
+ }
36069
+ function hasGitStatusEvidence(status) {
36070
+ 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(
36071
+ status.ahead,
36072
+ status.behind,
36073
+ status.staged,
36074
+ status.modified,
36075
+ status.untracked,
36076
+ status.deleted,
36077
+ status.renamed,
36078
+ status.lastCheckedAt,
36079
+ status.last_checked_at
36080
+ ) !== void 0 || Array.isArray(status.submodules) && status.submodules.length > 0;
36081
+ }
36082
+ function normalizeGitStatus(status, node, options) {
36083
+ const explicitIsGitRepo = readBoolean(status.isGitRepo);
36084
+ if (!Object.keys(status).length || !hasGitStatusEvidence(status)) return void 0;
36085
+ const isGitRepo = explicitIsGitRepo ?? true;
36086
+ const conflictFiles = Array.isArray(status.conflictFiles) ? status.conflictFiles.filter((entry) => typeof entry === "string") : [];
36087
+ const conflictCount = readNumber(status.conflicts) ?? conflictFiles.length;
36088
+ const hasConflicts = readBoolean(status.hasConflicts) ?? conflictCount > 0;
36089
+ const repoRoot = readString5(status.repoRoot, status.repo_root, node.repoRoot, node.repo_root, status.workspace, node.workspace) || void 0;
36090
+ const submodules = readGitSubmodules(status.submodules, repoRoot);
36091
+ const upstreamStatus = readString5(status.upstreamStatus, status.upstream_status);
36092
+ const upstreamFetchedAt = readNumber(status.upstreamFetchedAt, status.upstream_fetched_at);
36093
+ const upstreamFetchError = readString5(status.upstreamFetchError, status.upstream_fetch_error);
36094
+ const error48 = readString5(status.error);
36095
+ const staged = readNumber(status.staged) ?? 0;
36096
+ const modified = readNumber(status.modified) ?? 0;
36097
+ const untracked = readNumber(status.untracked) ?? 0;
36098
+ const deleted = readNumber(status.deleted) ?? 0;
36099
+ const renamed = readNumber(status.renamed) ?? 0;
36100
+ return {
36101
+ workspace: readString5(status.workspace, node.workspace) || "",
36102
+ repoRoot: repoRoot ?? null,
36103
+ isGitRepo,
36104
+ branch: readString5(status.branch) ?? null,
36105
+ headCommit: readString5(status.headCommit) ?? null,
36106
+ headMessage: readString5(status.headMessage) ?? null,
36107
+ upstream: readString5(status.upstream) ?? null,
36108
+ upstreamStatus: upstreamStatus ?? "unchecked",
36109
+ ...upstreamFetchedAt !== void 0 ? { upstreamFetchedAt } : {},
36110
+ ...upstreamFetchError ? { upstreamFetchError } : {},
36111
+ ahead: readNumber(status.ahead) ?? 0,
36112
+ behind: readNumber(status.behind) ?? 0,
36113
+ staged,
36114
+ modified,
36115
+ untracked,
36116
+ deleted,
36117
+ renamed,
36118
+ dirty: readBoolean(status.dirty, status.isDirty, status.is_dirty) ?? (staged + modified + untracked + deleted + renamed > 0 || hasConflicts),
36119
+ hasConflicts,
36120
+ conflictFiles,
36121
+ stashCount: readNumber(status.stashCount, status.stash_count) ?? 0,
36122
+ lastCheckedAt: options?.lastCheckedAt ?? readNumber(status.lastCheckedAt, status.last_checked_at) ?? Date.now(),
36123
+ ...submodules ? { submodules } : {},
36124
+ ...error48 ? { error: error48 } : {}
36125
+ };
36126
+ }
36127
+ function scoreGitStatusCandidate(git) {
36128
+ if (!git) return Number.NEGATIVE_INFINITY;
36129
+ let score = 0;
36130
+ if (git.isGitRepo === true) score += 50;
36131
+ if (git.isGitRepo === false) score -= 10;
36132
+ if (git.branch) score += 20;
36133
+ if (git.headCommit) score += 20;
36134
+ if (git.upstream) score += 10;
36135
+ score += scoreGitUpstreamFreshness(git.upstreamStatus);
36136
+ if (typeof git.ahead === "number") score += 2;
36137
+ if (typeof git.behind === "number") score += 2;
36138
+ if (Array.isArray(git.submodules) && git.submodules.length > 0) score += 4 + git.submodules.length;
36139
+ if (git.error) score -= 20;
36140
+ return score;
36141
+ }
36142
+ function pickBestTransitGitStatus(node, options) {
36143
+ const rawGit = readRecord3(node.lastGit ?? node.last_git);
36144
+ const gitResult = readRecord3(rawGit.result);
36145
+ const directStatus = readRecord3(rawGit.status);
36146
+ const nestedStatus = readRecord3(gitResult.status);
36147
+ const rawProbe = readRecord3(node.lastProbe ?? node.last_probe);
36148
+ const probeGit = readRecord3(rawProbe.git);
36149
+ const probeGitResult = readRecord3(probeGit.result);
36150
+ const probeDirectStatus = readRecord3(probeGit.status);
36151
+ const probeNestedStatus = readRecord3(probeGitResult.status);
36152
+ const lastCheckedAt = options?.lastCheckedAt;
36153
+ let best = null;
36154
+ for (const status of [directStatus, nestedStatus, probeDirectStatus, probeNestedStatus]) {
36155
+ const normalized = normalizeGitStatus(status, node, { lastCheckedAt: lastCheckedAt ?? Date.now() });
36156
+ if (!normalized) continue;
36157
+ const score = scoreGitStatusCandidate(normalized);
36158
+ if (!best || score > best.score) best = { git: normalized, score };
36159
+ }
36160
+ return best?.git;
36161
+ }
36162
+ function normalizeMeshNodeId(node) {
36163
+ const record2 = node && typeof node === "object" ? node : {};
36164
+ return readString5(record2.id, record2.nodeId, record2.node_id);
36165
+ }
36166
+ function meshNodeIdMatches(node, candidateId) {
36167
+ if (!candidateId) return false;
36168
+ const trimmed = candidateId.trim();
36169
+ if (!trimmed) return false;
36170
+ return normalizeMeshNodeId(node) === trimmed;
36171
+ }
36172
+ function summarizeGitShape(status) {
36173
+ const record2 = readRecord3(status);
36174
+ if (!Object.keys(record2).length) return null;
36175
+ const submodules = Array.isArray(record2.submodules) ? record2.submodules.map((entry) => {
36176
+ const sub = readRecord3(entry);
36177
+ return {
36178
+ path: readString5(sub.path) ?? null,
36179
+ commit: readString5(sub.commit)?.slice(0, 12) ?? null,
36180
+ dirty: readBoolean(sub.dirty) ?? false,
36181
+ outOfSync: readBoolean(sub.outOfSync, sub.out_of_sync) ?? false
36182
+ };
36183
+ }) : [];
36184
+ return {
36185
+ isGitRepo: readBoolean(record2.isGitRepo),
36186
+ workspace: readString5(record2.workspace) ?? null,
36187
+ repoRoot: readString5(record2.repoRoot, record2.repo_root) ?? null,
36188
+ branch: readString5(record2.branch) ?? null,
36189
+ upstream: readString5(record2.upstream) ?? null,
36190
+ upstreamStatus: readString5(record2.upstreamStatus, record2.upstream_status) ?? null,
36191
+ headCommit: readString5(record2.headCommit, record2.head_commit)?.slice(0, 12) ?? null,
36192
+ ahead: readNumber(record2.ahead) ?? null,
36193
+ behind: readNumber(record2.behind) ?? null,
36194
+ dirtyCounts: {
36195
+ staged: readNumber(record2.staged) ?? 0,
36196
+ modified: readNumber(record2.modified) ?? 0,
36197
+ untracked: readNumber(record2.untracked) ?? 0,
36198
+ deleted: readNumber(record2.deleted) ?? 0,
36199
+ renamed: readNumber(record2.renamed) ?? 0
36200
+ },
36201
+ lastCheckedAt: readNumber(record2.lastCheckedAt, record2.last_checked_at) ?? null,
36202
+ submoduleCount: submodules.length,
36203
+ submodules
36204
+ };
36205
+ }
36206
+ var init_dist = __esm2({
36207
+ "../mesh-shared/dist/index.mjs"() {
36208
+ "use strict";
36209
+ }
36210
+ });
35947
36211
  function readNonEmptyString2(value) {
35948
36212
  return typeof value === "string" && value.trim() ? value.trim() : "";
35949
36213
  }
35950
- function readRecord3(value) {
36214
+ function readRecord4(value) {
35951
36215
  return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
35952
36216
  }
35953
36217
  function buildMeshWorkerRelayStamp(currentSettings, meshContext) {
@@ -35971,13 +36235,13 @@ ${rendered}`, "utf-8");
35971
36235
  return readNonEmptyString2(event.targetSessionId) || readNonEmptyString2(event.sessionId) || readNonEmptyString2(event.instanceId) || readNonEmptyString2(fallback);
35972
36236
  }
35973
36237
  function readRefineJobId(event) {
35974
- const metadata = readRecord3(event.metadataEvent) || event;
35975
- const result = readRecord3(metadata.result);
35976
- const refineJob = readRecord3(result?.refineJob);
36238
+ const metadata = readRecord4(event.metadataEvent) || event;
36239
+ const result = readRecord4(metadata.result);
36240
+ const refineJob = readRecord4(result?.refineJob);
35977
36241
  return readNonEmptyString2(metadata.jobId) || readNonEmptyString2(refineJob?.jobId);
35978
36242
  }
35979
36243
  function readWorkerResultMetadata(event) {
35980
- return readRecord3(event.workerResult) || readRecord3(event.meshWorkerResult) || readRecord3(event.structuredResult);
36244
+ return readRecord4(event.workerResult) || readRecord4(event.meshWorkerResult) || readRecord4(event.structuredResult);
35981
36245
  }
35982
36246
  function formatCompletionMetadata(event) {
35983
36247
  const completionDiagnostic = event.completionDiagnostic && typeof event.completionDiagnostic === "object" ? event.completionDiagnostic : null;
@@ -36055,10 +36319,10 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
36055
36319
  }
36056
36320
  if (args.event === "refine:completed") {
36057
36321
  const jobId = readRefineJobId({ metadataEvent: args.metadataEvent });
36058
- const result = readRecord3(args.metadataEvent.result);
36059
- const validationSummary = readRecord3(result?.validationSummary);
36060
- const patchEquivalence = readRecord3(result?.patchEquivalence);
36061
- const finalConvergence = readRecord3(result?.finalBranchConvergenceState);
36322
+ const result = readRecord4(args.metadataEvent.result);
36323
+ const validationSummary = readRecord4(result?.validationSummary);
36324
+ const patchEquivalence = readRecord4(result?.patchEquivalence);
36325
+ const finalConvergence = readRecord4(result?.finalBranchConvergenceState);
36062
36326
  const validationStatus = readNonEmptyString2(validationSummary?.status);
36063
36327
  const patchStatus = readNonEmptyString2(patchEquivalence?.status) || (patchEquivalence?.equivalent === true ? "passed" : "");
36064
36328
  const into = readNonEmptyString2(result?.into);
@@ -36079,10 +36343,10 @@ Next step: ${nextStep}`;
36079
36343
  }
36080
36344
  if (args.event === "refine:failed") {
36081
36345
  const jobId = readRefineJobId({ metadataEvent: args.metadataEvent });
36082
- const result = readRecord3(args.metadataEvent.result);
36083
- const validationSummary = readRecord3(result?.validationSummary);
36084
- const patchEquivalence = readRecord3(result?.patchEquivalence);
36085
- const finalConvergence = readRecord3(result?.finalBranchConvergenceState);
36346
+ const result = readRecord4(args.metadataEvent.result);
36347
+ const validationSummary = readRecord4(result?.validationSummary);
36348
+ const patchEquivalence = readRecord4(result?.patchEquivalence);
36349
+ const finalConvergence = readRecord4(result?.finalBranchConvergenceState);
36086
36350
  const code = readNonEmptyString2(result?.code);
36087
36351
  const error48 = readNonEmptyString2(result?.error);
36088
36352
  const validationStatus = readNonEmptyString2(validationSummary?.status);
@@ -36127,9 +36391,9 @@ Next step: ${nextStep}`;
36127
36391
  return out;
36128
36392
  }
36129
36393
  function readRefineJobId2(event) {
36130
- const metadata = readRecord3(event.metadataEvent) || event;
36131
- const result = readRecord3(metadata.result);
36132
- const refineJob = readRecord3(result?.refineJob);
36394
+ const metadata = readRecord4(event.metadataEvent) || event;
36395
+ const result = readRecord4(metadata.result);
36396
+ const refineJob = readRecord4(result?.refineJob);
36133
36397
  return readNonEmptyString2(metadata.jobId) || readNonEmptyString2(refineJob?.jobId);
36134
36398
  }
36135
36399
  function hasPendingRefineTerminalEventDuplicate(event) {
@@ -36141,13 +36405,13 @@ Next step: ${nextStep}`;
36141
36405
  );
36142
36406
  }
36143
36407
  function buildPendingEventFingerprint(event) {
36144
- const metadata = readRecord3(event.metadataEvent) || {};
36408
+ const metadata = readRecord4(event.metadataEvent) || {};
36145
36409
  if (event.event === "worktree_bootstrap_complete" || event.event === "worktree_bootstrap_failed") {
36146
36410
  return [event.meshId, event.event, event.nodeId || ""].join("::");
36147
36411
  }
36148
36412
  const sessionId = resolveEventSessionId(metadata);
36149
36413
  const providerSessionId = readNonEmptyString2(metadata.providerSessionId);
36150
- const taskId = readNonEmptyString2(metadata.taskId) || readNonEmptyString2(readRecord3(metadata.payload)?.taskId);
36414
+ const taskId = readNonEmptyString2(metadata.taskId) || readNonEmptyString2(readRecord4(metadata.payload)?.taskId);
36151
36415
  const jobId = readRefineJobId2(event);
36152
36416
  const timestamp = metadata.timestamp !== void 0 && metadata.timestamp !== null ? String(metadata.timestamp) : "";
36153
36417
  return [
@@ -36215,15 +36479,15 @@ Next step: ${nextStep}`;
36215
36479
  for (let i = entries.length - 1; i >= 0; i--) {
36216
36480
  const entry = entries[i];
36217
36481
  if (entry.kind !== "task_completed" && entry.kind !== "task_failed") continue;
36218
- const payload = readRecord3(entry.payload);
36482
+ const payload = readRecord4(entry.payload);
36219
36483
  if (payload?.source !== "refine_mesh_node_async_job") continue;
36220
- const refineJob = readRecord3(payload.refineJob);
36484
+ const refineJob = readRecord4(payload.refineJob);
36221
36485
  const jobId = readNonEmptyString2(refineJob?.jobId);
36222
36486
  if (!jobId || !acceptedJobIds.has(jobId)) continue;
36223
36487
  const eventName = entry.kind === "task_completed" ? "refine:completed" : "refine:failed";
36224
36488
  if (existingTerminalJobIds.has(`${eventName}:${jobId}`)) continue;
36225
36489
  existingTerminalJobIds.add(`${eventName}:${jobId}`);
36226
- const result = readRecord3(payload.result);
36490
+ const result = readRecord4(payload.result);
36227
36491
  const metadataEvent = {
36228
36492
  source: "refine_mesh_node_async_job",
36229
36493
  jobId,
@@ -36835,7 +37099,7 @@ Next step: ${nextStep}`;
36835
37099
  const providerType = readNonEmptyString2(args.metadataEvent.providerType);
36836
37100
  const providerSessionId = readNonEmptyString2(args.metadataEvent.providerSessionId);
36837
37101
  const workerResult = readWorkerResultMetadata(args.metadataEvent);
36838
- const completionDiagnostic = readRecord3(args.metadataEvent.completionDiagnostic);
37102
+ const completionDiagnostic = readRecord4(args.metadataEvent.completionDiagnostic);
36839
37103
  const finalSummary = readNonEmptyString2(args.metadataEvent.finalSummary);
36840
37104
  const status = readNonEmptyString2(args.metadataEvent.status).toLowerCase();
36841
37105
  const explicitCompletionEvidence = Boolean(
@@ -37151,6 +37415,111 @@ Next step: ${nextStep}`;
37151
37415
  recentUnroutableDiagnostics = /* @__PURE__ */ new Map();
37152
37416
  }
37153
37417
  });
37418
+ function getStore() {
37419
+ try {
37420
+ return MeshRuntimeStore.getInstance();
37421
+ } catch {
37422
+ return void 0;
37423
+ }
37424
+ }
37425
+ function enqueueUnresolvedDelegateForward(coordinatorDaemonId, eventName, forwardPayload) {
37426
+ const target = readNonEmptyString2(coordinatorDaemonId);
37427
+ const event = readNonEmptyString2(eventName);
37428
+ if (!target || !event) return false;
37429
+ const store = getStore();
37430
+ if (!store) return false;
37431
+ const queuedAt = Date.now();
37432
+ const fingerprintSource = {
37433
+ event,
37434
+ meshId: UNRESOLVED_FORWARD_OUTBOX_MESH_ID,
37435
+ nodeLabel: readNonEmptyString2(forwardPayload.nodeId) || readNonEmptyString2(forwardPayload.workspace) || "unresolved-delegate",
37436
+ nodeId: readNonEmptyString2(forwardPayload.nodeId) || void 0,
37437
+ workspace: readNonEmptyString2(forwardPayload.workspace) || void 0,
37438
+ metadataEvent: forwardPayload,
37439
+ queuedAt,
37440
+ targetCoordinatorDaemonId: target
37441
+ };
37442
+ const fingerprint = `${target}::${buildPendingEventFingerprint(fingerprintSource)}`;
37443
+ try {
37444
+ const inserted = store.insertPendingEvent({
37445
+ id: (0, import_crypto9.randomUUID)(),
37446
+ meshId: UNRESOLVED_FORWARD_OUTBOX_MESH_ID,
37447
+ coordinatorDaemonId: target,
37448
+ event,
37449
+ // Store the flat forward payload + the queue timestamp so the retry tick can
37450
+ // rebuild the push args and apply age-based expiry without a schema change.
37451
+ payload: { forwardPayload, coordinatorDaemonId: target, queuedAt },
37452
+ fingerprint,
37453
+ queuedAt
37454
+ });
37455
+ if (inserted) {
37456
+ LOG2.info("MeshEvents", `Durably queued unresolved-delegate ${event} for coordinator ${target} (outbox)`);
37457
+ }
37458
+ return true;
37459
+ } catch (e) {
37460
+ LOG2.warn("MeshEvents", `Failed to persist unresolved-delegate forward to outbox: ${e?.message || e}`);
37461
+ return false;
37462
+ }
37463
+ }
37464
+ function peekUnresolvedDelegateForwards() {
37465
+ const store = getStore();
37466
+ if (!store) return [];
37467
+ let rows;
37468
+ try {
37469
+ rows = store.peekPendingEvents(UNRESOLVED_FORWARD_OUTBOX_MESH_ID);
37470
+ } catch {
37471
+ return [];
37472
+ }
37473
+ const out = [];
37474
+ for (const row of rows) {
37475
+ const stored = row.payload && typeof row.payload === "object" ? row.payload : {};
37476
+ const coordinatorDaemonId = readNonEmptyString2(stored.coordinatorDaemonId);
37477
+ const forwardPayload = stored.forwardPayload && typeof stored.forwardPayload === "object" ? stored.forwardPayload : void 0;
37478
+ if (!coordinatorDaemonId || !forwardPayload) continue;
37479
+ const queuedAt = typeof stored.queuedAt === "number" ? stored.queuedAt : 0;
37480
+ out.push({ id: row.id, coordinatorDaemonId, payload: forwardPayload, queuedAt });
37481
+ }
37482
+ return out;
37483
+ }
37484
+ function ackUnresolvedDelegateForward(id) {
37485
+ const store = getStore();
37486
+ if (!store) return;
37487
+ try {
37488
+ store.markPendingEventsDrainedById([id]);
37489
+ } catch {
37490
+ }
37491
+ }
37492
+ function expireStaleUnresolvedDelegateForwards(nowMs = Date.now()) {
37493
+ const entries = peekUnresolvedDelegateForwards();
37494
+ const staleIds = entries.filter((e) => e.queuedAt > 0 && nowMs - e.queuedAt >= UNRESOLVED_FORWARD_MAX_AGE_MS).map((e) => e.id);
37495
+ if (staleIds.length === 0) return 0;
37496
+ const store = getStore();
37497
+ if (!store) return 0;
37498
+ try {
37499
+ const removed = store.deletePendingEventsById(staleIds);
37500
+ if (removed > 0) {
37501
+ LOG2.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`);
37502
+ }
37503
+ return removed;
37504
+ } catch {
37505
+ return 0;
37506
+ }
37507
+ }
37508
+ var import_crypto9;
37509
+ var UNRESOLVED_FORWARD_OUTBOX_MESH_ID;
37510
+ var UNRESOLVED_FORWARD_MAX_AGE_MS;
37511
+ var init_mesh_unresolved_forward_outbox = __esm2({
37512
+ "src/mesh/mesh-unresolved-forward-outbox.ts"() {
37513
+ "use strict";
37514
+ import_crypto9 = require("crypto");
37515
+ init_logger();
37516
+ init_mesh_runtime_store();
37517
+ init_mesh_events_pending();
37518
+ init_mesh_events_utils();
37519
+ UNRESOLVED_FORWARD_OUTBOX_MESH_ID = "__unresolved_forward_outbox__";
37520
+ UNRESOLVED_FORWARD_MAX_AGE_MS = 30 * 60 * 1e3;
37521
+ }
37522
+ });
37154
37523
  function resolveCoordinatorDrainDaemonIds(components) {
37155
37524
  const ids = /* @__PURE__ */ new Set();
37156
37525
  const statusInstanceId = readNonEmptyString2(components.statusInstanceId);
@@ -37554,7 +37923,7 @@ Next step: ${nextStep}`;
37554
37923
  return { reason: `provider_priority_unusable: ${failed.join("; ") || nodeId}` };
37555
37924
  }
37556
37925
  function readMeshNodeId(node) {
37557
- return readNonEmptyString2(node?.id) || readNonEmptyString2(node?.nodeId) || readNonEmptyString2(node?.node_id);
37926
+ return normalizeMeshNodeId(node) ?? "";
37558
37927
  }
37559
37928
  async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
37560
37929
  const queue = getQueue(meshId);
@@ -37783,7 +38152,7 @@ Next step: ${nextStep}`;
37783
38152
  }
37784
38153
  async function maybeAutoFastForwardIdleNode(components, args) {
37785
38154
  const mesh = getMeshWithCache(components, args.meshId);
37786
- const node = mesh?.nodes?.find((candidate) => candidate?.id === args.nodeId || candidate?.nodeId === args.nodeId);
38155
+ const node = mesh?.nodes?.find((candidate) => meshNodeIdMatches(candidate, args.nodeId));
37787
38156
  const workspace = readNonEmptyString2(node?.workspace);
37788
38157
  if (!workspace) return;
37789
38158
  if (!(0, import_fs10.existsSync)(workspace)) return;
@@ -38284,12 +38653,25 @@ Next step: ${nextStep}`;
38284
38653
  nodeId: readNonEmptyString2(routing.nodeId) || readNonEmptyString2(event.meshNodeId) || void 0,
38285
38654
  workspace: readNonEmptyString2(routing.workspace) || readNonEmptyString2(event.workspace) || void 0
38286
38655
  };
38287
- Promise.resolve(components.dispatchMeshCommand(coordinatorDaemonId, "mesh_forward_event", payload)).catch((e) => {
38288
- LOG2.warn("MeshEvents", `Fallback forward of ${eventName} to coordinator ${coordinatorDaemonId} failed: ${e?.message || e}`);
38656
+ const persisted = enqueueUnresolvedDelegateForward(coordinatorDaemonId, eventName, payload);
38657
+ Promise.resolve(components.dispatchMeshCommand(coordinatorDaemonId, "mesh_forward_event", payload)).then((result) => {
38658
+ if (result && result.success === false) {
38659
+ LOG2.warn("MeshEvents", `Immediate forward of ${eventName} to coordinator ${coordinatorDaemonId} rejected (${readNonEmptyString2(result.error) || "no reason"}) \u2014 left queued for retry`);
38660
+ return;
38661
+ }
38662
+ if (persisted) ackUnresolvedDelegateForwardByFingerprint(coordinatorDaemonId, eventName, payload);
38663
+ }).catch((e) => {
38664
+ LOG2.warn("MeshEvents", `Immediate forward of ${eventName} to coordinator ${coordinatorDaemonId} failed: ${e?.message || e} \u2014 left queued for retry`);
38289
38665
  });
38290
- LOG2.info("MeshEvents", `Fallback-forwarded ${eventName} for unresolved-mesh worker at ${routing.workspace || "(no workspace)"} to coordinator daemon ${coordinatorDaemonId}`);
38666
+ LOG2.info("MeshEvents", `Durably forwarded ${eventName} for unresolved-mesh worker at ${routing.workspace || "(no workspace)"} to coordinator daemon ${coordinatorDaemonId}`);
38291
38667
  return true;
38292
38668
  }
38669
+ function ackUnresolvedDelegateForwardByFingerprint(coordinatorDaemonId, eventName, payload) {
38670
+ const match = peekUnresolvedDelegateForwards().find(
38671
+ (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)
38672
+ );
38673
+ if (match) ackUnresolvedDelegateForward(match.id);
38674
+ }
38293
38675
  function setupMeshEventForwarding(components) {
38294
38676
  components.instanceManager.onEvent((event) => {
38295
38677
  if (event.event === "agent:ready" || event.event === "agent:generating_completed") {
@@ -38384,7 +38766,9 @@ Next step: ${nextStep}`;
38384
38766
  init_mesh_runtime_store();
38385
38767
  init_mesh_events_pending();
38386
38768
  init_mesh_routing();
38769
+ init_mesh_unresolved_forward_outbox();
38387
38770
  init_repo_mesh_types();
38771
+ init_dist();
38388
38772
  init_mesh_events_stale();
38389
38773
  init_mesh_events_utils();
38390
38774
  REMOTE_IDLE_SESSION_TTL_MS = 5 * 60 * 1e3;
@@ -38496,6 +38880,13 @@ Next step: ${nextStep}`;
38496
38880
  return void 0;
38497
38881
  }
38498
38882
  })();
38883
+ if (dispatchMeshCommand) {
38884
+ try {
38885
+ await retryUnresolvedDelegateForwards(components);
38886
+ } catch (e) {
38887
+ LOG2.warn("MeshReconcile", `Unresolved-delegate forward retry failed: ${e?.message || e}`);
38888
+ }
38889
+ }
38499
38890
  if (dispatchMeshCommand) {
38500
38891
  for (const mesh of listMeshes()) {
38501
38892
  const selfIds = resolveCoordinatorSelfIds(mesh, drainDaemonIds);
@@ -38549,6 +38940,28 @@ Next step: ${nextStep}`;
38549
38940
  }
38550
38941
  }
38551
38942
  }
38943
+ async function retryUnresolvedDelegateForwards(components) {
38944
+ const dispatchMeshCommand = components.dispatchMeshCommand;
38945
+ if (!dispatchMeshCommand) return;
38946
+ expireStaleUnresolvedDelegateForwards();
38947
+ const entries = peekUnresolvedDelegateForwards();
38948
+ if (entries.length === 0) return;
38949
+ for (const entry of entries) {
38950
+ let result;
38951
+ try {
38952
+ result = await dispatchMeshCommand(entry.coordinatorDaemonId, "mesh_forward_event", entry.payload);
38953
+ } catch (e) {
38954
+ LOG2.warn("MeshReconcile", `Retry forward to coordinator ${entry.coordinatorDaemonId} failed: ${e?.message || e} \u2014 left queued`);
38955
+ continue;
38956
+ }
38957
+ if (result && result.success === false) {
38958
+ LOG2.warn("MeshReconcile", `Retry forward to coordinator ${entry.coordinatorDaemonId} rejected (${readNonEmptyString2(result.error) || "no reason"}) \u2014 left queued`);
38959
+ continue;
38960
+ }
38961
+ ackUnresolvedDelegateForward(entry.id);
38962
+ LOG2.info("MeshReconcile", `Retried+delivered unresolved-delegate ${readNonEmptyString2(entry.payload.event)} to coordinator ${entry.coordinatorDaemonId}`);
38963
+ }
38964
+ }
38552
38965
  async function pullRemoteNodeQueues(components, mesh, localDaemonId, candidateDaemonIds) {
38553
38966
  const dispatchMeshCommand = components.dispatchMeshCommand;
38554
38967
  if (!dispatchMeshCommand) return;
@@ -38625,6 +39038,7 @@ Next step: ${nextStep}`;
38625
39038
  init_mesh_events_pending();
38626
39039
  init_mesh_runtime_store();
38627
39040
  init_mesh_events_coordinator();
39041
+ init_mesh_unresolved_forward_outbox();
38628
39042
  init_mesh_events_utils();
38629
39043
  DEFAULT_RECONCILE_INTERVAL_MS = 4e3;
38630
39044
  }
@@ -47252,9 +47666,10 @@ ${lastSnapshot}`;
47252
47666
  };
47253
47667
  }
47254
47668
  init_mesh_work_queue();
47669
+ init_dist();
47255
47670
  var DIRECT_DISPATCH_VIA = /* @__PURE__ */ new Set(["p2p_direct", "local_direct", "mesh_send_task"]);
47256
47671
  var TERMINAL_LEDGER_KINDS = /* @__PURE__ */ new Set(["task_completed", "task_failed", "task_stalled"]);
47257
- function readString5(value) {
47672
+ function readString6(value) {
47258
47673
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
47259
47674
  }
47260
47675
  function summarizeMessage(message) {
@@ -47269,7 +47684,7 @@ ${lastSnapshot}`;
47269
47684
  function sessionStatusFromNodes(nodes, nodeId, sessionId) {
47270
47685
  if (!Array.isArray(nodes)) return {};
47271
47686
  if (!nodeId) return { staleReason: "direct task has no node id" };
47272
- const node = nodes.find((item) => readString5(item?.id) === nodeId || readString5(item?.nodeId) === nodeId || readString5(item?.node_id) === nodeId);
47687
+ const node = nodes.find((item) => meshNodeIdMatches(item, nodeId));
47273
47688
  if (!node) return { staleReason: "direct task node is no longer in the live mesh" };
47274
47689
  if (!sessionId) return {};
47275
47690
  const candidates = [];
@@ -47293,12 +47708,12 @@ ${lastSnapshot}`;
47293
47708
  }
47294
47709
  const session = candidates.find((item) => {
47295
47710
  if (typeof item === "string") return item === sessionId;
47296
- const id = readString5(item?.id) || readString5(item?.sessionId) || readString5(item?.session_id) || readString5(item?.runtimeSessionId) || readString5(item?.instanceId);
47711
+ const id = readString6(item?.id) || readString6(item?.sessionId) || readString6(item?.session_id) || readString6(item?.runtimeSessionId) || readString6(item?.instanceId);
47297
47712
  return id === sessionId;
47298
47713
  });
47299
47714
  if (!session) return { staleReason: "direct task session is not present in live session records" };
47300
47715
  if (typeof session === "string") return {};
47301
- const raw = `${readString5(session.status) || ""} ${readString5(session.lifecycle) || ""} ${readString5(session.state) || ""} ${readString5(session.activeChat?.status) || ""}`.toLowerCase();
47716
+ const raw = `${readString6(session.status) || ""} ${readString6(session.lifecycle) || ""} ${readString6(session.state) || ""} ${readString6(session.activeChat?.status) || ""}`.toLowerCase();
47302
47717
  if (raw.includes("approval")) return { status: "awaiting_approval" };
47303
47718
  if (raw.includes("generating") || raw.includes("running") || raw.includes("busy")) return { status: "generating" };
47304
47719
  if (raw.includes("failed") || raw.includes("stopped") || raw.includes("terminated") || raw.includes("exited")) return { status: "failed" };
@@ -47309,14 +47724,14 @@ ${lastSnapshot}`;
47309
47724
  if (entry.kind !== "task_dispatched") return false;
47310
47725
  const payload = entry.payload || {};
47311
47726
  if (payload.source === "direct") return true;
47312
- const via = readString5(payload.via);
47727
+ const via = readString6(payload.via);
47313
47728
  return Boolean(via && DIRECT_DISPATCH_VIA.has(via) && payload.source !== "queue");
47314
47729
  }
47315
47730
  function directDispatchTaskId(entry) {
47316
- return readString5(entry.payload?.taskId) || entry.id;
47731
+ return readString6(entry.payload?.taskId) || entry.id;
47317
47732
  }
47318
47733
  function terminalMatchesDispatch(terminal, dispatch, taskId) {
47319
- const terminalTaskId = readString5(terminal.payload?.taskId);
47734
+ const terminalTaskId = readString6(terminal.payload?.taskId);
47320
47735
  if (terminalTaskId && terminalTaskId === taskId) return true;
47321
47736
  if (terminalTaskId && terminalTaskId !== taskId) return false;
47322
47737
  if (dispatch.sessionId && terminal.sessionId === dispatch.sessionId) return true;
@@ -47439,7 +47854,7 @@ ${lastSnapshot}`;
47439
47854
  const isNoTransition = !terminalStatus && !live.status;
47440
47855
  const isIdleUnacknowledged = status === "idle";
47441
47856
  const ledgerOnlyStaleReason = !terminalRow && (isIdleUnacknowledged || isNoTransition || dispatchedToIdleSession && isIdleUnacknowledged) ? "direct task dispatch has no provider acknowledgement, transcript append, or active runtime transition" : void 0;
47442
- const message = readString5(dispatch.payload?.message) || readString5(dispatch.payload?.summary) || "";
47857
+ const message = readString6(dispatch.payload?.message) || readString6(dispatch.payload?.summary) || "";
47443
47858
  const { title, summary: summary2 } = summarizeMessage(message);
47444
47859
  const isFreshUnacknowledged = Boolean(ledgerOnlyStaleReason && !live.staleReason);
47445
47860
  const record2 = {
@@ -47448,11 +47863,11 @@ ${lastSnapshot}`;
47448
47863
  status,
47449
47864
  nodeId: dispatch.nodeId,
47450
47865
  sessionId: dispatch.sessionId,
47451
- providerType: dispatch.providerType || readString5(dispatch.payload?.providerType),
47452
- taskTitle: readString5(dispatch.payload?.taskTitle) || title,
47453
- taskSummary: readString5(dispatch.payload?.taskSummary) || summary2,
47866
+ providerType: dispatch.providerType || readString6(dispatch.payload?.providerType),
47867
+ taskTitle: readString6(dispatch.payload?.taskTitle) || title,
47868
+ taskSummary: readString6(dispatch.payload?.taskSummary) || summary2,
47454
47869
  message,
47455
- taskMode: readString5(dispatch.payload?.taskMode),
47870
+ taskMode: readString6(dispatch.payload?.taskMode),
47456
47871
  createdAt: dispatch.timestamp,
47457
47872
  updatedAt: terminal?.timestamp || dispatch.timestamp,
47458
47873
  dispatchedAt: dispatch.timestamp,
@@ -47487,7 +47902,7 @@ ${lastSnapshot}`;
47487
47902
  const isNoTransition = !terminalStatus && !live.status;
47488
47903
  const isIdleUnacknowledged = status === "idle";
47489
47904
  const ledgerOnlyStaleReason = !terminalRow && (isIdleUnacknowledged || isNoTransition || dispatchedToIdleSession && isIdleUnacknowledged) ? "direct task dispatch has no provider acknowledgement, transcript append, or active runtime transition" : void 0;
47490
- const message = readString5(dispatch.payload?.message) || readString5(dispatch.payload?.summary) || "";
47905
+ const message = readString6(dispatch.payload?.message) || readString6(dispatch.payload?.summary) || "";
47491
47906
  const { title, summary: summary2 } = summarizeMessage(message);
47492
47907
  const isFreshUnacknowledged = Boolean(ledgerOnlyStaleReason && !live.staleReason);
47493
47908
  const record2 = {
@@ -47496,11 +47911,11 @@ ${lastSnapshot}`;
47496
47911
  status,
47497
47912
  nodeId: dispatch.nodeId,
47498
47913
  sessionId: dispatch.sessionId,
47499
- providerType: dispatch.providerType || readString5(dispatch.payload?.providerType),
47500
- taskTitle: readString5(dispatch.payload?.taskTitle) || title,
47501
- taskSummary: readString5(dispatch.payload?.taskSummary) || summary2,
47914
+ providerType: dispatch.providerType || readString6(dispatch.payload?.providerType),
47915
+ taskTitle: readString6(dispatch.payload?.taskTitle) || title,
47916
+ taskSummary: readString6(dispatch.payload?.taskSummary) || summary2,
47502
47917
  message,
47503
- taskMode: readString5(dispatch.payload?.taskMode),
47918
+ taskMode: readString6(dispatch.payload?.taskMode),
47504
47919
  createdAt: dispatch.timestamp,
47505
47920
  updatedAt: terminal?.timestamp || dispatch.timestamp,
47506
47921
  dispatchedAt: dispatch.timestamp,
@@ -51804,7 +52219,7 @@ ${cleanBody}`;
51804
52219
  this.runtimeMessages = [];
51805
52220
  }
51806
52221
  updateSettings(newSettings) {
51807
- this.settings = { ...newSettings };
52222
+ this.settings = { ...this.settings, ...newSettings };
51808
52223
  this.monitor.updateConfig({
51809
52224
  approvalAlert: this.settings.approvalAlert !== false,
51810
52225
  longGeneratingAlert: this.settings.longGeneratingAlert !== false,
@@ -52461,7 +52876,7 @@ ${effect.notification.body || ""}`.trim();
52461
52876
  this.extensions.clear();
52462
52877
  }
52463
52878
  updateSettings(newSettings) {
52464
- this.settings = { ...newSettings };
52879
+ this.settings = { ...this.settings, ...newSettings };
52465
52880
  this.monitor.updateConfig({
52466
52881
  approvalAlert: this.settings.approvalAlert !== false,
52467
52882
  longGeneratingAlert: this.settings.longGeneratingAlert !== false,
@@ -61931,22 +62346,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
61931
62346
  };
61932
62347
  }
61933
62348
  updateSettings(newSettings) {
61934
- const runtimeMeshSettings = {};
61935
- for (const key of [
61936
- "meshNodeFor",
61937
- "meshNodeId",
61938
- "meshActiveTaskId",
61939
- "meshCoordinatorFor",
61940
- "meshCoordinatorDaemonId",
61941
- "meshCoordinatorNodeId",
61942
- "spawnedSessionVisibility",
61943
- "launchedByCoordinator"
61944
- ]) {
61945
- if (this.settings[key] !== void 0 && newSettings[key] === void 0) {
61946
- runtimeMeshSettings[key] = this.settings[key];
61947
- }
61948
- }
61949
- this.settings = { ...newSettings, ...runtimeMeshSettings };
62349
+ this.settings = { ...this.settings, ...newSettings };
61950
62350
  this.adapter.updateRuntimeSettings?.(this.settings);
61951
62351
  this.monitor.updateConfig({
61952
62352
  approvalAlert: this.settings.approvalAlert !== false,
@@ -69237,203 +69637,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
69237
69637
  init_config();
69238
69638
  init_cli_detector();
69239
69639
  init_git_status();
69240
- function readRecord5(value) {
69241
- return value && typeof value === "object" && !Array.isArray(value) ? value : {};
69242
- }
69243
- function readString6(...values) {
69244
- for (const value of values) {
69245
- if (typeof value !== "string") continue;
69246
- const trimmed = value.trim();
69247
- if (trimmed) return trimmed;
69248
- }
69249
- return void 0;
69250
- }
69251
- function readNumber(...values) {
69252
- for (const value of values) {
69253
- if (typeof value === "number" && Number.isFinite(value)) return value;
69254
- }
69255
- return void 0;
69256
- }
69257
- function readBoolean(...values) {
69258
- for (const value of values) {
69259
- if (typeof value === "boolean") return value;
69260
- }
69261
- return void 0;
69262
- }
69263
- function joinRepoPath(root, relativePath) {
69264
- const normalizedRoot = typeof root === "string" ? root.trim().replace(/[\\/]+$/, "") : "";
69265
- const normalizedPath = typeof relativePath === "string" ? relativePath.trim() : "";
69266
- if (!normalizedPath) return void 0;
69267
- if (/^(?:[A-Za-z]:[\\/]|\/)/.test(normalizedPath)) return normalizedPath;
69268
- if (!normalizedRoot) return void 0;
69269
- return `${normalizedRoot}/${normalizedPath.replace(/^[\\/]+/, "")}`;
69270
- }
69271
- function scoreGitUpstreamFreshness(status) {
69272
- switch (status) {
69273
- case "fresh":
69274
- return 30;
69275
- case "no_upstream":
69276
- return 4;
69277
- case "unchecked":
69278
- case void 0:
69279
- return 0;
69280
- case "stale":
69281
- return -10;
69282
- case "unavailable":
69283
- return -15;
69284
- default:
69285
- return 0;
69286
- }
69287
- }
69288
- function readGitSubmodules(value, parentRepoRoot) {
69289
- if (!Array.isArray(value)) return void 0;
69290
- const submodules = value.map((entry) => {
69291
- const submodule = readRecord5(entry);
69292
- const path40 = readString6(submodule.path);
69293
- const commit = readString6(submodule.commit);
69294
- const repoPath = readString6(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot, path40);
69295
- if (!path40 || !commit) return null;
69296
- const result = {
69297
- path: path40,
69298
- commit,
69299
- dirty: readBoolean(submodule.dirty) ?? false,
69300
- outOfSync: readBoolean(submodule.outOfSync, submodule.out_of_sync) ?? false,
69301
- lastCheckedAt: readNumber(submodule.lastCheckedAt, submodule.last_checked_at) ?? Date.now()
69302
- };
69303
- if (repoPath) result.repoPath = repoPath;
69304
- const error48 = readString6(submodule.error);
69305
- if (error48) result.error = error48;
69306
- return result;
69307
- }).filter((entry) => entry !== null);
69308
- return submodules.length > 0 ? submodules : void 0;
69309
- }
69310
- function hasGitStatusEvidence(status) {
69311
- 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(
69312
- status.ahead,
69313
- status.behind,
69314
- status.staged,
69315
- status.modified,
69316
- status.untracked,
69317
- status.deleted,
69318
- status.renamed,
69319
- status.lastCheckedAt,
69320
- status.last_checked_at
69321
- ) !== void 0 || Array.isArray(status.submodules) && status.submodules.length > 0;
69322
- }
69323
- function normalizeGitStatus(status, node, options) {
69324
- const explicitIsGitRepo = readBoolean(status.isGitRepo);
69325
- if (!Object.keys(status).length || !hasGitStatusEvidence(status)) return void 0;
69326
- const isGitRepo = explicitIsGitRepo ?? true;
69327
- const conflictFiles = Array.isArray(status.conflictFiles) ? status.conflictFiles.filter((entry) => typeof entry === "string") : [];
69328
- const conflictCount = readNumber(status.conflicts) ?? conflictFiles.length;
69329
- const hasConflicts = readBoolean(status.hasConflicts) ?? conflictCount > 0;
69330
- const repoRoot = readString6(status.repoRoot, status.repo_root, node.repoRoot, node.repo_root, status.workspace, node.workspace) || void 0;
69331
- const submodules = readGitSubmodules(status.submodules, repoRoot);
69332
- const upstreamStatus = readString6(status.upstreamStatus, status.upstream_status);
69333
- const upstreamFetchedAt = readNumber(status.upstreamFetchedAt, status.upstream_fetched_at);
69334
- const upstreamFetchError = readString6(status.upstreamFetchError, status.upstream_fetch_error);
69335
- const error48 = readString6(status.error);
69336
- const staged = readNumber(status.staged) ?? 0;
69337
- const modified = readNumber(status.modified) ?? 0;
69338
- const untracked = readNumber(status.untracked) ?? 0;
69339
- const deleted = readNumber(status.deleted) ?? 0;
69340
- const renamed = readNumber(status.renamed) ?? 0;
69341
- return {
69342
- workspace: readString6(status.workspace, node.workspace) || "",
69343
- repoRoot: repoRoot ?? null,
69344
- isGitRepo,
69345
- branch: readString6(status.branch) ?? null,
69346
- headCommit: readString6(status.headCommit) ?? null,
69347
- headMessage: readString6(status.headMessage) ?? null,
69348
- upstream: readString6(status.upstream) ?? null,
69349
- upstreamStatus: upstreamStatus ?? "unchecked",
69350
- ...upstreamFetchedAt !== void 0 ? { upstreamFetchedAt } : {},
69351
- ...upstreamFetchError ? { upstreamFetchError } : {},
69352
- ahead: readNumber(status.ahead) ?? 0,
69353
- behind: readNumber(status.behind) ?? 0,
69354
- staged,
69355
- modified,
69356
- untracked,
69357
- deleted,
69358
- renamed,
69359
- dirty: readBoolean(status.dirty, status.isDirty, status.is_dirty) ?? (staged + modified + untracked + deleted + renamed > 0 || hasConflicts),
69360
- hasConflicts,
69361
- conflictFiles,
69362
- stashCount: readNumber(status.stashCount, status.stash_count) ?? 0,
69363
- lastCheckedAt: options?.lastCheckedAt ?? readNumber(status.lastCheckedAt, status.last_checked_at) ?? Date.now(),
69364
- ...submodules ? { submodules } : {},
69365
- ...error48 ? { error: error48 } : {}
69366
- };
69367
- }
69368
- function scoreGitStatusCandidate(git) {
69369
- if (!git) return Number.NEGATIVE_INFINITY;
69370
- let score = 0;
69371
- if (git.isGitRepo === true) score += 50;
69372
- if (git.isGitRepo === false) score -= 10;
69373
- if (git.branch) score += 20;
69374
- if (git.headCommit) score += 20;
69375
- if (git.upstream) score += 10;
69376
- score += scoreGitUpstreamFreshness(git.upstreamStatus);
69377
- if (typeof git.ahead === "number") score += 2;
69378
- if (typeof git.behind === "number") score += 2;
69379
- if (Array.isArray(git.submodules) && git.submodules.length > 0) score += 4 + git.submodules.length;
69380
- if (git.error) score -= 20;
69381
- return score;
69382
- }
69383
- function pickBestTransitGitStatus(node, options) {
69384
- const rawGit = readRecord5(node.lastGit ?? node.last_git);
69385
- const gitResult = readRecord5(rawGit.result);
69386
- const directStatus = readRecord5(rawGit.status);
69387
- const nestedStatus = readRecord5(gitResult.status);
69388
- const rawProbe = readRecord5(node.lastProbe ?? node.last_probe);
69389
- const probeGit = readRecord5(rawProbe.git);
69390
- const probeGitResult = readRecord5(probeGit.result);
69391
- const probeDirectStatus = readRecord5(probeGit.status);
69392
- const probeNestedStatus = readRecord5(probeGitResult.status);
69393
- const lastCheckedAt = options?.lastCheckedAt;
69394
- let best = null;
69395
- for (const status of [directStatus, nestedStatus, probeDirectStatus, probeNestedStatus]) {
69396
- const normalized = normalizeGitStatus(status, node, { lastCheckedAt: lastCheckedAt ?? Date.now() });
69397
- if (!normalized) continue;
69398
- const score = scoreGitStatusCandidate(normalized);
69399
- if (!best || score > best.score) best = { git: normalized, score };
69400
- }
69401
- return best?.git;
69402
- }
69403
- function summarizeGitShape(status) {
69404
- const record2 = readRecord5(status);
69405
- if (!Object.keys(record2).length) return null;
69406
- const submodules = Array.isArray(record2.submodules) ? record2.submodules.map((entry) => {
69407
- const sub = readRecord5(entry);
69408
- return {
69409
- path: readString6(sub.path) ?? null,
69410
- commit: readString6(sub.commit)?.slice(0, 12) ?? null,
69411
- dirty: readBoolean(sub.dirty) ?? false,
69412
- outOfSync: readBoolean(sub.outOfSync, sub.out_of_sync) ?? false
69413
- };
69414
- }) : [];
69415
- return {
69416
- isGitRepo: readBoolean(record2.isGitRepo),
69417
- workspace: readString6(record2.workspace) ?? null,
69418
- repoRoot: readString6(record2.repoRoot, record2.repo_root) ?? null,
69419
- branch: readString6(record2.branch) ?? null,
69420
- upstream: readString6(record2.upstream) ?? null,
69421
- upstreamStatus: readString6(record2.upstreamStatus, record2.upstream_status) ?? null,
69422
- headCommit: readString6(record2.headCommit, record2.head_commit)?.slice(0, 12) ?? null,
69423
- ahead: readNumber(record2.ahead) ?? null,
69424
- behind: readNumber(record2.behind) ?? null,
69425
- dirtyCounts: {
69426
- staged: readNumber(record2.staged) ?? 0,
69427
- modified: readNumber(record2.modified) ?? 0,
69428
- untracked: readNumber(record2.untracked) ?? 0,
69429
- deleted: readNumber(record2.deleted) ?? 0,
69430
- renamed: readNumber(record2.renamed) ?? 0
69431
- },
69432
- lastCheckedAt: readNumber(record2.lastCheckedAt, record2.last_checked_at) ?? null,
69433
- submoduleCount: submodules.length,
69434
- submodules
69435
- };
69436
- }
69640
+ init_dist();
69437
69641
  init_logger();
69438
69642
  var fs222 = __toESM2(require("fs"));
69439
69643
  var path33 = __toESM2(require("path"));
@@ -70495,7 +70699,10 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
70495
70699
  branchConvergenceSummary: status?.branchConvergenceSummary ?? status?.branch_convergence_summary ?? null,
70496
70700
  nodeCount: nodes.length,
70497
70701
  nodes: nodes.map((node) => ({
70498
- nodeId: readStringValue(node?.nodeId, node?.id) ?? null,
70702
+ // Status emits the id under `nodeId` (3-way input absorbed). The
70703
+ // inline cache keeps `id` and `nodeId` equal, so this serialized form
70704
+ // round-trips back through the cache without flipping shape.
70705
+ nodeId: normalizeMeshNodeId(node) ?? null,
70499
70706
  daemonId: readStringValue(node?.daemonId, node?.daemon_id) ?? null,
70500
70707
  workspace: readStringValue(node?.workspace, node?.git?.workspace) ?? null,
70501
70708
  health: readStringValue(node?.health) ?? null,
@@ -70740,7 +70947,23 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
70740
70947
  return inlineMesh.nodes.some((node) => hasInlineMeshTransientNodeState(node));
70741
70948
  }
70742
70949
  function readInlineMeshNodeId(node) {
70743
- return readStringValue(node?.id, node?.nodeId) || "";
70950
+ return normalizeMeshNodeId(node) ?? "";
70951
+ }
70952
+ function foldMeshNodeIdentityToCanonical(node) {
70953
+ if (!node || typeof node !== "object" || Array.isArray(node)) return node;
70954
+ const canonical = normalizeMeshNodeId(node);
70955
+ if (canonical === void 0) return node;
70956
+ if (node.id === canonical && node.nodeId === canonical && node.node_id === void 0) return node;
70957
+ node.id = canonical;
70958
+ node.nodeId = canonical;
70959
+ if ("node_id" in node) delete node.node_id;
70960
+ return node;
70961
+ }
70962
+ function normalizeInlineMeshNodeIdentity(inlineMesh) {
70963
+ if (!inlineMesh || typeof inlineMesh !== "object" || Array.isArray(inlineMesh)) return inlineMesh;
70964
+ if (!Array.isArray(inlineMesh.nodes) || inlineMesh.nodes.length === 0) return inlineMesh;
70965
+ for (const node of inlineMesh.nodes) foldMeshNodeIdentityToCanonical(node);
70966
+ return inlineMesh;
70744
70967
  }
70745
70968
  function sanitizeInlineMesh(inlineMesh) {
70746
70969
  if (!inlineMesh || typeof inlineMesh !== "object" || Array.isArray(inlineMesh)) return inlineMesh;
@@ -70842,7 +71065,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
70842
71065
  return "online";
70843
71066
  }
70844
71067
  function readMeshNodeLabel(status, node) {
70845
- return readStringValue(status.nodeId, node?.id, node?.nodeId) ?? "unknown";
71068
+ return readStringValue(status.nodeId, normalizeMeshNodeId(node)) ?? "unknown";
70846
71069
  }
70847
71070
  function buildInlineMeshBranchConvergence(args) {
70848
71071
  const git = readObjectRecord(args.status.git);
@@ -71121,7 +71344,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
71121
71344
  let peerConfirmedCount = 0;
71122
71345
  const unavailableNodeIds = [];
71123
71346
  for (const [nodeIndex, node] of nodes.entries()) {
71124
- const nodeId = readStringValue(node?.id, node?.nodeId) || `node_${nodeIndex}`;
71347
+ const nodeId = normalizeMeshNodeId(node) || `node_${nodeIndex}`;
71125
71348
  const workspace = readStringValue(node?.workspace);
71126
71349
  const daemonId = readStringValue(node?.daemonId);
71127
71350
  const isSelfNode = Boolean(
@@ -71252,7 +71475,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
71252
71475
  const liveWorkspaces = /* @__PURE__ */ new Set();
71253
71476
  const missingLocalWorktreeNodeIds = /* @__PURE__ */ new Set();
71254
71477
  for (const node of args.nodes || []) {
71255
- const nodeId = readStringValue(node?.id, node?.nodeId);
71478
+ const nodeId = normalizeMeshNodeId(node);
71256
71479
  const workspace = readStringValue(node?.workspace);
71257
71480
  if (nodeId) liveNodeIds.add(nodeId);
71258
71481
  if (workspace) liveWorkspaces.add(workspace);
@@ -71377,9 +71600,13 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
71377
71600
  }
71378
71601
  return { enabled: false };
71379
71602
  }
71380
- async function computeGitPatchId(cwd, fromRef, toRef) {
71603
+ async function computeGitPatchId(cwd, fromRef, toRef, excludePaths = []) {
71381
71604
  const { execFileSync: execFileSync6 } = await import("child_process");
71382
- const diff = execFileSync6("git", ["diff", "--patch", "--full-index", fromRef, toRef], {
71605
+ const diffArgs = ["diff", "--patch", "--full-index", fromRef, toRef];
71606
+ if (excludePaths.length > 0) {
71607
+ diffArgs.push("--", ".", ...excludePaths.map((path40) => `:(exclude)${path40}`));
71608
+ }
71609
+ const diff = execFileSync6("git", diffArgs, {
71383
71610
  cwd,
71384
71611
  encoding: "utf8",
71385
71612
  maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
@@ -71448,8 +71675,9 @@ ${mergeTreeErr?.stderr || ""}`;
71448
71675
  gitlinkTrivialFastForward
71449
71676
  };
71450
71677
  }
71451
- const expectedPatchId = await computeGitPatchId(repoRoot, mergeBase, branchHead);
71452
- const actualPatchId = await computeGitPatchId(repoRoot, baseHead, mergedTree);
71678
+ const ffGitlinkExcludePaths = collectFastForwardGitlinkPaths(repoRoot, baseHead, branchHead);
71679
+ const expectedPatchId = await computeGitPatchId(repoRoot, mergeBase, branchHead, ffGitlinkExcludePaths);
71680
+ const actualPatchId = await computeGitPatchId(repoRoot, baseHead, mergedTree, ffGitlinkExcludePaths);
71453
71681
  const equivalent = expectedPatchId === actualPatchId;
71454
71682
  return {
71455
71683
  status: equivalent ? "passed" : "failed",
@@ -71645,6 +71873,14 @@ ${e?.stderr || ""}`
71645
71873
  return [];
71646
71874
  }
71647
71875
  }
71876
+ function collectFastForwardGitlinkPaths(repoRoot, baseHead, branchHead) {
71877
+ return readChangedGitlinkPaths(repoRoot, baseHead, branchHead).filter((path40) => {
71878
+ const baseCommit = readTreeObject(repoRoot, baseHead, path40);
71879
+ const branchCommit = readTreeObject(repoRoot, branchHead, path40);
71880
+ if (!baseCommit || !branchCommit) return false;
71881
+ return isSubmoduleFastForward((0, import_path10.resolve)(repoRoot, path40), baseCommit, branchCommit);
71882
+ });
71883
+ }
71648
71884
  function evaluateGitlinkTrivialFastForward(repoRoot, baseHead, branchHead) {
71649
71885
  const changedGitlinks = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((path40) => {
71650
71886
  const baseCommit = readTreeObject(repoRoot, baseHead, path40);
@@ -71694,20 +71930,95 @@ ${e?.stderr || ""}`
71694
71930
  }
71695
71931
  return { trivial: true, gitlinks: changedGitlinks };
71696
71932
  }
71933
+ function buildTreeWithGitlinksEqualized(repoRoot, commitish, paths, placeholderCommit) {
71934
+ try {
71935
+ const tree = (0, import_node_child_process6.execFileSync)("git", ["rev-parse", `${commitish}^{tree}`], {
71936
+ cwd: repoRoot,
71937
+ encoding: "utf8",
71938
+ maxBuffer: 1024 * 1024
71939
+ }).trim();
71940
+ if (!tree) return void 0;
71941
+ const updates = paths.map((path40) => `160000 commit ${placeholderCommit} ${path40}`).join("\n");
71942
+ if (!updates) return tree;
71943
+ const tmpIndex = (0, import_path10.join)(resolveGitDir(repoRoot), `adhdev-refine-eq-${commitish.slice(0, 12)}.index`);
71944
+ const env2 = { ...process.env, GIT_INDEX_FILE: tmpIndex };
71945
+ try {
71946
+ (0, import_node_child_process6.execFileSync)("git", ["read-tree", tree], { cwd: repoRoot, env: env2, stdio: "ignore" });
71947
+ (0, import_node_child_process6.execFileSync)("git", ["update-index", "--index-info"], {
71948
+ cwd: repoRoot,
71949
+ env: env2,
71950
+ input: `${updates}
71951
+ `,
71952
+ encoding: "utf8",
71953
+ stdio: ["pipe", "ignore", "ignore"]
71954
+ });
71955
+ const newTree = (0, import_node_child_process6.execFileSync)("git", ["write-tree"], { cwd: repoRoot, env: env2, encoding: "utf8" }).trim();
71956
+ return newTree || void 0;
71957
+ } finally {
71958
+ try {
71959
+ fs24.rmSync(tmpIndex, { force: true });
71960
+ } catch {
71961
+ }
71962
+ }
71963
+ } catch {
71964
+ return void 0;
71965
+ }
71966
+ }
71697
71967
  function synthesizeTrivialFastForwardMergeTree(repoRoot, baseHead, branchHead, gitlinks) {
71698
71968
  try {
71699
- const baseTree = (0, import_node_child_process6.execFileSync)("git", ["rev-parse", `${baseHead}^{tree}`], {
71969
+ const branchGitlinks = gitlinks.filter((entry) => entry.branchCommit);
71970
+ const gitlinkPaths = branchGitlinks.map((entry) => entry.path);
71971
+ const mergeBase = (0, import_node_child_process6.execFileSync)("git", ["merge-base", baseHead, branchHead], {
71972
+ cwd: repoRoot,
71973
+ encoding: "utf8",
71974
+ maxBuffer: 1024 * 1024
71975
+ }).trim();
71976
+ let mergedContentTree;
71977
+ if (mergeBase && gitlinkPaths.length > 0) {
71978
+ const placeholder = readTreeObject(repoRoot, mergeBase, gitlinkPaths[0]) || branchGitlinks[0].branchCommit;
71979
+ const baseEqTree = buildTreeWithGitlinksEqualized(repoRoot, mergeBase, gitlinkPaths, placeholder);
71980
+ const oursEqTree = buildTreeWithGitlinksEqualized(repoRoot, baseHead, gitlinkPaths, placeholder);
71981
+ const theirsEqTree = buildTreeWithGitlinksEqualized(repoRoot, branchHead, gitlinkPaths, placeholder);
71982
+ if (baseEqTree && oursEqTree && theirsEqTree) {
71983
+ try {
71984
+ const baseEqCommit = (0, import_node_child_process6.execFileSync)("git", ["commit-tree", baseEqTree, "-m", "refine-ff-base"], {
71985
+ cwd: repoRoot,
71986
+ encoding: "utf8",
71987
+ maxBuffer: 1024 * 1024
71988
+ }).trim();
71989
+ const oursEqCommit = (0, import_node_child_process6.execFileSync)("git", ["commit-tree", oursEqTree, "-p", baseEqCommit, "-m", "refine-ff-ours"], {
71990
+ cwd: repoRoot,
71991
+ encoding: "utf8",
71992
+ maxBuffer: 1024 * 1024
71993
+ }).trim();
71994
+ const theirsEqCommit = (0, import_node_child_process6.execFileSync)("git", ["commit-tree", theirsEqTree, "-p", baseEqCommit, "-m", "refine-ff-theirs"], {
71995
+ cwd: repoRoot,
71996
+ encoding: "utf8",
71997
+ maxBuffer: 1024 * 1024
71998
+ }).trim();
71999
+ const mergeOut = (0, import_node_child_process6.execFileSync)("git", ["merge-tree", "--write-tree", oursEqCommit, theirsEqCommit], {
72000
+ cwd: repoRoot,
72001
+ encoding: "utf8",
72002
+ maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
72003
+ }).trim();
72004
+ mergedContentTree = mergeOut.split(/\s+/)[0] || void 0;
72005
+ } catch {
72006
+ mergedContentTree = void 0;
72007
+ }
72008
+ }
72009
+ }
72010
+ const contentTree = mergedContentTree || (0, import_node_child_process6.execFileSync)("git", ["rev-parse", `${baseHead}^{tree}`], {
71700
72011
  cwd: repoRoot,
71701
72012
  encoding: "utf8",
71702
72013
  maxBuffer: 1024 * 1024
71703
72014
  }).trim();
71704
- if (!baseTree) return void 0;
71705
- const updates = gitlinks.filter((entry) => entry.branchCommit).map((entry) => `160000 commit ${entry.branchCommit} ${entry.path}`).join("\n");
71706
- if (!updates) return baseTree;
72015
+ if (!contentTree) return void 0;
72016
+ const updates = branchGitlinks.map((entry) => `160000 commit ${entry.branchCommit} ${entry.path}`).join("\n");
72017
+ if (!updates) return contentTree;
71707
72018
  const tmpIndex = (0, import_path10.join)(resolveGitDir(repoRoot), `adhdev-refine-ff-${baseHead.slice(0, 12)}-${branchHead.slice(0, 12)}.index`);
71708
72019
  const env2 = { ...process.env, GIT_INDEX_FILE: tmpIndex };
71709
72020
  try {
71710
- (0, import_node_child_process6.execFileSync)("git", ["read-tree", baseTree], { cwd: repoRoot, env: env2, stdio: "ignore" });
72021
+ (0, import_node_child_process6.execFileSync)("git", ["read-tree", contentTree], { cwd: repoRoot, env: env2, stdio: "ignore" });
71711
72022
  (0, import_node_child_process6.execFileSync)("git", ["update-index", "--index-info"], {
71712
72023
  cwd: repoRoot,
71713
72024
  env: env2,
@@ -72367,7 +72678,7 @@ ${e?.stderr || ""}`
72367
72678
  function buildMemberJoinNode(mesh, args, fallbackDaemonId) {
72368
72679
  const requestedNodeId = typeof args?.memberNodeId === "string" ? args.memberNodeId.trim() : "";
72369
72680
  const explicit = args?.memberNode && typeof args.memberNode === "object" && !Array.isArray(args.memberNode) ? args.memberNode : null;
72370
- const configured = Array.isArray(mesh?.nodes) ? requestedNodeId ? mesh.nodes.find((node) => node?.id === requestedNodeId || node?.nodeId === requestedNodeId) : mesh.nodes[0] : null;
72681
+ const configured = Array.isArray(mesh?.nodes) ? requestedNodeId ? mesh.nodes.find((node) => meshNodeIdMatches(node, requestedNodeId)) : mesh.nodes[0] : null;
72371
72682
  const source = explicit || configured;
72372
72683
  const workspace = typeof source?.workspace === "string" && source.workspace.trim() ? source.workspace.trim() : typeof args?.workspace === "string" && args.workspace.trim() ? args.workspace.trim() : process.cwd();
72373
72684
  if (!workspace) return null;
@@ -72423,7 +72734,7 @@ ${e?.stderr || ""}`
72423
72734
  if (nodeId) unavailableNodeIds.add(nodeId);
72424
72735
  }
72425
72736
  const nodes = snapshot.nodes.map((statusNode) => {
72426
- const nodeId = readStringValue(statusNode?.nodeId, statusNode?.id);
72737
+ const nodeId = normalizeMeshNodeId(statusNode);
72427
72738
  const inlineNode = nodeId ? inlineNodesById.get(nodeId) : void 0;
72428
72739
  if (!inlineNode) return statusNode;
72429
72740
  const liveGit = buildInlineMeshTransitGitStatus(inlineNode);
@@ -72536,7 +72847,7 @@ ${e?.stderr || ""}`
72536
72847
  }
72537
72848
  warmInlineMeshCache(meshId, inlineMesh) {
72538
72849
  if (!inlineMesh || typeof inlineMesh !== "object") return void 0;
72539
- const sanitizedInlineMesh = sanitizeInlineMesh(inlineMesh);
72850
+ const sanitizedInlineMesh = sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(inlineMesh));
72540
72851
  const cached22 = this.inlineMeshCache.get(meshId);
72541
72852
  if (cached22) {
72542
72853
  const merged = reconcileInlineMeshCache(cached22, sanitizedInlineMesh);
@@ -72553,7 +72864,7 @@ ${e?.stderr || ""}`
72553
72864
  if (cached3) {
72554
72865
  if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
72555
72866
  const merged = reconcileInlineMeshCache(cached3, inlineMesh);
72556
- this.inlineMeshCache.set(meshId, sanitizeInlineMesh(merged));
72867
+ this.inlineMeshCache.set(meshId, sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(merged)));
72557
72868
  return { mesh: merged, inline: true, source: "inline_cache" };
72558
72869
  }
72559
72870
  return { mesh: cached3, inline: true, source: "inline_cache" };
@@ -72589,17 +72900,19 @@ ${e?.stderr || ""}`
72589
72900
  return null;
72590
72901
  }
72591
72902
  updateInlineMeshNode(meshId, mesh, node) {
72592
- if (!mesh || !Array.isArray(mesh.nodes) || !node?.id) return;
72593
- const idx = mesh.nodes.findIndex((entry) => entry?.id === node.id || entry?.nodeId === node.id);
72903
+ const incomingId = normalizeMeshNodeId(node);
72904
+ if (!mesh || !Array.isArray(mesh.nodes) || !incomingId) return;
72905
+ const idx = mesh.nodes.findIndex((entry) => meshNodeIdMatches(entry, incomingId));
72594
72906
  if (idx >= 0) mesh.nodes[idx] = node;
72595
72907
  else mesh.nodes.push(node);
72596
72908
  mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
72909
+ for (const entry of mesh.nodes) foldMeshNodeIdentityToCanonical(entry);
72597
72910
  this.inlineMeshCache.set(meshId, mesh);
72598
72911
  this.invalidateAggregateMeshStatus(meshId);
72599
72912
  }
72600
72913
  removeInlineMeshNode(meshId, mesh, nodeId) {
72601
72914
  if (!mesh || !Array.isArray(mesh.nodes)) return false;
72602
- const idx = mesh.nodes.findIndex((entry) => entry?.id === nodeId || entry?.nodeId === nodeId);
72915
+ const idx = mesh.nodes.findIndex((entry) => meshNodeIdMatches(entry, nodeId));
72603
72916
  if (idx === -1) return false;
72604
72917
  mesh.nodes.splice(idx, 1);
72605
72918
  mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -72630,7 +72943,7 @@ ${e?.stderr || ""}`
72630
72943
  };
72631
72944
  }
72632
72945
  const worktreeExists = fs24.existsSync(workspace);
72633
- 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);
72946
+ const sourceNode = args.node?.clonedFromNodeId ? args.mesh?.nodes?.find((n) => meshNodeIdMatches(n, args.node.clonedFromNodeId)) : args.mesh?.nodes?.find((n) => !n.isLocalWorktree);
72634
72947
  const repoRoot = typeof sourceNode?.repoRoot === "string" && sourceNode.repoRoot.trim() ? sourceNode.repoRoot.trim() : typeof sourceNode?.workspace === "string" && sourceNode.workspace.trim() ? sourceNode.workspace.trim() : "";
72635
72948
  if (!worktreeExists) {
72636
72949
  return { success: true, skipped: true, removedPath: workspace, repoRoot: repoRoot || void 0, reason: "worktree_path_missing" };
@@ -73273,12 +73586,12 @@ ${e?.stderr || ""}`
73273
73586
  try {
73274
73587
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
73275
73588
  const mesh = meshRecord?.mesh;
73276
- const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
73589
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
73277
73590
  if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh`, refineStages };
73278
73591
  if (!node.isLocalWorktree || !node.workspace) {
73279
73592
  return { success: false, error: `Refinery requires a local worktree node`, refineStages };
73280
73593
  }
73281
- const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => n.id === node.clonedFromNodeId || n.nodeId === node.clonedFromNodeId) : mesh?.nodes.find((n) => !n.isLocalWorktree);
73594
+ const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => meshNodeIdMatches(n, node.clonedFromNodeId)) : mesh?.nodes.find((n) => !n.isLocalWorktree);
73282
73595
  const repoRoot = sourceNode?.repoRoot || sourceNode?.workspace;
73283
73596
  if (!repoRoot) return { success: false, error: "Source node repoRoot not found", refineStages };
73284
73597
  const { execFile: execFile5 } = await import("child_process");
@@ -73913,7 +74226,7 @@ ${hintLines.join("\n")}` : "",
73913
74226
  const missing = [];
73914
74227
  const nonWorktree = [];
73915
74228
  for (const nodeId of requestedNodeIds) {
73916
- const node = allNodes.find((n) => n.id === nodeId || n.nodeId === nodeId);
74229
+ const node = allNodes.find((n) => meshNodeIdMatches(n, nodeId));
73917
74230
  if (!node) {
73918
74231
  missing.push(nodeId);
73919
74232
  continue;
@@ -73942,7 +74255,7 @@ ${hintLines.join("\n")}` : "",
73942
74255
  const { promisify: promisify8 } = await import("util");
73943
74256
  const execFileAsync4 = promisify8(execFile5);
73944
74257
  const resolveRepoRootFor = (node) => {
73945
- const sourceNode = node.clonedFromNodeId ? allNodes.find((n) => n.id === node.clonedFromNodeId || n.nodeId === node.clonedFromNodeId) : allNodes.find((n) => !n.isLocalWorktree);
74258
+ const sourceNode = node.clonedFromNodeId ? allNodes.find((n) => meshNodeIdMatches(n, node.clonedFromNodeId)) : allNodes.find((n) => !n.isLocalWorktree);
73946
74259
  return sourceNode?.repoRoot || sourceNode?.workspace;
73947
74260
  };
73948
74261
  const repoRootBaseRef = /* @__PURE__ */ new Map();
@@ -74031,7 +74344,7 @@ ${hintLines.join("\n")}` : "",
74031
74344
  }));
74032
74345
  }
74033
74346
  const ordering = orderMeshRefineBatchNodes(changeAreas);
74034
- const orderedNodes = ordering.order.map((nodeId) => targetNodes.find((n) => n.id === nodeId || n.nodeId === nodeId)).filter((n) => !!n);
74347
+ const orderedNodes = ordering.order.map((nodeId) => targetNodes.find((n) => meshNodeIdMatches(n, nodeId))).filter((n) => !!n);
74035
74348
  const dryRun = args?.dryRun !== false && args?.execute !== true;
74036
74349
  if (dryRun) {
74037
74350
  return {
@@ -74290,7 +74603,7 @@ ${hintLines.join("\n")}` : "",
74290
74603
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
74291
74604
  const mesh = meshRecord?.mesh;
74292
74605
  const allNodes = Array.isArray(mesh?.nodes) ? mesh.nodes : [];
74293
- const orderedNodes = nodeIds.map((id) => allNodes.find((n) => n.id === id || n.nodeId === id)).filter((n) => !!n);
74606
+ const orderedNodes = nodeIds.map((id) => allNodes.find((n) => meshNodeIdMatches(n, id))).filter((n) => !!n);
74294
74607
  if (orderedNodes.length === 0) {
74295
74608
  return { success: false, error: "Batch nodes no longer resolvable in mesh", batch: true };
74296
74609
  }
@@ -74396,7 +74709,7 @@ ${hintLines.join("\n")}` : "",
74396
74709
  const terminal = this.terminalRefineJobs.get(key);
74397
74710
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
74398
74711
  const mesh = meshRecord?.mesh;
74399
- const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
74712
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
74400
74713
  if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
74401
74714
  if (!node.isLocalWorktree || !node.workspace) return { success: false, error: `Refinery requires a local worktree node` };
74402
74715
  const coordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
@@ -74443,7 +74756,7 @@ ${hintLines.join("\n")}` : "",
74443
74756
  try {
74444
74757
  const { getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
74445
74758
  const meshObj = getMesh2(meshId) ?? this.getCachedInlineMesh(meshId);
74446
- const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => n.id === meshNodeId || n.nodeId === meshNodeId) : void 0;
74759
+ const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => meshNodeIdMatches(n, meshNodeId)) : void 0;
74447
74760
  const bootstrapStatus = readStringValue(nodeObj?.worktreeBootstrap?.status);
74448
74761
  if (bootstrapStatus === "running") {
74449
74762
  return { success: true, ...launchResult, bootstrapPending: true };
@@ -74488,7 +74801,7 @@ ${hintLines.join("\n")}` : "",
74488
74801
  try {
74489
74802
  const { getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
74490
74803
  const meshObj = getMesh2(dispatchMeshId) ?? this.getCachedInlineMesh(dispatchMeshId);
74491
- const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => n.id === dispatchNodeId || n.nodeId === dispatchNodeId) : void 0;
74804
+ const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => meshNodeIdMatches(n, dispatchNodeId)) : void 0;
74492
74805
  const bootstrapStatus = readStringValue(nodeObj?.worktreeBootstrap?.status);
74493
74806
  if (bootstrapStatus === "running") {
74494
74807
  return {
@@ -75753,7 +76066,7 @@ ${hintLines.join("\n")}` : "",
75753
76066
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
75754
76067
  const mesh = meshRecord?.mesh;
75755
76068
  if (!mesh) return { success: false, error: "Mesh not found" };
75756
- const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
76069
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
75757
76070
  if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
75758
76071
  const mode = this.normalizeMeshSessionCleanupMode(args?.mode ?? mesh?.policy?.sessionCleanupOnNodeRemove);
75759
76072
  const sessionIds = Array.isArray(args?.sessionIds) ? args.sessionIds.map((id) => typeof id === "string" ? id.trim() : "").filter(Boolean) : void 0;
@@ -75808,7 +76121,7 @@ ${hintLines.join("\n")}` : "",
75808
76121
  if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
75809
76122
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
75810
76123
  const mesh = meshRecord?.mesh;
75811
- const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
76124
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
75812
76125
  if (!node?.workspace) return { success: false, error: `Node '${nodeId}' workspace not found` };
75813
76126
  return {
75814
76127
  success: true,
@@ -75830,7 +76143,7 @@ ${hintLines.join("\n")}` : "",
75830
76143
  if (meshId && nodeId) {
75831
76144
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
75832
76145
  const mesh = meshRecord?.mesh;
75833
- const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
76146
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
75834
76147
  if (!workspace) {
75835
76148
  workspace = typeof node?.workspace === "string" ? node.workspace.trim() : "";
75836
76149
  }
@@ -75873,7 +76186,7 @@ ${hintLines.join("\n")}` : "",
75873
76186
  if (isDryRun) {
75874
76187
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
75875
76188
  const mesh = meshRecord?.mesh;
75876
- const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
76189
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
75877
76190
  if (!node?.workspace) return { success: false, error: `Node '${nodeId}' workspace not found` };
75878
76191
  return {
75879
76192
  success: true,
@@ -75903,7 +76216,7 @@ ${hintLines.join("\n")}` : "",
75903
76216
  try {
75904
76217
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
75905
76218
  const mesh = meshRecord?.mesh;
75906
- const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
76219
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
75907
76220
  if (node && !args?._meshDirectDispatch && node.isLocalWorktree !== true && args?.force !== true) {
75908
76221
  const nodeDaemonId = typeof node.daemonId === "string" ? node.daemonId.trim() : "";
75909
76222
  const nodeMachineId = readMeshNodeMachineId(node) || "";
@@ -76017,7 +76330,7 @@ ${hintLines.join("\n")}` : "",
76017
76330
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
76018
76331
  const mesh = meshRecord?.mesh;
76019
76332
  if (!mesh) return { success: false, error: "Mesh not found" };
76020
- const sourceNode = mesh.nodes?.find((n) => n.id === sourceNodeId || n.nodeId === sourceNodeId);
76333
+ const sourceNode = mesh.nodes?.find((n) => meshNodeIdMatches(n, sourceNodeId));
76021
76334
  if (!sourceNode) return { success: false, error: `Source node '${sourceNodeId}' not found in mesh` };
76022
76335
  const sourceDaemonId = typeof sourceNode.daemonId === "string" ? sourceNode.daemonId.trim() : void 0;
76023
76336
  if (sourceDaemonId && sourceDaemonId !== this.deps.statusInstanceId && this.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
@@ -76037,9 +76350,9 @@ ${hintLines.join("\n")}` : "",
76037
76350
  });
76038
76351
  let node;
76039
76352
  if (meshRecord.inline) {
76040
- const { randomUUID: randomUUID14 } = await import("crypto");
76353
+ const { randomUUID: randomUUID15 } = await import("crypto");
76041
76354
  node = {
76042
- id: `node_${randomUUID14().replace(/-/g, "")}`,
76355
+ id: `node_${randomUUID15().replace(/-/g, "")}`,
76043
76356
  workspace: result.worktreePath,
76044
76357
  repoRoot: result.worktreePath,
76045
76358
  daemonId: sourceNode.daemonId,
@@ -76258,7 +76571,7 @@ ${hintLines.join("\n")}` : "",
76258
76571
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
76259
76572
  const mesh = meshRecord?.mesh;
76260
76573
  if (!mesh) return { success: false, error: "Mesh not found" };
76261
- const node = mesh.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
76574
+ const node = mesh.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
76262
76575
  if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
76263
76576
  if (!node.isLocalWorktree) return { success: false, error: "Node is not a local worktree node" };
76264
76577
  const nodeDaemonId = typeof node.daemonId === "string" ? node.daemonId.trim() : void 0;
@@ -76395,14 +76708,14 @@ ${hintLines.join("\n")}` : "",
76395
76708
  const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
76396
76709
  const workspace = readLiveMeshNodeWorkspace({
76397
76710
  meshId,
76398
- nodeId: String(coordinatorNode.id || coordinatorNode.nodeId || preferredCoordinatorNodeId || ""),
76711
+ nodeId: String(normalizeMeshNodeId(coordinatorNode) || preferredCoordinatorNodeId || ""),
76399
76712
  liveSessionRecords: liveMeshSessions,
76400
76713
  allowCoordinatorSession: true
76401
76714
  }) || (typeof coordinatorNode.workspace === "string" ? coordinatorNode.workspace.trim() : "");
76402
76715
  if (!workspace) return { success: false, error: "Coordinator node workspace required", meshId, cliType };
76403
76716
  if (!cliType) {
76404
76717
  const resolved = await resolveProviderTypeFromPriority({
76405
- nodeId: String(coordinatorNode.id || coordinatorNode.nodeId || preferredCoordinatorNodeId || "coordinator"),
76718
+ nodeId: String(normalizeMeshNodeId(coordinatorNode) || preferredCoordinatorNodeId || "coordinator"),
76406
76719
  providerPriority: readProviderPriorityFromPolicy(coordinatorNode.policy),
76407
76720
  providerLoader: this.deps.providerLoader,
76408
76721
  onStatusChange: this.deps.onStatusChange
@@ -76813,10 +77126,11 @@ ${ptyResult.output.slice(-2e3)}`);
76813
77126
  if (!mesh) return { success: false, error: "Mesh not found" };
76814
77127
  const meshHost = resolveMeshHostStatus(mesh);
76815
77128
  const refreshRequested = args?.refresh === true || args?.forceRefresh === true;
77129
+ const verboseMissions = args?.verbose === true || args?.compact === false;
76816
77130
  const peekScope = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
76817
77131
  const pendingCoordinatorEventCount = getPendingMeshCoordinatorEvents(meshId, peekScope).length;
76818
77132
  const hadAggregateCache = this.aggregateMeshStatusCache.has(meshId);
76819
- if (!refreshRequested && pendingCoordinatorEventCount === 0) {
77133
+ if (!refreshRequested && !verboseMissions && pendingCoordinatorEventCount === 0) {
76820
77134
  const cachedStatus = this.getCachedAggregateMeshStatus(meshId, mesh, { requireDirectPeerTruth: args?.requireDirectPeerTruth === true });
76821
77135
  if (cachedStatus) {
76822
77136
  logRepoMeshStatusDebug("return_cached", {
@@ -76856,7 +77170,7 @@ ${ptyResult.output.slice(-2e3)}`);
76856
77170
  const passivePeerTruthNotAttempted = requireDirectPeerTruth && !refreshRequested && directTruth.directEvidenceCount > 0 && directTruth.peerAttemptedCount === 0;
76857
77171
  const effectiveDirectTruth = passivePeerTruthNotAttempted ? { ...directTruth, unavailableNodeIds: [] } : directTruth;
76858
77172
  const unavailableDirectTruthNodeIds = new Set(effectiveDirectTruth.unavailableNodeIds);
76859
- 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);
77173
+ const unavailableNodesAreOnlyRemovedWorktrees = unavailableDirectTruthNodeIds.size > 0 && Array.isArray(mesh.nodes) && mesh.nodes.filter((node) => unavailableDirectTruthNodeIds.has(normalizeMeshNodeId(node) ?? "")).every((node) => node?.isLocalWorktree === true);
76860
77174
  const directTruthSatisfied = !requireDirectPeerTruth || effectiveDirectTruth.directEvidenceCount > 0 && (effectiveDirectTruth.unavailableNodeIds.length === 0 || unavailableNodesAreOnlyRemovedWorktrees);
76861
77175
  if (requireDirectPeerTruth && !directTruthSatisfied) {
76862
77176
  const failureResult = {
@@ -76891,14 +77205,13 @@ ${ptyResult.output.slice(-2e3)}`);
76891
77205
  const coordinatorHostname = (0, import_os3.hostname)();
76892
77206
  const selectedCoordinatorNodeId = readStringValue(
76893
77207
  mesh.coordinator?.preferredNodeId,
76894
- mesh.nodes?.[0]?.id,
76895
- mesh.nodes?.[0]?.nodeId
77208
+ normalizeMeshNodeId(mesh.nodes?.[0])
76896
77209
  );
76897
77210
  const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes) ? selectedCoordinatorNodeId : void 0;
76898
77211
  const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
76899
77212
  const nodeStatuses = [];
76900
77213
  for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
76901
- const nodeId = String(node.id || node.nodeId || "");
77214
+ const nodeId = normalizeMeshNodeId(node) ?? "";
76902
77215
  const daemonId = readStringValue(node.daemonId);
76903
77216
  const nodeMachineId = readMeshNodeMachineId(node);
76904
77217
  const nodeHostname = readMeshNodeHostname(node);
@@ -77120,7 +77433,7 @@ ${ptyResult.output.slice(-2e3)}`);
77120
77433
  liveSessionRecords: liveMeshSessions
77121
77434
  });
77122
77435
  const { getMeshStatusMissionSummaries: getMeshStatusMissionSummaries2 } = await Promise.resolve().then(() => (init_mesh_missions(), mesh_missions_exports));
77123
- const missions = getMeshStatusMissionSummaries2(meshId);
77436
+ const missions = getMeshStatusMissionSummaries2(meshId, { verbose: verboseMissions });
77124
77437
  const statusResult = {
77125
77438
  success: true,
77126
77439
  meshId: mesh.id,
@@ -77174,7 +77487,7 @@ ${ptyResult.output.slice(-2e3)}`);
77174
77487
  }))
77175
77488
  };
77176
77489
  const { pendingCoordinatorEvents: _pendingCoordinatorEvents, unroutableDeliveries: _unroutableDeliveries, ...cacheableStatusResult } = statusResult;
77177
- const rememberedStatus = this.rememberAggregateMeshStatus(meshId, cacheableStatusResult, refreshReason);
77490
+ const rememberedStatus = verboseMissions ? cacheableStatusResult : this.rememberAggregateMeshStatus(meshId, cacheableStatusResult, refreshReason);
77178
77491
  const returnedStatus = {
77179
77492
  ...rememberedStatus,
77180
77493
  ...pendingCoordinatorEvents.length > 0 ? { pendingCoordinatorEvents } : {},
@@ -84686,7 +84999,7 @@ data: ${JSON.stringify(msg.data)}
84686
84999
  });
84687
85000
  }
84688
85001
  };
84689
- var import_crypto9 = require("crypto");
85002
+ var import_crypto10 = require("crypto");
84690
85003
  var import_session_host_core10 = require_dist();
84691
85004
  var BASE_KEY_SEQUENCES = {
84692
85005
  enter: "\r",
@@ -84784,7 +85097,7 @@ data: ${JSON.stringify(msg.data)}
84784
85097
  const sessionId = String(options.sessionId || "").trim();
84785
85098
  if (!sessionId) throw new Error("sessionId is required");
84786
85099
  const mode = options.mode || "read";
84787
- const clientId = options.clientId || `raw-terminal-${process.pid}-${(0, import_crypto9.randomUUID)().slice(0, 8)}`;
85100
+ const clientId = options.clientId || `raw-terminal-${process.pid}-${(0, import_crypto10.randomUUID)().slice(0, 8)}`;
84788
85101
  const client = options.client || new import_session_host_core10.SessionHostClient({ endpoint: options.endpoint });
84789
85102
  await client.connect();
84790
85103
  const attachResponse = await client.request({