supipowers 1.2.6 → 1.5.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/README.md +118 -56
- package/bin/install.ts +48 -128
- package/package.json +11 -3
- package/skills/code-review/SKILL.md +137 -40
- package/skills/context-mode/SKILL.md +67 -56
- package/skills/creating-supi-agents/SKILL.md +204 -0
- package/skills/debugging/SKILL.md +86 -40
- package/skills/fix-pr/SKILL.md +96 -65
- package/skills/planning/SKILL.md +103 -46
- package/skills/qa-strategy/SKILL.md +68 -46
- package/skills/receiving-code-review/SKILL.md +60 -53
- package/skills/release/SKILL.md +111 -39
- package/skills/tdd/SKILL.md +118 -67
- package/skills/verification/SKILL.md +71 -37
- package/src/bootstrap.ts +27 -5
- package/src/commands/agents.ts +249 -0
- package/src/commands/ai-review.ts +1113 -0
- package/src/commands/config.ts +224 -95
- package/src/commands/doctor.ts +19 -13
- package/src/commands/fix-pr.ts +8 -11
- package/src/commands/generate.ts +200 -0
- package/src/commands/model-picker.ts +5 -15
- package/src/commands/model.ts +4 -5
- package/src/commands/optimize-context.ts +202 -0
- package/src/commands/plan.ts +148 -92
- package/src/commands/qa.ts +14 -23
- package/src/commands/release.ts +504 -275
- package/src/commands/review.ts +643 -86
- package/src/commands/status.ts +44 -17
- package/src/commands/supi.ts +69 -41
- package/src/commands/update.ts +57 -2
- package/src/config/defaults.ts +6 -39
- package/src/config/loader.ts +388 -40
- package/src/config/model-resolver.ts +26 -22
- package/src/config/schema.ts +113 -48
- package/src/context/analyzer.ts +61 -2
- package/src/context/optimizer.ts +199 -0
- package/src/context-mode/compressor.ts +14 -11
- package/src/context-mode/detector.ts +16 -54
- package/src/context-mode/event-extractor.ts +45 -16
- package/src/context-mode/event-store.ts +225 -16
- package/src/context-mode/hooks.ts +195 -22
- package/src/context-mode/knowledge/chunker.ts +235 -0
- package/src/context-mode/knowledge/store.ts +187 -0
- package/src/context-mode/routing.ts +12 -23
- package/src/context-mode/sandbox/executor.ts +183 -0
- package/src/context-mode/sandbox/runners.ts +40 -0
- package/src/context-mode/snapshot-builder.ts +243 -7
- package/src/context-mode/tools.ts +440 -0
- package/src/context-mode/web/fetcher.ts +117 -0
- package/src/context-mode/web/html-to-md.ts +293 -0
- package/src/debug/logger.ts +107 -0
- package/src/deps/registry.ts +0 -20
- package/src/docs/drift.ts +454 -0
- package/src/fix-pr/fetch-comments.ts +66 -0
- package/src/git/commit-msg.ts +2 -1
- package/src/git/commit.ts +123 -141
- package/src/git/conventions.ts +2 -2
- package/src/git/status.ts +4 -1
- package/src/lsp/bridge.ts +138 -12
- package/src/planning/approval-flow.ts +125 -19
- package/src/planning/plan-writer-prompt.ts +4 -11
- package/src/planning/planning-ask-tool.ts +81 -0
- package/src/planning/prompt-builder.ts +9 -169
- package/src/planning/system-prompt.ts +290 -0
- package/src/platform/omp.ts +50 -4
- package/src/platform/progress.ts +182 -0
- package/src/platform/test-utils.ts +4 -1
- package/src/platform/tui-colors.ts +30 -0
- package/src/platform/types.ts +1 -0
- package/src/qa/detect-app-type.ts +102 -0
- package/src/qa/discover-routes.ts +353 -0
- package/src/quality/ai-session.ts +96 -0
- package/src/quality/ai-setup.ts +86 -0
- package/src/quality/gates/ai-review.ts +129 -0
- package/src/quality/gates/build.ts +8 -0
- package/src/quality/gates/command.ts +150 -0
- package/src/quality/gates/format.ts +28 -0
- package/src/quality/gates/lint.ts +22 -0
- package/src/quality/gates/lsp-diagnostics.ts +84 -0
- package/src/quality/gates/test-suite.ts +8 -0
- package/src/quality/gates/typecheck.ts +22 -0
- package/src/quality/registry.ts +25 -0
- package/src/quality/review-gates.ts +33 -0
- package/src/quality/runner.ts +268 -0
- package/src/quality/schemas.ts +48 -0
- package/src/quality/setup.ts +227 -0
- package/src/release/changelog.ts +7 -3
- package/src/release/channels/custom.ts +43 -0
- package/src/release/channels/gitea.ts +35 -0
- package/src/release/channels/github.ts +35 -0
- package/src/release/channels/gitlab.ts +35 -0
- package/src/release/channels/registry.ts +52 -0
- package/src/release/channels/types.ts +27 -0
- package/src/release/detector.ts +10 -63
- package/src/release/executor.ts +61 -51
- package/src/release/prompt.ts +38 -38
- package/src/release/version.ts +129 -10
- package/src/review/agent-loader.ts +331 -0
- package/src/review/consolidator.ts +180 -0
- package/src/review/default-agents/correctness.md +72 -0
- package/src/review/default-agents/maintainability.md +64 -0
- package/src/review/default-agents/security.md +67 -0
- package/src/review/fixer.ts +219 -0
- package/src/review/multi-agent-runner.ts +135 -0
- package/src/review/output.ts +147 -0
- package/src/review/prompts/agent-review-wrapper.md +36 -0
- package/src/review/prompts/fix-findings.md +32 -0
- package/src/review/prompts/fix-output-schema.md +18 -0
- package/src/review/prompts/invalid-output-retry.md +22 -0
- package/src/review/prompts/output-instructions.md +14 -0
- package/src/review/prompts/review-output-schema.md +38 -0
- package/src/review/prompts/single-review.md +53 -0
- package/src/review/prompts/validation-review.md +30 -0
- package/src/review/runner.ts +128 -0
- package/src/review/scope.ts +353 -0
- package/src/review/template.ts +15 -0
- package/src/review/types.ts +296 -0
- package/src/review/validator.ts +160 -0
- package/src/storage/plans.ts +5 -3
- package/src/storage/reports.ts +50 -7
- package/src/storage/review-sessions.ts +117 -0
- package/src/text.ts +19 -0
- package/src/types.ts +336 -26
- package/src/utils/paths.ts +39 -0
- package/src/visual/companion.ts +5 -3
- package/src/visual/start-server.ts +101 -0
- package/src/visual/stop-server.ts +39 -0
- package/bin/ctx-mode-wrapper.mjs +0 -66
- package/src/config/profiles.ts +0 -64
- package/src/context-mode/installer.ts +0 -38
- package/src/quality/ai-review-gate.ts +0 -43
- package/src/quality/gate-runner.ts +0 -67
- package/src/quality/lsp-gate.ts +0 -24
- package/src/quality/test-gate.ts +0 -39
- package/src/visual/scripts/start-server.sh +0 -98
- package/src/visual/scripts/stop-server.sh +0 -21
package/README.md
CHANGED
|
@@ -30,73 +30,104 @@ The installer detects your agent, registers the extension, and optionally sets u
|
|
|
30
30
|
|
|
31
31
|
### Requirements
|
|
32
32
|
|
|
33
|
-
| Dependency
|
|
34
|
-
|
|
|
35
|
-
| [Oh My Pi (OMP)](https://github.com/can1357/oh-my-pi) | The coding agent that supipowers extends
|
|
36
|
-
| [Bun](https://bun.sh)
|
|
37
|
-
| [Git](https://git-scm.com)
|
|
33
|
+
| Dependency | What it's for |
|
|
34
|
+
| ----------------------------------------------------- | --------------------------------------------------------------------- |
|
|
35
|
+
| [Oh My Pi (OMP)](https://github.com/can1357/oh-my-pi) | The coding agent that supipowers extends |
|
|
36
|
+
| [Bun](https://bun.sh) | Runtime — required for installation and the built-in SQLite FTS index |
|
|
37
|
+
| [Git](https://git-scm.com) | Used by the installer and context-mode setup |
|
|
38
38
|
|
|
39
39
|
### Optional dependencies
|
|
40
40
|
|
|
41
41
|
The installer scans for these and offers to install any that are missing. Everything works without them, but each one unlocks additional capabilities.
|
|
42
42
|
|
|
43
|
-
| Dependency
|
|
44
|
-
|
|
|
45
|
-
| [mcpc](https://github.com/apify/mcpc) | MCP server management via `/supi:mcp`
|
|
46
|
-
|
|
|
47
|
-
| `typescript-language-server`
|
|
48
|
-
| `pyright`
|
|
49
|
-
| `rust-analyzer`
|
|
50
|
-
| `gopls`
|
|
51
|
-
| `@playwright/cli`
|
|
43
|
+
| Dependency | What it enables |
|
|
44
|
+
| ------------------------------------- | --------------------------------------------------------------------- |
|
|
45
|
+
| [mcpc](https://github.com/apify/mcpc) | MCP server management via `/supi:mcp` |
|
|
46
|
+
| supi-context-mode | Context window protection — large outputs are sandboxed automatically |
|
|
47
|
+
| `typescript-language-server` | TypeScript/JS diagnostics and references in review gates |
|
|
48
|
+
| `pyright` | Python type checking |
|
|
49
|
+
| `rust-analyzer` | Rust language server |
|
|
50
|
+
| `gopls` | Go language server |
|
|
51
|
+
| `@playwright/cli` | Browser exploration and E2E test execution via `/supi:qa` |
|
|
52
52
|
|
|
53
53
|
> [!NOTE]
|
|
54
54
|
> LSP servers are language-specific — install only the ones that match your project's stack.
|
|
55
|
+
> supi-context-mode is heavily inspired at [context-mode](https://github.com/mksglu/context-mode)
|
|
55
56
|
|
|
56
57
|
## Commands
|
|
57
58
|
|
|
58
|
-
| Command
|
|
59
|
-
|
|
|
60
|
-
| `/supi`
|
|
61
|
-
| `/supi:plan`
|
|
62
|
-
| `/supi:review`
|
|
63
|
-
| `/supi:
|
|
64
|
-
| `/supi:
|
|
65
|
-
| `/supi:
|
|
66
|
-
| `/supi:
|
|
67
|
-
| `/supi:
|
|
68
|
-
| `/supi:
|
|
69
|
-
| `/supi:
|
|
70
|
-
| `/supi:
|
|
71
|
-
| `/supi:
|
|
72
|
-
| `/supi:
|
|
73
|
-
| `/supi:
|
|
74
|
-
|
|
75
|
-
|
|
59
|
+
| Command | What it does |
|
|
60
|
+
| ------------------------ | ------------------------------------------------------------- |
|
|
61
|
+
| `/supi` | Interactive menu with commands and project status |
|
|
62
|
+
| `/supi:plan` | Collaborative planning with structured task breakdown |
|
|
63
|
+
| `/supi:review` | AI code review with validated findings docs and fix/document/discuss actions |
|
|
64
|
+
| `/supi:checks` | Run deterministic quality gates |
|
|
65
|
+
| `/supi:qa` | E2E testing pipeline with Playwright |
|
|
66
|
+
| `/supi:fix-pr` | Assess and fix PR review comments |
|
|
67
|
+
| `/supi:release` | Version bump, release notes, publish |
|
|
68
|
+
| `/supi:commit` | AI-powered commit with conventional message generation |
|
|
69
|
+
| `/supi:model` | Configure model assignments per action (plan, review, qa…) |
|
|
70
|
+
| `/supi:context` | Show current context window usage and system prompt breakdown |
|
|
71
|
+
| `/supi:optimize-context` | Analyze loaded prompt/context usage and suggest reductions |
|
|
72
|
+
| `/supi:mcp` | Manage MCP servers (connect, disconnect, migrate) |
|
|
73
|
+
| `/supi:config` | Interactive settings TUI |
|
|
74
|
+
| `/supi:status` | Check running sub-agents and progress |
|
|
75
|
+
| `/supi:doctor` | Diagnose extension health and missing dependencies |
|
|
76
|
+
| `/supi:generate` | Documentation drift detection |
|
|
77
|
+
| `/supi:update` | Update supipowers to the latest version |
|
|
78
|
+
| `/supi:agents` | Manage review agents |
|
|
79
|
+
|
|
80
|
+
Most commands steer the AI session. These are TUI-only — they open native dialogs without triggering the AI: `/supi`, `/supi:config`, `/supi:status`, `/supi:review`, `/supi:update`, `/supi:doctor`, `/supi:mcp`, `/supi:model`, `/supi:context`, `/supi:optimize-context`, `/supi:commit`, `/supi:release`, `/supi:checks`, `/supi:agents`.
|
|
76
81
|
|
|
77
82
|
## How it works
|
|
78
83
|
|
|
79
84
|
**Planning.** `/supi:plan` steers the AI through planning phases (scope → decompose → estimate → verify), saves the result to `.omp/supipowers/plans/`, and presents an approval UI. On approval, tasks execute in the same session.
|
|
80
85
|
|
|
81
|
-
**Quality gates.** `/supi:
|
|
86
|
+
**Quality gates.** `/supi:checks` runs deterministic quality gates. Six gates are available: `lsp-diagnostics`, `lint`, `typecheck`, `format`, `test-suite`, and `build`. Each gate can be enabled independently via `/supi:config` or `.omp/supipowers/config.json`. Gates report issues with severity levels.
|
|
82
87
|
|
|
83
|
-
**
|
|
84
|
-
|
|
85
|
-
**Context protection.** When [context-mode](https://github.com/ogrodev/context-mode) is detected, supipowers injects routing hooks that protect the agent's context window. Large outputs, file reads, and HTTP calls are automatically routed through sandboxed execution so only summaries enter the conversation.
|
|
88
|
+
**AI code review.** `/supi:review` runs a programmatic AI review pipeline with configurable depth (quick, deep, or multi-agent). It uses headless agent sessions with structured JSON validation, always validates findings before user action, writes the current validated findings to a session `findings.md` document, and then presents three next-step choices: `Fix now`, `Document only`, or `Discuss before fixing`.
|
|
86
89
|
|
|
87
|
-
**
|
|
90
|
+
**PR fixing.** `/supi:fix-pr` fetches PR review comments, critically assesses each one, checks for ripple effects, then fixes or rejects with evidence. Bot reviewers are auto-detected and filtered out.
|
|
88
91
|
|
|
89
|
-
|
|
92
|
+
**Context protection.** When [context-mode](https://github.com/mksglu/context-mode) is detected, supipowers injects routing hooks that protect the agent's context window. Large outputs, file reads, and HTTP calls are automatically routed through sandboxed execution so only summaries enter the conversation.
|
|
90
93
|
|
|
91
|
-
|
|
94
|
+
**Model assignment.** Each action can be assigned a different model and thinking level. `/supi:model` opens a TUI picker backed by OMP's model registry.
|
|
92
95
|
|
|
93
|
-
|
|
94
|
-
| --- | --- | --- | --- | --- | --- |
|
|
95
|
-
| `quick` | ✓ | quick scan | — | — | — |
|
|
96
|
-
| `thorough` _(default)_ | ✓ | deep | ✓ | — | — |
|
|
97
|
-
| `full-regression` | ✓ | deep | ✓ | ✓ | ✓ |
|
|
96
|
+
## Feature comparison with `obra/superpowers`
|
|
98
97
|
|
|
99
|
-
|
|
98
|
+
> [!NOTE]
|
|
99
|
+
> Based on the current `supipowers` repo and the documented features in [`obra/superpowers`](https://github.com/obra/superpowers). ✅ = part of the current documented product surface. ❌ = not part of the current documented product surface.
|
|
100
|
+
|
|
101
|
+
| What is being compared | supipowers | obra/superpowers |
|
|
102
|
+
| ------------------------------------- | ---------- | ---------------- |
|
|
103
|
+
| OMP-native slash commands | ✅ | ❌ |
|
|
104
|
+
| Automatic skill activation | ❌ | ✅ |
|
|
105
|
+
| Plan approval UI | ✅ | ❌ |
|
|
106
|
+
| Parallel agent execution workflow | ✅ | ✅ |
|
|
107
|
+
| Code review workflow | ✅ | ✅ |
|
|
108
|
+
| TDD / debugging / verification skills | ✅ | ✅ |
|
|
109
|
+
| Browser QA / Playwright workflow | ✅ | ❌ |
|
|
110
|
+
| PR review comment fixing workflow | ✅ | ❌ |
|
|
111
|
+
| Release automation | ✅ | ❌ |
|
|
112
|
+
| Commit workflow | ✅ | ❌ |
|
|
113
|
+
| Context-window optimizations | ✅ | ❌ |
|
|
114
|
+
| MCP server management through mcpc | ✅ | ❌ |
|
|
115
|
+
| Git worktree workflow | ❌ | ✅ |
|
|
116
|
+
|
|
117
|
+
## Quality gates
|
|
118
|
+
|
|
119
|
+
`/supi:checks` runs deterministic quality gates. Each gate is independently configurable in `quality.gates` via `/supi:config` or the config JSON files:
|
|
120
|
+
|
|
121
|
+
| Gate | What it checks | Config type |
|
|
122
|
+
| ------------------ | ------------------------------- | ----------------- |
|
|
123
|
+
| `lsp-diagnostics` | Language server diagnostics | enabled |
|
|
124
|
+
| `lint` | Linter (e.g. `eslint`, `biome`) | enabled + command |
|
|
125
|
+
| `typecheck` | Type checker (e.g. `tsc`) | enabled + command |
|
|
126
|
+
| `format` | Formatter check | enabled + command |
|
|
127
|
+
| `test-suite` | Test runner | enabled + command |
|
|
128
|
+
| `build` | Build verification | enabled + command |
|
|
129
|
+
|
|
130
|
+
Gates default to disabled. Enable them per-project in `.omp/supipowers/config.json` or globally in `~/.omp/supipowers/config.json`.
|
|
100
131
|
|
|
101
132
|
## Configuration
|
|
102
133
|
|
|
@@ -112,21 +143,50 @@ Configuration is a three-layer deep-merge (lowest to highest priority):
|
|
|
112
143
|
2. `~/.omp/supipowers/config.json` — global overrides
|
|
113
144
|
3. `.omp/supipowers/config.json` — per-project overrides
|
|
114
145
|
|
|
146
|
+
|
|
147
|
+
## Release channels
|
|
148
|
+
|
|
149
|
+
Three built-in channels are available: `github` (GitHub Release via `gh` CLI), `gitlab` (GitLab Release via `glab` CLI), and `gitea` (Gitea Release via `tea` CLI). Channels are selected per-project in `release.channels`.
|
|
150
|
+
|
|
151
|
+
Custom channels can be defined in `release.customChannels`:
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"release": {
|
|
156
|
+
"customChannels": {
|
|
157
|
+
"my-channel": {
|
|
158
|
+
"label": "My Channel",
|
|
159
|
+
"publishCommand": "./scripts/publish.sh $tag",
|
|
160
|
+
"detectCommand": "which my-tool"
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
| Field | Required | Description |
|
|
168
|
+
| ---------------- | -------- | -------------------------------------------------------------- |
|
|
169
|
+
| `label` | yes | Display name shown in the release picker |
|
|
170
|
+
| `publishCommand` | yes | Shell command run to publish; `$tag`, `$version`, `$changelog` are passed as environment variables |
|
|
171
|
+
| `detectCommand` | no | Shell command to detect availability; exit 0 = available. If omitted, the channel is assumed available |
|
|
172
|
+
|
|
115
173
|
## Skills
|
|
116
174
|
|
|
117
175
|
Supipowers ships runtime-loaded prompt skills that are also available to the agent during regular sessions:
|
|
118
176
|
|
|
119
|
-
| Skill
|
|
120
|
-
|
|
|
121
|
-
| `planning`
|
|
122
|
-
| `code-review`
|
|
123
|
-
| `qa-strategy`
|
|
124
|
-
| `fix-pr`
|
|
125
|
-
| `debugging`
|
|
126
|
-
| `tdd`
|
|
127
|
-
| `verification`
|
|
128
|
-
| `receiving-code-review` | Agent sessions
|
|
129
|
-
| `
|
|
177
|
+
| Skill | Used by |
|
|
178
|
+
| ----------------------- | ----------------------- |
|
|
179
|
+
| `planning` | `/supi:plan` |
|
|
180
|
+
| `code-review` | `/supi:review` |
|
|
181
|
+
| `qa-strategy` | `/supi:qa` |
|
|
182
|
+
| `fix-pr` | `/supi:fix-pr` |
|
|
183
|
+
| `debugging` | Agent sessions |
|
|
184
|
+
| `tdd` | Agent sessions |
|
|
185
|
+
| `verification` | Agent sessions |
|
|
186
|
+
| `receiving-code-review` | Agent sessions |
|
|
187
|
+
| `release` | `/supi:release` |
|
|
188
|
+
| `context-mode` | Context window guidance |
|
|
189
|
+
| `creating-supi-agents` | Agent creation guidance |
|
|
130
190
|
|
|
131
191
|
## Development
|
|
132
192
|
|
|
@@ -138,3 +198,5 @@ bun run build # emit to dist/
|
|
|
138
198
|
```
|
|
139
199
|
|
|
140
200
|
Tests live in `tests/`, mirroring `src/` one-to-one. The test runner is Bun's built-in `bun:test`.
|
|
201
|
+
|
|
202
|
+
Peer dependencies (`@oh-my-pi/pi-coding-agent`, `@oh-my-pi/pi-ai`, `@oh-my-pi/pi-tui`, `@sinclair/typebox`) are provided by the OMP host; they are devDependencies only for type-checking during development.
|
package/bin/install.ts
CHANGED
|
@@ -315,139 +315,52 @@ function installToPlatform(platformDir: string, packageRoot: string): string {
|
|
|
315
315
|
}
|
|
316
316
|
|
|
317
317
|
/**
|
|
318
|
-
*
|
|
319
|
-
*
|
|
320
|
-
* Per upstream docs (Pi Coding Agent):
|
|
321
|
-
* 1. git clone → ~/<platformDir>/extensions/context-mode
|
|
322
|
-
* 2. npm install && npm run build
|
|
323
|
-
* 3. Register MCP in ~/<platformDir>/settings/mcp.json
|
|
324
|
-
*
|
|
325
|
-
* Build requires Node.js 18+ (tsc, esbuild, node -e in build script).
|
|
326
|
-
* Runtime uses bun to leverage bun:sqlite — context-mode auto-detects
|
|
327
|
-
* Bun and skips better-sqlite3 entirely.
|
|
318
|
+
* Remove supi-context-mode / context-mode entries from the current agent/mcp.json
|
|
319
|
+
* and from the legacy settings/mcp.json location.
|
|
328
320
|
*/
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
// Check if already installed and built
|
|
334
|
-
if (existsSync(startMjs)) {
|
|
335
|
-
// Already installed — just ensure MCP registration is up to date
|
|
336
|
-
registerContextModeMcp(platformDir, startMjs);
|
|
337
|
-
return;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
const shouldInstall = await confirm({
|
|
341
|
-
message: `Install context-mode extension for context window protection? (${platformDir})`,
|
|
342
|
-
});
|
|
343
|
-
if (isCancel(shouldInstall) || !shouldInstall) {
|
|
344
|
-
note(
|
|
345
|
-
`Skipped. You can install later:\n` +
|
|
346
|
-
` git clone https://github.com/mksglu/context-mode.git ~/${platformDir}/extensions/context-mode\n` +
|
|
347
|
-
` cd ~/${platformDir}/extensions/context-mode && npm install && npm run build`,
|
|
348
|
-
`context-mode (${platformDir})`,
|
|
349
|
-
);
|
|
350
|
-
return;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
// Check Node.js 18+ (required for build: tsc, esbuild, node -e in build script)
|
|
354
|
-
const nodeCheck = run("node", ["--version"]);
|
|
355
|
-
if (nodeCheck.error || nodeCheck.status !== 0) {
|
|
356
|
-
note(
|
|
357
|
-
"Node.js 18+ is required to build context-mode.\n" +
|
|
358
|
-
"Install from https://nodejs.org then re-run the installer.",
|
|
359
|
-
"context-mode requires Node.js",
|
|
360
|
-
);
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
|
-
const nodeVersion = parseInt((nodeCheck.stdout ?? "").replace(/^v/, ""), 10);
|
|
364
|
-
if (nodeVersion < 18) {
|
|
365
|
-
note(
|
|
366
|
-
`Found Node.js v${nodeCheck.stdout?.trim()} but context-mode requires v18+.\n` +
|
|
367
|
-
"Update Node.js from https://nodejs.org then re-run the installer.",
|
|
368
|
-
"context-mode requires Node.js 18+",
|
|
369
|
-
);
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
const s = spinner();
|
|
374
|
-
s.start(`Cloning context-mode to ~/${platformDir}/extensions/context-mode...`);
|
|
375
|
-
|
|
376
|
-
// Clone
|
|
377
|
-
const cloneResult = run("git", [
|
|
378
|
-
"clone",
|
|
379
|
-
"https://github.com/mksglu/context-mode.git",
|
|
380
|
-
extDir,
|
|
381
|
-
]);
|
|
382
|
-
if (cloneResult.status !== 0) {
|
|
383
|
-
s.stop(`Failed to clone context-mode`);
|
|
384
|
-
note(
|
|
385
|
-
cloneResult.stderr?.trim() || "Unknown git clone error",
|
|
386
|
-
"context-mode install failed",
|
|
387
|
-
);
|
|
388
|
-
return;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// npm install (builds better-sqlite3 native bindings for Node.js fallback;
|
|
392
|
-
// at runtime under Bun, bun:sqlite is used instead via auto-detection)
|
|
393
|
-
s.message("Installing context-mode dependencies...");
|
|
394
|
-
const npmInstall = run("npm", ["install"], { cwd: extDir });
|
|
395
|
-
if (npmInstall.status !== 0) {
|
|
396
|
-
s.stop(`Failed to install context-mode dependencies`);
|
|
397
|
-
note(
|
|
398
|
-
npmInstall.stderr?.trim() || "Unknown npm install error",
|
|
399
|
-
"context-mode install failed",
|
|
400
|
-
);
|
|
401
|
-
return;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
// npm run build (requires tsc + esbuild from devDeps, runs under Node.js)
|
|
405
|
-
s.message("Building context-mode...");
|
|
406
|
-
const npmBuild = run("npm", ["run", "build"], { cwd: extDir });
|
|
407
|
-
if (npmBuild.status !== 0) {
|
|
408
|
-
s.stop(`Failed to build context-mode`);
|
|
409
|
-
note(
|
|
410
|
-
npmBuild.stderr?.trim() || "Unknown build error",
|
|
411
|
-
"context-mode install failed",
|
|
412
|
-
);
|
|
413
|
-
return;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
s.stop(`context-mode installed to ~/${platformDir}/extensions/context-mode`);
|
|
417
|
-
|
|
418
|
-
// Register MCP server
|
|
419
|
-
registerContextModeMcp(platformDir, startMjs);
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
/**
|
|
423
|
-
* Register context-mode MCP entry in the platform's settings/mcp.json.
|
|
424
|
-
*
|
|
425
|
-
* Uses "bun" as the command so context-mode auto-detects Bun runtime
|
|
426
|
-
* and uses bun:sqlite — no better-sqlite3 native bindings needed at runtime.
|
|
427
|
-
*/
|
|
428
|
-
function registerContextModeMcp(platformDir: string, startMjs: string): void {
|
|
429
|
-
const mcpConfigPath = join(homedir(), platformDir, "settings", "mcp.json");
|
|
430
|
-
let mcpConfig: { mcpServers: Record<string, unknown> } = { mcpServers: {} };
|
|
431
|
-
if (existsSync(mcpConfigPath)) {
|
|
321
|
+
function cleanupContextModeMcp(platformDir: string): void {
|
|
322
|
+
// Clean supi-context-mode from the current agent/mcp.json
|
|
323
|
+
const agentMcpPath = join(homedir(), platformDir, "agent", "mcp.json");
|
|
324
|
+
if (existsSync(agentMcpPath)) {
|
|
432
325
|
try {
|
|
433
|
-
|
|
434
|
-
|
|
326
|
+
const agentConfig = JSON.parse(readFileSync(agentMcpPath, "utf8"));
|
|
327
|
+
let changed = false;
|
|
328
|
+
if (agentConfig.mcpServers?.["context-mode"]) {
|
|
329
|
+
delete agentConfig.mcpServers["context-mode"];
|
|
330
|
+
changed = true;
|
|
331
|
+
}
|
|
332
|
+
if (agentConfig.mcpServers?.["supi-context-mode"]) {
|
|
333
|
+
delete agentConfig.mcpServers["supi-context-mode"];
|
|
334
|
+
changed = true;
|
|
335
|
+
}
|
|
336
|
+
if (changed) {
|
|
337
|
+
writeFileSync(agentMcpPath, JSON.stringify(agentConfig, null, 2));
|
|
338
|
+
}
|
|
435
339
|
} catch {
|
|
436
|
-
|
|
340
|
+
// Best effort — do not fail install on corrupt mcp.json
|
|
437
341
|
}
|
|
438
342
|
}
|
|
343
|
+
}
|
|
439
344
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
};
|
|
345
|
+
function cleanupLegacyMcp(platformDir: string): void {
|
|
346
|
+
const oldMcpPath = join(homedir(), platformDir, "settings", "mcp.json");
|
|
347
|
+
if (!existsSync(oldMcpPath)) return;
|
|
444
348
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
349
|
+
try {
|
|
350
|
+
const config = JSON.parse(readFileSync(oldMcpPath, "utf8"));
|
|
351
|
+
delete config.mcpServers?.["context-mode"];
|
|
352
|
+
delete config.mcpServers?.["supi-context-mode"];
|
|
353
|
+
|
|
354
|
+
if (!config.mcpServers || Object.keys(config.mcpServers).length === 0) {
|
|
355
|
+
rmSync(oldMcpPath);
|
|
356
|
+
} else {
|
|
357
|
+
// Other servers exist — keep the file, just remove our entries
|
|
358
|
+
writeFileSync(oldMcpPath, JSON.stringify(config, null, 2));
|
|
359
|
+
}
|
|
360
|
+
} catch {
|
|
361
|
+
// Corrupted — remove it
|
|
362
|
+
try { rmSync(oldMcpPath); } catch { /* best effort */ }
|
|
363
|
+
}
|
|
451
364
|
}
|
|
452
365
|
|
|
453
366
|
// ── Main ─────────────────────────────────────────────────────
|
|
@@ -544,10 +457,17 @@ async function main(): Promise<void> {
|
|
|
544
457
|
for (const target of targets) {
|
|
545
458
|
installToPlatform(target.dir, packageRoot);
|
|
546
459
|
|
|
547
|
-
// ── Step 3b:
|
|
548
|
-
|
|
460
|
+
// ── Step 3b: Clean up legacy context-mode MCP registrations ──
|
|
461
|
+
cleanupContextModeMcp(target.dir);
|
|
462
|
+
cleanupLegacyMcp(target.dir);
|
|
549
463
|
}
|
|
550
464
|
|
|
465
|
+
note(
|
|
466
|
+
"Context-mode tools are now built into supipowers (no external MCP server needed).\n" +
|
|
467
|
+
"You can manually remove any legacy installation at ~/<platformDir>/extensions/context-mode/",
|
|
468
|
+
"Context Mode",
|
|
469
|
+
);
|
|
470
|
+
|
|
551
471
|
if (DEBUG) {
|
|
552
472
|
note(`Debug log written to:\n${LOG_FILE}`, "Debug");
|
|
553
473
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "supipowers",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Workflow extension for OMP coding agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -16,17 +16,24 @@
|
|
|
16
16
|
"agent",
|
|
17
17
|
"supipowers"
|
|
18
18
|
],
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/ogrodev/supipowers.git"
|
|
22
|
+
},
|
|
19
23
|
"license": "MIT",
|
|
20
24
|
"bin": {
|
|
21
25
|
"supipowers": "bin/install.mjs"
|
|
22
26
|
},
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public",
|
|
29
|
+
"registry": "https://registry.npmjs.org"
|
|
30
|
+
},
|
|
23
31
|
"files": [
|
|
24
32
|
"src",
|
|
25
33
|
"skills",
|
|
26
34
|
"bin/install.mjs",
|
|
27
35
|
"bin/install.ts",
|
|
28
36
|
"bin/local-install.sh",
|
|
29
|
-
"bin/ctx-mode-wrapper.mjs",
|
|
30
37
|
"README.md",
|
|
31
38
|
"LICENSE"
|
|
32
39
|
],
|
|
@@ -39,7 +46,8 @@
|
|
|
39
46
|
]
|
|
40
47
|
},
|
|
41
48
|
"dependencies": {
|
|
42
|
-
"@clack/prompts": "^0.10.0"
|
|
49
|
+
"@clack/prompts": "^0.10.0",
|
|
50
|
+
"handlebars": "^4.7.8"
|
|
43
51
|
},
|
|
44
52
|
"peerDependencies": {
|
|
45
53
|
"@oh-my-pi/pi-coding-agent": "*",
|
|
@@ -3,43 +3,140 @@ name: code-review
|
|
|
3
3
|
description: Deep code review methodology for thorough quality assessment
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Code Review
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
##
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
6
|
+
# Code Review
|
|
7
|
+
|
|
8
|
+
Identify defects, security risks, and maintainability problems in code changes before they merge.
|
|
9
|
+
|
|
10
|
+
## Quick Reference
|
|
11
|
+
|
|
12
|
+
| Aspect | Detail |
|
|
13
|
+
|---|---|
|
|
14
|
+
| **Input** | PR diff, file contents, PR title/description |
|
|
15
|
+
| **Output** | Structured findings (see Finding Format below) |
|
|
16
|
+
| **Scope** | Changed lines + immediate context; follow references 1 level deep when a change touches a public API |
|
|
17
|
+
| **Skip** | Formatting, import order, whitespace — defer to linters |
|
|
18
|
+
| **Depth** | Read every changed line; skim unchanged context for broken assumptions |
|
|
19
|
+
|
|
20
|
+
## Finding Format
|
|
21
|
+
|
|
22
|
+
Each finding MUST follow this structure:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
**[severity]** `file:line` — Description of the issue.
|
|
26
|
+
Suggestion: concrete fix or direction.
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Severity levels:**
|
|
30
|
+
|
|
31
|
+
| Level | Meaning | Gate |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| `error` | Bugs, security holes, data loss, crashes | MUST fix before merge |
|
|
34
|
+
| `warning` | Wrong abstraction, missing validation, performance trap | SHOULD fix |
|
|
35
|
+
| `info` | Naming, style, minor simplification | Nice to have |
|
|
36
|
+
|
|
37
|
+
## Review Procedure
|
|
38
|
+
|
|
39
|
+
Execute these phases in order. Each phase produces findings or nothing.
|
|
40
|
+
|
|
41
|
+
### Phase 1 — Understand Intent
|
|
42
|
+
Read the PR title, description, and linked issues. Determine what the change is supposed to do. If intent is unclear, report as `warning` before proceeding.
|
|
43
|
+
|
|
44
|
+
### Phase 2 — Correctness
|
|
45
|
+
For each changed function/block:
|
|
46
|
+
- Trace inputs through the logic. Identify domain boundaries (null, empty, zero, negative, max-length).
|
|
47
|
+
- For each boundary, verify the code handles or explicitly rejects it. Unhandled → `error`.
|
|
48
|
+
- Check return values: can a caller confuse a failure return with a success? Silent failures → `error`.
|
|
49
|
+
|
|
50
|
+
### Phase 3 — Security
|
|
51
|
+
At every system boundary (user input, HTTP params, DB queries, shell commands, file paths):
|
|
52
|
+
- Verify input is validated or sanitized before use. Missing → `error`.
|
|
53
|
+
- Check for secrets in code, logs, or error messages. Present → `error`.
|
|
54
|
+
- Verify auth checks exist for protected operations. Missing → `error`.
|
|
55
|
+
|
|
56
|
+
### Phase 4 — Performance
|
|
57
|
+
- Identify loops over collections: is work inside the loop that could be batched or hoisted? Report as `warning`.
|
|
58
|
+
- Look for N+1 patterns: a query inside a loop that iterates query results. Report as `warning`.
|
|
59
|
+
- Flag unbounded lists or payloads with no pagination/limit. Report as `warning`.
|
|
60
|
+
|
|
61
|
+
### Phase 5 — Maintainability
|
|
62
|
+
- Flag functions doing more than one job (needs "and" to describe) → `warning`.
|
|
63
|
+
- Flag duplicated logic across the diff (same pattern 2+ times) → `info`.
|
|
64
|
+
- Flag misleading names (function name promises X, body does Y) → `warning`.
|
|
65
|
+
|
|
66
|
+
### Phase 6 — Tests
|
|
67
|
+
- If the change adds behavior, verify a test covers the happy path. Missing → `warning`.
|
|
68
|
+
- If the change fixes a bug, verify a regression test exists. Missing → `warning`.
|
|
69
|
+
- Flag non-deterministic tests (time-dependent, random, order-dependent) → `warning`.
|
|
70
|
+
|
|
71
|
+
## Examples
|
|
72
|
+
|
|
73
|
+
### Bug: unhandled null at domain boundary
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
// PR diff
|
|
77
|
+
function getUser(id: string) {
|
|
78
|
+
const row = db.query("SELECT * FROM users WHERE id = ?", [id]);
|
|
79
|
+
return { name: row.name, email: row.email };
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Finding:**
|
|
84
|
+
```
|
|
85
|
+
**[error]** `src/users.ts:3` — `db.query` returns `null` when no row matches,
|
|
86
|
+
but the next line unconditionally accesses `.name` on the result.
|
|
87
|
+
Suggestion: Guard with `if (!row) return null` or throw a NotFoundError.
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Security: unsanitized input in shell command
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
# PR diff
|
|
94
|
+
def export_report(filename):
|
|
95
|
+
os.system(f"tar czf /tmp/{filename}.tar.gz /data/reports")
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Finding:**
|
|
99
|
+
```
|
|
100
|
+
**[error]** `reports/export.py:3` — `filename` is interpolated into a shell
|
|
101
|
+
command without sanitization. An attacker passing `; rm -rf /` exploits this.
|
|
102
|
+
Suggestion: Use `subprocess.run(["tar", "czf", ...])` with a list to avoid shell injection,
|
|
103
|
+
and validate `filename` against an allowlist pattern.
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### N+1 query in loop
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
// PR diff
|
|
110
|
+
const orders = await db.orders.findMany({ where: { status: "open" } });
|
|
111
|
+
for (const order of orders) {
|
|
112
|
+
const customer = await db.customers.findUnique({ where: { id: order.customerId } });
|
|
113
|
+
order.customerName = customer.name;
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Finding:**
|
|
118
|
+
```
|
|
119
|
+
**[warning]** `src/orders.ts:2-5` — Each loop iteration issues a separate
|
|
120
|
+
DB query for the customer. With N open orders this is N+1 queries.
|
|
121
|
+
Suggestion: Use `include: { customer: true }` in the initial query, or
|
|
122
|
+
batch-fetch customers with `findMany({ where: { id: { in: customerIds } } })`.
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## MUST DO / MUST NOT DO
|
|
126
|
+
|
|
127
|
+
| MUST DO | MUST NOT DO |
|
|
128
|
+
|---|---|
|
|
129
|
+
| Report every finding with file, line, severity, and suggestion | Report vague findings without location or fix direction |
|
|
130
|
+
| Prioritize errors first, then warnings, then info | Bury a critical bug under 10 style nits |
|
|
131
|
+
| Read the full diff before writing findings | Review only the first file and stop |
|
|
132
|
+
| Verify claims by reading the referenced code | Assume a pattern is wrong without checking the implementation |
|
|
133
|
+
| Limit info-level findings to 5 max | Flood the review with cosmetic suggestions |
|
|
134
|
+
|
|
135
|
+
## Final Checklist
|
|
136
|
+
|
|
137
|
+
Before submitting your review, verify:
|
|
138
|
+
- [ ] Every `error` finding includes a concrete reproduction scenario or input
|
|
139
|
+
- [ ] Every finding has `file:line`, severity, description, and suggestion
|
|
140
|
+
- [ ] Findings are grouped by severity (errors first)
|
|
141
|
+
- [ ] No duplicate findings (same root cause reported once, not per-occurrence)
|
|
142
|
+
- [ ] If zero findings: explicitly state "No issues found" — do not return empty output
|