@adhdev/daemon-core 0.9.82-rc.63 → 0.9.82-rc.65
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +158 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +158 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/commands/router.ts +184 -3
package/dist/index.js
CHANGED
|
@@ -25401,6 +25401,7 @@ function summarizeRepoMeshStatusDebug(status) {
|
|
|
25401
25401
|
meshId: readStringValue(status?.meshId, status?.mesh_id) ?? null,
|
|
25402
25402
|
refreshedAt: readStringValue(status?.refreshedAt, status?.refreshed_at) ?? null,
|
|
25403
25403
|
sourceOfTruth: status?.sourceOfTruth ?? null,
|
|
25404
|
+
branchConvergenceSummary: status?.branchConvergenceSummary ?? status?.branch_convergence_summary ?? null,
|
|
25404
25405
|
nodeCount: nodes.length,
|
|
25405
25406
|
nodes: nodes.map((node) => ({
|
|
25406
25407
|
nodeId: readStringValue(node?.nodeId, node?.id) ?? null,
|
|
@@ -25416,7 +25417,8 @@ function summarizeRepoMeshStatusDebug(status) {
|
|
|
25416
25417
|
} : null,
|
|
25417
25418
|
gitProbePending: node?.gitProbePending === true,
|
|
25418
25419
|
launchReady: node?.launchReady === true,
|
|
25419
|
-
git: summarizeRepoMeshDebugGit(node?.git)
|
|
25420
|
+
git: summarizeRepoMeshDebugGit(node?.git),
|
|
25421
|
+
branchConvergence: node?.branchConvergence ?? node?.branch_convergence ?? null
|
|
25420
25422
|
}))
|
|
25421
25423
|
};
|
|
25422
25424
|
}
|
|
@@ -25471,6 +25473,9 @@ function normalizeInlineMeshGitStatus(status, node, options) {
|
|
|
25471
25473
|
headCommit: readStringValue(status.headCommit) ?? null,
|
|
25472
25474
|
headMessage: readStringValue(status.headMessage) ?? null,
|
|
25473
25475
|
upstream: readStringValue(status.upstream) ?? null,
|
|
25476
|
+
upstreamStatus: readStringValue(status.upstreamStatus, status.upstream_status) ?? (readStringValue(status.upstream) ? "unchecked" : "no_upstream"),
|
|
25477
|
+
upstreamFetchedAt: readNumberValue(status.upstreamFetchedAt, status.upstream_fetched_at),
|
|
25478
|
+
upstreamFetchError: readStringValue(status.upstreamFetchError, status.upstream_fetch_error),
|
|
25474
25479
|
ahead: readNumberValue(status.ahead) ?? 0,
|
|
25475
25480
|
behind: readNumberValue(status.behind) ?? 0,
|
|
25476
25481
|
staged: readNumberValue(status.staged) ?? 0,
|
|
@@ -25669,8 +25674,11 @@ function reconcileInlineMeshCache(cached, incoming) {
|
|
|
25669
25674
|
};
|
|
25670
25675
|
}
|
|
25671
25676
|
function hasGitWorktreeChanges(git) {
|
|
25672
|
-
|
|
25673
|
-
|
|
25677
|
+
return countGitWorktreeChanges(git) > 0;
|
|
25678
|
+
}
|
|
25679
|
+
function countGitWorktreeChanges(git) {
|
|
25680
|
+
if (!git) return 0;
|
|
25681
|
+
return Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0);
|
|
25674
25682
|
}
|
|
25675
25683
|
function getGitSubmoduleDriftState(git) {
|
|
25676
25684
|
const submodules = Array.isArray(git?.submodules) ? git.submodules : [];
|
|
@@ -25692,6 +25700,146 @@ function deriveMeshNodeHealthFromGit(git) {
|
|
|
25692
25700
|
if (submoduleDrift.dirty || hasGitWorktreeChanges(git)) return "dirty";
|
|
25693
25701
|
return "online";
|
|
25694
25702
|
}
|
|
25703
|
+
function readMeshNodeLabel(status, node) {
|
|
25704
|
+
return readStringValue(status.nodeId, node?.id, node?.nodeId) ?? "unknown";
|
|
25705
|
+
}
|
|
25706
|
+
function buildInlineMeshBranchConvergence(args) {
|
|
25707
|
+
const git = readObjectRecord(args.status.git);
|
|
25708
|
+
const nodeLabel = readMeshNodeLabel(args.status, args.node);
|
|
25709
|
+
const defaultBranch = readStringValue(args.mesh?.defaultBranch) ?? "main";
|
|
25710
|
+
const branch = readStringValue(git.branch, args.node?.worktreeBranch) ?? null;
|
|
25711
|
+
const upstream = readStringValue(git.upstream) ?? null;
|
|
25712
|
+
const upstreamStatus = readStringValue(git.upstreamStatus, git.upstream_status) ?? (upstream ? "unchecked" : "no_upstream");
|
|
25713
|
+
const ahead = readNumberValue(git.ahead) ?? 0;
|
|
25714
|
+
const behind = readNumberValue(git.behind) ?? 0;
|
|
25715
|
+
const uncommittedChanges = countGitWorktreeChanges(git);
|
|
25716
|
+
const hasConflicts = readBooleanValue(git.hasConflicts) ?? (Array.isArray(git.conflictFiles) && git.conflictFiles.length > 0);
|
|
25717
|
+
const base = {
|
|
25718
|
+
defaultBranch,
|
|
25719
|
+
branch,
|
|
25720
|
+
upstream,
|
|
25721
|
+
upstreamStatus,
|
|
25722
|
+
ahead,
|
|
25723
|
+
behind,
|
|
25724
|
+
isWorktree: args.node?.isLocalWorktree === true || args.status.isLocalWorktree === true,
|
|
25725
|
+
isDefaultBranch: branch === defaultBranch
|
|
25726
|
+
};
|
|
25727
|
+
if (readBooleanValue(git.isGitRepo) !== true) {
|
|
25728
|
+
return {
|
|
25729
|
+
...base,
|
|
25730
|
+
status: "blocked_review",
|
|
25731
|
+
needsConvergence: true,
|
|
25732
|
+
reason: "git_status_unavailable",
|
|
25733
|
+
nextStep: `Resolve git status for node '${nodeLabel}' before marking the task complete.`
|
|
25734
|
+
};
|
|
25735
|
+
}
|
|
25736
|
+
if (!branch) {
|
|
25737
|
+
return {
|
|
25738
|
+
...base,
|
|
25739
|
+
status: "blocked_review",
|
|
25740
|
+
needsConvergence: true,
|
|
25741
|
+
reason: "branch_unknown",
|
|
25742
|
+
nextStep: `Inspect node '${nodeLabel}' git branch before deciding whether it is merged to ${defaultBranch}.`
|
|
25743
|
+
};
|
|
25744
|
+
}
|
|
25745
|
+
if (hasConflicts || uncommittedChanges > 0) {
|
|
25746
|
+
return {
|
|
25747
|
+
...base,
|
|
25748
|
+
status: "not_mergeable",
|
|
25749
|
+
needsConvergence: true,
|
|
25750
|
+
reason: hasConflicts ? "conflicts_present" : "dirty_workspace",
|
|
25751
|
+
nextStep: `Commit, checkpoint, or resolve node '${nodeLabel}' before any main convergence step.`
|
|
25752
|
+
};
|
|
25753
|
+
}
|
|
25754
|
+
if (branch === defaultBranch) {
|
|
25755
|
+
if (upstream && upstreamStatus !== "fresh") {
|
|
25756
|
+
return {
|
|
25757
|
+
...base,
|
|
25758
|
+
status: "blocked_review",
|
|
25759
|
+
needsConvergence: true,
|
|
25760
|
+
reason: "default_branch_upstream_unverified",
|
|
25761
|
+
nextStep: `Refresh ${defaultBranch}'s upstream refs or resolve the fetch failure before declaring convergence complete for node '${nodeLabel}'.`
|
|
25762
|
+
};
|
|
25763
|
+
}
|
|
25764
|
+
if (ahead > 0 || behind > 0) {
|
|
25765
|
+
return {
|
|
25766
|
+
...base,
|
|
25767
|
+
status: "blocked_review",
|
|
25768
|
+
needsConvergence: true,
|
|
25769
|
+
reason: "default_branch_not_even_with_upstream",
|
|
25770
|
+
nextStep: `Bring ${defaultBranch} even with its upstream before declaring convergence complete.`
|
|
25771
|
+
};
|
|
25772
|
+
}
|
|
25773
|
+
return {
|
|
25774
|
+
...base,
|
|
25775
|
+
status: "merged_to_main",
|
|
25776
|
+
needsConvergence: false,
|
|
25777
|
+
reason: "clean_default_branch",
|
|
25778
|
+
nextStep: null
|
|
25779
|
+
};
|
|
25780
|
+
}
|
|
25781
|
+
if (args.node?.isLocalWorktree === true || args.status.isLocalWorktree === true) {
|
|
25782
|
+
return {
|
|
25783
|
+
...base,
|
|
25784
|
+
status: "cleanup_candidate",
|
|
25785
|
+
needsConvergence: true,
|
|
25786
|
+
reason: "clean_non_default_worktree_branch",
|
|
25787
|
+
nextStep: `Run mesh_refine_node(node_id: "${nodeLabel}") or explicitly classify this worktree as blocked_review/not_mergeable before ending the task.`
|
|
25788
|
+
};
|
|
25789
|
+
}
|
|
25790
|
+
if (upstream && upstreamStatus !== "fresh") {
|
|
25791
|
+
return {
|
|
25792
|
+
...base,
|
|
25793
|
+
status: "blocked_review",
|
|
25794
|
+
needsConvergence: true,
|
|
25795
|
+
reason: "feature_branch_upstream_unverified",
|
|
25796
|
+
nextStep: `Refresh branch '${branch}' upstream refs or resolve the fetch failure before deciding whether it is ready to merge into ${defaultBranch}.`
|
|
25797
|
+
};
|
|
25798
|
+
}
|
|
25799
|
+
if (!upstream || ahead > 0 || behind > 0) {
|
|
25800
|
+
return {
|
|
25801
|
+
...base,
|
|
25802
|
+
status: "blocked_review",
|
|
25803
|
+
needsConvergence: true,
|
|
25804
|
+
reason: !upstream ? "feature_branch_missing_upstream" : "feature_branch_not_even_with_upstream",
|
|
25805
|
+
nextStep: `Push or reconcile branch '${branch}', then merge it into ${defaultBranch} or mark it not_mergeable with a reason.`
|
|
25806
|
+
};
|
|
25807
|
+
}
|
|
25808
|
+
return {
|
|
25809
|
+
...base,
|
|
25810
|
+
status: "pushed_feature_branch_needs_merge",
|
|
25811
|
+
needsConvergence: true,
|
|
25812
|
+
reason: "clean_non_default_branch",
|
|
25813
|
+
nextStep: `Review and merge branch '${branch}' into ${defaultBranch}; do not report the task as fully complete while it remains off main.`
|
|
25814
|
+
};
|
|
25815
|
+
}
|
|
25816
|
+
function applyInlineMeshBranchConvergence(mesh, node, status) {
|
|
25817
|
+
const git = readObjectRecord(status.git);
|
|
25818
|
+
if (Object.keys(git).length === 0 && !status.gitProbePending) return;
|
|
25819
|
+
const uncommittedChanges = countGitWorktreeChanges(git);
|
|
25820
|
+
status.isDirty = uncommittedChanges > 0;
|
|
25821
|
+
status.uncommittedChanges = uncommittedChanges;
|
|
25822
|
+
status.branchConvergence = buildInlineMeshBranchConvergence({ mesh, node, status });
|
|
25823
|
+
}
|
|
25824
|
+
function summarizeInlineMeshBranchConvergence(nodes) {
|
|
25825
|
+
const followUps = nodes.filter((node) => readObjectRecord(node.branchConvergence).needsConvergence === true).map((node) => {
|
|
25826
|
+
const convergence = readObjectRecord(node.branchConvergence);
|
|
25827
|
+
return {
|
|
25828
|
+
nodeId: node.nodeId,
|
|
25829
|
+
workspace: node.workspace,
|
|
25830
|
+
branch: convergence.branch,
|
|
25831
|
+
status: convergence.status,
|
|
25832
|
+
reason: convergence.reason,
|
|
25833
|
+
nextStep: convergence.nextStep
|
|
25834
|
+
};
|
|
25835
|
+
});
|
|
25836
|
+
return {
|
|
25837
|
+
needsFollowUp: followUps.length > 0,
|
|
25838
|
+
unresolvedCount: followUps.length,
|
|
25839
|
+
requiredFinalStates: ["merged_to_main", "pushed_feature_branch_needs_merge", "blocked_review", "cleanup_candidate", "not_mergeable"],
|
|
25840
|
+
followUps
|
|
25841
|
+
};
|
|
25842
|
+
}
|
|
25695
25843
|
function readCachedInlineMeshActiveSessions(node) {
|
|
25696
25844
|
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
25697
25845
|
const activeSession = readObjectRecord(cachedStatus.activeSession);
|
|
@@ -25772,7 +25920,7 @@ function finalizeMeshNodeStatus(args) {
|
|
|
25772
25920
|
async function probeRemoteMeshGitStatus(args) {
|
|
25773
25921
|
if (!args.dispatchMeshCommand) return null;
|
|
25774
25922
|
const remoteResult = await Promise.race([
|
|
25775
|
-
args.dispatchMeshCommand(args.daemonId, "git_status", { workspace: args.workspace }),
|
|
25923
|
+
args.dispatchMeshCommand(args.daemonId, "git_status", { workspace: args.workspace, refreshUpstream: true }),
|
|
25776
25924
|
new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), args.timeoutMs))
|
|
25777
25925
|
]);
|
|
25778
25926
|
const remoteGit = remoteResult?.status ?? remoteResult?.git ?? remoteResult;
|
|
@@ -26365,6 +26513,7 @@ var DaemonCommandRouter = class {
|
|
|
26365
26513
|
const nextStatus = { ...statusNode };
|
|
26366
26514
|
nextStatus.git = liveGit;
|
|
26367
26515
|
nextStatus.health = deriveMeshNodeHealthFromGit(liveGit);
|
|
26516
|
+
applyInlineMeshBranchConvergence(mesh, inlineNode, nextStatus);
|
|
26368
26517
|
nextStatus.launchReady = readBooleanValue(nextStatus.launchReady) ?? true;
|
|
26369
26518
|
const connection = readObjectRecord(nextStatus.connection);
|
|
26370
26519
|
const connectionState = readStringValue(connection.state);
|
|
@@ -26403,6 +26552,7 @@ var DaemonCommandRouter = class {
|
|
|
26403
26552
|
error: "Selected coordinator could not confirm direct mesh truth for every remote node yet."
|
|
26404
26553
|
} : {},
|
|
26405
26554
|
sourceOfTruth: nextSourceOfTruth,
|
|
26555
|
+
branchConvergenceSummary: summarizeInlineMeshBranchConvergence(nodes),
|
|
26406
26556
|
nodes
|
|
26407
26557
|
};
|
|
26408
26558
|
}
|
|
@@ -29137,11 +29287,13 @@ ${block2}`);
|
|
|
29137
29287
|
node,
|
|
29138
29288
|
pendingPeerGitProbe ? { skipGit: true, skipError: true, skipHealth: true } : void 0
|
|
29139
29289
|
)) {
|
|
29290
|
+
applyInlineMeshBranchConvergence(mesh, node, status);
|
|
29140
29291
|
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
|
|
29141
29292
|
nodeStatuses.push(status);
|
|
29142
29293
|
continue;
|
|
29143
29294
|
}
|
|
29144
29295
|
if (meshRecord?.source === "inline_cache" && !isSelfNode) {
|
|
29296
|
+
applyInlineMeshBranchConvergence(mesh, node, status);
|
|
29145
29297
|
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
|
|
29146
29298
|
nodeStatuses.push(status);
|
|
29147
29299
|
continue;
|
|
@@ -29167,6 +29319,7 @@ ${block2}`);
|
|
|
29167
29319
|
} else {
|
|
29168
29320
|
applyCachedInlineMeshNodeStatus(status, node);
|
|
29169
29321
|
}
|
|
29322
|
+
applyInlineMeshBranchConvergence(mesh, node, status);
|
|
29170
29323
|
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
|
|
29171
29324
|
nodeStatuses.push(status);
|
|
29172
29325
|
}
|
|
@@ -29202,6 +29355,7 @@ ${block2}`);
|
|
|
29202
29355
|
} : {},
|
|
29203
29356
|
historicalEvidenceOnly: ["recoveryHints", "ledger.summary", "queue.summary"]
|
|
29204
29357
|
},
|
|
29358
|
+
branchConvergenceSummary: summarizeInlineMeshBranchConvergence(nodeStatuses),
|
|
29205
29359
|
nodes: nodeStatuses,
|
|
29206
29360
|
queue: { tasks: queue, summary: queueSummary },
|
|
29207
29361
|
ledger: { entries: ledgerEntries, summary: ledgerSummary }
|