{"slug": "show-hn-rungraph-see-your-ai-coding-agent-runs-as-a-graph", "title": "Show HN: Rungraph – See your AI coding-agent runs as a graph", "summary": "Rungraph, a new open-source tool, converts AI coding-agent transcripts into interactive directed graphs, allowing developers to visualize agent runs retroactively without hooks or setup. The tool, launched on Hacker News, scans ~/.claude/projects, starts a local server, and displays live-updating graphs of orchestrator, subagents, and tool nodes, with signals for retry storms, unresolved errors, interventions, outliers, and course changes. It aims to make 4,000-line transcripts readable by showing time flow, tool details, human interventions, and workflow runs.", "body_md": "**See your agent runs as a graph.**\n\n*That's rungraph watching the live session that built this feature — the strip\nsays what went wrong, and one click lights up the nodes it means.*\n\nYour coding agent already wrote down everything it did. `rungraph`\n\nturns those\ntranscripts into an interactive **directed agentic graph** — orchestrator,\nsubagents, and tools as nodes; spawn/return relationships as edges; the\ncourse-change moments (denials, answers, retries) marked on the path. It works\n**retroactively on every session you've ever run**: no hooks, no wrappers, no\nsetup, no telemetry.\n\n```\nnpx rungraph\n```\n\nThat's the whole quickstart. It scans `~/.claude/projects`\n\n, starts a local\nserver, and opens your browser. Pick a run — including one that's **running\nright now**: the graph grows live as the agent works (file watching only).\n\n**New here?** [docs/GUIDE.md](/fayzan123/rungraph/blob/master/docs/GUIDE.md) walks through the whole thing —\nreading the graph, what each signal means, wiring it to your own agent, and what\nto do when something looks broken.\n\nAgent sessions stopped being conversations a while ago. They're *runs*: an\norchestrator spawning subagents, workflows fanning out reviewers, tools\nfailing and retrying, a human occasionally saying no. rungraph draws that\nstructure so a 4,000-line transcript becomes something you can actually read:\n\n**Time flows down.** Your prompts are the backbone; parallel agents fan out into side-by-side lanes and return to the turn that collected their result.**Tool nodes say what ran**, not just which tool:`Bash · npm test ×12`\n\n,`Edit · canvas.jsx`\n\n,`Grep · waitForURL`\n\n. Consecutive calls of the same tool collapse into one node so a test-fix loop doesn't become a hairball.**Click any node** for the full story: prompt and response for turns; every call's inputs, outputs, errors, and timing for tools; the complete transcript for subagents. Tool nodes also show the**why**— the agent's own narration from just before the call (\"Now I'll rerun the tests to check…\").** Human interventions are first-class nodes.**A denied permission, an answered question, a mid-turn interrupt — these are the moments a run changes direction, and the edges that follow them carry the reason (`after permission denial`\n\n,`retry after failure`\n\n,`after Bash error`\n\n).**Workflow runs**(multi-agent orchestrations) appear as single nodes you can drill into: their own graph, phase boxes and all, retries linked to the attempts they replaced.**Tokens, durations, and models** annotate nodes; whole-run totals in the header.\n\nA graph that renders everything with equal weight points at nothing: a\ntwo-second file read and a forty-minute retry spiral look identical. So\nrungraph has an opinion. It derives **signals** from the run and puts them in a\nstrip above the canvas — and on a clean run that strip costs zero height,\nbecause a marker you can't trust is worse than no marker.\n\n| fires when | |\n|---|---|\n⟳ retry storm |\nthe same tool kept failing in one place — `Edit` fails, the agent reads the file, `Edit` fails again |\n⚠ unresolved error |\nsomething failed and nothing ever came back to fix it |\n✋ intervention |\nyou denied a permission, interrupted a turn, or answered a question |\n◆ outlier |\na step that cost far more tokens or wall-clock than the rest of the run |\n⚑ course change |\nthe run's own recorded lineage for why it changed direction |\n\nClick a signal and the graph **focuses**: those nodes light up, everything else\ndims to a quarter — dimmed, never hidden, so the shape you already memorized\nstays put. `Esc`\n\nor a click on empty canvas clears it.\n\nThe same focus mechanism backs everything else that points at nodes:\n\n**Find**(`/`\n\n) — plain substring over node labels*and the files each node touched*. No model, no network, no subprocess; it filters in the browser.**Files**— tool and agent nodes carry the paths they touched, including work done** inside subagents**, which is where a lot of real editing happens. The inspector lists every file the run touched with a count; click one to see exactly which steps touched it.**Live escalation**— signals are re-derived on every live-tail update. Go do something else while the agent works; the strip goes loud only when something new has actually gone wrong.\n\nThe dashboard is for you; the MCP server is for your agent. They are two ends of one loop, not two products.\n\n```\nnpx rungraph mcp --install     # one time, then restart Claude Code\nnpx rungraph mcp --check       # is it working? prints exactly what to fix\n```\n\nYou don't have to guess what to ask, either: the dashboard writes the\nquestions for you, from the run you're looking at — *\"why did the Edit on\ntoken.js keep failing?\"* — with a copy button. Paste one into Claude Code.\n\nThen, in Claude Code: *\"which edits in my last run failed?\"* Claude calls\n`find_nodes`\n\n/ `get_graph`\n\n/ `get_detail`\n\n, **answers in your terminal** — your\nmodel, your session, fully inspectable — and then calls `focus_nodes`\n\n, and the\ndashboard you have open lights up the nodes it just described.\n\nNothing is pinned, prompted, or proxied: rungraph contributes the graph, not the conversation. The read-only tools work with no server running at all.\n\n| tool | does |\n|---|---|\n`list_runs` |\nthe run index |\n`get_graph` |\none run's graph, compact by default (signals + files included) |\n`find_nodes` |\nnarrow before you pull — a big graph is 20k+ tokens |\n`get_detail` |\nthe actual error text behind one node |\n`focus_nodes` |\nlight up the open dashboard; returns a pastable deep link |\n`get_current_view` |\nwhat the dashboard is showing right now |\n`open_visualization` |\nopen the browser on a run |\n\nWith more than one dashboard live — yours, plus a bundle someone sent you\n(below) — the MCP aggregates them: `list_runs`\n\nmerges every server's runs,\ntagged with where they came from, and every other tool routes by run id to the\ndashboard actually showing that run.\n\nA run can leave the machine — as a file, on your terms. Say Bilal's agent went sideways and you could help, or you want to show a colleague where a feature was actually built.\n\n**Bilal exports.** Either from the dashboard — *share…* in the runs pane, check\noff runs, review what's about to leave — or by asking his agent:\n\n```\nrungraph export --last 2 --as Bilal\n# rungraph: export inventory (full content):\n#   2 runs · 143 nodes · 12 of your prompts included\n#   files touched: 24\n# rungraph: wrote acme-2026-08-15.rungraph (412,882 bytes)\n```\n\nThe inventory prints every time: people don't realize how much lives in a\ntranscript, so the tool shows it before it leaves. And export **blocks** if it\nfinds a high-confidence secret (AWS keys, GitHub/Slack/API tokens, private-key\nblocks — anchored patterns, calibrated for near-zero false positives), listing\nexactly where each one is. Resolve with `--redact-secrets`\n\n(placeholders,\neverything else verbatim), `--structure-only`\n\n(graph shape, tool names, files\nand timings — no prompts, no outputs), or `--allow-secrets`\n\nif they're fixture\nkeys you've checked.\n\n**The file is the transfer.** Send the `.rungraph`\n\nover whatever you already\ntrust — Slack, AirDrop, a repo. rungraph itself never touches a network.\n\n**You open it.**\n\n```\nnpx rungraph open team-work.rungraph\n```\n\nThat serves the bundle on its own ephemeral dashboard — nothing is copied\nanywhere; close the process and it's gone; keep the file to re-open it any\ntime. Every run wears its provenance (\"shared by Bilal · team-work.rungraph\"),\nand the whole loop works on it: signals derive on *your* rungraph, and your own\nagent can be pointed at Bilal's runs — *\"what went wrong in the bundle Bilal\nsent me?\"* — right alongside your own.\n\nA bundle carries the vendor-neutral IR, so a Codex run exports and opens\nidentically to a Claude Code one, and opening a bundle needs no adapters at\nall. `sharedBy`\n\nis a display string, not an identity — trust a bundle the way\nyou trust the channel it arrived on.\n\n**Link to what you see.** *copy link* in the header captures the current view —\nrun, selected node, focus — as a URL; `focus_nodes`\n\nreturns the same kind of\nlink, so your agent can hand you something pastable for a PR or an issue. Links\nre-execute their query on load (a find link re-finds, a signal link\nre-derives), and a link that lands on the wrong dashboard offers a one-click\njump to the one that has the run.\n\nNavigation is Figma-style, built for the tall, skinny graphs real runs produce:\n\n| Input | Action |\n|---|---|\n| Two-finger scroll | Pan |\n| Pinch / cmd+scroll | Zoom at the cursor |\n| Click-drag | Pan |\n| Click node / edge | Inspect it |\n| Double-click node | Zoom to 100%, centered |\n`j` / `k` (or `↓` / `↑` ) |\nWalk nodes in run order, inspector follows |\n`f` |\nFit the whole graph |\n`/` |\nFind by label or file |\n`Esc` |\nDeselect and clear the focus |\n\nA **minimap** (bottom-right) shows the whole run as a strip with a draggable\nviewport — errors glow as red beacons; click one to jump straight to the\nfailure. Runs open at readable zoom: finished runs at the first prompt, live\nruns at the latest activity, with follow mode sliding the view as new nodes\nstream in.\n\nEverything the UI can do, a coding agent can do over the CLI — no browser, no\nprompts, JSON on stdout, logs on stderr, exit codes `0`\n\nok / `1`\n\nerror / `2`\n\nno\nruns found. Paste this section into a prompt and an agent can self-serve:\n\n```\nnpx rungraph list --json\n# {\"runs\":[{\"runId\":\"claude-code:…:5822df8b-…\",\"kind\":\"session\",\"title\":\"Fix flaky auth test\",\n#           \"project\":\"/home/you/dev/app\",\"modifiedAt\":\"2026-08-11T16:31:06.055Z\",\"active\":true,…},…]}\n\nnpx rungraph graph 'claude-code:…:5822df8b-…' --json\n# The full Graph IR for that run on stdout:\n# {\"irVersion\":1,\"meta\":{\"runId\":\"…\",\"kind\":\"session\",\"title\":\"…\",\"totals\":{\"tokens\":184230,\"toolCalls\":57,\"agents\":4},…},\n#  \"nodes\":[{\"id\":\"…\",\"kind\":\"agent\",\"label\":\"Investigate flaky test\",\"status\":\"completed\",\n#            \"files\":[\"/home/you/dev/app/src/auth/token.js\"],\"tokens\":{…}},…],\n#  \"edges\":[{\"kind\":\"spawn\",\"from\":\"…\",\"to\":\"…\",\"label\":\"Investigate why auth.spec.ts flakes\"},…],\n#  \"groups\":[…],\n#  \"signals\":[{\"kind\":\"retry-storm\",\"severity\":\"high\",\"nodeIds\":[\"…\"],\"label\":\"6 failed Edit calls\",\n#              \"reason\":\"Edit failed 6× across 3 consecutive steps on token.js, …\"}]}\n# → an agent can read its own past runs: what it spawned, what failed, where the human said no.\n\nnpx rungraph find 'claude-code:…:5822df8b-…' token.js --json\n# {\"matched\":4,\"nodeIds\":[…],\"nodes\":[…]}\n# → narrow first. A big graph is 20k+ tokens of context to answer one question.\n\nnpx rungraph serve --no-open\n# {\"url\":\"http://127.0.0.1:4321\"}   (server stays in foreground; same data over HTTP + SSE live tail)\n```\n\nThe same surface is available as MCP tools — see \"Ask your agent about a run\"\nabove, or `rungraph mcp --install`\n\n.\n\nThe IR is versioned and documented in [SCHEMA.md](/fayzan123/rungraph/blob/master/SCHEMA.md). It is\nvendor-neutral, with two adapters: Claude Code (sessions, subagents, and\nWorkflow runs, under `~/.claude/projects`\n\n) and Codex CLI (rollout threads and\ntheir spawned subagent threads, under `~/.codex/sessions`\n\n). Everything\ndownstream — including `.rungraph`\n\nbundles — carries only the IR.\n\nEverything is local. The server binds `127.0.0.1`\n\nonly, and every request is\nHost-header-guarded, so a hostile web page can't DNS-rebind its way into your\ntranscripts. rungraph makes no network requests and phones nothing home.\n\nNothing leaves your machine unless you run `rungraph export`\n\n— an explicit\ncommand naming explicit runs, which prints an inventory of what's included\nevery time and hard-stops on detected secrets. The transfer channel for the\nresulting file is yours, not rungraph's.\n\nClaude Code writes JSONL transcripts under `~/.claude/projects`\n\n— main session\nfiles, per-subagent files, and workflow journals with a manifest per run.\n`rungraph`\n\nreconstructs the run graph from those files post-hoc: adapters turn\ntranscript lines into a versioned, vendor-neutral IR, and everything\ndownstream (web UI, CLI, HTTP API) consumes only the IR.\n\nIt is built to survive real transcripts:\n\n**Never a blank screen.** Unknown line types are skipped and counted — if the transcript format is newer than your rungraph, you get a banner and a graph, not a crash. A half-written final line (an agent mid-write) is tolerated and retried on the next tick.**Live without hooks.** Liveness comes from watching the run's own files; the graph updates over SSE with stable node ids, so deltas merge instead of redrawing.**Light on your machine.** The backend has zero runtime dependencies (`node:http`\n\n,`fs.watch`\n\nand friends). The frontend (Preact + elkjs) ships prebuilt in the package — there is no build step on your machine.\n\n```\nrungraph                       scan, serve, open browser (human default)\nrungraph list [--json]         run index, newest first\nrungraph graph <runId>         Graph IR for one run (JSON on stdout)\nrungraph find <runId> <query>  nodes whose label or files match a substring\nrungraph serve [--no-open]     start server; prints {\"url\": …}\nrungraph export <runId…>       write a shareable .rungraph bundle (see --help)\nrungraph open <bundle…>        serve bundle files, ephemerally\nrungraph mcp [--install]       MCP server on stdio; --install registers it once\nrungraph mcp --check           verify the agent side end to end\n  --project <path>             only runs for this project directory\n  --port <n>                   preferred port (auto-increments if taken)\n  --last <n>                   export: the n most recent runs of this project\n  --scope <s>                  mcp --install: user (default) | project | local\n```\n\nRequires Node ≥ 20.\n\n**Annotations**— mark nodes before exporting a bundle (\"look here first\").** Cross-run questions**— file attribution lives in each run's IR, so asking \"what else touched this file?\" across runs needs iteration, not a migration.**Run comparison**— diff two runs of the same task.** Cost estimates**— turn per-node token counts into dollars.", "url": "https://wpnews.pro/news/show-hn-rungraph-see-your-ai-coding-agent-runs-as-a-graph", "canonical_source": "https://github.com/fayzan123/rungraph", "published_at": "2026-08-16 16:18:51+00:00", "updated_at": "2026-08-16 16:40:53.026331+00:00", "lang": "en", "topics": ["developer-tools", "ai-agents", "ai-tools"], "entities": ["Rungraph", "Hacker News", "Claude"], "alternates": {"html": "https://wpnews.pro/news/show-hn-rungraph-see-your-ai-coding-agent-runs-as-a-graph", "markdown": "https://wpnews.pro/news/show-hn-rungraph-see-your-ai-coding-agent-runs-as-a-graph.md", "text": "https://wpnews.pro/news/show-hn-rungraph-see-your-ai-coding-agent-runs-as-a-graph.txt", "jsonld": "https://wpnews.pro/news/show-hn-rungraph-see-your-ai-coding-agent-runs-as-a-graph.jsonld"}}