The player is the one tile that both reads and publishes, so it has two bindings: it shows a `record` describing what is playing — title, artist, album, status, and position and duration in seconds — and publishes transport words back to one `str` message (`toggle`, `next`, `prev`, `seek:<seconds>`). Those are a streamer's own vocabulary rather than this app's, which is what lets one tile drive whatever is on the other end. The position counts forward in the browser between readings, so the bar moves at one second while the device behind it is polled at whatever rate suits it; every reading that arrives is taken as the truth and the count restarts there. That is also why this is one record rather than five messages — a tile drawn from five would redraw itself five times, and show a new title against the old duration in between. Being both is why `INPUT_WIDGETS` does not gain it: what that set means is "the message this widget publishes is its only binding", which is exactly what a player is not. Its reading is checked the usual way and its `target` separately. The fader beside it needed nothing new. `ui/core` has had `orientation` on the slider all along and all three looks draw it; only the widget never passed it, so a volume control — the one thing reached for without looking, where up is louder — could not be a column. Now it can, and the tile's height is the track.
Fluksio App
Fluksio is a node-based automation software that brings trust and reliability to your flow. It just works and looks good.
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)
Layout
backend/ FastAPI + SQLModel + Alembic + SQLite
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
Get started quickly by running
pip install fluksio
fluksio serve
Then, head over to fluksio.com, sign up and add a new installation. Using the code provided, run
fluksio enroll <code>
and you're ready to rock.
Fluksio is distributed at it's heart. 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.
License
Copyright (C) 2026 Melvin Strobl - GNU Affero General Public License v3.0 or later. See LICENSE.