botmux 2.31.1 → 2.32.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/README.en.md +69 -18
- package/README.md +70 -19
- package/dist/adapters/cli/antigravity.d.ts +4 -0
- package/dist/adapters/cli/antigravity.d.ts.map +1 -0
- package/dist/adapters/cli/antigravity.js +264 -0
- package/dist/adapters/cli/antigravity.js.map +1 -0
- package/dist/adapters/cli/registry.d.ts +2 -1
- package/dist/adapters/cli/registry.d.ts.map +1 -1
- package/dist/adapters/cli/registry.js +3 -1
- package/dist/adapters/cli/registry.js.map +1 -1
- package/dist/adapters/cli/types.d.ts +1 -1
- package/dist/adapters/cli/types.d.ts.map +1 -1
- package/dist/cli.js +73 -8
- package/dist/cli.js.map +1 -1
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +23 -2
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +5 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +27 -0
- package/dist/daemon.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +1 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +1 -0
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-builder.d.ts.map +1 -1
- package/dist/im/lark/card-builder.js +1 -0
- package/dist/im/lark/card-builder.js.map +1 -1
- package/dist/im/lark/client.d.ts +23 -0
- package/dist/im/lark/client.d.ts.map +1 -1
- package/dist/im/lark/client.js +30 -0
- package/dist/im/lark/client.js.map +1 -1
- package/dist/setup/bot-config-editor.d.ts +1 -1
- package/dist/setup/bot-config-editor.d.ts.map +1 -1
- package/dist/setup/bot-config-editor.js +3 -2
- package/dist/setup/bot-config-editor.js.map +1 -1
- package/dist/skills/definitions.d.ts.map +1 -1
- package/dist/skills/definitions.js +19 -4
- package/dist/skills/definitions.js.map +1 -1
- package/dist/utils/working-dir.d.ts +11 -0
- package/dist/utils/working-dir.d.ts.map +1 -0
- package/dist/utils/working-dir.js +45 -0
- package/dist/utils/working-dir.js.map +1 -0
- package/dist/worker.js +1 -1
- package/dist/worker.js.map +1 -1
- package/package.json +2 -1
package/README.en.md
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
|
|
40
40
|
### Design Philosophy
|
|
41
41
|
|
|
42
|
-
Core philosophy: **Bridge CLIs, don't rebuild them**. botmux doesn't reimplement Agent capabilities — it bridges existing AI coding CLIs (Claude Code, Codex, Cursor, Gemini, OpenCode) directly. Memory, context management, tool use, permission systems — these capabilities are evolving rapidly within the CLIs themselves. botmux rides on top of that evolution rather than rebuilding in parallel. Every CLI upgrade benefits botmux automatically with zero adaptation.
|
|
42
|
+
Core philosophy: **Bridge CLIs, don't rebuild them**. botmux doesn't reimplement Agent capabilities — it bridges existing AI coding CLIs (Claude Code, Codex, Cursor, Gemini, OpenCode, Antigravity) directly. Memory, context management, tool use, permission systems — these capabilities are evolving rapidly within the CLIs themselves. botmux rides on top of that evolution rather than rebuilding in parallel. Every CLI upgrade benefits botmux automatically with zero adaptation.
|
|
43
43
|
|
|
44
44
|
### Key Advantages
|
|
45
45
|
|
|
@@ -51,7 +51,7 @@ Compared to OpenClaw-style approaches built on Agent SDKs:
|
|
|
51
51
|
| CLI Capabilities | Full runtime (hooks, memory, plan mode, skills, `/` commands) | SDK API subset, missing features must be reimplemented |
|
|
52
52
|
| CLI Upgrades | Zero-adaptation automatic benefit | Must track SDK version changes |
|
|
53
53
|
| Memory / Context | Reuses CLI's built-in memory system, improves as the CLI evolves | Must build custom memory system, duplicating CLI-native capabilities |
|
|
54
|
-
| Multi-CLI Support |
|
|
54
|
+
| Multi-CLI Support | 6 CLIs, switch with one config (Claude Code / Codex / Cursor / Gemini / OpenCode / Antigravity) | Tied to a single SDK, cannot switch CLIs |
|
|
55
55
|
| Web Terminal | Interactive full terminal, mobile shortcut toolbar, phone/desktop/Lark tri-screen sync | Usually web chat UI or read-only output |
|
|
56
56
|
| Multi-Bot Collaboration | Multiple bots in same group via @mention routing, isolated processes, different CLIs sparring | Usually single bot |
|
|
57
57
|
| Terminal Access | tmux attach directly into the CLI process, same as local dev experience | No direct terminal access |
|
|
@@ -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`, or `
|
|
65
|
+
- **AI coding CLI** installed and authenticated (`claude`, `codex`, `cursor-agent`, `gemini`, `opencode`, 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
|
|
@@ -196,7 +196,7 @@ On mobile/tablet, a floating shortcut toolbar provides Esc, Ctrl+C, Tab, arrow k
|
|
|
196
196
|
|
|
197
197
|
### Multi-Bot Collaboration
|
|
198
198
|
|
|
199
|
-
Run multiple Lark bots on a single machine, each mapped to a different CLI. In the same group chat, messages are routed via @mention — each bot gets its own isolated CLI process. With a single bot in the group, it responds automatically without @. In a regular (non-topic) group, `@<bot1> @<bot2> /t xxx` spawns one independent thread per mentioned bot anchored at the same message.
|
|
199
|
+
Run multiple Lark bots on a single machine, each mapped to a different CLI. In the same group chat, messages are routed via @mention — each bot gets its own isolated CLI process. With a single bot in the group, it responds automatically without @. In a regular (non-topic) group, `@<bot1> @<bot2> /t xxx` spawns one independent thread per mentioned bot anchored at the same message. Send `@<bot1> @<bot2> /introduce` once so they register each other's open_id; afterwards each bot can explicitly @-mention the others from within its own session (see [§ Slash Commands](#slash-commands)).
|
|
200
200
|
|
|
201
201
|
### Tmux Persistence
|
|
202
202
|
|
|
@@ -267,7 +267,7 @@ Anthropic's official Telegram channel — which exposes each action as an
|
|
|
267
267
|
MCP tool — the Skill + CLI combo skips the MCP handshake on every CLI
|
|
268
268
|
launch, doesn't burn tool-list tokens, and works across every CLI that
|
|
269
269
|
can read a system prompt and shell out (Claude Code / Codex / Cursor /
|
|
270
|
-
Gemini / OpenCode), with no MCP protocol support required.
|
|
270
|
+
Gemini / OpenCode / Antigravity), with no MCP protocol support required.
|
|
271
271
|
|
|
272
272
|
### Dashboard
|
|
273
273
|
|
|
@@ -295,25 +295,76 @@ Gemini / OpenCode), with no MCP protocol support required.
|
|
|
295
295
|
|
|
296
296
|
### Slash Commands
|
|
297
297
|
|
|
298
|
+
Send these straight into a topic — the daemon intercepts them (no clash with the underlying CLI's own slash commands: any `/xxx` botmux doesn't recognize is forwarded verbatim to the CLI). Send `/help` anytime to see the same list inside the topic.
|
|
299
|
+
|
|
300
|
+
**📌 Session management**
|
|
301
|
+
|
|
298
302
|
| Command | Description |
|
|
299
303
|
|---------|-------------|
|
|
300
|
-
| `/repo` | Show project selector card |
|
|
304
|
+
| `/repo` | Show project selector card (interactive dropdown + text list) |
|
|
301
305
|
| `/repo <N>` | Switch to Nth project from last scan |
|
|
302
|
-
| `/skip` | Skip repo
|
|
303
|
-
| `/cd <path>` | Change working directory |
|
|
306
|
+
| `/skip` | Skip the repo selector card, start the session in the default dir |
|
|
307
|
+
| `/cd <path>` | Change working directory and restart the CLI process |
|
|
304
308
|
| `/status` | Show session info (uptime, terminal URL, etc.) |
|
|
305
|
-
| `/restart` | Restart CLI process |
|
|
309
|
+
| `/restart` | Restart CLI process (keeps the session context) |
|
|
306
310
|
| `/close` | Close session and send a resumable card (with the CLI's native resume command) |
|
|
307
311
|
| `/t <prompt>` / `/topic <prompt>` | Force-open a new topic from a non-topic group (shows the repo selector); empty prompt is allowed — fill it in after picking the repo |
|
|
312
|
+
|
|
313
|
+
**🔀 Forwarded to the underlying CLI**
|
|
314
|
+
|
|
315
|
+
| Command | Description |
|
|
316
|
+
|---------|-------------|
|
|
317
|
+
| `/compact` `/model` `/clear` `/plugin` `/usage` `/code-review` `/security-review` `/review` | Sent verbatim to the underlying CLI for its own built-in slash commands (e.g. Claude Code's `/compact`) |
|
|
318
|
+
|
|
319
|
+
**⏰ Scheduled tasks** (syntax & examples in [§ Scheduled Task Management](#scheduled-task-management))
|
|
320
|
+
|
|
321
|
+
| Command | Description |
|
|
322
|
+
|---------|-------------|
|
|
323
|
+
| `/schedule <natural language / cron>` | Create a task, e.g. `/schedule 每日17:50 check AI news` |
|
|
324
|
+
| `/schedule list` | List all scheduled tasks |
|
|
325
|
+
| `/schedule remove\|enable\|disable\|run <id>` | Remove / enable / disable / run once |
|
|
326
|
+
|
|
327
|
+
**📡 Session adoption**
|
|
328
|
+
|
|
329
|
+
| Command | Description |
|
|
330
|
+
|---------|-------------|
|
|
331
|
+
| `/adopt` | Scan local tmux and pop a card to adopt a running CLI session |
|
|
332
|
+
| `/adopt <tmux_pane>` | Adopt a specific tmux pane directly (e.g. `/adopt 0:2.0`) |
|
|
333
|
+
|
|
334
|
+
**🔐 User authorization**
|
|
335
|
+
|
|
336
|
+
| Command | Description |
|
|
337
|
+
|---------|-------------|
|
|
338
|
+
| `/login` | Lark user OAuth — afterwards you can download third-party card images and call cloud-doc/calendar APIs as yourself |
|
|
339
|
+
| `/login status` | Show current OAuth status |
|
|
340
|
+
|
|
341
|
+
**🛎️ Oncall mode (group chats)**
|
|
342
|
+
|
|
343
|
+
| Command | Description |
|
|
344
|
+
|---------|-------------|
|
|
308
345
|
| `/oncall bind <path>` | Bind current chat to a project dir, skip the repo card (any group member can @ the bot; buttons / daemon commands still gated by `allowedUsers`) |
|
|
309
|
-
| `/oncall unbind`
|
|
310
|
-
| `/
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
|
315
|
-
|
|
316
|
-
|
|
|
346
|
+
| `/oncall unbind` | Unbind the current chat |
|
|
347
|
+
| `/oncall status` | Inspect the current chat's oncall binding |
|
|
348
|
+
|
|
349
|
+
**🔑 Access grants (owner only)**
|
|
350
|
+
|
|
351
|
+
| Command | Description |
|
|
352
|
+
|---------|-------------|
|
|
353
|
+
| `@bot /grant @someone` | Pop an authorization card to add the user to the "this chat" or "global" allowlist; also auto-pops (and @s the owner) when an unauthorized user @-mentions the bot |
|
|
354
|
+
| `@bot /revoke @someone` | Revoke the user's this-chat + global access |
|
|
355
|
+
|
|
356
|
+
**👥 Multi-bot collaboration**
|
|
357
|
+
|
|
358
|
+
| Command | Description |
|
|
359
|
+
|---------|-------------|
|
|
360
|
+
| `@botA @botB /t <prompt>` | With multiple bots, each @-mentioned bot opens its own independent topic from the same message |
|
|
361
|
+
| `@botA @botB /introduce` | Bots register each other's open_id so they can later explicitly @-mention one another across sessions (any @ order, extra text allowed) |
|
|
362
|
+
|
|
363
|
+
**❓ Help**
|
|
364
|
+
|
|
365
|
+
| Command | Description |
|
|
366
|
+
|---------|-------------|
|
|
367
|
+
| `/help` | Show the full command list above, inside the topic |
|
|
317
368
|
|
|
318
369
|
### Scheduled Task Management
|
|
319
370
|
|
|
@@ -380,7 +431,7 @@ When `~/.botmux/bots.json` already exists, `botmux setup` can add a bot, reconfi
|
|
|
380
431
|
| `larkAppId` | Yes | Lark app ID |
|
|
381
432
|
| `larkAppSecret` | Yes | Lark app secret |
|
|
382
433
|
| `name` | No | Process name suffix shown by `botmux status`; e.g. `claude-main` appears as `botmux-claude-main`, defaults to `botmux-<index>` |
|
|
383
|
-
| `cliId` | No | CLI adapter, defaults to `claude-code` (options: `aiden`, `coco`, `codex`, `cursor`, `gemini`, `opencode`) |
|
|
434
|
+
| `cliId` | No | CLI adapter, defaults to `claude-code` (options: `aiden`, `coco`, `codex`, `cursor`, `gemini`, `opencode`, `antigravity`) |
|
|
384
435
|
| `cliPathOverride` | No | Absolute path to the CLI entry, for wrappers / routers; typical use: `ccr`, `claude-w`, `aiden-x-claude`, etc. |
|
|
385
436
|
| `backendType` | No | Session backend: `pty` or `tmux` (auto-detected by default) |
|
|
386
437
|
| `workingDir` | No | Default working directory, supports comma-separated |
|
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
---
|
|
23
23
|
|
|
24
|
-
**飞书话题群 + AI 编程 CLI,一条消息启动编程会话。** Daemon 监听飞书消息,为每个新话题自动启动独立 CLI 进程(Claude Code / Codex / Cursor / Gemini / OpenCode),提供实时流式卡片和可交互 Web 终端。
|
|
24
|
+
**飞书话题群 + AI 编程 CLI,一条消息启动编程会话。** Daemon 监听飞书消息,为每个新话题自动启动独立 CLI 进程(Claude Code / Codex / Cursor / Gemini / OpenCode / Antigravity),提供实时流式卡片和可交互 Web 终端。
|
|
25
25
|
|
|
26
26
|
## 演示
|
|
27
27
|
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
|
|
44
44
|
**不做 SDK wrapper,直接桥接 CLI。**
|
|
45
45
|
|
|
46
|
-
botmux 不重新实现 Agent 能力,而是直接桥接已有的 AI 编程 CLI(Claude Code、Codex、Cursor、Gemini、OpenCode)。记忆、上下文管理、工具调用、权限体系——这些能力 CLI 本身都在快速迭代,botmux 选择站在这个进化之上,而不是平行重造一套。CLI 的每次升级,botmux 零适配自动受益。
|
|
46
|
+
botmux 不重新实现 Agent 能力,而是直接桥接已有的 AI 编程 CLI(Claude Code、Codex、Cursor、Gemini、OpenCode、Antigravity)。记忆、上下文管理、工具调用、权限体系——这些能力 CLI 本身都在快速迭代,botmux 选择站在这个进化之上,而不是平行重造一套。CLI 的每次升级,botmux 零适配自动受益。
|
|
47
47
|
|
|
48
48
|
### 核心优势
|
|
49
49
|
|
|
@@ -55,7 +55,7 @@ botmux 不重新实现 Agent 能力,而是直接桥接已有的 AI 编程 CLI
|
|
|
55
55
|
| CLI 能力 | 完整运行时(hooks、memory、plan mode、Skill、`/` 命令) | SDK API 子集,需手动实现缺失功能 |
|
|
56
56
|
| CLI 升级 | 零适配自动受益 | 需要跟进 SDK 版本变更 |
|
|
57
57
|
| 记忆 / 上下文 | 直接复用 CLI 内建的记忆系统,随 CLI 迭代自动增强 | 需自建记忆系统,与 CLI 原生能力重复 |
|
|
58
|
-
| 多 CLI 支持 |
|
|
58
|
+
| 多 CLI 支持 | 6 种 CLI 一键切换(Claude Code / Codex / Cursor / Gemini / OpenCode / Antigravity) | 绑定单一 SDK,无法切换 CLI |
|
|
59
59
|
| Web 终端 | 可交互的完整终端,移动端快捷键工具栏,手机/电脑/飞书三端同步 | 通常仅 Web 聊天界面或只读输出 |
|
|
60
60
|
| 多机器人协作 | 多 bot 同群 @mention 路由,独立进程隔离,不同 CLI 赛博斗蛐蛐 | 通常单机器人 |
|
|
61
61
|
| 终端直连 | tmux attach 直接进入 CLI 进程,和本地开发体验一致 | 无法直接操作底层终端 |
|
|
@@ -84,7 +84,7 @@ botmux 不重新实现 Agent 能力,而是直接桥接已有的 AI 编程 CLI
|
|
|
84
84
|
|
|
85
85
|
### 多机器人协作
|
|
86
86
|
|
|
87
|
-
同一台机器上可运行多个飞书机器人,每个机器人可对应不同的 CLI。同一群聊中通过 @mention 路由消息,仅有一个机器人时无需 @ 自动响应;多机器人时 `@<bot1> @<bot2> /t xxx` 可让每个被 @
|
|
87
|
+
同一台机器上可运行多个飞书机器人,每个机器人可对应不同的 CLI。同一群聊中通过 @mention 路由消息,仅有一个机器人时无需 @ 自动响应;多机器人时 `@<bot1> @<bot2> /t xxx` 可让每个被 @ 的机器人在同一条消息上各自独立开新话题。先发一次 `@<bot1> @<bot2> /introduce` 让它们互相登记 open_id,之后各 bot 就能在自己的会话里显式 @mention 对方协作(见 [§ 斜杠命令](#斜杠命令))。
|
|
88
88
|
|
|
89
89
|
### Tmux 会话常驻
|
|
90
90
|
|
|
@@ -147,7 +147,7 @@ CLI 进入 botmux 会话时自动获得 `~/.botmux/bin` 在 PATH 中,以及一
|
|
|
147
147
|
- `botmux bots list` — 查询当前群聊的机器人及 open_id
|
|
148
148
|
- `botmux schedule` — 增删改查定时任务
|
|
149
149
|
|
|
150
|
-
这些能力通过 `--append-system-prompt` 注入和 Skill 描述自动引导 agent 使用。Skill + CLI 的组合相比 Anthropic 官方 Telegram channel 那套 MCP 方案:CLI 启动不用做 MCP 握手、不占用工具列表 token,且对 Claude Code / Codex / Cursor / Gemini / OpenCode 通用 —— 只要 CLI 能读 system prompt 跑 shell 命令就行,不依赖任何 MCP 协议支持。
|
|
150
|
+
这些能力通过 `--append-system-prompt` 注入和 Skill 描述自动引导 agent 使用。Skill + CLI 的组合相比 Anthropic 官方 Telegram channel 那套 MCP 方案:CLI 启动不用做 MCP 握手、不占用工具列表 token,且对 Claude Code / Codex / Cursor / Gemini / OpenCode / Antigravity 通用 —— 只要 CLI 能读 system prompt 跑 shell 命令就行,不依赖任何 MCP 协议支持。
|
|
151
151
|
|
|
152
152
|
### Dashboard 管控面
|
|
153
153
|
|
|
@@ -164,7 +164,7 @@ CLI 进入 botmux 会话时自动获得 `~/.botmux/bin` 在 PATH 中,以及一
|
|
|
164
164
|
## 前置要求
|
|
165
165
|
|
|
166
166
|
- **Node.js** >= 20
|
|
167
|
-
- **AI 编程 CLI** 已安装并完成认证(`claude`、`codex`、`cursor-agent`、`gemini` 或 `
|
|
167
|
+
- **AI 编程 CLI** 已安装并完成认证(`claude`、`codex`、`cursor-agent`、`gemini`、`opencode` 或 `agy`(Antigravity)在 PATH 中)
|
|
168
168
|
- **tmux** >= 3.x(可选,安装后自动启用会话常驻)
|
|
169
169
|
- **CJK 字体**(用于截图渲染中文/emoji):
|
|
170
170
|
- macOS 自带 PingFang/Hiragino,无需配置
|
|
@@ -289,25 +289,76 @@ botmux autostart enable
|
|
|
289
289
|
|
|
290
290
|
### 斜杠命令
|
|
291
291
|
|
|
292
|
+
在话题里直接发这些命令即可,由 daemon 拦截处理(与底层 CLI 自身的 slash 命令互不冲突——botmux 不认识的 `/xxx` 会原样透传给 CLI)。随时发 `/help` 可在话题内查看同一份清单。
|
|
293
|
+
|
|
294
|
+
**📌 会话管理**
|
|
295
|
+
|
|
292
296
|
| 命令 | 说明 |
|
|
293
297
|
|------|------|
|
|
294
|
-
| `/repo` |
|
|
298
|
+
| `/repo` | 显示项目选择卡片(交互式下拉 + 文本列表) |
|
|
295
299
|
| `/repo <N>` | 切换到上次扫描的第 N 个项目 |
|
|
296
|
-
| `/skip` |
|
|
297
|
-
| `/cd <路径>` |
|
|
300
|
+
| `/skip` | 跳过仓库选择卡片,直接用默认目录开启会话 |
|
|
301
|
+
| `/cd <路径>` | 切换工作目录并重启 CLI 进程 |
|
|
298
302
|
| `/status` | 查看会话信息(运行时间、终端地址等) |
|
|
299
|
-
| `/restart` | 重启 CLI
|
|
303
|
+
| `/restart` | 重启 CLI 进程(保留 session 上下文) |
|
|
300
304
|
| `/close` | 关闭会话并发送可恢复卡片(含 CLI 自身 resume 命令) |
|
|
301
305
|
| `/t <prompt>` / `/topic <prompt>` | 普通群内强制开新话题(弹仓库选择卡片);prompt 留空时也可在选完仓库后再补 |
|
|
306
|
+
|
|
307
|
+
**🔀 透传给底层 CLI**
|
|
308
|
+
|
|
309
|
+
| 命令 | 说明 |
|
|
310
|
+
|------|------|
|
|
311
|
+
| `/compact` `/model` `/clear` `/plugin` `/usage` `/code-review` `/security-review` `/review` | 字面送达底层 CLI,交给它的内置 slash 命令处理(例如 Claude Code 的 `/compact`) |
|
|
312
|
+
|
|
313
|
+
**⏰ 定时任务**(语法与示例详见 [§ 定时任务管理](#定时任务管理))
|
|
314
|
+
|
|
315
|
+
| 命令 | 说明 |
|
|
316
|
+
|------|------|
|
|
317
|
+
| `/schedule <自然语言/cron>` | 创建定时任务,如 `/schedule 每日17:50 看AI新闻` |
|
|
318
|
+
| `/schedule list` | 查看所有定时任务 |
|
|
319
|
+
| `/schedule remove\|enable\|disable\|run <id>` | 删除 / 启用 / 禁用 / 立即执行一次 |
|
|
320
|
+
|
|
321
|
+
**📡 会话接入**
|
|
322
|
+
|
|
323
|
+
| 命令 | 说明 |
|
|
324
|
+
|------|------|
|
|
325
|
+
| `/adopt` | 扫描本机 tmux,弹卡片选择要接入的已运行 CLI 会话 |
|
|
326
|
+
| `/adopt <tmux_pane>` | 直接接入指定 tmux pane(如 `/adopt 0:2.0`) |
|
|
327
|
+
|
|
328
|
+
**🔐 用户授权**
|
|
329
|
+
|
|
330
|
+
| 命令 | 说明 |
|
|
331
|
+
|------|------|
|
|
332
|
+
| `/login` | 飞书用户授权,授权后可下载第三方卡片图片、以你的身份调云文档/日历等 API |
|
|
333
|
+
| `/login status` | 查看当前授权状态 |
|
|
334
|
+
|
|
335
|
+
**🛎️ Oncall 模式(群聊)**
|
|
336
|
+
|
|
337
|
+
| 命令 | 说明 |
|
|
338
|
+
|------|------|
|
|
302
339
|
| `/oncall bind <path>` | 将当前群绑定到项目目录,跳过仓库选择卡片(群内任何成员可 @ 提问,按钮/命令仍走 `allowedUsers`) |
|
|
303
|
-
| `/oncall unbind`
|
|
304
|
-
| `/
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
|
309
|
-
|
|
310
|
-
|
|
|
340
|
+
| `/oncall unbind` | 解绑当前群 |
|
|
341
|
+
| `/oncall status` | 查看当前群的 oncall 绑定 |
|
|
342
|
+
|
|
343
|
+
**🔑 使用授权(owner 专用)**
|
|
344
|
+
|
|
345
|
+
| 命令 | 说明 |
|
|
346
|
+
|------|------|
|
|
347
|
+
| `@机器人 /grant @某人` | 弹授权卡片,把对方加进「本群使用」或「全局」白名单;无权限者 @ 机器人时也会自动弹这张卡并 @owner |
|
|
348
|
+
| `@机器人 /revoke @某人` | 撤销对方的本群 + 全局授权 |
|
|
349
|
+
|
|
350
|
+
**👥 多机器人协作**
|
|
351
|
+
|
|
352
|
+
| 命令 | 说明 |
|
|
353
|
+
|------|------|
|
|
354
|
+
| `@botA @botB /t <prompt>` | 多机器人时,让每个被 @ 的机器人在同一条消息上各自独立开新话题 |
|
|
355
|
+
| `@botA @botB /introduce` | 互相登记彼此的 open_id,便于后续跨 bot 显式 @mention 协作(@ 顺序任意,可带额外文本) |
|
|
356
|
+
|
|
357
|
+
**❓ 帮助**
|
|
358
|
+
|
|
359
|
+
| 命令 | 说明 |
|
|
360
|
+
|------|------|
|
|
361
|
+
| `/help` | 在话题内显示以上完整命令清单 |
|
|
311
362
|
|
|
312
363
|
### 定时任务管理
|
|
313
364
|
|
|
@@ -451,7 +502,7 @@ botmux setup
|
|
|
451
502
|
| `larkAppId` | 是 | 飞书应用 App ID |
|
|
452
503
|
| `larkAppSecret` | 是 | 飞书应用 App Secret |
|
|
453
504
|
| `name` | 否 | `botmux status` 中的进程名后缀;例如 `claude-main` 会显示为 `botmux-claude-main`,留空默认 `botmux-<序号>` |
|
|
454
|
-
| `cliId` | 否 | CLI 适配器,默认 `claude-code`(可选:`aiden`、`coco`、`codex`、`cursor`、`gemini`、`opencode`) |
|
|
505
|
+
| `cliId` | 否 | CLI 适配器,默认 `claude-code`(可选:`aiden`、`coco`、`codex`、`cursor`、`gemini`、`opencode`、`antigravity`) |
|
|
455
506
|
| `cliPathOverride` | 否 | CLI 入口的绝对路径,用于套 wrapper / router;典型场景:ccr、claude-w、aiden-x-claude 等自定义入口 |
|
|
456
507
|
| `backendType` | 否 | 会话后端:`pty` 或 `tmux`(默认自动检测) |
|
|
457
508
|
| `workingDir` | 否 | 默认工作目录,支持逗号分隔多个目录 |
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"antigravity.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/antigravity.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,YAAY,CAAC;AA0HxD,wBAAgB,wBAAwB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CAgI1E;AAED,eAAO,MAAM,MAAM,iCAA2B,CAAC"}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { existsSync, statSync, openSync, readSync, closeSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { resolveCommand } from './registry.js';
|
|
5
|
+
import { BOTMUX_SHELL_HINTS } from './shared-hints.js';
|
|
6
|
+
/**
|
|
7
|
+
* Adapter for Google Antigravity CLI (`agy`).
|
|
8
|
+
*
|
|
9
|
+
* Binary: `agy` (default install path: `~/.local/bin/agy`).
|
|
10
|
+
* State dir: `~/.gemini/antigravity-cli/` (Antigravity reuses Gemini CLI's
|
|
11
|
+
* home, namespaced under that subdir).
|
|
12
|
+
*
|
|
13
|
+
* Empirical findings (validated against agy 1.0.0 — May 2026 build):
|
|
14
|
+
*
|
|
15
|
+
* - Boot flags from `agy --help`:
|
|
16
|
+
* --dangerously-skip-permissions auto-approve tool calls
|
|
17
|
+
* --sandbox run in OS sandbox
|
|
18
|
+
* -i / --prompt-interactive initial prompt baked into args
|
|
19
|
+
* --conversation <id> resume by conversation UUID
|
|
20
|
+
* -c / --continue continue most recent conversation
|
|
21
|
+
* -p / --print one-shot non-interactive
|
|
22
|
+
* The earlier docs page omitted -i / --conversation; --help is the
|
|
23
|
+
* authoritative source.
|
|
24
|
+
*
|
|
25
|
+
* - Submit log: `~/.gemini/antigravity-cli/history.jsonl` appends a
|
|
26
|
+
* line on every Enter:
|
|
27
|
+
* {"display":"<user input>","timestamp":<ms>,"workspace":"<cwd>"}
|
|
28
|
+
* Multi-line submits use a literal `\n` inside `display` (JSON-encoded).
|
|
29
|
+
* Same shape as Codex / CoCo history files → suitable for submit
|
|
30
|
+
* verification.
|
|
31
|
+
*
|
|
32
|
+
* - Conversation transcript: `~/.gemini/antigravity-cli/brain/<id>/
|
|
33
|
+
* .system_generated/logs/transcript.jsonl` (line-delimited JSON, fields:
|
|
34
|
+
* step_index/source/type/status/created_at/content). Useful for an
|
|
35
|
+
* `/adopt` bridge later; not consumed for submit verification (the
|
|
36
|
+
* conversationId rotates per spawn and we don't capture it here).
|
|
37
|
+
*
|
|
38
|
+
* - Bracketed paste (`\e[200~...\e[201~`) does NOT work: agy treats the
|
|
39
|
+
* markers as literal text. Use sendText + Enter directly.
|
|
40
|
+
*
|
|
41
|
+
* - Multi-line: alt+Enter (M-Enter / `\x1b\r`) is documented as soft
|
|
42
|
+
* newline (along with ctrl+j / shift+enter). Verified — sending
|
|
43
|
+
* "line1" + M-Enter + "line2" + Enter produces ONE history line with
|
|
44
|
+
* `display:"line1\nline2"`.
|
|
45
|
+
*
|
|
46
|
+
* Skills layout note: Antigravity loads SKILL.md only inside plugin
|
|
47
|
+
* bundles (`plugins/<plugin>/{plugin.json, skills/<name>/SKILL.md}`),
|
|
48
|
+
* not from a flat `skills/` dir. botmux's installer writes the flat
|
|
49
|
+
* layout, so `skillsDir` is intentionally undefined; routing guidance
|
|
50
|
+
* is injected via `systemHints` instead.
|
|
51
|
+
*/
|
|
52
|
+
const HISTORY_PATH = join(homedir(), '.gemini', 'antigravity-cli', 'history.jsonl');
|
|
53
|
+
function delay(ms) {
|
|
54
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
55
|
+
}
|
|
56
|
+
function currentFileSize(path) {
|
|
57
|
+
if (!existsSync(path))
|
|
58
|
+
return 0;
|
|
59
|
+
try {
|
|
60
|
+
return statSync(path).size;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** Build a JSON-escaped prefix marker for substring-matching against
|
|
67
|
+
* history.jsonl's raw bytes. Three things to keep aligned with agy's
|
|
68
|
+
* on-disk encoding:
|
|
69
|
+
*
|
|
70
|
+
* 1. Literal `\n` in user content becomes the two-char escape `\n`
|
|
71
|
+
* (handled by JSON.stringify already).
|
|
72
|
+
* 2. agy is Go and its writer uses encoding/json's default
|
|
73
|
+
* SetEscapeHTML(true), so `<` / `>` / `&` land as `\u003c` /
|
|
74
|
+
* `\u003e` / `\u0026` on disk — JS's JSON.stringify does NOT
|
|
75
|
+
* emit those escapes, so we patch them in manually. Without this,
|
|
76
|
+
* botmux prompts (which always wrap user text in `<user_message>`
|
|
77
|
+
* and `<botmux_routing>` tags) would NEVER match and the worker
|
|
78
|
+
* would always show a spurious "submit not confirmed" warning,
|
|
79
|
+
* even though the model did receive the prompt.
|
|
80
|
+
* 3. 40 chars is plenty unique even when several bots submit nearly
|
|
81
|
+
* identical opening lines.
|
|
82
|
+
*/
|
|
83
|
+
function historyMarker(content) {
|
|
84
|
+
const prefix = content.slice(0, 40);
|
|
85
|
+
return JSON.stringify(prefix)
|
|
86
|
+
.slice(1, -1)
|
|
87
|
+
.replace(/</g, '\\u003c')
|
|
88
|
+
.replace(/>/g, '\\u003e')
|
|
89
|
+
.replace(/&/g, '\\u0026');
|
|
90
|
+
}
|
|
91
|
+
function historyDeltaContains(path, fromByte, marker) {
|
|
92
|
+
if (!existsSync(path))
|
|
93
|
+
return false;
|
|
94
|
+
let size;
|
|
95
|
+
try {
|
|
96
|
+
size = statSync(path).size;
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
if (size <= fromByte)
|
|
102
|
+
return false;
|
|
103
|
+
const len = size - fromByte;
|
|
104
|
+
const buf = Buffer.alloc(len);
|
|
105
|
+
const fd = openSync(path, 'r');
|
|
106
|
+
try {
|
|
107
|
+
readSync(fd, buf, 0, len, fromByte);
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
closeSync(fd);
|
|
111
|
+
}
|
|
112
|
+
const delta = buf.toString('utf8');
|
|
113
|
+
// Each line is a self-contained JSON object; we only care that one of them
|
|
114
|
+
// is a `display` field starting with our marker. Don't bother JSON.parse —
|
|
115
|
+
// raw substring on the encoded form is sufficient and robust against
|
|
116
|
+
// partial trailing writes.
|
|
117
|
+
for (const line of delta.split('\n')) {
|
|
118
|
+
if (!line.includes(`"display":"${marker}`))
|
|
119
|
+
continue;
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
async function waitForHistoryAppend(path, fromByte, marker, timeoutMs) {
|
|
125
|
+
const deadline = Date.now() + timeoutMs;
|
|
126
|
+
while (Date.now() < deadline) {
|
|
127
|
+
if (historyDeltaContains(path, fromByte, marker))
|
|
128
|
+
return true;
|
|
129
|
+
await delay(100);
|
|
130
|
+
}
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
export function createAntigravityAdapter(pathOverride) {
|
|
134
|
+
const bin = resolveCommand(pathOverride ?? 'agy');
|
|
135
|
+
return {
|
|
136
|
+
id: 'antigravity',
|
|
137
|
+
resolvedBin: bin,
|
|
138
|
+
buildArgs({ resume, resumeSessionId }) {
|
|
139
|
+
const args = ['--dangerously-skip-permissions'];
|
|
140
|
+
// Resume: only when we have agy's own conversation UUID. We never
|
|
141
|
+
// map botmux's sessionId here because agy generates its own id at
|
|
142
|
+
// spawn time and ignores any value we'd pass — `--conversation`
|
|
143
|
+
// strictly looks up an existing one. Without a stored cliSessionId,
|
|
144
|
+
// start fresh; do NOT use `-c/--continue` because "most recent" is
|
|
145
|
+
// racy when multiple botmux sessions run in parallel.
|
|
146
|
+
if (resume && resumeSessionId) {
|
|
147
|
+
args.push('--conversation', resumeSessionId);
|
|
148
|
+
}
|
|
149
|
+
// NOTE: we deliberately do NOT pass `-i` / `--prompt-interactive`.
|
|
150
|
+
// Despite the flag's existence in `agy --help`, empirical testing
|
|
151
|
+
// shows that:
|
|
152
|
+
// (a) -i prompts do NOT auto-submit (unlike Gemini's -i)
|
|
153
|
+
// (b) -i prompts do NOT appear in history.jsonl, so we can't even
|
|
154
|
+
// confirm submission through our usual marker channel
|
|
155
|
+
// (c) a follow-up Enter does not finish the deposit either
|
|
156
|
+
// Treating -i as the initial-prompt channel would cause the worker
|
|
157
|
+
// to skip stdin-injection (passesInitialPromptViaArgs=true), and
|
|
158
|
+
// the user's first message would silently disappear. Instead, the
|
|
159
|
+
// worker queues the prompt and writeInput delivers it after idle
|
|
160
|
+
// — same pattern as cursor/aiden. */
|
|
161
|
+
return args;
|
|
162
|
+
},
|
|
163
|
+
buildResumeCommand({ cliSessionId }) {
|
|
164
|
+
// Antigravity's conversation id is opaque and not derivable from
|
|
165
|
+
// botmux's sessionId. Without a captured cliSessionId we can't print
|
|
166
|
+
// a precise one-liner, so let the closed-session card fall back to
|
|
167
|
+
// its generic note. v1 does not capture cliSessionId — added in a
|
|
168
|
+
// later iteration once we wire conversation-id discovery against
|
|
169
|
+
// ~/.gemini/antigravity-cli/conversations/.
|
|
170
|
+
if (!cliSessionId)
|
|
171
|
+
return null;
|
|
172
|
+
return `agy --conversation ${cliSessionId}`;
|
|
173
|
+
},
|
|
174
|
+
async writeInput(pty, content) {
|
|
175
|
+
// Two known constraints (verified empirically):
|
|
176
|
+
//
|
|
177
|
+
// 1. Bracketed paste (`\e[200~...\e[201~`) doesn't work — agy treats
|
|
178
|
+
// the markers as literal characters. So we type each line via
|
|
179
|
+
// `send-keys -l` (sendText) and use M-Enter (alt+Enter) between
|
|
180
|
+
// lines as the documented soft-newline. Trailing plain Enter is
|
|
181
|
+
// the unambiguous submit.
|
|
182
|
+
//
|
|
183
|
+
// 2. agy logs every submit to ~/.gemini/antigravity-cli/history.jsonl
|
|
184
|
+
// as `{"display":"...","timestamp":...,"workspace":"..."}` —
|
|
185
|
+
// same pattern as Codex/CoCo. We poll the delta past `baseByte`
|
|
186
|
+
// for our `display` prefix marker. If unseen after the in-band
|
|
187
|
+
// retry budget, return {submitted:false, recheck} so the worker
|
|
188
|
+
// can warn the user.
|
|
189
|
+
const baseByte = currentFileSize(HISTORY_PATH);
|
|
190
|
+
const marker = historyMarker(content);
|
|
191
|
+
const trySendEnter = () => {
|
|
192
|
+
try {
|
|
193
|
+
if (pty.sendSpecialKeys)
|
|
194
|
+
pty.sendSpecialKeys('Enter');
|
|
195
|
+
else
|
|
196
|
+
pty.write('\r');
|
|
197
|
+
return true;
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
// tmux session gone (CLI exited mid-write) — bail cleanly rather
|
|
201
|
+
// than crashing the worker on an unhandled execFileSync error.
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
try {
|
|
206
|
+
if (pty.sendText && pty.sendSpecialKeys) {
|
|
207
|
+
const lines = content.split('\n');
|
|
208
|
+
for (let i = 0; i < lines.length; i++) {
|
|
209
|
+
if (lines[i].length > 0)
|
|
210
|
+
pty.sendText(lines[i]);
|
|
211
|
+
if (i < lines.length - 1) {
|
|
212
|
+
// M-Enter / alt+Enter: documented soft newline. Don't use
|
|
213
|
+
// `\` + Enter (Claude Code's idiom) — agy doesn't treat
|
|
214
|
+
// backslash as an escape.
|
|
215
|
+
pty.sendSpecialKeys('M-Enter');
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
// Raw PTY fallback (no tmux): write text directly with ESC+\r
|
|
221
|
+
// for soft newlines.
|
|
222
|
+
const lines = content.split('\n');
|
|
223
|
+
for (let i = 0; i < lines.length; i++) {
|
|
224
|
+
pty.write(lines[i]);
|
|
225
|
+
if (i < lines.length - 1)
|
|
226
|
+
pty.write('\x1b\r');
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
return { submitted: false };
|
|
232
|
+
}
|
|
233
|
+
await delay(300);
|
|
234
|
+
if (!trySendEnter())
|
|
235
|
+
return { submitted: false };
|
|
236
|
+
// 3 retries × 800ms each, then a final grace check. If the user
|
|
237
|
+
// concurrently types in the web terminal, a stray Enter may submit
|
|
238
|
+
// their half-typed text — we only retry when the JSONL is provably
|
|
239
|
+
// unchanged, so the race window is bounded to genuine submit
|
|
240
|
+
// failures.
|
|
241
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
242
|
+
if (await waitForHistoryAppend(HISTORY_PATH, baseByte, marker, 800)) {
|
|
243
|
+
return undefined;
|
|
244
|
+
}
|
|
245
|
+
if (!trySendEnter())
|
|
246
|
+
return { submitted: false };
|
|
247
|
+
}
|
|
248
|
+
if (await waitForHistoryAppend(HISTORY_PATH, baseByte, marker, 800)) {
|
|
249
|
+
return undefined;
|
|
250
|
+
}
|
|
251
|
+
// In-band budget exhausted. Hand the worker a recheck closure so a
|
|
252
|
+
// slow agy (cold start, large initial prompt, network-bound auth)
|
|
253
|
+
// can still resolve the warning before user-facing Lark notify.
|
|
254
|
+
const recheck = () => historyDeltaContains(HISTORY_PATH, baseByte, marker);
|
|
255
|
+
return { submitted: false, recheck };
|
|
256
|
+
},
|
|
257
|
+
completionPattern: undefined,
|
|
258
|
+
readyPattern: undefined,
|
|
259
|
+
systemHints: BOTMUX_SHELL_HINTS,
|
|
260
|
+
altScreen: true,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
export const create = createAntigravityAdapter;
|
|
264
|
+
//# sourceMappingURL=antigravity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"antigravity.js","sourceRoot":"","sources":["../../../src/adapters/cli/antigravity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,eAAe,CAAC,CAAC;AAEpF,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAChC,IAAI,CAAC;QAAC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,CAAC,CAAC;IAAC,CAAC;AACzD,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,SAAS,aAAa,CAAC,OAAe;IACpC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACpC,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;SAC1B,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;SACZ,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;SACxB,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;SACxB,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAY,EAAE,QAAgB,EAAE,MAAc;IAC1E,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACpC,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC;IAC3D,IAAI,IAAI,IAAI,QAAQ;QAAE,OAAO,KAAK,CAAC;IACnC,MAAM,GAAG,GAAG,IAAI,GAAG,QAAQ,CAAC;IAC5B,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC;QACH,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;IACtC,CAAC;YAAS,CAAC;QACT,SAAS,CAAC,EAAE,CAAC,CAAC;IAChB,CAAC;IACD,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACnC,2EAA2E;IAC3E,2EAA2E;IAC3E,qEAAqE;IACrE,2BAA2B;IAC3B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,MAAM,EAAE,CAAC;YAAE,SAAS;QACrD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,oBAAoB,CACjC,IAAY,EAAE,QAAgB,EAAE,MAAc,EAAE,SAAiB;IAEjE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IACxC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,IAAI,oBAAoB,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;QAC9D,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,YAAqB;IAC5D,MAAM,GAAG,GAAG,cAAc,CAAC,YAAY,IAAI,KAAK,CAAC,CAAC;IAClD,OAAO;QACL,EAAE,EAAE,aAAa;QACjB,WAAW,EAAE,GAAG;QAEhB,SAAS,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE;YACnC,MAAM,IAAI,GAAG,CAAC,gCAAgC,CAAC,CAAC;YAChD,kEAAkE;YAClE,kEAAkE;YAClE,gEAAgE;YAChE,oEAAoE;YACpE,mEAAmE;YACnE,sDAAsD;YACtD,IAAI,MAAM,IAAI,eAAe,EAAE,CAAC;gBAC9B,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;YAC/C,CAAC;YACD,mEAAmE;YACnE,kEAAkE;YAClE,cAAc;YACd,2DAA2D;YAC3D,oEAAoE;YACpE,4DAA4D;YAC5D,6DAA6D;YAC7D,mEAAmE;YACnE,iEAAiE;YACjE,kEAAkE;YAClE,iEAAiE;YACjE,qCAAqC;YACrC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,kBAAkB,CAAC,EAAE,YAAY,EAAE;YACjC,iEAAiE;YACjE,qEAAqE;YACrE,mEAAmE;YACnE,kEAAkE;YAClE,iEAAiE;YACjE,4CAA4C;YAC5C,IAAI,CAAC,YAAY;gBAAE,OAAO,IAAI,CAAC;YAC/B,OAAO,sBAAsB,YAAY,EAAE,CAAC;QAC9C,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,GAAc,EAAE,OAAe;YAC9C,gDAAgD;YAChD,EAAE;YACF,qEAAqE;YACrE,iEAAiE;YACjE,mEAAmE;YACnE,mEAAmE;YACnE,6BAA6B;YAC7B,EAAE;YACF,sEAAsE;YACtE,gEAAgE;YAChE,mEAAmE;YACnE,kEAAkE;YAClE,mEAAmE;YACnE,wBAAwB;YACxB,MAAM,QAAQ,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC;YAC/C,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;YAEtC,MAAM,YAAY,GAAG,GAAY,EAAE;gBACjC,IAAI,CAAC;oBACH,IAAI,GAAG,CAAC,eAAe;wBAAE,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;;wBACjD,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBACrB,OAAO,IAAI,CAAC;gBACd,CAAC;gBAAC,MAAM,CAAC;oBACP,iEAAiE;oBACjE,+DAA+D;oBAC/D,OAAO,KAAK,CAAC;gBACf,CAAC;YACH,CAAC,CAAC;YAEF,IAAI,CAAC;gBACH,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC;oBACxC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;wBACtC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC;4BAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;wBAChD,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4BACzB,0DAA0D;4BAC1D,wDAAwD;4BACxD,0BAA0B;4BAC1B,GAAG,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;wBACjC,CAAC;oBACH,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,8DAA8D;oBAC9D,qBAAqB;oBACrB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;wBACtC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;wBACpB,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC;4BAAE,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;oBAChD,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;YAC9B,CAAC;YAED,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;YACjB,IAAI,CAAC,YAAY,EAAE;gBAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;YAEjD,gEAAgE;YAChE,mEAAmE;YACnE,mEAAmE;YACnE,6DAA6D;YAC7D,YAAY;YACZ,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;gBAC7C,IAAI,MAAM,oBAAoB,CAAC,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;oBACpE,OAAO,SAAS,CAAC;gBACnB,CAAC;gBACD,IAAI,CAAC,YAAY,EAAE;oBAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;YACnD,CAAC;YACD,IAAI,MAAM,oBAAoB,CAAC,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;gBACpE,OAAO,SAAS,CAAC;YACnB,CAAC;YAED,mEAAmE;YACnE,kEAAkE;YAClE,gEAAgE;YAChE,MAAM,OAAO,GAAG,GAAY,EAAE,CAAC,oBAAoB,CAAC,YAAY,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YACpF,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QACvC,CAAC;QAED,iBAAiB,EAAE,SAAS;QAC5B,YAAY,EAAE,SAAS;QACvB,WAAW,EAAE,kBAAkB;QAC/B,SAAS,EAAE,IAAI;KAChB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,wBAAwB,CAAC"}
|
|
@@ -6,13 +6,14 @@ import { createCodexAdapter } from './codex.js';
|
|
|
6
6
|
import { createCursorAdapter } from './cursor.js';
|
|
7
7
|
import { createGeminiAdapter } from './gemini.js';
|
|
8
8
|
import { createOpenCodeAdapter } from './opencode.js';
|
|
9
|
+
import { createAntigravityAdapter } from './antigravity.js';
|
|
9
10
|
/** Resolve a command name to its absolute path via shell `which`.
|
|
10
11
|
* Tries login shell first (-lc), then interactive shell (-ic) for tools
|
|
11
12
|
* whose installers add PATH entries to .bashrc/.zshrc only. */
|
|
12
13
|
export declare function resolveCommand(cmd: string): string;
|
|
13
14
|
/** Async adapter factory (uses dynamic import for lazy loading in daemon process). */
|
|
14
15
|
export declare function createCliAdapter(id: CliId, pathOverride?: string): Promise<CliAdapter>;
|
|
15
|
-
export { createClaudeCodeAdapter, createAidenAdapter, createCocoAdapter, createCodexAdapter, createCursorAdapter, createGeminiAdapter, createOpenCodeAdapter };
|
|
16
|
+
export { createClaudeCodeAdapter, createAidenAdapter, createCocoAdapter, createCodexAdapter, createCursorAdapter, createGeminiAdapter, createOpenCodeAdapter, createAntigravityAdapter };
|
|
16
17
|
/** Synchronous version for use in worker process. */
|
|
17
18
|
export declare function createCliAdapterSync(id: CliId, pathOverride?: string): CliAdapter;
|
|
18
19
|
//# 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;
|
|
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"}
|
|
@@ -7,6 +7,7 @@ import { createCodexAdapter } from './codex.js';
|
|
|
7
7
|
import { createCursorAdapter } from './cursor.js';
|
|
8
8
|
import { createGeminiAdapter } from './gemini.js';
|
|
9
9
|
import { createOpenCodeAdapter } from './opencode.js';
|
|
10
|
+
import { createAntigravityAdapter } from './antigravity.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. */
|
|
@@ -43,7 +44,7 @@ export async function createCliAdapter(id, pathOverride) {
|
|
|
43
44
|
adapterCache.set(key, adapter);
|
|
44
45
|
return adapter;
|
|
45
46
|
}
|
|
46
|
-
export { createClaudeCodeAdapter, createAidenAdapter, createCocoAdapter, createCodexAdapter, createCursorAdapter, createGeminiAdapter, createOpenCodeAdapter };
|
|
47
|
+
export { createClaudeCodeAdapter, createAidenAdapter, createCocoAdapter, createCodexAdapter, createCursorAdapter, createGeminiAdapter, createOpenCodeAdapter, createAntigravityAdapter };
|
|
47
48
|
/** Synchronous version for use in worker process. */
|
|
48
49
|
export function createCliAdapterSync(id, pathOverride) {
|
|
49
50
|
switch (id.toLowerCase()) {
|
|
@@ -54,6 +55,7 @@ export function createCliAdapterSync(id, pathOverride) {
|
|
|
54
55
|
case 'cursor': return createCursorAdapter(pathOverride);
|
|
55
56
|
case 'gemini': return createGeminiAdapter(pathOverride);
|
|
56
57
|
case 'opencode': return createOpenCodeAdapter(pathOverride);
|
|
58
|
+
case 'antigravity': return createAntigravityAdapter(pathOverride);
|
|
57
59
|
default: throw new Error(`Unknown CLI adapter: ${id}`);
|
|
58
60
|
}
|
|
59
61
|
}
|