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.
Files changed (29) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/cli/dist/index.cjs +6218 -7897
  3. package/cli/dist/index.cjs.map +1 -1
  4. package/cli/package.json +5 -1
  5. package/config/pi/extensions/beads/index.ts +1 -1
  6. package/config/pi/extensions/beads/package.json +4 -1
  7. package/config/pi/extensions/core/package.json +18 -0
  8. package/config/pi/extensions/custom-footer/index.ts +138 -71
  9. package/config/pi/extensions/custom-footer/package.json +4 -1
  10. package/config/pi/extensions/quality-gates/index.ts +1 -1
  11. package/config/pi/extensions/quality-gates/package.json +4 -1
  12. package/config/pi/extensions/service-skills/index.ts +1 -1
  13. package/config/pi/extensions/service-skills/package.json +4 -1
  14. package/config/pi/extensions/session-flow/index.ts +1 -1
  15. package/config/pi/extensions/session-flow/package.json +4 -1
  16. package/config/pi/extensions/xtrm-loader/index.ts +1 -1
  17. package/config/pi/extensions/xtrm-loader/package.json +4 -1
  18. package/hooks/beads-compact-restore.mjs +11 -3
  19. package/hooks/beads-compact-save.mjs +13 -1
  20. package/hooks/tsconfig-cache.json +12 -2
  21. package/package.json +3 -2
  22. package/plugins/xtrm-tools/.claude-plugin/plugin.json +1 -1
  23. package/plugins/xtrm-tools/hooks/beads-compact-restore.mjs +11 -3
  24. package/plugins/xtrm-tools/hooks/beads-compact-save.mjs +13 -1
  25. package/plugins/xtrm-tools/hooks/tsconfig-cache.json +12 -2
  26. package/plugins/xtrm-tools/skills/xt-end/SKILL.md +1 -0
  27. package/plugins/xtrm-tools/skills/xt-merge/SKILL.md +141 -18
  28. package/skills/xt-end/SKILL.md +1 -0
  29. 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
- After merge, confirm main advanced:
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. Do them in queue order (oldest next).
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, call the user in to review before continuing
208
+ - When unsure, abort and escalate to the user
130
209
 
131
- After resolving, push with `--force-with-lease` and move to the next branch.
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, merge, rebase cascade,
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
- wait for CI green on head PR
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
- rebase all remaining PRs onto new main
146
- push each (--force-with-lease)
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
- **Branch was deleted** (worktree cleaned up by `xt end --keep`): The remote branch
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. In this case B will rebase cleanly onto main after A merges —
184
- its commits are a superset. No special handling needed; the rebase just eliminates
185
- the duplicate commits.
186
-
187
- **Multiple conflicts across many PRs**: If the cascade produces conflicts in several
188
- branches, tackle them one at a time in queue order. Don't try to resolve all of them
189
- before pushing any — push each one as you resolve it so CI starts running in parallel
190
- while you work on the next.
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.
@@ -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
 
@@ -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
- After merge, confirm main advanced:
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. Do them in queue order (oldest next).
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, call the user in to review before continuing
208
+ - When unsure, abort and escalate to the user
130
209
 
131
- After resolving, push with `--force-with-lease` and move to the next branch.
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, merge, rebase cascade,
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
- wait for CI green on head PR
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
- rebase all remaining PRs onto new main
146
- push each (--force-with-lease)
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
- **Branch was deleted** (worktree cleaned up by `xt end --keep`): The remote branch
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. In this case B will rebase cleanly onto main after A merges —
184
- its commits are a superset. No special handling needed; the rebase just eliminates
185
- the duplicate commits.
186
-
187
- **Multiple conflicts across many PRs**: If the cascade produces conflicts in several
188
- branches, tackle them one at a time in queue order. Don't try to resolve all of them
189
- before pushing any — push each one as you resolve it so CI starts running in parallel
190
- while you work on the next.
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.