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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +37 -3
  3. data/Rakefile +98 -1
  4. data/app/controllers/pgbus/application_controller.rb +8 -0
  5. data/app/controllers/pgbus/recurring_tasks_controller.rb +36 -0
  6. data/app/helpers/pgbus/application_helper.rb +41 -0
  7. data/app/models/pgbus/application_record.rb +7 -0
  8. data/app/models/pgbus/batch_entry.rb +31 -0
  9. data/app/models/pgbus/blocked_execution.rb +40 -0
  10. data/app/models/pgbus/process_entry.rb +9 -0
  11. data/app/models/pgbus/processed_event.rb +9 -0
  12. data/app/models/pgbus/recurring_execution.rb +33 -0
  13. data/app/models/pgbus/recurring_task.rb +42 -0
  14. data/app/models/pgbus/semaphore.rb +29 -0
  15. data/app/views/layouts/pgbus/application.html.erb +1 -0
  16. data/app/views/pgbus/dashboard/_stats_cards.html.erb +9 -1
  17. data/app/views/pgbus/dead_letter/_messages_table.html.erb +55 -18
  18. data/app/views/pgbus/jobs/_enqueued_table.html.erb +46 -8
  19. data/app/views/pgbus/recurring_tasks/_tasks_table.html.erb +79 -0
  20. data/app/views/pgbus/recurring_tasks/index.html.erb +6 -0
  21. data/app/views/pgbus/recurring_tasks/show.html.erb +122 -0
  22. data/config/routes.rb +7 -0
  23. data/lib/active_job/queue_adapters/pgbus_adapter.rb +29 -0
  24. data/lib/generators/pgbus/add_recurring_generator.rb +56 -0
  25. data/lib/generators/pgbus/install_generator.rb +76 -2
  26. data/lib/generators/pgbus/templates/add_recurring_tables.rb.erb +31 -0
  27. data/lib/generators/pgbus/templates/migration.rb.erb +72 -4
  28. data/lib/generators/pgbus/templates/recurring.yml.erb +40 -0
  29. data/lib/generators/pgbus/templates/upgrade_pgmq.rb.erb +30 -0
  30. data/lib/generators/pgbus/upgrade_pgmq_generator.rb +60 -0
  31. data/lib/pgbus/active_job/adapter.rb +0 -3
  32. data/lib/pgbus/active_job/executor.rb +27 -12
  33. data/lib/pgbus/batch.rb +60 -69
  34. data/lib/pgbus/cli.rb +11 -16
  35. data/lib/pgbus/client.rb +25 -7
  36. data/lib/pgbus/concurrency/blocked_execution.rb +32 -37
  37. data/lib/pgbus/concurrency/semaphore.rb +11 -39
  38. data/lib/pgbus/concurrency.rb +10 -2
  39. data/lib/pgbus/configuration.rb +33 -0
  40. data/lib/pgbus/engine.rb +19 -1
  41. data/lib/pgbus/event_bus/handler.rb +4 -14
  42. data/lib/pgbus/instrumentation.rb +29 -0
  43. data/lib/pgbus/pgmq_schema/pgmq_v1.11.0.sql +2123 -0
  44. data/lib/pgbus/pgmq_schema.rb +159 -0
  45. data/lib/pgbus/process/consumer.rb +8 -9
  46. data/lib/pgbus/process/dispatcher.rb +26 -24
  47. data/lib/pgbus/process/heartbeat.rb +15 -23
  48. data/lib/pgbus/process/signal_handler.rb +23 -1
  49. data/lib/pgbus/process/supervisor.rb +51 -2
  50. data/lib/pgbus/process/worker.rb +37 -9
  51. data/lib/pgbus/recurring/already_recorded.rb +7 -0
  52. data/lib/pgbus/recurring/command_job.rb +16 -0
  53. data/lib/pgbus/recurring/config_loader.rb +35 -0
  54. data/lib/pgbus/recurring/schedule.rb +102 -0
  55. data/lib/pgbus/recurring/scheduler.rb +102 -0
  56. data/lib/pgbus/recurring/task.rb +111 -0
  57. data/lib/pgbus/serializer.rb +10 -6
  58. data/lib/pgbus/version.rb +1 -1
  59. data/lib/pgbus/web/data_source.rb +187 -22
  60. data/lib/pgbus.rb +8 -0
  61. data/lib/tasks/pgbus_pgmq.rake +62 -0
  62. metadata +51 -24
  63. data/.bun-version +0 -1
  64. data/.claude/commands/architect.md +0 -100
  65. data/.claude/commands/github-review-comments.md +0 -237
  66. data/.claude/commands/lfg.md +0 -271
  67. data/.claude/commands/review-pr.md +0 -69
  68. data/.claude/commands/security.md +0 -122
  69. data/.claude/commands/tdd.md +0 -148
  70. data/.claude/rules/agents.md +0 -49
  71. data/.claude/rules/coding-style.md +0 -91
  72. data/.claude/rules/git-workflow.md +0 -56
  73. data/.claude/rules/performance.md +0 -73
  74. data/.claude/rules/testing.md +0 -67
  75. data/CLAUDE.md +0 -80
  76. data/CODE_OF_CONDUCT.md +0 -10
  77. data/bun.lock +0 -18
  78. data/docs/README.md +0 -28
  79. data/docs/switch_from_good_job.md +0 -279
  80. data/docs/switch_from_sidekiq.md +0 -226
  81. data/docs/switch_from_solid_queue.md +0 -247
  82. data/package.json +0 -9
  83. 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.0.1
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
- - bun.lock
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
- - package.json
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: 4.0.6
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.