Skip to main content

Developer tooling

The repository uses mise to provide project tools and named tasks. Install mise, then run:

mise install --locked

Tool versions​

The root, packages/client, and packages/server mise.toml files declare the tools, and each mise.lock pins the exact version and download for every platform, so installs stay reproducible until a lock changes. Tools are requested as latest (Node as lts). The server's Elixir and Erlang are the exception: they stay pinned to match the production image in packages/server/Dockerfile, and change together with it.

mise run lock keeps the locked versions and only refreshes platform entries. To upgrade tools, run mise run lock --bump, review the version changes in the lock diffs, and commit them. To add a tool, add it to the right mise.toml as latest and run mise run lock.

Commands​

Use the same commands locally and in automation; every task is listed in the Tooling Reference.

mise run check
mise run fix
mise run docs:serve
mise run deploy:dev -- up --clients 2

check is read-only and runs every hk step; fix applies the deterministic fixes. For example, Go module tidiness uses go mod tidy -diff in check and repairs the module files in fix. The pre-commit hook runs the same steps on staged files and may fix them while safely stashing unrelated unstaged work.

Running tests​

  • Server: from packages/server, run mise x -- mix test. DB-backed tasks start a local PostgreSQL container through mix db.ensure when nothing is listening on the configured port; set NIXSTASIS_DB_AUTOSTART=false to use your own database. mix precommit compiles with warnings as errors, prunes unused lock entries, formats, and tests.
  • Client: from packages/client, run mise run test for the race-detected suite with coverage, or mise x -- go test ./... for a quick run. TestRealSSHDIntegration needs a root-owned helper path, so CI runs with -tags no_sshd_integration. mise run test:packaging checks the native packaging contracts and needs Linux.
  • SSH integration: test/nixstasis/devices/ssh_client_integration_test.exs runs the real OpenSSH client against a local Erlang SSH daemon and is skipped unless ssh, ssh-keygen, and nc are on PATH.
  • Ash resources: after changing them, run mise x -- mix ash.codegen --check and follow the codegen rules in AGENTS.md.
  • Deployment contracts: see Local Stack.

The optional LiveDebugger dependency is compiled only when explicitly enabled, as described in packages/server/README.md, so the warnings-as-errors compile uses --no-optional-deps.

Documentation site​

The site is built with Docusaurus from website/, and the pages live in website/docs/. Where pages go, and how to write them, is covered in Documentation Conventions.

  • Navigation is defined in website/sidebars.ts. Add every new page there.
  • Page format: .md pages are plain CommonMark, so braces and angle brackets need no escaping. Use .mdx only when a page needs React components. Mermaid code fences render as diagrams.
  • Styling: the shared color and font tokens are in site/brand.css, and the Docusaurus theme maps onto them in website/src/css/custom.css. website/src/clientModules/index.ts loads the self-hosted fonts and adds the Expand button on diagrams.
  • API pages are generated during the build from website/docs/reference/openapi/*.yaml into website/docs/reference/api/, which Git ignores.
  • The build fails on any broken link, anchor, or image.
  • Dependencies install from website/package-lock.json with npm ci. The docs hk step rebuilds the site whenever documentation or site files change.
  • Base URL: the docs build for /nixstasis/docs/, because the product page owns the Pages root.

Product page​

The product page at the Pages root is plain HTML, CSS, and JavaScript in site/, with no build step. It uses the docs' logo, fonts, and site/brand.css tokens, and its color mode toggle shares the docs' theme localStorage key and html[data-theme] attribute, so a choice made on either carries to the other.

mise run site:build assembles both into _site/nixstasis, copying the fonts from the docs' npm packages. mise run site:serve builds and serves that folder at http://127.0.0.1:3000/nixstasis/, the same path as on GitHub Pages. Every claim on the page must match the code and the docs.

Commit messages​

The commit-message hook enforces Conventional Commits, a scope on changelog-visible changes, 72-character subjects, 100-character body lines, and the optional canonical Beads: footer. Preview the user-facing changelog with cog changelog. If the typo checker flags devlop in a lock file, leave it: that is the real name of an npm package.

GitHub validation​

.github/workflows/validate.yml runs on every pull request and is called by the Release workflow. It isolates user-global mise configuration, installs only the committed lock with mise install --locked, runs mise run check, and runs the server and client test suites. CI does not regenerate the lock or maintain a separate validation policy.

Hooks and lock updates​

mise install --locked installs the locked tools, and the postinstall hook in mise.toml then installs the repository-local hk hooks. Rerun it to restore tooling after an offline or interrupted setup. In a repository initialized with Git after the tools were installed, run hk install --mise once.

After changing a tool in any mise.toml, regenerate every lock for the supported platforms and commit them:

mise run lock