feat: claude-code reviewer engine (#2)
Build & push image / build-and-push (push) Successful in 28s
Build & push image / build-and-push (push) Successful in 28s
Phase 1: a second review engine alongside the majordomo agent loop. For each lens, shell out to the Claude Code CLI (`claude -p --output-format json`) inside the checked-out repo so it verifies findings with its own read tools, then reuse gadfly's verdict-parse + recheck + consolidate + emit pipeline. Select via GADFLY_MODELS `claude-code`/`claude-code/<model>`; auth via CLAUDE_CODE_OAUTH_TOKEN (no --bare) else ANTHROPIC_API_KEY; read-only by default; GADFLY_CLAUDE_* knobs. Dockerfile bundles Node + @anthropic-ai/claude-code. Also bumped the dogfood pin to the status-board image (PR #2 was the first dogfood with the live board + full fleet). Folded in the swarm's own review findings: minimal subprocess env (no GITEA_TOKEN leak to the CLI), runPass robustness (ctx/empty-result/runErr), process-group cleanup on timeout, rune-safe error truncation, and engine-neutral prompts (also de-mort-ified the recheck prompt). 66 findings graded via the gadfly MCP. gofmt clean, go vet quiet, go build + go test -race green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Steve Dudenhoeffer <steve@stevedudenhoeffer.com> Co-committed-by: Steve Dudenhoeffer <steve@stevedudenhoeffer.com>
This commit was merged in pull request #2.
This commit is contained in:
@@ -10,6 +10,7 @@ set the secrets/vars it references. Gadfly is advisory only — it never blocks
|
||||
| [`local-ollama.yml`](local-ollama.yml) | a **local/LAN Ollama** daemon | nothing (or `GADFLY_BASE_URL` for a remote host) |
|
||||
| [`openai-compatible.yml`](openai-compatible.yml) | any **OpenAI-compatible** endpoint (local Ollama `/v1`, gateway, vLLM, OpenRouter…) | `GADFLY_BASE_URL` (+ a key for most gateways) |
|
||||
| [`endpoint-aliases.yml`](endpoint-aliases.yml) | **several named backends** at once (one comment each) | repo vars `GADFLY_ENDPOINT_<NAME>` |
|
||||
| [`claude-code.yml`](claude-code.yml) | the bundled **Claude Code CLI** engine (`claude-code/<model>`) | secret `CLAUDE_CODE_OAUTH_TOKEN` (or `ANTHROPIC_API_KEY`) |
|
||||
| [`.gadfly.yml`](.gadfly.yml) | **per-repo specialist config** (not a workflow — goes at your repo root) | — |
|
||||
|
||||
Common to all:
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
# Gadfly reviewing via the Claude Code CLI engine.
|
||||
# Copy to .gitea/workflows/adversarial-review.yml in your repo.
|
||||
#
|
||||
# Instead of a majordomo model, each lens shells out to the bundled `claude` CLI
|
||||
# inside the checked-out repo (it uses its own Read/Grep/Glob tools to verify
|
||||
# findings), then Gadfly runs its usual verdict + recheck + consolidate pipeline.
|
||||
#
|
||||
# Auth: a Pro/Max subscription token from `claude setup-token` (no --bare),
|
||||
# stored as the CLAUDE_CODE_OAUTH_TOKEN secret. Falls back to ANTHROPIC_API_KEY
|
||||
# if you'd rather pay per-token — set only ONE.
|
||||
#
|
||||
# Heads-up: this engine is wired but not yet validated end-to-end here, and using
|
||||
# subscription auth in automated CI is a gray area in Anthropic's terms — read
|
||||
# the README's "Claude Code engine" note before relying on it.
|
||||
|
||||
name: Adversarial Review (Gadfly)
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, reopened, ready_for_review]
|
||||
issue_comment:
|
||||
types: [created]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
pr_number: { description: "PR number to review", required: true }
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: gadfly-${{ github.event.issue.number || github.event.pull_request.number || github.event.inputs.pr_number }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
review:
|
||||
# Security: only trusted users may trigger a secret-bearing run via a PR
|
||||
# comment. Replace the username(s) below with your maintainers — keep them in
|
||||
# sync with GADFLY_ALLOWED_USERS (the in-container belt-and-suspenders check).
|
||||
if: >-
|
||||
github.event_name != 'issue_comment'
|
||||
|| github.actor == 'your-username'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: docker://gitea.stevedudenhoeffer.com/steve/gadfly:latest
|
||||
env:
|
||||
GITEA_API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
# --- Claude Code engine ---
|
||||
# Pro/Max subscription token (preferred). Or set ANTHROPIC_API_KEY
|
||||
# instead for per-token billing — but never both.
|
||||
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
||||
# ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
# bare "claude-code" uses the CLI default model; "claude-code/<model>"
|
||||
# sets --model (sonnet/opus/haiku, or a full id). One comment per entry.
|
||||
GADFLY_MODELS: "claude-code/sonnet"
|
||||
# Optional CLI tuning (defaults are read-only-safe):
|
||||
# GADFLY_CLAUDE_PERMISSION_MODE: plan # read-only; never edits
|
||||
# GADFLY_CLAUDE_ALLOWED_TOOLS: "Read,Grep,Glob"
|
||||
# GADFLY_CLAUDE_EXTRA_ARGS: "--max-turns 30"
|
||||
GADFLY_ALLOWED_USERS: "your-username"
|
||||
# --- event context (leave as-is) ---
|
||||
EVENT_NAME: ${{ github.event_name }}
|
||||
PR: ${{ github.event.pull_request.number || github.event.issue.number || github.event.inputs.pr_number }}
|
||||
PR_BRANCH: ${{ github.head_ref }}
|
||||
IS_DRAFT: ${{ github.event.pull_request.draft }}
|
||||
COMMENT_BODY: ${{ github.event.comment.body }}
|
||||
COMMENT_ID: ${{ github.event.comment.id }}
|
||||
ACTOR: ${{ github.actor }}
|
||||
Reference in New Issue
Block a user