crewly 1.4.58 → 1.4.60

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.
Files changed (25) hide show
  1. package/dist/backend/backend/src/controllers/cloud/cloud.controller.d.ts.map +1 -1
  2. package/dist/backend/backend/src/controllers/cloud/cloud.controller.js +8 -0
  3. package/dist/backend/backend/src/controllers/cloud/cloud.controller.js.map +1 -1
  4. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
  5. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +41 -0
  6. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
  7. package/dist/backend/backend/src/services/cloud/cloud-initializer.d.ts +10 -0
  8. package/dist/backend/backend/src/services/cloud/cloud-initializer.d.ts.map +1 -1
  9. package/dist/backend/backend/src/services/cloud/cloud-initializer.js +72 -8
  10. package/dist/backend/backend/src/services/cloud/cloud-initializer.js.map +1 -1
  11. package/dist/backend/backend/src/services/cloud/cloud-sync.service.d.ts.map +1 -1
  12. package/dist/backend/backend/src/services/cloud/cloud-sync.service.js +20 -6
  13. package/dist/backend/backend/src/services/cloud/cloud-sync.service.js.map +1 -1
  14. package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts +39 -1
  15. package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
  16. package/dist/backend/backend/src/services/cloud/cloud-sync.types.js +16 -0
  17. package/dist/backend/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
  18. package/dist/backend/backend/src/services/messaging/message-router.service.d.ts +157 -0
  19. package/dist/backend/backend/src/services/messaging/message-router.service.d.ts.map +1 -0
  20. package/dist/backend/backend/src/services/messaging/message-router.service.js +317 -0
  21. package/dist/backend/backend/src/services/messaging/message-router.service.js.map +1 -0
  22. package/frontend/dist/assets/{index-78e43622.css → index-e2a673d6.css} +1 -1
  23. package/frontend/dist/assets/{index-988e322e.js → index-e830dc67.js} +309 -309
  24. package/frontend/dist/index.html +2 -2
  25. package/package.json +1 -1
@@ -26,6 +26,15 @@ export interface CloudSyncConfig {
26
26
  /** Human-readable device name (OS hostname) */
27
27
  deviceName: string;
28
28
  }
29
+ /** Summary of an agent running on a device, included in heartbeat payloads. */
30
+ export interface SyncAgentInfo {
31
+ /** Agent PTY session name (e.g. "crewly-product-leo-member-n") */
32
+ sessionName: string;
33
+ /** Agent role (e.g. "developer", "orchestrator") */
34
+ role: string;
35
+ /** Agent working status */
36
+ workingStatus: string;
37
+ }
29
38
  /** Summary of a team on a device, included in heartbeat payloads. */
30
39
  export interface SyncTeamSummary {
31
40
  /** Team identifier */
@@ -36,6 +45,8 @@ export interface SyncTeamSummary {
36
45
  memberCount: number;
37
46
  /** Number of currently active agents */
38
47
  activeAgents: number;
48
+ /** Active agent session details (for cross-device routing) */
49
+ agents?: SyncAgentInfo[];
39
50
  }
40
51
  /**
41
52
  * A device visible in the same Cloud account.
@@ -88,7 +99,7 @@ export interface HeartbeatPayload {
88
99
  timestamp: string;
89
100
  }
90
101
  /** All supported message types for inter-device communication. */
91
- export type MessageType = 'command' | 'sync_teams' | 'sync_settings' | 'notification' | 'relay' | 'ping' | 'task_update';
102
+ export type MessageType = 'command' | 'sync_teams' | 'sync_settings' | 'notification' | 'relay' | 'ping' | 'task_update' | 'agent_message';
92
103
  /** Valid message type values for runtime validation. */
93
104
  export declare const MESSAGE_TYPES: readonly MessageType[];
94
105
  /**
@@ -151,6 +162,33 @@ export interface TaskUpdatePayload {
151
162
  /** Summary of what was done */
152
163
  summary?: string;
153
164
  }
