botmux 2.2.7 → 2.3.1

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 (121) hide show
  1. package/README.en.md +63 -13
  2. package/README.md +52 -14
  3. package/dist/adapters/backend/tmux-backend.d.ts +8 -0
  4. package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
  5. package/dist/adapters/backend/tmux-backend.js +18 -0
  6. package/dist/adapters/backend/tmux-backend.js.map +1 -1
  7. package/dist/adapters/cli/aiden.d.ts.map +1 -1
  8. package/dist/adapters/cli/aiden.js +0 -40
  9. package/dist/adapters/cli/aiden.js.map +1 -1
  10. package/dist/adapters/cli/claude-code.d.ts.map +1 -1
  11. package/dist/adapters/cli/claude-code.js +21 -67
  12. package/dist/adapters/cli/claude-code.js.map +1 -1
  13. package/dist/adapters/cli/coco.d.ts.map +1 -1
  14. package/dist/adapters/cli/coco.js +0 -33
  15. package/dist/adapters/cli/coco.js.map +1 -1
  16. package/dist/adapters/cli/codex.d.ts.map +1 -1
  17. package/dist/adapters/cli/codex.js +0 -27
  18. package/dist/adapters/cli/codex.js.map +1 -1
  19. package/dist/adapters/cli/gemini.d.ts.map +1 -1
  20. package/dist/adapters/cli/gemini.js +1 -29
  21. package/dist/adapters/cli/gemini.js.map +1 -1
  22. package/dist/adapters/cli/opencode.d.ts.map +1 -1
  23. package/dist/adapters/cli/opencode.js +1 -44
  24. package/dist/adapters/cli/opencode.js.map +1 -1
  25. package/dist/adapters/cli/types.d.ts +11 -8
  26. package/dist/adapters/cli/types.d.ts.map +1 -1
  27. package/dist/cli.js +737 -16
  28. package/dist/cli.js.map +1 -1
  29. package/dist/config.d.ts +16 -0
  30. package/dist/config.d.ts.map +1 -1
  31. package/dist/config.js +30 -0
  32. package/dist/config.js.map +1 -1
  33. package/dist/core/command-handler.d.ts.map +1 -1
  34. package/dist/core/command-handler.js +8 -4
  35. package/dist/core/command-handler.js.map +1 -1
  36. package/dist/core/scheduler.d.ts +38 -16
  37. package/dist/core/scheduler.d.ts.map +1 -1
  38. package/dist/core/scheduler.js +335 -149
  39. package/dist/core/scheduler.js.map +1 -1
  40. package/dist/core/session-manager.d.ts +6 -0
  41. package/dist/core/session-manager.d.ts.map +1 -1
  42. package/dist/core/session-manager.js +105 -16
  43. package/dist/core/session-manager.js.map +1 -1
  44. package/dist/core/types.d.ts +26 -4
  45. package/dist/core/types.d.ts.map +1 -1
  46. package/dist/core/types.js +6 -0
  47. package/dist/core/types.js.map +1 -1
  48. package/dist/core/worker-pool.d.ts +15 -3
  49. package/dist/core/worker-pool.d.ts.map +1 -1
  50. package/dist/core/worker-pool.js +233 -31
  51. package/dist/core/worker-pool.js.map +1 -1
  52. package/dist/daemon.d.ts.map +1 -1
  53. package/dist/daemon.js +49 -10
  54. package/dist/daemon.js.map +1 -1
  55. package/dist/im/lark/card-builder.d.ts +29 -1
  56. package/dist/im/lark/card-builder.d.ts.map +1 -1
  57. package/dist/im/lark/card-builder.js +241 -55
  58. package/dist/im/lark/card-builder.js.map +1 -1
  59. package/dist/im/lark/card-handler.d.ts +1 -0
  60. package/dist/im/lark/card-handler.d.ts.map +1 -1
  61. package/dist/im/lark/card-handler.js +195 -40
  62. package/dist/im/lark/card-handler.js.map +1 -1
  63. package/dist/services/schedule-store.d.ts +20 -3
  64. package/dist/services/schedule-store.d.ts.map +1 -1
  65. package/dist/services/schedule-store.js +140 -16
  66. package/dist/services/schedule-store.js.map +1 -1
  67. package/dist/skills/definitions.d.ts +17 -0
  68. package/dist/skills/definitions.d.ts.map +1 -0
  69. package/dist/skills/definitions.js +254 -0
  70. package/dist/skills/definitions.js.map +1 -0
  71. package/dist/skills/installer.d.ts +9 -0
  72. package/dist/skills/installer.d.ts.map +1 -0
  73. package/dist/skills/installer.js +42 -0
  74. package/dist/skills/installer.js.map +1 -0
  75. package/dist/types.d.ts +84 -7
  76. package/dist/types.d.ts.map +1 -1
  77. package/dist/types.js +1 -5
  78. package/dist/types.js.map +1 -1
  79. package/dist/utils/lark-upload.d.ts +2 -0
  80. package/dist/utils/lark-upload.d.ts.map +1 -0
  81. package/dist/utils/lark-upload.js +27 -0
  82. package/dist/utils/lark-upload.js.map +1 -0
  83. package/dist/utils/screen-analyzer.d.ts +67 -0
  84. package/dist/utils/screen-analyzer.d.ts.map +1 -0
  85. package/dist/utils/screen-analyzer.js +279 -0
  86. package/dist/utils/screen-analyzer.js.map +1 -0
  87. package/dist/utils/screenshot-renderer.d.ts +11 -0
  88. package/dist/utils/screenshot-renderer.d.ts.map +1 -0
  89. package/dist/utils/screenshot-renderer.js +225 -0
  90. package/dist/utils/screenshot-renderer.js.map +1 -0
  91. package/dist/utils/terminal-renderer.d.ts +30 -0
  92. package/dist/utils/terminal-renderer.d.ts.map +1 -1
  93. package/dist/utils/terminal-renderer.js +25 -0
  94. package/dist/utils/terminal-renderer.js.map +1 -1
  95. package/dist/worker.js +372 -14
  96. package/dist/worker.js.map +1 -1
  97. package/package.json +2 -5
  98. package/dist/index.d.ts +0 -3
  99. package/dist/index.d.ts.map +0 -1
  100. package/dist/index.js +0 -16
  101. package/dist/index.js.map +0 -1
  102. package/dist/server.d.ts +0 -3
  103. package/dist/server.d.ts.map +0 -1
  104. package/dist/server.js +0 -133
  105. package/dist/server.js.map +0 -1
  106. package/dist/tools/get-thread-messages.d.ts +0 -26
  107. package/dist/tools/get-thread-messages.d.ts.map +0 -1
  108. package/dist/tools/get-thread-messages.js +0 -38
  109. package/dist/tools/get-thread-messages.js.map +0 -1
  110. package/dist/tools/index.d.ts +0 -9
  111. package/dist/tools/index.d.ts.map +0 -1
  112. package/dist/tools/index.js +0 -10
  113. package/dist/tools/index.js.map +0 -1
  114. package/dist/tools/list-bots.d.ts +0 -40
  115. package/dist/tools/list-bots.d.ts.map +0 -1
  116. package/dist/tools/list-bots.js +0 -77
  117. package/dist/tools/list-bots.js.map +0 -1
  118. package/dist/tools/send-to-thread.d.ts +0 -46
  119. package/dist/tools/send-to-thread.d.ts.map +0 -1
  120. package/dist/tools/send-to-thread.js +0 -275
  121. package/dist/tools/send-to-thread.js.map +0 -1
