npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

session-baton

v0.1.1

Published

Hand a live coding-agent session between your own machines, over plain SSH. Dependency-free bash.

Readme

session-baton 🎽

English · 简体中文 · 日本語 · 한국어 · Español · Français · Deutsch · Português · Русский · हिन्दी · العربية

在你自己的多台电脑之间传递一个正在进行的 Claude Code 会话——出门在外还能用手机继续工作。

CI npm downloads platform license release

你正在笔记本上专注地进行一个 Claude Code 会话,却不得不离开。不必就此中断,session-baton pass 会把整件事交给一台你在家里常开着的电脑。一切都会随之而来——你的代码(包括还没保存的改动)、与 Claude 的完整对话,以及一根"接力棒",它标记出现在由家里那台机器接管。出门时用手机继续;回到笔记本前,session-baton take 把它拉回本地,你就能从刚才停下的地方原样接着干。

flowchart LR
    L["💻 日常笔记本<br/>(你在这里工作)"]
    H["🏠 家里常开的 Mac<br/>(旧 MacBook 或 Mac Mini)"]
    P["📱 你的手机"]

    A(["Anthropic Remote Control<br/>(仅用于手机那一步)"])

    L -->|"pass(交出去)"| H
    H -->|"take(拿回来)"| L
    P -.-> A
    A -.->|"用手机操控"| H
# 在你的笔记本上,会话进行到一半,即将离开:
$ session-baton pass --remote-control
🎽 baton passed to 'home-mac'.
#  → 现在打开手机上的 Claude 应用,继续工作。

# 稍后回到你的笔记本前:
$ session-baton take
🎽 baton taken by laptop. Resume here with:
claude --resume 9f3c…

从设计上就注重隐私:一切都通过 你自己 掌控的机器之间的 SSH 连接传输——没有厂商云、没有账户、没有中间人。你的对话记录永远只在主机之间通过 SSH 直接拷贝。你的代码在使用 rsync 传输方式时也走同样的路径;而在默认的 git 传输方式下,它搭乘你现有的 git 远程仓库(origin),因此——就像任何一次 git push 一样——它会经过托管该远程仓库的服务(例如 GitHub)。若要做到严格的点对点、完全不经过任何 git 托管方,请设置 BATON_TRANSPORT=rsync。唯一的例外是那个可选的手机步骤:它会选择加入 Anthropic 的 Remote Control,而后者要经过 Anthropic 的服务器,并且在连接期间把对话记录存放在那里。你的文件绝不会走这一趟——执行过程和你的文件系统始终留在你自己的机器上——但如果你希望完全不经任何中间人之手,那就跳过 --remote-control,改用普通的 ssh 来操控这个会话。

它适合谁:一位开发者,有一台笔记本和一台可以留在家里开着的机器(那台闲置的 MacBook,或一台便宜的 Mac Mini)——他在一个 真实 的本地环境里工作(你的仓库、你的 .env、你的本地工具),只是想从手机上继续一个会话,或者在另一台机器上接着干,而不必去租一台云主机、跑一个服务器,或者失去那套本地环境。如果你要的反而是一支并行运行的 agent 大军、有保障的正常运行时间,或团队级管控,那你需要的是更庞大的东西——参见如何对比

为什么要费这个劲?(简短版)

你正在一个 真实 的会话中干到一半——项目打开着、设置就位、本地工具都接好了——却不得不走。每一种替代方案都有个坑:

  • 网页版 Claude 运行在云端,完全没有 你的本地环境——没有你的项目,没有你的文件。它无法接着你实际正在工作的那个会话继续。
  • Claude Code + 单用 Remote Control 很棒——但它操控的是你会话所在的那台机器,而那台机器必须保持唤醒且可达。合上笔记本走人,那个会话就直接联系不上了,直到你再把它打开为止。你需要一台始终开着的机器来托管会话。
  • "那干脆就住在那台始终开着的机器上"——这确实可行:把 Claude Code 长期跑在那里(它甚至有服务器模式),然后从手机上操控它。但这样一来,每个会话都从那边开始,远离你的笔记本——而你的编辑器、你的开发服务器,以及你已经积累了一小时的上下文,其实都在笔记本上。session-baton 面向的是你已经身处其中的那个会话,在你已经在用的那台机器上。
  • 一台云服务器(虚拟机) 倒是能始终在线——但这样一来,你就为了在沙发上继续工作而去租用、打补丁、加固一台机器。太小题大做了。

