agent-dag 1.33.34 → 1.33.36

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.
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <title>agents-deck</title>
7
7
  <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ctext y='84' font-size='84'%3E%E2%97%89%3C/text%3E%3C/svg%3E" />
8
- <script type="module" crossorigin src="/assets/index-w-uUYSqQ.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-m26PmDnF.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/assets/index-Cpi89XJ8.css">
10
10
  </head>
11
11
  <body>
package/hook/hook.js CHANGED
@@ -2,8 +2,8 @@
2
2
  // agent-dag hook forwarder. Invoked by Claude Code or Codex CLI as a command
3
3
  // hook. Reads stdin (event JSON), tags it with the provider passed via
4
4
  // `--provider <name>`, finds the matching agent-dag server via per-workspace
5
- // discovery files in ~/.claude/agent-dag/, and POSTs the payload. Dead
6
- // instances are cleaned up.
5
+ // discovery files in <claude config dir>/agent-dag/, and POSTs the payload.
6
+ // Dead instances are cleaned up.
7
7
  "use strict";
8
8
 
9
9
  const fs = require("fs");
@@ -23,7 +23,16 @@ if (process.env.AGENTS_DECK_INTERNAL === "1") process.exit(0);
23
23
 
24
24
  // Single shared discovery dir — Claude Code and Codex CLI both register here
25
25
  // via the installer. Lets one running agent-dag server receive both providers.
26
- const DIR = path.join(os.homedir(), ".claude", "agent-dag");
26
+ //
27
+ // This has to name the same directory src/server/claude-dir.mjs does, because
28
+ // the installer writes the files read below. It is duplicated rather than
29
+ // imported because this script is copied out of the package and run standalone
30
+ // by the host CLI, with no path back to the module it came from.
31
+ const configOverride = (process.env.CLAUDE_CONFIG_DIR || "").trim();
32
+ const CLAUDE_DIR = configOverride
33
+ ? path.resolve(configOverride)
34
+ : path.join(os.homedir(), ".claude");
35
+ const DIR = path.join(CLAUDE_DIR, "agent-dag");
27
36
 
