Skip to content

Configuration

RepoOS is configured by repoos.toml at the repo root, with secrets kept in a gitignored .env. Every field is optional — a repo with no repoos.toml at all still works on defaults.

Layout

toml
workDir  = "work"     # where task markdown files live
docsDir  = "docs"     # project context an agent reads before working
cacheDir = ".repoos"  # derived index, logs, database — disposable

cacheDir holds only derived state. Delete it and RepoOS rebuilds everything from the markdown files; nothing of record is lost.

Board behavior

toml
defaultStatus   = "inbox"     # status new tasks start in
defaultAssignee = "ai"        # "ai" or "human"
defaultTaskMode = "freeform"
maxActiveTasks  = 3           # how many tasks may be active at once
autoEngineeringMode = false   # automatically dispatch ready tasks to agents
worktreeWarnThreshold = 20    # warn once this many task worktrees exist

Server

toml
servePort = 7171

Without servePort, repoos serve derives a stable port from the repo's own path, so two repos running RepoOS at the same time never fight over one port. Pin it only when something external depends on a fixed port (a tunnel, a launchd/systemd unit, a bookmarked URL).

repoos stop finds the right process through a per-port lockfile, so stopping one repo's server never kills another's.

Agents

toml
maxConcurrentAgents  = 5        # agent CLI processes running at once; extras queue
ctoMonitorIntervalMs = 300000   # CTO agent poll interval

maxConcurrentAgents defaults to a value computed from your machine's core count. Raise it if the machine still looks idle under load, lower it if it's straining — agents are subprocess- and network-heavy, so the right number is usually well below your core count.

Runtime

RepoOS runs under Bun when available and Node otherwise. Control it with environment variables, not repoos.toml:

VariableEffect
(unset) or REPOOS_RUNTIME=autoUse Bun if it's on PATH, else Node. The default.
REPOOS_RUNTIME=bunRequire Bun; warn and stay on Node if it's missing.
REPOOS_RUNTIME=nodeAlways Node. The opt-out.
REPOOS_BUN_PATH=/path/to/bunUse this binary explicitly, skipping the PATH lookup.

repoos serve prints which runtime it picked at startup. Bun is substantially faster for the subprocess-heavy work RepoOS does — on this project's own test suite it's roughly a 5x difference — so the default is worth keeping unless you have a reason to pin Node.

Authentication

Auth is off by default. When enabled, the server refuses to start unless both a login provider and a bootstrapAdmin are configured.

toml
auth.enabled        = true
auth.sessionMaxAge  = "2592000"           # seconds
auth.bootstrapAdmin = "you@example.com"   # only this address can claim the founding admin account
auth.emailProvider.type        = "resend"
auth.emailProvider.fromAddress = "otp@send.example.com"
# auth.google.clientId = "..."            # optional "Sign in with Google" button

Secrets never go in repoos.toml — it's git-tracked. Put them in .env:

bash
REPOOS_RESEND_API_KEY=...
REPOOS_GOOGLE_CLIENT_SECRET=...

Auth changes take effect on the next repoos serve, not live.

Remote validation

Offloads the test suite to a disposable cloud VM, so a long check doesn't tie up (or get starved by) your laptop.

toml
remoteValidation.enabled         = false
remoteValidation.fallbackToLocal = false

Needs HETZNER_API_TOKEN and REPOOS_REMOTE_SSH_KEY in .env, plus a prebuilt snapshot.

Releases

Opt-in. When configured, RepoOS pushes an annotated version tag from a clean trunk after repoos check passes; your CI does the actual build and publish.

toml
[release]
enabled     = true
provider    = "git-tag"
branch      = "main"
versionFile = "package.json"
tagPrefix   = "v"
remote      = "origin"

The "Releases" page only appears in the UI when this block is present.

Appearance and notifications

toml
theme       = "dark"
uiTheme     = "classic"   # classic | clear | gen z | jelly
ntfyEnabled = true
ntfyTopic   = "your_topic"

FSL-1.1-MIT — free to use, self-host and modify; converts to MIT two years after release.