165
+ /**
166
+ * Payload for an agent_message sent between devices for transparent
167
+ * cross-device agent communication. The orchestrator's send-message /
168
+ * delegate-task skills remain unchanged — the message router transparently
169
+ * wraps undeliverable local messages into this payload and routes via Cloud.
170
+ */
171
+ export interface AgentMessagePayload {
172
+ /** Target agent session name on the remote device */
173
+ targetSession: string;
174
+ /** The message content to deliver */
175
+ message: string;
176
+ /** Source device ID */
177
+ fromDevice: string;
178
+ /** Human-readable source device name */
179
+ fromDeviceName: string;
180
+ /** Delivery priority */
181
+ priority?: 'high' | 'normal';
182
+ /** Optional correlation ID for request-response patterns */
183
+ correlationId?: string;
184
+ }
185
+ /**
186
+ * Check if an object satisfies the AgentMessagePayload interface shape.
187
+ *
188
+ * @param value - Value to check
189
+ * @returns True if the value has the required AgentMessagePayload fields
190
+ */
191
+ export declare function isAgentMessagePayload(value: unknown): value is AgentMessagePayload;
154
192
  /**
155
193
  * Check if a value is a valid CloudSyncState.
156
194
  *
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-sync.types.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/cloud/cloud-sync.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cloud-sync.types.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/cloud/cloud-sync.types.ts"],"names":[],"mappings":"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"}
@@ -19,7 +19,23 @@ export const MESSAGE_TYPES = [
19
19
  'relay',
20
20
  'ping',
21
21
  'task_update',
22
+ 'agent_message',
22
23
  ];
24
+ /**
25
+ * Check if an object satisfies the AgentMessagePayload interface shape.
26
+ *
27
+ * @param value - Value to check
28
+ * @returns True if the value has the required AgentMessagePayload fields
29
+ */
30
+ export function isAgentMessagePayload(value) {
31
+ if (typeof value !== 'object' || value === null)
32
+ return false;
33
+ const obj = value;
34
+ return (typeof obj.targetSession === 'string' &&
35
+ typeof obj.message === 'string' &&
36
+ typeof obj.fromDevice === 'string' &&
37
+ typeof obj.fromDeviceName === 'string');
38
+ }
23
39
  // ---------------------------------------------------------------------------
24
40
  // Type Guards
