@studiomopoke/crosschat 1.6.0

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 (169) hide show
  1. package/LICENSE +62 -0
  2. package/README.md +279 -0
  3. package/bin/cli.cjs +631 -0
  4. package/crosschat.md +196 -0
  5. package/dashboard/dist/assets/index-Blgmbgo_.css +1 -0
  6. package/dashboard/dist/assets/index-DzcjxzDR.js +49 -0
  7. package/dashboard/dist/index.html +13 -0
  8. package/dist/dashboard/dashboard-listener.d.ts +22 -0
  9. package/dist/dashboard/dashboard-listener.d.ts.map +1 -0
  10. package/dist/dashboard/dashboard-listener.js +124 -0
  11. package/dist/dashboard/dashboard-listener.js.map +1 -0
  12. package/dist/dashboard/http-server.d.ts +25 -0
  13. package/dist/dashboard/http-server.d.ts.map +1 -0
  14. package/dist/dashboard/http-server.js +281 -0
  15. package/dist/dashboard/http-server.js.map +1 -0
  16. package/dist/dashboard/message-bridge.d.ts +19 -0
  17. package/dist/dashboard/message-bridge.d.ts.map +1 -0
  18. package/dist/dashboard/message-bridge.js +48 -0
  19. package/dist/dashboard/message-bridge.js.map +1 -0
  20. package/dist/hub/agent-connection.d.ts +101 -0
  21. package/dist/hub/agent-connection.d.ts.map +1 -0
  22. package/dist/hub/agent-connection.js +383 -0
  23. package/dist/hub/agent-connection.js.map +1 -0
  24. package/dist/hub/hub-main.d.ts +2 -0
  25. package/dist/hub/hub-main.d.ts.map +1 -0
  26. package/dist/hub/hub-main.js +16 -0
  27. package/dist/hub/hub-main.js.map +1 -0
  28. package/dist/hub/hub-server.d.ts +8 -0
  29. package/dist/hub/hub-server.d.ts.map +1 -0
  30. package/dist/hub/hub-server.js +1500 -0
  31. package/dist/hub/hub-server.js.map +1 -0
  32. package/dist/hub/protocol.d.ts +221 -0
  33. package/dist/hub/protocol.d.ts.map +1 -0
  34. package/dist/hub/protocol.js +20 -0
  35. package/dist/hub/protocol.js.map +1 -0
  36. package/dist/hub/task-manager.d.ts +68 -0
  37. package/dist/hub/task-manager.d.ts.map +1 -0
  38. package/dist/hub/task-manager.js +250 -0
  39. package/dist/hub/task-manager.js.map +1 -0
  40. package/dist/index.d.ts +2 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +7 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/lifecycle.d.ts +2 -0
  45. package/dist/lifecycle.d.ts.map +1 -0
  46. package/dist/lifecycle.js +234 -0
  47. package/dist/lifecycle.js.map +1 -0
  48. package/dist/prompts.d.ts +3 -0
  49. package/dist/prompts.d.ts.map +1 -0
  50. package/dist/prompts.js +48 -0
  51. package/dist/prompts.js.map +1 -0
  52. package/dist/registry/cleanup.d.ts +2 -0
  53. package/dist/registry/cleanup.d.ts.map +1 -0
  54. package/dist/registry/cleanup.js +60 -0
  55. package/dist/registry/cleanup.js.map +1 -0
  56. package/dist/registry/registry.d.ts +11 -0
  57. package/dist/registry/registry.d.ts.map +1 -0
  58. package/dist/registry/registry.js +82 -0
  59. package/dist/registry/registry.js.map +1 -0
  60. package/dist/server.d.ts +9 -0
  61. package/dist/server.d.ts.map +1 -0
  62. package/dist/server.js +91 -0
  63. package/dist/server.js.map +1 -0
  64. package/dist/stores/message-store.d.ts +21 -0
  65. package/dist/stores/message-store.d.ts.map +1 -0
  66. package/dist/stores/message-store.js +83 -0
  67. package/dist/stores/message-store.js.map +1 -0
  68. package/dist/stores/task-store.d.ts +15 -0
  69. package/dist/stores/task-store.d.ts.map +1 -0
  70. package/dist/stores/task-store.js +57 -0
  71. package/dist/stores/task-store.js.map +1 -0
  72. package/dist/tools/accept-claim.d.ts +4 -0
  73. package/dist/tools/accept-claim.d.ts.map +1 -0
  74. package/dist/tools/accept-claim.js +27 -0
  75. package/dist/tools/accept-claim.js.map +1 -0
  76. package/dist/tools/chat-send.d.ts +4 -0
  77. package/dist/tools/chat-send.d.ts.map +1 -0
  78. package/dist/tools/chat-send.js +19 -0
  79. package/dist/tools/chat-send.js.map +1 -0
  80. package/dist/tools/claim-task.d.ts +4 -0
  81. package/dist/tools/claim-task.d.ts.map +1 -0
  82. package/dist/tools/claim-task.js +26 -0
  83. package/dist/tools/claim-task.js.map +1 -0
  84. package/dist/tools/clear-session.d.ts +5 -0
  85. package/dist/tools/clear-session.d.ts.map +1 -0
  86. package/dist/tools/clear-session.js +41 -0
  87. package/dist/tools/clear-session.js.map +1 -0
  88. package/dist/tools/complete-task.d.ts +4 -0
  89. package/dist/tools/complete-task.d.ts.map +1 -0
  90. package/dist/tools/complete-task.js +29 -0
  91. package/dist/tools/complete-task.js.map +1 -0
  92. package/dist/tools/create-room.d.ts +4 -0
  93. package/dist/tools/create-room.d.ts.map +1 -0
  94. package/dist/tools/create-room.js +28 -0
  95. package/dist/tools/create-room.js.map +1 -0
  96. package/dist/tools/delegate-task.d.ts +4 -0
  97. package/dist/tools/delegate-task.d.ts.map +1 -0
  98. package/dist/tools/delegate-task.js +32 -0
  99. package/dist/tools/delegate-task.js.map +1 -0
  100. package/dist/tools/get-messages.d.ts +4 -0
  101. package/dist/tools/get-messages.d.ts.map +1 -0
  102. package/dist/tools/get-messages.js +35 -0
  103. package/dist/tools/get-messages.js.map +1 -0
  104. package/dist/tools/get-room-digest.d.ts +4 -0
  105. package/dist/tools/get-room-digest.d.ts.map +1 -0
  106. package/dist/tools/get-room-digest.js +63 -0
  107. package/dist/tools/get-room-digest.js.map +1 -0
  108. package/dist/tools/get-task-status.d.ts +4 -0
  109. package/dist/tools/get-task-status.d.ts.map +1 -0
  110. package/dist/tools/get-task-status.js +26 -0
  111. package/dist/tools/get-task-status.js.map +1 -0
  112. package/dist/tools/join-room.d.ts +4 -0
  113. package/dist/tools/join-room.d.ts.map +1 -0
  114. package/dist/tools/join-room.js +26 -0
  115. package/dist/tools/join-room.js.map +1 -0
  116. package/dist/tools/list-peers.d.ts +4 -0
  117. package/dist/tools/list-peers.d.ts.map +1 -0
  118. package/dist/tools/list-peers.js +26 -0
  119. package/dist/tools/list-peers.js.map +1 -0
  120. package/dist/tools/list-tasks.d.ts +4 -0
  121. package/dist/tools/list-tasks.d.ts.map +1 -0
  122. package/dist/tools/list-tasks.js +28 -0
  123. package/dist/tools/list-tasks.js.map +1 -0
  124. package/dist/tools/send-message.d.ts +4 -0
  125. package/dist/tools/send-message.d.ts.map +1 -0
  126. package/dist/tools/send-message.js +28 -0
  127. package/dist/tools/send-message.js.map +1 -0
  128. package/dist/tools/set-status.d.ts +4 -0
  129. package/dist/tools/set-status.d.ts.map +1 -0
  130. package/dist/tools/set-status.js +28 -0
  131. package/dist/tools/set-status.js.map +1 -0
  132. package/dist/tools/update-task.d.ts +4 -0
  133. package/dist/tools/update-task.d.ts.map +1 -0
  134. package/dist/tools/update-task.js +28 -0
  135. package/dist/tools/update-task.js.map +1 -0
  136. package/dist/tools/wait-for-messages.d.ts +4 -0
  137. package/dist/tools/wait-for-messages.d.ts.map +1 -0
  138. package/dist/tools/wait-for-messages.js +84 -0
  139. package/dist/tools/wait-for-messages.js.map +1 -0
  140. package/dist/transport/peer-protocol.d.ts +7 -0
  141. package/dist/transport/peer-protocol.d.ts.map +1 -0
  142. package/dist/transport/peer-protocol.js +30 -0
  143. package/dist/transport/peer-protocol.js.map +1 -0
  144. package/dist/transport/uds-client.d.ts +3 -0
  145. package/dist/transport/uds-client.d.ts.map +1 -0
  146. package/dist/transport/uds-client.js +57 -0
  147. package/dist/transport/uds-client.js.map +1 -0
  148. package/dist/transport/uds-server.d.ts +12 -0
  149. package/dist/transport/uds-server.d.ts.map +1 -0
  150. package/dist/transport/uds-server.js +87 -0
  151. package/dist/transport/uds-server.js.map +1 -0
  152. package/dist/types.d.ts +18 -0
  153. package/dist/types.d.ts.map +1 -0
  154. package/dist/types.js +3 -0
  155. package/dist/types.js.map +1 -0
  156. package/dist/util/id.d.ts +2 -0
  157. package/dist/util/id.d.ts.map +1 -0
  158. package/dist/util/id.js +5 -0
  159. package/dist/util/id.js.map +1 -0
  160. package/dist/util/logger.d.ts +3 -0
  161. package/dist/util/logger.d.ts.map +1 -0
  162. package/dist/util/logger.js +13 -0
  163. package/dist/util/logger.js.map +1 -0
  164. package/dist/util/pid.d.ts +2 -0
  165. package/dist/util/pid.d.ts.map +1 -0
  166. package/dist/util/pid.js +10 -0
  167. package/dist/util/pid.js.map +1 -0
  168. package/hooks/permission-hook.sh +116 -0
  169. package/package.json +59 -0
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>CrossChat Dashboard</title>
7
+ <script type="module" crossorigin src="/assets/index-DzcjxzDR.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-Blgmbgo_.css">
9
+ </head>
10
+ <body>
11
+ <div id="root"></div>
12
+ </body>
13
+ </html>
@@ -0,0 +1,22 @@
1
+ import type { MessageStore } from '../stores/message-store.js';
2
+ /**
3
+ * Connects to the dashboard WebSocket as a client and listens for
4
+ * user-posted messages. Every CrossChat instance runs one of these
5
+ * so that dashboard messages are delivered directly — no relay needed.
6
+ */
7
+ export declare class DashboardListener {
8
+ private port;
9
+ private messageStore;
10
+ private ownName;
11
+ private ownPeerId;
12
+ private ws;
13
+ private reconnectTimer;
14
+ private stopped;
15
+ constructor(port: number, messageStore: MessageStore, ownName: string, ownPeerId: string);
16
+ start(): void;
17
+ private connect;
18
+ private handleUserMessage;
19
+ private scheduleReconnect;
20
+ stop(): void;
21
+ }
22
+ //# sourceMappingURL=dashboard-listener.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-listener.d.ts","sourceRoot":"","sources":["../../src/dashboard/dashboard-listener.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAQ/D;;;;GAIG;AACH,qBAAa,iBAAiB;IAM1B,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,SAAS;IARnB,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,OAAO,CAAS;gBAGd,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM;IAG3B,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,OAAO;IAiDf,OAAO,CAAC,iBAAiB;IAmCzB,OAAO,CAAC,iBAAiB;IASzB,IAAI,IAAI,IAAI;CAWb"}
@@ -0,0 +1,124 @@
1
+ import WebSocket from 'ws';
2
+ import { generateId } from '../util/id.js';
3
+ import { log, logError } from '../util/logger.js';
4
+ const RECONNECT_DELAY_MS = 3000;
5
+ const ROOMS_TO_JOIN = ['crosschat', 'general'];
6
+ /**
7
+ * Connects to the dashboard WebSocket as a client and listens for
8
+ * user-posted messages. Every CrossChat instance runs one of these
9
+ * so that dashboard messages are delivered directly — no relay needed.
10
+ */
11
+ export class DashboardListener {
12
+ port;
13
+ messageStore;
14
+ ownName;
15
+ ownPeerId;
16
+ ws = null;
17
+ reconnectTimer = null;
18
+ stopped = false;
19
+ constructor(port, messageStore, ownName, ownPeerId) {
20
+ this.port = port;
21
+ this.messageStore = messageStore;
22
+ this.ownName = ownName;
23
+ this.ownPeerId = ownPeerId;
24
+ }
25
+ start() {
26
+ this.stopped = false;
27
+ this.connect();
28
+ }
29
+ connect() {
30
+ if (this.stopped)
31
+ return;
32
+ const url = `ws://localhost:${this.port}/ws`;
33
+ try {
34
+ this.ws = new WebSocket(url);
35
+ }
36
+ catch {
37
+ this.scheduleReconnect();
38
+ return;
39
+ }
40
+ this.ws.on('open', () => {
41
+ log(`Dashboard listener connected on port ${this.port}`);
42
+ // Join all known rooms
43
+ for (const roomId of ROOMS_TO_JOIN) {
44
+ this.ws.send(JSON.stringify({ type: 'join', roomId, username: this.ownName, silent: true }));
45
+ }
46
+ });
47
+ this.ws.on('message', (raw) => {
48
+ try {
49
+ const data = JSON.parse(raw.toString());
50
+ // Only process user-posted messages (not agent-mirrored ones)
51
+ if (data.type === 'message' && data.source === 'user') {
52
+ this.handleUserMessage(data);
53
+ }
54
+ // Auto-join newly created rooms
55
+ if (data.type === 'roomCreated' && this.ws?.readyState === WebSocket.OPEN) {
56
+ this.ws.send(JSON.stringify({ type: 'join', roomId: data.room.id, username: this.ownName, silent: true }));
57
+ }
58
+ }
59
+ catch {
60
+ // Ignore malformed messages
61
+ }
62
+ });
63
+ this.ws.on('close', () => {
64
+ this.ws = null;
65
+ this.scheduleReconnect();
66
+ });
67
+ this.ws.on('error', (err) => {
68
+ logError('Dashboard listener WS error', err);
69
+ // 'close' event fires after 'error', which triggers reconnect
70
+ });
71
+ }
72
+ handleUserMessage(data) {
73
+ const text = data.text;
74
+ const username = data.username;
75
+ const roomId = data.roomId;
76
+ if (!text || !username)
77
+ return;
78
+ // Parse @mentions
79
+ const mentionPattern = /@([\w-]+)/g;
80
+ const mentions = [];
81
+ let match;
82
+ while ((match = mentionPattern.exec(text)) !== null) {
83
+ mentions.push(match[1].toLowerCase());
84
+ }
85
+ const message = {
86
+ messageId: data.messageId || generateId(),
87
+ fromPeerId: 'dashboard',
88
+ fromName: `[dashboard] ${username}`,
89
+ content: text,
90
+ metadata: {
91
+ source: 'dashboard',
92
+ mentions,
93
+ roomId,
94
+ },
95
+ sentAt: data.timestamp || new Date().toISOString(),
96
+ receivedAt: new Date().toISOString(),
97
+ read: false,
98
+ type: 'message',
99
+ };
100
+ this.messageStore.add(message);
101
+ log(`Dashboard message from ${username} in ${roomId}: ${text.slice(0, 80)}`);
102
+ }
103
+ scheduleReconnect() {
104
+ if (this.stopped || this.reconnectTimer)
105
+ return;
106
+ this.reconnectTimer = setTimeout(() => {
107
+ this.reconnectTimer = null;
108
+ this.connect();
109
+ }, RECONNECT_DELAY_MS);
110
+ this.reconnectTimer.unref();
111
+ }
112
+ stop() {
113
+ this.stopped = true;
114
+ if (this.reconnectTimer) {
115
+ clearTimeout(this.reconnectTimer);
116
+ this.reconnectTimer = null;
117
+ }
118
+ if (this.ws) {
119
+ this.ws.close();
120
+ this.ws = null;
121
+ }
122
+ }
123
+ }
124
+ //# sourceMappingURL=dashboard-listener.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-listener.js","sourceRoot":"","sources":["../../src/dashboard/dashboard-listener.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export type UserMessageCallback = (username: string, text: string, roomId: string) => void;
2
+ export declare class DashboardServer {
3
+ private app;
4
+ private server;
5
+ private wss;
6
+ private rooms;
7
+ private clientRooms;
8
+ private port;
9
+ private userMessageCallbacks;
10
+ constructor(port?: number);
11
+ private seedRooms;
12
+ private setupMiddleware;
13
+ private setupRoutes;
14
+ private broadcast;
15
+ /** Register a callback for messages posted by users via the dashboard UI */
16
+ onUserMessage(callback: UserMessageCallback): () => void;
17
+ private notifyUserMessage;
18
+ /** Post a message to a room programmatically (used by the message bridge) */
19
+ postToRoom(roomId: string, username: string, text: string): void;
20
+ private setupWebSocket;
21
+ start(): Promise<number>;
22
+ close(): Promise<void>;
23
+ getPort(): number;
24
+ }
25
+ //# sourceMappingURL=http-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../../src/dashboard/http-server.ts"],"names":[],"mappings":"AA2BA,MAAM,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAE3F,qBAAa,eAAe;IAC1B,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,GAAG,CAAgC;IAC3C,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,WAAW,CAAkD;IACrE,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,oBAAoB,CAA6B;gBAE7C,IAAI,GAAE,MAAU;IAQ5B,OAAO,CAAC,SAAS;IAejB,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,WAAW;IA+EnB,OAAO,CAAC,SAAS;IAajB,4EAA4E;IAC5E,aAAa,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,IAAI;IAQxD,OAAO,CAAC,iBAAiB;IAMzB,6EAA6E;IAC7E,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAehE,OAAO,CAAC,cAAc;IA0DhB,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IA8BxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAa5B,OAAO,IAAI,MAAM;CAGlB"}
@@ -0,0 +1,281 @@
1
+ import express from 'express';
2
+ import http from 'node:http';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { WebSocketServer, WebSocket } from 'ws';
6
+ import { generateId } from '../util/id.js';
7
+ import { log } from '../util/logger.js';
8
+ import { listRegistryEntries } from '../registry/registry.js';
9
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
10
+ export class DashboardServer {
11
+ app;
12
+ server = null;
13
+ wss = null;
14
+ rooms = new Map();
15
+ clientRooms = new WeakMap();
16
+ port;
17
+ userMessageCallbacks = [];
18
+ constructor(port = 0) {
19
+ this.port = port;
20
+ this.app = express();
21
+ this.setupMiddleware();
22
+ this.setupRoutes();
23
+ this.seedRooms();
24
+ }
25
+ seedRooms() {
26
+ this.rooms.set('general', {
27
+ id: 'general',
28
+ name: 'General',
29
+ createdAt: new Date().toISOString(),
30
+ messages: [],
31
+ });
32
+ this.rooms.set('crosschat', {
33
+ id: 'crosschat',
34
+ name: 'CrossChat Activity',
35
+ createdAt: new Date().toISOString(),
36
+ messages: [],
37
+ });
38
+ }
39
+ setupMiddleware() {
40
+ this.app.use(express.json());
41
+ this.app.use((_req, res, next) => {
42
+ res.header('Access-Control-Allow-Origin', '*');
43
+ res.header('Access-Control-Allow-Headers', 'Content-Type');
44
+ res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
45
+ next();
46
+ });
47
+ // Serve static frontend files
48
+ const distPath = path.join(__dirname, '..', '..', 'dashboard', 'dist');
49
+ this.app.use(express.static(distPath));
50
+ }
51
+ setupRoutes() {
52
+ // List rooms
53
+ this.app.get('/api/rooms', (_req, res) => {
54
+ const list = [...this.rooms.values()].map(({ id, name, createdAt, messages }) => ({
55
+ id,
56
+ name,
57
+ createdAt,
58
+ messageCount: messages.length,
59
+ }));
60
+ res.json(list);
61
+ });
62
+ // Create room
63
+ this.app.post('/api/rooms', (req, res) => {
64
+ const { name } = req.body;
65
+ if (!name || typeof name !== 'string' || name.trim().length === 0) {
66
+ res.status(400).json({ error: 'Room name is required' });
67
+ return;
68
+ }
69
+ const id = generateId();
70
+ const room = { id, name: name.trim(), createdAt: new Date().toISOString(), messages: [] };
71
+ this.rooms.set(id, room);
72
+ this.broadcast({ type: 'roomCreated', room: { id, name: room.name, createdAt: room.createdAt, messageCount: 0 } });
73
+ res.status(201).json({ id, name: room.name, createdAt: room.createdAt });
74
+ });
75
+ // Get messages
76
+ this.app.get('/api/rooms/:roomId/messages', (req, res) => {
77
+ const room = this.rooms.get(req.params.roomId);
78
+ if (!room) {
79
+ res.status(404).json({ error: 'Room not found' });
80
+ return;
81
+ }
82
+ res.json(room.messages);
83
+ });
84
+ // Post message
85
+ this.app.post('/api/rooms/:roomId/messages', (req, res) => {
86
+ const room = this.rooms.get(req.params.roomId);
87
+ if (!room) {
88
+ res.status(404).json({ error: 'Room not found' });
89
+ return;
90
+ }
91
+ const { username, text } = req.body;
92
+ if (!username || !text) {
93
+ res.status(400).json({ error: 'username and text are required' });
94
+ return;
95
+ }
96
+ const message = {
97
+ messageId: generateId(),
98
+ roomId: room.id,
99
+ username: username.trim(),
100
+ text: text.trim(),
101
+ timestamp: new Date().toISOString(),
102
+ source: 'user',
103
+ };
104
+ room.messages.push(message);
105
+ this.broadcast({ type: 'message', ...message }, room.id);
106
+ this.notifyUserMessage(message.username, message.text, room.id);
107
+ res.status(201).json(message);
108
+ });
109
+ // List connected peers
110
+ this.app.get('/api/peers', async (_req, res) => {
111
+ try {
112
+ const entries = await listRegistryEntries();
113
+ const peers = entries.map((e) => ({
114
+ peerId: e.peerId,
115
+ name: e.name,
116
+ status: e.status,
117
+ statusDetail: e.statusDetail,
118
+ cwd: e.metadata?.cwd,
119
+ }));
120
+ res.json(peers);
121
+ }
122
+ catch {
123
+ res.status(500).json({ error: 'Failed to list peers' });
124
+ }
125
+ });
126
+ // Fallback to index.html for SPA routing
127
+ this.app.use((_req, res, next) => {
128
+ const indexPath = path.join(__dirname, '..', '..', 'dashboard', 'dist', 'index.html');
129
+ res.sendFile(indexPath, (err) => {
130
+ if (err)
131
+ next();
132
+ });
133
+ });
134
+ }
135
+ broadcast(data, filterRoomId) {
136
+ if (!this.wss)
137
+ return;
138
+ const payload = JSON.stringify(data);
139
+ this.wss.clients.forEach((client) => {
140
+ if (client.readyState !== WebSocket.OPEN)
141
+ return;
142
+ if (filterRoomId) {
143
+ const joined = this.clientRooms.get(client);
144
+ if (!joined?.has(filterRoomId))
145
+ return;
146
+ }
147
+ client.send(payload);
148
+ });
149
+ }
150
+ /** Register a callback for messages posted by users via the dashboard UI */
151
+ onUserMessage(callback) {
152
+ this.userMessageCallbacks.push(callback);
153
+ return () => {
154
+ const idx = this.userMessageCallbacks.indexOf(callback);
155
+ if (idx !== -1)
156
+ this.userMessageCallbacks.splice(idx, 1);
157
+ };
158
+ }
159
+ notifyUserMessage(username, text, roomId) {
160
+ for (const cb of this.userMessageCallbacks) {
161
+ cb(username, text, roomId);
162
+ }
163
+ }
164
+ /** Post a message to a room programmatically (used by the message bridge) */
165
+ postToRoom(roomId, username, text) {
166
+ const room = this.rooms.get(roomId);
167
+ if (!room)
168
+ return;
169
+ const message = {
170
+ messageId: generateId(),
171
+ roomId: room.id,
172
+ username,
173
+ text,
174
+ timestamp: new Date().toISOString(),
175
+ source: 'agent',
176
+ };
177
+ room.messages.push(message);
178
+ this.broadcast({ type: 'message', ...message }, room.id);
179
+ }
180
+ setupWebSocket() {
181
+ if (!this.server)
182
+ return;
183
+ this.wss = new WebSocketServer({ server: this.server, path: '/ws' });
184
+ this.wss.on('connection', (ws) => {
185
+ this.clientRooms.set(ws, new Set());
186
+ ws.on('message', (raw) => {
187
+ let data;
188
+ try {
189
+ data = JSON.parse(raw.toString());
190
+ }
191
+ catch {
192
+ ws.send(JSON.stringify({ type: 'error', error: 'Invalid JSON' }));
193
+ return;
194
+ }
195
+ switch (data.type) {
196
+ case 'join': {
197
+ const room = this.rooms.get(data.roomId);
198
+ if (!room) {
199
+ ws.send(JSON.stringify({ type: 'error', error: 'Room not found' }));
200
+ return;
201
+ }
202
+ this.clientRooms.get(ws).add(data.roomId);
203
+ if (!data.silent) {
204
+ this.broadcast({ type: 'userJoined', roomId: data.roomId, username: data.username || 'Anonymous' }, data.roomId);
205
+ }
206
+ break;
207
+ }
208
+ case 'message': {
209
+ const room = this.rooms.get(data.roomId);
210
+ if (!room || !data.username || !data.text)
211
+ return;
212
+ const message = {
213
+ messageId: generateId(),
214
+ roomId: room.id,
215
+ username: data.username.trim(),
216
+ text: data.text.trim(),
217
+ timestamp: new Date().toISOString(),
218
+ source: 'user',
219
+ };
220
+ room.messages.push(message);
221
+ this.broadcast({ type: 'message', ...message }, room.id);
222
+ this.notifyUserMessage(message.username, message.text, room.id);
223
+ break;
224
+ }
225
+ case 'leave': {
226
+ this.clientRooms.get(ws)?.delete(data.roomId);
227
+ break;
228
+ }
229
+ }
230
+ });
231
+ ws.on('close', () => {
232
+ this.clientRooms.delete(ws);
233
+ });
234
+ });
235
+ }
236
+ async start() {
237
+ return new Promise((resolve, reject) => {
238
+ this.server = http.createServer(this.app);
239
+ let settled = false;
240
+ const onListening = () => {
241
+ if (settled)
242
+ return;
243
+ settled = true;
244
+ const addr = this.server.address();
245
+ const actualPort = typeof addr === 'object' && addr ? addr.port : this.port;
246
+ this.port = actualPort;
247
+ this.setupWebSocket();
248
+ log(`Dashboard running on http://localhost:${actualPort}`);
249
+ resolve(actualPort);
250
+ };
251
+ this.server.on('error', (err) => {
252
+ if (err.code === 'EADDRINUSE' && !settled) {
253
+ log(`Port ${this.port} in use, trying auto-select...`);
254
+ this.server.listen(0, onListening);
255
+ }
256
+ else if (!settled) {
257
+ settled = true;
258
+ reject(err);
259
+ }
260
+ });
261
+ this.server.listen(this.port, onListening);
262
+ });
263
+ }
264
+ async close() {
265
+ return new Promise((resolve) => {
266
+ if (this.wss) {
267
+ this.wss.close();
268
+ }
269
+ if (this.server) {
270
+ this.server.close(() => resolve());
271
+ }
272
+ else {
273
+ resolve();
274
+ }
275
+ });
276
+ }
277
+ getPort() {
278
+ return this.port;
279
+ }
280
+ }
281
+ //# sourceMappingURL=http-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-server.js","sourceRoot":"","sources":["../../src/dashboard/http-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { MessageStore } from '../stores/message-store.js';
2
+ import type { DashboardServer } from './http-server.js';
3
+ /**
4
+ * One-way bridge: peer messages → dashboard.
5
+ *
6
+ * The reverse direction (dashboard → peers) is handled by DashboardListener
7
+ * instances running on each peer, which connect to the dashboard WebSocket
8
+ * and receive user messages directly.
9
+ */
10
+ export declare class MessageBridge {
11
+ private messageStore;
12
+ private dashboard;
13
+ private unsubscribe;
14
+ constructor(messageStore: MessageStore, dashboard: DashboardServer);
15
+ start(): void;
16
+ stop(): void;
17
+ private mirrorToDashboard;
18
+ }
19
+ //# sourceMappingURL=message-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-bridge.d.ts","sourceRoot":"","sources":["../../src/dashboard/message-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAKxD;;;;;;GAMG;AACH,qBAAa,aAAa;IAItB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,SAAS;IAJnB,OAAO,CAAC,WAAW,CAA6B;gBAGtC,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,eAAe;IAGpC,KAAK,IAAI,IAAI;IAMb,IAAI,IAAI,IAAI;IAOZ,OAAO,CAAC,iBAAiB;CAoB1B"}
@@ -0,0 +1,48 @@
1
+ const CROSSCHAT_ROOM = 'crosschat';
2
+ /**
3
+ * One-way bridge: peer messages → dashboard.
4
+ *
5
+ * The reverse direction (dashboard → peers) is handled by DashboardListener
6
+ * instances running on each peer, which connect to the dashboard WebSocket
7
+ * and receive user messages directly.
8
+ */
9
+ export class MessageBridge {
10
+ messageStore;
11
+ dashboard;
12
+ unsubscribe = null;
13
+ constructor(messageStore, dashboard) {
14
+ this.messageStore = messageStore;
15
+ this.dashboard = dashboard;
16
+ }
17
+ start() {
18
+ this.unsubscribe = this.messageStore.onMessage((message) => {
19
+ this.mirrorToDashboard(message);
20
+ });
21
+ }
22
+ stop() {
23
+ if (this.unsubscribe) {
24
+ this.unsubscribe();
25
+ this.unsubscribe = null;
26
+ }
27
+ }
28
+ mirrorToDashboard(message) {
29
+ // Don't re-mirror messages that originated from the dashboard
30
+ if (message.metadata?.source === 'dashboard')
31
+ return;
32
+ const type = message.type || 'message';
33
+ let prefix = '';
34
+ switch (type) {
35
+ case 'task_delegated':
36
+ prefix = '[TASK] ';
37
+ break;
38
+ case 'task_result':
39
+ prefix = '[RESULT] ';
40
+ break;
41
+ default:
42
+ prefix = '';
43
+ }
44
+ const text = `${prefix}${message.content}`;
45
+ this.dashboard.postToRoom(CROSSCHAT_ROOM, message.fromName, text);
46
+ }
47
+ }
48
+ //# sourceMappingURL=message-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-bridge.js","sourceRoot":"","sources":["../../src/dashboard/message-bridge.ts"],"names":[],"mappings":"AAIA,MAAM,cAAc,GAAG,WAAW,CAAC;AAEnC;;;;;;GAMG;AACH,MAAM,OAAO,aAAa;IAId;IACA;IAJF,WAAW,GAAwB,IAAI,CAAC;IAEhD,YACU,YAA0B,EAC1B,SAA0B;QAD1B,iBAAY,GAAZ,YAAY,CAAc;QAC1B,cAAS,GAAT,SAAS,CAAiB;IACjC,CAAC;IAEJ,KAAK;QACH,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE;YACzD,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,IAAI,CAAC,WAAW,EAAE,CAAC;YACnB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC1B,CAAC;IACH,CAAC;IAEO,iBAAiB,CAAC,OAAoB;QAC5C,8DAA8D;QAC9D,IAAI,OAAO,CAAC,QAAQ,EAAE,MAAM,KAAK,WAAW;YAAE,OAAO;QAErD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC;QACvC,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,gBAAgB;gBACnB,MAAM,GAAG,SAAS,CAAC;gBACnB,MAAM;YACR,KAAK,aAAa;gBAChB,MAAM,GAAG,WAAW,CAAC;gBACrB,MAAM;YACR;gBACE,MAAM,GAAG,EAAE,CAAC;QAChB,CAAC;QAED,MAAM,IAAI,GAAG,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;QAC3C,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,cAAc,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACpE,CAAC;CACF"}