设备
什么会留下来
会话属于设备,而不属于窗口——所以关闭、退出、更新、断线都是脱离而不是杀掉。这里是每种情况下究竟有什么留了下来,以及当进程真的消失时代价是什么。
Termio 在结构上只有一个承诺:会话活得比你用来看它的那个东西更久。关掉窗口、退出应用、 让它自我更新、断开连到 VPS 的 SSH——Agent 都还在干活。这一页是这个说法的诚实版本: 每件事发生后什么留了下来、什么没有,以及当进程真的消失时代价是什么。
规则
每个会话都跑在拥有它的那台设备上的 termiod——Termio server——里面,
本机上的也一样。Mac 应用、CLI 和 iOS 应用都只是观察者。观察者附着到一个会话,也从它
上面脱离;它从不持有那个进程。
所以「这会不会杀掉我的 Agent」这个问题永远归结为一件事:是进程死了,还是只有一个观察者
松开了手? 只有两件事会有意地结束一个会话——关闭会话(⌘W),以及进程自己退出。
什么能扛过什么
| 发生了什么 | Agent 继续运行 | 布局回来 | 屏幕回来 | 对话接得上 |
|---|---|---|---|---|
| 切换会话、隐藏窗口、去用别的应用 | 是 | —— | 是 | 是 |
| 关闭窗口 | 是 | 是 | 是 | 是 |
退出 Termio(⌘Q)再重新打开 | 是 | 是 | 是 | 是 |
| Termio 自我更新 | 是 | 是 | 是 | 是 |
| 连到远程设备的 SSH 断了 | 是 | 是 | 是 | 是 |
termiod handoff(server 原地更新) | 是 | 是 | 是 | 是 |
| server 停止,或者机器重启 | 否 | 是 | 否 | 本机上、且 Agent 支持恢复时才会;另一台机器上永远不会 |
关闭会话(⌘W) | 否 | —— | —— | —— |
上面六行是同一件事的六个名字:一个观察者走了,而进程根本没察觉。重新附着会用 server 自己的回滚缓冲重绘屏幕,所以你回来看到的,就是你从没离开过时会看到的输出。
「布局回来」指的是侧栏树、拆分编组,以及你在每个工作区最后停留的检查器标签页。Termio 把这套结构写到磁盘上;你终端里的内容不在其中。
脱离才是默认
没有哪个随手的动作会结束一个会话。关窗口、退出应用、一次自我更新、笔记本在 ssh 中途掉了
Wi-Fi——每一样都是脱离。下次启动会重新附着到还在那里的会话,而不是新开一批,所以一次长
时间的 Agent 运行是可以放心走开的。
结束会话才是那个有意的动作:⌘W 关闭当前会话,就像 ⌘W 关掉一个浏览器标签页一样,
它的窗格也跟着收起来。等到一个会话都不剩,⌘W 才关闭窗口,而应用继续带着其余一切活着。
参见键盘快捷键。
想离开一台机器但把活儿留着?直接退出就行。没有什么「脱离」命令要记,因为退出本身就是 脱离。
当进程真的消失时
一个停掉的 server——重启、一次 termiod stop、一台断电的机器——会把它的 PTY 一起带走。
这没有绕过去的办法;进程就是进程。Termio 能做的是让回来变得便宜:
- 树会被恢复。 项目、worktree、工作区、拆分编组,以及你在每个工作区最后停留的会话都会 回来,因为它们存在一个文件里,而不是存在 daemon 里。
- 会话在自己的目录里重启。 一个 shell 回来还是一个 shell,根在原来的位置。
- 本机上能恢复的 Agent 会恢复。 重新打开会话会把 Agent 拉回同一段对话,而不是一段 空白。另一台机器上的会话永远是全新启动:恢复要读的那些记录都在本机磁盘上,而它的对话 在那边。
恢复是要么精确、要么不做:Termio 要么接上会话绑定的那段确切对话,要么重新开始。它从不 去猜一段相近的。哪些 Agent 能做到,是每个 Agent 自己 CLI 的事实,写在它的 清单里——见同时运行多个 Agent 里的恢复那一列。
扛过一次重启
没有服务的话,server 只活到你这次登录会话结束为止。这在你面前的 Mac 上通常还行,在一台你 只通过 SSH 连的机器上就几乎从来不行——那上面根本没人交互式登录过。
termiod service install # macOS 上是 launchd,Linux 上是 systemd --user
termiod service status装上服务之后,server 会在崩溃后被拉起来,也会在重启后于登录时再次启动。在 Linux 上,想让
它扛过你的登出,还需要为这个用户打开 lingering(loginctl enable-linger);没有它,这个
unit 会跟着你的会话一起停。
要把这件事说清楚:回来的是 server,不是它当时持有的那些进程。一次重启仍然会结束那台 机器上的每一个 PTY。服务的作用,是让「那台机器上没有任何东西在听」不再是一个永久状态—— 参见问题排查。
睡眠
睡着的机器不跑任何东西,所以对笔记本来说诚实的规则是:Mac 睡着时会话不会死,它们跟着一起 暂停,醒来时接着跑。
在有值得保护的活儿时,Termio 确实会把机器挡在闲置睡眠之外。只要还有会话在工作中或者在
等你,server 就会续一个短的 caffeinate 租约,这样一台插着电的 Mac 就仍然能被连上——正好
是那个在权限提示上安静下来的 Agent 最需要的时刻,也正好是你的手机要去回答它的时候。用电池
时它根本不取租约;合上盖子机器照样睡:用户态的任何东西都覆盖不了合盖睡眠。
如果你想要一个随时都能连上的会话,就把它跑在一台一直开着的机器上——一台 VPS,或者桌上 那台 Mac mini——并把 iPhone 配对到那台,而不是配对到笔记本。
更新时不丢会话
新的 server 构建会原地替换正在运行的那个:进程保留它的 id 和它的 PTY,会话完全不会 察觉。
termiod handoff应用自我更新时走的也是这条路,所以一次 Termio 更新不会让你赔上正在跑的 Agent。从设置 ▸ 远程主机里设置或更新一台机器走的是同一条路;而一次会打断正在进行的工作的更新,会先把 话说清楚并点名那个会话。
Termio 不会留下什么
把边界说清楚,也是这个承诺的一部分:
- Termio 不保留终端的任何记录。 回滚缓冲在 server 里活到会话结束为止,然后跟着一起 消失,不留下任何持久的东西。唯一的例外是一次 handoff:它通过一个随写随删的临时文件把 每个会话的重放缓冲交给接手的 server——只在更新那一瞬间存在,不是一份留存的记录。
- Agent 的对话属于 Agent。 恢复的办法是把 Agent 自己的会话 id 还给它;对话在 Agent 自己的存储里,在你自己的账号下,和从一个普通终端里跑时完全一样。
- 没有任何东西同步到别处。 状态是每台设备一份,就在那台设备上。没有一个 Termio 云 持有副本——参见设备。