Docs
CONTEXT.md Source

Runtime

Window and panes, daemon, tray, terminal, local API.

On this page
  1. 守护进程(Daemon)
  2. 窗口(App window)
  3. 退出(Quit)
  4. 登录启动(Launch at login)
  5. 托盘(Tray)
  6. 本机接口(Local API)
  7. 本机 token(Local token)
  8. 中断(Interrupted)
  9. 补跑(Catch-up)
  10. 终端(Terminal)
  11. 命令流(Command stream)
  12. 窗格(Pane)
  13. 布局(Layout)

守护进程(Daemon)

本机常驻的 TypeScript 进程,自己跑 tool-call 循环。关窗不停;窗口崩了轮次还在。插电时挡住空闲睡眠;合盖、菜单栏睡眠、没电、关机仍会睡,唤醒后续上。只有窗口进程还活着(含藏到托盘)时,被杀的守护进程会被拉起来;窗也没了之后再崩就停,直到你再开 App 或下次登录。设置里有可选独立运行时,默认关,生产在原生封闭门通过前保持禁用;未开启时监督仍是窗口进程。它还持有你开的终端会话,所以关窗之后那些进程照跑。退出或守护进程自己停掉时,进程一起停,但开在哪、屏幕上有什么会留下来;下次启动在原来的位置重新开一个,分屏布局按这个接回去。结束会话才忘掉它。

Avoid: 云电脑, 24/7 服务器, 把 UI 进程当运行时, 合盖仍继续, 杀一次就停, 独立 KeepAlive 登录项, 关窗杀掉终端

窗口(App window)

Tauri 桌面窗,里面是 Svelte 信使。关窗是隐藏到托盘,不是退出;隐藏时仍留在 Dock。登录时只到 Dock 和托盘,窗不弹。点 Dock / Cmd-Tab / Spotlight / 托盘左键 / 再开 App 把窗叫回来。同时只跑一个窗口进程;第二次启动只唤醒已有的那个并连上已有守护进程。窗口崩了不会自己回来。连上守护进程之前:退出可用,Stop 不可用,信使是「连不上运行时」。拖过的宽高和是否最大化,退出后再开还是关前那样;不记位置,免得换显示器落到屏外。拖边框的过程中不去问窗口是不是最大化:那一问在 macOS 上会把窗口挪开,松手时位置就和拖着的时候不一样。

Avoid: 只用浏览器打开, 无托盘, 隐藏即从 Dock 消失, 窗口 KeepAlive, 登录抢屏, 多窗口, 窗崩当退出

退出(Quit)

结束这次会话。窗口监督(默认)时窗口进程和守护进程都停,托盘和 Dock 都消失。独立运行时若已开启,退出只关 UI,作业继续;要停作业须显式 stop(写 runtime.stop)。进行中的轮次标成中断,你开的终端会话里的进程一起停;下次打开时,每个还开着的终端在原来的位置重新开一个,分屏布局按这个接回去。不是关窗。结束会话才忘掉它。不动登录启动偏好。关机和注销在轮次上也按退出处理。开发态同一条规则。生产独立运行时仍 gated,默认仍是窗口监督。

Avoid: 关窗当退出, 默认只关窗留无头守护进程, 退出当关掉开机启动, 开发态 Cmd+Q 只关窗, 把 gated 独立模式当成已开启

登录启动(Launch at login)

可选,默认开。登录时只拉窗口进程到 Dock 和托盘,信使窗不弹;窗口进程再确保守护进程在跑。关掉只影响下一次登录,不杀当前这次;下次登录窗和守护进程都不来。退出也不清这个开关。守护进程不是自己的登录项。

Avoid: 登录弹窗, 关掉立刻杀掉当前这次, 守护进程自己当登录项, 退出清掉开机启动, 关掉开机启动却留下会自己起来的作业

托盘(Tray)

窗口进程上的菜单栏图标。左键把窗叫回来。右键:显示窗口、Stop(没开窗则最近活动轮)、退出。没有隐藏、没有暂停守护进程。窗崩了托盘也没了。

