sequant 1.13.5 → 1.14.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.
Files changed (33) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/dist/bin/cli.js +1 -0
  3. package/dist/src/commands/run.d.ts +21 -0
  4. package/dist/src/commands/run.js +51 -1
  5. package/dist/src/index.d.ts +2 -1
  6. package/dist/src/index.js +2 -0
  7. package/dist/src/lib/cli-ui.d.ts +1 -1
  8. package/dist/src/lib/cli-ui.js +12 -14
  9. package/dist/src/lib/scope/analyzer.d.ts +91 -0
  10. package/dist/src/lib/scope/analyzer.js +310 -0
  11. package/dist/src/lib/scope/formatter.d.ts +52 -0
  12. package/dist/src/lib/scope/formatter.js +169 -0
  13. package/dist/src/lib/scope/index.d.ts +36 -0
  14. package/dist/src/lib/scope/index.js +73 -0
  15. package/dist/src/lib/scope/types.d.ts +198 -0
  16. package/dist/src/lib/scope/types.js +60 -0
  17. package/dist/src/lib/scope/verdict.d.ts +80 -0
  18. package/dist/src/lib/scope/verdict.js +173 -0
  19. package/dist/src/lib/settings.d.ts +33 -0
  20. package/dist/src/lib/settings.js +21 -0
  21. package/dist/src/lib/workflow/phase-detection.d.ts +114 -0
  22. package/dist/src/lib/workflow/phase-detection.js +215 -0
  23. package/dist/src/lib/workflow/state-manager.d.ts +11 -0
  24. package/dist/src/lib/workflow/state-manager.js +26 -0
  25. package/dist/src/lib/workflow/state-schema.d.ts +103 -0
  26. package/dist/src/lib/workflow/state-schema.js +20 -0
  27. package/package.json +1 -1
  28. package/templates/skills/exec/SKILL.md +50 -1
  29. package/templates/skills/fullsolve/SKILL.md +47 -1
  30. package/templates/skills/qa/SKILL.md +47 -1
  31. package/templates/skills/security-review/SKILL.md +0 -1
  32. package/templates/skills/spec/SKILL.md +39 -1
  33. package/templates/skills/testgen/SKILL.md +1 -0
@@ -60,6 +60,35 @@ export declare const PhaseSchema: z.ZodEnum<{
60
60
  merger: "merger";
61
61
  }>;
62
62
  export type Phase = z.infer<typeof PhaseSchema>;
63
+ /**
64
+ * Phase marker stored in GitHub issue comments for cross-session detection.
65
+ *
66
+ * Embedded as HTML comments: `<!-- SEQUANT_PHASE: {...} -->`
67
+ */
68
+ export declare const PhaseMarkerSchema: z.ZodObject<{
69
+ phase: z.ZodEnum<{
70
+ loop: "loop";
71
+ verify: "verify";
72
+ spec: "spec";
73
+ exec: "exec";
74
+ qa: "qa";
75
+ "security-review": "security-review";
76
+ testgen: "testgen";
77
+ test: "test";
78
+ merger: "merger";
79
+ }>;
80
+ status: z.ZodEnum<{
81
+ pending: "pending";
82
+ skipped: "skipped";
83
+ completed: "completed";
84
+ in_progress: "in_progress";
85
+ failed: "failed";
86
+ }>;
87
+ timestamp: z.ZodString;
88
+ pr: z.ZodOptional<z.ZodNumber>;
89
+ error: z.ZodOptional<z.ZodString>;
90
+ }, z.core.$strip>;
91
+ export type PhaseMarker = z.infer<typeof PhaseMarkerSchema>;
63
92
  /**
64
93
  * Individual phase state within an issue
65
94
  */
@@ -246,6 +275,43 @@ export declare const IssueStateSchema: z.ZodObject<{
246
275
  blocked: z.ZodNumber;
247
276
  }, z.core.$strip>;
248
277
  }, z.core.$strip>>;
