@adhdev/daemon-core 0.9.82-rc.291 → 0.9.82-rc.293
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/router.d.ts +50 -0
- package/dist/index.js +637 -327
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +639 -329
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-missions.d.ts +25 -1
- package/dist/mesh/mesh-runtime-store.d.ts +15 -0
- package/dist/mesh/mesh-unresolved-forward-outbox.d.ts +30 -0
- package/package.json +2 -2
- package/src/commands/router.ts +274 -58
- package/src/git/git-status.ts +46 -11
- package/src/mesh/coordinator-prompt.ts +2 -2
- package/src/mesh/mesh-active-work.ts +2 -1
- package/src/mesh/mesh-events-coordinator.ts +58 -10
- package/src/mesh/mesh-missions.ts +41 -3
- package/src/mesh/mesh-reconcile-loop.ts +55 -0
- package/src/mesh/mesh-runtime-store.ts +30 -0
- package/src/mesh/mesh-unresolved-forward-outbox.ts +185 -0
- package/src/providers/cli-provider-instance.ts +21 -16
- package/src/providers/extension-provider-instance.ts +5 -1
- package/src/providers/ide-provider-instance.ts +6 -1
package/dist/index.mjs
CHANGED
|
@@ -270,10 +270,10 @@ function readInjected(value) {
|
|
|
270
270
|
}
|
|
271
271
|
function getDaemonBuildInfo() {
|
|
272
272
|
if (cached) return cached;
|
|
273
|
-
const commit = readInjected(true ? "
|
|
274
|
-
const commitShort = readInjected(true ? "
|
|
275
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
276
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
273
|
+
const commit = readInjected(true ? "88f97abcc85d83fe5d5313b229d32a7d76b1208a" : void 0) ?? "unknown";
|
|
274
|
+
const commitShort = readInjected(true ? "88f97abc" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
275
|
+
const version = readInjected(true ? "0.9.82-rc.293" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
276
|
+
const builtAt = readInjected(true ? "2026-06-16T11:13:51.625Z" : void 0);
|
|
277
277
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
278
278
|
return cached;
|
|
279
279
|
}
|
|
@@ -344,6 +344,15 @@ async function getGitRepoStatus(workspace, options = {}) {
|
|
|
344
344
|
);
|
|
345
345
|
}
|
|
346
346
|
}
|
|
347
|
+
function isNonRuntimeRootFile(file) {
|
|
348
|
+
const base = file.slice(file.lastIndexOf("/") + 1);
|
|
349
|
+
if (/^\.(?:verify|marker|converge|ff-verify|patch-equiv|live-verify)\b/i.test(base)) return true;
|
|
350
|
+
if (/(?:^|\/)docs\//i.test(file)) return true;
|
|
351
|
+
if (/^(?:README|CHANGELOG|LICENSE|NOTICE|AUTHORS|CONTRIBUTING|CODEOWNERS)(?:\.[A-Za-z0-9]+)?$/i.test(base)) {
|
|
352
|
+
return true;
|
|
353
|
+
}
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
347
356
|
async function classifyDaemonBuildChange(repoPath, buildCommit, options) {
|
|
348
357
|
try {
|
|
349
358
|
const diff = await runGit(repoPath, ["diff", "--name-only", `${buildCommit}..HEAD`], options);
|
|
@@ -352,18 +361,18 @@ async function classifyDaemonBuildChange(repoPath, buildCommit, options) {
|
|
|
352
361
|
return { isDaemonAffecting: true, affectedPackages: [] };
|
|
353
362
|
}
|
|
354
363
|
const pkgs = /* @__PURE__ */ new Set();
|
|
355
|
-
let
|
|
364
|
+
let sawRuntimeAmbiguousNonPackage = false;
|
|
356
365
|
for (const file of files) {
|
|
357
366
|
const match = file.match(/(?:^|\/)packages\/([^/]+)\//);
|
|
358
367
|
if (!match) {
|
|
359
|
-
|
|
368
|
+
if (!isNonRuntimeRootFile(file)) sawRuntimeAmbiguousNonPackage = true;
|
|
360
369
|
continue;
|
|
361
370
|
}
|
|
362
371
|
pkgs.add(match[1]);
|
|
363
372
|
}
|
|
364
373
|
const affectedPackages = [...pkgs].sort();
|
|
365
|
-
const
|
|
366
|
-
return { isDaemonAffecting: !
|
|
374
|
+
const allBenign = !sawRuntimeAmbiguousNonPackage && affectedPackages.every((p) => WEB_ONLY_PACKAGES.has(p) && !DAEMON_RUNTIME_PACKAGES.has(p));
|
|
375
|
+
return { isDaemonAffecting: !allBenign, affectedPackages };
|
|
367
376
|
} catch {
|
|
368
377
|
return { isDaemonAffecting: true, affectedPackages: [] };
|
|
369
378
|
}
|
|
@@ -390,7 +399,8 @@ async function detectDaemonBuildBehind(repo, submodules, options) {
|
|
|
390
399
|
options
|
|
391
400
|
);
|
|
392
401
|
const scopeLabel = scope === "root" ? "workspace" : scope;
|
|
393
|
-
const
|
|
402
|
+
const benignDetail = affectedPackages.length > 0 ? `only web packages changed (${affectedPackages.join(", ")})` : "only non-runtime files changed (markers/docs)";
|
|
403
|
+
const warning = isDaemonAffecting ? `Live daemon was built from ${build.commitShort} which is behind ${scopeLabel} HEAD ${head.slice(0, 7)}. Merged code is NOT live until the daemon is rebuilt/redeployed and restarted \u2014 a local dist rebuild alone does not update a cloud daemon.` : `Live daemon was built from ${build.commitShort} which is behind ${scopeLabel} HEAD ${head.slice(0, 7)}, but ${benignDetail}. Daemon restart NOT required \u2014 redeploy the web app to reflect the change.`;
|
|
394
404
|
return {
|
|
395
405
|
buildCommit: build.commit,
|
|
396
406
|
buildCommitShort: build.commitShort,
|
|
@@ -1995,7 +2005,7 @@ function buildRulesSection(coordinatorCliType) {
|
|
|
1995
2005
|
- **Reuse idle sessions.** For follow-up, retry, commit/push, or cleanup on the same issue, send only the delta to the existing idle session. Start fresh only for independent work, provider mismatch, transcript contamination, or required worktree isolation.
|
|
1996
2006
|
- **Respect explicit provider requests.** Map: Hermes \u2192 \`hermes-cli\`, Claude/Claude Code \u2192 \`claude-cli\`, Codex \u2192 \`codex-cli\`, Gemini \u2192 \`gemini-cli\`, Antigravity \u2192 \`antigravity-cli\`. Never substitute the coordinator's own runtime.
|
|
1997
2007
|
- **Verify via git, not source.** Use \`mesh_git_status\` to confirm side effects. Treat agent summaries as self-reports, not verification.
|
|
1998
|
-
- **Limit parallelism.** Start with 1\u20132 tasks; scale only on success. Never duplicate a session because \`mesh_read_chat\` shows no final message while tool/terminal activity is ongoing.
|
|
2008
|
+
- **Limit parallelism.** Start with 1\u20132 tasks; scale only on success. Never duplicate a session because \`mesh_read_chat\` shows no final message while tool/terminal activity is ongoing. This caps *concurrent* load \u2014 it does not mean serialize independent work: when a new, independent request arrives and there is headroom under \`maxParallelTasks\`, dispatch it right away rather than waiting for an in-flight task or a user nudge (read-only diagnosis especially, since it has no merge cost).
|
|
1999
2009
|
- **Check history first.** Call \`mesh_task_history\` at session start to avoid duplicate work and inform recovery. On failure, read task history before retrying.
|
|
2000
2010
|
- **Converge branches.** After worktree tasks: refine/fast-forward, or classify as \`pushed_feature_branch_needs_merge\` / \`blocked_review\` / \`cleanup_candidate\` / \`not_mergeable\`. Clean up with \`mesh_remove_node\`.
|
|
2001
2011
|
- **Refinery is config-driven.** \`mesh_refine_node\` must run validation from \`.adhdev/refine.{json,yaml,yml}\` or \`repo-mesh.refine.*\`. Heuristics are scaffolding only.
|
|
@@ -2046,7 +2056,7 @@ Before doing any coordinator work, confirm that the actual callable tool list in
|
|
|
2046
2056
|
c. **Targeted Tasks**: Use \`mesh_send_task\` only when you need to bypass the queue and force a specific node to execute a task immediately.
|
|
2047
2057
|
d. For the first dispatch of a new task, provide a **complete, self-contained** instruction that includes all context the agent needs (file paths, line numbers, what to change, why). Do not send partial instructions expecting future follow-up.
|
|
2048
2058
|
e. For a continuation of the same issue in an existing session, send a concise **delta instruction**: current verified state, the exact failed/blocked step, the newly approved action, and final reporting requirements. Do not resend the full original task or open a new chat solely to continue the same work; that wastes coordinator and worker context.
|
|
2049
|
-
4. **Monitor** \u2014 Prefer event-driven completion/status notifications. Do **not** poll \`mesh_read_chat\` repeatedly. Do **not** repeatedly call \`mesh_status\` or \`mesh_view_queue\` just to wait for assigned/generating work. After dispatching a direct or queued task, send one progress update with the task/session handle, then stop. Wait for \`pendingCoordinatorEvents\` or another completion/approval/status signal, an explicit user status request, or a real timeout/stall signal before reading status/chat/queue again. Use at most one compact \`mesh_read_chat\` check after a terminal signal. Handle approvals via \`mesh_approve\`.
|
|
2059
|
+
4. **Monitor** \u2014 Prefer event-driven completion/status notifications. Do **not** poll \`mesh_read_chat\` repeatedly. Do **not** repeatedly call \`mesh_status\` or \`mesh_view_queue\` just to wait for assigned/generating work. After dispatching a direct or queued task, send one progress update with the task/session handle, then stop. Wait for \`pendingCoordinatorEvents\` or another completion/approval/status signal, an explicit user status request, or a real timeout/stall signal before reading status/chat/queue again. Use at most one compact \`mesh_read_chat\` check after a terminal signal. Handle approvals via \`mesh_approve\`. **Proactively parallelize new work.** When the user reports a new bug or asks for new work, start it immediately if it is independent of in-flight tasks and there is headroom under \`maxParallelTasks\` \u2014 do not wait for a current task to finish or for the user to prompt you to parallelize. Read-only diagnosis (\`live_debug_readonly\`) has no isolation or merge cost, so dispatch it in parallel right away. The no-polling / concurrency-limit rules constrain *re-checking or duplicating already-dispatched work*; they are **not** a reason to defer starting a new, independent task.
|
|
2050
2060
|
5. **Verify** \u2014 When a task reports completion or git work is visible, call \`mesh_git_status\` to verify changes were made.
|
|
2051
2061
|
6. **Checkpoint** \u2014 Call \`mesh_checkpoint\` to save the work.
|
|
2052
2062
|
7. **Converge branches** \u2014 Before marking any task complete, classify every touched node/branch into exactly one final state: \`merged_to_main\`, \`pushed_feature_branch_needs_merge\`, \`blocked_review\`, \`cleanup_candidate\`, or \`not_mergeable\`. Use \`mesh_status\` branchConvergenceSummary. For obvious clean branch catch-up (ahead 0, behind > 0, upstream fresh, no dirty/stash/submodule issues), use \`mesh_fast_forward_node\` dry-run first and execute only when explicitly safe/approved; this avoids consuming an agent session. Use \`mesh_refine_node\` for clean worktree branches when safe. Before/refine merging root commits that contain submodule gitlink changes, require each submodule commit to be reachable from the configured submodule remote main branch, not merely present on a feature ref or local checkout. If \`mesh_refine_node\` returns \`submodule_reachability_failed\` or publish-required evidence, keep the public convergence bucket as \`blocked_review\`; unless \`allowAutoPublishSubmoduleMainCommits\` is explicitly enabled and Refinery reports successful non-force publish plus post-publish verification, ask the user for explicit approval to push/publish the unreachable submodule commit(s) to submodule main, then rerun \`mesh_refine_node\`. Do not merge the root branch until the submodule commit(s) are reachable from submodule origin/main. A task that remains on a non-main branch is not fully complete unless the final report names the follow-up state and next step.
|
|
@@ -4389,6 +4399,34 @@ var init_mesh_runtime_store = __esm({
|
|
|
4389
4399
|
).get(meshId);
|
|
4390
4400
|
return row?.cnt ?? 0;
|
|
4391
4401
|
}
|
|
4402
|
+
/**
|
|
4403
|
+
* Mark specific pending-event rows drained by id (ack). Used by the
|
|
4404
|
+
* unresolved-delegate durable-forward outbox: an event is peeked (not drained)
|
|
4405
|
+
* while its push to the coordinator is unconfirmed, then marked drained ONLY
|
|
4406
|
+
* after the push is acked. A failed push leaves the row undrained so the next
|
|
4407
|
+
* reconcile tick retries it. Returns the number of rows newly marked drained.
|
|
4408
|
+
*/
|
|
4409
|
+
markPendingEventsDrainedById(ids) {
|
|
4410
|
+
const idList = ids.filter((id) => typeof id === "string" && id.length > 0);
|
|
4411
|
+
if (idList.length === 0) return 0;
|
|
4412
|
+
const now = Date.now();
|
|
4413
|
+
return this.db.prepare(
|
|
4414
|
+
`UPDATE mesh_pending_events SET drained = 1, drained_at = ? WHERE drained = 0 AND id IN (${idList.map(() => "?").join(",")})`
|
|
4415
|
+
).run(now, ...idList).changes;
|
|
4416
|
+
}
|
|
4417
|
+
/**
|
|
4418
|
+
* Hard-delete pending-event rows by id (including the dedup fingerprint history).
|
|
4419
|
+
* Used to expire an unresolved-delegate outbox entry that has exhausted its retry
|
|
4420
|
+
* budget — fully removing it frees the fingerprint so a genuinely new completion
|
|
4421
|
+
* for the same task could be re-queued later. Returns the number of rows deleted.
|
|
4422
|
+
*/
|
|
4423
|
+
deletePendingEventsById(ids) {
|
|
4424
|
+
const idList = ids.filter((id) => typeof id === "string" && id.length > 0);
|
|
4425
|
+
if (idList.length === 0) return 0;
|
|
4426
|
+
return this.db.prepare(
|
|
4427
|
+
`DELETE FROM mesh_pending_events WHERE id IN (${idList.map(() => "?").join(",")})`
|
|
4428
|
+
).run(...idList).changes;
|
|
4429
|
+
}
|
|
4392
4430
|
};
|
|
4393
4431
|
}
|
|
4394
4432
|
});
|
|
@@ -4396,6 +4434,7 @@ var init_mesh_runtime_store = __esm({
|
|
|
4396
4434
|
// src/mesh/mesh-missions.ts
|
|
4397
4435
|
var mesh_missions_exports = {};
|
|
4398
4436
|
__export(mesh_missions_exports, {
|
|
4437
|
+
GOAL_PREVIEW_MAX: () => GOAL_PREVIEW_MAX,
|
|
4399
4438
|
MESH_MISSION_STATUSES: () => MESH_MISSION_STATUSES,
|
|
4400
4439
|
buildMissionPromptSection: () => buildMissionPromptSection,
|
|
4401
4440
|
getActiveMeshMissionSummaries: () => getActiveMeshMissionSummaries,
|
|
@@ -4468,12 +4507,23 @@ function summarizeMeshMission(meshId, mission) {
|
|
|
4468
4507
|
function getActiveMeshMissionSummaries(meshId) {
|
|
4469
4508
|
return getMeshMissions(meshId, ["active"]).map((mission) => summarizeMeshMission(meshId, mission));
|
|
4470
4509
|
}
|
|
4510
|
+
function slimMissionSummary(summary) {
|
|
4511
|
+
const goal = typeof summary.goal === "string" ? summary.goal : "";
|
|
4512
|
+
const goalTruncated = goal.length > GOAL_PREVIEW_MAX;
|
|
4513
|
+
const { goal: _omitGoal, ...rest } = summary;
|
|
4514
|
+
return {
|
|
4515
|
+
...rest,
|
|
4516
|
+
goalPreview: goalTruncated ? goal.slice(0, GOAL_PREVIEW_MAX) : goal,
|
|
4517
|
+
goalTruncated
|
|
4518
|
+
};
|
|
4519
|
+
}
|
|
4471
4520
|
function getMeshStatusMissionSummaries(meshId, options) {
|
|
4472
4521
|
const historyLimit = Math.max(0, options?.historyLimit ?? 10);
|
|
4473
4522
|
const all = getMeshMissions(meshId);
|
|
4474
4523
|
const live = all.filter((m) => m.status === "active" || m.status === "paused");
|
|
4475
4524
|
const history = all.filter((m) => m.status === "completed" || m.status === "abandoned").sort((a, b) => (b.updatedAt || "").localeCompare(a.updatedAt || "")).slice(0, historyLimit);
|
|
4476
|
-
|
|
4525
|
+
const full = [...live, ...history].map((mission) => summarizeMeshMission(meshId, mission));
|
|
4526
|
+
return options?.verbose ? full : full.map(slimMissionSummary);
|
|
4477
4527
|
}
|
|
4478
4528
|
function buildMissionPromptSection(meshId) {
|
|
4479
4529
|
const summaries = getActiveMeshMissionSummaries(meshId);
|
|
@@ -4493,13 +4543,14 @@ function buildMissionPromptSection(meshId) {
|
|
|
4493
4543
|
);
|
|
4494
4544
|
return lines.join("\n");
|
|
4495
4545
|
}
|
|
4496
|
-
var MESH_MISSION_STATUSES;
|
|
4546
|
+
var MESH_MISSION_STATUSES, GOAL_PREVIEW_MAX;
|
|
4497
4547
|
var init_mesh_missions = __esm({
|
|
4498
4548
|
"src/mesh/mesh-missions.ts"() {
|
|
4499
4549
|
"use strict";
|
|
4500
4550
|
init_mesh_runtime_store();
|
|
4501
4551
|
init_mesh_work_queue();
|
|
4502
4552
|
MESH_MISSION_STATUSES = ["active", "paused", "completed", "abandoned"];
|
|
4553
|
+
GOAL_PREVIEW_MAX = 120;
|
|
4503
4554
|
}
|
|
4504
4555
|
});
|
|
4505
4556
|
|
|
@@ -6178,11 +6229,225 @@ var init_mesh_fast_forward = __esm({
|
|
|
6178
6229
|
}
|
|
6179
6230
|
});
|
|
6180
6231
|
|
|
6232
|
+
// ../mesh-shared/dist/index.mjs
|
|
6233
|
+
function readRecord3(value) {
|
|
6234
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
6235
|
+
}
|
|
6236
|
+
function readString5(...values) {
|
|
6237
|
+
for (const value of values) {
|
|
6238
|
+
if (typeof value !== "string") continue;
|
|
6239
|
+
const trimmed = value.trim();
|
|
6240
|
+
if (trimmed) return trimmed;
|
|
6241
|
+
}
|
|
6242
|
+
return void 0;
|
|
6243
|
+
}
|
|
6244
|
+
function readNumber(...values) {
|
|
6245
|
+
for (const value of values) {
|
|
6246
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
6247
|
+
}
|
|
6248
|
+
return void 0;
|
|
6249
|
+
}
|
|
6250
|
+
function readBoolean(...values) {
|
|
6251
|
+
for (const value of values) {
|
|
6252
|
+
if (typeof value === "boolean") return value;
|
|
6253
|
+
}
|
|
6254
|
+
return void 0;
|
|
6255
|
+
}
|
|
6256
|
+
function joinRepoPath(root, relativePath) {
|
|
6257
|
+
const normalizedRoot = typeof root === "string" ? root.trim().replace(/[\\/]+$/, "") : "";
|
|
6258
|
+
const normalizedPath = typeof relativePath === "string" ? relativePath.trim() : "";
|
|
6259
|
+
if (!normalizedPath) return void 0;
|
|
6260
|
+
if (/^(?:[A-Za-z]:[\\/]|\/)/.test(normalizedPath)) return normalizedPath;
|
|
6261
|
+
if (!normalizedRoot) return void 0;
|
|
6262
|
+
return `${normalizedRoot}/${normalizedPath.replace(/^[\\/]+/, "")}`;
|
|
6263
|
+
}
|
|
6264
|
+
function scoreGitUpstreamFreshness(status) {
|
|
6265
|
+
switch (status) {
|
|
6266
|
+
case "fresh":
|
|
6267
|
+
return 30;
|
|
6268
|
+
case "no_upstream":
|
|
6269
|
+
return 4;
|
|
6270
|
+
case "unchecked":
|
|
6271
|
+
case void 0:
|
|
6272
|
+
return 0;
|
|
6273
|
+
case "stale":
|
|
6274
|
+
return -10;
|
|
6275
|
+
case "unavailable":
|
|
6276
|
+
return -15;
|
|
6277
|
+
default:
|
|
6278
|
+
return 0;
|
|
6279
|
+
}
|
|
6280
|
+
}
|
|
6281
|
+
function readGitSubmodules(value, parentRepoRoot) {
|
|
6282
|
+
if (!Array.isArray(value)) return void 0;
|
|
6283
|
+
const submodules = value.map((entry) => {
|
|
6284
|
+
const submodule = readRecord3(entry);
|
|
6285
|
+
const path40 = readString5(submodule.path);
|
|
6286
|
+
const commit = readString5(submodule.commit);
|
|
6287
|
+
const repoPath = readString5(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot, path40);
|
|
6288
|
+
if (!path40 || !commit) return null;
|
|
6289
|
+
const result = {
|
|
6290
|
+
path: path40,
|
|
6291
|
+
commit,
|
|
6292
|
+
dirty: readBoolean(submodule.dirty) ?? false,
|
|
6293
|
+
outOfSync: readBoolean(submodule.outOfSync, submodule.out_of_sync) ?? false,
|
|
6294
|
+
lastCheckedAt: readNumber(submodule.lastCheckedAt, submodule.last_checked_at) ?? Date.now()
|
|
6295
|
+
};
|
|
6296
|
+
if (repoPath) result.repoPath = repoPath;
|
|
6297
|
+
const error = readString5(submodule.error);
|
|
6298
|
+
if (error) result.error = error;
|
|
6299
|
+
return result;
|
|
6300
|
+
}).filter((entry) => entry !== null);
|
|
6301
|
+
return submodules.length > 0 ? submodules : void 0;
|
|
6302
|
+
}
|
|
6303
|
+
function hasGitStatusEvidence(status) {
|
|
6304
|
+
return readBoolean(status.isGitRepo) !== void 0 || Boolean(readString5(status.branch, status.upstream, status.upstreamStatus, status.upstream_status, status.headCommit)) || Boolean(readString5(status.repoRoot, status.repo_root, status.workspace)) || readNumber(
|
|
6305
|
+
status.ahead,
|
|
6306
|
+
status.behind,
|
|
6307
|
+
status.staged,
|
|
6308
|
+
status.modified,
|
|
6309
|
+
status.untracked,
|
|
6310
|
+
status.deleted,
|
|
6311
|
+
status.renamed,
|
|
6312
|
+
status.lastCheckedAt,
|
|
6313
|
+
status.last_checked_at
|
|
6314
|
+
) !== void 0 || Array.isArray(status.submodules) && status.submodules.length > 0;
|
|
6315
|
+
}
|
|
6316
|
+
function normalizeGitStatus(status, node, options) {
|
|
6317
|
+
const explicitIsGitRepo = readBoolean(status.isGitRepo);
|
|
6318
|
+
if (!Object.keys(status).length || !hasGitStatusEvidence(status)) return void 0;
|
|
6319
|
+
const isGitRepo = explicitIsGitRepo ?? true;
|
|
6320
|
+
const conflictFiles = Array.isArray(status.conflictFiles) ? status.conflictFiles.filter((entry) => typeof entry === "string") : [];
|
|
6321
|
+
const conflictCount = readNumber(status.conflicts) ?? conflictFiles.length;
|
|
6322
|
+
const hasConflicts = readBoolean(status.hasConflicts) ?? conflictCount > 0;
|
|
6323
|
+
const repoRoot = readString5(status.repoRoot, status.repo_root, node.repoRoot, node.repo_root, status.workspace, node.workspace) || void 0;
|
|
6324
|
+
const submodules = readGitSubmodules(status.submodules, repoRoot);
|
|
6325
|
+
const upstreamStatus = readString5(status.upstreamStatus, status.upstream_status);
|
|
6326
|
+
const upstreamFetchedAt = readNumber(status.upstreamFetchedAt, status.upstream_fetched_at);
|
|
6327
|
+
const upstreamFetchError = readString5(status.upstreamFetchError, status.upstream_fetch_error);
|
|
6328
|
+
const error = readString5(status.error);
|
|
6329
|
+
const staged = readNumber(status.staged) ?? 0;
|
|
6330
|
+
const modified = readNumber(status.modified) ?? 0;
|
|
6331
|
+
const untracked = readNumber(status.untracked) ?? 0;
|
|
6332
|
+
const deleted = readNumber(status.deleted) ?? 0;
|
|
6333
|
+
const renamed = readNumber(status.renamed) ?? 0;
|
|
6334
|
+
return {
|
|
6335
|
+
workspace: readString5(status.workspace, node.workspace) || "",
|
|
6336
|
+
repoRoot: repoRoot ?? null,
|
|
6337
|
+
isGitRepo,
|
|
6338
|
+
branch: readString5(status.branch) ?? null,
|
|
6339
|
+
headCommit: readString5(status.headCommit) ?? null,
|
|
6340
|
+
headMessage: readString5(status.headMessage) ?? null,
|
|
6341
|
+
upstream: readString5(status.upstream) ?? null,
|
|
6342
|
+
upstreamStatus: upstreamStatus ?? "unchecked",
|
|
6343
|
+
...upstreamFetchedAt !== void 0 ? { upstreamFetchedAt } : {},
|
|
6344
|
+
...upstreamFetchError ? { upstreamFetchError } : {},
|
|
6345
|
+
ahead: readNumber(status.ahead) ?? 0,
|
|
6346
|
+
behind: readNumber(status.behind) ?? 0,
|
|
6347
|
+
staged,
|
|
6348
|
+
modified,
|
|
6349
|
+
untracked,
|
|
6350
|
+
deleted,
|
|
6351
|
+
renamed,
|
|
6352
|
+
dirty: readBoolean(status.dirty, status.isDirty, status.is_dirty) ?? (staged + modified + untracked + deleted + renamed > 0 || hasConflicts),
|
|
6353
|
+
hasConflicts,
|
|
6354
|
+
conflictFiles,
|
|
6355
|
+
stashCount: readNumber(status.stashCount, status.stash_count) ?? 0,
|
|
6356
|
+
lastCheckedAt: options?.lastCheckedAt ?? readNumber(status.lastCheckedAt, status.last_checked_at) ?? Date.now(),
|
|
6357
|
+
...submodules ? { submodules } : {},
|
|
6358
|
+
...error ? { error } : {}
|
|
6359
|
+
};
|
|
6360
|
+
}
|
|
6361
|
+
function scoreGitStatusCandidate(git) {
|
|
6362
|
+
if (!git) return Number.NEGATIVE_INFINITY;
|
|
6363
|
+
let score = 0;
|
|
6364
|
+
if (git.isGitRepo === true) score += 50;
|
|
6365
|
+
if (git.isGitRepo === false) score -= 10;
|
|
6366
|
+
if (git.branch) score += 20;
|
|
6367
|
+
if (git.headCommit) score += 20;
|
|
6368
|
+
if (git.upstream) score += 10;
|
|
6369
|
+
score += scoreGitUpstreamFreshness(git.upstreamStatus);
|
|
6370
|
+
if (typeof git.ahead === "number") score += 2;
|
|
6371
|
+
if (typeof git.behind === "number") score += 2;
|
|
6372
|
+
if (Array.isArray(git.submodules) && git.submodules.length > 0) score += 4 + git.submodules.length;
|
|
6373
|
+
if (git.error) score -= 20;
|
|
6374
|
+
return score;
|
|
6375
|
+
}
|
|
6376
|
+
function pickBestTransitGitStatus(node, options) {
|
|
6377
|
+
const rawGit = readRecord3(node.lastGit ?? node.last_git);
|
|
6378
|
+
const gitResult = readRecord3(rawGit.result);
|
|
6379
|
+
const directStatus = readRecord3(rawGit.status);
|
|
6380
|
+
const nestedStatus = readRecord3(gitResult.status);
|
|
6381
|
+
const rawProbe = readRecord3(node.lastProbe ?? node.last_probe);
|
|
6382
|
+
const probeGit = readRecord3(rawProbe.git);
|
|
6383
|
+
const probeGitResult = readRecord3(probeGit.result);
|
|
6384
|
+
const probeDirectStatus = readRecord3(probeGit.status);
|
|
6385
|
+
const probeNestedStatus = readRecord3(probeGitResult.status);
|
|
6386
|
+
const lastCheckedAt = options?.lastCheckedAt;
|
|
6387
|
+
let best = null;
|
|
6388
|
+
for (const status of [directStatus, nestedStatus, probeDirectStatus, probeNestedStatus]) {
|
|
6389
|
+
const normalized = normalizeGitStatus(status, node, { lastCheckedAt: lastCheckedAt ?? Date.now() });
|
|
6390
|
+
if (!normalized) continue;
|
|
6391
|
+
const score = scoreGitStatusCandidate(normalized);
|
|
6392
|
+
if (!best || score > best.score) best = { git: normalized, score };
|
|
6393
|
+
}
|
|
6394
|
+
return best?.git;
|
|
6395
|
+
}
|
|
6396
|
+
function normalizeMeshNodeId(node) {
|
|
6397
|
+
const record = node && typeof node === "object" ? node : {};
|
|
6398
|
+
return readString5(record.id, record.nodeId, record.node_id);
|
|
6399
|
+
}
|
|
6400
|
+
function meshNodeIdMatches(node, candidateId) {
|
|
6401
|
+
if (!candidateId) return false;
|
|
6402
|
+
const trimmed = candidateId.trim();
|
|
6403
|
+
if (!trimmed) return false;
|
|
6404
|
+
return normalizeMeshNodeId(node) === trimmed;
|
|
6405
|
+
}
|
|
6406
|
+
function summarizeGitShape(status) {
|
|
6407
|
+
const record = readRecord3(status);
|
|
6408
|
+
if (!Object.keys(record).length) return null;
|
|
6409
|
+
const submodules = Array.isArray(record.submodules) ? record.submodules.map((entry) => {
|
|
6410
|
+
const sub = readRecord3(entry);
|
|
6411
|
+
return {
|
|
6412
|
+
path: readString5(sub.path) ?? null,
|
|
6413
|
+
commit: readString5(sub.commit)?.slice(0, 12) ?? null,
|
|
6414
|
+
dirty: readBoolean(sub.dirty) ?? false,
|
|
6415
|
+
outOfSync: readBoolean(sub.outOfSync, sub.out_of_sync) ?? false
|
|
6416
|
+
};
|
|
6417
|
+
}) : [];
|
|
6418
|
+
return {
|
|
6419
|
+
isGitRepo: readBoolean(record.isGitRepo),
|
|
6420
|
+
workspace: readString5(record.workspace) ?? null,
|
|
6421
|
+
repoRoot: readString5(record.repoRoot, record.repo_root) ?? null,
|
|
6422
|
+
branch: readString5(record.branch) ?? null,
|
|
6423
|
+
upstream: readString5(record.upstream) ?? null,
|
|
6424
|
+
upstreamStatus: readString5(record.upstreamStatus, record.upstream_status) ?? null,
|
|
6425
|
+
headCommit: readString5(record.headCommit, record.head_commit)?.slice(0, 12) ?? null,
|
|
6426
|
+
ahead: readNumber(record.ahead) ?? null,
|
|
6427
|
+
behind: readNumber(record.behind) ?? null,
|
|
6428
|
+
dirtyCounts: {
|
|
6429
|
+
staged: readNumber(record.staged) ?? 0,
|
|
6430
|
+
modified: readNumber(record.modified) ?? 0,
|
|
6431
|
+
untracked: readNumber(record.untracked) ?? 0,
|
|
6432
|
+
deleted: readNumber(record.deleted) ?? 0,
|
|
6433
|
+
renamed: readNumber(record.renamed) ?? 0
|
|
6434
|
+
},
|
|
6435
|
+
lastCheckedAt: readNumber(record.lastCheckedAt, record.last_checked_at) ?? null,
|
|
6436
|
+
submoduleCount: submodules.length,
|
|
6437
|
+
submodules
|
|
6438
|
+
};
|
|
6439
|
+
}
|
|
6440
|
+
var init_dist = __esm({
|
|
6441
|
+
"../mesh-shared/dist/index.mjs"() {
|
|
6442
|
+
"use strict";
|
|
6443
|
+
}
|
|
6444
|
+
});
|
|
6445
|
+
|
|
6181
6446
|
// src/mesh/mesh-events-utils.ts
|
|
6182
6447
|
function readNonEmptyString2(value) {
|
|
6183
6448
|
return typeof value === "string" && value.trim() ? value.trim() : "";
|
|
6184
6449
|
}
|
|
6185
|
-
function
|
|
6450
|
+
function readRecord4(value) {
|
|
6186
6451
|
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
6187
6452
|
}
|
|
6188
6453
|
function buildMeshWorkerRelayStamp(currentSettings, meshContext) {
|
|
@@ -6206,13 +6471,13 @@ function resolveEventSessionId(event, fallback) {
|
|
|
6206
6471
|
return readNonEmptyString2(event.targetSessionId) || readNonEmptyString2(event.sessionId) || readNonEmptyString2(event.instanceId) || readNonEmptyString2(fallback);
|
|
6207
6472
|
}
|
|
6208
6473
|
function readRefineJobId(event) {
|
|
6209
|
-
const metadata =
|
|
6210
|
-
const result =
|
|
6211
|
-
const refineJob =
|
|
6474
|
+
const metadata = readRecord4(event.metadataEvent) || event;
|
|
6475
|
+
const result = readRecord4(metadata.result);
|
|
6476
|
+
const refineJob = readRecord4(result?.refineJob);
|
|
6212
6477
|
return readNonEmptyString2(metadata.jobId) || readNonEmptyString2(refineJob?.jobId);
|
|
6213
6478
|
}
|
|
6214
6479
|
function readWorkerResultMetadata(event) {
|
|
6215
|
-
return
|
|
6480
|
+
return readRecord4(event.workerResult) || readRecord4(event.meshWorkerResult) || readRecord4(event.structuredResult);
|
|
6216
6481
|
}
|
|
6217
6482
|
function formatCompletionMetadata(event) {
|
|
6218
6483
|
const completionDiagnostic = event.completionDiagnostic && typeof event.completionDiagnostic === "object" ? event.completionDiagnostic : null;
|
|
@@ -6290,10 +6555,10 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
6290
6555
|
}
|
|
6291
6556
|
if (args.event === "refine:completed") {
|
|
6292
6557
|
const jobId = readRefineJobId({ metadataEvent: args.metadataEvent });
|
|
6293
|
-
const result =
|
|
6294
|
-
const validationSummary =
|
|
6295
|
-
const patchEquivalence =
|
|
6296
|
-
const finalConvergence =
|
|
6558
|
+
const result = readRecord4(args.metadataEvent.result);
|
|
6559
|
+
const validationSummary = readRecord4(result?.validationSummary);
|
|
6560
|
+
const patchEquivalence = readRecord4(result?.patchEquivalence);
|
|
6561
|
+
const finalConvergence = readRecord4(result?.finalBranchConvergenceState);
|
|
6297
6562
|
const validationStatus = readNonEmptyString2(validationSummary?.status);
|
|
6298
6563
|
const patchStatus = readNonEmptyString2(patchEquivalence?.status) || (patchEquivalence?.equivalent === true ? "passed" : "");
|
|
6299
6564
|
const into = readNonEmptyString2(result?.into);
|
|
@@ -6314,10 +6579,10 @@ Next step: ${nextStep}`;
|
|
|
6314
6579
|
}
|
|
6315
6580
|
if (args.event === "refine:failed") {
|
|
6316
6581
|
const jobId = readRefineJobId({ metadataEvent: args.metadataEvent });
|
|
6317
|
-
const result =
|
|
6318
|
-
const validationSummary =
|
|
6319
|
-
const patchEquivalence =
|
|
6320
|
-
const finalConvergence =
|
|
6582
|
+
const result = readRecord4(args.metadataEvent.result);
|
|
6583
|
+
const validationSummary = readRecord4(result?.validationSummary);
|
|
6584
|
+
const patchEquivalence = readRecord4(result?.patchEquivalence);
|
|
6585
|
+
const finalConvergence = readRecord4(result?.finalBranchConvergenceState);
|
|
6321
6586
|
const code = readNonEmptyString2(result?.code);
|
|
6322
6587
|
const error = readNonEmptyString2(result?.error);
|
|
6323
6588
|
const validationStatus = readNonEmptyString2(validationSummary?.status);
|
|
@@ -6367,9 +6632,9 @@ function normalizeCoordinatorDaemonIds(coordinatorDaemonId) {
|
|
|
6367
6632
|
return out;
|
|
6368
6633
|
}
|
|
6369
6634
|
function readRefineJobId2(event) {
|
|
6370
|
-
const metadata =
|
|
6371
|
-
const result =
|
|
6372
|
-
const refineJob =
|
|
6635
|
+
const metadata = readRecord4(event.metadataEvent) || event;
|
|
6636
|
+
const result = readRecord4(metadata.result);
|
|
6637
|
+
const refineJob = readRecord4(result?.refineJob);
|
|
6373
6638
|
return readNonEmptyString2(metadata.jobId) || readNonEmptyString2(refineJob?.jobId);
|
|
6374
6639
|
}
|
|
6375
6640
|
function hasPendingRefineTerminalEventDuplicate(event) {
|
|
@@ -6381,13 +6646,13 @@ function hasPendingRefineTerminalEventDuplicate(event) {
|
|
|
6381
6646
|
);
|
|
6382
6647
|
}
|
|
6383
6648
|
function buildPendingEventFingerprint(event) {
|
|
6384
|
-
const metadata =
|
|
6649
|
+
const metadata = readRecord4(event.metadataEvent) || {};
|
|
6385
6650
|
if (event.event === "worktree_bootstrap_complete" || event.event === "worktree_bootstrap_failed") {
|
|
6386
6651
|
return [event.meshId, event.event, event.nodeId || ""].join("::");
|
|
6387
6652
|
}
|
|
6388
6653
|
const sessionId = resolveEventSessionId(metadata);
|
|
6389
6654
|
const providerSessionId = readNonEmptyString2(metadata.providerSessionId);
|
|
6390
|
-
const taskId = readNonEmptyString2(metadata.taskId) || readNonEmptyString2(
|
|
6655
|
+
const taskId = readNonEmptyString2(metadata.taskId) || readNonEmptyString2(readRecord4(metadata.payload)?.taskId);
|
|
6391
6656
|
const jobId = readRefineJobId2(event);
|
|
6392
6657
|
const timestamp = metadata.timestamp !== void 0 && metadata.timestamp !== null ? String(metadata.timestamp) : "";
|
|
6393
6658
|
return [
|
|
@@ -6455,15 +6720,15 @@ function refineTerminalEventFromLedger(meshId, pending) {
|
|
|
6455
6720
|
for (let i = entries.length - 1; i >= 0; i--) {
|
|
6456
6721
|
const entry = entries[i];
|
|
6457
6722
|
if (entry.kind !== "task_completed" && entry.kind !== "task_failed") continue;
|
|
6458
|
-
const payload =
|
|
6723
|
+
const payload = readRecord4(entry.payload);
|
|
6459
6724
|
if (payload?.source !== "refine_mesh_node_async_job") continue;
|
|
6460
|
-
const refineJob =
|
|
6725
|
+
const refineJob = readRecord4(payload.refineJob);
|
|
6461
6726
|
const jobId = readNonEmptyString2(refineJob?.jobId);
|
|
6462
6727
|
if (!jobId || !acceptedJobIds.has(jobId)) continue;
|
|
6463
6728
|
const eventName = entry.kind === "task_completed" ? "refine:completed" : "refine:failed";
|
|
6464
6729
|
if (existingTerminalJobIds.has(`${eventName}:${jobId}`)) continue;
|
|
6465
6730
|
existingTerminalJobIds.add(`${eventName}:${jobId}`);
|
|
6466
|
-
const result =
|
|
6731
|
+
const result = readRecord4(payload.result);
|
|
6467
6732
|
const metadataEvent = {
|
|
6468
6733
|
source: "refine_mesh_node_async_job",
|
|
6469
6734
|
jobId,
|
|
@@ -7068,7 +7333,7 @@ function buildLongGeneratingCompletionReconciliation(args) {
|
|
|
7068
7333
|
const providerType = readNonEmptyString2(args.metadataEvent.providerType);
|
|
7069
7334
|
const providerSessionId = readNonEmptyString2(args.metadataEvent.providerSessionId);
|
|
7070
7335
|
const workerResult = readWorkerResultMetadata(args.metadataEvent);
|
|
7071
|
-
const completionDiagnostic =
|
|
7336
|
+
const completionDiagnostic = readRecord4(args.metadataEvent.completionDiagnostic);
|
|
7072
7337
|
const finalSummary = readNonEmptyString2(args.metadataEvent.finalSummary);
|
|
7073
7338
|
const status = readNonEmptyString2(args.metadataEvent.status).toLowerCase();
|
|
7074
7339
|
const explicitCompletionEvidence = Boolean(
|
|
@@ -7383,6 +7648,111 @@ var init_mesh_routing = __esm({
|
|
|
7383
7648
|
}
|
|
7384
7649
|
});
|
|
7385
7650
|
|
|
7651
|
+
// src/mesh/mesh-unresolved-forward-outbox.ts
|
|
7652
|
+
import { randomUUID as randomUUID9 } from "crypto";
|
|
7653
|
+
function getStore() {
|
|
7654
|
+
try {
|
|
7655
|
+
return MeshRuntimeStore.getInstance();
|
|
7656
|
+
} catch {
|
|
7657
|
+
return void 0;
|
|
7658
|
+
}
|
|
7659
|
+
}
|
|
7660
|
+
function enqueueUnresolvedDelegateForward(coordinatorDaemonId, eventName, forwardPayload) {
|
|
7661
|
+
const target = readNonEmptyString2(coordinatorDaemonId);
|
|
7662
|
+
const event = readNonEmptyString2(eventName);
|
|
7663
|
+
if (!target || !event) return false;
|
|
7664
|
+
const store = getStore();
|
|
7665
|
+
if (!store) return false;
|
|
7666
|
+
const queuedAt = Date.now();
|
|
7667
|
+
const fingerprintSource = {
|
|
7668
|
+
event,
|
|
7669
|
+
meshId: UNRESOLVED_FORWARD_OUTBOX_MESH_ID,
|
|
7670
|
+
nodeLabel: readNonEmptyString2(forwardPayload.nodeId) || readNonEmptyString2(forwardPayload.workspace) || "unresolved-delegate",
|
|
7671
|
+
nodeId: readNonEmptyString2(forwardPayload.nodeId) || void 0,
|
|
7672
|
+
workspace: readNonEmptyString2(forwardPayload.workspace) || void 0,
|
|
7673
|
+
metadataEvent: forwardPayload,
|
|
7674
|
+
queuedAt,
|
|
7675
|
+
targetCoordinatorDaemonId: target
|
|
7676
|
+
};
|
|
7677
|
+
const fingerprint = `${target}::${buildPendingEventFingerprint(fingerprintSource)}`;
|
|
7678
|
+
try {
|
|
7679
|
+
const inserted = store.insertPendingEvent({
|
|
7680
|
+
id: randomUUID9(),
|
|
7681
|
+
meshId: UNRESOLVED_FORWARD_OUTBOX_MESH_ID,
|
|
7682
|
+
coordinatorDaemonId: target,
|
|
7683
|
+
event,
|
|
7684
|
+
// Store the flat forward payload + the queue timestamp so the retry tick can
|
|
7685
|
+
// rebuild the push args and apply age-based expiry without a schema change.
|
|
7686
|
+
payload: { forwardPayload, coordinatorDaemonId: target, queuedAt },
|
|
7687
|
+
fingerprint,
|
|
7688
|
+
queuedAt
|
|
7689
|
+
});
|
|
7690
|
+
if (inserted) {
|
|
7691
|
+
LOG.info("MeshEvents", `Durably queued unresolved-delegate ${event} for coordinator ${target} (outbox)`);
|
|
7692
|
+
}
|
|
7693
|
+
return true;
|
|
7694
|
+
} catch (e) {
|
|
7695
|
+
LOG.warn("MeshEvents", `Failed to persist unresolved-delegate forward to outbox: ${e?.message || e}`);
|
|
7696
|
+
return false;
|
|
7697
|
+
}
|
|
7698
|
+
}
|
|
7699
|
+
function peekUnresolvedDelegateForwards() {
|
|
7700
|
+
const store = getStore();
|
|
7701
|
+
if (!store) return [];
|
|
7702
|
+
let rows;
|
|
7703
|
+
try {
|
|
7704
|
+
rows = store.peekPendingEvents(UNRESOLVED_FORWARD_OUTBOX_MESH_ID);
|
|
7705
|
+
} catch {
|
|
7706
|
+
return [];
|
|
7707
|
+
}
|
|
7708
|
+
const out = [];
|
|
7709
|
+
for (const row of rows) {
|
|
7710
|
+
const stored = row.payload && typeof row.payload === "object" ? row.payload : {};
|
|
7711
|
+
const coordinatorDaemonId = readNonEmptyString2(stored.coordinatorDaemonId);
|
|
7712
|
+
const forwardPayload = stored.forwardPayload && typeof stored.forwardPayload === "object" ? stored.forwardPayload : void 0;
|
|
7713
|
+
if (!coordinatorDaemonId || !forwardPayload) continue;
|
|
7714
|
+
const queuedAt = typeof stored.queuedAt === "number" ? stored.queuedAt : 0;
|
|
7715
|
+
out.push({ id: row.id, coordinatorDaemonId, payload: forwardPayload, queuedAt });
|
|
7716
|
+
}
|
|
7717
|
+
return out;
|
|
7718
|
+
}
|
|
7719
|
+
function ackUnresolvedDelegateForward(id) {
|
|
7720
|
+
const store = getStore();
|
|
7721
|
+
if (!store) return;
|
|
7722
|
+
try {
|
|
7723
|
+
store.markPendingEventsDrainedById([id]);
|
|
7724
|
+
} catch {
|
|
7725
|
+
}
|
|
7726
|
+
}
|
|
7727
|
+
function expireStaleUnresolvedDelegateForwards(nowMs = Date.now()) {
|
|
7728
|
+
const entries = peekUnresolvedDelegateForwards();
|
|
7729
|
+
const staleIds = entries.filter((e) => e.queuedAt > 0 && nowMs - e.queuedAt >= UNRESOLVED_FORWARD_MAX_AGE_MS).map((e) => e.id);
|
|
7730
|
+
if (staleIds.length === 0) return 0;
|
|
7731
|
+
const store = getStore();
|
|
7732
|
+
if (!store) return 0;
|
|
7733
|
+
try {
|
|
7734
|
+
const removed = store.deletePendingEventsById(staleIds);
|
|
7735
|
+
if (removed > 0) {
|
|
7736
|
+
LOG.warn("MeshEvents", `Expired ${removed} unresolved-delegate forward(s) after ${Math.round(UNRESOLVED_FORWARD_MAX_AGE_MS / 6e4)}m of failed retries \u2014 coordinator unreachable, completion dropped`);
|
|
7737
|
+
}
|
|
7738
|
+
return removed;
|
|
7739
|
+
} catch {
|
|
7740
|
+
return 0;
|
|
7741
|
+
}
|
|
7742
|
+
}
|
|
7743
|
+
var UNRESOLVED_FORWARD_OUTBOX_MESH_ID, UNRESOLVED_FORWARD_MAX_AGE_MS;
|
|
7744
|
+
var init_mesh_unresolved_forward_outbox = __esm({
|
|
7745
|
+
"src/mesh/mesh-unresolved-forward-outbox.ts"() {
|
|
7746
|
+
"use strict";
|
|
7747
|
+
init_logger();
|
|
7748
|
+
init_mesh_runtime_store();
|
|
7749
|
+
init_mesh_events_pending();
|
|
7750
|
+
init_mesh_events_utils();
|
|
7751
|
+
UNRESOLVED_FORWARD_OUTBOX_MESH_ID = "__unresolved_forward_outbox__";
|
|
7752
|
+
UNRESOLVED_FORWARD_MAX_AGE_MS = 30 * 60 * 1e3;
|
|
7753
|
+
}
|
|
7754
|
+
});
|
|
7755
|
+
|
|
7386
7756
|
// src/mesh/mesh-events-coordinator.ts
|
|
7387
7757
|
import { existsSync as existsSync14 } from "fs";
|
|
7388
7758
|
function resolveCoordinatorDrainDaemonIds(components) {
|
|
@@ -7788,7 +8158,7 @@ async function resolveUsableProvider(components, nodeId, node, requiredTags) {
|
|
|
7788
8158
|
return { reason: `provider_priority_unusable: ${failed.join("; ") || nodeId}` };
|
|
7789
8159
|
}
|
|
7790
8160
|
function readMeshNodeId(node) {
|
|
7791
|
-
return
|
|
8161
|
+
return normalizeMeshNodeId(node) ?? "";
|
|
7792
8162
|
}
|
|
7793
8163
|
async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
|
|
7794
8164
|
const queue = getQueue(meshId);
|
|
@@ -8017,7 +8387,7 @@ async function triggerMeshQueue(components, meshId) {
|
|
|
8017
8387
|
}
|
|
8018
8388
|
async function maybeAutoFastForwardIdleNode(components, args) {
|
|
8019
8389
|
const mesh = getMeshWithCache(components, args.meshId);
|
|
8020
|
-
const node = mesh?.nodes?.find((candidate) => candidate
|
|
8390
|
+
const node = mesh?.nodes?.find((candidate) => meshNodeIdMatches(candidate, args.nodeId));
|
|
8021
8391
|
const workspace = readNonEmptyString2(node?.workspace);
|
|
8022
8392
|
if (!workspace) return;
|
|
8023
8393
|
if (!existsSync14(workspace)) return;
|
|
@@ -8518,12 +8888,25 @@ function forwardUnresolvedDelegateEvent(components, routing, event) {
|
|
|
8518
8888
|
nodeId: readNonEmptyString2(routing.nodeId) || readNonEmptyString2(event.meshNodeId) || void 0,
|
|
8519
8889
|
workspace: readNonEmptyString2(routing.workspace) || readNonEmptyString2(event.workspace) || void 0
|
|
8520
8890
|
};
|
|
8521
|
-
|
|
8522
|
-
|
|
8891
|
+
const persisted = enqueueUnresolvedDelegateForward(coordinatorDaemonId, eventName, payload);
|
|
8892
|
+
Promise.resolve(components.dispatchMeshCommand(coordinatorDaemonId, "mesh_forward_event", payload)).then((result) => {
|
|
8893
|
+
if (result && result.success === false) {
|
|
8894
|
+
LOG.warn("MeshEvents", `Immediate forward of ${eventName} to coordinator ${coordinatorDaemonId} rejected (${readNonEmptyString2(result.error) || "no reason"}) \u2014 left queued for retry`);
|
|
8895
|
+
return;
|
|
8896
|
+
}
|
|
8897
|
+
if (persisted) ackUnresolvedDelegateForwardByFingerprint(coordinatorDaemonId, eventName, payload);
|
|
8898
|
+
}).catch((e) => {
|
|
8899
|
+
LOG.warn("MeshEvents", `Immediate forward of ${eventName} to coordinator ${coordinatorDaemonId} failed: ${e?.message || e} \u2014 left queued for retry`);
|
|
8523
8900
|
});
|
|
8524
|
-
LOG.info("MeshEvents", `
|
|
8901
|
+
LOG.info("MeshEvents", `Durably forwarded ${eventName} for unresolved-mesh worker at ${routing.workspace || "(no workspace)"} to coordinator daemon ${coordinatorDaemonId}`);
|
|
8525
8902
|
return true;
|
|
8526
8903
|
}
|
|
8904
|
+
function ackUnresolvedDelegateForwardByFingerprint(coordinatorDaemonId, eventName, payload) {
|
|
8905
|
+
const match = peekUnresolvedDelegateForwards().find(
|
|
8906
|
+
(entry) => entry.coordinatorDaemonId === coordinatorDaemonId && readNonEmptyString2(entry.payload.event) === eventName && readNonEmptyString2(entry.payload.targetSessionId || entry.payload.sessionId || entry.payload.instanceId) === readNonEmptyString2(payload.targetSessionId || payload.sessionId || payload.instanceId) && readNonEmptyString2(entry.payload.workspace) === readNonEmptyString2(payload.workspace)
|
|
8907
|
+
);
|
|
8908
|
+
if (match) ackUnresolvedDelegateForward(match.id);
|
|
8909
|
+
}
|
|
8527
8910
|
function setupMeshEventForwarding(components) {
|
|
8528
8911
|
components.instanceManager.onEvent((event) => {
|
|
8529
8912
|
if (event.event === "agent:ready" || event.event === "agent:generating_completed") {
|
|
@@ -8604,7 +8987,9 @@ var init_mesh_events_coordinator = __esm({
|
|
|
8604
8987
|
init_mesh_runtime_store();
|
|
8605
8988
|
init_mesh_events_pending();
|
|
8606
8989
|
init_mesh_routing();
|
|
8990
|
+
init_mesh_unresolved_forward_outbox();
|
|
8607
8991
|
init_repo_mesh_types();
|
|
8992
|
+
init_dist();
|
|
8608
8993
|
init_mesh_events_stale();
|
|
8609
8994
|
init_mesh_events_utils();
|
|
8610
8995
|
REMOTE_IDLE_SESSION_TTL_MS = 5 * 60 * 1e3;
|
|
@@ -8718,6 +9103,13 @@ async function runMeshReconcileTick(components) {
|
|
|
8718
9103
|
return void 0;
|
|
8719
9104
|
}
|
|
8720
9105
|
})();
|
|
9106
|
+
if (dispatchMeshCommand) {
|
|
9107
|
+
try {
|
|
9108
|
+
await retryUnresolvedDelegateForwards(components);
|
|
9109
|
+
} catch (e) {
|
|
9110
|
+
LOG.warn("MeshReconcile", `Unresolved-delegate forward retry failed: ${e?.message || e}`);
|
|
9111
|
+
}
|
|
9112
|
+
}
|
|
8721
9113
|
if (dispatchMeshCommand) {
|
|
8722
9114
|
for (const mesh of listMeshes()) {
|
|
8723
9115
|
const selfIds = resolveCoordinatorSelfIds(mesh, drainDaemonIds);
|
|
@@ -8771,6 +9163,28 @@ async function runMeshReconcileTick(components) {
|
|
|
8771
9163
|
}
|
|
8772
9164
|
}
|
|
8773
9165
|
}
|
|
9166
|
+
async function retryUnresolvedDelegateForwards(components) {
|
|
9167
|
+
const dispatchMeshCommand = components.dispatchMeshCommand;
|
|
9168
|
+
if (!dispatchMeshCommand) return;
|
|
9169
|
+
expireStaleUnresolvedDelegateForwards();
|
|
9170
|
+
const entries = peekUnresolvedDelegateForwards();
|
|
9171
|
+
if (entries.length === 0) return;
|
|
9172
|
+
for (const entry of entries) {
|
|
9173
|
+
let result;
|
|
9174
|
+
try {
|
|
9175
|
+
result = await dispatchMeshCommand(entry.coordinatorDaemonId, "mesh_forward_event", entry.payload);
|
|
9176
|
+
} catch (e) {
|
|
9177
|
+
LOG.warn("MeshReconcile", `Retry forward to coordinator ${entry.coordinatorDaemonId} failed: ${e?.message || e} \u2014 left queued`);
|
|
9178
|
+
continue;
|
|
9179
|
+
}
|
|
9180
|
+
if (result && result.success === false) {
|
|
9181
|
+
LOG.warn("MeshReconcile", `Retry forward to coordinator ${entry.coordinatorDaemonId} rejected (${readNonEmptyString2(result.error) || "no reason"}) \u2014 left queued`);
|
|
9182
|
+
continue;
|
|
9183
|
+
}
|
|
9184
|
+
ackUnresolvedDelegateForward(entry.id);
|
|
9185
|
+
LOG.info("MeshReconcile", `Retried+delivered unresolved-delegate ${readNonEmptyString2(entry.payload.event)} to coordinator ${entry.coordinatorDaemonId}`);
|
|
9186
|
+
}
|
|
9187
|
+
}
|
|
8774
9188
|
async function pullRemoteNodeQueues(components, mesh, localDaemonId, candidateDaemonIds) {
|
|
8775
9189
|
const dispatchMeshCommand = components.dispatchMeshCommand;
|
|
8776
9190
|
if (!dispatchMeshCommand) return;
|
|
@@ -8847,6 +9261,7 @@ var init_mesh_reconcile_loop = __esm({
|
|
|
8847
9261
|
init_mesh_events_pending();
|
|
8848
9262
|
init_mesh_runtime_store();
|
|
8849
9263
|
init_mesh_events_coordinator();
|
|
9264
|
+
init_mesh_unresolved_forward_outbox();
|
|
8850
9265
|
init_mesh_events_utils();
|
|
8851
9266
|
DEFAULT_RECONCILE_INTERVAL_MS = 4e3;
|
|
8852
9267
|
}
|
|
@@ -17191,9 +17606,10 @@ function buildMeshLedgerReconciliationEvidence(meshId, replicas) {
|
|
|
17191
17606
|
init_mesh_work_queue();
|
|
17192
17607
|
|
|
17193
17608
|
// src/mesh/mesh-active-work.ts
|
|
17609
|
+
init_dist();
|
|
17194
17610
|
var DIRECT_DISPATCH_VIA = /* @__PURE__ */ new Set(["p2p_direct", "local_direct", "mesh_send_task"]);
|
|
17195
17611
|
var TERMINAL_LEDGER_KINDS = /* @__PURE__ */ new Set(["task_completed", "task_failed", "task_stalled"]);
|
|
17196
|
-
function
|
|
17612
|
+
function readString6(value) {
|
|
17197
17613
|
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
17198
17614
|
}
|
|
17199
17615
|
function summarizeMessage(message) {
|
|
@@ -17208,7 +17624,7 @@ function elapsedSince(value, now) {
|
|
|
17208
17624
|
function sessionStatusFromNodes(nodes, nodeId, sessionId) {
|
|
17209
17625
|
if (!Array.isArray(nodes)) return {};
|
|
17210
17626
|
if (!nodeId) return { staleReason: "direct task has no node id" };
|
|
17211
|
-
const node = nodes.find((item) =>
|
|
17627
|
+
const node = nodes.find((item) => meshNodeIdMatches(item, nodeId));
|
|
17212
17628
|
if (!node) return { staleReason: "direct task node is no longer in the live mesh" };
|
|
17213
17629
|
if (!sessionId) return {};
|
|
17214
17630
|
const candidates = [];
|
|
@@ -17232,12 +17648,12 @@ function sessionStatusFromNodes(nodes, nodeId, sessionId) {
|
|
|
17232
17648
|
}
|
|
17233
17649
|
const session = candidates.find((item) => {
|
|
17234
17650
|
if (typeof item === "string") return item === sessionId;
|
|
17235
|
-
const id =
|
|
17651
|
+
const id = readString6(item?.id) || readString6(item?.sessionId) || readString6(item?.session_id) || readString6(item?.runtimeSessionId) || readString6(item?.instanceId);
|
|
17236
17652
|
return id === sessionId;
|
|
17237
17653
|
});
|
|
17238
17654
|
if (!session) return { staleReason: "direct task session is not present in live session records" };
|
|
17239
17655
|
if (typeof session === "string") return {};
|
|
17240
|
-
const raw = `${
|
|
17656
|
+
const raw = `${readString6(session.status) || ""} ${readString6(session.lifecycle) || ""} ${readString6(session.state) || ""} ${readString6(session.activeChat?.status) || ""}`.toLowerCase();
|
|
17241
17657
|
if (raw.includes("approval")) return { status: "awaiting_approval" };
|
|
17242
17658
|
if (raw.includes("generating") || raw.includes("running") || raw.includes("busy")) return { status: "generating" };
|
|
17243
17659
|
if (raw.includes("failed") || raw.includes("stopped") || raw.includes("terminated") || raw.includes("exited")) return { status: "failed" };
|
|
@@ -17248,14 +17664,14 @@ function isDirectDispatch(entry) {
|
|
|
17248
17664
|
if (entry.kind !== "task_dispatched") return false;
|
|
17249
17665
|
const payload = entry.payload || {};
|
|
17250
17666
|
if (payload.source === "direct") return true;
|
|
17251
|
-
const via =
|
|
17667
|
+
const via = readString6(payload.via);
|
|
17252
17668
|
return Boolean(via && DIRECT_DISPATCH_VIA.has(via) && payload.source !== "queue");
|
|
17253
17669
|
}
|
|
17254
17670
|
function directDispatchTaskId(entry) {
|
|
17255
|
-
return
|
|
17671
|
+
return readString6(entry.payload?.taskId) || entry.id;
|
|
17256
17672
|
}
|
|
17257
17673
|
function terminalMatchesDispatch(terminal, dispatch, taskId) {
|
|
17258
|
-
const terminalTaskId =
|
|
17674
|
+
const terminalTaskId = readString6(terminal.payload?.taskId);
|
|
17259
17675
|
if (terminalTaskId && terminalTaskId === taskId) return true;
|
|
17260
17676
|
if (terminalTaskId && terminalTaskId !== taskId) return false;
|
|
17261
17677
|
if (dispatch.sessionId && terminal.sessionId === dispatch.sessionId) return true;
|
|
@@ -17378,7 +17794,7 @@ function buildMeshActiveWork(opts) {
|
|
|
17378
17794
|
const isNoTransition = !terminalStatus && !live.status;
|
|
17379
17795
|
const isIdleUnacknowledged = status === "idle";
|
|
17380
17796
|
const ledgerOnlyStaleReason = !terminalRow && (isIdleUnacknowledged || isNoTransition || dispatchedToIdleSession && isIdleUnacknowledged) ? "direct task dispatch has no provider acknowledgement, transcript append, or active runtime transition" : void 0;
|
|
17381
|
-
const message =
|
|
17797
|
+
const message = readString6(dispatch.payload?.message) || readString6(dispatch.payload?.summary) || "";
|
|
17382
17798
|
const { title, summary: summary2 } = summarizeMessage(message);
|
|
17383
17799
|
const isFreshUnacknowledged = Boolean(ledgerOnlyStaleReason && !live.staleReason);
|
|
17384
17800
|
const record = {
|
|
@@ -17387,11 +17803,11 @@ function buildMeshActiveWork(opts) {
|
|
|
17387
17803
|
status,
|
|
17388
17804
|
nodeId: dispatch.nodeId,
|
|
17389
17805
|
sessionId: dispatch.sessionId,
|
|
17390
|
-
providerType: dispatch.providerType ||
|
|
17391
|
-
taskTitle:
|
|
17392
|
-
taskSummary:
|
|
17806
|
+
providerType: dispatch.providerType || readString6(dispatch.payload?.providerType),
|
|
17807
|
+
taskTitle: readString6(dispatch.payload?.taskTitle) || title,
|
|
17808
|
+
taskSummary: readString6(dispatch.payload?.taskSummary) || summary2,
|
|
17393
17809
|
message,
|
|
17394
|
-
taskMode:
|
|
17810
|
+
taskMode: readString6(dispatch.payload?.taskMode),
|
|
17395
17811
|
createdAt: dispatch.timestamp,
|
|
17396
17812
|
updatedAt: terminal?.timestamp || dispatch.timestamp,
|
|
17397
17813
|
dispatchedAt: dispatch.timestamp,
|
|
@@ -17426,7 +17842,7 @@ function buildMeshActiveWork(opts) {
|
|
|
17426
17842
|
const isNoTransition = !terminalStatus && !live.status;
|
|
17427
17843
|
const isIdleUnacknowledged = status === "idle";
|
|
17428
17844
|
const ledgerOnlyStaleReason = !terminalRow && (isIdleUnacknowledged || isNoTransition || dispatchedToIdleSession && isIdleUnacknowledged) ? "direct task dispatch has no provider acknowledgement, transcript append, or active runtime transition" : void 0;
|
|
17429
|
-
const message =
|
|
17845
|
+
const message = readString6(dispatch.payload?.message) || readString6(dispatch.payload?.summary) || "";
|
|
17430
17846
|
const { title, summary: summary2 } = summarizeMessage(message);
|
|
17431
17847
|
const isFreshUnacknowledged = Boolean(ledgerOnlyStaleReason && !live.staleReason);
|
|
17432
17848
|
const record = {
|
|
@@ -17435,11 +17851,11 @@ function buildMeshActiveWork(opts) {
|
|
|
17435
17851
|
status,
|
|
17436
17852
|
nodeId: dispatch.nodeId,
|
|
17437
17853
|
sessionId: dispatch.sessionId,
|
|
17438
|
-
providerType: dispatch.providerType ||
|
|
17439
|
-
taskTitle:
|
|
17440
|
-
taskSummary:
|
|
17854
|
+
providerType: dispatch.providerType || readString6(dispatch.payload?.providerType),
|
|
17855
|
+
taskTitle: readString6(dispatch.payload?.taskTitle) || title,
|
|
17856
|
+
taskSummary: readString6(dispatch.payload?.taskSummary) || summary2,
|
|
17441
17857
|
message,
|
|
17442
|
-
taskMode:
|
|
17858
|
+
taskMode: readString6(dispatch.payload?.taskMode),
|
|
17443
17859
|
createdAt: dispatch.timestamp,
|
|
17444
17860
|
updatedAt: terminal?.timestamp || dispatch.timestamp,
|
|
17445
17861
|
dispatchedAt: dispatch.timestamp,
|
|
@@ -21783,7 +22199,7 @@ var ExtensionProviderInstance = class {
|
|
|
21783
22199
|
this.runtimeMessages = [];
|
|
21784
22200
|
}
|
|
21785
22201
|
updateSettings(newSettings) {
|
|
21786
|
-
this.settings = { ...newSettings };
|
|
22202
|
+
this.settings = { ...this.settings, ...newSettings };
|
|
21787
22203
|
this.monitor.updateConfig({
|
|
21788
22204
|
approvalAlert: this.settings.approvalAlert !== false,
|
|
21789
22205
|
longGeneratingAlert: this.settings.longGeneratingAlert !== false,
|
|
@@ -22450,7 +22866,7 @@ var IdeProviderInstance = class {
|
|
|
22450
22866
|
this.extensions.clear();
|
|
22451
22867
|
}
|
|
22452
22868
|
updateSettings(newSettings) {
|
|
22453
|
-
this.settings = { ...newSettings };
|
|
22869
|
+
this.settings = { ...this.settings, ...newSettings };
|
|
22454
22870
|
this.monitor.updateConfig({
|
|
22455
22871
|
approvalAlert: this.settings.approvalAlert !== false,
|
|
22456
22872
|
longGeneratingAlert: this.settings.longGeneratingAlert !== false,
|
|
@@ -23929,7 +24345,7 @@ function resolveLegacyProviderScript(fn, scriptName, params) {
|
|
|
23929
24345
|
import * as fs6 from "fs";
|
|
23930
24346
|
import * as os8 from "os";
|
|
23931
24347
|
import * as path13 from "path";
|
|
23932
|
-
import { randomUUID as
|
|
24348
|
+
import { randomUUID as randomUUID11 } from "crypto";
|
|
23933
24349
|
init_logger();
|
|
23934
24350
|
|
|
23935
24351
|
// src/logging/debug-trace.ts
|
|
@@ -25470,7 +25886,7 @@ function safeBundleIdSegment(value, fallback) {
|
|
|
25470
25886
|
function createChatDebugBundleId(targetSessionId) {
|
|
25471
25887
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:.]/g, "").replace("T", "T").replace("Z", "Z");
|
|
25472
25888
|
const sessionSegment = safeBundleIdSegment(targetSessionId, "unknown-session");
|
|
25473
|
-
return `chat-debug-${timestamp}-${sessionSegment}-${
|
|
25889
|
+
return `chat-debug-${timestamp}-${sessionSegment}-${randomUUID11().slice(0, 8)}`;
|
|
25474
25890
|
}
|
|
25475
25891
|
function buildChatDebugBundleSummary(bundle) {
|
|
25476
25892
|
const target = bundle.target && typeof bundle.target === "object" ? bundle.target : {};
|
|
@@ -31998,22 +32414,7 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
31998
32414
|
};
|
|
31999
32415
|
}
|
|
32000
32416
|
updateSettings(newSettings) {
|
|
32001
|
-
|
|
32002
|
-
for (const key of [
|
|
32003
|
-
"meshNodeFor",
|
|
32004
|
-
"meshNodeId",
|
|
32005
|
-
"meshActiveTaskId",
|
|
32006
|
-
"meshCoordinatorFor",
|
|
32007
|
-
"meshCoordinatorDaemonId",
|
|
32008
|
-
"meshCoordinatorNodeId",
|
|
32009
|
-
"spawnedSessionVisibility",
|
|
32010
|
-
"launchedByCoordinator"
|
|
32011
|
-
]) {
|
|
32012
|
-
if (this.settings[key] !== void 0 && newSettings[key] === void 0) {
|
|
32013
|
-
runtimeMeshSettings[key] = this.settings[key];
|
|
32014
|
-
}
|
|
32015
|
-
}
|
|
32016
|
-
this.settings = { ...newSettings, ...runtimeMeshSettings };
|
|
32417
|
+
this.settings = { ...this.settings, ...newSettings };
|
|
32017
32418
|
this.adapter.updateRuntimeSettings?.(this.settings);
|
|
32018
32419
|
this.monitor.updateConfig({
|
|
32019
32420
|
approvalAlert: this.settings.approvalAlert !== false,
|
|
@@ -39345,207 +39746,7 @@ function getAvailableIdeIds() {
|
|
|
39345
39746
|
init_config();
|
|
39346
39747
|
init_cli_detector();
|
|
39347
39748
|
init_git_status();
|
|
39348
|
-
|
|
39349
|
-
// ../mesh-shared/dist/index.mjs
|
|
39350
|
-
function readRecord5(value) {
|
|
39351
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
39352
|
-
}
|
|
39353
|
-
function readString6(...values) {
|
|
39354
|
-
for (const value of values) {
|
|
39355
|
-
if (typeof value !== "string") continue;
|
|
39356
|
-
const trimmed = value.trim();
|
|
39357
|
-
if (trimmed) return trimmed;
|
|
39358
|
-
}
|
|
39359
|
-
return void 0;
|
|
39360
|
-
}
|
|
39361
|
-
function readNumber(...values) {
|
|
39362
|
-
for (const value of values) {
|
|
39363
|
-
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
39364
|
-
}
|
|
39365
|
-
return void 0;
|
|
39366
|
-
}
|
|
39367
|
-
function readBoolean(...values) {
|
|
39368
|
-
for (const value of values) {
|
|
39369
|
-
if (typeof value === "boolean") return value;
|
|
39370
|
-
}
|
|
39371
|
-
return void 0;
|
|
39372
|
-
}
|
|
39373
|
-
function joinRepoPath(root, relativePath) {
|
|
39374
|
-
const normalizedRoot = typeof root === "string" ? root.trim().replace(/[\\/]+$/, "") : "";
|
|
39375
|
-
const normalizedPath = typeof relativePath === "string" ? relativePath.trim() : "";
|
|
39376
|
-
if (!normalizedPath) return void 0;
|
|
39377
|
-
if (/^(?:[A-Za-z]:[\\/]|\/)/.test(normalizedPath)) return normalizedPath;
|
|
39378
|
-
if (!normalizedRoot) return void 0;
|
|
39379
|
-
return `${normalizedRoot}/${normalizedPath.replace(/^[\\/]+/, "")}`;
|
|
39380
|
-
}
|
|
39381
|
-
function scoreGitUpstreamFreshness(status) {
|
|
39382
|
-
switch (status) {
|
|
39383
|
-
case "fresh":
|
|
39384
|
-
return 30;
|
|
39385
|
-
case "no_upstream":
|
|
39386
|
-
return 4;
|
|
39387
|
-
case "unchecked":
|
|
39388
|
-
case void 0:
|
|
39389
|
-
return 0;
|
|
39390
|
-
case "stale":
|
|
39391
|
-
return -10;
|
|
39392
|
-
case "unavailable":
|
|
39393
|
-
return -15;
|
|
39394
|
-
default:
|
|
39395
|
-
return 0;
|
|
39396
|
-
}
|
|
39397
|
-
}
|
|
39398
|
-
function readGitSubmodules(value, parentRepoRoot) {
|
|
39399
|
-
if (!Array.isArray(value)) return void 0;
|
|
39400
|
-
const submodules = value.map((entry) => {
|
|
39401
|
-
const submodule = readRecord5(entry);
|
|
39402
|
-
const path40 = readString6(submodule.path);
|
|
39403
|
-
const commit = readString6(submodule.commit);
|
|
39404
|
-
const repoPath = readString6(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot, path40);
|
|
39405
|
-
if (!path40 || !commit) return null;
|
|
39406
|
-
const result = {
|
|
39407
|
-
path: path40,
|
|
39408
|
-
commit,
|
|
39409
|
-
dirty: readBoolean(submodule.dirty) ?? false,
|
|
39410
|
-
outOfSync: readBoolean(submodule.outOfSync, submodule.out_of_sync) ?? false,
|
|
39411
|
-
lastCheckedAt: readNumber(submodule.lastCheckedAt, submodule.last_checked_at) ?? Date.now()
|
|
39412
|
-
};
|
|
39413
|
-
if (repoPath) result.repoPath = repoPath;
|
|
39414
|
-
const error = readString6(submodule.error);
|
|
39415
|
-
if (error) result.error = error;
|
|
39416
|
-
return result;
|
|
39417
|
-
}).filter((entry) => entry !== null);
|
|
39418
|
-
return submodules.length > 0 ? submodules : void 0;
|
|
39419
|
-
}
|
|
39420
|
-
function hasGitStatusEvidence(status) {
|
|
39421
|
-
return readBoolean(status.isGitRepo) !== void 0 || Boolean(readString6(status.branch, status.upstream, status.upstreamStatus, status.upstream_status, status.headCommit)) || Boolean(readString6(status.repoRoot, status.repo_root, status.workspace)) || readNumber(
|
|
39422
|
-
status.ahead,
|
|
39423
|
-
status.behind,
|
|
39424
|
-
status.staged,
|
|
39425
|
-
status.modified,
|
|
39426
|
-
status.untracked,
|
|
39427
|
-
status.deleted,
|
|
39428
|
-
status.renamed,
|
|
39429
|
-
status.lastCheckedAt,
|
|
39430
|
-
status.last_checked_at
|
|
39431
|
-
) !== void 0 || Array.isArray(status.submodules) && status.submodules.length > 0;
|
|
39432
|
-
}
|
|
39433
|
-
function normalizeGitStatus(status, node, options) {
|
|
39434
|
-
const explicitIsGitRepo = readBoolean(status.isGitRepo);
|
|
39435
|
-
if (!Object.keys(status).length || !hasGitStatusEvidence(status)) return void 0;
|
|
39436
|
-
const isGitRepo = explicitIsGitRepo ?? true;
|
|
39437
|
-
const conflictFiles = Array.isArray(status.conflictFiles) ? status.conflictFiles.filter((entry) => typeof entry === "string") : [];
|
|
39438
|
-
const conflictCount = readNumber(status.conflicts) ?? conflictFiles.length;
|
|
39439
|
-
const hasConflicts = readBoolean(status.hasConflicts) ?? conflictCount > 0;
|
|
39440
|
-
const repoRoot = readString6(status.repoRoot, status.repo_root, node.repoRoot, node.repo_root, status.workspace, node.workspace) || void 0;
|
|
39441
|
-
const submodules = readGitSubmodules(status.submodules, repoRoot);
|
|
39442
|
-
const upstreamStatus = readString6(status.upstreamStatus, status.upstream_status);
|
|
39443
|
-
const upstreamFetchedAt = readNumber(status.upstreamFetchedAt, status.upstream_fetched_at);
|
|
39444
|
-
const upstreamFetchError = readString6(status.upstreamFetchError, status.upstream_fetch_error);
|
|
39445
|
-
const error = readString6(status.error);
|
|
39446
|
-
const staged = readNumber(status.staged) ?? 0;
|
|
39447
|
-
const modified = readNumber(status.modified) ?? 0;
|
|
39448
|
-
const untracked = readNumber(status.untracked) ?? 0;
|
|
39449
|
-
const deleted = readNumber(status.deleted) ?? 0;
|
|
39450
|
-
const renamed = readNumber(status.renamed) ?? 0;
|
|
39451
|
-
return {
|
|
39452
|
-
workspace: readString6(status.workspace, node.workspace) || "",
|
|
39453
|
-
repoRoot: repoRoot ?? null,
|
|
39454
|
-
isGitRepo,
|
|
39455
|
-
branch: readString6(status.branch) ?? null,
|
|
39456
|
-
headCommit: readString6(status.headCommit) ?? null,
|
|
39457
|
-
headMessage: readString6(status.headMessage) ?? null,
|
|
39458
|
-
upstream: readString6(status.upstream) ?? null,
|
|
39459
|
-
upstreamStatus: upstreamStatus ?? "unchecked",
|
|
39460
|
-
...upstreamFetchedAt !== void 0 ? { upstreamFetchedAt } : {},
|
|
39461
|
-
...upstreamFetchError ? { upstreamFetchError } : {},
|
|
39462
|
-
ahead: readNumber(status.ahead) ?? 0,
|
|
39463
|
-
behind: readNumber(status.behind) ?? 0,
|
|
39464
|
-
staged,
|
|
39465
|
-
modified,
|
|
39466
|
-
untracked,
|
|
39467
|
-
deleted,
|
|
39468
|
-
renamed,
|
|
39469
|
-
dirty: readBoolean(status.dirty, status.isDirty, status.is_dirty) ?? (staged + modified + untracked + deleted + renamed > 0 || hasConflicts),
|
|
39470
|
-
hasConflicts,
|
|
39471
|
-
conflictFiles,
|
|
39472
|
-
stashCount: readNumber(status.stashCount, status.stash_count) ?? 0,
|
|
39473
|
-
lastCheckedAt: options?.lastCheckedAt ?? readNumber(status.lastCheckedAt, status.last_checked_at) ?? Date.now(),
|
|
39474
|
-
...submodules ? { submodules } : {},
|
|
39475
|
-
...error ? { error } : {}
|
|
39476
|
-
};
|
|
39477
|
-
}
|
|
39478
|
-
function scoreGitStatusCandidate(git) {
|
|
39479
|
-
if (!git) return Number.NEGATIVE_INFINITY;
|
|
39480
|
-
let score = 0;
|
|
39481
|
-
if (git.isGitRepo === true) score += 50;
|
|
39482
|
-
if (git.isGitRepo === false) score -= 10;
|
|
39483
|
-
if (git.branch) score += 20;
|
|
39484
|
-
if (git.headCommit) score += 20;
|
|
39485
|
-
if (git.upstream) score += 10;
|
|
39486
|
-
score += scoreGitUpstreamFreshness(git.upstreamStatus);
|
|
39487
|
-
if (typeof git.ahead === "number") score += 2;
|
|
39488
|
-
if (typeof git.behind === "number") score += 2;
|
|
39489
|
-
if (Array.isArray(git.submodules) && git.submodules.length > 0) score += 4 + git.submodules.length;
|
|
39490
|
-
if (git.error) score -= 20;
|
|
39491
|
-
return score;
|
|
39492
|
-
}
|
|
39493
|
-
function pickBestTransitGitStatus(node, options) {
|
|
39494
|
-
const rawGit = readRecord5(node.lastGit ?? node.last_git);
|
|
39495
|
-
const gitResult = readRecord5(rawGit.result);
|
|
39496
|
-
const directStatus = readRecord5(rawGit.status);
|
|
39497
|
-
const nestedStatus = readRecord5(gitResult.status);
|
|
39498
|
-
const rawProbe = readRecord5(node.lastProbe ?? node.last_probe);
|
|
39499
|
-
const probeGit = readRecord5(rawProbe.git);
|
|
39500
|
-
const probeGitResult = readRecord5(probeGit.result);
|
|
39501
|
-
const probeDirectStatus = readRecord5(probeGit.status);
|
|
39502
|
-
const probeNestedStatus = readRecord5(probeGitResult.status);
|
|
39503
|
-
const lastCheckedAt = options?.lastCheckedAt;
|
|
39504
|
-
let best = null;
|
|
39505
|
-
for (const status of [directStatus, nestedStatus, probeDirectStatus, probeNestedStatus]) {
|
|
39506
|
-
const normalized = normalizeGitStatus(status, node, { lastCheckedAt: lastCheckedAt ?? Date.now() });
|
|
39507
|
-
if (!normalized) continue;
|
|
39508
|
-
const score = scoreGitStatusCandidate(normalized);
|
|
39509
|
-
if (!best || score > best.score) best = { git: normalized, score };
|
|
39510
|
-
}
|
|
39511
|
-
return best?.git;
|
|
39512
|
-
}
|
|
39513
|
-
function summarizeGitShape(status) {
|
|
39514
|
-
const record = readRecord5(status);
|
|
39515
|
-
if (!Object.keys(record).length) return null;
|
|
39516
|
-
const submodules = Array.isArray(record.submodules) ? record.submodules.map((entry) => {
|
|
39517
|
-
const sub = readRecord5(entry);
|
|
39518
|
-
return {
|
|
39519
|
-
path: readString6(sub.path) ?? null,
|
|
39520
|
-
commit: readString6(sub.commit)?.slice(0, 12) ?? null,
|
|
39521
|
-
dirty: readBoolean(sub.dirty) ?? false,
|
|
39522
|
-
outOfSync: readBoolean(sub.outOfSync, sub.out_of_sync) ?? false
|
|
39523
|
-
};
|
|
39524
|
-
}) : [];
|
|
39525
|
-
return {
|
|
39526
|
-
isGitRepo: readBoolean(record.isGitRepo),
|
|
39527
|
-
workspace: readString6(record.workspace) ?? null,
|
|
39528
|
-
repoRoot: readString6(record.repoRoot, record.repo_root) ?? null,
|
|
39529
|
-
branch: readString6(record.branch) ?? null,
|
|
39530
|
-
upstream: readString6(record.upstream) ?? null,
|
|
39531
|
-
upstreamStatus: readString6(record.upstreamStatus, record.upstream_status) ?? null,
|
|
39532
|
-
headCommit: readString6(record.headCommit, record.head_commit)?.slice(0, 12) ?? null,
|
|
39533
|
-
ahead: readNumber(record.ahead) ?? null,
|
|
39534
|
-
behind: readNumber(record.behind) ?? null,
|
|
39535
|
-
dirtyCounts: {
|
|
39536
|
-
staged: readNumber(record.staged) ?? 0,
|
|
39537
|
-
modified: readNumber(record.modified) ?? 0,
|
|
39538
|
-
untracked: readNumber(record.untracked) ?? 0,
|
|
39539
|
-
deleted: readNumber(record.deleted) ?? 0,
|
|
39540
|
-
renamed: readNumber(record.renamed) ?? 0
|
|
39541
|
-
},
|
|
39542
|
-
lastCheckedAt: readNumber(record.lastCheckedAt, record.last_checked_at) ?? null,
|
|
39543
|
-
submoduleCount: submodules.length,
|
|
39544
|
-
submodules
|
|
39545
|
-
};
|
|
39546
|
-
}
|
|
39547
|
-
|
|
39548
|
-
// src/commands/router.ts
|
|
39749
|
+
init_dist();
|
|
39549
39750
|
init_logger();
|
|
39550
39751
|
|
|
39551
39752
|
// src/logging/command-log.ts
|
|
@@ -40625,7 +40826,10 @@ function summarizeRepoMeshStatusDebug(status) {
|
|
|
40625
40826
|
branchConvergenceSummary: status?.branchConvergenceSummary ?? status?.branch_convergence_summary ?? null,
|
|
40626
40827
|
nodeCount: nodes.length,
|
|
40627
40828
|
nodes: nodes.map((node) => ({
|
|
40628
|
-
nodeId
|
|
40829
|
+
// Status emits the id under `nodeId` (3-way input absorbed). The
|
|
40830
|
+
// inline cache keeps `id` and `nodeId` equal, so this serialized form
|
|
40831
|
+
// round-trips back through the cache without flipping shape.
|
|
40832
|
+
nodeId: normalizeMeshNodeId(node) ?? null,
|
|
40629
40833
|
daemonId: readStringValue(node?.daemonId, node?.daemon_id) ?? null,
|
|
40630
40834
|
workspace: readStringValue(node?.workspace, node?.git?.workspace) ?? null,
|
|
40631
40835
|
health: readStringValue(node?.health) ?? null,
|
|
@@ -40870,7 +41074,23 @@ function inlineMeshCarriesTransientNodeTruth(inlineMesh) {
|
|
|
40870
41074
|
return inlineMesh.nodes.some((node) => hasInlineMeshTransientNodeState(node));
|
|
40871
41075
|
}
|
|
40872
41076
|
function readInlineMeshNodeId(node) {
|
|
40873
|
-
return
|
|
41077
|
+
return normalizeMeshNodeId(node) ?? "";
|
|
41078
|
+
}
|
|
41079
|
+
function foldMeshNodeIdentityToCanonical(node) {
|
|
41080
|
+
if (!node || typeof node !== "object" || Array.isArray(node)) return node;
|
|
41081
|
+
const canonical = normalizeMeshNodeId(node);
|
|
41082
|
+
if (canonical === void 0) return node;
|
|
41083
|
+
if (node.id === canonical && node.nodeId === canonical && node.node_id === void 0) return node;
|
|
41084
|
+
node.id = canonical;
|
|
41085
|
+
node.nodeId = canonical;
|
|
41086
|
+
if ("node_id" in node) delete node.node_id;
|
|
41087
|
+
return node;
|
|
41088
|
+
}
|
|
41089
|
+
function normalizeInlineMeshNodeIdentity(inlineMesh) {
|
|
41090
|
+
if (!inlineMesh || typeof inlineMesh !== "object" || Array.isArray(inlineMesh)) return inlineMesh;
|
|
41091
|
+
if (!Array.isArray(inlineMesh.nodes) || inlineMesh.nodes.length === 0) return inlineMesh;
|
|
41092
|
+
for (const node of inlineMesh.nodes) foldMeshNodeIdentityToCanonical(node);
|
|
41093
|
+
return inlineMesh;
|
|
40874
41094
|
}
|
|
40875
41095
|
function sanitizeInlineMesh(inlineMesh) {
|
|
40876
41096
|
if (!inlineMesh || typeof inlineMesh !== "object" || Array.isArray(inlineMesh)) return inlineMesh;
|
|
@@ -40972,7 +41192,7 @@ function deriveMeshNodeHealthFromGit(git) {
|
|
|
40972
41192
|
return "online";
|
|
40973
41193
|
}
|
|
40974
41194
|
function readMeshNodeLabel(status, node) {
|
|
40975
|
-
return readStringValue(status.nodeId, node
|
|
41195
|
+
return readStringValue(status.nodeId, normalizeMeshNodeId(node)) ?? "unknown";
|
|
40976
41196
|
}
|
|
40977
41197
|
function buildInlineMeshBranchConvergence(args) {
|
|
40978
41198
|
const git = readObjectRecord(args.status.git);
|
|
@@ -41251,7 +41471,7 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
41251
41471
|
let peerConfirmedCount = 0;
|
|
41252
41472
|
const unavailableNodeIds = [];
|
|
41253
41473
|
for (const [nodeIndex, node] of nodes.entries()) {
|
|
41254
|
-
const nodeId =
|
|
41474
|
+
const nodeId = normalizeMeshNodeId(node) || `node_${nodeIndex}`;
|
|
41255
41475
|
const workspace = readStringValue(node?.workspace);
|
|
41256
41476
|
const daemonId = readStringValue(node?.daemonId);
|
|
41257
41477
|
const isSelfNode = Boolean(
|
|
@@ -41382,7 +41602,7 @@ function buildHistoricalMeshSessions(args) {
|
|
|
41382
41602
|
const liveWorkspaces = /* @__PURE__ */ new Set();
|
|
41383
41603
|
const missingLocalWorktreeNodeIds = /* @__PURE__ */ new Set();
|
|
41384
41604
|
for (const node of args.nodes || []) {
|
|
41385
|
-
const nodeId =
|
|
41605
|
+
const nodeId = normalizeMeshNodeId(node);
|
|
41386
41606
|
const workspace = readStringValue(node?.workspace);
|
|
41387
41607
|
if (nodeId) liveNodeIds.add(nodeId);
|
|
41388
41608
|
if (workspace) liveWorkspaces.add(workspace);
|
|
@@ -41507,9 +41727,13 @@ function resolveRefineryAutoPublishSubmoduleMainCommits(mesh, workspace) {
|
|
|
41507
41727
|
}
|
|
41508
41728
|
return { enabled: false };
|
|
41509
41729
|
}
|
|
41510
|
-
async function computeGitPatchId(cwd, fromRef, toRef) {
|
|
41730
|
+
async function computeGitPatchId(cwd, fromRef, toRef, excludePaths = []) {
|
|
41511
41731
|
const { execFileSync: execFileSync6 } = await import("child_process");
|
|
41512
|
-
const
|
|
41732
|
+
const diffArgs = ["diff", "--patch", "--full-index", fromRef, toRef];
|
|
41733
|
+
if (excludePaths.length > 0) {
|
|
41734
|
+
diffArgs.push("--", ".", ...excludePaths.map((path40) => `:(exclude)${path40}`));
|
|
41735
|
+
}
|
|
41736
|
+
const diff = execFileSync6("git", diffArgs, {
|
|
41513
41737
|
cwd,
|
|
41514
41738
|
encoding: "utf8",
|
|
41515
41739
|
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
@@ -41578,8 +41802,9 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
41578
41802
|
gitlinkTrivialFastForward
|
|
41579
41803
|
};
|
|
41580
41804
|
}
|
|
41581
|
-
const
|
|
41582
|
-
const
|
|
41805
|
+
const ffGitlinkExcludePaths = collectFastForwardGitlinkPaths(repoRoot, baseHead, branchHead);
|
|
41806
|
+
const expectedPatchId = await computeGitPatchId(repoRoot, mergeBase, branchHead, ffGitlinkExcludePaths);
|
|
41807
|
+
const actualPatchId = await computeGitPatchId(repoRoot, baseHead, mergedTree, ffGitlinkExcludePaths);
|
|
41583
41808
|
const equivalent = expectedPatchId === actualPatchId;
|
|
41584
41809
|
return {
|
|
41585
41810
|
status: equivalent ? "passed" : "failed",
|
|
@@ -41775,6 +42000,14 @@ function readChangedPathKinds(repoRoot, fromRef, toRef) {
|
|
|
41775
42000
|
return [];
|
|
41776
42001
|
}
|
|
41777
42002
|
}
|
|
42003
|
+
function collectFastForwardGitlinkPaths(repoRoot, baseHead, branchHead) {
|
|
42004
|
+
return readChangedGitlinkPaths(repoRoot, baseHead, branchHead).filter((path40) => {
|
|
42005
|
+
const baseCommit = readTreeObject(repoRoot, baseHead, path40);
|
|
42006
|
+
const branchCommit = readTreeObject(repoRoot, branchHead, path40);
|
|
42007
|
+
if (!baseCommit || !branchCommit) return false;
|
|
42008
|
+
return isSubmoduleFastForward(pathResolve2(repoRoot, path40), baseCommit, branchCommit);
|
|
42009
|
+
});
|
|
42010
|
+
}
|
|
41778
42011
|
function evaluateGitlinkTrivialFastForward(repoRoot, baseHead, branchHead) {
|
|
41779
42012
|
const changedGitlinks = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((path40) => {
|
|
41780
42013
|
const baseCommit = readTreeObject(repoRoot, baseHead, path40);
|
|
@@ -41824,20 +42057,95 @@ function evaluateGitlinkTrivialFastForward(repoRoot, baseHead, branchHead) {
|
|
|
41824
42057
|
}
|
|
41825
42058
|
return { trivial: true, gitlinks: changedGitlinks };
|
|
41826
42059
|
}
|
|
42060
|
+
function buildTreeWithGitlinksEqualized(repoRoot, commitish, paths, placeholderCommit) {
|
|
42061
|
+
try {
|
|
42062
|
+
const tree = execFileSync5("git", ["rev-parse", `${commitish}^{tree}`], {
|
|
42063
|
+
cwd: repoRoot,
|
|
42064
|
+
encoding: "utf8",
|
|
42065
|
+
maxBuffer: 1024 * 1024
|
|
42066
|
+
}).trim();
|
|
42067
|
+
if (!tree) return void 0;
|
|
42068
|
+
const updates = paths.map((path40) => `160000 commit ${placeholderCommit} ${path40}`).join("\n");
|
|
42069
|
+
if (!updates) return tree;
|
|
42070
|
+
const tmpIndex = pathJoin(resolveGitDir(repoRoot), `adhdev-refine-eq-${commitish.slice(0, 12)}.index`);
|
|
42071
|
+
const env = { ...process.env, GIT_INDEX_FILE: tmpIndex };
|
|
42072
|
+
try {
|
|
42073
|
+
execFileSync5("git", ["read-tree", tree], { cwd: repoRoot, env, stdio: "ignore" });
|
|
42074
|
+
execFileSync5("git", ["update-index", "--index-info"], {
|
|
42075
|
+
cwd: repoRoot,
|
|
42076
|
+
env,
|
|
42077
|
+
input: `${updates}
|
|
42078
|
+
`,
|
|
42079
|
+
encoding: "utf8",
|
|
42080
|
+
stdio: ["pipe", "ignore", "ignore"]
|
|
42081
|
+
});
|
|
42082
|
+
const newTree = execFileSync5("git", ["write-tree"], { cwd: repoRoot, env, encoding: "utf8" }).trim();
|
|
42083
|
+
return newTree || void 0;
|
|
42084
|
+
} finally {
|
|
42085
|
+
try {
|
|
42086
|
+
fs24.rmSync(tmpIndex, { force: true });
|
|
42087
|
+
} catch {
|
|
42088
|
+
}
|
|
42089
|
+
}
|
|
42090
|
+
} catch {
|
|
42091
|
+
return void 0;
|
|
42092
|
+
}
|
|
42093
|
+
}
|
|
41827
42094
|
function synthesizeTrivialFastForwardMergeTree(repoRoot, baseHead, branchHead, gitlinks) {
|
|
41828
42095
|
try {
|
|
41829
|
-
const
|
|
42096
|
+
const branchGitlinks = gitlinks.filter((entry) => entry.branchCommit);
|
|
42097
|
+
const gitlinkPaths = branchGitlinks.map((entry) => entry.path);
|
|
42098
|
+
const mergeBase = execFileSync5("git", ["merge-base", baseHead, branchHead], {
|
|
42099
|
+
cwd: repoRoot,
|
|
42100
|
+
encoding: "utf8",
|
|
42101
|
+
maxBuffer: 1024 * 1024
|
|
42102
|
+
}).trim();
|
|
42103
|
+
let mergedContentTree;
|
|
42104
|
+
if (mergeBase && gitlinkPaths.length > 0) {
|
|
42105
|
+
const placeholder = readTreeObject(repoRoot, mergeBase, gitlinkPaths[0]) || branchGitlinks[0].branchCommit;
|
|
42106
|
+
const baseEqTree = buildTreeWithGitlinksEqualized(repoRoot, mergeBase, gitlinkPaths, placeholder);
|
|
42107
|
+
const oursEqTree = buildTreeWithGitlinksEqualized(repoRoot, baseHead, gitlinkPaths, placeholder);
|
|
42108
|
+
const theirsEqTree = buildTreeWithGitlinksEqualized(repoRoot, branchHead, gitlinkPaths, placeholder);
|
|
42109
|
+
if (baseEqTree && oursEqTree && theirsEqTree) {
|
|
42110
|
+
try {
|
|
42111
|
+
const baseEqCommit = execFileSync5("git", ["commit-tree", baseEqTree, "-m", "refine-ff-base"], {
|
|
42112
|
+
cwd: repoRoot,
|
|
42113
|
+
encoding: "utf8",
|
|
42114
|
+
maxBuffer: 1024 * 1024
|
|
42115
|
+
}).trim();
|
|
42116
|
+
const oursEqCommit = execFileSync5("git", ["commit-tree", oursEqTree, "-p", baseEqCommit, "-m", "refine-ff-ours"], {
|
|
42117
|
+
cwd: repoRoot,
|
|
42118
|
+
encoding: "utf8",
|
|
42119
|
+
maxBuffer: 1024 * 1024
|
|
42120
|
+
}).trim();
|
|
42121
|
+
const theirsEqCommit = execFileSync5("git", ["commit-tree", theirsEqTree, "-p", baseEqCommit, "-m", "refine-ff-theirs"], {
|
|
42122
|
+
cwd: repoRoot,
|
|
42123
|
+
encoding: "utf8",
|
|
42124
|
+
maxBuffer: 1024 * 1024
|
|
42125
|
+
}).trim();
|
|
42126
|
+
const mergeOut = execFileSync5("git", ["merge-tree", "--write-tree", oursEqCommit, theirsEqCommit], {
|
|
42127
|
+
cwd: repoRoot,
|
|
42128
|
+
encoding: "utf8",
|
|
42129
|
+
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
42130
|
+
}).trim();
|
|
42131
|
+
mergedContentTree = mergeOut.split(/\s+/)[0] || void 0;
|
|
42132
|
+
} catch {
|
|
42133
|
+
mergedContentTree = void 0;
|
|
42134
|
+
}
|
|
42135
|
+
}
|
|
42136
|
+
}
|
|
42137
|
+
const contentTree = mergedContentTree || execFileSync5("git", ["rev-parse", `${baseHead}^{tree}`], {
|
|
41830
42138
|
cwd: repoRoot,
|
|
41831
42139
|
encoding: "utf8",
|
|
41832
42140
|
maxBuffer: 1024 * 1024
|
|
41833
42141
|
}).trim();
|
|
41834
|
-
if (!
|
|
41835
|
-
const updates =
|
|
41836
|
-
if (!updates) return
|
|
42142
|
+
if (!contentTree) return void 0;
|
|
42143
|
+
const updates = branchGitlinks.map((entry) => `160000 commit ${entry.branchCommit} ${entry.path}`).join("\n");
|
|
42144
|
+
if (!updates) return contentTree;
|
|
41837
42145
|
const tmpIndex = pathJoin(resolveGitDir(repoRoot), `adhdev-refine-ff-${baseHead.slice(0, 12)}-${branchHead.slice(0, 12)}.index`);
|
|
41838
42146
|
const env = { ...process.env, GIT_INDEX_FILE: tmpIndex };
|
|
41839
42147
|
try {
|
|
41840
|
-
execFileSync5("git", ["read-tree",
|
|
42148
|
+
execFileSync5("git", ["read-tree", contentTree], { cwd: repoRoot, env, stdio: "ignore" });
|
|
41841
42149
|
execFileSync5("git", ["update-index", "--index-info"], {
|
|
41842
42150
|
cwd: repoRoot,
|
|
41843
42151
|
env,
|
|
@@ -42497,7 +42805,7 @@ function normalizeStandaloneHostCommandUrl(hostAddress) {
|
|
|
42497
42805
|
function buildMemberJoinNode(mesh, args, fallbackDaemonId) {
|
|
42498
42806
|
const requestedNodeId = typeof args?.memberNodeId === "string" ? args.memberNodeId.trim() : "";
|
|
42499
42807
|
const explicit = args?.memberNode && typeof args.memberNode === "object" && !Array.isArray(args.memberNode) ? args.memberNode : null;
|
|
42500
|
-
const configured = Array.isArray(mesh?.nodes) ? requestedNodeId ? mesh.nodes.find((node) => node
|
|
42808
|
+
const configured = Array.isArray(mesh?.nodes) ? requestedNodeId ? mesh.nodes.find((node) => meshNodeIdMatches(node, requestedNodeId)) : mesh.nodes[0] : null;
|
|
42501
42809
|
const source = explicit || configured;
|
|
42502
42810
|
const workspace = typeof source?.workspace === "string" && source.workspace.trim() ? source.workspace.trim() : typeof args?.workspace === "string" && args.workspace.trim() ? args.workspace.trim() : process.cwd();
|
|
42503
42811
|
if (!workspace) return null;
|
|
@@ -42553,7 +42861,7 @@ var DaemonCommandRouter = class {
|
|
|
42553
42861
|
if (nodeId) unavailableNodeIds.add(nodeId);
|
|
42554
42862
|
}
|
|
42555
42863
|
const nodes = snapshot.nodes.map((statusNode) => {
|
|
42556
|
-
const nodeId =
|
|
42864
|
+
const nodeId = normalizeMeshNodeId(statusNode);
|
|
42557
42865
|
const inlineNode = nodeId ? inlineNodesById.get(nodeId) : void 0;
|
|
42558
42866
|
if (!inlineNode) return statusNode;
|
|
42559
42867
|
const liveGit = buildInlineMeshTransitGitStatus(inlineNode);
|
|
@@ -42666,7 +42974,7 @@ var DaemonCommandRouter = class {
|
|
|
42666
42974
|
}
|
|
42667
42975
|
warmInlineMeshCache(meshId, inlineMesh) {
|
|
42668
42976
|
if (!inlineMesh || typeof inlineMesh !== "object") return void 0;
|
|
42669
|
-
const sanitizedInlineMesh = sanitizeInlineMesh(inlineMesh);
|
|
42977
|
+
const sanitizedInlineMesh = sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(inlineMesh));
|
|
42670
42978
|
const cached2 = this.inlineMeshCache.get(meshId);
|
|
42671
42979
|
if (cached2) {
|
|
42672
42980
|
const merged = reconcileInlineMeshCache(cached2, sanitizedInlineMesh);
|
|
@@ -42683,7 +42991,7 @@ var DaemonCommandRouter = class {
|
|
|
42683
42991
|
if (cached3) {
|
|
42684
42992
|
if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
|
|
42685
42993
|
const merged = reconcileInlineMeshCache(cached3, inlineMesh);
|
|
42686
|
-
this.inlineMeshCache.set(meshId, sanitizeInlineMesh(merged));
|
|
42994
|
+
this.inlineMeshCache.set(meshId, sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(merged)));
|
|
42687
42995
|
return { mesh: merged, inline: true, source: "inline_cache" };
|
|
42688
42996
|
}
|
|
42689
42997
|
return { mesh: cached3, inline: true, source: "inline_cache" };
|
|
@@ -42719,17 +43027,19 @@ var DaemonCommandRouter = class {
|
|
|
42719
43027
|
return null;
|
|
42720
43028
|
}
|
|
42721
43029
|
updateInlineMeshNode(meshId, mesh, node) {
|
|
42722
|
-
|
|
42723
|
-
|
|
43030
|
+
const incomingId = normalizeMeshNodeId(node);
|
|
43031
|
+
if (!mesh || !Array.isArray(mesh.nodes) || !incomingId) return;
|
|
43032
|
+
const idx = mesh.nodes.findIndex((entry) => meshNodeIdMatches(entry, incomingId));
|
|
42724
43033
|
if (idx >= 0) mesh.nodes[idx] = node;
|
|
42725
43034
|
else mesh.nodes.push(node);
|
|
42726
43035
|
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
43036
|
+
for (const entry of mesh.nodes) foldMeshNodeIdentityToCanonical(entry);
|
|
42727
43037
|
this.inlineMeshCache.set(meshId, mesh);
|
|
42728
43038
|
this.invalidateAggregateMeshStatus(meshId);
|
|
42729
43039
|
}
|
|
42730
43040
|
removeInlineMeshNode(meshId, mesh, nodeId) {
|
|
42731
43041
|
if (!mesh || !Array.isArray(mesh.nodes)) return false;
|
|
42732
|
-
const idx = mesh.nodes.findIndex((entry) => entry
|
|
43042
|
+
const idx = mesh.nodes.findIndex((entry) => meshNodeIdMatches(entry, nodeId));
|
|
42733
43043
|
if (idx === -1) return false;
|
|
42734
43044
|
mesh.nodes.splice(idx, 1);
|
|
42735
43045
|
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -42760,7 +43070,7 @@ var DaemonCommandRouter = class {
|
|
|
42760
43070
|
};
|
|
42761
43071
|
}
|
|
42762
43072
|
const worktreeExists = fs24.existsSync(workspace);
|
|
42763
|
-
const sourceNode = args.node?.clonedFromNodeId ? args.mesh?.nodes?.find((n) => n
|
|
43073
|
+
const sourceNode = args.node?.clonedFromNodeId ? args.mesh?.nodes?.find((n) => meshNodeIdMatches(n, args.node.clonedFromNodeId)) : args.mesh?.nodes?.find((n) => !n.isLocalWorktree);
|
|
42764
43074
|
const repoRoot = typeof sourceNode?.repoRoot === "string" && sourceNode.repoRoot.trim() ? sourceNode.repoRoot.trim() : typeof sourceNode?.workspace === "string" && sourceNode.workspace.trim() ? sourceNode.workspace.trim() : "";
|
|
42765
43075
|
if (!worktreeExists) {
|
|
42766
43076
|
return { success: true, skipped: true, removedPath: workspace, repoRoot: repoRoot || void 0, reason: "worktree_path_missing" };
|
|
@@ -43403,12 +43713,12 @@ var DaemonCommandRouter = class {
|
|
|
43403
43713
|
try {
|
|
43404
43714
|
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
43405
43715
|
const mesh = meshRecord?.mesh;
|
|
43406
|
-
const node = mesh?.nodes?.find((n) => n
|
|
43716
|
+
const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
|
|
43407
43717
|
if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh`, refineStages };
|
|
43408
43718
|
if (!node.isLocalWorktree || !node.workspace) {
|
|
43409
43719
|
return { success: false, error: `Refinery requires a local worktree node`, refineStages };
|
|
43410
43720
|
}
|
|
43411
|
-
const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => n
|
|
43721
|
+
const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => meshNodeIdMatches(n, node.clonedFromNodeId)) : mesh?.nodes.find((n) => !n.isLocalWorktree);
|
|
43412
43722
|
const repoRoot = sourceNode?.repoRoot || sourceNode?.workspace;
|
|
43413
43723
|
if (!repoRoot) return { success: false, error: "Source node repoRoot not found", refineStages };
|
|
43414
43724
|
const { execFile: execFile5 } = await import("child_process");
|
|
@@ -44043,7 +44353,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
44043
44353
|
const missing = [];
|
|
44044
44354
|
const nonWorktree = [];
|
|
44045
44355
|
for (const nodeId of requestedNodeIds) {
|
|
44046
|
-
const node = allNodes.find((n) => n
|
|
44356
|
+
const node = allNodes.find((n) => meshNodeIdMatches(n, nodeId));
|
|
44047
44357
|
if (!node) {
|
|
44048
44358
|
missing.push(nodeId);
|
|
44049
44359
|
continue;
|
|
@@ -44072,7 +44382,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
44072
44382
|
const { promisify: promisify8 } = await import("util");
|
|
44073
44383
|
const execFileAsync4 = promisify8(execFile5);
|
|
44074
44384
|
const resolveRepoRootFor = (node) => {
|
|
44075
|
-
const sourceNode = node.clonedFromNodeId ? allNodes.find((n) => n
|
|
44385
|
+
const sourceNode = node.clonedFromNodeId ? allNodes.find((n) => meshNodeIdMatches(n, node.clonedFromNodeId)) : allNodes.find((n) => !n.isLocalWorktree);
|
|
44076
44386
|
return sourceNode?.repoRoot || sourceNode?.workspace;
|
|
44077
44387
|
};
|
|
44078
44388
|
const repoRootBaseRef = /* @__PURE__ */ new Map();
|
|
@@ -44161,7 +44471,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
44161
44471
|
}));
|
|
44162
44472
|
}
|
|
44163
44473
|
const ordering = orderMeshRefineBatchNodes(changeAreas);
|
|
44164
|
-
const orderedNodes = ordering.order.map((nodeId) => targetNodes.find((n) => n
|
|
44474
|
+
const orderedNodes = ordering.order.map((nodeId) => targetNodes.find((n) => meshNodeIdMatches(n, nodeId))).filter((n) => !!n);
|
|
44165
44475
|
const dryRun = args?.dryRun !== false && args?.execute !== true;
|
|
44166
44476
|
if (dryRun) {
|
|
44167
44477
|
return {
|
|
@@ -44420,7 +44730,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
44420
44730
|
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
44421
44731
|
const mesh = meshRecord?.mesh;
|
|
44422
44732
|
const allNodes = Array.isArray(mesh?.nodes) ? mesh.nodes : [];
|
|
44423
|
-
const orderedNodes = nodeIds.map((id) => allNodes.find((n) => n
|
|
44733
|
+
const orderedNodes = nodeIds.map((id) => allNodes.find((n) => meshNodeIdMatches(n, id))).filter((n) => !!n);
|
|
44424
44734
|
if (orderedNodes.length === 0) {
|
|
44425
44735
|
return { success: false, error: "Batch nodes no longer resolvable in mesh", batch: true };
|
|
44426
44736
|
}
|
|
@@ -44526,7 +44836,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
44526
44836
|
const terminal = this.terminalRefineJobs.get(key);
|
|
44527
44837
|
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
44528
44838
|
const mesh = meshRecord?.mesh;
|
|
44529
|
-
const node = mesh?.nodes?.find((n) => n
|
|
44839
|
+
const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
|
|
44530
44840
|
if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
|
|
44531
44841
|
if (!node.isLocalWorktree || !node.workspace) return { success: false, error: `Refinery requires a local worktree node` };
|
|
44532
44842
|
const coordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
|
|
@@ -44573,7 +44883,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
44573
44883
|
try {
|
|
44574
44884
|
const { getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
44575
44885
|
const meshObj = getMesh2(meshId) ?? this.getCachedInlineMesh(meshId);
|
|
44576
|
-
const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => n
|
|
44886
|
+
const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => meshNodeIdMatches(n, meshNodeId)) : void 0;
|
|
44577
44887
|
const bootstrapStatus = readStringValue(nodeObj?.worktreeBootstrap?.status);
|
|
44578
44888
|
if (bootstrapStatus === "running") {
|
|
44579
44889
|
return { success: true, ...launchResult, bootstrapPending: true };
|
|
@@ -44618,7 +44928,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
44618
44928
|
try {
|
|
44619
44929
|
const { getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
44620
44930
|
const meshObj = getMesh2(dispatchMeshId) ?? this.getCachedInlineMesh(dispatchMeshId);
|
|
44621
|
-
const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => n
|
|
44931
|
+
const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => meshNodeIdMatches(n, dispatchNodeId)) : void 0;
|
|
44622
44932
|
const bootstrapStatus = readStringValue(nodeObj?.worktreeBootstrap?.status);
|
|
44623
44933
|
if (bootstrapStatus === "running") {
|
|
44624
44934
|
return {
|
|
@@ -45883,7 +46193,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
45883
46193
|
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
45884
46194
|
const mesh = meshRecord?.mesh;
|
|
45885
46195
|
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
45886
|
-
const node = mesh?.nodes?.find((n) => n
|
|
46196
|
+
const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
|
|
45887
46197
|
if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
|
|
45888
46198
|
const mode = this.normalizeMeshSessionCleanupMode(args?.mode ?? mesh?.policy?.sessionCleanupOnNodeRemove);
|
|
45889
46199
|
const sessionIds = Array.isArray(args?.sessionIds) ? args.sessionIds.map((id) => typeof id === "string" ? id.trim() : "").filter(Boolean) : void 0;
|
|
@@ -45938,7 +46248,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
45938
46248
|
if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
|
|
45939
46249
|
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
45940
46250
|
const mesh = meshRecord?.mesh;
|
|
45941
|
-
const node = mesh?.nodes?.find((n) => n
|
|
46251
|
+
const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
|
|
45942
46252
|
if (!node?.workspace) return { success: false, error: `Node '${nodeId}' workspace not found` };
|
|
45943
46253
|
return {
|
|
45944
46254
|
success: true,
|
|
@@ -45960,7 +46270,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
45960
46270
|
if (meshId && nodeId) {
|
|
45961
46271
|
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
45962
46272
|
const mesh = meshRecord?.mesh;
|
|
45963
|
-
const node = mesh?.nodes?.find((n) => n
|
|
46273
|
+
const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
|
|
45964
46274
|
if (!workspace) {
|
|
45965
46275
|
workspace = typeof node?.workspace === "string" ? node.workspace.trim() : "";
|
|
45966
46276
|
}
|
|
@@ -46003,7 +46313,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
46003
46313
|
if (isDryRun) {
|
|
46004
46314
|
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
46005
46315
|
const mesh = meshRecord?.mesh;
|
|
46006
|
-
const node = mesh?.nodes?.find((n) => n
|
|
46316
|
+
const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
|
|
46007
46317
|
if (!node?.workspace) return { success: false, error: `Node '${nodeId}' workspace not found` };
|
|
46008
46318
|
return {
|
|
46009
46319
|
success: true,
|
|
@@ -46033,7 +46343,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
46033
46343
|
try {
|
|
46034
46344
|
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
46035
46345
|
const mesh = meshRecord?.mesh;
|
|
46036
|
-
const node = mesh?.nodes?.find((n) => n
|
|
46346
|
+
const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
|
|
46037
46347
|
if (node && !args?._meshDirectDispatch && node.isLocalWorktree !== true && args?.force !== true) {
|
|
46038
46348
|
const nodeDaemonId = typeof node.daemonId === "string" ? node.daemonId.trim() : "";
|
|
46039
46349
|
const nodeMachineId = readMeshNodeMachineId(node) || "";
|
|
@@ -46147,7 +46457,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
46147
46457
|
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
46148
46458
|
const mesh = meshRecord?.mesh;
|
|
46149
46459
|
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
46150
|
-
const sourceNode = mesh.nodes?.find((n) => n
|
|
46460
|
+
const sourceNode = mesh.nodes?.find((n) => meshNodeIdMatches(n, sourceNodeId));
|
|
46151
46461
|
if (!sourceNode) return { success: false, error: `Source node '${sourceNodeId}' not found in mesh` };
|
|
46152
46462
|
const sourceDaemonId = typeof sourceNode.daemonId === "string" ? sourceNode.daemonId.trim() : void 0;
|
|
46153
46463
|
if (sourceDaemonId && sourceDaemonId !== this.deps.statusInstanceId && this.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
|
|
@@ -46167,9 +46477,9 @@ ${hintLines.join("\n")}` : "",
|
|
|
46167
46477
|
});
|
|
46168
46478
|
let node;
|
|
46169
46479
|
if (meshRecord.inline) {
|
|
46170
|
-
const { randomUUID:
|
|
46480
|
+
const { randomUUID: randomUUID15 } = await import("crypto");
|
|
46171
46481
|
node = {
|
|
46172
|
-
id: `node_${
|
|
46482
|
+
id: `node_${randomUUID15().replace(/-/g, "")}`,
|
|
46173
46483
|
workspace: result.worktreePath,
|
|
46174
46484
|
repoRoot: result.worktreePath,
|
|
46175
46485
|
daemonId: sourceNode.daemonId,
|
|
@@ -46388,7 +46698,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
46388
46698
|
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
46389
46699
|
const mesh = meshRecord?.mesh;
|
|
46390
46700
|
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
46391
|
-
const node = mesh.nodes?.find((n) => n
|
|
46701
|
+
const node = mesh.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
|
|
46392
46702
|
if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
|
|
46393
46703
|
if (!node.isLocalWorktree) return { success: false, error: "Node is not a local worktree node" };
|
|
46394
46704
|
const nodeDaemonId = typeof node.daemonId === "string" ? node.daemonId.trim() : void 0;
|
|
@@ -46525,14 +46835,14 @@ ${hintLines.join("\n")}` : "",
|
|
|
46525
46835
|
const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
|
|
46526
46836
|
const workspace = readLiveMeshNodeWorkspace({
|
|
46527
46837
|
meshId,
|
|
46528
|
-
nodeId: String(coordinatorNode
|
|
46838
|
+
nodeId: String(normalizeMeshNodeId(coordinatorNode) || preferredCoordinatorNodeId || ""),
|
|
46529
46839
|
liveSessionRecords: liveMeshSessions,
|
|
46530
46840
|
allowCoordinatorSession: true
|
|
46531
46841
|
}) || (typeof coordinatorNode.workspace === "string" ? coordinatorNode.workspace.trim() : "");
|
|
46532
46842
|
if (!workspace) return { success: false, error: "Coordinator node workspace required", meshId, cliType };
|
|
46533
46843
|
if (!cliType) {
|
|
46534
46844
|
const resolved = await resolveProviderTypeFromPriority({
|
|
46535
|
-
nodeId: String(coordinatorNode
|
|
46845
|
+
nodeId: String(normalizeMeshNodeId(coordinatorNode) || preferredCoordinatorNodeId || "coordinator"),
|
|
46536
46846
|
providerPriority: readProviderPriorityFromPolicy(coordinatorNode.policy),
|
|
46537
46847
|
providerLoader: this.deps.providerLoader,
|
|
46538
46848
|
onStatusChange: this.deps.onStatusChange
|
|
@@ -46943,10 +47253,11 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
46943
47253
|
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
46944
47254
|
const meshHost = resolveMeshHostStatus(mesh);
|
|
46945
47255
|
const refreshRequested = args?.refresh === true || args?.forceRefresh === true;
|
|
47256
|
+
const verboseMissions = args?.verbose === true || args?.compact === false;
|
|
46946
47257
|
const peekScope = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
|
|
46947
47258
|
const pendingCoordinatorEventCount = getPendingMeshCoordinatorEvents(meshId, peekScope).length;
|
|
46948
47259
|
const hadAggregateCache = this.aggregateMeshStatusCache.has(meshId);
|
|
46949
|
-
if (!refreshRequested && pendingCoordinatorEventCount === 0) {
|
|
47260
|
+
if (!refreshRequested && !verboseMissions && pendingCoordinatorEventCount === 0) {
|
|
46950
47261
|
const cachedStatus = this.getCachedAggregateMeshStatus(meshId, mesh, { requireDirectPeerTruth: args?.requireDirectPeerTruth === true });
|
|
46951
47262
|
if (cachedStatus) {
|
|
46952
47263
|
logRepoMeshStatusDebug("return_cached", {
|
|
@@ -46986,7 +47297,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
46986
47297
|
const passivePeerTruthNotAttempted = requireDirectPeerTruth && !refreshRequested && directTruth.directEvidenceCount > 0 && directTruth.peerAttemptedCount === 0;
|
|
46987
47298
|
const effectiveDirectTruth = passivePeerTruthNotAttempted ? { ...directTruth, unavailableNodeIds: [] } : directTruth;
|
|
46988
47299
|
const unavailableDirectTruthNodeIds = new Set(effectiveDirectTruth.unavailableNodeIds);
|
|
46989
|
-
const unavailableNodesAreOnlyRemovedWorktrees = unavailableDirectTruthNodeIds.size > 0 && Array.isArray(mesh.nodes) && mesh.nodes.filter((node) => unavailableDirectTruthNodeIds.has(
|
|
47300
|
+
const unavailableNodesAreOnlyRemovedWorktrees = unavailableDirectTruthNodeIds.size > 0 && Array.isArray(mesh.nodes) && mesh.nodes.filter((node) => unavailableDirectTruthNodeIds.has(normalizeMeshNodeId(node) ?? "")).every((node) => node?.isLocalWorktree === true);
|
|
46990
47301
|
const directTruthSatisfied = !requireDirectPeerTruth || effectiveDirectTruth.directEvidenceCount > 0 && (effectiveDirectTruth.unavailableNodeIds.length === 0 || unavailableNodesAreOnlyRemovedWorktrees);
|
|
46991
47302
|
if (requireDirectPeerTruth && !directTruthSatisfied) {
|
|
46992
47303
|
const failureResult = {
|
|
@@ -47021,14 +47332,13 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
47021
47332
|
const coordinatorHostname = osHostname();
|
|
47022
47333
|
const selectedCoordinatorNodeId = readStringValue(
|
|
47023
47334
|
mesh.coordinator?.preferredNodeId,
|
|
47024
|
-
mesh.nodes?.[0]
|
|
47025
|
-
mesh.nodes?.[0]?.nodeId
|
|
47335
|
+
normalizeMeshNodeId(mesh.nodes?.[0])
|
|
47026
47336
|
);
|
|
47027
47337
|
const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes) ? selectedCoordinatorNodeId : void 0;
|
|
47028
47338
|
const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
47029
47339
|
const nodeStatuses = [];
|
|
47030
47340
|
for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
|
|
47031
|
-
const nodeId =
|
|
47341
|
+
const nodeId = normalizeMeshNodeId(node) ?? "";
|
|
47032
47342
|
const daemonId = readStringValue(node.daemonId);
|
|
47033
47343
|
const nodeMachineId = readMeshNodeMachineId(node);
|
|
47034
47344
|
const nodeHostname = readMeshNodeHostname(node);
|
|
@@ -47250,7 +47560,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
47250
47560
|
liveSessionRecords: liveMeshSessions
|
|
47251
47561
|
});
|
|
47252
47562
|
const { getMeshStatusMissionSummaries: getMeshStatusMissionSummaries2 } = await Promise.resolve().then(() => (init_mesh_missions(), mesh_missions_exports));
|
|
47253
|
-
const missions = getMeshStatusMissionSummaries2(meshId);
|
|
47563
|
+
const missions = getMeshStatusMissionSummaries2(meshId, { verbose: verboseMissions });
|
|
47254
47564
|
const statusResult = {
|
|
47255
47565
|
success: true,
|
|
47256
47566
|
meshId: mesh.id,
|
|
@@ -47304,7 +47614,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
47304
47614
|
}))
|
|
47305
47615
|
};
|
|
47306
47616
|
const { pendingCoordinatorEvents: _pendingCoordinatorEvents, unroutableDeliveries: _unroutableDeliveries, ...cacheableStatusResult } = statusResult;
|
|
47307
|
-
const rememberedStatus = this.rememberAggregateMeshStatus(meshId, cacheableStatusResult, refreshReason);
|
|
47617
|
+
const rememberedStatus = verboseMissions ? cacheableStatusResult : this.rememberAggregateMeshStatus(meshId, cacheableStatusResult, refreshReason);
|
|
47308
47618
|
const returnedStatus = {
|
|
47309
47619
|
...rememberedStatus,
|
|
47310
47620
|
...pendingCoordinatorEvents.length > 0 ? { pendingCoordinatorEvents } : {},
|
|
@@ -54860,7 +55170,7 @@ var SessionHostPtyTransportFactory = class {
|
|
|
54860
55170
|
};
|
|
54861
55171
|
|
|
54862
55172
|
// src/cli-adapters/raw-terminal-io.ts
|
|
54863
|
-
import { randomUUID as
|
|
55173
|
+
import { randomUUID as randomUUID14 } from "crypto";
|
|
54864
55174
|
import {
|
|
54865
55175
|
SessionHostClient as SessionHostClient2
|
|
54866
55176
|
} from "@adhdev/session-host-core";
|
|
@@ -54960,7 +55270,7 @@ var RawTerminalAttachment = class _RawTerminalAttachment {
|
|
|
54960
55270
|
const sessionId = String(options.sessionId || "").trim();
|
|
54961
55271
|
if (!sessionId) throw new Error("sessionId is required");
|
|
54962
55272
|
const mode = options.mode || "read";
|
|
54963
|
-
const clientId = options.clientId || `raw-terminal-${process.pid}-${
|
|
55273
|
+
const clientId = options.clientId || `raw-terminal-${process.pid}-${randomUUID14().slice(0, 8)}`;
|
|
54964
55274
|
const client = options.client || new SessionHostClient2({ endpoint: options.endpoint });
|
|
54965
55275
|
await client.connect();
|
|
54966
55276
|
const attachResponse = await client.request({
|