@adhdev/daemon-core 0.9.82-rc.382 → 0.9.82-rc.384

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.
@@ -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 ? "70741c4fe19c6f71bcef702e7e149d963d6fd916" : void 0) ?? "unknown";
387
- const commitShort = readInjected(true ? "70741c4f" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
388
- const version = readInjected(true ? "0.9.82-rc.382" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
389
- const builtAt = readInjected(true ? "2026-06-25T13:31:28.133Z" : void 0);
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.384" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
389
+ const builtAt = readInjected(true ? "2026-06-25T15:21:26.360Z" : 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.length > 0 ? idleCoordinators : generatingCoordinators;
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
- const mode = forceOnly ? "force-drain \u2192 generating" : "inject \u2192 idle";
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
- if (!trimmed) return void 0;
52470
+ const nodeHint = typeof ownerNodeIdHint === "string" ? ownerNodeIdHint.trim() : "";
52471
+ if (!trimmed && !nodeHint) return void 0;
52447
52472
  const selfDaemonId = this.deps.statusInstanceId;
52448
- for (const node of this.collectMeshSessionOwnerCandidateNodes()) {
52449
- if (!collectMeshNodeHostedSessionIds(node).has(trimmed)) continue;
52450
- const nodeDaemonId = readMeshNodeDaemonId(readObjectRecord(node));
52451
- if (!nodeDaemonId) continue;
52452
- if (selfDaemonId && daemonIdsEquivalent(nodeDaemonId, selfDaemonId)) return void 0;
52453
- return nodeDaemonId;
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 ownerDaemonId = this.resolveRemoteMeshSessionOwnerDaemonId(targetSessionId);
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, {