diff options
| author | Agando <roduccomm@gmail.com> | 2026-07-09 06:00:32 +0200 |
|---|---|---|
| committer | Agando <roduccomm@gmail.com> | 2026-07-09 06:00:32 +0200 |
| commit | 2538c91876455fe96febf441fc8dde20f2606023 (patch) | |
| tree | b74c949cdf4296d10103dd57ef8178ba427a5b39 /downloads/memory | |
| parent | ea4d09fb5ccba12ed774fcf7c913edfa1e6a851a (diff) | |
auto: 2026-07-09_06:00 changes
Diffstat (limited to 'downloads/memory')
| -rw-r--r-- | downloads/memory/newos-architecture-3d.html | 612 | ||||
| -rw-r--r-- | downloads/memory/release-arc-3d.html | 384 |
2 files changed, 996 insertions, 0 deletions
diff --git a/downloads/memory/newos-architecture-3d.html b/downloads/memory/newos-architecture-3d.html new file mode 100644 index 0000000..c1f30e5 --- /dev/null +++ b/downloads/memory/newos-architecture-3d.html @@ -0,0 +1,612 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="UTF-8"> +<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"> +<meta name="theme-color" content="#0a0e1a"> +<meta name="apple-mobile-web-app-capable" content="yes"> +<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> +<title>newOS4 · Mobile Architecture</title> +<style> + *, *::before, *::after { + box-sizing: border-box; + margin: 0; + padding: 0; + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + -webkit-user-select: none; + user-select: none; + } + html, body { + width: 100%; + height: 100%; + height: 100dvh; + overflow: hidden; + background: #0a0e1a; + color: #e8eef7; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + overscroll-behavior: none; + touch-action: none; + } + body { + position: fixed; + inset: 0; + background: radial-gradient(ellipse at center, #131a2c 0%, #0a0e1a 70%); + } + #scene { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + touch-action: none; + cursor: grab; + } + #scene.dragging { cursor: grabbing; } + + /* HUD — top-left, always visible, big enough to read on phone */ + #hud { + position: absolute; + top: max(env(safe-area-inset-top, 0px), 12px); + left: 12px; + z-index: 10; + pointer-events: none; + line-height: 1.35; + } + #hud .title { + font-size: 16px; + font-weight: 700; + letter-spacing: 0.3px; + color: #7dd3fc; + text-shadow: 0 0 8px rgba(125, 211, 252, 0.4); + } + #hud .sub { + font-size: 12px; + font-weight: 500; + color: #94a3b8; + margin-top: 2px; + } + #hud .hint { + font-size: 11px; + color: #64748b; + margin-top: 6px; + max-width: 220px; + } + + /* Node info card — top-right, big text */ + #card { + position: absolute; + top: max(env(safe-area-inset-top, 0px), 12px); + right: 12px; + z-index: 20; + max-width: min(78vw, 320px); + background: rgba(15, 22, 38, 0.92); + border: 1px solid rgba(125, 211, 252, 0.35); + border-radius: 12px; + padding: 14px 16px; + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + box-shadow: 0 10px 30px rgba(0,0,0,0.4), 0 0 0 1px rgba(125,211,252,0.08) inset; + pointer-events: none; + transform: translateX(20px); + opacity: 0; + transition: transform 0.18s ease-out, opacity 0.18s ease-out; + } + #card.visible { + transform: translateX(0); + opacity: 1; + } + #card .name { + font-size: 18px; + font-weight: 700; + color: #fff; + margin-bottom: 4px; + } + #card .layer { + display: inline-block; + font-size: 11px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.8px; + padding: 3px 8px; + border-radius: 4px; + margin-bottom: 8px; + } + #card .desc { + font-size: 14px; + line-height: 1.45; + color: #cbd5e1; + } + #card .close { + position: absolute; + top: 8px; + right: 8px; + width: 24px; + height: 24px; + border-radius: 12px; + background: rgba(255,255,255,0.08); + display: flex; + align-items: center; + justify-content: center; + font-size: 14px; + color: #94a3b8; + pointer-events: auto; + cursor: pointer; + } + + /* Control bar — bottom-center, big touch targets */ + #controls { + position: absolute; + bottom: max(env(safe-area-inset-bottom, 0px), 16px); + left: 50%; + transform: translateX(-50%); + z-index: 10; + display: flex; + gap: 8px; + padding: 8px; + background: rgba(15, 22, 38, 0.75); + border: 1px solid rgba(255,255,255,0.08); + border-radius: 32px; + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + } + .btn { + width: 44px; + height: 44px; + border-radius: 22px; + background: rgba(255,255,255,0.05); + border: 1px solid rgba(255,255,255,0.08); + color: #cbd5e1; + font-size: 18px; + font-weight: 600; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: background 0.15s, transform 0.1s; + } + .btn:active { + background: rgba(125, 211, 252, 0.2); + transform: scale(0.92); + } + .btn.active { + background: rgba(125, 211, 252, 0.18); + color: #7dd3fc; + border-color: rgba(125, 211, 252, 0.4); + } + + /* Status — bottom-left */ + #status { + position: absolute; + bottom: max(env(safe-area-inset-bottom, 0px), 24px); + left: 12px; + z-index: 10; + font-size: 11px; + color: #64748b; + pointer-events: none; + } + #status .dot { + display: inline-block; + width: 6px; + height: 6px; + border-radius: 3px; + background: #22c55e; + margin-right: 6px; + vertical-align: middle; + box-shadow: 0 0 6px #22c55e; + } + + /* SVG node label — big, never tiny */ + .label { + font-size: 13px; + font-weight: 600; + fill: #e2e8f0; + paint-order: stroke; + stroke: #0a0e1a; + stroke-width: 3px; + stroke-linejoin: round; + pointer-events: none; + text-anchor: middle; + dominant-baseline: middle; + } + .label.sub { + font-size: 10px; + font-weight: 500; + fill: #94a3b8; + } + .node-hit { + cursor: pointer; + transition: opacity 0.15s; + } + .node-hit.pinned { + opacity: 1; + } + .node-circle { + transition: r 0.15s, filter 0.15s; + } + .node-circle.pinned { + filter: drop-shadow(0 0 6px currentColor); + } + + /* Pulse animation overlay (CSS, fires once on demand) */ + @keyframes pulseRing { + 0% { transform: scale(0.6); opacity: 0.9; } + 100% { transform: scale(2.4); opacity: 0; } + } + .pulse-ring { + position: absolute; + width: 80px; + height: 80px; + border-radius: 50%; + border: 2px solid #7dd3fc; + pointer-events: none; + animation: pulseRing 1.2s ease-out forwards; + z-index: 5; + } +</style> +</head> +<body> + +<div id="hud"> + <div class="title">newOS4</div> + <div class="sub">41 modules · 24 skills · 303 files</div> + <div class="hint">Drag to orbit · Tap a node</div> +</div> + +<div id="card"> + <div class="close" id="cardClose">×</div> + <div class="layer" id="cardLayer">CORE</div> + <div class="name" id="cardName">—</div> + <div class="desc" id="cardDesc">—</div> +</div> + +<div id="controls"> + <button class="btn" id="btnReset" title="Reset view">⌂</button> + <button class="btn" id="btnPulse" title="Pulse">~</button> + <button class="btn" id="btnLabels" title="Toggle labels">A</button> + <button class="btn" id="btnFlows" title="Toggle flows">◉</button> + <button class="btn" id="btnHelp" title="Help">?</button> +</div> + +<div id="status"><span class="dot"></span><span id="statusText">idle</span></div> + +<svg id="scene" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 700" preserveAspectRatio="xMidYMid meet"> + <defs> + <radialGradient id="bgGrad" cx="50%" cy="50%" r="70%"> + <stop offset="0%" stop-color="#1a2440" stop-opacity="0.6"/> + <stop offset="100%" stop-color="#0a0e1a" stop-opacity="0"/> + </radialGradient> + <filter id="glow" x="-50%" y="-50%" width="200%" height="200%"> + <feGaussianBlur stdDeviation="2" result="blur"/> + <feMerge> + <feMergeNode in="blur"/> + <feMergeNode in="SourceGraphic"/> + </feMerge> + </filter> + </defs> + + <!-- Star field (static, cheap) --> + <g id="stars" opacity="0.6"></g> + + <!-- Background gradient overlay --> + <rect x="0" y="0" width="400" height="700" fill="url(#bgGrad)" pointer-events="none"/> + + <!-- Edges layer --> + <g id="edges" fill="none" stroke-linecap="round"></g> + + <!-- Nodes layer --> + <g id="nodes"></g> + + <!-- Labels layer --> + <g id="labels"></g> +</svg> + +<script> +(() => { + 'use strict'; + + // ---------- DATA ---------- + const layers = { + core: { color: '#7dd3fc', name: 'Core', y: 90 }, + ai: { color: '#a78bfa', name: 'AI Engine', y: 200 }, + ext: { color: '#34d399', name: 'Extensions', y: 310 }, + user: { color: '#fbbf24', name: 'User Space', y: 430 }, + world: { color: '#f472b6', name: 'World Model', y: 560 }, + }; + + const nodes = [ + // Core + { id: 'kernel', layer: 'core', label: 'Kernel', x: 200, r: 22 }, + { id: 'vfs', layer: 'core', label: 'VFS', x: 110, r: 18 }, + { id: 'modules', layer: 'core', label: 'Modules', x: 290, r: 18 }, + { id: 'skills', layer: 'core', label: 'Skills', x: 60, r: 16 }, + { id: 'agents', layer: 'core', label: 'Agents', x: 340, r: 16 }, + + // AI + { id: 'llm', layer: 'ai', label: 'LLM', x: 200, r: 22 }, + { id: 'router', layer: 'ai', label: 'Router', x: 100, r: 17 }, + { id: 'memory', layer: 'ai', label: 'Memory', x: 300, r: 18 }, + { id: 'tools', layer: 'ai', label: 'Tools', x: 40, r: 15 }, + { id: 'prompts', layer: 'ai', label: 'Prompts', x: 360, r: 15 }, + + // Extensions + { id: 'wallet', layer: 'ext', label: 'Wallet', x: 150, r: 20 }, + { id: 'wpm', layer: 'ext', label: 'WPM', x: 270, r: 17 }, + { id: 'webdav', layer: 'ext', label: 'WebDAV', x: 60, r: 16 }, + { id: 'cron', layer: 'ext', label: 'Cron', x: 340, r: 16 }, + { id: 'sandbox', layer: 'ext', label: 'Sandbox', x: 220, r: 15 }, + + // User + { id: 'profile', layer: 'user', label: 'Profile', x: 100, r: 17 }, + { id: 'sessions', layer: 'user', label: 'Sessions', x: 220, r: 18 }, + { id: 'vault', layer: 'user', label: 'Vault', x: 320, r: 17 }, + + // World Model + { id: 'wm', layer: 'world', label: 'WorldModel', x: 200, r: 22 }, + { id: 'graph', layer: 'world', label: 'Graph', x: 100, r: 17 }, + { id: 'predict', layer: 'world', label: 'Predict', x: 300, r: 18 }, + ]; + + const descs = { + kernel: 'System core. Mounts modules, routes commands, owns the event loop.', + vfs: 'Virtual filesystem. Resolves paths, lists dirs, reads/writes files.', + modules: '41 modules loaded. Core + extension. Hot-reloadable.', + skills: '24 markdown skills. Searchable, patchable, versioned.', + agents: '3 worker agents. Delegate tasks with capabilities.', + llm: 'MiniMax-M3 by MiniMax. Coding-tuned, 2026-01 cutoff.', + router: 'Routes tool calls to the right module. Zero-fallback chain.', + memory: '37 nodes, 51 edges in the memory graph. Auto-pruned.', + tools: '21 tools: read/write, modules, web, vault, agents.', + prompts: 'System + per-task prompts. Editable via edit_module.', + wallet: 'Wallet lookup, no auth. Read-only Hyperliquid queries.', + wpm: 'WebX11 Package Manager. Install modules with one command.', + webdav: 'Remote filesystem. Mount, browse, edit over HTTPS.', + cron: 'Scheduled tasks. Cron expressions in skill files.', + sandbox: 'Isolated JS execution. node -e, browser JS only.', + profile: 'User preferences. preferredModel, history, settings.', + sessions: 'Session save/load. Date-keyed, terminal-aware.', + vault: 'Secret vault. Hyperliquid keys, API tokens, encrypted.', + wm: 'Self-awareness model. Ask about state, health, projects.', + graph: 'Knowledge graph. 37 nodes linking tasks to files.', + predict: 'Predict task duration, tokens, confidence. ML-trained.', + }; + + const edges = [ + ['kernel','vfs'], ['kernel','modules'], ['kernel','skills'], ['kernel','agents'], + ['llm','router'], ['llm','memory'], ['llm','tools'], ['llm','prompts'], + ['modules','wallet'], ['modules','wpm'], ['modules','webdav'], ['modules','cron'], ['modules','sandbox'], + ['profile','sessions'], ['profile','vault'], + ['wm','graph'], ['wm','predict'], + ['llm','wm'], ['kernel','llm'], + ]; + + // ---------- RENDER ---------- + const svg = document.getElementById('scene'); + const starsG = document.getElementById('stars'); + const edgesG = document.getElementById('edges'); + const nodesG = document.getElementById('nodes'); + const labelsG = document.getElementById('labels'); + const card = document.getElementById('card'); + const cardName = document.getElementById('cardName'); + const cardDesc = document.getElementById('cardDesc'); + const cardLayer = document.getElementById('cardLayer'); + const cardClose = document.getElementById('cardClose'); + const statusText = document.getElementById('statusText'); + + // Stars + (function makeStars() { + let s = ''; + for (let i = 0; i < 60; i++) { + const x = Math.random() * 400; + const y = Math.random() * 700; + const r = Math.random() * 0.8 + 0.3; + const o = Math.random() * 0.6 + 0.2; + s += `<circle cx="${x.toFixed(1)}" cy="${y.toFixed(1)}" r="${r.toFixed(2)}" fill="#cbd5e1" opacity="${o.toFixed(2)}"/>`; + } + starsG.innerHTML = s; + })(); + + // Edges + const nodeMap = Object.fromEntries(nodes.map(n => [n.id, n])); + let edgeHTML = ''; + edges.forEach(([a, b]) => { + const na = nodeMap[a], nb = nodeMap[b]; + if (!na || !nb) return; + const la = layers[na.layer], lb = layers[nb.layer]; + const c = la.color; + const opacity = (la === lb) ? 0.45 : 0.3; + edgeHTML += `<line x1="${na.x}" y1="${la.y}" x2="${nb.x}" y2="${lb.y}" stroke="${c}" stroke-width="1.2" opacity="${opacity}"/>`; + }); + edgesG.innerHTML = edgeHTML; + + // Nodes + let nodeHTML = ''; + let labelHTML = ''; + let showLabels = true; + let showFlows = true; + nodes.forEach(n => { + const L = layers[n.layer]; + nodeHTML += ` + <g class="node-hit" data-id="${n.id}"> + <circle class="node-circle" cx="${n.x}" cy="${L.y}" r="${n.r}" fill="${L.color}" fill-opacity="0.18" stroke="${L.color}" stroke-width="2" filter="url(#glow)"/> + </g>`; + labelHTML += `<text class="label" x="${n.x}" y="${L.y + n.r + 14}">${n.label}</text>`; + }); + nodesG.innerHTML = nodeHTML; + labelsG.innerHTML = labelHTML; + + // ---------- INTERACTION ---------- + let pinned = null; + let camYaw = 0; // -1..1 mapped to dx + let dragging = false; + let dragStart = null; + let lastTap = null; + + function setStatus(t) { statusText.textContent = t; } + + function showCard(id) { + const n = nodeMap[id]; + if (!n) return; + const L = layers[n.layer]; + cardName.textContent = n.label; + cardDesc.textContent = descs[id] || ''; + cardLayer.textContent = L.name; + cardLayer.style.background = L.color; + cardLayer.style.color = '#0a0e1a'; + card.classList.add('visible'); + setStatus('viewing ' + n.label); + + // Highlight node + document.querySelectorAll('.node-circle').forEach(c => c.classList.remove('pinned')); + document.querySelectorAll('.node-hit').forEach(g => g.classList.remove('pinned')); + const hit = document.querySelector(`.node-hit[data-id="${id}"]`); + if (hit) { + hit.classList.add('pinned'); + hit.querySelector('.node-circle').classList.add('pinned'); + } + pinned = id; + } + + function hideCard() { + card.classList.remove('visible'); + document.querySelectorAll('.node-circle').forEach(c => c.classList.remove('pinned')); + document.querySelectorAll('.node-hit').forEach(g => g.classList.remove('pinned')); + pinned = null; + setStatus('idle'); + } + + cardClose.addEventListener('click', (e) => { + e.stopPropagation(); + hideCard(); + }); + + // Find node by touch/click coordinates + function hitTest(clientX, clientY) { + const rect = svg.getBoundingClientRect(); + // Map client coords into viewBox 400x700 + const x = (clientX - rect.left) * (400 / rect.width); + const y = (clientY - rect.top) * (700 / rect.height); + let best = null, bestD = Infinity; + for (const n of nodes) { + const ny = layers[n.layer].y; + const dx = x - n.x, dy = y - ny; + const d = Math.sqrt(dx*dx + dy*dy); + // Big hit radius on mobile (24-32) + const hr = Math.max(n.r + 14, 24); + if (d < hr && d < bestD) { bestD = d; best = n; } + } + return best; + } + + // Camera orbit (horizontal drag only — most natural on phone) + function applyCamera() { + const maxDx = 25; + const dx = camYaw * maxDx; + edgesG.setAttribute('transform', `translate(${dx} 0)`); + nodesG.setAttribute('transform', `translate(${dx} 0)`); + labelsG.setAttribute('transform', `translate(${dx} 0)`); + } + + function onPointerDown(e) { + dragging = true; + svg.classList.add('dragging'); + const t = (e.touches ? e.touches[0] : e); + dragStart = { x: t.clientX, y: t.clientY, t: Date.now(), dx: 0, dy: 0 }; + setStatus('dragging'); + } + + function onPointerMove(e) { + if (!dragging) return; + e.preventDefault(); + const t = (e.touches ? e.touches[0] : e); + dragStart.dx = t.clientX - dragStart.x; + dragStart.dy = t.clientY - dragStart.y; + // Map horizontal drag to yaw (-1..1) + camYaw = Math.max(-1, Math.min(1, dragStart.dx / 120)); + applyCamera(); + } + + function onPointerUp(e) { + if (!dragging) return; + dragging = false; + svg.classList.remove('dragging'); + const moved = Math.abs(dragStart.dx) + Math.abs(dragStart.dy); + const dt = Date.now() - dragStart.t; + // Tap = small movement, short time + if (moved < 8 && dt < 400) { + const t = (e.changedTouches ? e.changedTouches[0] : e); + const hit = hitTest(t.clientX, t.clientY); + if (hit) { + if (pinned === hit.id) hideCard(); + else showCard(hit.id); + } else { + hideCard(); + } + } else { + setStatus('idle'); + } + } + + // Touch + svg.addEventListener('touchstart', (e) => { onPointerDown(e); }, { passive: false }); + svg.addEventListener('touchmove', (e) => { onPointerMove(e); }, { passive: false }); + svg.addEventListener('touchend', (e) => { onPointerUp(e); }, { passive: false }); + svg.addEventListener('touchcancel',(e) => { dragging = false; svg.classList.remove('dragging'); setStatus('idle'); }); + + // Mouse (desktop fallback) + svg.addEventListener('mousedown', onPointerDown); + window.addEventListener('mousemove', onPointerMove); + window.addEventListener('mouseup', onPointerUp); + + // Pinch zoom (simple) + let pinchStart = 0; + svg.addEventListener('gesturestart', (e) => { pinchStart = e.scale; }); + svg.addEventListener('gesturechange', (e) => { + const s = e.scale / pinchStart; + svg.style.transform = `scale(${Math.max(0.6, Math.min(2, s))})`; + svg.style.transformOrigin = 'center center'; + }); + + // ---------- CONTROLS ---------- + document.getElementById('btnReset').addEventListener('click', () => { + camYaw = 0; applyCamera(); + svg.style.transform = ''; + hideCard(); + }); + + document.getElementById('btnPulse').addEventListener('click', (e) => { + const r = e.currentTarget.getBoundingClientRect(); + const ring = document.createElement('div'); + ring.className = 'pulse-ring'; + ring.style.left = (r.left + r.width/2 - 40) + 'px'; + ring.style.top = (r.top + r.height/2 - 40) + 'px'; + document.body.appendChild(ring); + setTimeout(() => ring.remove(), 1300); + setStatus('pulse'); + setTimeout(() => { if (!pinned) setStatus('idle'); }, 1200); + }); + + document.getElementById('btnLabels').addEventListener('click', (e) => { + showLabels = !showLabels; + labelsG.style.display = showLabels ? '' : 'none'; + e.currentTarget.classList.toggle('active', showLabels); + }); + document.getElementById('btnLabels').classList.add('active'); + + document.getElementById('btnFlows').addEventListener('click', (e) => { + showFlows = !showFlows; + edgesG.style.display = showFlows ? '' : 'none'; + e.currentTarget.classList.toggle('active', showFlows); + }); + document.getElementById('btnFlows').classList.add('active'); + + document.getElementById('btnHelp').addEventListener('click', () => { + showCard('kernel'); + }); + + // Initial status + setStatus('idle'); +})(); +</script> + +</body> +</html> diff --git a/downloads/memory/release-arc-3d.html b/downloads/memory/release-arc-3d.html new file mode 100644 index 0000000..2aa359d --- /dev/null +++ b/downloads/memory/release-arc-3d.html @@ -0,0 +1,384 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="UTF-8"> +<title>newOS4 Memory Constellation — v4.5.86 → v4.5.90b</title> +<style> + html,body { margin:0; padding:0; background:#02030a; color:#cfe; font-family:ui-monospace,Menlo,monospace; overflow:hidden; } + #app { position:fixed; inset:0; } + #hud { position:fixed; top:12px; left:12px; padding:10px 14px; background:rgba(0,0,0,.55); border:1px solid #234; border-radius:6px; max-width:320px; font-size:12px; line-height:1.5; backdrop-filter:blur(6px); } + #hud h1 { margin:0 0 6px; font-size:14px; color:#9ef; letter-spacing:.5px; } + #hud .row { display:flex; justify-content:space-between; gap:12px; } + #hud .k { color:#678; } #hud .v { color:#bdf; } + #info { position:fixed; bottom:12px; left:12px; padding:10px 14px; background:rgba(0,0,0,.55); border:1px solid #234; border-radius:6px; max-width:420px; font-size:12px; line-height:1.55; backdrop-filter:blur(6px); display:none; } + #info .ver { color:#fff; font-weight:700; } + #info .phase { color:#9ef; font-size:10px; text-transform:uppercase; letter-spacing:1px; } + #info ul { margin:6px 0 0; padding-left:16px; color:#9ab; } + #controls { position:fixed; top:12px; right:12px; display:flex; flex-direction:column; gap:6px; } + #controls button { background:rgba(0,0,0,.6); color:#9ef; border:1px solid #234; padding:6px 10px; font-family:inherit; font-size:11px; border-radius:4px; cursor:pointer; } + #controls button:hover { background:rgba(40,80,120,.5); } + #legend { position:fixed; bottom:12px; right:12px; padding:8px 12px; background:rgba(0,0,0,.55); border:1px solid #234; border-radius:6px; font-size:11px; } + #legend .item { display:flex; align-items:center; gap:6px; margin:2px 0; color:#9ab; } + #legend .dot { width:8px; height:8px; border-radius:50%; } + #tip { position:fixed; bottom:6px; left:50%; transform:translateX(-50%); color:#456; font-size:10px; letter-spacing:1px; } +</style> +</head> +<body> +<div id="app"></div> +<div id="hud"> + <h1>◉ newOS4 MEMORY CONSTELLATION</h1> + <div class="row"><span class="k">range</span><span class="v">v4.5.86 → v4.5.90b</span></div> + <div class="row"><span class="k">releases</span><span class="v">7</span></div> + <div class="row"><span class="k">modules</span><span class="v">43</span></div> + <div class="row"><span class="k">skills</span><span class="v">24</span></div> + <div class="row"><span class="k">review findings</span><span class="v">12 closed</span></div> + <div class="row"><span class="k">status</span><span class="v">✅ shipped clean</span></div> +</div> +<div id="info"></div> +<div id="controls"> + <button id="b-rot">⏸ auto-rotate</button> + <button id="b-pulse">◌ trigger pulse</button> + <button id="b-reset">⌖ reset view</button> +</div> +<div id="legend"> + <div class="item"><span class="dot" style="background:#4488ff"></span>v4.5.86 cold-start</div> + <div class="item"><span class="dot" style="background:#44ddff"></span>v4.5.87 purge</div> + <div class="item"><span class="dot" style="background:#44ffaa"></span>v4.5.88 schema</div> + <div class="item"><span class="dot" style="background:#88ff44"></span>v4.5.89 connectors</div> + <div class="item"><span class="dot" style="background:#ffee44"></span>v4.5.89b review</div> + <div class="item"><span class="dot" style="background:#ff9944"></span>v4.5.90 skills</div> + <div class="item"><span class="dot" style="background:#ff4488"></span>v4.5.90b skill-review</div> +</div> +<div id="tip">drag to rotate · scroll to zoom · click a node</div> + +<script type="importmap"> +{ + "imports": { + "three": "https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js", + "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/" + } +} +</script> + +<script type="module"> +import * as THREE from 'three'; +import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + +// ─── SCENE SETUP ───────────────────────────────────────────────────────── +const app = document.getElementById('app'); +const scene = new THREE.Scene(); +scene.fog = new THREE.FogExp2(0x02030a, 0.012); + +const camera = new THREE.PerspectiveCamera(55, innerWidth/innerHeight, 0.1, 200); +camera.position.set(12, 8, 16); + +const renderer = new THREE.WebGLRenderer({ antialias:true, alpha:false }); +renderer.setPixelRatio(Math.min(devicePixelRatio, 2)); +renderer.setSize(innerWidth, innerHeight); +renderer.setClearColor(0x02030a); +app.appendChild(renderer.domElement); + +const controls = new OrbitControls(camera, renderer.domElement); +controls.enableDamping = true; +controls.dampingFactor = 0.06; +controls.minDistance = 6; +controls.maxDistance = 40; +const initialCam = camera.position.clone(); + +// ─── LIGHTING ──────────────────────────────────────────────────────────── +scene.add(new THREE.HemisphereLight(0x6688aa, 0x110022, 0.55)); +const key = new THREE.DirectionalLight(0xffeebb, 1.1); key.position.set(8, 12, 6); scene.add(key); +const fill = new THREE.PointLight(0x4488ff, 1.4, 30); fill.position.set(-8, 4, -6); scene.add(fill); +const rim = new THREE.PointLight(0xff4488, 0.9, 24); rim.position.set(6, 8, -10); scene.add(rim); + +// ─── RELEASE DATA (hand-calculated helix positions) ───────────────────── +// Helix: 7 points, R=4.2, y-step=1.4, angle = i * 2π/6 +// x = R*cos(θ), z = R*sin(θ), y = i*1.4 - 4.2 (centered vertically) +const R = 4.2, STEP = 1.4, OFFSET_Y = -4.2; +const cos = (a)=>Math.cos(a), sin=(a)=>Math.sin(a); +const angle = (i)=>i * (Math.PI*2/6); +const yOf = (i)=>i * STEP + OFFSET_Y; + +const releases = [ + { v:'v4.5.86', phase:'Cold-Start', color:0x4488ff, size:0.55, info:[ + 'Activated 3 dormant modules', + 'Predictor, MemoryGraph, WorldModel', + 'First runnable cognitive stack']}, + { v:'v4.5.87', phase:'Purge + Slim', color:0x44ddff, size:0.50, info:[ + '-42% system prompt', + 'Removed dead code', + 'Smaller, faster, focused']}, + { v:'v4.5.88', phase:'Schema 2.0', color:0x44ffaa, size:0.55, info:[ + 'Namespace: global vs agent', + 'source_session field', + 'Dual-lookup (by id + by query)']}, + { v:'v4.5.89', phase:'Connectors', color:0x88ff44, size:0.62, info:[ + 'memgraph ↔ NVFS bridge', + 'World-model TTL + refresh', + 'Lazy decay, semantic sync']}, + { v:'v4.5.89b', phase:'Review Harden', color:0xffee44, size:0.58, info:[ + '6 review findings fixed', + 'Config persistence', + 'Clean before R3']}, + { v:'v4.5.90', phase:'Agent Skills', color:0xff9944, size:0.78, info:[ + '4 commands: learn, validate, audit, restore', + '8 methods exposed', + 'Skills self-improve']}, + { v:'v4.5.90b', phase:'Skill Review', color:0xff4488, size:0.85, info:[ + '6 more findings closed', + 'Bayesian confidence (uses/(uses+5))', + '0 P0/P1 outstanding']}, +]; + +// ─── GLOW TEXTURE (canvas-based radial gradient) ──────────────────────── +function glowTexture(inner, outer){ + const c = document.createElement('canvas'); c.width = c.height = 128; + const ctx = c.getContext('2d'); + const g = ctx.createRadialGradient(64,64,0, 64,64,64); + g.addColorStop(0, inner); g.addColorStop(0.4, outer); g.addColorStop(1, 'rgba(0,0,0,0)'); + ctx.fillStyle = g; ctx.fillRect(0,0,128,128); + return new THREE.CanvasTexture(c); +} + +// ─── CENTRAL CORE ──────────────────────────────────────────────────────── +const coreGeo = new THREE.IcosahedronGeometry(1.1, 1); +const coreMat = new THREE.MeshPhongMaterial({ color:0xffffff, emissive:0x4488ff, emissiveIntensity:0.6, shininess:80, flatShading:true }); +const core = new THREE.Mesh(coreGeo, coreMat); +scene.add(core); + +// core glow halo +const coreGlow = new THREE.Sprite(new THREE.SpriteMaterial({ map: glowTexture('rgba(120,180,255,0.9)','rgba(40,80,180,0.4)'), blending:THREE.AdditiveBlending, depthWrite:false })); +coreGlow.scale.set(5,5,5); +scene.add(coreGlow); + +// ─── RELEASE NODES ─────────────────────────────────────────────────────── +const releaseGroup = new THREE.Group(); +scene.add(releaseGroup); + +const releaseMeshes = []; +releases.forEach((r, i) => { + const a = angle(i); + const pos = new THREE.Vector3(R*cos(a), yOf(i), R*sin(a)); + + // sphere + const geo = new THREE.SphereGeometry(r.size, 32, 32); + const mat = new THREE.MeshPhongMaterial({ color: r.color, emissive: r.color, emissiveIntensity: 0.35, shininess:60 }); + const mesh = new THREE.Mesh(geo, mat); + mesh.position.copy(pos); + mesh.userData = r; + releaseGroup.add(mesh); + releaseMeshes.push(mesh); + + // glow sprite + const glow = new THREE.Sprite(new THREE.SpriteMaterial({ map: glowTexture('rgba(255,255,255,0.5)','rgba(0,0,0,0)'), color: r.color, blending:THREE.AdditiveBlending, depthWrite:false, transparent:true, opacity:0.7 })); + glow.scale.set(r.size*3.5, r.size*3.5, 1); + glow.position.copy(pos); + releaseGroup.add(glow); + + // label sprite (canvas-baked text) + const lc = document.createElement('canvas'); lc.width=256; lc.height=64; + const lctx = lc.getContext('2d'); + lctx.font='bold 28px ui-monospace,monospace'; + lctx.textAlign='center'; lctx.textBaseline='middle'; + lctx.fillStyle = '#' + r.color.toString(16).padStart(6,'0'); + lctx.shadowColor='#000'; lctx.shadowBlur=6; + lctx.fillText(r.v, 128, 32); + const labelTex = new THREE.CanvasTexture(lc); + const label = new THREE.Sprite(new THREE.SpriteMaterial({ map: labelTex, depthWrite:false, transparent:true })); + label.scale.set(2.0, 0.5, 1); + label.position.set(pos.x, pos.y + r.size + 0.35, pos.z); + releaseGroup.add(label); +}); + +// ─── EDGES (curves between consecutive releases + radial to core) ──────── +const edgeMat = new THREE.LineBasicMaterial({ color: 0x446688, transparent:true, opacity:0.55 }); +for (let i=0; i<releaseMeshes.length-1; i++){ + const a = releaseMeshes[i].position, b = releaseMeshes[i+1].position; + // quadratic curve via midpoint + slight outward bulge + const mid = a.clone().add(b).multiplyScalar(0.5); + mid.add(new THREE.Vector3(0, 0.6, 0)); + const curve = new THREE.QuadraticBezierCurve3(a, mid, b); + const pts = curve.getPoints(40).map(p => new THREE.Vector3(p.x, p.y, p.z)); + const geo = new THREE.BufferGeometry().setFromPoints(pts); + releaseGroup.add(new THREE.Line(geo, edgeMat)); +} +// radial spokes from each release to core +for (const m of releaseMeshes){ + const geo = new THREE.BufferGeometry().setFromPoints([m.position, new THREE.Vector3(0,0,0)]); + const line = new THREE.Line(geo, new THREE.LineDashedMaterial({ color:0x224466, dashSize:0.15, gapSize:0.1, transparent:true, opacity:0.4 })); + line.computeLineDistances(); + releaseGroup.add(line); +} + +// ─── SKILL ORBIT NODES (4 commands from v4.5.90) ──────────────────────── +const skills = [ + { name:'skill-learn', color:0xffddaa }, + { name:'skill-validate', color:0xaaffdd }, + { name:'skill-audit', color:0xddaaff }, + { name:'skill-restore', color:0xaadfff }, +]; +const skillOrbit = new THREE.Group(); +scene.add(skillOrbit); +const skillMeshes = []; +skills.forEach((s, i) => { + const a = i * (Math.PI*2/skills.length) + Math.PI/4; + const radius = 7.2; + const pos = new THREE.Vector3(radius*cos(a), yOf(5) + Math.sin(a)*1.5, radius*sin(a)); + const geo = new THREE.OctahedronGeometry(0.35, 0); + const mat = new THREE.MeshPhongMaterial({ color: s.color, emissive:s.color, emissiveIntensity:0.4, flatShading:true }); + const mesh = new THREE.Mesh(geo, mat); + mesh.position.copy(pos); + mesh.userData = { v:s.name, phase:'v4.5.90 command', color:s.color, + info:['Command shipped in v4.5.90','Part of Agent Skills bundle']}; + skillOrbit.add(mesh); + skillMeshes.push(mesh); + + const lc=document.createElement('canvas');lc.width=256;lc.height=48; + const lctx=lc.getContext('2d'); + lctx.font='20px ui-monospace,monospace'; lctx.textAlign='center'; lctx.textBaseline='middle'; + lctx.fillStyle='#cde'; lctx.shadowColor='#000'; lctx.shadowBlur=4; + lctx.fillText(s.name, 128, 24); + const label = new THREE.Sprite(new THREE.SpriteMaterial({ map: new THREE.CanvasTexture(lc), depthWrite:false, transparent:true })); + label.scale.set(1.6, 0.3, 1); + label.position.set(pos.x, pos.y+0.6, pos.z); + skillOrbit.add(label); +}); + +// ─── MEMORY PARTICLES (instanced points) ──────────────────────────────── +const N = 400; +const partGeo = new THREE.BufferGeometry(); +const positions = new Float32Array(N*3); +const phases = new Float32Array(N); +for (let i=0; i<N; i++){ + // random points in a torus shell + const theta = Math.random()*Math.PI*2; + const r = 9 + Math.random()*4; + const y = (Math.random()-0.5) * 14; + positions[i*3] = r*cos(theta); + positions[i*3+1] = y; + positions[i*3+2] = r*sin(theta); + phases[i] = Math.random()*Math.PI*2; +} +partGeo.setAttribute('position', new THREE.BufferAttribute(positions, 3)); +partGeo.setAttribute('phase', new THREE.BufferAttribute(phases, 1)); +const partMat = new THREE.PointsMaterial({ color:0x88aaff, size:0.05, transparent:true, opacity:0.6, sizeAttenuation:true, depthWrite:false }); +const particles = new THREE.Points(partGeo, partMat); +scene.add(particles); + +// ─── PULSE RING (decay visualization) ──────────────────────────────────── +const pulseGeo = new THREE.RingGeometry(0.5, 0.55, 64); +const pulseMat = new THREE.MeshBasicMaterial({ color:0x88ddff, side:THREE.DoubleSide, transparent:true, opacity:0.7, depthWrite:false, blending:THREE.AdditiveBlending }); +const pulse = new THREE.Mesh(pulseGeo, pulseMat); +pulse.rotation.x = -Math.PI/2; +pulse.visible = false; +scene.add(pulse); +let pulseT = 0, pulsing = false; + +// ─── STARFIELD ─────────────────────────────────────────────────────────── +const starGeo = new THREE.BufferGeometry(); +const starPos = new Float32Array(1500*3); +for (let i=0; i<1500; i++){ + // sphere shell far out + const t = Math.random()*Math.PI*2; + const p = Math.acos(2*Math.random()-1); + const r = 60 + Math.random()*40; + starPos[i*3] = r*Math.sin(p)*cos(t); + starPos[i*3+1] = r*Math.cos(p); + starPos[i*3+2] = r*Math.sin(p)*sin(t); +} +starGeo.setAttribute('position', new THREE.BufferAttribute(starPos, 3)); +scene.add(new THREE.Points(starGeo, new THREE.PointsMaterial({ color:0xffffff, size:0.15, sizeAttenuation:true, transparent:true, opacity:0.7 }))); + +// ─── RAYCASTER (click) ────────────────────────────────────────────────── +const raycaster = new THREE.Raycaster(); +const mouse = new THREE.Vector2(); +const pickables = [...releaseMeshes, ...skillMeshes, core]; +const infoEl = document.getElementById('info'); + +function showInfo(d){ + if (!d){ infoEl.style.display='none'; return; } + const c = '#' + (d.color||0x88aaff).toString(16).padStart(6,'0'); + infoEl.style.borderColor = c + '66'; + infoEl.innerHTML = `<div class="phase">${d.phase||''}</div> + <div class="ver" style="color:${c}">${d.v}</div> + <ul>${(d.info||[]).map(x=>`<li>${x}</li>`).join('')}</ul>`; + infoEl.style.display = 'block'; +} +window.addEventListener('click', (e) => { + mouse.x = (e.clientX/innerWidth)*2 - 1; + mouse.y = -(e.clientY/innerHeight)*2 + 1; + raycaster.setFromCamera(mouse, camera); + const hits = raycaster.intersectObjects(pickables, false); + if (hits.length){ showInfo(hits[0].object.userData); } + else { showInfo(null); } +}); + +// ─── HOVER CURSOR ─────────────────────────────────────────────────────── +window.addEventListener('mousemove', (e)=>{ + mouse.x = (e.clientX/innerWidth)*2 - 1; + mouse.y = -(e.clientY/innerHeight)*2 + 1; + raycaster.setFromCamera(mouse, camera); + const hits = raycaster.intersectObjects(pickables, false); + renderer.domElement.style.cursor = hits.length ? 'pointer' : 'grab'; +}); + +// ─── UI BUTTONS ────────────────────────────────────────────────────────── +let autoRotate = true; +document.getElementById('b-rot').onclick = () => { + autoRotate = !autoRotate; + document.getElementById('b-rot').textContent = autoRotate ? '⏸ auto-rotate' : '▶ auto-rotate'; +}; +document.getElementById('b-pulse').onclick = () => { pulsing = true; pulseT = 0; pulse.visible = true; }; +document.getElementById('b-reset').onclick = () => { + camera.position.copy(initialCam); + controls.target.set(0,0,0); + controls.update(); +}; + +// ─── RESIZE ────────────────────────────────────────────────────────────── +window.addEventListener('resize', () => { + camera.aspect = innerWidth/innerHeight; + camera.updateProjectionMatrix(); + renderer.setSize(innerWidth, innerHeight); +}); + +// ─── ANIMATION LOOP ────────────────────────────────────────────────────── +const clock = new THREE.Clock(); +function tick(){ + const dt = clock.getDelta(); + const t = clock.elapsedTime; + + if (autoRotate){ + releaseGroup.rotation.y += dt * 0.08; + skillOrbit.rotation.y -= dt * 0.15; + } + core.rotation.y += dt * 0.4; + core.rotation.x += dt * 0.2; + coreGlow.material.opacity = 0.7 + 0.3*Math.sin(t*2); + + // particle drift + const ppos = particles.geometry.attributes.position; + const ppha = particles.geometry.attributes.phase; + for (let i=0; i<N; i++){ + const ph = ppha.array[i]; + ppos.array[i*3+1] += Math.sin(t + ph) * 0.003; + } + ppos.needsUpdate = true; + + // pulse animation + if (pulsing){ + pulseT += dt; + const s = 0.5 + pulseT * 12; + pulse.scale.set(s, s, s); + pulseMat.opacity = Math.max(0, 0.8 - pulseT*0.6); + if (pulseT > 1.5){ pulsing = false; pulse.visible = false; } + } + + controls.update(); + renderer.render(scene, camera); + requestAnimationFrame(tick); +} +tick(); +</script> +</body> +</html> |