@yemi33/minions 0.1.337 → 0.1.339
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 +8 -0
- package/dashboard/js/command-center.js +2 -2
- package/dashboard/js/settings.js +23 -2
- package/dashboard.js +22 -5
- package/engine/llm.js +6 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -312,9 +312,9 @@ async function _ccDoSend(message, skipUserMsg) {
|
|
|
312
312
|
if (e.name === 'AbortError') {
|
|
313
313
|
if (streamedText) {
|
|
314
314
|
const ccElapsed = Math.round((Date.now() - ccStartTime) / 1000);
|
|
315
|
-
ccAddMessage('assistant', renderMd(streamedText) + '<div style="font-size:9px;color:var(--muted);margin-top:6px">Stopped after ' + ccElapsed + 's</div>');
|
|
315
|
+
ccAddMessage('assistant', renderMd(streamedText) + '<div style="font-size:9px;color:var(--muted);margin-top:6px;display:flex;justify-content:flex-end;padding-right:30px">Stopped after ' + ccElapsed + 's</div>');
|
|
316
316
|
} else {
|
|
317
|
-
ccAddMessage('assistant', '<span style="color:var(--
|
|
317
|
+
ccAddMessage('assistant', '<span style="color:var(--red);font-size:11px">Stopped</span>');
|
|
318
318
|
}
|
|
319
319
|
} else {
|
|
320
320
|
const retryId = 'cc-retry-' + Date.now();
|
package/dashboard/js/settings.js
CHANGED
|
@@ -75,7 +75,10 @@ async function openSettings() {
|
|
|
75
75
|
'<h3 style="font-size:13px;color:var(--blue);margin-bottom:8px">Routing Table</h3>' +
|
|
76
76
|
'<textarea id="set-routing" rows="12" style="width:100%;padding:8px;background:var(--surface);border:1px solid var(--border);border-radius:4px;color:var(--text);font-family:monospace;font-size:11px;resize:vertical">' + escHtml(data.routing || '') + '</textarea>' +
|
|
77
77
|
|
|
78
|
-
'<
|
|
78
|
+
'<div style="display:flex;align-items:center;gap:12px;margin-top:12px">' +
|
|
79
|
+
'<button onclick="resetSettingsToDefaults()" style="font-size:11px;padding:4px 12px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;color:var(--red);cursor:pointer">Reset to Defaults</button>' +
|
|
80
|
+
'<span id="settings-status" style="font-size:11px;color:var(--muted)"></span>' +
|
|
81
|
+
'</div>' +
|
|
79
82
|
'</div>';
|
|
80
83
|
|
|
81
84
|
document.getElementById('modal-title').textContent = 'Settings';
|
|
@@ -223,4 +226,22 @@ async function addProject() {
|
|
|
223
226
|
} catch (e) { alert('Error: ' + e.message); }
|
|
224
227
|
}
|
|
225
228
|
|
|
226
|
-
|
|
229
|
+
async function resetSettingsToDefaults() {
|
|
230
|
+
if (!confirm('Reset all engine, CLI, and agent settings to defaults? This cannot be undone.')) return;
|
|
231
|
+
const status = document.getElementById('settings-status');
|
|
232
|
+
try {
|
|
233
|
+
status.textContent = 'Resetting...';
|
|
234
|
+
status.style.color = 'var(--blue)';
|
|
235
|
+
const res = await fetch('/api/settings/reset', { method: 'POST' });
|
|
236
|
+
if (!res.ok) { const d = await res.json(); throw new Error(d.error || 'Reset failed'); }
|
|
237
|
+
status.textContent = 'Reset complete. Reloading...';
|
|
238
|
+
status.style.color = 'var(--green)';
|
|
239
|
+
showToast('cmd-toast', 'Settings reset to defaults', true);
|
|
240
|
+
setTimeout(() => openSettings(), 500);
|
|
241
|
+
} catch (e) {
|
|
242
|
+
status.textContent = 'Error: ' + e.message;
|
|
243
|
+
status.style.color = 'var(--red)';
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
window.MinionsSettings = { openSettings, saveSettings, addProject, resetSettingsToDefaults };
|
package/dashboard.js
CHANGED
|
@@ -277,8 +277,7 @@ let ccInFlight = false;
|
|
|
277
277
|
let ccInFlightSince = 0; // timestamp — auto-release stuck guard
|
|
278
278
|
const CC_INFLIGHT_TIMEOUT_MS = 2 * 60 * 1000; // 2 minutes — auto-release if request hangs
|
|
279
279
|
|
|
280
|
-
//
|
|
281
|
-
const _ccPromptHash = require('crypto').createHash('md5').update(CC_STATIC_SYSTEM_PROMPT).digest('hex').slice(0, 8);
|
|
280
|
+
// _ccPromptHash computed after CC_STATIC_SYSTEM_PROMPT is defined (see below)
|
|
282
281
|
|
|
283
282
|
function ccSessionValid() {
|
|
284
283
|
if (!ccSession.sessionId) return false;
|
|
@@ -436,6 +435,9 @@ Available action types:
|
|
|
436
435
|
8. **Never push to git remotes** without the user explicitly confirming.
|
|
437
436
|
9. For long-running processes (dev servers), start them detached so they survive after your session.`;
|
|
438
437
|
|
|
438
|
+
// Hash the system prompt so we can detect changes and invalidate stale sessions
|
|
439
|
+
const _ccPromptHash = require('crypto').createHash('md5').update(CC_STATIC_SYSTEM_PROMPT).digest('hex').slice(0, 8);
|
|
440
|
+
|
|
439
441
|
function buildCCStatePreamble() {
|
|
440
442
|
// Lightweight snapshot — just enough to orient. Use tools for details.
|
|
441
443
|
const agents = getAgents().map(a => `- ${a.name} (${a.id}): ${a.status}${a.currentTask ? ' — ' + a.currentTask.slice(0, 60) : ''}`).join('\n');
|
|
@@ -3020,8 +3022,9 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3020
3022
|
ccInFlightSince = Date.now();
|
|
3021
3023
|
|
|
3022
3024
|
res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' });
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
+
let _ccStreamAbort = null;
|
|
3026
|
+
// Kill LLM process immediately if client disconnects mid-stream
|
|
3027
|
+
req.on('close', () => { ccInFlight = false; ccInFlightSince = 0; if (_ccStreamAbort) _ccStreamAbort(); });
|
|
3025
3028
|
|
|
3026
3029
|
try {
|
|
3027
3030
|
// Session management — same as non-streaming path
|
|
@@ -3034,7 +3037,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3034
3037
|
const prompt = preamble + '\n\n---\n\n' + body.message;
|
|
3035
3038
|
|
|
3036
3039
|
const { callLLMStreaming, trackEngineUsage: trackUsage } = require('./engine/llm');
|
|
3037
|
-
const
|
|
3040
|
+
const llmPromise = callLLMStreaming(prompt, CC_STATIC_SYSTEM_PROMPT, {
|
|
3038
3041
|
timeout: 900000, label: 'command-center', model: 'sonnet', maxTurns: 50,
|
|
3039
3042
|
allowedTools: 'Bash,Read,Write,Edit,Glob,Grep,WebFetch,WebSearch',
|
|
3040
3043
|
sessionId,
|
|
@@ -3045,6 +3048,8 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3045
3048
|
try { res.write('data: ' + JSON.stringify({ type: 'tool', name, input: typeof input === 'string' ? input.slice(0, 200) : JSON.stringify(input).slice(0, 200) }) + '\n\n'); } catch {}
|
|
3046
3049
|
}
|
|
3047
3050
|
});
|
|
3051
|
+
_ccStreamAbort = llmPromise.abort;
|
|
3052
|
+
const result = await llmPromise;
|
|
3048
3053
|
trackUsage('command-center', result.usage);
|
|
3049
3054
|
|
|
3050
3055
|
// Handle failure — same error reporting as non-streaming
|
|
@@ -3279,6 +3284,17 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3279
3284
|
} catch (e) { return jsonReply(res, 500, { error: e.message }); }
|
|
3280
3285
|
}
|
|
3281
3286
|
|
|
3287
|
+
async function handleSettingsReset(req, res) {
|
|
3288
|
+
try {
|
|
3289
|
+
const config = getConfig();
|
|
3290
|
+
config.engine = { ...shared.ENGINE_DEFAULTS };
|
|
3291
|
+
config.claude = { ...shared.DEFAULT_CLAUDE };
|
|
3292
|
+
config.agents = { ...shared.DEFAULT_AGENTS };
|
|
3293
|
+
safeWrite(CONFIG_PATH, config);
|
|
3294
|
+
return jsonReply(res, 200, { ok: true });
|
|
3295
|
+
} catch (e) { return jsonReply(res, 500, { error: e.message }); }
|
|
3296
|
+
}
|
|
3297
|
+
|
|
3282
3298
|
async function handleHealth(req, res) {
|
|
3283
3299
|
const engine = getEngineState();
|
|
3284
3300
|
const agents = getAgents();
|
|
@@ -3740,6 +3756,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3740
3756
|
{ method: 'GET', path: '/api/settings', desc: 'Return current engine + claude + routing config', handler: handleSettingsRead },
|
|
3741
3757
|
{ method: 'POST', path: '/api/settings', desc: 'Update engine + claude + agent config', params: 'engine?, claude?, agents?', handler: handleSettingsUpdate },
|
|
3742
3758
|
{ method: 'POST', path: '/api/settings/routing', desc: 'Update routing.md', params: 'content', handler: handleSettingsRouting },
|
|
3759
|
+
{ method: 'POST', path: '/api/settings/reset', desc: 'Reset engine + claude + agent settings to defaults', handler: handleSettingsReset },
|
|
3743
3760
|
];
|
|
3744
3761
|
|
|
3745
3762
|
// Expose routes to CC preamble builder (once, on first request)
|
package/engine/llm.js
CHANGED
|
@@ -114,7 +114,8 @@ function isResumeSessionStillValid(result) {
|
|
|
114
114
|
* onChunk(text) is called for each assistant text block as it arrives.
|
|
115
115
|
*/
|
|
116
116
|
function callLLMStreaming(promptText, sysPromptText, { timeout = 120000, label = 'llm', model = 'sonnet', maxTurns = 1, allowedTools = '', sessionId = null, onChunk = () => {}, onToolUse = null } = {}) {
|
|
117
|
-
|
|
117
|
+
let _abort = null;
|
|
118
|
+
const promise = new Promise((resolve) => {
|
|
118
119
|
const id = uid();
|
|
119
120
|
const tmpDir = path.join(ENGINE_DIR, 'tmp');
|
|
120
121
|
if (!require('fs').existsSync(tmpDir)) require('fs').mkdirSync(tmpDir, { recursive: true });
|
|
@@ -135,6 +136,8 @@ function callLLMStreaming(promptText, sysPromptText, { timeout = 120000, label =
|
|
|
135
136
|
|
|
136
137
|
const proc = runFile(process.execPath, args, { cwd: MINIONS_DIR, stdio: ['pipe', 'pipe', 'pipe'], env: cleanChildEnv() });
|
|
137
138
|
|
|
139
|
+
_abort = () => { shared.killImmediate(proc); };
|
|
140
|
+
|
|
138
141
|
let stdout = '';
|
|
139
142
|
let stderr = '';
|
|
140
143
|
let lineBuf = '';
|
|
@@ -197,6 +200,8 @@ function callLLMStreaming(promptText, sysPromptText, { timeout = 120000, label =
|
|
|
197
200
|
resolve({ text: '', usage: null, sessionId: null, code: 1, stderr: err.message, raw: '' });
|
|
198
201
|
});
|
|
199
202
|
});
|
|
203
|
+
promise.abort = () => { if (_abort) _abort(); };
|
|
204
|
+
return promise;
|
|
200
205
|
}
|
|
201
206
|
|
|
202
207
|
module.exports = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.339",
|
|
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"
|