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.
Files changed (57) hide show
  1. package/package.json +3 -3
  2. package/skills/context-mode/SKILL.md +38 -0
  3. package/skills/qa-strategy/SKILL.md +103 -21
  4. package/src/commands/config.ts +23 -2
  5. package/src/commands/fix-pr.ts +1 -1
  6. package/src/commands/plan.ts +1 -1
  7. package/src/commands/qa.ts +232 -148
  8. package/src/commands/release.ts +1 -1
  9. package/src/commands/review.ts +1 -1
  10. package/src/commands/run.ts +9 -4
  11. package/src/commands/supi.ts +1 -1
  12. package/src/config/defaults.ts +11 -0
  13. package/src/config/schema.ts +11 -0
  14. package/src/context-mode/compressor.ts +200 -0
  15. package/src/context-mode/detector.ts +43 -0
  16. package/src/context-mode/event-extractor.ts +170 -0
  17. package/src/context-mode/event-store.ts +168 -0
  18. package/src/context-mode/hooks.ts +176 -0
  19. package/src/context-mode/installer.ts +71 -0
  20. package/src/context-mode/snapshot-builder.ts +127 -0
  21. package/src/discipline/debugging.ts +7 -7
  22. package/src/discipline/receiving-review.ts +5 -5
  23. package/src/discipline/tdd.ts +2 -2
  24. package/src/discipline/verification.ts +9 -9
  25. package/src/git/base-branch.ts +30 -0
  26. package/src/git/branch-finish.ts +12 -3
  27. package/src/git/sanitize.ts +19 -0
  28. package/src/git/worktree.ts +38 -11
  29. package/src/index.ts +8 -1
  30. package/src/orchestrator/agent-prompts.ts +15 -7
  31. package/src/orchestrator/conflict-resolver.ts +3 -2
  32. package/src/orchestrator/dispatcher.ts +76 -21
  33. package/src/orchestrator/prompts.ts +46 -6
  34. package/src/planning/plan-reviewer.ts +1 -1
  35. package/src/planning/plan-writer-prompt.ts +6 -9
  36. package/src/planning/prompt-builder.ts +17 -16
  37. package/src/planning/spec-reviewer.ts +2 -2
  38. package/src/qa/config.ts +43 -0
  39. package/src/qa/matrix.ts +84 -0
  40. package/src/qa/prompt-builder.ts +212 -0
  41. package/src/qa/scripts/detect-app-type.sh +68 -0
  42. package/src/qa/scripts/discover-routes.sh +143 -0
  43. package/src/qa/scripts/ensure-playwright.sh +38 -0
  44. package/src/qa/scripts/run-e2e-tests.sh +99 -0
  45. package/src/qa/scripts/start-dev-server.sh +46 -0
  46. package/src/qa/scripts/stop-dev-server.sh +36 -0
  47. package/src/qa/session.ts +39 -55
  48. package/src/qa/types.ts +97 -0
  49. package/src/storage/qa-sessions.ts +9 -9
  50. package/src/types.ts +22 -70
  51. package/src/qa/detector.ts +0 -61
  52. package/src/qa/phases/discovery.ts +0 -34
  53. package/src/qa/phases/execution.ts +0 -65
  54. package/src/qa/phases/matrix.ts +0 -41
  55. package/src/qa/phases/reporting.ts +0 -71
  56. package/src/qa/report.ts +0 -22
  57. package/src/qa/runner.ts +0 -46
@@ -1,3 +1,4 @@
1
+ import { assertSafeRef } from "./sanitize.js";
1
2
  import * as fs from "node:fs";
2
3
  import * as path from "node:path";
3
4
 
