@panguard-ai/manager 0.2.0 → 1.0.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.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Panguard AI Team
3
+ Copyright (c) 2025-2026 Panguard AI Team
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1 +1 @@
1
- {"version":3,"file":"agent-registry.d.ts","sourceRoot":"","sources":["../src/agent-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EACV,iBAAiB,EACjB,wBAAwB,EACxB,cAAc,EACd,WAAW,EACZ,MAAM,YAAY,CAAC;AAIpB;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,SAAS,EAAE,MAAM;IAK7B;;;;;;;OAOG;IACH,aAAa,CAAC,OAAO,EAAE,wBAAwB,GAAG,iBAAiB;IAmCnE;;;;;OAKG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAezC;;;;;;OAMG;IACH,eAAe,CAAC,SAAS,EAAE,cAAc,GAAG,iBAAiB,GAAG,SAAS;IAkBzE;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAMxD;;;;OAIG;IACH,eAAe,IAAI,SAAS,iBAAiB,EAAE;IAM/C;;;;OAIG;IACH,YAAY,IAAI,SAAS,iBAAiB,EAAE;IAO5C;;;;;;OAMG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,iBAAiB,EAAE;IA8B/D;;;;;OAKG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAkBrC;;;;OAIG;IACH,eAAe,IAAI,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC;IAc9C;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
1
+ {"version":3,"file":"agent-registry.d.ts","sourceRoot":"","sources":["../src/agent-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EACV,iBAAiB,EACjB,wBAAwB,EACxB,cAAc,EACd,WAAW,EACZ,MAAM,YAAY,CAAC;AAIpB;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,SAAS,EAAE,MAAM;IAK7B;;;;;;;OAOG;IACH,aAAa,CAAC,OAAO,EAAE,wBAAwB,GAAG,iBAAiB;IAmCnE;;;;;OAKG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAezC;;;;;;OAMG;IACH,eAAe,CAAC,SAAS,EAAE,cAAc,GAAG,iBAAiB,GAAG,SAAS;IAkBzE;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAMxD;;;;OAIG;IACH,eAAe,IAAI,SAAS,iBAAiB,EAAE;IAM/C;;;;OAIG;IACH,YAAY,IAAI,SAAS,iBAAiB,EAAE;IAO5C;;;;;;OAMG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,iBAAiB,EAAE;IA8B/D;;;;;OAKG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAiBrC;;;;OAIG;IACH,eAAe,IAAI,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC;IAc9C;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
@@ -31,14 +31,14 @@ export class AgentRegistry {
31
31
  */
32
32
  registerAgent(request) {
33
33
  if (this.agents.size >= this.maxAgents) {
34
- throw new Error(`Maximum agent limit reached (${this.maxAgents}). ` +
35
- 'Cannot register additional agents.');
34
+ throw new Error(`Maximum agent limit reached (${this.maxAgents}). ` + 'Cannot register additional agents.');
36
35
  }
37
36
  const agentId = generateAgentId();
38
37
  const now = new Date().toISOString();
39
38
  const registration = {
40
39
  agentId,
41
40
  hostname: request.hostname,
41
+ endpoint: request.endpoint,
42
42
  platform: {
43
43
  os: request.os,
44
44
  arch: request.arch,
@@ -172,8 +172,7 @@ export class AgentRegistry {
172
172
  status: 'offline',
173
173
  };
174
174
  this.agents.set(agentId, updated);
175
- logger.info(`Agent marked offline: ${agentId} (${existing.hostname}) / ` +
176
- `代理已標記為離線: ${agentId}`);
175
+ logger.info(`Agent marked offline: ${agentId} (${existing.hostname}) / ` + `代理已標記為離線: ${agentId}`);
177
176
  return true;
178
177
  }
179
178
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"agent-registry.js","sourceRoot":"","sources":["../src/agent-registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-registry.js","sourceRoot":"","sources":["../src/agent-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Dashboard Relay Server - Proxies dashboard connections between agents and clients
3
+ * Dashboard Relay Server - 在 agent 和客戶端之間代理 dashboard 連接
4
+ *
5
+ * URL routing:
6
+ * /api/dashboard/relay/{agentId} - Agent upstream connections (Guard -> Manager)
7
+ * /api/dashboard/view/{agentId} - Client downstream connections (Browser -> Manager)
8
+ *
9
+ * When an agent sends an event, it is broadcast to all subscribed clients.
10
+ * When a client sends a command, it is forwarded to the target agent.
11
+ *
12
+ * Uses Node.js built-in http module with native RFC 6455 WebSocket handshake.
13
+ *
14
+ * @module @panguard-ai/manager/dashboard-relay
15
+ */
16
+ import { EventEmitter } from 'node:events';
17
+ import type { IncomingMessage } from 'node:http';
18
+ import type { Socket } from 'node:net';
19
+ export interface DashboardRelayConfig {
20
+ /** Require auth for relay connections / 要求 relay 連接認證 */
21
+ readonly requireAuth?: boolean;
22
+ }
23
+ /**
24
+ * Dashboard relay server -- proxies dashboard connections between agents and clients
25
+ * Dashboard relay server -- 在 agent 和客戶端之間代理 dashboard 連接
26
+ */
27
+ export declare class DashboardRelay extends EventEmitter {
28
+ /** Map of agentId -> upstream agent WebSocket connection / agentId -> 上游 agent WebSocket 連接 */
29
+ private readonly agentConnections;
30
+ /** Map of agentId -> Set of downstream client connections / agentId -> 下游客戶端連接集合 */
31
+ private readonly clientConnections;
32
+ /** Configuration / 配置 */
33
+ private readonly config;
34
+ constructor(config?: DashboardRelayConfig);
35
+ /**
36
+ * Handle WebSocket upgrade for relay endpoint / 處理 relay 端點的 WebSocket 升級
37
+ *
38
+ * Routes based on URL path:
39
+ * /api/dashboard/relay/{agentId} -> agent connection
40
+ * /api/dashboard/view/{agentId} -> client connection
41
+ */
42
+ handleUpgrade(req: IncomingMessage, socket: Socket, _head: Buffer): void;
43
+ /**
44
+ * Get connected agent IDs / 取得已連接的 agent ID 列表
45
+ */
46
+ getConnectedAgents(): string[];
47
+ /**
48
+ * Get client count for an agent / 取得 agent 的客戶端數量
49
+ */
50
+ getClientCount(agentId: string): number;
51
+ /**
52
+ * Disconnect all connections / 斷開所有連接
53
+ */
54
+ disconnectAll(): void;
55
+ /** Handle agent WebSocket upgrade / 處理 agent WebSocket 升級 */
56
+ private handleAgentUpgrade;
57
+ /** Handle data from agent connection / 處理 agent 連接的資料 */
58
+ private handleAgentData;
59
+ /** Handle agent disconnect / 處理 agent 斷線 */
60
+ private handleAgentDisconnect;
61
+ /** Handle client WebSocket upgrade / 處理客戶端 WebSocket 升級 */
62
+ private handleClientUpgrade;
63
+ /** Handle data from client connection / 處理客戶端連接的資料 */
64
+ private handleClientData;
65
+ /** Handle client disconnect / 處理客戶端斷線 */
66
+ private handleClientDisconnect;
67
+ /** Broadcast a payload from agent to all subscribed clients / 將 agent 載荷廣播給所有訂閱的客戶端 */
68
+ private broadcastToClients;
69
+ /** Forward a payload from client to the target agent / 將客戶端載荷轉發給目標 agent */
70
+ private forwardToAgent;
71
+ /** Complete the WebSocket handshake / 完成 WebSocket 交握 */
72
+ private completeHandshake;
73
+ /** Create a WebSocket text frame (unmasked, server->client) / 建立 WebSocket 文字框架 */
74
+ private createWSFrame;
75
+ /** Extract payload from a WebSocket frame (handles both masked and unmasked) / 提取 WebSocket 框架載荷 */
76
+ private extractPayload;
77
+ /** Send a pong frame / 發送 pong 框架 */
78
+ private sendPong;
79
+ }
80
+ //# sourceMappingURL=dashboard-relay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-relay.d.ts","sourceRoot":"","sources":["../src/dashboard-relay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAWvC,MAAM,WAAW,oBAAoB;IACnC,yDAAyD;IACzD,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AASD;;;GAGG;AACH,qBAAa,cAAe,SAAQ,YAAY;IAC9C,+FAA+F;IAC/F,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA6C;IAC9E,oFAAoF;IACpF,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAkD;IACpF,yBAAyB;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;gBAElC,MAAM,CAAC,EAAE,oBAAoB;IAUzC;;;;;;OAMG;IACH,aAAa,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAuBxE;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAI9B;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAKvC;;OAEG;IACH,aAAa,IAAI,IAAI;IA8BrB,6DAA6D;IAC7D,OAAO,CAAC,kBAAkB;IA6D1B,yDAAyD;IACzD,OAAO,CAAC,eAAe;IA+BvB,4CAA4C;IAC5C,OAAO,CAAC,qBAAqB;IAyC7B,2DAA2D;IAC3D,OAAO,CAAC,mBAAmB;IA4D3B,sDAAsD;IACtD,OAAO,CAAC,gBAAgB;IAsBxB,yCAAyC;IACzC,OAAO,CAAC,sBAAsB;IA2B9B,uFAAuF;IACvF,OAAO,CAAC,kBAAkB;IAgC1B,4EAA4E;IAC5E,OAAO,CAAC,cAAc;IAkBtB,yDAAyD;IACzD,OAAO,CAAC,iBAAiB;IAwBzB,mFAAmF;IACnF,OAAO,CAAC,aAAa;IAuBrB,oGAAoG;IACpG,OAAO,CAAC,cAAc;IAiCtB,qCAAqC;IACrC,OAAO,CAAC,QAAQ;CAWjB"}
@@ -0,0 +1,463 @@
1
+ /**
2
+ * Dashboard Relay Server - Proxies dashboard connections between agents and clients
3
+ * Dashboard Relay Server - 在 agent 和客戶端之間代理 dashboard 連接
4
+ *
5
+ * URL routing:
6
+ * /api/dashboard/relay/{agentId} - Agent upstream connections (Guard -> Manager)
7
+ * /api/dashboard/view/{agentId} - Client downstream connections (Browser -> Manager)
8
+ *
9
+ * When an agent sends an event, it is broadcast to all subscribed clients.
10
+ * When a client sends a command, it is forwarded to the target agent.
11
+ *
12
+ * Uses Node.js built-in http module with native RFC 6455 WebSocket handshake.
13
+ *
14
+ * @module @panguard-ai/manager/dashboard-relay
15
+ */
16
+ import { EventEmitter } from 'node:events';
17
+ import { createHash } from 'node:crypto';
18
+ import { createLogger } from '@panguard-ai/core';
19
+ const logger = createLogger('panguard-manager:dashboard-relay');
20
+ /** WebSocket magic GUID per RFC 6455 / RFC 6455 WebSocket 魔術 GUID */
21
+ const WS_MAGIC_GUID = '258EAFA5-E914-47DA-95CA-5AB5DC11E65B';
22
+ /** Maximum clients per agent / 每個 agent 的最大客戶端數 */
23
+ const MAX_CLIENTS_PER_AGENT = 50;
24
+ /**
25
+ * Dashboard relay server -- proxies dashboard connections between agents and clients
26
+ * Dashboard relay server -- 在 agent 和客戶端之間代理 dashboard 連接
27
+ */
28
+ export class DashboardRelay extends EventEmitter {
29
+ /** Map of agentId -> upstream agent WebSocket connection / agentId -> 上游 agent WebSocket 連接 */
30
+ agentConnections = new Map();
31
+ /** Map of agentId -> Set of downstream client connections / agentId -> 下游客戶端連接集合 */
32
+ clientConnections = new Map();
33
+ /** Configuration / 配置 */
34
+ config;
35
+ constructor(config) {
36
+ super();
37
+ this.config = config ?? {};
38
+ logger.info(`Dashboard relay initialized (requireAuth: ${this.config.requireAuth ?? false}) / ` +
39
+ `Dashboard relay 已初始化`);
40
+ }
41
+ /**
42
+ * Handle WebSocket upgrade for relay endpoint / 處理 relay 端點的 WebSocket 升級
43
+ *
44
+ * Routes based on URL path:
45
+ * /api/dashboard/relay/{agentId} -> agent connection
46
+ * /api/dashboard/view/{agentId} -> client connection
47
+ */
48
+ handleUpgrade(req, socket, _head) {
49
+ const url = req.url ?? '';
50
+ const agentRelayMatch = url.match(/^\/api\/dashboard\/relay\/([^/?]+)/);
51
+ const clientViewMatch = url.match(/^\/api\/dashboard\/view\/([^/?]+)/);
52
+ if (agentRelayMatch) {
53
+ const agentId = agentRelayMatch[1];
54
+ this.handleAgentUpgrade(req, socket, agentId);
55
+ return;
56
+ }
57
+ if (clientViewMatch) {
58
+ const agentId = clientViewMatch[1];
59
+ this.handleClientUpgrade(req, socket, agentId);
60
+ return;
61
+ }
62
+ // Unknown path -> reject / 未知路徑 -> 拒絕
63
+ logger.warn(`Rejected relay upgrade for unknown path: ${url} / 拒絕未知路徑的 relay 升級`);
64
+ socket.write('HTTP/1.1 404 Not Found\r\n\r\n');
65
+ socket.destroy();
66
+ }
67
+ /**
68
+ * Get connected agent IDs / 取得已連接的 agent ID 列表
69
+ */
70
+ getConnectedAgents() {
71
+ return Array.from(this.agentConnections.keys());
72
+ }
73
+ /**
74
+ * Get client count for an agent / 取得 agent 的客戶端數量
75
+ */
76
+ getClientCount(agentId) {
77
+ const clients = this.clientConnections.get(agentId);
78
+ return clients ? clients.size : 0;
79
+ }
80
+ /**
81
+ * Disconnect all connections / 斷開所有連接
82
+ */
83
+ disconnectAll() {
84
+ // Close all agent connections / 關閉所有 agent 連接
85
+ for (const [agentId, conn] of this.agentConnections) {
86
+ try {
87
+ conn.socket.destroy();
88
+ }
89
+ catch {
90
+ /* ignore */
91
+ }
92
+ this.agentConnections.delete(agentId);
93
+ }
94
+ // Close all client connections / 關閉所有客戶端連接
95
+ for (const [agentId, clients] of this.clientConnections) {
96
+ for (const client of clients) {
97
+ try {
98
+ client.socket.destroy();
99
+ }
100
+ catch {
101
+ /* ignore */
102
+ }
103
+ }
104
+ this.clientConnections.delete(agentId);
105
+ }
106
+ logger.info('All relay connections disconnected / 所有 relay 連接已斷開');
107
+ }
108
+ // ---------------------------------------------------------------------------
109
+ // Agent connection handling / Agent 連接處理
110
+ // ---------------------------------------------------------------------------
111
+ /** Handle agent WebSocket upgrade / 處理 agent WebSocket 升級 */
112
+ handleAgentUpgrade(req, socket, agentId) {
113
+ // Validate auth if required / 若需要則驗證認證
114
+ if (this.config.requireAuth) {
115
+ const authHeader = req.headers.authorization ?? '';
116
+ const token = authHeader.replace('Bearer ', '');
117
+ if (!token) {
118
+ logger.warn(`Agent relay auth failed for ${agentId} / Agent relay 認證失敗`);
119
+ socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
120
+ socket.destroy();
121
+ return;
122
+ }
123
+ }
124
+ // Complete WebSocket handshake / 完成 WebSocket 交握
125
+ if (!this.completeHandshake(req, socket))
126
+ return;
127
+ // If agent already connected, close old connection / 若 agent 已連接,關閉舊連接
128
+ const existing = this.agentConnections.get(agentId);
129
+ if (existing) {
130
+ logger.info(`Replacing existing agent connection for ${agentId} / 替換現有 agent 連接`);
131
+ try {
132
+ existing.socket.destroy();
133
+ }
134
+ catch {
135
+ /* ignore */
136
+ }
137
+ }
138
+ const conn = {
139
+ socket,
140
+ agentId,
141
+ connectedAt: Date.now(),
142
+ };
143
+ this.agentConnections.set(agentId, conn);
144
+ this.emit('agent:connected', agentId);
145
+ logger.info(`Agent ${agentId} connected to dashboard relay / ` +
146
+ `Agent ${agentId} 已連接到 dashboard relay`);
147
+ // Handle incoming data from agent (events to forward to clients)
148
+ // 處理從 agent 收到的資料(轉發給客戶端的事件)
149
+ socket.on('data', (data) => {
150
+ this.handleAgentData(agentId, socket, data);
151
+ });
152
+ socket.on('end', () => {
153
+ this.handleAgentDisconnect(agentId, socket);
154
+ });
155
+ socket.on('close', () => {
156
+ this.handleAgentDisconnect(agentId, socket);
157
+ });
158
+ socket.on('error', (err) => {
159
+ logger.warn(`Agent ${agentId} relay socket error: ${err.message} / Agent relay 連線錯誤`);
160
+ this.handleAgentDisconnect(agentId, socket);
161
+ });
162
+ }
163
+ /** Handle data from agent connection / 處理 agent 連接的資料 */
164
+ handleAgentData(agentId, socket, data) {
165
+ if (data.length < 2)
166
+ return;
167
+ const firstByte = data[0] ?? 0;
168
+ const opcode = firstByte & 0x0f;
169
+ // Close frame / 關閉框架
170
+ if (opcode === 0x08) {
171
+ this.handleAgentDisconnect(agentId, socket);
172
+ return;
173
+ }
174
+ // Ping -> pong / Ping -> pong
175
+ if (opcode === 0x09) {
176
+ this.sendPong(this.agentConnections.get(agentId)?.socket);
177
+ return;
178
+ }
179
+ // Pong -> ignore
180
+ if (opcode === 0x0a)
181
+ return;
182
+ // Text frame -> extract payload and broadcast to clients
183
+ // 文字框架 -> 提取載荷並廣播給客戶端
184
+ if (opcode === 0x01) {
185
+ const payload = this.extractPayload(data);
186
+ if (payload) {
187
+ this.broadcastToClients(agentId, payload);
188
+ }
189
+ }
190
+ }
191
+ /** Handle agent disconnect / 處理 agent 斷線 */
192
+ handleAgentDisconnect(agentId, socket) {
193
+ const conn = this.agentConnections.get(agentId);
194
+ // Only remove if this is the current connection (not a replaced one)
195
+ // 只在這是當前連接時移除(而不是已被替換的連接)
196
+ if (!conn || conn.socket !== socket)
197
+ return;
198
+ try {
199
+ conn.socket.destroy();
200
+ }
201
+ catch {
202
+ /* ignore */
203
+ }
204
+ this.agentConnections.delete(agentId);
205
+ this.emit('agent:disconnected', agentId);
206
+ logger.info(`Agent ${agentId} disconnected from relay / ` + `Agent ${agentId} 已從 relay 斷線`);
207
+ // Notify all connected clients that the agent is gone
208
+ // 通知所有已連接的客戶端 agent 已離線
209
+ const disconnectMsg = JSON.stringify({
210
+ type: 'agent_disconnected',
211
+ agentId,
212
+ timestamp: new Date().toISOString(),
213
+ });
214
+ const frame = this.createWSFrame(Buffer.from(disconnectMsg, 'utf-8'));
215
+ const clients = this.clientConnections.get(agentId);
216
+ if (clients) {
217
+ for (const client of clients) {
218
+ try {
219
+ client.socket.write(frame);
220
+ }
221
+ catch {
222
+ /* ignore */
223
+ }
224
+ }
225
+ }
226
+ }
227
+ // ---------------------------------------------------------------------------
228
+ // Client connection handling / 客戶端連接處理
229
+ // ---------------------------------------------------------------------------
230
+ /** Handle client WebSocket upgrade / 處理客戶端 WebSocket 升級 */
231
+ handleClientUpgrade(req, socket, agentId) {
232
+ // Check if agent exists / 檢查 agent 是否存在
233
+ if (!this.agentConnections.has(agentId)) {
234
+ logger.warn(`Client tried to view non-connected agent ${agentId} / ` + `客戶端嘗試查看未連接的 agent`);
235
+ socket.write('HTTP/1.1 404 Not Found\r\n\r\n');
236
+ socket.destroy();
237
+ return;
238
+ }
239
+ // Enforce max clients per agent / 限制每個 agent 的最大客戶端數
240
+ const existingClients = this.clientConnections.get(agentId);
241
+ if (existingClients && existingClients.size >= MAX_CLIENTS_PER_AGENT) {
242
+ logger.warn(`Max clients reached for agent ${agentId} / 客戶端數已達上限`);
243
+ socket.write('HTTP/1.1 503 Service Unavailable\r\n\r\n');
244
+ socket.destroy();
245
+ return;
246
+ }
247
+ // Complete WebSocket handshake / 完成 WebSocket 交握
248
+ if (!this.completeHandshake(req, socket))
249
+ return;
250
+ const conn = {
251
+ socket,
252
+ agentId,
253
+ connectedAt: Date.now(),
254
+ };
255
+ if (!this.clientConnections.has(agentId)) {
256
+ this.clientConnections.set(agentId, new Set());
257
+ }
258
+ this.clientConnections.get(agentId).add(conn);
259
+ this.emit('client:connected', agentId);
260
+ logger.info(`Client connected to view agent ${agentId} (total: ${this.getClientCount(agentId)}) / ` +
261
+ `客戶端已連接查看 agent`);
262
+ // Handle incoming data from client (commands to forward to agent)
263
+ // 處理從客戶端收到的資料(轉發給 agent 的指令)
264
+ socket.on('data', (data) => {
265
+ this.handleClientData(agentId, data);
266
+ });
267
+ socket.on('end', () => {
268
+ this.handleClientDisconnect(agentId, conn);
269
+ });
270
+ socket.on('close', () => {
271
+ this.handleClientDisconnect(agentId, conn);
272
+ });
273
+ socket.on('error', () => {
274
+ this.handleClientDisconnect(agentId, conn);
275
+ });
276
+ }
277
+ /** Handle data from client connection / 處理客戶端連接的資料 */
278
+ handleClientData(agentId, data) {
279
+ if (data.length < 2)
280
+ return;
281
+ const firstByte = data[0] ?? 0;
282
+ const opcode = firstByte & 0x0f;
283
+ // Close frame
284
+ if (opcode === 0x08)
285
+ return;
286
+ // Ping -> pong
287
+ if (opcode === 0x09)
288
+ return;
289
+ // Pong -> ignore
290
+ if (opcode === 0x0a)
291
+ return;
292
+ // Text frame -> forward to agent / 文字框架 -> 轉發給 agent
293
+ if (opcode === 0x01) {
294
+ const payload = this.extractPayload(data);
295
+ if (payload) {
296
+ this.forwardToAgent(agentId, payload);
297
+ }
298
+ }
299
+ }
300
+ /** Handle client disconnect / 處理客戶端斷線 */
301
+ handleClientDisconnect(agentId, conn) {
302
+ try {
303
+ conn.socket.destroy();
304
+ }
305
+ catch {
306
+ /* ignore */
307
+ }
308
+ const clients = this.clientConnections.get(agentId);
309
+ if (clients) {
310
+ clients.delete(conn);
311
+ if (clients.size === 0) {
312
+ this.clientConnections.delete(agentId);
313
+ }
314
+ }
315
+ this.emit('client:disconnected', agentId);
316
+ logger.info(`Client disconnected from agent ${agentId} (remaining: ${this.getClientCount(agentId)}) / ` +
317
+ `客戶端已從 agent 斷線`);
318
+ }
319
+ // ---------------------------------------------------------------------------
320
+ // Message forwarding / 訊息轉發
321
+ // ---------------------------------------------------------------------------
322
+ /** Broadcast a payload from agent to all subscribed clients / 將 agent 載荷廣播給所有訂閱的客戶端 */
323
+ broadcastToClients(agentId, payload) {
324
+ const clients = this.clientConnections.get(agentId);
325
+ if (!clients || clients.size === 0)
326
+ return;
327
+ // Re-frame the payload as an unmasked server->client frame
328
+ // 將載荷重新包裝為未遮罩的 server->client 框架
329
+ const frame = this.createWSFrame(payload);
330
+ const deadClients = [];
331
+ for (const client of clients) {
332
+ try {
333
+ client.socket.write(frame);
334
+ }
335
+ catch {
336
+ deadClients.push(client);
337
+ }
338
+ }
339
+ // Cleanup dead clients / 清理斷線客戶端
340
+ for (const dead of deadClients) {
341
+ clients.delete(dead);
342
+ try {
343
+ dead.socket.destroy();
344
+ }
345
+ catch {
346
+ /* ignore */
347
+ }
348
+ }
349
+ if (clients.size === 0) {
350
+ this.clientConnections.delete(agentId);
351
+ }
352
+ }
353
+ /** Forward a payload from client to the target agent / 將客戶端載荷轉發給目標 agent */
354
+ forwardToAgent(agentId, payload) {
355
+ const agentConn = this.agentConnections.get(agentId);
356
+ if (!agentConn)
357
+ return;
358
+ try {
359
+ // Re-frame as unmasked server->client frame
360
+ const frame = this.createWSFrame(payload);
361
+ agentConn.socket.write(frame);
362
+ }
363
+ catch (err) {
364
+ const message = err instanceof Error ? err.message : String(err);
365
+ logger.warn(`Failed to forward to agent ${agentId}: ${message} / 轉發失敗`);
366
+ }
367
+ }
368
+ // ---------------------------------------------------------------------------
369
+ // WebSocket helpers / WebSocket 輔助函數
370
+ // ---------------------------------------------------------------------------
371
+ /** Complete the WebSocket handshake / 完成 WebSocket 交握 */
372
+ completeHandshake(req, socket) {
373
+ const key = req.headers['sec-websocket-key'];
374
+ if (!key) {
375
+ logger.warn('Missing Sec-WebSocket-Key header / 缺少 Sec-WebSocket-Key 標頭');
376
+ socket.write('HTTP/1.1 400 Bad Request\r\n\r\n');
377
+ socket.destroy();
378
+ return false;
379
+ }
380
+ const acceptKey = createHash('sha1')
381
+ .update(key + WS_MAGIC_GUID)
382
+ .digest('base64');
383
+ socket.write('HTTP/1.1 101 Switching Protocols\r\n' +
384
+ 'Upgrade: websocket\r\n' +
385
+ 'Connection: Upgrade\r\n' +
386
+ `Sec-WebSocket-Accept: ${acceptKey}\r\n` +
387
+ '\r\n');
388
+ return true;
389
+ }
390
+ /** Create a WebSocket text frame (unmasked, server->client) / 建立 WebSocket 文字框架 */
391
+ createWSFrame(payload) {
392
+ const length = payload.length;
393
+ let header;
394
+ if (length < 126) {
395
+ header = Buffer.alloc(2);
396
+ header[0] = 0x81; // FIN + text opcode
397
+ header[1] = length;
398
+ }
399
+ else if (length < 65536) {
400
+ header = Buffer.alloc(4);
401
+ header[0] = 0x81;
402
+ header[1] = 126;
403
+ header.writeUInt16BE(length, 2);
404
+ }
405
+ else {
406
+ header = Buffer.alloc(10);
407
+ header[0] = 0x81;
408
+ header[1] = 127;
409
+ header.writeBigUInt64BE(BigInt(length), 2);
410
+ }
411
+ return Buffer.concat([header, payload]);
412
+ }
413
+ /** Extract payload from a WebSocket frame (handles both masked and unmasked) / 提取 WebSocket 框架載荷 */
414
+ extractPayload(data) {
415
+ if (data.length < 2)
416
+ return null;
417
+ const secondByte = data[1] ?? 0;
418
+ const masked = (secondByte & 0x80) !== 0;
419
+ let payloadLength = secondByte & 0x7f;
420
+ let offset = 2;
421
+ if (payloadLength === 126) {
422
+ if (data.length < 4)
423
+ return null;
424
+ payloadLength = data.readUInt16BE(2);
425
+ offset = 4;
426
+ }
427
+ else if (payloadLength === 127) {
428
+ if (data.length < 10)
429
+ return null;
430
+ payloadLength = Number(data.readBigUInt64BE(2));
431
+ offset = 10;
432
+ }
433
+ if (masked) {
434
+ if (data.length < offset + 4 + payloadLength)
435
+ return null;
436
+ const maskKey = data.subarray(offset, offset + 4);
437
+ offset += 4;
438
+ const payload = Buffer.alloc(payloadLength);
439
+ for (let i = 0; i < payloadLength; i++) {
440
+ payload[i] = (data[offset + i] ?? 0) ^ (maskKey[i % 4] ?? 0);
441
+ }
442
+ return payload;
443
+ }
444
+ if (data.length < offset + payloadLength)
445
+ return null;
446
+ return data.subarray(offset, offset + payloadLength);
447
+ }
448
+ /** Send a pong frame / 發送 pong 框架 */
449
+ sendPong(socket) {
450
+ if (!socket)
451
+ return;
452
+ try {
453
+ const pong = Buffer.alloc(2);
454
+ pong[0] = 0x8a; // FIN + pong
455
+ pong[1] = 0x00; // 0 payload
456
+ socket.write(pong);
457
+ }
458
+ catch {
459
+ /* ignore */
460
+ }
461
+ }
462
+ }
463
+ //# sourceMappingURL=dashboard-relay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-relay.js","sourceRoot":"","sources":["../src/dashboard-relay.ts"],"names":[],"mappings":"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"}