Band Band

Project Configuration

Each Band project can include a .band/config.json file at the repository root. This file defines shell commands that run during workspace lifecycle events. Commit it to the repository so that all team members share the same workspace setup.

File Location

The configuration file is read from <worktree-root>/.band/config.json first, falling back to <project-root>/.band/config.json. The fallback handles the common case where the config file lives on the main branch but is .gitignored, so new worktrees don't contain it.

Schema

Both setup and teardown are single shell command strings — not arrays. Each runs through bash -c, so use &&, ;, or a multi-line shell snippet to chain steps.

{
  "setup": "npm install && npm run db:migrate",
  "teardown": "npm run db:reset",
  "workspace": {
    "copyFiles": [".env", ".env.local", "config/local.json"]
  }
}

Setup Command

The setup command runs after a workspace is created via band workspaces create (or the dashboard equivalent). It executes inside the new worktree directory with /opt/homebrew/bin and /usr/local/bin prepended to PATH so Homebrew tools are reachable. A failed setup is reported in the dashboard but does not delete the workspace.

"setup": "npm install && npm run db:migrate && cp .env.example .env"

Use the setup command for dependency installation, database migrations, environment file creation, or any other initialization your project needs.

Teardown Command

The teardown command runs before a workspace is removed via band workspaces remove. It runs inside the worktree (which still exists at this point) and is non-fatal — a teardown failure is logged and the workspace is removed anyway.

"teardown": "docker compose down -v"

Workspace File Copying

Workspaces are fresh git worktrees, so untracked files like .env, .env.local, local credential overrides, or IDE settings are not present after creation — git only checks out tracked files. Band can copy those files into a new worktree on creation, driven by either of two declarative sources at the project root:

Option A: .band/config.json::workspace.copyFiles

Explicit list of paths relative to the project root. Glob patterns (*, ?, [abc], {a,b}) are supported.

{
  "workspace": {
    "copyFiles": [
      ".env",
      ".env.local",
      "config/*.local.json",
      ".vscode/settings.json"
    ]
  }
}

Option B: .worktreeinclude

A .gitignore-syntax file at the project root, parallel to .gitignore. Patterns use the same grammar as .gitignore (anchored leading slash, ** segments, character classes, etc.).

Only files that match a pattern and are gitignored are copied (parity with Claude Code's own .worktreeinclude behavior). Tracked files are never duplicated — git already provides them via the worktree checkout.

# .worktreeinclude
.env*
config/*.local.json
.vscode/

Precedence and Semantics

  • When both sources are present, the resulting file sets are UNIONed and de-duped by absolute source path — neither source wins, and a file declared by both is copied exactly once.
  • The source is always the project's main checkout, not another worktree, so copies are deterministic regardless of which worktrees happen to exist at the time of creation.
  • Files are copied as regular files, not symlinks — edits inside the new worktree don't bleed back to the main checkout. Relative directory structure is preserved (config/local.json lands at <worktree>/config/local.json).
  • Missing source files are skipped with a warning, not treated as fatal. Stale entries in the config don't break workspace creation.
  • Copies run after git worktree add and before the setup script (and the first agent prompt, when one is supplied via band workspaces create --prompt), so the setup script can read .env / local credentials just like it can in the main checkout.

Out of scope (today): per-user overrides (.band/config.local.json), copying files back from a worktree to the main checkout on cleanup (workspace-files copy is one-way only), and variable substitution inside copied files.

Full Example

{
  "setup": "npm install && npx prisma db push && cp .env.example .env.local",
  "teardown": "docker compose down -v",
  "workspace": {
    "copyFiles": [".env", ".env.local", "config/*.local.json"]
  }
}