Skip to content

How it works

Splashdown is the glue between git and your env loader (mise, direnv, devbox). It installs a post-checkout git hook that forwards each checkout event to Splashdown, coexisting with your hook manager if you already use one. For a trusted clone, each checkout's free ports and other resources are allocated and handed to your loader automatically.

Run splash init once in your project. Splashdown walks the filesystem, identifies your apps and their frameworks, and writes a recipe (splashdown.toml) declaring per-checkout resources (ports, db urls, UUIDs, sim/emulator variants). On every git checkout or git worktree add, the post-checkout event handler checks clone trust and then allocates concrete values into a gitignored splashdown.env. Your shell-env loader (mise / direnv / devbox) sources that file automatically, so every process in the checkout sees the right PORT, DATABASE_URL, etc.

Four generated/config files end up in the project, and existing agent instructions may be updated:

File Committed? Purpose
splashdown.toml Yes Recipe: project/apps/resources, team-shared targets, and optional trusted bootstrap commands
splashdown.local.toml No (gitignored) Per-checkout additional [targets.*] variants on top of the recipe's
splashdown.env No (gitignored) Generated KEY=VALUE env file, the default destination. Splashdown rewrites the keys the recipe declares and leaves everything else, so point [project] env_file at a shared .env when you prefer
mise.toml (or .envrc / devbox.json) Yes Your shell-env loader's config, gains a line that sources splashdown.env
existing AGENTS.md / independent CLAUDE.md Yes A managed block names each detected app's actual port variables, the configured env destination, and stable launch commands. No instruction file is created when neither exists, and a file another tool generates is left untouched

The agent-guidance block is regenerated by every init path, including --overwrite. It explains that recipe ranges are allocation pools rather than assigned ports, names the env destination your recipe configures, and directs agents away from numeric port overrides. It never contains an allocated value, so the block is safe to commit, and it tells agents to keep using the project's own scripts where those already read the environment. deinit removes only the complete sentinel-wrapped block. A CLAUDE.md that imports @AGENTS.md is skipped to avoid duplicate instructions after any older complete local block is removed. Symlinked and non-regular instruction files are never rewritten.

An AGENTS.md or CLAUDE.md that another tool generates is left alone. Splashdown recognizes the generator header at the top of the file, prints the marker it found, and asks you to add, replace, or remove the block in that file's source instead, because an edit here would be lost on the generator's next sync. When there is a block to carry over, Splashdown prints it between two rule lines so you can copy it straight into that source. deinit skips those files too. A file that only mentions generated content in its prose is still updated normally.

The registry at ~/.local/state/splashdown/ is machine-wide, so when two checkouts both want port 8081 splashdown gives one of them 8082, even across unrelated repos.

Provision output is change-aware: the first run (or any run that allocates a new port or rewrites a file) prints only the changed vars and writer lines. A no-op run (git pull --rebase on a checkout already provisioned) collapses to one line:

splashdown: up to date (3 vars, 2 files)

This is what you see through a hook manager when nothing actually changed.

The hook does nothing until the clone has Splashdown trust, so a cloned repository cannot make an installed Splashdown write recipe-controlled output. splash init grants no trust. Clone-local splash trust grants sync and, when [bootstrap] is currently present, authorizes those commands. It also installs the local post-checkout hook that init left for it. Only an actual linked-worktree creation can trigger bootstrap automatically. See Trusted worktree bootstrap.