@timmeck/brain-core 2.36.17 → 2.36.18

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.
Files changed (2) hide show
  1. package/command-center.html +112 -12
  2. package/package.json +1 -1
@@ -648,31 +648,131 @@ function drawPeerGraph(brains) {
648
648
  }
649
649
  }
650
650
 
651
- // ── Canvas: Cross-Brain Animation ─────────────────────────
651
+ // ── Canvas: Cross-Brain + Borg Animation ──────────────────
652
652
  let particles = [];
653
+ let borgPackets = []; // big borg sync packets
654
+ function spawnBorgPacket(src, dst, items) {
655
+ borgPackets.push({ src, dst, items, progress: 0, speed: 0.004 + Math.random() * 0.003 });
656
+ }
657
+ // When borg data updates, spawn visual packets from history
658
+ let lastBorgHistLen = 0;
659
+ function checkBorgPackets() {
660
+ const h = state.borg?.history || [];
661
+ if (h.length > lastBorgHistLen && lastBorgHistLen > 0) {
662
+ const newEntries = h.slice(0, h.length - lastBorgHistLen);
663
+ for (const e of newEntries) {
664
+ const src = e.direction === 'sent' ? 'brain' : e.peer;
665
+ const dst = e.direction === 'sent' ? e.peer : 'brain';
666
+ spawnBorgPacket(src, dst, e.itemCount || 1);
667
+ }
668
+ }
669
+ lastBorgHistLen = h.length;
670
+ }
671
+
653
672
  function initCrossBrainCanvas() {
654
673
  const canvas = document.getElementById('crossBrainCanvas'); if (!canvas) return;
655
674
  function resize() { const r=canvas.parentElement.getBoundingClientRect(); canvas.width=r.width*2; canvas.height=r.height*2; }
656
675
  resize(); window.addEventListener('resize', resize);
657
676
  const positions = {};
658
- function getPos() { const w=canvas.width/2,h=canvas.height/2; positions.brain={x:w/2,y:50,color:'#00e5ff',label:'Brain'}; positions['trading-brain']={x:w*.2,y:h-50,color:'#00ff88',label:'Trading'}; positions['marketing-brain']={x:w*.8,y:h-50,color:'#ff44cc',label:'Marketing'}; }
659
- function spawn() { const n=Object.keys(positions); if(n.length<2)return; let s=n[Math.random()*n.length|0],d=n[Math.random()*n.length|0]; while(d===s)d=n[Math.random()*n.length|0]; const a=positions[s],b=positions[d]; particles.push({x:a.x,y:a.y,tx:b.x,ty:b.y,color:a.color,progress:0,speed:.008+Math.random()*.012}); }
677
+ function getPos() {
678
+ const w=canvas.width/2, h=canvas.height/2;
679
+ positions.brain={x:w/2,y:55,color:'#00e5ff',label:'Brain'};
680
+ positions['trading-brain']={x:w*.2,y:h-55,color:'#00ff88',label:'Trading'};
681
+ positions['marketing-brain']={x:w*.8,y:h-55,color:'#ff44cc',label:'Marketing'};
682
+ }
683
+ function spawnMsg() {
684
+ const n=Object.keys(positions); if(n.length<2)return;
685
+ let s=n[Math.random()*n.length|0],d=n[Math.random()*n.length|0];
686
+ while(d===s)d=n[Math.random()*n.length|0];
687
+ const a=positions[s],b=positions[d];
688
+ particles.push({x:a.x,y:a.y,tx:b.x,ty:b.y,color:a.color,progress:0,speed:.008+Math.random()*.012,isBorg:false});
689
+ }
690
+
660
691
  function draw() {
661
- const ctx=canvas.getContext('2d'),w=canvas.width/2,h=canvas.height/2; ctx.save(); ctx.scale(2,2); ctx.clearRect(0,0,w,h); getPos();
692
+ const ctx=canvas.getContext('2d'),w=canvas.width/2,h=canvas.height/2;
693
+ ctx.save(); ctx.scale(2,2); ctx.clearRect(0,0,w,h); getPos();
694
+ checkBorgPackets();
695
+
696
+ const borgEnabled = state.borg?.status?.enabled;
697
+ const borgSent = state.borg?.status?.totalSent || 0;
698
+ const borgRecv = state.borg?.status?.totalReceived || 0;
662
699
  const n=Object.keys(positions);
663
- for(let i=0;i<n.length;i++) for(let j=i+1;j<n.length;j++) { const a=positions[n[i]],b=positions[n[j]]; ctx.beginPath(); ctx.moveTo(a.x,a.y); ctx.lineTo(b.x,b.y); ctx.strokeStyle='rgba(100,140,255,0.1)'; ctx.lineWidth=1; ctx.stroke(); }
664
- if(Math.random()<.05&&state.connected) spawn();
700
+
701
+ // Draw connections
702
+ for(let i=0;i<n.length;i++) for(let j=i+1;j<n.length;j++) {
703
+ const a=positions[n[i]],b=positions[n[j]];
704
+ // Borg connections glow brighter when enabled
705
+ ctx.beginPath(); ctx.moveTo(a.x,a.y); ctx.lineTo(b.x,b.y);
706
+ ctx.strokeStyle = borgEnabled ? 'rgba(170,136,255,0.15)' : 'rgba(100,140,255,0.1)';
707
+ ctx.lineWidth = borgEnabled ? 2 : 1;
708
+ ctx.stroke();
709
+ // Dashed borg overlay
710
+ if (borgEnabled) {
711
+ ctx.beginPath(); ctx.setLineDash([4,8]); ctx.moveTo(a.x,a.y); ctx.lineTo(b.x,b.y);
712
+ ctx.strokeStyle='rgba(170,136,255,0.12)'; ctx.lineWidth=1; ctx.stroke(); ctx.setLineDash([]);
713
+ }
714
+ }
715
+
716
+ // Regular message particles
717
+ if(Math.random()<.05&&state.connected) spawnMsg();
665
718
  particles=particles.filter(p=>p.progress<1);
666
- for(const p of particles) { p.progress+=p.speed; const t=p.progress,cx=p.x+(p.tx-p.x)*t,cy=p.y+(p.ty-p.y)*t-Math.sin(t*Math.PI)*20;
719
+ for(const p of particles) {
720
+ p.progress+=p.speed;
721
+ const t=p.progress,cx=p.x+(p.tx-p.x)*t,cy=p.y+(p.ty-p.y)*t-Math.sin(t*Math.PI)*20;
667
722
  ctx.beginPath(); ctx.arc(cx,cy,3,0,Math.PI*2); ctx.fillStyle=p.color; ctx.fill();
668
- ctx.beginPath(); ctx.arc(cx,cy,6,0,Math.PI*2); const g=ctx.createRadialGradient(cx,cy,0,cx,cy,6); g.addColorStop(0,p.color+'40'); g.addColorStop(1,p.color+'00'); ctx.fillStyle=g; ctx.fill();
723
+ const g=ctx.createRadialGradient(cx,cy,0,cx,cy,6); g.addColorStop(0,p.color+'40'); g.addColorStop(1,p.color+'00');
724
+ ctx.beginPath(); ctx.arc(cx,cy,6,0,Math.PI*2); ctx.fillStyle=g; ctx.fill();
725
+ }
726
+
727
+ // Borg sync packets — bigger, purple, with item count label
728
+ borgPackets=borgPackets.filter(p=>p.progress<1);
729
+ for(const bp of borgPackets) {
730
+ bp.progress+=bp.speed;
731
+ const t=bp.progress;
732
+ const sp=positions[bp.src]||positions.brain, dp=positions[bp.dst]||positions.brain;
733
+ const cx=sp.x+(dp.x-sp.x)*t, cy=sp.y+(dp.y-sp.y)*t-Math.sin(t*Math.PI)*35;
734
+ // Outer glow
735
+ ctx.beginPath(); ctx.arc(cx,cy,14,0,Math.PI*2);
736
+ const gg=ctx.createRadialGradient(cx,cy,0,cx,cy,14);
737
+ gg.addColorStop(0,'rgba(170,136,255,0.35)'); gg.addColorStop(1,'rgba(170,136,255,0)');
738
+ ctx.fillStyle=gg; ctx.fill();
739
+ // Inner packet
740
+ ctx.beginPath(); ctx.arc(cx,cy,6,0,Math.PI*2); ctx.fillStyle='#aa88ff'; ctx.fill();
741
+ ctx.beginPath(); ctx.arc(cx,cy,4,0,Math.PI*2); ctx.fillStyle='#ddccff'; ctx.fill();
742
+ // Item count label
743
+ if(bp.items>0) {
744
+ ctx.fillStyle='#fff'; ctx.font='bold 9px Segoe UI,sans-serif'; ctx.textAlign='center';
745
+ ctx.fillText(bp.items+'x',cx,cy-12);
746
+ }
669
747
  }
670
- for(const[,p]of Object.entries(positions)) {
671
- ctx.beginPath(); ctx.arc(p.x,p.y,28,0,Math.PI*2); const g=ctx.createRadialGradient(p.x,p.y,0,p.x,p.y,28); g.addColorStop(0,p.color+'25'); g.addColorStop(1,p.color+'00'); ctx.fillStyle=g; ctx.fill();
672
- ctx.beginPath(); ctx.arc(p.x,p.y,18,0,Math.PI*2); ctx.fillStyle=p.color+'15'; ctx.strokeStyle=p.color; ctx.lineWidth=2; ctx.fill(); ctx.stroke();
748
+
749
+ // Draw nodes
750
+ for(const[name,p]of Object.entries(positions)) {
751
+ // Borg ring (purple outer ring when borg enabled)
752
+ if(borgEnabled) {
753
+ ctx.beginPath(); ctx.arc(p.x,p.y,24,0,Math.PI*2);
754
+ ctx.strokeStyle='rgba(170,136,255,0.25)'; ctx.lineWidth=1; ctx.stroke();
755
+ }
756
+ // Glow
757
+ ctx.beginPath(); ctx.arc(p.x,p.y,28,0,Math.PI*2);
758
+ const g=ctx.createRadialGradient(p.x,p.y,0,p.x,p.y,28);
759
+ g.addColorStop(0,p.color+'25'); g.addColorStop(1,p.color+'00'); ctx.fillStyle=g; ctx.fill();
760
+ // Circle
761
+ ctx.beginPath(); ctx.arc(p.x,p.y,18,0,Math.PI*2);
762
+ ctx.fillStyle=p.color+'15'; ctx.strokeStyle=p.color; ctx.lineWidth=2; ctx.fill(); ctx.stroke();
763
+ // Inner dot
673
764
  ctx.beginPath(); ctx.arc(p.x,p.y,5,0,Math.PI*2); ctx.fillStyle=p.color; ctx.fill();
674
- ctx.fillStyle='#fff'; ctx.font='12px Segoe UI,sans-serif'; ctx.textAlign='center'; ctx.fillText(p.label,p.x,p.y+34);
765
+ // Label
766
+ ctx.fillStyle='#fff'; ctx.font='12px Segoe UI,sans-serif'; ctx.textAlign='center';
767
+ ctx.fillText(p.label,p.x,p.y+34);
768
+ }
769
+
770
+ // Borg legend (bottom center)
771
+ if(borgEnabled) {
772
+ ctx.fillStyle='rgba(170,136,255,0.7)'; ctx.font='10px Segoe UI,sans-serif'; ctx.textAlign='center';
773
+ ctx.fillText(`BORG ACTIVE \u2022 ${borgSent} sent \u2022 ${borgRecv} received`, w/2, h-8);
675
774
  }
775
+
676
776
  ctx.restore(); requestAnimationFrame(draw);
677
777
  }
678
778
  draw();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timmeck/brain-core",
3
- "version": "2.36.17",
3
+ "version": "2.36.18",
4
4
  "description": "Shared core infrastructure for the Brain ecosystem — IPC, MCP, CLI, DB connection, and utilities",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",