crewly 1.4.57 → 1.4.59
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/backend/backend/src/controllers/cloud/cloud.controller.d.ts +13 -0
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.js +39 -0
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.routes.d.ts +1 -0
- package/dist/backend/backend/src/controllers/cloud/cloud.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.routes.js +3 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +41 -0
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-initializer.d.ts +10 -0
- package/dist/backend/backend/src/services/cloud/cloud-initializer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-initializer.js +55 -0
- package/dist/backend/backend/src/services/cloud/cloud-initializer.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.service.js +44 -7
- package/dist/backend/backend/src/services/cloud/cloud-sync.service.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts +39 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.js +16 -0
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/message-router.service.d.ts +157 -0
- package/dist/backend/backend/src/services/messaging/message-router.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/messaging/message-router.service.js +317 -0
- package/dist/backend/backend/src/services/messaging/message-router.service.js.map +1 -0
- package/frontend/dist/assets/{index-78e43622.css → index-e2a673d6.css} +1 -1
- package/frontend/dist/assets/{index-1b67fa33.js → index-e830dc67.js} +309 -309
- package/frontend/dist/index.html +2 -2
- package/package.json +1 -1
|
@@ -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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"}
|