@yemi33/minions 0.1.27 → 0.1.29

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 CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.29 (2026-03-28)
4
+
5
+ ### Dashboard
6
+ - dashboard.js
7
+
8
+ ## 0.1.28 (2026-03-28)
9
+
10
+ ### Engine
11
+ - engine.js
12
+
13
+ ### Dashboard
14
+ - dashboard/js/detail-panel.js
15
+
3
16
  ## 0.1.27 (2026-03-28)
4
17
 
5
18
  ### Engine
@@ -71,7 +71,7 @@ function renderDetailContent(detail, tab) {
71
71
  '<button class="pr-pager-btn" onclick="refreshLiveOutput()" style="font-size:10px">Refresh</button>' +
72
72
  '</div>' +
73
73
  '<div id="live-steer-bar" style="display:flex;gap:8px;padding:8px;border-top:1px solid var(--border)">' +
74
- '<input id="live-steer-input" type="text" placeholder="Steer this agent... (give additional context or redirect)" ' +
74
+ '<input id="live-steer-input" type="text" placeholder="Message this agent — ask for status, give context, or redirect..." ' +
75
75
  'style="flex:1;padding:6px 10px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);font-size:12px;font-family:inherit" ' +
76
76
  'onkeydown="if(event.key===\'Enter\')sendSteering()" />' +
77
77
  '<button onclick="sendSteering()" style="padding:6px 12px;background:var(--blue);color:#fff;border:none;border-radius:var(--radius-sm);cursor:pointer;font-size:11px">Send</button>' +
package/dashboard.js CHANGED
@@ -596,6 +596,7 @@ function jsonReply(res, code, data, req) {
596
596
  */
597
597
  function cleanDispatchEntries(matchFn) {
598
598
  const dispatchPath = path.join(MINIONS_DIR, 'engine', 'dispatch.json');
599
+ const engineDir = path.join(MINIONS_DIR, 'engine');
599
600
  try {
600
601
  let removed = 0;
601
602
  mutateJsonFileLocked(dispatchPath, (dispatch) => {
@@ -606,16 +607,18 @@ function cleanDispatchEntries(matchFn) {
606
607
  const before = dispatch[queue].length;
607
608
  if (queue === 'active') {
608
609
  for (const d of dispatch[queue]) {
609
- if (matchFn(d) && d.agent) {
610
- const statusPath = path.join(MINIONS_DIR, 'agents', d.agent, 'status.json');
611
- try {
612
- const status = JSON.parse(safeRead(statusPath) || '{}');
613
- if (status.pid) try { process.kill(status.pid, 'SIGTERM'); } catch {}
614
- status.status = 'idle';
615
- delete status.currentTask;
616
- safeWrite(statusPath, status);
617
- } catch {}
618
- }
610
+ if (!matchFn(d)) continue;
611
+ // Kill the running agent process via PID file
612
+ const pidFile = path.join(engineDir, `pid-${d.id}.pid`);
613
+ try {
614
+ const pid = parseInt(fs.readFileSync(pidFile, 'utf8').trim());
615
+ if (pid) process.kill(pid, 'SIGTERM');
616
+ } catch {}
617
+ try { fs.unlinkSync(pidFile); } catch {}
618
+ // Clean up temp prompt files
619
+ try { fs.unlinkSync(path.join(engineDir, 'tmp', `prompt-${d.id}.md`)); } catch {}
620
+ try { fs.unlinkSync(path.join(engineDir, 'tmp', `sysprompt-${d.id}.md`)); } catch {}
621
+ try { fs.unlinkSync(path.join(engineDir, 'tmp', `sysprompt-${d.id}.md.tmp`)); } catch {}
619
622
  }
620
623
  }
621
624
  dispatch[queue] = dispatch[queue].filter(d => !matchFn(d));
@@ -814,15 +817,24 @@ const server = http.createServer(async (req, res) => {
814
817
  safeWrite(wiPath, items);
815
818
 
816
819
  // Clean dispatch entries + kill running agent
817
- const sourcePrefix = (!source || source === 'central') ? 'central-work-' : `work-${source}-`;
818
- const dispatchKey = sourcePrefix + id;
819
- cleanDispatchEntries(d =>
820
- d.meta?.dispatchKey === dispatchKey ||
821
- (d.meta?.parentKey && d.meta.parentKey === dispatchKey) ||
822
- d.meta?.item?.id === id
820
+ const dispatchRemoved = cleanDispatchEntries(d =>
821
+ d.meta?.item?.id === id ||
822
+ d.meta?.dispatchKey?.endsWith(id)
823
823
  );
824
824
 
825
- return jsonReply(res, 200, { ok: true, id });
825
+ // Clean cooldown entries so item can be re-created immediately
826
+ try {
827
+ const cooldownPath = path.join(MINIONS_DIR, 'engine', 'cooldowns.json');
828
+ const cooldowns = JSON.parse(safeRead(cooldownPath) || '{}');
829
+ let cleaned = false;
830
+ for (const key of Object.keys(cooldowns)) {
831
+ if (key.includes(id)) { delete cooldowns[key]; cleaned = true; }
832
+ }
833
+ if (cleaned) safeWrite(cooldownPath, cooldowns);
834
+ } catch {}
835
+
836
+ invalidateStatusCache();
837
+ return jsonReply(res, 200, { ok: true, id, dispatchRemoved });
826
838
  } catch (e) { return jsonReply(res, 400, { error: e.message }); }
827
839
  }
828
840
 
package/engine.js CHANGED
@@ -1043,7 +1043,7 @@ function spawnAgent(dispatchItem, config) {
1043
1043
  log('info', `Steering: re-spawning ${agentId} with --resume ${steerSessionId}`);
1044
1044
 
1045
1045
  // Write new prompt with steering message
1046
- const steerPrompt = `HUMAN STEERING MESSAGE:\n\n${steerMsg}\n\nPlease acknowledge this update and adjust your approach accordingly. Continue working on your current task with this new context.`;
1046
+ const steerPrompt = `Message from your human teammate:\n\n${steerMsg}\n\nRespond to this, then continue working on your current task.`;
1047
1047
  const steerPromptPath = path.join(ENGINE_DIR, 'tmp', `prompt-steer-${id}.md`);
1048
1048
  safeWrite(steerPromptPath, steerPrompt);
1049
1049
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.27",
3
+ "version": "0.1.29",
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"