Skip to content

plugin(gemini-delegate): v0.1.0 — deterministic pipeline for Gemini CLI#100

Merged
nsalvacao merged 20 commits into
mainfrom
feat/gemini-delegate-v0.1.0
Apr 14, 2026
Merged

plugin(gemini-delegate): v0.1.0 — deterministic pipeline for Gemini CLI#100
nsalvacao merged 20 commits into
mainfrom
feat/gemini-delegate-v0.1.0

Conversation

@nsalvacao

Copy link
Copy Markdown
Owner

Summary

  • New plugin: gemini-delegate — mirrors qwen-delegate architecture, exploits Gemini-specific capabilities
  • Scripts layer: _lib.sh, delegate-summary.sh, delegate-format.sh, delegate-codegen.sh, delegate-research.sh (Google Search), delegate-analyze.sh (1M context), delegate-ui.sh (HTML/React/CSS), escalate-review.sh
  • Claude does not read Gemini output on the happy path — deterministic validators gate delivery
  • JSON output mode (--output-format json) + jq .response extraction — no text parsing of LLM output
  • Multi-model routing: gemini-2.5-flash for text tasks, gemini-2.5-pro for code/research/UI
  • Exit 41 (auth error) stops immediately — never retried
  • Security safelist identical to qwen-delegate (.env, *.pem, *.key denied at pre-flight)
  • --approval-mode plan (read-only) for all text tasks, --approval-mode yolo only for research (Google Search tool required)
  • Unique capabilities: Google Search grounding, 1M context window, HTML/React/CSS generation

Discovered during implementation

  • gemini-2.0-flash unavailable on personal Pro OAuth tier → using gemini-2.5-flash
  • JSON response field is .response (flat, confirmed with real Gemini v0.37.1 output)
  • gemini-2.5-pro may return 429 under load — documented in SKILL.md and README as known limitation
  • Smoke test for Pro-model scripts (research, analyze, ui) succeeded on analyze; research returned 429 transiently (transient capacity, not a script bug)

Test plan

  • test_lib.sh — 14 assertions, 0 failures (no real Gemini needed)
  • test_validators.sh — 12 assertions, 0 failures (offline)
  • delegate-summary.sh smoke — valid <gemini_output>, word-count retry fired correctly, exit 0
  • delegate-format.sh json smoke — idempotent JSON with sorted keys, exit 0
  • delegate-codegen.sh python smoke — valid Python + mypy clean, exit 0
  • delegate-analyze.sh smoke — valid analysis output listing all _lib.sh functions, exit 0
  • All 10 scripts shellcheck clean
  • All 4 markdown files markdownlint clean (0 errors)
  • marketplace.json + plugin.json valid JSON

🤖 Generated with Claude Code

Generated by Nuno Salvação nuno.salvacao@gmail.com & Co-Authored with: Nexo nexo.modeling@gmail.com

…, response extraction

Shared library for gemini-delegate plugin: exit code constants, stderr logging,
preflight auth/path-safelist checks, jq-based response extraction (.response/.content
fallback), retry wrapper with auth-error short-circuit, escalation output, and
present_output wrapper. 14/14 tests pass; shellcheck clean on both files.

Generated by Nuno Salvação <nuno.salvacao@gmail.com> & Co-Authored with: Nexo <nexo.modeling@gmail.com>
…th idempotency + syntax validators

Generated by Nuno Salvação <nuno.salvacao@gmail.com> & Co-Authored with: Nexo <nexo.modeling@gmail.com>
…lcheck validators, pro model

Generated by Nuno Salvação <nuno.salvacao@gmail.com> & Co-Authored with: Nexo <nexo.modeling@gmail.com>
… payload

Generated by Nuno Salvação <nuno.salvacao@gmail.com> & Co-Authored with: Nexo <nexo.modeling@gmail.com>
…6 delegation categories, model tiers

Generated by Nuno Salvação <nuno.salvacao@gmail.com> & Co-Authored with: Nexo <nexo.modeling@gmail.com>
…ries, error table

Generated by Nuno Salvação <nuno.salvacao@gmail.com> & Co-Authored with: Nexo <nexo.modeling@gmail.com>
…ch first for research, model tiers

