self 4af3da56cc fix: remove duplicate resource supervisor subscription
Keep store-to-supervisor wiring owned by EngineOps so state changes only schedule one reactive sync wave.
2026-06-13 03:23:15 +02:00
2026-06-13 03:12:07 +02:00
2026-06-08 19:54:05 +02:00
2026-03-15 22:23:54 +01:00
2026-06-12 19:30:32 +02:00
2026-05-29 14:39:18 +02:00
2026-06-01 22:51:02 +02:00
2026-06-06 15:19:06 +02:00
2026-05-24 19:53:08 +02:00
2026-03-20 15:41:40 +01:00
2026-04-09 20:01:17 +02:00
2026-05-24 16:25:49 +02:00
2026-04-09 20:01:17 +02:00
2026-06-12 13:32:45 +02:00
2026-04-09 20:01:17 +02:00

Legion Kommando & Kontrolle

Cloud provisioning for Tribes nodes, an Electron application with Svelte and TypeScript

Project Setup

Install dependencies

$ npm install

Run the app

$ npm run dev
$ VITE_LOCALE=de-DE npm run dev # Force UI language

Optional XState tracing

For local actor debugging, you can enable a dev-only XState trace log:

$ LEGION_TRACE_XSTATE=1 npm run dev

When enabled, the main process writes a JSONL trace file under the Electron user data logs directory and prints the full path once on startup. This is local-only and intended for development debugging of actor events, actions, and state transitions.

Run the CLI in development

Use the repo-local wrapper:

$ ./bin/legion-dev node list
$ ./bin/legion-dev provider configure hetzner --api-key-env HCLOUD_TOKEN
$ ./bin/legion-dev node create --name node-a --provider hetzner --region fsn1 --instance cax11
$ ./bin/legion-dev apply

Or via npm:

$ npm run cli -- node list

Quality checks

$ npm run precommit
$ npm run lint
$ npm run format:check
$ npm test
$ npm run check

Credentialed integration and E2E runs are documented in TESTING.md.

Architecture notes

For the current runtime layout, daemon security posture, GUI boundary, XState actors, and recovery loops, see docs/arch.md.

Refresh the pinned Guix base channel

When ../guix-fork changes, refresh the Guix pin in ../guix-tribes first:

$ (cd ../guix-tribes && ./scripts/update-base-channels-pin)
$ npm run generate:guix-base-channel

Use ../guix-tribes/scripts/update-base-channels-pin --official when switching back to the mirrored official Guix channel.

Refresh the default kexec installer

The default kexec installer image is built and published by the Guix mirror builder from the kexec-installer branch in guix-tribes. After changing the installer definition or pinned Guix channels, move that branch to the desired signed guix-tribes commit so the mirror builder can publish tribes-1/guix-kexec-installer-<system>-<commit>.tar.gz.

After the mirror publishes the matching .sha256, refresh Legion's generated pin:

$ npm run update:kexec-installer-pin

Regenerate OpenAPI clients

$ npm run update:hcloud-client
$ npm run update:serverspace-client

Refresh bundled data

npm run update:provider-catalogs reads provider credentials from the environment:

# Hetzner
export HCLOUD_TOKEN=...
# or
export HETZNER_API_TOKEN=...

# OVH
export OVH_APP_KEY=...
export OVH_APP_SECRET=...
export OVH_CONSUMER_KEY=...
# optional, defaults to ovh-eu
export OVH_ENDPOINT=ovh-eu

# Scaleway
export SCW_ACCESS_KEY=...
export SCW_SECRET_KEY=...
export SCW_DEFAULT_PROJECT_ID=...
# optional, defaults to fr-par-1
export SCW_DEFAULT_ZONE=fr-par-1
$ npm run update:provider-catalogs

When you enter the devenv shell, pre-commit hooks are generated from devenv.nix and run the same npm-based lint and format checks before commit.

Build installers

# For windows
$ npm run build:win

# For macOS
$ npm run build:mac

# For Linux
$ npm run build:linux
S
Description
Legion Kommando & Kontrolle TS/Svelte/Electron App with CLI
Readme 89 MiB
Languages
TypeScript 94%
Svelte 5.2%
CSS 0.2%
Scheme 0.2%
Shell 0.2%
Other 0.1%