########### # justfile ########### # Defaults default: @just --list default_instance := env_var_or_default("INSTANCE", "default") default_matrix := env_var_or_default("MATRIX", "tuwunel") ################################### # Local: Matrix dev stack (Compose) ################################### # Start Matrix + DB dev stack (Compose) local-matrix-up: cd local/matrix && docker compose up -d # Stop Matrix + DB dev stack local-matrix-down: cd local/matrix && docker compose down # Tail logs for Matrix + DB stack local-matrix-logs: cd local/matrix && docker compose logs -f # Reset local Matrix volumes, selected runtime Matrix state, and repository tmp/ local-matrix-reset: #!/usr/bin/env bash set -euo pipefail (cd local/matrix && docker compose down -v) uv run python - <<'PY' import shutil from mindroom.constants import encryption_keys_dir, matrix_state_file, resolve_runtime_paths, tracking_dir paths = resolve_runtime_paths() # The new homeserver knows none of the accounts, devices, and events this state is bound to. matrix_state_file(paths).unlink(missing_ok=True) for directory in (encryption_keys_dir(paths), paths.storage_root / "sync_continuity"): if directory.exists(): shutil.rmtree(directory) tracking = tracking_dir(paths) for journal in tracking.glob("event_journal*"): journal.unlink() for record in [*tracking.rglob("invited_rooms.json"), *tracking.rglob("pending_room_invites.json")]: record.unlink() for personal_rooms in list(tracking.rglob("personal_rooms")): shutil.rmtree(personal_rooms) # Releases up to v2026.10.37 kept these records in agents//, and startup would move them below tracking/. # Tool code can write agents/, so only agents// is removed and no link is followed. agents = paths.storage_root / "agents" for agent in sorted(agents.iterdir()) if agents.is_dir() and not agents.is_symlink() else []: if agent.is_symlink() or not agent.is_dir(): continue for name in ("invited_rooms.json", "pending_room_invites.json", "personal_rooms"): record = agent / name if record.is_dir() and not record.is_symlink(): shutil.rmtree(record) elif record.is_symlink() or record.exists(): record.unlink() PY rm -rf tmp/ echo "✅ Reset complete! Run 'just local-matrix-up' then 'mindroom run' to start fresh." ######################################### # Local: Instances orchestration (Compose) ######################################### # Create a local instance (Compose) local-instances-create instance=default_instance matrix=default_matrix: #!/usr/bin/env bash if [ "{{matrix}}" = "none" ]; then cd local/instances/deploy && ./deploy.py create {{instance}} else cd local/instances/deploy && ./deploy.py create {{instance}} --matrix {{matrix}} fi # Start a local instance local-instances-start instance=default_instance: cd local/instances/deploy && ./deploy.py start {{instance}} # Start only the Matrix side of a local instance local-instances-start-matrix instance=default_instance: cd local/instances/deploy && ./deploy.py start {{instance}} --only-matrix # Stop a local instance local-instances-stop instance=default_instance: cd local/instances/deploy && ./deploy.py stop {{instance}} # Remove a local instance (containers + data) local-instances-remove instance=default_instance: cd local/instances/deploy && ./deploy.py remove {{instance}} --force # List local instances local-instances-list: cd local/instances/deploy && ./deploy.py list # Tail logs for a local instance local-instances-logs instance=default_instance: cd local/instances/deploy && docker compose -p {{instance}} logs -f # Shell into the local MindRoom container for an instance local-instances-shell instance=default_instance: cd local/instances/deploy && docker compose -p {{instance}} exec mindroom bash # Remove ALL local instances (containers + data) local-instances-reset: cd local/instances/deploy && ./deploy.py remove --all --force ######################################## # Local: Platform dev stack (Compose) ######################################## # Start SaaS platform Compose stack (local) local-platform-compose-up: cd saas-platform && docker compose up -d # Stop SaaS platform Compose stack (local) local-platform-compose-down: cd saas-platform && docker compose down # Tail logs for SaaS platform Compose stack (local) local-platform-compose-logs: cd saas-platform && docker compose logs -f # ------------------------ # Development / CI helpers # ------------------------ # Export SaaS backend OpenAPI schema and regenerate frontend API types saas-openapi: cd saas-platform/platform-backend && uv run python scripts/export_openapi.py cd saas-platform/platform-frontend && bun install && bun run generate:api ################################ # Cluster: Terraform / Helm / DB ################################ # Helm # Render Helm manifests for platform chart (optional kubeconform validation) cluster-helm-template: #!/usr/bin/env bash set -euo pipefail if command -v kubeconform >/dev/null 2>&1; then helm template platform ./cluster/k8s/platform -f cluster/k8s/platform/values.yaml | kubeconform -ignore-missing-schemas else echo "[warn] kubeconform not found; rendering manifests without validation" >&2 helm template platform ./cluster/k8s/platform -f cluster/k8s/platform/values.yaml fi # Lint platform chart (Helm) cluster-helm-lint: helm lint ./cluster/k8s/platform # Terraform cluster-tf-up: bash cluster/terraform/terraform-k8s/scripts/up.sh cluster-tf-build-snapshots: bash cluster/terraform/terraform-k8s/scripts/build_snapshots.sh # Show Terraform outputs and cluster status cluster-tf-status: bash cluster/terraform/terraform-k8s/scripts/status.sh # Destroy platform + cluster (Terraform) cluster-tf-destroy: bash cluster/terraform/terraform-k8s/scripts/destroy.sh # Set up Terraform state symlinks (one-time setup for new clones) cluster-tf-state-setup: bash cluster/scripts/setup-terraform-state.sh # Backup Supabase database (requires env in saas-platform/.env) cluster-db-backup: bash cluster/scripts/db/backup_supabase.sh ############################ # Cluster: Local kind setup # ############################ # Create kind cluster with ingress (local) via Nix shell cluster-kind-up: nix-shell cluster/k8s/kind/shell.nix --run 'bash cluster/k8s/kind/up.sh' # Build images and load into kind (avoids registry pulls) via Nix shell cluster-kind-build-load: nix-shell cluster/k8s/kind/shell.nix --run 'env DOCKER_BUILDKIT=1 bash cluster/k8s/kind/build_load_images.sh' # Install platform Helm chart into kind via Nix shell cluster-kind-install-platform: nix-shell cluster/k8s/kind/shell.nix --run 'bash cluster/k8s/kind/install_platform.sh' # Port-forward backend service (kind) via Nix shell cluster-kind-port-backend: nix-shell cluster/k8s/kind/shell.nix --run 'kubectl -n mindroom-staging port-forward svc/platform-backend 8000:8000' # Port-forward frontend service (kind) via Nix shell cluster-kind-port-frontend: nix-shell cluster/k8s/kind/shell.nix --run 'kubectl -n mindroom-staging port-forward svc/platform-frontend 3000:3000' # Tear down kind cluster via Nix shell cluster-kind-down: nix-shell cluster/k8s/kind/shell.nix --run 'bash cluster/k8s/kind/down.sh' # One-shot: fresh kind up + build+load + install cluster-kind-fresh: nix-shell cluster/k8s/kind/shell.nix --run 'bash cluster/k8s/kind/start-fresh.sh' ################# # Env helpers # ################# # Print exported env vars from saas-platform/.env (for eval) env-saas: #!/usr/bin/env bash set -euo pipefail uvx --from python-dotenv[cli] dotenv -f saas-platform/.env list --format shell ############ # Test runs # ############ # SaaS platform backend tests # Run SaaS platform backend tests with optional arguments test-saas-backend *args: cd saas-platform/platform-backend && uv run pytest {{args}} # Run SaaS platform backend tests with a terminal coverage report test-saas-backend-coverage *args: cd saas-platform/platform-backend && uv run pytest --cov=backend --cov-report=term-missing {{ args }} # Run SaaS platform frontend tests (Jest) test-saas-frontend: cd saas-platform/platform-frontend && bun install && bun run test # Core frontend tests (vitest) # Run core frontend tests (vitest) test-front: cd frontend && bun install && bun run test --run # Core backend tests (pytest in repo) # Run core backend tests (pytest) with optional arguments test-backend *args: uv sync --all-extras uv run --all-extras pytest {{args}} # Run core backend tests with a terminal coverage report test-backend-coverage *args: uv sync --all-extras uv run --all-extras pytest --cov=mindroom --cov-report=term-missing {{ args }} # Run the standard cross-platform test suites with dependency preflight and fail-fast behavior test-standard: ./run-tests.sh # Boots a disposable Tuwunel, a deterministic model stub, and this worktree's # MindRoom, then restarts MindRoom mid-turn around forty times. Needs Docker, # free ports, and a mostly idle machine for 30-60 minutes. Deliberately not in # CI; scripts/README.md explains why and says what a pass has to show. # Live pre-merge gate for Matrix ingress, journal, dispatch, and shutdown changes test-live-journal-gate *args: uv run python scripts/testing/fuzz_live_matrix.py --seed 42 --steps 200 --threads 45 --restart-interval 5 {{args}} uv run python scripts/testing/fuzz_live_matrix.py --profile restart-regression {{args}} # Opt-in Docker minimal-mode smoke; use a built worker image and a persistent evidence directory test-minimal-agent-worker-smoke image evidence_dir: uv run python -m tests.manual.minimal_agent_worker_smoke --image {{quote(image)}} --evidence-dir {{quote(evidence_dir)}} # Check for public symbols that should be private check-module-privacy: uv run privata --methods . ############################# # Developer-friendly aliases ############################# # Docker builds (local) # Build the core MindRoom runtime image (bot + dashboard + APIs) docker-build-mindroom: docker build -t mindroom:dev -f local/instances/deploy/Dockerfile.mindroom . # Build SaaS platform frontend (Next.js standalone) docker-build-saas-frontend: docker build -t platform-frontend:dev -f saas-platform/Dockerfile.platform-frontend . # Build SaaS platform backend (FastAPI) docker-build-saas-backend: docker build -t platform-backend:dev -f saas-platform/Dockerfile.platform-backend . # Core MindRoom dev # Start core MindRoom frontend (dev) start-frontend-dev: cd frontend && bun install && bun run dev -- --host 0.0.0.0 --port 3003 # Start core MindRoom runtime (dev) start-mindroom-dev: uv run mindroom run # SaaS Platform app dev # Start SaaS platform frontend (dev) start-saas-frontend-dev: cd saas-platform/platform-frontend && bun install && bun dev # Start SaaS platform backend (dev) start-saas-backend-dev: cd saas-platform/platform-backend && uv run uvicorn main:app --host 0.0.0.0 --port 8000 --reload ############################# # Documentation ############################# # Build documentation doc-build: uv run zensical build # Serve documentation locally (with live reload) doc-serve: uv run zensical serve # Update auto-generated documentation doc-update: uv run python docs/run_markdown_code_runner.py