关于 Codeman
Codeman 是面向需要管理多个编码 Agent 会话的开发者的可自托管控制面板。它以 tmux 保持会话运行,并提供浏览器访问、后台监控和无人值守任务处理。
主要功能
- 01在会话中运行多种编码 CLI
- 02通过浏览器访问实时终端
- 03唤醒空闲或限额暂停的 Agent
- 04安排任务并监控后台 Agent
- 05断连或重启后保留会话
适用场景
- 01通过一个面板管理编码 Agent
- 02用手机查看会话并发送提示
- 03在使用限额暂停期间让 Agent 持续运行
MCP 相关
Codeman 提供 MCP 服务,允许 Agent 在可用 CLI 中启动工作会话、发送提示、等待完成并收集回复。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
AI 编码 Agent 的任务控制中心
Claude Code • OpenCode • Codex • Antigravity • Gemini • Pi • Grok • DeepSeek • OMP • Copilot • 终端 - 一个仪表盘 • 任意设备
英语 • 简体中文
Codeman 是一个面向 AI 编码 Agent 的可自托管任务控制中心。它会在持久化的 tmux 会话中启动 Claude Code、OpenCode、Codex、Antigravity、Gemini、Pi、Grok、DeepSeek Harness、OMP 或 GitHub Copilot CLI,将真实终端画面实时传输到任意浏览器,并让 Agent 在你离开后继续工作:空闲时重新发送提示词、使用限额重置后恢复运行、执行定时任务,并实时显示每个后台 Agent 的工作情况。
一行命令即可开始(macOS 和 Linux;Windows 需通过 WSL):
curl -fsSL https://getcodeman.com/install | bash
codeman web
# Open http://localhost:3000 and start your first session
安装程序会在每次更改系统前征求许可;再次运行相同命令即可原地更新。完整详情请参阅:快速入门 - 安装。
- 一个控制面板,十种 CLI —— 每个会话都可运行 Claude Code、OpenCode、Codex、Antigravity、Gemini、Pi、Grok、DeepSeek、OMP 或 GitHub Copilot(也可使用纯 Shell),并可在本地、Docker 中或通过 SSH运行;还可在旁边以网页标签页的形式打开自己的控制面板
- 真正适合手机使用 —— 配备触控优化终端,支持即时本地回显、二维码登录、滑动导航和推送通知
- 运行不间断 —— 借助空闲检测与重启循环,并在订阅额度重置后自动恢复,可无人值守运行 24 小时以上
- 观察 Agent 思考 —— 通过实时浮动窗口查看每个子 Agent 和队友,并获取实时转录内容
- Agent 也能操控它 —— codeman 技能(适用于所有 Agent CLI)、
codeman agent和 MCP 服务可让一个 Agent 在任意 CLI 中启动工作进程、向其发送提示词、等待其响应并收集答案 - 不会丢失任何内容 —— tmux 可在重启和网络中断后保持会话,确保输入恰好投递一次,并支持完整回滚记录重放
- 自托管且私密 —— 默认仅监听环回地址,采用 MIT 许可证,无遥测,完全在你的机器上运行
快速入门 - 安装
curl -fsSL https://getcodeman.com/install | bash
如果缺少 Node.js、tmux 和构建工具链,此安装程序会自动安装它们(node-pty 不提供 Linux 预编译版本,因此会从源代码编译),将 Codeman 克隆到 ~/.codeman/app 并进行构建。它会检查机器上已有的内容,最多询问三个问题,然后自动完成所有工作,最后显示带有手机二维码的 URL。以下几点值得了解:
- 开头先问三个问题。 如何访问控制面板、是否要为这台机器设置 tailnet 上的名称,以及是否将 Codeman 作为后台服务运行(systemd/launchd,开机自动启动;按 Enter 表示是)。所有需要你参与的操作,包括一次性同意安装所有缺失的软件包、输入一次 sudo 密码,以及登录 Tailscale,都会在构建前完成,因此你可以在编译期间离开。
- 如何访问,由你选择。 Tailscale(绑定到 loopback,由
tailscale serve提供服务,因此你会获得https://<machine>.<tailnet>.ts.net,使用真实证书,并以 tailnet 作为登录方式,无需密码)、网络中的任何设备(0.0.0.0,强烈建议设置密码),或仅限这台机器(127.0.0.1,最安全)。在绑定到网络时跳过密码,需要明确确认,最后还会显示醒目的警告。高亮的默认选项会反映机器上的现有设置(如果已连接 Tailscale,则选择 Tailscale;重新运行时则沿用现有绑定),直接按 Enter 绝不会安装新软件。如果节点上已有其他应用占用:443,Codeman 会改用https://<machine>.<tailnet>.ts.net/codeman或第二个端口,而不是替换它。手动启动的普通codeman web仍默认绑定到 loopback。 - 名称由你决定。 默认情况下,URL 使用机器现有的 tailnet 名称。对第二个问题回答是,会将机器重命名为
codeman-<hostname>(这也会更改 SSH 所用的名称,因此默认选项为否);之后也可以运行install.sh name。 - 重新运行即可更新。 同一条命令会原地更新已完成的安装:
~/.codeman/app中的本地更改会被暂存(绝不会丢弃),正在运行的服务也会重启并经过验证。如果首次安装中断,重新运行则会继续完成整个设置流程。install.sh status会再次显示 URL 和二维码;此外还有install.sh update、install.sh tailscale和install.sh uninstall。 - 给心急的人准备的标志。
curl -fsSL https://getcodeman.com/install | bash -s -- --tailscale --service可通过命令行回答这些问题(也支持--lan、--local、--run、--no-start、--name <n>、--port <n>、--yes)。**CI / 无头环境:**如果没有连接终端,需要更改系统的步骤会中止并显示操作说明,而不会静默执行;设置CODEMAN_NONINTERACTIVE=1即可批准这些操作以供自动化使用。
你至少需要安装一个 AI 编码 CLI——Claude Code、OpenCode、Codex、Antigravity、Gemini CLI、Pi、Grok Build、DeepSeek Harness、OMP 或 GitHub Copilot CLI(可任意组合使用;自 Google 面向消费者的服务切换后,Gemini CLI 仅供企业使用,Antigravity 是其后继产品)。安装程序会检测这十种工具中已安装的项;如果一个都没找到,会提供菜单供你选择安装其中任意一种(DeepSeek 除外,因为它的 npm 软件包只会安装启动器,不包含可运行的配置),你也可以跳过,稍后自行安装。安装后:
codeman web
# Open http://localhost:3000 and start your first session
要与小型团队共享吗? 改为以多用户模式启动:每个人都有自己的登录账号和工作区。
codeman users add alice --admin # create the first admin account
codeman web --multiuser # named logins + per-user case spaces
更喜欢使用 Docker Compose? docker/ 中提供了本地镜像 Compose 部署方式:将 docker/.env.example 复制为 docker/.env,设置 CODEMAN_PASSWORD,然后在 Linux 上运行 bash docker/Start-Codeman.sh。Codeman 在容器中运行,并通过主机套接字将 Docker 案例作为同级容器启动。更新后,请再次运行该脚本,而不要直接运行 docker compose up,以便重建后的镜像、刷新的卷和入口点一起就位。有关直接使用 Compose 命令、存储和网络选项,请参阅 Docker 部署指南。
详情见下文的多用户模式(可选)。
让它在后台持续运行
若要让它在启动它的 Shell 关闭后继续运行,无需进行任何设置:
codeman web -d # detach; logs to ~/.codeman/web.log
codeman web --status # is it up, and on which pid
codeman web --stop # graceful SIGTERM; agents keep running in tmux
-d 会等待服务器实际响应后才报告成功,并且如果同一数据目录中已有服务器运行,就会拒绝启动第二个服务器(两个共享 tmux 套接字的服务器会连接到彼此的会话)。
若要让它在重启后自动恢复运行,请将它安装为服务。安装程序的最后一个菜单会为你完成此操作(选项 2);对于通过 npm i -g aicodeman 安装的情况,codeman service 与之等效:
codeman service install # systemd user unit (Linux) or LaunchAgent (macOS)
codeman service status
codeman service uninstall
service install 会将你当前的 PATH 写入单元文件,这一点比听起来更重要:launchd 提供给任务的 PATH 是 /usr/bin:/bin:/usr/sbin:/sbin,因此手写 plist 时,Homebrew 或 nvm 安装的 node、tmux 或 claude 都不可见。它绝不会将 CODEMAN_PASSWORD 复制到单元文件中;如果服务需要身份验证,请自行添加。
若要改为手动编写单元文件:
Linux(systemd):
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/codeman-web.service << EOF
[Unit]
Description=Codeman Web Server
After=network.target
[Service]
Type=simple
ExecStart=$(which node) $HOME/.codeman/app/dist/index.js web
Restart=always
RestartSec=10
[Install]
WantedBy=default.target
EOF
systemctl --user daemon-reload
systemctl --user enable --now codeman-web
loginctl enable-linger $USER
macOS(launchd):
mkdir -p ~/Library/LaunchAgents
cat > ~/Library/LaunchAgents/com.codeman.web.plist << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.codeman.web</string>
<key>ProgramArguments</key>
<array>
<string>$(which node)</string>
<string>$HOME/.codeman/app/dist/index.js</string>
<string>web</string>
</array>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
<key>StandardOutPath</key>
<string>/tmp/codeman.log</string>
<key>StandardErrorPath</key>
<string>/tmp/codeman.log</string>
</dict>
</plist>
EOF
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.codeman.web.plist
Windows(WSL)
wsl bash -c "curl -fsSL https://getcodeman.com/install | bash"
Codeman 需要 tmux,因此 Windows 用户需要安装 WSL。如果尚未安装 WSL:在管理员 PowerShell 中运行 wsl --install,重启,打开 Ubuntu,然后在 WSL 中安装你偏好的 AI 编码 CLI(Claude Code、OpenCode、Codex、Antigravity、Gemini CLI、Pi、Grok Build、DeepSeek Harness 或 OMP)。安装完成后,你就可以在 Windows 浏览器中访问 http://localhost:3000。
移动端优化的 Web UI
在任何手机上都能获得响应最灵敏的 AI 编码 Agent 体验。完整的 xterm.js 终端,支持本地回显、滑动导航,以及专为实际远程工作打造的触控优化界面,而不是把桌面 UI 硬塞进小屏幕。
![]() | ![]() |
| 轻触即可回答提示词 | 快捷栏 + 专用 Enter 按钮 |
| 终端应用 | Codeman 移动端 |
|---|---|
| 远程输入延迟 200-300ms | 本地回显 — 即时反馈 |
| 文字太小,缺少上下文 | 完整的 xterm.js 终端 |
| 无法管理会话 | 滑动切换会话 |
| 没有通知 | 审批和空闲状态的推送提醒 |
| 需要手动重新连接 | tmux 持久化 |
| 无法查看 Agent 状态 | 实时查看后台 Agent |
| 需要复制粘贴斜杠命令 | 轻点即可执行 /init、/clear、/compact |
| 在手机上输入密码 | 扫描 QR 码 — 即时认证 |
- 键盘快捷栏 — 虚拟键盘上方提供
/init、/clear、/compact快捷操作按钮;危险命令需要双击确认,避免误触执行;在 Codex 会话中,快捷栏还会显示⇧←/⇧→(Shift+Left / Shift+Right:编辑上条已排队消息 / 返回提示词栈中的上一条) - 专用 Enter 按钮 — 通过终端重新发送按键,因此本地回显缓冲的文本会先被刷新,不会滞留
- 附件按钮:麦克风旁的图片图标会打开系统照片和文件选择面板,无需唤起键盘。照片和相机胶卷中的视频(mp4、mov、webm,最大 1 GB)会上传到会话文件夹,其路径会填入提示词,但不会发送
- 在 Shell 中粘贴:多行内容会作为一个整体粘贴,并等待你按 Enter,而不是逐行到达后立即运行
- 滑动导航和智能键盘处理 — 左右滑动即可切换会话;键盘打开时,工具栏和终端会向上移(
visualViewportAPI) - 专为手机打造 — 为刘海和 Home 指示条预留安全区域,触控目标尺寸为 44px,采用底部弹出式大小写选择器和原生惯性滚动;在折叠手机(iPhone Duo)上,对话框会避开铰链,打开或合上设备也绝不会被误判为键盘
codeman web --https
# Open on your phone: https://<your-ip>:3000
localhost可通过普通 HTTP 使用。从其他设备访问时,请使用--https,或使用 Tailscale(推荐):安装程序可以帮你完成设置(在网络访问提示中选择 Tailscale,或在现有安装中运行bash ~/.codeman/app/install.sh tailscale)。这样你就能通过https://<your-machine>.<tailnet>.ts.net访问,并使用有效证书:仅限你的 tailnet 内部访问,无需密码,而且手机上可安装 PWA 并使用推送通知。安装程序结束时会显示该 URL 和供扫描的 QR 码,随时运行bash ~/.codeman/app/install.sh status可再次查看。
安全二维码身份验证
在手机键盘上输入密码实在痛苦。Codeman 将其替换为通过密码学保障安全的一次性二维码令牌——扫描桌面上显示的二维码,手机即可立即完成身份验证。
每个二维码都编码一个 URL,其中包含一个 6 字符短码,该短码在服务器上对应一个 256 位密钥(crypto.randomBytes(32))。令牌每 60 秒自动轮换一次,首次扫描时即以原子方式消费(重放始终会失败),并使用基于哈希的 Map.get() 查找,不会通过响应时间泄露任何信息。短码是一个不透明指针——真实密钥绝不会出现在浏览器历史记录、Referer 标头或 Cloudflare 边缘日志中。
此安全设计针对《揭开基于二维码的登录的(不)安全性之谜》(USENIX Security 2025)指出的 6 个二维码身份验证关键缺陷逐一采取了措施;该研究发现排名前 100 的网站中有 47 个存在漏洞:一次性使用限制、较短的 TTL、密码学随机性、服务端生成、扫描时实时通知桌面端(检测 QRLjacking),以及绑定 IP 和 User-Agent 的会话并支持手动撤销。双层速率限制(按 IP + 全局)使暴力破解无法实现;可能的代码共有 62^6 = 568 亿种。完整安全分析:docs/qr-auth-plan.md
使用 Codeman——用户指南
从头到尾介绍如何通过浏览器使用 Codeman。如果你刚刚安装,这里就是入门之处。
1. 启动服务
codeman web # localhost:3000 (loopback only — safe default)
codeman web --port 8080 # custom port (or set CODEMAN_PORT)
codeman web --https # self-signed TLS (only needed for remote access)
codeman web -H 0.0.0.0 # bind LAN — REQUIRES CODEMAN_PASSWORD (see Security)
codeman web -d # detach: survives closing the shell (--status, --stop)
codeman service install # systemd/launchd service: comes back after reboots
打开打印出的 URL。该页面是一个独立仪表板;以下所有操作都在此进行。
2. 创建第一个会话
点击 + New Session(或 Quick Start)。一个会话就是一个在独立 tmux 终端中运行的 AI CLI。你可以选择:
| 字段 | 作用 |
|---|---|
| Working directory / case | Agent 操作的文件夹。“case”只是 Codeman 记住的一个命名工作目录。Add Case 可以从头创建一个、关联现有文件夹,或将 GitHub 仓库直接克隆到其中(Clone Repo)。 |
| CLI / run mode | Claude(默认)、OpenCode、Codex、Antigravity、Gemini、Pi、Grok、DeepSeek、OMP、Copilot 或 Terminal(普通 shell)。 |
| Model | 每个会话单独使用的模型(App Settings → Models → New Claude sessions)。这是一个宽松的默认值——会话中仍可使用 /model。 |
| Effort / Ultracode | 推理力度(low–max)或用于动态多 Agent 工作流的 ultracode。随时可通过 /effort 切换。 |
点击开始——Codeman 会通过真实 PTY 启动 CLI,并通过 SSE 将其内容流式传输到浏览器。
3. 查看仪表板
- 标签页(顶部)——每个会话对应一个标签页。使用
Alt+1-9跳转,使用Ctrl+Tab切换到下一个,拖动即可重新排序(标签页顺序会在你的设备间同步)。更喜欢列表?App Settings → Appearance → Tabs 可将其移至左侧边栏,并提供筛选框(Alt+B可将其收起),或移至纵向栏;纵向栏中的行按活动状态排序:首先是等待你处理的会话,然后是运行时间最长的会话,最后是最近最安静的会话。纵向栏还提供 Search sessions 搜索框、命名的标签页组(组菜单可直接在该组中启动 New session),以及一个 Focus 区域,其中包含你常用标签页的快捷方式。 - 终端(中央)——真实的
xterm.js终端;可正确呈现完整的 TUI。直接输入并按 Enter 发送。按Shift+Enter插入换行符。 - 侧边面板——Respawn、Orchestrator、Cron、Subagents、Settings(通过工具栏切换)。
4. 与 Agent 对话
- 直接在终端中输入提示词——即使断线重连,输入内容也只会送达一次(连接中断不会导致提示词丢失或重复发送)。
- 粘贴、拖放或附加图片、视频和文档(PDF、Office 文件、zip 和纯文本),直接添加到会话中。文件会保存在工作区中隐藏的
.codeman-uploads/文件夹里(该文件夹会在 git 中忽略自身,并在 7 天后清理),文件路径会添加到提示词中,但不会发送。 - 语音输入——使用
Ctrl+Shift+V(Deepgram Nova-3,或使用这台设备的 Claude Code 登录,无需 API 密钥;检测到静音时自动停止)。 - 附件——登记外部文件/文档,并在页面内预览 Office/PDF 文件;Agent 输出的任何文件路径都可以点击,包括终端和聊天视图中的
~/路径、相对路径以及跨行显示的路径。.html报告会以网页形式打开,Markdown 会以渲染后的形式打开,文件夹会以网格形式显示其中的文件。 - 需要你处理时——标签页会变为黄色(等待输入)或红色(问题阻塞进程)。审批收件箱 (可选启用) 会将 Claude Code、Codex 和 DeepSeek Harness 会话中等待你处理的提示词汇总到一个列表中。Claude 提示词可通过标题栏的铃铛按钮回答;Claude 对话框也可通过手机主屏幕回答;Claude 权限提示词还可通过推送通知上的“批准/拒绝”按钮处理。Codex 和 DeepSeek 条目会提醒你在终端中作答,其他 CLI 的提示词不会进入收件箱。🧠 读懂我的心思 (可选启用) 会根据案例目标和近期工作草拟你的下一条提示词。
- 复制屏幕上的内容——即使 CLI 占用鼠标,按住
Shift拖动也能选中文字;右键即可复制;启用“自动复制” (可选启用) 后,松开鼠标时会立即复制选中内容。使用 OSC 52 复制内容的程序(Claude Code 的/copy、tmux 剪贴、vim)也会将文本复制到浏览器剪贴板。
5. 实现自主运行
| 模式 | 用途 | 位置 |
|---|---|---|
| Respawn | 长时间无人值守运行——CLI 空闲或达到限制时自动重启,并自适应调整间隔。预设:solo-work、overnight-autonomous、… | Respawn 标签页 |
| Orchestrator | 将一个目标转化为分阶段计划,并通过多个 Agent 推动计划完成。 | Orchestrator 面板 |
| Cron | 按计划运行已保存并命名的任务(once/interval/daily/weekly),在到期时启动会话并发送提示词。 | ⏰ Cron 按钮 (可选启用:App Settings → Header & Panels → Scheduling) |
| 自动恢复 | 订阅速率限制重置后自动继续运行。 | Respawn 标签页(顶部) |
6. 随时随地访问
- 手机/平板电脑——界面经过全面触控优化;扫描桌面端的二维码即可登录,无需输入密码。
- 在网络外访问——运行
./scripts/tunnel.sh start打开 Cloudflare 隧道(请先设置CODEMAN_PASSWORD)。 - SSH——
codeman tui会在终端中打开全屏仪表板(运行codeman tui --list查看列表,运行codeman tui 2直接连接到一个会话)。
7. 运行与维护
- 应用设置 — 模型、工作量、权限启动模式、主题/皮肤、终端字体系列和字重、入口和磁贴动画(独立的 动画 区域)、通知(可调整 Toast 和浏览器通知的显示时长)、显示开关、各 CLI 的选项、同步的自定义显示名称,以及按设备设置的英语/简体中文 UI 语言。点击 应用 可保存设置而不关闭设置页面。
- 在后台运行 —
codeman web -d会让进程脱离 shell 运行(--status、--stop);codeman service install会将其安装为 systemd 用户单元/macOS LaunchAgent,使其在重启后仍能运行。两种方式都会在报告成功前验证服务确实有响应,并且都会阻止同一数据目录启动第二个服务。请参阅在后台持续运行。 - 自我更新 — 通过 Git 克隆安装的版本可在 应用设置 → 系统 → 更新 中原地更新。
- 部署你自己的更改 — 请参阅开发。
⚠️ 安全提示: 如果你正在 Codeman 管理的会话中工作(
echo $CODEMAN_MUX→1),切勿直接运行tmux kill-session/pkill claude;请使用 Web UI 或./scripts/tmux-manager.sh。
零延迟输入浮层
通过远程方式(VPN、Tailscale、SSH 隧道)访问编码 Agent 时,每次按键通常都需要 200-300ms 才能完成往返。Codeman 实现了一个受 Mosh 启发的本地回显系统,无论延迟多高,输入都能即时响应。
xterm.js 内部的像素级 DOM 浮层可在 0ms 内渲染按键。后台转发会以 50ms 的防抖批次静默地将每个字符发送到 PTY,因此 Tab 补全、Ctrl+R 历史搜索以及所有 shell 功能都能正常工作。200-300ms 后服务端回显到达时,浮层会无缝消失,由真实的终端文本接替,整个过渡过程悄然完成。
- 不受 Ink 重绘影响的架构 — 浮层作为
<span>位于.xterm-screen内的 z-index 7 层,完全不受 Ink 持续重绘屏幕的影响(此前两次尝试使用terminal.write()都失败了,因为 Ink 会破坏注入的缓冲区内容) - 匹配字体的渲染 — 从 xterm.js 计算样式中读取
fontFamily、fontSize、fontWeight和letterSpacing,使浮层文本在视觉上与真实终端输出无法区分 - 完整编辑支持 — 退格、重新输入、粘贴(多字符)、光标跟踪,以及输入超出终端宽度时的多行换行
- 重连后仍可保留 — 未发送的输入会通过 localStorage 在页面重新加载后保留
- 默认启用 — 在桌面端和移动端均可使用,适用于空闲和繁忙会话
已提取为独立库:
xterm-zerolag-input— 请参阅已发布的软件包。
实时 Agent 可视化
实时观察后台 Agent 的工作情况。Codeman 会监控 Agent 活动,并在可拖动的浮动窗口中显示每个 Agent,同时以动画矩阵风格的连接线连回父会话。
- 浮动终端窗口 — 为每个 Agent 提供可拖动、可调整大小的面板,并实时显示活动日志,记录每次工具调用、文件读取和进度更新
- 连接线 — 以动态绿色线条连接父会话与其子 Agent,并在 Agent 启动和完成时实时更新
- 状态与模型徽章 — 以绿色(活动)、黄色(空闲)、蓝色(已完成)指示状态,并用颜色区分 Haiku/Sonnet/Opus 模型
- 自动行为 — 启动时自动打开窗口,完成时自动最小化,标签页徽章显示“AGENT”或“AGENTS (n)”数量
- 嵌套 Agent — 支持 3 层层级结构(主会话 -> 队友 Agent -> 子子 Agent)
多 Agent 工作流运行(“ultracode”)也采用同样的可视化方式:浮动运行窗口会实时跟踪整个工作流,显示各个阶段、每个 Agent 的令牌数,以及每个 Agent 当前使用的工具:
Agent 团队 — 原生支持 Claude Code 的多 Agent 团队(CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1)。TeamWatcher 会轮询 ~/.claude/teams/,将队友与其主会话进行匹配,并将其显示为实时子 Agent 窗口,同时提供团队感知空闲检测——因此,只要队友仍在工作,Respawn Controller 就不会触发。参见 docs/agent-teams/。
Respawn Controller
自主工作的核心。当 Agent 进入空闲状态时,Respawn Controller 会检测到这一情况,发送继续提示词,循环执行上下文管理命令以刷新上下文,然后恢复运行——可完全无人值守地持续运行 24+ 小时。
WATCHING → IDLE DETECTED → SEND UPDATE → /clear → /init → CONTINUE → WATCHING
- 多层空闲检测 — 检测完成消息、通过 AI 检查空闲状态、检测输出静默和令牌数稳定
- 达到用量限制时自动恢复 (需主动启用,默认关闭) — 当 Claude 因订阅限制暂停运行(“You've hit your limit · resets 3pm”)时,Codeman 会解析重置时间,等待到期并额外留出 2 分钟安全缓冲,然后关闭速率限制对话框并发送
continue——这样,夜间运行就能撑过 5 小时的限制窗口,而不会停滞到早上。可识别 Claude Code 的所有限制消息格式,在仍受限制时会重试,可在 Codeman 重启后继续运行,并在暂停期间暂缓 Respawn 循环,避免/clear清除等待中的对话。可在 Respawn 标签页顶部按会话启用 - 熔断器 — 当 Claude 陷入卡住状态时,防止 Respawn 反复触发(CLOSED -> HALF_OPEN -> OPEN 状态;跟踪连续无进展情况和重复错误)
- 健康评分 — 0-100 分的健康评分,并提供各项组成评分,包括循环成功率、熔断器状态、迭代进度和卡住恢复情况
- 内置预设 —
solo-work(3 秒空闲,60 分钟)、subagent-workflow(45 秒,240 分钟)、team-lead(90 秒,480 分钟)、ralph-todo(8 秒,480 分钟)、overnight-autonomous(10 秒,480 分钟)
Orchestrator 循环
除了单会话重启,Orchestrator 还会将高层目标转化为分阶段计划,并通过多个 Agent 推动计划完成——它是一个按 idle → planning → approval → executing → verifying → (replanning) → completed 运行的状态机。
- 先规划,再执行——根据目标生成分阶段计划,并在执行任何操作前暂停等待批准;你可以提供反馈并拒绝,以便重新生成计划
- 各阶段均设有验证关卡——每个阶段都会在下一阶段开始前进行验证;如果失败,Orchestrator 会重新规划,而不是贸然继续
- 多 Agent 执行——将各阶段分派给团队 Agent/任务队列,协调单个会话无法承担的大型工作
- 崩溃安全——完整状态会保存在
state.json中的orchestrator键下,因此重启后仍会保留 - 通过 UI 或 API 驱动——使用 Orchestrator 面板,或调用
POST /api/orchestrator/start→/approve→/status(10 个端点)
多会话仪表板
运行 20 个并行会话,并全面掌握会话状态——实时 xterm.js 终端,帧率达 60fps;按会话跟踪令牌用量和费用;通过标签页导航;并支持一键管理。
平铺网格
在一个窗口中并排查看和操作多达 六个会话。点击标题栏中的 Tiles(或按 Ctrl+Shift+G),会话就会以实时终端网格的形式打开:每个平铺都能接收你的按键输入,标题栏还会显示其 Agent 的徽标、模型和状态。右键点击 Tiles 可选择 2、4 或 6 个平铺;拖动平铺的标题栏即可移动它。再次点击 Tiles 即可返回单会话视图。仅限桌面端(窗口宽度约为 1180px 或更大)。完整指南:平铺网格。
- 优先显示重要会话:如果尚未设置网格布局,它会优先填入正在运行的会话,其次是等待你处理的会话,然后是最近使用的会话,并且始终包含当前会话。
- 保留布局:设置好网格布局后(包括各会话所在位置、空单元格、平铺数量、分隔线尺寸、焦点所在平铺和缩放平铺),点击 Tiles 按钮即可精确恢复;网格打开时重新加载页面也会恢复布局。
- 平铺动画 (可选启用):在 App Settings → Animations → Tile Animations 中启用后,打开网格时会播放动画:CRT(各平铺依次如热线般亮起,效果如上方 GIF 所示)、Fly from tab、Deal、Beam down、Cascade、Pop 或 Soft。减少动态效果模式下不会播放动画。
- 滚动方式与主终端相同:鼠标滚轮可滚动平铺中的全屏 Claude 对话,Codex 平铺则会翻阅其记录;按住
Shift并滚动可浏览平铺的本地历史记录。 - 分离平铺 (Beta,可选启用):启用 App Settings → Appearance → Detach Tiles 后,将平铺的标题栏拖出浏览器,即可在独立窗口中弹出;将它拖到另一个 Codeman 窗口的平铺上,即可移至该窗口。
- 免手动操作:启用手势浮层后,可捏合并拖动平铺到另一个平铺上以交换位置,拖到空单元格以移动,或将标签页拖到网格上以添加。
持久化会话
每个会话都在 tmux 中运行——即使服务器重启、网络中断或机器休眠,会话也能保留。启动时会自动恢复,并采用双重冗余。幽灵会话发现功能可查找孤立的 tmux 会话。受管理的会话会添加环境标签,因此 Agent 不会终止自己的会话。
会话管理器与命令面板
按下 Ctrl/Cmd/Alt+K 可打开模糊搜索会话面板;浏览所有会话可打开会话管理器:这里会以去重列表显示 Codeman 知道的所有会话(活动会话、来自状态和生命周期历史记录的过往会话,以及 Claude 转录记录),每行显示会话的首条和最近一条提示词。
- 固定:固定会话可将其置顶。即使终止会话,被固定的会话也会保留(会降级为轻量级的已停止条目,仍然可见且可恢复)。
- 保留名称:恢复过往会话时,会保留其原名称,而不是生成新名称。
- 跨设备标签页顺序:拖动重新排序的标签页会保存到服务端,因此你在桌面端设置的顺序也会同步到手机。
根据主机名设置窗口标题
如果在多台主机(笔记本电脑、开发机、NAS)上运行 Codeman,浏览器标签页标题会显示为 codeman:<hostname>,无需点击即可辨别每个标签页连接的是哪个后端:
codeman web # codeman:<os.hostname()>
codeman web --title-hostname dev-box # codeman:dev-box (manual override for noisy hostnames)
标题会在服务端首次发送 HTML 字节时填入,因此从首次渲染开始就是正确的,而且无需 JavaScript。相同的主机名前缀也会应用到标签页闪烁格式(⚠️ (N) codeman:<host>)和操作系统级桌面通知(codeman:<host>: <event>),因此系统通知中心中的跨主机提醒也一目了然。
智能令牌管理
| 阈值 | 操作 | 结果 |
|---|---|---|
| 110k 个令牌 | 自动执行 /compact | 汇总上下文,继续工作 |
| 140k 个令牌 | 自动执行 /clear | 使用 /init 重新开始 |
标签页提醒
每个标签页都会一目了然地显示其状态。运行中的会话会保留绿色状态点。会话停止并等待输入时,其标签页会变为黄色:圆环保持稳定、背景带色调、显示黄色圆点,并叠加缓慢的呼吸光效。权限提示或问题阻塞 Agent 时,标签页会变为红色并更快地闪烁。底色不会闪灭,因此即使只是瞥一眼(或查看截图),也能看出真实状态;选中标签页时圆环仍保持可见;重新加载页面后,服务器会重新启用待处理提醒,因此被阻塞的会话绝不会藏在看起来刚刚加载的标签页后面。
通知
会话需要关注时会发出实时桌面提醒——permission_prompt 和 elicitation_dialog 会触发红色标签页闪烁,idle_prompt 会触发黄色闪烁。点击任意通知即可直接跳转到相关会话。每个案例目录都会自动配置相应钩子。
运行摘要
点击任意会话标签页上的图表图标,即可查看所有事件的时间线——包括重新生成周期、令牌里程碑、自动压缩触发、空闲/工作状态切换、钩子事件、错误等。
零闪烁终端
基于终端的 AI Agent(Claude Code 的 Ink、OpenCode 的 Bubble Tea)会在每次状态变化时重绘屏幕。Codeman 实现了 6 层防闪烁处理流程,让所有会话都能流畅地以 60 fps 输出:
PTY Output → 16ms Server Batch → DEC 2026 Wrap → SSE → Client rAF → xterm.js (60fps)
更多功能
- 后台守护进程与服务安装 —
codeman web -d会在后台启动服务器,并使用 pidfile、~/.codeman/web.log和经验证的启动流程(它会轮询服务器,直到收到响应,因此端口冲突绝不会被误报为成功);codeman service install会写入 systemd 用户单元(Linux)或 LaunchAgent(macOS),并将 shell 的 PATH 写入其中,因此 nvm 或 Homebrew 安装的node、tmux和claude都能被找到。密钥绝不会写入单元文件 - 设置中的诊断 — App Settings → System → Diagnostics → Run checks 会在服务器上运行
codeman doctor,并列出 Node、tmux、每个 Agent CLI 以及可选办公工具的版本、路径和安装提示。除了PATH,它也会检查各 CLI 通常的安装目录(~/.local/bin、~/.npm-global/bin等),因此在PATH精简的服务环境下也能找到大多数安装。多用户模式下仅限管理员使用。 - 自我更新 — 通过 git clone 安装并由 systemd/launchd 管理的实例,可在 App Settings → System → Updates 中原地更新:它会检测最新版本、自动暂存有未提交更改的工作树,并在服务重启期间持续输出构建进度(npm 安装会标记为不可更新)
- 底栏中的 Git 状态 — 默认关闭(按设备设置:App Settings → Header & Panels → Bottom bar → Git status)。底栏右侧的小型指示器可让你快速查看当前会话的仓库状态:
● 3个未提交文件,↑ 2个尚未推送的提交,⚠存在合并冲突,✓所有更改均已提交并推送。点击可打开一个可拖动窗口,列出已暂存、未暂存、未跟踪和冲突文件(按折叠文件夹分组;关闭该设置后则显示为平铺列表),以及未推送的提交;点击文件可查看差异(新文件显示为全部新增,已删除文件显示为全部删除),并可通过 Open file 跳转到查看器。包含多个项目的文件夹会为向下最多两层找到的每个仓库显示一个可折叠区段;打开前全部折叠。只读且离线(Codeman 不会获取或更改仓库);Docker 或远程会话中不显示。 - 将 GitHub 仓库克隆为案例 — 在 Add Case → Clone Repo 中粘贴仓库 URL,Codeman 会将其克隆到
~/codeman-cases/<name>,并将其注册为普通案例,可直接在其中运行 Agent。输入时会预先检查 URL(告知是否可匿名克隆,并为可选的分支/标签字段提供仓库的实际分支和标签),根据 URL 自动填写案例名称,并让你选择 Run 按钮应使用的 CLI。支持通过https://克隆公开仓库;Codeman 绝不会收集或存储凭据 - 在自定义文件夹中创建案例 — 在 Add Case → Create New 中勾选 Create in a custom folder,选择父文件夹(含 Browse)并输入名称,Codeman 就会在该位置创建案例,而不是放在
~/codeman-cases中。目标必须是新建或空文件夹;系统目录、你的主文件夹本身、~/.ssh等凭据目录,以及 Codeman 自身的数据文件夹均不允许使用。多用户模式下仅限管理员使用。 - 多 CLI 支持 — 可在每个会话中运行 Claude Code、OpenCode、Codex、Antigravity、Gemini、Pi、Grok、DeepSeek Harness、OMP 或 GitHub Copilot CLI;环境变量前缀会自动按 CLI 隔离(
CLAUDE_CODE_*与OPENCODE_*、CODEX_*、ANTIGRAVITY_*、GEMINI_*/GOOGLE_*、PI_*、GROK_*/XAI_*、DSH_*/DEEPSEEK_*、OMP_*、COPILOT_*)。参阅docs/opencode-integration.md、docs/pi-integration.md、docs/grok-integration.md、docs/deepseek-integration.md、docs/omp-integration.md和docs/copilot-integration.md - 自定义模型端点 (1.29.0 新增,目前提供 HTTP API) — 将会话的 CLI 指向任意兼容 OpenAI 的端点,而非其原生后端:本地 llama.cpp、llama-swap、Ollama 或 vLLM 主机,或 Azure AI Foundry、OpenRouter 等云端网关。保存一次端点(
POST /api/model-endpoints;其模型通过/v1/models探测),将其应用到会话(POST /api/sessions/:id/custom-model),CLI 就会在该端点上原地重启。已对 Claude、OpenCode、Pi、Grok 和 OMP 进行实时验证;Codex、Gemini 和 DeepSeek 存在已记录的限制,Antigravity 则没有可用机制。后续将加入工具栏选择器。参阅docs/custom-model-endpoints.md - 网页标签页 — 可将 Grafana、Uptime Kuma、Vite 开发服务器或任意仪表板 URL 作为标签页,与会话并排打开(Run 下拉菜单 → Web / URL → Add URL)。仪表板通过 Codeman 自身的源站代理,因此
http://目标可在 HTTPS 手机上打开,也可通过隧道访问;单页应用会在自身路径下路由,重新加载的框架也能自行恢复。Agent 输出的localhost链接会自动作为网页标签页打开。参阅docs/web-tabs.md - Docker 会话 — 在隔离且经过加固的容器中运行案例。在 Create New 中勾选一个选项即可用合理的默认设置启动容器,并在其中运行 Agent;同一案例的多个会话可共用一个容器,也可以将案例连接到你已运行的容器;还可将容器及其工作区导出为可移植的
.tar.gz,以便迁移到另一台机器。参阅docs/docker-cases.md - 远程 SSH 会话 — 将案例指向另一台机器,并在该机器上通过持久化的远程 tmux 运行 Agent:SSH 断开后仍会继续运行、自动重新连接,还能发现并连接主机上已运行的会话;文件预览和下载也通过同一 SSH 连接传输。参阅
docs/remote-sessions.md - Effort 与 Ultracode — 为每个会话设置默认 effort(
low–max),或启用 ultracode(动态多 Agent 工作流)。这只是软默认值,可随时在会话中通过/effort切换。扩展思考预算也可配置 - 语音输入 — 使用 Deepgram Nova-3 听写提示词,或通过此机器的 Claude Code 登录进行听写,无需 API 密钥(App Settings → Voice;可回退到 Web Speech API):切换录音、静音后自动停止、实时音量指示(
Ctrl+Shift+V) - 图像输入 — 直接将图像粘贴或拖放到会话中
- 手势控制 (可选启用) — 基于 MediaPipe 手部追踪的叠加层,可免手操作地抓取/拖动会话窗口和捏合按钮。使用
CODEMAN_GESTURE=1并前往 App Settings → Terminal & Input 启用 - 多显示器跨屏 (macOS) — 单击即可打开一个横跨所有显示器并最大化的浏览器窗口,让浮动的 Agent/手势面板可以跨越物理边界
- 文件查看器按钮 (可选启用) — 通过一个标题栏按钮轻点即可切换内置文件浏览器面板;在 App Settings → Header & Panels → Header buttons 下启用
- HTML 报告以页面形式打开:点击 Agent 输出的
.html路径(如测试报告、覆盖率页面或仪表板),文件查看器会将其作为真实页面显示,并加载其文件夹中的脚本、样式、图像和数据文件;Page 切换按钮可切换到源码及其 Edit 按钮。页面在沙箱中运行并使用不透明源站,因此无法读取 Codeman 的 Cookie、调用 Codeman 的 API 或读取自身文件夹以外的文件。网络访问保持开放,因此从 CDN 加载 Chart.js 或字体的仪表板可以像从磁盘打开时一样工作。宽泛目录(/、你的主文件夹、/tmp)会被拒绝,因此请为报告单独创建一个文件夹。在终端中点击.md路径也会打开渲染后的内容 - 可点击路径与文件夹网格:在终端和响应查看器中,写作
~/…、相对于会话文件夹的路径或被终端换行拆开的路径都可以点击,文件夹也一样:点击文件夹会打开其中文件的网格(渲染结果、屏幕截图、报告),可用方向键翻页 - OSC 52 剪贴板:会话中的程序通过 OSC 52 设置剪贴板时(Claude Code 的
/copy、tmux yank、vim),文本会复制到浏览器剪贴板,适用于主终端和每个平铺面板。剪贴板读取请求会被拒绝,重放缓冲区也不会执行复制 - MCP 服务同步 (可选启用):将各已安装 CLI 的用户级 MCP 服务(Claude、Codex、Gemini、OpenCode、Antigravity 和 GitHub Copilot CLI)复制到其他 CLI 各自的配置文件中。仅添加,不会复制你已关闭的服务;Preview 会先显示更改,并将原文件保留为
.codeman-bak。App Settings → Agents & CLIs;多用户模式下仅限管理员使用 - CJK / IME 输入 — 完整支持中文 / 日文 / 韩文输入法组合输入,并将 Ctrl 和 Alt 修饰的导航键传递给 CLI
- 配置备份 — 为保存自定义设置的文件创建带时间戳的副本(设置、CLI 覆盖项、自定义端点、webhook、关联案例、远程和 Docker 主机、已保存的仪表板,以及多用户模式下的账户);启动时及文件变更时都会备份。默认启用,备份到
~/.codeman/backups/config;文件夹位置、保留数量(2–500)和保留时间(天数,0 = 不限)均可设置,并可在 Settings → System 中使用 Back up now 和经过验证的 Restore。清理保留内容时只会删除 Codeman 创建的文件夹,且绝不会删除最新备份。参阅 wiki 页面 - 标题栏中的计划用量 — 显示 Claude 订阅的实时用量(5 小时和每周限额窗口),由 Codeman 在启动
claude时提供的状态栏导出器获取,且绝不会写入你的设置文件;还显示来自 Codex 自身 app-server 的限额,以及 GitHub Copilot 每月高级请求配额(服务器每 10 分钟使用 Copilot 自身的登录令牌向api.github.com查询:默认在安装并登录 Copilot CLI 后启用,关闭 Plan Usage Limits 后即停止查询);按设备设置,桌面端开启、手机端关闭 - 提示词缓存状态:每个 Claude 会话都会在页脚(未使用自定义状态栏时)以及 Session Options → Respawn 中显示提示词缓存是热缓存(
cache:until HH:MM)还是冷缓存,并显示重新缓存的成本以及压缩后的说明。仅供显示;重启后仍会保留 - 按你的方式排列会话列表 — 可选择标题栏条带、带筛选框的左侧边栏,或纵向栏;纵向栏中的详细行会显示创建时间和状态标记,并按活动排序。手机主屏幕和桌面主界面侧栏使用相同顺序。在纵向栏中,Search sessions 会将列表缩小到所有分组中匹配的标签页;即使名称不匹配,有提醒的标签页也会保留显示。命名后的标签页分组可折叠、重排并支持拖放;分组菜单中有 New session,Agent 创建的工作线程会紧跟在其父会话之后(默认关闭的 Spawned tabs follow their parent 会让工作线程随父会话移动)。Add to Focus 可将任意标签页的快捷方式固定到纵向栏顶部的区段中;CLI Logos on Tabs 可按设备关闭
- 终端外观 — 提供七种皮肤,其中四种为浅色;可按设备设置字体系列和字重(捆绑的 JetBrains Mono 支持 100 到 800 的字重),并可选择启用标签页、Agent 窗口、终端面板、连接线和 平铺网格面板的动画;所有设置均位于 App Settings → Animations(含动画试验区)
- 操作系统通知与主机名标题 — 桌面提醒和标签页标题会添加
codeman:<host>前缀,使多主机设置一目了然
隔离的 Docker 会话
在专属的加固 Docker 容器中运行案例,而不是直接在主机上运行 — 实现安全隔离、可复现的工具链和一键移植。
- 一键启动 — 在 新建案例 → 创建新案例 中勾选 🐳 在隔离的 Docker 容器中运行。Codeman 会创建案例文件夹,使用默认设置启动容器,并在其中启动 Agent。无需填写主机、镜像或网络字段。
- 资源模板 — 展开复选框,选择 小型 / 中型 / 大型 / GPU 预设(内存、CPU、GPU),或自行设置。磁盘容量可弹性扩展 — 随着数据流入而增长,没有固定上限。
- 每个案例共用一个容器 — 多个会话可以通过
docker exec进入同一个容器;结束一个会话不会导致其他会话所用的容器被移除。 - 默认加固 — 使用非 root 用户、
--cap-drop ALL、no-new-privileges、PID / 内存限制;绝不使用--privileged或 Docker 套接字;只需一个开关即可启用 密封配置文件(不使用主机凭据,关闭网络)。 - 无缝认证,凭据隔离 — 你的主机 Claude / Codex / Antigravity / Gemini / OpenCode / Pi / Grok / OMP 登录信息开箱即用:启动时会将凭据播种(复制)到容器中,并预先处理好引导和信任提示,因此不会出现登录向导。容器会保留自己的副本,绝不会写回主机凭据存储;仅共享对话记录,导出内容也不会包含机密信息。
- 连接到已运行的容器 — 在 Docker 面板中勾选 连接到现有容器,即可将案例关联到该容器,而不是新建容器。Codeman 只会通过
exec进入容器,不会启动、停止、重启或移除它;一个已接入的容器可以为多个使用不同目录的案例提供支持,复制现有案例会根据同级案例预填表单。在多用户模式下,此操作仅限管理员使用,因为容器挂载目录属于启动容器的用户。 - 迁移到另一台机器 — 将容器的整个环境(工具链 + 工作区)导出为可移植的
.tar.gz文件,在另一台机器上使用docker load加载,然后将其导入新建的案例。 - 持久化 — 重启后重新连接即可回到同一个运行中的 Agent;容器停止或重启后,会根据绑定挂载的对话记录恢复对话。
前置条件:只需安装 Docker(或 Podman)。首次使用时会自动构建 Agent 基础镜像,并将进度实时显示在 UI 中(也可以使用 node scripts/build-agent-image.mjs 预先构建)。完整指南:docs/docker-cases.md。
远程 SSH 会话
将案例指向另一台机器,通过 SSH 在那里运行 Agent,同时使用相同的仪表板、移动端 UI 和自主功能。你的笔记本电脑只是远程主机上某个会话的窗口。
- 经久耐用,设计如此:Agent 在远程主机专用的 tmux 会话中运行,因此 SSH 连接中断、网络切换或笔记本电脑休眠都不会终止运行。重新连接后会回到同一个活动对话。
- 自动重新连接:有界退避监视器会发现 SSH 窗格断开,并在后台重新连接到仍在运行的远程会话(可在设置中关闭;有意终止的会话绝不会恢复)。
- 发现并连接:列出主机上正在运行的
codeman-*会话(由该机器上的 Codeman 启动,或由其他操作者启动),并连接其中一个。你不拥有的已连接会话在关闭标签页时只会断开连接,不会终止。 - 共享会话:多个客户端可以在不同窗口尺寸下连接到同一个远程会话,互不限制;发现列表会显示带客户端数量的“共享”标记。
- 防注入:每条 ssh 命令行都通过统一的 shell 转义构造器传递,主机、路径和身份字段均受架构校验保护。
- 文件也可访问:远程案例中的预览、下载和文本读取都通过同一 SSH 连接进行(先执行一次
realpath+stat探测,再流式读取cat,并支持Range定位),因此点击路径会打开 Agent 所在机器上的文件。文件不会复制到 Codeman 主机;编辑和 Office 预览会返回明确的 400,而不是误导性的 404。 - 完整回滚记录:加载远程会话历史时,会通过一次有界 SSH 往返从远程 tmux 读取,因此重新连接或切换标签页后,会话仍保留完整的回滚记录;历史记录与实时屏幕交界处不会丢失行。
在 新建案例 → 远程 中进行设置(主机、用户、身份文件、可选跳板主机)。完整设计说明:docs/remote-sessions.md。
多用户模式(选择启用)
与一支小型可信团队共享一个 Codeman,让每个人拥有自己的登录账号和工作区。默认关闭——不启用标志时,不会有任何变化。
使用 codeman web --multiuser(或 CODEMAN_MULTIUSER=1)启用。创建首个管理员后,可通过 CLI 或应用设置中的 用户 标签页管理用户:
codeman users add alice --admin # prompts for a password (or --password-stdin)
codeman users add bob # a regular user
codeman users list
- 每用户独立空间 — 每位用户的案例都存放在
~/codeman-users/<name>/cases下;会话、案例、搜索和实时事件均按所有者隔离。管理员可以查看所有内容。 - 可单独撤销的登录账号 — 使用
~/.codeman/users.json中经过 scrypt 哈希处理的密码来管理具名用户;可随时禁用、重置(一次性密码)或删除账号。管理员操作会记录到~/.codeman/admin-audit.jsonl。 - 为普通用户设置更安全的默认值 — 非管理员运行 Claude 时会使用
--permission-mode auto(Anthropic 的分类器防护模式);原始 shell 会话、cronlaunchCommand和跳过权限检查都需要明确授予相应用户权限。
⚠️ 这会隔离工作区,但不会阻止用户访问彼此的文件。 每个会话都以同一个 OS 账号运行,因此蓄意为之的用户 Agent 仍可访问其他用户的文件。如需真正隔离,请搭配使用 Docker 案例,或在不同 OS 账号下运行独立实例。请参阅
docs/multi-user-plan.md和docs/security-architecture.md中的多用户部分。
远程访问 — Cloudflare Tunnel
使用免费的 Cloudflare quick tunnel,即可通过手机或本地网络以外的任何设备访问 Codeman — 无需端口转发、DNS 或静态 IP。
Browser (phone/tablet) → Cloudflare Edge (HTTPS) → cloudflared → localhost:3000
前提条件: 安装 cloudflared,并在环境中设置 CODEMAN_PASSWORD。
# Quick start
./scripts/tunnel.sh start # Start tunnel, prints public URL
./scripts/tunnel.sh url # Show current URL
./scripts/tunnel.sh stop # Stop tunnel
./scripts/tunnel.sh status # Service status + URL
脚本首次运行时会自动安装 systemd 用户服务。隧道 URL 是随机生成的 *.trycloudflare.com 地址,每次隧道重启时都会变化。
持久隧道(重启后仍然运行)
# Enable as a persistent service
systemctl --user enable codeman-tunnel
loginctl enable-linger $USER
# Or via the Codeman web UI: App Settings → System → Remote access → Cloudflare Tunnel
身份验证
- 首次请求 → 浏览器显示 Basic Auth 提示(用户名:
admin或CODEMAN_USERNAME) - 验证成功后 → 服务端发放
codeman_sessionCookie(有效期 24h,有活动时自动续期) - 后续请求通过 Cookie 静默验证
- 每个 IP 尝试失败 10 次 → 触发 429 速率限制(15 分钟后解除)
通过隧道公开访问前,务必设置 CODEMAN_PASSWORD — 否则,任何拥有 URL 的人都能完全访问你的会话。
QR 码身份验证
在手机键盘上输入密码体验很糟。Codeman 通过短时有效的一次性 QR 令牌解决这个问题 — 用桌面设备扫描二维码,手机便会立即通过身份验证。无需密码提示、无需输入,也无需剪贴板。
Desktop displays QR → Phone scans → GET /q/Xk9mQ3 → Server validates
→ Token atomically consumed (single-use) → Session cookie issued → 302 to /
→ Desktop notified: "Device authenticated via QR" → New QR auto-generated
只有隧道 URL(没有 QR 码)的人仍会看到标准密码提示。QR 码是快捷方式;密码则是备用方案。
工作原理
服务端会维护一个轮换池,其中包含短时有效的一次性令牌。每个令牌由一个 256 位密钥(crypto.randomBytes(32))和一个 6 个字符的 base62 短码组成;短码作为 URL 路径中的不透明查找键。QR 码编码的 URL 类似 https://abc-xyz.trycloudflare.com/q/Xk9mQ3 — 短码只是指针,本身并非密钥,因此不会通过浏览器历史记录、Referer 标头或 Cloudflare 边缘日志泄露。
服务端每 60 秒自动轮换为新令牌。为应对你恰好在轮换时扫描的情况,旧令牌会在 90 秒的宽限期内继续有效 — 宽限期过后,令牌即失效。每个令牌只能使用一次:手机成功扫描的瞬间,令牌便会以原子方式被消费,并立即生成新令牌供桌面显示。
安全设计
本设计参考了[“揭秘基于二维码登录的(不)安全性”](https://www.usenix.org/conference/usenixsecurity25/presentation/zhang-xin)(USENIX Security 2025)。该研究发现,排名前 100 的网站中,有 47 个因存在 6 项关键设计缺陷而易受二维码身份验证攻击,这些缺陷涉及 42 个 CVE。Codeman 解决了全部六项缺陷:
| USENIX 缺陷 | 缓解措施 |
|---|---|
| 缺陷-1:未强制单次使用 | 首次扫描时以原子方式消耗令牌——重放攻击始终会失败 |
| 缺陷-2:令牌有效期过长 | TTL 为 60 秒,宽限期为 90 秒,通过定时器自动轮换 |
| 缺陷-3:令牌生成可预测 | crypto.randomBytes(32)——256 位熵。短码使用拒绝采样消除模偏差 |
| 缺陷-4:客户端生成令牌 | 仅在服务端生成——令牌在嵌入二维码之前绝不会离开服务端 |
| 缺陷-5:缺少状态通知 | 桌面通知:“设备 [IP] 已通过二维码完成身份验证(Safari)。不是你?[撤销]”——实时检测 QRLjacking 攻击 |
| 缺陷-6:会话绑定不足 | 存储 IP + User-Agent 以供审计。通过 API 手动撤销会话。使用 HttpOnly + Secure + SameSite=lax Cookie |
时序安全查找
短码存储在 Map<shortCode, TokenRecord> 中。验证使用 Map.get()——这是基于哈希的 O(1) 查找,不会通过响应时间泄露目标字符串的任何信息。热路径中完全没有逐字符字符串比较,因此彻底消除了时序侧信道攻击。
速率限制(双层)
二维码身份验证有独立的速率限制,与密码身份验证完全分开:
- 每 IP:每个 IP 失败 10 次二维码身份验证后,将触发 429 封锁(衰减窗口为 15 分钟)——计数器与 Basic Auth 失败次数分开,因此输错密码不会消耗二维码尝试额度
- 全局:所有 IP 合计每分钟 30 次二维码身份验证——防御分布式暴力破解。共有 62^6 = 568 亿种可能的短码,而任一时刻只有约 2 个有效,因此无论如何,暴力破解在计算上都不可行
二维码尺寸优化
URL 被刻意保持较短(/q/ 路径 + 6 位短码 = 总计约 53-56 个字符),以使用二维码版本 4(33x33 个模块),而非版本 5(37x37)。较小的二维码在入门级手机上扫描更快——现代设备读取版本 4 只需 100-300 毫秒。与 /qr-auth/ 相比,/q/ 前缀节省了 7 个字节,仅此一项就足以影响二维码版本。
桌面体验
二维码显示通过 SSE 每 60 秒自动刷新一次,SVG 直接嵌入事件载荷中(约 2-5KB)——无需额外的 HTTP 请求,刷新耗时不到 50 毫秒。倒计时器会显示剩余时间。“重新生成”按钮会立即使所有现有令牌失效,并创建一个新令牌(如果你怀疑二维码已被拍照,此功能很有用)。
有人通过二维码完成身份验证时,桌面端会显示包含设备 IP 和浏览器的通知——如果不是你本人,只需点击一次即可撤销所有会话。
威胁覆盖范围
| 威胁 | 无法奏效的原因 |
|---|---|
| QR 截图被分享 | 单次使用:首次扫描后即被消耗。有效期为 60s:攻击者还来不及行动就已过期。桌面通知会立即提醒你。 |
| 重放攻击 | 原子化的单次使用消耗机制 + 60s 有效期。旧 URL 始终返回 401。 |
| Cloudflare 边缘日志 | 短代码是一个不透明的 6 字符查找键,并非真实的 256 位令牌。由于只能使用一次,从日志中重放始终会失败。 |
| 暴力破解 | 568 亿种组合,任一时刻约有 2 个有效组合;双层速率限制会在破解具备统计可行性之前很久就将其阻止。 |
| QRLjacking | 60s 轮换迫使攻击者实时中继。桌面弹窗可即时检测。可自托管的单用户场景使钓鱼攻击不切实际。 |
| 计时攻击 | 基于哈希的 Map 查找,不会泄露字符串比较的计时信息。 |
| 会话 Cookie 窃取 | HttpOnly + Secure + SameSite=lax + 24h 有效期。可通过 POST /api/auth/revoke 手动撤销。 |
对比
| 平台 | 模型 | 对比 |
|---|---|---|
| Discord | 长期有效的令牌,无确认, 曾多次遭到利用 | Codeman:单次使用 + 有效期 + 通知 |
| WhatsApp Web | 手机确认“链接设备?”,约每 60s 轮换 | 轮换机制相当;WhatsApp 还增加了明确确认(对单用户而言,这是可接受的权衡) |
| Signal | 临时公钥,端到端加密通道 | 加密更强,但 俄罗斯国家行为者在 2025 年仍通过社会工程攻击了它 |
完整的设计依据、安全分析和实现细节:
docs/qr-auth-plan.md
安全
Codeman 默认使用 --dangerously-skip-permissions 启动会话,因此,Web UI 按设计就是任何能够访问它的人可用于远程代码执行的入口——整个安全模型的目的,就是控制“谁”能够访问它。(启动权限模式可配置;见下文。)近期的安全加固(v0.9.0 + v0.9.5)封堵了那些会影响自托管开发工具的浏览器驱动攻击路径。完整模型:docs/security-architecture.md。发现漏洞? 请参阅 SECURITY.md,了解私下披露方式和已知限制列表。
网络与访问
- 默认使用环回地址 — 服务二进制文件绑定到
127.0.0.1,仅可从同一台机器访问,因此默认无需密码也能安全使用(引导式安装程序会询问网络访问需求,并为你配置绑定地址和密码)。如果绑定到非环回主机但未设置CODEMAN_PASSWORD,服务会_启动,但会打印醒目的警告_,并提供三种具体的解决方法(设置密码、使用环回地址并通过经过身份验证的隧道访问,或通过--allow-unauthenticated-network明确确认) - 可选身份验证,真实会话 — 通过
CODEMAN_USERNAME(默认值为admin)/CODEMAN_PASSWORD使用 HTTP Basic。验证成功后会签发一个不透明的 256 位codeman_sessionCookie(randomBytes(32))——在服务端验证,而非由客户端签名,因此无法离线伪造(有效期为 24 小时、自动续期,并记录设备上下文审计日志) - 按 IP 限流 — 10 次失败尝试后返回
429和Retry-After(15 分钟后衰减)。即使攻击者持续轰击同一 IP,有效 Cookie 或正确密码也能_立即_恢复访问——这很重要,因为所有隧道流量都共享一个环回 IP。QR 身份验证使用独立的限流器 - 可配置的权限模式 -
--dangerously-skip-permissions只是默认模式。通过应用设置 → Agent 与 CLI → Claude → 启动模式,可以将新会话切换为 Anthropic 的分类器保护型auto模式(提示词较少,需要 Claude Code 2.1.207+)、normal提示模式,或明确的允许工具列表。在多用户模式下,未获授权的用户会被强制使用auto模式;Shell 会话和跳过权限检查则需要针对每位用户单独授权
始终启用的浏览器安全加固(v0.9.5)
以下检查会在每个请求中运行——在身份验证之前,甚至在默认的无密码环回安装中也是如此:
- Host 标头允许列表 → 阻止 DNS 重绑定。 将自定义域名重新绑定到
127.0.0.1时,请求会在任何处理程序运行前被拒绝,并返回403 host not allowed。允许的主机包括:localhost、任何 IP 字面量、绑定主机、.ts.net/.trycloudflare.com/.cfargotunnel.com、当前启用的托管隧道,以及CODEMAN_ALLOWED_HOSTS(在此添加自定义反向代理域名,使用逗号分隔;可填写完整主机名,或以点开头的.suffix子域名后缀) - 跨站 Origin / CSRF 防护。 对于会改变状态的方法(
POST/PUT/PATCH/DELETE),Origin必须通过同一允许列表的检查,否则返回403 cross-site request blocked。允许缺少Origin(因此curl、CLI 和 Claude Code 钩子仍可正常工作);只拒绝存在但不受信任的 Origin,或不透明的nullOrigin - 原始
text/plain请求体。 全局解析器不再将text/plain解析为 JSON,从而封堵 CORS“简单请求”CSRF 攻击途径,避免跨站fetch在无需预检的情况下将 JSON 偷渡到写入路由 - WebSocket Origin 验证。 终端 WS 升级会执行相同的 Host + Origin 检查,失败时以代码
4003关闭连接(防范 CSWSH) - 经 XSS 转义的 Agent 输出。 AI 派生的字符串(工具名称、命令参数、子 Agent 描述)在子 Agent / 活动面板中渲染前,会在每个注入位置进行 HTML 转义
输入、文件和标头
- 经过 Schema 验证的输入 — 每个 API 请求正文都会通过 Zod v4 schema 检查;
CLAUDE_CODE_*/OPENCODE_*/CODEX_*/ANTIGRAVITY_*/GEMINI_*/GOOGLE_*/PI_*/GROK_*/XAI_*/DSH_*/DEEPSEEK_*/OMP_*/COPILOT_*环境变量前缀白名单会限制各 CLI 可接收的设置,而可能重定向 CLI 流量的键(基础 URL、配置目录)会对非管理员用户进行限制 - 路径约束 — 文件路由会在边界检查前执行
realpath(杜绝 TOCTOU);拒绝..、绝对路径,以及解析后指向工作目录之外的符号链接。上限:文本预览 10 MB,原始文件和下载 2 GB(CODEMAN_MAX_DOWNLOAD_BYTES;请求正文以流式方式处理,并支持Range请求,因此该上限是合理性限制,而非内存保护);/api/download会阻止敏感路径(.env、*credentials*、~/.ssh/、.aws/credentials)。SVG/HTML 会以octet-stream类型提供,并设置nosniff和附件标记,因此会下载而非执行。唯一会渲染 HTML 的位置是文件查看器的页面视图:使用独立的/html-view/<capability>/地址,范围限制在文件自身文件夹内,并在Content-Security-Policy: sandbox下提供,不设置allow-same-origin,因此页面具有不透明来源,无法读取 Codeman 的 Cookie,也无法调用其 API;拒绝隐藏文件夹和宽泛根目录(/、主目录、/tmp),并会在注销时撤销相关能力令牌 - 安全标头 —
Content-Security-Policy(default-src 'self',逐一列出所有例外)、X-Content-Type-Options: nosniff、X-Frame-Options: SAMEORIGIN、HTTPS 下的 HSTS,以及仅针对localhost/127.0.0.1/::1反射的 CORS
供应链与隔离
- 依赖项已固定并验证 — 通过 npm
overrides强制将安全敏感的传递依赖升级到已修补版本;每次提交/PR 都会检查锁文件完整性(所有条目均解析到registry.npmjs.org,并带有sha512哈希)。CI 会扫描公共资源中的 NUL 字节,并使用node --check验证 - 多实例隔离 —
CODEMAN_INSTANCE会分别限定 tmux 套接字(-L codeman-<name>)和数据目录(~/.codeman-<name>),确保两个实例不会连接到对方的活动会话
移动端登录使用一次性、有效期为 60 秒的 QR 令牌 — 完整设计请参阅上文的 QR Code Authentication(该设计解决了 USENIX Security 2025 的 QR 登录研究中发现的全部 6 个缺陷)。
终端 UI(codeman tui)
在终端中查看会话的全屏仪表板。状态与 Web UI 相同,因为它是同一服务的客户端:
codeman tui # the dashboard
codeman tui --list # numbered session list, then exit (scriptable)
codeman tui 2 # attach straight to session 2 of that list
会话按 需要你处理 → 正在工作 → 空闲 → 最近 分组,并按等待时间从长到短排序。↑↓/j/k 选择会话,1-9 和 [/] 切换会话,Enter 进入 tmux 窗格(按 F1 返回)。进入窗格后,顶部栏会持续显示会话列表,按 Alt+1-Alt+9 即可切换,无需离开。可直接在列表中按 y/n/数字回应待处理的权限对话框;按 p 发送单行提示词,按 n 开始会话并直接进入该会话,按 x 结束会话(按 y 确认),按 / 搜索,按 g 查看离开期间的摘要,按 ? 查看帮助,按 q 退出。终端宽度小于 72 列时,预览窗格会隐藏并切换为单列列表,因此在手机上的 Termius 中也能正常使用。即使没有运行中的服务,也会以仅支持连接的降级模式启动。
Web UI 仍是主要界面;完整指南请参阅 docs/tui.md。
键盘快捷键
Ctrl 组合键在 macOS 上也接受 Cmd。
| 快捷键 | 操作 |
|---|---|
Ctrl+W | 不是 Codeman 的快捷键:此组合键会传递给终端(删除前一个单词)。关闭会话没有默认快捷键,可在「应用设置」→「快捷键」中绑定 |
Ctrl/Cmd/Option+K | 查找已打开的会话或启动新会话 |
Ctrl/Cmd+Tab | 下一个会话 |
Alt/Option+[ / Alt/Option+] | 上一个 / 下一个会话 |
Alt/Option+1-Alt/Option+9 | 切换到第 N 个标签页(使用实体按键,因此适用于 macOS Option 布局) |
Alt/Option+B | 折叠 / 展开会话侧边栏(仅限侧边栏布局) |
Ctrl+Shift+{ / Ctrl+Shift+} | 将活动标签页向左 / 向右移动 |
Ctrl/Cmd+C | 复制选区;未选择内容时则中断操作 |
Ctrl+Shift+C | 复制选区(不会中断操作) |
Ctrl/Cmd+V | 粘贴,或上传剪贴板中的图像并粘贴其路径 |
Ctrl/Cmd+L | 清空终端 |
Ctrl+Shift+R | 恢复终端大小 |
Ctrl+Shift+V | 切换语音输入 |
Ctrl+Shift+G | 打开或关闭平铺网格 |
Alt+Shift+Arrows | 聚焦左侧、右侧、上方或下方的平铺 |
Ctrl+Shift+Arrows | 将聚焦的平铺移动一个位置(移入空单元格,或与其他平铺交换) |
Alt+Shift+Enter | 放大聚焦的平铺,或恢复网格 |
Ctrl/Cmd + / - | 字体大小 |
Ctrl/Cmd+? | 键盘快捷键帮助 |
Shift+Enter | 插入换行符(发送到终端) |
Shift+drag | 在鼠标事件会传递给 CLI 的面板中选择文本 |
| 右键单击 | 复制选区(未选择内容时保留原生菜单) |
Shift+Wheel | 滚动本地回滚缓冲区,同时将滚轮事件传递给 CLI |
Ctrl+Z | 在 Agent 会话中会被拦截,以防正在运行的 CLI 被挂起;在 shell 中则执行正常的作业控制 |
Escape | 关闭面板和模态框 |
通过 Agent 操控 Codeman — 编程指南
本指南适用于无需浏览器即可控制 Codeman 的 AI Agent 和自动化程序:例如启动工作会话的 Agent、CI 机器人,或在 Codeman 会话中运行并协调其他会话的 Claude Code。UI 中的所有操作都通过 HTTP 和 CLI 实现,因此 Agent 也可以完成这些操作。
Agent 技能(从这里开始)
本节中的所有内容也以 Agent 技能 的形式提供,位于 SKILL.md 格式的 skills/codeman 中,Claude Code、Codex、Gemini CLI、OpenCode、Grok、OMP 以及大多数其他 Agent CLI 都能读取这种格式。安装一次后,就再也不必把 API 文档粘贴到提示词中了。只需用简单的英语说出你的需求,Codeman 会话中已经运行的 Agent 就会加载这些操作指南并自行调用 API。完整指南包含所有安装方式、录屏,以及它会和不会自动执行的操作:Codeman 技能。
第 1 步:安装
| 方式 | 命令 | 适用范围 |
|---|---|---|
| Skills CLI | npx skills add Ark0N/Codeman --skill codeman -g | 全局安装,适用于任何支持技能的 Agent(skills.sh);这是将技能提供给 pi 的方式 |
| Claude Code 插件 | /plugin marketplace add Ark0N/Codeman then /plugin install codeman@codeman | 通过 Claude Code 插件管理器全局安装;/plugin update codeman 可跟进版本更新。选择此方式或 codeman skill install,不要同时使用:同时安装后,Claude Code 会将技能列出两次(codeman 和 codeman:codeman) |
| Bundled CLI | codeman skill install | 全局安装(~/.claude/skills/codeman),适用于从未克隆过仓库的 npm 安装 |
| Bundled CLI | codeman skill install --case <name> [--mode <mode>] | 仅适用于一个案例;--mode codex(或其他任何运行模式)会将其写入该 CLI 查找技能的位置 |
| Web UI | App Settings → Agents & CLIs → All agent CLIs → Codeman Agent Skill | 创建会话时自动注入到每个案例中,写入该会话的 CLI 查找技能的位置:Claude Code 使用 .claude/skills/,Codex、Gemini CLI、OpenCode、Antigravity、Grok、DeepSeek 和 OMP 使用 .agents/skills/;pi 除外,因为它的项目技能会触发信任提示(agentSkillEnabled,SYNCED,默认关闭) |
codeman skill uninstall [--case <name>] 可撤销 CLI 安装(指定 --case 时,会删除该案例中由 Codeman 管理的所有副本,无论它们位于哪个 CLI 的目录中),并且绝不会影响你自行编写的 skills/codeman。
第 2 步:提出需求
这就是全部交互界面。没有 curl,没有端点名称,也没有会话 ID。以下提示词可以直接使用:
| 你说的话 | 技能的操作 |
|---|---|
| “现在有哪些会话正在运行?” | 列出会话名称、模式和状态。只读操作,随时都可以安全询问。 |
“在 myapp 案例中启动一个 shell worker,运行测试套件,并告诉我是否通过。” | 启动会话,等待分割完成标记,读取退出代码,然后清理。 |
| “启动 3 个 worker,分别处理 lint、typecheck 和测试。并行运行,并报告失败项。” | 扇出流程:每项任务启动一个会话,先全部启动,再在各自完成时逐一收集结果。 |
“让一个 claude worker 总结 refactor-auth 中的 src/session.ts,然后关闭它。” | 启动会话,执行就绪检查流程(包括首次运行时的信任对话框),发送并等待,读取干净的转录回答,然后删除会话。 |
| “监视会话 w4,看看它是否卡在权限提示上,并告诉我。” | 等待 blocked 信号,并将问题呈现给你。它绝不会自行回答其他会话的提示。 |
一句简短的话就够了。这里,Claude Code 主会话收到 use codeman to start 5 claude workers, one per TODO item,随后 5 个真正的 Claude Code worker 启动,并排显示在平铺网格中:
第 3 步:无需操作
Agent 会删除它启动的所有会话。工作期间,可以在仪表板中看到标签页出现和消失。有 8 个 worker 时,每个 worker 都会有自己的标签页,并且一条谱系线会从启动它们的主会话延伸过来:
一次真实运行:从开始到结束
你: 启动 3 个 shell worker,并行运行 lint、typecheck 和前端语法检查,然后告诉我哪些失败了。
lint -> 9f2d8e5f dispatched
typecheck -> aff9c691 dispatched 3 tabs appear in the dashboard
syntax -> be9f1f15 dispatched
lint DONE_lint_17909 rc=0
typecheck DONE_typecheck_3409 rc=0 gathered as each one finishes
syntax DONE_syntax_18501 rc=0
deleted 9f2d8e5f, aff9c691, be9f1f15 tabs disappear
这些 DONE_<task>_<random> 字符串是这项技能使用的分割标记技巧,也是它能在没有 hook 的 shell 会话中可靠执行扇出流程的原因:输入的那一行包含 ${M}_17909,因此只有命令真正的输出会包含 DONE_17909。如果标记没有拆分,命令甚至还没运行,标记就会匹配你自己按键输入的回显。
包含的内容
| 文件 | 内容 |
|---|---|
SKILL.md | 安全规则、现成的快速路径(启动 N 个 worker、分配任务并收集结果)以及动词索引。始终加载。 |
reference/verbs.md | 14 个动词的详细说明:就绪状态、发送并等待、标记、中断、清理。按需加载。 |
reference/recipes.md | 8 个实用流程:claude、DeepSeek Harness 和 shell worker、扇出、受阻 worker 监控、消息扇出。按需加载。 |
reference/endpoints.md | 完整的端点表、错误代码、各模式的信号表、容量限制。按需加载。 |
reference/messaging.md | 通过 Claude Code 跨会话消息功能直接与 claude worker 通信。按需加载。 |
其中的每个流程都经过了实时服务验证,注释记录的是实测得出的故障模式,而非猜测。
有两点值得了解
- 它会自行设限。 在 Codeman 会话之外(未设置
CODEMAN_MUX),此技能会拒绝执行,也不会猜测 API URL,因此全局安装不会给无关的 Claude Code 会话带来任何负担。 - 它刻意采取保守策略。 在未收到明确提示时,它只能启动会话、向会话发送提示词,并通过默认拒绝的保护机制删除它在同一对话中创建的会话(必须使用准确的 ID);该机制会拒绝删除 Agent 自己的会话。删除 case(会抹除真实的代码目录)、批量终止、重启/ralph/cron/orchestrator 变更以及写入设置,都必须由你主动要求并指明目标。
⚠️ 重新关闭 agentSkillEnabled 不会移除已注入的副本(创建时进行清理会把该技能从共享同一工作区的其他活动会话中撤走)。请使用 codeman skill uninstall --case <name> 按 case 移除。
本节其余内容介绍手动操作路径:以原始 HTTP 执行相同操作,适用于 CI bot、shell 脚本或任何不支持技能的 Agent。
检测你是否位于 Codeman 内部
CLI 在 Codeman 管理的会话中运行时,会设置以下环境变量——读取这些变量,不要将任何值硬编码:
| 变量 | 含义 |
|---|---|
CODEMAN_MUX=1 | 你位于受管理的 tmux 会话中。绝不要执行 tmux kill-session / pkill claude / pkill tmux——否则会杀掉你自己或同级会话。 |
CODEMAN_API_URL | API 的基础 URL(例如 https://127.0.0.1:3000)。对下方所有调用都使用它。 |
CODEMAN_SESSION_ID | 你自己的 会话 ID。使用它以避免对自己采取操作。 |
CODEMAN_HOOK_SECRET_FILE | hook secret 的路径(受管理的隧道运行期间,/api/hook-event 必须使用此路径)。 |
使用须知(发布前请阅读)
- 输入必须以
\r结尾。 以编程方式发送的输入会作为纯文本处理,只有输入中包含回车符时才会触发 Enter:{"input":"run tests\r"}。没有\r时,文本会停留在会话提示符处,不会提交(而组合使用的wait会在一个尚未开始的轮次中耗尽完整超时时间)。使用useMux时,嵌入的换行符会保留,各行会作为一次粘贴输入,因此"echo A\necho B\r"会在 shell 中运行两条命令;用于重新按下被卡住的 Enter 的检查无法可靠识别多行粘贴,因此请将较长的多行内容写入文件,并告知 Agent 读取该文件。 - 确保输入具有幂等性。 在
POST …/input请求中包含稳定的clientId和单调递增的会话内seq。服务端会去重,因此即使连接中断后重试,也不会重复发送提示词。 - 身份验证。 如果设置了
CODEMAN_PASSWORD,请使用 HTTP Basic 身份验证(用户名为admin或CODEMAN_USERNAME),或使用codeman_sessioncookie。默认的回环安装无需密码。允许缺少Origin标头,因此可以直接使用curl;跨站浏览器来源会被拒绝(CSRF 防护)。⚠️401会返回裸字符串Unauthorized,而不是 JSON 封装,因此将其传给jq会导致解析错误,而不是显示失败信息:解析前请先检查状态码。 - 响应封装。 大多数端点会返回
{ "success": true, "data": … }(错误为{ "success": false, "error", "errorCode" })。少数旧版 GET 请求会返回未封装的正文——请同时处理两种情况(body.data ?? body)。 /api/v1/*是/api/*的稳定别名。- 等待,而不是轮询;不要把超时视为错误。 如果在规定时间内没有事件,等待端点会返回 HTTP
200,并设置wait.timedOut: true。因此,请循环进行较短的等待(默认 60s),而不要发起一次很长的调用,因为隧道会切断空闲连接。wait.timeoutMs会告知服务器实际应用的超时时间(限值为 600s)。 - 只有
claude和deepseek会话会发出stop;codex也会发出blocked。 这些信号来自钩子(Claude Code 自带的钩子,以及 DeepSeek Harness 状态桥接);但codex的blocked例外,Codeman 会在出现批准、提问或信任对话框时从屏幕读取该状态(请在终端中作答)。shell和其他外部 CLI(opencode/gemini/antigravity/pi/grok/omp)只接受idle、working和exit,而 codex 还会发出blocked。对这些会话明确请求stop会返回400;省略until始终安全。⚠️ 在shell会话中,idle只会在启动时触发一次,之后不会再次触发,因此在此类会话中发送并等待只会超时;对于没有钩子的会话,请使用wait-output标记进行同步。 - 没有任何信号会报告“就绪”,因此请明确等待。 新会话会返回
{"signal":"exit","immediate":true}(这表示尚未启动,而不是崩溃),直到其 PID 存在;在新案例中,claude工作进程随后会停留在 CLI 的信任对话框中。此时给出提示后,等待会在约 2s 后因idle而结束,看起来与轮次完成一模一样,但文本仍卡在对话框中。下方的配方 2b 提供了避免此问题的操作顺序。
操作示例
# CODEMAN_API_URL is auto-set inside every Codeman session, correct scheme included.
# The fallback below fits a stock install; on a --https install set the https:// URL
# yourself and add -k to each curl (self-signed cert).
API="${CODEMAN_API_URL:-http://127.0.0.1:3000}"
# (add -u admin:"$CODEMAN_PASSWORD" to each call if a password is set)
# 1. See what's running
curl -s "$API/api/sessions" | jq '.data // .'
# 2. Spin up a worker session (a "case" = named working dir)
curl -s -X POST "$API/api/quick-start" \
-H 'Content-Type: application/json' \
-d '{"caseName":"refactor-auth","mode":"claude","effort":"high"}' | jq
# 2b. Wait until that worker is actually READY (see rule 8): composer marker first,
# first-run trust dialog only as the fallback. (Probing trust first and sending
# a blind Enter misfires on re-runs: the dialog text stays in the buffer forever,
# so the probe matches stale text and the Enter lands in a ready composer.)
# Match single tokens: TUI text can reach the matcher without its spaces.
until [ "$(curl -s "$API/api/sessions/$SID" | jq '.data.pid')" != null ]; do sleep 1; done
R=$(curl -sG "$API/api/sessions/$SID/wait-output" --data-urlencode 'match=bypass' \
--data-urlencode 'from=buffer' --data-urlencode 'timeout=5000')
if ! jq -e '.data.wait.matched' <<<"$R" >/dev/null; then
T=$(curl -sG "$API/api/sessions/$SID/wait-output" --data-urlencode 'match=trust' \
--data-urlencode 'from=buffer' --data-urlencode 'timeout=2000')
jq -e '.data.wait.matched' <<<"$T" >/dev/null && \
curl -s -X POST "$API/api/sessions/$SID/input" -H 'Content-Type: application/json' \
-d '{"input":"\r","useMux":true}' # accept the first-run trust dialog
curl -sG "$API/api/sessions/$SID/wait-output" --data-urlencode 'match=bypass' \
--data-urlencode 'from=buffer' --data-urlencode 'timeout=45000' >/dev/null
fi
# 3. Send a prompt into a session (exactly-once: clientId + seq)
curl -s -X POST "$API/api/sessions/$SID/input" \
-H 'Content-Type: application/json' \
-d '{"input":"Run the test suite and summarize failures\r","useMux":true,"clientId":"agent-1","seq":1}'
# 4. Send a prompt and BLOCK until that turn is done (registers the wait before
# writing, so it can't answer with the previous turn's idle state)
curl -s -X POST "$API/api/sessions/$SID/input" \
-H 'Content-Type: application/json' \
-d '{"input":"Run the test suite and summarize failures\r","useMux":true,
"clientId":"agent-1","seq":2,"wait":"stop,exit","waitTimeout":60000}' \
| jq '.data.wait' # -> {"signal":"stop","timedOut":false,"waitedMs":41230,...}
# (`stop` is the definitive end-of-turn hook. Adding `idle` makes it resolve on a
# spinner pause too, and on anything that redraws a ❯ prompt — like a dialog.)
# 4b. Timed out? That's a 200, not a failure. Loop over short waits.
curl -s "$API/api/sessions/$SID/wait?until=stop,exit&timeout=60000" | jq '.data.wait'
# 4c. Or wait for a marker in the output (works for shell sessions too).
# ⚠️ Unique per call (tmux repaints replay old screen text), and SPLIT so the
# typed line never contains it: your own keystrokes echo into the output
# stream, so an unsplit marker matches before the command has run. from=buffer
# catches a marker that printed before the wait landed.
N=$RANDOM
curl -s -X POST "$API/api/sessions/$SID/input" -H 'Content-Type: application/json' \
-d "{\"input\":\"M=DONE; npm test; echo \${M}_$N rc=\$?\r\",\"useMux\":true}"
curl -sG "$API/api/sessions/$SID/wait-output" \
--data-urlencode "match=DONE_$N" --data-urlencode 'from=buffer' \
--data-urlencode 'timeout=60000' | jq '.data.wait'
# 5. Read the answer. claude / codex / deepseek sessions have last-response: it comes
# from the transcript, not the screen, so no TUI frames or repaint noise.
# ⚠️ Poll rather than read once: the transcript lands slightly after the stop
# signal, so a read right after send-and-wait returns often comes back empty.
for _ in $(seq 1 10); do
TXT=$(curl -s "$API/api/sessions/$SID/last-response" | jq -r '.data.text')
[ -n "$TXT" ] && break; sleep 1
done
printf '%s\n' "$TXT"
# 5b. Other modes (shell/opencode/gemini/antigravity/pi/grok/omp/copilot) have no transcript:
# read the terminal. ⚠️ Use terminal?tail=, NOT /output: the latter's textOutput
# is empty for every tmux-backed (i.e. every interactive) session. tail counts
# BYTES, and what comes back is terminal data, ANSI included.
curl -s "$API/api/sessions/$SID/terminal?tail=8000" | jq -r '.data.terminalBuffer'
# 6. Stream live events (session output, agent activity, status)
curl -sN "$API/api/events" # Server-Sent Events
# 7. Schedule recurring work (cron-style job)
curl -s -X POST "$API/api/cron/jobs" \
-H 'Content-Type: application/json' \
-d '{"name":"nightly-deps","agentType":"claude","workingDir":"/home/me/proj",
"promptMode":"inline_text","promptText":"Update dependencies and open a PR",
"inputMode":"typed","scheduleType":"daily","dailyTime":"03:00",
"enabled":true,"concurrencyPolicy":"warn_only"}' | jq
# 8. Inspect background sub-agents and their transcripts
curl -s "$API/api/subagents" | jq '.data // .'
curl -s "$API/api/subagents/$AID/transcript" | jq -r '.data // .'
# 9. Whole-system snapshot (sessions, settings, respawn, stats)
curl -s "$API/api/status" | jq
或使用捆绑的 CLI
相同操作也可通过命令使用(codeman <cmd>,别名见括号中)——在会话内的 shell 工具中使用很方便:
codeman session start -d /path/to/repo # (s) start a session
codeman session list # list sessions
codeman session logs <id> # tail output
codeman task add "fix the failing test" # (t) queue a task
codeman attach <path> # show an attachment card for a local file
codeman tui --list # numbered session list (plain text when piped)
codeman tui 3 # attach to session 3 of that list
codeman agent — 每种 CLI 模式下都可使用的会话间动词
上面的技能会在 Codeman 为每个会话注入的前置代码中使用 curl 和 jq 调用 API。对于无法使用该技能的情况(pi 或 shell 会话、未安装 jq 的机器),相同的环境变量仍然存在(CODEMAN_MUX=1、CODEMAN_SESSION_ID、CODEMAN_API_URL 会导出到每个窗格中),因此 codeman agent 会将相同的动词封装为命令。它是对 API 下所列端点的轻量客户端:不新增路由、不新增传输方式,身份验证和所有权规则保持不变。在某个案例的 AGENTS.md 中加一行即可:"其他会话:codeman agent --help"。
codeman agent ls # sessions; * marks this one
SID=$(codeman agent spawn scratch-1 --mode claude) # quick-start + wait for the composer where the mode has a ready mark
codeman agent send "$SID" 'review src/, then say DONE' --until stop,exit --timeout 300000 # --wait = default signal set
codeman agent read "$SID" # last answer (as the server reads it for that mode)
codeman agent read "$SID" --tail 3000 # terminal tail, ANSI stripped (every mode)
codeman agent send "$SID" 'run the tests, then print WORKDONE followed by _4711' # hook-less modes (opencode, pi, …): ask for the marker in halves …
codeman agent wait "$SID" --match WORKDONE_4711 # … and wait on the joined form, which the prompt's echo never contains
codeman agent interrupt "$SID" # a bare ESC, conversation intact
codeman agent rm "$SID" # any session except this one
这些命令会强制执行而非仅作说明的规则:在 Codeman 会话之外运行时会拒绝执行,且绝不猜测 URL;send 只会发送可打印文本并按下 Enter(例如 Ctrl+C 这样的控制字节在 opencode 中属于 app_exit——ESC 仅用于 interrupt,且绝不会追加 Enter);rm 会拒绝空 ID、无法证明是自身会话的 ID,以及任一方向上的前缀匹配。ID 可以使用 ls 输出的 8 个字符前缀(通过列表解析;前缀不唯一时会拒绝执行,任何动词都要求前缀至少为 8 个字符)。以 - 开头的提示词必须放在 -- 后面(send "$SID" -- "- 修复这个 bug")。发送的提示词回显也会作为输出:如果提示词中原样包含 --match 标记,就会立即匹配,在工作进程开始执行任何操作之前就匹配,因此提示词要分两部分请求该标记。远程会话所在主机休眠时,即发即弃的 send 会返回 buffered(Codeman 唤醒主机,并在窗格恢复后输入一次提示词)或 dropped(超过唤醒缓冲区上限,不会输入任何内容:退出码为 1)。退出码:0 表示已送达/已匹配/已发送信号,1 表示错误,2 表示超时,3 表示工作进程已退出或等待结束但未得到答复(delivered:false、ended:true),4 表示拒绝执行。spawn 只在 stdout 输出 ID(说明文字会输出到 stderr),因此 SID=$(…) 可准确捕获 ID。每个动词使用 --json 时,都会输出信封中的 data。对于没有钩子信号的模式,--until stop 会返回服务器的 400 错误,并原样传递——此时用标记路径(--match)获取答案,与技能中的方式完全相同。
MCP 服务(codeman mcp):通过任意 MCP 客户端驱动 Codeman
codeman mcp 是一个通过标准输入输出通信的 Model Context Protocol 服务,因此任意 MCP 客户端(Claude Code、Claude Desktop、Codex、Gemini CLI、Cursor 等)都可以在 Codeman 内部或外部启动任意已安装的 Agent CLI 中的 Codeman 会话,向其发送提示词、等待其完成、读取其回答并进行清理。与 codeman agent 一样,它是 HTTP API 的客户端:不新增路由,认证和所有权规则保持不变。
# Claude Code
claude mcp add codeman -e CODEMAN_API_URL=https://127.0.0.1:3000 -- codeman mcp
{
"mcpServers": {
"codeman": {
"command": "codeman",
"args": ["mcp"],
"env": { "CODEMAN_API_URL": "https://127.0.0.1:3000" }
}
}
}
# Codex (~/.codex/config.toml): raise the 60 s default tool timeout for long waits
[mcp_servers.codeman]
command = "codeman"
args = ["mcp"]
env = { CODEMAN_API_URL = "https://127.0.0.1:3000" }
env_vars = ["CODEMAN_MUX", "CODEMAN_SESSION_ID"] # Codex passes MCP servers a minimal env; these let it know the Codeman session it runs in
tool_timeout_sec = 120
Claude Desktop、Cursor 和 Gemini CLI 使用 JSON 格式。如果服务设有密码,请将 "CODEMAN_PASSWORD" 添加到 env(或者让它读取数据目录中的 .env)。如果 PATH 中没有 codeman 命令(未通过安装程序运行 Git 检出版本),请使用 node /path/to/Codeman/dist/index.js mcp。
| 工具 | 功能 |
|---|---|
list_sessions | 列出你可以查看的所有会话,包括其运行模式、状态、文件夹,以及这些工具是否可以向其发送提示词 |
start_session | 在某个案例中启动一个新工作器(使用新的临时文件夹或现有案例),可运行任意已安装的 CLI;等待它可以接收提示词 |
send_prompt | 输入单行提示词并按 Enter;可选择等待本轮结束 |
wait_for_session | 等待某个信号(stop、blocked、idle、working、exit)或输出中的指定标记 |
read_output | 读取最后一条回答、完整对话或终端最后的字节 |
interrupt_session | 按一次 Escape:停止当前轮次,但保留对话 |
delete_session | 关闭工作器(其案例文件夹会保留) |
服务会强制执行以下规则,而非仅作说明:
- 绝不猜测服务地址。 URL 来自
CODEMAN_API_URL或--url;若未提供,服务仍会启动并列出其工具,但每次调用都会说明如何配置。 - 只能操作其自身的会话。 发送提示词、中断和删除操作仅限于此服务启动的会话(若在 Codeman 会话内运行,则还包括该会话自己的工作器)。列出、读取和等待操作适用于所有会话。对于希望助手驱动现有标签页的用户,
codeman mcp --allow-any-session可解除此限制。它绝不会操作其自身运行所在的会话。 - 等待时长适配客户端。 默认等待 45 s(Codex 默认会在 60 s 后终止 MCP 工具),上限为 600 s;
timed_out/still_working表示需要再次调用。 - 支持两个协议版本。 支持 2026-07-28 修订版(每个请求的
_meta、server/discover),以及 2024-11-05 至 2025-11-25 版本的initialize握手。
Hooks(事件流向 Codeman)
Codeman 会注册 Claude Code hooks,并通过 POST /api/hook-event 发送事件(permission_prompt、idle_prompt、stop、task_completed 等),使控制面板能够实时响应。此端点在回环地址上免认证,但通过托管隧道访问时,需要提供 X-Codeman-Hook-Secret 请求头(从 $CODEMAN_HOOK_SECRET_FILE 读取)。通常无需手动调用此端点——Codeman 会自动完成配置——但自治层正是通过它来“了解” Agent 正在执行的操作。
完整的端点列表和请求/响应格式如下。
API
基于 Fastify 的 REST API——25 个路由模块中约有 230 个处理器,另有一个 SSE 流和一个 WebSocket 终端通道。所有响应均使用 ApiResponse<T> 封装({success, data} / {success, error, errorCode});/api/v1/* 是稳定别名。以下为部分代表性内容:
会话
| 方法 | 端点 | 描述 |
|---|---|---|
GET | /api/sessions | 列出全部 |
POST | /api/quick-start | 创建案例 + 启动会话({caseName?, mode?, effort?, envOverrides?}) |
POST | /api/sessions/:id/input | 发送输入({input, useMux?, clientId?, seq?, wait?, waitTimeout?}:clientId+seq = 恰好一次;wait 会阻塞,直到轮次结束) |
GET | /api/sessions/:id/terminal | 读取终端输出(?tail=<bytes>、?full=1);交互式会话的读取路径 |
GET | /api/sessions/:id/output | 解析后的一次性输出(基于 tmux 的会话中,textOutput 为空) |
GET | /api/sessions/:id/last-response | 从转录记录读取的最后一条回答,格式为纯文本(claude、codex、deepseek) |
GET | /api/sessions/:id/wait | 阻塞,直到触发信号(?until=stop,idle,exit&timeout=&fresh=);超时会返回 200 |
GET | /api/sessions/:id/wait-output | 阻塞,直到出现指定字符串(?match=&nocase=&from=now|buffer&timeout=) |
GET | /api/sessions/unified | 统一的实时 + 历史列表(Session Manager)— ?q=&limit= |
POST | /api/sessions/:id/pin | 在 Session Manager 中固定/取消固定({pinned}) |
PUT | /api/session-order | 跨设备同步标签页顺序({order: [ids]}) |
POST | /api/sessions/:id/custom-model | 在已保存的自定义端点上重启会话的 CLI({endpointId, modelId};{clear: true} 会返回原生后端) |
DELETE | /api/sessions/:id | 删除会话 |
Respawn
| 方法 | 端点 | 描述 |
|---|---|---|
POST | /api/sessions/:id/respawn/enable | 使用配置和计时器启用 |
POST | /api/sessions/:id/respawn/stop | 停止控制器 |
PUT | /api/sessions/:id/respawn/config | 更新配置 |
Orchestrator
| 方法 | 端点 | 描述 |
|---|---|---|
POST | /api/orchestrator/start | 根据目标启动编排 |
POST | /api/orchestrator/approve | 批准生成的计划 |
GET | /api/orchestrator/status | 当前阶段 + 进度 |
POST | /api/orchestrator/stop | 停止并清理 |
Cron(计划任务)
| 方法 | 端点 | 描述 |
|---|---|---|
GET / POST | /api/cron/jobs | 列出 / 创建 cron 任务 |
PUT / DELETE | /api/cron/jobs/:id | 更新 / 删除任务 |
PUT | /api/cron/jobs/:id/enabled | 启用 / 禁用 |
POST | /api/cron/jobs/:id/run | 立即运行 |
GET | /api/cron/jobs/:id/runs | 运行历史 |
子 Agent
| 方法 | 端点 | 描述 |
|---|---|---|
GET | /api/subagents | 列出所有后台 Agent |
GET | /api/subagents/:id | Agent 信息和状态 |
GET | /api/subagents/:id/transcript | 完整活动转录记录 |
DELETE | /api/subagents/:id | 终止 Agent 进程 |
系统
| 方法 | 端点 | 描述 |
|---|---|---|
GET | /api/events | SSE 流 |
GET | /api/status | 完整应用状态 |
POST | /api/hook-event | Hook 回调 |
GET | /api/system/update/check | 检查是否有新版本 |
POST | /api/system/update | 自更新(通过 git-clone 安装) |
POST | /api/clipboard | 向所有已连接的浏览器推送文本({text}) |
GET / POST | /api/model-endpoints | 列出 / 保存自定义的 OpenAI 兼容端点(PUT / DELETE /:id;多用户模式下仅限管理员) |
GET | /api/sessions/:id/run-summary | 时间线 + 统计数据 |
想基于 Codeman 构建功能?
docs/extending-codeman.md是集成指南:将自己的 UI 呈现为一个标签页,订阅 SSE 事件流以便在 Agent 需要你时做出响应,通过脚本驱动 Codeman,并了解开始前值得留意的问题。Codeman 有意不提供插件运行时,因此集成只需让你自己的进程通过 HTTP 通信。
架构
flowchart TB
subgraph Codeman["CODEMAN"]
subgraph Frontend["Frontend Layer"]
UI["Web UI<br/><small>xterm.js + Agent Windows</small>"]
API["REST API<br/><small>Fastify</small>"]
SSE["SSE Events<br/><small>/api/events</small>"]
end
subgraph Core["Core Layer"]
SM["Session Manager"]
S1["Session (PTY)"]
S2["Session (PTY)"]
RC["Respawn Controller"]
ORC["Orchestrator Loop"]
end
subgraph Detection["Detection Layer"]
SW["Subagent Watcher<br/><small>~/.claude/projects/*/subagents</small>"]
TW["Team Watcher<br/><small>~/.claude/teams/*</small>"]
end
subgraph Persistence["Persistence Layer"]
SCR["Mux Manager<br/><small>(tmux)</small>"]
SS["State Store<br/><small>state.json</small>"]
end
subgraph External["External"]
CLI["AI CLI<br/><small>Claude Code / OpenCode / Codex / Antigravity / Gemini / Pi / Grok / DeepSeek / OMP / GitHub Copilot</small>"]
BG["Background Agents<br/><small>(Task tool)</small>"]
end
end
UI <--> API
API <--> SSE
API --> SM
SM --> S1
SM --> S2
SM --> RC
SM --> ORC
SM --> SS
S1 --> SCR
S2 --> SCR
RC --> SCR
ORC --> SCR
SCR --> CLI
SW --> BG
SW --> SSE
TW --> SSE
开发
npm install
npx tsx src/index.ts web # Dev mode
npm run build # Production build
npm test # Run tests (same suite CI runs; browser/mobile/perf suites have their own commands)
完整文档请参阅 CLAUDE.md。
社区
如有疑问、需要设置帮助或想分享想法,请前往 GitHub Discussions:问答版块 解答最常见的问题(手机访问、通宵运行、更新),路线图则在 Ideas 中决定。请将 Bug 提交到 issues;报告通常会在一天内得到回复,每次发布都会署名感谢报告者和贡献者。想参与贡献?CONTRIBUTING.md 提供了指引:皮肤、翻译和文档都是很好的首次 PR 项目,而较大的功能则从 Discussion 开始。如果你为自己的设备配置感到自豪,也欢迎在 Show and tell 中分享。
代码库质量
代码库经过了全面的 7 阶段重构,消除了巨型对象、集中管理配置,并建立了模块化架构:
| 阶段 | 变更内容 | 影响 |
|---|---|---|
| 性能 | 缓存端点、SSE 自适应批处理、缓冲区分块 | 终端延迟低于 16ms |
| 路由拆分 | 将 server.ts 拆分为 15 个领域路由模块、身份验证中间件和端口接口 | server.ts 代码行数减少 67%(6,736 → 2,254) |
| 领域拆分 | types.ts → 16 个领域文件,ralph-tracker → 7 个文件,respawn-controller → 5 个文件,session → 6 个文件 | 不再有巨型文件 |
| 前端模块 | 将 app.js 拆分为 18 个模块,涵盖基础设施、领域和功能层 | app.js 核心缩减至 约 3.4K 行 |
| 配置整合 | 将约 70 个分散的魔法数字整合到 10 个面向领域的配置文件中 | 文件间重复项为零 |
| 测试基础设施 | 共享模拟库、12 个路由测试文件、整合的 MockSession | 可通过 app.inject() 测试路由处理器 |
完整详情:docs/archive/code-structure-findings.md
已发布的软件包
xterm-zerolag-input
适用于 xterm.js 的即时按键反馈叠加层。通过立即将输入字符渲染为像素级精准的 DOM 叠加层,消除高 RTT 连接上的感知输入延迟。无依赖,压缩后仅 6.1 kB,支持可配置的提示词检测、CJK/emoji 宽字符,并配有包含 238 项测试的完整状态机。
npm install xterm-zerolag-input
版本管理
Codeman 遵循 SemVer。版本号实际承诺的内容,以及哪些内容属于内部实现(HTTP/SSE API、磁盘状态、实验性功能),详见
docs/versioning-policy.md。如果你编写的脚本依赖
HTTP API,请固定使用确切版本。
许可证
MIT — 详见 LICENSE
跟踪会话。可视化 Agent。控制重启。让它在你睡觉时继续运行。
如果 Codeman 为你节省了时间,点一颗星,能帮助其他人发现它。
欢迎通过 Issues 提交 Bug 报告和功能建议。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。



