T3 Code 源码拆解
远程与平台能力

18 · 终端、预览与资源遥测

三条高吞吐旁路如何共享 Server 权限边界,却不挤进领域事件主干。

为什么把三者放在一起

终端、预览和资源遥测功能看似无关,却共享一个架构特征:它们都依赖执行机器的平台能力、数据频率高、生命周期独立, 不适合把每个字节/帧/采样写进 orchestration event log。它们通过专用 Manager/stream 提供能力,再只把与 Thread 有关的摘要或引用接入 UI。

领域主干与平台旁路
IDs / summaries Orchestration event log Thread messages / activities T3 Server capability boundary Terminal Manager Preview Manager Resource Telemetry Byte stream + replay buffer Ports / sessions / browser state Bounded samples / attribution Clients

Terminal Manager

terminal/Manager.ts 拥有 PTY session:创建、输入、resize、输出订阅、关闭和回收。底层通过 PtyAdapter 抽象运行时差异:

  • NodePtyAdapter.ts
  • BunPtyAdapter.ts

业务/RPC 不直接 import node-pty 或 Bun API,因此同一 Server composition 可选择平台实现。

Session identity 与授权

Terminal session 必须关联 environment/project/thread 或明确 working directory,并生成不可猜的 session ID。RPC 方法分别授权读/写/创建/关闭, 不能因为用户能读 thread 就默认能向 shell 写命令。

数据面

PTY 输出是 byte stream,可能包含 ANSI、控制序列和非 UTF-8 边界。Server 不应按普通 JSON 文本随意 split;adapter/manager 保持字节/块顺序, 客户端终端 surface 解释。Resize/input 是控制面,output 是流。

重放与背压

客户端断线后需要有限 replay buffer 或新 screen baseline,但不需要永久审计每个字节。缓冲必须有容量边界;慢订阅者超出窗口时重建终端状态, 而不是无限拖住 PTY 读取。输出 fan-out 不能让一个手机慢连接阻塞实际 shell 进程。

清理

Thread 页面关闭不一定等于终端进程应退出;Terminal Manager 的 session policy 决定保留/回收。Server shutdown、显式 close、child exit 都要结算 stream, 并防止 PID/session ID 复用导致旧客户端写入新进程。

Preview:从端口发现到浏览器会话

Server 侧 preview/PortScanner.ts 发现工作区相关监听端口,preview/Manager.ts 管理 preview session 与 URL。普通 Web 客户端可以打开可达 URL,Electron 还能用特权浏览器 surface。

端口扫描必须避免:

  • 把所有本机服务无差别暴露给远端客户端;
  • 对 0.0.0.0、localhost、IPv6 与容器映射解释不一致;
  • SSRF 式访问任意内网 URL;
  • 端口重用后仍将旧服务认作同一 preview。

Manager 应把“发现的候选端口”“用户打开的 session”“当前可达 URL”分成不同状态。

Electron preview 的额外能力

Desktop preview/Manager.ts 和 BrowserSession.ts 管 webContents/webview,preload 支持元素拾取、标注、快捷键和 agent browser cursor。 PlaywrightInjectedRuntime.ts 为自动化注入受控脚本。安全边界包括:context isolation、禁 Node integration、navigation policy、guest protocol 限制和窄 preload。

当 Agent 需要浏览器工具时,Server MCP preview toolkit 通过明确 handler 与桌面 automation host 协调,不能把任意 Electron handle 暴露给 Provider。

资源遥测:采集、归因、历史

resourceTelemetry/ 追踪 CPU、内存等资源,来源可能是:

  • Rust native/resource-monitor 子进程;
  • Electron main 发布的桌面遥测;
  • Server 对 Provider/session/process 的关联。

ResourceAttribution.ts 解决“这个 PID/子进程属于哪个 provider session/thread”。采样本身只是数字,只有可靠归因后 UI 才能回答哪个 Agent 占用资源。

资源遥测管线
Rust resource monitor NativeTelemetryClient Electron telemetry publisher DesktopTelemetryReceiver Normalized samples Provider process/session map ResourceAttribution Bounded telemetry history Telemetry snapshot/stream Usage UI

为什么 Rust 辅助进程

跨平台进程树、CPU 与内存采样通常需要系统 API,Node 库可能开销高或信息不一致。小型 Rust binary 可以做高效采集, Server 用 ResourceMonitorBinary.ts 定位/启动并通过协议读取。Binary 不可用时应降级 telemetry,而不是阻止 Agent 主功能。

历史容量

采样是无限流,ResourceTelemetryHistory 必须用时间/点数窗口保存;客户端进入页面时取 snapshot,再订阅增量。 采样频率要低到不显著影响被测系统,高到能看见异常峰值。原始点不应进入 orchestration event log。

三条旁路仍要共享的规则

规则TerminalPreviewTelemetry
Environment scopeworking dir/sessionport/browser sessionprocess/session mapping
方法级授权read/write/creatediscover/open/automateread diagnostics
有界数据replay buffersession/metadata limitshistory window
断线恢复buffer or baselinere-query sessionsnapshot + samples
降级PTY adapter unavailabledesktop-only ability hiddenmonitor unavailable
清理child exit/closewebContents/port stalesampler process/scope

可迁移经验

  • 高频平台数据使用专用流和有界快照,不要污染领域事件日志。
  • 将平台 API 放在 adapter 后,业务只依赖 PTY/preview/telemetry capability。
  • 断线恢复协议要针对数据类型设计:终端 buffer、preview re-query、telemetry time window 不应硬套一种 reducer。
  • 可选监控/预览失败应局部降级;终端写入和浏览器自动化则需要更高权限范围。
  • 资源数字只有在进程/session 归因可靠时才对用户有意义。

On this page