278
+ scopeAssessment: z.ZodOptional<z.ZodObject<{
279
+ assessedAt: z.ZodString;
280
+ skipped: z.ZodBoolean;
281
+ skipReason: z.ZodOptional<z.ZodString>;
282
+ verdict: z.ZodEnum<{
283
+ SCOPE_OK: "SCOPE_OK";
284
+ SCOPE_WARNING: "SCOPE_WARNING";
285
+ SCOPE_SPLIT_RECOMMENDED: "SCOPE_SPLIT_RECOMMENDED";
286
+ }>;
287
+ metrics: z.ZodArray<z.ZodObject<{
288
+ name: z.ZodString;
289
+ value: z.ZodNumber;
290
+ status: z.ZodEnum<{
291
+ red: "red";
292
+ green: "green";
293
+ yellow: "yellow";
294
+ }>;
295
+ }, z.core.$strip>>;
296
+ featureDetection: z.ZodObject<{
297
+ featureCount: z.ZodNumber;
298
+ clusters: z.ZodArray<z.ZodObject<{
299
+ keyword: z.ZodString;
300
+ acIds: z.ZodArray<z.ZodString>;
301
+ count: z.ZodNumber;
302
+ }, z.core.$strip>>;
303
+ multipleVerbs: z.ZodBoolean;
304
+ titleVerbs: z.ZodArray<z.ZodString>;
305
+ directorySpread: z.ZodNumber;
306
+ directories: z.ZodArray<z.ZodString>;
307
+ }, z.core.$strip>;
308
+ nonGoals: z.ZodObject<{
309
+ items: z.ZodArray<z.ZodString>;
310
+ found: z.ZodBoolean;
311
+ warning: z.ZodOptional<z.ZodString>;
312
+ }, z.core.$strip>;
313
+ recommendation: z.ZodString;
314
+ }, z.core.$strip>>;
249
315
  sessionId: z.ZodOptional<z.ZodString>;
250
316
  lastActivity: z.ZodString;
251
317
  createdAt: z.ZodString;
@@ -334,6 +400,43 @@ export declare const WorkflowStateSchema: z.ZodObject<{
334
400
  blocked: z.ZodNumber;
335
401
  }, z.core.$strip>;
336
402
  }, z.core.$strip>>;
403
+ scopeAssessment: z.ZodOptional<z.ZodObject<{
404
+ assessedAt: z.ZodString;
405
+ skipped: z.ZodBoolean;
406
+ skipReason: z.ZodOptional<z.ZodString>;
407
+ verdict: z.ZodEnum<{
408
+ SCOPE_OK: "SCOPE_OK";
409
+ SCOPE_WARNING: "SCOPE_WARNING";
410
+ SCOPE_SPLIT_RECOMMENDED: "SCOPE_SPLIT_RECOMMENDED";
411
+ }>;
412
+ metrics: z.ZodArray<z.ZodObject<{
413
+ name: z.ZodString;
414
+ value: z.ZodNumber;
415
+ status: z.ZodEnum<{
416
+ red: "red";
417
+ green: "green";
418
+ yellow: "yellow";
419
+ }>;
420
+ }, z.core.$strip>>;
421
+ featureDetection: z.ZodObject<{
422
+ featureCount: z.ZodNumber;
423
+ clusters: z.ZodArray<z.ZodObject<{
424
+ keyword: z.ZodString;
425
+ acIds: z.ZodArray<z.ZodString>;
426
+ count: z.ZodNumber;
427
+ }, z.core.$strip>>;
428
+ multipleVerbs: z.ZodBoolean;
429
+ titleVerbs: z.ZodArray<z.ZodString>;
430
+ directorySpread: z.ZodNumber;
431
+ directories: z.ZodArray<z.ZodString>;
432
+ }, z.core.$strip>;
433
+ nonGoals: z.ZodObject<{
434
+ items: z.ZodArray<z.ZodString>;
435
+ found: z.ZodBoolean;
436
+ warning: z.ZodOptional<z.ZodString>;
437
+ }, z.core.$strip>;
438
+ recommendation: z.ZodString;
439
+ }, z.core.$strip>>;
337
440
  sessionId: z.ZodOptional<z.ZodString>;
338
441
  lastActivity: z.ZodString;
339
442
  createdAt: z.ZodString;
