@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
|
@@ -82,6 +82,9 @@ export interface DaemonComponents {
|
|
|
82
82
|
refreshProviderAvailability: (providerType?: string) => Promise<void>;
|
|
83
83
|
dispatchMeshCommand?: (daemonId: string, command: string, args: Record<string, unknown>) => Promise<any>;
|
|
84
84
|
onMeshCoordinatorEventForwarded?: (payload: Record<string, unknown>) => void;
|
|
85
|
+
meshReconcileLoop?: {
|
|
86
|
+
stop(): void;
|
|
87
|
+
};
|
|
85
88
|
}
|
|
86
89
|
export interface DaemonDevSupportOptions {
|
|
87
90
|
components: DaemonComponents;
|
package/dist/index.js
CHANGED
|
@@ -275,10 +275,10 @@ function readInjected(value) {
|
|
|
275
275
|
}
|
|
276
276
|
function getDaemonBuildInfo() {
|
|
277
277
|
if (cached) return cached;
|
|
278
|
-
const commit = readInjected(true ? "
|
|
279
|
-
const commitShort = readInjected(true ? "
|
|
280
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
281
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
278
|
+
const commit = readInjected(true ? "080b607ef221e44126942d9d52eaf547b4e92550" : void 0) ?? "unknown";
|
|
279
|
+
const commitShort = readInjected(true ? "080b607e" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
280
|
+
const version = readInjected(true ? "0.9.82-rc.275" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
281
|
+
const builtAt = readInjected(true ? "2026-06-15T08:24:26.468Z" : void 0);
|
|
282
282
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
283
283
|
return cached;
|
|
284
284
|
}
|
|
@@ -4264,12 +4264,33 @@ var init_mesh_runtime_store = __esm({
|
|
|
4264
4264
|
this.maybeCheckpointWal();
|
|
4265
4265
|
return result.changes > 0;
|
|
4266
4266
|
}
|
|
4267
|
-
|
|
4267
|
+
/**
|
|
4268
|
+
* Drain undrained pending events for a mesh, atomically marking them drained.
|
|
4269
|
+
* When `opts.onlyEvents` is supplied, ONLY rows whose `event` is in that set are
|
|
4270
|
+
* drained — the rest stay queued (drained=0) for a later drain. This is how the
|
|
4271
|
+
* reconcile loop force-drains terminal/force-inject events into a *generating*
|
|
4272
|
+
* coordinator while leaving non-force progress events for the coordinator's next
|
|
4273
|
+
* idle transition. Filtering happens inside the same transaction as the
|
|
4274
|
+
* drained=1 marking, so force-drain + a concurrent full drain can never both
|
|
4275
|
+
* consume the same row.
|
|
4276
|
+
*/
|
|
4277
|
+
drainPendingEvents(meshId, coordinatorDaemonId, opts) {
|
|
4268
4278
|
return this.transaction(() => {
|
|
4269
|
-
const
|
|
4270
|
-
|
|
4279
|
+
const onlyEvents = opts?.onlyEvents;
|
|
4280
|
+
if (onlyEvents && onlyEvents.size === 0) return [];
|
|
4281
|
+
const eventList = onlyEvents ? [...onlyEvents] : [];
|
|
4282
|
+
const clauses = ["mesh_id = ?", "drained = 0"];
|
|
4283
|
+
const params = [meshId];
|
|
4284
|
+
if (coordinatorDaemonId) {
|
|
4285
|
+
clauses.push("(coordinator_daemon_id IS NULL OR coordinator_daemon_id = ?)");
|
|
4286
|
+
params.push(coordinatorDaemonId);
|
|
4287
|
+
}
|
|
4288
|
+
if (eventList.length > 0) {
|
|
4289
|
+
clauses.push(`event IN (${eventList.map(() => "?").join(",")})`);
|
|
4290
|
+
params.push(...eventList);
|
|
4291
|
+
}
|
|
4271
4292
|
const rows = this.db.prepare(
|
|
4272
|
-
`SELECT id, event, payload FROM mesh_pending_events ${
|
|
4293
|
+
`SELECT id, event, payload FROM mesh_pending_events WHERE ${clauses.join(" AND ")} ORDER BY queued_at ASC LIMIT 100`
|
|
4273
4294
|
).all(...params);
|
|
4274
4295
|
if (rows.length === 0) return [];
|
|
4275
4296
|
const ids = rows.map((r) => r.id);
|
|
@@ -6168,16 +6189,6 @@ function readNonEmptyString2(value) {
|
|
|
6168
6189
|
function readRecord3(value) {
|
|
6169
6190
|
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
6170
6191
|
}
|
|
6171
|
-
function canonicalDaemonId(value) {
|
|
6172
|
-
const id = readNonEmptyString2(value);
|
|
6173
|
-
if (!id) return "";
|
|
6174
|
-
return id.replace(/^(?:daemon|standalone)_/, "");
|
|
6175
|
-
}
|
|
6176
|
-
function sameDaemonId(a, b) {
|
|
6177
|
-
const ca = canonicalDaemonId(a);
|
|
6178
|
-
const cb = canonicalDaemonId(b);
|
|
6179
|
-
return ca !== "" && ca === cb;
|
|
6180
|
-
}
|
|
6181
6192
|
function buildMeshWorkerRelayStamp(currentSettings, meshContext) {
|
|
6182
6193
|
if (!meshContext) return void 0;
|
|
6183
6194
|
const settings = currentSettings && typeof currentSettings === "object" ? currentSettings : {};
|
|
@@ -6378,29 +6389,6 @@ function buildPendingEventFingerprint(event) {
|
|
|
6378
6389
|
timestamp || ""
|
|
6379
6390
|
].join("::");
|
|
6380
6391
|
}
|
|
6381
|
-
function markMeshCoordinatorEventDirectDelivered(coordinatorDaemonId, event) {
|
|
6382
|
-
const canonical = canonicalDaemonId(coordinatorDaemonId);
|
|
6383
|
-
if (!canonical) return;
|
|
6384
|
-
const fingerprint = buildPendingEventFingerprint(event);
|
|
6385
|
-
if (!fingerprint.trim()) return;
|
|
6386
|
-
try {
|
|
6387
|
-
const store = MeshRuntimeStore.getInstance();
|
|
6388
|
-
store.recordDirectDelivered(canonical, fingerprint, DIRECT_DELIVERED_TTL_MS);
|
|
6389
|
-
store.sweepExpiredDirectDelivered();
|
|
6390
|
-
} catch {
|
|
6391
|
-
}
|
|
6392
|
-
}
|
|
6393
|
-
function wasDirectDeliveredToCoordinator(coordinatorDaemonId, event) {
|
|
6394
|
-
const canonical = canonicalDaemonId(coordinatorDaemonId);
|
|
6395
|
-
if (!canonical) return false;
|
|
6396
|
-
const fingerprint = buildPendingEventFingerprint(event);
|
|
6397
|
-
if (!fingerprint.trim()) return false;
|
|
6398
|
-
try {
|
|
6399
|
-
return MeshRuntimeStore.getInstance().wasDirectDelivered(canonical, fingerprint);
|
|
6400
|
-
} catch {
|
|
6401
|
-
return false;
|
|
6402
|
-
}
|
|
6403
|
-
}
|
|
6404
6392
|
function hasPendingCoordinatorEventDuplicate(event) {
|
|
6405
6393
|
const fingerprint = buildPendingEventFingerprint(event);
|
|
6406
6394
|
if (!fingerprint.trim()) return false;
|
|
@@ -6562,8 +6550,57 @@ function atomicDrainFile(path39) {
|
|
|
6562
6550
|
return null;
|
|
6563
6551
|
}
|
|
6564
6552
|
}
|
|
6565
|
-
function
|
|
6553
|
+
function selectiveDrainFile(path39, predicate) {
|
|
6554
|
+
const tmpPath = `${path39}.draining`;
|
|
6555
|
+
try {
|
|
6556
|
+
(0, import_fs8.renameSync)(path39, tmpPath);
|
|
6557
|
+
} catch {
|
|
6558
|
+
return [];
|
|
6559
|
+
}
|
|
6560
|
+
let content;
|
|
6561
|
+
try {
|
|
6562
|
+
content = (0, import_fs8.readFileSync)(tmpPath, "utf-8");
|
|
6563
|
+
} catch {
|
|
6564
|
+
try {
|
|
6565
|
+
(0, import_fs8.unlinkSync)(tmpPath);
|
|
6566
|
+
} catch {
|
|
6567
|
+
}
|
|
6568
|
+
return [];
|
|
6569
|
+
}
|
|
6570
|
+
const consumed = [];
|
|
6571
|
+
const keptLines = [];
|
|
6572
|
+
for (const line of content.split("\n")) {
|
|
6573
|
+
if (!line) continue;
|
|
6574
|
+
let parsed;
|
|
6575
|
+
try {
|
|
6576
|
+
parsed = JSON.parse(line);
|
|
6577
|
+
} catch {
|
|
6578
|
+
parsed = void 0;
|
|
6579
|
+
}
|
|
6580
|
+
if (parsed && predicate(parsed)) {
|
|
6581
|
+
consumed.push(parsed);
|
|
6582
|
+
} else {
|
|
6583
|
+
keptLines.push(line);
|
|
6584
|
+
}
|
|
6585
|
+
}
|
|
6586
|
+
try {
|
|
6587
|
+
if (keptLines.length > 0) {
|
|
6588
|
+
(0, import_fs8.writeFileSync)(path39, keptLines.join("\n") + "\n", "utf-8");
|
|
6589
|
+
}
|
|
6590
|
+
(0, import_fs8.unlinkSync)(tmpPath);
|
|
6591
|
+
} catch {
|
|
6592
|
+
try {
|
|
6593
|
+
if ((0, import_fs8.existsSync)(tmpPath) && !(0, import_fs8.existsSync)(path39)) (0, import_fs8.renameSync)(tmpPath, path39);
|
|
6594
|
+
} catch {
|
|
6595
|
+
}
|
|
6596
|
+
return [];
|
|
6597
|
+
}
|
|
6598
|
+
return consumed;
|
|
6599
|
+
}
|
|
6600
|
+
function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId, opts) {
|
|
6566
6601
|
if (!meshId) return [];
|
|
6602
|
+
const onlyEvents = opts?.onlyEvents;
|
|
6603
|
+
const matchesFilter = (eventName) => !onlyEvents || onlyEvents.has(eventName);
|
|
6567
6604
|
const merged = [];
|
|
6568
6605
|
const seenFingerprints = /* @__PURE__ */ new Set();
|
|
6569
6606
|
const pushUnique = (event) => {
|
|
@@ -6577,7 +6614,7 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
6577
6614
|
try {
|
|
6578
6615
|
const store = MeshRuntimeStore.getInstance();
|
|
6579
6616
|
if (store.pendingEventCount(meshId) > 0) {
|
|
6580
|
-
for (const row of store.drainPendingEvents(meshId, coordinatorDaemonId)) {
|
|
6617
|
+
for (const row of store.drainPendingEvents(meshId, coordinatorDaemonId, onlyEvents ? { onlyEvents } : void 0)) {
|
|
6581
6618
|
const event = row.payload;
|
|
6582
6619
|
if (event) pushUnique(event);
|
|
6583
6620
|
}
|
|
@@ -6586,6 +6623,14 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
6586
6623
|
}
|
|
6587
6624
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
6588
6625
|
for (const path39 of paths) {
|
|
6626
|
+
const isSharedFile = coordinatorDaemonId && path39 === getPendingEventsPath(meshId);
|
|
6627
|
+
const targets = (e) => !isSharedFile || !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId;
|
|
6628
|
+
if (onlyEvents) {
|
|
6629
|
+
for (const event of selectiveDrainFile(path39, (e) => targets(e) && matchesFilter(e.event))) {
|
|
6630
|
+
pushUnique(event);
|
|
6631
|
+
}
|
|
6632
|
+
continue;
|
|
6633
|
+
}
|
|
6589
6634
|
const content = atomicDrainFile(path39);
|
|
6590
6635
|
if (!content) continue;
|
|
6591
6636
|
const parsed = content.split("\n").filter(Boolean).flatMap((line) => {
|
|
@@ -6595,13 +6640,11 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
6595
6640
|
return [];
|
|
6596
6641
|
}
|
|
6597
6642
|
});
|
|
6598
|
-
const filtered =
|
|
6643
|
+
const filtered = isSharedFile ? parsed.filter(targets) : parsed;
|
|
6599
6644
|
for (const event of filtered) pushUnique(event);
|
|
6600
6645
|
}
|
|
6601
6646
|
if (merged.length === 0) return [];
|
|
6602
|
-
|
|
6603
|
-
if (deliverable.length === 0) return [];
|
|
6604
|
-
return reconcilePendingMeshCoordinatorEvents(meshId, deliverable);
|
|
6647
|
+
return reconcilePendingMeshCoordinatorEvents(meshId, merged);
|
|
6605
6648
|
}
|
|
6606
6649
|
function getPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
6607
6650
|
if (!meshId) return [];
|
|
@@ -6628,8 +6671,7 @@ function getPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
6628
6671
|
for (const event of readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId)) {
|
|
6629
6672
|
pushUnique(event);
|
|
6630
6673
|
}
|
|
6631
|
-
|
|
6632
|
-
return reconcilePendingMeshCoordinatorEvents(meshId, deliverable);
|
|
6674
|
+
return reconcilePendingMeshCoordinatorEvents(meshId, merged);
|
|
6633
6675
|
}
|
|
6634
6676
|
function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
6635
6677
|
if (!meshId) return;
|
|
@@ -6645,7 +6687,7 @@ function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
6645
6687
|
}
|
|
6646
6688
|
}
|
|
6647
6689
|
}
|
|
6648
|
-
var import_fs8, import_path8, import_crypto7, REFINE_TERMINAL_EVENTS,
|
|
6690
|
+
var import_fs8, import_path8, import_crypto7, REFINE_TERMINAL_EVENTS, MAX_PENDING_EVENTS_BYTES, MAX_PENDING_EVENTS_KEEP;
|
|
6649
6691
|
var init_mesh_events_pending = __esm({
|
|
6650
6692
|
"src/mesh/mesh-events-pending.ts"() {
|
|
6651
6693
|
"use strict";
|
|
@@ -6657,7 +6699,6 @@ var init_mesh_events_pending = __esm({
|
|
|
6657
6699
|
init_mesh_runtime_store();
|
|
6658
6700
|
init_mesh_events_utils();
|
|
6659
6701
|
REFINE_TERMINAL_EVENTS = /* @__PURE__ */ new Set(["refine:completed", "refine:failed"]);
|
|
6660
|
-
DIRECT_DELIVERED_TTL_MS = 10 * 60 * 1e3;
|
|
6661
6702
|
MAX_PENDING_EVENTS_BYTES = 100 * 1024;
|
|
6662
6703
|
MAX_PENDING_EVENTS_KEEP = 50;
|
|
6663
6704
|
}
|
|
@@ -8019,7 +8060,6 @@ function injectMeshSystemMessage(components, args) {
|
|
|
8019
8060
|
const workerCoordinatorDaemonId = readNonEmptyString2(
|
|
8020
8061
|
sourceSession?.getState()?.settings?.meshCoordinatorDaemonId
|
|
8021
8062
|
);
|
|
8022
|
-
const localDaemonId = readNonEmptyString2(loadConfig().machineId);
|
|
8023
8063
|
if (components.onMeshCoordinatorEventForwarded) {
|
|
8024
8064
|
try {
|
|
8025
8065
|
components.onMeshCoordinatorEventForwarded({
|
|
@@ -8374,60 +8414,6 @@ function injectMeshSystemMessage(components, args) {
|
|
|
8374
8414
|
recoveryContext
|
|
8375
8415
|
});
|
|
8376
8416
|
if (!messageText) return { success: false, error: "unsupported mesh event" };
|
|
8377
|
-
const coordinatorInstances = components.instanceManager.getByCategory("cli").filter((inst) => {
|
|
8378
|
-
const instState = inst.getState();
|
|
8379
|
-
if (instState.settings?.meshCoordinatorFor !== args.meshId) return false;
|
|
8380
|
-
if (args.sourceInstanceId && instState.instanceId === args.sourceInstanceId) return false;
|
|
8381
|
-
if (workerCoordinatorDaemonId && localDaemonId && !sameDaemonId(workerCoordinatorDaemonId, localDaemonId)) return false;
|
|
8382
|
-
return true;
|
|
8383
|
-
});
|
|
8384
|
-
if (coordinatorInstances.length === 0) {
|
|
8385
|
-
const remoteCoordinatorDaemonId = workerCoordinatorDaemonId && localDaemonId && !sameDaemonId(workerCoordinatorDaemonId, localDaemonId) ? workerCoordinatorDaemonId : "";
|
|
8386
|
-
if (remoteCoordinatorDaemonId && components.dispatchMeshCommand) {
|
|
8387
|
-
const forwardPayload = {
|
|
8388
|
-
event: args.event,
|
|
8389
|
-
meshId: args.meshId,
|
|
8390
|
-
nodeId: args.nodeId || void 0,
|
|
8391
|
-
workspace: readNonEmptyString2(args.metadataEvent.workspace),
|
|
8392
|
-
...args.metadataEvent,
|
|
8393
|
-
...recoveryContext ? { recoveryContext } : {}
|
|
8394
|
-
};
|
|
8395
|
-
components.dispatchMeshCommand(remoteCoordinatorDaemonId, "mesh_forward_event", forwardPayload).then(() => {
|
|
8396
|
-
LOG.info("MeshEvents", `Forwarded ${args.event} for mesh ${args.meshId} to remote coordinator daemon ${remoteCoordinatorDaemonId.slice(0, 12)}\u2026`);
|
|
8397
|
-
}).catch((error) => {
|
|
8398
|
-
LOG.warn("MeshEvents", `Remote forward of ${args.event} failed (${error?.message || error}); queuing for backfill`);
|
|
8399
|
-
queuePendingMeshCoordinatorEvent({
|
|
8400
|
-
event: args.event,
|
|
8401
|
-
meshId: args.meshId,
|
|
8402
|
-
nodeLabel: args.nodeLabel,
|
|
8403
|
-
nodeId: args.nodeId || void 0,
|
|
8404
|
-
workspace: readNonEmptyString2(args.metadataEvent.workspace),
|
|
8405
|
-
metadataEvent: { ...args.metadataEvent, ...recoveryContext ? { recoveryContext } : {} },
|
|
8406
|
-
coordinatorMessage: messageText,
|
|
8407
|
-
queuedAt: Date.now(),
|
|
8408
|
-
targetCoordinatorDaemonId: remoteCoordinatorDaemonId
|
|
8409
|
-
});
|
|
8410
|
-
});
|
|
8411
|
-
return { success: true, forwarded: 0, remoteForwarded: true };
|
|
8412
|
-
}
|
|
8413
|
-
if (queuePendingMeshCoordinatorEvent({
|
|
8414
|
-
event: args.event,
|
|
8415
|
-
meshId: args.meshId,
|
|
8416
|
-
nodeLabel: args.nodeLabel,
|
|
8417
|
-
nodeId: args.nodeId || void 0,
|
|
8418
|
-
workspace: readNonEmptyString2(args.metadataEvent.workspace),
|
|
8419
|
-
metadataEvent: {
|
|
8420
|
-
...args.metadataEvent,
|
|
8421
|
-
...recoveryContext ? { recoveryContext } : {}
|
|
8422
|
-
},
|
|
8423
|
-
coordinatorMessage: messageText,
|
|
8424
|
-
queuedAt: Date.now(),
|
|
8425
|
-
...workerCoordinatorDaemonId ? { targetCoordinatorDaemonId: workerCoordinatorDaemonId } : {}
|
|
8426
|
-
})) {
|
|
8427
|
-
LOG.info("MeshEvents", `Queued ${args.event} for MCP coordinator (mesh ${args.meshId}${workerCoordinatorDaemonId ? `, coordinator daemon ${workerCoordinatorDaemonId}` : ""})`);
|
|
8428
|
-
}
|
|
8429
|
-
return { success: true, forwarded: 0 };
|
|
8430
|
-
}
|
|
8431
8417
|
const pendingEvent = {
|
|
8432
8418
|
event: args.event,
|
|
8433
8419
|
meshId: args.meshId,
|
|
@@ -8443,21 +8429,9 @@ function injectMeshSystemMessage(components, args) {
|
|
|
8443
8429
|
...workerCoordinatorDaemonId ? { targetCoordinatorDaemonId: workerCoordinatorDaemonId } : {}
|
|
8444
8430
|
};
|
|
8445
8431
|
if (queuePendingMeshCoordinatorEvent(pendingEvent)) {
|
|
8446
|
-
LOG.info("MeshEvents", `Queued ${args.event} for
|
|
8447
|
-
}
|
|
8448
|
-
if (localDaemonId) {
|
|
8449
|
-
markMeshCoordinatorEventDirectDelivered(localDaemonId, pendingEvent);
|
|
8450
|
-
}
|
|
8451
|
-
const forceInject = shouldForceInjectMeshEvent(args.event);
|
|
8452
|
-
for (const coord of coordinatorInstances) {
|
|
8453
|
-
const coordState = coord.getState();
|
|
8454
|
-
LOG.info("MeshEvents", `Forwarding mesh event to coordinator ${coordState.instanceId}${forceInject ? " (force)" : ""}`);
|
|
8455
|
-
coord.onEvent("send_message", {
|
|
8456
|
-
input: { text: messageText, textFallback: messageText },
|
|
8457
|
-
...forceInject ? { force: true } : {}
|
|
8458
|
-
});
|
|
8432
|
+
LOG.info("MeshEvents", `Queued ${args.event} for coordinator (mesh ${args.meshId}${workerCoordinatorDaemonId ? `, coordinator daemon ${workerCoordinatorDaemonId}` : ""})`);
|
|
8459
8433
|
}
|
|
8460
|
-
return { success: true, forwarded:
|
|
8434
|
+
return { success: true, forwarded: 0 };
|
|
8461
8435
|
}
|
|
8462
8436
|
function handleMeshForwardEvent(components, payload) {
|
|
8463
8437
|
const eventName = readNonEmptyString2(payload.event);
|
|
@@ -8628,6 +8602,176 @@ var init_mesh_events_coordinator = __esm({
|
|
|
8628
8602
|
}
|
|
8629
8603
|
});
|
|
8630
8604
|
|
|
8605
|
+
// src/mesh/mesh-reconcile-loop.ts
|
|
8606
|
+
function resolveReconcileIntervalMs() {
|
|
8607
|
+
const raw = readNonEmptyString2(process.env.MESH_RECONCILE_INTERVAL_MS);
|
|
8608
|
+
if (raw) {
|
|
8609
|
+
const parsed = Number.parseInt(raw, 10);
|
|
8610
|
+
if (Number.isFinite(parsed) && parsed >= 1e3 && parsed <= 6e4) return parsed;
|
|
8611
|
+
}
|
|
8612
|
+
return DEFAULT_RECONCILE_INTERVAL_MS;
|
|
8613
|
+
}
|
|
8614
|
+
function findLiveCoordinators(components) {
|
|
8615
|
+
const out = [];
|
|
8616
|
+
for (const inst of components.instanceManager.getByCategory("cli")) {
|
|
8617
|
+
const state = inst.getState();
|
|
8618
|
+
const settings = state.settings && typeof state.settings === "object" ? state.settings : {};
|
|
8619
|
+
const meshId = readNonEmptyString2(settings.meshCoordinatorFor);
|
|
8620
|
+
if (!meshId) continue;
|
|
8621
|
+
const status = readNonEmptyString2(state.status).toLowerCase();
|
|
8622
|
+
out.push({ meshId, instance: inst, idle: status === "idle" });
|
|
8623
|
+
}
|
|
8624
|
+
return out;
|
|
8625
|
+
}
|
|
8626
|
+
function injectPendingIntoCoordinator(coordinator, pending) {
|
|
8627
|
+
if (!coordinator || !pending.coordinatorMessage) return;
|
|
8628
|
+
const force = shouldForceInjectMeshEvent(pending.event);
|
|
8629
|
+
coordinator.onEvent("send_message", {
|
|
8630
|
+
input: { text: pending.coordinatorMessage, textFallback: pending.coordinatorMessage },
|
|
8631
|
+
...force ? { force: true } : {}
|
|
8632
|
+
});
|
|
8633
|
+
}
|
|
8634
|
+
async function runMeshReconcileTick(components) {
|
|
8635
|
+
const coordinators = findLiveCoordinators(components);
|
|
8636
|
+
if (coordinators.length === 0) {
|
|
8637
|
+
return;
|
|
8638
|
+
}
|
|
8639
|
+
const byMesh = /* @__PURE__ */ new Map();
|
|
8640
|
+
for (const c of coordinators) {
|
|
8641
|
+
const list = byMesh.get(c.meshId);
|
|
8642
|
+
if (list) list.push(c);
|
|
8643
|
+
else byMesh.set(c.meshId, [c]);
|
|
8644
|
+
}
|
|
8645
|
+
const localDaemonId = readNonEmptyString2(loadConfig().machineId) || void 0;
|
|
8646
|
+
const dispatchMeshCommand = components.dispatchMeshCommand;
|
|
8647
|
+
const store = (() => {
|
|
8648
|
+
try {
|
|
8649
|
+
return MeshRuntimeStore.getInstance();
|
|
8650
|
+
} catch {
|
|
8651
|
+
return void 0;
|
|
8652
|
+
}
|
|
8653
|
+
})();
|
|
8654
|
+
for (const [meshId, meshCoordinators] of byMesh) {
|
|
8655
|
+
if (dispatchMeshCommand) {
|
|
8656
|
+
try {
|
|
8657
|
+
await pullRemoteNodeQueues(components, meshId, localDaemonId);
|
|
8658
|
+
} catch (e) {
|
|
8659
|
+
LOG.warn("MeshReconcile", `Remote node pull failed for mesh ${meshId}: ${e?.message || e}`);
|
|
8660
|
+
}
|
|
8661
|
+
}
|
|
8662
|
+
const idleCoordinators = meshCoordinators.filter((c) => c.idle);
|
|
8663
|
+
const generatingCoordinators = meshCoordinators.filter((c) => !c.idle);
|
|
8664
|
+
const targetCoordinators = idleCoordinators.length > 0 ? idleCoordinators : generatingCoordinators;
|
|
8665
|
+
const forceOnly = idleCoordinators.length === 0;
|
|
8666
|
+
if (store) {
|
|
8667
|
+
try {
|
|
8668
|
+
if (store.pendingEventCount(meshId) === 0) continue;
|
|
8669
|
+
} catch {
|
|
8670
|
+
}
|
|
8671
|
+
}
|
|
8672
|
+
let pendingEvents = [];
|
|
8673
|
+
try {
|
|
8674
|
+
pendingEvents = drainPendingMeshCoordinatorEvents(
|
|
8675
|
+
meshId,
|
|
8676
|
+
localDaemonId,
|
|
8677
|
+
forceOnly ? { onlyEvents: MESH_FORCE_INJECT_EVENTS } : void 0
|
|
8678
|
+
);
|
|
8679
|
+
} catch (e) {
|
|
8680
|
+
LOG.warn("MeshReconcile", `Drain failed for mesh ${meshId}: ${e?.message || e}`);
|
|
8681
|
+
continue;
|
|
8682
|
+
}
|
|
8683
|
+
if (pendingEvents.length === 0) continue;
|
|
8684
|
+
const mode = forceOnly ? "force-drain \u2192 generating" : "inject \u2192 idle";
|
|
8685
|
+
LOG.info("MeshReconcile", `Reconcile ${mode}: ${pendingEvents.length} pending event(s) \u2192 ${targetCoordinators.length} coordinator(s) for mesh ${meshId}`);
|
|
8686
|
+
for (const pending of pendingEvents) {
|
|
8687
|
+
for (const c of targetCoordinators) {
|
|
8688
|
+
injectPendingIntoCoordinator(c.instance, pending);
|
|
8689
|
+
}
|
|
8690
|
+
}
|
|
8691
|
+
}
|
|
8692
|
+
}
|
|
8693
|
+
async function pullRemoteNodeQueues(components, meshId, localDaemonId) {
|
|
8694
|
+
const dispatchMeshCommand = components.dispatchMeshCommand;
|
|
8695
|
+
if (!dispatchMeshCommand) return;
|
|
8696
|
+
const mesh = listMeshes().find((m) => m.id === meshId);
|
|
8697
|
+
if (!mesh) return;
|
|
8698
|
+
const pendingEventArgs = {
|
|
8699
|
+
meshId,
|
|
8700
|
+
...localDaemonId ? { coordinatorDaemonId: localDaemonId } : {}
|
|
8701
|
+
};
|
|
8702
|
+
for (const node of mesh.nodes) {
|
|
8703
|
+
const nodeDaemonId = readNonEmptyString2(node.daemonId);
|
|
8704
|
+
if (!nodeDaemonId) continue;
|
|
8705
|
+
if (localDaemonId && nodeDaemonId === localDaemonId) continue;
|
|
8706
|
+
let events;
|
|
8707
|
+
try {
|
|
8708
|
+
events = await dispatchMeshCommand(nodeDaemonId, "get_pending_mesh_events", pendingEventArgs);
|
|
8709
|
+
} catch {
|
|
8710
|
+
continue;
|
|
8711
|
+
}
|
|
8712
|
+
const list = extractPendingEvents(events).filter((e) => readNonEmptyString2(e?.meshId) === meshId);
|
|
8713
|
+
for (const event of list) {
|
|
8714
|
+
const payload = buildForwardPayloadFromPending(event);
|
|
8715
|
+
if (!payload.event || !payload.meshId) continue;
|
|
8716
|
+
try {
|
|
8717
|
+
handleMeshForwardEvent(components, payload);
|
|
8718
|
+
} catch {
|
|
8719
|
+
}
|
|
8720
|
+
}
|
|
8721
|
+
}
|
|
8722
|
+
}
|
|
8723
|
+
function extractPendingEvents(raw) {
|
|
8724
|
+
if (Array.isArray(raw)) return raw;
|
|
8725
|
+
if (raw && typeof raw === "object") {
|
|
8726
|
+
const events = raw.events;
|
|
8727
|
+
if (Array.isArray(events)) return events;
|
|
8728
|
+
}
|
|
8729
|
+
return [];
|
|
8730
|
+
}
|
|
8731
|
+
function buildForwardPayloadFromPending(event) {
|
|
8732
|
+
const metadata = event?.metadataEvent && typeof event.metadataEvent === "object" ? event.metadataEvent : {};
|
|
8733
|
+
return {
|
|
8734
|
+
event: readNonEmptyString2(event?.event),
|
|
8735
|
+
meshId: readNonEmptyString2(event?.meshId),
|
|
8736
|
+
nodeId: readNonEmptyString2(event?.nodeId) || readNonEmptyString2(metadata.meshNodeId),
|
|
8737
|
+
workspace: readNonEmptyString2(event?.workspace) || readNonEmptyString2(metadata.workspace),
|
|
8738
|
+
...metadata
|
|
8739
|
+
};
|
|
8740
|
+
}
|
|
8741
|
+
function setupMeshReconcileLoop(components) {
|
|
8742
|
+
const intervalMs = resolveReconcileIntervalMs();
|
|
8743
|
+
let running = false;
|
|
8744
|
+
const timer = setInterval(() => {
|
|
8745
|
+
if (running) return;
|
|
8746
|
+
running = true;
|
|
8747
|
+
void runMeshReconcileTick(components).catch((e) => LOG.warn("MeshReconcile", `Reconcile tick error: ${e?.message || e}`)).finally(() => {
|
|
8748
|
+
running = false;
|
|
8749
|
+
});
|
|
8750
|
+
}, intervalMs);
|
|
8751
|
+
if (typeof timer.unref === "function") timer.unref();
|
|
8752
|
+
LOG.info("MeshReconcile", `Mesh reconcile loop started (interval ${intervalMs}ms)`);
|
|
8753
|
+
return {
|
|
8754
|
+
stop() {
|
|
8755
|
+
clearInterval(timer);
|
|
8756
|
+
LOG.info("MeshReconcile", "Mesh reconcile loop stopped");
|
|
8757
|
+
}
|
|
8758
|
+
};
|
|
8759
|
+
}
|
|
8760
|
+
var DEFAULT_RECONCILE_INTERVAL_MS;
|
|
8761
|
+
var init_mesh_reconcile_loop = __esm({
|
|
8762
|
+
"src/mesh/mesh-reconcile-loop.ts"() {
|
|
8763
|
+
"use strict";
|
|
8764
|
+
init_config();
|
|
8765
|
+
init_mesh_config();
|
|
8766
|
+
init_logger();
|
|
8767
|
+
init_mesh_events_pending();
|
|
8768
|
+
init_mesh_runtime_store();
|
|
8769
|
+
init_mesh_events_coordinator();
|
|
8770
|
+
init_mesh_events_utils();
|
|
8771
|
+
DEFAULT_RECONCILE_INTERVAL_MS = 4e3;
|
|
8772
|
+
}
|
|
8773
|
+
});
|
|
8774
|
+
|
|
8631
8775
|
// src/mesh/mesh-events.ts
|
|
8632
8776
|
var mesh_events_exports = {};
|
|
8633
8777
|
__export(mesh_events_exports, {
|
|
@@ -8638,10 +8782,11 @@ __export(mesh_events_exports, {
|
|
|
8638
8782
|
getPendingMeshCoordinatorEvents: () => getPendingMeshCoordinatorEvents,
|
|
8639
8783
|
handleMeshForwardEvent: () => handleMeshForwardEvent,
|
|
8640
8784
|
isMeshCoordinatorEvent: () => isMeshCoordinatorEvent,
|
|
8641
|
-
markMeshCoordinatorEventDirectDelivered: () => markMeshCoordinatorEventDirectDelivered,
|
|
8642
8785
|
queuePendingMeshCoordinatorEvent: () => queuePendingMeshCoordinatorEvent,
|
|
8643
8786
|
reconcileDirectDispatchCompletionFromTranscript: () => reconcileDirectDispatchCompletionFromTranscript,
|
|
8787
|
+
runMeshReconcileTick: () => runMeshReconcileTick,
|
|
8644
8788
|
setupMeshEventForwarding: () => setupMeshEventForwarding,
|
|
8789
|
+
setupMeshReconcileLoop: () => setupMeshReconcileLoop,
|
|
8645
8790
|
triggerMeshQueue: () => triggerMeshQueue,
|
|
8646
8791
|
tryAssignQueueTask: () => tryAssignQueueTask
|
|
8647
8792
|
});
|
|
@@ -8650,6 +8795,7 @@ var init_mesh_events = __esm({
|
|
|
8650
8795
|
"use strict";
|
|
8651
8796
|
init_mesh_events_pending();
|
|
8652
8797
|
init_mesh_events_stale();
|
|
8798
|
+
init_mesh_reconcile_loop();
|
|
8653
8799
|
init_mesh_events_coordinator();
|
|
8654
8800
|
}
|
|
8655
8801
|
});
|
|
@@ -55437,6 +55583,7 @@ var SessionRegistry = class {
|
|
|
55437
55583
|
init_logger();
|
|
55438
55584
|
init_config();
|
|
55439
55585
|
init_mesh_events();
|
|
55586
|
+
init_mesh_reconcile_loop();
|
|
55440
55587
|
|
|
55441
55588
|
// src/boot/process-hardening.ts
|
|
55442
55589
|
var _hardened = false;
|
|
@@ -55638,6 +55785,7 @@ async function initDaemonComponents(config) {
|
|
|
55638
55785
|
onMeshCoordinatorEventForwarded: config.onMeshCoordinatorEventForwarded
|
|
55639
55786
|
};
|
|
55640
55787
|
setupMeshEventForwarding(components);
|
|
55788
|
+
components.meshReconcileLoop = setupMeshReconcileLoop(components);
|
|
55641
55789
|
setImmediate(() => void router.resumePendingRefineJobsOnStartup());
|
|
55642
55790
|
return components;
|
|
55643
55791
|
}
|
|
@@ -55663,10 +55811,15 @@ async function shutdownDaemonComponents(components) {
|
|
|
55663
55811
|
agentStreamManager,
|
|
55664
55812
|
cliManager,
|
|
55665
55813
|
instanceManager,
|
|
55666
|
-
cdpManagers
|
|
55814
|
+
cdpManagers,
|
|
55815
|
+
meshReconcileLoop
|
|
55667
55816
|
} = components;
|
|
55668
55817
|
poller.stop();
|
|
55669
55818
|
cdpInitializer.stop();
|
|
55819
|
+
try {
|
|
55820
|
+
meshReconcileLoop?.stop();
|
|
55821
|
+
} catch {
|
|
55822
|
+
}
|
|
55670
55823
|
try {
|
|
55671
55824
|
if (agentStreamManager) {
|
|
55672
55825
|
await agentStreamManager.dispose(cdpManagers);
|