🧰opencode-kit:把 OpenCode 的工作流做成可复用扩展
约 4247 字大约 14 分钟
OpenCodePluginSkillsTypeScript
2026-07-14
OpenCode 本身提供执行能力,但一次完整的 Agent 工作流还缺少很多东西: 如何观察会话,如何澄清需求,如何压力测试方案,如何处理视频素材。
opencode-kit做的不是再造一个 Agent,而是把这些容易重复的工作整理成插件和 Skill。

项目到底包含什么
opencode-kit 当前由两部分组成:一个 npm package,以及四个放在 .opencode/skills/ 下的项目级 Skill。
| 类型 | 名称 | 作用 |
|---|---|---|
| Plugin | opencode-peek | 检查当前 OpenCode 会话,并生成 HTML transcript |
| Skill | brainstorming | 将模糊想法整理成设计和规格说明 |
| Skill | grilling | 在实现前逐项压力测试方案 |
| Skill | video-download | 使用 yt-dlp 下载视频、音频、字幕和元数据 |
| Skill | video-understand | 使用 FFmpeg 抽帧,并用 Whisper 本地转录视频 |
这个划分很清楚:
opencode-peek是真正需要安装和构建的 OpenCode 插件。- 四个 Skill 是 Markdown 工作流,核心内容写在各自的
SKILL.md中。 - 根目录使用 npm workspace 管理 package,Skill 则随 OpenCode 项目配置一起使用。
因此,opencode-kit 不是一个只有一个功能的插件仓库,也不是一个已经封装好所有能力的 Agent 框架。它更像一个个人工作流工具箱:把不同类型的高频任务放在一个仓库里统一维护。
仓库结构
当前仓库的结构如下:
opencode-kit/
├── assets/ # 根 README 使用的图片资源
├── .opencode/
│ ├── opencode.json # OpenCode 项目配置
│ └── skills/
│ ├── brainstorming/
│ │ └── SKILL.md
│ ├── grilling/
│ │ └── SKILL.md
│ ├── video-download/
│ │ └── SKILL.md
│ └── video-understand/
│ ├── SKILL.md
│ ├── references/
│ │ └── output-format.md
│ └── scripts/
│ └── understand_video.py
├── packages/
│ └── opencode-peek/
│ ├── src/
│ │ ├── lib/
│ │ └── plugin.ts
│ ├── scripts/
│ │ └── copy-assets.mjs
│ ├── README.md
│ ├── README.zh-CN.md
│ ├── package.json
│ └── tsconfig.*.json
├── package.json
└── package-lock.json根目录的 package.json 是一个私有 workspace:
{
"name": "opencode-kit",
"private": true,
"workspaces": ["packages/*"],
"scripts": {
"build": "npm run build --workspace opencode-peek",
"test": "npm run test --workspace opencode-peek",
"pack:peek": "npm pack --workspace opencode-peek"
}
}根目录并不直接编译所有源码,而是把 build、test 和 pack:peek 转发给 opencode-peek workspace。这样未来新增 package 时,可以继续保持每个 package 独立构建、独立测试和独立发布。
opencode-peek:给 OpenCode 加一层会话可观测性
将当前 OpenCode 会话渲染为 HTML transcript,并提供 Token Usage 报告和可扩展主题。
opencode-peek 的定位非常具体:把当前 OpenCode 会话转换成一个可读、可交互的 HTML transcript。
它提供的功能包括:
- 当前会话的 HTML transcript
- Token Usage 报告
- 自定义工具的稳定颜色分配
- 根据模型识别的本地头像
- 可扩展的主题渲染基础
当前 package 版本是 0.1.5,使用 ESM,入口为 dist/plugin.js,发布包只包含 dist、README 和 LICENSE。它声明了 OpenCode plugin 的 peer dependency:
{
"peerDependencies": {
"@opencode-ai/plugin": ">=1.17.14 <2"
},
"engines": {
"node": ">=22"
}
}这里的版本约束很重要:插件不是独立运行的 CLI,它依赖 OpenCode plugin API 注册工具,所以 OpenCode 的主版本和插件 API 需要保持兼容。
opencode-peek 的工作链路
它不是直接把聊天记录拼成一个 HTML 文件,而是将采集和渲染拆成两个工具:
session_inspect 负责采集
session_inspect 读取当前会话,生成 session report 和 snapshot,里面会涉及:
- 会话消息
- 工具调用
- token 使用量
- 系统提示词
- 模型元数据
- 工具输出
结构化产物会写入:
.workspace/cache/session-inspect/
├── latest.json
├── latest.md
└── sessions/
└── <session-id>/latest.json 方便程序继续读取,latest.md 方便人直接查看;sessions/<session-id>/ 用来保留按会话隔离的原始结果,避免不同会话互相覆盖。
peek 负责渲染
peek 消费 session_inspect 生成的快照,不需要重新扫描当前会话,最终将页面写入:
.workspace/cache/peek/latest.html页面包含双栏 transcript、Token 侧边栏、详细 Token 报告弹窗、模型头像和工具颜色。自定义工具的颜色根据工具名称稳定分配,因此同一个工具在不同会话中不会随机变色;OpenCode 内置工具则使用中性色。
当前内置的是 pixel 主题,但主题层和 session inspection 数据链路已经分离。未来增加主题时,不需要重新实现会话采集逻辑。
安装与配置
要求:Node.js >=22,OpenCode >=1.17.14。
让 Agent 自动配置
官方推荐将下面这段指令发送给 OpenCode Agent:
请为当前 OpenCode 项目安装并配置 opencode-peek。
1. 在当前项目目录执行 `opencode plugin opencode-peek`。
2. 读取 `.opencode/opencode.json`,保留所有已有的配置、plugin 和 command。
3. 使用下面的内容新增或更新 `command.peek`:
```json
{
"description": "Generate an HTML view of the current OpenCode session",
"template": "Generate a `peek` HTML transcript for the current session. First call `session_inspect` to generate a fresh snapshot and token report. Then call `peek`. Do not pass `firstNTurns` unless the user explicitly requests the first N turns only. If `session_inspect` fails, briefly state the reason and stop. If `peek` fails, briefly state the reason and stop. On success, reply only with the `markdownLink` returned by `peek`. Do not add explanations or perform other actions."
}
```
4. 验证 `.opencode/opencode.json`。
5. 配置完成后告诉我重启 OpenCode。
不要直接使用 npm 安装,不要创建重复的本地 plugin,不要修改无关文件。这段配置指令有几个关键约束:
- 保留已有的 plugin、command 和其他配置
- 先执行
session_inspect,再执行peek - 用户没有明确指定时,不要传
firstNTurns - 任一步失败都停止,不继续猜测
- 成功后只返回
markdownLink
它本质上是在把两个底层工具编排成一个稳定的 /peek 工作流。
手动配置
当前项目安装插件:
opencode plugin opencode-peek全局安装:
opencode plugin -g opencode-peek项目配置位于 .opencode/opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-peek"],
"command": {
"peek": {
"description": "Generate an HTML view of the current OpenCode session",
"template": "Generate a `peek` HTML transcript for the current session. First call `session_inspect` to generate a fresh snapshot and token report. Then call `peek`. Do not pass `firstNTurns` unless the user explicitly requests the first N turns only. If session_inspect fails, briefly state the reason and stop. If peek fails, briefly state the reason and stop. On success, reply only with the markdownLink returned by peek."
}
}
}修改配置后重启 OpenCode,然后执行:
/peek如果已经安装过旧版本,需要刷新 OpenCode 的插件缓存:
opencode plugin opencode-peek --force重启后再次执行 /peek,生成最新报告。
生成物和隐私边界
opencode-peek 处理的是当前会话,因此生成物可能包含比普通日志更多的信息:
- 完整对话内容
- session snapshot
- 系统提示词
- 模型元数据
- 工具输入与输出
- Token 使用报告
- 生成的 HTML transcript
这些文件默认位于 .workspace/cache/,应该加入 .gitignore:
.workspace/cache/这不是可有可无的清理动作。会话报告可能包含源码、路径、凭证上下文或内部指令,不应该因为方便查看就直接提交到 Git 或上传到公共空间。
brainstorming:把模糊想法变成设计
brainstorming 不是“让 Agent 多想一会儿”,而是一套有顺序约束的需求澄清流程。
它要求在提出最终方案前完成以下步骤:
- 先探索当前项目上下文
- 只有在视觉问题明显更适合图示时,才提供 visual companion
- 一次只问一个澄清问题
- 提出 2 到 3 种带权衡的实现路径,并给出推荐方案
在探索阶段,它要求读取项目 README、文档、现有规格和相关源码;必要时检查最近提交,以理解当前方向和约束。这个阶段应该保持只读,不因为“正在头脑风暴”就直接修改代码。
当需求足够明确后,它会分段呈现设计,每段控制在约 200 到 300 词,并在段落之间确认方向。设计内容必须覆盖:
- 架构
- 组件
- 数据流
- 错误处理
- 测试方式
如果用户需要留下文档记录,Skill 建议将确认后的设计写入 docs/specs/YYYY-MM-DD-.md 或项目合适的文档路径;如果继续实现,则交给正常的编码流程,而不是在 brainstorming 阶段混入实现工作。
它最有价值的地方是把“先问清楚”写成了硬约束,而不是一句建议:一次一个问题、先看上下文、先比较方案、逐段确认。
grilling:在写代码前把方案问穿
grilling 比 brainstorming 更强硬。它不负责发散想法,而是负责对已经存在的计划或设计进行压力测试。
它的规则很简单:
- 逐个决策往下追问
- 继续沿着设计树展开分支
- 解决决策之间的依赖关系
- 每个问题都给出推荐答案
- 一次只问一个问题
- 如果答案可以从代码库中查到,就先查代码,不要把问题抛给用户
这两个 Skill 的关系可以这样理解:
brainstorming:我到底要做什么?有哪些可行方案?
↓
grilling:这个方案的每个前提是否成立?边界和代价是什么?
↓
implementation:按确认后的设计进入实现它们都没有直接写代码的职责。前者负责形成设计,后者负责暴露设计漏洞,最终实现应该由后续开发流程完成。
video-download:不封装复杂逻辑,直接使用 yt-dlp
video-download 是一个很实用的 Skill,核心观点是:下载能力已经由 yt-dlp 解决,不需要再包一层自定义脚本。
它支持 YouTube 和其他大量站点的视频、音频、字幕和元数据下载,而且不需要 API key。
依赖
# macOS
brew install yt-dlp ffmpeg
# 或使用 pip 安装 yt-dlp
pip install yt-dlpffmpeg 主要用于合并视频流和音频流。高清资源经常是分离的 video/audio stream,没有 FFmpeg 就可能无法得到最终的 mp4 文件。
下载最佳质量
yt-dlp "URL" -o "%(title)s.%(ext)s" --merge-output-format mp4限制分辨率
# 不超过 1080p
yt-dlp "URL" \
-f "bestvideo[height<=1080]+bestaudio/best[height<=1080]" \
--merge-output-format mp4
# 不超过 720p
yt-dlp "URL" \
-f "bestvideo[height<=720]+bestaudio/best[height<=720]" \
--merge-output-format mp4音频、字幕与元数据
# 只下载音频
yt-dlp "URL" -x --audio-format mp3 --audio-quality 0
# 下载英文字幕
yt-dlp "URL" --write-subs --sub-langs en --merge-output-format mp4
# 只下载字幕,不下载视频
yt-dlp "URL" --write-subs --sub-langs en --skip-download
# 只获取元数据
yt-dlp "URL" --dump-json --no-download
# 查看可用格式
yt-dlp "URL" -F输出模板中的常用变量包括:%(title)s、%(ext)s、%(id)s、%(uploader)s、%(duration)s 和 %(resolution)s。下载失败时,第一步通常是更新 yt-dlp:
yt-dlp -U这个 Skill 的设计很克制:它不把成熟 CLI 重新实现为 Python 或 Node wrapper,而是补充参数选择、依赖说明和排错路径。
video-understand:用 FFmpeg + Whisper 本地理解视频
下载只是拿到文件,真正要让 Agent 使用视频,还需要把视频转换成模型容易处理的两类信息:关键帧和文本转录。
video-understand 使用 FFmpeg 抽帧,使用 Whisper 转录,默认不依赖外部 API,可以在本地完成处理。
依赖
# FFmpeg 和 ffprobe
brew install ffmpeg
# 可选:需要转录时安装 Whisper
pip install openai-whisper常用命令
# 默认:场景检测 + 转录
python3 skills/video-understand/scripts/understand_video.py video.mp4
# 只提取关键帧
python3 skills/video-understand/scripts/understand_video.py video.mp4 -m keyframe
# 按时间间隔提取帧
python3 skills/video-understand/scripts/understand_video.py video.mp4 -m interval
# 限制最多提取 10 帧
python3 skills/video-understand/scripts/understand_video.py video.mp4 --max-frames 10
# 使用更大的 Whisper 模型
python3 skills/video-understand/scripts/understand_video.py video.mp4 --whisper-model small
# 不做语音转录,只输出画面帧
python3 skills/video-understand/scripts/understand_video.py video.mp4 --no-transcribe
# 静默模式,只输出 JSON
python3 skills/video-understand/scripts/understand_video.py video.mp4 -q
# 将结果写入文件
python3 skills/video-understand/scripts/understand_video.py video.mp4 -o result.json三种抽帧模式
| 模式 | 实现方式 | 适合场景 |
|---|---|---|
scene | 使用 FFmpeg select='gt(scene,0.3)' 检测场景变化 | 大多数内容丰富的视频 |
keyframe | 提取编码器中的 I-frame | 有自然关键帧的视频 |
interval | 按视频时长均匀采样 | 需要可预测采样间隔的场景 |
默认模式是 scene。如果没有检测到场景变化,脚本会自动回退到 interval,并在结果 JSON 的 mode 字段中记录实际使用的模式。
输出 JSON
脚本输出的是结构化 JSON,而不是一段让模型自己猜的描述:
{
"video": "video.mp4",
"duration": 18.076,
"resolution": {
"width": 1224,
"height": 1080
},
"mode": "scene",
"frames": [
{
"path": "/absolute/path/frame_0001.jpg",
"timestamp": 0.0,
"timestamp_formatted": "00:00"
}
],
"frame_count": 12,
"transcript": [
{
"start": 0.0,
"end": 2.5,
"text": "Hello and welcome to this video."
}
],
"text": "Hello and welcome to this video.",
"note": "Use the Read tool to view frame images for visual understanding."
}顶层字段分别表示原始视频、时长、分辨率、实际抽帧模式、帧列表、帧数量、转录片段、完整文本和给 Agent 的使用提示。
抽出的图片会放在视频旁边的 {video_stem}_frames 目录中,JSON 中记录绝对路径。这样 Agent 可以直接读取 frames[].path 对应的 JPEG,再结合 transcript 进行视觉和语音分析。
如果使用 --no-transcribe,transcript 和 text 会是 null;如果本地没有安装 Whisper,也会保留帧信息,但无法生成转录。
.opencode/opencode.json 里的两种扩展
仓库自己的 OpenCode 配置同时展示了 plugin、command 和 MCP 的组合方式:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-peek"],
"command": {
"peek": {
"description": "Generate an HTML view of the current OpenCode session",
"template": "Generate a `peek` HTML transcript for the current session..."
}
},
"mcp": {
"exa": {
"type": "remote",
"url": "https://mcp.exa.ai/mcp",
"enabled": true
}
}
}这里的职责边界是:
plugin加载opencode-peek,提供工具能力。command将工具编排为/peek。mcp接入远程 Exa MCP,提供额外的外部检索能力。.opencode/skills提供需求和视频处理类工作流。
它们不是替代关系,而是不同层级的扩展:Plugin 提供运行时工具,MCP 提供外部能力,Skill 提供工具使用方法,Command 提供固定入口。
本地开发、测试与发布
在仓库根目录执行:
npm install
npm run build
npm test
npm run pack:peek -- --dry-run对应的实际 workspace 脚本如下:
npm run build
→ npm run build --workspace opencode-peek
npm test
→ npm run test --workspace opencode-peek
npm run pack:peek -- --dry-run
→ npm pack --workspace opencode-peek --dry-runopencode-peek 的 package script 还定义了几个细节:
prebuild会先删除dist,避免旧构建产物残留。build先运行 TypeScript 编译,再执行scripts/copy-assets.mjs复制资源。prepack会在打包前自动重新 build。test会先编译测试,再使用 Node 的 test runner 执行dist-tests/tests/*.js,最后删除测试构建目录。pack:check可以执行npm pack --dry-run检查发布内容。
发布前不能只在 workspace 内验证。应该使用 npm pack 检查最终 tarball,再把 tarball 安装到一个干净的 OpenCode 配置中,确认入口、资源和插件注册都没有依赖本地源码目录。
这个仓库最值得借鉴的地方
opencode-kit 的价值不在于文件数量,而在于它把 Agent 工作拆成了几个可复用层次:
OpenCode runtime
├── Plugin:opencode-peek
│ ├── session_inspect:采集会话数据
│ └── peek:渲染 HTML transcript
├── Command:/peek
├── MCP:Exa remote server
└── Skills
├── brainstorming:形成设计
├── grilling:压力测试设计
├── video-download:获取视频素材
└── video-understand:抽帧与转录其中,brainstorming 和 grilling 处理的是“开始写代码之前”的认知工作;video-download 和 video-understand 处理的是“把外部素材变成 Agent 可用输入”;opencode-peek 处理的是“任务执行之后如何复盘和观测”。
这比把所有内容都写成一段巨大的 system prompt 更容易维护:每个 Skill 有自己的触发场景和边界,插件有自己的构建与发布流程,command 只负责组合工具。
写在最后
opencode-kit 目前是一个规模不大的仓库,但它覆盖了 OpenCode 使用中的三个真实问题:
- 需求还没想清楚,先用
brainstorming和grilling收敛设计。 - 手里只有视频素材,用
video-download和video-understand转成文件、帧和文本。 - Agent 执行过程不透明,用
opencode-peek生成会话报告和 HTML transcript。
它没有试图把所有能力塞进一个框架里,而是通过 npm package、项目级 Skill、OpenCode command 和 MCP 配置分别解决问题。
如果要把自己的 OpenCode 使用经验沉淀下来,这个仓库提供了一个很直接的参考:先找到重复发生的工作,再决定它应该成为一个工具、一个 command,还是一套 SKILL.md 工作流。
