ima-claude 2.9.0

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 (182) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +463 -0
  3. package/dist/cli.js +1064 -0
  4. package/package.json +49 -0
  5. package/platforms/claude/adapter.ts +115 -0
  6. package/platforms/junie/adapter.ts +254 -0
  7. package/platforms/junie/agents-template.md +113 -0
  8. package/platforms/junie/hook-translations.md +84 -0
  9. package/platforms/shared/detector.ts +27 -0
  10. package/platforms/shared/installer.ts +202 -0
  11. package/platforms/shared/types.ts +78 -0
  12. package/plugins/ima-claude/.claude-plugin/plugin.json +25 -0
  13. package/plugins/ima-claude/agents/explorer.md +30 -0
  14. package/plugins/ima-claude/agents/implementer.md +30 -0
  15. package/plugins/ima-claude/agents/memory.md +42 -0
  16. package/plugins/ima-claude/agents/reviewer.md +53 -0
  17. package/plugins/ima-claude/agents/tester.md +33 -0
  18. package/plugins/ima-claude/agents/wp-developer.md +46 -0
  19. package/plugins/ima-claude/hooks/README.md +145 -0
  20. package/plugins/ima-claude/hooks/atlassian_prereqs.py +112 -0
  21. package/plugins/ima-claude/hooks/block_sed_edits.py +59 -0
  22. package/plugins/ima-claude/hooks/bootstrap.sh +90 -0
  23. package/plugins/ima-claude/hooks/bootstrap_utility_check.py +94 -0
  24. package/plugins/ima-claude/hooks/composer_autoload_check.py +70 -0
  25. package/plugins/ima-claude/hooks/docs_organization.py +104 -0
  26. package/plugins/ima-claude/hooks/enforce_rg_over_grep.py +56 -0
  27. package/plugins/ima-claude/hooks/fp_utility_check.py +90 -0
  28. package/plugins/ima-claude/hooks/hook_logger.py +69 -0
  29. package/plugins/ima-claude/hooks/hooks.json +239 -0
  30. package/plugins/ima-claude/hooks/jira_issue_fetch.py +79 -0
  31. package/plugins/ima-claude/hooks/jquery_in_wordpress.py +92 -0
  32. package/plugins/ima-claude/hooks/memory_bootstrap.py +79 -0
  33. package/plugins/ima-claude/hooks/memory_store_reminder.py +75 -0
  34. package/plugins/ima-claude/hooks/prompt_coach.py +125 -0
  35. package/plugins/ima-claude/hooks/prompt_coach_digest.md +48 -0
  36. package/plugins/ima-claude/hooks/prompt_coach_system.md +30 -0
  37. package/plugins/ima-claude/hooks/sequential_thinking_check.py +81 -0
  38. package/plugins/ima-claude/hooks/serena_over_grep.py +96 -0
  39. package/plugins/ima-claude/hooks/serena_over_read.py +66 -0
  40. package/plugins/ima-claude/hooks/serena_project_check.py +133 -0
  41. package/plugins/ima-claude/hooks/sql_injection_check.py +73 -0
  42. package/plugins/ima-claude/hooks/task_master_after_plan.py +31 -0
  43. package/plugins/ima-claude/hooks/task_master_before_impl.py +93 -0
  44. package/plugins/ima-claude/hooks/tavily_extract_advanced.py +48 -0
  45. package/plugins/ima-claude/hooks/vestige_before_external.py +86 -0
  46. package/plugins/ima-claude/hooks/webfetch_to_tavily.py +42 -0
  47. package/plugins/ima-claude/hooks/websearch_to_tavily.py +41 -0
  48. package/plugins/ima-claude/hooks/wp_security_check.py +150 -0
  49. package/plugins/ima-claude/personalities/README.md +45 -0
  50. package/plugins/ima-claude/personalities/enable-40k.md +69 -0
  51. package/plugins/ima-claude/personalities/enable-templars.md +69 -0
  52. package/plugins/ima-claude/skills/.research-summary.md +340 -0
  53. package/plugins/ima-claude/skills/architect/SKILL.md +304 -0
  54. package/plugins/ima-claude/skills/compound-bridge/SKILL.md +200 -0
  55. package/plugins/ima-claude/skills/discourse/SKILL.md +440 -0
  56. package/plugins/ima-claude/skills/discourse-admin/SKILL.md +192 -0
  57. package/plugins/ima-claude/skills/discourse-admin/references/api-endpoints.md +441 -0
  58. package/plugins/ima-claude/skills/discourse-admin/references/gotchas.md +107 -0
  59. package/plugins/ima-claude/skills/discourse-admin/references/staging-defaults.md +98 -0
  60. package/plugins/ima-claude/skills/discourse-admin/scripts/discourse-admin.py +319 -0
  61. package/plugins/ima-claude/skills/docs-organize/SKILL.md +254 -0
  62. package/plugins/ima-claude/skills/docs-organize/templates/active-README.md +50 -0
  63. package/plugins/ima-claude/skills/docs-organize/templates/archive-README.md +57 -0
  64. package/plugins/ima-claude/skills/docs-organize/templates/docs-README.md +43 -0
  65. package/plugins/ima-claude/skills/docs-organize/templates/phase-archive-README.md +83 -0
  66. package/plugins/ima-claude/skills/docs-organize/templates/section-README.md +48 -0
  67. package/plugins/ima-claude/skills/docs-organize/templates/transient-README.md +79 -0
  68. package/plugins/ima-claude/skills/docs-organize/templates/transient-gitignore +9 -0
  69. package/plugins/ima-claude/skills/ember-discourse/SKILL.md +496 -0
  70. package/plugins/ima-claude/skills/functional-programmer/SKILL.md +258 -0
  71. package/plugins/ima-claude/skills/ima-bootstrap/SKILL.md +278 -0
  72. package/plugins/ima-claude/skills/ima-bootstrap/references/bootstrap-patterns.md +356 -0
  73. package/plugins/ima-claude/skills/ima-bootstrap/references/ima-brand.md +273 -0
  74. package/plugins/ima-claude/skills/ima-bootstrap/references/theme-integration.md +212 -0
  75. package/plugins/ima-claude/skills/ima-brand/SKILL.md +108 -0
  76. package/plugins/ima-claude/skills/ima-brand/references/brand-identity.md +140 -0
  77. package/plugins/ima-claude/skills/ima-brand/references/digital-standards.md +180 -0
  78. package/plugins/ima-claude/skills/ima-brand/references/visual-system.md +173 -0
  79. package/plugins/ima-claude/skills/ima-forms-expert/SKILL.md +175 -0
  80. package/plugins/ima-claude/skills/ima-forms-expert/references/container-components.md +154 -0
  81. package/plugins/ima-claude/skills/ima-forms-expert/references/examples.md +328 -0
  82. package/plugins/ima-claude/skills/ima-forms-expert/references/field-components.md +298 -0
  83. package/plugins/ima-claude/skills/ima-forms-expert/references/form-factory.md +193 -0
  84. package/plugins/ima-claude/skills/ima-forms-expert/references/quick-reference.md +153 -0
  85. package/plugins/ima-claude/skills/ima-forms-expert/references/validation-engine.md +336 -0
  86. package/plugins/ima-claude/skills/jira-checkpoint/SKILL.md +178 -0
  87. package/plugins/ima-claude/skills/jquery/SKILL.md +413 -0
  88. package/plugins/ima-claude/skills/js-fp/SKILL.md +463 -0
  89. package/plugins/ima-claude/skills/js-fp/core-principles.md +487 -0
  90. package/plugins/ima-claude/skills/js-fp/examples/pure-functions.js +260 -0
  91. package/plugins/ima-claude/skills/js-fp/examples/tests/pure-functions.test.js +262 -0
  92. package/plugins/ima-claude/skills/js-fp/references/anti-patterns.md +120 -0
  93. package/plugins/ima-claude/skills/js-fp/references/performance-patterns.md +116 -0
  94. package/plugins/ima-claude/skills/js-fp/references/testing-patterns.md +134 -0
  95. package/plugins/ima-claude/skills/js-fp-api/SKILL.md +280 -0
  96. package/plugins/ima-claude/skills/js-fp-api/examples/crud-endpoint.js +258 -0
  97. package/plugins/ima-claude/skills/js-fp-api/references/middleware-patterns.md +134 -0
  98. package/plugins/ima-claude/skills/js-fp-api/references/security-sql.md +110 -0
  99. package/plugins/ima-claude/skills/js-fp-api/references/validation-patterns.md +165 -0
  100. package/plugins/ima-claude/skills/js-fp-react/SKILL.md +447 -0
  101. package/plugins/ima-claude/skills/js-fp-react/examples/ProductCard.tsx +65 -0
  102. package/plugins/ima-claude/skills/js-fp-react/references/hooks-advanced.md +136 -0
  103. package/plugins/ima-claude/skills/js-fp-react/references/performance-patterns.md +175 -0
  104. package/plugins/ima-claude/skills/js-fp-vue/SKILL.md +322 -0
  105. package/plugins/ima-claude/skills/js-fp-vue/references/complete-examples.md +397 -0
  106. package/plugins/ima-claude/skills/js-fp-vue/references/composables-advanced.md +282 -0
  107. package/plugins/ima-claude/skills/js-fp-vue/references/reactivity-patterns.md +348 -0
  108. package/plugins/ima-claude/skills/js-fp-vue/references/testing.md +314 -0
  109. package/plugins/ima-claude/skills/js-fp-wordpress/SKILL.md +301 -0
  110. package/plugins/ima-claude/skills/js-fp-wordpress/references/ajax-patterns.md +192 -0
  111. package/plugins/ima-claude/skills/js-fp-wordpress/references/event-patterns.md +136 -0
  112. package/plugins/ima-claude/skills/js-fp-wordpress/references/wp-integration.md +248 -0
  113. package/plugins/ima-claude/skills/livecanvas/SKILL.md +209 -0
  114. package/plugins/ima-claude/skills/livecanvas/references/livecanvas-features.md +311 -0
  115. package/plugins/ima-claude/skills/livecanvas/references/loops-and-logic.md +730 -0
  116. package/plugins/ima-claude/skills/livecanvas/references/picostrap.md +227 -0
  117. package/plugins/ima-claude/skills/mcp-atlassian/SKILL.md +339 -0
  118. package/plugins/ima-claude/skills/mcp-context7/SKILL.md +109 -0
  119. package/plugins/ima-claude/skills/mcp-memory/SKILL.md +182 -0
  120. package/plugins/ima-claude/skills/mcp-qdrant/SKILL.md +233 -0
  121. package/plugins/ima-claude/skills/mcp-sequential/SKILL.md +149 -0
  122. package/plugins/ima-claude/skills/mcp-serena/SKILL.md +174 -0
  123. package/plugins/ima-claude/skills/mcp-tavily/SKILL.md +118 -0
  124. package/plugins/ima-claude/skills/mcp-vestige/SKILL.md +259 -0
  125. package/plugins/ima-claude/skills/php-authnet/SKILL.md +275 -0
  126. package/plugins/ima-claude/skills/php-authnet/references/api-reference.md +624 -0
  127. package/plugins/ima-claude/skills/php-authnet/references/sandbox-testing.md +424 -0
  128. package/plugins/ima-claude/skills/php-fp/SKILL.md +333 -0
  129. package/plugins/ima-claude/skills/php-fp/examples/pure-functions.php +403 -0
  130. package/plugins/ima-claude/skills/php-fp/examples/tests/PureFunctionsTest.php +515 -0
  131. package/plugins/ima-claude/skills/php-fp/references/core-principles.md +277 -0
  132. package/plugins/ima-claude/skills/php-fp/references/testing-patterns.md +374 -0
  133. package/plugins/ima-claude/skills/php-fp-wordpress/SKILL.md +216 -0
  134. package/plugins/ima-claude/skills/php-fp-wordpress/references/fp-patterns.md +275 -0
  135. package/plugins/ima-claude/skills/php-fp-wordpress/references/plugin-architecture.md +295 -0
  136. package/plugins/ima-claude/skills/php-fp-wordpress/references/security-examples.md +203 -0
  137. package/plugins/ima-claude/skills/php-fp-wordpress/references/testing-strategy.md +259 -0
  138. package/plugins/ima-claude/skills/phpunit-wp/SKILL.md +716 -0
  139. package/plugins/ima-claude/skills/playwright/SKILL.md +434 -0
  140. package/plugins/ima-claude/skills/playwright/references/accessibility-testing.md +153 -0
  141. package/plugins/ima-claude/skills/playwright/references/ci-cd.md +268 -0
  142. package/plugins/ima-claude/skills/playwright/references/network-mocking.md +270 -0
  143. package/plugins/ima-claude/skills/playwright/references/visual-regression.md +215 -0
  144. package/plugins/ima-claude/skills/py-fp/SKILL.md +663 -0
  145. package/plugins/ima-claude/skills/py-fp/examples/pure-functions.py +185 -0
  146. package/plugins/ima-claude/skills/py-fp/examples/tests/test_pure_functions.py +244 -0
  147. package/plugins/ima-claude/skills/py-fp/references/core-principles.md +381 -0
  148. package/plugins/ima-claude/skills/py-fp/references/testing-patterns.md +283 -0
  149. package/plugins/ima-claude/skills/quasar-fp/SKILL.md +327 -0
  150. package/plugins/ima-claude/skills/quasar-fp/metadata.json +85 -0
  151. package/plugins/ima-claude/skills/quasar-fp/references/component-patterns.md +257 -0
  152. package/plugins/ima-claude/skills/quasar-fp/references/theme-integration.md +233 -0
  153. package/plugins/ima-claude/skills/quasar-fp/references/utility-classes.md +237 -0
  154. package/plugins/ima-claude/skills/quickstart/SKILL.md +129 -0
  155. package/plugins/ima-claude/skills/rails/SKILL.md +359 -0
  156. package/plugins/ima-claude/skills/resume-session/SKILL.md +68 -0
  157. package/plugins/ima-claude/skills/rg/SKILL.md +205 -0
  158. package/plugins/ima-claude/skills/ruby-fp/SKILL.md +336 -0
  159. package/plugins/ima-claude/skills/save-session/SKILL.md +81 -0
  160. package/plugins/ima-claude/skills/scorecard/SKILL.md +96 -0
  161. package/plugins/ima-claude/skills/skill-analyzer/SKILL.md +127 -0
  162. package/plugins/ima-claude/skills/skill-analyzer/references/advanced-checklist.md +44 -0
  163. package/plugins/ima-claude/skills/skill-analyzer/references/core-checklist.md +60 -0
  164. package/plugins/ima-claude/skills/skill-analyzer/scripts/analyze_skill.py +418 -0
  165. package/plugins/ima-claude/skills/skill-creator/LICENSE.txt +202 -0
  166. package/plugins/ima-claude/skills/skill-creator/SKILL.md +343 -0
  167. package/plugins/ima-claude/skills/skill-creator/references/output-patterns.md +82 -0
  168. package/plugins/ima-claude/skills/skill-creator/references/workflows.md +28 -0
  169. package/plugins/ima-claude/skills/skill-creator/scripts/init_skill.py +303 -0
  170. package/plugins/ima-claude/skills/skill-creator/scripts/package_skill.py +110 -0
  171. package/plugins/ima-claude/skills/skill-creator/scripts/quick_validate.py +103 -0
  172. package/plugins/ima-claude/skills/task-master/SKILL.md +51 -0
  173. package/plugins/ima-claude/skills/task-planner/SKILL.md +228 -0
  174. package/plugins/ima-claude/skills/task-runner/SKILL.md +192 -0
  175. package/plugins/ima-claude/skills/unit-testing/SKILL.md +198 -0
  176. package/plugins/ima-claude/skills/unit-testing/references/mock-patterns.md +181 -0
  177. package/plugins/ima-claude/skills/unit-testing/references/tdd-workflow.md +177 -0
  178. package/plugins/ima-claude/skills/unit-testing/references/test-strategy.md +126 -0
  179. package/plugins/ima-claude/skills/wp-local/SKILL.md +246 -0
  180. package/plugins/ima-claude/skills/wp-local/references/configuration.md +198 -0
  181. package/plugins/ima-claude/skills/wp-local/references/wp-cli-reference.md +406 -0
  182. package/plugins/ima-claude/skills/wp-local/scripts/wp-local.sh +61 -0
