sequant 1.15.1 → 1.15.3

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 (48) hide show
  1. package/.claude-plugin/marketplace.json +4 -4
  2. package/.claude-plugin/plugin.json +3 -3
  3. package/README.md +3 -3
  4. package/dist/bin/cli.js +3 -0
  5. package/dist/src/commands/init.js +1 -1
  6. package/dist/src/commands/logs.js +15 -0
  7. package/dist/src/commands/run.d.ts +114 -1
  8. package/dist/src/commands/run.js +513 -31
  9. package/dist/src/commands/stats.js +48 -0
  10. package/dist/src/lib/scope/index.d.ts +1 -0
  11. package/dist/src/lib/scope/index.js +2 -0
  12. package/dist/src/lib/scope/settings-converter.d.ts +28 -0
  13. package/dist/src/lib/scope/settings-converter.js +53 -0
  14. package/dist/src/lib/settings.d.ts +45 -0
  15. package/dist/src/lib/settings.js +30 -0
  16. package/dist/src/lib/test-tautology-detector.d.ts +122 -0
  17. package/dist/src/lib/test-tautology-detector.js +488 -0
  18. package/dist/src/lib/upstream/issues.js +5 -5
  19. package/dist/src/lib/workflow/git-diff-utils.d.ts +39 -0
  20. package/dist/src/lib/workflow/git-diff-utils.js +142 -0
  21. package/dist/src/lib/workflow/log-writer.d.ts +9 -2
  22. package/dist/src/lib/workflow/log-writer.js +9 -3
  23. package/dist/src/lib/workflow/metrics-schema.d.ts +9 -0
  24. package/dist/src/lib/workflow/metrics-schema.js +10 -1
  25. package/dist/src/lib/workflow/phase-detection.d.ts +3 -0
  26. package/dist/src/lib/workflow/phase-detection.js +27 -1
  27. package/dist/src/lib/workflow/qa-cache.d.ts +3 -1
  28. package/dist/src/lib/workflow/qa-cache.js +2 -0
  29. package/dist/src/lib/workflow/run-log-schema.d.ts +90 -3
  30. package/dist/src/lib/workflow/run-log-schema.js +44 -2
  31. package/dist/src/lib/workflow/state-utils.d.ts +46 -0
  32. package/dist/src/lib/workflow/state-utils.js +167 -0
  33. package/dist/src/lib/workflow/token-utils.d.ts +92 -0
  34. package/dist/src/lib/workflow/token-utils.js +170 -0
  35. package/dist/src/lib/workflow/types.d.ts +6 -0
  36. package/dist/src/lib/workflow/types.js +1 -0
  37. package/package.json +4 -4
  38. package/templates/hooks/pre-tool.sh +4 -0
  39. package/templates/skills/assess/SKILL.md +1 -1
  40. package/templates/skills/exec/SKILL.md +5 -4
  41. package/templates/skills/improve/SKILL.md +37 -24
  42. package/templates/skills/loop/SKILL.md +3 -3
  43. package/templates/skills/qa/SKILL.md +66 -1
  44. package/templates/skills/qa/references/code-review-checklist.md +10 -11
  45. package/templates/skills/qa/scripts/quality-checks.sh +16 -0
  46. package/templates/skills/security-review/references/security-checklists.md +89 -36
  47. package/templates/skills/solve/SKILL.md +3 -1
  48. package/templates/skills/spec/SKILL.md +8 -4
@@ -3,8 +3,8 @@
3
3
  "name": "sequant",
4
4
  "description": "Sequant plugin marketplace - structured workflow system for Claude Code",
5
5
  "owner": {
6
- "name": "admarble",
7
- "email": "github@admarble.com"
6
+ "name": "sequant-io",
7
+ "email": "hello@sequant.io"
8
8
  },
