diff --git a/docs/superpowers/specs/2026-03-22-codex-hud-design.md b/docs/superpowers/specs/2026-03-22-codex-hud-design.md index 89f7973..33007d9 100644 --- a/docs/superpowers/specs/2026-03-22-codex-hud-design.md +++ b/docs/superpowers/specs/2026-03-22-codex-hud-design.md @@ -68,7 +68,11 @@ codex-hud 启动 - 主 pane 启动真实 codex,参数原样透传 - Codex 退出时自动关闭 HUD pane -### 3.3 Inline Mode (fallback) +### 3.3 Inline Mode (degraded fallback, NOT peer to pane mode) + +> **定位:inline mode 是无 pane 能力时的退化方案,不是与 pane mode 平级的体验模式。** +> 它需要接管 scroll region 和终端清理,风险显著高于 pane mode。 +> 开发和测试优先级应低于 pane mode。 ``` | Codex 滚动输出 (--no-alt-screen) | @@ -84,6 +88,7 @@ codex-hud 启动 - PTY wrapper 注入 `--no-alt-screen`,预留底部 4 行 - ANSI scroll region + cursor save/restore - Codex 以滚动模式运行(牺牲全屏 TUI 体验) +- `--no-alt-screen` 不应自动强推;仅在 pane 能力探测失败时才进入此模式 ### 3.4 Passthrough Mode (last resort) @@ -183,8 +188,8 @@ src/ timer.ts # session elapsed (wrapper 启动时间起算) terminal/ - pane-renderer.ts # pane 模式:clearScreen 循环,写入 stdout - inline-renderer.ts # inline 模式:ANSI scroll region + cursor save/restore + pane-renderer.ts # pane 模式:clearScreen 循环,写入 stdout(简单) + inline-renderer.ts # inline 模式:ANSI scroll region + cursor save/restore(复杂) layout.ts # dense(4) / compact(3) 布局,输入 HudState 输出 string[] tty.ts # resize 监听,cleanup (scroll region 还原, cursor 还原) @@ -201,6 +206,11 @@ src/ - `observers/process-tree.ts` — 删除 - `state/tools.ts` / `state/agents.ts` 启发式推断 — 删除 +**渲染层共享边界:** +- `pane-renderer` 和 `inline-renderer` 只共享 `layout.ts` 输出的 `string[]`(纯文本行) +- 不共享任何底层终端控制逻辑(scroll region、cursor、PTY 管道) +- 两者的终端假设完全不同,不应试图抽象出公共终端控制层 + ## 6. HUD Layout ### 6.1 Dense Mode (4 lines, terminal height >= 24) @@ -346,7 +356,37 @@ inline 初始化失败 --> 自动降级到 passthrough mode - install 必须可逆(one command uninstall) - shell rc 修改使用标记块,安装幂等 -## 10. Tech Stack +## 10. Confidence & Risk Assessment + +### 10.1 已确认(可直接依赖) + +| 项 | 依据 | +|----|------| +| `~/.codex/state_5.sqlite` 可读 | 本地实测,threads 表含 model/cwd/git_branch/tokens_used | +| `~/.codex/sessions/*.jsonl` 存在 | 本地实测,含 session_meta/event_msg/response_item/task_started 等 type | +| Codex 支持 `--no-alt-screen` | `codex --help` 已确认 | +| tmux `split-window` 分屏可行 | 标准 tmux 功能 | + +### 10.2 待验证(normalize 层隔离,不写死) + +| 项 | 风险 | 对策 | +|----|------|------| +| JSONL 事件字段名(task_started 等) | 可能随 Codex 版本变化 | normalize(raw) -> HudEvent \| null,字段名只在 normalize 内部出现 | +| SQLite 表结构(state_5.sqlite) | 表名含版本号,可能升级 | 启动时检测 `state_*.sqlite` 最新版本;schema 读取失败降级为 n/a | +| `threads.tokens_used` 精确语义 | 可能是 prompt tokens / completion tokens / 合计 | 命名为 tokensUsedTotal,UI 只展示原始数值,不做百分比推算 | +| context window usage | 当前未确认有原生来源 | 默认 n/a,不伪装 | + +### 10.3 明确风险 + +| 风险 | 影响 | 缓解 | +|------|------|------| +| pane 生命周期管理 | 嵌套 session、退出时未关闭 pane、split 失败 | 双重探测进入条件;exit handler 强制关闭 pane | +| inline scroll region | 光标恢复失败、终端兼容性差异、resize 后撕裂 | 定位为 degraded fallback,开发优先级低于 pane mode;cleanup 必须覆盖所有退出路径 | +| JSONL 事件协议不稳定 | Codex 升级后解析失败 | normalize 层隔离,失败静默降级,HUD 其他部分不受影响 | +| SQLite schema 升级 | state_5 变成 state_6 | glob 匹配最新 state_*.sqlite,schema 不匹配时降级 | +| tokensUsedTotal 不等于 context | 用户可能误读为"剩余空间" | UI 只写 "tokens" 不写 "context",不画百分比条 | + +## 11. Tech Stack - Node.js 20+ / TypeScript - `node-pty` (inline mode PTY)