From 9e9ab374f0d90c4be671fe1eda9941d261639e15 Mon Sep 17 00:00:00 2001 From: dave Date: Tue, 7 Apr 2026 11:38:14 +0000 Subject: [PATCH] huskies: merge 485_story_documentation_site_for_huskies_dev --- website/docs/cli.html | 174 +++++++++++++ website/docs/commands.html | 181 +++++++++++++ website/docs/configuration.html | 230 ++++++++++++++++ website/docs/docs.css | 447 ++++++++++++++++++++++++++++++++ website/docs/index.html | 135 ++++++++++ website/docs/pipeline.html | 231 +++++++++++++++++ website/docs/quickstart.html | 165 ++++++++++++ website/docs/transports.html | 213 +++++++++++++++ website/index.html | 1 + 9 files changed, 1777 insertions(+) create mode 100644 website/docs/cli.html create mode 100644 website/docs/commands.html create mode 100644 website/docs/configuration.html create mode 100644 website/docs/docs.css create mode 100644 website/docs/index.html create mode 100644 website/docs/pipeline.html create mode 100644 website/docs/quickstart.html create mode 100644 website/docs/transports.html diff --git a/website/docs/cli.html b/website/docs/cli.html new file mode 100644 index 00000000..775ad6aa --- /dev/null +++ b/website/docs/cli.html @@ -0,0 +1,174 @@ + + + + + + CLI Reference — Huskies Docs + + + + + + + + +
+
+ + +
+
+ +
+
+ + +
+

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

+ + + + + + + + +
FlagDefaultDescription
--port <PORT>3000HTTP port to listen on. Set the HUSKIES_PORT environment variable as an alternative.
--project <PATH>current dirPath to the project directory. Huskies looks for .huskies/ here.
--helpPrint help and exit.
--versionPrint 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

+ + + + + + + +
FlagDefaultDescription
--port <PORT>3000Port written into .mcp.json for MCP tool discovery.
--project <PATH>current dirDirectory to initialise. Must be a git repository.
--helpPrint help and exit.
+ +

What it creates

+ + + + + + + + + + +
PathDescription
.huskies/project.tomlProject-wide settings (QA mode, agent limits, timezone, etc.).
.huskies/agents.tomlAgent definitions for coder, QA, and mergemaster roles.
.huskies/work/1_backlog/Pipeline stage directories (1 through 6).
.huskies/specs/00_CONTEXT.mdPlaceholder project context file for the setup wizard.
.huskies/specs/tech/STACK.mdPlaceholder tech stack file for the setup wizard.
.mcp.jsonMCP 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

+ + + + + + + + + +
FlagDescription
--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.
--helpPrint help and exit.
+ +

Environment variables

+ + + + + + + +
VariableDescription
HUSKIES_PORTServer port. Overrides the --port flag.
ANTHROPIC_API_KEYAnthropic API key for agent sessions. Can also be set via the web UI on first use.
GITEA_TOKENGitea API token used by the script/release script when publishing releases.
+ +

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
+
+
+ + +
+ + + diff --git a/website/docs/commands.html b/website/docs/commands.html new file mode 100644 index 00000000..7959874d --- /dev/null +++ b/website/docs/commands.html @@ -0,0 +1,181 @@ + + + + + + Bot Commands — Huskies Docs + + + + + + + + +
+
+ + +
+
+ +
+
+ + +
+

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).
+
+
+
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.
+
+
+
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/docs/configuration.html b/website/docs/configuration.html new file mode 100644 index 00000000..53370f17 --- /dev/null +++ b/website/docs/configuration.html @@ -0,0 +1,230 @@ + + + + + + Configuration — Huskies Docs + + + + + + + + +
+
+ + +
+
+ +
+
+ + +
+

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.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyTypeDefaultDescription
default_qastring"server"Default QA mode. One of "server" (automated gate run), "agent" (spawn a QA agent), or "human" (manual approval).
default_coder_modelstring"sonnet"Default model for coder agents. Only agents matching this model are auto-assigned. Use "opus" on individual stories for complex tasks.
max_codersinteger3Maximum concurrent coder agents. Stories wait in 2_current/ when all slots are full.
max_retriesinteger3Maximum retries per story per pipeline stage before marking it as blocked. Set to 0 to disable.
base_branchstringauto-detectedBase branch for merges and agent prompts. When unset, huskies reads the current HEAD branch.
rate_limit_notificationsboolfalseSend chat notifications when API soft rate limits are hit. Hard blocks and story-blocked notifications are always sent.
timezonestring"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.

