@yemi33/minions 0.1.685 → 0.1.687

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,11 +1,13 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.685 (2026-04-09)
3
+ ## 0.1.687 (2026-04-09)
4
4
 
5
5
  ### Features
6
+ - modal back button for artifact navigation
6
7
  - collapsible doc-chat thread in modal
7
8
 
8
9
  ### Fixes
10
+ - add archive fallback for artifact notes when KB entry was swept
9
11
  - link work item artifacts to KB entries, not raw archive copies
10
12
 
11
13
  ## 0.1.683 (2026-04-09)
@@ -4,6 +4,7 @@ function closeModal() {
4
4
  const modalEl = document.querySelector('#modal .modal');
5
5
  if (modalEl) modalEl.classList.remove('modal-wide');
6
6
  document.getElementById('modal').classList.remove('open');
7
+ clearModalBackStack();
7
8
  // Hide Q&A section (only shown for document modals)
8
9
  document.getElementById('modal-qa').style.display = 'none';
9
10
  // Remove settings buttons if present
@@ -452,24 +452,31 @@ function openWorkItemDetail(id) {
452
452
  var artPills = '';
453
453
  var pillStyle = 'display:inline-flex;align-items:center;gap:3px;padding:2px 8px;border-radius:10px;font-size:10px;cursor:pointer;background:var(--surface2);border:1px solid var(--border);color:var(--text)';
454
454
  // Output log pill removed — raw stream-json output is not human-readable
455
+ var artBackFn = "pushModalBack(function(){openWorkItemDetail('" + escHtml(item.id) + "')});";
455
456
  if (arts.branch) artPills += '<span style="' + pillStyle + ';cursor:default">🌿 ' + escHtml(arts.branch) + '</span> ';
456
- if (arts.plan) artPills += '<span onclick="planView(\'' + escHtml(arts.plan) + '\')" style="' + pillStyle + '">📋 Plan</span> ';
457
- if (arts.prd) artPills += '<span onclick="planView(\'' + escHtml(arts.prd) + '\')" style="' + pillStyle + '">📄 PRD</span> ';
458
- if (arts.sourcePlan) artPills += '<span onclick="planView(\'' + escHtml(arts.sourcePlan) + '\')" style="' + pillStyle + '">📋 Source Plan</span> ';
459
- if (arts.notes && arts.notes.length > 0) arts.notes.forEach(function(n) {
460
- var noteFile = (n && typeof n === 'object') ? (n.file || n) : String(n || '');
461
- // KB entries prefixed with 'kb:category/file'
462
- if (noteFile.startsWith('kb:')) {
463
- var kbParts = noteFile.slice(3).split('/');
464
- var kbCat = kbParts[0];
465
- var kbFile = kbParts.slice(1).join('/');
466
- var kbLabel = kbFile.replace(/\.md$/, '').slice(0, 30);
467
- artPills += '<span onclick="kbOpenItem(\'' + escHtml(kbCat) + '\',\'' + escHtml(kbFile) + '\')" style="' + pillStyle + '">📚 ' + escHtml(kbLabel) + '</span> ';
468
- } else {
469
- var noteLabel = noteFile.replace(/\.md$/, '').slice(0, 30);
470
- artPills += '<span onclick="openInboxNote(\'' + escHtml(noteFile) + '\')" style="' + pillStyle + '">📝 ' + escHtml(noteLabel) + '</span> ';
471
- }
472
- });
457
+ if (arts.plan) artPills += '<span onclick="' + artBackFn + 'planView(\'' + escHtml(arts.plan) + '\')" style="' + pillStyle + '">📋 Plan</span> ';
458
+ if (arts.prd) artPills += '<span onclick="' + artBackFn + 'planView(\'' + escHtml(arts.prd) + '\')" style="' + pillStyle + '">📄 PRD</span> ';
459
+ if (arts.sourcePlan) artPills += '<span onclick="' + artBackFn + 'planView(\'' + escHtml(arts.sourcePlan) + '\')" style="' + pillStyle + '">📋 Source Plan</span> ';
460
+ if (arts.notes && arts.notes.length > 0) {
461
+ var wiId = escHtml(item.id);
462
+ arts.notes.forEach(function(n) {
463
+ var noteFile = (n && typeof n === 'object') ? (n.file || n) : String(n || '');
464
+ var backFn = "pushModalBack(function(){openWorkItemDetail('" + wiId + "')});";
465
+ if (noteFile.startsWith('kb:')) {
466
+ var kbParts = noteFile.slice(3).split('/');
467
+ var kbCat = kbParts[0];
468
+ var kbFile = kbParts.slice(1).join('/');
469
+ var kbLabel = kbFile.replace(/\.md$/, '').slice(0, 30);
470
+ artPills += '<span onclick="' + backFn + 'kbOpenItem(\'' + escHtml(kbCat) + '\',\'' + escHtml(kbFile) + '\')" style="' + pillStyle + '">📚 ' + escHtml(kbLabel) + '</span> ';
471
+ } else if (noteFile.startsWith('archive:')) {
472
+ var archLabel = noteFile.slice(8).replace(/\.md$/, '').replace(/^\d{4}-\d{2}-\d{2}-/, '').slice(0, 30);
473
+ artPills += '<span onclick="' + backFn + 'openInboxNote(\'' + escHtml(noteFile.slice(8)) + '\')" style="' + pillStyle + ';opacity:0.7">📄 ' + escHtml(archLabel) + ' <span style="font-size:8px">(archived)</span></span> ';
474
+ } else {
475
+ var noteLabel = noteFile.replace(/\.md$/, '').slice(0, 30);
476
+ artPills += '<span onclick="' + backFn + 'openInboxNote(\'' + escHtml(noteFile) + '\')" style="' + pillStyle + '">📝 ' + escHtml(noteLabel) + '</span> ';
477
+ }
478
+ });
479
+ }
473
480
  if (arts.skills && arts.skills.length > 0) arts.skills.forEach(function(s) { artPills += '<span onclick="openSkill(\'' + escHtml(s) + '\',\'minions\',\'\')" style="' + pillStyle + '">⚙ ' + escHtml(s) + '</span> '; });
474
481
  if (artPills) html += field('Artifacts', '<div style="display:flex;flex-wrap:wrap;gap:4px">' + artPills + '</div>');
475
482
 
@@ -35,6 +35,25 @@ function _togglePinAndRefresh(key, source) {
35
35
  else if (source === 'kb') renderKnowledgeBase();
36
36
  }
37
37
 
38
+ // Modal navigation stack — enables back button when opening a modal from another modal
39
+ var _modalBackStack = [];
40
+ function pushModalBack(reopenFn) {
41
+ _modalBackStack.push(reopenFn);
42
+ var btn = document.getElementById('modal-back-btn');
43
+ if (btn) btn.style.display = '';
44
+ }
45
+ function modalGoBack() {
46
+ var fn = _modalBackStack.pop();
47
+ var btn = document.getElementById('modal-back-btn');
48
+ if (btn && _modalBackStack.length === 0) btn.style.display = 'none';
49
+ if (fn) fn();
50
+ }
51
+ function clearModalBackStack() {
52
+ _modalBackStack = [];
53
+ var btn = document.getElementById('modal-back-btn');
54
+ if (btn) btn.style.display = 'none';
55
+ }
56
+
38
57
  function updateModalPinBtn() {
39
58
  var btn = document.getElementById('modal-pin-btn');
40
59
  if (!btn) return;
@@ -98,6 +98,7 @@
98
98
  <div class="modal-header">
99
99
  <h3 id="modal-title">—</h3>
100
100
  <div class="modal-header-actions">
101
+ <button class="modal-copy" id="modal-back-btn" onclick="modalGoBack()" title="Back" style="display:none">&larr; Back</button>
101
102
  <button class="modal-copy" id="modal-edit-btn" onclick="modalToggleEdit()" title="Edit" style="display:none"><svg width="12" height="12" viewBox="0 0 16 16" fill="currentColor"><path d="M11.013 1.427a1.75 1.75 0 012.474 0l1.086 1.086a1.75 1.75 0 010 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 01-.927-.928l.929-3.25c.081-.286.235-.547.445-.758l8.61-8.61zM12.9 2.97L4.288 11.58l-.537 1.878 1.878-.537L14.242 4.31 12.9 2.97z"/></svg> Edit</button>
102
103
  <button class="modal-copy" id="modal-save-btn" onclick="modalSaveEdit()" title="Save" style="display:none;color:var(--green);border-color:var(--green)"><svg width="12" height="12" viewBox="0 0 16 16" fill="currentColor"><path d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"/></svg> Save</button>
103
104
  <button class="modal-copy" id="modal-cancel-edit-btn" onclick="modalCancelEdit()" title="Cancel edit" style="display:none">Cancel</button>
package/engine/queries.js CHANGED
@@ -721,6 +721,7 @@ function getWorkItems(config) {
721
721
  }
722
722
  const _agentDirCache = {};
723
723
  const _inboxFiles = safeReadDir(INBOX_DIR);
724
+ const _archiveFiles = safeReadDir(ARCHIVE_DIR);
724
725
  // Use cached KB entries (includes source frontmatter field)
725
726
  const _kbEntries = getKnowledgeBaseEntries();
726
727
  for (const item of allItems) {
@@ -736,7 +737,7 @@ function getWorkItems(config) {
736
737
  const matchLog = _agentDirCache[agentId].find(f => f.includes(dispatchId));
737
738
  if (matchLog) arts.outputLog = agentId + '/' + matchLog;
738
739
  }
739
- // Notes: check inbox first, then KB (consolidated destination) via source field
740
+ // Notes: inbox KB (via source field) archive (fallback if KB was swept)
740
741
  const itemId = item.id || '___';
741
742
  const matchInbox = _inboxFiles.filter(f => f.includes(agentId) && f.includes(itemId));
742
743
  const matchKb = _kbEntries.filter(kb => kb.source && kb.source.includes(agentId) && kb.source.includes(itemId));
@@ -744,6 +745,11 @@ function getWorkItems(config) {
744
745
  ...matchInbox,
745
746
  ...matchKb.map(kb => 'kb:' + kb.cat + '/' + kb.file),
746
747
  ];
748
+ // Archive fallback — only if nothing found in inbox or KB
749
+ if (allNotes.length === 0) {
750
+ const matchArchive = _archiveFiles.filter(f => f.includes(agentId) && f.includes(itemId));
751
+ for (const f of matchArchive) allNotes.push('archive:' + f);
752
+ }
747
753
  if (allNotes.length > 0) arts.notes = allNotes;
748
754
  }
749
755
  if (item.branch || item.featureBranch) arts.branch = item.branch || item.featureBranch;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.685",
3
+ "version": "0.1.687",
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"