Guides
Project config
A repository's .berth/config.json says how every worktree is set up, run and torn down, on every box.
A repository's .berth/config.json, committed with the code, says how every
worktree of that repository is set up and torn down, which ports,
environment and services it gets, and which agents to offer. It travels with
the repo, so every box does the same.
{
"setup": "pnpm install && createdb $BERTH_WORKTREE_SLUG",
"archive": "dropdb --if-exists $BERTH_WORKTREE_SLUG",
"ports": 2,
"env": {
"DATABASE_URL": "postgres://localhost/$BERTH_WORKTREE_SLUG",
"NEXT_PUBLIC_WEBAPP_URL": "http://localhost:$BERTH_PORT"
},
"services": [
{ "name": "web", "run": "pnpm dev --port $BERTH_PORT", "autostart": true },
{ "name": "worker", "run": "pnpm worker" }
],
"agents": [
{ "id": "claude", "name": "Claude Code (Opus)", "command": "claude --model opus" }
],
"hooks": [
{ "on": "worktree.created", "run": "cp ../cal/.env .env" }
],
"flows": []
}Every field is optional; the config reference lists them all with their rules.
Setup and teardown
setupruns right after a worktree is created, in it, through a login shell (up to 30 minutes, with its output in a log on the box).archiveruns before a worktree is removed, after its services stop; if it fails, the worktree stays.- Both also get Orca's names (
ORCA_ROOT_PATH,ORCA_WORKTREE_PATH,ORCA_WORKSPACE_NAME), so setup scripts written for Orca work unchanged.
Ports and environment
- Ports. Every worktree has its own block of ports, stable for its life
and freed when it is removed:
$BERTH_PORT, then$BERTH_PORT_1… up toportsof them (at most 10; at least one). Whatever listens on a port in the block counts as the worktree's, containers included, and the worktree's private URL,http://<worktree>.<location>.<box>.localhost:1377/, reaches the lowest one. - Environment. Everything run in a worktree (setup and archive scripts,
terminals and agents,
exec, hooks, flows, services) gets these, thenenvwith them expanded:
| Variable | Meaning |
|---|---|
BERTH_BOX | The box's name for itself |
BERTH_LOCATION | The location, like cal |
BERTH_ROOT_PATH | The repository's main checkout |
BERTH_WORKTREE_PATH, BERTH_WORKTREE_NAME | This worktree |
BERTH_WORKTREE_SLUG | Like cal_fix_billing, safe for database names |
BERTH_BRANCH | Its branch |
BERTH_PORT, BERTH_PORT_1, … | Its ports |
BERTH_KIT_DIR | Where the project's kit keeps its files, if it has one |
A value in env can use $NAME for those variables or berthd's own
environment, and can be a secret reference instead of a
value.
Services
Services run in each worktree as managed processes that survive the daemon restarting and come back if they crash, with their output in a log.
autostartones start when the worktree is created, after setup succeeds.- All of them stop before the archive script runs.
- A service also gets
PORT(its worktree's$BERTH_PORT) unlessenvsets it. - Start, stop and open them from the app's Run menu, or:
berth service list devl/cal/billing
berth service start devl/cal/billing web
berth service log devl/cal/billing webAgents
agents adds ways to start agents in this repository, or replaces a
built-in one with the same id (claude, codex, opencode, gemini,
cursor). A first prompt goes at the end of command, or after
prompt_flag if the agent needs one.
Hooks and flows
- Hooks fire only for this repository's events, inside the worktree the
event is about, with its environment.
before:gates here can refuse actions in this repository. See hooks. - Flows are this repository's automations, on every box that has it. See automations.
This box only
Some of it should not be committed: a database password, one box's paths. Each box keeps its own config for a location, laid over the file (and over the project's kit, if it has one):
setup,archive,portsand eachenventry replace the file's;services,agentsandflowsreplace the file's by name or id, and add new ones;hooksadd up.
Edit it in the app's Project settings, or PUT /v1/locations/{name}/config
on the box. berth location config devl/cal shows the repository's, the
box's and the effective config side by side.
berth location scripts devl/cal --setup "make bootstrap" # just the scripts
berth location scripts devl/cal --clearA box can also give every worktree on it some environment, in
~/.berth/env.json ({"env": {"KEY": "value"}}), under the project's own.
Next
- Kits carry this same config to a repository you can't commit to, or to several at once.
- Secrets keep passwords out of
env. - Task templates fill in the agent, branch and prompt for kinds of task you start often.