@@ -1,275 +0,0 @@
1
- import { z } from 'zod';
2
- import { readFileSync, writeFileSync, mkdirSync, readdirSync, existsSync } from 'node:fs';
3
- import { join } from 'node:path';
4
- import { replyMessage, uploadImage, uploadFile } from '../im/lark/client.js';
5
- import { config } from '../config.js';
6
- import * as sessionStore from '../services/session-store.js';
7
- import { logger } from '../utils/logger.js';
8
- export const schema = z.object({
9
- session_id: z.string().optional().describe('Session ID for the active session (auto-detected if omitted)'),
10
- content: z.string().describe('Message text to send (plain text). Can be empty string when sending only images/files.'),
11
- images: z.array(z.string()).optional().describe('Optional local file paths of images to attach (e.g. ["/tmp/chart.png"]). Images are embedded inline in the message.'),
12
- files: z.array(z.string()).optional().describe('Optional local file paths of files to attach (e.g. ["/tmp/report.pdf"]). Each file is sent as a separate message.'),
13
- mentions: z.array(z.object({
14
- open_id: z.string().describe('Open ID of the user/bot to @mention'),
15
- name: z.string().describe('Display name for the @mention'),
16
- })).optional().describe('Optional list of users/bots to @mention in the message. Get open_ids from list_bots tool.'),
17
- });
18
- export const description = 'Send a message to the Lark thread associated with a session. Supports plain text, images (embedded inline), and file attachments. Just send plain text — formatting is handled automatically. Use `images` to attach local image files (png/jpg/gif etc.) and `files` to attach documents.';
19
- /** Build a post content block from plain text, splitting by newlines into paragraphs.
20
- * When mentions are provided, @Name patterns in the text are replaced with inline `at` tags. */
21
- function textToPostContent(text, mentions) {
22
- // Build a regex that matches any @Name from the mentions list
23
- let mentionPattern = null;
24
- const mentionMap = new Map(); // lowercase name -> open_id
25
- if (mentions && mentions.length > 0) {
26
- const patterns = [];
27
- for (const m of mentions) {
28
- const escaped = m.name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
29
- patterns.push(escaped);
30
- mentionMap.set(m.name.toLowerCase(), m.open_id);
31
- }
32
- mentionPattern = new RegExp(`@(${patterns.join('|')})\\b`, 'gi');
33
- }
34
- return text.split('\n').map(line => {
35
- if (!mentionPattern)
36
- return [{ tag: 'text', text: line }];
37
- const nodes = [];
38
- let lastIndex = 0;
39
- for (const match of line.matchAll(mentionPattern)) {
40
- const matchedName = match[1];
41
- const openId = mentionMap.get(matchedName.toLowerCase());
42
- if (!openId)
43
- continue;
44
- // Add text before the match
45
- if (match.index > lastIndex) {
46
- nodes.push({ tag: 'text', text: line.slice(lastIndex, match.index) });
47
- }
48
- nodes.push({ tag: 'at', user_id: openId });
49
- lastIndex = match.index + match[0].length;
50
- }
51
- // Add remaining text
52
- if (lastIndex < line.length) {
53
- nodes.push({ tag: 'text', text: line.slice(lastIndex) });
54
- }
55
- // If no matches were found in this line, return as plain text
56
- if (nodes.length === 0) {
57
- nodes.push({ tag: 'text', text: line });
58
- }
59
- return nodes;
60
- });
61
- }
62
- /** Try to extract plain text from post JSON that Claude sometimes generates */
63
- function extractTextFromPostJson(raw) {
64
- try {
65
- const parsed = JSON.parse(raw);
66
- const inner = parsed.zh_cn ?? parsed.en_us ?? parsed;
67
- if (!Array.isArray(inner.content))
68
- return null;
69
- // Flatten post blocks back to plain text
70
- const lines = [];
71
- for (const paragraph of inner.content) {
72
- if (!Array.isArray(paragraph))
73
- continue;
74
- const parts = [];
75
- for (const node of paragraph) {
76
- if (node.tag === 'text' && typeof node.text === 'string') {
77
- parts.push(node.text);
78
- }
79
- }
80
- lines.push(parts.join(''));
81
- }
82
- return lines.join('\n').trim();
83
- }
84
- catch {
85
- return null;
86
- }
87
- }
88
- export async function execute(args) {
89
- if (!args.session_id) {
90
- return { error: 'session_id is required but was not provided and could not be auto-detected' };
91
- }
92
- const session = sessionStore.getSession(args.session_id);
93
- if (!session) {
94
- return { error: `Session ${args.session_id} not found` };
95
- }
96
- if (session.status === 'closed') {
97
- return { error: `Session ${args.session_id} is closed` };
98
- }
99
- try {
100
- // Read the session owner's open_id from the persisted session data.
101
- // The MCP server runs in a separate process (spawned by the CLI) and
102
- // does NOT inherit env vars from the worker, so we can't rely on __OWNER_OPEN_ID.
103
- const mentionUser = session.ownerOpenId;
104
- const replyInThread = true; // Always reply in thread to create topics in all chat types
105
- const appId = session.larkAppId || config.lark.appId;
106
- // Validate that image/file paths exist before doing anything
107
- for (const p of [...(args.images ?? []), ...(args.files ?? [])]) {
108
- if (!existsSync(p)) {
109
- return { error: `File not found: ${p}` };
110
- }
111
- }
112
- // Upload images in parallel
113
- const imageKeys = [];
114
- if (args.images && args.images.length > 0) {
115
- const results = await Promise.all(args.images.map(p => uploadImage(appId, p)));
116
- imageKeys.push(...results);
117
- }
118
- // If Claude sent post JSON as content, extract the plain text from it
119
- let text = args.content;
120
- const extracted = extractTextFromPostJson(text);
121
- if (extracted) {
122
- text = extracted;
123
- }
124
- // Build post content: text paragraphs + inline images.
125
- // Pass mentions so @Name in text gets replaced with proper `at` tags inline.
126
- const postContent = text ? textToPostContent(text, args.mentions) : [];
127
- for (const key of imageKeys) {
128
- postContent.push([{ tag: 'img', image_key: key }]);
129
- }
130
- // If there are mentions that weren't found in the text (e.g. no @Name in content),
131
- // append them at the end as fallback
132
- if (args.mentions && args.mentions.length > 0) {
133
- const usedOpenIds = new Set();
134
- for (const para of postContent) {
135
- for (const node of para) {
136
- if (node.tag === 'at' && node.user_id)
137
- usedOpenIds.add(node.user_id);
138
- }
139
- }
140
- const unusedMentions = args.mentions.filter(m => !usedOpenIds.has(m.open_id));
141
- if (unusedMentions.length > 0) {
142
- if (postContent.length === 0)
143
- postContent.push([]);
144
- const lastLine = postContent[postContent.length - 1];
145
- for (const m of unusedMentions) {
146
- lastLine.push({ tag: 'at', user_id: m.open_id });
147
- }
148
- }
149
- }
150
- // Append @mention to session owner (human user)
151
- if (mentionUser) {
152
- if (postContent.length === 0)
153
- postContent.push([]);
154
- postContent[postContent.length - 1].push({ tag: 'at', user_id: mentionUser });
155
- }
156
- const content = JSON.stringify({
157
- zh_cn: { title: '', content: postContent },
158
- });
159
- const messageId = await replyMessage(appId, session.rootMessageId, content, 'post', replyInThread);
160
- // Send file attachments as separate messages (Lark post doesn't support inline files)
161
- const fileMessageIds = [];
162
- if (args.files && args.files.length > 0) {
163
- for (const filePath of args.files) {
164
- const fileKey = await uploadFile(appId, filePath);
165
- const fileContent = JSON.stringify({ file_key: fileKey });
166
- const fid = await replyMessage(appId, session.rootMessageId, fileContent, 'file', replyInThread);
167
- fileMessageIds.push(fid);
168
- }
169
- }
170
- // Write signal files for bot-to-bot mentions.
171
- // Lark WSClient does not deliver im.message.receive_v1 events for bot-sent messages,
172
- // so the daemon uses these signal files to route messages to target bots internally.
173
- //
174
- // Resolve targets from two sources:
175
- // 1. Explicit args.mentions (CLI passed open_ids directly)
176
- // 2. Auto-detect @BotName in text content (CLIs often forget the mentions param)
177
- const botInfoPath = join(config.session.dataDir, 'bots-info.json');
178
- let botEntries = [];
179
- try {
180
- if (existsSync(botInfoPath)) {
181
- botEntries = JSON.parse(readFileSync(botInfoPath, 'utf-8'));
182
- }
183
- }
184
- catch { /* ignore */ }
185
- // Build a comprehensive open_id → larkAppId lookup that includes both
186
- // self-reported IDs (from bots-info.json) and cross-ref IDs (per-app scoped).
187
- // Lark open_ids are per-app: the open_id that list_bots returns for Bot B
188
- // (as seen by Bot A) differs from Bot B's self-reported open_id.
189
- const openIdToAppId = new Map();
190
- for (const entry of botEntries) {
191
- if (entry.botOpenId)
192
- openIdToAppId.set(entry.botOpenId, entry.larkAppId);
193
- }
194
- // Read cross-ref files: bot-openids-{appId}.json maps botName → open_id in that app's context
195
- try {
196
- const dataDir = config.session.dataDir;
197
- for (const file of readdirSync(dataDir)) {
198
- if (!file.startsWith('bot-openids-') || !file.endsWith('.json'))
199
- continue;
200
- try {
201
- const crossRef = JSON.parse(readFileSync(join(dataDir, file), 'utf-8'));
202
- for (const [botName, crossOpenId] of Object.entries(crossRef)) {
203
- // Resolve botName → larkAppId via bots-info
204
- const entry = botEntries.find(e => e.botName?.toLowerCase() === botName.toLowerCase());
205
- if (entry)
206
- openIdToAppId.set(crossOpenId, entry.larkAppId);
207
- }
208
- }
209
- catch { /* ignore corrupt file */ }
210
- }
211
- }
212
- catch { /* ignore */ }
213
- // Collect target larkAppIds: explicit mentions + auto-detected from text
214
- const targetAppIds = new Set();
215
- // 1. Explicit mentions (excluding self)
216
- if (args.mentions) {
217
- for (const m of args.mentions) {
218
- const targetApp = openIdToAppId.get(m.open_id);
219
- if (targetApp && targetApp !== appId)
220
- targetAppIds.add(targetApp);
221
- }
222
- }
223
- // 2. Auto-detect @BotName / @cliId in text (case-insensitive)
224
- if (text && botEntries.length > 0) {
225
- for (const entry of botEntries) {
226
- if (!entry.botOpenId || entry.larkAppId === appId)
227
- continue; // skip self
228
- const names = [entry.botName, entry.cliId].filter(Boolean);
229
- for (const name of names) {
230
- // Match @Name with word boundary (handles "@Aiden", "@Claude Code", "@claude-code")
231
- const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
232
- if (new RegExp(`@${escaped}\\b`, 'i').test(text)) {
233
- targetAppIds.add(entry.larkAppId);
234
- break;
235
- }
236
- }
237
- }
238
- }
239
- if (targetAppIds.size > 0) {
240
- const signalDir = join(config.session.dataDir, 'bot-mentions');
241
- if (!existsSync(signalDir))
242
- mkdirSync(signalDir, { recursive: true });
243
- for (const targetApp of targetAppIds) {
244
- // Use the target bot's self-reported open_id for the signal
245
- // (daemons match signals by their own botOpenId)
246
- const targetEntry = botEntries.find(e => e.larkAppId === targetApp);
247
- const targetOpenId = targetEntry?.botOpenId ?? targetApp;
248
- const signal = {
249
- rootMessageId: session.rootMessageId,
250
- chatId: session.chatId,
251
- chatType: session.chatType,
252
- senderAppId: appId,
253
- targetBotOpenId: targetOpenId,
254
- content: text,
255
- messageId,
256
- timestamp: Date.now(),
257
- };
258
- const filename = `${Date.now()}-${targetOpenId.slice(-8)}.json`;
259
- writeFileSync(join(signalDir, filename), JSON.stringify(signal));
260
- logger.info(`Wrote bot-mention signal for ${targetApp} in thread ${session.rootMessageId}`);
261
- }
262
- }
263
- return {
264
- success: true,
265
- messageId,
266
- ...(fileMessageIds.length > 0 && { fileMessageIds }),
267
- sessionId: args.session_id,
268
- };
269
- }
270
- catch (err) {
271
- logger.error(`Failed to send to thread: ${err.message}`);
272
- return { error: `Failed to send message: ${err.message}` };
273
- }
274
- }
275
- //# sourceMappingURL=send-to-thread.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"send-to-thread.js","sourceRoot":"","sources":["../../src/tools/send-to-thread.ts"],"names":[],"mappings":"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"}