PolyLever

● Tutorial // Guide

Run GeneralStaff locally on Windows with OpenRouter

No Claude Pro login: aider + OpenRouter for the engineer, OpenRouter for the reviewer, and a small test project to complete one full cycle. 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 (aider in .bot-worktree)
  3. 3.Verification gate
  4. 4.Reviewer
  5. 5.PROGRESS.jsonl
  6. 6.Rollback bot/work only on verification_failed
tasks.jsonaiderverifyreviewerPROGRESS.jsonlrollback?

Prerequisites

ToolPurpose
Bun ≥ 1.3GeneralStaff CLI
Git for WindowsBash for engineer + verification
pip install aider-chatEngineer provider
OpenRouter API keyEngineer + reviewer

Have Claude Pro / Max? See the Claude Code CLI 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 — Credentials in ~/.generalstaff/.env

GeneralStaff loads `~/.generalstaff/.env` on every `bun src/cli.ts` run. Create the directory and copy `env.example` from your clone.

New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.generalstaff"
Copy-Item (Join-Path $GS_ROOT "env.example") "$env:USERPROFILE\.generalstaff\.env"
notepad "$env:USERPROFILE\.generalstaff\.env"

Sanity-check that the shell sees your OpenRouter key (length only, not the value).

if ($env:OPENROUTER_API_KEY) { "OPENROUTER_API_KEY is set" } else { "NOT SET - restart shell or fix .env" }

If aider logged in via OAuth earlier, delete stale keys or aider will override your `.env`. Remove-Item "$env:USERPROFILE\.aider\oauth-keys.env"

Wrong output

OpenRouter 401 during a cycle — fix the key in `.env` and remove aider OAuth overrides.

litellm.AuthenticationError: OpenrouterException -
{"error":{"message":"User not found.","code":401}}
The API provider is not able to authenticate you. Check your API key.

Step 3 — Register the test project (projects.yaml)

Register the test project in `projects.yaml` (single `verification_command` key).

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 (PowerShell helper below).

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

Example block for $GS_PROJECT — set id and path from your path variables above.

projects:
  - id: generalstaff-test
    path: D:/your-test-repo
    priority: 1
    engineer_provider: aider
    engineer_model: openrouter/<openrouter-model-id>
    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_providerWhich agent runs the engineer step. aider = GeneralStaff builds the aider + worktree invocation; ignores engineer_command.
engineer_modelOpenRouter model id for aider (any model on openrouter.ai). Example: openrouter/deepseek/deepseek-chat. Requires OPENROUTER_API_KEY in ~/.generalstaff/.env.

Step 4 — Init state and add a task

Run doctor to validate tooling (from `$GS_ROOT`).

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

Fix warnings, initialize state, and add a pending 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 the branch does not exist yet.

git -C $GS_TEST branch bot/work main

List tasks to confirm your task is pending.

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

Step 5 — Run one cycle

Run one full cycle on the test project.

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

When the engineer succeeds, you should see a readme commit on `bot/work`.

readme.txt
Applied edit to readme.txt
Commit 1107536 docs: add simple readme.txt for project description
(... aider may show npm ci errors from its own test-cmd at repo root — ignore if GS verification passes below ...)

aider finished. Exit: 0
Engineer finished: exit=0, 21s
End SHA (bot/work): 11075364

On the good path, verification passes and the reviewer may return `verified_weak` (commit stays).

Running verification gate in worktree: .../.bot-worktree
Verification: passed (exit 0)
Running reviewer agent...
Reviewer verdict: verified_weak

Cycle outcome: verified_weak — No tasks were claimed to be completed but a readme file was added

=== 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 on `bot/work`.

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

Mark the task done (the bot often skips this).

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

List tasks again — your task should be `done`.

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

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

OpenRouter 401 / empty diff

Wrong or missing API key — engineer produces no useful diff.

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

verification_failed + rollback (e.g. bun test with no tests)

A bad `verification_command` fails the gate; GeneralStaff rolls back `bot/work` only.

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

Success: Verification passed + verified_weak

After fixing `verification_command` (e.g. npm ci + build in `frontend/`), the commit stays.

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

Next steps

Canonical markdown: docs/tutorials/local-setup-windows-openrouter.md · Path: /tutorials/local-setup-windows-openrouter

Orchestrate with absolute control

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