`widgets.spec.ts` took a one-shot `boundingBox()` of a fill that is still moving. Two ways that reads wrong. "a bar draws a row per reading" compared two widths that are both zero until the socket has delivered the readings, and a plain `expect` over a captured number does not retry. "a reading over its scale fills the track and no more" allowed the fill one pixel past the track, but the house spring is underdamped: `motion`'s own generator puts the fluksio look at 100.66% of the track 276ms in (material 100.91%, glass 103.58%), which on this tile's ~240px track is ~1.6px — over the tolerance, and reached only if the sample happens to land near the peak. Neither is the widget. `fractionOf` clamps the reading to [0, 1] and `.dui-bar-track` is `overflow: hidden`, so nothing past a full track is ever drawn; a bounding box just is not clipped by an ancestor's overflow. So both now poll: one until the shorter reading is drawn shorter, the other until the fill is flush with its track — which is a stricter reading of "and no more" than the pixel of slack was. The live-socket test gains the other half of what that spin cost: an ASGI task that never returns is one uvicorn's graceful shutdown waits on forever, which is why `fluksio serve` could only be SIGKILLed and left `serve.pid` behind.
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 instance. 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.fluksio.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.