botmux 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +3 -4
- package/README.en.md +44 -5
- package/README.md +44 -5
- package/dist/adapters/backend/tmux-backend.d.ts +33 -7
- package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
- package/dist/adapters/backend/tmux-backend.js +123 -13
- package/dist/adapters/backend/tmux-backend.js.map +1 -1
- package/dist/adapters/backend/types.d.ts +3 -0
- package/dist/adapters/backend/types.d.ts.map +1 -1
- package/dist/adapters/cli/aiden.d.ts.map +1 -1
- package/dist/adapters/cli/aiden.js +4 -0
- package/dist/adapters/cli/aiden.js.map +1 -1
- package/dist/adapters/cli/claude-code.d.ts.map +1 -1
- package/dist/adapters/cli/claude-code.js +5 -0
- package/dist/adapters/cli/claude-code.js.map +1 -1
- package/dist/adapters/cli/coco.d.ts.map +1 -1
- package/dist/adapters/cli/coco.js +5 -0
- package/dist/adapters/cli/coco.js.map +1 -1
- package/dist/adapters/cli/codex.d.ts.map +1 -1
- package/dist/adapters/cli/codex.js +3 -0
- package/dist/adapters/cli/codex.js.map +1 -1
- package/dist/adapters/cli/types.d.ts +3 -0
- package/dist/adapters/cli/types.d.ts.map +1 -1
- package/dist/cli.js +1 -4
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +13 -2
- package/dist/config.js.map +1 -1
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +8 -7
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/session-manager.d.ts +2 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +37 -5
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +41 -0
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +28 -11
- package/dist/daemon.js.map +1 -1
- package/dist/im/lark/client.d.ts +2 -3
- package/dist/im/lark/client.d.ts.map +1 -1
- package/dist/im/lark/client.js +5 -16
- package/dist/im/lark/client.js.map +1 -1
- package/dist/services/project-scanner.d.ts +4 -0
- package/dist/services/project-scanner.d.ts.map +1 -1
- package/dist/services/project-scanner.js +22 -0
- package/dist/services/project-scanner.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +13 -6
- package/dist/utils/logger.js.map +1 -1
- package/dist/worker.js +30 -5
- package/dist/worker.js.map +1 -1
- package/ecosystem.config.cjs +2 -2
- package/package.json +1 -1
- package/dist/scheduler.d.ts +0 -38
- package/dist/scheduler.d.ts.map +0 -1
- package/dist/scheduler.js +0 -221
- package/dist/scheduler.js.map +0 -1
- package/dist/services/lark-client.d.ts +0 -22
- package/dist/services/lark-client.d.ts.map +0 -1
- package/dist/services/lark-client.js +0 -238
- package/dist/services/lark-client.js.map +0 -1
- package/dist/services/lark-ws.d.ts +0 -5
- package/dist/services/lark-ws.d.ts.map +0 -1
- package/dist/services/lark-ws.js +0 -79
- package/dist/services/lark-ws.js.map +0 -1
- package/dist/services/message-router.d.ts +0 -8
- package/dist/services/message-router.d.ts.map +0 -1
- package/dist/services/message-router.js +0 -73
- package/dist/services/message-router.js.map +0 -1
- package/dist/tools/close-session.d.ts +0 -22
- package/dist/tools/close-session.d.ts.map +0 -1
- package/dist/tools/close-session.js +0 -38
- package/dist/tools/close-session.js.map +0 -1
- package/dist/tools/create-session.d.ts +0 -28
- package/dist/tools/create-session.d.ts.map +0 -1
- package/dist/tools/create-session.js +0 -40
- package/dist/tools/create-session.js.map +0 -1
- package/dist/tools/wait-for-reply.d.ts +0 -17
- package/dist/tools/wait-for-reply.d.ts.map +0 -1
- package/dist/tools/wait-for-reply.js +0 -65
- package/dist/tools/wait-for-reply.js.map +0 -1
- package/dist/utils/card-builder.d.ts +0 -16
- package/dist/utils/card-builder.d.ts.map +0 -1
- package/dist/utils/card-builder.js +0 -183
- package/dist/utils/card-builder.js.map +0 -1
- package/dist/utils/message-parser.d.ts +0 -45
- package/dist/utils/message-parser.d.ts.map +0 -1
- package/dist/utils/message-parser.js +0 -132
- package/dist/utils/message-parser.js.map +0 -1
package/.env.example
CHANGED
|
@@ -7,11 +7,10 @@ LARK_APP_SECRET=
|
|
|
7
7
|
|
|
8
8
|
# Daemon settings
|
|
9
9
|
# CLI_ID=claude-code # CLI adapter: claude-code, aiden, coco, codex
|
|
10
|
-
# WORKING_DIR=~ # Default working directory
|
|
10
|
+
# WORKING_DIR=~ # Default working directory (comma-separated for multiple dirs, e.g. ~/projects,~/work)
|
|
11
11
|
|
|
12
|
-
# Access control (comma-separated
|
|
13
|
-
# ALLOWED_USERS=alice,
|
|
14
|
-
# LARK_EMAIL_DOMAIN=example.com # Default email domain for ALLOWED_USERS prefixes
|
|
12
|
+
# Access control (comma-separated emails or Lark open_ids, empty = allow all)
|
|
13
|
+
# ALLOWED_USERS=alice@example.com,ou_xxxx
|
|
15
14
|
|
|
16
15
|
# Project scanning directory for /repo command (default: parent of WORKING_DIR)
|
|
17
16
|
# PROJECT_SCAN_DIR=
|
package/README.en.md
CHANGED
|
@@ -4,13 +4,17 @@
|
|
|
4
4
|
|
|
5
5
|
Bridge between Lark (Feishu) topic groups and AI coding CLIs. The daemon listens for Lark messages and automatically spawns an independent CLI process (supporting Claude Code, Aiden, CoCo, Codex) for each new topic thread, with live streaming cards and a web-based terminal.
|
|
6
6
|
|
|
7
|
+
## Demo
|
|
8
|
+
|
|
9
|
+
<video src="https://github.com/user-attachments/assets/840d3bb6-3b98-465a-8662-b4beadeb48ce" width="100%" controls></video>
|
|
10
|
+
|
|
7
11
|
## Features
|
|
8
12
|
|
|
9
13
|
- **One topic = one AI coding session** — each Lark thread gets its own isolated CLI process
|
|
10
14
|
- **Multi-CLI support** — adapter architecture supports Claude Code, Aiden, CoCo, Codex, and is extensible
|
|
11
15
|
- **Live streaming cards** — real-time terminal output rendered in Feishu cards with markdown support, per-turn card lifecycle
|
|
12
16
|
- **Web terminal (xterm.js)** — full PTY output in the browser with optional write access via on-demand DM link
|
|
13
|
-
- **Session persistence** — sessions survive daemon restarts
|
|
17
|
+
- **Session persistence** — sessions survive daemon restarts; with tmux backend, CLI processes persist across restarts with zero interruption
|
|
14
18
|
- **Scheduled tasks** — cron-based recurring prompts with natural language scheduling (Chinese supported)
|
|
15
19
|
- **Project management** — interactive repo selector, per-session working directory
|
|
16
20
|
- **MCP integration** — CLI can reply to Lark threads, read message history, and add reactions via MCP tools
|
|
@@ -31,7 +35,7 @@ Daemon (daemon.ts → core/ modules)
|
|
|
31
35
|
|
|
|
32
36
|
Worker (worker.ts) -- forked child process per session
|
|
33
37
|
|-- adapters/cli/*: CLI adapters (Claude Code / Aiden / CoCo / Codex)
|
|
34
|
-
|-- adapters/backend
|
|
38
|
+
|-- adapters/backend: PtyBackend (node-pty) or TmuxBackend (tmux + node-pty)
|
|
35
39
|
|-- utils/idle-detector: idle detection (quiescence + spinner + completion marker)
|
|
36
40
|
|-- HTTP + WebSocket server: serves xterm.js web terminal
|
|
37
41
|
|-- Headless xterm: captures screen for streaming cards
|
|
@@ -49,6 +53,7 @@ Lark API
|
|
|
49
53
|
- **Node.js** >= 20
|
|
50
54
|
- **AI coding CLI** installed and authenticated (`claude`, `aiden`, `coco`, or `codex` in PATH)
|
|
51
55
|
- **Lark app** with Bot and Message permissions (WebSocket event subscription)
|
|
56
|
+
- **tmux** >= 3.x (optional — auto-enabled when installed for persistent CLI sessions)
|
|
52
57
|
|
|
53
58
|
## Installation
|
|
54
59
|
|
|
@@ -100,8 +105,8 @@ Configuration is stored at `~/.botmux/.env`. Run `botmux setup` to create it int
|
|
|
100
105
|
|----------|---------|-------------|
|
|
101
106
|
| `CLI_ID` | `claude-code` | CLI adapter (`claude-code`, `aiden`, `coco`, `codex`) |
|
|
102
107
|
| `CLI_PATH` | _(auto-detect by CLI_ID)_ | CLI binary path override |
|
|
103
|
-
| `BACKEND_TYPE` |
|
|
104
|
-
| `WORKING_DIR` | `~` | Default working directory |
|
|
108
|
+
| `BACKEND_TYPE` | _(auto-detect)_ | Session backend: `tmux` if available, otherwise `pty` |
|
|
109
|
+
| `WORKING_DIR` | `~` | Default working directory; supports comma-separated multiple dirs (e.g. `~/a,~/b`), `/repo` scans all |
|
|
105
110
|
| `ALLOWED_USERS` | _(empty = allow all)_ | Comma-separated email prefixes or Lark open_ids |
|
|
106
111
|
| `PROJECT_SCAN_DIR` | _(parent of CWD)_ | Directory to scan for git repos |
|
|
107
112
|
| `WEB_HOST` | `0.0.0.0` | HTTP server bind address |
|
|
@@ -183,6 +188,40 @@ Each session exposes a web terminal at `http://<WEB_EXTERNAL_HOST>:<port>`.
|
|
|
183
188
|
|
|
184
189
|
Features: xterm.js with fit/unicode11/web-links addons, TokyoNight theme, scrollback buffer, mobile-friendly viewport.
|
|
185
190
|
|
|
191
|
+
### Tmux Persistent Sessions
|
|
192
|
+
|
|
193
|
+
When tmux is installed, botmux automatically uses the tmux backend (pty-under-tmux architecture). CLI processes run inside tmux sessions while the daemon attaches via node-pty to capture output — streaming cards, idle detection, and web terminal all work unchanged.
|
|
194
|
+
|
|
195
|
+
**Key benefit: daemon restarts don't interrupt the CLI.** During `botmux restart`, the worker process exits but the tmux session (and the CLI inside it) keeps running. The next incoming message triggers a re-attach — no `--resume` context reload needed.
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
# List active botmux tmux sessions
|
|
199
|
+
tmux list-sessions | grep bmx-
|
|
200
|
+
|
|
201
|
+
# Manually attach for debugging (observe CLI in real time)
|
|
202
|
+
tmux attach -t bmx-<first-8-chars-of-session-id>
|
|
203
|
+
# Ctrl+B, D to detach — CLI keeps running
|
|
204
|
+
|
|
205
|
+
# Force pure pty mode (disable tmux)
|
|
206
|
+
BACKEND_TYPE=pty botmux start
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**Session naming:** `bmx-<first 8 chars of session UUID>`, deterministically derived.
|
|
210
|
+
|
|
211
|
+
**Lifecycle:**
|
|
212
|
+
|
|
213
|
+
| Event | tmux session | CLI process |
|
|
214
|
+
|-------|-------------|-------------|
|
|
215
|
+
| `botmux restart` | Survives | Survives (re-attaches on next message) |
|
|
216
|
+
| `/close` or close button | Destroyed | Terminated (SIGHUP) |
|
|
217
|
+
| CLI exits / crashes | Closes with it | Already exited (auto-restart creates new session) |
|
|
218
|
+
| `CLI_ID` changed + restart | All destroyed | All terminated (prevents pattern mismatch) |
|
|
219
|
+
|
|
220
|
+
**Notes:**
|
|
221
|
+
- Switching `CLI_ID` (e.g. `claude-code` → `coco`) and restarting the daemon will kill all existing tmux sessions, since the old CLI's idle detection patterns are incompatible with the new adapter
|
|
222
|
+
- Orphaned tmux sessions (not in the active session list) are cleaned up automatically on daemon startup
|
|
223
|
+
- Set `BACKEND_TYPE=pty` to opt out of tmux persistence
|
|
224
|
+
|
|
186
225
|
## MCP Tools
|
|
187
226
|
|
|
188
227
|
Claude Code has access to three MCP tools for interacting with Lark:
|
|
@@ -230,7 +269,7 @@ src/
|
|
|
230
269
|
backend/
|
|
231
270
|
types.ts # SessionBackend interface
|
|
232
271
|
pty-backend.ts # node-pty backend
|
|
233
|
-
tmux-backend.ts # tmux backend (
|
|
272
|
+
tmux-backend.ts # tmux backend (pty-under-tmux, persistent sessions)
|
|
234
273
|
core/
|
|
235
274
|
types.ts # DaemonSession core type
|
|
236
275
|
worker-pool.ts # Worker process pool management
|
package/README.md
CHANGED
|
@@ -4,13 +4,17 @@
|
|
|
4
4
|
|
|
5
5
|
飞书话题群与 AI 编程 CLI 的桥接工具。Daemon 监听飞书消息,为每个新话题自动启动一个独立的 CLI 进程(支持 Claude Code、Aiden、CoCo、Codex),提供实时流式卡片和 Web 终端。
|
|
6
6
|
|
|
7
|
+
## 演示
|
|
8
|
+
|
|
9
|
+
<video src="https://github.com/user-attachments/assets/840d3bb6-3b98-465a-8662-b4beadeb48ce" width="100%" controls></video>
|
|
10
|
+
|
|
7
11
|
## 功能特性
|
|
8
12
|
|
|
9
13
|
- **一个话题 = 一个 AI 编程会话** — 每个飞书话题线程对应一个独立的 CLI 进程
|
|
10
14
|
- **多 CLI 支持** — 通过适配器架构支持 Claude Code、Aiden、CoCo、Codex,可扩展
|
|
11
15
|
- **实时流式卡片** — 终端输出实时渲染到飞书卡片中,支持 Markdown 格式,每轮对话独立卡片
|
|
12
16
|
- **Web 终端 (xterm.js)** — 浏览器查看完整 PTY 输出,按需获取可操作链接
|
|
13
|
-
- **会话持久化** — 会话在 Daemon
|
|
17
|
+
- **会话持久化** — 会话在 Daemon 重启后自动恢复;tmux 后端下 CLI 进程常驻,重启零中断
|
|
14
18
|
- **定时任务** — 基于 Cron 的周期性任务,支持中文自然语言配置
|
|
15
19
|
- **项目管理** — 交互式仓库选择器,每个会话独立工作目录
|
|
16
20
|
- **MCP 集成** — CLI 可通过 MCP 工具回复飞书话题、读取消息历史、添加表情回应
|
|
@@ -31,7 +35,7 @@ Daemon (daemon.ts → core/ 模块)
|
|
|
31
35
|
|
|
|
32
36
|
Worker (worker.ts) -- 每个会话 fork 一个子进程
|
|
33
37
|
|-- adapters/cli/*: CLI 适配器 (Claude Code / Aiden / CoCo / Codex)
|
|
34
|
-
|-- adapters/backend
|
|
38
|
+
|-- adapters/backend: PtyBackend (node-pty) 或 TmuxBackend (tmux + node-pty)
|
|
35
39
|
|-- utils/idle-detector: 空闲检测(静默 + Spinner + 完成标记)
|
|
36
40
|
|-- HTTP + WebSocket: 提供 xterm.js Web 终端
|
|
37
41
|
|-- Headless xterm: 捕获屏幕内容用于流式卡片
|
|
@@ -49,6 +53,7 @@ AI 编程 CLI (交互式 TTY 模式)
|
|
|
49
53
|
- **Node.js** >= 20
|
|
50
54
|
- **AI 编程 CLI** 已安装并完成认证(`claude`、`aiden`、`coco` 或 `codex` 在 PATH 中)
|
|
51
55
|
- **飞书应用** 具备机器人和消息权限(WebSocket 事件订阅)
|
|
56
|
+
- **tmux** >= 3.x(可选,安装后自动启用会话常驻)
|
|
52
57
|
|
|
53
58
|
## 安装
|
|
54
59
|
|
|
@@ -100,8 +105,8 @@ botmux start
|
|
|
100
105
|
|------|--------|------|
|
|
101
106
|
| `CLI_ID` | `claude-code` | CLI 适配器(`claude-code`、`aiden`、`coco`、`codex`) |
|
|
102
107
|
| `CLI_PATH` | _(按 CLI_ID 自动检测)_ | CLI 可执行文件路径覆盖 |
|
|
103
|
-
| `BACKEND_TYPE` |
|
|
104
|
-
| `WORKING_DIR` | `~` |
|
|
108
|
+
| `BACKEND_TYPE` | _(自动检测)_ | 会话后端:有 tmux 则用 `tmux`,否则 `pty` |
|
|
109
|
+
| `WORKING_DIR` | `~` | 默认工作目录,支持逗号分隔多个目录(如 `~/a,~/b`),`/repo` 会扫描所有目录 |
|
|
105
110
|
| `ALLOWED_USERS` | _(空 = 不限制)_ | 允许的用户,邮箱前缀或 open_id,逗号分隔 |
|
|
106
111
|
| `PROJECT_SCAN_DIR` | _(工作目录的上级)_ | 扫描 Git 仓库的目录 |
|
|
107
112
|
| `WEB_HOST` | `0.0.0.0` | HTTP 服务绑定地址 |
|
|
@@ -183,6 +188,40 @@ botmux start
|
|
|
183
188
|
|
|
184
189
|
特性:xterm.js + fit/unicode11/web-links 插件、TokyoNight 主题、滚动缓冲区、移动端适配。
|
|
185
190
|
|
|
191
|
+
### Tmux 会话常驻
|
|
192
|
+
|
|
193
|
+
安装 tmux 后,botmux 自动使用 tmux 后端(`pty-under-tmux` 架构)。CLI 进程运行在 tmux session 内,daemon 通过 node-pty attach 到 tmux 来捕获输出,现有的流式卡片、空闲检测、Web 终端等功能全部不受影响。
|
|
194
|
+
|
|
195
|
+
**核心收益:Daemon 重启不中断 CLI。** `botmux restart` 时 worker 进程退出,但 tmux session(及其中的 CLI 进程)保持运行。下次收到消息时 worker 自动 re-attach,无需 `--resume` 重载上下文。
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
# 查看活跃的 botmux tmux 会话
|
|
199
|
+
tmux list-sessions | grep bmx-
|
|
200
|
+
|
|
201
|
+
# 手动 attach 调试(实时观察 CLI 终端)
|
|
202
|
+
tmux attach -t bmx-<session-id-前8位>
|
|
203
|
+
# Ctrl+B, D 退出 attach,不影响 CLI 继续运行
|
|
204
|
+
|
|
205
|
+
# 强制降级到纯 pty 模式(不使用 tmux)
|
|
206
|
+
BACKEND_TYPE=pty botmux start
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**tmux 会话命名规则:** `bmx-<sessionId 前 8 位>`,由 session UUID 确定性派生。
|
|
210
|
+
|
|
211
|
+
**生命周期:**
|
|
212
|
+
|
|
213
|
+
| 事件 | tmux session | CLI 进程 |
|
|
214
|
+
|------|-------------|---------|
|
|
215
|
+
| `botmux restart` | 存活 | 存活(下次消息 re-attach) |
|
|
216
|
+
| `/close` 或关闭按钮 | 销毁 | 终止(SIGHUP) |
|
|
217
|
+
| CLI 自行退出 / 崩溃 | 随之关闭 | 已退出(自动重启用新 session) |
|
|
218
|
+
| 切换 `CLI_ID` 后重启 | 全部销毁 | 全部终止(防止 pattern 不匹配) |
|
|
219
|
+
|
|
220
|
+
**注意事项:**
|
|
221
|
+
- 切换 `CLI_ID`(如 `claude-code` → `coco`)后重启 daemon,所有旧 tmux session 会被自动清理,因为旧 CLI 的 idle detection pattern 与新适配器不兼容
|
|
222
|
+
- 孤儿 tmux session(不在 active session 列表中的)会在 daemon 启动时自动清理
|
|
223
|
+
- 如果不需要 tmux 常驻特性,设置 `BACKEND_TYPE=pty` 即可降级
|
|
224
|
+
|
|
186
225
|
## MCP 工具
|
|
187
226
|
|
|
188
227
|
Claude Code 可使用三个 MCP 工具与飞书交互:
|
|
@@ -230,7 +269,7 @@ src/
|
|
|
230
269
|
backend/
|
|
231
270
|
types.ts # SessionBackend 接口
|
|
232
271
|
pty-backend.ts # node-pty 后端
|
|
233
|
-
tmux-backend.ts # tmux 后端(
|
|
272
|
+
tmux-backend.ts # tmux 后端(pty-under-tmux,会话常驻)
|
|
234
273
|
core/
|
|
235
274
|
types.ts # DaemonSession 核心类型
|
|
236
275
|
worker-pool.ts # Worker 进程池管理
|
|
@@ -1,17 +1,43 @@
|
|
|
1
1
|
import type { SessionBackend, SpawnOpts } from './types.js';
|
|
2
2
|
/**
|
|
3
|
-
* TmuxBackend —
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* TmuxBackend — session backend using tmux for process persistence.
|
|
4
|
+
*
|
|
5
|
+
* Architecture: pty-under-tmux.
|
|
6
|
+
* - A node-pty process runs `tmux new-session` or `tmux attach-session`
|
|
7
|
+
* - All output flows through the pty (onData/onExit work unchanged)
|
|
8
|
+
* - kill() only detaches (kills the pty viewer), tmux session survives
|
|
9
|
+
* - destroySession() kills the tmux session (for explicit /close)
|
|
10
|
+
*
|
|
11
|
+
* Naming: tmux sessions are named `bmx-<sessionId.slice(0,8)>`.
|
|
6
12
|
*/
|
|
7
13
|
export declare class TmuxBackend implements SessionBackend {
|
|
8
|
-
private
|
|
14
|
+
private process;
|
|
15
|
+
private readonly sessionName;
|
|
16
|
+
private reattaching;
|
|
17
|
+
constructor(sessionName: string);
|
|
18
|
+
/** Check if tmux binary is available on PATH. */
|
|
19
|
+
static isAvailable(): boolean;
|
|
20
|
+
/** Derive tmux session name from a session UUID. */
|
|
21
|
+
static sessionName(sessionId: string): string;
|
|
22
|
+
/** Check if a named tmux session exists. */
|
|
23
|
+
static hasSession(name: string): boolean;
|
|
24
|
+
/** Kill a named tmux session (no-op if it doesn't exist). */
|
|
25
|
+
static killSession(name: string): void;
|
|
26
|
+
/** List all botmux tmux sessions (bmx-* prefix). */
|
|
27
|
+
static listBotmuxSessions(): string[];
|
|
9
28
|
spawn(bin: string, args: string[], opts: SpawnOpts): void;
|
|
29
|
+
/** Whether the last spawn() re-attached to an existing tmux session. */
|
|
30
|
+
get isReattach(): boolean;
|
|
10
31
|
write(data: string): void;
|
|
11
|
-
resize(
|
|
12
|
-
|
|
13
|
-
|
|
32
|
+
resize(cols: number, rows: number): void;
|
|
33
|
+
/** Must be called AFTER spawn(). Callbacks registered before spawn are silently lost. */
|
|
34
|
+
onData(cb: (data: string) => void): void;
|
|
35
|
+
/** Must be called AFTER spawn(). Callbacks registered before spawn are silently lost. */
|
|
36
|
+
onExit(cb: (code: number | null, signal: string | null) => void): void;
|
|
37
|
+
/** Detach only — kills the pty viewer but leaves tmux session alive. */
|
|
14
38
|
kill(): void;
|
|
39
|
+
/** Kill the tmux session permanently. Called on explicit /close. */
|
|
40
|
+
destroySession(): void;
|
|
15
41
|
getAttachInfo(): {
|
|
16
42
|
type: "tmux";
|
|
17
43
|
sessionName: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tmux-backend.d.ts","sourceRoot":"","sources":["../../../src/adapters/backend/tmux-backend.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tmux-backend.d.ts","sourceRoot":"","sources":["../../../src/adapters/backend/tmux-backend.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5D;;;;;;;;;;GAUG;AACH,qBAAa,WAAY,YAAW,cAAc;IAChD,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,WAAW,CAAS;gBAEhB,WAAW,EAAE,MAAM;IAM/B,iDAAiD;IACjD,MAAM,CAAC,WAAW,IAAI,OAAO;IAS7B,oDAAoD;IACpD,MAAM,CAAC,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAI7C,4CAA4C;IAC5C,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IASxC,6DAA6D;IAC7D,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAMtC,oDAAoD;IACpD,MAAM,CAAC,kBAAkB,IAAI,MAAM,EAAE;IAarC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IA+BzD,wEAAwE;IACxE,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIzB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAIxC,yFAAyF;IACzF,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIxC,yFAAyF;IACzF,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI;IAMtE,wEAAwE;IACxE,IAAI,IAAI,IAAI;IAOZ,oEAAoE;IACpE,cAAc,IAAI,IAAI;IAKtB,aAAa;;;;CAGd"}
|
|
@@ -1,30 +1,140 @@
|
|
|
1
|
+
import * as pty from 'node-pty';
|
|
2
|
+
import { execSync } from 'node:child_process';
|
|
1
3
|
/**
|
|
2
|
-
* TmuxBackend —
|
|
3
|
-
*
|
|
4
|
-
*
|
|
4
|
+
* TmuxBackend — session backend using tmux for process persistence.
|
|
5
|
+
*
|
|
6
|
+
* Architecture: pty-under-tmux.
|
|
7
|
+
* - A node-pty process runs `tmux new-session` or `tmux attach-session`
|
|
8
|
+
* - All output flows through the pty (onData/onExit work unchanged)
|
|
9
|
+
* - kill() only detaches (kills the pty viewer), tmux session survives
|
|
10
|
+
* - destroySession() kills the tmux session (for explicit /close)
|
|
11
|
+
*
|
|
12
|
+
* Naming: tmux sessions are named `bmx-<sessionId.slice(0,8)>`.
|
|
5
13
|
*/
|
|
6
14
|
export class TmuxBackend {
|
|
7
|
-
|
|
15
|
+
process = null;
|
|
16
|
+
sessionName;
|
|
17
|
+
reattaching = false;
|
|
18
|
+
constructor(sessionName) {
|
|
19
|
+
this.sessionName = sessionName;
|
|
20
|
+
}
|
|
21
|
+
// ─── Static helpers ───────────────────────────────────────────────────────
|
|
22
|
+
/** Check if tmux binary is available on PATH. */
|
|
23
|
+
static isAvailable() {
|
|
24
|
+
try {
|
|
25
|
+
execSync('tmux -V', { stdio: 'ignore' });
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Derive tmux session name from a session UUID. */
|
|
33
|
+
static sessionName(sessionId) {
|
|
34
|
+
return `bmx-${sessionId.slice(0, 8)}`;
|
|
35
|
+
}
|
|
36
|
+
/** Check if a named tmux session exists. */
|
|
37
|
+
static hasSession(name) {
|
|
38
|
+
try {
|
|
39
|
+
execSync(`tmux has-session -t ${shellescape(name)}`, { stdio: 'ignore' });
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/** Kill a named tmux session (no-op if it doesn't exist). */
|
|
47
|
+
static killSession(name) {
|
|
48
|
+
try {
|
|
49
|
+
execSync(`tmux kill-session -t ${shellescape(name)}`, { stdio: 'ignore' });
|
|
50
|
+
}
|
|
51
|
+
catch { /* session doesn't exist */ }
|
|
52
|
+
}
|
|
53
|
+
/** List all botmux tmux sessions (bmx-* prefix). */
|
|
54
|
+
static listBotmuxSessions() {
|
|
55
|
+
try {
|
|
56
|
+
const out = execSync("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
|
|
57
|
+
encoding: 'utf-8',
|
|
58
|
+
});
|
|
59
|
+
return out.split('\n').filter(s => s.startsWith('bmx-'));
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return [];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// ─── SessionBackend implementation ────────────────────────────────────────
|
|
8
66
|
spawn(bin, args, opts) {
|
|
9
|
-
|
|
67
|
+
this.reattaching = TmuxBackend.hasSession(this.sessionName);
|
|
68
|
+
if (this.reattaching) {
|
|
69
|
+
// Re-attach to surviving tmux session (CLI is still running)
|
|
70
|
+
this.process = pty.spawn('tmux', ['attach-session', '-t', this.sessionName], {
|
|
71
|
+
name: 'xterm-256color',
|
|
72
|
+
cols: opts.cols,
|
|
73
|
+
rows: opts.rows,
|
|
74
|
+
cwd: opts.cwd,
|
|
75
|
+
env: opts.env,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// Create new tmux session running the CLI command
|
|
80
|
+
const tmuxArgs = [
|
|
81
|
+
'new-session',
|
|
82
|
+
'-s', this.sessionName,
|
|
83
|
+
'-x', String(opts.cols),
|
|
84
|
+
'-y', String(opts.rows),
|
|
85
|
+
'--', bin, ...args,
|
|
86
|
+
];
|
|
87
|
+
this.process = pty.spawn('tmux', tmuxArgs, {
|
|
88
|
+
name: 'xterm-256color',
|
|
89
|
+
cols: opts.cols,
|
|
90
|
+
rows: opts.rows,
|
|
91
|
+
cwd: opts.cwd,
|
|
92
|
+
env: opts.env,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/** Whether the last spawn() re-attached to an existing tmux session. */
|
|
97
|
+
get isReattach() {
|
|
98
|
+
return this.reattaching;
|
|
10
99
|
}
|
|
11
100
|
write(data) {
|
|
12
|
-
|
|
101
|
+
this.process?.write(data);
|
|
13
102
|
}
|
|
14
|
-
resize(
|
|
15
|
-
|
|
103
|
+
resize(cols, rows) {
|
|
104
|
+
this.process?.resize(cols, rows);
|
|
16
105
|
}
|
|
17
|
-
|
|
18
|
-
|
|
106
|
+
/** Must be called AFTER spawn(). Callbacks registered before spawn are silently lost. */
|
|
107
|
+
onData(cb) {
|
|
108
|
+
this.process?.onData(cb);
|
|
19
109
|
}
|
|
20
|
-
|
|
21
|
-
|
|
110
|
+
/** Must be called AFTER spawn(). Callbacks registered before spawn are silently lost. */
|
|
111
|
+
onExit(cb) {
|
|
112
|
+
this.process?.onExit(({ exitCode, signal }) => {
|
|
113
|
+
cb(exitCode, signal !== undefined ? String(signal) : null);
|
|
114
|
+
});
|
|
22
115
|
}
|
|
116
|
+
/** Detach only — kills the pty viewer but leaves tmux session alive. */
|
|
23
117
|
kill() {
|
|
24
|
-
|
|
118
|
+
if (this.process) {
|
|
119
|
+
try {
|
|
120
|
+
this.process.kill();
|
|
121
|
+
}
|
|
122
|
+
catch { /* already dead */ }
|
|
123
|
+
this.process = null;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/** Kill the tmux session permanently. Called on explicit /close. */
|
|
127
|
+
destroySession() {
|
|
128
|
+
this.kill();
|
|
129
|
+
TmuxBackend.killSession(this.sessionName);
|
|
25
130
|
}
|
|
26
131
|
getAttachInfo() {
|
|
27
132
|
return { type: 'tmux', sessionName: this.sessionName };
|
|
28
133
|
}
|
|
29
134
|
}
|
|
135
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
136
|
+
/** Minimal shell-escape for tmux session names (alphanumeric + dash). */
|
|
137
|
+
function shellescape(s) {
|
|
138
|
+
return `'${s.replace(/'/g, "'\\''")}'`;
|
|
139
|
+
}
|
|
30
140
|
//# sourceMappingURL=tmux-backend.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tmux-backend.js","sourceRoot":"","sources":["../../../src/adapters/backend/tmux-backend.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tmux-backend.js","sourceRoot":"","sources":["../../../src/adapters/backend/tmux-backend.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,9 @@ export interface SessionBackend {
|
|
|
11
11
|
onData(cb: (data: string) => void): void;
|
|
12
12
|
onExit(cb: (code: number | null, signal: string | null) => void): void;
|
|
13
13
|
kill(): void;
|
|
14
|
+
/** Permanently destroy the backing session (e.g. kill tmux session).
|
|
15
|
+
* Called only on explicit /close. Default: same as kill(). */
|
|
16
|
+
destroySession?(): void;
|
|
14
17
|
getAttachInfo?(): {
|
|
15
18
|
type: 'tmux';
|
|
16
19
|
sessionName: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/adapters/backend/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAC1D,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IACzC,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC;IACvE,IAAI,IAAI,IAAI,CAAC;IACb,aAAa,CAAC,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAChE"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/adapters/backend/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAC1D,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IACzC,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC;IACvE,IAAI,IAAI,IAAI,CAAC;IACb;mEAC+D;IAC/D,cAAc,CAAC,IAAI,IAAI,CAAC;IACxB,aAAa,CAAC,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAChE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aiden.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/aiden.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAA6B,MAAM,YAAY,CAAC;AAMxE,wBAAgB,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"aiden.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/aiden.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAA6B,MAAM,YAAY,CAAC;AAMxE,wBAAgB,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CAuDpE;AAED,eAAO,MAAM,MAAM,2BAAqB,CAAC"}
|
|
@@ -56,6 +56,10 @@ export function createAidenAdapter(pathOverride) {
|
|
|
56
56
|
}
|
|
57
57
|
},
|
|
58
58
|
completionPattern: undefined, // quiescence only
|
|
59
|
+
systemHints: [
|
|
60
|
+
'消息可能包含 attachments,每个有 path 字段,用 Read 工具查看',
|
|
61
|
+
'不要使用 EnterPlanMode / ExitPlanMode 工具',
|
|
62
|
+
],
|
|
59
63
|
altScreen: false,
|
|
60
64
|
};
|
|
61
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aiden.js","sourceRoot":"","sources":["../../../src/adapters/cli/aiden.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"aiden.js","sourceRoot":"","sources":["../../../src/adapters/cli/aiden.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/claude-code.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAA6B,MAAM,YAAY,CAAC;AAIxE,wBAAgB,uBAAuB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/claude-code.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAA6B,MAAM,YAAY,CAAC;AAIxE,wBAAgB,uBAAuB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CAqDzE;AAED,eAAO,MAAM,MAAM,gCAA0B,CAAC"}
|
|
@@ -17,6 +17,7 @@ export function createClaudeCodeAdapter(pathOverride) {
|
|
|
17
17
|
args.push('--session-id', sessionId);
|
|
18
18
|
}
|
|
19
19
|
args.push('--dangerously-skip-permissions');
|
|
20
|
+
args.push('--disallowed-tools', 'EnterPlanMode,ExitPlanMode');
|
|
20
21
|
return args;
|
|
21
22
|
},
|
|
22
23
|
async writeInput(pty, content) {
|
|
@@ -52,6 +53,10 @@ export function createClaudeCodeAdapter(pathOverride) {
|
|
|
52
53
|
},
|
|
53
54
|
completionPattern: COMPLETION_RE,
|
|
54
55
|
readyPattern: /❯/,
|
|
56
|
+
systemHints: [
|
|
57
|
+
'消息可能包含 attachments,每个有 path 字段,用 Read 工具查看',
|
|
58
|
+
'不要使用 EnterPlanMode / ExitPlanMode 工具',
|
|
59
|
+
],
|
|
55
60
|
altScreen: false,
|
|
56
61
|
};
|
|
57
62
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/adapters/cli/claude-code.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/adapters/cli/claude-code.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coco.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/coco.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAA6B,MAAM,YAAY,CAAC;AAExE,wBAAgB,iBAAiB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"coco.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/coco.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAA6B,MAAM,YAAY,CAAC;AAExE,wBAAgB,iBAAiB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CAgDnE;AAED,eAAO,MAAM,MAAM,0BAAoB,CAAC"}
|
|
@@ -14,6 +14,7 @@ export function createCocoAdapter(pathOverride) {
|
|
|
14
14
|
args.push('--session-id', sessionId);
|
|
15
15
|
}
|
|
16
16
|
args.push('--yolo');
|
|
17
|
+
args.push('--disallowed-tool', 'EnterPlanMode', '--disallowed-tool', 'ExitPlanMode');
|
|
17
18
|
return args;
|
|
18
19
|
},
|
|
19
20
|
async writeInput(pty, content) {
|
|
@@ -39,6 +40,10 @@ export function createCocoAdapter(pathOverride) {
|
|
|
39
40
|
},
|
|
40
41
|
completionPattern: undefined,
|
|
41
42
|
readyPattern: /⏵⏵/, // status bar indicator — present when CoCo's TUI is rendered
|
|
43
|
+
systemHints: [
|
|
44
|
+
'消息可能包含 attachments,每个有 path 字段,用 Read 工具查看',
|
|
45
|
+
'不要使用 EnterPlanMode / ExitPlanMode 工具',
|
|
46
|
+
],
|
|
42
47
|
altScreen: false,
|
|
43
48
|
};
|
|
44
49
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coco.js","sourceRoot":"","sources":["../../../src/adapters/cli/coco.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,MAAM,UAAU,iBAAiB,CAAC,YAAqB;IACrD,MAAM,GAAG,GAAG,cAAc,CAAC,YAAY,IAAI,MAAM,CAAC,CAAC;IACnD,OAAO;QACL,EAAE,EAAE,MAAM;QACV,WAAW,EAAE,GAAG;QAEhB,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE;YAC7B,MAAM,IAAI,GAAa,EAAE,CAAC;YAC1B,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YACnC,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;YACvC,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,GAAc,EAAE,OAAe;YAC9C,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;QAC5B,CAAC;QAED,eAAe,CAAC,KAAqB;YACnC,2EAA2E;YAC3E,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;gBAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,GAAG,EAAE,KAAK,CAAC,GAAG;aACf,CAAC,CAAC;YACH,IAAI,CAAC;gBACH,QAAQ,CAAC,GAAG,GAAG,iBAAiB,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE;oBACpE,QAAQ,EAAE,OAAO;oBACjB,OAAO,EAAE,MAAM;oBACf,KAAK,EAAE,QAAQ;iBAChB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,OAAO,CAAC,IAAI,CAAC,oCAAoC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;QAED,iBAAiB,EAAE,SAAS;QAC5B,YAAY,EAAE,IAAI,EAAI,6DAA6D;QACnF,SAAS,EAAE,KAAK;KACjB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"coco.js","sourceRoot":"","sources":["../../../src/adapters/cli/coco.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,MAAM,UAAU,iBAAiB,CAAC,YAAqB;IACrD,MAAM,GAAG,GAAG,cAAc,CAAC,YAAY,IAAI,MAAM,CAAC,CAAC;IACnD,OAAO;QACL,EAAE,EAAE,MAAM;QACV,WAAW,EAAE,GAAG;QAEhB,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE;YAC7B,MAAM,IAAI,GAAa,EAAE,CAAC;YAC1B,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YACnC,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;YACvC,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACpB,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,eAAe,EAAE,mBAAmB,EAAE,cAAc,CAAC,CAAC;YACrF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,GAAc,EAAE,OAAe;YAC9C,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;QAC5B,CAAC;QAED,eAAe,CAAC,KAAqB;YACnC,2EAA2E;YAC3E,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;gBAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,GAAG,EAAE,KAAK,CAAC,GAAG;aACf,CAAC,CAAC;YACH,IAAI,CAAC;gBACH,QAAQ,CAAC,GAAG,GAAG,iBAAiB,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE;oBACpE,QAAQ,EAAE,OAAO;oBACjB,OAAO,EAAE,MAAM;oBACf,KAAK,EAAE,QAAQ;iBAChB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,OAAO,CAAC,IAAI,CAAC,oCAAoC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;QAED,iBAAiB,EAAE,SAAS;QAC5B,YAAY,EAAE,IAAI,EAAI,6DAA6D;QACnF,WAAW,EAAE;YACX,4CAA4C;YAC5C,sCAAsC;SACvC;QACD,SAAS,EAAE,KAAK;KACjB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,iBAAiB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/codex.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAA6B,MAAM,YAAY,CAAC;AAMxE,wBAAgB,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/codex.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAA6B,MAAM,YAAY,CAAC;AAMxE,wBAAgB,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CA6CpE;AAED,eAAO,MAAM,MAAM,2BAAqB,CAAC"}
|
|
@@ -40,6 +40,9 @@ export function createCodexAdapter(pathOverride) {
|
|
|
40
40
|
},
|
|
41
41
|
completionPattern: undefined,
|
|
42
42
|
readyPattern: /›/, // prompt indicator — present when Codex's input box is rendered
|
|
43
|
+
systemHints: [
|
|
44
|
+
'消息可能包含 attachments,每个有 path 字段,用 file_read 工具查看',
|
|
45
|
+
],
|
|
43
46
|
altScreen: false, // --no-alt-screen disables alternate screen
|
|
44
47
|
};
|
|
45
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../../src/adapters/cli/codex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,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,kBAAkB,CAAC,YAAqB;IACtD,MAAM,GAAG,GAAG,cAAc,CAAC,YAAY,IAAI,OAAO,CAAC,CAAC;IACpD,OAAO;QACL,EAAE,EAAE,OAAO;QACX,WAAW,EAAE,GAAG;QAEhB,SAAS;YACP,sEAAsE;YACtE,uEAAuE;YACvE,OAAO;gBACL,4CAA4C;gBAC5C,iBAAiB;aAClB,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,GAAc,EAAE,OAAe;YAC9C,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACnB,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;YACjB,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;QAED,eAAe,CAAC,KAAqB;YACnC,mFAAmF;YACnF,IAAI,CAAC;gBACH,QAAQ,CAAC,GAAG,GAAG,eAAe,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YACvG,CAAC;YAAC,MAAM,CAAC,CAAC,+BAA+B,CAAC,CAAC;YAE3C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC;iBACtC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;iBAClC,IAAI,CAAC,GAAG,CAAC,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,IAAI,IAAI,OAAO,OAAO,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAClG,IAAI,CAAC;gBACH,QAAQ,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YACzE,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,OAAO,CAAC,IAAI,CAAC,qCAAqC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;QAED,iBAAiB,EAAE,SAAS;QAC5B,YAAY,EAAE,GAAG,EAAG,gEAAgE;QACpF,SAAS,EAAE,KAAK,EAAI,4CAA4C;KACjE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../../src/adapters/cli/codex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,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,kBAAkB,CAAC,YAAqB;IACtD,MAAM,GAAG,GAAG,cAAc,CAAC,YAAY,IAAI,OAAO,CAAC,CAAC;IACpD,OAAO;QACL,EAAE,EAAE,OAAO;QACX,WAAW,EAAE,GAAG;QAEhB,SAAS;YACP,sEAAsE;YACtE,uEAAuE;YACvE,OAAO;gBACL,4CAA4C;gBAC5C,iBAAiB;aAClB,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,GAAc,EAAE,OAAe;YAC9C,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACnB,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;YACjB,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;QAED,eAAe,CAAC,KAAqB;YACnC,mFAAmF;YACnF,IAAI,CAAC;gBACH,QAAQ,CAAC,GAAG,GAAG,eAAe,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YACvG,CAAC;YAAC,MAAM,CAAC,CAAC,+BAA+B,CAAC,CAAC;YAE3C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC;iBACtC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;iBAClC,IAAI,CAAC,GAAG,CAAC,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,IAAI,IAAI,OAAO,OAAO,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAClG,IAAI,CAAC;gBACH,QAAQ,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YACzE,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,OAAO,CAAC,IAAI,CAAC,qCAAqC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;QAED,iBAAiB,EAAE,SAAS;QAC5B,YAAY,EAAE,GAAG,EAAG,gEAAgE;QACpF,WAAW,EAAE;YACX,iDAAiD;SAClD;QACD,SAAS,EAAE,KAAK,EAAI,4CAA4C;KACjE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,kBAAkB,CAAC"}
|
|
@@ -32,6 +32,9 @@ export interface CliAdapter {
|
|
|
32
32
|
*
|
|
33
33
|
* Examples: CoCo `⏵⏵` status bar, Codex `›` prompt indicator. */
|
|
34
34
|
readonly readyPattern?: RegExp;
|
|
35
|
+
/** CLI-specific system hints injected into the initial prompt.
|
|
36
|
+
* e.g. "use Read tool for attachments", "don't use PlanMode" */
|
|
37
|
+
readonly systemHints: string[];
|
|
35
38
|
/** Whether CLI uses alternate screen buffer */
|
|
36
39
|
readonly altScreen: boolean;
|
|
37
40
|
}
|
|
@@ -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;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B;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;uFACmF;IACnF,SAAS,CAAC,IAAI,EAAE;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,OAAO,CAAC;KACjB,GAAG,MAAM,EAAE,CAAC;IAEb;iDAC6C;IAC7C,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3D,mEAAmE;IACnE,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;IAE7C,wFAAwF;IACxF,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAEpC;;;;;sEAKkE;IAClE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAE/B,+CAA+C;IAC/C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,MAAM,KAAK,GAAG,aAAa,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,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;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B;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;uFACmF;IACnF,SAAS,CAAC,IAAI,EAAE;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,OAAO,CAAC;KACjB,GAAG,MAAM,EAAE,CAAC;IAEb;iDAC6C;IAC7C,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3D,mEAAmE;IACnE,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;IAE7C,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,+CAA+C;IAC/C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,MAAM,KAAK,GAAG,aAAa,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC"}
|
package/dist/cli.js
CHANGED
|
@@ -112,8 +112,7 @@ async function cmdSetup() {
|
|
|
112
112
|
const cliIdMap = { '1': 'claude-code', '2': 'aiden', '3': 'coco', '4': 'codex' };
|
|
113
113
|
const cliId = cliIdMap[cliChoice] ?? (cliChoice || 'claude-code');
|
|
114
114
|
const workingDir = await ask(rl, '默认工作目录 [~]: ');
|
|
115
|
-
const allowedUsers = await ask(rl, '允许的用户 (
|
|
116
|
-
const externalHost = await ask(rl, '外部 IP/域名 (终端链接用,留空=自动检测): ');
|
|
115
|
+
const allowedUsers = await ask(rl, '允许的用户 (邮箱或 open_id,逗号分隔,留空=不限制): ');
|
|
117
116
|
rl.close();
|
|
118
117
|
const lines = [
|
|
119
118
|
'# Lark (Feishu) App Credentials',
|
|
@@ -129,8 +128,6 @@ async function cmdSetup() {
|
|
|
129
128
|
];
|
|
130
129
|
if (allowedUsers)
|
|
131
130
|
lines.push(`ALLOWED_USERS=${allowedUsers}`);
|
|
132
|
-
if (externalHost)
|
|
133
|
-
lines.push(`WEB_EXTERNAL_HOST=${externalHost}`);
|
|
134
131
|
writeFileSync(ENV_FILE, lines.join('\n') + '\n');
|
|
135
132
|
console.log(`\n✅ 配置已写入: ${ENV_FILE}`);
|
|
136
133
|
console.log(`\n下一步: botmux start`);
|