supipowers 0.2.6 → 0.3.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.
- package/package.json +21 -6
- package/skills/debugging/SKILL.md +54 -15
- package/skills/planning/SKILL.md +70 -10
- package/skills/receiving-code-review/SKILL.md +87 -0
- package/skills/tdd/SKILL.md +83 -0
- package/skills/verification/SKILL.md +54 -0
- package/src/commands/config.ts +53 -23
- package/src/commands/plan.ts +96 -31
- package/src/commands/qa.ts +150 -29
- package/src/commands/release.ts +1 -1
- package/src/commands/review.ts +2 -2
- package/src/commands/run.ts +52 -2
- package/src/commands/update.ts +2 -2
- package/src/discipline/debugging.ts +57 -0
- package/src/discipline/receiving-review.ts +65 -0
- package/src/discipline/tdd.ts +77 -0
- package/src/discipline/verification.ts +68 -0
- package/src/git/branch-finish.ts +101 -0
- package/src/git/worktree.ts +119 -0
- package/src/index.ts +11 -2
- package/src/lsp/detector.ts +2 -2
- package/src/orchestrator/agent-prompts.ts +282 -0
- package/src/orchestrator/dispatcher.ts +150 -1
- package/src/orchestrator/prompts.ts +17 -31
- package/src/planning/plan-reviewer.ts +49 -0
- package/src/planning/plan-writer-prompt.ts +173 -0
- package/src/planning/prompt-builder.ts +178 -0
- package/src/planning/spec-reviewer.ts +43 -0
- package/src/qa/phases/discovery.ts +34 -0
- package/src/qa/phases/execution.ts +65 -0
- package/src/qa/phases/matrix.ts +41 -0
- package/src/qa/phases/reporting.ts +71 -0
- package/src/qa/session.ts +104 -0
- package/src/storage/qa-sessions.ts +83 -0
- package/src/storage/specs.ts +36 -0
- package/src/types.ts +70 -0
- package/src/visual/companion.ts +115 -0
- package/src/visual/prompt-instructions.ts +102 -0
- package/src/visual/scripts/frame-template.html +201 -0
- package/src/visual/scripts/helper.js +88 -0
- package/src/visual/scripts/index.js +148 -0
- package/src/visual/scripts/package.json +10 -0
- package/src/visual/scripts/start-server.sh +98 -0
- package/src/visual/scripts/stop-server.sh +21 -0
- package/src/visual/types.ts +16 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { buildPlanReviewerPrompt } from "./plan-reviewer.js";
|
|
2
|
+
|
|
3
|
+
export interface PlanWriterOptions {
|
|
4
|
+
specPath: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Build the plan writing prompt that guides the agent through creating
|
|
9
|
+
* a comprehensive implementation plan from an approved spec.
|
|
10
|
+
*
|
|
11
|
+
* Follows superpowers' writing-plans skill:
|
|
12
|
+
* - Scope check
|
|
13
|
+
* - File structure mapping
|
|
14
|
+
* - Bite-sized tasks with TDD steps
|
|
15
|
+
* - Plan review loop per chunk
|
|
16
|
+
* - Execution handoff
|
|
17
|
+
*/
|
|
18
|
+
export function buildPlanWriterPrompt(options: PlanWriterOptions): string {
|
|
19
|
+
const { specPath } = options;
|
|
20
|
+
|
|
21
|
+
const sections: string[] = [
|
|
22
|
+
"You are writing a comprehensive implementation plan from an approved design spec.",
|
|
23
|
+
"",
|
|
24
|
+
`**Spec document:** ${specPath}`,
|
|
25
|
+
"",
|
|
26
|
+
"Write the plan assuming the implementing engineer has zero context for this codebase.",
|
|
27
|
+
"Document everything they need: which files to touch, complete code, testing, exact commands.",
|
|
28
|
+
"Give them the whole plan as bite-sized tasks. DRY. YAGNI. TDD. Frequent commits.",
|
|
29
|
+
"",
|
|
30
|
+
|
|
31
|
+
// ── Scope Check ──────────────────────────────────────────────
|
|
32
|
+
"## Scope Check",
|
|
33
|
+
"",
|
|
34
|
+
"If the spec covers multiple independent subsystems, suggest breaking into separate plans.",
|
|
35
|
+
"Each plan should produce working, testable software on its own.",
|
|
36
|
+
"",
|
|
37
|
+
|
|
38
|
+
// ── File Structure ───────────────────────────────────────────
|
|
39
|
+
"## Step 1: Map file structure",
|
|
40
|
+
"",
|
|
41
|
+
"Before defining tasks, map out which files will be created or modified and what each one is responsible for.",
|
|
42
|
+
"This is where decomposition decisions get locked in.",
|
|
43
|
+
"",
|
|
44
|
+
"- Each file should have one clear responsibility with a well-defined interface",
|
|
45
|
+
"- Prefer smaller, focused files over large ones that do too much",
|
|
46
|
+
"- Files that change together should live together — split by responsibility, not by technical layer",
|
|
47
|
+
"- In existing codebases, follow established patterns",
|
|
48
|
+
"",
|
|
49
|
+
|
|
50
|
+
// ── Plan Header ──────────────────────────────────────────────
|
|
51
|
+
"## Step 2: Write Plan Document",
|
|
52
|
+
"",
|
|
53
|
+
"Every plan MUST start with this header:",
|
|
54
|
+
"",
|
|
55
|
+
"```markdown",
|
|
56
|
+
"# [Feature Name] Implementation Plan",
|
|
57
|
+
"",
|
|
58
|
+
"**Goal:** [One sentence describing what this builds]",
|
|
59
|
+
"",
|
|
60
|
+
"**Architecture:** [2-3 sentences about approach]",
|
|
61
|
+
"",
|
|
62
|
+
"**Tech Stack:** [Key technologies/libraries]",
|
|
63
|
+
"",
|
|
64
|
+
"---",
|
|
65
|
+
"```",
|
|
66
|
+
"",
|
|
67
|
+
|
|
68
|
+
// ── Task Granularity ─────────────────────────────────────────
|
|
69
|
+
"## Step 3: Define Bite-Sized Tasks",
|
|
70
|
+
"",
|
|
71
|
+
"Each step is one action (2-5 minutes):",
|
|
72
|
+
"- Write the failing test — one step",
|
|
73
|
+
"- Run it to verify it fails — one step",
|
|
74
|
+
"- Write minimal implementation — one step",
|
|
75
|
+
"- Run tests to verify it passes — one step",
|
|
76
|
+
"- Commit — one step",
|
|
77
|
+
"",
|
|
78
|
+
|
|
79
|
+
// ── Task Structure ───────────────────────────────────────────
|
|
80
|
+
"### Task Structure Template",
|
|
81
|
+
"",
|
|
82
|
+
"````markdown",
|
|
83
|
+
"### Task N: [Component Name]",
|
|
84
|
+
"",
|
|
85
|
+
"**Files:**",
|
|
86
|
+
"- Create: `exact/path/to/file.ts`",
|
|
87
|
+
"- Modify: `exact/path/to/existing.ts:123-145`",
|
|
88
|
+
"- Test: `tests/exact/path/to/test.ts`",
|
|
89
|
+
"",
|
|
90
|
+
"- [ ] **Step 1: Write the failing test**",
|
|
91
|
+
"",
|
|
92
|
+
"```typescript",
|
|
93
|
+
"test('specific behavior', () => {",
|
|
94
|
+
" const result = myFunction(input);",
|
|
95
|
+
" expect(result).toBe(expected);",
|
|
96
|
+
"});",
|
|
97
|
+
"```",
|
|
98
|
+
"",
|
|
99
|
+
"- [ ] **Step 2: Run test to verify it fails**",
|
|
100
|
+
"",
|
|
101
|
+
"Run: `npx vitest run tests/path/test.ts`",
|
|
102
|
+
'Expected: FAIL with "myFunction is not defined"',
|
|
103
|
+
"",
|
|
104
|
+
"- [ ] **Step 3: Write minimal implementation**",
|
|
105
|
+
"",
|
|
106
|
+
"```typescript",
|
|
107
|
+
"export function myFunction(input: string): string {",
|
|
108
|
+
" return expected;",
|
|
109
|
+
"}",
|
|
110
|
+
"```",
|
|
111
|
+
"",
|
|
112
|
+
"- [ ] **Step 4: Run test to verify it passes**",
|
|
113
|
+
"",
|
|
114
|
+
"Run: `npx vitest run tests/path/test.ts`",
|
|
115
|
+
"Expected: PASS",
|
|
116
|
+
"",
|
|
117
|
+
"- [ ] **Step 5: Commit**",
|
|
118
|
+
"",
|
|
119
|
+
"```bash",
|
|
120
|
+
"git add tests/path/test.ts src/path/file.ts",
|
|
121
|
+
'git commit -m "feat: add specific feature"',
|
|
122
|
+
"```",
|
|
123
|
+
"````",
|
|
124
|
+
"",
|
|
125
|
+
|
|
126
|
+
// ── Remember ─────────────────────────────────────────────────
|
|
127
|
+
"### Requirements",
|
|
128
|
+
"",
|
|
129
|
+
"- Exact file paths always",
|
|
130
|
+
"- Complete code in plan (not 'add validation' — show the actual code)",
|
|
131
|
+
"- Exact commands with expected output",
|
|
132
|
+
"- DRY, YAGNI, TDD, frequent commits",
|
|
133
|
+
"",
|
|
134
|
+
|
|
135
|
+
// ── Plan Review Loop ─────────────────────────────────────────
|
|
136
|
+
"## Step 4: plan review loop",
|
|
137
|
+
"",
|
|
138
|
+
"After completing each chunk of the plan, dispatch a plan-document-reviewer sub-agent.",
|
|
139
|
+
"",
|
|
140
|
+
"Use `## Chunk N: <name>` headings to delimit chunks. Each chunk should be under 1000 lines and logically self-contained.",
|
|
141
|
+
"",
|
|
142
|
+
"1. Dispatch the reviewer with this prompt:",
|
|
143
|
+
"",
|
|
144
|
+
"```",
|
|
145
|
+
buildPlanReviewerPrompt("<plan-file-path>", specPath, 1),
|
|
146
|
+
"```",
|
|
147
|
+
"",
|
|
148
|
+
"(Replace `<plan-file-path>` with actual path and adjust Chunk number.)",
|
|
149
|
+
"",
|
|
150
|
+
"2. If **Issues Found**: fix the issues, re-dispatch the reviewer",
|
|
151
|
+
"3. Repeat until **Approved** (max 5 iterations, then surface to human for guidance)",
|
|
152
|
+
"4. Proceed to next chunk or execution handoff",
|
|
153
|
+
"",
|
|
154
|
+
|
|
155
|
+
// ── Save Location ────────────────────────────────────────────
|
|
156
|
+
"## Step 5: Save Plan",
|
|
157
|
+
"",
|
|
158
|
+
"Save the plan to `.omp/supipowers/plans/YYYY-MM-DD-<feature-name>.md`",
|
|
159
|
+
"",
|
|
160
|
+
|
|
161
|
+
// ── Execution Handoff ────────────────────────────────────────
|
|
162
|
+
"## Step 6: Execution Handoff",
|
|
163
|
+
"",
|
|
164
|
+
"After saving the plan, ask:",
|
|
165
|
+
"",
|
|
166
|
+
'> "Plan complete and saved to `<path>`. Ready to execute?"',
|
|
167
|
+
"",
|
|
168
|
+
"Wait for user confirmation before proceeding to execution.",
|
|
169
|
+
"",
|
|
170
|
+
];
|
|
171
|
+
|
|
172
|
+
return sections.join("\n");
|
|
173
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { buildSpecReviewerPrompt } from "./spec-reviewer.js";
|
|
2
|
+
import { buildPlanWriterPrompt } from "./plan-writer-prompt.js";
|
|
3
|
+
|
|
4
|
+
export interface PlanningPromptOptions {
|
|
5
|
+
topic?: string;
|
|
6
|
+
skillContent?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Build the comprehensive planning prompt that encodes the full brainstorming flow.
|
|
11
|
+
* This is the steering prompt sent to the agent when `/supi:plan` runs.
|
|
12
|
+
*
|
|
13
|
+
* Follows superpowers' brainstorming skill flow:
|
|
14
|
+
* 1. Explore project context
|
|
15
|
+
* 2. Ask clarifying questions (one at a time)
|
|
16
|
+
* 3. Propose 2-3 approaches with trade-offs
|
|
17
|
+
* 4. Present design section by section
|
|
18
|
+
* 5. Write design doc to docs/supipowers/specs/
|
|
19
|
+
* 6. Spec review loop (dispatch reviewer sub-agent)
|
|
20
|
+
* 7. User review gate
|
|
21
|
+
* 8. Handoff to implementation plan
|
|
22
|
+
*/
|
|
23
|
+
export function buildPlanningPrompt(options: PlanningPromptOptions): string {
|
|
24
|
+
const { topic, skillContent } = options;
|
|
25
|
+
|
|
26
|
+
const sections: string[] = [
|
|
27
|
+
"You are starting a collaborative planning session with the user.",
|
|
28
|
+
"Follow this process step by step. Do NOT skip phases or combine them.",
|
|
29
|
+
"",
|
|
30
|
+
|
|
31
|
+
// ── Phase 1: Context ─────────────────────────────────────────
|
|
32
|
+
"## Phase 1: Explore project context",
|
|
33
|
+
"",
|
|
34
|
+
"Before asking questions, understand the current project context:",
|
|
35
|
+
"- Check files, docs, recent commits",
|
|
36
|
+
"- Understand existing architecture and patterns",
|
|
37
|
+
"- Assess scope: if the request describes multiple independent subsystems, flag it immediately and help decompose into sub-projects before proceeding",
|
|
38
|
+
"",
|
|
39
|
+
|
|
40
|
+
// ── Topic ────────────────────────────────────────────────────
|
|
41
|
+
topic
|
|
42
|
+
? `The user wants to plan: ${topic}`
|
|
43
|
+
: "Ask the user what they want to build or accomplish.",
|
|
44
|
+
"",
|
|
45
|
+
|
|
46
|
+
// ── Phase 2: Clarify ─────────────────────────────────────────
|
|
47
|
+
"## Phase 2: Ask Clarifying Questions",
|
|
48
|
+
"",
|
|
49
|
+
"- Ask one question at a time — never overwhelm with multiple questions",
|
|
50
|
+
"- Prefer **multiple choice** questions when possible, but open-ended is fine too",
|
|
51
|
+
"- Focus on: purpose, constraints, success criteria",
|
|
52
|
+
"- If a topic needs more exploration, break it into multiple questions",
|
|
53
|
+
"- Continue until you have enough clarity to propose approaches",
|
|
54
|
+
"",
|
|
55
|
+
|
|
56
|
+
// ── Phase 3: Approaches ──────────────────────────────────────
|
|
57
|
+
"## Phase 3: Propose 2-3 Approaches",
|
|
58
|
+
"",
|
|
59
|
+
"- Present 2-3 different approaches with trade-offs",
|
|
60
|
+
"- Lead with your recommended option and explain why",
|
|
61
|
+
"- Present options conversationally with your recommendation and reasoning",
|
|
62
|
+
"- Wait for the user to choose before proceeding",
|
|
63
|
+
"",
|
|
64
|
+
|
|
65
|
+
// ── Phase 4: Design ──────────────────────────────────────────
|
|
66
|
+
"## Phase 4: Present Design",
|
|
67
|
+
"",
|
|
68
|
+
"Once aligned on approach, present the design:",
|
|
69
|
+
"- Scale each section to its complexity: a few sentences if straightforward, up to 200-300 words if nuanced",
|
|
70
|
+
"- Cover: architecture, components, data flow, error handling, testing",
|
|
71
|
+
"- Ask after each section whether it looks right so far",
|
|
72
|
+
"- Design for isolation and clarity: smaller units with clear boundaries",
|
|
73
|
+
"- Apply YAGNI ruthlessly — remove unnecessary features",
|
|
74
|
+
"- Be ready to go back and clarify if something doesn't make sense",
|
|
75
|
+
"",
|
|
76
|
+
|
|
77
|
+
// ── Phase 5: Write Spec ──────────────────────────────────────
|
|
78
|
+
"## Phase 5: Write Design Doc",
|
|
79
|
+
"",
|
|
80
|
+
"Once the user approves the design:",
|
|
81
|
+
"- Write the validated design doc to `docs/supipowers/specs/YYYY-MM-DD-<topic>-design.md`",
|
|
82
|
+
"- Use clear, concise writing",
|
|
83
|
+
"- Commit the design document to git",
|
|
84
|
+
"",
|
|
85
|
+
|
|
86
|
+
// ── Phase 6: Spec Review Loop ────────────────────────────────
|
|
87
|
+
"## Phase 6: Spec Review Loop",
|
|
88
|
+
"",
|
|
89
|
+
"After writing the design doc, dispatch a spec-document-reviewer sub-agent to verify it:",
|
|
90
|
+
"",
|
|
91
|
+
"1. Dispatch the reviewer with this prompt:",
|
|
92
|
+
"",
|
|
93
|
+
"```",
|
|
94
|
+
buildSpecReviewerPrompt("<path-to-spec-file>"),
|
|
95
|
+
"```",
|
|
96
|
+
"",
|
|
97
|
+
"(Replace `<path-to-spec-file>` with the actual spec path.)",
|
|
98
|
+
"",
|
|
99
|
+
"2. If **Issues Found**: fix the issues, re-dispatch the reviewer",
|
|
100
|
+
"3. Repeat until **Approved** (max 5 iterations, then surface to human for guidance)",
|
|
101
|
+
"",
|
|
102
|
+
|
|
103
|
+
// ── Phase 7: User Gate ───────────────────────────────────────
|
|
104
|
+
"## Phase 7: User Review Gate",
|
|
105
|
+
"",
|
|
106
|
+
"After the spec review loop passes:",
|
|
107
|
+
"",
|
|
108
|
+
"After the spec review loop passes, ask the user to review the spec before proceeding:",
|
|
109
|
+
"",
|
|
110
|
+
'> "Spec written and committed to `<path>`. Please review it and let me know if you want to make any changes before we start writing out the implementation plan."',
|
|
111
|
+
"",
|
|
112
|
+
"Wait for the user's response. If they request changes, make them and re-run the spec review loop. Only proceed once the user approves.",
|
|
113
|
+
"",
|
|
114
|
+
|
|
115
|
+
// ── Phase 8: Handoff ─────────────────────────────────────────
|
|
116
|
+
"## Phase 8: Transition to Implementation Plan",
|
|
117
|
+
"",
|
|
118
|
+
"Once the user approves the spec, write a comprehensive implementation plan.",
|
|
119
|
+
"Follow these plan writing instructions:",
|
|
120
|
+
"",
|
|
121
|
+
buildPlanWriterPrompt({ specPath: "<path-to-approved-spec>" }),
|
|
122
|
+
"",
|
|
123
|
+
"(Replace `<path-to-approved-spec>` with the actual spec file path from Phase 5.)",
|
|
124
|
+
"",
|
|
125
|
+
|
|
126
|
+
// ── Principles ───────────────────────────────────────────────
|
|
127
|
+
"## Key Principles",
|
|
128
|
+
"",
|
|
129
|
+
"- **One question at a time** — Don't overwhelm with multiple questions",
|
|
130
|
+
"- **Multiple choice preferred** — Easier to answer than open-ended when possible",
|
|
131
|
+
"- **YAGNI ruthlessly** — Remove unnecessary features from all designs",
|
|
132
|
+
"- **Explore alternatives** — Always propose 2-3 approaches before settling",
|
|
133
|
+
"- **Incremental validation** — Present design, get approval before moving on",
|
|
134
|
+
"- **Decompose large scope** — If the request covers multiple independent subsystems, decompose into sub-projects first",
|
|
135
|
+
"- **Design for isolation** — Smaller units with clear boundaries and well-defined interfaces",
|
|
136
|
+
"",
|
|
137
|
+
];
|
|
138
|
+
|
|
139
|
+
if (skillContent) {
|
|
140
|
+
sections.push(
|
|
141
|
+
"## Additional Planning Guidelines",
|
|
142
|
+
"",
|
|
143
|
+
skillContent,
|
|
144
|
+
"",
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return sections.join("\n");
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Build the quick plan prompt that skips brainstorming.
|
|
153
|
+
* Used when `/supi:plan --quick <description>` is invoked.
|
|
154
|
+
*/
|
|
155
|
+
export function buildQuickPlanPrompt(description: string, skillContent?: string): string {
|
|
156
|
+
const sections: string[] = [
|
|
157
|
+
"Generate a concise implementation plan for the following task.",
|
|
158
|
+
"Skip brainstorming — go straight to task breakdown.",
|
|
159
|
+
"",
|
|
160
|
+
`Task: ${description}`,
|
|
161
|
+
"",
|
|
162
|
+
"Format the plan as markdown with YAML frontmatter (name, created, tags).",
|
|
163
|
+
"Each task should have: name, [parallel-safe] or [sequential] annotation,",
|
|
164
|
+
"**files**, **criteria**, and **complexity** (small/medium/large).",
|
|
165
|
+
"",
|
|
166
|
+
"After generating the plan, save it and confirm with the user.",
|
|
167
|
+
];
|
|
168
|
+
|
|
169
|
+
if (skillContent) {
|
|
170
|
+
sections.push(
|
|
171
|
+
"",
|
|
172
|
+
"Follow these planning guidelines:",
|
|
173
|
+
skillContent,
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return sections.join("\n");
|
|
178
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build the prompt for dispatching a spec document reviewer sub-agent.
|
|
3
|
+
* Follows the same pattern as superpowers' spec-document-reviewer-prompt.md.
|
|
4
|
+
*/
|
|
5
|
+
export function buildSpecReviewerPrompt(specFilePath: string): string {
|
|
6
|
+
return [
|
|
7
|
+
"You are a spec-document-reviewer. Verify this spec is complete and ready for planning.",
|
|
8
|
+
"",
|
|
9
|
+
`**Spec to review:** ${specFilePath}`,
|
|
10
|
+
"",
|
|
11
|
+
"## What to Check",
|
|
12
|
+
"",
|
|
13
|
+
"| Category | What to Look For |",
|
|
14
|
+
"|----------|------------------|",
|
|
15
|
+
"| Completeness | TODO markers, placeholders, \"TBD\", incomplete sections |",
|
|
16
|
+
"| Coverage | Missing error handling, edge cases, integration points |",
|
|
17
|
+
"| Consistency | Internal contradictions, conflicting requirements |",
|
|
18
|
+
"| Clarity | Ambiguous requirements that could be interpreted multiple ways |",
|
|
19
|
+
"| YAGNI | Unrequested features, over-engineering, gold-plating |",
|
|
20
|
+
"| Scope | Focused enough for a single plan — not covering multiple independent subsystems |",
|
|
21
|
+
"| Architecture | Units with clear boundaries, well-defined interfaces, independently understandable and testable |",
|
|
22
|
+
"",
|
|
23
|
+
"## Critical",
|
|
24
|
+
"",
|
|
25
|
+
"Look especially hard for:",
|
|
26
|
+
"- Any TODO markers or placeholder text",
|
|
27
|
+
'- Sections saying "to be defined later" or "will spec when X is done"',
|
|
28
|
+
"- Sections noticeably less detailed than others",
|
|
29
|
+
"- Units that lack clear boundaries or interfaces",
|
|
30
|
+
"",
|
|
31
|
+
"## Output Format",
|
|
32
|
+
"",
|
|
33
|
+
"## Spec Review",
|
|
34
|
+
"",
|
|
35
|
+
"**Status:** Approved | Issues Found",
|
|
36
|
+
"",
|
|
37
|
+
"**Issues (if any):**",
|
|
38
|
+
"- [Section X]: [specific issue] — [why it matters]",
|
|
39
|
+
"",
|
|
40
|
+
"**Recommendations (advisory):**",
|
|
41
|
+
"- [suggestions that don't block approval]",
|
|
42
|
+
].join("\n");
|
|
43
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { DetectedFramework } from "../detector.js";
|
|
2
|
+
|
|
3
|
+
export function buildDiscoveryPrompt(framework: DetectedFramework, cwd: string): string {
|
|
4
|
+
const sections: string[] = [
|
|
5
|
+
"# QA Phase: Test Discovery",
|
|
6
|
+
"",
|
|
7
|
+
`Project: ${cwd}`,
|
|
8
|
+
`Test framework: ${framework.name} (command: \`${framework.command}\`)`,
|
|
9
|
+
"",
|
|
10
|
+
"## Task",
|
|
11
|
+
"",
|
|
12
|
+
"Scan the project for all test files and enumerate every individual test case.",
|
|
13
|
+
"",
|
|
14
|
+
"1. Find all test files matching the framework's conventions",
|
|
15
|
+
"2. Parse each file to extract individual test/it/describe blocks",
|
|
16
|
+
"3. Classify each test with tags (unit, integration, e2e) based on file path or naming",
|
|
17
|
+
"",
|
|
18
|
+
"## Expected Output",
|
|
19
|
+
"",
|
|
20
|
+
"Write a JSON array to the QA session ledger's `tests` field. Each entry:",
|
|
21
|
+
"",
|
|
22
|
+
"```json",
|
|
23
|
+
'[{ "id": "<filePath>:<testName>", "filePath": "relative/path.test.ts", "testName": "test name", "suiteName": "describe block", "tags": ["unit"] }]',
|
|
24
|
+
"```",
|
|
25
|
+
"",
|
|
26
|
+
"The `id` must be deterministic: use `filePath:testName` so it stays stable across sessions.",
|
|
27
|
+
"",
|
|
28
|
+
"## After Completion",
|
|
29
|
+
"",
|
|
30
|
+
"Update the QA session ledger with the discovered tests, mark the discovery phase as completed, then invoke `/supi:qa` to continue to the next phase.",
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
return sections.join("\n");
|
|
34
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { QaSessionLedger, QaTestCase } from "../../types.js";
|
|
2
|
+
|
|
3
|
+
export interface ExecutionOptions {
|
|
4
|
+
failedOnly: true;
|
|
5
|
+
failedTests: QaTestCase[];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function buildExecutionPrompt(
|
|
9
|
+
ledger: QaSessionLedger,
|
|
10
|
+
options?: ExecutionOptions
|
|
11
|
+
): string {
|
|
12
|
+
const isRetry = options?.failedOnly === true;
|
|
13
|
+
const targetTests = isRetry ? options.failedTests : ledger.tests;
|
|
14
|
+
|
|
15
|
+
const testList = targetTests
|
|
16
|
+
.map((t) => `- ${t.id}: ${t.testName} (${t.filePath})`)
|
|
17
|
+
.join("\n");
|
|
18
|
+
|
|
19
|
+
const sections: string[] = [
|
|
20
|
+
"# QA Phase: Test Execution",
|
|
21
|
+
"",
|
|
22
|
+
`Framework: ${ledger.framework}`,
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
if (isRetry) {
|
|
26
|
+
sections.push(
|
|
27
|
+
"",
|
|
28
|
+
`## Re-running ${targetTests.length} failed test(s)`,
|
|
29
|
+
"",
|
|
30
|
+
"Run ONLY the following failed tests:",
|
|
31
|
+
"",
|
|
32
|
+
testList,
|
|
33
|
+
);
|
|
34
|
+
} else {
|
|
35
|
+
sections.push(
|
|
36
|
+
"",
|
|
37
|
+
`## Running all ${targetTests.length} test(s)`,
|
|
38
|
+
"",
|
|
39
|
+
testList,
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
sections.push(
|
|
44
|
+
"",
|
|
45
|
+
"## Instructions",
|
|
46
|
+
"",
|
|
47
|
+
"1. Run the tests using the framework's CLI",
|
|
48
|
+
"2. Collect per-test results: pass, fail, or skip",
|
|
49
|
+
"3. For failures, capture the error message",
|
|
50
|
+
"",
|
|
51
|
+
"## Expected Output",
|
|
52
|
+
"",
|
|
53
|
+
"Write a JSON array to the QA session ledger's `results` field:",
|
|
54
|
+
"",
|
|
55
|
+
"```json",
|
|
56
|
+
'[{ "testId": "file.test.ts:test name", "status": "pass|fail|skip", "duration": 123, "error": "only if failed" }]',
|
|
57
|
+
"```",
|
|
58
|
+
"",
|
|
59
|
+
"## After Completion",
|
|
60
|
+
"",
|
|
61
|
+
"Update the QA session ledger with results, mark the execution phase as completed, then invoke `/supi:qa` to continue to the next phase.",
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
return sections.join("\n");
|
|
65
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { QaSessionLedger } from "../../types.js";
|
|
2
|
+
|
|
3
|
+
export function buildMatrixPrompt(ledger: QaSessionLedger): string {
|
|
4
|
+
const testSummary = ledger.tests
|
|
5
|
+
.map((t) => `- ${t.id}: ${t.testName} (${t.filePath})${t.tags ? ` [${t.tags.join(", ")}]` : ""}`)
|
|
6
|
+
.join("\n");
|
|
7
|
+
|
|
8
|
+
const sections: string[] = [
|
|
9
|
+
"# QA Phase: Traceability Matrix",
|
|
10
|
+
"",
|
|
11
|
+
`Framework: ${ledger.framework}`,
|
|
12
|
+
`Discovered tests: ${ledger.tests.length}`,
|
|
13
|
+
"",
|
|
14
|
+
"## Discovered Tests",
|
|
15
|
+
"",
|
|
16
|
+
testSummary,
|
|
17
|
+
"",
|
|
18
|
+
"## Task",
|
|
19
|
+
"",
|
|
20
|
+
"Build a traceability matrix that maps requirements to test cases and platforms.",
|
|
21
|
+
"",
|
|
22
|
+
"1. Read the project's README, PR descriptions, code comments, and doc files to identify requirements",
|
|
23
|
+
"2. Map each requirement to the test case IDs that cover it",
|
|
24
|
+
"3. Identify target platforms (node, browser, CI) from project config",
|
|
25
|
+
"4. Assess coverage: full (all paths tested), partial (some paths), none (no tests)",
|
|
26
|
+
"",
|
|
27
|
+
"## Expected Output",
|
|
28
|
+
"",
|
|
29
|
+
"Write a JSON array to the QA session ledger's `matrix` field:",
|
|
30
|
+
"",
|
|
31
|
+
"```json",
|
|
32
|
+
'[{ "requirement": "User login validates email format", "testIds": ["auth.test.ts:validates email"], "platforms": ["node"], "coverage": "full" }]',
|
|
33
|
+
"```",
|
|
34
|
+
"",
|
|
35
|
+
"## After Completion",
|
|
36
|
+
"",
|
|
37
|
+
"Update the QA session ledger with the matrix, mark the matrix phase as completed, then invoke `/supi:qa` to continue to the next phase.",
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
return sections.join("\n");
|
|
41
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { QaSessionLedger } from "../../types.js";
|
|
2
|
+
|
|
3
|
+
export function buildReportingPrompt(ledger: QaSessionLedger): string {
|
|
4
|
+
const passed = ledger.results.filter((r) => r.status === "pass").length;
|
|
5
|
+
const failed = ledger.results.filter((r) => r.status === "fail").length;
|
|
6
|
+
const skipped = ledger.results.filter((r) => r.status === "skip").length;
|
|
7
|
+
const total = ledger.results.length;
|
|
8
|
+
|
|
9
|
+
const failedList = ledger.results
|
|
10
|
+
.filter((r) => r.status === "fail")
|
|
11
|
+
.map((r) => {
|
|
12
|
+
const test = ledger.tests.find((t) => t.id === r.testId);
|
|
13
|
+
return `- ${test?.testName ?? r.testId}: ${r.error ?? "no error captured"}`;
|
|
14
|
+
})
|
|
15
|
+
.join("\n");
|
|
16
|
+
|
|
17
|
+
const matrixSummary = ledger.matrix.length > 0
|
|
18
|
+
? ledger.matrix
|
|
19
|
+
.map((m) => `- ${m.requirement}: ${m.coverage} coverage (${m.testIds.length} tests)`)
|
|
20
|
+
.join("\n")
|
|
21
|
+
: "No traceability matrix available.";
|
|
22
|
+
|
|
23
|
+
const sections: string[] = [
|
|
24
|
+
"# QA Phase: Reporting",
|
|
25
|
+
"",
|
|
26
|
+
`Framework: ${ledger.framework}`,
|
|
27
|
+
`Session: ${ledger.id}`,
|
|
28
|
+
"",
|
|
29
|
+
"## Execution Summary",
|
|
30
|
+
"",
|
|
31
|
+
`- Total: ${total}`,
|
|
32
|
+
`- Passed: ${passed}`,
|
|
33
|
+
`- Failed: ${failed}`,
|
|
34
|
+
`- Skipped: ${skipped}`,
|
|
35
|
+
`- Pass rate: ${total > 0 ? Math.round((passed / total) * 100) : 0}%`,
|
|
36
|
+
"",
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
if (failed > 0) {
|
|
40
|
+
sections.push("## Failed Tests", "", failedList, "");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
sections.push(
|
|
44
|
+
"## Traceability Matrix",
|
|
45
|
+
"",
|
|
46
|
+
matrixSummary,
|
|
47
|
+
"",
|
|
48
|
+
"## Task",
|
|
49
|
+
"",
|
|
50
|
+
"Analyze the test results and traceability matrix above. Produce a QA report summary that includes:",
|
|
51
|
+
"",
|
|
52
|
+
"1. Overall assessment of test health",
|
|
53
|
+
"2. Coverage gaps identified from the matrix",
|
|
54
|
+
"3. Recommendations for improving coverage",
|
|
55
|
+
"4. Risk areas where failures cluster",
|
|
56
|
+
"",
|
|
57
|
+
"## Expected Output",
|
|
58
|
+
"",
|
|
59
|
+
"Write a JSON object to the QA session ledger's `report` field:",
|
|
60
|
+
"",
|
|
61
|
+
"```json",
|
|
62
|
+
`{ "generatedAt": "ISO timestamp", "total": ${total}, "passed": ${passed}, "failed": ${failed}, "skipped": ${skipped}, "passRate": ${total > 0 ? Math.round((passed / total) * 100) : 0}, "failedTests": [...], "coverageSummary": "free-text analysis" }`,
|
|
63
|
+
"```",
|
|
64
|
+
"",
|
|
65
|
+
"## After Completion",
|
|
66
|
+
"",
|
|
67
|
+
"Update the QA session ledger with the report, mark the reporting phase as completed. The QA pipeline is now complete.",
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
return sections.join("\n");
|
|
71
|
+
}
|