@@ -0,0 +1,359 @@
1
+ ---
2
+ name: "rails"
3
+ description: "Ruby on Rails conventions + security - strong parameters, ActiveRecord safety, CSRF, auth, secrets management"
4
+ ---
5
+
6
+ # Rails
7
+
8
+ Convention-over-configuration development on the happy path, with security non-negotiables that prevent the most common Rails vulnerabilities.
9
+
10
+ ## When to Use This Skill
11
+
12
+ - Building Rails controllers, models, services
13
+ - Reviewing Rails code for security or structure
14
+ - Adding features to an existing Rails application
15
+ - Discourse plugin development (see also `discourse` skill)
16
+
17
+ ## Core Philosophy
18
+
19
+ Rails has opinions. Work with them, not against them. The framework gives you:
20
+ - SQL injection protection via ActiveRecord (use it)
21
+ - CSRF protection by default (don't disable it)
22
+ - XSS protection via ERB auto-escaping (use `<%= %>`)
23
+ - Mass assignment protection via Strong Parameters (permit explicitly)
24
+
25
+ **Functional core still applies in Rails.** Business logic in service modules/plain Ruby objects. Keep models and controllers thin.
26
+
27
+ **Foundation**: Reference `../ruby-fp/SKILL.md` for Ruby FP core principles.
28
+
29
+ ## The 5 Non-Negotiable Security Practices
30
+
31
+ | Practice | Prevents | Rule |
32
+ |----------|----------|------|
33
+ | **Strong Parameters** | Mass assignment | `params.require(:model).permit(:field, ...)` on ALL controller actions |
34
+ | **Parameterized Queries** | SQL injection | ActiveRecord methods or `?`/named placeholders — NEVER string interpolation |
35
+ | **CSRF Protection** | CSRF | Never disable `protect_from_forgery`; use `form_with` helpers |
36
+ | **Before Actions (Auth)** | Unauthorized access | `before_action :authenticate_user!` or equivalent on ALL sensitive actions |
37
+ | **Secrets via Credentials** | Credential exposure | Rails credentials or ENV — never hardcode secrets in source |
38
+
39
+ ### Quick Reference: The Five in Code
40
+
41
+ ```ruby
42
+ # 1. Strong Parameters
43
+ def user_params
44
+ params.require(:user).permit(:name, :email, :bio)
45
+ # Never: params[:user] or params.permit!
46
+ end
47
+
48
+ # 2. Parameterized Queries — ActiveRecord keeps you safe
49
+ User.where(email: params[:email]) # safe
50
+ User.where("email = ?", params[:email]) # safe
51
+ User.where("email = :email", email: params[:email]) # safe
52
+ User.where("email = '#{params[:email]}'") # NEVER — SQL injection
53
+
54
+ # 3. CSRF — keep default, use form helpers
55
+ class ApplicationController < ActionController::Base
56
+ protect_from_forgery with: :exception # default — keep it
57
+ end
58
+ # form_with and form_for automatically include the token
59
+
60
+ # 4. Before action auth
61
+ class PostsController < ApplicationController
62
+ before_action :authenticate_user! # Devise
63
+ before_action :require_admin, only: [:destroy]
64
+
65
+ private
66
+ def require_admin
67
+ redirect_to root_path unless current_user&.admin?
68
+ end
69
+ end
70
+
71
+ # 5. Credentials — never hardcode
72
+ # config/credentials.yml.enc (encrypted)
73
+ # Access: Rails.application.credentials.stripe[:secret_key]
74
+ # ENV fallback: ENV.fetch('STRIPE_SECRET_KEY')
75
+ ```
76
+
77
+ ## ActiveRecord Safety
78
+
79
+ ```ruby
80
+ # SAFE — all these use parameterization internally
81
+ User.find(params[:id]) # auto-cast to integer
82
+ User.find_by(email: params[:email])
83
+ User.where(status: params[:status])
84
+ User.where("created_at > ?", 1.week.ago)
85
+
86
+ # SAFE — sanitize_sql_like for LIKE patterns
87
+ query = ActiveRecord::Base.sanitize_sql_like(params[:search])
88
+ User.where("name LIKE ?", "%#{query}%")
89
+
90
+ # UNSAFE — never do these
91
+ User.where("id = #{params[:id]}") # SQL injection
92
+ User.where("name LIKE '%#{params[:q]}%'") # SQL injection
93
+ User.find_by("email = '#{email}'") # SQL injection
94
+
95
+ # Raw SQL when needed — use sanitize or bind params
96
+ User.find_by_sql(["SELECT * FROM users WHERE token = ?", token])
97
+ ActiveRecord::Base.connection.execute(
98
+ ActiveRecord::Base.sanitize_sql(["UPDATE users SET x = ? WHERE id = ?", val, id])
99
+ )
100
+ ```
101
+
102
+ ## Mass Assignment
103
+
104
+ ```ruby
105
+ # BAD — never permit all, never skip permit
106
+ User.new(params[:user]) # bypasses strong params
107
+ User.update(params.permit!) # permits everything — dangerous
108
+
109
+ # GOOD — explicit whitelist
110
+ def user_params
111
+ params.require(:user).permit(:name, :email, :bio)
112
+ end
113
+
114
+ # Nested params
115
+ def post_params
116
+ params.require(:post).permit(:title, :body, tags: [], author: [:name, :email])
117
+ end
118
+
119
+ # Never permit sensitive fields
120
+ # role, admin, password_digest, confirmed_at — set these explicitly in code
121
+ def promote_to_admin
122
+ @user.update!(role: 'admin') # explicit, not from params
123
+ end
124
+ ```
125
+
126
+ ## XSS in Views
127
+
128
+ ```ruby
129
+ # ERB auto-escaping — always use <%= %> for user content
130
+ <%= user.name %> # safe — HTML-escaped
131
+ <%== user.name %> # UNSAFE — raw output, HTML injection risk
132
+ <%= raw user.name %> # UNSAFE — same as above
133
+ <%= user.name.html_safe %> # UNSAFE — marking untrusted content safe
134
+
135
+ # When you need to render HTML you control
136
+ <%= sanitize user.bio, tags: %w[b i em strong p] %>
137
+
138
+ # JavaScript context — never interpolate directly
139
+ <script>var name = "<%= user.name %>"</script> # UNSAFE — XSS via JS
140
+ # GOOD
141
+ <script>var data = <%= user.to_json.html_safe %></script> # if you control the data
142
+ # BEST — pass via data attributes
143
+ <div data-user-name="<%= user.name %>"></div>
144
+ ```
145
+
146
+ ## Authentication & Authorization Pattern
147
+
148
+ ```ruby
149
+ # Authentication — Devise is the Rails default
150
+ # Before action guards all sensitive routes
151
+ class ApplicationController < ActionController::Base
152
+ before_action :authenticate_user!
153
+
154
+ # Override to allow public actions
155
+ skip_before_action :authenticate_user!, only: [:index, :show]
156
+ end
157
+
158
+ # Authorization — policy objects (Pundit pattern or manual)
159
+ class PostPolicy
160
+ def initialize(user, post)
161
+ @user = user
162
+ @post = post
163
+ end
164
+
165
+ def update?
166
+ @user.admin? || @post.user_id == @user.id
167
+ end
168
+ end
169
+
170
+ # In controller
171
+ def update
172
+ @post = Post.find(params[:id])
173
+ policy = PostPolicy.new(current_user, @post)
174
+ return head :forbidden unless policy.update?
175
+ # ... update logic
176
+ end
177
+
178
+ # NEVER rely on hidden fields or client-side checks alone
179
+ # Always enforce auth server-side
180
+ ```
181
+
182
+ ## Secrets Management
183
+
184
+ ```ruby
185
+ # config/credentials.yml.enc (encrypted, safe to commit)
186
+ # Edit with: rails credentials:edit
187
+ # Access:
188
+ Rails.application.credentials.database[:password]
189
+ Rails.application.credentials.dig(:aws, :access_key_id)
190
+
191
+ # ENV for 12-factor apps (Heroku, Docker, etc.)
192
+ # Always use fetch to fail loudly if missing
193
+ DB_PASSWORD = ENV.fetch('DB_PASSWORD') # raises KeyError if missing
194
+ DB_PASSWORD = ENV.fetch('DB_PASSWORD') { raise "DB_PASSWORD not set" }
195
+
196
+ # Never in source code
197
+ config.secret_key_base = "abc123hardcoded" # NEVER
198
+ ```
199
+
200
+ ## Controller Pattern
201
+
202
+ ```ruby
203
+ class UsersController < ApplicationController
204
+ before_action :authenticate_user!
205
+ before_action :set_user, only: [:show, :update, :destroy]
206
+ before_action :authorize_user!, only: [:update, :destroy]
207
+
208
+ def show
209
+ render json: @user.as_json(only: [:id, :name, :email])
210
+ end
211
+
212
+ def update
213
+ if @user.update(user_params)
214
+ render json: @user
215
+ else
216
+ render json: { errors: @user.errors.full_messages }, status: :unprocessable_entity
217
+ end
218
+ end
219
+
220
+ private
221
+
222
+ def set_user
223
+ @user = User.find(params[:id])
224
+ end
225
+
226
+ def authorize_user!
227
+ head :forbidden unless current_user.admin? || @user == current_user
228
+ end
229
+
230
+ def user_params
231
+ params.require(:user).permit(:name, :email, :bio)
232
+ end
233
+ end
234
+ ```
235
+
236
+ ## Model: Thin, Validated, No Business Logic
237
+
238
+ ```ruby
239
+ class User < ApplicationRecord
240
+ # Validations
241
+ validates :email, presence: true, uniqueness: { case_sensitive: false },
242
+ format: { with: URI::MailTo::EMAIL_REGEXP }
243
+ validates :name, presence: true, length: { maximum: 100 }
244
+
245
+ # Scopes — declarative query building
246
+ scope :active, -> { where(active: true) }
247
+ scope :recent, -> { order(created_at: :desc) }
248
+ scope :admins, -> { where(role: 'admin') }
249
+
250
+ # Callbacks — use sparingly, only for model lifecycle concerns
251
+ before_save :normalize_email
252
+
253
+ # Associations
254
+ has_many :posts, dependent: :destroy
255
+ belongs_to :organization
256
+
257
+ private
258
+
259
+ def normalize_email
260
+ self.email = email.to_s.strip.downcase
261
+ end
262
+ end
263
+
264
+ # Business logic lives in service objects, NOT the model
265
+ # UserRegistrationService, UserImportService, etc.
266
+ ```
267
+
268
+ ## Service Objects (Functional Core in Rails)
269
+
270
+ ```ruby
271
+ # app/services/user_registration_service.rb
272
+ class UserRegistrationService
273
+ Result = Data.define(:success, :user, :errors)
274
+
275
+ def self.call(attrs)
276
+ new(attrs).call
277
+ end
278
+
279
+ def initialize(attrs)
280
+ @attrs = attrs
281
+ end
282
+
283
+ def call
284
+ user = User.new(normalized_attrs)
285
+ if user.save
286
+ send_welcome_email(user)
287
+ Result.new(success: true, user: user, errors: [])
288
+ else
289
+ Result.new(success: false, user: nil, errors: user.errors.full_messages)
290
+ end
291
+ end
292
+
293
+ private
294
+
295
+ def normalized_attrs
296
+ @attrs.slice(:name, :email, :password).merge(
297
+ email: @attrs[:email].to_s.strip.downcase,
298
+ name: @attrs[:name].to_s.strip
299
+ )
300
+ end
301
+
302
+ def send_welcome_email(user)
303
+ WelcomeMailer.with(user: user).welcome_email.deliver_later
304
+ end
305
+ end
306
+
307
+ # Usage in controller
308
+ result = UserRegistrationService.call(user_params)
309
+ ```
310
+
311
+ ## File Organization
312
+
313
+ ```
314
+ app/
315
+ ├── controllers/
316
+ │ └── users_controller.rb # Thin — delegate to services
317
+ ├── models/
318
+ │ └── user.rb # Validations, scopes, associations only
319
+ ├── services/
320
+ │ └── user_registration_service.rb # Business logic
321
+ ├── policies/
322
+ │ └── user_policy.rb # Authorization rules
323
+ └── views/
324
+ └── users/ # Only <%= %> — never <%== %>
325
+ config/
326
+ └── credentials.yml.enc # Secrets (encrypted)
327
+ ```
328
+
329
+ ## Security Checklist
330
+
331
+ - [ ] Strong Parameters on all mutating actions
332
+ - [ ] No string interpolation in SQL queries
333
+ - [ ] `protect_from_forgery` enabled (default — don't remove)
334
+ - [ ] `before_action` auth guard on all sensitive routes
335
+ - [ ] No secrets in source code — credentials or ENV.fetch
336
+ - [ ] ERB uses `<%= %>` not `<%== %>` for user content
337
+ - [ ] `sanitize` used when rendering user-supplied HTML
338
+ - [ ] Dependency audit: `bundle exec bundler-audit check --update`
339
+
340
+ ## When to Load Reference Files
341
+
342
+ ### Security Deep Dive
343
+ **File**: [`references/security.md`](references/security.md)
344
+ **Load when**: Need vulnerable vs. safe comparisons, injection examples, CSRF details
345
+ **Contains**: Full attack examples, all Rails security helpers, CSP configuration
346
+
347
+ ### ActiveRecord Patterns
348
+ **File**: [`references/activerecord.md`](references/activerecord.md)
349
+ **Load when**: Complex queries, raw SQL needs, migration patterns, performance
350
+ **Contains**: Query interface, raw SQL safety, N+1 prevention, index strategy
351
+
352
+ ### Testing Strategy
353
+ **File**: [`references/testing.md`](references/testing.md)
354
+ **Load when**: Writing request specs, model specs, service object tests
355
+ **Contains**: RSpec patterns, factory patterns, security test examples
356
+
357
+ ---
358
+
359
+ **Evidence Base**: OWASP Top 10 (2021), Rails Security Guide, RailsFactory/Corgea security research (2024–2025).
@@ -0,0 +1,68 @@
1
+ ---
2
+ name: "resume-session"
3
+ description: "Resume previous session from Serena MCP memory. Use when: resume session, restore session, load session, continue session, resume from save."
4
+ ---
5
+
6
+ # resume-session
7
+
8
+ Resume a previously saved session from Serena MCP memory.
9
+
10
+ ## Trigger Phrases
11
+
12
+ - "resume session"
13
+ - "restore session"
14
+ - "load session"
15
+ - "continue session"
16
+ - "resume from save"
17
+
18
+ ## Instructions
19
+
20
+ 1. Use `mcp__serena__read_memory` with memory name `session-state`
21
+ 2. Search Vestige for project context: `mcp__vestige__search query: "{project-name}" limit: 5`
22
+ 3. Check for pending intentions: `mcp__vestige__intention action: "check"`
23
+ 4. Parse the content and provide a brief status summary
24
+ 5. Wait for user direction before taking action
25
+
26
+ ## Output Format
27
+
28
+ ```
29
+ ## Session Resumed
30
+
31
+ **Task**: {current task from memory}
32
+ **Last saved**: {date from memory}
33
+
34
+ ### Status
35
+ - {bullet 1: what was in progress}
36
+ - {bullet 2: key decision or context}
37
+ - {bullet 3: main outstanding item}
38
+
39
+ ### Suggested Next Step
40
+ {The "Resume Hint" from memory, or first outstanding item}
41
+
42
+ Ready to continue. What would you like to focus on?
43
+ ```
44
+
45
+ ## Rules
46
+
47
+ - **Do not** take any actions beyond reading and summarizing
48
+ - **Do not** start working on outstanding items automatically
49
+ - **Do not** re-read files mentioned unless user asks
50
+ - **Do** present the state clearly and wait for direction
51
+
52
+ ## If Memory Not Found
53
+
54
+ Respond with:
55
+ ```
56
+ No session memory found.
57
+
58
+ To save a session, use: /ima-claude:save-session
59
+ ```
60
+
61
+ You can also check available memories with `mcp__serena__list_memories` if helpful.
62
+
63
+ ## Technical Notes
64
+
65
+ - Uses Serena MCP `read_memory` tool (no file path confusion)
66
+ - Memory persists across Claude sessions in project context
67
+ - Project-specific storage (sessions are project-bound)
68
+ - Single checkpoint model (latest session-state only)
@@ -0,0 +1,205 @@
1
+ ---
2
+ name: "rg"
3
+ description: "Ripgrep (rg) - fast recursive search tool. Prefer over grep/find for code search. Respects .gitignore, searches recursively, supports regex. Use for file content search, file listing, pattern matching. Triggers on: ripgrep, rg, search files, find in files, grep, search code, find pattern."
4
+ ---
5
+
6
+ # Ripgrep (rg) - Preferred Search Tool
7
+
8
+ **Always use `rg` instead of `grep` or `find -name`** - it's faster, has better defaults, and respects `.gitignore`.
9
+
10
+ ## Quick Reference
11
+
12
+ ### Basic Search
13
+ ```bash
14
+ # Search for pattern in current directory (recursive)
15
+ rg "pattern"
16
+
17
+ # Search specific file or directory
18
+ rg "pattern" src/
19
+ rg "pattern" file.ts
20
+
21
+ # Case-insensitive search
22
+ rg -i "pattern"
23
+
24
+ # Word boundary match (whole words only)
25
+ rg -w "function"
26
+
27
+ # Fixed string (not regex)
28
+ rg -F "exact.string.match"
29
+ ```
30
+
31
+ ### Output Control
32
+ ```bash
33
+ # Show N lines of context (before and after)
34
+ rg -C 3 "pattern"
35
+
36
+ # Lines before (-B) or after (-A) only
37
+ rg -B 2 -A 5 "pattern"
38
+
39
+ # Count matches per file
40
+ rg -c "pattern"
41
+
42
+ # List files with matches only (no content)
43
+ rg -l "pattern"
44
+ rg --files-with-matches "pattern"
45
+
46
+ # List files WITHOUT matches
47
+ rg --files-without-match "pattern"
48
+
49
+ # Show only the matched text (not full line)
50
+ rg -o "pattern"
51
+ ```
52
+
53
+ ### File Filtering
54
+ ```bash
55
+ # By file type (built-in types)
56
+ rg -t ts "pattern" # TypeScript only
57
+ rg -t py "pattern" # Python only
58
+ rg -t js "pattern" # JavaScript only
59
+ rg -t rust "pattern" # Rust only
60
+
61
+ # Exclude file type
62
+ rg -T js "pattern" # Exclude JavaScript
63
+
64
+ # By glob pattern
65
+ rg -g "*.vue" "pattern" # Only .vue files
66
+ rg -g "!*.test.ts" "pattern" # Exclude test files
67
+ rg -g "src/**/*.ts" "pattern" # TypeScript in src/
68
+
69
+ # Multiple globs
70
+ rg -g "*.ts" -g "*.vue" "pattern"
71
+ ```
72
+
73
+ ### List Files (No Search)
74
+ ```bash
75
+ # List all files that would be searched
76
+ rg --files
77
+
78
+ # List files matching glob
79
+ rg --files -g "*.ts"
80
+
81
+ # List files in specific directory
82
+ rg --files src/components/
83
+ ```
84
+
85
+ ### Bypass Filters
86
+ ```bash
87
+ # -u levels (unrestricted):
88
+ rg -u "pattern" # Ignore .gitignore
89
+ rg -uu "pattern" # + search hidden files
90
+ rg -uuu "pattern" # + search binary files
91
+
92
+ # Specific overrides
93
+ rg --hidden "pattern" # Include hidden files
94
+ rg --no-ignore "pattern" # Ignore all ignore files
95
+ ```
96
+
97
+ ### Advanced Patterns
98
+ ```bash
99
+ # Multiline search
100
+ rg -U "start.*\n.*end"
101
+
102
+ # PCRE2 regex (lookahead/lookbehind)
103
+ rg -P "(?<=prefix)pattern(?=suffix)"
104
+
105
+ # Replace in output (preview, doesn't modify files)
106
+ rg "old" -r "new"
107
+
108
+ # With capture groups
109
+ rg "fn (\w+)" -r "function $1"
110
+
111
+ # JSON output (for scripting)
112
+ rg --json "pattern"
113
+ ```
114
+
115
+ ## Common Recipes
116
+
117
+ ### Find Function/Class Definitions
118
+ ```bash
119
+ # JavaScript/TypeScript
120
+ rg "^(export )?(async )?(function|const|class) \w+"
121
+ rg "^export (default )?(function|class)"
122
+
123
+ # Python
124
+ rg "^(async )?def \w+|^class \w+"
125
+
126
+ # PHP
127
+ rg "^(public |private |protected )?(static )?(function) \w+"
128
+ ```
129
+
130
+ ### Find Imports/Requires
131
+ ```bash
132
+ rg "^import .+ from"
133
+ rg "require\(['\"]"
134
+ ```
135
+
136
+ ### Find TODOs/FIXMEs
137
+ ```bash
138
+ rg "TODO|FIXME|HACK|XXX" -g "!node_modules"
139
+ ```
140
+
141
+ ### Find Files by Extension
142
+ ```bash
143
+ rg --files -g "*.tsx" # All TSX files
144
+ rg --files -g "*.{ts,tsx}" # TS and TSX
145
+ rg --files -g "!*.test.*" # Exclude test files
146
+ ```
147
+
148
+ ### Search and Replace Preview
149
+ ```bash
150
+ # See what would change (doesn't modify files)
151
+ rg "oldFunction" -r "newFunction" --passthru
152
+ ```
153
+
154
+ ## vs grep/find
155
+
156
+ | Task | grep/find (avoid) | rg (prefer) |
157
+ |------|-------------------|-------------|
158
+ | Search text | `grep -r "pattern" .` | `rg "pattern"` |
159
+ | Find files | `find . -name "*.ts"` | `rg --files -g "*.ts"` |
160
+ | Case insensitive | `grep -ri "pattern" .` | `rg -i "pattern"` |
161
+ | Whole word | `grep -rw "word" .` | `rg -w "word"` |
162
+ | Show context | `grep -r -C 3 "pattern" .` | `rg -C 3 "pattern"` |
163
+ | List files only | `grep -rl "pattern" .` | `rg -l "pattern"` |
164
+
165
+ ## Key Advantages
166
+
167
+ 1. **Speed**: 2-10x faster than grep on large codebases
168
+ 2. **Smart defaults**: Respects `.gitignore`, skips binary/hidden files
169
+ 3. **Recursive by default**: No `-r` flag needed
170
+ 4. **Better regex**: Rust regex engine, optional PCRE2
171
+ 5. **Built-in file types**: `-t ts`, `-t py`, etc.
172
+ 6. **Colored output**: Easy to read in terminal
173
+
174
+ ## Configuration
175
+
176
+ Create `~/.ripgreprc` for persistent settings:
177
+ ```shell
178
+ # Smart case (case-insensitive unless uppercase used)
179
+ --smart-case
180
+
181
+ # Max line length for display
182
+ --max-columns=150
183
+ --max-columns-preview
184
+
185
+ # Include hidden files by default
186
+ # --hidden
187
+
188
+ # Custom file type
189
+ --type-add
190
+ web:*.{html,css,js,ts,vue}
191
+ ```
192
+
193
+ Set the config file path:
194
+ ```bash
195
+ export RIPGREP_CONFIG_PATH="$HOME/.ripgreprc"
196
+ ```
197
+
198
+ ## Type List
199
+
200
+ View all built-in types:
201
+ ```bash
202
+ rg --type-list
203
+ ```
204
+
205
+ Common types: `ts`, `js`, `py`, `rust`, `go`, `java`, `php`, `ruby`, `css`, `html`, `json`, `yaml`, `md`, `sh`