@@ -17,6 +17,7 @@
17
17
  * ```
18
18
  */
19
19
  import { z } from "zod";
20
+ import { ScopeAssessmentSchema } from "../scope/types.js";
20
21
  /**
21
22
  * Workflow phases in order of execution
22
23
  */
@@ -67,6 +68,23 @@ export const PhaseSchema = z.enum([
67
68
  "loop",
68
69
  "merger",
69
70
  ]);
71
+ /**
72
+ * Phase marker stored in GitHub issue comments for cross-session detection.
73
+ *
74
+ * Embedded as HTML comments: `<!-- SEQUANT_PHASE: {...} -->`
75
+ */
76
+ export const PhaseMarkerSchema = z.object({
77
+ /** The workflow phase */
78
+ phase: PhaseSchema,
79
+ /** Phase completion status */
80
+ status: PhaseStatusSchema,
81
+ /** ISO 8601 timestamp */
82
+ timestamp: z.string().datetime(),
83
+ /** PR number if created during this phase */
84
+ pr: z.number().int().positive().optional(),
85
+ /** Error message if phase failed */
86
+ error: z.string().optional(),
87
+ });
70
88
  /**
71
89
  * Individual phase state within an issue
72
90
  */
@@ -178,6 +196,8 @@ export const IssueStateSchema = z.object({
178
196
  loop: LoopStateSchema.optional(),
179
197
  /** Acceptance criteria tracking (if extracted by /spec) */
180
198
  acceptanceCriteria: AcceptanceCriteriaSchema.optional(),
199
+ /** Scope assessment result (if performed by /spec) */
200
+ scopeAssessment: ScopeAssessmentSchema.optional(),
181
201
  /** Claude session ID (for resume) */
182
202
  sessionId: z.string().optional(),
183
203
  /** Most recent activity timestamp */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sequant",
3
- "version": "1.13.5",
3
+ "version": "1.14.1",
4
4
  "description": "Quantize your development workflow - Sequential AI phases with quality gates",
5
5
  "type": "module",
6
6
  "bin": {
@@ -37,7 +37,7 @@ allowed-tools:
37
37
  - mcp__context7__* # Library documentation lookup - falls back to web search if unavailable
38
38
  - mcp__sequential-thinking__* # Complex reasoning - falls back to standard analysis if unavailable
39
39
  # Task management
40
- - Task
40
+ - Task(general-purpose)
41
41
  - TodoWrite
42
42
  ---
43
43
 
@@ -56,6 +56,55 @@ When invoked as `/exec`, your job is to:
56
56
  5. Iterate until the AC appear satisfied or clear blockers are reached.
57
57
  6. Draft a progress update for the GitHub issue.
58
58
 
59
+ ## Phase Detection (Smart Resumption)
60
+
61
+ **Before executing**, check if this phase has already been completed or if prerequisites are met:
62
+
63
+ ```bash
64
+ # Check for existing phase markers
65
+ phase_data=$(gh issue view <issue-number> --json comments --jq '[.comments[].body]' | \
66
+ grep -o '{[^}]*}' | grep '"phase"' | tail -1)
67
+
68
+ if [[ -n "$phase_data" ]]; then
69
+ phase=$(echo "$phase_data" | jq -r '.phase')
70
+ status=$(echo "$phase_data" | jq -r '.status')
71
+
72
+ # Skip if exec is already completed
73
+ if [[ "$phase" == "exec" && "$status" == "completed" ]]; then
74
+ echo "⏭️ Exec phase already completed. Skipping."
75
+ # Exit early — no work needed
76
+ fi
77
+
78
+ # Resume if exec previously failed
79
+ if [[ "$phase" == "exec" && "$status" == "failed" ]]; then
80
+ echo "🔄 Exec phase previously failed. Resuming from failure point."
81
+ # Continue execution — will retry the implementation
82
+ fi
83
+ fi
84
+ ```
85
+
86
+ **Behavior:**
87
+ - If `exec:completed` → Skip with message
88
+ - If `exec:failed` → Resume (retry implementation)
89
+ - If `spec:completed` (no exec marker) → Normal execution
90
+ - If no markers found → Normal execution (fresh start)
91
+ - If detection fails (API error) → Fall through to normal execution
92
+
93
+ **Phase Marker Emission:**
94
+
95
+ When posting the progress update comment to GitHub, append a phase marker at the end:
96
+
97
+ ```markdown
98
+ <!-- SEQUANT_PHASE: {"phase":"exec","status":"completed","timestamp":"<ISO-8601>","pr":<PR_NUMBER>} -->
99
+ ```
100
+
101
+ If exec fails, emit a failure marker:
102
+ ```markdown
103
+ <!-- SEQUANT_PHASE: {"phase":"exec","status":"failed","timestamp":"<ISO-8601>","error":"<error message>"} -->
104
+ ```
105
+
106
+ Include this marker in every `gh issue comment` that represents phase completion or failure.
107
+
59
108
  ## Behavior
60
109
 
61
110
  Invocation:
@@ -13,7 +13,7 @@ allowed-tools:
13
13
  - Grep
14
14
  - Bash
15
15
  - TodoWrite
16
- - Task
16
+ - Skill # For invoking child skills (/spec, /exec, /test, /qa)
17
17
  # Optional MCP tools (enhanced functionality if available)
18
18
  - mcp__chrome-devtools__* # Browser testing - falls back to manual checklist if unavailable
19
19
  - mcp__sequential-thinking__* # Complex reasoning - falls back to standard analysis if unavailable
@@ -90,6 +90,52 @@ When invoked as `/fullsolve <issue-number>`, execute the complete issue resoluti
90
90
  /fullsolve 218 --max-iterations 5 # Override max fix iterations
91
91
  ```
