The overlap hook only watched .petal-rail-card, so the History and Garden
drawers still sat under the mascot — with a real control ("写作证明 ·
Writing passport") buried under the halo on the live build.
Match [role="dialog"][aria-modal="true"] as well. Both drawers already
render it, so this covers them and any future drawer without a selector
list to keep in sync.
Two things the follow-up note didn't anticipate:
- The hook now reports { cards, modal } separately. A card overlap still
lets the kitten wake for a bubble; a modal overlap yields
unconditionally — a cheer isn't worth covering the panel she just
opened on purpose.
- The speech bubble is its own layer, so fading the badge didn't hide it.
Hold it back while a panel is open; useCompanion keeps it in state, so
it reappears when she closes the panel.
Also guard the poll's setState on value equality, so the 500 ms tick
stops re-rendering the companion for an unchanged answer.
UX_REVIEW item 1 (redo does not re-apply an accepted suggestion) is
recorded as NOT REPRODUCIBLE. Read the prosemirror-history state directly
and hooked view.dispatch: redo works pressed immediately, after an 18 s
pause that lets a full re-check land, and with the editor never focused.
The doc's hypothesis is false — every re-check transaction is
decoration-only, which prosemirror-history ignores, and canRedo stayed
true throughout. Two real findings from that dig are written into the doc
instead: keyboard undo dies when focus isn't in the editor, and an undone
suggestion stays accepted server-side so its card doesn't reliably return.
Item 5's premise is also partly wrong and now re-scoped: the Chinese
sentence does produce a card with an English rendering, just labeled
Clarity rather than a first-class Translate type.
Claude-Session: https://claude.ai/code/session_016y6gyuHkQXPiEuW8RGQyua
🌸 Petal
A self-hosted, privacy-first writing editor with warm bubbly design, auto-save, and
local-LLM grammar/ESL suggestions. See petal-spec.md for the full
design spec and BUILD_PLAN.md for build progress.
Stack
Go + chi backend · SQLite (modernc, pure Go) · React + Vite + Tiptap + Tailwind v4 frontend ·
local vLLM/Ollama for AI suggestions. Single-binary deployment (frontend embedded via go:embed).
Local development
Two processes during development:
# 1. Backend (serves /api on :8080)
go run ./cmd/server
# 2. Frontend dev server (HMR on :5173, proxies /api → :8080)
cd web && npm install && npm run dev
Open http://localhost:5173 while developing.
Production build (single binary)
cd web && npm run build # emits web/dist (embedded by the Go binary)
cd .. && go build -o petal ./cmd/server
./petal # serves UI + API on :8080
Configuration is via environment variables — copy .env.example to .env.
Deployment
docker compose up -d --build # petal + the two Piper read-aloud sidecars
Behind Traefik on the parodia.dev VPS; vLLM stays on millenia over headscale.
Full runbook — first deploy, the LLM link, backups and restore — in
deploy/README.md.
Status
Early build, multi-session. Auth (Authentik OIDC) is next; Copyleaks plagiarism is
still parked — see BUILD_PLAN.md.