Skip to content

feat: auto-generate Gemini CLI extension from Claude plugins - #369

Merged
openshift-merge-bot[bot] merged 1 commit into
openshift-eng:mainfrom
zhfeng:feat/gemini-extension-conversion
Mar 13, 2026
Merged

openshift-merge-bot[bot] merged 1 commit into
openshift-eng:mainfrom
zhfeng:feat/gemini-extension-conversion

Conversation

@zhfeng

@zhfeng zhfeng commented Mar 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Add scripts/convert_to_gemini.py to convert Claude Code plugins into a Gemini CLI extension.

  • Single-pass regex for Claude → Gemini text replacement (avoids recursive replacement issues)
  • YAML frontmatter parsed via yaml.safe_load (handles colons, multi-line values)
  • TOML description field uses triple-quote ''' syntax (handles newlines, special chars)
  • Skills nested under skills/{plugin}/{skill}/ to preserve path structure
  • ${CLAUDE_PLUGIN_ROOT} mapped to ${extensionPath} with correct skill path rewriting
  • adapt_text() applied to both command prompts and skill .md files
  • Atomic sync via staged .tmp + rename to avoid data loss on interruption
  • Auto-bump patch version only when content actually changes
  • --check mode for CI gating

Usage

# Convert all plugins
python3 scripts/convert_to_gemini.py

# Convert a single plugin for testing
python3 scripts/convert_to_gemini.py --plugin git

# Check if generated files are in sync
python3 scripts/convert_to_gemini.py --check

Text replacements

Claude Gemini
Claude Code plugin Gemini CLI extension
Claude Code Gemini CLI
Claude Gemini
https://claude.com/claude-code https://github.com/google-gemini/gemini-cli
~/.config/claude-code/ ~/.gemini/
CLAUDE.md GEMINI.md
.claude/ .gemini/
claude-code gemini-cli
claude gemini
${CLAUDE_PLUGIN_ROOT}/skills/X ${extensionPath}/skills/{plugin}/X
${CLAUDE_PLUGIN_ROOT} ${extensionPath}

Test plan

  • Full conversion of 33 plugins succeeds with valid TOML output
  • Running conversion twice produces no changes (idempotent)
  • --plugin git then --plugin ci bumps version from 1.0.0 to 1.0.1
  • --plugin git twice detects no changes, skips version bump
  • --check mode passes after full conversion
  • ${CLAUDE_PLUGIN_ROOT}/skills/suggest-reviewers/ correctly maps to ${extensionPath}/skills/git/suggest-reviewers/
  • All CLAUDE_PLUGIN_ROOT skill paths verified across all plugins
  • Case-insensitive grep finds only 1 remaining claude ref (Python code comment in .py file)
  • Skill .md files have text replacements applied
  • Descriptions with colons parsed correctly via yaml.safe_load

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Mar 9, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

This PR adds Gemini CLI support to the project by introducing a conversion script that transforms Claude Code plugins into Gemini CLI extensions. It updates project documentation to describe dual compatibility with Claude Code and Gemini CLI, adds a build target for running the conversion, and configures code review to exclude generated files.

Changes

Cohort / File(s) Summary
Build Tooling
Makefile
Added convert-to-gemini target that invokes the conversion script to transform Claude plugins to Gemini CLI extensions.
Project Documentation
README.md
Updated description to reflect dual AI coding assistant support (Claude Code and Gemini CLI). Added Gemini CLI usage section with installation, usage, and update instructions. Documented generated files (commands/, skills/, GEMINI.md, gemini-extension.json) with note not to edit manually.
Code Review Configuration
.coderabbit.yaml
Added path_filters to exclude generated Gemini files from review: commands/**, skills/**, GEMINI.md, gemini-extension.json.
Conversion Script
scripts/convert_to_gemini.py
New Python script that converts Claude Code plugins to Gemini CLI extensions. Discovers plugins, converts commands from Markdown to TOML format, copies skills with plugin-prefixed names, generates GEMINI.md context file and gemini-extension.json manifest, manages versioning, and includes check mode for synchronization verification with diffing capabilities.

Sequence Diagram

sequenceDiagram
    participant User
    participant Script as convert_to_gemini.py
    participant FS as File System
    participant Manifest as gemini-extension.json
    participant Context as GEMINI.md

    User->>Script: Run conversion (--plugin or default)
    Script->>FS: Discover plugins/ directories
    FS-->>Script: Return plugin list
    
    loop For each plugin
        Script->>FS: Read plugin.json & commands/
        FS-->>Script: Plugin metadata & MD files
        Script->>Script: Convert MD to TOML (extract frontmatter)
        Script->>FS: Write commands/{plugin}/*.toml
        
        Script->>FS: Read skills/ from plugin
        FS-->>Script: Skill directories
        Script->>FS: Copy to skills/{plugin}-{skill}/
    end
    
    Script->>Script: Determine version bump needed
    Script->>Manifest: Generate/update manifest
    Manifest-->>Script: Bumped version
    
    Script->>Context: Generate context file
    Context-->>Script: GEMINI.md created
    
    Script-->>User: Conversion complete with summary
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
No Real People Names In Style References ❓ Inconclusive Investigation of PR for references to real people's names in plugin commands, skills, style references, and example prompts requires examining the actual codebase and PR changes. Please provide the actual PR diff, file contents, or access to the codebase so specific references can be identified and evaluated against naming policies.
✅ Passed checks (7 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title accurately and concisely summarizes the main objective: auto-generating a Gemini CLI extension from Claude plugins, which aligns with the core functionality added in scripts/convert_to_gemini.py and related configuration changes.
Docstring Coverage ✅ Passed Docstring coverage is 95.24% which is sufficient. The required threshold is 80.00%.
No Assumed Git Remote Names ✅ Passed The newly added code does not contain hardcoded git remote name assumptions; the script performs file operations and README examples show user-provided parameters, not hardcoded git operations.
Git Push Safety Rules ✅ Passed Comprehensive repository scan found no git push operations, force push commands, or automated pushes to protected branches in any modified files.
No Untrusted Mcp Servers ✅ Passed The pull request does not introduce any MCP server installations from untrusted or any sources. The new script uses only Python standard library modules with no subprocess or package installation calls.
Ai-Helpers Overlap Detection ✅ Passed This PR adds infrastructure code (conversion script) and documentation changes, not ai-helpers content files. Overlap check not applicable.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can use your project's `ruff` configuration to improve the quality of Python code reviews.

Add a Ruff configuration file to your project to customize how CodeRabbit runs ruff.

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

Note

Due to the large number of review comments, Critical severity comments were prioritized as inline comments.

🟠 Major comments (41)
commands/git/fix-cherrypick-robot-pr.toml-57-74 (1)

57-74: ⚠️ Potential issue | 🟠 Major

Git remote discovery logic is flawed.

git config user.name returns the human-readable display name (e.g., "John Doe"), not the GitHub username. GitHub remote URLs use usernames (e.g., github.com/johndoe/repo), so the grep patterns on lines 60 and 63 will almost never match actual remote URLs.

This means the "auto-discovery" will silently fail and always fall back to the hardcoded defaults (origin/upstream), making the discovery logic misleading.

Consider using gh api user --jq .login to get the actual GitHub username, or parsing the remote URL directly.

🔧 Proposed fix for remote discovery
 # Discover the upstream remote (the main repository)
-# Look for a remote that's not owned by the current user
-UPSTREAM_REMOTE=$(git remote -v | grep "fetch" | grep -v "$(git config user.name)" | awk '{print $1}' | head -1)
+# Look for a remote that's not owned by the current GitHub user
+GH_USER=$(gh api user --jq .login 2>/dev/null || echo "")
+if [ -n "$GH_USER" ]; then
+  UPSTREAM_REMOTE=$(git remote -v | grep "fetch" | grep -v "$GH_USER" | awk '{print $1}' | head -1)
+  FORK_REMOTE=$(git remote -v | grep "$GH_USER.*push" | awk '{print $1}' | head -1)
+else
+  # Fallback if gh CLI not authenticated
+  UPSTREAM_REMOTE=""
+  FORK_REMOTE=""
+fi

-# Discover the fork remote (your fork)
-FORK_REMOTE=$(git remote -v | grep "$(git config user.name).*push" | awk '{print $1}' | head -1)

 # If not found, fall back to common names
 UPSTREAM_REMOTE=${UPSTREAM_REMOTE:-upstream}
 FORK_REMOTE=${FORK_REMOTE:-origin}

Note: The same issue exists at line 128 where the pattern is repeated.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/git/fix-cherrypick-robot-pr.toml` around lines 57 - 74, The remote
discovery uses `git config user.name` (human display name) to grep remotes,
which won't match GitHub usernames; update the logic that sets `UPSTREAM_REMOTE`
and `FORK_REMOTE` to derive the GitHub username from `gh api user --jq .login`
or parse each remote URL (via `git remote get-url <name>`) to extract the owner
segment and match against that owner, then select the non-fork remote as
UPSTREAM_REMOTE and the matching-owner remote as FORK_REMOTE; apply the same fix
to the repeated pattern where `UPSTREAM_REMOTE`/`FORK_REMOTE` are determined
later in the file.
commands/git/redescribe.toml-88-96 (1)

88-96: ⚠️ Potential issue | 🟠 Major

Use --body-file or stdin to pass multiline Markdown instead of inline --body.

The inline --body approach is fragile: quotes, backticks, dollar signs, and newlines in the generated description will corrupt the payload. GitHub CLI's gh pr edit supports the -F, --body-file option to safely handle multiline content:

Safe approaches:
# From a file
gh pr edit <pr-url> --body-file pr-body.md
# From stdin
gh pr edit <pr-url> --body-file - <<'EOF'
<new-description>
EOF
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/git/redescribe.toml` around lines 88 - 96, Replace the fragile
inline gh command that uses `gh pr edit <pr-url> --body "<new-description>"`
with a safe `--body-file` approach: write the generated multiline Markdown into
a temporary file (or pipe it to stdin) and call `gh pr edit <pr-url> --body-file
<file-or->` instead of `--body`, ensuring you use the same `gh pr edit`
invocation and remove the inline `--body` usage to avoid quoting/newline issues.
commands/node-tuning/generate-tuned-profile.toml-76-76 (1)

76-76: ⚠️ Potential issue | 🟠 Major

Fix the invalid oc apply dry-run flag.

Line 76 uses oc apply --server-dry-run=client, which is not a valid flag combination. The correct syntax uses --dry-run=client or --dry-run=server instead.

Suggested fix
-   - Optionally run `oc apply --server-dry-run=client -f .work/node-tuning/$PROFILE_NAME/tuned.yaml` to confirm schema compatibility.
+   - Optionally run `oc apply --dry-run=client -f .work/node-tuning/$PROFILE_NAME/tuned.yaml` to confirm local validation.
+   - If you want API-server validation, use `oc apply --dry-run=server -f .work/node-tuning/$PROFILE_NAME/tuned.yaml`.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/node-tuning/generate-tuned-profile.toml` at line 76, The
README/command text uses an invalid oc flag combination: replace the incorrect
string "oc apply --server-dry-run=client -f
.work/node-tuning/$PROFILE_NAME/tuned.yaml" with the correct dry-run form, e.g.
"oc apply --dry-run=client -f .work/node-tuning/$PROFILE_NAME/tuned.yaml" (or
use "--dry-run=server" if server-side dry-run is intended) so the instruction in
generate-tuned-profile.toml is valid.
commands/node/cluster-node-health-check.toml-60-63 (1)

60-63: ⚠️ Potential issue | 🟠 Major

--output-format json is documented but not implemented.

OUTPUT_FORMAT is initialized, but every execution path still prints text and exits; the JSON block here is only an example. As written, /node:cluster-node-health-check --output-format json cannot produce the machine-readable output the manifest promises.

Also applies to: 482-535

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/node/cluster-node-health-check.toml` around lines 60 - 63, The
manifest documents an --output-format flag but the code never emits JSON: update
the command handling that reads OUTPUT_FORMAT (the --output-format flag) to
branch on its value and produce machine-readable JSON when OUTPUT_FORMAT ==
"json" instead of always printing text; locate the main execution/print logic
that formats the health results (the block that currently prints human-readable
status lines) and add a JSON serialization path that builds a structured object
(statuses, node info, timestamps, exit code) and writes it to stdout, ensuring
the text output remains the default when OUTPUT_FORMAT is absent or set to
"text".
commands/hcp/cluster-health-check.toml-7-11 (1)

7-11: ⚠️ Potential issue | 🟠 Major

Add the optional namespace positional to the synopsis.

The implementation and examples accept a second positional namespace argument, but the synopsis omits it. That makes the documented two-positional form look invalid.

Also applies to: 49-53

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/hcp/cluster-health-check.toml` around lines 7 - 11, The Synopsis
block currently lists only one positional (<cluster-name>) but the
implementation and examples accept an optional second positional namespace;
update the synopsis string `/hcp:cluster-health-check <cluster-name> [--verbose]
[--output-format json|text]` to include the optional namespace (e.g.
`/hcp:cluster-health-check <cluster-name> [<namespace>] [--verbose]
[--output-format json|text]`) and make the same change to the other Synopsis
occurrence referenced in the file so the documented form matches the implemented
command signature.
commands/hcp/cluster-health-check.toml-58-60 (1)

58-60: ⚠️ Potential issue | 🟠 Major

--output-format json currently has no execution path.

The prompt advertises a JSON mode, but the implementation never branches on that flag and only shows a sample payload. Consumers expecting machine-readable output will still get text.

Also applies to: 472-533

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/hcp/cluster-health-check.toml` around lines 58 - 60, The CLI
advertises a --output-format flag but no code path uses it; update the main
command handler (the function that processes the cluster-health-check command,
e.g., the handler/execute function for this subcommand) to read the
--output-format value and branch: if value === "json" then serialize the
health-check result object to JSON and write it to stdout (instead of the
human-readable renderer), otherwise use the existing text renderer; ensure error
conditions still return appropriate exit codes and that the JSON output contains
the same structured fields shown in the sample payload; add/update
unit/integration tests for both "text" and "json" modes to validate output.
commands/lvms/analyze.toml-159-172 (1)

159-172: ⚠️ Potential issue | 🟠 Major

The fallback must-gather reader drops old-namespace support.

Earlier sections promise compatibility with both openshift-lvm-storage and openshift-storage, but the built-in file-reading path hardcodes only openshift-lvm-storage. If the Python helper is missing, older must-gathers will fail despite the documented backward-compatibility claim.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/lvms/analyze.toml` around lines 159 - 172, The fallback built-in
file-reading commands hardcode the namespace "openshift-lvm-storage", dropping
support for older "openshift-storage" must-gathers; update the commands that
read lvmclusters.yaml, lvmvolumegroups.yaml and the pods.yaml/events.yaml lines
so they try both namespaces (e.g., use find with -name "lvmclusters.yaml" and
-name "lvmvolumegroups.yaml" as before but search both namespace paths, or
change the cat lines to cat
{must-gather-path}/namespaces/{openshift-lvm-storage,openshift-storage}/pods.yaml
and cat
{must-gather-path}/namespaces/{openshift-lvm-storage,openshift-storage}/events.yaml),
ensuring the fallback supports both "openshift-lvm-storage" and
"openshift-storage" so older must-gathers are handled as documented.
commands/gwapi/install.toml-83-123 (1)

83-123: ⚠️ Potential issue | 🟠 Major

The polling snippet never fails on timeout.

Both loops stop when ELAPSED == TIMEOUT, but there is no post-loop check before continuing. A permanently unready GatewayClass/Gateway can therefore fall through into the final summary as if installation completed.

Suggested fix
   TIMEOUT=300
   INTERVAL=5
   ELAPSED=0
+  GATEWAYCLASS_READY=false
+  GATEWAY_READY=false

   # Wait for GatewayClass
   while [ $ELAPSED -lt $TIMEOUT ]; do
     ACCEPTED=$(oc get gatewayclass <name> -o jsonpath='{.status.conditions[?(@.type=="Accepted")].status}' 2>/dev/null)
     if [ "$ACCEPTED" = "True" ]; then
       echo "✓ GatewayClass is accepted"
+      GATEWAYCLASS_READY=true
       break
     fi
     echo "Waiting for GatewayClass to be accepted... ($(($ELAPSED))s / ${TIMEOUT}s)"
     sleep $INTERVAL
     ELAPSED=$(($ELAPSED + $INTERVAL))
   done
+
+  if [ "$GATEWAYCLASS_READY" != "true" ]; then
+    echo "Timeout waiting for GatewayClass to be accepted. Current status:"
+    oc get gatewayclass <name> -o yaml
+    exit 1
+  fi

   # Wait for Gateway
   ELAPSED=0
   while [ $ELAPSED -lt $TIMEOUT ]; do
     PROGRAMMED=$(oc get gateway <name> -n <namespace> -o jsonpath='{.status.conditions[?(@.type=="Programmed")].status}' 2>/dev/null)
     ACCEPTED=$(oc get gateway <name> -n <namespace> -o jsonpath='{.status.conditions[?(@.type=="Accepted")].status}' 2>/dev/null)
     if [ "$PROGRAMMED" = "True" ] && [ "$ACCEPTED" = "True" ]; then
       echo "✓ Gateway is ready"
+      GATEWAY_READY=true
       break
     fi
     echo "Waiting for Gateway to be ready... ($(($ELAPSED))s / ${TIMEOUT}s)"
     sleep $INTERVAL
     ELAPSED=$(($ELAPSED + $INTERVAL))
   done
+
+  if [ "$GATEWAY_READY" != "true" ]; then
+    echo "Timeout waiting for Gateway to be ready. Current status:"
+    oc get gateway <name> -n <namespace> -o yaml
+    exit 1
+  fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/gwapi/install.toml` around lines 83 - 123, The polling loops using
TIMEOUT/INTERVAL/ELAPSED for GatewayClass and Gateway do not check if they
exited due to timeout; after each while loop (for GatewayClass checks and for
Gateway checks) add an explicit check of whether the condition was satisfied
(e.g., test that ACCEPTED/PROGRAMMED variables are True), and if not then print
"Timeout waiting for resources to be ready. Current status:", dump full resource
status with oc get gatewayclass <name> -o yaml and oc get gateway <name> -n
<namespace> -o yaml, and exit with a non-zero status; ensure you reference the
same variables (ELAPSED, TIMEOUT, ACCEPTED, PROGRAMMED) and commands (oc get
gatewayclass, oc get gateway) so the timeout branch runs when the loop ends
without success.
commands/node/cluster-node-health-check.toml-33-50 (1)

33-50: ⚠️ Potential issue | 🟠 Major

Add jq as a documented prerequisite.

The implementation extensively uses jq for JSON processing (extracting node conditions, pod statuses, resource capacities, labels, and more), but the Prerequisites section (lines 33-50) only mentions oc/kubectl. The command will fail immediately when attempting the first jq pipeline if jq is not installed. Add jq to the prerequisites with installation instructions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/node/cluster-node-health-check.toml` around lines 33 - 50, Add jq to
the prerequisites for the cluster-node-health-check command: update the
Prerequisites section to list jq as a required tool, include installation links
for common platforms (e.g., package managers or official site) and a
verification command such as `jq --version`, and mention that the script relies
on jq for JSON processing of node conditions, pods, capacities and labels so the
command will fail without it.
commands/git/backport.toml-57-63 (1)

57-63: ⚠️ Potential issue | 🟠 Major

Clarify the sequence for conflict resolution and branch transitions.

The workflow tells the user to run git cherry-pick --continue or git cherry-pick --abort, then asks about continuing to the next branch. However, it doesn't explicitly state that the user must complete one of those commands (resolving the cherry-pick state) before the system can proceed to checkout the next branch. Without this clarity, an implementer might incorrectly attempt to switch branches while the cherry-pick is still in progress, causing the workflow to fail.

Revise lines 61-62 to make the sequence explicit: the user must first complete the conflict resolution command, and only after that is resolved will the next branch be checked out.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/git/backport.toml` around lines 57 - 63, Make the
conflict-resolution wording explicit: update the block that mentions `git
cherry-pick --continue` / `git cherry-pick --abort` so it states that the user
must finish the cherry-pick state (by running `git cherry-pick --continue` after
resolving conflicts or `git cherry-pick --abort`) before the tool or user can
switch branches; only after the cherry-pick is completed should the workflow
attempt to checkout the next branch or prompt “continue to the next branch.”
Reference the existing phrases `git status`, `git diff`, `git cherry-pick
--continue`, `git cherry-pick --abort`, and “checkout the next branch” when
updating the text to enforce this sequence.
commands/gwapi/install.toml-39-42 (1)

39-42: ⚠️ Potential issue | 🟠 Major

This manifest overstates Kubernetes support—it's functionally OpenShift-only.

The introduction claims Kubernetes/OpenShift compatibility and "uses oc (preferred) or kubectl", but multiple critical steps hardcode oc:

  • Line 40: Domain retrieval uses oc get ingresses.config/cluster (OpenShift-specific API; Kubernetes has no equivalent)
  • Line 61: Domain substitution hardcodes oc apply without conditional selection
  • Lines 91–92, 104–105, 122: Readiness checks and diagnostics hardcode oc throughout

The fallback at lines 41–42 (ask user for manual domain entry) is incomplete: even if a user supplies the domain, the workflow fails on pure Kubernetes at every subsequent step. Either remove Kubernetes from the supported platforms or implement conditional CLI detection and use throughout.

Also applies to: 61, 91–92, 104–105, 122, 194

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/gwapi/install.toml` around lines 39 - 42, The manifest currently
hardcodes OpenShift 'oc' usage (e.g., DOMAIN=$(oc get ingresses.config/cluster
-o jsonpath={.spec.domain}), all oc apply/oc get readiness checks and
diagnostics), so either remove Kubernetes from supported platforms or implement
conditional CLI/cluster detection: detect whether 'oc' is available and cluster
is OpenShift, else fall back to 'kubectl' and use Kubernetes-appropriate ways to
determine the external domain (e.g., examine Ingress/IngressClass, Service
LoadBalancer e.g., EXTERNAL-IP, or prompt with clear instructions), and apply
that conditional logic consistently for the DOMAIN retrieval, the resource
application steps (currently using oc apply), readiness checks/diagnostics
(currently using oc get/oc logs), and every other oc occurrence noted (lines
referenced in the review). Update messages and flow so a user-provided DOMAIN
will work on both paths and ensure all commands reference the chosen CLI
variable instead of hardcoded 'oc'.
commands/ci/query-job-status.toml-7-10 (1)

7-10: ⚠️ Potential issue | 🟠 Major

Keep the ci: namespace in every documented invocation.

This file declares ci:query-job-status on Line 5, but the synopsis and all examples document /query-job-status without the namespace. Users following this prompt will call a nonexistent command.

🛠️ Suggested change
-/query-job-status <execution-id>
+/ci:query-job-status <execution-id>
...
-The `query-job-status` command queries the status of a gangway job execution via the REST API using the execution ID returned when a job is triggered.
+The `ci:query-job-status` command queries the status of a gangway job execution via the REST API using the execution ID returned when a job is triggered.
...
-   /query-job-status ca249d50-dee8-4424-a0a7-6dd9d5605267
+   /ci:query-job-status ca249d50-dee8-4424-a0a7-6dd9d5605267
...
-   /query-job-status 8f3a9b2c-1234-5678-9abc-def012345678
+   /ci:query-job-status 8f3a9b2c-1234-5678-9abc-def012345678
...
-   /query-job-status 5a6b7c8d-9e0f-1a2b-3c4d-5e6f7a8b9c0d
+   /ci:query-job-status 5a6b7c8d-9e0f-1a2b-3c4d-5e6f7a8b9c0d

Also applies to: 14-19, 63-66, 78-81, 84-87

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/ci/query-job-status.toml` around lines 7 - 10, The synopsis and
examples omit the required namespace; update every user-facing invocation to
include the declared command name ci:query-job-status (e.g., change occurrences
of `/query-job-status` to `/ci:query-job-status`) for the synopsis and all
example blocks noted (lines around 14-19, 63-66, 78-81, 84-87) so documented
commands match the actual declared symbol ci:query-job-status.
commands/jira/solve.toml-27-27 (1)

27-27: ⚠️ Potential issue | 🟠 Major

Fix JIRA issue URL parameter expansion.

Lines 27 and 36 use {$1} in the REST API URL, which leaves literal braces in the path. This produces /issue/{OCPBUGS-12345} instead of /issue/OCPBUGS-12345, breaking the API request. Use ${1} for correct shell parameter expansion.

Changes required
- The command uses curl to fetch JIRA data via REST API: https://issues.redhat.com/rest/api/2/issue/{$1}
+ The command uses curl to fetch JIRA data via REST API: https://issues.redhat.com/rest/api/2/issue/${1}
   - Use curl to fetch JIRA issue data: curl -s "https://issues.redhat.com/rest/api/2/issue/{$1}"
+  - Use curl to fetch JIRA issue data: curl -s "https://issues.redhat.com/rest/api/2/issue/${1}"

Also applies to: 36-36

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/jira/solve.toml` at line 27, The JIRA REST API URL in the curl
invocations currently uses the literal brace form
"https://issues.redhat.com/rest/api/2/issue/{$1}" which leaves braces in the
path; update both occurrences of that URL (the curl command strings referencing
{$1}) to use shell parameter expansion "${1}" instead of "{$1}" so the request
becomes "/issue/OCPBUGS-12345" at runtime.
commands/ci/query-job-status.toml-52-59 (1)

52-59: ⚠️ Potential issue | 🟠 Major

Remove Claude-specific instructions and Skill tool references from this file.

Lines 52-59 and 82-88 contain instructions explicitly labeled "Important for Claude" that reference the "Skill tool" (a Claude-specific concept) and describe Claude-specific behaviors in the examples. These conflict with the Gemini conversion goal and will mislead Gemini users. Replace with tool-agnostic instructions that describe what the command does (parse JSON, display status, show artifact paths) without mentioning Claude or the Skill tool.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/ci/query-job-status.toml` around lines 52 - 59, Remove the
"Important for Claude" block and any references to the "Skill tool" and
Claude-specific instructions; instead replace those paragraphs (the ones that
mention using the Skill tool and Claude) with a tool-agnostic description that
(1) tells the command to ensure authentication is available before running
curl_with_token.sh, (2) instructs the runner to locate and verify
curl_with_token.sh is present in the repo before executing it, and (3) specifies
the expected behavior: parse the command's JSON response, present it in a
readable format, prominently display the job status, note that PENDING/RUNNING
means the job is still in progress and SUCCESS/FAILURE indicates completion, and
if a gcs_path is present include the artifact path.
commands/jira/issues-by-component.toml-45-49 (1)

45-49: ⚠️ Potential issue | 🟠 Major

This prompt still targets the Claude plugin runtime instead of the generated Gemini extension.

Lines 45-49 describe Claude-specific limits, and Lines 194-198 hardcode plugins/jira/skills/jira-issues-by-component/jira_curl.sh. In this PR the generated extension ships commands and skills in the new root layout, so these instructions now point at the wrong runtime and a nonexistent wrapper path. Please fix the converter too, or regeneration will reintroduce this.

Also applies to: 193-198

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/jira/issues-by-component.toml` around lines 45 - 49, Update the
prompt and converter so it targets the generated Gemini extension and the new
root layout instead of the Claude plugin runtime: replace any Claude-specific
language (e.g., references to Claude limits in
commands/jira/issues-by-component.toml) and change hardcoded wrapper paths like
"plugins/jira/skills/jira-issues-by-component/jira_curl.sh" to the new
extension/skill command locations produced by the generator (the root-level
commands/skills layout used by the generated Gemini extension); update the
converter logic that emits these strings so future regeneration produces the
correct runtime-targeted prompt and the correct root-level command paths.
commands/jira/clone-from-github.toml-91-123 (1)

91-123: ⚠️ Potential issue | 🟠 Major

Profile selection is described with three different identifiers.

These sections talk about profile “name” values like my-profile and default, but the documented profiles.yaml only exposes description, and Line 287 then tells users to pass "OLM Project". The setup and usage docs need one canonical profile identifier or users will call the command with values that cannot be resolved.

Also applies to: 272-287

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/jira/clone-from-github.toml` around lines 91 - 123, The docs show
inconsistent profile identifiers (flags `--profile` vs `--profile-name`,
examples using `my-profile`/`default`, and elsewhere referencing human labels
like "OLM Project") which will confuse users because `profiles.yaml` exposes
only keys like `description`; normalize to a single canonical identifier: pick
one flag name (e.g., `--profile-name`) and update all references (examples, flag
mapping, and the section describing profiles) to state that the CLI expects the
profile key from profiles.yaml (not the description/human label), and change the
example that uses `"OLM Project"` to use the actual profile key that appears in
profiles.yaml so the documented usage and the profiles.yaml schema match.
commands/ci/trigger-periodic.toml-5-10 (1)

5-10: ⚠️ Potential issue | 🟠 Major

Use the installed /ci: command names in the syntax and examples.

Line 5 defines ci:trigger-periodic, but the synopsis, follow-up suggestion, and examples all publish /trigger-periodic and /query-job-status. In the generated extension those commands are namespaced, so the current docs tell users to invoke the wrong command names.

Also applies to: 89-89, 104-122

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/ci/trigger-periodic.toml` around lines 5 - 10, The docs use the
un-namespaced commands (/trigger-periodic, /query-job-status) but the installed
extension exposes namespaced commands (ci:trigger-periodic); update the
synopsis, examples and any follow-up mentions to use the installed command names
(e.g. /ci:trigger-periodic and /ci:query-job-status) so users invoke the correct
names; search for occurrences of "/trigger-periodic" and "/query-job-status"
(including the blocks around ci:trigger-periodic and the sections at lines ~89
and ~104-122) and replace them with the namespaced equivalents while keeping the
same argument and ENV_VAR examples.
commands/jira/issues-by-component.toml-124-151 (1)

124-151: ⚠️ Potential issue | 🟠 Major

Map friendly time windows to valid JQL before composing the query.

Lines 125-128 accept values like last-week and YYYY-MM-DD:YYYY-MM-DD, but Lines 148-151 interpolate that token directly as created >= -{time-period}. That yields invalid JQL for the named presets and for custom ranges. This needs an explicit translation step first, e.g. last-week-7d, and custom ranges → bounded >= / <= clauses.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/jira/issues-by-component.toml` around lines 124 - 151, The
time-period token is being interpolated directly into the JQL ("created >=
-{time-period}"), which produces invalid JQL for named presets and custom
ranges; add a translation step that maps the incoming time-period values (e.g.,
"last-week", "last-2-weeks", "last-month") to JQL relative durations ("-7d",
"-14d", "-30d") and converts custom ranges "YYYY-MM-DD:YYYY-MM-DD" into explicit
bounded clauses ("created >= YYYY-MM-DD AND created <= YYYY-MM-DD") before
composing the query, then use the resulting JQL fragment instead of the raw
token when building the base query.
commands/must-gather/windows.toml-62-66 (1)

62-66: ⚠️ Potential issue | 🟠 Major

This execution step still points at the old plugin-local analyzer path.

It invokes plugins/must-gather/skills/must-gather-analyzer/scripts/analyze_windows_logs.py, which will not exist inside the generated Gemini extension. As written, the first real action for the command is a broken path.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/must-gather/windows.toml` around lines 62 - 66, Update the execution
step in commands/must-gather/windows.toml so it no longer references the removed
plugin-local path
"plugins/must-gather/skills/must-gather-analyzer/scripts/analyze_windows_logs.py";
replace it with the analyzer entry point that will exist inside the generated
Gemini extension (e.g., the extension-relative script or CLI installed with the
extension) so the command calls the correct analyze_windows_logs entry in the
extension package rather than the old plugin path.
commands/ci/trigger-periodic.toml-26-42 (1)

26-42: ⚠️ Potential issue | 🟠 Major

The security section still addresses Claude instead of Gemini.

These sections use “Claude MUST” / “Important for Claude” language even though this file is part of the generated Gemini extension. That leaves the runtime guidance ambiguous and misses the conversion goal for this PR. Please fix the generator so the platform-specific wording is rewritten everywhere.

Also applies to: 95-100

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/ci/trigger-periodic.toml` around lines 26 - 42, Update the
platform-specific wording in the security/confirmation section so all
occurrences of the assistant name refer to Gemini instead of Claude: search for
phrases like "Claude MUST", "Important for Claude", and any lines in the
"MANDATORY USER CONFIRMATION" block (and the similar block around lines 95-100)
and replace them with "Gemini MUST" / "Important for Gemini" (or equivalent
generator variables if this is templated) so the generated Gemini extension uses
the correct assistant name consistently; ensure the change is applied to every
instance in the file and in the generator template so no residual "Claude"
references remain.
commands/hcp/generate.toml-349-354 (1)

349-354: ⚠️ Potential issue | 🟠 Major

The skills reference still points at the source plugin tree.

These instructions tell users to inspect plugins/hypershift/skills/..., but those paths do not exist in the generated Gemini extension. The copied skills need to be referenced via the new extension layout, or these lookup steps will fail immediately.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/hcp/generate.toml` around lines 349 - 354, The docs incorrectly
point to the original plugin tree (plugins/hypershift/skills/...); update the
instructions in generate.toml so they reference the actual generated Gemini
extension layout where the skill files were copied (e.g., the extension's skills
directory and the SKILL.md files such as hcp-create-aws/SKILL.md and
hcp-create-kubevirt/SKILL.md). Replace occurrences of
"plugins/hypershift/skills/..." with the correct extension-relative path used by
the build output (the extension's skills folder) so the example commands
(ls/cat) succeed against the generated package.
commands/jira/setup-gh2jira.toml-199-212 (1)

199-212: ⚠️ Potential issue | 🟠 Major

Red Hat Jira users are routed through the wrong auth flow here.

This block classifies issues.redhat.com as Atlassian Cloud, then immediately describes Red Hat Jira as a separate case. That contradicts the other Jira manifests in this PR, which treat Red Hat Jira as its own PAT-based flow, and it will send Red Hat users to the wrong token creation instructions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/jira/setup-gh2jira.toml` around lines 199 - 212, The block
incorrectly treats issues.redhat.com as Atlassian Cloud; update the "For
Atlassian Cloud" and "For Red Hat Jira" sections so that issues.redhat.com is
routed to the Red Hat PAT-based flow instead of the Atlassian token flow: change
the classification logic/text so "issues.redhat.com" is explicitly handled by
the Red Hat Jira instructions and move any Red Hat-specific notes (SSO/Kerberos,
org docs) into the "For Red Hat Jira" section while keeping the Atlassian Cloud
steps for *.atlassian.net only and ensuring the token creation steps reflect the
PAT-based flow for Red Hat Jira.
commands/golang/lint-fix.toml-22-29 (1)

22-29: ⚠️ Potential issue | 🟠 Major

Preserve the user’s lint scope when falling back from hack/go-lint.sh.

Lines 22-25 say extra flags are passed through, but Lines 26-29 replace that with a plain golangci-lint run --fix when the wrapper is used. That fallback drops any package/file scoping the user requested and can end up rewriting a much larger surface than intended.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/golang/lint-fix.toml` around lines 22 - 29, The fallback that runs a
plain "golangci-lint run --fix" when "hack/go-lint.sh" is detected drops
user-provided package/file scope and flags; update the fallback logic so that
the exact extra flags (including package/file targets and any --config=...)
captured by the "Go Lint" skill are preserved and appended to the fallback
command (i.e., build the command as "golangci-lint run --fix <captured-flags>"),
ensuring the wrapper detection for hack/go-lint.sh still chooses direct
golangci-lint but retains all original flags and scope.
commands/must-gather/ovn-dbs.toml-47-55 (1)

47-55: ⚠️ Potential issue | 🟠 Major

The analyzer lookup still assumes the source plugin directory structure.

These steps tell the agent to find analyze_ovn_dbs.py under plugins/must-gather/... or ~/.cursor/commands/ai-helpers/plugins/must-gather. This PR generates a standalone Gemini extension with copied skills in the new extension layout, so that search path will not resolve at runtime.

Also applies to: 60-71

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/must-gather/ovn-dbs.toml` around lines 47 - 55, The analyzer lookup
in ovn-dbs.toml currently assumes the old plugin directory layout and hardcodes
the path to analyze_ovn_dbs.py; update the resolution so it does not rely on
"plugins/must-gather/..." layout—either (a) make the TOML reference a logical
resource name and change the runtime to locate the script by scanning the
plugin/extension installation root for "analyze_ovn_dbs.py" (recursively) or (b)
register the script as a package resource/entry point and load it via
importlib.resources or pkg_resources; modify the code that reads ovn-dbs.toml to
try both the legacy path and the new extension layout discovery (search for the
file name analyze_ovn_dbs.py) so the analyzer works for standalone Gemini
extensions as well.
commands/git/branch-cleanup.toml-137-146 (1)

137-146: ⚠️ Potential issue | 🟠 Major

Protected branches are still eligible for deletion in the example logic.

This loop only excludes $main_branch, so develop, release/*, and hotfix/* can still be surfaced as delete candidates even though the safety section says they must never be removed.

Also applies to: 271-276

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/git/branch-cleanup.toml` around lines 137 - 146, The loop that lists
merged branches only excludes $main_branch so protected branches like "develop",
"release/*", and "hotfix/*" still get output; update the branch-filtering logic
(in the loop that iterates over git branch, referencing variables main_branch,
check_if_merged, merge_status and method) to skip any branch that matches
protected names/patterns — e.g., add a check (or an is_protected_branch function
and a protected_branches list) that returns true for "develop" and for patterns
"release/*" and "hotfix/*" and continue to next branch when protected so they
are never printed as delete candidates.
commands/jira/grooming.toml-123-132 (1)

123-132: 🛠️ Refactor suggestion | 🟠 Major

Close the fenced block before ## Output Format.

The example that starts at Line 123 never closes its ```bash fence, so everything after it renders as code instead of structured help.

Proposed fix
 12. **Combine Label and status filters**:
     ```bash
     /jira:grooming OCPBUGS last-week --label "performance" --status "NEW"
+    ```
 
 
 ## Output Format
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/jira/grooming.toml` around lines 123 - 132, The fenced code block
that begins with ```bash at the /jira:grooming example is not closed, causing
subsequent content (including "## Output Format") to render as code; locate the
example containing the "/jira:grooming OCPBUGS last-week --label \"performance\"
--status \"NEW\"" line (under the "Combine Label and status filters" section)
and add the closing ``` fence immediately after that command so the code block
is properly terminated and the following "## Output Format" renders as normal
text.
commands/ci/ask-sippy.toml-4-10 (1)

4-10: ⚠️ Potential issue | 🟠 Major

This converted descriptor still advertises the Claude-era command and agent names.

The file maps to ci:ask-sippy, but the synopsis/examples still use /ask-sippy, and the operational notes still talk about Claude. That leaves the generated Gemini command inconsistent with both its path and the PR’s conversion goal.

Also applies to: 29-40, 70-76, 80-100

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/ci/ask-sippy.toml` around lines 4 - 10, The descriptor for the
command ci:ask-sippy is inconsistent: update all occurrences of the old
Claude-era command and agent names (e.g., the `/ask-sippy` examples and any
mentions of "Claude") to match the converted Gemini-style command and agent
naming; search for the symbols `ci:ask-sippy`, `/ask-sippy`, and the string
`Claude` in this file and replace the synopsis, examples, and operational notes
(including the sections noted around lines 29-40, 70-76, 80-100) so the command
name, usage examples, and agent references consistently reflect the new Gemini
conversion.
commands/ci/check-if-jira-regression-is-ongoing.toml-134-139 (1)

134-139: ⚠️ Potential issue | 🟠 Major

Recent-run analysis still assumes test_id exists.

The workflow explicitly supports bugs that only expose a test name or regression ID, but this step always calls fetch-test-runs "$test_id". For those valid inputs, the command dead-ends here instead of degrading gracefully.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/ci/check-if-jira-regression-is-ongoing.toml` around lines 134 - 139,
The step unconditionally calls fetch-test-runs
(script_path="plugins/ci/skills/fetch-test-runs/fetch_test_runs.py") using the
variable test_id even when only a test name or regression ID is provided; update
the logic to first verify test_id is set and non-empty before invoking python3
"$script_path" "$test_id" --include-success --format json, and if test_id is
absent, branch to a graceful fallback (e.g., call the fetch-test-runs script
with an alternative identifier such as test_name or regression_id, or skip this
check and mark the result as "not-applicable") so the workflow does not dead-end
when only test_name or regression ID inputs exist.
commands/ci/check-if-jira-regression-is-ongoing.toml-49-55 (1)

49-55: ⚠️ Potential issue | 🟠 Major

Use Jira version metadata before falling back to the latest release.

This prompt never extracts any release field from the Jira payload, so bugs whose summary/description omit 4.xx will be checked against whatever fetch-releases --latest returns. That can send the analysis to the wrong stream for older still-supported branches.

Also applies to: 72-78

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/ci/check-if-jira-regression-is-ongoing.toml` around lines 49 - 55,
The prompt parser currently extracts summary, comments, status, components, and
progress.level but never reads Jira release/version metadata, so it falls back
to running fetch-releases --latest; update the JSON extraction to prefer Jira's
release/version fields (e.g., fields.fixVersions, fields.versions, or a
"release" field in the payload) and use that value as the target branch/version
before calling fetch-releases --latest; apply the same change to the other
parsing block that mirrors this logic (the block referenced in the review as
also applying to lines 72-78).
commands/gwapi/delete.toml-19-20 (1)

19-20: ⚠️ Potential issue | 🟠 Major

Namespace-scoped cleanup should not implicitly delete the shared GatewayClass.

Passing /gwapi:delete gateway-system reads like a namespace-local operation, but this prompt still removes the cluster-scoped GatewayClass. If other namespaces use that class, a scoped cleanup becomes a cluster-wide outage.

Also applies to: 77-82, 124-128

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/gwapi/delete.toml` around lines 19 - 20, The docs currently state
that passing `$1` (optional) for a namespace will delete namespace-scoped
Gateway resources and the cluster-scoped `GatewayClass`, which is unsafe; update
the description to clarify that providing a namespace (e.g., `gateway-system`)
only removes resources in that namespace (from `openshift-ingress` YAMLs if
relevant) and does NOT delete the cluster-scoped `GatewayClass` unless an
explicit cluster-scoped flag or no-namespace invocation is used; change the
wording for the `$1` argument and the other affected blocks (the sections
referenced around lines 77-82 and 124-128) to reflect this behavior and, if
implementation currently deletes the `GatewayClass` when a namespace is given,
modify the delete logic so deletion of `GatewayClass` occurs only for
cluster-level invocations (e.g., explicit `--cluster` or when no namespace is
provided).
commands/ci/ask-sippy.toml-47-59 (1)

47-59: ⚠️ Potential issue | 🟠 Major

Fix the quoted heredoc to enable variable expansion.

The <<'EOF' syntax prevents shell expansion, sending the literal string $1 to the Sippy API instead of the user's actual question. Change to <<EOF (without quotes around the delimiter) to allow variable substitution.

Current problematic code
curl_with_token.sh https://api.cr.j7t7.p1.openshiftapps.com:6443 -s -X POST "https://sippy-auth.dptools.openshift.org/api/chat" \
  -H "Content-Type: application/json" \
  -d `@-` <<'EOF'
{
  "message": "$1",
  "chat_history": [],
  "show_thinking": false,
  "persona": "default"
}
EOF
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/ci/ask-sippy.toml` around lines 47 - 59, The heredoc passed to
curl_with_token.sh is quoted (<<'EOF') which prevents shell variable expansion
so the payload sends the literal "$1" instead of the caller's argument; change
the heredoc delimiter to an unquoted form (<<EOF) so the shell expands $1 inside
the JSON payload for the POST in the curl_with_token.sh invocation.
commands/git/suggest-reviewers.toml-57-88 (1)

57-88: ⚠️ Potential issue | 🟠 Major

New untracked files are excluded from all reviewer analysis paths.

On line 58, git status --short | grep -v '^??' discards untracked files. In Cases 1–3 (lines 61–88), git diff and git diff --cached are then used to collect changed files, but neither command includes untracked files. Since new files have no git blame history, OWNERS-based suggestions would be the only signal—yet untracked files are never collected, so no reviewer suggestions are made for them.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/git/suggest-reviewers.toml` around lines 57 - 88, The script
currently filters out untracked files with the pipeline using has_uncommitted
(git status --short | grep -v '^??') and then collects changed files with git
diff/git diff --cached, which never include new untracked files; update the
collection logic (the branches handling "Case 1/2/3" where diffs are gathered)
to also run a command that lists untracked files (e.g., using git ls-files
--others --exclude-standard) and merge those results with the outputs of git
diff and git diff --cached, deduplicating before feeding into the
OWNERS/reviewer logic so new files are considered for reviewer suggestions.
Ensure the combined set is used wherever the script currently references the
diff-based file lists (the variables/places that gather staged, unstaged,
committed, and combined files).
commands/gwapi/delete.toml-24-29 (1)

24-29: ⚠️ Potential issue | 🟠 Major

The kubectl fallback is documented but not implemented in the actual command sequence.

Tool detection (Step 1) advertises checking for kubectl when oc is unavailable, but Steps 3–8 hard-code oc for all resource discovery, deletion, and verification commands. On a Kubernetes-only workstation, the flow passes tool detection and then fails immediately when executing the first oc command. Step 2 is the only exception, offering both oc whoami and kubectl cluster-info alternatives.

To support true kubectl fallback, either remove it from Step 1 or implement kubectl alternatives throughout Steps 3–8.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/gwapi/delete.toml` around lines 24 - 29, Step 1 advertises a kubectl
fallback but later Steps 3–8 hard-code oc; change the command flow to detect the
available CLI once (use the existing oc whoami / kubectl cluster-info checks)
and set a single TOOL variable (e.g., TOOL or kube_cmd) to either "oc" or
"kubectl", then replace all hard-coded occurrances of oc in Steps 3–8 with that
TOOL variable so resource discovery, deletion, and verification use the detected
CLI; ensure commands referenced like oc whoami and kubectl cluster-info remain
as detection alternatives and that subsequent commands (resource listing,
delete, wait/check) use the unified TOOL symbol.
commands/ci/trigger-postsubmit.toml-7-10 (1)

7-10: ⚠️ Potential issue | 🟠 Major

Finish the Claude→Gemini conversion in this prompt.

The generated command is ci:trigger-postsubmit, but Line 9 and the later examples/follow-ups still use /trigger-postsubmit and /query-job-status, while Lines 30-46 and 122 still address “Claude”. That leaves the generated extension internally inconsistent and can make Gemini suggest commands that do not exist under the ci: namespace.

Suggested prompt cleanup
-/trigger-postsubmit <job-name> <org> <repo> <base-ref> <base-sha> [ENV_VAR=value ...]
+/ci:trigger-postsubmit <job-name> <org> <repo> <base-ref> <base-sha> [ENV_VAR=value ...]

-9. **Offer Follow-up**: Optionally offer to query the job status using `/query-job-status`
+9. **Offer Follow-up**: Optionally offer to query the job status using `/ci:query-job-status`

-**Important for Claude**:
+**Important for Gemini CLI**:

-/trigger-postsubmit branch-ci-openshift-assisted-installer-release-4.12-images openshift assisted-installer release-4.12 7336f38f75f91a876313daacbfw97f25dfe21bbf
+/ci:trigger-postsubmit branch-ci-openshift-assisted-installer-release-4.12-images openshift assisted-installer release-4.12 7336f38f75f91a876313daacbfw97f25dfe21bbf

Also applies to: 30-49, 116-128, 132-145

commands/code-review/pre-commit-review.toml-39-40 (1)

39-40: ⚠️ Potential issue | 🟠 Major

These skill lookups still point at the pre-conversion layout.

The PR output stores generated skills at repo-root skills/ with plugin-prefixed names, but this prompt still looks for skills/lang-<lang>/SKILL.md and skills/profile-<name>/SKILL.md relative to a plugin root. In the generated Gemini extension those lookups miss, so language/profile-aware review silently falls back to generic mode.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/code-review/pre-commit-review.toml` around lines 39 - 40, The skill
lookup paths are still using the old plugin-relative layout (checking for
"skills/lang-<lang>/SKILL.md" and "skills/profile-<name>/SKILL.md"); update the
logic that handles language and profile skill discovery to look in the repo-root
"skills/" directory for plugin-prefixed filenames (e.g.,
"skills/<plugin>-lang-<lang>/SKILL.md" and
"skills/<plugin>-profile-<name>/SKILL.md"), keep the same behavior when the
files are missing (inform/warn and fall back to generic review), and ensure the
--profile handling uses the new repo-root lookup; modify the code that
constructs those paths (the skill lookup code referenced by the language/profile
checks) to build and read these repo-root plugin-prefixed paths.
commands/code-review/pr.toml-41-42 (1)

41-42: ⚠️ Potential issue | 🟠 Major

These skill lookups still point at the pre-conversion layout.

The generated extension stores skills at repo-root skills/ with plugin-prefixed names, but this command still searches for skills/lang-<lang>/SKILL.md and skills/profile-<name>/SKILL.md relative to a plugin root. That means PR reviews will never load the converted language/profile skills and will degrade to the generic path.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/code-review/pr.toml` around lines 41 - 42, The PR review command's
skill lookup still uses the old plugin-relative paths; update the lookup code in
the PR review handler (e.g., the logic in processPRReviewOptions / findSkillFile
/ loadSkillContent) so it first checks repo-root prefixed skill names like
skills/<plugin>-lang-<lang>/SKILL.md for language skills and
skills/<plugin>-profile-<name>/SKILL.md for profile skills (then falls back to
the generic path if not found), and ensure the content is read and stored the
same way as before for use by sub-agents.
commands/jira/create.toml-734-739 (1)

734-739: ⚠️ Potential issue | 🟠 Major

Replace the token-shaped example before it trips secret scanning again.

Line 737 contains a realistic sk_live_... placeholder that Gitleaks already flags as a generic API key. Keeping that in a generated artifact will create noisy security failures in CI and make real leaks harder to spot.

Safer example text
 Steps to reproduce:
-1. Export API_KEY=sk_live_abc123xyz
+1. Export API_KEY=YOUR_API_KEY
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/jira/create.toml` around lines 734 - 739, The example includes a
realistic token-shaped value ("Export API_KEY=sk_live_abc123xyz") which triggers
secret scanners; update the example in the commands/jira/create.toml content to
use a clearly non-secret placeholder (e.g., "Export API_KEY=YOUR_API_KEY" or
"Export API_KEY=REPLACE_WITH_API_KEY") wherever the API_KEY example appears, and
avoid any strings that match common secret prefixes like "sk_live_" so
CI/Gitleaks no longer flags it.
commands/jira/create.toml-49-55 (1)

49-55: ⚠️ Potential issue | 🟠 Major

Don't use Epic Link field for Task→Story relationships; use a proper subtask or parent-child mechanism.

Line 54 maps Task → Story to customfield_12311140 (Epic Link), yet the validation rules (line 135) and argument documentation (line 538) both advertise "Epic or Story" as valid Task parents. Epic Link is semantically designed for Epic relationships only; using it for Task→Story creates a mismatch. Either remove Task→Story from the allowed parent types and restrict Tasks to Epic parents only, or implement Story-child Tasks as Jira subtasks using the standard parent field.

Also applies to: 132-137, 534-539

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/jira/create.toml` around lines 49 - 55, The mapping for "Task →
Story" incorrectly uses the Epic Link custom field
(`additional_fields.customfield_12311140`) — update the create.toml so Tasks
cannot use Epic Link as a Story parent: either remove the "Task → Story" row
from the relationships table and update the related validation rules (the block
around lines 132-137) and argument docs (around lines 534-539) to restrict Tasks
to Epic parents only, or change Task→Story handling to create Story-child Tasks
as Jira subtasks by using the standard `parent` field (replace the
`additional_fields.customfield_12311140` mapping for the Task→Story case and
adjust validation/docs to reflect `parent`-based subtasks).
commands/git/commit-suggest.toml-40-50 (1)

40-50: ⚠️ Potential issue | 🟠 Major

Add clean worktree validation and explicit confirmation before history rewrite in Mode 2.

Mode 2 currently proceeds from message selection directly to git commit --amend or squash operations without checking the working tree state or requiring final approval. If the repo has unrelated staged or unstaged changes, the rewrite can inadvertently fold them into history.

Add a clean worktree check via git status --porcelain before step 4. If the tree is not clean, stop and ask the user to stash or commit first. After suggestion selection, show the exact git command to be executed and require a separate explicit yes/no confirmation before mutating history.

Suggested implementation
 **Mode 2 (with N):**
 1. Retrieve last N commits using `git log`
 2. Parse commit messages to extract types, scopes, and descriptions
+3. Verify the working tree is clean with `git status --porcelain`.
+   - If not clean, stop and ask the user to stash/commit unrelated changes first.
-3. For **N=1**: Suggest improved rewrite
-   For **N≥2**: Merge commits intelligently by type priority (`fix > feat > perf > refactor > docs > test > chore`)
-4. Generate 3 commit message suggestions (Recommended, Standard, Minimal)
-5. Display formatted suggestions and prompt user for selection
+4. For **N=1**: Suggest improved rewrite
+   For **N≥2**: Merge commits intelligently by type priority (`fix > feat > perf > refactor > docs > test > chore`)
+5. Generate 3 commit message suggestions (Recommended, Standard, Minimal)
+6. Display formatted suggestions and prompt user for selection
    - Ask: "Which suggestion would you like to use? (1/2/3 or skip)"
-   - Support responses: `1`, `use option 2`, `amend with option 3`, `skip`
-   - Execute `git commit --amend` (N=1) or squash operation (N≥2) if user requests
+   - Support responses: `1`, `use option 2`, `skip`
+   - Before any history rewrite, show the exact git command and require a separate explicit `yes/no` confirmation.
+   - Execute `git commit --amend` (N=1) or squash operation (N≥2) only after that confirmation
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/git/commit-suggest.toml` around lines 40 - 50, Mode 2 currently
proceeds to history rewrites without validating the worktree or explicit user
confirmation; add a pre-selection worktree cleanliness check by running "git
status --porcelain" and if non-empty abort with a message to stash/commit
changes, and after the user picks one of the three suggestions
(Recommended/Standard/Minimal) display the exact git command that will be run
(e.g. the exact git commit --amend or the squash sequence) and require a
separate explicit yes/no confirmation before executing the rewrite; update the
Mode 2 flow logic (the selection -> execution path) to perform the cleanliness
check and then the two-step confirmation (selection then execute) so commits are
not mutated unintentionally.
commands/jira/categorize-activity-type.toml-115-125 (1)

115-125: ⚠️ Potential issue | 🟠 Major

Move custom field to additional_fields per MCP contract.

The official MCP reference documentation specifies that custom fields must be updated via additional_fields, not fields. The fields parameter is reserved for standard Jira fields. Placing customfield_12320040 in fields violates the documented contract and will likely cause the update to fail.

Suggested fix
 mcp__atlassian__jira_update_issue(
     issue_key="${1}",
-    fields={
+    fields={},
+    additional_fields={
         "customfield_12320040": {  # Activity Type field
             "value": "<SELECTED_ACTIVITY_TYPE>"
         }
     }
 )

Note: commands/jira/create-release-note.toml has the same issue and should be fixed separately.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/jira/categorize-activity-type.toml` around lines 115 - 125, The MCP
call mcp__atlassian__jira_update_issue currently places customfield_12320040
inside the fields argument which violates the MCP contract; move the
customfield_12320040 key/value into the additional_fields payload instead of
fields (i.e., stop writing customfield_12320040 under fields and add it under
additional_fields with the same value structure), and make the same change in
the other occurrence in create-release-note (ensure you keep the "value":
"<SELECTED_ACTIVITY_TYPE>" shape when moving it).
commands/etcd/analyze-performance.toml-82-93 (1)

82-93: ⚠️ Potential issue | 🟠 Major

Inconsistency in cluster analysis scope: log diagnostics should cover all etcd members.

Line 85 selects a single arbitrary etcd pod using .items[0], while lines 100–150 correctly use the --cluster flag to report database statistics and health for all three members. However, lines 168–275 perform all log-based diagnostics (slow operations, disk warnings, leader changes, proposal latency, network issues) on only that one pod. This creates an analysis gap: performance degradation on the other two members will be completely missed. Refactor the log analysis section to iterate over all running etcd members (oc get pods -n openshift-etcd -l app=etcd --field-selector=status.phase=Running -o jsonpath='{.items[*].metadata.name}') and report findings per member before providing cluster-wide summary.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/etcd/analyze-performance.toml` around lines 82 - 93, The script
currently sets ETCD_POD using jsonpath '.items[0]' (ETCD_POD variable) and then
runs all log-based diagnostics against that single pod; change this to capture
all running etcd pod names using jsonpath '.items[*].metadata.name' (e.g.,
ETCD_PODS) and refactor the log analysis section to loop over each pod name,
running the existing per-pod diagnostics (slow operations, disk warnings, leader
changes, proposal latency, network issues) for each member and printing
per-member findings, then keep the existing cluster-wide checks (the commands
that use --cluster) as a summary/aggregation step. Ensure references to ETCD_POD
in the log analysis are replaced with the per-pod loop variable so no
single-member-only commands remain.

Comment thread commands/container-image/compare.toml Outdated
Comment thread commands/git/branch-cleanup.toml Outdated
Comment thread commands/git/cherry-pick-by-patch.toml Outdated
@zhfeng
zhfeng force-pushed the feat/gemini-extension-conversion branch from 1efc60a to 67c2b11 Compare March 9, 2026 12:15

@coderabbitai coderabbitai 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.

Actionable comments posted: 18

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🟡 Minor comments (14)
commands/hcp/generate.toml-208-241 (1)

208-241: ⚠️ Potential issue | 🟡 Minor

Nested code blocks will render incorrectly in markdown.

The example output section embeds a ```bash block inside an outer ``` block. Standard markdown parsers will interpret the inner triple-backticks as closing the outer block, causing malformed rendering.

Consider using indentation (4 spaces) for the outer block or escaping the inner backticks:

🔧 Proposed fix using indented code block for outer wrapper
 **Example output:**
-```
-## Summary
-Creating a development AWS hosted cluster with basic configuration.
-
-## Generated Command
-```bash
+
+    ## Summary
+    Creating a development AWS hosted cluster with basic configuration.
+    
+    ## Generated Command
+    ```bash
+    hypershift create cluster aws \
+      --name dev-cluster \
+      ...
+    ```
+    
+    ## Key Decisions
+    ...

Alternatively, escape the inner backticks with a backslash or use a different fence character (e.g., ~~~) for the inner block.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/hcp/generate.toml` around lines 208 - 241, The markdown example uses
a fenced code block that contains another fenced block (a ```bash``` inside an
outer ```), which breaks rendering; fix the "Example output" by replacing the
outer fence with an indented code block (4-space indent) or by switching the
inner or outer fence to a different delimiter (e.g., use ~~~ for the inner block
or escape the inner backticks) so the nested command block renders correctly in
the generated TOML content.
commands/hcp/generate.toml-349-355 (1)

349-355: ⚠️ Potential issue | 🟡 Minor

Skill paths reference outdated directory structure.

The documentation references plugins/hypershift/skills/ which doesn't exist after conversion. Skills are located at skills/ with plugin-prefixed names.

Correct paths
 To view skill details:
 ```bash
-ls plugins/hypershift/skills/
-cat plugins/hypershift/skills/hcp-create-aws/SKILL.md
-cat plugins/hypershift/skills/hcp-create-kubevirt/SKILL.md
+ls skills/
+cat skills/hcp-hcp-create-aws/SKILL.md
+cat skills/hcp-hcp-create-kubevirt/SKILL.md
 # ... etc for other providers
 ```'''
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/hcp/generate.toml` around lines 349 - 355, Update the documentation
references that point to the now-removed plugins/hypershift/skills/ directory to
the new skills/ layout and use the plugin-prefixed skill directories; e.g.
replace occurrences like "plugins/hypershift/skills/" and "hcp-create-aws" with
"skills/" and "hcp-hcp-create-aws" (and similarly "hcp-hcp-create-kubevirt" for
kubevirt) so the examples read "ls skills/" and "cat
skills/hcp-hcp-create-aws/SKILL.md" etc.
commands/must-gather/ovn-dbs.toml-54-54 (1)

54-54: ⚠️ Potential issue | 🟡 Minor

Replace Claude reference with Gemini.

Per the PR objectives, Claude-specific references should be replaced with Gemini equivalents. This line still references "Claude" instead of "Gemini CLI".

,

📝 Proposed fix
-Claude will automatically locate it by searching for the script in the plugin installation directory, regardless of your current working directory.
+Gemini CLI will automatically locate it by searching for the script in the plugin installation directory, regardless of your current working directory.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/must-gather/ovn-dbs.toml` at line 54, Update the human-readable
sentence that currently says "Claude will automatically locate it by searching
for the script in the plugin installation directory, regardless of your current
working directory." to reference the Gemini product instead: replace "Claude"
with "Gemini CLI" so it reads that Gemini CLI will automatically locate the
script; edit the literal string in commands/must-gather/ovn-dbs.toml where that
sentence appears.
commands/jira/solve.toml-69-71 (1)

