Imported from superplanehq/superplane (
AGENTS.md). Install upstream withnpx skills add superplanehq/superplane. Copyright stays with the author.
Repository Guidelines
Guidance for AI coding agents and human contributors working in this repository.
Read this file in full. Do not truncate it with head, sed, or a partial
Read. Facts you need after setup (generated files, CI path, what not to commit)
are in this file. A prefix is not enough.
Read more only when the task needs it:
- UI: web_src/AGENTS.md, .agents/skills/ui-copy/SKILL.md, and .agents/skills/simplified-technical-english/SKILL.md
pkg/modelsor new database access: pkg/models/AGENTS.md- If changing Terraform, look at release/terraform/AGENTS.md.
- Local factory GitHub App: docs/contributing/connecting-to-3rdparty-services-from-development.md
Read this first
Generated files are not in Git
make pb.gen writes the paths below. Git ignores them. They will not appear in
git status or git diff. Do not search Git history or the working tree for
them as tracked changes. Do not commit them. Do not hand-edit them. Edit
protos/ and run make pb.gen again.
pkg/protos/— Go code fromprotos/*.protopkg/openapi_client/— generated Go SDK for the CLIweb_src/src/api-client/— generated TypeScript SDK for the UIapi/— generated OpenAPI/swagger spec
A clean clone does not contain these files until make dev.setup or
make pb.gen runs. CI is Semaphore (.semaphore/), not GitHub Actions. CI
runs make dev.setup, which includes pb.gen.
Do not rediscover the build system
Use the make targets in this file. Do not probe for .github/workflows or
raw docker compose file names.
Project Overview
SuperPlane is an open-source automation engine for AI-driven engineering. It orchestrates workflows across the tools teams already use (Git, LLMs, CI/CD, observability, incident, and infrastructure tools) with durable execution, approvals, and an operational UI.
- Backend: Go, exposing a gRPC API with a REST/OpenAPI gateway.
- Frontend: TypeScript + React, built with Vite.
- Infrastructure: PostgreSQL (state) and RabbitMQ (messaging), run via Docker.
- The application name is SuperPlane (not "Superplane") in all user-facing text.
Repository Layout
cmd/— Go entrypoints (server, workers, CLI).pkg/— Go application code. Notable packages:pkg/grpc/actions— gRPC API implementation.pkg/models— database models (see pkg/models/AGENTS.md).pkg/workers— background workers.pkg/integrations/<integration>/— integration component implementations.
web_src/— TypeScript/React frontend (Vite). UI component mappers live inweb_src/src/pages/app/mappers/<integration>/.protos/— protobuf definitions for the API. Generated output is gitignored (see Read this first).db/— database structure and migrations.scripts/— codegen, DB, and CI helper scripts.test/— backend and end-to-end tests.docs/— Markdown documentation (seedocs/contributing/).cmd/runner,cmd/fleetmanager,pkg/runners, andpkg/fleets— the integrated runner and Fleet Manager. Local development uses this stack.- Legacy runner source and release automation live in superplanehq/runner. App-side legacy broker routing remains here during the hosted rollout.
Makefile— the entrypoint for all common tasks..semaphore/— CI pipelines. There is no.github/workflows/directory.
Prerequisites & Setup
The development environment is entirely Docker-based: build, lint, test, and
run commands execute inside containers via docker compose. You do not need Go
or Node installed on the host, only Docker.
- Go
1.26.2(pinned ingo.mod; provided by the dev container). - Node.js, npm, and Bun (provided by the dev container; used by Vite/frontend).
- Docker with a working
docker compose.
Run these three steps once, in order:
make dev.up— builds the app and runner images and starts dependency containers (app shell, db, rabbitmq). The first run builds the images (~3-5 min); later runs reuse them. After you changerelease/runner/Dockerfile, runmake dev.upagain.make dev.setup— installs npm deps, downloads Go modules, runs protobuf codegen, and creates + migratessuperplane_dev. Re-run when protos, Go modules, or frontend deps change. By default onlysuperplane_devis migrated; useDEV_SETUP_DBS="superplane_dev superplane_test"when you also needsuperplane_test(E2E; backend CI sets this via the environment).make dev.server— starts the API (Go hot-reload viaair), the Vite dev server, and the Docker Fleet Manager. UI at http://localhost:8000; health check at http://localhost:8000/health.make dev.setupcreates or updates the locale1-large-amd64fleet. Fleet Manager waits for owner setup and creates its local development token. Usemake dev.server.fgfor foreground logs.
Factory workspace onboarding needs a public SuperPlane GitHub App on a
stable tunnel. Without SUPERPLANE_GITHUB_APP_* in .env, local factory
onboarding is blocked. Factory Sentry intake uses a public SuperPlane
Sentry app. Without SUPERPLANE_SENTRY_APP_* in .env, SuperPlane asks
for a personal token. See
docs/contributing/connecting-to-3rdparty-services-from-development.md.
make dev.up, make dev.setup, and make dev.server use the integrated
runner API and Docker Fleet Manager. Set TASK_BROKER_* in .env only while
testing legacy or remote broker routing (see .env.example).
The local worker image includes Claude Code, Codex, OpenCode, git, gh,
jq, ffmpeg, ffprobe, whisper-cli, and the Whisper tiny model. Factory
line apps run on that worker. Do not install those CLIs on the host.
Connect GitHub and Claude integrations in the organization before you
dispatch a factory line. Factory nodes use those integrations, not .env
ANTHROPIC_API_KEY. Check tools with make doctor-local after make dev.server. OpenCode must be on the runner PATH for Run OpenRouter Agent.
SuperPlane does not download OpenCode in the prompt prepare step.
Video and audio task files need ffmpeg, ffprobe, whisper-cli, and the baked
Whisper model. Missing media tools fail the setup step. Do not download
models during a task.
Local hosted OpenRouter is optional. Set SUPERPLANE_DEV_HOSTED_OPENROUTER
in .env only when you need the SuperPlane-hosted provider. See
docs/contributing/connecting-to-3rdparty-services-from-development.md.
On first UI load, owner setup is enabled (OWNER_SETUP_ENABLED=yes), so you are
prompted to create an admin account. Open registration is disabled by default
(BLOCK_SIGNUP=yes).
If go mod download / go build fail with missing or corrupt files in the Go
module cache (the go-pkg-cache Docker volume mounted at /go/pkg/mod, often
after a disk-full or interrupted download), run make dev.clean.go.cache then
make dev.setup.go.
Build, Test & Lint Commands
- One-shot backend tests:
make test(Go). - Targeted backend tests:
make test PKG_TEST_PACKAGES=./pkg/workers - Targeted E2E tests:
E2E_TEST_PACKAGES=./test/e2e/workflows make test.e2e(ormake test.e2e.single FILE=test/e2e/foo_test.go LINE=19for a single test). - UI unit tests:
make check.test.ui(Bun + Happy DOM). Targeted UI tests:make check.test.ui FILES=src/lib/duration.spec.ts. Paths inFILESare relative toweb_src/. - After editing Go code:
make format.go, thenmake lint && make check.build.app. Do not rungo build ./...—scripts/has more than onemainpackage. Usemake check.build.app. - After editing JS/TS code:
make format.js, thenmake check.lint.uiandmake check.build.ui. Runmake check.lint.uilocally before you open a pull request. CI fails when the ESLint budget grows. - After updating
protos/: regenerate protos, the OpenAPI spec, and the CLI/UI SDKs withmake pb.gen(requires a runningappcontainer frommake dev.up). Generated files stay gitignored; a cleangit statusafterpb.genis expected. After removing proto fields, renumber remaining fields so message field numbers stay contiguous (no gaps orreservedmarkers — these protos are used for JSON conversion, not wire compatibility), then runmake check.proto.field.numbers. - NEVER MANUALLY CREATE MIGRATION FILES. Use
make db.migration.create NAME=<name>(dashes, not underscores). We do not write rollbacks, so leave*.down.sqlempty. After adding a migration, runmake db.migrate DB_NAME=<DB_NAME>whereDB_NAMEissuperplane_devorsuperplane_test(requires a running app container). - NEVER DROP LOCAL DATABASES WITHOUT ASKING. Do not run
make db.delete,make db.recreate.all.dangerous,make dev.setup.no.cache,make dev.pr.clean.checkout,dropdb, orDROP DATABASEunless the user explicitly asked.make db.migrate.allapplies pending migrations and rewritesdb/structure.sql. It does not drop data. Do not pair it withdb.delete. If migrate fails (for exampleno migration found for version), stop and ask. Do not recreatesuperplane_devas a workaround.
Cross-cutting rules when extending the backend:
- When validating enum fields in protobuf requests, ensure enums are mapped to
constants in
pkg/models. Check theProto*and*ToProtofunctions inpkg/grpc/actions/common.go. - When adding a new worker in
pkg/workers, add its startup tocmd/server/main.goand update the docker compose files with any new environment variables. - After adding new API endpoints, ensure they are covered in
pkg/authorization/interceptor.go.
Further reading:
- Models and transactions: pkg/models/AGENTS.md
- E2E test authoring: docs/contributing/e2e-tests.md
- Dev server profiling: docs/contributing/profiling.md
- New components/triggers: docs/contributing/component-implementations.md
- Component design & quality: docs/contributing/component-design.md
- UI component workflow: web_src/AGENTS.md
Coding Style & Naming Conventions
- Always write clean code: work test-first by default, then keep names clear, functions focused, side effects explicit, control flow shallow, and error handling useful. Load .agents/skills/test-audit/SKILL.md when you write, change, review, or sweep tests.
- Tests end with
_test.go. - Always prefer early returns over else blocks when possible.
- Go: prefer
anyoverinterface{}. - Go: to check membership in a slice, use
slices.Containsorslices.ContainsFunc. - Avoid variable names like
*Stror*UUID; Go is typed, so types don't belong in variable names. - In tests needing specific timestamps, base them off
time.Now()rather than absolute times fromtime.Date. - The name of the application is "SuperPlane", not "Superplane", in all user-facing text (UIs, emails, notifications, documentation).
- Frontend: do not create or use
web_src/src/utils/*orutils.tsfiles. Put shared non-React helpers inweb_src/src/lib/, and React-specific reusable logic inweb_src/src/hooks/.
Files & Directories Not to Modify by Hand
- Generated code — see Read this first. All produced by
make pb.gen. Git ignores the output. Never hand-edit it. - Database migrations — never create or edit migration files by hand; use
make db.migration.create NAME=<name>(see the Build section). - Secrets & local config — never commit real secrets.
.env.exampleand.env.multi-instance.exampleare templates; do not check in a populated.env. - Vendored / cached dependencies — do not edit
web_src/node_modules/or the Go module cache undertmp/go/.
Commit & Pull Request Guidelines
Follow .agents/skills/commit-and-pr-messages/SKILL.md for commit subjects/bodies and for every PR title and description. That skill encodes the Chris Beams / Tim Pope conventions (imperative subject, ~50-char summary, blank line before body, wrap at 72, explain why not how) plus SuperPlane's CI and DCO rules.
Write commit bodies, PR descriptions, UI copy, and other reviewer/user-facing technical text in ASD-STE100 Simplified Technical English style. Follow .agents/skills/simplified-technical-english/SKILL.md (short sentences, active voice, imperative instructions, stable terminology; no contractions, slang, or idioms).
- PR titles must follow Conventional Commits with a release-type prefix that CI
enforces:
feat:,fix:,chore:, ordocs:. After the prefix, use an imperative, capitalized summary with no trailing period (e.g.feat: Add empty-state copy for integrations). - PR descriptions must explain why the change exists (problem, motivation, user/system impact), not narrate the diff. Use a short STE Summary plus a concrete STE Test plan checklist. Avoid empty or placeholder bodies when context matters.
- Commit subjects use the same imperative style; put motivation and trade-offs in the body. Separate subject and body with a blank line; wrap the body at 72 characters.
- All commits must include a DCO sign-off trailer
(
Signed-off-by: Name <email>). Usegit commit -s(orgit commit --amend -s). - Before submitting, run the checks relevant to your change:
- Backend:
make format.go,make lint,make check.build.app,make test. - Frontend:
make format.js,make check.lint.ui,make check.build.ui. Run ESLint locally (make check.lint.ui) before you open a pull request. - Protos:
make pb.genandmake check.proto.field.numbers.
- Backend:
For user-facing UI strings while designing or implementing frontend work, follow .agents/skills/ui-copy/SKILL.md together with the STE skill above.
Cursor Cloud VMs only: docs/contributing/cursor-cloud.md.
