@adhdev/daemon-core 0.9.82-rc.442 → 0.9.82-rc.443
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/commands/high-family/types.d.ts +4 -0
- package/dist/commands/router.d.ts +4 -0
- package/dist/index.js +221 -45
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +221 -45
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-node-identity.d.ts +15 -0
- package/dist/mesh/mesh-reconcile-loop.d.ts +15 -1
- package/dist/providers/chat-message-normalization.d.ts +1 -0
- package/dist/providers/cli-provider-instance.d.ts +1 -0
- package/package.json +2 -2
- package/src/commands/chat-commands-read.ts +41 -0
- package/src/commands/high-family/mesh-events.ts +11 -2
- package/src/commands/high-family/mesh-status.ts +102 -9
- package/src/commands/high-family/types.ts +5 -1
- package/src/commands/router.ts +19 -2
- package/src/mesh/mesh-node-identity.ts +106 -18
- package/src/mesh/mesh-reconcile-loop.ts +22 -1
- package/src/providers/chat-message-normalization.ts +1 -1
- package/src/providers/cli-provider-instance.ts +95 -8
package/dist/index.mjs
CHANGED
|
@@ -404,10 +404,10 @@ function readInjected(value) {
|
|
|
404
404
|
}
|
|
405
405
|
function getDaemonBuildInfo() {
|
|
406
406
|
if (cached) return cached;
|
|
407
|
-
const commit = readInjected(true ? "
|
|
408
|
-
const commitShort = readInjected(true ? "
|
|
409
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
410
|
-
const builtAt = readInjected(true ? "2026-07-
|
|
407
|
+
const commit = readInjected(true ? "21c6fe269d621db0b4841be14c111d4d656d6996" : void 0) ?? "unknown";
|
|
408
|
+
const commitShort = readInjected(true ? "21c6fe26" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
409
|
+
const version = readInjected(true ? "0.9.82-rc.443" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
410
|
+
const builtAt = readInjected(true ? "2026-07-01T10:41:15.424Z" : void 0);
|
|
411
411
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
412
412
|
return cached;
|
|
413
413
|
}
|
|
@@ -17195,7 +17195,7 @@ function resolveCoordinatorDrainDeliverability(components, meshId) {
|
|
|
17195
17195
|
holdForReconcile: !hasIdle
|
|
17196
17196
|
};
|
|
17197
17197
|
}
|
|
17198
|
-
function shouldHoldPendingDrainForBusyLocalCoordinator(components, meshId, requestedCoordinatorDaemonId) {
|
|
17198
|
+
function shouldHoldPendingDrainForBusyLocalCoordinator(components, meshId, requestedCoordinatorDaemonId, callerIsSelfCoordinatorInboxRead) {
|
|
17199
17199
|
if (!meshId) return false;
|
|
17200
17200
|
const deliverability = resolveCoordinatorDrainDeliverability(components, meshId);
|
|
17201
17201
|
if (!deliverability.holdForReconcile) return false;
|
|
@@ -17205,7 +17205,10 @@ function shouldHoldPendingDrainForBusyLocalCoordinator(components, meshId, reque
|
|
|
17205
17205
|
readNonEmptyString2(components.statusInstanceId),
|
|
17206
17206
|
readNonEmptyString2(loadConfig().machineId)
|
|
17207
17207
|
]);
|
|
17208
|
-
|
|
17208
|
+
const targetsLocalCoordinator = localIds.some((id) => daemonIdsEquivalent(id, requested));
|
|
17209
|
+
if (!targetsLocalCoordinator) return false;
|
|
17210
|
+
if (callerIsSelfCoordinatorInboxRead) return false;
|
|
17211
|
+
return true;
|
|
17209
17212
|
}
|
|
17210
17213
|
function injectPendingIntoCoordinator(coordinator, pending) {
|
|
17211
17214
|
if (!coordinator) return;
|
|
@@ -32038,6 +32041,26 @@ async function handleReadChat(h, args) {
|
|
|
32038
32041
|
ptyStatusApprovalOnly: false
|
|
32039
32042
|
});
|
|
32040
32043
|
if (supportsNative && !decision.nativeSelected) {
|
|
32044
|
+
if (safeMapping && historyMessages.length > 0) {
|
|
32045
|
+
LOG.debug("Command", `[read_chat] native-only content preserved despite pty-parser selection target=${String(args?.targetSessionId || "")} provider=${agentStr} rows=${historyMessages.length} cause=${decision.decision.transition.cause}`);
|
|
32046
|
+
return buildReadChatCommandResult({
|
|
32047
|
+
messages: historyMessages,
|
|
32048
|
+
status: "idle",
|
|
32049
|
+
messageSource: {
|
|
32050
|
+
...decision.messageSource,
|
|
32051
|
+
nativeOnlyContentPreserved: true,
|
|
32052
|
+
returnedMessageCount: historyMessages.length
|
|
32053
|
+
},
|
|
32054
|
+
transcriptProvenance: {
|
|
32055
|
+
...decision.messageSource,
|
|
32056
|
+
nativeOnlyContentPreserved: true
|
|
32057
|
+
},
|
|
32058
|
+
...typeof history?.title === "string" ? { title: history.title } : {},
|
|
32059
|
+
...historyProviderSessionId ? { providerSessionId: historyProviderSessionId } : {},
|
|
32060
|
+
...provider?.historyBehavior?.transcriptAuthority === "provider" || provider?.historyBehavior?.transcriptAuthority === "daemon" ? { transcriptAuthority: (provider?.historyBehavior).transcriptAuthority } : {},
|
|
32061
|
+
coverage: "tail"
|
|
32062
|
+
}, args, h);
|
|
32063
|
+
}
|
|
32041
32064
|
LOG.debug("Command", `[read_chat] soft pending: no live adapter and native history not safely mappable target=${String(args?.targetSessionId || "")} provider=${agentStr} reason=native_history_not_safely_available`);
|
|
32042
32065
|
return {
|
|
32043
32066
|
success: true,
|
|
@@ -40639,6 +40662,15 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
40639
40662
|
// first sets it; the other becomes a no-op.
|
|
40640
40663
|
agentReadyEmitted = false;
|
|
40641
40664
|
generatingStartedAt = 0;
|
|
40665
|
+
// FALSE-IDLE continuity epoch: monotonically bumped on EVERY entry into a busy
|
|
40666
|
+
// phase (→generating or →waiting_approval). The completedDebouncePending snapshots
|
|
40667
|
+
// this value at arm time (busyEpochAtArm); the flush guard requires it UNCHANGED
|
|
40668
|
+
// — proving the session did not re-enter a busy phase (a momentary busy→idle blip
|
|
40669
|
+
// in an inter-approval valley) between arming the debounce and flushing it. A
|
|
40670
|
+
// single point-sample of status at flush time cannot see a generating phase that
|
|
40671
|
+
// opened AND closed within the settle window; the epoch can. See
|
|
40672
|
+
// flushCompletedDebounceIfFinalized.
|
|
40673
|
+
busyEpoch = 0;
|
|
40642
40674
|
// GENERATING-BOUNDARY (R4b): the per-turn taskId for which a startup-grace
|
|
40643
40675
|
// started+completed pair was already synthesized. Both fast-collapse callers
|
|
40644
40676
|
// (starting→idle transition AND the idle-stayed no-status-change poll) route
|
|
@@ -41305,13 +41337,17 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
41305
41337
|
}
|
|
41306
41338
|
this.applyProviderResponse(parsed.payload, { phase: "immediate" });
|
|
41307
41339
|
}
|
|
41308
|
-
completionHasFinalAssistantMessage(messages) {
|
|
41340
|
+
completionHasFinalAssistantMessage(messages, turnStartedAt) {
|
|
41309
41341
|
const visibleMessages = (Array.isArray(messages) ? messages : []).filter((message) => isUserFacingChatMessage(message));
|
|
41310
41342
|
const lastVisible = visibleMessages[visibleMessages.length - 1];
|
|
41311
41343
|
const role = typeof lastVisible?.role === "string" ? lastVisible.role.trim().toLowerCase() : "";
|
|
41312
41344
|
const content = lastVisible ? flattenContent(lastVisible.content).trim() : "";
|
|
41313
41345
|
if (role !== "assistant" || !content) return false;
|
|
41314
41346
|
if (looksLikeActiveApprovalPromptText(content)) return false;
|
|
41347
|
+
if (typeof turnStartedAt === "number" && Number.isFinite(turnStartedAt) && turnStartedAt > 0) {
|
|
41348
|
+
const ts2 = readChatMessageTimestampMs(lastVisible);
|
|
41349
|
+
if (typeof ts2 === "number" && ts2 < turnStartedAt) return false;
|
|
41350
|
+
}
|
|
41315
41351
|
return true;
|
|
41316
41352
|
}
|
|
41317
41353
|
buildExternalTranscriptProbe(messages, sourcePath, sourceMtimeMs) {
|
|
@@ -41374,8 +41410,8 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
41374
41410
|
);
|
|
41375
41411
|
return restoredHistory.messages;
|
|
41376
41412
|
}
|
|
41377
|
-
completionFinalAssistantEvidence(parsedMessages) {
|
|
41378
|
-
if (this.completionHasFinalAssistantMessage(parsedMessages)) {
|
|
41413
|
+
completionFinalAssistantEvidence(parsedMessages, turnStartedAt) {
|
|
41414
|
+
if (this.completionHasFinalAssistantMessage(parsedMessages, turnStartedAt)) {
|
|
41379
41415
|
return {
|
|
41380
41416
|
present: true,
|
|
41381
41417
|
messages: Array.isArray(parsedMessages) ? parsedMessages : [],
|
|
@@ -41385,7 +41421,7 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
41385
41421
|
const externalMessages = this.readExternalCompletionMessages();
|
|
41386
41422
|
if (externalMessages) {
|
|
41387
41423
|
return {
|
|
41388
|
-
present: this.completionHasFinalAssistantMessage(externalMessages),
|
|
41424
|
+
present: this.completionHasFinalAssistantMessage(externalMessages, turnStartedAt),
|
|
41389
41425
|
messages: externalMessages,
|
|
41390
41426
|
source: "external-native"
|
|
41391
41427
|
};
|
|
@@ -41398,8 +41434,9 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
41398
41434
|
}
|
|
41399
41435
|
completionFinalSummary(parsedMessages, turnStartedAt) {
|
|
41400
41436
|
const adapterOwnsMessagesElsewhere = this.adapter?.chatMessagesOwnedExternally === true;
|
|
41401
|
-
const parsedSummary =
|
|
41402
|
-
this.completionHasFinalAssistantMessage(parsedMessages) ? Array.isArray(parsedMessages) ? parsedMessages : [] : []
|
|
41437
|
+
const parsedSummary = extractFinalSummaryFromMessagesAfter(
|
|
41438
|
+
this.completionHasFinalAssistantMessage(parsedMessages, turnStartedAt) ? Array.isArray(parsedMessages) ? parsedMessages : [] : [],
|
|
41439
|
+
turnStartedAt
|
|
41403
41440
|
);
|
|
41404
41441
|
if (adapterOwnsMessagesElsewhere) {
|
|
41405
41442
|
const externalMessages = this.readExternalCompletionMessages();
|
|
@@ -41504,7 +41541,7 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
41504
41541
|
}
|
|
41505
41542
|
if (parsed?.activeModal || parsed?.modal) return { reason: "parsed_modal_active", terminal: true };
|
|
41506
41543
|
const adapterOwnsMessagesElsewhere = this.adapter?.chatMessagesOwnedExternally === true;
|
|
41507
|
-
const finalAssistantEvidence = this.completionFinalAssistantEvidence(parsed?.messages);
|
|
41544
|
+
const finalAssistantEvidence = this.completionFinalAssistantEvidence(parsed?.messages, pending.turnStartedAt);
|
|
41508
41545
|
const allowMissingAssistantTimeout = !!(this.settings.meshNodeFor || this.settings.meshActiveTaskId || this.settings.launchedByCoordinator);
|
|
41509
41546
|
LOG.debug("CLI", `[${this.type}] finalAssistantEvidence: present=${finalAssistantEvidence.present} source=${finalAssistantEvidence.source} adapterOwnsMessagesElsewhere=${adapterOwnsMessagesElsewhere} parsedStatus=${parsedStatus}`);
|
|
41510
41547
|
if (!finalAssistantEvidence.present) {
|
|
@@ -41645,6 +41682,19 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
41645
41682
|
this.completedDebounceTimer = null;
|
|
41646
41683
|
return;
|
|
41647
41684
|
}
|
|
41685
|
+
if (typeof pending.busyEpochAtArm === "number" && this.busyEpoch !== pending.busyEpochAtArm) {
|
|
41686
|
+
LOG.info("CLI", `[${this.type}] cancelled pending completed (busy re-entry during settle: epoch ${pending.busyEpochAtArm}\u2192${this.busyEpoch})`);
|
|
41687
|
+
this.completedDebouncePending = null;
|
|
41688
|
+
this.completedDebounceTimer = null;
|
|
41689
|
+
return;
|
|
41690
|
+
}
|
|
41691
|
+
const latestOutputAt = typeof latestStatus?.lastOutputAt === "number" ? latestStatus.lastOutputAt : void 0;
|
|
41692
|
+
if (typeof pending.lastOutputAtArm === "number" && typeof latestOutputAt === "number" && latestOutputAt > pending.lastOutputAtArm) {
|
|
41693
|
+
LOG.info("CLI", `[${this.type}] cancelled pending completed (new PTY output during settle: ${pending.lastOutputAtArm}\u2192${latestOutputAt})`);
|
|
41694
|
+
this.completedDebouncePending = null;
|
|
41695
|
+
this.completedDebounceTimer = null;
|
|
41696
|
+
return;
|
|
41697
|
+
}
|
|
41648
41698
|
const block2 = this.getCompletedFinalizationBlock(latestVisibleStatus, pending);
|
|
41649
41699
|
if (block2) {
|
|
41650
41700
|
const blockReason = block2.reason;
|
|
@@ -41947,6 +41997,7 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
41947
41997
|
this.completedDebouncePending = null;
|
|
41948
41998
|
}
|
|
41949
41999
|
if (!this.generatingStartedAt) this.generatingStartedAt = now;
|
|
42000
|
+
this.busyEpoch++;
|
|
41950
42001
|
if (this.generatingDebounceTimer) clearTimeout(this.generatingDebounceTimer);
|
|
41951
42002
|
this.generatingDebouncePending = { chatTitle, timestamp: now };
|
|
41952
42003
|
this.generatingDebounceTimer = setTimeout(() => {
|
|
@@ -41972,6 +42023,7 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
41972
42023
|
}
|
|
41973
42024
|
this.completedDebouncePending = null;
|
|
41974
42025
|
if (!this.generatingStartedAt) this.generatingStartedAt = now;
|
|
42026
|
+
this.busyEpoch++;
|
|
41975
42027
|
const modal = adapterStatus.activeModal;
|
|
41976
42028
|
LOG.info("CLI", `[${this.type}] approval modal: "${modal?.message?.slice(0, 80) ?? "none"}"`);
|
|
41977
42029
|
const approvalEntrySeq = typeof adapterStatus?.approvalEntrySeq === "number" ? adapterStatus.approvalEntrySeq : 0;
|
|
@@ -42070,7 +42122,13 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
42070
42122
|
const engineTurnStart = typeof this.adapter?.currentTurnStartedAt === "number" && Number.isFinite(this.adapter.currentTurnStartedAt) ? this.adapter.currentTurnStartedAt : 0;
|
|
42071
42123
|
const turnStartedAt = engineTurnStart || this.generatingStartedAt || 0;
|
|
42072
42124
|
return turnStartedAt ? { turnStartedAt } : {};
|
|
42073
|
-
})()
|
|
42125
|
+
})(),
|
|
42126
|
+
// FALSE-IDLE continuity: snapshot the busy epoch + raw PTY output
|
|
42127
|
+
// clock at arm time so the flush guard can prove the session stayed
|
|
42128
|
+
// continuously idle (no busy re-entry, no new PTY output) through the
|
|
42129
|
+
// settle window rather than merely reading 'idle' once at flush.
|
|
42130
|
+
busyEpochAtArm: this.busyEpoch,
|
|
42131
|
+
...typeof adapterStatus?.lastOutputAt === "number" && Number.isFinite(adapterStatus.lastOutputAt) ? { lastOutputAtArm: adapterStatus.lastOutputAt } : {}
|
|
42074
42132
|
};
|
|
42075
42133
|
const ownsExternalHistory = !!this.adapter?.chatMessagesOwnedExternally;
|
|
42076
42134
|
const meshWorkerSession = this.isMeshWorkerSession();
|
|
@@ -50883,12 +50941,13 @@ var meshEventsHandlers = {
|
|
|
50883
50941
|
get_pending_mesh_events: async (ctx, args) => {
|
|
50884
50942
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
50885
50943
|
const coordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : void 0;
|
|
50944
|
+
const selfCoordinatorInboxRead = args?.selfCoordinatorInboxRead === true;
|
|
50886
50945
|
const hasLiveCliCoordinator = meshId ? resolveCoordinatorDrainDeliverability(ctx.deps, meshId).hasLiveCliCoordinator : false;
|
|
50887
|
-
if (meshId && shouldHoldPendingDrainForBusyLocalCoordinator(ctx.deps, meshId, coordinatorDaemonId)) {
|
|
50946
|
+
if (meshId && shouldHoldPendingDrainForBusyLocalCoordinator(ctx.deps, meshId, coordinatorDaemonId, selfCoordinatorInboxRead)) {
|
|
50888
50947
|
return { success: true, events: [], heldForBusyLocalCoordinator: true, hasLiveCliCoordinator };
|
|
50889
50948
|
}
|
|
50890
50949
|
const events = drainPendingMeshCoordinatorEvents(meshId || void 0, coordinatorDaemonId);
|
|
50891
|
-
return { success: true, events, hasLiveCliCoordinator };
|
|
50950
|
+
return { success: true, events, hasLiveCliCoordinator, ...selfCoordinatorInboxRead ? { surfacedForSelfCoordinator: true } : {} };
|
|
50892
50951
|
},
|
|
50893
50952
|
interactive_prompt_response: async (ctx, args) => {
|
|
50894
50953
|
const sessionId = typeof args?.targetSessionId === "string" && args.targetSessionId.trim() ? args.targetSessionId.trim() : typeof args?.sessionId === "string" && args.sessionId.trim() ? args.sessionId.trim() : "";
|
|
@@ -51526,6 +51585,7 @@ var meshStatusHandlers = {
|
|
|
51526
51585
|
mesh_status: async (ctx, args) => {
|
|
51527
51586
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
51528
51587
|
if (!meshId) return { success: false, error: "meshId required" };
|
|
51588
|
+
const startedAtMs = Date.now();
|
|
51529
51589
|
try {
|
|
51530
51590
|
const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
51531
51591
|
const mesh = meshRecord?.mesh;
|
|
@@ -51543,10 +51603,38 @@ var meshStatusHandlers = {
|
|
|
51543
51603
|
meshId,
|
|
51544
51604
|
command: "mesh_status",
|
|
51545
51605
|
refreshRequested,
|
|
51606
|
+
durationMs: Date.now() - startedAtMs,
|
|
51546
51607
|
summary: summarizeRepoMeshStatusDebug(cachedStatus)
|
|
51547
51608
|
});
|
|
51548
51609
|
return cachedStatus;
|
|
51549
51610
|
}
|
|
51611
|
+
const staleStatus = ctx.getCachedAggregateMeshStatus(meshId, mesh, {
|
|
51612
|
+
requireDirectPeerTruth: args?.requireDirectPeerTruth === true,
|
|
51613
|
+
allowStalePending: true
|
|
51614
|
+
});
|
|
51615
|
+
if (staleStatus) {
|
|
51616
|
+
if (!ctx.swrRefreshInFlight.has(meshId)) {
|
|
51617
|
+
ctx.swrRefreshInFlight.add(meshId);
|
|
51618
|
+
void Promise.resolve().then(() => ctx.execute("mesh_status", {
|
|
51619
|
+
meshId,
|
|
51620
|
+
inlineMesh: args?.inlineMesh,
|
|
51621
|
+
coordinatorDaemonId: args?.coordinatorDaemonId,
|
|
51622
|
+
requireDirectPeerTruth: args?.requireDirectPeerTruth === true,
|
|
51623
|
+
refresh: true
|
|
51624
|
+
}, "mesh_status_swr_freshen")).catch(() => {
|
|
51625
|
+
}).finally(() => {
|
|
51626
|
+
ctx.swrRefreshInFlight.delete(meshId);
|
|
51627
|
+
});
|
|
51628
|
+
}
|
|
51629
|
+
logRepoMeshStatusDebug("return_stale_swr", {
|
|
51630
|
+
meshId,
|
|
51631
|
+
command: "mesh_status",
|
|
51632
|
+
refreshRequested,
|
|
51633
|
+
durationMs: Date.now() - startedAtMs,
|
|
51634
|
+
summary: summarizeRepoMeshStatusDebug(staleStatus)
|
|
51635
|
+
});
|
|
51636
|
+
return staleStatus;
|
|
51637
|
+
}
|
|
51550
51638
|
}
|
|
51551
51639
|
const refreshReason = refreshRequested ? "explicit_refresh" : pendingCoordinatorEventCount > 0 ? "pending_coordinator_events" : hadAggregateCache ? "stale_pending_cache_refresh" : "cold_cache_miss";
|
|
51552
51640
|
const { getMeshQueueStats: getMeshQueueStats2, getQueue: getQueue2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
|
|
@@ -51627,8 +51715,7 @@ var meshStatusHandlers = {
|
|
|
51627
51715
|
);
|
|
51628
51716
|
const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes) ? selectedCoordinatorNodeId : void 0;
|
|
51629
51717
|
const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
51630
|
-
const
|
|
51631
|
-
for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
|
|
51718
|
+
const renderMeshNode = async (nodeIndex, node) => {
|
|
51632
51719
|
const nodeId = normalizeMeshNodeId(node) ?? "";
|
|
51633
51720
|
const daemonId = readStringValue(node.daemonId);
|
|
51634
51721
|
const nodeMachineId = readMeshNodeMachineId(node);
|
|
@@ -51783,19 +51870,19 @@ var meshStatusHandlers = {
|
|
|
51783
51870
|
)) {
|
|
51784
51871
|
applyInlineMeshBranchConvergence(mesh, node, status);
|
|
51785
51872
|
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode, directTruthUnavailable: directTruthUnavailableNodeIds.has(nodeId) });
|
|
51786
|
-
|
|
51787
|
-
continue;
|
|
51873
|
+
return status;
|
|
51788
51874
|
}
|
|
51789
51875
|
if (meshRecord?.source === "inline_cache" && !isSelfNode) {
|
|
51790
51876
|
applyInlineMeshBranchConvergence(mesh, node, status);
|
|
51791
51877
|
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode, directTruthUnavailable: directTruthUnavailableNodeIds.has(nodeId) });
|
|
51792
|
-
|
|
51793
|
-
continue;
|
|
51878
|
+
return status;
|
|
51794
51879
|
}
|
|
51795
51880
|
}
|
|
51796
51881
|
} else {
|
|
51797
51882
|
try {
|
|
51798
|
-
const
|
|
51883
|
+
const runLocalProbe = () => getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
51884
|
+
const gitStatus = await meshGitProbeCache.probeLocal(workspace, runLocalProbe);
|
|
51885
|
+
if (!gitStatus) throw new Error("local_git_probe_unavailable");
|
|
51799
51886
|
status.git = gitStatus;
|
|
51800
51887
|
status[MESH_NODE_LIVE_TRUTH_MARKER] = true;
|
|
51801
51888
|
const reporter = recordInlineMeshDirectGitTruth(node, gitStatus, "selected_coordinator_local_git");
|
|
@@ -51817,8 +51904,38 @@ var meshStatusHandlers = {
|
|
|
51817
51904
|
}
|
|
51818
51905
|
applyInlineMeshBranchConvergence(mesh, node, status);
|
|
51819
51906
|
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode, directTruthUnavailable: directTruthUnavailableNodeIds.has(nodeId) });
|
|
51820
|
-
|
|
51821
|
-
}
|
|
51907
|
+
return status;
|
|
51908
|
+
};
|
|
51909
|
+
const meshNodeEntries = [...(mesh.nodes || []).entries()];
|
|
51910
|
+
const settledNodeStatuses = await Promise.allSettled(
|
|
51911
|
+
meshNodeEntries.map(([nodeIndex, node]) => renderMeshNode(nodeIndex, node))
|
|
51912
|
+
);
|
|
51913
|
+
const nodeStatuses = settledNodeStatuses.map((settled, i) => {
|
|
51914
|
+
if (settled.status === "fulfilled") return settled.value;
|
|
51915
|
+
const [nodeIndex, node] = meshNodeEntries[i];
|
|
51916
|
+
const nodeId = normalizeMeshNodeId(node) ?? "";
|
|
51917
|
+
const daemonId = readStringValue(node.daemonId);
|
|
51918
|
+
const fallback = {
|
|
51919
|
+
nodeId,
|
|
51920
|
+
machineLabel: buildMeshNodeDisplayLabel(node, nodeId, readProviderPriorityFromPolicy(node.policy)),
|
|
51921
|
+
workspace: node.workspace,
|
|
51922
|
+
repoRoot: node.repoRoot,
|
|
51923
|
+
isLocalWorktree: node.isLocalWorktree,
|
|
51924
|
+
worktreeBranch: node.worktreeBranch,
|
|
51925
|
+
daemonId,
|
|
51926
|
+
machineId: readMeshNodeMachineId(node) || node.machineId,
|
|
51927
|
+
health: "unknown",
|
|
51928
|
+
providers: node.providers || [],
|
|
51929
|
+
activeSessions: [],
|
|
51930
|
+
activeSessionDetails: [],
|
|
51931
|
+
launchReady: false,
|
|
51932
|
+
error: settled.reason instanceof Error ? settled.reason.message : "node render failed"
|
|
51933
|
+
};
|
|
51934
|
+
applyCachedInlineMeshNodeStatus(fallback, node);
|
|
51935
|
+
applyInlineMeshBranchConvergence(mesh, node, fallback);
|
|
51936
|
+
finalizeMeshNodeStatus({ status: fallback, node, daemonId, isSelfNode: false, directTruthUnavailable: directTruthUnavailableNodeIds.has(nodeId) });
|
|
51937
|
+
return fallback;
|
|
51938
|
+
});
|
|
51822
51939
|
const callerCoordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : ctx.deps.statusInstanceId || void 0;
|
|
51823
51940
|
const pendingCoordinatorEvents = getPendingMeshCoordinatorEvents(meshId, callerCoordinatorDaemonId);
|
|
51824
51941
|
const unroutableDeliveries = getRecentUnroutableDeliveries();
|
|
@@ -51934,6 +52051,7 @@ var meshStatusHandlers = {
|
|
|
51934
52051
|
refreshReason,
|
|
51935
52052
|
meshSource: meshRecord.source,
|
|
51936
52053
|
directTruth,
|
|
52054
|
+
durationMs: Date.now() - startedAtMs,
|
|
51937
52055
|
summary: summarizeRepoMeshStatusDebug(returnedStatus)
|
|
51938
52056
|
});
|
|
51939
52057
|
return returnedStatus;
|
|
@@ -53134,7 +53252,7 @@ var MESH_DIRECT_PROBE_TIMEOUT_MS = readMeshTimeoutEnvMs("MESH_DIRECT_PROBE_TIMEO
|
|
|
53134
53252
|
var MESH_DIRECT_PROBE_RETRY_TIMEOUT_MS = readMeshTimeoutEnvMs("MESH_DIRECT_PROBE_RETRY_TIMEOUT_MS", 25e3);
|
|
53135
53253
|
var MESH_DIRECT_PROBE_CONNECT_TIMEOUT_MS = MESH_CONNECT_TIMEOUT_MS;
|
|
53136
53254
|
var MESH_DIRECT_PROBE_REUSE_MS = readMeshTimeoutEnvMs("MESH_DIRECT_PROBE_REUSE_MS", 12e3);
|
|
53137
|
-
var MeshGitProbeCache = class {
|
|
53255
|
+
var MeshGitProbeCache = class _MeshGitProbeCache {
|
|
53138
53256
|
constructor(reuseMs, now = Date.now) {
|
|
53139
53257
|
this.reuseMs = reuseMs;
|
|
53140
53258
|
this.now = now;
|
|
@@ -53144,6 +53262,23 @@ var MeshGitProbeCache = class {
|
|
|
53144
53262
|
key(daemonId, workspace) {
|
|
53145
53263
|
return `${daemonId}::${workspace}`;
|
|
53146
53264
|
}
|
|
53265
|
+
/**
|
|
53266
|
+
* Local (same-machine) git_status dedup. The bootstrap direct-truth hydrate
|
|
53267
|
+
* and the per-node render loop both call getGitRepoStatus(refreshUpstream:true)
|
|
53268
|
+
* for the same local workspace within one mesh_status call. Each such probe
|
|
53269
|
+
* fans out ~13-15 git subprocesses, and because the two passes are separated by
|
|
53270
|
+
* the render/hydrate work of every OTHER node they routinely straddle the
|
|
53271
|
+
* getGitRepoStatus 1.5s TTL, so the second pass re-shells the whole ~14-process
|
|
53272
|
+
* collection. Routing both through this cache (namespaced under a reserved
|
|
53273
|
+
* daemon id so it never collides with a remote-peer key) collapses them to one
|
|
53274
|
+
* collection per workspace per request, and reuses it across the reuse window
|
|
53275
|
+
* so the dashboard auto-retry loop can't restart a fresh local probe seconds
|
|
53276
|
+
* apart either.
|
|
53277
|
+
*/
|
|
53278
|
+
static LOCAL_PROBE_DAEMON_ID = "__local_git__";
|
|
53279
|
+
async probeLocal(workspace, probe) {
|
|
53280
|
+
return this.probe(_MeshGitProbeCache.LOCAL_PROBE_DAEMON_ID, workspace, probe);
|
|
53281
|
+
}
|
|
53147
53282
|
/**
|
|
53148
53283
|
* Run `probe` for this peer, but reuse a fresh recent result or an in-flight
|
|
53149
53284
|
* probe for the same key when one is available. `probe` is only invoked when
|
|
@@ -53254,7 +53389,7 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
53254
53389
|
let standingEvidenceCount = 0;
|
|
53255
53390
|
const unavailableNodeIds = [];
|
|
53256
53391
|
const deadNodeIds = [];
|
|
53257
|
-
|
|
53392
|
+
const classifyNode = async (nodeIndex, node) => {
|
|
53258
53393
|
const nodeId = normalizeMeshNodeId(node) || `node_${nodeIndex}`;
|
|
53259
53394
|
const workspace = readStringValue(node?.workspace);
|
|
53260
53395
|
const daemonId = readStringValue(node?.daemonId);
|
|
@@ -53267,38 +53402,33 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
53267
53402
|
daemonId && (daemonIdsEquivalent(daemonId, args.localMachineId) || daemonIdsEquivalent(daemonId, args.statusInstanceId))
|
|
53268
53403
|
);
|
|
53269
53404
|
if ((isSelfNode || isSelfDaemonNode) && isDeadLocalWorktreeNode(node)) {
|
|
53270
|
-
|
|
53271
|
-
continue;
|
|
53405
|
+
return { kind: "dead", nodeId };
|
|
53272
53406
|
}
|
|
53273
53407
|
if (!workspace) {
|
|
53274
|
-
|
|
53275
|
-
continue;
|
|
53408
|
+
return !isSelfNode && daemonId ? { kind: "unavailable", nodeId } : { kind: "skip" };
|
|
53276
53409
|
}
|
|
53277
53410
|
if (fs29.existsSync(workspace)) {
|
|
53278
53411
|
try {
|
|
53279
|
-
const
|
|
53412
|
+
const runLocalProbe = () => getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
53413
|
+
const localGit = args.probeCache ? await args.probeCache.probeLocal(workspace, runLocalProbe) : await runLocalProbe();
|
|
53280
53414
|
if (localGit?.isGitRepo) {
|
|
53281
53415
|
const reporter = recordInlineMeshDirectGitTruth(node, localGit, "selected_coordinator_local_git");
|
|
53282
53416
|
persistNodeReporterPlatform(args.meshSource, args.mesh, nodeId, reporter);
|
|
53283
|
-
|
|
53284
|
-
continue;
|
|
53417
|
+
return { kind: "local" };
|
|
53285
53418
|
}
|
|
53286
53419
|
} catch {
|
|
53287
53420
|
}
|
|
53288
53421
|
}
|
|
53289
53422
|
const standingGit = buildInlineMeshTransitGitStatus(node);
|
|
53290
53423
|
if (standingGit) {
|
|
53291
|
-
|
|
53292
|
-
continue;
|
|
53424
|
+
return { kind: "standing" };
|
|
53293
53425
|
}
|
|
53294
53426
|
if (!args.probeRemotePeers) {
|
|
53295
|
-
|
|
53427
|
+
return { kind: "skip" };
|
|
53296
53428
|
}
|
|
53297
53429
|
if (!daemonId || !args.dispatchMeshCommand) {
|
|
53298
|
-
|
|
53299
|
-
continue;
|
|
53430
|
+
return !isSelfNode ? { kind: "unavailable", nodeId } : { kind: "skip" };
|
|
53300
53431
|
}
|
|
53301
|
-
peerAttemptedCount += 1;
|
|
53302
53432
|
const runProbe = () => probeRemoteMeshGitStatusWithRetry({
|
|
53303
53433
|
dispatchMeshCommand: args.dispatchMeshCommand,
|
|
53304
53434
|
daemonId,
|
|
@@ -53312,11 +53442,52 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
53312
53442
|
if (remoteGit) {
|
|
53313
53443
|
const reporter = recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
|
|
53314
53444
|
persistNodeReporterPlatform(args.meshSource, args.mesh, nodeId, reporter);
|
|
53315
|
-
|
|
53316
|
-
continue;
|
|
53445
|
+
return { kind: "peerConfirmed" };
|
|
53317
53446
|
}
|
|
53318
|
-
|
|
53319
|
-
}
|
|
53447
|
+
return { kind: "peerUnavailable", nodeId };
|
|
53448
|
+
};
|
|
53449
|
+
const nodeEntries = [...nodes.entries()];
|
|
53450
|
+
const settledResults = await Promise.allSettled(
|
|
53451
|
+
nodeEntries.map(([nodeIndex, node]) => classifyNode(nodeIndex, node))
|
|
53452
|
+
);
|
|
53453
|
+
settledResults.forEach((settled, i) => {
|
|
53454
|
+
const [nodeIndex, node] = nodeEntries[i];
|
|
53455
|
+
const result = settled.status === "fulfilled" ? settled.value : (() => {
|
|
53456
|
+
const nodeId = normalizeMeshNodeId(node) || `node_${nodeIndex}`;
|
|
53457
|
+
const daemonId = readStringValue(node?.daemonId);
|
|
53458
|
+
const isSelfNode = Boolean(
|
|
53459
|
+
nodeId && selectedCoordinatorNodeId && nodeId === selectedCoordinatorNodeId
|
|
53460
|
+
) || Boolean(
|
|
53461
|
+
daemonId && (daemonIdsEquivalent(daemonId, args.localMachineId) || daemonIdsEquivalent(daemonId, args.statusInstanceId))
|
|
53462
|
+
);
|
|
53463
|
+
return !isSelfNode && daemonId ? { kind: "unavailable", nodeId } : { kind: "skip" };
|
|
53464
|
+
})();
|
|
53465
|
+
switch (result.kind) {
|
|
53466
|
+
case "dead":
|
|
53467
|
+
deadNodeIds.push(result.nodeId);
|
|
53468
|
+
break;
|
|
53469
|
+
case "unavailable":
|
|
53470
|
+
unavailableNodeIds.push(result.nodeId);
|
|
53471
|
+
break;
|
|
53472
|
+
case "local":
|
|
53473
|
+
localConfirmedCount += 1;
|
|
53474
|
+
break;
|
|
53475
|
+
case "standing":
|
|
53476
|
+
standingEvidenceCount += 1;
|
|
53477
|
+
break;
|
|
53478
|
+
case "peerConfirmed":
|
|
53479
|
+
peerAttemptedCount += 1;
|
|
53480
|
+
peerConfirmedCount += 1;
|
|
53481
|
+
break;
|
|
53482
|
+
case "peerUnavailable":
|
|
53483
|
+
peerAttemptedCount += 1;
|
|
53484
|
+
unavailableNodeIds.push(result.nodeId);
|
|
53485
|
+
break;
|
|
53486
|
+
case "skip":
|
|
53487
|
+
default:
|
|
53488
|
+
break;
|
|
53489
|
+
}
|
|
53490
|
+
});
|
|
53320
53491
|
return {
|
|
53321
53492
|
directEvidenceCount: localConfirmedCount + peerConfirmedCount + standingEvidenceCount,
|
|
53322
53493
|
localConfirmedCount,
|
|
@@ -54687,6 +54858,10 @@ var DaemonCommandRouter = class {
|
|
|
54687
54858
|
* Spans separate mesh_status/get_mesh calls so the dashboard auto-retry
|
|
54688
54859
|
* loop cannot storm a slow peer with back-to-back refreshUpstream probes. */
|
|
54689
54860
|
meshGitProbeCache = new MeshGitProbeCache(MESH_DIRECT_PROBE_REUSE_MS);
|
|
54861
|
+
/** Meshes with a background SWR freshen (async mesh_status refresh) already in
|
|
54862
|
+
* flight — so a burst of interactive detail-opens serves the cached snapshot
|
|
54863
|
+
* and coalesces onto ONE background refresh instead of storming the peers. */
|
|
54864
|
+
swrRefreshInFlight = /* @__PURE__ */ new Set();
|
|
54690
54865
|
/** In-memory async Refinery jobs keyed by meshId:nodeId to reject/return duplicate in-flight requests. */
|
|
54691
54866
|
runningRefineJobs = /* @__PURE__ */ new Map();
|
|
54692
54867
|
/** Terminal async Refinery jobs preserve a clear answer after the worktree node has been removed. */
|
|
@@ -54790,7 +54965,7 @@ var DaemonCommandRouter = class {
|
|
|
54790
54965
|
if (cached3.queueRevision !== getMeshQueueRevision(meshId)) return null;
|
|
54791
54966
|
let snapshot = this.cloneJsonValue(cached3.snapshot);
|
|
54792
54967
|
snapshot = this.hydrateCachedAggregateMeshStatusFromInline(snapshot, mesh, options);
|
|
54793
|
-
if (shouldRefreshStalePendingAggregate(snapshot, options)) return null;
|
|
54968
|
+
if (!options?.allowStalePending && shouldRefreshStalePendingAggregate(snapshot, options)) return null;
|
|
54794
54969
|
const ageMs = Math.max(0, Date.now() - cached3.builtAt);
|
|
54795
54970
|
const sourceOfTruth = snapshot.sourceOfTruth && typeof snapshot.sourceOfTruth === "object" ? snapshot.sourceOfTruth : {};
|
|
54796
54971
|
snapshot.sourceOfTruth = {
|
|
@@ -55020,6 +55195,7 @@ var DaemonCommandRouter = class {
|
|
|
55020
55195
|
rememberAggregateMeshStatus: this.rememberAggregateMeshStatus.bind(this),
|
|
55021
55196
|
execute: this.execute.bind(this),
|
|
55022
55197
|
aggregateMeshStatusCache: this.aggregateMeshStatusCache,
|
|
55198
|
+
swrRefreshInFlight: this.swrRefreshInFlight,
|
|
55023
55199
|
runningRefineJobs: this.runningRefineJobs,
|
|
55024
55200
|
inlineMeshCache: this.inlineMeshCache,
|
|
55025
55201
|
meshGitProbeCache: this.meshGitProbeCache
|