尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

oh-my-codex 插件包 SSOT 契约:plugins/ 镜像目录的同步、校验与交付机制

oh-my-codex 插件包 SSOT 契约:plugins/ 镜像目录的同步、校验与交付机制 oh-my-codex 插件包 SSOT 契约plugins/ 镜像目录的同步、校验与交付机制【免费下载链接】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-codexoh-my-codex 仓库为每一类插件/配置资产只保留唯一的权威编写面canonical authoring surface并把plugins/oh-my-codex视为由权威面生成或校验的插件输出。本文围绕仓库中的 docs/plugin-bundle-ssot.md 契约展开结合 sync-plugin-mirror.ts、verify-native-agents.ts 等源码实现讲清 SSOT 的权威根、同步/校验命令、技能与 Native Agent 的治理流程以及prepack/CI 如何让打包时才暴露过期产物的隐患无处遁形。读完你将掌握如何安全地新增或废弃一个技能、为什么插件清单必须省略agents/prompts以及omx setup如何在不误删用户文件的前提下收敛旧资产。一、什么是插件包 SSOT 契约SSOTSingle Source of Truth单一事实来源的核心思想是同一种资产只允许有一个权威编写面其他位置一律视为派生产物。oh-my-codex 的插件包契约把这条规则落到两处权威面canonical roots位于仓库根目录的skills/、templates/、src/config/、package.json等派生面generated-or-verified output位于plugins/oh-my-codex/的镜像与元数据只能通过同步命令刷新必须与权威面逐字节一致。这种设计的直接收益是贡献者永远只需要编辑一个地方其余产物由脚本重放生成并在 CI 中非破坏性校验杜绝改了一处、漏了另一处的漂移。二、Canonical roots五类资产的权威面一览契约在文档中明确划定了五类资产的权威根资产类型权威根Canonical Root派生产物 / 约束插件技能skills/name/SKILL.md镜像plugins/oh-my-codex/skills/name/由npm run sync:plugin刷新由npm run verify:plugin-bundle校验技能目录成员资格templates/catalog-manifest.json决定哪些 catalog 技能可安装active/internal 技能 setup-only 策略追加项必须有权威技能目录与插件镜像插件 MCP 元数据src/config/omx-first-party-mcp.tsplugins/oh-my-codex/.mcp.json必须与buildOmxPluginMcpManifest()完全一致插件清单版本与路径package.json插件清单plugin manifest必须指向./skills/、./.mcp.json、./.app.jsonNative agents 与 prompts根prompts/ src/agents/definitions.tssetup 拥有的权威源官方插件有意不发布 plugin-scoped 的agents/prompts最后一行值得展开官方插件刻意不携带插件作用域的agents或prompts原因是这些资产属于setup 拥有setup-owned。插件 setup 会归档/移除旧版 OMX 管理的 prompt 文件但仍会从权威源刷新 setup 拥有的 Native Agent TOML从而保证agent_type路由可用。而官方 Codex 插件作用域的生命周期钩子则位于 plugins/oh-my-codex/hooks/hooks.json统一通过已安装的omxCLI 转接。三、三条命令同步、校验与兼容别名npm run sync:plugin # 变更型从权威根刷新插件镜像/元数据 npm run verify:plugin-bundle # 非变更型SSOT 一致性检查供 CI/评审使用 npm run sync:plugin:check # 兼容别名与上一条等价同为非变更型检查从 package.json 的 scripts 可以看到三个关键事实sync:plugin: node dist/scripts/sync-plugin-mirror.js是真正执行同步的入口sync:plugin:check与verify:plugin-bundle都等价于node dist/scripts/sync-plugin-mirror.js --check即同一个脚本的--check非变更模式prepack在打包前会依次执行npm run build npm run verify:native-agents npm run sync:plugin npm run verify:plugin-bundle npm run clean:native-package-assets。契约特别提醒虽然prepack会在发布前做同步与校验贡献者在评审之前仍应手动运行非变更型校验否则发布期的同步操作会把已经过期的插件产物悄悄修复掉掩盖评审时本应发现的漂移。也就是说verify:plugin-bundle的价值在于它是一面照妖镜任何未提交的权威面改动只要没有同步检查就会立刻失败。四、实现原理sync-plugin-mirror.ts 的同步与断言同步脚本的核心实现位于 src/scripts/sync-plugin-mirror.ts它对外暴露syncPluginMirror(options)支持check与verbose两个选项。4.1 同步模式mutating的完整流程读取 catalog manifest通过getSetupInstallableSkillNames()计算应安装的技能名集合调用assertRootSkillCatalogConsistency()做前置一致性断言见 4.3对比当前镜像compareSkillMirror()判断是否已漂移清空并重建plugins/oh-my-codex/skills/把skills/name逐个递归复制过去调用writePluginMetadata()重写四份派生元数据见第六节再次执行镜像与元数据断言保证同步结果自洽。脚本直接以 CLI 方式执行时通过isDirectCliInvocation()判断测试覆盖了仓库路径含空格的情况会打印类似[sync-plugin-mirror] synced N canonical skill director... and plugin metadata的摘要。4.2 校验模式non-mutating--check模式下脚本只执行两件事assertSkillMirror(rootSkillsDir, pluginSkillsDir, skillNames)逐文件比对技能镜像assertPluginMetadata(root)校验全部派生元数据。任何不一致都会抛出错误并设置非零退出码从而让 CI 直接变红。4.3 根技能目录与目录清单的一致性断言assertRootSkillCatalogConsistency()是防止目录清单与真实目录脱节的第一道闸门它断言四类不变量canonical_skill_missing凡是应安装集合里的技能名skills/name/SKILL.md必须真实存在canonical_skill_catalog_out_of_sync未列目录skills/下每个目录都必须出现在 catalog manifest 中或由 setup policy 显式包含否则报错——这正是文档所说未列出的根目录既不 installable 也未显式排除时校验必失败的代码出处canonical_skill_catalog_out_of_sync排除状态不想进入插件的根技能目录其 catalog 状态必须是alias、merged或deprecated三者之一否则无法证明它是有意排除installable 缺漏catalog 中所有active/internal技能必须落入插件/setup 的可安装集合。五、技能镜像与目录清单catalog manifest5.1 谁决定技能能否进入插件逻辑集中在 src/catalog/installable.tsexport const SETUP_ONLY_INSTALLABLE_SKILLS new Set([wiki]); export function isCatalogInstallableStatus(status) { return status active || status internal; } export function getSetupInstallableSkillNames(manifest) { return new Set([ ...manifest.skills.filter(s isCatalogInstallableStatus(s.status)).map(s s.name), ...SETUP_ONLY_INSTALLABLE_SKILLS, ]); }也就是说技能的可安装状态只有active对外提供与internal内部使用如worker其internalRequired: truedeprecated、alias、merged都不会进入插件镜像。wiki是一个 setup-only 策略追加项它不在 catalog 里标记为active但由SETUP_ONLY_INSTALLABLE_SKILLS显式纳入可安装集合。5.2 状态语义与 canonical 指向以 templates/catalog-manifest.json 实际内容为例activeautopilot、team、ralplan、ultragoal、deep-interview、wiki、worker(internal) 等deprecatedralph、ultrawork、pipeline、autoresearch-goal等——这些目录仍保留在skills/下但不再镜像mergedconfigure-discord/configure-telegram/configure-slack/configure-openclaw均声明canonical: configure-notifications表示能力已并入后者aliasgit-master等作为别名指向 canonical 技能。契约规定不打算进入插件的根技能目录在 catalog 中必须表示为alias或merged也包括deprecated否则镜像校验会因既不可安装又未被显式排除而失败。这条规则在 4.3 的断言中得到了落实也被 plugin-bundle-ssot.test.ts 的用例覆盖向skills/复制一个未编目的uncataloged-skill目录后check: true模式必然抛canonical_skill_catalog_out_of_sync。5.3 新增或修改技能的完整操作流按契约给出的四步操作配以源码依据编辑/新增权威技能修改或添加skills/name/SKILL.md同步目录清单在 templates/catalog-manifest.json 与 src/catalog/manifest.json 中新增/更新对应条目src/catalog/manifest.json是模板清单的运行时镜像供 catalog 读取逻辑使用构建并同步执行npm run build npm run sync:plugin把技能镜像到plugins/oh-my-codex/skills/name/非变更校验执行npm run verify:plugin-bundle确认一切一致后再提交评审。测试用例还演示了反向流程在 fixture 中把deep-interview的状态从active改为deprecated后执行同步mirroredSkillNames就不再包含它随后check依然通过——证明废弃技能的正确姿势就是改状态后同步而不是手动删除镜像。六、插件元数据四件套从权威源生成而非手写同步脚本会重写四份元数据文件每份都有明确的生成函数与断言。6.1 插件清单 plugins/oh-my-codex/.codex-plugin/plugin.json仓库中实际的 plugin.json 版本为0.21.2其中关键的路径字段为skills: ./skills/, mcpServers: ./.mcp.json, apps: ./.app.json, hooks: ./hooks/hooks.json这与buildExpectedPluginManifest()的期望完全一致name: oh-my-codex、version: pkg.version取自 package.json保证插件版本与包版本永不脱节、skills: ./skills/、mcpServers: ./.mcp.json、apps: ./.app.json、hooks: ./hooks/hooks.json。assertPluginManifestPolicy()更进一步做了负面断言对SETUP_OWNED_PLUGIN_MANIFEST_FIELDS [agents, prompts]如果清单中出现了这两个字段立即抛出plugin_bundle_metadata_out_of_sync与 setup-owned agents/prompts must not be plugin-scoped——这就是文档反复强调官方插件清单必须继续省略agents和prompts的机制保障。6.2 MCP 元数据 plugins/oh-my-codex/.mcp.json权威源是 src/config/omx-first-party-mcp.ts。其中定义了六个一等 MCP serveromx_state、omx_memory、omx_code_intel、omx_trace、omx_wiki、omx_hermes。插件场景下buildOmxPluginMcpManifest()生成的内容为mcpServers: { omx_state: { command: omx, args: [mcp-serve, state], enabled: false }, omx_memory: { command: omx, args: [mcp-serve, memory], enabled: false }, omx_code_intel:{ command: omx, args: [mcp-serve, code-intel],enabled: false }, omx_trace: { command: omx, args: [mcp-serve, trace], enabled: false }, omx_wiki: { command: omx, args: [mcp-serve, wiki], enabled: false }, omx_hermes: { command: omx, args: [mcp-serve, hermes], enabled: false } }注意插件模式下命令统一走omx mcp-serve target而不是 setup 模式下的 Node 绝对路径启动方式getOmxFirstPartySetupMcpServers()使用process.execPathdist/mcp/entrypoint.js。测试用例特别断言签入仓库的插件 MCP 元数据默认全部enabled: false由用户在运行时按需启用buildOmxPluginMcpManifest({ enabled: true })是显式的兼容性开启路径。6.3 apps 元数据与 hooks 元数据.app.json期望内容恒为{ apps: {} }当前没有内置 app但字段必须存在以符合插件接口plugins/oh-my-codex/hooks/hooks.json由buildOmxPluginHooksManifest()生成覆盖SessionStart、PreToolUse、PostToolUse、UserPromptSubmit、PreCompact、PostCompact、Stop等事件统一执行{ type: command, command: node \${PLUGIN_ROOT}/hooks/codex-native-hook.mjs\ }其中Stop事件带 30 秒超时SessionStart带matcher: startup|resume|clear。这些事件集来自MANAGED_HOOK_EVENTSsrc/config/codex-hooks.ts目前插件与 setup 的钩子覆盖保持一致。6.4 Hook Launcher 的内容契约校验器还对 plugins/oh-my-codex/hooks/codex-native-hook.mjs 做内容级检查必须包含omx-plugin-hook-launcher:v1与omx-plugin-hook-routing-only:v1两个契约标记同时不得出现native-anchor、createHmac/hmac、randomBytes、launch-claim、signature、claim等模式这些是旧版 setup 时代的残留实现确保 launcher 只做路由、不携带旧式 claim 签名逻辑。相关背景可参考 src/scripts/codex-native-hook.ts。七、Native Agent SSOTsetup 拥有的资产治理Native Agents 是setup 拥有的资产而不是插件作用域的捆绑资产。契约给出了完整的数据流每一步都能在源码中找到对应实现templates/catalog-manifest.json 与 src/catalog/manifest.json 以active/internal状态选出可安装的 Native Agent TOMLsrc/agents/definitions.ts 定义每个 agent 的元数据、模型车道、姿态posture、路由角色与工具姿态prompts/name.md提供提示词引导。即使某个 agent 状态变成merged/alias/deprecated其 prompt 文件仍属于 setup 拥有的 prompt 资产explore-harness与team-orchestrator则是显式声明的非 Native Agent prompt 资产见 src/agents/policy.ts 的NON_NATIVE_AGENT_PROMPT_ASSETSsrc/agents/native-config.ts 仅对active/internal的 Native Agent 生成 Codex TOMLomx setup把生成的 TOML 写入.codex/agents/name.toml并把 setup 拥有的 prompt 安装到.codex/prompts/name.md。7.1 verify:native-agents 的失败条件发布或评审前执行非变更校验npm run verify:native-agents从 src/scripts/verify-native-agents.ts 看该校验器在以下任一情况都会失败native_agent_definition_missing可安装的 catalog agent 缺少定义native_agent_prompt_missing缺少prompts/name.mdnative_agent_catalog_out_of_sync定义存在但不在 catalog agents 中native_agent_prompt_unclassifiedprompt 文件既不是 cataloged Native Agent也不是显式 setup prompt 资产native_agent_canonical_invalidalias/merged状态没有声明canonical、canonical 目标不在目录中、或 canonical 目标不是可直接安装状态——即merged/alias 的权威目标必须直接解析到可安装 agentnative_agent_toml_invalid生成出的 TOML 丢失必需元数据。校验器用iarna/toml解析并断言name、description、model_reasoning_effort、非空developer_instructions且指令文本中必须包含## OMX Agent Metadata段含- role、- posture、- model_class、- routing_role四行对于不允许委派的叶子 agent必须带有native_subagent_leaf_guard防递归护栏而允许委派的 agent 不得出现该护栏同时必须声明- native_subagent_delegation: allowednative_agent_plugin_boundary_violation插件清单出现agents/prompts字段。7.2 omx setup 的安全收敛逻辑omx setup对生成式 Native Agent TOML 采取安全收敛策略常规 setup 只会删除携带精确生成标记# oh-my-codex agent: name、且对应 catalog agent 已不再可安装的过期 TOML用户手写或无法判定的 TOML 一律保留--force才是显式的破坏性清理路径用于清理过期的非可安装 Native Agent 文件prompt 清理遵循 prompt 资产策略即使某 prompt 对应的 agent 不可安装只要它是 cataloged 或显式 setup 资产就会被保留。插件模式与传统 setup 模式的差异传统 setup 模式安装 prompts/Native Agents并管理.codex/hooks.json插件 setup 模式移除归档的旧版 prompt 副本、刷新 setup 拥有的 Native Agent TOML 以保证agent_type路由、只删除过期生成式文件当 Codex 报告[features].plugin_hooks特性时移除 setup 管理的.codex/hooks.json包装器而不是刷新它——把生命周期钩子的管理权彻底交给插件作用域的hooks ./hooks/hooks.json。八、测试与 CI 保障把契约变成可执行断言契约不是纸面约定而是被自动化测试牢牢钉死。核心测试文件是 src/catalog/tests/plugin-bundle-ssot.test.ts它在临时 fixture 中复制templates/、skills/、plugins/、package.json后验证直接 CLI 执行判定在仓库路径含空格时依然正确签入的插件包与权威根镜像完全一致含ultragoal、deep-interview、autopilot、ralplan且不包含ralph、ultrawork、pipeline插件 MCP 元数据默认全部 disabledbuildOmxPluginMcpManifest()默认禁用、{ enabled: true }显式启用篡改.mcp.json后check模式抛出plugin_bundle_metadata_out_of_sync/kindmcp-manifest同步模式能把被污染的元数据从权威根修复回来并让check重新通过把deep-interview降级为deprecated后它从镜像中消失未编目的uncataloged-skill目录触发canonical_skill_catalog_out_of_sync。这些用例同时被npm run testtest:plugin-boundaries:compiled会运行codex-plugin-layout、package-bin-contract、setup-hooks-shared-ownership与本文件以及prepack管线覆盖形成开发—评审—打包三段式护栏。九、总结oh-my-codex 的插件包 SSOT 契约可以浓缩为三条原则一个权威面多处派生产物技能看skills/目录成员看templates/catalog-manifest.jsonMCP 看 src/config/omx-first-party-mcp.ts版本看 package.jsonNative Agent 看prompts/与 src/agents/definitions.ts同步是唯一的写入通道校验是唯一的放行闸门npm run sync:plugin负责刷新npm run verify:plugin-bundle与npm run verify:native-agents负责把关prepack与 CI 负责兜底职责边界清晰skills/MCP/apps/hooks 属于插件作用域agents/prompts 属于 setup 作用域——这个边界同时被 manifest 负面断言、verify-native-agents 边界检查与omx setup的收敛策略三重守护。对维护者而言这套契约让新增技能、废弃技能、调整 MCP、变更 agent都变成可复现、可审查、可自动校验的标准流程对使用者而言它保证了plugins/oh-my-codex这个发布物在任何时刻都与仓库权威源一致不会出现文档说的能力包里有、实际插件里却没有的割裂。【免费下载链接】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),仅供参考
返回列表