@biggora/claude-plugins 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/README.md +11 -4
  2. package/package.json +1 -1
  3. package/registry/registry.json +319 -244
  4. package/specs/coding.md +24 -0
  5. package/specs/pod.md +2 -0
  6. package/src/skills/captcha/README.md +221 -0
  7. package/src/skills/captcha/SKILL.md +355 -0
  8. package/src/skills/captcha/references/captcha-types.md +254 -0
  9. package/src/skills/captcha/references/services.md +172 -0
  10. package/src/skills/captcha/references/stealth.md +238 -0
  11. package/src/skills/captcha/scripts/solve_captcha.py +323 -0
  12. package/src/skills/captcha/scripts/solve_image_grid.py +350 -0
  13. package/src/skills/google-merchant-api/SKILL.md +581 -0
  14. package/src/skills/google-merchant-api/references/accounts.md +247 -0
  15. package/src/skills/google-merchant-api/references/content-api-legacy.md +216 -0
  16. package/src/skills/google-merchant-api/references/datasources.md +233 -0
  17. package/src/skills/google-merchant-api/references/inventories.md +201 -0
  18. package/src/skills/google-merchant-api/references/migration.md +267 -0
  19. package/src/skills/google-merchant-api/references/products.md +316 -0
  20. package/src/skills/google-merchant-api/references/promotions.md +201 -0
  21. package/src/skills/google-merchant-api/references/reports.md +240 -0
  22. package/src/skills/lv-aggregators-api/SKILL.md +113 -0
  23. package/src/skills/lv-aggregators-api/references/integration-guide.md +368 -0
  24. package/src/skills/lv-aggregators-api/references/kurpirkt.md +103 -0
  25. package/src/skills/lv-aggregators-api/references/salidzini.md +122 -0
  26. package/src/skills/tailwindcss-best-practices/SKILL.md +180 -0
  27. package/src/skills/tailwindcss-best-practices/references/best-practices-utility-patterns.md +87 -0
  28. package/src/skills/tailwindcss-best-practices/references/core-installation.md +109 -0
  29. package/src/skills/tailwindcss-best-practices/references/core-preflight.md +200 -0
  30. package/src/skills/tailwindcss-best-practices/references/core-responsive.md +163 -0
  31. package/src/skills/tailwindcss-best-practices/references/core-source-detection.md +114 -0
  32. package/src/skills/tailwindcss-best-practices/references/core-theme.md +108 -0
  33. package/src/skills/tailwindcss-best-practices/references/core-utility-classes.md +59 -0
  34. package/src/skills/tailwindcss-best-practices/references/core-variants.md +204 -0
  35. package/src/skills/tailwindcss-best-practices/references/effects-form-controls.md +76 -0
  36. package/src/skills/tailwindcss-best-practices/references/effects-mask.md +91 -0
  37. package/src/skills/tailwindcss-best-practices/references/effects-scroll-snap.md +59 -0
  38. package/src/skills/tailwindcss-best-practices/references/effects-text-shadow.md +78 -0
  39. package/src/skills/tailwindcss-best-practices/references/effects-transition-animation.md +80 -0
  40. package/src/skills/tailwindcss-best-practices/references/effects-visibility-interactivity.md +82 -0
  41. package/src/skills/tailwindcss-best-practices/references/features-content-detection.md +175 -0
  42. package/src/skills/tailwindcss-best-practices/references/features-custom-styles.md +203 -0
  43. package/src/skills/tailwindcss-best-practices/references/features-dark-mode.md +137 -0
  44. package/src/skills/tailwindcss-best-practices/references/features-functions-directives.md +241 -0
  45. package/src/skills/tailwindcss-best-practices/references/features-upgrade.md +160 -0
  46. package/src/skills/tailwindcss-best-practices/references/layout-aspect-ratio.md +39 -0
  47. package/src/skills/tailwindcss-best-practices/references/layout-columns.md +80 -0
  48. package/src/skills/tailwindcss-best-practices/references/layout-display.md +110 -0
  49. package/src/skills/tailwindcss-best-practices/references/layout-flexbox.md +112 -0
  50. package/src/skills/tailwindcss-best-practices/references/layout-grid.md +87 -0
  51. package/src/skills/tailwindcss-best-practices/references/layout-height.md +97 -0
  52. package/src/skills/tailwindcss-best-practices/references/layout-inset.md +103 -0
  53. package/src/skills/tailwindcss-best-practices/references/layout-logical-properties.md +92 -0
  54. package/src/skills/tailwindcss-best-practices/references/layout-margin.md +126 -0
  55. package/src/skills/tailwindcss-best-practices/references/layout-min-max-sizing.md +63 -0
  56. package/src/skills/tailwindcss-best-practices/references/layout-object-fit-position.md +64 -0
  57. package/src/skills/tailwindcss-best-practices/references/layout-overflow.md +57 -0
  58. package/src/skills/tailwindcss-best-practices/references/layout-padding.md +77 -0
  59. package/src/skills/tailwindcss-best-practices/references/layout-position.md +85 -0
  60. package/src/skills/tailwindcss-best-practices/references/layout-tables.md +67 -0
  61. package/src/skills/tailwindcss-best-practices/references/layout-width.md +102 -0
  62. package/src/skills/tailwindcss-best-practices/references/transform-base.md +68 -0
  63. package/src/skills/tailwindcss-best-practices/references/transform-rotate.md +70 -0
  64. package/src/skills/tailwindcss-best-practices/references/transform-scale.md +83 -0
  65. package/src/skills/tailwindcss-best-practices/references/transform-skew.md +62 -0
  66. package/src/skills/tailwindcss-best-practices/references/transform-translate.md +77 -0
  67. package/src/skills/tailwindcss-best-practices/references/typography-font-text.md +142 -0
  68. package/src/skills/tailwindcss-best-practices/references/typography-list-style.md +65 -0
  69. package/src/skills/tailwindcss-best-practices/references/typography-text-align.md +60 -0
  70. package/src/skills/tailwindcss-best-practices/references/visual-background.md +76 -0
  71. package/src/skills/tailwindcss-best-practices/references/visual-border.md +108 -0
  72. package/src/skills/tailwindcss-best-practices/references/visual-effects.md +111 -0
  73. package/src/skills/tailwindcss-best-practices/references/visual-svg.md +82 -0
  74. package/src/skills/test-mobile-app/SKILL.md +11 -6
  75. package/src/skills/test-mobile-app/scripts/analyze_apk.py +15 -4
  76. package/src/skills/test-mobile-app/scripts/check_environment.py +5 -5
  77. package/src/skills/test-mobile-app/scripts/run_tests.py +1 -1
  78. package/src/skills/test-web-ui/SKILL.md +264 -84
  79. package/src/skills/test-web-ui/scripts/discover.py +25 -12
  80. package/src/skills/test-web-ui/scripts/run_tests.py +3 -2
  81. package/src/skills/vite-best-practices/SKILL.md +115 -0
  82. package/src/skills/vite-best-practices/references/build-and-ssr.md +255 -0
  83. package/src/skills/vite-best-practices/references/core-config.md +231 -0
  84. package/src/skills/vite-best-practices/references/core-features.md +222 -0
  85. package/src/skills/vite-best-practices/references/core-plugin-api.md +294 -0
  86. package/src/skills/vite-best-practices/references/environment-api.md +108 -0
  87. package/src/skills/vite-best-practices/references/rolldown-migration.md +242 -0
  88. package/codex-cli-workspace/iteration-1/benchmark.json +0 -122
  89. package/codex-cli-workspace/iteration-1/eval-1-ci-integration/eval_metadata.json +0 -13
  90. package/codex-cli-workspace/iteration-1/eval-1-ci-integration/with_skill/grading.json +0 -52
  91. package/codex-cli-workspace/iteration-1/eval-1-ci-integration/with_skill/outputs/response.md +0 -163
  92. package/codex-cli-workspace/iteration-1/eval-1-ci-integration/with_skill/timing.json +0 -5
  93. package/codex-cli-workspace/iteration-1/eval-1-ci-integration/without_skill/grading.json +0 -58
  94. package/codex-cli-workspace/iteration-1/eval-1-ci-integration/without_skill/outputs/response.md +0 -151
  95. package/codex-cli-workspace/iteration-1/eval-1-ci-integration/without_skill/timing.json +0 -5
  96. package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/eval_metadata.json +0 -13
  97. package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/grading.json +0 -52
  98. package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/outputs/response.md +0 -86
  99. package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/timing.json +0 -5
  100. package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/grading.json +0 -58
  101. package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/outputs/response.md +0 -164
  102. package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/timing.json +0 -5
  103. package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/eval_metadata.json +0 -13
  104. package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/with_skill/grading.json +0 -52
  105. package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/with_skill/outputs/response.md +0 -130
  106. package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/with_skill/timing.json +0 -5
  107. package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/without_skill/grading.json +0 -64
  108. package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/without_skill/outputs/response.md +0 -209
  109. package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/without_skill/timing.json +0 -5
  110. package/codex-cli-workspace/iteration-1/review.html +0 -1325
  111. package/gemini-cli-workspace/iteration-1/benchmark.json +0 -86
  112. package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/eval_metadata.json +0 -37
  113. package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/with_skill/grading.json +0 -37
  114. package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/with_skill/outputs/response.md +0 -401
  115. package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/with_skill/timing.json +0 -5
  116. package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/without_skill/grading.json +0 -37
  117. package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/without_skill/outputs/response.md +0 -405
  118. package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/without_skill/timing.json +0 -5
  119. package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/eval_metadata.json +0 -37
  120. package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/grading.json +0 -37
  121. package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/outputs/response.md +0 -212
  122. package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/timing.json +0 -5
  123. package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/grading.json +0 -37
  124. package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/outputs/response.md +0 -427
  125. package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/timing.json +0 -5
  126. package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/eval_metadata.json +0 -32
  127. package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/with_skill/grading.json +0 -32
  128. package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/with_skill/outputs/response.md +0 -171
  129. package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/with_skill/timing.json +0 -5
  130. package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/without_skill/grading.json +0 -32
  131. package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/without_skill/outputs/response.md +0 -199
  132. package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/without_skill/timing.json +0 -5
  133. package/gemini-cli-workspace/iteration-1/review.html +0 -1325
  134. package/gemini-cli-workspace/iteration-2/benchmark.json +0 -173
  135. package/gemini-cli-workspace/iteration-2/benchmark.md +0 -28
  136. package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/eval_metadata.json +0 -37
  137. package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/with_skill/grading.json +0 -37
  138. package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/with_skill/outputs/response.md +0 -195
  139. package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/with_skill/timing.json +0 -5
  140. package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/without_skill/grading.json +0 -37
  141. package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/without_skill/outputs/response.md +0 -377
  142. package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/without_skill/timing.json +0 -5
  143. package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/eval_metadata.json +0 -37
  144. package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/with_skill/grading.json +0 -37
  145. package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/with_skill/outputs/response.md +0 -127
  146. package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/with_skill/timing.json +0 -5
  147. package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/without_skill/grading.json +0 -37
  148. package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/without_skill/outputs/response.md +0 -164
  149. package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/without_skill/timing.json +0 -5
  150. package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/eval_metadata.json +0 -32
  151. package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/with_skill/grading.json +0 -32
  152. package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/with_skill/outputs/response.md +0 -91
  153. package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/with_skill/timing.json +0 -5
  154. package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/without_skill/grading.json +0 -32
  155. package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/without_skill/outputs/response.md +0 -112
  156. package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/without_skill/timing.json +0 -5
  157. package/gemini-cli-workspace/iteration-2/eval-viewer.html +0 -1325
  158. package/screen-recording-workspace/evals.json +0 -41
  159. package/screen-recording-workspace/iteration-1/benchmark.json +0 -102
  160. package/screen-recording-workspace/iteration-1/eval-0-fullscreen/eval_metadata.json +0 -31
  161. package/screen-recording-workspace/iteration-1/eval-0-fullscreen/with_skill/grading.json +0 -11
  162. package/screen-recording-workspace/iteration-1/eval-0-fullscreen/with_skill/outputs/demo.mp4 +0 -0
  163. package/screen-recording-workspace/iteration-1/eval-0-fullscreen/with_skill/timing.json +0 -5
  164. package/screen-recording-workspace/iteration-1/eval-0-fullscreen/without_skill/grading.json +0 -11
  165. package/screen-recording-workspace/iteration-1/eval-0-fullscreen/without_skill/outputs/demo.mp4 +0 -0
  166. package/screen-recording-workspace/iteration-1/eval-0-fullscreen/without_skill/timing.json +0 -5
  167. package/screen-recording-workspace/iteration-1/eval-1-region-audio/eval_metadata.json +0 -31
  168. package/screen-recording-workspace/iteration-1/eval-1-region-audio/with_skill/grading.json +0 -11
  169. package/screen-recording-workspace/iteration-1/eval-1-region-audio/with_skill/outputs/region_capture.mp4 +0 -0
  170. package/screen-recording-workspace/iteration-1/eval-1-region-audio/with_skill/timing.json +0 -5
  171. package/screen-recording-workspace/iteration-1/eval-1-region-audio/without_skill/grading.json +0 -11
  172. package/screen-recording-workspace/iteration-1/eval-1-region-audio/without_skill/outputs/region_capture.mp4 +0 -0
  173. package/screen-recording-workspace/iteration-1/eval-1-region-audio/without_skill/timing.json +0 -5
  174. package/screen-recording-workspace/iteration-1/eval-2-python-fallback/eval_metadata.json +0 -31
  175. package/screen-recording-workspace/iteration-1/eval-2-python-fallback/with_skill/grading.json +0 -11
  176. package/screen-recording-workspace/iteration-1/eval-2-python-fallback/with_skill/outputs/fallback_recording.mp4 +0 -0
  177. package/screen-recording-workspace/iteration-1/eval-2-python-fallback/with_skill/timing.json +0 -5
  178. package/screen-recording-workspace/iteration-1/eval-2-python-fallback/without_skill/grading.json +0 -11
  179. package/screen-recording-workspace/iteration-1/eval-2-python-fallback/without_skill/outputs/fallback_recording.mp4 +0 -0
  180. package/screen-recording-workspace/iteration-1/eval-2-python-fallback/without_skill/outputs/record_screen.py +0 -67
  181. package/screen-recording-workspace/iteration-1/eval-2-python-fallback/without_skill/timing.json +0 -5
  182. package/screen-recording-workspace/iteration-1/review.html +0 -1325
  183. package/src/skills/codex-cli/evals/evals.json +0 -47
  184. package/src/skills/gemini-cli/evals/evals.json +0 -46
  185. package/src/skills/tm-search/evals/evals.json +0 -23
