@yemi33/minions 0.1.2447 → 0.1.2448

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.
@@ -1175,9 +1175,14 @@ async function _ccDoSend(message, skipUserMsg, forceTabId, intentMetadata) {
1175
1175
 
1176
1176
  if (!skipUserMsg) addMsg('user', escHtml(message) + _ccAttachmentBadge(sendImages.length));
1177
1177
 
1178
- // Remove queue indicator before processing (it'll be re-added if more queued)
1179
- var existingQueueEl = document.getElementById('cc-queue-indicator');
1180
- if (existingQueueEl) existingQueueEl.remove();
1178
+ // NOTE: no queue-indicator teardown here on purpose. This used to remove a
1179
+ // single `#cc-queue-indicator` element, a vestige of an older one-node design;
1180
+ // that id has not existed since indicators became one `.cc-queue-item` node per
1181
+ // queued message, so the call was a silent no-op. _renderQueueIndicator() clears
1182
+ // every `.cc-queue-item` before re-rendering, so it solely owns their lifecycle.
1183
+ // Re-adding a removal here would wipe the indicators the drain loop and retry
1184
+ // path render for STILL-queued messages immediately before calling this
1185
+ // function, hiding them for the whole in-flight request.
1181
1186
 
1182
1187
  var ccStartTime = Date.now();
1183
1188
  var reconnectAttempts = 0;
@@ -28,7 +28,6 @@
28
28
  // navigates.
29
29
 
30
30
  let _qaRunsPollInterval = null;
31
- let _qaTargetsCache = [];
32
31
  let _qaRunbooksCache = [];
33
32
 
34
33
  function _stopQaRunsPoll() {
@@ -84,8 +83,6 @@ async function loadQaTargets() {
84
83
  '<p class="empty" style="color:var(--red)">Failed to load targets: ' + escHtml(err.message || String(err)) + '</p>'
85
84
  );
86
85
  root.replaceChildren(frag);
87
- _qaTargetsCache = [];
88
- _qaPopulateTargetDropdown();
89
86
  return;
90
87
  }
91
88
 
@@ -130,9 +127,6 @@ async function loadQaTargets() {
130
127
  });
131
128
  }
132
129
 
