@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.mjs
CHANGED
|
@@ -25149,6 +25149,7 @@ function summarizeRepoMeshStatusDebug(status) {
|
|
|
25149
25149
|
meshId: readStringValue(status?.meshId, status?.mesh_id) ?? null,
|
|
25150
25150
|
refreshedAt: readStringValue(status?.refreshedAt, status?.refreshed_at) ?? null,
|
|
25151
25151
|
sourceOfTruth: status?.sourceOfTruth ?? null,
|
|
25152
|
+
branchConvergenceSummary: status?.branchConvergenceSummary ?? status?.branch_convergence_summary ?? null,
|
|
25152
25153
|
nodeCount: nodes.length,
|
|
25153
25154
|
nodes: nodes.map((node) => ({
|
|
25154
25155
|
nodeId: readStringValue(node?.nodeId, node?.id) ?? null,
|
|
@@ -25164,7 +25165,8 @@ function summarizeRepoMeshStatusDebug(status) {
|
|
|
25164
25165
|
} : null,
|
|
25165
25166
|
gitProbePending: node?.gitProbePending === true,
|
|
25166
25167
|
launchReady: node?.launchReady === true,
|
|
25167
|
-
git: summarizeRepoMeshDebugGit(node?.git)
|
|
25168
|
+
git: summarizeRepoMeshDebugGit(node?.git),
|
|
25169
|
+
branchConvergence: node?.branchConvergence ?? node?.branch_convergence ?? null
|
|
25168
25170
|
}))
|
|
25169
25171
|
};
|
|
25170
25172
|
}
|
|
@@ -25219,6 +25221,9 @@ function normalizeInlineMeshGitStatus(status, node, options) {
|
|
|
25219
25221
|
headCommit: readStringValue(status.headCommit) ?? null,
|
|
25220
25222
|
headMessage: readStringValue(status.headMessage) ?? null,
|
|
25221
25223
|
upstream: readStringValue(status.upstream) ?? null,
|
|
25224
|
+
upstreamStatus: readStringValue(status.upstreamStatus, status.upstream_status) ?? (readStringValue(status.upstream) ? "unchecked" : "no_upstream"),
|
|
25225
|
+
upstreamFetchedAt: readNumberValue(status.upstreamFetchedAt, status.upstream_fetched_at),
|
|
25226
|
+
upstreamFetchError: readStringValue(status.upstreamFetchError, status.upstream_fetch_error),
|
|
25222
25227
|
ahead: readNumberValue(status.ahead) ?? 0,
|
|
25223
25228
|
behind: readNumberValue(status.behind) ?? 0,
|
|
25224
25229
|
staged: readNumberValue(status.staged) ?? 0,
|
|
@@ -25417,8 +25422,11 @@ function reconcileInlineMeshCache(cached, incoming) {
|
|
|
25417
25422
|
};
|
|
25418
25423
|
}
|
|
25419
25424
|
function hasGitWorktreeChanges(git) {
|
|
25420
|
-
|
|
25421
|
-
|
|
25425
|
+
return countGitWorktreeChanges(git) > 0;
|
|
25426
|
+
}
|
|
25427
|
+
function countGitWorktreeChanges(git) {
|
|
25428
|
+
if (!git) return 0;
|
|
25429
|
+
return Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0);
|
|
25422
25430
|
}
|
|
25423
25431
|
function getGitSubmoduleDriftState(git) {
|
|
25424
25432
|
const submodules = Array.isArray(git?.submodules) ? git.submodules : [];
|
|
@@ -25440,6 +25448,146 @@ function deriveMeshNodeHealthFromGit(git) {
|
|
|
25440
25448
|
if (submoduleDrift.dirty || hasGitWorktreeChanges(git)) return "dirty";
|
|
25441
25449
|
return "online";
|
|
25442
25450
|
}
|
|
25451
|
+
function readMeshNodeLabel(status, node) {
|
|
25452
|
+
return readStringValue(status.nodeId, node?.id, node?.nodeId) ?? "unknown";
|
|
25453
|
+
}
|
|
25454
|
+
function buildInlineMeshBranchConvergence(args) {
|
|
25455
|
+
const git = readObjectRecord(args.status.git);
|
|
25456
|
+
const nodeLabel = readMeshNodeLabel(args.status, args.node);
|
|
25457
|
+
const defaultBranch = readStringValue(args.mesh?.defaultBranch) ?? "main";
|
|
25458
|
+
const branch = readStringValue(git.branch, args.node?.worktreeBranch) ?? null;
|
|
25459
|
+
const upstream = readStringValue(git.upstream) ?? null;
|
|
25460
|
+
const upstreamStatus = readStringValue(git.upstreamStatus, git.upstream_status) ?? (upstream ? "unchecked" : "no_upstream");
|
|
25461
|
+
const ahead = readNumberValue(git.ahead) ?? 0;
|
|
25462
|
+
const behind = readNumberValue(git.behind) ?? 0;
|
|
25463
|
+
const uncommittedChanges = countGitWorktreeChanges(git);
|
|
25464
|
+
const hasConflicts = readBooleanValue(git.hasConflicts) ?? (Array.isArray(git.conflictFiles) && git.conflictFiles.length > 0);
|
|
25465
|
+
const base = {
|
|
25466
|
+
defaultBranch,
|
|
25467
|
+
branch,
|
|
25468
|
+
upstream,
|
|
25469
|
+
upstreamStatus,
|
|
25470
|
+
ahead,
|
|
25471
|
+
behind,
|
|
25472
|
+
isWorktree: args.node?.isLocalWorktree === true || args.status.isLocalWorktree === true,
|
|
25473
|
+
isDefaultBranch: branch === defaultBranch
|
|
25474
|
+
};
|
|
25475
|
+
if (readBooleanValue(git.isGitRepo) !== true) {
|
|
25476
|
+
return {
|
|
25477
|
+
...base,
|
|
25478
|
+
status: "blocked_review",
|
|
25479
|
+
needsConvergence: true,
|
|
25480
|
+
reason: "git_status_unavailable",
|
|
25481
|
+
nextStep: `Resolve git status for node '${nodeLabel}' before marking the task complete.`
|
|
25482
|
+
};
|
|
25483
|
+
}
|
|
25484
|
+
if (!branch) {
|
|
25485
|
+
return {
|
|
25486
|
+
...base,
|
|
25487
|
+
status: "blocked_review",
|
|
25488
|
+
needsConvergence: true,
|
|
25489
|
+
reason: "branch_unknown",
|
|
25490
|
+
nextStep: `Inspect node '${nodeLabel}' git branch before deciding whether it is merged to ${defaultBranch}.`
|
|
25491
|
+
};
|
|
25492
|
+
}
|
|
25493
|
+
if (hasConflicts || uncommittedChanges > 0) {
|
|
25494
|
+
return {
|
|
25495
|
+
...base,
|
|
25496
|
+
status: "not_mergeable",
|
|
25497
|
+
needsConvergence: true,
|
|
25498
|
+
reason: hasConflicts ? "conflicts_present" : "dirty_workspace",
|
|
25499
|
+
nextStep: `Commit, checkpoint, or resolve node '${nodeLabel}' before any main convergence step.`
|
|
25500
|
+
};
|
|
25501
|
+
}
|
|
25502
|
+
if (branch === defaultBranch) {
|
|
25503
|
+
if (upstream && upstreamStatus !== "fresh") {
|
|
25504
|
+
return {
|
|
25505
|
+
...base,
|
|
25506
|
+
status: "blocked_review",
|
|
25507
|
+
needsConvergence: true,
|
|
25508
|
+
reason: "default_branch_upstream_unverified",
|
|
25509
|
+
nextStep: `Refresh ${defaultBranch}'s upstream refs or resolve the fetch failure before declaring convergence complete for node '${nodeLabel}'.`
|
|
25510
|
+
};
|
|
25511
|
+
}
|
|
25512
|
+
if (ahead > 0 || behind > 0) {
|
|
25513
|
+
return {
|
|
25514
|
+
...base,
|
|
25515
|
+
status: "blocked_review",
|
|
25516
|
+
needsConvergence: true,
|
|
25517
|
+
reason: "default_branch_not_even_with_upstream",
|
|
25518
|
+
nextStep: `Bring ${defaultBranch} even with its upstream before declaring convergence complete.`
|
|
25519
|
+
};
|
|
25520
|
+
}
|
|
25521
|
+
return {
|
|
25522
|
+
...base,
|
|
25523
|
+
status: "merged_to_main",
|
|
25524
|
+
needsConvergence: false,
|
|
25525
|
+
reason: "clean_default_branch",
|
|
25526
|
+
nextStep: null
|
|
25527
|
+
};
|
|
25528
|
+
}
|
|
25529
|
+
if (args.node?.isLocalWorktree === true || args.status.isLocalWorktree === true) {
|
|
25530
|
+
return {
|
|
25531
|
+
...base,
|
|
25532
|
+
status: "cleanup_candidate",
|
|
25533
|
+
needsConvergence: true,
|
|
25534
|
+
reason: "clean_non_default_worktree_branch",
|
|
25535
|
+
nextStep: `Run mesh_refine_node(node_id: "${nodeLabel}") or explicitly classify this worktree as blocked_review/not_mergeable before ending the task.`
|
|
25536
|
+
};
|
|
25537
|
+
}
|
|
25538
|
+
if (upstream && upstreamStatus !== "fresh") {
|
|
25539
|
+
return {
|
|
25540
|
+
...base,
|
|
25541
|
+
status: "blocked_review",
|
|
25542
|
+
needsConvergence: true,
|
|
25543
|
+
reason: "feature_branch_upstream_unverified",
|
|
25544
|
+
nextStep: `Refresh branch '${branch}' upstream refs or resolve the fetch failure before deciding whether it is ready to merge into ${defaultBranch}.`
|
|
25545
|
+
};
|
|
25546
|
+
}
|
|
25547
|
+
if (!upstream || ahead > 0 || behind > 0) {
|
|
25548
|
+
return {
|
|
25549
|
+
...base,
|
|
25550
|
+
status: "blocked_review",
|
|
25551
|
+
needsConvergence: true,
|
|
25552
|
+
reason: !upstream ? "feature_branch_missing_upstream" : "feature_branch_not_even_with_upstream",
|
|
25553
|
+
nextStep: `Push or reconcile branch '${branch}', then merge it into ${defaultBranch} or mark it not_mergeable with a reason.`
|
|
25554
|
+
};
|
|
25555
|
+
}
|
|
25556
|
+
return {
|
|
25557
|
+
...base,
|
|
25558
|
+
status: "pushed_feature_branch_needs_merge",
|
|
25559
|
+
needsConvergence: true,
|
|
25560
|
+
reason: "clean_non_default_branch",
|
|
25561
|
+
nextStep: `Review and merge branch '${branch}' into ${defaultBranch}; do not report the task as fully complete while it remains off main.`
|
|
25562
|
+
};
|
|
25563
|
+
}
|
|
25564
|
+
function applyInlineMeshBranchConvergence(mesh, node, status) {
|
|
25565
|
+
const git = readObjectRecord(status.git);
|
|
25566
|
+
if (Object.keys(git).length === 0 && !status.gitProbePending) return;
|
|
25567
|
+
const uncommittedChanges = countGitWorktreeChanges(git);
|
|
25568
|
+
status.isDirty = uncommittedChanges > 0;
|
|
25569
|
+
status.uncommittedChanges = uncommittedChanges;
|
|
25570
|
+
status.branchConvergence = buildInlineMeshBranchConvergence({ mesh, node, status });
|
|
25571
|
+
}
|
|
25572
|
+
function summarizeInlineMeshBranchConvergence(nodes) {
|
|
25573
|
+
const followUps = nodes.filter((node) => readObjectRecord(node.branchConvergence).needsConvergence === true).map((node) => {
|
|
25574
|
+
const convergence = readObjectRecord(node.branchConvergence);
|
|
25575
|
+
return {
|
|
25576
|
+
nodeId: node.nodeId,
|
|
25577
|
+
workspace: node.workspace,
|
|
25578
|
+
branch: convergence.branch,
|
|
25579
|
+
status: convergence.status,
|
|
25580
|
+
reason: convergence.reason,
|
|
25581
|
+
nextStep: convergence.nextStep
|
|
25582
|
+
};
|
|
25583
|
+
});
|
|
25584
|
+
return {
|
|
25585
|
+
needsFollowUp: followUps.length > 0,
|
|
25586
|
+
unresolvedCount: followUps.length,
|
|
25587
|
+
requiredFinalStates: ["merged_to_main", "pushed_feature_branch_needs_merge", "blocked_review", "cleanup_candidate", "not_mergeable"],
|
|
25588
|
+
followUps
|
|
25589
|
+
};
|
|
25590
|
+
}
|
|
25443
25591
|
function readCachedInlineMeshActiveSessions(node) {
|
|
25444
25592
|
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
25445
25593
|
const activeSession = readObjectRecord(cachedStatus.activeSession);
|
|
@@ -25520,7 +25668,7 @@ function finalizeMeshNodeStatus(args) {
|
|
|
25520
25668
|
async function probeRemoteMeshGitStatus(args) {
|
|
25521
25669
|
if (!args.dispatchMeshCommand) return null;
|
|
25522
25670
|
const remoteResult = await Promise.race([
|
|
25523
|
-
args.dispatchMeshCommand(args.daemonId, "git_status", { workspace: args.workspace }),
|
|
25671
|
+
args.dispatchMeshCommand(args.daemonId, "git_status", { workspace: args.workspace, refreshUpstream: true }),
|
|
25524
25672
|
new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), args.timeoutMs))
|
|
25525
25673
|
]);
|
|
25526
25674
|
const remoteGit = remoteResult?.status ?? remoteResult?.git ?? remoteResult;
|
|
@@ -26113,6 +26261,7 @@ var DaemonCommandRouter = class {
|
|
|
26113
26261
|
const nextStatus = { ...statusNode };
|
|
26114
26262
|
nextStatus.git = liveGit;
|
|
26115
26263
|
nextStatus.health = deriveMeshNodeHealthFromGit(liveGit);
|
|
26264
|
+
applyInlineMeshBranchConvergence(mesh, inlineNode, nextStatus);
|
|
26116
26265
|
nextStatus.launchReady = readBooleanValue(nextStatus.launchReady) ?? true;
|
|
26117
26266
|
const connection = readObjectRecord(nextStatus.connection);
|
|
26118
26267
|
const connectionState = readStringValue(connection.state);
|
|
@@ -26151,6 +26300,7 @@ var DaemonCommandRouter = class {
|
|
|
26151
26300
|
error: "Selected coordinator could not confirm direct mesh truth for every remote node yet."
|
|
26152
26301
|
} : {},
|
|
26153
26302
|
sourceOfTruth: nextSourceOfTruth,
|
|
26303
|
+
branchConvergenceSummary: summarizeInlineMeshBranchConvergence(nodes),
|
|
26154
26304
|
nodes
|
|
26155
26305
|
};
|
|
26156
26306
|
}
|
|
@@ -28885,11 +29035,13 @@ ${block2}`);
|
|
|
28885
29035
|
node,
|
|
28886
29036
|
pendingPeerGitProbe ? { skipGit: true, skipError: true, skipHealth: true } : void 0
|
|
28887
29037
|
)) {
|
|
29038
|
+
applyInlineMeshBranchConvergence(mesh, node, status);
|
|
28888
29039
|
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
|
|
28889
29040
|
nodeStatuses.push(status);
|
|
28890
29041
|
continue;
|
|
28891
29042
|
}
|
|
28892
29043
|
if (meshRecord?.source === "inline_cache" && !isSelfNode) {
|
|
29044
|
+
applyInlineMeshBranchConvergence(mesh, node, status);
|
|
28893
29045
|
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
|
|
28894
29046
|
nodeStatuses.push(status);
|
|
28895
29047
|
continue;
|
|
@@ -28915,6 +29067,7 @@ ${block2}`);
|
|
|
28915
29067
|
} else {
|
|
28916
29068
|
applyCachedInlineMeshNodeStatus(status, node);
|
|
28917
29069
|
}
|
|
29070
|
+
applyInlineMeshBranchConvergence(mesh, node, status);
|
|
28918
29071
|
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
|
|
28919
29072
|
nodeStatuses.push(status);
|
|
28920
29073
|
}
|
|
@@ -28950,6 +29103,7 @@ ${block2}`);
|
|
|
28950
29103
|
} : {},
|
|
28951
29104
|
historicalEvidenceOnly: ["recoveryHints", "ledger.summary", "queue.summary"]
|
|
28952
29105
|
},
|
|
29106
|
+
branchConvergenceSummary: summarizeInlineMeshBranchConvergence(nodeStatuses),
|
|
28953
29107
|
nodes: nodeStatuses,
|
|
28954
29108
|
queue: { tasks: queue, summary: queueSummary },
|
|
28955
29109
|
ledger: { entries: ledgerEntries, summary: ledgerSummary }
|