Lumiverse

Lumiverse 0.8.0 on Staging — The One That Did a Lot

March 29, 2026
lumiversechat applumiverse updates

This is the one where we add theming. And make Memory Cortex even smarter. And a lot of other little things you might appreciate.


Custom CSS & Component Overrides

You can now write CSS and replace entire React components without touching source. Open the editor from Theme > Advanced > Custom CSS Editor.

  • Custom CSS: Injected at the lumiverse-user layer, so it always wins over base styles. CodeMirror editor with syntax highlighting and validation.
  • Component overrides: Write TSX that replaces built-in components (BubbleMessage, ChatView, etc.). Runtime-transpiled via Sucrase. Each override can carry its own scoped CSS.
  • Theme packs: Bundle global CSS + component overrides into a single portable config. applyThemePack() wires everything at once.
  • Data attributes for targeting: Every chat component now carries data-component="ComponentName" so your CSS can select precisely. No more guessing class names.

BubbleMessage was refactored to support this. The original rendering logic is now BubbleMessageDefault.tsx, loaded through the override system. If you've written extensions that patch BubbleMessage internally, check the new shape.


Drawer Tab Registry

Hardcoded tab definitions are gone from ViewportDrawer and commands.ts. Both now read from a central registry (drawer-tab-registry.tsx). Extensions can register tabs dynamically and they'll show up in the command palette automatically. We've updated the developer documentation to show you how.

ViewportDrawer lost ~160 lines of imports and switch-case spaghetti. commands.ts lost ~200 lines of duplicate panel definitions. Both are better for it.

New option in settings: Show tab labels renders short text labels below drawer icons.


Memory Cortex: Heuristics Engine

The entity/relationship tracking system got a ground-up overhaul of its scoring, resolution, and data integrity layers. Four bugs fixed, five improvements landed.

Bug fixes:

  • Alias enforcement at edge write time. Previously, characters mentioned by first and first/last name created separate nodes, fracturing relationship graphs across two identities. Every edge write now resolves both endpoints through a canonical resolver (direct ID match > alias lookup > normalized fuzzy match with title stripping). Existing edges are rekeyed on migration.
  • Edge strength no longer starts at 50%. A single-chunk detection carried the same confidence as a well-established relationship. New formula: 1 - exp(-0.15 * evidence_count). One chunk = 14%. Five chunks = 53%. Twelve chunks = 84%. Feels right.
  • Contradicting edges are flagged, not silently stored. Someone being both a lover and an enemy of the same character now gets classified: temporal (newer arc supersedes older), complex (both well-evidenced, genuinely ambivalent), or suspect (one-off detection against established edge, held for corroboration). Standard retrieval excludes suspect and superseded edges.
  • Ghost entities get retried. Entities with high salience but zero facts now carry a factExtractionStatus field. The system will attempt extraction on the next available cycle instead of quietly ignoring them forever.

Improvements:

  • Independent edge decay. Relationship salience now decays independently of endpoint entity salience. High-strength edges in narratively heavy arcs decay slower. Retrieval becomes "what relationships are currently active and confident" rather than "everything that ever existed."
  • Salience breakdown. Entity salience decomposes into three visible components: mention frequency, arc weight, and graph centrality. The frontend shows this as a three-segment bar to reflect them.
  • Graph centrality. Single-hop weighted centrality (not PageRank, that's overkill at this graph size). Dense relationship hubs score higher regardless of mention recency. Weighted conservatively at 0.1-0.2x.
  • NP chunker for Phase 1. Server-side noun phrase extraction runs during sidecar-enabled chunk processing. Finds entity candidates the regex misses. Creates provisional entities that promote after appearing in two or more chunks, or decay out if never corroborated. Does not run on Phase 2 (live message path).
  • Edge type consolidation. Parallel edges of semantically overlapping types between the same entity pair now merge. lover subsumes ally. ally and custom merge when sentiment is within 0.3. Spatial (located_in) and hostile (enemy) edges are always independent.

Schema: Two new migrations (046, 047) add 13 columns to memory_relations and 6 to memory_entities. Backfill runs automatically. For existing chats, hit the new Migrate Heuristics endpoint or trigger a rebuild.

Frontend: Entity cards now show provisional badges, fact extraction status, salience breakdown bars, and relative last-seen times. The relations drill-down shows edge salience, contradiction flags, sentiment ranges, and label aliases.


Connection Manager UI

Action buttons (test, duplicate, delete) on connection items collapsed into a context menu. Same change on image generation connections. Less clutter in the list view.


Google Vertex AI

Fixed a URL construction bug where the provider sometimes generated malformed endpoint URLs with leftover path fragments. Regional endpoints now always use https://{location}-aiplatform.googleapis.com. The "global" region (which Vertex doesn't actually support for generation APIs) falls back to us-central1.


Extension Commands

Extensions can now register custom commands in the command palette (Cmd/Ctrl+K). Free tier, no permission needed.

spindle.commands.register() takes a list of command definitions with label, description, keywords, and scope. When a user picks one, the extension gets the commandId plus a context snapshot (active chat, character, route, group status) via spindle.commands.onInvoked(). Commands are contextual: call register() again with a different set whenever the available actions should change. Each call replaces the previous set.

Max 20 commands per extension. Cleanup is automatic on unload. See developer-docs/docs/backend-api/commands.md.


Operator Panel: Maintenance Tools

Three new actions in the Operator panel, grouped under a Maintenance section.

  • Clear Package Cache: Runs bun pm cache rm. No restart.
  • Ensure Dependencies: Runs bun install at project root and in frontend/. No restart.
  • Rebuild Frontend: Deletes frontend/dist, rebuilds from source, restarts the server. Mutex-protected like updates and branch switches.

All three require runner IPC.


Smaller changes

  • Streaming indicator animation moved from global CSS to a scoped CSS module. No more naming collisions with custom CSS.
  • CSS layer ordering added (lumiverse-base, lumiverse-theme, lumiverse-user) so the cascade is predictable.
  • Service worker cache limit bumped to 4MB. We're getting a little chonky.
  • model_labels field added to connection models API response for human-readable model names.