@adhdev/daemon-core 0.9.82-rc.382 → 0.9.82-rc.383
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/router.d.ts +11 -1
- package/dist/index.js +58 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +58 -19
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/commands/router.ts +50 -17
- package/src/mesh/mesh-reconcile-loop.ts +74 -30
|
@@ -156,8 +156,18 @@ export declare class DaemonCommandRouter {
|
|
|
156
156
|
* the wider plural-shape scan so a controlbar/modal command targeting a non-primary remote
|
|
157
157
|
* session still resolves its owner — the singular readCachedInlineMeshActiveSessions semantics
|
|
158
158
|
* other consumers depend on stay untouched.
|
|
159
|
+
*
|
|
160
|
+
* CANCEL-STOP-RELAY: the session-id cache scan above only matches when the coordinator's
|
|
161
|
+
* cached status snapshot already lists the worker's session id in a recognized active-sessions
|
|
162
|
+
* shape. A worktree-clone worker session whose id form/timing differs from the cached snapshot
|
|
163
|
+
* (or is simply not yet reflected) misses the scan, so a stop that carries the authoritative
|
|
164
|
+
* owning nodeId (mesh_queue_cancel knows assignedNodeId) used to silently fail to forward.
|
|
165
|
+
* `ownerNodeIdHint` adds a deterministic fallback: when the session-id scan misses, resolve the
|
|
166
|
+
* owner daemonId by matching the node by id (meshNodeIdMatches — same form-tolerant compare the
|
|
167
|
+
* rest of the router uses, no new raw compare). The same self-loopback guard applies to both
|
|
168
|
+
* paths, so a coordinator-hosted node is still never force-forwarded to a remote form of itself.
|
|
159
169
|
*/
|
|
160
|
-
resolveRemoteMeshSessionOwnerDaemonId(sessionId: string): string | undefined;
|
|
170
|
+
resolveRemoteMeshSessionOwnerDaemonId(sessionId: string, ownerNodeIdHint?: string): string | undefined;
|
|
161
171
|
/**
|
|
162
172
|
* Candidate nodes for remote-session owner resolution: the cached inline-mesh nodes (which
|
|
163
173
|
* carry each node's primary session) plus the nodes from every cached aggregate mesh-status
|
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 ? "6cca365bcea9757dd350c6bac460ca5a169a9280" : void 0) ?? "unknown";
|
|
387
|
+
const commitShort = readInjected(true ? "6cca365b" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
388
|
+
const version = readInjected(true ? "0.9.82-rc.383" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
389
|
+
const builtAt = readInjected(true ? "2026-06-25T15:14:41.579Z" : void 0);
|
|
390
390
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
391
391
|
return cached;
|
|
392
392
|
}
|
|
@@ -15157,8 +15157,7 @@ async function runMeshReconcileTick(components) {
|
|
|
15157
15157
|
const idleCoordinators = meshCoordinators.filter((c) => c.idle);
|
|
15158
15158
|
const generatingCoordinators = meshCoordinators.filter((c) => !c.idle && !c.modalParked);
|
|
15159
15159
|
const modalParkedCoordinators = meshCoordinators.filter((c) => !c.idle && c.modalParked);
|
|
15160
|
-
const targetCoordinators = idleCoordinators
|
|
15161
|
-
const forceOnly = idleCoordinators.length === 0;
|
|
15160
|
+
const targetCoordinators = idleCoordinators;
|
|
15162
15161
|
if (targetCoordinators.length === 0) {
|
|
15163
15162
|
if (modalParkedCoordinators.length > 0) {
|
|
15164
15163
|
const liveSessionIds = new Set(
|
|
@@ -15225,6 +15224,23 @@ async function runMeshReconcileTick(components) {
|
|
|
15225
15224
|
modalParkedCoordinators.length
|
|
15226
15225
|
);
|
|
15227
15226
|
}
|
|
15227
|
+
} else if (generatingCoordinators.length > 0) {
|
|
15228
|
+
let hasPending = true;
|
|
15229
|
+
if (store) {
|
|
15230
|
+
try {
|
|
15231
|
+
hasPending = store.pendingEventCount(meshId) > 0;
|
|
15232
|
+
} catch {
|
|
15233
|
+
}
|
|
15234
|
+
}
|
|
15235
|
+
if (hasPending) {
|
|
15236
|
+
LOG.info("MeshReconcile", `Reconcile skip \u2192 generating: holding pending event(s) for mesh ${meshId} (${generatingCoordinators.length} coordinator(s) busy; events left queued for the next idle tick)`);
|
|
15237
|
+
recordHeldTerminalEventsToLedger(
|
|
15238
|
+
meshId,
|
|
15239
|
+
drainDaemonIds.length > 0 ? drainDaemonIds : localDaemonId ? [localDaemonId] : [],
|
|
15240
|
+
"generating_no_idle_coordinator",
|
|
15241
|
+
generatingCoordinators.length
|
|
15242
|
+
);
|
|
15243
|
+
}
|
|
15228
15244
|
}
|
|
15229
15245
|
continue;
|
|
15230
15246
|
}
|
|
@@ -15238,16 +15254,14 @@ async function runMeshReconcileTick(components) {
|
|
|
15238
15254
|
try {
|
|
15239
15255
|
pendingEvents = drainPendingMeshCoordinatorEvents(
|
|
15240
15256
|
meshId,
|
|
15241
|
-
drainDaemonIds.length > 0 ? drainDaemonIds : localDaemonId
|
|
15242
|
-
forceOnly ? { onlyEvents: MESH_FORCE_INJECT_EVENTS } : void 0
|
|
15257
|
+
drainDaemonIds.length > 0 ? drainDaemonIds : localDaemonId
|
|
15243
15258
|
);
|
|
15244
15259
|
} catch (e) {
|
|
15245
15260
|
LOG.warn("MeshReconcile", `Drain failed for mesh ${meshId}: ${e?.message || e}`);
|
|
15246
15261
|
continue;
|
|
15247
15262
|
}
|
|
15248
15263
|
if (pendingEvents.length === 0) continue;
|
|
15249
|
-
|
|
15250
|
-
LOG.info("MeshReconcile", `Reconcile ${mode}: ${pendingEvents.length} pending event(s) \u2192 ${targetCoordinators.length} coordinator(s) for mesh ${meshId}`);
|
|
15264
|
+
LOG.info("MeshReconcile", `Reconcile inject \u2192 idle: ${pendingEvents.length} pending event(s) \u2192 ${targetCoordinators.length} coordinator(s) for mesh ${meshId}`);
|
|
15251
15265
|
for (const pending of pendingEvents) {
|
|
15252
15266
|
const wantSession = readNonEmptyString2(pending.targetCoordinatorSessionId);
|
|
15253
15267
|
if (wantSession) {
|
|
@@ -52440,17 +52454,40 @@ var DaemonCommandRouter = class {
|
|
|
52440
52454
|
* the wider plural-shape scan so a controlbar/modal command targeting a non-primary remote
|
|
52441
52455
|
* session still resolves its owner — the singular readCachedInlineMeshActiveSessions semantics
|
|
52442
52456
|
* other consumers depend on stay untouched.
|
|
52457
|
+
*
|
|
52458
|
+
* CANCEL-STOP-RELAY: the session-id cache scan above only matches when the coordinator's
|
|
52459
|
+
* cached status snapshot already lists the worker's session id in a recognized active-sessions
|
|
52460
|
+
* shape. A worktree-clone worker session whose id form/timing differs from the cached snapshot
|
|
52461
|
+
* (or is simply not yet reflected) misses the scan, so a stop that carries the authoritative
|
|
52462
|
+
* owning nodeId (mesh_queue_cancel knows assignedNodeId) used to silently fail to forward.
|
|
52463
|
+
* `ownerNodeIdHint` adds a deterministic fallback: when the session-id scan misses, resolve the
|
|
52464
|
+
* owner daemonId by matching the node by id (meshNodeIdMatches — same form-tolerant compare the
|
|
52465
|
+
* rest of the router uses, no new raw compare). The same self-loopback guard applies to both
|
|
52466
|
+
* paths, so a coordinator-hosted node is still never force-forwarded to a remote form of itself.
|
|
52443
52467
|
*/
|
|
52444
|
-
resolveRemoteMeshSessionOwnerDaemonId(sessionId) {
|
|
52468
|
+
resolveRemoteMeshSessionOwnerDaemonId(sessionId, ownerNodeIdHint) {
|
|
52445
52469
|
const trimmed = typeof sessionId === "string" ? sessionId.trim() : "";
|
|
52446
|
-
|
|
52470
|
+
const nodeHint = typeof ownerNodeIdHint === "string" ? ownerNodeIdHint.trim() : "";
|
|
52471
|
+
if (!trimmed && !nodeHint) return void 0;
|
|
52447
52472
|
const selfDaemonId = this.deps.statusInstanceId;
|
|
52448
|
-
|
|
52449
|
-
|
|
52450
|
-
const
|
|
52451
|
-
|
|
52452
|
-
|
|
52453
|
-
|
|
52473
|
+
const candidates = this.collectMeshSessionOwnerCandidateNodes();
|
|
52474
|
+
if (trimmed) {
|
|
52475
|
+
for (const node of candidates) {
|
|
52476
|
+
if (!collectMeshNodeHostedSessionIds(node).has(trimmed)) continue;
|
|
52477
|
+
const nodeDaemonId = readMeshNodeDaemonId(readObjectRecord(node));
|
|
52478
|
+
if (!nodeDaemonId) continue;
|
|
52479
|
+
if (selfDaemonId && daemonIdsEquivalent(nodeDaemonId, selfDaemonId)) return void 0;
|
|
52480
|
+
return nodeDaemonId;
|
|
52481
|
+
}
|
|
52482
|
+
}
|
|
52483
|
+
if (nodeHint) {
|
|
52484
|
+
for (const node of candidates) {
|
|
52485
|
+
if (!meshNodeIdMatches(node, nodeHint)) continue;
|
|
52486
|
+
const nodeDaemonId = readMeshNodeDaemonId(readObjectRecord(node));
|
|
52487
|
+
if (!nodeDaemonId) continue;
|
|
52488
|
+
if (selfDaemonId && daemonIdsEquivalent(nodeDaemonId, selfDaemonId)) return void 0;
|
|
52489
|
+
return nodeDaemonId;
|
|
52490
|
+
}
|
|
52454
52491
|
}
|
|
52455
52492
|
return void 0;
|
|
52456
52493
|
}
|
|
@@ -54584,7 +54621,9 @@ ${hintLines.join("\n")}` : "",
|
|
|
54584
54621
|
const localInstance = this.deps.instanceManager?.getInstance(targetSessionId);
|
|
54585
54622
|
const localRegistry = this.deps.sessionRegistry?.get?.(targetSessionId);
|
|
54586
54623
|
if (!localInstance && !localRegistry) {
|
|
54587
|
-
const
|
|
54624
|
+
const meshContext = readObjectRecord(args?.meshContext);
|
|
54625
|
+
const ownerNodeIdHint = readStringValue(meshContext.nodeId);
|
|
54626
|
+
const ownerDaemonId = this.resolveRemoteMeshSessionOwnerDaemonId(targetSessionId, ownerNodeIdHint);
|
|
54588
54627
|
if (ownerDaemonId) {
|
|
54589
54628
|
LOG.info("Mesh", `[Mesh] Forwarding session-scoped '${cmd}' for remote worker session ${targetSessionId.split("_")[0]} \u2192 daemon ${ownerDaemonId.slice(0, 12)}`);
|
|
54590
54629
|
const forwarded = await this.deps.dispatchMeshCommand(ownerDaemonId, cmd, {
|