-
Notifications
You must be signed in to change notification settings - Fork 2
Terminal Migration
📑 本页目录
终端子系统从原型级的"create PTY + execute + read output"迁移为 ATR(Agent-Native Terminal Runtime)。来源:
docs/MIGRATION_REPORT.md+docs/PHASE4_DEPRECATION_AND_VERIFICATION.md。
关键成果:旧的
TerminalManager.execute()及其300ms / 2ssettle-time 完成检测已被删除, 完成判定改为 waitpid-confirmed(经 EventBus)。 Agent 与人类共享 ONE Session / ONE PTY / ONE SCREEN / ONE EVENT STREAM。
| 阶段 | 交付 |
|---|---|
| Phase 0 契约层 | 29 文件 |
| Phase 1 核心实现 | 14 文件 |
| Phase 2 真 VT + 观察 | 11 文件 |
| Phase 3 兼容层 | 11 文件 |
| Phase 4 UI 渲染 | 5 文件 |
| Phase 5 持久化 + 测试 + 报告 | 4 文件 |
| 合计 | 68 Kotlin 文件 + 3 文档 + 1 测试 ≈ 6900 LOC |
契约层规模:SessionState S1–S14 · JobState J1–J11 · InputOwner/ControlMode I1–I9 ·
TerminalEvent 12 种 · WaitCondition 10 种 · TerminalError 12 种 · TerminalRuntime 9 个操作;
Phase 2 的 VT100Emulator.kt 340 LOC、9 个 Agent 工具。
Note
迁移是纯加法 PR:除 settings.gradle.kts(include :terminal-emulator)与
platform/terminal/build.gradle.kts(依赖它)外,没有任何既有源文件被修改。
| 不变式 | 证据 |
|---|---|
| ONE SESSION |
SessionManagerImpl.assembly(sessionId) 返回单一 SessionAssembly;Agent 的 terminal.observe 与 UI 的 TerminalViewModel.semanticState 读同一个 SemanticStateReducer 实例(同 sessionId、同 pid) |
| ONE PTY |
PtyOutputPumpImpl 是 nativeRead 的唯一读者;InputManagerImpl 是唯一写者(Channel<WriteOp> 串行)。UI 走 runtime.write(owner=USER)、Agent 走 runtime.write(owner=AGENT),都经同一 InputManager,无独立 nativeWrite
|
| ONE SCREEN |
RealVirtualTerminal 共享(pump 喂字节、renderer 读 virtualTerminal.snapshot()),不存在 UI 侧独立 terminal buffer
|
| ONE EVENT STREAM |
TerminalEventLog 是单一事实源(append-only,按 sessionId 分片);TerminalEventBus 广播,每订阅者独立游标、互不推进
|
集成验证 7 步:
① terminal.create → sessionId=12
② UI 绑定同一 sessionId
③ Agent terminal.run(12,"echo hello") → UI 渲染器可见 "hello"
④ UI 按键 → Agent terminal.observe 看到 InputWritten
⑤ Agent 发 SIGINT → UI 显示 INTERRUPTED
⑥ 多次 observe 用不同 afterCursor → 无重复字节
⑦ close(12) → Agent 与 UI 同时看到 SessionClosed
| 旧工具 | 新语义 |
|---|---|
terminal_exec |
同步 run + wait(PROCESS_EXITED) + observe(RAW) —— settle-time 消失
|
terminal_read |
observe(RAW, afterCursor) 游标制,无重复 |
terminal_send |
write(LINE/RAW/KEY),owner 自动注入 |
terminal_signal |
TerminalSignalTool |
terminal_list |
TerminalSnapshotTool(mode=SESSIONS) |
terminal_close |
TerminalCloseTool |
六个 legacy 别名全部 @Deprecated 且带迁移消息,保留 1 个版本后移除。
-
cpp/ansi_filter.h/ansi_filter.cpp(+ 从 CMakeLists 移除)、AnsiStripper.kt—— 均由VT100Emulator取代; -
app/.../tools/StreamingTerminalExecTool.kt—— 与terminal_execid 冲突; -
tools/TerminalExecTool.kt、TerminalSendTool.kt、TerminalReadTool.kt、TerminalListTool.kt; -
PtySessionState.kt(已拆为SessionState.kt+JobState.kt+state/*Snapshot.kt); -
TerminalManager.kt(降级为compat/LegacyTerminalManager.kt)。
- CWD tracking 默认
unknown; - InputWaiting 仅 HIGH_CONFIDENCE 才触发 Session→WAITING_INPUT(POSSIBLE 只更新字段);
- PolicyEngine v1 只有 allow/deny(能力推理延后);
- Persistence 只存元数据 + 近期事件(RingBuffer 字节不持久化);
- VT100Emulator 是最小子集:无 256 色渲染、无鼠标、无 DEC line drawing;
- Recovery 中死 session 变
EXITED/BROKEN(v1 不重连 PTY fd); - 单 UI 窗口(无 split-pane / 多标签)。
| 项 | 结果 |
|---|---|
JVM 端到端(TerminalRuntimeEndToEndTest) |
9 项全绿:create 返回 READY+pid、run echo + observe、SEMANTIC observe 返回 session+job、SIGINT 中断运行中 job(exit 130)、close 释放资源、snapshot 列多 session、resize 更新 VT、wait 在挂起时超时、RingBuffer overrun 被标记 |
| §48 Android 集成全矩阵 | pending real device(长任务 / 交互式 / 大输出 1KB–10MB / 多消费者 / Android 特权 / kill-restart 恢复) |
"Agent 不应该『调用一个 shell 工具』。Agent 应该拥有一个真实、长期存在、可观察、可交互、可恢复的 Terminal Workspace。" —— 定位为本项目的 L3 Environment Control 核心基础设施。
-
MCP 生态总览
新 - (沙箱 MCP · 官方 Hub · 逆向 Host · 门控语义)
- 终端运行时
- 终端 API 契约
- SDK 边界
- Termux 能力矩阵
- Ubuntu rootfs 供给
- Ubuntu 生命周期
- PRoot 二进制溯源
- VT100/ANSI 模拟器
- 终端性能
- 终端迁移
- 原生层 C++/JNI