Avoid: 托盘角标, 第二套信使, 守护进程自己做托盘

本机接口(Local API)

守护进程在 127.0.0.1 上给窗口用的 HTTP + WebSocket,带本机 token。变更走 HTTP;转录流走一条只收的 WebSocket。窗口经它读写名册、发消息、订阅转录流。

Avoid: 把 UI 进程当运行时, 云 API, 双向命令通道, 工作区文件当 HTTP 资源, 把本机 token 放进 URL

本机 token(Local token)

守护进程每次进程启动新铸的随机秘密,用来认证对本机接口的请求。HTTP 用 Authorization: Bearer;WebSocket 在连上后第一条消息带上,不进 URL。窗崩不换;守护进程退出或崩溃后下一进程再铸。不是端点 API key,不进 SQLite,不进仓库。

Avoid: API key, 安装一次的长活密钥, 写进 .env, 放进 WebSocket query

中断(Interrupted)

守护进程挂了、被杀后拉起、你退出、关机或注销时,进行中的轮次被标成中断。转录里那一行和其他 Bot 消息一样带头像和名字,「继续」贴在「中断」气泡后面:新开一轮、触发条是这条中断行,不重试断掉的那一下;该 Bot 的下一轮(哪个会话都行)能看见「上次断了」,看一次即止。合盖 / 系统睡眠不是中断:冻住,醒来接着跑。窗口崩了不是中断:守护进程继续。补全超时、流挂、端点 4xx/5xx 不是中断。健康检查暂时失败而守护进程进程还在,也不是中断:窗不拉第二份,第二份抢不到端口就不改库。

Avoid: 从断点接着调工具, 睡眠当中断, 关机当睡眠, 窗崩当中断, 把「上次断了」永远挂在人设上, 把补全超时当中断, 把端点错误当中断, 把健康检查超时当中断

补跑(Catch-up)

守护进程回来之后(唤醒、崩溃拉起、退出后再开、开机),每个错过的日程只再执行最近该跑的那一次,不把错过的周期连开。

Avoid: 错过就跳过, 错过几次跑几次, 只补睡眠不补退出

终端(Terminal)

你自己在这台机器上开的一条 shell 会话,守护进程持有。和 Terminal.app 同权:cwd 默认落在工作区,但不关在工作区里,也不走批准——批准管的是 Bot 的危险动作,你不需要向自己申请。用来跑你自己的活,包括启动项目这类一直开着的进程。关窗不停。它在哪个目录,以 shell 自己报告的为准(zsh 开箱即用,每个提示符前报一次):cd 之后标签名跟着变;从没报告过的,就是开的那个目录。退出或守护进程自己停掉时,里面的进程一起停,但它在哪个目录、屏幕上有什么会留下来,下次启动在那个目录重新开一个。结束会话才忘掉它。屏幕也在守护进程那里:接回时拿到的是它现在的样子,全屏程序也原样;程序问终端的问题只由它回答,窗格不答,所以几个窗格同时看一条会话也只答一次。shell 拿到的环境按 Terminal.app 那样配,但只放行一份白名单,守护进程自己的其他环境变量(包括密钥)不带进去。桌面和手机同时看一条会话时,它的行列按你最近在看、在敲的那一端来。配对过的设备同权,手机上看得见也敲得动。Bot 看不见、用不了,也不知道它存在。桌面上一个终端标签就是一条会话:新开一个终端标签就是新起一个 shell,标签里不再有一排会话可切。关掉标签只是从窗里拿走,进程照跑;没被任何标签摆出来的会话在「+」和空窗格里可以「接回」。手机和窄屏上没有窗格,所有会话收在终端那一页里当它的标签。要停必须显式「结束会话」并确认。守护进程那份会话列表才是真的;同一个文件夹里开的几条按开的先后编号,桌面标签和手机上叫法一样。

Avoid: 把它当工作区壳, 给 Bot 开终端, 让终端命令走批准卡, 关窗即杀, 关标签即杀进程, 把窗格标签当会话列表, 一个终端标签里再套一排会话, 两个标签指着同一个 shell, 跨守护进程重启续命, 云电脑

