04/Documentation
终端
将 Collie 指向 Herdr、tmux、zellij、tuios 或 Tern,各自支持的查询,以及 agent 信标。对 tmux、zellij、tuios 和 Tern 仍属实验性支持;欢迎提交 bug 报告
以下是 Collie 从中读取 sessions 的终端:Herdr、tmux、zellij、tuios 和 Tern。每个 Collie 安装实例驱动一个终端,默认使用 Herdr。本页介绍如何将 Collie 指向其中任意一个终端、各终端可响应的内容,以及 Collie 用于检测窗格中 agent 的 beacon。无屏幕的 durable agent 不是终端,详见 持久 agent。
tmux 和 zellij 将其顶层分组称为 session。Collie 将其显示为一个 space。
将 Collie 指向多路复用器
在 COLLIE_MUX 中指定后端名称,将其指向端点,重启,然后安装 beacon hook。
实验性功能。 tmux 和 zellij(自 1.0 起)已在单台主机上的 tmux 3.6b 和 zellij 0.44.2 上测试。tuios(自 1.15.0 起)已在 tuios 0.8.4 上测试。Tern 由其贡献者在 tern 0.4.5 上进行了探测,这是一个维护者无法运行的封闭测试版。Herdr 是默认且主要支持的后端。征集测试者: 在 AltanS/collie 上提交 issue,标题为tmux: …、zellij: …、tuios: …或tern: …,并注明你的多路复用器、版本、操作系统以及你观察到的现象。
在命令行中指定多路复用器:
COLLIE_MUX=herdr collie start
COLLIE_MUX=tmux collie start
COLLIE_MUX=zellij collie start
COLLIE_MUX=tuios collie start
COLLIE_MUX=tern collie start当默认目标不是所需目标时,设置端点:
# in your .env: ~/.config/collie/.env, or Herdr's plugin config dir on a Herdr
# install. See Configure for the full precedence.
COLLIE_MUX=tmux
COLLIE_MUX_ENDPOINT_TMUX=/run/user/1000/collie-tmux.sock
COLLIE_MUX_ENDPOINT_ZELLIJ=collie-zellij
# only if the binary sits somewhere unusual
# COLLIE_TMUX_BIN=/usr/bin/tmux
# COLLIE_ZELLIJ_BIN=/home/you/.local/bin/zellij| 变量 | 值 | 含义 |
|---|---|---|
COLLIE_MUX | herdr、tern、tmux、zellij 或 tuios | 当前安装实例驱动哪个终端 |
COLLIE_MUX_ENDPOINT_TMUX | /run/user/1000/collie-tmux.sock | 套接字 PATH (tmux -S),因为它包含 / |
COLLIE_MUX_ENDPOINT_TMUX | work | 套接字 NAME (tmux -L work),无 / |
COLLIE_MUX_ENDPOINT_TMUX | 空 | tmux 自身的默认服务器 |
COLLIE_MUX_ENDPOINT_ZELLIJ | collie-zellij | 会话 NAME,不是路径 |
COLLIE_MUX_ENDPOINT_ZELLIJ | 空 | 单个运行中的会话 |
COLLIE_MUX_ENDPOINT_TUIOS | /run/user/1000/tuios/tuios.sock | tuios 守护进程的套接字 PATH |
COLLIE_MUX_ENDPOINT_TUIOS | 空 | $XDG_RUNTIME_DIR/tuios/tuios.sock,否则为 /tmp/tuios-<uid>/tuios.sock |
COLLIE_MUX_ENDPOINT_TERN | /run/user/1000/tern/daemon.sock | Tern 守护进程的 socket PATH |
COLLIE_MUX_ENDPOINT_TERN | 空 | $XDG_RUNTIME_DIR/tern/daemon.sock,否则为 /tmp/tern-<uid>/daemon.sock |
COLLIE_TERN_BIN | /home/you/.local/opt/tern/tern | 仅当 tern 位于非寻常位置时 |
COLLIE_TMUX_BIN | /usr/bin/tmux | 仅当 tmux 位于非标准路径时使用 |
COLLIE_ZELLIJ_BIN | /home/you/.local/bin/zellij | 仅当 zellij 位于非标准路径时使用 |
Herdr 在此处没有端点变量:其套接字为 HERDR_SOCKET_PATH,而不是 COLLIE_MUX_ENDPOINT_ 名称。
该套接字仅为本地套接字,别无其他。保存在 Herdr 中的机器不是 crew 成员,只有 Collie crew 才会将另一台机器的窗格同步到手机上。各个列表的定义及其区别见 Herdr 机器与 crew。
然后重启,安装 beacon 钩子,并在手机可见的位置启动 agent:
collie restart # after every .env edit
collie hooks install claude # once per host; tmux, zellij and tern need it, Herdr gets hook edges
# open a window or a tab for the agent
tmux -S /run/user/1000/collie-tmux.sock new-window -n claude
zellij --session collie-zellij action new-tab --name claude
claude # in that window or tab这些命令的作用
在命令行中设置 COLLIE_MUX 会为当前运行及后续所有运行确定该选择。start 将名称写入 .env,因此稍后运行 collie start 会驱动相同的多路复用器。
如果未设置 COLLIE_MUX,start 会探测 Herdr、tmux 和 zellij,提示选择后端,并将结果写入 .env。完整配置参考请参见 MUX_CONTRACT.md → 将 collie 指向多路复用器。
collie hooks install claude 会安装 Collie 的 beacon 钩子,tmux、zellij 和 tern 都需要这些钩子。它们将窗格暴露为通用 shell,因此没有钩子时,每个窗格都会显示为 bash。
该命令更新 ~/.claude/settings.json 且不改动项目配置(详情见下文)。Claude Code 2.1.301 在运行时会重新加载其 hook。旧版 Claude 请重启。
注意。 在此模式下不需要 Herdr。使用COLLIE_MUX=tmux或COLLIE_MUX=zellij时,适配层仅加载选定的适配器并忽略 Herdr 的套接字。跨 Herdr 配置根目录发现多个 Herdr session 的功能已被禁用(bridge/index.ts)。您无需安装或运行 Herdr,且.env位于~/.config/collie/中,而非插件配置目录。
tmux 说明
COLLIE_TMUX_BIN 通常保持未设置状态。Collie 会检查一系列标准路径,不会读取 PATH,后台服务和 Herdr 动作不会与登录 shell 共享该变量。
注意。 保持套接字路径简短。长度超过约 100 个字符的 Unix 域套接字会连接失败,tmux 会返回error connecting to … (File name too long)。请使用/run/user/<uid>/或/tmp,而不是较深的目录路径。
在低于 3.7 且 window-size 设置为 manual 的 tmux 版本上,创建窗口会导致服务器崩溃。Collie 在此状态下会阻止窗口创建并提示运行 tmux set -g window-size latest;环境要求 列出了测试过的版本。
在启用 automatic-rename 时,tmux 会根据其中运行的程序重命名窗口;Collie 则会改显示该窗口活动 pane 的最后一级文件夹,因为整屏名为 bash 的标签页没有任何意义。你自己命名的窗口将保留该名称。
zellij 说明
如果你的发行版缺少 zellij 软件包,请从 zellij 的 GitHub release 页面 下载二进制文件并放入 PATH 中。
端点留空时,默认使用单个运行中的会话。如果不存在会话或存在多个会话,Collie 会停止运行并报错,而不会随意选择一个。如果具名会话退出,Collie 会按名称报告该会话,而不是切换到活动会话。
Zellij 需要 XDG_RUNTIME_DIR 来定位会话。如果 Collie 报告所有会话均已退出,请检查 systemd 服务是否包含此环境变量 (约定)。
Zellij 会话独立于其初始终端持久存在。使用 zellij -s collie-zellij 创建会话,并使用 Ctrl o d 分离。在无头主机上,zellij attach --create-background collie-zellij 可以直接启动已分离的会话(在 zellij 0.44.2 上验证)。
注意。 Collie 负责管理活动会话,但不会创建或重启它们。
Zellij 0.44 及更高版本会报告每个窗格的目录,因此 zellij 窗格会获得 Files 按钮并显示其分支。较旧的 zellij 不报告目录,其窗格两者皆无。
tern 说明
将 Collie 指向 Tern:
COLLIE_MUX=tern collie start
collie hooks install claude # beacon hooks for agent detectionCollie 将 Tern 会话读取为 space,将 tab 读取为 tab,将 block 读取为窗格。端点是 Tern 守护进程的 socket,默认为 $XDG_RUNTIME_DIR/tern/daemon.sock(或 /tmp/tern-<uid>/daemon.sock)。在 Tern 窗格内,$TERN_PANE 用于标识 block,$TERN_PANE_SOCKET 指向守护进程 socket。
Tern 通过 tern events 报告生命周期事件,从而实现即时的拓扑变更通知。
"Show in terminal" 会将您的 Tern 窗口切换到该窗格所属的 Tern session 和标签页,并聚焦其代码块。由 Collie 创建的标签页或 Tern session 会在后台打开,不会切换您的窗口。
Collie 不会自动检测 Tern,正如它不会自动检测 tuios 一样:请使用 COLLIE_MUX=tern 指定它。超过 128 KiB 的键入文本会被拒绝,因为它是作为单个命令行参数传递的。
durable 说明
您连接的 durable agent 不是终端,也没有屏幕。持久 agent 介绍了如何使用 collie durable attach 连接 durable agent、使用 COLLIE_MUX=durable 单独驱动 durable agent 的旧版形式、访问 durable agent 的两种方式、它在手机端支持的操作,以及当它显示为无法访问时的排查步骤。
tuios 注意事项
tuios 会自行上报 agent,因此不需要信标钩子:
COLLIE_MUX=tuios collie start
tuios integration install claude-code # once, so tuios hears the agent's hooksCollie 从 tuios 守护进程读取 agent 及其状态和对话。等待你的窗格会显示为阻塞状态,当 agent 上报其对话时,窗格的历史记录便会开启。Collie 没有线束适配的 agent 会显示为 shell。
Collie 将每个 tuios 会话显示为一个 space,每个工作区显示为一个标签页,每个窗口显示为一个窗格。包含窗格的工作区会显示为标签页。运行在另一台机器上的窗格不会显示。请将那台机器上的 Collie 指向其自身的 tuios。
端点即为守护进程的套接字。留空则使用 tuios 自身所用的套接字。Collie 通过读取 XDG_RUNTIME_DIR 来查找它,因此请确保服务中包含该变量。在 tuios 窗格内,echo $TUIOS_SOCKET 会打印该路径。
Collie 需要 tuios 0.8.3 或更高版本:守护进程必须发出 workspace-renamed 事件,而 0.8.2 不支持此操作。若守护进程版本较旧,Collie 会将网桥显示为已断开,日志中会说明需要更新的内容。
某些功能在 tuios 上的表现有所不同:
- 新标签页会在编号最小的空闲工作区打开。tuios session 默认有 9 个工作区,因此 Collie 会拒绝打开第 10 个标签页。
- Show in terminal 会移动所有显示该窗格所属 tuios session 的终端,包括 tuios-web 标签页。tuios 无法将终端移至另一个 tuios session。如果没有终端显示该窗格的 tuios session,Collie 将拒绝操作并指出该终端当前显示的 tuios session 名称。
- “新建”页面上的 新建 worktree 开关保持关闭状态,并提示需要 Herdr。
是否生效?
collie doctor # the `mux` check names the multiplexer, its endpoint,
# and whether it answered (durable: the six `durable-*` checks)
# `[bridge] mux: tmux · socket /run/user/1000/collie-tmux.sock`, printed at
# startup; a multiplexer it cannot reach is one warning line more
collie logs
# the herd, as the phone is given it; reads need the pairing token
curl -s -H "Authorization: Bearer $COLLIE_TOKEN" http://127.0.0.1:8787/api/snapshot | head -c 400每次读取都需要配对设备的 token,因此该 curl 调用会发送一个。若没有它,网桥会返回 403 device not paired。要获取用于脚本的 token,请参阅 升级到 1.18.0。collie doctor 在主机上不需要 token。COLLIE_DEVICE_HEADER 仍然只限制写入操作和 Files 视图(配对设备)。
检查手机 UI:仪表板应显示你的 tmux 窗口 或 zellij 标签页,Claude 窗格应识别为 agent 而不是 bash。如果窗格仍显示为标准 shell,请检查下方的 beacon hook 安装情况。
Collie 将 hook 写入 Claude 自身的设置中
$ collie hooks install claude
$ collie hooks status
would install: /home/you/collie/bin/collie beacon emit (this checkout)
/home/you/.claude/settings.json: installed (v1)由于 tmux、zellij 和 tern 将窗格暴露为通用 shell,agent 必须自行声明其存在。这需要将 Collie 的 beacon hook 安装到 Claude Code 的配置中。在 Herdr 上,这些 hook 仅提供 hook edge。
输出引用了此仓库中的 bin/collie 路径。软件包安装使用已安装的二进制文件路径(~/.local/bin/collie 或 ~/.local/share/collie/current/bin/collie)而非带版本的目录,确保链接在更新后依然有效。
Claude 配置更改的行为详情:
- 修改 全局
~/.claude/settings.json以及任何活动的CLAUDE_CONFIG_DIR。项目级.claude/settings.json文件保持不变。 - 注入标记为
# collie-beacon v1且超时时间为 10 秒的 5 hook。现有的 hook 会被保留。hooks uninstall claude仅删除 Collie 条目。 - 除非显式要求,否则不会更改你的 statusLine。 在没有 flag 的情况下,安装不会触动
statusLine。腰带上方模型旁边的上下文圆点依然存在:hook 会读取会话转录,并在会话启动时读取窗口大小。 - 5 小时和 7 天窗口会自动显示。 它们不需要 hook 和 statusLine。当 Claude 窗格打开时,bridge 会读取此机器上的 Claude 登录信息(
~/.claude/.credentials.json或$CLAUDE_CONFIG_DIR/.credentials.json;Mac 上若无文件则读取 Keychain),并请求api.anthropic.com/api/oauth/usage,与 Claude Code 的/usage发起的调用相同。它在窗格出现时、一轮对话结束后(最多每分钟一次)以及每五分钟请求一次。它不存储任何登录信息,绝不刷新它,也不发送到其他任何地方。它会跳过其他人可读的登录文件(权限宽松于0600的任何文件)和已过期的登录信息,Claude Code 会在下一次调用时刷新过期信息。API-key、Bedrock 或 Vertex 会话没有可显示的窗口。Codex 窗格以同样的方式、按相同的时间表从其自身的会话文件中获取,无需读取登录信息。OpenCode Go 和 Grok 默认关闭,直到你通过COLLIE_ACCOUNT_WINDOWS=all或列表(参见 用量窗口)指定它们。COLLIE_ACCOUNT_WINDOWS=0(或[bridge] account_windows = false)会关闭全部,collie doctor会在其account-windows行中说明具体状态。 - 包装 statusLine 是第二种方式。 传入
collie hooks install claude --statusline时,Collie 还会包装你自己的 statusLine,窗口数据直接取自 Claude Code 传给它的内容。如果你更倾向于这种方式而不是读取登录信息,请使用COLLIE_ACCOUNT_WINDOWS=0。它的命令会变成collie beacon statusline …,你的脚本仍会像以前一样运行并输出。Collie 从不添加 statusLine,而hooks uninstall claude会完全还原你的命令。不带 flag 的安装会保留现有的包装并将其指向当前二进制文件。若要移除不再需要的包装,请运行collie hooks uninstall claude,然后运行不带--statusline的collie hooks install claude。不支持 Windows。 - 要修改被包装的 statusLine,请先解包。 运行
collie hooks uninstall claude,编辑statusLine.command,然后再次运行collie hooks install claude --statusline。包装后的命令会通过路径指定 collie 二进制文件,因此如果该二进制文件发生移动,statusLine 在你重新运行安装之前不会输出任何内容。当包装的 statusLine 指向较旧的二进制文件时,collie update会发出提醒。若要手动测试包装器,请在多路复用器外运行它(env -u HERDR_PANE_ID -u TMUX_PANE -u ZELLIJ_PANE_ID …),否则它会向每个正在运行的 bridge 写入读取记录。 - Claude Code 在运行时会重新加载其 hook。 此特性适用于 2.1.301。如果没有 hook edge 发送过来,旧版 Claude 请重启。
- 仅限 Linux。 agent 存活检查依赖于
/proc。其他操作系统不会发出 beacon。 - Beacon 区分多路复用器。 它们会记录当前活跃后端的 pane 和 session 标识符。切换
COLLIE_MUX会使现有的 beacon 失效。旧的 beacon 会一直保留在磁盘上直到被清除,并显示在collie doctor的beacons计数中。 - 如果使用
COLLIE_STATE_DIR,请在 agent 的 shell 环境中导出它。collie beacon emit会直接读取此变量;否则,beacon 将写入默认状态目录,导致 bridge 无法找到它们。
collie doctor 包含一项 beacon-hooks-claude 诊断检查,可指出缺失的 hook 或移动检出后的损坏路径。有关运行时详情,请参阅 Agent beacon。
与 Herdr 相比有哪些变化
下表总结了主要差异。具体规范请参考 MUX_CONTRACT.md。
| Herdr | tmux | zellij | |
|---|---|---|---|
| space 是 | workspace | session | 会话恰好有一个,因此手机会去掉留白条 |
| tab 是 | tab | window | tab |
| pane 是 | pane | pane | 终端 pane |
| 谁来确认 pane 中运行着 agent | Herdr 自身来确认 | beacon,或无 | beacon,或无 |
| 未通告的更改多快能被检测到 | 推送 | 推送 | 按计划轮询计数,上限 12 秒 |
| "在终端中显示" | 是 | 是 | 否,zellij 接受请求且不移动任何内容 |
| 打开 / 重命名 / 关闭标签页 | 是 | 是(在上述 tmux 崩溃情况下会拒绝打开) | 是 |
| 打开 space | 是 | 是 | 否,它创建的会话将对其自身不可见 |
| pane 历史记录 | 来自 Herdr 自身的 pane 记录 | 来自 beacon 的 session key | 来自 beacon 的 session key |
没有活跃的 beacon 时,tmux、zellij 和 tern 会将窗格呈现为原始 shell,并且窗格历史会被标记为不可用,而不是返回空内容。
手机端体验不同的两点
- "synced Ns ago": 此指示器显示在仪表盘顶部,用于展示数据时效。它仅在后端依赖计划轮询时显示,例如 zellij(轮询间隔最长 12 秒)。Herdr 和 tmux 会立即推送状态变更,因此会省略新鲜度徽标。
- "Show in terminal": 此 pane 操作会在活跃的宿主机终端中聚焦选中的 pane。该操作在 在 zellij 上已禁用,因为 zellij 的 focus 命令虽接受指令但不会改变视图状态。
注意。 移动端界面绝不会自动更改主机终端的焦点。只有明确执行“Show in terminal”操作时才会更新显示。浏览仪表板或打开窗格不会影响活动的主机光标 (ADR 0031)。
tmux 使用技巧:重启后恢复你的窗口
claude --resume # reconnects the conversation, not the windowCollie 不存储复用器状态。重启 tmux 服务端会销毁其窗口,导致控制面板变空。标准 tmux 插件可恢复窗口布局和工作目录:tpm 用于插件管理,tmux-resurrect 用于保存会话树,tmux-continuum 用于自动创建快照。
注意。 运行中的 agent 进程不会被保留。恢复后请手动重启 Claude Code。
zellij 使用技巧:重启后没有任何内容需要恢复
zellij -s collie-zellij # start the session
zellij attach --create-background collie-zellij # headless: start it detached
claude --resume # reconnects the agentZellij 没有提供与 tmux-resurrect 等效的功能。终端分离后持久化的会话显示为 (EXITED - attach to resurrect),附加会话会触发重新执行会话命令,因此重启意味着需要使用上述命令之一重新启动会话并在其中启动 agent,然后使用 claude --resume 或 claude --continue 重新连接各个 agent。
注意。 由于附加操作会产生副作用,Collie 不会附加到会话或恢复会话。已退出的会话显示为 不可达,UI 会显示断开连接横幅,而不是空白的会话列表。
Agent 信标(可选,Linux)
beacon 是 agent 在 tmux、zellij 和 tern 上向 Collie 标识自身的方式,在这些环境中窗格通常只显示为通用 shell。
$ collie hooks install claude
$ collie hooks status
would install: /home/you/collie/bin/collie beacon emit (this checkout)
/home/you/.claude/settings.json: installed (v1)Claude Code 设置中的 hook 会运行 collie beacon emit,该命令会写入一个包含 harness 名称、会话和目标窗格的文件。Herdr 原生跟踪此内容。配置详情请参阅 将 Collie 指向多路复用器;本节仅解释其机制。
上面的路径引用了本地检出中的 bin/collie。二进制安装指向 ~/.local/bin/collie,或者在该名称未链接时指向 ~/.local/share/collie/current/bin/collie,如上所述。status 命令不执行任何写入操作。
运行 hooks uninstall claude 仅会移除 Collie 添加的条目。它会修改你的 全局 Claude 配置,而不会修改项目级文件。此功能仅限 Linux:活跃度检查会检查 /proc,且 Collie 不会在其他操作系统上写入 beacon。
Claude 在启动时立即变为可见。由于 hook 会在 SessionStart 时触发,等待输入的打开窗格会显示为空闲 agent 而非 shell。
进程退出时可见性即终止。Collie 在每次检查时都会验证发送方 PID,因此一旦 agent 终止,该窗格会立即报告为标准 shell,而不会停留在未知状态。
Collie 不需要删除 beacon 文件来实现此操作:文件仍保留在磁盘上,collie doctor 会在 beacons 下将其报告为 已过期,下一次 hook 调用会覆盖该文件。
这允许仪表盘按 agent 名称而非 bash 标记窗格。它支持 “需要你”按阻塞状态对窗格排序,并提供告警所需的状态。窗格历史记录也依赖信标来提供日志使用的会话密钥。
Hook edge
这些 hook 还会为每个事件写入一个 hook edge。hook edge 是针对单个窗格的简短记录。例如"已输入提示词"、"当前轮次结束"和"弹出权限确认对话框"。Collie 在所有复用器上都会使用 hook edge,Herdr 亦然。Herdr 能自行命名其 agent。因此在 Herdr 上,hook 仅写入 hook edge,不写入 beacon。
hook 边本身绝不会判定窗格已空闲。每次触发边后,Collie 会在大约 0.7 秒后重新读取屏幕。只有屏幕才能表明输入框为空且没有弹窗。边可以表明轮次正在运行或弹窗已弹出。随后 Collie 会将窗格保持为繁忙状态,直到结束边出现。在十秒内连续三次读取到屏幕空闲,也会结束保持状态。来自子 agent 的 tool 边与该窗格无关,因此绝不会改变 Collie 在该窗格读取到的内容。
从手机发送的内容可能会显示为 Confirmed。当发送后不久 prompt edge 携带了相同文本时,就会发生这种情况。判定窗口为 30 秒,排在轮次之后的排队发送则为 10 分钟。该 edge 仅携带提示词加盐后的哈希值,绝不携带文本本身。
Claude Code 和 Codex 在轮次进行期间接受消息或命令。Collie 会立即键入,harness 在轮次结束后执行。若 harness 无法在轮次期间接收发送内容,该发送则会被暂留。如果消息检测到输入框未处于空闲状态(例如位于弹出层下方、屏幕在 Collie 两次读取之间发生变化,或是探测字符输入失败后 Collie 通过单次 Backspace 将其从重新读取为干净的输入框中删去),也会被暂留。此类消息会在 10 秒内连续 5 次轮询均空闲后发出,或在 Collie 检测到轮次结束后发出。此状态下的命令仍会被拒绝,在您使用“在此处键入”确认过的屏幕上进行的发送也会被拒绝。在没有 profile 的窗格上,发送绝不会被暂留。Collie 会保留文本,并在终端视图底部显示浮动卡片:“已排队。轮次结束时发送。”如果 Collie 无法读取 agent 的版本,卡片会提示该情况并指向 collie doctor:Collie 仅在 agent 报告过的版本上向运行中的轮次键入内容。卡片会显示该文本以及“取消”按钮。轮次结束后,一旦窗格连续两次轮询均为空闲,Collie 就会按先来后到的顺序将其发送。后续的每个暂留发送都会等待其前一个发送所启动的轮次。若未检测到轮次,它会在 10 秒内连续 5 次轮询均空闲后发出。在 pi、OMP 或 Codex 上,暂留的命令会发送 Enter,而在这些环境中 Enter 会直接引导轮次运行。此类命令会一直等待到轮次结束,在 Collie 无法读取版本的 agent 上的任何暂留命令也是如此:要求至少间隔两秒的两次空闲轮询,或者如果 Collie 完全未看到轮次,则要求在 10 秒内进行 5 次空闲轮询。OMP 在轮次期间会立即运行 /goal,因此 Collie 会使用 Enter 立即发送 /goal、/goal pause 或 /goal resume。它们绝不会被暂留,也不会排在其他暂留发送之后。该窗格上后续的消息则会排在暂留内容之后。暂留的文本保留 30 分钟,暂留的命令保留 10 分钟。超时后,该行会显示消息未发送,并提供“重新发送”。对讲机消息在草稿存在时也会被暂留,绝不会键入草稿中,其暂留时间为 60 分钟(Walky talky)。在已有草稿时您主动进行的发送仍会被拒绝,并显示“追加”和“替换”。在 Collie 拒绝、追加或清空草稿之前,它会先键入一个探测字符并将其删除,以确认输入框接收按键;如果屏幕上的输入框不接收按键,发送会被拒绝,且不会删除任何内容。在桌面上聚焦该窗格或调整其大小,让 agent 重新绘制屏幕,然后再次发送。某些命令绝不等待,Collie 会在轮次期间直接拒绝它们。在 Claude Code 上,这些是 /clear、/exit、/quit、/logout、/resume、/branch 以及每一行 !。在 Codex 上,这些是 /quit、/exit、/new、/resume、/logout 以及每一行 !。在 Hermes 上,这些是 /exit、/quit、/clear、/new、/resume 以及每一行 !。暂留的发送在 Collie 重启后依然存在。在发送开始发出之前均可取消,且仅支持在当前机器自身的窗格上取消。存在两个或更多暂留发送时,卡片会显示计数和第一条文本,“显示全部”会列出每个发送及其各自的“取消”按钮。Collie 以纯文本形式将暂留文本保存在磁盘上仅供当前用户读取的文件中(权限 0600)。文本在发出后立即删除,最晚在暂留结束一小时后删除。
Collie 将每个 edge 放置在一个窗格上。该 edge 标明 agent 的进程及其窗格(HERDR_PANE_ID、TMUX_PANE 或 ZELLIJ_PANE_ID)。Collie 会丢弃未标明窗格、标明两个窗格或标明已不存在进程的 edge。随后 bridge 日志会显示一行 surface.edge.dropped。每个原因和进程每分钟最多显示一行。早于 30 秒的 edge,或者不是 edge 的文件,会被计数但绝不记录日志。
哪些 bridge 接收 edge
接收 hook edge 的每个 bridge 在启动时都会在 ~/.local/state/collie/hook-targets/ 中列出自身。设置 XDG_STATE_HOME 后,目录为 $XDG_STATE_HOME/collie/hook-targets/。正常停止时,bridge 会删除其文件。运行中的 bridge 若发现文件丢失,会在两秒内重新写入其文件。hook 会将每个 edge 写入仍在运行的每个已列出 bridge 中。它会删除已不存在的 bridge 的文件。若未列出任何 bridge,hook 会写入默认状态目录。agent 自身环境中的 COLLIE_STATE_DIR 也始终会接收 edge。
窗格信息
手机上的窗格信息显示窗格是否发送 hook edge:
- Hooks: live 表示该窗格中的 agent 发送 hook edge。
- Hooks: none 表示 Collie 没有来自该窗格的 hook edge。hook 未安装,或者 agent 自安装以来尚未发送任何事件。Claude Code 2.1.301 在运行时会加载新 hook。较旧版本的 Claude 请重启。
bridge 在自身重启后仍会保留活跃窗格。bridge 重启后该行保持 "live" 状态。
来自较早版本 Collie 的安装不会为权限对话框发送 edge。collie hooks status 将其显示为 partial。再次运行 collie hooks install claude 进行就地更新。
为手机拦截权限
$ collie hooks install claude --hold-permissions这会在 Claude 的 PermissionRequest 上再添加一个 hook。当 Claude 请求权限时,hook 会暂存该请求并等待你的点击。手机将该请求显示为卡片。点击 是 或 No 会通过 hook 返回给 Claude。Collie 不会为此向窗格发送按键。此安装需要 Claude Code 2.0.45 或更高版本,这是包含此 hook 的首个版本。较旧版本会被拒绝。
- hook 寻找每个运行中 bridge 的方式与 hook edge 相同。 它读取
hook-targets/并与每个活跃的 bridge 一同拦截。以最先响应的为准。其他手机随后会显示 "Another Collie answered"。 - 控制台仍可正常使用。 在终端中回答对话框,手机卡片会显示 "The desk answered first"。此后 Collie 不会采用点击操作。
- 仅 Yes 和 No 通过 hook 传递。 诸如 "don't ask again" 之类的选项保留为屏幕回答。Collie 会在暂存卡片上拒绝该点击。
- 暂存请求的时间限制为 290 秒。 超时后,对话框保留在屏幕上,并变成带有新 ID 的普通卡片。旧的点击绝不会转化为按键。
- 无 bridge,不暂存。 在没有 bridge 监听或发生任何错误时,hook 不打印任何内容。随后 Claude 会照常显示其自带的对话框。hook 绝不会自行回答。
- 卡片显示所呈现的输入内容。 即命令、文件路径或其他按键输入。它会加入有风险的 Bash 标志,以及写入操作存入文件的完整文本。Collie 会丢弃隐藏或翻转文本的字符。显示的输入限制为 1000 个字符,包含写入的文本。Collie 绝不暂存更长的请求:卡片无法完全显示它,因此由屏幕上的对话框来回答。当输入的行数超出文本框显示范围时,卡片会予以提示。
- 被挂起的请求仅拥有显示该请求本身的对话框。 对话框标题必须标明请求的工具。当子 agent 发起请求时,它必须准确显示 "from the ... agent",并指明相同类型的子 agent。输入的每一行都必须按顺序显示在对话框中。当两个暂存请求符合同一个对话框时,没有请求归其所有。任何其他对话框都在手机上保留其自己的卡片。随后该请求在其暂存卡片上等待,且只有来自该卡片的点击才能回答它。在显示新请求后的前 400 毫秒内,卡片不接受点击。如果你用按键回答了另一个对话框,随后 Claude 结束了 hook,暂存卡片会显示是按键回答了它。
- 当 hook 挂起子 agent 的请求时,屏幕不显示对话框。 这适用于 Claude Code 2.1.301。此时挂起卡片是查看该请求的唯一方式,因此它会显示工具和所展示的输入。
- 即使没有手机在查看,后台请求最多也会等待至挂起时限。 随后 Collie 释放 hook,Claude 在屏幕上显示对话框。Claude 2.1.301 不会拒绝它。
- 问题和计划保持为屏幕卡片。
AskUserQuestion和ExitPlanMode从不挂起。
Socket 位于 <stateDir>/hold/sock。其目录权限为 0700,socket 权限为 0600,因此其他用户无法连接。在连接前,hook 会检查 socket、其目录以及状态目录均属于你。它还会检查没有其他人可以写入这两个目录。bridge 仅接收来自其置于窗格中的进程的请求。它会用一行 surface.hold.dropped 丢弃所有其他请求。hook 和设置不携带 token。每张卡片携带工具、所展示输入以及标签的哈希。携带其他哈希的点击会释放 hook 且不返回应答。
当 Claude 读取的设置挂起 hook 时,窗格信息会显示 "holds permissions"。Collie 会读取用户设置、两个项目设置文件以及受管设置。disableAllHooks 会关闭挂起,受管文件中的 allowManagedHooksOnly 也是如此。
不带标志运行 collie hooks install claude 可再次移除挂起。collie doctor 显示有多少个设置文件中的 hook 挂起了权限。
注意。 Beacon 和 hook 边缘不提供控制通道。它们仅改变 Collie 显示 的内容以及何时 读取 窗格。它们无法发送文本、注入按键、重命名窗格、关闭会话或绕过访问控制。威胁模型和省略的字段记录在 ADR 0024 中。权限挂起是唯一的控制通道。手机上的点击会转换为 Claude 对单项权限的应答。有四项机制保护它:Socket 仅归你所有(0700 目录下的 0600 权限),hook 在连接前会检查此项;bridge 仅响应其置于窗格中的进程;点击必须携带工具、所展示输入以及卡片所显示标签的哈希;应答始终只能是人工点击:Collie 从不自行允许或拒绝。
Codex
Codex 有一个外部 hook,即其 notify 命令。当 Codex 轮次结束时,Collie 可以将其用作 hook 边缘:
$ collie hooks install codex
$ collie hooks status
/home/you/.codex/config.toml: installed安装程序会在 $CODEX_HOME/config.toml 顶部写入一行(未设置 CODEX_HOME 时为 ~/.codex/config.toml)。该行位于文件顶部的注释之后:
notify = ["/home/you/.local/bin/collie", "beacon", "emit", "codex"]Codex 仅运行一个 notify 命令。如果你的配置中已指定了一个,Collie 会保留它,安装随之中止并显示提示信息。如果 Collie 无法将该文件作为 TOML 读取,安装会中止并指出该行。Collie 会在首次更改前保留该文件的一份副本。collie hooks uninstall codex 会恢复安装前的完全一致的字节。如果文件由安装程序创建,卸载时会将其删除。已打开的 Codex 可能在重启后才能识别新行。
Codex 在每轮结束时发送一个事件:agent-turn-complete。Collie 将其记为停止边缘,随后的屏幕读取将判定窗格是否空闲。限制如下:
- Codex 不会为审批对话框或新提示发送事件。仅屏幕会显示对话框,手机发送的操作在 Codex 窗格上绝不会显示为 Confirmed。
- Codex 0.163.0 从后台 helper(
codex app-server)运行 notify 命令。Collie 会在/proc中查找具有相同CODEX_HOME和事件目录的 Codex 窗口。这仅限 Linux。 - 同一个
CODEX_HOME上同一目录中的两个 Codex 窗口不会获得边缘。Collie 无法区分它们。它们的窗格仍像没有 hook 时一样通过屏幕更新。 - Codex 还会运行一个短暂的隐藏轮次来命名新任务。该轮次会多发送一个停止边缘,因此窗格会多进行一次屏幕读取。
Collie 发送 Codex 消息时按 Tab。在轮次进行期间,Codex 会将其排队。在 Codex 中,Tab 在空闲输入框中发送消息,在轮次进行期间将其排队。因此 Tab 在两种状态下均适用。Enter 会干预正在运行的轮次,因此 Collie 从不使用 Enter 发送消息。以 / 或 ! 开头的文本是命令。它在空闲输入框中需要 Enter,因为 Tab 会在此处补全 / 命令。在轮次进行期间它需要 Tab,Codex 会像处理消息一样将其排队。Codex 将 ! 文本作为 shell 命令运行。仅当 Codex 显示带有该文本的排队行时,回执才会显示为已排队。
Collie 用单个按键应答 Codex 审批:选项的数字、y 或 Escape。只有 Codex 0.156 的信任提示需要逐步移动光标。此时 Collie 会按方向键,读回光标位置,然后按 Enter。Codex 问题对话框同样接受单个按键,即选项的数字。在 Codex 0.163.0 中,输入数字会立即应答。在最后一个问题上它会发送所有应答。
Harness 配置文件
Collie 在通过手机发送消息之前会检查 agent 的输入框。profile 文件用于描述特定 agent 的该输入框。它指定了输入框的起始和结束位置。它还说明了草稿的外观、发送所用的按键,以及 agent 针对长粘贴所绘制的文本。普通 shell 以及没有 profile 的 agent 仍可接收发送。Collie 无法读取它们的输入框,因此它会不经检查直接键入文本并按 Enter,每次一行。只有最后几行出现密码提示时才会阻止它:Collie 不会在那里键入任何内容,且手机会提供“键入”选项。
| Agent | 轮次进行期间按 Enter | 发送键 | 探测 | 核对目标 |
|---|---|---|---|---|
| OpenCode | 将消息排队 | Enter | 是 | 1.18.33 |
| pi | 引导轮次;Alt+Enter 加入队列 | Windows 上使用 Alt+Enter、Ctrl+Q | 简短文本并发送至轮次 | 1.1.0 |
| OMP | 引导轮次;Ctrl+Q 加入队列 | Ctrl+Q | 是 | 18.4.10 |
| Grok | 未测定 | Enter | 是 | 1.0.41 |
Antigravity (agy) | 未测定 | Enter | 是 | 1.1.17 的屏幕截图 |
| Muse | 未测定 | Enter | 是 | 1.4.7 |
| Hermes(经典 CLI) | 默认中断对话轮次;Hermes 的 /busy 可以使其排队或引导走向 | Enter | 是 | 0.22.2 |
Cursor CLI (cursor-agent) | 将消息排队 | Enter | 是 | 2026.10.16 |
Kiro (kiro-cli) | 引导对话轮次;Collie 会暂存发送直至轮次结束 | Enter | 短文本 | 2.32.0 |
命令(例如 /model)始终配合 Enter 发送。探测发送会先多输入一个字符。Collie 确认该字符落入输入框后将其移除。
- OpenCode 将其输入框绘制为
┃行的列,由一条╹▀▀▀线闭合。Collie 通过这些行定位该输入框。发送到运行中轮次的消息会在记录中等待,并带有QUEUED标记。换行使用 Ctrl+J 输入。Collie 会拒绝超出输入框显示长度的消息,因为无法将其回读。
- pi 在两条分隔线之间绘制输入框,没有提示符。Collie 通过这对分隔线以及 pi 在其下方绘制的状态行来定位它。pi 对话框在相同的两条分隔线之间打开。因此 Collie 从上方的分隔线向下读取按键提示和列表。在 pi 中,Enter 会引导运行中的轮次,但在空闲输入框中按 Alt+Enter 会发送,在轮次中则加入队列。因此 Collie 使用 Alt+Enter 发送,在 Windows 上使用 Ctrl+Q。pi 在输入框上方将排队的消息显示为一行
Follow-up:。高度超过 30 行的输入框不会被识别为输入框。屏幕将被识别为未知状态,发送需要你手动确认。
- OMP 允许您选择其输入框的边框样式,Collie 支持其中的五种。一种是顶部带状态行的开口框。其余包括双实线、无底边实线、中间为空的双实线以及无边框。Collie 会去除 OMP 在提示行右端绘制的提示符。在 OMP 中,Enter 会引导运行中的轮次,而 Ctrl+Q 在空闲输入框上表示发送,在轮次中表示排队。因此 Collie 使用 Ctrl+Q 发送。OMP 会在输入框上方的
After yield块中列出排队的消息。OMP 可以在文本后显示暗色补全。遇到暗色补全的发送会在按下发送键前停止,并将文本保留在输入框中。在开口框中,OMP 对长消息最多只显示最后 17 行。Collie 随后会根据其键入内容的末尾来校验这些行,回执中会注明此情况。“替换”会拒绝填满这 17 行的草稿,因为 Collie 无法看到其开头。不会删除任何内容。
- Grok 绘制一个带有
❯提示行且下方有一行按键提示的圆角框。较长的草稿会在输入框右边缘显示滚动条。这样的屏幕会被识别为无法读取,因此发送需要你手动确认。模型列表在输入框上方打开,并被计为输入框的一部分。只要该列表存在,该窗格就永远不会被识别为空闲。
- Antigravity (
agy) 将其输入框绘制为一条线、一个>行和一条线,并带有? for shortcuts页脚。该轮次在输入框上方显示带有...的微调器行,下方显示esc to cancel。Herdr 将此 agent 命名为agy或antigravity。Collie 将两者都归类在agy下。
- Muse 将其输入框绘制为一条可能带有标签的线、一个
❯行和一条线。空输入框显示灰色提示,Collie 将该提示视为空文本。在输入框下方打开的命令面板会显示为你的草稿。输入框下方的后台任务列表会被识别为未知状态,发送需要你手动确认。运行中的轮次会显示一行带有计时器和esc to interrupt的内容。
- Hermes(经典 CLI;不读取
hermes --tui)将其输入框绘制为一条横线、一个❯行和一条横线。低于 64 列时,输入框下方不绘制横线。指定命名的配置文件会在❯之前显示其名称。换行通过 Alt+Enter 输入:在display.cli_multiline_shortcuts关闭时,Ctrl+J 用于发送消息。输入框最多显示八行。更长的消息无法回读,因此发送会在按 Enter 之前停止。Submit 会直接发送,之后手机端无法确认是否成功发出。Hermes 可能会在你的文本之后以灰色显示上一条消息的剩余部分。这种情况下发送也会在 Enter 之前停止,Submit 仅会发送你输入的内容。模型选择器和命令面板会在转录内容上方打开,在它们下方窗格绝不会读取为空闲。
- 轮次进行中的 Hermes 的行以
☤开头,Collie 根据该标记判断对话轮次。此时 Enter 的行为取决于 Hermes 自身的设置,因此 Collie 绝不会在轮次进行中按下它。轮次进行中的发送会被暂存,并在轮次结束时发出。如果在 Collie 键入时开始了一轮对话,发送会在 Enter 之前停止,文本保留在输入框中。
- Hermes 的问题: 问题的键入回答会打开一个
✎行,来自手机的发送会对其进行回答。暂存的消息绝不会进入该行。它会等待问题关闭,然后作为消息发送。在暂存消息等待期间,新的发送会加入排队,因此若要从手机回答,请先取消暂存的消息。
- Cursor CLI(
cursor-agent)将其输入框绘制为一个▄横线、一个→行和一个▀横线。空输入框会显示灰色提示,“Plan, search, build anything”或“Add a follow-up”,Collie 将该提示视为空文本。!会将输入框转为带有独立提示的 shell 提示符。Collie 将该提示视为文本,因此消息绝不会进入 shell 模式。正在运行的轮次会在输入框上方显示一个微调器行(如Running),并在→行右端显示ctrl+c to stop。Collie 会截断该提示。在轮次进行中按 Enter 会将消息排入输入框上方的follow-ups框中。该框最多显示六行,较长的草稿会滚动显示。Collie 无法回读更高的消息,因此会将键入的文本留在框中且不按 Enter。它的对话框(命令批准、提问、目录信任提示)会替换输入框,导致屏幕被读取为无法解析。在 2026.10.14 和 2026.10.16 通过了实测探测发送。
- Kiro 会按一定规则绘制输入框:状态栏、文件夹、空行以及
›提示行。Collie 仅在该完整画面出现在屏幕上时才输入内容。换行符作为 Ctrl+J 输入。轮次运行期间,提示行显示为Kiro is working。在 Kiro 中,按下 Enter 随后会将文本引导(steer)进该轮次。Collie 不会在运行中的轮次里按下 Enter。Ctrl+S 可在引导与排队之间切换 Kiro,因此 Collie 未指定排队按键。所以 Collie 会在 Kiro 忙碌时暂存发送内容,并在输入框显示为空闲时发送。其配置文件仅在 Herdr 上验证过,未在 tmux 或 zellij 上验证。
构建主机上未安装 Grok、Antigravity 和 Muse。它们的配置文件基于各 agent 保存的屏幕截图。尚未有实际消息通过配置文件发送给它们,因此 Collie 会探测发送给它们的每条消息。尚无人测量过在轮次运行期间按下 Enter 会对它们产生什么效果。因此,当屏幕显示轮次正在运行时,Collie 会拒绝发送,且不输入任何内容。若 harness 未绘制运行中标识,Collie 无法判断,由 agent 决定 Enter 的作用。OpenCode 和 OMP 在高于已验证版本的版本上通过了实际发送测试。Collie 会对它们探测每次发送,直到发送在已验证范围内通过。Hermes(传统 CLI)在 0.22.2 版本上通过了实际发送测试,位于其支持范围内,且仅限 Herdr。Ink TUI(hermes --tui,或启动它的配置)尚未读取;点击此处输入即可发送。该探测尚未在 Hermes 的每个对话中尝试,因此 Collie 也会探测发往那里的每次发送。
高于已验证版本的版本仍可工作,收据显示 provisional。
引导或排队
当 agent 工作时,从手机端发送的内容可以等待该轮次结束,也可以直接插入该轮次。直接点击“发送”会将文本排队,留待本轮结束后处理。这适用于所有 agent。Collie 绝不会意外引导某个轮次。
引导 是你自己的选择,仅针对单次发送有效。按住“发送”按钮并点击 引导。agent 会在当前工具调用结束后、同一轮次中读取该行内容。该操作行仅在 agent 工作时显示,且仅出现在配置文件中包含 steer 按键的 agent 上,例如目前的 pi、Codex 和 OMP。输入框下方有一条简短提示,说明点击为排队,按住为引导。Codex 会将紧跟 Enter 的文本视为粘贴,因此 Collie 会在文本输入后等待一秒,然后再按下 steer 按键。
回执会说明处理结果:
- 已引导。 agent 已将该行内容接入正在运行的轮次。Collie 检测到了 agent 绘制该内容。
- 已改为排队。 尽管你要求引导,agent 仍将该行保留至本轮结束后处理。内容未丢失。
- 已输入,未提交。 文本已在输入框中,但 steer 按键未能将其发送。请点击“发送”,或清空输入框。
- 当前窗格不可用。 agent 的配置文件中没有 steer 按键,Collie 不信任其版本在运行轮次时的表现,或者该文本是一条命令。未发送任何内容。请在不使用“引导”的情况下发送。
- 只有手机端的用户才能进行引导。 来自任何其他来源的引导均被拒绝。
如果轮次在 Collie 输入期间结束,该行内容将作为普通发送处理。Collie 不会暂存引导操作。耗时较长的引导可能会在没有明确迹象的情况下结束。此时回执会提示 Collie 无法确定,且不会再次发送该文本。
agent 发送给另一个 agent 的消息(Walky talky)绝不会执行引导。它始终会等待当前轮次结束。