sequant 1.15.2 → 1.15.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/dist/bin/cli.js +4 -0
- package/dist/src/commands/logs.js +15 -0
- package/dist/src/commands/run.d.ts +150 -1
- package/dist/src/commands/run.js +642 -31
- package/dist/src/commands/stats.js +48 -0
- package/dist/src/lib/scope/index.d.ts +1 -0
- package/dist/src/lib/scope/index.js +2 -0
- package/dist/src/lib/scope/settings-converter.d.ts +28 -0
- package/dist/src/lib/scope/settings-converter.js +53 -0
- package/dist/src/lib/settings.d.ts +45 -0
- package/dist/src/lib/settings.js +30 -0
- package/dist/src/lib/test-tautology-detector.d.ts +122 -0
- package/dist/src/lib/test-tautology-detector.js +488 -0
- package/dist/src/lib/workflow/git-diff-utils.d.ts +39 -0
- package/dist/src/lib/workflow/git-diff-utils.js +142 -0
- package/dist/src/lib/workflow/log-writer.d.ts +13 -2
- package/dist/src/lib/workflow/log-writer.js +25 -3
- package/dist/src/lib/workflow/metrics-schema.d.ts +9 -0
- package/dist/src/lib/workflow/metrics-schema.js +10 -1
- package/dist/src/lib/workflow/phase-detection.d.ts +3 -0
- package/dist/src/lib/workflow/phase-detection.js +27 -1
- package/dist/src/lib/workflow/qa-cache.d.ts +3 -1
- package/dist/src/lib/workflow/qa-cache.js +2 -0
- package/dist/src/lib/workflow/run-log-schema.d.ts +90 -3
- package/dist/src/lib/workflow/run-log-schema.js +44 -2
- package/dist/src/lib/workflow/state-utils.d.ts +46 -0
- package/dist/src/lib/workflow/state-utils.js +167 -0
- package/dist/src/lib/workflow/token-utils.d.ts +92 -0
- package/dist/src/lib/workflow/token-utils.js +170 -0
- package/dist/src/lib/workflow/types.d.ts +10 -0
- package/dist/src/lib/workflow/types.js +1 -0
- package/package.json +1 -1
- package/templates/hooks/pre-tool.sh +4 -0
- package/templates/skills/assess/SKILL.md +1 -1
- package/templates/skills/exec/SKILL.md +6 -4
- package/templates/skills/improve/SKILL.md +37 -24
- package/templates/skills/loop/SKILL.md +3 -3
- package/templates/skills/qa/references/code-review-checklist.md +10 -11
- package/templates/skills/qa/scripts/quality-checks.sh +16 -0
- package/templates/skills/security-review/references/security-checklists.md +89 -36
- package/templates/skills/solve/SKILL.md +3 -1
- package/templates/skills/spec/SKILL.md +8 -4
package/dist/bin/cli.js
CHANGED
|
@@ -139,7 +139,11 @@ program
|
|
|
139
139
|
.option("--qa-gate", "Wait for QA pass before starting next issue in chain (requires --chain)")
|
|
140
140
|
.option("--base <branch>", "Base branch for worktree creation (default: main or settings.run.defaultBase)")
|
|
141
141
|
.option("--no-mcp", "Disable MCP server injection in headless mode")
|
|
142
|
+
.option("--no-retry", "Disable automatic retry with MCP fallback (useful for debugging)")
|
|
142
143
|
.option("--resume", "Resume from last completed phase (reads phase markers from GitHub)")
|
|
144
|
+
.option("--no-rebase", "Skip pre-PR rebase onto origin/main (use when you want to handle rebasing manually)")
|
|
145
|
+
.option("--no-pr", "Skip PR creation after successful QA (manual PR workflow)")
|
|
146
|
+
.option("-f, --force", "Force re-execution of completed issues (bypass pre-flight state guard)")
|
|
143
147
|
.action(runCommand);
|
|
144
148
|
program
|
|
145
149
|
.command("logs")
|
|
@@ -112,6 +112,21 @@ function displayLogSummary(log, filename) {
|
|
|
112
112
|
const phaseDuration = chalk.gray(`(${formatDuration(phase.durationSeconds)})`);
|
|
113
113
|
const error = phase.error ? chalk.red(` - ${phase.error}`) : "";
|
|
114
114
|
console.log(` ${phaseStatus} ${phase.phase} ${phaseDuration}${error}`);
|
|
115
|
+
// Show observability data (AC-9)
|
|
116
|
+
if (phase.commitHash) {
|
|
117
|
+
console.log(chalk.gray(` commit: ${phase.commitHash.slice(0, 8)}`));
|
|
118
|
+
}
|
|
119
|
+
if (phase.filesModified && phase.filesModified.length > 0) {
|
|
120
|
+
console.log(chalk.gray(` files: ${phase.filesModified.length} modified`));
|
|
121
|
+
}
|
|
122
|
+
if (phase.fileDiffStats && phase.fileDiffStats.length > 0) {
|
|
123
|
+
const totalAdditions = phase.fileDiffStats.reduce((sum, f) => sum + f.additions, 0);
|
|
124
|
+
const totalDeletions = phase.fileDiffStats.reduce((sum, f) => sum + f.deletions, 0);
|
|
125
|
+
console.log(chalk.gray(` diff: +${totalAdditions}/-${totalDeletions} lines`));
|
|
126
|
+
}
|
|
127
|
+
if (phase.cacheMetrics) {
|
|
128
|
+
console.log(chalk.gray(` cache: ${phase.cacheMetrics.hits} hits, ${phase.cacheMetrics.misses} misses, ${phase.cacheMetrics.skipped} skipped`));
|
|
129
|
+
}
|
|
115
130
|
}
|
|
116
131
|
}
|
|
117
132
|
}
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
* Runs the Sequant workflow (/spec → /exec → /qa) for one or more issues
|
|
5
5
|
* using the Claude Agent SDK for proper skill invocation.
|
|
6
6
|
*/
|
|
7
|
-
import { Phase, QaVerdict } from "../lib/workflow/types.js";
|
|
7
|
+
import { Phase, ExecutionConfig, PhaseResult, QaVerdict } from "../lib/workflow/types.js";
|
|
8
|
+
import { ShutdownManager } from "../lib/shutdown.js";
|
|
9
|
+
import { PhaseSpinner } from "../lib/phase-spinner.js";
|
|
8
10
|
/**
|
|
9
11
|
* Parse QA verdict from phase output
|
|
10
12
|
*
|
|
@@ -17,6 +19,36 @@ import { Phase, QaVerdict } from "../lib/workflow/types.js";
|
|
|
17
19
|
* @returns The parsed verdict or null if not found
|
|
18
20
|
*/
|
|
19
21
|
export declare function parseQaVerdict(output: string): QaVerdict | null;
|
|
22
|
+
/**
|
|
23
|
+
* Result of worktree freshness check
|
|
24
|
+
*/
|
|
25
|
+
interface WorktreeFreshnessResult {
|
|
26
|
+
/** True if worktree is stale (significantly behind main) */
|
|
27
|
+
isStale: boolean;
|
|
28
|
+
/** Number of commits behind origin/main */
|
|
29
|
+
commitsBehind: number;
|
|
30
|
+
/** True if worktree has uncommitted changes */
|
|
31
|
+
hasUncommittedChanges: boolean;
|
|
32
|
+
/** True if worktree has unpushed commits */
|
|
33
|
+
hasUnpushedCommits: boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Check if a worktree is stale (behind origin/main) and should be recreated
|
|
37
|
+
*
|
|
38
|
+
* @param worktreePath - Path to the worktree
|
|
39
|
+
* @param verbose - Enable verbose output
|
|
40
|
+
* @returns Freshness check result
|
|
41
|
+
*/
|
|
42
|
+
export declare function checkWorktreeFreshness(worktreePath: string, verbose: boolean): WorktreeFreshnessResult;
|
|
43
|
+
/**
|
|
44
|
+
* Remove and recreate a stale worktree
|
|
45
|
+
*
|
|
46
|
+
* @param existingPath - Path to existing worktree
|
|
47
|
+
* @param branch - Branch name
|
|
48
|
+
* @param verbose - Enable verbose output
|
|
49
|
+
* @returns true if worktree was removed
|
|
50
|
+
*/
|
|
51
|
+
export declare function removeStaleWorktree(existingPath: string, branch: string, verbose: boolean): boolean;
|
|
20
52
|
/**
|
|
21
53
|
* List all active worktrees with their branches
|
|
22
54
|
*/
|
|
@@ -59,6 +91,75 @@ export declare function filterResumedPhases(issueNumber: number, phases: Phase[]
|
|
|
59
91
|
* @internal Exported for testing
|
|
60
92
|
*/
|
|
61
93
|
export declare function createCheckpointCommit(worktreePath: string, issueNumber: number, verbose: boolean): boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Check if any lockfile changed during a rebase and re-run install if needed.
|
|
96
|
+
* This prevents dependency drift when the lockfile was updated on main.
|
|
97
|
+
* @param worktreePath Path to the worktree
|
|
98
|
+
* @param packageManager Package manager to use for install
|
|
99
|
+
* @param verbose Whether to show verbose output
|
|
100
|
+
* @param preRebaseRef Git ref pointing to pre-rebase HEAD (defaults to ORIG_HEAD,
|
|
101
|
+
* which git sets automatically after rebase). Using ORIG_HEAD captures all
|
|
102
|
+
* lockfile changes across multi-commit rebases, unlike HEAD~1 which only
|
|
103
|
+
* checks the last commit.
|
|
104
|
+
* @returns true if reinstall was performed, false otherwise
|
|
105
|
+
* @internal Exported for testing
|
|
106
|
+
*/
|
|
107
|
+
export declare function reinstallIfLockfileChanged(worktreePath: string, packageManager: string | undefined, verbose: boolean, preRebaseRef?: string): boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Result of a pre-PR rebase operation
|
|
110
|
+
*/
|
|
111
|
+
export interface RebaseResult {
|
|
112
|
+
/** Whether the rebase was performed */
|
|
113
|
+
performed: boolean;
|
|
114
|
+
/** Whether the rebase succeeded */
|
|
115
|
+
success: boolean;
|
|
116
|
+
/** Whether dependencies were reinstalled */
|
|
117
|
+
reinstalled: boolean;
|
|
118
|
+
/** Error message if rebase failed */
|
|
119
|
+
error?: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Rebase the worktree branch onto origin/main before PR creation.
|
|
123
|
+
* This ensures the branch is up-to-date and prevents lockfile drift.
|
|
124
|
+
*
|
|
125
|
+
* @param worktreePath Path to the worktree
|
|
126
|
+
* @param issueNumber Issue number (for logging)
|
|
127
|
+
* @param packageManager Package manager to use if reinstall needed
|
|
128
|
+
* @param verbose Whether to show verbose output
|
|
129
|
+
* @returns RebaseResult indicating success/failure and whether reinstall was performed
|
|
130
|
+
* @internal Exported for testing
|
|
131
|
+
*/
|
|
132
|
+
export declare function rebaseBeforePR(worktreePath: string, issueNumber: number, packageManager: string | undefined, verbose: boolean): RebaseResult;
|
|
133
|
+
/**
|
|
134
|
+
* Result of PR creation
|
|
135
|
+
*/
|
|
136
|
+
export interface PRCreationResult {
|
|
137
|
+
/** Whether PR creation was attempted */
|
|
138
|
+
attempted: boolean;
|
|
139
|
+
/** Whether PR was created successfully (or already existed) */
|
|
140
|
+
success: boolean;
|
|
141
|
+
/** PR number */
|
|
142
|
+
prNumber?: number;
|
|
143
|
+
/** PR URL */
|
|
144
|
+
prUrl?: string;
|
|
145
|
+
/** Error message if failed */
|
|
146
|
+
error?: string;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Push branch and create a PR after successful QA.
|
|
150
|
+
*
|
|
151
|
+
* Handles both fresh PR creation and detection of existing PRs.
|
|
152
|
+
* Failures are warnings — they don't fail the run.
|
|
153
|
+
*
|
|
154
|
+
* @param worktreePath Path to the worktree
|
|
155
|
+
* @param issueNumber Issue number
|
|
156
|
+
* @param issueTitle Issue title (for PR title)
|
|
157
|
+
* @param branch Branch name
|
|
158
|
+
* @param verbose Whether to show verbose output
|
|
159
|
+
* @returns PRCreationResult with PR info or error
|
|
160
|
+
* @internal Exported for testing
|
|
161
|
+
*/
|
|
162
|
+
export declare function createPR(worktreePath: string, issueNumber: number, issueTitle: string, branch: string, verbose: boolean, labels?: string[]): PRCreationResult;
|
|
62
163
|
/**
|
|
63
164
|
* Detect phases based on issue labels (like /solve logic)
|
|
64
165
|
*/
|
|
@@ -124,7 +225,55 @@ interface RunOptions {
|
|
|
124
225
|
* Reads phase markers from GitHub issue comments and skips completed phases.
|
|
125
226
|
*/
|
|
126
227
|
resume?: boolean;
|
|
228
|
+
/**
|
|
229
|
+
* Disable automatic retry with MCP fallback.
|
|
230
|
+
* When true, no retry attempts are made on phase failure.
|
|
231
|
+
* Useful for debugging to see the actual failure without retry masking it.
|
|
232
|
+
*/
|
|
233
|
+
noRetry?: boolean;
|
|
234
|
+
/**
|
|
235
|
+
* Skip pre-PR rebase onto origin/main.
|
|
236
|
+
* When true, branches are not rebased before creating the PR.
|
|
237
|
+
* Use when you want to preserve branch state or handle rebasing manually.
|
|
238
|
+
*/
|
|
239
|
+
noRebase?: boolean;
|
|
240
|
+
/**
|
|
241
|
+
* Skip PR creation after successful QA.
|
|
242
|
+
* When true, branches are pushed but no PR is created.
|
|
243
|
+
* Useful for manual workflows where PRs are created separately.
|
|
244
|
+
*/
|
|
245
|
+
noPr?: boolean;
|
|
246
|
+
/**
|
|
247
|
+
* Force re-execution of issues even if they have completed status.
|
|
248
|
+
* Bypasses the pre-flight state guard that skips ready_for_merge/merged issues.
|
|
249
|
+
*/
|
|
250
|
+
force?: boolean;
|
|
127
251
|
}
|
|
252
|
+
/**
|
|
253
|
+
* Execute a single phase for an issue using Claude Agent SDK
|
|
254
|
+
*/
|
|
255
|
+
declare function executePhase(issueNumber: number, phase: Phase, config: ExecutionConfig, sessionId?: string, worktreePath?: string, shutdownManager?: ShutdownManager, spinner?: PhaseSpinner): Promise<PhaseResult & {
|
|
256
|
+
sessionId?: string;
|
|
257
|
+
}>;
|
|
258
|
+
/**
|
|
259
|
+
* Execute a phase with automatic retry for cold-start failures and MCP fallback.
|
|
260
|
+
*
|
|
261
|
+
* Retry strategy:
|
|
262
|
+
* 1. If phase fails within COLD_START_THRESHOLD_SECONDS, retry up to COLD_START_MAX_RETRIES times
|
|
263
|
+
* 2. If still failing and MCP is enabled, retry once with MCP disabled (npx-based MCP servers
|
|
264
|
+
* can fail on first run due to cold-cache issues)
|
|
265
|
+
*
|
|
266
|
+
* The MCP fallback is safe because MCP servers are optional enhancements, not required
|
|
267
|
+
* for core functionality.
|
|
268
|
+
*/
|
|
269
|
+
/**
|
|
270
|
+
* @internal Exported for testing only
|
|
271
|
+
*/
|
|
272
|
+
export declare function executePhaseWithRetry(issueNumber: number, phase: Phase, config: ExecutionConfig, sessionId?: string, worktreePath?: string, shutdownManager?: ShutdownManager, spinner?: PhaseSpinner,
|
|
273
|
+
/** @internal Injected for testing — defaults to module-level executePhase */
|
|
274
|
+
executePhaseFn?: typeof executePhase): Promise<PhaseResult & {
|
|
275
|
+
sessionId?: string;
|
|
276
|
+
}>;
|
|
128
277
|
/**
|
|
129
278
|
* Main run command
|
|
130
279
|
*/
|