sequant 2.9.0 â 2.11.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 +20 -5
- package/dist/bin/cli.js +143 -18
- package/dist/marketplace/external_plugins/sequant/.claude-plugin/plugin.json +1 -1
- package/dist/marketplace/external_plugins/sequant/.mcp.json +1 -1
- package/dist/marketplace/external_plugins/sequant/README.md +56 -2
- package/dist/marketplace/external_plugins/sequant/hooks/parallel-marker.sh +50 -0
- package/dist/marketplace/external_plugins/sequant/hooks/post-tool.sh +20 -7
- package/dist/marketplace/external_plugins/sequant/hooks/pre-tool.sh +75 -10
- package/dist/marketplace/external_plugins/sequant/skills/_shared/references/trust-model.md +18 -0
- package/dist/marketplace/external_plugins/sequant/skills/assess/SKILL.md +215 -390
- package/dist/marketplace/external_plugins/sequant/skills/assess/references/predicted-collision-detection.md +1 -1
- package/dist/marketplace/external_plugins/sequant/skills/docs/SKILL.md +4 -4
- package/dist/marketplace/external_plugins/sequant/skills/exec/SKILL.md +26 -6
- package/dist/marketplace/external_plugins/sequant/skills/fullsolve/SKILL.md +3 -1
- package/dist/marketplace/external_plugins/sequant/skills/loop/SKILL.md +38 -2
- package/dist/marketplace/external_plugins/sequant/skills/merger/SKILL.md +2 -2
- package/dist/marketplace/external_plugins/sequant/skills/qa/SKILL.md +337 -57
- package/dist/marketplace/external_plugins/sequant/skills/qa/references/anti-pattern-detection.md +6 -6
- package/dist/marketplace/external_plugins/sequant/skills/qa/references/call-site-review.md +2 -2
- package/dist/marketplace/external_plugins/sequant/skills/qa/references/code-review-checklist.md +2 -2
- package/dist/marketplace/external_plugins/sequant/skills/qa/references/fixtures/injection-issue-body.md +36 -0
- package/dist/marketplace/external_plugins/sequant/skills/qa/references/quality-gates.md +21 -7
- package/dist/marketplace/external_plugins/sequant/skills/qa/references/testing-requirements.md +1 -1
- package/dist/marketplace/external_plugins/sequant/skills/qa/scripts/quality-checks.sh +11 -11
- package/dist/marketplace/external_plugins/sequant/skills/release/SKILL.md +1 -1
- package/dist/marketplace/external_plugins/sequant/skills/setup/SKILL.md +5 -5
- package/dist/marketplace/external_plugins/sequant/skills/spec/SKILL.md +2 -0
- package/dist/marketplace/external_plugins/sequant/skills/test/SKILL.md +1 -1
- package/dist/src/commands/assess-render.d.ts +23 -0
- package/dist/src/commands/assess-render.js +60 -0
- package/dist/src/commands/doctor.js +8 -13
- package/dist/src/commands/init.js +13 -1
- package/dist/src/commands/locks.d.ts +20 -1
- package/dist/src/commands/locks.js +208 -4
- package/dist/src/commands/logs.js +14 -5
- package/dist/src/commands/merge.js +154 -2
- package/dist/src/commands/ready-tui-adapter.js +6 -1
- package/dist/src/commands/ready.d.ts +31 -3
- package/dist/src/commands/ready.js +53 -13
- package/dist/src/commands/resume.d.ts +113 -0
- package/dist/src/commands/resume.js +193 -0
- package/dist/src/commands/run-display.js +38 -4
- package/dist/src/commands/run-flags.d.ts +42 -1
- package/dist/src/commands/run-flags.js +53 -1
- package/dist/src/commands/run-progress.js +26 -1
- package/dist/src/commands/run.js +11 -10
- package/dist/src/commands/state.js +7 -0
- package/dist/src/commands/status.d.ts +9 -0
- package/dist/src/commands/status.js +24 -1
- package/dist/src/commands/sync.js +90 -19
- package/dist/src/commands/update.js +28 -5
- package/dist/src/commands/worktree.d.ts +31 -0
- package/dist/src/commands/worktree.js +95 -0
- package/dist/src/lib/ac-parser.d.ts +14 -0
- package/dist/src/lib/ac-parser.js +99 -5
- package/dist/src/lib/assess/index.d.ts +10 -0
- package/dist/src/lib/assess/index.js +9 -0
- package/dist/src/lib/assess/renderer.d.ts +64 -0
- package/dist/src/lib/assess/renderer.js +481 -0
- package/dist/src/lib/assess/types.d.ts +224 -0
- package/dist/src/lib/assess/types.js +241 -0
- package/dist/src/lib/ci/outputs.d.ts +15 -2
- package/dist/src/lib/ci/outputs.js +17 -5
- package/dist/src/lib/cli-flags.d.ts +56 -0
- package/dist/src/lib/cli-flags.js +89 -0
- package/dist/src/lib/cli-ui/run-renderer-types.d.ts +23 -7
- package/dist/src/lib/cli-ui/run-renderer.d.ts +10 -0
- package/dist/src/lib/cli-ui/run-renderer.js +69 -1
- package/dist/src/lib/errors.d.ts +78 -6
- package/dist/src/lib/errors.js +133 -15
- package/dist/src/lib/locks/checkout-lock.d.ts +193 -0
- package/dist/src/lib/locks/checkout-lock.js +389 -0
- package/dist/src/lib/locks/index.d.ts +7 -4
- package/dist/src/lib/locks/index.js +5 -3
- package/dist/src/lib/locks/lock-manager.d.ts +101 -3
- package/dist/src/lib/locks/lock-manager.js +277 -8
- package/dist/src/lib/locks/types.d.ts +106 -3
- package/dist/src/lib/locks/types.js +44 -0
- package/dist/src/lib/mcp-config.d.ts +45 -0
- package/dist/src/lib/mcp-config.js +77 -1
- package/dist/src/lib/merge-check/combined-branch-test.d.ts +21 -2
- package/dist/src/lib/merge-check/combined-branch-test.js +233 -110
- package/dist/src/lib/merge-check/command-result.d.ts +36 -0
- package/dist/src/lib/merge-check/command-result.js +56 -0
- package/dist/src/lib/merge-check/index.d.ts +4 -0
- package/dist/src/lib/merge-check/index.js +1 -1
- package/dist/src/lib/merge-check/report.js +5 -1
- package/dist/src/lib/merge-check/types.d.ts +9 -0
- package/dist/src/lib/merge-check/watch.d.ts +121 -0
- package/dist/src/lib/merge-check/watch.js +215 -0
- package/dist/src/lib/qa/infra-blocked-ci.d.ts +90 -0
- package/dist/src/lib/qa/infra-blocked-ci.js +80 -0
- package/dist/src/lib/settings.d.ts +87 -0
- package/dist/src/lib/settings.js +106 -8
- package/dist/src/lib/shutdown.d.ts +42 -2
- package/dist/src/lib/shutdown.js +75 -5
- package/dist/src/lib/skills-check.d.ts +26 -0
- package/dist/src/lib/skills-check.js +31 -0
- package/dist/src/lib/stacks.d.ts +110 -1
- package/dist/src/lib/stacks.js +244 -5
- package/dist/src/lib/templates.d.ts +74 -0
- package/dist/src/lib/templates.js +171 -16
- package/dist/src/lib/test-tautology-detector.d.ts +10 -2
- package/dist/src/lib/test-tautology-detector.js +213 -12
- package/dist/src/lib/version-check.d.ts +31 -0
- package/dist/src/lib/version-check.js +45 -2
- package/dist/src/lib/workflow/batch-executor.d.ts +125 -6
- package/dist/src/lib/workflow/batch-executor.js +552 -60
- package/dist/src/lib/workflow/chain-resume.d.ts +13 -11
- package/dist/src/lib/workflow/chain-resume.js +24 -20
- package/dist/src/lib/workflow/completed-status.d.ts +52 -0
- package/dist/src/lib/workflow/completed-status.js +57 -0
- package/dist/src/lib/workflow/config-resolver.d.ts +51 -0
- package/dist/src/lib/workflow/config-resolver.js +143 -2
- package/dist/src/lib/workflow/drivers/agent-driver.d.ts +22 -0
- package/dist/src/lib/workflow/drivers/aider.d.ts +2 -0
- package/dist/src/lib/workflow/drivers/aider.js +2 -0
- package/dist/src/lib/workflow/drivers/claude-code.d.ts +14 -0
- package/dist/src/lib/workflow/drivers/claude-code.js +25 -2
- package/dist/src/lib/workflow/effort-escalation.d.ts +73 -0
- package/dist/src/lib/workflow/effort-escalation.js +82 -0
- package/dist/src/lib/workflow/error-classifier.d.ts +4 -1
- package/dist/src/lib/workflow/error-classifier.js +4 -0
- package/dist/src/lib/workflow/git-diff-utils.d.ts +35 -3
- package/dist/src/lib/workflow/git-diff-utils.js +77 -4
- package/dist/src/lib/workflow/heartbeat.d.ts +38 -0
- package/dist/src/lib/workflow/heartbeat.js +90 -0
- package/dist/src/lib/workflow/log-writer.d.ts +54 -2
- package/dist/src/lib/workflow/log-writer.js +95 -6
- package/dist/src/lib/workflow/metrics-schema.d.ts +52 -9
- package/dist/src/lib/workflow/metrics-schema.js +33 -0
- package/dist/src/lib/workflow/metrics-writer.d.ts +11 -0
- package/dist/src/lib/workflow/phase-detection.d.ts +12 -0
- package/dist/src/lib/workflow/phase-detection.js +5 -1
- package/dist/src/lib/workflow/phase-executor.d.ts +203 -14
- package/dist/src/lib/workflow/phase-executor.js +467 -52
- package/dist/src/lib/workflow/phase-registry.js +2 -1
- package/dist/src/lib/workflow/platforms/github.d.ts +64 -0
- package/dist/src/lib/workflow/platforms/github.js +152 -0
- package/dist/src/lib/workflow/qa-cache.d.ts +6 -1
- package/dist/src/lib/workflow/qa-cache.js +22 -9
- package/dist/src/lib/workflow/ready-gate.d.ts +45 -4
- package/dist/src/lib/workflow/ready-gate.js +49 -12
- package/dist/src/lib/workflow/run-log-schema.d.ts +69 -0
- package/dist/src/lib/workflow/run-log-schema.js +78 -2
- package/dist/src/lib/workflow/run-orchestrator.d.ts +19 -0
- package/dist/src/lib/workflow/run-orchestrator.js +168 -20
- package/dist/src/lib/workflow/skills-preflight.d.ts +89 -0
- package/dist/src/lib/workflow/skills-preflight.js +112 -0
- package/dist/src/lib/workflow/spec-recommendation.d.ts +71 -0
- package/dist/src/lib/workflow/spec-recommendation.js +142 -0
- package/dist/src/lib/workflow/state-cleanup.js +9 -2
- package/dist/src/lib/workflow/state-manager.d.ts +33 -0
- package/dist/src/lib/workflow/state-manager.js +83 -0
- package/dist/src/lib/workflow/state-schema.d.ts +26 -0
- package/dist/src/lib/workflow/state-schema.js +47 -0
- package/dist/src/lib/workflow/types.d.ts +190 -4
- package/dist/src/lib/workflow/types.js +1 -0
- package/dist/src/lib/workflow/worktree-manager.d.ts +36 -3
- package/dist/src/lib/workflow/worktree-manager.js +111 -24
- package/dist/src/lib/workflow/worktree-resolver.d.ts +73 -0
- package/dist/src/lib/workflow/worktree-resolver.js +126 -0
- package/dist/src/mcp/tools/run.d.ts +9 -1
- package/dist/src/mcp/tools/run.js +20 -1
- package/dist/src/mcp/tools/status.js +6 -0
- package/dist/src/ui/tui/ElapsedTimer.d.ts +12 -3
- package/dist/src/ui/tui/ElapsedTimer.js +12 -10
- package/dist/src/ui/tui/IssueBox.js +10 -2
- package/dist/src/ui/tui/row-cap.js +2 -1
- package/dist/src/ui/tui/theme.d.ts +7 -0
- package/dist/src/ui/tui/theme.js +9 -0
- package/package.json +10 -8
- package/templates/hooks/parallel-marker.sh +50 -0
- package/templates/hooks/post-tool.sh +20 -7
- package/templates/hooks/pre-tool.sh +303 -10
- package/templates/scripts/cleanup-worktree.sh +217 -33
- package/templates/scripts/new-feature.sh +289 -35
- package/templates/skills/_shared/references/subagent-types.md +7 -18
- package/templates/skills/_shared/references/trust-model.md +18 -0
- package/templates/skills/assess/SKILL.md +220 -391
- package/templates/skills/assess/references/predicted-collision-detection.md +1 -1
- package/templates/skills/docs/SKILL.md +4 -4
- package/templates/skills/exec/SKILL.md +87 -13
- package/templates/skills/fullsolve/SKILL.md +130 -22
- package/templates/skills/loop/SKILL.md +94 -13
- package/templates/skills/merger/SKILL.md +100 -12
- package/templates/skills/qa/SKILL.md +396 -63
- package/templates/skills/qa/references/anti-pattern-detection.md +6 -6
- package/templates/skills/qa/references/call-site-review.md +2 -2
- package/templates/skills/qa/references/code-review-checklist.md +2 -2
- package/templates/skills/qa/references/fixtures/injection-issue-body.md +36 -0
- package/templates/skills/qa/references/quality-gates.md +21 -7
- package/templates/skills/qa/references/testing-requirements.md +1 -1
- package/templates/skills/qa/scripts/quality-checks.sh +11 -11
- package/templates/skills/release/SKILL.md +80 -1
- package/templates/skills/setup/SKILL.md +5 -5
- package/templates/skills/spec/SKILL.md +33 -15
- package/templates/skills/spec/references/recommended-workflow.md +14 -1
- package/templates/skills/test/SKILL.md +1 -1
- package/templates/skills/testgen/SKILL.md +23 -6
- package/dist/src/lib/phase-spinner.d.ts +0 -146
- package/dist/src/lib/phase-spinner.js +0 -255
- package/dist/src/lib/workflow/pr-operations.d.ts +0 -86
- package/dist/src/lib/workflow/pr-operations.js +0 -326
- package/dist/src/lib/workflow/run-summary.d.ts +0 -36
- package/dist/src/lib/workflow/run-summary.js +0 -142
- package/templates/agents/sequant-explorer.md +0 -24
|
@@ -1,326 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PR Operations Module
|
|
3
|
-
*
|
|
4
|
-
* Handles pre-PR and PR creation operations:
|
|
5
|
-
* - Checkpoint commits for chain recovery
|
|
6
|
-
* - Lockfile change detection and dependency reinstall
|
|
7
|
-
* - Pre-PR rebase onto origin/main
|
|
8
|
-
* - PR creation with existing-PR detection
|
|
9
|
-
*
|
|
10
|
-
* @module pr-operations
|
|
11
|
-
*/
|
|
12
|
-
import chalk from "chalk";
|
|
13
|
-
import { spawnSync } from "child_process";
|
|
14
|
-
import { PM_CONFIG } from "../stacks.js";
|
|
15
|
-
/**
|
|
16
|
-
* Lockfile names for different package managers
|
|
17
|
-
*/
|
|
18
|
-
const LOCKFILES = [
|
|
19
|
-
"package-lock.json",
|
|
20
|
-
"pnpm-lock.yaml",
|
|
21
|
-
"bun.lock",
|
|
22
|
-
"yarn.lock",
|
|
23
|
-
];
|
|
24
|
-
/**
|
|
25
|
-
* Create a checkpoint commit in the worktree after QA passes
|
|
26
|
-
* This allows recovery in case later issues in the chain fail
|
|
27
|
-
* @internal Exported for testing
|
|
28
|
-
*/
|
|
29
|
-
export function createCheckpointCommit(worktreePath, issueNumber, verbose) {
|
|
30
|
-
// Check if there are uncommitted changes
|
|
31
|
-
const statusResult = spawnSync("git", ["-C", worktreePath, "status", "--porcelain"], { stdio: "pipe" });
|
|
32
|
-
if (statusResult.status !== 0) {
|
|
33
|
-
if (verbose) {
|
|
34
|
-
console.log(chalk.yellow(` â ī¸ Could not check git status for checkpoint`));
|
|
35
|
-
}
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
const hasChanges = statusResult.stdout.toString().trim().length > 0;
|
|
39
|
-
if (!hasChanges) {
|
|
40
|
-
if (verbose) {
|
|
41
|
-
console.log(chalk.gray(` đ No changes to checkpoint (already committed)`));
|
|
42
|
-
}
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
// Stage all changes
|
|
46
|
-
const addResult = spawnSync("git", ["-C", worktreePath, "add", "-A"], {
|
|
47
|
-
stdio: "pipe",
|
|
48
|
-
});
|
|
49
|
-
if (addResult.status !== 0) {
|
|
50
|
-
if (verbose) {
|
|
51
|
-
console.log(chalk.yellow(` â ī¸ Could not stage changes for checkpoint`));
|
|
52
|
-
}
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
// Create checkpoint commit
|
|
56
|
-
const commitMessage = `checkpoint(#${issueNumber}): QA passed
|
|
57
|
-
|
|
58
|
-
This is an automatic checkpoint commit created after issue #${issueNumber}
|
|
59
|
-
passed QA in chain mode. It serves as a recovery point if later issues fail.`;
|
|
60
|
-
const commitResult = spawnSync("git", ["-C", worktreePath, "commit", "-m", commitMessage], { stdio: "pipe" });
|
|
61
|
-
if (commitResult.status !== 0) {
|
|
62
|
-
const error = commitResult.stderr.toString();
|
|
63
|
-
if (verbose) {
|
|
64
|
-
console.log(chalk.yellow(` â ī¸ Could not create checkpoint commit: ${error}`));
|
|
65
|
-
}
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
console.log(chalk.green(` đ Checkpoint commit created for #${issueNumber}`));
|
|
69
|
-
return true;
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Check if any lockfile changed during a rebase and re-run install if needed.
|
|
73
|
-
* This prevents dependency drift when the lockfile was updated on main.
|
|
74
|
-
* @param worktreePath Path to the worktree
|
|
75
|
-
* @param packageManager Package manager to use for install
|
|
76
|
-
* @param verbose Whether to show verbose output
|
|
77
|
-
* @param preRebaseRef Git ref pointing to pre-rebase HEAD (defaults to ORIG_HEAD,
|
|
78
|
-
* which git sets automatically after rebase). Using ORIG_HEAD captures all
|
|
79
|
-
* lockfile changes across multi-commit rebases, unlike HEAD~1 which only
|
|
80
|
-
* checks the last commit.
|
|
81
|
-
* @returns true if reinstall was performed, false otherwise
|
|
82
|
-
* @internal Exported for testing
|
|
83
|
-
*/
|
|
84
|
-
export function reinstallIfLockfileChanged(worktreePath, packageManager, verbose, preRebaseRef = "ORIG_HEAD") {
|
|
85
|
-
// Compare pre-rebase state to current HEAD to detect all lockfile changes
|
|
86
|
-
// introduced by the rebase (including changes from main that were pulled in)
|
|
87
|
-
let lockfileChanged = false;
|
|
88
|
-
for (const lockfile of LOCKFILES) {
|
|
89
|
-
const result = spawnSync("git", [
|
|
90
|
-
"-C",
|
|
91
|
-
worktreePath,
|
|
92
|
-
"diff",
|
|
93
|
-
"--name-only",
|
|
94
|
-
`${preRebaseRef}..HEAD`,
|
|
95
|
-
"--",
|
|
96
|
-
lockfile,
|
|
97
|
-
], { stdio: "pipe" });
|
|
98
|
-
if (result.status === 0 && result.stdout.toString().trim().length > 0) {
|
|
99
|
-
lockfileChanged = true;
|
|
100
|
-
if (verbose) {
|
|
101
|
-
console.log(chalk.gray(` đĻ Lockfile changed: ${lockfile}`));
|
|
102
|
-
}
|
|
103
|
-
break;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
if (!lockfileChanged) {
|
|
107
|
-
if (verbose) {
|
|
108
|
-
console.log(chalk.gray(` đĻ No lockfile changes detected`));
|
|
109
|
-
}
|
|
110
|
-
return false;
|
|
111
|
-
}
|
|
112
|
-
// Re-run install to sync node_modules with updated lockfile
|
|
113
|
-
console.log(chalk.blue(` đĻ Reinstalling dependencies (lockfile changed)...`));
|
|
114
|
-
const pm = packageManager || "npm";
|
|
115
|
-
const pmConfig = PM_CONFIG[pm];
|
|
116
|
-
const [cmd, ...args] = pmConfig.installSilent.split(" ");
|
|
117
|
-
const installResult = spawnSync(cmd, args, {
|
|
118
|
-
cwd: worktreePath,
|
|
119
|
-
stdio: "pipe",
|
|
120
|
-
});
|
|
121
|
-
if (installResult.status !== 0) {
|
|
122
|
-
const error = installResult.stderr.toString();
|
|
123
|
-
console.log(chalk.yellow(` â ī¸ Dependency reinstall failed: ${error.trim()}`));
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
console.log(chalk.green(` â
Dependencies reinstalled`));
|
|
127
|
-
return true;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Rebase the worktree branch onto origin/main before PR creation.
|
|
131
|
-
* This ensures the branch is up-to-date and prevents lockfile drift.
|
|
132
|
-
*
|
|
133
|
-
* @param worktreePath Path to the worktree
|
|
134
|
-
* @param issueNumber Issue number (for logging)
|
|
135
|
-
* @param packageManager Package manager to use if reinstall needed
|
|
136
|
-
* @param verbose Whether to show verbose output
|
|
137
|
-
* @returns RebaseResult indicating success/failure and whether reinstall was performed
|
|
138
|
-
* @internal Exported for testing
|
|
139
|
-
*/
|
|
140
|
-
export function rebaseBeforePR(worktreePath, issueNumber, packageManager, verbose) {
|
|
141
|
-
if (verbose) {
|
|
142
|
-
console.log(chalk.gray(` đ Rebasing #${issueNumber} onto origin/main before PR...`));
|
|
143
|
-
}
|
|
144
|
-
// Fetch latest main to ensure we're rebasing onto fresh state
|
|
145
|
-
const fetchResult = spawnSync("git", ["-C", worktreePath, "fetch", "origin", "main"], {
|
|
146
|
-
stdio: "pipe",
|
|
147
|
-
});
|
|
148
|
-
if (fetchResult.status !== 0) {
|
|
149
|
-
const error = fetchResult.stderr.toString();
|
|
150
|
-
console.log(chalk.yellow(` â ī¸ Could not fetch origin/main: ${error.trim()}`));
|
|
151
|
-
// Continue anyway - might work with local state
|
|
152
|
-
}
|
|
153
|
-
// Perform the rebase
|
|
154
|
-
const rebaseResult = spawnSync("git", ["-C", worktreePath, "rebase", "origin/main"], { stdio: "pipe" });
|
|
155
|
-
if (rebaseResult.status !== 0) {
|
|
156
|
-
const rebaseError = rebaseResult.stderr.toString();
|
|
157
|
-
// Check if it's a conflict
|
|
158
|
-
if (rebaseError.includes("CONFLICT") ||
|
|
159
|
-
rebaseError.includes("could not apply")) {
|
|
160
|
-
console.log(chalk.yellow(` â ī¸ Rebase conflict detected. Aborting rebase and keeping original branch state.`));
|
|
161
|
-
console.log(chalk.yellow(` âšī¸ PR will be created without rebase. Manual rebase may be required before merge.`));
|
|
162
|
-
// Abort the rebase to restore branch state
|
|
163
|
-
spawnSync("git", ["-C", worktreePath, "rebase", "--abort"], {
|
|
164
|
-
stdio: "pipe",
|
|
165
|
-
});
|
|
166
|
-
return {
|
|
167
|
-
performed: true,
|
|
168
|
-
success: false,
|
|
169
|
-
reinstalled: false,
|
|
170
|
-
error: "Rebase conflict - manual resolution required",
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
else {
|
|
174
|
-
console.log(chalk.yellow(` â ī¸ Rebase failed: ${rebaseError.trim()}`));
|
|
175
|
-
console.log(chalk.yellow(` âšī¸ Continuing with branch in its original state.`));
|
|
176
|
-
return {
|
|
177
|
-
performed: true,
|
|
178
|
-
success: false,
|
|
179
|
-
reinstalled: false,
|
|
180
|
-
error: rebaseError.trim(),
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
console.log(chalk.green(` â
Branch rebased onto origin/main`));
|
|
185
|
-
// Check if lockfile changed and reinstall if needed
|
|
186
|
-
const reinstalled = reinstallIfLockfileChanged(worktreePath, packageManager, verbose);
|
|
187
|
-
return {
|
|
188
|
-
performed: true,
|
|
189
|
-
success: true,
|
|
190
|
-
reinstalled,
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
/**
|
|
194
|
-
* Push branch and create a PR after successful QA.
|
|
195
|
-
*
|
|
196
|
-
* Handles both fresh PR creation and detection of existing PRs.
|
|
197
|
-
* Failures are warnings â they don't fail the run.
|
|
198
|
-
*
|
|
199
|
-
* @param worktreePath Path to the worktree
|
|
200
|
-
* @param issueNumber Issue number
|
|
201
|
-
* @param issueTitle Issue title (for PR title)
|
|
202
|
-
* @param branch Branch name
|
|
203
|
-
* @param verbose Whether to show verbose output
|
|
204
|
-
* @returns PRCreationResult with PR info or error
|
|
205
|
-
* @internal Exported for testing
|
|
206
|
-
*/
|
|
207
|
-
export function createPR(worktreePath, issueNumber, issueTitle, branch, verbose, labels) {
|
|
208
|
-
// Step 1: Check for existing PR on this branch
|
|
209
|
-
const existingPR = spawnSync("gh", ["pr", "view", branch, "--json", "number,url"], { stdio: "pipe", cwd: worktreePath, timeout: 15000 });
|
|
210
|
-
if (existingPR.status === 0 && existingPR.stdout) {
|
|
211
|
-
try {
|
|
212
|
-
const prInfo = JSON.parse(existingPR.stdout.toString());
|
|
213
|
-
if (prInfo.number && prInfo.url) {
|
|
214
|
-
if (verbose) {
|
|
215
|
-
console.log(chalk.gray(` âšī¸ PR #${prInfo.number} already exists for branch ${branch}`));
|
|
216
|
-
}
|
|
217
|
-
return {
|
|
218
|
-
attempted: true,
|
|
219
|
-
success: true,
|
|
220
|
-
prNumber: prInfo.number,
|
|
221
|
-
prUrl: prInfo.url,
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
catch {
|
|
226
|
-
// JSON parse failed â no existing PR, continue to create
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
// Step 2: Push branch to remote
|
|
230
|
-
if (verbose) {
|
|
231
|
-
console.log(chalk.gray(` đ Pushing branch ${branch} to origin...`));
|
|
232
|
-
}
|
|
233
|
-
const pushResult = spawnSync("git", ["-C", worktreePath, "push", "-u", "origin", branch], { stdio: "pipe", timeout: 60000 });
|
|
234
|
-
if (pushResult.status !== 0) {
|
|
235
|
-
const pushError = pushResult.stderr?.toString().trim() ?? "Unknown error";
|
|
236
|
-
console.log(chalk.yellow(` â ī¸ git push failed: ${pushError}`));
|
|
237
|
-
return {
|
|
238
|
-
attempted: true,
|
|
239
|
-
success: false,
|
|
240
|
-
error: `git push failed: ${pushError}`,
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
// Step 3: Create PR
|
|
244
|
-
if (verbose) {
|
|
245
|
-
console.log(chalk.gray(` đ Creating PR for #${issueNumber}...`));
|
|
246
|
-
}
|
|
247
|
-
const isBug = labels?.some((l) => /^bug/i.test(l));
|
|
248
|
-
const prefix = isBug ? "fix" : "feat";
|
|
249
|
-
const prTitle = `${prefix}(#${issueNumber}): ${issueTitle}`;
|
|
250
|
-
const prBody = [
|
|
251
|
-
`## Summary`,
|
|
252
|
-
``,
|
|
253
|
-
`Automated PR for issue #${issueNumber}.`,
|
|
254
|
-
``,
|
|
255
|
-
`Fixes #${issueNumber}`,
|
|
256
|
-
``,
|
|
257
|
-
`---`,
|
|
258
|
-
`đ¤ Generated by \`sequant run\``,
|
|
259
|
-
].join("\n");
|
|
260
|
-
const prResult = spawnSync("gh", ["pr", "create", "--title", prTitle, "--body", prBody, "--head", branch], { stdio: "pipe", cwd: worktreePath, timeout: 30000 });
|
|
261
|
-
if (prResult.status !== 0) {
|
|
262
|
-
const prError = prResult.stderr?.toString().trim() ?? "Unknown error";
|
|
263
|
-
// Check if PR already exists (race condition or push-before-PR scenarios)
|
|
264
|
-
if (prError.includes("already exists")) {
|
|
265
|
-
const retryView = spawnSync("gh", ["pr", "view", branch, "--json", "number,url"], { stdio: "pipe", cwd: worktreePath, timeout: 15000 });
|
|
266
|
-
if (retryView.status === 0 && retryView.stdout) {
|
|
267
|
-
try {
|
|
268
|
-
const prInfo = JSON.parse(retryView.stdout.toString());
|
|
269
|
-
return {
|
|
270
|
-
attempted: true,
|
|
271
|
-
success: true,
|
|
272
|
-
prNumber: prInfo.number,
|
|
273
|
-
prUrl: prInfo.url,
|
|
274
|
-
};
|
|
275
|
-
}
|
|
276
|
-
catch {
|
|
277
|
-
// Fall through to error
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
console.log(chalk.yellow(` â ī¸ PR creation failed: ${prError}`));
|
|
282
|
-
return {
|
|
283
|
-
attempted: true,
|
|
284
|
-
success: false,
|
|
285
|
-
error: `gh pr create failed: ${prError}`,
|
|
286
|
-
};
|
|
287
|
-
}
|
|
288
|
-
// Step 4: Extract PR URL from output and get PR details
|
|
289
|
-
const prOutput = prResult.stdout?.toString().trim() ?? "";
|
|
290
|
-
const prUrlMatch = prOutput.match(/https:\/\/github\.com\/[^\s]+\/pull\/(\d+)/);
|
|
291
|
-
if (prUrlMatch) {
|
|
292
|
-
const prNumber = parseInt(prUrlMatch[1], 10);
|
|
293
|
-
const prUrl = prUrlMatch[0];
|
|
294
|
-
console.log(chalk.green(` â
PR #${prNumber} created: ${prUrl}`));
|
|
295
|
-
return {
|
|
296
|
-
attempted: true,
|
|
297
|
-
success: true,
|
|
298
|
-
prNumber,
|
|
299
|
-
prUrl,
|
|
300
|
-
};
|
|
301
|
-
}
|
|
302
|
-
// Fallback: try gh pr view to get details
|
|
303
|
-
const viewResult = spawnSync("gh", ["pr", "view", branch, "--json", "number,url"], { stdio: "pipe", cwd: worktreePath, timeout: 15000 });
|
|
304
|
-
if (viewResult.status === 0 && viewResult.stdout) {
|
|
305
|
-
try {
|
|
306
|
-
const prInfo = JSON.parse(viewResult.stdout.toString());
|
|
307
|
-
console.log(chalk.green(` â
PR #${prInfo.number} created: ${prInfo.url}`));
|
|
308
|
-
return {
|
|
309
|
-
attempted: true,
|
|
310
|
-
success: true,
|
|
311
|
-
prNumber: prInfo.number,
|
|
312
|
-
prUrl: prInfo.url,
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
catch {
|
|
316
|
-
// Fall through
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
// PR was created but we couldn't parse the URL
|
|
320
|
-
console.log(chalk.yellow(` â ī¸ PR created but could not extract URL from output: ${prOutput}`));
|
|
321
|
-
return {
|
|
322
|
-
attempted: true,
|
|
323
|
-
success: true,
|
|
324
|
-
error: "PR created but URL extraction failed",
|
|
325
|
-
};
|
|
326
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Run Summary Module
|
|
3
|
-
*
|
|
4
|
-
* Handles post-execution reporting for sequant run:
|
|
5
|
-
* - Metrics recording (local analytics)
|
|
6
|
-
* - Summary display with pass/fail counts
|
|
7
|
-
*
|
|
8
|
-
* @module run-summary
|
|
9
|
-
*/
|
|
10
|
-
import type { ExecutionConfig, IssueResult } from "./types.js";
|
|
11
|
-
import type { WorktreeInfo } from "./worktree-manager.js";
|
|
12
|
-
import type { RunOptions } from "./batch-executor.js";
|
|
13
|
-
/**
|
|
14
|
-
* Record run metrics to local analytics file
|
|
15
|
-
*
|
|
16
|
-
* @param params - Metrics recording parameters
|
|
17
|
-
*/
|
|
18
|
-
export declare function recordRunMetrics(params: {
|
|
19
|
-
results: IssueResult[];
|
|
20
|
-
issueNumbers: number[];
|
|
21
|
-
config: ExecutionConfig;
|
|
22
|
-
worktreeMap: Map<number, WorktreeInfo>;
|
|
23
|
-
mergedOptions: RunOptions;
|
|
24
|
-
}): Promise<void>;
|
|
25
|
-
/**
|
|
26
|
-
* Print the run summary to console
|
|
27
|
-
*
|
|
28
|
-
* @param params - Summary display parameters
|
|
29
|
-
* @returns exit code (0 for success, 1 if any failed)
|
|
30
|
-
*/
|
|
31
|
-
export declare function printRunSummary(params: {
|
|
32
|
-
results: IssueResult[];
|
|
33
|
-
logPath: string | null;
|
|
34
|
-
config: ExecutionConfig;
|
|
35
|
-
mergedOptions: RunOptions;
|
|
36
|
-
}): number;
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Run Summary Module
|
|
3
|
-
*
|
|
4
|
-
* Handles post-execution reporting for sequant run:
|
|
5
|
-
* - Metrics recording (local analytics)
|
|
6
|
-
* - Summary display with pass/fail counts
|
|
7
|
-
*
|
|
8
|
-
* @module run-summary
|
|
9
|
-
*/
|
|
10
|
-
import chalk from "chalk";
|
|
11
|
-
import { MetricsWriter } from "./metrics-writer.js";
|
|
12
|
-
import { determineOutcome } from "./metrics-schema.js";
|
|
13
|
-
import { ui, colors } from "../cli-ui.js";
|
|
14
|
-
import { getTokenUsageForRun } from "./token-utils.js";
|
|
15
|
-
import { getWorktreeDiffStats } from "./worktree-manager.js";
|
|
16
|
-
import { formatDuration } from "./phase-executor.js";
|
|
17
|
-
/**
|
|
18
|
-
* Record run metrics to local analytics file
|
|
19
|
-
*
|
|
20
|
-
* @param params - Metrics recording parameters
|
|
21
|
-
*/
|
|
22
|
-
export async function recordRunMetrics(params) {
|
|
23
|
-
const { results, issueNumbers, config, worktreeMap, mergedOptions } = params;
|
|
24
|
-
const metricsWriter = new MetricsWriter({ verbose: config.verbose });
|
|
25
|
-
// Calculate total duration
|
|
26
|
-
const totalDuration = results.reduce((sum, r) => sum + (r.durationSeconds ?? 0), 0);
|
|
27
|
-
// Get unique phases from all results
|
|
28
|
-
const allPhases = new Set();
|
|
29
|
-
for (const result of results) {
|
|
30
|
-
for (const phaseResult of result.phaseResults) {
|
|
31
|
-
const phase = phaseResult.phase;
|
|
32
|
-
if ([
|
|
33
|
-
"spec",
|
|
34
|
-
"security-review",
|
|
35
|
-
"testgen",
|
|
36
|
-
"exec",
|
|
37
|
-
"test",
|
|
38
|
-
"qa",
|
|
39
|
-
"loop",
|
|
40
|
-
].includes(phase)) {
|
|
41
|
-
allPhases.add(phase);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
// Calculate aggregate metrics from worktrees
|
|
46
|
-
let totalFilesChanged = 0;
|
|
47
|
-
let totalLinesAdded = 0;
|
|
48
|
-
let totalQaIterations = 0;
|
|
49
|
-
for (const result of results) {
|
|
50
|
-
const worktreeInfo = worktreeMap.get(result.issueNumber);
|
|
51
|
-
if (worktreeInfo?.path) {
|
|
52
|
-
const stats = getWorktreeDiffStats(worktreeInfo.path);
|
|
53
|
-
totalFilesChanged += stats.filesChanged;
|
|
54
|
-
totalLinesAdded += stats.linesAdded;
|
|
55
|
-
}
|
|
56
|
-
if (result.loopTriggered) {
|
|
57
|
-
totalQaIterations += result.phaseResults.filter((p) => p.phase === "loop").length;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
// Build CLI flags for metrics
|
|
61
|
-
const cliFlags = [];
|
|
62
|
-
if (mergedOptions.sequential)
|
|
63
|
-
cliFlags.push("--sequential");
|
|
64
|
-
if (mergedOptions.chain)
|
|
65
|
-
cliFlags.push("--chain");
|
|
66
|
-
if (mergedOptions.qaGate)
|
|
67
|
-
cliFlags.push("--qa-gate");
|
|
68
|
-
if (mergedOptions.qualityLoop)
|
|
69
|
-
cliFlags.push("--quality-loop");
|
|
70
|
-
if (mergedOptions.testgen)
|
|
71
|
-
cliFlags.push("--testgen");
|
|
72
|
-
// Read token usage from SessionEnd hook files
|
|
73
|
-
const tokenUsage = getTokenUsageForRun(undefined, true);
|
|
74
|
-
const passed = results.filter((r) => r.success).length;
|
|
75
|
-
await metricsWriter.recordRun({
|
|
76
|
-
issues: issueNumbers,
|
|
77
|
-
phases: Array.from(allPhases),
|
|
78
|
-
outcome: determineOutcome(passed, results.length),
|
|
79
|
-
duration: totalDuration,
|
|
80
|
-
model: process.env.ANTHROPIC_MODEL ?? "opus",
|
|
81
|
-
flags: cliFlags,
|
|
82
|
-
metrics: {
|
|
83
|
-
tokensUsed: tokenUsage.tokensUsed,
|
|
84
|
-
filesChanged: totalFilesChanged,
|
|
85
|
-
linesAdded: totalLinesAdded,
|
|
86
|
-
acceptanceCriteria: 0,
|
|
87
|
-
qaIterations: totalQaIterations,
|
|
88
|
-
inputTokens: tokenUsage.inputTokens || undefined,
|
|
89
|
-
outputTokens: tokenUsage.outputTokens || undefined,
|
|
90
|
-
cacheTokens: tokenUsage.cacheTokens || undefined,
|
|
91
|
-
},
|
|
92
|
-
});
|
|
93
|
-
if (config.verbose) {
|
|
94
|
-
console.log(chalk.gray(` đ Metrics recorded to .sequant/metrics.json`));
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Print the run summary to console
|
|
99
|
-
*
|
|
100
|
-
* @param params - Summary display parameters
|
|
101
|
-
* @returns exit code (0 for success, 1 if any failed)
|
|
102
|
-
*/
|
|
103
|
-
export function printRunSummary(params) {
|
|
104
|
-
const { results, logPath, config, mergedOptions } = params;
|
|
105
|
-
const passed = results.filter((r) => r.success).length;
|
|
106
|
-
const failed = results.filter((r) => !r.success).length;
|
|
107
|
-
console.log("\n" + ui.divider());
|
|
108
|
-
console.log(colors.info(" Summary"));
|
|
109
|
-
console.log(ui.divider());
|
|
110
|
-
console.log(colors.muted(`\n Results: ${colors.success(`${passed} passed`)}, ${colors.error(`${failed} failed`)}`));
|
|
111
|
-
for (const result of results) {
|
|
112
|
-
const status = result.success
|
|
113
|
-
? ui.statusIcon("success")
|
|
114
|
-
: ui.statusIcon("error");
|
|
115
|
-
const duration = result.durationSeconds
|
|
116
|
-
? colors.muted(` (${formatDuration(result.durationSeconds)})`)
|
|
117
|
-
: "";
|
|
118
|
-
const phases = result.phaseResults
|
|
119
|
-
.map((p) => (p.success ? colors.success(p.phase) : colors.error(p.phase)))
|
|
120
|
-
.join(" â ");
|
|
121
|
-
const loopInfo = result.loopTriggered ? colors.warning(" [loop]") : "";
|
|
122
|
-
const prInfo = result.prUrl
|
|
123
|
-
? colors.muted(` â PR #${result.prNumber}`)
|
|
124
|
-
: "";
|
|
125
|
-
console.log(` ${status} #${result.issueNumber}: ${phases}${loopInfo}${prInfo}${duration}`);
|
|
126
|
-
}
|
|
127
|
-
console.log("");
|
|
128
|
-
if (logPath) {
|
|
129
|
-
console.log(colors.muted(` đ Log: ${logPath}`));
|
|
130
|
-
console.log("");
|
|
131
|
-
}
|
|
132
|
-
if (results.length > 1 && passed > 0 && !config.dryRun) {
|
|
133
|
-
console.log(colors.muted(" đĄ Verify batch integration before merging:"));
|
|
134
|
-
console.log(colors.muted(" sequant merge --check"));
|
|
135
|
-
console.log("");
|
|
136
|
-
}
|
|
137
|
-
if (config.dryRun) {
|
|
138
|
-
console.log(colors.warning(" âšī¸ This was a dry run. Use without --dry-run to execute."));
|
|
139
|
-
console.log("");
|
|
140
|
-
}
|
|
141
|
-
return failed > 0 && !config.dryRun ? 1 : 0;
|
|
142
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: sequant-explorer
|
|
3
|
-
description: Codebase exploration agent for sequant /spec phase. Searches for existing patterns, components, database schemas, and file structures. Use when gathering context before planning a feature implementation.
|
|
4
|
-
# Note: per anthropics/claude-code#43869 this is currently a no-op; agent runs on parent's model
|
|
5
|
-
model: haiku
|
|
6
|
-
maxTurns: 15
|
|
7
|
-
tools:
|
|
8
|
-
- Read
|
|
9
|
-
- Grep
|
|
10
|
-
- Glob
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
You are an exploration agent for the sequant development workflow.
|
|
14
|
-
|
|
15
|
-
Your job is to search the codebase for existing patterns, components, and structures relevant to a planned feature.
|
|
16
|
-
|
|
17
|
-
Rules:
|
|
18
|
-
- Search thoroughly across relevant directories
|
|
19
|
-
- Report findings in structured format: file paths, patterns discovered, recommendations
|
|
20
|
-
- Do NOT modify any files
|
|
21
|
-
- Do NOT run shell commands
|
|
22
|
-
- Send results back via SendMessage when complete
|
|
23
|
-
- All grep commands must use `|| true` to prevent exit code 1 on zero matches
|
|
24
|
-
- Focus on actionable findings that inform implementation decisions
|