@timmeck/brain-core 2.36.28 → 2.36.30

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.
@@ -234,6 +234,7 @@ canvas{display:block;width:100%;height:100%}
234
234
  <div class="nav-item" data-page="learning"><span class="nav-icon">&#x1F9E0;</span><span class="nav-label" data-t="Lern-Kreislauf">Lern-Kreislauf</span></div>
235
235
  <div class="nav-item" data-page="trading"><span class="nav-icon">&#x1F4C8;</span><span class="nav-label">Trading Flow</span></div>
236
236
  <div class="nav-item" data-page="marketing"><span class="nav-icon">&#x1F4E3;</span><span class="nav-label">Marketing Flow</span></div>
237
+ <div class="nav-item" data-page="intelligence"><span class="nav-icon">&#x1F4A1;</span><span class="nav-label" data-t="Intelligenz">Intelligenz</span></div>
237
238
  <div class="nav-section">System</div>
238
239
  <div class="nav-item" data-page="crossbrain"><span class="nav-icon">&#x1F517;</span><span class="nav-label">Cross-Brain</span></div>
239
240
  <div class="nav-item" data-page="debates"><span class="nav-icon">&#x2696;</span><span class="nav-label">Debates</span></div>
@@ -473,7 +474,76 @@ canvas{display:block;width:100%;height:100%}
473
474
  </div>
474
475
  </div>
475
476
 
