OPEN SOURCE DEEP DIVE
herdr:编码代理常驻的终端运行时
后台终端服务器:编码代理进程常驻,pane 标 working/blocked/idle,代理经 CLI 与 socket API 互控,会话跨重启恢复。
一句话定位
herdr 是一个为编码代理而生的终端运行时:单个 Rust 二进制、没有 Electron,以后台服务器形态跑在你已有的终端里,托管 Claude Code、Codex、Cursor、OpenCode、Grok 等代理的终端进程。它不包装也不替换任何代理,它接管它们的终端。项目自述只有一句:the runtime your coding agents live on——合上笔记本、断网、重启机器,代理继续工作;从任意终端或 ssh 重新接入,会话还在原处。
项目采用 Apache-2.0 协议,GitHub 星标超过三万五千,2026 年 8 月的 0.8.2 版将 Windows 支持转为正式可用。安装是一条 curl 脚本、Homebrew 或 mise,装完在工作目录里直接运行 herdr 即可启动。
服务器与客户端:终端活在服务器里
herdr 的默认形态是「后台服务器 + 一个或多个附着客户端」。服务器拥有全部 pane 与进程状态,客户端只是附着其上的终端界面。层级分三级:workspace 是顶层项目容器,一个仓库、一个任务或一次调查用一个;tab 是 workspace 内的布局,用来分隔 agents、logs、server、review 这类视图;pane 是真正的终端——herdr 渲染它的输出、把输入送回进程,并在客户端 detach 后保留它。
交互以鼠标为先:点击 pane、tab、workspace 与代理,拖拽分割线,选择文本,右键菜单,都是一等公民;同时保留 tmux 风格的前缀键,ctrl+b q 脱离,herdr 重新接入。键盘与鼠标是两层并列的能力,按当下场景选,而不是按工具选。命名 session 是完全隔离的运行时命名空间,有独立的 pane、socket 与持久化状态,但文档建议优先使用 workspace。
四条持久化路径
文档把状态路径分成四条,写得很诚实。detach 再 reattach 是最强的一条:原进程从不停止,pane、shell、代理、测试与服务都活在服务器里。服务器重启会失去进程,但从快照恢复会话形状:workspace、tab、pane、工作目录、布局与焦点都回来,无法走更强路径的 pane 以保存目录里的新 shell 形式返回。
pane 屏幕历史回放是可选的实验功能:在不恢复旧进程的前提下,于完全重启后恢复最近的终端内容;它默认关闭,因为 pane 输出可能包含密钥、令牌、提示词与命令结果,开启后历史写在 session.json 旁的 session-history.json,文档要求把这个目录当作终端历史对待。原生代理会话恢复默认开启:herdr 利用官方集成上报的会话引用,在服务器重启后重启受支持的代理 pane,只恢复上报过原生会话引用的 pane。更新另有 --handoff 路径:对受支持的运行中服务器做尽力而为的活体交接,成功时进程继续运行、屏幕来自活终端。
基于证据的代理状态检测
herdr 最有辨识度的能力,是每个 pane 都带状态:blocked 表示代理需要输入、批准或决策;working 表示正在运行;done 表示已完成但你还没看;idle 表示已完成或等待且已被看过;unknown 表示无法有信心地分类。侧边栏状态由 workspace 内的代理汇总而来,一眼就能看出哪个项目需要处理——不必再去逐个翻找卡住的那个。
检测是基于证据的,且与终端解析器解耦:检测器只读屏幕快照,从不触碰解析器或视口状态;它明确不用用户可见视口判断状态,因为用户可以滚动它。每个代理有一份 manifest,src/detect/manifests 下二十一个 toml 文件覆盖 claude、codex、cursor、gemini、github-copilot、grok、opencode、qwen、cline、devin、droid、amp、antigravity、hermes、kilo、kimi、kiro、maki、muse、pi、qodercli,把「哪些可见控件是不变量、哪些是替代形态」编码为显式的与或门,禁止匹配整 pane 的偶然文本。改 manifest 必须先用 herdr agent read --source detection 抓取底部缓冲证据;仓库配套抓取与校验脚本,让检测规则成为可测试的工程产物,而不是手调的正则。
为代理而写的控制面
herdr 把代理当作一等用户。CLI 与本地 socket API 共用同一控制面:创建、列出、聚焦、重命名、关闭 workspace 与 tab;分割、交换、缩放、读取 pane 并向其发送输入;列出、读取、提示代理并等待代理;从钩子与插件上报自定义状态;订阅事件、等待输出或状态变化。herdr api schema 能打印随二进制打包的 JSON Schema,覆盖原始请求、成功与错误响应、发出事件与订阅事件。
两个细节说明这套控制面真的是为代理写的:agent prompt 会拒绝向已停在批准或提问对话框前的代理发送文本或回车,直接返回 agent_blocked;agent start 会等待新 pane 的 shell 与首次运行提示就绪,而不是抢跑报告就绪。仓库自带一份 agent 技能(skills/herdr/SKILL.md),第一步是校验 HERDR_ENV=1——不在 herdr 内的代理不允许检查或控制当前会话;并要求以已安装二进制的帮助输出为命令语法权威,禁止用缺参方式试探会执行变更的命令。代理因此可以开 pane、互相提示、等待另一个代理真正阻塞。
终端引擎与性能架构
终端模拟使用 vendored 的 Ghostty VT 引擎(libghostty-vt)加 portable-pty,另有独立的 kitty 图形协议模块;Windows 路径走 ConPTY,在 0.8.2 转为正式可用,Windows 客户端还能用 --remote 附着到 Linux 与 macOS 服务器。无客户端附着的无头服务器使用可配置的 120x40 虚拟终端,而非 80x24。
AGENTS.md 把性能写成架构法:AppState 是纯数据,不依赖 PTY 与异步即可测试,与 PaneRuntime 分离;compute_view 负责几何与变更,render 只取状态绘制、绝不在渲染中改状态;平台行为只住在 src/platform 下按操作系统分立的文件里,核心模块不写目标系统条件编译。凡是从视图计算、渲染、后台 pane 缩放、PTY 解析、检测、客户端帧分发可达的工作,都被视为乘法路径——代价按每字节、每事件、每渲染乘以 pane、tab 与附着客户端数计;pane 尺度循环里禁止收集聚合状态、禁止文件系统 IO、能在标量事实足够时禁止分配,隐藏 pane 仍解析输出但不得仅为保持状态新鲜而触发呈现工作。变更日志里记着对应的修复:繁忙多 pane 会话避免冗余的隐藏 pane 唤醒与全量终端状态格式化,防止高速后台输出造成的 CPU 回归。
生态与发布姿态
插件市场以独立 worker 运行:它在仓库根目录与子目录发现有效 manifest,把同一仓库下的多个插件分组,并发布版本与精确的默认分支提交;插件注册表住在持久化层,与会话快照同命运。官方集成承担两件事:上报用于原生恢复的会话引用,以及让钩子与插件上报自定义代理状态。
发布工程同样重:仓库内有 vendor 校验、文档翻译一致性、配置参考检查、代理检测 manifest 检查、Windows ConPTY 打包与一整套冒烟和性能脚本。文档英、日、中三语并行,README 有简体中文版。对同时跑多个编码代理的人,herdr 的答案不是再做一个代理包装器,而是让终端本身成为运行时:有状态、有证据、有控制面,代理住在里面,而不是被它管着。