TokenEconomizer
Experience-Driven Black-Box Cost Control for Coding Agents
A local, read-only live 3D viewer and replayer for Claude Code sessions. Open source (Apache-2.0).
Developer toolsGitHub @burn001OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Repository information has not been collected yet.
No updates detected yet. GitHub releases will appear here.
See what your Claude Code agents are doing — live in 3D, then replay it. Local, read-only viewer for subagents, workflows, claude -p and background shells.
Taken from the repository README
Loading the full README.
Read the full README ↗Agent4D — your coding agents in 3D space + time
Visual Companion for Lonely Vibecoders
English (canonical) · 한국어
See what your Claude Code agents are doing, live, in 3D — and play it back later. Agent4D is a local, read-only viewer that turns the main agent, its subagents, workflow agents, nested claude -p runs, background shells and monitors into one live tree in your browser: three dimensions of space, plus time through live streaming and replay. The command-line tool is agent4d (ccviz still works).
▶ Watch the 24-second intro video (MP4)
You need Node.js 22.18 or newer on a PC where you use Claude Code (it reads the session files under ~/.claude/projects/). Nothing to npm install.
git clone https://github.com/burn001/agent4d
node agent4d/bin/agent4d.mjs start # prints a local link: http://127.0.0.1:7788/?t=<token>
Open the printed link in your browser. To let Claude Code open it for you ("open agent4d"), install the bundled skill: Use with Claude Code (skill). No Claude Code history yet? Try npm run demo inside the clone (Run).
claude -p runs in one live tree, with the current tool next to each one.Unofficial project. Agent4D is an independent tool. Anthropic did not make it, does not endorse it and does not support it. "Claude" and "Claude Code" are trademarks of Anthropic, PBC, used here only to say what this tool works with.
The default view: hexagon nodes, tapered curved beams and packets moving along them.
| Live | Dark | Light |
|---|---|---|
The main agent is a gyro tourbillon — a steel cage with chamfered bridges turning over a fixed gold fourth wheel, its escape pinion rolling on the wheel and ticking on each beat, a balance wheel swinging inside a tilted inner cage. Subagents are planets with a simpler cage. Each project is a round orbital system.
| Live | Dark | Light |
|---|---|---|
Agents as office workers at desks, shelves and terminals.
| Live | Dark | Light |
|---|---|---|
| You, as a console next to the main agent | Work targets under the Planet view | 2D mode for slow machines |
|---|---|---|
All screenshots and loops use the built-in mock data (?mock=1&lang=en). Project names and labels are made up.
The server tails the transcripts that Claude Code already writes under ~/.claude/projects/ (and background task output files) and streams a summarized event feed to the browser over Server-Sent Events. It never writes to those files.
agent4d archive add).claude -p) visibly heats up as its own context window fills (warming at 30%, overheating at 70%, critical at 90%; cools down after a compact) — and an opt-in usage-limit gauge for the 5-hour and 7-day windows.Agent4D reads Claude Code today. Adapters for other agent harnesses are welcome as community pull requests — see docs/ADAPTERS.md for how the reader works and what an adapter has to provide.
| Harness | Status | Session files (to verify) | Tracking issue |
|---|---|---|---|
| Claude Code | ✅ Supported | ~/.claude/projects/<project>/<session>.jsonl | — |
| Codex CLI | Help wanted — PRs welcome | ~/.codex/sessions/**/*.jsonl (unverified) | #1 |
| Gemini CLI | Help wanted — PRs welcome | ~/.gemini/tmp/<project-hash>/ chats and checkpoints (unverified) | #2 |
| OpenClaw | Help wanted — PRs welcome | session JSONL files (unverified) | #3 |
| Hermes | Help wanted — PRs welcome | unknown | #4 |
npm install for local use.bin/agent4d shell wrapper), but macOS and Linux have not been tested yet. autostart is Windows-only (Task Scheduler).cloudflared, and for the stable link a Cloudflare account with the cf CLI.numpy and lameenc (music/requirements.txt).git clone https://github.com/burn001/agent4d.git
cd agent4d
# optional: background music (see below)
gh release download --pattern "*.mp3" --dir web/assets
Quick start is enough to run it; the music download is optional. bin/agent4d (sh) and bin/agent4d.cmd (Windows) are thin wrappers around node bin/agent4d.mjs; put bin/ on your PATH if you want to type agent4d. The old name still works: ccviz (bin/ccviz, bin/ccviz.cmd, bin/ccviz.mjs) is an alias.
node bin/agent4d.mjs start # start the server on 127.0.0.1:7788 and print the local link
node bin/agent4d.mjs url # print the link again (it contains your view token)
node bin/agent4d.mjs status # server / tunnel / Worker status
node bin/agent4d.mjs stop # stop everything `start` launched
node bin/agent4d.mjs help # all commands and options
The first run creates a config file with random tokens (see Configuration). The link from url ends in ?t=<token>. After the first visit the browser keeps a cookie and the token is removed from the address bar.
start stays local unless you ask otherwise. It opens a public Cloudflare tunnel only with --tunnel, or when the config has "remote": true or a deployed workerUrl. --no-tunnel always forces local-only. Add --watch to keep a small watchdog that restarts the server if it dies.
Long jobs started outside Claude Code (a detached measurement run, a batch script) can be shown next to their project: node bin/agent4d.mjs job add --log run.log [--pid N] [--pattern RE] [--end done.flag] [--expect 2h]. The server tails the log and draws the job with its progress, rate and time left (live only). Manage them with job list, job find, job rm and job prune.
Try it without your own data:
npm run demo # synthetic session tree: reads no transcripts, makes no network calls
Then open http://127.0.0.1:7788/?t=<viewToken> (the token is viewToken in the config file). On a running server you can also add &mock=1 (one session) or &mock=1&scope=all (all projects) to the link to drive the UI from built-in mock data, and &view=planet or &view=voxel to pick a view.
The repository ships a Claude Code skill in skills/agent4d/. Put it in your personal skills folder and you can ask Claude Code things like "open agent4d", "show my agents in 3D", "update agent4d" or "stop agent4d". The skill finds your install (AGENT4D_HOME, then ~/agent4d, then agent4d on PATH), starts the local server if needed and shows you the link. It never starts a public tunnel unless you ask for one.
Link the folder rather than copying it, so the skill always matches your clone:
# macOS / Linux (clone at ~/agent4d)
mkdir -p ~/.claude/skills && ln -s ~/agent4d/skills/agent4d ~/.claude/skills/agent4d
:: Windows (cmd), clone at %USERPROFILE%\agent4d — a junction needs no admin rights
mkdir "%USERPROFILE%\.claude\skills" 2>nul
mklink /J "%USERPROFILE%\.claude\skills\agent4d" "%USERPROFILE%\agent4d\skills\agent4d"
A plain copy (cp -r skills/agent4d ~/.claude/skills/, or Copy-Item -Recurse in PowerShell) works too: agent4d update refreshes a copied skill when it differs from the clone, keeping the old files as *.bak.
If your clone is not at ~/agent4d, set AGENT4D_HOME to its folder. Start a new Claude Code session after installing so the skill is picked up.
node bin/agent4d.mjs update --check # is there a newer release? (cached for 24 hours)
node bin/agent4d.mjs update # show the plan, ask, then update
node bin/agent4d.mjs update --yes # update without asking
update works on a git clone. It stops and explains why if the clone has local changes, is not on main, or cannot fast-forward to origin/main. Otherwise it runs git pull --ff-only (with tags), refreshes a copied skill (a linked skill needs nothing), and restarts the server with the same options if it was running. An install that is not a git clone only gets a pointer to the Releases page. Clones whose origin is not this repository (forks, development clones) are left alone.
The server checks for a new release when it starts and then once a day (the result is cached in update-check.json). When one is out, the ⚙ menu shows a small dot and "vX.Y.Z available" next to the version, linking to the release. With the skill installed, Claude Code also mentions a new version when you open Agent4D and asks before updating (set AGENT4D_AUTO_UPDATE=1 to let it update without asking).
To turn the check off, set "updateCheck": false in config.json or the environment variable AGENT4D_NO_UPDATE_CHECK=1. Then no network request is made.
The 46 tracks (bgm-aurora.mp3, bgm-bossa.mp3, bgm-caper.mp3, bgm-chillhop.mp3, bgm-circuit.mp3, bgm-city.mp3, bgm-comet.mp3, bgm-copier.mp3, bgm-cursor.mp3, bgm-dawn.mp3, bgm-deadline.mp3, bgm-deepfield.mp3, bgm-deephouse.mp3, bgm-drive.mp3, bgm-espresso.mp3, bgm-funk.mp3, bgm-glacier.mp3, bgm-gravity.mp3, bgm-hotfix.mp3, bgm-hyperspace.mp3, bgm-ionstorm.mp3, bgm-jazz.mp3, bgm-liquid.mp3, bgm-lofi.mp3, bgm-mambo.mp3, bgm-meeting.mp3, bgm-nebula.mp3, bgm-orbit.mp3, bgm-overclock.mp3, bgm-pantry.mp3, bgm-pulsar.mp3, bgm-pulse.mp3, bgm-queue.mp3, bgm-rainwindow.mp3, bgm-refactor.mp3, bgm-satellite.mp3, bgm-sprint.mp3, bgm-stack.mp3, bgm-stardust.mp3, bgm-supernova.mp3, bgm-swing.mp3, bgm-teatime.mp3, bgm-typewriter.mp3, bgm-uplift.mp3, bgm-warp.mp3, bgm.mp3; about 4.6 MB each) are attached to the latest release rather than stored in the repository. Put them in web/assets/. Without them the viewer works fine, just without music (sound effects still play).
# with the GitHub CLI, inside the clone (latest release)
gh release download --pattern "*.mp3" --dir web/assets
# or with curl, one file at a time
curl -L -o web/assets/bgm-lofi.mp3 https://github.com/burn001/agent4d/releases/latest/download/bgm-lofi.mp3
You can also generate them yourself. Output is deterministic; each track takes about 2–4 minutes and up to 1.5 GB of RAM.
python -m pip install -r music/requirements.txt
python music/compose.py # web/assets/bgm.mp3
python music/compose_lofi.py --out <tmp>/bgm-lofi.mp3 # likewise jazz, city, chillhop, dawn, …
python music/tracks.py copy lofi --from <tmp> # copy mp3 + json into web/assets/
music/README.md (in Korean) has the details.
Everything here runs on your own Cloudflare account. Nothing in this repository points at a shared deployment.
browser ─▶ https://cc-agent-viz.<your-subdomain>.workers.dev/?t=<token> (stable link)
Worker: check token → cookie → look up the current origin in KV → proxy (SSE streaming)
─▶ https://<random>.trycloudflare.com (quick tunnel, changes on restart)
─▶ relay :7789 ─▶ server :7788 (127.0.0.1)
cloudflared. On Windows the default path is C:/Program Files (x86)/cloudflared/cloudflared.exe; elsewhere it is looked up on PATH. You can set cloudflaredPath in the config.cf CLI and sign in (cf auth login). The Worker is configured in cloudflare/cloudflare.config.ts; no Wrangler file is used.node bin/agent4d.mjs deploy creates or reuses a KV namespace, deploys the Worker (named cc-agent-viz unless you change workerName), sets the VIEW_TOKEN and ADMIN_SECRET secrets, and saves your workers.dev URL in the config. The KV namespace ID is passed at deploy time and never written to the repository.node bin/agent4d.mjs start --tunnel --watch starts the server, relay and tunnel, registers the tunnel address with the Worker, and keeps a watchdog that restarts and re-registers on failure. Once deploy has saved a workerUrl, a plain start also goes remote; set "remote": false in the config (or pass --no-tunnel) to stay local.node bin/agent4d.mjs rotate-token issues a new view token and updates the Worker secret. Old links stop working.Useful options: start --project <encoded-project-dir> limits what the link can see to one project; start --session <id> pins the link to one session.
The 5-hour / 7-day gauge is filled by a small collector that reads the Claude Code OAuth access token from ~/.claude/.credentials.json and calls https://api.anthropic.com/api/oauth/usage. This endpoint is undocumented and unofficial and may change or stop working at any time.
agent4d/<version>.It is off by default. To turn it on, run node bin/agent4d.mjs start --limits once; this saves "limits": { "source": "oauth" } in the config (restart a running server with stop, then start). start --no-limits turns it off again. node bin/agent4d.mjs limits --once queries it once from the command line. Use it at your own discretion.
Read this before you share any link.
t, cookie, or X-CCVIZ-Token header). There is no localhost exemption. Treat a link with ?t= like a password: keep it out of chats, tickets and screenshots. If it leaks, run rotate-token.project is set (or start --project), a token holder can browse every Claude Code session on the machine. Limit it to one project before giving a link to anyone else.127.0.0.1. It is reachable from the internet only through the optional tunnel and Worker, which you turn on yourself (--tunnel, "remote": true, or a deployed Worker).agent4d archive add.server/redact.mjs, which masks API keys, bearer tokens, JWTs, PEM blocks, credentials in URLs, password=-style pairs, emails, phone and ID numbers, and long opaque strings. Thinking content and full tool inputs are never sent. "privacy": "minimal" sends even less. Redaction cannot catch everything, so don't rely on it for sensitive work.agent4d update --check make one unauthenticated request to the GitHub API (api.github.com/repos/burn001/agent4d/releases/latest) at most once a day. Nothing else is sent: no session data, paths, tokens or identifiers beyond the usual HTTP headers (User-Agent: agent4d/<version>). Turn it off with "updateCheck": false or AGENT4D_NO_UPDATE_CHECK=1.State and secrets live outside the repository, in ~/.cc-agent-viz/ (the folder keeps the project's earlier name for now). If you used an earlier version and ~/.cc-session-viz/ exists, that folder keeps being used. Set CCVIZ_HOME to use any other folder. Files are created with owner-only permissions where the OS allows it.
| File | Contents |
|---|---|
config.json | viewToken, adminSecret, port (7788), privacy (summary / minimal), project, linkSession, remote (true / false; unset = remote only if workerUrl is set), cloudflaredPath, tunnelProtocol (http2), workerName (cc-agent-viz), workerUrl, kvNamespaceId, limits { source: off (default) / oauth / auto / statusline, … }, overviewMaxRoots, archiveDir, serviceScripts, updateCheck (true by default; false = no update check) |
usage-cache.json | last usage-limit values (percentages and reset times only) |
update-check.json | last update check: time, installed and latest version, release link, one-line notes |
state.json | process IDs of the server, relay, tunnel and watchdog; current tunnel URL |
logs/ | server.log, relay.log, cloudflared.log, watch.log |
Claude Code data is read from ~/.claude (or CLAUDE_CONFIG_DIR). The archive folder is set with archiveDir, CCVIZ_ARCHIVE or --dir; there is no default.
serviceScripts lets the "work targets" layer label your own helper scripts as external services, for example [{ "pattern": "my-mail-cli\\.mjs", "name": "Mail" }] (a case-insensitive regex matched against the arguments of node, python or bash). Well-known CLIs (gws, aws, gcloud, cf, docker, …) are recognized without it.
The page is empty or says it is waiting for sessions.
The viewer only shows sessions that Claude Code has written to ~/.claude/projects/. Start or continue a Claude Code session and it appears within a few seconds. If your Claude Code data lives elsewhere, set CLAUDE_CONFIG_DIR before start.
I get "401" or "unauthorized".
The link needs the view token. Run node bin/agent4d.mjs url and open that link once; the browser then keeps a cookie. After rotate-token, old links and cookies stop working.
Port 7788 is already in use.
Use start --port 7790 (or set port in the config). status shows what agent4d itself is running; stop stops it.
3D is blank, black or very slow.
Switch to 2D with the 3D/2D button in the top bar (or add &dim=2d to the link). three.js is loaded from the jsDelivr CDN; on networks that block it, only 2D works.
No music. The MP3 files are not in the repository; see Background music. Browsers also block audio until you interact with the page, so click once after turning sound on.
The usage-limit gauge shows nothing.
It is off by default. Turn it on with start --limits, and make sure you are signed in to Claude Code with a subscription account (the collector reads ~/.claude/.credentials.json). The endpoint is unofficial and may stop working.
How do I change the language?
Web UI: the language row in the ⚙ settings menu, or ?lang=en / ?lang=ko in the link. CLI: --lang en|ko or the CCVIZ_LANG environment variable; otherwise LC_ALL, LC_MESSAGES, LANG and then the system locale decide, with English as the fallback.
Does it send my data anywhere? Not in the default local mode. Only the optional remote mode sends the viewer stream through your own Cloudflare tunnel and Worker, and only the opt-in usage-limit collector talks to Anthropic's API (to read your own usage).
Is it safe to run next to Claude Code? Yes. It only reads files that Claude Code writes, never modifies them, and does not talk to the Claude Code process.
npm test # node --test for server/ and web/
agent4d --version # also shown by `agent4d status` and at the bottom of the ⚙ menu
Releases follow Semantic Versioning (0.x until 1.0); see CHANGELOG.md. Contributions: CONTRIBUTING.md.
Most code comments are in Korean. Bug reports and pull requests are welcome; please include your OS, Node version and browser, and never paste a link that contains ?t=.
music/ with numpy and encoded with lameenc. Three tracks (lofi, jazz, city) are arrangements derived from the author's earlier project; the rest are original.cloudflared) and Cloudflare Workers with KV.Apache License 2.0 © 2026 burn001 (Dr. Cho, Sangkyu). See NOTICE. Uses three.js (MIT).