oh-my-codex 0.18.6 自适应 HUD 行预算解析:Ultragoal 状态感知的渲染与 tmux 面板策略
【免费下载链接】oh-my-codexOmX - Oh My codeX: Your codex is not alone. Add hooks, agent teams, HUDs, and so much more.项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-codex
本文是 oh-my-codex 0.18.6 补丁版本(v0.18.5 → v0.18.6)的深度技术解读,核心围绕
#2555「keep Ultragoal HUD compact and state-aware」展开:普通会话的 HUD 保持紧凑的默认行数预算,激活 Ultragoal 时最多使用三行展示;tmux 面板的 reconcile/resize 行为与渲染共用同一套行预算助手,当前 Ultragoal 获得独立的品红色(magenta)强调色,并丢弃低优先级的 next-goal 文本以避免混合摘要。读完本文你将掌握 HUD 行预算的自适应机制、ANSI 安全截断与 watch 模式的实现原理,以及相关的回归测试与本地发布验证门禁。
1. 发布背景:一次聚焦的 HUD 渲染补丁
0.18.6是0.18.5之后针对 Ultragoal/HUD 渲染后续工作(landed ondev)的一个 patch release。它的目标非常明确:让运行期 HUD 保持紧凑,同时不隐藏活跃的 Ultragoal 上下文。具体来说:
- 非 Ultragoal 会话维持较小的行数预算(默认 2 行);
- 活跃 Ultragoal 会话最多使用 3 行展示;
- tmux 面板按同一策略调整尺寸(reconcile 与 resize 从渲染所用的 Ultragoal 感知行预算助手派生);
- 当前 Ultragoal 获得独立的品红色(magenta)强调色;
- 紧凑 HUD 输出丢弃低优先级的 next-goal 文本,避免混合摘要。
该版本只改变了渲染与面板尺寸行为,不改变既有 Ultragoal aggregate plans 与 HUD state 文件格式,因此对已有状态完全兼容。发布范围内没有单独关闭的 GitHub issue,范围由合并的 PR 清单(#2555)代表。发布就绪性证据记录在 docs/qa/release-readiness-0.18.6.md。
2. 核心机制:Ultragoal 感知的 HUD 行预算
2.1 常量定义
行预算的核心常量定义在 src/hud/constants.ts:
export const HUD_TMUX_HEIGHT_LINES = 2; export const HUD_TMUX_ULTRAGOAL_HEIGHT_LINES = 3; export const HUD_TMUX_TEAM_HEIGHT_LINES = 3; export const HUD_TMUX_MAX_HEIGHT_LINES = 3;即:普通会话的 HUD 面板默认 2 行,活跃 Ultragoal 会话(以及团队模式)最多 3 行,全局上限 3 行。
2.2 行预算选择助手
渲染端与 tmux reconcile 端共同依赖同一助手getHudRenderMaxLines(src/hud/render.ts):
export function getHudRenderMaxLines(ctx: Pick<HudRenderContext, 'ultragoal'>): number { return ctx.ultragoal?.active ? HUD_TMUX_ULTRAGOAL_HEIGHT_LINES : HUD_TMUX_HEIGHT_LINES; }renderHud渲染时通过clampHudMaxLines(src/hud/render.ts)对调用方传入的maxLines做二次钳制:即便调用方请求更多行,活跃 Ultragoal 的输出也只会被钳制到自适应上限(3 行);普通会话则钳制到 2 行。这正是测试用例「clamps active ultragoal output to the adaptive max even when callers request more lines」验证的行为(见 src/hud/tests/render.test.ts)。
2.3 判断「活跃 Ultragoal」的依据
ctx.ultragoal?.active由 src/hud/state.ts 的readUltragoalState从.omx/ultragoal/goals.json聚合计划推导:解析每个 goal 的id/title/objective/status,统计 complete/pending/in_progress/failed/review_blocked/needs_user_decision 数量,并处理superseded(被取代)与blocked状态;complete = aggregateComplete || unresolved_goals === 0,即当所有未解析目标都完成时,active为 false,HUD 回到紧凑 2 行。已完成的 Ultragoal 计划不会在 HUD 上显示陈旧进度(对应测试「omits completed ultragoal plans instead of showing stale progress」,src/hud/tests/render.test.ts)。
3. 当前 Ultragoal 的品红色强调与摘要折叠
renderUltragoal(src/hud/render.ts)负责拼装活跃 Ultragoal 摘要:
- 进度前缀:
ultragoal {complete}/{total}(cyan),若同时有团队则追加+ team:{n} workers; - 当前目标:取
activeGoal ?? ongoingGoals[0],标题经truncateDynamicText截断到 36 字符,然后整体包上magenta(...)强调色(activeSummary),输出形如▶ G003-tests: HUD progress display; - 当没有任何可展示的进行中目标时才展示
objective(截断到 96 字符,dim 样式),避免与目标标题形成混合摘要; - 低优先级的 next-goal 文本不再输出:
ongoingGoals只包含 activeSummary 一项,pending 后续目标(nextPendingGoals)被有意排除在 HUD 渲染之外,以保证紧凑性与信息单一性(对应测试「renders active ultragoal and omits lower-priority pending items to protect compactness」,src/hud/tests/render.test.ts)。
品红色 ANSI 码定义在 src/hud/colors.ts(MAGENTA = '\x1b[35m'),并通过wrapColor在启用颜色时包裹、禁用时透传原文。
4. ANSI 安全截断与 watch 模式行保护
4.1 面向可见宽度的截断
紧凑展示离不开宽度控制。render.ts提供两条配套路径:
visibleLength/stripAnsi:先剥离\x1b[...mSGR 序列再计算可见长度(src/hud/render.ts);ellipsizeSegment+sliceAnsiVisible(src/hud/render.ts):在受限宽度内对带 ANSI 样式的分段做头尾保留 +…中缀截断,逐字符扫描 SGR 序列并维护activeSgr状态,保证被截断的字符串仍然闭合 ANSI 样式(输出尾部补RESET),不会把终端染色泄漏到 HUD 之外。这正是 0.18.6「constrained-width truncation preserves ANSI styling」修复点。
4.2 watch 模式避免多余行输出
watch 渲染循环(src/hud/index.ts)每帧读取配置与状态,通过getHudRenderMaxLines(ctx)计算行预算并传给renderHud。关键细节:当maxLines变化(例如 Ultragoal 激活/完成导致 2↔3 行切换)时,先输出清屏序列再调用reconcileRunningHudPaneHeight调整面板高度,随后立即重绘,避免 tmux 在高度变化时把陈旧 HUD 行回流进可见输出或滚动缓冲区。同时输出使用\x1b[H ... \x1b[K\x1b[J(行内清除 + 向下清除)而非整屏滚动,避免额外行输出。
4.3 面板尺寸遵循同一策略
tmux 面板的 reconcile/resize 不再单独维护一套高度逻辑,而是直接复用渲染侧的行预算助手:src/hud/reconcile.ts 计算desiredHeight = hudState ? getHudRenderMaxLines(hudState) : HUD_TMUX_HEIGHT_LINES,随后needsHudHeightResize(src/hud/reconcile.ts)对比当前 pane 高度,不一致时执行resizeTmuxPane。这样渲染与面板尺寸在「Ultragoal 激活时放行到 3 行」这一策略上严格一致,不会出现渲染溢出面板或面板留白的情况。
5. 运行时命令与配置
5.1 CLI 用法
HUD 的 CLI 入口(src/hud/index.ts)支持:
omx hud 单次渲染 omx hud --watch 每 1s 轮询并清屏刷新 omx hud --preset=X preset: minimal / focused / full omx hud --tmux 在 tmux 分屏面板中打开 HUD(自动探测方向)5.2 配置文件.omx/hud-config.json
配置模型定义于 src/hud/types.ts,默认值见DEFAULT_HUD_CONFIG(src/hud/types.ts):
{ "preset": "focused", "git": { "display": "repo-branch" }, "statusLine": { "preset": "focused" }, "guardex": { "enabled": false } }字段说明:
| 字段 | 类型 | 取值 | 说明 |
|---|---|---|---|
preset | string | minimal/focused/full | HUD 展示的元素集合;focused为默认(src/hud/render.ts),full追加total-turns,minimal移除autopilot/tokens/quota/session/last等元素 |
git.display | string | branch/repo-branch | 分支标签展示形式;repo-branch为默认,附加仓库名 |
git.remoteName/git.repoLabel | string | — | 仓库标签解析的远程名或显式覆盖 |
statusLine.preset | string | 同上 | 驱动~/.codex/config.toml中[tui].status_line(src/hud/types.ts) |
guardex.enabled | boolean | true/false | 是否把仓库内gx branch finish进度读入 HUD,默认false(src/hud/types.ts) |
HUD 的状态文件读取逻辑在 src/hud/state.ts 的readAllState:并行读取 ralph/ultragoal/ultrawork/autopilot/ralplan/deep-interview/autoresearch/ultraqa/team 等权威模式状态,结合 canonical skill 状态与 subagent 追踪证据,最终组装成HudRenderContext。当 Rust runtime bridge 启用时,会优先读取 Rust 侧snapshot.json作为 authority/backlog 显示依据。
6. tmux HUD 生命周期与 reconcile 机制
0.18.6 的 tmux 相关改动不止行预算。reconcileHudForPromptSubmit(src/hud/reconcile.ts)负责每次 prompt 提交后的面板对账,包含多种跳过/处理状态(skipped_not_tmux、skipped_not_omx_owned_tmux、resized、recreated、replaced_duplicates、skipped_concurrent等),其核心流程:
- 孤儿回收:
reapOrphanedSessionHudPanes(src/hud/reconcile.ts)清理 leader pane 已消亡、但仍残留的 owner 标记 HUD,防止窗口退化成「一列 HUD 条」; - 陈旧 leader 回收:
reapStaleCurrentLeaderHudPanes(src/hud/reconcile.ts)处理 Codex 自更新导致同一 pane 换 session id 的残留 HUD; - 拓扑校验:
needsHudTopologyRecreate检查 HUD 是否完整横跨 leader 宽度、且紧贴 leader 下方; - 高度对账:
needsHudHeightResize+resizeTmuxPane依据desiredHeight(来自getHudRenderMaxLines)调整; - 去重:
planOwnedHudPaneDedupe在创建后二次扫描,合并并发创建的重复 HUD; - 并发锁:基于
.omx/state/hud-reconcile.lock目录锁(waitForHudReconcileLock,src/hud/reconcile.ts),串行化布局变更,同时容忍 10s 陈旧锁回收。
此外,src/hud/constants.ts 定义了HUD_TMUX_MIN_LAUNCH_WINDOW_HEIGHT_LINES = 45与isTmuxWindowTooCrampedForHudSplit:当现有 tmux 窗口高度低于 45 行时,启动路径与 prompt-submit reconcile 路径都不会强加 HUD 分屏,避免挤压 Codex TUI 到不可读(closes #2754)。tmux 命令解析与 hook 注册(client-resized/window-layout-changed/after-split-window)在 src/hud/tmux.ts 中实现。
7. 回归测试:保护 HUD 契约
0.18.6 为自适应行为补充的回归覆盖集中在 src/hud/tests/render.test.ts:
uses a distinct accent for the current ultragoal only(L377):只有当前目标带品红色强调;preserves the current ultragoal accent under constrained-width truncation(L415):截断后 ANSI 强调不丢失;clamps active ultragoal output to the adaptive max even when callers request more lines(L452):活跃 Ultragoal 输出被钳制在自适应上限;renders active ultragoal progress and title in English(L483):进度与标题渲染;omits ultragoal when null/defaults no-ultragoal rendering to the compact line budget(L515/L520):无 Ultragoal 时回到紧凑行预算;combines active ultragoal and team into one non-duplicated focused summary(L535):Ultragoal 与团队摘要合一,不重复;omits completed ultragoal plans instead of showing stale progress(L569):完成计划不显示陈旧进度;renders active ultragoal and omits lower-priority pending items to protect compactness(L655):低优先级 pending 项被省略。
配合 src/hud/tests/reconcile.test.ts、src/hud/tests/hud-tmux-injection.test.ts 与 src/hud/tests/index.test.ts,覆盖了渲染、watch、reconcile、live tmux resize、终端行预算五大方面。
8. 发布验证门禁(Local gates)
按 docs/qa/release-readiness-0.18.6.md,打标签前须通过以下本地门禁:
# 版本同步探测(package=0.18.6 / workspace=0.18.6 / tag=v0.18.6) npm run build node --test dist/hud/__tests__/render.test.js dist/hud/__tests__/index.test.js \ dist/hud/__tests__/reconcile.test.js dist/hud/__tests__/hud-tmux-injection.test.js npm run lint npm run check:no-unused npm run verify:native-agents npm run sync:plugin npm run verify:plugin-bundle node dist/scripts/generate-catalog-docs.js --check git diff --check npm pack --dry-run其中 HUD 回归切片在本版本实测128pass /0fail;npm pack --dry-run产出oh-my-codex-0.18.6.tgz(package 3.6 MB / unpacked 22.2 MB / 2974 files)。另外本次发布预备期修正了 src/scripts/check-version-sync.ts,使其检查当前crates/omx-runtime与crates/omx-sparkshell路径,与 release workflow 保持一致。tag 推送后,跨平台原生资产与 npm 发布仍以 GitHub release workflow 为权威门禁。
9. 兼容性与影响范围
- 状态兼容:既有 Ultragoal aggregate plans 与 HUD state 文件无需迁移,本次仅变更渲染与面板尺寸行为;
- 渲染变化:普通会话保持 2 行紧凑显示;活跃 Ultragoal 会话放行到 3 行;当前目标品红色强调;紧凑输出不再混入低优先级 next-goal 文本;
- tmux 行为变化:面板 reconcile/resize 与渲染共用同一行预算助手,窗口过矮(<45 行)时不强加分屏。
10. 小结
0.18.6 用一次小而聚焦的补丁证明了「紧凑不牺牲信息」的设计取舍:以getHudRenderMaxLines为单一事实来源,让渲染、watch 帧率控制与 tmux 面板尺寸在 Ultragoal 状态感知下行成一致;以 ANSI 安全的可见宽度截断保护终端样式;以回归测试固化 HUD 契约。如果你想继续深入,可以从 src/hud/render.ts 的渲染管线、src/hud/reconcile.ts 的 tmux 对账,以及 src/hud/tests/render.test.ts 的测试矩阵入手。
【免费下载链接】oh-my-codexOmX - Oh My codeX: Your codex is not alone. Add hooks, agent teams, HUDs, and so much more.项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-codex
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考