botmux 2.37.0-canary.0 → 2.37.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 (215) hide show
  1. package/README.en.md +2 -2
  2. package/README.md +2 -2
  3. package/dist/adapters/cli/cursor.d.ts.map +1 -1
  4. package/dist/adapters/cli/cursor.js +53 -11
  5. package/dist/adapters/cli/cursor.js.map +1 -1
  6. package/dist/adapters/cli/mtr.d.ts +5 -0
  7. package/dist/adapters/cli/mtr.d.ts.map +1 -0
  8. package/dist/adapters/cli/mtr.js +62 -0
  9. package/dist/adapters/cli/mtr.js.map +1 -0
  10. package/dist/adapters/cli/registry.d.ts +2 -1
  11. package/dist/adapters/cli/registry.d.ts.map +1 -1
  12. package/dist/adapters/cli/registry.js +3 -1
  13. package/dist/adapters/cli/registry.js.map +1 -1
  14. package/dist/adapters/cli/shared-hints.d.ts +1 -1
  15. package/dist/adapters/cli/shared-hints.js +1 -1
  16. package/dist/adapters/cli/types.d.ts +1 -1
  17. package/dist/adapters/cli/types.d.ts.map +1 -1
  18. package/dist/cli/bots-list-output.d.ts +0 -8
  19. package/dist/cli/bots-list-output.d.ts.map +1 -1
  20. package/dist/cli/bots-list-output.js +0 -9
  21. package/dist/cli/bots-list-output.js.map +1 -1
  22. package/dist/cli.js +30 -29
  23. package/dist/cli.js.map +1 -1
  24. package/dist/core/command-handler.d.ts.map +1 -1
  25. package/dist/core/command-handler.js +8 -88
  26. package/dist/core/command-handler.js.map +1 -1
  27. package/dist/core/dashboard-ipc-server.d.ts +0 -2
  28. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  29. package/dist/core/dashboard-ipc-server.js +0 -51
  30. package/dist/core/dashboard-ipc-server.js.map +1 -1
  31. package/dist/core/role-resolver.d.ts +1 -17
  32. package/dist/core/role-resolver.d.ts.map +1 -1
  33. package/dist/core/role-resolver.js +10 -64
  34. package/dist/core/role-resolver.js.map +1 -1
  35. package/dist/core/session-discovery.d.ts.map +1 -1
  36. package/dist/core/session-discovery.js +2 -1
  37. package/dist/core/session-discovery.js.map +1 -1
  38. package/dist/core/session-manager.d.ts.map +1 -1
  39. package/dist/core/session-manager.js +9 -14
  40. package/dist/core/session-manager.js.map +1 -1
  41. package/dist/core/worker-pool.d.ts.map +1 -1
  42. package/dist/core/worker-pool.js +41 -6
  43. package/dist/core/worker-pool.js.map +1 -1
  44. package/dist/daemon.d.ts.map +1 -1
  45. package/dist/daemon.js +24 -29
  46. package/dist/daemon.js.map +1 -1
  47. package/dist/dashboard/web/app.js +0 -3
  48. package/dist/dashboard/web/app.js.map +1 -1
  49. package/dist/dashboard/web/sessions.d.ts.map +1 -1
  50. package/dist/dashboard/web/sessions.js +1 -0
  51. package/dist/dashboard/web/sessions.js.map +1 -1
  52. package/dist/dashboard/web/workflows.js +2 -2
  53. package/dist/dashboard/web/workflows.js.map +1 -1
  54. package/dist/dashboard-web/app.js +223 -271
  55. package/dist/dashboard-web/index.html +0 -1
  56. package/dist/dashboard-web/style.css +2 -0
  57. package/dist/dashboard.js +1 -148
  58. package/dist/dashboard.js.map +1 -1
  59. package/dist/i18n/en.d.ts.map +1 -1
  60. package/dist/i18n/en.js +6 -23
  61. package/dist/i18n/en.js.map +1 -1
  62. package/dist/i18n/zh.d.ts.map +1 -1
  63. package/dist/i18n/zh.js +6 -23
  64. package/dist/i18n/zh.js.map +1 -1
  65. package/dist/im/lark/card-builder.d.ts.map +1 -1
  66. package/dist/im/lark/card-builder.js +1 -0
  67. package/dist/im/lark/card-builder.js.map +1 -1
  68. package/dist/im/lark/client.d.ts +18 -21
  69. package/dist/im/lark/client.d.ts.map +1 -1
  70. package/dist/im/lark/client.js +76 -131
  71. package/dist/im/lark/client.js.map +1 -1
  72. package/dist/im/lark/identity-cache.d.ts.map +1 -1
  73. package/dist/im/lark/identity-cache.js +3 -3
  74. package/dist/im/lark/identity-cache.js.map +1 -1
  75. package/dist/services/groups-store.d.ts.map +1 -1
  76. package/dist/services/groups-store.js +8 -12
  77. package/dist/services/groups-store.js.map +1 -1
  78. package/dist/setup/bot-config-editor.d.ts +1 -1
  79. package/dist/setup/bot-config-editor.d.ts.map +1 -1
  80. package/dist/setup/bot-config-editor.js +3 -2
  81. package/dist/setup/bot-config-editor.js.map +1 -1
  82. package/dist/setup/verify-permissions.d.ts.map +1 -1
  83. package/dist/setup/verify-permissions.js +6 -1
  84. package/dist/setup/verify-permissions.js.map +1 -1
  85. package/dist/skills/definitions.d.ts.map +1 -1
  86. package/dist/skills/definitions.js +10 -64
  87. package/dist/skills/definitions.js.map +1 -1
  88. package/dist/utils/bot-routing.d.ts +31 -0
  89. package/dist/utils/bot-routing.d.ts.map +1 -1
  90. package/dist/utils/bot-routing.js +54 -0
  91. package/dist/utils/bot-routing.js.map +1 -1
  92. package/dist/worker.js +1 -1
  93. package/dist/worker.js.map +1 -1
  94. package/dist/workflows/attempt-resume.d.ts.map +1 -1
  95. package/dist/workflows/attempt-resume.js +1 -1
  96. package/dist/workflows/attempt-resume.js.map +1 -1
  97. package/dist/workflows/events/payloads.d.ts +2 -2
  98. package/dist/workflows/events/schema.d.ts +8 -8
  99. package/package.json +1 -1
  100. package/dist/core/trigger-session.d.ts +0 -9
  101. package/dist/core/trigger-session.d.ts.map +0 -1
  102. package/dist/core/trigger-session.js +0 -158
  103. package/dist/core/trigger-session.js.map +0 -1
  104. package/dist/dashboard/connector-api.d.ts +0 -3
  105. package/dist/dashboard/connector-api.d.ts.map +0 -1
  106. package/dist/dashboard/connector-api.js +0 -362
  107. package/dist/dashboard/connector-api.js.map +0 -1
  108. package/dist/dashboard/federation-api.d.ts +0 -16
  109. package/dist/dashboard/federation-api.d.ts.map +0 -1
  110. package/dist/dashboard/federation-api.js +0 -162
  111. package/dist/dashboard/federation-api.js.map +0 -1
  112. package/dist/dashboard/federation-spoke-api.d.ts +0 -39
  113. package/dist/dashboard/federation-spoke-api.d.ts.map +0 -1
  114. package/dist/dashboard/federation-spoke-api.js +0 -276
  115. package/dist/dashboard/federation-spoke-api.js.map +0 -1
  116. package/dist/dashboard/pairing-api.d.ts +0 -19
  117. package/dist/dashboard/pairing-api.d.ts.map +0 -1
  118. package/dist/dashboard/pairing-api.js +0 -83
  119. package/dist/dashboard/pairing-api.js.map +0 -1
  120. package/dist/dashboard/team-group.d.ts +0 -18
  121. package/dist/dashboard/team-group.d.ts.map +0 -1
  122. package/dist/dashboard/team-group.js +0 -7
  123. package/dist/dashboard/team-group.js.map +0 -1
  124. package/dist/dashboard/team-page.d.ts +0 -8
  125. package/dist/dashboard/team-page.d.ts.map +0 -1
  126. package/dist/dashboard/team-page.js +0 -480
  127. package/dist/dashboard/team-page.js.map +0 -1
  128. package/dist/dashboard/team-routes.d.ts +0 -30
  129. package/dist/dashboard/team-routes.d.ts.map +0 -1
  130. package/dist/dashboard/team-routes.js +0 -458
  131. package/dist/dashboard/team-routes.js.map +0 -1
  132. package/dist/dashboard/trigger-api.d.ts +0 -13
  133. package/dist/dashboard/trigger-api.d.ts.map +0 -1
  134. package/dist/dashboard/trigger-api.js +0 -77
  135. package/dist/dashboard/trigger-api.js.map +0 -1
  136. package/dist/dashboard/web/team-federation.d.ts +0 -2
  137. package/dist/dashboard/web/team-federation.d.ts.map +0 -1
  138. package/dist/dashboard/web/team-federation.js +0 -193
  139. package/dist/dashboard/web/team-federation.js.map +0 -1
  140. package/dist/dashboard/webhook-routes.d.ts +0 -19
  141. package/dist/dashboard/webhook-routes.d.ts.map +0 -1
  142. package/dist/dashboard/webhook-routes.js +0 -321
  143. package/dist/dashboard/webhook-routes.js.map +0 -1
  144. package/dist/services/bot-owner-store.d.ts +0 -28
  145. package/dist/services/bot-owner-store.d.ts.map +0 -1
  146. package/dist/services/bot-owner-store.js +0 -82
  147. package/dist/services/bot-owner-store.js.map +0 -1
  148. package/dist/services/bot-profile-store.d.ts +0 -16
  149. package/dist/services/bot-profile-store.d.ts.map +0 -1
  150. package/dist/services/bot-profile-store.js +0 -98
  151. package/dist/services/bot-profile-store.js.map +0 -1
  152. package/dist/services/connector-store.d.ts +0 -63
  153. package/dist/services/connector-store.d.ts.map +0 -1
  154. package/dist/services/connector-store.js +0 -79
  155. package/dist/services/connector-store.js.map +0 -1
  156. package/dist/services/deployment-identity.d.ts +0 -9
  157. package/dist/services/deployment-identity.d.ts.map +0 -1
  158. package/dist/services/deployment-identity.js +0 -47
  159. package/dist/services/deployment-identity.js.map +0 -1
  160. package/dist/services/federation-membership-store.d.ts +0 -17
  161. package/dist/services/federation-membership-store.d.ts.map +0 -1
  162. package/dist/services/federation-membership-store.js +0 -59
  163. package/dist/services/federation-membership-store.js.map +0 -1
  164. package/dist/services/federation-roster.d.ts +0 -39
  165. package/dist/services/federation-roster.d.ts.map +0 -1
  166. package/dist/services/federation-roster.js +0 -49
  167. package/dist/services/federation-roster.js.map +0 -1
  168. package/dist/services/federation-store.d.ts +0 -53
  169. package/dist/services/federation-store.d.ts.map +0 -1
  170. package/dist/services/federation-store.js +0 -125
  171. package/dist/services/federation-store.js.map +0 -1
  172. package/dist/services/invite-store.d.ts +0 -28
  173. package/dist/services/invite-store.d.ts.map +0 -1
  174. package/dist/services/invite-store.js +0 -85
  175. package/dist/services/invite-store.js.map +0 -1
  176. package/dist/services/pairing-store.d.ts +0 -47
  177. package/dist/services/pairing-store.d.ts.map +0 -1
  178. package/dist/services/pairing-store.js +0 -132
  179. package/dist/services/pairing-store.js.map +0 -1
  180. package/dist/services/team-roster.d.ts +0 -28
  181. package/dist/services/team-roster.d.ts.map +0 -1
  182. package/dist/services/team-roster.js +0 -58
  183. package/dist/services/team-roster.js.map +0 -1
  184. package/dist/services/team-store.d.ts +0 -54
  185. package/dist/services/team-store.d.ts.map +0 -1
  186. package/dist/services/team-store.js +0 -156
  187. package/dist/services/team-store.js.map +0 -1
  188. package/dist/services/trigger-log-store.d.ts +0 -46
  189. package/dist/services/trigger-log-store.d.ts.map +0 -1
  190. package/dist/services/trigger-log-store.js +0 -132
  191. package/dist/services/trigger-log-store.js.map +0 -1
  192. package/dist/services/trigger-types.d.ts +0 -57
  193. package/dist/services/trigger-types.d.ts.map +0 -1
  194. package/dist/services/trigger-types.js +0 -28
  195. package/dist/services/trigger-types.js.map +0 -1
  196. package/dist/services/web-session-store.d.ts +0 -28
  197. package/dist/services/web-session-store.d.ts.map +0 -1
  198. package/dist/services/web-session-store.js +0 -84
  199. package/dist/services/web-session-store.js.map +0 -1
  200. package/dist/services/webhook-key.d.ts +0 -16
  201. package/dist/services/webhook-key.d.ts.map +0 -1
  202. package/dist/services/webhook-key.js +0 -123
  203. package/dist/services/webhook-key.js.map +0 -1
  204. package/dist/services/webhook-lifecycle-extractors.d.ts +0 -15
  205. package/dist/services/webhook-lifecycle-extractors.d.ts.map +0 -1
  206. package/dist/services/webhook-lifecycle-extractors.js +0 -59
  207. package/dist/services/webhook-lifecycle-extractors.js.map +0 -1
  208. package/dist/services/webhook-lifecycle-store.d.ts +0 -45
  209. package/dist/services/webhook-lifecycle-store.d.ts.map +0 -1
  210. package/dist/services/webhook-lifecycle-store.js +0 -159
  211. package/dist/services/webhook-lifecycle-store.js.map +0 -1
  212. package/dist/workflows/trigger-from-envelope.d.ts +0 -13
  213. package/dist/workflows/trigger-from-envelope.d.ts.map +0 -1
  214. package/dist/workflows/trigger-from-envelope.js +0 -67
  215. package/dist/workflows/trigger-from-envelope.js.map +0 -1
