@adhdev/daemon-core 0.9.82-rc.63 → 0.9.82-rc.64

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