@adhdev/daemon-core 0.9.82-rc.250 → 0.9.82-rc.251

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.9.82-rc.250",
3
+ "version": "0.9.82-rc.251",
4
4
  "description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1338,28 +1338,28 @@ function injectMeshSystemMessage(components: DaemonComponents, args: {
1338
1338
  return { success: true, forwarded: 0 };
1339
1339
  }
1340
1340
 
1341
- // Non-terminal events are also queued for MCP coordinator dual delivery.
1342
- // Terminal events are forwarded directly without buffering — previously
1343
- // they were buffered when coordinators were generating and auto-flushed on
1344
- // idle, but auto-flush was unreliable and events were silently lost.
1345
- const isTerminalEvent = new Set(['refine:completed', 'refine:failed', 'agent:generating_completed', 'agent:stopped']).has(args.event);
1346
- if (!isTerminalEvent) {
1347
- if (queuePendingMeshCoordinatorEvent({
1348
- event: args.event,
1349
- meshId: args.meshId,
1350
- nodeLabel: args.nodeLabel,
1351
- nodeId: args.nodeId || undefined,
1352
- workspace: readNonEmptyString(args.metadataEvent.workspace),
1353
- metadataEvent: {
1354
- ...args.metadataEvent,
1355
- ...(recoveryContext ? { recoveryContext } : {}),
1356
- },
1357
- coordinatorMessage: messageText,
1358
- queuedAt: Date.now(),
1359
- ...(workerCoordinatorDaemonId ? { targetCoordinatorDaemonId: workerCoordinatorDaemonId } : {}),
1360
- })) {
1361
- LOG.info('MeshEvents', `Queued ${args.event} for MCP coordinator (mesh ${args.meshId})`);
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);