持久运行时

cordy-runtime 如何让终端、TUI 与智能体保持存活——环境变量覆盖、工作区级配置与运行时状态。

在 Cordy 的终端与智能体之下,运行着 cordy-runtime——一个用 Rust 编写的、持久的跨平台进程监督器。正是它让你的 shell、TUI 与 CLI 智能体能在窗口重载、渲染进程崩溃,或(在 Windows 上)收起到托盘之后依然存活。

关键在于:cordy-runtime 是一个终端与进程监督器,而不是 LLM 网关。它不做任何模型调用、不组装 prompt、不管理上下文窗口——那些完全是它所启动的外部 CLI 智能体的职责。这一边界在源码层面被强制约束:运行时的各个 crate 有意不依赖任何 HTTP 或 LLM 库。

终端与智能体为何持久

你的终端会话(PTY)与 CLI 智能体子进程并不存在于 Electron 窗口内部,而是存在于独立的 cordy-runtime 进程中。窗口只会通过本地通道对会话进行挂接(attach)分离(detach),从不拥有进程本身。

这一项设计选择带来一个直接后果:

  • 切换工作区、卸载某个面板,或重载渲染进程,都只是分离
  • 只有当你显式关闭一个终端标签页时,底层进程才会被终止。

因此,一个长时间运行的构建、一个 vim 会话,或一个运行中的智能体,会在展示它的界面消失又回来的过程中继续运行。

以快照方式挂接

每个会话在运行时内部都跑着一个无头终端模拟器,它接收 PTY 的每一个字节输出,并与真实终端同步调整尺寸。当界面重新挂接时,运行时会返回以下两者之一:

  • 增量(delta)——仅包含界面上次看到该会话之后缓冲的帧(在同一视图仍存活且间隔较小时使用);或
  • 快照(snapshot)——终端当前尺寸下完整序列化的屏幕状态(在全新重载、托盘恢复,或缓冲的增量窗口已被淘汰时使用)。

以模拟器快照方式重新挂接——而非重放原始回滚缓冲——正是全屏 TUI 能被完整重建、而不是逐步重绘的原因,并且消除了一整类输出重复的问题。(关于备用屏 TUI 尚存的一处限制,见 故障排查。)

监督与自动重启

Electron 主进程会监督运行时,并在其意外退出时重启它。重启采用指数退避,因此一个每次启动都崩溃的运行时不会拖垮你的机器:

  • 退避时长按 1s → 2s → 4s → 8s → 16s 增长,上限为 30s
  • 一旦运行时保持健康(ready)达 60 秒,退避便重置为基础时长,因此很久之后的、无关的崩溃能够快速重启。
  • 重启次数没有固定上限;每次崩溃只会再安排一次受控的重启。

每一次自动重启(尝试次数、退避、退出码、信号)都会写入诊断日志,因此崩溃循环事后可查——见 故障排查。你也可以从应用内的运行时状态指示器手动重启运行时。

运行时能让你的终端在渲染进程重载与主进程短暂重启之间保持存活。但运行时进程自身崩溃后的保活尚无法保证——这是一个已规划的加固方向。

运行时状态

运行时状态指示器会显示以下状态之一:

状态含义该怎么做
starting运行时进程正在启动。稍候片刻。
ready健康且已连接;终端与智能体正常工作。无需操作。
binary-missing在任何已知路径上都未找到运行时二进制。构建它,或设置 CORDY_RUNTIME_BIN(见下文)。
incompatible运行时的协议版本与当前应用构建所期望的不匹配。从匹配的源码重新构建运行时,或重新安装匹配的应用构建。
crashed运行时意外退出;已安排一次受控的自动重启。通常会自愈。若持续重启,请查看诊断日志。
stopped运行时被有意停止(例如应用关闭时)。重启应用或运行时。

当状态为 binary-missing 时,应用会报告它尝试过的每一个路径,让你清楚它在哪里查找过。不存在单独的"崩溃循环"状态——崩溃循环表现为诊断日志中 crashed 反复出现,且重启计数不断增加。

环境变量覆盖

以下环境变量用于调整运行时与窗口行为。它们都是可选的;对于常规使用,默认值即为正确设置。

CORDY_RUNTIME_BIN

将应用指向某个特定的运行时二进制——主要面向运行自定义构建的开发者。二进制解析按如下顺序进行:

  1. CORDY_RUNTIME_BIN,若已设置且文件存在。
  2. <repoRoot>/cordy-runtime/target/debug/cordy-runtime[.exe]——仓库内的开发构建。
  3. <resourcesPath>/runtime/<platform>/cordy-runtime[.exe]——打包的二进制。

若都不存在,应用会显示 binary-missing 并附上它尝试过的路径列表,而不会悄悄禁用相关功能。

CORDY_WINDOW_CLOSE_MODE

控制在 Windows 上将窗口收起到托盘时的行为。取值:hidedestroy默认:destroy

  • destroy(默认)在完成数据安全挂起握手后销毁渲染进程以释放其内存,同时运行时、PTY 与智能体继续运行。重新打开时会重新挂接到一切。
  • hide 则让渲染进程常驻内存。

该变量仅影响 Windows 的收起到托盘路径。

CORDY_DEFAULT_SHELL

设置 Windows 上新建终端所用的 shell(默认 pwsh.exe)。在 macOS 与 Linux 上,shell 取自 $SHELL,回退为 /bin/bash;该变量是 Windows 一侧的覆盖项。

CORDY_USER_DATA_DIR

覆盖 Cordy 存储用户数据(项目、工作区、笔记、布局、设置、主题)的位置。未设置时,Cordy 使用各操作系统标准的应用数据位置。其中存放的内容见 隐私

工作区级配置:.cordy/config.json

每个工作区都可以在其代码目录中携带一个可选的配置文件 .cordy/config.json。它定义了 Cordy 围绕工作区生命周期运行的 setup 与 teardown 命令——相当于"准备好这个 worktree"与"事后清理它"。

{
  "schemaVersion": 1,
  "defaultAgent": "claude-code",
  "setup": ["./.cordy/setup.sh"],
  "teardown": ["./.cordy/teardown.sh"]
}
字段类型用途
schemaVersion数字(必须为 1配置格式版本。必填。
defaultAgent字符串,可选在该工作区中默认提供的智能体预设 id。
setup字符串数组(默认 []在工作区(或其 worktree)创建之后运行的命令——例如复制 env 文件或安装依赖。
teardown字符串数组(默认 []在工作区及其 worktree 被删除之前运行的命令——例如清理容器或临时文件。

setupteardown 中的每一项都是一条 shell 命令字符串;你可以内联命令,也可以指向与配置一同放在 .cordy/ 目录中的脚本。若文件不存在,工作区的表现如同拥有一份空配置。格式错误的文件(无效 JSON 或无效 schema)会被报告出来,而不是被悄悄忽略,未知字段也会被拒绝。

由于 setupteardown 会从你的仓库中运行真实的 shell 命令,请以对待该仓库中任何脚本相同的信任标准来对待项目的 .cordy/ 目录。

永不进行模型调用

再直白地重申这一边界:cordy-runtime 监督终端与进程。它从不调用语言模型,从不接触你的提供商密钥,也从不组装 prompt 或管理上下文。它所启动的每个 CLI 智能体都在各自的进程中、使用各自的配置,与各自的提供商通信。见 智能体隐私

相关页面

  • 故障排查——运行时故障状态与诊断。
  • 智能体——运行时所启动的 CLI 智能体。
  • 隐私——用户数据存储在何处。