@@ -1,405 +0,0 @@
1
- # Setting Up Gemini CLI for Automated PR Reviews in GitHub Actions
2
-
3
- This guide covers how to configure Gemini CLI in a GitHub Actions CI/CD pipeline to automatically review pull requests, using an API key from GitHub Secrets and structured JSON output for parsing.
4
-
5
- ## Prerequisites
6
-
7
- - A Google AI API key (from [Google AI Studio](https://aistudio.google.com/apikey))
8
- - The API key stored as a GitHub repository secret (e.g., `GEMINI_API_KEY`)
9
- - A GitHub repository with pull request workflows
10
-
11
- ## Step 1: Store Your API Key in GitHub Secrets
12
-
13
- 1. Go to your repository on GitHub.
14
- 2. Navigate to **Settings > Secrets and variables > Actions**.
15
- 3. Click **New repository secret**.
16
- 4. Name it `GEMINI_API_KEY` and paste your API key as the value.
17
-
18
- ## Step 2: Create the GitHub Actions Workflow
19
-
20
- Create a file at `.github/workflows/gemini-pr-review.yml`:
21
-
22
- ```yaml
23
- name: Gemini PR Review
24
-
25
- on:
26
- pull_request:
27
- types: [opened, synchronize, reopened]
28
-
29
- permissions:
30
- contents: read
31
- pull-requests: write
32
-
33
- jobs:
34
- review:
35
- runs-on: ubuntu-latest
36
- steps:
37
- - name: Checkout repository
38
- uses: actions/checkout@v4
39
- with:
40
- fetch-depth: 0
41
-
42
- - name: Set up Node.js
43
- uses: actions/setup-node@v4
44
- with:
45
- node-version: '20'
46
-
47
- - name: Install Gemini CLI
48
- run: npm install -g @anthropic-ai/gemini-cli || npm install -g gemini-cli
49
-
50
- - name: Get PR diff
51
- id: diff
52
- run: |
53
- git fetch origin ${{ github.base_ref }}
54
- DIFF=$(git diff origin/${{ github.base_ref }}...HEAD)
55
- # Write diff to a file to avoid shell escaping issues
56
- echo "$DIFF" > /tmp/pr_diff.txt
57
-
58
- - name: Get changed files list
59
- id: files
60
- run: |
61
- git fetch origin ${{ github.base_ref }}
62
- FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD)
63
- echo "$FILES" > /tmp/changed_files.txt
64
-
65
- - name: Run Gemini CLI review
66
- id: gemini-review
67
- env:
68
- GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
69
- run: |
70
- DIFF=$(cat /tmp/pr_diff.txt)
71
- FILES=$(cat /tmp/changed_files.txt)
72
-
73
- PROMPT=$(cat <<'PROMPT_EOF'
74
- You are a senior code reviewer. Analyze the following pull request diff and provide a structured review.
75
-
76
- Changed files:
77
- FILE_LIST_PLACEHOLDER
78
-
79
- Diff:
80
- DIFF_PLACEHOLDER
81
-
82
- Respond ONLY with valid JSON in this exact format (no markdown fencing, no extra text):
83
- {
84
- "summary": "Brief summary of the changes",
85
- "risk_level": "low|medium|high",
86
- "issues": [
87
- {
88
- "file": "path/to/file",
89
- "line": 42,
90
- "severity": "error|warning|suggestion",
91
- "message": "Description of the issue",
92
- "suggestion": "How to fix it"
93
- }
94
- ],
95
- "positive_aspects": ["List of things done well"],
96
- "approval_recommendation": "approve|request_changes|comment"
97
- }
98
- PROMPT_EOF
99
- )
100
-
101
- # Replace placeholders
102
- PROMPT="${PROMPT/FILE_LIST_PLACEHOLDER/$FILES}"
103
- PROMPT="${PROMPT/DIFF_PLACEHOLDER/$DIFF}"
104
-
105
- # Run Gemini CLI with the prompt
106
- # Using the --json flag if available, or parsing output directly
107
- RESPONSE=$(echo "$PROMPT" | gemini \
108
- --model gemini-2.0-flash \
109
- --api-key "$GEMINI_API_KEY" \
110
- 2>/dev/null) || true
111
-
112
- # If gemini CLI is not available, fall back to direct API call
113
- if [ -z "$RESPONSE" ]; then
114
- RESPONSE=$(curl -s "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${GEMINI_API_KEY}" \
115
- -H 'Content-Type: application/json' \
116
- -d "$(jq -n --arg prompt "$PROMPT" '{
117
- "contents": [{"parts": [{"text": $prompt}]}],
118
- "generationConfig": {
119
- "responseMimeType": "application/json",
120
- "temperature": 0.2
121
- }
122
- }')" | jq -r '.candidates[0].content.parts[0].text')
123
- fi
124
-
125
- echo "$RESPONSE" > /tmp/review_result.json
126
-
127
- # Validate JSON
128
- if jq empty /tmp/review_result.json 2>/dev/null; then
129
- echo "valid_json=true" >> $GITHUB_OUTPUT
130
- else
131
- echo "valid_json=false" >> $GITHUB_OUTPUT
132
- echo "Raw response was not valid JSON, attempting extraction..."
133
- # Try to extract JSON from markdown fenced blocks
134
- sed -n '/^```json/,/^```$/p' /tmp/review_result.json | sed '1d;$d' > /tmp/review_cleaned.json
135
- if jq empty /tmp/review_cleaned.json 2>/dev/null; then
136
- mv /tmp/review_cleaned.json /tmp/review_result.json
137
- echo "valid_json=true" >> $GITHUB_OUTPUT
138
- fi
139
- fi
140
-
141
- - name: Parse and post review
142
- if: success()
143
- env:
144
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
145
- run: |
146
- REVIEW_FILE="/tmp/review_result.json"
147
-
148
- if ! jq empty "$REVIEW_FILE" 2>/dev/null; then
149
- echo "Failed to get valid JSON review. Posting raw output as comment."
150
- gh pr comment ${{ github.event.pull_request.number }} \
151
- --body "## Gemini Review
152
-
153
- > Could not parse structured output. Raw response attached.
154
-
155
- \`\`\`
156
- $(cat "$REVIEW_FILE")
157
- \`\`\`"
158
- exit 0
159
- fi
160
-
161
- # Extract fields from JSON
162
- SUMMARY=$(jq -r '.summary' "$REVIEW_FILE")
163
- RISK=$(jq -r '.risk_level' "$REVIEW_FILE")
164
- APPROVAL=$(jq -r '.approval_recommendation' "$REVIEW_FILE")
165
- POSITIVES=$(jq -r '.positive_aspects // [] | map("- " + .) | join("\n")' "$REVIEW_FILE")
166
- ISSUE_COUNT=$(jq -r '.issues | length' "$REVIEW_FILE")
167
-
168
- # Build issue table
169
- ISSUES_MD=""
170
- if [ "$ISSUE_COUNT" -gt 0 ]; then
171
- ISSUES_MD="### Issues Found ($ISSUE_COUNT)
172
-
173
- | Severity | File | Line | Message | Suggestion |
174
- |----------|------|------|---------|------------|
175
- "
176
- ISSUES_MD+=$(jq -r '.issues[] | "| \(.severity) | `\(.file)` | \(.line) | \(.message) | \(.suggestion) |"' "$REVIEW_FILE")
177
- else
178
- ISSUES_MD="### No issues found"
179
- fi
180
-
181
- # Build risk badge
182
- case "$RISK" in
183
- low) RISK_BADGE="![Risk: Low](https://img.shields.io/badge/Risk-Low-green)" ;;
184
- medium) RISK_BADGE="![Risk: Medium](https://img.shields.io/badge/Risk-Medium-yellow)" ;;
185
- high) RISK_BADGE="![Risk: High](https://img.shields.io/badge/Risk-High-red)" ;;
186
- *) RISK_BADGE="Risk: $RISK" ;;
187
- esac
188
-
189
- # Compose comment
190
- COMMENT=$(cat <<EOF
191
- ## Gemini Automated PR Review
192
-
193
- $RISK_BADGE
194
-
195
- ### Summary
196
- $SUMMARY
197
-
198
- $ISSUES_MD
199
-
200
- ### Positive Aspects
201
- $POSITIVES
202
-
203
- ---
204
- **Recommendation:** \`$APPROVAL\`
205
- EOF
206
- )
207
-
208
- # Post comment to PR
209
- gh pr comment ${{ github.event.pull_request.number }} --body "$COMMENT"
210
- ```
211
-
212
- ## Step 3: Direct API Approach with Structured JSON Output (Recommended)
213
-
214
- If the Gemini CLI does not reliably produce JSON, use the Gemini REST API directly with `responseMimeType` set to `application/json`. This forces the model to return valid JSON. Here is a standalone workflow that uses `curl` and `jq`:
215
-
216
- ```yaml
217
- name: Gemini PR Review (API Direct)
218
-
219
- on:
220
- pull_request:
221
- types: [opened, synchronize, reopened]
222
-
223
- permissions:
224
- contents: read
225
- pull-requests: write
226
-
227
- jobs:
228
- review:
229
- runs-on: ubuntu-latest
230
- steps:
231
- - name: Checkout
232
- uses: actions/checkout@v4
233
- with:
234
- fetch-depth: 0
235
-
236
- - name: Generate review via Gemini API
237
- id: review
238
- env:
239
- GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
240
- run: |
241
- git fetch origin ${{ github.base_ref }}
242
- DIFF=$(git diff origin/${{ github.base_ref }}...HEAD | head -c 30000)
243
- FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD)
244
-
245
- # Build the prompt
246
- PROMPT="You are a code reviewer. Review this PR diff. Changed files: ${FILES}. Diff: ${DIFF}. Return a JSON object with keys: summary (string), risk_level (low/medium/high), issues (array of {file, line, severity, message, suggestion}), positive_aspects (array of strings), approval_recommendation (approve/request_changes/comment)."
247
-
248
- # Call Gemini API with structured output
249
- RESPONSE=$(curl -sf \
250
- "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${GEMINI_API_KEY}" \
251
- -H 'Content-Type: application/json' \
252
- -d "$(jq -n --arg prompt "$PROMPT" '{
253
- contents: [{parts: [{text: $prompt}]}],
254
- generationConfig: {
255
- responseMimeType: "application/json",
256
- responseSchema: {
257
- type: "object",
258
- properties: {
259
- summary: {type: "string"},
260
- risk_level: {type: "string", enum: ["low", "medium", "high"]},
261
- issues: {
262
- type: "array",
263
- items: {
264
- type: "object",
265
- properties: {
266
- file: {type: "string"},
267
- line: {type: "integer"},
268
- severity: {type: "string", enum: ["error", "warning", "suggestion"]},
269
- message: {type: "string"},
270
- suggestion: {type: "string"}
271
- },
272
- required: ["file", "severity", "message"]
273
- }
274
- },
275
- positive_aspects: {type: "array", items: {type: "string"}},
276
- approval_recommendation: {type: "string", enum: ["approve", "request_changes", "comment"]}
277
- },
278
- required: ["summary", "risk_level", "issues", "approval_recommendation"]
279
- },
280
- temperature: 0.2
281
- }
282
- }')")
283
-
284
- # Extract the text content from the API response
285
- REVIEW=$(echo "$RESPONSE" | jq -r '.candidates[0].content.parts[0].text')
286
- echo "$REVIEW" > /tmp/review.json
287
-
288
- # Validate
289
- jq empty /tmp/review.json
290
-
291
- - name: Post review comment
292
- env:
293
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
294
- run: |
295
- REVIEW_FILE="/tmp/review.json"
296
-
297
- SUMMARY=$(jq -r '.summary' "$REVIEW_FILE")
298
- RISK=$(jq -r '.risk_level' "$REVIEW_FILE")
299
- APPROVAL=$(jq -r '.approval_recommendation' "$REVIEW_FILE")
300
-
301
- # Format issues as markdown
302
- ISSUES=$(jq -r '
303
- if (.issues | length) > 0 then
304
- "| Severity | File | Line | Issue | Fix |\n|---|---|---|---|---|\n" +
305
- (.issues[] | "| \(.severity) | `\(.file)` | \(.line // "N/A") | \(.message) | \(.suggestion // "N/A") |")
306
- else
307
- "_No issues found._"
308
- end
309
- ' "$REVIEW_FILE")
310
-
311
- POSITIVES=$(jq -r '(.positive_aspects // []) | map("- " + .) | join("\n")' "$REVIEW_FILE")
312
-
313
- BODY=$(cat <<EOF
314
- ## Automated PR Review (Gemini)
315
-
316
- **Risk Level:** \`${RISK}\` | **Recommendation:** \`${APPROVAL}\`
317
-
318
- ### Summary
319
- ${SUMMARY}
320
-
321
- ### Issues
322
- ${ISSUES}
323
-
324
- ### What looks good
325
- ${POSITIVES}
326
- EOF
327
- )
328
-
329
- gh pr comment "${{ github.event.pull_request.number }}" --body "$BODY"
330
- ```
331
-
332
- ## Step 4: Using Gemini CLI with `--json` Flag (If Supported)
333
-
334
- Some versions of the Gemini CLI support a `--json` output flag. If your version does, the invocation simplifies to:
335
-
336
- ```bash
337
- gemini --model gemini-2.0-flash \
338
- --api-key "$GEMINI_API_KEY" \
339
- --json \
340
- --prompt "Review this code diff and return structured JSON: $DIFF"
341
- ```
342
-
343
- Check your installed version's help output (`gemini --help`) to confirm available flags.
344
-
345
- ## Step 5: Parsing the JSON Output in Downstream Steps
346
-
347
- Once you have valid JSON in a file, you can use it in subsequent pipeline steps:
348
-
349
- ```yaml
350
- - name: Fail on high-risk reviews
351
- run: |
352
- RISK=$(jq -r '.risk_level' /tmp/review.json)
353
- ERRORS=$(jq '[.issues[] | select(.severity == "error")] | length' /tmp/review.json)
354
-
355
- echo "Risk level: $RISK"
356
- echo "Error count: $ERRORS"
357
-
358
- if [ "$RISK" = "high" ] || [ "$ERRORS" -gt 0 ]; then
359
- echo "::error::PR review found high risk or errors. Please address the issues."
360
- exit 1
361
- fi
362
- ```
363
-
364
- You can also use it in a matrix strategy or pass data between jobs:
365
-
366
- ```yaml
367
- - name: Export review data
368
- id: export
369
- run: |
370
- echo "risk=$(jq -r '.risk_level' /tmp/review.json)" >> $GITHUB_OUTPUT
371
- echo "approval=$(jq -r '.approval_recommendation' /tmp/review.json)" >> $GITHUB_OUTPUT
372
- echo "issue_count=$(jq '.issues | length' /tmp/review.json)" >> $GITHUB_OUTPUT
373
- ```
374
-
375
- Then reference in later steps or jobs:
376
-
377
- ```yaml
378
- - name: Auto-approve if clean
379
- if: steps.export.outputs.approval == 'approve' && steps.export.outputs.issue_count == '0'
380
- env:
381
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
382
- run: |
383
- gh pr review "${{ github.event.pull_request.number }}" --approve --body "Automated review passed with no issues."
384
- ```
385
-
386
- ## Key Points
387
-
388
- 1. **`responseMimeType: "application/json"`** in the Gemini API `generationConfig` forces the model to return valid JSON. This is the most reliable way to get structured output.
389
-
390
- 2. **`responseSchema`** lets you define the exact JSON schema you expect. The model will conform to it. This eliminates the need for post-processing or regex extraction.
391
-
392
- 3. **Diff size limits**: Git diffs can be very large. Truncate them (e.g., `head -c 30000`) to stay within token limits. For large PRs, consider reviewing changed files individually.
393
-
394
- 4. **Error handling**: Always validate the JSON output with `jq empty` before trying to parse it. Have a fallback path that posts raw output as a comment.
395
-
396
- 5. **Rate limits**: The Gemini API has rate limits. For high-traffic repos, add retry logic or use the paid tier.
397
-
398
- 6. **Security**: The `GEMINI_API_KEY` secret is never exposed in logs because GitHub Actions automatically masks secrets in output. The `GITHUB_TOKEN` is provided automatically by Actions with the permissions declared in the workflow.
399
-
400
- ## Troubleshooting
401
-
402
- - **"jq: parse error"**: The model returned non-JSON text. Use `responseMimeType: "application/json"` to fix this.
403
- - **Empty response**: Check that `GEMINI_API_KEY` is set correctly in secrets and that the model name is valid.
404
- - **Diff too large**: Truncate the diff or split the review across multiple API calls, one per file.
405
- - **Permission denied on PR comment**: Ensure `permissions: pull-requests: write` is set in the workflow.
@@ -1,5 +0,0 @@
1
- {
2
- "total_tokens": 60035,
3
- "duration_ms": 77857,
4
- "total_duration_seconds": 77.9
5
- }
@@ -1,37 +0,0 @@
1
- {
2
- "eval_id": 2,
3
- "eval_name": "mcp-server-config",
4
- "prompt": "I need to connect a custom MCP server I built in Python to gemini cli. The server needs an API key from my environment. Also I want to restrict which tools it can expose. How do I configure this?",
5
- "assertions": [
6
- {
7
- "id": "correct-settings-location",
8
- "text": "Points to ~/.gemini/settings.json or project-level settings.json",
9
- "type": "content_check"
10
- },
11
- {
12
- "id": "shows-mcp-config-structure",
13
- "text": "Shows mcpServers config with command, args fields",
14
- "type": "content_check"
15
- },
16
- {
17
- "id": "env-var-dollar-pattern",
18
- "text": "Shows $VAR pattern for environment variable references in env field",
19
- "type": "content_check"
20
- },
21
- {
22
- "id": "tool-filtering",
23
- "text": "Explains includeTools and/or excludeTools for restricting exposed tools",
24
- "type": "content_check"
25
- },
26
- {
27
- "id": "security-note",
28
- "text": "Mentions security considerations (trust field, not hardcoding keys, etc.)",
29
- "type": "content_check"
30
- },
31
- {
32
- "id": "python-command-correct",
33
- "text": "Uses correct Python command (python/python3) in the command field for the MCP server",
34
- "type": "accuracy_check"
35
- }
36
- ]
37
- }
@@ -1,37 +0,0 @@
1
- {
2
- "eval_id": 2,
3
- "eval_name": "mcp-server-config",
4
- "configuration": "with_skill",
5
- "expectations": [
6
- {
7
- "text": "Points to ~/.gemini/settings.json or project-level settings.json",
8
- "passed": true,
9
- "evidence": "Mentions both `~/.gemini/settings.json` (global) and `<project>/.gemini/settings.json` (project-scoped)"
10
- },
11
- {
12
- "text": "Shows mcpServers config with command, args fields",
13
- "passed": true,
14
- "evidence": "Complete mcpServers config with command, args, cwd, env, timeout, trust, includeTools fields"
15
- },
16
- {
17
- "text": "Shows $VAR pattern for environment variable references in env field",
18
- "passed": true,
19
- "evidence": "Shows `\"MY_API_KEY\": \"$MY_API_KEY\"` and explains the $VAR_NAME pattern explicitly"
20
- },
21
- {
22
- "text": "Explains includeTools and/or excludeTools for restricting exposed tools",
23
- "passed": true,
24
- "evidence": "Explains both includeTools (whitelist) and excludeTools (blacklist) with examples and guidance on when to use each"
25
- },
26
- {
27
- "text": "Mentions security considerations (trust field, not hardcoding keys, etc.)",
28
- "passed": true,
29
- "evidence": "Warns to never hardcode secrets, explains trust field, mentions auto-redaction of sensitive env vars"
30
- },
31
- {
32
- "text": "Uses correct Python command (python/python3) in the command field",
33
- "passed": true,
34
- "evidence": "Uses both `python` and `python3` with note about system differences"
35
- }
36
- ]
37
- }