Skip to content

feat: add codex support and optimize runtime transport#10

Merged
pallyoung merged 516 commits into
mainfrom
develop
May 6, 2026
Merged

feat: add codex support and optimize runtime transport#10
pallyoung merged 516 commits into
mainfrom
develop

Conversation

@pallyoung

Copy link
Copy Markdown
Contributor

Summary

  • add Codex agent support aligned with the existing Claude session/runtime flow
  • unify agent config to the current runtime environment instead of splitting native vs WSL settings
  • introduce an agent-client abstraction layer so Claude and Codex share the same upper-layer session/UI logic
  • optimize websocket/runtime reload hot paths to reduce duplicate attach work, request fanout, and frontend churn
  • collapse backend DB critical sections on runtime attach/controller guard/disconnect paths
  • reduce runtime snapshot session scans during attach assembly

Validation

  • node --test tests/runtime-attach.test.ts tests/workspace-artifact-refresh.test.ts
  • node --test tests/workspace-runtime-controller.test.ts tests/workspace-view-persistence.test.ts
  • pnpm build:web
  • cargo test --manifest-path apps/server/Cargo.toml
  • CODER_STUDIO_DEV_BACKEND_PORT=43123 CODER_STUDIO_DEV_FRONTEND_PORT=5378 pnpm test:e2e --grep "reload keeps automatic workspace runtime attaches bounded|reload defers session history loading until the drawer is opened|reload replays agent lifecycle history into running and idle browser state|interrupted sessions show an explicit resume entry and reuse the saved claude session id"
  • CODER_STUDIO_DEV_BACKEND_PORT=43123 CODER_STUDIO_DEV_FRONTEND_PORT=5378 pnpm test:e2e --grep "reload keeps automatic workspace runtime attaches bounded|observer follows controller and takeover succeeds after timeout|same-device new client takes over immediately after controller disconnects"
  • CODER_STUDIO_DEV_BACKEND_PORT=43123 CODER_STUDIO_DEV_FRONTEND_PORT=5378 pnpm test:e2e --grep "reload keeps automatic workspace runtime attaches bounded|interrupted sessions show an explicit resume entry and reuse the saved claude session id"

UI 文体 (font-sans):
- 添加 'PingFang SC' (macOS/iOS 系统中文字体)
- 添加 'Hiragino Sans GB' (macOS 中文黑体)
- 添加 'Microsoft YaHei' (Windows 微软雅黑)
- 添加 'Noto Sans SC' (开源思源黑体)

等宽字体 (font-mono):
- 添加 'Sarasa Mono SC' (更纱黑体,中英文等宽)
- 添加 'PingFang SC' 作为 fallback

优先级:专有字体 > 系统字体 > 开源字体 > 通用字体
字体集成:
- 安装 @fontsource/jetbrains-mono (代码字体)
- 安装 @fontsource/ibm-plex-sans (UI 字体)
- 安装 @fontsource/noto-sans-sc (中文字体)

变更:
- 创建 fonts.css 导入本地字体
- 在 main.tsx 中导入字体 CSS
- 移除 index.html 的 Google Fonts CDN 链接
- 简化 font-family 定义,使用本地加载的字体

优势:
- 无需依赖外部 CDN,提升加载稳定性
- 字体文件打包到本地,离线可用
- Noto Sans SC 按需加载子集,约 5MB
- WOFF2 格式,体积优化

构建后:
- 字体文件总数:455个 WOFF2
- 总体积:约 5.5MB (主要是中文字体)
- CSS Bundle:384KB (包含字体定义)
- ring buffer 由 16MB 扩大至 64MB(提取为 RING_BUFFER_SIZE 常量)
- 终端退出时不再将 ring buffer 归档到 archivedReplayBuffers,随
  ActiveTerminal 一起释放,消除无限内存积累
- 移除 archivedReplayBuffers 及所有相关引用(死代码)
- 终端输出直接以 Uint8Array 写入 xterm.js,移除中间 TextDecoder 转换
  避免 UTF-8 跨 chunk 截断导致的乱码
- 修复 chunk 修剪逻辑:仅移除本次已写入的前缀,防止并发追加的 chunk 丢失
- 更新 ring-buffer.ts 过时注释,补充 xterm-host 相关测试
前端xterm.js onData回调只发送单个字符,Enter键只发送\r字符而非完整输入文本。
修改后端从终端输出缓冲区提取用户输入:

