# 从 OpenCode 分叉：增量全景

> 用 blob 比对找出上游基线 v1.14.19，再按目录清点 MiMo 新增、修改、删除了哪些文件，默认开启的统计上报，以及产品层面改了哪些名字。

- 作者：David（道雾轩）
- 专栏：MiMo Code 源码解读（https://daiw.net/manual/mimo-code.md）
- 最后更新：2026-09-17
- 原文：https://daiw.net/manual/mimo-code/fork-map
- 转载与引用：请注明出处并附原文链接（https://daiw.net/about/copyright）

MiMo Code 开源时只有一个整体提交，没有保留上游历史，`git log` 回答不了“它是从哪个 OpenCode 分出来的、改了什么”。本专栏的主线恰恰是这个增量，所以先把账算清楚：基线是哪个版本，增量落在哪些目录，哪些文件被删掉，以及改名改到了哪一层。

## 怎么确定上游基线

思路是比较文件内容的指纹。Git 的树对象里记着每个文件的 blob SHA，它只由文件内容决定，内容逐字相同的文件 SHA 必然相同。于是：

1. 用 `gh api` 调 `git/trees/<ref>?recursive=1` 取回 MiMo 首个开源提交（`8e5cc8a84b91`）的完整文件树，只保留 `packages/opencode/src/` 下的文件；
2. 对上游 `anomalyco/opencode` 的一批候选 tag 做同样的事；
3. 对每个 tag 统计两边都有的路径数，以及其中 SHA 相同的文件数。