Generated by Nuno Salvação <nuno.salvacao@gmail.com> & Co-Authored with: Nexo <nexo.modeling@gmail.com>
…ontext, UI generation

Generated by Nuno Salvação <nuno.salvacao@gmail.com> & Co-Authored with: Nexo <nexo.modeling@gmail.com>
Generated by Nuno Salvação <nuno.salvacao@gmail.com> & Co-Authored with: Nexo <nexo.modeling@gmail.com>
@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Plugin Review

🔴 1 critical, 🟡 3 warnings, 🔵 2 info across 7 files


🔴 CRITICAL · gemini-delegate/plugin.json · structure

Issue: The file is not in the correct location

Fix: Move to .claude-plugin/plugin.json

Confidence: 90%


🟡 WARNING · plugins/gemini-delegate/.claude-plugin/plugin.json · manifest

Issue: The manifest contains unknown fields (homepage, repository, license, keywords)

Fix: Remove or validate unknown fields against the official specification

Confidence: 90%


🟡 WARNING · plugins/gemini-delegate/commands/ask-gemini.md · command

Issue: The command contains direct paths to plugin scripts

Fix: Use ${CLAUDE_PLUGIN_ROOT} instead of hardcoding 'plugins/gemini-delegate'

Confidence: 90%


🟡 WARNING · plugins/gemini-delegate/commands/ask-gemini.md · security

Issue: The command executes bash scripts directly with user-controlled input

Fix: Validate and sanitize user input before passing it to bash scripts

Confidence: 80%


🔵 INFO · plugins/gemini-delegate/skills/gemini-delegate/SKILL.md · skill

Issue: The skill description is well-written and follows most guidelines

Fix: Minor improvement: consider adding more specific trigger phrases

Confidence: 90%


🔵 INFO · plugins/gemini-delegate/agents/gemini-advisor.md · agent

Issue: The agent description includes blocks as required

Fix: None needed

Confidence: 90%


AI Review · model: meta/llama-4-maverick-17b-128e-instruct-fp8 · 6181 tokens · 6 findings · GitHub Models free tier · 0 premium requests

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the gemini-delegate plugin, which enables Claude to offload various tasks such as summarization, research, and code generation to the Gemini CLI through a deterministic validation pipeline. The review feedback highlights several important technical improvements: addressing a security vulnerability related to insecure temporary file creation in _lib.sh, ensuring the presence of the jq dependency during pre-flight checks, and utilizing jq for robust JSON construction instead of fragile sed-based escaping. Additionally, the feedback suggests optimizing string concatenation in delegate-analyze.sh for better performance, refining markdown fence removal in delegate-codegen.sh to avoid accidental data loss, and improving the portability of hashing commands in delegate-format.sh.

Comment thread plugins/gemini-delegate/scripts/_lib.sh Outdated
Comment thread plugins/gemini-delegate/scripts/_lib.sh
Comment thread plugins/gemini-delegate/scripts/_lib.sh Outdated
Comment thread plugins/gemini-delegate/scripts/delegate-analyze.sh Outdated
Comment thread plugins/gemini-delegate/scripts/delegate-codegen.sh Outdated
Comment thread plugins/gemini-delegate/scripts/delegate-format.sh Outdated
- _lib.sh: use mktemp for stderr temp file (CWE-377 / R1)
- _lib.sh: add jq pre-flight check in gemini_preflight() (R2)
- _lib.sh: replace fragile sed JSON escaping with jq -n --arg in gemini_escalate() (R3)
- delegate-analyze.sh: replace O(N²) string concat with temp file approach (R4)
- delegate-codegen.sh: strip markdown fences only from first/last line (R5)

Generated by Nuno Salvação <nuno.salvacao@gmail.com> & Co-Authored with: Nexo <nexo.modeling@gmail.com>