而这一切的根源在于:Claude Code 会话不会在你的多台设备之间同步——每个会话都只存在于它启动的那台机器上,所以一个做到一半的会话就被卡在那里了。

**诀窍在于:**你几乎肯定已经拥有那台始终开着的机器了——抽屉里那台旧笔记本,或者一台便宜的 Mac Mini。把它放在家里开着,让 session-baton 通过 SSH 把会话交给它。你的机器、你的连接、没有云服务。

你需要准备什么

你不必是硬核工程师——只需要两台你自己的电脑

  • 💻 你的日常笔记本——你真正工作(然后离开)的地方。
  • 🏠 一台始终开着的机器——一台你可以在家里一直开着的机器。抽屉里那台落灰的旧 MacBook 再合适不过了(便宜的 Mac Mini 也行)。在它上面要快速设置两件事:
    • 打开它的 SSH 服务器,好让你的笔记本能连上它——macOS:系统设置 → 通用 → 共享 → 远程登录(打开)。Linux:sudo systemctl enable --now ssh
    • 让它保持唤醒——macOS:系统设置 → 电池 / 锁定屏幕 → 阻止它进入睡眠(一台合着盖的笔记本还需要保持接通电源)。或者,在那台机器上运行 caffeinate -s(让它保持唤醒,直到你按 Ctrl-C)。

两台机器都应是 macOS 或 Linux,此外还需要:

  • 🔑 SSH——一种标准、安全的方式,让你的一台电脑在另一台上运行命令——用密钥配置好,这样它就永远不会问你要密码。不在同一个网络上?Tailscale 大约两分钟就能免费把它们私密地连起来。
  • 🤖 在两台机器上都装好 Claude Code
  • 📱 一份 Claude 订阅(Pro、Max、Team 或 Enterprise)——仅当 你想从手机操控一个已交出去的会话时才需要。如果你平时只是登录来用 Claude,那你已经准备好了;用不了手机操控的是开发者 API 密钥。(在 Team / Enterprise 上,需要由一位所有者为整个组织打开 Remote Control。)

不需要云账户,不用租服务器,不往你的代码里加任何东西。

🚀 最快的配置方式:让 Claude Code 帮你搞定

**首先,在那台始终开着的机器上:**打开远程登录、阻止它睡眠、装好 Claude Code(你需要准备什么一节里的那两条)。下面的配置在你的笔记本上运行,无法替你完成那些事。

然后是简单的办法:在你的日常笔记本上打开一个 Claude Code 会话,粘贴下面的提示词。你不需要读懂它——Claude 会安装并配置好一切,问你几件只有你才知道的事情,然后用 session-baton doctor 检查结果。

Set up "session-baton" (https://github.com/kazuki-sf/session-baton) on THIS machine — it hands my
live Claude Code session off to another machine I own, over SSH, so I can keep going from my
phone. Do the whole setup, asking me only for what you can't detect, verifying each step, and
never overwriting anything without showing it to me first:

1. Prereqs: confirm git, ssh, scp exist and bash is >= 3.2 (and rsync, if I want the rsync
   transport). On macOS, if git/make are missing, tell me to run `xcode-select --install`. If
   something's missing, tell me how to install it and stop.
2. Get the code: clone https://github.com/kazuki-sf/session-baton into ~/GitHub/session-baton (if it
   already exists, cd in and `git pull`), then `make install` (it puts a `session-baton` command in
   ~/.local/bin). Make sure ~/.local/bin is on my PATH — add it to my shell rc if it isn't.
3. Interview me for the two things you can't know:
   - REMOTE: the SSH target of my OTHER, always-on machine (the idle Mac/Mini I leave on) — a
     user@host or an ssh-config / Tailscale alias I can already ssh into.
   - HOST: a short, DISTINCT name for THIS machine (e.g. "laptop"). The two machines must differ.