69-71: ⚠️ Potential issue | 🟡 Minor

Fix Go syntax in example.

The example function signature uses invalid Go syntax. Parameter types should follow parameter names.

📝 Proposed fix
-      - For example, a comment should not be generated for a simple function like func add(int a, b) int { return a + b}
+      - For example, a comment should not be generated for a simple function like func add(a, b int) int { return a + b }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/jira/solve.toml` around lines 69 - 71, The example under the
guidance for godoc comments uses invalid Go parameter syntax for the function
symbol func add; update that example so parameter names precede their types
(e.g., list parameter names followed by their shared type or each name with its
type) and keep the return type and body unchanged, so the example is valid Go
syntax and compiles if copied.
Makefile-45-47 (1)

45-47: ⚠️ Potential issue | 🟡 Minor

Target help text points to the wrong generated artifacts.

convert_to_gemini.py --check validates the root-level generated outputs, not a gemini-extensions/ directory. When this target fails, the current description will send contributors looking in the wrong place.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Makefile` around lines 45 - 47, Update the Makefile target description for
verify-gemini-sync to accurately reflect what convert_to_gemini.py --check
validates: change the help text from mentioning "gemini-extensions/" to
indicating it verifies the root-level generated outputs (or "generated artifacts
at the repository root") so contributors are pointed to the correct location;
reference the Makefile target name verify-gemini-sync and the script
convert_to_gemini.py --check when making this wording change.
commands/ci/list-step.toml-63-66 (1)

63-66: ⚠️ Potential issue | 🟡 Minor

Example command omits the /ci: namespace.

The synopsis defines /ci:list-step, but the example uses /list-step. Copy-pasting this example will invoke the wrong command.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/ci/list-step.toml` around lines 63 - 66, The example invocation is
missing the required /ci: namespace so users will call the wrong command; update
the example to use the correct command name (/ci:list-step) instead of
/list-step in the snippet and any related examples so they match the synopsis
(reference: the /ci:list-step command name used in the synopsis).
commands/ci/list-step.toml-52-59 (1)

52-59: ⚠️ Potential issue | 🟡 Minor

Claude-specific wording leaked into the generated Gemini command.

The PR objective says Claude-specific references are rewritten, but this section is still titled Important for Claude:. That makes the converted extension look only partially migrated.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/ci/list-step.toml` around lines 52 - 59, The header "Important for
Claude:" in commands/ci/list-step.toml leaks Claude-specific wording; search for
that exact heading and any occurrences of "Claude" in the file (including the
numbered checklist lines) and replace them with neutral, target-agnostic
phrasing (e.g., "Important for agent:" or "Important for the analyzer:") and
ensure the remaining checklist entries (lines starting with "1. REQUIRED:" etc.)
do not contain any Claude-specific references so the converted Gemini command is
fully migrated.
commands/ci/trigger-postsubmit.toml-55-63 (1)

55-63: ⚠️ Potential issue | 🟡 Minor

Implementation step numbering error.

Step numbering jumps from step 1 to step 3, skipping step 2. This appears to be a copy-paste or editing error.

📝 Suggested fix
    - $6-$N: environment variable overrides in KEY=VALUE format (optional)

-3. **Construct JSON Payload**: Build the payload with refs structure:
+2. **Construct JSON Payload**: Build the payload with refs structure:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/ci/trigger-postsubmit.toml` around lines 55 - 63, The markdown
numbered steps in the comment block are misnumbered (it shows "1. **Parse
Arguments**" then jumps to "3. **Construct JSON Payload**"); update the sequence
so the intermediate step is "2." (or renumber the entire list) to restore proper
ordering and consistency—look for the strings "1. **Parse Arguments**" and "3.
**Construct JSON Payload**" in the TOML/comment and change the numbering to "2."
(or sequential numbers) so the steps read 1, 2, 3 correctly.
commands/ci/trigger-postsubmit.toml-7-10 (1)

7-10: ⚠️ Potential issue | 🟡 Minor

Synopsis command name mismatch.

The synopsis on line 9 shows /trigger-postsubmit but the command name defined on line 5 is ci:trigger-postsubmit. This inconsistency could confuse users.

📝 Suggested fix
 ## Synopsis

-/trigger-postsubmit [ENV_VAR=value ...]
+/ci:trigger-postsubmit [ENV_VAR=value ...]

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/ci/trigger-postsubmit.toml` around lines 7 - 10, The synopsis uses
the wrong command name: update the synopsis line that currently shows
"/trigger-postsubmit <job-name> <org> <repo> <base-ref> <base-sha>
[ENV_VAR=value ...]" to use the actual command name "ci:trigger-postsubmit
<job-name> <org> <repo> <base-ref> <base-sha> [ENV_VAR=value ...]" so it matches
the defined command (ci:trigger-postsubmit) and avoids user confusion.
commands/must-gather/analyze.toml-46-59 (1)

46-59: ⚠️ Potential issue | 🟡 Minor

Missing scripts in Prerequisites documentation.

The Prerequisites section lists available scripts (lines 50-59), but the Implementation section references additional scripts that aren't documented:

  • analyze_prometheus.py (referenced at lines 122, 136)
  • analyze_windows_logs.py (referenced at lines 123, 140)
📝 Suggested fix
 ├── analyze_etcd.py
-└── analyze_pvs.py
+├── analyze_pvs.py
+├── analyze_prometheus.py
+└── analyze_windows_logs.py
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/must-gather/analyze.toml` around lines 46 - 59, The Prerequisites
list in analyze.toml is missing two scripts that are actually referenced
elsewhere: add analyze_prometheus.py and analyze_windows_logs.py to the
documented scripts under the Analysis scripts bundle so the Implementation
section references match the Prerequisites; update the list that currently
enumerates analyze_clusterversion.py, analyze_clusteroperators.py,
analyze_nodes.py, analyze_pods.py, analyze_network.py, analyze_ovn_dbs.py,
analyze_events.py, analyze_etcd.py, analyze_pvs.py to include
analyze_prometheus.py and analyze_windows_logs.py (these are the files
referenced in the Implementation at lines that call/mention
analyze_prometheus.py and analyze_windows_logs.py).
commands/jira/clone-from-github.toml-264-266 (1)

264-266: ⚠️ Potential issue | 🟡 Minor

Jira PAT creation URL may be incorrect for Red Hat Jira.

Line 265 references the Atlassian Cloud URL (https://id.atlassian.com/manage-profile/security/api-tokens), but Red Hat uses on-premise Jira Server at issues.redhat.com, which has a different PAT creation flow. The note on line 266 acknowledges this but could be clearer.

Consider updating to provide clearer guidance:

📝 Suggested clarification
-  - Create at: https://id.atlassian.com/manage-profile/security/api-tokens (for Jira Cloud)
-  - Or follow your organization's Jira PAT creation process
+  - For Red Hat Jira: https://issues.redhat.com (Profile → Personal Access Tokens)
+  - For Jira Cloud: https://id.atlassian.com/manage-profile/security/api-tokens
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/jira/clone-from-github.toml` around lines 264 - 266, Update the Jira
PAT guidance under the "**Jira**: Personal Access Token" section to avoid
pointing exclusively to Atlassian Cloud; replace or augment the Atlassian Cloud
URL with a clear note that on-prem Red Hat Jira (issues.redhat.com) uses a
different PAT/token creation flow and that users should follow their Red
Hat/Jira Server instance's local security or admin docs (or contact their Jira
admin) to create an access token; ensure the text mentions both the Atlassian
Cloud URL (https://id.atlassian.com/manage-profile/security/api-tokens) as
applicable for cloud users and a distinct sentence for Red Hat on-prem users
directing them to issues.redhat.com local procedures or admin support so the
guidance is unambiguous.
commands/jira/grooming.toml-127-131 (1)

127-131: ⚠️ Potential issue | 🟡 Minor

Unclosed code block in example 12.

The code block for example 12 is missing its closing triple backticks, which will cause Markdown rendering issues.

📝 Proposed fix
 12. **Combine Label and status filters**:
     ```bash
     /jira:grooming OCPBUGS last-week --label "performance" --status "NEW"
+    ```
 
 
 ## Output Format
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/jira/grooming.toml` around lines 127 - 131, The Markdown example
labeled "Combine Label and status filters" contains an unclosed code block for
the bash snippet "/jira:grooming OCPBUGS last-week --label \"performance\"
--status \"NEW\""; fix it by adding the missing closing triple backticks (```)
immediately after that command so the fenced code block is properly terminated
and renders correctly in the grooming.toml example.
commands/ci/analyze-prow-job-test-failure.toml-26-41 (1)

