diff --git a/.huskies/AGENT.md b/.huskies/AGENT.md
index 0c8a3f86..7100f6a7 100644
--- a/.huskies/AGENT.md
+++ b/.huskies/AGENT.md
@@ -56,7 +56,7 @@ There are no exceptions. The merge gate runs `source-map-check` and rejects the
Before committing, run `cargo run -p source-map-gen --bin source-map-check -- --worktree . --base master` and address every missing-docs direction it prints. If you added a new module file (e.g. `foo.rs` or `foo/mod.rs`), the FIRST line of that file MUST be a `//! What this module is for` doc comment.
## Documentation
-Docs live in `website/docs/*.html` (static HTML), **not** Markdown files. When a story asks you to document something, edit the relevant `.html` file in `website/docs/`.
+Docs live in `website/app/docs/*.tsx` (Next.js pages), **not** Markdown files. When a story asks you to document something, edit the relevant `.tsx` file under `website/app/docs/`. Run `npm run build` in `website/` to verify your changes render correctly.
## Configuration files
- Agent config: `.huskies/agents.toml` (preferred) or `[[agent]]` blocks in `.huskies/project.toml`
diff --git a/website/.gitignore b/website/.gitignore
new file mode 100644
index 00000000..c03a1711
--- /dev/null
+++ b/website/.gitignore
@@ -0,0 +1,4 @@
+node_modules/
+.next/
+out/
+next-env.d.ts
diff --git a/website/README.md b/website/README.md
new file mode 100644
index 00000000..45c65894
--- /dev/null
+++ b/website/README.md
@@ -0,0 +1,57 @@
+# Huskies Website
+
+Static marketing and documentation site, built with Next.js (`output: 'export'`).
+
+## Development
+
+```bash
+npm install
+npm run dev # starts dev server at http://localhost:3000
+```
+
+## Build
+
+```bash
+npm install
+npm run build # produces out/ directory
+```
+
+The `out/` directory is a fully static export — plain HTML, CSS, JS, and assets. No Node.js required at runtime.
+
+## Deploy
+
+Serve the `out/` directory with any static file server. nginx example:
+
+```nginx
+server {
+ listen 80;
+ server_name huskies.dev;
+ root /path/to/out;
+ index index.html;
+
+ location / {
+ try_files $uri $uri.html $uri/ =404;
+ }
+}
+```
+
+## Pages
+
+| Route | File |
+|-------|------|
+| `/` | `app/page.tsx` |
+| `/privacy` | `app/privacy/page.tsx` |
+| `/docs` | `app/docs/page.tsx` |
+| `/docs/quickstart` | `app/docs/quickstart/page.tsx` |
+| `/docs/pipeline` | `app/docs/pipeline/page.tsx` |
+| `/docs/commands` | `app/docs/commands/page.tsx` |
+| `/docs/configuration` | `app/docs/configuration/page.tsx` |
+| `/docs/cli` | `app/docs/cli/page.tsx` |
+| `/docs/transports` | `app/docs/transports/page.tsx` |
+
+## Tech
+
+- Next.js 14 App Router with `output: 'export'`
+- TypeScript
+- `next/font/google` for self-hosted Bricolage Grotesque and Karla fonts
+- No server components with dynamic data, no API routes, no server actions
diff --git a/website/app/docs/cli/page.tsx b/website/app/docs/cli/page.tsx
new file mode 100644
index 00000000..a7066911
--- /dev/null
+++ b/website/app/docs/cli/page.tsx
@@ -0,0 +1,384 @@
+/** CLI reference — flags and subcommands for the huskies binary. */
+import type { Metadata } from 'next'
+
+/** Page metadata for the CLI reference. */
+export const metadata: Metadata = {
+ title: 'CLI Reference — Huskies Docs',
+ description: 'Command-line reference for huskies, huskies init, and related subcommands.',
+}
+
+/** Renders the CLI reference for huskies command-line flags. */
+export default function CliPage() {
+ return (
+ <>
+
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.
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
+
+
+ Obtain a one-time join token: POST /gateway/tokens →{' '}
+ {'{"token":"…"}'}
+
+
+ Open a WebSocket upgrade to{' '}
+ GET /gateway/events/push?token=TOKEN&project=PROJECT_NAME
+
+
+ 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:
+
+ 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
+
+ >
+ )
+}
diff --git a/website/app/docs/commands/page.tsx b/website/app/docs/commands/page.tsx
new file mode 100644
index 00000000..9defb66b
--- /dev/null
+++ b/website/app/docs/commands/page.tsx
@@ -0,0 +1,209 @@
+/** Bot commands reference — full list of chat transport commands. */
+import type { Metadata } from 'next'
+
+/** Page metadata for the bot commands reference. */
+export const metadata: Metadata = {
+ title: 'Bot Commands — Huskies Docs',
+ description:
+ 'Full reference of huskies bot commands available in Matrix, Slack, WhatsApp, Discord, and the web UI.',
+}
+
+/** Renders the full bot commands reference page. */
+export default function CommandsPage() {
+ return (
+ <>
+
Bot Commands
+
+ Commands available in every chat transport (Matrix, Slack, WhatsApp, Discord) and the built-in web
+ UI. Commands are case-insensitive. Run help in any chat to see the list.
+
+
+
+ How to invoke: In chat rooms, address the bot first (e.g.{' '}
+ @huskies start 42) or enable ambient mode so it responds to all messages. In the web
+ UI, type commands directly.
+
+
+
Pipeline management
+
+
+
status
+
+ Show pipeline status and agent availability. Use status <number> for a
+ detailed triage dump on a specific story.
+
+
+
+
start
+
+ Start an agent on a story: start <number>. To use the opus model:{' '}
+ start <number> opus.
+
+
+
+
move
+
+ Move a work item to a pipeline stage: move <number> <stage>. Stages:{' '}
+ backlog, current, qa, merge,{' '}
+ done.
+
+
+
+
show
+
+ Display the full text of a work item: show <number>.
+
+
+
+
delete
+
+ Remove a work item from the pipeline: delete <number>.
+
+
+
+
unblock
+
+ Reset a blocked story: unblock <number>. Clears the blocked flag and resets
+ the retry count.
+
+
+
+
assign
+
+ Pre-assign a model to a story before starting: assign <number> <model>{' '}
+ (e.g. assign 42 opus).
+
+
+
+
backlog
+
+ Show all items in the backlog with dependency satisfaction status — which are ready to
+ start and which are still waiting on other stories.
+
+
+
+
depends
+
+ Set story dependencies: depends <number> [dep1 dep2 ...]. Call with no deps
+ to clear all dependencies.
+
+
+
+
timer
+
+ Schedule a deferred agent start: timer <number> HH:MM. List all timers:{' '}
+ timer list. Cancel: timer cancel <number>. Times are interpreted
+ in the project timezone.
+
+
+
+
+
Worktrees
+
+
+
rmtree
+
+ Delete the worktree for a story without removing the story from the pipeline:{' '}
+ rmtree <number>. Useful for freeing disk space on a story that needs to be
+ restarted.
+
+
+
+
+
Observability
+
+
+
cost
+
+ Show token spend: 24h total, top stories, breakdown by agent type, and all-time total.
+
+
+
+
coverage
+
+ Show test coverage from the cached baseline. Use coverage run to rerun the full
+ test suite and regenerate the report.
+
+
+
+
git
+
+ Show git status for the main repository: current branch, uncommitted changes, and ahead/behind
+ remote.
+
+
+
+
htop
+
+ Live system and agent process dashboard. Use htop to start,{' '}
+ htop 10m to run for 10 minutes, htop stop to stop.
+
+
+
+
run_tests
+
+ Run the project's test suite (script/test) and show a pass/fail summary with
+ output. Use run_tests <number> to run tests inside a specific story's
+ worktree instead of the project root.
+
+
+
+
loc
+
+ Show top source files by line count: loc (top 10), loc <N> for
+ N files, or loc <filepath> for a specific file.
+
+
+
+
overview
+
+ Show an implementation summary for a merged story: overview <number>.
+
+
+
+
unreleased
+
+ Show stories merged to master since the last release tag.
+
+
+
+
+
Server management
+
+
+
rebuild
+
Rebuild the huskies server binary and restart the process.
+
+
+
reset
+
+ Clear the current Claude Code session and start a fresh context window.
+
+
+
+
+
Setup & configuration
+
+
+
setup
+
+ Show setup wizard progress. Drive the wizard from chat: setup generate,{' '}
+ setup confirm, setup skip, setup retry.
+
+
+
+
ambient
+
+ Toggle ambient mode for the current room: ambient on or{' '}
+ ambient off. In ambient mode the bot responds to all messages, not just addressed
+ ones.
+
+
+
+
help
+
Show the list of available commands.
+
+
+ >
+ )
+}
diff --git a/website/app/docs/configuration/page.tsx b/website/app/docs/configuration/page.tsx
new file mode 100644
index 00000000..0dac07d7
--- /dev/null
+++ b/website/app/docs/configuration/page.tsx
@@ -0,0 +1,459 @@
+/** Configuration reference — project.toml, agents.toml, and bot.toml docs. */
+import type { Metadata } from 'next'
+
+/** Page metadata for the configuration reference. */
+export const metadata: Metadata = {
+ title: 'Configuration — Huskies Docs',
+ description: 'Reference for project.toml, agents.toml, and bot.toml configuration files.',
+}
+
+/** Renders the configuration reference for all huskies TOML files. */
+export default function ConfigurationPage() {
+ return (
+ <>
+
Configuration
+
+ Huskies is configured via three TOML files in your .huskies/ directory. All files are
+ created by huskies init with sensible defaults.
+
+
+
project.toml
+
+ Project-wide settings. Lives at .huskies/project.toml.
+
+
+
+
+
+
Key
+
Type
+
Default
+
Description
+
+
+
+
+
default_qa
+
string
+
+ "server"
+
+
+ Default QA mode. One of "server" (automated gate run),{' '}
+ "agent" (spawn a QA agent), or "human" (manual
+ approval).
+
+
+
+
default_coder_model
+
string
+
+ "sonnet"
+
+
+ Default model for coder agents. Only agents matching this model are auto-assigned. Use{' '}
+ "opus" on individual stories for complex tasks.
+
+
+
+
max_coders
+
integer
+
+ 3
+
+
+ Maximum concurrent coder agents. Stories wait in 2_current/ when all slots are
+ full.
+
+
+
+
max_retries
+
integer
+
+ 3
+
+
+ Maximum retries per story per pipeline stage before marking it as blocked. Set to{' '}
+ 0 to disable.
+
+
+
+
base_branch
+
string
+
auto-detected
+
+ Base branch for merges and agent prompts. When unset, huskies reads the current HEAD branch.
+
+
+
+
rate_limit_notifications
+
bool
+
+ false
+
+
+ Send chat notifications when API soft rate limits are hit. Hard blocks and story-blocked
+ notifications are always sent.
+
+
+
+
timezone
+
string
+
+ "UTC"
+
+
+ IANA timezone for timer scheduling (e.g. "Europe/London",{' '}
+ "America/New_York"). Timer HH:MM inputs are interpreted in this
+ timezone.
+
+
+
+
+
+
Component setup
+
+ The [[component]] sections define how to build and verify each part of your project.
+ The server runs setup commands before accepting a story's QA and teardown commands after
+ merging.
+
+ Place a file at .huskies/AGENT.md in your project root to append project-specific
+ guidance to every agent's initial prompt at spawn time.
+
+
+
How it works
+
+
+ Huskies reads .huskies/AGENT.md each time an agent is spawned — no caching, no
+ restart required.
+
+
+ The file content is appended after the baked-in agent prompt, so project guidance
+ refines core instructions without overriding them.
+
+
Applies to all agent roles: coder, QA, mergemaster, and supervisor.
+
+ If the file is missing or empty, agents spawn normally — no warnings, no errors.
+
+
+ When the file exists and is non-empty, a single INFO log line is emitted showing the
+ file path and byte count.
+
+
+
+
Ordering
+
+
+ Baked-in agent prompt (from agents.toml or project.toml)
+
+
+ Project-local content from .huskies/AGENT.md
+
+
Resume context (only on agent restart after a gate failure)
+
+
+
Example
+
+ {`# .huskies/AGENT.md
+
+## Documentation
+Docs live in \`website/docs/*.html\`, not Markdown files.
+Edit the relevant .html file when a story asks for documentation.
+
+## Quality gates
+Run \`cargo clippy -- -D warnings\` before committing. Zero warnings allowed.`}
+
+
+ Edit the file at any time — the next agent spawn picks up the latest content automatically.
+
+
+
bot.toml
+
+ Chat transport configuration. Lives at .huskies/bot.toml. This file is gitignored as
+ it contains credentials. Copy the appropriate example file to get started:
+
+ Only one transport can be active at a time. See the{' '}
+ Chat transports guide for setup instructions for each platform.
+
+
+
Common fields
+
+
+
+
Key
+
Description
+
+
+
+
+
enabled
+
+ Set to true to activate the bot. Set to false to disable without
+ removing the file.
+
+
+
+
transport
+
+ Transport type: "matrix", "whatsapp",{' '}
+ "slack", or "discord".
+
+
+
+
display_name
+
Optional. Bot display name in chat messages.
+
+
+
history_size
+
+ Optional. Maximum conversation turns to remember per room/user (default: 20).
+
+
+
+
+
+
Gateway: aggregated chat stream
+
+ When running huskies --gateway, you can configure a single bot that receives pipeline
+ notifications from all registered projects. Events are prefixed with{' '}
+ [project-name] so you can tell them apart in one shared room.
+
+
+ The aggregated stream is configured entirely in the gateway's{' '}
+ .huskies/bot.toml — no per-project bot config is required and no per-project
+ files need to change when you add a new project to projects.toml.
+
+
+
Enabling the aggregated stream
+
+ Add or edit <gateway-config-dir>/.huskies/bot.toml and set{' '}
+ enabled = true. The gateway bot will automatically poll every project listed in{' '}
+ projects.toml and forward events to the configured rooms.
+
+ Set to false to disable the aggregated stream without disabling the gateway bot
+ entirely. Per-project configs are never consulted.
+
+
+
+
aggregated_notifications_poll_interval_secs
+
integer
+
+ 5
+
+
+ How often (in seconds) the gateway polls each project's /api/events{' '}
+ endpoint. Lower values reduce notification latency.
+
+
+
+
+
+
No-duplicate guarantee
+
+ Per-project bots and the gateway aggregated stream send to different rooms — they are
+ independent. Events from a per-project bot go to that project's rooms; events from the gateway
+ stream go to the gateway rooms. The same event will never appear twice in either room.
+
+
+
Unreachable projects
+
+ If a per-project server is temporarily unreachable, the gateway logs a warning and skips that
+ project for the current poll cycle. All other projects continue to deliver notifications normally.
+ No configuration change is required — the poller retries on the next interval.
+
+
+
Supported event types
+
+ The aggregated stream delivers the following event types, each prefixed with the project name:
+
+ Huskies is a story-driven development server. You write stories (feature requests) with acceptance
+ criteria; huskies spawns coding agents in isolated git worktrees, runs them through quality gates, and
+ squash-merges the result to your main branch — all without you writing a line of code.
+
+
+ It ships as a single Rust binary with an embedded React frontend. No separate database or build
+ infrastructure required.
+
+
+
How it works
+
+
+
+ Write a story. Describe the change with acceptance criteria via the web UI, a chat
+ room (Matrix, WhatsApp, Slack), or by dropping a Markdown file in{' '}
+ .huskies/work/1_backlog/.
+
+
+
+
+ Agent picks it up. Run start <number> (or configure
+ auto-start). A coder agent creates a feature branch, implements the code, and writes tests against
+ your criteria.
+
+
+
+
+ Quality gates run. Linters, tests, and compilation checks run automatically when
+ the agent exits. Nothing moves forward until everything passes.
+
+
+
+
+ QA review. A QA agent verifies each acceptance criterion, runs your test suite,
+ and either approves or rejects with detailed findings.
+
+
+
+
+ Merge & land. A merge agent resolves conflicts and squash-merges to your main
+ branch. The worktree is cleaned up automatically.
+
+
+
+
+
Key concepts
+
+ Stories are Markdown files with YAML front matter. They live in{' '}
+ .huskies/work/ and move through pipeline stages as work progresses.
+
+
+ Agents are Claude Code sessions that run autonomously in git worktrees. Each story gets
+ its own isolated worktree so multiple stories can be in flight simultaneously.
+
+
+ MCP tools give Claude Code sessions programmatic access to the pipeline: creating
+ stories, starting agents, checking status, recording test results.
+
+ >
+ )
+}
diff --git a/website/app/docs/pipeline/page.tsx b/website/app/docs/pipeline/page.tsx
new file mode 100644
index 00000000..89cd83b0
--- /dev/null
+++ b/website/app/docs/pipeline/page.tsx
@@ -0,0 +1,200 @@
+/** Pipeline stages reference — describes the six-stage story workflow. */
+import type { Metadata } from 'next'
+
+/** Page metadata for the pipeline stages guide. */
+export const metadata: Metadata = {
+ title: 'Pipeline Stages — Huskies Docs',
+ description:
+ 'How work items move through the huskies pipeline: backlog, current, QA, merge, done.',
+}
+
+/** Renders the pipeline stages reference page. */
+export default function PipelinePage() {
+ return (
+ <>
+
Pipeline Stages
+
+ Work items move through six stages from idea to archive. Each stage is a directory under{' '}
+ .huskies/work/. Moving a file between directories advances the story.
+
+
+
+
+
1
+
Backlog
+
+ 1_backlog/ — New work items awaiting prioritisation. Stories sit here until
+ you decide to start them.
+
+
+
+
2
+
Current
+
+ 2_current/ — Work in progress. Run start <number> to
+ assign a coder agent. Multiple stories can be in current simultaneously (up to{' '}
+ max_coders).
+
+
+
+
3
+
QA
+
+ 3_qa/ — Quality review. The server automatically moves stories here when the
+ coder agent passes all quality gates. A QA agent (or a human) verifies each acceptance criterion.
+
+
+
+
4
+
Merge
+
+ 4_merge/ — Ready to merge. Stories reach here after QA approval. Run{' '}
+ start <number> to trigger the mergemaster agent, which squash-merges to your
+ base branch.
+
+
+
+
5
+
Done
+
+ 5_done/ — Merged and complete. The mergemaster moves stories here after a
+ successful merge. Auto-swept to archive after 4 hours.
+
+
+
+
6
+
Archived
+
+ 6_archived/ — Long-term storage. Stories land here automatically from done.
+ Use overview <number> to see the implementation summary for any archived
+ story.
+
+
+
+
+
Work item types
+
+ All work item types move through the same pipeline. They differ in naming convention and workflow:
+
+
+
+
+
+
Type
+
Filename pattern
+
When to use
+
+
+
+
+
story
+
+ 42_story_add_login.md
+
+
New functionality. Requires acceptance criteria and tests.
+
+
+
bug
+
+ 43_bug_login_crashes.md
+
+
Defect in existing functionality. Write a failing test first.
+
+
+
spike
+
+ 44_spike_auth_options.md
+
+
Time-boxed research to reduce uncertainty. No production code.
+
+
+
refactor
+
+ 45_refactor_extract_auth.md
+
+
Code quality improvement. Behaviour must not change.
+
+
+
+
+
Story file format
+
Every work item is a Markdown file with YAML front matter:
+
+ {`---
+name: "Short human-readable name"
+qa: agent # optional: override default_qa
+agent: opus # optional: request specific agent model
+---
+
+# Story 42: Add login endpoint
+
+## User Story
+As a user, I want to log in with email and password so that I can access my account.
+
+## Acceptance Criteria
+- [ ] POST /auth/login accepts email and password
+- [ ] Returns a JWT token on success
+- [ ] Returns 401 on invalid credentials
+- [ ] Rate-limited to 5 attempts per minute per IP
+
+## Out of Scope
+- OAuth / social login
+- Password reset flow`}
+
+
+
Acceptance criteria tracking
+
+ Acceptance criteria use Markdown checkboxes (- [ ]). The QA agent reviews each criterion
+ against the code diff and marks passing criteria as - [x] in the story file. Criteria
+ that fail are noted in the QA report.
+
+
+
+ Golden rule: No code is written until acceptance criteria are captured in the story.
+ The agent reads the story file to understand what to build and what to test.
+
+
+
Filesystem watcher
+
+ The server watches .huskies/work/ for changes. When a file is created, moved, or
+ modified, the watcher auto-commits with a deterministic message and broadcasts a WebSocket update to
+ the frontend. This means:
+
+
+
+ You can drag a story between stage folders in your IDE and it advances automatically.
+
+
MCP tools only need to write or move files — the watcher handles git commits.
+
The pipeline board updates in real time without a manual refresh.
+
+
+
Blocked stories
+
+ A story is marked blocked when it fails the same pipeline stage more than{' '}
+ max_retries times (default: 3). Blocked stories require manual intervention:
+
+
+
+ Run status <number> to see the failure log.
+
+
Fix the underlying issue (update the story, fix a build problem, etc.).
+
+ Run unblock <number> to reset the retry counter.
+
+
+ Run start <number> to try again.
+
+
+
+
Dependencies
+
+ Stories can declare dependencies using the depends command. A story with unresolved
+ dependencies waits in 2_current/ until all its dependencies have reached{' '}
+ 5_done/.
+
+
+ {`depends 45 42 43 # story 45 waits for 42 and 43 to finish\ndepends 45 # clear all dependencies`}
+
+ >
+ )
+}
diff --git a/website/app/docs/quickstart/page.tsx b/website/app/docs/quickstart/page.tsx
new file mode 100644
index 00000000..934e1cc4
--- /dev/null
+++ b/website/app/docs/quickstart/page.tsx
@@ -0,0 +1,161 @@
+/** Quickstart guide — Docker, binary, and source install instructions. */
+import type { Metadata } from 'next'
+
+/** Page metadata for the quickstart guide. */
+export const metadata: Metadata = {
+ title: 'Quickstart — Huskies Docs',
+ description: 'Get huskies running in minutes: Docker setup, first story, first agent run.',
+}
+
+/** Renders the quickstart installation and setup guide. */
+export default function QuickstartPage() {
+ return (
+ <>
+
Quickstart
+
+ Get huskies running in your project in a few minutes. This guide covers Docker setup, running from a
+ binary, your first story, and your first agent run.
+
+
+
Option A: Docker (recommended)
+
+ The easiest way to run huskies is with Docker Compose. This requires Docker and a Claude API key.
+
+
+
+
+ Get the compose file. Download docker-compose.yml from the{' '}
+ releases page or copy it from
+ the repository's docker/ directory.
+
+
+
+
+ Set your API key. Create a .env file next to the compose file:
+
ANTHROPIC_API_KEY=sk-ant-...
+
+
+
+
+ Mount your project. Edit the compose file to mount your project directory:
+
+ .huskies/work/ — the 6-stage pipeline directory
+
+
+ .mcp.json — MCP server config for Claude Code integration
+
+
+ .huskies/specs/ — placeholder spec files for your project context
+
+
+
+
+ Claude Code integration: The .mcp.json file automatically registers
+ huskies' MCP tools with Claude Code. Open a Claude Code session in your project and it will
+ discover tools like create_story, start_agent, and{' '}
+ get_pipeline_status automatically.
+
+
+
Start the server
+
huskies --port 3000
+
+ Open http://localhost:3000 to see the pipeline board, agent
+ status, and chat interface.
+
+
+
Run the setup wizard
+
+ Open a Claude Code session in your project directory (or use the web chat UI), and tell Claude:
+
+
help me set up this project with huskies
+
+ Claude will walk you through the setup wizard — generating project context (
+ specs/00_CONTEXT.md), tech stack docs (specs/tech/STACK.md), and
+ test/release scripts. Review each step and confirm or ask to retry.
+
+
+
Create your first story
+
In the chat UI or via a chat transport, type:
+
I want to add a health check endpoint to the API
+
+ Claude will create a story file in .huskies/work/1_backlog/ with a user story and
+ acceptance criteria. Review it, then move it to current:
+
+
move <story-number> current
+
+
Start an agent
+
+ Once a story is in 2_current/, start a coding agent:
+
+
start <story-number>
+
+ The agent creates an isolated git worktree, implements the feature against the acceptance criteria,
+ runs quality gates (clippy, tests, biome), and exits. The server automatically advances the story to
+ QA if all gates pass.
+
+
+
Review and merge
+
Once QA passes, the story moves to 4_merge/. To merge:
+
start <story-number>
+
+ The mergemaster agent resolves any conflicts and squash-merges to your main branch. The worktree is
+ cleaned up automatically.
+
+
+
+ Tip: Use status in the chat at any time to see the current pipeline
+ state, active agents, and their progress.
+
+ >
+ )
+}
diff --git a/website/app/docs/transports/page.tsx b/website/app/docs/transports/page.tsx
new file mode 100644
index 00000000..5ed6dfc6
--- /dev/null
+++ b/website/app/docs/transports/page.tsx
@@ -0,0 +1,384 @@
+/** Chat transports guide — Matrix, Slack, WhatsApp, Discord, and web UI setup. */
+import type { Metadata } from 'next'
+import Link from 'next/link'
+
+/** Page metadata for the chat transports guide. */
+export const metadata: Metadata = {
+ title: 'Chat Transports — Huskies Docs',
+ description:
+ 'Connect huskies to Matrix, WhatsApp, Slack, Discord, or the built-in web UI.',
+}
+
+/** Renders the chat transports setup guide for all supported platforms. */
+export default function TransportsPage() {
+ return (
+ <>
+
Chat Transports
+
+ Huskies can be controlled via bot commands in any of five transports. Only one external transport
+ can be active at a time. The web UI is always available regardless.
+
+
+
+ Configuration: Copy the relevant example file to{' '}
+ .huskies/bot.toml and fill in your credentials. The file is gitignored. Restart
+ huskies after changes.
+
+
+
Web UI
+
+ The built-in web interface is always available at http://localhost:<port>. No
+ configuration required. It provides:
+
+
+
Pipeline board showing all work items and their stages
+
Agent status panel with live output streaming
+
Chat interface for running commands and talking to Claude
+
Coverage and cost dashboards
+
+
+ No bot.toml is required for the web UI. If no transport is configured, huskies runs
+ in web-only mode.
+
+
+
Matrix
+
+ Matrix uses the Matrix Client-Server API with long-polling sync. No public webhook URL is required
+ — the bot connects outbound to your homeserver.
+
+
+
Setup
+
+
+
Register a Matrix account for the bot on your homeserver (e.g. @huskies:example.com).
+
+
+
Invite the bot account to the rooms you want it to monitor.
+
+
+
+ Copy the example config and fill in your credentials:
+
+ Set whatsapp_provider = "twilio" and fill in your Twilio account SID, auth
+ token, and phone numbers. The webhook URL is the same:{' '}
+ https://your-server/webhook/whatsapp.
+
+
+
Discord
+
+ Connects huskies to Discord using the Discord Gateway WebSocket. No public webhook URL required
+ — the bot connects outbound.
+
+ List of channel IDs to listen in (e.g.{' '}
+ {`["123456789012345678"]`}).
+
+
+
+
discord_allowed_users
+
+ Optional. Discord user IDs allowed to interact. When absent, all users in configured
+ channels can interact.
+
+
+
+
+
+
Gateway: aggregated notifications
+
+ When using huskies --gateway, you can configure the gateway bot to receive
+ notifications from all registered projects in a single room. Events are prefixed
+ with [project-name].
+
+
+ No additional transport is required — the gateway aggregated stream works with any of the
+ transports above. Configure the gateway's .huskies/bot.toml with your transport
+ credentials and set aggregated_notifications_enabled = true (the default). See{' '}
+
+ Configuration → Gateway aggregated stream
+ {' '}
+ for the full reference.
+
+
+ No per-project changes needed: Adding a new project to{' '}
+ projects.toml does not require editing per-project bot configs — the gateway
+ picks it up automatically.
+
+ They're enthusiastic, sometimes wild, and they'll happily wander off on their own. But put
+ them in a harness and they'll take you anywhere. Huskies is the harness — a story-driven
+ pipeline that turns coding agents into a disciplined team.
+
+
+
+
+
+ Story
+
+
+
+
+ Implement
+
+
+
+
+ QA
+
+
+
+
+ Merge
+
+
+
+
+ Done
+
+
+
+
+
+
How it works
+
+
+ 01
+
+
Write a story
+
Describe what you want with acceptance criteria. From your IDE, a chat room, or WhatsApp.
+
+
+
+ 02
+
+
Agent picks it up
+
A coder agent creates a feature branch, implements the code, and writes tests against your criteria.
+
+
+
+ 03
+
+
Quality gates run
+
Linters, tests, and compilation checks run automatically. Nothing moves forward until everything passes.
+
+
+
+ 04
+
+
Merge & land
+
A merge agent resolves conflicts and squash-merges to your main branch. You review and accept.
+
+
+
+
+
+
+
Features
+
+
+
+
+
+
The Harness
+
+ Stories define the change. Tests define the truth. Code defines the reality. Every agent runs on
+ rails — nothing ships without acceptance criteria.
+
+
+
+
+
+
+
The Pack
+
+ Coder, QA, and merge agents work in parallel across isolated git worktrees. A coordinated pack, not
+ a lone wolf. Configure agent count, models, and budgets.
+
+
+
+
+
+
+
Chat Anywhere
+
+ Control the pipeline from Matrix, WhatsApp, Slack, or the built-in web UI. Create stories, start
+ agents, check status.
+
+
+
+
+
+
+
You're the Musher
+
+ Agents implement, test, and merge independently. You set the direction and approve what ships. Every
+ story is traceable from request to release.
+
+ Huskies is operated by Libby Labs Ltd (“we”, “us”, “our”), trading
+ as Crashlabs. Our contact email is{' '}
+ hello@huskies.dev.
+
+
+
+
+
What we collect
+
+ When you interact with Huskies via WhatsApp, Slack, Matrix, or the web interface, we may collect:
+
+
+ Messaging data: Your phone number or chat identifier and the content of messages you
+ send to the bot. This is used solely to process your requests and maintain conversation context.
+
+
+ Usage data: Basic server logs including timestamps and request metadata. We do not use
+ analytics trackers on this website.
+
+
+
+
+
How we use your data
+
We use your data only to provide and improve the Huskies service. Specifically:
+
+ - To process commands and respond to your messages.
+ - To maintain conversation history within active sessions.
+ - To diagnose and fix technical issues.
+
+
We do not sell, rent, or share your personal data with third parties for marketing purposes.
+
+
+
+
Third-party services
+
+ Messages sent via WhatsApp are processed through Meta's WhatsApp Business API or Twilio's
+ messaging platform, subject to their respective privacy policies. Messages sent via Slack or Matrix pass
+ through those platforms' infrastructure.
+
+
+
+
+
Data retention
+
+ Conversation history is stored locally on our servers and retained only for the duration needed to
+ maintain session context. We do not retain message data indefinitely.
+
+
+
+
+
Your rights
+
+ You may request access to, correction of, or deletion of your personal data at any time by contacting
+ us at hello@huskies.dev.
+
+
+
+
+
Changes to this policy
+
+ We may update this policy from time to time. Changes will be posted on this page with an updated date.
+