agent-dag 1.0.0 → 1.0.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,14 +1,27 @@
1
- # ccgraph
1
+ # agent-dag
2
2
 
3
3
  Live DAG of Claude Code agents. Watch parallel subagents fork, call tools, and return — all on one calm canvas.
4
4
 
5
5
  ## Run
6
6
 
7
7
  ```bash
8
- npx ccgraph
8
+ npx agent-dag
9
9
  ```
10
10
 
11
- Opens http://127.0.0.1:4317. Start a Claude Code session in any directory and watch the graph fill in.
11
+ Opens http://127.0.0.1:4317 (or a random port in 4318–4400 if 4317 is taken). Start a Claude Code session in any directory and watch the graph fill in.
12
+
13
+ ## Options
14
+
15
+ ```
16
+ -p, --port <number> Preferred port (default: 4317; falls back to random 4318–4400)
17
+ --no-open Don't open the browser automatically
18
+ --workspace <path> Workspace root to filter events (default: cwd)
19
+ --all Capture sessions from all workspaces (machine-wide)
20
+ --history <path> Override events log file (default: ~/.claude/ccgraph/events.jsonl)
21
+ --no-persist RAM-only mode, no log file
22
+ --uninstall Remove agent-dag hooks from ~/.claude/settings.json
23
+ -h, --help Show help
24
+ ```
12
25
 
13
26
  ## Design
14
27
 
@@ -20,11 +33,19 @@ Opens http://127.0.0.1:4317. Start a Claude Code session in any directory and wa
20
33
 
21
34
  ## How it works
22
35
 
23
- `ccgraph` registers a hook script in `~/.claude/settings.json` for these Claude Code events:
36
+ `agent-dag` registers a hook script in `~/.claude/settings.json` for these Claude Code events:
24
37
 
25
38
  `SessionStart`, `UserPromptSubmit`, `PreToolUse`, `PostToolUse`, `SubagentStart`, `SubagentStop`, `Stop`, `SessionEnd`, `Notification`.
26
39
 
27
- The hook forwards the event JSON to the running `ccgraph` server, which streams it to the browser via SSE.
40
+ The hook forwards the event JSON to the running server, which streams it to the browser via SSE.
41
+
42
+ ## Uninstall
43
+
44
+ ```bash
45
+ npx agent-dag --uninstall
46
+ ```
47
+
48
+ Removes all hooks from `~/.claude/settings.json`.
28
49
 
29
50
  ## Status
30
51
 
package/bin/ccgraph.js CHANGED
@@ -41,7 +41,7 @@ if (!existsSync(WEB_DIST)) {
41
41
  process.exit(1);
42
42
  }
43
43
 
44
- console.log("ccgraph");
44
+ console.log("agent-dag");
45
45
  console.log(" workspace:", workspace === "" ? "(all)" : workspace);
46
46
 
47
47
  const { settingsPath, hookPath, events } = await installHooks();
@@ -50,11 +50,7 @@ console.log(" events:", events.join(", "));
50
50
  console.log(" settings:", settingsPath);
51
51
 
52
52
  const server = await startServer({ port, persist }).catch(err => {
53
- if (err && err.code === "EADDRINUSE") {
54
- console.error(`\nccgraph: port ${port} in use. Try --port <N>.`);
55
- } else {
56
- console.error("ccgraph: server failed:", err.message);
57
- }
53
+ console.error("ccgraph: server failed:", err.message);
58
54
  process.exit(1);
59
55
  });
60
56
 
@@ -103,19 +99,19 @@ function parseArgs(args) {
103
99
  }
104
100
 
105
101
  function printHelp() {
106
- process.stdout.write(`ccgraph — live DAG of Claude Code agents
102
+ process.stdout.write(`agent-dag — live DAG of Claude Code agents
107
103
 
108
104
  Usage:
109
- ccgraph [options]
105
+ agent-dag [options]
110
106
 
111
107
  Options:
112
- -p, --port <number> Port for the server (default: 4317)
108
+ -p, --port <number> Preferred port (default: 4317; falls back to random 4318–4400)
113
109
  --no-open Don't open the browser automatically
114
110
  --workspace <path> Workspace root (default: cwd)
115
111
  --all Capture sessions from ALL workspaces (machine-wide)
116
112
  --history <path> Override events log file (default: ~/.claude/ccgraph/events.jsonl)
117
113
  --no-persist Don't write or replay events log (RAM-only)
118
- --uninstall Remove ccgraph hook entries from ~/.claude/settings.json
114
+ --uninstall Remove agent-dag hook entries from ~/.claude/settings.json
119
115
  -h, --help Show this help
120
116
  `);
121
117
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-dag",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Live DAG of Claude Code agents — watch parallel subagents fork, call tools, and return on one calm canvas.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -191,7 +191,21 @@ async function sweepStaleDiscovery() {
191
191
  return removed;
192
192
  }
193
193
 
194
- export async function startServer({ port = 4317, host = "127.0.0.1", persist = null } = {}) {
194
+ function randomPort(min, max) {
195
+ return Math.floor(Math.random() * (max - min + 1)) + min;
196
+ }
197
+
198
+ async function tryListen(server, port, host) {
199
+ return new Promise((res, rej) => {
200
+ server.once("error", rej);
201
+ server.listen(port, host, () => {
202
+ server.removeListener("error", rej);
203
+ res();
204
+ });
205
+ });
206
+ }
207
+
208
+ export async function startServer({ port = 4317, host = "127.0.0.1", persist = null, portRange = [4318, 4400] } = {}) {
195
209
  const removed = await sweepStaleDiscovery();
196
210
  if (removed > 0) console.log(` swept ${removed} stale discovery file(s)`);
197
211
  if (persist) {
@@ -227,13 +241,20 @@ export async function startServer({ port = 4317, host = "127.0.0.1", persist = n
227
241
  send(res, 405, { error: "method not allowed" });
228
242
  });
229
243
 
230
- return new Promise((resolveStart, rejectStart) => {
231
- server.once("error", rejectStart);
232
- server.listen(port, host, () => {
233
- server.removeListener("error", rejectStart);
234
- resolveStart(server);
235
- });
236
- });
244
+ // Try requested port first, then up to 10 random ports from portRange.
245
+ const candidates = [port];
246
+ for (let i = 0; i < 10; i++) candidates.push(randomPort(portRange[0], portRange[1]));
247
+
248
+ for (const candidate of candidates) {
249
+ try {
250
+ await tryListen(server, candidate, host);
251
+ return server;
252
+ } catch (err) {
253
+ if (err && err.code === "EADDRINUSE") continue;
254
+ throw err;
255
+ }
256
+ }
257
+ throw Object.assign(new Error(`all ports tried — none available`), { code: "EADDRINUSE" });
237
258
  }
238
259
 
239
260
  // Allow running this file directly for dev.