Skip to content

Commit 210507e

Browse files
lapc506claude
andauthored
feat(commands): add /gemini-code-review — Gemini 3.5 Flash first-pass review (#27)
New command + self-contained worker (scripts/gemini-code-review.sh): one-shot diff review on gemini-3.5-flash via a transient liteLLM proxy, curated by the orchestrator against the local repo's CLAUDE.md. Design B — no nested Claude Code agent on Gemini (no tool-call-translation fragility). Repo-agnostic; secret via the plugin's /secret-input + /secret-use. Bump 1.18.0 + CHANGELOG. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 7e92b02 commit 210507e

7 files changed

Lines changed: 259 additions & 5 deletions

File tree

.claude-plugin/marketplace.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
33
"name": "make-no-mistakes",
4-
"version": "1.17.0",
4+
"version": "1.18.0",
55
"description": "The disciplined dev lifecycle — implement issues, review PRs, sync releases, test E2E, manage sessions, and stash secrets via OS-native prompts. One plugin to make no mistakes.",
66
"owner": {
77
"name": "Luis Andres Pena Castillo",
@@ -11,7 +11,7 @@
1111
{
1212
"name": "make-no-mistakes",
1313
"description": "Dev lifecycle orchestrator: disciplined Linear issue execution with worktree isolation, PR review with Greptile gating, team release sync, E2E test generation and execution, test suite previewer, security pentesting, MoSCoW + RICE prioritization, cross-platform secret stash via OS-native GUI prompts (zenity / kdialog / osascript / Get-Credential), and session management. 18 commands, 6 auto-activating skills, 2 specialized agents.",
14-
"version": "1.17.0",
14+
"version": "1.18.0",
1515
"author": {
1616
"name": "Luis Andres Pena Castillo",
1717
"email": "lapc506@users.noreply.github.com"

.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "make-no-mistakes",
3-
"version": "1.17.0",
3+
"version": "1.18.0",
44
"description": "The disciplined dev lifecycle — implement issues, review PRs, sync releases, test E2E, manage sessions, stash secrets, and enforce manifest-driven tool-call hooks. One plugin to make no mistakes.",
55
"author": {
66
"name": "Luis Andres Pena Castillo",

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1818
1919
## [Unreleased]
2020

21+
## [1.18.0] - 2026-05-26
22+
23+
### Added
24+
- **New command `/make-no-mistakes:gemini-code-review`** + worker
25+
`scripts/gemini-code-review.sh`. A cost-optimized first-pass code review: the
26+
heavy diff-reading runs on **Gemini 3.5 Flash** (one-shot via a transient
27+
liteLLM proxy), then the orchestrator (on a Claude model) curates the findings
28+
against the local repo's `CLAUDE.md`. **Design B** — no nested Claude Code
29+
agent runs on Gemini, so there is no tool-call-translation fragility. Repo-
30+
agnostic: base branch auto-detected (`origin/HEAD``develop`/`main`/`master`),
31+
the rubric is generic, and the curation layer adds repo specifics. Secret
32+
handling via the plugin's own `/secret-input` + `/secret-use` so
33+
`GEMINI_API_KEY` never leaks into logs.
34+
35+
### Notes
36+
- **Parallel-version coordination:** the `andres/stale-push-hook` branch also
37+
claims `1.18.0`. Whichever merges first keeps `1.18.0`; the other rebases onto
38+
the updated `main` and bumps to `1.19.0`.
39+
2140
## [1.17.0] - 2026-05-25
2241

2342
### Added

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# make-no-mistakes
22

3-
**Version: 1.17.0** · [CHANGELOG](./CHANGELOG.md) · [Marketplace](https://github.com/DojoCodingLabs/make-no-mistakes-toolkit)
3+
**Version: 1.18.0** · [CHANGELOG](./CHANGELOG.md) · [Marketplace](https://github.com/DojoCodingLabs/make-no-mistakes-toolkit)
44

55
The disciplined dev lifecycle — implement issues, review PRs, sync releases, test E2E, and manage sessions. One plugin to make no mistakes.
66

commands/gemini-code-review.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
description: Cheap first-pass code review on Gemini 3.5 Flash (one-shot via liteLLM), curated by the orchestrator against the local repo's CLAUDE.md. Design B — no nested agent.
3+
argument-hint: "[PR# | branch | --uncommitted] (default: <base>...HEAD)"
4+
---
5+
6+
# Gemini Code Review: $ARGUMENTS
7+
8+
A **cost-optimized first-pass** code review. The heavy diff-reading runs on
9+
**Gemini 3.5 Flash** (cheap/fast) in a single one-shot request; you (the
10+
orchestrator, on a Claude model) then **curate** the output against the local
11+
repo's review rules. This is NOT a replacement for a full Claude-model review on
12+
high-risk PRs — it's a fast triage pass.
13+
14+
## How it works (Design B)
15+
16+
`${CLAUDE_PLUGIN_ROOT}/scripts/gemini-code-review.sh` resolves the diff, starts a
17+
transient liteLLM proxy, sends the diff + a condensed review rubric to
18+
gemini-3.5-flash in ONE completion, and returns review markdown. No nested Claude
19+
Code agent runs on Gemini, so there is no tool-call-translation fragility.
20+
21+
## Steps
22+
23+
1. **Run the worker** against the requested target (default `<base>...HEAD`, base
24+
auto-detected from `origin/HEAD``develop`/`main`/`master`). The worker needs
25+
`GEMINI_API_KEY` in the environment — provide it via this plugin's secret
26+
helpers so it never leaks into logs:
27+
28+
```bash
29+
# one-time, if not already staged: /secret-input
30+
/secret-use GEMINI_API_KEY -- bash "${CLAUDE_PLUGIN_ROOT}/scripts/gemini-code-review.sh" $ARGUMENTS
31+
```
32+
33+
- `$ARGUMENTS` may be a PR number, branch, `--uncommitted`, an `a..b` range, or
34+
empty. Pass it through verbatim.
35+
- If the script exits non-zero, surface the stderr reason (missing
36+
`GEMINI_API_KEY`, empty diff, proxy failed to start) and STOP — do not
37+
fabricate a review.
38+
39+
2. **Curate the Gemini output** — do NOT just relay it. For each finding:
40+
- **Validate** against the actual diff and **this repo's `CLAUDE.md`** (and any
41+
nearest-directory `CLAUDE.md` / `docs/agent-standards`). Confirm, correct, or
42+
**drop false positives** (Flash over-flags).
43+
- **Add** repo-rule-specific issues Flash missed that are visible in the diff
44+
(architecture-boundary violations, banned patterns, test conventions, RLS /
45+
security rules — whatever the repo's standards encode).
46+
- Keep `file:line` precision; discard vague advice.
47+
48+
3. **Present the curated review** in the worker's shape (Files table,
49+
Critical/Major/Minor findings, Missing Tests, Verdict + metrics) with a one-line
50+
header noting it is a **Gemini-3.5-Flash first pass curated by the orchestrator**.
51+
52+
## When to use
53+
54+
- **`/make-no-mistakes:gemini-code-review`**: cheap triage, WIP self-review,
55+
large/low-risk diffs, fast feedback.
56+
- A full Claude-model review (e.g. a repo's own `/code-review`): authoritative
57+
review on high-risk PRs (auth, payments, migrations, RLS, infra).

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@lapc506/make-no-mistakes",
3-
"version": "1.17.0",
3+
"version": "1.18.0",
44
"description": "The disciplined dev lifecycle — implement issues, review PRs, sync releases, test E2E, manage sessions, stash secrets, and enforce manifest-driven tool-call hooks (no SSH+DB, no manual prod, no minified build, no secret leaks, Slack format). OpenCode + Claude Code plugin.",
55
"type": "module",
66
"main": "./dist/index.js",

scripts/gemini-code-review.sh

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
#!/usr/bin/env bash
2+
# gemini-code-review.sh — one-shot code review on Gemini 3.5 Flash via liteLLM.
3+
#
4+
# Self-contained, repo-agnostic worker for the /make-no-mistakes:gemini-code-review
5+
# command. Resolves a diff, sends it + a condensed review rubric to
6+
# gemini-3.5-flash in a SINGLE completion through a transient liteLLM proxy, and
7+
# prints review markdown to stdout. NO nested Claude Code agent runs on Gemini,
8+
# so there is no tool-call-translation fragility — just one completion. An Opus
9+
# orchestrator (the command) then curates the output against the local repo's
10+
# CLAUDE.md rules.
11+
#
12+
# Usage:
13+
# gemini-code-review.sh # diff <base>...HEAD (base auto-detected)
14+
# gemini-code-review.sh 245 # gh pr diff 245
15+
# gemini-code-review.sh --uncommitted # git diff HEAD (staged + unstaged)
16+
# gemini-code-review.sh my-branch # git diff <base>...my-branch
17+
# gemini-code-review.sh a..b # git diff a..b
18+
# [--base <branch>] # override auto-detected base
19+
#
20+
# Secret: requires GEMINI_API_KEY in the environment. Provide it WITHOUT leaking
21+
# it into logs via this plugin's own secret helpers:
22+
# /secret-input (stage the key once)
23+
# /secret-use GEMINI_API_KEY -- bash <this-script> [args]
24+
#
25+
# Requires: litellm, jq, curl, git (+ gh for PR mode).
26+
set -euo pipefail
27+
28+
PORT="${GEMINI_REVIEW_PORT:-4100}"
29+
MODEL="gemini/gemini-3.5-flash"
30+
BASE=""
31+
TARGET=""
32+
33+
while [ $# -gt 0 ]; do
34+
case "$1" in
35+
--base) [ -z "${2:-}" ] && { echo "ERROR: --base requiere un valor." >&2; exit 1; }; BASE="$2"; shift 2 ;;
36+
--uncommitted) TARGET="--uncommitted"; shift ;;
37+
-h|--help) sed -n '2,26p' "$0"; exit 0 ;;
38+
*) TARGET="$1"; shift ;;
39+
esac
40+
done
41+
42+
for bin in litellm jq curl git; do
43+
command -v "$bin" >/dev/null 2>&1 || { echo "ERROR: falta '$bin' en PATH." >&2; exit 1; }
44+
done
45+
if [ -z "${GEMINI_API_KEY:-}" ]; then
46+
echo "ERROR: GEMINI_API_KEY no está en el entorno." >&2
47+
echo "Stage it once with /secret-input, then run via:" >&2
48+
echo " /secret-use GEMINI_API_KEY -- bash \"$0\" $*" >&2
49+
exit 1
50+
fi
51+
52+
# --- auto-detect base branch (repo-agnostic) ---
53+
if [ -z "$BASE" ]; then
54+
BASE="$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's@^origin/@@' || true)"
55+
if [ -z "$BASE" ]; then
56+
for b in develop main master; do
57+
git show-ref --verify --quiet "refs/remotes/origin/$b" && BASE="$b" && break
58+
done
59+
fi
60+
[ -z "$BASE" ] && BASE="main"
61+
fi
62+
63+
# --- resolve diff ---
64+
LABEL=""
65+
if [ -z "$TARGET" ]; then
66+
LABEL="${BASE}...HEAD"; DIFF="$(git diff "${BASE}...HEAD")"
67+
elif [ "$TARGET" = "--uncommitted" ]; then
68+
LABEL="uncommitted (git diff HEAD)"; DIFF="$(git diff HEAD)"
69+
elif [[ "$TARGET" =~ ^[0-9]+$ ]]; then
70+
command -v gh >/dev/null 2>&1 || { echo "ERROR: 'gh' requerido para modo PR." >&2; exit 1; }
71+
LABEL="PR #${TARGET}"; DIFF="$(gh pr diff "$TARGET")"
72+
elif [[ "$TARGET" == *..* ]]; then
73+
LABEL="$TARGET"; DIFF="$(git diff "$TARGET")"
74+
else
75+
LABEL="${BASE}...${TARGET}"; DIFF="$(git diff "${BASE}...${TARGET}")"
76+
fi
77+
if [ -z "${DIFF// }" ]; then echo "ERROR: diff vacío para '${LABEL}'." >&2; exit 2; fi
78+
DIFF_CHARS=${#DIFF}
79+
[ "$DIFF_CHARS" -gt 600000 ] && echo "WARN: diff grande (${DIFF_CHARS} chars) — el review puede perder profundidad." >&2
80+
81+
# --- rubric (repo-agnostic; the command curates against the repo's CLAUDE.md) ---
82+
read -r -d '' RUBRIC <<'RUBRIC_EOF' || true
83+
You are a battle-tested senior engineer doing a rigorous code review of a diff.
84+
Review as if you will debug this at 3 AM during an incident. Read EVERY changed
85+
line. You are given ONLY the diff — do not ask to run commands or open other
86+
files; review what is shown and flag where you'd want to see more.
87+
88+
Hunt for:
89+
- Logic: race conditions, null/undefined access without guards, missing awaits,
90+
off-by-one, inverted/incorrect boolean logic, wrong equality, bad type coercion.
91+
- State/data-flow: stale closures, missing effect/memo deps, direct mutation of
92+
shared/immutable state, lost error context in catch blocks.
93+
- Edge cases: empty/zero/negative, empty-string vs null vs undefined, encoding,
94+
timezones, large-input performance, concurrency.
95+
- Architecture: single-responsibility violations, oversized units, missing types,
96+
magic numbers/strings, leftover debug logs / commented-out code, dead code.
97+
- Tests: new logic without tests; missing error/empty/edge coverage.
98+
- Security: secrets/keys committed or logged, privileged credentials in client
99+
code, unvalidated input, missing authz/ownership checks, SQL injection, XSS via
100+
raw/unsafe HTML injection, SSRF on server-side fetch, missing rate limiting.
101+
102+
Output EXACTLY this markdown:
103+
104+
## Gemini Code Review — {LABEL}
105+
106+
### Files Reviewed
107+
| File | +/- | Risk | Notes |
108+
|------|-----|------|-------|
109+
110+
### Findings
111+
#### Critical (blocks merge)
112+
- **[Category]** `file:line` — issue -> fix
113+
#### Major (fix before merge)
114+
- ...
115+
#### Minor (recommended)
116+
- ...
117+
118+
### Missing Tests / Changes
119+
- ...
120+
121+
### Verdict: Approve | Request Changes | Block
122+
| Critical | Major | Minor |
123+
|----------|-------|-------|
124+
| N | N | N |
125+
126+
If a section is empty, write "None.". Be specific with file:line; no vague advice.
127+
RUBRIC_EOF
128+
RUBRIC="${RUBRIC/\{LABEL\}/$LABEL}"
129+
130+
# --- transient liteLLM proxy (self-generated config + master key; kill only ours) ---
131+
PROXY_LOG="$(mktemp -t gcr-proxy.XXXXXX.log)"
132+
PROXY_CFG="$(mktemp -t gcr-config.XXXXXX.yaml)"
133+
export LITELLM_MASTER_KEY="sk-gcr-local-$$"
134+
cat > "$PROXY_CFG" <<CFG
135+
model_list:
136+
- model_name: $MODEL
137+
litellm_params:
138+
model: $MODEL
139+
api_key: os.environ/GEMINI_API_KEY
140+
general_settings:
141+
master_key: os.environ/LITELLM_MASTER_KEY
142+
litellm_settings:
143+
drop_params: true
144+
CFG
145+
STARTED=false
146+
ready() { curl -fsS "http://127.0.0.1:${PORT}/health/readiness" >/dev/null 2>&1; }
147+
cleanup() { $STARTED && [ -n "${PID:-}" ] && kill "$PID" 2>/dev/null || true; rm -f "$PROXY_LOG" "$PROXY_CFG"; }
148+
trap cleanup EXIT INT TERM
149+
150+
if ! ready; then
151+
echo "Levantando liteLLM proxy (gemini-3.5-flash) en 127.0.0.1:${PORT}..." >&2
152+
litellm --config "$PROXY_CFG" --host 127.0.0.1 --port "$PORT" >"$PROXY_LOG" 2>&1 &
153+
PID=$!; STARTED=true
154+
for _ in $(seq 1 40); do ready && break; sleep 1; done
155+
ready || { echo "ERROR: el proxy no arrancó. Log:" >&2; tail -8 "$PROXY_LOG" >&2; exit 4; }
156+
fi
157+
158+
# --- one completion ---
159+
# `-sS` (NOT -fsS): on an HTTP 4xx/5xx the body is captured + diagnosed below,
160+
# instead of curl failing silently and masking the real API error (quota, bad key).
161+
BODY="$(jq -n --arg m "$MODEL" --arg sys "$RUBRIC" \
162+
--arg usr "Review this diff (${LABEL}):"$'\n\n'"\`\`\`diff"$'\n'"${DIFF}"$'\n'"\`\`\`" \
163+
'{model:$m, messages:[{role:"system",content:$sys},{role:"user",content:$usr}]}')"
164+
RESP="$(curl -sS "http://127.0.0.1:${PORT}/v1/chat/completions" \
165+
-H "Authorization: Bearer ${LITELLM_MASTER_KEY}" \
166+
-H "Content-Type: application/json" -d "$BODY")" \
167+
|| { echo "ERROR: no se pudo conectar al proxy." >&2; exit 5; }
168+
169+
CONTENT="$(printf '%s' "$RESP" | jq -r '.choices[0].message.content // empty')"
170+
if [ -z "$CONTENT" ]; then
171+
echo "ERROR: respuesta sin contenido:" >&2
172+
printf '%s\n' "$RESP" | jq -r '.error // .' >&2 2>/dev/null || printf '%s\n' "$RESP" >&2
173+
exit 6
174+
fi
175+
176+
OUT="$(mktemp -t gemini-code-review.XXXXXX.md)"
177+
printf '%s\n' "$CONTENT" | tee "$OUT"
178+
echo "[saved: $OUT · model: gemini-3.5-flash · diff: $LABEL · ${DIFF_CHARS} chars]" >&2

0 commit comments

Comments
 (0)