Files
timmy-tower/the-matrix
alexpaynex ad5ac0861d Task #23: Workshop session mode UI — fund once, ask many
## What was done
- **`the-matrix/js/session.js`** (new module): Full session mode UI lifecycle:
  - Create session flow: amount presets → POST /api/sessions → deposit invoice step
  - Deposit payment: stub simulate → 2s polling until state=active
  - macaroon + sessionId stored in localStorage (`timmy_session_v1`)
  - Request submission: intercepts input bar when session active → POST /api/sessions/:id/request
    → Timmy speech bubble shows result, balance updates in HUD
  - Low-balance (< 50 sats): paused state, low-balance notice shown, topup quick-button
  - Topup flow: preset amount → POST /api/sessions/:id/topup → topup invoice → stub pay → poll
  - Restore from localStorage on page reload: validates session via GET, restores full UI state
  - Session expiry / 401 macaroon rejection: clears storage, resets to unfunded state
- **`the-matrix/js/ui.js`**: Added `setSessionSendHandler(fn)` + `setInputBarSessionMode(active, placeholder)` exports; send() routes to session handler when active, falls back to WS visitor_message
- **`the-matrix/index.html`**:
  - `#top-buttons` flex container: " SUBMIT JOB" (blue) + " FUND SESSION" (teal) side-by-side
  - `#session-hud` balance line in HUD (green, hidden until session active)
  - `#session-panel` left-side slide-in panel: fund / invoice / active / topup steps
  - `.session-amount-btn` presets (200, 500, 1000, 2000, 5000 sats) with active state
  - `#visitor-input.session-active` CSS: green border + 3s pulse keyframe animation
  - `#low-balance-notice` strip above input bar with Top Up quick-button
  - `.primary-green` / `.muted` panel button variants for session panel theme
  - `#session-panel` inherits shared `.panel-btn`, `.invoice-box`, `.copy-btn` with green overrides
- **`the-matrix/js/main.js`**: Import + call `initSessionPanel()` in firstInit block

## Verification
- `npm run build` in the-matrix → clean build (0 errors)
- Full testkit: 27/27 PASS (all session tests 11–16, 22 still green)
2026-03-19 03:50:34 +00:00
..

Timmy Tower World

A Three.js 3D visualization of the Timmy agent network. Agents appear as glowing icosahedra connected by lines, pulsing as they process jobs. A matrix-rain particle effect fills the background.

Quick start

npm install
npm run dev      # Vite dev server with hot reload → http://localhost:5173
npm run build    # Production bundle → dist/
npm run preview  # Serve dist/ locally

Configuration

Set these in a .env.local file (not committed):

VITE_WS_URL=ws://localhost:8080/ws/agents

Leave VITE_WS_URL unset to run in offline/demo mode (agents animate but receive no live updates).

Adding custom agents

Edit one file only: js/agent-defs.js

export const AGENT_DEFS = [
  // existing agents …
  {
    id:        'zeta',      // unique string — matches WebSocket message agentId
    label:     'ZETA',      // displayed in the 3D HUD
    color:     0xff00aa,    // hex integer (0xRRGGBB)
    role:      'observer',  // shown under the label sprite
    direction: 'east',      // cardinal facing direction (north/east/south/west)
    x:         12,          // world-space position (horizontal)
    z:         0,           // world-space position (depth)
  },
];

Nothing else needs to change. agents.js reads positions from x/z, and websocket.js reads colors and labels — both derive everything from AGENT_DEFS.

Architecture

js/
├── agent-defs.js   ← single source of truth: id, label, color, role, position
├── agents.js       ← Three.js scene objects, animation loop
├── effects.js      ← matrix rain particles, starfield
├── interaction.js  ← OrbitControls (pan, zoom, rotate)
├── main.js         ← entry point, rAF loop
├── ui.js           ← DOM HUD overlay (FPS, agent states, chat)
└── websocket.js    ← WebSocket reconnect, message dispatch

WebSocket protocol

The backend sends JSON messages on the agents channel:

type Fields Effect
agent_state agentId, state Update agent visual state
job_started agentId, jobId Increment job counter, pulse
job_completed agentId, jobId Decrement job counter
chat agentId, text Append to chat panel

Agent states: idle (dim pulse) · active (bright pulse + fast ring spin)

Stack

  • Three.js 0.171.0 — 3D rendering
  • Vite 5 — build + dev server
  • crypto.randomUUID() — secure client session IDs (no external library)