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

资讯详情

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

opencode 调试环境搭建手记:从 bun install 到 VSCode 断点

opencode 调试环境搭建手记:从 bun install 到 VSCode 断点 1. 为什么 opencode 值得从源码跑起来opencode 是一个用 TypeScript 写的终端 AI 编程助手整个仓库是 29 个 packages 的 monorepo包管理器用的是 BunCLI 入口在packages/opencode/src/index.ts。你当然可以直接npx opencode用发布好的二进制版本日常写代码完全够用。但只要你动了「想改它一行逻辑」「想知道 Agent 循环到底怎么跑的」「想给它加个子命令」的念头二进制版本就立刻变成黑盒console.log加不进去断点打不上变量看不到调用栈跟不了。这就是本地调试环境存在的意义。把 opencode 从源码跑起来之后你能在任意.ts文件按 F9 下断点执行到那一行自动停住能在 Variables 窗口悬停看值在 Watch 窗口跟表达式能通过 Call Stack 看清一次run命令从 yargs 解析到 Agent 循环的完整路径。对于读一个陌生 monorepo 来说调试器比文档有用得多——文档告诉你「做了什么」调试器告诉你「怎么跑的」。这篇手记聚焦一件事从零把 opencode 的本地调试环境搭起来。具体交付四样东西可复制的bun install依赖安装流程、VSCodelaunch.json断点配置片段、源码映射与热重载的验证步骤以及把模型 endpoint 改到统一 Key/API 通道完成联调的方法。适合已经会一点 TypeScript、想深入读 opencode 源码或做二次开发的开发者。全程命令都可以直接复制执行踩过的坑我会在排障章节里标出来。opencode 的调试环境搭建其实不复杂作者在仓库里留了.vscode/launch.example.json这个钥匙复制改名就能用。真正需要理解的是四个要素的选择包管理器为什么是 Bun、运行时为什么用--conditionsbrowser、IDE 为什么是 VSCode、入口为什么是packages/opencode/src/index.ts。把这四个想清楚后面所有配置都是顺理成章的。2. 前置准备Bun 版本、monorepo 结构与 TaoToken 通道2.1 确认 Bun 版本与 monorepo 依赖模型opencode 的package.json里写死了packageManager: bun1.3.14所以第一步是确认你本机的 Bun 版本对得上。版本不一致时bun install可能装出和 CI 不同的依赖树调试时会出现「我本地能跑、别人跑不了」的诡异问题。# 查看当前 Bun 版本 bun --version # 如果低于 1.3.14升级 bun upgrade # 再次确认 bun --version # 期望输出1.3.14 或更高为什么是 Bun 而不是 npm/pnpm因为 opencode 的 monorepo 用了 workspace catalog 的原生支持。29 个 packages 之间全部用workspace:*协议链接catalog 则把公共依赖的版本集中管理。Bun 对这两者的支持是内置的装依赖时不需要额外的 workspace 配置解析速度也快——实测 709 个依赖包安装完成大约 11 秒。2.2 理解--conditionsbrowser这个 flagopencode 的 dev 脚本是bun run --conditionsbrowser ./src/index.ts。这个--conditionsbrowser是 Bun 的 exports conditions 特性它让 TypeScript 在解析package.json的exports字段时走browser条件分支。举个仓库里的真实例子#db这个内部导入imports: { #db: { bun: ./src/storage/db.bun.ts, node: ./src/storage/db.node.ts, default: ./src/storage/db.bun.ts } }带上--conditionsbrowser之后跨平台模块会优先选浏览器兼容的实现。如果你不加这个 flag 直接bun run ./src/index.ts某些模块会解析到 Node 分支运行时可能报Cannot find module或者行为不一致。所以调试时务必用bun run dev不要自己拼命令。2.3 把模型 endpoint 指向 TaoToken 统一通道opencode 作为 AI 编程助手运行时需要调用模型 API。默认配置会指向官方 endpoint但在本地调试场景下把 endpoint 统一到一个 Key/API 通道更省事一个 Key 管多个模型切换模型不用改代码调试 Agent 循环时也不会因为 Key 分散而混乱。TaoToken 提供的就是这样一个统一通道官网在https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endAPI 基址是https://taotoken.net/api。你需要在 TaoToken 控制台创建一个 API Key然后在 opencode 的配置里把 Base URL 和 Key 填进去。具体配置片段在下一章给出这里先记住三件套Base URL、API Key、Model ID缺一不可。注意调试环境里改 endpoint 只影响你本地的源码运行不会动到仓库里提交的默认配置。建议用环境变量或本地配置文件覆盖不要把 Key 硬编码进源码。3. 可复制配置bun install 到 launch.json 全流程3.1 克隆仓库并安装依赖先把代码拉下来进入 monorepo 根目录执行安装。注意 opencode 的 dev 脚本 CWD 是packages/opencode但依赖安装要在仓库根目录做因为 workspace 链接是在根层解析的。# 克隆仓库假设你已经 fork 或直接 clone 上游 git clone https://github.com/sst/opencode.git cd opencode # 在仓库根目录安装全部 workspace 依赖 bun install安装完成后你会看到类似输出709 个依赖包安装完成29 个 workspace packages 全部用workspace:*协议链接。如果卡在某个包上先检查网络再检查 Bun 版本。3.2 复制并理解 launch.jsonopencode 源码里已经给了示例配置直接复制改名cp .vscode/launch.example.json .vscode/launch.json打开这个文件你会看到两个配置项。第一个是 attach 模式先用bun --inspect启动进程再在 VSCode 里 F5 attach 上去。第二个是 launch 模式F5 直接启动自动带 inspector。推荐用 launch 模式一键启动不用手动敲命令。一个可用的launch.json结构大致如下关键是runtimeExecutable指向 bunprogram指向入口文件cwd指向packages/opencode{ version: 0.2.0, configurations: [ { name: opencode (launch), type: bun, request: launch, program: ${workspaceFolder}/packages/opencode/src/index.ts, cwd: ${workspaceFolder}/packages/opencode, runtimeExecutable: bun, runtimeArgs: [run, --conditionsbrowser], console: integratedTerminal, internalConsoleOptions: neverOpen }, { name: opencode (attach), type: bun, request: attach, url: ws://localhost:6499/opencode } ] }type: bun需要你装了 VSCode 的 Bun Debug Extension。没装的话在扩展市场搜 Bun 装上否则 F5 会提示找不到调试类型。3.3 配置模型 endpoint 到 TaoTokenopencode 的模型配置通常在项目级或用户级配置文件里。把 Base URL 指向 TaoToken 的 API 地址Key 填你在控制台创建的 KeyModel ID 填你要调试的模型标识。三件套对照如下配置项值说明Base URLhttps://taotoken.net/api统一 API 通道不带 UTMAPI Key控制台创建建议用环境变量注入Model ID按需选择与 Key 权限匹配如果你用的是auth.json这类凭证文件Codex 风格结构大致是{ base_url: https://taotoken.net/api, api_key: sk-你的Key, model: 你的模型ID }提示调试 Agent 循环时建议先用一个便宜的小模型跑通流程确认断点能命中、请求能返回再换成正式模型。这样能排除「是代码问题还是模型问题」的干扰。4. 验证请求断点命中与热重载实测4.1 找到入口并下第一个断点opencode CLI 的真正入口是packages/opencode/src/index.ts。这个文件用 yargs 注册了 23 个子命令核心结构是hideBin(process.argv)去掉 bun run 自身参数.middleware()在命令执行前设置环境变量AGENT1、OPENCODE1、启动 Heap 监控然后一串.command(XxxCommand)注册子命令最后await cli.parse()交给 yargs 匹配执行。第一个断点建议下在await cli.parse()这一行。打开index.ts找到这行按 F9行号左边出现红点。然后按 F5选择opencode (launch)配置。CLI 启动后会停在这一行此时你可以按 F8Step Into跟进 yargs 内部看它怎么解析参数、怎么匹配命令。4.2 在 Agent 主循环下断点run命令是 opencode 最核心的命令它启动整个 Agent 循环。主循环在packages/opencode/src/cli/cmd/run/runtime.ts的runInteractiveRuntime()函数里。在这个函数第一行下断点然后重新 F5 启动在终端里执行run命令断点就会命中。命中后你能在 Variables 窗口看到当前会话状态、消息历史、工具调用列表在 Call Stack 里看到从index.ts的cli.parse()一路调用到runInteractiveRuntime()的完整链路。这就是源码调试的价值——你不再靠猜而是看着数据流走。4.3 验证热重载与源码映射Bun 的调试器支持源码映射你下的断点直接对应.ts源文件的行号不需要手动配 sourceMap。验证方法是改一行runtime.ts里的日志输出保存然后重新 F5。如果新日志出现在终端里说明源码映射和热重载都正常。如果你用的是 attach 模式流程是先在终端跑bun --inspect run --conditionsbrowser ./src/index.ts run然后在 VSCode 里 F5 选 attach 配置。attach 模式下改代码需要重启进程不如 launch 模式方便所以日常调试推荐 launch。4.4 确认模型请求走通断点命中后继续 F5 让流程往下走观察终端里是否有模型请求发出。如果配置了 TaoToken 通道请求会打到https://taotoken.net/api。你可以在 TaoToken 控制台看到调用记录确认 Key 生效、模型返回正常。这一步跑通说明调试环境和模型联调都完成了。5. 本篇常见错排查401、local proxy failed 与断点不命中5.1 401 Unauthorized最常见的报错是 401通常有三个原因。第一API Key 没填或填错检查配置文件里的api_key字段确认没有多余空格。第二Base URL 写成了带路径的形式比如https://taotoken.net/api/v1而实际应该用https://taotoken.net/api多一层路径会导致鉴权失败。第三Key 权限和 Model ID 不匹配比如用了一个只允许某几个模型的 Key 去调别的模型。排查顺序先用 curl 直接测 Key 是否有效排除配置文件解析问题。curl https://taotoken.net/api/v1/models \ -H Authorization: Bearer sk-你的Key如果 curl 返回 200说明 Key 没问题问题在 opencode 的配置读取如果 curl 也 401说明 Key 本身或 Base URL 有问题。5.2 local proxy failed这个报错通常出现在你本地配了某种转发但目标不可达时。opencode 调试环境本身不需要本地转发如果你看到local proxy failed先检查是不是环境变量里残留了HTTP_PROXY或HTTPS_PROXY指向了一个已经关掉的本地端口。清掉这些环境变量再启动unset HTTP_PROXY HTTPS_PROXY ALL_PROXY bun run dev另一个可能是 attach 模式下 WebSocket 地址不对。attach 配置里的url必须是ws://localhost:6499/opencode端口和路径都要和bun --inspect实际监听的一致。端口被占用时换个端口两边同步改。5.3 reading choices 报错Cannot read properties of undefined (reading choices)这个报错说明模型返回的响应结构和你代码里解析的字段对不上。常见原因是 endpoint 返回的不是 OpenAI 兼容格式或者请求根本没成功、返回了一个错误对象但代码直接去读response.choices。排查方法在发请求的那一行下断点命中后看response的实际内容。如果是错误对象先解决错误如果是格式不兼容检查 Base URL 是否指向了兼容 OpenAI 协议的通道。TaoToken 的 API 是 OpenAI 兼容的正常配置下不会出现这个问题。5.4 OAuth 相关报错如果你在调试登录流程时遇到 OAuth 报错先确认是不是在本地调试环境里误触了生产 OAuth 流程。调试环境应该用 API Key 直连不走 OAuth。检查配置文件里是否有残留的 OAuth token 字段清掉它们改用 Key 认证。5.5 断点不命中断点打了但 F5 之后没停通常是这几个原因launch.json里的program路径写错了指向了不存在的文件cwd没设成packages/opencode导致相对路径解析失败或者 Bun Debug Extension 没装VSCode 根本没启动调试器。逐个检查先确认扩展装了再确认路径对最后确认 Bun 版本匹配。6. 把调试环境用起来从读源码到改源码环境搭好之后opencode 的源码就从「只能读」变成了「可以玩」。你可以用 F5 启动在index.ts的cli.parse()下断点看 yargs 怎么把run --model xxx解析成命令和参数可以在runtime.ts的runInteractiveRuntime()下断点看 Agent 循环每一轮怎么组装消息、怎么调工具、怎么处理返回可以在模型请求发出前下断点看请求体长什么样确认 endpoint 和 Key 都正确注入。调试方式的选择上通读源码理解结构用 VSCode F5 Launch查一个特定 bug 用bun --inspect加 Chrome DevTools快速验证一个小改动用console.log记得删。三种方式各有适用场景不用死守一种。如果你打算长期在 opencode 上做二次开发或 Agent 调试可以考虑用 Coding Plan 这类长期编码方案把模型调用和调试流程固定下来省去每次配 Key 的麻烦。验证模型是否正常时可以直接在模型对话页面测一下通道是否通。接入过程中遇到配置问题API Keys 页面和接入文档里有完整的参数说明。最后留一个实操清单按顺序执行就能从零跑起来# 1. 确认 Bun 版本 bun --version # 期望 1.3.14 # 2. 克隆并安装依赖 git clone https://github.com/sst/opencode.git cd opencode bun install # 3. 复制调试配置 cp .vscode/launch.example.json .vscode/launch.json # 4. 用 VSCode 打开项目 code . # 5. 在 packages/opencode/src/index.ts 的 await cli.parse() 行按 F9 下断点 # 6. 按 F5选择 opencode (launch)开始调试断点命中之后你就真正进入了 opencode 的内部。剩下的就是顺着调用栈一行行看下去把「它怎么跑的」变成你自己的知识。
返回列表