botmux 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +24 -0
- package/LICENSE +21 -0
- package/README.en.md +267 -0
- package/README.md +267 -0
- package/dist/adapters/backend/pty-backend.d.ts +13 -0
- package/dist/adapters/backend/pty-backend.d.ts.map +1 -0
- package/dist/adapters/backend/pty-backend.js +39 -0
- package/dist/adapters/backend/pty-backend.js.map +1 -0
- package/dist/adapters/backend/tmux-backend.d.ts +20 -0
- package/dist/adapters/backend/tmux-backend.d.ts.map +1 -0
- package/dist/adapters/backend/tmux-backend.js +30 -0
- package/dist/adapters/backend/tmux-backend.js.map +1 -0
- package/dist/adapters/backend/types.d.ts +19 -0
- package/dist/adapters/backend/types.d.ts.map +1 -0
- package/dist/adapters/backend/types.js +2 -0
- package/dist/adapters/backend/types.js.map +1 -0
- package/dist/adapters/cli/aiden.d.ts +4 -0
- package/dist/adapters/cli/aiden.d.ts.map +1 -0
- package/dist/adapters/cli/aiden.js +63 -0
- package/dist/adapters/cli/aiden.js.map +1 -0
- package/dist/adapters/cli/claude-code.d.ts +4 -0
- package/dist/adapters/cli/claude-code.d.ts.map +1 -0
- package/dist/adapters/cli/claude-code.js +59 -0
- package/dist/adapters/cli/claude-code.js.map +1 -0
- package/dist/adapters/cli/coco.d.ts +4 -0
- package/dist/adapters/cli/coco.d.ts.map +1 -0
- package/dist/adapters/cli/coco.js +46 -0
- package/dist/adapters/cli/coco.js.map +1 -0
- package/dist/adapters/cli/codex.d.ts +4 -0
- package/dist/adapters/cli/codex.d.ts.map +1 -0
- package/dist/adapters/cli/codex.js +47 -0
- package/dist/adapters/cli/codex.js.map +1 -0
- package/dist/adapters/cli/registry.d.ts +13 -0
- package/dist/adapters/cli/registry.d.ts.map +1 -0
- package/dist/adapters/cli/registry.js +42 -0
- package/dist/adapters/cli/registry.js.map +1 -0
- package/dist/adapters/cli/types.d.ts +39 -0
- package/dist/adapters/cli/types.d.ts.map +1 -0
- package/dist/adapters/cli/types.js +2 -0
- package/dist/adapters/cli/types.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +245 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +39 -0
- package/dist/config.js.map +1 -0
- package/dist/core/command-handler.d.ts +11 -0
- package/dist/core/command-handler.d.ts.map +1 -0
- package/dist/core/command-handler.js +322 -0
- package/dist/core/command-handler.js.map +1 -0
- package/dist/core/cost-calculator.d.ts +12 -0
- package/dist/core/cost-calculator.d.ts.map +1 -0
- package/dist/core/cost-calculator.js +61 -0
- package/dist/core/cost-calculator.js.map +1 -0
- package/dist/core/scheduler.d.ts +38 -0
- package/dist/core/scheduler.d.ts.map +1 -0
- package/dist/core/scheduler.js +221 -0
- package/dist/core/scheduler.js.map +1 -0
- package/dist/core/session-manager.d.ts +13 -0
- package/dist/core/session-manager.d.ts.map +1 -0
- package/dist/core/session-manager.js +125 -0
- package/dist/core/session-manager.js.map +1 -0
- package/dist/core/types.d.ts +29 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/worker-pool.d.ts +26 -0
- package/dist/core/worker-pool.d.ts.map +1 -0
- package/dist/core/worker-pool.js +261 -0
- package/dist/core/worker-pool.js.map +1 -0
- package/dist/daemon.d.ts +3 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +344 -0
- package/dist/daemon.js.map +1 -0
- package/dist/im/lark/card-builder.d.ts +18 -0
- package/dist/im/lark/card-builder.d.ts.map +1 -0
- package/dist/im/lark/card-builder.js +194 -0
- package/dist/im/lark/card-builder.js.map +1 -0
- package/dist/im/lark/card-handler.d.ts +9 -0
- package/dist/im/lark/card-handler.d.ts.map +1 -0
- package/dist/im/lark/card-handler.js +131 -0
- package/dist/im/lark/card-handler.js.map +1 -0
- package/dist/im/lark/client.d.ts +23 -0
- package/dist/im/lark/client.d.ts.map +1 -0
- package/dist/im/lark/client.js +259 -0
- package/dist/im/lark/client.js.map +1 -0
- package/dist/im/lark/event-dispatcher.d.ts +34 -0
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -0
- package/dist/im/lark/event-dispatcher.js +195 -0
- package/dist/im/lark/event-dispatcher.js.map +1 -0
- package/dist/im/lark/message-parser.d.ts +45 -0
- package/dist/im/lark/message-parser.d.ts.map +1 -0
- package/dist/im/lark/message-parser.js +132 -0
- package/dist/im/lark/message-parser.js.map +1 -0
- package/dist/im/types.d.ts +78 -0
- package/dist/im/types.d.ts.map +1 -0
- package/dist/im/types.js +2 -0
- package/dist/im/types.js.map +1 -0
- package/dist/index-daemon.d.ts +3 -0
- package/dist/index-daemon.d.ts.map +1 -0
- package/dist/index-daemon.js +21 -0
- package/dist/index-daemon.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/scheduler.d.ts +38 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +221 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +23 -0
- package/dist/server.js.map +1 -0
- package/dist/services/lark-client.d.ts +22 -0
- package/dist/services/lark-client.d.ts.map +1 -0
- package/dist/services/lark-client.js +238 -0
- package/dist/services/lark-client.js.map +1 -0
- package/dist/services/lark-ws.d.ts +5 -0
- package/dist/services/lark-ws.d.ts.map +1 -0
- package/dist/services/lark-ws.js +79 -0
- package/dist/services/lark-ws.js.map +1 -0
- package/dist/services/message-queue.d.ts +9 -0
- package/dist/services/message-queue.d.ts.map +1 -0
- package/dist/services/message-queue.js +77 -0
- package/dist/services/message-queue.js.map +1 -0
- package/dist/services/message-router.d.ts +8 -0
- package/dist/services/message-router.d.ts.map +1 -0
- package/dist/services/message-router.js +73 -0
- package/dist/services/message-router.js.map +1 -0
- package/dist/services/project-scanner.d.ts +12 -0
- package/dist/services/project-scanner.d.ts.map +1 -0
- package/dist/services/project-scanner.js +109 -0
- package/dist/services/project-scanner.js.map +1 -0
- package/dist/services/schedule-store.d.ts +14 -0
- package/dist/services/schedule-store.d.ts.map +1 -0
- package/dist/services/schedule-store.js +89 -0
- package/dist/services/schedule-store.js.map +1 -0
- package/dist/services/session-store.d.ts +8 -0
- package/dist/services/session-store.d.ts.map +1 -0
- package/dist/services/session-store.js +93 -0
- package/dist/services/session-store.js.map +1 -0
- package/dist/tools/close-session.d.ts +22 -0
- package/dist/tools/close-session.d.ts.map +1 -0
- package/dist/tools/close-session.js +38 -0
- package/dist/tools/close-session.js.map +1 -0
- package/dist/tools/create-session.d.ts +28 -0
- package/dist/tools/create-session.d.ts.map +1 -0
- package/dist/tools/create-session.js +40 -0
- package/dist/tools/create-session.js.map +1 -0
- package/dist/tools/get-thread-messages.d.ts +26 -0
- package/dist/tools/get-thread-messages.d.ts.map +1 -0
- package/dist/tools/get-thread-messages.js +33 -0
- package/dist/tools/get-thread-messages.js.map +1 -0
- package/dist/tools/index.d.ts +9 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +10 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/react-to-message.d.ts +41 -0
- package/dist/tools/react-to-message.d.ts.map +1 -0
- package/dist/tools/react-to-message.js +30 -0
- package/dist/tools/react-to-message.js.map +1 -0
- package/dist/tools/send-to-thread.d.ts +24 -0
- package/dist/tools/send-to-thread.d.ts.map +1 -0
- package/dist/tools/send-to-thread.js +83 -0
- package/dist/tools/send-to-thread.js.map +1 -0
- package/dist/tools/wait-for-reply.d.ts +17 -0
- package/dist/tools/wait-for-reply.d.ts.map +1 -0
- package/dist/tools/wait-for-reply.js +65 -0
- package/dist/tools/wait-for-reply.js.map +1 -0
- package/dist/types.d.ts +85 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/card-builder.d.ts +16 -0
- package/dist/utils/card-builder.d.ts.map +1 -0
- package/dist/utils/card-builder.js +183 -0
- package/dist/utils/card-builder.js.map +1 -0
- package/dist/utils/idle-detector.d.ts +21 -0
- package/dist/utils/idle-detector.d.ts.map +1 -0
- package/dist/utils/idle-detector.js +95 -0
- package/dist/utils/idle-detector.js.map +1 -0
- package/dist/utils/logger.d.ts +7 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +22 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/message-parser.d.ts +45 -0
- package/dist/utils/message-parser.d.ts.map +1 -0
- package/dist/utils/message-parser.js +132 -0
- package/dist/utils/message-parser.js.map +1 -0
- package/dist/utils/terminal-renderer.d.ts +39 -0
- package/dist/utils/terminal-renderer.d.ts.map +1 -0
- package/dist/utils/terminal-renderer.js +186 -0
- package/dist/utils/terminal-renderer.js.map +1 -0
- package/dist/worker.d.ts +3 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +411 -0
- package/dist/worker.js.map +1 -0
- package/ecosystem.config.cjs +15 -0
- package/package.json +60 -0
package/.env.example
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Lark (Feishu) App Credentials — required
|
|
2
|
+
LARK_APP_ID=
|
|
3
|
+
LARK_APP_SECRET=
|
|
4
|
+
|
|
5
|
+
# Session data directory (default: ./data)
|
|
6
|
+
# SESSION_DATA_DIR=
|
|
7
|
+
|
|
8
|
+
# Daemon settings
|
|
9
|
+
# CLI_ID=claude-code # CLI adapter: claude-code, aiden, coco, codex
|
|
10
|
+
# WORKING_DIR=~ # Default working directory
|
|
11
|
+
|
|
12
|
+
# Access control (comma-separated email prefixes or Lark open_ids, empty = allow all)
|
|
13
|
+
# ALLOWED_USERS=alice,bob
|
|
14
|
+
# LARK_EMAIL_DOMAIN=example.com # Default email domain for ALLOWED_USERS prefixes
|
|
15
|
+
|
|
16
|
+
# Project scanning directory for /repo command (default: parent of WORKING_DIR)
|
|
17
|
+
# PROJECT_SCAN_DIR=
|
|
18
|
+
|
|
19
|
+
# Web terminal settings
|
|
20
|
+
# WEB_HOST=0.0.0.0 # HTTP server bind address
|
|
21
|
+
# WEB_EXTERNAL_HOST= # External hostname/IP for terminal URLs (default: auto-detect LAN IP)
|
|
22
|
+
|
|
23
|
+
# Debug logging
|
|
24
|
+
# DEBUG=1
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 botmux contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.en.md
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# botmux
|
|
2
|
+
|
|
3
|
+
[中文](README.md) | English
|
|
4
|
+
|
|
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
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **One topic = one AI coding session** — each Lark thread gets its own isolated CLI process
|
|
10
|
+
- **Multi-CLI support** — adapter architecture supports Claude Code, Aiden, CoCo, Codex, and is extensible
|
|
11
|
+
- **Live streaming cards** — real-time terminal output rendered in Feishu cards with markdown support, per-turn card lifecycle
|
|
12
|
+
- **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 and resume automatically
|
|
14
|
+
- **Scheduled tasks** — cron-based recurring prompts with natural language scheduling (Chinese supported)
|
|
15
|
+
- **Project management** — interactive repo selector, per-session working directory
|
|
16
|
+
- **MCP integration** — CLI can reply to Lark threads, read message history, and add reactions via MCP tools
|
|
17
|
+
- **Access control** — allowlist for users, token-based write access for terminals, button restrictions on cards
|
|
18
|
+
|
|
19
|
+
## Architecture
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
Lark WebSocket Events
|
|
23
|
+
|
|
|
24
|
+
Daemon (daemon.ts → core/ modules)
|
|
25
|
+
|-- im/lark/event-dispatcher: Lark event routing
|
|
26
|
+
|-- im/lark/card-handler: card interaction handling
|
|
27
|
+
|-- core/worker-pool: worker process pool management
|
|
28
|
+
|-- core/command-handler: slash command processing
|
|
29
|
+
|-- core/session-manager: session lifecycle
|
|
30
|
+
|-- core/scheduler: cron task scheduling
|
|
31
|
+
|
|
|
32
|
+
Worker (worker.ts) -- forked child process per session
|
|
33
|
+
|-- adapters/cli/*: CLI adapters (Claude Code / Aiden / CoCo / Codex)
|
|
34
|
+
|-- adapters/backend/pty-backend: pseudo-terminal management (node-pty)
|
|
35
|
+
|-- utils/idle-detector: idle detection (quiescence + spinner + completion marker)
|
|
36
|
+
|-- HTTP + WebSocket server: serves xterm.js web terminal
|
|
37
|
+
|-- Headless xterm: captures screen for streaming cards
|
|
38
|
+
|-- IPC: communicates with daemon
|
|
39
|
+
|
|
|
40
|
+
AI Coding CLI (interactive TTY mode)
|
|
41
|
+
|-- MCP Server (stdio): send_to_thread, get_thread_messages, react_to_message
|
|
42
|
+
|
|
|
43
|
+
Lark API
|
|
44
|
+
|-- Replies, reactions, card updates, DMs
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Prerequisites
|
|
48
|
+
|
|
49
|
+
- **Node.js** >= 20
|
|
50
|
+
- **AI coding CLI** installed and authenticated (`claude`, `aiden`, `coco`, or `codex` in PATH)
|
|
51
|
+
- **Lark app** with Bot and Message permissions (WebSocket event subscription)
|
|
52
|
+
|
|
53
|
+
## Installation
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npm install -g botmux
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Quick Start
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# 1. Interactive setup — creates ~/.botmux/.env
|
|
63
|
+
botmux setup
|
|
64
|
+
|
|
65
|
+
# 2. Start the daemon
|
|
66
|
+
botmux start
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The `setup` command will guide you through:
|
|
70
|
+
- Creating a Lark app (with required permissions listed)
|
|
71
|
+
- Entering App ID, App Secret, Chat ID
|
|
72
|
+
- Optional: Claude model, working directory, access control
|
|
73
|
+
|
|
74
|
+
## CLI Commands
|
|
75
|
+
|
|
76
|
+
| Command | Description |
|
|
77
|
+
|---------|-------------|
|
|
78
|
+
| `botmux setup` | Interactive first-time configuration |
|
|
79
|
+
| `botmux start` | Start daemon (PM2 managed) |
|
|
80
|
+
| `botmux stop` | Stop daemon |
|
|
81
|
+
| `botmux restart` | Restart daemon (auto-restores active sessions) |
|
|
82
|
+
| `botmux logs` | View daemon logs (`--lines N` for more) |
|
|
83
|
+
| `botmux status` | Show daemon status |
|
|
84
|
+
| `botmux upgrade` | Upgrade to latest version |
|
|
85
|
+
|
|
86
|
+
## Configuration
|
|
87
|
+
|
|
88
|
+
Configuration is stored at `~/.botmux/.env`. Run `botmux setup` to create it interactively, or edit manually:
|
|
89
|
+
|
|
90
|
+
### Required
|
|
91
|
+
|
|
92
|
+
| Variable | Description |
|
|
93
|
+
|----------|-------------|
|
|
94
|
+
| `LARK_APP_ID` | Lark app ID |
|
|
95
|
+
| `LARK_APP_SECRET` | Lark app secret |
|
|
96
|
+
|
|
97
|
+
### Optional
|
|
98
|
+
|
|
99
|
+
| Variable | Default | Description |
|
|
100
|
+
|----------|---------|-------------|
|
|
101
|
+
| `CLI_ID` | `claude-code` | CLI adapter (`claude-code`, `aiden`, `coco`, `codex`) |
|
|
102
|
+
| `CLI_PATH` | _(auto-detect by CLI_ID)_ | CLI binary path override |
|
|
103
|
+
| `BACKEND_TYPE` | `pty` | Session backend (`pty`, `tmux`) |
|
|
104
|
+
| `WORKING_DIR` | `~` | Default working directory |
|
|
105
|
+
| `ALLOWED_USERS` | _(empty = allow all)_ | Comma-separated email prefixes or Lark open_ids |
|
|
106
|
+
| `PROJECT_SCAN_DIR` | _(parent of CWD)_ | Directory to scan for git repos |
|
|
107
|
+
| `WEB_HOST` | `0.0.0.0` | HTTP server bind address |
|
|
108
|
+
| `WEB_EXTERNAL_HOST` | _(auto-detect LAN IP)_ | External hostname/IP for terminal URLs |
|
|
109
|
+
| `SESSION_DATA_DIR` | `~/.botmux/data` | Where sessions and queues are stored |
|
|
110
|
+
| `DEBUG` | _(unset)_ | Set to `1` for debug logging |
|
|
111
|
+
|
|
112
|
+
## File Locations
|
|
113
|
+
|
|
114
|
+
| Path | Description |
|
|
115
|
+
|------|-------------|
|
|
116
|
+
| `~/.botmux/.env` | Configuration |
|
|
117
|
+
| `~/.botmux/data/` | Session data, message queues |
|
|
118
|
+
| `~/.botmux/logs/` | Daemon logs |
|
|
119
|
+
|
|
120
|
+
## Usage
|
|
121
|
+
|
|
122
|
+
### Workflow
|
|
123
|
+
|
|
124
|
+
1. Send a message in your Lark topic group to create a new thread
|
|
125
|
+
2. The bot shows a repo selection card — pick a project or click "Start directly"
|
|
126
|
+
3. Claude Code spawns in the selected directory
|
|
127
|
+
4. A live streaming card appears in the thread, showing real-time terminal output with markdown rendering
|
|
128
|
+
5. Each reply creates a new streaming card for that turn; previous cards freeze at their last state
|
|
129
|
+
6. Click "🔑 Get Write Link" on the card to receive a write-enabled terminal URL via DM
|
|
130
|
+
7. Claude replies in the thread via MCP tools
|
|
131
|
+
|
|
132
|
+
### Slash Commands
|
|
133
|
+
|
|
134
|
+
| Command | Description |
|
|
135
|
+
|---------|-------------|
|
|
136
|
+
| `/repo` | Show project selector card |
|
|
137
|
+
| `/repo <N>` | Switch to Nth project from last scan |
|
|
138
|
+
| `/cd <path>` | Change working directory |
|
|
139
|
+
| `/status` | Show session info (uptime, terminal URL, etc.) |
|
|
140
|
+
| `/cost` | Show token usage and estimated cost |
|
|
141
|
+
| `/restart` | Restart Claude process |
|
|
142
|
+
| `/close` | Close session and terminate Claude |
|
|
143
|
+
| `/clear` | Clear context (new session, same thread) |
|
|
144
|
+
| `/schedule` | Manage scheduled tasks |
|
|
145
|
+
| `/help` | Show available commands |
|
|
146
|
+
|
|
147
|
+
### Scheduled Tasks
|
|
148
|
+
|
|
149
|
+
Create recurring tasks with natural language:
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
/schedule every day at 17:50 check AI news
|
|
153
|
+
/schedule weekdays at 9:00 run health check
|
|
154
|
+
/schedule every Monday at 10:00 generate weekly report
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Manage tasks:
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
/schedule list
|
|
161
|
+
/schedule remove <id>
|
|
162
|
+
/schedule enable <id>
|
|
163
|
+
/schedule disable <id>
|
|
164
|
+
/schedule run <id>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Streaming Cards
|
|
168
|
+
|
|
169
|
+
Each conversation turn gets a live-updating Feishu card that shows:
|
|
170
|
+
|
|
171
|
+
- Real-time terminal output (rendered via headless xterm + Feishu Card v2 markdown)
|
|
172
|
+
- Status indicator: 🟡 Starting → 🔵 Working → 🟢 Idle
|
|
173
|
+
- Action buttons: Open Terminal, Get Write Link, Restart Claude, Close Session
|
|
174
|
+
|
|
175
|
+
The card content is captured from a headless xterm terminal that filters out TUI chrome (logo, status bar, prompts, box-drawing characters) and shows only Claude's actual work output.
|
|
176
|
+
|
|
177
|
+
### Web Terminal
|
|
178
|
+
|
|
179
|
+
Each session exposes a web terminal at `http://<WEB_EXTERNAL_HOST>:<port>`.
|
|
180
|
+
|
|
181
|
+
- **Read-only link** — shown on the streaming card in the group thread
|
|
182
|
+
- **Write-enabled link** — sent via DM on demand (click "🔑 Get Write Link" on the card)
|
|
183
|
+
|
|
184
|
+
Features: xterm.js with fit/unicode11/web-links addons, TokyoNight theme, scrollback buffer, mobile-friendly viewport.
|
|
185
|
+
|
|
186
|
+
## MCP Tools
|
|
187
|
+
|
|
188
|
+
Claude Code has access to three MCP tools for interacting with Lark:
|
|
189
|
+
|
|
190
|
+
| Tool | Description |
|
|
191
|
+
|------|-------------|
|
|
192
|
+
| `send_to_thread` | Send a message (text or rich post) to the Lark thread |
|
|
193
|
+
| `get_thread_messages` | Retrieve message history from the thread |
|
|
194
|
+
| `react_to_message` | Add or remove emoji reactions on messages |
|
|
195
|
+
|
|
196
|
+
## Development
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
git clone <repo-url>
|
|
200
|
+
cd botmux
|
|
201
|
+
pnpm install
|
|
202
|
+
pnpm build
|
|
203
|
+
|
|
204
|
+
# Run directly (no PM2)
|
|
205
|
+
pnpm daemon
|
|
206
|
+
|
|
207
|
+
# Or with PM2
|
|
208
|
+
pnpm daemon:start
|
|
209
|
+
pnpm daemon:logs
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Project Structure
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
src/
|
|
216
|
+
cli.ts # CLI entry point (setup/start/stop/restart/logs)
|
|
217
|
+
daemon.ts # Daemon orchestrator (~400 lines, wires modules together)
|
|
218
|
+
worker.ts # Worker process: uses adapters to manage CLI + PTY
|
|
219
|
+
config.ts # Configuration from environment variables
|
|
220
|
+
server.ts # MCP server setup
|
|
221
|
+
types.ts # IPC message types
|
|
222
|
+
adapters/
|
|
223
|
+
cli/
|
|
224
|
+
types.ts # CliAdapter interface, CliId type
|
|
225
|
+
registry.ts # Adapter factory + resolveCommand
|
|
226
|
+
claude-code.ts # Claude Code adapter
|
|
227
|
+
aiden.ts # Aiden adapter
|
|
228
|
+
coco.ts # CoCo adapter
|
|
229
|
+
codex.ts # Codex adapter
|
|
230
|
+
backend/
|
|
231
|
+
types.ts # SessionBackend interface
|
|
232
|
+
pty-backend.ts # node-pty backend
|
|
233
|
+
tmux-backend.ts # tmux backend (stub)
|
|
234
|
+
core/
|
|
235
|
+
types.ts # DaemonSession core type
|
|
236
|
+
worker-pool.ts # Worker process pool management
|
|
237
|
+
command-handler.ts # Slash command processing
|
|
238
|
+
session-manager.ts # Session lifecycle + path resolution
|
|
239
|
+
cost-calculator.ts # Token usage & cost estimation
|
|
240
|
+
scheduler.ts # Cron scheduling with natural language parsing
|
|
241
|
+
im/
|
|
242
|
+
types.ts # ImAdapter interface definitions (multi-IM abstraction)
|
|
243
|
+
lark/
|
|
244
|
+
client.ts # Lark API wrapper
|
|
245
|
+
event-dispatcher.ts # Lark WebSocket event routing
|
|
246
|
+
card-handler.ts # Lark card interaction handling
|
|
247
|
+
card-builder.ts # Lark interactive card builders
|
|
248
|
+
message-parser.ts # Lark event message parsing
|
|
249
|
+
tools/
|
|
250
|
+
index.ts # MCP tool registry
|
|
251
|
+
send-to-thread.ts # MCP tool: send message
|
|
252
|
+
get-thread-messages.ts # MCP tool: read messages
|
|
253
|
+
react-to-message.ts # MCP tool: emoji reactions
|
|
254
|
+
services/
|
|
255
|
+
session-store.ts # Session persistence (JSON)
|
|
256
|
+
schedule-store.ts # Scheduled task persistence
|
|
257
|
+
message-queue.ts # Per-thread JSONL message queue
|
|
258
|
+
project-scanner.ts # Git repo/worktree discovery
|
|
259
|
+
utils/
|
|
260
|
+
idle-detector.ts # CLI idle detection (quiescence + spinner + completion marker)
|
|
261
|
+
terminal-renderer.ts # Headless xterm renderer for screen capture & TUI filtering
|
|
262
|
+
logger.ts # Logging utility
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## License
|
|
266
|
+
|
|
267
|
+
[MIT](LICENSE)
|
package/README.md
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# botmux
|
|
2
|
+
|
|
3
|
+
中文 | [English](README.en.md)
|
|
4
|
+
|
|
5
|
+
飞书话题群与 AI 编程 CLI 的桥接工具。Daemon 监听飞书消息,为每个新话题自动启动一个独立的 CLI 进程(支持 Claude Code、Aiden、CoCo、Codex),提供实时流式卡片和 Web 终端。
|
|
6
|
+
|
|
7
|
+
## 功能特性
|
|
8
|
+
|
|
9
|
+
- **一个话题 = 一个 AI 编程会话** — 每个飞书话题线程对应一个独立的 CLI 进程
|
|
10
|
+
- **多 CLI 支持** — 通过适配器架构支持 Claude Code、Aiden、CoCo、Codex,可扩展
|
|
11
|
+
- **实时流式卡片** — 终端输出实时渲染到飞书卡片中,支持 Markdown 格式,每轮对话独立卡片
|
|
12
|
+
- **Web 终端 (xterm.js)** — 浏览器查看完整 PTY 输出,按需获取可操作链接
|
|
13
|
+
- **会话持久化** — 会话在 Daemon 重启后自动恢复
|
|
14
|
+
- **定时任务** — 基于 Cron 的周期性任务,支持中文自然语言配置
|
|
15
|
+
- **项目管理** — 交互式仓库选择器,每个会话独立工作目录
|
|
16
|
+
- **MCP 集成** — CLI 可通过 MCP 工具回复飞书话题、读取消息历史、添加表情回应
|
|
17
|
+
- **权限控制** — 用户白名单、终端 Token 写入权限、卡片按钮操作限制
|
|
18
|
+
|
|
19
|
+
## 架构
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
飞书 WebSocket 事件
|
|
23
|
+
|
|
|
24
|
+
Daemon (daemon.ts → core/ 模块)
|
|
25
|
+
|-- im/lark/event-dispatcher: 飞书事件路由
|
|
26
|
+
|-- im/lark/card-handler: 卡片交互处理
|
|
27
|
+
|-- core/worker-pool: Worker 进程池管理
|
|
28
|
+
|-- core/command-handler: 斜杠命令处理
|
|
29
|
+
|-- core/session-manager: 会话生命周期
|
|
30
|
+
|-- core/scheduler: 定时任务调度
|
|
31
|
+
|
|
|
32
|
+
Worker (worker.ts) -- 每个会话 fork 一个子进程
|
|
33
|
+
|-- adapters/cli/*: CLI 适配器 (Claude Code / Aiden / CoCo / Codex)
|
|
34
|
+
|-- adapters/backend/pty-backend: 伪终端管理 (node-pty)
|
|
35
|
+
|-- utils/idle-detector: 空闲检测(静默 + Spinner + 完成标记)
|
|
36
|
+
|-- HTTP + WebSocket: 提供 xterm.js Web 终端
|
|
37
|
+
|-- Headless xterm: 捕获屏幕内容用于流式卡片
|
|
38
|
+
|-- IPC: 与 Daemon 通信
|
|
39
|
+
|
|
|
40
|
+
AI 编程 CLI (交互式 TTY 模式)
|
|
41
|
+
|-- MCP Server (stdio): send_to_thread, get_thread_messages, react_to_message
|
|
42
|
+
|
|
|
43
|
+
飞书 API
|
|
44
|
+
|-- 回复消息、表情回应、卡片更新、私聊
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 前置要求
|
|
48
|
+
|
|
49
|
+
- **Node.js** >= 20
|
|
50
|
+
- **AI 编程 CLI** 已安装并完成认证(`claude`、`aiden`、`coco` 或 `codex` 在 PATH 中)
|
|
51
|
+
- **飞书应用** 具备机器人和消息权限(WebSocket 事件订阅)
|
|
52
|
+
|
|
53
|
+
## 安装
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npm install -g botmux
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 快速开始
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# 1. 交互式配置 — 创建 ~/.botmux/.env
|
|
63
|
+
botmux setup
|
|
64
|
+
|
|
65
|
+
# 2. 启动 daemon
|
|
66
|
+
botmux start
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`setup` 命令会引导你完成:
|
|
70
|
+
- 创建飞书应用(列出所需权限)
|
|
71
|
+
- 输入 App ID、App Secret、Chat ID
|
|
72
|
+
- 可选:Claude 模型、工作目录、权限控制
|
|
73
|
+
|
|
74
|
+
## CLI 命令
|
|
75
|
+
|
|
76
|
+
| 命令 | 说明 |
|
|
77
|
+
|------|------|
|
|
78
|
+
| `botmux setup` | 交互式首次配置 |
|
|
79
|
+
| `botmux start` | 启动 daemon(PM2 管理) |
|
|
80
|
+
| `botmux stop` | 停止 daemon |
|
|
81
|
+
| `botmux restart` | 重启 daemon(自动恢复活跃会话) |
|
|
82
|
+
| `botmux logs` | 查看日志(`--lines N`) |
|
|
83
|
+
| `botmux status` | 查看 daemon 状态 |
|
|
84
|
+
| `botmux upgrade` | 升级到最新版本 |
|
|
85
|
+
|
|
86
|
+
## 配置
|
|
87
|
+
|
|
88
|
+
配置文件位于 `~/.botmux/.env`。运行 `botmux setup` 交互式创建,或手动编辑:
|
|
89
|
+
|
|
90
|
+
### 必填
|
|
91
|
+
|
|
92
|
+
| 变量 | 说明 |
|
|
93
|
+
|------|------|
|
|
94
|
+
| `LARK_APP_ID` | 飞书应用 App ID |
|
|
95
|
+
| `LARK_APP_SECRET` | 飞书应用 App Secret |
|
|
96
|
+
|
|
97
|
+
### 可选
|
|
98
|
+
|
|
99
|
+
| 变量 | 默认值 | 说明 |
|
|
100
|
+
|------|--------|------|
|
|
101
|
+
| `CLI_ID` | `claude-code` | CLI 适配器(`claude-code`、`aiden`、`coco`、`codex`) |
|
|
102
|
+
| `CLI_PATH` | _(按 CLI_ID 自动检测)_ | CLI 可执行文件路径覆盖 |
|
|
103
|
+
| `BACKEND_TYPE` | `pty` | 会话后端(`pty`、`tmux`) |
|
|
104
|
+
| `WORKING_DIR` | `~` | 默认工作目录 |
|
|
105
|
+
| `ALLOWED_USERS` | _(空 = 不限制)_ | 允许的用户,邮箱前缀或 open_id,逗号分隔 |
|
|
106
|
+
| `PROJECT_SCAN_DIR` | _(工作目录的上级)_ | 扫描 Git 仓库的目录 |
|
|
107
|
+
| `WEB_HOST` | `0.0.0.0` | HTTP 服务绑定地址 |
|
|
108
|
+
| `WEB_EXTERNAL_HOST` | _(自动检测局域网 IP)_ | 终端链接中的外部主机名/IP |
|
|
109
|
+
| `SESSION_DATA_DIR` | `~/.botmux/data` | 会话和队列的存储目录 |
|
|
110
|
+
| `DEBUG` | _(未设置)_ | 设为 `1` 启用调试日志 |
|
|
111
|
+
|
|
112
|
+
## 文件位置
|
|
113
|
+
|
|
114
|
+
| 路径 | 说明 |
|
|
115
|
+
|------|------|
|
|
116
|
+
| `~/.botmux/.env` | 配置文件 |
|
|
117
|
+
| `~/.botmux/data/` | 会话数据、消息队列 |
|
|
118
|
+
| `~/.botmux/logs/` | Daemon 日志 |
|
|
119
|
+
|
|
120
|
+
## 使用
|
|
121
|
+
|
|
122
|
+
### 使用流程
|
|
123
|
+
|
|
124
|
+
1. 在飞书话题群中发送消息创建新话题
|
|
125
|
+
2. 机器人弹出仓库选择卡片 — 选择项目或点击「直接开启会话」
|
|
126
|
+
3. Claude Code 在所选目录下启动
|
|
127
|
+
4. 话题中出现实时流式卡片,展示终端输出并支持 Markdown 渲染
|
|
128
|
+
5. 每次回复创建新的流式卡片,上一轮卡片冻结在最后状态
|
|
129
|
+
6. 点击卡片上的「🔑 获取操作链接」通过私聊获取可写终端链接
|
|
130
|
+
7. Claude 通过 MCP 工具在话题中回复
|
|
131
|
+
|
|
132
|
+
### 斜杠命令
|
|
133
|
+
|
|
134
|
+
| 命令 | 说明 |
|
|
135
|
+
|------|------|
|
|
136
|
+
| `/repo` | 显示项目选择卡片 |
|
|
137
|
+
| `/repo <N>` | 切换到上次扫描的第 N 个项目 |
|
|
138
|
+
| `/cd <路径>` | 切换工作目录 |
|
|
139
|
+
| `/status` | 查看会话信息(运行时间、终端地址等) |
|
|
140
|
+
| `/cost` | 查看 Token 用量和费用估算 |
|
|
141
|
+
| `/restart` | 重启 Claude 进程 |
|
|
142
|
+
| `/close` | 关闭会话并终止 Claude |
|
|
143
|
+
| `/clear` | 清除上下文(新会话,同一话题) |
|
|
144
|
+
| `/schedule` | 管理定时任务 |
|
|
145
|
+
| `/help` | 显示可用命令 |
|
|
146
|
+
|
|
147
|
+
### 定时任务
|
|
148
|
+
|
|
149
|
+
用自然语言创建周期性任务:
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
/schedule 每日17:50 帮我看看AI圈有什么新闻
|
|
153
|
+
/schedule 工作日每天9:00 检查服务状态
|
|
154
|
+
/schedule 每周一10:00 生成周报
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
管理任务:
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
/schedule list
|
|
161
|
+
/schedule remove <id>
|
|
162
|
+
/schedule enable <id>
|
|
163
|
+
/schedule disable <id>
|
|
164
|
+
/schedule run <id>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 流式卡片
|
|
168
|
+
|
|
169
|
+
每轮对话会生成一个实时更新的飞书卡片,展示:
|
|
170
|
+
|
|
171
|
+
- 实时终端输出(通过 headless xterm 捕获 + 飞书卡片 v2 Markdown 渲染)
|
|
172
|
+
- 状态指示:🟡 启动中 → 🔵 工作中 → 🟢 就绪
|
|
173
|
+
- 操作按钮:打开终端、获取操作链接、重启 Claude、关闭会话
|
|
174
|
+
|
|
175
|
+
卡片内容由 headless xterm 终端捕获,自动过滤 TUI 装饰(Logo、状态栏、提示符、框线字符),仅展示 Claude 的实际工作输出。
|
|
176
|
+
|
|
177
|
+
### Web 终端
|
|
178
|
+
|
|
179
|
+
每个会话提供一个 Web 终端,地址为 `http://<WEB_EXTERNAL_HOST>:<端口>`。
|
|
180
|
+
|
|
181
|
+
- **只读链接** — 展示在群话题的流式卡片上
|
|
182
|
+
- **可操作链接** — 按需获取(点击卡片上的「🔑 获取操作链接」通过私聊发送)
|
|
183
|
+
|
|
184
|
+
特性:xterm.js + fit/unicode11/web-links 插件、TokyoNight 主题、滚动缓冲区、移动端适配。
|
|
185
|
+
|
|
186
|
+
## MCP 工具
|
|
187
|
+
|
|
188
|
+
Claude Code 可使用三个 MCP 工具与飞书交互:
|
|
189
|
+
|
|
190
|
+
| 工具 | 说明 |
|
|
191
|
+
|------|------|
|
|
192
|
+
| `send_to_thread` | 向飞书话题发送消息(纯文本或富文本) |
|
|
193
|
+
| `get_thread_messages` | 获取话题的消息历史 |
|
|
194
|
+
| `react_to_message` | 添加或移除消息的表情回应 |
|
|
195
|
+
|
|
196
|
+
## 开发
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
git clone <repo-url>
|
|
200
|
+
cd botmux
|
|
201
|
+
pnpm install
|
|
202
|
+
pnpm build
|
|
203
|
+
|
|
204
|
+
# 直接运行(不经 PM2)
|
|
205
|
+
pnpm daemon
|
|
206
|
+
|
|
207
|
+
# 或使用 PM2
|
|
208
|
+
pnpm daemon:start
|
|
209
|
+
pnpm daemon:logs
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## 项目结构
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
src/
|
|
216
|
+
cli.ts # CLI 入口(setup/start/stop/restart/logs)
|
|
217
|
+
daemon.ts # Daemon 编排入口(~400 行,调用各模块)
|
|
218
|
+
worker.ts # Worker 进程:使用适配器管理 CLI + PTY
|
|
219
|
+
config.ts # 环境变量配置
|
|
220
|
+
server.ts # MCP Server
|
|
221
|
+
types.ts # IPC 消息类型
|
|
222
|
+
adapters/
|
|
223
|
+
cli/
|
|
224
|
+
types.ts # CliAdapter 接口、CliId 类型
|
|
225
|
+
registry.ts # 适配器工厂 + resolveCommand
|
|
226
|
+
claude-code.ts # Claude Code 适配器
|
|
227
|
+
aiden.ts # Aiden 适配器
|
|
228
|
+
coco.ts # CoCo 适配器
|
|
229
|
+
codex.ts # Codex 适配器
|
|
230
|
+
backend/
|
|
231
|
+
types.ts # SessionBackend 接口
|
|
232
|
+
pty-backend.ts # node-pty 后端
|
|
233
|
+
tmux-backend.ts # tmux 后端(stub)
|
|
234
|
+
core/
|
|
235
|
+
types.ts # DaemonSession 核心类型
|
|
236
|
+
worker-pool.ts # Worker 进程池管理
|
|
237
|
+
command-handler.ts # 斜杠命令处理
|
|
238
|
+
session-manager.ts # 会话生命周期 + 路径解析
|
|
239
|
+
cost-calculator.ts # Token 用量 & 费用估算
|
|
240
|
+
scheduler.ts # 定时任务调度(自然语言解析)
|
|
241
|
+
im/
|
|
242
|
+
types.ts # ImAdapter 接口定义(多 IM 抽象)
|
|
243
|
+
lark/
|
|
244
|
+
client.ts # 飞书 API 封装
|
|
245
|
+
event-dispatcher.ts # 飞书 WebSocket 事件路由
|
|
246
|
+
card-handler.ts # 飞书卡片交互处理
|
|
247
|
+
card-builder.ts # 飞书交互卡片构建
|
|
248
|
+
message-parser.ts # 飞书事件消息解析
|
|
249
|
+
tools/
|
|
250
|
+
index.ts # MCP 工具注册表
|
|
251
|
+
send-to-thread.ts # MCP 工具:发送消息
|
|
252
|
+
get-thread-messages.ts # MCP 工具:读取消息
|
|
253
|
+
react-to-message.ts # MCP 工具:表情回应
|
|
254
|
+
services/
|
|
255
|
+
session-store.ts # 会话持久化 (JSON)
|
|
256
|
+
schedule-store.ts # 定时任务持久化
|
|
257
|
+
message-queue.ts # 话题消息队列 (JSONL)
|
|
258
|
+
project-scanner.ts # Git 仓库/Worktree 扫描
|
|
259
|
+
utils/
|
|
260
|
+
idle-detector.ts # CLI 空闲检测(静默 + Spinner + 完成标记)
|
|
261
|
+
terminal-renderer.ts # Headless xterm 渲染器(屏幕捕获 & TUI 过滤)
|
|
262
|
+
logger.ts # 日志工具
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## 许可证
|
|
266
|
+
|
|
267
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { SessionBackend, SpawnOpts } from './types.js';
|
|
2
|
+
export declare class PtyBackend implements SessionBackend {
|
|
3
|
+
private process;
|
|
4
|
+
spawn(bin: string, args: string[], opts: SpawnOpts): void;
|
|
5
|
+
write(data: string): void;
|
|
6
|
+
resize(cols: number, rows: number): void;
|
|
7
|
+
/** Must be called AFTER spawn(). Callbacks registered before spawn are silently lost. */
|
|
8
|
+
onData(cb: (data: string) => void): void;
|
|
9
|
+
/** Must be called AFTER spawn(). Callbacks registered before spawn are silently lost. */
|
|
10
|
+
onExit(cb: (code: number | null, signal: string | null) => void): void;
|
|
11
|
+
kill(): void;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=pty-backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pty-backend.d.ts","sourceRoot":"","sources":["../../../src/adapters/backend/pty-backend.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5D,qBAAa,UAAW,YAAW,cAAc;IAC/C,OAAO,CAAC,OAAO,CAAyB;IAExC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAUzD,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,IAAI,IAAI,IAAI;CAMb"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as pty from 'node-pty';
|
|
2
|
+
export class PtyBackend {
|
|
3
|
+
process = null;
|
|
4
|
+
spawn(bin, args, opts) {
|
|
5
|
+
this.process = pty.spawn(bin, args, {
|
|
6
|
+
name: 'xterm-256color',
|
|
7
|
+
cols: opts.cols,
|
|
8
|
+
rows: opts.rows,
|
|
9
|
+
cwd: opts.cwd,
|
|
10
|
+
env: opts.env,
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
write(data) {
|
|
14
|
+
this.process?.write(data);
|
|
15
|
+
}
|
|
16
|
+
resize(cols, rows) {
|
|
17
|
+
this.process?.resize(cols, rows);
|
|
18
|
+
}
|
|
19
|
+
/** Must be called AFTER spawn(). Callbacks registered before spawn are silently lost. */
|
|
20
|
+
onData(cb) {
|
|
21
|
+
this.process?.onData(cb);
|
|
22
|
+
}
|
|
23
|
+
/** Must be called AFTER spawn(). Callbacks registered before spawn are silently lost. */
|
|
24
|
+
onExit(cb) {
|
|
25
|
+
this.process?.onExit(({ exitCode, signal }) => {
|
|
26
|
+
cb(exitCode, signal !== undefined ? String(signal) : null);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
kill() {
|
|
30
|
+
if (this.process) {
|
|
31
|
+
try {
|
|
32
|
+
this.process.kill();
|
|
33
|
+
}
|
|
34
|
+
catch { /* already dead */ }
|
|
35
|
+
this.process = null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=pty-backend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pty-backend.js","sourceRoot":"","sources":["../../../src/adapters/backend/pty-backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAGhC,MAAM,OAAO,UAAU;IACb,OAAO,GAAoB,IAAI,CAAC;IAExC,KAAK,CAAC,GAAW,EAAE,IAAc,EAAE,IAAe;QAChD,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE;YAClC,IAAI,EAAE,gBAAgB;YACtB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,GAAG,EAAE,IAAI,CAAC,GAAG;SACd,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAY;QAChB,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,IAAY;QAC/B,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACnC,CAAC;IAED,yFAAyF;IACzF,MAAM,CAAC,EAA0B;QAC/B,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;IAED,yFAAyF;IACzF,MAAM,CAAC,EAAwD;QAC7D,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE;YAC5C,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC;gBAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;YACzD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { SessionBackend, SpawnOpts } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* TmuxBackend — experimental session backend using tmux.
|
|
4
|
+
* Enables: physical `tmux attach`, web terminal, and IM all on same session.
|
|
5
|
+
* TODO: Full implementation.
|
|
6
|
+
*/
|
|
7
|
+
export declare class TmuxBackend implements SessionBackend {
|
|
8
|
+
private sessionName;
|
|
9
|
+
spawn(bin: string, args: string[], opts: SpawnOpts): void;
|
|
10
|
+
write(data: string): void;
|
|
11
|
+
resize(_cols: number, _rows: number): void;
|
|
12
|
+
onData(_cb: (data: string) => void): void;
|
|
13
|
+
onExit(_cb: (code: number | null, signal: string | null) => void): void;
|
|
14
|
+
kill(): void;
|
|
15
|
+
getAttachInfo(): {
|
|
16
|
+
type: "tmux";
|
|
17
|
+
sessionName: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=tmux-backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tmux-backend.d.ts","sourceRoot":"","sources":["../../../src/adapters/backend/tmux-backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5D;;;;GAIG;AACH,qBAAa,WAAY,YAAW,cAAc;IAChD,OAAO,CAAC,WAAW,CAAM;IAEzB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAIzD,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIzB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAI1C,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIzC,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI;IAIvE,IAAI,IAAI,IAAI;IAIZ,aAAa;;;;CAGd"}
|