26-41: ⚠️ Potential issue | 🟡 Minor

Inconsistent command names in usage examples.

The examples reference /ci:analyze-test-failure (Lines 28, 36), but the actual command name defined at Line 5 is /ci:analyze-prow-job-test-failure. This inconsistency will confuse users.

📝 Proposed fix
 **Default (comprehensive analysis)**:
 ```text
-/ci:analyze-test-failure <url> <test-name>
+/ci:analyze-prow-job-test-failure <url> <test-name>
  • Detects must-gather availability
  • Prompts user whether to include cluster diagnostics
  • Provides correlated test + cluster analysis

Fast mode (skip must-gather):

-/ci:analyze-test-failure <url> <test-name> --fast
+/ci:analyze-prow-job-test-failure <url> <test-name> --fast
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @commands/ci/analyze-prow-job-test-failure.toml around lines 26 - 41, The
usage examples incorrectly show the command as /ci:analyze-test-failure; update
both examples to use the actual command name /ci:analyze-prow-job-test-failure
(including the fast-mode example with --fast) so the displayed invocation
matches the implemented command and avoids confusion when users copy/paste.


</details>

</blockquote></details>
<details>
<summary>commands/etcd/analyze-performance.toml-29-55 (1)</summary><blockquote>

`29-55`: _⚠️ Potential issue_ | _🟡 Minor_

**Add `jq` and `bc` to the prerequisites section.**

The documented prerequisites only mention OpenShift CLI (`oc`), but the implementation requires `jq` (lines 111–139 for JSON parsing) and `bc` (lines 293–338 for floating-point arithmetic). On a clean admin host, the script will fail with `command not found` errors after passing initial checks. Update the prerequisites and regenerate the plugin spec.

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @commands/etcd/analyze-performance.toml around lines 29 - 55, Update the "##
Prerequisites" section to list jq and bc as required tools (alongside oc),
because the analyze-performance implementation uses jq for JSON parsing and bc
for floating-point arithmetic; add short install/verify hints for both (e.g.,
package names and a verification command like jq --version and bc --version)
and then regenerate the plugin spec so the updated TOML is published.


</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🧹 Nitpick comments (3)</summary><blockquote>

<details>
<summary>README.md (1)</summary><blockquote>

`71-74`: **Add language specifier to fenced code block.**

For consistency with other code blocks in this file and to satisfy markdownlint (MD040), specify a language for this code block.


<details>
<summary>📝 Proposed fix</summary>

```diff
 **Use the commands:**