package/README.en.md CHANGED
@@ -62,7 +62,7 @@ Compared to OpenClaw-style approaches built on Agent SDKs:
62
62
  ## Prerequisites
63
63
 
64
64
  - **Node.js** >= 20
65
- - **AI coding CLI** installed and authenticated (`claude`, `codex`, `cursor-agent`, `gemini`, `opencode`, or `agy` (Antigravity) in PATH)
65
+ - **AI coding CLI** installed and authenticated (`claude`, `codex`, `cursor-agent`, `gemini`, `opencode`, `mtr`, or `agy` (Antigravity) in PATH)
66
66
  - **tmux** >= 3.x (optional — auto-enabled when installed for persistent CLI sessions)
67
67
  - **CJK fonts** (only needed for screenshot rendering of Chinese text / emoji):
68
68
  - macOS: ships with PingFang / Hiragino, no action needed
@@ -443,7 +443,7 @@ When `~/.botmux/bots.json` already exists, `botmux setup` can add a bot, reconfi
443
443
  | `larkAppId` | Yes | Lark app ID |
444
444
  | `larkAppSecret` | Yes | Lark app secret |
445
445
  | `name` | No | Process name suffix shown by `botmux status`; e.g. `claude-main` appears as `botmux-claude-main`, defaults to `botmux-<index>` |