1. 处理ANSI cursor movement codes (\x1B[NC]),转换为实际空格
2. 清除其他ANSI escape codes获得纯净文本
3. 反向搜索识别最后的用户输入行(提示符后文本)
4. 使用提取的文本作为session标题

测试验证:手动测试确认标题从SESSION-XX正确更新为用户输入内容
提出方案C改良版:前端Grid + 服务端Diff架构,解决刷新慢和多尺寸客户端问题。

核心创新:
- 服务端维护单一master grid(最大尺寸)
- 前端各自维护local grid + 坐标转换
- Diff协议实现增量传输
- 支持多尺寸浏览器同时访问

预期收益:刷新时间从1分钟降至<300ms,支持未来自定义样式扩展。
详细说明服务端master_grid的尺寸确定策略:
- 默认120x40,覆盖主流1080p显示器
- 动态扩展策略(只增不减)
- 内存占用分析(48MB/终端)
- 配置覆盖支持

解决多尺寸客户端场景下的内存和性能平衡问题。
新增 Quick Pick 风格的 Git 分支切换功能设计,包含完整的架构、状态管理、组件设计、后端 API、样式和测试策略。

核心特性:
- VS Code 风格的 Quick Pick 交互
- 支持本地和远程分支切换
- 快速创建新分支
- 完整键盘导航支持
详细的分步实现计划,包含 12 个主任务:
- 后端 git 命令增强
- Jotai 状态管理
- React 组件开发
- 样式设计
- 单元测试和 E2E 测试
- 集成和验证

采用 TDD 方法,所有步骤包含完整代码和测试命令。
tail(N) 原实现通过 snapshot() 先完整拷贝整个有效内容(最多 64MB),
再从末尾切片,导致每次 supervisor 构建上下文时都分配一块大 Buffer。

改为直接从 writePos 往回定位 N 字节的起始位置,只分配 N 字节,
与 replayFrom() 的读取逻辑一致。
将终端输出从「JSON 元数据事件 + 二进制帧」两步协议简化为单个 v2
二进制帧,帧内直接携带 topic/seq/streamId,消除客户端需要等待
JSON 事件到达后才能组装的竞态窗口。

主要变更:
- core: 新增 encodeTerminalOutputFrame / decodeTerminalOutputFrame
  及 TERMINAL_BINARY_OUTPUT_VERSION = 2
- server/hub: 移除 sendTerminalStreamToClient 中的 JSON 元数据发送,
  改用 encodeTerminalOutputFrame;实现 handleResync 真实重发逻辑
- server/terminal: replay streamId 从 Date.now()>>>0 改为单调递增
  计数器,修复并发请求同毫秒碰撞问题;新增 traceTerminal 调试工具
  函数(受 CODER_STUDIO_TERMINAL_TRACE=1 环境变量控制)
- web/client: 移除 pendingTerminalEvents 及关联的 JSON 等待逻辑;
  handleBinaryMessage 通过 version 字节区分 v2 输出帧与旧 replay 帧;
  sendCommand 支持 timeoutMs 选项
- web/xterm-host: 新增 replay UI 状态机(loading/ready/degraded),
  显示加载中遮罩与失败/关闭/截断降级提示;replay 请求改为直接调用
  wsClient.sendCommand 并使用 120s 超时;移除 OutputBuffer.lastWritten
- web/agent-panes: 移除 session 加载态屏、移除 onSessionCreated
  传递链、provider 按钮在 create 请求期间置灰防重入
服务端:TerminalManager.resize() 增加维度去重,跳过 cols/rows 未变的
pty.resize() 调用,避免冗余 SIGWINCH 触发 TUI 全屏 clear+repaint,
在 StreamBuffer 背压下丢失 clear 帧导致前端出现重复内容。

前端:ResizeObserver 回调增加 150ms debounce,合并快速 layout 变化
(如连续 toggle terminal panel)为单次 fit + resize dispatch。
replay 期间屏蔽 xterm.js 自动应答(DSR 等)被转发到服务端 PTY。
pallyoung and others added 23 commits May 5, 2026 22:31
Remove PTY tail parsing from completion notifications and use fixed completion hints instead, so terminal UI chrome no longer leaks into notification content.
@pallyoung
pallyoung merged commit a04de57 into main May 6, 2026
1 check passed
pallyoung added a commit that referenced this pull request Jun 7, 2026
feat: add codex support and optimize runtime transport
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant