@adhdev/daemon-core 0.9.82-rc.44 → 0.9.82-rc.46

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.9.82-rc.44",
3
+ "version": "0.9.82-rc.46",
4
4
  "description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -263,16 +263,12 @@ function buildInlineMeshTransitGitStatus(node: any): Record<string, unknown> | u
263
263
  const probeGitResult = readObjectRecord(probeGit.result);
264
264
  const probeDirectStatus = readObjectRecord(probeGit.status);
265
265
  const probeNestedStatus = readObjectRecord(probeGitResult.status);
266
- const status = Object.keys(directStatus).length
267
- ? directStatus
268
- : Object.keys(nestedStatus).length
269
- ? nestedStatus
270
- : Object.keys(probeDirectStatus).length
271
- ? probeDirectStatus
272
- : Object.keys(probeNestedStatus).length
273
- ? probeNestedStatus
274
- : {};
275
- return normalizeInlineMeshGitStatus(status, node, { lastCheckedAt: Date.now() });
266
+ const candidates = [directStatus, nestedStatus, probeDirectStatus, probeNestedStatus];
267
+ for (const status of candidates) {
268
+ const normalized = normalizeInlineMeshGitStatus(status, node, { lastCheckedAt: Date.now() });
269
+ if (normalized) return normalized;
270
+ }
271
+ return undefined;
276
272
  }
277
273
 
