xtrm-tools 0.5.48 → 0.6.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.
- package/.claude-plugin/plugin.json +1 -1
- package/cli/dist/index.cjs +6218 -7897
- package/cli/dist/index.cjs.map +1 -1
- package/cli/package.json +5 -1
- package/config/pi/extensions/beads/index.ts +1 -1
- package/config/pi/extensions/beads/package.json +4 -1
- package/config/pi/extensions/core/package.json +18 -0
- package/config/pi/extensions/custom-footer/index.ts +138 -71
- package/config/pi/extensions/custom-footer/package.json +4 -1
- package/config/pi/extensions/quality-gates/index.ts +1 -1
- package/config/pi/extensions/quality-gates/package.json +4 -1
- package/config/pi/extensions/service-skills/index.ts +1 -1
- package/config/pi/extensions/service-skills/package.json +4 -1
- package/config/pi/extensions/session-flow/index.ts +1 -1
- package/config/pi/extensions/session-flow/package.json +4 -1
- package/config/pi/extensions/xtrm-loader/index.ts +1 -1
- package/config/pi/extensions/xtrm-loader/package.json +4 -1
- package/hooks/beads-compact-restore.mjs +11 -3
- package/hooks/beads-compact-save.mjs +13 -1
- package/hooks/tsconfig-cache.json +12 -2
- package/package.json +3 -2
- package/plugins/xtrm-tools/.claude-plugin/plugin.json +1 -1
- package/plugins/xtrm-tools/hooks/beads-compact-restore.mjs +11 -3
- package/plugins/xtrm-tools/hooks/beads-compact-save.mjs +13 -1
- package/plugins/xtrm-tools/hooks/tsconfig-cache.json +12 -2
- package/plugins/xtrm-tools/skills/xt-end/SKILL.md +1 -0
- package/plugins/xtrm-tools/skills/xt-merge/SKILL.md +141 -18
- package/skills/xt-end/SKILL.md +1 -0
- package/skills/xt-merge/SKILL.md +141 -18
|
@@ -40,6 +40,46 @@ you're rebasing more than necessary and risk conflicts that wouldn't have existe
|
|
|
40
40
|
|
|
41
41
|
---
|
|
42
42
|
|
|
43
|
+
## Stage 0 — Pre-flight checks
|
|
44
|
+
|
|
45
|
+
Run these before touching any branch.
|
|
46
|
+
|
|
47
|
+
**1. Verify you are in a git repository:**
|
|
48
|
+
```bash
|
|
49
|
+
git rev-parse --git-dir
|
|
50
|
+
```
|
|
51
|
+
Stop immediately if this fails.
|
|
52
|
+
|
|
53
|
+
**2. Verify gh auth:**
|
|
54
|
+
```bash
|
|
55
|
+
gh auth status
|
|
56
|
+
```
|
|
57
|
+
If this fails, stop immediately. Without auth, `gh pr merge` will silently fail or
|
|
58
|
+
produce confusing errors mid-run.
|
|
59
|
+
|
|
60
|
+
**3. Fetch all remotes:**
|
|
61
|
+
```bash
|
|
62
|
+
git fetch --all --prune
|
|
63
|
+
```
|
|
64
|
+
This ensures local remote-tracking refs reflect current upstream state before any
|
|
65
|
+
rebase or CI check. Without this, CI status checks and rebase targets may be stale.
|
|
66
|
+
|
|
67
|
+
**4. Check for uncommitted local changes:**
|
|
68
|
+
```bash
|
|
69
|
+
git status --porcelain
|
|
70
|
+
```
|
|
71
|
+
If the output is non-empty, **warn the user and stop**. The rebase cascade will
|
|
72
|
+
check out other branches (`git checkout xt/<branch>`), which will either fail or
|
|
73
|
+
silently carry dirty changes into the wrong branch. Resolve before continuing:
|
|
74
|
+
- `git stash push -m "xt-merge cascade stash"` — stash and pop after cascade finishes
|
|
75
|
+
- Or commit the work first
|
|
76
|
+
- Or abort if the changes belong to a live worktree session
|
|
77
|
+
|
|
78
|
+
If the user stashes, record the stash ref (`git stash list | head -1`) so you can
|
|
79
|
+
pop it when done in Stage 6.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
43
83
|
## Stage 1 — Build the queue
|
|
44
84
|
|
|
45
85
|
List all open PRs from xt worktree branches:
|
|
@@ -54,6 +94,9 @@ This sorts by creation time. The top row is the **head of the queue** — merge
|
|
|
54
94
|
|
|
55
95
|
If there are draft PRs in the list, skip them. Drafts are not ready to merge.
|
|
56
96
|
|
|
97
|
+
If `gh pr list` returns an error (network, auth, wrong repo), stop and report the
|
|
98
|
+
error. Do not continue with stale or incomplete data.
|
|
99
|
+
|
|
57
100
|
Present the sorted queue to the user before proceeding:
|
|
58
101
|
```
|
|
59
102
|
Queue (oldest → newest):
|
|
@@ -70,6 +113,14 @@ Queue (oldest → newest):
|
|
|
70
113
|
gh pr checks <number>
|
|
71
114
|
```
|
|
72
115
|
|
|
116
|
+
**Stale CI warning:** After a rebase cascade the PR's HEAD SHA changes. Always verify
|
|
117
|
+
the SHA that CI ran against matches the current branch tip before trusting a green result:
|
|
118
|
+
```bash
|
|
119
|
+
gh pr view <number> --json headRefOid --jq '.headRefOid'
|
|
120
|
+
# compare against the commit SHA shown in gh pr checks output
|
|
121
|
+
```
|
|
122
|
+
If they differ, the green result is from before the rebase — wait for the new run.
|
|
123
|
+
|
|
73
124
|
Wait for all checks to pass. If CI is still running, tell the user and pause — don't
|
|
74
125
|
merge a PR with pending or failing checks.
|
|
75
126
|
|
|
@@ -90,12 +141,18 @@ gh pr merge <number> --rebase --delete-branch
|
|
|
90
141
|
Use `--rebase` (not `--squash` or `--merge`) to keep linear history and preserve
|
|
91
142
|
individual commits from the session. Use `--delete-branch` to clean up the remote branch.
|
|
92
143
|
|
|
93
|
-
|
|
144
|
+
If `gh pr merge` fails with "No commits between main and xt/<branch>", the branch's
|
|
145
|
+
commits were already absorbed into main (e.g. from a previous push). Close the PR
|
|
146
|
+
and continue to the next.
|
|
147
|
+
|
|
148
|
+
After merge, fetch and confirm main advanced:
|
|
94
149
|
```bash
|
|
95
150
|
git fetch origin
|
|
96
151
|
git log origin/main --oneline -3
|
|
97
152
|
```
|
|
98
153
|
|
|
154
|
+
Record the new HEAD SHA of main — you will verify the cascade rebases onto it.
|
|
155
|
+
|
|
99
156
|
---
|
|
100
157
|
|
|
101
158
|
## Stage 4 — Rebase cascade (all remaining PRs)
|
|
@@ -106,10 +163,24 @@ For every remaining PR in the queue, rebase its branch onto the new main:
|
|
|
106
163
|
git fetch origin main
|
|
107
164
|
git checkout xt/<branch>
|
|
108
165
|
git rebase origin/main
|
|
109
|
-
git push origin xt/<branch> --force-with-lease
|
|
166
|
+
git push origin xt/<branch> --force-with-lease --force-if-includes
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
`--force-with-lease` rejects the push if the remote has commits your local ref
|
|
170
|
+
doesn't know about. `--force-if-includes` additionally verifies that whatever
|
|
171
|
+
you're overwriting was reachable from your local history — together they prevent
|
|
172
|
+
accidentally overwriting a collaborator's push that arrived after your last fetch.
|
|
173
|
+
(Requires Git 2.30+. If not available, `--force-with-lease` alone is acceptable.)
|
|
174
|
+
|
|
175
|
+
**After each push, verify it landed:**
|
|
176
|
+
```bash
|
|
177
|
+
git rev-parse HEAD
|
|
178
|
+
git rev-parse origin/xt/<branch>
|
|
110
179
|
```
|
|
180
|
+
Both SHAs must match. If the push was rejected (lease violation or other error),
|
|
181
|
+
stop and report — do not silently continue to the next branch.
|
|
111
182
|
|
|
112
|
-
Repeat for each remaining branch
|
|
183
|
+
Repeat for each remaining branch in queue order (oldest next).
|
|
113
184
|
|
|
114
185
|
After pushing, GitHub will re-trigger CI on each rebased PR. You don't need to wait
|
|
115
186
|
for CI here — the rebase just gets the branches current. CI will run in parallel.
|
|
@@ -123,27 +194,43 @@ git add <resolved-files>
|
|
|
123
194
|
git rebase --continue
|
|
124
195
|
```
|
|
125
196
|
|
|
197
|
+
If you cannot safely resolve a conflict, **abort the rebase immediately**:
|
|
198
|
+
```bash
|
|
199
|
+
git rebase --abort
|
|
200
|
+
```
|
|
201
|
+
The branch is left unchanged. Report the branch name and conflicted files to the
|
|
202
|
+
user. Continue the cascade for remaining branches; the user can resolve and push
|
|
203
|
+
this one manually before you loop back to merge it.
|
|
204
|
+
|
|
126
205
|
Conflicts mean two sessions touched the same file. Resolve carefully:
|
|
127
206
|
- Keep both changes if they're in different parts of the file
|
|
128
207
|
- If they overlap, understand what each session was doing and merge the intent
|
|
129
|
-
- When unsure,
|
|
208
|
+
- When unsure, abort and escalate to the user
|
|
130
209
|
|
|
131
|
-
After resolving, push with `--force-with-lease` and
|
|
210
|
+
After resolving, push with `--force-with-lease --force-if-includes` and verify the
|
|
211
|
+
push landed (SHA check above) before moving to the next branch.
|
|
132
212
|
|
|
133
213
|
---
|
|
134
214
|
|
|
135
215
|
## Stage 5 — Repeat
|
|
136
216
|
|
|
137
|
-
Go back to Stage 2 with the new head of the queue. Check CI
|
|
217
|
+
Go back to Stage 2 with the new head of the queue. Check CI on the **new SHA**
|
|
218
|
+
produced by the rebase cascade push — not a pre-rebase result. Merge, cascade,
|
|
138
219
|
repeat until the queue is empty.
|
|
139
220
|
|
|
140
221
|
The full loop:
|
|
141
222
|
```
|
|
142
223
|
while queue not empty:
|
|
143
|
-
|
|
224
|
+
check CI on head PR
|
|
225
|
+
→ verify: gh pr view <n> headRefOid == SHA in gh pr checks output
|
|
226
|
+
→ wait for green; stop if failing
|
|
144
227
|
merge head PR (--rebase --delete-branch)
|
|
145
|
-
|
|
146
|
-
|
|
228
|
+
git fetch origin → confirm main advanced
|
|
229
|
+
for each remaining branch in queue order:
|
|
230
|
+
git checkout xt/<branch>
|
|
231
|
+
git rebase origin/main
|
|
232
|
+
git push --force-with-lease --force-if-includes
|
|
233
|
+
verify: git rev-parse HEAD == git rev-parse origin/xt/<branch>
|
|
147
234
|
```
|
|
148
235
|
|
|
149
236
|
---
|
|
@@ -151,7 +238,11 @@ while queue not empty:
|
|
|
151
238
|
## Stage 6 — Done
|
|
152
239
|
|
|
153
240
|
When the queue is empty:
|
|
241
|
+
|
|
154
242
|
```bash
|
|
243
|
+
# If you stashed changes in Stage 0, pop now:
|
|
244
|
+
git stash pop # report any conflicts — do not discard silently
|
|
245
|
+
|
|
155
246
|
gh pr list --state open
|
|
156
247
|
git log origin/main --oneline -5
|
|
157
248
|
```
|
|
@@ -164,7 +255,10 @@ Confirm no open xt/ PRs remain and show the user the final state of main.
|
|
|
164
255
|
|
|
165
256
|
**PR was already merged**: `gh pr merge` will error. Skip it and continue.
|
|
166
257
|
|
|
167
|
-
**
|
|
258
|
+
**No commits between main and xt/branch**: branch was already absorbed into main.
|
|
259
|
+
Close the PR and continue.
|
|
260
|
+
|
|
261
|
+
**Branch was deleted** (worktree cleaned up by `xt end`): The remote branch
|
|
168
262
|
still exists (pushed by `xt end`). The local branch may not. Check out from remote:
|
|
169
263
|
```bash
|
|
170
264
|
git fetch origin
|
|
@@ -178,13 +272,42 @@ git commit --allow-empty -m "trigger CI"
|
|
|
178
272
|
git push origin xt/<branch>
|
|
179
273
|
```
|
|
180
274
|
|
|
275
|
+
**Stale CI result after rebase**: Always confirm the SHA in `gh pr checks` matches
|
|
276
|
+
`git rev-parse origin/xt/<branch>` before treating a green result as valid. If they
|
|
277
|
+
differ, wait for the new run.
|
|
278
|
+
|
|
279
|
+
**Push rejected (lease violation)**: Do not retry blindly. Fetch and inspect:
|
|
280
|
+
```bash
|
|
281
|
+
git fetch origin xt/<branch>
|
|
282
|
+
git log origin/xt/<branch> --oneline -5
|
|
283
|
+
```
|
|
284
|
+
Decide whether the remote commits should be incorporated or overwritten, then act
|
|
285
|
+
deliberately.
|
|
286
|
+
|
|
287
|
+
**`gh auth` expired mid-run**: Stop the cascade immediately. Report which branches
|
|
288
|
+
were successfully rebased/pushed and which were not, so the user can resume from the
|
|
289
|
+
right point after re-authenticating.
|
|
290
|
+
|
|
291
|
+
**Uncommitted changes on current branch**: Stash before the cascade, pop after:
|
|
292
|
+
```bash
|
|
293
|
+
git stash push -m "xt-merge cascade stash"
|
|
294
|
+
# ... run cascade ...
|
|
295
|
+
git stash pop
|
|
296
|
+
```
|
|
297
|
+
If `git stash pop` produces conflicts, report them — do not silently discard work.
|
|
298
|
+
|
|
181
299
|
**Dependent sessions** (B was intentionally built on A's work): If session B was
|
|
182
300
|
started from inside session A's worktree rather than from main, B's branch already
|
|
183
|
-
contains A's commits.
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
301
|
+
contains A's commits. B will rebase cleanly onto main after A merges — the rebase
|
|
302
|
+
eliminates the duplicate commits. No special handling needed.
|
|
303
|
+
|
|
304
|
+
**Multiple conflicts across many PRs**: Abort each failing rebase (`git rebase --abort`)
|
|
305
|
+
and tackle them one at a time in queue order after the user resolves. Push each
|
|
306
|
+
resolved branch immediately so CI starts running in parallel.
|
|
307
|
+
|
|
308
|
+
**Rollback / abort mid-cascade**: If anything goes wrong and you need to stop cleanly:
|
|
309
|
+
1. `git rebase --abort` if a rebase is in progress
|
|
310
|
+
2. `git checkout <original-branch>` to return to where you started
|
|
311
|
+
3. `git stash pop` if you stashed in Stage 0
|
|
312
|
+
4. Report exactly which PRs were merged, which were rebased-and-pushed, and which
|
|
313
|
+
were untouched — so the user can resume or restart from the correct point.
|
package/skills/xt-end/SKILL.md
CHANGED
|
@@ -19,6 +19,7 @@ Default to **autonomous execution**:
|
|
|
19
19
|
- do not ask the user routine clarification questions
|
|
20
20
|
- prefer deterministic fallbacks over conversational review
|
|
21
21
|
- only stop when a real blocker prevents safe progress
|
|
22
|
+
- **always invoke `xt end --yes`** — never call `xt end` without this flag; the bare command prompts interactively for worktree removal which blocks autonomous execution
|
|
22
23
|
|
|
23
24
|
## Success States
|
|
24
25
|
|
package/skills/xt-merge/SKILL.md
CHANGED
|
@@ -40,6 +40,46 @@ you're rebasing more than necessary and risk conflicts that wouldn't have existe
|
|
|
40
40
|
|
|
41
41
|
---
|
|
42
42
|
|
|
43
|
+
## Stage 0 — Pre-flight checks
|
|
44
|
+
|
|
45
|
+
Run these before touching any branch.
|
|
46
|
+
|
|
47
|
+
**1. Verify you are in a git repository:**
|
|
48
|
+
```bash
|
|
49
|
+
git rev-parse --git-dir
|
|
50
|
+
```
|
|
51
|
+
Stop immediately if this fails.
|
|
52
|
+
|
|
53
|
+
**2. Verify gh auth:**
|
|
54
|
+
```bash
|
|
55
|
+
gh auth status
|
|
56
|
+
```
|
|
57
|
+
If this fails, stop immediately. Without auth, `gh pr merge` will silently fail or
|
|
58
|
+
produce confusing errors mid-run.
|
|
59
|
+
|
|
60
|
+
**3. Fetch all remotes:**
|
|
61
|
+
```bash
|
|
62
|
+
git fetch --all --prune
|
|
63
|
+
```
|
|
64
|
+
This ensures local remote-tracking refs reflect current upstream state before any
|
|
65
|
+
rebase or CI check. Without this, CI status checks and rebase targets may be stale.
|
|
66
|
+
|
|
67
|
+
**4. Check for uncommitted local changes:**
|
|
68
|
+
```bash
|
|
69
|
+
git status --porcelain
|
|
70
|
+
```
|
|
71
|
+
If the output is non-empty, **warn the user and stop**. The rebase cascade will
|
|
72
|
+
check out other branches (`git checkout xt/<branch>`), which will either fail or
|
|
73
|
+
silently carry dirty changes into the wrong branch. Resolve before continuing:
|
|
74
|
+
- `git stash push -m "xt-merge cascade stash"` — stash and pop after cascade finishes
|
|
75
|
+
- Or commit the work first
|
|
76
|
+
- Or abort if the changes belong to a live worktree session
|
|
77
|
+
|
|
78
|
+
If the user stashes, record the stash ref (`git stash list | head -1`) so you can
|
|
79
|
+
pop it when done in Stage 6.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
43
83
|
## Stage 1 — Build the queue
|
|
44
84
|
|
|
45
85
|
List all open PRs from xt worktree branches:
|
|
@@ -54,6 +94,9 @@ This sorts by creation time. The top row is the **head of the queue** — merge
|
|
|
54
94
|
|
|
55
95
|
If there are draft PRs in the list, skip them. Drafts are not ready to merge.
|
|
56
96
|
|
|
97
|
+
If `gh pr list` returns an error (network, auth, wrong repo), stop and report the
|
|
98
|
+
error. Do not continue with stale or incomplete data.
|
|
99
|
+
|
|
57
100
|
Present the sorted queue to the user before proceeding:
|
|
58
101
|
```
|
|
59
102
|
Queue (oldest → newest):
|
|
@@ -70,6 +113,14 @@ Queue (oldest → newest):
|
|
|
70
113
|
gh pr checks <number>
|
|
71
114
|
```
|
|
72
115
|
|
|
116
|
+
**Stale CI warning:** After a rebase cascade the PR's HEAD SHA changes. Always verify
|
|
117
|
+
the SHA that CI ran against matches the current branch tip before trusting a green result:
|
|
118
|
+
```bash
|
|
119
|
+
gh pr view <number> --json headRefOid --jq '.headRefOid'
|
|
120
|
+
# compare against the commit SHA shown in gh pr checks output
|
|
121
|
+
```
|
|
122
|
+
If they differ, the green result is from before the rebase — wait for the new run.
|
|
123
|
+
|
|
73
124
|
Wait for all checks to pass. If CI is still running, tell the user and pause — don't
|
|
74
125
|
merge a PR with pending or failing checks.
|
|
75
126
|
|
|
@@ -90,12 +141,18 @@ gh pr merge <number> --rebase --delete-branch
|
|
|
90
141
|
Use `--rebase` (not `--squash` or `--merge`) to keep linear history and preserve
|
|
91
142
|
individual commits from the session. Use `--delete-branch` to clean up the remote branch.
|
|
92
143
|
|
|
93
|
-
|
|
144
|
+
If `gh pr merge` fails with "No commits between main and xt/<branch>", the branch's
|
|
145
|
+
commits were already absorbed into main (e.g. from a previous push). Close the PR
|
|
146
|
+
and continue to the next.
|
|
147
|
+
|
|
148
|
+
After merge, fetch and confirm main advanced:
|
|
94
149
|
```bash
|
|
95
150
|
git fetch origin
|
|
96
151
|
git log origin/main --oneline -3
|
|
97
152
|
```
|
|
98
153
|
|
|
154
|
+
Record the new HEAD SHA of main — you will verify the cascade rebases onto it.
|
|
155
|
+
|
|
99
156
|
---
|
|
100
157
|
|
|
101
158
|
## Stage 4 — Rebase cascade (all remaining PRs)
|
|
@@ -106,10 +163,24 @@ For every remaining PR in the queue, rebase its branch onto the new main:
|
|
|
106
163
|
git fetch origin main
|
|
107
164
|
git checkout xt/<branch>
|
|
108
165
|
git rebase origin/main
|
|
109
|
-
git push origin xt/<branch> --force-with-lease
|
|
166
|
+
git push origin xt/<branch> --force-with-lease --force-if-includes
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
`--force-with-lease` rejects the push if the remote has commits your local ref
|
|
170
|
+
doesn't know about. `--force-if-includes` additionally verifies that whatever
|
|
171
|
+
you're overwriting was reachable from your local history — together they prevent
|
|
172
|
+
accidentally overwriting a collaborator's push that arrived after your last fetch.
|
|
173
|
+
(Requires Git 2.30+. If not available, `--force-with-lease` alone is acceptable.)
|
|
174
|
+
|
|
175
|
+
**After each push, verify it landed:**
|
|
176
|
+
```bash
|
|
177
|
+
git rev-parse HEAD
|
|
178
|
+
git rev-parse origin/xt/<branch>
|
|
110
179
|
```
|
|
180
|
+
Both SHAs must match. If the push was rejected (lease violation or other error),
|
|
181
|
+
stop and report — do not silently continue to the next branch.
|
|
111
182
|
|
|
112
|
-
Repeat for each remaining branch
|
|
183
|
+
Repeat for each remaining branch in queue order (oldest next).
|
|
113
184
|
|
|
114
185
|
After pushing, GitHub will re-trigger CI on each rebased PR. You don't need to wait
|
|
115
186
|
for CI here — the rebase just gets the branches current. CI will run in parallel.
|
|
@@ -123,27 +194,43 @@ git add <resolved-files>
|
|
|
123
194
|
git rebase --continue
|
|
124
195
|
```
|
|
125
196
|
|
|
197
|
+
If you cannot safely resolve a conflict, **abort the rebase immediately**:
|
|
198
|
+
```bash
|
|
199
|
+
git rebase --abort
|
|
200
|
+
```
|
|
201
|
+
The branch is left unchanged. Report the branch name and conflicted files to the
|
|
202
|
+
user. Continue the cascade for remaining branches; the user can resolve and push
|
|
203
|
+
this one manually before you loop back to merge it.
|
|
204
|
+
|
|
126
205
|
Conflicts mean two sessions touched the same file. Resolve carefully:
|
|
127
206
|
- Keep both changes if they're in different parts of the file
|
|
128
207
|
- If they overlap, understand what each session was doing and merge the intent
|
|
129
|
-
- When unsure,
|
|
208
|
+
- When unsure, abort and escalate to the user
|
|
130
209
|
|
|
131
|
-
After resolving, push with `--force-with-lease` and
|
|
210
|
+
After resolving, push with `--force-with-lease --force-if-includes` and verify the
|
|
211
|
+
push landed (SHA check above) before moving to the next branch.
|
|
132
212
|
|
|
133
213
|
---
|
|
134
214
|
|
|
135
215
|
## Stage 5 — Repeat
|
|
136
216
|
|
|
137
|
-
Go back to Stage 2 with the new head of the queue. Check CI
|
|
217
|
+
Go back to Stage 2 with the new head of the queue. Check CI on the **new SHA**
|
|
218
|
+
produced by the rebase cascade push — not a pre-rebase result. Merge, cascade,
|
|
138
219
|
repeat until the queue is empty.
|
|
139
220
|
|
|
140
221
|
The full loop:
|
|
141
222
|
```
|
|
142
223
|
while queue not empty:
|
|
143
|
-
|
|
224
|
+
check CI on head PR
|
|
225
|
+
→ verify: gh pr view <n> headRefOid == SHA in gh pr checks output
|
|
226
|
+
→ wait for green; stop if failing
|
|
144
227
|
merge head PR (--rebase --delete-branch)
|
|
145
|
-
|
|
146
|
-
|
|
228
|
+
git fetch origin → confirm main advanced
|
|
229
|
+
for each remaining branch in queue order:
|
|
230
|
+
git checkout xt/<branch>
|
|
231
|
+
git rebase origin/main
|
|
232
|
+
git push --force-with-lease --force-if-includes
|
|
233
|
+
verify: git rev-parse HEAD == git rev-parse origin/xt/<branch>
|
|
147
234
|
```
|
|
148
235
|
|
|
149
236
|
---
|
|
@@ -151,7 +238,11 @@ while queue not empty:
|
|
|
151
238
|
## Stage 6 — Done
|
|
152
239
|
|
|
153
240
|
When the queue is empty:
|
|
241
|
+
|
|
154
242
|
```bash
|
|
243
|
+
# If you stashed changes in Stage 0, pop now:
|
|
244
|
+
git stash pop # report any conflicts — do not discard silently
|
|
245
|
+
|
|
155
246
|
gh pr list --state open
|
|
156
247
|
git log origin/main --oneline -5
|
|
157
248
|
```
|
|
@@ -164,7 +255,10 @@ Confirm no open xt/ PRs remain and show the user the final state of main.
|
|
|
164
255
|
|
|
165
256
|
**PR was already merged**: `gh pr merge` will error. Skip it and continue.
|
|
166
257
|
|
|
167
|
-
**
|
|
258
|
+
**No commits between main and xt/branch**: branch was already absorbed into main.
|
|
259
|
+
Close the PR and continue.
|
|
260
|
+
|
|
261
|
+
**Branch was deleted** (worktree cleaned up by `xt end`): The remote branch
|
|
168
262
|
still exists (pushed by `xt end`). The local branch may not. Check out from remote:
|
|
169
263
|
```bash
|
|
170
264
|
git fetch origin
|
|
@@ -178,13 +272,42 @@ git commit --allow-empty -m "trigger CI"
|
|
|
178
272
|
git push origin xt/<branch>
|
|
179
273
|
```
|
|
180
274
|
|
|
275
|
+
**Stale CI result after rebase**: Always confirm the SHA in `gh pr checks` matches
|
|
276
|
+
`git rev-parse origin/xt/<branch>` before treating a green result as valid. If they
|
|
277
|
+
differ, wait for the new run.
|
|
278
|
+
|
|
279
|
+
**Push rejected (lease violation)**: Do not retry blindly. Fetch and inspect:
|
|
280
|
+
```bash
|
|
281
|
+
git fetch origin xt/<branch>
|
|
282
|
+
git log origin/xt/<branch> --oneline -5
|
|
283
|
+
```
|
|
284
|
+
Decide whether the remote commits should be incorporated or overwritten, then act
|
|
285
|
+
deliberately.
|
|
286
|
+
|
|
287
|
+
**`gh auth` expired mid-run**: Stop the cascade immediately. Report which branches
|
|
288
|
+
were successfully rebased/pushed and which were not, so the user can resume from the
|
|
289
|
+
right point after re-authenticating.
|
|
290
|
+
|
|
291
|
+
**Uncommitted changes on current branch**: Stash before the cascade, pop after:
|
|
292
|
+
```bash
|
|
293
|
+
git stash push -m "xt-merge cascade stash"
|
|
294
|
+
# ... run cascade ...
|
|
295
|
+
git stash pop
|
|
296
|
+
```
|
|
297
|
+
If `git stash pop` produces conflicts, report them — do not silently discard work.
|
|
298
|
+
|
|
181
299
|
**Dependent sessions** (B was intentionally built on A's work): If session B was
|
|
182
300
|
started from inside session A's worktree rather than from main, B's branch already
|
|
183
|
-
contains A's commits.
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
301
|
+
contains A's commits. B will rebase cleanly onto main after A merges — the rebase
|
|
302
|
+
eliminates the duplicate commits. No special handling needed.
|
|
303
|
+
|
|
304
|
+
**Multiple conflicts across many PRs**: Abort each failing rebase (`git rebase --abort`)
|
|
305
|
+
and tackle them one at a time in queue order after the user resolves. Push each
|
|
306
|
+
resolved branch immediately so CI starts running in parallel.
|
|
307
|
+
|
|
308
|
+
**Rollback / abort mid-cascade**: If anything goes wrong and you need to stop cleanly:
|
|
309
|
+
1. `git rebase --abort` if a rebase is in progress
|
|
310
|
+
2. `git checkout <original-branch>` to return to where you started
|
|
311
|
+
3. `git stash pop` if you stashed in Stage 0
|
|
312
|
+
4. Report exactly which PRs were merged, which were rebased-and-pushed, and which
|
|
313
|
+
were untouched — so the user can resume or restart from the correct point.
|