9
9
  "plugins": [
10
10
  {
@@ -12,8 +12,8 @@
12
12
  "description": "Structured workflow system for Claude Code - GitHub issue resolution with spec, exec, test, and QA phases. Includes 16 skills for planning, implementation, testing, code review, and quality assurance.",
13
13
  "version": "1.13.0",
14
14
  "author": {
15
- "name": "admarble",
16
- "email": "github@admarble.com"
15
+ "name": "sequant-io",
16
+ "email": "hello@sequant.io"
17
17
  },
18
18
  "source": "./",
19
19
  "category": "workflow"
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "sequant",
3
3
  "description": "Structured workflow system for Claude Code - GitHub issue resolution with spec, exec, test, and QA phases",
4
- "version": "1.15.1",
4
+ "version": "1.15.3",
5
5
  "author": {
6
- "name": "admarble",
7
- "email": "github@admarble.com"
6
+ "name": "sequant-io",
7
+ "email": "hello@sequant.io"
8
8
  }
9
9
  }
package/README.md CHANGED
@@ -238,9 +238,9 @@ Stack guides: [Next.js](docs/stacks/nextjs.md) · [Rust](docs/stacks/rust.md) ·
238
238
 
239
239
  ### Reporting Issues
240
240
 
241
- - **Bug reports:** [Bug template](https://github.com/admarble/sequant/issues/new?template=bug.yml)
242
- - **Feature requests:** [Feature template](https://github.com/admarble/sequant/issues/new?template=feature.yml)
243
- - **Questions:** [GitHub Discussions](https://github.com/admarble/sequant/discussions)
241
+ - **Bug reports:** [Bug template](https://github.com/sequant-io/sequant/issues/new?template=bug.yml)
242
+ - **Feature requests:** [Feature template](https://github.com/sequant-io/sequant/issues/new?template=feature.yml)
243
+ - **Questions:** [GitHub Discussions](https://github.com/sequant-io/sequant/discussions)
244
244
 
245
245
  ### Using `/improve` for Feedback
246
246
 
package/dist/bin/cli.js CHANGED
@@ -139,7 +139,10 @@ 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("-f, --force", "Force re-execution of completed issues (bypass pre-flight state guard)")
143
146
  .action(runCommand);
144
147
  program
145
148
  .command("logs")
@@ -407,5 +407,5 @@ export async function initCommand(options) {
407
407
  if (optionalSection) {
408
408
  console.log(optionalSection);
409
409
  }
410
- console.log(chalk.gray("\nDocumentation: https://github.com/admarble/sequant#readme\n"));
410
+ console.log(chalk.gray("\nDocumentation: https://github.com/sequant-io/sequant#readme\n"));
411
411
  }
@@ -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,45 @@ 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;
62
133
  /**
63
134
  * Detect phases based on issue labels (like /solve logic)
64
135
  */
@@ -124,7 +195,49 @@ interface RunOptions {
124
195
  * Reads phase markers from GitHub issue comments and skips completed phases.
125
196
  */
126
197
  resume?: boolean;
198
+ /**
199
+ * Disable automatic retry with MCP fallback.
200
+ * When true, no retry attempts are made on phase failure.
201
+ * Useful for debugging to see the actual failure without retry masking it.
202
+ */
203
+ noRetry?: boolean;
204
+ /**
205
+ * Skip pre-PR rebase onto origin/main.
206
+ * When true, branches are not rebased before creating the PR.
207
+ * Use when you want to preserve branch state or handle rebasing manually.
208
+ */
209
+ noRebase?: boolean;
210
+ /**
211
+ * Force re-execution of issues even if they have completed status.
212
+ * Bypasses the pre-flight state guard that skips ready_for_merge/merged issues.
213
+ */
214
+ force?: boolean;
127
215
  }
216
+ /**
217
+ * Execute a single phase for an issue using Claude Agent SDK
218
+ */
219
+ declare function executePhase(issueNumber: number, phase: Phase, config: ExecutionConfig, sessionId?: string, worktreePath?: string, shutdownManager?: ShutdownManager, spinner?: PhaseSpinner): Promise<PhaseResult & {
220
+ sessionId?: string;
221
+ }>;
222
+ /**
223
+ * Execute a phase with automatic retry for cold-start failures and MCP fallback.
224
+ *
225
+ * Retry strategy:
226
+ * 1. If phase fails within COLD_START_THRESHOLD_SECONDS, retry up to COLD_START_MAX_RETRIES times
227
+ * 2. If still failing and MCP is enabled, retry once with MCP disabled (npx-based MCP servers
228
+ * can fail on first run due to cold-cache issues)
229
+ *
230
+ * The MCP fallback is safe because MCP servers are optional enhancements, not required
231
+ * for core functionality.
232
+ */
233
+ /**
234
+ * @internal Exported for testing only
235
+ */
236
+ export declare function executePhaseWithRetry(issueNumber: number, phase: Phase, config: ExecutionConfig, sessionId?: string, worktreePath?: string, shutdownManager?: ShutdownManager, spinner?: PhaseSpinner,
237
+ /** @internal Injected for testing — defaults to module-level executePhase */
238
+ executePhaseFn?: typeof executePhase): Promise<PhaseResult & {
239
+ sessionId?: string;
240
+ }>;
128
241
  /**
129
242
  * Main run command
130
243
  */