133
- _qaTargetsCache = targets;
134
- _qaPopulateTargetDropdown();
135
-
136
130
  if (!targets.length) {
137
131
  const frag = document.createRange().createContextualFragment(
138
132
  '<p class="empty">No live targets. Spawn a service via <code>meta.managed_spawn</code> or <code>meta.keep_processes</code> to populate this list. Full inventory on <a href="/engine">/engine</a>.</p>'
@@ -163,25 +157,13 @@ async function loadQaTargets() {
163
157
  root.replaceChildren(frag);
164
158
  }
165
159
 
166
- function _qaPopulateTargetDropdown() {
167
- const sel = document.getElementById('qa-runbook-target');
168
- if (!sel) return;
169
- const current = sel.value;
170
- // Build option nodes via DOM API no innerHTML.
171
- while (sel.firstChild) sel.removeChild(sel.firstChild);
172
- const placeholder = document.createElement('option');
173
- placeholder.value = '';
174
- placeholder.textContent = '— select a target —';
175
- sel.appendChild(placeholder);
176
- for (const t of _qaTargetsCache) {
177
- const opt = document.createElement('option');
178
- opt.value = t.name;
179
- const projLabel = t.project ? ' (' + t.project + ')' : '';
180
- opt.textContent = t.name + projLabel + ' [' + t.source + ']';
181
- sel.appendChild(opt);
182
- }
183
- if (current) sel.value = current;
184
- }
160
+ // W-mpxp7a3e000g0a49 removed the inline "Start QA Session" / runbook form from
161
+ // dashboard/pages/qa.html, taking the `qa-runbook-target` <select> with it
162
+ // (asserted absent by test/unit/qa-tab-ui.test.js). The _qaPopulateTargetDropdown
163
+ // helper that filled it was left behind as an unreachable no-op and has been
164
+ // deleted (W-ms5dlone012i457a-b), along with the `_qaTargetsCache` module state
165
+ // that existed only to feed it — loadQaTargets renders its rows directly.
166
+ // Runbook targets are chosen via Command Center.
185
167
 
186
168
  // ── Section 2: Runbooks ────────────────────────────────────────────────────
187
169
  async function loadQaRunbooks() {
@@ -44,21 +44,40 @@ const DASHBOARD_JS_FILES = [
44
44
  /**
45
45
  * Read a page fragment and substitute any sub-fragment markers declared for it.
46
46
  * Shared by both assemblers so a sub-fragment can never be wired into one only.
47
+ *
48
+ * When `sources` is an array, every file read here is pushed to it as
49
+ * `{file, content}` holding that file's RAW text — the parent separately from
50
+ * each sub-fragment — so static-audit callers can report violations against
51
+ * each source file's own true line numbers.
47
52
  */
48
- function readPageFragment(dashDir, page) {
49
- let content = safeRead(path.join(dashDir, 'pages', page + '.html'));
53
+ function readPageFragment(dashDir, page, sources) {
54
+ const raw = safeRead(path.join(dashDir, 'pages', page + '.html'));
55
+ let content = raw;
50
56
  const subs = DASHBOARD_PAGE_SUB_FRAGMENTS[page];
51
57
  if (subs) {
52
58
  for (const [marker, basename] of Object.entries(subs)) {
53
59
  const fragment = safeRead(path.join(dashDir, 'pages', basename + '.html'));
60
+ if (sources) sources.push({ file: `dashboard/pages/${basename}.html`, content: fragment });
54
61
  // Function replacer: fragment text may contain `$&`/`$1` patterns.
55
62
  content = content.replace(marker, () => fragment);
56
63
  }
57
64
  }
65
+ if (sources) sources.push({ file: `dashboard/pages/${page}.html`, content: raw });
58
66
  return content;
59
67
  }
60
68
 
61
- function buildDashboardHtml() {
69
+ /**
70
+ * Assemble the classic dashboard's constituent parts.
71
+ *
72
+ * Exported (as `_buildClassicParts`) so static-audit tests can inspect the exact
73
+ * page HTML and JS bundle the server ships without reimplementing — or drifting
74
+ * from — the concatenation performed here.
75
+ *
76
+ * @returns {{layout: string, css: string, pageHtml: string, jsHtml: string,
77
+ * jsSources: Array<{file: string, content: string}>,
78
+ * pageSources: Array<{file: string, content: string}>}}
79
+ */
80
+ function _buildClassicParts() {
62
81
  const dashDir = path.join(MINIONS_DIR, 'dashboard');
63
82
  const layoutPath = path.join(dashDir, 'layout.html');
64
83
 
@@ -69,25 +88,38 @@ function buildDashboardHtml() {
69
88
  const layout = safeRead(layoutPath);
70
89
  const css = safeRead(path.join(dashDir, 'styles.css'));
71
90
 
91
+ const pageSources = [];
72
92
  const pages = DASHBOARD_PAGES;
73
93
  let pageHtml = '';
74
94
  for (const p of pages) {
75
- const content = readPageFragment(dashDir, p);
95
+ // readPageFragment() collects each source file's RAW text into pageSources
96
+ // (parent and sub-fragments separately), so every file keeps its own true
97
+ // line numbers for violation reporting.
98
+ const content = readPageFragment(dashDir, p, pageSources);
76
99
  const activeClass = p === 'home' ? ' active' : '';
77
100
  pageHtml += ` <div class="page${activeClass}" id="page-${p}">\n${content}\n </div>\n\n`;
78
101
  }
79
102
 
103
+ const jsSources = [];
80
104
  const jsFiles = DASHBOARD_JS_FILES;
81
105
  let jsHtml = '';
82
106
  for (const f of DASHBOARD_SHARED_JS) {
83
107
  const content = safeRead(path.join(dashDir, 'shared', f + '.js'));
108
+ jsSources.push({ file: `dashboard/shared/${f}.js`, content });
84
109
  jsHtml += `\n// ─── shared/${f}.js ────────────────────────────────────────\n${content}\n`;
85
110
  }
86
111
  for (const f of jsFiles) {
87
112
  const content = safeRead(path.join(dashDir, 'js', f + '.js'));
113
+ jsSources.push({ file: `dashboard/js/${f}.js`, content });
88
114
  jsHtml += `\n// ─── ${f}.js ────────────────────────────────────────\n${content}\n`;
89
115
  }
90
116
 
117
+ return { layout, css, pageHtml, jsHtml, jsSources, pageSources };
118
+ }
119
+
120
+ function buildDashboardHtml() {
121
+ const { layout, css, pageHtml, jsHtml } = _buildClassicParts();
122
+
91
123
  // Use function replacer to avoid $ special patterns in String.replace
92
124
  return layout
93
125
  .replace('/* __CSS__ */', () => css)
@@ -206,5 +238,8 @@ module.exports = {
206
238
  DASHBOARD_JS_FILES,
207
239
  readPageFragment,
208
240
  SLIM_JS_ORDER,
241
+ CLASSIC_PAGES: DASHBOARD_PAGES,
242
+ CLASSIC_JS_FILES: DASHBOARD_JS_FILES,
243
+ _buildClassicParts,
209
244
  _resetSlimPartsCacheForTest,
210
245
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.2447",
3
+ "version": "0.1.2448",
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"