Codex 源码解析 · 第 34 讲
Codex 源码解析系列 第 34 讲:Plugins / Connectors / Marketplace 基于 OpenAI Codex 源码 · 2026-10-28 💡 本讲一句话: Codex 的插件不是"装完就完"——marketplace 决定它从哪来,cache/data 双目录决定它装到哪,manifest 双格式决定它怎么被读,最后 effective_*() 把 skills / MCP servers / apps / hooks 投影进运行时。本讲沿这条供给链逐行拆。 一、插件系统全景:一条"能力供给链" 前几讲我们拆过 skills(第 31 讲)和 hooks(第 32 讲),但它们的"上游供应商"一直没露面:插件。Codex 里一个插件可以同时携带四类能力——skills、MCP servers、ChatGPT apps(connectors)、hooks,而插件本身又来自 marketplace(市场)。整条链路是: 🔹 marketplace :插件的来源清单(git 仓库 / 本地目录),声明有哪些插件、怎么装 🔹 store : ~/.codex/plugins/ 下的安装布局,代码与数据分离 🔹 loader + manager :把磁盘上的插件读成内存对象,处理并发、缓存、账号切换 🔹 projection : PluginLoadOutcome::effective_* () 把四类能力分别投影给 skills 系统、MCP 连接层、app runtime、hooks 引擎 代码分布在三个 crate: core-plugins (manager.rs 3772 行、loader.rs 1920 行、store.rs 818 行、manifest.rs 1020 行、marketplace*.rs)、 plugin (LoadedPlugin / PluginLoadOutcome 数据模型,plugin/src/load_outcome.rs)、 connectors (ChatGPT app 连接器运行时)。入口在 core/src/plugins/mod.rs 第 33-46 行的 plugins_manager_for_config() ——它把 Config、AuthManager、HostSkillsService 三样东西组装进 PluginsManager,后面所有加载都走这个 manager。 二、安装布局:代码与数据为什么必须分家 先看 PluginStore(core-plugins/src/store.rs)。它只有三个字段——codex_home、root(代码缓存根)、data_root(数据根),但派生出的路径规则信息量很大: 📄 codex-rs/core-plugins/src/store.rs (第 123-146 行) pub fn root(&self) -> &AbsolutePathBuf { // 返回插件代码缓存根:~/.codex/plugins/cache &self.root // 直接借用内部字段,零拷贝暴露给 loader } pub(crate) fn codex_home(&self) -> &AbsolutePathBuf { // 暴露 codex home——缓存键、数据目录都要以它为基准 &self.codex_home // 同样零拷贝借用,避免每次 clone 路径 } pub fn plugin_base_root(&self, plugin_id: &PluginId) -> AbsolutePathBuf { // 某插件的"基础目录"= cache/{marketplace}/{plugin} self.root // 从缓存根出发 .join(&plugin_id.marketplace_name) // 先按 marketplace 分桶——同名插件在不同市场互不干扰 .join(&plugin_id.plugin_name) // 再落到具体插件名,形成两级命名空间 } pub fn plugin_root(&self, plugin_id: &PluginId, plugin_version: &st…
阅读全文:Codex 源码解析 第 34 讲