+
[[component]]
+name = "frontend"
+path = "frontend"
+setup = ["npm ci", "npm run build"]
+teardown = []
+
+[[component]]
+name = "server"
+path = "."
+setup = ["mkdir -p frontend/dist", "cargo check"]
+teardown = []
+ +

Story front matter overrides

+

Individual stories can override project defaults using YAML front matter:

+
---
+name: "My Complex Story"
+qa: agent        # override default_qa
+agent: opus      # use the opus coder agent
+---
+ +

agents.toml

+

Agent definitions. Lives at .huskies/agents.toml. Each [[agent]] block defines one agent slot.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyDescription
nameUnique identifier for this agent slot (e.g. "coder-1", "qa").
stagePipeline stage this agent handles. One of "coder", "qa", or "mergemaster".
roleHuman-readable description of the agent's responsibilities (shown in status output).
modelClaude model to use. One of "sonnet" (claude-sonnet-4-6) or "opus" (claude-opus-4-6).
max_turnsMaximum conversation turns before the agent is forcefully stopped.
max_budget_usdMaximum API spend in USD before the agent is stopped.
promptThe initial user-turn prompt sent to the agent. Supports template variables (see below).
system_promptThe system prompt sent to the agent session.
+ +

Template variables

+

The following variables are interpolated into prompt and system_prompt at agent start time:

+ + + + + + + + + +
VariableDescription
{{story_id}}The story's ID slug (e.g. 42_story_add_login).
{{worktree_path}}Absolute path to the agent's git worktree.
{{base_branch}}The base branch name from project.toml.
+ +

Example: adding an opus coder

+
[[agent]]
+name = "coder-opus"
+stage = "coder"
+role = "Senior engineer for complex tasks."
+model = "opus"
+max_turns = 80
+max_budget_usd = 20.00
+prompt = "You are working on story {{story_id}} ..."
+system_prompt = "You are a senior full-stack engineer ..."
+

To use this agent for a specific story, add agent: opus to the story's front matter, or run start <number> opus in chat.

+ +

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:

+
cp .huskies/bot.toml.matrix.example .huskies/bot.toml
+

Only one transport can be active at a time. See the Chat transports guide for setup instructions for each platform.

+ +

Common fields

