@yemi33/minions 0.1.200 → 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 +1 -1
- package/engine/spawn-agent.js +50 -58
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/engine/spawn-agent.js
CHANGED
|
@@ -22,64 +22,55 @@ 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
|
+
let claudeIsNative = false; // true = native binary, false = node cli.js
|
|
27
28
|
|
|
28
|
-
// Strategy 1:
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
path.join(path.dirname(process.execPath), 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js'),
|
|
44
|
-
// Local node_modules (if minions is in a project)
|
|
45
|
-
path.join(__dirname, '..', 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js'),
|
|
46
|
-
].filter(Boolean);
|
|
47
|
-
for (const p of searchPaths) {
|
|
48
|
-
try { if (fs.existsSync(p)) { claudeBin = p; break; } } catch {}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Strategy 2: Use `which` (Unix) or `where` (Windows) to find the claude wrapper, then resolve cli.js
|
|
52
|
-
if (!claudeBin) {
|
|
53
|
-
try {
|
|
54
|
-
const isWin = process.platform === 'win32';
|
|
55
|
-
const cmd = isWin ? 'where claude 2>NUL' : 'which claude 2>/dev/null';
|
|
56
|
-
const which = exec(cmd, { encoding: 'utf8', env, timeout: 10000 }).trim().split('\n')[0].trim();
|
|
57
|
-
if (which) {
|
|
58
|
-
const whichNative = isWin ? which : which.replace(/^\/([a-zA-Z])\//, (_, d) => d.toUpperCase() + ':/').replace(/\//g, path.sep);
|
|
59
|
-
// The wrapper script or symlink — resolve to cli.js
|
|
60
|
-
try {
|
|
61
|
-
const resolved = fs.realpathSync(whichNative);
|
|
62
|
-
if (resolved.endsWith('cli.js')) {
|
|
63
|
-
claudeBin = resolved;
|
|
64
|
-
} else {
|
|
65
|
-
// Read wrapper script to extract cli.js path
|
|
66
|
-
const wrapper = fs.readFileSync(resolved, 'utf8');
|
|
67
|
-
const m = wrapper.match(/node_modules[\\/]@anthropic-ai[\\/]claude-code[\\/]cli\.js/);
|
|
68
|
-
if (m) claudeBin = path.join(path.dirname(resolved), 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js');
|
|
69
|
-
}
|
|
70
|
-
} catch {
|
|
71
|
-
// Try reading the wrapper directly (may be a batch file on Windows)
|
|
72
|
-
try {
|
|
73
|
-
const wrapper = fs.readFileSync(whichNative, 'utf8');
|
|
74
|
-
const m = wrapper.match(/node_modules[\\/]@anthropic-ai[\\/]claude-code[\\/]cli\.js/);
|
|
75
|
-
if (m) claudeBin = path.join(path.dirname(whichNative), 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js');
|
|
76
|
-
} catch {}
|
|
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; }
|
|
77
44
|
}
|
|
45
|
+
} catch {
|
|
46
|
+
// Can't read as text — it's a compiled binary
|
|
78
47
|
}
|
|
79
|
-
|
|
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
|
+
}
|
|
80
71
|
}
|
|
81
72
|
|
|
82
|
-
// Strategy 3: npm root -g
|
|
73
|
+
// Strategy 3: npm root -g
|
|
83
74
|
if (!claudeBin) {
|
|
84
75
|
try {
|
|
85
76
|
const globalRoot = exec('npm root -g', { encoding: 'utf8', env, timeout: 10000 }).trim();
|
|
@@ -92,7 +83,7 @@ if (!claudeBin) {
|
|
|
92
83
|
const tmpDir = path.join(__dirname, 'tmp');
|
|
93
84
|
if (!fs.existsSync(tmpDir)) fs.mkdirSync(tmpDir, { recursive: true });
|
|
94
85
|
const debugPath = path.join(tmpDir, 'spawn-debug.log');
|
|
95
|
-
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`);
|
|
96
87
|
|
|
97
88
|
// When resuming a session, skip system prompt (it's baked into the session)
|
|
98
89
|
const isResume = extraArgs.includes('--resume');
|
|
@@ -124,7 +115,9 @@ try {
|
|
|
124
115
|
if (_sysPromptFileSupported === null) {
|
|
125
116
|
try {
|
|
126
117
|
const { spawnSync } = require('child_process');
|
|
127
|
-
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 });
|
|
128
121
|
_sysPromptFileSupported = (testResult.stdout || '').includes('system-prompt-file');
|
|
129
122
|
try { fs.writeFileSync(capsCachePath, JSON.stringify({ claudeBin, sysPromptFile: _sysPromptFileSupported, checkedAt: new Date().toISOString() })); } catch { /* optional */ }
|
|
130
123
|
} catch { _sysPromptFileSupported = true; /* assume supported */ }
|
|
@@ -150,10 +143,9 @@ if (!isResume) try {
|
|
|
150
143
|
// If help check fails, try file approach anyway
|
|
151
144
|
}
|
|
152
145
|
|
|
153
|
-
const proc =
|
|
154
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
155
|
-
env
|
|
156
|
-
});
|
|
146
|
+
const proc = claudeIsNative
|
|
147
|
+
? runFile(claudeBin, actualArgs, { stdio: ['pipe', 'pipe', 'pipe'], env })
|
|
148
|
+
: runFile(process.execPath, [claudeBin, ...actualArgs], { stdio: ['pipe', 'pipe', 'pipe'], env });
|
|
157
149
|
|
|
158
150
|
fs.appendFileSync(debugPath, `PID=${proc.pid || 'none'}\nargs=${actualArgs.join(' ').slice(0, 500)}\n`);
|
|
159
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"
|