Hooks
Hooks are repository-local executable files under .shipper/hooks/. There is no user-level hook
mechanism. Shipper runs a hook only when a supported filename exists in the checkout and the file is
executable.
Stage hooks
Section titled “Stage hooks”Stage hooks run immediately before or after a supported Shipper workflow stage.
| Stage | Pre-stage hook | Post-stage hook |
|---|---|---|
new | pre-new | post-new |
groom | pre-groom | post-groom |
design | pre-design | post-design |
plan | pre-plan | post-plan |
implement | pre-implement | post-implement |
pr-review | pre-pr-review | post-pr-review |
merge | pre-merge | post-merge |
The stage names setup, unblock, adopt, reset, and init do not fire stage hooks.
Creating files such as .shipper/hooks/pre-unblock or .shipper/hooks/post-init will not run.
Worktree lifecycle hooks
Section titled “Worktree lifecycle hooks”Worktree lifecycle hooks are separate from pre-<stage> and post-<stage> hooks.
| Hook | Workflow point |
|---|---|
worktree-setup | Runs after Shipper creates a temporary worktree and after the configured installCommand finishes, when one is configured. |
worktree-teardown | Runs during cleanup before Shipper discovers or signals processes whose cwd is inside the temporary worktree, and before Shipper removes that worktree. |
These hooks run for temporary worktrees created by new, groom, design, plan, implement,
pr-open and pr-review. They do not run for merge, setup, unblock,
adopt, reset, or init.
Repositories should use worktree-teardown to stop background services gracefully. After the hook
settles, Shipper unconditionally stops anything still working inside the workspace: SIGTERM
comes first, followed after a fixed two-second grace period by SIGKILL, with one further second
allowed for exit. A failure to inspect or terminate a holder produces a warning but does not change
stage success or prevent workspace removal. No hook timeout, flag, environment variable, setting,
or command option disables or tunes this enforcement schedule.
Exit codes
Section titled “Exit codes”| Hook type | Non-zero exit behavior |
|---|---|
pre-<stage> | Aborts the stage. |
post-<stage> | Warns and continues. |
worktree-setup | Warns and continues. |
worktree-teardown | Warns and continues. |
Timeouts
Section titled “Timeouts”Shipper enforces hook timeouts with the hookTimeoutMinutes setting. The default is 10 minutes.
Set it to 0 to disable timeout enforcement.
hookTimeoutMinutes governs only hook execution. It does not alter the fixed process-termination
schedule that begins after worktree-teardown settles.
| Hook type | Timeout behavior |
|---|---|
pre-<stage> | Aborts the stage. |
post-<stage> | Warns and continues. |
worktree-setup | Aborts worktree setup. |
worktree-teardown | Warns and continues. |
Cancellation
Section titled “Cancellation”SIGINT or SIGTERM cancellation always aborts the current Shipper operation, including hooks that otherwise warn and continue on non-zero exit or timeout.
Non-executable files
Section titled “Non-executable files”If a supported hook file exists but is not executable, Shipper warns and skips it without running
it. Run chmod +x .shipper/hooks/<hook-name> to make the hook executable.
Runtime context
Section titled “Runtime context”Shipper passes runtime context to hook scripts through environment variables.
For full per-variable detail, see Environment variables.
| Hook type | Variables |
|---|---|
| Stage hooks | SHIPPER_STAGE, SHIPPER_ISSUE_NUMBER, SHIPPER_BRANCH_NAME |
| Worktree lifecycle hooks | SHIPPER_STAGE, SHIPPER_ISSUE_NUMBER, SHIPPER_BRANCH_NAME, SHIPPER_WORKTREE_PATH |
SHIPPER_ISSUE_NUMBER is empty for the new stage because no issue exists yet.
Related: dependency install
Section titled “Related: dependency install”Dependency bootstrap consists of the configured installCommand followed by executable
.shipper/hooks/worktree-setup. worktree-setup can be part of the bootstrap for monorepos and
multi-package repositories, and it can be the only configured bootstrap when no single
installCommand is appropriate. An executable worktree-setup suppresses the no-bootstrap advisory
warning even when installCommand is unset or empty.
Bare shipper setup --assist does not create hooks by default. In user-level assisted setup, the
assistant first tries to express bootstrap as a single installCommand, including compound commands
for multi-area repositories. Creating .shipper/hooks/worktree-setup during that flow is an
explicit committed-footprint opt-in for bootstrap cases that genuinely cannot fit one command.
A non-zero installCommand exit is fatal to the stage — Shipper stops before the agent runs and
reports the failing command and its exit code (a command-not-found exit also notes the tool appears
missing or not on PATH). This is distinct from .shipper/hooks/worktree-setup, whose non-zero
exit warns and continues. installCommand is not a hook, so it is absent from the hook exit-code
behavior above.
Both installCommand and worktree-setup share the hookTimeoutMinutes timeout setting. See
Settings for full configuration semantics.