Skip to content

Walkthrough: Building an Online Chess Game with Feature Agent

This guide walks you through the full Feature Agent workflow from scratch. We'll:

  1. Create an empty GitHub repo for an online chess game
  2. Enroll it in Feature Agent
  3. Submit the first feature request via curl — build the entire first version
  4. 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
  • curl installed
  • 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:

bash
# 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-game

Initialize it with a minimal README so the repo isn't completely empty (the agent needs at least one commit to clone from):

bash
echo "# My Chess Game" > README.md
git add README.md
git commit -m "Initial commit"
git push -u origin main

That's it — the repo is just a README. Feature Agent will build everything else.


Step 2: Start Feature Agent

If you haven't already:

bash
cd /path/to/featureagent
cp .env.example .env

Edit .env with your settings. At minimum:

env
PORT=3100
AGENT_MODEL=sonnet
AGENT_MAX_CONCURRENCY=1
AGENT_PERMISSIONS=dangerously-skip-permissions
GITHUB_TOKEN=ghp_your_github_token_here

Start the server:

bash
npm run dev

You 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-permissions

Open 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:

bash
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.

bash
export ADMIN_KEY="fa_..."  # from the response above

Now 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:

bash
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:

json
{
  "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:

bash
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).

bash
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:

json
{
  "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:

bash
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:

bash
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:

  1. The feature status change from queuedin progress
  2. The "Active Jobs" counter in the header go to 1/1
  3. 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

bash
# 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

bash
cd /path/to/my-chess-game
git fetch origin
git checkout feature/build-initial-online-chess-game-XXXXXXXX

# See what was created
ls -la

You 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.md

Run It

bash
npm install
npm start

Open 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

bash
npm test

The 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:

javascript
const FEATUREAGENT_URL = "YOUR_FEATUREAGENT_URL";
const FEATUREAGENT_API_KEY = "CHESS_API_KEY_HERE";

Replace with your actual values:

javascript
const FEATUREAGENT_URL = "http://localhost:3100";  // or your deployed URL
const FEATUREAGENT_API_KEY = "fa_8f3a1b2c...";     // your actual key

Commit the change and merge the PR (or push directly to main):

bash
git add .
git commit -m "Configure Feature Agent connection"
git push origin feature/build-initial-online-chess-game-XXXXXXXX

Then 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:

  1. Users play the chess game and submit feature requests via the built-in panel
  2. Feature Agent picks them up, creates branches, implements them with tests and docs
  3. Draft PRs appear on GitHub for your review
  4. 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.

bash
# 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_mode

Set Up an Approver

Create an approver user and link them to the chess project:

bash
# 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:
bash
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:

  1. Auto-retry — The agent automatically retries failed features up to 3 times (configurable via AGENT_MAX_RETRIES). Each retry resets the feature to queued and increments retry_count.

  2. Manual retry — From the dashboard, open a failed feature and click Retry. Or via the API:

bash
curl -X POST http://localhost:3100/api/features/$FEATURE_ID/retry \
  -H "Authorization: Bearer $CHESS_API_KEY"
  1. Check the implementation log — The feature detail view (dashboard or GET /api/features/:id) shows what went wrong in the implementation_log field.

  2. 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:

  1. The repo is cloned into ./workspaces/<feature-id>/ (or wherever WORKSPACE_DIR points)
  2. Claude Code is spawned as a child process in that directory — you can see it with ps aux | grep claude
  3. 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:

bash
# 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_TOKEN set, the agent polls open PRs and marks a feature merged once 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/revise nudges the agent to fetch the PR's comments and apply them on the same branch:
    bash
    curl -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-pr opens the draft PR for the already-pushed branch.
  • Cancel an in-flight runPOST /api/features/:id/cancel aborts the agent and wipes the workspace; edit the description and retry.
  • Spec-Kit — enroll the project (/spec-kit/enable or /spec-kit/check) and submit features with "use_spec_kit": true to run the full specify → clarify → plan → tasks → analyze → implement pipeline.
  • Per-feature overrides — set base_branch, spec_path, or verbatim spec_content on a submission to control the target branch and where/how the spec is written.
  • Workspace data provisioning — declare data_dirs + a setup_command on 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 revise to 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": true on critical projects to prevent accidental deletion.
  • Feature Agent eats its own dog food — Feature Agent is enrolled as its own project (po_approval mode). Submit features for the agent itself and let it improve its own codebase.

Released under the MIT License.