@yemi33/minions 0.1.199 → 0.1.201
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/CHANGELOG.md +3 -1
- package/engine/preflight.js +37 -13
- package/engine/spawn-agent.js +57 -26
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.201 (2026-04-02)
|
|
4
4
|
|
|
5
5
|
### Engine
|
|
6
6
|
- engine/ado.js
|
|
7
7
|
- engine/github.js
|
|
8
8
|
- engine/lifecycle.js
|
|
9
|
+
- engine/preflight.js
|
|
9
10
|
- engine/queries.js
|
|
10
11
|
- engine/shared.js
|
|
12
|
+
- engine/spawn-agent.js
|
|
11
13
|
|
|
12
14
|
### Dashboard
|
|
13
15
|
- dashboard.js
|
package/engine/preflight.js
CHANGED
|
@@ -14,26 +14,50 @@ const { execSync } = require('child_process');
|
|
|
14
14
|
*/
|
|
15
15
|
function findClaudeBinary() {
|
|
16
16
|
const searchPaths = [
|
|
17
|
-
|
|
18
|
-
path.join(process.env.
|
|
17
|
+
// npm global (npm_config_prefix)
|
|
18
|
+
process.env.npm_config_prefix ? path.join(process.env.npm_config_prefix, 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js') : '',
|
|
19
|
+
// Windows: %APPDATA%\npm
|
|
20
|
+
process.env.APPDATA ? path.join(process.env.APPDATA, 'npm', 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js') : '',
|
|
21
|
+
// Unix global
|
|
19
22
|
'/usr/local/lib/node_modules/@anthropic-ai/claude-code/cli.js',
|
|
20
23
|
'/usr/lib/node_modules/@anthropic-ai/claude-code/cli.js',
|
|
21
|
-
|
|
24
|
+
// Homebrew (macOS)
|
|
25
|
+
'/opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/cli.js',
|
|
26
|
+
// nvm (current node version)
|
|
27
|
+
path.join(path.dirname(process.execPath), '..', 'lib', 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js'),
|
|
28
|
+
// fnm / volta — sibling to the node binary
|
|
29
|
+
path.join(path.dirname(process.execPath), 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js'),
|
|
30
|
+
].filter(Boolean);
|
|
22
31
|
for (const p of searchPaths) {
|
|
23
|
-
if (
|
|
32
|
+
try { if (fs.existsSync(p)) return p; } catch {}
|
|
24
33
|
}
|
|
25
|
-
// Fallback:
|
|
34
|
+
// Fallback: which/where → resolve wrapper to cli.js
|
|
26
35
|
try {
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
const isWin = process.platform === 'win32';
|
|
37
|
+
const cmd = isWin ? 'where claude 2>NUL' : 'which claude 2>/dev/null';
|
|
38
|
+
const which = execSync(cmd, { encoding: 'utf8', windowsHide: true, timeout: 5000 }).trim().split('\n')[0].trim();
|
|
39
|
+
if (which) {
|
|
40
|
+
const whichNative = isWin ? which : which.replace(/^\/([a-zA-Z])\//, (_, d) => d.toUpperCase() + ':/').replace(/\//g, path.sep);
|
|
41
|
+
try {
|
|
42
|
+
const resolved = fs.realpathSync(whichNative);
|
|
43
|
+
if (resolved.endsWith('cli.js') && fs.existsSync(resolved)) return resolved;
|
|
44
|
+
} catch {}
|
|
45
|
+
try {
|
|
46
|
+
const wrapper = fs.readFileSync(whichNative, 'utf8');
|
|
47
|
+
const m = wrapper.match(/node_modules[\\/]@anthropic-ai[\\/]claude-code[\\/]cli\.js/);
|
|
48
|
+
if (m) {
|
|
49
|
+
const candidate = path.join(path.dirname(whichNative), 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js');
|
|
50
|
+
if (fs.existsSync(candidate)) return candidate;
|
|
51
|
+
}
|
|
52
|
+
} catch {}
|
|
35
53
|
}
|
|
36
54
|
} catch { /* optional */ }
|
|
55
|
+
// Last resort: npm root -g
|
|
56
|
+
try {
|
|
57
|
+
const globalRoot = execSync('npm root -g', { encoding: 'utf8', windowsHide: true, timeout: 5000 }).trim();
|
|
58
|
+
const candidate = path.join(globalRoot, '@anthropic-ai', 'claude-code', 'cli.js');
|
|
59
|
+
if (fs.existsSync(candidate)) return candidate;
|
|
60
|
+
} catch { /* optional */ }
|
|
37
61
|
return null;
|
|
38
62
|
}
|
|
39
63
|
|
package/engine/spawn-agent.js
CHANGED
|
@@ -22,30 +22,60 @@ const sysPrompt = fs.readFileSync(sysPromptFile, 'utf8');
|
|
|
22
22
|
|
|
23
23
|
const env = cleanChildEnv();
|
|
24
24
|
|
|
25
|
-
// Resolve claude binary —
|
|
25
|
+
// Resolve claude binary — supports both npm install (cli.js) and native installer (binary on PATH)
|
|
26
26
|
let claudeBin;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
'
|
|
33
|
-
'
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
27
|
+
let claudeIsNative = false; // true = native binary, false = node cli.js
|
|
28
|
+
|
|
29
|
+
// Strategy 1: Check if `claude` is on PATH (native installer or npm global bin)
|
|
30
|
+
try {
|
|
31
|
+
const isWin = process.platform === 'win32';
|
|
32
|
+
const cmd = isWin ? 'where claude 2>NUL' : 'which claude 2>/dev/null';
|
|
33
|
+
const which = exec(cmd, { encoding: 'utf8', env, timeout: 10000 }).trim().split('\n')[0].trim();
|
|
34
|
+
if (which) {
|
|
35
|
+
const whichNative = isWin ? which : which.replace(/^\/([a-zA-Z])\//, (_, d) => d.toUpperCase() + ':/').replace(/\//g, path.sep);
|
|
36
|
+
// Check if it's a node wrapper (npm install) or native binary
|
|
37
|
+
try {
|
|
38
|
+
const content = fs.readFileSync(whichNative, 'utf8');
|
|
39
|
+
// npm wrapper scripts reference cli.js — extract the path
|
|
40
|
+
const m = content.match(/node_modules[\\/]@anthropic-ai[\\/]claude-code[\\/]cli\.js/);
|
|
41
|
+
if (m) {
|
|
42
|
+
const candidate = path.join(path.dirname(whichNative), 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js');
|
|
43
|
+
if (fs.existsSync(candidate)) { claudeBin = candidate; }
|
|
44
|
+
}
|
|
45
|
+
} catch {
|
|
46
|
+
// Can't read as text — it's a compiled binary
|
|
47
|
+
}
|
|
48
|
+
if (!claudeBin) {
|
|
49
|
+
// Native binary or wrapper without cli.js reference — use directly
|
|
50
|
+
claudeBin = whichNative;
|
|
51
|
+
claudeIsNative = true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
} catch { /* optional */ }
|
|
55
|
+
|
|
56
|
+
// Strategy 2: Known node_modules locations (npm global installs)
|
|
57
|
+
if (!claudeBin) {
|
|
58
|
+
const searchPaths = [
|
|
59
|
+
process.env.npm_config_prefix ? path.join(process.env.npm_config_prefix, 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js') : '',
|
|
60
|
+
process.env.APPDATA ? path.join(process.env.APPDATA, 'npm', 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js') : '',
|
|
61
|
+
'/usr/local/lib/node_modules/@anthropic-ai/claude-code/cli.js',
|
|
62
|
+
'/usr/lib/node_modules/@anthropic-ai/claude-code/cli.js',
|
|
63
|
+
'/opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/cli.js',
|
|
64
|
+
path.join(path.dirname(process.execPath), '..', 'lib', 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js'),
|
|
65
|
+
path.join(path.dirname(process.execPath), 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js'),
|
|
66
|
+
path.join(__dirname, '..', 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js'),
|
|
67
|
+
].filter(Boolean);
|
|
68
|
+
for (const p of searchPaths) {
|
|
69
|
+
try { if (fs.existsSync(p)) { claudeBin = p; break; } } catch {}
|
|
70
|
+
}
|
|
37
71
|
}
|
|
38
|
-
|
|
72
|
+
|
|
73
|
+
// Strategy 3: npm root -g
|
|
39
74
|
if (!claudeBin) {
|
|
40
75
|
try {
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
const m = wrapper.match(/node_modules\/@anthropic-ai\/claude-code\/cli\.js/);
|
|
45
|
-
if (m) {
|
|
46
|
-
const basedir = path.dirname(whichNative);
|
|
47
|
-
claudeBin = path.join(basedir, 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js');
|
|
48
|
-
}
|
|
76
|
+
const globalRoot = exec('npm root -g', { encoding: 'utf8', env, timeout: 10000 }).trim();
|
|
77
|
+
const candidate = path.join(globalRoot, '@anthropic-ai', 'claude-code', 'cli.js');
|
|
78
|
+
if (fs.existsSync(candidate)) claudeBin = candidate;
|
|
49
79
|
} catch { /* optional */ }
|
|
50
80
|
}
|
|
51
81
|
|
|
@@ -53,7 +83,7 @@ if (!claudeBin) {
|
|
|
53
83
|
const tmpDir = path.join(__dirname, 'tmp');
|
|
54
84
|
if (!fs.existsSync(tmpDir)) fs.mkdirSync(tmpDir, { recursive: true });
|
|
55
85
|
const debugPath = path.join(tmpDir, 'spawn-debug.log');
|
|
56
|
-
fs.writeFileSync(debugPath, `spawn-agent.js at ${new Date().toISOString()}\nclaudeBin=${claudeBin || 'not found'}\nprompt=${promptFile}\nsysPrompt=${sysPromptFile}\nextraArgs=${extraArgs.join(' ')}\n`);
|
|
86
|
+
fs.writeFileSync(debugPath, `spawn-agent.js at ${new Date().toISOString()}\nclaudeBin=${claudeBin || 'not found'}\nnative=${claudeIsNative}\nprompt=${promptFile}\nsysPrompt=${sysPromptFile}\nextraArgs=${extraArgs.join(' ')}\n`);
|
|
57
87
|
|
|
58
88
|
// When resuming a session, skip system prompt (it's baked into the session)
|
|
59
89
|
const isResume = extraArgs.includes('--resume');
|
|
@@ -85,7 +115,9 @@ try {
|
|
|
85
115
|
if (_sysPromptFileSupported === null) {
|
|
86
116
|
try {
|
|
87
117
|
const { spawnSync } = require('child_process');
|
|
88
|
-
const testResult =
|
|
118
|
+
const testResult = claudeIsNative
|
|
119
|
+
? spawnSync(claudeBin, ['--help'], { encoding: 'utf8', timeout: 10000, windowsHide: true })
|
|
120
|
+
: spawnSync(process.execPath, [claudeBin, '--help'], { encoding: 'utf8', timeout: 10000, windowsHide: true });
|
|
89
121
|
_sysPromptFileSupported = (testResult.stdout || '').includes('system-prompt-file');
|
|
90
122
|
try { fs.writeFileSync(capsCachePath, JSON.stringify({ claudeBin, sysPromptFile: _sysPromptFileSupported, checkedAt: new Date().toISOString() })); } catch { /* optional */ }
|
|
91
123
|
} catch { _sysPromptFileSupported = true; /* assume supported */ }
|
|
@@ -111,10 +143,9 @@ if (!isResume) try {
|
|
|
111
143
|
// If help check fails, try file approach anyway
|
|
112
144
|
}
|
|
113
145
|
|
|
114
|
-
const proc =
|
|
115
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
116
|
-
env
|
|
117
|
-
});
|
|
146
|
+
const proc = claudeIsNative
|
|
147
|
+
? runFile(claudeBin, actualArgs, { stdio: ['pipe', 'pipe', 'pipe'], env })
|
|
148
|
+
: runFile(process.execPath, [claudeBin, ...actualArgs], { stdio: ['pipe', 'pipe', 'pipe'], env });
|
|
118
149
|
|
|
119
150
|
fs.appendFileSync(debugPath, `PID=${proc.pid || 'none'}\nargs=${actualArgs.join(' ').slice(0, 500)}\n`);
|
|
120
151
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.201",
|
|
4
4
|
"description": "Multi-agent AI dev team that runs from ~/.minions/ — five autonomous agents share a single engine, dashboard, and knowledge base",
|
|
5
5
|
"bin": {
|
|
6
6
|
"minions": "bin/minions.js"
|