Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

opencode-diff-detail

opencode 插件:每个 turn 结束时,把本轮修改的文件 diff 逐个上报到统计服务器,用于统计 AI 编写的代码量。

工作原理

插件只监听一个事件:session.idle(一个 turn 结束的信号)。收到后:

  1. 查该 session 最后一条 user 消息 ID(client.session.messages
  2. 调 opencode 官方接口 client.session.diff({ sessionID, messageID }) 拿本 turn 的文件级 diff
  3. 把每个文件转成标准 git 格式 unified diff,逐个 POST 上报

session.diff 内部走的正是 opencode 的 snapshot 机制(每个 step-finish 后重算并持久化到消息的 summary.diffs),实测在 session.idle 触发前就已经算好,idle 时查一定拿得到。用官方接口的好处是 不依赖影子仓的物理路径,抗 opencode 版本变化。

这样天然满足:turn 内同一文件的多次修改只在结束后统一上报一次;并发 turn 按 sessionID 隔离不会串。

兼容性:session.diff 的返回结构在不同 opencode 版本间变过 ({file, patch, status}{file, before, after} 两套),插件对两种都做了适配, 有 patch 直接用,只有 before/after 就本地生成 diff。

上报规则

情况 处理
新增、修改文件 上报
删除文件 不上报
纯重命名(内容零变更) 不上报,没写代码(靠内容指纹配对「删旧+加新」识别)
二进制文件 不上报
前台 subagent 不单独上报,其改动已包含在父 turn 的 diff 内
后台 subagent(task(background:true) 单独上报,因为它可能在父 turn 结束后才写完

上报失败重试 3 次(200ms / 500ms / 1000ms 退避),仍失败则打日志丢弃。 所有上报走后台串行队列,不阻塞 opencode 主流程。

已知限制

  • opencode 的 diff 是整个 worktree 的快照对比,是 turn 执行期间的改动,并不确定是谁写的(agent/人工)
  • .gitignore 忽略的文件不进快照,不会上报。
  • opencode 配置里 snapshot: falsesession.diff 返回空,插件打印警告后躺平。
  • 改名+改内容因缺少 rename 关联,会被当作全新文件上报(整文件算新增行)。纯改名能正确跳过。
  • 后台 subagent 在父 turn 结束前写的文件会被父子各上报一次,依赖服务端去重。

配置

三层取值,优先级:环境变量 > 插件 options > 内置默认值

配置项 环境变量 默认值
url OPENCODE_DIFF_DETAIL_URL http://127.0.0.1:9070/test
token OPENCODE_DIFF_DETAIL_TOKEN xxxxxx
userId OPENCODE_DIFF_DETAIL_USER_ID 1234566
userName OPENCODE_DIFF_DETAIL_USER_NAME 张三
logSource OPENCODE_DIFF_DETAIL_LOG_SOURCE 9
retries OPENCODE_DIFF_DETAIL_RETRIES 3
timeoutMs OPENCODE_DIFF_DETAIL_TIMEOUT_MS 5000
enabled OPENCODE_DIFF_DETAIL_ENABLED true

opencode.json 里注册插件并传 options:

{
  "plugin": [
    [
      "/Users/j/project/opencode-diff-detail/src/server.ts",
      { "url": "http://127.0.0.1:9070/test" }
    ]
  ]
}

开发

bun install
bun run typecheck     # tsc 类型检查(noEmit,不产出 dist)
bun run test-server   # 本地上报接收端,监听 9070,请求体落盘到 ./received

test-server 支持 PORTOUT_DIR 环境变量。

关于依赖与构建

  • 不构建 dist:opencode 用 Bun 直接加载 src/server.ts 源码运行,import type 在 转译时被剥掉,所以插件运行时不需要 @opencode-ai/*,也不产出编译结果。
  • 源码依赖 opencode@opencode-ai/plugin / @opencode-ai/sdk 不装进 node_modules, 而是通过 tsconfig.jsonpaths 指向相邻的 opencode 仓源码 (默认 ../opencode/packages/...)。git pull opencode 后类型自动跟着更新, 避免 node_modules 里的版本与实际运行的 opencode 漂移。
    • 因此类型检查依赖相邻存在 ../opencode 源码仓;路径不同请改 paths
    • 因为会一并检查 opencode 源码,本项目 tsconfig 与 opencode 对齐关闭了 exactOptionalPropertyTypes / noUncheckedIndexedAccess 两个额外严格项。
  • 运行时唯一的第三方依赖是 diff(由 before/after 结构生成 patch 时用)。

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages