@herouucn/opencode-commandcode
v0.1.12
Published
Inject Command Code API provider into opencode — access Claude, GPT, Gemini, DeepSeek, Qwen, Kimi, GLM, MiniMax & Step via unified Command Code API. / 将 Command Code API provider 注入 opencode —— 通过统一的 Command Code API 使用 Claude、GPT、Gemini、DeepSeek、Qwen、Kim
Maintainers
Readme
opencode-commandcode
Command Code(统一多模型 API)的 opencode provider。一个 key 即可在 opencode 中使用 Claude、GPT、Gemini、DeepSeek、Qwen、Kimi、GLM、MiniMax、Step 等 70+ 模型。
安装即用:插件启动时自动注入 provider 配置、API key 读取与最新模型目录,无需任何手写配置;模型目录随上游发布自动同步,新模型即时可用。
特性
| 特性 | 说明 |
|---|---|
| 零配置接入 | 安装后重启 opencode 即可使用,provider 配置与模型列表自动注入 |
| 单 key 多模型 | 一个 Command Code API key 聚合 70+ 模型(Claude、GPT、Gemini、DeepSeek 等) |
| 运行时目录同步 | 每次启动拉取最新 models.json,上游新模型即时生效 |
| 离线兜底 | 拉取失败自动回退本地缓存 → 包内静态目录;缓存带时间戳,按新鲜度择优 |
| 目录自同步 | CI 每 6 小时检测上游 command-code 新版本并直推 main |
| 安全发布 | 基于 GitHub OIDC Trusted Publishing 发布 npm,无需 long-lived token |
演示
安装插件 → 重启 opencode → /models 中选择 Command Code 模型 → 直接对话。
安装
安装插件:
opencode plugin @herouucn/opencode-commandcode或手动在 opencode.json 声明:
// opencode.json
{
"plugin": ["@herouucn/opencode-commandcode"]
}本地开发可直接用路径:"plugin": ["file:///absolute/path/to/opencode-commandcode"]。
版本兼容(opencode v1 / v2 双入口)
本插件是 one-package 双版本,入口随 opencode 大版本而不同:
| opencode | 入口 | 说明 |
|---|---|---|
| v2 | 包名或目录 | 组合入口(plugin/index.ts),读 id / setup |
| v1(≥ 1.18.29) | @herouucn/opencode-commandcode/plugin.v1 | 纯 V1 adapter(对应文件 plugin/v1.ts) |
v1 的 opencode.json 写法:
// opencode.json(opencode v1)
{
"plugin": ["@herouucn/opencode-commandcode/plugin.v1"]
}本地路径用法(v1):
// opencode.json(opencode v1,本地开发)
{
"plugin": ["file:///absolute/path/to/opencode-commandcode/plugin/v1.ts"]
}v1 不要挂目录或包名(即 "plugin": ["@herouucn/opencode-commandcode"])。原因:v1 的配置挂载路径对含顶层 await 的目录入口求值会崩溃(模型列表为 0),且 v1 运行时不注入 @opencode/plugin,所以 v1 必须改用不依赖它的纯 V1 adapter plugin/v1.ts。
重启 opencode 后在 /models 中选择 Command Code 模型即可对话。
模型引用格式(V1 / V2 通用)
模型引用一律写成 commandcode/<完整 id>,两个大版本格式完全相同,一份配置(如
oh-my-opencode-slim、opencode.json 的 model 字段、opencode run --model)无需按版本分叉:
| 场景 | 写法 |
| --- | --- |
| deepseek v4.1 flash | commandcode/deepseek/deepseek-v4.1-flash |
| MiniMax M3 Free | commandcode/MiniMaxAI/MiniMax-M3-Free |
原因是 src/catalog.ts 的 toConfigKey 恒等返回目录 id(含首段、含内部斜杠、含大小写),
V1 注入的 config key 与 V2 的 model id 逐字一致。(历史版本曾在 V1 剥掉首段并转小写,
导致 V1 写 commandcode/deepseek-v4.1-flash、且 minimax/… 与 MiniMaxAI/… 撞 key——已废弃。)
V2 下用 auth login 录入 API key
opencode v2 的 auth login 候选列表来自 integration 注册表,插件已按 v2 机制注册
commandcode integration(一个 key 方法 + 一个 COMMANDCODE_API_KEY env 方法):
opencode auth login commandcode # v2:位置参数(/connect 里搜 Command Code)
opencode auth login --provider commandcode # v1:flag 形态(见上表入口差异)- 通过
auth login录入的 key 会存成 credential,并覆盖插件注入的settings.apiKey模板(即 credential 优先;没有 credential 时才回落到模板 / 环境变量)。 - 环境变量方式依然可用;此时
opencode auth list会把COMMANDCODE_API_KEY显示为commandcode的 environment 连接(无需登录)。 - 注册 integration 后插件会同时把 provider 的
activation固定为enabled(opencode v2 的 provider 可用性判定在有同名 integration 时不再走「无 integration」兜底分支), 因此未配置任何凭证时 provider 与模型列表仍然可用。
配置
API key 任选一种方式提供:
export COMMANDCODE_API_KEY="你的 key" # 方式一:环境变量opencode auth login --provider commandcode # 方式二:交互式(/connect 搜 Command Code)方式三:~/.commandcode/auth.json(若已用官方 CLI 登录则自动复用)。
插件自动注入 provider 配置(
npm、baseURL、模型列表)且不覆盖已存在的手写配置。手动配置provider.commandcode.options.baseURL时请保留npm: "@ai-sdk/openai-compatible"或指定其他兼容 SDK,否则 opencode 无法解析 provider。
目录源(可选覆盖)
默认拉取本仓库 main 分支的 models.json,一般无需配置。可用环境变量 COMMANDCODE_CATALOG_URL 或配置 catalogUrl 覆盖:
| 取值 | 行为 |
|---|---|
| URL | 每次启动拉取该地址(8s 超时),成功后写本地缓存 |
| disabled | 关闭远程拉取,仅用包内静态 models.json |
工作原理
插件采用 opencode 的 config hook:opencode 每次启动时执行插件导出的 config 函数,并向其传入待解析的全局配置。插件在 config hook 中完成两件事:
- 注入 provider 配置:通过
??=确保provider.commandcode块存在,并补齐npm: "@ai-sdk/openai-compatible"、name、COMMANDCODE_API_KEYenv 与默认baseURL,实现安装即用、零手写配置。若用户已显式书写该块,插件不会覆盖已存在字段。 - 注入模型目录:按
远程 models.json → opt-in 本地包 → 包内静态 → 本地缓存顺序加载模型列表,写入provider.commandcode.models。
配合 opencode 的 auth hook 声明 API Key 认证方式,/connect 与 opencode auth login --provider commandcode 可直接完成登录。
sequenceDiagram
autonumber
participant NPM as command-code 官方 npm
participant CI as catalog-sync CI
participant REPO as 本仓库 main
participant PLUGIN as 插件 config hook
participant CACHE as 本地缓存
participant OC as opencode 模型列表
rect rgb(235, 248, 255)
Note over NPM,REPO: 同步线 · 每 6 小时(后台)
NPM->>CI: 发布新版本 command-code@X
CI->>CI: 比对 _version.txt,版本不一致
CI->>CI: sync-models 提取模型
alt 提取成功且模型数达标
CI->>REPO: 直推 models.json(不经 PR)
else 提取失败 / 跌破保护线
CI->>REPO: 开 catalog-break issue,不推坏数据
end
end
rect rgb(255, 250, 235)
Note over PLUGIN,OC: 使用线 · 每次启动(用户可见)
PLUGIN->>REPO: fetch raw models.json(8s 超时)
alt 拉取成功
PLUGIN->>CACHE: 写入缓存(带 generatedAt 元数据)
else 拉取失败
PLUGIN->>CACHE: 缓存 vs 包内目录,按新鲜度择优
end
CACHE->>PLUGIN: 模型列表
PLUGIN->>OC: 注入 provider.commandcode.models
end三处关键设计:
- 目录自更新:
.github/workflows/catalog-sync.yml每 6 小时比对上游command-codenpm 版本与_version.txt,有新版本则重新提取模型并直接推送到 main。 - 运行时解耦:插件每次启动 fetch 本仓库 raw
models.json,模型更新不依赖 npm 发版。 - 质量护栏:模型数跌破保护线时触发
catalog-breakissue 并回滚,坏数据不落库。
发布
本仓库使用 GitHub OIDC Trusted Publishing,无需 long-lived npm token。push v* tag 触发 release.yml:先跑 check(lint + format + typecheck + unit test),通过后 npm publish --provenance。
npm version patch # 或 minor / major
git push origin main --tagsnpm 包:@herouucn/opencode-commandcode
开发与维护
bun install
bun run check # CI 门槛:oxlint + oxfmt --check + bun test + tsc
bun run sync -- --remote # 本地手动刷新 models.json / manifest.json / _version.txt⚠️
models.json、manifest.json、_version.txt由 CI / 同步脚本自动生成,不要手改。
CI 一览:
ci.yml— 4 个 check(test / typecheck / lint / format),push 与 PR 触发。catalog-sync.yml— 每 6 小时 + 手动 dispatch,直推 main(不经 PR、不发版)。release.yml— pushv*tag 或手动 dispatch,check + trusted publishing 发布。
常见问题
模型列表不更新?
先确认能访问 https://raw.githubusercontent.com/herouu/opencode-commandcode/main/models.json;再查本机状态 ~/.local/state/opencode/commandcode-provider/startup.json:
catalogSource应为remote;为cache/bundled表示本次走了兜底(degraded会为true,degradedReason说明原因)。- 兜底时不是固定优先级:本地缓存与包内静态目录都有时间戳(
catalogGeneratedAtvsmanifest.generatedAt),取更新的那一份;旧格式缓存(裸数组、无时间戳)退化为比较模型数量。 - 只有
remote/opt-in-local成功才写缓存,包内目录不会写进缓存,避免把随包冻结的旧目录钉死在缓存里。
升级插件后模型列表还是旧的 / 行为异常?
opencode 将插件缓存于 ~/.cache/opencode/packages/@herouucn/。删除该目录后重跑 opencode models 强制重拉最新版:
Remove-Item -Recurse -Force "$HOME\.cache\opencode\packages\@herouucn"opencode models 报 undefined is not an object (evaluating '$.models')?
确认已升级到 v0.1.7 及以上。v0.1.6 及更早版本在全局配置 provider: {}(空对象)时,config hook 会跳过 commandcode 注入,导致 opencode 内部崩溃。v0.1.7 起改用 ??= 确保 commandcode 块始终存在。
离线环境能用吗?
能。首次成功后模型已写入本地缓存;离线启动时走 bundled → cache 回退链,模型不缺失。
致谢
本项目由 herouu 独立维护。初始灵感来自 BrainerVirus/opencode-commandcode(Brent Weatherall 原始实现),现已完全独立开发。
许可证
MIT — 见 LICENSE。
