@apdesign/cursor-roi-tracker
v0.9.9
Published
Collect commit-level AI coding metrics from staged diff and local AI events
Keywords
Readme
cursor-roi-tracker
cursor-roi-tracker 是一个面向 Git 提交的 AI 代码归因工具。
它会在 pre-commit 阶段统计本次暂存区代码变更与 AI 事件的交集,在 post-commit 阶段补齐提交信息、写入本地历史,在 pre-push 阶段进行非阻塞上报。
功能概览
- 自动安装 Git hooks(
pre-commit/post-commit/pre-push) - 基于暂存区 diff 做行级 AI 归因(新增/删除)
- 提交后生成结构化报告(JSON/JSONL)
- 支持“消费索引 + TTL 宽限 + 过期物理压缩”,减少事件文件膨胀
- 可选静默换 token + 自动上报提交报告
- 默认不阻塞开发流程(异常会记录到错误日志)
安装
当前包名为 @apdesign/cursor-roi-tracker,在仓库根目录执行:
npm i -D @apdesign/cursor-roi-tracker
# or
bun add -d @apdesign/cursor-roi-tracker如果你的私有源做了别名映射(例如映射到
cursor-roi-tracker),也可以按你们内部包名安装。
安装时会自动执行 postinstall,尝试完成以下动作:
- 写入/更新
.git/hooks/pre-commit - 写入/更新
.git/hooks/post-commit - 写入/更新
.git/hooks/pre-push - 初始化默认配置文件
.cursor-roi-tracker.json(若不存在) - 将事件文件加入
.git/info/exclude - 若配置了服务端地址,尝试静默换取本地 token
使用方法(推荐流程)
第 1 步:安装 hooks(仅首次或需要重装时)
npx cursor-roi-install-hooks
# or
bunx cursor-roi-install-hooks若安装依赖后自动注入成功,这一步可跳过。
第 2 步:正常开发并提交
git add .
git commit -m "feat: your message"提交时会自动触发:
pre-commit:采集当前暂存区指标,生成待提交报告post-commit:绑定 commit sha/time,写入最终报告和历史pre-push:上报本次将推送的 commits(失败不阻塞 push,支持队列补传)
第 3 步:查看本地产物
默认写入在仓库的 .cursor/ 下(若不可写则回退到 .cursor-roi/):
.cursor/ai-commit-report.pending.json.cursor/ai-commit-report.final.json.cursor/ai-commit-history.jsonl.cursor/ai-commit-errors.jsonl
手动命令
你也可以单独执行:
# 手动执行 pre-commit 采集
npx cursor-roi-pre-commit
# or
bunx cursor-roi-pre-commit
# 手动执行 post-commit 绑定/压缩/上报
npx cursor-roi-post-commit
# or
bunx cursor-roi-post-commit
# 手动执行 pre-push 上报
npx cursor-roi-pre-push
# or
bunx cursor-roi-pre-push
# 重新安装 hooks
npx cursor-roi-install-hooks
# or
bunx cursor-roi-install-hooks定时任务扫描(GitLab CI)
仓库内提供了离线归因扫描脚本:
npm run ci:ai-attribution
# or
bun run ci:ai-attribution脚本位置与详细说明:
ci/ai-attribution-scan.mjsci/README.md
该脚本用于每日定时任务:拉取服务端 AI 事件、执行 git blame -w --line-porcelain、产出统一 Payload(total* + 可选 modules[])并回传服务端。
配置说明
配置文件名:.cursor-roi-tracker.json(仓库根目录)
示例:
{
"highThreshold": 0.75,
"bulkInsertThreshold": 1,
"pureDeleteThreshold": 1,
"sourceExtensions": [".ts", ".tsx", ".js", ".jsx", ".vue", ".go", ".java", ".php"],
"excludeRegexes": ["(^|/)dist/", "(^|/)build/", "\\.min\\."],
"eventsDirectory": [".cursor/animus-ai-events.jsonl", ".cursor/animus/animus-ai-events.jsonl", ".cursor/local-ai-events"],
"membersFile": ".cursor/enginuity_yunxiao_members.names.json",
"serverBaseUrl": "https://your-server.example.com",
"silentTokenPath": "/api/cursor-board/auth/silent-token",
"commitReportPath": "/api/cursor-board/commit-reports",
"commitReportBatchPath": "/api/cursor-board/commit-reports/batch",
"requestTimeoutMs": 5000,
"batchUploadChunkSize": 30,
"batchUploadBaseTimeoutMs": 3000,
"batchUploadPerItemTimeoutMs": 100,
"batchUploadMaxTimeoutMs": 15000,
"uploadMaxRetryCount": 5,
"uploadDlqMaxRecords": 500,
"eventGraceTtlMs": 604800000,
"enableConsumedFallback": true,
"consumeIndexPath": ".cursor/animus-ai-consumed-events.jsonl"
}建议在
excludeRegexes中排除 lock 文件(包括bun.lock/bun.lockb),避免其参与源码归因统计。
关键字段说明
highThreshold:判定 AI 归因命中阈值bulkInsertThreshold:扩展记录agent_bulk_insert的最小插入行数(默认 1)pureDeleteThreshold:扩展记录agent_pure_delete的最小删除行数(默认 1)sourceExtensions:参与统计的代码文件后缀excludeRegexes:排除路径/文件规则(正则字符串)eventsDirectory:AI 事件文件路径(支持多个)eventGraceTtlMs:事件消费后的宽限期(默认 7 天)enableConsumedFallback:是否允许在宽限期内回滚重提时复用已消费事件consumeIndexPath:消费索引文件路径(JSONL)serverBaseUrl:配置后启用提交后上报commitReportBatchPath:pre-push 多 commit 优先调用的批量上报接口requestTimeoutMs:服务端请求超时(毫秒)batchUploadChunkSize:pre-push 批量上报分片大小batchUploadBaseTimeoutMs:批量上报基础超时batchUploadPerItemTimeoutMs:批量每条附加超时batchUploadMaxTimeoutMs:批量上报最大超时uploadMaxRetryCount:单 commit 最大重试次数,超出进入 DLQuploadDlqMaxRecords:DLQ 最大保留条数(滚动保留最新)
事件生命周期:
- 未消费:作为 fresh 事件参与匹配
- 已消费且 TTL 内:进入 fallback 池,允许回滚重提兜底
- 超过 TTL:从消费索引移除,并对源事件文件做物理压缩
与服务端联动(可选)
当 serverBaseUrl 已配置时:
- 安装 hooks 时会尝试调用
silentTokenPath换取 token - token 会写入 Git 目录下的本地文件(并自动加入 exclude)
pre-push会把即将推送的报告 POST 到commitReportBatchPath(多 commit)或commitReportPath(单 commit)- 对部分失败的 commit 按
commitSha精确判定,失败项进入本地 pending 队列,下次 push(即便无新 commit)继续补传
如果未配置 serverBaseUrl,工具仍可完整执行本地统计,只是不进行网络上报。
常见问题
1) 为什么没有看到 AI 指标(全是 0)?
优先检查:
eventsDirectory指向的事件文件是否存在- 事件文件中是否有有效
eventId - 本次提交文件是否命中
sourceExtensions且未被excludeRegexes排除 - 查看
.cursor/animus/ai-commit-report.final.json中eventReadStats:eventFilesConfiguredResolved:命中的配置路径文件eventFilesAutoDiscovered:自动发现的事件文件filesRead/eventsRawCount:是否真正读取到事件内容
说明:
- pre-commit 会先按
eventsDirectory读取事件,并自动在.cursor/目录下补充发现常见ai-event文件,减少环境路径差异导致的误判。 - 扩展会记录整文件替换类型的编辑(不少 AI 应用修改属于此类),避免“事件未落盘导致 AI 指标恒为 0”。
2) 为什么 commit 后服务端没有立刻看到数据?
上报触发点已改为 pre-push,需要执行 git push 后才会上报。
如果网络失败或超时,hook 会非阻塞放行;失败项会进入本地 pending 队列并在后续 push 自动补传。
3) 为什么没有生成报告文件?
优先检查:
- 是否在 Git 仓库内执行
- hooks 是否成功写入
.git/hooks/ - 是否真的有暂存区源代码文件参与提交
4) 会不会阻塞提交或推送?
默认不会。命令失败会尽量记录到 .cursor/ai-commit-errors.jsonl,并避免中断主流程。pre-push 上报阶段也会在超时或异常时直接放行。
许可证
MIT
