{"id":51080454,"url":"https://github.com/umgbhalla/cwviz","last_synced_at":"2026-06-23T17:03:52.667Z","repository":{"id":366841091,"uuid":"1278082034","full_name":"umgbhalla/cwviz","owner":"umgbhalla","description":"Terminal UI to visualise Claude Code workflows, live/historical runs, and chat-history sessions — yuku-analysed, opentui-rendered","archived":false,"fork":false,"pushed_at":"2026-06-23T13:36:36.000Z","size":10637,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-23T15:25:42.919Z","etag":null,"topics":["bun","claude-code","opentui","terminal","tui","visualization","workflow","yuku"],"latest_commit_sha":null,"homepage":"https://viz.quel.computer","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/umgbhalla.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-23T12:53:32.000Z","updated_at":"2026-06-23T13:37:06.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/umgbhalla/cwviz","commit_stats":null,"previous_names":["umgbhalla/cwviz"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/umgbhalla/cwviz","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umgbhalla%2Fcwviz","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umgbhalla%2Fcwviz/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umgbhalla%2Fcwviz/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umgbhalla%2Fcwviz/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/umgbhalla","download_url":"https://codeload.github.com/umgbhalla/cwviz/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umgbhalla%2Fcwviz/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34698946,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-23T02:00:07.161Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bun","claude-code","opentui","terminal","tui","visualization","workflow","yuku"],"created_at":"2026-06-23T17:03:51.966Z","updated_at":"2026-06-23T17:03:52.661Z","avatar_url":"https://github.com/umgbhalla.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003ecwviz\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003eA terminal UI to see what your Claude Code workflows actually do —\u003cbr/\u003e\n  the blueprints, the live runs, and the chat history behind them.\u003c/b\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg alt=\"license\" src=\"https://img.shields.io/badge/license-MIT-9ece6a?style=flat-square\" /\u003e\n  \u003cimg alt=\"runtime\" src=\"https://img.shields.io/badge/runtime-Bun-c0caf5?style=flat-square\u0026logo=bun\" /\u003e\n  \u003cimg alt=\"ui\" src=\"https://img.shields.io/badge/TUI-opentui-7dcfff?style=flat-square\" /\u003e\n  \u003cimg alt=\"analysis\" src=\"https://img.shields.io/badge/analysis-yuku-bb9af7?style=flat-square\" /\u003e\n  \u003cimg alt=\"status\" src=\"https://img.shields.io/badge/status-alpha-e0af68?style=flat-square\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/demo.gif\" alt=\"cwviz demo — Workflows, Runs and Sessions modes\" width=\"900\" /\u003e\n\u003c/p\u003e\n\n---\n\nClaude Code's [Workflow tool](https://docs.claude.com/en/docs/claude-code) lets an agent fan\nout subagents from a script — `agent()` / `parallel()` / `pipeline()` / `phase()`. Those scripts\nlive in `.claude/workflows/*.js`, every execution is journaled under `~/.claude/projects/`, and\nevery conversation is a `.jsonl` transcript. **cwviz reads all three and shows them in one TUI.**\n\n`Tab` cycles three modes:\n\n| Mode | What it shows | Source |\n|------|---------------|--------|\n| **Workflows** | The *blueprint* — phase tree, every `agent()` call with its `agentType` / `schema` / `model`, `parallel`/`pipeline` fan-out, loops. | `.claude/workflows/*.js`, parsed with [yuku](https://github.com/yuku-toolchain/yuku) — **never executed** |\n| **Runs** | Live + historical *executions* — per-agent state (`✓` done · `●` running · `✗` error · `◌` queued), the tool each agent is on, tokens, tool calls, duration, result previews. A workflow running **right now** shows up `● LIVE` with its agents reconstructed from their live subagent transcripts. Auto-refreshes. | `wf_*.json` journals + live `subagents/` tail |\n| **Sessions** | The *chat history* — full transcript: prompts, replies, tool calls, results, collapsed thinking. | `~/.claude/projects/**/*.jsonl` transcripts (lazy-loaded) |\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd width=\"33%\"\u003e\u003cimg src=\"assets/01-workflows.png\" alt=\"Workflows mode\" /\u003e\u003cp align=\"center\"\u003e\u003csub\u003e\u003cb\u003eWorkflows\u003c/b\u003e — static graph\u003c/sub\u003e\u003c/p\u003e\u003c/td\u003e\n    \u003ctd width=\"33%\"\u003e\u003cimg src=\"assets/02-runs.png\" alt=\"Runs mode\" /\u003e\u003cp align=\"center\"\u003e\u003csub\u003e\u003cb\u003eRuns\u003c/b\u003e — live + historical\u003c/sub\u003e\u003c/p\u003e\u003c/td\u003e\n    \u003ctd width=\"33%\"\u003e\u003cimg src=\"assets/03-sessions.png\" alt=\"Sessions mode\" /\u003e\u003cp align=\"center\"\u003e\u003csub\u003e\u003cb\u003eSessions\u003c/b\u003e — chat history\u003c/sub\u003e\u003c/p\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n## Why\n\nA workflow script tells you what *should* happen. The run journal tells you what *did* —\nwhich agent stalled, where the tokens went, what each one concluded. cwviz puts the blueprint\nnext to its executions next to the conversation that started them, so you can actually read your\nown orchestration instead of grepping JSON.\n\n## Install\n\nNeeds [Bun](https://bun.sh). Then:\n\n```bash\ngit clone git@github.com:umgbhalla/cwviz.git\ncd cwviz\nbun install\nbun link          # registers the `cwviz` command on your PATH\n```\n\n## Use\n\nRun it in **any folder** that has a `.claude/workflows/` directory:\n\n```bash\ncd ~/some/repo\ncwviz                 # TUI — Tab toggles Workflows ⇄ Runs ⇄ Sessions\n```\n\nHeadless modes (no TUI — pipe-friendly):\n\n```bash\ncwviz --list [dir]    # one line per workflow script\ncwviz --runs [n]      # newest n run journals\ncwviz --json [dir]    # full static analysis as JSON\n```\n\n`dir` defaults to the current folder and is scanned recursively (skipping `node_modules`, `.git`,\n`worktrees`, `.deploy`). Runs and Sessions are read from `~/.claude/projects` (all repos).\n\n**Scope it** with `CWVIZ_PROJECTS` — a comma-separated allowlist matched against any path segment\nof a workflow's repo or a run/session's project. Useful for privacy or a focused view:\n\n```bash\nCWVIZ_PROJECTS=ax2,bun cwviz      # only the ax2 and bun repos in every mode\n```\n\n### Keys\n\n`Tab` switch mode · `↑↓` / `j` `k` select · `/` or `Ctrl-K` search · `esc` clear search · `PgUp` / `PgDn` scroll detail · `q` quit\n\n## How it works\n\n- **Workflows** — [`yuku-analyzer`](https://github.com/yuku-toolchain/yuku) parses each script\n  into an ESTree AST (`new Analyzer().addFile(...).ast`), then a `walk()` visitor pulls out the\n  `meta` block and every orchestration call. Statically-resolvable strings (literals, no-hole\n  templates, `+` concats) are read directly; template holes show as `·`; dynamic fan counts\n  (`arr.map(...)`) are reported as dynamic, never guessed. **No code is run.**\n- **Runs** — each journal carries a `workflowProgress` event stream (`workflow_phase` +\n  `workflow_agent` with `state`, `lastToolName`, `tokens`, `toolCalls`, `durationMs`,\n  `resultPreview`). cwviz rebuilds the phase→agent tree from it. In-flight runs are detected from\n  start-written `workflows/scripts/\u003cname\u003e-\u003crunId\u003e.js` that have no journal yet; the list\n  auto-refreshes every 1.5s so a running workflow appears and updates live.\n- **Sessions** — transcripts are large, so the list is built from a cheap head-read (title +\n  metadata) and the full transcript is parsed only when you select a session. The selected\n  session's `.jsonl` is **`fs.watch`ed** — Claude Code appends it per message, so the transcript\n  re-renders in real time and an active session is marked `● LIVE`. No polling.\n\nThe exact on-disk layout, line schemas, and write cadence — reverse-engineered from the Claude\nCode binary with [bun-demincer](https://github.com/vicnaum/bun-demincer) and verified empirically\n— are documented in [`docs/INFRA.md`](docs/INFRA.md).\n\n## Project layout\n\n```\nsrc/\n  model.ts  analyze.ts  discover.ts   Workflows: model, yuku analyser, file finder\n  runs-model.ts  runs.ts              Runs: model + journal/orphan discovery\n  sessions-model.ts  sessions.ts      Sessions: model + transcript parser\n  ui.ts                               opentui scene (3 modes, live polling)\n  index.ts                            CLI entry\n  *.test.ts                           parser + headless-render checks\n```\n\n```bash\nbun run check     # tsc --noEmit\nbun test          # analyser + run parser + session parser + headless render\n```\n\nThe render test mounts the real scene on [opentui's test renderer](https://github.com/anomalyco/opentui)\nand asserts against the captured cell grid — no PTY needed.\n\n## Built with\n\n- [**opentui**](https://github.com/anomalyco/opentui) — the native (Zig) terminal UI core that powers the interface\n- [**yuku**](https://github.com/yuku-toolchain/yuku) — the Zig JS/TS toolchain whose analyzer parses the workflow scripts\n- [**terminal-control**](https://github.com/kitlangton/terminal-control) (`termctrl`) — drove the real TUI in a PTY to capture every screenshot and the demo above\n- [**bun-demincer**](https://github.com/vicnaum/bun-demincer) — extracted the Claude Code binary to map its on-disk infra (see [`docs/INFRA.md`](docs/INFRA.md))\n- [**termcast**](https://github.com/kitlangton/termcast) — reference for opentui app patterns\n- [**Bun**](https://bun.sh) — runtime; runs the TypeScript directly, no build step\n\nThe demo corpus is real: workflows and runs from [Bun](https://github.com/oven-sh/bun) and a\nprivate agent project, browsed live.\n\n## License\n\n[MIT](LICENSE) © Umang Bhalla\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fumgbhalla%2Fcwviz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fumgbhalla%2Fcwviz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fumgbhalla%2Fcwviz/lists"}