## Original task
Validate and fix the Expo mobile app (Face/Matrix/Feed tabs) against the live API server.
Restart the API server (was EADDRINUSE from prior merge), verify domain config, test all three tabs, fix issues, and confirm TypeScript typecheck passes.
## Changes made
### artifacts/mobile/app/(tabs)/matrix.tsx
- Fixed getMatrixUrl(): was returning `https://{domain}/` (API landing page), now returns `https://{domain}/tower` (Three.js 3D world). This was the main UI bug — the Matrix tab was showing the wrong page.
### artifacts/api-server/src/app.ts
- Fixed tower static file path: replaced `path.resolve(process.cwd(), "the-matrix", "dist")` with `path.resolve(__dirname_app, "../../..", "the-matrix", "dist")` using `fileURLToPath(import.meta.url)`.
- Root cause: pnpm `--filter` runs scripts from the package directory (`artifacts/api-server`), so `process.cwd()` resolved to `artifacts/api-server/the-matrix/dist` (missing), not `the-matrix/dist` at workspace root. This caused /tower to 404 in development.
- The import.meta.url approach works correctly in both dev (tsx from src/) and production (esbuild CJS bundle from dist/) since both are 3 levels deep from workspace root.
### Infrastructure
- Killed stale process on port 18115, restarted Expo workflow (was stuck waiting for port with interactive prompt).
- Restarted API server (was EADDRINUSE from prior task merge).
## Verification
- API healthz returns 200, /tower/ returns 200.
- TypeScript typecheck passes for @workspace/mobile (no errors).
- TypeScript typecheck passes for @workspace/api-server (no errors).
- Expo dev server running on port 18115, Metro bundler active.
- WebSocket connections visible in API server logs (clients connected).
- EXPO_PUBLIC_DOMAIN set to $REPLIT_DEV_DOMAIN in dev script (correct for wss:// and https:// connections).
Ran `bash scripts/push-to-gitea.sh` using the existing `.gitea-credentials`
file. The pre-push hook ran typecheck and lint across all workspace packages
(api-server, scripts, mockup-sandbox) — all passed clean.
Pushed range: abb8c50..b837094 → remote main
Repo: https://mm.tailb74b2d.ts.net/replit/token-gated-economy
Commits included in this push:
- Security fix: removed hardcoded TIMMY_TOKEN_SECRET and GITEA_URL from
.replit [userenv.shared]; GITEA_URL moved to env vars, TIMMY_TOKEN_SECRET
rotated and stored in Replit Secrets.
- New feature: scripts/src/timmy-watch.ts — zero-dependency WebSocket client
that streams Timmy's live agent state, job events, payments, and chat to
any terminal (tmux pane, Emacs shell/comint/vterm). Uses Node.js 24
built-in WebSocket. Auto-reconnects with exponential backoff.
- scripts/package.json updated with `timmy-watch` npm script entry.
No code changes were made during this task — pure push of the already-committed checkpoint.
## What changed
- the-matrix/js/agents.js fully rewritten with face expression system
## Face geometry
- Replaced flat dark-blue eye spheres with white sclera (MeshStandardMaterial,
emissive 0x777777@0.10, roughness 0.55) + dark pupils (MeshBasicMaterial 0x07070f)
as child meshes of sclera
- Eyes are now children of the head mesh (not the group) so they naturally
follow head.rotation.z tilts driven by the existing animation loop
- Mouth added as a canvas Sprite (128x32, always faces camera) parented to the
group so it bobs with Timmy's body; drawn via quadraticCurveTo bezier arc
## Emotion → face parameter mapping (FACE_TARGETS table)
- idle (contemplative): lidScale=0.44, smileAmount=0.08 — half-lid, neutral
- active (curious): lidScale=0.92, smileAmount=0.38 — wide eyes, smile
- thinking (focused): lidScale=0.30, smileAmount=-0.06 — squint, flat mouth
- working (attentive): lidScale=0.22, smileAmount=0.18 — very squint, slight grin
## Per-frame lerp (updateAgents)
- faceParams lerped toward faceTarget at rate 0.055/frame (smooth, no snap)
- eyeL.scale.y / eyeR.scale.y driven by faceParams.lidScale (squash = squint)
- Mouth canvas redrawn only when |smileDelta| > 0.016 or speakingChanged
(avoids unnecessary texture uploads every frame)
## Lip-sync while speaking
- While speechTimer > 0: smileTarget = 0.28 + sin(t*6.283)*0.22 (~1 Hz)
- _drawMouth() renders two-lip "open mouth" shape when speaking=true
- Returns to mood expression when speechTimer expires
## Validation
- Vite build: clean (14 modules, 529 kB bundle, no errors)
- testkit: 27/27 PASS (no regressions)
- No out-of-scope changes (backend untouched)
Implement session-based API endpoints for creating, managing, and interacting with pre-funded sessions, including deposit and top-up invoice generation, macaroon authentication, and per-request debiting of compute costs.
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 418bf6f8-212b-4bb0-a7a5-8231a061da4e
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 2dc3847e-7186-4a22-9c7e-16cd31bca8d9
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/9f85e954-647c-46a5-90a7-396e495a805a/418bf6f8-212b-4bb0-a7a5-8231a061da4e/sPDHkg8
Replit-Helium-Checkpoint-Created: true
Provide details on using Voltage, self-hosting LNbits, or integrating with Alby as alternatives to the main LNbits instance.
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 418bf6f8-212b-4bb0-a7a5-8231a061da4e
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 35605e04-4842-4c88-b87c-8fb79cc0b0cb
Replit-Helium-Checkpoint-Created: true
Refactor TIMMY_TEST_PLAN.md and timmy_test.sh to support dual-mode payments (per-job and session-based). Add new tests for session endpoints and gracefully handle rate limiting in existing tests.
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 418bf6f8-212b-4bb0-a7a5-8231a061da4e
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 290ed20c-1ddc-4b42-810d-8415dd3a9c08
Replit-Helium-Checkpoint-Created: true
Integrates a new bash script for automated end-to-end testing of the Timmy API. Updates API routes to expose payment hashes in stub mode for easier invoice payment simulation during testing. Modifies test plan documentation to include the new automated script.
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 418bf6f8-212b-4bb0-a7a5-8231a061da4e
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 6f2776b0-a913-41d3-a988-759a82feb6f3
Replit-Helium-Checkpoint-Created: true
Rename an asset file and update its title in agent metadata.
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 418bf6f8-212b-4bb0-a7a5-8231a061da4e
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 158594e4-4fa2-40f1-9b6a-645eed86d4b7
Replit-Helium-Checkpoint-Created: true
Add research report to the project, creating a new markdown file and updating metadata.
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 418bf6f8-212b-4bb0-a7a5-8231a061da4e
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: a9eaa27a-395b-46bf-96d3-7d93423cb5d0
Replit-Helium-Checkpoint-Created: true