Run it locally
Prerequisites
Section titled “Prerequisites”- Ruby 3.4.6 (see
.ruby-version) - PostgreSQL 14+
- Redis
- Node.js (for the AIR CLI and
npx-based MCP servers) - The
claudeand/orcodexCLI, logged in ghCLI, logged in (agents use it to open PRs)
bundle installcp .env.example .env # then set ANTHROPIC_API_KEYbin/rails db:setupbin/dev # → http://localhost:3000bin/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 servercss: while true; do bin/rails tailwindcss:watch || sleep 5; doneTwo databases
Section titled “Two databases”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.
Environment variables
Section titled “Environment variables”Everything in .env.example is commented out except RAILS_ENV=development. The ones that matter:
| Var | What for |
|---|---|
DATABASE_HOST / _PORT / _USERNAME / _PASSWORD | Postgres. Postgres.app users want 5450. |
REDIS_URL | Cache. redis://localhost:6379 |
ANTHROPIC_API_KEY | Claude Code, if not using OAuth |
API_KEYS | Comma-separated keys for the REST API. Unset ⇒ the API 401s on everything. |
APP_HOST | The MCP OAuth redirect host. Unset ⇒ defaults to localhost:3000. |
RAILS_MASTER_KEY | Unlocks Rails credentials (mcp_secrets, mcp_oauth_clients) |
AIR_CONFIG | Override which air.json the catalog resolves from |
AGENT_CLONES_DIR | Where session clones go. Default ~/.zimmer/clones |
GOOD_JOB_AGENTS_THREADS | Worker concurrency: how many agent sessions run at once. It also moves the database pool that has to serve them — see the connection budget |
gh and the agent CLIs authenticate via OAuth (gh auth login, claude /login), not env vars.
First run: the catalog
Section titled “First run: the catalog”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.
Running tests
Section titled “Running tests”bin/rails test test/models/session_test.rb # targeted — do thisbin/rails test # the whole suitebin/rubocop # lintbin/brakeman # security scanRun targeted tests locally and let CI run the full suite.
The browser suite runs in CI
Section titled “The browser suite runs in CI”.github/workflows/ci.yml runs the Chrome-driven system suite (test/system/*.rb) in a dedicated
test-system job, alongside the unit + integration test-unit job. The JavaScript Playwright
scripts under test/e2e/*.js are the one browser layer still not wired in (issue #162) — see
Testing philosophy.