Files
enricobuehler 4ebe7d1185 fix(host): the plugin runner was located by FHS path only, so NixOS never found it
On NixOS every plugin PACKAGE op failed with "the plugin runner isn't
installed" on a box where the runner was installed, enabled and running.
`runner_command()` checked FHS locations exclusively — /usr/bin, the
/usr/lib + /usr/share pair behind it, and the ~/.local mirror the SteamOS
installer lays down. Nix ships punktfunk-scripting as a derivation of its
OWN, so its wrapper is neither beside the host binary nor anywhere under
/usr, and no rung could ever match. Service ops go through systemd and
were unaffected, which is what made it read as arbitrary: `plugins
status` said running/enabled while `plugins add` said not installed.

Resolution now matches punktfunk-encode-worker's: PUNKTFUNK_SCRIPTING ->
beside the host binary -> PATH -> /usr -> ~/.local. PATH is the rung Nix
lands on. The /usr rungs stay AFTER it rather than being dropped, because
a systemd unit's PATH need not include /usr/bin. As with the encode
worker the env override is deliberately not existence-checked — a named
path that is wrong should fail naming itself, not fall through to some
other runner. Lifted into a pure injected function so the whole table is
testable, which is also how the regression is pinned: removing the PATH
rung fails the NixOS row specifically.

Second half, and the reason the Rust change alone would not have fixed
the console: the NixOS module now puts the runner on the HOST UNIT's
`path`. The console installs plugins from inside the host service, whose
PATH is exactly that unit list — `environment.systemPackages` only ever
covered an operator's interactive shell. Without it the CLI would have
been fixed and the console would not. module-check.nix gains both the
positive and the negative assertion, so CI's `nix flake check --no-build`
holds the property.

The error text named only apt and SteamOS; it now names NixOS and the
override. The ~/.local/bin symlink workaround is no longer needed.
2026-08-13 20:27:26 +02:00
..

punktfunk-docs

The Punktfunk documentation site: Fumadocs on TanStack Start (Vite + Nitro/bun preset).

Content lives in content/docs/ as .md/.mdx. This site is the source of truth for the user-facing guides; design rationale lives in the internal punktfunk-planning repo.

API reference

/api renders the host's management REST API as an interactive Scalar reference (linked from the top nav, the docs sidebar, and the landing page). It reads public/openapi.json — a snapshot of the repo's generated spec. Refresh it after a management-API change:

# from the repo root — regenerate the spec, then copy the snapshot in:
cargo run -p punktfunk-host -- openapi > api/openapi.json
cp api/openapi.json docs-site/public/openapi.json

Nothing in CI diffs the two, so the snapshot goes stale silently — that manual cp is the only thing keeping them in sync. Before publishing docs, check that they match:

diff <(jq -S . api/openapi.json) <(jq -S . docs-site/public/openapi.json)

That should print nothing. Right now it doesn't: the committed snapshot predates the /api/v1/update/check, /api/v1/update/apply and /api/v1/update/status endpoints, so the published /api reference is missing the host self-update surface — re-copy it.

Develop

bun install
bun run dev        # http://localhost:3001  (docs at /docs)

CI gates every change on bun run build followed by bun run lint (the TypeScript typecheck), in that order — the build emits the .source typegen the typecheck imports. Run both before you push.

Build & serve

bun run build
bun run start      # serves .output/ via Bun

Layout

source.config.ts          Fumadocs MDX collection (content/docs)
content/docs/             the docs content (.md/.mdx) + meta.json nav
src/
  routes/
    __root.tsx            RootProvider + html shell
    index.tsx            landing page
    docs/$.tsx           catch-all docs renderer (Fumadocs DocsLayout)
    api/index.tsx        Scalar API reference (reads public/openapi.json)
    api/search.ts        Orama search endpoint
  lib/source.ts          Fumadocs loader over the generated collection
  lib/layout.shared.tsx  shared nav chrome
  components/mdx.tsx      MDX component map
  styles/app.css          Tailwind 4 + Fumadocs preset