agent-acta
Verified@yxzpro/agent-acta · v2.14.6 · MIT · Web UI
本地 AI agent 请求日志面板:聚合 atomcode / codebuddy / workbuddy / claude / codex / codearts / gemini / cursor / kimi / dsh 等本地日志,看每轮耗时、token、缓存、上下文与工具调用
Install
dsh plugin add @yxzpro/agent-acta Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Published to npm without a public repository. Inspect the package contents before installing.
Tags
Creators
Readme
AgentActa
本地 AI agent 请求日志面板:聚合多款 AI agent 写在磁盘上的会话日志,在浏览器里查看每一「轮次/请求」的耗时、token、缓存命中、上下文占用与工具调用明细。
- 本地常驻服务 + SSE 实时推送,无外部依赖、无网络上报、纯只读旁路(不注入、不改各 agent 的配置)
- 一个页面看 24 家 agent:atomcode / codebuddy / workbuddy / claude / codex / cursor / trae / qoder / opencode / gemini / copilot / windsurf / codearts / kimi / dsh / zcode / doubao / hermes / devin / minimax / mimocode / kilo / openclaw / cline
- 另有桌面悬浮卡片(Electron 小窗):今日/累计 token + 最新卡片流
要求:机器上有 node(node -v 可用即可,>=22.5)。Windows 是主要验证平台;mac / Linux / 鸿蒙 PC
的代码路径(候选目录按平台展开、跨平台搬运的自愈、POSIX 权限)已就位并有回归钉着,但未在真机端到端跑过 ——
换平台前先看 REFERENCE.md「跨平台」一节,那里写明了两边不一致的地方与要手工处理的两三件事。
完整口径、原理与排障详解见 REFERENCE.md;各 agent 日志格式的字段口径与解析边界见 LOGFORMATS.md。
安装与快速上手
从 npm 装
npm i -g @yxzpro/agent-acta # 装完多出命令 agentacta 与 agentacta-mcp
agentacta --open # 起服务并打开 http://127.0.0.1:14570
⚠ 包名带作用域 @yxzpro/:裸名 agent-acta 与 npm 上已存在的 agentacta(别人的同类项目)被判定太像而发不出去。命令名不受影响,敲的还是 agentacta。国内镜像同步有先后(实测 npmmirror 还没同步到,腾讯云镜像已可回源),装不上就加 --registry=https://registry.npmjs.org/。
拿到的是压缩包(tgz)
npm i -g agent-acta-<版本>.tgz # 装完多出命令 agentacta
agentacta --install-hooks # 可选:会话启动时自动拉起服务
agentacta --open # 起服务并打开 http://127.0.0.1:14570
拿到的是源码目录
npm i -g <本目录> # 软链安装,改源码即时生效
node <本目录>/agent-acta-server.mjs --ensure # 或者不装 npm,直接一条命令起服务
然后浏览器打开 http://127.0.0.1:14570。支持的服务已自动发现,无需配置。
命令一览
| 命令 | 作用 |
|---|---|
agentacta |
前台常驻(服务本体) |
agentacta --ensure |
确保端口上跑的是本版服务:同版幂等退出,旧版自动重启(hook 调的就是它) |
agentacta --open |
起服务并打开浏览器 |
agentacta --client |
起桌面悬浮卡片(首次执行会装 ~100MB Electron 运行时到 ~/.agent-acta/widget-runtime/) |
agentacta --stop |
停止服务(先优雅关闭并落盘索引,拿不到响应才按 pid 强杀) |
agentacta --status |
查状态:服务在不在跑、端口上那版与本地包是否一致、悬浮卡片开着没(退出码 0 一致 / 1 不一致或问不出 / 2 没在跑) |
agentacta --doctor |
自检并输出一段可粘贴的病历:配置能不能解析、配置指向的目录还在不在、索引片有没有损坏或口径对不上、端口上跑的是不是这一版、页面文件齐不齐、归档现在多大(退出码 0 无失败 / 1 有失败)。只读,不改数据也不改配置 |
agentacta --install-hooks [--dry] [--agent atomcode,claude] |
把「会话启动自动拉起」写进 atomcode / claude 的配置(幂等,改前自动备份) |
agentacta --uninstall-hooks |
移除上面写入的 hook |
agentacta --where |
打印自身安装路径 + 可直接抄的 hook 命令 |
agentacta --archive |
归档一次:把「已结束、且早于今天」的日志条目连详情快照冻进 ~/.agent-acta/archive/(有些 agent 自己删日志,不冻就永久没了)。服务在跑时也会每天自动归档;这条是手动补跑/排查用的 |
agentacta --archive --list |
只看归档清单,不做归档 |
agentacta --archive --dry |
只报要写什么、不落盘(可配 --list) |
agentacta --search-reindex [--dry] |
手动重建全文搜索索引(页面搜索框回车搜的就是它)。日常不用跑:服务启动 60 秒后自己建首轮、之后每 10 分钟一轮增量。服务在跑时拒绝执行(先 --stop),--dry 只统计不落盘 |
agentacta-mcp |
以 MCP server 身份跑(stdio):给 Claude / Cursor / Qoder 这类客户端当只读工具用,见下节 |
agentacta --version / -v |
版本号 + 服务脚本指纹(判断端口上跑的是不是这一版) |
agentacta --help / -h |
用法 |
未知参数会报错并以退出码 2 结束,不会默默起服务。
改完服务端代码后:agentacta --ensure 一步到位(比对代码指纹,不一致就停旧拉新)。改页面只需刷新浏览器。
当 MCP server 用(让 agent 自己查日志)
agentacta-mcp 是随包发的第二个命令,把本机日志以 MCP 工具的形式开放给客户端;它是独立进程、直读日志与索引,不连 14570、不写任何文件,所以常驻服务在不在跑都能用(首次握手后要全量扫一遍本机日志,约 2s,期间不打日志)。
配置片段(把路径换成本机实际装的那份,agentacta --where 可查):
{ "mcpServers": { "agent-acta": { "command": "node", "args": ["<安装目录>/mcp-server.mjs"] } } }
| 工具 | 干什么 |
|---|---|
overview |
有哪些 agent、各多少条、索引新旧 |
search_entries |
按 agent/项目/时间范围列轮次(时间倒序,默认 50 条) |
get_entry |
按条目 id 取全文(提问、输出、工具调用、LLM 明细) |
list_sessions |
按会话聚合:几轮、多少 token、跨多久 |
usage_stats |
by=day 逐日 / by=model 按模型的汇总 |
slowest_turns |
最慢的 N 轮 + p50/p95 |
tool_fails |
哪个工具最常失败 / 超时(三分类排行 + 逐 agent 覆盖度,超时算失败、软失败单列) |
工具口径与页面/HTTP API 同源(同一批聚合函数),不另算一套。完整说明与逐客户端配置在 REFERENCE 的「作为 MCP server 接入」。
当 DSH 插件用(在 DeepSeek Harness 里看同一块面板)
装了 DeepSeek Harness(DSH)的话,可以把它当 Cordis 插件装进去:左侧栏多一个「AgentActa」图标,点开在中间栏占一整块面板 —— 就是同一个 Vue3 页面(iframe 承载,筛选 / 详情 / SSE 实时推送都在),不需要你再开浏览器或常驻服务。
dsh plugin --profile desktop add "@yxzpro/agent-acta" # npm 包名
dsh plugin --profile desktop add "git+https://atomgit.com/elegant001/agent-acta.git#v2.14.4" # 或直接从仓库
包名带
@yxzpro/是因为 npm 的相似性规则:裸名agent-acta与已存在的agentacta(别人的同类项目,2026-02 就发了)判为太像而被拒。 产品名没改 —— 命令仍是agentacta,仓库、面板标题、URL 全不变;只有 npm 标识与 DSH 的 bundle 名跟着包名走。
dsh plugin的参数逐字转发给 pnpm,认 registry / git / tarball / path 四态;只想要文件就把上面换成"file:C:/绝对路径/yxzpro-agent-acta-2.14.4.tgz"(作用域包打出来的 tgz 文件名会去掉@、把/变成-)。⚠github:那种缩写认的是 GitHub,本仓库在 AtomGit 要写全git+https;URL 里的#与带@的包名在 Git Bash / PowerShell 里整条加引号。把v2.14.4换成你要的版本即可(git ls-remote --tags https://atomgit.com/elegant001/agent-acta.git能看全)。- 本项目以 MIT 许可发布(见
LICENSE),代码里没有网络出口、也不上传任何日志内容 —— 它只读你自己机器上那些 agent 已经落盘的文件。 - 装完要彻底退出 DSH 再启动(进程全没才算,只关窗口无效 —— 宿主有模块缓存)。
- 图标没出现,先按这两条查:① 宿主按 semver 判插件兼容(不匹配只进
skippedBundles、不报错,表现就是不出现);②--profile有没有指对你实际在用的那个 profile。已在 DSH 0.1.7-rc.2 / runtime 0.2.0-rc.1 上验通。
和命令行服务怎么共处(这条最常问):插件每次请求现判 127.0.0.1:14570 在不在(环回探测约 1ms,结果缓存 2 秒),所以不用你选:
| 14570 | 面板给你什么 |
|---|---|
| 在跑 | 就是它的面板,原样递进 iframe(数据、SSE、写操作全通)—— 本机仍然只有它那一个扫描器,插件不另起一套 |
| 没在跑 | 插件自己在宿主进程里起一套(不监听端口、不写 pid、不空闲自停),面板照常用 |
CLI 中途退出时面板会换成一小页「命令行服务已退出」,带一个让插件接手按钮 —— 点了才起,不自动起:自动起可能和你又把 CLI 拉回来撞成两个写者,这种决定留给人做。
不需要为了看面板去 agentacta --stop 或重启整个 DSH(早先那版要你这么做,体验很差,已改掉)。
边界(有意为之,不是漏做):插件不唤起悬浮卡片,/(宿主的认证兜底位)、/api/shutdown、/api/client、/api/trae/capture-key、/widget 这五条路由在宿主里根本不注册(防一次误触把宿主进程带走);面板保持自家深色皮、不跟宿主明暗切换;数据面照旧只读本机、零网络出口。细节在 REFERENCE 的「作为 DSH 插件接入」。
页面用法速查
- 筛选:Agent / 项目 / 时间范围(今天 / 近 7 天 / 近 30 天,按本地自然日)/ 状态 / 关键词
- 全文搜索:搜索框里敲字 = 只筛当前窗口(即时、免费);按回车 = 全库检索 —— 搜的是每条轮次的正文
(用户输入 + AI 回复 + 工具入参/返回),跨 agent、跨未加载的历史,默认不套时间范围(「上周那次报错」本来就在默认两天之外)。
结果直接接手卡片列表,命中片段会高亮;顶部横幅如实报「已索引 A/B 条」「不套用时间范围」,以及这一轮是否被
单轮 200 条上限截断(「本次只取回 200 条」),想按当前日期收窄就勾「限定当前时间范围」。
索引由服务在后台增量维护(
~/.agent-acta/search/),首次启动约一分钟后可搜 - 卡片:点任意卡片展开用户输入、AI 输出、执行链路、LLM 调用明细与工具调用
- 右上角状态徽标 = SSE 连接状态,点它可调刷新频率;旁边下拉可开「空闲自停」(30 分钟 / 2 小时 / 6 小时,默认关)
- 按会话浏览(侧栏第 2 项):以 session 为单位看完整多轮演进;dsh / zcode / trae 的会话带真实时间轴。
会话名取产品自己起的标题(I14:claude 系读转录里的
ai-title、没有则退回last-prompt;dsh / gemini / buddy / zcode / traedb / opencode / kilo / hermes / devin 各有各的源头),都没有才退回显示会话 key —— 不拿文件名冒充标题 - 子 agent 拓扑(I16):会话列表里子 agent 会话缩进带
└,父会话那行显示「合计 N 轮 · x tok」(含自身); 右栏顶部可点着跳父 / 跳子。判据是源头的显式谱系外键(dsh 的parentSession、claude 的subagents/目录 +.meta.json、zcode/opencode 的session.parent_id、hermes 的parent_session_id),不按时间区间猜 - 时间未知如实标注(I16):拿不到轮时间戳的轮(atomcode 的
.jsonl0 字节 /turn_id缺失,本机 44.6%) 不再拿会话updated_at冒充 —— 卡片标「时间未知」,且不进按天统计(统计弹层写明少算了几轮) - 用量统计(工具栏折线图标):按天聚合 token 与耗时 + 按模型聚合,跟随当前筛选; 「时延分析」里有四个排行子 tab —— 最慢轮 / 工具调用 / 缓存命中率 / 工具失败画像(I6:哪个工具最常失败, 含覆盖度表:哪几家源头根本没有逐工具失败信号,那里空着不是"从不出错")
- 导出(工具栏下载图标 → JSON / CSV / Excel):导的就是列表此刻这份筛选集,并且把筛选条件一起写进文件
(CSV 头两行、Excel 说明行、JSON 的
meta.filters)—— 事后能自证「这批数是按什么筛出来的」。展开某一轮后 详情底部还有导出该轮完整详情(走/api/entry?full=1,工具入参/返回不截断)。纯浏览器下载,服务端不写盘; 口径、列清单与「为什么 Excel 是 SpreadsheetML」见 REFERENCE.md「导出(R11)」一节 - 两轮对比(卡片顶行「对比」按钮,点两条自动弹开):并排比耗时 / 模型 / LLM 调用 / 工具 / 积分或 Token /
上下文占用 / 压缩,每条指标标出「谁大」与差多少;下半区是两条的用户输入、AI 输出与工具调用逐条对照(点开才取)。
qoder 那侧只给积分与占比(它不落盘 token,印 0 会被读成"没花钱"),混比时不适用的一格给
—且不作差 - 单轮复现包(卡片详情底栏「导出复现包」):一键 zip = 该轮原始日志片段(按解析器同一套开轮判定切, 行号与磁盘一致)+ 完整解析结果 + 四枚版本指纹 + 导出那一刻的筛选条件,贴群 / 提 bug 直接带上文。 zip 在浏览器里手写打包(store 模式、零依赖),服务端不写盘、不新增网络出口;数据库 / 多帧压缩那几家 切不出原始片段,会退回「原始路径 + 完整解析结果」并说明原因
- 历史归档(侧栏第 4 项):浏览
~/.agent-acta/archive/里被冻结的历史条目 —— 产品自己删日志(如 CodeArts 只留约 30 天)后,这里还打得开当时的用户输入 / AI 输出 / 工具与调用明细。只读旁路,不跟随左侧筛选;左下还有一排归档开关(每个 agent 一个,不想留的关掉即可) - 磁盘占用(侧栏第 6 项):按 agent 列「日志目录 / 归档 / 索引片」各占多少、谁最大,清理前先看清构成(
~/.agent-acta顶层逐项列出,含 widget 那份 Electron 运行时)。只统计、不删除;遍历带预算,走不完会明标「统计到一半」而不是给个看似完整的假数 - 解析器自检(侧栏同名一项):改完解析口径,上一次回归跑成什么样 ——
test/下每个脚本各自的结果(绿 / 红 / 超时)、耗时、以及这次没跑的以及为什么不跑,一页看全。数据来自~/.agent-acta/selftest.json(由node test/selftest.mjs写),这一页只读、不在浏览器里跑测试;结果出自另一版代码时顶部会黄条警告「这份绿不代表当前这版」 - 侧栏每个 agent 旁的开关 = 临时禁用(不删配置);
✕= 移除该 agent 配置(不动本地日志文件);+= 手动添加 - cursor 行那个图标按钮 = 注入 / 卸载 token 采集钩子:cursor 的转录文件里没有 token,本地唯一的逐轮用量
来自它自己的
stop钩子。点一下(二次确认)就往~/.cursor/hooks.json加一条命令,之后每轮的 input/output/缓存用量会被采到~/.agent-acta/cursor-usage.jsonl并贴回卡片上;再点一下卸载。 只加自己那一条、不动你已有的钩子;hooks.json不是合法 JSON 时会拒绝改动而不是覆盖。口径见 LOGFORMATS.md 的 cursor 一节,接口见 REFERENCE.md 的POST /api/cursor-hook - 桌面挂件(不用 Electron 的轻量玩法):
msedge --app=http://127.0.0.1:14570/widget,再用 PowerToys 置顶
数据与配置
- 配置:
~/.agent-acta/config.json(老位置~/.agent-log/、~/.atomcode/agent-log/启动时自动搬迁) - 索引:
~/.agent-acta/index/<kind>.json(增量偏移持久化,重启不全量重扫) - 归档:
~/.agent-acta/archive/<agent>/<YYYY-MM-DD>.jsonl+manifest.json(条目级冻结,默认永久保留)- 每个 agent 可单独开关:在「历史归档」弹层左下直接点(写
config.json的archive.skip,即改即生效,不用重启); 手改配置也行:"archive": { "skip": ["cursor"] }。只停未来的归档,已冻好的文件保留 - 同段还能配
enabled(关自动轮)、maxDays/maxMB(限量,只删整天文件)。详见 REFERENCE「历史归档」
- 每个 agent 可单独开关:在「历史归档」弹层左下直接点(写
- 全文索引:
~/.agent-acta/search/<kind>.json(每条轮次的正文,一个源一条记录)。由服务自己在后台增量维护 (启动 60 秒后首轮、之后每 10 分钟一轮),不需要手工干预;手动重建用agentacta --search-reindex(服务在跑时先--stop)。 本机量级参考(2026-09-22 晚,常驻服务实测/api/search/status):648 个源 / 5111 条可查(该机共 5431 条, 余下的要么源文件已被产品删掉、要么这一轮本来就没有正文)→ 索引约 24MB。 想关掉「每条正文最多索引 8000 字」的上限,用环境变量AGENT_LOG_SEARCH_MAX_CHARS- 记录按绝对路径认源,所以把
~/.agent-acta搬去另一台机器/另一个平台后,载入时会把对不上本机的 记录剪掉并重扫(日志与/api/search/status.pruned都会报数)。POSIX 上search/index/archive/三处都按私有新建(0700/0600,里面是明文对话);老文件不动,要一次收干净就chmod -R go-rwx ~/.agent-acta
- 记录按绝对路径认源,所以把
- 端口:默认
14570,环境变量AGENT_LOG_PORT可覆盖 - pid 文件:
~/.agent-acta/server-<端口>.pid
服务端 HTTP API
| 端点 | 作用 |
|---|---|
GET / |
页面 |
GET /widget |
桌面小卡片页(SSE 实时刷新) |
GET /api/ping |
存活探测 |
GET /api/version |
{version, build, pid},build = 服务脚本内容指纹 |
GET /api/agents · POST /api/agents · DELETE /api/agents?name= · POST /api/agents/toggle |
agent 配置的增删改查 |
GET /api/diagnose |
环境诊断:每个候选 agent 每条候选路径的探测结果与未识别原因 |
GET /api/usage?force=1 |
磁盘占用:按 agent 的日志/归档大小 + 索引片 + ~/.agent-acta 顶层构成(结果缓存 60s,force=1 绕开) |
GET /api/selftest |
上一次回归自检的结果(原样递出 ~/.agent-acta/selftest.json + ageMs / sameBuild / sameParserRev 三个诚实标注)。不跑测试,没跑过时 ok:false 并附 hint |
GET /api/snapshot?limit&agent=&project=&range=&scan=1 |
条目快照(列表主数据) |
GET /api/daily |
按自然日聚合 token/耗时(不吃 limit,算整个筛选集) |
GET /api/models |
按模型聚合(参数同上) |
GET /api/analyze?range=&agent=&project=&from=&to=&top= |
排行分析:slowest / p50 / p95 / byTools(本轮工具次数)/ byCacheRate + toolFails(I6 工具失败画像:rows 按 agent×工具名出 fail/total/rate,agents 出覆盖度与「未索引」数)。top 上限 50,默认 10 |
GET /api/entry?id=&full=1 |
单轮详情(dsh/zcode/traedb 额外返回逐事件 events[]) |
GET /api/search?q=&re=1&agent=&project=&status=&from=&to=&limit=&offset= |
全文搜索(页面搜索框回车走的就是它)。from/to 只在页面勾了「限定当前时间范围」时才传,不传 = 不限时间;每条的 _snip 是命中片段(三段纯文本,页面自己转义再高亮)。空的 q 与非法正则都回 400 + 原话 |
GET /api/search/status |
全文索引的覆盖度:{entries, files, total, building, unreadable, noState, bytes, at, maxChars} —— 页面横幅「已索引 A/B 条」用的就是前四个 |
GET /api/sessions · GET /api/session?key= |
会话列表与会话详情(「按会话浏览」) |
GET /api/events |
SSE:hello / update / remove / agents / settings / resync / scanning |
GET /api/settings · POST /api/settings |
扫描节奏 / 空闲自停 |
GET /api/ctxwindows · POST /api/ctxwindows |
上下文窗口表(claude/kimi 进度条分母) |
GET /api/archive/index |
归档清单:{root, days[], agents[], totals, skip[], configAgents[]}(skip / configAgents 供「归档开关」列表用) |
POST /api/archive/skip |
逐个 agent 开关归档:{agent, skip} → 改 config.archive.skip,即改即生效 |
GET /api/archive/entries?agent&day&q&limit&offset |
归档条目列表(不含详情,只给 hasDetail 标记) |
GET /api/archive/entry?agent&day&id |
单条冻结的详情快照(没了返回 404) |
POST /api/shutdown |
优雅关闭(落盘索引后退出) |
各端点的字段细节与口径见 REFERENCE.md「服务端 HTTP API」。
打包分发(开发者)
mkdir -p ../dist
npm pack --pack-destination ../dist # → dist/agent-acta-<版本>.tgz(发版前先 bump package.json 的 version)
node test/pack-smoke.mjs # 冒烟:解包→隔离环境跑起来→逐个接口探一遍
回归/验收脚本在 test/(带 fixture,可重复运行)。一次跑完并在页面上看结果:
node test/selftest.mjs # 默认清单(不依赖仓库外东西的那些),串行约 2 分钟
node test/selftest.mjs --only parser # 只跑名字对得上的(前缀或标题里含这个词)
node test/selftest.mjs --group parser # 只跑一组:static / parser / cli / release / real / parity / slow
node test/selftest.mjs --all # 连默认不跑的组一起跑(要看本机脸色)
结果写进 ~/.agent-acta/selftest.json,页面侧栏「解析器自检」读的就是它(细节见 REFERENCE「解析器自检」)。
发出去的那份 tgz 同时是 DSH 插件包:files 里带 plugin/,装载契约全在 package.json 上 —— exports["."] 给宿主动态 import 服务端壳、dsh.bundle.patch 指到 plugin/cordis.patch.yml、dsh.client.inject 列那两个宿主 UI 包(漏了就装得上但图标不出现)。所以 bump 版本后要一起看一眼:plugin/client.js 不能有顶层 import/export(宿主把它原样拼进普通 <script>,带 ESM 会把整个 DSH 启动带崩)。
常见问题速查
- 不知道从哪查起:
agentacta --doctor—— 一次列出配置 / 目录 / 索引 / 端口版本 / 页面文件 / 归档的现状,把整段贴出来即可(只读,不改任何东西) - 页面打不开 / 一直「重连中…」:
curl http://127.0.0.1:14570/api/ping;无响应跑agentacta --ensure - 升级/改码后新接口 404:端口上是旧版服务,
agentacta --ensure重启(判据:GET /api/version的build指纹;--doctor会直接把这条报成[fail]) - 某个 agent 一直是 0 条:看侧栏「环境诊断」或
GET /api/diagnose - 换到 mac / Linux(或换了台机器):把
~/.agent-acta搬过去即可 —— 索引会按本机磁盘自动校验重建, 对不上的旧记录自己剪掉;config.json里手工加的 agent 根会一直留着且 0 条,--doctor会点名并提示 「这是 Windows 的路径形态」,删掉那几条让自动发现重新认。trae 的密钥抓取只有 Windows,换平台后 token 与 AI 正文拿不到。详见 REFERENCE.md「跨平台」 - trae 看不到 token / AI 正文:SQLCipher 库需要一把机器各自的密钥,用
tools/grab-trae-key.ps1抓取后填traeKey——步骤见 REFERENCE.md「Trae 的 SQLCipher 库」 - 更多排障(codex 用户输入为空、atomcode datalog、hook 验证卡管道、改源码不生效等)见 REFERENCE.md「常见问题」