ace-git 0.18.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 (72) hide show
  1. checksums.yaml +7 -0
  2. data/.ace-defaults/git/config.yml +83 -0
  3. data/.ace-defaults/nav/protocols/guide-sources/ace-git.yml +10 -0
  4. data/.ace-defaults/nav/protocols/tmpl-sources/ace-git.yml +19 -0
  5. data/.ace-defaults/nav/protocols/wfi-sources/ace-git.yml +19 -0
  6. data/CHANGELOG.md +762 -0
  7. data/LICENSE +21 -0
  8. data/README.md +48 -0
  9. data/Rakefile +14 -0
  10. data/docs/demo/ace-git-getting-started.gif +0 -0
  11. data/docs/demo/ace-git-getting-started.tape.yml +18 -0
  12. data/docs/demo/fixtures/README.md +3 -0
  13. data/docs/demo/fixtures/sample.txt +1 -0
  14. data/docs/getting-started.md +87 -0
  15. data/docs/handbook.md +50 -0
  16. data/docs/usage.md +259 -0
  17. data/exe/ace-git +37 -0
  18. data/handbook/guides/version-control/ruby.md +41 -0
  19. data/handbook/guides/version-control/rust.md +49 -0
  20. data/handbook/guides/version-control/typescript.md +47 -0
  21. data/handbook/guides/version-control-system-git.g.md +829 -0
  22. data/handbook/skills/as-git-rebase/SKILL.md +43 -0
  23. data/handbook/skills/as-git-reorganize-commits/SKILL.md +41 -0
  24. data/handbook/skills/as-github-pr-create/SKILL.md +60 -0
  25. data/handbook/skills/as-github-pr-update/SKILL.md +41 -0
  26. data/handbook/skills/as-github-release-publish/SKILL.md +58 -0
  27. data/handbook/templates/commit/squash.template.md +59 -0
  28. data/handbook/templates/pr/bugfix.template.md +103 -0
  29. data/handbook/templates/pr/default.template.md +40 -0
  30. data/handbook/templates/pr/feature.template.md +41 -0
  31. data/handbook/workflow-instructions/git/rebase.wf.md +402 -0
  32. data/handbook/workflow-instructions/git/reorganize-commits.wf.md +158 -0
  33. data/handbook/workflow-instructions/github/pr/create.wf.md +282 -0
  34. data/handbook/workflow-instructions/github/pr/update.wf.md +199 -0
  35. data/handbook/workflow-instructions/github/release-publish.wf.md +162 -0
  36. data/lib/ace/git/atoms/command_executor.rb +253 -0
  37. data/lib/ace/git/atoms/date_resolver.rb +129 -0
  38. data/lib/ace/git/atoms/diff_numstat_parser.rb +82 -0
  39. data/lib/ace/git/atoms/diff_parser.rb +110 -0
  40. data/lib/ace/git/atoms/file_grouper.rb +152 -0
  41. data/lib/ace/git/atoms/git_scope_filter.rb +86 -0
  42. data/lib/ace/git/atoms/git_status_fetcher.rb +29 -0
  43. data/lib/ace/git/atoms/grouped_stats_formatter.rb +233 -0
  44. data/lib/ace/git/atoms/lock_error_detector.rb +79 -0
  45. data/lib/ace/git/atoms/pattern_filter.rb +156 -0
  46. data/lib/ace/git/atoms/pr_identifier_parser.rb +88 -0
  47. data/lib/ace/git/atoms/repository_checker.rb +97 -0
  48. data/lib/ace/git/atoms/repository_state_detector.rb +92 -0
  49. data/lib/ace/git/atoms/stale_lock_cleaner.rb +247 -0
  50. data/lib/ace/git/atoms/status_formatter.rb +180 -0
  51. data/lib/ace/git/atoms/task_pattern_extractor.rb +57 -0
  52. data/lib/ace/git/atoms/time_formatter.rb +84 -0
  53. data/lib/ace/git/cli/commands/branch.rb +62 -0
  54. data/lib/ace/git/cli/commands/diff.rb +252 -0
  55. data/lib/ace/git/cli/commands/pr.rb +119 -0
  56. data/lib/ace/git/cli/commands/status.rb +84 -0
  57. data/lib/ace/git/cli.rb +87 -0
  58. data/lib/ace/git/models/diff_config.rb +185 -0
  59. data/lib/ace/git/models/diff_result.rb +94 -0
  60. data/lib/ace/git/models/repo_status.rb +202 -0
  61. data/lib/ace/git/molecules/branch_reader.rb +92 -0
  62. data/lib/ace/git/molecules/config_loader.rb +108 -0
  63. data/lib/ace/git/molecules/diff_filter.rb +102 -0
  64. data/lib/ace/git/molecules/diff_generator.rb +160 -0
  65. data/lib/ace/git/molecules/git_status_fetcher.rb +32 -0
  66. data/lib/ace/git/molecules/pr_metadata_fetcher.rb +286 -0
  67. data/lib/ace/git/molecules/recent_commits_fetcher.rb +53 -0
  68. data/lib/ace/git/organisms/diff_orchestrator.rb +178 -0
  69. data/lib/ace/git/organisms/repo_status_loader.rb +264 -0
  70. data/lib/ace/git/version.rb +7 -0
  71. data/lib/ace/git.rb +230 -0
  72. metadata +201 -0
