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,510 @@
1
+ ---
2
+ name: rails-controllers
3
+ description: "Rails controllers: structure template, concerns, parameter handling, and response patterns"
4
+ group: rails
5
+ ---
6
+
7
+ # Controllers
8
+
9
+ Comprehensive patterns and best practices for Rails controllers.
10
+
11
+ ---
12
+
13
+ ## Core Philosophy
14
+
15
+ 1. **Thin controllers** - Delegate business logic to models
16
+ 2. **Standard REST** - Use index, show, new, create, edit, update, destroy
17
+ 3. **Resource actions as resources** - Not custom actions
18
+ 4. **Concerns for shared behavior** - Authentication, scoping, etc.
19
+ 5. **Respond to multiple formats** - HTML, JSON, Turbo Stream
20
+
21
+ ---
22
+
23
+ ## File Structure
24
+
25
+ ```
26
+ app/controllers/
27
+ ├── application_controller.rb
28
+ ├── boards_controller.rb # CRUD controller
29
+ ├── cards/
30
+ │ ├── closures_controller.rb # Resource-action controller
31
+ │ ├── goldnesses_controller.rb # Resource-action controller
32
+ │ ├── pins_controller.rb
33
+ │ └── comments_controller.rb
34
+ └── concerns/
35
+ ├── authentication.rb # Shared concern
36
+ ├── card_scoped.rb # Scoping concern
37
+ └── filter_scoped.rb
38
+ ```
39
+
40
+ ---
41
+
42
+ ## Controller Structure Template
43
+
44
+ ### CRUD Controller
45
+
46
+ ```ruby
47
+ class BoardsController < ApplicationController
48
+ # 1. CONCERNS (at top)
49
+ include FilterScoped
50
+
51
+ # 2. BEFORE ACTIONS (explicit conditions)
52
+ before_action :set_board, except: %i[ index new create ]
53
+ before_action :ensure_permission_to_admin_board, only: %i[ update destroy ]
54
+ before_action :ensure_user_has_access, only: %i[ show ]
55
+
56
+ # 3. ACTIONS (in REST order: index, show, new, create, edit, update, destroy)
57
+
58
+ def index
59
+ @boards = Current.user.boards.ordered
60
+ end
61
+
62
+ def show
63
+ @cards = @board.cards.published.preloaded
64
+ end
65
+
66
+ def new
67
+ @board = Board.new
68
+ end
69
+
70
+ def create
71
+ @board = Current.user.boards.create!(board_params)
72
+
73
+ respond_to do |format|
74
+ format.html { redirect_to board_path(@board), notice: "Board created" }
75
+ format.json { head :created, location: board_path(@board, format: :json) }
76
+ format.turbo_stream { render turbo_stream: turbo_stream.prepend(:boards, @board) }
77
+ end
78
+ end
79
+
80
+ def edit
81
+ # Renders edit form
82
+ end
83
+
84
+ def update
85
+ @board.update!(board_params)
86
+
87
+ respond_to do |format|
88
+ format.html { redirect_to board_path(@board), notice: "Board updated" }
89
+ format.json { head :no_content }
90
+ format.turbo_stream { render turbo_stream: turbo_stream.replace(@board, @board) }
91
+ end
92
+ end
93
+
94
+ def destroy
95
+ @board.destroy!
96
+
97
+ respond_to do |format|
98
+ format.html { redirect_to boards_path, notice: "Board deleted" }
99
+ format.json { head :no_content }
100
+ format.turbo_stream { render turbo_stream: turbo_stream.remove(@board) }
101
+ end
102
+ end
103
+
104
+ # 4. PRIVATE METHODS (ordered by invocation)
105
+ private
106
+ def set_board
107
+ @board = Current.user.boards.find params[:id]
108
+ end
109
+
110
+ def ensure_permission_to_admin_board
111
+ unless Current.user.can_administer_board?(@board)
112
+ head :forbidden
113
+ end
114
+ end
115
+
116
+ def ensure_user_has_access
117
+ unless @board.accessible_to?(Current.user)
118
+ head :forbidden
119
+ end
120
+ end
121
+
122
+ def board_params
123
+ params.expect(board: [ :name, :all_access, :auto_postpone_period, :public_description ])
124
+ end
125
+ end
126
+ ```
127
+
128
+ ### Resource-Action Controller (Singleton)
129
+
130
+ ```ruby
131
+ # Route: resource :closure
132
+ # POST /cards/:card_id/closure → create (close)
133
+ # DELETE /cards/:card_id/closure → destroy (reopen)
134
+
135
+ class Cards::ClosuresController < ApplicationController
136
+ include CardScoped # Sets @card and @board
137
+
138
+ def create
139
+ @card.close(user: Current.user) # Delegate to model
140
+
141
+ respond_to do |format|
142
+ format.html { redirect_back fallback_location: @card }
143
+ format.json { head :no_content }
144
+ format.turbo_stream { render_card_replacement }
145
+ end
146
+ end
147
+
148
+ def destroy
149
+ @card.reopen(user: Current.user)
150
+
151
+ respond_to do |format|
152
+ format.html { redirect_back fallback_location: @card }
153
+ format.json { head :no_content }
154
+ format.turbo_stream { render_card_replacement }
155
+ end
156
+ end
157
+ end
158
+ ```
159
+
160
+ ### Nested Resource Controller
161
+
162
+ ```ruby
163
+ class Cards::CommentsController < ApplicationController
164
+ include CardScoped # Sets @card
165
+
166
+ before_action :set_comment, only: %i[ show edit update destroy ]
167
+
168
+ def index
169
+ @comments = @card.comments.chronologically
170
+ end
171
+
172
+ def show
173
+ end
174
+
175
+ def create
176
+ @comment = @card.comments.create!(comment_params.merge(creator: Current.user))
177
+
178
+ respond_to do |format|
179
+ format.turbo_stream
180
+ format.json { render json: @comment, status: :created }
181
+ end
182
+ end
183
+
184
+ def update
185
+ @comment.update!(comment_params)
186
+
187
+ respond_to do |format|
188
+ format.turbo_stream
189
+ format.json { head :no_content }
190
+ end
191
+ end
192
+
193
+ def destroy
194
+ @comment.destroy!
195
+
196
+ respond_to do |format|
197
+ format.turbo_stream { render turbo_stream: turbo_stream.remove(@comment) }
198
+ format.json { head :no_content }
199
+ end
200
+ end
201
+
202
+ private
203
+ def set_comment
204
+ @comment = @card.comments.find(params[:id])
205
+ end
206
+
207
+ def comment_params
208
+ params.expect(comment: [ :body ])
209
+ end
210
+ end
211
+ ```
212
+
213
+ ---
214
+
215
+ ## Controller Concerns
216
+
217
+ ### Authentication Concern
218
+
219
+ ```ruby
220
+ # app/controllers/concerns/authentication.rb
221
+ module Authentication
222
+ extend ActiveSupport::Concern
223
+
224
+ included do
225
+ before_action :require_account
226
+ before_action :require_authentication
227
+
228
+ helper_method :authenticated?, :current_user
229
+ end
230
+
231
+ class_methods do
232
+ # Allow specific actions without authentication
233
+ def allow_unauthenticated_access(**options)
234
+ skip_before_action :require_authentication, **options
235
+ before_action :resume_session, **options
236
+ end
237
+
238
+ # Require unauthenticated (for login pages)
239
+ def require_unauthenticated_access(**options)
240
+ allow_unauthenticated_access **options
241
+ before_action :redirect_authenticated_user, **options
242
+ end
243
+ end
244
+
245
+ private
246
+ def authenticated?
247
+ Current.identity.present?
248
+ end
249
+
250
+ def current_user
251
+ Current.user
252
+ end
253
+
254
+ def require_authentication
255
+ unless authenticated?
256
+ redirect_to new_session_path
257
+ end
258
+ end
259
+
260
+ def require_account
261
+ unless Current.account
262
+ redirect_to root_url(untenanted: true)
263
+ end
264
+ end
265
+
266
+ def resume_session
267
+ if session_cookie = cookies.signed[:session_id]
268
+ Current.session = Session.find_by(id: session_cookie)
269
+ end
270
+ end
271
+
272
+ def redirect_authenticated_user
273
+ if authenticated?
274
+ redirect_to root_path
275
+ end
276
+ end
277
+ end
278
+ ```
279
+
280
+ ### Scoping Concern
281
+
282
+ ```ruby
283
+ # app/controllers/concerns/card_scoped.rb
284
+ module CardScoped
285
+ extend ActiveSupport::Concern
286
+
287
+ included do
288
+ before_action :set_card, :set_board
289
+ end
290
+
291
+ private
292
+ def set_card
293
+ @card = Current.user.accessible_cards.find_by!(number: params[:card_id])
294
+ end
295
+
296
+ def set_board
297
+ @board = @card.board
298
+ end
299
+
300
+ # Helper methods for this resource
301
+ def render_card_replacement
302
+ render turbo_stream: turbo_stream.replace(
303
+ [ @card, :card_container ],
304
+ partial: "cards/container",
305
+ method: :morph,
306
+ locals: { card: @card.reload }
307
+ )
308
+ end
309
+
310
+ def render_card_preview_replacement
311
+ render turbo_stream: turbo_stream.replace(
312
+ [ @card, :preview ],
313
+ partial: "cards/display/preview",
314
+ locals: { card: @card.reload }
315
+ )
316
+ end
317
+ end
318
+ ```
319
+
320
+ ### Feature Toggle Concern
321
+
322
+ ```ruby
323
+ module FeatureGuarded
324
+ extend ActiveSupport::Concern
325
+
326
+ included do
327
+ before_action :ensure_feature_enabled
328
+ end
329
+
330
+ private
331
+ def ensure_feature_enabled
332
+ unless Current.account.feature_enabled?(controller_name)
333
+ head :forbidden
334
+ end
335
+ end
336
+ end
337
+ ```
338
+
339
+ ---
340
+
341
+ ## Parameter Handling
342
+
343
+ ### Rails 8+ params.expect
344
+
345
+ Rails 8 introduced `params.expect` as the modern, safer alternative to `params.require().permit()`.
346
+
347
+ **Key difference:** `expect` renders a 400 Bad Request response for malformed params (production-friendly), while `expect!` raises an exception (for debugging/internal APIs).
348
+
349
+ ```ruby
350
+ # Simple parameters
351
+ def board_params
352
+ params.expect(board: [ :name, :description ])
353
+ end
354
+
355
+ # Nested parameters
356
+ def card_params
357
+ params.expect(card: [ :title, :status, { tag_ids: [] } ])
358
+ end
359
+
360
+ # Multiple nested levels
361
+ def user_params
362
+ params.expect(user: [
363
+ :name,
364
+ :email,
365
+ :role,
366
+ {
367
+ avatar: [:image],
368
+ preferences: [:theme, :notifications]
369
+ }
370
+ ])
371
+ end
372
+ ```
373
+
374
+ **expect vs expect!**
375
+
376
+ ```ruby
377
+ # expect - Production use (returns 400 response for malformed params)
378
+ def create
379
+ @board = Board.create!(board_params)
380
+ end
381
+
382
+ private
383
+ def board_params
384
+ params.expect(board: [ :name, :description ])
385
+ end
386
+ # Missing or malformed params → renders 400 Bad Request
387
+
388
+ # expect! - Debugging/Internal APIs (raises exception)
389
+ def board_params
390
+ params.expect!(board: [ :name, :description ])
391
+ end
392
+ # Missing or malformed params → raises ActionController::ParameterMissing
393
+ ```
394
+
395
+ **Legacy pattern (Rails 7 and earlier)**
396
+
397
+ ```ruby
398
+ # Still works in Rails 8, but expect is preferred
399
+ def board_params
400
+ params.require(:board).permit(:name, :description, :all_access)
401
+ end
402
+ ```
403
+
404
+ ### Parameter Sanitization
405
+
406
+ ```ruby
407
+ private
408
+ def sanitized_tag_title_param
409
+ params.required(:tag_title).strip.gsub(/\A#/, "")
410
+ end
411
+
412
+ def sanitized_email_param
413
+ params.required(:email).downcase.strip
414
+ end
415
+
416
+ def normalized_url_param
417
+ url = params.required(:url)
418
+ url = "https://#{url}" unless url.start_with?("http")
419
+ url
420
+ end
421
+ ```
422
+
423
+ ---
424
+
425
+ ## Response Patterns
426
+
427
+ ### Multi-Format Responses
428
+
429
+ ```ruby
430
+ def create
431
+ @board = Board.create!(board_params)
432
+
433
+ respond_to do |format|
434
+ format.html { redirect_to board_path(@board), notice: "Created!" }
435
+ format.json { render json: @board, status: :created }
436
+ format.turbo_stream { render turbo_stream: turbo_stream.prepend(:boards, @board) }
437
+ end
438
+ end
439
+ ```
440
+
441
+ ### Redirect Patterns
442
+
443
+ ```ruby
444
+ # Basic redirect
445
+ redirect_to board_path(@board)
446
+
447
+ # With notice/alert
448
+ redirect_to @board, notice: "Board created"
449
+ redirect_to @board, alert: "Something went wrong"
450
+
451
+ # Redirect back with fallback
452
+ redirect_back fallback_location: @board
453
+
454
+ # Conditional redirect
455
+ if @board.accessible_to?(Current.user)
456
+ redirect_to @board
457
+ else
458
+ redirect_to boards_path
459
+ end
460
+
461
+ # Turbo-aware redirect
462
+ redirect_to @board, status: :see_other # Forces GET request in Turbo
463
+ ```
464
+
465
+ ### Status Codes
466
+
467
+ ```ruby
468
+ # Success
469
+ head :ok # 200
470
+ head :created # 201
471
+ head :no_content # 204
472
+
473
+ # Client errors
474
+ head :bad_request # 400
475
+ head :unauthorized # 401
476
+ head :forbidden # 403
477
+ head :not_found # 404
478
+ head :unprocessable_entity # 422
479
+
480
+ # Server errors
481
+ head :internal_server_error # 500
482
+
483
+ # With location
484
+ head :created, location: board_path(@board)
485
+ ```
486
+
487
+ ### Turbo Stream Responses
488
+
489
+ ```ruby
490
+ # Replace element
491
+ render turbo_stream: turbo_stream.replace(@card, partial: "cards/card")
492
+
493
+ # Update element
494
+ render turbo_stream: turbo_stream.update(@card, partial: "cards/card")
495
+
496
+ # Append/Prepend
497
+ render turbo_stream: turbo_stream.append(:cards, @card)
498
+ render turbo_stream: turbo_stream.prepend(:cards, @card)
499
+
500
+ # Remove
501
+ render turbo_stream: turbo_stream.remove(@card)
502
+
503
+ # Multiple actions
504
+ render turbo_stream: [
505
+ turbo_stream.replace(@card, @card),
506
+ turbo_stream.update(:sidebar, partial: "cards/sidebar")
507
+ ]
508
+ ```
509
+
510
+ ---