@adhdev/daemon-core 0.9.76-rc.67 → 0.9.76-rc.69

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.
@@ -1,4 +1,13 @@
1
1
  import type { DaemonComponents } from '../boot/daemon-lifecycle.js';
2
+ export interface PendingMeshCoordinatorEvent {
3
+ event: string;
4
+ meshId: string;
5
+ nodeLabel: string;
6
+ metadataEvent: Record<string, unknown>;
7
+ queuedAt: number;
8
+ }
9
+ /** Drain and return all pending coordinator events, clearing the queue. */
10
+ export declare function drainPendingMeshCoordinatorEvents(): PendingMeshCoordinatorEvent[];
2
11
  export declare function handleMeshForwardEvent(components: DaemonComponents, payload: Record<string, unknown>): {
3
12
  success: boolean;
4
13
  forwarded: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.9.76-rc.67",
3
+ "version": "0.9.76-rc.69",
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",
@@ -285,8 +285,10 @@ export class TerminalTranscriptAccumulator {
285
285
  return;
286
286
  }
287
287
  while (line.length < this.col) line.push(' ');
288
+ const wide = isWideCodePoint(ch);
288
289
  line[this.col] = ch;
289
- this.col += isWideCodePoint(ch) ? 2 : 1;
290
+ if (wide) line[this.col + 1] = '';
291
+ this.col += wide ? 2 : 1;
290
292
  }
291
293
 
292
294
  private consumeEscape(seq: string): number {
@@ -36,7 +36,7 @@ import { createInteractionId, getRecentDebugTrace, recordDebugTrace } from '../l
36
36
  import { getSessionHostSurfaceKind, partitionSessionHostRecords } from '../session-host/runtime-surface.js';
37
37
  import { createHermesManualMeshCoordinatorSetup, resolveMeshCoordinatorSetup } from './mesh-coordinator.js';
38
38
  import { buildSessionEntries } from '../status/builders.js';
39
- import { handleMeshForwardEvent } from '../mesh/mesh-events.js';
39
+ import { handleMeshForwardEvent, drainPendingMeshCoordinatorEvents } from '../mesh/mesh-events.js';
40
40
  import { buildMachineInfo, buildStatusSnapshot } from '../status/snapshot.js';
41
41
  import { getSessionCompletionMarker } from '../status/snapshot.js';
42
42
  import { execNpmCommandSync, resolveCurrentGlobalInstallSurface, spawnDetachedDaemonUpgradeHelper } from './upgrade-helper.js';
@@ -651,6 +651,11 @@ export class DaemonCommandRouter {
651
651
  return handleMeshForwardEvent({ instanceManager: this.deps.instanceManager } as any, args as Record<string, unknown>);
652
652
  }
653
653
 
654
+ case 'get_pending_mesh_events': {
655
+ const events = drainPendingMeshCoordinatorEvents();
656
+ return { success: true, events };
657
+ }
658
+
654
659
  case 'launch_cli':
655
660
  case 'stop_cli':
656
661
  case 'set_cli_view_mode':
@@ -2,6 +2,30 @@ import type { DaemonComponents } from '../boot/daemon-lifecycle.js';
2
2
  import { getMesh, getMeshByRepo } from '../config/mesh-config.js';
3
3
  import { LOG } from '../logging/logger.js';
4
4
 
5
+ // ---------------------------------------------------------------------------
6
+ // MCP coordinator pending-event queue
7
+ // ---------------------------------------------------------------------------
8
+ // When a mesh event fires but no CLI coordinator session is registered (e.g.
9
+ // the coordinator is Claude Code running via MCP), we buffer the event here.
10
+ // The MCP server drains this queue on every mesh_status / mesh_send_task poll.
11
+ // ---------------------------------------------------------------------------
12
+
13
+ export interface PendingMeshCoordinatorEvent {
14
+ event: string;
15
+ meshId: string;
16
+ nodeLabel: string;
17
+ metadataEvent: Record<string, unknown>;
18
+ queuedAt: number;
19
+ }
20
+
21
+ const MAX_PENDING_EVENTS = 50;
22
+ const pendingMeshCoordinatorEvents: PendingMeshCoordinatorEvent[] = [];
23
+
24
+ /** Drain and return all pending coordinator events, clearing the queue. */
25
+ export function drainPendingMeshCoordinatorEvents(): PendingMeshCoordinatorEvent[] {
26
+ return pendingMeshCoordinatorEvents.splice(0);
27
+ }
28
+
5
29
  function readNonEmptyString(value: unknown): string {
6
30
  return typeof value === 'string' && value.trim() ? value.trim() : '';
7
31
  }
@@ -61,7 +85,20 @@ function injectMeshSystemMessage(components: DaemonComponents, args: {
61
85
  return true;
62
86
  });
63
87
 
64
- if (coordinatorInstances.length === 0) return { success: true, forwarded: 0 };
88
+ if (coordinatorInstances.length === 0) {
89
+ // No CLI coordinator session found — buffer for MCP-based coordinators.
90
+ if (pendingMeshCoordinatorEvents.length < MAX_PENDING_EVENTS) {
91
+ pendingMeshCoordinatorEvents.push({
92
+ event: args.event,
93
+ meshId: args.meshId,
94
+ nodeLabel: args.nodeLabel,
95
+ metadataEvent: args.metadataEvent,
96
+ queuedAt: Date.now(),
97
+ });
98
+ LOG.info('MeshEvents', `Queued ${args.event} for MCP coordinator (mesh ${args.meshId})`);
99
+ }
100
+ return { success: true, forwarded: 0 };
101
+ }
65
102
 
66
103
  const messageText = buildMeshSystemMessage({
67
104
  event: args.event,