Storing doc_lang on the document row is not enough on its own. The editor sees that row when the document is opened or saved, and the pass that decides the verdict runs after a save — so the client was always one save behind, and read-aloud is reached for precisely when she has stopped typing and no further save is coming. Heard in a browser: a Portuguese paragraph read in an American voice, twice, until another keystroke went in. /check, /voice and /collocation now answer with X-Petal-Doc-Lang. A header rather than a wider body: all three answer with a bare array of the unified pending set and every caller reads it as one, and a verdict is metadata about the pass rather than another suggestion. It reaches the app through the same handler shape onUnauthorized already uses. Claude-Session: https://claude.ai/code/session_01GJHNvirh7Hzhc9RL3HAvz7
🌸 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.