@adhdev/daemon-core 0.9.82-rc.250 → 0.9.82-rc.252
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.js +20 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +20 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/commands/router.ts +7 -11
- package/src/mesh/mesh-events-coordinator.ts +22 -22
- package/src/mesh/mesh-events-pending.ts +6 -0
package/package.json
CHANGED
package/src/commands/router.ts
CHANGED
|
@@ -7301,19 +7301,15 @@ export class DaemonCommandRouter {
|
|
|
7301
7301
|
nodeStatuses.push(status);
|
|
7302
7302
|
}
|
|
7303
7303
|
|
|
7304
|
-
// (B3) Resolve the coordinator daemon scope for the
|
|
7305
|
-
//
|
|
7306
|
-
//
|
|
7307
|
-
//
|
|
7308
|
-
//
|
|
7309
|
-
// they're running under, fall back to *this daemon's*
|
|
7310
|
-
// ID — the caller reached us over our IPC/WS, so they
|
|
7311
|
-
// are by definition under this daemon. Falling back to
|
|
7312
|
-
// undefined would silently miss every scoped event.
|
|
7304
|
+
// (B3) Resolve the coordinator daemon scope for the peek.
|
|
7305
|
+
// mesh_status is a read-only status query — it must not consume
|
|
7306
|
+
// (drain) pending events as a side effect. Coordinators that see
|
|
7307
|
+
// pendingCoordinatorEvents in the response are expected to call
|
|
7308
|
+
// get_pending_mesh_events to explicitly drain them after processing.
|
|
7313
7309
|
const callerCoordinatorDaemonId = typeof args?.coordinatorDaemonId === 'string' && args.coordinatorDaemonId.trim()
|
|
7314
7310
|
? args.coordinatorDaemonId.trim()
|
|
7315
7311
|
: (this.deps.statusInstanceId || undefined);
|
|
7316
|
-
const pendingCoordinatorEvents =
|
|
7312
|
+
const pendingCoordinatorEvents = getPendingMeshCoordinatorEvents(meshId, callerCoordinatorDaemonId);
|
|
7317
7313
|
const previewFreshness = (() => {
|
|
7318
7314
|
const localRepoRoot = nodeStatuses
|
|
7319
7315
|
.map((node: any) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace))
|
|
@@ -7323,7 +7319,7 @@ export class DaemonCommandRouter {
|
|
|
7323
7319
|
const asyncRefineJobs = buildMeshAsyncRefineJobs({
|
|
7324
7320
|
meshId,
|
|
7325
7321
|
ledgerEntries: asyncRefineLedgerEntries,
|
|
7326
|
-
pendingEvents: pendingCoordinatorEvents,
|
|
7322
|
+
pendingEvents: [...pendingCoordinatorEvents],
|
|
7327
7323
|
});
|
|
7328
7324
|
const historicalSessions = buildHistoricalMeshSessions({
|
|
7329
7325
|
meshId,
|
|
@@ -1338,28 +1338,28 @@ function injectMeshSystemMessage(components: DaemonComponents, args: {
|
|
|
1338
1338
|
return { success: true, forwarded: 0 };
|
|
1339
1339
|
}
|
|
1340
1340
|
|
|
1341
|
-
//
|
|
1342
|
-
//
|
|
1343
|
-
//
|
|
1344
|
-
//
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
},
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
}
|
|
1361
|
-
|
|
1362
|
-
}
|
|
1341
|
+
// All events — terminal and non-terminal — are queued for MCP coordinator
|
|
1342
|
+
// delivery via the pending-events file/SQLite path. This ensures that MCP
|
|
1343
|
+
// coordinators (which poll via get_pending_mesh_events / mesh_status) always
|
|
1344
|
+
// receive terminal events even when a live CLI coordinator session is present.
|
|
1345
|
+
// Previously, terminal events skipped the queue and were only direct-injected
|
|
1346
|
+
// into live CLI coordinators via send_message, which silently dropped them
|
|
1347
|
+
// when the coordinator was in a generating state.
|
|
1348
|
+
if (queuePendingMeshCoordinatorEvent({
|
|
1349
|
+
event: args.event,
|
|
1350
|
+
meshId: args.meshId,
|
|
1351
|
+
nodeLabel: args.nodeLabel,
|
|
1352
|
+
nodeId: args.nodeId || undefined,
|
|
1353
|
+
workspace: readNonEmptyString(args.metadataEvent.workspace),
|
|
1354
|
+
metadataEvent: {
|
|
1355
|
+
...args.metadataEvent,
|
|
1356
|
+
...(recoveryContext ? { recoveryContext } : {}),
|
|
1357
|
+
},
|
|
1358
|
+
coordinatorMessage: messageText,
|
|
1359
|
+
queuedAt: Date.now(),
|
|
1360
|
+
...(workerCoordinatorDaemonId ? { targetCoordinatorDaemonId: workerCoordinatorDaemonId } : {}),
|
|
1361
|
+
})) {
|
|
1362
|
+
LOG.info('MeshEvents', `Queued ${args.event} for MCP coordinator (mesh ${args.meshId})`);
|
|
1363
1363
|
}
|
|
1364
1364
|
|
|
1365
1365
|
for (const coord of coordinatorInstances) {
|
|
@@ -60,6 +60,12 @@ function hasPendingRefineTerminalEventDuplicate(event: PendingMeshCoordinatorEve
|
|
|
60
60
|
|
|
61
61
|
export function buildPendingEventFingerprint(event: PendingMeshCoordinatorEvent): string {
|
|
62
62
|
const metadata = readRecord(event.metadataEvent) || {};
|
|
63
|
+
// Bootstrap events are node-scoped: dedup by meshId+event+nodeId only.
|
|
64
|
+
// They carry no sessionId/taskId/timestamp — using those fields would produce
|
|
65
|
+
// an empty fingerprint that defeats dedup entirely.
|
|
66
|
+
if (event.event === 'worktree_bootstrap_complete' || event.event === 'worktree_bootstrap_failed') {
|
|
67
|
+
return [event.meshId, event.event, event.nodeId || ''].join('::');
|
|
68
|
+
}
|
|
63
69
|
const sessionId = resolveEventSessionId(metadata);
|
|
64
70
|
const providerSessionId = readNonEmptyString(metadata.providerSessionId);
|
|
65
71
|
const taskId = readNonEmptyString(metadata.taskId) || readNonEmptyString(readRecord(metadata.payload)?.taskId);
|