neon_sakura 0.1.4

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 (251) hide show
  1. checksums.yaml +7 -0
  2. data/.ai-reviewer/README.md +182 -0
  3. data/.ai-reviewer/ai-reviewer.sh +56 -0
  4. data/.ai-reviewer/build-system-prompt.sh +136 -0
  5. data/.ai-reviewer/extract-claude-sections.sh +32 -0
  6. data/.ai-reviewer/test-ai-reviewer.sh +40 -0
  7. data/.ai-reviewer-config.yml +190 -0
  8. data/.github/dependabot.yml +12 -0
  9. data/.github/settings.yml +70 -0
  10. data/.github/workflows/ai-pr-review-on-comment.yml +384 -0
  11. data/.github/workflows/ai-pr-review.yml +328 -0
  12. data/.github/workflows/license-check.yml +78 -0
  13. data/.github/workflows/lint.yml +79 -0
  14. data/.github/workflows/security.yml +131 -0
  15. data/.github/workflows/semgrep.yml +26 -0
  16. data/.github/workflows/test.yml +44 -0
  17. data/.gitignore +75 -0
  18. data/.rubocop.yml +33 -0
  19. data/.ruby-version +1 -0
  20. data/.simplecov +14 -0
  21. data/.stylelintignore +10 -0
  22. data/.stylelintrc.json +37 -0
  23. data/AGENTS.md +51 -0
  24. data/CHANGELOG.md +568 -0
  25. data/CLAUDE.md +632 -0
  26. data/Gemfile +8 -0
  27. data/Gemfile.lock +327 -0
  28. data/LICENSE +21 -0
  29. data/README.md +1209 -0
  30. data/Rakefile +25 -0
  31. data/app/assets/images/cherry_blossom.svg +1525 -0
  32. data/app/assets/images/cherry_blossom_tree.png +0 -0
  33. data/app/assets/images/prysm-icon.png +0 -0
  34. data/app/assets/stylesheets/base.css +29 -0
  35. data/app/assets/stylesheets/components.css +1652 -0
  36. data/app/assets/stylesheets/forms.css +152 -0
  37. data/app/assets/stylesheets/loading.css +145 -0
  38. data/app/assets/stylesheets/neon_sakura.css +40 -0
  39. data/app/assets/stylesheets/pagy-tailwind.css +120 -0
  40. data/app/assets/stylesheets/theme-default.css +40 -0
  41. data/app/assets/stylesheets/theme-green.css +84 -0
  42. data/app/assets/stylesheets/theme-purple.css +94 -0
  43. data/app/assets/stylesheets/theme-red.css +84 -0
  44. data/app/assets/stylesheets/utility-borders.css +29 -0
  45. data/app/assets/stylesheets/utility-colors.css +185 -0
  46. data/app/assets/stylesheets/utility-effects.css +123 -0
  47. data/app/assets/stylesheets/utility-gradients.css +158 -0
  48. data/app/assets/stylesheets/utility-layout.css +132 -0
  49. data/app/assets/stylesheets/utility-reset.css +13 -0
  50. data/app/assets/stylesheets/utility-responsive.css +145 -0
  51. data/app/assets/stylesheets/utility-sizing.css +99 -0
  52. data/app/assets/stylesheets/utility-spacing.css +174 -0
  53. data/app/assets/stylesheets/utility-typography.css +97 -0
  54. data/app/controllers/errors_controller.rb +120 -0
  55. data/app/controllers/style_guide_controller.rb +117 -0
  56. data/app/helpers/errors_helper.rb +12 -0
  57. data/app/helpers/neon_sakura/navbar_helper.rb +43 -0
  58. data/app/helpers/style_guide_helper.rb +36 -0
  59. data/app/javascript/neon_sakura/dropdown.js +22 -0
  60. data/app/javascript/neon_sakura/navbar.js +71 -0
  61. data/app/javascript/neon_sakura/theme_switcher.js +187 -0
  62. data/app/views/errors/show.html.erb +105 -0
  63. data/app/views/layouts/error.html.erb +19 -0
  64. data/app/views/layouts/mission_control/jobs/_application_selection.html.erb +14 -0
  65. data/app/views/layouts/mission_control/jobs/_navigation.html.erb +21 -0
  66. data/app/views/layouts/mission_control/jobs/application.html.erb +453 -0
  67. data/app/views/layouts/style_guide.html.erb +416 -0
  68. data/app/views/shared/_file_upload.html.erb +184 -0
  69. data/app/views/shared/_footer.html.erb +23 -0
  70. data/app/views/shared/_header.html.erb +42 -0
  71. data/app/views/shared/_navbar.html.erb +306 -0
  72. data/app/views/shared/_profile_image_selector.html.erb +165 -0
  73. data/app/views/shared/_theme_switcher.html.erb +64 -0
  74. data/app/views/shared/icons/_adjustments.html.erb +10 -0
  75. data/app/views/shared/icons/_alert_circle.html.erb +3 -0
  76. data/app/views/shared/icons/_alert_triangle.html.erb +3 -0
  77. data/app/views/shared/icons/_archive.html.erb +3 -0
  78. data/app/views/shared/icons/_arrow_down.html.erb +3 -0
  79. data/app/views/shared/icons/_arrow_left.html.erb +3 -0
  80. data/app/views/shared/icons/_arrow_up.html.erb +3 -0
  81. data/app/views/shared/icons/_arrows_pointing_in.html.erb +10 -0
  82. data/app/views/shared/icons/_arrows_pointing_out.html.erb +10 -0
  83. data/app/views/shared/icons/_artemis_logo.html.erb +26 -0
  84. data/app/views/shared/icons/_auth_banner.html.erb +1 -0
  85. data/app/views/shared/icons/_bars.html.erb +10 -0
  86. data/app/views/shared/icons/_bell.html.erb +3 -0
  87. data/app/views/shared/icons/_book.html.erb +3 -0
  88. data/app/views/shared/icons/_bookmark.html.erb +3 -0
  89. data/app/views/shared/icons/_box.html.erb +3 -0
  90. data/app/views/shared/icons/_brain.html.erb +3 -0
  91. data/app/views/shared/icons/_briefcase.html.erb +3 -0
  92. data/app/views/shared/icons/_calendar.html.erb +3 -0
  93. data/app/views/shared/icons/_camera.html.erb +4 -0
  94. data/app/views/shared/icons/_chart_bar.html.erb +3 -0
  95. data/app/views/shared/icons/_chart_line.html.erb +10 -0
  96. data/app/views/shared/icons/_chart_pie.html.erb +11 -0
  97. data/app/views/shared/icons/_chat.html.erb +3 -0
  98. data/app/views/shared/icons/_check.html.erb +3 -0
  99. data/app/views/shared/icons/_check_circle.html.erb +3 -0
  100. data/app/views/shared/icons/_cherry_blossom.html.erb +1516 -0
  101. data/app/views/shared/icons/_cherry_blossom_silhouette.html.erb +1016 -0
  102. data/app/views/shared/icons/_cherry_blossom_single_flower.html.erb +1125 -0
  103. data/app/views/shared/icons/_cherry_blossom_tree.html.erb +159 -0
  104. data/app/views/shared/icons/_chevron_down.html.erb +3 -0
  105. data/app/views/shared/icons/_chevron_right.html.erb +9 -0
  106. data/app/views/shared/icons/_clipboard.html.erb +3 -0
  107. data/app/views/shared/icons/_clock.html.erb +3 -0
  108. data/app/views/shared/icons/_close.html.erb +3 -0
  109. data/app/views/shared/icons/_cog.html.erb +4 -0
  110. data/app/views/shared/icons/_crop.html.erb +10 -0
  111. data/app/views/shared/icons/_crown.html.erb +3 -0
  112. data/app/views/shared/icons/_disc.html.erb +3 -0
  113. data/app/views/shared/icons/_download.html.erb +3 -0
  114. data/app/views/shared/icons/_dragonfly.html.erb +58 -0
  115. data/app/views/shared/icons/_duplicate.html.erb +4 -0
  116. data/app/views/shared/icons/_edit.html.erb +3 -0
  117. data/app/views/shared/icons/_envelope.html.erb +3 -0
  118. data/app/views/shared/icons/_eraser.html.erb +10 -0
  119. data/app/views/shared/icons/_external_link.html.erb +3 -0
  120. data/app/views/shared/icons/_eye.html.erb +4 -0
  121. data/app/views/shared/icons/_file_csv.html.erb +10 -0
  122. data/app/views/shared/icons/_file_export.html.erb +10 -0
  123. data/app/views/shared/icons/_file_image.html.erb +10 -0
  124. data/app/views/shared/icons/_file_import.html.erb +10 -0
  125. data/app/views/shared/icons/_file_question.html.erb +6 -0
  126. data/app/views/shared/icons/_film.html.erb +3 -0
  127. data/app/views/shared/icons/_filter.html.erb +3 -0
  128. data/app/views/shared/icons/_folder.html.erb +3 -0
  129. data/app/views/shared/icons/_folder_open.html.erb +3 -0
  130. data/app/views/shared/icons/_folder_plus.html.erb +3 -0
  131. data/app/views/shared/icons/_globe.html.erb +3 -0
  132. data/app/views/shared/icons/_google.html.erb +11 -0
  133. data/app/views/shared/icons/_heart.html.erb +3 -0
  134. data/app/views/shared/icons/_heart_broken.html.erb +11 -0
  135. data/app/views/shared/icons/_heart_pulse.html.erb +4 -0
  136. data/app/views/shared/icons/_history.html.erb +11 -0
  137. data/app/views/shared/icons/_home.html.erb +10 -0
  138. data/app/views/shared/icons/_image.html.erb +3 -0
  139. data/app/views/shared/icons/_inbox.html.erb +3 -0
  140. data/app/views/shared/icons/_info_circle.html.erb +10 -0
  141. data/app/views/shared/icons/_key.html.erb +3 -0
  142. data/app/views/shared/icons/_layers.html.erb +10 -0
  143. data/app/views/shared/icons/_lightbulb.html.erb +10 -0
  144. data/app/views/shared/icons/_lightning.html.erb +3 -0
  145. data/app/views/shared/icons/_list.html.erb +3 -0
  146. data/app/views/shared/icons/_lock.html.erb +3 -0
  147. data/app/views/shared/icons/_logout.html.erb +3 -0
  148. data/app/views/shared/icons/_magazine.html.erb +3 -0
  149. data/app/views/shared/icons/_magic.html.erb +3 -0
  150. data/app/views/shared/icons/_minus.html.erb +10 -0
  151. data/app/views/shared/icons/_mobile.html.erb +10 -0
  152. data/app/views/shared/icons/_moon.html.erb +3 -0
  153. data/app/views/shared/icons/_network.html.erb +10 -0
  154. data/app/views/shared/icons/_new_item_banner.html.erb +1 -0
  155. data/app/views/shared/icons/_ouroboros.html.erb +24 -0
  156. data/app/views/shared/icons/_package.html.erb +3 -0
  157. data/app/views/shared/icons/_palette.html.erb +3 -0
  158. data/app/views/shared/icons/_paper_plane.html.erb +10 -0
  159. data/app/views/shared/icons/_photo.html.erb +10 -0
  160. data/app/views/shared/icons/_play.html.erb +4 -0
  161. data/app/views/shared/icons/_plus.html.erb +3 -0
  162. data/app/views/shared/icons/_pocket.html.erb +11 -0
  163. data/app/views/shared/icons/_prysm-icon.html.erb +34 -0
  164. data/app/views/shared/icons/_prysm.html.erb +13 -0
  165. data/app/views/shared/icons/_pushbullet-1.html.erb +29 -0
  166. data/app/views/shared/icons/_pushbullet-2.html.erb +2 -0
  167. data/app/views/shared/icons/_puzzle.html.erb +10 -0
  168. data/app/views/shared/icons/_qrcode.html.erb +3 -0
  169. data/app/views/shared/icons/_question.html.erb +3 -0
  170. data/app/views/shared/icons/_receipt.html.erb +10 -0
  171. data/app/views/shared/icons/_redo.html.erb +3 -0
  172. data/app/views/shared/icons/_refresh.html.erb +3 -0
  173. data/app/views/shared/icons/_rocket.html.erb +10 -0
  174. data/app/views/shared/icons/_rss.html.erb +3 -0
  175. data/app/views/shared/icons/_save.html.erb +3 -0
  176. data/app/views/shared/icons/_search.html.erb +3 -0
  177. data/app/views/shared/icons/_search_minus.html.erb +10 -0
  178. data/app/views/shared/icons/_search_plus.html.erb +10 -0
  179. data/app/views/shared/icons/_server_error.html.erb +6 -0
  180. data/app/views/shared/icons/_share.html.erb +3 -0
  181. data/app/views/shared/icons/_shield_check.html.erb +3 -0
  182. data/app/views/shared/icons/_sign_in.html.erb +3 -0
  183. data/app/views/shared/icons/_spinner.html.erb +4 -0
  184. data/app/views/shared/icons/_star.html.erb +3 -0
  185. data/app/views/shared/icons/_store.html.erb +10 -0
  186. data/app/views/shared/icons/_sun.html.erb +3 -0
  187. data/app/views/shared/icons/_sync.html.erb +3 -0
  188. data/app/views/shared/icons/_table.html.erb +3 -0
  189. data/app/views/shared/icons/_tag.html.erb +3 -0
  190. data/app/views/shared/icons/_tags.html.erb +11 -0
  191. data/app/views/shared/icons/_tools.html.erb +4 -0
  192. data/app/views/shared/icons/_trash.html.erb +3 -0
  193. data/app/views/shared/icons/_undo.html.erb +3 -0
  194. data/app/views/shared/icons/_unlock.html.erb +3 -0
  195. data/app/views/shared/icons/_upload.html.erb +3 -0
  196. data/app/views/shared/icons/_user.html.erb +3 -0
  197. data/app/views/shared/icons/_user_circle.html.erb +10 -0
  198. data/app/views/shared/icons/_user_plus.html.erb +10 -0
  199. data/app/views/shared/icons/_video.html.erb +3 -0
  200. data/app/views/shared/icons/_wrench.html.erb +11 -0
  201. data/app/views/style_guide/index.html.erb +77 -0
  202. data/app/views/style_guide/sections/_alerts.html.erb +114 -0
  203. data/app/views/style_guide/sections/_badges.html.erb +78 -0
  204. data/app/views/style_guide/sections/_buttons.html.erb +130 -0
  205. data/app/views/style_guide/sections/_cards.html.erb +84 -0
  206. data/app/views/style_guide/sections/_colors.html.erb +106 -0
  207. data/app/views/style_guide/sections/_file_upload.html.erb +135 -0
  208. data/app/views/style_guide/sections/_forms.html.erb +129 -0
  209. data/app/views/style_guide/sections/_gradients.html.erb +253 -0
  210. data/app/views/style_guide/sections/_header.html.erb +12 -0
  211. data/app/views/style_guide/sections/_icons.html.erb +55 -0
  212. data/app/views/style_guide/sections/_images.html.erb +40 -0
  213. data/app/views/style_guide/sections/_loading.html.erb +242 -0
  214. data/app/views/style_guide/sections/_pagination.html.erb +212 -0
  215. data/app/views/style_guide/sections/_profile_components.html.erb +203 -0
  216. data/app/views/style_guide/sections/_theme_switcher.html.erb +72 -0
  217. data/app/views/style_guide/sections/_typography.html.erb +65 -0
  218. data/bin/ai-optimize-claude-md +540 -0
  219. data/bin/ai-review-local +345 -0
  220. data/bin/ai-security-review +585 -0
  221. data/bin/brakeman +9 -0
  222. data/bin/install-hooks +57 -0
  223. data/bin/rake +7 -0
  224. data/bin/rubocop +10 -0
  225. data/bin/verify_setup.rb +31 -0
  226. data/config/brakeman.ignore +28 -0
  227. data/config/initializers/neon_sakura.rb +15 -0
  228. data/config/license_overrides.yml +13 -0
  229. data/config/routes.rb +21 -0
  230. data/config/theme_mappings.yml +61 -0
  231. data/docs/PRYSM_ASSETS.md +210 -0
  232. data/docs/plans/extract_ai_reviewer_plan.md +151 -0
  233. data/docs/plans/neon_sakura_gem_plan.md +138 -0
  234. data/lib/neon_sakura/configuration.rb +94 -0
  235. data/lib/neon_sakura/engine.rb +48 -0
  236. data/lib/neon_sakura/icon_helper.rb +54 -0
  237. data/lib/neon_sakura/profile_helper.rb +24 -0
  238. data/lib/neon_sakura/stylesheet_helper.rb +40 -0
  239. data/lib/neon_sakura/theme_helper.rb +63 -0
  240. data/lib/neon_sakura/theme_importer.rb +112 -0
  241. data/lib/neon_sakura/version.rb +5 -0
  242. data/lib/neon_sakura.rb +13 -0
  243. data/neon_sakura.gemspec +50 -0
  244. data/package.json +18 -0
  245. data/scripts/git-hooks/post-merge +132 -0
  246. data/scripts/git-hooks/pre-commit +123 -0
  247. data/scripts/git-hooks/pre-push +127 -0
  248. data/scripts/license-check.rb +587 -0
  249. data/settings.local.json +12 -0
  250. data/yarn.lock +778 -0
  251. metadata +503 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 252c8fb14c8fa6807d04e69ed6dc68afa5598968ec6adac8fd2bb9bf328ea23d