@nsalvacao nsalvacao left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review item Decision Technical rationale
[R1] _lib.sh:87 — predictable /tmp/gemini_stderr_$$.txt (CWE-377) Accepted — implemented Replaced with mktemp /tmp/gemini_stderr_XXXXXX.txt + trap … RETURN; all manual rm -f calls removed.
[R2] _lib.sh:28 — no jq pre-flight check Accepted — implemented Added command -v jq guard at top of gemini_preflight(); failure exits with EXIT_PREFLIGHT_FAIL and actionable message.
[R3] _lib.sh:148 — fragile sed JSON escaping in gemini_escalate() Accepted — implemented Replaced with jq -n --arg … --argjson …; handles all control chars and multi-line error messages correctly. jq is now a verified dependency (R2).
[R4] delegate-analyze.sh:47 — O(N²) string concatenation Accepted — implemented Replaced CONTENT+="…" loop with printf … >> _content_file (mktemp); read once at end. Avoids quadratic re-allocation for 1M-token payloads.
[R5] delegate-codegen.sh:36sed '/^\``/d'` removes all fences Accepted with adaptation Changed to sed -e '1{/^\``/d}' -e '${/^```$/d}'` — strips only first/last lines. Prevents accidental deletion of fences inside docstrings or string literals. Applied to both fence-strip sites in the file.
[R6] delegate-format.sh:84sha256sum portability (macOS) Not accepted Linux/WSL is the declared target platform (consistent with qwen-delegate v0.2.0 which uses the same command). macOS portability is out of scope for this PR.
[R7] AI Review CRITICAL — plugin.json wrong location Not accepted False positive. plugins/gemini-delegate/.claude-plugin/plugin.json is the correct path per repo convention; identical to every other plugin in this marketplace.
[R8] AI Review WARNING — unknown fields in plugin.json Not accepted False positive. homepage, repository, license, keywords are present and accepted in qwen-delegate's plugin.json (already merged). Same convention applied here.
[R9] AI Review WARNING — hardcoded script paths in command Not accepted False positive. qwen-delegate's ask-qwen.md uses the same plugins/qwen-delegate/scripts/… pattern. ${CLAUDE_PLUGIN_ROOT} is not used anywhere in this repo.
[R10] AI Review WARNING — user input to bash scripts without sanitization Not accepted Prompts are passed as properly double-quoted strings (--prompt "$prompt") to the Gemini CLI binary, not eval'd as shell code. No shell injection surface exists. Consistent with qwen-delegate.
[CI1] CodeQL Pass — no action All checks green on HEAD.
[CI2] GitGuardian Pass — no action No secrets detected.
[CI3] OpenSSF Scorecard Pass — no action
[CI4] Preflight check Pass — no action
[CI5] Review changed plugins Pass — no action
[CI6] Validate plugins Pass — no action

@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Plugin Review

No issues found. All changed plugin components look good.


AI Review · model: ? · ? tokens · 0 findings · GitHub Models free tier · 0 premium requests

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces a new gemini-delegate plugin that delegates common tasks to the Gemini CLI behind deterministic, bash-based validators, plus documentation and offline tests.

Changes:

  • Added gemini-delegate plugin manifest, marketplace registration, README, skill, command, and agent docs.
  • Implemented delegation scripts for summary/format/codegen/research/analyze/UI with retry + validation + escalation flow.
  • Added offline test scripts and fixtures for library/validator behavior.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
plugins/gemini-delegate/skills/gemini-delegate/SKILL.md Skill definition and operational guidance for when/how to delegate to Gemini.
plugins/gemini-delegate/scripts/_lib.sh Core invocation/retry, response extraction, safelist checks, escalation, and output wrapping.
plugins/gemini-delegate/scripts/delegate-summary.sh Summarisation delegation + word-count and bullet-structure validation.
plugins/gemini-delegate/scripts/delegate-format.sh JSON/YAML/Markdown formatting delegation + validators (syntax/idempotency/linters).
plugins/gemini-delegate/scripts/delegate-codegen.sh Code generation delegation + language-specific validators (py_compile/mypy/tsc/shellcheck).
plugins/gemini-delegate/scripts/delegate-research.sh Research delegation using Search grounding (yolo) + minimum word-count validator.
plugins/gemini-delegate/scripts/delegate-analyze.sh Large-context analysis delegation over files/dirs/stdin with basic response validation.
plugins/gemini-delegate/scripts/delegate-ui.sh UI generation delegation (html/react/css) with structural validators and optional file write.
plugins/gemini-delegate/scripts/escalate-review.sh Helper to emit escalation payloads (currently appears unused).
plugins/gemini-delegate/scripts/tests/test_lib.sh Offline tests for _lib.sh helpers (exit codes, path safelist, JSON extraction).
plugins/gemini-delegate/scripts/tests/test_validators.sh Offline tests for validator behavior across summary/format/code/html checks.
plugins/gemini-delegate/scripts/tests/fixtures/sample.md Markdown fixture for tests.
plugins/gemini-delegate/scripts/tests/fixtures/sample.json JSON fixture for tests.
plugins/gemini-delegate/scripts/tests/fixtures/sample.html HTML fixture for tests.
plugins/gemini-delegate/commands/ask-gemini.md Command doc to dispatch tasks to the appropriate delegate script.
plugins/gemini-delegate/agents/gemini-advisor.md Agent doc for identifying delegation opportunities and routing.
plugins/gemini-delegate/README.md Plugin README: install/use, security model, categories, and known limitations.
plugins/gemini-delegate/LICENSE Plugin-local license text.
plugins/gemini-delegate/.claude-plugin/plugin.json Plugin manifest (name/version/metadata/license).
.claude-plugin/marketplace.json Registers the new gemini-delegate plugin in the marketplace index.

Comment thread plugins/gemini-delegate/scripts/_lib.sh Outdated
Comment thread plugins/gemini-delegate/scripts/_lib.sh Outdated
Comment thread plugins/gemini-delegate/scripts/delegate-analyze.sh
Comment thread plugins/gemini-delegate/.claude-plugin/plugin.json Outdated
Comment thread plugins/gemini-delegate/scripts/escalate-review.sh Outdated
Comment thread plugins/gemini-delegate/README.md Outdated
Comment thread plugins/gemini-delegate/scripts/delegate-format.sh Outdated
Comment thread plugins/gemini-delegate/scripts/_lib.sh Outdated
C1: gemini_check_path_safe — use *$pattern* substring matching to
    block nested secrets (config/.env, secrets/.env.prod, foo/.git/config).
    Patterns: .env.* → .env., .git/* → .git/ for correct glob behaviour.

C2: gemini_preflight — add command -v gemini check before auth check.

C3: delegate-analyze.sh — guard content >1.5MB before --prompt arg
    (OS ARG_MAX ~2MB on Linux; headroom for prompt wrapper + env).

C4: plugin.json — fix license "Apache-2.0" → "MIT" (matches LICENSE file).

C5: escalate-review.sh — correct misleading comment; script is standalone,
    _lib.sh::gemini_escalate() is the runtime code path.

C6: README.md — Python 3 listed as required (not graceful degradation);
    clarifies JSON validation and codegen validator dependency.

C7: delegate-format.sh — fence stripping: sed -e '1{/^```/d}' -e '${/^```$/d}'
    instead of /^```/d to avoid corrupting fences inside formatted content.

C8: _lib.sh gemini_invoke_with_retry — remove trap RETURN (global bash scope
    fires on every function return); add explicit rm -f before each exit/return.

Generated by Nuno Salvação <nuno.salvacao@gmail.com> & Co-Authored with: Nexo <nexo.modeling@gmail.com>
@nsalvacao

Copy link
Copy Markdown
Owner Author

Review Response — Round 2 (C1–C8)

All 8 Copilot findings from the second pass have been addressed in commit 9b33d2e.

ID File Decision Action
C1 scripts/_lib.shgemini_check_path_safe ✅ Fix Changed $pattern)*$pattern*) for substring matching; .env.*.env., .git/*.git/ — now blocks nested paths (config/.env, secrets/.env.prod, foo/.git/config)
C2 scripts/_lib.shgemini_preflight ✅ Fix Added command -v gemini check before auth check; provides actionable install error instead of obscure failure
C3 scripts/delegate-analyze.sh ✅ Fix Added 1.5 MB size guard before building --prompt argument (OS ARG_MAX ~2MB on Linux; guard leaves headroom for prompt wrapper + env)
C4 .claude-plugin/plugin.json ✅ Fix "license": "Apache-2.0""MIT" — matches actual LICENSE file content
C5 scripts/escalate-review.sh ✅ Fix Corrected misleading comment: script is a standalone helper; _lib.sh::gemini_escalate() is the runtime code path (it never calls this script)
C6 README.md ✅ Fix Python 3 listed as required with specific scope (JSON validation + codegen validators); removed "graceful degradation" which was inaccurate
C7 scripts/delegate-format.sh ✅ Fix Fence stripping changed to sed -e '1{/^```/d}' -e '${/^```$/d}' — strips only first and last lines, consistent with delegate-codegen.sh; avoids corrupting fences inside formatted markdown/code content
C8 scripts/_lib.shgemini_invoke_with_retry ✅ Fix Removed trap 'rm -f "$_stderr_file"' RETURN (bash traps are global — would fire on every function return in the calling script); replaced with explicit rm -f "$_stderr_file" before every exit/return path

All scripts pass shellcheck and unit tests (14/14 test_lib.sh, 12/12 test_validators.sh).

@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Plugin Review

No issues found. All changed plugin components look good.


AI Review · model: ? · ? tokens · 0 findings · GitHub Models free tier · 0 premium requests

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 8 comments.

Comment thread plugins/gemini-delegate/scripts/_lib.sh Outdated
Comment thread plugins/gemini-delegate/scripts/_lib.sh
Comment thread plugins/gemini-delegate/scripts/escalate-review.sh Outdated
Comment thread plugins/gemini-delegate/scripts/delegate-format.sh Outdated
Comment thread plugins/gemini-delegate/scripts/tests/test_validators.sh Outdated
Comment thread plugins/gemini-delegate/scripts/delegate-ui.sh Outdated
Comment thread plugins/gemini-delegate/skills/gemini-delegate/SKILL.md Outdated
Comment thread plugins/gemini-delegate/scripts/_lib.sh Outdated
D1/D7: rename "safelist" → "denylist" in _lib.sh comments/log and
       SKILL.md section heading — safelist means allowlist; this logic
       is a blocklist. Terminology fix only, behaviour unchanged.

D2: fix max_retries semantics — change loop from `attempt < max_retries`
    to `attempt <= max_retries` so GEMINI_DELEGATE_MAX_RETRIES=2 means
    initial attempt + 2 retries (3 total), consistent with the variable
    name and qwen-delegate. Update log message and exhausted message.

D3: escalate-review.sh — replace heredoc JSON interpolation with
    jq -n --arg/--argjson to prevent JSON injection via args containing
    quotes or newlines (same approach as _lib.sh::gemini_escalate).

D3b: fix "${3:-{}}" bash parsing bug in both escalate-review.sh and
     _lib.sh::gemini_escalate — when $3 is set, the literal `}` after
     the expansion was appended, producing invalid JSON. Fixed with
     two-step assignment: "${3:-}" then [[ -z ]] check.

D4/D5: sha256sum portability — use `(sha256sum 2>/dev/null || shasum -a 256)`
       in delegate-format.sh and test_validators.sh so JSON idempotency
       check works on macOS (shasum -a 256) and Linux (sha256sum).

D6: delegate-ui.sh header comment — remove "(after user review)" which
    contradicts the implementation; script writes immediately with a
    log_warn, not after confirmation.

D8: fix .git pattern in gemini_check_path_safe — bare ".git" substring
    pattern would match .github/ paths (e.g. .github/actions/workflow.yml).
    Replace with an explicit case block covering .git|.git/*|*/.git|*/.git/*
    that correctly blocks .git internals without touching .github. Remove
    now-redundant ".git" and ".git/" from the denylist array.
    Add 3 regression tests (T5b/c/d) in test_lib.sh: .git blocked,
    foo/.git/config blocked, .github path allowed. Tests: 17/17 pass.

Generated by Nuno Salvação <nuno.salvacao@gmail.com> & Co-Authored with: Nexo <nexo.modeling@gmail.com>
@nsalvacao

Copy link
Copy Markdown
Owner Author

Review Response — Round 3 (D1–D8)

All 8 Copilot findings from the third pass addressed in commit 4837f0f.

Review item Decision Technical rationale
[D1] _lib.sh:54 — "safelist" terminology Accepted — implemented "Safelist" means allowlist; this is a blocklist. Renamed to "denylist" in comments and log message. Behaviour unchanged.
[D2] _lib.sh:96max_retries total-attempts vs retries semantics Accepted — implemented Changed attempt < max_retriesattempt <= max_retries; GEMINI_DELEGATE_MAX_RETRIES=2 now means 3 total attempts (initial + 2 retries), consistent with the variable name and qwen-delegate. Updated log and exhausted message.
[D3] escalate-review.sh:24 — JSON injection via arg interpolation Accepted — implemented Replaced heredoc with jq -n --arg/--argjson, matching _lib.sh::gemini_escalate. Also fixed a latent "${3:-{}}" bash parsing bug (when $3 is set the literal } was appended, producing invalid JSON); fixed in both escalate-review.sh and _lib.sh::gemini_escalate with two-step assignment.
[D4] delegate-format.sh:88sha256sum not available on macOS Accepted — implemented (sha256sum 2>/dev/null || shasum -a 256) fallback; works on macOS and Linux.
[D5] test_validators.sh:69 — same sha256sum portability Accepted — implemented Same fallback applied to test file.
[D6] delegate-ui.sh:6 — comment "after user review" contradicts implementation Accepted — implemented Changed to "writes output directly to file" — the script logs a warning but writes immediately; no confirmation step exists.
[D7] SKILL.md:35 — "security safelist" section heading Accepted — implemented Renamed to "security denylist" — consistent with D1 and with the actual blocking behaviour.
[D8] _lib.sh:55.git pattern blocks .github/ paths Accepted — implemented Bare .git substring pattern matched .github/actions/... via *$pattern*. Replaced with a dedicated case .git|.git/*|*/.git|*/.git/*) block that correctly blocks git internals without touching .github. Removed the redundant .git/.git/ entries from the denylist array. Added 3 regression tests (T5b/c/d) in test_lib.sh: test_lib.sh now 17/17 pass.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Plugin Review

No issues found. All changed plugin components look good.


AI Review · model: ? · ? tokens · 0 findings · GitHub Models free tier · 0 premium requests

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 5 comments.

Comment thread plugins/gemini-delegate/scripts/_lib.sh
Comment thread plugins/gemini-delegate/scripts/delegate-ui.sh Outdated
Comment thread plugins/gemini-delegate/scripts/delegate-analyze.sh
Comment thread plugins/gemini-delegate/scripts/tests/test_validators.sh Outdated
Comment thread plugins/gemini-delegate/scripts/_lib.sh
E1: add gemini_check_python3() helper to _lib.sh — checks that python3
    is installed before running Python-based validators. Call it in
    delegate-format.sh (json.tool) and delegate-codegen.sh (py_compile)
    immediately after gemini_preflight. Not added to global preflight
    to avoid blocking scripts that don't need python3 (research, summary,
    analyze, ui). Provides a clear, actionable error instead of a generic
    "command not found" deep in the validator path.

E2: delegate-ui.sh — fix fence stripping: sed -e '1{/^```/d}' -e '${/^```$/d}'
    (first/last line only) instead of /^```/d (all lines). Same fix as
    C7/delegate-format.sh — avoids corrupting template literals or embedded
    code examples in generated HTML/React/CSS output.

E3: delegate-analyze.sh — log "characters" → "bytes" to match wc -c
    semantics and the guard error message (which correctly said "bytes").

E4: test_validators.sh — fix comment: only gemini_preflight is mocked,
    not gemini_invoke_with_retry. Removed the inaccurate claim.

Generated by Nuno Salvação <nuno.salvacao@gmail.com> & Co-Authored with: Nexo <nexo.modeling@gmail.com>
@nsalvacao

Copy link
Copy Markdown
Owner Author

Review Response — Round 4 (E1–E5)

All actionable findings from the fourth Copilot pass addressed in commit 14735d8.

Review item Decision Technical rationale
[E1] _lib.sh:40 — no python3 pre-flight check Accepted with adaptation — implemented Added gemini_check_python3() helper to _lib.sh; called in delegate-format.sh (uses json.tool) and delegate-codegen.sh (uses py_compile). Not added to the global gemini_preflight()delegate-research.sh, delegate-summary.sh, delegate-analyze.sh, and delegate-ui.sh don't use python3 and would be unnecessarily broken on python3-free systems.
[E2] delegate-ui.sh:72sed '/^```/d' strips all fences Accepted — implemented Applied the same C7/D7 fix: sed -e '1{/^```/d}' -e '${/^```$/d}' strips only the first and last lines, preserving template literals and embedded code examples in generated HTML/React/CSS.
[E3] delegate-analyze.sh:60 — log says "characters" but wc -c measures bytes Accepted — implemented Changed log message from "characters" to "bytes" — consistent with wc -c semantics and the guard error message.
[E4] test_validators.sh:31 — comment claims gemini_invoke_with_retry is mocked when it isn't Accepted — implemented Corrected the comment: only gemini_preflight is mocked; gemini_invoke_with_retry is never called in this test file.
[E5] _lib.sh:67 — denylist matching is case-sensitive (.ENV, SERVER.PEM not blocked) Not accepted On Linux/WSL (the target platform), filesystems are case-sensitive — .ENV and .env are physically different files and convention dictates lowercase. Adding shopt -s nocasematch has global bash scope side effects. Uppercase variants would double the pattern count. Deferred to Phase B with a documented known limitation.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Plugin Review

🟡 5 warnings, 🔵 1 info across 7 files


🟡 WARNING · plugins/gemini-delegate/.claude-plugin/plugin.json · manifest

Issue: The manifest contains unknown fields (homepage, repository, license, keywords)

Fix: Remove or validate unknown fields against the official specification

Confidence: 90%


🟡 WARNING · plugins/gemini-delegate/commands/ask-gemini.md · command

Issue: The command contains direct paths to local files/scripts in the examples

Fix: Use ${CLAUDE_PLUGIN_ROOT} instead of hardcoding 'plugins/gemini-delegate'

Confidence: 90%


🟡 WARNING · plugins/gemini-delegate/skills/gemini-delegate/SKILL.md · skill

Issue: The skill contains direct paths to local files/scripts in the examples

Fix: Use ${CLAUDE_PLUGIN_ROOT} instead of hardcoding 'plugins/gemini-delegate'

Confidence: 90%


🟡 WARNING · plugins/gemini-delegate/commands/ask-gemini.md · security

Issue: The command executes bash scripts directly with user-controlled input

Fix: Validate and sanitize user input before passing it to bash scripts

Confidence: 80%


🟡 WARNING · plugins/gemini-delegate/skills/gemini-delegate/SKILL.md · security

Issue: The skill executes bash scripts directly with potentially user-controlled content

Fix: Ensure proper validation and sanitization of content before passing to bash scripts

Confidence: 80%


🔵 INFO · plugins/gemini-delegate/skills/gemini-delegate/SKILL.md · skill

Issue: The skill description contains version field which is not required

Fix: Remove the version field from the frontmatter

Confidence: 90%


AI Review · model: meta/llama-4-maverick-17b-128e-instruct-fp8 · 6219 tokens · 6 findings · GitHub Models free tier · 0 premium requests

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 4 comments.

Comment thread plugins/gemini-delegate/scripts/delegate-format.sh Outdated
Comment thread plugins/gemini-delegate/scripts/delegate-ui.sh
Comment thread plugins/gemini-delegate/README.md
Comment thread plugins/gemini-delegate/scripts/delegate-codegen.sh
F1: delegate-format.sh JSON validator — replace python3 -m json.tool
    with jq for both syntax check and normalization:
    - syntax: `jq . > /dev/null` (exits non-zero on invalid JSON)
    - normalize: `jq --indent 2 -S .` (2-space indentation + sorted keys)
    python3 -m json.tool emitted 4-space indent and unsorted keys,
    violating the stated formatting contract. jq is already a required
    dependency (pre-flight check). Remove gemini_check_python3 from
    delegate-format.sh (python3 no longer used there).
    Update test_validators.sh JSON section to use jq consistently.

F2: delegate-ui.sh OUTPUT_FILE path traversal — reject absolute paths
    (leading /) and paths containing '..' before the denylist check and
    write. Prevents arbitrary file overwrite via e.g. '../../etc/cron.d/x'.

F3: README.md — replace inaccurate "max 2x" retry claim with
    "up to GEMINI_DELEGATE_MAX_RETRIES retries per call". Scripts can
    invoke gemini_invoke_with_retry multiple times (e.g. format-json
    invokes twice on syntax error; codegen up to 3× in the compile loop);
    the env var already documents the configurable retry count.

Generated by Nuno Salvação <nuno.salvacao@gmail.com> & Co-Authored with: Nexo <nexo.modeling@gmail.com>
@nsalvacao

Copy link
Copy Markdown
Owner Author

Review Response — Round 5 (E1–E5 re-review + F1–F3)

Prior round findings E1–E4 were implemented in commit 14735d8. E5 was not accepted (rationale in previous comment). This round addresses the 3 new findings (F1–F3) in commit df0c099.

Review item Decision Technical rationale
[E1] _lib.sh — python3 pre-flight Accepted with adaptation — implemented (14735d8) gemini_check_python3() added to _lib.sh; called in scripts that need it, not in global preflight. After F1, delegate-format.sh no longer needs python3; the call was removed there.
[E2] delegate-ui.shsed '/^```/d' strips all fences Accepted — implemented (14735d8) Fixed to sed -e '1{/^```/d}' -e '${/^```$/d}' (first/last line only).
[E3] delegate-analyze.sh — "characters" vs bytes Accepted — implemented (14735d8) Log message changed to "bytes" to match wc -c semantics.
[E4] test_validators.sh — comment claims more mocks than exist Accepted — implemented (14735d8) Comment corrected: only gemini_preflight is mocked.
[E5] Denylist case-sensitivity Not accepted On Linux/WSL (target platform) filesystems are case-sensitive; shopt -s nocasematch has global bash scope side effects. Deferred to Phase B.
[F1] delegate-format.sh:92python3 -m json.tool mismatches 2-space + sorted-keys contract Accepted — implemented (df0c099) Replaced with jq --indent 2 -S . for both syntax check and normalization. jq is already a required dependency; python3 -m json.tool emits 4-space indent and does not sort keys. Removed gemini_check_python3 from delegate-format.sh (python3 no longer used). Updated test_validators.sh JSON section to use jq consistently.
[F2] delegate-ui.sh:122 — OUTPUT_FILE path traversal Accepted — implemented (df0c099) Added guard before the write: reject paths starting with / (absolute) or containing .. (traversal). Prevents overwriting arbitrary files outside the workspace.
[F3] README.md:88 — "max 2×" retry count inaccurate Accepted with adaptation — implemented (df0c099) Changed to "up to GEMINI_DELEGATE_MAX_RETRIES retries per call" — scripts can call gemini_invoke_with_retry multiple times (format-json: 2×; codegen compile-fix: up to 3×); the env var documents the configurable per-call retry count.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Plugin Review

No issues found. All changed plugin components look good.


AI Review · model: ? · ? tokens · 0 findings · GitHub Models free tier · 0 premium requests

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.

Comment thread plugins/gemini-delegate/scripts/delegate-ui.sh Outdated
React `export` check was warn-only; a component without export is
unimportable and just as unusable as one without `return`. Apply the
same retry-then-escalate pattern as the HTML DOCTYPE validator:
- retry once with explicit instruction to include export
- escalate with '{"export":"fail"}' if still absent after retry

This aligns with "deterministic validators gate delivery" — invalid
components no longer pass the pipeline silently.

Generated by Nuno Salvação <nuno.salvacao@gmail.com> & Co-Authored with: Nexo <nexo.modeling@gmail.com>
@nsalvacao

Copy link
Copy Markdown
Owner Author

Review Response — Round 6 (G1)

Addressed in commit 0db2461.

Review item Decision Technical rationale
[G1] delegate-ui.sh:98-104 — React export check is warn-only, not retry/escalate Accepted — implemented A React component without export is unimportable and unusable, same severity as a missing return. Applied the retry-then-escalate pattern consistent with the HTML DOCTYPE validator: retry once with explicit export instruction, then gemini_escalate "ui-react" ... '{"export":"fail"}' if still absent. Removes the inconsistency where return escalated but export only warned.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Plugin Review

No issues found. All changed plugin components look good.


AI Review · model: ? · ? tokens · 0 findings · GitHub Models free tier · 0 premium requests

@nsalvacao nsalvacao merged commit 6d266ec into main Apr 14, 2026
7 checks passed
@nsalvacao nsalvacao deleted the feat/gemini-delegate-v0.1.0 branch April 14, 2026 21:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants