ag-cortex 0.1.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.
- package/.agent/commands/test-browser.md +339 -0
- package/.agent/rules/00-constitution.md +46 -0
- package/.agent/rules/project-rules.md +49 -0
- package/.agent/skills/agent-browser/SKILL.md +223 -0
- package/.agent/skills/agent-native-architecture/SKILL.md +435 -0
- package/.agent/skills/agent-native-architecture/references/action-parity-discipline.md +409 -0
- package/.agent/skills/agent-native-architecture/references/agent-execution-patterns.md +467 -0
- package/.agent/skills/agent-native-architecture/references/agent-native-testing.md +582 -0
- package/.agent/skills/agent-native-architecture/references/architecture-patterns.md +478 -0
- package/.agent/skills/agent-native-architecture/references/dynamic-context-injection.md +338 -0
- package/.agent/skills/agent-native-architecture/references/files-universal-interface.md +301 -0
- package/.agent/skills/agent-native-architecture/references/from-primitives-to-domain-tools.md +359 -0
- package/.agent/skills/agent-native-architecture/references/mcp-tool-design.md +506 -0
- package/.agent/skills/agent-native-architecture/references/mobile-patterns.md +871 -0
- package/.agent/skills/agent-native-architecture/references/product-implications.md +443 -0
- package/.agent/skills/agent-native-architecture/references/refactoring-to-prompt-native.md +317 -0
- package/.agent/skills/agent-native-architecture/references/self-modification.md +269 -0
- package/.agent/skills/agent-native-architecture/references/shared-workspace-architecture.md +680 -0
- package/.agent/skills/agent-native-architecture/references/system-prompt-design.md +250 -0
- package/.agent/skills/agent-native-reviewer/SKILL.md +246 -0
- package/.agent/skills/andrew-kane-gem-writer/SKILL.md +184 -0
- package/.agent/skills/andrew-kane-gem-writer/references/database-adapters.md +231 -0
- package/.agent/skills/andrew-kane-gem-writer/references/module-organization.md +121 -0
- package/.agent/skills/andrew-kane-gem-writer/references/rails-integration.md +183 -0
- package/.agent/skills/andrew-kane-gem-writer/references/resources.md +119 -0
- package/.agent/skills/andrew-kane-gem-writer/references/testing-patterns.md +261 -0
- package/.agent/skills/ankane-readme-writer/SKILL.md +50 -0
- package/.agent/skills/architecture-strategist/SKILL.md +52 -0
- package/.agent/skills/best-practices-researcher/SKILL.md +100 -0
- package/.agent/skills/bug-reproduction-validator/SKILL.md +67 -0
- package/.agent/skills/code-simplicity-reviewer/SKILL.md +85 -0
- package/.agent/skills/coding-tutor/.claude-plugin/plugin.json +9 -0
- package/.agent/skills/coding-tutor/README.md +37 -0
- package/.agent/skills/coding-tutor/commands/quiz-me.md +1 -0
- package/.agent/skills/coding-tutor/commands/sync-tutorials.md +25 -0
- package/.agent/skills/coding-tutor/commands/teach-me.md +1 -0
- package/.agent/skills/coding-tutor/skills/coding-tutor/SKILL.md +214 -0
- package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/create_tutorial.py +202 -0
- package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/index_tutorials.py +203 -0
- package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/quiz_priority.py +190 -0
- package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/setup_tutorials.py +132 -0
- package/.agent/skills/compound-docs/SKILL.md +510 -0
- package/.agent/skills/compound-docs/assets/critical-pattern-template.md +34 -0
- package/.agent/skills/compound-docs/assets/resolution-template.md +93 -0
- package/.agent/skills/compound-docs/references/yaml-schema.md +65 -0
- package/.agent/skills/compound-docs/schema.yaml +176 -0
- package/.agent/skills/create-agent-skills/SKILL.md +299 -0
- package/.agent/skills/create-agent-skills/references/api-security.md +226 -0
- package/.agent/skills/create-agent-skills/references/be-clear-and-direct.md +531 -0
- package/.agent/skills/create-agent-skills/references/best-practices.md +404 -0
- package/.agent/skills/create-agent-skills/references/common-patterns.md +595 -0
- package/.agent/skills/create-agent-skills/references/core-principles.md +437 -0
- package/.agent/skills/create-agent-skills/references/executable-code.md +175 -0
- package/.agent/skills/create-agent-skills/references/iteration-and-testing.md +474 -0
- package/.agent/skills/create-agent-skills/references/official-spec.md +185 -0
- package/.agent/skills/create-agent-skills/references/recommended-structure.md +168 -0
- package/.agent/skills/create-agent-skills/references/skill-structure.md +372 -0
- package/.agent/skills/create-agent-skills/references/using-scripts.md +113 -0
- package/.agent/skills/create-agent-skills/references/using-templates.md +112 -0
- package/.agent/skills/create-agent-skills/references/workflows-and-validation.md +510 -0
- package/.agent/skills/create-agent-skills/templates/router-skill.md +73 -0
- package/.agent/skills/create-agent-skills/templates/simple-skill.md +33 -0
- package/.agent/skills/create-agent-skills/workflows/add-reference.md +96 -0
- package/.agent/skills/create-agent-skills/workflows/add-script.md +93 -0
- package/.agent/skills/create-agent-skills/workflows/add-template.md +74 -0
- package/.agent/skills/create-agent-skills/workflows/add-workflow.md +120 -0
- package/.agent/skills/create-agent-skills/workflows/audit-skill.md +138 -0
- package/.agent/skills/create-agent-skills/workflows/create-domain-expertise-skill.md +605 -0
- package/.agent/skills/create-agent-skills/workflows/create-new-skill.md +191 -0
- package/.agent/skills/create-agent-skills/workflows/get-guidance.md +121 -0
- package/.agent/skills/create-agent-skills/workflows/upgrade-to-router.md +161 -0
- package/.agent/skills/create-agent-skills/workflows/verify-skill.md +204 -0
- package/.agent/skills/data-integrity-guardian/SKILL.md +70 -0
- package/.agent/skills/data-migration-expert/SKILL.md +97 -0
- package/.agent/skills/deployment-verification-agent/SKILL.md +159 -0
- package/.agent/skills/design-implementation-reviewer/SKILL.md +85 -0
- package/.agent/skills/design-iterator/SKILL.md +197 -0
- package/.agent/skills/dhh-rails-reviewer/SKILL.md +45 -0
- package/.agent/skills/dhh-rails-style/SKILL.md +184 -0
- package/.agent/skills/dhh-rails-style/references/architecture.md +653 -0
- package/.agent/skills/dhh-rails-style/references/controllers.md +303 -0
- package/.agent/skills/dhh-rails-style/references/frontend.md +510 -0
- package/.agent/skills/dhh-rails-style/references/gems.md +266 -0
- package/.agent/skills/dhh-rails-style/references/models.md +359 -0
- package/.agent/skills/dhh-rails-style/references/testing.md +338 -0
- package/.agent/skills/dspy-ruby/SKILL.md +594 -0
- package/.agent/skills/dspy-ruby/assets/config-template.rb +359 -0
- package/.agent/skills/dspy-ruby/assets/module-template.rb +326 -0
- package/.agent/skills/dspy-ruby/assets/signature-template.rb +143 -0
- package/.agent/skills/dspy-ruby/references/core-concepts.md +265 -0
- package/.agent/skills/dspy-ruby/references/optimization.md +623 -0
- package/.agent/skills/dspy-ruby/references/providers.md +305 -0
- package/.agent/skills/every-style-editor/SKILL.md +134 -0
- package/.agent/skills/every-style-editor/references/EVERY_WRITE_STYLE.md +529 -0
- package/.agent/skills/figma-design-sync/SKILL.md +166 -0
- package/.agent/skills/file-todos/SKILL.md +251 -0
- package/.agent/skills/file-todos/assets/todo-template.md +155 -0
- package/.agent/skills/framework-docs-researcher/SKILL.md +83 -0
- package/.agent/skills/frontend-design/SKILL.md +42 -0
- package/.agent/skills/gemini-imagegen/SKILL.md +237 -0
- package/.agent/skills/gemini-imagegen/requirements.txt +2 -0
- package/.agent/skills/gemini-imagegen/scripts/compose_images.py +168 -0
- package/.agent/skills/gemini-imagegen/scripts/edit_image.py +157 -0
- package/.agent/skills/gemini-imagegen/scripts/gemini_images.py +265 -0
- package/.agent/skills/gemini-imagegen/scripts/generate_image.py +147 -0
- package/.agent/skills/gemini-imagegen/scripts/multi_turn_chat.py +215 -0
- package/.agent/skills/git-history-analyzer/SKILL.md +42 -0
- package/.agent/skills/git-worktree/SKILL.md +302 -0
- package/.agent/skills/git-worktree/scripts/worktree-manager.sh +345 -0
- package/.agent/skills/julik-frontend-races-reviewer/SKILL.md +222 -0
- package/.agent/skills/kieran-python-reviewer/SKILL.md +104 -0
- package/.agent/skills/kieran-rails-reviewer/SKILL.md +86 -0
- package/.agent/skills/kieran-typescript-reviewer/SKILL.md +95 -0
- package/.agent/skills/lint/SKILL.md +16 -0
- package/.agent/skills/pattern-recognition-specialist/SKILL.md +57 -0
- package/.agent/skills/performance-oracle/SKILL.md +110 -0
- package/.agent/skills/pr-comment-resolver/SKILL.md +69 -0
- package/.agent/skills/rclone/SKILL.md +150 -0
- package/.agent/skills/rclone/scripts/check_setup.sh +60 -0
- package/.agent/skills/repo-research-analyst/SKILL.md +113 -0
- package/.agent/skills/security-sentinel/SKILL.md +93 -0
- package/.agent/skills/skill-creator/SKILL.md +209 -0
- package/.agent/skills/skill-creator/scripts/init_skill.py +304 -0
- package/.agent/skills/skill-creator/scripts/package_skill.py +112 -0
- package/.agent/skills/skill-creator/scripts/quick_validate.py +72 -0
- package/.agent/skills/spec-flow-analyzer/SKILL.md +113 -0
- package/.agent/skills/test-agent/SKILL.md +4 -0
- package/.agent/workflows/agent-native-audit.md +277 -0
- package/.agent/workflows/ask-user-question.md +21 -0
- package/.agent/workflows/changelog.md +137 -0
- package/.agent/workflows/compound.md +202 -0
- package/.agent/workflows/create-agent-skill.md +8 -0
- package/.agent/workflows/deepen-plan-research.md +334 -0
- package/.agent/workflows/deepen-plan-synthesis.md +182 -0
- package/.agent/workflows/deepen-plan.md +79 -0
- package/.agent/workflows/feature-video.md +342 -0
- package/.agent/workflows/generate-command.md +162 -0
- package/.agent/workflows/heal-skill.md +142 -0
- package/.agent/workflows/lfg.md +20 -0
- package/.agent/workflows/plan-analysis.md +67 -0
- package/.agent/workflows/plan-next-steps.md +63 -0
- package/.agent/workflows/plan-review.md +33 -0
- package/.agent/workflows/plan-synthesis.md +106 -0
- package/.agent/workflows/plan.md +49 -0
- package/.agent/workflows/report-bug.md +150 -0
- package/.agent/workflows/reproduce-bug.md +99 -0
- package/.agent/workflows/resolve-parallel.md +34 -0
- package/.agent/workflows/resolve-pr-parallel.md +49 -0
- package/.agent/workflows/resolve-todo-parallel.md +35 -0
- package/.agent/workflows/review-analysis.md +145 -0
- package/.agent/workflows/review-synthesis.md +262 -0
- package/.agent/workflows/review.md +64 -0
- package/.agent/workflows/ship.md +90 -0
- package/.agent/workflows/test-command.md +3 -0
- package/.agent/workflows/triage.md +310 -0
- package/.agent/workflows/work.md +157 -0
- package/.agent/workflows/xcode-test.md +332 -0
- package/LICENSE +22 -0
- package/README.md +49 -0
- package/bin/ag-cortex.js +54 -0
- package/lib/core.js +165 -0
- package/package.json +31 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# Database Adapter Patterns
|
|
2
|
+
|
|
3
|
+
## Abstract Base Class Pattern
|
|
4
|
+
|
|
5
|
+
```ruby
|
|
6
|
+
# lib/strong_migrations/adapters/abstract_adapter.rb
|
|
7
|
+
module StrongMigrations
|
|
8
|
+
module Adapters
|
|
9
|
+
class AbstractAdapter
|
|
10
|
+
def initialize(checker)
|
|
11
|
+
@checker = checker
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def min_version
|
|
15
|
+
nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def set_statement_timeout(timeout)
|
|
19
|
+
# no-op by default
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def check_lock_timeout
|
|
23
|
+
# no-op by default
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def connection
|
|
29
|
+
@checker.send(:connection)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def quote(value)
|
|
33
|
+
connection.quote(value)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## PostgreSQL Adapter
|
|
41
|
+
|
|
42
|
+
```ruby
|
|
43
|
+
# lib/strong_migrations/adapters/postgresql_adapter.rb
|
|
44
|
+
module StrongMigrations
|
|
45
|
+
module Adapters
|
|
46
|
+
class PostgreSQLAdapter < AbstractAdapter
|
|
47
|
+
def min_version
|
|
48
|
+
"12"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def set_statement_timeout(timeout)
|
|
52
|
+
select_all("SET statement_timeout = #{timeout.to_i * 1000}")
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def set_lock_timeout(timeout)
|
|
56
|
+
select_all("SET lock_timeout = #{timeout.to_i * 1000}")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def check_lock_timeout
|
|
60
|
+
lock_timeout = connection.select_value("SHOW lock_timeout")
|
|
61
|
+
lock_timeout_sec = timeout_to_sec(lock_timeout)
|
|
62
|
+
# validation logic
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
def select_all(sql)
|
|
68
|
+
connection.select_all(sql)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def timeout_to_sec(timeout)
|
|
72
|
+
units = {"us" => 1e-6, "ms" => 1e-3, "s" => 1, "min" => 60}
|
|
73
|
+
timeout.to_f * (units[timeout.gsub(/\d+/, "")] || 1e-3)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## MySQL Adapter
|
|
81
|
+
|
|
82
|
+
```ruby
|
|
83
|
+
# lib/strong_migrations/adapters/mysql_adapter.rb
|
|
84
|
+
module StrongMigrations
|
|
85
|
+
module Adapters
|
|
86
|
+
class MySQLAdapter < AbstractAdapter
|
|
87
|
+
def min_version
|
|
88
|
+
"8.0"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def set_statement_timeout(timeout)
|
|
92
|
+
select_all("SET max_execution_time = #{timeout.to_i * 1000}")
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def check_lock_timeout
|
|
96
|
+
lock_timeout = connection.select_value("SELECT @@lock_wait_timeout")
|
|
97
|
+
# validation logic
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## MariaDB Adapter (MySQL variant)
|
|
105
|
+
|
|
106
|
+
```ruby
|
|
107
|
+
# lib/strong_migrations/adapters/mariadb_adapter.rb
|
|
108
|
+
module StrongMigrations
|
|
109
|
+
module Adapters
|
|
110
|
+
class MariaDBAdapter < MySQLAdapter
|
|
111
|
+
def min_version
|
|
112
|
+
"10.5"
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Override MySQL-specific behavior
|
|
116
|
+
def set_statement_timeout(timeout)
|
|
117
|
+
select_all("SET max_statement_time = #{timeout.to_i}")
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Adapter Detection Pattern
|
|
125
|
+
|
|
126
|
+
Use regex matching on adapter name:
|
|
127
|
+
|
|
128
|
+
```ruby
|
|
129
|
+
def adapter
|
|
130
|
+
@adapter ||= case connection.adapter_name
|
|
131
|
+
when /postg/i
|
|
132
|
+
Adapters::PostgreSQLAdapter.new(self)
|
|
133
|
+
when /mysql|trilogy/i
|
|
134
|
+
if connection.try(:mariadb?)
|
|
135
|
+
Adapters::MariaDBAdapter.new(self)
|
|
136
|
+
else
|
|
137
|
+
Adapters::MySQLAdapter.new(self)
|
|
138
|
+
end
|
|
139
|
+
when /sqlite/i
|
|
140
|
+
Adapters::SQLiteAdapter.new(self)
|
|
141
|
+
else
|
|
142
|
+
Adapters::AbstractAdapter.new(self)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Multi-Database Support (PgHero pattern)
|
|
148
|
+
|
|
149
|
+
```ruby
|
|
150
|
+
module PgHero
|
|
151
|
+
class << self
|
|
152
|
+
attr_accessor :databases
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
self.databases = {}
|
|
156
|
+
|
|
157
|
+
def self.primary_database
|
|
158
|
+
databases.values.first
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def self.capture_query_stats(database: nil)
|
|
162
|
+
db = database ? databases[database] : primary_database
|
|
163
|
+
db.capture_query_stats
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
class Database
|
|
167
|
+
attr_reader :id, :config
|
|
168
|
+
|
|
169
|
+
def initialize(id, config)
|
|
170
|
+
@id = id
|
|
171
|
+
@config = config
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def connection_model
|
|
175
|
+
@connection_model ||= begin
|
|
176
|
+
Class.new(ActiveRecord::Base) do
|
|
177
|
+
self.abstract_class = true
|
|
178
|
+
end.tap do |model|
|
|
179
|
+
model.establish_connection(config)
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def connection
|
|
185
|
+
connection_model.connection
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Connection Switching
|
|
192
|
+
|
|
193
|
+
```ruby
|
|
194
|
+
def with_connection(database_name)
|
|
195
|
+
db = databases[database_name.to_s]
|
|
196
|
+
raise Error, "Unknown database: #{database_name}" unless db
|
|
197
|
+
|
|
198
|
+
yield db.connection
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Usage
|
|
202
|
+
PgHero.with_connection(:replica) do |conn|
|
|
203
|
+
conn.execute("SELECT * FROM users")
|
|
204
|
+
end
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## SQL Dialect Handling
|
|
208
|
+
|
|
209
|
+
```ruby
|
|
210
|
+
def quote_column(column)
|
|
211
|
+
case adapter_name
|
|
212
|
+
when /postg/i
|
|
213
|
+
%("#{column}")
|
|
214
|
+
when /mysql/i
|
|
215
|
+
"`#{column}`"
|
|
216
|
+
else
|
|
217
|
+
column
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def boolean_value(value)
|
|
222
|
+
case adapter_name
|
|
223
|
+
when /postg/i
|
|
224
|
+
value ? "true" : "false"
|
|
225
|
+
when /mysql/i
|
|
226
|
+
value ? "1" : "0"
|
|
227
|
+
else
|
|
228
|
+
value.to_s
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
```
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Module Organization Patterns
|
|
2
|
+
|
|
3
|
+
## Simple Gem Layout
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
lib/
|
|
7
|
+
├── gemname.rb # Entry point, config, errors
|
|
8
|
+
└── gemname/
|
|
9
|
+
├── helper.rb # Core functionality
|
|
10
|
+
├── engine.rb # Rails engine (if needed)
|
|
11
|
+
└── version.rb # VERSION constant only
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Complex Gem Layout (PgHero pattern)
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
lib/
|
|
18
|
+
├── pghero.rb
|
|
19
|
+
└── pghero/
|
|
20
|
+
├── database.rb # Main class
|
|
21
|
+
├── engine.rb # Rails engine
|
|
22
|
+
└── methods/ # Functional decomposition
|
|
23
|
+
├── basic.rb
|
|
24
|
+
├── connections.rb
|
|
25
|
+
├── indexes.rb
|
|
26
|
+
├── queries.rb
|
|
27
|
+
└── replication.rb
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Method Decomposition Pattern
|
|
31
|
+
|
|
32
|
+
Break large classes into includable modules by feature:
|
|
33
|
+
|
|
34
|
+
```ruby
|
|
35
|
+
# lib/pghero/database.rb
|
|
36
|
+
module PgHero
|
|
37
|
+
class Database
|
|
38
|
+
include Methods::Basic
|
|
39
|
+
include Methods::Connections
|
|
40
|
+
include Methods::Indexes
|
|
41
|
+
include Methods::Queries
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# lib/pghero/methods/indexes.rb
|
|
46
|
+
module PgHero
|
|
47
|
+
module Methods
|
|
48
|
+
module Indexes
|
|
49
|
+
def index_hit_rate
|
|
50
|
+
# implementation
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def unused_indexes
|
|
54
|
+
# implementation
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Version File Pattern
|
|
62
|
+
|
|
63
|
+
Keep version.rb minimal:
|
|
64
|
+
|
|
65
|
+
```ruby
|
|
66
|
+
# lib/gemname/version.rb
|
|
67
|
+
module GemName
|
|
68
|
+
VERSION = "2.0.0"
|
|
69
|
+
end
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Require Order in Entry Point
|
|
73
|
+
|
|
74
|
+
```ruby
|
|
75
|
+
# lib/searchkick.rb
|
|
76
|
+
|
|
77
|
+
# 1. Standard library
|
|
78
|
+
require "forwardable"
|
|
79
|
+
require "json"
|
|
80
|
+
|
|
81
|
+
# 2. External dependencies (minimal)
|
|
82
|
+
require "active_support"
|
|
83
|
+
|
|
84
|
+
# 3. Internal files via require_relative
|
|
85
|
+
require_relative "searchkick/index"
|
|
86
|
+
require_relative "searchkick/model"
|
|
87
|
+
require_relative "searchkick/query"
|
|
88
|
+
require_relative "searchkick/version"
|
|
89
|
+
|
|
90
|
+
# 4. Conditional Rails loading (LAST)
|
|
91
|
+
require_relative "searchkick/railtie" if defined?(Rails)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Autoload vs Require
|
|
95
|
+
|
|
96
|
+
Kane uses explicit `require_relative`, not autoload:
|
|
97
|
+
|
|
98
|
+
```ruby
|
|
99
|
+
# CORRECT
|
|
100
|
+
require_relative "gemname/model"
|
|
101
|
+
require_relative "gemname/query"
|
|
102
|
+
|
|
103
|
+
# AVOID
|
|
104
|
+
autoload :Model, "gemname/model"
|
|
105
|
+
autoload :Query, "gemname/query"
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Comments Style
|
|
109
|
+
|
|
110
|
+
Minimal section headers only:
|
|
111
|
+
|
|
112
|
+
```ruby
|
|
113
|
+
# dependencies
|
|
114
|
+
require "active_support"
|
|
115
|
+
|
|
116
|
+
# adapters
|
|
117
|
+
require_relative "adapters/postgresql_adapter"
|
|
118
|
+
|
|
119
|
+
# modules
|
|
120
|
+
require_relative "migration"
|
|
121
|
+
```
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# Rails Integration Patterns
|
|
2
|
+
|
|
3
|
+
## The Golden Rule
|
|
4
|
+
|
|
5
|
+
**Never require Rails gems directly.** This causes loading order issues.
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
# WRONG - causes premature loading
|
|
9
|
+
require "active_record"
|
|
10
|
+
ActiveRecord::Base.include(MyGem::Model)
|
|
11
|
+
|
|
12
|
+
# CORRECT - lazy loading
|
|
13
|
+
ActiveSupport.on_load(:active_record) do
|
|
14
|
+
extend MyGem::Model
|
|
15
|
+
end
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## ActiveSupport.on_load Hooks
|
|
19
|
+
|
|
20
|
+
Common hooks and their uses:
|
|
21
|
+
|
|
22
|
+
```ruby
|
|
23
|
+
# Models
|
|
24
|
+
ActiveSupport.on_load(:active_record) do
|
|
25
|
+
extend GemName::Model # Add class methods (searchkick, has_encrypted)
|
|
26
|
+
include GemName::Callbacks # Add instance methods
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Controllers
|
|
30
|
+
ActiveSupport.on_load(:action_controller) do
|
|
31
|
+
include Ahoy::Controller
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Jobs
|
|
35
|
+
ActiveSupport.on_load(:active_job) do
|
|
36
|
+
include GemName::JobExtensions
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Mailers
|
|
40
|
+
ActiveSupport.on_load(:action_mailer) do
|
|
41
|
+
include GemName::MailerExtensions
|
|
42
|
+
end
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Prepend for Behavior Modification
|
|
46
|
+
|
|
47
|
+
When overriding existing Rails methods:
|
|
48
|
+
|
|
49
|
+
```ruby
|
|
50
|
+
ActiveSupport.on_load(:active_record) do
|
|
51
|
+
ActiveRecord::Migration.prepend(StrongMigrations::Migration)
|
|
52
|
+
ActiveRecord::Migrator.prepend(StrongMigrations::Migrator)
|
|
53
|
+
end
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Railtie Pattern
|
|
57
|
+
|
|
58
|
+
Minimal Railtie for non-mountable gems:
|
|
59
|
+
|
|
60
|
+
```ruby
|
|
61
|
+
# lib/gemname/railtie.rb
|
|
62
|
+
module GemName
|
|
63
|
+
class Railtie < Rails::Railtie
|
|
64
|
+
initializer "gemname.configure" do
|
|
65
|
+
ActiveSupport.on_load(:active_record) do
|
|
66
|
+
extend GemName::Model
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Optional: Add to controller runtime logging
|
|
71
|
+
initializer "gemname.log_runtime" do
|
|
72
|
+
require_relative "controller_runtime"
|
|
73
|
+
ActiveSupport.on_load(:action_controller) do
|
|
74
|
+
include GemName::ControllerRuntime
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Optional: Rake tasks
|
|
79
|
+
rake_tasks do
|
|
80
|
+
load "tasks/gemname.rake"
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Engine Pattern (Mountable Gems)
|
|
87
|
+
|
|
88
|
+
For gems with web interfaces (PgHero, Blazer, Ahoy):
|
|
89
|
+
|
|
90
|
+
```ruby
|
|
91
|
+
# lib/pghero/engine.rb
|
|
92
|
+
module PgHero
|
|
93
|
+
class Engine < ::Rails::Engine
|
|
94
|
+
isolate_namespace PgHero
|
|
95
|
+
|
|
96
|
+
initializer "pghero.assets", group: :all do |app|
|
|
97
|
+
if app.config.respond_to?(:assets) && defined?(Sprockets)
|
|
98
|
+
app.config.assets.precompile << "pghero/application.js"
|
|
99
|
+
app.config.assets.precompile << "pghero/application.css"
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
initializer "pghero.config" do
|
|
104
|
+
PgHero.config = Rails.application.config_for(:pghero) rescue {}
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Routes for Engines
|
|
111
|
+
|
|
112
|
+
```ruby
|
|
113
|
+
# config/routes.rb (in engine)
|
|
114
|
+
PgHero::Engine.routes.draw do
|
|
115
|
+
root to: "home#index"
|
|
116
|
+
resources :databases, only: [:show]
|
|
117
|
+
end
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Mount in app:
|
|
121
|
+
|
|
122
|
+
```ruby
|
|
123
|
+
# config/routes.rb (in app)
|
|
124
|
+
mount PgHero::Engine, at: "pghero"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## YAML Configuration with ERB
|
|
128
|
+
|
|
129
|
+
For complex gems needing config files:
|
|
130
|
+
|
|
131
|
+
```ruby
|
|
132
|
+
def self.settings
|
|
133
|
+
@settings ||= begin
|
|
134
|
+
path = Rails.root.join("config", "blazer.yml")
|
|
135
|
+
if path.exist?
|
|
136
|
+
YAML.safe_load(ERB.new(File.read(path)).result, aliases: true)
|
|
137
|
+
else
|
|
138
|
+
{}
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Generator Pattern
|
|
145
|
+
|
|
146
|
+
```ruby
|
|
147
|
+
# lib/generators/gemname/install_generator.rb
|
|
148
|
+
module GemName
|
|
149
|
+
module Generators
|
|
150
|
+
class InstallGenerator < Rails::Generators::Base
|
|
151
|
+
source_root File.expand_path("templates", __dir__)
|
|
152
|
+
|
|
153
|
+
def copy_initializer
|
|
154
|
+
template "initializer.rb", "config/initializers/gemname.rb"
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def copy_migration
|
|
158
|
+
migration_template "migration.rb", "db/migrate/create_gemname_tables.rb"
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Conditional Feature Detection
|
|
166
|
+
|
|
167
|
+
```ruby
|
|
168
|
+
# Check for specific Rails versions
|
|
169
|
+
if ActiveRecord.version >= Gem::Version.new("7.0")
|
|
170
|
+
# Rails 7+ specific code
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Check for optional dependencies
|
|
174
|
+
def self.client
|
|
175
|
+
@client ||= if defined?(OpenSearch::Client)
|
|
176
|
+
OpenSearch::Client.new
|
|
177
|
+
elsif defined?(Elasticsearch::Client)
|
|
178
|
+
Elasticsearch::Client.new
|
|
179
|
+
else
|
|
180
|
+
raise Error, "Install elasticsearch or opensearch-ruby"
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
```
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Andrew Kane Resources
|
|
2
|
+
|
|
3
|
+
## Primary Documentation
|
|
4
|
+
|
|
5
|
+
- **Gem Patterns Article**: https://ankane.org/gem-patterns
|
|
6
|
+
- Kane's own documentation of patterns used across his gems
|
|
7
|
+
- Covers configuration, Rails integration, error handling
|
|
8
|
+
|
|
9
|
+
## Top Ruby Gems by Stars
|
|
10
|
+
|
|
11
|
+
### Search & Data
|
|
12
|
+
|
|
13
|
+
| Gem | Stars | Description | Source |
|
|
14
|
+
|-----|-------|-------------|--------|
|
|
15
|
+
| **Searchkick** | 6.6k+ | Intelligent search for Rails | https://github.com/ankane/searchkick |
|
|
16
|
+
| **Chartkick** | 6.4k+ | Beautiful charts in Ruby | https://github.com/ankane/chartkick |
|
|
17
|
+
| **Groupdate** | 3.8k+ | Group by day, week, month | https://github.com/ankane/groupdate |
|
|
18
|
+
| **Blazer** | 4.6k+ | SQL dashboard for Rails | https://github.com/ankane/blazer |
|
|
19
|
+
|
|
20
|
+
### Database & Migrations
|
|
21
|
+
|
|
22
|
+
| Gem | Stars | Description | Source |
|
|
23
|
+
|-----|-------|-------------|--------|
|
|
24
|
+
| **PgHero** | 8.2k+ | PostgreSQL insights | https://github.com/ankane/pghero |
|
|
25
|
+
| **Strong Migrations** | 4.1k+ | Safe migration checks | https://github.com/ankane/strong_migrations |
|
|
26
|
+
| **Dexter** | 1.8k+ | Auto index advisor | https://github.com/ankane/dexter |
|
|
27
|
+
| **PgSync** | 1.5k+ | Sync Postgres data | https://github.com/ankane/pgsync |
|
|
28
|
+
|
|
29
|
+
### Security & Encryption
|
|
30
|
+
|
|
31
|
+
| Gem | Stars | Description | Source |
|
|
32
|
+
|-----|-------|-------------|--------|
|
|
33
|
+
| **Lockbox** | 1.5k+ | Application-level encryption | https://github.com/ankane/lockbox |
|
|
34
|
+
| **Blind Index** | 1.0k+ | Encrypted search | https://github.com/ankane/blind_index |
|
|
35
|
+
| **Secure Headers** | — | Contributed patterns | Referenced in gems |
|
|
36
|
+
|
|
37
|
+
### Analytics & ML
|
|
38
|
+
|
|
39
|
+
| Gem | Stars | Description | Source |
|
|
40
|
+
|-----|-------|-------------|--------|
|
|
41
|
+
| **Ahoy** | 4.2k+ | Analytics for Rails | https://github.com/ankane/ahoy |
|
|
42
|
+
| **Neighbor** | 1.1k+ | Vector search for Rails | https://github.com/ankane/neighbor |
|
|
43
|
+
| **Rover** | 700+ | DataFrames for Ruby | https://github.com/ankane/rover |
|
|
44
|
+
| **Tomoto** | 200+ | Topic modeling | https://github.com/ankane/tomoto-ruby |
|
|
45
|
+
|
|
46
|
+
### Utilities
|
|
47
|
+
|
|
48
|
+
| Gem | Stars | Description | Source |
|
|
49
|
+
|-----|-------|-------------|--------|
|
|
50
|
+
| **Pretender** | 2.0k+ | Login as another user | https://github.com/ankane/pretender |
|
|
51
|
+
| **Authtrail** | 900+ | Login activity tracking | https://github.com/ankane/authtrail |
|
|
52
|
+
| **Notable** | 200+ | Track notable requests | https://github.com/ankane/notable |
|
|
53
|
+
| **Logstop** | 200+ | Filter sensitive logs | https://github.com/ankane/logstop |
|
|
54
|
+
|
|
55
|
+
## Key Source Files to Study
|
|
56
|
+
|
|
57
|
+
### Entry Point Patterns
|
|
58
|
+
- https://github.com/ankane/searchkick/blob/master/lib/searchkick.rb
|
|
59
|
+
- https://github.com/ankane/pghero/blob/master/lib/pghero.rb
|
|
60
|
+
- https://github.com/ankane/strong_migrations/blob/master/lib/strong_migrations.rb
|
|
61
|
+
- https://github.com/ankane/lockbox/blob/master/lib/lockbox.rb
|
|
62
|
+
|
|
63
|
+
### Class Macro Implementations
|
|
64
|
+
- https://github.com/ankane/searchkick/blob/master/lib/searchkick/model.rb
|
|
65
|
+
- https://github.com/ankane/lockbox/blob/master/lib/lockbox/model.rb
|
|
66
|
+
- https://github.com/ankane/neighbor/blob/master/lib/neighbor/model.rb
|
|
67
|
+
- https://github.com/ankane/blind_index/blob/master/lib/blind_index/model.rb
|
|
68
|
+
|
|
69
|
+
### Rails Integration (Railtie/Engine)
|
|
70
|
+
- https://github.com/ankane/pghero/blob/master/lib/pghero/engine.rb
|
|
71
|
+
- https://github.com/ankane/searchkick/blob/master/lib/searchkick/railtie.rb
|
|
72
|
+
- https://github.com/ankane/ahoy/blob/master/lib/ahoy/engine.rb
|
|
73
|
+
- https://github.com/ankane/blazer/blob/master/lib/blazer/engine.rb
|
|
74
|
+
|
|
75
|
+
### Database Adapters
|
|
76
|
+
- https://github.com/ankane/strong_migrations/tree/master/lib/strong_migrations/adapters
|
|
77
|
+
- https://github.com/ankane/groupdate/tree/master/lib/groupdate/adapters
|
|
78
|
+
- https://github.com/ankane/neighbor/tree/master/lib/neighbor
|
|
79
|
+
|
|
80
|
+
### Error Messages (Template Pattern)
|
|
81
|
+
- https://github.com/ankane/strong_migrations/blob/master/lib/strong_migrations/error_messages.rb
|
|
82
|
+
|
|
83
|
+
### Gemspec Examples
|
|
84
|
+
- https://github.com/ankane/searchkick/blob/master/searchkick.gemspec
|
|
85
|
+
- https://github.com/ankane/neighbor/blob/master/neighbor.gemspec
|
|
86
|
+
- https://github.com/ankane/ahoy/blob/master/ahoy_matey.gemspec
|
|
87
|
+
|
|
88
|
+
### Test Setups
|
|
89
|
+
- https://github.com/ankane/searchkick/tree/master/test
|
|
90
|
+
- https://github.com/ankane/lockbox/tree/master/test
|
|
91
|
+
- https://github.com/ankane/strong_migrations/tree/master/test
|
|
92
|
+
|
|
93
|
+
## GitHub Profile
|
|
94
|
+
|
|
95
|
+
- **Profile**: https://github.com/ankane
|
|
96
|
+
- **All Ruby Repos**: https://github.com/ankane?tab=repositories&q=&type=&language=ruby&sort=stargazers
|
|
97
|
+
- **RubyGems Profile**: https://rubygems.org/profiles/ankane
|
|
98
|
+
|
|
99
|
+
## Blog Posts & Articles
|
|
100
|
+
|
|
101
|
+
- **ankane.org**: https://ankane.org/
|
|
102
|
+
- **Gem Patterns**: https://ankane.org/gem-patterns (essential reading)
|
|
103
|
+
- **Postgres Performance**: https://ankane.org/introducing-pghero
|
|
104
|
+
- **Search Tips**: https://ankane.org/search-rails
|
|
105
|
+
|
|
106
|
+
## Design Philosophy Summary
|
|
107
|
+
|
|
108
|
+
From studying 100+ gems, Kane's consistent principles:
|
|
109
|
+
|
|
110
|
+
1. **Zero dependencies when possible** - Each dep is a maintenance burden
|
|
111
|
+
2. **ActiveSupport.on_load always** - Never require Rails gems directly
|
|
112
|
+
3. **Class macro DSLs** - Single method configures everything
|
|
113
|
+
4. **Explicit over magic** - No method_missing, define methods directly
|
|
114
|
+
5. **Minitest only** - Simple, sufficient, no RSpec
|
|
115
|
+
6. **Multi-version testing** - Support broad Rails/Ruby versions
|
|
116
|
+
7. **Helpful errors** - Template-based messages with fix suggestions
|
|
117
|
+
8. **Abstract adapters** - Clean multi-database support
|
|
118
|
+
9. **Engine isolation** - isolate_namespace for mountable gems
|
|
119
|
+
10. **Minimal documentation** - Code is self-documenting, README is examples
|