# How to Stop a SwarmForge Swarm: Complete Shutdown Guide

> Effectively stop a SwarmForge swarm by running the close-swarm script. This guide details the shutdown process and ensures proper cleanup of your sessions.

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

---

**The canonical way to stop a SwarmForge swarm is to run the `./close-swarm` wrapper script from your project root, which automatically discovers running sessions and delegates cleanup to [`swarm-cleanup.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarm-cleanup.sh).**

SwarmForge manages swarms through tmux sessions, a hand-off daemon, and tracked terminal windows. Proper shutdown requires terminating all three components in the correct order to prevent orphaned processes or socket conflicts. This guide covers the standard one-command approach and advanced manual options for troubleshooting.

## Using the close-swarm Wrapper

The `close-swarm` script at the repository root provides the simplest shutdown path. It handles all discovery steps automatically.

### Basic Usage

Run from your project directory:

```bash
./close-swarm

```

Or specify a different project root:

```bash
./close-swarm /path/to/project

```

Both forms locate the hidden `.swarmforge` directory and initiate the full cleanup sequence.

## What Happens During Shutdown

The `.close-swarm` script executes a five-stage teardown process:

1. **Locate swarm state** – Finds `.swarmforge/` containing `tmux-socket`, session lists, and window-ID files
2. **Identify running sessions** – Reads `sessions.tsv` and `windows.tsv` or queries the tmux socket directly
3. **Delegate to cleanup script** – Invokes [`swarmforge/scripts/swarm-cleanup.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/swarm-cleanup.sh) with discovered parameters
4. **Terminate hand-off daemon** – Runs `stop_handoff_daemon.bb` or manually kills the PID from `.swarmforge/daemon/handoffd.pid`
5. **Kill sessions and close windows** – Executes `tmux kill-session` for each session and closes terminal windows via the terminal-adapter backend

## Advanced: Manual Cleanup

For finer-grained control or debugging, invoke [`swarm-cleanup.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarm-cleanup.sh) directly with explicit parameters:

```bash
./swarmforge/scripts/swarm-cleanup.sh \
    /path/to/project/.swarmforge/tmux-socket \
    /path/to/project/.swarmforge/window-ids \
    session1 session2

```

This bypasses automatic discovery and targets specific resources.

## Key Source Files

| File | Purpose |
|------|---------|
| `close-swarm` | Wrapper script that discovers `.swarmforge/` state and delegates cleanup |
| [`swarmforge/scripts/swarm-cleanup.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/swarm-cleanup.sh) | Core logic for killing sessions, stopping daemon, and window cleanup |
| `swarmforge/scripts/stop_handoff_daemon.bb` | Babashka script for safe hand-off daemon termination |

## Summary

- **Primary command:** `./close-swarm` (optionally with project path)
- **Core implementation:** [`swarmforge/scripts/swarm-cleanup.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/swarm-cleanup.sh)
- **Daemon termination:** `swarmforge/scripts/stop_handoff_daemon.bb` or PID-based fallback
- **State directory:** `.swarmforge/` with `tmux-socket`, `sessions.tsv`, `windows.tsv`, and `daemon/handoffd.pid`

## Frequently Asked Questions

### Can I stop a SwarmForge swarm without using close-swarm?

Yes, but it requires manual steps. You must identify the tmux socket in `.swarmforge/tmux-socket`, kill sessions with `tmux -S <socket> kill-session`, terminate the hand-off daemon using the PID in `.swarmforge/daemon/handoffd.pid`, and close tracked terminal windows. The `close-swarm` wrapper exists to prevent errors from incomplete manual cleanup.

### What if the hand-off daemon doesn't stop cleanly?

The [`swarm-cleanup.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarm-cleanup.sh) script first attempts `stop_handoff_daemon.bb` for graceful shutdown. If Babashka is unavailable, it falls back to reading `handoffd.pid` and sending `kill` to that process. You can verify daemon status with `ps -p $(cat .swarmforge/daemon/handoffd.pid)` before and after running the stop command.

### Where does SwarmForge store running session information?

All runtime state lives in the `.swarmforge/` directory at your project root. Key files include `tmux-socket` (the tmux server socket), `sessions.tsv` and `windows.tsv` (session/window registries), and `window-ids` (terminal window identifiers for the active terminal adapter). The `close-swarm` script discovers and reads these automatically.

### How do I stop a swarm if I've deleted the .swarmforge directory?

Without `.swarmforge/`, automated discovery fails. You'll need to manually identify and kill the tmux process (`tmux list-sessions` or `ps aux | grep tmux`), terminate any running `handoffd` processes, and close terminal windows. Future SwarmForge runs will recreate `.swarmforge/` with fresh state.