claudeboard 2.0.0 → 2.2.0

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.
@@ -11,6 +11,66 @@
11
11
 
12
12
  import { query } from "@anthropic-ai/claude-agent-sdk";
13
13
  import { startTask, completeTask, failTask, addLog } from "./board-client.js";
14
+ import { execSync } from "child_process";
15
+
16
+ // Resolve the global `claude` binary path at startup
17
+ function resolveClaudePath() {
18
+ // 1. Explicit override via env var
19
+ if (process.env.CLAUDE_CODE_PATH) return process.env.CLAUDE_CODE_PATH;
20
+
21
+ // 2. Ask the shell where `claude` lives (works after: npm install -g @anthropic-ai/claude-code)
22
+ try {
23
+ return execSync("which claude", { stdio: "pipe" }).toString().trim();
24
+ } catch {}
25
+
26
+ // 3. Common Homebrew / nvm / fnm paths
27
+ const candidates = [
28
+ "/opt/homebrew/bin/claude",
29
+ "/usr/local/bin/claude",
30
+ `${process.env.HOME}/.nvm/versions/node/current/bin/claude`,
31
+ `${process.env.HOME}/.npm-global/bin/claude`,
32
+ ];
33
+ for (const p of candidates) {
34
+ try { execSync(`test -f "${p}"`, { stdio: "pipe" }); return p; } catch {}
35
+ }
36
+
37
+ return null; // will surface as CLINotFoundError
38
+ }
39
+
40
+ const CLAUDE_PATH = resolveClaudePath();
41
+
42
+ // Build a full PATH for the Claude Code subprocess
43
+ // Exit code 127 = "command not found" inside the subprocess — node/npm not in PATH
44
+ function buildEnv() {// Exit code 127 = "command not found" inside the subprocess — node/npm not in PATH
45
+ function buildEnv() {
46
+ // Get node/npm directory to ensure they're in PATH
47
+ let nodeBinDir = "";
48
+ try {
49
+ nodeBinDir = execSync("dirname $(which node)", { stdio: "pipe" }).toString().trim();
50
+ } catch {}
51
+
52
+ // Merge: existing PATH + node bin dir + common locations
53
+ const pathParts = [
54
+ process.env.PATH || "",
55
+ nodeBinDir,
56
+ "/opt/homebrew/bin",
57
+ "/opt/homebrew/sbin",
58
+ "/usr/local/bin",
59
+ "/usr/bin",
60
+ "/bin",
61
+ `${process.env.HOME}/.npm-global/bin`,
62
+ `${process.env.HOME}/.nvm/versions/node/current/bin`,
63
+ ].filter(Boolean);
64
+
65
+ const fullPath = [...new Set(pathParts.join(":").split(":"))].join(":");
66
+
67
+ return {
68
+ ...process.env,
69
+ PATH: fullPath,
70
+ ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
71
+ HOME: process.env.HOME,
72
+ };
73
+ }
14
74
 
15
75
  // Tools Claude Code can use — full developer access
16
76
  const DEVELOPER_TOOLS = [
@@ -41,6 +101,15 @@ RULES:
41
101
 
42
102
  export async function runDeveloperAgent(task, projectPath, techStack, retryContext = null) {
43
103
  console.log(` 🤖 Claude Code working on: ${task.title}`);
104
+ if (CLAUDE_PATH) {
105
+ console.log(` CLI: ${CLAUDE_PATH}`);
106
+ } else {
107
+ const hint = "Claude Code CLI not found. Run: npm install -g @anthropic-ai/claude-code";
108
+ await startTask(task.id, hint);
109
+ await failTask(task.id, hint);
110
+ console.error(`\n ✗ ${hint}\n`);
111
+ return { success: false, error: hint };
112
+ }
44
113
  await startTask(task.id, `Claude Code starting: ${task.title}`);
45
114
 
46
115
  const retryNote = retryContext
@@ -80,14 +149,13 @@ ${retryNote}
80
149
  permissionMode: "bypassPermissions",
81
150
  allowedTools: DEVELOPER_TOOLS,
82
151
  maxTurns: 80,
152
+ ...(CLAUDE_PATH ? { pathToClaudeCodeExecutable: CLAUDE_PATH } : {}),
83
153
  systemPrompt: {
84
154
  type: "preset",
85
155
  preset: "claude_code",
86
156
  append: DEV_RULES,
87
157
  },
88
- env: {
89
- ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
90
- },
158
+ env: buildEnv(),
91
159
  },
92
160
  })) {
93
161
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudeboard",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "description": "AI engineering team — from PRD to working mobile app, autonomously",
5
5
  "type": "module",
6
6
  "bin": {