oh-my-codex v0.9.0 Spark Initiative 深度解析:omx explore只读仓库探索与omx sparkshell原生侧车的设计、分发与实战
【免费下载链接】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(简称 OMX)v0.9.0 是"Spark Initiative"(火花计划)的基座特性版本:它以 Rust 原生二进制为后盾,正式引入omx explore作为默认的只读仓库探索入口,同时将omx sparkshell定位为面向操作者的显式 shell 原生侧车。本文基于 docs/release-notes-0.9.0.md 的版本说明,结合仓库内 Rust crate 与 TypeScript CLI 的源码实现,完整梳理这两个命令的用法、参数、分发契约、CI 验证与升级路径,读完后你可以直接在生产环境中安全地使用"只读探索 + 长输出摘要"的 Spark 工作流。
版本定位:Spark Initiative 是什么
v0.9.0是发布在v0.8.15之后、基于未发布dev分支的预发布草案(Drafted 2026-03-12),共包含55 个非 merge 提交(v0.8.15..dev,2026-03-10 至 2026-03-12),diff 快照为149 个文件变更,+12,325 / -254 行。贡献者包括 Yeachan-Heo、Bellman、2233admin、Seunghwan Eom、hoky1227。
该版本的核心诉求是:让 OMX 拥有"更强的原生快速路径"用于仓库发现与 shell 原生检查,具体落在四条主线:
omx explore成为默认的只读探索入口;- 引入Rust 实现的探索 harness(omx-explore-harness),并配套打包与源码回退(source-fallback)流程;
- 引入
omx sparkshell <command> [args...],作为显式面向操作者的原生侧车; - 允许符合条件的只读 shell 原生任务从
omx explore路由到omx sparkshell。
官方对探索路径的定位是"刻意受限"的:只允许 shell、只读、且经过白名单(allowlist)约束。
omx explore:受限的只读探索入口
设计约束
omx explore不是又一个随意执行命令的入口,而是被设计为一个低成本的只读仓库检查 harness。在 crates/omx-explore/src/main.rs 中,prompt 组装函数明确写入了行为契约(L959-L974):
- 仅允许仓库检查类 shell 命令(
rg、grep,以及对rg/grep/ls/find/wc/cat/head/tail的紧密有界只读 bash 包装); - 禁止写、删、改名或修改任何文件,禁止执行会改变工作区状态的 git 命令;
- 输出必须为纯 Markdown。
从源码结构看,harness 的完整调用形态是(crates/omx-explore/src/main.rs):
Usage: omx-explore --cwd <dir> --prompt <text> --prompt-file <explore-prompt.md> --instructions-file <AGENTS.md> --model-spark <model> --model-fallback <model>其中--prompt-file是探索行为的提示词契约文件,--instructions-file通常指向项目级AGENTS.md,--model-spark是低成本探索模型,--model-fallback是备用重试模型。
白名单执行环境(allowlist environment)
为了真正落实"只读且白名单"约束,harness 会构造一个临时白名单环境(prepare_allowlist_environment,L976 起):把当前可执行文件自身复制为临时bin目录下的包装器,仅暴露以下直接命令(ALLOWED_DIRECT_COMMANDS,L41-L43):
rg, grep, ls, find, wc, cat, head, tail, pwd, printf同时会清洗子进程环境变量(EXPLORE_SUBPROCESS_ENV_VARS_TO_SCRUB,L28-L37),移除BASH_ENV、ENV、PROMPT_COMMAND、NODE_OPTIONS、SHELLOPTS、BASHOPTS、GREP_OPTIONS、GREP_COLORS等可能注入行为的变量,并把PATH与SHELL指到受限位置,从源头防止 shell 逃逸与副作用。
运行时护栏与退出码语义
harness 对 Codex 子进程施加了三重资源护栏(run_command_with_timeout,L430-L525),每一项都有对应退出码:
| 护栏 | 默认值 | 环境变量覆盖 | 超限退出码 |
|---|---|---|---|
| 执行超时 | 180,000 ms(3 分钟) | OMX_EXPLORE_CODEX_TIMEOUT_MS | 124 |
| 进程数上限(进程风暴防护) | 96 | OMX_EXPLORE_PROCESS_LIMIT | 125 |
| stdout/stderr 输出上限 | 8 MB | OMX_EXPLORE_CODEX_OUTPUT_LIMIT_BYTES | 126 |
超限后会终止整棵进程树(POSIX 下通过libc::kill(-pgid, SIGTERM)后补SIGKILL),防止"runaway shell storm"与无界内存增长;Linux 下还会轮询/proc统计进程树数量(count_process_tree,L527-L561)。其他可用环境变量还包括OMX_EXPLORE_CODEX_BIN(指定 codex 可执行文件)与OMX_EXPLORE_ROOT。
模型回退(model fallback)
探索流程采用"低成本模型优先、失败回退"策略(run_with_args,L124-L166):先用--model-spark指定的模型执行,退出码为 0 则直接输出;否则在 stderr 打印回退事件(fallback-attempt=model from=... to=... reason=spark_attempt_failed),再改用--model-fallback重试,并在最终 stdout 输出中附带## OMX Explore fallback提示块,明确标注"成本/行为边界可能不同",避免静默切换模型。
平台限制与后续演进(重要)
omx explore的内置 harness在 Windows 上尚不可用:其白名单运行时依赖 POSIX sh/bash 包装器。Windows 用户需要设置OMX_EXPLORE_BIN指向兼容的自定义 harness,或优先使用omx sparkshell,或运行omx doctor查看就绪状态(见 crates/omx-explore/src/main.rs)。
需要特别说明的是:截至当前仓库 HEAD,omx explore已被硬弃用(hard-deprecated),直接命令面已移除(见 src/cli/explore.ts),官方建议改为:普通只读仓库查找走常规 Codex 仓库检查工具/subagent;显式 shell 原生只读取证或 pane 摘要走omx sparkshell -- <command>与--tmux-pane。也就是说,0.9.0引入的这条探索线最终收敛到omx sparkshell上,这也印证了发布说明里"允许符合条件的只读 shell 任务路由到 sparkshell"的演进方向。
omx sparkshell:面向操作者的原生侧车
omx sparkshell是本次发布的另一主角。它由 crates/omx-sparkshell/src/main.rs(依赖omx-mux提供 tmux capture 参数构建,见 crates/omx-mux/src/tmux.rs)与 TypeScript 侧的 src/cli/sparkshell.ts 封装层共同构成。其用途文案(src/cli/sparkshell.ts):
Usage: omx sparkshell <command> [args...] or: omx sparkshell [--json] [--budget <chars>] <command> [args...] or: omx sparkshell --shell '<shell command>' or: omx sparkshell --tmux-pane <pane-id> [--tail-lines <100-1000>]三种执行目标
底层SparkShellTarget枚举(crates/omx-sparkshell/src/main.rs)对应三种模式:
- 直接命令模式(默认):
omx sparkshell <command> [args...],按 argv 直接执行,不做 shell 元字符解析——这是安全默认,管道、重定向、;、$()等不会被解释。 - 显式 shell 模式:
omx sparkshell --shell '<cmd>',通过bash -lc/sh -lc(POSIX)或原生 Windows shell 执行,只有显式 opt-in 才解释元字符。Windows 下的 shell 选择顺序为pwsh→powershell.exe→cmd.exe(src/cli/sparkshell.ts)。 - tmux pane 模式:
omx sparkshell --tmux-pane <pane-id> [--tail-lines <N>],捕获更大范围的 pane 尾部后,走同样的"原始输出 vs 摘要输出"判定。
参数与默认值
| 参数 | 含义 | 默认值 / 约束 |
|---|---|---|
--json | 输出结构化 JSON 报告 | 默认关闭(纯文本/摘要) |
--budget <chars> | 摘要/输出的字符预算 | 默认 1000 |
--tail-lines <100-1000> | tmux pane 尾部行数 | 默认 200,范围 100–1000(MIN_TMUX_TAIL_LINES/MAX_TMUX_TAIL_LINES,L24-L26) |
--since-last | 只输出与上次观测相比的增量 | 依赖缓存 |
--cache on/off | 是否启用 pane 内容缓存 | 默认 on |
--cache-ttl-ms <ms> | 缓存有效期 | 默认 10 分钟(DEFAULT_CACHE_TTL_MS = 600_000) |
--team <id> | 团队检查上下文 | 无 |
--worker <id> | 团队 worker 检查上下文 | 无 |
-- | 终止选项解析,后续全部视为命令 | — |
缓存正文带版本标记omx-sparkshell-cache-v2,缓存目录解析顺序为OMX_SPARKSHELL_CACHE_DIR→OMX_TEAM_STATE_ROOT/../cache/sparkshell→.omx/cache/sparkshell(L515-L523)。--tail-lines与--tmux-pane之外的组合(如 shell 模式附加参数、tail-lines 脱离 pane)会直接报参数错误,体现了"显式 opt-in、禁止歧义"的接口哲学。
原始输出 vs 摘要输出(threshold 机制)
sparkshell 的核心价值在于"长输出可预测化":通过行数阈值(read_line_threshold)判断是否需要调用模型做摘要,避免每次都用大模型处理海量输出:
- 输出行数 ≤ 阈值:直接输出原始 stdout/stderr;
- 超过阈值:调用 codex 桥(crates/omx-sparkshell/src/codex_bridge.rs 的
summarize_output)生成摘要,并用--budget做字符级截断(compact_text,超出预算时追加[truncated: N chars omitted]); - 摘要失败时回退为原始输出并在 stderr 说明原因。
配套能力还包括:
- 脱敏(redaction):输出先经过 crates/omx-sparkshell/src/redaction.rs 的
redact_output处理,摘要与 JSON 报告使用脱敏后内容,--json报告中含redactions.count字段; - 低推理成本:发布说明强调 PR #781 强制 sparkshell 摘要使用低推理(low reasoning)模式,控制成本;
- 语言注册表:源码中还有面向多种语言的检查注册表(crates/omx-sparkshell/src/registry/ 下含 python、rust、go、node_js、git、generic_shell 等子模块),用于语言相关的只读取证;
- 压力测试覆盖:发布说明提到新增了 noisy 与 adversarial 输出的压力测试覆盖(对应测试见 crates/omx-sparkshell/tests/)。
JSON 报告与诊断
--json模式输出结构化的机器可读报告(write_json_report,L907-L985),关键字段包括:
{ "ok": true, "mode": "command|shell|tmux-pane", "status": "ok|failed", "exit_code": 0, "summary": "...", "errors": [], "warnings": [], "evidence": { "stdout_lines": N, "stderr_lines": N, "raw_hash": "...", "pane_id": null, "tail_lines": null, "line_range": null }, "next_action": "...", "confidence": 0.xx, "classification": "...", "cache": { "cache_hit": bool, "previous_hash": "...", "current_hash": "...", "changed_line_ranges": [] }, "redactions": { "count": N } }classification与next_action由内置诊断分类器产出(classify,L701-L750):能识别auth_error(401/authentication)、type_error、test_failure、waiting_for_input(等待输入/press enter)、busy_processing(thinking/running/building,提示"do not shutdown yet")等模式,并给出置信度。
团队运营中的 sparkshell
sparkshell 不只是隐藏后端,它正式进入了操作者叙事(operator story):
- pane 显式摘要:
omx sparkshell --tmux-pane <pane-id> --tail-lines <100-1000>用于显式 pane 摘要,可直接观察某个团队 worker 的实时运行面板; - 团队检查元数据:
--team <id> --worker <id>会把分类器升级为团队感知(classify_team,L752-L786):读取OMX_TEAM_STATE_ROOT(默认.omx/state)下的team/<id>/workers/<worker>/heartbeat.json与status.json,心跳超过 120 秒(STALE_HEARTBEAT_MS)判定为stale_heartbeat并建议"run omx team status";worker 状态为blocked/needs_input时建议"inspect raw pane"、failed时归类为 test_failure,并保持与 src/team/state.ts 中WorkerStatus.state联合类型对齐(源码注释明确要求)。
也就是说,sparkshell 已经能为"团队运行时巡检"提供结构化证据:它能告诉你一个 worker 是在忙碌、等待输入还是已经失败,以及下一步该做什么。
原生发布资产成为一等公民:分发与水合契约
0.9.0同时对发布形态做了升级,让新原生面可跨平台发布与消费:
- 统一
omx-explore-harness与omx-sparkshell的跨平台原生发布; - 生成带per-target 元数据与校验和的原生发布清单
native-release-manifest.json; - 发布工作流新增packed-install 冒烟验证;
- CI 直接验证
build:full。
关键分发契约
官方在发布说明中明确的分发契约是:
- 用户正常安装:
npm install -g oh-my-codex; - npm 包刻意不直接打包全部原生二进制;
- 带 tag 的 Release 发布跨平台原生压缩包,覆盖
omx-explore-harness与omx-sparkshell两个产品; - packaged 安装通过
native-release-manifest.json从 Release assets 水合(hydrate)匹配的原生二进制; npm pack刻意不携带 staged 原生二进制——原生压缩包附加在 GitHub Release 上,通过 native-asset 工作流消费。
二进制解析与水合顺序
TypeScript 侧 src/cli/native-assets.ts 负责整个水合流程,产物类型包括omx-explore-harness、omx-sparkshell、omx-api、omx-runtime(L13)。清单默认从OMX_NATIVE_MANIFEST_URL或<repo>/releases/download/v<version>/native-release-manifest.json拉取(L102-L111),缓存根目录默认~/.cache/oh-my-codex/native(Windows 为LOCALAPPDATA,L113-L120)。
sparkshell 的二进制解析顺序(src/cli/sparkshell.ts)体现了官方强调的"显式回退顺序":
- env 覆盖:
OMX_SPARKSHELL_BIN(绝对路径或相对 cwd 解析); - 水合缓存:按版本 + 平台/arch(Linux 区分 musl/glibc,
resolveLinuxNativeLibcPreference)检查托管缓存,校验通过(verified)即命中; - packaged 产物:
bin/native/<platform>-<arch>[-<libc>]/omx-sparkshell; - repo-local 构建:
target/release/omx-sparkshell与嵌套的native/omx-sparkshell/target/release/omx-sparkshell; - Release 水合:联网拉取
native-release-manifest.json对应的压缩包并校验 SHA-256; - 全部失败则报错,提示恢复网络或设置
OMX_SPARKSHELL_BIN。
omx explore侧同样支持OMX_EXPLORE_BIN覆盖(见 src/cli/explore.ts 的 packaged 元数据解析)。此外,当原生侧车不可用时,sparkshell 命令会降级为原始命令执行(runSparkShellFallback,src/cli/sparkshell.ts),在 stderr 打印cause/path/state/remediation诊断后以stdio: inherit直接跑原始命令;GLIBC 不兼容(GLIBC_* not found模式)也会触发同样的降级路径。
相关环境变量速查
| 变量 | 作用 |
|---|---|
OMX_SPARKSHELL_BIN/OMX_EXPLORE_BIN | 显式指定原生二进制路径(最高优先级) |
OMX_SPARKSHELL_MODEL/OMX_SPARKSHELL_FALLBACK_MODEL | 摘要模型与重试模型 |
OMX_SPARKSHELL_MODEL_INSTRUCTIONS_FILE | 覆盖打包的摘要指令(默认templates/model-instructions/sparkshell-lightweight-AGENTS.md) |
OMX_SPARKSHELL_SUMMARY_TIMEOUT_MS | 本地 API 摘要超时 |
OMX_NATIVE_AUTO_FETCH/OMX_NATIVE_MANIFEST_URL/OMX_NATIVE_RELEASE_BASE_URL/OMX_NATIVE_CACHE_DIR | 控制水合开关、清单地址、发布基址、缓存目录 |
OMX_SPARKSHELL_CACHE_DIR/OMX_TEAM_STATE_ROOT | pane 缓存目录与团队状态根目录 |
v0.9.1 热修复:本地化冒烟水合资产
值得注意的是,官方将v0.9.0标记为历史上"红"(red)的版本——packed-install 冒烟水合热修复在该 tag 之后才落地,因此干净的超替(superseding)版本是v0.9.1(见 docs/release-notes-0.9.1.md)。该热修复把冒烟流程中的水合资产本地化到测试工作区,不再依赖只在源码 checkout 布局下才有效的路径,对应当前仓库的 src/scripts/smoke-packed-install.ts。历史记录建议的发布口径是:"v0.9.0保持历史红;v0.9.1是携带 packed-install 冒烟水合热修复的干净超替版本。"
CI 与构建验证:Rust 路径成为一等公民
0.9.0让 CI 更直接地验证 Rust 路径(与仓库根目录 Cargo.toml 下的 workspace 对应):
- 完整构建 lane 显式配置 Rust 工具链;
cargo fmt --all --check:格式门禁;cargo clippy --workspace --all-targets -- -D warnings:以 warning 为错误的全 workspace 静态检查;build:full在 workflow 中直接验证,并与纯 TS 构建(TS-only build)明确区分(release 说明里的d12e5f4提交同时补了build:full及文档);- 发布工作流新增packed install 冒烟门禁(
559089f)。
这保证了"npm 安装保持简单,同时仍交付经过验证的跨平台原生助手"这一目标。
升级指南与配套打磨
升级操作
- 使用project-scoped OMX 安装的用户,需要重跑:
omx setup --force --scope projectomx explore与omx sparkshell的 packaged 安装,在没有显式二进制覆盖或 repo-local 产物时,会依赖Release asset 水合,请保证安装环境可访问发布资产源;- 再次强调:
npm pack不会携带 staged 原生二进制,原生资产通过 native-asset 工作流消费。
0.9.0 同期打磨项
除 Spark 主线外,dev还收编了一批让版本更完整的配套改进(均有对应 PR 编号,见发布说明):
- worker 邮箱/触发措辞(#805):提示 worker 在回复后继续汇报进度并执行,而不是停止;
- 默认模型解析集中化(#787):把 OMX 默认模型解析收敛到统一位置(对应 src/config/models.ts 的模型解析体系);
- 本地帮助路由清理(#786):
ask与hud的嵌套帮助路由整理; - 团队运行时生命周期与清理加固(#785);
- Windows Codex 命令 shim 探测修复(#793);
- 团队 worker 的 aspect-task 分发修复(#789):生成类 aspect 任务在 worker 间的分配;
- HUD 分支/配置加载加固(#788);
- 关联 issue 还包括 linked Ralph 与默认团队运行的生命周期配置持久化(#744)、团队清理策略加固(#745)、团队策略/治理拆分(#746)等后续项。
结语:一条"受限、可预测、可审计"的原生快速路径
回看0.9.0,Spark Initiative 的核心方法论非常清晰:用 Rust 原生侧车承接高频、机械、只读的 shell 取证工作,把"是否值得动用模型"交给行数阈值与预算控制,把"是否安全"交给白名单、环境清洗与进程护栏,把"是否可观测"交给 JSON 报告、缓存哈希与团队诊断。omx explore作为默认只读入口负责仓库发现,omx sparkshell作为显式操作者侧车负责 shell 原生取证与 tmux pane 摘要,两者通过 native-release-manifest 完成跨平台分发,并在后续版本中收敛为以 sparkshell 为主的单一原生取证面。对于想要在团队协同场景中"少看全量日志、只看变化与结论"的操作者,这套工作流直接可落地:omx sparkshell --json --since-last --tmux-pane <pane-id>就是它的最小实战范式。
【免费下载链接】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),仅供参考