@yemi33/minions 0.1.2420 → 0.1.2421

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.
@@ -0,0 +1,208 @@
1
+ (function attachMemoryExplainer(globalObject, factory) {
2
+ const api = factory();
3
+
4
+ if (typeof module !== 'undefined' && module.exports) {
5
+ module.exports = api;
6
+ }
7
+ if (globalObject) {
8
+ globalObject.MemoryExplainer = api;
9
+ }
10
+
11
+ if (typeof document !== 'undefined') {
12
+ const start = () => api.init(document);
13
+ if (document.readyState === 'loading') {
14
+ document.addEventListener('DOMContentLoaded', start, { once: true });
15
+ } else {
16
+ start();
17
+ }
18
+ }
19
+ })(typeof globalThis !== 'undefined' ? globalThis : this, function memoryExplainerFactory() {
20
+ 'use strict';
21
+
22
+ const FORWARD_KEYS = new Set(['ArrowRight', 'ArrowDown', 'next']);
23
+ const BACKWARD_KEYS = new Set(['ArrowLeft', 'ArrowUp', 'previous']);
24
+
25
+ function createSelectionModel(inputIds, initialId) {
26
+ if (!Array.isArray(inputIds) || inputIds.length === 0) {
27
+ throw new TypeError('Selection model requires at least one item');
28
+ }
29
+ const ids = inputIds.map(id => String(id || '').trim());
30
+ if (ids.some(id => !id)) {
31
+ throw new TypeError('Selection model ids must be non-empty');
32
+ }
33
+ if (new Set(ids).size !== ids.length) {
34
+ throw new TypeError('Selection model ids must be unique');
35
+ }
36
+
37
+ let index = ids.indexOf(String(initialId || ''));
38
+ if (index < 0) index = 0;
39
+
40
+ function current() {
41
+ return ids[index];
42
+ }
43
+
44
+ function select(id) {
45
+ const nextIndex = ids.indexOf(String(id || ''));
46
+ if (nextIndex >= 0) index = nextIndex;
47
+ return current();
48
+ }
49
+
50
+ function move(action) {
51
+ if (FORWARD_KEYS.has(action)) {
52
+ index = (index + 1) % ids.length;
53
+ } else if (BACKWARD_KEYS.has(action)) {
54
+ index = (index - 1 + ids.length) % ids.length;
55
+ } else if (action === 'Home') {
56
+ index = 0;
57
+ } else if (action === 'End') {
58
+ index = ids.length - 1;
59
+ }
60
+ return current();
61
+ }
62
+
63
+ return { current, select, move };
64
+ }
65
+
66
+ function setupSelectionGroup(root, options) {
67
+ if (!root) return null;
68
+ const items = Array.from(root.querySelectorAll(options.itemSelector));
69
+ if (!items.length) return null;
70
+ const ids = items.map(item => item.dataset[options.dataKey]);
71
+ const initial = ids.find((id, index) => options.isInitiallySelected(items[index])) || ids[0];
72
+ const model = createSelectionModel(ids, initial);
73
+ const panels = Array.from(root.querySelectorAll(options.panelSelector));
74
+
75
+ function render(id, focusItem) {
76
+ items.forEach(item => {
77
+ const selected = item.dataset[options.dataKey] === id;
78
+ item.setAttribute(options.selectedAttribute, String(selected));
79
+ item.tabIndex = selected ? 0 : -1;
80
+ item.classList.toggle('is-active', selected);
81
+ if (selected && focusItem) item.focus();
82
+ });
83
+ panels.forEach(panel => {
84
+ const selected = panel.id === options.panelId(id);
85
+ panel.hidden = !selected;
86
+ panel.classList.toggle('is-active', selected);
87
+ });
88
+ if (typeof options.onRender === 'function') options.onRender(id, ids.indexOf(id), ids.length);
89
+ return id;
90
+ }
91
+
92
+ items.forEach(item => {
93
+ item.addEventListener('click', () => render(model.select(item.dataset[options.dataKey]), false));
94
+ item.addEventListener('keydown', event => {
95
+ if (!FORWARD_KEYS.has(event.key)
96
+ && !BACKWARD_KEYS.has(event.key)
97
+ && event.key !== 'Home'
98
+ && event.key !== 'End') return;
99
+ event.preventDefault();
100
+ render(model.move(event.key), true);
101
+ });
102
+ });
103
+
104
+ render(model.current(), false);
105
+ return {
106
+ current: model.current,
107
+ select(id, focusItem) {
108
+ return render(model.select(id), !!focusItem);
109
+ },
110
+ move(action, focusItem) {
111
+ return render(model.move(action), !!focusItem);
112
+ },
113
+ };
114
+ }
115
+
116
+ function initJourney(doc) {
117
+ const root = doc.getElementById('memory-journey');
118
+ const shell = root && root.querySelector('.journey-shell');
119
+ if (!root || !shell) return null;
120
+ const liveRegion = root.querySelector('[data-journey-status]');
121
+ const controller = setupSelectionGroup(root, {
122
+ itemSelector: '[data-step-id]',
123
+ panelSelector: '.journey-panel',
124
+ dataKey: 'stepId',
125
+ selectedAttribute: 'aria-selected',
126
+ panelId: id => `journey-${id}`,
127
+ isInitiallySelected: item => item.getAttribute('aria-selected') === 'true',
128
+ onRender(id, index, count) {
129
+ const progress = count > 1 ? (index * 100) / (count - 1) : 0;
130
+ shell.style.setProperty('--journey-progress', `${progress}%`);
131
+ if (liveRegion) {
132
+ const label = root.querySelector(`[data-step-id="${id}"] .step-label`);
133
+ liveRegion.textContent = `Showing step ${index + 1} of 7: ${label ? label.textContent : id}`;
134
+ }
135
+ },
136
+ });
137
+ if (!controller) return null;
138
+
139
+ const playButton = root.querySelector('[data-play-journey]');
140
+ const reducedMotion = typeof matchMedia === 'function'
141
+ && matchMedia('(prefers-reduced-motion: reduce)').matches;
142
+ let timer = null;
143
+
144
+ function stop() {
145
+ if (timer) clearInterval(timer);
146
+ timer = null;
147
+ shell.classList.remove('is-playing');
148
+ if (playButton) {
149
+ playButton.setAttribute('aria-pressed', 'false');
150
+ playButton.querySelector('span').textContent = 'Play the flow';
151
+ }
152
+ }
153
+
154
+ function advance() {
155
+ controller.move('next', false);
156
+ }
157
+
158
+ if (playButton) {
159
+ playButton.addEventListener('click', () => {
160
+ if (reducedMotion) {
161
+ advance();
162
+ return;
163
+ }
164
+ if (timer) {
165
+ stop();
166
+ return;
167
+ }
168
+ advance();
169
+ shell.classList.add('is-playing');
170
+ playButton.setAttribute('aria-pressed', 'true');
171
+ playButton.querySelector('span').textContent = 'Pause the flow';
172
+ timer = setInterval(advance, 3200);
173
+ });
174
+ }
175
+
176
+ doc.addEventListener('visibilitychange', () => {
177
+ if (doc.hidden) stop();
178
+ });
179
+ return controller;
180
+ }
181
+
182
+ function initArchitectureMap(doc) {
183
+ const root = doc.getElementById('architecture-map');
184
+ return setupSelectionGroup(root, {
185
+ itemSelector: '[data-map-node]',
186
+ panelSelector: '.map-detail',
187
+ dataKey: 'mapNode',
188
+ selectedAttribute: 'aria-pressed',
189
+ panelId: id => `map-detail-${id}`,
190
+ isInitiallySelected: item => item.getAttribute('aria-pressed') === 'true',
191
+ });
192
+ }
193
+
194
+ function init(doc) {
195
+ doc.documentElement.classList.remove('no-js');
196
+ doc.documentElement.classList.add('js');
197
+ const journey = initJourney(doc);
198
+ const architectureMap = initArchitectureMap(doc);
199
+ return { journey, architectureMap };
200
+ }
201
+
202
+ return {
203
+ createSelectionModel,
204
+ init,
205
+ initJourney,
206
+ initArchitectureMap,
207
+ };
208
+ });
package/docs/index.html CHANGED
@@ -27,6 +27,7 @@
27
27
  .cta-primary:hover { background: #79c0ff; }
28
28
  .cta-secondary { background: var(--surface); color: var(--text); border: 1px solid var(--border); }
29
29
  .cta-secondary:hover { border-color: var(--blue); color: var(--blue); }
30
+ .cta a:focus-visible, .feature-link:focus-visible { outline: 3px solid var(--yellow); outline-offset: 4px; }
30
31
 
31
32
  /* Container */
32
33
  .container { max-width: 1100px; margin: 0 auto; padding: 0 20px; }
@@ -43,6 +44,8 @@
43
44
  .feature { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 24px; }
44
45
  .feature h3 { color: var(--blue); font-size: 1em; margin-bottom: 6px; }
45
46
  .feature p { color: var(--muted); font-size: 13px; line-height: 1.5; }
47
+ .feature-link { color: inherit; text-decoration: none; transition: border-color 0.2s, transform 0.2s; }
48
+ .feature-link:hover { border-color: var(--blue); transform: translateY(-2px); }
46
49
 
47
50
  /* Scenario sections */
48
51
  .scenario { margin: 60px 0; }
@@ -93,6 +96,7 @@
93
96
  <div class="cta">
94
97
  <a href="https://www.npmjs.com/package/@yemi33/minions" class="cta-primary">Install from npm</a>
95
98
  <a href="#quickstart" class="cta-secondary">Quick Start</a>
99
+ <a href="demo/memory-system.html" class="cta-secondary">Explore the Memory System</a>
96
100
  </div>
97
101
  </div>
98
102
 
@@ -114,7 +118,7 @@
114
118
  <div class="feature"><h3>Multi-Stage Pipelines</h3><p>Chain tasks, meetings, plans, and more into automated workflows. Cron triggers or manual. Artifacts flow between stages.</p></div>
115
119
  <div class="feature"><h3>Review / Fix Loop</h3><p>After implementation, Minions can dispatch reviews, react to human PR comments, and send fixes back to the original author agent.</p></div>
116
120
  <div class="feature"><h3>Git Worktree Isolation</h3><p>Each agent works in its own worktree. No conflicts, no cross-contamination, safe parallel execution.</p></div>
117
- <div class="feature"><h3>Knowledge Consolidation</h3><p>Agent findings, quick notes, pinned notes, and feedback consolidate into team notes and a categorized knowledge base.</p></div>
121
+ <a class="feature feature-link" href="demo/memory-system.html"><h3>Interactive Memory System</h3><p>Follow findings from inbox consolidation through SQL/FTS5 retrieval, prompt bounds, provenance, fencing, and episodic capture.</p></a>
118
122
  <div class="feature"><h3>PR Integration</h3><p>Tracks Azure DevOps and GitHub PRs, including review votes, build status, merge status, human comments, and context-only links.</p></div>
119
123
  <div class="feature"><h3>Scheduled Tasks &amp; Watches</h3><p>Cron-style recurring work plus watches for PRs, work items, dispatches, meetings, pipelines, agents, and status changes.</p></div>
120
124
  <div class="feature"><h3>Command Center &amp; Doc Chat</h3><p>Natural language orchestration, persistent CC tabs, document Q&amp;A/editing, issue filing, routing updates, and local API actions.</p></div>
@@ -277,4 +281,3 @@ minions update</pre>
277
281
 
278
282
  </body>
279
283
  </html>
280
-
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.2420",
3
+ "version": "0.1.2421",
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"