@adhdev/daemon-core 0.9.82-rc.384 → 0.9.82-rc.386
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/cli-adapter-types.d.ts +12 -0
- package/dist/cli-adapters/provider-cli-shared.d.ts +11 -0
- package/dist/index.js +71 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +71 -7
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-events.d.ts +1 -1
- package/dist/mesh/mesh-reconcile-loop.d.ts +56 -0
- package/dist/providers/cli-provider-instance.d.ts +8 -0
- package/dist/providers/spec/fsm-driver.d.ts +10 -0
- package/package.json +2 -2
- package/src/cli-adapter-types.ts +12 -0
- package/src/cli-adapters/provider-cli-shared.ts +11 -0
- package/src/commands/high-family/mesh-events.ts +13 -1
- package/src/mesh/mesh-events.ts +2 -0
- package/src/mesh/mesh-reconcile-loop.ts +84 -0
- package/src/providers/cli-provider-instance.ts +43 -1
- package/src/providers/spec/cli-adapter.ts +6 -1
- package/src/providers/spec/fsm-driver.ts +12 -0
|
@@ -26,6 +26,18 @@ export interface CliAdapterStatus {
|
|
|
26
26
|
providerSessionId?: string;
|
|
27
27
|
errorMessage?: string;
|
|
28
28
|
errorReason?: string;
|
|
29
|
+
/**
|
|
30
|
+
* FSM-spec adapters only: true once the driver has observed its first
|
|
31
|
+
* non-initial idle state (the prompt is genuinely drawn — see
|
|
32
|
+
* FsmDriver.maybeMarkReady / readySeenOnce). Used by CliProviderInstance to
|
|
33
|
+
* re-arm the queue-claim `agent:ready` event on the first genuine ready,
|
|
34
|
+
* independent of the boot-time starting→idle one-shot. That one-shot is
|
|
35
|
+
* consumed too early for providers whose INITIAL FSM state already reports
|
|
36
|
+
* status 'idle' (e.g. antigravity-cli), so without this re-arm the worker
|
|
37
|
+
* never claims its queued task and the coordinator relaunch-loops. Absent
|
|
38
|
+
* (undefined) for non-FSM adapters — they keep the boot one-shot behavior.
|
|
39
|
+
*/
|
|
40
|
+
fsmReadySeen?: boolean;
|
|
29
41
|
}
|
|
30
42
|
export interface AcpAdapterHandle {
|
|
31
43
|
onEvent(event: string, data?: unknown): void;
|
|
@@ -58,6 +58,17 @@ export interface CliSessionStatus {
|
|
|
58
58
|
errorMessage?: string;
|
|
59
59
|
errorReason?: string;
|
|
60
60
|
providerSessionId?: string;
|
|
61
|
+
/**
|
|
62
|
+
* Spec/FSM adapters only (SpecCliAdapter): true once the driver has observed
|
|
63
|
+
* its first non-initial idle state — the prompt is genuinely drawn. The
|
|
64
|
+
* legacy ProviderCliAdapter never sets it (undefined). CliProviderInstance
|
|
65
|
+
* uses it to re-arm the queue-claim agent:ready on the first genuine ready,
|
|
66
|
+
* independent of the boot-time starting→idle one-shot (which is consumed too
|
|
67
|
+
* early for specs whose initial state already reports status 'idle', e.g.
|
|
68
|
+
* antigravity-cli — without the re-arm the worker never claims its queued
|
|
69
|
+
* task and the coordinator relaunch-loops).
|
|
70
|
+
*/
|
|
71
|
+
fsmReadySeen?: boolean;
|
|
61
72
|
/**
|
|
62
73
|
* Timestamp (ms) of the most recent raw PTY output chunk. Advances on every
|
|
63
74
|
* byte the process emits, including tool/build output that produces no
|
package/dist/index.js
CHANGED
|
@@ -383,10 +383,10 @@ function readInjected(value) {
|
|
|
383
383
|
}
|
|
384
384
|
function getDaemonBuildInfo() {
|
|
385
385
|
if (cached) return cached;
|
|
386
|
-
const commit = readInjected(true ? "
|
|
387
|
-
const commitShort = readInjected(true ? "
|
|
388
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
389
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
386
|
+
const commit = readInjected(true ? "fad1d175ca84a75f52bd0c1d88125fbb783ad241" : void 0) ?? "unknown";
|
|
387
|
+
const commitShort = readInjected(true ? "fad1d175" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
388
|
+
const version = readInjected(true ? "0.9.82-rc.386" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
389
|
+
const builtAt = readInjected(true ? "2026-06-26T00:12:44.100Z" : void 0);
|
|
390
390
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
391
391
|
return cached;
|
|
392
392
|
}
|
|
@@ -14972,6 +14972,32 @@ function findLiveCoordinators(components) {
|
|
|
14972
14972
|
}
|
|
14973
14973
|
return out;
|
|
14974
14974
|
}
|
|
14975
|
+
function resolveCoordinatorDrainDeliverability(components, meshId) {
|
|
14976
|
+
const coordinators = findLiveCoordinators(components).filter((c) => c.meshId === meshId);
|
|
14977
|
+
if (coordinators.length === 0) {
|
|
14978
|
+
return { hasLiveCliCoordinator: false, deliverableNow: false, holdForReconcile: false };
|
|
14979
|
+
}
|
|
14980
|
+
const hasIdle = coordinators.some((c) => c.idle);
|
|
14981
|
+
return {
|
|
14982
|
+
hasLiveCliCoordinator: true,
|
|
14983
|
+
deliverableNow: hasIdle,
|
|
14984
|
+
// A live CLI coordinator exists but none is idle → the reconcile loop is
|
|
14985
|
+
// holding the events; the poll must not steal them.
|
|
14986
|
+
holdForReconcile: !hasIdle
|
|
14987
|
+
};
|
|
14988
|
+
}
|
|
14989
|
+
function shouldHoldPendingDrainForBusyLocalCoordinator(components, meshId, requestedCoordinatorDaemonId) {
|
|
14990
|
+
if (!meshId) return false;
|
|
14991
|
+
const deliverability = resolveCoordinatorDrainDeliverability(components, meshId);
|
|
14992
|
+
if (!deliverability.holdForReconcile) return false;
|
|
14993
|
+
const requested = readNonEmptyString2(requestedCoordinatorDaemonId);
|
|
14994
|
+
if (!requested) return true;
|
|
14995
|
+
const localIds = expandDaemonIdForms([
|
|
14996
|
+
readNonEmptyString2(components.statusInstanceId),
|
|
14997
|
+
readNonEmptyString2(loadConfig().machineId)
|
|
14998
|
+
]);
|
|
14999
|
+
return localIds.some((id) => daemonIdsEquivalent(id, requested));
|
|
15000
|
+
}
|
|
14975
15001
|
function injectPendingIntoCoordinator(coordinator, pending) {
|
|
14976
15002
|
if (!coordinator || !pending.coordinatorMessage) return;
|
|
14977
15003
|
const force = shouldForceInjectMeshEvent(pending.event);
|
|
@@ -15688,9 +15714,11 @@ __export(mesh_events_exports, {
|
|
|
15688
15714
|
isMeshCoordinatorEvent: () => isMeshCoordinatorEvent,
|
|
15689
15715
|
queuePendingMeshCoordinatorEvent: () => queuePendingMeshCoordinatorEvent,
|
|
15690
15716
|
reconcileDirectDispatchCompletionFromTranscript: () => reconcileDirectDispatchCompletionFromTranscript,
|
|
15717
|
+
resolveCoordinatorDrainDeliverability: () => resolveCoordinatorDrainDeliverability,
|
|
15691
15718
|
runMeshReconcileTick: () => runMeshReconcileTick,
|
|
15692
15719
|
setupMeshEventForwarding: () => setupMeshEventForwarding,
|
|
15693
15720
|
setupMeshReconcileLoop: () => setupMeshReconcileLoop,
|
|
15721
|
+
shouldHoldPendingDrainForBusyLocalCoordinator: () => shouldHoldPendingDrainForBusyLocalCoordinator,
|
|
15694
15722
|
triggerMeshQueue: () => triggerMeshQueue,
|
|
15695
15723
|
tryAssignQueueTask: () => tryAssignQueueTask
|
|
15696
15724
|
});
|
|
@@ -36186,6 +36214,17 @@ var FsmDriver = class {
|
|
|
36186
36214
|
hasIdleHoldPending() {
|
|
36187
36215
|
return (this.lastFsmEval?.transitions ?? []).some((t) => !t.holdSatisfied && t.condResult);
|
|
36188
36216
|
}
|
|
36217
|
+
/**
|
|
36218
|
+
* True once the machine has reached its first non-initial idle state (the
|
|
36219
|
+
* prompt is genuinely drawn — see maybeMarkReady). The cli-adapter surfaces
|
|
36220
|
+
* this on its idle status so CliProviderInstance can re-arm the queue-claim
|
|
36221
|
+
* agent:ready on the first genuine ready, independent of the boot-time
|
|
36222
|
+
* starting→idle one-shot (which is consumed too early for specs whose
|
|
36223
|
+
* initial state already reports idle).
|
|
36224
|
+
*/
|
|
36225
|
+
hasSeenReady() {
|
|
36226
|
+
return this.readySeenOnce;
|
|
36227
|
+
}
|
|
36189
36228
|
getCompletionIdleDebounceState() {
|
|
36190
36229
|
const out = outgoingTransitions(this.spec, this.currentStateId);
|
|
36191
36230
|
const toReady = this.lastFsmEval?.transitions.find((t, i) => {
|
|
@@ -37852,7 +37891,7 @@ var SpecCliAdapter = class _SpecCliAdapter {
|
|
|
37852
37891
|
if (state.status === "generating") {
|
|
37853
37892
|
return { status: "generating", messages: [], activeModal: null, activeInteractivePrompt: this.activeInteractivePrompt, ...sessionFields };
|
|
37854
37893
|
}
|
|
37855
|
-
return { status: "idle", messages: [], activeModal: null, activeInteractivePrompt: this.activeInteractivePrompt, ...sessionFields };
|
|
37894
|
+
return { status: "idle", messages: [], activeModal: null, activeInteractivePrompt: this.activeInteractivePrompt, fsmReadySeen: this.driver.hasSeenReady?.() ?? false, ...sessionFields };
|
|
37856
37895
|
}
|
|
37857
37896
|
maybeRefreshNativeHistory() {
|
|
37858
37897
|
}
|
|
@@ -38897,6 +38936,14 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
38897
38936
|
context = null;
|
|
38898
38937
|
events = [];
|
|
38899
38938
|
lastStatus = "starting";
|
|
38939
|
+
// Idempotency guard for the queue-claim agent:ready event. agent:ready is the
|
|
38940
|
+
// sole signal the mesh coordinator's tryAssignQueueTask waits on to hand a
|
|
38941
|
+
// queued task to this worker. It is emitted in two places: the boot-time
|
|
38942
|
+
// starting→idle one-shot, and the readySeen re-arm below. This flag makes the
|
|
38943
|
+
// event fire AT MOST ONCE per session so a worker is never claimed twice and a
|
|
38944
|
+
// queued task is never double-dispatched/double-injected. Whichever path fires
|
|
38945
|
+
// first sets it; the other becomes a no-op.
|
|
38946
|
+
agentReadyEmitted = false;
|
|
38900
38947
|
generatingStartedAt = 0;
|
|
38901
38948
|
settings = {};
|
|
38902
38949
|
monitor;
|
|
@@ -39977,6 +40024,17 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
39977
40024
|
} catch {
|
|
39978
40025
|
}
|
|
39979
40026
|
}
|
|
40027
|
+
/**
|
|
40028
|
+
* Emit the queue-claim agent:ready event at most once per session. Both the
|
|
40029
|
+
* boot-time starting→idle one-shot and the fsmReadySeen re-arm call this; the
|
|
40030
|
+
* agentReadyEmitted guard ensures the second caller is a no-op so a worker is
|
|
40031
|
+
* never claimed twice and a queued task is never double-dispatched.
|
|
40032
|
+
*/
|
|
40033
|
+
emitAgentReadyOnce(chatTitle, now) {
|
|
40034
|
+
if (this.agentReadyEmitted) return;
|
|
40035
|
+
this.agentReadyEmitted = true;
|
|
40036
|
+
this.pushEvent({ event: "agent:ready", chatTitle, timestamp: now });
|
|
40037
|
+
}
|
|
39980
40038
|
detectStatusTransition() {
|
|
39981
40039
|
const now = Date.now();
|
|
39982
40040
|
const adapterStatus = this.adapter.getStatus({ allowParse: false });
|
|
@@ -40129,7 +40187,7 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
40129
40187
|
this.scheduleCompletedDebounceFlush(flushDelay);
|
|
40130
40188
|
}
|
|
40131
40189
|
} else if (newStatus === "idle" && this.lastStatus === "starting") {
|
|
40132
|
-
this.
|
|
40190
|
+
this.emitAgentReadyOnce(chatTitle, now);
|
|
40133
40191
|
} else if (newStatus === "error") {
|
|
40134
40192
|
if (this.generatingDebounceTimer) {
|
|
40135
40193
|
clearTimeout(this.generatingDebounceTimer);
|
|
@@ -40168,6 +40226,9 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
40168
40226
|
}
|
|
40169
40227
|
this.lastStatus = newStatus;
|
|
40170
40228
|
}
|
|
40229
|
+
if (newStatus === "idle" && adapterStatus.fsmReadySeen === true && !this.agentReadyEmitted) {
|
|
40230
|
+
this.emitAgentReadyOnce(chatTitle, now);
|
|
40231
|
+
}
|
|
40171
40232
|
this.applyProviderResponse(parsedStatus, {
|
|
40172
40233
|
phase: newStatus === "idle" && (previousStatus === "generating" || previousStatus === "waiting_approval") ? "turn_completed" : "immediate"
|
|
40173
40234
|
});
|
|
@@ -48514,9 +48575,12 @@ var meshEventsHandlers = {
|
|
|
48514
48575
|
mesh_forward_event: async (ctx, args) => {
|
|
48515
48576
|
return handleMeshForwardEvent({ instanceManager: ctx.deps.instanceManager }, args);
|
|
48516
48577
|
},
|
|
48517
|
-
get_pending_mesh_events: async (
|
|
48578
|
+
get_pending_mesh_events: async (ctx, args) => {
|
|
48518
48579
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
48519
48580
|
const coordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : void 0;
|
|
48581
|
+
if (meshId && shouldHoldPendingDrainForBusyLocalCoordinator(ctx.deps, meshId, coordinatorDaemonId)) {
|
|
48582
|
+
return { success: true, events: [], heldForBusyLocalCoordinator: true };
|
|
48583
|
+
}
|
|
48520
48584
|
const events = drainPendingMeshCoordinatorEvents(meshId || void 0, coordinatorDaemonId);
|
|
48521
48585
|
return { success: true, events };
|
|
48522
48586
|
},
|