28
37
  function parseProvider(argv) {
29
38
  for (let i = 0; i < argv.length; i++) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-dag",
3
- "version": "1.33.34",
3
+ "version": "1.33.36",
4
4
  "description": "Live deck of Claude Code and Codex agents — watch parallel subagents fork, call tools, and return on one calm canvas. Also available as npx ccdeck and npx agent-dag.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,22 @@
1
+ // Where Claude Code keeps its configuration — and therefore where the
2
+ // settings.json our hooks have to be registered in actually lives.
3
+ //
4
+ // CLAUDE_CONFIG_DIR relocates that directory wholesale; it is a replacement for
5
+ // ~/.claude, not an overlay, so on a machine where it is set there is nothing in
6
+ // ~/.claude for Claude Code to read. Writing hook entries there is silent
7
+ // failure of the worst kind: the install reports success, no hook ever fires,
8
+ // and the deck stays empty with no error anywhere to explain it.
9
+ //
10
+ // Every module on the Claude side of the install resolves the directory through
11
+ // here, so the deck can never register its hooks in one file while Claude Code
12
+ // reads another. hook/hook.js repeats the rule inline rather than importing it:
13
+ // it is copied out of the package and run standalone by the host CLI, so it has
14
+ // no way back to this module, but it has to resolve the same directory.
15
+ import { homedir } from "node:os";
16
+ import { join, resolve } from "node:path";
17
+
18
+ /** Absolute path of the Claude Code config dir: $CLAUDE_CONFIG_DIR or ~/.claude. */
19
+ export function claudeConfigDir() {
20
+ const override = process.env.CLAUDE_CONFIG_DIR?.trim();
21
+ return override ? resolve(override) : join(homedir(), ".claude");
22
+ }
@@ -8,6 +8,7 @@ import { extname, join, resolve, dirname as pdirname, sep } from "node:path";
8
8
  import { fileURLToPath, pathToFileURL } from "node:url";
9
9
  import { dirname } from "node:path";
10
10
  import { createInterface } from "node:readline";
11
+ import { claudeConfigDir } from "./claude-dir.mjs";
11
12
 
12
13
  const __dirname = dirname(fileURLToPath(import.meta.url));
13
14
  const PKG_ROOT = resolve(__dirname, "..", "..");
@@ -1283,7 +1284,8 @@ function isProcessAlive(pid) {
1283
1284
  }
1284
1285
 
1285
1286
  async function sweepStaleDiscovery() {
1286
- const dir = join(homedir(), ".claude", "agent-dag");
1287
+ // Same directory the installer writes and the hooks read — see claude-dir.mjs.
1288
+ const dir = join(claudeConfigDir(), "agent-dag");
1287
1289
  let files;
1288
1290
  try { files = await readdir(dir); } catch { return 0; }
1289
1291
  let removed = 0;
@@ -1,27 +1,32 @@
1
1
  // Idempotent hook installer. Supports two providers:
2
- // - "claude" → ~/.claude/settings.json (Claude Code)
3
- // - "codex" → ~/.codex/hooks.json (OpenAI Codex CLI)
4
- // Both providers share the discovery dir at ~/.claude/agent-dag/ so a single
5
- // running server can receive events from either CLI. Re-runs are safe; entries
6
- // are tagged with __agent-dag and de-duped.
2
+ // - "claude" → $CLAUDE_CONFIG_DIR/settings.json (Claude Code, ~/.claude by default)
3
+ // - "codex" → $CODEX_HOME/hooks.json (OpenAI Codex CLI, ~/.codex by default)
4
+ // Both providers share the discovery dir at <claude config dir>/agent-dag/ so a
5
+ // single running server can receive events from either CLI. Re-runs are safe;
6
+ // entries are tagged with __agent-dag and de-duped.
7
7
  import { readFile, writeFile, mkdir, copyFile, unlink, rename, open, stat, chmod } from "node:fs/promises";
8
8
  import { existsSync } from "node:fs";
9
9
  import { homedir } from "node:os";
10
10
  import { join, resolve, dirname } from "node:path";
11
11
  import { setTimeout as delay } from "node:timers/promises";
12
12
  import { fileURLToPath } from "node:url";
13
+ import { claudeConfigDir } from "./claude-dir.mjs";
13
14
 
14
15
  const __dirname = dirname(fileURLToPath(import.meta.url));
15
16
  const PKG_ROOT = resolve(__dirname, "..", "..");
16
17
 
17
18
  const HOME = homedir();
18
- const CLAUDE_DIR = join(HOME, ".claude");
19
+ // Honours CLAUDE_CONFIG_DIR, exactly as CODEX_DIR honours CODEX_HOME below.
20
+ // Without it the hooks land in a settings.json Claude Code never opens.
21
+ const CLAUDE_DIR = claudeConfigDir();
19
22
  const CODEX_DIR = process.env.CODEX_HOME
20
23
  ? resolve(process.env.CODEX_HOME)
21
24
  : join(HOME, ".codex");
22
25
 
23
26
  // Single shared discovery dir — both providers' hook scripts post here so one
24
- // running agent-dag server can match either ecosystem's events.
27
+ // running agent-dag server can match either ecosystem's events. It follows the
28
+ // Claude config dir, so hook/hook.js has to resolve that dir the same way: it
29
+ // reads what this writes, and a disagreement means the hooks find no server.
25
30
  const AGENT_DAG_DIR = join(CLAUDE_DIR, "agent-dag");
26
31
 
27
32
  const CLAUDE_EVENTS = [
@@ -15,10 +15,11 @@ import { existsSync } from "node:fs";
15
15
  import { join, dirname } from "node:path";
16
16
  import { homedir } from "node:os";
17
17
  import { fileURLToPath } from "node:url";
18
+ import { claudeConfigDir } from "./claude-dir.mjs";
18
19
  import { readSettingsForWrite, writeFileAtomic } from "./installer.mjs";
19
20
 
20
21
  const PKG_ROOT = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
21
- const CLAUDE_DIR = process.env.CLAUDE_CONFIG_DIR ?? join(homedir(), ".claude");
22
+ const CLAUDE_DIR = claudeConfigDir();
22
23
  const SETTINGS_PATH = join(CLAUDE_DIR, "settings.json");
23
24
  const INSTALL_DIR = join(CLAUDE_DIR, "agent-dag");
24
25
  const NOTIFY_PATH = join(INSTALL_DIR, "notify.js");