sequant 1.20.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/.claude-plugin/marketplace.json +2 -4
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +29 -9
  4. package/dist/bin/cli.js +25 -2
  5. package/dist/src/commands/doctor.js +42 -9
  6. package/dist/src/commands/init.d.ts +1 -0
  7. package/dist/src/commands/init.js +52 -0
  8. package/dist/src/commands/logs.d.ts +1 -0
  9. package/dist/src/commands/logs.js +18 -2
  10. package/dist/src/commands/run.d.ts +7 -0
  11. package/dist/src/commands/run.js +235 -68
  12. package/dist/src/commands/serve.d.ts +13 -0
  13. package/dist/src/commands/serve.js +131 -0
  14. package/dist/src/commands/stats.d.ts +1 -0
  15. package/dist/src/commands/stats.js +185 -26
  16. package/dist/src/commands/status.d.ts +2 -0
  17. package/dist/src/commands/status.js +99 -50
  18. package/dist/src/index.d.ts +2 -2
  19. package/dist/src/index.js +4 -1
  20. package/dist/src/lib/ac-parser.d.ts +2 -0
  21. package/dist/src/lib/ac-parser.js +12 -2
  22. package/dist/src/lib/assess-comment-parser.d.ts +137 -0
  23. package/dist/src/lib/assess-comment-parser.js +344 -0
  24. package/dist/src/lib/ci/config.d.ts +22 -0
  25. package/dist/src/lib/ci/config.js +134 -0
  26. package/dist/src/lib/ci/index.d.ts +12 -0
  27. package/dist/src/lib/ci/index.js +10 -0
  28. package/dist/src/lib/ci/inputs.d.ts +29 -0
  29. package/dist/src/lib/ci/inputs.js +103 -0
  30. package/dist/src/lib/ci/labels.d.ts +34 -0
  31. package/dist/src/lib/ci/labels.js +101 -0
  32. package/dist/src/lib/ci/outputs.d.ts +25 -0
  33. package/dist/src/lib/ci/outputs.js +84 -0
  34. package/dist/src/lib/ci/triggers.d.ts +9 -0
  35. package/dist/src/lib/ci/triggers.js +86 -0
  36. package/dist/src/lib/ci/types.d.ts +131 -0
  37. package/dist/src/lib/ci/types.js +47 -0
  38. package/dist/src/lib/mcp-config.d.ts +54 -0
  39. package/dist/src/lib/mcp-config.js +172 -0
  40. package/dist/src/lib/merge-check/index.js +6 -12
  41. package/dist/src/lib/merge-check/types.d.ts +20 -7
  42. package/dist/src/lib/merge-check/types.js +11 -0
  43. package/dist/src/lib/phase-signal.d.ts +3 -3
  44. package/dist/src/lib/phase-signal.js +5 -3
  45. package/dist/src/lib/settings.d.ts +52 -0
  46. package/dist/src/lib/settings.js +41 -0
  47. package/dist/src/lib/shutdown.d.ts +16 -5
  48. package/dist/src/lib/shutdown.js +32 -12
  49. package/dist/src/lib/solve-comment-parser.d.ts +9 -102
  50. package/dist/src/lib/solve-comment-parser.js +13 -248
  51. package/dist/src/lib/stacks.d.ts +8 -0
  52. package/dist/src/lib/stacks.js +34 -0
  53. package/dist/src/lib/system.js +3 -7
  54. package/dist/src/lib/test-tautology-detector.d.ts +10 -0
  55. package/dist/src/lib/test-tautology-detector.js +43 -4
  56. package/dist/src/lib/upstream/assessment.js +9 -59
  57. package/dist/src/lib/upstream/issues.js +12 -75
  58. package/dist/src/lib/version-check.d.ts +2 -2
  59. package/dist/src/lib/version-check.js +6 -3
  60. package/dist/src/lib/version.d.ts +4 -0
  61. package/dist/src/lib/version.js +25 -0
  62. package/dist/src/lib/workflow/batch-executor.d.ts +18 -86
  63. package/dist/src/lib/workflow/batch-executor.js +232 -55
  64. package/dist/src/lib/workflow/drivers/agent-driver.d.ts +56 -0
  65. package/dist/src/lib/workflow/drivers/agent-driver.js +8 -0
  66. package/dist/src/lib/workflow/drivers/aider.d.ts +18 -0
  67. package/dist/src/lib/workflow/drivers/aider.js +160 -0
  68. package/dist/src/lib/workflow/drivers/claude-code.d.ts +17 -0
  69. package/dist/src/lib/workflow/drivers/claude-code.js +165 -0
  70. package/dist/src/lib/workflow/drivers/index.d.ts +20 -0
  71. package/dist/src/lib/workflow/drivers/index.js +27 -0
  72. package/dist/src/lib/workflow/error-classifier.d.ts +16 -0
  73. package/dist/src/lib/workflow/error-classifier.js +90 -0
  74. package/dist/src/lib/workflow/log-writer.d.ts +6 -3
  75. package/dist/src/lib/workflow/log-writer.js +57 -27
  76. package/dist/src/lib/workflow/metrics-schema.d.ts +9 -9
  77. package/dist/src/lib/workflow/phase-detection.d.ts +23 -0
  78. package/dist/src/lib/workflow/phase-detection.js +45 -29
  79. package/dist/src/lib/workflow/phase-executor.d.ts +42 -3
  80. package/dist/src/lib/workflow/phase-executor.js +345 -220
  81. package/dist/src/lib/workflow/phase-mapper.d.ts +1 -1
  82. package/dist/src/lib/workflow/phase-mapper.js +7 -7
  83. package/dist/src/lib/workflow/platforms/github.d.ts +157 -0
  84. package/dist/src/lib/workflow/platforms/github.js +466 -0
  85. package/dist/src/lib/workflow/platforms/index.d.ts +17 -0
  86. package/dist/src/lib/workflow/platforms/index.js +25 -0
  87. package/dist/src/lib/workflow/platforms/platform-provider.d.ts +67 -0
  88. package/dist/src/lib/workflow/platforms/platform-provider.js +8 -0
  89. package/dist/src/lib/workflow/pr-status.d.ts +2 -4
  90. package/dist/src/lib/workflow/pr-status.js +3 -16
  91. package/dist/src/lib/workflow/qa-cache.d.ts +58 -0
  92. package/dist/src/lib/workflow/qa-cache.js +88 -0
  93. package/dist/src/lib/workflow/reconcile.d.ts +69 -0
  94. package/dist/src/lib/workflow/reconcile.js +290 -0
  95. package/dist/src/lib/workflow/ring-buffer.d.ts +17 -0
  96. package/dist/src/lib/workflow/ring-buffer.js +37 -0
  97. package/dist/src/lib/workflow/run-log-schema.d.ts +115 -24
  98. package/dist/src/lib/workflow/run-log-schema.js +47 -12
  99. package/dist/src/lib/workflow/run-reflect.js +1 -1
  100. package/dist/src/lib/workflow/state-cleanup.js +21 -0
  101. package/dist/src/lib/workflow/state-manager.d.ts +34 -3
  102. package/dist/src/lib/workflow/state-manager.js +278 -126
  103. package/dist/src/lib/workflow/state-schema.d.ts +34 -30
  104. package/dist/src/lib/workflow/state-schema.js +35 -25
  105. package/dist/src/lib/workflow/state-utils.d.ts +3 -1
  106. package/dist/src/lib/workflow/state-utils.js +1 -0
  107. package/dist/src/lib/workflow/types.d.ts +208 -6
  108. package/dist/src/lib/workflow/types.js +20 -1
  109. package/dist/src/lib/workflow/worktree-discovery.d.ts +1 -1
  110. package/dist/src/lib/workflow/worktree-discovery.js +6 -14
  111. package/dist/src/lib/workflow/worktree-manager.js +33 -51
  112. package/dist/src/mcp/index.d.ts +4 -0
  113. package/dist/src/mcp/index.js +4 -0
  114. package/dist/src/mcp/resources.d.ts +7 -0
  115. package/dist/src/mcp/resources.js +111 -0
  116. package/dist/src/mcp/run-registry.d.ts +34 -0
  117. package/dist/src/mcp/run-registry.js +42 -0
  118. package/dist/src/mcp/server.d.ts +12 -0
  119. package/dist/src/mcp/server.js +50 -0
  120. package/dist/src/mcp/tools/logs.d.ts +7 -0
  121. package/dist/src/mcp/tools/logs.js +149 -0
  122. package/dist/src/mcp/tools/run.d.ts +121 -0
  123. package/dist/src/mcp/tools/run.js +591 -0
  124. package/dist/src/mcp/tools/status.d.ts +7 -0
  125. package/dist/src/mcp/tools/status.js +127 -0
  126. package/package.json +10 -1
  127. package/templates/hooks/post-tool.sh +19 -8
  128. package/templates/hooks/pre-tool.sh +36 -49
  129. package/templates/mcp.json +6 -0
  130. package/templates/skills/assess/SKILL.md +354 -352
  131. package/templates/skills/exec/SKILL.md +64 -1
  132. package/templates/skills/fullsolve/SKILL.md +35 -4
  133. package/templates/skills/qa/SKILL.md +486 -9
  134. package/templates/skills/qa/scripts/quality-checks.sh +1 -1
  135. package/templates/skills/setup/SKILL.md +386 -0
  136. package/templates/skills/solve/SKILL.md +38 -664
  137. package/templates/skills/spec/SKILL.md +90 -31
