@yemi33/minions 0.1.1751 → 0.1.1753

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,9 +1,19 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.1751 (2026-05-06)
3
+ ## 0.1.1753 (2026-05-06)
4
+
5
+ ### Other
6
+ - refactor(doc-chat): drop brittle regex action gate in favour of sysprompt
7
+
8
+ ## 0.1.1752 (2026-05-06)
4
9
 
5
10
  ### Features
6
- - install unhandledRejection / uncaughtException crash handlers (P-h1crash-4e21) (#2122)
11
+ - bring PRD graph view to parity with list view
12
+
13
+ ### Other
14
+ - Show Copilot MCPs in dashboard
15
+
16
+ ## 0.1.1750 (2026-05-06)
7
17
 
8
18
  ### Fixes
9
19
  - lock doc-chat into plain-response mode (no tool calls) (#2127)
@@ -85,17 +85,18 @@ function renderMcpServers(servers) {
85
85
  const countEl = document.getElementById('mcp-count');
86
86
  countEl.textContent = servers.length;
87
87
  if (!servers.length) {
88
- el.innerHTML = '<p class="empty">No MCP servers found. Add them to <code>~/.claude.json</code> and they\'ll appear here automatically.</p>';
88
+ el.innerHTML = '<p class="empty">No MCP servers found. Add them to <code>~/.claude.json</code> or <code>~/.copilot/mcp-config.json</code> and they\'ll appear here automatically.</p>';
89
89
  return;
90
90
  }
91
91
  el.innerHTML = '<div style="display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px">' +
92
92
  servers.map(s =>
93
- '<div style="font-size:11px;padding:5px 10px;background:var(--surface2);border:1px solid var(--border);border-radius:6px;color:var(--text)" title="' + escHtml(s.args || s.command) + '">' +
93
+ '<div style="font-size:11px;padding:5px 10px;background:var(--surface2);border:1px solid var(--border);border-radius:6px;color:var(--text)" title="' + escHtml([s.source, s.args || s.command].filter(Boolean).join(': ')) + '">' +
94
94
  escHtml(s.name) +
95
+ (s.source ? ' <span style="color:var(--muted)">(' + escHtml(s.source) + ')</span>' : '') +
95
96
  '</div>'
96
97
  ).join('') +
97
98
  '</div>' +
98
- '<p style="font-size:10px;color:var(--muted);margin:0">Synced from <code style="color:var(--blue)">~/.claude.json</code> add MCP servers there to make them available to all agents.</p>';
99
+ '<p style="font-size:10px;color:var(--muted);margin:0">Synced from <code style="color:var(--blue)">~/.claude.json</code> and <code style="color:var(--blue)">~/.copilot/mcp-config.json</code>.</p>';
99
100
  }
100
101
 
101
102
  function renderMetrics(metrics) {
@@ -406,12 +406,22 @@ function renderPrdProgress(prog) {
406
406
  const agentDisplay = agentInfo ? (agentInfo.emoji || '') + ' ' + escHtml(agentInfo.name || agentId) : (agentId ? escHtml(agentId) : '');
407
407
  const deps = (i.depends_on || []).join(', ');
408
408
  const wipAnim = i.status === 'in-progress' ? 'animation:prdWipPulse 2s infinite;' : '';
409
+ const wiForCard = wi[i.id];
410
+ const wiIdBadge = wiForCard ? '<span style="font-size:8px;color:var(--muted);background:var(--surface);padding:1px 4px;border-radius:3px;border:1px solid var(--border)" title="Work item: ' + escHtml(wiForCard.id) + '">' + escHtml(wiForCard.id) + '</span>' : '';
411
+ const isDoneCard = i.status === 'done' || (wiForCard && wiForCard.status === 'done');
412
+ const reopenBtnGraph = isDoneCard
413
+ ? '<span onclick="event.stopPropagation();prdItemReopen(\'' + src + '\',\'' + iid + '\')" style="font-size:8px;color:var(--blue);cursor:pointer;padding:1px 4px;background:rgba(56,139,253,0.1);border:1px solid rgba(56,139,253,0.3);border-radius:3px" title="Re-open: set to updated so engine re-dispatches on existing branch">re-open</span>'
414
+ : '';
415
+ const cardTitle = i.description ? escHtml(i.name + ' — ' + i.description) : escHtml(i.name || '');
409
416
  html += '<div onclick="prdItemEdit(\'' + src + '\',\'' + iid + '\')" ' +
417
+ 'title="' + cardTitle + '" ' +
410
418
  'style="background:var(--surface2);border:1px solid var(--border);border-left:3px solid ' + borderColor + ';' + wipAnim +
411
419
  'border-radius:4px;padding:6px 8px;margin-bottom:6px;cursor:pointer;font-size:11px">' +
412
420
  '<div style="display:flex;align-items:center;gap:4px;margin-bottom:2px">' +
413
421
  statusBadge(i.status, i.id) +
414
422
  '<span style="font-weight:600;color:var(--text)">' + escHtml(i.id) + '</span>' +
423
+ wiIdBadge +
424
+ '<span onclick="event.stopPropagation();prdItemRemove(\'' + src + '\',\'' + iid + '\')" style="margin-left:auto;color:var(--red);cursor:pointer;font-size:10px;padding:0 4px;line-height:1" title="Remove item">x</span>' +
415
425
  '</div>' +
416
426
  '<div style="color:var(--text);font-size:11px;line-height:1.3;margin-bottom:3px;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical">' + escHtml(i.name) + '</div>' +
417
427
  '<div style="display:flex;gap:4px;flex-wrap:wrap;align-items:center">' +
@@ -436,6 +446,7 @@ function renderPrdProgress(prog) {
436
446
  if (!canRetry) return '';
437
447
  return '<span onclick="event.stopPropagation();prdItemRequeue(\'' + escHtml(rqId) + '\',\'' + escHtml(w ? (w._source || '') : '') + '\',\'' + escHtml(i.source || '') + '\')" style="font-size:8px;color:var(--green);cursor:pointer;padding:1px 4px;background:rgba(63,185,80,0.1);border:1px solid rgba(63,185,80,0.3);border-radius:3px">retry</span>';
438
448
  })() +
449
+ reopenBtnGraph +
439
450
  (deps ? '<span style="font-size:8px;color:var(--muted)" title="Depends on: ' + escHtml(deps) + '">deps: ' + escHtml(deps) + '</span>' : '') +
440
451
  (function() {
441
452
  var w = wi[i.id];
package/dashboard.js CHANGED
@@ -721,17 +721,24 @@ function getDiskVersion() {
721
721
  return _diskVersionCache;
722
722
  }
723
723
 
724
+ function readMcpServersFromConfig(configPath, source) {
725
+ const data = safeJsonObj(configPath);
726
+ const servers = data.mcpServers || {};
727
+ return Object.entries(servers).map(([name, cfg]) => ({
728
+ name,
729
+ source,
730
+ command: cfg.command || cfg.url || '',
731
+ args: (cfg.args || []).slice(-1)[0] || '',
732
+ }));
733
+ }
734
+
724
735
  function getMcpServers() {
725
736
  try {
726
737
  const home = os.homedir();
727
- const claudeJsonPath = path.join(home, '.claude.json');
728
- const data = safeJsonObj(claudeJsonPath);
729
- const servers = data.mcpServers || {};
730
- return Object.entries(servers).map(([name, cfg]) => ({
731
- name,
732
- command: cfg.command || '',
733
- args: (cfg.args || []).slice(-1)[0] || '',
734
- }));
738
+ return [
739
+ ...readMcpServersFromConfig(path.join(home, '.claude.json'), 'Claude'),
740
+ ...readMcpServersFromConfig(path.join(home, '.copilot', 'mcp-config.json'), 'Copilot'),
741
+ ];
735
742
  } catch { return []; }
736
743
  }
737
744
 
@@ -1503,34 +1510,6 @@ function stripCCActionSyntax(text) {
1503
1510
  return displayText.replace(/`{3,}\s*action\s*\r?\n[\s\S]*?`{3,}\n?/g, '').trim();
1504
1511
  }
1505
1512
 
1506
- function _messageRequestsOrchestration(message) {
1507
- const text = String(message || '').toLowerCase();
1508
- if (!text.trim()) return false;
1509
-
1510
- const docTarget = '\\b(document|doc|text|selection|selected text|selected paragraph|selected section|paragraph|section|wording|copy|markdown|plan)\\b';
1511
- const docEditVerb = '\\b(edit|rewrite|revise|update|change|rephrase|polish|format|shorten|expand|summarize|correct|add|write)\\b';
1512
- const explicitDocEdit = new RegExp(`${docEditVerb}[\\s\\S]{0,120}${docTarget}|${docTarget}[\\s\\S]{0,120}${docEditVerb}`).test(text)
1513
- || /\bfix\b[\s\S]{0,80}\b(typo|typos|grammar|spelling|wording|copy|markdown)\b[\s\S]{0,80}\b(document|doc|text|selection|paragraph|section|plan)\b/.test(text);
1514
- const actionTerm = '\\b(dispatch|delegate|assign|orchestrate|hand off|handoff|work item|ticket|agent|minions|watch|monitor|schedule|pipeline|meeting)\\b';
1515
- const untrustedActionMention = new RegExp(
1516
- `${docTarget}[\\s\\S]{0,120}\\b(says|contains|mentions|includes|reads|states|instructs|asks|tells|literal|literally)\\b[\\s\\S]{0,160}${actionTerm}`
1517
- ).test(text)
1518
- || new RegExp(`\\b(summarize|explain|quote|describe|analyze|extract)\\b[\\s\\S]{0,160}${docTarget}[\\s\\S]{0,160}${actionTerm}`).test(text);
1519
- const explicitFollowupAction = /\b(and|then|also)\b[\s\S]{0,80}\b(dispatch|delegate|assign|orchestrate|hand off|handoff|work item|ticket|agent|minions|watch|monitor|schedule|pipeline|meeting)\b/.test(text);
1520
- if (untrustedActionMention && !explicitFollowupAction) return false;
1521
-
1522
- const dispatchAction = /\b(dispatch|delegate|assign|orchestrate|hand off|handoff)\b[\s\S]{0,120}\b(agent|dallas|ripley|lambert|rebecca|ralph|work item|task|fix|implement|explore|investigate|audit|review|test|verify|build)\b/.test(text);
1523
- const workItemAction = /\b(create|open|file|add)\b[\s\S]{0,80}\b(work item|task|ticket)\b/.test(text);
1524
- const stateAction = /\b(create|add|set up|start)\b[\s\S]{0,80}\b(watch|monitor|schedule|pipeline|meeting)\b/.test(text)
1525
- || /\b(watch|monitor|keep an eye on)\b[\s\S]{0,100}\b(pr|pull request|work item|build)\b/.test(text)
1526
- || /\b(cancel|retry|reopen|archive|pause|approve|reject|execute|resume|steer)\b[\s\S]{0,100}\b(plan|work item|agent|pr|pull request|schedule|pipeline)\b/.test(text);
1527
- const agentEngineeringAction = /\b(minions|agent|dallas|ripley|lambert|rebecca|ralph)\b[\s\S]{0,120}\b(fix|debug|repair|investigate|audit|review|test|verify|build|refactor|implement)\b/.test(text)
1528
- || /\b(fix|debug|repair|investigate|audit|review|test|verify|build|refactor|implement)\b[\s\S]{0,120}\b(minions|agent|dallas|ripley|lambert|rebecca|ralph)\b/.test(text);
1529
- const explicitActionIntent = dispatchAction || workItemAction || stateAction || agentEngineeringAction;
1530
- if (explicitDocEdit && !explicitActionIntent) return false;
1531
- return explicitActionIntent;
1532
- }
1533
-
1534
1513
  function _escapeRegExp(str) {
1535
1514
  return String(str).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1536
1515
  }
@@ -2510,13 +2489,11 @@ function contentFingerprint(str) {
2510
2489
  return str.length + ':' + str.charCodeAt(0) + ':' + str.charCodeAt(mid) + ':' + str.charCodeAt(str.length - 1);
2511
2490
  }
2512
2491
 
2513
- function _parseDocChatResultText(text, { allowActions = false } = {}) {
2492
+ function _parseDocChatResultText(text) {
2514
2493
  const docDelimiter = findDocChatDocumentDelimiter(text);
2515
2494
  if (docDelimiter) {
2516
2495
  const answerPart = text.slice(0, docDelimiter.index).trim();
2517
- const parsedActions = allowActions
2518
- ? parseCCActions(answerPart)
2519
- : { text: stripCCActionSyntax(answerPart), actions: [] };
2496
+ const parsedActions = parseCCActions(answerPart);
2520
2497
  const { text: answer, actions } = parsedActions;
2521
2498
  let content = text.slice(docDelimiter.index + docDelimiter.length).trim();
2522
2499
  content = content.replace(/^```\w*\n?/, '').replace(/\n?```$/, '').trim();
@@ -2527,9 +2504,7 @@ function _parseDocChatResultText(text, { allowActions = false } = {}) {
2527
2504
  ...(parsedActions._actionParseError ? { actionParseError: parsedActions._actionParseError } : {}),
2528
2505
  };
2529
2506
  }
2530
- const parsedActions = allowActions
2531
- ? parseCCActions(text)
2532
- : { text: stripCCActionSyntax(text), actions: [] };
2507
+ const parsedActions = parseCCActions(text);
2533
2508
  const { text: stripped, actions } = parsedActions;
2534
2509
  return {
2535
2510
  answer: stripped,
@@ -2539,8 +2514,8 @@ function _parseDocChatResultText(text, { allowActions = false } = {}) {
2539
2514
  };
2540
2515
  }
2541
2516
 
2542
- function _docChatDisplayText(text, opts) {
2543
- return _parseDocChatResultText(text, opts).answer;
2517
+ function _docChatDisplayText(text) {
2518
+ return _parseDocChatResultText(text).answer;
2544
2519
  }
2545
2520
 
2546
2521
  function _formatDocChatContext({ document, title, filePath, selection, canEdit, isJson, docUnchanged }) {
@@ -2636,8 +2611,6 @@ async function ccDocCall({ message, document, title, filePath, selection, canEdi
2636
2611
  // Skip persistDocSessions() here — the post-call cleanup below handles persistence.
2637
2612
  }
2638
2613
 
2639
- const allowActions = _messageRequestsOrchestration(message);
2640
-
2641
2614
  const runOnce = async () => {
2642
2615
  const { extraContext } = _buildDocChatPass({
2643
2616
  docSlice, title, filePath, selection, canEdit, isJson, sessionKey, freshSession,
@@ -2684,7 +2657,7 @@ async function ccDocCall({ message, document, title, filePath, selection, canEdi
2684
2657
  return _docChatFailureResponse('doc-chat', filePath, result, sessionPreserved);
2685
2658
  }
2686
2659
 
2687
- return _parseDocChatResultText(result.text, { allowActions });
2660
+ return _parseDocChatResultText(result.text);
2688
2661
  }
2689
2662
 
2690
2663
  async function ccDocCallStreaming({ message, document, title, filePath, selection, canEdit, isJson, model, freshSession, onAbortReady, onChunk, onToolUse, onRetry }) {
@@ -2695,8 +2668,6 @@ async function ccDocCallStreaming({ message, document, title, filePath, selectio
2695
2668
  docSessions.delete(sessionKey);
2696
2669
  }
2697
2670
 
2698
- const allowActions = _messageRequestsOrchestration(message);
2699
-
2700
2671
  const runOnce = async () => {
2701
2672
  const { extraContext } = _buildDocChatPass({
2702
2673
  docSlice, title, filePath, selection, canEdit, isJson, sessionKey, freshSession,
@@ -2713,7 +2684,7 @@ async function ccDocCallStreaming({ message, document, title, filePath, selectio
2713
2684
  systemPrompt: DOC_CHAT_SYSTEM_PROMPT,
2714
2685
  ...(model ? { model } : {}),
2715
2686
  onAbortReady,
2716
- onChunk: (text) => { if (onChunk) onChunk(_docChatDisplayText(text, { allowActions })); },
2687
+ onChunk: (text) => { if (onChunk) onChunk(_docChatDisplayText(text)); },
2717
2688
  onToolUse,
2718
2689
  onRetry,
2719
2690
  });
@@ -2742,7 +2713,7 @@ async function ccDocCallStreaming({ message, document, title, filePath, selectio
2742
2713
  return _docChatFailureResponse('doc-chat-stream', filePath, result, sessionPreserved);
2743
2714
  }
2744
2715
 
2745
- return _parseDocChatResultText(result.text, { allowActions });
2716
+ return _parseDocChatResultText(result.text);
2746
2717
  }
2747
2718
 
2748
2719
  // -- POST helpers --
@@ -7428,7 +7399,6 @@ module.exports = {
7428
7399
  _meetingParticipantsFromAction: meetingParticipantsFromAction,
7429
7400
  parsePinnedEntries,
7430
7401
  _parseDocChatResultText,
7431
- _messageRequestsOrchestration,
7432
7402
  _formatDocChatContext,
7433
7403
  _linkPullRequestForTracking: linkPullRequestForTracking,
7434
7404
  _resolveSkillReadPath,
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "runtime": "copilot",
3
3
  "models": null,
4
- "cachedAt": "2026-05-06T20:22:59.939Z"
4
+ "cachedAt": "2026-05-06T21:07:27.809Z"
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.1751",
3
+ "version": "0.1.1753",
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"