@adhdev/daemon-core 0.9.82-rc.262 → 0.9.82-rc.263
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/build-info.d.ts +37 -0
- package/dist/git/git-status.d.ts +7 -0
- package/dist/git/git-types.d.ts +19 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +490 -64
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +486 -64
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-active-work.d.ts +18 -0
- package/dist/mesh/mesh-fast-forward.d.ts +41 -1
- package/dist/mesh/mesh-ledger.d.ts +1 -1
- package/dist/mesh/mesh-runtime-store.d.ts +6 -0
- package/dist/mesh/mesh-work-queue.d.ts +6 -0
- package/package.json +1 -1
- package/src/build-info.ts +73 -0
- package/src/commands/router.ts +49 -2
- package/src/git/git-status.ts +73 -1
- package/src/git/git-types.ts +20 -0
- package/src/index.ts +5 -2
- package/src/mesh/mesh-active-work.ts +31 -0
- package/src/mesh/mesh-fast-forward.ts +418 -17
- package/src/mesh/mesh-ledger.ts +1 -0
- package/src/mesh/mesh-runtime-store.ts +19 -0
- package/src/mesh/mesh-work-queue.ts +13 -0
package/dist/index.js
CHANGED
|
@@ -256,6 +256,29 @@ var init_git_executor = __esm({
|
|
|
256
256
|
}
|
|
257
257
|
});
|
|
258
258
|
|
|
259
|
+
// src/build-info.ts
|
|
260
|
+
function readInjected(value) {
|
|
261
|
+
if (typeof value !== "string") return void 0;
|
|
262
|
+
const trimmed = value.trim();
|
|
263
|
+
if (!trimmed || trimmed === "unknown") return void 0;
|
|
264
|
+
return trimmed;
|
|
265
|
+
}
|
|
266
|
+
function getDaemonBuildInfo() {
|
|
267
|
+
if (cached) return cached;
|
|
268
|
+
const commit = readInjected(true ? "2cf602f99ce68b3d3f1af02b429f6fb7a7c8e686" : void 0) ?? "unknown";
|
|
269
|
+
const commitShort = readInjected(true ? "2cf602f" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
270
|
+
const version = readInjected(true ? "0.9.82-rc.263" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
271
|
+
const builtAt = readInjected(true ? "2026-06-14T13:48:10.699Z" : void 0);
|
|
272
|
+
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
273
|
+
return cached;
|
|
274
|
+
}
|
|
275
|
+
var cached;
|
|
276
|
+
var init_build_info = __esm({
|
|
277
|
+
"src/build-info.ts"() {
|
|
278
|
+
"use strict";
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
|
|
259
282
|
// src/git/git-status.ts
|
|
260
283
|
async function getGitRepoStatus(workspace, options = {}) {
|
|
261
284
|
const lastCheckedAt = Date.now();
|
|
@@ -278,6 +301,7 @@ async function getGitRepoStatus(workspace, options = {}) {
|
|
|
278
301
|
}
|
|
279
302
|
const submoduleDirty = (submodules || []).some((submodule) => submodule.dirty || submodule.outOfSync || !!submodule.error);
|
|
280
303
|
const dirty = parsed.staged + parsed.modified + parsed.untracked + parsed.deleted + parsed.renamed > 0 || parsed.conflictFiles.length > 0 || stashCount > 0 || submoduleDirty;
|
|
304
|
+
const daemonBuildBehind = await detectDaemonBuildBehind(repo, submodules, options);
|
|
281
305
|
return {
|
|
282
306
|
workspace: repo.workspace,
|
|
283
307
|
repoRoot: repo.repoRoot,
|
|
@@ -301,7 +325,8 @@ async function getGitRepoStatus(workspace, options = {}) {
|
|
|
301
325
|
conflictFiles: parsed.conflictFiles,
|
|
302
326
|
stashCount,
|
|
303
327
|
lastCheckedAt,
|
|
304
|
-
submodules
|
|
328
|
+
submodules,
|
|
329
|
+
...daemonBuildBehind ? { daemonBuildBehind } : {}
|
|
305
330
|
};
|
|
306
331
|
} catch (error) {
|
|
307
332
|
if (error instanceof GitCommandError) {
|
|
@@ -314,6 +339,35 @@ async function getGitRepoStatus(workspace, options = {}) {
|
|
|
314
339
|
);
|
|
315
340
|
}
|
|
316
341
|
}
|
|
342
|
+
async function detectDaemonBuildBehind(repo, submodules, options) {
|
|
343
|
+
const build = options.daemonBuildInfo ?? getDaemonBuildInfo();
|
|
344
|
+
if (!build.commit || build.commit === "unknown") return void 0;
|
|
345
|
+
const scopes = [
|
|
346
|
+
{ scope: "root", repoPath: repo.repoRoot || repo.workspace }
|
|
347
|
+
];
|
|
348
|
+
for (const sub of submodules || []) {
|
|
349
|
+
if (sub.repoPath && !sub.error) scopes.push({ scope: sub.path, repoPath: sub.repoPath });
|
|
350
|
+
}
|
|
351
|
+
for (const { scope, repoPath } of scopes) {
|
|
352
|
+
try {
|
|
353
|
+
await runGit(repoPath, ["cat-file", "-e", `${build.commit}^{commit}`], options);
|
|
354
|
+
const headResult = await runGit(repoPath, ["rev-parse", "HEAD"], options);
|
|
355
|
+
const head = headResult.stdout.trim();
|
|
356
|
+
if (!head || head === build.commit) continue;
|
|
357
|
+
await runGit(repoPath, ["merge-base", "--is-ancestor", build.commit, "HEAD"], options);
|
|
358
|
+
return {
|
|
359
|
+
buildCommit: build.commit,
|
|
360
|
+
buildCommitShort: build.commitShort,
|
|
361
|
+
head,
|
|
362
|
+
scope,
|
|
363
|
+
warning: `Live daemon was built from ${build.commitShort} which is behind ${scope === "root" ? "workspace" : scope} 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.`
|
|
364
|
+
};
|
|
365
|
+
} catch {
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return void 0;
|
|
370
|
+
}
|
|
317
371
|
async function readPorcelainStatus(repo, options) {
|
|
318
372
|
const statusOutput = await runGit(repo, ["status", "--porcelain=v2", "--branch"], options);
|
|
319
373
|
return parsePorcelainV2Status(statusOutput.stdout);
|
|
@@ -530,6 +584,7 @@ var init_git_status = __esm({
|
|
|
530
584
|
"src/git/git-status.ts"() {
|
|
531
585
|
"use strict";
|
|
532
586
|
init_git_executor();
|
|
587
|
+
init_build_info();
|
|
533
588
|
}
|
|
534
589
|
});
|
|
535
590
|
|
|
@@ -2386,8 +2441,8 @@ function readLedgerFromStore(meshId) {
|
|
|
2386
2441
|
}
|
|
2387
2442
|
function getCachedRawEntries(meshId) {
|
|
2388
2443
|
const now = Date.now();
|
|
2389
|
-
const
|
|
2390
|
-
if (
|
|
2444
|
+
const cached2 = ledgerReadCache.get(meshId);
|
|
2445
|
+
if (cached2 && now - cached2.cachedAt < LEDGER_CACHE_TTL_MS) return cached2.entries;
|
|
2391
2446
|
let entries;
|
|
2392
2447
|
try {
|
|
2393
2448
|
entries = readLedgerFromStore(meshId);
|
|
@@ -2650,6 +2705,7 @@ __export(mesh_work_queue_exports, {
|
|
|
2650
2705
|
cancelTask: () => cancelTask,
|
|
2651
2706
|
claimNextTask: () => claimNextTask,
|
|
2652
2707
|
cleanupTerminalDirectDispatches: () => cleanupTerminalDirectDispatches,
|
|
2708
|
+
deleteDirectDispatchesByTaskId: () => deleteDirectDispatchesByTaskId,
|
|
2653
2709
|
describeTaskDependencyState: () => describeTaskDependencyState,
|
|
2654
2710
|
enqueueTask: () => enqueueTask,
|
|
2655
2711
|
getActiveDirectDispatches: () => getActiveDirectDispatches,
|
|
@@ -3058,6 +3114,13 @@ function markStaleDirectDispatches(meshId, olderThanMs = 60 * 6e4) {
|
|
|
3058
3114
|
} catch {
|
|
3059
3115
|
}
|
|
3060
3116
|
}
|
|
3117
|
+
function deleteDirectDispatchesByTaskId(meshId, taskIds) {
|
|
3118
|
+
try {
|
|
3119
|
+
return MeshRuntimeStore.getInstance().deleteDirectDispatchesByTaskId(meshId, taskIds);
|
|
3120
|
+
} catch {
|
|
3121
|
+
return 0;
|
|
3122
|
+
}
|
|
3123
|
+
}
|
|
3061
3124
|
function recordMeshToolCall(opts) {
|
|
3062
3125
|
try {
|
|
3063
3126
|
return MeshRuntimeStore.getInstance().recordMeshToolCall(opts);
|
|
@@ -3691,6 +3754,24 @@ var init_mesh_runtime_store = __esm({
|
|
|
3691
3754
|
deleteDirectDispatches(meshId) {
|
|
3692
3755
|
this.db.prepare(`DELETE FROM mesh_direct_dispatches WHERE mesh_id = ?`).run(meshId);
|
|
3693
3756
|
}
|
|
3757
|
+
/**
|
|
3758
|
+
* Delete specific direct dispatch rows by taskId for a mesh. Used by the staleDirect prune
|
|
3759
|
+
* path to remove orphaned/terminal dispatch records whose node/session is no longer in the
|
|
3760
|
+
* live mesh. Returns the number of rows actually deleted. No-op for an empty taskId list.
|
|
3761
|
+
*/
|
|
3762
|
+
deleteDirectDispatchesByTaskId(meshId, taskIds) {
|
|
3763
|
+
const ids = (taskIds || []).map((id) => typeof id === "string" ? id.trim() : "").filter(Boolean);
|
|
3764
|
+
if (!ids.length) return 0;
|
|
3765
|
+
const stmt = this.db.prepare(`DELETE FROM mesh_direct_dispatches WHERE mesh_id = ? AND task_id = ?`);
|
|
3766
|
+
let deleted = 0;
|
|
3767
|
+
const run = this.db.transaction((rows) => {
|
|
3768
|
+
for (const taskId of rows) {
|
|
3769
|
+
deleted += stmt.run(meshId, taskId).changes;
|
|
3770
|
+
}
|
|
3771
|
+
});
|
|
3772
|
+
run(ids);
|
|
3773
|
+
return deleted;
|
|
3774
|
+
}
|
|
3694
3775
|
markStaleDirectDispatches(meshId, olderThanMs) {
|
|
3695
3776
|
const cutoff = new Date(Date.now() - olderThanMs).toISOString();
|
|
3696
3777
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -5359,11 +5440,14 @@ async function fastForwardMeshNode(args) {
|
|
|
5359
5440
|
const trigger = normalizeOptionalString(args.trigger) || "manual";
|
|
5360
5441
|
const updateSubmodules = args.updateSubmodules === true;
|
|
5361
5442
|
const dryRun = args.dryRun === true || args.execute !== true;
|
|
5362
|
-
const
|
|
5443
|
+
const mode = args.mode === "push" ? "push" : "merge";
|
|
5444
|
+
const pushSubmodules = mode === "push" && args.pushSubmodules === true;
|
|
5445
|
+
const plannedSteps = buildPlannedSteps(mode, updateSubmodules, pushSubmodules);
|
|
5363
5446
|
const base = {
|
|
5364
5447
|
...nodeId ? { nodeId } : {},
|
|
5365
5448
|
...meshId ? { meshId } : {},
|
|
5366
5449
|
workspace,
|
|
5450
|
+
mode,
|
|
5367
5451
|
dryRun,
|
|
5368
5452
|
updateSubmodules,
|
|
5369
5453
|
plannedSteps,
|
|
@@ -5377,13 +5461,24 @@ async function fastForwardMeshNode(args) {
|
|
|
5377
5461
|
submoduleIgnorePaths: args.submoduleIgnorePaths,
|
|
5378
5462
|
timeoutMs: args.timeoutMs ?? STATUS_OPTIONS.timeoutMs
|
|
5379
5463
|
});
|
|
5464
|
+
if (mode === "push") {
|
|
5465
|
+
return pushMeshNode(base, args, current, {
|
|
5466
|
+
pushSubmodules,
|
|
5467
|
+
allowAutoPublishSubmoduleMainCommits: args.allowAutoPublishSubmoduleMainCommits === true
|
|
5468
|
+
});
|
|
5469
|
+
}
|
|
5380
5470
|
const earlyBlockers = collectPreflightBlockers(current, requestedBranch);
|
|
5381
5471
|
if (earlyBlockers.length > 0) {
|
|
5472
|
+
const blockCode = chooseBlockCode(current, earlyBlockers);
|
|
5382
5473
|
const result2 = {
|
|
5383
|
-
...block(base,
|
|
5474
|
+
...block(base, blockCode, earlyBlockers),
|
|
5384
5475
|
current,
|
|
5385
|
-
finalBranchConvergenceState: buildConvergenceState(current, codeToConvergenceStatus(
|
|
5476
|
+
finalBranchConvergenceState: buildConvergenceState(current, codeToConvergenceStatus(blockCode))
|
|
5386
5477
|
};
|
|
5478
|
+
if (blockCode === "branch_ahead" && current.ahead > 0 && current.behind === 0 && otherBlockersAreOnlyAhead(earlyBlockers)) {
|
|
5479
|
+
result2.code = "ahead_needs_push";
|
|
5480
|
+
result2.nextStep = 'Local branch is ahead of origin with nothing to merge. Re-run mesh_fast_forward_node with mode="push" (execute=true) to ff-only push the local commits to origin.';
|
|
5481
|
+
}
|
|
5387
5482
|
await appendFastForwardLedger(result2, "blocked");
|
|
5388
5483
|
return result2;
|
|
5389
5484
|
}
|
|
@@ -5494,7 +5589,246 @@ async function fastForwardMeshNode(args) {
|
|
|
5494
5589
|
await appendFastForwardLedger(result, success ? "executed" : "failed");
|
|
5495
5590
|
return result;
|
|
5496
5591
|
}
|
|
5497
|
-
function
|
|
5592
|
+
async function pushMeshNode(base, args, current, options) {
|
|
5593
|
+
const workspace = base.workspace;
|
|
5594
|
+
const requestedBranch = normalizeOptionalString(args.branch);
|
|
5595
|
+
const dryRun = base.dryRun;
|
|
5596
|
+
const blockers = collectPushPreflightBlockers(current, requestedBranch);
|
|
5597
|
+
if (blockers.length > 0) {
|
|
5598
|
+
const code2 = choosePushBlockCode(current, blockers);
|
|
5599
|
+
const result2 = {
|
|
5600
|
+
...block(base, code2, blockers),
|
|
5601
|
+
current,
|
|
5602
|
+
preStatus: current,
|
|
5603
|
+
finalBranchConvergenceState: buildConvergenceState(current, codeToConvergenceStatus(code2))
|
|
5604
|
+
};
|
|
5605
|
+
await appendFastForwardLedger(result2, "blocked");
|
|
5606
|
+
return result2;
|
|
5607
|
+
}
|
|
5608
|
+
const target = parseUpstreamTarget(current.upstream || "");
|
|
5609
|
+
if (!target) {
|
|
5610
|
+
const result2 = {
|
|
5611
|
+
...block(base, "upstream_unparseable", ["upstream_unparseable"]),
|
|
5612
|
+
current,
|
|
5613
|
+
preStatus: current,
|
|
5614
|
+
finalBranchConvergenceState: buildConvergenceState(current, "blocked")
|
|
5615
|
+
};
|
|
5616
|
+
await appendFastForwardLedger(result2, "blocked");
|
|
5617
|
+
return result2;
|
|
5618
|
+
}
|
|
5619
|
+
const refspec = `HEAD:refs/heads/${target.remoteBranch}`;
|
|
5620
|
+
const pushTarget = { remote: target.remote, remoteBranch: target.remoteBranch, refspec };
|
|
5621
|
+
if (current.ahead <= 0) {
|
|
5622
|
+
const result2 = {
|
|
5623
|
+
...base,
|
|
5624
|
+
success: true,
|
|
5625
|
+
code: "nothing_to_push",
|
|
5626
|
+
allowed: true,
|
|
5627
|
+
willRun: false,
|
|
5628
|
+
executed: false,
|
|
5629
|
+
blockingReasons: [],
|
|
5630
|
+
current,
|
|
5631
|
+
preStatus: current,
|
|
5632
|
+
postStatus: current,
|
|
5633
|
+
pushTarget,
|
|
5634
|
+
finalBranchConvergenceState: buildConvergenceState(current, "up_to_date")
|
|
5635
|
+
};
|
|
5636
|
+
await appendFastForwardLedger(result2, "noop");
|
|
5637
|
+
return result2;
|
|
5638
|
+
}
|
|
5639
|
+
const descendant = await verifyUpstreamIsAncestorOfHead(workspace, current.upstream || "", args.timeoutMs);
|
|
5640
|
+
if (!descendant.ok) {
|
|
5641
|
+
const result2 = {
|
|
5642
|
+
...block(base, "non_fast_forward_push", ["head_is_not_descendant_of_upstream"]),
|
|
5643
|
+
current,
|
|
5644
|
+
preStatus: current,
|
|
5645
|
+
pushTarget,
|
|
5646
|
+
operationError: descendant.error,
|
|
5647
|
+
nextStep: "origin/<branch> has commits not in local HEAD; a ff-only push would lose them. Converge by rebasing onto origin first, then re-run. This operation never force-pushes.",
|
|
5648
|
+
finalBranchConvergenceState: buildConvergenceState(current, "not_mergeable")
|
|
5649
|
+
};
|
|
5650
|
+
await appendFastForwardLedger(result2, "blocked");
|
|
5651
|
+
return result2;
|
|
5652
|
+
}
|
|
5653
|
+
if (dryRun) {
|
|
5654
|
+
const result2 = {
|
|
5655
|
+
...base,
|
|
5656
|
+
success: true,
|
|
5657
|
+
code: "push_available",
|
|
5658
|
+
allowed: true,
|
|
5659
|
+
willRun: false,
|
|
5660
|
+
executed: false,
|
|
5661
|
+
blockingReasons: [],
|
|
5662
|
+
current,
|
|
5663
|
+
preStatus: current,
|
|
5664
|
+
pushTarget,
|
|
5665
|
+
...options.pushSubmodules ? { submodulePushes: await planSubmodulePushes(current, options, args.timeoutMs) } : {},
|
|
5666
|
+
finalBranchConvergenceState: buildConvergenceState(current, "push_available")
|
|
5667
|
+
};
|
|
5668
|
+
await appendFastForwardLedger(result2, "dry_run");
|
|
5669
|
+
return result2;
|
|
5670
|
+
}
|
|
5671
|
+
try {
|
|
5672
|
+
await runGit(workspace, ["push", target.remote, refspec], { timeoutMs: args.timeoutMs ?? 3e4 });
|
|
5673
|
+
} catch (error) {
|
|
5674
|
+
const result2 = {
|
|
5675
|
+
...block(base, "push_ff_only_failed", ["push_ff_only_failed"]),
|
|
5676
|
+
current,
|
|
5677
|
+
preStatus: current,
|
|
5678
|
+
pushTarget,
|
|
5679
|
+
operationError: formatGitError2(error),
|
|
5680
|
+
finalBranchConvergenceState: buildConvergenceState(current, "not_mergeable")
|
|
5681
|
+
};
|
|
5682
|
+
await appendFastForwardLedger(result2, "failed");
|
|
5683
|
+
return result2;
|
|
5684
|
+
}
|
|
5685
|
+
let submodulePushes;
|
|
5686
|
+
if (options.pushSubmodules) {
|
|
5687
|
+
submodulePushes = await executeSubmodulePushes(current, options, args.timeoutMs);
|
|
5688
|
+
}
|
|
5689
|
+
const postStatus = await getGitRepoStatus(workspace, {
|
|
5690
|
+
...STATUS_OPTIONS,
|
|
5691
|
+
submoduleIgnorePaths: args.submoduleIgnorePaths,
|
|
5692
|
+
timeoutMs: args.timeoutMs ?? STATUS_OPTIONS.timeoutMs
|
|
5693
|
+
});
|
|
5694
|
+
const submodulePushFailed = (submodulePushes || []).some((entry) => !entry.pushed && !entry.skipped);
|
|
5695
|
+
const blockingReasons = [];
|
|
5696
|
+
if (postStatus.ahead !== 0) blockingReasons.push("post_branch_ahead");
|
|
5697
|
+
if (submodulePushFailed) blockingReasons.push("submodule_push_failed");
|
|
5698
|
+
const success = blockingReasons.length === 0;
|
|
5699
|
+
const code = success ? "push_applied" : submodulePushFailed && postStatus.ahead === 0 ? "push_applied_submodule_push_failed" : "post_push_verify_failed";
|
|
5700
|
+
const result = {
|
|
5701
|
+
...base,
|
|
5702
|
+
success,
|
|
5703
|
+
code,
|
|
5704
|
+
allowed: true,
|
|
5705
|
+
willRun: true,
|
|
5706
|
+
executed: true,
|
|
5707
|
+
blockingReasons,
|
|
5708
|
+
current,
|
|
5709
|
+
preStatus: current,
|
|
5710
|
+
postStatus,
|
|
5711
|
+
pushTarget,
|
|
5712
|
+
...submodulePushes ? { submodulePushes } : {},
|
|
5713
|
+
finalBranchConvergenceState: buildConvergenceState(postStatus, success ? "pushed" : "post_verify_failed")
|
|
5714
|
+
};
|
|
5715
|
+
await appendFastForwardLedger(result, success ? "executed" : "failed");
|
|
5716
|
+
return result;
|
|
5717
|
+
}
|
|
5718
|
+
function collectPushPreflightBlockers(status, requestedBranch) {
|
|
5719
|
+
const blockers = [];
|
|
5720
|
+
if (!status.isGitRepo) blockers.push("not_git_repo");
|
|
5721
|
+
if (!status.branch) blockers.push("detached_head_or_unknown_branch");
|
|
5722
|
+
if (requestedBranch && status.branch !== requestedBranch) blockers.push("branch_mismatch");
|
|
5723
|
+
if (!status.upstream) blockers.push("upstream_missing");
|
|
5724
|
+
if (status.upstreamStatus !== "fresh") blockers.push("upstream_not_fresh");
|
|
5725
|
+
if (status.hasConflicts) blockers.push("conflicts_present");
|
|
5726
|
+
if (status.staged > 0) blockers.push("staged_changes_present");
|
|
5727
|
+
if (status.modified > 0) blockers.push("modified_changes_present");
|
|
5728
|
+
if (status.untracked > 0) blockers.push("untracked_changes_present");
|
|
5729
|
+
if (status.deleted > 0) blockers.push("deleted_changes_present");
|
|
5730
|
+
if (status.renamed > 0) blockers.push("renamed_changes_present");
|
|
5731
|
+
if (status.stashCount > 0) blockers.push("stash_entries_present");
|
|
5732
|
+
if (status.ahead > 0 && status.behind > 0) blockers.push("branch_diverged_from_upstream");
|
|
5733
|
+
else if (status.behind > 0) blockers.push("branch_behind_upstream");
|
|
5734
|
+
return blockers;
|
|
5735
|
+
}
|
|
5736
|
+
function choosePushBlockCode(status, blockers) {
|
|
5737
|
+
if (blockers.includes("not_git_repo")) return "not_git_repo";
|
|
5738
|
+
if (blockers.includes("branch_mismatch")) return "branch_mismatch";
|
|
5739
|
+
if (blockers.includes("upstream_missing")) return "upstream_missing";
|
|
5740
|
+
if (blockers.includes("upstream_not_fresh")) return "upstream_not_fresh";
|
|
5741
|
+
if (blockers.includes("branch_diverged_from_upstream")) return "branch_diverged";
|
|
5742
|
+
if (blockers.includes("branch_behind_upstream")) return "non_fast_forward_push";
|
|
5743
|
+
if (blockers.some((reason) => reason.includes("changes") || reason.includes("conflicts") || reason.includes("stash"))) return "dirty_worktree";
|
|
5744
|
+
return "preflight_blocked";
|
|
5745
|
+
}
|
|
5746
|
+
function parseUpstreamTarget(upstream) {
|
|
5747
|
+
const trimmed = upstream.trim();
|
|
5748
|
+
const slash = trimmed.indexOf("/");
|
|
5749
|
+
if (slash <= 0 || slash >= trimmed.length - 1) return null;
|
|
5750
|
+
return { remote: trimmed.slice(0, slash), remoteBranch: trimmed.slice(slash + 1) };
|
|
5751
|
+
}
|
|
5752
|
+
async function verifyUpstreamIsAncestorOfHead(workspace, upstream, timeoutMs) {
|
|
5753
|
+
if (!upstream) return { ok: false, error: "missing upstream" };
|
|
5754
|
+
try {
|
|
5755
|
+
await runGit(workspace, ["merge-base", "--is-ancestor", upstream, "HEAD"], { timeoutMs: timeoutMs ?? 15e3 });
|
|
5756
|
+
return { ok: true };
|
|
5757
|
+
} catch (error) {
|
|
5758
|
+
return { ok: false, error: formatGitError2(error) };
|
|
5759
|
+
}
|
|
5760
|
+
}
|
|
5761
|
+
async function planSubmodulePushes(status, options, timeoutMs) {
|
|
5762
|
+
return resolveSubmodulePushes(status, options, false, timeoutMs);
|
|
5763
|
+
}
|
|
5764
|
+
async function executeSubmodulePushes(status, options, timeoutMs) {
|
|
5765
|
+
return resolveSubmodulePushes(status, options, true, timeoutMs);
|
|
5766
|
+
}
|
|
5767
|
+
async function resolveSubmodulePushes(status, options, execute, timeoutMs) {
|
|
5768
|
+
const submodules = Array.isArray(status.submodules) ? status.submodules : [];
|
|
5769
|
+
const results = [];
|
|
5770
|
+
for (const submodule of submodules) {
|
|
5771
|
+
const base = {
|
|
5772
|
+
path: submodule.path,
|
|
5773
|
+
commit: submodule.commit,
|
|
5774
|
+
remote: "origin",
|
|
5775
|
+
remoteBranch: "main",
|
|
5776
|
+
pushed: false,
|
|
5777
|
+
skipped: true,
|
|
5778
|
+
code: "submodule_push_skipped"
|
|
5779
|
+
};
|
|
5780
|
+
if (!options.allowAutoPublishSubmoduleMainCommits) {
|
|
5781
|
+
results.push({ ...base, code: "submodule_push_policy_disabled", error: "allowAutoPublishSubmoduleMainCommits is not enabled" });
|
|
5782
|
+
continue;
|
|
5783
|
+
}
|
|
5784
|
+
if (submodule.error || submodule.dirty) {
|
|
5785
|
+
results.push({ ...base, code: "submodule_not_clean", error: submodule.error || "submodule worktree is dirty" });
|
|
5786
|
+
continue;
|
|
5787
|
+
}
|
|
5788
|
+
const repoPath = submodule.repoPath;
|
|
5789
|
+
if (!repoPath || !submodule.commit) {
|
|
5790
|
+
results.push({ ...base, code: "submodule_status_incomplete" });
|
|
5791
|
+
continue;
|
|
5792
|
+
}
|
|
5793
|
+
try {
|
|
5794
|
+
await runGit(repoPath, ["-c", "protocol.file.allow=always", "fetch", "origin", "refs/heads/main:refs/remotes/origin/main"], { timeoutMs: timeoutMs ?? 3e4 });
|
|
5795
|
+
} catch (error) {
|
|
5796
|
+
results.push({ ...base, code: "submodule_fetch_failed", error: formatGitError2(error) });
|
|
5797
|
+
continue;
|
|
5798
|
+
}
|
|
5799
|
+
let alreadyReachable = false;
|
|
5800
|
+
try {
|
|
5801
|
+
await runGit(repoPath, ["merge-base", "--is-ancestor", submodule.commit, "refs/remotes/origin/main"], { timeoutMs: timeoutMs ?? 15e3 });
|
|
5802
|
+
alreadyReachable = true;
|
|
5803
|
+
} catch {
|
|
5804
|
+
}
|
|
5805
|
+
if (alreadyReachable) {
|
|
5806
|
+
results.push({ ...base, pushed: false, skipped: true, code: "submodule_already_reachable" });
|
|
5807
|
+
continue;
|
|
5808
|
+
}
|
|
5809
|
+
try {
|
|
5810
|
+
await runGit(repoPath, ["merge-base", "--is-ancestor", "refs/remotes/origin/main", submodule.commit], { timeoutMs: timeoutMs ?? 15e3 });
|
|
5811
|
+
} catch (error) {
|
|
5812
|
+
results.push({ ...base, pushed: false, skipped: false, code: "submodule_non_fast_forward", error: formatGitError2(error) });
|
|
5813
|
+
continue;
|
|
5814
|
+
}
|
|
5815
|
+
const refspec = `${submodule.commit}:refs/heads/main`;
|
|
5816
|
+
if (!execute) {
|
|
5817
|
+
results.push({ ...base, pushed: false, skipped: false, code: "submodule_push_available", refspec });
|
|
5818
|
+
continue;
|
|
5819
|
+
}
|
|
5820
|
+
try {
|
|
5821
|
+
await runGit(repoPath, ["push", "origin", refspec], { timeoutMs: timeoutMs ?? 3e4 });
|
|
5822
|
+
await runGit(repoPath, ["-c", "protocol.file.allow=always", "fetch", "origin", "refs/heads/main:refs/remotes/origin/main"], { timeoutMs: timeoutMs ?? 3e4 });
|
|
5823
|
+
await runGit(repoPath, ["merge-base", "--is-ancestor", submodule.commit, "refs/remotes/origin/main"], { timeoutMs: timeoutMs ?? 15e3 });
|
|
5824
|
+
results.push({ ...base, pushed: true, skipped: false, code: "submodule_pushed", refspec });
|
|
5825
|
+
} catch (error) {
|
|
5826
|
+
results.push({ ...base, pushed: false, skipped: false, code: "submodule_push_failed", refspec, error: formatGitError2(error) });
|
|
5827
|
+
}
|
|
5828
|
+
}
|
|
5829
|
+
return results;
|
|
5830
|
+
}
|
|
5831
|
+
function buildPlannedSteps(mode, updateSubmodules, pushSubmodules) {
|
|
5498
5832
|
const steps = [
|
|
5499
5833
|
{
|
|
5500
5834
|
operation: "refresh_upstream",
|
|
@@ -5507,20 +5841,49 @@ function buildPlannedSteps(updateSubmodules) {
|
|
|
5507
5841
|
description: "Require clean staged/modified/untracked/deleted/renamed/conflict/stash/submodule state.",
|
|
5508
5842
|
safe: true,
|
|
5509
5843
|
willMutateWorktree: false
|
|
5510
|
-
}
|
|
5511
|
-
|
|
5512
|
-
|
|
5513
|
-
|
|
5844
|
+
}
|
|
5845
|
+
];
|
|
5846
|
+
if (mode === "push") {
|
|
5847
|
+
steps.push({
|
|
5848
|
+
operation: "verify_push_descendant",
|
|
5849
|
+
description: "Require HEAD to be a descendant of origin/<branch> (origin/<branch> is an ancestor of HEAD); refuse any non-fast-forward push.",
|
|
5514
5850
|
safe: true,
|
|
5515
5851
|
willMutateWorktree: false
|
|
5516
|
-
}
|
|
5517
|
-
{
|
|
5518
|
-
operation: "
|
|
5519
|
-
description: "
|
|
5852
|
+
});
|
|
5853
|
+
steps.push({
|
|
5854
|
+
operation: "push_ff_only",
|
|
5855
|
+
description: "Run git push origin HEAD:<branch> as a strict ff-only push; never --force, --force-with-lease, reset, or rebase. Does not mutate the worktree.",
|
|
5520
5856
|
safe: true,
|
|
5521
|
-
willMutateWorktree:
|
|
5857
|
+
willMutateWorktree: false
|
|
5858
|
+
});
|
|
5859
|
+
if (pushSubmodules) {
|
|
5860
|
+
steps.push({
|
|
5861
|
+
operation: "push_submodules_ff_only",
|
|
5862
|
+
description: "For each submodule, if allowAutoPublishSubmoduleMainCommits is enabled and the submodule HEAD is a descendant of its origin main, ff-only push it to submodule origin main; otherwise skip.",
|
|
5863
|
+
safe: true,
|
|
5864
|
+
willMutateWorktree: false
|
|
5865
|
+
});
|
|
5522
5866
|
}
|
|
5523
|
-
|
|
5867
|
+
steps.push({
|
|
5868
|
+
operation: "verify_post_status",
|
|
5869
|
+
description: "Re-read daemon-owned git status and report final branch convergence state.",
|
|
5870
|
+
safe: true,
|
|
5871
|
+
willMutateWorktree: false
|
|
5872
|
+
});
|
|
5873
|
+
return steps;
|
|
5874
|
+
}
|
|
5875
|
+
steps.push({
|
|
5876
|
+
operation: "verify_fast_forward",
|
|
5877
|
+
description: "Require ahead=0, behind>0, and HEAD to be an ancestor of the upstream ref.",
|
|
5878
|
+
safe: true,
|
|
5879
|
+
willMutateWorktree: false
|
|
5880
|
+
});
|
|
5881
|
+
steps.push({
|
|
5882
|
+
operation: "merge_ff_only",
|
|
5883
|
+
description: "Apply git merge --ff-only against the tracked upstream; no force, reset, rebase, push, or deploy.",
|
|
5884
|
+
safe: true,
|
|
5885
|
+
willMutateWorktree: true
|
|
5886
|
+
});
|
|
5524
5887
|
if (updateSubmodules) {
|
|
5525
5888
|
steps.push({
|
|
5526
5889
|
operation: "submodule_update",
|
|
@@ -5537,6 +5900,10 @@ function buildPlannedSteps(updateSubmodules) {
|
|
|
5537
5900
|
});
|
|
5538
5901
|
return steps;
|
|
5539
5902
|
}
|
|
5903
|
+
function otherBlockersAreOnlyAhead(blockers) {
|
|
5904
|
+
const aheadOnly = /* @__PURE__ */ new Set(["branch_has_local_commits"]);
|
|
5905
|
+
return blockers.every((reason) => aheadOnly.has(reason));
|
|
5906
|
+
}
|
|
5540
5907
|
function collectPreflightBlockers(status, requestedBranch) {
|
|
5541
5908
|
const blockers = [];
|
|
5542
5909
|
if (!status.isGitRepo) blockers.push("not_git_repo");
|
|
@@ -5593,7 +5960,7 @@ function chooseBlockCode(status, blockers) {
|
|
|
5593
5960
|
return "preflight_blocked";
|
|
5594
5961
|
}
|
|
5595
5962
|
function codeToConvergenceStatus(code) {
|
|
5596
|
-
if (code === "branch_diverged" || code === "branch_ahead" || code === "non_fast_forward") return "not_mergeable";
|
|
5963
|
+
if (code === "branch_diverged" || code === "branch_ahead" || code === "non_fast_forward" || code === "non_fast_forward_push" || code === "upstream_unparseable") return "not_mergeable";
|
|
5597
5964
|
if (code === "dirty_worktree" || code === "submodule_not_clean") return "blocked_review";
|
|
5598
5965
|
return "blocked";
|
|
5599
5966
|
}
|
|
@@ -5676,6 +6043,7 @@ async function appendFastForwardLedger(result, outcome) {
|
|
|
5676
6043
|
...result.nodeId ? { nodeId: result.nodeId } : {},
|
|
5677
6044
|
payload: {
|
|
5678
6045
|
operation: "mesh_fast_forward_node",
|
|
6046
|
+
mode: result.mode,
|
|
5679
6047
|
trigger: result.trigger || "manual",
|
|
5680
6048
|
outcome,
|
|
5681
6049
|
code: result.code,
|
|
@@ -5686,6 +6054,7 @@ async function appendFastForwardLedger(result, outcome) {
|
|
|
5686
6054
|
executed: result.executed,
|
|
5687
6055
|
branch: result.postStatus?.branch ?? result.current?.branch,
|
|
5688
6056
|
upstream: result.postStatus?.upstream ?? result.current?.upstream,
|
|
6057
|
+
...result.pushTarget ? { pushTarget: result.pushTarget } : {},
|
|
5689
6058
|
before: result.current ? {
|
|
5690
6059
|
headCommit: result.current.headCommit,
|
|
5691
6060
|
ahead: result.current.ahead,
|
|
@@ -5696,6 +6065,16 @@ async function appendFastForwardLedger(result, outcome) {
|
|
|
5696
6065
|
ahead: result.postStatus.ahead,
|
|
5697
6066
|
behind: result.postStatus.behind
|
|
5698
6067
|
} : void 0,
|
|
6068
|
+
...result.submodulePushes ? {
|
|
6069
|
+
submodulePushes: result.submodulePushes.map((entry) => ({
|
|
6070
|
+
path: entry.path,
|
|
6071
|
+
commit: entry.commit,
|
|
6072
|
+
pushed: entry.pushed,
|
|
6073
|
+
skipped: entry.skipped,
|
|
6074
|
+
code: entry.code,
|
|
6075
|
+
...entry.refspec ? { refspec: entry.refspec } : {}
|
|
6076
|
+
}))
|
|
6077
|
+
} : {},
|
|
5699
6078
|
blockingReasons: result.blockingReasons
|
|
5700
6079
|
}
|
|
5701
6080
|
});
|
|
@@ -6866,8 +7245,8 @@ var init_mesh_routing = __esm({
|
|
|
6866
7245
|
// src/mesh/mesh-events-coordinator.ts
|
|
6867
7246
|
function getCachedMeshByWorkspace(workspace) {
|
|
6868
7247
|
const now = Date.now();
|
|
6869
|
-
const
|
|
6870
|
-
if (
|
|
7248
|
+
const cached2 = meshByWorkspaceCache.get(workspace);
|
|
7249
|
+
if (cached2 && now - cached2.cachedAt < MESH_WORKSPACE_CACHE_TTL_MS) return cached2.mesh;
|
|
6871
7250
|
const mesh = getMeshByRepo(workspace);
|
|
6872
7251
|
meshByWorkspaceCache.set(workspace, { mesh, cachedAt: now });
|
|
6873
7252
|
return mesh;
|
|
@@ -11759,10 +12138,10 @@ ${lastSnapshot}`;
|
|
|
11759
12138
|
return this.accumulatedRawBuffer.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, "").replace(/\x1B[P^_X][\s\S]*?(?:\x07|\x1B\\)/g, "").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
|
|
11760
12139
|
}
|
|
11761
12140
|
getFreshParsedStatusCache() {
|
|
11762
|
-
const
|
|
12141
|
+
const cached2 = this.parsedStatusCache;
|
|
11763
12142
|
const accumulatedRawBufferKey = this.getAccumulatedRawBufferCacheKey();
|
|
11764
|
-
if (
|
|
11765
|
-
return
|
|
12143
|
+
if (cached2 && cached2.responseBuffer === this.responseBuffer && cached2.currentTurnScope === this.engine.currentTurnScope && cached2.recentOutputBuffer === this.recentOutputBuffer && cached2.accumulatedBuffer === this.accumulatedBuffer && cached2.accumulatedRawBufferKey === accumulatedRawBufferKey && cached2.screenText === this.lastScreenText && cached2.currentStatus === this.engine.currentStatus && cached2.activeModal === this.engine.activeModal && cached2.cliName === this.cliName) {
|
|
12144
|
+
return cached2.result;
|
|
11766
12145
|
}
|
|
11767
12146
|
return null;
|
|
11768
12147
|
}
|
|
@@ -12222,10 +12601,10 @@ ${lastSnapshot}`;
|
|
|
12222
12601
|
getScriptParsedStatus() {
|
|
12223
12602
|
const screenText = this.readTerminalScreenText();
|
|
12224
12603
|
const parseScreenText = this.getParseScreenText(screenText);
|
|
12225
|
-
const
|
|
12604
|
+
const cached2 = this.parsedStatusCache;
|
|
12226
12605
|
const accumulatedRawBufferKey = this.getAccumulatedRawBufferCacheKey();
|
|
12227
|
-
if (!this.providerOwnsTranscript() &&
|
|
12228
|
-
return
|
|
12606
|
+
if (!this.providerOwnsTranscript() && cached2 && cached2.responseBuffer === this.responseBuffer && cached2.currentTurnScope === this.engine.currentTurnScope && cached2.recentOutputBuffer === this.recentOutputBuffer && cached2.accumulatedBuffer === this.accumulatedBuffer && cached2.accumulatedRawBufferKey === accumulatedRawBufferKey && cached2.screenText === parseScreenText && cached2.currentStatus === this.engine.currentStatus && cached2.activeModal === this.engine.activeModal && cached2.cliName === this.cliName) {
|
|
12607
|
+
return cached2.result;
|
|
12229
12608
|
}
|
|
12230
12609
|
const parsed = this.runParseSession();
|
|
12231
12610
|
if (!parsed || !Array.isArray(parsed.messages)) {
|
|
@@ -14091,6 +14470,7 @@ __export(index_exports, {
|
|
|
14091
14470
|
MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS: () => MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS,
|
|
14092
14471
|
NodePtyTransportFactory: () => NodePtyTransportFactory,
|
|
14093
14472
|
P2pRelayFailureError: () => P2pRelayFailureError,
|
|
14473
|
+
PRUNABLE_ORPHAN_STALE_REASONS: () => PRUNABLE_ORPHAN_STALE_REASONS,
|
|
14094
14474
|
ProviderCliAdapter: () => ProviderCliAdapter,
|
|
14095
14475
|
ProviderInstanceManager: () => ProviderInstanceManager,
|
|
14096
14476
|
ProviderLoader: () => ProviderLoader,
|
|
@@ -14144,6 +14524,7 @@ __export(index_exports, {
|
|
|
14144
14524
|
classifyChatMessageVisibility: () => classifyChatMessageVisibility,
|
|
14145
14525
|
classifyHotChatSessionsForSubscriptionFlush: () => classifyHotChatSessionsForSubscriptionFlush,
|
|
14146
14526
|
classifyP2pRelayFailure: () => classifyP2pRelayFailure,
|
|
14527
|
+
classifyStaleDirectForPrune: () => classifyStaleDirectForPrune,
|
|
14147
14528
|
cleanupTerminalDirectDispatches: () => cleanupTerminalDirectDispatches,
|
|
14148
14529
|
clearDebugTrace: () => clearDebugTrace,
|
|
14149
14530
|
clearPendingMeshCoordinatorEvents: () => clearPendingMeshCoordinatorEvents,
|
|
@@ -14163,6 +14544,7 @@ __export(index_exports, {
|
|
|
14163
14544
|
createNativeHistoryDispatcher: () => createNativeHistoryDispatcher,
|
|
14164
14545
|
createSessionDelivery: () => createSessionDelivery,
|
|
14165
14546
|
createWorktree: () => createWorktree,
|
|
14547
|
+
deleteDirectDispatchesByTaskId: () => deleteDirectDispatchesByTaskId,
|
|
14166
14548
|
deleteMesh: () => deleteMesh,
|
|
14167
14549
|
deriveMeshReviewInboxItems: () => deriveMeshReviewInboxItems,
|
|
14168
14550
|
describeTaskDependencyState: () => describeTaskDependencyState,
|
|
@@ -14191,6 +14573,7 @@ __export(index_exports, {
|
|
|
14191
14573
|
getAvailableIdeIds: () => getAvailableIdeIds,
|
|
14192
14574
|
getCoordinatorForSession: () => getCoordinatorForSession,
|
|
14193
14575
|
getCurrentDaemonLogPath: () => getCurrentDaemonLogPath,
|
|
14576
|
+
getDaemonBuildInfo: () => getDaemonBuildInfo,
|
|
14194
14577
|
getDaemonDataDir: () => getDaemonDataDir,
|
|
14195
14578
|
getDaemonLogDir: () => getDaemonLogDir,
|
|
14196
14579
|
getDebugRuntimeConfig: () => getDebugRuntimeConfig,
|
|
@@ -17037,6 +17420,17 @@ function buildMeshActiveWork(opts) {
|
|
|
17037
17420
|
}
|
|
17038
17421
|
return { activeWork: records, staleDirectWork, staleDirectWorkNote, terminalDirectWork, summary };
|
|
17039
17422
|
}
|
|
17423
|
+
var PRUNABLE_ORPHAN_STALE_REASONS = /* @__PURE__ */ new Set([
|
|
17424
|
+
"direct task node is no longer in the live mesh",
|
|
17425
|
+
"direct task session is not present in live session records",
|
|
17426
|
+
"direct task has no node id"
|
|
17427
|
+
]);
|
|
17428
|
+
function classifyStaleDirectForPrune(record, opts = {}) {
|
|
17429
|
+
if (record.staleDispatchUnacknowledged === true) return "preserve_unacknowledged";
|
|
17430
|
+
if (record.terminal === true) return opts.includeTerminal ? "prunable_terminal" : "preserve_active";
|
|
17431
|
+
if (record.staleReason && PRUNABLE_ORPHAN_STALE_REASONS.has(record.staleReason)) return "prunable_orphan";
|
|
17432
|
+
return "preserve_active";
|
|
17433
|
+
}
|
|
17040
17434
|
function buildCompactStaleDirectWorkSummary(staleDirectWork, opts = {}) {
|
|
17041
17435
|
const sampleLimit = Math.max(0, Math.min(10, Math.floor(opts.sampleLimit ?? 3)));
|
|
17042
17436
|
const reasonCounts = {};
|
|
@@ -20260,9 +20654,9 @@ function computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatur
|
|
|
20260
20654
|
for (const file of files.slice().sort()) {
|
|
20261
20655
|
const filePath = path12.join(dir, file);
|
|
20262
20656
|
const signature = fileSignatures.get(file) || `${file}:missing`;
|
|
20263
|
-
const
|
|
20657
|
+
const cached2 = savedHistoryFileSummaryCache.get(filePath);
|
|
20264
20658
|
const persisted = persistedEntries.get(file);
|
|
20265
|
-
const reusableEntry =
|
|
20659
|
+
const reusableEntry = cached2?.signature === signature ? cached2 : persisted?.signature === signature ? persisted : null;
|
|
20266
20660
|
const fileSummary = reusableEntry?.summary || computeSavedHistoryFileSummary(dir, file);
|
|
20267
20661
|
const nextEntry = reusableEntry || {
|
|
20268
20662
|
signature,
|
|
@@ -20714,23 +21108,23 @@ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
|
20714
21108
|
savedHistorySessionCache.delete(sanitized);
|
|
20715
21109
|
return { sessions: [], hasMore: false };
|
|
20716
21110
|
}
|
|
20717
|
-
const
|
|
21111
|
+
const cached2 = savedHistorySessionCache.get(sanitized);
|
|
20718
21112
|
const offset = Math.max(0, options.offset || 0);
|
|
20719
21113
|
const limit = Math.max(1, options.limit || 30);
|
|
20720
21114
|
const indexSignature = buildSavedHistoryIndexFileSignature(dir);
|
|
20721
21115
|
let cacheWasInvalidated = false;
|
|
20722
|
-
if (
|
|
20723
|
-
const cacheLooksPersisted =
|
|
20724
|
-
const cacheStillValid = cacheLooksPersisted ?
|
|
21116
|
+
if (cached2) {
|
|
21117
|
+
const cacheLooksPersisted = cached2.signature.startsWith("index:");
|
|
21118
|
+
const cacheStillValid = cacheLooksPersisted ? cached2.signature === indexSignature : (() => {
|
|
20725
21119
|
const files2 = listHistoryFiles(dir);
|
|
20726
21120
|
const fileSignatures2 = buildSavedHistoryFileSignatureMap(dir, files2);
|
|
20727
|
-
return
|
|
21121
|
+
return cached2.signature === buildSavedHistoryCacheSignature(files2, fileSignatures2);
|
|
20728
21122
|
})();
|
|
20729
21123
|
if (cacheStillValid) {
|
|
20730
|
-
const sliced2 =
|
|
21124
|
+
const sliced2 = cached2.summaries.slice(offset, offset + limit);
|
|
20731
21125
|
return {
|
|
20732
21126
|
sessions: sliced2,
|
|
20733
|
-
hasMore:
|
|
21127
|
+
hasMore: cached2.summaries.length > offset + limit
|
|
20734
21128
|
};
|
|
20735
21129
|
}
|
|
20736
21130
|
cacheWasInvalidated = true;
|
|
@@ -37319,8 +37713,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
37319
37713
|
return null;
|
|
37320
37714
|
}
|
|
37321
37715
|
registerProviderScriptRootSafely(path30.dirname(path30.dirname(providerDir)));
|
|
37322
|
-
const
|
|
37323
|
-
if (
|
|
37716
|
+
const cached2 = this.scriptsCache.get(dir);
|
|
37717
|
+
if (cached2) return cached2;
|
|
37324
37718
|
const scriptsJs = path30.join(dir, "scripts.js");
|
|
37325
37719
|
if (fs20.existsSync(scriptsJs)) {
|
|
37326
37720
|
try {
|
|
@@ -39318,6 +39712,9 @@ function buildStatusSnapshot(options) {
|
|
|
39318
39712
|
};
|
|
39319
39713
|
}
|
|
39320
39714
|
|
|
39715
|
+
// src/commands/router.ts
|
|
39716
|
+
init_build_info();
|
|
39717
|
+
|
|
39321
39718
|
// src/commands/upgrade-helper.ts
|
|
39322
39719
|
var import_child_process7 = require("child_process");
|
|
39323
39720
|
var import_child_process8 = require("child_process");
|
|
@@ -40103,13 +40500,13 @@ function sanitizeInlineMesh(inlineMesh) {
|
|
|
40103
40500
|
nodes
|
|
40104
40501
|
};
|
|
40105
40502
|
}
|
|
40106
|
-
function reconcileInlineMeshCache(
|
|
40107
|
-
if (!
|
|
40108
|
-
if (!incoming || typeof incoming !== "object" || Array.isArray(incoming)) return
|
|
40109
|
-
const cachedNodes = Array.isArray(
|
|
40503
|
+
function reconcileInlineMeshCache(cached2, incoming) {
|
|
40504
|
+
if (!cached2 || typeof cached2 !== "object" || Array.isArray(cached2)) return incoming;
|
|
40505
|
+
if (!incoming || typeof incoming !== "object" || Array.isArray(incoming)) return cached2;
|
|
40506
|
+
const cachedNodes = Array.isArray(cached2.nodes) ? cached2.nodes : [];
|
|
40110
40507
|
const incomingNodes = Array.isArray(incoming.nodes) ? incoming.nodes : [];
|
|
40111
|
-
if (!cachedNodes.length || !incomingNodes.length) return { ...
|
|
40112
|
-
const cachedUpdatedAt = Date.parse(readStringValue(
|
|
40508
|
+
if (!cachedNodes.length || !incomingNodes.length) return { ...cached2, ...incoming };
|
|
40509
|
+
const cachedUpdatedAt = Date.parse(readStringValue(cached2.updatedAt, cached2.updated_at) || "");
|
|
40113
40510
|
const incomingUpdatedAt = Date.parse(readStringValue(incoming.updatedAt, incoming.updated_at) || "");
|
|
40114
40511
|
const preserveCachedMembership = Number.isFinite(cachedUpdatedAt) && (!Number.isFinite(incomingUpdatedAt) || cachedUpdatedAt > incomingUpdatedAt);
|
|
40115
40512
|
const cachedById = /* @__PURE__ */ new Map();
|
|
@@ -40138,7 +40535,7 @@ function reconcileInlineMeshCache(cached, incoming) {
|
|
|
40138
40535
|
}
|
|
40139
40536
|
}
|
|
40140
40537
|
return {
|
|
40141
|
-
...
|
|
40538
|
+
...cached2,
|
|
40142
40539
|
...incoming,
|
|
40143
40540
|
nodes
|
|
40144
40541
|
};
|
|
@@ -41822,13 +42219,13 @@ var DaemonCommandRouter = class {
|
|
|
41822
42219
|
};
|
|
41823
42220
|
}
|
|
41824
42221
|
getCachedAggregateMeshStatus(meshId, mesh, options) {
|
|
41825
|
-
const
|
|
41826
|
-
if (!
|
|
41827
|
-
if (
|
|
41828
|
-
let snapshot = this.cloneJsonValue(
|
|
42222
|
+
const cached2 = this.aggregateMeshStatusCache.get(meshId);
|
|
42223
|
+
if (!cached2?.snapshot || cached2.snapshot.success !== true || !Array.isArray(cached2.snapshot.nodes)) return null;
|
|
42224
|
+
if (cached2.queueRevision !== getMeshQueueRevision(meshId)) return null;
|
|
42225
|
+
let snapshot = this.cloneJsonValue(cached2.snapshot);
|
|
41829
42226
|
snapshot = this.hydrateCachedAggregateMeshStatusFromInline(snapshot, mesh, options);
|
|
41830
42227
|
if (shouldRefreshStalePendingAggregate(snapshot, options)) return null;
|
|
41831
|
-
const ageMs = Math.max(0, Date.now() -
|
|
42228
|
+
const ageMs = Math.max(0, Date.now() - cached2.builtAt);
|
|
41832
42229
|
const sourceOfTruth = snapshot.sourceOfTruth && typeof snapshot.sourceOfTruth === "object" ? snapshot.sourceOfTruth : {};
|
|
41833
42230
|
snapshot.sourceOfTruth = {
|
|
41834
42231
|
...sourceOfTruth,
|
|
@@ -41839,7 +42236,7 @@ var DaemonCommandRouter = class {
|
|
|
41839
42236
|
source: "memory",
|
|
41840
42237
|
refreshReason: "memory_cache_hit",
|
|
41841
42238
|
ageMs,
|
|
41842
|
-
cachedAt: new Date(
|
|
42239
|
+
cachedAt: new Date(cached2.builtAt).toISOString(),
|
|
41843
42240
|
returnedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
41844
42241
|
}
|
|
41845
42242
|
};
|
|
@@ -41883,9 +42280,9 @@ var DaemonCommandRouter = class {
|
|
|
41883
42280
|
warmInlineMeshCache(meshId, inlineMesh) {
|
|
41884
42281
|
if (!inlineMesh || typeof inlineMesh !== "object") return void 0;
|
|
41885
42282
|
const sanitizedInlineMesh = sanitizeInlineMesh(inlineMesh);
|
|
41886
|
-
const
|
|
41887
|
-
if (
|
|
41888
|
-
const merged = reconcileInlineMeshCache(
|
|
42283
|
+
const cached2 = this.inlineMeshCache.get(meshId);
|
|
42284
|
+
if (cached2) {
|
|
42285
|
+
const merged = reconcileInlineMeshCache(cached2, sanitizedInlineMesh);
|
|
41889
42286
|
this.inlineMeshCache.set(meshId, merged);
|
|
41890
42287
|
return merged;
|
|
41891
42288
|
}
|
|
@@ -41895,14 +42292,14 @@ var DaemonCommandRouter = class {
|
|
|
41895
42292
|
async getMeshForCommand(meshId, inlineMesh, options) {
|
|
41896
42293
|
const preferInline = options?.preferInline === true;
|
|
41897
42294
|
if (preferInline) {
|
|
41898
|
-
const
|
|
41899
|
-
if (
|
|
42295
|
+
const cached3 = this.getCachedInlineMesh(meshId);
|
|
42296
|
+
if (cached3) {
|
|
41900
42297
|
if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
|
|
41901
|
-
const merged = reconcileInlineMeshCache(
|
|
42298
|
+
const merged = reconcileInlineMeshCache(cached3, inlineMesh);
|
|
41902
42299
|
this.inlineMeshCache.set(meshId, sanitizeInlineMesh(merged));
|
|
41903
42300
|
return { mesh: merged, inline: true, source: "inline_cache" };
|
|
41904
42301
|
}
|
|
41905
|
-
return { mesh:
|
|
42302
|
+
return { mesh: cached3, inline: true, source: "inline_cache" };
|
|
41906
42303
|
}
|
|
41907
42304
|
if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
|
|
41908
42305
|
this.warmInlineMeshCache(meshId, inlineMesh);
|
|
@@ -41915,8 +42312,8 @@ var DaemonCommandRouter = class {
|
|
|
41915
42312
|
if (mesh) return { mesh, inline: false, source: "local_config" };
|
|
41916
42313
|
} catch {
|
|
41917
42314
|
}
|
|
41918
|
-
const
|
|
41919
|
-
if (
|
|
42315
|
+
const cached2 = this.getCachedInlineMesh(meshId);
|
|
42316
|
+
if (cached2) return { mesh: cached2, inline: true, source: "inline_cache" };
|
|
41920
42317
|
const warmedInline = this.warmInlineMeshCache(meshId, inlineMesh);
|
|
41921
42318
|
return warmedInline ? { mesh: warmedInline, inline: true, source: "inline_bootstrap" } : null;
|
|
41922
42319
|
}
|
|
@@ -42223,6 +42620,8 @@ var DaemonCommandRouter = class {
|
|
|
42223
42620
|
const skippedSessionIds = [];
|
|
42224
42621
|
const skippedLiveSessionIds = [];
|
|
42225
42622
|
const skippedCoordinatorSessionIds = [];
|
|
42623
|
+
const skippedLiveSessionReasons = [];
|
|
42624
|
+
const actedLiveDelegateSessionIds = [];
|
|
42226
42625
|
const deleteUnsupportedSessionIds = [];
|
|
42227
42626
|
const recordsRemainSessionIds = [];
|
|
42228
42627
|
const errors = [];
|
|
@@ -42256,16 +42655,31 @@ var DaemonCommandRouter = class {
|
|
|
42256
42655
|
const surfaceKind = getSessionHostSurfaceKind(record);
|
|
42257
42656
|
const liveRuntime = surfaceKind === "live_runtime";
|
|
42258
42657
|
const coordinatorSession = readStringValue(record?.meta?.meshCoordinatorFor) === args.meshId;
|
|
42658
|
+
const recordNodeId = readStringValue(record?.meta?.meshNodeId);
|
|
42659
|
+
const recordMeshNodeFor = readStringValue(record?.meta?.meshNodeFor);
|
|
42660
|
+
const delegateBoundToThisNode = !!recordNodeId && recordNodeId === args.nodeId && (!recordMeshNodeFor || recordMeshNodeFor === args.meshId);
|
|
42259
42661
|
if (!hasExplicitSessionIds && coordinatorSession) {
|
|
42260
42662
|
skippedSessionIds.push(sessionId);
|
|
42261
42663
|
skippedCoordinatorSessionIds.push(sessionId);
|
|
42262
42664
|
continue;
|
|
42263
42665
|
}
|
|
42264
|
-
if (!hasExplicitSessionIds && liveRuntime) {
|
|
42666
|
+
if (!hasExplicitSessionIds && liveRuntime && !delegateBoundToThisNode) {
|
|
42667
|
+
skippedSessionIds.push(sessionId);
|
|
42668
|
+
skippedLiveSessionIds.push(sessionId);
|
|
42669
|
+
const matchedByWorkspaceOnly = !recordNodeId;
|
|
42670
|
+
const reason = recordNodeId && recordNodeId !== args.nodeId ? `live_delegate_bound_to_other_node:${recordNodeId}` : matchedByWorkspaceOnly ? "live_session_matched_by_workspace_only_no_node_binding" : "live_session_not_bound_to_this_node";
|
|
42671
|
+
skippedLiveSessionReasons.push({ sessionId, reason });
|
|
42672
|
+
continue;
|
|
42673
|
+
}
|
|
42674
|
+
if (!hasExplicitSessionIds && liveRuntime && delegateBoundToThisNode && args.mode === "delete_stopped") {
|
|
42265
42675
|
skippedSessionIds.push(sessionId);
|
|
42266
42676
|
skippedLiveSessionIds.push(sessionId);
|
|
42677
|
+
skippedLiveSessionReasons.push({ sessionId, reason: "live_delegate_preserved_by_delete_stopped_mode_use_stop_or_stop_and_delete" });
|
|
42267
42678
|
continue;
|
|
42268
42679
|
}
|
|
42680
|
+
if (!hasExplicitSessionIds && liveRuntime && delegateBoundToThisNode) {
|
|
42681
|
+
actedLiveDelegateSessionIds.push(sessionId);
|
|
42682
|
+
}
|
|
42269
42683
|
try {
|
|
42270
42684
|
if (args.mode === "stop") {
|
|
42271
42685
|
if (!completed) {
|
|
@@ -42327,6 +42741,8 @@ var DaemonCommandRouter = class {
|
|
|
42327
42741
|
skippedSessionIds,
|
|
42328
42742
|
skippedLiveSessionIds,
|
|
42329
42743
|
skippedCoordinatorSessionIds,
|
|
42744
|
+
...actedLiveDelegateSessionIds.length ? { actedLiveDelegateSessionIds } : {},
|
|
42745
|
+
...skippedLiveSessionReasons.length ? { skippedLiveSessionReasons } : {},
|
|
42330
42746
|
...deleteUnsupported ? {
|
|
42331
42747
|
deleteUnsupported: true,
|
|
42332
42748
|
effectiveCleanup: args.mode === "stop_and_delete" ? "stopped_only_records_remain" : "delete_unsupported_records_remain",
|
|
@@ -43254,8 +43670,8 @@ ${hintLines.join("\n")}` : "",
|
|
|
43254
43670
|
const repoRootBaseRef = /* @__PURE__ */ new Map();
|
|
43255
43671
|
const submodulePathsByRepoRoot = /* @__PURE__ */ new Map();
|
|
43256
43672
|
const resolveBaseRef = async (repoRoot) => {
|
|
43257
|
-
const
|
|
43258
|
-
if (
|
|
43673
|
+
const cached2 = repoRootBaseRef.get(repoRoot);
|
|
43674
|
+
if (cached2) return cached2;
|
|
43259
43675
|
let baseBranch = "main";
|
|
43260
43676
|
try {
|
|
43261
43677
|
const { stdout } = await execFileAsync4("git", ["branch", "--show-current"], { cwd: repoRoot, encoding: "utf8" });
|
|
@@ -44153,7 +44569,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
44153
44569
|
version: this.deps.statusVersion || "unknown",
|
|
44154
44570
|
profile: "metadata"
|
|
44155
44571
|
});
|
|
44156
|
-
return { success: true, status: snapshot };
|
|
44572
|
+
return { success: true, status: snapshot, daemonBuild: getDaemonBuildInfo() };
|
|
44157
44573
|
}
|
|
44158
44574
|
case "get_machine_runtime_stats": {
|
|
44159
44575
|
return {
|
|
@@ -45123,6 +45539,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
45123
45539
|
let workspace = typeof args?.workspace === "string" ? args.workspace.trim() : "";
|
|
45124
45540
|
let submoduleIgnorePaths = Array.isArray(args?.submoduleIgnorePaths) ? args.submoduleIgnorePaths.filter((value) => typeof value === "string") : void 0;
|
|
45125
45541
|
let nodeDaemonId;
|
|
45542
|
+
let allowAutoPublishSubmoduleMainCommits = false;
|
|
45126
45543
|
if (meshId && nodeId) {
|
|
45127
45544
|
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
45128
45545
|
const mesh = meshRecord?.mesh;
|
|
@@ -45133,6 +45550,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
45133
45550
|
if (!submoduleIgnorePaths && Array.isArray(node?.policy?.submoduleIgnorePaths)) {
|
|
45134
45551
|
submoduleIgnorePaths = node.policy.submoduleIgnorePaths.filter((value) => typeof value === "string");
|
|
45135
45552
|
}
|
|
45553
|
+
allowAutoPublishSubmoduleMainCommits = mesh?.policy?.allowAutoPublishSubmoduleMainCommits === true;
|
|
45136
45554
|
nodeDaemonId = typeof node?.daemonId === "string" ? node.daemonId.trim() : void 0;
|
|
45137
45555
|
}
|
|
45138
45556
|
const selfDaemonId = this.deps.statusInstanceId;
|
|
@@ -45153,7 +45571,10 @@ ${hintLines.join("\n")}` : "",
|
|
|
45153
45571
|
execute: args?.execute === true,
|
|
45154
45572
|
dryRun: args?.dryRun === true,
|
|
45155
45573
|
updateSubmodules: args?.updateSubmodules === true,
|
|
45156
|
-
submoduleIgnorePaths
|
|
45574
|
+
submoduleIgnorePaths,
|
|
45575
|
+
mode: args?.mode === "push" ? "push" : "merge",
|
|
45576
|
+
pushSubmodules: args?.pushSubmodules === true,
|
|
45577
|
+
allowAutoPublishSubmoduleMainCommits
|
|
45157
45578
|
});
|
|
45158
45579
|
return result;
|
|
45159
45580
|
}
|
|
@@ -46853,6 +47274,7 @@ var DaemonStatusReporter = class {
|
|
|
46853
47274
|
};
|
|
46854
47275
|
|
|
46855
47276
|
// src/index.ts
|
|
47277
|
+
init_build_info();
|
|
46856
47278
|
init_logger();
|
|
46857
47279
|
init_debug_config();
|
|
46858
47280
|
|
|
@@ -55124,6 +55546,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
|
|
|
55124
55546
|
MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS,
|
|
55125
55547
|
NodePtyTransportFactory,
|
|
55126
55548
|
P2pRelayFailureError,
|
|
55549
|
+
PRUNABLE_ORPHAN_STALE_REASONS,
|
|
55127
55550
|
ProviderCliAdapter,
|
|
55128
55551
|
ProviderInstanceManager,
|
|
55129
55552
|
ProviderLoader,
|
|
@@ -55177,6 +55600,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
|
|
|
55177
55600
|
classifyChatMessageVisibility,
|
|
55178
55601
|
classifyHotChatSessionsForSubscriptionFlush,
|
|
55179
55602
|
classifyP2pRelayFailure,
|
|
55603
|
+
classifyStaleDirectForPrune,
|
|
55180
55604
|
cleanupTerminalDirectDispatches,
|
|
55181
55605
|
clearDebugTrace,
|
|
55182
55606
|
clearPendingMeshCoordinatorEvents,
|
|
@@ -55196,6 +55620,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
|
|
|
55196
55620
|
createNativeHistoryDispatcher,
|
|
55197
55621
|
createSessionDelivery,
|
|
55198
55622
|
createWorktree,
|
|
55623
|
+
deleteDirectDispatchesByTaskId,
|
|
55199
55624
|
deleteMesh,
|
|
55200
55625
|
deriveMeshReviewInboxItems,
|
|
55201
55626
|
describeTaskDependencyState,
|
|
@@ -55224,6 +55649,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
|
|
|
55224
55649
|
getAvailableIdeIds,
|
|
55225
55650
|
getCoordinatorForSession,
|
|
55226
55651
|
getCurrentDaemonLogPath,
|
|
55652
|
+
getDaemonBuildInfo,
|
|
55227
55653
|
getDaemonDataDir,
|
|
55228
55654
|
getDaemonLogDir,
|
|
55229
55655
|
getDebugRuntimeConfig,
|