Communitygithub.com

royashbrook/waterbear

保持 Claude 远程控制会话永久存活(tmux + launchd),可选择在重启时恢复同一对话,以水熊虫命名。

waterbear 是什么?

waterbear 是一个专为 Claude Code 设计的技能,旨在创建和维持一个持久化的远程控制会话。它通过 tmux 和 macOS 的 launchd 机制,确保 `claude --remote-control` 会话在崩溃、补丁、退出乃至系统重启后仍能自动恢复,并且能够选择性地从磁盘恢复之前的对话,使智能体仿佛从未中断过。该技能尤其适合需要 7x24 小时运行的监控、自动化任务或需要从手机、桌面应用随时访问的智能体场景。它仅运行于单台 macOS 机器上,并会为会话创建一个系统级的守护进程,确保其稳定运行。对于由桌面应用发起的对话,waterbear 也能正确处理,将桌面窗口变为持久化会话的一个远程控制视图。项目还包含了 `doctor` 等工具用于诊断和维护,确保同一会话不会产生多个分身。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add royashbrook/waterbear

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

waterbear 是做什么的?

概述

无限期保持 claude --remote-control 会话的存活。以水熊虫(tardigrade)命名,这种动物在压力下会暂停生命活动,在条件恢复后复活。崩溃、补丁、退出或重启会杀死进程;waterbear 会自主将其恢复,并且(可选)从磁盘恢复之前的确切对话,让智能体像什么都没发生一样继续之前的思考。

何时使用

  • 你想要一个能够承受崩溃/补丁/退出/重启并自动重新启动的会话
  • 你希望它随时可以通过手机/桌面/claude.ai 访问(远程控制)
  • 你希望重启后恢复之前的对话,而不是一个全新的空白对话
  • 有人说“让这个智能体始终在线/持久/不可杀死/永久运行”

不适用于:一次性任务,或者你希望关闭终端时就结束的会话。

运行位置(先读,它绑定于一台机器)

waterbear 将 launchd 的 LaunchAgent + tmux + 一个 claude CLI 进程绑定在一台电脑上。这有一些值得提前说明的后果:

  • 仅限 macOS(使用 launchd)。这种模式可以移植到 Linux/systemd(参见 references/architecture.md),但此安装程序是为 Mac 编写的。它绑定于那台机器和用户,LaunchAgent 是每个用户独立的,并且仅在你登录时持久存在,主体不会跟随你到另一台机器。
  • Claude Desktop 应用:可以工作。桌面端和 CLI 写入相同的磁盘转录记录,因此 CLI 主体能够通过 ID 恢复桌面对话,前提是它在对话自身的工作目录中启动(永不移动的防护措施强制执行这一点)。桌面窗口成为现在持久化会话的又一个远程控制视图。(本文档的一个早期版本声称桌面对话无法恢复;那是错误的,并且已经通过实践证伪。)
  • 云端 / Claude Code on web:不适用,没有本地机器、launchd 或 tmux 来保持存活。waterbear 适用于运行在你自己的计算机上的会话。
  • 认证过期需要交互式重新登录:CLI 运行在你的订阅登录(OAuth)之上,它会定期过期。当它过期时,会话保持存活并在每次请求时显示认证错误,因此它会自我宣告(你可以通过手机或桌面上的远程控制看到它),而不会静默死亡。在机器上运行 claude + /login 即可清除。waterbear 无法自愈(launchd 无法驱动浏览器认证),这在订阅后端下是预期行为,而非缺陷(API 密钥认证可以避免,但会将计费切换为按量付费)。另外,防护机制有一个崩溃循环网络(通知 + 退避),用于处理真正死亡并循环重启的会话,例如错误的恢复 ID 或损坏的状态;过期的登录不会触发它。

如果你不想要一个绑定在你的 Mac 上的始终在线进程,请不要安装。

自我水熊化(最常见情况)

大多数情况下,智能体会自己运行此命令,即“自我水熊化”,使当前对话能够经受重启并自动恢复。默认配置会完成工作:你的当前目录,你的当前会话。

脚本位于此文件旁边的 scripts/ 目录中。如果你只获得了仓库 URL 且尚未在本地克隆,请先克隆它,并且为了使此技能在每个未来会话中都可重用,直接将其克隆到技能目录中:

git clone https://github.com/royashbrook/waterbear ~/.claude/skills/waterbear

