supipowers 0.4.0 → 0.6.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 +3 -3
- package/skills/context-mode/SKILL.md +38 -0
- package/skills/qa-strategy/SKILL.md +103 -21
- package/src/commands/config.ts +23 -2
- package/src/commands/fix-pr.ts +1 -1
- package/src/commands/plan.ts +1 -1
- package/src/commands/qa.ts +232 -148
- package/src/commands/release.ts +1 -1
- package/src/commands/review.ts +1 -1
- package/src/commands/run.ts +9 -4
- package/src/commands/supi.ts +1 -1
- package/src/config/defaults.ts +11 -0
- package/src/config/schema.ts +11 -0
- package/src/context-mode/compressor.ts +200 -0
- package/src/context-mode/detector.ts +43 -0
- package/src/context-mode/event-extractor.ts +170 -0
- package/src/context-mode/event-store.ts +168 -0
- package/src/context-mode/hooks.ts +176 -0
- package/src/context-mode/installer.ts +71 -0
- package/src/context-mode/snapshot-builder.ts +127 -0
- package/src/discipline/debugging.ts +7 -7
- package/src/discipline/receiving-review.ts +5 -5
- package/src/discipline/tdd.ts +2 -2
- package/src/discipline/verification.ts +9 -9
- package/src/git/base-branch.ts +30 -0
- package/src/git/branch-finish.ts +12 -3
- package/src/git/sanitize.ts +19 -0
- package/src/git/worktree.ts +38 -11
- package/src/index.ts +8 -1
- package/src/orchestrator/agent-prompts.ts +15 -7
- package/src/orchestrator/conflict-resolver.ts +3 -2
- package/src/orchestrator/dispatcher.ts +76 -21
- package/src/orchestrator/prompts.ts +46 -6
- package/src/planning/plan-reviewer.ts +1 -1
- package/src/planning/plan-writer-prompt.ts +6 -9
- package/src/planning/prompt-builder.ts +17 -16
- package/src/planning/spec-reviewer.ts +2 -2
- package/src/qa/config.ts +43 -0
- package/src/qa/matrix.ts +84 -0
- package/src/qa/prompt-builder.ts +212 -0
- package/src/qa/scripts/detect-app-type.sh +68 -0
- package/src/qa/scripts/discover-routes.sh +143 -0
- package/src/qa/scripts/ensure-playwright.sh +38 -0
- package/src/qa/scripts/run-e2e-tests.sh +99 -0
- package/src/qa/scripts/start-dev-server.sh +46 -0
- package/src/qa/scripts/stop-dev-server.sh +36 -0
- package/src/qa/session.ts +39 -55
- package/src/qa/types.ts +97 -0
- package/src/storage/qa-sessions.ts +9 -9
- package/src/types.ts +22 -70
- package/src/qa/detector.ts +0 -61
- package/src/qa/phases/discovery.ts +0 -34
- package/src/qa/phases/execution.ts +0 -65
- package/src/qa/phases/matrix.ts +0 -41
- package/src/qa/phases/reporting.ts +0 -71
- package/src/qa/report.ts +0 -22
- package/src/qa/runner.ts +0 -46
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "supipowers",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "OMP-native workflow extension inspired by
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "OMP-native workflow extension inspired by supipowers.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "vitest run",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"omp-extension",
|
|
14
14
|
"workflow",
|
|
15
15
|
"agent",
|
|
16
|
-
"
|
|
16
|
+
"supipowers"
|
|
17
17
|
],
|
|
18
18
|
"license": "MIT",
|
|
19
19
|
"bin": {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Context Mode — Tool Routing Instructions
|
|
2
|
+
|
|
3
|
+
When context-mode sandbox tools are available, prefer them over raw tool calls to keep your context window lean.
|
|
4
|
+
|
|
5
|
+
## Tool Selection Hierarchy
|
|
6
|
+
|
|
7
|
+
Use context-mode tools in this priority order:
|
|
8
|
+
|
|
9
|
+
1. **ctx_batch_execute** — for multi-step operations. Runs multiple commands and searches in a single call.
|
|
10
|
+
- Use when: you need to run 2+ commands, or combine a command with a search
|
|
11
|
+
- Example: checking a build AND searching for a symbol
|
|
12
|
+
|
|
13
|
+
2. **ctx_search** — for querying previously indexed knowledge. No re-execution needed.
|
|
14
|
+
- Use when: you've already indexed data and need to find something in it
|
|
15
|
+
- Example: finding a function definition you indexed earlier
|
|
16
|
+
|
|
17
|
+
3. **ctx_execute / ctx_execute_file** — for single commands or file processing.
|
|
18
|
+
- Use when: running one command whose output would be large
|
|
19
|
+
- Example: listing a directory, reading a large log file
|
|
20
|
+
|
|
21
|
+
4. **Raw Bash/Read/Grep** — only when necessary.
|
|
22
|
+
- Use when: editing files (Read before Edit), running build/test commands where real-time output matters, or when the output is known to be small
|
|
23
|
+
|
|
24
|
+
## Forbidden Patterns
|
|
25
|
+
|
|
26
|
+
- Do NOT use Bash for `curl`/`wget`/HTTP requests — use `ctx_fetch_and_index` instead
|
|
27
|
+
- Do NOT use Read for analyzing large files (>100 lines) — use `ctx_execute_file` to process and summarize
|
|
28
|
+
- Do NOT use Bash for directory listings with >20 expected files — use `ctx_execute`
|
|
29
|
+
|
|
30
|
+
## Output Constraints
|
|
31
|
+
|
|
32
|
+
- Keep tool output responses under 500 words when possible
|
|
33
|
+
- Write large artifacts (generated code, data dumps) to files rather than returning them inline
|
|
34
|
+
- Prefer structured summaries over raw output
|
|
35
|
+
|
|
36
|
+
## Sub-Agent Awareness
|
|
37
|
+
|
|
38
|
+
These routing instructions apply within sub-agent sessions. When you are a sub-agent dispatched by supipowers, follow the same tool preference hierarchy.
|
|
@@ -1,32 +1,114 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: qa-strategy
|
|
3
|
-
description:
|
|
3
|
+
description: E2E product testing strategy using Playwright — flow-based, autonomous, close to human interaction
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# E2E Product Testing Strategy
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## Core Principle
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
2. **Integration tests**: Test component interactions
|
|
12
|
-
3. **E2E tests**: Test user-facing flows end-to-end
|
|
10
|
+
Test the product the way a user uses it. Every test simulates a real user flow — navigating, clicking, filling forms, waiting for responses. If a human wouldn't do it, don't test it here.
|
|
13
11
|
|
|
14
|
-
|
|
12
|
+
**This is NOT for unit or integration tests.** This pipeline tests complete user journeys through the running application.
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
- New API endpoint → integration test
|
|
18
|
-
- New user flow → E2E test
|
|
19
|
-
- Bug fix → regression test at the appropriate level
|
|
14
|
+
## Flow Discovery
|
|
20
15
|
|
|
21
|
-
|
|
16
|
+
Before writing tests, understand what the product does:
|
|
22
17
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
1. **Scan routes and pages** — every URL a user can visit is a potential flow entry point
|
|
19
|
+
2. **Identify forms** — login, signup, search, create, edit — these are high-value interaction points
|
|
20
|
+
3. **Map navigation** — how does a user get from page A to page B? What's the happy path?
|
|
21
|
+
4. **Find auth boundaries** — what's public vs protected? Test both sides
|
|
22
|
+
5. **Check CRUD operations** — can you create, read, update, delete the core entities?
|
|
28
23
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
## Flow Prioritization
|
|
25
|
+
|
|
26
|
+
| Priority | Description | Examples |
|
|
27
|
+
|----------|-------------|---------|
|
|
28
|
+
| **Critical** | Revenue or access blocking | Login, checkout, payment |
|
|
29
|
+
| **High** | Core product value | Create/edit main entities, dashboard |
|
|
30
|
+
| **Medium** | Secondary features | Settings, profile, search |
|
|
31
|
+
| **Low** | Nice-to-have | Theme toggle, tooltips |
|
|
32
|
+
|
|
33
|
+
Test critical and high flows first. Skip low flows if hitting the token budget.
|
|
34
|
+
|
|
35
|
+
## Playwright Best Practices
|
|
36
|
+
|
|
37
|
+
### Locators (prefer resilient selectors)
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
// GOOD — role-based, resilient to styling changes
|
|
41
|
+
page.getByRole('button', { name: 'Submit' })
|
|
42
|
+
page.getByLabel('Email')
|
|
43
|
+
page.getByText('Welcome back')
|
|
44
|
+
page.getByTestId('user-avatar')
|
|
45
|
+
|
|
46
|
+
// BAD — fragile, breaks on refactoring
|
|
47
|
+
page.locator('.btn-primary')
|
|
48
|
+
page.locator('#submit-btn')
|
|
49
|
+
page.locator('div > form > button:nth-child(2)')
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Assertions
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
// Wait for navigation
|
|
56
|
+
await expect(page).toHaveURL('/dashboard');
|
|
57
|
+
|
|
58
|
+
// Wait for element visibility
|
|
59
|
+
await expect(page.getByText('Success')).toBeVisible();
|
|
60
|
+
|
|
61
|
+
// Wait for element to disappear (loading states)
|
|
62
|
+
await expect(page.getByText('Loading...')).not.toBeVisible();
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Waiting
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
// GOOD — wait for specific condition
|
|
69
|
+
await page.waitForResponse(resp => resp.url().includes('/api/users'));
|
|
70
|
+
await page.waitForLoadState('networkidle');
|
|
71
|
+
|
|
72
|
+
// BAD — arbitrary delays
|
|
73
|
+
await page.waitForTimeout(3000);
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Test Structure
|
|
77
|
+
|
|
78
|
+
One flow per file. Each test in the flow tests a step or variant:
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
test.describe('Checkout flow', () => {
|
|
82
|
+
test('adds item to cart', async ({ page }) => { ... });
|
|
83
|
+
test('fills shipping info', async ({ page }) => { ... });
|
|
84
|
+
test('completes payment', async ({ page }) => { ... });
|
|
85
|
+
test('shows confirmation', async ({ page }) => { ... });
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## What Makes a Good E2E Test
|
|
90
|
+
|
|
91
|
+
| Quality | Good | Bad |
|
|
92
|
+
|---------|------|-----|
|
|
93
|
+
| **User-centric** | Tests what a user would do | Tests implementation details |
|
|
94
|
+
| **Independent** | Each test can run alone | Tests depend on previous test state |
|
|
95
|
+
| **Resilient** | Uses role/label selectors | Uses CSS classes or DOM structure |
|
|
96
|
+
| **Fast-failing** | Fails clearly on the broken step | Fails on a timeout with no context |
|
|
97
|
+
| **Readable** | Test name describes the user action | Test name is a technical description |
|
|
98
|
+
|
|
99
|
+
## Common Pitfalls
|
|
100
|
+
|
|
101
|
+
1. **Testing internal state** — don't check Redux store, localStorage, or cookies directly. Test what the user sees.
|
|
102
|
+
2. **Flaky waits** — use `waitForResponse` or `waitForSelector`, never `waitForTimeout`.
|
|
103
|
+
3. **Shared state** — each test should set up its own state. Don't rely on test execution order.
|
|
104
|
+
4. **Over-testing** — one flow per critical path. Don't test every permutation of a form.
|
|
105
|
+
5. **Ignoring error states** — test what happens when the API returns an error, the network is slow, or the user enters invalid data.
|
|
106
|
+
|
|
107
|
+
## Regression Analysis
|
|
108
|
+
|
|
109
|
+
When a previously-passing test fails:
|
|
110
|
+
|
|
111
|
+
1. **Read the error** — what element wasn't found? What URL didn't match?
|
|
112
|
+
2. **Check if the app changed** — did a route move? Did a button get renamed?
|
|
113
|
+
3. **Distinguish bug from change** — if the app intentionally changed, the test needs updating. If not, it's a regression.
|
|
114
|
+
4. **Record the finding** — update the flow matrix with the new status and reasoning.
|
package/src/commands/config.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ExtensionAPI, ExtensionContext } from "@oh-my-pi/pi-coding-agent";
|
|
2
2
|
import { loadConfig, updateConfig } from "../config/loader.js";
|
|
3
3
|
import { listProfiles } from "../config/profiles.js";
|
|
4
|
+
import { checkInstallation } from "../context-mode/installer.js";
|
|
4
5
|
import type { SupipowersConfig } from "../types.js";
|
|
5
6
|
|
|
6
7
|
const FRAMEWORK_OPTIONS = [
|
|
@@ -126,7 +127,7 @@ function buildSettings(cwd: string): SettingDef[] {
|
|
|
126
127
|
];
|
|
127
128
|
}
|
|
128
129
|
|
|
129
|
-
export function handleConfig(ctx: ExtensionContext): void {
|
|
130
|
+
export function handleConfig(pi: ExtensionAPI, ctx: ExtensionContext): void {
|
|
130
131
|
if (!ctx.hasUI) {
|
|
131
132
|
ctx.ui.notify("Config UI requires interactive mode", "warning");
|
|
132
133
|
return;
|
|
@@ -179,13 +180,33 @@ export function handleConfig(ctx: ExtensionContext): void {
|
|
|
179
180
|
}
|
|
180
181
|
}
|
|
181
182
|
})();
|
|
183
|
+
|
|
184
|
+
// Context-mode status (async, fire-and-forget)
|
|
185
|
+
checkInstallation(
|
|
186
|
+
(cmd: string, args: string[]) => pi.exec(cmd, args),
|
|
187
|
+
pi.getActiveTools(),
|
|
188
|
+
).then((status) => {
|
|
189
|
+
const lines = [
|
|
190
|
+
"",
|
|
191
|
+
"Context Mode:",
|
|
192
|
+
` CLI installed: ${status.cliInstalled ? "\u2713" + (status.version ? ` v${status.version}` : "") : "\u2717"}`,
|
|
193
|
+
` MCP configured: ${status.mcpConfigured ? "\u2713" : "\u2717"}`,
|
|
194
|
+
` Tools available: ${status.toolsAvailable ? "\u2713" : "\u2717"}`,
|
|
195
|
+
];
|
|
196
|
+
if (!status.mcpConfigured && status.cliInstalled) {
|
|
197
|
+
lines.push(" \u2192 Run `omp mcp add context-mode` to enable");
|
|
198
|
+
}
|
|
199
|
+
ctx.ui.notify(lines.join("\n"), "info");
|
|
200
|
+
}).catch(() => {
|
|
201
|
+
// Silently ignore — context-mode status is optional
|
|
202
|
+
});
|
|
182
203
|
}
|
|
183
204
|
|
|
184
205
|
export function registerConfigCommand(pi: ExtensionAPI): void {
|
|
185
206
|
pi.registerCommand("supi:config", {
|
|
186
207
|
description: "View and manage Supipowers configuration",
|
|
187
208
|
async handler(_args, ctx) {
|
|
188
|
-
handleConfig(ctx);
|
|
209
|
+
handleConfig(pi, ctx);
|
|
189
210
|
},
|
|
190
211
|
});
|
|
191
212
|
}
|
package/src/commands/fix-pr.ts
CHANGED
|
@@ -172,7 +172,7 @@ export function registerFixPrCommand(pi: ExtensionAPI): void {
|
|
|
172
172
|
content: [{ type: "text", text: prompt }],
|
|
173
173
|
display: "none",
|
|
174
174
|
},
|
|
175
|
-
{ deliverAs: "steer" },
|
|
175
|
+
{ deliverAs: "steer", triggerTurn: true },
|
|
176
176
|
);
|
|
177
177
|
|
|
178
178
|
notifyInfo(ctx, `Fix-PR started: PR #${prNumber}`, `${commentCount} comments to assess | session ${ledger.id}`);
|
package/src/commands/plan.ts
CHANGED
|
@@ -130,7 +130,7 @@ export function registerPlanCommand(pi: ExtensionAPI): void {
|
|
|
130
130
|
content: [{ type: "text", text: prompt }],
|
|
131
131
|
display: "none",
|
|
132
132
|
},
|
|
133
|
-
{ deliverAs: "steer" }
|
|
133
|
+
{ deliverAs: "steer", triggerTurn: true }
|
|
134
134
|
);
|
|
135
135
|
|
|
136
136
|
notifyInfo(ctx, "Planning started", args ? `Topic: ${args}` : "Describe what you want to build");
|