4. Verify SSH: run `ssh -o BatchMode=yes <REMOTE> true`. If it's refused, remind me that the
   ALWAYS-ON machine needs its SSH server on (macOS: System Settings > General > Sharing > Remote
   Login) and to stay awake — you can't do those from here (they're on the other machine). If it
   fails on auth, walk me through `ssh-copy-id <REMOTE>`. Don't continue until it succeeds.
5. Write ~/.config/session-baton/config (create the dir; if one exists, show it and ask first):
       BATON_REMOTE="<REMOTE>"
       BATON_HOST="<HOST>"
       # Optional — copy the working tree instead of pushing a branch (no CI, no origin needed):
       # BATON_TRANSPORT="rsync"
       # If my agent isn't on the remote's non-login PATH (common with nvm), set its full path:
       # BATON_REMOTE_AGENT="/opt/homebrew/bin/claude"
6. Validate: run `session-baton doctor` and fix whatever it flags (deps, ssh, config, and that the
   other machine is passive). Re-run until everything is a check mark.
7. Remind me: (a) on my OTHER machine, install Claude Code + session-baton the same way, but do NOT
   set BATON_REMOTE there — only ONE machine initiates; (b) `--remote-control` (to drive a handoff
   from my phone) needs me signed into Claude Code with a Claude SUBSCRIPTION (Pro/Max/Team/Enterprise), not an API key.
8. Show me how to use it: `session-baton pass --remote-control` (hand off + drive from phone),
   `session-baton take` (bring it back), `session-baton status`, and `session-baton --help`.

When you're done, print a one-line summary of exactly what you configured.

这会配置好这些东西:~/.local/bin 里的一个 session-baton 命令,以及 ~/.config/session-baton/config 处的一个小配置文件。除此之外别无他物——没有后台应用,没有登录项,不改动你的代码。想自己手动来?请看 安装

安装

上面那段粘贴即用的提示词会替你完成所有这些——不过这里是手动的路径。

# On macOS, run `xcode-select --install` first if git/make aren't installed.
git clone https://github.com/kazuki-sf/session-baton
cd session-baton && make install                        # puts a `session-baton` command in ~/.local/bin
make check                                             # optional: shellcheck + the test suites

确保 ~/.local/bin 在你的 PATH 上,这样你就能直接输入 session-baton

echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc

**平台:**macOS 和 Linux。**Windows:**在 WSL 里运行(在那里它就是 Linux);不支持原生 Windows 和 Git-Bash。任何时候都可以运行 session-baton doctor 来检查你的配置。

配置

只在你的日常笔记本上,把 session-baton 指向那台始终开着的机器——用一个环境变量,或者 ~/.config/session-baton/config

BATON_REMOTE="home-mac"      # ssh target of your always-on machine (user@host or an ssh alias)
BATON_HOST="laptop"          # a short, distinct name for THIS machine

⚠️ **也在那台始终开着的机器上安装 session-baton,但不要在那里设置 BATON_REMOTE。**只有一台机器(你的笔记本)驱动这次交接;两台都设置会破坏"只有一台在掌管"的保证。(如果两边都设置了,session-baton doctor 会警告你。)

比起手写那两行,更想要一份读得懂的文件?在你 clone 出来的目录里运行 mkdir -p ~/.config/session-baton && cp config.example ~/.config/session-baton/config——它对每一个旋钮都做了注释,还写明了你在什么情况下会去改它。其他一切都会自动检测(仓库、会话,配置文件优先于环境变量)。运行 session-baton --help 查看每一个旋钮(例如,当仓库在另一台机器上位于不同路径时用 BATON_REMOTE_REPO)。

用法

| 命令 | 它的作用 | |---|---| | session-baton pass [name] [--remote-control] | 把当前会话交给那台始终开着的机器。加上 --remote-control 就能从手机继续操控它。 | | session-baton take | 把会话带回这台机器;打印出 claude --resume … 命令。 | | session-baton status | 显示当前是谁持有接力棒,以及在哪个分支上。 | | session-baton doctor | 检查你的配置(依赖、SSH、config)并报告 ✓/⚠/✗。先运行这个。 | | session-baton adopt | 拉入一个你那台始终开着的机器上启动的会话——见下文。 |

