ccdeck 1.42.0 → 1.44.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,33 +1,229 @@
1
+ <div align="center">
2
+
1
3
  # ccdeck
2
4
 
3
5
  **A live canvas for your AI agents.** Watch Claude Code and OpenAI Codex call tools and finish — every Claude Code subagent on a node of its own — all on one calm graph, in real time.
4
6
 
7
+ [![npm](https://img.shields.io/npm/v/ccdeck?color=cb3837&logo=npm&logoColor=white)](https://www.npmjs.com/package/ccdeck)
8
+ [![agents-deck downloads](https://img.shields.io/npm/dm/agents-deck?color=blue&label=agents-deck%20downloads)](https://www.npmjs.com/package/agents-deck)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
10
+ [![Node.js >=18](https://img.shields.io/badge/node-%3E%3D18-brightgreen?logo=node.js&logoColor=white)](https://nodejs.org)
11
+ [![macOS · Linux · Windows](https://img.shields.io/badge/macOS%20·%20Linux%20·%20Windows-supported-6aa9f7)](#requirements)
12
+
13
+ [What you get](#what-you-get) · [Quick start](#quick-start) · [How it works](#how-it-works) · [What it touches](#what-it-touches) · [Accounts](#accounts) · [Options](#options)
14
+
5
15
  ```bash
6
16
  npx ccdeck
7
17
  ```
8
18
 
9
- Opens **http://127.0.0.1:4317** and registers the Claude Code hook on first run. Start any Claude Code or Codex session and the graph fills in live. `Ctrl+C` stops it. No config file, no account, no telemetry.
19
+ [![ccdeck — live agent DAG](assets/canvas.png)](assets/canvas.png)
20
+
21
+ *An older shot — the deck was still called `agents-deck` then. Click through for full size.*
22
+
23
+ </div>
10
24
 
11
- ## What this package is
25
+ ---
12
26
 
13
- `ccdeck` is the short name for [`agents-deck`](https://www.npmjs.com/package/agents-deck) — one project published under three names (`ccdeck`, `agents-deck`, and the original `agent-dag`), running the same deck from any of them.
27
+ ## Why
14
28
 
15
- This package is a thin stub: it depends on the exact matching version of `agents-deck`, hands your arguments to its binary, and reports back whatever the deck reported — including the signal it was killed by. It ships only the `ccdeck` command; a global install of `agents-deck` puts all three on your `PATH`.
29
+ An agent session is a tree, but a terminal shows it as a scroll. Five subagents working in parallel arrive as one interleaved column of text, and the questions you actually have — *what is running right now, what did that subagent do, which one is stuck, what is this costing* — are the ones the scroll answers worst.
16
30
 
17
- ## Everything else
31
+ ccdeck draws the tree instead. It is local and needs no configuration: it registers a hook, listens, and paints.
18
32
 
19
- Options, environment variables, the Accounts panel, how capture works for each provider, updating, uninstalling — all of it is documented once, in the project README:
33
+ ## What you get
20
34
 
21
- **https://github.com/BarganConstantin/ccdeck#readme**
35
+ One canvas. No tabs. No kanban.
36
+
37
+ | | |
38
+ |---|---|
39
+ | **Blocked on you** | A permission prompt or a finished turn waiting for your next instruction sorts that session to the top of the sidebar with how long it has been stuck, and puts a count in the topbar that jumps to the oldest one. Claude Code only — Codex emits no such signal. |
40
+ | **Cost and quota, live** | Spend per model and per session, plus Claude and Codex quota windows as they refill. |
41
+ | **Live DAG** | Nodes are agents, edges are spawns and tool calls. In-flight edges animate, settled ones fade. |
42
+ | **Both providers, one canvas** | Claude Code through hooks, Codex through its rollout log. The model chip (`Opus 5`, `GPT-5.5`) tells them apart. |
43
+ | **Click to inspect** | Any node opens its prompt, tool calls, token usage and timing. |
44
+ | **Survives restarts** | Events are appended to `~/.claude/agent-dag/events.jsonl` and replayed on open. |
45
+ | **Accounts without a terminal** | Sign a new Claude account in, share one to another machine, rename, reorder, remove — from the panel. |
46
+ | **Knows when it is stale** | Node caches modules at startup, so an upgraded-while-running deck keeps executing old code. This one says so, and can restart itself when nothing is running. |
47
+ | **Workspace scoping** | `--scope` for the current directory, `--workspace <path>` for any subtree — for Claude Code and Codex alike. |
48
+
49
+ ## Quick start
50
+
51
+ ```bash
52
+ npx ccdeck # or: npx agents-deck · npx agent-dag — same deck
53
+ ```
54
+
55
+ Opens **http://127.0.0.1:4317** and registers the Claude Code hook on first run. Start any Claude Code or Codex session and the graph fills in live. `Ctrl+C` stops it.
56
+
57
+ No config file. No account. No telemetry — nothing about your sessions is reported anywhere.
58
+
59
+ What the deck does write, and the short list of what does leave the machine, is in [What it touches](#what-it-touches).
22
60
 
23
61
  ## Requirements
24
62
 
25
- Node.js ≥ 18 — macOS, Linux and Windows. Plus the Claude Code CLI or the OpenAI Codex CLI, or both.
63
+ - Node.js ≥ 18 — macOS, Linux and Windows
64
+ - Claude Code CLI or OpenAI Codex CLI (or both)
65
+ - Optional: [claude-swap](https://pypi.org/project/claude-swap/) for the Accounts panel; the deck can install it for you
66
+
67
+ ## How it works
68
+
69
+ Two capture paths feed one SSE stream, which feeds one canvas.
70
+
71
+ **Claude Code** — on first run, ccdeck adds a hook entry to `~/.claude/settings.json` for every relevant event (or to `$CLAUDE_CONFIG_DIR/settings.json`, and every other path below moves with it, when you have that variable set):
72
+
73
+ ```
74
+ SessionStart · UserPromptSubmit · PreToolUse · PostToolUse · PostToolUseFailure
75
+ SubagentStart · SubagentStop · Stop · SessionEnd · Notification
76
+ ```
77
+
78
+ Each one fires the bundled `hook.js`, which POSTs the event JSON to the running server. The hook is fire-and-forget with a 1-second timeout: if the deck is not running, your session is not slowed down and nothing fails.
79
+
80
+ **OpenAI Codex** — Codex CLI hooks do not fire reliably on Windows, so nothing is installed at all. The server tails Codex's own rollout files at `~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl` and reconstructs the equivalent stream — session start, prompts, tool calls, token usage, model. No hook install, no trust prompt. Set `CODEX_HOME` to override the path.
81
+
82
+ Quota is the one thing that is not just reading. It needs a live token, so when the one in `~/.codex/auth.json` is within 90 seconds of expiring the deck refreshes it exactly as the CLI does and writes the rotated credential back — one refresh at a time, re-reading the file inside the lock, and atomically, because OpenAI's refresh tokens are single-use and a rotation that never reaches disk costs you a `codex login`. It happens only while the page is open, and nothing else in `auth.json` is touched.
83
+
84
+ ## What it touches
85
+
86
+ It never steers an agent or edits your code, but it is not read-only either — besides the hook entry and its own event log, it manages the two tools it leans on, and it refreshes the Codex token it reads quota with, rewriting `~/.codex/auth.json` the way `codex` itself does.
87
+
88
+ What does go out is short and ordinary: a ~20-byte version check against the npm registry (plus one small request to confirm a version it has not seen before), installs and daily version checks for the two tools the deck manages (claude-swap from PyPI, ccusage from npm), and, while the page is open, quota reads to Anthropic and OpenAI signed with your own credentials — that is where those numbers live. `AGENTS_DECK_NO_INSTALL=1` turns off everything but the quota reads; `AGENTS_DECK_NO_DOWNLOAD=1` is the narrower version — no `uv` binary is fetched, the managed installs stay.
89
+
90
+ ## Accounts
91
+
92
+ The Accounts panel reads the store [claude-swap](https://pypi.org/project/claude-swap/) keeps, and can drive it.
93
+
94
+ **`+` → Sign in** runs `claude auth login`, shows you the link, takes the code your browser gives back, and hands the result to `cswap add`. The account you were using **stays active** — signing in replaces the live credentials, so the previous one is switched back the moment the new one is recorded. The code goes straight into the CLI's stdin on this machine; it is never stored, logged, or sent anywhere else.
95
+
96
+ **`share`** on an account produces a `ccdeck1:…` blob to paste into another deck's **`+` → Paste a share**.
97
+
98
+ > [!WARNING]
99
+ > A share carries that account's **live login in the clear** — claude-swap's export format has no encryption. It expires ten minutes after it is made and imports refuse it after that. While it lives, treat it like a password: anything that can read your clipboard can read the account.
100
+
101
+ Renaming, reordering and removing are on the same row menu. Removal takes two clicks and cannot be undone.
102
+
103
+ ## Options
104
+
105
+ ```
106
+ ccdeck [options]
107
+
108
+ -p, --port <number> Preferred port (default: 4317; fallback: random 4318–4400)
109
+ --no-open Don't open the browser automatically
110
+ --workspace <path> Only capture sessions whose cwd is inside <path>
111
+ --scope Restrict to the current working directory
112
+ --all Capture every session on this machine (default)
113
+ --history <path> Override the events log file
114
+ (default: ~/.claude/agent-dag/events.jsonl)
115
+ --no-persist RAM-only mode — don't write or replay the log
116
+ --codex Force Codex capture even if ~/.codex/ is missing
117
+ --no-codex Skip Codex capture (Claude only)
118
+ --claude Force Claude capture even if Claude Code wasn't found
119
+ --no-claude Skip Claude entirely — no hooks, no claude-swap,
120
+ no Accounts panel (Codex only)
121
+ --uninstall Remove ccdeck's hooks from settings files
122
+ -h, --help Show this help
123
+ -v, --version Print the version and exit
124
+ ```
125
+
126
+ Anything else on the command line is reported as an unknown option and then
127
+ ignored — the deck still starts, so a typo costs you a warning rather than a
128
+ dashboard.
129
+
130
+ ccdeck looks for each CLI before it does anything on that CLI's behalf. Claude
131
+ Code counts as present when its binary is on `PATH` (or in one of the places its
132
+ installers put it), or when its config dir carries traces of having been used;
133
+ Codex counts as present when `~/.codex/` exists. On a machine with only one of
134
+ them, the other one's hooks, installs and panels are skipped rather than shown
135
+ empty — the boot banner says which way it went, and `--claude` / `--codex`
136
+ override it if the guess is wrong.
137
+
138
+ `--workspace` is a filter this deck applies to itself, not a claim on the sessions it matches: **every** running deck whose workspace contains a session's directory draws that session, so a machine-wide deck and one scoped to `~/proj` both show the agents working inside `~/proj`. It reads the same way on both capture paths — Claude Code's hook and Codex's rollout files — and the events log still gets exactly one copy of each event, whichever decks are up. A relative path is resolved against the directory you start the deck in, and once, so both paths scope to the same tree.
139
+
140
+ Environment:
141
+
142
+ | Variable | Effect |
143
+ |---|---|
144
+ | `AGENT_DAG_PORT` | Default port, same as `-p` |
145
+ | `CODEX_HOME` | Override `~/.codex` |
146
+ | `AGENTS_DECK_NO_INSTALL=1` | Never install or update claude-swap / ccusage, and never ask npm about releases |
147
+ | `AGENTS_DECK_NO_DOWNLOAD=1` | Never download the `uv` binary, but keep the managed installs |
148
+ | `AGENTS_DECK_NO_UPDATE_CHECK=1` | Don't ask npm about releases, but keep everything else |
149
+ | `AGENTS_DECK_NO_FRESHEN=1` | Never nudge claude-swap to collect usage early |
150
+ | `AGENTS_DECK_CSWAP` | Full path to `cswap`, when it lives somewhere unusual |
151
+ | `AGENTS_DECK_CLAUDE` | Full path to the `claude` CLI |
152
+ | `AGENTS_DECK_CCUSAGE` | Full path to your own `ccusage`, used ahead of everything else |
153
+ | `CLAUDE_SWAP_BACKUP` | Override the claude-swap store root the Accounts panel reads |
154
+
155
+ Usage history is read with `ccusage`, and the deck takes the first of these that answers: `AGENTS_DECK_CCUSAGE` if you set it, then the copy it installed for itself under `~/.agents-deck/ccusage`, then a `ccusage` on your PATH, then `npx -y ccusage@latest`. So installing ccusage yourself is enough — the deck will not fetch a second copy, and it works under `AGENTS_DECK_NO_INSTALL=1`, which is the combination that variable is for. When something fails, the modal names which of those four it was.
156
+
157
+ Being told to restart after an upgrade is local only — no network involved — and cannot be turned off, because a deck running superseded code is a bug you cannot see any other way.
158
+
159
+ ## Uninstall
160
+
161
+ ```bash
162
+ npx ccdeck --uninstall
163
+ ```
164
+
165
+ Removes every hook entry ccdeck injected from `~/.claude/settings.json`, and `~/.codex/hooks.json` if present.
166
+
167
+ It removes the hook entries and nothing else. The forwarder script
168
+ (`~/.claude/agent-dag/hook.js`), the discovery directory around it, the events
169
+ log, and the tools ccdeck installed for you — claude-swap, ccusage, and a `uv`
170
+ binary if it had to fetch one — are all left in place, and each has its own
171
+ uninstaller. Deleting `~/.claude/agent-dag/` and `~/.agents-deck/` clears
172
+ ccdeck's own files; `uv tool uninstall claude-swap` (or `pipx uninstall
173
+ claude-swap`) removes the account switcher.
174
+
175
+ ## Updating
176
+
177
+ The deck checks npm for a newer release at most once an hour, plus once when it starts — a ~20-byte GET to `registry.npmjs.org`, asking about the package this copy would actually install (a deck started with `npx ccdeck` asks about `ccdeck`). When that names a version it has not seen before, one more request confirms the version is really there: npm moves the dist-tag before the version itself has propagated, and a banner shown inside that window ends in `ETARGET` instead of an upgrade. So a check is one request, or two when there is something new to confirm — and a version that is tagged but not yet installable is looked at again in five minutes rather than in an hour. Click the version chip in the topbar to ask immediately.
178
+
179
+ What the banner offers depends on how this copy was installed:
180
+
181
+ | Installed as | Offer |
182
+ |---|---|
183
+ | global npm install | **Update now** — runs `npm install -g` on the name you installed (`ccdeck`, `agents-deck` or `agent-dag`), then restarts once nothing is running |
184
+ | `npx` | **Update & restart** — re-runs the spec through npx, which fetches a fresh copy and takes over the same port |
185
+ | git checkout | the command, because your working copy leads npm: `git pull && npm run build` |
186
+ | directory not writable | the command — a root-owned prefix is declined up front rather than failing inside npm |
187
+ | `AGENTS_DECK_NO_INSTALL=1` | the command only; you asked for no installs |
188
+
189
+ Nothing is ever installed unless you click, the argument vector is fixed in the server rather than taken from the request, and the command is always on screen — button or no button. If npm fails, the banner shows npm's own last line.
190
+
191
+ ### Restarting
192
+
193
+ ccdeck runs as a two-process pair: a supervisor that owns nothing but the lifecycle, and the deck itself. When newer code is found, the deck exits with code 75 and the supervisor brings it back **on the port it actually bound**, which is not always the one it asked for. Ctrl+C, stdout and exit codes behave exactly as before — same terminal, same process group.
194
+
195
+ It restarts on its own only after 30 seconds with nothing running, because hook events are fire-and-forget and anything fired during the gap is lost. The toggle in the banner turns that off; the preference is per-browser. Under `--no-persist` a restart is refused outright — with no event log there is nothing to replay, and the canvas would be gone.
196
+
197
+ ## Design
198
+
199
+ - Node = agent (root session or subagent)
200
+ - Edge = parent → child (spawn), or agent → tool (call)
201
+ - In-flight animates; settled dims
202
+ - Click a node for the full story
203
+
204
+ ## Names
205
+
206
+ **ccdeck** is the name — of this repo and of the command. On npm it goes out
207
+ under three, and `npx` runs the same deck from any of them.
208
+
209
+ ```bash
210
+ npx ccdeck # this repo's name — the short one
211
+ npx agents-deck # the name it shipped under before the rename
212
+ npx agent-dag # the original name; existing installs and scripts keep working
213
+ ```
214
+
215
+ The three are one build published three times, so they behave identically:
216
+ `npx` on any of them fetches a single package, and `npm i -g` on any of them
217
+ puts all three commands on your `PATH`.
218
+
219
+ `ccdeck` was the exception until recently — a thin package that depended on
220
+ `agents-deck` and spawned its binary. It worked, but `npx ccdeck` downloaded two
221
+ packages instead of one and a global `ccdeck` ran under the old package's name.
222
+ It is now the same build as the other two.
26
223
 
27
- ## Links
224
+ The repository was previously named `agents-deck`; the old URL redirects here,
225
+ so existing clones, links and bookmarks keep working.
28
226
 
29
- - Documentation and source — https://github.com/BarganConstantin/ccdeck
30
- - Issues — https://github.com/BarganConstantin/ccdeck/issues
31
- - The package this one forwards to — https://www.npmjs.com/package/agents-deck
227
+ ## License
32
228
 
33
229
  MIT © [Bargan Constantin](https://github.com/BarganConstantin)