Codenest is a desktop app for running and supervising AI agent teams: a Tauri 2 (Rust)
shell hosting a React/TypeScript frontend, with a FastAPI (Python) sidecar owning all state in
SQLite. Embedded terminals run real claude sessions; the app tracks their tasks, telemetry,
schedules, and MCP configuration. The stack is cross-platform (macOS, Windows, Linux); today it
is built and tested only on macOS (Apple Silicon).
Prerequisites: macOS (Apple Silicon for dev), Xcode Command Line Tools, Rust (stable), Node 20+ with pnpm, Python 3.12.
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
pnpm install
pnpm tauri:dev # full app: Vite on :1420 + Rust shell + sidecar from .venvpnpm tauri:dev builds the sidecar archive on first run if it is missing (Tauri
beforeDevCommand hook) and pnpm tauri:build always rebuilds it, so
bash scripts/build-sidecar.sh is only needed to prebuild it by hand.
There is one verification gate: make check-all must pass before any change is done.
| Command | What it does |
|---|---|
pnpm tauri:dev |
Run the full app in dev mode |
pnpm tauri:build |
Production .app + DMG bundle |
make check-all |
check-rust + check-python + test-python + check-frontend + test-frontend + build-frontend |
make check-rust |
cargo check + cargo clippy --all-targets -- -D warnings (in src-tauri/) |
make check-python |
ruff format --check . + ruff check . + mypy app/ |
make test-python |
python -m pytest app/tests tests/sidecar -q |
make check-frontend |
tsc -b --noEmit + eslint |
make test-frontend |
vitest run (jsdom; tests in src/**/__tests__/) |
make seed-demo |
Seed data/codenest.demo.db with synthetic demo data (ARGS=--reset to wipe) |
bash scripts/build-sidecar.sh |
PyInstaller onedir sidecar → src-tauri/resources/sidecar.tar.gz (host arch only) |
| Sidecar standalone | venv active: uvicorn main:app --port 8002 (rare — API testing in isolation) |
main.py # sidecar entrypoint (frozen PyInstaller binary runs the __main__ branch)
app/ # FastAPI sidecar: routers/ (thin HTTP), services/ (all business logic),
# models/, config.py (env + DB paths), database.py (migration runner)
frontend/src/ # React app: pages/, components/, lib/ (api.ts, ipc.ts, nav-items.ts),
# stores/ (zustand), hooks/, styles/ (design tokens)
src-tauri/src/ # Rust shell: lib.rs (commands/wiring), sidecar/ (spawn + health),
# pty/ (terminals), session/, scheduler/, tray/, workspace/, commands/
src-tauri/resources/org-agents/ # bundled org agents + manifest.json (sha256 per file)
migrations/ # append-only NNN_*.sql; 000_baseline_schema.sql is the initial DB state
scripts/ # build-sidecar.sh, pyinstaller.spec, seed_demo.py
tests/sidecar/ # pytest integration suite (fresh migrated SQLite per test)
data/ # local dev DBs (gitignored; auto-created)
The Rust shell is the process supervisor. On launch it spawns the sidecar (dev: .venv
uvicorn on port 8002, no --reload; release: PyInstaller onedir extracted once per version
into app-data) and polls GET /health — a 200 means migrations have applied and the app is
ready. The frontend talks HTTP/SSE to the sidecar at 127.0.0.1:8002 and uses Tauri invoke
for shell things: PTYs (xterm.js terminals), windows, preview webview, screenshots, git.
Scheduling is split by design: the sidecar queues due cron runs in SQLite; the Rust scheduler
polls for pending runs and spawns headless claude processes. The Command Center bootstrap
(deferred, idempotent) creates the app-data workspace and installs the bundled org-agents.
| Var | Effect | Default |
|---|---|---|
CODENEST_ENV |
demo or prod — selects the DB file |
demo in dev; prod when packaged |
CODENEST_DB_PATH |
Absolute DB path override (tests/CI); wins over CODENEST_ENV |
unset |
CODENEST_SIDECAR_PORT |
Sidecar port for standalone runs (the shell pins 8002) | 8002 |
CODENEST_APP_DATA_DIR |
App-data root; injected by the shell | platformdirs fallback |
CODENEST_BUNDLE_RESOURCES |
Bundled org-agents dir; injected by the shell | src-tauri/resources/org-agents |
CODENEST_DISABLE_SCHEDULE_TICK |
1 disables background tick loops (tests) |
off |
VITE_SIDECAR_URL |
Frontend override for the sidecar base URL | http://127.0.0.1:8002 |
DB locations: dev demo data/codenest.demo.db; dev prod data/codenest.db;
packaged ~/Library/Application Support/com.codenest.dashboard/codenest.db.
- Migrations are append-only. Plain SQL files
NNN_*.sql, applied sorted by filename viaexecutescript, recorded by filename stem inschema_migrations, skipped if recorded — content is never re-checked. Never edit an applied migration; never rename000_baseline_schema.sql. Never reuse the stems000_baseline_schema,001_agent_sessions_pane_id,001_workflow_labels,002_schedule_artifact_dir(recorded in existing installs) — start new migrations at003_. - A freshly migrated DB ships empty apart from functional reference data (settings defaults,
taxonomies, catalog). No people, no projects, no history.
make seed-demois the only way demo data enters a DB, and only the repo-local demo DB. - The dev sidecar has no
--reload. Python edits require an app restart; only the Vite frontend hot-reloads. - Process spawning lives in the Rust shell, never the sidecar. The sidecar owns state and queues; the shell owns child processes. Bridged by poll-dispatch.
- The sidecar binds
127.0.0.1only and is deliberately unauthenticated; the MCP manager's trust model (registering a server executes a local command) depends on loopback-only binding. Never widen the bind address or CORS allowlist. - Frontend chrome renders only from known-good state.
FEATURE_DEFAULTSinfrontend/src/lib/nav-items.tsmust mirror_FEATURES_DEFAULTinapp/services/settings_service.py. Left-nav visibility is governed solely by feature toggles. - Org-agent bundle is manifest-driven. Editing any file in
src-tauri/resources/org-agents/requires recomputing its sha256 inmanifest.json(and bumping the manifestversion). Installs are idempotent, per-file-hash-diffed; user edits are reverted on next launch. sidecar.tar.gzis a build artifact (gitignored). Rebuild withscripts/build-sidecar.shafter sidecar changes and beforepnpm tauri:build.- The Rust binary name
Codenest(Cargo[[bin]]) must matchmainBinaryNameintauri.conf.json. The macOS app menu deliberately omits Cmd+W "Close Window" — the frontend owns Cmd+W for tab close; don't reintroduce it.
Installed into every user's app-data workspace at first run (read-only, symlinked into the
Command Center workspace's .claude/agents/):
- Atlas (
atlas-recruiter.md) — recruiting & team architecture: designs new agent definitions for the user's team and registers them in the dashboard via Orion. - Orion (
orion-ops.md) — IT & workflow operations: the sole gateway for dashboard DB writes; other agents route natural-language requests through it and it executes the correspondinghttp://localhost:8002/api/v1/calls (tasks, inbox, team, documents). - Vega (
vega-research.md) — lead researcher: produces structured markdown research reports and files follow-up tasks/inbox items via Orion.
Agents must never call the dashboard API directly for writes — Orion is the gateway.
Python: make test-python (unit in app/tests/, integration in tests/sidecar/ — each test
gets a fresh migrated SQLite via the migrated_db fixture). Bare pytest from the repo
root works too — test paths come from pytest.ini. Frontend: make test-frontend
plus make check-frontend for types/lint. Rust: cargo test in src-tauri/ (unit tests in
pty, window, scheduler, docs modules). New services/routers should land with tests; schema
changes must keep tests/sidecar/test_migrations green.
- Small, focused commits; short imperative subject lines. No
Co-Authored-Bytrailers. - One layer per PR where possible (sidecar / frontend / shell); cross-layer changes should explain the contract change in the description.
make check-allmust pass before requesting review.