@aaronshaf/ger 1.2.11 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/.ast-grep/rules/no-as-casting.yml +13 -0
  2. package/.claude-plugin/plugin.json +22 -0
  3. package/.github/workflows/ci-simple.yml +53 -0
  4. package/.github/workflows/ci.yml +171 -0
  5. package/.github/workflows/claude-code-review.yml +83 -0
  6. package/.github/workflows/claude.yml +50 -0
  7. package/.github/workflows/dependency-update.yml +84 -0
  8. package/.github/workflows/release.yml +166 -0
  9. package/.github/workflows/security-scan.yml +113 -0
  10. package/.github/workflows/security.yml +96 -0
  11. package/.husky/pre-commit +16 -0
  12. package/.husky/pre-push +25 -0
  13. package/.lintstagedrc.json +6 -0
  14. package/.tool-versions +1 -0
  15. package/CLAUDE.md +105 -0
  16. package/DEVELOPMENT.md +361 -0
  17. package/EXAMPLES.md +457 -0
  18. package/README.md +831 -16
  19. package/bin/ger +3 -18
  20. package/biome.json +36 -0
  21. package/bun.lock +678 -0
  22. package/bunfig.toml +8 -0
  23. package/docs/adr/0001-use-effect-for-side-effects.md +65 -0
  24. package/docs/adr/0002-use-bun-runtime.md +64 -0
  25. package/docs/adr/0003-store-credentials-in-home-directory.md +75 -0
  26. package/docs/adr/0004-use-commander-for-cli.md +76 -0
  27. package/docs/adr/0005-use-effect-schema-for-validation.md +93 -0
  28. package/docs/adr/0006-use-msw-for-api-mocking.md +89 -0
  29. package/docs/adr/0007-git-hooks-for-quality.md +94 -0
  30. package/docs/adr/0008-no-as-typecasting.md +83 -0
  31. package/docs/adr/0009-file-size-limits.md +82 -0
  32. package/docs/adr/0010-llm-friendly-xml-output.md +93 -0
  33. package/docs/adr/0011-ai-tool-strategy-pattern.md +102 -0
  34. package/docs/adr/0012-build-status-message-parsing.md +94 -0
  35. package/docs/adr/0013-git-subprocess-integration.md +98 -0
  36. package/docs/adr/0014-group-management-support.md +95 -0
  37. package/docs/adr/0015-batch-comment-processing.md +111 -0
  38. package/docs/adr/0016-flexible-change-identifiers.md +94 -0
  39. package/docs/adr/0017-git-worktree-support.md +102 -0
  40. package/docs/adr/0018-auto-install-commit-hook.md +103 -0
  41. package/docs/adr/0019-sdk-package-exports.md +95 -0
  42. package/docs/adr/0020-code-coverage-enforcement.md +105 -0
  43. package/docs/adr/0021-typescript-isolated-declarations.md +83 -0
  44. package/docs/adr/0022-biome-oxlint-tooling.md +124 -0
  45. package/docs/adr/README.md +30 -0
  46. package/docs/prd/README.md +12 -0
  47. package/docs/prd/architecture.md +325 -0
  48. package/docs/prd/commands.md +425 -0
  49. package/docs/prd/data-model.md +349 -0
  50. package/docs/prd/overview.md +124 -0
  51. package/index.ts +219 -0
  52. package/oxlint.json +24 -0
  53. package/package.json +82 -15
  54. package/scripts/check-coverage.ts +69 -0
  55. package/scripts/check-file-size.ts +38 -0
  56. package/scripts/fix-test-mocks.ts +55 -0
  57. package/skills/gerrit-workflow/SKILL.md +247 -0
  58. package/skills/gerrit-workflow/examples.md +572 -0
  59. package/skills/gerrit-workflow/reference.md +728 -0
  60. package/src/api/gerrit.ts +696 -0
  61. package/src/cli/commands/abandon.ts +65 -0
  62. package/src/cli/commands/add-reviewer.ts +156 -0
  63. package/src/cli/commands/build-status.ts +282 -0
  64. package/src/cli/commands/checkout.ts +422 -0
  65. package/src/cli/commands/comment.ts +460 -0
  66. package/src/cli/commands/comments.ts +85 -0
  67. package/src/cli/commands/diff.ts +71 -0
  68. package/src/cli/commands/extract-url.ts +266 -0
  69. package/src/cli/commands/groups-members.ts +104 -0
  70. package/src/cli/commands/groups-show.ts +169 -0
  71. package/src/cli/commands/groups.ts +137 -0
  72. package/src/cli/commands/incoming.ts +226 -0
  73. package/src/cli/commands/init.ts +164 -0
  74. package/src/cli/commands/mine.ts +115 -0
  75. package/src/cli/commands/open.ts +57 -0
  76. package/src/cli/commands/projects.ts +68 -0
  77. package/src/cli/commands/push.ts +430 -0
  78. package/src/cli/commands/rebase.ts +52 -0
  79. package/src/cli/commands/remove-reviewer.ts +123 -0
  80. package/src/cli/commands/restore.ts +50 -0
  81. package/src/cli/commands/review.ts +486 -0
  82. package/src/cli/commands/search.ts +162 -0
  83. package/src/cli/commands/setup.ts +286 -0
  84. package/src/cli/commands/show.ts +491 -0
  85. package/src/cli/commands/status.ts +35 -0
  86. package/src/cli/commands/submit.ts +108 -0
  87. package/src/cli/commands/vote.ts +119 -0
  88. package/src/cli/commands/workspace.ts +200 -0
  89. package/src/cli/index.ts +53 -0
  90. package/src/cli/register-commands.ts +659 -0
  91. package/src/cli/register-group-commands.ts +88 -0
  92. package/src/cli/register-reviewer-commands.ts +97 -0
  93. package/src/prompts/default-review.md +86 -0
  94. package/src/prompts/system-inline-review.md +135 -0
  95. package/src/prompts/system-overall-review.md +206 -0
  96. package/src/schemas/config.test.ts +245 -0
  97. package/src/schemas/config.ts +84 -0
  98. package/src/schemas/gerrit.ts +681 -0
  99. package/src/services/commit-hook.ts +314 -0
  100. package/src/services/config.test.ts +150 -0
  101. package/src/services/config.ts +250 -0
  102. package/src/services/git-worktree.ts +342 -0
  103. package/src/services/review-strategy.ts +292 -0
  104. package/src/test-utils/mock-generator.ts +138 -0
  105. package/src/utils/change-id.test.ts +98 -0
  106. package/src/utils/change-id.ts +63 -0
  107. package/src/utils/comment-formatters.ts +153 -0
  108. package/src/utils/diff-context.ts +103 -0
  109. package/src/utils/diff-formatters.ts +141 -0
  110. package/src/utils/formatters.ts +85 -0
  111. package/src/utils/git-commit.test.ts +277 -0
  112. package/src/utils/git-commit.ts +122 -0
  113. package/src/utils/index.ts +55 -0
  114. package/src/utils/message-filters.ts +26 -0
  115. package/src/utils/review-formatters.ts +89 -0
  116. package/src/utils/review-prompt-builder.ts +110 -0
  117. package/src/utils/shell-safety.ts +117 -0
  118. package/src/utils/status-indicators.ts +100 -0
  119. package/src/utils/url-parser.test.ts +271 -0
  120. package/src/utils/url-parser.ts +118 -0
  121. package/tests/abandon.test.ts +230 -0
  122. package/tests/add-reviewer.test.ts +579 -0
  123. package/tests/build-status-watch.test.ts +344 -0
  124. package/tests/build-status.test.ts +789 -0
  125. package/tests/change-id-formats.test.ts +268 -0
  126. package/tests/checkout/integration.test.ts +653 -0
  127. package/tests/checkout/parse-input.test.ts +55 -0
  128. package/tests/checkout/validation.test.ts +178 -0
  129. package/tests/comment-batch-advanced.test.ts +431 -0
  130. package/tests/comment-gerrit-api-compliance.test.ts +414 -0
  131. package/tests/comment.test.ts +708 -0
  132. package/tests/comments.test.ts +323 -0
  133. package/tests/config-service-simple.test.ts +100 -0
  134. package/tests/diff.test.ts +419 -0
  135. package/tests/extract-url.test.ts +517 -0
  136. package/tests/groups-members.test.ts +256 -0
  137. package/tests/groups-show.test.ts +323 -0
  138. package/tests/groups.test.ts +334 -0
  139. package/tests/helpers/build-status-test-setup.ts +83 -0
  140. package/tests/helpers/config-mock.ts +27 -0
  141. package/tests/incoming.test.ts +357 -0
  142. package/tests/init.test.ts +70 -0
  143. package/tests/integration/commit-hook.test.ts +246 -0
  144. package/tests/interactive-incoming.test.ts +173 -0
  145. package/tests/mine.test.ts +285 -0
  146. package/tests/mocks/msw-handlers.ts +80 -0
  147. package/tests/open.test.ts +233 -0
  148. package/tests/projects.test.ts +259 -0
  149. package/tests/rebase.test.ts +271 -0
  150. package/tests/remove-reviewer.test.ts +357 -0
  151. package/tests/restore.test.ts +237 -0
  152. package/tests/review.test.ts +135 -0
  153. package/tests/search.test.ts +712 -0
  154. package/tests/setup.test.ts +63 -0
  155. package/tests/show-auto-detect.test.ts +324 -0
  156. package/tests/show.test.ts +813 -0
  157. package/tests/status.test.ts +145 -0
  158. package/tests/submit.test.ts +316 -0
  159. package/tests/unit/commands/push.test.ts +194 -0
  160. package/tests/unit/git-branch-detection.test.ts +82 -0
  161. package/tests/unit/git-worktree.test.ts +55 -0
  162. package/tests/unit/patterns/push-patterns.test.ts +148 -0
  163. package/tests/unit/schemas/gerrit.test.ts +85 -0
  164. package/tests/unit/services/commit-hook.test.ts +132 -0
  165. package/tests/unit/services/review-strategy.test.ts +349 -0
  166. package/tests/unit/test-utils/mock-generator.test.ts +154 -0
  167. package/tests/unit/utils/comment-formatters.test.ts +415 -0
  168. package/tests/unit/utils/diff-context.test.ts +171 -0
  169. package/tests/unit/utils/diff-formatters.test.ts +165 -0
  170. package/tests/unit/utils/formatters.test.ts +411 -0
  171. package/tests/unit/utils/message-filters.test.ts +227 -0
  172. package/tests/unit/utils/shell-safety.test.ts +230 -0
  173. package/tests/unit/utils/status-indicators.test.ts +137 -0
  174. package/tests/vote.test.ts +317 -0
  175. package/tests/workspace.test.ts +295 -0
  176. package/tsconfig.json +36 -5
  177. package/src/commands/branch.ts +0 -196
  178. package/src/ger.ts +0 -22
  179. package/src/types.d.ts +0 -35
  180. package/src/utils.ts +0 -130
