Skip to content

Getting started (technical)

Setup, running, testing, and client regeneration for fleet-mission-control. See ARCHITECTURE.md for how the pieces fit together and contributing.md for the branch/review workflow.

Prerequisites

Tool Version Used for
.NET SDK 10.0.x src/FleetMissionControl.Api, tests/
Node.js 24.x frontend/, extensions/vscode/
npm bundled with Node package management, NSwag client generation
D2 0.7.x (optional) regenerating docs/diagrams/*.svg

The API reads live fleet state from a shared OneDrive-backed directory tree (FleetPaths) and ~/.claude/usage-governor/state.json — those are optional for local dev; every reader degrades gracefully to empty/UNKNOWN when its source file is absent (see ARCHITECTURE.md for the exact fallback behavior of each reader).

Run it

# backend (terminal 1)
dotnet run --project src/FleetMissionControl.Api      # http://localhost:5170

# frontend (terminal 2)
cd frontend && npm ci && npx ng serve --proxy-config proxy.conf.json   # http://localhost:4200

The dev proxy (frontend/proxy.conf.json) forwards /api, /hubs (websocket), and /openapi to :5170 — open http://localhost:4200, not :5170, during frontend development.

Kestrel binds localhost plus any Tailscale (100.64.0.0/10) interface — see ARCHITECTURE.md §1. No LAN/public interface is ever bound.

Test

dotnet test                      # backend: xUnit, reader/parser/gate suites against temp dirs
cd frontend && npx ng test       # Angular/Karma-style runner
cd frontend && npm run test:vitest  # standalone vitest config — kept passing in lockstep with `ng test`;
                                     # this is the config the Stryker mutation job drives directly

Both frontend test stacks must stay green together — CI runs both independently precisely so they can't silently drift apart.

Client regeneration (do this after any backend contract change)

dotnet build src/FleetMissionControl.Api   # refreshes openapi/FleetMissionControl.Api.json
cd frontend && npm run generate:client     # rewrites src/app/api/fleet-api.generated.ts

Commit both regenerated files. CI runs two independent drift checks — a backend job diffs openapi/ after a clean build, and a frontend job runs npm run check:drift (regenerate + diff) — either one fails the build if you forget.

CI locally

Run the same checks the home-ci runners run before pushing:

dotnet build FleetMissionControl.slnx --no-restore -warnaserror
dotnet test FleetMissionControl.slnx --no-build

cd frontend
npx ng lint
npx ng build
npx ng test
npm run test:vitest
npm audit --omit=dev --audit-level=high

Mutation testing (dotnet tool run dotnet-stryker -- --config-file stryker-config.json backend, npm run test:mutation frontend) and the 5×-repeat flake gate are slow — CI runs them on every push/PR, but they're optional for a local inner loop. See ARCHITECTURE.md §13 for the full gate list.

Diagram regeneration

Mermaid diagrams live inline in the markdown under docs/technical/ and docs/plain/, with their sources mirrored under docs/diagrams/*.mmd for independent editing — GitHub renders Mermaid natively, no build step needed.

The two C4 diagrams are rendered to committed SVG via D2:

d2 docs/diagrams/c4-context.d2 docs/diagrams/c4-context.svg
d2 docs/diagrams/c4-container.d2 docs/diagrams/c4-container.svg

Regenerate both after any change to the system's external dependencies or its container boundaries.

IDE extensions

extensions/vscode/ and extensions/vs2026/ each embed the built cockpit bundle in a webview/WebView2 host and inject window.__FLEET_CONFIG__.apiBaseUrl to point it at a live API instance — see ARCHITECTURE.md §10. Building the frontend bundle first is a prerequisite for both:

cd frontend && npm ci && npm run build
cd extensions/vscode && npm ci && npm run package   # vsce package

extensions/vs2026/ builds via its own .csproj (FleetMissionControl.Vs2026.csproj) with dotnet build, not the main solution.