@yemi33/minions 0.1.564 → 0.1.565
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 +4 -1
- package/engine/spawn-agent.js +19 -12
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.565 (2026-04-08)
|
|
4
4
|
|
|
5
5
|
### Fixes
|
|
6
6
|
- worktree audit followups — delete ordering, path traversal guard
|
|
7
7
|
- worktree lifecycle — fail on dep merge, fallback rm, cleanup on plan delete
|
|
8
8
|
- auto-reset CC session on resume failure, add error logging
|
|
9
9
|
|
|
10
|
+
### Other
|
|
11
|
+
- perf: cache claude binary path across spawns in spawn-agent.js
|
|
12
|
+
|
|
10
13
|
## 0.1.561 (2026-04-08)
|
|
11
14
|
|
|
12
15
|
### Fixes
|
package/engine/spawn-agent.js
CHANGED
|
@@ -25,9 +25,21 @@ const env = cleanChildEnv();
|
|
|
25
25
|
// Resolve claude binary — supports both npm install (cli.js) and native installer (binary on PATH)
|
|
26
26
|
let claudeBin;
|
|
27
27
|
let claudeIsNative = false; // true = native binary, false = node cli.js
|
|
28
|
+
const capsCachePath = path.join(__dirname, 'claude-caps.json');
|
|
29
|
+
let _sysPromptFileSupported = null;
|
|
28
30
|
|
|
29
|
-
//
|
|
31
|
+
// Fast path: use cached binary path if it still exists on disk
|
|
30
32
|
try {
|
|
33
|
+
const caps = JSON.parse(fs.readFileSync(capsCachePath, 'utf8'));
|
|
34
|
+
if (caps.claudeBin && fs.existsSync(caps.claudeBin)) {
|
|
35
|
+
claudeBin = caps.claudeBin;
|
|
36
|
+
claudeIsNative = !!caps.claudeIsNative;
|
|
37
|
+
_sysPromptFileSupported = caps.sysPromptFile ?? null;
|
|
38
|
+
}
|
|
39
|
+
} catch {}
|
|
40
|
+
|
|
41
|
+
// Strategy 1: Check if `claude` is on PATH (native installer or npm global bin)
|
|
42
|
+
if (!claudeBin) try {
|
|
31
43
|
const isWin = process.platform === 'win32';
|
|
32
44
|
const cmd = isWin ? 'where claude 2>NUL' : 'which claude 2>/dev/null';
|
|
33
45
|
const which = exec(cmd, { encoding: 'utf8', env, timeout: 10000 }).trim().split('\n')[0].trim();
|
|
@@ -79,11 +91,11 @@ if (!claudeBin) {
|
|
|
79
91
|
} catch { /* optional */ }
|
|
80
92
|
}
|
|
81
93
|
|
|
82
|
-
// Debug log
|
|
94
|
+
// Debug log (async — not on critical path)
|
|
83
95
|
const tmpDir = path.join(__dirname, 'tmp');
|
|
84
96
|
if (!fs.existsSync(tmpDir)) fs.mkdirSync(tmpDir, { recursive: true });
|
|
85
97
|
const debugPath = path.join(tmpDir, 'spawn-debug.log');
|
|
86
|
-
fs.
|
|
98
|
+
fs.writeFile(debugPath, `spawn-agent.js at ${ts()}\nclaudeBin=${claudeBin || 'not found'}\nnative=${claudeIsNative}\nprompt=${promptFile}\nsysPrompt=${sysPromptFile}\nextraArgs=${extraArgs.join(' ')}\n`, () => {});
|
|
87
99
|
|
|
88
100
|
// When resuming a session, skip system prompt (it's baked into the session)
|
|
89
101
|
const isResume = extraArgs.includes('--resume');
|
|
@@ -104,14 +116,8 @@ if (!claudeBin) {
|
|
|
104
116
|
process.exit(78); // 78 = configuration error (distinct from runtime failures)
|
|
105
117
|
}
|
|
106
118
|
|
|
107
|
-
// Check if --system-prompt-file is supported (cached
|
|
119
|
+
// Check if --system-prompt-file is supported (cached alongside binary path above)
|
|
108
120
|
let actualArgs = cliArgs;
|
|
109
|
-
const capsCachePath = path.join(__dirname, 'claude-caps.json');
|
|
110
|
-
let _sysPromptFileSupported = null;
|
|
111
|
-
try {
|
|
112
|
-
const caps = JSON.parse(fs.readFileSync(capsCachePath, 'utf8'));
|
|
113
|
-
if (caps.claudeBin === claudeBin) _sysPromptFileSupported = caps.sysPromptFile;
|
|
114
|
-
} catch {}
|
|
115
121
|
if (_sysPromptFileSupported === null) {
|
|
116
122
|
try {
|
|
117
123
|
const { spawnSync } = require('child_process');
|
|
@@ -119,8 +125,9 @@ if (_sysPromptFileSupported === null) {
|
|
|
119
125
|
? spawnSync(claudeBin, ['--help'], { encoding: 'utf8', timeout: 10000, windowsHide: true })
|
|
120
126
|
: spawnSync(process.execPath, [claudeBin, '--help'], { encoding: 'utf8', timeout: 10000, windowsHide: true });
|
|
121
127
|
_sysPromptFileSupported = (testResult.stdout || '').includes('system-prompt-file');
|
|
122
|
-
try { fs.writeFileSync(capsCachePath, JSON.stringify({ claudeBin, sysPromptFile: _sysPromptFileSupported, checkedAt: ts() })); } catch { /* optional */ }
|
|
123
128
|
} catch { _sysPromptFileSupported = true; /* assume supported */ }
|
|
129
|
+
// Save binary path + capability flag together
|
|
130
|
+
try { fs.writeFileSync(capsCachePath, JSON.stringify({ claudeBin, claudeIsNative, sysPromptFile: _sysPromptFileSupported, checkedAt: ts() })); } catch {}
|
|
124
131
|
}
|
|
125
132
|
if (!isResume) try {
|
|
126
133
|
if (!_sysPromptFileSupported) {
|
|
@@ -147,7 +154,7 @@ const proc = claudeIsNative
|
|
|
147
154
|
? runFile(claudeBin, actualArgs, { stdio: ['pipe', 'pipe', 'pipe'], env })
|
|
148
155
|
: runFile(process.execPath, [claudeBin, ...actualArgs], { stdio: ['pipe', 'pipe', 'pipe'], env });
|
|
149
156
|
|
|
150
|
-
fs.
|
|
157
|
+
fs.appendFile(debugPath, `PID=${proc.pid || 'none'}\nargs=${actualArgs.join(' ').slice(0, 500)}\n`, () => {});
|
|
151
158
|
|
|
152
159
|
// Write PID file for parent engine to verify spawn
|
|
153
160
|
const pidFile = promptFile.replace(/prompt-/, 'pid-').replace(/\.md$/, '.pid');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.565",
|
|
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"
|