446
- | `cliId` | No | CLI adapter, defaults to `claude-code` (options: `aiden`, `coco`, `codex`, `cursor`, `gemini`, `opencode`, `antigravity`) |
446
+ | `cliId` | No | CLI adapter, defaults to `claude-code` (options: `aiden`, `coco`, `codex`, `cursor`, `gemini`, `opencode`, `antigravity`, `mtr`) |
447
447
  | `cliPathOverride` | No | Absolute path to the CLI entry, for wrappers / routers; typical use: `ccr`, `claude-w`, `aiden-x-claude`, etc. |
448
448
  | `backendType` | No | Session backend: `pty` or `tmux` (auto-detected by default) |
449
449
  | `workingDir` | No | Default working directory, supports comma-separated. The new-topic repo-select card scans for git repos **from this directory downward** (recursive, up to 3 levels), no longer climbing to the parent: point it at a repos root (e.g. `~/projects`) to list every repo beneath it, or at a single repo to list just that repo (and its linked worktrees) |
package/README.md CHANGED
@@ -169,7 +169,7 @@ CLI 进入 botmux 会话时自动获得 `~/.botmux/bin` 在 PATH 中,以及一
169
169
  ## 前置要求
170
170
 
171
171
  - **Node.js** >= 20
172
- - **AI 编程 CLI** 已安装并完成认证(`claude`、`codex`、`cursor-agent`、`gemini`、`opencode` 或 `agy`(Antigravity)在 PATH 中)
172
+ - **AI 编程 CLI** 已安装并完成认证(`claude`、`codex`、`cursor-agent`、`gemini`、`opencode`、`mtr` 或 `agy`(Antigravity)在 PATH 中)
173
173
  - **tmux** >= 3.x(可选,安装后自动启用会话常驻)
174
174
  - **CJK 字体**(用于截图渲染中文/emoji):
175
175
  - macOS 自带 PingFang/Hiragino,无需配置
@@ -547,7 +547,7 @@ botmux setup
547
547
  | `larkAppId` | 是 | 飞书应用 App ID |
548
548
  | `larkAppSecret` | 是 | 飞书应用 App Secret |
549
549
  | `name` | 否 | `botmux status` 中的进程名后缀;例如 `claude-main` 会显示为 `botmux-claude-main`,留空默认 `botmux-<序号>` |
550
- | `cliId` | 否 | CLI 适配器,默认 `claude-code`(可选:`aiden`、`coco`、`codex`、`cursor`、`gemini`、`opencode`、`antigravity`) |
550
+ | `cliId` | 否 | CLI 适配器,默认 `claude-code`(可选:`aiden`、`coco`、`codex`、`cursor`、`gemini`、`opencode`、`antigravity`、`mtr`) |
551
551
  | `cliPathOverride` | 否 | CLI 入口的绝对路径,用于套 wrapper / router;典型场景:ccr、claude-w、aiden-x-claude 等自定义入口 |
552
552
  | `backendType` | 否 | 会话后端:`pty` 或 `tmux`(默认自动检测) |
553
553
  | `workingDir` | 否 | 默认工作目录,支持逗号分隔多个目录。新话题的 repo 选择卡片会**从该目录自身向下**递归查找 git 仓库(最多 3 层),不再向上扫父目录:指向仓库集合根目录(如 `~/projects`)即列出其下所有仓库,指向单个仓库则只列该仓库(及其 linked worktrees) |
@@ -1 +1 @@
1
- {"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/cursor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,YAAY,CAAC;AAMxD,wBAAgB,mBAAmB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CAgDrE;AAED,eAAO,MAAM,MAAM,4BAAsB,CAAC"}
1
+ {"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/cursor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,YAAY,CAAC;AAYxD,wBAAgB,mBAAmB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CAuFrE;AAED,eAAO,MAAM,MAAM,4BAAsB,CAAC"}
@@ -3,6 +3,11 @@ import { BOTMUX_SHELL_HINTS } from './shared-hints.js';
3
3
  function delay(ms) {
4
4
  return new Promise(resolve => setTimeout(resolve, ms));
5
5
  }
