ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

oh-my-openagent 根级 typecheck gate:用 CI 固定复现隔离环境漂移与真实类型错误

2026/9/19 21:03:27 拓冰建站 浏览量
oh-my-openagent 根级 typecheck gate:用 CI 固定复现隔离环境漂移与真实类型错误 oh-my-openagent 根级 typecheck gate用 CI 固定复现隔离环境漂移与真实类型错误【免费下载链接】oh-my-openagentOmO: Just type mass ulw keyword with your prompt. Now you are the master of graph engineering.项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-openagent本篇技术指南围绕 oh-my-openagent 仓库中fix/windows-ci-root-causes分支的证据记录 typecheck.md 展开讲解根级 typecheck gate的完整结构与一次典型的环境漂移environment drift诊断全过程当本地工具链版本与 CI 固定版本不一致时如何用npx bunpinned install --frozen-lockfile --ignore-scripts精确复现 CI 的 typecheck 结果从而区分补丁引入的真实类型错误与本地工具链差异造成的假阳性。读完本文你将掌握 oh-my-openagent 的bun run typecheck三段式检查链、如何从 CI 工作流中读取当前固定版本、以及如何写出可审计的CI-pinned 复现 清理收据式验证记录。一次绿 CI、红本地的典型环境漂移在排查 Windows CI 根因时作者在本地工作站对fix/windows-ci-root-causes分支执行了第一次根级 typecheck本地使用 Bun 1.4.0 与 Node 26结果在未修改的代码上直接失败报错集中在两类缺失的 workspace 类型条目missing workspace type entriesSenpi factory 的类型转换不匹配Senpi factory cast mismatch。而同一 commit 在 GitHub Actions 的 typecheck job 中Linux、macOS、Windows 三个平台全部绿色通过。同一份源码、两套结果只有一种合理解释这不是补丁引入的回归而是本地工具链与 CI 工具链的版本差异导致的假阳性。证据记录将该结果归类为 environment drift环境漂移既没有掩盖失败也没有错误地把责任推给该补丁——这正是严谨工程验证的第一步先分类再复现。Root typecheck gate 的结构tsgo script packages 三段式根级 typecheckRoot typecheck gate在仓库根目录 package.json 中由一条脚本链组成typecheck: tsgo --noEmit bun run typecheck:script bun run typecheck:packages, typecheck:script: tsgo --noEmit -p script/tsconfig.json, typecheck:packages: tsgo --noEmit -p packages/rules-engine/tsconfig.json ...三个环节依次执行tsgo --noEmit在根 tsconfig 下做全量类型检查。tsgo是 TypeScript 的原生 Go 预览编译器由 devDependencies 中的typescript/native-preview当前仓库固定为7.0.0-dev.20260707.2见 package.json提供--noEmit表示只检查、不产出构建产物。typecheck:script对script/tsconfig.json覆盖的仓库脚本目录单独做一次tsgo --noEmit保证构建与 QA 脚本自身的类型安全。typecheck:packages对全部 28 个 workspace 包逐个执行tsgo --noEmit -p pkg/tsconfig.json覆盖 package.json 中声明的workspaces列表rules-engine、delegate-core、ast-grep-mcp、git-bash-mcp、mcp-stdio-core、lsp-core、model-core、omo-codex、omo-senpi、senpi-task、omo-opencode、omo-native 等。只要这三段中的任何一段失败bun run typecheck就整体非零退出。因此typecheck gate 实际上校验的是根项目 脚本目录 所有包的完整 TypeScript 项目集合。首次本地运行的失败模式工具链版本差异的典型症状证据记录中的第一次运行有两个值得注意的失败症状缺失 workspace 类型条目monorepo 中包与包之间通过workspace:*依赖互相引用例如oh-my-opencode/agents-md-core: workspace:*。当 workspace 图在较新版本的工具链下被重新解析、或锁文件元数据与本地 Bun 版本不匹配时跨包的类型声明可能无法被正确解析从而出现类型条目缺失这类未修改代码上的报错。Senpi factory cast mismatchpackages/omo-senpi与packages/senpi-task是仓库中类型系统最重的模块之一见 typecheck:packages 脚本其工厂函数与泛型推断对 TypeScript 编译器版本高度敏感。本地较新的 Bun 1.4.0 所解析出的typescript/native-preview版本与 lockfile 固定的版本不同就会在从未改动过的 factory 代码上抛出 cast 不匹配。这两类错误的共同特征是出现在未修改的代码中且与本次补丁的 diff 无关。这正是判定环境漂移的关键证据。CI-pinned 复现完整命令与逐行输出为了确证上述判定证据记录在隔离 worktree 中执行了与 CI 完全一致的复现当时的 CI typecheck 矩阵固定为 Bun 1.3.12cd /Volumes/mengmotaStorage/local-workspaces/omo-wt/fix/windows-ci-root-causes npx --yes bun1.3.12 install --frozen-lockfile --ignore-scripts npx --yes bun1.3.12 run typecheck观察到的输出原文照录bun install v1.3.12 (700fc117) $ tsgo --noEmit bun run typecheck:script bun run typecheck:packages $ tsgo --noEmit -p script/tsconfig.json $ tsgo --noEmit -p packages/.../tsconfig.json PINNED_TYPECHECK_DONE exit0复现时锁定的版本Bun 1.3.12 tsgo 7.0.0-dev.20260518.1逐行解读这段输出可以看到整个 gate 的执行路径bun install v1.3.12 (700fc117)使用固定版本的 Bun 执行安装$ tsgo --noEmit ...bun run typecheck启动先执行根级tsgo --noEmit$ tsgo --noEmit -p script/tsconfig.json进入typecheck:script环节$ tsgo --noEmit -p packages/.../tsconfig.json进入typecheck:packages环节PINNED_TYPECHECK_DONE exit0全部环节通过以 0 退出。三个关键参数值得展开--frozen-lockfile严格按bun.lock解析依赖禁止任何隐式版本浮动。这正是保证tsgo解析到7.0.0-dev.20260518.1lockfile 内固定版本而不是本地最新 dev 版本的原因——frozen lockfile 同时冻结了 TypeScript 编译器本身。--ignore-scripts跳过依赖的安装脚本。仓库根 package.json 的prepare钩子会触发bun run build--ignore-scripts让安装阶段不做任何构建把构建与检查彻底分离。npx --yes bun1.3.12通过npx临时拉取指定版本的 Bun不动用户全局安装的 Bun实现用 CI 的版本、用 CI 的路径。为什么这种复现足够与 CI 矩阵逐项对齐证据记录明确给出了为什么足够Why this is enough的论证可以逐项对照当时的 CI typecheck 矩阵维度CI 矩阵CI-pinned 复现Bun 版本固定 1.3.12npx bun1.3.12完全一致安装方式bun install --frozen-lockfile --ignore-scripts完全一致检查命令bun run typecheck完全一致覆盖范围根 script 全部包 TS 项目完全一致源码与诊断不改源码、不压制诊断完全一致该复现在没有修改任何源码、没有禁用任何诊断的前提下全绿通过直接证明了此前本地 Bun 1.4.0 / Node 26 上的失败纯粹是工具链漂移与fix/windows-ci-root-causes的补丁无关。这正是CI-pinned 复现方法论的核心价值——用 CI 自身的执行环境作为裁判而不是相信任何本地环境的解释。版本以当前仓库为准从 CI 工作流读取固定版本需要特别说明上述证据记录于 2026-08-10当时 CI 固定 Bun 1.3.12当前仓库的 CI 已经演进。以当前 .github/workflows/ci.yml 中的typecheckjob 为准typecheck: needs: [ci-mode] runs-on: ubuntu-latest steps: - uses: actions/setup-nodev7 with: node-version: 24 - uses: oven-sh/setup-bunv2 with: bun-version: 1.4.2 - run: bun install --frozen-lockfile --ignore-scripts - run: bun run typecheck即当前 CI 固定Node 24 Bun 1.4.2并同样使用--frozen-lockfile --ignore-scripts安装路径与bun run typecheck命令。因此实践中的正确做法是在动手复现前先打开 .github/workflows/ci.yml 读取当前的node-version与bun-version而不是照抄证据记录中的旧版本号。这也解释了 setup.sh 中版本检查的期望值来源。配套保障setup.sh 的工具链版本告警机制仓库在 script/agent/setup.sh 中内置了工具链漂移的主动检测逻辑expected_bun1.4.2 expected_node_major24 bun_version$(bun --version 2/dev/null || echo unknown) node_major$(node --version 2/dev/null | sed -E s/^v?([0-9]).*/\1/) [ $bun_version $expected_bun ] || log WARN: Bun $bun_version differs from CI-pinned $expected_bun (see .devcontainer/Dockerfile) [ $node_major $expected_node_major ] || log WARN: Node major $node_major differs from CI-pinned $expected_node_major该脚本是跨开发环境的统一 bootstrapCodex App、Cursor、Claude Code SessionStart、devcontainer postCreateCommand 均接入采用WARN 而不 FAIL的策略版本不一致只打印告警不阻断开发。配套的隔离 worktree 记录 setup-local.md 展示了告警实际触发时的样子[setup] WARN: Bun 1.4.0 differs from CI-pinned 1.3.12 [setup] WARN: Node major 26 differs from CI-pinned 24 build:codex-plugin build:senpi-plugin build: all steps completed SETUP_DONE exit0该记录还处理了另一类典型漂移本地 Bun 构建packages/omo-senpi/plugin/extensions/omo.js时产生了与 CI 无关的 minifier churn压缩器改写噪音经确认后仅对这一个生成文件执行git restore --sourceHEAD最终git status只剩分支名## fix/windows-ci-root-causes...origin/dev。生成物漂移要逐个甄别、逐项清理这是本地验证与 CI 保持可对比性的前提。证据闭环清理收据与不改源码原则证据记录最后给出了清理收据Cleanup receipt构成完整闭环监控进程monitor以 0 退出安装过程只改变了被 gitignore 的依赖状态node_modules 类目录git status中仅包含任务预期的四个源码文件无任何意外改动。把复现成功与工作区干净同时写入记录意味着后续任何人包括 Agent都能审计这个全绿结果不是靠隐藏错误或修改源码换来的。结合 .omo/evidence/20260810-windows-ci-root-causes/README.md 对整个证据目录的组织red-install、red-windows-tests、competing-pr-6708、typecheck 等分文件存档可以看出这是一种值得借鉴的工程实践失败先行failing-first、绿证归档、清理留痕。实践要点小结复现 CI 结论时永远用 CI 的版本与安装路径npx --yes bun当前ci固定版本 install --frozen-lockfile --ignore-scripts之后紧跟bun run typecheck不要把本地全局 Bun 当作可信执行环境先读 CI 再复现以 .github/workflows/ci.yml 中typecheckjob 的node-version/bun-version为唯一事实来源历史证据记录中的版本号只作参考区分错误归属报错若出现在未修改的代码上优先怀疑工具链漂移用 CI-pinned 复现验证而不是顺手修掉或压制诊断保留审计痕迹记录复现命令、原始输出、版本快照与清理收据确保全绿结论可被复核且工作区只含预期改动。【免费下载链接】oh-my-openagentOmO: Just type mass ulw keyword with your prompt. Now you are the master of graph engineering.项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-openagent创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考