red64-cli 0.1.0 → 0.2.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 (103) hide show
  1. package/dist/cli/parseArgs.d.ts.map +1 -1
  2. package/dist/cli/parseArgs.js +5 -0
  3. package/dist/cli/parseArgs.js.map +1 -1
  4. package/dist/components/init/CompleteStep.d.ts.map +1 -1
  5. package/dist/components/init/CompleteStep.js +2 -2
  6. package/dist/components/init/CompleteStep.js.map +1 -1
  7. package/dist/components/init/TestCheckStep.d.ts +16 -0
  8. package/dist/components/init/TestCheckStep.d.ts.map +1 -0
  9. package/dist/components/init/TestCheckStep.js +120 -0
  10. package/dist/components/init/TestCheckStep.js.map +1 -0
  11. package/dist/components/init/index.d.ts +1 -0
  12. package/dist/components/init/index.d.ts.map +1 -1
  13. package/dist/components/init/index.js +1 -0
  14. package/dist/components/init/index.js.map +1 -1
  15. package/dist/components/init/types.d.ts +9 -0
  16. package/dist/components/init/types.d.ts.map +1 -1
  17. package/dist/components/screens/InitScreen.d.ts.map +1 -1
  18. package/dist/components/screens/InitScreen.js +69 -6
  19. package/dist/components/screens/InitScreen.js.map +1 -1
  20. package/dist/components/screens/StartScreen.d.ts.map +1 -1
  21. package/dist/components/screens/StartScreen.js +89 -3
  22. package/dist/components/screens/StartScreen.js.map +1 -1
  23. package/dist/services/ConfigService.d.ts +1 -0
  24. package/dist/services/ConfigService.d.ts.map +1 -1
  25. package/dist/services/ConfigService.js.map +1 -1
  26. package/dist/services/ProjectDetector.d.ts +28 -0
  27. package/dist/services/ProjectDetector.d.ts.map +1 -0
  28. package/dist/services/ProjectDetector.js +236 -0
  29. package/dist/services/ProjectDetector.js.map +1 -0
  30. package/dist/services/TestRunner.d.ts +46 -0
  31. package/dist/services/TestRunner.d.ts.map +1 -0
  32. package/dist/services/TestRunner.js +85 -0
  33. package/dist/services/TestRunner.js.map +1 -0
  34. package/dist/services/index.d.ts +2 -0
  35. package/dist/services/index.d.ts.map +1 -1
  36. package/dist/services/index.js +2 -0
  37. package/dist/services/index.js.map +1 -1
  38. package/dist/types/index.d.ts +1 -0
  39. package/dist/types/index.d.ts.map +1 -1
  40. package/dist/types/index.js.map +1 -1
  41. package/framework/agents/claude/.claude/agents/red64/spec-impl.md +131 -2
  42. package/framework/agents/claude/.claude/commands/red64/spec-impl.md +24 -0
  43. package/framework/agents/codex/.codex/agents/red64/spec-impl.md +131 -2
  44. package/framework/agents/codex/.codex/commands/red64/spec-impl.md +24 -0
  45. package/framework/stacks/generic/feedback.md +80 -0
  46. package/framework/stacks/nextjs/accessibility.md +437 -0
  47. package/framework/stacks/nextjs/api.md +431 -0
  48. package/framework/stacks/nextjs/coding-style.md +282 -0
  49. package/framework/stacks/nextjs/commenting.md +226 -0
  50. package/framework/stacks/nextjs/components.md +411 -0
  51. package/framework/stacks/nextjs/conventions.md +333 -0
  52. package/framework/stacks/nextjs/css.md +310 -0
  53. package/framework/stacks/nextjs/error-handling.md +442 -0
  54. package/framework/stacks/nextjs/feedback.md +124 -0
  55. package/framework/stacks/nextjs/migrations.md +332 -0
  56. package/framework/stacks/nextjs/models.md +362 -0
  57. package/framework/stacks/nextjs/queries.md +410 -0
  58. package/framework/stacks/nextjs/responsive.md +338 -0
  59. package/framework/stacks/nextjs/tech-stack.md +177 -0
  60. package/framework/stacks/nextjs/test-writing.md +475 -0
  61. package/framework/stacks/nextjs/validation.md +467 -0
  62. package/framework/stacks/python/api.md +468 -0
  63. package/framework/stacks/python/authentication.md +342 -0
  64. package/framework/stacks/python/code-quality.md +283 -0
  65. package/framework/stacks/python/code-refactoring.md +315 -0
  66. package/framework/stacks/python/coding-style.md +462 -0
  67. package/framework/stacks/python/conventions.md +399 -0
  68. package/framework/stacks/python/error-handling.md +512 -0
  69. package/framework/stacks/python/feedback.md +92 -0
  70. package/framework/stacks/python/implement-ai-llm.md +468 -0
  71. package/framework/stacks/python/migrations.md +388 -0
  72. package/framework/stacks/python/models.md +399 -0
  73. package/framework/stacks/python/python.md +232 -0
  74. package/framework/stacks/python/queries.md +451 -0
  75. package/framework/stacks/python/structure.md +245 -58
  76. package/framework/stacks/python/tech.md +92 -35
  77. package/framework/stacks/python/testing.md +380 -0
  78. package/framework/stacks/python/validation.md +471 -0
  79. package/framework/stacks/rails/authentication.md +176 -0
  80. package/framework/stacks/rails/code-quality.md +287 -0
  81. package/framework/stacks/rails/code-refactoring.md +299 -0
  82. package/framework/stacks/rails/feedback.md +130 -0
  83. package/framework/stacks/rails/implement-ai-llm-with-rubyllm.md +342 -0
  84. package/framework/stacks/rails/rails.md +301 -0
  85. package/framework/stacks/rails/rails8-best-practices.md +498 -0
  86. package/framework/stacks/rails/rails8-css.md +573 -0
  87. package/framework/stacks/rails/structure.md +140 -0
  88. package/framework/stacks/rails/tech.md +108 -0
  89. package/framework/stacks/react/code-quality.md +521 -0
  90. package/framework/stacks/react/components.md +625 -0
  91. package/framework/stacks/react/data-fetching.md +586 -0
  92. package/framework/stacks/react/feedback.md +110 -0
  93. package/framework/stacks/react/forms.md +694 -0
  94. package/framework/stacks/react/performance.md +640 -0
  95. package/framework/stacks/react/product.md +22 -9
  96. package/framework/stacks/react/state-management.md +472 -0
  97. package/framework/stacks/react/structure.md +351 -44
  98. package/framework/stacks/react/tech.md +219 -30
  99. package/framework/stacks/react/testing.md +690 -0
  100. package/package.json +1 -1
  101. package/framework/stacks/node/product.md +0 -27
  102. package/framework/stacks/node/structure.md +0 -82
  103. package/framework/stacks/node/tech.md +0 -63