-```
+```bash
 /jira:solve OCPBUGS-12345 origin
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @README.md around lines 71 - 74, The fenced code block containing the command
"/jira:solve OCPBUGS-12345 origin" in README.md lacks a language specifier;
update that fenced block to include a language token (e.g., "bash") so it reads
like bash ... to match other blocks and satisfy markdownlint MD040,
ensuring the block around the string "/jira:solve OCPBUGS-12345 origin" is
changed accordingly.


</details>

</blockquote></details>
<details>
<summary>commands/ci/trigger-periodic.toml (1)</summary><blockquote>

`95-101`: **Clarify AI assistant references.**

The "Important for Claude" section header at line 95 seems inconsistent with this being a Gemini extension. Line 97 correctly references "Gemini CLI" but the section title and line 96's "Skill tool" reference may cause confusion about which AI assistant is being addressed.

Consider updating the section header and clarifying the context if this guidance applies to Gemini CLI users.

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against the current code and only fix it if needed.

In `@commands/ci/trigger-periodic.toml` around lines 95 - 101, Update the section
header and wording that currently reads "Important for Claude" to explicitly
target Gemini CLI users (e.g., "Important for Gemini") and reword any mentions
of "Skill tool" to the correct invocation method for the Gemini environment;
ensure the instructions reference the required skill name "ci:oc-auth", the
script "curl_with_token.sh", and the follow-up action "/query-job-status" so
it's clear the steps are for Gemini CLI (load ci:oc-auth, locate
curl_with_token.sh, parse JSON for execution ID, display it, and offer to check
job status).
```

</details>

</blockquote></details>
<details>
<summary>commands/jira/update-weekly-status.toml (1)</summary><blockquote>

`276-283`: **Hardcoded custom field ID may require documentation.**

The custom field ID `customfield_12320841` is hardcoded for the Status Summary field. While this is acceptable for organization-specific tooling, consider adding a comment in the prompt noting that this field ID is specific to the Red Hat Jira instance and may need adjustment for other environments.


<details>
<summary>💡 Suggested improvement</summary>

```diff
 Use `mcp__atlassian-mcp__jira_update_issue`:

+**Note**: The custom field ID below (`customfield_12320841`) is specific to the Red Hat Jira instance for the "Status Summary" field. Other Jira instances may use different field IDs.
+
 ```json
 {
   "issue_key": "{ISSUE-KEY}",
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against the current code and only fix it if needed.

In `@commands/jira/update-weekly-status.toml` around lines 276 - 283, The JSON
payload hardcodes the Jira custom field ID customfield_12320841 for the Status
Summary; update the prompt or nearby documentation in update-weekly-status.toml
to add a clear comment that customfield_12320841 is Red Hat–specific and may
need to be changed for other Jira instances, and optionally indicate where to
configure or override this field ID (e.g., via environment variable or template
parameter) so maintainers know how to adapt it.
```

</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against the current code and only fix it if needed.

