sequant 1.20.3 → 2.0.1
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 +2 -4
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +36 -15
- package/dist/bin/cli.js +25 -2
- package/dist/src/commands/doctor.js +42 -9
- package/dist/src/commands/init.d.ts +1 -0
- package/dist/src/commands/init.js +52 -0
- package/dist/src/commands/logs.d.ts +1 -0
- package/dist/src/commands/logs.js +18 -2
- package/dist/src/commands/run.d.ts +7 -0
- package/dist/src/commands/run.js +235 -68
- package/dist/src/commands/serve.d.ts +13 -0
- package/dist/src/commands/serve.js +131 -0
- package/dist/src/commands/stats.d.ts +1 -0
- package/dist/src/commands/stats.js +185 -26
- package/dist/src/commands/status.d.ts +2 -0
- package/dist/src/commands/status.js +99 -50
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.js +4 -1
- package/dist/src/lib/ac-parser.d.ts +2 -0
- package/dist/src/lib/ac-parser.js +12 -2
- package/dist/src/lib/assess-comment-parser.d.ts +137 -0
- package/dist/src/lib/assess-comment-parser.js +344 -0
- package/dist/src/lib/ci/config.d.ts +22 -0
- package/dist/src/lib/ci/config.js +134 -0
- package/dist/src/lib/ci/index.d.ts +12 -0
- package/dist/src/lib/ci/index.js +10 -0
- package/dist/src/lib/ci/inputs.d.ts +29 -0
- package/dist/src/lib/ci/inputs.js +103 -0
- package/dist/src/lib/ci/labels.d.ts +34 -0
- package/dist/src/lib/ci/labels.js +101 -0
- package/dist/src/lib/ci/outputs.d.ts +25 -0
- package/dist/src/lib/ci/outputs.js +84 -0
- package/dist/src/lib/ci/triggers.d.ts +9 -0
- package/dist/src/lib/ci/triggers.js +86 -0
- package/dist/src/lib/ci/types.d.ts +131 -0
- package/dist/src/lib/ci/types.js +47 -0
- package/dist/src/lib/mcp-config.d.ts +54 -0
- package/dist/src/lib/mcp-config.js +172 -0
- package/dist/src/lib/merge-check/index.js +6 -12
- package/dist/src/lib/merge-check/types.d.ts +20 -7
- package/dist/src/lib/merge-check/types.js +11 -0
- package/dist/src/lib/phase-signal.d.ts +3 -3
- package/dist/src/lib/phase-signal.js +5 -3
- package/dist/src/lib/settings.d.ts +52 -0
- package/dist/src/lib/settings.js +41 -0
- package/dist/src/lib/shutdown.d.ts +16 -5
- package/dist/src/lib/shutdown.js +32 -12
- package/dist/src/lib/solve-comment-parser.d.ts +9 -102
- package/dist/src/lib/solve-comment-parser.js +13 -248
- package/dist/src/lib/stacks.d.ts +8 -0
- package/dist/src/lib/stacks.js +34 -0
- package/dist/src/lib/system.js +3 -7
- package/dist/src/lib/test-tautology-detector.d.ts +10 -0
- package/dist/src/lib/test-tautology-detector.js +43 -4
- package/dist/src/lib/upstream/assessment.js +9 -59
- package/dist/src/lib/upstream/issues.js +12 -75
- package/dist/src/lib/version-check.d.ts +2 -2
- package/dist/src/lib/version-check.js +6 -3
- package/dist/src/lib/version.d.ts +4 -0
- package/dist/src/lib/version.js +25 -0
- package/dist/src/lib/workflow/batch-executor.d.ts +26 -86
- package/dist/src/lib/workflow/batch-executor.js +269 -55
- package/dist/src/lib/workflow/drivers/agent-driver.d.ts +56 -0
- package/dist/src/lib/workflow/drivers/agent-driver.js +8 -0
- package/dist/src/lib/workflow/drivers/aider.d.ts +18 -0
- package/dist/src/lib/workflow/drivers/aider.js +160 -0
- package/dist/src/lib/workflow/drivers/claude-code.d.ts +17 -0
- package/dist/src/lib/workflow/drivers/claude-code.js +165 -0
- package/dist/src/lib/workflow/drivers/index.d.ts +20 -0
- package/dist/src/lib/workflow/drivers/index.js +27 -0
- package/dist/src/lib/workflow/error-classifier.d.ts +16 -0
- package/dist/src/lib/workflow/error-classifier.js +90 -0
- package/dist/src/lib/workflow/log-writer.d.ts +6 -3
- package/dist/src/lib/workflow/log-writer.js +57 -27
- package/dist/src/lib/workflow/metrics-schema.d.ts +9 -9
- package/dist/src/lib/workflow/phase-detection.d.ts +23 -0
- package/dist/src/lib/workflow/phase-detection.js +45 -29
- package/dist/src/lib/workflow/phase-executor.d.ts +42 -3
- package/dist/src/lib/workflow/phase-executor.js +375 -229
- package/dist/src/lib/workflow/phase-mapper.d.ts +1 -1
- package/dist/src/lib/workflow/phase-mapper.js +7 -7
- package/dist/src/lib/workflow/platforms/github.d.ts +157 -0
- package/dist/src/lib/workflow/platforms/github.js +466 -0
- package/dist/src/lib/workflow/platforms/index.d.ts +17 -0
- package/dist/src/lib/workflow/platforms/index.js +25 -0
- package/dist/src/lib/workflow/platforms/platform-provider.d.ts +67 -0
- package/dist/src/lib/workflow/platforms/platform-provider.js +8 -0
- package/dist/src/lib/workflow/pr-status.d.ts +2 -4
- package/dist/src/lib/workflow/pr-status.js +3 -16
- package/dist/src/lib/workflow/qa-cache.d.ts +58 -0
- package/dist/src/lib/workflow/qa-cache.js +88 -0
- package/dist/src/lib/workflow/reconcile.d.ts +69 -0
- package/dist/src/lib/workflow/reconcile.js +290 -0
- package/dist/src/lib/workflow/ring-buffer.d.ts +17 -0
- package/dist/src/lib/workflow/ring-buffer.js +37 -0
- package/dist/src/lib/workflow/run-log-schema.d.ts +115 -24
- package/dist/src/lib/workflow/run-log-schema.js +47 -12
- package/dist/src/lib/workflow/run-reflect.js +1 -1
- package/dist/src/lib/workflow/state-cleanup.js +21 -0
- package/dist/src/lib/workflow/state-manager.d.ts +34 -3
- package/dist/src/lib/workflow/state-manager.js +278 -126
- package/dist/src/lib/workflow/state-schema.d.ts +34 -30
- package/dist/src/lib/workflow/state-schema.js +35 -25
- package/dist/src/lib/workflow/state-utils.d.ts +3 -1
- package/dist/src/lib/workflow/state-utils.js +1 -0
- package/dist/src/lib/workflow/types.d.ts +224 -6
- package/dist/src/lib/workflow/types.js +20 -1
- package/dist/src/lib/workflow/worktree-discovery.d.ts +1 -1
- package/dist/src/lib/workflow/worktree-discovery.js +6 -14
- package/dist/src/lib/workflow/worktree-manager.js +33 -51
- package/dist/src/mcp/index.d.ts +4 -0
- package/dist/src/mcp/index.js +4 -0
- package/dist/src/mcp/resources.d.ts +7 -0
- package/dist/src/mcp/resources.js +111 -0
- package/dist/src/mcp/run-registry.d.ts +34 -0
- package/dist/src/mcp/run-registry.js +42 -0
- package/dist/src/mcp/server.d.ts +12 -0
- package/dist/src/mcp/server.js +50 -0
- package/dist/src/mcp/tools/logs.d.ts +7 -0
- package/dist/src/mcp/tools/logs.js +149 -0
- package/dist/src/mcp/tools/run.d.ts +121 -0
- package/dist/src/mcp/tools/run.js +591 -0
- package/dist/src/mcp/tools/status.d.ts +7 -0
- package/dist/src/mcp/tools/status.js +127 -0
- package/package.json +26 -7
- package/templates/hooks/post-tool.sh +19 -8
- package/templates/hooks/pre-tool.sh +36 -49
- package/templates/mcp.json +6 -0
- package/templates/skills/assess/SKILL.md +354 -352
- package/templates/skills/exec/SKILL.md +64 -1
- package/templates/skills/fullsolve/SKILL.md +35 -4
- package/templates/skills/qa/SKILL.md +486 -9
- package/templates/skills/qa/scripts/quality-checks.sh +1 -1
- package/templates/skills/setup/SKILL.md +386 -0
- package/templates/skills/solve/SKILL.md +38 -664
- 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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
|
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
|
-
/**
|
|
29
|
-
|
|
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,43 @@ 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;
|
|
83
|
+
/**
|
|
84
|
+
* Additional context appended to the phase prompt.
|
|
85
|
+
* Used by the quality loop to pass QA findings directly to the /loop skill
|
|
86
|
+
* so it doesn't need to reconstruct context from GitHub comments.
|
|
87
|
+
*/
|
|
88
|
+
promptContext?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Last QA verdict from a preceding phase.
|
|
91
|
+
* Propagated as SEQUANT_LAST_VERDICT env var to skills.
|
|
92
|
+
*/
|
|
93
|
+
lastVerdict?: string;
|
|
94
|
+
/**
|
|
95
|
+
* Failed AC descriptions from a preceding QA phase.
|
|
96
|
+
* Propagated as SEQUANT_FAILED_ACS env var to skills.
|
|
97
|
+
*/
|
|
98
|
+
failedAcs?: string;
|
|
44
99
|
}
|
|
45
100
|
/**
|
|
46
101
|
* Default execution configuration
|
|
47
102
|
*/
|
|
48
103
|
export declare const DEFAULT_CONFIG: ExecutionConfig;
|
|
49
|
-
import type { QaVerdict } from "./run-log-schema.js";
|
|
50
|
-
export type { QaVerdict } from "./run-log-schema.js";
|
|
104
|
+
import type { QaVerdict, QaSummary } from "./run-log-schema.js";
|
|
105
|
+
export type { QaVerdict, QaSummary } from "./run-log-schema.js";
|
|
51
106
|
/**
|
|
52
107
|
* Result of executing a single phase
|
|
53
108
|
*/
|
|
@@ -60,6 +115,14 @@ export interface PhaseResult {
|
|
|
60
115
|
output?: string;
|
|
61
116
|
/** Parsed QA verdict (only for qa phase) */
|
|
62
117
|
verdict?: QaVerdict;
|
|
118
|
+
/** Condensed QA summary with AC coverage (#434) */
|
|
119
|
+
summary?: QaSummary;
|
|
120
|
+
/** Last N lines of stderr captured from the agent process (#447) */
|
|
121
|
+
stderrTail?: string[];
|
|
122
|
+
/** Last N lines of stdout captured from the agent process (#447) */
|
|
123
|
+
stdoutTail?: string[];
|
|
124
|
+
/** Process exit code from the agent driver (#447) */
|
|
125
|
+
exitCode?: number;
|
|
63
126
|
}
|
|
64
127
|
/**
|
|
65
128
|
* Result of executing all phases for an issue
|
|
@@ -76,6 +139,96 @@ export interface IssueResult {
|
|
|
76
139
|
/** PR URL if created after successful QA */
|
|
77
140
|
prUrl?: string;
|
|
78
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* CLI options for the run command, merged with settings and env config.
|
|
144
|
+
* Moved from batch-executor.ts for use in IssueExecutionContext (#402).
|
|
145
|
+
*/
|
|
146
|
+
export interface RunOptions {
|
|
147
|
+
phases?: string;
|
|
148
|
+
sequential?: boolean;
|
|
149
|
+
dryRun?: boolean;
|
|
150
|
+
verbose?: boolean;
|
|
151
|
+
timeout?: number;
|
|
152
|
+
logJson?: boolean;
|
|
153
|
+
noLog?: boolean;
|
|
154
|
+
logPath?: string;
|
|
155
|
+
qualityLoop?: boolean;
|
|
156
|
+
maxIterations?: number;
|
|
157
|
+
batch?: string[];
|
|
158
|
+
smartTests?: boolean;
|
|
159
|
+
noSmartTests?: boolean;
|
|
160
|
+
testgen?: boolean;
|
|
161
|
+
autoDetectPhases?: boolean;
|
|
162
|
+
/** Enable automatic worktree creation for issue isolation */
|
|
163
|
+
worktreeIsolation?: boolean;
|
|
164
|
+
/** Reuse existing worktrees instead of creating new ones */
|
|
165
|
+
reuseWorktrees?: boolean;
|
|
166
|
+
/** Suppress version warnings and non-essential output */
|
|
167
|
+
quiet?: boolean;
|
|
168
|
+
/** Chain issues: each branches from previous (requires --sequential) */
|
|
169
|
+
chain?: boolean;
|
|
170
|
+
/**
|
|
171
|
+
* Wait for QA pass before starting next issue in chain mode.
|
|
172
|
+
* When enabled, the chain pauses if QA fails, preventing downstream issues
|
|
173
|
+
* from building on potentially broken code.
|
|
174
|
+
*/
|
|
175
|
+
qaGate?: boolean;
|
|
176
|
+
/**
|
|
177
|
+
* Base branch for worktree creation.
|
|
178
|
+
* Resolution priority: this CLI flag → settings.run.defaultBase → 'main'
|
|
179
|
+
*/
|
|
180
|
+
base?: string;
|
|
181
|
+
/**
|
|
182
|
+
* Disable MCP servers in headless mode.
|
|
183
|
+
* When true, MCPs are not passed to the SDK (faster/cheaper runs).
|
|
184
|
+
* Resolution priority: this CLI flag → settings.run.mcp → default (true)
|
|
185
|
+
*/
|
|
186
|
+
noMcp?: boolean;
|
|
187
|
+
/**
|
|
188
|
+
* Resume from last completed phase.
|
|
189
|
+
* Reads phase markers from GitHub issue comments and skips completed phases.
|
|
190
|
+
*/
|
|
191
|
+
resume?: boolean;
|
|
192
|
+
/**
|
|
193
|
+
* Disable automatic retry with MCP fallback.
|
|
194
|
+
* When true, no retry attempts are made on phase failure.
|
|
195
|
+
* Useful for debugging to see the actual failure without retry masking it.
|
|
196
|
+
*/
|
|
197
|
+
noRetry?: boolean;
|
|
198
|
+
/**
|
|
199
|
+
* Skip pre-PR rebase onto the base branch.
|
|
200
|
+
* When true, branches are not rebased before creating the PR.
|
|
201
|
+
* Use when you want to preserve branch state or handle rebasing manually.
|
|
202
|
+
*/
|
|
203
|
+
noRebase?: boolean;
|
|
204
|
+
/**
|
|
205
|
+
* Skip PR creation after successful QA.
|
|
206
|
+
* When true, branches are pushed but no PR is created.
|
|
207
|
+
* Useful for manual workflows where PRs are created separately.
|
|
208
|
+
*/
|
|
209
|
+
noPr?: 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;
|
|
215
|
+
/**
|
|
216
|
+
* Analyze run results and suggest workflow improvements.
|
|
217
|
+
* Displays observations about timing patterns, phase mismatches, and
|
|
218
|
+
* actionable suggestions after the summary output.
|
|
219
|
+
*/
|
|
220
|
+
reflect?: boolean;
|
|
221
|
+
/**
|
|
222
|
+
* Max concurrent issues in parallel mode (default: 3).
|
|
223
|
+
* Only applies when --sequential is not set.
|
|
224
|
+
*/
|
|
225
|
+
concurrency?: number;
|
|
226
|
+
/**
|
|
227
|
+
* Agent driver for phase execution.
|
|
228
|
+
* Default: "claude-code"
|
|
229
|
+
*/
|
|
230
|
+
agent?: string;
|
|
231
|
+
}
|
|
79
232
|
/**
|
|
80
233
|
* CLI arguments for run command
|
|
81
234
|
*/
|
|
@@ -104,3 +257,68 @@ export interface BatchResult {
|
|
|
104
257
|
issueResults: IssueResult[];
|
|
105
258
|
success: boolean;
|
|
106
259
|
}
|
|
260
|
+
/**
|
|
261
|
+
* Callback type for per-phase progress updates.
|
|
262
|
+
* Used by parallel mode in run.ts to render phase status to the terminal.
|
|
263
|
+
*/
|
|
264
|
+
export type ProgressCallback = (issue: number, phase: string, event: "start" | "complete" | "failed", extra?: {
|
|
265
|
+
durationSeconds?: number;
|
|
266
|
+
error?: string;
|
|
267
|
+
}) => void;
|
|
268
|
+
/**
|
|
269
|
+
* Shared context for executing a batch of issues.
|
|
270
|
+
* Replaces 11 positional parameters in executeBatch (#402).
|
|
271
|
+
*/
|
|
272
|
+
export interface BatchExecutionContext {
|
|
273
|
+
config: ExecutionConfig;
|
|
274
|
+
options: RunOptions;
|
|
275
|
+
issueInfoMap: Map<number, {
|
|
276
|
+
title: string;
|
|
277
|
+
labels: string[];
|
|
278
|
+
}>;
|
|
279
|
+
worktreeMap: Map<number, WorktreeInfo>;
|
|
280
|
+
logWriter: LogWriter | null;
|
|
281
|
+
stateManager: StateManager | null;
|
|
282
|
+
shutdownManager?: ShutdownManager;
|
|
283
|
+
packageManager?: string;
|
|
284
|
+
baseBranch?: string;
|
|
285
|
+
onProgress?: ProgressCallback;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Context object for executing a single issue through the workflow.
|
|
289
|
+
* Replaces 15 positional parameters in runIssueWithLogging (#402).
|
|
290
|
+
*/
|
|
291
|
+
export interface IssueExecutionContext {
|
|
292
|
+
/** GitHub issue number */
|
|
293
|
+
issueNumber: number;
|
|
294
|
+
/** Issue title for display and PR creation */
|
|
295
|
+
title: string;
|
|
296
|
+
/** GitHub labels for phase detection and issue type */
|
|
297
|
+
labels: string[];
|
|
298
|
+
/** Execution configuration (phases, timeouts, flags) */
|
|
299
|
+
config: ExecutionConfig;
|
|
300
|
+
/** CLI options merged with settings and env */
|
|
301
|
+
options: RunOptions;
|
|
302
|
+
/** Services used during execution */
|
|
303
|
+
services: {
|
|
304
|
+
logWriter: LogWriter | null;
|
|
305
|
+
stateManager: StateManager | null;
|
|
306
|
+
shutdownManager?: ShutdownManager;
|
|
307
|
+
};
|
|
308
|
+
/** Worktree info (when worktree isolation is enabled) */
|
|
309
|
+
worktree?: {
|
|
310
|
+
path: string;
|
|
311
|
+
branch: string;
|
|
312
|
+
};
|
|
313
|
+
/** Chain mode settings */
|
|
314
|
+
chain?: {
|
|
315
|
+
enabled: boolean;
|
|
316
|
+
isLast: boolean;
|
|
317
|
+
};
|
|
318
|
+
/** Package manager name (e.g., "npm", "pnpm") */
|
|
319
|
+
packageManager?: string;
|
|
320
|
+
/** Base branch for rebase/PR (e.g., "main") */
|
|
321
|
+
baseBranch?: string;
|
|
322
|
+
/** Per-phase progress callback (used in parallel mode) */
|
|
323
|
+
onProgress?: ProgressCallback;
|
|
324
|
+
}
|
|
@@ -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
|
-
|
|
36
|
+
concurrency: 3,
|
|
37
|
+
parallel: false,
|
|
19
38
|
verbose: false,
|
|
20
39
|
noSmartTests: false,
|
|
21
40
|
dryRun: false,
|
|
@@ -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
|
|
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
|
-
|
|
54
|
-
|
|
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"], {
|