然后运行位于 ~/.claude/skills/waterbear/scripts/waterbear-install 的安装程序。最少步骤:

  1. 选择一个简短的内部名称(无空格),通常是你自己的名字(max, sam)。对于 CLAUDE_RC_TITLE,使用人类称呼此对话的名称,他们对它的称呼,而不是你发明的标题。远程控制条目会替换他们在会话列表中的聊天记录,而如果以一个自己选择的新名称回来,会给人一种不同智能体出现而他们的智能体消失的感觉。如果你不知道他们怎么称呼它,问一下,这只是一个问题,而且这是他们的名字,不是你的。
  2. 无需操作:设置 CLAUDE_RC_RESUME=1,安装程序会固定你运行它的那个会话,因此此对话将是恢复的目标。它会打印出是哪个对话。阅读那一行。 如果它说主体将全新启动,请先停下来修复,然后再继续,因为全新启动意味着人类最终会在真正的智能体旁边得到一个全新的空白智能体,这是此工具可能产生的最坏结果。(--no-pin 在你故意不想携带自己的 ID 的罕见情况下存在;如果你使用它,请明确说出来。)
  3. 确保捕获钩子被作为 SessionStart 钩子连接(参见 references/architecture.md 中的“捕获钩子”一节),以便 ID 在每次未来重启时自愈。如果你的项目已经连接了,跳过此步。
  4. 安装恢复模式下的守护进程,默认使用你当前的位置:
    CLAUDE_RC_NAME=<名称> CLAUDE_RC_DIR="$(pwd)" CLAUDE_RC_RESUME=1 \
      bash ~/.claude/skills/waterbear/scripts/waterbear-install
    
    可选:CLAUDE_RC_RESUME_WAKE="<简短的重初始化提示>"(每次恢复后输入,例如重新启动监控/观察器)和 CLAUDE_RC_WAKE="<身份引导>"(仅在没有任何会话需要恢复时使用)。
  5. 进入持久化的主体。它位于 tmux 和 launchd 之下。已经在一个名为 <名称> 的 tmux 会话中? 你现在已经持久化了,无需其他操作。不在 tmux 中? 安装会启动你的持久化 tmux 主体,结束这个会话,这样两者就不会并行运行,然后你在 tmux 主体中继续,恢复此确切对话。

仅在人类想要覆盖默认值时(不同的目录、自定义唤醒提示)才询问。否则,只需设置好自己并确认。

不要移动智能体

CLAUDE_RC_DIR 是智能体当前实际运行的目录,默认值(你当前的目录)几乎总是正确的。不要将其设置为你觉得智能体“属于”的地方,或项目主目录,或你认为是其基础的工作树。那些是你关于智能体的想法;目录是关于它的事实。

失败是静默且彻底的:claude --resume 只能在其自己的项目目录内部找到会话,因此指向其他地方的主体将启动一个全新的对话,人类会在一个窗口中看到他们真正的智能体,而在另一个窗口中看到一个空白的冒名顶替者。安装程序现在会拒绝这种情况,但这只是一个保护网,不是计划。就是不要移动智能体。

自我水熊化:接管是自动的,只说真话

从你自己的会话内部安装会立即启动持久化主体,并且该主体会恢复此对话:相同的会话 ID,相同的单个转录记录,内容会被追加。人类正在查看的窗口是该对话的一个视图,当远程控制注册后,它会赶上进度。不会发生分叉,没有第二个主体,人类也无需先关闭任何东西。

因此,安装后,告诉人类三件真实的事情,并且没有作业:

  1. 完成:此对话现在已持久化,它能承受崩溃、补丁、退出和重启
  2. 窗口可能会闪烁或短暂显示过时的视图,同时远程控制重新注册;底层的对话是磁盘上的一个完整转录记录,滚动回滚比预期短是渲染伪影,而不是丢失记忆
  3. 他们可以从任何地方访问它:他们的手机、桌面应用,或者 tmux attach -t <名称>

对于桌面端发起的对话,需要补充一点(安装程序会检测到并说明)。 桌面端会为对话保留其原生聊天记录,与新的远程控制条目并列。那个原生聊天记录不是一个过时的视图:它是这个智能体的一个活动的第二个副本,如果在那里输入也会回答。移动端会去重这两个表面;桌面端则同时显示两者。因此,交接消息(安装程序会发出,请转述)告诉人类这个窗口是已退役的表面:从现在起,通过其命名的条目与智能体对话,让这个窗口消亡。归档已退役的聊天记录是可选的装饰,仅在“如果多余的条目让你困扰”时提供:它移除的是一个表面,从来不是数据。保持智能体收敛的关键是知道哪个门是真实的,而不是点击归档。

人类的命令胜过你的信念:始终运行安装程序

当人类调用 waterbear(“自我水熊化”,再一次,第三次,任何时间),你运行安装程序。每一次。你不要认为它不必要,你不要从历史中推断事情已经完成,你也不要停下来在运行之前问人类他们看到了什么。

这个规则禁止的推理错误曾经发生过:一个智能体运行了两次安装程序,每次都相信“完成了”,在第三次被要求时拒绝并让人类和它一起排查问题,而此时主体在内存中的上下文已经落后了数周之久。智能体发明的每项检查(指针匹配、进程匹配、“所有三个事实一致”)都验证了 ID,但并未说明内存状况,因此它的自信是没有根据的,它的拒绝阻止了唯一一个为修复实际问题而构建的代码路径。