package/README.md CHANGED
@@ -1,28 +1,843 @@
1
- ## Install
1
+ # ger
2
2
 
3
+ Gerrit CLI built with Bun.
4
+
5
+ ## Features
6
+
7
+ - **LLM-Friendly**: XML output for AI/automation pipelines
8
+ - **Interactive UI**: Terminal UI for change selection and navigation
9
+ - **Effect-based**: Robust error handling and functional architecture
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ # Install Bun runtime
15
+ curl -fsSL https://bun.sh/install | bash
16
+
17
+ # Install ger
18
+ bun install -g @aaronshaf/ger
19
+ ```
20
+
21
+ ## Getting Started
22
+
23
+ ```bash
24
+ ger setup
25
+ ```
26
+
27
+ This will prompt for your Gerrit credentials:
28
+ - Gerrit host URL
29
+ - Username
30
+ - HTTP password (from Gerrit settings)
31
+
32
+ ## Common Commands
33
+
34
+ ### Daily Workflow
35
+
36
+ ```bash
37
+ # Check your connection status
38
+ ger status
39
+
40
+ # View your changes
41
+ ger mine
42
+
43
+ # View incoming reviews
44
+ ger incoming
45
+
46
+ # View a specific change
47
+ ger show 12345
48
+
49
+ # Checkout a change for local testing
50
+ ger checkout 12345
51
+
52
+ # Add a comment
53
+ ger comment 12345 -m "LGTM"
54
+
55
+ # Vote on a change
56
+ ger vote 12345 --code-review 2 -m "LGTM"
57
+
58
+ # Add reviewers to a change
59
+ ger add-reviewer user@example.com -c 12345
60
+
61
+ # Get diff for review
62
+ ger diff 12345
63
+
64
+ # Push your changes for review
65
+ ger push
66
+ ger push -r alice@example.com -t my-feature --wip
67
+
68
+ # Search for changes using Gerrit query syntax
69
+ ger search "owner:self status:open"
70
+ ger search "project:my-project" -n 10
71
+
72
+ # Extract URLs from messages (e.g., Jenkins build links)
73
+ ger extract-url "build-summary-report" | tail -1
74
+
75
+ # Check CI build status (parses build messages)
76
+ ger build-status 12345 # Returns: pending, running, success, failure, or not_found
77
+ ger build-status # Auto-detects from HEAD commit
78
+
79
+ # Watch build status until completion (like gh run watch)
80
+ ger build-status 12345 --watch
81
+ ger build-status --watch --exit-status && deploy.sh
82
+
83
+ # Rebase, submit, restore changes
84
+ ger rebase 12345
85
+ ger submit 12345
86
+ ger restore 12345
87
+
88
+ # AI-powered code review (requires claude, llm, or opencode CLI)
89
+ ger review 12345
90
+ ger review 12345 --dry-run # Preview without posting
91
+ ```
92
+
93
+ ## Commands
94
+
95
+ ### Connection Status
96
+ ```bash
97
+ ger status
98
+ ger status --pretty
99
+ ```
100
+
101
+ ### Show Change Details
102
+ ```bash
103
+ # Complete change info with metadata, diff, inline comments, and review activity
104
+ ger show 12345
105
+ ger show 12345 --pretty
106
+ ```
107
+
108
+ ### List Changes
109
+ ```bash
110
+ # Your changes
111
+ ger mine
112
+ ger mine --pretty
113
+
114
+ # Incoming reviews
115
+ ger incoming
116
+ ger incoming --pretty
117
+
118
+ # Workspace changes (local branch tracking)
119
+ ger workspace
120
+ ger workspace --pretty
121
+ ```
122
+
123
+ ### Search Changes
124
+
125
+ Search for changes across your Gerrit instance using native query syntax:
126
+
127
+ ```bash
128
+ # Search for all open changes (default)
129
+ ger search
130
+
131
+ # Search for your open changes
132
+ ger search "owner:self status:open"
133
+
134
+ # Search for changes by a specific user
135
+ ger search "owner:john@example.com"
136
+
137
+ # Search by project
138
+ ger search "project:my-project status:open"
139
+
140
+ # Search with date filters
141
+ ger search "owner:self after:2025-01-01"
142
+ ger search "status:merged age:7d"
143
+
144
+ # Combine filters
145
+ ger search "owner:self status:merged before:2025-06-01"
146
+
147
+ # Limit results (default: 25)
148
+ ger search "project:my-project" -n 10
149
+
150
+ # XML output for automation
151
+ ger search "owner:self" --xml
152
+ ```
153
+
154
+ #### Common query operators:
155
+ | Operator | Description |
156
+ |----------|-------------|
157
+ | `owner:USER` | Changes owned by USER (use 'self' for yourself) |
158
+ | `status:STATE` | open, merged, abandoned, closed |
159
+ | `project:NAME` | Changes in a specific project |
160
+ | `branch:NAME` | Changes targeting a branch |
161
+ | `age:TIME` | Time since last update (e.g., 1d, 2w, 1mon) |
162
+ | `before:DATE` | Changes modified before date (YYYY-MM-DD) |
163
+ | `after:DATE` | Changes modified after date (YYYY-MM-DD) |
164
+ | `is:wip` | Work-in-progress changes |
165
+ | `is:submittable` | Changes ready to submit |
166
+ | `reviewer:USER` | Changes where USER is a reviewer |
167
+ | `label:NAME=VALUE` | Filter by label (e.g., label:Code-Review+2) |
168
+
169
+ See the [full query syntax documentation](https://gerrit-review.googlesource.com/Documentation/user-search.html).
170
+
171
+ ### Comments
172
+
173
+ #### Overall Comments
174
+ ```bash
175
+ # Using -m flag
176
+ ger comment 12345 -m "LGTM"
177
+
178
+ # Piping plain text (becomes overall comment message)
179
+ echo "Review text" | ger comment 12345
180
+ cat review.txt | ger comment 12345
181
+ ```
182
+
183
+ #### Line-Specific Comments
184
+ ```bash
185
+ # Single line comment (line numbers refer to post-merge view)
186
+ ger comment 12345 --file src/main.ts --line 42 -m "Consider error handling"
187
+
188
+ # Mark as unresolved
189
+ ger comment 12345 --file src/main.ts --line 42 -m "Fix this" --unresolved
190
+ ```
191
+
192
+ #### Batch Line Comments (JSON Array)
193
+
194
+ The batch comment feature accepts a JSON array of comment objects. Each comment can target specific lines, ranges, or sides of the diff.
195
+
196
+ ##### Basic Structure
197
+ ```javascript
198
+ [
199
+ {
200
+ "file": "path/to/file.js", // Required: File path
201
+ "line": 42, // Optional: Line number (omit when using range)
202
+ "message": "Your comment", // Required: Comment text
203
+ "side": "REVISION", // Optional: "PARENT" or "REVISION" (default: REVISION)
204
+ "range": { // Optional: Comment on multiple lines or characters
205
+ "start_line": 10,
206
+ "end_line": 20,
207
+ "start_character": 0, // Optional: Character position (0-indexed)
208
+ "end_character": 80
209
+ },
210
+ "unresolved": true // Optional: Mark as unresolved (default: false)
211
+ }
212
+ ]
213
+ ```
214
+
215
+ ##### Examples
216
+
217
+ ```bash
218
+ # Basic batch comments
219
+ echo '[
220
+ {"file": "src/main.ts", "line": 10, "message": "Add type annotation"},
221
+ {"file": "src/utils.ts", "line": 25, "message": "Extract to constant"},
222
+ {"file": "src/api.ts", "line": 100, "message": "Handle error", "unresolved": true}
223
+ ]' | ger comment 12345 --batch
224
+
225
+ # Comment on different sides of the diff
226
+ # PARENT: The original code before changes
227
+ # REVISION: The new code after changes
228
+ echo '[
229
+ {"file": "src/Calculator.java", "line": 5, "side": "PARENT", "message": "Why was this removed?"},
230
+ {"file": "src/Calculator.java", "line": 5, "side": "REVISION", "message": "Good improvement"}
231
+ ]' | ger comment 12345 --batch
232
+
233
+ # Range comments for blocks of code
234
+ echo '[
235
+ {
236
+ "file": "src/Service.java",
237
+ "range": {"start_line": 50, "end_line": 55},
238
+ "message": "This entire method needs refactoring"
239
+ },
240
+ {
241
+ "file": "src/Service.java",
242
+ "range": {"start_line": 10, "start_character": 8, "end_line": 10, "end_character": 25},
243
+ "message": "This variable name is confusing"
244
+ }
245
+ ]' | ger comment 12345 --batch
246
+
247
+ # Combined features: range + side + unresolved
248
+ echo '[
249
+ {
250
+ "file": "src/UserService.java",
251
+ "range": {"start_line": 20, "end_line": 35},
252
+ "side": "PARENT",
253
+ "message": "Why was this error handling removed?",
254
+ "unresolved": true
255
+ },
256
+ {
257
+ "file": "src/UserService.java",
258
+ "range": {"start_line": 20, "end_line": 35},
259
+ "side": "REVISION",
260
+ "message": "New error handling looks good, but consider extracting to a method"
261
+ }
262
+ ]' | ger comment 12345 --batch
263
+
264
+ # Load comments from a file
265
+ cat comments.json | ger comment 12345 --batch
266
+ ```
267
+
268
+ #### View Comments
3
269
  ```bash
