Both screens the house is looked at on are 1280x800, so that is what the three dashboards are laid out for: twelve columns of 96px, twelve rows of 51px, and nothing past the bottom, because a panel does not scroll. The motors are one control each instead of three buttons. A button could only publish; a segmented control reads back as well — so the motor writes what it is doing to the same message the control sets, and the segment that is held is the direction it actually went. Up, Stop, Down for the shutters; Close/Open for the window and In/Out for the awning, which is what those two are for. A run stopped part way now leaves the position unknown rather than claiming the target it never reached, so the next command in either direction moves it. The preflight gained the two checks this needed. One runs each sample shape past the port that would receive it. The other is arithmetic: every tile inside the panel and none on top of another — both silent failures on a screen with no scrollbar, and both caught before anything is written. Sizes were settled by looking. A slider needs three rows or its tick labels fall off; a status icon needs three or it loses the word under the glyph; a gauge in two rows has no arc worth reading, so the battery is a bar on Home and a gauge on Energy where there is height for one. A chart spends eighty pixels on its chrome whatever it is given, so two of them read on this panel and three did not — the temperature history is the one that went, and `history` still answers for it. `capture-panels.mjs` is how that was checked: the three panels at the screen's own pixels, in both themes, reporting whether anything spilled. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fluksio App
Fluksio has the goal to build a revolutionary system to tackle any sort of automation challenge.
The core of Fluksio: a node-based, test-driven automation software built to scale. This
repo holds the FastAPI backend, the flow engine, and the dashboard SPA. It is served on
app.${DOMAIN} (SPA) and api.${DOMAIN} (API); the marketing site lives in the sibling
index repo.
Layout
backend/ FastAPI + SQLModel + Alembic + SQLite — the `fluksio` distribution
fluksio/flow/ the flow engine (nodes, pipeline, state backends, controller)
fluksio/cli.py `fluksio serve` / `enroll` / `worker`
worker/ the `fluksio-worker` distribution: the agent and the node runner
frontend/ React 19 + TanStack Router + Tailwind 4 + shadcn/ui
docs/ the public documentation site (zensical), served on docs.${DOMAIN}
docker/ compose.yml → compose.dev.yml → compose.local.yml (+ compose.traefik.yml)
scripts/ generate-client.sh, test.sh
Install without Docker
pip install fluksio
fluksio serve # ~/.fluksio, SQLite, prints an admin password once
fluksio enroll <code> --portal https://hub.fluksio.com # watch it from the portal
Nothing else has to be running. --data-dir puts the installation somewhere else —
worth it on a cluster, where $HOME is often a network filesystem SQLite cannot use.
git is not required but is worth having: flows are files either way, and it is what
turns each save into a commit.
The dashboard is served by the portal, so a machine with no inbound route is reached
without opening a port: it dials out.
A machine that should only run nodes for an engine elsewhere installs less:
pip install fluksio-worker
fluksio-worker --url wss://api.example.com/api/v1/workers/attach --token "$TOKEN" --labels gpu
Getting started
Normally driven from the workspace root (make init once, then make dev). Standalone:
make install # uv sync + bun install
make dev-utils # proxy and mailcatcher only
make dev-backend # FastAPI on :8000, hot reload
make dev-frontend # Vite on :5173
make test # pytest + Playwright (the e2e half needs the stack up)
make lint # ruff + mypy + biome
make generate-client # regenerate the frontend SDK from the OpenAPI schema
make help lists every target.
Documentation
The public site lives in docs/ and is built with zensical:
make docs-serve # live preview on :8000
make docs # static build into ./site
It is served at docs.${DOMAIN} by the docs service in docker/compose.yml,
and .gitea/workflows/docs.yml builds it with --strict on every push. Style
follows the root DESIGN-GUIDELINES.md; the tokens are mirrored in
docs/stylesheets/extra.css.
Repo-only material:
ROADMAP.md— strategy and feature recordNOTEPAD.md— deferred work and findingsDESIGN.md— points at the workspace root'sDESIGN-GUIDELINES.mddocs/architecture/in the siblingdocsrepo — the requirement sources