feat: live memory materialization — nodes spawn in 3D graph in real-time

When memories are created, promoted, deleted, or dreamed via MCP tools,
the 3D graph now shows spectacular live animations:

- Rainbow particle burst + elastic scale-up on MemoryCreated
- Ripple wave cascading to nearby nodes
- Green pulse + node growth on MemoryPromoted
- Implosion + dissolution on MemoryDeleted
- Edge growth animation on ConnectionDiscovered
- Purple cascade on DreamStarted/DreamProgress/DreamCompleted
- FIFO eviction at 50 live nodes to guard performance

Also: graph center defaults to most-connected node, legacy HTML
redirects to SvelteKit dashboard, CSS height chain fix in layout.

Testing: 150 unit tests (vitest), 11 e2e tests (Playwright with
MCP Streamable HTTP client), 22 proof screenshots.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Sam Valladares 2026-03-03 14:04:31 -06:00
parent 816b577f69
commit 9bdcc69ce3
76 changed files with 5915 additions and 332 deletions

View file

@ -1,6 +1,6 @@
[package]
name = "vestige-core"
version = "2.0.2"
version = "2.0.3"
edition = "2024"
rust-version = "1.91"
authors = ["Vestige Team"]

View file

@ -3532,6 +3532,21 @@ impl Storage {
Ok(result)
}
/// Get the memory with the most connections (best center node for graph visualization)
pub fn get_most_connected_memory(&self) -> Result<Option<String>> {
let reader = self.reader.lock()
.map_err(|_| StorageError::Init("Reader lock poisoned".into()))?;
let mut stmt = reader.prepare(
"SELECT id, COUNT(*) as cnt FROM (
SELECT source_id as id FROM memory_connections
UNION ALL
SELECT target_id as id FROM memory_connections
) GROUP BY id ORDER BY cnt DESC LIMIT 1"
)?;
let result = stmt.query_row([], |row| row.get::<_, String>(0)).optional()?;
Ok(result)
}
/// Get memories with their connection data for graph visualization
pub fn get_memory_subgraph(&self, center_id: &str, depth: u32, max_nodes: usize) -> Result<(Vec<KnowledgeNode>, Vec<ConnectionRecord>)> {
let mut visited_ids: std::collections::HashSet<String> = std::collections::HashSet::new();