命令流(Command stream)

Bot 执行一次 shell 时 stdout / stderr 的实时外推,让那一次调用在它跑的时候就看得见。只是可见性,不改变那次调用是什么:仍然 stdin 关闭、仍然十分钟超时、路径仍然逐次判定。不是终端,没有输入,不进主转录:进行中挂在那条气泡下面,结束折叠成一行,回看走工作目录的轮次视图。

Avoid: 给命令流加输入, 把它当终端会话, 让它改批准粒度, 进主转录, 新增一种消息种类

窗格(Pane)

桌面窗里的一块内容区。一块窗格是一组标签页;一个标签可以是一条会话(它的产物预览、流程图都跟着它;它自己的设置从这个标签里的对话右侧滑出、带一层只盖这块窗格的遮罩,不另占标签),也可以是一个终端(一个标签一条 shell 会话)、日程图、工作区或花费。窗里可以纵横任意分割出多块窗格,分隔条和交汇处都能拖;标签可以在窗格之间拖、拖到边缘就地分割、按住 ⌥ 拖出来变成浮在上面的窗格。在窗格里任意位置右键,可以向上、下、左、右就地分出一块空窗格;里面本来有右键菜单的(消息、代码编辑器)和输入框仍是它们自己的,按住 ⌥ 右键是网页视图的原生菜单;浮动窗格不就地分,右键提供停靠回布局与关闭窗格。空窗格右上角可直接关闭;每块窗格的右键菜单也可关闭整块窗格及其标签,工作区和产物预览有未保存编辑时先确认。最后一块平铺窗格关闭后留下一块空窗格。窗里分成多块窗格,那仍然是同一个窗口进程,浮起来的也不是第二个系统窗口。同时只有一块是当前窗格——键盘在哪块就是哪块,在哪块里点一下或滚一下也换到哪块:Stop 打它那一轮,点通知先找已经开着那条会话的窗格。摆着不止一块时,当前那块四周描一圈强调色,一眼看得出是哪块;只有一块时不描。侧栏里点一条会话:只有一块窗格时,它替换这块窗格正看着的那条会话(终端、工作区这些不被顶掉,新会话在旁边开标签);摆着不止一块时,已经开着它的那块切到前面,哪块都没开就在当前窗格里新开一个标签,不替换任何一块正看着的东西。会话设置同时只在一条会话上开着,在别处打开就把原来那处收起;日程图同时只有一块。每条会话只有一块产物预览、一块流程图:在这条会话里、它的预览文件树里或它的流程图上再打开别的文件、别的那件事,是那一块转过去,不另开一块。这两块的标签名是固定的,跟会话标题走:「<会话名>流程」「<会话名>的产物」,不跟打开的文件或这件事改。窗格窄到 680px 及以下时,会话的顶栏并进它的标签:头像(带状态点)和名字在标签上,顶栏的第二行成了标签的提示;悬停标签出 ⋯,里面是置顶、经过和设置,右键会话标签也在分割前面给出这几项。宽的窗格照旧有顶栏。其他标签(终端、工作区、日程、花费、流程、产物)在同样窄的窗格里也在名字前带上各自的图标。窄屏(≤680px)和手机上没有窗格,仍然是一次一屏、一层层盖上去。

Avoid: 多窗口, 第二个窗口进程, 把浮动窗格当系统窗口, 手机上分屏, 看得见就算已读, 通知自己改布局, 空窗格留着, 设置另开标签, 窄窗格里顶栏和标签各报一遍名字

布局(Layout)

窗格是怎么分的:纵横分割、各自的宽高、哪些浮着、哪块是当前的、终端窗格摆着哪条会话。只记在这台机器的 localStorage 里,不进守护进程,也不进 URL——URL 只说当前窗格正看着哪条会话。退出再开还是关前那样;引用的会话或终端没了就自己收拾掉;重置回默认的一块窗格前先问未保存的改动。

Avoid: 布局进库, 布局进 URL, 跨设备同步布局, 换台机器跟着走, 重置直接丢掉未保存的改动