@galda/cli 0.10.16 → 0.10.19

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,7 @@ import { existsSync } from 'node:fs';
11
11
  import { join, resolve, dirname } from 'node:path';
12
12
  import { fileURLToPath, pathToFileURL } from 'node:url';
13
13
  import { createServer } from 'node:net';
14
+ import { isCommandOnPath, resolveConnectedAgents } from '../engine/lib.mjs';
14
15
 
15
16
  const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
16
17
  const say = (m) => console.log(`[galda] ${m}`);
@@ -36,21 +37,26 @@ async function pickPort(start) {
36
37
  const WIN = process.platform === 'win32';
37
38
  const probe = (cmd, args) => spawnSync(cmd, args, { encoding: 'utf8', shell: WIN });
38
39
 
39
- // 1) claude CLI (the enginerequired)
40
+ // 1) Worker agent CLIs. Galda drives whichever you have Claude Code OR Codex;
41
+ // at least one is required. Claude Code is safe to run for detection (notarized),
42
+ // so we probe it for a version string. Codex is detected by a PATH lookup ONLY —
43
+ // never executed — because running the codex binary can trip macOS XProtect (a
44
+ // false positive that looks like Galda shipped malware). Galda never installs or
45
+ // downloads either; it only offers what's already on the machine.
40
46
  const claude = probe('claude', ['--version']);
41
- if (claude.error || claude.status !== 0) {
42
- say('ERROR: the `claude` CLI was not found.');
43
- say('Galda runs on your Claude Code subscription (no extra API cost).');
44
- say('Install it first: https://claude.com/claude-codethen log in with `claude`.');
47
+ const hasClaude = !claude.error && claude.status === 0;
48
+ const hasCodex = isCommandOnPath('codex', { pathEnv: process.env.PATH || '', sep: WIN ? ';' : ':', pathExt: WIN ? (process.env.PATHEXT || '') : '' });
49
+ if (!hasClaude && !hasCodex) {
50
+ say('ERROR: no agent CLI found Galda needs Claude Code or Codex on this machine.');
51
+ say('Install Claude Code (https://claude.com/claude-code — runs on your subscription, no extra API cost)');
52
+ say('or Codex, then run `npx @galda/cli` again.');
45
53
  process.exit(1);
46
54
  }
47
- say(`claude CLI: ${claude.stdout.trim()}`);
48
-
49
- // 1b) codex CLI (optional alternate worker). Informational only so Codex users
50
- // see it's detected and supported, not just Claude Code. Galda can run workers on
51
- // either; you pick per task (Claude Code / Codex) in the board's composer.
52
- const codex = probe('codex', ['--version']);
53
- if (!codex.error && codex.status === 0) say(`codex CLI: ${codex.stdout.trim()} (Codex)`);
55
+ if (hasClaude) say(`claude CLI: ${claude.stdout.trim()}`);
56
+ if (hasCodex) say('codex CLI: detected (Codex)');
57
+ // Hand the detected set to the server so the board only offers installed agents.
58
+ const availableAgents = resolveConnectedAgents({ claude: hasClaude, codex: hasCodex });
59
+ process.env.MANAGER_AVAILABLE_AGENTS = availableAgents.join(',');
54
60
 
55
61
  // 2) Chrome (for verification proof) — recommended; warn if missing
56
62
  const chromeCandidates = [