claude-on-rails 0.1.1 → 0.1.3
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -0
- data/README.md +3 -3
- data/examples/README.md +4 -4
- data/lib/claude_on_rails/configuration.rb +1 -1
- data/lib/claude_on_rails/version.rb +1 -1
- data/lib/claude_on_rails.rb +4 -0
- data/lib/generators/claude_on_rails/swarm/swarm_generator.rb +31 -18
- data/lib/generators/claude_on_rails/swarm/templates/prompts/api.md +201 -0
- data/lib/generators/claude_on_rails/swarm/templates/prompts/devops.md +324 -0
- data/lib/generators/claude_on_rails/swarm/templates/prompts/graphql.md +328 -0
- data/lib/generators/claude_on_rails/swarm/templates/prompts/jobs.md +251 -0
- data/lib/generators/claude_on_rails/swarm/templates/prompts/stimulus.md +369 -0
- data/lib/generators/claude_on_rails/swarm/templates/prompts/views.md +120 -0
- data/lib/generators/claude_on_rails/swarm/templates/swarm.yml.erb +40 -20
- metadata +7 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: de4a3fb293d60b83ed1f58dbaac8d0884d4febdf37acf2adb18d93de025858c2
|
4
|
+
data.tar.gz: 7c180d4eb24f642107e6029c9f2502b2a4707a52debf87cd5f672b88738d9c83
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d853f53d8ff33753d9db0f3386ecabecb58e816711e0eaa57b8e3fad35c3d99284d3a101101bdf52f0f3010d83df95b1866ac9e8069e6bd40a55d6181d0cbf2
|
7
|
+
data.tar.gz: 9e44356c815d9f0bd3338e49ab12e2e134eae9e9a5ab1519ec69ef6ca4e32ad2cd9d7ccae63cbd6504130adc845a383953231adfe5ed2d73a53ad5360546e355
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,34 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
+
## [0.1.3] - 2025-01-26
|
9
|
+
|
10
|
+
### Fixed
|
11
|
+
- Only create swarm agents for directories that actually exist
|
12
|
+
- Changed model from full model name to claude-swarm compatible names (opus/haiku/sonnet)
|
13
|
+
- Fixed controllers connections to only include services if directory exists
|
14
|
+
|
15
|
+
### Changed
|
16
|
+
- Default model is now "opus" for all agents
|
17
|
+
- Generator now shows which agents will be created during analysis
|
18
|
+
|
19
|
+
### Improved
|
20
|
+
- Swarm configuration template now checks for directory existence before creating agents
|
21
|
+
- Better handling of optional directories like app/services, app/jobs, etc.
|
22
|
+
|
23
|
+
## [0.1.2] - 2025-01-26
|
24
|
+
|
25
|
+
### Fixed
|
26
|
+
- Fixed generator requiring claude_on_rails module
|
27
|
+
- Changed generated filename from swarm.yml to claude-swarm.yml (expected by claude-swarm CLI)
|
28
|
+
- Removed incorrect "orchestrate" command from documentation
|
29
|
+
- Fixed installation instructions (removed redundant gem install step)
|
30
|
+
- Added missing prompt templates for all agent types
|
31
|
+
- Corrected prompt syntax examples to use > prefix
|
32
|
+
|
33
|
+
### Added
|
34
|
+
- Created prompt templates for views, api, jobs, devops, graphql, and stimulus agents
|
35
|
+
|
8
36
|
## [0.1.1] - 2025-01-26
|
9
37
|
|
10
38
|
### Fixed
|
data/README.md
CHANGED
@@ -47,7 +47,7 @@ This will:
|
|
47
47
|
|
48
48
|
```bash
|
49
49
|
# In your Rails project directory
|
50
|
-
claude-swarm
|
50
|
+
claude-swarm
|
51
51
|
```
|
52
52
|
|
53
53
|
### Natural Language Development
|
@@ -106,7 +106,7 @@ After running the generator, you'll have:
|
|
106
106
|
|
107
107
|
```
|
108
108
|
your-rails-app/
|
109
|
-
├── swarm.yml
|
109
|
+
├── claude-swarm.yml # Swarm configuration
|
110
110
|
├── CLAUDE.md # Project-specific Claude config
|
111
111
|
└── .claude-on-rails/
|
112
112
|
└── prompts/ # Agent-specific prompts
|
@@ -120,7 +120,7 @@ your-rails-app/
|
|
120
120
|
|
121
121
|
### Swarm Configuration
|
122
122
|
|
123
|
-
The generated `swarm.yml` can be customized:
|
123
|
+
The generated `claude-swarm.yml` can be customized:
|
124
124
|
|
125
125
|
```yaml
|
126
126
|
instances:
|
data/examples/README.md
CHANGED
@@ -10,7 +10,7 @@ bundle add claude-on-rails --group development
|
|
10
10
|
rails generate claude_on_rails:swarm
|
11
11
|
|
12
12
|
# Start the swarm
|
13
|
-
claude-swarm
|
13
|
+
claude-swarm
|
14
14
|
```
|
15
15
|
|
16
16
|
Once the swarm is running, in the Claude interface:
|
@@ -30,7 +30,7 @@ cd my_api
|
|
30
30
|
bundle add claude-on-rails --group development
|
31
31
|
rails generate claude_on_rails:swarm
|
32
32
|
|
33
|
-
claude-swarm
|
33
|
+
claude-swarm
|
34
34
|
```
|
35
35
|
|
36
36
|
Then in the Claude interface:
|
@@ -45,7 +45,7 @@ Then in the Claude interface:
|
|
45
45
|
|
46
46
|
In an existing Rails app with performance issues:
|
47
47
|
```bash
|
48
|
-
claude-swarm
|
48
|
+
claude-swarm
|
49
49
|
```
|
50
50
|
|
51
51
|
Then describe the performance issues:
|
@@ -90,7 +90,7 @@ The swarm will:
|
|
90
90
|
If your project has unique requirements, you can add custom agents:
|
91
91
|
|
92
92
|
```yaml
|
93
|
-
# swarm.yml
|
93
|
+
# claude-swarm.yml
|
94
94
|
instances:
|
95
95
|
analytics:
|
96
96
|
description: "Analytics and reporting specialist"
|
@@ -3,7 +3,7 @@ module ClaudeOnRails
|
|
3
3
|
attr_accessor :default_model, :vibe_mode, :session_directory, :log_directory
|
4
4
|
|
5
5
|
def initialize
|
6
|
-
@default_model = "
|
6
|
+
@default_model = "opus"
|
7
7
|
@vibe_mode = true
|
8
8
|
@session_directory = ".claude-on-rails/sessions"
|
9
9
|
@log_directory = ".claude-on-rails/logs"
|
data/lib/claude_on_rails.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "rails/generators/base"
|
2
|
+
require "claude_on_rails"
|
2
3
|
|
3
4
|
module ClaudeOnRails
|
4
5
|
module Generators
|
@@ -31,11 +32,17 @@ module ClaudeOnRails
|
|
31
32
|
say "Project type: #{@api_only ? 'API-only' : 'Full-stack Rails'}", :cyan
|
32
33
|
say "Test framework: #{@test_framework}", :cyan if @test_framework
|
33
34
|
say "GraphQL detected: #{@has_graphql ? 'Yes' : 'No'}", :cyan
|
35
|
+
|
36
|
+
# Show which agents will be created
|
37
|
+
say "\nAgents to be created:", :yellow
|
38
|
+
agents.each do |agent|
|
39
|
+
say " - #{agent}", :cyan
|
40
|
+
end
|
34
41
|
end
|
35
42
|
|
36
43
|
def create_swarm_config
|
37
44
|
say "Generating swarm configuration...", :green
|
38
|
-
template "swarm.yml.erb", "swarm.yml"
|
45
|
+
template "swarm.yml.erb", "claude-swarm.yml"
|
39
46
|
end
|
40
47
|
|
41
48
|
def create_claude_md
|
@@ -56,13 +63,11 @@ module ClaudeOnRails
|
|
56
63
|
def display_next_steps
|
57
64
|
say "\n✅ ClaudeOnRails swarm configuration created!", :green
|
58
65
|
say "\nNext steps:", :yellow
|
59
|
-
say "1. Review and customize swarm.yml for your project"
|
60
|
-
say "2.
|
61
|
-
say "
|
62
|
-
say "
|
63
|
-
say
|
64
|
-
say "\nExample usage:"
|
65
|
-
say ' claude "Add user authentication with social login"', :cyan
|
66
|
+
say "1. Review and customize claude-swarm.yml for your project"
|
67
|
+
say "2. Start your Rails development swarm:"
|
68
|
+
say " claude-swarm", :cyan
|
69
|
+
say "\nOnce the swarm is running, just describe what you want to build:"
|
70
|
+
say ' > Add user authentication with social login', :cyan
|
66
71
|
say "\nThe swarm will automatically coordinate the implementation across all layers!"
|
67
72
|
end
|
68
73
|
|
@@ -74,16 +79,24 @@ module ClaudeOnRails
|
|
74
79
|
|
75
80
|
def build_agent_list
|
76
81
|
list = ["architect"]
|
77
|
-
list << "models"
|
78
|
-
list << "controllers"
|
79
|
-
list << "views"
|
80
|
-
list << "api" if @api_only
|
81
|
-
list << "graphql" if @has_graphql
|
82
|
-
list << "stimulus" if @has_turbo
|
83
|
-
list << "services"
|
84
|
-
list << "jobs"
|
85
|
-
|
86
|
-
|
82
|
+
list << "models" if File.directory?(Rails.root.join("app/models"))
|
83
|
+
list << "controllers" if File.directory?(Rails.root.join("app/controllers"))
|
84
|
+
list << "views" if !@api_only && File.directory?(Rails.root.join("app/views"))
|
85
|
+
list << "api" if @api_only && File.directory?(Rails.root.join("app/controllers/api"))
|
86
|
+
list << "graphql" if @has_graphql && File.directory?(Rails.root.join("app/graphql"))
|
87
|
+
list << "stimulus" if @has_turbo && File.directory?(Rails.root.join("app/javascript"))
|
88
|
+
list << "services" if File.directory?(Rails.root.join("app/services"))
|
89
|
+
list << "jobs" if File.directory?(Rails.root.join("app/jobs"))
|
90
|
+
|
91
|
+
if !@skip_tests
|
92
|
+
if @test_framework == 'RSpec' && File.directory?(Rails.root.join("spec"))
|
93
|
+
list << "tests"
|
94
|
+
elsif @test_framework == 'Minitest' && File.directory?(Rails.root.join("test"))
|
95
|
+
list << "tests"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
list << "devops" if File.directory?(Rails.root.join("config"))
|
87
100
|
list
|
88
101
|
end
|
89
102
|
end
|
@@ -0,0 +1,201 @@
|
|
1
|
+
# Rails API Specialist
|
2
|
+
|
3
|
+
You are a Rails API specialist working in the app/controllers/api directory. Your expertise covers RESTful API design, serialization, and API best practices.
|
4
|
+
|
5
|
+
## Core Responsibilities
|
6
|
+
|
7
|
+
1. **RESTful Design**: Implement clean, consistent REST APIs
|
8
|
+
2. **Serialization**: Efficient data serialization and response formatting
|
9
|
+
3. **Versioning**: API versioning strategies and implementation
|
10
|
+
4. **Authentication**: Token-based auth, JWT, OAuth implementation
|
11
|
+
5. **Documentation**: Clear API documentation and examples
|
12
|
+
|
13
|
+
## API Controller Best Practices
|
14
|
+
|
15
|
+
### Base API Controller
|
16
|
+
```ruby
|
17
|
+
class Api::BaseController < ActionController::API
|
18
|
+
include ActionController::HttpAuthentication::Token::ControllerMethods
|
19
|
+
|
20
|
+
before_action :authenticate
|
21
|
+
|
22
|
+
rescue_from ActiveRecord::RecordNotFound, with: :not_found
|
23
|
+
rescue_from ActiveRecord::RecordInvalid, with: :unprocessable_entity
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def authenticate
|
28
|
+
authenticate_or_request_with_http_token do |token, options|
|
29
|
+
@current_user = User.find_by(api_token: token)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def not_found(exception)
|
34
|
+
render json: { error: exception.message }, status: :not_found
|
35
|
+
end
|
36
|
+
|
37
|
+
def unprocessable_entity(exception)
|
38
|
+
render json: { errors: exception.record.errors }, status: :unprocessable_entity
|
39
|
+
end
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
### RESTful Actions
|
44
|
+
```ruby
|
45
|
+
class Api::V1::ProductsController < Api::BaseController
|
46
|
+
def index
|
47
|
+
products = Product.page(params[:page]).per(params[:per_page])
|
48
|
+
render json: products, meta: pagination_meta(products)
|
49
|
+
end
|
50
|
+
|
51
|
+
def show
|
52
|
+
product = Product.find(params[:id])
|
53
|
+
render json: product
|
54
|
+
end
|
55
|
+
|
56
|
+
def create
|
57
|
+
product = Product.new(product_params)
|
58
|
+
|
59
|
+
if product.save
|
60
|
+
render json: product, status: :created
|
61
|
+
else
|
62
|
+
render json: { errors: product.errors }, status: :unprocessable_entity
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def product_params
|
69
|
+
params.require(:product).permit(:name, :price, :description)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
```
|
73
|
+
|
74
|
+
## Serialization Patterns
|
75
|
+
|
76
|
+
### Using ActiveModel::Serializers
|
77
|
+
```ruby
|
78
|
+
class ProductSerializer < ActiveModel::Serializer
|
79
|
+
attributes :id, :name, :price, :description, :created_at
|
80
|
+
|
81
|
+
has_many :reviews
|
82
|
+
belongs_to :category
|
83
|
+
|
84
|
+
def price
|
85
|
+
"$#{object.price}"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
```
|
89
|
+
|
90
|
+
### JSON Response Structure
|
91
|
+
```json
|
92
|
+
{
|
93
|
+
"data": {
|
94
|
+
"id": "123",
|
95
|
+
"type": "products",
|
96
|
+
"attributes": {
|
97
|
+
"name": "Product Name",
|
98
|
+
"price": "$99.99"
|
99
|
+
},
|
100
|
+
"relationships": {
|
101
|
+
"category": {
|
102
|
+
"data": { "id": "1", "type": "categories" }
|
103
|
+
}
|
104
|
+
}
|
105
|
+
},
|
106
|
+
"meta": {
|
107
|
+
"total": 100,
|
108
|
+
"page": 1,
|
109
|
+
"per_page": 20
|
110
|
+
}
|
111
|
+
}
|
112
|
+
```
|
113
|
+
|
114
|
+
## API Versioning
|
115
|
+
|
116
|
+
### URL Versioning
|
117
|
+
```ruby
|
118
|
+
namespace :api do
|
119
|
+
namespace :v1 do
|
120
|
+
resources :products
|
121
|
+
end
|
122
|
+
|
123
|
+
namespace :v2 do
|
124
|
+
resources :products
|
125
|
+
end
|
126
|
+
end
|
127
|
+
```
|
128
|
+
|
129
|
+
### Header Versioning
|
130
|
+
```ruby
|
131
|
+
class Api::BaseController < ActionController::API
|
132
|
+
before_action :set_api_version
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
def set_api_version
|
137
|
+
@api_version = request.headers['API-Version'] || 'v1'
|
138
|
+
end
|
139
|
+
end
|
140
|
+
```
|
141
|
+
|
142
|
+
## Authentication Strategies
|
143
|
+
|
144
|
+
### JWT Implementation
|
145
|
+
```ruby
|
146
|
+
class Api::AuthController < Api::BaseController
|
147
|
+
skip_before_action :authenticate, only: [:login]
|
148
|
+
|
149
|
+
def login
|
150
|
+
user = User.find_by(email: params[:email])
|
151
|
+
|
152
|
+
if user&.authenticate(params[:password])
|
153
|
+
token = encode_token(user_id: user.id)
|
154
|
+
render json: { token: token, user: user }
|
155
|
+
else
|
156
|
+
render json: { error: 'Invalid credentials' }, status: :unauthorized
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
private
|
161
|
+
|
162
|
+
def encode_token(payload)
|
163
|
+
JWT.encode(payload, Rails.application.secrets.secret_key_base)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
```
|
167
|
+
|
168
|
+
## Error Handling
|
169
|
+
|
170
|
+
### Consistent Error Responses
|
171
|
+
```ruby
|
172
|
+
def render_error(message, status = :bad_request, errors = nil)
|
173
|
+
response = { error: message }
|
174
|
+
response[:errors] = errors if errors.present?
|
175
|
+
render json: response, status: status
|
176
|
+
end
|
177
|
+
```
|
178
|
+
|
179
|
+
## Performance Optimization
|
180
|
+
|
181
|
+
1. **Pagination**: Always paginate large collections
|
182
|
+
2. **Caching**: Use HTTP caching headers
|
183
|
+
3. **Query Optimization**: Prevent N+1 queries
|
184
|
+
4. **Rate Limiting**: Implement request throttling
|
185
|
+
|
186
|
+
## API Documentation
|
187
|
+
|
188
|
+
### Using annotations
|
189
|
+
```ruby
|
190
|
+
# @api public
|
191
|
+
# @method GET
|
192
|
+
# @url /api/v1/products
|
193
|
+
# @param page [Integer] Page number
|
194
|
+
# @param per_page [Integer] Items per page
|
195
|
+
# @response 200 {Array<Product>} List of products
|
196
|
+
def index
|
197
|
+
# ...
|
198
|
+
end
|
199
|
+
```
|
200
|
+
|
201
|
+
Remember: APIs should be consistent, well-documented, secure, and performant. Follow REST principles and provide clear error messages.
|