@@ -17,10 +17,11 @@
17
17
  * ```
18
18
  */
19
19
  import { z } from "zod";
20
+ import { PhaseSchema } from "./types.js";
20
21
  /**
21
22
  * Workflow phases in order of execution
22
23
  */
23
- export declare const WORKFLOW_PHASES: readonly ["spec", "security-review", "exec", "testgen", "test", "verify", "qa", "loop", "merger"];
24
+ export declare const WORKFLOW_PHASES: ("qa" | "loop" | "verify" | "spec" | "security-review" | "exec" | "testgen" | "test" | "merger")[];
24
25
  /**
25
26
  * Phase status - tracks individual phase progress
26
27
  */
@@ -28,38 +29,25 @@ export declare const PhaseStatusSchema: z.ZodEnum<{
28
29
  pending: "pending";
29
30
  skipped: "skipped";
30
31
  completed: "completed";
31
- in_progress: "in_progress";
32
32
  failed: "failed";
33
+ in_progress: "in_progress";
33
34
  }>;
34
35
  export type PhaseStatus = z.infer<typeof PhaseStatusSchema>;
35
36
  /**
36
37
  * Issue status - tracks overall issue progress
37
38
  */
38
39
  export declare const IssueStatusSchema: z.ZodEnum<{
40
+ merged: "merged";
39
41
  in_progress: "in_progress";
40
42
  not_started: "not_started";
41
43
  waiting_for_qa_gate: "waiting_for_qa_gate";
42
44
  ready_for_merge: "ready_for_merge";
43
- merged: "merged";
44
45
  blocked: "blocked";
45
46
  abandoned: "abandoned";
46
47
  }>;
47
48
  export type IssueStatus = z.infer<typeof IssueStatusSchema>;
48
- /**
49
- * Phase type
50
- */
51
- export declare const PhaseSchema: z.ZodEnum<{
52
- loop: "loop";
53
- verify: "verify";
54
- spec: "spec";
55
- exec: "exec";
56
- qa: "qa";
57
- "security-review": "security-review";
58
- testgen: "testgen";
59
- test: "test";
60
- merger: "merger";
61
- }>;
62
- export type Phase = z.infer<typeof PhaseSchema>;
49
+ export { PhaseSchema };
50
+ export type { Phase } from "./types.js";
63
51
  /**
64
52
  * Phase marker stored in GitHub issue comments for cross-session detection.
65
53
  *
@@ -67,12 +55,12 @@ export type Phase = z.infer<typeof PhaseSchema>;
67
55
  */
68
56
  export declare const PhaseMarkerSchema: z.ZodObject<{
69
57
  phase: z.ZodEnum<{
58
+ qa: "qa";
70
59
  loop: "loop";
71
60
  verify: "verify";
72
61
  spec: "spec";
73
- exec: "exec";
74
- qa: "qa";
75
62
  "security-review": "security-review";
63
+ exec: "exec";
76
64
  testgen: "testgen";
77
65
  test: "test";
78
66
  merger: "merger";
@@ -81,12 +69,13 @@ export declare const PhaseMarkerSchema: z.ZodObject<{
81
69
  pending: "pending";
82
70
  skipped: "skipped";
83
71
  completed: "completed";
84
- in_progress: "in_progress";
85
72
  failed: "failed";
73
+ in_progress: "in_progress";
86
74
  }>;
87
75
  timestamp: z.ZodString;
88
76
  pr: z.ZodOptional<z.ZodNumber>;
89
77
  error: z.ZodOptional<z.ZodString>;
78
+ commitSHA: z.ZodOptional<z.ZodString>;
90
79
  }, z.core.$strip>;
91
80
  export type PhaseMarker = z.infer<typeof PhaseMarkerSchema>;
92
81
  /**
@@ -97,8 +86,8 @@ export declare const PhaseStateSchema: z.ZodObject<{
97
86
  pending: "pending";
98
87
  skipped: "skipped";
99
88
  completed: "completed";
100
- in_progress: "in_progress";
101
89
  failed: "failed";
90
+ in_progress: "in_progress";
102
91
  }>;
103
92
  startedAt: z.ZodOptional<z.ZodString>;
104
93
  completedAt: z.ZodOptional<z.ZodString>;
@@ -204,23 +193,23 @@ export declare const IssueStateSchema: z.ZodObject<{
204
193
  number: z.ZodNumber;
205
194
  title: z.ZodString;
206
195
  status: z.ZodEnum<{
196
+ merged: "merged";
207
197
  in_progress: "in_progress";
208
198
  not_started: "not_started";
209
199
  waiting_for_qa_gate: "waiting_for_qa_gate";
210
200
  ready_for_merge: "ready_for_merge";
211
- merged: "merged";
212
201
  blocked: "blocked";
213
202
  abandoned: "abandoned";
214
203
  }>;
215
204
  worktree: z.ZodOptional<z.ZodString>;
216
205
  branch: z.ZodOptional<z.ZodString>;
217
206
  currentPhase: z.ZodOptional<z.ZodEnum<{
207
+ qa: "qa";
218
208
  loop: "loop";
219
209
  verify: "verify";
220
210
  spec: "spec";
221
- exec: "exec";
222
- qa: "qa";
223
211
  "security-review": "security-review";
212
+ exec: "exec";
224
213
  testgen: "testgen";
225
214
  test: "test";
226
215
  merger: "merger";
@@ -230,8 +219,8 @@ export declare const IssueStateSchema: z.ZodObject<{
230
219
  pending: "pending";
231
220
  skipped: "skipped";
232
221
  completed: "completed";
233
- in_progress: "in_progress";
234
222
  failed: "failed";
223
+ in_progress: "in_progress";
235
224
  }>;
236
225
  startedAt: z.ZodOptional<z.ZodString>;
237
226
  completedAt: z.ZodOptional<z.ZodString>;
@@ -313,6 +302,7 @@ export declare const IssueStateSchema: z.ZodObject<{
313
302
  recommendation: z.ZodString;
314
303
  }, z.core.$strip>>;
315
304
  sessionId: z.ZodOptional<z.ZodString>;
305
+ resolvedAt: z.ZodOptional<z.ZodString>;
316
306
  lastActivity: z.ZodString;
317
307
  createdAt: z.ZodString;
318
308
  }, z.core.$strip>;
@@ -325,27 +315,28 @@ export type IssueState = z.infer<typeof IssueStateSchema>;
325
315
  export declare const WorkflowStateSchema: z.ZodObject<{
326
316
  version: z.ZodLiteral<1>;
327
317
  lastUpdated: z.ZodString;
318
+ lastSynced: z.ZodOptional<z.ZodString>;
328
319
  issues: z.ZodRecord<z.ZodString, z.ZodObject<{
329
320
  number: z.ZodNumber;
330
321
  title: z.ZodString;
331
322
  status: z.ZodEnum<{
323
+ merged: "merged";
332
324
  in_progress: "in_progress";
333
325
  not_started: "not_started";
334
326
  waiting_for_qa_gate: "waiting_for_qa_gate";
335
327
  ready_for_merge: "ready_for_merge";
336
- merged: "merged";
337
328
  blocked: "blocked";
338
329
  abandoned: "abandoned";
339
330
  }>;
340
331
  worktree: z.ZodOptional<z.ZodString>;
341
332
  branch: z.ZodOptional<z.ZodString>;
342
333
  currentPhase: z.ZodOptional<z.ZodEnum<{
334
+ qa: "qa";
343
335
  loop: "loop";
344
336
  verify: "verify";
345
337
  spec: "spec";
346
- exec: "exec";
347
- qa: "qa";
348
338
  "security-review": "security-review";
339
+ exec: "exec";
349
340
  testgen: "testgen";
350
341
  test: "test";
351
342
  merger: "merger";
@@ -355,8 +346,8 @@ export declare const WorkflowStateSchema: z.ZodObject<{
355
346
  pending: "pending";
356
347
  skipped: "skipped";
357
348
  completed: "completed";
358
- in_progress: "in_progress";
359
349
  failed: "failed";
350
+ in_progress: "in_progress";
360
351
  }>;
361
352
  startedAt: z.ZodOptional<z.ZodString>;
362
353
  completedAt: z.ZodOptional<z.ZodString>;
@@ -438,6 +429,7 @@ export declare const WorkflowStateSchema: z.ZodObject<{
438
429
  recommendation: z.ZodString;
439
430
  }, z.core.$strip>>;
440
431
  sessionId: z.ZodOptional<z.ZodString>;
432
+ resolvedAt: z.ZodOptional<z.ZodString>;
441
433
  lastActivity: z.ZodString;
442
434
  createdAt: z.ZodString;
443
435
  }, z.core.$strip>>;
@@ -476,3 +468,15 @@ export declare function createAcceptanceCriteria(items: AcceptanceCriterion[]):
476
468
  * Update acceptance criteria summary based on item statuses
477
469
  */
478
470
  export declare function updateAcceptanceCriteriaSummary(ac: AcceptanceCriteria): AcceptanceCriteria;
471
+ /**
472
+ * Check if an issue status is terminal (resolved)
473
+ */
474
+ export declare function isTerminalStatus(status: IssueStatus): boolean;
475
+ /**
476
+ * Check if a resolved issue has expired based on TTL.
477
+ *
478
+ * @param entry - The issue state to check
479
+ * @param ttlDays - TTL in days. 0 = never auto-prune, -1 = prune immediately
480
+ * @param now - Current time (for testing)
481
+ */
482
+ export declare function isExpired(entry: IssueState, ttlDays: number, now?: number): boolean;
@@ -18,20 +18,11 @@
18
18
  */
19
19
  import { z } from "zod";
20
20
  import { ScopeAssessmentSchema } from "../scope/types.js";
21
+ import { PhaseSchema } from "./types.js";
21
22
  /**
22
23
  * Workflow phases in order of execution
23
24
  */
24
- export const WORKFLOW_PHASES = [
25
- "spec",
26
- "security-review",
27
- "exec",
28
- "testgen",
29
- "test",
30
- "verify",
31
- "qa",
32
- "loop",
33
- "merger",
34
- ];
25
+ export const WORKFLOW_PHASES = PhaseSchema.options;
35
26
  /**
36
27
  * Phase status - tracks individual phase progress
37
28
  */
@@ -54,20 +45,8 @@ export const IssueStatusSchema = z.enum([
54
45
  "blocked", // Waiting on external input or dependency
55
46
  "abandoned", // Work stopped, will not continue
56
47
  ]);
57
- /**
58
- * Phase type
59
- */
60
- export const PhaseSchema = z.enum([
61
- "spec",
62
- "security-review",
63
- "exec",
64
- "testgen",
65
- "test",
66
- "verify",
67
- "qa",
68
- "loop",
69
- "merger",
70
- ]);
48
+ // Re-export canonical Phase types from types.ts (single source of truth)
49
+ export { PhaseSchema };
71
50
  /**
72
51
  * Phase marker stored in GitHub issue comments for cross-session detection.
73
52
  *
@@ -84,6 +63,8 @@ export const PhaseMarkerSchema = z.object({
84
63
  pr: z.number().int().positive().optional(),
85
64
  /** Error message if phase failed */
86
65
  error: z.string().optional(),
66
+ /** Git HEAD SHA at time of phase completion (used for incremental QA) */
67
+ commitSHA: z.string().optional(),
87
68
  });
88
69
  /**
89
70
  * Individual phase state within an issue
@@ -200,6 +181,8 @@ export const IssueStateSchema = z.object({
200
181
  scopeAssessment: ScopeAssessmentSchema.optional(),
201
182
  /** Claude session ID (for resume) */
202
183
  sessionId: z.string().optional(),
184
+ /** When the issue transitioned to a terminal status (merged/abandoned/closed) */
185
+ resolvedAt: z.string().datetime().optional(),
203
186
  /** Most recent activity timestamp */
204
187
  lastActivity: z.string().datetime(),
205
188
  /** When this issue was first tracked */
@@ -215,6 +198,8 @@ export const WorkflowStateSchema = z.object({
215
198
  version: z.literal(1),
216
199
  /** When the state file was last updated */
217
200
  lastUpdated: z.string().datetime(),
201
+ /** When state was last reconciled with GitHub */
202
+ lastSynced: z.string().datetime().optional(),
218
203
  /** State for all tracked issues, keyed by issue number */
219
204
  issues: z.record(z.string(), IssueStateSchema),
220
205
  });
@@ -307,3 +292,28 @@ export function updateAcceptanceCriteriaSummary(ac) {
307
292
  };
308
293
  return { ...ac, summary };
309
294
  }
295
+ /** Terminal statuses that indicate an issue is resolved */
296
+ const TERMINAL_STATUSES = ["merged", "abandoned"];
297
+ /**
298
+ * Check if an issue status is terminal (resolved)
299
+ */
300
+ export function isTerminalStatus(status) {
301
+ return TERMINAL_STATUSES.includes(status);
302
+ }
303
+ /**
304
+ * Check if a resolved issue has expired based on TTL.
305
+ *
306
+ * @param entry - The issue state to check
307
+ * @param ttlDays - TTL in days. 0 = never auto-prune, -1 = prune immediately
308
+ * @param now - Current time (for testing)
309
+ */
310
+ export function isExpired(entry, ttlDays, now = Date.now()) {
311
+ if (ttlDays === 0)
312
+ return false; // opt-out
313
+ if (!entry.resolvedAt)
314
+ return false; // not resolved
315
+ if (ttlDays < 0)
316
+ return true; // prune immediately
317
+ const age = now - new Date(entry.resolvedAt).getTime();
318
+ return age > ttlDays * 86_400_000;
319
+ }
@@ -24,5 +24,7 @@ export type { RebuildOptions, RebuildResult } from "./state-rebuild.js";
24
24
  export { rebuildStateFromLogs } from "./state-rebuild.js";
25
25
  export type { DiscoverOptions, DiscoveredWorktree, SkippedWorktree, DiscoverResult, } from "./worktree-discovery.js";
26
26
  export { discoverUntrackedWorktrees } from "./worktree-discovery.js";
27
- export type { CleanupOptions, CleanupResult, ReconcileOptions, ReconcileResult, } from "./state-cleanup.js";
27
+ export type { CleanupOptions, CleanupResult, ReconcileOptions as StartupReconcileOptions, ReconcileResult as StartupReconcileResult, } from "./state-cleanup.js";
28
28
  export { cleanupStaleEntries, reconcileStateAtStartup, } from "./state-cleanup.js";
29
+ export type { ReconcileOptions, ReconcileResult, DriftAction, DriftType, } from "./reconcile.js";
30
+ export { reconcileState, classifyDrift, getNextActionHint, formatRelativeTime, } from "./reconcile.js";
@@ -22,3 +22,4 @@ export { checkPRMergeStatus, isBranchMergedIntoMain, isIssueMergedIntoMain, } fr
22
22
  export { rebuildStateFromLogs } from "./state-rebuild.js";
23
23
  export { discoverUntrackedWorktrees } from "./worktree-discovery.js";
24
24
  export { cleanupStaleEntries, reconcileStateAtStartup, } from "./state-cleanup.js";
25
+ export { reconcileState, classifyDrift, getNextActionHint, formatRelativeTime, } from "./reconcile.js";
@@ -1,10 +1,33 @@
1
1
  /**
2
2
  * Core types for workflow execution
3
3
  */
4
+ import { z } from "zod";
5
+ import type { AiderSettings } from "../settings.js";
6
+ import type { LogWriter } from "./log-writer.js";
7
+ import type { StateManager } from "./state-manager.js";
8
+ import type { ShutdownManager } from "../shutdown.js";
9
+ import type { WorktreeInfo } from "./worktree-manager.js";
4
10
  /**
5
- * Available workflow phases
11
+ * Canonical Zod schema for all workflow phases.
12
+ *
13
+ * This is the single source of truth — state-schema.ts and run-log-schema.ts
14
+ * both reference this definition. Add new phases here only.
6
15
  */
7
- export type Phase = "spec" | "security-review" | "testgen" | "exec" | "test" | "qa" | "loop";
16
+ export declare const PhaseSchema: z.ZodEnum<{
17
+ qa: "qa";
18
+ loop: "loop";
19
+ verify: "verify";
20
+ spec: "spec";
21
+ "security-review": "security-review";
22
+ exec: "exec";
23
+ testgen: "testgen";
24
+ test: "test";
25
+ merger: "merger";
26
+ }>;
27
+ /**
28
+ * Available workflow phases (inferred from PhaseSchema)
29
+ */
30
+ export type Phase = z.infer<typeof PhaseSchema>;
8
31
  /**
9
32
  * Default phases for workflow execution
10
33
  */
@@ -25,8 +48,10 @@ export interface ExecutionConfig {
25
48
  skipVerification: boolean;
26
49
  /** Run issues sequentially */
27
50
  sequential: boolean;
28
- /** Force parallel even with dependencies */
29
- forceParallel: boolean;
51
+ /** Max concurrent issues in parallel mode (default: 3) */
52
+ concurrency: number;
53
+ /** Suppress per-issue spinners and console output (set true when running issues concurrently) */
54
+ parallel: boolean;
30
55
  /** Verbose output */
31
56
  verbose: boolean;
32
57
  /** Disable smart test detection */
@@ -41,13 +66,27 @@ export interface ExecutionConfig {
41
66
  * When false (--no-retry flag), no retry attempts are made.
42
67
  */
43
68
  retry?: boolean;
69
+ /**
70
+ * Agent driver to use for phase execution.
71
+ * Default: "claude-code"
72
+ */
73
+ agent?: string;
74
+ /**
75
+ * Aider-specific configuration. Passed to AiderDriver when agent is "aider".
76
+ */
77
+ aiderSettings?: AiderSettings;
78
+ /**
79
+ * Issue type detected from labels (e.g., "docs").
80
+ * Propagated as SEQUANT_ISSUE_TYPE env var to skills.
81
+ */
82
+ issueType?: string;
44
83
  }
45
84
  /**
46
85
  * Default execution configuration
47
86
  */
48
87
  export declare const DEFAULT_CONFIG: ExecutionConfig;
49
- import type { QaVerdict } from "./run-log-schema.js";
50
- export type { QaVerdict } from "./run-log-schema.js";
88
+ import type { QaVerdict, QaSummary } from "./run-log-schema.js";
89
+ export type { QaVerdict, QaSummary } from "./run-log-schema.js";
51
90
  /**
52
91
  * Result of executing a single phase
53
92
  */
@@ -60,6 +99,14 @@ export interface PhaseResult {
60
99
  output?: string;
61
100
  /** Parsed QA verdict (only for qa phase) */
62
101
  verdict?: QaVerdict;
102
+ /** Condensed QA summary with AC coverage (#434) */
103
+ summary?: QaSummary;
104
+ /** Last N lines of stderr captured from the agent process (#447) */
105
+ stderrTail?: string[];
106
+ /** Last N lines of stdout captured from the agent process (#447) */
107
+ stdoutTail?: string[];
108
+ /** Process exit code from the agent driver (#447) */
109
+ exitCode?: number;
63
110
  }
64
111
  /**
65
112
  * Result of executing all phases for an issue
@@ -76,6 +123,96 @@ export interface IssueResult {
76
123
  /** PR URL if created after successful QA */
77
124
  prUrl?: string;
78
125
  }
126
+ /**
127
+ * CLI options for the run command, merged with settings and env config.
128
+ * Moved from batch-executor.ts for use in IssueExecutionContext (#402).
129
+ */
130
+ export interface RunOptions {
131
+ phases?: string;
132
+ sequential?: boolean;
133
+ dryRun?: boolean;
134
+ verbose?: boolean;
135
+ timeout?: number;
136
+ logJson?: boolean;
137
+ noLog?: boolean;
138
+ logPath?: string;
139
+ qualityLoop?: boolean;
140
+ maxIterations?: number;
141
+ batch?: string[];
142
+ smartTests?: boolean;
143
+ noSmartTests?: boolean;
144
+ testgen?: boolean;
145
+ autoDetectPhases?: boolean;
146
+ /** Enable automatic worktree creation for issue isolation */
147
+ worktreeIsolation?: boolean;
148
+ /** Reuse existing worktrees instead of creating new ones */
149
+ reuseWorktrees?: boolean;
150
+ /** Suppress version warnings and non-essential output */
151
+ quiet?: boolean;
152
+ /** Chain issues: each branches from previous (requires --sequential) */
153
+ chain?: boolean;
154
+ /**
155
+ * Wait for QA pass before starting next issue in chain mode.
156
+ * When enabled, the chain pauses if QA fails, preventing downstream issues
157
+ * from building on potentially broken code.
158
+ */
159
+ qaGate?: boolean;
160
+ /**
161
+ * Base branch for worktree creation.
162
+ * Resolution priority: this CLI flag → settings.run.defaultBase → 'main'
163
+ */
164
+ base?: string;
165
+ /**
166
+ * Disable MCP servers in headless mode.
167
+ * When true, MCPs are not passed to the SDK (faster/cheaper runs).
168
+ * Resolution priority: this CLI flag → settings.run.mcp → default (true)
169
+ */
170
+ noMcp?: boolean;
171
+ /**
172
+ * Resume from last completed phase.
173
+ * Reads phase markers from GitHub issue comments and skips completed phases.
174
+ */
175
+ resume?: boolean;
176
+ /**
177
+ * Disable automatic retry with MCP fallback.
178
+ * When true, no retry attempts are made on phase failure.
179
+ * Useful for debugging to see the actual failure without retry masking it.
180
+ */
181
+ noRetry?: boolean;
182
+ /**
183
+ * Skip pre-PR rebase onto the base branch.
184
+ * When true, branches are not rebased before creating the PR.
185
+ * Use when you want to preserve branch state or handle rebasing manually.
186
+ */
187
+ noRebase?: boolean;
188
+ /**
189
+ * Skip PR creation after successful QA.
190
+ * When true, branches are pushed but no PR is created.
191
+ * Useful for manual workflows where PRs are created separately.
192
+ */
193
+ noPr?: boolean;
194
+ /**
195
+ * Force re-execution of issues even if they have completed status.
196
+ * Bypasses the pre-flight state guard that skips ready_for_merge/merged issues.
197
+ */
198
+ force?: boolean;
199
+ /**
200
+ * Analyze run results and suggest workflow improvements.
201
+ * Displays observations about timing patterns, phase mismatches, and
202
+ * actionable suggestions after the summary output.
203
+ */
204
+ reflect?: boolean;
205
+ /**
206
+ * Max concurrent issues in parallel mode (default: 3).
207
+ * Only applies when --sequential is not set.
208
+ */
209
+ concurrency?: number;
210
+ /**
211
+ * Agent driver for phase execution.
212
+ * Default: "claude-code"
213
+ */
214
+ agent?: string;
215
+ }
79
216
  /**
80
217
  * CLI arguments for run command
81
218
  */
@@ -104,3 +241,68 @@ export interface BatchResult {
104
241
  issueResults: IssueResult[];
105
242
  success: boolean;
106
243
  }
244
+ /**
245
+ * Callback type for per-phase progress updates.
246
+ * Used by parallel mode in run.ts to render phase status to the terminal.
247
+ */
248
+ export type ProgressCallback = (issue: number, phase: string, event: "start" | "complete" | "failed", extra?: {
249
+ durationSeconds?: number;
250
+ error?: string;
251
+ }) => void;
252
+ /**
253
+ * Shared context for executing a batch of issues.
254
+ * Replaces 11 positional parameters in executeBatch (#402).
255
+ */
256
+ export interface BatchExecutionContext {
257
+ config: ExecutionConfig;
258
+ options: RunOptions;
259
+ issueInfoMap: Map<number, {
260
+ title: string;
261
+ labels: string[];
262
+ }>;
263
+ worktreeMap: Map<number, WorktreeInfo>;
264
+ logWriter: LogWriter | null;
265
+ stateManager: StateManager | null;
266
+ shutdownManager?: ShutdownManager;
267
+ packageManager?: string;
268
+ baseBranch?: string;
269
+ onProgress?: ProgressCallback;
270
+ }
271
+ /**
272
+ * Context object for executing a single issue through the workflow.
273
+ * Replaces 15 positional parameters in runIssueWithLogging (#402).
274
+ */
275
+ export interface IssueExecutionContext {
276
+ /** GitHub issue number */
277
+ issueNumber: number;
278
+ /** Issue title for display and PR creation */
279
+ title: string;
280
+ /** GitHub labels for phase detection and issue type */
281
+ labels: string[];
282
+ /** Execution configuration (phases, timeouts, flags) */
283
+ config: ExecutionConfig;
284
+ /** CLI options merged with settings and env */
285
+ options: RunOptions;
286
+ /** Services used during execution */
287
+ services: {
288
+ logWriter: LogWriter | null;
289
+ stateManager: StateManager | null;
290
+ shutdownManager?: ShutdownManager;
291
+ };
292
+ /** Worktree info (when worktree isolation is enabled) */
293
+ worktree?: {
294
+ path: string;
295
+ branch: string;
296
+ };
297
+ /** Chain mode settings */
298
+ chain?: {
299
+ enabled: boolean;
300
+ isLast: boolean;
301
+ };
302
+ /** Package manager name (e.g., "npm", "pnpm") */
303
+ packageManager?: string;
304
+ /** Base branch for rebase/PR (e.g., "main") */
305
+ baseBranch?: string;
306
+ /** Per-phase progress callback (used in parallel mode) */
307
+ onProgress?: ProgressCallback;
308
+ }
@@ -1,6 +1,24 @@
1
1
  /**
2
2
  * Core types for workflow execution
3
3
  */
4
+ import { z } from "zod";
5
+ /**
6
+ * Canonical Zod schema for all workflow phases.
7
+ *
8
+ * This is the single source of truth — state-schema.ts and run-log-schema.ts
9
+ * both reference this definition. Add new phases here only.
10
+ */
11
+ export const PhaseSchema = z.enum([
12
+ "spec",
13
+ "security-review",
14
+ "exec",
15
+ "testgen",
16
+ "test",
17
+ "verify",
18
+ "qa",
19
+ "loop",
20
+ "merger",
21
+ ]);
4
22
  /**
5
23
  * Default phases for workflow execution
6
24
  */
@@ -15,7 +33,8 @@ export const DEFAULT_CONFIG = {
15
33
  maxIterations: 3,
16
34
  skipVerification: false,
17
35
  sequential: false,
18
- forceParallel: false,
36
+ concurrency: 3,
37
+ parallel: false,
19
38
  verbose: false,
20
39
  noSmartTests: false,
21
40
  dryRun: false,
@@ -13,7 +13,7 @@
13
13
  * }
14
14
  * ```
