wiggum-cli 0.16.0 → 0.17.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 (97) hide show
  1. package/bin/ralph.js +0 -0
  2. package/dist/agent/memory/ingest.d.ts +14 -0
  3. package/dist/agent/memory/ingest.js +77 -0
  4. package/dist/agent/memory/store.d.ts +15 -0
  5. package/dist/agent/memory/store.js +98 -0
  6. package/dist/agent/memory/types.d.ts +16 -0
  7. package/dist/agent/memory/types.js +14 -0
  8. package/dist/agent/orchestrator.d.ts +7 -0
  9. package/dist/agent/orchestrator.js +266 -0
  10. package/dist/agent/resolve-config.d.ts +26 -0
  11. package/dist/agent/resolve-config.js +43 -0
  12. package/dist/agent/tools/backlog.d.ts +27 -0
  13. package/dist/agent/tools/backlog.js +51 -0
  14. package/dist/agent/tools/dry-run.d.ts +106 -0
  15. package/dist/agent/tools/dry-run.js +119 -0
  16. package/dist/agent/tools/execution.d.ts +51 -0
  17. package/dist/agent/tools/execution.js +256 -0
  18. package/dist/agent/tools/feature-state.d.ts +43 -0
  19. package/dist/agent/tools/feature-state.js +184 -0
  20. package/dist/agent/tools/introspection.d.ts +23 -0
  21. package/dist/agent/tools/introspection.js +40 -0
  22. package/dist/agent/tools/memory.d.ts +44 -0
  23. package/dist/agent/tools/memory.js +99 -0
  24. package/dist/agent/tools/preflight.d.ts +7 -0
  25. package/dist/agent/tools/preflight.js +137 -0
  26. package/dist/agent/tools/reporting.d.ts +58 -0
  27. package/dist/agent/tools/reporting.js +119 -0
  28. package/dist/agent/tools/schemas.d.ts +2 -0
  29. package/dist/agent/tools/schemas.js +3 -0
  30. package/dist/agent/types.d.ts +45 -0
  31. package/dist/agent/types.js +1 -0
  32. package/dist/ai/conversation/conversation-manager.js +8 -0
  33. package/dist/ai/conversation/url-fetcher.js +27 -0
  34. package/dist/ai/providers.js +5 -5
  35. package/dist/commands/agent.d.ts +17 -0
  36. package/dist/commands/agent.js +114 -0
  37. package/dist/commands/monitor.js +50 -183
  38. package/dist/commands/new-auto.d.ts +15 -0
  39. package/dist/commands/new-auto.js +237 -0
  40. package/dist/commands/run.js +20 -10
  41. package/dist/commands/sync.d.ts +15 -0
  42. package/dist/commands/sync.js +68 -0
  43. package/dist/generator/config.d.ts +1 -41
  44. package/dist/generator/config.js +7 -0
  45. package/dist/generator/index.d.ts +2 -2
  46. package/dist/generator/templates.d.ts +2 -0
  47. package/dist/generator/templates.js +9 -1
  48. package/dist/index.d.ts +1 -1
  49. package/dist/index.js +115 -4
  50. package/dist/repl/command-parser.d.ts +5 -0
  51. package/dist/repl/command-parser.js +5 -0
  52. package/dist/templates/prompts/PROMPT.md.tmpl +13 -10
  53. package/dist/templates/prompts/PROMPT_e2e.md.tmpl +13 -7
  54. package/dist/templates/prompts/PROMPT_feature.md.tmpl +16 -3
  55. package/dist/templates/prompts/PROMPT_review_auto.md.tmpl +32 -12
  56. package/dist/templates/prompts/PROMPT_review_manual.md.tmpl +4 -1
  57. package/dist/templates/prompts/PROMPT_review_merge.md.tmpl +39 -14
  58. package/dist/templates/prompts/PROMPT_verify.md.tmpl +5 -2
  59. package/dist/templates/scripts/feature-loop.sh.tmpl +441 -69
  60. package/dist/tui/app.d.ts +19 -2
  61. package/dist/tui/app.js +22 -4
  62. package/dist/tui/components/IssuePicker.d.ts +27 -0
  63. package/dist/tui/components/IssuePicker.js +64 -0
  64. package/dist/tui/components/RunCompletionSummary.js +6 -3
  65. package/dist/tui/hooks/useAgentOrchestrator.d.ts +29 -0
  66. package/dist/tui/hooks/useAgentOrchestrator.js +453 -0
  67. package/dist/tui/orchestration/interview-orchestrator.d.ts +5 -1
  68. package/dist/tui/orchestration/interview-orchestrator.js +27 -6
  69. package/dist/tui/screens/AgentScreen.d.ts +21 -0
  70. package/dist/tui/screens/AgentScreen.js +159 -0
  71. package/dist/tui/screens/InitScreen.js +4 -0
  72. package/dist/tui/screens/InterviewScreen.d.ts +3 -1
  73. package/dist/tui/screens/InterviewScreen.js +146 -10
  74. package/dist/tui/screens/MainShell.d.ts +1 -1
  75. package/dist/tui/screens/MainShell.js +36 -1
  76. package/dist/tui/screens/RunScreen.js +38 -6
  77. package/dist/tui/utils/build-run-summary.d.ts +1 -1
  78. package/dist/tui/utils/build-run-summary.js +40 -84
  79. package/dist/tui/utils/clear-screen.d.ts +14 -0
  80. package/dist/tui/utils/clear-screen.js +16 -0
  81. package/dist/tui/utils/loop-status.d.ts +41 -1
  82. package/dist/tui/utils/loop-status.js +243 -35
  83. package/dist/tui/utils/pr-summary.d.ts +3 -2
  84. package/dist/tui/utils/pr-summary.js +41 -6
  85. package/dist/utils/config.d.ts +8 -0
  86. package/dist/utils/config.js +8 -0
  87. package/dist/utils/github.d.ts +32 -0
  88. package/dist/utils/github.js +106 -0
  89. package/package.json +4 -1
  90. package/src/templates/prompts/PROMPT.md.tmpl +13 -10
  91. package/src/templates/prompts/PROMPT_e2e.md.tmpl +13 -7
  92. package/src/templates/prompts/PROMPT_feature.md.tmpl +16 -3
  93. package/src/templates/prompts/PROMPT_review_auto.md.tmpl +32 -12
  94. package/src/templates/prompts/PROMPT_review_manual.md.tmpl +4 -1
  95. package/src/templates/prompts/PROMPT_review_merge.md.tmpl +39 -14
  96. package/src/templates/prompts/PROMPT_verify.md.tmpl +5 -2
  97. package/src/templates/scripts/feature-loop.sh.tmpl +441 -69
