Skip to content

The Build Loop

Every stk command lives under stk. Run stk --help to see them grouped by purpose.

Terminal window
uv run stk --help

Prefer bare stk? Activate the venv once per shell:

Terminal window
source .venv/bin/activate
stk run
Terminal window
uv run stk doctor
✓ env file .env
✓ secrets SECRET_KEY and password salt look random
✓ database sqlite stk.db (124 KiB)
! migrations database at 20261006_0001, head is 20261006_0002
→ uv run stk db upgrade
✓ admin user 1 admin(s)
✓ assets vue 3.5.40 vuetify 4.1.6
✓ agent login disabled
✓ browser chromium ready for stk smoke
✓ shell ptpython: highlighting and completion
Usable, with the warnings above.

Every line that is not ✓ tells you the command that fixes it. A ! is a warning, a ✗ is a failure, and the exit code is 1 only on a failure, so it works in scripts. --json for tooling.

Terminal window
uv run stk new invoice

NAME is a lowercase snake_case identifier. This writes the blueprint package (model and views) and its template, registers it in app.py, adds a sidebar entry to navigation.js, generates the migration for the new model, applies it, and then tells you where to look:

Open: http://localhost:5000/invoices/ (start it with: stk run)

Pass --no-migrate if you would rather write the migration yourself, and --port if your dev server is not on 5000.

Terminal window
uv run stk verify --watch

It checks everything once, then polls for saved files and re-runs only what the change can break. A .py edit re-runs ruff, the sanity checks, and migration drift; a template, JS, or CSS edit re-runs only the sanity checks.

changed: stk/invoice/models.py
✗ migration-drift
add_column: invoice due_date
→ uv run stk db revision -m "describe change" && uv run stk db upgrade
✓ ruff
✓ checks

Leave it in a split pane. You find out the moment you break something, not ten minutes later, and the fix is on screen.

Terminal window
uv run stk smoke

Boots a throwaway app on a free port against a temporary database, drives Chromium through the home page, login, dashboard, and admin users page, then visits every other GET page that takes no URL arguments. It fails on any of: an HTTP status of 400 or above, a console or uncaught error, a failed request, or button, chip, and alert text below 3:1 contrast with its background. That last one catches the class of bug no console error ever reports. The dashboard screenshot lands in .stk/smoke/dashboard.png; --json emits the per-page report.

Smoke needs Playwright’s Chromium. stk doctor tells you if it is missing.

Terminal window
uv run stk verify && uv run stk smoke
uv run stk report # docs/stk-report.html: routes, auth, gate results

stk verify runs ruff, checks.py, and migration drift, and exits 1 if any fail. CI runs both stk verify --json and stk smoke --json (after the unit tests), so the pair above is the same gate locally. stk report --json prints the routes and verify results instead of writing HTML, and -o picks another output path.

Terminal window
uv run stk doctor # am I ready?
uv run stk new invoice # scaffold to a clickable URL
uv run stk verify --watch # instant feedback while editing
uv run stk smoke # real browser before shipping