15
15
  */
16
- import { type Phase } from "./state-schema.js";
16
+ import { type Phase } from "./types.js";
17
17
  export interface DiscoverOptions {
18
18
  /** State file path (default: .sequant/state.json) */
19
19
  statePath?: string;
@@ -18,6 +18,7 @@ import * as path from "path";
18
18
  import { spawnSync } from "child_process";
19
19
  import { StateManager } from "./state-manager.js";
20
20
  import { RunLogSchema, LOG_PATHS } from "./run-log-schema.js";
21
+ import { GitHubProvider } from "./platforms/github.js";
21
22
  /**
22
23
  * Parse issue number from a branch name
23
24
  *
@@ -44,25 +45,16 @@ function parseIssueNumberFromBranch(branch) {
44
45
  }
45
46
  return null;
46
47
  }
48
+ /** Shared GitHubProvider instance for issue title lookups. */
49
+ const ghProvider = new GitHubProvider();
47
50
  /**
48
- * Fetch issue title from GitHub using gh CLI
51
+ * Fetch issue title from GitHub using GitHubProvider.
49
52
  *
50
53
  * Returns placeholder if gh is not available or fetch fails.
51
54
  */
52
55
  function fetchIssueTitle(issueNumber) {
53
- try {
54
- const result = spawnSync("gh", ["issue", "view", String(issueNumber), "--json", "title", "-q", ".title"], { stdio: "pipe", timeout: 10000 });
55
- if (result.status === 0 && result.stdout) {
56
- const title = result.stdout.toString().trim();
57
- if (title) {
58
- return title;
59
- }
60
- }
61
- }
62
- catch {
63
- // gh not available or error - use placeholder
64
- }
65
- return `(title unavailable for #${issueNumber})`;
56
+ return (ghProvider.fetchIssueTitleSync(String(issueNumber)) ??
57
+ `(title unavailable for #${issueNumber})`);
66
58
  }
67
59
  function getWorktreeDetails() {
68
60
  const result = spawnSync("git", ["worktree", "list", "--porcelain"], {