PolyLever

● Tutorial // Guide

Run GeneralStaff locally on Windows with Claude Code CLI

Default path: Claude Code runs the engineer via your project's engineer_command.sh and (by default) the reviewer via the same CLI session. Set four PowerShell variables once, then copy every command block as-is.

What one cycle does

  1. 1.Pending task (tasks.json)
  2. 2.Engineer (engineer_command.sh → claude -p in .bot-worktree)
  3. 3.Verification gate
  4. 4.Reviewer (default: claude -p)
  5. 5.PROGRESS.jsonl
  6. 6.Rollback bot/work only on verification_failed

Prerequisites

ToolPurpose
Bun ≥ 1.3GeneralStaff CLI
Git for WindowsBash for engineer_command.sh + verification
Claude Code CLIEngineer + default reviewer (`claude -p`)

Prefer OpenRouter for the engineer? See the OpenRouter + aider tutorial.

Path variables (run once)

Run this block once in the same PowerShell window before any other step. Edit the two folder paths to match your machine; keep `$GS_PROJECT` aligned with the `id` in `projects.yaml`.

# Edit these four lines for your machine, then run the block
$GS_ROOT    = "D:\GeneralStaff"       # GeneralStaff CLI clone
$GS_TEST    = "D:\generalstaff-test"  # Your test git repo
$GS_PROJECT = "generalstaff-test"      # projects.yaml project id
$GS_TASK     = "ge-003"                # Task id for this walkthrough

Step 1 — Install GeneralStaff

Install dependencies in your GeneralStaff clone.

Set-Location $GS_ROOT
bun install

Optional: run the GeneralStaff test suite (still in `$GS_ROOT`).

bun test

Step 2 — Claude Code CLI auth

Confirm Claude Code is on PATH (install from Anthropic if missing).

claude --version

Sign in once if you use a Claude Pro / Max subscription. Skip if you rely on `ANTHROPIC_API_KEY` instead.

claude login

Optional BYOK: set `ANTHROPIC_API_KEY` in the shell or in `~/.generalstaff/.env` when you do not use subscription auth.

if ($env:ANTHROPIC_API_KEY) { "ANTHROPIC_API_KEY is set" } else { "Using Claude Code session auth (or set ANTHROPIC_API_KEY)" }

Step 3 — projects.yaml and engineer_command.sh

Create `projects.yaml` from the example (omit `engineer_provider` to use Claude Code).

Copy-Item (Join-Path $GS_ROOT "projects.yaml.example") (Join-Path $GS_ROOT "projects.yaml")
notepad (Join-Path $GS_ROOT "projects.yaml")

Set `path` to the same folder as `$GS_TEST`, using forward slashes.

$GS_TEST -replace '\\','/'

Omit engineer_provider and engineer_model for Claude Code (default).

projects:
  - id: generalstaff-test
    path: D:/your-test-repo
    priority: 1
    engineer_command: "bash engineer_command.sh ${cycle_budget_minutes}"
    verification_command: "cd frontend && npm ci && npm run build"
    cycle_budget_minutes: 30
    work_detection: tasks_json
    concurrency_detection: worktree
    branch: bot/work
    auto_merge: false
    hands_off:
      - .git/
      - .env
      - .env.*
      - node_modules/
      - dist/
      - build/
      - coverage/

What each field means

FieldMeaning
idUnique project name in GeneralStaff. Must match $GS_PROJECT. Used in CLI flags (--project=…) and state/generalstaff-test/ paths.
pathAbsolute path to the git repo the bot edits. Use forward slashes (run $GS_TEST -replace '\\','/'). Must match $GS_TEST.
priorityPicker order when multiple projects have work. 1 = highest; larger numbers run later.
verification_commandShell command GeneralStaff runs after the engineer, in .bot-worktree. Must exit 0 to pass the gate (e.g. tests or npm run build). Use one key only — duplicate keys break YAML.
cycle_budget_minutesWall-clock cap for one cycle. Substituted into engineer_command as ${cycle_budget_minutes} where supported.
work_detectionHow GS finds pending work. tasks_json = read state/<id>/tasks.json (this tutorial).
concurrency_detectionHow GS isolates concurrent work. worktree = separate .bot-worktree checkout per cycle.
branchGit branch the bot commits to (typically bot/work). Your main branch stays untouched until you merge.
auto_mergeIf true, GS may merge bot/work into main after a verified cycle. false = you merge manually (recommended while learning).
hands_offGlob patterns the engineer must not modify. Violations fail verification / trigger rollback.
engineer_commandShell command GS runs for the engineer (Git Bash on Windows). Usually bash engineer_command.sh ${cycle_budget_minutes} — your script calls claude -p inside the worktree.
engineer_providerOptional. Omit for Claude Code (default claude). Set to aider only if you switch to the OpenRouter tutorial path.
engineer_modelIgnored when engineer_provider is claude (model comes from your claude -p / Claude Code settings). Only used for aider.

