Skip to content

Dev setup & the gate

Setting up a dev environment and passing the monorepo gate before you push. This page mirrors CONTRIBUTING.md at the repo root — that file is the source of truth if the two ever drift.

Setup

Host prerequisites: Docker and fvm (Flutter Version Management — manages the pinned Flutter SDK in .fvmrc).

fvm install
./jarvis up
cd app && fvm flutter run

./jarvis up builds and starts the whole backend stack, seeds demo data, and prints the PocketBase admin URL and the dev-user credentials. fvm flutter run then runs the app against http://localhost:8091. Run ./jarvis doctor if anything looks off, and ./jarvis reset for a clean slate — see Operating → The jarvis CLI for the full verb reference.

Python suites don't need the stack running. Each suite runs under its own PYTHONPATH with python3 -m pytest — see the gate below for the exact invocations.

The monorepo gate

This is the exact set of commands CI runs. Run all of it, from the repo root, before opening a PR.

Flutter (per package, via fvm)

(cd core && fvm flutter pub get && fvm dart format --output=none --set-exit-if-changed . && fvm flutter analyze --fatal-infos --fatal-warnings && fvm flutter test)
(cd modules/vitals && fvm flutter pub get && fvm dart format --output=none --set-exit-if-changed . && fvm flutter analyze --fatal-infos --fatal-warnings && fvm flutter test)
(cd modules/sample && fvm flutter pub get && fvm dart format --output=none --set-exit-if-changed . && fvm flutter analyze --fatal-infos --fatal-warnings && fvm flutter test)
(cd app && fvm flutter pub get && fvm dart format --output=none --set-exit-if-changed . && fvm flutter analyze --fatal-infos --fatal-warnings && fvm flutter test)

Each package gets the same four steps: pub get, a format check (fails the build if anything isn't already formatted), flutter analyze with both infos and warnings promoted to errors, then flutter test.

Python

PYTHONPATH=agent-runtime/src python3 -m pytest agent-runtime/tests -q
PYTHONPATH=agent-runtime/src:modules/vitals/agent python3 -m pytest modules/vitals/agent/tests -q
PYTHONPATH=agent-runtime/src:core/agent python3 -m pytest core/agent/tests -q
PYTHONPATH=cli/src python3 -m pytest cli/tests -q
python3 -m pytest tools/checks -q

Every module-agent and core/agent suite is run with the agent-runtime framework (agent-runtime/src) on PYTHONPATH alongside its own package, so it can import both jarvis_agent/jarvis_platform and its own agent code.

Expected counts as of S7

Flutter — core 67, vitals 51, sample 1, app 4. Python — agent-runtime 46, vitals-agent 21, core-agent 6, cli 28, tools/checks 20. Counts drift as slices land; treat them as a sanity check, not a contract.

Two environmental Docker contract-test errors

If you see 2 Docker contract errors under tools/checks, that's environmental — it happens when the local dev stack (./jarvis up) is already running and its container names conflict with the contract test's own docker compose up. Stop the stack first, or ignore those 2 if you know why they're there. See Troubleshooting if this doesn't match what you're seeing.

What CI runs

The flutter job runs this same gate across every package by discovering every pubspec.yaml in the repo (a glob, not a hardcoded list); the backend job runs every Python suite the same way. Adding a module needs no CI edit — as long as it follows the module layout (see Authoring a module), both jobs pick it up automatically.

Conventions

  • Commit messages: Conventional Commits (feat: ..., fix: ..., docs: ..., test: ..., ci: ..., etc.).
  • One slice/feature per PR. Keep PRs scoped to a single slice or feature. Never commit directly to main — all work lands via PR.
  • Branch naming: feat/<short-description>, fix/<short-description> (and similarly docs/..., ci/..., test/... as needed).
  • Adding a module never modifies the core. This is a hard invariant — see Authoring a module and Architecture for how the registry-in-app layering and codegen enforce it structurally, not just by convention.