Skip to main content
Repos often need setup after cloning before an agent can work productively: npm ci, go mod download, code generation, writing local config. Without it, every agent burns its first minutes (and tokens) rediscovering and running your setup commands. A repo hook is a Bash script committed to the repository that Murmur runs on the VM after cloning and before the agent starts. Committing the file enables it without configuration or spawn flags.

The prepare-workspace hook

Create the hook at this exact path in your repo:
The hook runs:
  • Once per prepared workspace: after all repos are cloned on their working branches, git identity and credentials are configured, and workspace plugins are installed; immediately before the agent process starts. It does not re-run when an agent wakes from sleep on the same VM. An agent resurrected onto a fresh VM prepares a fresh workspace and runs the hook again.
  • From the working branch the agent will operate on: the hook version that runs is the one the agent’s code will see, so a branch that changes the build system carries the matching hook change in the same commit.
  • With the repo’s checkout directory as the working directory, so relative paths resolve inside the repo.
  • Under /bin/bash: no executable bit or shebang required. Bash is the contract.
In multi-repo workspaces, each repo’s hook runs sequentially in workspace repo order.

Environment

The hook sees the same environment as the agent itself: Mounted secrets (workspace, developer, and spawn-time), model API keys, and file-mounted secrets are also available, exactly as the agent receives them.

Failure semantics

Hooks fail loudly. If the hook exits non-zero, the spawn fails with an error naming the repo and the hook: the agent never starts in a workspace whose declared setup failed. There is no retry: fix the hook (or the setup it runs) and spawn again. All hooks in a workspace share a 5-minute total budget. A hook still running when the budget expires is killed and the spawn fails with a timeout error. Heavier setup belongs in a custom image: bake the toolchain into the image, and use the hook only for the per-branch remainder. Hook output streams to the VM’s system log in real time, and the tail of the output is captured in the failure error so you can see why a hook failed.

Organizing helper scripts

.murmur/hooks/ is free-form. Murmur executes only the hook names it recognizes (prepare-workspace.sh) and ignores everything else, so you can organize sub-scripts however you want:
If a .murmur/hooks/ directory exists but contains no recognized hook (for example, a misspelled file name), Murmur logs a warning rather than silently doing nothing.

Guidelines

Hook output lands in logs, and the failure tail is captured with the error. Never echo secrets, and never set -x around commands that take credentials in arguments.
  • Set up the workspace; don’t mutate remotes. The hook runs before Murmur’s git/gh instrumentation is installed, so pushes or gh calls made from a hook won’t generate PR tracking or timeline events. Save remote operations for the agent.
  • Keep it fast. The hook delays agent start on every spawn. Anything stable across branches (toolchains, system packages, large dependency trees) belongs in a custom image; the hook is for what changes with the code.
  • Make it idempotent-friendly. The hook runs once per prepared workspace, but a resurrected agent gets a fresh VM and runs it again: don’t depend on state from a previous run.

Hooks vs. custom images