@@ -3,47 +3,7 @@
3
3
  * Generates ralph.config.cjs file from scan results
4
4
  */
5
5
  import type { ScanResult } from '../scanner/types.js';
6
- /**
7
- * Ralph configuration structure
8
- */
9
- export interface RalphConfig {
10
- name: string;
11
- stack: {
12
- framework: {
13
- name: string;
14
- version: string;
15
- variant: string;
16
- };
17
- packageManager: string;
18
- testing: {
19
- unit: string;
20
- e2e: string;
21
- };
22
- styling: string;
23
- };
24
- commands: {
25
- dev: string;
26
- build: string;
27
- test: string;
28
- lint: string;
29
- typecheck: string;
30
- };
31
- paths: {
32
- root: string;
33
- prompts: string;
34
- guides: string;
35
- specs: string;
36
- scripts: string;
37
- learnings: string;
38
- agents: string;
39
- };
40
- loop: {
41
- maxIterations: number;
42
- maxE2eAttempts: number;
43
- defaultModel: string;
44
- planningModel: string;
45
- };
46
- }
6
+ import type { RalphConfig } from '../utils/config.js';
47
7
  /**
48
8
  * Generate ralph config object from scan result
49
9
  */
@@ -10,6 +10,8 @@ export function generateConfig(scanResult, customVars = {}) {
10
10
  const vars = extractVariables(scanResult, customVars);
11
11
  const defaultModel = customVars.defaultModel || 'sonnet';
12
12
  const planningModel = customVars.planningModel || 'opus';
13
+ const agentProvider = customVars.agentProvider || 'anthropic';
14
+ const agentModel = customVars.agentModel || 'claude-sonnet-4-6';
13
15
  return {
14
16
  name: vars.projectName,
15
17
  stack: {
@@ -46,6 +48,11 @@ export function generateConfig(scanResult, customVars = {}) {
46
48
  maxE2eAttempts: 5,
47
49
  defaultModel,
48
50
  planningModel,
51
+ reviewMode: 'manual',
52
+ },
53
+ agent: {
54
+ defaultProvider: agentProvider,
55
+ defaultModel: agentModel,
49
56
  },
50
57
  };
51
58
  }
@@ -4,10 +4,10 @@
4
4
  */
5
5
  import type { ScanResult } from '../scanner/types.js';
6
6
  import { type TemplateVariables } from './templates.js';
7
- import { type RalphConfig } from './config.js';
7
+ import type { RalphConfig } from '../utils/config.js';
8
8
  import { type WriteSummary } from './writer.js';
9
9
  export type { TemplateVariables } from './templates.js';
10
- export type { RalphConfig } from './config.js';
10
+ export type { RalphConfig } from '../utils/config.js';
11
11
  export type { WriteOptions, WriteSummary, WriteResult } from './writer.js';
12
12
  export { extractVariables, processTemplate, processTemplateFile, getTemplatesDir, } from './templates.js';
13
13
  export { generateConfig, generateConfigFile } from './config.js';
@@ -29,6 +29,8 @@ export interface TemplateVariables {
29
29
  formatCommand: string;
30
30
  appDir: string;
31
31
  isTui: string;
32
+ hasSupabase: string;
33
+ hasPosthog: string;
32
34
  aiEntryPoints: string;
33
35
  aiKeyDirectories: string;
34
36
  aiNamingConventions: string;
@@ -150,8 +150,10 @@ export function extractVariables(scanResult, customVars = {}) {
150
150
  existsSync(join(projectRoot, 'src', 'main.ts'))) {
151
151
  appDir = 'src';
152
152
  }
153
- // Detect TUI (Ink) projects
153
+ // Detect TUI (Ink) projects and service dependencies
154
154
  let isTui = '';
155
+ let hasSupabase = '';
156
+ let hasPosthog = '';
155
157
  try {
156
158
  const pkgPath = join(projectRoot, 'package.json');
157
159
  if (existsSync(pkgPath)) {
@@ -159,6 +161,10 @@ export function extractVariables(scanResult, customVars = {}) {
159
161
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
160
162
  if (allDeps['ink'])
161
163
  isTui = 'true';
164
+ if (allDeps['@supabase/supabase-js'] || allDeps['@supabase/ssr'])
165
+ hasSupabase = 'true';
166
+ if (allDeps['posthog-js'] || allDeps['posthog-node'])
167
+ hasPosthog = 'true';
162
168
  }
163
169
  }
164
170
  catch { /* ignore */ }
@@ -179,6 +185,8 @@ export function extractVariables(scanResult, customVars = {}) {
179
185
  stylingVariant,
180
186
  appDir,
181
187
  isTui,
188
+ hasSupabase,
189
+ hasPosthog,
182
190
  ...commands,
183
191
  ...aiData,
184
192
  ...customVars,
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  export interface ParsedArgs {
5
5
  command: string | undefined;
6
6
  positionalArgs: string[];
7
- flags: Record<string, string | boolean>;
7
+ flags: Record<string, string | boolean | string[]>;
8
8
  }
9
9
  /**
10
10
  * Parse CLI arguments into command, positional args, and flags.
package/dist/index.js CHANGED
@@ -43,7 +43,15 @@ export function parseCliArgs(argv) {
43
43
  '--interval',
44
44
  '--provider',
45
45
  '--review-mode',
46
+ '--issue',
47
+ '--context',
48
+ '--goals',
49
+ '--max-items',
50
+ '--max-steps',
51
+ '--labels',
46
52
  ]);
53
+ // Flags that can be specified multiple times, accumulating into an array
54
+ const repeatableFlagSet = new Set(['--issue', '--context']);
47
55
  let i = 0;
48
56
  while (i < argv.length) {
49
57
  const arg = argv[i];
@@ -63,7 +71,22 @@ export function parseCliArgs(argv) {
63
71
  if (arg.startsWith('--')) {
64
72
  const normalized = normalizeFlagName(arg);
65
73
  if (valueFlagSet.has(arg) && i + 1 < argv.length && !argv[i + 1].startsWith('-')) {
66
- flags[normalized] = argv[i + 1];
74
+ const value = argv[i + 1];
75
+ if (repeatableFlagSet.has(arg)) {
76
+ const existing = flags[normalized];
77
+ if (Array.isArray(existing)) {
78
+ existing.push(value);
79
+ }
80
+ else if (typeof existing === 'string') {
81
+ flags[normalized] = [existing, value];
82
+ }
83
+ else {
84
+ flags[normalized] = [value];
85
+ }
86
+ }
87
+ else {
88
+ flags[normalized] = value;
89
+ }
67
90
  i += 2;
68
91
  }
69
92
  else {
@@ -155,6 +178,7 @@ async function startInkTui(initialScreen = 'shell', options) {
155
178
  provider: initialState.provider,
156
179
  model: initialState.model,
157
180
  scanResult: initialState.scanResult,
181
+ initialReferences: options?.initialReferences,
158
182
  }
159
183
  : undefined;
160
184
  // Build run props if starting on run/monitor screen
@@ -167,6 +191,7 @@ async function startInkTui(initialScreen = 'shell', options) {
167
191
  version,
168
192
  interviewProps,
169
193
  runProps,
194
+ agentProps: options?.agentOptions,
170
195
  onComplete: (specPath) => {
171
196
  // Spec was saved to disk by app.tsx (avoid stdout noise during TUI)
172
197
  logger.debug(`Created spec: ${specPath}`);
@@ -199,7 +224,9 @@ Usage:
199
224
  wiggum new <name> Create new feature spec (TUI)
200
225
  wiggum run <feature> Run feature development loop
201
226
  wiggum monitor <feature> Monitor a running feature loop
227
+ wiggum sync Refresh project context (scan + AI analysis)
202
228
  wiggum config [args...] Manage API keys and settings
229
+ wiggum agent Autonomous backlog executor
203
230
 
204
231
  Options for run:
205
232
  --worktree Use git worktree isolation
@@ -222,9 +249,22 @@ Options for init:
222
249
  Options for new:
223
250
  --provider <name> AI provider
224
251
  --model <model> AI model
252
+ --issue <number|url> Add GitHub issue as context (repeatable)
253
+ --context <url|path> Add URL or file as context (repeatable)
254
+ --auto Headless mode (skip TUI, for scripting/agents)
255
+ --goals <description> Feature goals (used with --auto)
225
256
  -e, --edit Open in editor after creation
226
257
  -f, --force Overwrite existing spec
227
258
 
259
+ Options for agent:
260
+ --model <model> AI model (overrides ralph.config.cjs agent.defaultModel)
261
+ --max-items <n> Max issues to process before stopping
262
+ --max-steps <n> Max agent steps before stopping
263
+ --labels <l1,l2> Only work on issues with these labels (comma-separated)
264
+ --review-mode <mode> Review mode: 'manual', 'auto', or 'merge' (default: manual)
265
+ --dry-run Plan what would be done without executing
266
+ --stream Stream output in real-time (default: wait for completion)
267
+
228
268
  In the TUI:
229
269
  /init Initialize or reconfigure project
230
270
  /new <name> Create a new feature specification
@@ -259,11 +299,37 @@ Press Esc to cancel any operation.
259
299
  const featureName = parsed.positionalArgs[0];
260
300
  if (!featureName) {
261
301
  console.error('Error: <name> is required for "new"');
262
- console.error('Usage: wiggum new <name> [--provider <name>] [--model <model>] [-e] [-f]');
302
+ console.error('Usage: wiggum new <name> [--issue <number|url>] [--context <url|path>] [--model <model>] [--auto] [--goals <desc>] [-e] [-f]');
263
303
  process.exit(1);
264
304
  }
265
- // TODO: pass parsed flags to startInkTui once TUI supports new flags
266
- await startInkTui('interview', { interviewFeature: featureName });
305
+ const initialReferences = [];
306
+ const issueFlags = parsed.flags.issue;
307
+ if (Array.isArray(issueFlags))
308
+ initialReferences.push(...issueFlags.map(v => `issue:${v}`));
309
+ else if (typeof issueFlags === 'string')
310
+ initialReferences.push(`issue:${issueFlags}`);
311
+ const contextFlags = parsed.flags.context;
312
+ if (Array.isArray(contextFlags))
313
+ initialReferences.push(...contextFlags);
314
+ else if (typeof contextFlags === 'string')
315
+ initialReferences.push(contextFlags);
316
+ if (parsed.flags.auto === true) {
317
+ const { newAutoCommand } = await import('./commands/new-auto.js');
318
+ const providerFlag = typeof parsed.flags.provider === 'string' ? parsed.flags.provider : undefined;
319
+ const validProviders = new Set(['anthropic', 'openai', 'openrouter']);
320
+ await newAutoCommand(featureName, {
321
+ goals: typeof parsed.flags.goals === 'string' ? parsed.flags.goals : undefined,
322
+ initialReferences: initialReferences.length > 0 ? initialReferences : undefined,
323
+ model: typeof parsed.flags.model === 'string' ? parsed.flags.model : undefined,
324
+ provider: providerFlag && validProviders.has(providerFlag) ? providerFlag : undefined,
325
+ });
326
+ }
327
+ else {
328
+ await startInkTui('interview', {
329
+ interviewFeature: featureName,
330
+ initialReferences: initialReferences.length > 0 ? initialReferences : undefined,
331
+ });
332
+ }
267
333
  break;
268
334
  }
269
335
  case 'run': {
@@ -319,6 +385,11 @@ Press Esc to cancel any operation.
319
385
  }
320
386
  break;
321
387
  }
388
+ case 'sync': {
389
+ const { syncCommand } = await import('./commands/sync.js');
390
+ await syncCommand();
391
+ break;
392
+ }
322
393
  case 'config': {
323
394
  const provider = getAvailableProvider();
324
395
  const model = provider
@@ -328,6 +399,46 @@ Press Esc to cancel any operation.
328
399
  await handleConfigCommand(parsed.positionalArgs, state);
329
400
  break;
330
401
  }
402
+ case 'agent': {
403
+ const reviewModeFlag = typeof parsed.flags.reviewMode === 'string' ? parsed.flags.reviewMode : undefined;
404
+ if (reviewModeFlag && !['manual', 'auto', 'merge'].includes(reviewModeFlag)) {
405
+ console.error(`Error: Invalid --review-mode '${reviewModeFlag}'. Allowed values: manual, auto, merge`);
406
+ process.exit(1);
407
+ }
408
+ const agentOpts = {
409
+ model: typeof parsed.flags.model === 'string' ? parsed.flags.model : undefined,
410
+ maxItems: typeof parsed.flags.maxItems === 'string' ? parseIntFlag(parsed.flags.maxItems, '--max-items') : undefined,
411
+ maxSteps: typeof parsed.flags.maxSteps === 'string' ? parseIntFlag(parsed.flags.maxSteps, '--max-steps') : undefined,
412
+ labels: typeof parsed.flags.labels === 'string' ? parsed.flags.labels.split(',').map(l => l.trim()).filter(Boolean) : undefined,
413
+ reviewMode: reviewModeFlag,
414
+ dryRun: parsed.flags.dryRun === true,
415
+ stream: parsed.flags.stream === true,
416
+ };
417
+ if (agentOpts.stream === true) {
418
+ // Explicit --stream: always headless
419
+ const { agentCommand } = await import('./commands/agent.js');
420
+ await agentCommand(agentOpts);
421
+ }
422
+ else if (process.stdout.isTTY && !isCI()) {
423
+ // TTY: launch TUI
424
+ await startInkTui('agent', {
425
+ agentOptions: {
426
+ modelOverride: agentOpts.model,
427
+ maxItems: agentOpts.maxItems,
428
+ maxSteps: agentOpts.maxSteps,
429
+ labels: agentOpts.labels,
430
+ reviewMode: agentOpts.reviewMode,
431
+ dryRun: agentOpts.dryRun,
432
+ },
433
+ });
434
+ }
435
+ else {
436
+ // Non-TTY / CI: headless
437
+ const { agentCommand } = await import('./commands/agent.js');
438
+ await agentCommand(agentOpts);
439
+ }
440
+ break;
441
+ }
331
442
  default:
332
443
  // Unknown command - start TUI at shell
333
444
  logger.warn(`Unknown command: ${parsed.command}. Starting TUI...`);
@@ -54,6 +54,11 @@ export declare const REPL_COMMANDS: {
54
54
  readonly usage: "/monitor <feature-name>";
55
55
  readonly aliases: readonly ["m"];
56
56
  };
57
+ readonly agent: {
58
+ readonly description: "Start the autonomous backlog agent";
59
+ readonly usage: "/agent [--dry-run] [--max-items <n>]";
60
+ readonly aliases: readonly ["a"];
61
+ };
57
62
  readonly config: {
58
63
  readonly description: "Manage API keys and settings";
59
64
  readonly usage: "/config [set <service> <key>]";
@@ -31,6 +31,11 @@ export const REPL_COMMANDS = {
31
31
  usage: '/monitor <feature-name>',
32
32
  aliases: ['m'],
33
33
  },
34
+ agent: {
35
+ description: 'Start the autonomous backlog agent',
36
+ usage: '/agent [--dry-run] [--max-items <n>]',
37
+ aliases: ['a'],
38
+ },
34
39
  config: {
35
40
  description: 'Manage API keys and settings',
36
41
  usage: '/config [set <service> <key>]',
@@ -1,5 +1,5 @@
1
1
  ## Context
2
- Study @.ralph/AGENTS.md for commands and patterns.
2
+ If @.ralph/guides/AGENTS.md exists, study it for commands and patterns.
3
3
  Study @.ralph/specs/$FEATURE.md for feature specification.
4
4
  Study @.ralph/specs/$FEATURE-implementation-plan.md for current tasks.
5
5
  {{#if frameworkVariant}}For detailed architecture, see @{{appDir}}/.claude/CLAUDE.md{{/if}}
@@ -18,10 +18,10 @@ Key patterns: parallel fetches, direct imports, React.cache(), lazy loading.
18
18
  - Search codebase before assuming something doesn't exist
19
19
 
20
20
  ## Task
21
- Pick the next incomplete task from the implementation plan.
21
+ Work through ALL incomplete tasks in the implementation plan in a single session.
22
22
  **Skip E2E tasks** (tasks starting with `E2E:`) - those are handled in a separate phase.
23
- Implement it following the patterns in AGENTS.md.
24
- Write tests for the implementation.
23
+ For each task: implement it, write tests, validate, commit, then move to the next task.
24
+ Do not stop after one task — keep going until all non-E2E tasks are complete.
25
25
 
26
26
  ## Validation
27
27
  After changes, ALL must pass:
@@ -36,7 +36,8 @@ If any validation fails, fix the issue before proceeding.
36
36
  Before committing, review your changes against @.ralph/guides/SECURITY.md:
37
37
  1. **Quick scan**: Input validation, injection prevention, auth checks, data exposure
38
38
  2. **Run**: `cd {{appDir}} && {{packageManager}} audit` (check for vulnerable dependencies)
39
- 3. **Check**: `mcp__supabase__get_advisors` with type "security" (RLS policies)
39
+ {{#if hasSupabase}}3. **Check**: `mcp__supabase__get_advisors` with type "security" (RLS policies)
40
+ {{/if}}
40
41
  4. **Red team**: Can auth be bypassed? Can other users' data be accessed?
41
42
 
42
43
  Flag any security issues in the implementation plan and fix before committing.
@@ -54,7 +55,7 @@ If any check fails, fix before committing.
54
55
 
55
56
  ## Completion
56
57
  When ALL validations pass:
57
- 1. Update @.ralph/specs/$FEATURE-implementation-plan.md - mark task done with commit hash
58
+ 1. Update @.ralph/specs/$FEATURE-implementation-plan.md change the task's `- [ ]` to `- [x]` and append the commit hash (e.g., `- [x] Task description - abc1234`). The harness tracks progress by counting checkboxes, so this step is mandatory.
58
59
  2. `git -C {{appDir}} add -A`
59
60
  3. `git -C {{appDir}} commit -m "type(scope): description"`
60
61
  4. `git -C {{appDir}} push origin feat/$FEATURE`
@@ -69,9 +70,11 @@ If this iteration revealed something useful, append to @.ralph/LEARNINGS.md:
69
70
  Format: `- [YYYY-MM-DD] [$FEATURE] Brief description`
70
71
 
71
72
  ## Rules
72
- - One task per iteration
73
+ - Complete ALL remaining non-E2E tasks before ending the session
74
+ - Commit after each task so progress is preserved if the session is interrupted
73
75
  - Tests are mandatory - no task is complete without tests
74
76
  - Search codebase before assuming something doesn't exist
75
- - If blocked, document in implementation plan and move to next task
76
- - Use Supabase MCP for database operations
77
- - Use PostHog MCP for analytics queries
77
+ - If blocked on a task, document in implementation plan and move to the next task
78
+ {{#if hasSupabase}}- Use Supabase MCP for database operations
79
+ {{/if}}{{#if hasPosthog}}- Use PostHog MCP for analytics queries
80
+ {{/if}}
@@ -1,5 +1,5 @@
1
1
  ## Context
2
- Study @.ralph/AGENTS.md for commands and patterns.
2
+ If @.ralph/guides/AGENTS.md exists, study it for commands and patterns.
3
3
  Study @.ralph/specs/$FEATURE.md for feature specification.
4
4
  Study @.ralph/specs/$FEATURE-implementation-plan.md for E2E test scenarios.
5
5
  {{#if frameworkVariant}}For detailed architecture, see @{{appDir}}/.claude/CLAUDE.md{{/if}}
@@ -21,6 +21,7 @@ If either fails, fix issues before proceeding with E2E tests.
21
21
  {{#if isTui}}
22
22
  ## Task
23
23
  Execute automated E2E tests for the completed TUI feature using the xterm.js bridge and agent-browser.
24
+ Run ALL scenarios in a single session — do not end between scenarios.
24
25
 
25
26
  ### Step 1: Start Bridge
26
27
  Check the bridge is running:
@@ -149,11 +150,11 @@ When all scenarios are executed:
149
150
  2. Update the Implementation Summary status to `[PASSED]` if all passed
150
151
  3. **Commit the updated implementation plan:**
151
152
  ```bash
152
- git add -A && git commit -m "test($FEATURE): E2E tests passed via agent-browser"
153
+ git -C {{appDir}} add -A && git -C {{appDir}} commit -m "test($FEATURE): E2E tests passed via agent-browser"
153
154
  ```
154
155
  4. **Push to remote:**
155
156
  ```bash
156
- git push origin feat/$FEATURE
157
+ git -C {{appDir}} push origin feat/$FEATURE
157
158
  ```
158
159
  5. If all passed: signal ready for PR phase
159
160
  6. If any failed: failures documented, loop will retry after fix iteration
@@ -168,6 +169,7 @@ Format: `- [YYYY-MM-DD] [$FEATURE] Brief description`
168
169
  {{else}}
169
170
  ## Task
170
171
  Execute automated E2E tests for the completed feature using Playwright MCP tools.
172
+ Run ALL scenarios in a single session — do not end between scenarios.
171
173
 
172
174
  ### Step 1: Check Dev Server
173
175
  Verify dev server is running at http://localhost:3000. If not accessible, start it:
@@ -176,7 +178,7 @@ cd {{appDir}} && {{devCommand}} &
176
178
  ```
177
179
  Wait ~10 seconds for server startup, then verify with a simple browser_navigate.
178
180
 
179
- ### Step 1.5: Seed Test Data (if needed)
181
+ {{#if hasSupabase}}### Step 1.5: Seed Test Data (if needed)
180
182
 
181
183
  Check if test scenarios require specific data volumes (e.g., pagination needs >10 rows).
182
184
 
@@ -199,6 +201,7 @@ query: "DELETE FROM table_name WHERE data->>'_test' = 'true';"
199
201
  ```
200
202
 
201
203
  **If seeding is impractical:** Document in implementation plan that E2E was skipped but unit tests provide coverage.
204
+ {{/if}}
202
205
 
203
206
  ### Step 2: Parse E2E Test Scenarios
204
207
  Read E2E test scenarios from @.ralph/specs/$FEATURE-implementation-plan.md.
@@ -246,7 +249,7 @@ For each E2E test scenario:
246
249
  - Check console: `browser_console_messages` for JS errors
247
250
  - Document failure details
248
251
 
249
- ### Step 4: Database Verification
252
+ {{#if hasSupabase}}### Step 4: Database Verification
250
253
  For scenarios with database checks, use Supabase MCP:
251
254
  ```
252
255
  mcp__plugin_supabase_supabase__execute_sql
@@ -255,6 +258,7 @@ query: "SELECT * FROM survey_responses WHERE ..."
255
258
  ```
256
259
 
257
260
  Verify returned data matches expected state.
261
+ {{/if}}
258
262
 
259
263
  ### Unique Test Data (for Parallel Execution)
260
264
  When creating test data, use unique identifiers to avoid conflicts with other loops:
@@ -315,11 +319,12 @@ Update @.ralph/specs/$FEATURE-implementation-plan.md for each scenario:
315
319
  2. Verify URL contains expected path/params
316
320
  ```
317
321
 
318
- ### Database State
322
+ {{#if hasSupabase}}### Database State
319
323
  ```
320
324
  1. mcp__plugin_supabase_supabase__execute_sql with SELECT query
321
325
  2. Verify row count, column values match expectations
322
326
  ```
327
+ {{/if}}
323
328
 
324
329
  ## Browser State Management
325
330
 
@@ -364,8 +369,9 @@ If code changes don't appear in the browser:
364
369
 
365
370
  ### Stale Data
366
371
  - Clear browser storage: Use `browser_close` between scenarios
367
- - Check Supabase for stale test data from previous runs
372
+ {{#if hasSupabase}}- Check Supabase for stale test data from previous runs
368
373
  - Delete test data: `DELETE FROM table WHERE data->>'_test' = 'true'`
374
+ {{/if}}
369
375
 
370
376
  ## Rules
371
377
  - Always get a fresh `browser_snapshot` after actions before making assertions
@@ -1,5 +1,5 @@
1
1
  ## Context
2
- Study @.ralph/AGENTS.md for commands and patterns.
2
+ If @.ralph/guides/AGENTS.md exists, study it for commands and patterns.
3
3
  Study @.ralph/specs/README.md for spec structure.
4
4
  Study @.ralph/specs/$FEATURE.md for feature specification.
5
5
  {{#if frameworkVariant}}For detailed architecture, see @{{appDir}}/.claude/CLAUDE.md{{/if}}
@@ -96,9 +96,22 @@ Example E2E scenario:
96
96
  - [x] E2E: Scenario name - PASSED
97
97
  ```
98
98
 
99
+ ## CRITICAL CONSTRAINT — PLANNING ONLY
100
+ **You are in the PLANNING phase. Your ONLY job is to produce an implementation plan.**
101
+ - Do NOT write any source code, test code, or configuration files
102
+ - Do NOT create, modify, or touch any files outside `.ralph/specs/`
103
+ - Do NOT run build, test, or lint commands
104
+ - Do NOT make git commits
105
+ - If you feel the urge to "just implement a small piece", STOP — that is a phase violation
106
+ - The implementation phase runs AFTER this session ends, in a separate session
107
+ - Violation of this constraint wastes tokens and breaks the harness automation
108
+
99
109
  ## Rules
100
- - Plan only in this phase, do NOT implement
101
- - One task = one commit-sized unit of work
110
+ - You MUST use `- [ ]` checkbox syntax for every task in the plan
111
+ - Do NOT use heading-based task formats (e.g., `#### Task 1:`) for individual tasks
112
+ - The harness parses `- [ ]` lines to track progress — other formats will break automation
113
+ - Use `### Phase N:` headings only for phase grouping, not for individual tasks
114
+ - One task = one commit-sized unit of work (but tasks can be grouped into phases for batch implementation)
102
115
  - Every implementation task needs a corresponding test task
103
116
  - Use Supabase MCP to check existing schema
104
117
  - Use PostHog MCP to check existing analytics setup
@@ -1,5 +1,5 @@
1
1
  ## Context
2
- Study @.ralph/AGENTS.md for commands and patterns.
2
+ If @.ralph/guides/AGENTS.md exists, study it for commands and patterns.
3
3
  Study @.ralph/specs/$FEATURE.md for feature specification.
4
4
  Study @.ralph/specs/$FEATURE-implementation-plan.md for completed tasks.
5
5
 
@@ -9,6 +9,7 @@ Capture any review feedback patterns for future iterations.
9
9
 
10
10
  ## Task
11
11
  All implementation and E2E tasks are complete. Create PR and request review.
12
+ Complete ALL steps in a single pass — do not end the session between steps.
12
13
 
13
14
  ### Step 1: Verify Ready State
14
15
  1. Check all tasks are complete in implementation plan (no `- [ ]` items)
@@ -52,12 +53,14 @@ cd {{appDir}} && gh pr create --base main --head feat/$FEATURE \
52
53
  [Read from implementation plan - list completed phases]
53
54
 
54
55
  ## Testing
55
- - [x] Unit/integration tests: 97 passing
56
- - [x] E2E tests: All scenarios passed via Playwright MCP
56
+ - [x] Unit/integration tests: passing
57
+ - [x] E2E tests: All scenarios passed
57
58
  - [x] Build succeeds
58
59
 
59
60
  ## E2E Test Results
60
- [Copy from implementation plan Phase 9]
61
+ [Copy from implementation plan E2E section]
62
+
63
+ Closes #[Read the source issue number from the spec file metadata or context section]
61
64
 
62
65
  Generated with Claude Code
63
66
  EOF
@@ -88,17 +91,27 @@ Review the git diff against main and check:
88
91
 
89
92
  Run: git diff main
90
93
 
91
- Respond with:
92
- - APPROVED if everything looks good
93
- - Or list specific issues with file:line references that need to be fixed
94
-
95
- IMPORTANT: After posting any PR review comment, you MUST print your final verdict as the LAST line of your output. Print exactly one of:
96
- VERDICT: APPROVED
97
- VERDICT: NOT APPROVED
98
- This line is parsed by the automation — do not omit it."
94
+ Then:
95
+ 1. Post your complete review as a comment on the PR using:
96
+ gh pr comment --body '<your review in markdown>'
97
+ Format the comment with: a summary, specific issues with file:line refs (if any), and the verdict.
98
+ 2. Print your final verdict as the LAST line of stdout. Print exactly one of:
99
+ VERDICT: APPROVED
100
+ VERDICT: NOT APPROVED
101
+ This line is parsed by the automation — do not omit it."
99
102
  fi
100
103
  ```
101
104
 
105
+ After the review completes, check its output:
106
+ - If it contains "VERDICT: APPROVED", echo that line so the automation detects it:
107
+ ```bash
108
+ echo "VERDICT: APPROVED"
109
+ ```
110
+ - If issues were found, echo:
111
+ ```bash
112
+ echo "VERDICT: NOT APPROVED"
113
+ ```
114
+
102
115
  **Handle review feedback:**
103
116
  - If Claude outputs "VERDICT: APPROVED" -> Done. The PR is ready for manual merge by the user.
104
117
  - If Claude lists issues:
@@ -113,8 +126,15 @@ After review is complete (approved or max iterations reached):
113
126
  1. Post a summary comment on the PR with the review outcome
114
127
  2. Do NOT merge — the user will review and merge manually
115
128
 
129
+ ## IMPORTANT: Review scope
130
+ If you discover that no implementation code exists (empty diff, no source files changed),
131
+ do NOT implement the feature yourself. Instead, report "VERDICT: NOT APPROVED —
132
+ no implementation found" so the harness can trigger a new implementation iteration.
133
+
116
134
  ## Rules
135
+ - **NEVER approve if any tests are failing.** Output "VERDICT: NOT APPROVED — test failures" if any tests fail.
117
136
  - Do NOT merge the PR — auto mode only reviews, the user merges
137
+ - Do NOT implement missing features — only review and fix minor issues
118
138
  - Address ALL review comments before marking as approved
119
139
  - If gh CLI fails, check authentication: `gh auth status`
120
140
  - Keep review conversation focused and professional
@@ -1,5 +1,5 @@
1
1
  ## Context
2
- Study @.ralph/AGENTS.md for commands and patterns.
2
+ If @.ralph/guides/AGENTS.md exists, study it for commands and patterns.
3
3
  Study @.ralph/specs/$FEATURE.md for feature specification.
4
4
  Study @.ralph/specs/$FEATURE-implementation-plan.md for completed tasks.
5
5
 
@@ -9,6 +9,7 @@ Capture any review feedback patterns for future iterations.
9
9
 
10
10
  ## Task
11
11
  All implementation and E2E tasks are complete. Create PR for manual review.
12
+ Complete ALL steps in a single pass — do not end the session between steps.
12
13
 
13
14
  ### Step 1: Verify Ready State
14
15
  1. Check all tasks are complete in implementation plan (no `- [ ]` items)
@@ -59,6 +60,8 @@ cd {{appDir}} && gh pr create --base main --head feat/$FEATURE \
59
60
  ## E2E Test Results
60
61
  [Copy from implementation plan if E2E phase exists]
61
62
 
63
+ Closes #[Read the source issue number from the spec file metadata or context section]
64
+
62
65
  Generated with Claude Code
63
66
  EOF
64
67
  )"