@yu_robotics/remote-cli-router 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.
Files changed (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +115 -0
  3. package/bin/remote-cli-router.js +2 -0
  4. package/dist/binding/BindingManager.d.ts +62 -0
  5. package/dist/binding/BindingManager.d.ts.map +1 -0
  6. package/dist/binding/BindingManager.js +119 -0
  7. package/dist/binding/BindingManager.js.map +1 -0
  8. package/dist/cli.d.ts +3 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +32 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/commands/config.d.ts +19 -0
  13. package/dist/commands/config.d.ts.map +1 -0
  14. package/dist/commands/config.js +206 -0
  15. package/dist/commands/config.js.map +1 -0
  16. package/dist/commands/start.d.ts +5 -0
  17. package/dist/commands/start.d.ts.map +1 -0
  18. package/dist/commands/start.js +65 -0
  19. package/dist/commands/start.js.map +1 -0
  20. package/dist/commands/status.d.ts +5 -0
  21. package/dist/commands/status.d.ts.map +1 -0
  22. package/dist/commands/status.js +103 -0
  23. package/dist/commands/status.js.map +1 -0
  24. package/dist/commands/stop.d.ts +5 -0
  25. package/dist/commands/stop.d.ts.map +1 -0
  26. package/dist/commands/stop.js +56 -0
  27. package/dist/commands/stop.js.map +1 -0
  28. package/dist/config/ConfigManager.d.ts +46 -0
  29. package/dist/config/ConfigManager.d.ts.map +1 -0
  30. package/dist/config/ConfigManager.js +101 -0
  31. package/dist/config/ConfigManager.js.map +1 -0
  32. package/dist/feishu/FeishuClient.d.ts +46 -0
  33. package/dist/feishu/FeishuClient.d.ts.map +1 -0
  34. package/dist/feishu/FeishuClient.js +130 -0
  35. package/dist/feishu/FeishuClient.js.map +1 -0
  36. package/dist/feishu/FeishuLongConnHandler.d.ts +149 -0
  37. package/dist/feishu/FeishuLongConnHandler.d.ts.map +1 -0
  38. package/dist/feishu/FeishuLongConnHandler.js +632 -0
  39. package/dist/feishu/FeishuLongConnHandler.js.map +1 -0
  40. package/dist/server.d.ts +80 -0
  41. package/dist/server.d.ts.map +1 -0
  42. package/dist/server.js +533 -0
  43. package/dist/server.js.map +1 -0
  44. package/dist/storage/JsonStore.d.ts +90 -0
  45. package/dist/storage/JsonStore.d.ts.map +1 -0
  46. package/dist/storage/JsonStore.js +215 -0
  47. package/dist/storage/JsonStore.js.map +1 -0
  48. package/dist/storage/MemoryStore.d.ts +69 -0
  49. package/dist/storage/MemoryStore.d.ts.map +1 -0
  50. package/dist/storage/MemoryStore.js +117 -0
  51. package/dist/storage/MemoryStore.js.map +1 -0
  52. package/dist/types/config.d.ts +53 -0
  53. package/dist/types/config.d.ts.map +1 -0
  54. package/dist/types/config.js +31 -0
  55. package/dist/types/config.js.map +1 -0
  56. package/dist/types/index.d.ts +93 -0
  57. package/dist/types/index.d.ts.map +1 -0
  58. package/dist/types/index.js +18 -0
  59. package/dist/types/index.js.map +1 -0
  60. package/dist/utils/PidManager.d.ts +28 -0
  61. package/dist/utils/PidManager.d.ts.map +1 -0
  62. package/dist/utils/PidManager.js +90 -0
  63. package/dist/utils/PidManager.js.map +1 -0
  64. package/dist/utils/ToolFormatter.d.ts +41 -0
  65. package/dist/utils/ToolFormatter.d.ts.map +1 -0
  66. package/dist/utils/ToolFormatter.js +273 -0
  67. package/dist/utils/ToolFormatter.js.map +1 -0
  68. package/dist/websocket/ConnectionHub.d.ts +73 -0
  69. package/dist/websocket/ConnectionHub.d.ts.map +1 -0
  70. package/dist/websocket/ConnectionHub.js +177 -0
  71. package/dist/websocket/ConnectionHub.js.map +1 -0
  72. package/package.json +70 -0
@@ -0,0 +1,632 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.FeishuLongConnHandler = void 0;
37
+ const lark = __importStar(require("@larksuiteoapi/node-sdk"));
38
+ const uuid_1 = require("uuid");
39
+ const BindingManager_1 = require("../binding/BindingManager");
40
+ const types_1 = require("../types");
41
+ /**
42
+ * Feishu Long Connection Handler
43
+ * Uses Feishu SDK's WSClient for WebSocket long connection
44
+ */
45
+ class FeishuLongConnHandler {
46
+ client;
47
+ wsClient = null;
48
+ bindingManager;
49
+ connectionHub = null;
50
+ appId;
51
+ appSecret;
52
+ // Feishu message size limit (4000 chars per message)
53
+ FEISHU_MESSAGE_LIMIT = 4000;
54
+ // Track message chains: messageId -> [messageId1, messageId2, ...]
55
+ messageChains = new Map();
56
+ // Track the last processed text length for each message chain
57
+ // This helps us only send NEW content to existing messages, preventing duplication
58
+ lastProcessedLengths = new Map();
59
+ // Per-message serialization locks to prevent concurrent updates from creating duplicates
60
+ messageLocks = new Map();
61
+ // Pattern to match tool use separator lines
62
+ TOOL_USE_PATTERN = /─+ TOOL USE ─+/;
63
+ TOOL_SEPARATOR_PATTERN = /─{20,}/;
64
+ constructor(config) {
65
+ this.appId = config.appId;
66
+ this.appSecret = config.appSecret;
67
+ this.bindingManager = new BindingManager_1.BindingManager(config.store);
68
+ // Initialize Feishu SDK client for API calls
69
+ this.client = new lark.Client({
70
+ appId: config.appId,
71
+ appSecret: config.appSecret,
72
+ appType: lark.AppType.SelfBuild,
73
+ domain: lark.Domain.Feishu,
74
+ });
75
+ }
76
+ /**
77
+ * Set ConnectionHub (called from RouterServer)
78
+ */
79
+ setConnectionHub(hub) {
80
+ this.connectionHub = hub;
81
+ }
82
+ /**
83
+ * Callback to register streaming message with RouterServer
84
+ */
85
+ onStartStreaming;
86
+ /**
87
+ * Set streaming start callback
88
+ */
89
+ setOnStartStreaming(callback) {
90
+ this.onStartStreaming = callback;
91
+ }
92
+ /**
93
+ * Handle message event
94
+ */
95
+ async handleMessageEvent(data) {
96
+ try {
97
+ const message = data.message;
98
+ const sender = data.sender;
99
+ // Skip non-text messages
100
+ if (message.message_type !== 'text') {
101
+ return;
102
+ }
103
+ const openId = sender.sender_id.open_id;
104
+ const messageId = message.message_id;
105
+ const content = this.parseMessageContent(message);
106
+ console.log(`[FeishuHandler] Received message from ${openId}: ${content}, msgId=${messageId}`);
107
+ // Check if it's a command
108
+ if (this.isCommand(content)) {
109
+ await this.handleCommand(openId, messageId, content);
110
+ }
111
+ else {
112
+ console.log(`[FeishuHandler] Handling regular command, msgId=${messageId}`);
113
+ await this.handleRegularCommand(openId, messageId, content);
114
+ console.log(`[FeishuHandler] Finished handling regular command, msgId=${messageId}`);
115
+ }
116
+ }
117
+ catch (error) {
118
+ console.error('Error in handleMessageEvent:', error);
119
+ }
120
+ }
121
+ /**
122
+ * Parse message content
123
+ */
124
+ parseMessageContent(message) {
125
+ try {
126
+ const content = JSON.parse(message.content);
127
+ return (content.text || '').trim();
128
+ }
129
+ catch (error) {
130
+ return '';
131
+ }
132
+ }
133
+ /**
134
+ * Check if it's a command
135
+ */
136
+ isCommand(content) {
137
+ return content.startsWith('/');
138
+ }
139
+ /**
140
+ * Handle command
141
+ */
142
+ async handleCommand(openId, messageId, content) {
143
+ const parts = content.split(/\s+/);
144
+ const command = parts[0].toLowerCase();
145
+ switch (command) {
146
+ case '/bind':
147
+ if (parts.length >= 2) {
148
+ await this.handleBindCommand(openId, messageId, parts[1]);
149
+ }
150
+ else {
151
+ await this.replyToMessage(messageId, 'Please provide binding code, format: /bind ABC-123-XYZ');
152
+ }
153
+ break;
154
+ case '/status':
155
+ await this.handleStatusCommand(openId, messageId);
156
+ break;
157
+ case '/unbind':
158
+ await this.handleUnbindCommand(openId, messageId);
159
+ break;
160
+ case '/help':
161
+ await this.handleHelpCommand(openId, messageId);
162
+ break;
163
+ default:
164
+ // Pass through unknown slash commands to the client
165
+ // This allows users to use their local Claude Code custom commands
166
+ await this.handleSlashCommandPassthrough(openId, messageId, content, command);
167
+ }
168
+ }
169
+ /**
170
+ * Handle slash command passthrough to client
171
+ * Passes unknown slash commands to the local Claude Code instance
172
+ */
173
+ async handleSlashCommandPassthrough(openId, messageId, content, command) {
174
+ try {
175
+ // Find user binding
176
+ const binding = await this.bindingManager.getUserBinding(openId);
177
+ if (!binding) {
178
+ await this.replyToMessage(messageId, '❌ You have not bound a device yet, please send /bind <binding-code> to bind first');
179
+ return;
180
+ }
181
+ // Check if ConnectionHub is available
182
+ if (!this.connectionHub) {
183
+ await this.replyToMessage(messageId, '❌ Server error: ConnectionHub not initialized');
184
+ return;
185
+ }
186
+ // Check if device is online
187
+ if (!this.connectionHub.isDeviceOnline(binding.deviceId)) {
188
+ await this.replyToMessage(messageId, `❌ Device ${binding.deviceName} is currently offline, please ensure the device is started and connected to the server`);
189
+ return;
190
+ }
191
+ console.log(`[FeishuHandler] Passing through slash command: ${command}`);
192
+ // Generate message ID first
193
+ const commandMessageId = (0, uuid_1.v4)();
194
+ // Register streaming session BEFORE sending command
195
+ const feishuMessageId = await this.sendStreamingStart(openId, `🤔 Executing ${command}...`);
196
+ console.log(`[FeishuHandler] Created card ${feishuMessageId} for slash command ${commandMessageId}`);
197
+ if (this.onStartStreaming) {
198
+ this.onStartStreaming(commandMessageId, openId, feishuMessageId, binding.deviceId);
199
+ }
200
+ // Send slash command to device - the client will execute it locally
201
+ const success = await this.connectionHub.sendToDevice(binding.deviceId, {
202
+ type: types_1.MessageType.COMMAND,
203
+ messageId: commandMessageId,
204
+ timestamp: Date.now(),
205
+ content, // Send the full command including arguments
206
+ openId,
207
+ isSlashCommand: true, // Flag to indicate this is a slash command
208
+ });
209
+ if (!success) {
210
+ await this.replyToMessage(messageId, '❌ Command sending failed, please try again later');
211
+ }
212
+ }
213
+ catch (error) {
214
+ console.error('Error handling slash command passthrough:', error);
215
+ await this.replyToMessage(messageId, '❌ Error processing command, please try again later');
216
+ }
217
+ }
218
+ /**
219
+ * Handle bind command
220
+ */
221
+ async handleBindCommand(openId, messageId, code) {
222
+ try {
223
+ // Verify binding code
224
+ const bindingCode = await this.bindingManager.verifyBindingCode(code);
225
+ if (!bindingCode) {
226
+ await this.replyToMessage(messageId, '❌ Binding code is invalid or expired, please generate a new one');
227
+ return;
228
+ }
229
+ // Bind user
230
+ const deviceName = 'Device'; // Will be updated by client later
231
+ await this.bindingManager.bindUser(openId, bindingCode.deviceId, deviceName);
232
+ await this.replyToMessage(messageId, `✅ Binding successful!\n\nDevice ID: ${bindingCode.deviceId}\n\nYou can now control your device through Feishu.`);
233
+ }
234
+ catch (error) {
235
+ console.error('Error binding user:', error);
236
+ await this.replyToMessage(messageId, '❌ Binding failed, please try again later');
237
+ }
238
+ }
239
+ /**
240
+ * Handle status command
241
+ */
242
+ async handleStatusCommand(openId, messageId) {
243
+ try {
244
+ const binding = await this.bindingManager.getUserBinding(openId);
245
+ if (!binding) {
246
+ await this.replyToMessage(messageId, '❌ You have not bound a device yet, please send /bind <binding-code> to bind first');
247
+ return;
248
+ }
249
+ const isOnline = this.connectionHub?.isDeviceOnline(binding.deviceId) || false;
250
+ const status = isOnline ? '🟢 Online' : '🔴 Offline';
251
+ const message = `📊 Device Status\n\nDevice Name: ${binding.deviceName}\nDevice ID: ${binding.deviceId}\nStatus: ${status}\nBinding Time: ${new Date(binding.boundAt).toLocaleString('en-US')}`;
252
+ await this.replyToMessage(messageId, message);
253
+ }
254
+ catch (error) {
255
+ console.error('Error handling status command:', error);
256
+ await this.replyToMessage(messageId, '❌ Status query failed, please try again later');
257
+ }
258
+ }
259
+ /**
260
+ * Handle unbind command
261
+ */
262
+ async handleUnbindCommand(openId, messageId) {
263
+ try {
264
+ const binding = await this.bindingManager.getUserBinding(openId);
265
+ if (!binding) {
266
+ await this.replyToMessage(messageId, '❌ You have not bound a device yet');
267
+ return;
268
+ }
269
+ await this.bindingManager.unbindUser(openId);
270
+ await this.replyToMessage(messageId, `✅ Device ${binding.deviceName} has been unbound`);
271
+ }
272
+ catch (error) {
273
+ console.error('Error handling unbind command:', error);
274
+ await this.replyToMessage(messageId, '❌ Unbinding failed, please try again later');
275
+ }
276
+ }
277
+ /**
278
+ * Handle help command
279
+ */
280
+ async handleHelpCommand(openId, messageId) {
281
+ const helpMessage = `📖 Feishu Remote Control Help
282
+
283
+ Available commands:
284
+ /bind <binding-code> - Bind your device
285
+ /status - View device status
286
+ /unbind - Unbind device
287
+ /help - Show help information
288
+
289
+ Regular messages will be sent directly to your device for execution.
290
+
291
+ Examples:
292
+ • "List files in current directory"
293
+ • "Run tests"
294
+ • "View recent git commits"`;
295
+ await this.replyToMessage(messageId, helpMessage);
296
+ }
297
+ /**
298
+ * Handle regular command (non-slash commands)
299
+ */
300
+ async handleRegularCommand(openId, messageId, content) {
301
+ try {
302
+ // Find user binding
303
+ const binding = await this.bindingManager.getUserBinding(openId);
304
+ if (!binding) {
305
+ await this.replyToMessage(messageId, '❌ You have not bound a device yet, please send /bind <binding-code> to bind first');
306
+ return;
307
+ }
308
+ // Check if ConnectionHub is available
309
+ if (!this.connectionHub) {
310
+ await this.replyToMessage(messageId, '❌ Server error: ConnectionHub not initialized');
311
+ return;
312
+ }
313
+ // Check if device is online
314
+ if (!this.connectionHub.isDeviceOnline(binding.deviceId)) {
315
+ await this.replyToMessage(messageId, `❌ Device ${binding.deviceName} is currently offline, please ensure the device is started and connected to the server`);
316
+ return;
317
+ }
318
+ // Generate message ID first
319
+ const commandMessageId = (0, uuid_1.v4)();
320
+ console.log(`[FeishuHandler] Creating streaming card for command ${commandMessageId}`);
321
+ // Register streaming session BEFORE sending command to avoid race condition
322
+ // where stream chunks arrive before registration
323
+ const feishuMessageId = await this.sendStreamingStart(openId, '🤔 Processing...');
324
+ console.log(`[FeishuHandler] Created card ${feishuMessageId} for command ${commandMessageId}`);
325
+ if (this.onStartStreaming) {
326
+ this.onStartStreaming(commandMessageId, openId, feishuMessageId, binding.deviceId);
327
+ }
328
+ // Send command to device
329
+ const success = await this.connectionHub.sendToDevice(binding.deviceId, {
330
+ type: types_1.MessageType.COMMAND,
331
+ messageId: commandMessageId,
332
+ timestamp: Date.now(),
333
+ content,
334
+ openId
335
+ });
336
+ if (!success) {
337
+ // Send failed - delete the streaming session and notify user
338
+ if (this.onStartStreaming) {
339
+ // We need a way to clean up, for now just send error as new message
340
+ await this.replyToMessage(messageId, '❌ Command sending failed, please try again later');
341
+ }
342
+ }
343
+ }
344
+ catch (error) {
345
+ console.error('Error handling regular command:', error);
346
+ await this.replyToMessage(messageId, '❌ Error processing command, please try again later');
347
+ }
348
+ }
349
+ /**
350
+ * Reply to a message
351
+ */
352
+ async replyToMessage(messageId, text) {
353
+ try {
354
+ await this.client.im.message.reply({
355
+ path: { message_id: messageId },
356
+ data: {
357
+ msg_type: 'text',
358
+ content: JSON.stringify({ text }),
359
+ },
360
+ });
361
+ }
362
+ catch (error) {
363
+ console.error('Failed to reply to message:', error?.message || error);
364
+ }
365
+ }
366
+ /**
367
+ * Send message to user
368
+ */
369
+ async sendMessage(openId, text) {
370
+ try {
371
+ await this.client.im.message.create({
372
+ params: { receive_id_type: 'open_id' },
373
+ data: {
374
+ receive_id: openId,
375
+ msg_type: 'text',
376
+ content: JSON.stringify({ text }),
377
+ },
378
+ });
379
+ return true;
380
+ }
381
+ catch (error) {
382
+ console.error('Failed to send message:', error?.message || error);
383
+ return false;
384
+ }
385
+ }
386
+ /**
387
+ * Send streaming message with card update support
388
+ * Returns message_id for updating
389
+ */
390
+ async sendStreamingStart(openId, initialText = '🤔 Thinking...') {
391
+ console.log(`[FeishuHandler] Creating interactive card v2 for ${openId}`);
392
+ try {
393
+ const result = await this.client.im.message.create({
394
+ params: { receive_id_type: 'open_id' },
395
+ data: {
396
+ receive_id: openId,
397
+ msg_type: 'interactive',
398
+ content: JSON.stringify({
399
+ schema: '2.0',
400
+ body: {
401
+ elements: [
402
+ {
403
+ tag: 'markdown',
404
+ content: initialText,
405
+ },
406
+ ],
407
+ },
408
+ }),
409
+ },
410
+ });
411
+ return result?.data?.message_id || null;
412
+ }
413
+ catch (error) {
414
+ console.error('Failed to send streaming start:', error?.message || error);
415
+ return null;
416
+ }
417
+ }
418
+ /**
419
+ * Serialize async operations per messageId to prevent race conditions.
420
+ * Concurrent calls for the same messageId will queue and execute in order.
421
+ */
422
+ async withMessageLock(messageId, fn) {
423
+ const previous = this.messageLocks.get(messageId) || Promise.resolve();
424
+ const current = previous.then(fn, fn); // Run fn after previous completes (even if it failed)
425
+ this.messageLocks.set(messageId, current);
426
+ try {
427
+ return await current;
428
+ }
429
+ finally {
430
+ // Clean up lock if this is still the latest operation
431
+ if (this.messageLocks.get(messageId) === current) {
432
+ this.messageLocks.delete(messageId);
433
+ }
434
+ }
435
+ }
436
+ /**
437
+ * Split text into chunks that fit within Feishu's message size limit
438
+ * Tries to split at newlines to keep context intact
439
+ *
440
+ * Reserves space for continuation indicators:
441
+ * - "~➡️ Continued in next message...~" (40 chars) at end of non-final chunks
442
+ * - "~⬅️ Continued from previous message...~" (44 chars) at start of continuation chunks
443
+ */
444
+ splitTextIntoChunks(text, limit = this.FEISHU_MESSAGE_LIMIT) {
445
+ // Reserve space for continuation indicator
446
+ const continuationOverhead = 50; // "\n\n_➡️ Continued in next message..._"
447
+ const effectiveLimit = limit - continuationOverhead;
448
+ if (text.length <= limit) {
449
+ return [text];
450
+ }
451
+ const chunks = [];
452
+ let remainingText = text;
453
+ while (remainingText.length > 0) {
454
+ if (remainingText.length <= limit) {
455
+ chunks.push(remainingText);
456
+ break;
457
+ }
458
+ // Try to find a good split point (newline, space, or just at limit)
459
+ let splitPoint = effectiveLimit;
460
+ // Look for last newline before limit
461
+ const lastNewline = remainingText.lastIndexOf('\n', effectiveLimit);
462
+ if (lastNewline > effectiveLimit * 0.7) { // Only split at newline if it's not too far back
463
+ splitPoint = lastNewline + 1;
464
+ }
465
+ else {
466
+ // Look for last space before limit
467
+ const lastSpace = remainingText.lastIndexOf(' ', effectiveLimit);
468
+ if (lastSpace > effectiveLimit * 0.8) { // Only split at space if it's close to limit
469
+ splitPoint = lastSpace + 1;
470
+ }
471
+ }
472
+ chunks.push(remainingText.substring(0, splitPoint));
473
+ remainingText = remainingText.substring(splitPoint);
474
+ }
475
+ return chunks;
476
+ }
477
+ /**
478
+ * Update streaming message content
479
+ * Automatically creates new messages if content exceeds Feishu's size limit
480
+ *
481
+ * This method uses an incremental approach to prevent content duplication:
482
+ * - Once a message (except the last one) is created, its content is frozen
483
+ * - Only the last message in the chain gets updated with new content
484
+ * - New messages are only created when the last message exceeds the limit
485
+ *
486
+ * @param messageId The Feishu message ID
487
+ * @param elements Array of Feishu Card 2.0 elements
488
+ * @param openId User's open_id for creating continuation messages
489
+ */
490
+ async updateStreamingMessage(messageId, elements, openId) {
491
+ return this.withMessageLock(messageId, () => this._updateStreamingMessage(messageId, elements, openId));
492
+ }
493
+ async _updateStreamingMessage(messageId, elements, openId) {
494
+ try {
495
+ // Get or initialize message chain
496
+ let chain = this.messageChains.get(messageId);
497
+ if (!chain) {
498
+ chain = [messageId]; // First message in chain
499
+ this.messageChains.set(messageId, chain);
500
+ }
501
+ // For now, just update the single message with all elements
502
+ // TODO: In the future, implement message chaining if elements become too large
503
+ await this.client.im.message.patch({
504
+ path: { message_id: messageId },
505
+ data: {
506
+ content: JSON.stringify({
507
+ schema: '2.0',
508
+ body: {
509
+ elements,
510
+ },
511
+ }),
512
+ },
513
+ });
514
+ return true;
515
+ }
516
+ catch (error) {
517
+ console.error('Failed to update streaming message:', error?.message || error);
518
+ return false;
519
+ }
520
+ }
521
+ /**
522
+ * Finalize streaming message
523
+ * Automatically creates new messages if content exceeds Feishu's size limit
524
+ *
525
+ * @param messageId The Feishu message ID
526
+ * @param elements Array of Feishu Card 2.0 elements
527
+ * @param sessionAbbr Optional session abbreviation
528
+ * @param openId User's open_id for creating continuation messages
529
+ */
530
+ async finalizeStreamingMessage(messageId, elements, sessionAbbr, openId) {
531
+ return this.withMessageLock(messageId, () => this._finalizeStreamingMessage(messageId, elements, sessionAbbr, openId));
532
+ }
533
+ async _finalizeStreamingMessage(messageId, elements, sessionAbbr, openId) {
534
+ try {
535
+ // Get or initialize message chain
536
+ let chain = this.messageChains.get(messageId);
537
+ if (!chain) {
538
+ chain = [messageId];
539
+ this.messageChains.set(messageId, chain);
540
+ }
541
+ // Build note content with session abbreviation if available
542
+ let noteContent = '✅ Completed';
543
+ if (sessionAbbr) {
544
+ noteContent += ` · Session: ${sessionAbbr}`;
545
+ }
546
+ // Add completion note element as markdown
547
+ const finalElements = [
548
+ ...elements,
549
+ {
550
+ tag: 'markdown',
551
+ content: noteContent,
552
+ },
553
+ ];
554
+ // Update the message with final content
555
+ // TODO: In the future, implement message chaining if elements become too large
556
+ await this.client.im.message.patch({
557
+ path: { message_id: messageId },
558
+ data: {
559
+ content: JSON.stringify({
560
+ schema: '2.0',
561
+ body: {
562
+ elements: finalElements,
563
+ },
564
+ }),
565
+ },
566
+ });
567
+ // Clean up message chain tracking
568
+ this.messageChains.delete(messageId);
569
+ this.lastProcessedLengths.delete(messageId);
570
+ return true;
571
+ }
572
+ catch (error) {
573
+ console.error('Failed to finalize streaming message:', error?.message || error);
574
+ return false;
575
+ }
576
+ }
577
+ /**
578
+ * Start the Feishu WebSocket long connection
579
+ */
580
+ async start() {
581
+ try {
582
+ console.log('Starting Feishu WebSocket long connection...');
583
+ // Create WSClient with event dispatcher
584
+ this.wsClient = new lark.WSClient({
585
+ appId: this.appId,
586
+ appSecret: this.appSecret,
587
+ loggerLevel: lark.LoggerLevel.info,
588
+ });
589
+ // Start WebSocket client with event handler
590
+ await this.wsClient.start({
591
+ eventDispatcher: new lark.EventDispatcher({}).register({
592
+ 'im.message.receive_v1': async (data) => {
593
+ await this.handleMessageEvent(data);
594
+ }
595
+ })
596
+ });
597
+ console.log('✅ Feishu WebSocket long connection established');
598
+ console.log(' Listening for messages from Feishu...');
599
+ }
600
+ catch (error) {
601
+ console.error('Failed to start Feishu WebSocket connection:', error);
602
+ throw error;
603
+ }
604
+ }
605
+ /**
606
+ * Stop the Feishu connection
607
+ */
608
+ async stop() {
609
+ try {
610
+ console.log('Stopping Feishu WebSocket connection...');
611
+ // Close WebSocket connection
612
+ if (this.wsClient) {
613
+ // The SDK doesn't provide a stop method, but closing the instance should work
614
+ this.wsClient = null;
615
+ }
616
+ await this.bindingManager.close();
617
+ console.log('✅ Feishu WebSocket connection stopped');
618
+ }
619
+ catch (error) {
620
+ console.error('Error stopping Feishu WebSocket connection:', error);
621
+ throw error;
622
+ }
623
+ }
624
+ /**
625
+ * Get BindingManager instance
626
+ */
627
+ getBindingManager() {
628
+ return this.bindingManager;
629
+ }
630
+ }
631
+ exports.FeishuLongConnHandler = FeishuLongConnHandler;
632
+ //# sourceMappingURL=FeishuLongConnHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeishuLongConnHandler.js","sourceRoot":"","sources":["../../src/feishu/FeishuLongConnHandler.ts"],"names":[],"mappings":"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"}