Skip to content

Commands

Every command, two-shell where it applies. Run from the repo root unless noted. Full walkthroughs: §02 — Getting Started, §10 — Development Workflow, §14 — Deployment, §15 — Operations.

First run

git clone <repo-url>; cd Aetherium-core
dotnet --info          # expect 10.0.x
docker compose up -d    # Postgres + ChromaDB
docker ps
git clone <repo-url> && cd Aetherium-core
dotnet --info          # expect 10.0.x
docker compose up -d    # Postgres + ChromaDB
docker ps

The Engine listens on http://localhost:5257, which redirects to the web client at /app. Migrations apply automatically at startup. LM Studio is not started for you — load a model on :1234 first.

Build

dotnet build Aetherium_Refactor\Aetherium_Refactor.slnx
dotnet build Aetherium_Refactor/Aetherium_Refactor.slnx

Build the web client before publishing

dotnet build does not build Aetherium.Web, and .NET bakes its static-asset manifest at publish time — so bun run build must run before dotnet publish or the client silently is not in the output. scripts/deploy.sh does this in order.

Web client

cd Aetherium_Refactor\Aetherium.Web
bun install
bun run dev        # :5273, proxies /api to :5257
bun run build      # -> ..\Aetherium_Refactor\wwwroot\app
bun test ; bun run typecheck
cd Aetherium_Refactor/Aetherium.Web
bun install
bun run dev        # :5273, proxies /api to :5257
bun run build      # -> ../Aetherium_Refactor/wwwroot/app
bun test && bun run typecheck

Regenerate the API types after changing a controller:

scripts/generate-contract.sh     # server -> docs/contract/openapi.v1.json
bun run generate:api             # that -> src/api/schema.d.ts

Run / hot reload

dotnet run   --project Aetherium_Refactor\Aetherium_Refactor\Aetherium_Refactor.csproj
dotnet watch --project Aetherium_Refactor\Aetherium_Refactor\Aetherium_Refactor.csproj
dotnet run   --project Aetherium_Refactor/Aetherium_Refactor/Aetherium_Refactor.csproj
dotnet watch --project Aetherium_Refactor/Aetherium_Refactor/Aetherium_Refactor.csproj

Test

Two suites — the server's and the client's.

dotnet test Aetherium_Refactor\Aetherium_Refactor.Tests\Aetherium_Refactor.Tests.csproj
cd Aetherium_Refactor\Aetherium.Web ; bun test
dotnet test Aetherium_Refactor/Aetherium_Refactor.Tests/Aetherium_Refactor.Tests.csproj
(cd Aetherium_Refactor/Aetherium.Web && bun test)

EF migrations

Target the server .csproj (it is its own startup project — no --startup-project).

$p = "Aetherium_Refactor\Aetherium_Refactor\Aetherium_Refactor.csproj"
dotnet ef migrations add AddNotes --project $p
dotnet ef database update --project $p
dotnet ef database update PreviousMigrationName --project $p   # roll back
dotnet ef migrations remove --project $p                       # drop last un-applied
p=Aetherium_Refactor/Aetherium_Refactor/Aetherium_Refactor.csproj
dotnet ef migrations add AddNotes --project $p
dotnet ef database update --project $p
dotnet ef database update PreviousMigrationName --project $p   # roll back
dotnet ef migrations remove --project $p                       # drop last un-applied

Publish

Publish the .csproj, never the .slnx

dotnet publish against the .slnx builds every project but never runs the server's Publish target — no runnable output, no wwwroot/ (browser client 404s). build/watch work against either; publish must target the server .csproj.

dotnet publish Aetherium_Refactor\Aetherium_Refactor\Aetherium_Refactor.csproj -c Release -o publish-out
dotnet publish Aetherium_Refactor/Aetherium_Refactor/Aetherium_Refactor.csproj -c Release -o /tmp/aetherium-publish

Deploy (Linux · systemd)

Production runs on Linux under systemd; these are bash-only by design.

./scripts/deploy.sh --dry-run        # report, change nothing
./scripts/deploy.sh                  # deploy current commit
#   flags: --no-pull  --no-restart  --force(over dirty tree)

sudo systemctl daemon-reload
sudo systemctl enable --now aetherium.service
sudo systemctl status  aetherium.service
sudo systemctl restart aetherium.service
cat /opt/aetherium/deployed-commit.txt   # currently-deployed SHA

Roll back: git checkout <good-sha> && ./scripts/deploy.sh --no-pull.

Operations (Linux)

journalctl -u aetherium.service -f -n 0                              # follow from tail
journalctl -u aetherium.service -n 200 --no-pager | grep -iE "error|exception"
journalctl -u aetherium.service -f | grep "\[MODEL-ROUTING\]"        # one concern
curl -s http://localhost:5257/api/health                            # API + Postgres
curl -s http://localhost:5257/api/health/detailed | jq              # read the body

Data backup & restore (Linux)

# PostgreSQL
docker exec <postgres-container> pg_dump -U aetherium_user -d aetherium_refactor_db \
  --clean --if-exists --no-owner --no-privileges > aetherium-db-backup.sql
docker exec -i <postgres-container> psql -U aetherium_user -d aetherium_refactor_db < aetherium-db-backup.sql

# ChromaDB (stop-copy-start) + workspaces
docker stop <chroma-container>
tar czf chroma-backup.tar.gz -C /var/lib/aetherium chroma-data
docker start <chroma-container>
tar czf workspaces-backup.tar.gz -C /var/lib/aetherium workspaces

# Prune the unbounded audit table (no retention exists)
docker exec -i <postgres-container> psql -U aetherium_user -d aetherium_refactor_db <<'SQL'
DELETE FROM "ToolSecurityAuditEntries" WHERE "Timestamp" < NOW() - INTERVAL '90 days';
VACUUM (ANALYZE) "ToolSecurityAuditEntries";
SQL

Helper scripts

Script Purpose
start-aetherium-linux.sh Start the Engine (Linux); also brings up SearXNG
scripts/deploy.sh Deploy a Git commit to the running service
scripts/render-gpu-env.py Write each GPU unit's card-pin environment file from the Engine config (--validate and --check write nothing; deploy.sh runs it). --host NAME renders the units of the cards whose Host is NAME, --list-hosts prints each card Host, --export prints only the config sections it reads. A GPU service on a slot with no Card gets a file without a pin when no configured card is in this machine
scripts/gpu-node-units.sh The GPU-unit step of deploy.sh — pin files, leased GPU service units, llama-server routers — for the machine it runs on; deploy.sh runs it locally and, with --host, on each card Host over SSH
scripts/sync-chroma.{ps1,sh} · scripts/sync-db.{ps1,sh} Move ChromaDB / Postgres state between machines

Docs site (this documentation)

pip install -r requirements.txt   # first time
mkdocs serve                      # http://127.0.0.1:8765
mkdocs build                      # static site → _build/
pip install -r requirements.txt   # first time
mkdocs serve                      # http://127.0.0.1:8765
mkdocs build                      # static site → _build/