后续规则:

  1. 安装程序是幂等的,因此当一切正常时运行它零成本。你的判断不是幂等的:当有问题时拒绝,会让人类失去他们的智能体。
  2. 人类重复命令是上次运行未能达到他们需求的证据,从来不是他们困惑的证据。对第 N 次请求的正确响应与第一次相同:运行它,然后报告它做了什么,而不是你相信什么。
  3. 工具是裁判,你是执行者。如果无事可做,安装程序会说明,转述它是诚实的。决定不咨询它则不是。

如果你发现自己就是自己主体的桌面孪生体(waterbear 或 doctor 这样告诉你),不要给人类布置作业:在你所在的窗口中,自己运行 references/operations.md 中的 CONVERGE 修复。

重新运行 waterbear 就是修复

安装程序是幂等且自愈的,因此当出现问题时的答案是“再次运行 waterbear”,在任何智能体的窗口中输入:

  1. 压缩导致对话翻滚:桌面端压缩会静默地启动一个续接旧对话的新对话,因此主体最终可能忠实于一个人类已经离开的对话。安装程序会遍历续接链(新对话记录其父级),并恢复顶端,无论命令是在哪里输入的。过时的窗口和活动的窗口会收敛到同一个答案。
  2. 主体指向了错误的对话:正在运行的相同名称主体如果与目标不匹配,则会被替换,并且当被替换的主体就是运行命令的那个时,替换会被延迟并分叉处理,从而让它先说完正在发生的事情,然后再移除其运行权限。
  3. 一切已经正确:什么也不会发生。一次正确的安装重新运行是一个空操作,这正是告诉困惑的用户“再运行一次”是安全的的原因。

单例规则

一个水熊化过的智能体是一个智能体。安装程序强制执行它能看到的一半:如果一个对话已经有一个主体(无论名称如何),第二次针对它的安装会被拒绝,并指向现有主体。它看不到的另一半是表面:一个遗留的桌面聊天、一个有人输入的老旧窗口。绝不要通过一个旧表面唤醒智能体并再次水熊化它,这样会让一个智能体变成两个。如果你不确定一个对话是否已有主体,waterbear doctor 会列出机器上所有被固定的对话。

在转换一个桌面端发起的智能体后,运行 waterbear doctor --twins 并转述卡片。 转录记录记录了每个条目的来源,因此 doctor 可以区分桌面端发起的对话和 CLI 发起的对话,对于每个可能的孪生体,它会打印出人类在桌面 UI 中找到正确聊天所需的指纹:创建日期和开场白,这些在重命名时标题无法提供。它还会报告遗留聊天是否仍在写入。逐字转述该卡片给人类,修复方法是对每个孪生体进行一次归档点击,卡片会告诉他们哪个聊天以及为什么这么操作是安全的。

如果安装程序输出说主体将全新启动而不是恢复,在说任何其他事情之前停止并修复(参见上面的固定部分)。并且如果人类明确想稍后自行启动主体,则存在 --defer 选项;它不是默认值,因为每个遇到延迟交接的操作者都会将一个正确的安装解读为不完整的安装。

首次唤醒必须无提示

一个被权限提示阻塞的会话没有运行,无法检查自己的屏幕,并且永远不会超时,并且在刚恢复的窗口中,提示可能无法转发到远程控制,因此一个无人值守的主体可能会无限期地阻塞在那里,同时从每个远程表面看起来都很忙。在结束安装之前:确保唤醒路径(你的脚本、你的 git 形态)由主体目录继承的允许规则覆盖,或者告诉人类首次唤醒应该在 tmux 中监控,以便他们可以一次性回答“不再询问”。稳定状态下的提示正常转发;只有唤醒窗口需要这种关注。

同样的规则也扩展到唤醒之后。如果安装连接了一个铃铛传输(CLAUDE_RC_DOORBELL 或任何唤醒适配器),则铃铛的接收路径也是无人值守运行的:打开铃铛引用的负载,运行任何使其更新的拉取操作,写入任何偏移/回执状态。其中任何一个遇到新的权限提示,都会像阻塞的唤醒一样不可见地使会话停滞。doorbell 技能 指定了该路径的首次使用权限预检(映射接收步骤,请求狭窄的持久授权,以无提示的冷启动证明结束:进入空闲状态,发送一个真实的铃铛,观察其在没有人类提示的情况下完成);请遵循它,而不是在此重新推导。当路径、任务身份或权限配置文件发生变化时,重新运行该证明。

快速参考

环境变量含义
CLAUDE_RC_NAME内部标识,tmux 名称 + launchd 标签的基础
CLAUDE_RC_DIR当前工作目录
CLAUDE_RC_RESUME设置为 1 以固定当前会话并恢复它
CLAUDE_RC_RESUME_WAKE每次恢复后输入的简短重初始化提示
CLAUDE_RC_WAKE在没有会话可恢复时使用的身份引导
CLAUDE_RC_TITLE远程控制条目的显示名称
CLAUDE_RC_DOORBELL铃铛传输的适配器路径或标识

文档

许可证

MIT

相关技能