From edc5823622a03e945d784ce5a2d091eece6c195f Mon Sep 17 00:00:00 2001 From: lekss361 Date: Sat, 30 May 2026 10:38:10 +0300 Subject: [PATCH] chore(bots): per-role launcher scripts + move bot pipeline to forgejo MCP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (a) Launcher scripts — больше не экспортировать токен руками: - scripts/start-bot.ps1 — выставляет per-bot identity + токены (FORGEJO_ACCESS_TOKEN для forgejo MCP + FORGEJO_TOKEN для curl-fallback), git-identity, forgejo-bot remote, verify, затем запускает claude. - scripts/start-{analyst,backend,frontend,reviewer,qa}.ps1 — тонкие врапперы. (b) Bots on forgejo MCP (goern) вместо curl: - _autonomous_pickup.md: новая секция «Forgejo операции — mcp__forgejo__* (PRIMARY)» с полным curl→MCP mapping (list_repo_issues / create_pull_request / merge_pull_request / get_pull_request_diff / create_pull_review / add+remove_issue_labels / update_issue / issue_state_change / create_issue_comment). curl_forgejo помечен FALLBACK. - 5 auto-*.md + 5 work-as-*.md: директива «Forgejo API → mcp__forgejo__* tools (mapping в _autonomous_pickup); curl только fallback» + указатель на start-bot.ps1. Gotcha задокументирован: include_org_labels:false на user-репо (lekss361 не org). Требует: рестарт Claude Code (forgejo MCP eager из .mcp.json) + FORGEJO_ACCESS_TOKEN per-window (делает start-bot.ps1). --- .claude/agents/_autonomous_pickup.md | 23 ++++++++++- .claude/agents/auto-analyst.md | 2 + .claude/agents/auto-backend.md | 2 + .claude/agents/auto-code-reviewer.md | 2 + .claude/agents/auto-frontend.md | 2 + .claude/agents/auto-qa-tester.md | 2 + .claude/commands/work-as-analyst.md | 8 ++++ .claude/commands/work-as-backend.md | 8 ++++ .claude/commands/work-as-frontend.md | 8 ++++ .claude/commands/work-as-qa.md | 8 ++++ .claude/commands/work-as-reviewer.md | 8 ++++ scripts/start-analyst.ps1 | 2 + scripts/start-backend.ps1 | 2 + scripts/start-bot.ps1 | 57 ++++++++++++++++++++++++++++ scripts/start-frontend.ps1 | 2 + scripts/start-qa.ps1 | 2 + scripts/start-reviewer.ps1 | 2 + 17 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 scripts/start-analyst.ps1 create mode 100644 scripts/start-backend.ps1 create mode 100644 scripts/start-bot.ps1 create mode 100644 scripts/start-frontend.ps1 create mode 100644 scripts/start-qa.ps1 create mode 100644 scripts/start-reviewer.ps1 diff --git a/.claude/agents/_autonomous_pickup.md b/.claude/agents/_autonomous_pickup.md index d8f9b535..96de5365 100644 --- a/.claude/agents/_autonomous_pickup.md +++ b/.claude/agents/_autonomous_pickup.md @@ -103,7 +103,28 @@ git remote -v | Select-String "forgejo-bot" Только после `4a/4b/4c ✓` — запускай `/loop`. -## Forgejo API endpoints (использует env vars из Шага 2) +## Forgejo операции — `mcp__forgejo__*` tools (PRIMARY) + +forgejo MCP (goern) подключён и eager в bot-окнах. Токен бота — из `FORGEJO_ACCESS_TOKEN` +(его выставляет `scripts/start-bot.ps1 ` ДО запуска claude). **Используй MCP-tools, не curl.** +Псевдо-bash `curl_forgejo` ниже — **fallback**, только если MCP недоступен. + +| Операция | MCP tool | Заметки | +|---|---|---| +| kill-switch / pickup / fixup-pickup | `mcp__forgejo__list_repo_issues` | фильтр `labels`,`state`; unassigned/assignee — фильтруй клиентом (`.assignees`) | +| claim: assign + label transition | `mcp__forgejo__update_issue` (assignees) + `mcp__forgejo__add_issue_labels` + `mcp__forgejo__remove_issue_labels` | | +| PR open | `mcp__forgejo__create_pull_request` | head/base/title/body | +| PR diff / files | `mcp__forgejo__get_pull_request_diff`, `mcp__forgejo__list_pull_request_files` | diff умеет `file_path` | +| review verdict | `mcp__forgejo__create_pull_review` | event=APPROVED / REQUEST_CHANGES / COMMENT | +| merge | `mcp__forgejo__merge_pull_request` | Do=squash, delete_branch_after_merge | +| comment (marker / fixup K/3) | `mcp__forgejo__create_issue_comment` | | +| status transition | `mcp__forgejo__add_issue_labels` / `mcp__forgejo__remove_issue_labels` | | +| close issue (qa done) | `mcp__forgejo__issue_state_change` | | + +**Gotcha:** на user-репо (`lekss361` — не org) для label-листинга передавай `include_org_labels:false`, +иначе 403 на `/orgs/...`. + +## Forgejo API endpoints — curl FALLBACK (если MCP недоступен) ```bash curl_forgejo() { diff --git a/.claude/agents/auto-analyst.md b/.claude/agents/auto-analyst.md index c2574b1e..7c56bbb7 100644 --- a/.claude/agents/auto-analyst.md +++ b/.claude/agents/auto-analyst.md @@ -16,6 +16,8 @@ tools: Read, Glob, Grep, Bash, mcp__obsidian__obsidian_simple_search, mcp__obsid > Твой issue — ЕДИНСТВЕННЫЙ канал к worker'у (он не видит твой контекст, не читает vault). Качество > всего pipeline упирается в качество твоей декомпозиции → запускай окно в сильной модели осознанно. +> **Forgejo API → `mcp__forgejo__*` tools** (primary; полный mapping в [[_autonomous_pickup]] § «Forgejo операции»). curl — только fallback. Запуск окна: `scripts/start-bot.ps1 analyst`. + ## Role Read-only tech-analyst в autonomous-pickup mode. Создаёшь Forgejo issues из: diff --git a/.claude/agents/auto-backend.md b/.claude/agents/auto-backend.md index c3601a02..86da8c5d 100644 --- a/.claude/agents/auto-backend.md +++ b/.claude/agents/auto-backend.md @@ -17,6 +17,8 @@ tools: Read, Write, Edit, Glob, Grep, Bash, mcp__obsidian__obsidian_simple_searc > (frontmatter игнорируется). Worker несёт всю judgment-нагрузку сам (интерпретация issue, > интеграция, self-check), без Opus-оркестратора → запускай окно в достаточно сильной модели осознанно. +> **Forgejo API → `mcp__forgejo__*` tools** (primary; полный mapping в [[_autonomous_pickup]] § «Forgejo операции»). curl — только fallback. Запуск окна: `scripts/start-bot.ps1 backend`. + ## Role Backend Python engineer (FastAPI + Celery + PostgreSQL+PostGIS) в autonomous-pickup diff --git a/.claude/agents/auto-code-reviewer.md b/.claude/agents/auto-code-reviewer.md index 063c7155..42444208 100644 --- a/.claude/agents/auto-code-reviewer.md +++ b/.claude/agents/auto-code-reviewer.md @@ -16,6 +16,8 @@ tools: Read, Glob, Grep, Bash, mcp__obsidian__obsidian_simple_search, mcp__obsid > В standalone `/loop`-окне модель = модель окна. Reviewer держит merge-authority и всю > judgment-нагрузку → запускай это окно в Opus 4.8 осознанно. +> **Forgejo API → `mcp__forgejo__*` tools** (primary; полный mapping в [[_autonomous_pickup]] § «Forgejo операции»). curl — только fallback. Запуск окна: `scripts/start-bot.ps1 reviewer` (в Opus 4.8). + ## Role Staff+ code reviewer в autonomous-merge режиме. Polling PRs с `status/review`, diff --git a/.claude/agents/auto-frontend.md b/.claude/agents/auto-frontend.md index 5ee87cd3..889c55f5 100644 --- a/.claude/agents/auto-frontend.md +++ b/.claude/agents/auto-frontend.md @@ -16,6 +16,8 @@ tools: Read, Write, Edit, Glob, Grep, Bash, mcp__obsidian__obsidian_simple_searc > В standalone `/loop`-окне модель = модель окна. Worker несёт всю judgment-нагрузку сам → запускай > окно в достаточно сильной модели осознанно. +> **Forgejo API → `mcp__forgejo__*` tools** (primary; полный mapping в [[_autonomous_pickup]] § «Forgejo операции»). curl — только fallback. Запуск окна: `scripts/start-bot.ps1 frontend`. + ## Role Frontend engineer (Next.js 15 / React 19 / TypeScript strict / Tailwind 4) в diff --git a/.claude/agents/auto-qa-tester.md b/.claude/agents/auto-qa-tester.md index 7fe5e985..72d24b0b 100644 --- a/.claude/agents/auto-qa-tester.md +++ b/.claude/agents/auto-qa-tester.md @@ -15,6 +15,8 @@ tools: Read, Bash, Grep, Glob, mcp__obsidian__obsidian_simple_search, mcp__obsid > **Модель = модель окна.** Frontmatter `model: sonnet` действует ТОЛЬКО при Task-spawn (запрещён). > В standalone `/loop`-окне модель = модель окна → запускай осознанно. +> **Forgejo API → `mcp__forgejo__*` tools** (primary; полный mapping в [[_autonomous_pickup]] § «Forgejo операции»). curl — только fallback. Запуск окна: `scripts/start-bot.ps1 qa`. + ## Role QA в autonomous-pickup mode. Polling issues с `status/qa` (PR уже merged auto-code-reviewer'ом), запускаешь Playwright smoke по golden-path. OK → close issue + status/done. FAIL (feature_regression) → reopen + `status/needs-fix` + assignee=PR author (worker сам чинит). FAIL (prod_down) → `pause-bots` + needs-human. diff --git a/.claude/commands/work-as-analyst.md b/.claude/commands/work-as-analyst.md index d2a56921..5c9301c4 100644 --- a/.claude/commands/work-as-analyst.md +++ b/.claude/commands/work-as-analyst.md @@ -7,6 +7,14 @@ description: Запустить окно как auto-analyst (декомпози Я — auto-analyst. Декомпозирую work-items из vault на actionable Forgejo issues. +## Запуск окна (проще всего) + +Запусти окно через **`scripts/start-bot.ps1 analyst`** — он выставит identity, токены (incl `FORGEJO_ACCESS_TOKEN` для forgejo MCP), verify, затем claude. Внутри: `/work-as-analyst` → `/loop 30m`. + +**Forgejo-операции (create issue / labels) — через `mcp__forgejo__*` tools** (mapping в `.claude/agents/_autonomous_pickup.md`); curl только fallback. + +Ручной pre-flight ниже — fallback. + ## Pre-flight checks (выполни СЕЙЧАС, до /loop) ```powershell diff --git a/.claude/commands/work-as-backend.md b/.claude/commands/work-as-backend.md index 8ccb0cd6..fd9597a0 100644 --- a/.claude/commands/work-as-backend.md +++ b/.claude/commands/work-as-backend.md @@ -7,6 +7,14 @@ description: Запустить окно как auto-backend (pickup scope/backe Я — auto-backend. Подхватываю issues `scope/backend status/ready`, делаю работу, открываю PR. **Не мержу сам** — это работа auto-code-reviewer. +## Запуск окна (проще всего) + +Запусти окно через **`scripts/start-bot.ps1 backend`** — он выставит bot identity, токены (incl `FORGEJO_ACCESS_TOKEN` для forgejo MCP), git-identity, bot-remote, verify, затем откроет claude. Внутри: `/work-as-backend` → `/loop dynamic`. + +**Forgejo-операции — через `mcp__forgejo__*` tools** (mapping в `.claude/agents/_autonomous_pickup.md`); curl только fallback. + +Ручной pre-flight ниже — fallback, если запускаешь без `start-bot.ps1`. + ## Pre-flight checks (выполни СЕЙЧАС, до /loop) ```powershell diff --git a/.claude/commands/work-as-frontend.md b/.claude/commands/work-as-frontend.md index 1c57c341..64f2b0d8 100644 --- a/.claude/commands/work-as-frontend.md +++ b/.claude/commands/work-as-frontend.md @@ -7,6 +7,14 @@ description: Запустить окно как auto-frontend (pickup scope/fron Я — auto-frontend. Подхватываю issues `scope/frontend status/ready`, делаю работу, открываю PR. **Не мержу сам.** +## Запуск окна (проще всего) + +Запусти окно через **`scripts/start-bot.ps1 frontend`** — он выставит identity, токены (incl `FORGEJO_ACCESS_TOKEN` для forgejo MCP), git-identity, bot-remote, verify, затем claude. Внутри: `/work-as-frontend` → `/loop dynamic`. + +**Forgejo-операции — через `mcp__forgejo__*` tools** (mapping в `.claude/agents/_autonomous_pickup.md`); curl только fallback. + +Ручной pre-flight ниже — fallback. + ## Pre-flight checks Идентично `work-as-backend.md`, только изменить две строки: diff --git a/.claude/commands/work-as-qa.md b/.claude/commands/work-as-qa.md index 39841d54..0cda6285 100644 --- a/.claude/commands/work-as-qa.md +++ b/.claude/commands/work-as-qa.md @@ -7,6 +7,14 @@ description: Запустить окно как auto-qa-tester (Playwright smoke Я — auto-qa-tester. Polling issues `status/qa` (PR merged auto-code-reviewer'ом, smoke pending), запускаю Playwright golden-path. +## Запуск окна (проще всего) + +Запусти окно через **`scripts/start-bot.ps1 qa`** — он выставит identity, токены (incl `FORGEJO_ACCESS_TOKEN` для forgejo MCP), verify, затем claude. Внутри: `/work-as-qa` → `/loop 10m`. + +**Forgejo-операции — через `mcp__forgejo__*` tools** (mapping в `.claude/agents/_autonomous_pickup.md`); curl только fallback. + +Ручной pre-flight ниже — fallback. + ## Pre-flight checks Идентично `work-as-backend.md`, только изменить две строки: diff --git a/.claude/commands/work-as-reviewer.md b/.claude/commands/work-as-reviewer.md index 2476b005..b5b1c18a 100644 --- a/.claude/commands/work-as-reviewer.md +++ b/.claude/commands/work-as-reviewer.md @@ -10,6 +10,14 @@ description: Запустить окно как auto-code-reviewer (review + mer > **Запускай это окно осознанно в Opus 4.8** — reviewer держит merge-authority и всю judgment-нагрузку. > Frontmatter `model:` в `auto-code-reviewer.md` в standalone `/loop`-окне НЕ действует (модель = модель окна). +## Запуск окна (проще всего) + +Запусти окно **в Opus 4.8** через **`scripts/start-bot.ps1 reviewer`** — он выставит identity, токены (incl `FORGEJO_ACCESS_TOKEN` для forgejo MCP), git-identity, bot-remote, verify, затем claude. Внутри: `/work-as-reviewer` → `/loop 5m`. + +**Forgejo-операции (review/merge/labels) — через `mcp__forgejo__*` tools** (mapping в `.claude/agents/_autonomous_pickup.md`): `get_pull_request_diff` → `create_pull_review` → `merge_pull_request` + `add/remove_issue_labels`. curl только fallback. + +Ручной pre-flight ниже — fallback. + ## Pre-flight checks Идентично `work-as-backend.md`, только изменить две строки: diff --git a/scripts/start-analyst.ps1 b/scripts/start-analyst.ps1 new file mode 100644 index 00000000..97f53105 --- /dev/null +++ b/scripts/start-analyst.ps1 @@ -0,0 +1,2 @@ +# Wrapper: launch this window as auto-analyst. См. scripts/start-bot.ps1. +& "$PSScriptRoot\start-bot.ps1" analyst diff --git a/scripts/start-backend.ps1 b/scripts/start-backend.ps1 new file mode 100644 index 00000000..86156e81 --- /dev/null +++ b/scripts/start-backend.ps1 @@ -0,0 +1,2 @@ +# Wrapper: launch this window as auto-backend. См. scripts/start-bot.ps1. +& "$PSScriptRoot\start-bot.ps1" backend diff --git a/scripts/start-bot.ps1 b/scripts/start-bot.ps1 new file mode 100644 index 00000000..f3a69711 --- /dev/null +++ b/scripts/start-bot.ps1 @@ -0,0 +1,57 @@ +# Launch a Claude Code window pre-configured as a GenDesign autonomous bot. +# +# Usage: .\scripts\start-bot.ps1 reviewer +# roles: analyst | backend | frontend | reviewer | qa +# +# Выставляет per-bot identity + токены (для forgejo MCP И curl-fallback), bot-remote, +# verify, затем запускает `claude`. Внутри окна: /work-as- -> /loop. +# +# Требует: scripts/setup-bot-env.ps1 уже выполнен (FORGEJO_TOKEN_, *_BOTS в User env). +param( + [Parameter(Mandatory = $true)] + [ValidateSet('analyst', 'backend', 'frontend', 'reviewer', 'qa')] + [string]$Role +) +$ErrorActionPreference = 'Stop' + +$roleUp = $Role.ToUpper() +$bot = "bot-$Role" + +$token = [Environment]::GetEnvironmentVariable("FORGEJO_TOKEN_$roleUp", "User") +if (-not $token) { + Write-Error "FORGEJO_TOKEN_$roleUp не выставлен в User env. Запусти scripts/setup-bot-env.ps1 сначала." + return +} +$url = [Environment]::GetEnvironmentVariable("FORGEJO_URL_BOTS", "User") +$repo = [Environment]::GetEnvironmentVariable("FORGEJO_REPO_BOTS", "User") + +# forgejo MCP (goern) читает FORGEJO_ACCESS_TOKEN — MCP-процесс наследует его при старте claude. +$env:FORGEJO_ACCESS_TOKEN = $token +# curl-fallback + in-session pre-flight +$env:FORGEJO_TOKEN = $token +$env:BOT_USERNAME = $bot +$env:FORGEJO_URL = $url +$env:FORGEJO_REPO = $repo +# git identity — иначе commit author = lekss361 +$env:GIT_AUTHOR_NAME = $bot +$env:GIT_AUTHOR_EMAIL = "$bot@gendsgn.local" +$env:GIT_COMMITTER_NAME = $bot +$env:GIT_COMMITTER_EMAIL = "$bot@gendsgn.local" + +# bot-remote для push audit-log (токен в URL — только локально) +git remote remove forgejo-bot 2>$null | Out-Null +git remote add forgejo-bot "https://$($bot):$token@git.gendsgn.ru/lekss361/gendesign.git" + +# verify: PAT принадлежит ожидаемому боту +$me = (curl.exe -sS -H "Authorization: token $token" "$url/api/v1/user" | ConvertFrom-Json).login +if ($me -ne $bot) { + Write-Error "Identity mismatch: PAT принадлежит '$me', ожидался '$bot'. Проверь FORGEJO_TOKEN_$roleUp." + return +} + +Write-Host "OK bot=$bot" -ForegroundColor Green +Write-Host "OK forgejo MCP token set (FORGEJO_ACCESS_TOKEN) + git identity + forgejo-bot remote" -ForegroundColor Green +Write-Host "" +Write-Host "В окне Claude (Opus 4.8 для reviewer): /work-as-$Role -> затем /loop" -ForegroundColor Cyan + +claude diff --git a/scripts/start-frontend.ps1 b/scripts/start-frontend.ps1 new file mode 100644 index 00000000..c0164ac7 --- /dev/null +++ b/scripts/start-frontend.ps1 @@ -0,0 +1,2 @@ +# Wrapper: launch this window as auto-frontend. См. scripts/start-bot.ps1. +& "$PSScriptRoot\start-bot.ps1" frontend diff --git a/scripts/start-qa.ps1 b/scripts/start-qa.ps1 new file mode 100644 index 00000000..117b5ba7 --- /dev/null +++ b/scripts/start-qa.ps1 @@ -0,0 +1,2 @@ +# Wrapper: launch this window as auto-qa-tester. См. scripts/start-bot.ps1. +& "$PSScriptRoot\start-bot.ps1" qa diff --git a/scripts/start-reviewer.ps1 b/scripts/start-reviewer.ps1 new file mode 100644 index 00000000..e3b060af --- /dev/null +++ b/scripts/start-reviewer.ps1 @@ -0,0 +1,2 @@ +# Wrapper: launch this window as auto-code-reviewer. См. scripts/start-bot.ps1. +& "$PSScriptRoot\start-bot.ps1" reviewer -- 2.45.3