agent-notes 2.0.4__py3-none-any.whl

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 (162) hide show
  1. agent_notes/VERSION +1 -0
  2. agent_notes/__init__.py +1 -0
  3. agent_notes/__main__.py +4 -0
  4. agent_notes/cli.py +348 -0
  5. agent_notes/commands/__init__.py +27 -0
  6. agent_notes/commands/_install_helpers.py +262 -0
  7. agent_notes/commands/build.py +170 -0
  8. agent_notes/commands/doctor.py +112 -0
  9. agent_notes/commands/info.py +95 -0
  10. agent_notes/commands/install.py +99 -0
  11. agent_notes/commands/list.py +169 -0
  12. agent_notes/commands/memory.py +430 -0
  13. agent_notes/commands/regenerate.py +152 -0
  14. agent_notes/commands/set_role.py +143 -0
  15. agent_notes/commands/uninstall.py +26 -0
  16. agent_notes/commands/update.py +169 -0
  17. agent_notes/commands/validate.py +199 -0
  18. agent_notes/commands/wizard.py +720 -0
  19. agent_notes/config.py +154 -0
  20. agent_notes/data/agents/agents.yaml +352 -0
  21. agent_notes/data/agents/analyst.md +45 -0
  22. agent_notes/data/agents/api-reviewer.md +47 -0
  23. agent_notes/data/agents/architect.md +46 -0
  24. agent_notes/data/agents/coder.md +28 -0
  25. agent_notes/data/agents/database-specialist.md +45 -0
  26. agent_notes/data/agents/debugger.md +47 -0
  27. agent_notes/data/agents/devil.md +47 -0
  28. agent_notes/data/agents/devops.md +38 -0
  29. agent_notes/data/agents/explorer.md +23 -0
  30. agent_notes/data/agents/integrations.md +44 -0
  31. agent_notes/data/agents/lead.md +216 -0
  32. agent_notes/data/agents/performance-profiler.md +44 -0
  33. agent_notes/data/agents/refactorer.md +48 -0
  34. agent_notes/data/agents/reviewer.md +44 -0
  35. agent_notes/data/agents/security-auditor.md +44 -0
  36. agent_notes/data/agents/system-auditor.md +38 -0
  37. agent_notes/data/agents/tech-writer.md +32 -0
  38. agent_notes/data/agents/test-runner.md +36 -0
  39. agent_notes/data/agents/test-writer.md +39 -0
  40. agent_notes/data/cli/claude.yaml +25 -0
  41. agent_notes/data/cli/copilot.yaml +18 -0
  42. agent_notes/data/cli/opencode.yaml +22 -0
  43. agent_notes/data/commands/brainstorm.md +8 -0
  44. agent_notes/data/commands/debug.md +9 -0
  45. agent_notes/data/commands/review.md +10 -0
  46. agent_notes/data/global-claude.md +290 -0
  47. agent_notes/data/global-copilot.md +27 -0
  48. agent_notes/data/global-opencode.md +40 -0
  49. agent_notes/data/hooks/session-context.md.tpl +19 -0
  50. agent_notes/data/models/claude-haiku-4-5.yaml +15 -0
  51. agent_notes/data/models/claude-opus-4-1.yaml +16 -0
  52. agent_notes/data/models/claude-opus-4-5.yaml +16 -0
  53. agent_notes/data/models/claude-opus-4-6.yaml +16 -0
  54. agent_notes/data/models/claude-opus-4-7.yaml +15 -0
  55. agent_notes/data/models/claude-sonnet-4-5.yaml +16 -0
  56. agent_notes/data/models/claude-sonnet-4-6.yaml +15 -0
  57. agent_notes/data/models/claude-sonnet-4.yaml +16 -0
  58. agent_notes/data/pricing.yaml +33 -0
  59. agent_notes/data/roles/orchestrator.yaml +5 -0
  60. agent_notes/data/roles/reasoner.yaml +5 -0
  61. agent_notes/data/roles/scout.yaml +5 -0
  62. agent_notes/data/roles/worker.yaml +5 -0
  63. agent_notes/data/rules/code-quality.md +9 -0
  64. agent_notes/data/rules/safety.md +10 -0
  65. agent_notes/data/scripts/cost-report +211 -0
  66. agent_notes/data/skills/brainstorming/SKILL.md +57 -0
  67. agent_notes/data/skills/code-review/SKILL.md +64 -0
  68. agent_notes/data/skills/debugging-protocol/SKILL.md +51 -0
  69. agent_notes/data/skills/docker-compose/SKILL.md +318 -0
  70. agent_notes/data/skills/docker-compose-advanced/SKILL.md +575 -0
  71. agent_notes/data/skills/docker-dockerfile/SKILL.md +385 -0
  72. agent_notes/data/skills/docker-dockerfile-languages/SKILL.md +293 -0
  73. agent_notes/data/skills/git/SKILL.md +87 -0
  74. agent_notes/data/skills/rails-active-storage/SKILL.md +321 -0
  75. agent_notes/data/skills/rails-broadcasting/SKILL.md +374 -0
  76. agent_notes/data/skills/rails-concerns/SKILL.md +806 -0
  77. agent_notes/data/skills/rails-controllers/SKILL.md +510 -0
  78. agent_notes/data/skills/rails-controllers-advanced/SKILL.md +441 -0
  79. agent_notes/data/skills/rails-helpers/SKILL.md +677 -0
  80. agent_notes/data/skills/rails-initializers/SKILL.md +79 -0
  81. agent_notes/data/skills/rails-javascript/SKILL.md +567 -0
  82. agent_notes/data/skills/rails-jobs/SKILL.md +700 -0
  83. agent_notes/data/skills/rails-kamal/SKILL.md +483 -0
  84. agent_notes/data/skills/rails-lib/SKILL.md +101 -0
  85. agent_notes/data/skills/rails-mailers/SKILL.md +321 -0
  86. agent_notes/data/skills/rails-migrations/SKILL.md +268 -0
  87. agent_notes/data/skills/rails-models/SKILL.md +459 -0
  88. agent_notes/data/skills/rails-models-advanced/SKILL.md +398 -0
  89. agent_notes/data/skills/rails-routes/SKILL.md +804 -0
  90. agent_notes/data/skills/rails-style/SKILL.md +538 -0
  91. agent_notes/data/skills/rails-testing-controllers/SKILL.md +343 -0
  92. agent_notes/data/skills/rails-testing-models/SKILL.md +296 -0
  93. agent_notes/data/skills/rails-testing-system/SKILL.md +375 -0
  94. agent_notes/data/skills/rails-validations/SKILL.md +108 -0
  95. agent_notes/data/skills/rails-view-components/SKILL.md +511 -0
  96. agent_notes/data/skills/rails-view-components-advanced/SKILL.md +376 -0
  97. agent_notes/data/skills/rails-views/SKILL.md +413 -0
  98. agent_notes/data/skills/rails-views-advanced/SKILL.md +450 -0
  99. agent_notes/data/skills/refactoring-protocol/SKILL.md +64 -0
  100. agent_notes/data/skills/tdd/SKILL.md +57 -0
  101. agent_notes/data/templates/__init__.py +1 -0
  102. agent_notes/data/templates/__pycache__/__init__.cpython-314.pyc +0 -0
  103. agent_notes/data/templates/frontmatter/__init__.py +1 -0
  104. agent_notes/data/templates/frontmatter/__pycache__/__init__.cpython-314.pyc +0 -0
  105. agent_notes/data/templates/frontmatter/__pycache__/claude.cpython-314.pyc +0 -0
  106. agent_notes/data/templates/frontmatter/__pycache__/cursor.cpython-314.pyc +0 -0
  107. agent_notes/data/templates/frontmatter/__pycache__/opencode.cpython-314.pyc +0 -0
  108. agent_notes/data/templates/frontmatter/claude.py +44 -0
  109. agent_notes/data/templates/frontmatter/opencode.py +104 -0
  110. agent_notes/doctor_checks.py +189 -0
  111. agent_notes/domain/__init__.py +17 -0
  112. agent_notes/domain/agent.py +34 -0
  113. agent_notes/domain/cli_backend.py +40 -0
  114. agent_notes/domain/diagnostics.py +29 -0
  115. agent_notes/domain/diff.py +44 -0
  116. agent_notes/domain/model.py +27 -0
  117. agent_notes/domain/role.py +13 -0
  118. agent_notes/domain/rule.py +13 -0
  119. agent_notes/domain/skill.py +15 -0
  120. agent_notes/domain/state.py +46 -0
  121. agent_notes/install_state.py +11 -0
  122. agent_notes/registries/__init__.py +16 -0
  123. agent_notes/registries/_base.py +46 -0
  124. agent_notes/registries/agent_registry.py +107 -0
  125. agent_notes/registries/cli_registry.py +89 -0
  126. agent_notes/registries/model_registry.py +85 -0
  127. agent_notes/registries/role_registry.py +64 -0
  128. agent_notes/registries/rule_registry.py +80 -0
  129. agent_notes/registries/skill_registry.py +141 -0
  130. agent_notes/services/__init__.py +8 -0
  131. agent_notes/services/diagnostics/__init__.py +47 -0
  132. agent_notes/services/diagnostics/_checks.py +272 -0
  133. agent_notes/services/diagnostics/_display.py +346 -0
  134. agent_notes/services/diagnostics/_fix.py +169 -0
  135. agent_notes/services/diff.py +349 -0
  136. agent_notes/services/fs.py +195 -0
  137. agent_notes/services/install_state_builder.py +210 -0
  138. agent_notes/services/installer.py +293 -0
  139. agent_notes/services/memory_backend.py +155 -0
  140. agent_notes/services/rendering.py +329 -0
  141. agent_notes/services/session_context.py +23 -0
  142. agent_notes/services/settings_writer.py +79 -0
  143. agent_notes/services/state_store.py +249 -0
  144. agent_notes/services/ui.py +419 -0
  145. agent_notes/services/user_config.py +62 -0
  146. agent_notes/services/validation.py +67 -0
  147. agent_notes/state.py +21 -0
  148. agent_notes-2.0.4.dist-info/METADATA +14 -0
  149. agent_notes-2.0.4.dist-info/RECORD +162 -0
  150. agent_notes-2.0.4.dist-info/WHEEL +5 -0
  151. agent_notes-2.0.4.dist-info/entry_points.txt +2 -0
  152. agent_notes-2.0.4.dist-info/licenses/LICENSE +21 -0
  153. agent_notes-2.0.4.dist-info/top_level.txt +2 -0
  154. tests/conftest.py +20 -0
  155. tests/functional/__init__.py +0 -0
  156. tests/functional/test_build_commands.py +88 -0
  157. tests/functional/test_registries.py +128 -0
  158. tests/integration/__init__.py +0 -0
  159. tests/integration/test_build_output.py +129 -0
  160. tests/plugins/__init__.py +0 -0
  161. tests/plugins/test_agents.py +93 -0
  162. tests/plugins/test_skills.py +77 -0