6
+ /** PTYs that have already received a writeInput. The first write lands while
7
+ * cursor-agent's TUI is still doing its startup render, so it needs a longer
8
+ * settle + throttle than later writes. Tracked by identity so the warmup state
9
+ * is shared across adapter instances. Mirrors claude-code's first-write guard. */
10
+ const cursorFirstWriteSeen = new WeakSet();
6
11
  export function createCursorAdapter(pathOverride) {
7
12
  const bin = resolveCommand(pathOverride ?? 'cursor-agent');
8
13
  return {
@@ -31,20 +36,57 @@ export function createCursorAdapter(pathOverride) {
31
36
  return `cursor-agent --resume ${cliSessionId}`;
32
37
  },
33
38
  async writeInput(pty, content) {
34
- // No on-disk submit verification yet cursor stores transcripts as
35
- // JSONL but the path isn't documented. Treat like aiden: paste the
36
- // text, brief settle, send Enter. Worker still gets quiescence-based
37
- // idle and the bridge fallback timer if the model never replies.
38
- if (pty.sendText && pty.sendSpecialKeys) {
39
- pty.sendText(content);
39
+ // Emit line-by-line instead of writing the whole message at once.
40
+ // cursor-agent's paste detector folds a multi-line chunk that arrives in
41
+ // one burst into a `[Pasted text +N lines]` placeholder the model can't
42
+ // read; typing each line with a throttle between keeps it under that
43
+ // threshold so the text lands verbatim. Covers both backends — tmux
44
+ // (send-keys) and raw PTY (write only). Never use bracketed-paste markers
45
+ // (\x1b[200~ … \x1b[201~): they trigger the fold.
46
+ //
47
+ // Soft-newline differs per backend because the detector counts LF (0x0a)
48
+ // bytes arriving densely:
49
+ // - tmux: Ctrl+J, cursor's native soft-newline — renders cleanly and
50
+ // send-keys spaces the bytes out enough to never fold.
51
+ // - raw PTY: a fast write('\n') folds, so send `\` + CR; cursor eats the
52
+ // backslash-before-CR as a soft-newline (not part of the submitted
53
+ // text) and no LF byte hits the stream, making it fold-immune. Costs a
54
+ // cosmetic trailing `\` in the local TUI render only.
55
+ // Submit is always a bare Enter (\r). No on-disk submit verification —
56
+ // cursor's transcript path isn't documented, so the worker relies on
57
+ // idle detection + the bridge fallback timer.
58
+ const useKeys = !!(pty.sendText && pty.sendSpecialKeys);
59
+ const emitText = (s) => (useKeys ? pty.sendText(s) : pty.write(s));
60
+ const emitSoftNewline = () => {
61
+ if (useKeys) {
62
+ pty.sendSpecialKeys('C-j');
63
+ }
64
+ else {
65
+ pty.write('\\');
66
+ pty.write('\r');
67
+ }
68
+ };
69
+ const emitEnter = () => (useKeys ? pty.sendSpecialKeys('Enter') : pty.write('\r'));
70
+ const isFirstWrite = !cursorFirstWriteSeen.has(pty);
71
+ if (isFirstWrite) {
72
+ cursorFirstWriteSeen.add(pty);
40
73
  await delay(200);
41
- pty.sendSpecialKeys('Enter');
42
74
  }
43
- else {
44
- pty.write(content);
45
- await delay(1000);
46
- pty.write('\r');
75
+ const throttleMs = isFirstWrite ? 80 : 30;
76
+ const tick = () => delay(throttleMs);
77
+ const lines = content.split('\n');
78
+ for (let i = 0; i < lines.length; i++) {
79
+ if (lines[i].length > 0) {
80
+ emitText(lines[i]);
81
+ await tick();
82
+ }
83
+ if (i < lines.length - 1) {
84
+ emitSoftNewline();
85
+ await tick();
86
+ }
47
87
  }
88
+ await delay(200);
89
+ emitEnter();
48
90
  },
49
91
  completionPattern: undefined,
50
92
  skillsDir: '~/.cursor/skills',
@@ -1 +1 @@
1
- {"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../../src/adapters/cli/cursor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGvD,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,YAAqB;IACvD,MAAM,GAAG,GAAG,cAAc,CAAC,YAAY,IAAI,cAAc,CAAC,CAAC;IAC3D,OAAO;QACL,EAAE,EAAE,QAAQ;QACZ,WAAW,EAAE,GAAG;QAEhB,SAAS,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE;YACnC,wEAAwE;YACxE,yEAAyE;YACzE,0EAA0E;YAC1E,kCAAkC;YAClC,MAAM,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;YACzB,IAAI,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC;YACzB,IAAI,eAAe;gBAAE,OAAO,CAAC,GAAG,IAAI,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;YACnE,qEAAqE;YACrE,wEAAwE;YACxE,OAAO,CAAC,GAAG,IAAI,EAAE,YAAY,CAAC,CAAC;QACjC,CAAC;QAED,kBAAkB,CAAC,EAAE,YAAY,EAAE;YACjC,wEAAwE;YACxE,4EAA4E;YAC5E,sCAAsC;YACtC,IAAI,CAAC,YAAY;gBAAE,OAAO,IAAI,CAAC;YAC/B,OAAO,yBAAyB,YAAY,EAAE,CAAC;QACjD,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,GAAc,EAAE,OAAe;YAC9C,oEAAoE;YACpE,mEAAmE;YACnE,qEAAqE;YACrE,iEAAiE;YACjE,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC;gBACxC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBACtB,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;gBACjB,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACnB,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;gBAClB,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,iBAAiB,EAAE,SAAS;QAC5B,SAAS,EAAE,kBAAkB;QAC7B,WAAW,EAAE,kBAAkB;QAC/B,SAAS,EAAE,IAAI;KAChB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,mBAAmB,CAAC"}
1
+ {"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../../src/adapters/cli/cursor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { CliAdapter } from './types.js';
2
+ export declare function mtrSessionIdForBotmuxSession(sessionId: string): string;
3
+ export declare function createMtrAdapter(pathOverride?: string): CliAdapter;
4
+ export declare const create: typeof createMtrAdapter;
5
+ //# sourceMappingURL=mtr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mtr.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/mtr.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,YAAY,CAAC;AAYxD,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAQtE;AAMD,wBAAgB,gBAAgB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CA0ClE;AAED,eAAO,MAAM,MAAM,yBAAmB,CAAC"}
@@ -0,0 +1,62 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { resolveCommand } from './registry.js';
3
+ import { BOTMUX_SHELL_HINTS } from './shared-hints.js';
4
+ const BASE62 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
5
+ function delay(ms) {
6
+ return new Promise(resolve => setTimeout(resolve, ms));
7
+ }
8
+ function isMtrSessionId(value) {
9
+ return typeof value === 'string' && /^ses_[0-9A-Za-z]+$/.test(value);
10
+ }
11
+ export function mtrSessionIdForBotmuxSession(sessionId) {
12
+ const digest = createHash('sha256').update(sessionId).digest();
13
+ const timeHex = digest.subarray(0, 6).toString('hex');
14
+ let suffix = '';
15
+ for (let i = 6; i < 20; i++) {
16
+ suffix += BASE62[digest[i] % BASE62.length];
17
+ }
18
+ return `ses_${timeHex}${suffix}`;
19
+ }
20
+ function nativeSessionId(sessionId, cliSessionId) {
21
+ return isMtrSessionId(cliSessionId) ? cliSessionId : mtrSessionIdForBotmuxSession(sessionId);
22
+ }
23
+ export function createMtrAdapter(pathOverride) {
24
+ const bin = resolveCommand(pathOverride ?? 'mtr');
25
+ return {
26
+ id: 'mtr',
27
+ resolvedBin: bin,
28
+ buildArgs({ sessionId, resume, resumeSessionId, initialPrompt }) {
29
+ const mtrSessionId = nativeSessionId(sessionId, resumeSessionId);
30
+ const args = resume
31
+ ? ['--session', mtrSessionId]
32
+ : ['--set-session', mtrSessionId];
33
+ if (initialPrompt) {
34
+ args.push('--prompt', initialPrompt);
35
+ }
36
+ return args;
37
+ },
38
+ buildResumeCommand({ sessionId, cliSessionId }) {
39
+ return `mtr --session ${nativeSessionId(sessionId, cliSessionId)}`;
40
+ },
41
+ passesInitialPromptViaArgs: true,
42
+ async writeInput(pty, content) {
43
+ if (pty.sendText && pty.sendSpecialKeys) {
44
+ pty.sendText(content);
45
+ await delay(200);
46
+ pty.sendSpecialKeys('Enter');
47
+ }
48
+ else {
49
+ pty.write(content);
50
+ await delay(1000);
51
+ pty.write('\r');
52
+ }
53
+ },
54
+ completionPattern: undefined,
55
+ readyPattern: undefined,
56
+ systemHints: BOTMUX_SHELL_HINTS,
57
+ altScreen: true,
58
+ skillsDir: '~/.config/opencode/skills',
59
+ };
60
+ }
61
+ export const create = createMtrAdapter;
62
+ //# sourceMappingURL=mtr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mtr.js","sourceRoot":"","sources":["../../../src/adapters/cli/mtr.ts"],"names":[],"mappings":"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"}
@@ -7,13 +7,14 @@ import { createCursorAdapter } from './cursor.js';
7
7
  import { createGeminiAdapter } from './gemini.js';
8
8
  import { createOpenCodeAdapter } from './opencode.js';
9
9
  import { createAntigravityAdapter } from './antigravity.js';
10
+ import { createMtrAdapter } from './mtr.js';
10
11
  /** Resolve a command name to its absolute path via shell `which`.
11
12
  * Tries login shell first (-lc), then interactive shell (-ic) for tools
12
13
  * whose installers add PATH entries to .bashrc/.zshrc only. */
13
14
  export declare function resolveCommand(cmd: string): string;
14
15
  /** Async adapter factory (uses dynamic import for lazy loading in daemon process). */
15
16
  export declare function createCliAdapter(id: CliId, pathOverride?: string): Promise<CliAdapter>;
16
- export { createClaudeCodeAdapter, createAidenAdapter, createCocoAdapter, createCodexAdapter, createCursorAdapter, createGeminiAdapter, createOpenCodeAdapter, createAntigravityAdapter };
17
+ export { createClaudeCodeAdapter, createAidenAdapter, createCocoAdapter, createCodexAdapter, createCursorAdapter, createGeminiAdapter, createOpenCodeAdapter, createAntigravityAdapter, createMtrAdapter };
17
18
  /** Synchronous version for use in worker process. */
18
19
  export declare function createCliAdapterSync(id: CliId, pathOverride?: string): CliAdapter;
19
20
  //# sourceMappingURL=registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/registry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAE5D;;gEAEgE;AAChE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAkBlD;AAID,sFAAsF;AACtF,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAO5F;AAED,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,CAAC;AAEzL,qDAAqD;AACrD,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CAYjF"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/registry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C;;gEAEgE;AAChE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAkBlD;AAID,sFAAsF;AACtF,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAO5F;AAED,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,CAAC;AAE3M,qDAAqD;AACrD,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CAajF"}
@@ -8,6 +8,7 @@ import { createCursorAdapter } from './cursor.js';
8
8
  import { createGeminiAdapter } from './gemini.js';
9
9
  import { createOpenCodeAdapter } from './opencode.js';
10
10
  import { createAntigravityAdapter } from './antigravity.js';
11
+ import { createMtrAdapter } from './mtr.js';
11
12
  /** Resolve a command name to its absolute path via shell `which`.
12
13
  * Tries login shell first (-lc), then interactive shell (-ic) for tools
13
14
  * whose installers add PATH entries to .bashrc/.zshrc only. */
@@ -44,7 +45,7 @@ export async function createCliAdapter(id, pathOverride) {
44
45
  adapterCache.set(key, adapter);
45
46
  return adapter;
46
47
  }
47
- export { createClaudeCodeAdapter, createAidenAdapter, createCocoAdapter, createCodexAdapter, createCursorAdapter, createGeminiAdapter, createOpenCodeAdapter, createAntigravityAdapter };
48
+ export { createClaudeCodeAdapter, createAidenAdapter, createCocoAdapter, createCodexAdapter, createCursorAdapter, createGeminiAdapter, createOpenCodeAdapter, createAntigravityAdapter, createMtrAdapter };
48
49
  /** Synchronous version for use in worker process. */
49
50
  export function createCliAdapterSync(id, pathOverride) {
50
51
  switch (id.toLowerCase()) {
@@ -56,6 +57,7 @@ export function createCliAdapterSync(id, pathOverride) {
56
57
  case 'gemini': return createGeminiAdapter(pathOverride);
57
58
  case 'opencode': return createOpenCodeAdapter(pathOverride);
58
59
  case 'antigravity': return createAntigravityAdapter(pathOverride);
60
+ case 'mtr': return createMtrAdapter(pathOverride);
59
61
  default: throw new Error(`Unknown CLI adapter: ${id}`);
60
62
  }
61
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/adapters/cli/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/adapters/cli/registry.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Claude Code has its own `--append-system-prompt` text baked into
5
5
  * `claude-code.ts`; this constant is only consumed by CLIs that don't expose
6
- * a system-prompt flag (coco / codex / gemini / opencode / aiden).
6
+ * a system-prompt flag (coco / codex / gemini / opencode / aiden / mtr).
7
7
  *
8
8
  * Each array element becomes one line inside the `<botmux_routing>` XML block
9
9
  * rendered by `buildNewTopicPrompt` in `session-manager.ts`.
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Claude Code has its own `--append-system-prompt` text baked into
5
5
  * `claude-code.ts`; this constant is only consumed by CLIs that don't expose
6
- * a system-prompt flag (coco / codex / gemini / opencode / aiden).
6
+ * a system-prompt flag (coco / codex / gemini / opencode / aiden / mtr).
7
7
  *
8
8
  * Each array element becomes one line inside the `<botmux_routing>` XML block
9
9
  * rendered by `buildNewTopicPrompt` in `session-manager.ts`.
@@ -116,5 +116,5 @@ export interface CliAdapter {
116
116
  /** Whether CLI uses alternate screen buffer */
117
117
  readonly altScreen: boolean;
118
118
  }
119
- export type CliId = 'claude-code' | 'aiden' | 'coco' | 'codex' | 'cursor' | 'gemini' | 'opencode' | 'antigravity';
119
+ export type CliId = 'claude-code' | 'aiden' | 'coco' | 'codex' | 'cursor' | 'gemini' | 'opencode' | 'antigravity' | 'mtr';
120
120
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,4FAA4F;IAC5F,eAAe,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC1C,8FAA8F;IAC9F,SAAS,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;;2FAEuF;IACvF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;yEAEqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;+DAC2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,+CAA+C;IAC/C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B;;;;;yCAKqC;IACrC,SAAS,CAAC,IAAI,EAAE;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,OAAO,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,sFAAsF;QACtF,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,+EAA+E;QAC/E,MAAM,CAAC,EAAE,OAAO,qBAAqB,EAAE,MAAM,CAAC;KAC/C,GAAG,MAAM,EAAE,CAAC;IAEb;+DAC2D;IAC3D,QAAQ,CAAC,0BAA0B,CAAC,EAAE,OAAO,CAAC;IAE9C;;;;;;;;;;;;;0DAasD;IACtD,kBAAkB,CAAC,CAAC,IAAI,EAAE;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,uEAAuE;QACvE,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,GAAG,MAAM,GAAG,IAAI,CAAC;IAElB;;;;;;;;;;;;;gEAa4D;IAC5D,UAAU,CACR,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,GAAG;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB;;sEAE8D;QAC9D,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,OAAO,CAAC,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAC5C,CAAC,CAAC;IAEH;;;4EAGwE;IACxE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAE5B,wFAAwF;IACxF,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAEpC;;;;;sEAKkE;IAClE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAE/B;qEACiE;IACjE,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC;IAE/B;;2EAEuE;IACvE,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEzC;;;;6EAIyE;IACzE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAErC,+CAA+C;IAC/C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,MAAM,KAAK,GAAG,aAAa,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,aAAa,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,4FAA4F;IAC5F,eAAe,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC1C,8FAA8F;IAC9F,SAAS,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;;2FAEuF;IACvF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;yEAEqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;+DAC2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,+CAA+C;IAC/C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B;;;;;yCAKqC;IACrC,SAAS,CAAC,IAAI,EAAE;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,OAAO,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,sFAAsF;QACtF,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,+EAA+E;QAC/E,MAAM,CAAC,EAAE,OAAO,qBAAqB,EAAE,MAAM,CAAC;KAC/C,GAAG,MAAM,EAAE,CAAC;IAEb;+DAC2D;IAC3D,QAAQ,CAAC,0BAA0B,CAAC,EAAE,OAAO,CAAC;IAE9C;;;;;;;;;;;;;0DAasD;IACtD,kBAAkB,CAAC,CAAC,IAAI,EAAE;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,uEAAuE;QACvE,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,GAAG,MAAM,GAAG,IAAI,CAAC;IAElB;;;;;;;;;;;;;gEAa4D;IAC5D,UAAU,CACR,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,GAAG;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB;;sEAE8D;QAC9D,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,OAAO,CAAC,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAC5C,CAAC,CAAC;IAEH;;;4EAGwE;IACxE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAE5B,wFAAwF;IACxF,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAEpC;;;;;sEAKkE;IAClE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAE/B;qEACiE;IACjE,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC;IAE/B;;2EAEuE;IACvE,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEzC;;;;6EAIyE;IACzE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAErC,+CAA+C;IAC/C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,MAAM,KAAK,GAAG,aAAa,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,aAAa,GAAG,KAAK,CAAC"}
@@ -15,14 +15,6 @@ export type BotListOutputEntry = {
15
15
  larkAppId: string;
16
16
  /** Alias for workflow authors. Equal to larkAppId when locally configured. */
17
17
  workflowBot: string | null;
18
- /** Short capability label (team-level), for picking who to hand off to. */
19
- capability: string | null;
20
- /** Whether this bot has a team-level role registered. */
21
- hasTeamRole: boolean;
22
- /** Whether YOU (the listing bot) can reliably @-mention it from here. */
23
- mentionable: boolean;
24
- /** How the @-mention handle was resolved. */
25
- mentionSource: 'cross-ref' | 'self' | 'observed' | 'fallback';
26
18
  };
27
19
  export declare function formatChatBotsForCli(chatBots: ChatBotMember[], currentLarkAppId: string): BotListOutputEntry[];
28
20
  export declare function formatBotInfoEntriesForCli(botEntries: BotInfoEntryForList[], currentLarkAppId: string): BotListOutputEntry[];
@@ -1 +1 @@
1
- {"version":3,"file":"bots-list-output.d.ts","sourceRoot":"","sources":["../../src/cli/bots-list-output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,wFAAwF;IACxF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,YAAY,GAAG,WAAW,CAAC;IACnC,gGAAgG;IAChG,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,2EAA2E;IAC3E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,yDAAyD;IACzD,WAAW,EAAE,OAAO,CAAC;IACrB,yEAAyE;IACzE,WAAW,EAAE,OAAO,CAAC;IACrB,6CAA6C;IAC7C,aAAa,EAAE,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;CAC/D,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,aAAa,EAAE,EACzB,gBAAgB,EAAE,MAAM,GACvB,kBAAkB,EAAE,CAatB;AAED,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,mBAAmB,EAAE,EACjC,gBAAgB,EAAE,MAAM,GACvB,kBAAkB,EAAE,CAgBtB"}
1
+ {"version":3,"file":"bots-list-output.d.ts","sourceRoot":"","sources":["../../src/cli/bots-list-output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,wFAAwF;IACxF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,YAAY,GAAG,WAAW,CAAC;IACnC,gGAAgG;IAChG,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,aAAa,EAAE,EACzB,gBAAgB,EAAE,MAAM,GACvB,kBAAkB,EAAE,CAStB;AAED,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,mBAAmB,EAAE,EACjC,gBAAgB,EAAE,MAAM,GACvB,kBAAkB,EAAE,CAWtB"}
@@ -6,10 +6,6 @@ export function formatChatBotsForCli(chatBots, currentLarkAppId) {
6
6
  source: cb.source,
7
7
  larkAppId: cb.larkAppId,
8
8
  workflowBot: cb.larkAppId || null,
9
- capability: cb.capability ?? null,
10
- hasTeamRole: cb.hasTeamRole,
11
- mentionable: cb.mentionable,
12
- mentionSource: cb.mentionSource,
13
9
  }));
14
10
  }
15
11
  export function formatBotInfoEntriesForCli(botEntries, currentLarkAppId) {
@@ -22,11 +18,6 @@ export function formatBotInfoEntriesForCli(botEntries, currentLarkAppId) {
22
18
  source: 'configured',
23
19
  larkAppId: b.larkAppId,
24
20
  workflowBot: b.larkAppId,
25
- // Local fallback path (no live chat query): we only know self reliably.
26
- capability: null,
27
- hasTeamRole: false,
28
- mentionable: b.larkAppId === currentLarkAppId,
29
- mentionSource: (b.larkAppId === currentLarkAppId ? 'self' : 'fallback'),
30
21
  }));
31
22
  }
32
23
  //# sourceMappingURL=bots-list-output.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bots-list-output.js","sourceRoot":"","sources":["../../src/cli/bots-list-output.ts"],"names":[],"mappings":"AA6BA,MAAM,UAAU,oBAAoB,CAClC,QAAyB,EACzB,gBAAwB;IAExB,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC3B,IAAI,EAAE,EAAE,CAAC,WAAW;QACpB,MAAM,EAAE,EAAE,CAAC,MAAM;QACjB,MAAM,EAAE,EAAE,CAAC,SAAS,KAAK,gBAAgB;QACzC,MAAM,EAAE,EAAE,CAAC,MAAM;QACjB,SAAS,EAAE,EAAE,CAAC,SAAS;QACvB,WAAW,EAAE,EAAE,CAAC,SAAS,IAAI,IAAI;QACjC,UAAU,EAAE,EAAE,CAAC,UAAU,IAAI,IAAI;QACjC,WAAW,EAAE,EAAE,CAAC,WAAW;QAC3B,WAAW,EAAE,EAAE,CAAC,WAAW;QAC3B,aAAa,EAAE,EAAE,CAAC,aAAa;KAChC,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,UAAiC,EACjC,gBAAwB;IAExB,OAAO,UAAU;SACd,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;SAC1B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACX,IAAI,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK;QAC1B,MAAM,EAAE,CAAC,CAAC,SAAU;QACpB,MAAM,EAAE,CAAC,CAAC,SAAS,KAAK,gBAAgB;QACxC,MAAM,EAAE,YAAqB;QAC7B,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,WAAW,EAAE,CAAC,CAAC,SAAS;QACxB,wEAAwE;QACxE,UAAU,EAAE,IAAI;QAChB,WAAW,EAAE,KAAK;QAClB,WAAW,EAAE,CAAC,CAAC,SAAS,KAAK,gBAAgB;QAC7C,aAAa,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAwB;KAC/F,CAAC,CAAC,CAAC;AACR,CAAC"}
1
+ {"version":3,"file":"bots-list-output.js","sourceRoot":"","sources":["../../src/cli/bots-list-output.ts"],"names":[],"mappings":"AAqBA,MAAM,UAAU,oBAAoB,CAClC,QAAyB,EACzB,gBAAwB;IAExB,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC3B,IAAI,EAAE,EAAE,CAAC,WAAW;QACpB,MAAM,EAAE,EAAE,CAAC,MAAM;QACjB,MAAM,EAAE,EAAE,CAAC,SAAS,KAAK,gBAAgB;QACzC,MAAM,EAAE,EAAE,CAAC,MAAM;QACjB,SAAS,EAAE,EAAE,CAAC,SAAS;QACvB,WAAW,EAAE,EAAE,CAAC,SAAS,IAAI,IAAI;KAClC,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,UAAiC,EACjC,gBAAwB;IAExB,OAAO,UAAU;SACd,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;SAC1B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACX,IAAI,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK;QAC1B,MAAM,EAAE,CAAC,CAAC,SAAU;QACpB,MAAM,EAAE,CAAC,CAAC,SAAS,KAAK,gBAAgB;QACxC,MAAM,EAAE,YAAqB;QAC7B,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,WAAW,EAAE,CAAC,CAAC,SAAS;KACzB,CAAC,CAAC,CAAC;AACR,CAAC"}
package/dist/cli.js CHANGED
@@ -33,6 +33,7 @@ import { logger } from './utils/logger.js';
33
33
  import { invalidWorkingDirs } from './utils/working-dir.js';
34
34
  import { firstPositional } from './cli/arg-utils.js';
35
35
  import { formatBotInfoEntriesForCli, formatChatBotsForCli, } from './cli/bots-list-output.js';
36
+ import { buildFooterAddressing, hasKnownBotMention, knownBotOpenIdsFromCrossRef, } from './utils/bot-routing.js';
36
37
  import { isLocale, setDefaultLocale, SUPPORTED_LOCALES } from './i18n/index.js';
37
38
  import { readGlobalConfig, setGlobalLocale, globalConfigPath } from './global-config.js';
38
39
  // Resolve the CLI's UI locale once from the global config file, so subsequent
@@ -478,7 +479,7 @@ async function promptBotConfig(rl) {
478
479
  return null;
479
480
  }
480
481
  console.log('✅ 凭证有效(tenant_access_token 已成功获取)\n');
481
- console.log('支持的 CLI: 1) claude-code 2) aiden 3) coco 4) codex 5) cursor 6) gemini 7) opencode 8) antigravity');
482
+ console.log('支持的 CLI: 1) claude-code 2) aiden 3) coco 4) codex 5) cursor 6) gemini 7) opencode 8) antigravity 9) mtr');
482
483
  const cliChoice = await ask(rl, 'CLI 适配器 [1]: ');
483
484
  let cliId;
484
485
  try {
@@ -562,7 +563,7 @@ async function promptEditBotConfig(rl, bot) {
562
563
  '留空保留当前值。',
563
564
  ]);
564
565
  input.larkAppSecret = await ask(rl, `LARK_APP_SECRET [保留当前值]: `);
565
- console.log('\n支持的 CLI: 1) claude-code 2) aiden 3) coco 4) codex 5) cursor 6) gemini 7) opencode 8) antigravity');
566
+ console.log('\n支持的 CLI: 1) claude-code 2) aiden 3) coco 4) codex 5) cursor 6) gemini 7) opencode 8) antigravity 9) mtr');
566
567
  printInputHelp('CLI 适配器', [
567
568
  '选择 botmux 需要套用哪一种 CLI 参数协议和会话恢复方式。',
568
569
  '留空保留当前值;可以输入序号,也可以直接输入适配器 ID。',
@@ -2456,20 +2457,6 @@ function argValues(args, ...flags) {
2456
2457
  // daemon's bridge fallback path can produce identical cards. cmdSend
2457
2458
  // keeps using `buildCardBodyElements` and `hasMarkdown` from there.
2458
2459
  import { buildCardBodyElements, hasMarkdown } from './im/lark/md-card.js';
2459
- /**
2460
- * Decide who the reply card should @ in its footer.
2461
- *
2462
- * Non-oncall chats: `发送给: @<owner>`.
2463
- * Oncall chats: `发送给: @<last caller>` (falls back to owner if unknown) —
2464
- * permission is governed by allowedUsers, so there's no per-chat list to cc.
2465
- */
2466
- function buildFooterAddressing(s, oncall) {
2467
- const owner = s.ownerOpenId;
2468
- const caller = s.lastCallerOpenId ?? owner;
2469
- if (!oncall)
2470
- return { sendTo: owner, cc: [] };
2471
- return { sendTo: caller, cc: [] };
2472
- }
2473
2460
  async function cmdSend(rest) {
2474
2461
  // Safety gate: a CLI agent running inside a workflow subagent (Slice F)
2475
2462
  // must not chat-post directly — chat-facing side effects are reserved
@@ -2616,12 +2603,14 @@ async function cmdSend(rest) {
2616
2603
  // "获取群组中其他机器人和用户@当前机器人的消息"权限),不再走任何本地
2617
2604
  // 转发——botmux 历史上为绕过 Lark 不投递跨 bot 事件搞过 signal-file,
2618
2605
  // 那套已经在该权限上线后整体下线。
2606
+ let botEntries = [];
2607
+ let crossRef = {};
2619
2608
  try {
2620
2609
  const dataDir = resolveDataDir();
2621
2610
  const botInfoPath = join(dataDir, 'bots-info.json');
2622
- const botEntries = existsSync(botInfoPath) ? JSON.parse(readFileSync(botInfoPath, 'utf-8')) : [];
2611
+ botEntries = existsSync(botInfoPath) ? JSON.parse(readFileSync(botInfoPath, 'utf-8')) : [];
2623
2612
  const crossRefPath = join(dataDir, `bot-openids-${appId}.json`);
2624
- const crossRef = existsSync(crossRefPath)
2613
+ crossRef = existsSync(crossRefPath)
2625
2614
  ? JSON.parse(readFileSync(crossRefPath, 'utf-8'))
2626
2615
  : {};
2627
2616
  const alreadyMentioned = new Set(mentions.map(m => m.open_id));
@@ -2629,10 +2618,16 @@ async function cmdSend(rest) {
2629
2618
  // prefix ("Claude") when both could match — break-on-first-hit otherwise
2630
2619
  // routes "@Claude分身" to Claude.
2631
2620
  const sortedEntries = [...botEntries].sort((a, b) => (b.botName?.length ?? 0) - (a.botName?.length ?? 0));
2621
+ const selfAliases = new Set(botEntries
2622
+ .filter(entry => entry.larkAppId === appId)
2623
+ .flatMap(entry => [entry.botName, entry.cliId])
2624
+ .filter((name) => !!name)
2625
+ .map(name => name.toLowerCase()));
2632
2626
  for (const entry of sortedEntries) {
2633
2627
  if (!entry.botName || entry.larkAppId === appId)
2634
2628
  continue;
2635
- const names = [entry.botName, entry.cliId].filter(Boolean);
2629
+ const names = [entry.botName, entry.cliId]
2630
+ .filter((name) => !!name && !selfAliases.has(name.toLowerCase()));
2636
2631
  for (const name of names) {
2637
2632
  const escName = name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
2638
2633
  // Boundary: lookbehind blocks only ASCII word chars (so `user@Claude`
@@ -2661,6 +2656,15 @@ async function cmdSend(rest) {
2661
2656
  }
2662
2657
  }
2663
2658
  catch { /* best-effort */ }
2659
+ const explicitKnownBotMention = hasKnownBotMention(text, mentions, botEntries, crossRef, appId);
2660
+ const knownBotOpenIds = knownBotOpenIdsFromCrossRef(crossRef, botEntries, appId);
2661
+ const footerAddressing = sendTopLevel
2662
+ ? { sendTo: undefined, cc: [] }
2663
+ : buildFooterAddressing(s, {
2664
+ isOncall: !!oncallEntry,
2665
+ hasExplicitBotMention: explicitKnownBotMention,
2666
+ knownBotOpenIds,
2667
+ });
2664
2668
  // Decide: interactive card (renders markdown) vs. post (plain text).
2665
2669
  // Explicit --card / --text wins; otherwise auto-detect markdown syntax.
2666
2670
  const useCard = forceCard || (!forceText && hasMarkdown(text));
@@ -2724,14 +2728,13 @@ async function cmdSend(rest) {
2724
2728
  const elements = mdWithImages ? buildCardBodyElements(mdWithImages) : [];
2725
2729
  // Footer: de-emphasized markdown (v2 dropped the `note` tag). Use small
2726
2730
  // text size + grey font tag so it reads like a footnote below the hr.
2727
- // Oncall groups: `发送给` targets whoever triggered this turn (may not
2728
- // be the session owner). Non-oncall: keep owner-only behaviour.
2731
+ // Oncall groups usually address whoever triggered this turn (may not be
2732
+ // the session owner). Bot recipients are filtered out so footer chrome
2733
+ // cannot accidentally wake a sibling bot.
2729
2734
  const footerParts = ['[botmux](https://github.com/deepcoldy/botmux)'];
2730
2735
  // Top-level publish has no specific recipient — drop "发送给/cc" addressing
2731
2736
  // so the message doesn't @ the session owner who isn't even in the target chat.
2732
- const addressing = sendTopLevel
2733
- ? { sendTo: undefined, cc: [] }
2734
- : buildFooterAddressing(s, oncallEntry);
2737
+ const addressing = footerAddressing;
2735
2738
  if (addressing.sendTo)
2736
2739
  footerParts.push(`发送给:<at id=${addressing.sendTo}></at>`);
2737
2740
  if (addressing.cc.length > 0) {
@@ -2787,11 +2790,9 @@ async function cmdSend(rest) {
2787
2790
  }
2788
2791
  }
2789
2792
  // Footer: mirror the card layout — a blank paragraph separates the body
2790
- // from the addressing line(s). `发送给: @<caller>` always. Top-level
2791
- // publish has no specific recipient skip addressing entirely.
2792
- const addressing = sendTopLevel
2793
- ? { sendTo: undefined, cc: [] }
2794
- : buildFooterAddressing(s, oncallEntry);
2793
+ // from the addressing line(s). Top-level publish has no specific
2794
+ // recipient; bot recipients are filtered out by footerAddressing.
2795
+ const addressing = footerAddressing;
2795
2796
  if (addressing.sendTo || addressing.cc.length > 0) {
2796
2797
  if (postContent.length > 0)
2797
2798
  postContent.push([{ tag: 'text', text: '' }]);