Changelog

Product evolution timeline

### Added **Frontend: Anima Page Nebula Cloud Animation + Edit Modal** (~2 hours) Dynamic particle-based nebula cloud visualization replacing static gradient sphere. **AnimaNebulaCore Component**: - Canvas-based 1000-particle nebula with pixelated aesthetic (`imageRendering: pixelated`) - 4 cycling color palettes (10s intervals): Default (warm grey/amber) → Cool (blue/cyan) → Warm (amber/orange) → Emerald (green) - Smooth RGB interpolation (~2s transitions) via `lerpColor()` helper - Warm palette: 70% grey tones, 30% amber/cyan/emerald lightning traces - Subtle glow effects (shadowBlur: 4, opacity: 0.6) - Breathing animation via sinusoidal life cycles + gravitational drift - Increased size to 420px for better presence **Anima Page Layout Updates**: - Removed rigid box container (borderless floating cloud) - Repositioned cloud ~20% down page (`pt-16 lg:pt-24`) - Anima name moved below cloud as character title - Hover-to-edit: "EDIT" button appears on name hover - Responsive bottom alignment for Memories/Events sections **EditAnimaModal Component**: - New modal for editing anima name/description - Terminal aesthetic matching CreateAnimaModal - Calls `AnimasAPI.updateById()` with auto-refetch **Files Created**: - `frontend/src/components/anima/AnimaNebulaCore.tsx` - `frontend/src/components/anima/index.ts` - `frontend/src/components/modals/EditAnimaModal.tsx` **Files Modified**: - `frontend/src/components/modals/index.ts` - `frontend/src/app/(authenticated)/anima/page.tsx` --- **Frontend: Sandbox Flowchart Visualization with Animated Event Flow** (~1.5 hours) Real-time data flow visualization showing message-to-event transformation with 90-degree particle animations. **FlowchartBox Component** (new): - Minimalist "Data Flow" panel replacing empty middle box - Events container with live event count - Session-scoped chronological event list (oldest → newest) - Smooth stagger animations (30ms delay per event) - New event highlights: cyan/green border glow (1s fade) **AnimatedEventFlow Refactor**: - **90-degree curved path**: Horizontal → vertical curve (Supabase FK-style) - SVG path: `M start L control-horizontal Q end-x control-y, end-x end-y` - Target changed from inspector panel to flowchart Events container - Dynamic end position via `document.getElementById('flowchart-events-container')` - **Particle redesign**: Large bubble → small glowing orb (12px core) - Glowing particle trail with `pathLength` animation - Speed increased: 1500ms → 800ms for snappier feel - Color-coded: Green (#22c55e) for user, Cyan (#06b6d4) for AI **Sandbox Page Integration**: - Session filtering: `events.filter(e => e.session_id === sessionId)` - Chronological sorting for flowchart display - Both MESSAGE_IN and MESSAGE_OUT events animate through **Animation Flow**: 1. User sends message → input highlights 2. Particle spawns from message bubble 3. Travels horizontally right → curves 90° down 4. Event materializes in flowchart with glow 5. Persists in chronological list for session **Files Created**: - `frontend/src/components/sandbox/FlowchartBox.tsx` **Files Modified**: - `frontend/src/components/sandbox/AnimatedEventFlow.tsx` - `frontend/src/app/(authenticated)/sandbox/page.tsx` ### Build Verification - ✅ Build successful (2.5s compile, 240 kB sandbox route) - ✅ No TypeScript errors - ✅ Linter passed (0 errors, 1 pre-existing warning) ### Related Documentation - `docs/completions/cosmetic-refinements-1Nov25.md` - Full implementation details ---
### Changed **Frontend: Sandbox UX Refinements** (~3 hours across 5 incremental improvements) Comprehensive UX enhancement pass on Sandbox page focusing on navigation, event management, and dual-chatbox layout. Five refinements shipped incrementally over 2 days. #### 1. Elephantasm Inspector Panel - Tab Navigation **Added tabbed navigation** to Elephantasm inspector panel for organized content views: - **"All" tab**: Original layout (Status, Events preview, Memories) - **"Events" tab**: Dedicated full-height scrollable event list **Features**: - Cyan underline indicator for active tab - Event cards with type badges (green: `message.in`, cyan: `message.out`) - New event highlight with cyan border/glow - Empty states for disabled capture #### 2. Historical Events & Session Grouping **Extended event visibility** from current session to all anima history: - Events tab now shows up to 200 events (was: 50 current session only) - Grouped by session with collapsible cards - Session headers show: indicator (🟢 Current vs Session ID), event count, time range - Cyan highlight for active session **Chat box height adjustment**: - Natural height with `min-h-[600px]` and `max-h-[calc(100vh-8rem)]` - Prevents over-stretching on tall screens while maintaining comfortable minimum #### 3. Event & Session Sorting Controls **Dual sorting system** for flexible event browsing: - **Event sorting**: Toggle between newest-first (default) ↔ chronological reading order - **Session sorting**: Toggle between newest session first ↔ oldest session first - Independent controls with animated arrow icons (rotate 180° on toggle) - ALL tab limited to 5 recent events with "View all" navigation button #### 4. Session Collapsing & Bulk Controls **Session management enhancements** for noise reduction: - Sessions start collapsed (click header to expand) - Chevron icons indicate expand/collapse state with rotation animation - Bulk controls: Collapse/Expand all sessions button (`[ + ]` / `[ - ]`) - Hover states on session headers for better interaction feedback #### 5. Provider Expansion & Dual Chatbox Layout **Multi-provider toggle** showing future LLM options: - ✅ Anthropic (Claude) - Active, cyan accent - ✅ OpenAI (GPT-4) - Active, green accent - 🔒 xAI (Grok) - Disabled/grayed out (coming soon) - 🔒 Google (Gemini) - Disabled/grayed out (coming soon) **Session label accuracy fix**: - Changed from "Session 1, 2..." to actual session ID prefixes (`Session a3b4c5d6`) - Labels now reflect real session identity regardless of sort order **Dual chatbox layout** for future split-view features: - Side-by-side configuration: Left (active chat, `max-w-xl`) + Right (empty, `flex-1`) - Height increased to `max-h-[1200px]` for better vertical screen utilization - Improved spacing: `p-8` padding, `gap-6` between boxes **Input ergonomics**: - Textarea height increased from 1 row → 3 rows - Better for multi-line prompts ### Files Modified **Type System**: - `frontend/src/types/features/sandbox.ts` - Extended LLMProvider type (+xAI, +Google), added `enabled` field **Components**: - `frontend/src/components/sandbox/SandboxSettings.tsx` - 4-provider dynamic rendering - `frontend/src/components/sandbox/ChatInput.tsx` - Height increase (rows={3}) **Pages**: - `frontend/src/app/(authenticated)/sandbox/page.tsx` - All 5 refinements ### Build Verification - ✅ Build successful (13 routes, 2.2s compile) - ✅ No TypeScript errors - ✅ Linter passed (0 errors, 1 pre-existing warning) - 📦 Sandbox route: 239 kB total (76.5 kB route-specific) ### UX Improvements - **Improved Navigation**: Tab system organizes content, reduces clutter - **Historical Context**: View all anima events across sessions (not just current) - **Flexible Browsing**: Independent event/session sorting for different reading patterns - **Noise Reduction**: Collapsible sessions + bulk controls prevent overwhelm - **Future-Ready UI**: Provider expansion builds anticipation, dual chatbox prepares for comparison features ---
### Changed **Frontend: Type System Consolidation** (~1 hour) Unified scattered TypeScript types from fragmented structure (`types/`, `lib/api/types/`) into single `src/types/` directory following Next.js 15 best practices. **Migration**: - Moved backend DTO types: `lib/api/types/*.ts` → `types/api/` (anima, event, memory, common) - Moved feature types: `types/sandbox.ts` → `types/features/sandbox.ts` - Updated 13 import statements across API clients, hooks, components - Deleted old `lib/api/types/` directory **Benefits**: - Single import: `import { Anima, Event, Memory } from '@/types'` (was: `@/lib/api/types/anima`) - Eliminated type duplication (conflicting Event/Memory definitions) - Clear organization: `api/` (backend DTOs) vs `features/` (UI types) - Better IDE autocomplete and type discovery **Verification**: - ✅ Build successful (13 routes, 2.0s compile) - ✅ Linter passed (0 errors, 3 pre-existing warnings) **Files Changed**: - Created: `types/api/index.ts`, `types/features/sandbox.ts` - Modified: 13 files (API clients, hooks, components) - Deleted: `lib/api/types/` (6 files) --- ### Added **Documentation: Frontend Architecture Overview** Created `docs/frontend-architecture.md` (288 lines) - comprehensive frontend architecture guide for senior engineers and LLM agents. **Coverage**: - Tech stack (Next.js 15, React 19, TypeScript, Tailwind 4, Supabase) - Complete directory structure with annotations - 5 core architecture patterns (route groups, two-tier API client, custom hooks, auth flow, type system) - Key features (landing page, anima dashboard, sandbox AI chat) - Design system (terminal aesthetic, styling approach) - Development workflow and API integration ---
### Added **Frontend: Sandbox AI Integration - Streaming Chat with Event Capture** (~3 hours) Implemented production-ready AI chat interface allowing users to converse with Claude 3.5 Sonnet or GPT-4o. Conversations automatically generate Events feeding into the Memory Synthesis workflow when Elephantasm toggle enabled. #### Core Features - **Multi-Provider Support**: Anthropic Claude (`claude-3-5-sonnet-20241022`) + OpenAI GPT-4 (`gpt-4o`) - **Real-Time Streaming**: Token-by-token message updates using custom fetch-based implementation - **Event Persistence**: Automatic MESSAGE_IN/MESSAGE_OUT event creation with session-based grouping - **Session Management**: UUID-based session IDs (per browser tab) stored in sessionStorage - **BYOK Model**: Bring-your-own-key approach with session-only storage (no database persistence) - **Error Handling**: Invalid API keys, network failures, provider errors with user-friendly messages #### Implementation Details **New Files**: - `frontend/src/types/sandbox.ts` - LLM provider types and configuration constants - `frontend/src/app/api/sandbox/chat/route.ts` - Next.js Edge route for streaming LLM responses - `frontend/src/hooks/useSandboxSession.ts` - Session UUID management with sessionStorage **Modified Files**: - `frontend/src/components/sandbox/SandboxSettings.tsx` - Refactored to controlled component with real anima fetching - `frontend/src/app/(authenticated)/sandbox/page.tsx` - Complete chat implementation with streaming and event capture **Dependencies**: - `ai@5.0.82` - Core AI SDK - `@ai-sdk/anthropic@2.0.39` - Anthropic provider - `@ai-sdk/openai@2.0.58` - OpenAI provider #### Technical Architecture **Streaming Flow**: 1. Frontend creates MESSAGE_IN event (if Elephantasm ON) 2. POST to `/api/sandbox/chat` with conversation history 3. Edge route streams LLM response via `toTextStreamResponse()` 4. Frontend decodes plain text stream and updates UI in real-time 5. Frontend creates MESSAGE_OUT event after stream completion #### UX Improvements - **Provider Toggle**: Two-button UI (Claude/GPT-4) with auto-clear API key on switch (prevents auth mismatches) - **Dynamic Placeholders**: API key field shows provider-specific format hints (`sk-ant-...` vs `sk-proj-...`) - **Active States**: Cyan border for Claude, green for GPT-4 when selected - **Elephantasm Toggle**: Disabled when no anima selected, shows capture status in inspector panel - **Inspector Panel**: Real-time session info (capture mode, session ID, message count) ---
### Added **Frontend: Sandbox UI Design Phase - Complete Chat Interface** (~1.5 hours) Implemented full terminal-aesthetic chat interface for AI sandbox experimentation, featuring two-column layout with floating chat panel and Elephantasm inspector. #### Components Created (Static/Mock Phase) **SandboxSettings.tsx** - Horizontal settings bar with: - Anima selector dropdown (3 mock animas) - Provider selector (Anthropic/OpenAI) - API key input with session state indicator (unsaved → saving → saved) - Elephantasm toggle with tooltip - Terminal-styled grid layout with zinc separators **ChatMessage.tsx** - Role-based message styling: - Border accents: green (`border-green-500`) for user, cyan (`border-cyan-500`) for assistant - Timestamp formatting with `date-fns` (relative time: "5m ago") - Monospace fonts (`font-mono text-sm`) **ChatContainer.tsx** - Message list container: - Auto-scroll to bottom on new messages - Empty state: "Start conversation..." - Max-width centered layout with smooth scroll **ChatInput.tsx** - Terminal prompt interface: - Green `>` prompt indicator - Auto-expanding textarea - Keyboard shortcut: Ctrl+Enter / Cmd+Enter to send - Disabled states with opacity styling **Sandbox Page** (`/sandbox`): - Two-column fixed layout: floating chat panel (left) + inspector (right, `w-96`) - Chat floats in bordered card (`border-2 border-zinc-800 bg-black/90`) - Inspector placeholder sections: Events, Memories, Session Info - Mock data: 4 hardcoded messages (user/assistant alternating) - Particle field background override #### Navigation Integration Modified `layout.tsx` with active state highlighting: - "Anima" → `/anima` (green text + underline when active) - "Sandbox" → `/sandbox` (cyan text + underline when active) - Uses `usePathname()` hook for dynamic highlighting **Build Status**: ✅ Successful - No TypeScript errors, route size 40.6 kB --- ### Changed **Backend Architecture: LLM Infrastructure Reorganization** Relocated `backend/app/workflows/llm/` to `backend/app/services/llm/` to align with architectural separation of concerns. **Rationale**: LLM clients are reusable infrastructure (multi-provider API adapters) that can be used by any workflow, API route, or script. `services/` layer holds infrastructure (scheduler, LLM clients), while `workflows/` layer holds domain-specific orchestration (LangGraph state machines). **Files Moved**: - `workflows/llm/clients/` → `services/llm/clients/` - `workflows/llm/factory.py` → `services/llm/factory.py` --- ### Removed **Backend API Cleanup: Deprecated Synthesis Routes** Removed `backend/app/api/routes/synthesis.py` (195 lines) containing deprecated workflow-specific endpoints. Unified all workflow orchestration under `/api/scheduler/workflows/{workflow_name}/trigger` pattern. ---
### Added **LangGraph Memory Synthesis System: Complete End-to-End Automated Workflow** (~10 hours, Phases 0-6) Successfully implemented a production-ready, fully automated memory synthesis system that transforms raw events into structured memories using LLM-powered analysis, with scheduled automation, full provenance tracking, and checkpoint infrastructure. #### System Overview **What We Built:** - 🎯 **5 workflow nodes** orchestrating memory synthesis pipeline - 🤖 **Multi-provider LLM client** (Anthropic Claude + OpenAI GPT with automatic retry) - 📊 **Accumulation scoring algorithm** (time + events + tokens) - 🔗 **Full provenance tracking** (Memory ↔ Event links with bulk operations) - 🏗️ **Compiled StateGraph** with conditional routing and async PostgreSQL checkpointer - 💾 **Dedicated PostgreSQL schema** (`langgraph`) for checkpoint isolation - ⏰ **Automated scheduler** (APScheduler with FastAPI lifespan integration) - 🚀 **Parallel anima processing** (10× faster via asyncio.gather) - 🔌 **REST API endpoints** for manual triggers and monitoring - ✅ **22 passing tests** across domain operations, services, and scheduler - 📝 **Complete state schema** (14 fields) with checkpoint support --- #### Key Components **Phase 0-1: Setup & Foundation** - Dependencies: `langgraph`, `langgraph-checkpoint-postgres`, `anthropic`, `openai`, `tenacity`, `apscheduler`, `structlog` - State schema: `MemorySynthesisState` TypedDict (14 fields, JSON-serializable) - Configuration: Environment-driven via Pydantic Settings **Phase 2: Domain Extensions** - `MemoryOperations.get_last_memory_time()` - Baseline timestamp - `EventOperations.count_since()`, `get_since()` - Temporal queries - Database context manager for workflow nodes **Phase 3: Multi-Provider LLM Client** - Abstract `BaseLLMClient` with shared prompt building - Concrete: `AnthropicClient`, `OpenAIClient` - Automatic retry (exponential backoff), robust JSON parsing **Phase 4: Workflow Nodes** 1. **Accumulation Score** - Calculates composite score from time/events/tokens 2. **Threshold Gate** - Routes based on synthesis threshold 3. **Event Collection** - Fetches chronological events 4. **Memory Synthesis** - LLM-powered analysis (async) 5. **Memory Persistence** - Atomic DB write with provenance **Phase 5: Graph Assembly & Checkpoints** - `StateGraph` with 5 nodes + conditional routing - Dedicated `langgraph` schema (separate from `public`) - Async PostgreSQL checkpointer (schema-aware) **Phase 6: Scheduler Integration** - 3-layer architecture: Orchestrator → Base → Workflow - APScheduler singleton with graceful shutdown - FastAPI lifespan integration - REST API: `/api/synthesis/trigger`, `/status`, `/start`, `/stop` - Parallel execution: `asyncio.gather()` (10× faster) --- #### Performance Characteristics **Node Execution Times:** - Accumulation Score: ~50ms - Threshold Gate: <1ms - Event Collection: ~100ms - Memory Synthesis: **2-5s** (LLM bottleneck) - Memory Persistence: ~50ms **Total Workflow Latency:** ~3-6 seconds (LLM-dominated) **Scaling:** - 10 animas: 6-8s (parallel) - 100 animas: 10-15s (parallel) - 1000 animas: 60-90s (LLM concurrency bottleneck) --- #### Testing Coverage **22 passing tests:** - 4 tests: Domain extensions - 10 tests: LLM client (providers, retry, parsing) - 8 tests: Scheduler (lifecycle, triggers, statistics) ---
### Added **Whitepaper Blog Expansion: From Philosophy to System Architecture** (~35 minutes) - Added structured post in `docs/blog/from-philosophy-to-system-architecture.md` with standard frontmatter, sectioned narrative, and updated terminology (Anima, Dreamer) - Linked cover art via `/images/blog/philosophy-to-architecture.png` and set publication metadata for 29 Oct 2025 - Ensured blog principles align with LTAM roadmap for continuity, reflection, and deterministic introspection ---
### Added **Event Schema Enhancement** (`backend/app/models/database/events.py`, migration `f699f48a6e39`) **New Fields (nullable, backward compatible):** - `role` - VARCHAR(50), indexed - Message role type (user/assistant/system/tool) - `author` - VARCHAR(255) - Author identifier (username, tool name, model name) **Benefits:** - Structured message attribution for Memory synthesis provenance - Efficient role-based queries via indexed column - Industry alignment with OpenAI/Anthropic message patterns - Enables conversation reconstruction with proper attribution **API Enhancement:** - Query by role: `GET /api/events?anima_id={uuid}&role=user` - Update role/author via PATCH `/api/events/{id}` ### Documentation - `docs/completions/event-role-author-fields-27oct25.md` ---
### Changed **BREAKING CHANGES - Full-Stack Refactoring** (~5.5 hours, 30 files) **1. Spirit → Anima Entity Rename** (migrations `5d828e895a4c`) - Renamed core entity for philosophical alignment (Jungian psychology: inner self/soul) - **Database:** Table `spirits` → `animas` (safe rename, zero data loss) - **API:** `/api/spirits/*` → `/api/animas/*`, query param `spirit_id` → `anima_id` - **Backend:** Models, operations, routes (`SpiritOperations` → `AnimaOperations`) - **Frontend:** Types, API clients, hooks, components (`useSpirits()` → `useAnimas()`) - Files: 7 created, 20 modified, 6 deleted **2. Event & Memory Model Schema Evolution** (migration `d1575f589a89`) - **Event:** Renamed `meta_summary` → `summary` (clearer naming) - **Memory:** Added `content` field (nullable), made 5 fields nullable (`summary`, `importance`, `confidence`, `state`, `meta`) for development flexibility - **Domain:** `EventOperations.update_meta_summary()` → `update_summary()` - Files: 1 created, 10 modified **Breaking API Changes:** ```diff # Endpoints - /api/spirits → /api/animas # Event field - "meta_summary" → "summary" # Memory fields (now nullable) - summary: required → optional - importance: required → optional ``` **Key Technical Lesson:** - Alembic autogenerate sees renames as drop+add - manually edit migrations to use `op.rename_table()` / `op.alter_column(new_column_name=...)` - Update `migrations/env.py` imports after entity renames ---
### Added **Research Library System** (`/research`, dynamic `/downloads/[filename]`) **Core Components:** - **Gallery page:** Responsive grid (1/2/3 columns), PDF cover images, category badges, source attribution - **Download previews:** SEO metadata, Open Graph tags, cover images with download CTA - **PDF cover workflow:** Pre-generated static images (10-30x faster than client-side rendering: ~150ms vs 2-5s) - **Source attribution:** Internal (`→ Elephantasm Team`) vs external (`🔗 Author et al.`) with clickable links - **Footer redesign:** Minimal single-line fixed overlay (67% vertical space reduction: 40px vs 120px) - **Navigation:** Replaced "Changelog" with "RESEARCH" in main nav, moved Changelog to footer **Performance Benefits:** - Static images: +0KB bundle vs +500KB for pdf.js - SEO-friendly (crawlers see images, Open Graph tags work) - CDN-cacheable **Current Research Papers:** 1. "A Guide to Memory in Agents" (Elephantasm whitepaper, 5.9 MB) 2. "MemoryR1" (arXiv:2508.19828, external, 2.8 MB) **Workflow:** Add PDF → generate cover via `pdftoppm` → optimize with `pngquant` → configure metadata in `downloads-config.ts` **Files Created:** 7 (gallery, preview pages, footer, config, READMEs) ---
### Added **Backend Production Deployment: Fly.io Single-Region Setup** (https://elephantasm.fly.dev) **Configuration:** - **Region:** Singapore (`sin`), 2 machines, auto-suspend mode (~200ms wake-up) - **Infrastructure:** Multi-stage Docker (87 MB), Python 3.12.6-slim, single worker per machine - **Health checks:** `/api/health` every 30s with DB connectivity verification - **Secrets:** 5 environment variables via `fly secrets set` (DATABASE_URL, MIGRATION_DATABASE_URL, Supabase keys) - **Cost:** ~$11-15/month (30-40% reduction vs Marlin multi-region) **Key Decisions:** - Single region v1 (simpler than Marlin's multi-region, no manual machine pinning) - Suspend mode (not stop) for fast wake-ups vs cold starts - Min 1 machine for zero cold starts - External Supabase PostgreSQL (no migration needed), pgBouncer pooling **Files Created:** - `backend/Dockerfile` (multi-stage build) - `backend/.dockerignore` (build optimization) - `backend/fly.toml` (deployment config) - `backend/app/api/routes/health.py` (enhanced health checks) **Comparison to Marlin:** - Regions: 2 → 1, Machines: 4 → 2, Cost: $18-22 → $11-15/month - Simpler deployment (no post-deploy manual steps) ---
### Added **Whitepaper & Blog Page** (`/whitepaper`) **Features:** - Markdown-based blog system (`docs/blog/` directory, `gray-matter` frontmatter parsing) - Magazine-style whitepaper cover preview (192px × 256px, 3:4 aspect) - Multi-layered starfield background (20 twinkling stars + 3 drifting nebulae) - Modal overlay for reading posts (Escape key, click-outside-to-close) - Glassmorphic cards with backdrop blur - Responsive grid layout (1/2/3 columns) - Server/client component split for performance **Files Created:** 7 (whitepaper page, client component, nav, blog parser, guides) ### Fixed **Landing Page Mobile Responsive Text Overflow** **Solution:** Responsive CSS strategy - animations on desktop (>640px), static wrapped text on mobile (≤640px) - Tradeoff: Sacrificed typewriter animation on mobile for readability ---
### Fixed **API Routing Consistency: 404 Errors + 307 Redirects Eliminated** **Issues Fixed:** - **Memories 404:** Router hardcoded `/api/memories` while mounted at `/api` prefix → created `/api/api/memories` (404) - Fix: Added `prefix="/memories"` to router, changed decorators to relative paths - **Trailing Slash Redirects (307):** Route decorators used `"/"` creating `/api/spirits/` (with slash), frontend called `/api/spirits` (no slash) - Fix: Changed all root routes from `"/"` → `""` across 4 routers **Impact:** - Fixed 9 endpoints returning 404 (memories CRUD + stats) - Eliminated 307 redirects on 5 list/create endpoints (50% HTTP request reduction) ### Changed **Database Startup: Migration Discipline Enforcement** Removed auto-table creation (`SQLModel.metadata.create_all()`) on startup, replaced with migration verification. **New Behavior:** - Checks `alembic_version` table exists - Raises `RuntimeError` with clear message if migrations not applied - Logs current migration version on startup **Breaking Change:** ⚠️ First-time setup now requires `alembic upgrade head` before `uvicorn main:app` **Benefits:** Enforces migration discipline, faster startup (no DDL queries), production-safe ---
### Changed **Backend Architecture Refactor: Async-to-Sync Migration (Marlin Hybrid Pattern)** (~2 hours) Migrated entire backend from AsyncSQLAlchemy to sync SQLAlchemy, implementing hybrid async/sync pattern that eliminates prepared statement collisions with pgBouncer while maintaining HTTP concurrency. **Three Phases:** **Phase 1 - Database Layer:** - `create_async_engine` → `create_engine` (sync) - `AsyncSession` → `Session` with NullPool (delegates to pgBouncer) - `async def get_db()` → `def get_db()` (generator pattern) **Phase 2 - Domain Operations:** - Converted 48 methods from `async def` → `def` (4 files, ~2,020 lines) - Removed ~165 `await` keywords - No business logic changes (purely mechanical) **Phase 3 - API Routes:** - Updated 32 endpoints (removed ~80 `await` when calling domain operations) - **Kept routes as `async def`** for HTTP concurrency (critical!) **Hybrid Pattern:** ```python @router.post("/", response_model=SpiritRead) async def create_spirit( # ← Still async! data: SpiritCreate, db: Session = Depends(get_db) # ← Sync Session ): spirit = SpiritOperations.create(db, data) # ← No await! return SpiritRead.model_validate(spirit) ``` **Architecture Evolution:** ``` Before: Routes (async) → await → Domain (async) → await → AsyncSession After: Routes (async) → Domain (sync via thread pool) → Session ``` **Benefits:** - Fixes prepared statement collisions with pgBouncer - Removes async overhead from business logic - Simpler debugging (no coroutine frames) - Maintains HTTP concurrency ---
### Added **Frontend Phase 2: Spirit Creation UI + Data Visualizations** (~2 hours, 3 sessions) **Session 1 - Spirit Creation Modal:** - **CreateSpiritModal** component (179 lines) - Modal form for creating first Spirit - Name (required) + description (optional) fields - Loading states, error handling, auto-close on success - Terminal aesthetic (Space Mono, green accents, bordered UI) - Triggers parent refetch after creation **Session 2 - Events Timeline:** - **EventsTimeline** visualization - Horizontal scrollable timeline (recent 50 events) - Color-coded event blocks (blue/green/purple/gray by type) - Relative time formatting (`getRelativeTime()` helper - "2h ago", "Yesterday", etc.) - Hover tooltips with event content preview - Custom thin scrollbar (6px height, cross-browser) **Session 3 - Memories Heatmap:** - **MemoriesMosaic** visualization - GitHub-style heatmap (7×26 grid, 182 days) - Week-aligned grid math (Sunday boundaries) - 5-level color intensity (0-4) based on memory count ratio - Month labels with intelligent positioning - Day labels (Mon/Wed/Fri/Sun alternate days) - Hover tooltips with singular/plural logic **Helper Functions:** - `dateUtils.ts` (105 lines) - `aggregateMemoriesByDate()`, `getMonthLabels()` - Pure functions (no React deps, easily testable) **Files Created:** 3 (modal, dateUtils, modals barrel export) **Files Modified:** 4 (platform page, timeline, mosaic, globals.css) **Tailwind v4 Configuration:** - Added `--grid-template-columns-26` custom property for heatmap grid ---
### Added **Frontend API Integration Layer: Complete Backend Connection** (15 files, 1,058 lines, ~3 hours) **Two-Tier API Client Architecture:** - **BaseAPIClient** (213 lines) - Generic HTTP foundation with auto JWT injection, 401 token refresh, type-safe `APIResponse<T>` wrapper - **Domain clients** (4 files, ~500 lines) - `SpiritsAPI`, `EventsAPI`, `MemoriesAPI`, `ProvenanceAPI` with singleton exports - **Type definitions** (5 files, ~150 lines) - DTOs matching backend exactly (`Spirit`, `Event`, `Memory`, enums) - **React hooks** (4 files, ~250 lines) - `useSpirits()`, `useMemories()`, `useEvents()` with `{ data, loading, error, refetch }` pattern **Platform Page Integration:** - Live data fetching via API hooks (replaced hardcoded "Spirit-01") - Loading states (spinner + terminal text), error states (reload button), empty states - Components accept data props: `<MemoriesMosaic memories={data} loading={bool} />` **Technical Patterns:** - Method collision fix: `get(id)` → `getById(id)` to avoid shadowing base class - Type safety: `unknown` over `any` throughout (ESLint compliance) - Singleton services: `export const SpiritsAPI = new SpiritsAPIClient()` - Auto-refresh on 401 with single retry **Bundle Impact:** +40 KB minified, 100% TypeScript coverage ---
### Added **Spirit View Dashboard v2: Particle Background + Centered Layout + Empty State Components** (3 phases, ~80 minutes) **Phase 1 - Particle Field Background:** - Pure CSS starfield (8 radial gradient layers, `@keyframes twinkle`, opacity 0.1-0.2) - GPU-accelerated, zero JavaScript overhead **Phase 2 - Centered Layout:** - Three-column grid → vertical stack (removed sidebars) - Spirit Core enlarged 50% (192px → 288px desktop) - Bundle reduced 29% (1.83 kB → 1.3 kB) **Phase 3 - Empty State Components:** - `MemoriesMosaic.tsx` (99 lines) - Terminal container, `> No memory history yet.`, TypeScript interfaces matching backend - `EventsTimeline.tsx` (73 lines) - Horizontal timeline, `> No events recorded yet.`, custom green scrollbar - Barrel export in `dashboard/index.ts` ### Changed - Platform page: Removed left (metrics/actions) and right (memories/system) sidebars - Integrated components with hardcoded `spiritId="spirit-01"` ---
### Added **Spirit View Dashboard: RPG Character Screen Paradigm with Terminal Aesthetic** (`/platform`, 162 lines) **Three-Column RPG Layout:** - Left: Spirit Metrics (memory/event counts, importance, confidence) + Actions (New Memory, View Events, API Docs buttons) - Center: Spirit Core (circular sphere 🌌 emoji 48×48→56×56, green/blue gradient glow, `> ACTIVE` status) - Right: Recent Memories + System Info (user, version, online status) **Authenticated Layout Redesign** (`layout.tsx`, 99 lines): - Galactic cityscape background (matches landing page) - Minimal terminal header: Wordmark + Spirit switcher (`> Spirit-01`) + email + sign out - Terminal-styled loading: Green spinner + `> LOADING...` - Space Mono font, black/gray/green palette **Design Pattern:** Terminal window component (2px border, glassmorphism, `[ TITLE ]` headers) used 5× across dashboard ### Changed - Landing page header: Wrapped wordmark in `flex-1` for three-column centering - Dashboard route: `(authenticated)/page.tsx` → `(authenticated)/platform/page.tsx` (now `/platform`) ### Fixed **User Auth Trigger** (migration `4faf087cf25d`): - Problem: `handle_new_user()` trigger missing `is_deleted` field → 500 errors on signup - Solution: Added `is_deleted=false` to INSERT statement ---
### Added **Frontend UX Enhancements: Mobile-Responsive Landing Page + Terminal-Styled Login Redesign** **Landing Page Mobile Responsiveness:** - Hamburger menu (client component with React state, auto-close on link click) - Responsive sizing: `px-4 sm:px-8`, `text-base sm:text-lg md:text-xl` - Green `>` prompts with `flex-shrink-0`, text `break-words` for wrapping **Login Page Terminal Redesign:** - Terminal window (`[ ELEPHANTASM LOGIN TERMINAL ]`, 2px gray border, X to home) - Galactic cityscape background with `bg-black/40` overlay - Glassmorphism + Space Mono font, green terminal prompts (`>`) on buttons/messages - Dark inputs with green focus borders (`focus:border-green-500`) - Email/password + magic link auth (both methods retained, zero breaking changes) ### Changed - Landing: Desktop three-column → mobile two-column (wordmark + hamburger), navigation in dropdown - Login: Removed sign-up toggle, replaced Card with terminal design, uppercase labels with tracking ---
### Added **Frontend Authentication & Platform Restructure: Route Groups + Supabase SSR** (6 files, 618 lines) **Route Groups:** - `(public)/` - Landing page, accessible without auth - `(authenticated)/` - Platform dashboard, protected by middleware - Shared layouts with auth boundaries, URL structure unchanged (`/` vs `/platform`) **Supabase SSR Integration:** - `@supabase/ssr` with cookie-based sessions (browser + server clients) - Auth middleware with automatic token refresh, redirect logic (`/login?redirect={path}`) - `AuthContext` provider for global user state, `useAuth()` hook **Platform Dashboard** (`/platform` - authenticated route): - Empty state placeholder: "Welcome to Elephantasm Platform" - Protected route (redirects to `/login` if unauthenticated) **Environment:** `NEXT_PUBLIC_SUPABASE_URL`, `NEXT_PUBLIC_SUPABASE_ANON_KEY` ---

Showing latest 20 releases • View all on GitHub