Skip to content

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 插件接入」。

页面用法速查

打开 http://127.0.0.1:14570:

  • 筛选: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 的 .jsonl 0 字节 / 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-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「常见问题」