77 lines
4 KiB
PowerShell
77 lines
4 KiB
PowerShell
# 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-<role> -> /loop.
|
||
#
|
||
# Требует: scripts/setup-bot-env.ps1 уже выполнен (FORGEJO_TOKEN_<ROLE>, *_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
|
||
}
|
||
|
||
# MCP-секреты для per-role конфига (.claude/mcp/<role>.json через ${VAR}-подстановку).
|
||
# Единый источник — существующий ~/.claude.json; в role-файлах секретов НЕТ.
|
||
$claudeJson = Join-Path $env:USERPROFILE ".claude.json"
|
||
if (Test-Path $claudeJson) {
|
||
$ms = (Get-Content $claudeJson -Raw | ConvertFrom-Json).mcpServers
|
||
if ($ms.obsidian) { $env:OBSIDIAN_API_KEY = $ms.obsidian.env.OBSIDIAN_API_KEY }
|
||
if ($ms.'postgres-gendesign') { $env:GENDESIGN_DB_URI = $ms.'postgres-gendesign'.env.DATABASE_URI }
|
||
if ($ms.'postgres-tradein') { $env:TRADEIN_DB_URI = $ms.'postgres-tradein'.env.DATABASE_URI }
|
||
if ($ms.glitchtip) { $env:GLITCHTIP_TOKEN = $ms.glitchtip.env.GLITCHTIP_TOKEN }
|
||
}
|
||
# fallback: obsidian-ключ может жить в project .mcp.json
|
||
if (-not $env:OBSIDIAN_API_KEY -and (Test-Path "$PSScriptRoot\..\.mcp.json")) {
|
||
$env:OBSIDIAN_API_KEY = (Get-Content "$PSScriptRoot\..\.mcp.json" -Raw | ConvertFrom-Json).mcpServers.obsidian.env.OBSIDIAN_API_KEY
|
||
}
|
||
|
||
$mcpConfig = (Resolve-Path "$PSScriptRoot\..\.claude\mcp\$Role.json").Path
|
||
|
||
Write-Host "OK bot=$bot" -ForegroundColor Green
|
||
Write-Host "OK identity + tokens + forgejo-bot remote" -ForegroundColor Green
|
||
Write-Host "OK per-role MCP (--strict-mcp-config): $mcpConfig" -ForegroundColor Green
|
||
Write-Host ""
|
||
Write-Host "В окне Claude (Sonnet — экономия недельного Opus-пула): /work-as-$Role -> затем /loop" -ForegroundColor Cyan
|
||
|
||
# --strict-mcp-config: грузим ТОЛЬКО серверы этой роли (игнорируем .mcp.json + ~/.claude.json)
|
||
# --model sonnet: loop-роли на Sonnet (отдельный пул); Opus оставляем main-оркестратору
|
||
claude --model sonnet --strict-mcp-config --mcp-config "$mcpConfig"
|