A barebones autonomous SaaS development team powered by OpenClaw. Four AI agents β Lead, Dev, Designer, Marketer β run in Docker, share a product codebase, and coordinate through a JSON dashboard and a bash CLI.
No Convex. No Next.js dashboard. Just files, jq, and agents that ship.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Host β
β claw CLI βββββββββββββββββββββββββββββββββββββββ β
β (reads/writes data/shared/dashboard.json) β β
ββββββββββββββββββββββββββββββββββββ¬βββββββββββββββ β
β HTTP :18789 β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββ€
β Docker β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββ β
β β gateway (OpenClaw) β β
β β β β
β β lead (Lead π¦) β β
β β ββ subagent: Dev π» β β
β β ββ subagent: Designer π¨ β β
β β ββ subagent: Marketer π β β
β β β β
β β dev β β
β β designer β β
β β marketer β β
β ββββββββββββββββββββββββββββββ¬βββββββββββββββββ β
β β HTTP :8080 β
β ββββββββββββββββββββββββββββββΌβββββββββββββββββ β
β β searxng (local search engine) β β
β βββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Volumes: β
β /data/shared/ β dashboard.json, memory β
β /data/product/ β the actual SaaS code β
β /data/workspace-lead/ β
β /data/workspace-dev/ β
β /data/workspace-designer/ β
β /data/workspace-marketer/ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Component | What it does |
|---|---|
| OpenClaw gateway | Runs agent sessions, fires heartbeats on cron, routes messages between agents |
| dashboard.json | Single source of truth β tasks, agent status, activity feed, deliverables |
claw CLI |
Bash script; reads/writes dashboard.json with jq, triggers agents via OpenClaw CLI |
| SearXNG | Local, privacy-respecting search engine available to all agents as a skill |
shared/WORKING.md |
Soft file-lock table agents use to coordinate edits on /data/product/ |
| Agent | Role | Owns |
|---|---|---|
| Lead π¦ | Coordinator. Breaks user requests into tasks, assigns work, reviews deliverables. Spawns Dev/Designer/Marketer as subagents. | Everything at a high level |
| Dev π» | Full-stack engineer. Writes features, routes, APIs, tests. | product/src/, product/api/ |
| Designer π¨ | UI/UX. Produces Tailwind components, wireframes, design tokens. | product/src/components/, product/public/, product/src/styles/ |
| Marketer π | Growth. Writes landing copy, blog posts, email sequences, SEO strategy. | product/content/, product/public/copy/ |
Every agent runs on a 15-minute heartbeat β they check the task board, pick up assigned work, update their status, and write results back to /data/product/.
Lead can spawn Dev, Designer, and Marketer as parallel subagents for complex tasks (max depth 2).
/data/product/ β all agents read/write here
βββ src/ β Dev (logic, features, routes)
β βββ components/ β Designer (UI components)
β βββ app/ β Dev + Designer
β βββ styles/ β Designer
βββ api/ β Dev
βββ public/ β Designer (images, icons, fonts)
β βββ copy/ β Marketer (landing page copy)
βββ content/ β Marketer (blog posts, docs, email sequences)
Each agent workspace has a product/ symlink pointing to /data/product/ for convenience.
Agents use shared/WORKING.md as a soft lock registry. Before editing any file in /data/product/, an agent adds a row to the lock table. Other agents check this table before touching the same files. The claw notify command lets agents ping each other when they need a file that's claimed.
- Docker + Docker Compose v2
jq(brew install jq/apt install jq)- An OpenRouter API key
# 1. Clone
git clone <your-repo> claw && cd claw
# 2. First-run setup β creates .env, data dirs, SearXNG config, generates tokens
bash scripts/setup.sh
# β exits after creating .env. Open it and set your API key:
nano .env # OPENROUTER_API_KEY=sk-or-...
# 3. Finish setup
bash scripts/setup.sh
# 4. Build and launch
docker compose up -d
# 5. Check everything is running
docker compose ps
docker compose logs gateway # watch for init errors
claw squad # shows agent status
docker exec claw-gateway openclaw agents listOr with Make:
make setup # runs setup.sh (run twice: first to create .env, then to finish)
make up # docker compose up -d
make status # docker ps + claw squadIf the host claw command says Gateway ... unreachable but container logs show OpenClaw listening, verify directly with:
docker exec claw-gateway openclaw agents list| Variable | Required | Default | Description |
|---|---|---|---|
OPENROUTER_API_KEY |
Yes | β | Your OpenRouter API key (sk-or-...) |
GATEWAY_TOKEN |
Yes | auto-generated | Secret token for CLI β gateway communication. Auto-set by setup.sh. |
OPENROUTER_BASE_URL |
No | https://openrouter.ai/api/v1 |
OpenRouter API base URL |
OPENROUTER_MODEL |
No | openrouter/auto |
Default model for all agents. Any OpenRouter model works. |
SEARXNG_URL |
No | http://localhost:8080 |
SearXNG endpoint (host-side). Inside containers it's always http://searxng:8080. |
GATEWAY_URL |
No | http://localhost:18789 |
OpenClaw gateway URL for the CLI on the host |
The claw binary is symlinked to /usr/local/bin/claw by setup.sh (host-side). Inside containers it's at /usr/local/bin/claw.
claw init # Initialize a fresh dashboard.jsonclaw dashboard # Pretty-print the full dashboard
claw feed # Recent activity feed (last 20 events)
claw squad # Agent status tableclaw task:create "Title" "Description" [--priority critical|high|medium|low] [--assign lead|dev|designer|marketer]
claw task:view <taskId> # Full task detail with comments and subtasks
claw task:status <taskId> <status> # Update status: todo|pending|in_progress|review|done|blocked
claw task:assign <taskId> <agent> # Reassign task
claw task:comment <taskId> "text" # Add a comment
claw tasks [--agent <name>] [--status <status>] # List tasks with optional filtersclaw subtask:add <taskId> "Subtask title"
claw subtask:progress <taskId> <subtaskId>
claw subtask:check <taskId> <subtaskId> # Toggle completeclaw deliver <taskId> <path> "Description" [--by <agent>]
claw deliverables [<taskId>] # List deliverables (task-specific or all)claw heartbeat <agent> # Trigger an immediate heartbeat for an agent
claw notify <agent> "message" [--from <sender>] # Send a message to an agentclaw business:set "Your SaaS description and ICP" # Set business context for agents
claw business:get # Show current business contextclaw check [<agent>] # No arg: health check. With agent: poll tasks + notificationsclaw check does an HTTP check first; OpenClaw is WS-first. If this reports unreachable, use docker exec claw-gateway openclaw agents list as the authoritative check.
make setup # Run setup.sh
make up # Start containers
make down # Stop containers
make restart # Restart gateway only
make build # Rebuild images (--no-cache)
make logs # Follow gateway logs
make logs-all # Follow all service logs
make status # docker ps + claw squad
make squad # claw squad
make tasks # claw tasks
make feed # claw feed
make hb-lead # Trigger lead heartbeat
make hb-dev # Trigger dev heartbeat
make hb-designer # Trigger designer heartbeat
make hb-marketer # Trigger marketer heartbeatclaw/
βββ cli/
β βββ claw # Bash CLI (symlinked to /usr/local/bin/claw)
βββ docker/
β βββ gateway/
β βββ Dockerfile
β βββ entrypoint.sh # First-run init, workspace setup, skill install
βββ scripts/
β βββ setup.sh # Bootstrap: .env, data dirs, SearXNG config
β βββ init-workspaces.sh # Create agent workspaces from committed definitions
βββ config/
β βββ config.json # OpenClaw config copied to /data/config/config.json
β βββ dashboard.json # Dashboard seed copied to /data/shared/dashboard.json
βββ workspaces/
β βββ shared/
β β βββ WORKING.md # File lock table + agent status
β βββ lead/
β β βββ SOUL.md # Lead identity and principles
β β βββ HEARTBEAT.md # What Lead does every 15 minutes
β β βββ AGENTS.md # How to use claw CLI and subagents
β β βββ MEMORY.md # Persistent memory seed
β β βββ .claude/agents/ # Subagent definitions (dev, designer, marketer)
β βββ dev/
β β βββ SOUL.md
β β βββ HEARTBEAT.md
β β βββ MEMORY.md
β βββ designer/
β β βββ SOUL.md
β β βββ HEARTBEAT.md
β β βββ MEMORY.md
β βββ marketer/
β βββ SOUL.md
β βββ HEARTBEAT.md
β βββ MEMORY.md
βββ skills/
β βββ searxng/
β βββ SKILL.md # SearXNG search skill (installed into all agents)
βββ agent-management.md # Step-by-step add/remove agent guide
βββ data/ # Git-ignored; created by setup.sh
β βββ config/ # OpenClaw state + runtime config.json
β βββ shared/ # dashboard.json, memory, deliverables
β βββ product/ # The actual SaaS codebase
β βββ workspace-lead/
β βββ workspace-dev/
β βββ workspace-designer/
β βββ workspace-marketer/
βββ docker-compose.yml
βββ Makefile
βββ .env.example
βββ .gitignore
Each agent wakes up on schedule, reads HEARTBEAT.md for instructions, then:
- Checks
claw tasks --agent <self>for assigned work - Picks up
in_progressortodotasks - Works on the task (writes to
/data/product/or their workspace) - Registers deliverables with
claw deliver - Updates task status with
claw task:status - Updates
shared/WORKING.mdwith their current status
Lead reads the task board, creates subtasks, and uses its .claude/agents/ subagent definitions to spawn Dev, Designer, or Marketer as parallel Claude subagents. Each subagent gets the full task context, works in the shared product volume, and returns results to Lead for review.
All agents have the SearXNG skill available. They call it to research competitors, find design inspiration, look up SEO data, or fetch technical documentation β all through the local SearXNG instance with no external tracking.
- Both ports (
18789,8080) are bound to127.0.0.1β not exposed to the internet. Use a reverse proxy (nginx, Caddy) with auth if you need remote access. GATEWAY_TOKENis generated bysetup.shvia/dev/urandomand stored in.env(git-ignored).- SearXNG runs with
cap_drop: ALLand only the minimum capabilities re-added. - The
.envfile and alldata/directories are git-ignored.