@yemi33/minions 0.1.720 → 0.1.722
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/refresh.js +1 -0
- package/dashboard/js/render-plans.js +1 -1
- package/dashboard/js/utils.js +15 -5
- package/dashboard.html +1 -1
- package/dashboard.js +22 -0
- package/package.json +1 -1
- package/prompts/cc-system.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.722 (2026-04-09)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
- server-side KB pin state so CC can pin items
|
|
7
|
+
|
|
8
|
+
### Fixes
|
|
9
|
+
- remove 200-char truncation from PRD item descriptions in plan viewer (closes #670) (#700)
|
|
10
|
+
|
|
3
11
|
## 0.1.720 (2026-04-09)
|
|
4
12
|
|
|
5
13
|
### Fixes
|
package/dashboard/js/refresh.js
CHANGED
|
@@ -414,7 +414,7 @@ function _renderPlanModal(normalizedFile, raw, lastMod) {
|
|
|
414
414
|
const items = (plan.missing_features || []).map((f, i) =>
|
|
415
415
|
(i + 1) + '. [' + f.id + '] ' + f.name + ' (' + (f.estimated_complexity || '?') + ', ' + (f.priority || '?') + ')' +
|
|
416
416
|
(f.depends_on?.length ? ' \u2192 depends on: ' + f.depends_on.join(', ') : '') +
|
|
417
|
-
'\n ' + (f.description || '')
|
|
417
|
+
'\n ' + (f.description || '') +
|
|
418
418
|
(f.acceptance_criteria?.length ? '\n Criteria: ' + f.acceptance_criteria.join('; ') : '')
|
|
419
419
|
).join('\n\n');
|
|
420
420
|
text = 'Project: ' + (plan.project || '?') +
|
package/dashboard/js/utils.js
CHANGED
|
@@ -8,13 +8,13 @@ const _deletedIds = new Map(); // key → expiry timestamp
|
|
|
8
8
|
function markDeleted(key) { _deletedIds.set(key, Date.now() + 10000); } // suppress for 10s
|
|
9
9
|
function isDeleted(key) { const exp = _deletedIds.get(key); if (!exp) return false; if (Date.now() > exp) { _deletedIds.delete(key); return false; } return true; }
|
|
10
10
|
|
|
11
|
-
//
|
|
12
|
-
const PINS_KEY = 'minions-pinned-items';
|
|
11
|
+
// Pin-to-top — persisted server-side so CC and agents can also pin items
|
|
13
12
|
let _pinsCache = null;
|
|
14
13
|
function invalidatePinsCache() { _pinsCache = null; }
|
|
15
14
|
function getPinnedItems() {
|
|
16
15
|
if (_pinsCache) return _pinsCache;
|
|
17
|
-
|
|
16
|
+
// Migrate from localStorage if server hasn't been seeded yet
|
|
17
|
+
try { _pinsCache = JSON.parse(localStorage.getItem('minions-pinned-items') || '[]'); } catch { _pinsCache = []; }
|
|
18
18
|
return _pinsCache;
|
|
19
19
|
}
|
|
20
20
|
function isPinned(key) { return getPinnedItems().includes(key); }
|
|
@@ -22,10 +22,20 @@ function togglePin(key) {
|
|
|
22
22
|
const pins = getPinnedItems();
|
|
23
23
|
const idx = pins.indexOf(key);
|
|
24
24
|
if (idx >= 0) pins.splice(idx, 1); else pins.unshift(key);
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
_pinsCache = pins;
|
|
26
|
+
// Persist to server (fire-and-forget)
|
|
27
|
+
fetch('/api/kb-pins', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ pins }) }).catch(function() {});
|
|
27
28
|
return idx < 0; // true if now pinned
|
|
28
29
|
}
|
|
30
|
+
function _syncPinsFromServer() {
|
|
31
|
+
fetch('/api/kb-pins').then(function(r) { return r.json(); }).then(function(d) {
|
|
32
|
+
if (Array.isArray(d.pins) && d.pins.length > 0) {
|
|
33
|
+
_pinsCache = d.pins;
|
|
34
|
+
// Clear legacy localStorage
|
|
35
|
+
localStorage.removeItem('minions-pinned-items');
|
|
36
|
+
}
|
|
37
|
+
}).catch(function() {});
|
|
38
|
+
}
|
|
29
39
|
function inboxPinKey(name) { return 'notes/inbox/' + name; }
|
|
30
40
|
function kbPinKey(cat, file) { return 'knowledge/' + cat + '/' + file; }
|
|
31
41
|
function _togglePinAndRefresh(key, source) {
|
package/dashboard.html
CHANGED
|
@@ -4273,7 +4273,7 @@ async function planView(file) {
|
|
|
4273
4273
|
const items = (plan.missing_features || []).map((f, i) =>
|
|
4274
4274
|
(i + 1) + '. [' + f.id + '] ' + f.name + ' (' + (f.estimated_complexity || '?') + ', ' + (f.priority || '?') + ')' +
|
|
4275
4275
|
(f.depends_on?.length ? ' → depends on: ' + f.depends_on.join(', ') : '') +
|
|
4276
|
-
'\n ' + (f.description || '')
|
|
4276
|
+
'\n ' + (f.description || '') +
|
|
4277
4277
|
(f.acceptance_criteria?.length ? '\n Criteria: ' + f.acceptance_criteria.join('; ') : '')
|
|
4278
4278
|
).join('\n\n');
|
|
4279
4279
|
text = 'Project: ' + (plan.project || '?') +
|
package/dashboard.js
CHANGED
|
@@ -3784,6 +3784,28 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3784
3784
|
return jsonReply(res, 200, { ok: true });
|
|
3785
3785
|
}},
|
|
3786
3786
|
|
|
3787
|
+
// KB pin state (server-side so CC can pin items)
|
|
3788
|
+
{ method: 'GET', path: '/api/kb-pins', desc: 'Get pinned KB item keys', handler: async (req, res) => {
|
|
3789
|
+
const pins = shared.safeJson(path.join(MINIONS_DIR, 'engine', 'kb-pins.json')) || [];
|
|
3790
|
+
return jsonReply(res, 200, { pins });
|
|
3791
|
+
}},
|
|
3792
|
+
{ method: 'POST', path: '/api/kb-pins', desc: 'Set pinned KB item keys', params: 'pins[]', handler: async (req, res) => {
|
|
3793
|
+
const body = await readBody(req);
|
|
3794
|
+
if (!Array.isArray(body.pins)) return jsonReply(res, 400, { error: 'pins array required' });
|
|
3795
|
+
safeWrite(path.join(MINIONS_DIR, 'engine', 'kb-pins.json'), body.pins);
|
|
3796
|
+
return jsonReply(res, 200, { ok: true });
|
|
3797
|
+
}},
|
|
3798
|
+
{ method: 'POST', path: '/api/kb-pins/toggle', desc: 'Toggle a single KB pin', params: 'key', handler: async (req, res) => {
|
|
3799
|
+
const body = await readBody(req);
|
|
3800
|
+
if (!body.key) return jsonReply(res, 400, { error: 'key required' });
|
|
3801
|
+
const pinsPath = path.join(MINIONS_DIR, 'engine', 'kb-pins.json');
|
|
3802
|
+
const pins = shared.safeJson(pinsPath) || [];
|
|
3803
|
+
const idx = pins.indexOf(body.key);
|
|
3804
|
+
if (idx >= 0) pins.splice(idx, 1); else pins.unshift(body.key);
|
|
3805
|
+
safeWrite(pinsPath, pins);
|
|
3806
|
+
return jsonReply(res, 200, { ok: true, pinned: idx < 0 });
|
|
3807
|
+
}},
|
|
3808
|
+
|
|
3787
3809
|
// Notes
|
|
3788
3810
|
{ method: 'POST', path: '/api/notes', desc: 'Write a note to inbox for consolidation', params: 'title, what, why?, author?', handler: handleNotesCreate },
|
|
3789
3811
|
{ method: 'GET', path: '/api/notes-full', desc: 'Return full notes.md content', handler: handleNotesFull },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.722",
|
|
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"
|
package/prompts/cc-system.md
CHANGED
|
@@ -30,7 +30,7 @@ Core action types:
|
|
|
30
30
|
- **knowledge**: title, content, category (architecture/conventions/project-notes/build-reports/reviews) — create new KB entry or copy existing doc to KB
|
|
31
31
|
- **pin-to-pinned**: title, content, level (critical/warning) — write to pinned.md, force-injected into ALL agent prompts (rarely needed)
|
|
32
32
|
|
|
33
|
-
**IMPORTANT**: When user says "pin", "pin this", "pin a note", or "pin in KB" — they mean
|
|
33
|
+
**IMPORTANT**: When user says "pin", "pin this", "pin a note", or "pin in KB" — they mean **pin an existing KB entry to the top** of the knowledge base list. Do this by calling: `curl -s -X POST http://localhost:7331/api/kb-pins/toggle -H 'Content-Type: application/json' -d '{"key":"knowledge/<category>/<filename>"}'`. If the file isn't in KB yet, first copy it to `knowledge/<category>/<slug>.md`, then pin it. Do NOT write to `pinned.md` unless user explicitly says "pinned.md" or "critical alert for all agents".
|
|
34
34
|
- **plan**: title, description, project, branchStrategy (parallel/shared-branch)
|
|
35
35
|
- **cancel**: agent, reason
|
|
36
36
|
- **retry**: ids[]
|