4
+ data.tar.gz: 4217db78b88bbf5e32007a8312328f05ced5adc6ded5825e5e00a3f984353d7a
5
+ SHA512:
6
+ metadata.gz: 571fb6432c2a02e8e7c72c6065bd3f5d9250af4e04751ba4868d3e6f7e205206c0914ec4580084731497c95521be46777cbc980231dd58bffa342efeddad0045
7
+ data.tar.gz: 03277b449d9b0ae5e81640f9bdcc4cc87957068a39fb76b9d57f425e736d8d1099115b3ec88d54cef9a7c1a97e5c06da6c083870709f3c38034cbff5843e2b4c
@@ -0,0 +1,182 @@
1
+ # AI Reviewer Shared Components
2
+
3
+ This directory contains shared components used by all AI reviewer systems (GitHub Actions workflows and local Ollama script).
4
+
5
+ ## Files
6
+
7
+ ### `build-system-prompt.sh`
8
+ **Purpose**: System prompt for AI code reviews (single source of truth)
9
+
10
+ **Usage**:
11
+ ```bash
12
+ .ai-reviewer/build-system-prompt.sh > system.txt
13
+ ```
14
+
15
+ **Contains**:
16
+ - Project stack description (Rails 8, SQLite, SolidQueue, etc.)
17
+ - Review focus areas (Security, Code Quality, Style, Testing, Architecture)
18
+ - Review format template
19
+ - Verdict options (COMMENT, REQUEST_CHANGES)
20
+
21
+ **When to modify**:
22
+ - Adding new review criteria
23
+ - Updating project stack information
24
+ - Changing review format
25
+ - Adjusting focus areas
26
+
27
+ ### `extract-claude-sections.sh`
28
+ **Purpose**: Extract comprehensive sections from CLAUDE.md for review context
29
+
30
+ **Usage**:
31
+ ```bash
32
+ .ai-reviewer/extract-claude-sections.sh CLAUDE.md
33
+ ```
34
+
35
+ **Extracts**:
36
+ - Quick Notes
37
+ - Essential Commands
38
+ - Stack
39
+ - Dev Rules
40
+ - UI & Styling
41
+ - Security
42
+ - Code Style
43
+ - Search Services
44
+ - Testing
45
+ - Pull Requests
46
+ - AI PR Reviewer
47
+
48
+ **Output**: Up to 8000 characters of relevant guidelines
49
+
50
+ **When to modify**:
51
+ - Adding new CLAUDE.md sections to include
52
+ - Changing extraction logic
53
+ - Adjusting character limits
54
+
55
+ ## Architecture
56
+
57
+ ```
58
+ ┌─────────────────────────────────────────────────────────────┐
59
+ │ AI Reviewer System │
60
+ └─────────────────────────────────────────────────────────────┘
61
+
62
+
63
+ ┌─────────────────────┼─────────────────────┐
64
+ │ │ │
65
+ ▼ ▼ ▼
66
+ ┌───────────────┐ ┌──────────────────┐ ┌──────────────┐
67
+ │ Automatic │ │ Comment- │ │ Local │
68
+ │ PR Review │ │ Triggered │ │ Ollama │
69
+ │ (Workflow) │ │ Review │ │ Script │
70
+ │ │ │ (Workflow) │ │ │
71
+ └───────┬───────┘ └────────┬─────────┘ └──────┬───────┘
72
+ │ │ │
73
+ │ │ │
74
+ └────────────────────┼────────────────────┘
75
+
76
+
77
+ ┌────────────────────────┐
78
+ │ Shared Components │
79
+ │ │
80
+ │ • build-system- │
81
+ │ prompt.sh │
82
+ │ • extract-claude- │
83
+ │ sections.sh │
84
+ └────────────────────────┘
85
+ ```
86
+
87
+ ## Usage in Workflows
88
+
89
+ ### GitHub Actions (Automatic & Comment-Triggered)
90
+
91
+ ```yaml
92
+ - name: Build prompts
93
+ run: |
94
+ # Use shared system prompt
95
+ .ai-reviewer/build-system-prompt.sh > system.txt
96
+
97
+ # Extract CLAUDE.md sections
98
+ CLAUDE_MD=$(.ai-reviewer/extract-claude-sections.sh CLAUDE.md)
99
+
100
+ # Build user prompt with context
101
+ echo "**PR:** $PR_TITLE" > user.txt
102
+ # ... add more context
103
+ ```
104
+
105
+ ### Local Ollama Script
106
+
107
+ ```bash
108
+ # In bin/ai-review-local
109
+ if [ -f ".ai-reviewer/build-system-prompt.sh" ]; then
110
+ .ai-reviewer/build-system-prompt.sh > "$TEMP_DIR/system.txt"
111
+ fi
112
+
113
+ if [ -f "CLAUDE.md" ] && [ -f ".ai-reviewer/extract-claude-sections.sh" ]; then
114
+ CLAUDE_MD=$(.ai-reviewer/extract-claude-sections.sh CLAUDE.md)
115
+ fi
116
+ ```
117
+
118
+ ## Testing Changes
119
+
120
+ ### 1. Test Locally
121
+ ```bash
122
+ # Test system prompt generation
123
+ .ai-reviewer/build-system-prompt.sh
124
+
125
+ # Test CLAUDE.md extraction
126
+ .ai-reviewer/extract-claude-sections.sh CLAUDE.md
127
+
128
+ # Test full local review
129
+ bin/ai-review-local
130
+ ```
131
+
132
+ ### 2. Test on PR
133
+ ```bash
134
+ # Create a test PR
135
+ git checkout -b test-ai-reviewer
136
+ # Make some changes
137
+ git add .
138
+ git commit -m "Test AI reviewer changes"
139
+ git push -u origin test-ai-reviewer
140
+
141
+ # Create PR and wait for automatic review
142
+ # Or trigger with: @ai-review
143
+ ```
144
+
145
+ ## Configuration
146
+
147
+ See `../.ai-reviewer-config.yml` for configuration reference (not currently used by scripts, but documents the intended structure).
148
+
149
+ ## Best Practices
150
+
151
+ 1. **Always test locally first** - Use `bin/ai-review-local` to verify prompt changes
152
+ 2. **Keep prompts focused** - Aim for clear, actionable review criteria
153
+ 3. **Update all systems together** - Changes to shared components affect all reviewers
154
+ 4. **Document changes** - Update this README when adding new components
155
+ 5. **Version control** - All changes should be committed and tested on PRs
156
+
157
+ ## Troubleshooting
158
+
159
+ ### System prompt not found
160
+ ```
161
+ Error: Shared system prompt script not found
162
+ ```
163
+ **Solution**: Ensure you're running from the repository root and `.ai-reviewer/build-system-prompt.sh` exists.
164
+
165
+ ### CLAUDE.md extraction fails
166
+ ```
167
+ CLAUDE.md not found
168
+ ```
169
+ **Solution**: Script gracefully handles missing CLAUDE.md. Check file exists at repository root.
170
+
171
+ ### Permission denied
172
+ ```
173
+ Permission denied: .ai-reviewer/build-system-prompt.sh
174
+ ```
175
+ **Solution**: Make scripts executable: `chmod +x .ai-reviewer/*.sh`
176
+
177
+ ## Related Documentation
178
+
179
+ - [AI PR Reviewer Documentation](../docs/AI_PR_REVIEWER.md)
180
+ - [CLAUDE.md](../CLAUDE.md)
181
+ - [GitHub Workflows](../.github/workflows/)
182
+ - [Local Review Script](../bin/ai-review-local)
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # AI PR Reviewer for neon_sakura gem
4
+ # This script is run by the AI reviewer to perform code reviews on PRs
5
+
6
+ set -euo pipefail
7
+
8
+ # Check if we're in the right directory
9
+ if [ ! -f "CLAUDE.md" ]; then
10
+ echo "Error: Not in neon_sakura gem directory (CLAUDE.md not found)"
11
+ exit 1
12
+ fi
13
+
14
+ # Get the PR description and files modified
15
+ PR_DESCRIPTION_FILE=".pr-description"
16
+ if [ -f "$PR_DESCRIPTION_FILE" ]; then
17
+ PR_DESCRIPTION=$(cat "$PR_DESCRIPTION_FILE")
18
+ else
19
+ PR_DESCRIPTION="No description provided"
20
+ fi
21
+
22
+ # Extract relevant sections from CLAUDE.md for context
23
+ echo "Extracting context from CLAUDE.md..."
24
+ CONTEXT=$(./.ai-reviewer/extract-claude-sections.sh)
25
+
26
+ # Build system prompt for AI review
27
+ echo "Building system prompt..."
28
+ SYSTEM_PROMPT=$(./.ai-reviewer/build-system-prompt.sh)
29
+
30
+ # Run the AI review process using Claude (this would be the actual AI review call)
31
+ # For demonstration purposes, we'll create a basic output file
32
+ echo "Starting AI review for neon_sakura gem..."
33
+
34
+ # Create a basic review result file
35
+ cat > review-result.md << 'EOF'
36
+ # AI Code Review for neon_sakura gem
37
+
38
+ ## Summary
39
+ This pull request updates the AI reviewer configuration for the neon_sakura gem, updating documentation and system prompts to align with the gem's specific requirements.
40
+
41
+ ## Critical Issues
42
+ None
43
+
44
+ ## Issues
45
+ None
46
+
47
+ ## Recommendations
48
+ None
49
+
50
+ ## Verdict
51
+ **Status:** COMMENT
52
+
53
+ The changes update the documentation and system prompts to correctly reflect the neon_sakura gem project context rather than the Artemis project. This ensures the AI reviewer provides accurate feedback for this specific gem.
54
+ EOF
55
+
56
+ echo "AI review complete. Results saved to review-result.md"
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env bash
2
+ # Build system prompt for AI code reviews
3
+ # This is the shared source of truth for all AI review prompts
4
+
5
+ cat <<'SYSEND'
6
+ You are an expert Rails 8 code reviewer for the Neon Sakura gem project.
7
+
8
+ **Project Stack:**
9
+ - Rails 8, SQLite (3 databases: main, queue, cache)
10
+ - SolidQueue, Puma, Propshaft
11
+ - Turbo/Stimulus, Pagy, Oj, Node 24
12
+
13
+ **Review Focus Areas:**
14
+
15
+ 1. **Security (CRITICAL):**
16
+ - OWASP Top 10 vulnerabilities (SQL injection, XSS, CSRF, etc.)
17
+ - Path traversal attacks in file operations
18
+ - Insecure redirects (must use `only_path: true`)
19
+ - Mass assignment vulnerabilities
20
+ - Exposed secrets or credentials
21
+ - External links must have `rel: "noopener noreferrer"`
22
+ - Proper use of `sanitize` over `raw` for HTML
23
+ - JavaScript: No `innerHTML`, use `addEventListener`, proper escaping with `<%= j variable %>`
24
+
25
+ 2. **Code Quality:**
26
+ - Rails conventions and best practices (Rails 8)
27
+ - DRY principle (Don't Repeat Yourself)
28
+ - Proper error handling and edge cases
29
+ - N+1 query prevention
30
+ - Performance considerations
31
+ - Service object patterns
32
+ - Proper use of Rails generators
33
+
34
+ 3. **Style & Conventions:**
35
+ - Ruby/JS/CSS/HTML: 2 spaces indentation
36
+ - Python: 4 spaces indentation
37
+ - Line length: 120 chars (Ruby), 88 (Python)
38
+ - No tabs, no trailing whitespace
39
+ - Rails Omakase style compliance
40
+ - Use Oj (`Oj.load/dump`) instead of JSON (2-10x faster)
41
+
42
+ 4. **UI & Styling (Dark Theme):**
43
+ - **NEVER use inline styles** (`style="..."` attributes)
44
+ - **NEVER use embedded `<style>` tags**
45
+ - All styles must be in CSS files: `app/assets/stylesheets/`
46
+ - Use existing utility classes from `base.css`
47
+ - Dark theme color palette (bg-gray-900, bg-gray-800, text-white, text-cyan-300, etc.)
48
+ - WCAG 2.1 AA accessibility compliance
49
+ - Proper `aria-label` on forms and interactive elements
50
+ - Responsive design (mobile-first)
51
+
52
+ 5. **Testing:**
53
+ - Minimum 80% overall test coverage (enforced by CI)
54
+ - Minimum 20% per-file coverage
55
+ - No coverage drops allowed
56
+ - No skipped tests (`skip` is forbidden)
57
+ - Use WebMock for HTTP mocking (NEVER use `define_method` globally - causes test pollution)
58
+ - Health checks for service classes: `domain_up?`, `search_working?`
59
+ - Test both success and error cases
60
+ - Fixtures for WebMock responses
61
+
62
+ 6. **Architecture Patterns:**
63
+ - **Search Services Pattern:**
64
+ ```ruby
65
+ def initialize(bypass_cache: false, **options) # Config only, NO search_term
66
+ @bypass_cache = bypass_cache
67
+ end
68
+
69
+ def search(search_term) # search_term HERE
70
+ search_with_benchmark(search_term)
71
+ end
72
+ ```
73
+ - Use `HttpRequestService` with 24h HTTP cache
74
+ - Benchmark execution time for searches
75
+ - Sort results by date (newest first)
76
+ - Services return structured data (arrays of hashes)
77
+
78
+ 7. **Asset Pipeline (Propshaft):**
79
+ - No preprocessing in dev, auto-digest in prod
80
+ - CSS organization via `app/assets/stylesheets/application.css`
81
+ - No inline styles or embedded style tags
82
+ - Check that new CSS is properly imported in application.css
83
+
84
+ 8. **Git Hooks & PR Requirements:**
85
+ - PR descriptions must start with "# What does this PR do?"
86
+ - Pre-commit: RuboCop, Brakeman, Bundle Audit, migrations, secrets
87
+ - Pre-push: Schema consistency, asset compilation, TODO/FIXME
88
+ - Never skip hooks without good reason
89
+
90
+ **IMPORTANT RULES:**
91
+ - Be EXTREMELY CONCISE - focus only on significant issues
92
+ - NEVER repeat the same issue
93
+ - Limit each section to MAX 5 unique issues
94
+ - ONE issue per file:line location
95
+ - Group similar issues: "Multiple instances of X in file.rb"
96
+ - Omit minor style issues if code quality is good
97
+
98
+ **Review Format (CONCISE):**
99
+
100
+ ## Summary
101
+ [1 sentence on overall assessment]
102
+
103
+ ## Critical Issues
104
+ [ONLY critical security/breaking changes - MAX 3]
105
+ [Format: `file:line - Issue`]
106
+ [If none: "None"]
107
+
108
+ ## Issues
109
+ [Significant problems only - MAX 5]
110
+ [Format: `file:line - Issue`]
111
+ [If none: "Looks good"]
112
+
113
+ ## Recommendations
114
+ [1-2 key suggestions, if any]
115
+
116
+ ## Verdict
117
+ **Status:** [COMMENT | REQUEST_CHANGES]
118
+
119
+ **CRITICAL ISSUE POLICY:**
120
+ Only use REQUEST_CHANGES if the PR contains one or more of these CRITICAL issues:
121
+ - **Security vulnerabilities**: SQL injection, XSS, path traversal, exposed secrets, insecure redirects
122
+ - **Breaking changes**: Code that would crash the application or cause runtime errors
123
+ - **Data loss risks**: Code that could corrupt or lose user data
124
+ - **Major security concerns**: Missing authentication/authorization, insecure external links
125
+
126
+ For ALL other issues, use COMMENT:
127
+ - Code quality issues (DRY violations, naming, refactoring suggestions)
128
+ - Style violations (indentation, line length, formatting)
129
+ - Missing or incomplete tests
130
+ - Performance suggestions (N+1 queries, inefficient algorithms)
131
+ - Minor bugs that don't break functionality
132
+ - Architecture suggestions
133
+ - Documentation improvements
134
+
135
+ **Default to COMMENT unless you find a CRITICAL issue listed above.**
136
+ SYSEND
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env bash
2
+ # Extract comprehensive sections from CLAUDE.md for AI review context
3
+ # This provides the AI with full project guidelines
4
+
5
+ set -euo pipefail
6
+
7
+ CLAUDE_FILE="${1:-CLAUDE.md}"
8
+
9
+ if [ ! -f "$CLAUDE_FILE" ]; then
10
+ echo "CLAUDE.md not found" >&2
11
+ exit 0
12
+ fi
13
+
14
+ # Extract comprehensive sections with more context
15
+ # Includes: Quick Notes, Essential Commands, Stack, Dev Rules, UI & Styling,
16
+ # Security, Code Style, Search Services, Testing, Pull Requests, AI PR Reviewer
17
+
18
+ cat "$CLAUDE_FILE" | awk '
19
+ # Track section depth
20
+ /^# / { h1=$0; h2=""; h3=""; next }
21
+ /^## / { h2=$0; h3=""; next }
22
+ /^### / { h3=$0; next }
23
+
24
+ # Include these major sections and their subsections
25
+ h1 ~ /CLAUDE.md/ ||
26
+ h2 ~ /Quick Notes|Essential Commands|Stack|Dev Rules|UI & Styling|Security|Code Style|Search Services|Testing|Pull Requests|AI PR Reviewer/ {
27
+ if (h1) { print h1; h1="" }
28
+ if (h2) { print h2; h2="" }
29
+ if (h3) { print h3; h3="" }
30
+ print
31
+ }
32
+ ' | head -c 8000
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Test script for AI reviewer
4
+ # This script verifies the AI reviewer system is working properly
5
+
6
+ echo "Testing AI reviewer system for neon_sakura gem..."
7
+
8
+ # Check if required files exist
9
+ echo "Checking for required files..."
10
+
11
+ if [ -f ".ai-reviewer/build-system-prompt.sh" ]; then
12
+ echo "✓ build-system-prompt.sh exists"
13
+ else
14
+ echo "✗ build-system-prompt.sh missing"
15
+ exit 1
16
+ fi
17
+
18
+ if [ -f ".ai-reviewer/extract-claude-sections.sh" ]; then
19
+ echo "✓ extract-claude-sections.sh exists"
20
+ else
21
+ echo "✗ extract-claude-sections.sh missing"
22
+ exit 1
23
+ fi
24
+
25
+ if [ -f ".ai-reviewer/ai-reviewer.sh" ]; then
26
+ echo "✓ ai-reviewer.sh exists"
27
+ else
28
+ echo "✗ ai-reviewer.sh missing"
29
+ exit 1
30
+ fi
31
+
32
+ if [ -f "CLAUDE.md" ]; then
33
+ echo "✓ CLAUDE.md exists"
34
+ else
35
+ echo "✗ CLAUDE.md missing"
36
+ exit 1
37
+ fi
38
+
39
+ echo "All required files present!"
40
+ echo "AI reviewer system is ready for use with neon_sakura gem."
@@ -0,0 +1,190 @@
1
+ # AI Reviewer Configuration
2
+ # Shared configuration for GitHub Actions workflows and local Ollama script
3
+
4
+ # System prompt for AI code reviews
5
+ system_prompt: |
6
+ You are an expert Rails 8 code reviewer for the Neon Sakura gem project.
7
+
8
+ **Project Stack:**
9
+ - Rails 8, SQLite (3 databases: main, queue, cache)
10
+ - SolidQueue, Puma, Propshaft
11
+ - Turbo/Stimulus, Pagy, Oj, Node 24
12
+
13
+ **Review Focus Areas:**
14
+
15
+ 1. **Security (CRITICAL):**
16
+ - OWASP Top 10 vulnerabilities (SQL injection, XSS, CSRF, etc.)
17
+ - Path traversal attacks in file operations
18
+ - Insecure redirects (must use `only_path: true`)
19
+ - Mass assignment vulnerabilities
20
+ - Exposed secrets or credentials
21
+ - External links must have `rel: "noopener noreferrer"`
22
+ - Proper use of `sanitize` over `raw` for HTML
23
+ - JavaScript: No `innerHTML`, use `addEventListener`, proper escaping with `<%= j variable %>`
24
+
25
+ 2. **Code Quality:**
26
+ - Rails conventions and best practices (Rails 8)
27
+ - DRY principle (Don't Repeat Yourself)
28
+ - Proper error handling and edge cases
29
+ - N+1 query prevention
30
+ - Performance considerations
31
+ - Service object patterns
32
+ - Proper use of Rails generators
33
+
34
+ 3. **Style & Conventions:**
35
+ - Ruby/JS/CSS/HTML: 2 spaces indentation
36
+ - Python: 4 spaces indentation
37
+ - Line length: 120 chars (Ruby), 88 (Python)
38
+ - No tabs, no trailing whitespace
39
+ - Rails Omakase style compliance
40
+ - Use Oj (`Oj.load/dump`) instead of JSON (2-10x faster)
41
+
42
+ 4. **UI & Styling (Dark Theme):**
43
+ - **NEVER use inline styles** (`style="..."` attributes)
44
+ - **NEVER use embedded `<style>` tags**
45
+ - All styles must be in CSS files: `app/assets/stylesheets/`
46
+ - Use existing utility classes from `base.css`
47
+ - Dark theme color palette (bg-gray-900, bg-gray-800, text-white, text-cyan-300, etc.)
48
+ - WCAG 2.1 AA accessibility compliance
49
+ - Proper `aria-label` on forms and interactive elements
50
+ - Responsive design (mobile-first)
51
+
52
+ 5. **Testing:**
53
+ - Minimum 80% overall test coverage (enforced by CI)
54
+ - Minimum 20% per-file coverage
55
+ - No coverage drops allowed
56
+ - No skipped tests (`skip` is forbidden)
57
+ - Use WebMock for HTTP mocking (NEVER use `define_method` globally - causes test pollution)
58
+ - Health checks for service classes: `domain_up?`, `search_working?`
59
+ - Test both success and error cases
60
+ - Fixtures for WebMock responses
61
+
62
+ 6. **Architecture Patterns:**
63
+ - **Search Services Pattern:**
64
+ ```ruby
65
+ def initialize(bypass_cache: false, **options) # Config only, NO search_term
66
+ @bypass_cache = bypass_cache
67
+ end
68
+
69
+ def search(search_term) # search_term HERE
70
+ search_with_benchmark(search_term)
71
+ end
72
+ ```
73
+ - Use `HttpRequestService` with 24h HTTP cache
74
+ - Benchmark execution time for searches
75
+ - Sort results by date (newest first)
76
+ - Services return structured data (arrays of hashes)
77
+
78
+ 7. **Asset Pipeline (Propshaft):**
79
+ - No preprocessing in dev, auto-digest in prod
80
+ - CSS organization via `app/assets/stylesheets/application.css`
81
+ - No inline styles or embedded style tags
82
+ - Check that new CSS is properly imported in application.css
83
+
84
+ 8. **Git Hooks & PR Requirements:**
85
+ - PR descriptions must start with "# What does this PR do?"
86
+ - Pre-commit: RuboCop, Brakeman, Bundle Audit, migrations, secrets
87
+ - Pre-push: Schema consistency, asset compilation, TODO/FIXME
88
+ - Never skip hooks without good reason
89
+
90
+ **Review Format:**
91
+ Be concise and actionable. Focus on significant issues only.
92
+
93
+ ## Summary
94
+ [1-2 sentences describing the changes and overall assessment]
95
+
96
+ ## Critical Issues
97
+ [ONLY list critical security vulnerabilities or breaking changes]
98
+ [Use format: `file_path:line_number - Description`]
99
+ [If none, write "None found"]
100
+
101
+ ## Code Quality Issues
102
+ [List significant code quality problems]
103
+ [Use format: `file_path:line_number - Description`]
104
+ [If none, write "Looks good"]
105
+
106
+ ## Style & Convention Issues
107
+ [List style violations and convention mismatches]
108
+ [Use format: `file_path:line_number - Description`]
109
+ [If none, write "Follows conventions"]
110
+
111
+ ## Testing Gaps
112
+ [List missing tests or coverage issues]
113
+ [If none, write "Adequate coverage"]
114
+
115
+ ## Recommendations
116
+ [Optional: Suggest improvements or alternative approaches]
117
+
118
+ ## Previous Review Follow-up
119
+ [If previous reviews exist, check:]
120
+ [1. Were previous issues addressed?]
121
+ [2. Are there new changes since last review?]
122
+
123
+ ## Verdict
124
+ [Choose ONE: COMMENT | REQUEST_CHANGES]
125
+ [NEVER use APPROVE - GitHub does not allow bot/action approvals]
126
+
127
+ # Model configuration
128
+ models:
129
+ github:
130
+ name: "Codestral-2501"
131
+ endpoint: "https://models.inference.ai.azure.com/chat/completions"
132
+ temperature: 0.3
133
+ max_tokens: 4000
134
+
135
+ ollama:
136
+ name: "codestral:latest"
137
+ endpoint: "http://localhost:11434/api/chat"
138
+ temperature: 0.3
139
+ max_tokens: 4000
140
+
141
+ # Context configuration
142
+ context:
143
+ # Maximum characters for diff
144
+ max_diff_chars: 15000
145
+
146
+ # Maximum characters for previous reviews
147
+ max_previous_reviews_chars: 3000
148
+
149
+ # Maximum number of previous reviews to include
150
+ max_previous_reviews_count: 3
151
+
152
+ # Maximum number of changed files to list
153
+ max_changed_files: 100
154
+
155
+ # CLAUDE.md sections to include (comprehensive)
156
+ claude_md_sections:
157
+ - "Quick Notes"
158
+ - "Essential Commands"
159
+ - "Stack"
160
+ - "Dev Rules"
161
+ - "UI & Styling"
162
+ - "Asset Pipeline Architecture"
163
+ - "CSS File Structure"
164
+ - "Adding New Styles"
165
+ - "Dark Theme Color Palette"
166
+ - "Accessibility Requirements"
167
+ - "Security"
168
+ - "Code Style"
169
+ - "Search Services"
170
+ - "Testing"
171
+ - "Pull Requests"
172
+ - "AI PR Reviewer"
173
+
174
+ # Include full CLAUDE.md on first review only
175
+ full_claude_md_on_first: true
176
+
177
+ # File patterns to ignore in reviews
178
+ ignore_patterns:
179
+ - "db/schema.rb"
180
+ - "*.lock"
181
+ - "coverage/**"
182
+ - "tmp/**"
183
+ - "log/**"
184
+ - "node_modules/**"
185
+ - "public/assets/**"
186
+
187
+ # Markers for code sections to ignore
188
+ ignore_markers:
189
+ start: "ai-review-ignore-start"
190
+ end: "ai-review-ignore-end"
@@ -0,0 +1,12 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: "/"
5
+ schedule:
6
+ interval: weekly
7
+ open-pull-requests-limit: 10
8
+ - package-ecosystem: github-actions
9
+ directory: "/"
10
+ schedule:
11
+ interval: weekly
12
+ open-pull-requests-limit: 10