运行 session-baton --help 查看每一个标志(--tmux--force--allow-empty……)。

拒绝操作是为了保护你的工作。take 从不盲目覆盖:只有当自你交出会话以来这台机器没有变过时,它才把会话带回来——否则它会停下,让你自己去理清差异,而不是把任何东西冲掉。pass 不会从一台已经持有接力棒的机器手里抢走它(用 --force 来强制覆盖)。

在你的手机上

session-baton pass --remote-control 之后,打开手机上的 Claude 应用(如果还没装,就从 App Store / Play Store 装一个),用同一个 Claude 账户登录——交出去的会话会出现在你的会话列表里;点它,继续工作。它跑在你家里的机器上;你的手机只是遥控器。

adopt——接着一个你在家里的机器上启动的会话

反方向的流程:你那台始终开着的机器上启动了一个 Claude 会话(比如从手机上),想在笔记本上接着做。session-baton adopt 会把那个会话的工作文件和对话拷贝过来。它会覆盖当前文件夹以匹配家里的机器,所以它会在有未提交改动时拒绝操作,并且不会删除只存在于你笔记本上的文件--force 可强制覆盖,但你从没保存到 git 里的文件是无法恢复的——先提交)。在 adopt 之前,先让家里机器上的会话处于空闲状态(这样文件不会在拷贝中途变化)。

在 Claude Code 内部 (/pass, /take, /baton)

你可以不离开对话就完成交接。把 examples/claude-commands/ 里现成的三个斜杠命令复制到你的 Claude Code 命令文件夹里:

