pgbus 0.0.1 → 0.1.1
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/README.md +37 -3
- data/Rakefile +98 -1
- data/app/controllers/pgbus/application_controller.rb +8 -0
- data/app/controllers/pgbus/recurring_tasks_controller.rb +36 -0
- data/app/helpers/pgbus/application_helper.rb +41 -0
- data/app/models/pgbus/application_record.rb +7 -0
- data/app/models/pgbus/batch_entry.rb +31 -0
- data/app/models/pgbus/blocked_execution.rb +40 -0
- data/app/models/pgbus/process_entry.rb +9 -0
- data/app/models/pgbus/processed_event.rb +9 -0
- data/app/models/pgbus/recurring_execution.rb +33 -0
- data/app/models/pgbus/recurring_task.rb +42 -0
- data/app/models/pgbus/semaphore.rb +29 -0
- data/app/views/layouts/pgbus/application.html.erb +1 -0
- data/app/views/pgbus/dashboard/_stats_cards.html.erb +9 -1
- data/app/views/pgbus/dead_letter/_messages_table.html.erb +55 -18
- data/app/views/pgbus/jobs/_enqueued_table.html.erb +46 -8
- data/app/views/pgbus/recurring_tasks/_tasks_table.html.erb +79 -0
- data/app/views/pgbus/recurring_tasks/index.html.erb +6 -0
- data/app/views/pgbus/recurring_tasks/show.html.erb +122 -0
- data/config/routes.rb +7 -0
- data/lib/active_job/queue_adapters/pgbus_adapter.rb +29 -0
- data/lib/generators/pgbus/add_recurring_generator.rb +56 -0
- data/lib/generators/pgbus/install_generator.rb +76 -2
- data/lib/generators/pgbus/templates/add_recurring_tables.rb.erb +31 -0
- data/lib/generators/pgbus/templates/migration.rb.erb +72 -4
- data/lib/generators/pgbus/templates/recurring.yml.erb +40 -0
- data/lib/generators/pgbus/templates/upgrade_pgmq.rb.erb +30 -0
- data/lib/generators/pgbus/upgrade_pgmq_generator.rb +60 -0
- data/lib/pgbus/active_job/adapter.rb +0 -3
- data/lib/pgbus/active_job/executor.rb +27 -12
- data/lib/pgbus/batch.rb +60 -69
- data/lib/pgbus/cli.rb +11 -16
- data/lib/pgbus/client.rb +25 -7
- data/lib/pgbus/concurrency/blocked_execution.rb +32 -37
- data/lib/pgbus/concurrency/semaphore.rb +11 -39
- data/lib/pgbus/concurrency.rb +10 -2
- data/lib/pgbus/configuration.rb +33 -0
- data/lib/pgbus/engine.rb +19 -1
- data/lib/pgbus/event_bus/handler.rb +4 -14
- data/lib/pgbus/instrumentation.rb +29 -0
- data/lib/pgbus/pgmq_schema/pgmq_v1.11.0.sql +2123 -0
- data/lib/pgbus/pgmq_schema.rb +159 -0
- data/lib/pgbus/process/consumer.rb +8 -9
- data/lib/pgbus/process/dispatcher.rb +26 -24
- data/lib/pgbus/process/heartbeat.rb +15 -23
- data/lib/pgbus/process/signal_handler.rb +23 -1
- data/lib/pgbus/process/supervisor.rb +51 -2
- data/lib/pgbus/process/worker.rb +37 -9
- data/lib/pgbus/recurring/already_recorded.rb +7 -0
- data/lib/pgbus/recurring/command_job.rb +16 -0
- data/lib/pgbus/recurring/config_loader.rb +35 -0
- data/lib/pgbus/recurring/schedule.rb +102 -0
- data/lib/pgbus/recurring/scheduler.rb +102 -0
- data/lib/pgbus/recurring/task.rb +111 -0
- data/lib/pgbus/serializer.rb +10 -6
- data/lib/pgbus/version.rb +1 -1
- data/lib/pgbus/web/data_source.rb +187 -22
- data/lib/pgbus.rb +8 -0
- data/lib/tasks/pgbus_pgmq.rake +62 -0
- metadata +51 -24
- data/.bun-version +0 -1
- data/.claude/commands/architect.md +0 -100
- data/.claude/commands/github-review-comments.md +0 -237
- data/.claude/commands/lfg.md +0 -271
- data/.claude/commands/review-pr.md +0 -69
- data/.claude/commands/security.md +0 -122
- data/.claude/commands/tdd.md +0 -148
- data/.claude/rules/agents.md +0 -49
- data/.claude/rules/coding-style.md +0 -91
- data/.claude/rules/git-workflow.md +0 -56
- data/.claude/rules/performance.md +0 -73
- data/.claude/rules/testing.md +0 -67
- data/CLAUDE.md +0 -80
- data/CODE_OF_CONDUCT.md +0 -10
- data/bun.lock +0 -18
- data/docs/README.md +0 -28
- data/docs/switch_from_good_job.md +0 -279
- data/docs/switch_from_sidekiq.md +0 -226
- data/docs/switch_from_solid_queue.md +0 -247
- data/package.json +0 -9
- data/sig/pgbus.rbs +0 -4
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
namespace :pgbus do
|
|
4
|
+
namespace :pgmq do
|
|
5
|
+
desc "Show current PGMQ schema status (installed version, available updates)"
|
|
6
|
+
task status: :environment do
|
|
7
|
+
require "pgbus/pgmq_schema"
|
|
8
|
+
|
|
9
|
+
puts "PGMQ Schema Status"
|
|
10
|
+
puts "=" * 40
|
|
11
|
+
|
|
12
|
+
latest = Pgbus::PgmqSchema.latest_version
|
|
13
|
+
puts "Vendored version: #{latest}"
|
|
14
|
+
|
|
15
|
+
if ActiveRecord::Base.connection.table_exists?("pgbus_pgmq_schema_versions")
|
|
16
|
+
row = ActiveRecord::Base.connection.select_one(
|
|
17
|
+
"SELECT version, install_method, installed_at FROM pgbus_pgmq_schema_versions ORDER BY installed_at DESC LIMIT 1"
|
|
18
|
+
)
|
|
19
|
+
if row
|
|
20
|
+
puts "Installed version: #{row["version"]}"
|
|
21
|
+
puts "Install method: #{row["install_method"]}"
|
|
22
|
+
puts "Installed at: #{row["installed_at"]}"
|
|
23
|
+
|
|
24
|
+
puts ""
|
|
25
|
+
if Gem::Version.new(row["version"]) < Gem::Version.new(latest)
|
|
26
|
+
puts "Update available! Run: rails generate pgbus:upgrade_pgmq"
|
|
27
|
+
else
|
|
28
|
+
puts "Schema is up to date."
|
|
29
|
+
end
|
|
30
|
+
else
|
|
31
|
+
puts "Installed version: unknown (no records in tracking table)"
|
|
32
|
+
end
|
|
33
|
+
else
|
|
34
|
+
# Check if pgmq schema exists at all
|
|
35
|
+
schema_exists = ActiveRecord::Base.connection.select_value(
|
|
36
|
+
"SELECT 1 FROM information_schema.schemata WHERE schema_name = 'pgmq'"
|
|
37
|
+
)
|
|
38
|
+
if schema_exists
|
|
39
|
+
puts "Installed version: unknown (installed before version tracking)"
|
|
40
|
+
puts ""
|
|
41
|
+
puts "Run: rails generate pgbus:upgrade_pgmq"
|
|
42
|
+
puts "This will add version tracking and ensure latest functions."
|
|
43
|
+
else
|
|
44
|
+
puts "PGMQ is not installed."
|
|
45
|
+
puts ""
|
|
46
|
+
puts "Run: rails generate pgbus:install"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
desc "Show available vendored PGMQ versions"
|
|
52
|
+
task versions: :environment do
|
|
53
|
+
require "pgbus/pgmq_schema"
|
|
54
|
+
|
|
55
|
+
puts "Available vendored PGMQ versions:"
|
|
56
|
+
Pgbus::PgmqSchema.available_versions.each do |v|
|
|
57
|
+
marker = v == Pgbus::PgmqSchema.latest_version ? " (latest)" : ""
|
|
58
|
+
puts " #{v}#{marker}"
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pgbus
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mikael Henriksson
|
|
@@ -23,6 +23,26 @@ dependencies:
|
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '1.2'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: fugit
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '1.11'
|
|
33
|
+
- - ">="
|
|
34
|
+
- !ruby/object:Gem::Version
|
|
35
|
+
version: 1.11.1
|
|
36
|
+
type: :runtime
|
|
37
|
+
prerelease: false
|
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
39
|
+
requirements:
|
|
40
|
+
- - "~>"
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '1.11'
|
|
43
|
+
- - ">="
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: 1.11.1
|
|
26
46
|
- !ruby/object:Gem::Dependency
|
|
27
47
|
name: pgmq-ruby
|
|
28
48
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -83,21 +103,7 @@ executables:
|
|
|
83
103
|
extensions: []
|
|
84
104
|
extra_rdoc_files: []
|
|
85
105
|
files:
|
|
86
|
-
- ".bun-version"
|
|
87
|
-
- ".claude/commands/architect.md"
|
|
88
|
-
- ".claude/commands/github-review-comments.md"
|
|
89
|
-
- ".claude/commands/lfg.md"
|
|
90
|
-
- ".claude/commands/review-pr.md"
|
|
91
|
-
- ".claude/commands/security.md"
|
|
92
|
-
- ".claude/commands/tdd.md"
|
|
93
|
-
- ".claude/rules/agents.md"
|
|
94
|
-
- ".claude/rules/coding-style.md"
|
|
95
|
-
- ".claude/rules/git-workflow.md"
|
|
96
|
-
- ".claude/rules/performance.md"
|
|
97
|
-
- ".claude/rules/testing.md"
|
|
98
106
|
- CHANGELOG.md
|
|
99
|
-
- CLAUDE.md
|
|
100
|
-
- CODE_OF_CONDUCT.md
|
|
101
107
|
- LICENSE.txt
|
|
102
108
|
- README.md
|
|
103
109
|
- Rakefile
|
|
@@ -109,7 +115,16 @@ files:
|
|
|
109
115
|
- app/controllers/pgbus/jobs_controller.rb
|
|
110
116
|
- app/controllers/pgbus/processes_controller.rb
|
|
111
117
|
- app/controllers/pgbus/queues_controller.rb
|
|
118
|
+
- app/controllers/pgbus/recurring_tasks_controller.rb
|
|
112
119
|
- app/helpers/pgbus/application_helper.rb
|
|
120
|
+
- app/models/pgbus/application_record.rb
|
|
121
|
+
- app/models/pgbus/batch_entry.rb
|
|
122
|
+
- app/models/pgbus/blocked_execution.rb
|
|
123
|
+
- app/models/pgbus/process_entry.rb
|
|
124
|
+
- app/models/pgbus/processed_event.rb
|
|
125
|
+
- app/models/pgbus/recurring_execution.rb
|
|
126
|
+
- app/models/pgbus/recurring_task.rb
|
|
127
|
+
- app/models/pgbus/semaphore.rb
|
|
113
128
|
- app/views/layouts/pgbus/application.html.erb
|
|
114
129
|
- app/views/pgbus/dashboard/_processes_table.html.erb
|
|
115
130
|
- app/views/pgbus/dashboard/_queues_table.html.erb
|
|
@@ -130,17 +145,21 @@ files:
|
|
|
130
145
|
- app/views/pgbus/queues/_queues_list.html.erb
|
|
131
146
|
- app/views/pgbus/queues/index.html.erb
|
|
132
147
|
- app/views/pgbus/queues/show.html.erb
|
|
133
|
-
-
|
|
148
|
+
- app/views/pgbus/recurring_tasks/_tasks_table.html.erb
|
|
149
|
+
- app/views/pgbus/recurring_tasks/index.html.erb
|
|
150
|
+
- app/views/pgbus/recurring_tasks/show.html.erb
|
|
134
151
|
- config/routes.rb
|
|
135
|
-
- docs/README.md
|
|
136
|
-
- docs/switch_from_good_job.md
|
|
137
|
-
- docs/switch_from_sidekiq.md
|
|
138
|
-
- docs/switch_from_solid_queue.md
|
|
139
152
|
- exe/pgbus
|
|
153
|
+
- lib/active_job/queue_adapters/pgbus_adapter.rb
|
|
154
|
+
- lib/generators/pgbus/add_recurring_generator.rb
|
|
140
155
|
- lib/generators/pgbus/install_generator.rb
|
|
156
|
+
- lib/generators/pgbus/templates/add_recurring_tables.rb.erb
|
|
141
157
|
- lib/generators/pgbus/templates/migration.rb.erb
|
|
142
158
|
- lib/generators/pgbus/templates/pgbus.yml.erb
|
|
143
159
|
- lib/generators/pgbus/templates/pgbus_binstub.erb
|
|
160
|
+
- lib/generators/pgbus/templates/recurring.yml.erb
|
|
161
|
+
- lib/generators/pgbus/templates/upgrade_pgmq.rb.erb
|
|
162
|
+
- lib/generators/pgbus/upgrade_pgmq_generator.rb
|
|
144
163
|
- lib/pgbus.rb
|
|
145
164
|
- lib/pgbus/active_job/adapter.rb
|
|
146
165
|
- lib/pgbus/active_job/executor.rb
|
|
@@ -158,24 +177,32 @@ files:
|
|
|
158
177
|
- lib/pgbus/event_bus/publisher.rb
|
|
159
178
|
- lib/pgbus/event_bus/registry.rb
|
|
160
179
|
- lib/pgbus/event_bus/subscriber.rb
|
|
180
|
+
- lib/pgbus/instrumentation.rb
|
|
181
|
+
- lib/pgbus/pgmq_schema.rb
|
|
182
|
+
- lib/pgbus/pgmq_schema/pgmq_v1.11.0.sql
|
|
161
183
|
- lib/pgbus/process/consumer.rb
|
|
162
184
|
- lib/pgbus/process/dispatcher.rb
|
|
163
185
|
- lib/pgbus/process/heartbeat.rb
|
|
164
186
|
- lib/pgbus/process/signal_handler.rb
|
|
165
187
|
- lib/pgbus/process/supervisor.rb
|
|
166
188
|
- lib/pgbus/process/worker.rb
|
|
189
|
+
- lib/pgbus/recurring/already_recorded.rb
|
|
190
|
+
- lib/pgbus/recurring/command_job.rb
|
|
191
|
+
- lib/pgbus/recurring/config_loader.rb
|
|
192
|
+
- lib/pgbus/recurring/schedule.rb
|
|
193
|
+
- lib/pgbus/recurring/scheduler.rb
|
|
194
|
+
- lib/pgbus/recurring/task.rb
|
|
167
195
|
- lib/pgbus/serializer.rb
|
|
168
196
|
- lib/pgbus/version.rb
|
|
169
197
|
- lib/pgbus/web/authentication.rb
|
|
170
198
|
- lib/pgbus/web/data_source.rb
|
|
171
|
-
-
|
|
172
|
-
- sig/pgbus.rbs
|
|
199
|
+
- lib/tasks/pgbus_pgmq.rake
|
|
173
200
|
homepage: https://github.com/mhenrixon/pgbus
|
|
174
201
|
licenses:
|
|
175
202
|
- MIT
|
|
176
203
|
metadata:
|
|
177
204
|
homepage_uri: https://github.com/mhenrixon/pgbus
|
|
178
|
-
source_code_uri: https://github.com/mhenrixon/pgbus
|
|
205
|
+
source_code_uri: https://github.com/mhenrixon/pgbus/tree/main
|
|
179
206
|
changelog_uri: https://github.com/mhenrixon/pgbus/blob/main/CHANGELOG.md
|
|
180
207
|
rubygems_mfa_required: 'true'
|
|
181
208
|
rdoc_options: []
|
|
@@ -192,7 +219,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
192
219
|
- !ruby/object:Gem::Version
|
|
193
220
|
version: '0'
|
|
194
221
|
requirements: []
|
|
195
|
-
rubygems_version:
|
|
222
|
+
rubygems_version: 3.6.9
|
|
196
223
|
specification_version: 4
|
|
197
224
|
summary: PostgreSQL-native job processing and event bus for Rails, built on PGMQ
|
|
198
225
|
test_files: []
|
data/.bun-version
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
1.3.11
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: "Coordinates development across pgbus layers. Use when planning multi-layer features, orchestrating implementation order, or designing new subsystems."
|
|
3
|
-
model: claude-opus-4-6
|
|
4
|
-
argument-hint: "feature or task to coordinate"
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Pgbus Architect Mode
|
|
8
|
-
|
|
9
|
-
You are now in **Architect Mode** - coordinating development across all pgbus layers.
|
|
10
|
-
|
|
11
|
-
## Why This Skill Exists
|
|
12
|
-
|
|
13
|
-
Pgbus spans multiple layers (PGMQ transport, ActiveJob adapter, event bus, process model, dashboard). Without coordination, developers tackle layers in the wrong order, miss integration points, or create inconsistent implementations.
|
|
14
|
-
|
|
15
|
-
## Pgbus Architecture Layers
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
Layer 6: Dashboard (Web UI) app/controllers/pgbus/, app/views/pgbus/
|
|
19
|
-
Layer 5: CLI lib/pgbus/cli.rb
|
|
20
|
-
Layer 4: Process Model lib/pgbus/process/ (supervisor, worker, dispatcher, consumer)
|
|
21
|
-
Layer 3: Event Bus lib/pgbus/event_bus/ (publisher, subscriber, registry, handler)
|
|
22
|
-
Layer 2: ActiveJob Adapter lib/pgbus/active_job/ (adapter, executor)
|
|
23
|
-
Layer 1: Client lib/pgbus/client.rb (PGMQ wrapper)
|
|
24
|
-
Layer 0: Configuration lib/pgbus/configuration.rb, config_loader.rb
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## Typical Implementation Flow
|
|
28
|
-
|
|
29
|
-
1. **Configuration** - Add new config options if needed
|
|
30
|
-
2. **Client** - Add PGMQ operations to the client wrapper
|
|
31
|
-
3. **Adapter / Event Bus** - Build the feature's core logic
|
|
32
|
-
4. **Process Model** - Add worker/consumer support
|
|
33
|
-
5. **Dashboard** - Expose in the web UI via DataSource
|
|
34
|
-
6. **Tests** - Coverage across all touched layers
|
|
35
|
-
|
|
36
|
-
## When to Delegate vs. Do Directly
|
|
37
|
-
|
|
38
|
-
**Delegate when**:
|
|
39
|
-
- Multiple files across a layer need changes
|
|
40
|
-
- Deep domain expertise is needed (e.g., PGMQ internals)
|
|
41
|
-
- Work is clearly scoped to one layer
|
|
42
|
-
|
|
43
|
-
**Handle directly when**:
|
|
44
|
-
- Simple, single-file changes
|
|
45
|
-
- Cross-cutting concerns affecting multiple layers
|
|
46
|
-
- Quick fixes or minor adjustments
|
|
47
|
-
|
|
48
|
-
## Decision Guidelines
|
|
49
|
-
|
|
50
|
-
| Decision | Use When |
|
|
51
|
-
|----------|----------|
|
|
52
|
-
| New config option | Feature needs user-configurable behavior |
|
|
53
|
-
| New Client method | New PGMQ operation needed |
|
|
54
|
-
| New event handler | Business event needs processing |
|
|
55
|
-
| New worker type | Different processing pattern needed |
|
|
56
|
-
| Dashboard page | Users need visibility into new feature |
|
|
57
|
-
| Migration change | New metadata table or PGMQ queue |
|
|
58
|
-
|
|
59
|
-
## Integration Points
|
|
60
|
-
|
|
61
|
-
| When working on... | Also consider... |
|
|
62
|
-
|-------------------|------------------|
|
|
63
|
-
| Client changes | Worker/consumer that calls it |
|
|
64
|
-
| New queue type | Dead letter queue, dashboard visibility |
|
|
65
|
-
| Event bus feature | Idempotency table, subscriber registry |
|
|
66
|
-
| Process model | Heartbeat, supervisor restart logic |
|
|
67
|
-
| Dashboard | DataSource queries, authentication |
|
|
68
|
-
| Configuration | Config loader YAML, generator template |
|
|
69
|
-
|
|
70
|
-
## Common Mistakes to Avoid
|
|
71
|
-
|
|
72
|
-
| Wrong | Right |
|
|
73
|
-
|-------|-------|
|
|
74
|
-
| Start with dashboard | Start with client/adapter layer |
|
|
75
|
-
| Skip configuration | Make it configurable from the start |
|
|
76
|
-
| Direct PGMQ calls | Go through Client wrapper |
|
|
77
|
-
| Forget DLQ | Every queue needs a dead letter strategy |
|
|
78
|
-
| Skip tests | TDD -- tests first at every layer |
|
|
79
|
-
| Monolith methods | Small files, focused classes |
|
|
80
|
-
|
|
81
|
-
## Verification Checklist
|
|
82
|
-
|
|
83
|
-
- [ ] Implementation order planned (bottom-up)
|
|
84
|
-
- [ ] Dependencies between layers identified
|
|
85
|
-
- [ ] PGMQ operations go through Client
|
|
86
|
-
- [ ] Configuration is extensible
|
|
87
|
-
- [ ] Dashboard exposes new data via DataSource
|
|
88
|
-
- [ ] Tests cover all touched layers
|
|
89
|
-
- [ ] `bundle exec rubocop` passes
|
|
90
|
-
- [ ] `bundle exec rspec` passes
|
|
91
|
-
|
|
92
|
-
## Handoff
|
|
93
|
-
|
|
94
|
-
When complete, summarize:
|
|
95
|
-
- Implementation plan with layer order
|
|
96
|
-
- Files to create/modify per layer
|
|
97
|
-
- Integration points identified
|
|
98
|
-
- Architectural decisions made
|
|
99
|
-
|
|
100
|
-
Now, coordinate pgbus development with this architectural perspective.
|
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: "Use when a PR has unresolved review comments that need responses -- evaluates each comment, implements valid fixes, pushes back on incorrect suggestions, and resolves all threads."
|
|
3
|
-
model: claude-opus-4-6
|
|
4
|
-
argument-hint: "PR number (e.g., 123 or #123)"
|
|
5
|
-
allowed-tools: Bash(gh pr view:*), Bash(gh pr diff:*), Bash(gh pr comment:*), Bash(gh api:*), Bash(git log:*), Bash(git blame:*), Bash(git push:*), Bash(git commit:*), Bash(git add:*), Bash(bundle exec:*), Read, Write, Edit, Glob, Grep, Agent
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Review GitHub PR Comments: $ARGUMENTS
|
|
9
|
-
|
|
10
|
-
You are reviewing and responding to all unresolved review comments on a GitHub pull request. Apply technical rigour -- evaluate each comment against the actual codebase before accepting or rejecting it.
|
|
11
|
-
|
|
12
|
-
## Phase 0: Determine the PR Number
|
|
13
|
-
|
|
14
|
-
The user may provide a PR number as `$ARGUMENTS`. Parse it flexibly:
|
|
15
|
-
|
|
16
|
-
- `PR123`, `PR 123`, `pr123` -> PR 123
|
|
17
|
-
- `123` -> PR 123
|
|
18
|
-
- `#123` -> PR 123
|
|
19
|
-
- Empty/blank -> auto-detect from current branch
|
|
20
|
-
|
|
21
|
-
**If no PR number is provided**, detect it automatically:
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
gh pr list --author=@me --head="$(git branch --show-current)" --state=open --json number,title
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
If exactly one open PR exists for the current branch, use it. If none or multiple, ask the user.
|
|
28
|
-
|
|
29
|
-
Once you have the PR number, confirm it:
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
gh pr view <PR_NUMBER> --json title,state,url
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## Phase 1: Fetch All Unresolved Review Comments
|
|
38
|
-
|
|
39
|
-
Retrieve all review comments and identify unresolved ones:
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
# Get all review comments (not resolved)
|
|
43
|
-
gh api "repos/mhenrixon/pgbus/pulls/<PR_NUMBER>/comments" --paginate
|
|
44
|
-
|
|
45
|
-
# Get all review threads to check resolution status
|
|
46
|
-
gh api graphql -f query='
|
|
47
|
-
query($owner: String!, $repo: String!, $pr: Int!) {
|
|
48
|
-
repository(owner: $owner, name: $repo) {
|
|
49
|
-
pullRequest(number: $pr) {
|
|
50
|
-
reviewThreads(first: 100) {
|
|
51
|
-
nodes {
|
|
52
|
-
id
|
|
53
|
-
isResolved
|
|
54
|
-
path
|
|
55
|
-
line
|
|
56
|
-
comments(first: 20) {
|
|
57
|
-
nodes {
|
|
58
|
-
id
|
|
59
|
-
databaseId
|
|
60
|
-
body
|
|
61
|
-
author { login }
|
|
62
|
-
createdAt
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
' -f owner=mhenrixon -f repo=pgbus -F pr=<PR_NUMBER>
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
For each unresolved thread, extract:
|
|
74
|
-
- Thread ID (for resolving)
|
|
75
|
-
- Comment body (the review feedback)
|
|
76
|
-
- File path and line number (if inline)
|
|
77
|
-
- Author (to understand context)
|
|
78
|
-
|
|
79
|
-
Filter to only **unresolved** threads. Skip bot comments (CodeRabbit, dependabot), resolved threads, and PR description comments.
|
|
80
|
-
|
|
81
|
-
If there are no unresolved review comments, report that and stop.
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
## Phase 2: Read and Categorise Each Comment
|
|
86
|
-
|
|
87
|
-
For each unresolved comment, read the full body and categorise it:
|
|
88
|
-
|
|
89
|
-
| Category | Action |
|
|
90
|
-
|----------|--------|
|
|
91
|
-
| Valid fix needed | Implement the fix |
|
|
92
|
-
| Valid test gap | Add the missing test |
|
|
93
|
-
| Valid style/consistency issue | Fix it |
|
|
94
|
-
| Incorrect suggestion | Push back with technical reasoning |
|
|
95
|
-
| Suggestion conflicts with architecture | Push back, reference existing patterns |
|
|
96
|
-
| Over-engineering / YAGNI | Push back, explain why it's unnecessary |
|
|
97
|
-
| Unclear | Ask for clarification (do NOT implement) |
|
|
98
|
-
|
|
99
|
-
**Before categorising**, always:
|
|
100
|
-
1. Read the actual file and line being commented on
|
|
101
|
-
2. Check if the suggestion is technically correct for THIS codebase
|
|
102
|
-
3. Check if it would break existing functionality
|
|
103
|
-
4. Check if existing patterns/conventions contradict the suggestion
|
|
104
|
-
5. Check CLAUDE.md rules -- project conventions override reviewer preferences
|
|
105
|
-
|
|
106
|
-
---
|
|
107
|
-
|
|
108
|
-
## Phase 3: Implement Accepted Fixes
|
|
109
|
-
|
|
110
|
-
For all comments you've decided to accept:
|
|
111
|
-
|
|
112
|
-
1. **Make the code changes** -- edit the relevant files
|
|
113
|
-
2. **Run affected tests** to verify nothing breaks:
|
|
114
|
-
```bash
|
|
115
|
-
bundle exec rspec <relevant_spec_files>
|
|
116
|
-
```
|
|
117
|
-
3. **Run validators**:
|
|
118
|
-
```bash
|
|
119
|
-
bundle exec rubocop <changed_files>
|
|
120
|
-
```
|
|
121
|
-
4. **Commit** all fixes together with a clear message:
|
|
122
|
-
```bash
|
|
123
|
-
git commit -m "$(cat <<'EOF'
|
|
124
|
-
fix: address PR review feedback
|
|
125
|
-
|
|
126
|
-
- Description of fix 1
|
|
127
|
-
- Description of fix 2
|
|
128
|
-
EOF
|
|
129
|
-
)"
|
|
130
|
-
```
|
|
131
|
-
5. **Push** to the remote branch:
|
|
132
|
-
```bash
|
|
133
|
-
git push
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## Phase 4: Reply to Every Comment
|
|
139
|
-
|
|
140
|
-
For **each** unresolved thread, reply:
|
|
141
|
-
|
|
142
|
-
### For accepted fixes:
|
|
143
|
-
|
|
144
|
-
Reply with what was fixed and the commit SHA:
|
|
145
|
-
|
|
146
|
-
```bash
|
|
147
|
-
gh api "repos/mhenrixon/pgbus/pulls/<PR>/comments/<COMMENT_ID>/replies" \
|
|
148
|
-
--method POST \
|
|
149
|
-
-f 'body=Fixed in <SHA>. <Brief description of what changed>.'
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### For rejected suggestions:
|
|
153
|
-
|
|
154
|
-
Reply with technical reasoning:
|
|
155
|
-
|
|
156
|
-
```bash
|
|
157
|
-
gh api "repos/mhenrixon/pgbus/pulls/<PR>/comments/<COMMENT_ID>/replies" \
|
|
158
|
-
--method POST \
|
|
159
|
-
-f 'body=<Technical explanation of why the suggestion was not implemented>'
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### Resolving threads (via GraphQL):
|
|
163
|
-
|
|
164
|
-
After replying, resolve the thread:
|
|
165
|
-
|
|
166
|
-
```bash
|
|
167
|
-
gh api graphql -f query='
|
|
168
|
-
mutation($threadId: ID!) {
|
|
169
|
-
resolveReviewThread(input: {threadId: $threadId}) {
|
|
170
|
-
thread { isResolved }
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
' -f threadId=<THREAD_NODE_ID>
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
### For general PR comments (not inline review threads):
|
|
177
|
-
|
|
178
|
-
Reply directly:
|
|
179
|
-
|
|
180
|
-
```bash
|
|
181
|
-
gh pr comment <PR_NUMBER> --body "<Response addressing each point>"
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
---
|
|
185
|
-
|
|
186
|
-
## Phase 5: Verify Completion
|
|
187
|
-
|
|
188
|
-
After processing all comments, verify no unresolved threads remain:
|
|
189
|
-
|
|
190
|
-
```bash
|
|
191
|
-
gh api graphql -f query='
|
|
192
|
-
query($owner: String!, $repo: String!, $pr: Int!) {
|
|
193
|
-
repository(owner: $owner, name: $repo) {
|
|
194
|
-
pullRequest(number: $pr) {
|
|
195
|
-
reviewThreads(first: 100) {
|
|
196
|
-
totalCount
|
|
197
|
-
nodes { isResolved }
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
' -f owner=mhenrixon -f repo=pgbus -F pr=<PR_NUMBER>
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
Report the final tally: how many comments were accepted/fixed, how many were pushed back on, and confirm all threads are resolved.
|
|
206
|
-
|
|
207
|
-
---
|
|
208
|
-
|
|
209
|
-
## Response Style
|
|
210
|
-
|
|
211
|
-
When replying to comments:
|
|
212
|
-
|
|
213
|
-
- **No performative agreement** -- never say "Great point!" or "You're absolutely right!"
|
|
214
|
-
- **No gratitude** -- never say "Thanks for catching that"
|
|
215
|
-
- **Be direct** -- state the fix or the reasoning, nothing more
|
|
216
|
-
- **Reference commits** -- always include the short SHA when a fix was made
|
|
217
|
-
- **Be specific** -- when pushing back, reference actual code, not abstract principles
|
|
218
|
-
|
|
219
|
-
When pushing back:
|
|
220
|
-
|
|
221
|
-
- Use technical reasoning grounded in the actual codebase
|
|
222
|
-
- Reference existing patterns if the suggestion contradicts them
|
|
223
|
-
- Reference CLAUDE.md rules when applicable
|
|
224
|
-
- Explain what would break or what edge case the reviewer missed
|
|
225
|
-
- If the suggestion is valid in principle but wrong for this context, say so
|
|
226
|
-
|
|
227
|
-
---
|
|
228
|
-
|
|
229
|
-
## Important Notes
|
|
230
|
-
|
|
231
|
-
- Always read the actual code before evaluating a comment -- reviewers sometimes misread diffs
|
|
232
|
-
- If a comment reveals a genuine bug you missed, fix it without defensiveness
|
|
233
|
-
- If multiple comments suggest the same change, implement it once and reference the fix in all replies
|
|
234
|
-
- Bot reviewers (CodeRabbit, etc.) sometimes suggest changes that conflict with project conventions -- verify against CLAUDE.md
|
|
235
|
-
- If a new round of review comments appears after your push (from re-review), report that to the user rather than entering an infinite loop
|
|
236
|
-
|
|
237
|
-
Now begin by determining the PR number from `$ARGUMENTS` or the current branch.
|