@@ -0,0 +1,441 @@
1
+ ---
2
+ name: rails-controllers-advanced
3
+ description: "Rails controllers advanced: error handling, filters, streaming, API patterns, security, and testing"
4
+ group: rails
5
+ ---
6
+
7
+ # Controllers (Advanced)
8
+
9
+ ## Error Handling
10
+
11
+ ### Rescue from Exceptions
12
+
13
+ ```ruby
14
+ class ApplicationController < ActionController::Base
15
+ # Rescue specific errors
16
+ rescue_from ActiveRecord::RecordNotFound, with: :record_not_found
17
+ rescue_from ActiveRecord::RecordInvalid, with: :record_invalid
18
+ rescue_from ActionController::ParameterMissing, with: :parameter_missing
19
+
20
+ private
21
+ def record_not_found
22
+ respond_to do |format|
23
+ format.html { redirect_to root_path, alert: "Not found" }
24
+ format.json { head :not_found }
25
+ end
26
+ end
27
+
28
+ def record_invalid(exception)
29
+ @errors = exception.record.errors
30
+
31
+ respond_to do |format|
32
+ format.html { render :edit, status: :unprocessable_entity }
33
+ format.json { render json: { errors: @errors }, status: :unprocessable_entity }
34
+ end
35
+ end
36
+
37
+ def parameter_missing(exception)
38
+ respond_to do |format|
39
+ format.html { redirect_back fallback_location: root_path, alert: "Invalid request" }
40
+ format.json { render json: { error: exception.message }, status: :bad_request }
41
+ end
42
+ end
43
+ end
44
+ ```
45
+
46
+ ### Handling Validation Errors
47
+
48
+ ```ruby
49
+ def create
50
+ @board = Board.new(board_params)
51
+
52
+ if @board.save
53
+ redirect_to @board, notice: "Created!"
54
+ else
55
+ render :new, status: :unprocessable_entity
56
+ end
57
+ end
58
+
59
+ # With create! (raises exception)
60
+ def create
61
+ @board = Board.create!(board_params)
62
+ redirect_to @board, notice: "Created!"
63
+ rescue ActiveRecord::RecordInvalid
64
+ render :new, status: :unprocessable_entity
65
+ end
66
+ ```
67
+
68
+ ---
69
+
70
+ ## Before/After/Around Actions
71
+
72
+ ### Before Actions
73
+
74
+ ```ruby
75
+ # Run before specific actions
76
+ before_action :set_board, only: %i[ show edit update destroy ]
77
+ before_action :set_board, except: %i[ index new create ]
78
+
79
+ # Run for all actions
80
+ before_action :require_authentication
81
+
82
+ # Conditional
83
+ before_action :check_admin, if: :admin_required?
84
+
85
+ # With Proc
86
+ before_action -> { redirect_to root_path unless admin? }, only: :admin_dashboard
87
+ ```
88
+
89
+ ### After Actions
90
+
91
+ ```ruby
92
+ after_action :log_action
93
+ after_action :set_cache_headers, only: :show
94
+
95
+ private
96
+ def log_action
97
+ Rails.logger.info "Action: #{action_name} by #{Current.user&.email}"
98
+ end
99
+
100
+ def set_cache_headers
101
+ expires_in 5.minutes, public: true
102
+ end
103
+ ```
104
+
105
+ ### Around Actions
106
+
107
+ ```ruby
108
+ around_action :wrap_in_transaction, only: :complex_operation
109
+
110
+ private
111
+ def wrap_in_transaction
112
+ ActiveRecord::Base.transaction do
113
+ yield
114
+ end
115
+ end
116
+ ```
117
+
118
+ ### Skip Actions
119
+
120
+ ```ruby
121
+ skip_before_action :require_authentication, only: :public_page
122
+ skip_after_action :log_action, only: :health_check
123
+ ```
124
+
125
+ ---
126
+
127
+ ## Flash Messages
128
+
129
+ ```ruby
130
+ # Set flash
131
+ redirect_to @board, notice: "Board created"
132
+ redirect_to @board, alert: "Something went wrong"
133
+
134
+ # Custom flash keys
135
+ redirect_to @board, flash: { warning: "Please verify your email" }
136
+
137
+ # Flash.now (doesn't persist to next request)
138
+ def create
139
+ @board = Board.new(board_params)
140
+ if @board.save
141
+ redirect_to @board
142
+ else
143
+ flash.now[:alert] = "Could not create board"
144
+ render :new
145
+ end
146
+ end
147
+
148
+ # Keep flash for another request
149
+ flash.keep(:notice)
150
+ ```
151
+
152
+ ---
153
+
154
+ ## Streaming & Live Updates
155
+
156
+ ### Turbo Streams
157
+
158
+ ```ruby
159
+ # In controller
160
+ def create
161
+ @comment = @card.comments.create!(comment_params)
162
+
163
+ respond_to do |format|
164
+ format.turbo_stream # Renders create.turbo_stream.erb
165
+ end
166
+ end
167
+ ```
168
+
169
+ ### Server-Sent Events
170
+
171
+ ```ruby
172
+ def stream
173
+ response.headers["Content-Type"] = "text/event-stream"
174
+
175
+ sse = SSE.new(response.stream)
176
+
177
+ begin
178
+ loop do
179
+ sse.write({ message: "Hello" })
180
+ sleep 1
181
+ end
182
+ rescue IOError
183
+ # Client disconnected
184
+ ensure
185
+ sse.close
186
+ end
187
+ end
188
+ ```
189
+
190
+ ---
191
+
192
+ ## Performance Patterns
193
+
194
+ ### Eager Loading
195
+
196
+ ```ruby
197
+ def index
198
+ @cards = Card.includes(:creator, :tags, :assignees)
199
+ .preload(board: :columns)
200
+ .where(board: Current.user.boards)
201
+ end
202
+ ```
203
+
204
+ ### Caching
205
+
206
+ ```ruby
207
+ # Fragment caching (in view)
208
+ <% cache @board do %>
209
+ <%= render @board %>
210
+ <% end %>
211
+
212
+ # HTTP caching
213
+ def show
214
+ fresh_when etag: @board, last_modified: @board.updated_at, public: true
215
+ end
216
+
217
+ # Stale check
218
+ def show
219
+ if stale?(@board)
220
+ # Render view
221
+ end
222
+ end
223
+ ```
224
+
225
+ ### Pagination
226
+
227
+ ```ruby
228
+ def index
229
+ @cards = Card.page(params[:page]).per(25)
230
+ end
231
+ ```
232
+
233
+ ---
234
+
235
+ ## API Patterns
236
+
237
+ ### JSON API Responses
238
+
239
+ ```ruby
240
+ def show
241
+ render json: @board
242
+ end
243
+
244
+ def create
245
+ @board = Board.create!(board_params)
246
+ render json: @board, status: :created, location: @board
247
+ end
248
+
249
+ # With serializer/Jbuilder
250
+ render json: @board, serializer: BoardSerializer
251
+ # or
252
+ render :show # Uses show.json.jbuilder
253
+ ```
254
+
255
+ ### API Error Responses
256
+
257
+ ```ruby
258
+ rescue_from ActiveRecord::RecordInvalid do |exception|
259
+ render json: {
260
+ error: "Validation failed",
261
+ details: exception.record.errors.full_messages
262
+ }, status: :unprocessable_entity
263
+ end
264
+
265
+ rescue_from ActiveRecord::RecordNotFound do
266
+ render json: { error: "Not found" }, status: :not_found
267
+ end
268
+ ```
269
+
270
+ ### API Versioning
271
+
272
+ ```ruby
273
+ # Namespace approach
274
+ namespace :api do
275
+ namespace :v1 do
276
+ resources :boards
277
+ end
278
+ end
279
+
280
+ # Or header-based (in ApplicationController)
281
+ before_action :set_api_version
282
+
283
+ private
284
+ def set_api_version
285
+ @api_version = request.headers["X-API-Version"] || "v1"
286
+ end
287
+ ```
288
+
289
+ ---
290
+
291
+ ## Security Patterns
292
+
293
+ ### CSRF Protection
294
+
295
+ ```ruby
296
+ # Enabled by default
297
+ class ApplicationController < ActionController::Base
298
+ protect_from_forgery with: :exception
299
+ end
300
+
301
+ # Skip for API endpoints
302
+ class ApiController < ApplicationController
303
+ skip_before_action :verify_authenticity_token
304
+ end
305
+ ```
306
+
307
+ ### Strong Parameters
308
+
309
+ ```ruby
310
+ # Only permitted params get through
311
+ def board_params
312
+ params.expect(board: [ :name, :description ])
313
+ end
314
+
315
+ # Attempting to pass other params will raise ActionController::ParameterMissing
316
+ ```
317
+
318
+ ### Authorization Checks
319
+
320
+ ```ruby
321
+ before_action :ensure_owner, only: %i[ destroy ]
322
+
323
+ private
324
+ def ensure_owner
325
+ unless @board.owner?(Current.user)
326
+ head :forbidden
327
+ end
328
+ end
329
+ ```
330
+
331
+ ---
332
+
333
+ ## Testing Controllers
334
+
335
+ ```ruby
336
+ class BoardsControllerTest < ActionDispatch::IntegrationTest
337
+ setup do
338
+ sign_in_as :kevin
339
+ end
340
+
341
+ test "index shows user's boards" do
342
+ get boards_path
343
+
344
+ assert_response :success
345
+ assert_select "h1", "Boards"
346
+ end
347
+
348
+ test "create creates board" do
349
+ assert_difference -> { Board.count }, +1 do
350
+ post boards_path, params: { board: { name: "New Board" } }
351
+ end
352
+
353
+ assert_redirected_to board_path(Board.last)
354
+ assert_equal "New Board", Board.last.name
355
+ end
356
+
357
+ test "update updates board" do
358
+ board = boards(:writebook)
359
+
360
+ patch board_path(board), params: { board: { name: "Updated" } }
361
+
362
+ assert_redirected_to board_path(board)
363
+ assert_equal "Updated", board.reload.name
364
+ end
365
+
366
+ test "destroy removes board" do
367
+ board = boards(:writebook)
368
+
369
+ assert_difference -> { Board.count }, -1 do
370
+ delete board_path(board)
371
+ end
372
+
373
+ assert_redirected_to boards_path
374
+ end
375
+
376
+ test "non-admin cannot update board" do
377
+ logout_and_sign_in_as :member
378
+
379
+ board = boards(:writebook)
380
+ original_name = board.name
381
+
382
+ patch board_path(board), params: { board: { name: "Hacked" } }
383
+
384
+ assert_response :forbidden
385
+ assert_equal original_name, board.reload.name
386
+ end
387
+
388
+ test "turbo stream response on create" do
389
+ post boards_path,
390
+ params: { board: { name: "Test" } },
391
+ as: :turbo_stream
392
+
393
+ assert_response :success
394
+ assert_match "turbo-stream", response.body
395
+ end
396
+
397
+ test "json response includes board data" do
398
+ board = boards(:writebook)
399
+
400
+ get board_path(board), as: :json
401
+
402
+ assert_response :success
403
+ json = JSON.parse(response.body)
404
+ assert_equal board.name, json["name"]
405
+ end
406
+ end
407
+ ```
408
+
409
+ ---
410
+
411
+ ## Best Practices
412
+
413
+ ### DO
414
+
415
+ 1. **Keep controllers thin** - Delegate to models
416
+ 2. **Use concerns for shared behavior**
417
+ 3. **Respond to multiple formats**
418
+ 4. **Use strong parameters**
419
+ 5. **Test permissions thoroughly**
420
+ 6. **Return appropriate status codes**
421
+ 7. **Use before_action for setup**
422
+
423
+ ### DON'T
424
+
425
+ 1. **Business logic in controllers** - Belongs in models
426
+ 2. **Multiple responsibilities** - One resource per controller
427
+ 3. **Complex queries** - Use model scopes
428
+ 4. **Rescue exceptions broadly** - Be specific
429
+ 5. **Skip CSRF protection** - Unless API
430
+ 6. **Fat controllers** - Extract to concerns/models
431
+
432
+ ---
433
+
434
+ ## Summary
435
+
436
+ - **Structure**: Concerns, before_actions, REST actions, private methods
437
+ - **Delegation**: Controllers delegate to models
438
+ - **Responses**: Multi-format with appropriate status codes
439
+ - **Security**: Strong parameters, CSRF, authorization
440
+ - **Testing**: Test happy path, edge cases, and permissions
441
+ - **Performance**: Eager loading, caching, pagination