@theihtisham/agent-shadow-brain 6.0.0 → 6.0.3
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 +372 -0
- package/README.md +366 -355
- package/dist/brain/auto-update.js +1 -1
- package/dist/brain/brain-3d.d.ts +79 -0
- package/dist/brain/brain-3d.d.ts.map +1 -0
- package/dist/brain/brain-3d.js +468 -0
- package/dist/brain/brain-3d.js.map +1 -0
- package/dist/brain/brain-active-learner.d.ts +74 -0
- package/dist/brain/brain-active-learner.d.ts.map +1 -0
- package/dist/brain/brain-active-learner.js +425 -0
- package/dist/brain/brain-active-learner.js.map +1 -0
- package/dist/brain/brain-ascii.d.ts +32 -0
- package/dist/brain/brain-ascii.d.ts.map +1 -0
- package/dist/brain/brain-ascii.js +402 -0
- package/dist/brain/brain-ascii.js.map +1 -0
- package/dist/brain/brain-cinema.d.ts +45 -0
- package/dist/brain/brain-cinema.d.ts.map +1 -0
- package/dist/brain/brain-cinema.js +393 -0
- package/dist/brain/brain-cinema.js.map +1 -0
- package/dist/brain/brain-coach.d.ts +45 -0
- package/dist/brain/brain-coach.d.ts.map +1 -0
- package/dist/brain/brain-coach.js +383 -0
- package/dist/brain/brain-coach.js.map +1 -0
- package/dist/brain/brain-consolidator.d.ts +56 -0
- package/dist/brain/brain-consolidator.d.ts.map +1 -0
- package/dist/brain/brain-consolidator.js +386 -0
- package/dist/brain/brain-consolidator.js.map +1 -0
- package/dist/brain/brain-contradictions.d.ts +57 -0
- package/dist/brain/brain-contradictions.d.ts.map +1 -0
- package/dist/brain/brain-contradictions.js +443 -0
- package/dist/brain/brain-contradictions.js.map +1 -0
- package/dist/brain/brain-diff.d.ts +61 -0
- package/dist/brain/brain-diff.d.ts.map +1 -0
- package/dist/brain/brain-diff.js +439 -0
- package/dist/brain/brain-diff.js.map +1 -0
- package/dist/brain/brain-dna.d.ts +59 -0
- package/dist/brain/brain-dna.d.ts.map +1 -0
- package/dist/brain/brain-dna.js +336 -0
- package/dist/brain/brain-dna.js.map +1 -0
- package/dist/brain/brain-doppelganger.d.ts +32 -0
- package/dist/brain/brain-doppelganger.d.ts.map +1 -0
- package/dist/brain/brain-doppelganger.js +417 -0
- package/dist/brain/brain-doppelganger.js.map +1 -0
- package/dist/brain/brain-graph-walker.d.ts +54 -0
- package/dist/brain/brain-graph-walker.d.ts.map +1 -0
- package/dist/brain/brain-graph-walker.js +412 -0
- package/dist/brain/brain-graph-walker.js.map +1 -0
- package/dist/brain/brain-holiday-card.d.ts +50 -0
- package/dist/brain/brain-holiday-card.d.ts.map +1 -0
- package/dist/brain/brain-holiday-card.js +432 -0
- package/dist/brain/brain-holiday-card.js.map +1 -0
- package/dist/brain/brain-memes.d.ts +44 -0
- package/dist/brain/brain-memes.d.ts.map +1 -0
- package/dist/brain/brain-memes.js +438 -0
- package/dist/brain/brain-memes.js.map +1 -0
- package/dist/brain/brain-memory-tiers.d.ts +67 -0
- package/dist/brain/brain-memory-tiers.d.ts.map +1 -0
- package/dist/brain/brain-memory-tiers.js +292 -0
- package/dist/brain/brain-memory-tiers.js.map +1 -0
- package/dist/brain/brain-notebook.d.ts +68 -0
- package/dist/brain/brain-notebook.d.ts.map +1 -0
- package/dist/brain/brain-notebook.js +379 -0
- package/dist/brain/brain-notebook.js.map +1 -0
- package/dist/brain/brain-portability.js +3 -3
- package/dist/brain/brain-portability.js.map +1 -1
- package/dist/brain/brain-quantize.d.ts +62 -0
- package/dist/brain/brain-quantize.d.ts.map +1 -0
- package/dist/brain/brain-quantize.js +346 -0
- package/dist/brain/brain-quantize.js.map +1 -0
- package/dist/brain/brain-query-expander.d.ts +31 -0
- package/dist/brain/brain-query-expander.d.ts.map +1 -0
- package/dist/brain/brain-query-expander.js +417 -0
- package/dist/brain/brain-query-expander.js.map +1 -0
- package/dist/brain/brain-quest.d.ts +58 -0
- package/dist/brain/brain-quest.d.ts.map +1 -0
- package/dist/brain/brain-quest.js +541 -0
- package/dist/brain/brain-quest.js.map +1 -0
- package/dist/brain/brain-recall-cache.d.ts +73 -0
- package/dist/brain/brain-recall-cache.d.ts.map +1 -0
- package/dist/brain/brain-recall-cache.js +444 -0
- package/dist/brain/brain-recall-cache.js.map +1 -0
- package/dist/brain/brain-reflex.d.ts +55 -0
- package/dist/brain/brain-reflex.d.ts.map +1 -0
- package/dist/brain/brain-reflex.js +364 -0
- package/dist/brain/brain-reflex.js.map +1 -0
- package/dist/brain/brain-replay.d.ts +74 -0
- package/dist/brain/brain-replay.d.ts.map +1 -0
- package/dist/brain/brain-replay.js +336 -0
- package/dist/brain/brain-replay.js.map +1 -0
- package/dist/brain/brain-rerank.d.ts +39 -0
- package/dist/brain/brain-rerank.d.ts.map +1 -0
- package/dist/brain/brain-rerank.js +216 -0
- package/dist/brain/brain-rerank.js.map +1 -0
- package/dist/brain/brain-roast.d.ts +44 -0
- package/dist/brain/brain-roast.d.ts.map +1 -0
- package/dist/brain/brain-roast.js +566 -0
- package/dist/brain/brain-roast.js.map +1 -0
- package/dist/brain/brain-sonification.d.ts +57 -0
- package/dist/brain/brain-sonification.d.ts.map +1 -0
- package/dist/brain/brain-sonification.js +286 -0
- package/dist/brain/brain-sonification.js.map +1 -0
- package/dist/brain/brain-tarot.d.ts +49 -0
- package/dist/brain/brain-tarot.d.ts.map +1 -0
- package/dist/brain/brain-tarot.js +634 -0
- package/dist/brain/brain-tarot.js.map +1 -0
- package/dist/brain/brain-time-capsule.d.ts +80 -0
- package/dist/brain/brain-time-capsule.d.ts.map +1 -0
- package/dist/brain/brain-time-capsule.js +289 -0
- package/dist/brain/brain-time-capsule.js.map +1 -0
- package/dist/brain/brain-trophies.d.ts +60 -0
- package/dist/brain/brain-trophies.d.ts.map +1 -0
- package/dist/brain/brain-trophies.js +431 -0
- package/dist/brain/brain-trophies.js.map +1 -0
- package/dist/brain/brain-working-memory.d.ts +78 -0
- package/dist/brain/brain-working-memory.d.ts.map +1 -0
- package/dist/brain/brain-working-memory.js +367 -0
- package/dist/brain/brain-working-memory.js.map +1 -0
- package/dist/brain/confidence-gate.d.ts +69 -0
- package/dist/brain/confidence-gate.d.ts.map +1 -0
- package/dist/brain/confidence-gate.js +244 -0
- package/dist/brain/confidence-gate.js.map +1 -0
- package/dist/brain/constitution.d.ts +59 -0
- package/dist/brain/constitution.d.ts.map +1 -0
- package/dist/brain/constitution.js +315 -0
- package/dist/brain/constitution.js.map +1 -0
- package/dist/brain/context-continuity.d.ts +78 -0
- package/dist/brain/context-continuity.d.ts.map +1 -0
- package/dist/brain/context-continuity.js +341 -0
- package/dist/brain/context-continuity.js.map +1 -0
- package/dist/brain/embeddings-v2.d.ts +58 -0
- package/dist/brain/embeddings-v2.d.ts.map +1 -0
- package/dist/brain/embeddings-v2.js +344 -0
- package/dist/brain/embeddings-v2.js.map +1 -0
- package/dist/brain/global-brain.d.ts.map +1 -1
- package/dist/brain/global-brain.js +35 -9
- package/dist/brain/global-brain.js.map +1 -1
- package/dist/brain/hive-voice.d.ts +71 -0
- package/dist/brain/hive-voice.d.ts.map +1 -0
- package/dist/brain/hive-voice.js +352 -0
- package/dist/brain/hive-voice.js.map +1 -0
- package/dist/brain/live-brain.d.ts +119 -0
- package/dist/brain/live-brain.d.ts.map +1 -0
- package/dist/brain/live-brain.js +405 -0
- package/dist/brain/live-brain.js.map +1 -0
- package/dist/brain/markdown-export.d.ts +48 -0
- package/dist/brain/markdown-export.d.ts.map +1 -0
- package/dist/brain/markdown-export.js +382 -0
- package/dist/brain/markdown-export.js.map +1 -0
- package/dist/brain/mcp-server.d.ts +4 -0
- package/dist/brain/mcp-server.d.ts.map +1 -1
- package/dist/brain/mcp-server.js +81 -5
- package/dist/brain/mcp-server.js.map +1 -1
- package/dist/brain/memory-seeder.d.ts +78 -0
- package/dist/brain/memory-seeder.d.ts.map +1 -0
- package/dist/brain/memory-seeder.js +326 -0
- package/dist/brain/memory-seeder.js.map +1 -0
- package/dist/brain/multimodal-vision.d.ts +38 -0
- package/dist/brain/multimodal-vision.d.ts.map +1 -0
- package/dist/brain/multimodal-vision.js +257 -0
- package/dist/brain/multimodal-vision.js.map +1 -0
- package/dist/brain/orchestrator.js +1 -1
- package/dist/brain/otel-lite.d.ts +71 -0
- package/dist/brain/otel-lite.d.ts.map +1 -0
- package/dist/brain/otel-lite.js +232 -0
- package/dist/brain/otel-lite.js.map +1 -0
- package/dist/brain/token-economy.d.ts +2 -0
- package/dist/brain/token-economy.d.ts.map +1 -1
- package/dist/brain/token-economy.js +80 -24
- package/dist/brain/token-economy.js.map +1 -1
- package/dist/cli.js +1120 -32
- package/dist/cli.js.map +1 -1
- package/dist/dashboard/server.d.ts +5 -0
- package/dist/dashboard/server.d.ts.map +1 -1
- package/dist/dashboard/server.js +355 -2
- package/dist/dashboard/server.js.map +1 -1
- package/dist/dashboard/v6-dashboard-html.d.ts +1 -1
- package/dist/dashboard/v6-dashboard-html.d.ts.map +1 -1
- package/dist/dashboard/v6-dashboard-html.js +755 -85
- package/dist/dashboard/v6-dashboard-html.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +17 -12
- package/dist/types.d.ts.map +1 -1
- package/docs/launch/README.md +61 -0
- package/docs/launch/RELEASE_CHECKLIST_v6.0.3.md +102 -0
- package/docs/launch/RELEASE_NOTES_v6.0.3.md +111 -0
- package/package.json +25 -13
- package/tools/export-resume-pack.mjs +56 -0
- package/tools/record-global-memory.mjs +72 -0
|
@@ -397,12 +397,80 @@ export const V6_DASHBOARD_HTML = `<!DOCTYPE html>
|
|
|
397
397
|
.stat-card .label { font-size: 11px; color: var(--text-3); text-transform: uppercase; letter-spacing: 0.06em; font-weight: 700; }
|
|
398
398
|
.stat-card .value { font-size: 32px; font-weight: 900; letter-spacing: -1px; margin: 6px 0 4px; font-variant-numeric: tabular-nums; }
|
|
399
399
|
.stat-card .value.accent { background: var(--brand-gradient); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; }
|
|
400
|
-
.stat-card .trend { font-size: 11px; color: var(--text-2); display: flex; align-items: center; gap: 4px; }
|
|
401
|
-
.stat-card .trend.up { color: var(--success); }
|
|
402
|
-
.stat-card .trend.down { color: var(--danger); }
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
400
|
+
.stat-card .trend { font-size: 11px; color: var(--text-2); display: flex; align-items: center; gap: 4px; }
|
|
401
|
+
.stat-card .trend.up { color: var(--success); }
|
|
402
|
+
.stat-card .trend.down { color: var(--danger); }
|
|
403
|
+
|
|
404
|
+
.workflow-strip {
|
|
405
|
+
display: grid;
|
|
406
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
407
|
+
gap: 12px;
|
|
408
|
+
align-items: end;
|
|
409
|
+
margin-bottom: 16px;
|
|
410
|
+
}
|
|
411
|
+
.workflow-path {
|
|
412
|
+
font-family: var(--font-mono);
|
|
413
|
+
font-size: 12px;
|
|
414
|
+
color: var(--text-2);
|
|
415
|
+
background: var(--bg-elev-1);
|
|
416
|
+
border: 1px solid var(--border);
|
|
417
|
+
border-radius: 8px;
|
|
418
|
+
padding: 10px 12px;
|
|
419
|
+
width: 100%;
|
|
420
|
+
}
|
|
421
|
+
.warning-stack { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
|
|
422
|
+
.warning-banner {
|
|
423
|
+
display: flex;
|
|
424
|
+
gap: 10px;
|
|
425
|
+
align-items: flex-start;
|
|
426
|
+
border: 1px solid rgba(217, 119, 6, 0.38);
|
|
427
|
+
background: rgba(217, 119, 6, 0.10);
|
|
428
|
+
color: var(--warning);
|
|
429
|
+
border-radius: 8px;
|
|
430
|
+
padding: 10px 12px;
|
|
431
|
+
font-size: 12px;
|
|
432
|
+
}
|
|
433
|
+
.brain-feed { display: flex; flex-direction: column; gap: 10px; }
|
|
434
|
+
.stack { display: flex; flex-direction: column; gap: 8px; }
|
|
435
|
+
.memory-item {
|
|
436
|
+
border: 1px solid var(--border);
|
|
437
|
+
background: var(--bg-elev-1);
|
|
438
|
+
border-radius: 8px;
|
|
439
|
+
padding: 10px 12px;
|
|
440
|
+
}
|
|
441
|
+
.memory-item .meta {
|
|
442
|
+
display: flex;
|
|
443
|
+
gap: 8px;
|
|
444
|
+
flex-wrap: wrap;
|
|
445
|
+
align-items: center;
|
|
446
|
+
margin-bottom: 6px;
|
|
447
|
+
font-size: 11px;
|
|
448
|
+
color: var(--text-3);
|
|
449
|
+
}
|
|
450
|
+
.memory-item .content {
|
|
451
|
+
color: var(--text-2);
|
|
452
|
+
font-size: 12px;
|
|
453
|
+
line-height: 1.45;
|
|
454
|
+
word-break: break-word;
|
|
455
|
+
}
|
|
456
|
+
.ops-agent-grid {
|
|
457
|
+
display: grid;
|
|
458
|
+
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
459
|
+
gap: 8px;
|
|
460
|
+
}
|
|
461
|
+
.ops-agent {
|
|
462
|
+
border: 1px solid var(--border);
|
|
463
|
+
background: var(--bg-elev-1);
|
|
464
|
+
border-radius: 8px;
|
|
465
|
+
padding: 9px 10px;
|
|
466
|
+
font-size: 12px;
|
|
467
|
+
}
|
|
468
|
+
.ops-agent .name { font-weight: 700; margin-bottom: 5px; }
|
|
469
|
+
.ops-agent .status { display: flex; gap: 6px; flex-wrap: wrap; }
|
|
470
|
+
.empty-tight { color: var(--text-3); padding: 18px 4px; font-size: 12px; text-align: center; }
|
|
471
|
+
|
|
472
|
+
/* ──────────────────────────────────────────────────────────────────── */
|
|
473
|
+
/* Rows, pills, badges */
|
|
406
474
|
/* ──────────────────────────────────────────────────────────────────── */
|
|
407
475
|
.row {
|
|
408
476
|
display: flex; justify-content: space-between; align-items: center;
|
|
@@ -824,24 +892,36 @@ export const V6_DASHBOARD_HTML = `<!DOCTYPE html>
|
|
|
824
892
|
<aside class="sidebar" id="sidebar">
|
|
825
893
|
<div class="nav-group">
|
|
826
894
|
<div class="nav-group-label">Overview</div>
|
|
827
|
-
<button class="nav-item active" data-tab="overview" data-title="Overview" data-icon="activity">
|
|
828
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>
|
|
829
|
-
Dashboard
|
|
830
|
-
</button>
|
|
831
|
-
<button class="nav-item" data-tab="
|
|
832
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><
|
|
833
|
-
|
|
834
|
-
</button>
|
|
895
|
+
<button class="nav-item active" data-tab="overview" data-title="Overview" data-icon="activity">
|
|
896
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>
|
|
897
|
+
Dashboard
|
|
898
|
+
</button>
|
|
899
|
+
<button class="nav-item" data-tab="ww2br" data-title="WW2BR Brain">
|
|
900
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19V5"/><path d="M4 6h9l1 2h6v8h-9l-1-2H4"/></svg>
|
|
901
|
+
WW2BR Brain<span class="badge-count" id="badge-ww2br">0</span>
|
|
902
|
+
</button>
|
|
903
|
+
<button class="nav-item" data-tab="graph" data-title="Live Graph">
|
|
904
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><circle cx="12" cy="12" r="8"/></svg>
|
|
905
|
+
Live Graph
|
|
906
|
+
</button>
|
|
835
907
|
<button class="nav-item" data-tab="agents" data-title="Agents">
|
|
836
908
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
|
|
837
909
|
Agents<span class="badge-count" id="badge-agents">0</span>
|
|
838
910
|
</button>
|
|
839
911
|
<button class="nav-item" data-tab="chat" data-title="Chat with Brain"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>Chat with Brain</button>
|
|
840
|
-
<button class="nav-item" data-tab="memory" data-title="Memory Browser">
|
|
841
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"/><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/></svg>
|
|
842
|
-
Memory Browser
|
|
843
|
-
</button>
|
|
844
|
-
<button class="nav-item" data-tab="
|
|
912
|
+
<button class="nav-item" data-tab="memory" data-title="Memory Browser">
|
|
913
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"/><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/></svg>
|
|
914
|
+
Memory Browser
|
|
915
|
+
</button>
|
|
916
|
+
<button class="nav-item" data-tab="seeder" data-title="Memory Seeder">
|
|
917
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v20"/><path d="M5 9c0-3 2-5 7-7 5 2 7 4 7 7 0 5-4 8-7 8s-7-3-7-8z"/><path d="M8 12h8"/></svg>
|
|
918
|
+
Memory Seeder<span class="badge-count" id="badge-seeder">0</span>
|
|
919
|
+
</button>
|
|
920
|
+
<button class="nav-item" data-tab="livebrain" data-title="Live Brain">
|
|
921
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v4"/><path d="M12 18v4"/><path d="m4.93 4.93 2.83 2.83"/><path d="m16.24 16.24 2.83 2.83"/><path d="M2 12h4"/><path d="M18 12h4"/><circle cx="12" cy="12" r="5"/></svg>
|
|
922
|
+
Live Brain
|
|
923
|
+
</button>
|
|
924
|
+
<button class="nav-item" data-tab="activity" data-title="Activity Log">
|
|
845
925
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></svg>
|
|
846
926
|
Activity Log
|
|
847
927
|
</button>
|
|
@@ -928,7 +1008,7 @@ export const V6_DASHBOARD_HTML = `<!DOCTYPE html>
|
|
|
928
1008
|
|
|
929
1009
|
<div class="grid cols-3 mt-lg">
|
|
930
1010
|
<div class="card span-2">
|
|
931
|
-
<div class="card-header"><div class="card-title"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="20" x2="12" y2="10"/><line x1="18" y1="20" x2="18" y2="4"/><line x1="6" y1="20" x2="6" y2="16"/></svg>
|
|
1011
|
+
<div class="card-header"><div class="card-title"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="20" x2="12" y2="10"/><line x1="18" y1="20" x2="18" y2="4"/><line x1="6" y1="20" x2="6" y2="16"/></svg>Historical Recorded Spend by Agent (last 7 days)</div></div>
|
|
932
1012
|
<div class="chart-wrap"><canvas id="chart-tokens"></canvas></div>
|
|
933
1013
|
</div>
|
|
934
1014
|
<div class="card">
|
|
@@ -950,7 +1030,105 @@ export const V6_DASHBOARD_HTML = `<!DOCTYPE html>
|
|
|
950
1030
|
</section>
|
|
951
1031
|
|
|
952
1032
|
<!-- ════ LIVE GRAPH ══════════════════════════════════════════════ -->
|
|
953
|
-
|
|
1033
|
+
<!-- WW2BR BRAIN -->
|
|
1034
|
+
<section class="section" id="tab-ww2br">
|
|
1035
|
+
<div class="accent-bar"></div>
|
|
1036
|
+
<div class="section-header">
|
|
1037
|
+
<div>
|
|
1038
|
+
<h1 class="section-title">WW2BR Brain View</h1>
|
|
1039
|
+
<div class="section-subtitle">Live project memory, recall, and integration status for the current game-development workflow</div>
|
|
1040
|
+
</div>
|
|
1041
|
+
<div class="section-actions">
|
|
1042
|
+
<button class="btn primary" onclick="refreshWW2BR()">Refresh</button>
|
|
1043
|
+
</div>
|
|
1044
|
+
</div>
|
|
1045
|
+
|
|
1046
|
+
<div class="workflow-strip">
|
|
1047
|
+
<div>
|
|
1048
|
+
<div class="field" style="margin:0">
|
|
1049
|
+
<label>Active project path</label>
|
|
1050
|
+
<input class="workflow-path" id="ww2-project-path" value="D:\\New Game"/>
|
|
1051
|
+
</div>
|
|
1052
|
+
</div>
|
|
1053
|
+
<button class="btn" onclick="refreshWW2BR()">Load</button>
|
|
1054
|
+
</div>
|
|
1055
|
+
|
|
1056
|
+
<div id="ww2-warnings" class="warning-stack"></div>
|
|
1057
|
+
|
|
1058
|
+
<div class="grid cols-4">
|
|
1059
|
+
<div class="card stat-card">
|
|
1060
|
+
<div class="label">Global Memories</div>
|
|
1061
|
+
<div class="value accent" id="ww2-stat-memories">0</div>
|
|
1062
|
+
<div class="trend" id="ww2-stat-scope">project scoped</div>
|
|
1063
|
+
</div>
|
|
1064
|
+
<div class="card stat-card">
|
|
1065
|
+
<div class="label">Brain Projects</div>
|
|
1066
|
+
<div class="value" id="ww2-stat-projects">0</div>
|
|
1067
|
+
<div class="trend">known roots</div>
|
|
1068
|
+
</div>
|
|
1069
|
+
<div class="card stat-card">
|
|
1070
|
+
<div class="label">Agent Hooks</div>
|
|
1071
|
+
<div class="value" id="ww2-stat-hooks">0</div>
|
|
1072
|
+
<div class="trend">wired for this path</div>
|
|
1073
|
+
</div>
|
|
1074
|
+
<div class="card stat-card">
|
|
1075
|
+
<div class="label">Hit Rate</div>
|
|
1076
|
+
<div class="value" id="ww2-stat-hit">0%</div>
|
|
1077
|
+
<div class="trend" id="ww2-stat-sync">last sync unknown</div>
|
|
1078
|
+
</div>
|
|
1079
|
+
</div>
|
|
1080
|
+
|
|
1081
|
+
<div class="grid cols-3 mt-lg">
|
|
1082
|
+
<div class="card">
|
|
1083
|
+
<div class="card-header"><div class="card-title">Memory Quality</div></div>
|
|
1084
|
+
<div id="ww2-quality" class="stack"></div>
|
|
1085
|
+
</div>
|
|
1086
|
+
<div class="card span-2">
|
|
1087
|
+
<div class="card-header">
|
|
1088
|
+
<div class="card-title">Context Continuity Pack</div>
|
|
1089
|
+
<button class="btn sm" onclick="openWW2ResumePack()">Markdown</button>
|
|
1090
|
+
</div>
|
|
1091
|
+
<div id="ww2-resume-pack"></div>
|
|
1092
|
+
</div>
|
|
1093
|
+
</div>
|
|
1094
|
+
|
|
1095
|
+
<div class="grid cols-3 mt-lg">
|
|
1096
|
+
<div class="card span-2">
|
|
1097
|
+
<div class="card-header">
|
|
1098
|
+
<div class="card-title">Recent Brain Timeline</div>
|
|
1099
|
+
<button class="btn sm" onclick="refreshWW2BR()">Refresh</button>
|
|
1100
|
+
</div>
|
|
1101
|
+
<div id="ww2-timeline" class="brain-feed"></div>
|
|
1102
|
+
</div>
|
|
1103
|
+
<div class="card">
|
|
1104
|
+
<div class="card-header"><div class="card-title">Agent Integrations</div></div>
|
|
1105
|
+
<div id="ww2-agents" class="ops-agent-grid"></div>
|
|
1106
|
+
</div>
|
|
1107
|
+
</div>
|
|
1108
|
+
|
|
1109
|
+
<div class="grid cols-3 mt-lg">
|
|
1110
|
+
<div class="card">
|
|
1111
|
+
<div class="card-header"><div class="card-title">Memory Categories</div></div>
|
|
1112
|
+
<div id="ww2-categories"></div>
|
|
1113
|
+
</div>
|
|
1114
|
+
<div class="card span-2">
|
|
1115
|
+
<div class="card-header"><div class="card-title">Recall Query</div></div>
|
|
1116
|
+
<div class="grid cols-3">
|
|
1117
|
+
<div class="field span-2"><label>Query</label><input id="ww2-query" placeholder="Gate 2, operator proof, lobby blocker"/></div>
|
|
1118
|
+
<div class="field"><label>Category</label><input id="ww2-category" placeholder="optional"/></div>
|
|
1119
|
+
</div>
|
|
1120
|
+
<div class="flex gap">
|
|
1121
|
+
<button class="btn primary" onclick="runWW2Recall()">Recall</button>
|
|
1122
|
+
<button class="btn" onclick="setWW2Query('Gate 2 visual proof')">Gate 2</button>
|
|
1123
|
+
<button class="btn" onclick="setWW2Query('operator hands rifle hold')">Operator</button>
|
|
1124
|
+
<button class="btn" onclick="setWW2Query('lobby verification blockers')">Lobby</button>
|
|
1125
|
+
</div>
|
|
1126
|
+
<div id="ww2-recall-results" class="brain-feed mt"></div>
|
|
1127
|
+
</div>
|
|
1128
|
+
</div>
|
|
1129
|
+
</section>
|
|
1130
|
+
|
|
1131
|
+
<section class="section" id="tab-graph">
|
|
954
1132
|
<div class="accent-bar"></div>
|
|
955
1133
|
<div class="section-header">
|
|
956
1134
|
<div>
|
|
@@ -1027,7 +1205,7 @@ export const V6_DASHBOARD_HTML = `<!DOCTYPE html>
|
|
|
1027
1205
|
<div class="section-header">
|
|
1028
1206
|
<div>
|
|
1029
1207
|
<h1 class="section-title">Memory Browser</h1>
|
|
1030
|
-
<div class="section-subtitle">Full-text search
|
|
1208
|
+
<div class="section-subtitle">Full-text search plus live memory quality, provenance, freshness, and agent coverage</div>
|
|
1031
1209
|
</div>
|
|
1032
1210
|
</div>
|
|
1033
1211
|
<div class="card">
|
|
@@ -1044,10 +1222,119 @@ export const V6_DASHBOARD_HTML = `<!DOCTYPE html>
|
|
|
1044
1222
|
<tbody id="mem-results"></tbody>
|
|
1045
1223
|
</table>
|
|
1046
1224
|
</div>
|
|
1047
|
-
</section>
|
|
1048
|
-
|
|
1049
|
-
<!-- ════
|
|
1050
|
-
|
|
1225
|
+
</section>
|
|
1226
|
+
|
|
1227
|
+
<!-- ════ LIVE BRAIN ═══════════════════════════════════════════════ -->
|
|
1228
|
+
<!-- MEMORY SEEDER -->
|
|
1229
|
+
<section class="section" id="tab-seeder">
|
|
1230
|
+
<div class="accent-bar"></div>
|
|
1231
|
+
<div class="section-header">
|
|
1232
|
+
<div>
|
|
1233
|
+
<h1 class="section-title">Memory Seeder</h1>
|
|
1234
|
+
<div class="section-subtitle">Research drafts, approval gates, and source-backed global brain writes</div>
|
|
1235
|
+
</div>
|
|
1236
|
+
<div class="section-actions">
|
|
1237
|
+
<button class="btn" onclick="refreshSeedDrafts()">Refresh</button>
|
|
1238
|
+
</div>
|
|
1239
|
+
</div>
|
|
1240
|
+
|
|
1241
|
+
<div class="grid cols-3">
|
|
1242
|
+
<div class="card span-2">
|
|
1243
|
+
<div class="card-header"><div class="card-title">Seed Research Draft</div></div>
|
|
1244
|
+
<div class="grid cols-2">
|
|
1245
|
+
<div class="field"><label>Project path</label><input id="seed-project-path" placeholder="C:\\path\\to\\project"/></div>
|
|
1246
|
+
<div class="field"><label>Topic</label><input id="seed-topic" placeholder="memory routing, architecture, release, debugging"/></div>
|
|
1247
|
+
</div>
|
|
1248
|
+
<div class="field"><label>Objective</label><input id="seed-objective" placeholder="what the next agent must learn and reuse"/></div>
|
|
1249
|
+
<div class="grid cols-3">
|
|
1250
|
+
<div class="field"><label>Research agent</label><select id="seed-research-agent"><option>codex</option><option>claude-code</option><option>cursor</option><option>cline</option><option>copilot</option><option>windsurf</option><option>kilo-code</option><option>roo-code</option><option>aider</option><option>opencode</option></select></div>
|
|
1251
|
+
<div class="field"><label>Approver</label><select id="seed-approver-agent"><option>user</option><option>codex</option><option>claude-code</option><option>cursor</option><option>cline</option><option>copilot</option><option>windsurf</option><option>kilo-code</option><option>roo-code</option><option>aider</option><option>opencode</option></select></div>
|
|
1252
|
+
<div class="field"><label>Approval mode</label><select id="seed-approval-mode"><option>user</option><option>agent</option><option>dual</option></select></div>
|
|
1253
|
+
</div>
|
|
1254
|
+
<div class="grid cols-3">
|
|
1255
|
+
<div class="field"><label>Category</label><input id="seed-category" value="project.research"/></div>
|
|
1256
|
+
<div class="field"><label>Tags</label><input id="seed-tags" placeholder="enterprise,memory,release"/></div>
|
|
1257
|
+
<div class="field"><label>Importance</label><input id="seed-importance" type="number" min="0.05" max="1" step="0.05" value="0.78"/></div>
|
|
1258
|
+
</div>
|
|
1259
|
+
<div class="field"><label>Sources</label><textarea id="seed-sources" rows="2" placeholder="README.md, CHANGELOG.md, docs/launch/RELEASE_NOTES_v6.0.3.md"></textarea></div>
|
|
1260
|
+
<div class="field"><label>Research notes</label><textarea id="seed-content" rows="4" placeholder="facts, constraints, tradeoffs, exact commands, source-backed decisions"></textarea></div>
|
|
1261
|
+
<div class="flex gap">
|
|
1262
|
+
<button class="btn primary" onclick="createSeedDraft()">Create Draft</button>
|
|
1263
|
+
<button class="btn" onclick="copyLivePathToSeeder()">Use Live Brain Path</button>
|
|
1264
|
+
</div>
|
|
1265
|
+
</div>
|
|
1266
|
+
<div class="card">
|
|
1267
|
+
<div class="card-header"><div class="card-title">Seeder Status</div></div>
|
|
1268
|
+
<div id="seed-status" class="stack"></div>
|
|
1269
|
+
</div>
|
|
1270
|
+
</div>
|
|
1271
|
+
|
|
1272
|
+
<div class="card mt-lg">
|
|
1273
|
+
<div class="card-header">
|
|
1274
|
+
<div class="card-title">Approval Queue</div>
|
|
1275
|
+
<button class="btn sm" onclick="refreshSeedDrafts()">Refresh</button>
|
|
1276
|
+
</div>
|
|
1277
|
+
<div id="seed-drafts" class="brain-feed"></div>
|
|
1278
|
+
</div>
|
|
1279
|
+
</section>
|
|
1280
|
+
|
|
1281
|
+
<section class="section" id="tab-livebrain">
|
|
1282
|
+
<div class="accent-bar"></div>
|
|
1283
|
+
<div class="section-header">
|
|
1284
|
+
<div>
|
|
1285
|
+
<h1 class="section-title">Live Brain</h1>
|
|
1286
|
+
<div class="section-subtitle">Memory health, source coverage, recall eval, and agent briefing for the current workspace</div>
|
|
1287
|
+
</div>
|
|
1288
|
+
<div class="section-actions">
|
|
1289
|
+
<button class="btn" onclick="openSeederForLiveBrain()">Seed Memory</button>
|
|
1290
|
+
<button class="btn primary" onclick="refreshLiveBrain()">Refresh</button>
|
|
1291
|
+
</div>
|
|
1292
|
+
</div>
|
|
1293
|
+
<div class="grid cols-4">
|
|
1294
|
+
<div class="card stat-card"><div class="label">Total Memories</div><div class="value" id="mem-total">0</div><div class="trend" id="mem-sampled">sampled</div></div>
|
|
1295
|
+
<div class="card stat-card"><div class="label">Source Coverage</div><div class="value" id="mem-source">0%</div><div class="trend">evidence-backed records</div></div>
|
|
1296
|
+
<div class="card stat-card"><div class="label">Fresh 7 Days</div><div class="value" id="mem-fresh">0</div><div class="trend">recent learning</div></div>
|
|
1297
|
+
<div class="card stat-card"><div class="label">Seed Queue</div><div class="value" id="mem-seed-open">0</div><div class="trend" id="mem-seed-sub">approval queue</div></div>
|
|
1298
|
+
</div>
|
|
1299
|
+
<div class="grid cols-3 mt">
|
|
1300
|
+
<div class="card"><div class="card-header"><div class="card-title">Top Categories</div></div><div id="mem-categories"></div></div>
|
|
1301
|
+
<div class="card"><div class="card-header"><div class="card-title">Agent Coverage</div></div><div id="mem-agents"></div></div>
|
|
1302
|
+
<div class="card"><div class="card-header"><div class="card-title">Top Tags</div></div><div id="mem-tags"></div></div>
|
|
1303
|
+
</div>
|
|
1304
|
+
<div class="card mt">
|
|
1305
|
+
<div class="field-row">
|
|
1306
|
+
<div class="field"><label>Project path</label><input id="live-project-path" placeholder="C:\\path\\to\\project"/></div>
|
|
1307
|
+
<div class="field"><label>Eval queries</label><input id="live-queries" placeholder="current blocker|do not repeat|verified command"/></div>
|
|
1308
|
+
</div>
|
|
1309
|
+
</div>
|
|
1310
|
+
<div class="grid cols-4 mt">
|
|
1311
|
+
<div class="card stat-card"><div class="label">Memories</div><div class="value" id="live-memories">0</div><div class="trend" id="live-scope">scope</div></div>
|
|
1312
|
+
<div class="card stat-card"><div class="label">Quality</div><div class="value" id="live-quality">0</div><div class="trend">average score</div></div>
|
|
1313
|
+
<div class="card stat-card"><div class="label">Sources</div><div class="value" id="live-sources">0%</div><div class="trend">coverage</div></div>
|
|
1314
|
+
<div class="card stat-card"><div class="label">Recall</div><div class="value" id="live-recall">0</div><div class="trend">avg hits/query</div></div>
|
|
1315
|
+
</div>
|
|
1316
|
+
<div class="grid cols-2 mt-lg">
|
|
1317
|
+
<div class="card">
|
|
1318
|
+
<div class="card-header"><div class="card-title">Recommended Actions</div></div>
|
|
1319
|
+
<div id="live-actions" class="stack"></div>
|
|
1320
|
+
</div>
|
|
1321
|
+
<div class="card">
|
|
1322
|
+
<div class="card-header"><div class="card-title">Recall Eval</div></div>
|
|
1323
|
+
<div id="live-eval" class="stack"></div>
|
|
1324
|
+
</div>
|
|
1325
|
+
<div class="card">
|
|
1326
|
+
<div class="card-header"><div class="card-title">Top Memories</div></div>
|
|
1327
|
+
<div id="live-top" class="stack"></div>
|
|
1328
|
+
</div>
|
|
1329
|
+
<div class="card">
|
|
1330
|
+
<div class="card-header"><div class="card-title">Agent Briefing</div></div>
|
|
1331
|
+
<pre class="mono" id="live-brief" style="max-height:360px;overflow:auto;background:var(--bg-elev-1);padding:12px;border-radius:6px;white-space:pre-wrap"></pre>
|
|
1332
|
+
</div>
|
|
1333
|
+
</div>
|
|
1334
|
+
</section>
|
|
1335
|
+
|
|
1336
|
+
<!-- ════ ACTIVITY LOG ════════════════════════════════════════════ -->
|
|
1337
|
+
<section class="section" id="tab-activity">
|
|
1051
1338
|
<div class="accent-bar"></div>
|
|
1052
1339
|
<div class="section-header">
|
|
1053
1340
|
<div>
|
|
@@ -1227,16 +1514,22 @@ export const V6_DASHBOARD_HTML = `<!DOCTYPE html>
|
|
|
1227
1514
|
<section class="section" id="tab-tokens">
|
|
1228
1515
|
<div class="accent-bar"></div>
|
|
1229
1516
|
<div class="section-header"><div><h1 class="section-title">Token Economy Engine</h1><div class="section-subtitle">Cross-agent spend tracking · savings suggestions · routing advice</div></div></div>
|
|
1230
|
-
<div class="grid cols-4">
|
|
1231
|
-
<div class="card stat-card"><div class="label">
|
|
1232
|
-
<div class="card stat-card"><div class="label">
|
|
1233
|
-
<div class="card stat-card"><div class="label">
|
|
1234
|
-
<div class="card stat-card"><div class="label">Total Calls</div><div class="value" id="tok-calls">—</div><div class="trend" id="tok-calls-sub"></div></div>
|
|
1235
|
-
</div>
|
|
1236
|
-
<div class="grid cols-2 mt
|
|
1237
|
-
<div class="card
|
|
1238
|
-
<div class="card
|
|
1239
|
-
</div>
|
|
1517
|
+
<div class="grid cols-4">
|
|
1518
|
+
<div class="card stat-card"><div class="label">Current Agent</div><div class="value" id="tok-agent">—</div><div class="trend" id="tok-runtime">runtime context</div></div>
|
|
1519
|
+
<div class="card stat-card"><div class="label">Total Spend</div><div class="value" id="tok-total">$—</div><div class="trend">all historical records</div></div>
|
|
1520
|
+
<div class="card stat-card"><div class="label">Last 7 Days</div><div class="value" id="tok-recent">$—</div><div class="trend">recent records only</div></div>
|
|
1521
|
+
<div class="card stat-card"><div class="label">Total Calls</div><div class="value" id="tok-calls">—</div><div class="trend" id="tok-calls-sub"></div></div>
|
|
1522
|
+
</div>
|
|
1523
|
+
<div class="grid cols-2 mt">
|
|
1524
|
+
<div class="card stat-card"><div class="label">Monthly Projection</div><div class="value" id="tok-proj">$—</div><div class="trend">from last 7 days</div></div>
|
|
1525
|
+
<div class="card stat-card"><div class="label">Savings Available</div><div class="value" style="color:var(--success)" id="tok-save">$—</div><div class="trend up">via smart routing</div></div>
|
|
1526
|
+
</div>
|
|
1527
|
+
<div class="warning-banner mt" id="tok-runtime-note"><strong>Accuracy</strong><span>Token records are historical. Current agent and model spend are shown separately.</span></div>
|
|
1528
|
+
<div class="grid cols-2 mt-lg">
|
|
1529
|
+
<div class="card"><div class="card-header"><div class="card-title">Recent Spend by Agent</div></div><div class="chart-wrap"><canvas id="chart-tokens-agent"></canvas></div><div id="tok-agent-table" class="mt"></div></div>
|
|
1530
|
+
<div class="card"><div class="card-header"><div class="card-title">Historical Spend by Model</div></div><div class="chart-wrap"><canvas id="chart-tokens-model"></canvas></div><div id="tok-model-table" class="mt"></div></div>
|
|
1531
|
+
<div class="card span-2"><div class="card-header"><div class="card-title">Savings Suggestions</div></div><div id="tok-suggestions"></div></div>
|
|
1532
|
+
</div>
|
|
1240
1533
|
</section>
|
|
1241
1534
|
|
|
1242
1535
|
<!-- ════ FORGET ══════════════════════════════════════════════════ -->
|
|
@@ -1528,8 +1821,8 @@ function switchTab(id, title) {
|
|
|
1528
1821
|
if (window.innerWidth <= 768) document.getElementById('sidebar').classList.remove('open');
|
|
1529
1822
|
onTabOpen(id);
|
|
1530
1823
|
}
|
|
1531
|
-
function onTabOpen(tab) {
|
|
1532
|
-
const fn = { overview: refreshOverview, graph: startGraph, agents: refreshAgents, memory: () => searchMemory(), chat: refreshChat, activity: refreshActivity,
|
|
1824
|
+
function onTabOpen(tab) {
|
|
1825
|
+
const fn = { overview: refreshOverview, ww2br: refreshWW2BR, graph: startGraph, agents: refreshAgents, memory: () => { refreshMemoryIntelligence(); searchMemory(); }, seeder: refreshSeedDrafts, livebrain: refreshLiveBrain, chat: refreshChat, activity: refreshActivity,
|
|
1533
1826
|
sabb: refreshSABB, causal: refreshCausal, collision: refreshCollision, dream: refreshDream, reputation: refreshReputation,
|
|
1534
1827
|
tokens: refreshTokens, forget: refreshForget, formal: null, calibration: refreshCalibration, branch: refreshBranch,
|
|
1535
1828
|
privacy: refreshPrivacy, garden: refreshGarden, team: refreshTeam, exchange: refreshExchange, features: refreshFeatures,
|
|
@@ -1564,10 +1857,22 @@ async function api(path, body) {
|
|
|
1564
1857
|
if (!res.ok) { toast('API error', res.status + ' ' + path, 'error'); return null; }
|
|
1565
1858
|
const ct = res.headers.get('content-type') || '';
|
|
1566
1859
|
return ct.includes('application/json') ? await res.json() : await res.text();
|
|
1567
|
-
} catch (err) { toast('Network error', err.message, 'error'); return null; }
|
|
1568
|
-
}
|
|
1569
|
-
|
|
1570
|
-
|
|
1860
|
+
} catch (err) { toast('Network error', err.message, 'error'); return null; }
|
|
1861
|
+
}
|
|
1862
|
+
function htmlEscape(value) {
|
|
1863
|
+
return String(value ?? '')
|
|
1864
|
+
.replace(/&/g, '&')
|
|
1865
|
+
.replace(/</g, '<')
|
|
1866
|
+
.replace(/>/g, '>')
|
|
1867
|
+
.replace(/"/g, '"')
|
|
1868
|
+
.replace(/'/g, ''');
|
|
1869
|
+
}
|
|
1870
|
+
function fmtDate(value) {
|
|
1871
|
+
const d = new Date(value);
|
|
1872
|
+
return Number.isNaN(d.getTime()) ? 'unknown' : d.toLocaleString();
|
|
1873
|
+
}
|
|
1874
|
+
|
|
1875
|
+
// ──── Toasts ───────────────────────────────────────────────────────────
|
|
1571
1876
|
function toast(title, body, variant='success') {
|
|
1572
1877
|
const c = document.getElementById('toast-container');
|
|
1573
1878
|
const icons = { success:'<path d="M20 6 9 17l-5-5"/>', warn:'<path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/>', error:'<circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/>', info:'<circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/>' };
|
|
@@ -1659,18 +1964,19 @@ async function refreshOverview() {
|
|
|
1659
1964
|
\`<div class="row"><span class="k">\${k}</span><span class="v \${cls || ''}">\${v}</span></div>\`
|
|
1660
1965
|
).join('');
|
|
1661
1966
|
|
|
1662
|
-
const health = [
|
|
1663
|
-
['Local-first', hive.localFirst ? 'ON' : 'OFF', hive.localFirst ? 'good' : 'warn'],
|
|
1664
|
-
['
|
|
1665
|
-
['
|
|
1666
|
-
['
|
|
1967
|
+
const health = [
|
|
1968
|
+
['Local-first', hive.localFirst ? 'ON' : 'OFF', hive.localFirst ? 'good' : 'warn'],
|
|
1969
|
+
['Current agent', hive.runtime?.currentAgentDisplay || 'Unknown', hive.runtime?.currentAgentTool === 'codex' ? 'good' : ''],
|
|
1970
|
+
['Air-gap', hive.modules.airGap?.enabled ? 'ENABLED' : 'disabled', hive.modules.airGap?.enabled ? 'good' : ''],
|
|
1971
|
+
['Version', hive.version, ''],
|
|
1972
|
+
['Monthly cost', '$' + (hive.modules.tokenEconomy?.monthlyProjectionUsd?.toFixed?.(2) ?? '0.00'), 'warn'],
|
|
1667
1973
|
['Cost saved/mo', '$' + (hive.modules.tokenEconomy?.savingsOpportunitiesUsd?.toFixed?.(2) ?? '0.00'), 'good'],
|
|
1668
1974
|
];
|
|
1669
1975
|
document.getElementById('ov-health').innerHTML = health.map(([k, v, cls]) => \`<div class="row"><span class="k">\${k}</span><span class="v \${cls}">\${v}</span></div>\`).join('');
|
|
1670
1976
|
|
|
1671
1977
|
// Tokens chart
|
|
1672
|
-
const tok = hive.modules.tokenEconomy;
|
|
1673
|
-
if (tok
|
|
1978
|
+
const tok = hive.modules.tokenEconomy;
|
|
1979
|
+
if (tok) drawTokensChart(tok.recentByAgent || tok.byAgent || {});
|
|
1674
1980
|
|
|
1675
1981
|
// Timeline
|
|
1676
1982
|
const timeline = await api('/api/v6/activity-log?limit=15') ?? [];
|
|
@@ -1678,38 +1984,191 @@ async function refreshOverview() {
|
|
|
1678
1984
|
? timeline.slice(0, 10).map(e => \`<div style="padding:5px 0;border-bottom:1px solid var(--border);display:flex;gap:8px"><span style="color:var(--text-dim);flex-shrink:0">\${new Date(e.timestamp).toLocaleTimeString()}</span><span class="pill \${typeToPill(e.type)}">\${e.type}</span><span style="color:var(--text-2);font-size:11px">\${(e.detail||'').slice(0,90)}</span></div>\`).join('')
|
|
1679
1985
|
: '<div class="empty">No activity yet</div>';
|
|
1680
1986
|
}
|
|
1681
|
-
function typeToPill(type) {
|
|
1682
|
-
if (type === 'memory-write') return 'green';
|
|
1683
|
-
if (type === 'subagent-spawn') return 'cyan';
|
|
1684
|
-
if (type === 'collision') return 'red';
|
|
1685
|
-
if (type === 'quarantine') return 'yellow';
|
|
1686
|
-
if (
|
|
1687
|
-
return '';
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1987
|
+
function typeToPill(type) {
|
|
1988
|
+
if (type === 'memory-write') return 'green';
|
|
1989
|
+
if (type === 'subagent-spawn') return 'cyan';
|
|
1990
|
+
if (type === 'collision') return 'red';
|
|
1991
|
+
if (type === 'quarantine') return 'yellow';
|
|
1992
|
+
if (type === 'seed-draft') return 'yellow';
|
|
1993
|
+
if (type === 'memory-seeded') return 'green';
|
|
1994
|
+
if (['dream','revisit','counterfactual','consolidation','pattern-discovery','contradiction'].includes(type)) return 'purple';
|
|
1995
|
+
return '';
|
|
1996
|
+
}
|
|
1997
|
+
|
|
1998
|
+
function getWW2ProjectPath() {
|
|
1999
|
+
return document.getElementById('ww2-project-path')?.value?.trim() || 'D:\\\\New Game';
|
|
2000
|
+
}
|
|
2001
|
+
async function refreshWW2BR() {
|
|
2002
|
+
const projectDir = getWW2ProjectPath();
|
|
2003
|
+
const data = await api('/api/v6/ww2br-ops?projectDir=' + encodeURIComponent(projectDir));
|
|
2004
|
+
if (!data) return;
|
|
2005
|
+
|
|
2006
|
+
const stats = data.stats || {};
|
|
2007
|
+
const hooked = (data.agents || []).filter(a => a.hookInstalled).length;
|
|
2008
|
+
document.getElementById('badge-ww2br').textContent = data.recent?.length ?? 0;
|
|
2009
|
+
animateNum('ww2-stat-memories', stats.totalEntries ?? 0);
|
|
2010
|
+
animateNum('ww2-stat-projects', stats.totalProjects ?? 0);
|
|
2011
|
+
animateNum('ww2-stat-hooks', hooked);
|
|
2012
|
+
document.getElementById('ww2-stat-hit').textContent = Math.round((stats.hitRate ?? 0) * 100) + '%';
|
|
2013
|
+
document.getElementById('ww2-stat-scope').textContent = data.projectScoped ? 'project scoped' : 'global fallback';
|
|
2014
|
+
document.getElementById('ww2-stat-sync').textContent = stats.lastSync ? 'sync ' + fmtDate(stats.lastSync) : 'last sync unknown';
|
|
2015
|
+
|
|
2016
|
+
const warnings = data.warnings || [];
|
|
2017
|
+
document.getElementById('ww2-warnings').innerHTML = warnings.length
|
|
2018
|
+
? warnings.map(w => '<div class="warning-banner"><strong>Warning</strong><span>' + htmlEscape(w) + '</span></div>').join('')
|
|
2019
|
+
: '';
|
|
2020
|
+
|
|
2021
|
+
document.getElementById('ww2-timeline').innerHTML = renderMemoryItems(data.recent || [], 'No memories found for this workflow yet.');
|
|
2022
|
+
document.getElementById('ww2-agents').innerHTML = renderWW2Agents(data.agents || []);
|
|
2023
|
+
document.getElementById('ww2-categories').innerHTML = renderWW2Categories(data.categories || {});
|
|
2024
|
+
document.getElementById('ww2-quality').innerHTML = renderWW2Quality(data.quality);
|
|
2025
|
+
document.getElementById('ww2-resume-pack').innerHTML = renderWW2ResumePack(data.resumePack);
|
|
2026
|
+
|
|
2027
|
+
const query = document.getElementById('ww2-query');
|
|
2028
|
+
if (query && !query.value) query.value = 'Gate 2 visual proof';
|
|
2029
|
+
if (!document.getElementById('ww2-recall-results').innerHTML.trim()) {
|
|
2030
|
+
document.getElementById('ww2-recall-results').innerHTML = '<div class="empty-tight">Run a recall query to inspect relevant brain memory.</div>';
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
function renderMemoryItems(items, emptyMessage) {
|
|
2034
|
+
if (!items || !items.length) return '<div class="empty-tight">' + htmlEscape(emptyMessage) + '</div>';
|
|
2035
|
+
return items.map(item => {
|
|
2036
|
+
const confidence = item.importance !== undefined ? Math.round((item.importance || 0) * 100) + '%' : '';
|
|
2037
|
+
const sources = item.sources || (item.metadata && item.metadata.sources) || [];
|
|
2038
|
+
const tags = item.tags || (item.metadata && item.metadata.tags) || [];
|
|
2039
|
+
const quality = item.qualityScore !== undefined ? '<span class="pill">Q ' + htmlEscape(item.qualityScore) + '</span>' : '';
|
|
2040
|
+
const sourceLine = sources.length
|
|
2041
|
+
? '<div class="content" style="font-size:10.5px;color:var(--text-3);margin-top:6px">Sources: ' + sources.slice(0, 3).map(s => '<code>' + htmlEscape(s) + '</code>').join(' · ') + '</div>'
|
|
2042
|
+
: '<div class="content" style="font-size:10.5px;color:var(--warning);margin-top:6px">Sources: none recorded</div>';
|
|
2043
|
+
const tagLine = tags.length ? '<span class="pill">' + tags.slice(0, 3).map(htmlEscape).join(', ') + '</span>' : '';
|
|
2044
|
+
return '<div class="memory-item">' +
|
|
2045
|
+
'<div class="meta">' +
|
|
2046
|
+
'<span class="pill cyan">' + htmlEscape(item.agentTool || item.agent || 'brain') + '</span>' +
|
|
2047
|
+
'<span class="pill">' + htmlEscape(item.category || 'memory') + '</span>' +
|
|
2048
|
+
(confidence ? '<span class="pill green">' + confidence + '</span>' : '') +
|
|
2049
|
+
quality +
|
|
2050
|
+
tagLine +
|
|
2051
|
+
'<span>' + fmtDate(item.createdAt || item.lastAccessed) + '</span>' +
|
|
2052
|
+
'</div>' +
|
|
2053
|
+
'<div class="content">' + htmlEscape(item.content || item.detail || '').slice(0, 420) + '</div>' +
|
|
2054
|
+
sourceLine +
|
|
2055
|
+
'</div>';
|
|
2056
|
+
}).join('');
|
|
2057
|
+
}
|
|
2058
|
+
function renderWW2Quality(quality) {
|
|
2059
|
+
if (!quality) return '<div class="empty-tight">No memory quality data.</div>';
|
|
2060
|
+
const sourcePct = Math.round((quality.sourceCoverage || 0) * 100);
|
|
2061
|
+
const scoreCls = quality.avgScore >= 75 ? 'good' : quality.avgScore >= 55 ? 'warn' : 'bad';
|
|
2062
|
+
return [
|
|
2063
|
+
'<div class="row"><span class="k">Average score</span><span class="v ' + scoreCls + '">' + htmlEscape(quality.avgScore ?? 0) + '/100</span></div>',
|
|
2064
|
+
'<div class="row"><span class="k">Source coverage</span><span class="v ' + (sourcePct >= 70 ? 'good' : 'warn') + '">' + sourcePct + '%</span></div>',
|
|
2065
|
+
'<div class="row"><span class="k">Stale memories</span><span class="v ' + (quality.stale ? 'warn' : 'good') + '">' + htmlEscape(quality.stale || 0) + '</span></div>',
|
|
2066
|
+
'<div class="row"><span class="k">Duplicate clusters</span><span class="v ' + (quality.duplicates?.length ? 'warn' : 'good') + '">' + htmlEscape(quality.duplicates?.length || 0) + '</span></div>',
|
|
2067
|
+
].join('');
|
|
2068
|
+
}
|
|
2069
|
+
function renderWW2ResumePack(pack) {
|
|
2070
|
+
if (!pack) return '<div class="empty-tight">No resume pack generated.</div>';
|
|
2071
|
+
const warnings = pack.warnings && pack.warnings.length
|
|
2072
|
+
? '<div class="warning-stack" style="margin:10px 0 0">' + pack.warnings.slice(0, 3).map(w => '<div class="warning-banner"><strong>Review</strong><span>' + htmlEscape(w) + '</span></div>').join('') + '</div>'
|
|
2073
|
+
: '';
|
|
2074
|
+
const blockers = pack.blockers && pack.blockers.length
|
|
2075
|
+
? '<div class="brain-feed mt">' + renderMemoryItems(pack.blockers.slice(0, 3), 'No blockers in pack.') + '</div>'
|
|
2076
|
+
: '<div class="empty-tight">No blockers in pack.</div>';
|
|
2077
|
+
const stats = pack.stats || {};
|
|
2078
|
+
return '<div class="grid cols-3">' +
|
|
2079
|
+
'<div class="row"><span class="k">Docs</span><span class="v">' + htmlEscape(stats.docCount ?? 0) + '</span></div>' +
|
|
2080
|
+
'<div class="row"><span class="k">Memories</span><span class="v">' + htmlEscape(stats.memoryCount ?? 0) + '</span></div>' +
|
|
2081
|
+
'<div class="row"><span class="k">Quality</span><span class="v">' + htmlEscape(stats.avgQualityScore ?? 0) + '/100</span></div>' +
|
|
2082
|
+
'</div>' +
|
|
2083
|
+
'<div class="mt" style="font-size:12px;color:var(--text-2)">Generated ' + htmlEscape(fmtDate(pack.generatedAt)) + '. Uses visible docs and stored memories only.</div>' +
|
|
2084
|
+
warnings +
|
|
2085
|
+
'<div class="mt">' + blockers + '</div>';
|
|
2086
|
+
}
|
|
2087
|
+
function openWW2ResumePack() {
|
|
2088
|
+
const url = '/api/v6/resume-pack?format=markdown&projectDir=' + encodeURIComponent(getWW2ProjectPath());
|
|
2089
|
+
window.open(url, '_blank', 'noopener');
|
|
2090
|
+
}
|
|
2091
|
+
function renderWW2Agents(agents) {
|
|
2092
|
+
if (!agents.length) return '<div class="empty-tight">No known agent integrations returned.</div>';
|
|
2093
|
+
return agents.map(agent => {
|
|
2094
|
+
const cls = agent.hookInstalled ? 'green' : agent.detected ? 'cyan' : '';
|
|
2095
|
+
const hook = agent.hookInstalled ? 'hooked' : 'not wired';
|
|
2096
|
+
const detected = agent.detected ? 'detected' : 'not found';
|
|
2097
|
+
return '<div class="ops-agent">' +
|
|
2098
|
+
'<div class="name">' + htmlEscape(agent.displayName || agent.name) + '</div>' +
|
|
2099
|
+
'<div class="status">' +
|
|
2100
|
+
'<span class="pill ' + cls + '">' + hook + '</span>' +
|
|
2101
|
+
'<span class="pill">' + detected + '</span>' +
|
|
2102
|
+
'</div>' +
|
|
2103
|
+
'</div>';
|
|
2104
|
+
}).join('');
|
|
2105
|
+
}
|
|
2106
|
+
function renderWW2Categories(categories) {
|
|
2107
|
+
const rows = Object.entries(categories).sort((a, b) => b[1] - a[1]);
|
|
2108
|
+
if (!rows.length) return '<div class="empty-tight">No categories yet.</div>';
|
|
2109
|
+
return rows.map(([name, count]) => '<div class="row"><span class="k">' + htmlEscape(name) + '</span><span class="v">' + count + '</span></div>').join('');
|
|
2110
|
+
}
|
|
2111
|
+
function setWW2Query(query) {
|
|
2112
|
+
document.getElementById('ww2-query').value = query;
|
|
2113
|
+
runWW2Recall();
|
|
2114
|
+
}
|
|
2115
|
+
async function runWW2Recall() {
|
|
2116
|
+
const resultsEl = document.getElementById('ww2-recall-results');
|
|
2117
|
+
const query = document.getElementById('ww2-query').value.trim();
|
|
2118
|
+
const category = document.getElementById('ww2-category').value.trim();
|
|
2119
|
+
resultsEl.innerHTML = '<div class="empty-tight">Searching brain memory...</div>';
|
|
2120
|
+
const data = await api('/api/v6/ww2br-recall', {
|
|
2121
|
+
projectDir: getWW2ProjectPath(),
|
|
2122
|
+
query,
|
|
2123
|
+
category: category || undefined,
|
|
2124
|
+
limit: 12,
|
|
2125
|
+
});
|
|
2126
|
+
if (!data) return;
|
|
2127
|
+
const prefix = data.projectScoped ? '' : '<div class="warning-banner"><strong>Fallback</strong><span>No project-scoped matches; showing global brain recall results.</span></div>';
|
|
2128
|
+
resultsEl.innerHTML = prefix + renderMemoryItems(data.results || [], 'No recall matches for that query.');
|
|
2129
|
+
}
|
|
2130
|
+
|
|
2131
|
+
// ──── Charts ───────────────────────────────────────────────────────────
|
|
1691
2132
|
function chartTheme() {
|
|
1692
2133
|
const dark = document.documentElement.dataset.theme !== 'light';
|
|
1693
2134
|
return { grid: dark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.05)', text: dark ? '#a4afc4' : '#3d4864' };
|
|
1694
2135
|
}
|
|
1695
|
-
function
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
const
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
}
|
|
2136
|
+
function spendLabels(buckets) {
|
|
2137
|
+
return Object.keys(buckets || {}).sort((a, b) => (buckets[b]?.spendUsd || 0) - (buckets[a]?.spendUsd || 0));
|
|
2138
|
+
}
|
|
2139
|
+
function drawSpendBarChart(canvasId, chartKey, buckets) {
|
|
2140
|
+
const ctx = document.getElementById(canvasId);
|
|
2141
|
+
if (!ctx) return;
|
|
2142
|
+
const labels = spendLabels(buckets);
|
|
2143
|
+
const data = labels.map(l => buckets[l].spendUsd || 0);
|
|
2144
|
+
const t = chartTheme();
|
|
2145
|
+
if (charts[chartKey]) charts[chartKey].destroy();
|
|
2146
|
+
charts[chartKey] = new Chart(ctx, { type: 'bar', data: { labels, datasets: [{ label: 'Spend (USD)', data, backgroundColor: ['#18ffff','#a855f7','#ec4899','#10e68c','#ffb53f','#4fb6ff'], borderRadius: 6 }] }, options: { responsive:true, maintainAspectRatio:false, plugins:{legend:{display:false}}, scales:{x:{grid:{color:t.grid},ticks:{color:t.text}},y:{grid:{color:t.grid},ticks:{color:t.text,callback:v=>'$'+Number(v).toFixed(2)}}} } });
|
|
2147
|
+
}
|
|
2148
|
+
function drawTokensChart(byAgent) {
|
|
2149
|
+
drawSpendBarChart('chart-tokens', 'tokens', byAgent || {});
|
|
2150
|
+
}
|
|
2151
|
+
function drawTokensAgentChart(byAgent) {
|
|
2152
|
+
drawSpendBarChart('chart-tokens-agent', 'tokensAgent', byAgent || {});
|
|
2153
|
+
}
|
|
2154
|
+
function drawTokensModelChart(byModel) {
|
|
2155
|
+
const ctx = document.getElementById('chart-tokens-model');
|
|
2156
|
+
if (!ctx) return;
|
|
2157
|
+
const labels = spendLabels(byModel);
|
|
2158
|
+
const data = labels.map(l => byModel[l].spendUsd || 0);
|
|
2159
|
+
const t = chartTheme();
|
|
2160
|
+
if (charts.tokensModel) charts.tokensModel.destroy();
|
|
2161
|
+
charts.tokensModel = new Chart(ctx, { type: 'doughnut', data: { labels, datasets: [{ data, backgroundColor: ['#18ffff','#a855f7','#ec4899','#10e68c','#ffb53f','#4fb6ff'], borderWidth:0 }] }, options: { responsive:true, maintainAspectRatio:false, plugins:{legend:{position:'right',labels:{color:t.text,boxWidth:12}}} } });
|
|
2162
|
+
}
|
|
2163
|
+
function renderSpendRows(buckets, emptyMessage) {
|
|
2164
|
+
const labels = spendLabels(buckets).slice(0, 8);
|
|
2165
|
+
if (!labels.length) return '<div class="empty-tight">' + htmlEscape(emptyMessage) + '</div>';
|
|
2166
|
+
return labels.map(label => {
|
|
2167
|
+
const b = buckets[label] || {};
|
|
2168
|
+
const last = b.lastSeen ? new Date(b.lastSeen).toLocaleString() : '—';
|
|
2169
|
+
return \`<div class="row"><span class="k">\${htmlEscape(label)} <span class="tag-code">\${b.calls || 0} calls</span></span><span class="v">$\${Number(b.spendUsd || 0).toFixed(4)} <span class="mono" style="color:var(--text-3)">\${last}</span></span></div>\`;
|
|
2170
|
+
}).join('');
|
|
2171
|
+
}
|
|
1713
2172
|
function drawDreamChart(byType) {
|
|
1714
2173
|
const ctx = document.getElementById('chart-dreams');
|
|
1715
2174
|
if (!ctx) return;
|
|
@@ -1865,16 +2324,24 @@ async function runAttention() {
|
|
|
1865
2324
|
}
|
|
1866
2325
|
|
|
1867
2326
|
// ──── Tokens ───────────────────────────────────────────────────────────
|
|
1868
|
-
async function refreshTokens() {
|
|
1869
|
-
const res = await api('/api/v6/tokens-report');
|
|
1870
|
-
if (!res) return;
|
|
1871
|
-
|
|
1872
|
-
document.getElementById('tok-
|
|
2327
|
+
async function refreshTokens() {
|
|
2328
|
+
const res = await api('/api/v6/tokens-report');
|
|
2329
|
+
if (!res) return;
|
|
2330
|
+
const runtime = res.runtime || {};
|
|
2331
|
+
document.getElementById('tok-agent').textContent = runtime.currentAgentDisplay || 'Unknown';
|
|
2332
|
+
document.getElementById('tok-runtime').textContent = (runtime.provider || 'provider') + (runtime.model ? ' / ' + runtime.model : '');
|
|
2333
|
+
document.getElementById('tok-runtime-note').innerHTML = \`<strong>Accuracy</strong><span>\${htmlEscape(runtime.note || 'Token records are historical. Current agent and model spend are shown separately.')}</span>\`;
|
|
2334
|
+
document.getElementById('tok-total').textContent = '$' + (res.totalSpendUsd || 0).toFixed(4);
|
|
2335
|
+
document.getElementById('tok-recent').textContent = '$' + (res.recentSpendUsd || 0).toFixed(4);
|
|
2336
|
+
document.getElementById('tok-proj').textContent = '$' + (res.monthlyProjectionUsd || 0).toFixed(2);
|
|
1873
2337
|
document.getElementById('tok-save').textContent = '$' + (res.savingsOpportunitiesUsd || 0).toFixed(2);
|
|
1874
2338
|
const calls = Object.values(res.byAgent || {}).reduce((a, b) => a + b.calls, 0);
|
|
1875
2339
|
document.getElementById('tok-calls').textContent = calls;
|
|
1876
2340
|
document.getElementById('tok-calls-sub').textContent = \`\${(res.totalInputTokens || 0).toLocaleString()} in · \${(res.totalOutputTokens || 0).toLocaleString()} out\`;
|
|
1877
|
-
|
|
2341
|
+
drawTokensAgentChart(res.recentByAgent || res.byAgent || {});
|
|
2342
|
+
drawTokensModelChart(res.byModel || {});
|
|
2343
|
+
document.getElementById('tok-agent-table').innerHTML = renderSpendRows(res.recentByAgent || res.byAgent || {}, 'No recent agent spend records.');
|
|
2344
|
+
document.getElementById('tok-model-table').innerHTML = renderSpendRows(res.byModel || {}, 'No model spend records.');
|
|
1878
2345
|
document.getElementById('tok-suggestions').innerHTML = (res.suggestions || []).map(s => \`<div style="padding:8px 0;border-bottom:1px solid var(--border);display:flex;gap:8px"><span style="color:var(--success);flex-shrink:0">💡</span><span style="font-size:12px">\${s}</span></div>\`).join('') || '<div class="empty">Running lean — no suggestions</div>';
|
|
1879
2346
|
}
|
|
1880
2347
|
|
|
@@ -2246,7 +2713,26 @@ async function attachAll() { const r = await api('/api/v6/agents-attach-all', {}
|
|
|
2246
2713
|
async function detachAll() { if (!confirm('Detach Shadow Brain hooks from ALL agents?')) return; const r = await api('/api/v6/agents-detach-all', {}); if (r) { toast('Detach All', (r.attached?.length ?? 0) + ' agents', 'warn'); refreshAgents(); } }
|
|
2247
2714
|
|
|
2248
2715
|
// ──── Memory browser ───────────────────────────────────────────────────
|
|
2249
|
-
|
|
2716
|
+
function renderCountRows(rows, emptyMessage) {
|
|
2717
|
+
if (!rows || !rows.length) return '<div class="empty-tight">' + htmlEscape(emptyMessage) + '</div>';
|
|
2718
|
+
return rows.slice(0, 8).map(row =>
|
|
2719
|
+
'<div class="row"><span class="k">' + htmlEscape(row.name) + '</span><span class="v">' + htmlEscape(row.count) + '</span></div>'
|
|
2720
|
+
).join('');
|
|
2721
|
+
}
|
|
2722
|
+
async function refreshMemoryIntelligence() {
|
|
2723
|
+
const data = await api('/api/v6/memory-intelligence?limit=500');
|
|
2724
|
+
if (!data) return;
|
|
2725
|
+
document.getElementById('mem-total').textContent = data.totalEntries ?? 0;
|
|
2726
|
+
document.getElementById('mem-sampled').textContent = (data.sampledEntries ?? 0) + ' shown in intelligence sample';
|
|
2727
|
+
document.getElementById('mem-source').textContent = Math.round((data.sourceCoverage || 0) * 100) + '%';
|
|
2728
|
+
document.getElementById('mem-fresh').textContent = data.recent7d ?? 0;
|
|
2729
|
+
document.getElementById('mem-seed-open').textContent = data.openSeedDrafts ?? 0;
|
|
2730
|
+
document.getElementById('mem-seed-sub').textContent = (data.pendingApprovals ?? 0) + ' need approval';
|
|
2731
|
+
document.getElementById('mem-categories').innerHTML = renderCountRows(data.byCategory, 'No categories yet.');
|
|
2732
|
+
document.getElementById('mem-agents').innerHTML = renderCountRows(data.byAgent, 'No agent memory writes yet.');
|
|
2733
|
+
document.getElementById('mem-tags').innerHTML = renderCountRows(data.topTags, 'No tags yet.');
|
|
2734
|
+
}
|
|
2735
|
+
async function searchMemory() {
|
|
2250
2736
|
const r = await api('/api/v6/memory-browser', {
|
|
2251
2737
|
query: document.getElementById('mem-query').value,
|
|
2252
2738
|
agent: document.getElementById('mem-agent').value,
|
|
@@ -2260,7 +2746,191 @@ async function searchMemory() {
|
|
|
2260
2746
|
}
|
|
2261
2747
|
|
|
2262
2748
|
// ──── Activity ─────────────────────────────────────────────────────────
|
|
2263
|
-
|
|
2749
|
+
// Live Brain
|
|
2750
|
+
// Memory Seeder
|
|
2751
|
+
function seedProjectPath() {
|
|
2752
|
+
return document.getElementById('seed-project-path')?.value?.trim()
|
|
2753
|
+
|| document.getElementById('live-project-path')?.value?.trim()
|
|
2754
|
+
|| document.getElementById('ww2-project-path')?.value?.trim()
|
|
2755
|
+
|| '';
|
|
2756
|
+
}
|
|
2757
|
+
function copyLivePathToSeeder() {
|
|
2758
|
+
const value = document.getElementById('live-project-path')?.value?.trim()
|
|
2759
|
+
|| document.getElementById('ww2-project-path')?.value?.trim()
|
|
2760
|
+
|| '';
|
|
2761
|
+
if (value) document.getElementById('seed-project-path').value = value;
|
|
2762
|
+
}
|
|
2763
|
+
function openSeederForLiveBrain() {
|
|
2764
|
+
const projectDir = liveProjectPath() || document.getElementById('ww2-project-path')?.value?.trim() || '';
|
|
2765
|
+
switchTab('seeder', 'Memory Seeder');
|
|
2766
|
+
if (projectDir) document.getElementById('seed-project-path').value = projectDir;
|
|
2767
|
+
const topic = document.getElementById('seed-topic');
|
|
2768
|
+
const objective = document.getElementById('seed-objective');
|
|
2769
|
+
if (topic && !topic.value) topic.value = 'Source-backed live brain improvement';
|
|
2770
|
+
if (objective && !objective.value) objective.value = 'Capture verified project knowledge that future agents should recall before complex work.';
|
|
2771
|
+
refreshSeedDrafts();
|
|
2772
|
+
}
|
|
2773
|
+
function seedDraftStatusClass(status) {
|
|
2774
|
+
if (status === 'seeded') return 'green';
|
|
2775
|
+
if (status === 'approved') return 'cyan';
|
|
2776
|
+
if (status === 'rejected') return 'red';
|
|
2777
|
+
return 'yellow';
|
|
2778
|
+
}
|
|
2779
|
+
function renderSeedStatus(drafts) {
|
|
2780
|
+
const counts = { draft: 0, approved: 0, seeded: 0, rejected: 0 };
|
|
2781
|
+
for (const d of drafts || []) counts[d.status] = (counts[d.status] || 0) + 1;
|
|
2782
|
+
return [
|
|
2783
|
+
'<div class="row"><span class="k">Open drafts</span><span class="v warn">' + counts.draft + '</span></div>',
|
|
2784
|
+
'<div class="row"><span class="k">Approved</span><span class="v good">' + counts.approved + '</span></div>',
|
|
2785
|
+
'<div class="row"><span class="k">Seeded</span><span class="v good">' + counts.seeded + '</span></div>',
|
|
2786
|
+
'<div class="row"><span class="k">Rejected</span><span class="v bad">' + counts.rejected + '</span></div>',
|
|
2787
|
+
'<div class="row"><span class="k">Current project</span><span class="v mono">' + htmlEscape(seedProjectPath() || 'dashboard default') + '</span></div>',
|
|
2788
|
+
].join('');
|
|
2789
|
+
}
|
|
2790
|
+
function seedJsArg(value) {
|
|
2791
|
+
return JSON.stringify(String(value || ''));
|
|
2792
|
+
}
|
|
2793
|
+
function renderSeedDrafts(drafts) {
|
|
2794
|
+
if (!drafts || !drafts.length) return '<div class="empty-tight">No seed drafts yet.</div>';
|
|
2795
|
+
return drafts.map(d => {
|
|
2796
|
+
const approvedBy = new Set((d.approvals || []).map(a => a.by));
|
|
2797
|
+
const required = d.requiredApprovals || [];
|
|
2798
|
+
const pending = required.filter(a => !approvedBy.has(a));
|
|
2799
|
+
const agentApprover = d.approverAgent && d.approverAgent !== 'user' ? d.approverAgent : d.researchAgent;
|
|
2800
|
+
const warnings = (d.warnings || []).length
|
|
2801
|
+
? '<div class="warning-stack" style="margin-top:8px">' + d.warnings.map(w => '<div class="warning-banner"><strong>Review</strong><span>' + htmlEscape(w) + '</span></div>').join('') + '</div>'
|
|
2802
|
+
: '';
|
|
2803
|
+
const sources = (d.sources || []).slice(0, 5).map(s => '<code>' + htmlEscape(s) + '</code>').join(' ');
|
|
2804
|
+
let actions = '';
|
|
2805
|
+
if (d.status === 'draft') {
|
|
2806
|
+
actions += '<button class="btn sm success" onclick="approveSeedDraft(' + seedJsArg(d.id) + ',' + seedJsArg('user') + ')">User Approve</button> ';
|
|
2807
|
+
actions += '<button class="btn sm" onclick="approveSeedDraft(' + seedJsArg(d.id) + ',' + seedJsArg(agentApprover) + ')">Agent Approve</button> ';
|
|
2808
|
+
actions += '<button class="btn sm danger" onclick="rejectSeedDraft(' + seedJsArg(d.id) + ')">Reject</button>';
|
|
2809
|
+
}
|
|
2810
|
+
if (d.status === 'approved') {
|
|
2811
|
+
actions += '<button class="btn sm primary" onclick="commitSeedDraft(' + seedJsArg(d.id) + ')">Seed to Brain</button> ';
|
|
2812
|
+
actions += '<button class="btn sm danger" onclick="rejectSeedDraft(' + seedJsArg(d.id) + ')">Reject</button>';
|
|
2813
|
+
}
|
|
2814
|
+
if (d.status === 'seeded') {
|
|
2815
|
+
actions += '<span class="pill green">memory ' + htmlEscape((d.seededMemoryId || '').slice(0, 10)) + '</span>';
|
|
2816
|
+
}
|
|
2817
|
+
return '<div class="memory-item">' +
|
|
2818
|
+
'<div class="meta">' +
|
|
2819
|
+
'<span class="pill ' + seedDraftStatusClass(d.status) + '">' + htmlEscape(d.status) + '</span>' +
|
|
2820
|
+
'<span class="pill purple">' + htmlEscape(d.researchAgent) + '</span>' +
|
|
2821
|
+
'<span class="pill cyan">' + htmlEscape(d.approvalMode) + '</span>' +
|
|
2822
|
+
'<span>' + htmlEscape(new Date(d.updatedAt || d.createdAt).toLocaleString()) + '</span>' +
|
|
2823
|
+
'</div>' +
|
|
2824
|
+
'<div style="display:flex;gap:12px;align-items:flex-start;justify-content:space-between;flex-wrap:wrap">' +
|
|
2825
|
+
'<div style="min-width:260px;flex:1">' +
|
|
2826
|
+
'<div style="font-weight:700;margin-bottom:4px">' + htmlEscape(d.topic) + '</div>' +
|
|
2827
|
+
'<div class="content">' + htmlEscape(d.objective || '').slice(0, 260) + '</div>' +
|
|
2828
|
+
'<div class="mono" style="font-size:11px;color:var(--text-3);margin-top:6px">pending: ' + htmlEscape(pending.join(', ') || 'none') + ' | category: ' + htmlEscape(d.category) + '</div>' +
|
|
2829
|
+
'<div style="font-size:11px;color:var(--text-3);margin-top:6px">' + (sources || 'No sources') + '</div>' +
|
|
2830
|
+
'</div>' +
|
|
2831
|
+
'<div style="display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end">' + actions + '</div>' +
|
|
2832
|
+
'</div>' +
|
|
2833
|
+
warnings +
|
|
2834
|
+
'<pre class="mono" style="margin-top:10px;max-height:180px;overflow:auto;background:var(--bg-elev-1);padding:10px;border-radius:6px;white-space:pre-wrap">' + htmlEscape(d.content || '') + '</pre>' +
|
|
2835
|
+
'</div>';
|
|
2836
|
+
}).join('');
|
|
2837
|
+
}
|
|
2838
|
+
async function refreshSeedDrafts() {
|
|
2839
|
+
const input = document.getElementById('seed-project-path');
|
|
2840
|
+
if (input && !input.value) input.value = seedProjectPath();
|
|
2841
|
+
const drafts = await api('/api/v6/seed-drafts?limit=50') ?? [];
|
|
2842
|
+
const open = drafts.filter(d => d.status === 'draft' || d.status === 'approved').length;
|
|
2843
|
+
const badge = document.getElementById('badge-seeder');
|
|
2844
|
+
if (badge) badge.textContent = open;
|
|
2845
|
+
const status = document.getElementById('seed-status');
|
|
2846
|
+
if (status) status.innerHTML = renderSeedStatus(drafts);
|
|
2847
|
+
const list = document.getElementById('seed-drafts');
|
|
2848
|
+
if (list) list.innerHTML = renderSeedDrafts(drafts);
|
|
2849
|
+
}
|
|
2850
|
+
async function createSeedDraft() {
|
|
2851
|
+
const topic = document.getElementById('seed-topic').value.trim();
|
|
2852
|
+
if (!topic) { toast('Topic required', 'Add a seed topic before creating a draft.', 'warn'); return; }
|
|
2853
|
+
const draft = await api('/api/v6/seed-draft', {
|
|
2854
|
+
projectDir: seedProjectPath(),
|
|
2855
|
+
topic,
|
|
2856
|
+
objective: document.getElementById('seed-objective').value,
|
|
2857
|
+
researchAgent: document.getElementById('seed-research-agent').value,
|
|
2858
|
+
approverAgent: document.getElementById('seed-approver-agent').value,
|
|
2859
|
+
approvalMode: document.getElementById('seed-approval-mode').value,
|
|
2860
|
+
category: document.getElementById('seed-category').value,
|
|
2861
|
+
tags: document.getElementById('seed-tags').value,
|
|
2862
|
+
importance: parseFloat(document.getElementById('seed-importance').value || '0.78'),
|
|
2863
|
+
sources: document.getElementById('seed-sources').value,
|
|
2864
|
+
content: document.getElementById('seed-content').value,
|
|
2865
|
+
});
|
|
2866
|
+
if (draft) {
|
|
2867
|
+
toast('Seed draft created', draft.status);
|
|
2868
|
+
refreshSeedDrafts();
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
async function approveSeedDraft(id, approvedBy) {
|
|
2872
|
+
const draft = await api('/api/v6/seed-approve', { id, approvedBy });
|
|
2873
|
+
if (draft) {
|
|
2874
|
+
toast('Approval recorded', draft.status);
|
|
2875
|
+
refreshSeedDrafts();
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
2878
|
+
async function rejectSeedDraft(id) {
|
|
2879
|
+
const reason = prompt('Reject reason', 'Not verified enough');
|
|
2880
|
+
if (reason === null) return;
|
|
2881
|
+
const draft = await api('/api/v6/seed-reject', { id, reason, rejectedBy: 'user' });
|
|
2882
|
+
if (draft) {
|
|
2883
|
+
toast('Draft rejected', draft.topic, 'warn');
|
|
2884
|
+
refreshSeedDrafts();
|
|
2885
|
+
}
|
|
2886
|
+
}
|
|
2887
|
+
async function commitSeedDraft(id) {
|
|
2888
|
+
const draft = await api('/api/v6/seed-commit', { id, seededBy: 'user' });
|
|
2889
|
+
if (draft) {
|
|
2890
|
+
toast('Seeded to brain', (draft.seededMemoryId || '').slice(0, 10));
|
|
2891
|
+
refreshSeedDrafts();
|
|
2892
|
+
refreshLiveBrain();
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2895
|
+
|
|
2896
|
+
function liveProjectPath() {
|
|
2897
|
+
return document.getElementById('live-project-path')?.value?.trim() || '';
|
|
2898
|
+
}
|
|
2899
|
+
function liveActionPill(priority) {
|
|
2900
|
+
if (priority === 'critical' || priority === 'high') return 'red';
|
|
2901
|
+
if (priority === 'medium') return 'yellow';
|
|
2902
|
+
return 'cyan';
|
|
2903
|
+
}
|
|
2904
|
+
async function refreshLiveBrain() {
|
|
2905
|
+
const projectDir = liveProjectPath();
|
|
2906
|
+
const queries = document.getElementById('live-queries')?.value?.trim() || '';
|
|
2907
|
+
const url = '/api/v6/live-brain?projectDir=' + encodeURIComponent(projectDir) + (queries ? '&queries=' + encodeURIComponent(queries) : '');
|
|
2908
|
+
const data = await api(url);
|
|
2909
|
+
if (!data) return;
|
|
2910
|
+
|
|
2911
|
+
const quality = data.memoryQuality || {};
|
|
2912
|
+
document.getElementById('live-memories').textContent = quality.totalEntries ?? 0;
|
|
2913
|
+
document.getElementById('live-quality').textContent = (quality.avgScore ?? 0) + '/100';
|
|
2914
|
+
document.getElementById('live-sources').textContent = Math.round((quality.sourceCoverage ?? 0) * 100) + '%';
|
|
2915
|
+
document.getElementById('live-recall').textContent = data.recallEval?.avgHitCount ?? 0;
|
|
2916
|
+
document.getElementById('live-scope').textContent = data.projectScoped ? 'project scoped' : 'global fallback';
|
|
2917
|
+
|
|
2918
|
+
document.getElementById('live-actions').innerHTML = (data.learningActions || []).length
|
|
2919
|
+
? data.learningActions.map(a => \`<div class="memory-item"><div class="meta"><span class="pill \${liveActionPill(a.priority)}">\${a.priority}</span><span>\${a.title}</span></div><div class="content">\${a.reason}</div>\${a.command ? '<code>' + a.command + '</code>' : ''}</div>\`).join('')
|
|
2920
|
+
: '<div class="empty">No immediate hygiene actions.</div>';
|
|
2921
|
+
|
|
2922
|
+
document.getElementById('live-eval').innerHTML = (data.recallEval?.cases || []).map(c =>
|
|
2923
|
+
\`<div class="row"><span class="k">\${c.query}</span><span class="v \${c.hitCount ? 'good' : 'bad'}">\${c.hitCount} hits - \${c.sourceBackedHits} sourced</span></div>\`
|
|
2924
|
+
).join('') || '<div class="empty">No eval cases.</div>';
|
|
2925
|
+
|
|
2926
|
+
document.getElementById('live-top').innerHTML = (data.topMemories || []).slice(0, 8).map(m =>
|
|
2927
|
+
\`<div class="memory-item"><div class="meta"><span class="pill purple">\${m.agentTool}</span><span>\${m.category}</span><span>score \${m.qualityScore}/100</span></div><div class="content">\${(m.content || '').slice(0, 260)}</div></div>\`
|
|
2928
|
+
).join('') || '<div class="empty">No memories.</div>';
|
|
2929
|
+
|
|
2930
|
+
document.getElementById('live-brief').textContent = data.agentBriefing || '';
|
|
2931
|
+
}
|
|
2932
|
+
|
|
2933
|
+
async function refreshActivity() {
|
|
2264
2934
|
const filter = document.getElementById('act-filter').value;
|
|
2265
2935
|
const log = await api('/api/v6/activity-log?limit=200') ?? [];
|
|
2266
2936
|
const filtered = filter ? log.filter(e => e.type === filter) : log;
|