Add web UI with Smokey's crow as the stand-in mascot

- ui/: Vite + plain TypeScript, builds into ./web for `crows serve`
- CrowView mirrors CrowModel in RIVE_CONTRACT.md (pose, trust,
  reactions) so the .riv can replace the SVG later
- Event handling follows the contract's mapping table; server text
  is only ever inserted as text
- Prank: toast plus a send-button cooldown countdown
- art/crow.svg: source art for Rive import

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UQnSw4RRWp8uqpj3nsnnXF
This commit is contained in:
SmokeyandClaude Opus 5.5 committed 2026-10-27 11:44:54 -06:00
1 parent 940c74672a
commit a89157803b
12 files changed
+1796

No files matched your search

+2
View File
@@ -19,6 +19,7 @@ Optional: `CROWS_MODEL` overrides the model. Results land in `todo.crows.md`; st
## Web server
```
cd ui && npm install && npm run build && cd .. # builds the UI into ./web
./crows serve # localhost:8080; API + Server-Sent Events (SSE); Ctrl-C to stop
```
@@ -34,6 +35,7 @@ curl localhost:8080/api/trust
- Item IDs are `<list_id>-<n>`, numbered from 1 in list order.
- Approvals left unanswered for 10 minutes count as rejected (`verdict: timeout`). `-approval-timeout` changes this for testing.
- A flooding requester gets 429 with `message` and `cooldown_s`; any list of theirs that is still flying also gets `requester.pranked`.
- UI development: run `crows serve`, then `cd ui && npm run dev` (Vite proxies `/api`). The crow art is `art/crow.svg`; the UI's `CrowView` mirrors `RIVE_CONTRACT.md`, so a Rive-backed view replaces the SVG stand-in later.
- POST bodies are capped at 64 KB. Static files are served from `./web` when that folder exists.
## How an item flies