+ + + + + + + + + + +
KeyDescription
enabledSet to true to activate the bot. Set to false to disable without removing the file.
transportTransport type: "matrix", "whatsapp", "slack", or "discord".
display_nameOptional. Bot display name in chat messages.
history_sizeOptional. Maximum conversation turns to remember per room/user (default: 20).
+
+
+ + +
+ + + diff --git a/website/docs/docs.css b/website/docs/docs.css new file mode 100644 index 00000000..a2233991 --- /dev/null +++ b/website/docs/docs.css @@ -0,0 +1,447 @@ +:root { + --bg: #080c15; + --surface: #0e1420; + --surface-hover: #131a28; + --border: #1a2235; + --text: #e8ecf4; + --text-secondary: #8892a8; + --text-dim: #4a5568; + --cyan: #22d3ee; + --cyan-dim: rgba(34, 211, 238, 0.07); + --cyan-glow: rgba(34, 211, 238, 0.15); + --display: 'Bricolage Grotesque', sans-serif; + --body: 'Karla', sans-serif; +} + +* { margin: 0; padding: 0; box-sizing: border-box; } +html { scroll-behavior: smooth; } + +body { + font-family: var(--body); + background: var(--bg); + color: var(--text); + line-height: 1.6; + min-height: 100vh; + overflow-x: hidden; + -webkit-font-smoothing: antialiased; +} + +a { color: var(--cyan); text-decoration: none; transition: opacity 0.2s; } +a:hover { opacity: 0.7; } + +/* Animations */ +@keyframes fadeUp { + from { opacity: 0; transform: translateY(18px); } + to { opacity: 1; transform: translateY(0); } +} + +.reveal { + opacity: 0; + animation: fadeUp 0.7s cubic-bezier(0.16, 1, 0.3, 1) forwards; +} +.r1 { animation-delay: 0.05s; } +.r2 { animation-delay: 0.15s; } +.r3 { animation-delay: 0.3s; } + +/* Outer shell */ +.shell { + max-width: 1100px; + margin: 0 auto; + padding: 0 2rem; +} + +@media (max-width: 640px) { + .shell { padding: 0 1.25rem; } +} + +/* Header */ +header { + padding: 2rem 0; + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid var(--border); + margin-bottom: 0; +} + +.logo { + font-family: var(--display); + font-size: 1.1rem; + font-weight: 800; + letter-spacing: -0.03em; + color: var(--text) !important; +} + +header nav { + display: flex; + align-items: center; + gap: 2rem; +} + +header nav a { + font-size: 0.82rem; + color: var(--text-secondary); +} + +header nav a:hover { color: var(--text); opacity: 1; } +header nav a.active { color: var(--cyan); } + +.nav-cta { + color: var(--cyan) !important; + font-weight: 500; +} + +/* Docs layout */ +.docs-layout { + display: grid; + grid-template-columns: 220px 1fr; + gap: 0; + min-height: calc(100vh - 80px); +} + +/* Sidebar */ +.sidebar { + border-right: 1px solid var(--border); + padding: 2.5rem 0 2.5rem 0; + position: sticky; + top: 0; + height: 100vh; + overflow-y: auto; +} + +.sidebar-section { + margin-bottom: 2rem; +} + +.sidebar-heading { + font-family: var(--display); + font-size: 0.6rem; + font-weight: 700; + letter-spacing: 0.14em; + text-transform: uppercase; + color: var(--text-dim); + padding: 0 1.5rem; + margin-bottom: 0.5rem; +} + +.sidebar nav a { + display: block; + padding: 0.4rem 1.5rem; + font-size: 0.83rem; + color: var(--text-secondary); + transition: color 0.15s, background 0.15s; + border-left: 2px solid transparent; +} + +.sidebar nav a:hover { + color: var(--text); + opacity: 1; +} + +.sidebar nav a.active { + color: var(--cyan); + border-left-color: var(--cyan); + background: var(--cyan-dim); +} + +/* Main content */ +.docs-main { + padding: 2.5rem 3rem 4rem; + max-width: 780px; +} + +@media (max-width: 768px) { + .docs-layout { grid-template-columns: 1fr; } + .sidebar { + position: static; + height: auto; + border-right: none; + border-bottom: 1px solid var(--border); + padding: 1.5rem 0; + } + .docs-main { padding: 2rem 0 3rem; } +} + +/* Typography */ +.page-title { + font-family: var(--display); + font-size: 2rem; + font-weight: 800; + letter-spacing: -0.03em; + margin-bottom: 0.5rem; + line-height: 1.2; +} + +.page-subtitle { + font-size: 1rem; + color: var(--text-secondary); + font-weight: 300; + margin-bottom: 3rem; + line-height: 1.7; + max-width: 560px; +} + +h2 { + font-family: var(--display); + font-size: 1.25rem; + font-weight: 700; + letter-spacing: -0.02em; + margin: 3rem 0 1rem; + padding-top: 1rem; + border-top: 1px solid var(--border); + scroll-margin-top: 2rem; +} + +h2:first-of-type { + margin-top: 0; + padding-top: 0; + border-top: none; +} + +h3 { + font-family: var(--display); + font-size: 0.95rem; + font-weight: 600; + margin: 1.8rem 0 0.5rem; +} + +p { + font-size: 0.9rem; + color: var(--text-secondary); + line-height: 1.8; + margin-bottom: 1rem; +} + +p strong { + color: var(--text); + font-weight: 600; +} + +ul, ol { + padding-left: 1.4rem; + margin-bottom: 1rem; +} + +li { + font-size: 0.9rem; + color: var(--text-secondary); + line-height: 1.8; + margin-bottom: 0.2rem; +} + +li strong { + color: var(--text); + font-weight: 600; +} + +/* Code */ +code { + font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', monospace; + font-size: 0.8rem; + background: var(--surface); + border: 1px solid var(--border); + border-radius: 4px; + padding: 0.1em 0.4em; + color: var(--cyan); +} + +pre { + background: var(--surface); + border: 1px solid var(--border); + border-radius: 6px; + padding: 1.2rem 1.4rem; + overflow-x: auto; + margin: 1rem 0 1.5rem; +} + +pre code { + background: none; + border: none; + padding: 0; + font-size: 0.82rem; + color: var(--text); + line-height: 1.7; +} + +/* Tables */ +table { + width: 100%; + border-collapse: collapse; + margin: 1rem 0 1.5rem; + font-size: 0.85rem; +} + +th { + text-align: left; + font-family: var(--display); + font-size: 0.72rem; + font-weight: 700; + letter-spacing: 0.06em; + text-transform: uppercase; + color: var(--text-dim); + padding: 0.6rem 1rem; + border-bottom: 1px solid var(--border); +} + +td { + padding: 0.65rem 1rem; + border-bottom: 1px solid var(--border); + color: var(--text-secondary); + vertical-align: top; + line-height: 1.6; +} + +td:first-child { + font-family: 'SF Mono', 'Fira Code', monospace; + font-size: 0.8rem; + color: var(--cyan); + white-space: nowrap; +} + +tr:last-child td { border-bottom: none; } + +/* Callout / note box */ +.note { + background: var(--cyan-dim); + border: 1px solid rgba(34, 211, 238, 0.2); + border-radius: 6px; + padding: 1rem 1.2rem; + margin: 1.2rem 0; + font-size: 0.85rem; + color: var(--text-secondary); + line-height: 1.7; +} + +.note strong { + color: var(--cyan); + font-weight: 600; +} + +/* Step list */ +.step-list { + list-style: none; + padding: 0; + counter-reset: steps; +} + +.step-list li { + counter-increment: steps; + display: grid; + grid-template-columns: 40px 1fr; + gap: 1rem; + padding: 1.2rem 0; + border-bottom: 1px solid var(--border); + align-items: start; +} + +.step-list li:first-child { border-top: 1px solid var(--border); } + +.step-list li::before { + content: counter(steps, decimal-leading-zero); + font-family: var(--display); + font-size: 0.72rem; + font-weight: 700; + color: var(--text-dim); + padding-top: 0.15rem; +} + +/* Command cards */ +.cmd-grid { + display: flex; + flex-direction: column; + gap: 1px; + background: var(--border); + border: 1px solid var(--border); + border-radius: 6px; + overflow: hidden; + margin: 1rem 0 1.5rem; +} + +.cmd-row { + display: grid; + grid-template-columns: 160px 1fr; + background: var(--surface); + transition: background 0.2s; +} + +.cmd-row:hover { background: var(--surface-hover); } + +.cmd-name { + padding: 0.9rem 1.1rem; + font-family: 'SF Mono', 'Fira Code', monospace; + font-size: 0.8rem; + color: var(--cyan); + border-right: 1px solid var(--border); + display: flex; + align-items: center; +} + +.cmd-desc { + padding: 0.9rem 1.1rem; + font-size: 0.84rem; + color: var(--text-secondary); + line-height: 1.6; + display: flex; + align-items: center; +} + +/* Docs index cards */ +.doc-cards { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1px; + background: var(--border); + border: 1px solid var(--border); + border-radius: 6px; + overflow: hidden; + margin-top: 2rem; +} + +.doc-card { + background: var(--surface); + padding: 1.6rem; + transition: background 0.2s; + text-decoration: none; + display: block; + color: inherit; +} + +.doc-card:hover { background: var(--surface-hover); opacity: 1; } + +.doc-card-title { + font-family: var(--display); + font-size: 0.95rem; + font-weight: 600; + color: var(--text); + margin-bottom: 0.4rem; +} + +.doc-card-desc { + font-size: 0.82rem; + color: var(--text-secondary); + line-height: 1.6; +} + +@media (max-width: 600px) { + .doc-cards { grid-template-columns: 1fr; } + .cmd-row { grid-template-columns: 130px 1fr; } +} + +/* Footer */ +footer { + padding: 2rem 0; + border-top: 1px solid var(--border); + display: flex; + justify-content: space-between; + align-items: center; + font-size: 0.75rem; + color: var(--text-dim); + margin-top: 0; +} + +footer a { + color: var(--text-dim); + font-size: 0.75rem; +} + +footer a:hover { color: var(--text-secondary); } diff --git a/website/docs/index.html b/website/docs/index.html new file mode 100644 index 00000000..7335bdd7 --- /dev/null +++ b/website/docs/index.html @@ -0,0 +1,135 @@ + + + + + + Documentation — Huskies + + + + + + + + +
+
+ + +
+
+ +
+
+ + +
+

Documentation

+

Huskies Docs

+

Everything you need to set up and run huskies — a story-driven development pipeline that turns coding agents into a disciplined team.

+ + + +

What is huskies?

+

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

+
    +
  1. +
    + 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/. +
    +
  2. +
  3. +
    + 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. +
    +
  4. +
  5. +
    + Quality gates run. Linters, tests, and compilation checks run automatically when the agent exits. Nothing moves forward until everything passes. +
    +
  6. +
  7. +
    + QA review. A QA agent verifies each acceptance criterion, runs your test suite, and either approves or rejects with detailed findings. +
    +
  8. +
  9. +
    + Merge & land. A merge agent resolves conflicts and squash-merges to your main branch. The worktree is cleaned up automatically. +
    +
  10. +
+ +

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/docs/pipeline.html b/website/docs/pipeline.html new file mode 100644 index 00000000..39eaa162 --- /dev/null +++ b/website/docs/pipeline.html @@ -0,0 +1,231 @@ + + + + + + Pipeline Stages — Huskies Docs + + + + + + + + + +
+
+ + +
+
+ +
+
+ + +
+

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:

+ + + + + + + + + + + + + + + + + + + + + + + + + +
TypeFilename patternWhen to use
story42_story_add_login.mdNew functionality. Requires acceptance criteria and tests.
bug43_bug_login_crashes.mdDefect in existing functionality. Write a failing test first.
spike44_spike_auth_options.mdTime-boxed research to reduce uncertainty. No production code.
refactor45_refactor_extract_auth.mdCode 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:

+
    +
  1. Run status <number> to see the failure log.
  2. +
  3. Fix the underlying issue (update the story, fix a build problem, etc.).
  4. +
  5. Run unblock <number> to reset the retry counter.
  6. +
  7. Run start <number> to try again.
  8. +
+ +

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
+depends 45          # clear all dependencies
+
+
+ + +
+ + + diff --git a/website/docs/quickstart.html b/website/docs/quickstart.html new file mode 100644 index 00000000..1633ac35 --- /dev/null +++ b/website/docs/quickstart.html @@ -0,0 +1,165 @@ + + + + + + Quickstart — Huskies Docs + + + + + + + + +
+
+ + +
+
+ +
+
+ + +
+

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.

+
    +
  1. +
    + Get the compose file. Download docker-compose.yml from the releases page or copy it from the repository's docker/ directory. +
    +
  2. +
  3. +
    + Set your API key. Create a .env file next to the compose file: +
    ANTHROPIC_API_KEY=sk-ant-...
    +
    +
  4. +
  5. +
    + Mount your project. Edit the compose file to mount your project directory: +
    volumes:
    +  - /path/to/your/project:/workspace
    +
    +
  6. +
  7. +
    + Start the server. +
    docker compose up
    + Open http://localhost:3000 to see the pipeline board. +
    +
  8. +
+ +

Option B: Binary

+

Download the pre-built binary for your platform from the releases page and place it somewhere on your PATH.

+ +

macOS (Apple Silicon)

+
curl -L https://code.crashlabs.io/crashlabs/huskies/releases/download/latest/huskies-aarch64-apple-darwin \
+  -o /usr/local/bin/huskies
+chmod +x /usr/local/bin/huskies
+ +

Linux (x86-64)

+
curl -L https://code.crashlabs.io/crashlabs/huskies/releases/download/latest/huskies-x86_64-unknown-linux-musl \
+  -o /usr/local/bin/huskies
+chmod +x /usr/local/bin/huskies
+ +

Option C: Build from source

+

Requires Rust (stable), Node.js, and npm.

+
git clone https://code.crashlabs.io/crashlabs/huskies
+cd huskies
+cargo build --release
+# Binary is at target/release/huskies
+ +

Initialise your project

+

From your project directory, run the init command. This creates the .huskies/ directory with the pipeline structure and configuration files.

+
cd /path/to/your/project
+huskies init --port 3000
+

This creates:

+
    +
  • .huskies/project.toml — project-wide settings
  • +
  • .huskies/agents.toml — agent definitions (coder, QA, mergemaster)
  • +
  • .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/docs/transports.html b/website/docs/transports.html new file mode 100644 index 00000000..7742f662 --- /dev/null +++ b/website/docs/transports.html @@ -0,0 +1,213 @@ + + + + + + Chat Transports — Huskies Docs + + + + + + + + +
+
+ + +
+
+ +
+
+ + +
+

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

+
    +
  1. Register a Matrix account for the bot on your homeserver (e.g. @huskies:example.com).
  2. +
  3. Invite the bot account to the rooms you want it to monitor.
  4. +
  5. +
    + Copy the example config and fill in your credentials: +
    cp .huskies/bot.toml.matrix.example .huskies/bot.toml
    +
    +
  6. +
+ +

bot.toml fields

+ + + + + + + + + + +
KeyDescription
homeserverYour Matrix homeserver URL (e.g. https://matrix.example.com).
usernameBot account Matrix ID (e.g. @huskies:example.com).
passwordBot account password.
room_idsList of room IDs to listen in (e.g. ["!roomid:example.com"]).
allowed_usersMatrix IDs allowed to interact. Empty list means nobody — always set this.
ambient_roomsRooms where the bot responds to all messages (not just addressed ones). Updated automatically by ambient on/off.
+ +

Slack

+

Slack uses event subscriptions over a webhook. You'll need a public HTTPS URL pointing to your huskies server.

+ +

Setup

+
    +
  1. Create a Slack App at api.slack.com/apps.
  2. +
  3. Add OAuth scopes: chat:write, chat:update.
  4. +
  5. Subscribe to bot events: message.channels, message.groups, message.im.
  6. +
  7. Install the app to your workspace and copy the bot token.
  8. +
  9. +
    + Set your webhook URL in Event Subscriptions: + https://your-server/webhook/slack +
    +
  10. +
  11. +
    + Copy the example config: +
    cp .huskies/bot.toml.slack.example .huskies/bot.toml
    +
    +
  12. +
+ +

bot.toml fields

+ + + + + + + +
KeyDescription
slack_bot_tokenOAuth bot token starting with xoxb-.
slack_signing_secretSigning secret from the app's Basic Information page.
slack_channel_idsList of channel IDs to listen in (e.g. ["C01ABCDEF"]).
+ +

WhatsApp (Meta Cloud API)

+

Connects huskies to WhatsApp Business via the Meta Cloud API. Requires a Meta Business account and a public webhook URL.

+ +

Setup

+
    +
  1. Create a Meta Business App at developers.facebook.com.
  2. +
  3. Add the WhatsApp product and get a Phone Number ID.
  4. +
  5. Generate a permanent access token.
  6. +
  7. +
    + Register your webhook URL in Meta's dashboard: + https://your-server/webhook/whatsapp +
    +
  8. +
  9. +
    + Copy the example config: +
    cp .huskies/bot.toml.whatsapp-meta.example .huskies/bot.toml
    +
    +
  10. +
+ +

bot.toml fields

+ + + + + + + + + + +
KeyDescription
whatsapp_providerSet to "meta" for the Meta Cloud API.
whatsapp_phone_number_idPhone Number ID from the Meta dashboard.
whatsapp_access_tokenPermanent access token.
whatsapp_verify_tokenWebhook verify token — must match what you set in Meta's dashboard.
whatsapp_allowed_phonesOptional. List of phone numbers allowed to interact (e.g. ["+15551234567"]). When absent, all numbers are allowed.
whatsapp_notification_templateOptional. Name of the approved Meta message template for out-of-window notifications (default: "pipeline_notification").
+ +

WhatsApp (Twilio)

+

An alternative WhatsApp integration using Twilio's WhatsApp API. Requires a Twilio account.

+
cp .huskies/bot.toml.whatsapp-twilio.example .huskies/bot.toml
+

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.

+ +

Setup

+
    +
  1. Create a Discord Application at discord.com/developers/applications.
  2. +
  3. Go to Bot, create a bot, and copy the token.
  4. +
  5. Enable Message Content Intent under Privileged Gateway Intents.
  6. +
  7. Go to OAuth2 → URL Generator, select the bot scope with permissions: Send Messages, Read Message History, Manage Messages.
  8. +
  9. Use the generated URL to invite the bot to your server.
  10. +
  11. Right-click target channels → Copy Channel ID (requires Developer Mode enabled in Discord settings).
  12. +
  13. +
    + Copy the example config: +
    cp .huskies/bot.toml.discord.example .huskies/bot.toml
    +
    +
  14. +
+ +

bot.toml fields

+ + + + + + + +
KeyDescription
discord_bot_tokenBot token from the Discord developer portal.
discord_channel_idsList of channel IDs to listen in (e.g. ["123456789012345678"]).
discord_allowed_usersOptional. Discord user IDs allowed to interact. When absent, all users in configured channels can interact.
+
+
+ + +
+ + + diff --git a/website/index.html b/website/index.html index 0f6de70a..ed2d6cb1 100644 --- a/website/index.html +++ b/website/index.html @@ -20,6 +20,7 @@