Install
Pick whichever method fits your machine. All three produce a single berth binary with no runtime dependencies beyond Git and the toolchains your project already uses.
Prebuilt binaries
Archives for Linux, macOS and Windows are published on the releases page. Extract the archive and place the executable somewhere on your PATH.
With Go
Requires Go 1.25 or newer:
go install github.com/Mrjwj34/berth/cmd/berth@latest
From source
git clone https://github.com/Mrjwj34/berth.git
cd berth
go build -o bin/berth ./cmd/berth
Install only the agent skill
If you want the agent instructions before the binary exists, the skills CLI installs just the skill. It checks for the binary first and tells your agent how to install berth when it is missing:
npx skills add Mrjwj34/berth
Initialize a repository
Run this at the repository root. It writes a commented berth.yaml template, installs the agent skill into the shared .agents/skills/berth/ convention that twelve harnesses read, and merges berth’s worktree hooks into the harness configurations that document one.
berth init
berth hook install all
Commit berth.yaml before creating a workspace. Each workspace loads the configuration from its own branch, so uncommitted edits never reach a workspace created from them.
Configure berth.yaml
The fastest path is to let your coding agent write the first version: the installed skill knows the field list, the traps and the container recipe.
Prompt: “Inspect this repository and configure berth.yaml based on the existing startup scripts, toolchains and listen ports.”
A minimal native service looks like this — one named port, one managed process, one readiness probe:
version: 1
base: main
ports: [web]
processes:
web:
command: npm run dev -- --port "$BERTH_PORT_WEB"
readiness_probe:
http_get: {host: 127.0.0.1, port: "${BERTH_PORT_WEB}", path: /}
Every field — runtime, listen, env, env_file, copy_dirs, hooks, processes, gc and the worktree include file — is documented on the features and configuration page.
Create your first workspace
berth new feature-a --up
One command creates the linked worktree, reserves the declared ports, seeds the private data directory, runs setup hooks and starts the process graph. Without --up, the workspace is created but nothing is started.
Where it lands
<repo>.berths/<slug> beside the repository, or <worktree_root>/<slug> when worktree_root is configured.
Branch
berth/<slug>, based on base: from berth.yaml or the --base flag.
Slug rules
Lowercase ASCII letters, digits, - and _ only. No slashes.
Useful variations:
berth new api-rewrite --base release/2.0 # start from another ref
berth new spike --print-path # print only the absolute path
berth new audit --json # machine-readable result
The primary checkout is never a workspace, and berth adopt refuses it. berth run and berth open take no slug: they resolve the workspace from the current directory, so run them from inside the path that berth new printed (its last line, or path in --json). Commands that accept a slug also work from anywhere as long as the slug is unambiguous.
Working inside a workspace
berth run joins the same runtime and environment as the services and hooks, passes argv through verbatim without reparsing, and propagates the exit code.
cd ../my-repo.berths/feature-a
berth run -- npm test
berth run -- sh -c 'npm ci && npm test' # request a shell explicitly
berth status --json # readiness instead of sleep loops
berth logs web # stream one managed process
berth ports # allocated ports and listen mappings
berth plan # the execution contract, before anything starts
berth run deliberately does not prepend a shell: berth run -- npm test executes npm with the arguments test. Ask for a shell when you want one. On Windows a native cmd script and a POSIX sh script are not interchangeable, so a shell one-liner that works on macOS may need rewriting there.
In container mode, cancelling a berth run stops that workspace’s whole container, including its sibling services. Other workspaces keep running.
Stop, reset and release
Three commands with deliberately different blast radius:
-
berth downstops the processes and keeps everything: checkout, private data, container instance. Start again withberth up. -
berth resetwipes the private data directory on purpose — after a verified shutdown — and reruns setup hooks. Use it when the local database or cache is the thing that is broken. -
berth donerequires the branch commit to be preserved (merged or present upstream) and the worktree to be clean, then tears down the runtime and removes the checkout and its registration.--forcecannot bypass ownership, identity, primary-worktree or shutdown checks, and an adopted checkout is preserved even with--force.
berth down feature-a
berth reset feature-a
berth done feature-a
berth gc --dry-run # inspect before collecting
berth gc # reclaim vanished, idle, merged or excess workspaces
berth ls # what is still around
berth doctor --fix # check git, engine, image, process-compose and state
Do not clean up by hand. rm -rf, git worktree remove and guessed PID or port cleanup corrupt the registry instead of releasing a workspace. berth gc never forces anything, and a workspace in an unknown process or engine state is preserved for you to inspect rather than deleted.
Command reference
| Command | Purpose | Key flags |
|---|---|---|
berth init |
Write a commented berth.yaml and install the agent skill |
--force |
berth new <slug> |
Create an isolated workspace, worktree and branch-local setup | --up, --base <ref>, --print-path, --json |
berth ls |
List workspaces with their phase, running state and ports | --json |
berth status [slug] |
Processes, readiness and ports of one workspace | --json |
berth ports [slug] |
Allocated host ports and container listen mappings | --json |
berth plan [slug] |
Print the execution contract as JSON without starting anything | — |
berth up [slug] |
Start the workspace process graph and wait for readiness | — |
berth down [slug] |
Stop processes, preserving data and the container instance | — |
berth logs <proc> [slug] |
Logs of one managed process | — |
berth run [--] <cmd> [args…] |
Run one command inside the workspace runtime and environment | — |
berth attach [slug] |
Print path, branch and shell exports for the workspace | --json |
berth open [port-name] |
Open a workspace port’s host URL in the browser | --json |
berth reset [slug] |
Wipe $BERTH_DATA_DIR and rerun setup |
— |
berth done [slug] |
Tear a workspace down once its work is preserved | --force |
berth adopt |
Register an existing linked Git worktree as a workspace | --setup |
berth gc |
Reclaim vanished, idle, merged or excess workspaces | --dry-run, --json |
berth doctor |
Check git, engine, image, process-compose and state health | --fix, --json |
berth agents |
List supported harnesses and what is installed in this repository | --json |
berth skill install |
Install the embedded skill into the selected harness directories | --agent, --all, --scope project|user |
berth hook install [cursor|windsurf|claude|all] |
Merge berth’s worktree hook into the selected harness configuration | --agent, --all, --scope |
berth version |
Print version information | — |
Environment contract
berth injects the same identity and port variables into every hook, service and berth run command, so a script behaves identically whichever way it is invoked.
| Variable | Meaning |
|---|---|
BERTH_WORKSPACE |
Absolute path to the workspace directory |
BERTH_ROOT |
Path to the primary Git repository |
BERTH_DATA_DIR |
Private data directory for this workspace (.berth/data) |
BERTH_SLUG |
Workspace slug identifier |
BERTH_BRANCH |
Git branch associated with this workspace |
BERTH_PORT_<NAME> |
The port inside the current execution context — the one the service binds |
BERTH_HOST_PORT_<NAME> |
The host publication on 127.0.0.1, for browsers and other host tools |
In container mode, Git metadata and a private home are provided as well: GIT_DIR, GIT_WORK_TREE, HOME and XDG_CACHE_HOME. The full port and network semantics, including gateway ports and loopback rules, are in the runtime contract.
Next steps
- Features & configuration — the complete
berth.yamlfield list, worked examples and agent integration. - Runtime contract — native versus container, addressing, readiness and recovery rules.
- Architecture — the daemonless lock model, recovery intent and safety invariants.
- Comparisons — how the workspace boundary compares with worktrees and OS containers.