4
- npm i -g @aaronshaf/ger
270
+ # View all comments with diff context
271
+ ger comments 12345
272
+ ger comments 12345 --pretty
5
273
  ```
6
274
 
7
- ## Assumption: gerrit in known_hosts
275
+ ### Extract URLs
276
+
277
+ Extract URLs from change messages and comments for automation and scripting:
278
+
279
+ ```bash
280
+ # Extract URLs from current HEAD commit's change (auto-detect)
281
+ ger extract-url "build-summary-report"
282
+
283
+ # Get the latest build URL (using tail)
284
+ ger extract-url "build-summary-report" | tail -1
285
+
286
+ # Get the first/oldest build URL (using head)
287
+ ger extract-url "jenkins" | head -1
288
+
289
+ # For a specific change (using change number)
290
+ ger extract-url "build-summary" 12345
291
+
292
+ # For a specific change (using Change-ID)
293
+ ger extract-url "build-summary" If5a3ae8cb5a107e187447802358417f311d0c4b1
8
294
 
295
+ # Chain with other tools for specific change
296
+ ger extract-url "build-summary-report" 12345 | tail -1 | jk failures --smart --xml
297
+
298
+ # Use regex for precise matching
299
+ ger extract-url "job/MyProject/job/main/\d+/" --regex
300
+
301
+ # Search both messages and inline comments
302
+ ger extract-url "github.com" --include-comments
303
+
304
+ # JSON output for scripting
305
+ ger extract-url "jenkins" --json | jq -r '.urls[-1]'
306
+
307
+ # XML output
308
+ ger extract-url "jenkins" --xml
9
309
  ```
10
- # ~/.ssh/known_hosts
11
- Host gerrit
12
- HostName gerrit.[your domain].com
13
- User [your username]
14
- Port 29418
310
+
311
+ #### How it works:
312
+ - **Change detection**: Auto-detects Change-ID from HEAD commit if not specified, or accepts explicit change number/Change-ID
313
+ - **Pattern matching**: Substring match by default, regex with `--regex`
314
+ - **Sources**: Searches messages by default, add `--include-comments` to include inline comments
315
+ - **Ordering**: URLs are output in chronological order (oldest first)
316
+ - **Composable**: Pipe to `tail -1` for latest, `head -1` for oldest
317
+
318
+ #### Common use cases:
319
+ ```bash
320
+ # Get latest Jenkins build URL for a change
321
+ ger extract-url "jenkins.inst-ci.net" | tail -1
322
+
323
+ # Find all GitHub PR references
324
+ ger extract-url "github.com" --include-comments
325
+
326
+ # Extract specific build job URLs with regex
327
+ ger extract-url "job/[^/]+/job/[^/]+/\d+/$" --regex
15
328
  ```
16
329
 
17
- ## Usage
330
+ ### Build Status
331
+
332
+ Check the CI build status of a change by parsing Gerrit messages for build events and verification results:
333
+
334
+ #### Single Check (Snapshot)
335
+ ```bash
336
+ # Check build status for a specific change
337
+ ger build-status 12345
338
+ # Output: {"state":"success"}
339
+
340
+ # Auto-detect change from HEAD commit
341
+ ger build-status
342
+
343
+ # Use in scripts with jq
344
+ ger build-status | jq -r '.state'
345
+ ```
346
+
347
+ #### Watch Mode (Poll Until Completion)
348
+ Like `gh run watch`, you can poll the build status until it reaches a terminal state:
18
349
 
19
350
  ```bash