mkdir -p ~/.claude/commands
cp examples/claude-commands/*.md ~/.claude/commands/

现在,就在任意一个 Claude Code 会话里:

  • /pass [名称]——把这个会话交给那台始终开着的机器,并从手机上操控它
  • /take——把它带回这台机器
  • /baton——显示谁持有接力棒

无需切换到终端——会话进行到一半时输入命令,Claude 就会替你运行它。


如果出了问题

先从 session-baton doctor 开始——它是只读的,能抓出大多数配置问题。除此之外:这里没有任何一步是单向的。在任何东西被覆盖之前,都会先在一旁留下一份副本。

| 什么 | 保存在哪里 | | ---- | --------------- | | 你之前的本地对话记录(每一次 take / adopt) | ~/.claude/projects/<project-key>/<session-id>.jsonl.bak-<timestamp> | | 另一台机器上还没被拿回来的工作(pass --force、rsync 传输) | 在另一台机器上:~/.claude/baton/worktrees/<project-key>.baton-bak-<timestamp> | | 另一台机器上原本就存在的工作(git 传输的恢复过程) | 另一台机器上的一个 git stash——用 git -C <repo> stash pop 取回 | | 你已提交的代码(git 传输) | 永远都在 origin 上那个已经 push 的分支里 |

没有任何东西会替你清理它们——等你确认无误之后自己删掉。

**"我交出去了,但手机上什么都没出现。"**你的工作已经在另一台机器上了;只是会话没有在那里跑起来。运行 session-baton doctor(常见原因是那台机器上没有 tmux,或者 claude 不在它的非交互式 PATH 上——把 BATON_REMOTE_AGENT 设为绝对路径)。无论如何,session-baton take 都能把一切带回来。

**"take 报了 DIVERGENCE。"**你在交出会话之后又改动了这台机器,所以 take 选择拒绝,而不是覆盖。什么都没有被动过。要么保留这台机器的版本(session-baton pass --force——另一台机器上的那份会被挪到一旁,而不是被删掉),要么保留另一台机器的版本(先提交或 stash 掉你本地的改动,再重新运行 session-baton take)。

**"take 说没有接力棒状态。"**那个指针从来没被写进去(连接断了,或者另一台机器的磁盘满了)。你的分支和记录都还在另一台机器上——等连接稳定之后重新运行一次 session-baton pass

**"另一个操作正在进行中。"**某次崩溃留下的锁会在几分钟后自行解除。想立刻清掉它——仅限确实没有交接在跑的时候,因为它连活着的锁也会一并清掉:ssh <remote> 'rm -f ~/.claude/baton/<key>.lock/owner && rmdir ~/.claude/baton/<key>.lock'。光靠 rmdir 做不到:锁目录里始终有一个 owner 文件(那条消息里会写明具体是哪一把锁,也会把这条命令原样打出来)。


深入原理

下面的内容全是参考资料——在你需要之前都可以跳过。它是如何工作的:docs/DESIGN.md。它为保护你的数据做了什么、经过了哪些审查、以及还有哪些问题悬而未决:docs/HARDENING.md

你的代码传输的两种方式(BATON_TRANSPORT

| | git(默认) | rsync | | ------------------- | -------------------------------------------- | --------------------------------------------------- | | 代码如何移动 | 提交 → 把一个分支 pushorigin | 通过 SSH 拷贝工作树(rsync) | | 未提交的工作 | 提交到该分支 | 原样两向携带,不提交 | | CI / 远程 | 运行你仓库的 CI;需要 origin | 不 push、不 CI、不需要 origin | | 分叉检查 | 非快进(git pull --ff-only) | 工作集的内容签名 |

大多数人用 git(默认)并且从不去操心这个。rsync 的存在是为了那些生产仓库——你不想让一个用完即弃的交接分支触发 CI(你的项目在每次 push 时运行的自动检查)并把你的远程搞得乱七八糟:它把工作树直接拷进另一台机器上一个专用的文件夹——不 push、不 CI、不需要 origin——并两向携带未提交的工作。它对你的文件很谨慎:它只会传输/删除 git 认为未被忽略的文件(所以 node_modules.env.local 和构建产物永远不会被碰到),从不使用 rsync --delete,并且拒绝覆盖一台你在两边都改动过的机器。(细节与安全性证明:DESIGN.md。)

把你的记忆和文档一起带上(BATON_CONTEXT_SYNC

默认情况下,接力棒携带的是你的代码和对话。但一个 agent 依赖的不止这些:它长期积累下来的笔记、操作手册(runbook)和记忆(memory)——这些都存放在你的仓库之外~/.claude 之下),所以不会随行。如果让会话在另一台机器上落地却没带上它们,它就忘了你是怎么部署的、该调用哪个 API、以及你教过它的那些坑。

设置 BATON_CONTEXT_SYNC=1,接力棒就会沿着交接的方向把这些上下文也带上:pass 把它送过去,take/adopt 把它(以及另一台机器在持有接力棒期间学到的东西)带回来。它是增量式的——文件按并集合并(每个文件以较新者为准),绝不删除——所以两边已有的东西都不会丢失。它会自动携带本仓库自己的记忆文件夹,外加你在 BATON_CONTEXT_PATHS 中列出的任何数据路径(例如 ~/notes~/runbooks)。

只携带数据,绝不携带会被执行的配置。由于拉取会把另一台机器的文件内容写到你的机器上,上下文同步拒绝携带任何 agent 会自动运行或自动加载的东西——settings.json.mcp.json、hooks、CLAUDE.md,以及 ~/.claude/{commands,agents,hooks,plugins} 之下的一切——这样一台被攻陷的对端机器就无法把一次交接变成代码执行或注入的指令。请把 BATON_CONTEXT_PATHS 指向笔记/操作手册,而不是配置。

它在凭据安全上与这个工具的其余部分遵循同样的原则:它绝不移动 ~/.claude/.credentials.json(既拒绝排除),绝不移动整个 ~/.claude 文件夹,也绝不移动你的会话记录或嵌套的 .git。在启用它的情况下运行 session-baton doctor,可以准确看到它解析出了哪些路径、各有多大。除非你主动开启,否则它是关闭的——完整的不变式参见 DESIGN.md

设计原则

  • **独占所有权,绝不合并。**两个已经分叉的对话无法被有意义地合并,所以同一时刻只有一台机器持有接力棒。当两边都改动过时,take 拒绝冲掉并停下,好让你自己去解决;pass 拒绝抢夺接力棒(除非 --force)。
  • **携带你未提交的工作,**而不只是聊天记录——提交到一个分支(git)或原样拷贝(rsync)。
  • **凭据安全。**只拷贝那一个会话的记录——绝不拷贝 ~/.claude/.credentials.json 或你的配置目录。到达另一台机器 shell 的值会被严格校验;任何返回的东西都会被重新校验并清理。
  • **一台机器发起。**接力棒存在于另一台机器上,所以 passtake 必须由同一台机器运行。不要在两台机器上把 BATON_REMOTE 互相指向对方——那会造成两根独立的接力棒。

身份标识

每台机器由它的短主机名标识,若设置了 BATON_HOST 则用它。如果你有两台机器可能共用同一个主机名(两台默认命名的 Mac,两台 ubuntu 虚拟机),就在每台上设置一个不同的 BATON_HOST——否则接力棒无法把它们区分开。

它如何工作(git 传输)

pass:在 git 传输下,如果你在一个受保护的或游离的分支上,它会创建一个 baton/<timestamp> 分支;提交你未提交的工作;push;把对话记录拷到另一台机器;写入接力棒指针;然后才可选地在那里恢复它——这样一来,一次启动了 agent 却丢掉连接的恢复,绝不会让另一台机器跑着会话、却没有任何人被记录为持有接力棒。take 把它反过来——按接力棒里记录的会话 id 取回记录(而不是按"最新的文件"),并且只做快进。rsync 传输拷贝的是工作树而非提交/push,但共用记录 + 接力棒的那些步骤。它从不提交、从不 push,也从不创建 baton/<timestamp> 分支——你会留在原本所在的分支上。

依赖

你的笔记本:bash 3.2+、gitsshscp(rsync 传输或 adopt 还需要 rsync——macOS 内置的 openrsync 就行)。**那台始终开着的机器:**git 传输需要一个 POSIX shell;rsync 传输需要 rsync + git;此外还需要 git、你的 agent CLI,以及(对于 --tmux)用于手机/Remote-Control 恢复的 tmux。如果 agent 不在另一台机器的非登录 PATH 上(用 nvm 时常见),就把 BATON_REMOTE_AGENT 设为它的完整路径。

局限与注意事项

  • 两台机器上仓库路径相同(或设置 BATON_REMOTE_REPO),这样才能找到会话——避免用符号链接的路径。
  • 仓库路径必须是绝对路径,且不含空格 / shell 元字符(会被校验)。
  • 记录格式是一种可能在版本之间变化的 Claude Code 内部格式——在两台机器上运行兼容的版本。
  • 独占所有权是一种尽力而为的锁 + 拒绝机制,不是分布式事务;不要故意让两个 pass 竞争。
  • 首次用 --remote-control/--tmux 交接到一个新目录时:Claude Code 在第一次打开一个它没见过的目录时,会弹出一次性的 "信任此文件夹?" 提示,而一个以无头(headless)方式恢复的 agent 会卡在那里——于是会话就不会出现(比如在你的手机上,那个提示既看不见、也无法回答)。现在 pass 会在启动之前就替接收方目录预先接受这份信任:它把 Claude Code 在你接受该提示时所记录的同一个标志写进对端机器的 ~/.claude.json,并且是 合并 进你已有的配置(绝不覆盖它,遇到解析不了的文件也拒绝去动)。会话会立刻出现。这需要对端机器上有 python3node(几乎必然存在——那台机器本来就要跑 Claude Code);如果两者都找不到,pass 会回退到旧行为,并打印出如何手动批准这个提示。(pass 仍然是窗格一启动就报告"已恢复"(resumed);它能确认信任已被预先写入,但无法确认 agent 已经通过了任何 其他 启动提示。)
  • rsync 的额外事项:pass --force 会在远程留下一个 …baton-bak-<ts> 备份目录,每次 take 都会在本地留下一个 <transcript>.jsonl.bak-<ts>(自己去清理它们);take --allow-empty 用于有意的清空。
  • **Alpha 阶段,而且是被当回事地审查过的。**请把它当作 alpha 来对待——你的数据本质上是安全的(git 历史 + 你本地的记录)。它经历了一轮又一轮的敌对式安全审查;每一轮发现了什么——包括上一轮自己的修复所引入的 bug——以及还有哪些缺口没堵上,都公布在 docs/HARDENING.md 里。发现了什么问题?请看 SECURITY.md

如何对比

如今"离开工位也能用 Claude Code"的工具有一大堆——但它们几乎全都在解决一个 不同的 问题。session-baton 填补的是一个特定的空白:在另一台你自己拥有的机器上,继续你现有的本地会话。 Claude Code 把每个会话存成一份机器本地的记录,没有内置的跨设备同步——这是它呼声最高的功能之一#73639 以及许多重复反馈)。下面是一张实事求是的地图(截至 2026 年年中):

| 类别 | 例子 | 它给你什么 | 为什么它不是这个 | |---|---|---|---| | Anthropic 官方原生 | Remote ControlClaude on the web--teleport | 从手机操控你机器上的一个会话;在 Anthropic 的云里跑一个全新的会话;或者把一个云端会话拉回你的终端 | Remote Control 需要源机器保持唤醒且运行;云端会话看不到你的本地文件、.env、MCP 服务器或数据库teleport只在云↔终端之间、且拒绝一棵有改动的工作树。它们都不会把一个正在进行的本地会话——连同你未提交的工作——在两台你自己的机器之间搬动。(session-baton 使用 Remote Control 来完成手机那一段。) | | 会话传输类工具(最接近) | HappierHappyclaude-git-sessions | 在设备之间搬动或镜像一个会话 | Happier / Happy 经由一个中继服务器(即便自托管,它也是个中间人——不是你自己的原始 SSH),不是 git 原生的,并且把你的工作文件当作可选的附带拷贝。claude-git-sessions 是 git 原生但只有记录(不含未提交的代码),而且是团队共享 / 自动合并的,不是一根独占单一所有者的接力棒。 | | 遥控与通知类应用 | Paseo、CC Pocket、Nimbalyst、ntfy hooks、Claude Code Channels | 给一个留在同一台机器上的会话一个更好看的手机/网页窗口——或者"需要批准 / 已完成"的推送 | 它们不会搬动会话,也不会把你未提交的工作带到另一台你自己拥有的机器上。 | | 始终在线的 agent 框架 | OpenClawHermes Agent | 在一台你自己运行的机器上的常驻守护进程:由聊天驱动、多通道、有记忆,能生成并管理 agent | 重量级——一个要部署、打补丁并付费的服务器;持续的 API 花销;一个暴露给聊天机器人的 shell。而且它们是委派给全新的 Claude Code 子进程——session-baton 搬动的是你真正正在进行的会话。 | | 云端开发环境与托管 agent | Codespaces、Cursor cloud、Devin、Codex cloud、Jules | 在厂商的云/容器里跑这些活 | 一个全新的云端沙盒(不是你的本地环境),按小时或按席位计费,你的代码在别人的云上。session-baton 用的是你已经拥有的硬件,免费,在你真实的环境里。 |

是什么让 session-baton 与众不同——一种我们在其他任何单一工具里都找不到的组合:你的文件只在你自己的机器之间移动——用 rsync 传输方式时走你自己的 SSH,用默认的 git 传输方式时经由你自己的 origin(见上文 从设计上就注重隐私);那些基于中继的工具会让你的工作文件经过一个中间人,而 baton 唯一经手中间人的地方,是可选的手机那一段,走的是 Anthropic 自己的 Remote Control;它是 git 原生的,并携带你未提交的工作;它在另一台机器的真实终端里交给你一个原生会话(不是一个镜像/中继的视图);而且它是一根独占所有权的接力棒——交出去,然后再拿回来,它拒绝合并或冲掉。没有服务器,没有守护进程,没有厂商云,没有持续花销——只有在你叫它跑的时候它才跑。

**什么时候你会想要别的东西:**如果你需要许多 agent 并行、一台有正常运行时间保障的加固的始终在线主机、在一切都离线时也能远程开启工作的能力,或团队级的治理——那就去找一个始终在线的编排器或一个云端开发环境。session-baton 刻意就是那个小巧、私密、面向单个开发者的"把我这一个正在进行的会话带到我的另一台机器、再带回来"的工具。

许可证

MIT