92
92
 
93
+ ## Phase Detection (Smart Resumption)
94
+
95
+ **Before starting any phase**, detect the current workflow state from GitHub issue comments to enable smart resumption:
96
+
97
+ ```bash
98
+ # Get all phase markers from issue comments
99
+ comments_json=$(gh issue view <issue-number> --json comments --jq '[.comments[].body]')
100
+ markers=$(echo "$comments_json" | grep -o '{[^}]*}' | grep '"phase"')
101
+
102
+ if [[ -n "$markers" ]]; then
103
+ echo "Phase markers detected:"
104
+ echo "$markers" | jq -r '" \(.phase): \(.status)"'
105
+
106
+ # Determine resume point
107
+ latest_completed=$(echo "$markers" | jq -r 'select(.status == "completed") | .phase' | tail -1)
108
+ latest_failed=$(echo "$markers" | jq -r 'select(.status == "failed") | .phase' | tail -1)
109
+
110
+ echo "Latest completed: ${latest_completed:-none}"
111
+ echo "Latest failed: ${latest_failed:-none}"
112
+ fi
113
+ ```
114
+
115
+ **Resume Logic:**
116
+
117
+ | Detected State | Action |
118
+ |---------------|--------|
119
+ | No markers | Start from Phase 1 (spec) — fresh start |
120
+ | `spec:completed` | Skip to Phase 2 (exec) |
121
+ | `exec:completed` | Skip to Phase 3 (test) or Phase 4 (qa) |
122
+ | `exec:failed` | Resume at Phase 2 (exec) — retry |
123
+ | `test:completed` | Skip to Phase 4 (qa) |
124
+ | `qa:completed` | Skip to Phase 5 (PR) |
125
+ | `qa:failed` | Resume at Phase 4 (qa) — retry with /loop |
126
+ | All completed | Skip to PR creation (if no PR exists) |
127
+
128
+ **Backward Compatibility:**
129
+ - Issues without markers → treat as fresh start (no phase detection)
130
+ - If detection fails (API error) → fall through to standard Phase 0 checks
131
+
132
+ **Phase Marker Emission:**
133
+
134
+ When posting progress comments after each phase, append the appropriate marker:
135
+ ```markdown
136
+ <!-- SEQUANT_PHASE: {"phase":"<phase>","status":"<completed|failed>","timestamp":"<ISO-8601>"} -->
137
+ ```
138
+
93
139
  ## Phase 0: Pre-flight Checks
94
140
 
95
141
  **CRITICAL after context restoration:** Before starting any work, verify the current git state to avoid duplicate work.
@@ -19,7 +19,7 @@ allowed-tools:
19
19
  - Bash(semgrep:*)
20
20
  - Bash(npx semgrep:*)
21
21
  - Bash(npx tsx scripts/semgrep-scan.ts:*)
22
- - Task
22
+ - Task(general-purpose)
23
23
  - AgentOutputTool
24
24
  ---
25
25
 
@@ -37,6 +37,52 @@ When invoked as `/qa`, your job is to:
37
37
  4. Assess whether the change is "A+ status" or needs more work.
38
38
  5. Draft a GitHub review/QA comment summarizing findings and recommendations.
39
39
 