@@ -25,20 +26,44 @@ export function detectWorktreeDir(cwd: string): string | null {
25
26
  * Auto-detect project type and setup commands from project files.
26
27
  */
27
28
  export function detectProjectSetup(cwd: string): ProjectSetup {
29
+ // Bun (check before generic package.json since Bun projects also have package.json)
30
+ if (fs.existsSync(path.join(cwd, "bun.lock")) || fs.existsSync(path.join(cwd, "bun.lockb"))) {
31
+ return { type: "node", installCommand: "bun install", testCommand: "bun test" };
32
+ }
28
33
  if (fs.existsSync(path.join(cwd, "package.json"))) {
29
- return { type: "node", installCommand: "npm install", testCommand: "npm test" };
34
+ return {
35
+ type: "node",
36
+ installCommand: "npm install",
37
+ testCommand: "npm test",
38
+ };
30
39
  }
31
40
  if (fs.existsSync(path.join(cwd, "Cargo.toml"))) {
32
- return { type: "rust", installCommand: "cargo build", testCommand: "cargo test" };
33
- }
34
- if (fs.existsSync(path.join(cwd, "requirements.txt"))) {
35
- return { type: "python", installCommand: "pip install -r requirements.txt", testCommand: "pytest" };
41
+ return {
42
+ type: "rust",
43
+ installCommand: "cargo build",
44
+ testCommand: "cargo test",
45
+ };
36
46
  }
37
47
  if (fs.existsSync(path.join(cwd, "pyproject.toml"))) {
38
- return { type: "python", installCommand: "poetry install", testCommand: "pytest" };
48
+ return {
49
+ type: "python",
50
+ installCommand: "poetry install",
51
+ testCommand: "pytest",
52
+ };
53
+ }
54
+ if (fs.existsSync(path.join(cwd, "requirements.txt"))) {
55
+ return {
56
+ type: "python",
57
+ installCommand: "pip install -r requirements.txt",
58
+ testCommand: "pytest",
59
+ };
39
60
  }
40
61
  if (fs.existsSync(path.join(cwd, "go.mod"))) {
41
- return { type: "go", installCommand: "go mod download", testCommand: "go test ./..." };
62
+ return {
63
+ type: "go",
64
+ installCommand: "go mod download",
65
+ testCommand: "go test ./...",
66
+ };
42
67
  }
43
68
  return { type: "unknown", installCommand: null, testCommand: null };
44
69
  }
@@ -50,7 +75,7 @@ export interface WorktreePromptOptions {
50
75
 
51
76
  /**
52
77
  * Build the prompt that guides the agent through creating an isolated git worktree.
53
- * Follows superpowers' using-git-worktrees skill:
78
+ * Follows supipowers' using-git-worktrees skill:
54
79
  * - Smart directory selection (.worktrees > worktrees > ask)
55
80
  * - .gitignore verification
56
81
  * - Project setup detection
@@ -58,6 +83,7 @@ export interface WorktreePromptOptions {
58
83
  */
59
84
  export function buildWorktreePrompt(options: WorktreePromptOptions): string {
60
85
  const { branchName, cwd } = options;
86
+ assertSafeRef(branchName, "branchName");
61
87
 
62
88
  return [
63
89
  "## Set Up Isolated Worktree",
@@ -71,8 +97,8 @@ export function buildWorktreePrompt(options: WorktreePromptOptions): string {
71
97
  `2. \`${cwd}/worktrees/\` — if it exists, use it`,
72
98
  "3. Check CLAUDE.md for worktree directory preference",
73
99
  "4. If none found, ask the user:",
74
- ' - `.worktrees/` (project-local, hidden)',
75
- ' - `~/.config/supipowers/worktrees/<project>/` (global location)',
100
+ " - `.worktrees/` (project-local, hidden)",
101
+ " - `~/.config/supipowers/worktrees/<project>/` (global location)",
76
102
  "",
77
103
  "### Step 2: Verify gitignore",
78
104
  "",
@@ -97,10 +123,11 @@ export function buildWorktreePrompt(options: WorktreePromptOptions): string {
97
123
  "",
98
124
  "| File | Command |",
99
125
  "|------|---------|",
126
+ "| `bun.lock` / `bun.lockb` | `bun install` |",
100
127
  "| `package.json` | `npm install` |",
101
128
  "| `Cargo.toml` | `cargo build` |",
102
- "| `requirements.txt` | `pip install -r requirements.txt` |",
103
129
  "| `pyproject.toml` | `poetry install` |",
130
+ "| `requirements.txt` | `pip install -r requirements.txt` |",
104
131
  "| `go.mod` | `go mod download` |",
105
132
  "",
106
133
  "### Step 5: Verify baseline",
package/src/index.ts CHANGED
@@ -13,12 +13,14 @@ import { registerQaCommand } from "./commands/qa.js";
13
13
  import { registerReleaseCommand } from "./commands/release.js";
14
14
  import { registerUpdateCommand, handleUpdate } from "./commands/update.js";
15
15
  import { registerFixPrCommand } from "./commands/fix-pr.js";
16
+ import { loadConfig } from "./config/loader.js";
17
+ import { registerContextModeHooks } from "./context-mode/hooks.js";
16
18
 
17
19
  // TUI-only commands — intercepted at the input level to prevent
18
20
  // message submission and "Working..." indicator
19
21
  const TUI_COMMANDS: Record<string, (pi: ExtensionAPI, ctx: any) => void> = {
20
22
  "supi": (pi, ctx) => handleSupi(pi, ctx),
21
- "supi:config": (_pi, ctx) => handleConfig(ctx),
23
+ "supi:config": (pi, ctx) => handleConfig(pi, ctx),
22
24
  "supi:status": (_pi, ctx) => handleStatus(ctx),
23
25
  "supi:update": (pi, ctx) => handleUpdate(pi, ctx),
24
26
  };
@@ -62,6 +64,11 @@ export default function supipowers(pi: ExtensionAPI): void {
62
64
  return { handled: true };
63
65
  });
64
66
 
67
+ // Context-mode integration
68
+ const config = loadConfig(process.cwd());
69
+ registerContextModeHooks(pi, config);
70
+
71
+
65
72
  // Session start
66
73
  pi.on("session_start", async (_event, ctx) => {
67
74
  // Clean up any leftover visual companion from a previous session
@@ -13,7 +13,7 @@ export interface ImplementerPromptOptions {
13
13
 
14
14
  /**
15
15
  * Build the prompt for an implementer sub-agent.
16
- * Follows superpowers' implementer-prompt.md pattern:
16
+ * Follows supipowers' implementer-prompt.md pattern:
17
17
  * - Full task description
18
18
  * - Ask-before-starting section
19
19
  * - TDD and code organization guidance
@@ -21,7 +21,9 @@ export interface ImplementerPromptOptions {
21
21
  * - Self-review before reporting
22
22
  * - Structured report format
23
23
  */
24
- export function buildImplementerPrompt(options: ImplementerPromptOptions): string {
24
+ export function buildImplementerPrompt(
25
+ options: ImplementerPromptOptions,
26
+ ): string {
25
27
  const { task, planContext, workDir } = options;
26
28
 
27
29
  return [
@@ -33,7 +35,9 @@ export function buildImplementerPrompt(options: ImplementerPromptOptions): strin
33
35
  "",
34
36
  "## Target Files",
35
37
  "",
36
- ...task.files.map((f) => `- ${f}`),
38
+ ...(task.files.length > 0
39
+ ? task.files.map((f) => `- ${f}`)
40
+ : ["(No specific files targeted \u2014 determine from task description)"]),
37
41
  "",
38
42
  "## Acceptance Criteria",
39
43
  "",
@@ -152,12 +156,14 @@ export interface SpecComplianceReviewOptions {
152
156
 
153
157
  /**
154
158
  * Build the prompt for a spec compliance reviewer sub-agent.
155
- * Follows superpowers' spec-reviewer-prompt.md pattern:
159
+ * Follows supipowers' spec-reviewer-prompt.md pattern:
156
160
  * - Do not trust the implementer's report
157
161
  * - Verify by reading actual code
158
162
  * - Check for missing, extra, and misunderstood requirements
159
163
  */
160
- export function buildSpecComplianceReviewPrompt(options: SpecComplianceReviewOptions): string {
164
+ export function buildSpecComplianceReviewPrompt(
165
+ options: SpecComplianceReviewOptions,
166
+ ): string {
161
167
  const { taskRequirements, implementerReport } = options;
162
168
 
163
169
  return [
@@ -225,12 +231,14 @@ export interface CodeQualityReviewOptions {
225
231
 
226
232
  /**
227
233
  * Build the prompt for a code quality reviewer sub-agent.
228
- * Follows superpowers' code-quality-reviewer-prompt.md pattern:
234
+ * Follows supipowers' code-quality-reviewer-prompt.md pattern:
229
235
  * - Review git diff between base and head
230
236
  * - Check file responsibilities and unit decomposition
231
237
  * - Categorize issues as Critical/Important/Minor
232
238
  */
233
- export function buildCodeQualityReviewPrompt(options: CodeQualityReviewOptions): string {
239
+ export function buildCodeQualityReviewPrompt(
240
+ options: CodeQualityReviewOptions,
241
+ ): string {
234
242
  const { taskSummary, implementerReport, baseSha, headSha } = options;
235
243
 
236
244
  return [
@@ -10,7 +10,8 @@ export interface ConflictResolution {
10
10
 
11
11
  export function analyzeConflicts(
12
12
  results: AgentResult[],
13
- tasks: PlanTask[]
13
+ tasks: PlanTask[],
14
+ contextModeAvailable = false,
14
15
  ): ConflictResolution {
15
16
  const conflictingFiles = detectConflicts(results);
16
17
 
@@ -33,6 +34,6 @@ export function analyzeConflicts(
33
34
  return {
34
35
  hasConflicts: true,
35
36
  conflictingFiles,
36
- mergePrompt: buildMergePrompt(conflictingFiles, agentOutputs),
37
+ mergePrompt: buildMergePrompt(conflictingFiles, agentOutputs, contextModeAvailable),
37
38
  };
38
39
  }
@@ -1,27 +1,44 @@
1
1
  import type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent";
2
- import type { PlanTask, AgentResult, AgentStatus, SupipowersConfig } from "../types.js";
2
+ import type {
3
+ PlanTask,
4
+ AgentResult,
5
+ AgentStatus,
6
+ SupipowersConfig,
7
+ } from "../types.js";
3
8
  import { buildTaskPrompt, buildFixPrompt } from "./prompts.js";
4
9
  import {
5
10
  buildSpecComplianceReviewPrompt,
6
11
  buildCodeQualityReviewPrompt,
7
12
  } from "./agent-prompts.js";
8
13
  import { isLspAvailable } from "../lsp/detector.js";
9
- import { notifySuccess, notifyWarning, notifyError, notifyInfo } from "../notifications/renderer.js";
14
+ import { detectContextMode } from "../context-mode/detector.js";
15
+ import {
16
+ notifySuccess,
17
+ notifyWarning,
18
+ notifyError,
19
+ notifyInfo,
20
+ } from "../notifications/renderer.js";
10
21
 
11
22
  export interface DispatchOptions {
12
23
  pi: ExtensionAPI;
13
- ctx: { cwd: string; ui: { notify(msg: string, type?: "info" | "warning" | "error"): void } };
24
+ ctx: {
25
+ cwd: string;
26
+ ui: { notify(msg: string, type?: "info" | "warning" | "error"): void };
27
+ };
14
28
  task: PlanTask;
15
29
  planContext: string;
16
30
  config: SupipowersConfig;
17
31
  lspAvailable: boolean;
32
+ contextModeAvailable: boolean;
18
33
  }
19
34
 
20
- export async function dispatchAgent(options: DispatchOptions): Promise<AgentResult> {
21
- const { pi, ctx, task, planContext, config, lspAvailable } = options;
35
+ export async function dispatchAgent(
36
+ options: DispatchOptions,
37
+ ): Promise<AgentResult> {
38
+ const { pi, ctx, task, planContext, config, lspAvailable, contextModeAvailable } = options;
22
39
  const startTime = Date.now();
23
40
 
24
- const prompt = buildTaskPrompt(task, planContext, config, lspAvailable);
41
+ const prompt = buildTaskPrompt(task, planContext, config, lspAvailable, contextModeAvailable);
25
42
 
26
43
  try {
27
44
  const result = await executeSubAgent(pi, prompt, task, config);
@@ -40,7 +57,11 @@ export async function dispatchAgent(options: DispatchOptions): Promise<AgentResu
40
57
  notifySuccess(ctx, `Task ${task.id} completed`, task.name);
41
58
  break;
42
59
  case "done_with_concerns":
43
- notifyWarning(ctx, `Task ${task.id} done with concerns`, agentResult.concerns);
60
+ notifyWarning(
61
+ ctx,
62
+ `Task ${task.id} done with concerns`,
63
+ agentResult.concerns,
64
+ );
44
65
  break;
45
66
  case "blocked":
46
67
  notifyError(ctx, `Task ${task.id} blocked`, agentResult.output);
@@ -72,11 +93,11 @@ async function executeSubAgent(
72
93
  pi: ExtensionAPI,
73
94
  prompt: string,
74
95
  task: PlanTask,
75
- config: SupipowersConfig
96
+ config: SupipowersConfig,
76
97
  ): Promise<SubAgentResult> {
77
98
  throw new Error(
78
99
  "Sub-agent dispatch requires OMP runtime. " +
79
- "This will be connected to createAgentSession during integration."
100
+ "This will be connected to createAgentSession during integration.",
80
101
  );
81
102
  }
82
103
 
@@ -88,7 +109,7 @@ export interface ReviewResult {
88
109
 
89
110
  /**
90
111
  * Dispatch an implementer with 2-stage review (spec compliance + code quality).
91
- * Follows superpowers' subagent-driven-development pattern:
112
+ * Follows supipowers' subagent-driven-development pattern:
92
113
  * 1. Implementer implements + self-reviews
93
114
  * 2. Spec compliance reviewer verifies implementation matches spec
94
115
  * 3. If spec issues → re-dispatch implementer with feedback
@@ -98,7 +119,7 @@ export interface ReviewResult {
98
119
  export async function dispatchAgentWithReview(
99
120
  options: DispatchOptions & { workDir?: string },
100
121
  ): Promise<AgentResult> {
101
- const { pi, ctx, task, planContext, config, lspAvailable, workDir } = options;
122
+ const { pi, ctx, task, planContext, config, lspAvailable, contextModeAvailable, workDir } = options;
102
123
  const maxReviewRetries = config.orchestration.maxFixRetries;
103
124
 
104
125
  // Step 1: Dispatch implementer
@@ -111,7 +132,12 @@ export async function dispatchAgentWithReview(
111
132
 
112
133
  // Step 2: Spec compliance review
113
134
  for (let attempt = 0; attempt <= maxReviewRetries; attempt++) {
114
- const specReview = await dispatchSpecReview(pi, task, implementResult, config);
135
+ const specReview = await dispatchSpecReview(
136
+ pi,
137
+ task,
138
+ implementResult,
139
+ config,
140
+ );
115
141
 
116
142
  if (specReview.passed) {
117
143
  notifyInfo(ctx, `Task ${task.id} spec review passed`);
@@ -119,14 +145,22 @@ export async function dispatchAgentWithReview(
119
145
  }
120
146
 
121
147
  if (attempt === maxReviewRetries) {
122
- notifyWarning(ctx, `Task ${task.id} spec review failed after ${maxReviewRetries + 1} attempts`, specReview.issues);
148
+ notifyWarning(
149
+ ctx,
150
+ `Task ${task.id} spec review failed after ${maxReviewRetries + 1} attempts`,
151
+ specReview.issues,
152
+ );
123
153
  implementResult.status = "done_with_concerns";
124
154
  implementResult.concerns = `Spec compliance issues: ${specReview.issues}`;
125
155
  return implementResult;
126
156
  }
127
157
 
128
158
  // Re-dispatch implementer with spec review feedback
129
- notifyInfo(ctx, `Task ${task.id} spec issues found, re-dispatching`, specReview.issues);
159
+ notifyInfo(
160
+ ctx,
161
+ `Task ${task.id} spec issues found, re-dispatching`,
162
+ specReview.issues,
163
+ );
130
164
  const fixResult = await dispatchFixAgent({
131
165
  ...options,
132
166
  previousOutput: implementResult.output,
@@ -141,7 +175,12 @@ export async function dispatchAgentWithReview(
141
175
 
142
176
  // Step 3: Code quality review
143
177
  for (let attempt = 0; attempt <= maxReviewRetries; attempt++) {
144
- const qualityReview = await dispatchQualityReview(pi, task, implementResult, config);
178
+ const qualityReview = await dispatchQualityReview(
179
+ pi,
180
+ task,
181
+ implementResult,
182
+ config,
183
+ );
145
184
 
146
185
  if (qualityReview.passed) {
147
186
  notifyInfo(ctx, `Task ${task.id} quality review passed`);
@@ -149,14 +188,22 @@ export async function dispatchAgentWithReview(
149
188
  }
150
189
 
151
190
  if (attempt === maxReviewRetries) {
152
- notifyWarning(ctx, `Task ${task.id} quality review failed after ${maxReviewRetries + 1} attempts`, qualityReview.issues);
191
+ notifyWarning(
192
+ ctx,
193
+ `Task ${task.id} quality review failed after ${maxReviewRetries + 1} attempts`,
194
+ qualityReview.issues,
195
+ );
153
196
  implementResult.status = "done_with_concerns";
154
197
  implementResult.concerns = `Code quality issues: ${qualityReview.issues}`;
155
198
  return implementResult;
156
199
  }
157
200
 
158
201
  // Re-dispatch implementer with quality review feedback
159
- notifyInfo(ctx, `Task ${task.id} quality issues found, re-dispatching`, qualityReview.issues);
202
+ notifyInfo(
203
+ ctx,
204
+ `Task ${task.id} quality issues found, re-dispatching`,
205
+ qualityReview.issues,
206
+ );
160
207
  const fixResult = await dispatchFixAgent({
161
208
  ...options,
162
209
  previousOutput: implementResult.output,
@@ -186,7 +233,8 @@ async function dispatchSpecReview(
186
233
 
187
234
  try {
188
235
  const result = await executeSubAgent(pi, prompt, task, config);
189
- const passed = result.status === "done" ||
236
+ const passed =
237
+ result.status === "done" ||
190
238
  result.output.toLowerCase().includes("spec compliant");
191
239
  return {
192
240
  passed,
@@ -226,12 +274,19 @@ async function dispatchQualityReview(
226
274
  }
227
275
 
228
276
  export async function dispatchFixAgent(
229
- options: DispatchOptions & { previousOutput: string; failureReason: string }
277
+ options: DispatchOptions & { previousOutput: string; failureReason: string },
230
278
  ): Promise<AgentResult> {
231
- const { pi, ctx, task, config, lspAvailable, previousOutput, failureReason } = options;
279
+ const { pi, ctx, task, config, lspAvailable, contextModeAvailable, previousOutput, failureReason } =
280
+ options;
232
281
  const startTime = Date.now();
233
282
 
234
- const prompt = buildFixPrompt(task, previousOutput, failureReason, lspAvailable);
283
+ const prompt = buildFixPrompt(
284
+ task,
285
+ previousOutput,
286
+ failureReason,
287
+ lspAvailable,
288
+ contextModeAvailable,
289
+ );
235
290
 
236
291
  try {
237
292
  const result = await executeSubAgent(pi, prompt, task, config);
@@ -10,17 +10,18 @@ export function buildTaskPrompt(
10
10
  planContext: string,
11
11
  config: SupipowersConfig,
12
12
  lspAvailable: boolean,
13
+ contextModeAvailable = false,
13
14
  workDir?: string,
14
15
  ): string {
15
- const prompt = buildImplementerPrompt({
16
+ let result = buildImplementerPrompt({
16
17
  task,
17
18
  planContext,
18
19
  workDir: workDir ?? process.cwd(),
19
20
  });
20
21
 
21
22
  if (lspAvailable) {
22
- return [
23
- prompt,
23
+ result = [
24
+ result,
24
25
  "",
25
26
  "## LSP Available",
26
27
  "You have access to the LSP tool. Use it to:",
@@ -32,7 +33,22 @@ export function buildTaskPrompt(
32
33
  ].join("\n");
33
34
  }
34
35
 
35
- return prompt;
36
+ if (contextModeAvailable) {
37
+ result = [
38
+ result,
39
+ "",
40
+ "## Context Mode Available",
41
+ "You have access to context-mode sandbox tools. Prefer them for large operations:",
42
+ "- Use `ctx_batch_execute` for multi-step operations",
43
+ "- Use `ctx_search` for querying indexed knowledge",
44
+ "- Use `ctx_execute` for single commands with large output",
45
+ "- Do NOT use `curl`/`wget` \u2014 use `ctx_fetch_and_index`",
46
+ "- Do NOT use Read for analyzing large files \u2014 use `ctx_execute_file`",
47
+ "- Keep output under 500 words; write large artifacts to files",
48
+ ].join("\n");
49
+ }
50
+
51
+ return result;
36
52
  }
37
53
 
38
54
  /** Build prompt for a fix agent */
@@ -40,7 +56,8 @@ export function buildFixPrompt(
40
56
  task: PlanTask,
41
57
  previousOutput: string,
42
58
  failureReason: string,
43
- lspAvailable: boolean
59
+ lspAvailable: boolean,
60
+ contextModeAvailable = false,
44
61
  ): string {
45
62
  const sections: string[] = [
46
63
  "# Fix Assignment",
@@ -74,13 +91,28 @@ export function buildFixPrompt(
74
91
  sections.push("", buildLspValidationPrompt(task.files));
75
92
  }
76
93
 
94
+ if (contextModeAvailable) {
95
+ sections.push(
96
+ "",
97
+ "## Context Mode Available",
98
+ "You have access to context-mode sandbox tools. Prefer them for large operations:",
99
+ "- Use `ctx_batch_execute` for multi-step operations",
100
+ "- Use `ctx_search` for querying indexed knowledge",
101
+ "- Use `ctx_execute` for single commands with large output",
102
+ "- Do NOT use `curl`/`wget` \u2014 use `ctx_fetch_and_index`",
103
+ "- Do NOT use Read for analyzing large files \u2014 use `ctx_execute_file`",
104
+ "- Keep output under 500 words; write large artifacts to files",
105
+ );
106
+ }
107
+
77
108
  return sections.join("\n");
78
109
  }
79
110
 
80
111
  /** Build prompt for a merge/conflict resolution agent */
81
112
  export function buildMergePrompt(
82
113
  conflictingFiles: string[],
83
- agentOutputs: { taskName: string; output: string }[]
114
+ agentOutputs: { taskName: string; output: string }[],
115
+ contextModeAvailable = false,
84
116
  ): string {
85
117
  const sections: string[] = [
86
118
  "# Merge Assignment",
@@ -105,5 +137,13 @@ export function buildMergePrompt(
105
137
  "4. If changes are incompatible, report BLOCKED with explanation"
106
138
  );
107
139
 
140
+ if (contextModeAvailable) {
141
+ sections.push(
142
+ "",
143
+ "## Context Mode Available",
144
+ "Prefer context-mode sandbox tools for large operations.",
145
+ );
146
+ }
147
+
108
148
  return sections.join("\n");
109
149
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Build the prompt for dispatching a plan document reviewer sub-agent.
3
- * Follows the same pattern as superpowers' plan-document-reviewer-prompt.md.
3
+ * Follows the same pattern as supipowers' plan-document-reviewer-prompt.md.
4
4
  */
5
5
  export function buildPlanReviewerPrompt(
6
6
  planFilePath: string,
@@ -1,4 +1,3 @@
1
- import { buildPlanReviewerPrompt } from "./plan-reviewer.js";
2
1
 
3
2
  export interface PlanWriterOptions {
4
3
  specPath: string;
@@ -8,7 +7,7 @@ export interface PlanWriterOptions {
8
7
  * Build the plan writing prompt that guides the agent through creating
9
8
  * a comprehensive implementation plan from an approved spec.
10
9
  *
11
- * Follows superpowers' writing-plans skill:
10
+ * Follows supipowers' writing-plans skill:
12
11
  * - Scope check
13
12
  * - File structure mapping
14
13
  * - Bite-sized tasks with TDD steps
@@ -139,13 +138,11 @@ export function buildPlanWriterPrompt(options: PlanWriterOptions): string {
139
138
  "",
140
139
  "Use `## Chunk N: <name>` headings to delimit chunks. Each chunk should be under 1000 lines and logically self-contained.",
141
140
  "",
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.)",
141
+ "1. Dispatch a plan-document-reviewer sub-agent for each chunk.",
142
+ " The reviewer checks: completeness, spec alignment, task decomposition,",
143
+ " file structure, file size rules, checkbox syntax, and chunk size.",
144
+ " Provide the reviewer with: the plan file path, the spec file path, and the chunk number.",
145
+
149
146
  "",
150
147
  "2. If **Issues Found**: fix the issues, re-dispatch the reviewer",
151
148
  "3. Repeat until **Approved** (max 5 iterations, then surface to human for guidance)",
@@ -10,7 +10,7 @@ export interface PlanningPromptOptions {
10
10
  * Build the comprehensive planning prompt that encodes the full brainstorming flow.
11
11
  * This is the steering prompt sent to the agent when `/supi:plan` runs.
12
12
  *
13
- * Follows superpowers' brainstorming skill flow:
13
+ * Follows supipowers' brainstorming skill flow:
14
14
  * 1. Explore project context
15
15
  * 2. Ask clarifying questions (one at a time)
16
16
  * 3. Propose 2-3 approaches with trade-offs
@@ -103,8 +103,6 @@ export function buildPlanningPrompt(options: PlanningPromptOptions): string {
103
103
  // ── Phase 7: User Gate ───────────────────────────────────────
104
104
  "## Phase 7: User Review Gate",
105
105
  "",
106
- "After the spec review loop passes:",
107
- "",
108
106
  "After the spec review loop passes, ask the user to review the spec before proceeding:",
109
107
  "",
110
108
  '> "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."',
@@ -137,12 +135,7 @@ export function buildPlanningPrompt(options: PlanningPromptOptions): string {
137
135
  ];
138
136
 
139
137
  if (skillContent) {
140
- sections.push(
141
- "## Additional Planning Guidelines",
142
- "",
143
- skillContent,
144
- "",
145
- );
138
+ sections.push("## Additional Planning Guidelines", "", skillContent, "");
146
139
  }
147
140
 
148
141
  return sections.join("\n");
@@ -152,14 +145,26 @@ export function buildPlanningPrompt(options: PlanningPromptOptions): string {
152
145
  * Build the quick plan prompt that skips brainstorming.
153
146
  * Used when `/supi:plan --quick <description>` is invoked.
154
147
  */
155
- export function buildQuickPlanPrompt(description: string, skillContent?: string): string {
148
+ export function buildQuickPlanPrompt(
149
+ description: string,
150
+ skillContent?: string,
151
+ ): string {
156
152
  const sections: string[] = [
157
153
  "Generate a concise implementation plan for the following task.",
158
154
  "Skip brainstorming — go straight to task breakdown.",
159
155
  "",
160
156
  `Task: ${description}`,
161
157
  "",
162
- "Format the plan as markdown with YAML frontmatter (name, created, tags).",
158
+ "Format the plan as markdown with YAML frontmatter:",
159
+ "",
160
+ "```yaml",
161
+ "---",
162
+ "name: <feature-name>",
163
+ "created: YYYY-MM-DD",
164
+ "tags: [tag1, tag2]",
165
+ "---",
166
+ "```",
167
+ "",
163
168
  "Each task should have: name, [parallel-safe] or [sequential] annotation,",
164
169
  "**files**, **criteria**, and **complexity** (small/medium/large).",
165
170
  "",
@@ -167,11 +172,7 @@ export function buildQuickPlanPrompt(description: string, skillContent?: string)
167
172
  ];
168
173
 
169
174
  if (skillContent) {
170
- sections.push(
171
- "",
172
- "Follow these planning guidelines:",
173
- skillContent,
174
- );
175
+ sections.push("", "Follow these planning guidelines:", skillContent);
175
176
  }
176
177
 
177
178
  return sections.join("\n");
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Build the prompt for dispatching a spec document reviewer sub-agent.
3
- * Follows the same pattern as superpowers' spec-document-reviewer-prompt.md.
3
+ * Follows the same pattern as supipowers' spec-document-reviewer-prompt.md.
4
4
  */
5
5
  export function buildSpecReviewerPrompt(specFilePath: string): string {
6
6
  return [
@@ -12,7 +12,7 @@ export function buildSpecReviewerPrompt(specFilePath: string): string {
12
12
  "",
13
13
  "| Category | What to Look For |",
14
14
  "|----------|------------------|",
15
- "| Completeness | TODO markers, placeholders, \"TBD\", incomplete sections |",
15
+ '| Completeness | TODO markers, placeholders, "TBD", incomplete sections |',
16
16
  "| Coverage | Missing error handling, edge cases, integration points |",
17
17
  "| Consistency | Internal contradictions, conflicting requirements |",
18
18
  "| Clarity | Ambiguous requirements that could be interpreted multiple ways |",