@@ -0,0 +1,287 @@
1
+ # Code Quality Standards
2
+
3
+ Project memory for code quality conventions, testing patterns, and maintainability standards in MediaPulse.
4
+
5
+ ---
6
+
7
+ ## Linting and Style
8
+
9
+ ### RuboCop Configuration
10
+ - **Style**: `rubocop-rails-omakase` - Rails default conventions
11
+ - Configuration: `.rubocop.yml` inherits from gem
12
+ - Run: `bundle exec rubocop`
13
+
14
+ ```ruby
15
+ # .rubocop.yml pattern: inherit defaults, override sparingly
16
+ inherit_gem: { rubocop-rails-omakase: rubocop.yml }
17
+
18
+ # Only add project-specific overrides when necessary
19
+ ```
20
+
21
+ ### Naming Conventions
22
+
23
+ | Type | Pattern | Example |
24
+ |------|---------|---------|
25
+ | Models | Singular, CamelCase | `Source`, `CollectedContent` |
26
+ | Controllers | Plural + Controller | `SourcesController` |
27
+ | Services | Action-oriented | `ContentCollectionService` |
28
+ | Jobs | Descriptive + Job | `CollectContentJob` |
29
+ | Tests | Subject + Test | `SourceTest` |
30
+
31
+ ---
32
+
33
+ ## Testing Patterns
34
+
35
+ ### Framework
36
+ - **Minitest** (Rails default) with Capybara for system tests
37
+ - **WebMock** for HTTP stubbing
38
+ - Parallel execution: `parallelize(workers: :number_of_processors)`
39
+ - Fixtures: `test/fixtures/*.yml`
40
+
41
+ ### Test Organization
42
+ Tests organized by type in `test/` directory:
43
+ - `test/models/` - Unit tests for ActiveRecord models
44
+ - `test/controllers/` - Controller action tests
45
+ - `test/services/` - Service object tests
46
+ - `test/integration/` - Multi-component workflow tests
47
+ - `test/system/` - Full browser tests (Capybara/Selenium)
48
+ - `test/helpers/` - View helper tests
49
+ - `test/views/` - View rendering tests
50
+ - `test/jobs/` - Background job tests
51
+
52
+ ### Test Style Pattern
53
+ ```ruby
54
+ # Pattern: Descriptive test blocks with setup and clear assertions
55
+ class SourceTest < ActiveSupport::TestCase
56
+ setup do
57
+ # Stub external dependencies
58
+ stub_request(:head, /example\.com/).to_return(status: 200)
59
+ end
60
+
61
+ # Test naming: describe behavior, not implementation
62
+ test "validates url presence" do
63
+ project = Project.create!(name: "Test", user: users(:one))
64
+ source = Source.new(project: project)
65
+
66
+ assert_not source.valid?
67
+ assert_includes source.errors[:url], "can't be blank"
68
+ end
69
+
70
+ # Pattern: Test behavior scenarios, not implementation details
71
+ test "detects youtube.com as youtube type" do
72
+ project = Project.create!(name: "Test", user: users(:one))
73
+ source = Source.create!(url: "https://www.youtube.com/watch?v=abc123", project: project)
74
+
75
+ assert source.youtube?
76
+ end
77
+ end
78
+ ```
79
+
80
+ ### Service Testing Pattern
81
+ ```ruby
82
+ # Pattern: Inject dependencies for testability
83
+ class ContentCollectionServiceTest < ActiveSupport::TestCase
84
+ test "returns error when source is already collecting" do
85
+ source = sources(:one)
86
+ source.update!(status: :collecting)
87
+
88
+ service = ContentCollectionService.new(source: source)
89
+ result = service.call
90
+
91
+ assert result.error?
92
+ assert_equal :already_collecting, result.error_type
93
+ end
94
+
95
+ # Pattern: Use dependency injection for external services
96
+ test "enqueues collection job on success" do
97
+ job_enqueued = false
98
+ mock_enqueuer = ->(id) { job_enqueued = true; OpenStruct.new(job_id: "test-123") }
99
+
100
+ service = ContentCollectionService.new(
101
+ source: source,
102
+ skip_credential_check: true,
103
+ job_enqueuer: mock_enqueuer
104
+ )
105
+
106
+ result = service.call
107
+ assert result.success?
108
+ assert job_enqueued
109
+ end
110
+ end
111
+ ```
112
+
113
+ ---
114
+
115
+ ## Code Organization
116
+
117
+ ### Service Objects
118
+ Place in `app/services/` when logic:
119
+ - Spans multiple models
120
+ - Involves external APIs
121
+ - Has complex business rules
122
+ - Needs extensive testing in isolation
123
+
124
+ ```ruby
125
+ # Pattern: Result objects for service outcomes
126
+ class ContentCollectionService
127
+ class Result
128
+ attr_reader :job_id, :error_type, :error_message
129
+
130
+ def initialize(success:, job_id: nil, error_type: nil, error_message: nil)
131
+ @success = success
132
+ @job_id = job_id
133
+ @error_type = error_type
134
+ @error_message = error_message
135
+ freeze
136
+ end
137
+
138
+ def success?
139
+ @success
140
+ end
141
+
142
+ def error?
143
+ !@success
144
+ end
145
+
146
+ # Factory methods for clarity
147
+ def self.success(job_id:)
148
+ new(success: true, job_id: job_id)
149
+ end
150
+
151
+ def self.error(type:, message:)
152
+ new(success: false, error_type: type, error_message: message)
153
+ end
154
+ end
155
+ end
156
+ ```
157
+
158
+ ### Error Handling Pattern
159
+ ```ruby
160
+ # Pattern: Custom error hierarchy for services
161
+ class LlmService
162
+ class Error < StandardError; end
163
+ class ConfigurationError < Error; end
164
+ class AuthenticationError < Error; end
165
+ class RateLimitError < Error; end
166
+ class ApiError < Error; end
167
+
168
+ # Map external errors to domain errors
169
+ def generate_ideas(prompt:, system_prompt: nil, model: DEFAULT_MODEL)
170
+ chat = build_chat(model: model, system_prompt: system_prompt)
171
+ response = chat.ask(prompt)
172
+ build_response(response)
173
+ rescue RubyLLM::UnauthorizedError => e
174
+ raise AuthenticationError, e.message
175
+ rescue RubyLLM::RateLimitError => e
176
+ raise RateLimitError, e.message
177
+ end
178
+ end
179
+ ```
180
+
181
+ ### Model Patterns
182
+ ```ruby
183
+ # Pattern: Lean models with clear responsibilities
184
+ class Source < ApplicationRecord
185
+ # 1. Includes
186
+ include Turbo::Broadcastable
187
+
188
+ # 2. Associations
189
+ belongs_to :project
190
+ belongs_to :feed, optional: true
191
+ has_many :ideas, through: :idea_sources
192
+
193
+ # 3. Enums
194
+ enum :source_type, { web: 0, youtube: 1, substack: 2 }
195
+ enum :status, { pending: 0, collecting: 1, collected: 2, failed: 3 }
196
+
197
+ # 4. Validations
198
+ validates :url, presence: true, format: { with: URI::DEFAULT_PARSER.make_regexp(%w[http https]) }
199
+ validates :url, uniqueness: { scope: [:project_id, :feed_id], case_sensitive: false }
200
+
201
+ # 5. Scopes
202
+ scope :from_feed, ->(feed) { where(feed: feed) }
203
+ scope :manually_added, -> { where(feed: nil) }
204
+ scope :search, ->(query) { where("url LIKE ? OR title LIKE ?", "%#{query}%", "%#{query}%") }
205
+
206
+ # 6. Callbacks (use sparingly)
207
+ before_validation :detect_source_type, on: :create
208
+
209
+ # 7. Public instance methods
210
+ def has_full_metadata?
211
+ title.present? && description.present? && published_at.present?
212
+ end
213
+
214
+ private
215
+
216
+ # 8. Private methods
217
+ def detect_source_type
218
+ # implementation
219
+ end
220
+ end
221
+ ```
222
+
223
+ ---
224
+
225
+ ## Security Analysis Tools
226
+
227
+ ### Static Analysis
228
+ - **Brakeman**: Security vulnerability scanner
229
+ - Run: `bundle exec brakeman`
230
+ - Check before deployment for SQL injection, XSS, CSRF issues
231
+
232
+ - **bundler-audit**: Gem vulnerability scanning
233
+ - Configuration: `config/bundler-audit.yml` for ignoring known issues
234
+ - Run: `bundle audit`
235
+
236
+ ### Credential Management
237
+ - Use Rails credentials: `bin/rails credentials:edit`
238
+ - Access: `Rails.application.credentials.dig(:service, :api_key)`
239
+ - Never commit unencrypted secrets
240
+ - Filter sensitive params (see `config/initializers/filter_parameter_logging.rb`)
241
+
242
+ ---
243
+
244
+ ## Documentation Standards
245
+
246
+ ### Method Documentation
247
+ ```ruby
248
+ # Pattern: Document public interfaces
249
+ # Unified service wrapping ruby_llm gem for multi-provider LLM access
250
+ #
251
+ # Usage:
252
+ # response = LlmService.generate_ideas(prompt: "...", system_prompt: "...")
253
+ # response.content #=> "Generated ideas..."
254
+ #
255
+ class LlmService
256
+ # Generate ideas from source content
257
+ #
258
+ # @param prompt [String] Formatted prompt with source content
259
+ # @param system_prompt [String, nil] System instructions
260
+ # @param model [String] Model identifier (default: claude-sonnet-4-20250514)
261
+ # @return [LlmResponse] Response with content and metadata
262
+ # @raise [ConfigurationError] if API key not configured
263
+ def generate_ideas(prompt:, system_prompt: nil, model: DEFAULT_MODEL)
264
+ # implementation
265
+ end
266
+ end
267
+ ```
268
+
269
+ ---
270
+
271
+ ## Quality Commands
272
+
273
+ ```bash
274
+ # Run all quality checks
275
+ bundle exec rubocop # Style
276
+ bundle exec brakeman # Security
277
+ bundle exec rake test # Tests
278
+ bundle exec rake test:system # System tests
279
+
280
+ # Development workflow
281
+ bin/rails test # Fast feedback
282
+ bin/rails test test/models/ # Focused testing
283
+ ```
284
+
285
+ ---
286
+
287
+ _Focus on patterns over exhaustive rules. Code should be readable, testable, and secure._
@@ -0,0 +1,299 @@
1
+ # Code Refactoring Patterns
2
+
3
+ Project memory for safe code refactoring strategies in MediaPulse.
4
+
5
+ ---
6
+
7
+ ## Refactoring Philosophy
8
+
9
+ Refactoring in MediaPulse follows three core principles:
10
+ 1. **Safety first**: Tests pass before and after every change
11
+ 2. **Small steps**: Incremental changes that can be reverted independently
12
+ 3. **Preserve behavior**: Refactoring changes structure, not functionality
13
+
14
+ ---
15
+
16
+ ## Extraction Patterns
17
+
18
+ ### Service Extraction
19
+
20
+ Extract business logic from controllers/models when it:
21
+ - Spans multiple models
22
+ - Involves external APIs
23
+ - Has complex business rules
24
+ - Needs extensive testing
25
+
26
+ **Pattern**: Controller to Service
27
+ ```ruby
28
+ # Before: Fat controller action
29
+ class CollectionsController < ApplicationController
30
+ def create
31
+ source = @project.sources.find(params[:source_id])
32
+ return render_error if source.collecting?
33
+
34
+ credential = Rails.application.credentials.dig(:service, :api_key)
35
+ return render_error("Missing credentials") if credential.blank?
36
+
37
+ source.update!(status: :collecting)
38
+ CollectContentJob.perform_later(source.id)
39
+ # ...
40
+ end
41
+ end
42
+
43
+ # After: Thin controller, extracted service
44
+ class CollectionsController < ApplicationController
45
+ def create
46
+ result = ContentCollectionService.new(source: @source).call
47
+
48
+ if result.success?
49
+ redirect_to @source, notice: "Collection started"
50
+ else
51
+ redirect_to @source, alert: result.error_message
52
+ end
53
+ end
54
+ end
55
+ ```
56
+
57
+ **Key elements**:
58
+ - Service returns Result object (success/error pattern)
59
+ - Controller only handles HTTP concerns
60
+ - Business logic fully testable in isolation
61
+
62
+ ### Concern Extraction
63
+
64
+ Extract shared model behavior into concerns when:
65
+ - Same logic appears in 3+ models
66
+ - Behavior is cohesive and nameable
67
+ - Logic is self-contained
68
+
69
+ **Pattern**: Model to Concern
70
+ ```ruby
71
+ # Before: Duplicated broadcast logic in models
72
+ class Source < ApplicationRecord
73
+ after_update_commit :broadcast_status_change, if: :saved_change_to_status?
74
+
75
+ def dom_target
76
+ "source_#{id}"
77
+ end
78
+
79
+ def broadcast_status_change
80
+ broadcast_replace_later_to(project, target: dom_target, ...)
81
+ end
82
+ end
83
+
84
+ # After: Extracted concern
85
+ # app/models/concerns/turbo_broadcastable.rb
86
+ module TurboBroadcastable
87
+ extend ActiveSupport::Concern
88
+
89
+ included do
90
+ include Turbo::Broadcastable
91
+ end
92
+
93
+ def dom_target
94
+ "#{model_name.singular}_#{id}"
95
+ end
96
+ end
97
+ ```
98
+
99
+ ### Strategy Pattern Extraction
100
+
101
+ Use when type-based conditionals grow complex:
102
+
103
+ ```ruby
104
+ # Before: Growing case statement
105
+ def process_content(source)
106
+ case source.source_type
107
+ when :youtube then # 50 lines
108
+ when :web then # 40 lines
109
+ when :twitter then # 45 lines
110
+ end
111
+ end
112
+
113
+ # After: Strategy pattern via registry
114
+ # ExtractorRegistry.for(:youtube) => YoutubeExtractor
115
+ result = ExtractorRegistry.extract(source)
116
+ ```
117
+
118
+ **Established patterns**:
119
+ - `ExtractorRegistry` maps source types to extractors
120
+ - `FeedTypeStrategy` provides type-specific configurations
121
+ - New types require only adding entry to registry + implementing class
122
+
123
+ ---
124
+
125
+ ## Safe Refactoring Workflow
126
+
127
+ ### Step 1: Ensure Test Coverage
128
+
129
+ Before refactoring, verify tests exist:
130
+ ```bash
131
+ # Check existing coverage
132
+ bin/rails test test/models/source_test.rb
133
+ bin/rails test test/services/
134
+
135
+ # Add characterization tests if missing
136
+ test "current behavior for X" do
137
+ # Document existing behavior before changing
138
+ end
139
+ ```
140
+
141
+ ### Step 2: Make Small, Reversible Changes
142
+
143
+ **Good**: One concept per commit
144
+ ```
145
+ commit 1: Extract Result class from service
146
+ commit 2: Move validation logic to private method
147
+ commit 3: Rename extracted method for clarity
148
+ ```
149
+
150
+ **Avoid**: Large refactors that touch many files
151
+
152
+ ### Step 3: Verify After Each Change
153
+
154
+ ```bash
155
+ # Run related tests
156
+ bin/rails test test/services/content_collection_service_test.rb
157
+
158
+ # Run full suite before pushing
159
+ bin/rails test
160
+ bundle exec rubocop
161
+ ```
162
+
163
+ ---
164
+
165
+ ## Dependency Injection for Testability
166
+
167
+ Services use dependency injection for external calls:
168
+
169
+ ```ruby
170
+ class ContentCollectionService
171
+ def initialize(source:, credentials_checker: nil, job_enqueuer: nil)
172
+ @source = source
173
+ @credentials_checker = credentials_checker || method(:default_credentials_checker)
174
+ @job_enqueuer = job_enqueuer || method(:default_job_enqueuer)
175
+ end
176
+ end
177
+
178
+ # In tests: inject mocks
179
+ service = ContentCollectionService.new(
180
+ source: source,
181
+ job_enqueuer: ->(id) { OpenStruct.new(job_id: "test-123") }
182
+ )
183
+ ```
184
+
185
+ **Pattern**: Default to production behavior, override in tests.
186
+
187
+ ---
188
+
189
+ ## Refactoring Signals
190
+
191
+ ### When to Extract
192
+
193
+ | Signal | Action |
194
+ |--------|--------|
195
+ | Controller action > 15 lines | Extract to service |
196
+ | Model > 150 lines | Consider concerns or query objects |
197
+ | Case statement > 3 branches | Consider strategy pattern |
198
+ | Same 5+ lines in multiple places | Extract to shared method/concern |
199
+ | External API call in model | Move to client class |
200
+
201
+ ### When NOT to Extract
202
+
203
+ - Single-use logic that fits naturally in one place
204
+ - Simple CRUD without business rules
205
+ - Premature abstraction (wait for 3+ uses)
206
+
207
+ ---
208
+
209
+ ## Backward Compatibility
210
+
211
+ ### API Deprecation Pattern
212
+
213
+ When changing public interfaces:
214
+
215
+ ```ruby
216
+ # Step 1: Add new method, keep old
217
+ def self.config_for(feed_type, custom_rules: nil)
218
+ # new implementation
219
+ end
220
+
221
+ # @deprecated Use config_for instead
222
+ def self.prompt_for(feed_type, custom_rules: nil)
223
+ config_for(feed_type, custom_rules: custom_rules).prompt
224
+ end
225
+
226
+ # Step 2: Add deprecation warning (future release)
227
+ # Step 3: Remove old method (after deprecation period)
228
+ ```
229
+
230
+ ### Database Migration Safety
231
+
232
+ For schema changes that affect running code:
233
+
234
+ ```ruby
235
+ # Safe: Add column with default
236
+ add_column :sources, :priority, :integer, default: 0
237
+
238
+ # Safe: Add index concurrently (PostgreSQL)
239
+ # For SQLite: migrations run quickly, less concern
240
+
241
+ # Risky: Rename column
242
+ # Use two-step: add new, migrate data, remove old
243
+ ```
244
+
245
+ ---
246
+
247
+ ## Common Refactoring Targets
248
+
249
+ ### Fat Models
250
+
251
+ Move to services when models handle:
252
+ - Complex state transitions
253
+ - Multi-model coordination
254
+ - External service calls
255
+
256
+ Keep in models:
257
+ - Validations and associations
258
+ - Simple scopes
259
+ - Attribute helpers
260
+
261
+ ### Complex Conditionals
262
+
263
+ Replace nested conditionals with:
264
+ - Guard clauses (early returns)
265
+ - Strategy/registry patterns
266
+ - Polymorphism where appropriate
267
+
268
+ ### Test Duplication
269
+
270
+ Extract to test helpers:
271
+ ```ruby
272
+ # test/test_helper.rb
273
+ def stub_external_services
274
+ stub_request(:head, /example\.com/).to_return(status: 200)
275
+ end
276
+ ```
277
+
278
+ ---
279
+
280
+ ## Refactoring Checklist
281
+
282
+ Before starting:
283
+ - [ ] Tests pass for affected code
284
+ - [ ] Understand current behavior fully
285
+ - [ ] Plan incremental steps
286
+
287
+ During refactoring:
288
+ - [ ] One logical change per commit
289
+ - [ ] Tests pass after each step
290
+ - [ ] No behavior changes (unless intentional)
291
+
292
+ After completing:
293
+ - [ ] Full test suite passes
294
+ - [ ] RuboCop passes
295
+ - [ ] Manual smoke test of affected features
296
+
297
+ ---
298
+
299
+ _Refactoring improves code structure while preserving behavior. Small, tested steps over large rewrites._
@@ -0,0 +1,130 @@
1
+ # Feedback Configuration
2
+
3
+ Project-specific commands for automated feedback during Rails implementation.
4
+
5
+ ---
6
+
7
+ ## Test Commands
8
+
9
+ Commands to run tests during implementation. The agent will use these to verify code changes.
10
+
11
+ ```yaml
12
+ # Primary test command (REQUIRED)
13
+ test: bin/rails test
14
+
15
+ # Test with verbose output
16
+ test_verbose: bin/rails test -v
17
+
18
+ # Run specific test file (use {file} as placeholder)
19
+ test_file: bin/rails test {file}
20
+
21
+ # Run system tests (browser-based)
22
+ test_system: bin/rails test:system
23
+
24
+ # Run all tests including system
25
+ test_all: bin/rails test:all
26
+ ```
27
+
28
+ ---
29
+
30
+ ## Linting Commands
31
+
32
+ Commands for code quality checks.
33
+
34
+ ```yaml
35
+ # Primary lint command (RuboCop)
36
+ lint: bundle exec rubocop
37
+
38
+ # Lint with auto-fix
39
+ lint_fix: bundle exec rubocop -A
40
+
41
+ # Security check (Brakeman)
42
+ security: bundle exec brakeman -q
43
+
44
+ # Bundle audit for dependencies
45
+ bundle_audit: bundle exec bundle-audit check --update
46
+ ```
47
+
48
+ ---
49
+
50
+ ## Development Server
51
+
52
+ Commands for starting the development server (required for UI verification).
53
+
54
+ ```yaml
55
+ # Start dev server (Rails)
56
+ dev_server: bin/rails server
57
+
58
+ # Dev server port
59
+ dev_port: 3000
60
+
61
+ # Dev server base URL
62
+ dev_url: http://localhost:3000
63
+
64
+ # Start with binding (for Docker)
65
+ dev_server_docker: bin/rails server -b 0.0.0.0
66
+ ```
67
+
68
+ ---
69
+
70
+ ## Database Commands
71
+
72
+ Commands for database operations.
73
+
74
+ ```yaml
75
+ # Run migrations
76
+ db_migrate: bin/rails db:migrate
77
+
78
+ # Setup test database
79
+ db_test_prepare: bin/rails db:test:prepare
80
+
81
+ # Reset database
82
+ db_reset: bin/rails db:reset
83
+ ```
84
+
85
+ ---
86
+
87
+ ## UI Verification
88
+
89
+ Settings for agent-browser UI verification.
90
+
91
+ ```yaml
92
+ # Enable UI verification for this project
93
+ ui_verification_enabled: true
94
+
95
+ # Default wait time after navigation (milliseconds)
96
+ navigation_wait: 3000
97
+
98
+ # Screenshot directory
99
+ screenshot_dir: /tmp/ui-captures
100
+
101
+ # Common routes to verify
102
+ routes:
103
+ - /
104
+ - /health
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Asset Pipeline
110
+
111
+ Commands for asset management.
112
+
113
+ ```yaml
114
+ # Precompile assets
115
+ assets_precompile: bin/rails assets:precompile
116
+
117
+ # Clean assets
118
+ assets_clean: bin/rails assets:clean
119
+ ```
120
+
121
+ ---
122
+
123
+ ## Notes
124
+
125
+ - Uses Minitest by default (or RSpec if configured)
126
+ - RuboCop for Ruby style enforcement
127
+ - Brakeman for security scanning
128
+ - Rails dev server on port 3000 by default
129
+ - System tests use Capybara with Selenium
130
+ - For Hotwire/Turbo projects, UI verification is essential