476
- <!-- ════ Page 5: Cross-Brain & Borg ═════════════════ -->
477
+ <!-- ════ Page 5: Intelligence ═══════════════════════ -->
478
+ <div class="page" id="page-intelligence">
479
+ <!-- RAG Pipeline -->
480
+ <div class="section">
481
+ <div class="section-title"><span class="icon">&#x1F50D;</span> RAG Pipeline — <span data-t="Vektor-Suche">Vektor-Suche</span></div>
482
+ <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px" data-t="Alles Wissen als Vektoren indexiert. Semantische Suche über Insights, Memories, Principles, Errors, Solutions und absorbierten Code.">Alles Wissen als Vektoren indexiert. Semantische Suche über Insights, Memories, Principles, Errors, Solutions und absorbierten Code.</p>
483
+ <div class="grid grid-3">
484
+ <div class="card" style="text-align:center"><div class="card-value" id="int-rag-total" style="color:var(--cyan)">0</div><div class="card-sub" data-t="Vektoren gesamt">Vektoren gesamt</div></div>
485
+ <div class="card" style="text-align:center"><div class="card-value" id="int-rag-collections" style="color:var(--green)">0</div><div class="card-sub">Collections</div></div>
486
+ <div class="card" style="text-align:center"><div class="card-value" id="int-rag-indexed" style="color:var(--purple);font-size:14px">—</div><div class="card-sub" data-t="Letzte Indexierung">Letzte Indexierung</div></div>
487
+ </div>
488
+ <div id="ragCollections" style="margin-top:12px"></div>
489
+ </div>
490
+
491
+ <!-- Knowledge Graph -->
492
+ <div class="section">
493
+ <div class="section-title"><span class="icon">&#x1F578;</span> Knowledge Graph — <span data-t="Fakten-Netzwerk">Fakten-Netzwerk</span></div>
494
+ <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px" data-t="Typisierte Relationen: Subjekt → Prädikat → Objekt. Automatisch extrahiert aus Insights, Error-Solutions und assimilierten Repos.">Typisierte Relationen: Subjekt → Prädikat → Objekt. Automatisch extrahiert aus Insights, Error-Solutions und assimilierten Repos.</p>
495
+ <div class="grid grid-3">
496
+ <div class="card" style="text-align:center"><div class="card-value" id="int-kg-facts" style="color:var(--cyan)">0</div><div class="card-sub" data-t="Fakten gesamt">Fakten gesamt</div></div>
497
+ <div class="card" style="text-align:center"><div class="card-value" id="int-kg-predicates" style="color:var(--green)">0</div><div class="card-sub" data-t="Prädikate">Prädikate</div></div>
498
+ <div class="card" style="text-align:center"><div class="card-value" id="int-kg-confidence" style="color:var(--yellow)">0%</div><div class="card-sub" data-t="Ø Konfidenz">Ø Konfidenz</div></div>
499
+ </div>
500
+ <div id="kgPredicates" style="margin-top:12px"></div>
501
+ </div>
502
+
503
+ <!-- Tool Learning -->
504
+ <div class="section">
505
+ <div class="section-title"><span class="icon">&#x1F6E0;</span> Tool Learning — <span data-t="Nutzungsmuster">Nutzungsmuster</span></div>
506
+ <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px" data-t="Trackt jeden IPC-Call: welche Tools werden wie oft und wie erfolgreich genutzt.">Trackt jeden IPC-Call: welche Tools werden wie oft und wie erfolgreich genutzt.</p>
507
+ <div id="toolStats" style="margin-top:8px"><div class="empty" data-t="Keine Tool-Daten">Keine Tool-Daten</div></div>
508
+ </div>
509
+
510
+ <!-- Feedback & Proactive Row -->
511
+ <div class="grid grid-2">
512
+ <!-- Feedback Learning -->
513
+ <div class="section" style="margin:0">
514
+ <div class="section-title"><span class="icon">&#x1F4AC;</span> Feedback</div>
515
+ <div class="grid grid-2" style="gap:8px">
516
+ <div class="card" style="text-align:center;padding:8px"><div class="card-value" id="int-fb-positive" style="color:var(--green);font-size:20px">0</div><div class="card-sub">Positive</div></div>
517
+ <div class="card" style="text-align:center;padding:8px"><div class="card-value" id="int-fb-negative" style="color:var(--red);font-size:20px">0</div><div class="card-sub">Negative</div></div>
518
+ </div>
519
+ <div class="card" style="text-align:center;margin-top:8px;padding:8px"><div class="card-value" id="int-fb-reward" style="font-size:16px">0</div><div class="card-sub" data-t="Ø Reward Score">Ø Reward Score</div></div>
520
+ </div>
521
+
522
+ <!-- Proactive Suggestions -->
523
+ <div class="section" style="margin:0">
524
+ <div class="section-title"><span class="icon">&#x1F4A1;</span> <span data-t="Proaktive Vorschläge">Proaktive Vorschläge</span></div>
525
+ <div class="grid grid-2" style="gap:8px">
526
+ <div class="card" style="text-align:center;padding:8px"><div class="card-value" id="int-pr-active" style="color:var(--cyan);font-size:20px">0</div><div class="card-sub" data-t="Offen">Offen</div></div>
527
+ <div class="card" style="text-align:center;padding:8px"><div class="card-value" id="int-pr-dismissed" style="color:var(--text-dim);font-size:20px">0</div><div class="card-sub" data-t="Verworfen">Verworfen</div></div>
528
+ </div>
529
+ <div class="card" style="text-align:center;margin-top:8px;padding:8px"><div class="card-value" id="int-pr-total" style="font-size:16px">0</div><div class="card-sub" data-t="Vorschläge gesamt">Vorschläge gesamt</div></div>
530
+ </div>
531
+ </div>
532
+
533
+ <!-- User Model -->
534
+ <div class="section">
535
+ <div class="section-title"><span class="icon">&#x1F464;</span> User Model — <span data-t="Dein Profil">Dein Profil</span></div>
536
+ <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px" data-t="Brain lernt dein Verhalten: Skill-Domains, bevorzugte Tools, Arbeitszeiten.">Brain lernt dein Verhalten: Skill-Domains, bevorzugte Tools, Arbeitszeiten.</p>
537
+ <div class="grid grid-3">
538
+ <div class="card" style="text-align:center"><div class="card-value" id="int-um-domains" style="color:var(--cyan)">0</div><div class="card-sub" data-t="Skill-Domains">Skill-Domains</div></div>
539
+ <div class="card" style="text-align:center"><div class="card-value" id="int-um-keys" style="color:var(--green)">0</div><div class="card-sub" data-t="Profil-Keys">Profil-Keys</div></div>
540
+ <div class="card" style="text-align:center"><div class="card-value" id="int-um-updated" style="color:var(--purple);font-size:14px">—</div><div class="card-sub" data-t="Zuletzt aktualisiert">Zuletzt aktualisiert</div></div>
541
+ </div>
542
+ <div id="userTopTools" style="margin-top:12px"></div>
543
+ </div>
544
+ </div>
545
+
546
+ <!-- ════ Page 6: Cross-Brain & Borg ═════════════════ -->
477
547
  <div class="page" id="page-crossbrain">