278
274
  function recordInlineMeshDirectGitTruth(
@@ -1445,10 +1441,73 @@ export class DaemonCommandRouter {
1445
1441
  return JSON.parse(JSON.stringify(value)) as T;
1446
1442
  }
1447
1443
 
1448
- private getCachedAggregateMeshStatus(meshId: string): any | null {
1444
+ private hydrateCachedAggregateMeshStatusFromInline(snapshot: any, mesh: any, options?: { requireDirectPeerTruth?: boolean }): any {
1445
+ if (!mesh || typeof mesh !== 'object' || !Array.isArray(mesh.nodes) || !Array.isArray(snapshot?.nodes)) return snapshot;
1446
+ const inlineNodesById = new Map<string, any>();
1447
+ for (const node of mesh.nodes) {
1448
+ const nodeId = readInlineMeshNodeId(node);
1449
+ if (nodeId) inlineNodesById.set(nodeId, node);
1450
+ }
1451
+ if (!inlineNodesById.size) return snapshot;
1452
+
1453
+ let changed = false;
1454
+ const unavailableNodeIds = new Set<string>();
1455
+ const sourceOfTruth = readObjectRecord(snapshot.sourceOfTruth);
1456
+ const directPeerTruth = readObjectRecord(sourceOfTruth.directPeerTruth);
1457
+ for (const entry of Array.isArray(directPeerTruth.unavailableNodeIds) ? directPeerTruth.unavailableNodeIds : []) {
1458
+ const nodeId = readStringValue(entry);
1459
+ if (nodeId) unavailableNodeIds.add(nodeId);
1460
+ }
1461
+
1462
+ const nodes = snapshot.nodes.map((statusNode: any) => {
1463
+ const nodeId = readStringValue(statusNode?.nodeId, statusNode?.id);
1464
+ const inlineNode = nodeId ? inlineNodesById.get(nodeId) : undefined;
1465
+ if (!inlineNode) return statusNode;
1466
+ const liveGit = buildInlineMeshTransitGitStatus(inlineNode);
1467
+ if (!liveGit) return statusNode;
1468
+ const nextStatus = { ...statusNode };
1469
+ nextStatus.git = liveGit;
1470
+ nextStatus.health = deriveMeshNodeHealthFromGit(liveGit);
1471
+ delete nextStatus.gitProbePending;
1472
+ if (readStringValue(nextStatus.error) === 'waiting for live peer git snapshot') delete nextStatus.error;
1473
+ if (!readStringValue(nextStatus.machineStatus)) nextStatus.machineStatus = 'online';
1474
+ if (nodeId) unavailableNodeIds.delete(nodeId);
1475
+ changed = true;
1476
+ return nextStatus;
1477
+ });
1478
+
1479
+ if (!changed && !(options?.requireDirectPeerTruth && unavailableNodeIds.size > 0)) return snapshot;
1480
+ const nextSourceOfTruth = {
1481
+ ...sourceOfTruth,
1482
+ ...(Object.keys(directPeerTruth).length ? {
1483
+ directPeerTruth: {
1484
+ ...directPeerTruth,
1485
+ satisfied: options?.requireDirectPeerTruth === true ? unavailableNodeIds.size === 0 : directPeerTruth.satisfied,
1486
+ unavailableNodeIds: [...unavailableNodeIds],
1487
+ },
1488
+ ...(options?.requireDirectPeerTruth === true ? {
1489
+ coordinatorOwnsLiveTruth: unavailableNodeIds.size === 0,
1490
+ currentStatus: unavailableNodeIds.size === 0 ? 'live_git_and_session_probes' : 'direct_peer_truth_unavailable',
1491
+ } : {}),
1492
+ } : {}),
1493
+ };
1494
+ return {
1495
+ ...snapshot,
1496
+ ...(options?.requireDirectPeerTruth === true && unavailableNodeIds.size > 0 ? {
1497
+ success: false,
1498
+ code: 'mesh_direct_peer_truth_unavailable',
1499
+ error: 'Selected coordinator could not confirm direct mesh truth for every remote node yet.',
1500
+ } : {}),
1501
+ sourceOfTruth: nextSourceOfTruth,
1502
+ nodes,
1503
+ };
1504
+ }
1505
+
1506
+ private getCachedAggregateMeshStatus(meshId: string, mesh?: any, options?: { requireDirectPeerTruth?: boolean }): any | null {
1449
1507
  const cached = this.aggregateMeshStatusCache.get(meshId);
1450
1508
  if (!cached?.snapshot || cached.snapshot.success !== true || !Array.isArray(cached.snapshot.nodes)) return null;
1451
- const snapshot = this.cloneJsonValue(cached.snapshot);
1509
+ let snapshot = this.cloneJsonValue(cached.snapshot);
1510
+ snapshot = this.hydrateCachedAggregateMeshStatusFromInline(snapshot, mesh, options);
1452
1511
  const ageMs = Math.max(0, Date.now() - cached.builtAt);
1453
1512
  const sourceOfTruth = snapshot.sourceOfTruth && typeof snapshot.sourceOfTruth === 'object'
1454
1513
  ? snapshot.sourceOfTruth
@@ -1522,7 +1581,14 @@ export class DaemonCommandRouter {
1522
1581
  const preferInline = options?.preferInline === true;
1523
1582
  if (preferInline) {
1524
1583
  const cached = this.getCachedInlineMesh(meshId);
1525
- if (cached) return { mesh: cached, inline: true, source: 'inline_cache' };
1584
+ if (cached) {
1585
+ if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
1586
+ const merged = reconcileInlineMeshCache(cached, inlineMesh as any);
1587
+ this.inlineMeshCache.set(meshId, sanitizeInlineMesh(merged));
1588
+ return { mesh: merged, inline: true, source: 'inline_cache' };
1589
+ }
1590
+ return { mesh: cached, inline: true, source: 'inline_cache' };
1591
+ }
1526
1592
  if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
1527
1593
  this.warmInlineMeshCache(meshId, inlineMesh);
1528
1594
  return { mesh: inlineMesh, inline: true, source: 'inline_bootstrap' };
@@ -3794,7 +3860,7 @@ export class DaemonCommandRouter {
3794
3860
 
3795
3861
  const refreshRequested = args?.refresh === true || args?.forceRefresh === true;
3796
3862
  if (!refreshRequested) {
3797
- const cachedStatus = this.getCachedAggregateMeshStatus(meshId);
3863
+ const cachedStatus = this.getCachedAggregateMeshStatus(meshId, mesh, { requireDirectPeerTruth: args?.requireDirectPeerTruth === true });
3798
3864
  if (cachedStatus) {
3799
3865
  logRepoMeshStatusDebug('return_cached', {
3800
3866
  meshId,
@@ -3836,7 +3902,17 @@ export class DaemonCommandRouter {
3836
3902
  peerConfirmedCount: 0,
3837
3903
  unavailableNodeIds: [] as string[],
3838
3904
  };
3839
- const directTruthSatisfied = meshRecord.source !== 'inline_bootstrap' || directTruth.directEvidenceCount > 0;
3905
+ // Default/cached loads may not attempt a remote peer probe yet; do not surface that as
3906
+ // a direct mesh truth failure until an explicit probe attempt actually fails.
3907
+ const passivePeerTruthNotAttempted = requireDirectPeerTruth
3908
+ && !refreshRequested
3909
+ && directTruth.directEvidenceCount > 0
3910
+ && directTruth.peerAttemptedCount === 0;
3911
+ const effectiveDirectTruth = passivePeerTruthNotAttempted
3912
+ ? { ...directTruth, unavailableNodeIds: [] as string[] }
3913
+ : directTruth;
3914
+ const directTruthSatisfied = !requireDirectPeerTruth
3915
+ || (effectiveDirectTruth.directEvidenceCount > 0 && effectiveDirectTruth.unavailableNodeIds.length === 0);
3840
3916
  if (requireDirectPeerTruth && !directTruthSatisfied) {
3841
3917
  const failureResult = {
3842
3918
  success: false,
@@ -3870,7 +3946,7 @@ export class DaemonCommandRouter {
3870
3946
  });
3871
3947
  return failureResult;
3872
3948
  }
3873
- const directTruthUnavailableNodeIds = new Set(directTruth.unavailableNodeIds);
3949
+ const directTruthUnavailableNodeIds = new Set(effectiveDirectTruth.unavailableNodeIds);
3874
3950
  const selectedCoordinatorNodeId = readStringValue(
3875
3951
  mesh.coordinator?.preferredNodeId,
3876
3952
  (mesh.nodes?.[0] as any)?.id,
@@ -4091,11 +4167,11 @@ export class DaemonCommandRouter {
4091
4167
  directPeerTruth: {
4092
4168
  required: true,
4093
4169
  satisfied: directTruthSatisfied,
4094
- directEvidenceCount: directTruth.directEvidenceCount,
4095
- localConfirmedCount: directTruth.localConfirmedCount,
4096
- peerAttemptedCount: directTruth.peerAttemptedCount,
4097
- peerConfirmedCount: directTruth.peerConfirmedCount,
4098
- unavailableNodeIds: directTruth.unavailableNodeIds,
4170
+ directEvidenceCount: effectiveDirectTruth.directEvidenceCount,
4171
+ localConfirmedCount: effectiveDirectTruth.localConfirmedCount,
4172
+ peerAttemptedCount: effectiveDirectTruth.peerAttemptedCount,
4173
+ peerConfirmedCount: effectiveDirectTruth.peerConfirmedCount,
4174
+ unavailableNodeIds: effectiveDirectTruth.unavailableNodeIds,
4099
4175
  },
4100
4176
  } : {}),
4101
4177
  historicalEvidenceOnly: ['recoveryHints', 'ledger.summary', 'queue.summary'],