为什么我把编辑器和代理分在两个 app 里、tmux 怎么让 Claude Code 会话不随窗口关闭而丢、以及那些真正让整套环境顺手的小配置。

刚开始认真用 Claude Code 的时候,我以为会把它和 VS Code 的 Claude Code 插件一起用。试了几周,能用,但总像两个工具在抢同一块地盘。编辑器想让我看代码,代理想让我全神贯注,两个都在争窗口下半屏。
现在落下来的配置,是把这两个角色拆成两个 app:终端跑代理,编辑器负责看代理改了什么。这一拆反而成了整个工作流顺起来的关键。这篇文章就是这套配置的走读 —— Ghostty + tmux 负责代理那半边,Zed 负责看改动那半边,外加那些真正要解开才能用顺的小配置结。
基于插件的方案(VS Code + Claude Code 扩展)把代理和编辑器塞进一个窗口,方便,但有两件事一直别扭:
把两个 app 拆开就把这两件事都解决了。代理在 Ghostty 里全屏跑(需要两个代理并行时就用 tmux 把它拆成多个 pane)。编辑器单独开,眼里只有代码。编辑器关了代理还在跑,代理改了文件编辑器自己会刷新。
心智模型很简单:Claude Code 是一个进程,不是一个面板。 一旦你这样想它,把它放到终端复用器里就是顺理成章的选择。
┌────────────────────────────────┐ ┌────────────────────────────────┐
│ Ghostty(全屏) │ │ Zed │
│ │ │ │
│ ┌─ tmux session: misoto22 ──┐ │ │ Project diff / Git 面板 │
│ │ ┌ claude ┐ ┌ pnpm dev ┐ │ │ │ 边栏 diff 标记 │
│ │ │ │ │ │ │ │ │ (读 Claude 改了什么) │
│ │ │ │ │ │ │ │ │ │
│ │ └────────┘ └──────────┘ │ │ │ │
│ └────────────────────────────┘ │ │ │
└────────────────────────────────┘ └────────────────────────────────┘
由 tmux + resurrect 想看改动的时候才开
做持久化
Ghostty 里跑 tmux,tmux 里跑 Claude Code 还有一个 dev server 或者 REPL。Zed 单独开,用来看 Claude 改了什么。关掉 Ghostty 并不会杀掉 Claude 会话 —— tmux 只是把它 detach 了,tmux-resurrect 之后还能把它搬回来。
下面逐项展开。
之前一直在用 VS Code。把 Zed 换上来做我"以读为主"的编辑器,理由只有两条:它快到开起来我不会察觉,它的 git diff 集成好到"看代理改了啥"这件事做起来顺手。
Git 集成是我真正在用的。Zed 提供三种看改动的视图:
cmd-y / alt-y 暂存或撤销某个 hunkGit 面板和 Project Diff 都会在 Claude 写盘时立刻刷新,所以我能看着改动随代理出现。有一个要知道的坑:已经打开的 buffer 不会自动 reload。如果某个文件已经在 Zed 标签页里开着,Claude 又改了它,Zed 注意到磁盘变了,但标签页里的内容还是旧的,除非你手动触发 editor::ReloadFile。社区早就提了"未修改 buffer 自动刷新"的需求,但还没实装。
我的习惯是:用 Git 面板和 Project Diff 找到 Claude 改了哪些文件,然后重新打开(不是复用已开的标签)去读内容。这样就绕开了 stale buffer 的问题。
拆分视图 —— 适合一边是 diff、一边是当前文件的场景,或者两个相关文件并排。Zed 拆分够轻,我会下意识就拆,而不是不停切标签。
Zed 我不用来写代码。代码 Claude 基本都写了,Zed 就是读、批、偶尔改一两行比解释给 Claude 还快的地方。
Ghostty 是 GPU 加速、零配置哲学的终端。功能上对标 iTerm2 和 Alacritty,但默认就够好用,我除了改字体大小之外基本没动它的配置。
专门为 Claude Code 选它的理由:
Shift+Enter 原生就支持多行输入。大部分终端需要改键绑定;文档里明确列出能开箱即用的只有 Ghostty、iTerm2、WezTerm、Kitty 四个。Ghostty 有意做得"无聊" —— 没有高级标签 UI、没有插件系统、没有脚本层。要 session 和拆分就去用 tmux。它就是这个意思。
tmux 是终端复用器。没用过的话,三个概念要搞清楚:
核心动作是 detach。从 session detach 之后,里面所有东西都还在跑 —— Claude Code 对话、dev server、REPL、长时间编译都还在。之后 tmux attach -t <name> 就能回到你离开时的样子。整个关掉 Ghostty 再开 —— 还在跑;部署做一半 SSH 掉了 —— 还在跑。
对 Claude Code 来说,这恰好解决了终端代理最烦人的一件事:关窗口就丢对话。
我默认的项目 session 是两个 pane:左边 Claude Code,右边 dev server 或者测试 watcher。同时在不同分支上跑两个代理的时候,就变成一个 window 里上下两个横 pane,一个项目一个 session。
detach / reattach 解决关窗口和 SSH 断开的问题,但扛不住重启 —— tmux session 存在内存里,机器一重启就没了。要让它扛住重启需要两个插件;对 Claude Code 来说,还要加第三个。
tmux-resurrect 负责保存环境:session 列表、window 布局、pane 排列、工作目录,很多情况下连 pane 里跑的程序也能恢复。prefix + Ctrl-s 保存,prefix + Ctrl-r 恢复。
tmux-continuum 在 resurrect 之上再自动化一层。每 15 分钟在后台自动保存,加一行配置还能在 tmux 启动时自动恢复:
set -g @continuum-restore 'on'设完之后重启机器、敲 tmux,自动就回到上次的样子。
但有个缺口:普通的 resurrect 能记住某个 pane 里"跑着 Claude Code",但记不住"跑的是哪段对话"。恢复回来的 pane 打开的是全新会话,不是你之前那段。对 shell 和 dev server 来说没关系,想续一段长对话就不够用了。
tmux-assistant-resurrect 就是补这个缺口的配套插件。它挂到 Claude Code 的 SessionStart 事件上记下每个在跑会话的 UUID,再挂到 tmux-resurrect 的保存 / 恢复生命周期里,恢复时自动在对应 pane 里跑 claude --resume <id>。它重建的命令会保留你原来的 CLI 参数、环境变量和会话历史。通过 TPM 和另外两个一起装:
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'
set -g @plugin 'timvw/tmux-assistant-resurrect'实际效果是:重启机器,Ghostty 开起来,tmux 自动 attach,三个 Claude Code 窗口都回到原来的状态 —— 同一段对话、同一个工作目录、旁边的 dev server 也还在跑。
~/.tmux.conf 大部分是个人偏好。但有几行专门为 Claude Code 是必须的。
Shift+Enter 能换行。 tmux 默认会吃掉扩展按键,所以 Shift+Enter 在 Claude Code 里会变成"发送消息"而不是"插入换行"。两行解决:
set -s extended-keys on
set -as terminal-features 'xterm*:extkeys'第一行让 tmux 在 Claude Code 请求时承认扩展按键;第二行告诉 tmux 外层终端(Ghostty)能传这些序列进来。
桌面通知打通。 Claude Code 通知 hook 发的是一段逃逸序列,外层终端把它转成系统通知。tmux 默认会拦掉,所以通知到不了 Ghostty。一行放开:
set -g allow-passthrough on同一个设置也让 Claude Code 的终端进度条能穿透到外层终端。
合理的默认。 我用了标准的 tmux-sensible 插件,省得一条条记那些古怪的默认值。在它之上我只多改两样:提高 history 上限(Claude 有时会倒出很长的 trace)、开 set -g mouse on 让我能点击切 pane 而不是每次都先 prefix。
剩下的 —— 状态栏、颜色、键重映 —— 都是口味,跟 Claude 无关。
习惯成自然之后的流程:
tmux attach(或者 continuum 已经恢复好的话直接 tmux)—— 瞬间回到离开时的状态。cmd-tab 到 Zed。Project Diff 里能看到所有改动。读、批、或者把修改意见发回给 Claude。cmd-tab 去 Zed 里看。两个 app、职责清楚、切换不痛。到这个阶段就不再像是"配置",而是一个完整的环境。
如果你要从 VS Code + Claude Code 扩展切到终端托管方案,按投入产出比排:
Shift+Enter 原生就能用的终端。 Ghostty、iTerm2、WezTerm、Kitty 四选一。tmux-resurrect、tmux-continuum、tmux-assistant-resurrect。 通过 TPM 十五分钟能搞完,这是让整套环境真正稳固的一环。extended-keys、terminal-features、allow-passthrough)。cmd-tab。 两个全屏窗口一开始会觉得怪,给一周时间。AI 驱动的工作流里大部分摩擦,都来自工具跟你抢注意力。把代理和编辑器拆成两个 app 就结束了这场争夺。其它的 —— 会话持久化、键绑定、diff 视图 —— 都是这一个决定之上的抛光。
下面每个链接都是写这篇时实际翻过的页面。一句话注释说的是"点进去你真正能拿到什么"。
Shift+Enter 配置、tmux extended-keys 要求、通知穿透的权威参考。动 ~/.tmux.conf 之前先读它。SessionStart 跟踪 session ID、怎么在恢复时跑 claude --resume。