
OmX 0.17.2 热修复解析omx question结构化问答的 Leader Pane 恢复与 Hermes/MCP 安全注入【免费下载链接】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-codexOmXOh My codeX0.17.2 是一次针对 0.17.1 之后回归问题的热修复发布核心目标是恢复omx question在结构化问答场景下的 leader-pane发起方窗格回复恢复能力并让 Hermes/MCP 问答桥接路径走同一条安全、有边界的答案回注通道。读完本文你将理解 OMX 问答记录中renderer.return_target元数据的生命周期、[omx question answered]有界回注的判定条件与底层 tmux 调用链以及本次热修复在源码与测试层面的全部验证证据。为什么需要 0.17.2结构化答案回注的回归与修复omx question是 OmX 中面向终端交互的结构化提问能力OMX 创建一条omx.question/v1记录在 tmux 中启动一个独立的渲染 pane 展示问题 UI用户在该 pane 内作答后答案需要被送回发起提问的原始 pane让等待中的 Agent 会话继续执行。0.17.1 及之前的版本中这一“答完回原窗格”的行为在部分路径上出现回归当一条由 OMX 创建的提问记录持久化了renderer.return_target元数据后回答该问题时[omx question answered]有界通知并没有被可靠地发回对应 pane尤其是经过 Hermes/MCP 桥接提交答案的路径。0.17.2 通过 PR #2330restore safeomx questionanswer resume injection for structured/Hermes paths修复了该回归其设计目标非常明确恢复对持久化了return_target的提问记录回答后把有界通知发回原 pane统一Hermes 桥接的有界答案提交路径与本地 UI 路径共享同一套“先落盘、再授权回注”的顺序安全coordinators协调者不提供 terminal targets也不获得任意 stdin 代理能力没有合法%pane目标的记录只持久化答案绝不进行不安全的注入。关键概念renderer.return_target与return_transport要理解这次修复需要先看提问记录question record中渲染器状态的结构。在 src/question/types.ts 中export interface QuestionRendererState { renderer: QuestionRendererKind; // tmux-pane | tmux-session | inline-tty | windows-console target: string; // 渲染器所在的目标 launched_at: string; return_target?: string; // 答案应被回注的目标 pane形如 %11 return_transport?: tmux-send-keys; // 回注使用的传输通道 pid?: number; }字段语义如下字段类型含义取值/默认rendererstring渲染器种类tmux-pane/tmux-session/inline-tty/windows-consoletargetstring渲染器所在目标tmux pane/session ID 等launched_atstring渲染器启动时间ISO 8601 时间戳return_targetstring可选答案要回注的 pane ID形如%11的 tmux pane IDreturn_transportstring可选回注传输方式当前唯一值tmux-send-keyspidnumber可选渲染器进程 PID—return_target的写入时机在 src/question/renderer.ts当提问 pane 启动时携带了returnTarget参数则返回状态中同时带上return_target与return_transport: tmux-send-keys该元数据随后随记录一起持久化。启动时会通过split-window之类的 tmux 调用创建渲染 pane并用isLaunchedQuestionPaneAlive校验 pane 在启动后仍然存活否则抛出Question UI pane disappeared immediately after launch。传输信息也会通过环境变量传递给渲染进程src/question/renderer.tsOMX_QUESTION_RETURN_TARGET回注目标 pane IDOMX_QUESTION_RETURN_TRANSPORT固定为tmux-send-keys。核心修复链路markQuestionAnswered与有界回注判定0.17.2 恢复的答案回注核心实现在 src/question/state.ts。markQuestionAnswered采用“先持久化、再副作用”的两段式结构export async function markQuestionAnswered(recordPath, answerOrAnswers, options) { const updated await withQuestionSubmitLock(recordPath, () persistQuestionAnswered(recordPath, answerOrAnswers)); runAnsweredQuestionSideEffects(updated, options); return updated; }persistQuestionAnswered在提交锁内将记录状态改为answered写入answer/answers字段runAnsweredQuestionSideEffects随后执行两个副作用回注到返回 pane、关闭渲染器。回注判定函数maybeInjectQuestionAnswersToReturnPanesrc/question/state.ts是本次修复的安全核心const returnTarget record.renderer?.return_target; if (record.renderer?.return_transport ! tmux-send-keys) return false; if (typeof returnTarget ! string || !/^%\d$/.test(returnTarget.trim())) return false; if (!record.answers?.length) return false; return injectAnswersToPane(returnTarget.trim(), record.answers);判定条件逐条解释传输通道必须匹配return_transport必须是tmux-send-keys杜绝其它未授权通道目标必须是合法 tmux pane IDreturn_target必须匹配^%\d$形如%11not-a-pane这类非法值会被直接拒绝从而避免把答案注入到任意字符串标识的目标必须有答案record.answers非空才执行注入注入失败不阻断落盘注入过程包在 try/finally 中即使抛错也会先关闭渲染器错误再向上抛出——答案已持久化不会丢失。答案文本的格式化与[omx question answered]有界通知回注到 pane 的文本不是裸答案而是带前缀的有界通知。格式化逻辑在 src/question/renderer.ts单选/普通答案[omx question answered] valueother自由文本[omx question answered] other_textmulti多选[omx question answered] v1, v2, ...多条结构化答案[omx question answered] q-1: a; q-2: b, c文本经过sanitizeReplyInput清理后再通过buildSendPaneArgvs来自 src/notifications/tmux-detector.ts构造tmux send-keys -t paneId参数序列逐条执行并在步骤间按QUESTION_TEXT_SETTLE_MS/QUESTION_SUBMIT_REPEAT_DELAY_MS节流避免在 pane 尚未就绪时一次性灌入导致丢字。[omx question answered]前缀在接收端由 src/hooks/keyword-detector.ts 识别/^\s*\[omx question answered\]/i.test(text)并归类为保留输入omx-question-answeredreservedInput。这意味着回注内容不会触发任意的 prompt 注入或技能调用——它只作为“该问题的答案”被消费正是文档所说“bounded”有界性的体现。Hermes/MCP 桥接路径同样先验证、再授权回注Hermes 桥接在 src/mcp/hermes-bridge.ts 暴露hermesSubmitQuestionAnswer校验allow_mutation后规范化workingDirectory、session_id、question_id将answers多答案数组或answer单答案归一为同一 payload调用submitQuestionAnswerById并透传injectAnswersToPane依赖。关键点在于Hermes 桥接并不直接拥有向任意 pane 注入的能力。它复用markQuestionAnswered→maybeInjectQuestionAnswersToReturnPane的同一判定逻辑——只有当记录本身持久化了合法的return_target且return_transport tmux-send-keys时才会执行回注。因此coordinator协调者不提供 terminal targets不获得任意 stdin 代理能力记录没有合法%pane目标时答案照常持久化但不做注入已有的 stale过期、duplicate重复、malformed畸形答案校验逻辑保持不变。这正好对应 release notes 中“bridge remains structured and bounded”的兼容性说明。提交锁与并发安全withQuestionSubmitLock答案提交路径上的并发安全由提交锁保证src/question/state.ts每个记录对应recordPath.submit.lock目录锁写入owner令牌锁获取超时默认 10 秒QUESTION_SUBMIT_LOCK_TIMEOUT_MS锁目录超过 30 秒QUESTION_SUBMIT_LOCK_STALE_MS未更新视为陈旧锁并强制回收。事件追加侧appendQuestionAnsweredEventOnce见 src/question/events.ts也使用同类锁并保证question-answered事件只追加一次——即使重复提交答案也不会产生重复事件。验证证据测试与 CI 门禁本次修复的验证覆盖了三条路径单条注入state.test.ts中injects answered text to the persisted renderer return pane用例断言注入到%11的目标 panesrc/question/tests/state.test.ts非法目标拒绝skips return-pane injection when renderer metadata has no valid tmux return target用例使用return_target: not-a-pane断言injected falsesrc/question/tests/state.test.ts注入异常兜底still closes the renderer when return-pane injection throws after persisting the answer用例验证答案持久化后即使注入抛错渲染器仍被关闭src/question/tests/state.test.ts。发布验证命令在仓库根目录执行npm run build env -u OMX_STATE_ROOT -u OMX_ROOT -u OMX_SESSION_ID -u CODEX_SESSION_ID -u SESSION_ID \ node --test dist/question/__tests__/state.test.js dist/question/__tests__/ui.test.js \ dist/mcp/__tests__/hermes-bridge.test.js dist/question/__tests__/renderer.test.js npm run check:no-unused npx biome lint src/question src/mcp/hermes-bridge.ts注意测试命令显式-uunset了OMX_STATE_ROOT、OMX_ROOT、OMX_SESSION_ID、CODEX_SESSION_ID、SESSION_ID等环境变量确保测试在隔离的状态根目录下运行不依赖开发者本机残留会话状态。兼容性小结0.17.2 的变更对既有行为保持严格兼容场景0.17.2 行为记录含合法return_targettmux-send-keys持久化答案后回注[omx question answered]到该 paneHermes 桥接提交答案先验证/写状态再按记录授权的 return target 回注记录无合法%pane目标仅持久化答案不做注入重复/过期/畸形答案沿用既有校验逻辑行为不变从实现看这一版的核心是把“回注”从各调用方的自由裁量收敛为记录自身元数据授权 统一传输通道校验任何路径本地 UI、Hermes/MCP都先落盘、再按记录授权的目标回注从而同时满足功能恢复与安全边界两个目标。【免费下载链接】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),仅供参考