478
548
  <div class="section">
479
549
  <div class="section-title"><span class="icon">&#x1F517;</span> <span data-t="So kommunizieren die Brains">So kommunizieren die Brains</span></div>
@@ -536,6 +606,18 @@ canvas{display:block;width:100%;height:100%}
536
606
  </div>
537
607
  <div id="missionList" style="margin-top:12px"><div class="empty">Keine aktiven Missionen</div></div>
538
608
  </div>
609
+
610
+ <!-- Repo Absorber -->
611
+ <div class="section">
612
+ <div class="section-title"><span class="icon">&#x1F9EC;</span> <span data-t="Code-Assimilierung">Code-Assimilierung</span></div>
613
+ <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px" data-t="Brain klont Open-Source-Repos, extrahiert Patterns und Wissen, indexiert alles in RAG + Knowledge Graph, und löscht den Clone wieder.">Brain klont Open-Source-Repos, extrahiert Patterns und Wissen, indexiert alles in RAG + Knowledge Graph, und löscht den Clone wieder.</p>
614
+ <div class="grid grid-3" id="absorberStats">
615
+ <div class="card" style="text-align:center"><div class="card-value" id="ra-total" style="color:var(--cyan)">0</div><div class="card-sub" data-t="Repos assimiliert">Repos assimiliert</div></div>
616
+ <div class="card" style="text-align:center"><div class="card-value" id="ra-queue" style="color:var(--yellow)">0</div><div class="card-sub" data-t="In der Warteschlange">In der Warteschlange</div></div>
617
+ <div class="card" style="text-align:center"><div class="card-value" id="ra-last" style="color:var(--green);font-size:14px">—</div><div class="card-sub" data-t="Zuletzt assimiliert">Zuletzt assimiliert</div></div>
618
+ </div>
619
+ <div id="absorberHistory" style="margin-top:12px"><div class="empty" data-t="Noch keine Repos assimiliert">Noch keine Repos assimiliert</div></div>
620
+ </div>
539
621
  </div>
540
622
 
541
623
  <!-- ════ Page 7: Debates & Challenges ═════════════════ -->