20
- # list branches with gerrit info
21
- ger branch
351
+ # Watch until completion (outputs JSON on each poll)
352
+ ger build-status 12345 --watch
353
+ # Output:
354
+ # {"state":"pending"}
355
+ # {"state":"running"}
356
+ # {"state":"running"}
357
+ # {"state":"success"}
358
+
359
+ # Auto-detect from HEAD commit
360
+ ger build-status --watch
361
+
362
+ # Custom polling interval (check every 5 seconds, default: 10)
363
+ ger build-status --watch --interval 5
364
+
365
+ # Custom timeout (60 minutes, default: 30 minutes)
366
+ ger build-status --watch --timeout 3600
367
+
368
+ # Exit with code 1 on build failure (for CI/CD pipelines)
369
+ ger build-status --watch --exit-status && deploy.sh
370
+
371
+ # Trigger notification when done (like gh run watch pattern)
372
+ ger build-status --watch && notify-send 'Build is done!'
373
+
374
+ # Extract final state in scripts
375
+ ger build-status --watch | tail -1 | jq -r '.state'
376
+ ```
377
+
378
+ #### Output format (JSON):
379
+ ```json
380
+ {"state": "success"}
381
+ ```
382
+
383
+ #### Build states:
384
+ - **`pending`**: No "Build Started" message found yet
385
+ - **`running`**: "Build Started" found, but no verification result yet
386
+ - **`success`**: Verified +1 after most recent "Build Started"
387
+ - **`failure`**: Verified -1 after most recent "Build Started"
388
+ - **`not_found`**: Change does not exist
389
+
390
+ #### Exit codes:
391
+ - **`0`**: Default for all states (like `gh run watch`)
392
+ - **`1`**: Only when `--exit-status` flag is used AND build fails
393
+ - **`2`**: Timeout reached in watch mode
394
+ - **`3`**: API/network errors
395
+
396
+ #### How it works:
397
+ 1. Fetches all messages for the change
398
+ 2. Finds the most recent "Build Started" message
399
+ 3. Checks for "Verified +1" or "Verified -1" messages after the build started
400
+ 4. Returns the appropriate state
401
+ 5. In watch mode: polls every N seconds until terminal state or timeout
402
+
403
+ #### Use cases:
404
+ - **CI/CD integration**: Wait for builds before proceeding with deployment
405
+ - **Automation**: Trigger actions based on build results
406
+ - **Scripting**: Check build status in shell scripts
407
+ - **Monitoring**: Poll build status for long-running builds with watch mode
408
+
409
+ ### Diff
410
+ ```bash
411
+ # Full diff
412
+ ger diff 12345
413
+ ger diff 12345 --pretty
414
+
415
+ # List changed files
416
+ ger diff 12345 --files-only
417
+
418
+ # Specific file
419
+ ger diff 12345 --file src/main.ts
420
+ ```
421
+
422
+ ### Change Management
423
+
424
+ #### Checkout Changes
425
+ ```bash
426
+ # Checkout latest patchset
427
+ ger checkout 12345
428
+
429
+ # Checkout specific patchset
430
+ ger checkout 12345/3
431
+
432
+ # Checkout by Change-ID
433
+ ger checkout If5a3ae8cb5a107e187447802358417f311d0c4b1
434
+
435
+ # Checkout from URL
436
+ ger checkout https://gerrit.example.com/c/my-project/+/392385
437
+
438
+ # Detached HEAD mode (for quick review)
439
+ ger checkout 12345 --detach
440
+
441
+ # Use specific remote
442
+ ger checkout 12345 --remote upstream
443
+ ```
444
+
445
+ **How it works:**
446
+ - Creates/updates branch named `review/<change-number>`
447
+ - Sets upstream tracking to target branch
448
+ - Updates existing review branch if it exists
449
+ - Auto-detects Gerrit remote matching your configured host
450
+
451
+ #### Push Changes to Gerrit
452
+ ```bash
453
+ # Basic push to auto-detected target branch
454
+ ger push
455
+
456
+ # Push to specific branch
457
+ ger push -b master
458
+ ger push --branch feature/foo
459
+
460
+ # With topic
461
+ ger push -t my-feature
462
+
463
+ # With reviewers (can be repeated)
464
+ ger push -r alice@example.com -r bob@example.com
465
+
466
+ # With CC
467
+ ger push --cc manager@example.com
468
+
469
+ # Work in progress
470
+ ger push --wip
471
+
472
+ # Mark ready for review
473
+ ger push --ready
474
+
475
+ # Add hashtag
476
+ ger push --hashtag bugfix
477
+
478
+ # Combine options
479
+ ger push -b master -t refactor-auth -r alice@example.com --wip
480
+
481
+ # Dry run (show what would be pushed)
482
+ ger push --dry-run
483
+ ```
484
+
485
+ **Features:**
486
+ - Auto-installs commit-msg hook if missing
487
+ - Auto-detects target branch from tracking branch or defaults to main/master
488
+ - Supports all standard Gerrit push options
489
+ - Validates reviewer email addresses
490
+ - Returns change URL on successful push
491
+
492
+ #### Vote on Changes
493
+ ```bash
494
+ # Cast Code-Review vote
495
+ ger vote 12345 --code-review 2
496
+
497
+ # Cast Verified vote
498
+ ger vote 12345 --verified 1
499
+
500
+ # Combine votes with message
501
+ ger vote 12345 --code-review 2 --verified 1 -m "LGTM"
502
+
503
+ # Custom labels
504
+ ger vote 12345 --label "API-Review" 1
505
+
506
+ # XML output for automation
507
+ ger vote 12345 --code-review 1 --xml
508
+ ```
509
+
510
+ **Common votes:**
511
+ - Code-Review: -2, -1, 0, +1, +2
512
+ - Verified: -1, 0, +1
513
+ - Custom labels vary by project configuration
514
+
515
+ #### Rebase Changes
516
+ ```bash
517
+ # Rebase onto target branch HEAD
518
+ ger rebase 12345
519
+
520
+ # Rebase onto specific base
521
+ ger rebase 12345 --base refs/heads/main
522
+
523
+ # XML output
524
+ ger rebase 12345 --xml
525
+ ```
526
+
527
+ #### Submit Changes
528
+ ```bash
529
+ # Submit change for merging
530
+ ger submit 12345
531
+
532
+ # XML output
533
+ ger submit 12345 --xml
534
+ ```
535
+
536
+ **Pre-submission checks:**
537
+ - Verifies change status is NEW
538
+ - Checks for required approvals (Code-Review+2, Verified+1)
539
+ - Ensures change is not work-in-progress
540
+ - Validates all submit requirements are met
541
+
542
+ #### Restore Abandoned Changes
543
+ ```bash
544
+ # Restore an abandoned change
545
+ ger restore 12345
546
+
547
+ # Restore with message
548
+ ger restore 12345 -m "Reopening after discussion"
549
+
550
+ # XML output
551
+ ger restore 12345 --xml
552
+ ```
553
+
554
+ #### Abandon Changes
555
+ ```bash
556
+ # Abandon interactively (prompts for selection)
557
+ ger abandon
558
+
559
+ # Abandon specific change
560
+ ger abandon 12345
561
+
562
+ # Abandon with reason
563
+ ger abandon 12345 -m "Duplicate of #12346"
564
+ ```
565
+
566
+ #### Open in Browser
567
+ ```bash
568
+ # Open change in browser
569
+ ger open 12345
570
+ ```
571
+
572
+ ### Projects
573
+
574
+ List and filter Gerrit projects:
575
+
576
+ ```bash
577
+ # List all projects
578
+ ger projects
579
+
580
+ # Filter by pattern (regex)
581
+ ger projects --pattern "^canvas-.*"
582
+
583
+ # XML output for automation
584
+ ger projects --xml
585
+ ```
586
+
587
+ **Output:**
588
+ - Plain text: One project name per line (default)
589
+ - XML: Structured output with project details (id, name, parent, state)
590
+
591
+ ### Add Reviewers
592
+
593
+ Add reviewers, groups, or CCs to a change:
594
+
595
+ ```bash
596
+ # Add a single reviewer
597
+ ger add-reviewer user@example.com -c 12345
598
+
599
+ # Add multiple reviewers
600
+ ger add-reviewer user1@example.com user2@example.com -c 12345
601
+
602
+ # Add a group as reviewer
603
+ ger add-reviewer --group project-reviewers -c 12345
604
+
605
+ # Add a group as CC
606
+ ger add-reviewer --group administrators --cc -c 12345
607
+
608
+ # Add as CC instead of reviewer
609
+ ger add-reviewer --cc user@example.com -c 12345
610
+
611
+ # Suppress email notifications
612
+ ger add-reviewer --notify none user@example.com -c 12345
613
+
614
+ # XML output for automation
615
+ ger add-reviewer user@example.com -c 12345 --xml
616
+ ```
617
+
618
+ #### Options:
619
+ - `-c, --change <id>` - Change ID (required)
620
+ - `--group` - Add as group instead of individual reviewer
621
+ - `--cc` - Add as CC instead of reviewer
622
+ - `--notify <level>` - Notification level: `none`, `owner`, `owner_reviewers`, `all` (default: `all`)
623
+ - `--xml` - XML output for LLM/automation consumption
624
+
625
+ #### Notes:
626
+ - Both email addresses and usernames are accepted for individual reviewers
627
+ - Group names/IDs can be used with the `--group` flag
628
+ - Multiple reviewers or groups can be added in a single command
629
+ - Use `--cc` for carbon copy (notified but not required to review)
630
+
631
+ ### Groups
632
+
633
+ List, view, and query Gerrit groups:
634
+
635
+ ```bash
636
+ # List all groups
637
+ ger groups
638
+
639
+ # Filter by pattern (regex)
640
+ ger groups --pattern "^project-.*"
641
+
642
+ # Show only groups you own
643
+ ger groups --owned
644
+
645
+ # Show groups for a specific project
646
+ ger groups --project my-project
647
+
648
+ # Limit results
649
+ ger groups --limit 50
650
+
651
+ # Show detailed group information
652
+ ger groups-show administrators
653
+
654
+ # Show group by numeric ID or UUID
655
+ ger groups-show 1
656
+ ger groups-show uuid-123456
657
+
658
+ # List all members of a group
659
+ ger groups-members project-reviewers
660
+
661
+ # XML output for automation
662
+ ger groups --xml
663
+ ger groups-show administrators --xml
664
+ ger groups-members project-reviewers --xml
665
+ ```
666
+
667
+ #### Commands:
668
+ - `ger groups` - List and search groups
669
+ - `--pattern <regex>` - Filter groups by name pattern
670
+ - `--owned` - Show only groups you own
671
+ - `--project <name>` - Show groups for a specific project
672
+ - `--user <account>` - Show groups a user belongs to
673
+ - `--limit <n>` - Limit results (default: 25)
674
+ - `--xml` - XML output
675
+
676
+ - `ger groups-show <group-id>` - Show detailed group information
677
+ - Accepts group name, numeric ID, or UUID
678
+ - Shows members, subgroups, owner, and metadata
679
+ - `--xml` - XML output
680
+
681
+ - `ger groups-members <group-id>` - List all members of a group
682
+ - Shows member names, emails, usernames, and account IDs
683
+ - `--xml` - XML output
684
+
685
+ #### Notes:
686
+ - All group commands provide read-only access
687
+ - Group IDs can be names, numeric IDs, or UUIDs
688
+ - Use groups with `ger add-reviewer --group` to add entire teams as reviewers
689
+
690
+ ### AI-Powered Review
691
+
692
+ The `ger review` command provides automated code review using AI tools (claude, llm, or opencode CLI).
693
+
694
+ ```bash
695
+ # Full AI review with inline and overall comments
696
+ ger review 12345
697
+
698
+ # Preview what would be posted without actually posting
699
+ ger review 12345 --dry-run
700
+
701
+ # Show debug output including AI responses
702
+ ger review 12345 --debug
703
+ ```
704
+
705
+ The review command performs a two-stage review process:
706
+ 1. **Inline comments**: Specific code issues with line-by-line feedback
707
+ 2. **Overall review**: High-level assessment and recommendations
708
+
709
+ Requirements:
710
+ - One of these AI tools must be installed: `claude`, `llm`, or `opencode`
711
+ - Gerrit credentials must be configured (`ger setup`)
712
+
713
+ ## Claude Code Skill
714
+
715
+ This repository includes a Claude Code Agent Skill that teaches Claude how to work effectively with Gerrit using the ger CLI. The skill provides Claude with expertise in Gerrit workflows, command usage, and best practices.
716
+
717
+ ### Installation
718
+
719
+ Install the skill globally using Claude Code's plugin system:
720
+
721
+ ```bash
722
+ # Add ger as a plugin marketplace
723
+ /plugin marketplace add aaronshaf/ger
724
+
725
+ # Install the gerrit-workflow skill
726
+ /plugin install gerrit-workflow@ger
727
+ ```
728
+
729
+ The skill will be available across all your projects, ready to assist with Gerrit operations whenever you need it.
730
+
731
+ ### What's Included
732
+
733
+ The skill provides Claude with knowledge about:
734
+ - Common Gerrit workflows (reviewing changes, posting comments)
735
+ - All ger CLI commands and their options
736
+ - Integration with Jenkins builds and AI tools
737
+ - Best practices for code review
738
+ - Real-world usage examples and scripting patterns
739
+
740
+ ### Using the Skill
741
+
742
+ Once installed, simply ask Claude to help with Gerrit tasks:
743
+
744
+ ```
745
+ "Review the incoming changes"
746
+ "Show me the diff for change 12345"
747
+ "Post a comment on this change"
748
+ "Help me set up an AI review workflow"
749
+ ```
750
+
751
+ Claude will automatically use the skill and guide you through Gerrit operations using ger commands.
752
+
753
+ ### Skill Contents
754
+
755
+ ```
756
+ skills/gerrit-workflow/
757
+ ├── SKILL.md # Main skill instructions
758
+ ├── reference.md # Complete command reference
759
+ └── examples.md # Real-world usage examples
760
+ ```
761
+
762
+ ## LLM Integration
763
+
764
+ ```bash
765
+ # Review with AI
766
+ ger diff 12345 | llm "Review this code"
767
+
768
+ # AI-generated comment
769
+ llm "Review change 12345" | ger comment 12345
770
+
771
+ # Complete change analysis
772
+ ger show 12345 | llm "Summarize this change and its review status"
773
+
774
+ # Automated approvals
775
+ echo "LGTM" | ger comment 12345
776
+ ```
777
+
778
+ ## Output Formats
779
+
780
+ ### XML (Default)
781
+ ```xml
782
+ <?xml version="1.0" encoding="UTF-8"?>
783
+ <comment_result>
784
+ <status>success</status>
785
+ <change_id>12345</change_id>
786
+ <message><![CDATA[LGTM]]></message>
787
+ </comment_result>
788
+ ```
789
+
790
+ ### Pretty (--pretty flag)
791
+ ```
792
+ Comment posted successfully
793
+ Change: Fix authentication bug (NEW)
794
+ Message: LGTM
795
+ ```
796
+
797
+ ## Upgrading
798
+
799
+ To upgrade gi to the latest version:
800
+
801
+ ```bash
802
+ bun update -g @aaronshaf/ger
803
+ ```
804
+
805
+ After upgrading, you may want to review new configuration options:
806
+
807
+ ```bash
808
+ ger setup # Review and update your configuration
809
+ ```
810
+
811
+ ## Development
812
+
813
+ For local development:
814
+
815
+ ```bash
816
+ git clone https://github.com/aaronshaf/ger
817
+ cd ger
818
+ bun install
819
+
820
+ # Run locally
821
+ bun run dev
822
+
823
+ # Run tests
824
+ bun test
825
+ bun run test:coverage
826
+
827
+ # Type checking
828
+ bun run typecheck
829
+
830
+ # Linting
831
+ bun run lint
832
+ ```
833
+
834
+ ### Stack
835
+ - **Bun** - Runtime and package manager
836
+ - **Effect** - Type-safe error handling and functional architecture
837
+ - **TypeScript** - With isolatedDeclarations
838
+ - **Ink** - Terminal UI components
839
+ - **Commander** - CLI argument parsing
22
840
 
23
- # list branches with expanded gerrit info
24
- ger branch -v
841
+ ## License
25
842
 
26
- # prompt to delete branches of submitted or abandoned changes
27
- ger branch -d
28
- ```
843
+ MIT