@adhdev/daemon-core 0.9.82-rc.274 → 0.9.82-rc.276

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.mjs CHANGED
@@ -270,10 +270,10 @@ function readInjected(value) {
270
270
  }
271
271
  function getDaemonBuildInfo() {
272
272
  if (cached) return cached;
273
- const commit = readInjected(true ? "89d1ac61612c1dfe7fac53be61ec5dbfa67d00b2" : void 0) ?? "unknown";
274
- const commitShort = readInjected(true ? "89d1ac61" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
275
- const version = readInjected(true ? "0.9.82-rc.274" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
276
- const builtAt = readInjected(true ? "2026-06-15T07:04:52.710Z" : void 0);
273
+ const commit = readInjected(true ? "746fc68e4c297b988b76207bb8c63ab6062a38e1" : void 0) ?? "unknown";
274
+ const commitShort = readInjected(true ? "746fc68e" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
275
+ const version = readInjected(true ? "0.9.82-rc.276" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
276
+ const builtAt = readInjected(true ? "2026-06-15T09:29:09.895Z" : void 0);
277
277
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
278
278
  return cached;
279
279
  }
@@ -4258,12 +4258,34 @@ var init_mesh_runtime_store = __esm({
4258
4258
  this.maybeCheckpointWal();
4259
4259
  return result.changes > 0;
4260
4260
  }
4261
- drainPendingEvents(meshId, coordinatorDaemonId) {
4261
+ /**
4262
+ * Drain undrained pending events for a mesh, atomically marking them drained.
4263
+ * When `opts.onlyEvents` is supplied, ONLY rows whose `event` is in that set are
4264
+ * drained — the rest stay queued (drained=0) for a later drain. This is how the
4265
+ * reconcile loop force-drains terminal/force-inject events into a *generating*
4266
+ * coordinator while leaving non-force progress events for the coordinator's next
4267
+ * idle transition. Filtering happens inside the same transaction as the
4268
+ * drained=1 marking, so force-drain + a concurrent full drain can never both
4269
+ * consume the same row.
4270
+ */
4271
+ drainPendingEvents(meshId, coordinatorDaemonId, opts) {
4262
4272
  return this.transaction(() => {
4263
- const whereClause = coordinatorDaemonId ? `WHERE mesh_id = ? AND drained = 0 AND (coordinator_daemon_id IS NULL OR coordinator_daemon_id = ?)` : `WHERE mesh_id = ? AND drained = 0`;
4264
- const params = coordinatorDaemonId ? [meshId, coordinatorDaemonId] : [meshId];
4273
+ const onlyEvents = opts?.onlyEvents;
4274
+ if (onlyEvents && onlyEvents.size === 0) return [];
4275
+ const eventList = onlyEvents ? [...onlyEvents] : [];
4276
+ const daemonIds = (Array.isArray(coordinatorDaemonId) ? coordinatorDaemonId : coordinatorDaemonId ? [coordinatorDaemonId] : []).filter((id) => typeof id === "string" && id.length > 0);
4277
+ const clauses = ["mesh_id = ?", "drained = 0"];
4278
+ const params = [meshId];
4279
+ if (daemonIds.length > 0) {
4280
+ clauses.push(`(coordinator_daemon_id IS NULL OR coordinator_daemon_id IN (${daemonIds.map(() => "?").join(",")}))`);
4281
+ params.push(...daemonIds);
4282
+ }
4283
+ if (eventList.length > 0) {
4284
+ clauses.push(`event IN (${eventList.map(() => "?").join(",")})`);
4285
+ params.push(...eventList);
4286
+ }
4265
4287
  const rows = this.db.prepare(
4266
- `SELECT id, event, payload FROM mesh_pending_events ${whereClause} ORDER BY queued_at ASC LIMIT 100`
4288
+ `SELECT id, event, payload FROM mesh_pending_events WHERE ${clauses.join(" AND ")} ORDER BY queued_at ASC LIMIT 100`
4267
4289
  ).all(...params);
4268
4290
  if (rows.length === 0) return [];
4269
4291
  const ids = rows.map((r) => r.id);
@@ -4286,8 +4308,9 @@ var init_mesh_runtime_store = __esm({
4286
4308
  }
4287
4309
  /** Non-destructive peek — returns undrained events without marking them drained. */
4288
4310
  peekPendingEvents(meshId, coordinatorDaemonId) {
4289
- const whereClause = coordinatorDaemonId ? `WHERE mesh_id = ? AND drained = 0 AND (coordinator_daemon_id IS NULL OR coordinator_daemon_id = ?)` : `WHERE mesh_id = ? AND drained = 0`;
4290
- const params = coordinatorDaemonId ? [meshId, coordinatorDaemonId] : [meshId];
4311
+ const daemonIds = (Array.isArray(coordinatorDaemonId) ? coordinatorDaemonId : coordinatorDaemonId ? [coordinatorDaemonId] : []).filter((id) => typeof id === "string" && id.length > 0);
4312
+ const whereClause = daemonIds.length > 0 ? `WHERE mesh_id = ? AND drained = 0 AND (coordinator_daemon_id IS NULL OR coordinator_daemon_id IN (${daemonIds.map(() => "?").join(",")}))` : `WHERE mesh_id = ? AND drained = 0`;
4313
+ const params = daemonIds.length > 0 ? [meshId, ...daemonIds] : [meshId];
4291
4314
  const rows = this.db.prepare(
4292
4315
  `SELECT id, event, payload FROM mesh_pending_events ${whereClause} ORDER BY queued_at ASC LIMIT 100`
4293
4316
  ).all(...params);
@@ -6330,6 +6353,19 @@ var init_mesh_events_utils = __esm({
6330
6353
  import { appendFileSync as appendFileSync2, existsSync as existsSync12, readFileSync as readFileSync10, renameSync as renameSync4, statSync as statSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "fs";
6331
6354
  import { join as join13 } from "path";
6332
6355
  import { randomUUID as randomUUID7 } from "crypto";
6356
+ function normalizeCoordinatorDaemonIds(coordinatorDaemonId) {
6357
+ const raw = Array.isArray(coordinatorDaemonId) ? coordinatorDaemonId : coordinatorDaemonId != null ? [coordinatorDaemonId] : [];
6358
+ const seen = /* @__PURE__ */ new Set();
6359
+ const out = [];
6360
+ for (const id of raw) {
6361
+ if (typeof id !== "string") continue;
6362
+ const trimmed = id.trim();
6363
+ if (!trimmed || seen.has(trimmed)) continue;
6364
+ seen.add(trimmed);
6365
+ out.push(trimmed);
6366
+ }
6367
+ return out;
6368
+ }
6333
6369
  function readRefineJobId2(event) {
6334
6370
  const metadata = readRecord3(event.metadataEvent) || event;
6335
6371
  const result = readRecord3(metadata.result);
@@ -6384,7 +6420,9 @@ function getPendingEventsPath(meshId, coordinatorDaemonId) {
6384
6420
  }
6385
6421
  function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
6386
6422
  if (!meshId) return [];
6387
- const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
6423
+ const daemonIds = normalizeCoordinatorDaemonIds(coordinatorDaemonId);
6424
+ const primaryDaemonId = daemonIds[0];
6425
+ const paths = primaryDaemonId ? [getPendingEventsPath(meshId, primaryDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
6388
6426
  const events = [];
6389
6427
  for (const path39 of paths) {
6390
6428
  if (!existsSync12(path39)) continue;
@@ -6397,7 +6435,7 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
6397
6435
  return [];
6398
6436
  }
6399
6437
  });
6400
- const filtered = coordinatorDaemonId && path39 === getPendingEventsPath(meshId) ? parsed.filter((e) => !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId) : parsed;
6438
+ const filtered = primaryDaemonId && path39 === getPendingEventsPath(meshId) ? parsed.filter((e) => !e.targetCoordinatorDaemonId || daemonIds.includes(e.targetCoordinatorDaemonId)) : parsed;
6401
6439
  events.push(...filtered);
6402
6440
  } catch {
6403
6441
  }
@@ -6526,8 +6564,59 @@ function atomicDrainFile(path39) {
6526
6564
  return null;
6527
6565
  }
6528
6566
  }
6529
- function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
6567
+ function selectiveDrainFile(path39, predicate) {
6568
+ const tmpPath = `${path39}.draining`;
6569
+ try {
6570
+ renameSync4(path39, tmpPath);
6571
+ } catch {
6572
+ return [];
6573
+ }
6574
+ let content;
6575
+ try {
6576
+ content = readFileSync10(tmpPath, "utf-8");
6577
+ } catch {
6578
+ try {
6579
+ unlinkSync2(tmpPath);
6580
+ } catch {
6581
+ }
6582
+ return [];
6583
+ }
6584
+ const consumed = [];
6585
+ const keptLines = [];
6586
+ for (const line of content.split("\n")) {
6587
+ if (!line) continue;
6588
+ let parsed;
6589
+ try {
6590
+ parsed = JSON.parse(line);
6591
+ } catch {
6592
+ parsed = void 0;
6593
+ }
6594
+ if (parsed && predicate(parsed)) {
6595
+ consumed.push(parsed);
6596
+ } else {
6597
+ keptLines.push(line);
6598
+ }
6599
+ }
6600
+ try {
6601
+ if (keptLines.length > 0) {
6602
+ writeFileSync6(path39, keptLines.join("\n") + "\n", "utf-8");
6603
+ }
6604
+ unlinkSync2(tmpPath);
6605
+ } catch {
6606
+ try {
6607
+ if (existsSync12(tmpPath) && !existsSync12(path39)) renameSync4(tmpPath, path39);
6608
+ } catch {
6609
+ }
6610
+ return [];
6611
+ }
6612
+ return consumed;
6613
+ }
6614
+ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId, opts) {
6530
6615
  if (!meshId) return [];
6616
+ const daemonIds = normalizeCoordinatorDaemonIds(coordinatorDaemonId);
6617
+ const primaryDaemonId = daemonIds[0];
6618
+ const onlyEvents = opts?.onlyEvents;
6619
+ const matchesFilter = (eventName) => !onlyEvents || onlyEvents.has(eventName);
6531
6620
  const merged = [];
6532
6621
  const seenFingerprints = /* @__PURE__ */ new Set();
6533
6622
  const pushUnique = (event) => {
@@ -6541,15 +6630,23 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
6541
6630
  try {
6542
6631
  const store = MeshRuntimeStore.getInstance();
6543
6632
  if (store.pendingEventCount(meshId) > 0) {
6544
- for (const row of store.drainPendingEvents(meshId, coordinatorDaemonId)) {
6633
+ for (const row of store.drainPendingEvents(meshId, daemonIds.length > 0 ? daemonIds : void 0, onlyEvents ? { onlyEvents } : void 0)) {
6545
6634
  const event = row.payload;
6546
6635
  if (event) pushUnique(event);
6547
6636
  }
6548
6637
  }
6549
6638
  } catch {
6550
6639
  }
6551
- const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
6640
+ const paths = primaryDaemonId ? [getPendingEventsPath(meshId, primaryDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
6552
6641
  for (const path39 of paths) {
6642
+ const isSharedFile = !!primaryDaemonId && path39 === getPendingEventsPath(meshId);
6643
+ const targets = (e) => !isSharedFile || !e.targetCoordinatorDaemonId || daemonIds.includes(e.targetCoordinatorDaemonId);
6644
+ if (onlyEvents) {
6645
+ for (const event of selectiveDrainFile(path39, (e) => targets(e) && matchesFilter(e.event))) {
6646
+ pushUnique(event);
6647
+ }
6648
+ continue;
6649
+ }
6553
6650
  const content = atomicDrainFile(path39);
6554
6651
  if (!content) continue;
6555
6652
  const parsed = content.split("\n").filter(Boolean).flatMap((line) => {
@@ -6559,7 +6656,7 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
6559
6656
  return [];
6560
6657
  }
6561
6658
  });
6562
- const filtered = coordinatorDaemonId && path39 === getPendingEventsPath(meshId) ? parsed.filter((e) => !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId) : parsed;
6659
+ const filtered = isSharedFile ? parsed.filter(targets) : parsed;
6563
6660
  for (const event of filtered) pushUnique(event);
6564
6661
  }
6565
6662
  if (merged.length === 0) return [];
@@ -6567,6 +6664,7 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
6567
6664
  }
6568
6665
  function getPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
6569
6666
  if (!meshId) return [];
6667
+ const daemonIds = normalizeCoordinatorDaemonIds(coordinatorDaemonId);
6570
6668
  const merged = [];
6571
6669
  const seenFingerprints = /* @__PURE__ */ new Set();
6572
6670
  const pushUnique = (event) => {
@@ -6580,14 +6678,14 @@ function getPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
6580
6678
  try {
6581
6679
  const store = MeshRuntimeStore.getInstance();
6582
6680
  if (store.pendingEventCount(meshId) > 0) {
6583
- for (const row of store.peekPendingEvents(meshId, coordinatorDaemonId)) {
6681
+ for (const row of store.peekPendingEvents(meshId, daemonIds.length > 0 ? daemonIds : void 0)) {
6584
6682
  const event = row.payload;
6585
6683
  if (event) pushUnique(event);
6586
6684
  }
6587
6685
  }
6588
6686
  } catch {
6589
6687
  }
6590
- for (const event of readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId)) {
6688
+ for (const event of readPendingMeshCoordinatorEventsFromDisk(meshId, daemonIds)) {
6591
6689
  pushUnique(event);
6592
6690
  }
6593
6691
  return reconcilePendingMeshCoordinatorEvents(meshId, merged);
@@ -7286,6 +7384,14 @@ var init_mesh_routing = __esm({
7286
7384
 
7287
7385
  // src/mesh/mesh-events-coordinator.ts
7288
7386
  import { existsSync as existsSync14 } from "fs";
7387
+ function resolveCoordinatorDrainDaemonIds(components) {
7388
+ const ids = /* @__PURE__ */ new Set();
7389
+ const statusInstanceId = readNonEmptyString2(components.statusInstanceId);
7390
+ if (statusInstanceId) ids.add(statusInstanceId);
7391
+ const machineId = readNonEmptyString2(loadConfig().machineId);
7392
+ if (machineId) ids.add(machineId);
7393
+ return [...ids];
7394
+ }
7289
7395
  function getCachedMeshByWorkspace(workspace) {
7290
7396
  const now = Date.now();
7291
7397
  const cached2 = meshByWorkspaceCache.get(workspace);
@@ -8410,8 +8516,8 @@ function setupMeshEventForwarding(components) {
8410
8516
  const status = readNonEmptyString2(flushState.status).toLowerCase();
8411
8517
  if (status === "idle") {
8412
8518
  try {
8413
- const localDaemonId = readNonEmptyString2(loadConfig().machineId) || void 0;
8414
- const pendingEvents = drainPendingMeshCoordinatorEvents(coordinatorMeshId, localDaemonId);
8519
+ const drainDaemonIds = resolveCoordinatorDrainDaemonIds(components);
8520
+ const pendingEvents = drainPendingMeshCoordinatorEvents(coordinatorMeshId, drainDaemonIds.length > 0 ? drainDaemonIds : void 0);
8415
8521
  if (pendingEvents.length > 0) {
8416
8522
  LOG.info("MeshEvents", `Auto-flushing ${pendingEvents.length} pending coordinator event(s) for mesh ${coordinatorMeshId} on coordinator idle`);
8417
8523
  for (const pending of pendingEvents) {
@@ -8526,6 +8632,14 @@ function resolveReconcileIntervalMs() {
8526
8632
  }
8527
8633
  return DEFAULT_RECONCILE_INTERVAL_MS;
8528
8634
  }
8635
+ function resolveCoordinatorDaemonIds(components) {
8636
+ const ids = /* @__PURE__ */ new Set();
8637
+ const statusInstanceId = readNonEmptyString2(components.statusInstanceId);
8638
+ if (statusInstanceId) ids.add(statusInstanceId);
8639
+ const machineId = readNonEmptyString2(loadConfig().machineId);
8640
+ if (machineId) ids.add(machineId);
8641
+ return [...ids];
8642
+ }
8529
8643
  function findLiveCoordinators(components) {
8530
8644
  const out = [];
8531
8645
  for (const inst of components.instanceManager.getByCategory("cli")) {
@@ -8558,6 +8672,7 @@ async function runMeshReconcileTick(components) {
8558
8672
  else byMesh.set(c.meshId, [c]);
8559
8673
  }
8560
8674
  const localDaemonId = readNonEmptyString2(loadConfig().machineId) || void 0;
8675
+ const drainDaemonIds = resolveCoordinatorDaemonIds(components);
8561
8676
  const dispatchMeshCommand = components.dispatchMeshCommand;
8562
8677
  const store = (() => {
8563
8678
  try {
@@ -8575,7 +8690,9 @@ async function runMeshReconcileTick(components) {
8575
8690
  }
8576
8691
  }
8577
8692
  const idleCoordinators = meshCoordinators.filter((c) => c.idle);
8578
- if (idleCoordinators.length === 0) continue;
8693
+ const generatingCoordinators = meshCoordinators.filter((c) => !c.idle);
8694
+ const targetCoordinators = idleCoordinators.length > 0 ? idleCoordinators : generatingCoordinators;
8695
+ const forceOnly = idleCoordinators.length === 0;
8579
8696
  if (store) {
8580
8697
  try {
8581
8698
  if (store.pendingEventCount(meshId) === 0) continue;
@@ -8584,15 +8701,20 @@ async function runMeshReconcileTick(components) {
8584
8701
  }
8585
8702
  let pendingEvents = [];
8586
8703
  try {
8587
- pendingEvents = drainPendingMeshCoordinatorEvents(meshId, localDaemonId);
8704
+ pendingEvents = drainPendingMeshCoordinatorEvents(
8705
+ meshId,
8706
+ drainDaemonIds.length > 0 ? drainDaemonIds : localDaemonId,
8707
+ forceOnly ? { onlyEvents: MESH_FORCE_INJECT_EVENTS } : void 0
8708
+ );
8588
8709
  } catch (e) {
8589
8710
  LOG.warn("MeshReconcile", `Drain failed for mesh ${meshId}: ${e?.message || e}`);
8590
8711
  continue;
8591
8712
  }
8592
8713
  if (pendingEvents.length === 0) continue;
8593
- LOG.info("MeshReconcile", `Reconcile inject: ${pendingEvents.length} pending event(s) \u2192 ${idleCoordinators.length} idle coordinator(s) for mesh ${meshId}`);
8714
+ const mode = forceOnly ? "force-drain \u2192 generating" : "inject \u2192 idle";
8715
+ LOG.info("MeshReconcile", `Reconcile ${mode}: ${pendingEvents.length} pending event(s) \u2192 ${targetCoordinators.length} coordinator(s) for mesh ${meshId}`);
8594
8716
  for (const pending of pendingEvents) {
8595
- for (const c of idleCoordinators) {
8717
+ for (const c of targetCoordinators) {
8596
8718
  injectPendingIntoCoordinator(c.instance, pending);
8597
8719
  }
8598
8720
  }
@@ -55368,7 +55490,8 @@ async function initDaemonComponents(config) {
55368
55490
  detectedIdes: detectedIdesRef,
55369
55491
  refreshProviderAvailability,
55370
55492
  dispatchMeshCommand: config.dispatchMeshCommand,
55371
- onMeshCoordinatorEventForwarded: config.onMeshCoordinatorEventForwarded
55493
+ onMeshCoordinatorEventForwarded: config.onMeshCoordinatorEventForwarded,
55494
+ statusInstanceId: config.statusInstanceId
55372
55495
  };
55373
55496
  setupMeshEventForwarding(components);
55374
55497
  components.meshReconcileLoop = setupMeshReconcileLoop(components);