sequant 2.2.0 → 2.3.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/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +73 -0
- package/dist/bin/cli.js +94 -9
- package/dist/src/commands/doctor.d.ts +25 -0
- package/dist/src/commands/doctor.js +36 -1
- package/dist/src/commands/locks.d.ts +67 -0
- package/dist/src/commands/locks.js +290 -0
- package/dist/src/commands/merge.js +11 -0
- package/dist/src/commands/prompt.d.ts +39 -0
- package/dist/src/commands/prompt.js +179 -0
- package/dist/src/commands/run-display.d.ts +11 -2
- package/dist/src/commands/run-display.js +62 -28
- package/dist/src/commands/run-progress.d.ts +32 -0
- package/dist/src/commands/run-progress.js +76 -0
- package/dist/src/commands/run.js +80 -18
- package/dist/src/commands/stats.d.ts +2 -0
- package/dist/src/commands/stats.js +94 -8
- package/dist/src/commands/status.js +12 -0
- package/dist/src/commands/watch.d.ts +16 -0
- package/dist/src/commands/watch.js +147 -0
- package/dist/src/lib/ac-linter.d.ts +1 -1
- package/dist/src/lib/ac-linter.js +81 -0
- package/dist/src/lib/assess-collision-detect.d.ts +91 -0
- package/dist/src/lib/assess-collision-detect.js +217 -0
- package/dist/src/lib/assess-comment-parser.d.ts +59 -1
- package/dist/src/lib/assess-comment-parser.js +124 -2
- package/dist/src/lib/cli-ui/format.d.ts +19 -0
- package/dist/src/lib/cli-ui/format.js +34 -0
- package/dist/src/lib/cli-ui/run-renderer-types.d.ts +181 -0
- package/dist/src/lib/cli-ui/run-renderer-types.js +7 -0
- package/dist/src/lib/cli-ui/run-renderer.d.ts +239 -0
- package/dist/src/lib/cli-ui/run-renderer.js +1173 -0
- package/dist/src/lib/heuristics/behavior-rule-detector.d.ts +94 -0
- package/dist/src/lib/heuristics/behavior-rule-detector.js +467 -0
- package/dist/src/lib/locks/index.d.ts +7 -0
- package/dist/src/lib/locks/index.js +5 -0
- package/dist/src/lib/locks/lock-manager.d.ts +168 -0
- package/dist/src/lib/locks/lock-manager.js +433 -0
- package/dist/src/lib/locks/types.d.ts +59 -0
- package/dist/src/lib/locks/types.js +31 -0
- package/dist/src/lib/qa/markdown-only-ci.d.ts +46 -0
- package/dist/src/lib/qa/markdown-only-ci.js +74 -0
- package/dist/src/lib/relay/activation.d.ts +60 -0
- package/dist/src/lib/relay/activation.js +122 -0
- package/dist/src/lib/relay/archive.d.ts +34 -0
- package/dist/src/lib/relay/archive.js +106 -0
- package/dist/src/lib/relay/frame.d.ts +20 -0
- package/dist/src/lib/relay/frame.js +76 -0
- package/dist/src/lib/relay/index.d.ts +13 -0
- package/dist/src/lib/relay/index.js +13 -0
- package/dist/src/lib/relay/paths.d.ts +43 -0
- package/dist/src/lib/relay/paths.js +59 -0
- package/dist/src/lib/relay/pid.d.ts +34 -0
- package/dist/src/lib/relay/pid.js +72 -0
- package/dist/src/lib/relay/reader.d.ts +35 -0
- package/dist/src/lib/relay/reader.js +115 -0
- package/dist/src/lib/relay/types.d.ts +68 -0
- package/dist/src/lib/relay/types.js +76 -0
- package/dist/src/lib/relay/writer.d.ts +48 -0
- package/dist/src/lib/relay/writer.js +113 -0
- package/dist/src/lib/settings.d.ts +31 -1
- package/dist/src/lib/settings.js +18 -3
- package/dist/src/lib/version-check.d.ts +60 -5
- package/dist/src/lib/version-check.js +97 -9
- package/dist/src/lib/workflow/batch-executor.d.ts +20 -1
- package/dist/src/lib/workflow/batch-executor.js +248 -175
- package/dist/src/lib/workflow/config-resolver.js +4 -0
- package/dist/src/lib/workflow/heartbeat.d.ts +71 -0
- package/dist/src/lib/workflow/heartbeat.js +194 -0
- package/dist/src/lib/workflow/phase-executor.d.ts +62 -8
- package/dist/src/lib/workflow/phase-executor.js +157 -16
- package/dist/src/lib/workflow/phase-mapper.d.ts +3 -2
- package/dist/src/lib/workflow/phase-mapper.js +17 -20
- package/dist/src/lib/workflow/platforms/github.d.ts +1 -1
- package/dist/src/lib/workflow/platforms/github.js +20 -3
- package/dist/src/lib/workflow/pr-status.d.ts +18 -2
- package/dist/src/lib/workflow/pr-status.js +41 -9
- package/dist/src/lib/workflow/qa-stagnation.d.ts +117 -0
- package/dist/src/lib/workflow/qa-stagnation.js +179 -0
- package/dist/src/lib/workflow/run-orchestrator.d.ts +39 -0
- package/dist/src/lib/workflow/run-orchestrator.js +340 -15
- package/dist/src/lib/workflow/run-reflect.js +1 -1
- package/dist/src/lib/workflow/run-state.d.ts +71 -0
- package/dist/src/lib/workflow/run-state.js +14 -0
- package/dist/src/lib/workflow/state-cleanup.d.ts +13 -5
- package/dist/src/lib/workflow/state-cleanup.js +17 -5
- package/dist/src/lib/workflow/state-manager.d.ts +12 -1
- package/dist/src/lib/workflow/state-manager.js +37 -0
- package/dist/src/lib/workflow/state-schema.d.ts +62 -0
- package/dist/src/lib/workflow/state-schema.js +35 -1
- package/dist/src/lib/workflow/types.d.ts +74 -1
- package/dist/src/lib/workflow/worktree-manager.d.ts +8 -1
- package/dist/src/lib/workflow/worktree-manager.js +15 -6
- package/dist/src/mcp/tools/run.d.ts +44 -0
- package/dist/src/mcp/tools/run.js +104 -13
- package/dist/src/ui/tui/App.d.ts +14 -0
- package/dist/src/ui/tui/App.js +41 -0
- package/dist/src/ui/tui/ElapsedTimer.d.ts +10 -0
- package/dist/src/ui/tui/ElapsedTimer.js +31 -0
- package/dist/src/ui/tui/Header.d.ts +6 -0
- package/dist/src/ui/tui/Header.js +15 -0
- package/dist/src/ui/tui/IssueBox.d.ts +16 -0
- package/dist/src/ui/tui/IssueBox.js +68 -0
- package/dist/src/ui/tui/Spinner.d.ts +9 -0
- package/dist/src/ui/tui/Spinner.js +18 -0
- package/dist/src/ui/tui/index.d.ts +15 -0
- package/dist/src/ui/tui/index.js +29 -0
- package/dist/src/ui/tui/theme.d.ts +29 -0
- package/dist/src/ui/tui/theme.js +52 -0
- package/dist/src/ui/tui/truncate.d.ts +11 -0
- package/dist/src/ui/tui/truncate.js +31 -0
- package/package.json +10 -3
- package/templates/agents/sequant-explorer.md +1 -0
- package/templates/agents/sequant-qa-checker.md +2 -1
- package/templates/agents/sequant-testgen.md +1 -0
- package/templates/hooks/post-tool.sh +11 -0
- package/templates/hooks/pre-tool.sh +18 -9
- package/templates/hooks/relay-check.sh +107 -0
- package/templates/relay/frame.txt +11 -0
- package/templates/scripts/cleanup-worktree.sh +25 -3
- package/templates/scripts/new-feature.sh +6 -0
- package/templates/skills/_shared/references/behavior-rule-detection.md +205 -0
- package/templates/skills/_shared/references/subagent-types.md +21 -8
- package/templates/skills/assess/SKILL.md +103 -49
- package/templates/skills/assess/references/predicted-collision-detection.md +109 -0
- package/templates/skills/docs/SKILL.md +141 -22
- package/templates/skills/exec/SKILL.md +10 -8
- package/templates/skills/fullsolve/SKILL.md +79 -5
- package/templates/skills/loop/SKILL.md +28 -0
- package/templates/skills/merger/SKILL.md +621 -0
- package/templates/skills/qa/SKILL.md +727 -8
- package/templates/skills/setup/SKILL.md +6 -0
- package/templates/skills/spec/SKILL.md +52 -0
- package/templates/skills/spec/references/parallel-groups.md +7 -0
- package/templates/skills/spec/references/recommended-workflow.md +4 -2
- package/templates/skills/testgen/SKILL.md +24 -17
|
@@ -0,0 +1,621 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: merger
|
|
3
|
+
description: "Multi-issue integration and merge skill - handles post-QA integration of completed worktrees"
|
|
4
|
+
license: MIT
|
|
5
|
+
metadata:
|
|
6
|
+
author: sequant
|
|
7
|
+
version: "1.0"
|
|
8
|
+
allowed-tools:
|
|
9
|
+
- Bash(git:*)
|
|
10
|
+
- Bash(gh pr:*)
|
|
11
|
+
- Bash(gh issue:*)
|
|
12
|
+
- Bash(npm test:*)
|
|
13
|
+
- Bash(npm run build:*)
|
|
14
|
+
- Read
|
|
15
|
+
- Grep
|
|
16
|
+
- Glob
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Merger Skill
|
|
20
|
+
|
|
21
|
+
You are the "Merger Agent" for handling post-QA integration of completed worktrees.
|
|
22
|
+
|
|
23
|
+
## Purpose
|
|
24
|
+
|
|
25
|
+
When invoked as `/merger <issue-numbers>`, you:
|
|
26
|
+
1. Capture baseline metrics on main (build errors, test counts)
|
|
27
|
+
2. Validate QA status for all specified issues
|
|
28
|
+
3. Detect file conflicts between worktrees
|
|
29
|
+
4. Generate integration branches for incompatible changes
|
|
30
|
+
5. Respect dependency ordering
|
|
31
|
+
6. Clean up worktrees after successful merge
|
|
32
|
+
7. Run post-merge smoketest with regression comparison against baseline
|
|
33
|
+
8. Provide detailed merge reports
|
|
34
|
+
|
|
35
|
+
### Recommended Pre-Merge Check
|
|
36
|
+
|
|
37
|
+
Before running `/merger`, use `sequant merge --check` to catch cross-issue gaps at zero AI cost:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
sequant run 10 11 12 # implement
|
|
41
|
+
sequant merge --check # verify (deterministic checks)
|
|
42
|
+
/merger 10 11 12 # merge (this command)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`sequant merge` detects merge conflicts, template mirroring gaps, file overlaps, and residual patterns before `/merger` attempts the actual merge. See `docs/reference/merge-command.md` for details.
|
|
46
|
+
|
|
47
|
+
## Usage
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Merge single issue
|
|
51
|
+
/merger 10
|
|
52
|
+
|
|
53
|
+
# Merge multiple issues (detects conflicts, creates integration if needed)
|
|
54
|
+
/merger 10 12
|
|
55
|
+
|
|
56
|
+
# Merge with dependency ordering
|
|
57
|
+
/merger 10 12 --order=dependency
|
|
58
|
+
|
|
59
|
+
# Dry run - show what would happen
|
|
60
|
+
/merger 10 12 --dry-run
|
|
61
|
+
|
|
62
|
+
# Force parallel validation of multiple issues (faster, higher token usage)
|
|
63
|
+
/merger 10 12 --parallel
|
|
64
|
+
|
|
65
|
+
# Force sequential validation (slower, lower token usage)
|
|
66
|
+
/merger 10 12 --sequential
|
|
67
|
+
|
|
68
|
+
# Skip post-merge smoketest
|
|
69
|
+
/merger 10 12 --skip-smoketest
|
|
70
|
+
|
|
71
|
+
# Force merge even if regression is detected (bypasses regression gate)
|
|
72
|
+
/merger 10 12 --force
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Agent Execution Mode
|
|
76
|
+
|
|
77
|
+
When processing multiple issues, determine the execution mode for validation checks:
|
|
78
|
+
|
|
79
|
+
1. **Check for CLI flag override:**
|
|
80
|
+
- `--parallel` → Validate all issues in parallel (spawn agents simultaneously)
|
|
81
|
+
- `--sequential` → Validate issues one at a time
|
|
82
|
+
|
|
83
|
+
2. **If no flag, read project settings:**
|
|
84
|
+
Use the Read tool to check project settings:
|
|
85
|
+
```
|
|
86
|
+
Read(file_path=".sequant/settings.json")
|
|
87
|
+
# Parse JSON and extract agents.parallel (default: false)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
3. **Default:** Sequential (cost-optimized)
|
|
91
|
+
|
|
92
|
+
| Mode | Token Usage | Speed | Best For |
|
|
93
|
+
|------|-------------|-------|----------|
|
|
94
|
+
| Sequential | 1x (baseline) | Slower | Limited API plans, 1-2 issues |
|
|
95
|
+
| Parallel | ~Nx (N=issues) | ~50% faster | Unlimited plans, batch merges |
|
|
96
|
+
|
|
97
|
+
## Workflow
|
|
98
|
+
|
|
99
|
+
### Step 0: Baseline Capture (REQUIRED)
|
|
100
|
+
|
|
101
|
+
**Purpose:** Capture build error count and test pass/fail counts on main **before** any merge, so post-merge results can be compared to detect regressions.
|
|
102
|
+
|
|
103
|
+
**Skip if:** `--skip-smoketest` flag is set (no comparison needed if smoketest is skipped).
|
|
104
|
+
|
|
105
|
+
**Session caching:** If baseline has already been captured in this `/merger` invocation (e.g., when merging multiple issues), reuse the cached values instead of re-running build and tests.
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# Check if baseline is already cached (multi-issue merge scenario)
|
|
109
|
+
if [[ -n "$BASELINE_BUILD_ERRORS" && -n "$BASELINE_TEST_FAILURES" ]]; then
|
|
110
|
+
echo "♻️ Using cached baseline metrics (captured earlier in this session)"
|
|
111
|
+
echo " Build errors: $BASELINE_BUILD_ERRORS"
|
|
112
|
+
echo " Test failures: $BASELINE_TEST_FAILURES"
|
|
113
|
+
echo " Test passes: $BASELINE_TEST_PASSES"
|
|
114
|
+
else
|
|
115
|
+
echo "📊 Capturing baseline metrics on main..."
|
|
116
|
+
|
|
117
|
+
# Ensure we're on main with latest changes
|
|
118
|
+
git checkout main
|
|
119
|
+
git pull origin main
|
|
120
|
+
|
|
121
|
+
# 1. Capture build error count
|
|
122
|
+
build_output=$(npm run build 2>&1 || true)
|
|
123
|
+
BASELINE_BUILD_ERRORS=$(echo "$build_output" | grep -c "error TS" || true)
|
|
124
|
+
echo " Baseline build errors: $BASELINE_BUILD_ERRORS"
|
|
125
|
+
|
|
126
|
+
# 2. Capture test pass/fail counts
|
|
127
|
+
test_output=$(npm test 2>&1 || true)
|
|
128
|
+
|
|
129
|
+
# Parse vitest output format: "Tests X passed | Y failed" or "Tests X passed"
|
|
130
|
+
# Use tail -1 to get the Tests line (not Test Files line) from vitest output
|
|
131
|
+
BASELINE_TEST_PASSES=$(echo "$test_output" | grep -oE '[0-9]+ passed' | tail -1 | grep -oE '[0-9]+' || echo "0")
|
|
132
|
+
BASELINE_TEST_FAILURES=$(echo "$test_output" | grep -oE '[0-9]+ failed' | tail -1 | grep -oE '[0-9]+' || echo "0")
|
|
133
|
+
echo " Baseline test passes: $BASELINE_TEST_PASSES"
|
|
134
|
+
echo " Baseline test failures: $BASELINE_TEST_FAILURES"
|
|
135
|
+
|
|
136
|
+
echo "✅ Baseline captured"
|
|
137
|
+
fi
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Output format (include in merge report):**
|
|
141
|
+
|
|
142
|
+
```markdown
|
|
143
|
+
### Baseline Metrics (main before merge)
|
|
144
|
+
|
|
145
|
+
| Metric | Count |
|
|
146
|
+
|--------|-------|
|
|
147
|
+
| Build errors (TS) | $BASELINE_BUILD_ERRORS |
|
|
148
|
+
| Test passes | $BASELINE_TEST_PASSES |
|
|
149
|
+
| Test failures | $BASELINE_TEST_FAILURES |
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Step 1: Pre-Merge Validation
|
|
153
|
+
|
|
154
|
+
For each issue specified:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# Find the worktree for the issue
|
|
158
|
+
git worktree list --porcelain | grep -A2 "feature/$ISSUE" || true
|
|
159
|
+
|
|
160
|
+
# Check PR status
|
|
161
|
+
gh pr list --head "feature/$ISSUE-*" --json number,state,title
|
|
162
|
+
|
|
163
|
+
# Verify worktree exists and has commits
|
|
164
|
+
git -C <worktree-path> log --oneline main..HEAD
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Validation checklist:
|
|
168
|
+
- [ ] Worktree exists for the issue
|
|
169
|
+
- [ ] PR exists (or will be created)
|
|
170
|
+
- [ ] Changes have been committed
|
|
171
|
+
- [ ] No uncommitted work
|
|
172
|
+
|
|
173
|
+
### Step 2: Conflict Detection
|
|
174
|
+
|
|
175
|
+
Get files changed in each worktree:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
# For each worktree
|
|
179
|
+
git -C <worktree-path> diff --name-only main...HEAD
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Find overlapping files:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
# Compare file lists between worktrees
|
|
186
|
+
comm -12 <(sort files_issue1.txt) <(sort files_issue2.txt)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Step 3: Conflict Analysis
|
|
190
|
+
|
|
191
|
+
If overlapping files found:
|
|
192
|
+
|
|
193
|
+
1. **Semantic analysis**: Are the changes compatible?
|
|
194
|
+
- Additive changes (new functions) -> likely compatible
|
|
195
|
+
- Same function modified -> likely incompatible
|
|
196
|
+
- Same file, different sections -> may be compatible
|
|
197
|
+
|
|
198
|
+
2. **Generate merge preview**:
|
|
199
|
+
```bash
|
|
200
|
+
git merge-tree $(git merge-base main branch1) branch1 branch2
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Step 4: Resolution Strategy
|
|
204
|
+
|
|
205
|
+
| Scenario | Action |
|
|
206
|
+
|----------|--------|
|
|
207
|
+
| No conflicts | Merge sequentially |
|
|
208
|
+
| Compatible changes | Auto-merge with verification |
|
|
209
|
+
| Incompatible changes | Generate unified implementation in integration branch |
|
|
210
|
+
| True dependency | Enforce merge order |
|
|
211
|
+
|
|
212
|
+
### Step 5: Merge Execution
|
|
213
|
+
|
|
214
|
+
#### For clean merges (no conflicts):
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
# Merge PR first (without --delete-branch to avoid worktree lock conflicts)
|
|
218
|
+
gh pr merge <PR_NUMBER> --squash
|
|
219
|
+
|
|
220
|
+
# Only clean up worktree AFTER merge succeeds
|
|
221
|
+
# If merge fails, the worktree is preserved so work isn't lost
|
|
222
|
+
worktree_path=$(git worktree list | grep "feature/$ISSUE" | awk '{print $1}' || true)
|
|
223
|
+
if [[ -n "$worktree_path" ]]; then
|
|
224
|
+
git worktree remove "$worktree_path" --force
|
|
225
|
+
git branch -D "feature/$ISSUE-"* 2>/dev/null || true
|
|
226
|
+
fi
|
|
227
|
+
|
|
228
|
+
# Delete remote branch (previously handled by --delete-branch)
|
|
229
|
+
gh api repos/{owner}/{repo}/git/refs/heads/$(gh pr view <PR_NUMBER> --json headRefName --jq '.headRefName') -X DELETE 2>/dev/null || true
|
|
230
|
+
|
|
231
|
+
# State is tracked by the orchestrator runtime when available
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
#### For conflicting changes (integration branch):
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
# Create integration branch
|
|
238
|
+
git checkout -b integrate/<issue1>-<issue2>-<description> main
|
|
239
|
+
|
|
240
|
+
# Cherry-pick or merge each worktree's changes
|
|
241
|
+
git merge feature/<issue1>-* --no-commit
|
|
242
|
+
# Resolve conflicts...
|
|
243
|
+
git add .
|
|
244
|
+
git commit -m "feat: Integrate #<issue1> changes"
|
|
245
|
+
|
|
246
|
+
git merge feature/<issue2>-* --no-commit
|
|
247
|
+
# Resolve conflicts...
|
|
248
|
+
git add .
|
|
249
|
+
git commit -m "feat: Integrate #<issue2> changes"
|
|
250
|
+
|
|
251
|
+
# Run tests on integration branch
|
|
252
|
+
npm test
|
|
253
|
+
npm run build
|
|
254
|
+
|
|
255
|
+
# Create integration PR
|
|
256
|
+
gh pr create --title "feat: Integrate #<issue1> and #<issue2>" --body "..."
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Step 6: Post-Merge Verification
|
|
260
|
+
|
|
261
|
+
After successful merge:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
# Pull merged changes to main
|
|
265
|
+
git checkout main
|
|
266
|
+
git pull origin main
|
|
267
|
+
|
|
268
|
+
# Verify worktree was cleaned up
|
|
269
|
+
git worktree list # Should not show the merged feature branch
|
|
270
|
+
|
|
271
|
+
# Remote branch is deleted explicitly after merge (see Step 5)
|
|
272
|
+
|
|
273
|
+
# REQUIRED: Verify state was updated (#305)
|
|
274
|
+
# The state should show status="merged" for the issue
|
|
275
|
+
# Use the Read tool to check state, then parse JSON
|
|
276
|
+
Read(file_path=".sequant/state.json")
|
|
277
|
+
# Verify the issue status shows "merged"
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Step 6a: Worktree Cleanup After Merge (REQUIRED - #305)
|
|
281
|
+
|
|
282
|
+
**After each successful merge, ensure the worktree is removed:**
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
# Find and remove worktree for the issue
|
|
286
|
+
worktree_path=$(git worktree list | grep "feature/$ISSUE" | awk '{print $1}' || true)
|
|
287
|
+
if [[ -n "$worktree_path" ]]; then
|
|
288
|
+
echo "Removing worktree: $worktree_path"
|
|
289
|
+
git worktree remove "$worktree_path" --force
|
|
290
|
+
else
|
|
291
|
+
echo "No worktree found for #$ISSUE (already cleaned up)"
|
|
292
|
+
fi
|
|
293
|
+
|
|
294
|
+
# Verify worktree removal
|
|
295
|
+
git worktree list | grep -q "feature/$ISSUE" && echo "WARNING: Worktree still exists" || echo "✅ Worktree removed"
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**Why this matters:** Leftover worktrees waste disk space and can cause confusion when re-running `sequant run` on the same issues. The state guard (#305) prevents re-execution, but the worktree should still be cleaned up.
|
|
299
|
+
|
|
300
|
+
### Step 7: Post-Merge Smoketest with Regression Comparison
|
|
301
|
+
|
|
302
|
+
**Skip if:** `--skip-smoketest` flag is set or `SEQUANT_MERGER_SKIP_SMOKETEST` environment variable is true.
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
# Check skip flag
|
|
306
|
+
if [[ "$SKIP_SMOKETEST" == "true" ]]; then
|
|
307
|
+
echo "⏭️ Smoketest skipped (--skip-smoketest flag set)"
|
|
308
|
+
# Continue to output report
|
|
309
|
+
fi
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
**After all merges complete and worktrees are cleaned up**, verify main is healthy and compare against baseline:
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
# 1. Ensure we're on main with latest changes
|
|
316
|
+
git checkout main
|
|
317
|
+
git pull origin main
|
|
318
|
+
|
|
319
|
+
# 2. Build verification — capture post-merge error count
|
|
320
|
+
echo "Running build..."
|
|
321
|
+
post_build_output=$(npm run build 2>&1); build_exit=$?
|
|
322
|
+
POST_BUILD_ERRORS=$(echo "$post_build_output" | grep -c "error TS" || true)
|
|
323
|
+
|
|
324
|
+
# 3. Test suite — capture post-merge test counts
|
|
325
|
+
echo "Running tests..."
|
|
326
|
+
post_test_output=$(npm test 2>&1); test_exit=$?
|
|
327
|
+
POST_TEST_PASSES=$(echo "$post_test_output" | grep -oE '[0-9]+ passed' | tail -1 | grep -oE '[0-9]+' || echo "0")
|
|
328
|
+
POST_TEST_FAILURES=$(echo "$post_test_output" | grep -oE '[0-9]+ failed' | tail -1 | grep -oE '[0-9]+' || echo "0")
|
|
329
|
+
|
|
330
|
+
# 4. CLI health check (if sequant CLI is available)
|
|
331
|
+
echo "Running CLI health check..."
|
|
332
|
+
npx sequant doctor 2>&1 || true
|
|
333
|
+
doctor_exit=$?
|
|
334
|
+
|
|
335
|
+
# 5. Regression comparison against baseline
|
|
336
|
+
REGRESSION_DETECTED=false
|
|
337
|
+
|
|
338
|
+
BUILD_DELTA=$((POST_BUILD_ERRORS - BASELINE_BUILD_ERRORS))
|
|
339
|
+
TEST_FAIL_DELTA=$((POST_TEST_FAILURES - BASELINE_TEST_FAILURES))
|
|
340
|
+
TEST_PASS_DELTA=$((POST_TEST_PASSES - BASELINE_TEST_PASSES))
|
|
341
|
+
|
|
342
|
+
if [[ $BUILD_DELTA -gt 0 ]]; then
|
|
343
|
+
echo "❌ REGRESSION: $BUILD_DELTA new build error(s) introduced"
|
|
344
|
+
REGRESSION_DETECTED=true
|
|
345
|
+
fi
|
|
346
|
+
|
|
347
|
+
if [[ $TEST_FAIL_DELTA -gt 0 ]]; then
|
|
348
|
+
echo "❌ REGRESSION: $TEST_FAIL_DELTA new test failure(s) introduced"
|
|
349
|
+
REGRESSION_DETECTED=true
|
|
350
|
+
fi
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
#### Smoketest & Regression Output
|
|
354
|
+
|
|
355
|
+
Report results including regression comparison:
|
|
356
|
+
|
|
357
|
+
```markdown
|
|
358
|
+
### Post-Merge Smoketest
|
|
359
|
+
|
|
360
|
+
| Check | Command | Result | Details |
|
|
361
|
+
|-------|---------|--------|---------|
|
|
362
|
+
| Build | `npm run build` | ✅ PASS / ❌ FAIL | [build output summary] |
|
|
363
|
+
| Tests | `npm test` | ✅ PASS (N/N) / ❌ FAIL | [test count or failure summary] |
|
|
364
|
+
| CLI Health | `npx sequant doctor` | ✅ PASS / ❌ FAIL / ⏭️ SKIP | [health check output] |
|
|
365
|
+
|
|
366
|
+
### Regression Check
|
|
367
|
+
|
|
368
|
+
| Metric | Baseline (main) | Post-merge | Delta | Status |
|
|
369
|
+
|--------|----------------|------------|-------|--------|
|
|
370
|
+
| Build errors | $BASELINE_BUILD_ERRORS | $POST_BUILD_ERRORS | +$BUILD_DELTA / 0 | ✅ No regression / ❌ REGRESSION |
|
|
371
|
+
| Test failures | $BASELINE_TEST_FAILURES | $POST_TEST_FAILURES | +$TEST_FAIL_DELTA / 0 | ✅ No regression / ❌ REGRESSION |
|
|
372
|
+
| Test passes | $BASELINE_TEST_PASSES | $POST_TEST_PASSES | +$TEST_PASS_DELTA | ✅ Tests added / ⚠️ Tests removed |
|
|
373
|
+
|
|
374
|
+
**Regression Result:** ✅ NO REGRESSIONS / ❌ REGRESSIONS DETECTED
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
#### Regression Gate
|
|
378
|
+
|
|
379
|
+
**If regressions are detected:**
|
|
380
|
+
|
|
381
|
+
```bash
|
|
382
|
+
if [[ "$REGRESSION_DETECTED" == "true" ]]; then
|
|
383
|
+
if [[ "$FORCE_MERGE" == "true" ]]; then
|
|
384
|
+
echo "⚠️ REGRESSION DETECTED but --force flag set. Proceeding with merge."
|
|
385
|
+
echo "⚠️ Acknowledgment: Merging despite $BUILD_DELTA new build error(s) and $TEST_FAIL_DELTA new test failure(s)."
|
|
386
|
+
else
|
|
387
|
+
echo "❌ REGRESSION DETECTED — merge is blocked."
|
|
388
|
+
echo ""
|
|
389
|
+
echo "New build errors: $BUILD_DELTA"
|
|
390
|
+
echo "New test failures: $TEST_FAIL_DELTA"
|
|
391
|
+
echo ""
|
|
392
|
+
echo "To override this gate, re-run with --force:"
|
|
393
|
+
echo " /merger <issues> --force"
|
|
394
|
+
echo ""
|
|
395
|
+
echo "To investigate:"
|
|
396
|
+
echo " npm run build 2>&1 | grep 'error TS'"
|
|
397
|
+
echo " npm test -- --verbose 2>&1"
|
|
398
|
+
# Do NOT proceed — report regression and halt
|
|
399
|
+
fi
|
|
400
|
+
fi
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
**Regression gate behavior:**
|
|
404
|
+
|
|
405
|
+
| Scenario | `--force` not set | `--force` set |
|
|
406
|
+
|----------|-------------------|---------------|
|
|
407
|
+
| No regressions | ✅ Proceed | ✅ Proceed |
|
|
408
|
+
| New build errors | ❌ Block merge, report | ⚠️ Warn, proceed |
|
|
409
|
+
| New test failures | ❌ Block merge, report | ⚠️ Warn, proceed |
|
|
410
|
+
| Both | ❌ Block merge, report | ⚠️ Warn, proceed |
|
|
411
|
+
|
|
412
|
+
**Important:** The regression gate does NOT trigger automatic rollback. It blocks further action and reports for human decision-making. Use `--force` only when you've confirmed the regressions are acceptable (e.g., known flaky tests).
|
|
413
|
+
|
|
414
|
+
#### Failure Handling (Non-Regression)
|
|
415
|
+
|
|
416
|
+
If smoketest checks fail but are NOT regressions (same count as baseline), report as pre-existing:
|
|
417
|
+
|
|
418
|
+
```markdown
|
|
419
|
+
### ℹ️ Pre-existing Failures (not regressions)
|
|
420
|
+
|
|
421
|
+
| Check | Status | Notes |
|
|
422
|
+
|-------|--------|-------|
|
|
423
|
+
| Build | ⚠️ $BASELINE_BUILD_ERRORS errors | Same as baseline — pre-existing |
|
|
424
|
+
| Tests | ⚠️ $BASELINE_TEST_FAILURES failures | Same as baseline — pre-existing |
|
|
425
|
+
|
|
426
|
+
These failures existed on main before this merge. They are not caused by the merged PR(s).
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
If smoketest checks fail AND are regressions, report with diagnostic commands:
|
|
430
|
+
|
|
431
|
+
```markdown
|
|
432
|
+
### ❌ Regressions Detected
|
|
433
|
+
|
|
434
|
+
| Check | Baseline | Post-merge | New Failures |
|
|
435
|
+
|-------|----------|------------|--------------|
|
|
436
|
+
| Build errors | $BASELINE_BUILD_ERRORS | $POST_BUILD_ERRORS | +$BUILD_DELTA |
|
|
437
|
+
| Test failures | $BASELINE_TEST_FAILURES | $POST_TEST_FAILURES | +$TEST_FAIL_DELTA |
|
|
438
|
+
|
|
439
|
+
**⚠️ Action Required:**
|
|
440
|
+
- Investigate new failures introduced by this merge
|
|
441
|
+
- Consider reverting the merge if regressions are critical
|
|
442
|
+
- Use `--force` to override if regressions are acceptable
|
|
443
|
+
|
|
444
|
+
**Diagnostic commands:**
|
|
445
|
+
\`\`\`bash
|
|
446
|
+
# Investigate new build errors
|
|
447
|
+
npm run build 2>&1 | grep "error TS"
|
|
448
|
+
|
|
449
|
+
# Run failing tests with verbose output
|
|
450
|
+
npm test -- --verbose 2>&1
|
|
451
|
+
|
|
452
|
+
# Check what the merge changed
|
|
453
|
+
git log --oneline -3
|
|
454
|
+
git diff HEAD~1 --stat
|
|
455
|
+
\`\`\`
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
**Important:** Regression detection does NOT trigger automatic rollback. It reports for human decision-making.
|
|
459
|
+
|
|
460
|
+
## Dependency Detection
|
|
461
|
+
|
|
462
|
+
Parse dependencies from issue body or comments:
|
|
463
|
+
|
|
464
|
+
```markdown
|
|
465
|
+
<!-- In issue body -->
|
|
466
|
+
**Depends on**: #10
|
|
467
|
+
|
|
468
|
+
<!-- Or via label -->
|
|
469
|
+
Labels: depends-on/10
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
```bash
|
|
473
|
+
# Check issue for dependency markers
|
|
474
|
+
gh issue view <issue> --json body,labels | jq '.body, .labels[].name'
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
If dependencies found, enforce merge order.
|
|
478
|
+
|
|
479
|
+
### Stacked PR Detection (#605)
|
|
480
|
+
|
|
481
|
+
PRs created with `sequant run --stacked` have a non-`main` base and a manifest
|
|
482
|
+
line in the body (`Part of stack: #N1 → #N2 → ...`). They **must merge in
|
|
483
|
+
order** — predecessor first. Merging out of order re-bases the dependent PR's
|
|
484
|
+
diff against an unexpected commit and inflates the visible change set.
|
|
485
|
+
|
|
486
|
+
**Detect stacked PRs:**
|
|
487
|
+
|
|
488
|
+
```bash
|
|
489
|
+
# A PR with a non-main base + manifest is part of a stack
|
|
490
|
+
gh pr view <PR_NUMBER> --json baseRefName,body | \
|
|
491
|
+
jq -r 'if (.baseRefName != "main" and (.body | contains("Part of stack:"))) then "STACKED" else "STANDALONE" end'
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
**Enforce stack order before merging:**
|
|
495
|
+
|
|
496
|
+
1. Extract the stack manifest from each PR's body (`Part of stack: #100 → #101 (this) → #102`).
|
|
497
|
+
2. Treat the order in the manifest as the merge order — earlier entries land first.
|
|
498
|
+
3. If the user requests an out-of-order merge (e.g. `/merger 102 100 101` for the stack above), **warn before proceeding** and recommend the manifest order.
|
|
499
|
+
4. GitHub auto-updates the dependent PR's base when its predecessor merges, so once the order is correct no manual rebasing is needed.
|
|
500
|
+
|
|
501
|
+
**Warning template:**
|
|
502
|
+
|
|
503
|
+
```text
|
|
504
|
+
⚠️ Stack order violation detected
|
|
505
|
+
PR #102 is part of stack: #100 → #101 → #102
|
|
506
|
+
You requested merge order: #102, #100, #101
|
|
507
|
+
Recommended: merge in manifest order to preserve incremental diffs.
|
|
508
|
+
Continue anyway? (y/N)
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
## Output Format
|
|
512
|
+
|
|
513
|
+
### Merge Report
|
|
514
|
+
|
|
515
|
+
```markdown
|
|
516
|
+
## Merger Report: Issues #10, #12
|
|
517
|
+
|
|
518
|
+
### Pre-Merge Validation
|
|
519
|
+
| Issue | Worktree | PR | Status |
|
|
520
|
+
|-------|----------|-----|--------|
|
|
521
|
+
| #10 | feature/10-* | #15 | Ready |
|
|
522
|
+
| #12 | feature/12-* | #16 | Ready |
|
|
523
|
+
|
|
524
|
+
### Conflict Analysis
|
|
525
|
+
| File | #10 | #12 | Status |
|
|
526
|
+
|------|-----|-----|--------|
|
|
527
|
+
| `src/api/route.ts` | Modified | Modified | CONFLICT |
|
|
528
|
+
| `src/components/list.tsx` | - | Created | OK |
|
|
529
|
+
|
|
530
|
+
### Resolution
|
|
531
|
+
**Strategy:** Integration branch
|
|
532
|
+
**Branch:** integrate/10-12-api-merge
|
|
533
|
+
**PR:** #17
|
|
534
|
+
|
|
535
|
+
### Actions Taken
|
|
536
|
+
1. Captured baseline metrics on main
|
|
537
|
+
2. Created integration branch from main
|
|
538
|
+
3. Merged #10 changes (no conflicts)
|
|
539
|
+
4. Merged #12 changes (resolved 1 conflict in route.ts)
|
|
540
|
+
5. Tests passed (45 tests)
|
|
541
|
+
6. Build succeeded
|
|
542
|
+
|
|
543
|
+
### Cleanup
|
|
544
|
+
- Removed worktree: feature/10-*
|
|
545
|
+
- Removed worktree: feature/12-*
|
|
546
|
+
- Closed: PR #15, PR #16 (superseded by #17)
|
|
547
|
+
|
|
548
|
+
### Baseline Metrics (main before merge)
|
|
549
|
+
| Metric | Count |
|
|
550
|
+
|--------|-------|
|
|
551
|
+
| Build errors (TS) | 0 |
|
|
552
|
+
| Test passes | 42 |
|
|
553
|
+
| Test failures | 0 |
|
|
554
|
+
|
|
555
|
+
### Post-Merge Smoketest
|
|
556
|
+
| Check | Command | Result | Details |
|
|
557
|
+
|-------|---------|--------|---------|
|
|
558
|
+
| Build | `npm run build` | ✅ PASS | Compiled successfully |
|
|
559
|
+
| Tests | `npm test` | ✅ PASS (45/45) | All tests passing |
|
|
560
|
+
| CLI Health | `npx sequant doctor` | ✅ PASS | No issues detected |
|
|
561
|
+
|
|
562
|
+
### Regression Check
|
|
563
|
+
| Metric | Baseline (main) | Post-merge | Delta | Status |
|
|
564
|
+
|--------|----------------|------------|-------|--------|
|
|
565
|
+
| Build errors | 0 | 0 | 0 | ✅ No regression |
|
|
566
|
+
| Test failures | 0 | 0 | 0 | ✅ No regression |
|
|
567
|
+
| Test passes | 42 | 45 | +3 | ✅ Tests added |
|
|
568
|
+
|
|
569
|
+
**Regression Result:** ✅ NO REGRESSIONS
|
|
570
|
+
|
|
571
|
+
### Final Status
|
|
572
|
+
**Result:** SUCCESS
|
|
573
|
+
**Integration PR:** #17
|
|
574
|
+
**Issues to close on merge:** #10, #12
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
## Error Handling
|
|
578
|
+
|
|
579
|
+
**If validation fails:**
|
|
580
|
+
- Report which issues failed validation
|
|
581
|
+
- Suggest corrective actions
|
|
582
|
+
- Do not proceed with merge
|
|
583
|
+
|
|
584
|
+
**If merge conflicts cannot be resolved:**
|
|
585
|
+
- Document the conflicts
|
|
586
|
+
- Create a draft PR with conflicts marked
|
|
587
|
+
- Request manual intervention
|
|
588
|
+
|
|
589
|
+
**If tests fail on integration branch:**
|
|
590
|
+
- Document failing tests
|
|
591
|
+
- Keep integration branch for debugging
|
|
592
|
+
- Do not merge
|
|
593
|
+
|
|
594
|
+
**If worktree cleanup fails:**
|
|
595
|
+
- Log warning but continue
|
|
596
|
+
- Manual cleanup may be needed
|
|
597
|
+
|
|
598
|
+
## Configuration
|
|
599
|
+
|
|
600
|
+
Environment variables:
|
|
601
|
+
- `SEQUANT_MERGER_DRY_RUN` - If true, only show what would happen
|
|
602
|
+
- `SEQUANT_MERGER_NO_CLEANUP` - If true, keep worktrees after merge
|
|
603
|
+
- `SEQUANT_MERGER_FORCE` - If true, proceed even with conflicts or regressions (bypasses regression gate)
|
|
604
|
+
- `SEQUANT_MERGER_SKIP_SMOKETEST` - If true, skip post-merge smoketest (also skips baseline capture)
|
|
605
|
+
|
|
606
|
+
## Output Verification
|
|
607
|
+
|
|
608
|
+
**Before responding, verify your output includes ALL of these:**
|
|
609
|
+
|
|
610
|
+
- [ ] **Baseline Metrics** - Build errors, test passes/failures on main before merge (or "Skipped" if `--skip-smoketest`)
|
|
611
|
+
- [ ] **Pre-Merge Validation** - Status of each issue/worktree/PR
|
|
612
|
+
- [ ] **Conflict Analysis** - Table of overlapping files and status
|
|
613
|
+
- [ ] **Resolution Strategy** - How conflicts were resolved (if any)
|
|
614
|
+
- [ ] **Actions Taken** - Step-by-step log of what was done
|
|
615
|
+
- [ ] **Cleanup Status** - Which worktrees/branches were removed
|
|
616
|
+
- [ ] **Post-Merge Smoketest** - Build, test, and CLI health results (or "Skipped" if `--skip-smoketest`)
|
|
617
|
+
- [ ] **Regression Check** - Baseline vs post-merge comparison table (or "Skipped" if `--skip-smoketest`)
|
|
618
|
+
- [ ] **Regression Gate** - Whether regressions were detected and what action was taken
|
|
619
|
+
- [ ] **Final Status** - SUCCESS/FAILURE with PR link
|
|
620
|
+
|
|
621
|
+
**DO NOT respond until all items are verified.**
|