@@ -0,0 +1,282 @@
1
+ ---
2
+ doc-type: workflow
3
+ title: Pull Request Creation Workflow
4
+ purpose: pull request creation workflow
5
+ ace-docs:
6
+ last-updated: 2026-03-04
7
+ last-checked: 2026-03-21
8
+ ---
9
+
10
+ # Pull Request Creation Workflow
11
+
12
+ ## Purpose
13
+
14
+ Create pull requests with descriptions sourced from code evidence (diff, commits, tests, changelogs), using consistent section structure.
15
+
16
+ ## Variables
17
+
18
+ - `$pr_type`: `feature`, `bugfix`, or `default`
19
+ - `$target_branch`: target branch (default resolved from task/worktree context)
20
+ - `$draft`: create as draft (`false` by default)
21
+
22
+ ## Instructions
23
+
24
+ ### 1. Pre-PR Verification
25
+
26
+ ```bash
27
+ git branch --show-current
28
+ git status
29
+ git log origin/${target_branch:-main}..HEAD --oneline
30
+ ace-test
31
+ ```
32
+
33
+ Checklist:
34
+ - [ ] All changes committed
35
+ - [ ] Relevant tests pass
36
+ - [ ] CHANGELOG updated if release notes changed
37
+ - [ ] No sensitive data in diff
38
+
39
+ ### 2. Resolve Target Branch
40
+
41
+ Prefer task/worktree metadata from `_current/*.s.md` (`worktree.target_branch`), fallback to `main`.
42
+
43
+ ```bash
44
+ task_file=$(ls _current/*.s.md 2>/dev/null | head -1)
45
+ ```
46
+
47
+ If subtask context exists and current target is `main`, switch target to parent task branch.
48
+
49
+ ### 3. Push Branch
50
+
51
+ ```bash
52
+ git push -u origin "$(git branch --show-current)"
53
+ ```
54
+
55
+ **If push is rejected (non-fast-forward)**:
56
+ - For feature branches with worktree-based divergence, prefer `git push --force-with-lease`
57
+ - For shared branches or uncertain divergence, ask the user before force-pushing or rebasing
58
+ - Do NOT silently rebase — this is a potentially destructive operation requiring user consent
59
+
60
+ ### 4. Build Evidence Inputs
61
+
62
+ Before writing the body, collect evidence:
63
+
64
+ ```bash
65
+ git log origin/${target_branch:-main}..HEAD --oneline
66
+ ace-git diff --format grouped-stats
67
+ ```
68
+
69
+ And collect:
70
+ - Behavioral evidence from diff (old behavior vs new behavior)
71
+ - Test evidence (test names -> behavior proved, suite totals)
72
+ - Release evidence (CHANGELOG additions)
73
+
74
+ ### 5. Draft PR Body with Required Sections
75
+
76
+ Use this order:
77
+
78
+ ```markdown
79
+ ## 📋 Summary
80
+ ## ✏️ Changes
81
+ ## 📁 File Changes
82
+ ## 🧪 Test Evidence
83
+ ## 📦 Releases
84
+ ## 🎮 Demo
85
+ ```
86
+
87
+ Section sourcing rules:
88
+
89
+ | Section | Data Source | Avoid |
90
+ |---|---|---|
91
+ | Summary | Diff behavior and user pain removed | Restating task objective text |
92
+ | Changes | Concern-grouped code changes linked to commits | Raw commit dump |
93
+ | File Changes | `ace-git diff --format grouped-stats` | Manual unstructured file list |
94
+ | Test Evidence | Test names mapped to behaviors + totals | Raw command output paste |
95
+ | Releases | CHANGELOG diff entries | Duplicating Changes section |
96
+ | Demo | Runnable commands from README/usage.md + observed output | Screenshots, prose-only descriptions without commands |
97
+
98
+ **Grouped-stats formatting rule:**
99
+ - The `## 📁 File Changes` section must wrap grouped-stats output inside a fenced code block (```)
100
+ - Paste the output exactly as produced — preserve all column alignment, tree indentation, and emoji markers
101
+ - Never convert grouped-stats output into bullet lists, tables, or prose
102
+
103
+ Summary writing rules:
104
+ - Start with what is easier now
105
+ - Mention what users/reviewers had to do before
106
+ - Do not lead with method/class names
107
+ - Do not use task-spec text as prose source
108
+
109
+ Bullet formatting rules:
110
+ - **Bold the first key term** in each bullet (feature name, class name, CLI flag, or config key) so it serves as a visual anchor before the explanation. Example: `- Add **\`GroupedStatsFormatter\`**: formats numstat output into...`
111
+ - In Test Evidence, bold the test class name: `- **GroupedStatsFormatterTest** (6 tests) — validates...`
112
+ - In Releases, bold the package+version: `- **ace-git v0.11.0–v0.11.6** — Add grouped-stats format...`
113
+
114
+ Demo section rules:
115
+ - Include `## 🎮 Demo` when the PR introduces a user-facing CLI or runnable entry point
116
+ - Structure: `### Run` (exact command), `### Expected Output`, `### Artifacts` (where to find results)
117
+ - Omit when: no user-facing CLI, no runnable entry point, or purely internal refactoring
118
+
119
+ Omission/fallback rules:
120
+ - No changelog evidence -> omit `## 📦 Releases`
121
+ - No test-file evidence -> `## 🧪 Test Evidence` may include totals-only validation
122
+ - grouped-stats unavailable -> fallback to flat file list in `## 📁 File Changes`
123
+ - No user-facing CLI or runnable entry point -> omit `## 🎮 Demo`
124
+ - Omit any section lacking evidence; never leave empty placeholders
125
+
126
+ #### Grouped-stats example
127
+
128
+ Correct — output wrapped in a fenced code block preserving all formatting:
129
+
130
+ ````
131
+ ## 📁 File Changes
132
+
133
+ ```
134
+ +762, -54 34 files total
135
+
136
+ +358, -35 10 files ace-overseer/
137
+ +117, -18 4 files 🧱 lib/
138
+ +19, -3 ace/overseer/cli/commands/work_on.rb
139
+ ```
140
+ ````
141
+
142
+ Incorrect — reformatted into bullet list (loses tree structure and alignment):
143
+
144
+ ```
145
+ ## 📁 File Changes
146
+
147
+ - ace-overseer/lib/ace/overseer/cli/commands/work_on.rb (+19, -3)
148
+ - ace-overseer/lib/ace/overseer/molecules/assignment_launcher.rb (+42, -8)
149
+ ```
150
+
151
+ ### 6. Create PR
152
+
153
+ ```bash
154
+ gh pr create \
155
+ --title "<task-id-or-type>: <user-impact-description>" \
156
+ --body-file pr-description.md \
157
+ --base "${target_branch:-main}"
158
+ ```
159
+
160
+ Optional draft mode:
161
+
162
+ ```bash
163
+ gh pr create --draft --title "..." --body-file pr-description.md --base "${target_branch:-main}"
164
+ ```
165
+
166
+ ### 7. Add Metadata (Optional)
167
+
168
+ ```bash
169
+ gh pr edit --add-reviewer @reviewer1,@reviewer2
170
+ gh pr edit --add-label "enhancement,needs-review"
171
+ ```
172
+
173
+ ### 8. Verify PR
174
+
175
+ ```bash
176
+ gh pr view
177
+ gh pr checks
178
+ ```
179
+
180
+ ## Success Criteria
181
+
182
+ - PR created with evidence-based body
183
+ - Section order matches required structure
184
+ - Summary is user-impact-first and task-spec-independent
185
+ - File changes sourced from grouped-stats (or fallback)
186
+ - Test evidence maps tests to behavior
187
+ - Releases only included when changelog evidence exists
188
+
189
+ ## Response Template
190
+
191
+ **PR Created:** [URL]
192
+ **PR Number:** #[number]
193
+ **Title:** [PR title]
194
+ **Type:** [feature/bugfix/default]
195
+ **Status:** [created|draft|failed]
196
+
197
+ <documents>
198
+ <template path="ace-git/handbook/templates/pr/feature.template.md">
199
+ ## 📋 Summary
200
+
201
+ [What is easier now for users/reviewers]
202
+ [What pain/manual step/error existed before]
203
+
204
+ ## ✏️ Changes
205
+
206
+ - Add **`[FeatureName]`**: [what it does]
207
+ - Add **`[ClassName]`** to [what it enables]
208
+
209
+ ## 📁 File Changes
210
+
211
+ [Paste `ace-git diff --format grouped-stats` output verbatim inside a fenced code block — preserve all spacing and tree structure]
212
+ [Fallback: flat file list if grouped-stats unavailable]
213
+
214
+ ## 🧪 Test Evidence
215
+
216
+ - **[TestClassName]** ([N] tests) — [behavior validated]
217
+ - Suite totals: [passed]/[total]
218
+
219
+ ## 📦 Releases
220
+
221
+ - **[package vX.Y.Z]** — [CHANGELOG entry from diff]
222
+
223
+ ## 🎮 Demo
224
+
225
+ [Runnable command(s) demonstrating the feature — omit section if no user-facing CLI]
226
+ [Expected output and artifact locations]
227
+ </template>
228
+
229
+ <template path="ace-git/handbook/templates/pr/bugfix.template.md">
230
+ ## 📋 Summary
231
+
232
+ [What broke and what is now fixed]
233
+
234
+ ## ✏️ Changes
235
+
236
+ - Fix **`[ErrorType]`** when [condition] ([commit-sha])
237
+ - Add **`[TestName]`** to guard against regression ([commit-sha])
238
+
239
+ ## 📁 File Changes
240
+
241
+ [Paste `ace-git diff --format grouped-stats` output verbatim inside a fenced code block — preserve all spacing and tree structure]
242
+
243
+ ## 🧪 Test Evidence
244
+
245
+ - **[TestClassName]** ([N] tests) — [regression behavior covered]
246
+ - Suite totals: [passed]/[total]
247
+
248
+ ## 📦 Releases
249
+
250
+ - **[package vX.Y.Z]** — [CHANGELOG fix entry from diff]
251
+ </template>
252
+
253
+ <template path="ace-git/handbook/templates/pr/default.template.md">
254
+ ## 📋 Summary
255
+
256
+ [What is easier now]
257
+ [What changed from user/reviewer perspective]
258
+
259
+ ## ✏️ Changes
260
+
261
+ - Add **`[PrimaryChange]`**: [description] ([commit-sha])
262
+ - Update **`[SecondaryChange]`**: [description] ([commit-sha])
263
+
264
+ ## 📁 File Changes
265
+
266
+ [Paste `ace-git diff --format grouped-stats` output verbatim inside a fenced code block — preserve all spacing and tree structure]
267
+
268
+ ## 🧪 Test Evidence
269
+
270
+ - **[TestClassName]** ([N] tests) — [behavior validated]
271
+ - Suite totals: [passed]/[total]
272
+
273
+ ## 📦 Releases
274
+
275
+ - **[package vX.Y.Z]** — [CHANGELOG entry from diff, if any]
276
+
277
+ ## 🎮 Demo
278
+
279
+ [Runnable command(s) demonstrating the change — omit section if no user-facing CLI]
280
+ [Expected output and artifact locations]
281
+ </template>
282
+ </documents>
@@ -0,0 +1,199 @@
1
+ ---
2
+ doc-type: workflow
3
+ title: Update PR Description Workflow
4
+ purpose: evidence-based PR documentation
5
+ ace-docs:
6
+ last-updated: 2026-03-04
7
+ last-checked: 2026-03-21
8
+ ---
9
+
10
+ # Update PR Description Workflow
11
+
12
+ ## Purpose
13
+
14
+ Generate PR titles and descriptions from code evidence in the PR (diff, commits, tests, and changelog entries), not from task specification text.
15
+
16
+ ## Variables
17
+
18
+ - `$pr_number`: PR number to update (optional - auto-detect from current branch)
19
+
20
+ ## Instructions
21
+
22
+ ### 1. Resolve PR Number
23
+
24
+ ```bash
25
+ gh pr view --json number -q .number
26
+ ```
27
+
28
+ If no PR exists for current branch, ask the user for the target PR number.
29
+
30
+ ### 2. Verify Target Branch
31
+
32
+ ```bash
33
+ gh pr view $pr_number --json baseRefName,headRefName,title
34
+ ace-taskflow status
35
+ ```
36
+
37
+ If taskflow context indicates a subtask and the PR targets `main`, retarget to the parent task branch before continuing.
38
+
39
+ ### 3. Collect Evidence Inputs
40
+
41
+ Collect the evidence used to write the PR:
42
+
43
+ ```bash
44
+ # Changed files
45
+ gh pr diff $pr_number --name-only
46
+
47
+ # Full diff for behavior and error-message changes
48
+ gh pr diff $pr_number
49
+
50
+ # Commit headlines
51
+ gh pr view $pr_number --json commits -q '.commits[].messageHeadline'
52
+
53
+ # File-change grouping (preferred)
54
+ ace-git diff $(git merge-base HEAD origin/main)..HEAD --format grouped-stats
55
+ ```
56
+
57
+ Also gather test evidence and release evidence:
58
+ - Test evidence: test files changed in diff + relevant test outputs/suite totals
59
+ - Release evidence: CHANGELOG entries present in diff
60
+
61
+ ### 4. Generate Evidence-Based Title
62
+
63
+ Title format:
64
+ - If task ID available from `ace-git status --no-pr`: `<task-id>: <description>`
65
+ - Otherwise: `<type>(<scope>): <description>`
66
+
67
+ Title guidance:
68
+ - Focus on user-facing impact
69
+ - Keep concise (target < 60 chars after task-id)
70
+ - Do not lead with class/method names unless unavoidable
71
+
72
+ ### 5. Generate PR Description
73
+
74
+ Use this section order exactly:
75
+
76
+ ```markdown
77
+ ## 📋 Summary
78
+ ## ✏️ Changes
79
+ ## 📁 File Changes
80
+ ## 🧪 Test Evidence
81
+ ## 📦 Releases
82
+ ## 🎮 Demo
83
+ ```
84
+
85
+ Section sourcing rules:
86
+
87
+ | Section | Required Source | Avoid |
88
+ |---|---|---|
89
+ | Summary | Behavioral change in diff + commit intent | Task spec objective text |
90
+ | Changes | Concern-grouped diff changes, traced to commits | Raw commit list dump |
91
+ | File Changes | `ace-git diff $(git merge-base HEAD origin/main)..HEAD --format grouped-stats` output, pasted verbatim and in full | Manual hand-written file listing, trimming or abbreviating the grouped-stats output |
92
+ | Test Evidence | Test names mapped to behaviors + suite totals | Raw unstructured test output paste |
93
+ | Releases | CHANGELOG entries from diff | Repeating content already in Changes |
94
+ | Demo | Runnable commands from README/usage.md + observed output | Screenshots, prose-only descriptions without commands |
95
+
96
+ **Grouped-stats formatting rule:**
97
+ - The `## 📁 File Changes` section must wrap grouped-stats output inside a fenced code block (```)
98
+ - Paste the output exactly as produced — preserve all column alignment, tree indentation, and emoji markers
99
+ - Never convert grouped-stats output into bullet lists, tables, or prose
100
+
101
+ Bullet formatting rules:
102
+ - **Bold the first key term** in each bullet (feature name, class name, CLI flag, or config key) so it serves as a visual anchor before the explanation. Example: `- Add **\`GroupedStatsFormatter\`**: formats numstat output into...`
103
+ - In Test Evidence, bold the test class name: `- **GroupedStatsFormatterTest** (6 tests) — validates...`
104
+ - In Releases, bold the package+version: `- **ace-git v0.11.0–v0.11.6** — Add grouped-stats format...`
105
+
106
+ ### 6. Summary Writing Rules
107
+
108
+ Write Summary in this sequence:
109
+ 1. What is easier now for users/reviewers
110
+ 2. What pain/manual step/error state existed before
111
+ 3. What changed to remove that pain
112
+
113
+ Constraints:
114
+ - Do not copy wording from task specs
115
+ - Do not start with method/class names
116
+ - Prefer behavior language over implementation language
117
+
118
+ ### 7. Demo Section Rules
119
+
120
+ Include `## 🎮 Demo` when the PR introduces a user-facing CLI command or runnable entry point that a reviewer can try.
121
+
122
+ Structure:
123
+
124
+ ```markdown
125
+ ## 🎮 Demo
126
+
127
+ ### Run
128
+ \`\`\`bash
129
+ [exact command to copy-paste]
130
+ \`\`\`
131
+
132
+ ### Expected Output
133
+ [what the reviewer should see]
134
+
135
+ ### Artifacts
136
+ [where to find generated files]
137
+ ```
138
+
139
+ Omit when: the PR has no user-facing CLI, no runnable entry point, or is purely internal refactoring.
140
+
141
+ ### 8. Omission and Fallback Rules
142
+
143
+ - If no changelog evidence: omit `## 📦 Releases`
144
+ - If no test-file evidence: keep `## 🧪 Test Evidence` with suite totals only
145
+ - If `ace-git diff $(git merge-base HEAD origin/main)..HEAD --format grouped-stats` is unavailable: use flat file list fallback under `## 📁 File Changes`
146
+ - If no user-facing CLI or runnable entry point: omit `## 🎮 Demo`
147
+ - Omit sections with no supporting evidence instead of leaving placeholders
148
+
149
+ #### Grouped-stats example
150
+
151
+ Correct — output wrapped in a fenced code block preserving all formatting:
152
+
153
+ ````
154
+ ## 📁 File Changes
155
+
156
+ ```
157
+ +762, -54 34 files total
158
+
159
+ +358, -35 10 files ace-overseer/
160
+ +117, -18 4 files 🧱 lib/
161
+ +19, -3 ace/overseer/cli/commands/work_on.rb
162
+ ```
163
+ ````
164
+
165
+ Incorrect — reformatted into bullet list (loses tree structure and alignment):
166
+
167
+ ```
168
+ ## 📁 File Changes
169
+
170
+ - ace-overseer/lib/ace/overseer/cli/commands/work_on.rb (+19, -3)
171
+ - ace-overseer/lib/ace/overseer/molecules/assignment_launcher.rb (+42, -8)
172
+ ```
173
+
174
+ ### 9. Update PR
175
+
176
+ ```bash
177
+ gh pr edit $pr_number \
178
+ --title "Generated title" \
179
+ --body "$(cat <<'BODY'
180
+ ## 📋 Summary
181
+ ...
182
+ BODY
183
+ )"
184
+ ```
185
+
186
+ ### 10. Confirm Update
187
+
188
+ ```bash
189
+ gh pr view $pr_number --json url,title -q '.url + "\n" + .title'
190
+ ```
191
+
192
+ ## Success Criteria
193
+
194
+ - Description uses: `📋 Summary -> ✏️ Changes -> 📁 File Changes -> 🧪 Test Evidence -> 📦 Releases -> 🎮 Demo`
195
+ - Summary leads with user impact and does not restate task specs
196
+ - File Changes contains the complete, untruncated grouped-stats output (never trimmed, summarised, or selectively omitted)
197
+ - Test Evidence maps tests to behavior and includes totals
198
+ - Releases derived from changelog evidence only
199
+ - Empty/no-evidence sections are omitted
@@ -0,0 +1,162 @@
1
+ ---
2
+ doc-type: workflow
3
+ title: GitHub Release Publish Workflow
4
+ purpose: GitHub release publishing workflow
5
+ ace-docs:
6
+ last-updated: 2026-03-21
7
+ last-checked: 2026-03-21
8
+ ---
9
+
10
+ # GitHub Release Publish Workflow
11
+
12
+ ## Purpose
13
+
14
+ Create GitHub releases from root `CHANGELOG.md` entries that have no corresponding GitHub release, supporting retroactive bulk publishing and ongoing single-version releases.
15
+
16
+ ## Variables
17
+
18
+ - `$version`: explicit version like `v0.9.846`, or range like `v0.9.840..v0.9.846`
19
+ - `$since`: time filter like `"3 days"` or `"this week"`
20
+ - `$dry_run`: if set, print what would be created without creating anything
21
+
22
+ ## Instructions
23
+
24
+ ### 1. Determine Published Baseline
25
+
26
+ Find the latest GitHub release with a `v*` tag, ignoring non-version releases:
27
+
28
+ ```bash
29
+ gh release list --limit 50 --json tagName,name --jq '[.[] | select(.tagName | startswith("v"))] | first // empty'
30
+ ```
31
+
32
+ If no `v*` release exists, treat all changelog versions as unpublished.
33
+
34
+ ### 2. Parse Root CHANGELOG
35
+
36
+ Read `CHANGELOG.md` and extract all version entries matching `## [X.Y.Z] - YYYY-MM-DD`.
37
+
38
+ Build a list of `{version, date, body}` records where:
39
+ - `version`: the semver string (e.g., `0.9.846`)
40
+ - `date`: the release date
41
+ - `body`: the full markdown content between this heading and the next `## [` heading
42
+
43
+ ### 3. Filter Versions
44
+
45
+ Apply filters based on arguments:
46
+
47
+ | Argument | Filter |
48
+ |---|---|
49
+ | No args | All versions newer than latest published `v*` release |
50
+ | Single version `v0.9.846` | Just that version |
51
+ | Range `v0.9.840..v0.9.846` | All versions where `840 <= patch <= 846` (comparing full semver) |
52
+ | `--since "3 days"` | Versions with changelog date within the time window |
53
+
54
+ If no versions remain after filtering, report and stop:
55
+
56
+ ```text
57
+ No unpublished versions found matching the given criteria.
58
+ ```
59
+
60
+ ### 4. Group by Date
61
+
62
+ Multiple changelog versions on the same date are consolidated into one GitHub release per day:
63
+
64
+ - **Tag/title**: uses the highest version of that day (e.g., `v0.9.846` if versions 840–846 all share 2026-03-18)
65
+ - **Release body**: combines all changelog entries for that day, ordered from highest to lowest version, separated by `---` dividers with version headers
66
+
67
+ Single-version days produce a release with just that version's changelog body (no divider needed).
68
+
69
+ Format for multi-version daily release body:
70
+
71
+ ```markdown
72
+ ## [0.9.846] - 2026-03-18
73
+
74
+ [changelog body for 0.9.846]
75
+
76
+ ---
77
+
78
+ ## [0.9.845] - 2026-03-18
79
+
80
+ [changelog body for 0.9.845]
81
+
82
+ ---
83
+
84
+ ## [0.9.844] - 2026-03-18
85
+
86
+ [changelog body for 0.9.844]
87
+ ```
88
+
89
+ ### 5. Resolve Target Commits
90
+
91
+ For each daily release group, find the commit that introduced the highest version's changelog entry:
92
+
93
+ ```bash
94
+ git log --all -1 --format=%H -S "[${HIGHEST_VERSION}]" -- CHANGELOG.md
95
+ ```
96
+
97
+ If the commit cannot be found, try alternative approaches:
98
+
99
+ ```bash
100
+ git log --all -1 --format=%H --grep="\\[${HIGHEST_VERSION}\\]" -- CHANGELOG.md
101
+ git log --all -1 --format=%H --after="${DATE}T00:00:00" --before="${DATE}T23:59:59" -- CHANGELOG.md
102
+ ```
103
+
104
+ If no commit is found for a version group, skip it and report:
105
+
106
+ ```text
107
+ ⚠ Could not find commit for v${VERSION} (${DATE}) — skipping
108
+ ```
109
+
110
+ ### 6. Create Releases
111
+
112
+ Process each daily group from oldest date to newest:
113
+
114
+ **Dry-run mode** (`--dry-run`):
115
+
116
+ ```text
117
+ [DRY RUN] Would create release:
118
+ Tag: v${VERSION}
119
+ Title: v${VERSION}
120
+ Target: ${SHA}
121
+ Body: ${LINE_COUNT} lines (${VERSION_COUNT} version(s) from ${DATE})
122
+ ```
123
+
124
+ **Live mode**:
125
+
126
+ ```bash
127
+ gh release create "v${VERSION}" \
128
+ --title "v${VERSION}" \
129
+ --notes "${COMBINED_BODY}" \
130
+ --target "${SHA}"
131
+ ```
132
+
133
+ Verify each creation:
134
+
135
+ ```bash
136
+ gh release view "v${VERSION}" --json tagName,targetCommitish --jq '{tag: .tagName, target: .targetCommitish}'
137
+ ```
138
+
139
+ ### 7. Report Results
140
+
141
+ Summarize all created releases:
142
+
143
+ ```text
144
+ ✓ Created v0.9.846 targeting abc1234 (2026-03-18, 7 versions)
145
+ ✓ Created v0.9.839 targeting def5678 (2026-03-17, 3 versions)
146
+ ⚠ Skipped v0.9.835 — commit not found
147
+ ```
148
+
149
+ ## Success Criteria
150
+
151
+ - Every unpublished changelog version is covered by a GitHub release
152
+ - Releases are tagged at the correct commits
153
+ - Multi-version days are consolidated with combined bodies
154
+ - `--dry-run` produces accurate output without side effects
155
+ - Oldest releases are created first to maintain chronological order
156
+
157
+ ## Response Template
158
+
159
+ **Releases Created:** [count]
160
+ **Versions Covered:** [range or list]
161
+ **Skipped:** [count and reasons, if any]
162
+ **Mode:** [live|dry-run]