Wakapi 是一个自己搭的编码时间统计服务,兼容 WakaTime 客户端:编辑器插件把心跳打过来,它按时长 / 语言 / 项目 / 编辑器汇总成图表。Go 写的单文件程序,默认用 SQLite,不用另装数据库。这篇在 Windows 上从解压到灌心跳、看报表,把每一步的数字记下来。

一个 41 MB 的 exe,7.79 秒起服务

发布包      wakapi_windows_amd64.zip,15,865,539 字节
解压后      wakapi.exe,41,452,544 字节 + config.yml,8,925 字节
版本        2.18.2
启动命令    wakapi.exe -config config.yml
启动耗时    7.79 秒(进程到 3000 端口可连)
监听地址    127.0.0.1:3000(config.yml 里 listen_ipv4)

不用装运行时,解压就能跑。默认配置把监听地址限制在 127.0.0.1,要给局域网用就得改 listen_ipv4。数据库是当前目录下的 wakapi_db.db,首次启动自动建表。

注册走网页,接口没有 signup

POST /api/signup                    404,没有这个接口
GET  /signup                        200,表单四栏
表单字段                            username / email / password / password_repeat
隐藏字段                            captcha_id / invite_code / location

注册只能走网页表单,提交成功直接跳到仪表盘。表单里带一个隐藏的 captcha_id,说明页面上挂了人机校验组件,用脚本硬提交容易被挡。注册后用户主键就是用户名,API Key 存在 users.api_key 这一列,36 位 UUID。

心跳接口只认查询参数里的 key

POST /api/heartbeat?api_key=<key>      201
Authorization: Basic base64(key:)     401
Authorization: Basic base64(user:key) 401
Authorization: Bearer <key>           401

如果用 Basic 或 Bearer 鉴权,请求会失败并返回 401,脚本必须把 key 挂到查询串上才通。这一点和 WakaTime 官方接口不同,写脚本时容易踩。请求体是 JSON,必填 entity(文件名)、type、time(Unix 秒),其余 project、language、editor、operating_system 可选。

灌 120 条心跳,库里有 121 行

项目实测值
发送成功120 条,每条间隔 150 秒
库里总行数121(含探测时插入的 1 条)
按语言分布Go 31 / Python 30 / Typescript 30 / Bash 30
数据库体积229,376 字节

注册后 users 表只多 1 行,has_data 还是 0,说明统计是按需算的,不是写死字段。每条心跳单独存一行,不做预聚合,所以体积随使用时间线性涨。真正的汇总发生在打开报表时按时间范围算,这也是为什么灌完数据立刻刷新页面就能看到结果,不用等定时任务。

报表页六个数:总时长、心跳数,以及三个 Top

Total Time        2 hrs 55 mins(after Thu, 22 Oct 2026 00:01)
Total Heartbeats  72
Top Project       web
Top Language      Typescript
Top Editor        Unknown
AI coding ratio   0%

末尾那个 0% 不是没写代码,而是心跳里没有任何 AI 相关标记,这项按字段统计,传了才算。四个筛选器背后是同一份心跳数据的不同维度,改任何一个,上面六个数字会一起变。

仪表盘按项目画横条,按语言和编辑器各画一个环形图,右上角还能切日期范围。Top Editor 显示 Unknown,是因为心跳里带了编辑器名但统计页取的是另一个字段,不填就归到 unknown。72 与 121 的差是因为报表只算当天范围内的心跳,跨过零点的那部分被切掉了。

筛选器五个维度,全是下拉

Project     lab-tools / ops / seo-audit / web
Language    Bash / Go / Python / Typescript
Machine     unknown
Label       default
Category    coding

五个筛选器都支持输入过滤,多选之后整页图表跟着变。项目名和语言名直接来自心跳里的字段,所以只要客户端传得规范,这里就自动长出来,不用先在后台建字典。想区分机器,得在心跳里额外加 machine 字段,否则统一算 unknown。

实测范围:Windows 10 22H2(10.0.19045.6466) / Wakapi 2.18.2 / SQLite / 2026-10-22。真实编辑器插件上报 / 周报邮件 / 排行榜、导入 WakaTime 历史数据、PostgreSQL 后端都没有验证,不作结论。