# squadron engage

Start Squadron as a long-running background service. By default, Squadron launches the local command center web UI. Pass `--headless` to run without a UI, or declare a `command_center` block in your config to connect to a remote one instead.

## Usage

```bash
squadron engage [flags]
```

Run `engage` from the root of your Squadron project directory. All runtime state lives in a `.squadron/` folder created next to your HCL files, so the directory you're in determines which project the daemon belongs to.

> **Important:** `squadron disengage` must be run from the **same directory** you engaged from — it finds the running daemon via `<project>/.squadron/engage.pid`. If you're somewhere else, either `cd` back or pass `-c /path/to/project`.

## Project State (`.squadron/`)

The first run creates `.squadron/` in the current directory. Everything Squadron tracks for this project lives there:

| Path | Purpose |
|------|---------|
| `vars.vault` | Encrypted variable store (API keys, secrets) |
| `vault.key` | Vault passphrase (file vault provider, `0600` perms) |
| `store.db` | SQLite mission/task/session state for resume |
| `plugins/<platform>/<name>/<version>/` | Cached plugin binaries |
| `mcp/<platform>/<name>/<version>/` | Cached MCP server binaries |
| `command-center/<platform>/<version>/` | Cached command center binary (when the local UI is launched) |
| `engage.pid` | PID of the running daemon |
| `engage.log` | Daemon stdout/stderr |
| `engage.ready` | Ready signal file (parent ↔ child IPC during fork) |

Multiple projects can run simultaneously on the same host — each gets its own `.squadron/`. Add `.squadron/` to your `.gitignore`.

## Flags

| Flag | Description |
|------|-------------|
| `-c, --config` | Path to config directory (default: `.`) |
| `--headless` | Skip launching the local command center UI |
| `--cc-port` | Port for the local command center (default: `8080`) |
| `--foreground` | Run in the terminal instead of forking to background |
| `--init` | Auto-initialize Squadron if not already initialized |

A `command_center` block in your config takes precedence — Squadron connects to the remote command center and skips the local UI. Passing `--headless` alongside a `command_center` block is an error.

## What it does

1. **Validates the directory** — refuses to run inside `~`, `/`, `/tmp`, etc., and errors on nested `.squadron/` projects.
2. **Runs the [quickstart wizard](/cli/quickstart)** if there's no `.hcl` config and no `.squadron/` directory (interactive terminals only).
3. **Auto-initializes the vault** in all other first-run cases.
4. **Forks to the background** unless `--foreground` is set.
5. **Launches the command center UI** unless `--headless` is set or a `command_center` block is declared.
6. **Installs a system service** (launchd on macOS, systemd user unit on Linux) so Squadron starts automatically on boot.

Each Squadron project gets its own PID file in `<project>/.squadron/engage.pid`, so multiple projects can run simultaneously on the same host.

## Examples

### Default

```bash
squadron engage
```

Runs Squadron in the background, launches the local command center on `http://localhost:8080`, and opens your browser.

### Headless

```bash
squadron engage --headless
```

Runs in the background with no UI. Use this when missions run purely via schedules, webhooks, or remote command center.

### Foreground mode

```bash
squadron engage --foreground
```

Keeps the process attached to the terminal. Useful for debugging or when running inside Docker / systemd / a process manager.

### Custom port

```bash
squadron engage --cc-port 9090
```

## Stopping

```bash
squadron disengage
```

Sends SIGTERM to the running daemon, removes the system service, cleans up the command center process. See [disengage](/cli/disengage).

## Remote Command Center

If your config declares a `command_center` block:

```hcl
command_center {
  url           = "wss://command-center.example.com/ws"
  instance_name = "my-instance"
}
```

…Squadron connects outbound to that command center and skips the local UI automatically. See [Command Center](/config/command_center) for all fields and production patterns (auto-reconnect, webhooks, variable interpolation).

## Behavior with Invalid Config

`engage` is forgiving about config issues:

- **HCL syntax errors or missing required fields** — Squadron starts in degraded mode; unless `--headless` was passed, the UI lets you fix files in place.
- **Missing variables** — Squadron starts; the UI lets you add them.
- **Storage open failure** — Squadron exits (this is a real environment problem, not user-fixable from the UI).

This means you can deploy a half-finished config and finish setup through the browser.

## Schedules & Triggers

In engage mode, missions with `schedule` blocks run automatically on their cron timers. Missions with a `trigger` block expose a webhook through the command center.

See [Schedules & Triggers](/missions/schedules) for details.

## Docker

The official image sets `SQUADRON_CONTAINER=1`, which tells Squadron to run in the foreground. The command center still launches by default — browser auto-open is always skipped inside containers. Pass `--headless` if you don't need the UI:

```bash
docker run -v ./my-project:/config -p 8080:8080 \
  ghcr.io/mlund01/squadron engage
```

See the [Docker guide](/getting-started/docker).

## See Also

- [quickstart](/cli/quickstart) — Interactive setup wizard
- [disengage](/cli/disengage) — Stop the daemon
- [Schedules & Triggers](/missions/schedules) — Automatic scheduling and webhooks
- [Docker](/getting-started/docker) — Running in containers
