Local development setup
dashboard, desktop shell, plugins, and (optionally) the commercial cloud control plane.
Using Coro (not hacking on it)? Install the desktop app from Coro-ai-framework/coro-release and follow the README quick start. No Node.js or
pnpmrequired.
Prerequisites
| Tool | Why | Install |
|---|---|---|
| Node.js 20+ | Runner, dashboard, desktop packaging | https://nodejs.org |
| pnpm 9+ | Workspace package manager | corepack enable && corepack prepare pnpm@9.15.0 --activate |
| Git | Target repos and gitRemote tenant overlays | system |
| Docker | Optional — Postgres + Redis for cloud development | https://docker.com |
Coro is a pnpm workspace. Do not run npm install at the root — the
workspace:* protocol is required and npm fails mid-install.
For end-to-end job runs you also need (configured in the dashboard or
~/.coro/config.json):
- Anthropic credentials (executor plugin
anthropic) - SCM credentials — built-in GitHub or Bitbucket; GitLab via
@coro-ai/plugin-gitlab
Optional: tune runner guardrails (PR description, diff size) in Settings → Guardrails or see guardrails.md.
Workspace bootstrap
From the repository root:
pnpm installpnpm -r build # intelligence-base, runner, dashboard, plugins, …pnpm typecheck # optional but recommended before a PRpnpm test # all packages; see Testing below| Command | Purpose |
|---|---|
pnpm start | Built runner + dashboard (coro start) |
pnpm dev | Runner from source via tsx (fast iteration) |
pnpm dev:dashboard | Vite HMR for dashboard (proxies API to :3000) |
pnpm dev:cloud | Cloud control plane (needs Postgres + .env.cloud) |
pnpm --filter @coro-ai/desktop-electron dev | Electron shell + bundled sidecar |
pnpm clean | Remove dist/ and node_modules/ everywhere |
Solo (local) mode
Solo mode runs the runner, dashboard, and SQLite state on one machine. No Docker required.
Start the runner
From a build:
pnpm start# equivalent:node packages/runner/dist/cli/index.js startFrom source (no prior build):
pnpm devThis:
- listens on http://localhost:3000 (override with
coro start --port N) - serves the dashboard at http://localhost:3000/dashboard/
- opens the browser by default (skipped in headless/SSH/CI; use
--open,--no-open, orCORO_NO_OPEN=1)
Optional: pnpm --filter @coro-ai/runner exec npm link then use coro start
anywhere.
Configure
Use Settings in the dashboard (recommended) or edit ~/.coro/config.json.
Typical fields:
plugins.installed.anthropic— API key, OAuth, or Claude Code loginplugins.installed.<scm>— GitHub / Bitbucket (see built-ins below)git— legacy-friendly block; merged into plugin config when neededpaths.workingDir— job working tree (default under~/.coro/work)intelligence.dir— tenant overlay directory (optional)
Schema: packages/runner/src/config/local-config.ts.
Submit a job
Dashboard: New Job → pick repo → describe the change.
CLI (runner must already be running):
coro job \ --repo my-service \ --description "Add rate limiting to /api/users" \ --reviewers alice,bobOptional: --git-provider github|bitbucket, --jira-ticket PROJ-123 (Jira-driven
job). The default implementation workflow is
workflows/job/workflow.md (resolved from intelligence layers).
coro jobscoro status <jobId>coro logs <jobId> --followcoro resume <jobId>Plugins (SCM, tracker, LLM)
The runner loads built-in plugins from packages/runner/src/plugins/builtin/
and drop-in plugins from ~/.coro/plugins/<id>/ (with coro-plugin.json).
| Kind | Built-in IDs | Notes |
|---|---|---|
| SCM | github, bitbucket | Configure via Settings → Git |
| Tracker | jira, linear, github-issues | Enable in plugins.installed |
| Executor (LLM) | anthropic, openai | Anthropic required for default workflows |
GitLab (SCM): install the reference package:
coro plugin install @coro-ai/plugin-gitlab# configure plugins.installed.gitlab in Settings or config.jsonAuthoring: coro plugin init <id> scaffolds ~/.coro/plugins/<id>/.
See packages/plugin-sdk/README.md and
packages/plugin-gitlab.
coro plugin list # built-in + drop-ins (runner must be up for full list)Solo-mode storage
~/.coro/├── config.json ← LocalConfig├── state.db ← SQLite (jobs, logs, proposals, …)├── work/<jobId>/ ← Per-job dirs│ ├── _intelligence/ ← Materialised overlay for the job│ └── <repoSlug>/ ← Cloned target repo├── intelligence/ ← Optional local tenant overlay├── plugins/<id>/ ← Drop-in plugins└── cache/tenant-overlays/ ← Cached gitRemote overlaysInspect a running job:
ls ~/.coro/work/<jobId>/_intelligence/Reset local state (stop the runner first):
rm ~/.coro/state.dbrm -rf ~/.coro/work/rm -rf ~/.coro/cache/Tenant overlay (optional)
Add a tenant.overlay block to ~/.coro/config.json:
{ "tenant": { "displayName": "My Team", "overlay": { "kind": "gitRemote", "url": "git@github.com:my-team/coro-overlay.git", "ref": "main" } }}kind | Behaviour |
|---|---|
localDir | { "kind": "localDir", "path": "/abs/path" } |
gitRemote | Cloned under ~/.coro/cache/tenant-overlays/<tenantId>/ |
cloudBlob | Served by Coro Cloud in team mode (stub / limited in solo today) |
Merge semantics: architecture.md §4.
Hybrid (team) mode
Pre-1.0. Hybrid mode (local runner + shared cloud control plane) is under active development. Expect rough edges; production team deployments use the commercial surface in
packages/runner/src/cloud/(NOTICE.md).
Each developer runs a local runner; job state and team coordination go through Coro Cloud.
Pair with cloud
With cloud running locally (see below) or against a deployed URL:
coro login --cloud-url http://localhost:4000This writes a cloud block to ~/.coro/config.json:
{ "cloud": { "url": "http://localhost:4000", "token": "<runner JWT>" }}Then coro start (or the desktop app) connects over WebSocket. The dashboard
on localhost:3000 still works; state may be team-scoped via the cloud backend.
Webhooks (cloud)
Webhooks hit the cloud, not your laptop. Preferred shape:
POST https://<cloud-host>/webhook/<teamId>/<pluginId>Example: https://cloud.example.com/webhook/team-uuid/github
Configure HMAC secrets per team/plugin in the cloud DB. Legacy provider-named
routes may still forward but are deprecated — see
packages/runner/src/cloud/routes/webhooks.ts.
Cloud control plane (developing)
Source: packages/runner/src/cloud/ (commercial license — development and
transparency only; see cloud/LICENSE).
1. Start Postgres and Redis
docker compose -f packages/runner/docker-compose.cloud.yml up -dDefaults: Postgres localhost:5432 (db/user/password corocloud), Redis
localhost:6379.
2. Environment
Create packages/runner/.env.cloud (gitignored):
DATABASE_URL=postgresql://corocloud:corocloud_dev@localhost:5432/corocloudREDIS_URL=redis://localhost:6379JWT_SECRET=change-me-to-at-least-32-random-characters# optional:# CLOUD_PORT=4000# JWT_ISSUER=corolabs-cloud# LOG_LEVEL=debugApply schema:
cd packages/runnerpnpm db:push # or: pnpm db:migrate3. Run the cloud API
From repo root:
pnpm dev:cloudDefault listen port: 4000 (CLOUD_PORT). Health check:
http://localhost:4000/health (if exposed).
4. Pair a runner
coro login --cloud-url http://localhost:4000coro startDeveloping the dashboard
The runner serves the built dashboard at /dashboard/. For HMR:
# Terminal 1pnpm dev # runner on :3000
# Terminal 2pnpm dev:dashboard # Vite on :5173, proxies API to :3000Override the bundle the runner serves:
export CORO_DASHBOARD_DIST=/abs/path/to/packages/dashboard/distpnpm startCoro plan mode (New Run chat) hits POST /intake/stream on the runner.
It requires a configured LLM executor and uses the executor’s chat() path
when available (@coro-ai/llm-anthropic, @coro-ai/llm-openai). User-facing
documentation lives in the docs site: Coro plan mode.
Developing the desktop app
The shipping app is @coro-ai/desktop-electron — Electron wraps the runner sidecar
and dashboard (desktop-packaging.md).
pnpm install && pnpm -r buildpnpm --filter @coro-ai/desktop-electron devPackages a local run (macOS arm64 / Windows x64) via
pnpm --filter @coro-ai/desktop-electron dist:mac or dist:win. Releases publish to
Coro-ai-framework/coro-release.
Testing
pnpm test # all workspace packagespnpm --filter @coro-ai/runner test # runner unit + MCP + integrationpnpm --filter @coro-ai/runner test -- tests/unit/foo.test.tsTroubleshooting
Dashboard does not open
- Browse to http://localhost:3000/dashboard/ manually, or
coro start --open. - Headless/SSH/CI suppresses auto-open; set
CORO_NO_OPEN=1to keep it off.
npm install crashes
- Use
pnpm installat the repo root.
Job stuck or lost
coro status <jobId>or open the job in the dashboard.ls ~/.coro/work/<jobId>/coro resume <jobId>
Runner cannot pair with cloud
- Cloud reachable at
cloud.urlin config (default dev:http://localhost:4000). - Re-run
coro login. - Confirm
cloud.tokenis present in~/.coro/config.json.
Plugin not loading
- Drop-ins:
~/.coro/plugins/<id>/coro-plugin.jsonand restart the runner. - Built-ins: check
plugins.installed.<id>.enabledand config in Settings. coro plugin listwith runner online.
tenant.overlay not applied
localDirpath must exist and be absolute.- For
gitRemote, delete~/.coro/cache/tenant-overlays/<tenantId>/to force re-clone; useLOG_LEVEL=debugon the runner for loader logs.
Related docs
| Document | Content |
|---|---|
| architecture-overview.md | Plain-English system tour |
| architecture.md | Full architecture + layered intelligence |
| agent-host-spec.md | Runner HTTP API, MCP tools, job lifecycle |
| desktop-packaging.md | Desktop release and updater |
| workflow-extension-contract.md | Workflow/plugin extension points |
| ../README.md | Product overview and downloads |
| ../CONTRIBUTING.md | PR process, CLA, help wanted |