Problem Statement
用户安装 @matthewye/opencode-toolbox 插件后,缺乏一种方式来验证插件是否被 OpenCode 正确、完整地加载。目前用户只能通过观察 agent/command/skill 是否出现在 OpenCode 中来做主观判断,没有系统化的验证手段。初次安装或升级后尤其容易遗漏问题(如 dist/ 未构建、skill 路径未注册、principles 未注入等)。
Solution
提供一个 /toolbox-lint 命令,运行三层自检,输出结构化的 TOOLBOX_LINT_REPORT,逐项报告 PASS/FAIL/WARN。
插件在 config hook 中额外做两件事以支持自检:
- 写入自我报告 JSON(
.opencode/.toolbox-lint-report.json),记录实际注入的 agents、commands、skill paths、principles - 注入 Canary 探针(一个 skill + 一个 command),供运行时验证
User Stories
- As a 初次使用者, I want to run
/toolbox-lint after installing the plugin, so that I can confirm the installation is correct and complete - As a 开发者, I want to see a clear PASS/FAIL/WARN per-item report, so that I can quickly identify and fix specific issues
- As a 插件维护者, I want the lint to cover all injection channels (agents, commands, skills, upstream skills, principles), so that no registration path goes unverified
- As a 日常用户, I want to know whether the plugin is still correctly loaded after OpenCode or plugin upgrades
- As a CI operator, I want a machine-parseable report structure (TOOLBOX_LINT_REPORT: header + per-item verdicts), so that I can integrate the check into automated workflows
Implementation Decisions
三层检查架构
- L1 — 存在性检查:验证所有必需的文件和目录存在(dist/index.js, node_modules/, agents/.md, commands/.md, skills/, upstream/skills/, principles/, canary 文件等)
- L2 — 内容正确性检查:验证 YAML frontmatter 有效性、agent prompt 包含 Karpathy principles、SKILL.md 有 name/description、自我报告 JSON 与文件系统一致
- L3 — 功能冒烟检查:加载 canary skill、调用 canary command、加载上游 skill(如 tdd/caveman)、调用上游 command、dispatch agent、检查 bun runtime
自我报告 JSON
插件在 config hook 结束时将注入结果写入 .opencode/.toolbox-lint-report.json,每次启动覆盖写入。Schema 包含:
version: 插件版本generated_at: ISO 时间戳agents: 每个 agent 的注册状态及 principles 注入情况commands: 本地 commands 列表upstream_skill_commands: 从上游 SKILL.md 生成的 command 列表skill_paths: 已注册的 skill 目录绝对路径principles_injected: Karpathy principles 是否已注入 agent promptsinstructions_injected: 主 principles 是否已加入 config.instructions
Canary 探针
- Canary skill (
skills/_toolbox-canary/SKILL.md):被加载时返回 CANARY_OK: toolbox skill registration verified - Canary command (
commands/_toolbox-canary.md):被调用时输出 CANARY_OK: toolbox command registration verified - 两个探针均只用于验证,无其他副作用
命令设计
- 命令名:
/toolbox-lint - 无参数,总是运行全量 L1+L2+L3
- 输出格式:
TOOLBOX_LINT_REPORT: 报告头 + 逐层逐项 [PASS] / [FAIL] / [WARN] 清单 - 失败处理:仅报告,不自动修复
遗漏项 vs 现有命令
/toolbox-lint 自身在 L1 命令文件中被检查,形成自指(self-referential)验证/toolbox-lint 在 L3 中不自我调用(避免无限循环)
Testing Decisions
什么是好的测试
- 只通过 public interface(config hook 输出、command 执行结果)验证行为
- 不测试内部实现细节(如 readMarkdownConfigs 的中间状态)
测试接缝
| 接缝 | 位置 | 验证方式 |
|---|
| 自我报告写入 | config hook → .opencode/.toolbox-lint-report.json | 插件加载后文件存在且 schema 正确 |
| Canary skill 注册 | skills/_toolbox-canary/SKILL.md | skill 工具加载后返回固定签名 |
| Canary command 注册 | commands/_toolbox-canary.md | command 调用后输出固定签名 |
/toolbox-lint 执行 | commands/toolbox-lint.md → agent | 输出 TOOLBOX_LINT_REPORT 结构正确 |
参考现有模式
- 遵循现有
commands/*.md 的 YAML frontmatter 格式(description, arguments) - 报告输出格式参考
IMPLEMENTER_REPORT / REVIEWER_REPORT 的 header convention
Out of Scope
- 自动修复:
/toolbox-lint 只报告问题,不执行修复 - 持续监控:仅在用户主动调用时运行,不做后台 daemon
- 参数化检查:本期不支持
--level 或 --quick 参数,始终全量 - 非 toolbox 插件自检:此命令仅检查 toolbox 自身,不检查其他插件
- 性能 profiling:不测量 plugin 加载耗时
- GitHub Issue 上报:不自动创建 issue 报告 lint 结果
Further Notes
- Canary 文件(
skills/_toolbox-canary/SKILL.md、commands/_toolbox-canary.md)需要加入 .gitignore 或标记为自动生成,避免被误认为正式 skill - 自我报告文件
.opencode/.toolbox-lint-report.json 位于 .opencode/ 下,该目录由 OpenCode 管理,插件不负责创建父目录 - 需要创建 ADR 记录 self-report + canary 的设计决策
Problem Statement
用户安装
@matthewye/opencode-toolbox插件后,缺乏一种方式来验证插件是否被 OpenCode 正确、完整地加载。目前用户只能通过观察 agent/command/skill 是否出现在 OpenCode 中来做主观判断,没有系统化的验证手段。初次安装或升级后尤其容易遗漏问题(如 dist/ 未构建、skill 路径未注册、principles 未注入等)。Solution
提供一个
/toolbox-lint命令,运行三层自检,输出结构化的TOOLBOX_LINT_REPORT,逐项报告 PASS/FAIL/WARN。插件在
confighook 中额外做两件事以支持自检:.opencode/.toolbox-lint-report.json),记录实际注入的 agents、commands、skill paths、principlesUser Stories
/toolbox-lintafter installing the plugin, so that I can confirm the installation is correct and completeImplementation Decisions
三层检查架构
自我报告 JSON
插件在
confighook 结束时将注入结果写入.opencode/.toolbox-lint-report.json,每次启动覆盖写入。Schema 包含:version: 插件版本generated_at: ISO 时间戳agents: 每个 agent 的注册状态及 principles 注入情况commands: 本地 commands 列表upstream_skill_commands: 从上游 SKILL.md 生成的 command 列表skill_paths: 已注册的 skill 目录绝对路径principles_injected: Karpathy principles 是否已注入 agent promptsinstructions_injected: 主 principles 是否已加入 config.instructionsCanary 探针
skills/_toolbox-canary/SKILL.md):被加载时返回CANARY_OK: toolbox skill registration verifiedcommands/_toolbox-canary.md):被调用时输出CANARY_OK: toolbox command registration verified命令设计
/toolbox-lintTOOLBOX_LINT_REPORT:报告头 + 逐层逐项[PASS]/[FAIL]/[WARN]清单遗漏项 vs 现有命令
/toolbox-lint自身在 L1 命令文件中被检查,形成自指(self-referential)验证/toolbox-lint在 L3 中不自我调用(避免无限循环)Testing Decisions
什么是好的测试
测试接缝
confighook →.opencode/.toolbox-lint-report.jsonskills/_toolbox-canary/SKILL.mdcommands/_toolbox-canary.md/toolbox-lint执行commands/toolbox-lint.md→ agent参考现有模式
commands/*.md的 YAML frontmatter 格式(description, arguments)IMPLEMENTER_REPORT/REVIEWER_REPORT的 header conventionOut of Scope
/toolbox-lint只报告问题,不执行修复--level或--quick参数,始终全量Further Notes
skills/_toolbox-canary/SKILL.md、commands/_toolbox-canary.md)需要加入.gitignore或标记为自动生成,避免被误认为正式 skill.opencode/.toolbox-lint-report.json位于.opencode/下,该目录由 OpenCode 管理,插件不负责创建父目录