Walkthrough: Building an Online Chess Game with Feature Agent
This guide walks you through the full Feature Agent workflow from scratch. We'll:
- Create an empty GitHub repo for an online chess game
- Enroll it in Feature Agent
- Submit the first feature request via
curl— build the entire first version - Watch the agent autonomously implement it, including a built-in feature request UI wired back to Feature Agent so users can request enhancements later
By the end, you'll have a working chess game with a "Request a Feature" panel — all built autonomously.
Prerequisites
Before starting, ensure you have:
- Feature Agent running (
npm run dev— see SETUP.md) - A GitHub account with a personal access token
curlinstalled- Claude Code CLI installed and authenticated (
claude --version)
Step 1: Create the Chess Game Repository
Create a new empty repo on GitHub. You can do this via the GitHub UI or CLI:
# Using GitHub CLI
gh repo create my-chess-game --public --clone
cd my-chess-game
# Or manually: create the repo on github.com, then clone it
git clone https://github.com/YOUR_USERNAME/my-chess-game.git
cd my-chess-gameInitialize it with a minimal README so the repo isn't completely empty (the agent needs at least one commit to clone from):
echo "# My Chess Game" > README.md
git add README.md
git commit -m "Initial commit"
git push -u origin mainThat's it — the repo is just a README. Feature Agent will build everything else.
Step 2: Start Feature Agent
If you haven't already:
cd /path/to/featureagent
cp .env.example .envEdit .env with your settings. At minimum:
PORT=3100
AGENT_MODEL=sonnet
AGENT_MAX_CONCURRENCY=1
AGENT_PERMISSIONS=dangerously-skip-permissions
GITHUB_TOKEN=ghp_your_github_token_hereStart the server:
npm run devYou should see:
[featureagent] API server running on port 3100
[featureagent] Database: ./data/featureagent.db
[featureagent] Workspaces: ./workspaces
[agent] Starting agent loop (poll: 30000ms, concurrency: 1)
[agent] Model: sonnet, permissions: dangerously-skip-permissionsOpen http://localhost:3100 to see the dashboard login screen. You can also browse the full API documentation at http://localhost:3100/api-docs (Swagger UI).
Create Your Admin User
Before enrolling projects, create an admin user so you can log into the dashboard:
curl -s -X POST http://localhost:3100/api/users \
-H "Content-Type: application/json" \
-d '{
"email": "admin@example.com",
"name": "Admin",
"role": "admin"
}' | jq .Save the returned api_key — you'll use it to log into the dashboard and authenticate admin API calls.
export ADMIN_KEY="fa_..." # from the response aboveNow open http://localhost:3100, enter your admin API key, and sign in.
Step 3: Enroll the Chess Game Project
Register the chess game repo with Feature Agent. We'll use full_auto mode so the agent starts implementing immediately, and enable draft PR creation:
curl -s -X POST http://localhost:3100/api/projects \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "my-chess-game",
"repo_url": "https://github.com/YOUR_USERNAME/my-chess-game.git",
"default_branch": "main",
"autonomy_mode": "full_auto",
"tech_stack": ["html", "css", "javascript"],
"auto_create_pr": true
}' | jq .You'll get back something like:
{
"id": "a1b2c3d4-...",
"name": "my-chess-game",
"repo_url": "https://github.com/YOUR_USERNAME/my-chess-game.git",
"api_key": "fa_8f3a1b2c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1",
"autonomy_mode": "full_auto",
...
}Save the api_key — you'll need it for submitting features. Export it for convenience:
export CHESS_API_KEY="fa_8f3a1b2c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1"Check the dashboard — you should see "my-chess-game" listed under Projects.
Step 4: Submit the First Feature — Build the Entire Game
Now the fun part. We'll submit a single, detailed feature request that tells the agent to build the complete first version of the chess game, including a feature request UI that talks back to Feature Agent.
Replace YOUR_FEATUREAGENT_URL below with the URL where your Feature Agent is accessible (e.g., http://localhost:3100 for local dev, or your deployed URL).
curl -s -X POST http://localhost:3100/api/features \
-H "Authorization: Bearer $CHESS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Build initial online chess game with feature request UI",
"priority": "high",
"description": "Build the first version of an online chess game as a single-page web application. The game should be playable in a browser with no server-side requirements beyond serving static files.\n\n## Chess Game Requirements\n\n1. **Board & Pieces**: Render an 8x8 chess board with all standard pieces in their starting positions. Use Unicode chess symbols (♔♕♖♗♘♙♚♛♜♝♞♟) or simple styled divs. The board should look clean and professional with alternating light/dark squares.\n\n2. **Game Logic**: Implement full chess rules:\n - Legal move validation for all piece types (pawn, rook, knight, bishop, queen, king)\n - Turn-based play (white moves first, alternating)\n - Capture mechanics\n - Check and checkmate detection\n - Castling (kingside and queenside)\n - En passant\n - Pawn promotion (auto-promote to queen is fine for v1)\n - Stalemate detection\n\n3. **UI/UX**:\n - Click a piece to select it, then click a destination to move\n - Highlight the selected piece\n - Highlight legal moves for the selected piece\n - Show whose turn it is\n - Show check/checkmate/stalemate status\n - New Game button to reset\n - Move history panel showing algebraic notation\n\n4. **Styling**: Modern, clean design. Dark theme preferred. Responsive — should work on desktop and tablet.\n\n## Feature Request Panel\n\nThis is critical: Include a \"Request a Feature\" panel in the UI that lets users submit new feature requests directly to the Feature Agent API. This creates a feedback loop where users of the chess game can request enhancements.\n\n### Feature Request Panel Requirements:\n\n- A collapsible sidebar or modal accessible via a button labeled \"Request a Feature\" or similar\n- Form fields:\n - **Title** (text input, required)\n - **Description** (textarea, required)\n - **Your Email** (text input, optional)\n- On submit, the form sends a POST request to the Feature Agent API:\n ```\n POST FEATUREAGENT_URL/api/features\n Authorization: Bearer CHESS_API_KEY\n Content-Type: application/json\n \n {\"title\": \"...\", \"description\": \"...\", \"submitter_email\": \"...\"}\n ```\n- The Feature Agent URL and API key should be configurable at the top of the JavaScript file as constants:\n ```javascript\n const FEATUREAGENT_URL = \"YOUR_FEATUREAGENT_URL\";\n const FEATUREAGENT_API_KEY = \"CHESS_API_KEY_HERE\";\n ```\n- Show a success message after submission (\"Feature request submitted! The agent will work on it.\")\n- Show an error message if the request fails\n- Also display a read-only list of previously submitted features by fetching:\n ```\n GET FEATUREAGENT_URL/api/features\n Authorization: Bearer CHESS_API_KEY\n ```\n Show each feature with its title, status (as a colored badge), and created date.\n\n## Project Structure\n\n- `index.html` — main page\n- `css/style.css` — styles\n- `js/chess.js` — game logic (board, pieces, rules, move validation)\n- `js/ui.js` — UI rendering, event handlers, feature request panel\n- `js/app.js` — initialization, ties everything together\n- Include a simple `package.json` with a start script that serves the files (e.g., using `npx serve .` or a small express static server)\n\n## Testing\n\n- Write tests for the chess logic (legal moves, check, checkmate, castling, en passant)\n- Use a simple test framework that works without heavy build tooling (vitest or similar)\n- Tests should be runnable via `npm test`",
"submitter_email": "admin@example.com"
}' | jq .You should see:
{
"id": "...",
"title": "Build initial online chess game with feature request UI",
"status": "queued",
...
}Since the project is full_auto, the feature goes straight to queued. Note the priority field — you can set it to low, medium (default), high, or critical.
You can also update a feature after submission — for example, to add more detail or change priority:
FEATURE_ID="..." # from the response above
curl -s -X PATCH http://localhost:3100/api/features/$FEATURE_ID \
-H "Authorization: Bearer $CHESS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"description": "Updated description with more detail...",
"priority": "critical"
}' | jq .Admins can update any feature (including agent-managed fields like status and branch info) via the admin endpoint:
curl -s -X PATCH http://localhost:3100/api/features/admin/$FEATURE_ID \
-H "Content-Type: application/json" \
-d '{
"status": "in_progress",
"branch_name": "feat/chess-game-abc123"
}' | jq .Step 5: Watch the Agent Work
Now sit back and watch. Within 30 seconds (the default poll interval), the agent will pick up the feature.
Monitor via Dashboard
Open http://localhost:3100 — you'll see:
- The feature status change from queued → in progress
- The "Active Jobs" counter in the header go to
1/1 - After implementation, the status becomes implemented with a branch name and PR link
Monitor via Terminal
Watch the Feature Agent logs. You'll see output like:
[agent] Processing feature: Build initial online chess game... (a1b2c3d4) [1/1 slots]
[agent] Feature implemented: a1b2c3d4 on feature/build-initial-online-chess-game-a1b2c3d4 (PR: https://github.com/...)Monitor via API
# Check feature status
curl -s http://localhost:3100/api/features \
-H "Authorization: Bearer $CHESS_API_KEY" | jq '.[0].status'
# Get full detail once implemented
curl -s http://localhost:3100/api/features \
-H "Authorization: Bearer $CHESS_API_KEY" | jq '.[0] | {status, branch_name, pr_url}'Step 6: Review the Implementation
Once the feature status shows implemented:
Check the Branch
cd /path/to/my-chess-game
git fetch origin
git checkout feature/build-initial-online-chess-game-XXXXXXXX
# See what was created
ls -laYou should see a complete project structure:
my-chess-game/
├── index.html
├── css/
│ └── style.css
├── js/
│ ├── app.js
│ ├── chess.js
│ └── ui.js
├── package.json
├── tests/
│ └── chess.test.js
└── docs/
└── features/
└── build-initial-online-chess-game.mdRun It
npm install
npm startOpen the URL shown (typically http://localhost:3000 or similar). You should see:
- A fully playable chess board
- Move history panel
- Game status display
- "Request a Feature" button — this is the feedback loop
Run the Tests
npm testThe agent should have written tests for the chess logic — legal moves, check/checkmate detection, castling, en passant, etc.
Check the Draft PR
If you configured GITHUB_TOKEN and auto_create_pr: true, there will be a draft PR on GitHub with:
- Feature description
- Test results
- Link to the feature doc
- Ready for your review
Step 7: Configure the Feature Request Panel
Before merging, update the Feature Agent connection constants in the chess game's JavaScript. Open the main JS file and find:
const FEATUREAGENT_URL = "YOUR_FEATUREAGENT_URL";
const FEATUREAGENT_API_KEY = "CHESS_API_KEY_HERE";Replace with your actual values:
const FEATUREAGENT_URL = "http://localhost:3100"; // or your deployed URL
const FEATUREAGENT_API_KEY = "fa_8f3a1b2c..."; // your actual keyCommit the change and merge the PR (or push directly to main):
git add .
git commit -m "Configure Feature Agent connection"
git push origin feature/build-initial-online-chess-game-XXXXXXXXThen merge the PR via GitHub.
Step 8: Submit a Feature Request from the Chess Game
Now the loop is complete. Open the chess game in your browser, click "Request a Feature", and submit something:
- Title: "Add AI opponent"
- Description: "Add a single-player mode where the player can play against a computer opponent. Start with a simple minimax AI with alpha-beta pruning, with an adjustable difficulty slider (easy/medium/hard). The AI should think for no more than 2 seconds per move on medium difficulty."
Hit submit. The request goes directly to Feature Agent via the API.
Go back to the Feature Agent dashboard (http://localhost:3100) — you'll see the new feature request appear. Since the project is full_auto, the agent will pick it up and start implementing it on a new branch.
Step 9: Keep Going
You now have an autonomous development loop:
- Users play the chess game and submit feature requests via the built-in panel
- Feature Agent picks them up, creates branches, implements them with tests and docs
- Draft PRs appear on GitHub for your review
- You merge what looks good, and the chess game gets better
Some feature ideas to try:
- "Add move timers for each player (5 min, 10 min, 30 min options)"
- "Add sound effects for moves, captures, and check"
- "Add an undo/redo button"
- "Add online multiplayer via WebSocket"
- "Add a game replay feature that lets you step through completed games"
- "Add piece animation when moving"
- "Show captured pieces for each player"
Each one will be autonomously implemented by the agent.
Switching to PO Approval Mode with an Approver
Once the game has a solid foundation, you might want to switch to po_approval mode so a product owner reviews and approves each feature before the agent implements it.
# Get the project ID
PROJECT_ID=$(curl -s http://localhost:3100/api/projects \
-H "Authorization: Bearer $ADMIN_KEY" | jq -r '.[0].id')
# Update the autonomy mode
curl -s -X PATCH http://localhost:3100/api/projects/$PROJECT_ID \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"autonomy_mode": "po_approval", "po_email": "po@example.com"}' | jq .autonomy_modeSet Up an Approver
Create an approver user and link them to the chess project:
# Create the approver
APPROVER=$(curl -s -X POST http://localhost:3100/api/users \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "po@example.com", "name": "PO Smith", "role": "approver"}')
echo "Approver API key: $(echo $APPROVER | jq -r .api_key)"
APPROVER_ID=$(echo $APPROVER | jq -r .id)
# Link them to the chess project
curl -s -X POST http://localhost:3100/api/users/$APPROVER_ID/projects \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d "{\"project_id\": \"$PROJECT_ID\"}"Now when a user submits a feature, it goes to awaiting_approval. The approver can:
- Log into the dashboard with their API key — they'll only see features for their linked projects
- Click Approve on any feature awaiting approval
- Or approve via API:
curl -s -X POST http://localhost:3100/api/features/$FEATURE_ID/approve \
-H "Authorization: Bearer $APPROVER_KEY"The approved_by field is automatically set to the approver's email. Once approved, the agent analyzes and implements the feature.
Full Workflow Diagram
┌──────────────────────────────────────────────────────────┐
│ Chess Game (Browser) │
│ │
│ ┌──────────┐ ┌──────────────────────────────────┐ │
│ │ │ │ "Request a Feature" Panel │ │
│ │ Chess │ │ │ │
│ │ Board │ │ Title: [Add AI opponent ] │ │
│ │ │ │ Desc: [Add single-player mode ] │ │
│ │ │ │ [with minimax AI... ] │ │
│ │ │ │ Email: [user@example.com ] │ │
│ │ │ │ │ │
│ │ │ │ [Submit Feature Request] │ │
│ │ │ │ │ │
│ │ │ │ Previously Requested: │ │
│ │ │ │ ● Add AI opponent [in_progress] │ │
│ │ │ │ ● Add timers [queued] │ │
│ └──────────┘ └───────────────┬────────────────────┘ │
└──────────────────────────────────┼────────────────────────┘
│ POST /api/features
▼
┌──────────────────────────────────────────────────────────┐
│ Feature Agent (:3100) │
│ │
│ ┌─────────┐ ┌──────────┐ ┌─────────┐ ┌──────────┐ │
│ │ Queue │→│ Agent │→│ Tests │→│ Push │ │
│ │ │ │ (Claude) │ │ Pass? │ │ Branch │ │
│ └─────────┘ └──────────┘ └─────────┘ └────┬─────┘ │
│ │ │
│ ┌──────────────────────────────────────────────┼──────┐ │
│ │ Notifications (WhatsApp) ← Status Changes │ │ │
│ │ Webhooks (HTTP POST) ← Status Changes │ │ │
│ └──────────────────────────────────────────────┼──────┘ │
└──────────────────────────────────────────────────┼────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ GitHub (my-chess-game) │
│ │
│ PR #1: feat: Build initial chess game [merged] │
│ PR #2: feat: Add AI opponent [draft] │
│ PR #3: feat: Add move timers [draft] │
└──────────────────────────────────────────────────────────┘If a Feature Fails
Features can fail for various reasons — ambiguous requirements, test failures, network issues during clone/push, or Claude Code timeout. When a feature fails:
Auto-retry — The agent automatically retries failed features up to 3 times (configurable via
AGENT_MAX_RETRIES). Each retry resets the feature toqueuedand incrementsretry_count.Manual retry — From the dashboard, open a failed feature and click Retry. Or via the API:
curl -X POST http://localhost:3100/api/features/$FEATURE_ID/retry \
-H "Authorization: Bearer $CHESS_API_KEY"Check the implementation log — The feature detail view (dashboard or
GET /api/features/:id) shows what went wrong in theimplementation_logfield.Improve the description and retry — If the feature keeps failing, update the description with more specifics (
PATCH /api/features/:id), then retry.
Where the Agent Works
When the agent picks up a feature, here's what happens on your machine:
- The repo is cloned into
./workspaces/<feature-id>/(or whereverWORKSPACE_DIRpoints) - Claude Code is spawned as a child process in that directory — you can see it with
ps aux | grep claude - On success the workspace is cleaned up; on failure it's preserved so you can inspect what went wrong
To watch the agent work in real-time:
# See active workspaces
ls ./workspaces/
# Watch files being created
watch -n 2 "find ./workspaces -type f 2>/dev/null | head -30"
# Check the Feature Agent server logs for status updates
# (they log to stdout of the npm run dev process)See SETUP.md — How the Agent Works for the full technical breakdown.
Beyond the Basics
Once you're comfortable with the loop above, these capabilities extend it (full details in SETUP.md and README.md):
- Auto-merge tracking — with
GITHUB_TOKENset, the agent polls open PRs and marks a featuremergedonce you merge its PR. PRs with review comments get a!in the dashboard. - Address review comments — instead of hand-editing after a review,
POST /api/features/:id/revisenudges the agent to fetch the PR's comments and apply them on the same branch:bashcurl -X POST http://localhost:3100/api/features/$FEATURE_ID/revise \ -H "Authorization: Bearer $CHESS_API_KEY" - Manual PR recovery — if auto-PR creation failed (e.g. an expired token),
POST /api/features/:id/create-propens the draft PR for the already-pushed branch. - Cancel an in-flight run —
POST /api/features/:id/cancelaborts the agent and wipes the workspace; edit the description andretry. - Spec-Kit — enroll the project (
/spec-kit/enableor/spec-kit/check) and submit features with"use_spec_kit": trueto run the fullspecify → clarify → plan → tasks → analyze → implementpipeline. - Per-feature overrides — set
base_branch,spec_path, or verbatimspec_contenton a submission to control the target branch and where/how the spec is written. - Workspace data provisioning — declare
data_dirs+ asetup_commandon the project so features get the external data they need while the agent stays confined to its workspace.
Tips
- Feature descriptions matter — The more specific the description, the better the implementation. Include acceptance criteria, edge cases, and UI expectations.
- Review before merging — The agent is good but not perfect. Always review the diff before merging a PR.
- Iterate — If a feature isn't quite right, submit a follow-up feature to refine it, or use
reviseto fold in PR review comments. - Check the feature docs — The agent creates documentation in
docs/features/for each feature it implements. These explain what was built and how to test it. - Protected projects — Set
"protected": trueon critical projects to prevent accidental deletion. - Feature Agent eats its own dog food — Feature Agent is enrolled as its own project (
po_approvalmode). Submit features for the agent itself and let it improve its own codebase.