@adhdev/daemon-core 0.9.82-rc.273 → 0.9.82-rc.275
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/boot/daemon-lifecycle.d.ts +3 -0
- package/dist/index.js +275 -122
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +275 -122
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-events-coordinator.d.ts +2 -21
- package/dist/mesh/mesh-events-pending.d.ts +14 -9
- package/dist/mesh/mesh-events.d.ts +2 -1
- package/dist/mesh/mesh-reconcile-loop.d.ts +7 -0
- package/dist/mesh/mesh-runtime-store.d.ts +13 -1
- package/package.json +2 -2
- package/src/boot/daemon-lifecycle.ts +16 -2
- package/src/mesh/mesh-events-coordinator.ts +32 -108
- package/src/mesh/mesh-events-pending.ts +98 -62
- package/src/mesh/mesh-events.ts +5 -1
- package/src/mesh/mesh-reconcile-loop.ts +276 -0
- package/src/mesh/mesh-runtime-store.ts +33 -8
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 ? "
|
|
274
|
-
const commitShort = readInjected(true ? "
|
|
275
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
276
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
273
|
+
const commit = readInjected(true ? "080b607ef221e44126942d9d52eaf547b4e92550" : void 0) ?? "unknown";
|
|
274
|
+
const commitShort = readInjected(true ? "080b607e" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
275
|
+
const version = readInjected(true ? "0.9.82-rc.275" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
276
|
+
const builtAt = readInjected(true ? "2026-06-15T08:24:26.468Z" : void 0);
|
|
277
277
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
278
278
|
return cached;
|
|
279
279
|
}
|
|
@@ -4258,12 +4258,33 @@ var init_mesh_runtime_store = __esm({
|
|
|
4258
4258
|
this.maybeCheckpointWal();
|
|
4259
4259
|
return result.changes > 0;
|
|
4260
4260
|
}
|
|
4261
|
-
|
|
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
|
|
4264
|
-
|
|
4273
|
+
const onlyEvents = opts?.onlyEvents;
|
|
4274
|
+
if (onlyEvents && onlyEvents.size === 0) return [];
|
|
4275
|
+
const eventList = onlyEvents ? [...onlyEvents] : [];
|
|
4276
|
+
const clauses = ["mesh_id = ?", "drained = 0"];
|
|
4277
|
+
const params = [meshId];
|
|
4278
|
+
if (coordinatorDaemonId) {
|
|
4279
|
+
clauses.push("(coordinator_daemon_id IS NULL OR coordinator_daemon_id = ?)");
|
|
4280
|
+
params.push(coordinatorDaemonId);
|
|
4281
|
+
}
|
|
4282
|
+
if (eventList.length > 0) {
|
|
4283
|
+
clauses.push(`event IN (${eventList.map(() => "?").join(",")})`);
|
|
4284
|
+
params.push(...eventList);
|
|
4285
|
+
}
|
|
4265
4286
|
const rows = this.db.prepare(
|
|
4266
|
-
`SELECT id, event, payload FROM mesh_pending_events ${
|
|
4287
|
+
`SELECT id, event, payload FROM mesh_pending_events WHERE ${clauses.join(" AND ")} ORDER BY queued_at ASC LIMIT 100`
|
|
4267
4288
|
).all(...params);
|
|
4268
4289
|
if (rows.length === 0) return [];
|
|
4269
4290
|
const ids = rows.map((r) => r.id);
|
|
@@ -6162,16 +6183,6 @@ function readNonEmptyString2(value) {
|
|
|
6162
6183
|
function readRecord3(value) {
|
|
6163
6184
|
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
6164
6185
|
}
|
|
6165
|
-
function canonicalDaemonId(value) {
|
|
6166
|
-
const id = readNonEmptyString2(value);
|
|
6167
|
-
if (!id) return "";
|
|
6168
|
-
return id.replace(/^(?:daemon|standalone)_/, "");
|
|
6169
|
-
}
|
|
6170
|
-
function sameDaemonId(a, b) {
|
|
6171
|
-
const ca = canonicalDaemonId(a);
|
|
6172
|
-
const cb = canonicalDaemonId(b);
|
|
6173
|
-
return ca !== "" && ca === cb;
|
|
6174
|
-
}
|
|
6175
6186
|
function buildMeshWorkerRelayStamp(currentSettings, meshContext) {
|
|
6176
6187
|
if (!meshContext) return void 0;
|
|
6177
6188
|
const settings = currentSettings && typeof currentSettings === "object" ? currentSettings : {};
|
|
@@ -6375,29 +6386,6 @@ function buildPendingEventFingerprint(event) {
|
|
|
6375
6386
|
timestamp || ""
|
|
6376
6387
|
].join("::");
|
|
6377
6388
|
}
|
|
6378
|
-
function markMeshCoordinatorEventDirectDelivered(coordinatorDaemonId, event) {
|
|
6379
|
-
const canonical = canonicalDaemonId(coordinatorDaemonId);
|
|
6380
|
-
if (!canonical) return;
|
|
6381
|
-
const fingerprint = buildPendingEventFingerprint(event);
|
|
6382
|
-
if (!fingerprint.trim()) return;
|
|
6383
|
-
try {
|
|
6384
|
-
const store = MeshRuntimeStore.getInstance();
|
|
6385
|
-
store.recordDirectDelivered(canonical, fingerprint, DIRECT_DELIVERED_TTL_MS);
|
|
6386
|
-
store.sweepExpiredDirectDelivered();
|
|
6387
|
-
} catch {
|
|
6388
|
-
}
|
|
6389
|
-
}
|
|
6390
|
-
function wasDirectDeliveredToCoordinator(coordinatorDaemonId, event) {
|
|
6391
|
-
const canonical = canonicalDaemonId(coordinatorDaemonId);
|
|
6392
|
-
if (!canonical) return false;
|
|
6393
|
-
const fingerprint = buildPendingEventFingerprint(event);
|
|
6394
|
-
if (!fingerprint.trim()) return false;
|
|
6395
|
-
try {
|
|
6396
|
-
return MeshRuntimeStore.getInstance().wasDirectDelivered(canonical, fingerprint);
|
|
6397
|
-
} catch {
|
|
6398
|
-
return false;
|
|
6399
|
-
}
|
|
6400
|
-
}
|
|
6401
6389
|
function hasPendingCoordinatorEventDuplicate(event) {
|
|
6402
6390
|
const fingerprint = buildPendingEventFingerprint(event);
|
|
6403
6391
|
if (!fingerprint.trim()) return false;
|
|
@@ -6559,8 +6547,57 @@ function atomicDrainFile(path39) {
|
|
|
6559
6547
|
return null;
|
|
6560
6548
|
}
|
|
6561
6549
|
}
|
|
6562
|
-
function
|
|
6550
|
+
function selectiveDrainFile(path39, predicate) {
|
|
6551
|
+
const tmpPath = `${path39}.draining`;
|
|
6552
|
+
try {
|
|
6553
|
+
renameSync4(path39, tmpPath);
|
|
6554
|
+
} catch {
|
|
6555
|
+
return [];
|
|
6556
|
+
}
|
|
6557
|
+
let content;
|
|
6558
|
+
try {
|
|
6559
|
+
content = readFileSync10(tmpPath, "utf-8");
|
|
6560
|
+
} catch {
|
|
6561
|
+
try {
|
|
6562
|
+
unlinkSync2(tmpPath);
|
|
6563
|
+
} catch {
|
|
6564
|
+
}
|
|
6565
|
+
return [];
|
|
6566
|
+
}
|
|
6567
|
+
const consumed = [];
|
|
6568
|
+
const keptLines = [];
|
|
6569
|
+
for (const line of content.split("\n")) {
|
|
6570
|
+
if (!line) continue;
|
|
6571
|
+
let parsed;
|
|
6572
|
+
try {
|
|
6573
|
+
parsed = JSON.parse(line);
|
|
6574
|
+
} catch {
|
|
6575
|
+
parsed = void 0;
|
|
6576
|
+
}
|
|
6577
|
+
if (parsed && predicate(parsed)) {
|
|
6578
|
+
consumed.push(parsed);
|
|
6579
|
+
} else {
|
|
6580
|
+
keptLines.push(line);
|
|
6581
|
+
}
|
|
6582
|
+
}
|
|
6583
|
+
try {
|
|
6584
|
+
if (keptLines.length > 0) {
|
|
6585
|
+
writeFileSync6(path39, keptLines.join("\n") + "\n", "utf-8");
|
|
6586
|
+
}
|
|
6587
|
+
unlinkSync2(tmpPath);
|
|
6588
|
+
} catch {
|
|
6589
|
+
try {
|
|
6590
|
+
if (existsSync12(tmpPath) && !existsSync12(path39)) renameSync4(tmpPath, path39);
|
|
6591
|
+
} catch {
|
|
6592
|
+
}
|
|
6593
|
+
return [];
|
|
6594
|
+
}
|
|
6595
|
+
return consumed;
|
|
6596
|
+
}
|
|
6597
|
+
function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId, opts) {
|
|
6563
6598
|
if (!meshId) return [];
|
|
6599
|
+
const onlyEvents = opts?.onlyEvents;
|
|
6600
|
+
const matchesFilter = (eventName) => !onlyEvents || onlyEvents.has(eventName);
|
|
6564
6601
|
const merged = [];
|
|
6565
6602
|
const seenFingerprints = /* @__PURE__ */ new Set();
|
|
6566
6603
|
const pushUnique = (event) => {
|
|
@@ -6574,7 +6611,7 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
6574
6611
|
try {
|
|
6575
6612
|
const store = MeshRuntimeStore.getInstance();
|
|
6576
6613
|
if (store.pendingEventCount(meshId) > 0) {
|
|
6577
|
-
for (const row of store.drainPendingEvents(meshId, coordinatorDaemonId)) {
|
|
6614
|
+
for (const row of store.drainPendingEvents(meshId, coordinatorDaemonId, onlyEvents ? { onlyEvents } : void 0)) {
|
|
6578
6615
|
const event = row.payload;
|
|
6579
6616
|
if (event) pushUnique(event);
|
|
6580
6617
|
}
|
|
@@ -6583,6 +6620,14 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
6583
6620
|
}
|
|
6584
6621
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
6585
6622
|
for (const path39 of paths) {
|
|
6623
|
+
const isSharedFile = coordinatorDaemonId && path39 === getPendingEventsPath(meshId);
|
|
6624
|
+
const targets = (e) => !isSharedFile || !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId;
|
|
6625
|
+
if (onlyEvents) {
|
|
6626
|
+
for (const event of selectiveDrainFile(path39, (e) => targets(e) && matchesFilter(e.event))) {
|
|
6627
|
+
pushUnique(event);
|
|
6628
|
+
}
|
|
6629
|
+
continue;
|
|
6630
|
+
}
|
|
6586
6631
|
const content = atomicDrainFile(path39);
|
|
6587
6632
|
if (!content) continue;
|
|
6588
6633
|
const parsed = content.split("\n").filter(Boolean).flatMap((line) => {
|
|
@@ -6592,13 +6637,11 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
6592
6637
|
return [];
|
|
6593
6638
|
}
|
|
6594
6639
|
});
|
|
6595
|
-
const filtered =
|
|
6640
|
+
const filtered = isSharedFile ? parsed.filter(targets) : parsed;
|
|
6596
6641
|
for (const event of filtered) pushUnique(event);
|
|
6597
6642
|
}
|
|
6598
6643
|
if (merged.length === 0) return [];
|
|
6599
|
-
|
|
6600
|
-
if (deliverable.length === 0) return [];
|
|
6601
|
-
return reconcilePendingMeshCoordinatorEvents(meshId, deliverable);
|
|
6644
|
+
return reconcilePendingMeshCoordinatorEvents(meshId, merged);
|
|
6602
6645
|
}
|
|
6603
6646
|
function getPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
6604
6647
|
if (!meshId) return [];
|
|
@@ -6625,8 +6668,7 @@ function getPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
6625
6668
|
for (const event of readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId)) {
|
|
6626
6669
|
pushUnique(event);
|
|
6627
6670
|
}
|
|
6628
|
-
|
|
6629
|
-
return reconcilePendingMeshCoordinatorEvents(meshId, deliverable);
|
|
6671
|
+
return reconcilePendingMeshCoordinatorEvents(meshId, merged);
|
|
6630
6672
|
}
|
|
6631
6673
|
function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
6632
6674
|
if (!meshId) return;
|
|
@@ -6642,7 +6684,7 @@ function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
6642
6684
|
}
|
|
6643
6685
|
}
|
|
6644
6686
|
}
|
|
6645
|
-
var REFINE_TERMINAL_EVENTS,
|
|
6687
|
+
var REFINE_TERMINAL_EVENTS, MAX_PENDING_EVENTS_BYTES, MAX_PENDING_EVENTS_KEEP;
|
|
6646
6688
|
var init_mesh_events_pending = __esm({
|
|
6647
6689
|
"src/mesh/mesh-events-pending.ts"() {
|
|
6648
6690
|
"use strict";
|
|
@@ -6651,7 +6693,6 @@ var init_mesh_events_pending = __esm({
|
|
|
6651
6693
|
init_mesh_runtime_store();
|
|
6652
6694
|
init_mesh_events_utils();
|
|
6653
6695
|
REFINE_TERMINAL_EVENTS = /* @__PURE__ */ new Set(["refine:completed", "refine:failed"]);
|
|
6654
|
-
DIRECT_DELIVERED_TTL_MS = 10 * 60 * 1e3;
|
|
6655
6696
|
MAX_PENDING_EVENTS_BYTES = 100 * 1024;
|
|
6656
6697
|
MAX_PENDING_EVENTS_KEEP = 50;
|
|
6657
6698
|
}
|
|
@@ -8013,7 +8054,6 @@ function injectMeshSystemMessage(components, args) {
|
|
|
8013
8054
|
const workerCoordinatorDaemonId = readNonEmptyString2(
|
|
8014
8055
|
sourceSession?.getState()?.settings?.meshCoordinatorDaemonId
|
|
8015
8056
|
);
|
|
8016
|
-
const localDaemonId = readNonEmptyString2(loadConfig().machineId);
|
|
8017
8057
|
if (components.onMeshCoordinatorEventForwarded) {
|
|
8018
8058
|
try {
|
|
8019
8059
|
components.onMeshCoordinatorEventForwarded({
|
|
@@ -8368,60 +8408,6 @@ function injectMeshSystemMessage(components, args) {
|
|
|
8368
8408
|
recoveryContext
|
|
8369
8409
|
});
|
|
8370
8410
|
if (!messageText) return { success: false, error: "unsupported mesh event" };
|
|
8371
|
-
const coordinatorInstances = components.instanceManager.getByCategory("cli").filter((inst) => {
|
|
8372
|
-
const instState = inst.getState();
|
|
8373
|
-
if (instState.settings?.meshCoordinatorFor !== args.meshId) return false;
|
|
8374
|
-
if (args.sourceInstanceId && instState.instanceId === args.sourceInstanceId) return false;
|
|
8375
|
-
if (workerCoordinatorDaemonId && localDaemonId && !sameDaemonId(workerCoordinatorDaemonId, localDaemonId)) return false;
|
|
8376
|
-
return true;
|
|
8377
|
-
});
|
|
8378
|
-
if (coordinatorInstances.length === 0) {
|
|
8379
|
-
const remoteCoordinatorDaemonId = workerCoordinatorDaemonId && localDaemonId && !sameDaemonId(workerCoordinatorDaemonId, localDaemonId) ? workerCoordinatorDaemonId : "";
|
|
8380
|
-
if (remoteCoordinatorDaemonId && components.dispatchMeshCommand) {
|
|
8381
|
-
const forwardPayload = {
|
|
8382
|
-
event: args.event,
|
|
8383
|
-
meshId: args.meshId,
|
|
8384
|
-
nodeId: args.nodeId || void 0,
|
|
8385
|
-
workspace: readNonEmptyString2(args.metadataEvent.workspace),
|
|
8386
|
-
...args.metadataEvent,
|
|
8387
|
-
...recoveryContext ? { recoveryContext } : {}
|
|
8388
|
-
};
|
|
8389
|
-
components.dispatchMeshCommand(remoteCoordinatorDaemonId, "mesh_forward_event", forwardPayload).then(() => {
|
|
8390
|
-
LOG.info("MeshEvents", `Forwarded ${args.event} for mesh ${args.meshId} to remote coordinator daemon ${remoteCoordinatorDaemonId.slice(0, 12)}\u2026`);
|
|
8391
|
-
}).catch((error) => {
|
|
8392
|
-
LOG.warn("MeshEvents", `Remote forward of ${args.event} failed (${error?.message || error}); queuing for backfill`);
|
|
8393
|
-
queuePendingMeshCoordinatorEvent({
|
|
8394
|
-
event: args.event,
|
|
8395
|
-
meshId: args.meshId,
|
|
8396
|
-
nodeLabel: args.nodeLabel,
|
|
8397
|
-
nodeId: args.nodeId || void 0,
|
|
8398
|
-
workspace: readNonEmptyString2(args.metadataEvent.workspace),
|
|
8399
|
-
metadataEvent: { ...args.metadataEvent, ...recoveryContext ? { recoveryContext } : {} },
|
|
8400
|
-
coordinatorMessage: messageText,
|
|
8401
|
-
queuedAt: Date.now(),
|
|
8402
|
-
targetCoordinatorDaemonId: remoteCoordinatorDaemonId
|
|
8403
|
-
});
|
|
8404
|
-
});
|
|
8405
|
-
return { success: true, forwarded: 0, remoteForwarded: true };
|
|
8406
|
-
}
|
|
8407
|
-
if (queuePendingMeshCoordinatorEvent({
|
|
8408
|
-
event: args.event,
|
|
8409
|
-
meshId: args.meshId,
|
|
8410
|
-
nodeLabel: args.nodeLabel,
|
|
8411
|
-
nodeId: args.nodeId || void 0,
|
|
8412
|
-
workspace: readNonEmptyString2(args.metadataEvent.workspace),
|
|
8413
|
-
metadataEvent: {
|
|
8414
|
-
...args.metadataEvent,
|
|
8415
|
-
...recoveryContext ? { recoveryContext } : {}
|
|
8416
|
-
},
|
|
8417
|
-
coordinatorMessage: messageText,
|
|
8418
|
-
queuedAt: Date.now(),
|
|
8419
|
-
...workerCoordinatorDaemonId ? { targetCoordinatorDaemonId: workerCoordinatorDaemonId } : {}
|
|
8420
|
-
})) {
|
|
8421
|
-
LOG.info("MeshEvents", `Queued ${args.event} for MCP coordinator (mesh ${args.meshId}${workerCoordinatorDaemonId ? `, coordinator daemon ${workerCoordinatorDaemonId}` : ""})`);
|
|
8422
|
-
}
|
|
8423
|
-
return { success: true, forwarded: 0 };
|
|
8424
|
-
}
|
|
8425
8411
|
const pendingEvent = {
|
|
8426
8412
|
event: args.event,
|
|
8427
8413
|
meshId: args.meshId,
|
|
@@ -8437,21 +8423,9 @@ function injectMeshSystemMessage(components, args) {
|
|
|
8437
8423
|
...workerCoordinatorDaemonId ? { targetCoordinatorDaemonId: workerCoordinatorDaemonId } : {}
|
|
8438
8424
|
};
|
|
8439
8425
|
if (queuePendingMeshCoordinatorEvent(pendingEvent)) {
|
|
8440
|
-
LOG.info("MeshEvents", `Queued ${args.event} for
|
|
8441
|
-
}
|
|
8442
|
-
if (localDaemonId) {
|
|
8443
|
-
markMeshCoordinatorEventDirectDelivered(localDaemonId, pendingEvent);
|
|
8444
|
-
}
|
|
8445
|
-
const forceInject = shouldForceInjectMeshEvent(args.event);
|
|
8446
|
-
for (const coord of coordinatorInstances) {
|
|
8447
|
-
const coordState = coord.getState();
|
|
8448
|
-
LOG.info("MeshEvents", `Forwarding mesh event to coordinator ${coordState.instanceId}${forceInject ? " (force)" : ""}`);
|
|
8449
|
-
coord.onEvent("send_message", {
|
|
8450
|
-
input: { text: messageText, textFallback: messageText },
|
|
8451
|
-
...forceInject ? { force: true } : {}
|
|
8452
|
-
});
|
|
8426
|
+
LOG.info("MeshEvents", `Queued ${args.event} for coordinator (mesh ${args.meshId}${workerCoordinatorDaemonId ? `, coordinator daemon ${workerCoordinatorDaemonId}` : ""})`);
|
|
8453
8427
|
}
|
|
8454
|
-
return { success: true, forwarded:
|
|
8428
|
+
return { success: true, forwarded: 0 };
|
|
8455
8429
|
}
|
|
8456
8430
|
function handleMeshForwardEvent(components, payload) {
|
|
8457
8431
|
const eventName = readNonEmptyString2(payload.event);
|
|
@@ -8621,6 +8595,176 @@ var init_mesh_events_coordinator = __esm({
|
|
|
8621
8595
|
}
|
|
8622
8596
|
});
|
|
8623
8597
|
|
|
8598
|
+
// src/mesh/mesh-reconcile-loop.ts
|
|
8599
|
+
function resolveReconcileIntervalMs() {
|
|
8600
|
+
const raw = readNonEmptyString2(process.env.MESH_RECONCILE_INTERVAL_MS);
|
|
8601
|
+
if (raw) {
|
|
8602
|
+
const parsed = Number.parseInt(raw, 10);
|
|
8603
|
+
if (Number.isFinite(parsed) && parsed >= 1e3 && parsed <= 6e4) return parsed;
|
|
8604
|
+
}
|
|
8605
|
+
return DEFAULT_RECONCILE_INTERVAL_MS;
|
|
8606
|
+
}
|
|
8607
|
+
function findLiveCoordinators(components) {
|
|
8608
|
+
const out = [];
|
|
8609
|
+
for (const inst of components.instanceManager.getByCategory("cli")) {
|
|
8610
|
+
const state = inst.getState();
|
|
8611
|
+
const settings = state.settings && typeof state.settings === "object" ? state.settings : {};
|
|
8612
|
+
const meshId = readNonEmptyString2(settings.meshCoordinatorFor);
|
|
8613
|
+
if (!meshId) continue;
|
|
8614
|
+
const status = readNonEmptyString2(state.status).toLowerCase();
|
|
8615
|
+
out.push({ meshId, instance: inst, idle: status === "idle" });
|
|
8616
|
+
}
|
|
8617
|
+
return out;
|
|
8618
|
+
}
|
|
8619
|
+
function injectPendingIntoCoordinator(coordinator, pending) {
|
|
8620
|
+
if (!coordinator || !pending.coordinatorMessage) return;
|
|
8621
|
+
const force = shouldForceInjectMeshEvent(pending.event);
|
|
8622
|
+
coordinator.onEvent("send_message", {
|
|
8623
|
+
input: { text: pending.coordinatorMessage, textFallback: pending.coordinatorMessage },
|
|
8624
|
+
...force ? { force: true } : {}
|
|
8625
|
+
});
|
|
8626
|
+
}
|
|
8627
|
+
async function runMeshReconcileTick(components) {
|
|
8628
|
+
const coordinators = findLiveCoordinators(components);
|
|
8629
|
+
if (coordinators.length === 0) {
|
|
8630
|
+
return;
|
|
8631
|
+
}
|
|
8632
|
+
const byMesh = /* @__PURE__ */ new Map();
|
|
8633
|
+
for (const c of coordinators) {
|
|
8634
|
+
const list = byMesh.get(c.meshId);
|
|
8635
|
+
if (list) list.push(c);
|
|
8636
|
+
else byMesh.set(c.meshId, [c]);
|
|
8637
|
+
}
|
|
8638
|
+
const localDaemonId = readNonEmptyString2(loadConfig().machineId) || void 0;
|
|
8639
|
+
const dispatchMeshCommand = components.dispatchMeshCommand;
|
|
8640
|
+
const store = (() => {
|
|
8641
|
+
try {
|
|
8642
|
+
return MeshRuntimeStore.getInstance();
|
|
8643
|
+
} catch {
|
|
8644
|
+
return void 0;
|
|
8645
|
+
}
|
|
8646
|
+
})();
|
|
8647
|
+
for (const [meshId, meshCoordinators] of byMesh) {
|
|
8648
|
+
if (dispatchMeshCommand) {
|
|
8649
|
+
try {
|
|
8650
|
+
await pullRemoteNodeQueues(components, meshId, localDaemonId);
|
|
8651
|
+
} catch (e) {
|
|
8652
|
+
LOG.warn("MeshReconcile", `Remote node pull failed for mesh ${meshId}: ${e?.message || e}`);
|
|
8653
|
+
}
|
|
8654
|
+
}
|
|
8655
|
+
const idleCoordinators = meshCoordinators.filter((c) => c.idle);
|
|
8656
|
+
const generatingCoordinators = meshCoordinators.filter((c) => !c.idle);
|
|
8657
|
+
const targetCoordinators = idleCoordinators.length > 0 ? idleCoordinators : generatingCoordinators;
|
|
8658
|
+
const forceOnly = idleCoordinators.length === 0;
|
|
8659
|
+
if (store) {
|
|
8660
|
+
try {
|
|
8661
|
+
if (store.pendingEventCount(meshId) === 0) continue;
|
|
8662
|
+
} catch {
|
|
8663
|
+
}
|
|
8664
|
+
}
|
|
8665
|
+
let pendingEvents = [];
|
|
8666
|
+
try {
|
|
8667
|
+
pendingEvents = drainPendingMeshCoordinatorEvents(
|
|
8668
|
+
meshId,
|
|
8669
|
+
localDaemonId,
|
|
8670
|
+
forceOnly ? { onlyEvents: MESH_FORCE_INJECT_EVENTS } : void 0
|
|
8671
|
+
);
|
|
8672
|
+
} catch (e) {
|
|
8673
|
+
LOG.warn("MeshReconcile", `Drain failed for mesh ${meshId}: ${e?.message || e}`);
|
|
8674
|
+
continue;
|
|
8675
|
+
}
|
|
8676
|
+
if (pendingEvents.length === 0) continue;
|
|
8677
|
+
const mode = forceOnly ? "force-drain \u2192 generating" : "inject \u2192 idle";
|
|
8678
|
+
LOG.info("MeshReconcile", `Reconcile ${mode}: ${pendingEvents.length} pending event(s) \u2192 ${targetCoordinators.length} coordinator(s) for mesh ${meshId}`);
|
|
8679
|
+
for (const pending of pendingEvents) {
|
|
8680
|
+
for (const c of targetCoordinators) {
|
|
8681
|
+
injectPendingIntoCoordinator(c.instance, pending);
|
|
8682
|
+
}
|
|
8683
|
+
}
|
|
8684
|
+
}
|
|
8685
|
+
}
|
|
8686
|
+
async function pullRemoteNodeQueues(components, meshId, localDaemonId) {
|
|
8687
|
+
const dispatchMeshCommand = components.dispatchMeshCommand;
|
|
8688
|
+
if (!dispatchMeshCommand) return;
|
|
8689
|
+
const mesh = listMeshes().find((m) => m.id === meshId);
|
|
8690
|
+
if (!mesh) return;
|
|
8691
|
+
const pendingEventArgs = {
|
|
8692
|
+
meshId,
|
|
8693
|
+
...localDaemonId ? { coordinatorDaemonId: localDaemonId } : {}
|
|
8694
|
+
};
|
|
8695
|
+
for (const node of mesh.nodes) {
|
|
8696
|
+
const nodeDaemonId = readNonEmptyString2(node.daemonId);
|
|
8697
|
+
if (!nodeDaemonId) continue;
|
|
8698
|
+
if (localDaemonId && nodeDaemonId === localDaemonId) continue;
|
|
8699
|
+
let events;
|
|
8700
|
+
try {
|
|
8701
|
+
events = await dispatchMeshCommand(nodeDaemonId, "get_pending_mesh_events", pendingEventArgs);
|
|
8702
|
+
} catch {
|
|
8703
|
+
continue;
|
|
8704
|
+
}
|
|
8705
|
+
const list = extractPendingEvents(events).filter((e) => readNonEmptyString2(e?.meshId) === meshId);
|
|
8706
|
+
for (const event of list) {
|
|
8707
|
+
const payload = buildForwardPayloadFromPending(event);
|
|
8708
|
+
if (!payload.event || !payload.meshId) continue;
|
|
8709
|
+
try {
|
|
8710
|
+
handleMeshForwardEvent(components, payload);
|
|
8711
|
+
} catch {
|
|
8712
|
+
}
|
|
8713
|
+
}
|
|
8714
|
+
}
|
|
8715
|
+
}
|
|
8716
|
+
function extractPendingEvents(raw) {
|
|
8717
|
+
if (Array.isArray(raw)) return raw;
|
|
8718
|
+
if (raw && typeof raw === "object") {
|
|
8719
|
+
const events = raw.events;
|
|
8720
|
+
if (Array.isArray(events)) return events;
|
|
8721
|
+
}
|
|
8722
|
+
return [];
|
|
8723
|
+
}
|
|
8724
|
+
function buildForwardPayloadFromPending(event) {
|
|
8725
|
+
const metadata = event?.metadataEvent && typeof event.metadataEvent === "object" ? event.metadataEvent : {};
|
|
8726
|
+
return {
|
|
8727
|
+
event: readNonEmptyString2(event?.event),
|
|
8728
|
+
meshId: readNonEmptyString2(event?.meshId),
|
|
8729
|
+
nodeId: readNonEmptyString2(event?.nodeId) || readNonEmptyString2(metadata.meshNodeId),
|
|
8730
|
+
workspace: readNonEmptyString2(event?.workspace) || readNonEmptyString2(metadata.workspace),
|
|
8731
|
+
...metadata
|
|
8732
|
+
};
|
|
8733
|
+
}
|
|
8734
|
+
function setupMeshReconcileLoop(components) {
|
|
8735
|
+
const intervalMs = resolveReconcileIntervalMs();
|
|
8736
|
+
let running = false;
|
|
8737
|
+
const timer = setInterval(() => {
|
|
8738
|
+
if (running) return;
|
|
8739
|
+
running = true;
|
|
8740
|
+
void runMeshReconcileTick(components).catch((e) => LOG.warn("MeshReconcile", `Reconcile tick error: ${e?.message || e}`)).finally(() => {
|
|
8741
|
+
running = false;
|
|
8742
|
+
});
|
|
8743
|
+
}, intervalMs);
|
|
8744
|
+
if (typeof timer.unref === "function") timer.unref();
|
|
8745
|
+
LOG.info("MeshReconcile", `Mesh reconcile loop started (interval ${intervalMs}ms)`);
|
|
8746
|
+
return {
|
|
8747
|
+
stop() {
|
|
8748
|
+
clearInterval(timer);
|
|
8749
|
+
LOG.info("MeshReconcile", "Mesh reconcile loop stopped");
|
|
8750
|
+
}
|
|
8751
|
+
};
|
|
8752
|
+
}
|
|
8753
|
+
var DEFAULT_RECONCILE_INTERVAL_MS;
|
|
8754
|
+
var init_mesh_reconcile_loop = __esm({
|
|
8755
|
+
"src/mesh/mesh-reconcile-loop.ts"() {
|
|
8756
|
+
"use strict";
|
|
8757
|
+
init_config();
|
|
8758
|
+
init_mesh_config();
|
|
8759
|
+
init_logger();
|
|
8760
|
+
init_mesh_events_pending();
|
|
8761
|
+
init_mesh_runtime_store();
|
|
8762
|
+
init_mesh_events_coordinator();
|
|
8763
|
+
init_mesh_events_utils();
|
|
8764
|
+
DEFAULT_RECONCILE_INTERVAL_MS = 4e3;
|
|
8765
|
+
}
|
|
8766
|
+
});
|
|
8767
|
+
|
|
8624
8768
|
// src/mesh/mesh-events.ts
|
|
8625
8769
|
var mesh_events_exports = {};
|
|
8626
8770
|
__export(mesh_events_exports, {
|
|
@@ -8631,10 +8775,11 @@ __export(mesh_events_exports, {
|
|
|
8631
8775
|
getPendingMeshCoordinatorEvents: () => getPendingMeshCoordinatorEvents,
|
|
8632
8776
|
handleMeshForwardEvent: () => handleMeshForwardEvent,
|
|
8633
8777
|
isMeshCoordinatorEvent: () => isMeshCoordinatorEvent,
|
|
8634
|
-
markMeshCoordinatorEventDirectDelivered: () => markMeshCoordinatorEventDirectDelivered,
|
|
8635
8778
|
queuePendingMeshCoordinatorEvent: () => queuePendingMeshCoordinatorEvent,
|
|
8636
8779
|
reconcileDirectDispatchCompletionFromTranscript: () => reconcileDirectDispatchCompletionFromTranscript,
|
|
8780
|
+
runMeshReconcileTick: () => runMeshReconcileTick,
|
|
8637
8781
|
setupMeshEventForwarding: () => setupMeshEventForwarding,
|
|
8782
|
+
setupMeshReconcileLoop: () => setupMeshReconcileLoop,
|
|
8638
8783
|
triggerMeshQueue: () => triggerMeshQueue,
|
|
8639
8784
|
tryAssignQueueTask: () => tryAssignQueueTask
|
|
8640
8785
|
});
|
|
@@ -8643,6 +8788,7 @@ var init_mesh_events = __esm({
|
|
|
8643
8788
|
"use strict";
|
|
8644
8789
|
init_mesh_events_pending();
|
|
8645
8790
|
init_mesh_events_stale();
|
|
8791
|
+
init_mesh_reconcile_loop();
|
|
8646
8792
|
init_mesh_events_coordinator();
|
|
8647
8793
|
}
|
|
8648
8794
|
});
|
|
@@ -55108,6 +55254,7 @@ var SessionRegistry = class {
|
|
|
55108
55254
|
init_logger();
|
|
55109
55255
|
init_config();
|
|
55110
55256
|
init_mesh_events();
|
|
55257
|
+
init_mesh_reconcile_loop();
|
|
55111
55258
|
|
|
55112
55259
|
// src/boot/process-hardening.ts
|
|
55113
55260
|
var _hardened = false;
|
|
@@ -55309,6 +55456,7 @@ async function initDaemonComponents(config) {
|
|
|
55309
55456
|
onMeshCoordinatorEventForwarded: config.onMeshCoordinatorEventForwarded
|
|
55310
55457
|
};
|
|
55311
55458
|
setupMeshEventForwarding(components);
|
|
55459
|
+
components.meshReconcileLoop = setupMeshReconcileLoop(components);
|
|
55312
55460
|
setImmediate(() => void router.resumePendingRefineJobsOnStartup());
|
|
55313
55461
|
return components;
|
|
55314
55462
|
}
|
|
@@ -55334,10 +55482,15 @@ async function shutdownDaemonComponents(components) {
|
|
|
55334
55482
|
agentStreamManager,
|
|
55335
55483
|
cliManager,
|
|
55336
55484
|
instanceManager,
|
|
55337
|
-
cdpManagers
|
|
55485
|
+
cdpManagers,
|
|
55486
|
+
meshReconcileLoop
|
|
55338
55487
|
} = components;
|
|
55339
55488
|
poller.stop();
|
|
55340
55489
|
cdpInitializer.stop();
|
|
55490
|
+
try {
|
|
55491
|
+
meshReconcileLoop?.stop();
|
|
55492
|
+
} catch {
|
|
55493
|
+
}
|
|
55341
55494
|
try {
|
|
55342
55495
|
if (agentStreamManager) {
|
|
55343
55496
|
await agentStreamManager.dispose(cdpManagers);
|