@yemi33/minions 0.1.2437 → 0.1.2438
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/dashboard/js/render-kb.js +35 -3
- package/dashboard.js +13 -3
- package/package.json +1 -1
|
@@ -205,17 +205,32 @@ async function kbSweep() {
|
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
let _memorySearchUiLoading = false;
|
|
208
|
+
// Lazily loads /assets/memory-search.js, then opens the modal.
|
|
209
|
+
//
|
|
210
|
+
// Both failure paths matter (W-ms5dlone012i457a-c):
|
|
211
|
+
// - script.onerror -> the network/404 case
|
|
212
|
+
// - script.onload but window.MinionsMemorySearch still undefined -> the
|
|
213
|
+
// script was served but did not register (e.g. a truncated/empty body, or
|
|
214
|
+
// it threw while evaluating). Dereferencing .open() here used to raise an
|
|
215
|
+
// uncaught TypeError.
|
|
216
|
+
// In every path the loading latch must be cleared, otherwise the early-return
|
|
217
|
+
// below permanently and silently bricks the button for the rest of the session.
|
|
208
218
|
function openMemorySearchModal() {
|
|
209
219
|
if (window.MinionsMemorySearch) return window.MinionsMemorySearch.open();
|
|
210
220
|
if (_memorySearchUiLoading) return;
|
|
211
221
|
_memorySearchUiLoading = true;
|
|
212
222
|
const script = document.createElement('script');
|
|
213
223
|
script.src = '/assets/memory-search.js';
|
|
214
|
-
|
|
215
|
-
script.onerror = () => {
|
|
224
|
+
const fail = () => {
|
|
216
225
|
_memorySearchUiLoading = false;
|
|
217
226
|
showToast('kb-sweep-toast', 'Memory search UI failed to load', false);
|
|
218
227
|
};
|
|
228
|
+
script.onload = () => {
|
|
229
|
+
_memorySearchUiLoading = false;
|
|
230
|
+
if (!window.MinionsMemorySearch) return fail();
|
|
231
|
+
window.MinionsMemorySearch.open();
|
|
232
|
+
};
|
|
233
|
+
script.onerror = fail;
|
|
219
234
|
document.head.appendChild(script);
|
|
220
235
|
}
|
|
221
236
|
|
|
@@ -262,7 +277,24 @@ async function submitKbEntry(e) {
|
|
|
262
277
|
|
|
263
278
|
async function kbOpenItem(category, file) {
|
|
264
279
|
try {
|
|
265
|
-
const
|
|
280
|
+
const res = await fetch('/api/knowledge/' + category + '/' + encodeURIComponent(file));
|
|
281
|
+
// Without this check a 404/500 body was rendered as if it were the entry,
|
|
282
|
+
// and a 200-with-empty-body opened a completely blank modal with no error
|
|
283
|
+
// (W-ms5dlone012i457a-c). Surface the failure instead of rendering nothing.
|
|
284
|
+
if (!res.ok) {
|
|
285
|
+
document.getElementById('modal-title').textContent = file;
|
|
286
|
+
const failBody = document.getElementById('modal-body');
|
|
287
|
+
failBody.replaceChildren();
|
|
288
|
+
const msg = document.createElement('p');
|
|
289
|
+
msg.className = 'empty';
|
|
290
|
+
msg.textContent = res.status === 404
|
|
291
|
+
? 'This knowledge entry no longer exists on disk (404). It may have been renamed or swept.'
|
|
292
|
+
: 'Could not load this knowledge entry (HTTP ' + res.status + ').';
|
|
293
|
+
failBody.appendChild(msg);
|
|
294
|
+
document.getElementById('modal').classList.add('open');
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
const content = await res.text();
|
|
266
298
|
const display = content.replace(/^---[\s\S]*?---\n*/m, '');
|
|
267
299
|
document.getElementById('modal-title').textContent = file;
|
|
268
300
|
const modalBody = document.getElementById('modal-body');
|
package/dashboard.js
CHANGED
|
@@ -9080,7 +9080,11 @@ const server = http.createServer(async (req, res) => {
|
|
|
9080
9080
|
MINIONS_DIR,
|
|
9081
9081
|
);
|
|
9082
9082
|
const kbCatDir = path.join(MINIONS_DIR, 'knowledge', cat);
|
|
9083
|
-
|
|
9083
|
+
// safeReadOrNull (not safeRead): safeRead collapses ENOENT to '', which
|
|
9084
|
+
// made this 404 guard dead code and served a missing entry as 200 with an
|
|
9085
|
+
// empty body — render-kb.js#kbOpenItem then opened a blank modal with no
|
|
9086
|
+
// error. Present-but-empty still reads as '' and correctly returns 200.
|
|
9087
|
+
const content = safeReadOrNull(path.join(kbCatDir, file));
|
|
9084
9088
|
if (content === null) return jsonReply(res, 404, { error: 'not found', code: 'not-found' });
|
|
9085
9089
|
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
|
|
9086
9090
|
res.end(content);
|
|
@@ -15825,7 +15829,9 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
15825
15829
|
catch { return jsonReply(res, 400, { error: 'invalid path' }); }
|
|
15826
15830
|
const agentsDir = path.join(MINIONS_DIR, 'agents');
|
|
15827
15831
|
if (!safePath.startsWith(agentsDir + path.sep)) return jsonReply(res, 400, { error: 'path must be within agents/' });
|
|
15828
|
-
|
|
15832
|
+
// safeReadOrNull (not safeRead) so a missing log 404s instead of being
|
|
15833
|
+
// served as 200 with an empty body — see the KB read above.
|
|
15834
|
+
const content = _agentApiCall('readOutputFile', safeReadOrNull, safePath);
|
|
15829
15835
|
if (content === null) return jsonReply(res, 404, { error: 'not found' });
|
|
15830
15836
|
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
|
|
15831
15837
|
res.setHeader('Cache-Control', 'no-cache');
|
|
@@ -15834,7 +15840,11 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
15834
15840
|
|
|
15835
15841
|
// Knowledge base
|
|
15836
15842
|
{ method: 'GET', path: '/assets/memory-search.js', desc: 'Serve the lazy-loaded structured memory search UI', handler: (req, res) => {
|
|
15837
|
-
|
|
15843
|
+
// safeReadOrNull (not safeRead): a 200 with an empty body still fires
|
|
15844
|
+
// the loader's script.onload, leaving window.MinionsMemorySearch
|
|
15845
|
+
// undefined so openMemorySearchModal() throws. 404 lets script.onerror
|
|
15846
|
+
// surface the intended "failed to load" toast instead.
|
|
15847
|
+
const content = safeReadOrNull(path.join(MINIONS_DIR, 'dashboard', 'js', 'memory-search.js'));
|
|
15838
15848
|
if (content == null) { res.statusCode = 404; return res.end('not found'); }
|
|
15839
15849
|
res.setHeader('Content-Type', 'application/javascript; charset=utf-8');
|
|
15840
15850
|
res.setHeader('Cache-Control', 'no-cache');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2438",
|
|
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"
|