40
+ ## Phase Detection (Smart Resumption)
41
+
42
+ **Before executing**, check if the exec phase has been completed (prerequisite for QA):
43
+
44
+ ```bash
45
+ # Check for existing phase markers
46
+ comments_json=$(gh issue view <issue-number> --json comments --jq '[.comments[].body]')
47
+ exec_completed=$(echo "$comments_json" | \
48
+ grep -o '{[^}]*}' | grep '"phase"' | \
49
+ jq -r 'select(.phase == "exec" and .status == "completed")' 2>/dev/null)
50
+
51
+ if [[ -z "$exec_completed" ]]; then
52
+ # Check if any exec marker exists at all
53
+ exec_any=$(echo "$comments_json" | \
54
+ grep -o '{[^}]*}' | grep '"phase"' | \
55
+ jq -r 'select(.phase == "exec")' 2>/dev/null)
56
+
57
+ if [[ -n "$exec_any" ]]; then
58
+ echo "⚠️ Exec phase not completed (status: $(echo "$exec_any" | jq -r '.status')). Run /exec first."
59
+ else
60
+ echo "ℹ️ No phase markers found — proceeding with QA (may be a fresh issue or legacy workflow)."
61
+ fi
62
+ fi
63
+ ```
64
+
65
+ **Behavior:**
66
+ - If `exec:completed` marker found → Normal QA execution
67
+ - If `exec:failed` or `exec:in_progress` → Warn "Exec not complete, run /exec first" (but don't block — QA may still be useful for partial review)
68
+ - If no markers found → Normal execution (backward compatible)
69
+ - If detection fails (API error) → Fall through to normal execution
70
+
71
+ **Phase Marker Emission:**
72
+
73
+ When posting the QA review comment to GitHub, append a phase marker at the end:
74
+
75
+ ```markdown
76
+ <!-- SEQUANT_PHASE: {"phase":"qa","status":"completed","timestamp":"<ISO-8601>"} -->
77
+ ```
78
+
79
+ If QA determines AC_NOT_MET, emit:
80
+ ```markdown
81
+ <!-- SEQUANT_PHASE: {"phase":"qa","status":"failed","timestamp":"<ISO-8601>","error":"AC_NOT_MET"} -->
82
+ ```
83
+
84
+ Include this marker in every `gh issue comment` that represents QA completion.
85
+
40
86
  ## Behavior
41
87
 
42
88
  Invocation:
@@ -9,7 +9,6 @@ allowed-tools:
9
9
  - Read
10
10
  - Glob
11
11
  - Grep
12
- - Task
13
12
  - Bash(git diff:*)
14
13
  - Bash(git status:*)
15
14
  - Bash(git log:*)
@@ -13,7 +13,7 @@ allowed-tools:
13
13
  - Bash(gh label:*)
14
14
  - Bash(git worktree:*)
15
15
  - Bash(git -C:*)
16
- - Task
16
+ - Task(Explore)
17
17
  - AgentOutputTool
18
18
  ---
19
19
 
@@ -30,6 +30,44 @@ When invoked as `/spec`, your job is to:
30
30
  3. Identify ambiguities, gaps, or risks.
31
31
  4. Draft a GitHub issue comment summarizing AC + the agreed plan.
32
32
 
33
+ ## Phase Detection (Smart Resumption)
34
+
35
+ **Before executing**, check if this phase has already been completed by reading phase markers from issue comments:
36
+
37
+ ```bash
38
+ # Check for existing phase markers
39
+ phase_data=$(gh issue view <issue-number> --json comments --jq '[.comments[].body]' | \
40
+ grep -o '{[^}]*}' | grep '"phase"' | tail -1)
41
+
42
+ if [[ -n "$phase_data" ]]; then
43
+ phase=$(echo "$phase_data" | jq -r '.phase')
44
+ status=$(echo "$phase_data" | jq -r '.status')
45
+
46
+ # Skip if spec is already completed or a later phase is completed
47
+ if [[ "$phase" == "spec" && "$status" == "completed" ]] || \
48
+ [[ "$phase" == "exec" || "$phase" == "test" || "$phase" == "qa" ]]; then
49
+ echo "⏭️ Spec phase already completed (detected: $phase:$status). Skipping."
50
+ # Exit early — no work needed
51
+ fi
52
+ fi
53
+ ```
54
+
55
+ **Behavior:**
56
+ - If `spec:completed` or a later phase is detected → Skip with message
57
+ - If `spec:failed` → Re-run spec (retry)
58
+ - If no markers found → Normal execution (fresh start)
59
+ - If detection fails (API error) → Fall through to normal execution
60
+
61
+ **Phase Marker Emission:**
62
+
63
+ When posting the spec plan comment to GitHub, append a phase marker at the end:
64
+
65
+ ```markdown
66
+ <!-- SEQUANT_PHASE: {"phase":"spec","status":"completed","timestamp":"<ISO-8601>"} -->
67
+ ```
68
+
69
+ Include this marker in every `gh issue comment` that represents phase completion.
70
+
33
71
  ## Behavior
34
72
 
35
73
  When called like `/spec 123`:
@@ -17,6 +17,7 @@ allowed-tools:
17
17
  - Bash(git worktree list:*)
18
18
  - Bash(ls:*)
19
19
  - Bash(mkdir:*)
20
+ - Task(general-purpose)
20
21
  ---
21
22
 
22
23
  # Test Generation Command