# CLI Reference

Huskies ships as a single binary. Most interaction happens through the web UI or chat transports, but the CLI is used for initial setup and server control.

## huskies

Start the huskies server.

    huskies [OPTIONS]

### Options

Flag | Default | Description
--- | --- | ---
--port <PORT> | 3000 | HTTP port to listen on. Set the `HUSKIES_PORT` environment variable as an alternative.
--project <PATH> | current dir | Path to the project directory. Huskies looks for `.huskies/` here.
--help | — | Print help and exit.
--version | — | Print version and exit.

### Examples

    # Start on the default port
    huskies

    # Start on a custom port
    huskies --port 3001

    # Specify project directory explicitly
    huskies --project /path/to/project --port 3000

    # Using environment variable
    HUSKIES_PORT=3002 huskies

Multiple instances: Each worktree or project can run its own huskies instance on a different port. Use `HUSKIES_PORT` to avoid conflicts when running several instances simultaneously.

## huskies init

Initialise a project directory for use with huskies. Creates the `.huskies/` directory structure, default configuration files, and `.mcp.json`.

    huskies init [OPTIONS]

### Options

Flag | Default | Description
--- | --- | ---
--port <PORT> | 3000 | Port written into `.mcp.json` for MCP tool discovery.
--project <PATH> | current dir | Directory to initialise. Must be a git repository.
--help | — | Print help and exit.

### What it creates

Path | Description
--- | ---
`.huskies/project.toml` | Project-wide settings (QA mode, agent limits, timezone, etc.).
`.huskies/agents.toml` | Agent definitions for coder, QA, and mergemaster roles.
`.huskies/work/1_backlog/` | Pipeline stage directories (1 through 6).
`.huskies/specs/00_CONTEXT.md` | Placeholder project context file for the setup wizard.
`.huskies/specs/tech/STACK.md` | Placeholder tech stack file for the setup wizard.
`.mcp.json` | MCP server config so Claude Code discovers huskies' tools automatically.

Git required: The project directory must be a git repository. Run `git init` first if needed.

## huskies agent

Spawn a single agent process directly from the command line. This is the command the server uses internally when you run `start <number>` in chat — you rarely need to invoke it manually.

    huskies agent [OPTIONS]

### Options

Flag | Description
--- | ---
--story <ID> | Story ID slug to work on (e.g. `42_story_add_login`).
--agent <NAME> | Agent name from `agents.toml` to use (e.g. `coder-1`, `qa`).
--worktree <PATH> | Path to the git worktree the agent should work in.
--port <PORT> | Huskies server port, so the agent can call MCP tools.
--help | Print help and exit.

## Environment variables

Variable | Description
--- | ---
`HUSKIES_PORT` | Server port. Overrides the `--port` flag.
`ANTHROPIC_API_KEY` | Anthropic API key for agent sessions. Can also be set via the web UI on first use.
`GITEA_TOKEN` | Gitea API token used by the `script/release` script when publishing releases.

## Gateway event-push protocol

Project nodes can push pipeline status events to the gateway in real time over a WebSocket connection. The gateway fans each event out to all connected local subscribers.

### Connecting

1. Obtain a one-time join token: `POST /gateway/tokens` → `{"token":"…"}`
2. Open a WebSocket upgrade to `GET /gateway/events/push?token=TOKEN&project=PROJECT_NAME`
3. The token is consumed on upgrade. The project name is attached to every event the server broadcasts downstream.

### Sending events

Each message must be a JSON-encoded `StoredEvent` frame:

    // Stage transition
    {"type":"stage_transition","story_id":"42_story_login","from_stage":"2_current","to_stage":"3_qa","timestamp_ms":1700000000000}

    // Merge failure
    {"type":"merge_failure","story_id":"42_story_login","reason":"conflict in src/main.rs","timestamp_ms":1700000001000}

    // Story blocked
    {"type":"story_blocked","story_id":"42_story_login","reason":"retry limit exceeded","timestamp_ms":1700000002000}

The server does not send frames back. Any other frames received by the project node indicate an error or server restart — treat them as a disconnect signal.

### Reconnect with exponential back-off

Project nodes must reconnect on any disconnect. Use the following policy to avoid thundering herds after a gateway restart:

Parameter | Value
--- | ---
Initial delay | 1 s
Back-off multiplier | 2× per attempt
Maximum delay | 60 s
Jitter | ±10 % of the computed delay

Pseudocode:

    delay = 1.0          // seconds
    max_delay = 60.0

    loop:
        token = POST /gateway/tokens
        connect ws:/gateway/events/push?token=TOKEN&project=NAME
        while connected:
            send StoredEvent frames
        // disconnected — wait and retry
        jitter = delay * (random(0.9, 1.1))
        sleep(min(jitter, max_delay))
        delay = min(delay * 2, max_delay)

New token per connection: Each WebSocket upgrade consumes the join token. Request a fresh token for every reconnect attempt.

## Building from source

### Standard release build

    cargo build --release
    # Output: target/release/huskies

### Static Linux binary (musl)

Requires `cross`: `cargo install cross`.

    cross build --release --target x86_64-unknown-linux-musl

### Docker image

    docker compose -f docker/docker-compose.yml build

### Release script

Builds macOS arm64 and Linux amd64 binaries, bumps the version, tags the repo, and publishes a Gitea release with changelog and binaries attached.

    script/release 0.8.0