Inline comments:
In @commands/bigquery/analyze-usage.toml:

  • Around line 64-68: The "Offer to Save Report" step that suggests saving to
    bigquery-usage--.md and calls the Write tool must not
    save sensitive identifiers or query previews without explicit user consent and
    redaction; update the save flow to (1) add a redaction mode that strips or masks
    user/service-account identifiers and query snippets before writing, (2) present
    a clear explicit warning prompt summarizing what sensitive fields will be saved
    and require an affirmative confirmation (e.g., "I understand the risks and want
    to save unredacted"), and (3) default to saving a redacted report unless the
    user explicitly chooses unredacted and confirms; make these changes in the code
    path that builds the suggested filename and invokes the Write tool so the
    prompt, redaction logic, and confirmed write are enforced before any file is
    created.

In @commands/ci/add-debug-wait.toml:

  • Around line 443-455: The script currently hard-codes pushing to "origin" and
    the compare URL to
    "openshift/release@master...${branch_name}", which
    breaks fork workflows; change the flow to determine or prompt for the push
    remote (e.g., a variable like push_remote) and derive the repository owner/name
    from that remote (or ask the user if ambiguous) and then use that push_remote
    and derived repo owner/name to construct both the git push command and the
    compare URL instead of using "origin" and "openshift/release"; update
    occurrences of git push origin "${branch_name}" and the printed compare URL to
    use the new push_remote and repo variables.

In @commands/ci/payload-agent.toml:

  • Around line 20-25: Summary: The HIGH-confidence action path is not idempotent
    and can create duplicate TRT JIRA bugs, revert PRs, and validation-job triggers
    when re-run. Fix: implement the same persistence/guard pattern used by the
    MEDIUM-confidence flow—before creating a TRT JIRA bug, opening a revert PR, or
    triggering payload validation jobs, check for an existing marker/tracking
    artifact (the "tracking file" concept used by Phase 1/Phase 2) tied to the
    payload identifier; if the marker exists, skip creation and instead reconcile or
    report status. Locate the HIGH-confidence branch that performs "Automatically
    creates a TRT JIRA bug, opens a revert PR, and triggers payload validation jobs"
    and add existence checks and consistent marker writes equivalent to the
    medium-confidence tracking-file logic so repeated runs are no-ops.

In @commands/ci/trigger-presubmit.toml:

  • Around line 8-10: Update all user-visible command references to include the
    namespace prefix so they match the actual command names: replace occurrences of
    "/trigger-presubmit" with "/ci:trigger-presubmit" and "/query-job-status" with
    "/ci:query-job-status" (and similarly for any other command mentions) in the
    synopsis, examples, and follow-up steps; ensure the displayed command strings
    match the defined command symbol ci:trigger-presubmit and ci:query-job-status so
    generated docs/examples are accurate.

In @commands/code-review/pr.toml:

  • Around line 41-42: The lookup still only checks plugin-root paths
    skills/lang-<lang>/SKILL.md and skills/profile-<name>/SKILL.md, so
    --language and --profile miss converted, repo-level skills; update the
    resolver (the code that handles the --language and --profile flags) to first
    attempt the original plugin-root paths and then fall back to repo-level
    skills/ directory using the plugin-prefixed filenames the converter produces
    (e.g. skills/<plugin>-lang-<lang>/SKILL.md and
    skills/<plugin>-profile-<name>/SKILL.md), reading and storing the content if
    found and warning/continuing only if both checks fail.

In @commands/compliance/analyze-cve.toml:

  • Line 48: The generated TOML contains relative skill links like the string
    "cve-intelligence-gathering"
    that point to commands/skills/... instead of the top-level skills tree; update
    the generator that emits commands/compliance/analyze-cve.toml (and other
    affected sections producing lines similar to the "Skill:
    ") to rewrite those hrefs to
    "skills//SKILL.md" (i.e., remove the leading "../") so generated
    artifacts reference the top-level skills directory consistently across all
    occurrences (also fix the same pattern at the other noted locations, e.g., lines
    around 62-63 and 98).

In @commands/etcd/analyze-performance.toml:

  • Around line 82-94: The script currently selects a single pod via ETCD_POD and
    later pulls logs only from that pod; change this to collect logs from all etcd
    members by replacing the single ETCD_POD selection with ETCD_PODS="$(oc get pods
    -n openshift-etcd -l app=etcd --field-selector=status.phase=Running -o
    jsonpath='{.items[*].metadata.name}')" and loop over each pod name to run oc
    logs (the commands that reference ETCD_POD and the oc logs invocation)
    aggregating per-member logs; also update the source plugin prompt text (the
    artifact generation input) to state explicitly that logs must be gathered and
    analyzed across all etcd members (cluster-wide) so sections that summarize
    cluster state use the aggregated logs rather than a single pod’s logs.

In @commands/etcd/health-check.toml:

  • Around line 152-160: Initialize a WARNINGS counter early (e.g., set
    WARNINGS=0) and increment it each time a warning branch is triggered: after the
    quorum check that uses MEMBER_COUNT, after the unstarted-members check that uses
    UNSTARTED and MEMBER_LIST, and similarly in the other warning branches (the ones
    around lines referencing dns/port or health checks). Concretely, add
    WARNINGS=$((WARNINGS + 1)) immediately after each echo "WARNING: ..." so the
    final summary that tests $WARNINGS works reliably and avoids "integer expression
    expected".
  • Around line 46-52: Add explicit bash argument parsing and initialization for
    the missing flags and counters: initialize VERBOSE=0 and WARNINGS=0 at the top
    of the health-check script in plugins/etcd/commands/health-check.md, add a
    command-line parsing loop that recognizes --verbose (sets VERBOSE=1) and any
    other flags that should affect WARNINGS, and ensure any warning-producing checks
    increment WARNINGS when they detect issues (so the summary's $WARNINGS reflects
    real counts). After updating the script, regenerate the TOML so the documented
    --verbose argument and summary counters match the implementation.

In @commands/git/suggest-reviewers.toml:

  • Around line 95-120: Replace Claude-specific environment variable references
    ${CLAUDE_PLUGIN_ROOT} in the suggested commands with a Gemini-compatible or
    neutral variable (e.g., ${GEMINI_PLUGIN_ROOT} or ${PLUGIN_ROOT}) so the
    helper script path
    ${CLAUDE_PLUGIN_ROOT}/skills/suggest-reviewers/analyze_blame.py becomes
    ${GEMINI_PLUGIN_ROOT}/skills/suggest-reviewers/analyze_blame.py (or
    ${PLUGIN_ROOT}/skills/suggest-reviewers/analyze_blame.py) everywhere it
    appears; update all occurrences in the file (the three command examples that
    reference the helper script) to use the chosen variable consistently and ensure
    the displayed bash examples use the same replacement.

In @commands/jira/backlog.toml:

  • Around line 44-52: The content mixes Gemini and Claude setup flows—keep one
    consistent (prefer Gemini) by replacing all Claude-specific instructions: change
    any "claude mcp add" to "gemini mcp add", update the config path
    "/.config/claude-code/mcp.json" to the Gemini equivalent (e.g.
    "
    /.config/gemini/mcp.json"), and ensure the earlier instruction to restart the
    Gemini CLI is followed by the Gemini-specific command and config references;
    apply the same normalization for the other affected block mentioned (the later
    115-145 range).
  • Around line 505-512: Replace the unsafe inline PAT in the curl example with an
    env-based or wrapper pattern: instruct users to export JIRA_PERSONAL_TOKEN (or
    use the existing JIRA_PERSONAL_TOKEN/JIRA_URL variables) and run curl with the
    header built from the environment (e.g., using -H "Authorization: Bearer
    $JIRA_PERSONAL_TOKEN" or recommend the provided CLI wrapper) instead of
    embedding the token on the command line; update the troubleshooting bullet that
    currently shows curl -H "Authorization: Bearer YOUR_TOKEN"
    YOUR_JIRA_URL/rest/api/2/myself to use JIRA_PERSONAL_TOKEN and JIRA_URL
    environment variables and a wrapper/env-based example to avoid shell-history
    token leakage.

In @commands/jira/generate-test-plan.toml:

  • Around line 17-18: The command in generate-test-plan.toml hard-codes the Jira
    host in the curl REST call ("https://issues.redhat.com/rest/api/2/issue/{$1}")
    and in the WebFetch scraping step, so it won't respect the shared Jira host
    configuration; update both places to use the shared Jira host configuration
    (e.g., a common variable/env like JIRA_HOST or the project's jiraHost config)
    instead of the literal "issues.redhat.com", and ensure the WebFetch URL and the
    REST API URL are constructed from that single config value so the command works
    against other Jira instances.

In @commands/jira/issues-by-component.toml:

  • Around line 124-128: The JQL builder currently injects user tokens like
    last-week, last-2-weeks, and last-month (from the parser reading
    $2/time-period) directly into the template created >= -{time-period},
    producing invalid JQL; update the code that prepares the time-period variable
    (the parser/templating step that reads $2) to map those friendly tokens to
    valid JQL values (e.g., last-week -> 7d or compute explicit ISO dates like
    YYYY/MM/DD ranges) and accept custom YYYY-MM-DD:YYYY-MM-DD by converting it
    into an explicit created >= "YYYY-MM-DD" AND created <= "YYYY-MM-DD" clause
    (or created >= -Nd for relative ranges). Apply the same conversion logic where
    the template injection is performed so the final JQL uses valid duration syntax
    or explicit dates instead of -last-week.

In @commands/jira/setup-gh2jira.toml:

  • Around line 169-173: The curl examples expose secrets via command-line
    arguments; instead read the tokens from the environment and supply the
    Authorization header via stdin or a temporary file so the token never appears in
    the process argument list—replace the two direct-argument uses (the curl call
    that uses GITHUB_TOKEN and the curl call that uses JIRA_TOKEN) with a pattern
    that builds the header from the environment and feeds it to curl via stdin or a
    secure temp file (e.g., echo/printf the header from $GITHUB_TOKEN or $JIRA_TOKEN
    and pipe it to curl using curl's "@-" or file-header mechanism), ensuring the
    shell never places the raw token text into the command-line arguments.

In @commands/lvms/analyze.toml:

  • Around line 159-172: The built-in file reads in commands/lvms/analyze.toml
    currently hard-code the namespace "openshift-lvm-storage" for files like
    "{must-gather-path}/namespaces/openshift-lvm-storage/pods.yaml" and
    "{must-gather-path}/namespaces/openshift-lvm-storage/events.yaml", which drops
    support for older "openshift-storage" must-gathers; update the logic/text so the
    analyzer tries both namespaces (e.g., attempt
    "{must-gather-path}/namespaces/openshift-lvm-storage/..." and if missing fall
    back to "{must-gather-path}/namespaces/openshift-storage/..."), or iterate over
    a namespaces list before giving up, and ensure the LVMCluster/LVMVolumeGroup
    find commands likewise check both names when the optional Python script is
    absent.
  • Around line 550-558: Step 4 uses the same namespace-wide delete command as
    Step 2 and therefore restarts every vg-manager pod; replace that line so it
    targets only the vg-manager pod running on worker-0. Change the command string
    "oc delete pod -n openshift-lvm-storage -l
    app.kubernetes.io/component=vg-manager" in Step 4 to a node-scoped delete that
    selects the pod on worker-0 (for example by adding a field selector like
    --field-selector spec.nodeName=worker-0 or by resolving the pod name on worker-0
    and deleting that single pod) so only the vg-manager on worker-0 is restarted.

In @commands/must-gather/windows.toml:

  • Around line 7-10: The documented flags (--component, --errors-only,
    --max-errors) are not passed to the implementation and the synopsis omits
    --max-errors; update the CLI invocation in commands/must-gather/windows.toml so
    the command calls analyze_windows_logs.py with the flags forwarded (e.g.,
    include --component, --errors-only, --max-errors when present) and update the
    synopsis block to list --max-errors as well; search for any other occurrences
    mentioned (around lines referenced) and ensure all places that launch
    analyze_windows_logs.py or document the /must-gather:windows command
    consistently accept and forward those three flags.

Minor comments:
In @commands/ci/analyze-prow-job-test-failure.toml:

  • Around line 26-41: The usage examples incorrectly show the command as
    /ci:analyze-test-failure; update both examples to use the actual command name
    /ci:analyze-prow-job-test-failure (including the fast-mode example with --fast)
    so the displayed invocation matches the implemented command and avoids confusion
    when users copy/paste.

In @commands/ci/list-step.toml:

  • Around line 63-66: The example invocation is missing the required /ci:
    namespace so users will call the wrong command; update the example to use the
    correct command name (/ci:list-step) instead of /list-step in the snippet and
    any related examples so they match the synopsis (reference: the /ci:list-step
    command name used in the synopsis).
  • Around line 52-59: The header "Important for Claude:" in
    commands/ci/list-step.toml leaks Claude-specific wording; search for that exact
    heading and any occurrences of "Claude" in the file (including the numbered
    checklist lines) and replace them with neutral, target-agnostic phrasing (e.g.,
    "Important for agent:" or "Important for the analyzer:") and ensure the
    remaining checklist entries (lines starting with "1. REQUIRED:" etc.) do not
    contain any Claude-specific references so the converted Gemini command is fully
    migrated.

In @commands/ci/trigger-postsubmit.toml:

  • Around line 55-63: The markdown numbered steps in the comment block are
    misnumbered (it shows "1. Parse Arguments" then jumps to "3. Construct
    JSON Payload
    "); update the sequence so the intermediate step is "2." (or
    renumber the entire list) to restore proper ordering and consistency—look for
    the strings "1. Parse Arguments" and "3. Construct JSON Payload" in the
    TOML/comment and change the numbering to "2." (or sequential numbers) so the
    steps read 1, 2, 3 correctly.
  • Around line 7-10: The synopsis uses the wrong command name: update the
    synopsis line that currently shows "/trigger-postsubmit
    [ENV_VAR=value ...]" to use the actual command name
    "ci:trigger-postsubmit
    [ENV_VAR=value ...]" so it matches the defined command (ci:trigger-postsubmit)
    and avoids user confusion.

In @commands/etcd/analyze-performance.toml:

  • Around line 29-55: Update the "## Prerequisites" section to list jq and bc as
    required tools (alongside oc), because the analyze-performance implementation
    uses jq for JSON parsing and bc for floating-point arithmetic; add short
    install/verify hints for both (e.g., package names and a verification command
    like jq --version and bc --version) and then regenerate the plugin spec so
    the updated TOML is published.

In @commands/hcp/generate.toml:

  • Around line 208-241: The markdown example uses a fenced code block that
    contains another fenced block (a bash inside an outer ```), which breaks
    rendering; fix the "Example output" by replacing the outer fence with an
    indented code block (4-space indent) or by switching the inner or outer fence to
    a different delimiter (e.g., use ~~~ for the inner block or escape the inner
    backticks) so the nested command block renders correctly in the generated TOML
    content.
  • Around line 349-355: Update the documentation references that point to the
    now-removed plugins/hypershift/skills/ directory to the new skills/ layout and
    use the plugin-prefixed skill directories; e.g. replace occurrences like
    "plugins/hypershift/skills/" and "hcp-create-aws" with "skills/" and
    "hcp-hcp-create-aws" (and similarly "hcp-hcp-create-kubevirt" for kubevirt) so
    the examples read "ls skills/" and "cat skills/hcp-hcp-create-aws/SKILL.md" etc.

In @commands/jira/clone-from-github.toml:

  • Around line 264-266: Update the Jira PAT guidance under the "Jira:
    Personal Access Token" section to avoid pointing exclusively to Atlassian Cloud;
    replace or augment the Atlassian Cloud URL with a clear note that on-prem Red
    Hat Jira (issues.redhat.com) uses a different PAT/token creation flow and that
    users should follow their Red Hat/Jira Server instance's local security or admin
    docs (or contact their Jira admin) to create an access token; ensure the text
    mentions both the Atlassian Cloud URL
    (https://id.atlassian.com/manage-profile/security/api-tokens) as applicable for
    cloud users and a distinct sentence for Red Hat on-prem users directing them to
    issues.redhat.com local procedures or admin support so the guidance is
    unambiguous.

In @commands/jira/grooming.toml:

  • Around line 127-131: The Markdown example labeled "Combine Label and status
    filters" contains an unclosed code block for the bash snippet "/jira:grooming
    OCPBUGS last-week --label "performance" --status "NEW""; fix it by adding
    the missing closing triple backticks (```) immediately after that command so the
    fenced code block is properly terminated and renders correctly in the
    grooming.toml example.

In @commands/jira/solve.toml:

  • Around line 69-71: The example under the guidance for godoc comments uses
    invalid Go parameter syntax for the function symbol func add; update that
    example so parameter names precede their types (e.g., list parameter names
    followed by their shared type or each name with its type) and keep the return
    type and body unchanged, so the example is valid Go syntax and compiles if
    copied.

In @commands/must-gather/analyze.toml:

  • Around line 46-59: The Prerequisites list in analyze.toml is missing two
    scripts that are actually referenced elsewhere: add analyze_prometheus.py and
    analyze_windows_logs.py to the documented scripts under the Analysis scripts
    bundle so the Implementation section references match the Prerequisites; update
    the list that currently enumerates analyze_clusterversion.py,
    analyze_clusteroperators.py, analyze_nodes.py, analyze_pods.py,
    analyze_network.py, analyze_ovn_dbs.py, analyze_events.py, analyze_etcd.py,
    analyze_pvs.py to include analyze_prometheus.py and analyze_windows_logs.py
    (these are the files referenced in the Implementation at lines that call/mention
    analyze_prometheus.py and analyze_windows_logs.py).

In @commands/must-gather/ovn-dbs.toml:

  • Line 54: Update the human-readable sentence that currently says "Claude will
    automatically locate it by searching for the script in the plugin installation
    directory, regardless of your current working directory." to reference the
    Gemini product instead: replace "Claude" with "Gemini CLI" so it reads that
    Gemini CLI will automatically locate the script; edit the literal string in
    commands/must-gather/ovn-dbs.toml where that sentence appears.

In @Makefile:

  • Around line 45-47: Update the Makefile target description for
    verify-gemini-sync to accurately reflect what convert_to_gemini.py --check
    validates: change the help text from mentioning "gemini-extensions/" to
    indicating it verifies the root-level generated outputs (or "generated artifacts
    at the repository root") so contributors are pointed to the correct location;
    reference the Makefile target name verify-gemini-sync and the script
    convert_to_gemini.py --check when making this wording change.

Nitpick comments:
In @commands/ci/trigger-periodic.toml:

  • Around line 95-101: Update the section header and wording that currently reads
    "Important for Claude" to explicitly target Gemini CLI users (e.g., "Important
    for Gemini") and reword any mentions of "Skill tool" to the correct invocation
    method for the Gemini environment; ensure the instructions reference the
    required skill name "ci:oc-auth", the script "curl_with_token.sh", and the
    follow-up action "/query-job-status" so it's clear the steps are for Gemini CLI
    (load ci:oc-auth, locate curl_with_token.sh, parse JSON for execution ID,
    display it, and offer to check job status).

In @commands/jira/update-weekly-status.toml:

  • Around line 276-283: The JSON payload hardcodes the Jira custom field ID
    customfield_12320841 for the Status Summary; update the prompt or nearby
    documentation in update-weekly-status.toml to add a clear comment that
    customfield_12320841 is Red Hat–specific and may need to be changed for other
    Jira instances, and optionally indicate where to configure or override this
    field ID (e.g., via environment variable or template parameter) so maintainers
    know how to adapt it.

In @README.md:

  • Around line 71-74: The fenced code block containing the command "/jira:solve
    OCPBUGS-12345 origin" in README.md lacks a language specifier; update that
    fenced block to include a language token (e.g., "bash") so it reads like bash ... to match other blocks and satisfy markdownlint MD040, ensuring the block
    around the string "/jira:solve OCPBUGS-12345 origin" is changed accordingly.

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: Path: .coderabbit.yaml

**Review profile**: CHILL

**Plan**: Pro

**Run ID**: `477f4806-0012-4a86-bb20-772e858670e3`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 1efc60a88fc70793c0d48ba2c0227e04db8ae764 and 67c2b11fafa9aa57e90321104aadc927e1dd2277.

</details>

<details>
<summary>📒 Files selected for processing (300)</summary>

* `.github/workflows/verify-gemini-sync.yml`
* `GEMINI.md`
* `Makefile`
* `README.md`
* `commands/agendas/outcome-refinement.toml`
* `commands/bigquery/analyze-usage.toml`
* `commands/ci/add-debug-wait.toml`
* `commands/ci/analyze-payload.toml`
* `commands/ci/analyze-pr-reverts.toml`
* `commands/ci/analyze-prow-job-install-failure.toml`
* `commands/ci/analyze-prow-job-resource.toml`
* `commands/ci/analyze-prow-job-test-failure.toml`
* `commands/ci/analyze-regression.toml`
* `commands/ci/ask-sippy.toml`
* `commands/ci/check-if-jira-regression-is-ongoing.toml`
* `commands/ci/extract-prow-job-must-gather.toml`
* `commands/ci/fetch-payloads.toml`
* `commands/ci/fetch-test-report.toml`
* `commands/ci/list-step.toml`
* `commands/ci/list-unstable-tests.toml`
* `commands/ci/payload-agent.toml`
* `commands/ci/query-job-status.toml`
* `commands/ci/query-test-result.toml`
* `commands/ci/revert-pr.toml`
* `commands/ci/trigger-periodic.toml`
* `commands/ci/trigger-postsubmit.toml`
* `commands/ci/trigger-presubmit.toml`
* `commands/code-review/pr.toml`
* `commands/code-review/pre-commit-review.toml`
* `commands/compliance/analyze-cve.toml`
* `commands/container-image/compare.toml`
* `commands/container-image/inspect.toml`
* `commands/container-image/tags.toml`
* `commands/doc/note.toml`
* `commands/etcd/analyze-performance.toml`
* `commands/etcd/health-check.toml`
* `commands/git/backport.toml`
* `commands/git/bisect.toml`
* `commands/git/branch-cleanup.toml`
* `commands/git/cherry-pick-by-patch.toml`
* `commands/git/commit-suggest.toml`
* `commands/git/debt-scan.toml`
* `commands/git/fix-cherrypick-robot-pr.toml`
* `commands/git/redescribe.toml`
* `commands/git/suggest-reviewers.toml`
* `commands/git/summary.toml`
* `commands/golang/lint-fix.toml`
* `commands/gwapi/check.toml`
* `commands/gwapi/delete.toml`
* `commands/gwapi/install.toml`
* `commands/hcp/cluster-health-check.toml`
* `commands/hcp/generate.toml`
* `commands/hello-world/echo.toml`
* `commands/jira/backlog.toml`
* `commands/jira/categorize-activity-type.toml`
* `commands/jira/clone-from-github.toml`
* `commands/jira/create-release-note.toml`
* `commands/jira/create.toml`
* `commands/jira/generate-feature-doc.toml`
* `commands/jira/generate-test-plan.toml`
* `commands/jira/grooming.toml`
* `commands/jira/issues-by-component.toml`
* `commands/jira/reconcile-github.toml`
* `commands/jira/setup-gh2jira.toml`
* `commands/jira/solve.toml`
* `commands/jira/status-rollup.toml`
* `commands/jira/update-weekly-status.toml`
* `commands/jira/validate-blockers.toml`
* `commands/lvms/analyze.toml`
* `commands/must-gather/analyze.toml`
* `commands/must-gather/ovn-dbs.toml`
* `commands/must-gather/windows.toml`
* `commands/node-tuning/analyze-node-tuning.toml`
* `commands/node-tuning/generate-tuned-profile.toml`
* `commands/node/cluster-node-health-check.toml`
* `commands/olm-team/configure-agent.toml`
* `commands/olm-team/dev-setup.toml`
* `commands/olm-team/ep-watch.toml`
* `commands/olm/approve.toml`
* `commands/olm/catalog.toml`
* `commands/olm/debug.toml`
* `commands/olm/diagnose.toml`
* `commands/olm/install.toml`
* `commands/olm/list.toml`
* `commands/olm/opm.toml`
* `commands/olm/search.toml`
* `commands/olm/status.toml`
* `commands/olm/uninstall.toml`
* `commands/olm/upgrade.toml`
* `commands/openshift/add-enhancement.toml`
* `commands/openshift/bootstrap-om.toml`
* `commands/openshift/bump-deps.toml`
* `commands/openshift/cluster-health-check.toml`
* `commands/openshift/crd-review.toml`
* `commands/openshift/create-cluster.toml`
* `commands/openshift/destroy-cluster.toml`
* `commands/openshift/expand-test-case.toml`
* `commands/openshift/ironic-status.toml`
* `commands/openshift/new-e2e-test.toml`
* `commands/openshift/node-kernel-conntrack.toml`
* `commands/openshift/node-kernel-ip.toml`
* `commands/openshift/node-kernel-iptables.toml`
* `commands/openshift/node-kernel-nft.toml`
* `commands/openshift/rebase.toml`
* `commands/openshift/review-test-cases.toml`
* `commands/openshift/visualize-ovn-topology.toml`
* `commands/origin/two-node-origin-pr-helper.toml`
* `commands/ote-migration/migrate.toml`
* `commands/session/save-session.toml`
* `commands/sosreport/analyze.toml`
* `commands/sosreport/ovs-db.toml`
* `commands/teams/coderabbit-adoption-report.toml`
* `commands/teams/coderabbit-inheritance-scanner.toml`
* `commands/teams/health-check-jiras.toml`
* `commands/teams/health-check-regressions.toml`
* `commands/teams/health-check.toml`
* `commands/teams/list-components.toml`
* `commands/teams/list-jiras.toml`
* `commands/teams/list-regressions.toml`
* `commands/teams/list-teams.toml`
* `commands/test-coverage/analyze.toml`
* `commands/test-coverage/gaps.toml`
* `commands/testing/mutation-test.toml`
* `commands/utils/address-reviews.toml`
* `commands/utils/auto-approve-konflux-prs.toml`
* `commands/utils/generate-test-plan.toml`
* `commands/utils/gh-attention.toml`
* `commands/utils/placeholder.toml`
* `commands/utils/process-renovate-pr.toml`
* `commands/utils/review-ai-helpers-overlap.toml`
* `commands/utils/review-security.toml`
* `commands/workspaces/create.toml`
* `commands/workspaces/delete.toml`
* `commands/yaml/docs.toml`
* `gemini-extension.json`
* `scripts/convert_to_gemini.py`
* `skills/bigquery-analyze-usage/SKILL.md`
* `skills/ci-analyze-payload/SKILL.md`
* `skills/ci-bisect-payload-suspects/SKILL.md`
* `skills/ci-fetch-jira-issue/README.md`
* `skills/ci-fetch-jira-issue/SKILL.md`
* `skills/ci-fetch-jira-issue/fetch_jira_issue.py`
* `skills/ci-fetch-new-prs-in-payload/SKILL.md`
* `skills/ci-fetch-new-prs-in-payload/fetch_new_prs_in_payload.py`
* `skills/ci-fetch-payloads/SKILL.md`
* `skills/ci-fetch-payloads/fetch_payloads.py`
* `skills/ci-fetch-prowjob-json/SKILL.md`
* `skills/ci-fetch-regression-details/README.md`
* `skills/ci-fetch-regression-details/SKILL.md`
* `skills/ci-fetch-regression-details/fetch_regression_details.py`
* `skills/ci-fetch-related-triages/SKILL.md`
* `skills/ci-fetch-related-triages/fetch_related_triages.py`
* `skills/ci-fetch-releases/SKILL.md`
* `skills/ci-fetch-releases/fetch_releases.py`
* `skills/ci-fetch-test-report/SKILL.md`
* `skills/ci-fetch-test-report/fetch_test_report.py`
* `skills/ci-fetch-test-runs/README.md`
* `skills/ci-fetch-test-runs/SKILL.md`
* `skills/ci-fetch-test-runs/fetch_test_runs.py`
* `skills/ci-oc-auth/README.md`
* `skills/ci-oc-auth/SKILL.md`
* `skills/ci-oc-auth/curl_with_token.sh`
* `skills/ci-payload-agent/SKILL.md`
* `skills/ci-prow-job-analyze-install-failure/SKILL.md`
* `skills/ci-prow-job-analyze-metal-install-failure/SKILL.md`
* `skills/ci-prow-job-analyze-resource/CHANGELOG.md`
* `skills/ci-prow-job-analyze-resource/README.md`
* `skills/ci-prow-job-analyze-resource/SCRIPTS.md`
* `skills/ci-prow-job-analyze-resource/SKILL.md`
* `skills/ci-prow-job-analyze-resource/create_context_html_files.py`
* `skills/ci-prow-job-analyze-resource/create_inline_html_files.py`
* `skills/ci-prow-job-analyze-resource/generate_html_report.py`
* `skills/ci-prow-job-analyze-resource/generate_report.py`
* `skills/ci-prow-job-analyze-resource/parse_all_logs.py`
* `skills/ci-prow-job-analyze-resource/parse_audit_logs.py`
* `skills/ci-prow-job-analyze-resource/parse_pod_logs.py`
* `skills/ci-prow-job-analyze-resource/parse_url.py`
* `skills/ci-prow-job-analyze-resource/prow_job_resource_grep.sh`
* `skills/ci-prow-job-analyze-resource/report_template.html`
* `skills/ci-prow-job-analyze-test-failure/README.md`
* `skills/ci-prow-job-analyze-test-failure/SKILL.md`
* `skills/ci-prow-job-artifact-search/SKILL.md`
* `skills/ci-prow-job-artifact-search/prow_job_artifact_search.py`
* `skills/ci-prow-job-extract-must-gather/CHANGELOG.md`
* `skills/ci-prow-job-extract-must-gather/README.md`
* `skills/ci-prow-job-extract-must-gather/SKILL.md`
* `skills/ci-prow-job-extract-must-gather/extract_archives.py`
* `skills/ci-prow-job-extract-must-gather/generate_html_report.py`
* `skills/ci-revert-pr/SKILL.md`
* `skills/ci-set-release-blocker/SKILL.md`
* `skills/ci-set-release-blocker/set_release_blocker.py`
* `skills/ci-stage-payload-reverts/SKILL.md`
* `skills/ci-triage-regression/README.md`
* `skills/ci-triage-regression/SKILL.md`
* `skills/ci-triage-regression/triage_regression.py`
* `skills/ci-trigger-payload-job/SKILL.md`
* `skills/code-review-lang-go/SKILL.md`
* `skills/code-review-profile-hypershift/SKILL.md`
* `skills/compliance-call-graph-analysis/SKILL.md`
* `skills/compliance-codebase-impact-analysis/SKILL.md`
* `skills/compliance-cve-intelligence-gathering/SKILL.md`
* `skills/compliance-remediation-planning/SKILL.md`
* `skills/git-suggest-reviewers/SKILL.md`
* `skills/git-suggest-reviewers/analyze_blame.py`
* `skills/golang-lint/SKILL.md`
* `skills/hcp-hcp-create-agent/SKILL.md`
* `skills/hcp-hcp-create-aws/SKILL.md`
* `skills/hcp-hcp-create-azure/SKILL.md`
* `skills/hcp-hcp-create-kubevirt/SKILL.md`
* `skills/hcp-hcp-create-openstack/SKILL.md`
* `skills/hcp-hcp-create-powervs/SKILL.md`
* `skills/jira-categorize-activity-type/SKILL.md`
* `skills/jira-cntrlplane/SKILL.md`
* `skills/jira-create-bug/SKILL.md`
* `skills/jira-create-epic/SKILL.md`
* `skills/jira-create-feature-request/SKILL.md`
* `skills/jira-create-feature/SKILL.md`
* `skills/jira-create-release-note/SKILL.md`
* `skills/jira-create-story/SKILL.md`
* `skills/jira-create-task/SKILL.md`
* `skills/jira-extract-prs/SKILL.md`
* `skills/jira-gcp-hcp/CLAUDE.md`
* `skills/jira-gcp-hcp/SKILL.md`
* `skills/jira-hypershift/SKILL.md`
* `skills/jira-jira-doc-generator/SKILL.md`
* `skills/jira-jira-issues-by-component/README.md`
* `skills/jira-jira-issues-by-component/SKILL.md`
* `skills/jira-jira-issues-by-component/jira_curl.sh`
* `skills/jira-jira-validate-blockers/SKILL.md`
* `skills/jira-ocpbugs/SKILL.md`
* `skills/jira-status-analysis/SKILL.md`
* `skills/jira-status-analysis/activity-analysis.md`
* `skills/jira-status-analysis/data-collection.md`
* `skills/jira-status-analysis/external-links.md`
* `skills/jira-status-analysis/formatting.md`
* `skills/jira-status-analysis/scripts/gather_status_data.py`
* `skills/lvms-lvms-analyzer/SKILL.md`
* `skills/lvms-lvms-analyzer/scripts/analyze_lvms.py`
* `skills/must-gather-must-gather-analyzer/SKILL.md`
* `skills/must-gather-must-gather-analyzer/scripts/analyze_clusteroperators.py`
* `skills/must-gather-must-gather-analyzer/scripts/analyze_clusterversion.py`
* `skills/must-gather-must-gather-analyzer/scripts/analyze_etcd.py`
* `skills/must-gather-must-gather-analyzer/scripts/analyze_events.py`
* `skills/must-gather-must-gather-analyzer/scripts/analyze_network.py`
* `skills/must-gather-must-gather-analyzer/scripts/analyze_nodes.py`
* `skills/must-gather-must-gather-analyzer/scripts/analyze_ovn_dbs.py`
* `skills/must-gather-must-gather-analyzer/scripts/analyze_pods.py`
* `skills/must-gather-must-gather-analyzer/scripts/analyze_prometheus.py`
* `skills/must-gather-must-gather-analyzer/scripts/analyze_pvs.py`
* `skills/must-gather-must-gather-analyzer/scripts/analyze_windows_logs.py`
* `skills/node-tuning-scripts/SKILL.md`
* `skills/node-tuning-scripts/analyze_node_tuning.py`
* `skills/node-tuning-scripts/generate_tuned_profile.py`
* `skills/olm-team-k8s-ocp-olm-expert/README.md`
* `skills/olm-team-k8s-ocp-olm-expert/SKILL.md`
* `skills/olm-team-k8s-ocp-olm-expert/config-example.json`
* `skills/olm-team-k8s-ocp-olm-expert/config-template.json`
* `skills/openshift-generating-ovn-topology/README.md`
* `skills/openshift-generating-ovn-topology/SKILL.md`
* `skills/openshift-generating-ovn-topology/scripts/analyze_placement.py`
* `skills/openshift-generating-ovn-topology/scripts/check_permissions.py`
* `skills/openshift-generating-ovn-topology/scripts/collect_ovn_data.py`
* `skills/openshift-generating-ovn-topology/scripts/detect-cluster.sh`
* `skills/openshift-generating-ovn-topology/scripts/ovn_utils.py`
* `skills/openshift-openshift-node-kernel/SKILL.md`
* `skills/openshift-openshift-node-kernel/kernel-helper.sh`
* `skills/openshift-openshift-node-kernel/node-kernel-conntrack.sh`
* `skills/openshift-openshift-node-kernel/node-kernel-ip.sh`
* `skills/openshift-openshift-node-kernel/node-kernel-iptables.sh`
* `skills/openshift-openshift-node-kernel/node-kernel-nft.sh`
* `skills/ote-migration-ote-migration-workflow/SKILL.md`
* `skills/sosreport-logs-analysis/SKILL.md`
* `skills/sosreport-network-analysis/SKILL.md`
* `skills/sosreport-ovs-db-analysis/SKILL.md`
* `skills/sosreport-ovs-db-analysis/scripts/analyze_ovs_db.py`
* `skills/sosreport-resource-analysis/SKILL.md`
* `skills/sosreport-system-config-analysis/SKILL.md`
* `skills/teams-analyze-regressions/README.md`
* `skills/teams-analyze-regressions/SKILL.md`
* `skills/teams-analyze-regressions/generate_html_report.py`
* `skills/teams-analyze-regressions/report_template.html`
* `skills/teams-coderabbit-adoption/SKILL.md`
* `skills/teams-coderabbit-adoption/coderabbit_adoption.py`
* `skills/teams-coderabbit-inheritance-scanner-check/SKILL.md`
* `skills/teams-coderabbit-inheritance-scanner-existing-pr/SKILL.md`
* `skills/teams-coderabbit-inheritance-scanner-open-pr/SKILL.md`
* `skills/teams-coderabbit-inheritance-scanner-search/SKILL.md`
* `skills/teams-get-release-dates/README.md`
* `skills/teams-get-release-dates/SKILL.md`
* `skills/teams-get-release-dates/get_release_dates.py`
* `skills/teams-list-components/SKILL.md`
* `skills/teams-list-components/list_components.py`
* `skills/teams-list-jiras/SKILL.md`
* `skills/teams-list-jiras/list_jiras.py`
* `skills/teams-list-regressions/README.md`
* `skills/teams-list-regressions/SKILL.md`
* `skills/teams-list-regressions/list_regressions.py`
* `skills/teams-list-teams/SKILL.md`
* `skills/teams-list-teams/list_teams.py`
* `skills/teams-summarize-jiras/SKILL.md`

</details>

<details>
<summary>✅ Files skipped from review due to trivial changes (1)</summary>

* commands/container-image/compare.toml

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (27)</summary>

* commands/git/summary.toml
* commands/hello-world/echo.toml
* commands/container-image/inspect.toml
* commands/container-image/tags.toml
* commands/ci/query-job-status.toml
* commands/code-review/pre-commit-review.toml
* commands/ci/revert-pr.toml
* commands/ci/ask-sippy.toml
* commands/ci/analyze-prow-job-resource.toml
* commands/ci/extract-prow-job-must-gather.toml
* commands/jira/status-rollup.toml
* commands/jira/generate-feature-doc.toml
* commands/ci/query-test-result.toml
* commands/agendas/outcome-refinement.toml
* commands/git/cherry-pick-by-patch.toml
* commands/git/commit-suggest.toml
* commands/git/redescribe.toml
* commands/hcp/cluster-health-check.toml
* commands/gwapi/delete.toml
* commands/jira/validate-blockers.toml
* commands/ci/fetch-payloads.toml
* commands/node-tuning/generate-tuned-profile.toml
* GEMINI.md
* commands/golang/lint-fix.toml
* commands/git/fix-cherrypick-robot-pr.toml
* commands/ci/list-unstable-tests.toml
* commands/git/debt-scan.toml

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Comment thread commands/bigquery/analyze-usage.toml Outdated
Comment thread commands/ci/add-debug-wait.toml Outdated
Comment thread commands/ci/payload-agent.toml Outdated
Comment thread commands/ci/trigger-presubmit.toml Outdated
Comment thread commands/code-review/pr.toml Outdated
Comment thread commands/jira/issues-by-component.toml Outdated
Comment thread commands/jira/setup-gh2jira.toml Outdated
Comment thread commands/lvms/analyze.toml Outdated
Comment thread commands/lvms/analyze.toml Outdated
Comment thread commands/must-gather/windows.toml Outdated
@wangke19

wangke19 commented Mar 9, 2026

Copy link
Copy Markdown
Contributor

PR is too big to review. better to split into many small ones one by one.

@zhfeng

zhfeng commented Mar 9, 2026

Copy link
Copy Markdown
Contributor Author

Sorry, I think most of changes are added by the generated files. So not sure it can be seperated in another PR?

@stbenjam

Copy link
Copy Markdown
Member

I would split out the code that does the conversion and the converison itself. CodeRabbit also seems intent on reviewing all the generated files, too.

We should exclude anything generated: https://docs.coderabbit.ai/reference/configuration

@zhfeng
zhfeng force-pushed the feat/gemini-extension-conversion branch from 67c2b11 to 16e1603 Compare March 10, 2026 03:06
@zhfeng

zhfeng commented Mar 10, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @stbenjam - I split them to two seperated commits and add exclude the generated files from review in .coderabbit.yaml.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
Makefile (1)

37-43: Reuse convert-to-gemini from update.

update now duplicates the same conversion recipe as convert-to-gemini, so future changes to the invocation can drift between the two targets.

♻️ Proposed refactor
 	`@echo` "Building website data..."
 	`@python3` scripts/build-website.py
-	`@echo` "Converting plugins to Gemini extensions..."
-	`@python3` scripts/convert_to_gemini.py
+	@$(MAKE) convert-to-gemini
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Makefile` around lines 37 - 43, Duplicate conversion recipe exists in the
Makefile: remove the duplicated commands under the update target and make update
invoke the canonical convert-to-gemini target instead; specifically, replace the
duplicated echo/python lines in the update target with a call to the
convert-to-gemini target using $(MAKE) or make so update depends on and reuses
convert-to-gemini (reference targets: convert-to-gemini and update).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Makefile`:
- Around line 45-47: The Makefile target verify-gemini-sync has a stale help
description referencing gemini-extensions/ but actually runs "python3
scripts/convert_to_gemini.py --check" to verify root-level generated Gemini
artifacts; update the target's comment/description line to accurately describe
that it verifies root-level generated Gemini artifacts (or "generated Gemini
files in the repository root") so contributors are pointed to the correct
location when the check fails—modify the comment next to the verify-gemini-sync
target to mention the root-level generated Gemini artifacts and/or the
scripts/convert_to_gemini.py --check check.

In `@README.md`:
- Around line 71-74: Replace the hardcoded remote name in the README example
command '/jira:solve OCPBUGS-12345 origin' with a placeholder (e.g., '<remote>')
and update the surrounding text to instruct readers to discover their remote
first (suggest using 'git remote -v' or 'git branch -vv'); modify the example
command and adjacent explanation so the README no longer assumes a remote named
"origin" and instead guides users to determine the correct remote for their fork
or repo.

---

Nitpick comments:
In `@Makefile`:
- Around line 37-43: Duplicate conversion recipe exists in the Makefile: remove
the duplicated commands under the update target and make update invoke the
canonical convert-to-gemini target instead; specifically, replace the duplicated
echo/python lines in the update target with a call to the convert-to-gemini
target using $(MAKE) or make so update depends on and reuses convert-to-gemini
(reference targets: convert-to-gemini and update).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ed93f5c9-c111-4b98-95ee-7bf011fa484e

📥 Commits

Reviewing files that changed from the base of the PR and between 67c2b11 and 16e1603.

⛔ Files ignored due to path filters (295)
  • GEMINI.md is excluded by !GEMINI.md
  • commands/agendas/outcome-refinement.toml is excluded by !commands/**
  • commands/bigquery/analyze-usage.toml is excluded by !commands/**
  • commands/ci/add-debug-wait.toml is excluded by !commands/**
  • commands/ci/analyze-payload.toml is excluded by !commands/**
  • commands/ci/analyze-pr-reverts.toml is excluded by !commands/**
  • commands/ci/analyze-prow-job-install-failure.toml is excluded by !commands/**
  • commands/ci/analyze-prow-job-resource.toml is excluded by !commands/**
  • commands/ci/analyze-prow-job-test-failure.toml is excluded by !commands/**
  • commands/ci/analyze-regression.toml is excluded by !commands/**
  • commands/ci/ask-sippy.toml is excluded by !commands/**
  • commands/ci/check-if-jira-regression-is-ongoing.toml is excluded by !commands/**
  • commands/ci/extract-prow-job-must-gather.toml is excluded by !commands/**
  • commands/ci/fetch-payloads.toml is excluded by !commands/**
  • commands/ci/fetch-test-report.toml is excluded by !commands/**
  • commands/ci/list-step.toml is excluded by !commands/**
  • commands/ci/list-unstable-tests.toml is excluded by !commands/**
  • commands/ci/payload-agent.toml is excluded by !commands/**
  • commands/ci/query-job-status.toml is excluded by !commands/**
  • commands/ci/query-test-result.toml is excluded by !commands/**
  • commands/ci/revert-pr.toml is excluded by !commands/**
  • commands/ci/trigger-periodic.toml is excluded by !commands/**
  • commands/ci/trigger-postsubmit.toml is excluded by !commands/**
  • commands/ci/trigger-presubmit.toml is excluded by !commands/**
  • commands/code-review/pr.toml is excluded by !commands/**
  • commands/code-review/pre-commit-review.toml is excluded by !commands/**
  • commands/compliance/analyze-cve.toml is excluded by !commands/**
  • commands/container-image/compare.toml is excluded by !commands/**
  • commands/container-image/inspect.toml is excluded by !commands/**
  • commands/container-image/tags.toml is excluded by !commands/**
  • commands/doc/note.toml is excluded by !commands/**
  • commands/etcd/analyze-performance.toml is excluded by !commands/**
  • commands/etcd/health-check.toml is excluded by !commands/**
  • commands/git/backport.toml is excluded by !commands/**
  • commands/git/bisect.toml is excluded by !commands/**
  • commands/git/branch-cleanup.toml is excluded by !commands/**
  • commands/git/cherry-pick-by-patch.toml is excluded by !commands/**
  • commands/git/commit-suggest.toml is excluded by !commands/**
  • commands/git/debt-scan.toml is excluded by !commands/**
  • commands/git/fix-cherrypick-robot-pr.toml is excluded by !commands/**
  • commands/git/redescribe.toml is excluded by !commands/**
  • commands/git/suggest-reviewers.toml is excluded by !commands/**
  • commands/git/summary.toml is excluded by !commands/**
  • commands/golang/lint-fix.toml is excluded by !commands/**
  • commands/gwapi/check.toml is excluded by !commands/**
  • commands/gwapi/delete.toml is excluded by !commands/**
  • commands/gwapi/install.toml is excluded by !commands/**
  • commands/hcp/cluster-health-check.toml is excluded by !commands/**
  • commands/hcp/generate.toml is excluded by !commands/**
  • commands/hello-world/echo.toml is excluded by !commands/**
  • commands/jira/backlog.toml is excluded by !commands/**
  • commands/jira/categorize-activity-type.toml is excluded by !commands/**
  • commands/jira/clone-from-github.toml is excluded by !commands/**
  • commands/jira/create-release-note.toml is excluded by !commands/**
  • commands/jira/create.toml is excluded by !commands/**
  • commands/jira/generate-feature-doc.toml is excluded by !commands/**
  • commands/jira/generate-test-plan.toml is excluded by !commands/**
  • commands/jira/grooming.toml is excluded by !commands/**
  • commands/jira/issues-by-component.toml is excluded by !commands/**
  • commands/jira/reconcile-github.toml is excluded by !commands/**
  • commands/jira/setup-gh2jira.toml is excluded by !commands/**
  • commands/jira/solve.toml is excluded by !commands/**
  • commands/jira/status-rollup.toml is excluded by !commands/**
  • commands/jira/update-weekly-status.toml is excluded by !commands/**
  • commands/jira/validate-blockers.toml is excluded by !commands/**
  • commands/lvms/analyze.toml is excluded by !commands/**
  • commands/must-gather/analyze.toml is excluded by !commands/**
  • commands/must-gather/ovn-dbs.toml is excluded by !commands/**
  • commands/must-gather/windows.toml is excluded by !commands/**
  • commands/node-tuning/analyze-node-tuning.toml is excluded by !commands/**
  • commands/node-tuning/generate-tuned-profile.toml is excluded by !commands/**
  • commands/node/cluster-node-health-check.toml is excluded by !commands/**
  • commands/olm-team/configure-agent.toml is excluded by !commands/**
  • commands/olm-team/dev-setup.toml is excluded by !commands/**
  • commands/olm-team/ep-watch.toml is excluded by !commands/**
  • commands/olm/approve.toml is excluded by !commands/**
  • commands/olm/catalog.toml is excluded by !commands/**
  • commands/olm/debug.toml is excluded by !commands/**
  • commands/olm/diagnose.toml is excluded by !commands/**
  • commands/olm/install.toml is excluded by !commands/**
  • commands/olm/list.toml is excluded by !commands/**
  • commands/olm/opm.toml is excluded by !commands/**
  • commands/olm/search.toml is excluded by !commands/**
  • commands/olm/status.toml is excluded by !commands/**
  • commands/olm/uninstall.toml is excluded by !commands/**
  • commands/olm/upgrade.toml is excluded by !commands/**
  • commands/openshift/add-enhancement.toml is excluded by !commands/**
  • commands/openshift/bootstrap-om.toml is excluded by !commands/**
  • commands/openshift/bump-deps.toml is excluded by !commands/**
  • commands/openshift/cluster-health-check.toml is excluded by !commands/**
  • commands/openshift/crd-review.toml is excluded by !commands/**
  • commands/openshift/create-cluster.toml is excluded by !commands/**
  • commands/openshift/destroy-cluster.toml is excluded by !commands/**
  • commands/openshift/expand-test-case.toml is excluded by !commands/**
  • commands/openshift/ironic-status.toml is excluded by !commands/**
  • commands/openshift/new-e2e-test.toml is excluded by !commands/**
  • commands/openshift/node-kernel-conntrack.toml is excluded by !commands/**
  • commands/openshift/node-kernel-ip.toml is excluded by !commands/**
  • commands/openshift/node-kernel-iptables.toml is excluded by !commands/**
  • commands/openshift/node-kernel-nft.toml is excluded by !commands/**
  • commands/openshift/rebase.toml is excluded by !commands/**
  • commands/openshift/review-test-cases.toml is excluded by !commands/**
  • commands/openshift/visualize-ovn-topology.toml is excluded by !commands/**
  • commands/origin/two-node-origin-pr-helper.toml is excluded by !commands/**
  • commands/ote-migration/migrate.toml is excluded by !commands/**
  • commands/session/save-session.toml is excluded by !commands/**
  • commands/sosreport/analyze.toml is excluded by !commands/**
  • commands/sosreport/ovs-db.toml is excluded by !commands/**
  • commands/teams/coderabbit-adoption-report.toml is excluded by !commands/**
  • commands/teams/coderabbit-inheritance-scanner.toml is excluded by !commands/**
  • commands/teams/health-check-jiras.toml is excluded by !commands/**
  • commands/teams/health-check-regressions.toml is excluded by !commands/**
  • commands/teams/health-check.toml is excluded by !commands/**
  • commands/teams/list-components.toml is excluded by !commands/**
  • commands/teams/list-jiras.toml is excluded by !commands/**
  • commands/teams/list-regressions.toml is excluded by !commands/**
  • commands/teams/list-teams.toml is excluded by !commands/**
  • commands/test-coverage/analyze.toml is excluded by !commands/**
  • commands/test-coverage/gaps.toml is excluded by !commands/**
  • commands/testing/mutation-test.toml is excluded by !commands/**
  • commands/utils/address-reviews.toml is excluded by !commands/**
  • commands/utils/auto-approve-konflux-prs.toml is excluded by !commands/**
  • commands/utils/generate-test-plan.toml is excluded by !commands/**
  • commands/utils/gh-attention.toml is excluded by !commands/**
  • commands/utils/placeholder.toml is excluded by !commands/**
  • commands/utils/process-renovate-pr.toml is excluded by !commands/**
  • commands/utils/review-ai-helpers-overlap.toml is excluded by !commands/**
  • commands/utils/review-security.toml is excluded by !commands/**
  • commands/workspaces/create.toml is excluded by !commands/**
  • commands/workspaces/delete.toml is excluded by !commands/**
  • commands/yaml/docs.toml is excluded by !commands/**
  • gemini-extension.json is excluded by !gemini-extension.json
  • skills/bigquery-analyze-usage/SKILL.md is excluded by !skills/**
  • skills/ci-analyze-payload/SKILL.md is excluded by !skills/**
  • skills/ci-bisect-payload-suspects/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-jira-issue/README.md is excluded by !skills/**
  • skills/ci-fetch-jira-issue/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-jira-issue/fetch_jira_issue.py is excluded by !skills/**
  • skills/ci-fetch-new-prs-in-payload/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-new-prs-in-payload/fetch_new_prs_in_payload.py is excluded by !skills/**
  • skills/ci-fetch-payloads/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-payloads/fetch_payloads.py is excluded by !skills/**
  • skills/ci-fetch-prowjob-json/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-regression-details/README.md is excluded by !skills/**
  • skills/ci-fetch-regression-details/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-regression-details/fetch_regression_details.py is excluded by !skills/**
  • skills/ci-fetch-related-triages/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-related-triages/fetch_related_triages.py is excluded by !skills/**
  • skills/ci-fetch-releases/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-releases/fetch_releases.py is excluded by !skills/**
  • skills/ci-fetch-test-report/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-test-report/fetch_test_report.py is excluded by !skills/**
  • skills/ci-fetch-test-runs/README.md is excluded by !skills/**
  • skills/ci-fetch-test-runs/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-test-runs/fetch_test_runs.py is excluded by !skills/**
  • skills/ci-oc-auth/README.md is excluded by !skills/**
  • skills/ci-oc-auth/SKILL.md is excluded by !skills/**
  • skills/ci-oc-auth/curl_with_token.sh is excluded by !skills/**
  • skills/ci-payload-agent/SKILL.md is excluded by !skills/**
  • skills/ci-prow-job-analyze-install-failure/SKILL.md is excluded by !skills/**
  • skills/ci-prow-job-analyze-metal-install-failure/SKILL.md is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/CHANGELOG.md is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/README.md is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/SCRIPTS.md is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/SKILL.md is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/create_context_html_files.py is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/create_inline_html_files.py is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/generate_html_report.py is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/generate_report.py is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/parse_all_logs.py is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/parse_audit_logs.py is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/parse_pod_logs.py is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/parse_url.py is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/prow_job_resource_grep.sh is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/report_template.html is excluded by !skills/**
  • skills/ci-prow-job-analyze-test-failure/README.md is excluded by !skills/**
  • skills/ci-prow-job-analyze-test-failure/SKILL.md is excluded by !skills/**
  • skills/ci-prow-job-artifact-search/SKILL.md is excluded by !skills/**
  • skills/ci-prow-job-artifact-search/prow_job_artifact_search.py is excluded by !skills/**
  • skills/ci-prow-job-extract-must-gather/CHANGELOG.md is excluded by !skills/**
  • skills/ci-prow-job-extract-must-gather/README.md is excluded by !skills/**
  • skills/ci-prow-job-extract-must-gather/SKILL.md is excluded by !skills/**
  • skills/ci-prow-job-extract-must-gather/extract_archives.py is excluded by !skills/**
  • skills/ci-prow-job-extract-must-gather/generate_html_report.py is excluded by !skills/**
  • skills/ci-revert-pr/SKILL.md is excluded by !skills/**
  • skills/ci-set-release-blocker/SKILL.md is excluded by !skills/**
  • skills/ci-set-release-blocker/set_release_blocker.py is excluded by !skills/**
  • skills/ci-stage-payload-reverts/SKILL.md is excluded by !skills/**
  • skills/ci-triage-regression/README.md is excluded by !skills/**
  • skills/ci-triage-regression/SKILL.md is excluded by !skills/**
  • skills/ci-triage-regression/triage_regression.py is excluded by !skills/**
  • skills/ci-trigger-payload-job/SKILL.md is excluded by !skills/**
  • skills/code-review-lang-go/SKILL.md is excluded by !skills/**
  • skills/code-review-profile-hypershift/SKILL.md is excluded by !skills/**
  • skills/compliance-call-graph-analysis/SKILL.md is excluded by !skills/**
  • skills/compliance-codebase-impact-analysis/SKILL.md is excluded by !skills/**
  • skills/compliance-cve-intelligence-gathering/SKILL.md is excluded by !skills/**
  • skills/compliance-remediation-planning/SKILL.md is excluded by !skills/**
  • skills/git-suggest-reviewers/SKILL.md is excluded by !skills/**
  • skills/git-suggest-reviewers/analyze_blame.py is excluded by !skills/**
  • skills/golang-lint/SKILL.md is excluded by !skills/**
  • skills/hcp-hcp-create-agent/SKILL.md is excluded by !skills/**
  • skills/hcp-hcp-create-aws/SKILL.md is excluded by !skills/**
  • skills/hcp-hcp-create-azure/SKILL.md is excluded by !skills/**
  • skills/hcp-hcp-create-kubevirt/SKILL.md is excluded by !skills/**
  • skills/hcp-hcp-create-openstack/SKILL.md is excluded by !skills/**
  • skills/hcp-hcp-create-powervs/SKILL.md is excluded by !skills/**
  • skills/jira-categorize-activity-type/SKILL.md is excluded by !skills/**
  • skills/jira-cntrlplane/SKILL.md is excluded by !skills/**
  • skills/jira-create-bug/SKILL.md is excluded by !skills/**
  • skills/jira-create-epic/SKILL.md is excluded by !skills/**
  • skills/jira-create-feature-request/SKILL.md is excluded by !skills/**
  • skills/jira-create-feature/SKILL.md is excluded by !skills/**
  • skills/jira-create-release-note/SKILL.md is excluded by !skills/**
  • skills/jira-create-story/SKILL.md is excluded by !skills/**
  • skills/jira-create-task/SKILL.md is excluded by !skills/**
  • skills/jira-extract-prs/SKILL.md is excluded by !skills/**
  • skills/jira-gcp-hcp/CLAUDE.md is excluded by !skills/**
  • skills/jira-gcp-hcp/SKILL.md is excluded by !skills/**
  • skills/jira-hypershift/SKILL.md is excluded by !skills/**
  • skills/jira-jira-doc-generator/SKILL.md is excluded by !skills/**
  • skills/jira-jira-issues-by-component/README.md is excluded by !skills/**
  • skills/jira-jira-issues-by-component/SKILL.md is excluded by !skills/**
  • skills/jira-jira-issues-by-component/jira_curl.sh is excluded by !skills/**
  • skills/jira-jira-validate-blockers/SKILL.md is excluded by !skills/**
  • skills/jira-ocpbugs/SKILL.md is excluded by !skills/**
  • skills/jira-status-analysis/SKILL.md is excluded by !skills/**
  • skills/jira-status-analysis/activity-analysis.md is excluded by !skills/**
  • skills/jira-status-analysis/data-collection.md is excluded by !skills/**
  • skills/jira-status-analysis/external-links.md is excluded by !skills/**
  • skills/jira-status-analysis/formatting.md is excluded by !skills/**
  • skills/jira-status-analysis/scripts/gather_status_data.py is excluded by !skills/**
  • skills/lvms-lvms-analyzer/SKILL.md is excluded by !skills/**
  • skills/lvms-lvms-analyzer/scripts/analyze_lvms.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/SKILL.md is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_clusteroperators.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_clusterversion.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_etcd.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_events.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_network.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_nodes.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_ovn_dbs.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_pods.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_prometheus.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_pvs.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_windows_logs.py is excluded by !skills/**
  • skills/node-tuning-scripts/SKILL.md is excluded by !skills/**
  • skills/node-tuning-scripts/analyze_node_tuning.py is excluded by !skills/**
  • skills/node-tuning-scripts/generate_tuned_profile.py is excluded by !skills/**
  • skills/olm-team-k8s-ocp-olm-expert/README.md is excluded by !skills/**
  • skills/olm-team-k8s-ocp-olm-expert/SKILL.md is excluded by !skills/**
  • skills/olm-team-k8s-ocp-olm-expert/config-example.json is excluded by !skills/**
  • skills/olm-team-k8s-ocp-olm-expert/config-template.json is excluded by !skills/**
  • skills/openshift-generating-ovn-topology/README.md is excluded by !skills/**
  • skills/openshift-generating-ovn-topology/SKILL.md is excluded by !skills/**
  • skills/openshift-generating-ovn-topology/scripts/analyze_placement.py is excluded by !skills/**
  • skills/openshift-generating-ovn-topology/scripts/check_permissions.py is excluded by !skills/**
  • skills/openshift-generating-ovn-topology/scripts/collect_ovn_data.py is excluded by !skills/**
  • skills/openshift-generating-ovn-topology/scripts/detect-cluster.sh is excluded by !skills/**
  • skills/openshift-generating-ovn-topology/scripts/ovn_utils.py is excluded by !skills/**
  • skills/openshift-openshift-node-kernel/SKILL.md is excluded by !skills/**
  • skills/openshift-openshift-node-kernel/kernel-helper.sh is excluded by !skills/**
  • skills/openshift-openshift-node-kernel/node-kernel-conntrack.sh is excluded by !skills/**
  • skills/openshift-openshift-node-kernel/node-kernel-ip.sh is excluded by !skills/**
  • skills/openshift-openshift-node-kernel/node-kernel-iptables.sh is excluded by !skills/**
  • skills/openshift-openshift-node-kernel/node-kernel-nft.sh is excluded by !skills/**
  • skills/ote-migration-ote-migration-workflow/SKILL.md is excluded by !skills/**
  • skills/sosreport-logs-analysis/SKILL.md is excluded by !skills/**
  • skills/sosreport-network-analysis/SKILL.md is excluded by !skills/**
  • skills/sosreport-ovs-db-analysis/SKILL.md is excluded by !skills/**
  • skills/sosreport-ovs-db-analysis/scripts/analyze_ovs_db.py is excluded by !skills/**
  • skills/sosreport-resource-analysis/SKILL.md is excluded by !skills/**
  • skills/sosreport-system-config-analysis/SKILL.md is excluded by !skills/**
  • skills/teams-analyze-regressions/README.md is excluded by !skills/**
  • skills/teams-analyze-regressions/SKILL.md is excluded by !skills/**
  • skills/teams-analyze-regressions/generate_html_report.py is excluded by !skills/**
  • skills/teams-analyze-regressions/report_template.html is excluded by !skills/**
  • skills/teams-coderabbit-adoption/SKILL.md is excluded by !skills/**
  • skills/teams-coderabbit-adoption/coderabbit_adoption.py is excluded by !skills/**
  • skills/teams-coderabbit-inheritance-scanner-check/SKILL.md is excluded by !skills/**
  • skills/teams-coderabbit-inheritance-scanner-existing-pr/SKILL.md is excluded by !skills/**
  • skills/teams-coderabbit-inheritance-scanner-open-pr/SKILL.md is excluded by !skills/**
  • skills/teams-coderabbit-inheritance-scanner-search/SKILL.md is excluded by !skills/**
  • skills/teams-get-release-dates/README.md is excluded by !skills/**
  • skills/teams-get-release-dates/SKILL.md is excluded by !skills/**
  • skills/teams-get-release-dates/get_release_dates.py is excluded by !skills/**
  • skills/teams-list-components/SKILL.md is excluded by !skills/**
  • skills/teams-list-components/list_components.py is excluded by !skills/**
  • skills/teams-list-jiras/SKILL.md is excluded by !skills/**
  • skills/teams-list-jiras/list_jiras.py is excluded by !skills/**
  • skills/teams-list-regressions/README.md is excluded by !skills/**
  • skills/teams-list-regressions/SKILL.md is excluded by !skills/**
  • skills/teams-list-regressions/list_regressions.py is excluded by !skills/**
  • skills/teams-list-teams/SKILL.md is excluded by !skills/**
  • skills/teams-list-teams/list_teams.py is excluded by !skills/**
📒 Files selected for processing (5)
  • .coderabbit.yaml
  • .github/workflows/verify-gemini-sync.yml
  • Makefile
  • README.md
  • scripts/convert_to_gemini.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/verify-gemini-sync.yml

Comment thread Makefile Outdated
Comment thread README.md Outdated
@zhfeng
zhfeng force-pushed the feat/gemini-extension-conversion branch from 16e1603 to d1cf0c3 Compare March 10, 2026 03:21

@coderabbitai coderabbitai 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.

♻️ Duplicate comments (1)
README.md (1)

71-74: ⚠️ Potential issue | 🟠 Major

Replace the hardcoded remote and label the fenced block.

This example still assumes origin, which is exactly the case the repo’s git-remote safety rules try to avoid, and Line 72 is missing a language identifier. Use a placeholder remote, tell readers to discover it first, and mark the block as bash.

🛠️ Proposed change
-**Use the commands:**
-```
-/jira:solve OCPBUGS-12345 origin
-```
+**Use the commands:**
+```bash
+/jira:solve OCPBUGS-12345 <remote>
+```
+
+Discover the remote name first with `git remote -v` or `git branch -vv`.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 71 - 74, Replace the hardcoded remote in the example
command "/jira:solve OCPBUGS-12345 origin" with a placeholder (e.g. "<remote>"),
add the fenced block language identifier "bash" to the triple-backtick fence,
and include a short note instructing readers to discover their remote name using
commands like "git remote -v" or "git branch -vv" so they know what to
substitute for <remote>; update the README.md example accordingly.
🧹 Nitpick comments (1)
.github/workflows/verify-gemini-sync.yml (1)

26-27: Prefer the Make target as the CI entrypoint.

This duplicates the verification command instead of reusing make verify-gemini-sync, so CI can drift from the documented local path over time.

♻️ Proposed change
-      - name: Verify Gemini extension is in sync
-        run: python3 scripts/convert_to_gemini.py --check
+      - name: Verify Gemini extension is in sync
+        run: make verify-gemini-sync
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/verify-gemini-sync.yml around lines 26 - 27, The CI step
currently runs the verification script directly; replace that run command to
invoke the Make target instead so the pipeline uses the canonical entrypoint
(use the make target verify-gemini-sync rather than calling python3
scripts/convert_to_gemini.py --check). Update the job step that currently has
the run command to call make verify-gemini-sync (ensuring the runner has
required tools for the Make target), so CI and local verification remain in
sync.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@README.md`:
- Around line 71-74: Replace the hardcoded remote in the example command
"/jira:solve OCPBUGS-12345 origin" with a placeholder (e.g. "<remote>"), add the
fenced block language identifier "bash" to the triple-backtick fence, and
include a short note instructing readers to discover their remote name using
commands like "git remote -v" or "git branch -vv" so they know what to
substitute for <remote>; update the README.md example accordingly.

---

Nitpick comments:
In @.github/workflows/verify-gemini-sync.yml:
- Around line 26-27: The CI step currently runs the verification script
directly; replace that run command to invoke the Make target instead so the
pipeline uses the canonical entrypoint (use the make target verify-gemini-sync
rather than calling python3 scripts/convert_to_gemini.py --check). Update the
job step that currently has the run command to call make verify-gemini-sync
(ensuring the runner has required tools for the Make target), so CI and local
verification remain in sync.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a6037064-bee2-4248-a44d-5671d3f9babd

📥 Commits

Reviewing files that changed from the base of the PR and between 16e1603 and d1cf0c3.

⛔ Files ignored due to path filters (295)
  • GEMINI.md is excluded by !GEMINI.md
  • commands/agendas/outcome-refinement.toml is excluded by !commands/**
  • commands/bigquery/analyze-usage.toml is excluded by !commands/**
  • commands/ci/add-debug-wait.toml is excluded by !commands/**
  • commands/ci/analyze-payload.toml is excluded by !commands/**
  • commands/ci/analyze-pr-reverts.toml is excluded by !commands/**
  • commands/ci/analyze-prow-job-install-failure.toml is excluded by !commands/**
  • commands/ci/analyze-prow-job-resource.toml is excluded by !commands/**
  • commands/ci/analyze-prow-job-test-failure.toml is excluded by !commands/**
  • commands/ci/analyze-regression.toml is excluded by !commands/**
  • commands/ci/ask-sippy.toml is excluded by !commands/**
  • commands/ci/check-if-jira-regression-is-ongoing.toml is excluded by !commands/**
  • commands/ci/extract-prow-job-must-gather.toml is excluded by !commands/**
  • commands/ci/fetch-payloads.toml is excluded by !commands/**
  • commands/ci/fetch-test-report.toml is excluded by !commands/**
  • commands/ci/list-step.toml is excluded by !commands/**
  • commands/ci/list-unstable-tests.toml is excluded by !commands/**
  • commands/ci/payload-agent.toml is excluded by !commands/**
  • commands/ci/query-job-status.toml is excluded by !commands/**
  • commands/ci/query-test-result.toml is excluded by !commands/**
  • commands/ci/revert-pr.toml is excluded by !commands/**
  • commands/ci/trigger-periodic.toml is excluded by !commands/**
  • commands/ci/trigger-postsubmit.toml is excluded by !commands/**
  • commands/ci/trigger-presubmit.toml is excluded by !commands/**
  • commands/code-review/pr.toml is excluded by !commands/**
  • commands/code-review/pre-commit-review.toml is excluded by !commands/**
  • commands/compliance/analyze-cve.toml is excluded by !commands/**
  • commands/container-image/compare.toml is excluded by !commands/**
  • commands/container-image/inspect.toml is excluded by !commands/**
  • commands/container-image/tags.toml is excluded by !commands/**
  • commands/doc/note.toml is excluded by !commands/**
  • commands/etcd/analyze-performance.toml is excluded by !commands/**
  • commands/etcd/health-check.toml is excluded by !commands/**
  • commands/git/backport.toml is excluded by !commands/**
  • commands/git/bisect.toml is excluded by !commands/**
  • commands/git/branch-cleanup.toml is excluded by !commands/**
  • commands/git/cherry-pick-by-patch.toml is excluded by !commands/**
  • commands/git/commit-suggest.toml is excluded by !commands/**
  • commands/git/debt-scan.toml is excluded by !commands/**
  • commands/git/fix-cherrypick-robot-pr.toml is excluded by !commands/**
  • commands/git/redescribe.toml is excluded by !commands/**
  • commands/git/suggest-reviewers.toml is excluded by !commands/**
  • commands/git/summary.toml is excluded by !commands/**
  • commands/golang/lint-fix.toml is excluded by !commands/**
  • commands/gwapi/check.toml is excluded by !commands/**
  • commands/gwapi/delete.toml is excluded by !commands/**
  • commands/gwapi/install.toml is excluded by !commands/**
  • commands/hcp/cluster-health-check.toml is excluded by !commands/**
  • commands/hcp/generate.toml is excluded by !commands/**
  • commands/hello-world/echo.toml is excluded by !commands/**
  • commands/jira/backlog.toml is excluded by !commands/**
  • commands/jira/categorize-activity-type.toml is excluded by !commands/**
  • commands/jira/clone-from-github.toml is excluded by !commands/**
  • commands/jira/create-release-note.toml is excluded by !commands/**
  • commands/jira/create.toml is excluded by !commands/**
  • commands/jira/generate-feature-doc.toml is excluded by !commands/**
  • commands/jira/generate-test-plan.toml is excluded by !commands/**
  • commands/jira/grooming.toml is excluded by !commands/**
  • commands/jira/issues-by-component.toml is excluded by !commands/**
  • commands/jira/reconcile-github.toml is excluded by !commands/**
  • commands/jira/setup-gh2jira.toml is excluded by !commands/**
  • commands/jira/solve.toml is excluded by !commands/**
  • commands/jira/status-rollup.toml is excluded by !commands/**
  • commands/jira/update-weekly-status.toml is excluded by !commands/**
  • commands/jira/validate-blockers.toml is excluded by !commands/**
  • commands/lvms/analyze.toml is excluded by !commands/**
  • commands/must-gather/analyze.toml is excluded by !commands/**
  • commands/must-gather/ovn-dbs.toml is excluded by !commands/**
  • commands/must-gather/windows.toml is excluded by !commands/**
  • commands/node-tuning/analyze-node-tuning.toml is excluded by !commands/**
  • commands/node-tuning/generate-tuned-profile.toml is excluded by !commands/**
  • commands/node/cluster-node-health-check.toml is excluded by !commands/**
  • commands/olm-team/configure-agent.toml is excluded by !commands/**
  • commands/olm-team/dev-setup.toml is excluded by !commands/**
  • commands/olm-team/ep-watch.toml is excluded by !commands/**
  • commands/olm/approve.toml is excluded by !commands/**
  • commands/olm/catalog.toml is excluded by !commands/**
  • commands/olm/debug.toml is excluded by !commands/**
  • commands/olm/diagnose.toml is excluded by !commands/**
  • commands/olm/install.toml is excluded by !commands/**
  • commands/olm/list.toml is excluded by !commands/**
  • commands/olm/opm.toml is excluded by !commands/**
  • commands/olm/search.toml is excluded by !commands/**
  • commands/olm/status.toml is excluded by !commands/**
  • commands/olm/uninstall.toml is excluded by !commands/**
  • commands/olm/upgrade.toml is excluded by !commands/**
  • commands/openshift/add-enhancement.toml is excluded by !commands/**
  • commands/openshift/bootstrap-om.toml is excluded by !commands/**
  • commands/openshift/bump-deps.toml is excluded by !commands/**
  • commands/openshift/cluster-health-check.toml is excluded by !commands/**
  • commands/openshift/crd-review.toml is excluded by !commands/**
  • commands/openshift/create-cluster.toml is excluded by !commands/**
  • commands/openshift/destroy-cluster.toml is excluded by !commands/**
  • commands/openshift/expand-test-case.toml is excluded by !commands/**
  • commands/openshift/ironic-status.toml is excluded by !commands/**
  • commands/openshift/new-e2e-test.toml is excluded by !commands/**
  • commands/openshift/node-kernel-conntrack.toml is excluded by !commands/**
  • commands/openshift/node-kernel-ip.toml is excluded by !commands/**
  • commands/openshift/node-kernel-iptables.toml is excluded by !commands/**
  • commands/openshift/node-kernel-nft.toml is excluded by !commands/**
  • commands/openshift/rebase.toml is excluded by !commands/**
  • commands/openshift/review-test-cases.toml is excluded by !commands/**
  • commands/openshift/visualize-ovn-topology.toml is excluded by !commands/**
  • commands/origin/two-node-origin-pr-helper.toml is excluded by !commands/**
  • commands/ote-migration/migrate.toml is excluded by !commands/**
  • commands/session/save-session.toml is excluded by !commands/**
  • commands/sosreport/analyze.toml is excluded by !commands/**
  • commands/sosreport/ovs-db.toml is excluded by !commands/**
  • commands/teams/coderabbit-adoption-report.toml is excluded by !commands/**
  • commands/teams/coderabbit-inheritance-scanner.toml is excluded by !commands/**
  • commands/teams/health-check-jiras.toml is excluded by !commands/**
  • commands/teams/health-check-regressions.toml is excluded by !commands/**
  • commands/teams/health-check.toml is excluded by !commands/**
  • commands/teams/list-components.toml is excluded by !commands/**
  • commands/teams/list-jiras.toml is excluded by !commands/**
  • commands/teams/list-regressions.toml is excluded by !commands/**
  • commands/teams/list-teams.toml is excluded by !commands/**
  • commands/test-coverage/analyze.toml is excluded by !commands/**
  • commands/test-coverage/gaps.toml is excluded by !commands/**
  • commands/testing/mutation-test.toml is excluded by !commands/**
  • commands/utils/address-reviews.toml is excluded by !commands/**
  • commands/utils/auto-approve-konflux-prs.toml is excluded by !commands/**
  • commands/utils/generate-test-plan.toml is excluded by !commands/**
  • commands/utils/gh-attention.toml is excluded by !commands/**
  • commands/utils/placeholder.toml is excluded by !commands/**
  • commands/utils/process-renovate-pr.toml is excluded by !commands/**
  • commands/utils/review-ai-helpers-overlap.toml is excluded by !commands/**
  • commands/utils/review-security.toml is excluded by !commands/**
  • commands/workspaces/create.toml is excluded by !commands/**
  • commands/workspaces/delete.toml is excluded by !commands/**
  • commands/yaml/docs.toml is excluded by !commands/**
  • gemini-extension.json is excluded by !gemini-extension.json
  • skills/bigquery-analyze-usage/SKILL.md is excluded by !skills/**
  • skills/ci-analyze-payload/SKILL.md is excluded by !skills/**
  • skills/ci-bisect-payload-suspects/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-jira-issue/README.md is excluded by !skills/**
  • skills/ci-fetch-jira-issue/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-jira-issue/fetch_jira_issue.py is excluded by !skills/**
  • skills/ci-fetch-new-prs-in-payload/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-new-prs-in-payload/fetch_new_prs_in_payload.py is excluded by !skills/**
  • skills/ci-fetch-payloads/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-payloads/fetch_payloads.py is excluded by !skills/**
  • skills/ci-fetch-prowjob-json/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-regression-details/README.md is excluded by !skills/**
  • skills/ci-fetch-regression-details/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-regression-details/fetch_regression_details.py is excluded by !skills/**
  • skills/ci-fetch-related-triages/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-related-triages/fetch_related_triages.py is excluded by !skills/**
  • skills/ci-fetch-releases/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-releases/fetch_releases.py is excluded by !skills/**
  • skills/ci-fetch-test-report/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-test-report/fetch_test_report.py is excluded by !skills/**
  • skills/ci-fetch-test-runs/README.md is excluded by !skills/**
  • skills/ci-fetch-test-runs/SKILL.md is excluded by !skills/**
  • skills/ci-fetch-test-runs/fetch_test_runs.py is excluded by !skills/**
  • skills/ci-oc-auth/README.md is excluded by !skills/**
  • skills/ci-oc-auth/SKILL.md is excluded by !skills/**
  • skills/ci-oc-auth/curl_with_token.sh is excluded by !skills/**
  • skills/ci-payload-agent/SKILL.md is excluded by !skills/**
  • skills/ci-prow-job-analyze-install-failure/SKILL.md is excluded by !skills/**
  • skills/ci-prow-job-analyze-metal-install-failure/SKILL.md is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/CHANGELOG.md is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/README.md is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/SCRIPTS.md is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/SKILL.md is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/create_context_html_files.py is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/create_inline_html_files.py is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/generate_html_report.py is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/generate_report.py is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/parse_all_logs.py is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/parse_audit_logs.py is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/parse_pod_logs.py is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/parse_url.py is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/prow_job_resource_grep.sh is excluded by !skills/**
  • skills/ci-prow-job-analyze-resource/report_template.html is excluded by !skills/**
  • skills/ci-prow-job-analyze-test-failure/README.md is excluded by !skills/**
  • skills/ci-prow-job-analyze-test-failure/SKILL.md is excluded by !skills/**
  • skills/ci-prow-job-artifact-search/SKILL.md is excluded by !skills/**
  • skills/ci-prow-job-artifact-search/prow_job_artifact_search.py is excluded by !skills/**
  • skills/ci-prow-job-extract-must-gather/CHANGELOG.md is excluded by !skills/**
  • skills/ci-prow-job-extract-must-gather/README.md is excluded by !skills/**
  • skills/ci-prow-job-extract-must-gather/SKILL.md is excluded by !skills/**
  • skills/ci-prow-job-extract-must-gather/extract_archives.py is excluded by !skills/**
  • skills/ci-prow-job-extract-must-gather/generate_html_report.py is excluded by !skills/**
  • skills/ci-revert-pr/SKILL.md is excluded by !skills/**
  • skills/ci-set-release-blocker/SKILL.md is excluded by !skills/**
  • skills/ci-set-release-blocker/set_release_blocker.py is excluded by !skills/**
  • skills/ci-stage-payload-reverts/SKILL.md is excluded by !skills/**
  • skills/ci-triage-regression/README.md is excluded by !skills/**
  • skills/ci-triage-regression/SKILL.md is excluded by !skills/**
  • skills/ci-triage-regression/triage_regression.py is excluded by !skills/**
  • skills/ci-trigger-payload-job/SKILL.md is excluded by !skills/**
  • skills/code-review-lang-go/SKILL.md is excluded by !skills/**
  • skills/code-review-profile-hypershift/SKILL.md is excluded by !skills/**
  • skills/compliance-call-graph-analysis/SKILL.md is excluded by !skills/**
  • skills/compliance-codebase-impact-analysis/SKILL.md is excluded by !skills/**
  • skills/compliance-cve-intelligence-gathering/SKILL.md is excluded by !skills/**
  • skills/compliance-remediation-planning/SKILL.md is excluded by !skills/**
  • skills/git-suggest-reviewers/SKILL.md is excluded by !skills/**
  • skills/git-suggest-reviewers/analyze_blame.py is excluded by !skills/**
  • skills/golang-lint/SKILL.md is excluded by !skills/**
  • skills/hcp-hcp-create-agent/SKILL.md is excluded by !skills/**
  • skills/hcp-hcp-create-aws/SKILL.md is excluded by !skills/**
  • skills/hcp-hcp-create-azure/SKILL.md is excluded by !skills/**
  • skills/hcp-hcp-create-kubevirt/SKILL.md is excluded by !skills/**
  • skills/hcp-hcp-create-openstack/SKILL.md is excluded by !skills/**
  • skills/hcp-hcp-create-powervs/SKILL.md is excluded by !skills/**
  • skills/jira-categorize-activity-type/SKILL.md is excluded by !skills/**
  • skills/jira-cntrlplane/SKILL.md is excluded by !skills/**
  • skills/jira-create-bug/SKILL.md is excluded by !skills/**
  • skills/jira-create-epic/SKILL.md is excluded by !skills/**
  • skills/jira-create-feature-request/SKILL.md is excluded by !skills/**
  • skills/jira-create-feature/SKILL.md is excluded by !skills/**
  • skills/jira-create-release-note/SKILL.md is excluded by !skills/**
  • skills/jira-create-story/SKILL.md is excluded by !skills/**
  • skills/jira-create-task/SKILL.md is excluded by !skills/**
  • skills/jira-extract-prs/SKILL.md is excluded by !skills/**
  • skills/jira-gcp-hcp/CLAUDE.md is excluded by !skills/**
  • skills/jira-gcp-hcp/SKILL.md is excluded by !skills/**
  • skills/jira-hypershift/SKILL.md is excluded by !skills/**
  • skills/jira-jira-doc-generator/SKILL.md is excluded by !skills/**
  • skills/jira-jira-issues-by-component/README.md is excluded by !skills/**
  • skills/jira-jira-issues-by-component/SKILL.md is excluded by !skills/**
  • skills/jira-jira-issues-by-component/jira_curl.sh is excluded by !skills/**
  • skills/jira-jira-validate-blockers/SKILL.md is excluded by !skills/**
  • skills/jira-ocpbugs/SKILL.md is excluded by !skills/**
  • skills/jira-status-analysis/SKILL.md is excluded by !skills/**
  • skills/jira-status-analysis/activity-analysis.md is excluded by !skills/**
  • skills/jira-status-analysis/data-collection.md is excluded by !skills/**
  • skills/jira-status-analysis/external-links.md is excluded by !skills/**
  • skills/jira-status-analysis/formatting.md is excluded by !skills/**
  • skills/jira-status-analysis/scripts/gather_status_data.py is excluded by !skills/**
  • skills/lvms-lvms-analyzer/SKILL.md is excluded by !skills/**
  • skills/lvms-lvms-analyzer/scripts/analyze_lvms.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/SKILL.md is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_clusteroperators.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_clusterversion.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_etcd.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_events.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_network.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_nodes.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_ovn_dbs.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_pods.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_prometheus.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_pvs.py is excluded by !skills/**
  • skills/must-gather-must-gather-analyzer/scripts/analyze_windows_logs.py is excluded by !skills/**
  • skills/node-tuning-scripts/SKILL.md is excluded by !skills/**
  • skills/node-tuning-scripts/analyze_node_tuning.py is excluded by !skills/**
  • skills/node-tuning-scripts/generate_tuned_profile.py is excluded by !skills/**
  • skills/olm-team-k8s-ocp-olm-expert/README.md is excluded by !skills/**
  • skills/olm-team-k8s-ocp-olm-expert/SKILL.md is excluded by !skills/**
  • skills/olm-team-k8s-ocp-olm-expert/config-example.json is excluded by !skills/**
  • skills/olm-team-k8s-ocp-olm-expert/config-template.json is excluded by !skills/**
  • skills/openshift-generating-ovn-topology/README.md is excluded by !skills/**
  • skills/openshift-generating-ovn-topology/SKILL.md is excluded by !skills/**
  • skills/openshift-generating-ovn-topology/scripts/analyze_placement.py is excluded by !skills/**
  • skills/openshift-generating-ovn-topology/scripts/check_permissions.py is excluded by !skills/**
  • skills/openshift-generating-ovn-topology/scripts/collect_ovn_data.py is excluded by !skills/**
  • skills/openshift-generating-ovn-topology/scripts/detect-cluster.sh is excluded by !skills/**
  • skills/openshift-generating-ovn-topology/scripts/ovn_utils.py is excluded by !skills/**
  • skills/openshift-openshift-node-kernel/SKILL.md is excluded by !skills/**
  • skills/openshift-openshift-node-kernel/kernel-helper.sh is excluded by !skills/**
  • skills/openshift-openshift-node-kernel/node-kernel-conntrack.sh is excluded by !skills/**
  • skills/openshift-openshift-node-kernel/node-kernel-ip.sh is excluded by !skills/**
  • skills/openshift-openshift-node-kernel/node-kernel-iptables.sh is excluded by !skills/**
  • skills/openshift-openshift-node-kernel/node-kernel-nft.sh is excluded by !skills/**
  • skills/ote-migration-ote-migration-workflow/SKILL.md is excluded by !skills/**
  • skills/sosreport-logs-analysis/SKILL.md is excluded by !skills/**
  • skills/sosreport-network-analysis/SKILL.md is excluded by !skills/**
  • skills/sosreport-ovs-db-analysis/SKILL.md is excluded by !skills/**
  • skills/sosreport-ovs-db-analysis/scripts/analyze_ovs_db.py is excluded by !skills/**
  • skills/sosreport-resource-analysis/SKILL.md is excluded by !skills/**
  • skills/sosreport-system-config-analysis/SKILL.md is excluded by !skills/**
  • skills/teams-analyze-regressions/README.md is excluded by !skills/**
  • skills/teams-analyze-regressions/SKILL.md is excluded by !skills/**
  • skills/teams-analyze-regressions/generate_html_report.py is excluded by !skills/**
  • skills/teams-analyze-regressions/report_template.html is excluded by !skills/**
  • skills/teams-coderabbit-adoption/SKILL.md is excluded by !skills/**
  • skills/teams-coderabbit-adoption/coderabbit_adoption.py is excluded by !skills/**
  • skills/teams-coderabbit-inheritance-scanner-check/SKILL.md is excluded by !skills/**
  • skills/teams-coderabbit-inheritance-scanner-existing-pr/SKILL.md is excluded by !skills/**
  • skills/teams-coderabbit-inheritance-scanner-open-pr/SKILL.md is excluded by !skills/**
  • skills/teams-coderabbit-inheritance-scanner-search/SKILL.md is excluded by !skills/**
  • skills/teams-get-release-dates/README.md is excluded by !skills/**
  • skills/teams-get-release-dates/SKILL.md is excluded by !skills/**
  • skills/teams-get-release-dates/get_release_dates.py is excluded by !skills/**
  • skills/teams-list-components/SKILL.md is excluded by !skills/**
  • skills/teams-list-components/list_components.py is excluded by !skills/**
  • skills/teams-list-jiras/SKILL.md is excluded by !skills/**
  • skills/teams-list-jiras/list_jiras.py is excluded by !skills/**
  • skills/teams-list-regressions/README.md is excluded by !skills/**
  • skills/teams-list-regressions/SKILL.md is excluded by !skills/**
  • skills/teams-list-regressions/list_regressions.py is excluded by !skills/**
  • skills/teams-list-teams/SKILL.md is excluded by !skills/**
  • skills/teams-list-teams/list_teams.py is excluded by !skills/**
📒 Files selected for processing (5)
  • .coderabbit.yaml
  • .github/workflows/verify-gemini-sync.yml
  • Makefile
  • README.md
  • scripts/convert_to_gemini.py

@wangke19

Copy link
Copy Markdown
Contributor

My previous approach was to submit one or several small plugins as a PR, which was conducive to review and maintenance. See https://github.com/wangke19/gemini-ai-helpers/commits/main/

@zhfeng
zhfeng force-pushed the feat/gemini-extension-conversion branch from d1cf0c3 to af9ef7e Compare March 10, 2026 06:56
@zhfeng

zhfeng commented Mar 10, 2026

Copy link
Copy Markdown
Contributor Author

Thanksk @wangke19 - now I removed all the generated gemini files and let's try to do the migration in more small steps.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

♻️ Duplicate comments (1)
README.md (1)

72-74: ⚠️ Potential issue | 🟡 Minor

Add language specifier to fenced code block and avoid hardcoded remote name.

The code block at line 72 is missing a language specifier. Additionally, hardcoding origin has been flagged in a previous review - this applies equally to the Gemini CLI example.

📝 Proposed fix
 **Use the commands:**
-```
-/jira:solve OCPBUGS-12345 origin
+```bash
+/jira:solve OCPBUGS-12345 <remote>

+Discover the remote name with git remote -v.

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @README.md around lines 72 - 74, Update the fenced code block containing the
example command "/jira:solve OCPBUGS-12345 origin" to include a bash language
specifier and remove the hardcoded remote name; replace the trailing "origin"
with a placeholder like "" and mirror this change in the Gemini CLI
example so both examples use the placeholder instead of a fixed remote; add a
short note suggesting users discover their remote name with "git remote -v".


</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🧹 Nitpick comments (3)</summary><blockquote>

<details>
<summary>scripts/convert_to_gemini.py (3)</summary><blockquote>

`614-615`: **Inconsistent temp directory cleanup handling.**

Line 615 uses `shutil.rmtree(temp_dir)` without `ignore_errors`, while line 645 uses `ignore_errors=True`. If cleanup fails in `--check` mode, the script will crash after completing its work. Consider using `ignore_errors=True` consistently for both.



<details>
<summary>♻️ Proposed fix</summary>

```diff
         finally:
-            shutil.rmtree(temp_dir)
+            shutil.rmtree(temp_dir, ignore_errors=True)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/convert_to_gemini.py` around lines 614 - 615, The finally block
currently calls shutil.rmtree(temp_dir) which can raise on failure and crash the
script in --check mode; change that call inside the finally to
shutil.rmtree(temp_dir, ignore_errors=True) to match the other cleanup at line
645 and ensure consistent, non-fatal temp directory cleanup for the function
handling the conversion (referencing the temp_dir variable used in that
try/finally).

100-105: Use raise ... from exc for proper exception chaining.

Per static analysis (B904), re-raising with from exc preserves the original traceback and distinguishes the new exception from errors in exception handling.

♻️ Proposed fix
     try:
         tomllib.loads(toml_content)
     except Exception as exc:
-        raise ValueError(
+        raise ValueError(
             f"Generated invalid TOML for {plugin_name}/{os.path.basename(md_path)}: {exc}"
-        )
+        ) from exc
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/convert_to_gemini.py` around lines 100 - 105, In the except block
that catches Exception as exc around tomllib.loads(toml_content), re-raise the
ValueError using exception chaining so the original traceback is preserved:
replace the current raise ValueError(...) with raise ValueError(f"Generated
invalid TOML for {plugin_name}/{os.path.basename(md_path)}: {exc}") from exc
(i.e., add "from exc" to the raise in the except handling of tomllib.loads).

636-636: Remove extraneous f prefix from string literal.

The f-string has no placeholders.

♻️ Proposed fix
-                print(f"Changed plugins:")
+                print("Changed plugins:")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/convert_to_gemini.py` at line 636, The print statement uses an
unnecessary f-string: replace the call print(f"Changed plugins:") with a normal
string literal (print("Changed plugins:")) to remove the extraneous `f` prefix;
locate the print(f"Changed plugins:") occurrence in convert_to_gemini.py and
update it accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/convert_to_gemini.py`:
- Around line 333-334: The file comparison uses open(new_path).read() and
open(existing_path).read() which leaves file descriptors open; change these to
use context managers (with open(new_path, "r", encoding="utf-8") as f: data_new
= f.read()) and similarly for existing_path, then compare the strings (e.g.,
data_new != data_existing); apply the same context-manager fix for the other
occurrences referenced (the comparisons using open() at the other locations) to
ensure all file handles are properly closed and use explicit encodings.
- Line 96: The current line building the TOML prompt uses lines.append(f"prompt
= '''\n{body}'''") which will produce invalid TOML if body contains '''; update
the logic in scripts/convert_to_gemini.py to detect whether body contains triple
single quotes and, if so, either switch to a triple-double-quoted TOML multiline
string (e.g. use """...""" surrounding the body) or escape occurrences of '''
inside body (replace "'''" with "\\'\\'\\'") before appending; change the code
path that writes the prompt (the lines.append call referencing body) to choose
the safe quoting/escaping strategy based on the presence of '''.

---

Duplicate comments:
In `@README.md`:
- Around line 72-74: Update the fenced code block containing the example command
"/jira:solve OCPBUGS-12345 origin" to include a bash language specifier and
remove the hardcoded remote name; replace the trailing "origin" with a
placeholder like "<remote>" and mirror this change in the Gemini CLI example so
both examples use the placeholder instead of a fixed remote; add a short note
suggesting users discover their remote name with "git remote -v".

---

Nitpick comments:
In `@scripts/convert_to_gemini.py`:
- Around line 614-615: The finally block currently calls shutil.rmtree(temp_dir)
which can raise on failure and crash the script in --check mode; change that
call inside the finally to shutil.rmtree(temp_dir, ignore_errors=True) to match
the other cleanup at line 645 and ensure consistent, non-fatal temp directory
cleanup for the function handling the conversion (referencing the temp_dir
variable used in that try/finally).
- Around line 100-105: In the except block that catches Exception as exc around
tomllib.loads(toml_content), re-raise the ValueError using exception chaining so
the original traceback is preserved: replace the current raise ValueError(...)
with raise ValueError(f"Generated invalid TOML for
{plugin_name}/{os.path.basename(md_path)}: {exc}") from exc (i.e., add "from
exc" to the raise in the except handling of tomllib.loads).
- Line 636: The print statement uses an unnecessary f-string: replace the call
print(f"Changed plugins:") with a normal string literal (print("Changed
plugins:")) to remove the extraneous `f` prefix; locate the print(f"Changed
plugins:") occurrence in convert_to_gemini.py and update it accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6e002d16-c1bd-4455-8214-b43dcc27d06a

📥 Commits

Reviewing files that changed from the base of the PR and between d1cf0c3 and af9ef7e.

📒 Files selected for processing (4)
  • .coderabbit.yaml
  • Makefile
  • README.md
  • scripts/convert_to_gemini.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • .coderabbit.yaml

Comment thread scripts/convert_to_gemini.py Outdated
if description:
escaped_desc = description.replace("\\", "\\\\").replace('"', '\\"')
lines.append(f'description = "{escaped_desc}"')
lines.append(f"prompt = '''\n{body}'''")

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.

⚠️ Potential issue | 🟡 Minor

Triple single quotes in prompt body could break TOML parsing.

If a command's markdown body contains ''', the generated TOML will be invalid. Consider escaping or using a different quoting strategy.

🛡️ Proposed fix to handle edge case
-    lines.append(f"prompt = '''\n{body}'''")
+    # Escape any ''' sequences in body to prevent TOML breakage
+    escaped_body = body.replace("'''", "'''\"'''\"'''")
+    lines.append(f"prompt = '''\n{escaped_body}'''")

Alternatively, check if ''' exists and use double-quoted multiline string with proper escaping instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/convert_to_gemini.py` at line 96, The current line building the TOML
prompt uses lines.append(f"prompt = '''\n{body}'''") which will produce invalid
TOML if body contains '''; update the logic in scripts/convert_to_gemini.py to
detect whether body contains triple single quotes and, if so, either switch to a
triple-double-quoted TOML multiline string (e.g. use """...""" surrounding the
body) or escape occurrences of ''' inside body (replace "'''" with "\\'\\'\\'")
before appending; change the code path that writes the prompt (the lines.append
call referencing body) to choose the safe quoting/escaping strategy based on the
presence of '''.

Comment on lines +333 to +334
if open(new_path).read() != open(existing_path).read():
return True

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.

⚠️ Potential issue | 🟡 Minor

File handles not properly closed - potential resource leak.

Using open() without a context manager leaves file handles open until garbage collection. This pattern repeats at lines 390 and 404.

🛡️ Proposed fix
-            if open(new_path).read() != open(existing_path).read():
+            with open(new_path) as f1, open(existing_path) as f2:
+                if f1.read() != f2.read():

Apply similar fixes at lines 390 and 404.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if open(new_path).read() != open(existing_path).read():
return True
with open(new_path) as f1, open(existing_path) as f2:
if f1.read() != f2.read():
return True
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/convert_to_gemini.py` around lines 333 - 334, The file comparison
uses open(new_path).read() and open(existing_path).read() which leaves file
descriptors open; change these to use context managers (with open(new_path, "r",
encoding="utf-8") as f: data_new = f.read()) and similarly for existing_path,
then compare the strings (e.g., data_new != data_existing); apply the same
context-manager fix for the other occurrences referenced (the comparisons using
open() at the other locations) to ensure all file handles are properly closed
and use explicit encodings.

@zhfeng

zhfeng commented Mar 10, 2026

Copy link
Copy Markdown
Contributor Author

@wangke19 @stbenjam may I ask you to take a review as well?

@wangke19

Copy link
Copy Markdown
Contributor

Code Review

Overview

This PR adds a Python script (scripts/convert_to_gemini.py) that auto-converts Claude Code plugins into Gemini CLI extensions. It reads plugin commands/*.md and skills/ from plugins/, converts them to TOML format, and writes them to the repo root. A make convert-to-gemini target is added, and the .coderabbit.yaml is updated to exclude generated files from review.


✅ Strengths

  • Good idempotency design: Changes are detected via filecmp, and the version is only bumped when content actually changes.
  • Safe write pattern: Content is generated to a tempfile first, then synced — avoids partial writes.
  • TOML validation: All generated TOML files are validated immediately after generation.
  • Incremental support: --plugin <name> allows testing a single plugin in isolation.
  • --check mode: Useful for CI gating.
  • Quote escaping: Descriptions with embedded quotes are properly escaped in TOML.

🔴 Issues

1. No Example of Generated Output in PR

There's no commands/, GEMINI.md, or gemini-extension.json in the diff for reviewers to validate. It's hard to trust correctness without seeing the output, especially for the TOML format, "Claude""Gemini" substitution, and command namespacing.

Suggestion: Run make convert-to-gemini and commit the generated files, or at minimum add sample output to the PR description. Without this, reviewers cannot verify the Gemini CLI can actually load these extensions.


2. .coderabbit.yaml path_filters Placement

The path_filters block is placed between collapse_walkthrough and auto_review. The filter !commands/** and !skills/** would also exclude plugin source files if they ever appear at root level.

Suggestion: Confirm path_filters placement is correct per CodeRabbit's spec.


3. REPLACEMENTS Is an Incomplete Heuristic

REPLACEMENTS = [
    ("Claude agent text", "Gemini agent text"),
    ("Claude Code plugin", "Gemini CLI extension"),
    ("Claude Code", "Gemini CLI"),
    ("Claude plugin", "Gemini extension"),
]
  • "Claude" alone is not replaced, so references like "Use Claude to analyze..." in command bodies pass through unchanged.
  • The phrase "Claude agent text" seems like a placeholder artifact — it doesn't match anything real.

Suggestion: Either replace "Claude" generically (with care for false positives), or document explicitly that partial replacement is intentional.


4. generate_context_file — Incomplete Plugin List in convert_single_plugin

When using --plugin, GEMINI.md is generated from the commands/ directory at root (only already-converted plugins), not the full plugins/ list. This means GEMINI.md content differs between incremental and full runs.

Suggestion: Clarify in documentation that this is intentional ("accumulates incrementally"), and that make convert-to-gemini produces the canonical GEMINI.md.


5. copy_skills Doesn't Adapt Text

def copy_skills(plugin_name, plugin_dir, output_dir):
    ...
    shutil.copytree(skill_src, skill_dst)

Skills are copied verbatim without adapt_text() substitution. If skills contain "Claude Code" references in their SKILL.md, those will appear in the Gemini extension unchanged.

Suggestion: Apply adapt_text() to SKILL.md files during copy, or document that skills are intentionally passed through unmodified.


6. parse_md_frontmatter — Fragile YAML Parsing

for line in parts[1].strip().split("\n"):
    if ":" in line:
        key, val = line.split(":", 1)

This custom YAML parser will break on values with colons (e.g., description: "Fix: handle errors"), multi-line values, or nested YAML structures. The description field in many command files likely contains colons.

Suggestion: Use PyYAML (import yaml; yaml.safe_load(parts[1])) for robust frontmatter parsing.


7. tomllib / tomli Import — Undeclared Dependency

try:
    import tomllib
except ImportError:
    import tomli as tomllib

tomllib is stdlib in Python 3.11+, but tomli is not. There's no requirements.txt to declare this dependency.

Suggestion: Add a scripts/requirements.txt or note in README.md that Python 3.11+ is required (or tomli must be installed for older versions).


8. Code Duplication Between convert_single_plugin and get_changed_plugins

The skill-change-detection logic in convert_single_plugin is essentially duplicated from get_changed_plugins. Bugs in one place won't be caught in the other.

Suggestion: Extract the skill comparison logic into a shared helper (e.g., _skills_changed(plugin_name, new_dir)) and call it from both functions.


🟡 Minor Issues

  • No --dry-run mode: Would be useful for CI/CD previewing.
  • print(f"Changed plugins:"): f-string with no interpolation — linter warning.
  • File handles not explicitly closed: Uses open(...).read() without context managers in has_content_changes and report_content_diffs.
  • No error handling for malformed plugin.json: A broken plugin will abort the entire conversion with an unhelpful traceback.
  • --check mode doesn't validate the manifest version — only content. A manually edited version won't be caught.

📋 Summary

Category Assessment
Correctness Mostly correct, but fragile YAML parsing could silently mangle frontmatter
Code quality Good structure; significant duplication between convert_single_plugin and get_changed_plugins
Conventions Follows existing script style; tomli dependency not declared
Test coverage ⚠️ No generated output committed — cannot verify end-to-end correctness
Security Low risk (read-only from plugins, write to repo root)

The most important gap is #1: without committed generated output (or at least a sample), it's impossible to verify the extension actually loads in Gemini CLI. Running make convert-to-gemini and committing the result should be a prerequisite for merge.

@zhfeng
zhfeng force-pushed the feat/gemini-extension-conversion branch from af9ef7e to a4a0aec Compare March 11, 2026 04:23
@zhfeng

zhfeng commented Mar 11, 2026

Copy link
Copy Markdown
Contributor Author

@wangke19 I address the major issues of #3 and #5 and #8

  • Expanded REPLACEMENTS to handle URLs, config paths, filenames, and lowercase references
  • ${CLAUDE_PLUGIN_ROOT} → ${extensionPath} with correct skill path rewriting
  • Skills now use skills/{plugin}/{skill}/ structure to preserve paths
  • adapt_text() applied to skill .md files and command descriptions
  • Autogenerated comment no longer mentions "claude"

And I run the convert-to-gemini.py with all the plugins, and manually check there is no any claude word in the generted commands and skills files.

I think other ones could be improved later if needed. WDYT?

@wangke19

wangke19 commented Mar 11, 2026

Copy link
Copy Markdown
Contributor

Here is a focused review of potential issues and architectural "hallucinations" to watch out for.

  1. The "Recursive Replacement" Trap
    The REPLACEMENTS list is a series of str.replace() calls. This is a common AI pattern that is "brittle."

The Issue: Because the script iterates through the list and performs replacements on the same string, an earlier replacement could create a pattern that a later replacement accidentally triggers.

Example: If you had a replacement ("Claude", "Gemini") and later ("Gemini-Extension", "New-Format"), a string that was originally "Claude-Extension" would be turned into "Gemini-Extension" and then transformed again.

Fix: Use a single-pass regular expression with a mapping dictionary to ensure each segment of text is only replaced once.

  1. Manual Frontmatter Parsing
    The parse_md_frontmatter function assumes a very specific, simple YAML structure:
Python
for line in parts[1].strip().split("\n"):
    if ":" in line:
        key, val = line.split(":", 1)

The Risk: This will break if a value contains a colon (e.g., summary: "Task: Fix Bug") or if the frontmatter uses multi-line strings or comments.

Claude Code Bias: Claude tends to write "good enough" parsers for standard cases but ignores the full YAML spec. If your plugins have complex metadata, this script will lose data.

  1. TOML Escaping Logic
    In convert_command_to_toml, the script manually escapes double quotes:

Python
escaped_desc = description.replace("\", "\\").replace('"', '\"')
lines.append(f'description = "{escaped_desc}"')
The Problem: It doesn't handle newlines or control characters in the description. If a description has a newline, the generated TOML will be invalid because a single-quoted string " in TOML cannot span multiple lines.

The Fix: Use the same triple-single-quote ''' syntax for the description field as used for the prompt field.

  1. File System Race Conditions
    The sync_to_root function deletes and then copies:

Python

if os.path.isdir(dst):
    shutil.rmtree(dst)
# ... then copy ...

The Risk: If the script is interrupted (or a disk error occurs) between the rmtree and the copytree, you lose your existing commands/skills entirely.

The Fix: Use an "atomic" approach: copy to a .tmp folder next to the destination, then use os.replace() to swap them instantly.

  1. Logical Inconsistency in Versions
    In convert_single_plugin, the script bumps the Extension version even if only one Plugin was updated.

The Observation: This means the global extension version could jump from 1.0.1 to 1.0.2 just by running the script on a single plugin, even if the other 10 plugins stayed the same. This is generally fine, but ensure the gemini-extension.json is intended to be a "Monorepo" version for all tools combined.

@wangke19

Copy link
Copy Markdown
Contributor

Review of convert-to-gemini Target

  1. Dependency Management
    The convert-to-gemini target currently runs blindly. If the Python script requires external libraries (like tomli for Python < 3.11), the make command will fail with a traceback that might be confusing to some users.

Suggestion: Add a check for requirements or a note in the help text if a virtual environment is expected.

  1. Redundancy with update
    You have an update target that handles documentation and marketplace syncing.

Observation: If the Gemini extension is intended to be a first-class citizen in this repo, you should consider whether make update should automatically trigger make convert-to-gemini. Otherwise, a developer might update a Claude plugin, run make update, and forget to regenerate the Gemini version, leading to out-of-sync files in a PR.

  1. Execution Safety
    The current target:
Makefile
convert-to-gemini: ## Convert Claude plugins to Gemini CLI extensions
	@echo "Converting plugins to Gemini extensions..."
	@python3 scripts/convert_to_gemini.py

Risk: If scripts/convert_to_gemini.py fails (e.g., due to a TOML validation error inside the script), make will technically report a failure, but since it's the last command, it's fine. However, it's good practice to ensure the script's exit codes are respected (which @ does, but double-check your script exits with sys.exit(1) on errors).

Suggested Improvements
A. Linking to the Linting/Syncing Workflow
I recommend adding the Gemini conversion to a "pre-commit" style check or linking it to update. If the Gemini extension files are checked into the repo, they must stay in sync.

Makefile
.PHONY: check-gemini-sync
check-gemini-sync: ## Check if Gemini extensions are out of sync
	@python3 scripts/convert_to_gemini.py --check

B. Enhancing the Help Text
Since this is a conversion/migration tool, it's helpful to indicate that it's an automated generation step.

Makefile
convert-to-gemini: ## Regenerate Gemini CLI extensions from Claude plugins (auto-bumps version)
	@python3 scripts/convert_to_gemini.py

@zhfeng
zhfeng force-pushed the feat/gemini-extension-conversion branch from a4a0aec to 20553dd Compare March 11, 2026 16:27
@zhfeng

zhfeng commented Mar 11, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @wangke19 - now I remove all other changes and let's focus on the convert script now. All of the issues have been addressed.

@wangke19

wangke19 commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

The script looks good to me.
Suggestion test:
Plan

  1. Run conversion on one simple plugin (e.g. hello-world)
  2. Install the generated Gemini extension locally
  3. Test it in Gemini CLI (e.g. run /hello-world:echo)
  4. If it works → approve/merge PR feat: auto-generate Gemini CLI extension from Claude plugins #369

Step-by-step

Step 1: install deps & convert hello-world

pip3 install pyyaml tomli
python3 scripts/convert_to_gemini.py --plugin hello-world

Step 2: install the generated extension into Gemini CLI

Gemini CLI looks for extensions in ~/.gemini/extensions/

mkdir -p ~/.gemini/extensions/ai-helpers
cp gemini-extension.json ~/.gemini/extensions/ai-helpers/
cp GEMINI.md ~/.gemini/extensions/ai-helpers/
cp -r commands ~/.gemini/extensions/ai-helpers/
cp -r skills ~/.gemini/extensions/ai-helpers/

Step 3: launch Gemini CLI and test

gemini

then type: /hello-world:echo

What to verify

  • The /hello-world:echo command is recognized by Gemini CLI
  • It responds correctly (echoes back)
  • No "Claude" references leak into the output (should all say "Gemini")

@stbenjam

Copy link
Copy Markdown
Member

/approve

Feel free to lgtm when its ready. Looks reasonable to me. Does it make one extension with all plugins? I could see that causing issues with context but we can see how it goes

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Mar 12, 2026
Add convert_to_gemini.py that converts Claude Code plugins into a
Gemini CLI extension. Supports full conversion, single-plugin mode
(--plugin), and sync checking (--check).

Key features:
- Single-pass regex for Claude->Gemini text replacement
- YAML frontmatter parsed via yaml.safe_load
- Skills nested under skills/{plugin}/{skill}/ preserving paths
- ${CLAUDE_PLUGIN_ROOT} mapped to ${extensionPath}
- Atomic sync to avoid data loss on interruption
- Version auto-bumped only when content changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@zhfeng
zhfeng force-pushed the feat/gemini-extension-conversion branch from 20553dd to d927094 Compare March 13, 2026 02:04
@zhfeng

zhfeng commented Mar 13, 2026

Copy link
Copy Markdown
Contributor Author

Hi all,

I test with gemini locally

  • Create symlink of gemini extension to the current dev folder
ln -s "$(pwd)" ~/.gemini/extensions/ai-helpers
  • Generate all the plugins
python3 scripts/convert_to_gemini.py
  • Run /command reload in gemini to refresh the commands
  • Run /hello-world:echo in gemini and it runs in Shell and returns Hello world as expected

I also some other commnds on git and ci. All of them looks good. So I'm happy to go for the next step and start to imigrate the plugins.

@wangke19

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Mar 13, 2026
@openshift-ci

openshift-ci Bot commented Mar 13, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: stbenjam, wangke19, zhfeng

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-bot
openshift-merge-bot Bot merged commit 82ce78f into openshift-eng:main Mar 13, 2026
5 checks passed
@zhfeng

zhfeng commented Mar 13, 2026

Copy link
Copy Markdown
Contributor Author

Hi @stbenjam,

The first migration of hello-world for testing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants