# How the `get-swarm-forge` Script Works: A Complete Guide to Installing a SwarmForge Forge

> Discover how the get-swarm-forge script works to download the SwarmForge repository, merge configurations, and build a self-contained development environment in your current directory. Get your forge up and running fast.

- Repository: [Robert C. Martin/swarm-forge](https://github.com/unclebob/swarm-forge)
- Tags: how-to-guide
- Published: 2026-08-28

---

**The `get-swarm-forge` script is a zsh-based bootstrap utility that downloads the SwarmForge repository, merges shared configuration files from the main branch with pack-specific files from individual branches, and assembles a self-contained development environment (forge) in the current directory.**

A **SwarmForge forge** is a complete, portable workspace that combines host scripts, constitution articles, role prompts, and pack configurations. The `get-swarm-forge` script automates the complex task of stitching these components together from multiple Git branches. This guide examines the script's internal workflow function-by-function, based on the source code in [`unclebob/swarm-forge`](https://github.com/unclebob/swarm-forge).

## Script Overview and Entry Point

The `get-swarm-forge` script resides at the repository root: [`get-swarm-forge`](https://github.com/unclebob/swarm-forge/blob/main/get-swarm-forge). It is designed to run standalone — you can curl it directly and execute it in any empty directory.

The script performs nine distinct stages, from environment setup through final verification.

### Default Configuration and Help Output

Lines 4–16 establish baseline settings:

- `FORGE_REPO_URL`: Defaults to `https://github.com/unclebob/swarm-forge`
- `PACK_NAMES`: The three standard packs — `two-pack`, `four-pack`, `six-pack`
- Help flags (`-h`, `--help`) trigger a usage message and clean exit

These defaults can be overridden via environment variables to support forks, custom branches, or offline installations.

## Environment Variable Configuration

Lines 18–26 implement a flexible configuration layer. The `get-swarm-forge` script recognizes four optional environment variables:

| Variable | Purpose |
|----------|---------|
| `SWARMFORGE_REPO_URL` | Alternate GitHub repository URL |
| `SWARMFORGE_BASE_BRANCH` | Branch to use for base files (default: `main`) |
| `SWARMFORGE_BASE_DIR` | Local directory containing pre-downloaded base files |
| `SWARMFORGE_PACKS_DIR` | Local directory containing pre-downloaded pack files |

The script also creates a temporary working directory with automatic cleanup on exit via `trap`.

## Three Core Helper Functions

Lines 27–63 define the script's operational building blocks.

### `download_branch`

Fetches a Git branch as a tarball and extracts it to a target directory. This avoids requiring Git CLI installation — only `curl` and standard Unix utilities are needed.

### `fail_missing`

Implements strict validation. If any required file is absent after assembly, the script aborts immediately with a descriptive error message rather than producing a broken forge.

### `copy_pack_template`

Copies core pack files while specifically **excluding** the three shared constitution articles: `engineering.prompt`, `workflow.prompt`, and `handoffs.prompt`. These shared articles come from the base branch instead, ensuring consistency across all packs.

## Stage-by-Stage Forge Assembly

### Step 1: Download the Base Branch (lines 68–74)

Unless `SWARMFORGE_BASE_DIR` is provided, the script downloads the main branch into `$tmp_dir/base`. It then validates that critical directories exist:
- `swarmforge/scripts/` — host runtime scripts
- `swarmforge/constitution/articles/` — shared constitution prompts

### Step 2: Create Directory Skeleton (lines 75–88)

The script establishes the forge's top-level structure:

```

./
├─ swarmforge/
│   ├─ scripts/
│   ├─ constitution/articles/
│   └─ roles/
└─ packs/

```

It populates this skeleton by copying:
- All scripts from `swarmforge/scripts/` in the base branch
- The three **shared** constitution articles (`engineering.prompt`, `workflow.prompt`, `handoffs.prompt`)
- The root `constitution.prompt` file
- The `lieutenant.prompt` role file

### Step 3: Install the `swarm` Launcher (lines 88–99)

The `swarm` executable serves as the user's entry point. The script handles two scenarios:

- **Base branch contains `swarm`**: Copy it directly
- **No pre-built `swarm`**: Generate a minimal wrapper that forwards to [`swarmforge/scripts/swarmforge.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/swarmforge.sh)

The wrapper is made executable with `chmod +x`. This design lets packs remain lightweight while ensuring consistent launch behavior.

### Step 4: Process Each Pack (lines 100–115)

For each pack in `PACK_NAMES` (`two-pack`, `four-pack`, `six-pack`):

1. **Determine source**: Use `$packs_src/$pack_name` if `SWARMFORGE_PACKS_DIR` is set, otherwise download the pack's branch
2. **Verify existence**: Call `fail_missing` if the pack directory is absent
3. **Copy template**: Invoke `copy_pack_template` to bring pack files into `packs/<name>/`
4. **Validate configuration**: Ensure [`swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge.conf) exists and that every role it references has a corresponding `.prompt` file

This validation catches configuration errors at install time rather than runtime.

### Step 5: Final Verification (lines 117–133)

The script declares an array of **mandatory files** and checks each:

- The `swarm` wrapper executable
- Core scripts in `swarmforge/scripts/`
- Shared constitution articles
- The lieutenant role prompt
- Each pack's [`swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge.conf)

Any missing item triggers `fail_missing` with a precise path indicator.

### Step 6: Completion Message (line 135)

Upon successful verification, the script prints:

```

SwarmForge forge installed. Run ./swarm to start the dashboard.

```

## Resulting Forge Layout

A complete forge follows this structure:

```

./
├─ swarm                    # launcher wrapper (executable)

├─ swarmforge/
│   ├─ scripts/             # host scripts from main branch

│   │   └─ swarmforge.sh    # core runtime

│   ├─ constitution/
│   │   ├─ constitution.prompt
│   │   └─ articles/
│   │       ├─ engineering.prompt   # shared

│   │       ├─ workflow.prompt      # shared

│   │       └─ handoffs.prompt      # shared

│   └─ roles/
│       └─ lieutenant.prompt
└─ packs/
    ├─ two-pack/
    │   └─ swarmforge/
    │       ├─ swarmforge.conf
    │       └─ roles/
    │           ├─ role-a.prompt
    │           └─ role-b.prompt
    ├─ four-pack/ ...
    └─ six-pack/ ...

```

The resulting directory is **self-contained**, **version-controllable**, and **relocatable**.

## Usage Examples

### Basic Installation

Run from an empty directory to create a fresh forge:

```bash
curl -fsSL https://raw.githubusercontent.com/unclebob/swarm-forge/main/get-swarm-forge > get-swarm-forge
chmod +x get-swarm-forge
./get-swarm-forge

# → SwarmForge forge installed. Run ./swarm to start the dashboard.

```

### Custom Repository and Branch

Override the source location for development forks:

```bash
SWARMFORGE_REPO_URL=https://github.com/yourorg/custom-swarm-forge \
SWARMFORGE_BASE_BRANCH=dev \
./get-swarm-forge

```

### Offline Installation with Pre-Downloaded Files

Speed up repeated installs or work air-gapped:

```bash
SWARMFORGE_BASE_DIR=/tmp/swarm-forge-main \
SWARMFORGE_PACKS_DIR=/tmp/swarm-forge-packs \
./get-swarm-forge

```

### Permanent Installation

Add to your PATH for frequent use:

```bash
cp get-swarm-forge ~/bin/
chmod +x ~/bin/get-swarm-forge

# Now run `get-swarm-forge` from any directory

```

## Key Source Files Reference

| File | Function in Installation |
|------|--------------------------|
| [`get-swarm-forge`](https://github.com/unclebob/swarm-forge/blob/main/get-swarm-forge) | Main bootstrap script |
| [[`swarmforge/scripts/swarmforge.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/swarmforge.sh)](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/swarmforge.sh) | Core runtime invoked by wrapper |
| [`swarmforge/constitution/articles/`](https://github.com/unclebob/swarm-forge/tree/main/swarmforge/constitution/articles) | Shared constitution prompts |
| [`swarmforge/roles/lieutenant.prompt`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/roles/lieutenant.prompt) | Required default role |
| `packs/<pack>/swarmforge/swarmforge.conf` | Pack configuration (branch-specific) |
| `packs/<pack>/swarmforge/roles/*.prompt` | Pack-specific role definitions |

## Summary

- The `get-swarm-forge` script is a **zsh bootstrapper** that assembles complete SwarmForge forges without requiring Git installation
- It **downloads and merges** files from multiple branches: shared infrastructure from `main`, pack-specific content from individual pack branches
- Three **helper functions** (`download_branch`, `fail_missing`, `copy_pack_template`) handle the core mechanical work
- **Environment variables** enable customization of source repository, branch, and local cache directories
- **Strict verification** at lines 117–133 ensures no broken forges are produced
- The output is a **self-contained directory** ready for version control, copying, or deployment

## Frequently Asked Questions

### What shell does `get-swarm-forge` require?

The script is written for **zsh**. While it uses portable patterns where possible, it expects zsh-specific features. Run with `zsh ./get-swarm-forge` explicitly if your default shell differs.

### Can I install `get-swarm-forge` without downloading it first?

Yes. Pipe directly from curl: `curl -fsSL ... | zsh`. However, saving the script first allows inspection, caching, and reuse — recommended for production environments.

### Why does the script exclude `engineering.prompt`, `workflow.prompt`, and `handoffs.prompt` from packs?

These three constitution articles are **shared across all packs** and sourced from the `main` branch instead. This design ensures consistency — changes to engineering standards propagate to all packs automatically when the base branch updates.

### What happens if a pack's [`swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge.conf) references a role with no prompt file?

The `get-swarm-forge` script **fails explicitly** during the validation phase at lines 100–115. It checks that every role declared in [`swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge.conf) has a corresponding `.prompt` file in `packs/<name>/swarmforge/roles/`. This catch-early approach prevents runtime errors in the SwarmForge dashboard.