逐字相同的文件越多，说明分叉点越近。结果是 **v1.14.19**（2026-04-20）最接近：509 个共同路径里有 280 个逐字相同。之后 MiMo 独立演进，没有再整体同步上游，旁证也不少：根 `package.json` 的 catalog 里 Effect 仍是 `4.0.0-beta.48`（`package.json:56`），TUI 仍在 `packages/opencode/src/cli/cmd/tui/`，服务端路由仍是 Hono，而[《OpenCode 源码解读》](https://daiw.net/manual/opencode/monorepo-map)对照的 v1.18.30 早已拆出 `packages/tui` 与 `packages/core`。

下文的“上游”一律指 v1.14.19 的 `packages/opencode/src`，数字口径是 git 跟踪的 `.ts` 与 `.tsx` 文件，排除 `test/` 目录与 `*.test.*`、`*.spec.*`，行数为 `wc -l` 的物理行。

## 总账

```mermaid
flowchart LR
  B["上游 v1.14.19<br/>443 个文件，80081 行"] --> S["逐字未动 182"]
  B --> M["有修改 254"]
  B --> D["删除 7"]
  S --> T["MiMo v0.1.14<br/>674 个文件，141012 行"]
  M --> T
  N["新增 238 个文件<br/>42274 行"] --> T
```

行数增加了约 76%，上游的 443 个文件里只有 182 个没被碰过。TS 之外还新增了不少非代码资产：30 个 `.txt` 提示词（2290 行）、5 个 `.js`（主要是内置 Workflow 脚本，1584 行）、405 个内置技能包文件（52900 行，在 `packages/opencode/src/skill/builtin/.bundle` 与 `packages/opencode/src/skill/compose/.bundle`），以及语音活动检测用的 1 个 `.wasm`。

## 增量落在哪些目录

把克隆与上游基线逐文件比较，就能按目录列出新增、修改、未动的文件。如果把所有文件类型都算进去，技能包会让 `skill/` 显得格外庞大，所以下表只数 TS 文件，与上面的总账口径一致，大致按增长的行数排序：

| 目录 | 文件：新增 / 修改 / 未动 | 行数：上游 → MiMo | 增量内容 | 本书篇目 |
| --- | --- | --- | --- | --- |
| `session/` | 34 / 18 / 2 | 6894 → 20906 | 检查点与重建、修剪与请求前缀快照、Goal、Max 模式、步骤分类与复读检测、会话导入 | 第 1 部分、[Goal](https://daiw.net/manual/mimo-code/goal)、[Max 模式](https://daiw.net/manual/mimo-code/max-mode)、[复读检测与重试](https://daiw.net/manual/mimo-code/loop-recovery) |
| `cli/cmd/tui/` | 49 / 73 / 36 | 19749 → 33526 | 七种界面语言、语音输入、登录对话框、目标与任务侧栏 | [终端体验](https://daiw.net/manual/mimo-code/tui) |
| `tool/` | 33 / 19 / 5，删 2 | 3976 → 13978 | `actor`、`task`、`memory`、`history`、`exec`、`cron`、`session`、`workflow` 等新工具，命令行式调用与输出精简，Git 隔离护栏 | 第 4、5、6 部分 |
| `workflow/`（新） | 11 / 0 / 0 | 0 → 2929 | Workflow 运行时与 QuickJS 沙箱，外加 4 个内置 `.js` 脚本 | [Workflow 运行时](https://daiw.net/manual/mimo-code/workflow-runtime)、[四个内置 Workflow](https://daiw.net/manual/mimo-code/builtin-workflows)、[exec 与 QuickJS 沙箱](https://daiw.net/manual/mimo-code/exec-sandbox) |
| `actor/`（新） | 11 / 0 / 0 | 0 → 2445 | 子智能体的注册、生成、等待与回收 | [Actor](https://daiw.net/manual/mimo-code/actors) |
| `provider/` | 2 / 12 / 20 | 8004 → 10405 | 模型能力登记、图片处理，适配层扩充 | [模型、提供方与提示词路由](https://daiw.net/manual/mimo-code/providers) |
| `llm-server/`（新） | 5 / 0 / 0 | 0 → 2221 | 兼容 OpenAI Chat Completions 协议的内置模型服务 | [内置 LLM 服务](https://daiw.net/manual/mimo-code/llm-server) |
| `server/` | 7 / 21 / 17 | 5885 → 7519 | 内置 LLM 服务与 workflow、交互式 bash 的路由，认证与限流 | 同上 |
| `mcp/` | 3 / 4 / 0 | 1522 → 3118 | 客户端采样、stdio 传输、工具结果归一 | [MCP](https://daiw.net/manual/mimo-code/mcp) |
| `plugin/` | 5 / 7 / 2 | 2685 → 4277 | MiMo 与 xAI 的登录插件，检查点写手收尾校验与子智能体进度检查两个钩子 | [模型、提供方与提示词路由](https://daiw.net/manual/mimo-code/providers)、[收件箱、团队与进度检查](https://daiw.net/manual/mimo-code/inbox-team) |
| `cron/`（新） | 8 / 0 / 0 | 0 → 1256 | 调度器、cron 表达式、自定节奏的循环 | [定时任务与循环](https://daiw.net/manual/mimo-code/cron) |
| `skill/` | 9 / 2 / 0 | 404 → 1400 | 内置技能与 compose 技能的构建期打包、技能检索 | [内置技能包与技能检索](https://daiw.net/manual/mimo-code/skills)、[Compose](https://daiw.net/manual/mimo-code/compose) |
| `history/`（新） | 8 / 0 / 0 | 0 → 712 | 会话轨迹的 FTS5 全文检索 | [历史轨迹与全文检索](https://daiw.net/manual/mimo-code/history) |
| `task/`（新） | 6 / 0 / 0 | 0 → 596 | 树状任务与完成门 | [树状任务](https://daiw.net/manual/mimo-code/tasks) |
| `permission/` | 2 / 1 / 3 | 520 → 1104 | Orchestrator 子会话的授权转发与持久化 | [Orchestrator](https://daiw.net/manual/mimo-code/orchestrator) |
| `inbox/`（新） | 5 / 0 / 0 | 0 → 574 | 智能体之间的收件箱 | [收件箱、团队与进度检查](https://daiw.net/manual/mimo-code/inbox-team) |
| `memory/`（新） | 7 / 0 / 0 | 0 → 498 | 记忆文件路径、全文索引、写入开关 | [分层记忆](https://daiw.net/manual/mimo-code/memory) |
| `metrics/`（新） | 6 / 0 / 0 | 0 → 197 | 使用统计上报 | 见下文 |
| `team/`（新） | 3 / 0 / 0 | 0 → 166 | 团队成员登记 | [收件箱、团队与进度检查](https://daiw.net/manual/mimo-code/inbox-team) |

`config/`、`flag/`、`agent/` 的变化是新配置段、新开关和新智能体，见[怎么读这份源码](https://daiw.net/manual/mimo-code/reading-the-source)；其余目录（`lsp/`、`acp/`、`snapshot/`、`format/` 等）改动很小，这些机制直接看 OpenCode 专栏即可。十个全新目录合计 70 个 TS 文件、11594 行。

内置工具列表的后半段集中了大部分新工具，末尾三个受开关控制（`packages/opencode/src/tool/registry.ts:296`）：

```ts
            tool.actor,
            tool.fetch,
            tool.search,
            tool.code,
            tool.mcptoolsearch,
            tool.skillsearch,
            tool.skill,
            tool.patch,
            ...(Flag.MIMOCODE_EXPERIMENTAL_LSP_TOOL ? [tool.lsp] : []),
            tool.planexit,
            tool.memory,
            tool.history,
            tool.task,
            tool.toolscript,
            ...(Flag.MIMOCODE_EXPERIMENTAL_CRON ? [tool.cron] : []),
            ...(Flag.MIMOCODE_EXPERIMENTAL_ORCHESTRATOR ? [tool.session] : []),
            ...(Flag.MIMOCODE_EXPERIMENTAL_WORKFLOW_TOOL ? [tool.workflow] : []),
```

其中 `tool.toolscript` 就是 `exec` 工具，注册后还要过一道筛选：只对 GPT 系列工具集或设了 `MIMOCODE_ENABLE_EXEC_TOOL` 时可用（`registry.ts:374`）。

## 被删掉的 7 个文件

| 上游文件 | 行数 | 去向 |
| --- | --- | --- |
| `tool/todo.ts` | 47 | `todowrite` 工具整个移除；MiMo 的 `task` 工具改成了持久化的树状任务，工具说明写明它是唯一的工作项工具。上游 `task` 工具原本的派发子智能体职责交给了新的 `actor` 工具 |
| `tool/websearch.ts` | 74 | 拆成目录 `tool/websearch/`，多了走 MiMo 平台接口的 `mimo.ts` |
| `util/opencode-process.ts` | 24 | 改名为 `util/mimo-process.ts`，环境变量换成 `MIMOCODE_RUN_ID` 与 `MIMOCODE_PROCESS_ROLE` |
| `v2/session.ts`、`v2/session-entry.ts`、`v2/session-entry-stepper.ts`、`v2/session-event.ts` | 69、219、261、458 | 上游当时的 V2 会话原型，整个 `v2/` 目录删除，对应的 `session_entry` 表由迁移 `20260423145421_remove_session_entry` 删掉 |

最后一行值得多说一句：上游此后继续推进 V2，到 v1.18.30 已经有了 `packages/core` 里的新内核（见 [V2 会话内核](https://daiw.net/manual/opencode/session-v2)）；MiMo 删掉了这条线，新功能大多直接挂在 V1 的 `SessionPrompt` 主循环上，`session/prompt.ts` 从 1844 行涨到了 5647 行，见[一条消息的旅程](https://daiw.net/manual/mimo-code/message-lifecycle)。

## 产品层面的改名

面向用户的名字基本都换了：

| 项 | 上游 | MiMo |
| --- | --- | --- |
| 命令名 | `opencode` | `mimo`（`packages/opencode/src/index.ts:76`） |
| 工作区包作用域 | `@opencode-ai/` | `@mimo-ai/`，CLI 的 npm 包是 `@mimo-ai/cli` |
| 环境变量前缀 | `OPENCODE_` | `MIMOCODE_` |
| 项目配置目录 | `.opencode` | `.mimocode`（`packages/opencode/src/config/paths.ts:31`） |
| 全局配置文件 | `opencode.jsonc`、`opencode.json` | `mimocode.jsonc`、`mimocode.json`（`packages/opencode/src/config/config.ts:543`） |
| 数据目录名 | `opencode` | `mimocode`，解析逻辑移到 `packages/shared/src/global.ts:6`，并支持 `MIMOCODE_HOME` |
| 系统提示词里的自称 | `You are opencode` | `You are MiMoCode`（`packages/opencode/src/session/prompt/default.txt:1`） |

开关文件 `flag.ts` 从 107 行涨到 441 行，`Flag` 对象里的键从 54 个增加到 111 个。上游的键除了 `OPENCODE_EXPERIMENTAL_PLAN_MODE`（MiMo 的 plan 相关工具不再受它控制）都换了前缀保留下来，不少新键附带说明默认值的注释，例如（`packages/opencode/src/flag/flag.ts:353`）：

```ts
  // Defaults to OFF (opt-in): the Orchestrator primary mode — a general
  // coordinator that delegates to child sessions via the `session` tool, with a
  // global singleton workspace and child permission-approval routing. Enable with
  // MIMOCODE_EXPERIMENTAL_ORCHESTRATOR=true (or the umbrella MIMOCODE_EXPERIMENTAL).
  MIMOCODE_EXPERIMENTAL_ORCHESTRATOR: MIMOCODE_EXPERIMENTAL || truthy("MIMOCODE_EXPERIMENTAL_ORCHESTRATOR"),
  // Defaults to OFF (opt-in): dynamic workflows and built-in workflows.
  // Enable with MIMOCODE_EXPERIMENTAL_WORKFLOW_TOOL=true (or the umbrella
  // MIMOCODE_EXPERIMENTAL flag).
  MIMOCODE_EXPERIMENTAL_WORKFLOW_TOOL:
    MIMOCODE_EXPERIMENTAL || truthy("MIMOCODE_EXPERIMENTAL_WORKFLOW_TOOL"),
```

数据库也有一处默认值变化：`MIMOCODE_DISABLE_CHANNEL_DB` 默认为真（`flag.ts:390`），所有发布渠道共用一个 `mimocode.db`，不再按渠道分库。

改名没有深入到内部标识：

- 源码目录仍叫 `packages/opencode`，根 `package.json` 的 `name` 仍是 `opencode`（`package.json:3`），`repository` 仍指向 `anomalyco/opencode`（`package.json:107`）；
- `packages/opencode/src` 里 65 个 Effect 服务标签有 62 个仍以 `@opencode/` 开头，连 `@opencode/Inbox`、`@opencode/TaskRegistry` 这样的新服务也不例外，只有 3 个用 `@mimocode/`；
- 构建期注入的常量仍叫 `OPENCODE_MIGRATIONS`、`OPENCODE_WORKER_PATH`、`OPENCODE_LIBC`（`packages/opencode/script/build.ts:270`），`packages/opencode/src/ide/index.ts:46` 仍读环境变量 `OPENCODE_CALLER`。

读源码时知道这一点，搜索时就不会漏：找服务用 `@opencode/`，找开关用 `MIMOCODE_`。

## 默认开启的使用统计

新目录里有一个与功能无关、但用户值得知道的：`metrics/` 订阅模型调用、工具调用、单轮请求与 Try-Best 检测四类总线事件，把耗时、token 数、工具名等字段上报到 `packages/opencode/src/metrics/client.ts` 里写死的地址。开关 `MIMOCODE_ENABLE_ANALYSIS` 默认为真，设为 `false` 或 `0` 才关闭（`flag.ts:108`，判断在 `packages/opencode/src/metrics/subscriber.ts:13`）。

## 不再维护的界面

仓库根 `AGENTS.md` 的 Core Focus 一节写得很明确（`AGENTS.md:15`）：

> Development focuses on the **TUI** (`packages/opencode/src/cli/cmd/tui/`) and the **engine core** it runs on. The Web, App and Desktop surfaces are not currently maintained.

代码里的对应是 `web` 命令被注释掉（`packages/opencode/src/index.ts:201`）。`packages/app`、`packages/desktop`、`packages/web` 与 `packages/console/*` 仍留在仓库里，但本书只读 `packages/opencode`：TUI 加引擎，外加它依赖的 `packages/shared`、`packages/plugin` 与 `packages/sdk/js`。

下一篇：[怎么读这份源码](https://daiw.net/manual/mimo-code/reading-the-source)——仓库布局、目录地图、代码约定、构建期宏、开关与新增的数据表，以及几条阅读路线。