25
41
  // ---------------------------------------------------------------------------
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-sync.types.js","sourceRoot":"","sources":["../../../../../../backend/src/services/cloud/cloud-sync.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,4DAA4D;AAC5D,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAU,CAAC;AA2G1E,wDAAwD;AACxD,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,SAAS;IACT,YAAY;IACZ,eAAe;IACf,cAAc;IACd,OAAO;IACP,MAAM;IACN,aAAa;CACL,CAAC;AAkEX,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,iBAAiB,CAAC,QAAQ,CAAC,KAAuB,CAAC,CAAC;AAC1F,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,aAAa,CAAC,QAAQ,CAAC,KAAoB,CAAC,CAAC;AACnF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,OAAO,CACL,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ;QAChC,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ;QAClC,CAAC,GAAG,CAAC,MAAM,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC;QACrD,OAAO,GAAG,CAAC,eAAe,KAAK,QAAQ,CACxC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,OAAO,CACL,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ;QAC1B,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;QAC5B,OAAO,GAAG,CAAC,cAAc,KAAK,QAAQ;QACtC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;QACvB,OAAO,GAAG,CAAC,SAAS,KAAK,SAAS;QAClC,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,CAC/B,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,OAAO,CACL,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ;QAChC,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ;QAC7B,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ;QAChC,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,CACnC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"cloud-sync.types.js","sourceRoot":"","sources":["../../../../../../backend/src/services/cloud/cloud-sync.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,4DAA4D;AAC5D,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAU,CAAC;AAwH1E,wDAAwD;AACxD,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,SAAS;IACT,YAAY;IACZ,eAAe;IACf,cAAc;IACd,OAAO;IACP,MAAM;IACN,aAAa;IACb,eAAe;CACP,CAAC;AAuFX;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,OAAO,CACL,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ;QACrC,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ;QAC/B,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ;QAClC,OAAO,GAAG,CAAC,cAAc,KAAK,QAAQ,CACvC,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,iBAAiB,CAAC,QAAQ,CAAC,KAAuB,CAAC,CAAC;AAC1F,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,aAAa,CAAC,QAAQ,CAAC,KAAoB,CAAC,CAAC;AACnF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,OAAO,CACL,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ;QAChC,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ;QAClC,CAAC,GAAG,CAAC,MAAM,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC;QACrD,OAAO,GAAG,CAAC,eAAe,KAAK,QAAQ,CACxC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,OAAO,CACL,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ;QAC1B,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;QAC5B,OAAO,GAAG,CAAC,cAAc,KAAK,QAAQ;QACtC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;QACvB,OAAO,GAAG,CAAC,SAAS,KAAK,SAAS;QAClC,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,CAC/B,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,OAAO,CACL,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ;QAChC,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ;QAC7B,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ;QAChC,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,CACnC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Message Router Service
3
+ *
4
+ * Provides transparent cross-device message routing for agent communication.
5
+ * When a target agent session is not found locally, the router queries
6
+ * CloudSyncService for same-account devices that host the agent and forwards
7
+ * the message through the Cloud message queue.
8
+ *
9
+ * On the receiving end, listens for incoming `agent_message` events from
10
+ * CloudSyncService and delivers them to the local agent session via the
11
+ * standard terminal delivery path.
12
+ *
13
+ * This makes cross-device communication fully transparent to callers —
14
+ * orchestrator skills (send-message, delegate-task) require zero changes.
15
+ *
16
+ * @module services/messaging/message-router.service
17
+ */
18
+ import type { SyncDevice, IncomingMessage } from '../cloud/cloud-sync.types.js';
19
+ /** Constants for the MessageRouterService. */
20
+ export declare const MESSAGE_ROUTER_CONSTANTS: {
21
+ /** Maximum time to wait for remote delivery confirmation (ms) */
22
+ readonly REMOTE_DELIVERY_TIMEOUT_MS: 15000;
23
+ /** Log component name */
24
+ readonly COMPONENT_NAME: "MessageRouterService";
25
+ };
26
+ /** Result of a remote routing attempt. */
27
+ export interface RouteResult {
28
+ /** Whether the message was successfully routed to a remote device */
29
+ routed: boolean;
30
+ /** Target device ID (if routed) */
31
+ deviceId?: string;
32
+ /** Target device name (if routed) */
33
+ deviceName?: string;
34
+ /** Error message (if routing failed) */
35
+ error?: string;
36
+ }
37
+ /**
38
+ * Handler function for delivering a message to a local agent session.
39
+ * Injected via setLocalDeliveryHandler() to avoid circular dependencies
40
+ * with terminal.controller / AgentRegistrationService.
41
+ */
42
+ export type LocalDeliveryHandler = (sessionName: string, message: string) => Promise<{
43
+ success: boolean;
44
+ error?: string;
45
+ }>;
46
+ /**
47
+ * MessageRouterService singleton.
48
+ *
49
+ * Transparently routes agent messages across devices under the same
50
+ * Cloud account. Local sessions are delivered directly; remote sessions
51
+ * are forwarded via the Cloud message queue.
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * const router = MessageRouterService.getInstance();
56
+ * router.setLocalDeliveryHandler(myDeliveryFn);
57
+ * router.startListening();
58
+ *
59
+ * // Route a message — automatically determines local vs remote
60
+ * const result = await router.routeRemote('crewly-product-leo', 'Hello Leo');
61
+ * if (result.routed) {
62
+ * console.log(`Routed to device ${result.deviceName}`);
63
+ * }
64
+ * ```
65
+ */
66
+ export declare class MessageRouterService {
67
+ private static instance;
68
+ private readonly logger;
69
+ /** Whether we are listening for incoming agent_message events */
70
+ private listening;
71
+ /** Bound handler reference for cleanup */
72
+ private boundMessageHandler;
73
+ /** Handler for delivering messages to local agent sessions */
74
+ private localDeliveryHandler;
75
+ private constructor();
76
+ /**
77
+ * Get the singleton instance.
78
+ *
79
+ * @returns MessageRouterService instance
80
+ */
81
+ static getInstance(): MessageRouterService;
82
+ /**
83
+ * Reset the singleton (for testing).
84
+ */
85
+ static resetInstance(): void;
86
+ /**
87
+ * Set the handler used to deliver messages to local agent sessions.
88
+ * Must be called before startListening() to enable incoming message delivery.
89
+ *
90
+ * @param handler - Function that delivers a message to a local session
91
+ */
92
+ setLocalDeliveryHandler(handler: LocalDeliveryHandler): void;
93
+ /**
94
+ * Find which remote device hosts the given agent session.
95
+ *
96
+ * Searches the cached device list from CloudSyncService, inspecting
97
+ * each device's team summaries for matching agent session names.
98
+ *
99
+ * @param sessionName - Target agent session name
100
+ * @returns The SyncDevice hosting the session, or null if not found
101
+ */
102
+ findDeviceForSession(sessionName: string): SyncDevice | null;
103
+ /**
104
+ * Route a message to a remote device via the Cloud message queue.
105
+ *
106
+ * Called when a target agent session is not found locally. Queries
107
+ * CloudSyncService for the device hosting that session and sends
108
+ * an `agent_message` through the Cloud queue.
109
+ *
110
+ * @param targetSession - Target agent session name
111
+ * @param message - Message content to deliver
112
+ * @param priority - Delivery priority (default: 'normal')
113
+ * @returns RouteResult indicating success/failure
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * const result = await router.routeRemote('crewly-product-leo', 'Build the feature');
118
+ * if (!result.routed) {
119
+ * console.error('Remote routing failed:', result.error);
120
+ * }
121
+ * ```
122
+ */
123
+ routeRemote(targetSession: string, message: string, priority?: 'high' | 'normal'): Promise<RouteResult>;
124
+ /**
125
+ * Start listening for incoming `agent_message` events from CloudSyncService.
126
+ *
127
+ * When an `agent_message` is received, it extracts the target session name
128
+ * and delivers the message to the local agent via the configured
129
+ * localDeliveryHandler.
130
+ */
131
+ startListening(): void;
132
+ /**
133
+ * Stop listening for incoming messages.
134
+ */
135
+ stopListening(): void;
136
+ /**
137
+ * Handle an incoming message from CloudSyncService.
138
+ * Only processes messages of type `agent_message`.
139
+ *
140
+ * @param msg - The incoming message from another device
141
+ */
142
+ handleIncomingMessage(msg: IncomingMessage): Promise<void>;
143
+ /**
144
+ * Check if the router is currently listening for incoming messages.
145
+ *
146
+ * @returns True if listening
147
+ */
148
+ isListening(): boolean;
149
+ /**
150
+ * Get local device identity info from CloudSyncService config.
151
+ * Falls back to defaults if sync is not started.
152
+ *
153
+ * @returns Object with deviceId and deviceName
154
+ */
155
+ private getLocalDeviceInfo;
156
+ }
157
+ //# sourceMappingURL=message-router.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-router.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/message-router.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EAEhB,MAAM,8BAA8B,CAAC;AAOtC,8CAA8C;AAC9C,eAAO,MAAM,wBAAwB;IACnC,iEAAiE;;IAEjE,yBAAyB;;CAEjB,CAAC;AAMX,0CAA0C;AAC1C,MAAM,WAAW,WAAW;IAC1B,qEAAqE;IACrE,MAAM,EAAE,OAAO,CAAC;IAChB,mCAAmC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,CACjC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAMnD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAqC;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IAEzC,iEAAiE;IACjE,OAAO,CAAC,SAAS,CAAS;IAC1B,0CAA0C;IAC1C,OAAO,CAAC,mBAAmB,CAAiD;IAC5E,8DAA8D;IAC9D,OAAO,CAAC,oBAAoB,CAAqC;IAEjE,OAAO;IAMP;;;;OAIG;IACH,MAAM,CAAC,WAAW,IAAI,oBAAoB;IAO1C;;OAEG;IACH,MAAM,CAAC,aAAa,IAAI,IAAI;IAW5B;;;;;OAKG;IACH,uBAAuB,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI;IAQ5D;;;;;;;;OAQG;IACH,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAqB5D;;;;;;;;;;;;;;;;;;;OAmBG;IACG,WAAW,CACf,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAM,GAAG,QAAmB,GACrC,OAAO,CAAC,WAAW,CAAC;IAyDvB;;;;;;OAMG;IACH,cAAc,IAAI,IAAI;IAkBtB;;OAEG;IACH,aAAa,IAAI,IAAI;IAUrB;;;;;OAKG;IACG,qBAAqB,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAqDhE;;;;OAIG;IACH,WAAW,IAAI,OAAO;IAQtB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;CAa3B"}
@@ -0,0 +1,317 @@
1
+ /**
2
+ * Message Router Service
3
+ *
4
+ * Provides transparent cross-device message routing for agent communication.
5
+ * When a target agent session is not found locally, the router queries
6
+ * CloudSyncService for same-account devices that host the agent and forwards
7
+ * the message through the Cloud message queue.
8
+ *
9
+ * On the receiving end, listens for incoming `agent_message` events from
10
+ * CloudSyncService and delivers them to the local agent session via the
11
+ * standard terminal delivery path.
12
+ *
13
+ * This makes cross-device communication fully transparent to callers —
14
+ * orchestrator skills (send-message, delegate-task) require zero changes.
15
+ *
16
+ * @module services/messaging/message-router.service
17
+ */
18
+ import { LoggerService } from '../core/logger.service.js';
19
+ import { CloudSyncService } from '../cloud/cloud-sync.service.js';
20
+ import { isAgentMessagePayload } from '../cloud/cloud-sync.types.js';
21
+ // ---------------------------------------------------------------------------
22
+ // Constants
23
+ // ---------------------------------------------------------------------------
24
+ /** Constants for the MessageRouterService. */
25
+ export const MESSAGE_ROUTER_CONSTANTS = {
26
+ /** Maximum time to wait for remote delivery confirmation (ms) */
27
+ REMOTE_DELIVERY_TIMEOUT_MS: 15_000,
28
+ /** Log component name */
29
+ COMPONENT_NAME: 'MessageRouterService',
30
+ };
31
+ // ---------------------------------------------------------------------------
32
+ // Service
33
+ // ---------------------------------------------------------------------------
34
+ /**
35
+ * MessageRouterService singleton.
36
+ *
37
+ * Transparently routes agent messages across devices under the same
38
+ * Cloud account. Local sessions are delivered directly; remote sessions
39
+ * are forwarded via the Cloud message queue.
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * const router = MessageRouterService.getInstance();
44
+ * router.setLocalDeliveryHandler(myDeliveryFn);
45
+ * router.startListening();
46
+ *
47
+ * // Route a message — automatically determines local vs remote
48
+ * const result = await router.routeRemote('crewly-product-leo', 'Hello Leo');
49
+ * if (result.routed) {
50
+ * console.log(`Routed to device ${result.deviceName}`);
51
+ * }
52
+ * ```
53
+ */
54
+ export class MessageRouterService {
55
+ static instance = null;
56
+ logger;
57
+ /** Whether we are listening for incoming agent_message events */
58
+ listening = false;
59
+ /** Bound handler reference for cleanup */
60
+ boundMessageHandler = null;
61
+ /** Handler for delivering messages to local agent sessions */
62
+ localDeliveryHandler = null;
63
+ constructor() {
64
+ this.logger = LoggerService.getInstance().createComponentLogger(MESSAGE_ROUTER_CONSTANTS.COMPONENT_NAME);
65
+ }
66
+ /**
67
+ * Get the singleton instance.
68
+ *
69
+ * @returns MessageRouterService instance
70
+ */
71
+ static getInstance() {
72
+ if (!MessageRouterService.instance) {
73
+ MessageRouterService.instance = new MessageRouterService();
74
+ }
75
+ return MessageRouterService.instance;
76
+ }
77
+ /**
78
+ * Reset the singleton (for testing).
79
+ */
80
+ static resetInstance() {
81
+ if (MessageRouterService.instance) {
82
+ MessageRouterService.instance.stopListening();
83
+ }
84
+ MessageRouterService.instance = null;
85
+ }
86
+ // -------------------------------------------------------------------------
87
+ // Configuration
88
+ // -------------------------------------------------------------------------
89
+ /**
90
+ * Set the handler used to deliver messages to local agent sessions.
91
+ * Must be called before startListening() to enable incoming message delivery.
92
+ *
93
+ * @param handler - Function that delivers a message to a local session
94
+ */
95
+ setLocalDeliveryHandler(handler) {
96
+ this.localDeliveryHandler = handler;
97
+ }
98
+ // -------------------------------------------------------------------------
99
+ // Outbound: Remote Routing
100
+ // -------------------------------------------------------------------------
101
+ /**
102
+ * Find which remote device hosts the given agent session.
103
+ *
104
+ * Searches the cached device list from CloudSyncService, inspecting
105
+ * each device's team summaries for matching agent session names.
106
+ *
107
+ * @param sessionName - Target agent session name
108
+ * @returns The SyncDevice hosting the session, or null if not found
109
+ */
110
+ findDeviceForSession(sessionName) {
111
+ const sync = CloudSyncService.getInstance();
112
+ if (!sync.isStarted())
113
+ return null;
114
+ const onlineDevices = sync.getOnlineDevices();
115
+ for (const device of onlineDevices) {
116
+ if (!device.teams)
117
+ continue;
118
+ for (const team of device.teams) {
119
+ if (!team.agents)
120
+ continue;
121
+ for (const agent of team.agents) {
122
+ if (agent.sessionName === sessionName) {
123
+ return device;
124
+ }
125
+ }
126
+ }
127
+ }
128
+ return null;
129
+ }
130
+ /**
131
+ * Route a message to a remote device via the Cloud message queue.
132
+ *
133
+ * Called when a target agent session is not found locally. Queries
134
+ * CloudSyncService for the device hosting that session and sends
135
+ * an `agent_message` through the Cloud queue.
136
+ *
137
+ * @param targetSession - Target agent session name
138
+ * @param message - Message content to deliver
139
+ * @param priority - Delivery priority (default: 'normal')
140
+ * @returns RouteResult indicating success/failure
141
+ *
142
+ * @example
143
+ * ```typescript
144
+ * const result = await router.routeRemote('crewly-product-leo', 'Build the feature');
145
+ * if (!result.routed) {
146
+ * console.error('Remote routing failed:', result.error);
147
+ * }
148
+ * ```
149
+ */
150
+ async routeRemote(targetSession, message, priority = 'normal') {
151
+ const sync = CloudSyncService.getInstance();
152
+ // Guard: CloudSync must be running
153
+ if (!sync.isStarted()) {
154
+ return { routed: false, error: 'CloudSyncService not started' };
155
+ }
156
+ // Find the device hosting this session
157
+ const targetDevice = this.findDeviceForSession(targetSession);
158
+ if (!targetDevice) {
159
+ return {
160
+ routed: false,
161
+ error: `Session '${targetSession}' not found on any online device`,
162
+ };
163
+ }
164
+ // Build the agent_message payload
165
+ const config = this.getLocalDeviceInfo();
166
+ const payload = {
167
+ targetSession,
168
+ message,
169
+ fromDevice: config.deviceId,
170
+ fromDeviceName: config.deviceName,
171
+ priority,
172
+ };
173
+ try {
174
+ await sync.sendMessage(targetDevice.deviceId, 'agent_message', payload);
175
+ this.logger.info('Message routed to remote device', {
176
+ targetSession,
177
+ deviceId: targetDevice.deviceId,
178
+ deviceName: targetDevice.deviceName,
179
+ messageLength: message.length,
180
+ });
181
+ return {
182
+ routed: true,
183
+ deviceId: targetDevice.deviceId,
184
+ deviceName: targetDevice.deviceName,
185
+ };
186
+ }
187
+ catch (error) {
188
+ const errorMsg = error instanceof Error ? error.message : String(error);
189
+ this.logger.error('Failed to route message to remote device', {
190
+ targetSession,
191
+ deviceId: targetDevice.deviceId,
192
+ error: errorMsg,
193
+ });
194
+ return { routed: false, error: errorMsg };
195
+ }
196
+ }
197
+ // -------------------------------------------------------------------------
198
+ // Inbound: Incoming Message Handling
199
+ // -------------------------------------------------------------------------
200
+ /**
201
+ * Start listening for incoming `agent_message` events from CloudSyncService.
202
+ *
203
+ * When an `agent_message` is received, it extracts the target session name
204
+ * and delivers the message to the local agent via the configured
205
+ * localDeliveryHandler.
206
+ */
207
+ startListening() {
208
+ if (this.listening)
209
+ return;
210
+ const sync = CloudSyncService.getInstance();
211
+ this.boundMessageHandler = (msg) => {
212
+ this.handleIncomingMessage(msg).catch((err) => {
213
+ this.logger.error('Error handling incoming agent_message', {
214
+ error: err instanceof Error ? err.message : String(err),
215
+ messageId: msg.id,
216
+ });
217
+ });
218
+ };
219
+ sync.on('message', this.boundMessageHandler);
220
+ this.listening = true;
221
+ this.logger.info('MessageRouterService started listening for agent_message events');
222
+ }
223
+ /**
224
+ * Stop listening for incoming messages.
225
+ */
226
+ stopListening() {
227
+ if (!this.listening || !this.boundMessageHandler)
228
+ return;
229
+ const sync = CloudSyncService.getInstance();
230
+ sync.removeListener('message', this.boundMessageHandler);
231
+ this.boundMessageHandler = null;
232
+ this.listening = false;
233
+ this.logger.info('MessageRouterService stopped listening');
234
+ }
235
+ /**
236
+ * Handle an incoming message from CloudSyncService.
237
+ * Only processes messages of type `agent_message`.
238
+ *
239
+ * @param msg - The incoming message from another device
240
+ */
241
+ async handleIncomingMessage(msg) {
242
+ // Only handle agent_message type
243
+ if (msg.type !== 'agent_message')
244
+ return;
245
+ const payload = msg.payload;
246
+ if (!isAgentMessagePayload(payload)) {
247
+ this.logger.warn('Received agent_message with invalid payload', {
248
+ messageId: msg.id,
249
+ from: msg.from,
250
+ });
251
+ return;
252
+ }
253
+ this.logger.info('Received remote agent_message', {
254
+ messageId: msg.id,
255
+ from: msg.fromDeviceName,
256
+ targetSession: payload.targetSession,
257
+ messageLength: payload.message.length,
258
+ });
259
+ // Deliver to the local agent session
260
+ if (!this.localDeliveryHandler) {
261
+ this.logger.error('No localDeliveryHandler configured — cannot deliver remote message', {
262
+ targetSession: payload.targetSession,
263
+ });
264
+ return;
265
+ }
266
+ try {
267
+ const result = await this.localDeliveryHandler(payload.targetSession, payload.message);
268
+ if (result.success) {
269
+ this.logger.info('Remote message delivered to local agent', {
270
+ targetSession: payload.targetSession,
271
+ from: payload.fromDeviceName,
272
+ });
273
+ }
274
+ else {
275
+ this.logger.warn('Failed to deliver remote message to local agent', {
276
+ targetSession: payload.targetSession,
277
+ error: result.error,
278
+ });
279
+ }
280
+ }
281
+ catch (error) {
282
+ this.logger.error('Exception delivering remote message to local agent', {
283
+ targetSession: payload.targetSession,
284
+ error: error instanceof Error ? error.message : String(error),
285
+ });
286
+ }
287
+ }
288
+ /**
289
+ * Check if the router is currently listening for incoming messages.
290
+ *
291
+ * @returns True if listening
292
+ */
293
+ isListening() {
294
+ return this.listening;
295
+ }
296
+ // -------------------------------------------------------------------------
297
+ // Internal Helpers
298
+ // -------------------------------------------------------------------------
299
+ /**
300
+ * Get local device identity info from CloudSyncService config.
301
+ * Falls back to defaults if sync is not started.
302
+ *
303
+ * @returns Object with deviceId and deviceName
304
+ */
305
+ getLocalDeviceInfo() {
306
+ // Access the device list and find our own entry
307
+ const sync = CloudSyncService.getInstance();
308
+ const devices = sync.getDevices();
309
+ const local = devices.find((d) => d.isLocal);
310
+ if (local) {
311
+ return { deviceId: local.deviceId, deviceName: local.deviceName };
312
+ }
313
+ // Fallback: return placeholder (will still work for logging)
314
+ return { deviceId: 'unknown', deviceName: 'unknown' };
315
+ }
316
+ }
317
+ //# sourceMappingURL=message-router.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-router.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/message-router.service.ts"],"names":[],"mappings":"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"}