[
  {
    "id": "01-cli-startup",
    "title": "CLI / 启动入口",
    "difficulty": "入门",
    "status": "complete",
    "estimatedMinutes": 35,
    "summary": "从一次带文件的 opencode run 出发，理解 bin、yargs、effectCmd、session 选择、事件订阅，以及本地与远程如何复用统一 SDK/server 边界。",
    "html": "chapters/01-cli-startup.html",
    "markdown": "markdown/01-cli-startup.md",
    "sourceFiles": [
      "packages/opencode/package.json",
      "packages/opencode/src/index.ts",
      "packages/opencode/src/cli/cmd/run.ts",
      "packages/opencode/src/cli/effect-cmd.ts"
    ]
  },
  {
    "id": "02-session-message",
    "title": "用户输入与会话",
    "difficulty": "中等",
    "status": "complete",
    "estimatedMinutes": 40,
    "summary": "从 text + file prompt 出发，理解 HTTP payload 如何选择 agent/model、解析 typed parts、经插件后持久化，并在 noReply 与 agent loop 之间分流。",
    "html": "chapters/02-session-message.html",
    "markdown": "markdown/02-session-message.md",
    "sourceFiles": [
      "packages/opencode/src/server/routes/instance/httpapi/groups/session.ts",
      "packages/opencode/src/server/routes/instance/httpapi/handlers/session.ts",
      "packages/opencode/src/session/prompt.ts",
      "packages/opencode/src/session/session.ts",
      "packages/opencode/src/session/message-v2.ts"
    ]
  },
  {
    "id": "03-agent-core-loop",
    "title": "Agent 核心循环",
    "difficulty": "较难",
    "status": "complete",
    "estimatedMinutes": 45,
    "summary": "沿一次“读取文件再回答”的典型源码路径，理解 OpenCode 如何以 session 消息为账本，执行工具、回填结果，并决定继续、压缩或停止。",
    "html": "chapters/03-agent-core-loop.html",
    "markdown": "markdown/03-agent-core-loop.md",
    "sourceFiles": [
      "packages/opencode/src/session/prompt.ts",
      "packages/opencode/src/session/processor.ts",
      "packages/opencode/src/session/run-state.ts",
      "packages/opencode/src/session/tools.ts",
      "packages/opencode/src/session/llm.ts",
      "packages/opencode/src/session/llm/ai-sdk.ts",
      "packages/opencode/src/session/message-v2.ts",
      "packages/opencode/src/cli/cmd/run.ts",
      "packages/opencode/src/server/routes/instance/httpapi/handlers/session.ts"
    ]
  },
  {
    "id": "04-llm-provider",
    "title": "模型 Provider / LLM 调用",
    "difficulty": "较难",
    "status": "complete",
    "estimatedMinutes": 50,
    "summary": "从已准备好的模型上下文出发，理解 provider client、system/options/tools/headers、消息兼容转换、native 回退与统一 LLMEvent。",
    "html": "chapters/04-llm-provider.html",
    "markdown": "markdown/04-llm-provider.md",
    "sourceFiles": [
      "packages/opencode/src/session/llm.ts",
      "packages/opencode/src/session/llm/ai-sdk.ts",
      "packages/opencode/src/session/llm/native-runtime.ts",
      "packages/opencode/src/provider/provider.ts",
      "packages/opencode/src/provider/transform.ts",
      "packages/llm/src/protocols/index.ts"
    ]
  },
  {
    "id": "05-tool-calling",
    "title": "Tool 调用系统",
    "difficulty": "中等",
    "status": "complete",
    "estimatedMinutes": 50,
    "summary": "从 read 能力出发，理解 Tool.define、registry 筛选、本轮绑定、参数校验、权限、hook、截断与 MCP 汇合。",
    "html": "chapters/05-tool-calling.html",
    "markdown": "markdown/05-tool-calling.md",
    "sourceFiles": [
      "packages/opencode/src/tool/tool.ts",
      "packages/opencode/src/tool/registry.ts",
      "packages/opencode/src/session/tools.ts",
      "packages/plugin/src/tool.ts"
    ]
  },
  {
    "id": "06-file-editing",
    "title": "文件读写与代码修改",
    "difficulty": "中等",
    "status": "complete",
    "estimatedMinutes": 40,
    "summary": "沿一次局部 edit，理解路径边界、进程内文件锁、容错匹配、diff 审批、落盘、格式化与 LSP 反馈。",
    "html": "chapters/06-file-editing.html",
    "markdown": "markdown/06-file-editing.md",
    "sourceFiles": [
      "packages/opencode/src/tool/read.ts",
      "packages/opencode/src/tool/edit.ts",
      "packages/opencode/src/tool/write.ts",
      "packages/core/src/filesystem/watcher.ts",
      "packages/opencode/src/format/",
      "packages/opencode/src/lsp/lsp.ts"
    ]
  },
  {
    "id": "07-shell-execution",
    "title": "Shell / 命令执行",
    "difficulty": "较难",
    "status": "complete",
    "estimatedMinutes": 45,
    "summary": "沿一次测试命令，理解 shell tool 的 parse、collect、ask、run 管线，以及外部路径、输出截断、取消和超时边界。",
    "html": "chapters/07-shell-execution.html",
    "markdown": "markdown/07-shell-execution.md",
    "sourceFiles": [
      "packages/opencode/src/tool/shell.ts",
      "packages/opencode/src/session/prompt.ts",
      "packages/opencode/src/session/run-state.ts",
      "packages/opencode/src/permission/index.ts"
    ]
  },
  {
    "id": "08-lsp-diagnostics",
    "title": "LSP / 诊断 / 上下文增强",
    "difficulty": "较难",
    "status": "complete",
    "estimatedMinutes": 45,
    "summary": "沿一次 edit 后诊断，理解 LSP client 的懒启动与复用、didOpen/didChange、push/pull diagnostics 和 best-effort 边界。",
    "html": "chapters/08-lsp-diagnostics.html",
    "markdown": "markdown/08-lsp-diagnostics.md",
    "sourceFiles": [
      "packages/opencode/src/lsp/lsp.ts",
      "packages/opencode/src/lsp/client.ts",
      "packages/opencode/src/lsp/diagnostic.ts",
      "packages/opencode/src/tool/edit.ts",
      "packages/opencode/src/tool/write.ts"
    ]
  },
  {
    "id": "09-permission-security",
    "title": "权限、审批、安全边界",
    "difficulty": "中等",
    "status": "complete",
    "estimatedMinutes": 40,
    "summary": "沿一次 edit 审批，理解 last-match ruleset、Deferred 等待、once/always/reject，以及默认 Agent 策略与非交互拒绝。",
    "html": "chapters/09-permission-security.html",
    "markdown": "markdown/09-permission-security.md",
    "sourceFiles": [
      "packages/opencode/src/permission/index.ts",
      "packages/opencode/src/permission/evaluate.ts",
      "packages/core/src/v1/permission.ts",
      "packages/opencode/src/agent/agent.ts",
      "packages/opencode/src/session/tools.ts"
    ]
  },
  {
    "id": "10-config-system",
    "title": "配置系统",
    "difficulty": "较难",
    "status": "complete",
    "estimatedMinutes": 45,
    "summary": "沿一次项目配置的合并路径，理解远程、全局、项目、内联与托管来源如何经过替换、校验、规范化和 provenance 保留，最终影响 agent、permission 与 plugin。",
    "html": "chapters/10-config-system.html",
    "markdown": "markdown/10-config-system.md",
    "sourceFiles": [
      "packages/opencode/src/config/config.ts",
      "packages/opencode/src/config/agent.ts",
      "packages/core/src/v1/config/permission.ts",
      "packages/opencode/src/config/plugin.ts",
      "packages/opencode/src/project/bootstrap.ts"
    ]
  },
  {
    "id": "11-ui-tui-desktop-ide",
    "title": "UI / TUI / Desktop / IDE 相关",
    "difficulty": "中等到较难",
    "status": "complete",
    "estimatedMinutes": 35,
    "summary": "沿一次 VS Code 选区进入 TUI 的路径，理解 CLI、TUI、Web、Desktop 与 IDE 如何通过命令和事件共享同一套 runtime。",
    "html": "chapters/11-ui-tui-desktop-ide.html",
    "markdown": "markdown/11-ui-tui-desktop-ide.md",
    "sourceFiles": [
      "packages/opencode/src/cli/cmd/run.ts",
      "packages/opencode/src/cli/cmd/run/",
      "packages/opencode/src/cli/tui/",
      "packages/app/package.json",
      "packages/ui/package.json",
      "packages/desktop/package.json",
      "sdks/vscode/package.json",
      "sdks/vscode/src/extension.ts"
    ]
  },
  {
    "id": "12-sdk-api-extension",
    "title": "SDK / API / 对外扩展点",
    "difficulty": "中等",
    "status": "complete",
    "estimatedMinutes": 40,
    "summary": "沿一次 session prompt API 调用，理解 typed HTTP contract、generated SDK、SSE 事件与 plugin hook 如何组成受控扩展边界。",
    "html": "chapters/12-sdk-api-extension.html",
    "markdown": "markdown/12-sdk-api-extension.md",
    "sourceFiles": [
      "packages/opencode/src/server/server.ts",
      "packages/opencode/src/server/routes/instance/httpapi/api.ts",
      "packages/opencode/src/server/routes/instance/httpapi/groups/session.ts",
      "packages/opencode/src/server/routes/instance/httpapi/handlers/session.ts",
      "packages/sdk/js/src/client.ts",
      "packages/sdk/js/src/server.ts",
      "packages/opencode/src/plugin/index.ts",
      "packages/plugin/src/index.ts"
    ]
  },
  {
    "id": "13-testing-engineering",
    "title": "测试与工程化",
    "difficulty": "入门",
    "status": "complete",
    "estimatedMinutes": 30,
    "summary": "沿一次 package 级改动的验证路径，理解 workspace、Turbo 任务图、测试根目录保护、类型检查和 SDK 生成如何形成工程信任链。",
    "html": "chapters/13-testing-engineering.html",
    "markdown": "markdown/13-testing-engineering.md",
    "sourceFiles": [
      "package.json",
      "turbo.json",
      "tsconfig.json",
      "AGENTS.md",
      "packages/opencode/package.json",
      "packages/sdk/js/package.json"
    ]
  },
  {
    "id": "14-mini-coding-agent",
    "title": "从 OpenCode 反推 mini coding agent",
    "difficulty": "中等",
    "status": "complete",
    "estimatedMinutes": 60,
    "summary": "把 CLI、session、LLM、tool、permission 与 processor 的最小机制重组为一个可实现、可观察、可设安全边界的 mini coding agent。",
    "html": "chapters/14-mini-coding-agent.html",
    "markdown": "markdown/14-mini-coding-agent.md",
    "sourceFiles": [
      "packages/opencode/src/cli/cmd/run.ts",
      "packages/opencode/src/session/prompt.ts",
      "packages/opencode/src/session/llm.ts",
      "packages/opencode/src/tool/tool.ts",
      "packages/opencode/src/session/tools.ts",
      "packages/opencode/src/permission/index.ts",
      "packages/opencode/src/tool/read.ts",
      "packages/opencode/src/tool/edit.ts",
      "packages/opencode/src/tool/shell.ts",
      "packages/opencode/src/session/processor.ts",
      "packages/opencode/src/server/routes/instance/httpapi/handlers/event.ts"
    ]
  }
]