@@ -644,6 +726,25 @@ const translations = { en: {
644
726
  'Aktive Recherche-Missionen':'Active Research Missions',
645
727
  'Brain forscht eigenständig zu Themen. Jede Mission durchläuft 5 Phasen: Aufteilen, Sammeln, Hypothesen bilden, Analysieren, Zusammenfassen.':'Brain researches topics autonomously. Each mission goes through 5 phases: decompose, gather, hypothesize, analyze, synthesize.',
646
728
  'Aktive Missionen':'Active Missions','Abgeschlossen':'Completed','Quellen gesammelt':'Sources Gathered',
729
+ 'Code-Assimilierung':'Code Assimilation',
730
+ 'Brain klont Open-Source-Repos, extrahiert Patterns und Wissen, indexiert alles in RAG + Knowledge Graph, und löscht den Clone wieder.':'Brain clones open-source repos, extracts patterns and knowledge, indexes everything into RAG + Knowledge Graph, then deletes the clone.',
731
+ 'Repos assimiliert':'Repos Assimilated','In der Warteschlange':'In Queue','Zuletzt assimiliert':'Last Assimilated',
732
+ 'Noch keine Repos assimiliert':'No repos assimilated yet','Dateien':'Files',
733
+ 'Intelligenz':'Intelligence','Vektor-Suche':'Vector Search',
734
+ 'Alles Wissen als Vektoren indexiert. Semantische Suche über Insights, Memories, Principles, Errors, Solutions und absorbierten Code.':'All knowledge indexed as vectors. Semantic search across insights, memories, principles, errors, solutions and absorbed code.',
735
+ 'Vektoren gesamt':'Total Vectors','Letzte Indexierung':'Last Indexed','Vektoren':'Vectors',
736
+ 'Fakten-Netzwerk':'Fact Network',
737
+ 'Typisierte Relationen: Subjekt → Prädikat → Objekt. Automatisch extrahiert aus Insights, Error-Solutions und assimilierten Repos.':'Typed relations: Subject → Predicate → Object. Auto-extracted from insights, error-solutions and assimilated repos.',
738
+ 'Fakten gesamt':'Total Facts','Prädikate':'Predicates','Ø Konfidenz':'Avg Confidence',
739
+ 'Nutzungsmuster':'Usage Patterns',
740
+ 'Trackt jeden IPC-Call: welche Tools werden wie oft und wie erfolgreich genutzt.':'Tracks every IPC call: which tools are used how often and how successfully.',
741
+ 'Keine Tool-Daten':'No tool data','Aufrufe':'Calls','Erfolg':'Success',
742
+ 'Proaktive Vorschläge':'Proactive Suggestions','Offen':'Open','Verworfen':'Dismissed','Vorschläge gesamt':'Total Suggestions',
743
+ 'Ø Reward Score':'Avg Reward Score',
744
+ 'Dein Profil':'Your Profile',
745
+ 'Brain lernt dein Verhalten: Skill-Domains, bevorzugte Tools, Arbeitszeiten.':'Brain learns your behavior: skill domains, preferred tools, working hours.',
746
+ 'Skill-Domains':'Skill Domains','Profil-Keys':'Profile Keys','Zuletzt aktualisiert':'Last Updated',
747
+ 'Deine Top-Tools:':'Your Top Tools:',
647
748
  'Multi-Perspektiven-Debatten zu Schlüsselfragen. Jeder Brain liefert seine Sichtweise basierend auf Prinzipien, Hypothesen und Vorhersagen.':'Multi-perspective debates on key questions. Each brain provides its viewpoint based on principles, hypotheses, and predictions.',
648
749
  'Debatten gesamt':'Total Debates','Offen':'Open','Synthesiert':'Synthesized','Letzte Debatten':'Recent Debates',
649
750
  'Advocatus Diaboli — Prinzip-Challenges':'Advocatus Diaboli — Principle Challenges',
@@ -710,7 +811,7 @@ function getLocale() { return currentLang === 'de' ? 'de-DE' : 'en-US'; }
710
811
  function getTitle(page) {
711
812
  const titles = {
712
813
  overview:'Ecosystem Overview', learning:t('Der Lern-Kreislauf'), trading:'Trading Flow',
713
- marketing:'Marketing Flow', crossbrain:'Cross-Brain & Borg', activity:t('Aktivität & Missionen'),
814
+ marketing:'Marketing Flow', intelligence:t('Intelligenz'), crossbrain:'Cross-Brain & Borg', activity:t('Aktivität & Missionen'),
714
815
  debates:'Debates & Challenges', infra:t('Infrastruktur')
715
816
  }; return titles[page] || '';
716
817
  }
@@ -719,6 +820,7 @@ const titles = {
719
820
  learning:'Der Lern-Kreislauf',
720
821
  trading:'Trading Flow',
721
822
  marketing:'Marketing Flow',
823
+ intelligence:'Intelligenz',
722
824
  crossbrain:'Cross-Brain & Borg',
723
825
  activity:'Aktivität & Missionen',
724
826
  debates:'Debates & Challenges',
@@ -748,6 +850,8 @@ function connectSSE() {
748
850
  es.addEventListener('errors', e => { state.errors = JSON.parse(e.data); renderErrors(); });
749
851
  es.addEventListener('selfmod', e => { state.selfmod = JSON.parse(e.data); renderSelfMod(); });
750
852
  es.addEventListener('missions', e => { state.missions = JSON.parse(e.data); renderMissions(); });
853
+ es.addEventListener('repoAbsorber', e => { state.repoAbsorber = JSON.parse(e.data); renderRepoAbsorber(); });
854
+ es.addEventListener('intelligence', e => { state.intelligence = JSON.parse(e.data); renderIntelligence(); });
751
855
  es.addEventListener('knowledge', e => { state.knowledge = JSON.parse(e.data); renderKnowledge(); });
752
856
  es.addEventListener('debates', e => { state.debates = JSON.parse(e.data); renderDebates(); });
753
857
  es.onerror = () => { state.connected = false; updateConnection(); };
@@ -767,12 +871,12 @@ async function loadInitial() {
767
871
  state.watchdog = data.watchdog || []; state.plugins = data.plugins || [];
768
872
  state.borg = data.borg; state.analytics = data.analytics; state.llm = data.llm;
769
873
  state.errors = data.errors; state.selfmod = data.selfmod;
770
- state.missions = data.missions; state.knowledge = data.knowledge;
874
+ state.missions = data.missions; state.knowledge = data.knowledge; state.repoAbsorber = data.repoAbsorber; state.intelligence = data.intelligence;
771
875
  state.debates = data.debates;
772
876
  if (data.thoughts) { state.thoughts = data.thoughts; renderThoughts(); }
773
877
  renderEcosystem(); renderEngines(); renderWatchdog(); renderPlugins();
774
878
  renderBorg(); renderAnalytics(); renderLLM(); renderErrors();
775
- renderSelfMod(); renderMissions(); renderKnowledge(); renderDebates();
879
+ renderSelfMod(); renderMissions(); renderRepoAbsorber(); renderIntelligence(); renderKnowledge(); renderDebates();
776
880
  } catch {}
777
881
  }
778
882
 
@@ -955,6 +1059,124 @@ function renderMissions() {
955
1059
  }).join('');
956
1060
  }
957
1061
 
1062
+ // ── Repo Absorber ────────────────────────────────────────
1063
+ function renderRepoAbsorber() {
1064
+ const d = state.repoAbsorber;
1065
+ if (!d || !d.status) {
1066
+ setText('ra-total', 0); setText('ra-queue', 0); setText('ra-last', '—');
1067
+ document.getElementById('absorberHistory').innerHTML = `<div class="empty">${t('Noch keine Repos assimiliert')}</div>`;
1068
+ return;
1069
+ }
1070
+ setText('ra-total', d.status.totalAbsorbed || 0);
1071
+ setText('ra-queue', d.status.queueSize || 0);
1072
+ setText('ra-last', d.status.lastAbsorbed || '—');
1073
+
1074
+ const list = d.history || [];
1075
+ const el = document.getElementById('absorberHistory');
1076
+ if (!list.length) { el.innerHTML = `<div class="empty">${t('Noch keine Repos assimiliert')}</div>`; return; }
1077
+ el.innerHTML = list.map(r => `<div class="card" style="padding:8px 12px;margin-bottom:6px;display:flex;justify-content:space-between;align-items:center">
1078
+ <div>
1079
+ <div style="font-weight:600;color:var(--cyan)">${escHtml(r.name)}</div>
1080
+ <div style="font-size:11px;color:var(--text-dim)">${r.filesScanned} ${t('Dateien')} · ${r.ragVectors} RAG · ${r.factsExtracted} Facts · ${(r.durationMs/1000).toFixed(1)}s</div>
1081
+ </div>
1082
+ <div style="font-size:11px;color:var(--text-dim)">${r.absorbedAt ? new Date(r.absorbedAt).toLocaleString(getLocale(), {day:'2-digit',month:'2-digit',hour:'2-digit',minute:'2-digit'}) : ''}</div>
1083
+ </div>`).join('');
1084
+ }
1085
+
1086
+ // ── Intelligence ─────────────────────────────────────────
1087
+ function renderIntelligence() {
1088
+ const d = state.intelligence;
1089
+ if (!d) return;
1090
+
1091
+ // RAG
1092
+ if (d.rag) {
1093
+ setText('int-rag-total', (d.rag.totalVectors || 0).toLocaleString());
1094
+ const cols = d.rag.collections || [];
1095
+ setText('int-rag-collections', cols.length);
1096
+ setText('int-rag-indexed', d.rag.lastIndexedAt ? new Date(d.rag.lastIndexedAt).toLocaleString(getLocale(), {day:'2-digit',month:'2-digit',hour:'2-digit',minute:'2-digit'}) : '—');
1097
+ const el = document.getElementById('ragCollections');
1098
+ if (cols.length) {
1099
+ el.innerHTML = cols.map(c => `<div class="card" style="padding:6px 12px;margin-bottom:4px;display:flex;justify-content:space-between">
1100
+ <span style="color:var(--cyan)">${escHtml(c.collection)}</span>
1101
+ <span style="color:var(--text-dim)">${(c.count||0).toLocaleString()} ${t('Vektoren')}</span>
1102
+ </div>`).join('');
1103
+ }
1104
+ }
1105
+
1106
+ // Knowledge Graph
1107
+ if (d.kg) {
1108
+ setText('int-kg-facts', (d.kg.totalFacts || 0).toLocaleString());
1109
+ const preds = d.kg.predicateDistribution || {};
1110
+ const predKeys = Object.keys(preds);
1111
+ setText('int-kg-predicates', predKeys.length);
1112
+ setText('int-kg-confidence', ((d.kg.avgConfidence || 0) * 100).toFixed(0) + '%');
1113
+ const el = document.getElementById('kgPredicates');
1114
+ if (predKeys.length) {
1115
+ const sorted = predKeys.sort((a,b) => preds[b] - preds[a]).slice(0, 10);
1116
+ el.innerHTML = sorted.map(k => `<div class="card" style="padding:6px 12px;margin-bottom:4px;display:flex;justify-content:space-between">
1117
+ <span style="color:var(--green)">${escHtml(k)}</span>
1118
+ <span style="color:var(--text-dim)">${preds[k]}</span>
1119
+ </div>`).join('');
1120
+ }
1121
+ }
1122
+
1123
+ // Tool Learning
1124
+ const tools = Array.isArray(d.toolStats) ? d.toolStats : [];
1125
+ const toolEl = document.getElementById('toolStats');
1126
+ if (tools.length) {
1127
+ const top = tools.slice(0, 10);
1128
+ toolEl.innerHTML = `<div style="display:grid;grid-template-columns:1fr 60px 70px 60px;gap:4px;font-size:12px;padding:0 4px">
1129
+ <div style="color:var(--text-dim);font-weight:600">Tool</div>
1130
+ <div style="color:var(--text-dim);font-weight:600;text-align:right">${t('Aufrufe')}</div>
1131
+ <div style="color:var(--text-dim);font-weight:600;text-align:right">${t('Erfolg')}</div>
1132
+ <div style="color:var(--text-dim);font-weight:600;text-align:right">Avg ms</div>
1133
+ </div>` + top.map(t => {
1134
+ const rate = (t.successRate * 100).toFixed(0);
1135
+ const rateColor = t.successRate >= 0.9 ? 'var(--green)' : t.successRate >= 0.7 ? 'var(--yellow)' : 'var(--red)';
1136
+ return `<div class="card" style="padding:4px 8px;margin-bottom:2px;display:grid;grid-template-columns:1fr 60px 70px 60px;gap:4px;font-size:12px">
1137
+ <span style="color:var(--cyan);overflow:hidden;text-overflow:ellipsis;white-space:nowrap" title="${escHtml(t.tool)}">${escHtml(t.tool)}</span>
1138
+ <span style="text-align:right">${t.totalUses}</span>
1139
+ <span style="text-align:right;color:${rateColor}">${rate}%</span>
1140
+ <span style="text-align:right;color:var(--text-dim)">${Math.round(t.avgDuration)}</span>
1141
+ </div>`;
1142
+ }).join('');
1143
+ } else {
1144
+ toolEl.innerHTML = `<div class="empty">${t('Keine Tool-Daten')}</div>`;
1145
+ }
1146
+
1147
+ // Feedback
1148
+ if (d.feedback) {
1149
+ setText('int-fb-positive', d.feedback.positiveCount || 0);
1150
+ setText('int-fb-negative', d.feedback.negativeCount || 0);
1151
+ const reward = d.feedback.avgRewardScore || 0;
1152
+ const rewardEl = document.getElementById('int-fb-reward');
1153
+ rewardEl.textContent = reward.toFixed(2);
1154
+ rewardEl.style.color = reward > 0 ? 'var(--green)' : reward < 0 ? 'var(--red)' : 'var(--text-dim)';
1155
+ }
1156
+
1157
+ // Proactive
1158
+ if (d.proactive) {
1159
+ setText('int-pr-active', d.proactive.activeSuggestions || 0);
1160
+ setText('int-pr-dismissed', d.proactive.dismissedCount || 0);
1161
+ setText('int-pr-total', d.proactive.totalSuggestions || 0);
1162
+ }
1163
+
1164
+ // User Model
1165
+ if (d.userModel) {
1166
+ setText('int-um-domains', d.userModel.domains || 0);
1167
+ setText('int-um-keys', d.userModel.totalKeys || 0);
1168
+ setText('int-um-updated', d.userModel.lastUpdated ? new Date(d.userModel.lastUpdated).toLocaleString(getLocale(), {day:'2-digit',month:'2-digit',hour:'2-digit',minute:'2-digit'}) : '—');
1169
+ }
1170
+ if (d.userProfile && d.userProfile.topTools) {
1171
+ const el = document.getElementById('userTopTools');
1172
+ const tools = d.userProfile.topTools.slice(0, 5);
1173
+ if (tools.length) {
1174
+ el.innerHTML = `<div style="font-size:12px;color:var(--text-dim);margin-bottom:6px">${t('Deine Top-Tools:')}</div>` +
1175
+ tools.map((t,i) => `<span class="badge badge-ok" style="margin:2px">${i+1}. ${escHtml(t)}</span>`).join('');
1176
+ }
1177
+ }
1178
+ }
1179
+
958
1180
  // ── Knowledge Growth ──────────────────────────────────────
959
1181
  function renderKnowledge() {
960
1182
  const d = state.knowledge;
@@ -5,4 +5,6 @@ export { CodeGenerator, runCodeGeneratorMigration } from './code-generator.js';
5
5
  export type { SelfImprovementProposal } from './code-generator.js';
6
6
  export { CodegenServer } from './codegen-server.js';
7
7
  export type { CodegenServerOptions } from './codegen-server.js';
8
+ export { RepoAbsorber } from './repo-absorber.js';
9
+ export type { AbsorbResult, RepoAbsorberStatus } from './repo-absorber.js';
8
10
  export type { CodeMinerConfig, RepoContent, CodeMinerSummary, ExtractedPattern, DependencyPattern, TechStack, ProjectStructure, ReadmePattern, ContextBuilderConfig, BuiltContext, CodeGeneratorConfig, GenerationTrigger, GenerationStatus, GenerationRequest, GenerationResult, GenerationRecord, CodeGeneratorSummary, } from './types.js';
@@ -3,4 +3,5 @@ export { PatternExtractor, runPatternExtractorMigration } from './pattern-extrac
3
3
  export { ContextBuilder } from './context-builder.js';
4
4
  export { CodeGenerator, runCodeGeneratorMigration } from './code-generator.js';
5
5
  export { CodegenServer } from './codegen-server.js';
6
+ export { RepoAbsorber } from './repo-absorber.js';
6
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/codegen/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AACxF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAE/E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/codegen/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AACxF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAE/E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,83 @@
1
+ import type Database from 'better-sqlite3';
2
+ import type { ThoughtStream } from '../consciousness/thought-stream.js';
3
+ import type { RAGEngine } from '../rag/rag-engine.js';
4
+ import type { KnowledgeGraphEngine } from '../knowledge-graph/graph-engine.js';
5
+ export interface AbsorbResult {
6
+ repo: string;
7
+ filesScanned: number;
8
+ patternsFound: number;
9
+ factsExtracted: number;
10
+ ragVectorsAdded: number;
11
+ durationMs: number;
12
+ }
13
+ export interface RepoAbsorberStatus {
14
+ totalAbsorbed: number;
15
+ lastAbsorbed: string | null;
16
+ queueSize: number;
17
+ }
18
+ interface RepoCandidate {
19
+ name: string;
20
+ url: string;
21
+ source: string;
22
+ relevance: number;
23
+ }
24
+ export declare class RepoAbsorber {
25
+ private readonly db;
26
+ private readonly log;
27
+ private thoughtStream;
28
+ private ragEngine;
29
+ private knowledgeGraph;
30
+ private totalAbsorbed;
31
+ private lastAbsorbed;
32
+ constructor(db: Database.Database);
33
+ setThoughtStream(ts: ThoughtStream): void;
34
+ setRAGEngine(rag: RAGEngine): void;
35
+ setKnowledgeGraph(kg: KnowledgeGraphEngine): void;
36
+ private ensureTable;
37
+ /**
38
+ * Pick the next repo to absorb from TechRadar + DataScout discoveries.
39
+ * Skips repos already absorbed.
40
+ */
41
+ getNextCandidate(): RepoCandidate | null;
42
+ /**
43
+ * Absorb one repo: clone → scan → index → delete.
44
+ * Returns null if no candidate available.
45
+ */
46
+ absorbNext(): Promise<AbsorbResult | null>;
47
+ /**
48
+ * Recursively scan for code files, respecting limits.
49
+ */
50
+ private scanFiles;
51
+ /**
52
+ * Extract structured patterns from a code file for the Knowledge Graph.
53
+ */
54
+ private extractCodePatterns;
55
+ /**
56
+ * Count interesting patterns in a file (for stats).
57
+ */
58
+ private countPatterns;
59
+ /**
60
+ * Detect test framework from package.json.
61
+ */
62
+ private detectTestFramework;
63
+ /**
64
+ * Normalize various GitHub URL formats to a clonable URL.
65
+ */
66
+ private normalizeGitUrl;
67
+ getStatus(): RepoAbsorberStatus;
68
+ /**
69
+ * Get recently absorbed repos from DB.
70
+ */
71
+ getHistory(limit?: number): Array<{
72
+ name: string;
73
+ url: string;
74
+ source: string;
75
+ filesScanned: number;
76
+ patternsFound: number;
77
+ factsExtracted: number;
78
+ ragVectors: number;
79
+ durationMs: number;
80
+ absorbedAt: string;
81
+ }>;
82
+ }
83
+ export {};