Add `engineer_command.sh` at the root of your test repo. Set `PROJECT_ID` inside the script to match `$GS_PROJECT`.

notepad (Join-Path $GS_TEST "engineer_command.sh")
#!/usr/bin/env bash
set -euo pipefail

BUDGET_MINUTES="${1:-30}"
PROJECT_ROOT="$(cd "$(dirname "$0")" && pwd)"
WORKTREE_DIR="$PROJECT_ROOT/.bot-worktree"
BRANCH="bot/work"
# Match $GS_PROJECT in projects.yaml:
PROJECT_ID="generalstaff-test"

echo "=== Bot Launcher (Claude Code) ==="
echo "Budget: ${BUDGET_MINUTES} min | Project: $PROJECT_ROOT"

if ! git -C "$PROJECT_ROOT" rev-parse --verify "$BRANCH" >/dev/null 2>&1; then
  git -C "$PROJECT_ROOT" branch "$BRANCH" main
fi

git -C "$PROJECT_ROOT" worktree prune 2>/dev/null || true
if [ -d "$WORKTREE_DIR" ]; then
  git -C "$PROJECT_ROOT" worktree remove "$WORKTREE_DIR" --force 2>/dev/null || true
  rm -rf "$WORKTREE_DIR" 2>/dev/null || true
fi

git -C "$PROJECT_ROOT" worktree add "$WORKTREE_DIR" "$BRANCH"
cd "$WORKTREE_DIR"
bun install || npm ci || true

claude -p "You are an autonomous engineering bot.

Read $GENERALSTAFF_ROOT/state/${PROJECT_ID}/tasks.json and pick the highest-priority pending task.
Work in this worktree only. Run the project verification command when done.
Mark the task done via:
  bun \"$GENERALSTAFF_ROOT/src/cli.ts\" task done --project=${PROJECT_ID} --task=<task-id>

Stop after one task." --output-format text

Step 4 — Init state and add a task

Run doctor — `claude` should pass when Claude Code is installed.

Set-Location $GS_ROOT
bun src/cli.ts doctor

Initialize state and queue a task.

bun src/cli.ts doctor --fix
bun src/cli.ts init --project=$GS_PROJECT
bun src/cli.ts task add --project=$GS_PROJECT --id=$GS_TASK --title="Add a simple readme.txt" --priority=1

Create `bot/work` if needed.

git -C $GS_TEST branch bot/work main

Confirm the task is pending.

bun src/cli.ts tasks --project=$GS_PROJECT

Step 5 — Run one cycle

Run one cycle — GeneralStaff executes `engineer_command.sh`, which invokes `claude -p` in the worktree.

Set-Location $GS_ROOT
bun src/cli.ts cycle --project=$GS_PROJECT

When the engineer finishes, you should see commits on `bot/work` and verification output.

Engineer finished: exit=0, 180s
Running verification gate in worktree: .../.bot-worktree
Verification: passed (exit 0)
Running reviewer agent...
Reviewer verdict: verified_weak

=== Cycle complete: verified_weak ===

Step 6 — Confirm git state and finish the task

Confirm the latest commit on `bot/work`.

git -C $GS_TEST log bot/work -1 --oneline

Inspect the file the bot added.

git -C $GS_TEST show bot/work:readme.txt

Mark the task done if the bot did not.

bun src/cli.ts task done --project=$GS_PROJECT --task=$GS_TASK

Step 7 — Inspect the audit log

Tail the audit log for verification, reviewer, and cycle end events.

Get-Content (Join-Path $GS_ROOT "state\$GS_PROJECT\PROGRESS.jsonl") -Tail 3

Reset a stuck worktree

If a worktree is stuck, stop the daemon and remove `.bot-worktree`.

Set-Location $GS_ROOT
bun src/cli.ts stop --force
git -C $GS_TEST worktree remove (Join-Path $GS_TEST ".bot-worktree") --force
Remove-Item (Join-Path $GS_TEST ".bot-worktree") -Recurse -Force -ErrorAction SilentlyContinue
git -C $GS_TEST checkout main
Remove-Item (Join-Path $GS_ROOT "STOP") -ErrorAction SilentlyContinue

Outcomes cheat sheet

Line in terminalRollback?Commit kept?
Verification: passed + verifiedNoYes
Verification: passed + verified_weakNoYes
Verification: failedYesNo
empty diff, skipping verificationNoNo change on branch

Troubleshooting

doctor: claude not found

Claude Code CLI is missing from PATH.

claude --version

Engineer exits 1 — not authenticated

Subscription session expired or API key missing.

claude login

verification_failed + rollback

Fix `verification_command`, then re-run the cycle.

Set-Location $GS_ROOT
bun src/cli.ts cycle --project=$GS_PROJECT

Next steps

Path: /tutorials/local-setup-windows-claude-code

Orchestrate with absolute control

Start with gs welcome, register a project, and run your first verified cycle. Your codebase deserves gates, not just prompts.