@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 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
- if (!git) return false;
25673
- return Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
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 }