@adhdev/daemon-core 0.9.82-rc.304 → 0.9.82-rc.305
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 +28 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +28 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/commands/router.ts +54 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adhdev/daemon-core",
|
|
3
|
-
"version": "0.9.82-rc.
|
|
3
|
+
"version": "0.9.82-rc.305",
|
|
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",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"author": "vilmire",
|
|
47
47
|
"license": "AGPL-3.0-or-later",
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@adhdev/mesh-shared": "0.9.82-rc.
|
|
49
|
+
"@adhdev/mesh-shared": "0.9.82-rc.305",
|
|
50
50
|
"@adhdev/session-host-core": "*",
|
|
51
51
|
"@agentclientprotocol/sdk": "^0.16.1",
|
|
52
52
|
"ajv": "^8.20.0",
|
package/src/commands/router.ts
CHANGED
|
@@ -1009,11 +1009,21 @@ async function hydrateInlineMeshDirectTruth(args: {
|
|
|
1009
1009
|
dispatchMeshCommand?: (daemonId: string, cmd: string, args: Record<string, unknown>) => Promise<unknown>;
|
|
1010
1010
|
statusInstanceId?: string;
|
|
1011
1011
|
localMachineId?: string;
|
|
1012
|
+
// Standing-state model: the default (non-refresh) bootstrap load must NOT
|
|
1013
|
+
// fan out a blocking git_status probe to every peer — a single slow
|
|
1014
|
+
// (TURN-relayed) peer would time out and mark the whole mesh unavailable,
|
|
1015
|
+
// blocking the graph. When false, a non-local node is satisfied from its
|
|
1016
|
+
// held standing git truth (lastGit / cachedStatus reflected via mesh
|
|
1017
|
+
// events) and is never pushed to unavailableNodeIds merely because no live
|
|
1018
|
+
// probe was attempted. Only an explicit refresh (probeRemotePeers=true)
|
|
1019
|
+
// performs the fan-out and classifies an unreachable peer as unavailable.
|
|
1020
|
+
probeRemotePeers: boolean;
|
|
1012
1021
|
}): Promise<{
|
|
1013
1022
|
directEvidenceCount: number;
|
|
1014
1023
|
localConfirmedCount: number;
|
|
1015
1024
|
peerAttemptedCount: number;
|
|
1016
1025
|
peerConfirmedCount: number;
|
|
1026
|
+
standingEvidenceCount: number;
|
|
1017
1027
|
unavailableNodeIds: string[];
|
|
1018
1028
|
}> {
|
|
1019
1029
|
const nodes = Array.isArray(args.mesh?.nodes) ? args.mesh.nodes : [];
|
|
@@ -1023,6 +1033,7 @@ async function hydrateInlineMeshDirectTruth(args: {
|
|
|
1023
1033
|
localConfirmedCount: 0,
|
|
1024
1034
|
peerAttemptedCount: 0,
|
|
1025
1035
|
peerConfirmedCount: 0,
|
|
1036
|
+
standingEvidenceCount: 0,
|
|
1026
1037
|
unavailableNodeIds: [],
|
|
1027
1038
|
};
|
|
1028
1039
|
}
|
|
@@ -1036,6 +1047,7 @@ async function hydrateInlineMeshDirectTruth(args: {
|
|
|
1036
1047
|
let localConfirmedCount = 0;
|
|
1037
1048
|
let peerAttemptedCount = 0;
|
|
1038
1049
|
let peerConfirmedCount = 0;
|
|
1050
|
+
let standingEvidenceCount = 0;
|
|
1039
1051
|
const unavailableNodeIds: string[] = [];
|
|
1040
1052
|
|
|
1041
1053
|
for (const [nodeIndex, node] of nodes.entries()) {
|
|
@@ -1066,6 +1078,25 @@ async function hydrateInlineMeshDirectTruth(args: {
|
|
|
1066
1078
|
}
|
|
1067
1079
|
}
|
|
1068
1080
|
|
|
1081
|
+
// Standing-state first: a non-local peer's held git truth (reflected
|
|
1082
|
+
// from its self-emitted mesh events into node.lastGit / cachedStatus)
|
|
1083
|
+
// counts as direct evidence without any probe. On the default load this
|
|
1084
|
+
// is the ONLY thing we consult — no fan-out, so one slow peer can't
|
|
1085
|
+
// block the bootstrap.
|
|
1086
|
+
const standingGit = buildInlineMeshTransitGitStatus(node);
|
|
1087
|
+
if (standingGit) {
|
|
1088
|
+
standingEvidenceCount += 1;
|
|
1089
|
+
continue;
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
if (!args.probeRemotePeers) {
|
|
1093
|
+
// Default (non-refresh) load: a peer with no held truth yet is left
|
|
1094
|
+
// pending (the per-node loop marks it gitProbePending and the graph
|
|
1095
|
+
// shows setup inventory for it). It is NOT unavailable — the graph
|
|
1096
|
+
// must still render. An explicit refresh will fan out and freshen it.
|
|
1097
|
+
continue;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1069
1100
|
if (!daemonId || !args.dispatchMeshCommand) {
|
|
1070
1101
|
if (!isSelfNode) unavailableNodeIds.push(nodeId);
|
|
1071
1102
|
continue;
|
|
@@ -1092,10 +1123,11 @@ async function hydrateInlineMeshDirectTruth(args: {
|
|
|
1092
1123
|
}
|
|
1093
1124
|
|
|
1094
1125
|
return {
|
|
1095
|
-
directEvidenceCount: localConfirmedCount + peerConfirmedCount,
|
|
1126
|
+
directEvidenceCount: localConfirmedCount + peerConfirmedCount + standingEvidenceCount,
|
|
1096
1127
|
localConfirmedCount,
|
|
1097
1128
|
peerAttemptedCount,
|
|
1098
1129
|
peerConfirmedCount,
|
|
1130
|
+
standingEvidenceCount,
|
|
1099
1131
|
unavailableNodeIds,
|
|
1100
1132
|
};
|
|
1101
1133
|
}
|
|
@@ -6504,12 +6536,16 @@ export class DaemonCommandRouter {
|
|
|
6504
6536
|
if (!meshRecord?.mesh) return { success: false, error: 'Mesh not found' };
|
|
6505
6537
|
|
|
6506
6538
|
const requireDirectPeerTruth = args?.requireDirectPeerTruth === true;
|
|
6539
|
+
// Only an explicit refresh fans out a blocking peer probe.
|
|
6540
|
+
// Default loads are satisfied from held standing-state git truth.
|
|
6541
|
+
const probeRemotePeers = args?.refresh === true || args?.forceRefresh === true;
|
|
6507
6542
|
const directTruth = await hydrateInlineMeshDirectTruth({
|
|
6508
6543
|
mesh: meshRecord.mesh,
|
|
6509
6544
|
meshSource: meshRecord.source,
|
|
6510
6545
|
dispatchMeshCommand: this.deps.dispatchMeshCommand,
|
|
6511
6546
|
statusInstanceId: this.deps.statusInstanceId,
|
|
6512
6547
|
localMachineId: loadConfig().machineId || '',
|
|
6548
|
+
probeRemotePeers,
|
|
6513
6549
|
});
|
|
6514
6550
|
const directTruthSatisfied = meshRecord.source !== 'inline_bootstrap' || directTruth.directEvidenceCount > 0;
|
|
6515
6551
|
const sourceOfTruth = {
|
|
@@ -8398,12 +8434,17 @@ export class DaemonCommandRouter {
|
|
|
8398
8434
|
dispatchMeshCommand: this.deps.dispatchMeshCommand,
|
|
8399
8435
|
statusInstanceId: this.deps.statusInstanceId,
|
|
8400
8436
|
localMachineId,
|
|
8437
|
+
// Standing-state model: only an explicit refresh fans
|
|
8438
|
+
// out a blocking peer git probe. Default loads return
|
|
8439
|
+
// held truth so one slow peer can't block the graph.
|
|
8440
|
+
probeRemotePeers: refreshRequested,
|
|
8401
8441
|
})
|
|
8402
8442
|
: {
|
|
8403
8443
|
directEvidenceCount: 0,
|
|
8404
8444
|
localConfirmedCount: 0,
|
|
8405
8445
|
peerAttemptedCount: 0,
|
|
8406
8446
|
peerConfirmedCount: 0,
|
|
8447
|
+
standingEvidenceCount: 0,
|
|
8407
8448
|
unavailableNodeIds: [] as string[],
|
|
8408
8449
|
};
|
|
8409
8450
|
// Default/cached loads may not attempt a remote peer probe yet; do not surface that as
|
|
@@ -8421,9 +8462,15 @@ export class DaemonCommandRouter {
|
|
|
8421
8462
|
&& mesh.nodes
|
|
8422
8463
|
.filter((node: any) => unavailableDirectTruthNodeIds.has(normalizeMeshNodeId(node) ?? ''))
|
|
8423
8464
|
.every((node: any) => node?.isLocalWorktree === true);
|
|
8465
|
+
// Default (non-refresh) loads never hard-fail: held
|
|
8466
|
+
// standing-state truth is returned and the graph renders
|
|
8467
|
+
// immediately. The hard mesh_direct_peer_truth_unavailable
|
|
8468
|
+
// failure is reserved for an explicit refresh that actually
|
|
8469
|
+
// attempted a peer probe and could not confirm any evidence.
|
|
8424
8470
|
const directTruthSatisfied = !requireDirectPeerTruth
|
|
8471
|
+
|| !refreshRequested
|
|
8425
8472
|
|| (effectiveDirectTruth.directEvidenceCount > 0 && (effectiveDirectTruth.unavailableNodeIds.length === 0 || unavailableNodesAreOnlyRemovedWorktrees));
|
|
8426
|
-
if (requireDirectPeerTruth && !directTruthSatisfied) {
|
|
8473
|
+
if (requireDirectPeerTruth && refreshRequested && !directTruthSatisfied) {
|
|
8427
8474
|
const failureResult = {
|
|
8428
8475
|
success: false,
|
|
8429
8476
|
code: 'mesh_direct_peer_truth_unavailable',
|
|
@@ -8588,7 +8635,11 @@ export class DaemonCommandRouter {
|
|
|
8588
8635
|
status.connection = buildLivePeerGitConnection(connection, refreshedAt);
|
|
8589
8636
|
}
|
|
8590
8637
|
remoteProbeApplied = true;
|
|
8591
|
-
} else if (!isSelfNode && daemonId && this.deps.dispatchMeshCommand && !directTruthUnavailableNodeIds.has(nodeId)) {
|
|
8638
|
+
} else if (refreshRequested && !isSelfNode && daemonId && this.deps.dispatchMeshCommand && !directTruthUnavailableNodeIds.has(nodeId)) {
|
|
8639
|
+
// Only an explicit refresh fans out a blocking
|
|
8640
|
+
// per-node git probe. On the default load a peer
|
|
8641
|
+
// with no held truth falls through to
|
|
8642
|
+
// gitProbePending below — the graph still renders.
|
|
8592
8643
|
try {
|
|
8593
8644
|
const remoteGit = await probeRemoteMeshGitStatus({
|
|
8594
8645
|
dispatchMeshCommand: this.deps.dispatchMeshCommand,
|