git 4.3.2 → 5.0.0.beta.2

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 (297) hide show
  1. checksums.yaml +4 -4
  2. data/.github/copilot-instructions.md +73 -2705
  3. data/.github/prompts/iteratively-address-copilot-reviews.prompt.md +188 -0
  4. data/.github/pull_request_template.md +3 -1
  5. data/.github/skills/breaking-change-analysis/SKILL.md +102 -0
  6. data/.github/skills/ci-cd-troubleshooting/SKILL.md +264 -0
  7. data/.github/skills/command-implementation/REFERENCE.md +993 -0
  8. data/.github/skills/command-implementation/SKILL.md +229 -0
  9. data/.github/skills/command-test-conventions/SKILL.md +660 -0
  10. data/.github/skills/command-yard-documentation/SKILL.md +426 -0
  11. data/.github/skills/dependency-management/SKILL.md +72 -0
  12. data/.github/skills/development-workflow/SKILL.md +506 -0
  13. data/.github/skills/extract-command-from-lib/SKILL.md +487 -0
  14. data/.github/skills/extract-facade-from-base-lib/KEYWORD_ARG_REMEDIATION.md +22 -0
  15. data/.github/skills/extract-facade-from-base-lib/SKILL.md +600 -0
  16. data/.github/skills/facade-implementation/REFERENCE.md +840 -0
  17. data/.github/skills/facade-implementation/SKILL.md +274 -0
  18. data/.github/skills/facade-test-conventions/SKILL.md +394 -0
  19. data/.github/skills/facade-yard-documentation/SKILL.md +429 -0
  20. data/.github/skills/make-skill-template/SKILL.md +176 -0
  21. data/.github/skills/pr-readiness-review/SKILL.md +185 -0
  22. data/.github/skills/project-context/SKILL.md +313 -0
  23. data/.github/skills/pull-request-review/SKILL.md +168 -0
  24. data/.github/skills/refactor-command-to-commandlineresult/SKILL.md +131 -0
  25. data/.github/skills/release-management/SKILL.md +125 -0
  26. data/.github/skills/review-arguments-dsl/CHECKLIST.md +788 -0
  27. data/.github/skills/review-arguments-dsl/SKILL.md +214 -0
  28. data/.github/skills/review-backward-compatibility/SKILL.md +275 -0
  29. data/.github/skills/review-cross-command-consistency/SKILL.md +139 -0
  30. data/.github/skills/reviewing-skills/SKILL.md +189 -0
  31. data/.github/skills/rspec-unit-testing-standards/SKILL.md +639 -0
  32. data/.github/skills/tdd-refactor-step/SKILL.md +236 -0
  33. data/.github/skills/test-debugging/SKILL.md +160 -0
  34. data/.github/skills/yard-documentation/SKILL.md +793 -0
  35. data/.github/workflows/continuous_integration.yml +3 -2
  36. data/.github/workflows/enforce_conventional_commits.yml +1 -1
  37. data/.github/workflows/experimental_continuous_integration.yml +2 -2
  38. data/.github/workflows/release.yml +3 -4
  39. data/.gitignore +8 -0
  40. data/.husky/pre-commit +13 -0
  41. data/.release-please-manifest.json +1 -1
  42. data/.rspec +3 -0
  43. data/.rubocop.yml +12 -3
  44. data/.rubocop_todo.yml +23 -5
  45. data/.yardopts +1 -0
  46. data/CHANGELOG.md +0 -40
  47. data/CONTRIBUTING.md +694 -53
  48. data/README.md +67 -15
  49. data/Rakefile +61 -9
  50. data/UPGRADING.md +141 -0
  51. data/commitlint.test +4 -0
  52. data/git.gemspec +18 -7
  53. data/lib/git/args_builder.rb +0 -8
  54. data/lib/git/branch.rb +369 -43
  55. data/lib/git/branch_delete_failure.rb +31 -0
  56. data/lib/git/branch_delete_result.rb +63 -0
  57. data/lib/git/branch_info.rb +178 -0
  58. data/lib/git/branches.rb +122 -24
  59. data/lib/git/command_line/base.rb +255 -0
  60. data/lib/git/command_line/capturing.rb +251 -0
  61. data/lib/git/command_line/result.rb +96 -0
  62. data/lib/git/command_line/streaming.rb +196 -0
  63. data/lib/git/command_line.rb +43 -322
  64. data/lib/git/command_line_result.rb +4 -88
  65. data/lib/git/commands/add.rb +131 -0
  66. data/lib/git/commands/am/abort.rb +43 -0
  67. data/lib/git/commands/am/apply.rb +252 -0
  68. data/lib/git/commands/am/continue.rb +43 -0
  69. data/lib/git/commands/am/quit.rb +43 -0
  70. data/lib/git/commands/am/retry.rb +47 -0
  71. data/lib/git/commands/am/show_current_patch.rb +64 -0
  72. data/lib/git/commands/am/skip.rb +42 -0
  73. data/lib/git/commands/am.rb +33 -0
  74. data/lib/git/commands/apply.rb +237 -0
  75. data/lib/git/commands/archive/list_formats.rb +46 -0
  76. data/lib/git/commands/archive.rb +140 -0
  77. data/lib/git/commands/arguments.rb +3510 -0
  78. data/lib/git/commands/base.rb +404 -0
  79. data/lib/git/commands/branch/copy.rb +94 -0
  80. data/lib/git/commands/branch/create.rb +173 -0
  81. data/lib/git/commands/branch/delete.rb +80 -0
  82. data/lib/git/commands/branch/list.rb +162 -0
  83. data/lib/git/commands/branch/move.rb +94 -0
  84. data/lib/git/commands/branch/set_upstream.rb +86 -0
  85. data/lib/git/commands/branch/show_current.rb +49 -0
  86. data/lib/git/commands/branch/unset_upstream.rb +57 -0
  87. data/lib/git/commands/branch.rb +34 -0
  88. data/lib/git/commands/cat_file/batch.rb +369 -0
  89. data/lib/git/commands/cat_file/filtered.rb +105 -0
  90. data/lib/git/commands/cat_file/raw.rb +216 -0
  91. data/lib/git/commands/cat_file.rb +49 -0
  92. data/lib/git/commands/checkout/branch.rb +151 -0
  93. data/lib/git/commands/checkout/files.rb +115 -0
  94. data/lib/git/commands/checkout.rb +38 -0
  95. data/lib/git/commands/checkout_index.rb +105 -0
  96. data/lib/git/commands/clean.rb +100 -0
  97. data/lib/git/commands/clone.rb +240 -0
  98. data/lib/git/commands/commit.rb +272 -0
  99. data/lib/git/commands/commit_tree.rb +100 -0
  100. data/lib/git/commands/config_option_syntax/add.rb +83 -0
  101. data/lib/git/commands/config_option_syntax/get.rb +117 -0
  102. data/lib/git/commands/config_option_syntax/get_all.rb +115 -0
  103. data/lib/git/commands/config_option_syntax/get_color.rb +91 -0
  104. data/lib/git/commands/config_option_syntax/get_color_bool.rb +93 -0
  105. data/lib/git/commands/config_option_syntax/get_regexp.rb +115 -0
  106. data/lib/git/commands/config_option_syntax/get_urlmatch.rb +107 -0
  107. data/lib/git/commands/config_option_syntax/list.rb +107 -0
  108. data/lib/git/commands/config_option_syntax/remove_section.rb +74 -0
  109. data/lib/git/commands/config_option_syntax/rename_section.rb +78 -0
  110. data/lib/git/commands/config_option_syntax/replace_all.rb +104 -0
  111. data/lib/git/commands/config_option_syntax/set.rb +114 -0
  112. data/lib/git/commands/config_option_syntax/unset.rb +89 -0
  113. data/lib/git/commands/config_option_syntax/unset_all.rb +89 -0
  114. data/lib/git/commands/config_option_syntax.rb +56 -0
  115. data/lib/git/commands/describe.rb +155 -0
  116. data/lib/git/commands/diff.rb +656 -0
  117. data/lib/git/commands/diff_files.rb +518 -0
  118. data/lib/git/commands/diff_index.rb +496 -0
  119. data/lib/git/commands/fetch.rb +352 -0
  120. data/lib/git/commands/fsck.rb +136 -0
  121. data/lib/git/commands/gc.rb +132 -0
  122. data/lib/git/commands/grep.rb +338 -0
  123. data/lib/git/commands/init.rb +99 -0
  124. data/lib/git/commands/log.rb +632 -0
  125. data/lib/git/commands/ls_files.rb +191 -0
  126. data/lib/git/commands/ls_remote.rb +155 -0
  127. data/lib/git/commands/ls_tree.rb +131 -0
  128. data/lib/git/commands/maintenance/register.rb +75 -0
  129. data/lib/git/commands/maintenance/run.rb +104 -0
  130. data/lib/git/commands/maintenance/start.rb +66 -0
  131. data/lib/git/commands/maintenance/stop.rb +55 -0
  132. data/lib/git/commands/maintenance/unregister.rb +79 -0
  133. data/lib/git/commands/maintenance.rb +31 -0
  134. data/lib/git/commands/merge/abort.rb +44 -0
  135. data/lib/git/commands/merge/continue.rb +44 -0
  136. data/lib/git/commands/merge/quit.rb +46 -0
  137. data/lib/git/commands/merge/start.rb +245 -0
  138. data/lib/git/commands/merge.rb +28 -0
  139. data/lib/git/commands/merge_base.rb +86 -0
  140. data/lib/git/commands/mv.rb +77 -0
  141. data/lib/git/commands/name_rev.rb +114 -0
  142. data/lib/git/commands/pull.rb +377 -0
  143. data/lib/git/commands/push.rb +246 -0
  144. data/lib/git/commands/read_tree.rb +149 -0
  145. data/lib/git/commands/remote/add.rb +91 -0
  146. data/lib/git/commands/remote/get_url.rb +66 -0
  147. data/lib/git/commands/remote/list.rb +54 -0
  148. data/lib/git/commands/remote/prune.rb +61 -0
  149. data/lib/git/commands/remote/remove.rb +52 -0
  150. data/lib/git/commands/remote/rename.rb +69 -0
  151. data/lib/git/commands/remote/set_branches.rb +63 -0
  152. data/lib/git/commands/remote/set_head.rb +82 -0
  153. data/lib/git/commands/remote/set_url.rb +71 -0
  154. data/lib/git/commands/remote/set_url_add.rb +61 -0
  155. data/lib/git/commands/remote/set_url_delete.rb +64 -0
  156. data/lib/git/commands/remote/show.rb +71 -0
  157. data/lib/git/commands/remote/update.rb +72 -0
  158. data/lib/git/commands/remote.rb +42 -0
  159. data/lib/git/commands/repack.rb +277 -0
  160. data/lib/git/commands/reset.rb +147 -0
  161. data/lib/git/commands/rev_parse.rb +297 -0
  162. data/lib/git/commands/revert/abort.rb +45 -0
  163. data/lib/git/commands/revert/continue.rb +57 -0
  164. data/lib/git/commands/revert/quit.rb +47 -0
  165. data/lib/git/commands/revert/skip.rb +44 -0
  166. data/lib/git/commands/revert/start.rb +153 -0
  167. data/lib/git/commands/revert.rb +29 -0
  168. data/lib/git/commands/rm.rb +114 -0
  169. data/lib/git/commands/show.rb +632 -0
  170. data/lib/git/commands/show_ref/exclude_existing.rb +120 -0
  171. data/lib/git/commands/show_ref/exists.rb +78 -0
  172. data/lib/git/commands/show_ref/list.rb +145 -0
  173. data/lib/git/commands/show_ref/verify.rb +120 -0
  174. data/lib/git/commands/show_ref.rb +42 -0
  175. data/lib/git/commands/stash/apply.rb +75 -0
  176. data/lib/git/commands/stash/branch.rb +65 -0
  177. data/lib/git/commands/stash/clear.rb +41 -0
  178. data/lib/git/commands/stash/create.rb +58 -0
  179. data/lib/git/commands/stash/drop.rb +67 -0
  180. data/lib/git/commands/stash/list.rb +39 -0
  181. data/lib/git/commands/stash/pop.rb +78 -0
  182. data/lib/git/commands/stash/push.rb +103 -0
  183. data/lib/git/commands/stash/show.rb +149 -0
  184. data/lib/git/commands/stash/store.rb +63 -0
  185. data/lib/git/commands/stash.rb +38 -0
  186. data/lib/git/commands/status.rb +169 -0
  187. data/lib/git/commands/symbolic_ref/delete.rb +68 -0
  188. data/lib/git/commands/symbolic_ref/read.rb +95 -0
  189. data/lib/git/commands/symbolic_ref/update.rb +76 -0
  190. data/lib/git/commands/symbolic_ref.rb +38 -0
  191. data/lib/git/commands/tag/create.rb +139 -0
  192. data/lib/git/commands/tag/delete.rb +55 -0
  193. data/lib/git/commands/tag/list.rb +143 -0
  194. data/lib/git/commands/tag/verify.rb +71 -0
  195. data/lib/git/commands/tag.rb +26 -0
  196. data/lib/git/commands/update_ref/batch.rb +140 -0
  197. data/lib/git/commands/update_ref/delete.rb +92 -0
  198. data/lib/git/commands/update_ref/update.rb +106 -0
  199. data/lib/git/commands/update_ref.rb +42 -0
  200. data/lib/git/commands/version.rb +57 -0
  201. data/lib/git/commands/worktree/add.rb +140 -0
  202. data/lib/git/commands/worktree/list.rb +64 -0
  203. data/lib/git/commands/worktree/lock.rb +58 -0
  204. data/lib/git/commands/worktree/management_base.rb +51 -0
  205. data/lib/git/commands/worktree/move.rb +66 -0
  206. data/lib/git/commands/worktree/prune.rb +67 -0
  207. data/lib/git/commands/worktree/remove.rb +63 -0
  208. data/lib/git/commands/worktree/repair.rb +76 -0
  209. data/lib/git/commands/worktree/unlock.rb +47 -0
  210. data/lib/git/commands/worktree.rb +43 -0
  211. data/lib/git/commands/write_tree.rb +68 -0
  212. data/lib/git/commands.rb +87 -0
  213. data/lib/git/config.rb +17 -0
  214. data/lib/git/config_entry_info.rb +106 -0
  215. data/lib/git/configuring.rb +665 -0
  216. data/lib/git/deprecation.rb +9 -0
  217. data/lib/git/detached_head_info.rb +54 -0
  218. data/lib/git/diff.rb +293 -7
  219. data/lib/git/diff_file_numstat_info.rb +29 -0
  220. data/lib/git/diff_file_patch_info.rb +134 -0
  221. data/lib/git/diff_file_raw_info.rb +127 -0
  222. data/lib/git/diff_info.rb +169 -0
  223. data/lib/git/diff_path_status.rb +67 -19
  224. data/lib/git/diff_result.rb +32 -0
  225. data/lib/git/diff_stats.rb +51 -14
  226. data/lib/git/dirstat_info.rb +86 -0
  227. data/lib/git/errors.rb +65 -2
  228. data/lib/git/execution_context/global.rb +31 -0
  229. data/lib/git/execution_context/repository.rb +136 -0
  230. data/lib/git/execution_context.rb +501 -0
  231. data/lib/git/file_ref.rb +74 -0
  232. data/lib/git/fsck_object.rb +9 -9
  233. data/lib/git/fsck_result.rb +1 -1
  234. data/lib/git/log.rb +9 -2
  235. data/lib/git/object.rb +90 -27
  236. data/lib/git/parsers/branch.rb +224 -0
  237. data/lib/git/parsers/cat_file.rb +111 -0
  238. data/lib/git/parsers/config_entry.rb +110 -0
  239. data/lib/git/parsers/diff.rb +585 -0
  240. data/lib/git/parsers/fsck.rb +133 -0
  241. data/lib/git/parsers/grep.rb +42 -0
  242. data/lib/git/parsers/ls_remote.rb +79 -0
  243. data/lib/git/parsers/ls_tree.rb +58 -0
  244. data/lib/git/parsers/stash.rb +208 -0
  245. data/lib/git/parsers/tag.rb +257 -0
  246. data/lib/git/remote.rb +120 -9
  247. data/lib/git/repository/branching.rb +743 -0
  248. data/lib/git/repository/committing.rb +187 -0
  249. data/lib/git/repository/configuring.rb +351 -0
  250. data/lib/git/repository/context_helpers.rb +264 -0
  251. data/lib/git/repository/diffing.rb +775 -0
  252. data/lib/git/repository/factories.rb +682 -0
  253. data/lib/git/repository/inspecting.rb +252 -0
  254. data/lib/git/repository/logging.rb +247 -0
  255. data/lib/git/repository/maintenance.rb +65 -0
  256. data/lib/git/repository/merging.rb +357 -0
  257. data/lib/git/repository/object_operations.rb +1199 -0
  258. data/lib/git/repository/path_resolver.rb +207 -0
  259. data/lib/git/repository/remote_operations.rb +898 -0
  260. data/lib/git/repository/shared_private.rb +51 -0
  261. data/lib/git/repository/staging.rb +554 -0
  262. data/lib/git/repository/stashing.rb +143 -0
  263. data/lib/git/repository/status_operations.rb +201 -0
  264. data/lib/git/repository/worktree_operations.rb +159 -0
  265. data/lib/git/repository.rb +203 -1
  266. data/lib/git/stash.rb +78 -4
  267. data/lib/git/stash_info.rb +104 -0
  268. data/lib/git/stashes.rb +125 -13
  269. data/lib/git/status.rb +215 -18
  270. data/lib/git/tag_delete_failure.rb +31 -0
  271. data/lib/git/tag_delete_result.rb +63 -0
  272. data/lib/git/tag_info.rb +105 -0
  273. data/lib/git/version.rb +109 -2
  274. data/lib/git/version_constraint.rb +81 -0
  275. data/lib/git/worktree.rb +108 -6
  276. data/lib/git/worktrees.rb +94 -7
  277. data/lib/git.rb +260 -61
  278. data/redesign/1_architecture_existing.md +54 -18
  279. data/redesign/2_architecture_redesign.md +365 -46
  280. data/redesign/3_architecture_implementation.md +1497 -63
  281. data/redesign/Phase 4 - Step A.md +360 -0
  282. data/redesign/beta_release.md +107 -0
  283. data/redesign/c1c2_audit.md +566 -0
  284. data/redesign/c1c2_bucket6_lib_orphans.md +626 -0
  285. data/redesign/config_design.rb +501 -0
  286. data/tasks/gem_tasks.rake +4 -0
  287. data/tasks/npm_tasks.rake +7 -0
  288. data/tasks/rspec.rake +48 -0
  289. data/tasks/test.rake +13 -1
  290. data/tasks/yard.rake +34 -7
  291. metadata +365 -22
  292. data/lib/git/base.rb +0 -1128
  293. data/lib/git/index.rb +0 -6
  294. data/lib/git/lib.rb +0 -2277
  295. data/lib/git/path.rb +0 -38
  296. data/lib/git/working_directory.rb +0 -6
  297. /data/{release-please-config.json → .release-please-config.json} +0 -0
