开源工具(MIT)扫描 Claude Code/Codex CLI/Hermes 已有的会话 JSONL,渲染成交互式执行图,支持用自然语言查询「上次运行哪些编辑失败了」。通过 MCP 接入终端实时对话。
Coding agent 把我的瓶颈挪了个位置。写代码变快了,但理解 agent 实际上做了什么,反而成了慢的那一环。
证据就在眼前。Claude Code、Codex CLI 和 Hermes Agent 都会在磁盘上保留完整的会话记录(分别是 ~/.claude/projects、~/.codex/sessions 和 ~/.hermes):每一次工具调用、每一个错误、每一次重试、每一个子 agent 和委托。但几乎没人去读它们,因为一个单独的会话就能跑出几千行 JSONL。
所以我做了 rungraph。免费、MIT 协议、没有付费版。
npx rungraph
它扫描磁盘上已有的转录文本,然后打开任意会话的交互式图谱:各个 turn 按时间顺序沿主干排列,工具调用被归为一组,子 agent 有自己的泳道。不需要任何 hook、不需要包装器、不需要任何设置,所以昨天那个跑歪了的运行记录已经躺在那里了。实时会话在 agent 工作的同时,图谱也会同步更新。
这部分只是标配。下面这两点才是我每天还在用的原因。
npx rungraph mcp --install
这会把 rungraph 通过 MCP 接入你的 agent。现在你不用再滚动翻阅转录文本,而是在你已经工作的终端里直接提问:
"我上次运行里哪些编辑失败了?"
"它真的跑了测试,还是只是嘴上说跑了?"
"认证重构第一次碰到 token.js 是在哪里?"
这里有件事是我没想到它会这么重要的。图谱在终端里回答你的问题,然后答案背后的那些节点会在打开的图谱上亮起来。它会把画布平移过去。如果你的仪表板正在显示另一个运行记录,它会跟着答案走,而且是一键撤销。如果什么都没打开,它会在正确的运行记录上开一个标签页。
这是同一件事的两个端点,不是什么两个功能。终端是你提问的地方,在你自己的会话里、用你自己的模型,你可以精确检查究竟说了什么。画布是你看到的地方。你在一个地方得到一个结论,在另一个地方得到支撑这个结论的证据,这样你是在审视一次运行,而不是在信任一个总结。
每一个高亮也会生成一个可粘贴的链接。链接用来源来命名焦点,而不是用一个固定的节点 ID 列表,所以一个链接和一次新的查询永远不可能互相矛盾:明天打开它,在运行记录已经增长之后,查询会重新执行。
这就是标准的 MCP over stdio,所以任何支持 MCP 的 agent 都可以接入。比如 Hermes:
hermes mcp add rungraph --command npx --args -y rungraph mcp
工具名称在所有地方都一样(list_runs、find_nodes、get_graph、get_detail、focus_nodes、get_current_view、open_visualization),循环逻辑也一样。
Agent 工作正在变得协作化,而"你的 agent 做了什么"这个问题目前的答案是把一堆终端输出粘贴到 Slack 里。
在仪表板里选中运行记录然后点导出,或者就在终端里操作:
rungraph export --last 2
两种方式都会得到一个单独的 .rungraph 文件。你的同事在他们自己的仪表板里打开它:
rungraph open <file>
有三件事让这比直接丢转录文本更有用。
这个包携带的是中间表示,而不是原始转录文本。所以查看器不需要任何适配器,而且厂商中立性在交接时得以保留:一个 Hermes 的运行记录在只用过 Claude Code 的人那里也能完美打开。没人需要安装你的 agent 就能审查你的运行。
他们的 agent 可以查询你的运行。rungraph mcp 会聚合所有实时服务器,所以同事打开的包会和他们的仪表板并排存在,他们的 agent 用同样的工具和同样的高亮来回答关于你的会话的问题。这就是那个循环的协作版本:你发一个文件,他们问自己的 agent 在里面哪里出了问题,然后节点在他们的屏幕上亮起来。这是针对 agent 运行记录的代码审查,而不是针对这次运行恰好产生的 diff 的审查。
信号是在查看时导出的,而不是预先烘进去的。一个几个月前导出的包,打开时会获得今天的校准过的标记。
在构建 Codex 适配器的时候,我发现 Codex 会逐字记录文件读取。当它读取我的 .env 时,一个 npm token 和两个 API 密钥正以明文形式躺在我的会话文件里。在你备份或分享它们之前,先检查一下你自己的。
所以每次导出都会给你展示一份即将离开你机器的内容清单,并且当秘密扫描发现高置信度匹配时会直接阻止。你然后选择你的保真度:把每个发现 redact 成占位符然后保留其余内容,把所有内容剥离到只剩下形状、工具名、文件和时序,或者当这个发现是误报时override阻止。
对话框和 flags 走的是同一段代码路径、有同样的默认值,这是刻意为之的。两个不同的 consent 界面教两种不同的隐私姿态,这比单独任何一个都要糟糕。分享一个运行记录不应该是你泄露密钥的方式。
图谱会标记一个一直在某处失败的工具、一个运行从未回来修复的错误、以及一个比周围所有步骤消耗多得多的 token 的步骤。故意保守,因为一次误报的成本比漏掉一个真正的要高。一旦你不再信任这些标记,你就又回到了要读完整段运行记录的状态。
点击任意节点可以看到它背后的实际输入、输出、错误和时序。
服务器只绑定 127.0.0.1 且不发出任何出站请求。你的转录文本永远不会离开你的机器,在你主动运行 export 之前不会有任何东西被分享。
这些格式比你猜的变动更频繁。退出码在 Codex exec 的历代版本中以三种形态存在过,fork 出的线程嵌入了一份父级历史的重新时间戳的副本,需要从结构上而非时间戳来剪切,而 Hermes 把它的委托树存在 SQLite 里(需要 Node 22.13+ 才能用内置 reader;旧版 Node 会跳过 Hermes 运行记录并给出警告,其他一切仍然正常工作)。我的整个语料库在三个 agent 上都解析干净,但我很想看看是什么让它出问题。如果你有这样一个情况,把错误发给我。
Live demo: https://fayzan123.github.io/rungraph
Repo: https://github.com/fayzan123/rungraph
用 npx rungraph 对你自己的会话跑一下,然后接入 MCP 服务器,问你的 agent 一个你以前会滚动去找的问题。如果它在某个你本来已经信任的运行记录里标记出了真实的问题,我想听听。