Skip to content

Run it locally

  • Ruby 3.4.6 (see .ruby-version)
  • PostgreSQL 14+
  • Redis
  • Node.js (for the AIR CLI and npx-based MCP servers)
  • The claude and/or codex CLI, logged in
  • gh CLI, logged in (agents use it to open PRs)
Terminal window
bundle install
cp .env.example .env # then set ANTHROPIC_API_KEY
bin/rails db:setup
bin/dev # → http://localhost:3000

bin/setup does the same thing plus bundle check, db:prepare, and log:clear, then execs bin/dev. Use PORT=0 bin/dev for a random port.

bin/dev installs foreman if it’s missing, warns (non-fatally) if redis-cli ping fails, kills any stale foreman or port-3000 processes, and starts Procfile.dev:

web: bin/rails server
css: while true; do bin/rails tailwindcss:watch || sleep 5; done

config/database.yml and config/cable.yml expect two databases per environment: zimmer_development and zimmer_development_cable. The second is Action Cable’s, via solid_cable. bin/rails db:setup creates both.

Everything in .env.example is commented out except RAILS_ENV=development. The ones that matter:

VarWhat for
DATABASE_HOST / _PORT / _USERNAME / _PASSWORDPostgres. Postgres.app users want 5450.
REDIS_URLCache. redis://localhost:6379
ANTHROPIC_API_KEYClaude Code, if not using OAuth
API_KEYSComma-separated keys for the REST API. Unset ⇒ the API 401s on everything.
APP_HOSTThe MCP OAuth redirect host. Unset ⇒ defaults to localhost:3000.
RAILS_MASTER_KEYUnlocks Rails credentials (mcp_secrets, mcp_oauth_clients)
AIR_CONFIGOverride which air.json the catalog resolves from
AGENT_CLONES_DIRWhere session clones go. Default ~/.agent-orchestrator/clones
GOOD_JOB_MAX_THREADSWorker concurrency

gh and the agent CLIs authenticate via OAuth (gh auth login, claude /login), not env vars.

On boot, config/initializers/air_catalog.rb runs AirCatalogService.refresh!, which lazily npm installs the AIR CLI (pinned to 0.13.0) into AIR_INSTALL_DIR and then shells out to air resolve. The first boot is slow because of that install.

If the catalog fails to resolve, the app downgrades to a warning and serves a stale snapshot — but the test suite is less forgiving. See below.

Terminal window
bin/rails test test/models/session_test.rb # targeted — do this
bin/rails test # the whole suite
bin/rubocop # lint
bin/brakeman # security scan

Run targeted tests locally and let CI run the full suite.

.github/workflows/ci.yml runs “unit + integration; system tests excluded.” The browser suite never runs on a PR. Combined with the four open UI bugs (issues #12–#15), that’s the obvious hole — see Testing philosophy.