@@ -0,0 +1,188 @@
1
+ ---
2
+ agent: agent
3
+ model: claude-sonnet-4.6
4
+ description: Address all unresolved Copilot review threads on the active pull request until there are no remaining unresolved review threads
5
+ ---
6
+
7
+ Address unresolved **Copilot** review threads on the active pull request. Ignore threads opened by human reviewers. Ask me for clarification or decisions as needed.
8
+
9
+ If any terminal script command fails, stop immediately. Do not continue the loop, do not resolve additional threads, and do not request a new review. Report: the failed command, exit code, and the most relevant stderr output. **Exception**: the reply POST in Step 3 is intentionally non-fatal — a 404 after a force-push is expected and the resolve step must still run.
10
+
11
+ ## Terminology
12
+
13
+ - **Review** — a top-level review submission by `copilot-pull-request-reviewer`, with a `submittedAt` timestamp and an optional summary body. A single review may contain zero or more Review Threads.
14
+ - **Review Thread** — an inline comment thread attached to a specific code location. Key fields: `id` (GraphQL node ID, e.g. `PRRT_…`), `isResolved` (manually resolved by a maintainer), `isOutdated` (the underlying code changed since the thread was created). Each thread has one or more comments; the first comment is Copilot's suggestion.
15
+ - **Check Run** — a standard CI status object on the HEAD commit. Note: Copilot Reviews do **not** create a Check Run; use the Reviews API to detect completion instead.
16
+
17
+ ## Before the Loop
18
+
19
+ Run in terminal to establish `OWNER`, `REPO`, and `PR_NUMBER` for use throughout:
20
+
21
+ ```bash
22
+ set -euo pipefail
23
+ OWNER=$(gh repo view --json owner --jq '.owner.login')
24
+ REPO=$(gh repo view --json name --jq '.name')
25
+ PR_NUMBER=$(gh pr view --json number --jq '.number')
26
+ : "${OWNER:?failed to resolve OWNER}"
27
+ : "${REPO:?failed to resolve REPO}"
28
+ : "${PR_NUMBER:?failed to resolve PR_NUMBER}"
29
+ ```
30
+
31
+ Fetch unresolved, non-outdated Copilot Review Threads:
32
+
33
+ ```bash
34
+ set -euo pipefail
35
+ : "${OWNER:?missing OWNER}"
36
+ : "${REPO:?missing REPO}"
37
+ : "${PR_NUMBER:?missing PR_NUMBER}"
38
+ threads_json=$(gh api graphql -f query='
39
+ query($owner:String!,$repo:String!,$pr:Int!){
40
+ repository(owner:$owner,name:$repo){
41
+ pullRequest(number:$pr){
42
+ reviewThreads(first:100){nodes{id isResolved isOutdated path
43
+ comments(first:1){nodes{databaseId author{login} createdAt body}}}}}}
44
+ }' -f owner="$OWNER" -f repo="$REPO" -F pr="$PR_NUMBER" \
45
+ --jq '.data.repository.pullRequest.reviewThreads.nodes')
46
+ if [[ $(echo "$threads_json" | jq 'length') -ge 100 ]]; then
47
+ echo "Error: the PR already has 100 threads or more. Aborting."
48
+ exit 1
49
+ fi
50
+ echo "$threads_json" | jq '[.[] |
51
+ select(.isResolved==false) |
52
+ select(.isOutdated==false) |
53
+ select(.comments.nodes[0].author.login=="copilot-pull-request-reviewer")]'
54
+ ```
55
+
56
+ - **Results non-empty** → proceed directly to the iteration loop.
57
+ - **Results empty** → record `REVIEW_REQUESTED_AT` (current UTC, `YYYY-MM-DDTHH:MM:SSZ`, e.g. `2026-06-16T12:00:00Z`), request a new Copilot Review using the `mcp_github_mcp_se_request_copilot_review` tool (owner, repo, pullNumber), then jump to the **Wait for Review** section below.
58
+
59
+ ## Iteration Loop
60
+
61
+ Repeat up to **${input:maxIterations:5}** iterations:
62
+
63
+ ### 1. Address threads
64
+
65
+ Re-fetch unresolved, non-outdated Copilot Review Threads using the same `gh api graphql` query from Before the Loop. Group by file. For each file, read it once and address all its threads in that single pass:
66
+ - Validate each suggestion before accepting it.
67
+ - If a suggestion is invalid or out of scope: reply explaining why, then resolve the thread without changing code.
68
+ - Otherwise: implement the change using TDD where possible; ensure test coverage.
69
+
70
+ Skip any thread where `isOutdated` is true — the code it references has already changed; Copilot will re-evaluate it in the next Review.
71
+
72
+ After all threads are addressed, run `rake`. If it fails, capture `rake 2>&1 | tail -n 50` and fix the failure before continuing.
73
+
74
+ ### 2. Commit and push
75
+
76
+ Amend each change into the most relevant existing commit on the branch based on file name. If a change spans multiple commits or doesn't map clearly to one, ask me which commit to amend into (or whether to create a new commit). Confirm the working tree is clean and `rake` passes, then force push.
77
+
78
+ ### 3. Reply and resolve
79
+
80
+ For each addressed thread object from the unresolved-threads query, in the same `run_in_terminal` script block that performs reply/resolve, export:
81
+
82
+ - `COMMENT_DBID=.comments.nodes[0].databaseId`
83
+ - `THREAD_ID=.id`
84
+ - `EXPLANATION` to your plain-language fix summary for that thread
85
+
86
+ Set the per-thread variables (`COMMENT_DBID`, `THREAD_ID`, `EXPLANATION`) immediately before running the commands below — do not rely on them surviving from a prior terminal invocation.
87
+
88
+ Then post a reply and resolve it:
89
+
90
+ ```bash
91
+ set -euo pipefail
92
+ : "${OWNER:?missing OWNER}"
93
+ : "${REPO:?missing REPO}"
94
+ : "${COMMENT_DBID:?missing COMMENT_DBID}"
95
+ : "${EXPLANATION:?missing EXPLANATION}"
96
+
97
+ # Reply (COMMENT_DBID = databaseId of the thread's first comment)
98
+ # Build JSON via jq to safely handle quotes/newlines/special chars in EXPLANATION.
99
+ # EXPLANATION should contain the full reply text (e.g. "Fixed: ..." or "Not addressing this because...").
100
+ BODY_JSON=$(jq -n --arg body "$EXPLANATION" '{body:$body}')
101
+ # Non-fatal: a force-push can mark threads as outdated, causing the REST reply to return 404.
102
+ # Always continue to the GraphQL resolve step regardless.
103
+ gh api "repos/$OWNER/$REPO/pulls/comments/$COMMENT_DBID/replies" \
104
+ -X POST --input - <<<"$BODY_JSON" \
105
+ || echo "Warning: reply POST failed (thread may be outdated after force-push) — skipping reply, will still resolve"
106
+
107
+ : "${THREAD_ID:?missing THREAD_ID}"
108
+
109
+ # Resolve (THREAD_ID = GraphQL node id, e.g. PRRT_...)
110
+ gh api graphql \
111
+ -f query='mutation($id:ID!){resolveReviewThread(input:{threadId:$id}){thread{isResolved}}}' \
112
+ -f id="$THREAD_ID"
113
+ ```
114
+
115
+ ### 4. Request review
116
+
117
+ **If this was the ${input:maxIterations:5}th iteration**, skip steps 4 and 6 entirely — go directly to step 5 (Report) and then produce the Final Report.
118
+
119
+ Otherwise, capture `REVIEW_REQUESTED_AT` by running `date -u +%Y-%m-%dT%H:%M:%SZ` in the terminal immediately before requesting the review. Then request a new Copilot Review using the `mcp_github_mcp_se_request_copilot_review` tool (owner, repo, pullNumber).
120
+
121
+ ### 5. Report
122
+
123
+ List what was addressed and how each issue was resolved.
124
+
125
+ ### 6. Wait
126
+
127
+ Jump to the **Wait for Review** section below. Return here to begin the next iteration once the new Copilot Review has been submitted.
128
+
129
+ ## Wait for Review
130
+
131
+ **[BLOCKING — do not proceed until complete]** Poll for a new Copilot Review submission using the Reviews API. A Review with `submittedAt >= REVIEW_REQUESTED_AT` is the authoritative completion signal — it fires even when Copilot produces zero Review Threads.
132
+
133
+ Run the following script via `run_in_terminal` (sync mode, timeout 750000 ms). Set the four variables on the first line to their actual values. On success, capture the script's last output line; on failure, follow the global failure-reporting rule (failed command, exit code, relevant stderr):
134
+
135
+ ```bash
136
+ set -euo pipefail
137
+ # Replace with actual values. REVIEW_REQUESTED_AT = output of `date -u +%Y-%m-%dT%H:%M:%SZ` captured just before requesting the review.
138
+ OWNER="ruby-git"; REPO="ruby-git"; PR_NUMBER="1439"; REVIEW_REQUESTED_AT="2026-06-16T12:00:00Z"
139
+ : "${OWNER:?missing OWNER}"
140
+ : "${REPO:?missing REPO}"
141
+ : "${PR_NUMBER:?missing PR_NUMBER}"
142
+ : "${REVIEW_REQUESTED_AT:?missing REVIEW_REQUESTED_AT}"
143
+ START=$(date +%s)
144
+ for i in $(seq 1 60); do
145
+ new_review=$(gh pr view "$PR_NUMBER" --repo "$OWNER/$REPO" --json reviews \
146
+ --jq "[.reviews[] | select(.author.login==\"copilot-pull-request-reviewer\") | select(.submittedAt != null) | select(.submittedAt | fromdateiso8601 >= (\"$REVIEW_REQUESTED_AT\" | fromdateiso8601))] | length") \
147
+ || { rc=$?; echo "Error: gh pr view failed (exit $rc)"; exit $rc; }
148
+ if [[ -n "$new_review" && "$new_review" -gt 0 ]]; then
149
+ raw_nodes=$(gh api graphql -f query='
150
+ query($owner:String!,$repo:String!,$pr:Int!){
151
+ repository(owner:$owner,name:$repo){
152
+ pullRequest(number:$pr){
153
+ reviewThreads(first:100){nodes{isResolved isOutdated comments(first:1){nodes{author{login}}}}}
154
+ }
155
+ }
156
+ }' -f owner="$OWNER" -f repo="$REPO" -F pr="$PR_NUMBER" \
157
+ --jq '.data.repository.pullRequest.reviewThreads.nodes') \
158
+ || { rc=$?; echo "Error: gh api graphql failed (exit $rc)"; exit $rc; }
159
+ if [[ $(echo "$raw_nodes" | jq 'length') -ge 100 ]]; then
160
+ echo "Error: the PR already has 100 threads or more. Aborting."
161
+ exit 1
162
+ fi
163
+ count=$(echo "$raw_nodes" | jq "[.[] |
164
+ select(.isResolved==false) |
165
+ select(.isOutdated==false) |
166
+ select(.comments.nodes[0].author.login==\"copilot-pull-request-reviewer\")] | length")
167
+ echo "done: $count threads" # count of all unresolved non-outdated Copilot Review Threads
168
+ exit 0
169
+ fi
170
+ elapsed=$(( $(date +%s) - START ))
171
+ echo "Waiting for Copilot Review to complete... (${elapsed}s elapsed)"
172
+ sleep 10
173
+ done
174
+ echo "timed out after 60 polls"
175
+ exit 1
176
+ ```
177
+
178
+ **If `timed out after 60 polls`**: stop immediately and ask me whether to re-request the review and retry, or abort.
179
+
180
+ **If `done: 0 threads`**: the loop is complete — exit.
181
+
182
+ **If `done: N threads`** (N > 0): begin the next iteration.
183
+
184
+ ## Final Report
185
+
186
+ - Total iterations completed
187
+ - Total threads addressed
188
+ - Unresolved threads in the final Copilot review (should be 0 if the loop exited cleanly)
@@ -13,5 +13,7 @@ Review our [guidelines for contributing](https://github.com/ruby-git/ruby-git/bl
13
13
  - [ ] I reviewed and applied the project's [AI Policy](../AI_POLICY.md). I understand
14
14
  and verify any AI-assisted changes included in this PR and ensured they meet
15
15
  quality, security, and licensing standards.
16
- - [ ] Tests added/updated as needed and `rake` passes locally.
16
+ - [ ] I ran `bundle exec rake` locally on this branch and it passed (see
17
+ [Local development setup](../CONTRIBUTING.md#local-development-setup)).
18
+ - [ ] Tests added/updated as needed.
17
19
  - [ ] Documentation updated where applicable (README and/or YARD).
@@ -0,0 +1,102 @@
1
+ ---
2
+ name: breaking-change-analysis
3
+ description: "Assesses the impact of API changes before implementation to understand what code would break and plan appropriate migration paths. Use when removing methods, changing interfaces, or planning deprecations."
4
+ ---
5
+
6
+ # Breaking Change Analysis Workflow
7
+
8
+ Assess the impact of API changes before implementation. Use when removing methods,
9
+ changing method signatures, altering return types/values, changing exception types,
10
+ or modifying default behavior.
11
+
12
+ ## Contents
13
+
14
+ - [How to use this skill](#how-to-use-this-skill)
15
+ - [Related skills](#related-skills)
16
+ - [Step 1: Identify the Change Scope](#step-1-identify-the-change-scope)
17
+ - [Step 2: Find All Usages](#step-2-find-all-usages)
18
+ - [Step 3: Assess and Document Impact](#step-3-assess-and-document-impact)
19
+ - [Step 4: Plan Migration Path](#step-4-plan-migration-path)
20
+
21
+ ## How to use this skill
22
+
23
+ Attach this file to your Copilot Chat context, then invoke it with the specific
24
+ API/method change you are considering. Use this workflow before coding to assess
25
+ impact and plan migration.
26
+
27
+ ## Related skills
28
+
29
+ - [Review Backward Compatibility](../review-backward-compatibility/SKILL.md) —
30
+ verify backward compatibility after command migrations
31
+ - [Development Workflow](../development-workflow/SKILL.md) — implement required
32
+ changes using strict TDD
33
+
34
+ ## Step 1: Identify the Change Scope
35
+
36
+ 1. Determine which classes and methods are affected.
37
+ 2. Check API visibility (`@api public` vs `@api private` in YARD docs).
38
+ 3. Check if the change affects `Git::Lib` (facade layer used by most callers).
39
+
40
+ ## Step 2: Find All Usages
41
+
42
+ 1. **Internal usages:**
43
+
44
+ ```bash
45
+ grep -rn "method_name" lib/ tests/ spec/
46
+ ```
47
+
48
+ 2. **External usage (if applicable):**
49
+
50
+ ```bash
51
+ gh search code "Git::Base#method_name language:ruby"
52
+ ```
53
+
54
+ ## Step 3: Assess and Document Impact
55
+
56
+ Produce an impact assessment:
57
+
58
+ ```markdown
59
+ ## Breaking Change Impact Assessment
60
+
61
+ ### Change Description
62
+ [What is being changed]
63
+
64
+ ### Affected API
65
+ - Class: `Git::SomeClass`
66
+ - Method: `#some_method`
67
+ - Current signature: `def some_method(arg, opts = {})`
68
+ - Proposed signature: `def some_method(arg, force: false)`
69
+
70
+ ### Internal Impact
71
+ - Files affected: X
72
+ - Tests to update: Y
73
+
74
+ ### External Impact
75
+ - Severity: [High/Medium/Low]
76
+ - Migration difficulty: [Easy/Medium/Hard]
77
+
78
+ ### Migration Path
79
+ [How users should update their code]
80
+ ```
81
+
82
+ ## Step 4: Plan Migration Path
83
+
84
+ **Project versioning policy:**
85
+ - Current release line: v4.x (heading to v5.0.0)
86
+ - Breaking changes are batched for major releases (v5.0.0)
87
+ - Use deprecation warnings in the current release line before removal in the next major
88
+
89
+ **Deprecation approach:**
90
+
91
+ ```ruby
92
+ # @deprecated Use {#new_method} instead. Will be removed in v5.0.
93
+ def old_method(*args)
94
+ warn "[DEPRECATION] `old_method` is deprecated. Use `new_method` instead."
95
+ new_method(*args)
96
+ end
97
+ ```
98
+
99
+ **Documentation requirements:**
100
+ - Add `@deprecated` YARD tag with migration guidance
101
+ - Mark commits with `!` for breaking changes and include `BREAKING CHANGE:` footer
102
+ - DO NOT update CHANGELOG.md — it is auto-generated from commit messages
@@ -0,0 +1,264 @@
1
+ ---
2
+ name: ci-cd-troubleshooting
3
+ description: "Diagnoses and fixes CI/CD failures in GitHub Actions workflows. Use when CI is failing on a PR, builds are broken, or tests pass locally but fail in CI."
4
+ ---
5
+
6
+ # CI/CD Troubleshooting Workflow
7
+
8
+ When asked to diagnose or fix CI/CD failures (e.g., "Why is CI failing on PR #999?",
9
+ "Fix the failing build"), follow this workflow to identify the root cause and
10
+ optionally implement fixes.
11
+
12
+ ## Contents
13
+
14
+ - [How to use this skill](#how-to-use-this-skill)
15
+ - [Related skills](#related-skills)
16
+ - [Step 1: Identify the Failure](#step-1-identify-the-failure)
17
+ - [Step 2: Fetch Relevant Logs](#step-2-fetch-relevant-logs)
18
+ - [Step 3: Diagnose Root Cause](#step-3-diagnose-root-cause)
19
+ - [Step 4: Reproduce Locally (if applicable)](#step-4-reproduce-locally-if-applicable)
20
+ - [Step 5: Report Findings or Fix](#step-5-report-findings-or-fix)
21
+ - [Option A: Diagnostic Report ("Why is CI failing?")](#option-a-diagnostic-report-why-is-ci-failing)
22
+ - [Option B: Implement Fix ("Fix the failing build")](#option-b-implement-fix-fix-the-failing-build)
23
+ - [Step 6: Verify Fix](#step-6-verify-fix)
24
+ - [Special Troubleshooting Considerations](#special-troubleshooting-considerations)
25
+
26
+ ## How to use this skill
27
+
28
+ Attach this file to your Copilot Chat context, then invoke it with a failing PR
29
+ number, branch, or CI run context. Use Option A for diagnosis-only requests and
30
+ Option B when the user explicitly asks for a fix.
31
+
32
+ ## Related skills
33
+
34
+ - [Test Debugging](../test-debugging/SKILL.md) — deep-dive test failure analysis
35
+ and flakiness fixes
36
+ - [Development Workflow](../development-workflow/SKILL.md) — full TDD execution
37
+ when implementing CI fixes
38
+ - [PR Readiness Review](../pr-readiness-review/SKILL.md) — final validation
39
+ before opening or updating a PR
40
+
41
+ ## Step 1: Identify the Failure
42
+
43
+ 1. **Get CI Status:**
44
+ - For PRs: `gh pr checks #999`
45
+ - For branches: `gh run list --branch <branch-name> --limit 5`
46
+ - Note which jobs passed and which failed
47
+
48
+ 2. **Categorize the Failure Type:**
49
+ - **Test failures** - Unit tests, integration tests failing
50
+ - **Linter failures** - Rubocop, YARD documentation issues
51
+ - **Build failures** - Dependency installation, compilation errors
52
+ - **Timeout failures** - Jobs exceeding time limits
53
+ - **Platform-specific failures** - Failing on specific Ruby version or OS
54
+
55
+ 3. **Identify Specific Failing Steps:**
56
+ - Note the exact job name and step that failed
57
+ - Record the Ruby version, OS, and other environment details
58
+
59
+ ## Step 2: Fetch Relevant Logs
60
+
61
+ **CRITICAL: CI logs can be massive (100K+ lines) and exceed token limits.**
62
+
63
+ 1. **Get the Run ID:**
64
+
65
+ ```bash
66
+ gh run list --branch <branch> --limit 1 --json databaseId --jq '.[0].databaseId'
67
+ ```
68
+
69
+ 2. **Fetch Failed Job Logs Only:**
70
+
71
+ ```bash
72
+ gh run view <run-id> --log-failed
73
+ ```
74
+
75
+ This limits output to only failed jobs, making it manageable.
76
+
77
+ 3. **Extract Key Error Information:**
78
+
79
+ - For test failures: Look for stack traces, assertion errors, specific test names
80
+ - For linter failures: Extract file names, line numbers, and violation types
81
+ - For build failures: Find dependency errors or missing packages
82
+ - Use `grep` to filter logs if still too large:
83
+
84
+ ```bash
85
+ gh run view <run-id> --log-failed | grep -A 10 -B 5 "Error\|FAILED\|Failure"
86
+ ```
87
+
88
+ 4. **Avoid Full Log Downloads:**
89
+
90
+ - Do NOT use `--log` without `--log-failed` unless specifically requested
91
+ - If logs are still too large, focus on the most recent or critical failure
92
+
93
+ ## Step 3: Diagnose Root Cause
94
+
95
+ Based on the failure type, investigate:
96
+
97
+ **For Test Failures:**
98
+
99
+ - Check if the test exists and what it's testing
100
+ - Look for recent changes that might have broken the test
101
+ - Consider environment differences (local vs. CI)
102
+ - Check for flaky tests (intermittent failures)
103
+
104
+ **For Linter Failures:**
105
+
106
+ - Run linters locally: `bundle exec rubocop` and `bundle exec rake yard`
107
+ - Identify specific violations from the log
108
+ - Check if violations are in files related to recent changes
109
+
110
+ **For Build Failures:**
111
+
112
+ - Check dependency versions in `Gemfile` and `git.gemspec`
113
+ - Look for platform-specific dependency issues
114
+ - Verify Ruby version compatibility
115
+
116
+ **For Timeout Failures:**
117
+
118
+ - Identify which test or step is timing out
119
+ - Check for infinite loops or performance regressions
120
+ - Consider if it's a resource limitation in CI environment
121
+
122
+ ## Step 4: Reproduce Locally (if applicable)
123
+
124
+ **For PR Failures:**
125
+
126
+ 1. Fetch the PR branch:
127
+
128
+ ```bash
129
+ gh pr checkout #999
130
+ ```
131
+
132
+ 2. Run the failing tests locally:
133
+
134
+ ```bash
135
+ bundle exec bin/test <test-name>
136
+ ```
137
+
138
+ 3. Run linters:
139
+
140
+ ```bash
141
+ bundle exec rubocop
142
+ bundle exec rake yard
143
+ ```
144
+
145
+ **For Branch Failures:**
146
+
147
+ 1. Checkout the branch.
148
+ 2. Run full CI workflow:
149
+
150
+ ```bash
151
+ bundle exec rake default
152
+ ```
153
+
154
+ ## Step 5: Report Findings or Fix
155
+
156
+ Determine the appropriate action based on the user's request:
157
+
158
+ ### Option A: Diagnostic Report ("Why is CI failing?")
159
+
160
+ Present findings to the user:
161
+
162
+ ````markdown
163
+ # CI Failure Diagnosis: <Branch/PR>
164
+
165
+ **Status:** <X of Y jobs failed>
166
+
167
+ ## Failed Jobs
168
+ 1. **<Job Name>** (<Ruby version>, <OS>)
169
+ - **Step:** <failing step name>
170
+ - **Failure Type:** <test/linter/build/timeout>
171
+
172
+ ## Root Cause
173
+ <Explanation of what's causing the failure>
174
+
175
+ ## Error Details
176
+ ```
177
+ <Relevant error messages and stack traces>
178
+ ```
179
+
180
+ ## Recommendations
181
+ - <Specific fix suggestion 1>
182
+ - <Specific fix suggestion 2>
183
+
184
+ **Would you like me to implement a fix, or do you need more information?**
185
+ ````
186
+
187
+ **STOP here** unless the user asks you to proceed with fixes.
188
+
189
+ ### Option B: Implement Fix ("Fix the failing build")
190
+
191
+ Proceed based on failure type:
192
+
193
+ - **Test Failures:** Use the full TDD workflow (Phase 1-3) to fix the failing tests
194
+ - **Linter Failures:** Fix violations directly, commit with appropriate message
195
+ (e.g., `style: fix rubocop violations in lib/git/base.rb`)
196
+ - **Build Failures:** Update dependencies or configuration as needed
197
+ - **Timeout Failures:** Investigate performance issues, may require user guidance
198
+
199
+ **For PR Failures on Someone Else's PR:**
200
+
201
+ - You may not have push access to their branch
202
+ - Present the fix and ask user to either:
203
+ - Push to the PR branch (if they have access)
204
+ - Comment on the PR with suggested changes
205
+ - Create a new PR with fixes
206
+
207
+ ## Step 6: Verify Fix
208
+
209
+ After implementing fixes:
210
+
211
+ 1. **Run Affected Tests Locally:**
212
+
213
+ ```bash
214
+ bundle exec bin/test <test-name>
215
+ ```
216
+
217
+ 2. **Run Full CI Suite:**
218
+
219
+ ```bash
220
+ bundle exec rake default
221
+ ```
222
+
223
+ 3. **Push and Monitor:**
224
+
225
+ - Push the fixes
226
+ - Monitor CI to confirm the fix worked:
227
+
228
+ ```bash
229
+ gh run watch
230
+ ```
231
+
232
+ 4. **Confirm Resolution:**
233
+
234
+ ```text
235
+ Fix implemented and pushed. Monitoring CI run...
236
+ CI Status: <link to run>
237
+ ```
238
+
239
+ ## Special Troubleshooting Considerations
240
+
241
+ **Platform-Specific Failures:**
242
+
243
+ - If tests pass on macOS but fail on Linux/Windows, document the difference
244
+ - Check for path separator issues (`/` vs. `\`)
245
+ - Look for encoding differences
246
+ - Consider file system case sensitivity
247
+
248
+ **Flaky Tests:**
249
+
250
+ - If a test fails intermittently, note this in your diagnosis
251
+ - Run the test multiple times locally to confirm flakiness
252
+ - Suggest fixes for race conditions or timing issues
253
+
254
+ **Permission Issues:**
255
+
256
+ - If you can't push to a PR branch, clearly communicate this limitation
257
+ - Provide the exact commands or changes needed for the user to apply
258
+
259
+ **Token Limit Management:**
260
+
261
+ - Always use `--log-failed` to limit output
262
+ - If logs are still too large, use `grep` to extract errors
263
+ - Focus on the first failure if multiple failures exist
264
+ - Consider running tests locally instead of relying on full CI logs