From 653ccd7f2ffa802b92db1fd7780e81c32774d2bf Mon Sep 17 00:00:00 2001 From: azmym Date: Fri, 29 May 2026 18:58:53 +0200 Subject: [PATCH] feat: add /gemini-plugin:gemini-doctor diagnostic command (v0.5.0) --- .claude-plugin/plugin.json | 2 +- CHANGELOG.md | 6 +++ README.md | 3 +- commands/gemini-doctor.md | 108 +++++++++++++++++++++++++++++++++++++ docs/index.md | 4 +- docs/reference/commands.md | 24 ++++++++- tests/commands.bats | 13 +++-- 7 files changed, 152 insertions(+), 8 deletions(-) create mode 100644 commands/gemini-doctor.md diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 4ee3f5a..50ea335 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "gemini-plugin", "displayName": "Gemini Plugin", - "version": "0.4.1", + "version": "0.5.0", "description": "Wraps gemini-mcp into a Claude Code plugin so Gemini acts as a second opinion: validator/challenger/researcher/summarizer/reviewer subagents, auto-trigger hooks, and 9 task-oriented skills.", "author": { "name": "azmym" }, "homepage": "https://github.com/azmym/gemini-plugin", diff --git a/CHANGELOG.md b/CHANGELOG.md index 42bdd4a..59031be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to gemini-plugin are documented here. The format follows [Ke ## [Unreleased] +## [0.5.0] - 2026-05-29 + +### Added + +- **`/gemini-plugin:gemini-doctor` command.** A one-step self-diagnostic that distinguishes a real Gemini outage from a stale session. It runs four checks: (1) API key configured, (2) the MCP server is reachable from the main agent (resolves the tool under either the plugin namespace `mcp__plugin_gemini-plugin_gemini__*` or the manual-install namespace `mcp__gemini__*`, then calls it for real), (3) the subagent grounding path works by spawning `gemini-researcher` and confirming it actually sees a Gemini tool, and (4) the on-disk plugin version. When checks 1 and 2 pass but check 3 fails, it reports STALE SESSION and tells the user to restart Claude Code. This is the common cause of "grounding produced nothing" reports: the MCP server works, but a session started before a plugin update still has the outdated agent definitions loaded in memory. + ## [0.4.1] - 2026-05-29 ### Fixed diff --git a/README.md b/README.md index d269770..57dd2cc 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ The two are separate surfaces: commands are listed below under [Slash commands]( ## Slash commands -Five commands, all under the `/gemini-plugin:` prefix. +Six commands, all under the `/gemini-plugin:` prefix. | Command | Arguments | What it does | |---|---|---| @@ -108,6 +108,7 @@ Five commands, all under the `/gemini-plugin:` prefix. | `/gemini-plugin:gemini-research` | ` [--deep]` | Quick web search with citations; add `--deep` for multi-source synthesis. Spawns `gemini-researcher`. | | `/gemini-plugin:gemini-brainstorm-off` | (none) | Opt out of grounding-on-every-prompt; fall back to narrow keyword matching. Recommended for chatty sessions to control cost. | | `/gemini-plugin:gemini-brainstorm-on` | (none) | Re-enable grounding on every prompt after a previous opt-out (this is the default after install). | +| `/gemini-plugin:gemini-doctor` | (none) | Diagnose whether Gemini grounding works in this session. Checks the API key, the MCP server (main agent), and the subagent path; flags a stale session that needs a restart. | There is no `gemini-review` command: diff review runs through the `gemini-consult` skill, which dispatches the `gemini-reviewer` subagent. See [Subagents](#subagents). diff --git a/commands/gemini-doctor.md b/commands/gemini-doctor.md new file mode 100644 index 0000000..d57d977 --- /dev/null +++ b/commands/gemini-doctor.md @@ -0,0 +1,108 @@ +--- +description: Diagnose whether the Gemini MCP server and the subagent grounding path are working in this session +allowed-tools: Read, Bash, ToolSearch +argument-hint: (no arguments) +--- + +You are running the /gemini-plugin:gemini-doctor slash command. Your job is to +diagnose, with EVIDENCE, whether Gemini grounding actually works in THIS session, +and to distinguish a real outage from a stale session that needs a restart. + +Run all four checks below, then print the summary table. Do not skip a check +because an earlier one failed; each is independent diagnostic signal. + +## Check 1: API key configured + +Read the API key presence WITHOUT printing the key itself. Run: + +``` +test -n "${CLAUDE_PLUGIN_OPTION_GEMINI_API_KEY:-}${GEMINI_API_KEY:-}" && echo "key: present" || echo "key: MISSING" +``` + +PASS if "key: present". If MISSING, the user has not configured the API key +(re-run plugin install, or set it in plugin config). + +## Check 2: MCP server reachable from the MAIN agent + +Use ToolSearch with the query +`select:mcp__plugin_gemini-plugin_gemini__gemini_search_grounded` to load the +tool schema. If that returns no match, also try +`select:mcp__gemini__gemini_search_grounded` (the namespace used for a manual, +non-plugin install). + +- PASS if either tool schema loads. Record the exact tool name that matched; + call this RESOLVED_TOOL. +- FAIL if neither loads (the MCP server is not registered in this session). + +If a tool resolved, CALL it once with a trivial query (parameter is `prompt`), +for example `{"prompt": "what is the current stable Node.js LTS version"}`. + +- PASS if it returns real results with citation URLs. +- FAIL if the call errors (server registered but not responding, for example a + bad API key or the uvx process failing to start). + +## Check 3: Subagent grounding path (THE important one) + +This is the check that catches the stale-session bug: the main agent can reach +the MCP server, but the gemini-researcher subagent loaded at session start has +an outdated definition and cannot. + +Spawn @agent-gemini-plugin:gemini-researcher with this exact task: + +``` +DIAGNOSTIC: Report the exact names of every tool in your inventory whose name +contains "gemini" or "search". Then, if you have a grounded-search tool, call it +with the query "current stable Node.js LTS version" and report whether it +returned real URLs. Return your JSON verdict with the resolved tool name in the +reasoning field, or "NO GEMINI TOOL IN INVENTORY" if you have none. +``` + +Block until the researcher returns. Then judge: + +- PASS if the researcher reports a Gemini search tool in its inventory AND its + verdict confidence is NOT "unavailable" (it grounded for real). +- FAIL if the researcher reports "NO GEMINI TOOL IN INVENTORY" or returns + confidence "unavailable". + +## Check 4: Installed version on disk + +Run: + +``` +cat "${CLAUDE_PLUGIN_ROOT}/.claude-plugin/plugin.json" 2>/dev/null | grep '"version"' || echo "version: unknown" +``` + +Report the on-disk plugin version. This is the version the NEXT fresh session +will load, which may differ from what this session is running in memory. + +## Summary and diagnosis + +Print a table: + +``` +Gemini Plugin Doctor +-------------------------------------------- +1. API key configured PASS | FAIL +2. MCP server (main agent) PASS | FAIL (resolved tool: ) +3. Subagent grounding path PASS | FAIL +4. On-disk version +-------------------------------------------- +``` + +Then give ONE clear diagnosis, choosing the first that matches: + +- Check 1 FAIL: "Gemini API key is not configured. Set it in the plugin + config (re-run the install, or set GEMINI_API_KEY)." +- Check 2 FAIL (key present): "The Gemini MCP server is not reachable. The uvx + process may be failing to start, or the API key may be rejected. Check that + `uv` is installed and the key is valid." +- Check 2 PASS but Check 3 FAIL: "STALE SESSION. The MCP server works, but the + gemini-researcher subagent in this session was loaded from an outdated plugin + definition and cannot see the Gemini tools. Restart Claude Code to load the + current agents (on-disk version is shown in check 4). This is the most common + cause of 'grounding produced nothing' reports." +- All of 1, 2, 3 PASS: "Healthy. Gemini grounding works in this session, in both + the main agent and the subagent path." + +Be precise and factual. Report what the checks actually returned; do not claim a +PASS you did not observe. diff --git a/docs/index.md b/docs/index.md index 75c64dc..e5c30b8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -16,7 +16,7 @@ A Claude Code plugin that turns Google Gemini into a second-opinion assistant la | [Skills](reference/skills.md) | All 9 skills with descriptions and MCP tool mappings | | [Subagents](reference/subagents.md) | All 5 subagents with frontmatter, tools, and output schemas | | [Hooks](reference/hooks.md) | All 7 hooks with event types, gates, and exit behavior | -| [Commands](reference/commands.md) | All 5 slash commands with usage examples | +| [Commands](reference/commands.md) | All 6 slash commands with usage examples | | **Explanation** | | | [Design decisions](explanation/design-decisions.md) | Why single-turn validation, why these gates, cost tradeoffs | @@ -34,7 +34,7 @@ Plugin installs via marketplace │ researcher, summarizer, │ │ reviewer │ │ 7 hooks - auto-trigger on key events │ -│ 5 commands - manual slash invocation │ +│ 6 commands - manual slash invocation │ │ 1 rule - session-level guidance │ │ │ │ MCP: gemini-mcp (13 tools, pinned v0.2.0) │ diff --git a/docs/reference/commands.md b/docs/reference/commands.md index ea09d9b..f557b7b 100644 --- a/docs/reference/commands.md +++ b/docs/reference/commands.md @@ -1,6 +1,6 @@ # Commands Reference -The plugin ships 5 slash commands. Three invoke subagents for manual consultation. Two toggle brainstorming mode. +The plugin ships 6 slash commands. Three invoke subagents for manual consultation. Two toggle brainstorming mode. One diagnoses the session. ## Command index @@ -11,6 +11,7 @@ The plugin ships 5 slash commands. Three invoke subagents for manual consultatio | `/gemini-plugin:gemini-research` | gemini-researcher | Grounded research | | `/gemini-plugin:gemini-brainstorm-on` | (none) | Enable unconditional grounding | | `/gemini-plugin:gemini-brainstorm-off` | (none) | Disable unconditional grounding | +| `/gemini-plugin:gemini-doctor` | gemini-researcher (probe) | Diagnose the MCP server and subagent grounding path | ## gemini-validate @@ -103,3 +104,24 @@ The plugin ships 5 slash commands. Three invoke subagents for manual consultatio **Behavior:** Creates `brainstorm.off` in `${CLAUDE_PLUGIN_DATA}`. While this file exists, the `UserPromptSubmit` hook only fires on prompts that match a narrow keyword regex (e.g. "latest version of X", "CVE-YYYY-NNN", "changelog for X"). Recommended for chatty sessions where you want to control cost. **Confirmation message:** "Brainstorming mode OFF. Gemini will only ground prompts that match post-cutoff keyword patterns." + +## gemini-doctor + +**Usage:** + +``` +/gemini-plugin:gemini-doctor +``` + +**Arguments:** none + +**Behavior:** Runs four diagnostic checks and prints a pass/fail summary: + +1. **API key configured.** Confirms `CLAUDE_PLUGIN_OPTION_GEMINI_API_KEY` or `GEMINI_API_KEY` is set, without printing the key. +2. **MCP server reachable from the main agent.** Resolves the grounded-search tool under either the plugin namespace (`mcp__plugin_gemini-plugin_gemini__gemini_search_grounded`) or the manual-install namespace (`mcp__gemini__gemini_search_grounded`), then calls it once to confirm live results with citation URLs. +3. **Subagent grounding path.** Spawns `gemini-researcher` and confirms it actually sees a Gemini tool in its inventory and grounds for real. This is the check that catches the most common failure. +4. **On-disk version.** Reports the plugin version in `${CLAUDE_PLUGIN_ROOT}/.claude-plugin/plugin.json`, which is what the next fresh session will load. + +**Why it exists:** the most common "grounding produced nothing" report is a **stale session**: the MCP server works (check 2 passes), but a session started before a plugin update still has the outdated subagent definitions loaded in memory (check 3 fails). Subagent definitions are loaded at session start and are not reloaded when the plugin updates on disk. When the doctor sees check 2 pass and check 3 fail, it tells the user to restart Claude Code. + +**Diagnosis output:** one line identifying the first failing condition (missing key, server unreachable, stale session, or healthy). diff --git a/tests/commands.bats b/tests/commands.bats index 46f0f15..796fd72 100644 --- a/tests/commands.bats +++ b/tests/commands.bats @@ -2,22 +2,23 @@ COMMANDS_DIR="commands" -@test "all 5 command files exist" { +@test "all 6 command files exist" { [ -f "$COMMANDS_DIR/gemini-validate.md" ] [ -f "$COMMANDS_DIR/gemini-challenge.md" ] [ -f "$COMMANDS_DIR/gemini-research.md" ] [ -f "$COMMANDS_DIR/gemini-brainstorm-on.md" ] [ -f "$COMMANDS_DIR/gemini-brainstorm-off.md" ] + [ -f "$COMMANDS_DIR/gemini-doctor.md" ] } @test "all commands have description in frontmatter" { - for cmd in gemini-validate gemini-challenge gemini-research gemini-brainstorm-on gemini-brainstorm-off; do + for cmd in gemini-validate gemini-challenge gemini-research gemini-brainstorm-on gemini-brainstorm-off gemini-doctor; do grep -q "^description:" "$COMMANDS_DIR/$cmd.md" done } @test "all commands have --- frontmatter delimiters" { - for cmd in gemini-validate gemini-challenge gemini-research gemini-brainstorm-on gemini-brainstorm-off; do + for cmd in gemini-validate gemini-challenge gemini-research gemini-brainstorm-on gemini-brainstorm-off gemini-doctor; do HEAD=$(head -1 "$COMMANDS_DIR/$cmd.md") [ "$HEAD" = "---" ] done @@ -29,6 +30,12 @@ COMMANDS_DIR="commands" grep -q "gemini-researcher" "$COMMANDS_DIR/gemini-research.md" } +@test "doctor command checks both the MCP server and the subagent path" { + grep -q "gemini-researcher" "$COMMANDS_DIR/gemini-doctor.md" + grep -q "mcp__plugin_gemini-plugin_gemini__gemini_search_grounded" "$COMMANDS_DIR/gemini-doctor.md" + grep -qi "stale session" "$COMMANDS_DIR/gemini-doctor.md" +} + @test "research command mentions --deep flag" { grep -q "\-\-deep" "$COMMANDS_DIR/gemini-research.md" }