[manus] Sovereign Heartbeat — Real-time State Broadcaster (#39) (#40)
Some checks failed
Deploy Nexus / deploy (push) Has been cancelled

Co-authored-by: manus <manus@noreply.143.198.27.163>
Co-committed-by: manus <manus@noreply.143.198.27.163>
This commit was merged in pull request #40.
This commit is contained in:
manus
2026-03-24 02:17:19 +00:00
committed by Timmy Time
parent 6587869984
commit 4f137aa507

173
app.js
View File

@@ -22,6 +22,68 @@ const NEXUS = {
}
};
// ═══ SOVEREIGN STATE (The Heartbeat) ═══
const STATE = {
metrics: {
fps: 0,
drawCalls: 0,
triangles: 0,
uptime: 0,
activeLoops: 5,
cpu: 12,
mem: 4.2
},
agents: {
timmy: 'RUNNING',
kimi: 'STANDBY',
claude: 'ACTIVE',
perplexity: 'STANDBY'
},
thoughts: [
'ANALYZING WORLD...',
'SYNCING MEMORY...',
'WAITING FOR INPUT',
'SOUL ON BITCOIN'
],
lastUpdate: 0,
pulseRate: 1.0 // Hz
};
// ═══ STATE BROADCASTER ═══
const Broadcaster = {
listeners: [],
subscribe(fn) { this.listeners.push(fn); },
broadcast() { this.listeners.forEach(fn => fn(STATE)); }
};
// ═══ STATE UPDATER ═══
function updateSovereignState(elapsed) {
STATE.metrics.uptime = elapsed;
// Simulate some jitter/activity
if (Math.random() > 0.95) {
STATE.metrics.cpu = 10 + Math.floor(Math.random() * 15);
STATE.metrics.activeLoops = 4 + Math.floor(Math.random() * 3);
// Random thought shift
if (Math.random() > 0.7) {
const newThoughts = [
'DECENTRALIZING COGNITION',
'ZAPPING CONTRIBUTORS',
'MAPPING SPATIAL LOOPS',
'REFINING LORA WEIGHTS',
'OBSERVING ALEXANDER',
'NEXUS INTEGRITY: 100%',
'HERMES LINK STABLE'
];
STATE.thoughts.shift();
STATE.thoughts.push(newThoughts[Math.floor(Math.random() * newThoughts.length)]);
}
Broadcaster.broadcast();
}
}
// ═══ STATE ═══
let camera, scene, renderer, composer;
let clock, playerPos, playerRot;
@@ -346,22 +408,23 @@ function createBatcaveTerminal() {
const terminalGroup = new THREE.Group();
terminalGroup.position.set(0, 0, -8);
const panelData = [
{ title: 'NEXUS COMMAND', color: NEXUS.colors.primary, rot: -0.4, x: -6, y: 3, lines: ['> STATUS: NOMINAL', '> UPTIME: 142.4h', '> HARNESS: STABLE', '> MODE: SOVEREIGN'] },
{ title: 'DEV QUEUE', color: NEXUS.colors.gold, rot: -0.2, x: -3, y: 3, lines: ['> ISSUE #4: CORE', '> ISSUE #5: PORTAL', '> ISSUE #6: TERMINAL', '> ISSUE #7: TIMMY'] },
{ title: 'METRICS', color: NEXUS.colors.secondary, rot: 0, x: 0, y: 3, lines: ['> CPU: 12% [||....]', '> MEM: 4.2GB', '> COMMITS: 842', '> ACTIVE LOOPS: 5'] },
{ title: 'THOUGHTS', color: NEXUS.colors.primary, rot: 0.2, x: 3, y: 3, lines: ['> ANALYZING WORLD...', '> SYNCING MEMORY...', '> WAITING FOR INPUT', '> SOUL ON BITCOIN'] },
{ title: 'AGENT STATUS', color: NEXUS.colors.gold, rot: 0.4, x: 6, y: 3, lines: ['> TIMMY: ● RUNNING', '> KIMI: ○ STANDBY', '> CLAUDE: ● ACTIVE', '> PERPLEXITY: ○'] },
const panels = [
{ id: 'command', title: 'NEXUS COMMAND', color: NEXUS.colors.primary, rot: -0.4, x: -6, y: 3 },
{ id: 'queue', title: 'DEV QUEUE', color: NEXUS.colors.gold, rot: -0.2, x: -3, y: 3 },
{ id: 'metrics', title: 'METRICS', color: NEXUS.colors.secondary, rot: 0, x: 0, y: 3 },
{ id: 'thoughts',title: 'THOUGHTS', color: NEXUS.colors.primary, rot: 0.2, x: 3, y: 3 },
{ id: 'agents', title: 'AGENT STATUS', color: NEXUS.colors.gold, rot: 0.4, x: 6, y: 3 },
];
panelData.forEach(data => {
createTerminalPanel(terminalGroup, data.x, data.y, data.rot, data.title, data.color, data.lines);
panels.forEach(data => {
createTerminalPanel(terminalGroup, data);
});
scene.add(terminalGroup);
}
function createTerminalPanel(parent, x, y, rot, title, color, lines) {
function createTerminalPanel(parent, data) {
const { x, y, rot, title, color, id } = data;
const w = 2.8, h = 3.5;
const group = new THREE.Group();
group.position.set(x, y, 0);
@@ -392,25 +455,6 @@ function createTerminalPanel(parent, x, y, rot, title, color, lines) {
textCanvas.height = 640;
const ctx = textCanvas.getContext('2d');
// Header
ctx.fillStyle = '#' + new THREE.Color(color).getHexString();
ctx.font = 'bold 32px "Orbitron", sans-serif';
ctx.fillText(title, 20, 45);
ctx.fillRect(20, 55, 472, 2);
// Lines
ctx.font = '20px "JetBrains Mono", monospace';
ctx.fillStyle = '#a0b8d0';
lines.forEach((line, i) => {
// Color active indicators
let fillColor = '#a0b8d0';
if (line.includes('● RUNNING') || line.includes('● ACTIVE')) fillColor = '#4af0c0';
else if (line.includes('○ STANDBY')) fillColor = '#5a6a8a';
else if (line.includes('NOMINAL')) fillColor = '#4af0c0';
ctx.fillStyle = fillColor;
ctx.fillText(line, 20, 100 + i * 40);
});
const textTexture = new THREE.CanvasTexture(textCanvas);
textTexture.minFilter = THREE.LinearFilter;
const textMat = new THREE.MeshBasicMaterial({
@@ -423,6 +467,56 @@ function createTerminalPanel(parent, x, y, rot, title, color, lines) {
textMesh.position.z = 0.01;
group.add(textMesh);
// Update function for this specific panel
const updatePanel = (state) => {
ctx.clearRect(0, 0, 512, 640);
// Header
ctx.fillStyle = '#' + new THREE.Color(color).getHexString();
ctx.font = 'bold 32px "Orbitron", sans-serif';
ctx.fillText(title, 20, 45);
ctx.fillRect(20, 55, 472, 2);
ctx.font = '20px "JetBrains Mono", monospace';
ctx.fillStyle = '#a0b8d0';
let lines = [];
if (id === 'command') {
lines = [
`> STATUS: NOMINAL`,
`> UPTIME: ${state.metrics.uptime.toFixed(1)}s`,
`> HARNESS: STABLE`,
`> MODE: SOVEREIGN`
];
} else if (id === 'queue') {
lines = ['> ISSUE #4: CORE', '> ISSUE #5: PORTAL', '> ISSUE #6: TERMINAL', '> ISSUE #39: HEART'];
} else if (id === 'metrics') {
lines = [
`> CPU: ${state.metrics.cpu}%`,
`> MEM: ${state.metrics.mem}GB`,
`> LOOPS: ${state.metrics.activeLoops}`,
`> FPS: ${state.metrics.fps}`
];
} else if (id === 'thoughts') {
lines = state.thoughts.map(t => `> ${t}`);
} else if (id === 'agents') {
lines = Object.entries(state.agents).map(([name, status]) => `> ${name.toUpperCase()}: ${status}`);
}
lines.forEach((line, i) => {
let fillColor = '#a0b8d0';
if (line.includes('RUNNING') || line.includes('ACTIVE')) fillColor = '#4af0c0';
ctx.fillStyle = fillColor;
ctx.fillText(line, 20, 100 + i * 40);
});
textTexture.needsUpdate = true;
};
// Initial draw
updatePanel(STATE);
Broadcaster.subscribe(updatePanel);
// Scanline effect overlay
const scanGeo = new THREE.PlaneGeometry(w, h);
const scanMat = new THREE.ShaderMaterial({
@@ -458,18 +552,6 @@ function createTerminalPanel(parent, x, y, rot, title, color, lines) {
scanMesh.position.z = 0.02;
group.add(scanMesh);
// Glow behind panel
const glowGeo = new THREE.PlaneGeometry(w + 0.5, h + 0.5);
const glowMat = new THREE.MeshBasicMaterial({
color: color,
transparent: true,
opacity: 0.06,
side: THREE.DoubleSide,
});
const glowMesh = new THREE.Mesh(glowGeo, glowMat);
glowMesh.position.z = -0.05;
group.add(glowMesh);
parent.add(group);
batcaveTerminals.push({ group, scanMat, borderMat });
}
@@ -877,6 +959,9 @@ function gameLoop() {
const delta = Math.min(clock.getDelta(), 0.1);
const elapsed = clock.elapsedTime;
// ─── Sovereign State Update ─────────────────────────────────────
updateSovereignState(elapsed);
// ─── Navigation update ───────────────────────────────────────────
const mode = NAV_MODES[navModeIdx];
const chatActive = document.activeElement === document.getElementById('chat-input');
@@ -993,6 +1078,7 @@ function gameLoop() {
core.position.y = 2.5 + Math.sin(elapsed * 1.2) * 0.3;
core.rotation.y = elapsed * 0.4;
core.rotation.x = elapsed * 0.2;
// Core pulses in sync with state updates (simulated heartbeat)
core.material.emissiveIntensity = 1.5 + Math.sin(elapsed * 2) * 0.5;
}
@@ -1006,11 +1092,14 @@ function gameLoop() {
fps = frameCount;
frameCount = 0;
lastFPSTime = now;
// Update state metrics
STATE.metrics.fps = fps;
STATE.metrics.drawCalls = renderer.info.render.calls;
STATE.metrics.triangles = renderer.info.render.triangles;
}
if (debugOverlay) {
const info = renderer.info;
debugOverlay.textContent =
`FPS: ${fps} Draw: ${info.render?.calls} Tri: ${info.render?.triangles} [${performanceTier}]\n` +
`FPS: ${fps} Draw: ${renderer.info.render.calls} Tri: ${renderer.info.render.triangles} [${performanceTier}]\n` +
`Pos: ${playerPos.x.toFixed(1)}, ${playerPos.y.toFixed(1)}, ${playerPos.z.toFixed(1)} NAV: ${NAV_MODES[navModeIdx]}`;
}
renderer.info.reset();