wiggum-cli 0.1.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 (236) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +341 -0
  3. package/bin/ralph.js +8 -0
  4. package/dist/ai/enhancer.d.ts +100 -0
  5. package/dist/ai/enhancer.d.ts.map +1 -0
  6. package/dist/ai/enhancer.js +233 -0
  7. package/dist/ai/enhancer.js.map +1 -0
  8. package/dist/ai/index.d.ts +8 -0
  9. package/dist/ai/index.d.ts.map +1 -0
  10. package/dist/ai/index.js +11 -0
  11. package/dist/ai/index.js.map +1 -0
  12. package/dist/ai/prompts.d.ts +26 -0
  13. package/dist/ai/prompts.d.ts.map +1 -0
  14. package/dist/ai/prompts.js +201 -0
  15. package/dist/ai/prompts.js.map +1 -0
  16. package/dist/ai/providers.d.ts +35 -0
  17. package/dist/ai/providers.d.ts.map +1 -0
  18. package/dist/ai/providers.js +104 -0
  19. package/dist/ai/providers.js.map +1 -0
  20. package/dist/cli.d.ts +6 -0
  21. package/dist/cli.d.ts.map +1 -0
  22. package/dist/cli.js +196 -0
  23. package/dist/cli.js.map +1 -0
  24. package/dist/commands/init.d.ts +16 -0
  25. package/dist/commands/init.d.ts.map +1 -0
  26. package/dist/commands/init.js +124 -0
  27. package/dist/commands/init.js.map +1 -0
  28. package/dist/commands/monitor.d.ts +17 -0
  29. package/dist/commands/monitor.d.ts.map +1 -0
  30. package/dist/commands/monitor.js +342 -0
  31. package/dist/commands/monitor.js.map +1 -0
  32. package/dist/commands/new.d.ts +19 -0
  33. package/dist/commands/new.d.ts.map +1 -0
  34. package/dist/commands/new.js +272 -0
  35. package/dist/commands/new.js.map +1 -0
  36. package/dist/commands/run.d.ts +16 -0
  37. package/dist/commands/run.d.ts.map +1 -0
  38. package/dist/commands/run.js +175 -0
  39. package/dist/commands/run.js.map +1 -0
  40. package/dist/generator/config.d.ts +59 -0
  41. package/dist/generator/config.d.ts.map +1 -0
  42. package/dist/generator/config.js +68 -0
  43. package/dist/generator/config.js.map +1 -0
  44. package/dist/generator/index.d.ts +64 -0
  45. package/dist/generator/index.d.ts.map +1 -0
  46. package/dist/generator/index.js +147 -0
  47. package/dist/generator/index.js.map +1 -0
  48. package/dist/generator/templates.d.ts +70 -0
  49. package/dist/generator/templates.d.ts.map +1 -0
  50. package/dist/generator/templates.js +296 -0
  51. package/dist/generator/templates.js.map +1 -0
  52. package/dist/generator/writer.d.ts +93 -0
  53. package/dist/generator/writer.d.ts.map +1 -0
  54. package/dist/generator/writer.js +213 -0
  55. package/dist/generator/writer.js.map +1 -0
  56. package/dist/index.d.ts +12 -0
  57. package/dist/index.d.ts.map +1 -0
  58. package/dist/index.js +17 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/scanner/detectors/core/framework.d.ts +11 -0
  61. package/dist/scanner/detectors/core/framework.d.ts.map +1 -0
  62. package/dist/scanner/detectors/core/framework.js +275 -0
  63. package/dist/scanner/detectors/core/framework.js.map +1 -0
  64. package/dist/scanner/detectors/core/packageManager.d.ts +11 -0
  65. package/dist/scanner/detectors/core/packageManager.d.ts.map +1 -0
  66. package/dist/scanner/detectors/core/packageManager.js +74 -0
  67. package/dist/scanner/detectors/core/packageManager.js.map +1 -0
  68. package/dist/scanner/detectors/core/styling.d.ts +12 -0
  69. package/dist/scanner/detectors/core/styling.d.ts.map +1 -0
  70. package/dist/scanner/detectors/core/styling.js +230 -0
  71. package/dist/scanner/detectors/core/styling.js.map +1 -0
  72. package/dist/scanner/detectors/core/testing.d.ts +12 -0
  73. package/dist/scanner/detectors/core/testing.d.ts.map +1 -0
  74. package/dist/scanner/detectors/core/testing.js +190 -0
  75. package/dist/scanner/detectors/core/testing.js.map +1 -0
  76. package/dist/scanner/detectors/data/api.d.ts +12 -0
  77. package/dist/scanner/detectors/data/api.d.ts.map +1 -0
  78. package/dist/scanner/detectors/data/api.js +261 -0
  79. package/dist/scanner/detectors/data/api.js.map +1 -0
  80. package/dist/scanner/detectors/data/database.d.ts +12 -0
  81. package/dist/scanner/detectors/data/database.d.ts.map +1 -0
  82. package/dist/scanner/detectors/data/database.js +213 -0
  83. package/dist/scanner/detectors/data/database.js.map +1 -0
  84. package/dist/scanner/detectors/data/orm.d.ts +12 -0
  85. package/dist/scanner/detectors/data/orm.d.ts.map +1 -0
  86. package/dist/scanner/detectors/data/orm.js +160 -0
  87. package/dist/scanner/detectors/data/orm.js.map +1 -0
  88. package/dist/scanner/detectors/frontend/formHandling.d.ts +12 -0
  89. package/dist/scanner/detectors/frontend/formHandling.d.ts.map +1 -0
  90. package/dist/scanner/detectors/frontend/formHandling.js +211 -0
  91. package/dist/scanner/detectors/frontend/formHandling.js.map +1 -0
  92. package/dist/scanner/detectors/frontend/stateManagement.d.ts +12 -0
  93. package/dist/scanner/detectors/frontend/stateManagement.d.ts.map +1 -0
  94. package/dist/scanner/detectors/frontend/stateManagement.js +221 -0
  95. package/dist/scanner/detectors/frontend/stateManagement.js.map +1 -0
  96. package/dist/scanner/detectors/frontend/uiComponents.d.ts +12 -0
  97. package/dist/scanner/detectors/frontend/uiComponents.d.ts.map +1 -0
  98. package/dist/scanner/detectors/frontend/uiComponents.js +285 -0
  99. package/dist/scanner/detectors/frontend/uiComponents.js.map +1 -0
  100. package/dist/scanner/detectors/infra/deployment.d.ts +12 -0
  101. package/dist/scanner/detectors/infra/deployment.d.ts.map +1 -0
  102. package/dist/scanner/detectors/infra/deployment.js +301 -0
  103. package/dist/scanner/detectors/infra/deployment.js.map +1 -0
  104. package/dist/scanner/detectors/infra/monorepo.d.ts +12 -0
  105. package/dist/scanner/detectors/infra/monorepo.d.ts.map +1 -0
  106. package/dist/scanner/detectors/infra/monorepo.js +219 -0
  107. package/dist/scanner/detectors/infra/monorepo.js.map +1 -0
  108. package/dist/scanner/detectors/mcp/mcpProject.d.ts +12 -0
  109. package/dist/scanner/detectors/mcp/mcpProject.d.ts.map +1 -0
  110. package/dist/scanner/detectors/mcp/mcpProject.js +154 -0
  111. package/dist/scanner/detectors/mcp/mcpProject.js.map +1 -0
  112. package/dist/scanner/detectors/mcp/mcpServers.d.ts +17 -0
  113. package/dist/scanner/detectors/mcp/mcpServers.d.ts.map +1 -0
  114. package/dist/scanner/detectors/mcp/mcpServers.js +193 -0
  115. package/dist/scanner/detectors/mcp/mcpServers.js.map +1 -0
  116. package/dist/scanner/detectors/services/analytics.d.ts +12 -0
  117. package/dist/scanner/detectors/services/analytics.d.ts.map +1 -0
  118. package/dist/scanner/detectors/services/analytics.js +236 -0
  119. package/dist/scanner/detectors/services/analytics.js.map +1 -0
  120. package/dist/scanner/detectors/services/auth.d.ts +12 -0
  121. package/dist/scanner/detectors/services/auth.d.ts.map +1 -0
  122. package/dist/scanner/detectors/services/auth.js +217 -0
  123. package/dist/scanner/detectors/services/auth.js.map +1 -0
  124. package/dist/scanner/detectors/services/email.d.ts +12 -0
  125. package/dist/scanner/detectors/services/email.d.ts.map +1 -0
  126. package/dist/scanner/detectors/services/email.js +211 -0
  127. package/dist/scanner/detectors/services/email.js.map +1 -0
  128. package/dist/scanner/detectors/services/payments.d.ts +12 -0
  129. package/dist/scanner/detectors/services/payments.d.ts.map +1 -0
  130. package/dist/scanner/detectors/services/payments.js +185 -0
  131. package/dist/scanner/detectors/services/payments.js.map +1 -0
  132. package/dist/scanner/detectors/utils.d.ts +160 -0
  133. package/dist/scanner/detectors/utils.d.ts.map +1 -0
  134. package/dist/scanner/detectors/utils.js +222 -0
  135. package/dist/scanner/detectors/utils.js.map +1 -0
  136. package/dist/scanner/index.d.ts +42 -0
  137. package/dist/scanner/index.d.ts.map +1 -0
  138. package/dist/scanner/index.js +282 -0
  139. package/dist/scanner/index.js.map +1 -0
  140. package/dist/scanner/registry.d.ts +43 -0
  141. package/dist/scanner/registry.d.ts.map +1 -0
  142. package/dist/scanner/registry.js +243 -0
  143. package/dist/scanner/registry.js.map +1 -0
  144. package/dist/scanner/types.d.ts +112 -0
  145. package/dist/scanner/types.d.ts.map +1 -0
  146. package/dist/scanner/types.js +6 -0
  147. package/dist/scanner/types.js.map +1 -0
  148. package/dist/templates/config/ralph.config.js.tmpl +38 -0
  149. package/dist/templates/guides/AGENTS.md.tmpl +100 -0
  150. package/dist/templates/guides/FRONTEND.md.tmpl +523 -0
  151. package/dist/templates/guides/PERFORMANCE.md.tmpl +264 -0
  152. package/dist/templates/guides/SECURITY.md.tmpl +100 -0
  153. package/dist/templates/prompts/PROMPT.md.tmpl +77 -0
  154. package/dist/templates/prompts/PROMPT_e2e.md.tmpl +234 -0
  155. package/dist/templates/prompts/PROMPT_feature.md.tmpl +83 -0
  156. package/dist/templates/prompts/PROMPT_review.md.tmpl +167 -0
  157. package/dist/templates/prompts/PROMPT_verify.md.tmpl +72 -0
  158. package/dist/templates/root/.gitignore.tmpl +5 -0
  159. package/dist/templates/root/LEARNINGS.md.tmpl +24 -0
  160. package/dist/templates/root/README.md.tmpl +61 -0
  161. package/dist/templates/scripts/feature-loop.sh.tmpl +267 -0
  162. package/dist/templates/scripts/loop.sh.tmpl +59 -0
  163. package/dist/templates/scripts/ralph-monitor.sh.tmpl +244 -0
  164. package/dist/templates/specs/README.md.tmpl +57 -0
  165. package/dist/templates/specs/_example.md.tmpl +71 -0
  166. package/dist/utils/config.d.ts +95 -0
  167. package/dist/utils/config.d.ts.map +1 -0
  168. package/dist/utils/config.js +148 -0
  169. package/dist/utils/config.js.map +1 -0
  170. package/dist/utils/header.d.ts +5 -0
  171. package/dist/utils/header.d.ts.map +1 -0
  172. package/dist/utils/header.js +15 -0
  173. package/dist/utils/header.js.map +1 -0
  174. package/dist/utils/logger.d.ts +11 -0
  175. package/dist/utils/logger.d.ts.map +1 -0
  176. package/dist/utils/logger.js +24 -0
  177. package/dist/utils/logger.js.map +1 -0
  178. package/package.json +44 -0
  179. package/src/ai/enhancer.ts +350 -0
  180. package/src/ai/index.ts +38 -0
  181. package/src/ai/prompts.ts +217 -0
  182. package/src/ai/providers.ts +136 -0
  183. package/src/cli.ts +255 -0
  184. package/src/commands/init.ts +149 -0
  185. package/src/commands/monitor.ts +412 -0
  186. package/src/commands/new.ts +312 -0
  187. package/src/commands/run.ts +214 -0
  188. package/src/generator/config.ts +116 -0
  189. package/src/generator/index.ts +227 -0
  190. package/src/generator/templates.ts +412 -0
  191. package/src/generator/writer.ts +293 -0
  192. package/src/index.ts +41 -0
  193. package/src/scanner/detectors/core/framework.ts +332 -0
  194. package/src/scanner/detectors/core/packageManager.ts +91 -0
  195. package/src/scanner/detectors/core/styling.ts +261 -0
  196. package/src/scanner/detectors/core/testing.ts +221 -0
  197. package/src/scanner/detectors/data/api.ts +303 -0
  198. package/src/scanner/detectors/data/database.ts +245 -0
  199. package/src/scanner/detectors/data/orm.ts +180 -0
  200. package/src/scanner/detectors/frontend/formHandling.ts +244 -0
  201. package/src/scanner/detectors/frontend/stateManagement.ts +261 -0
  202. package/src/scanner/detectors/frontend/uiComponents.ts +328 -0
  203. package/src/scanner/detectors/infra/deployment.ts +343 -0
  204. package/src/scanner/detectors/infra/monorepo.ts +251 -0
  205. package/src/scanner/detectors/mcp/mcpProject.ts +176 -0
  206. package/src/scanner/detectors/mcp/mcpServers.ts +237 -0
  207. package/src/scanner/detectors/services/analytics.ts +273 -0
  208. package/src/scanner/detectors/services/auth.ts +254 -0
  209. package/src/scanner/detectors/services/email.ts +244 -0
  210. package/src/scanner/detectors/services/payments.ts +213 -0
  211. package/src/scanner/detectors/utils.ts +251 -0
  212. package/src/scanner/index.ts +354 -0
  213. package/src/scanner/registry.ts +301 -0
  214. package/src/scanner/types.ts +152 -0
  215. package/src/templates/config/ralph.config.js.tmpl +38 -0
  216. package/src/templates/guides/AGENTS.md.tmpl +100 -0
  217. package/src/templates/guides/FRONTEND.md.tmpl +523 -0
  218. package/src/templates/guides/PERFORMANCE.md.tmpl +264 -0
  219. package/src/templates/guides/SECURITY.md.tmpl +100 -0
  220. package/src/templates/prompts/PROMPT.md.tmpl +77 -0
  221. package/src/templates/prompts/PROMPT_e2e.md.tmpl +234 -0
  222. package/src/templates/prompts/PROMPT_feature.md.tmpl +83 -0
  223. package/src/templates/prompts/PROMPT_review.md.tmpl +167 -0
  224. package/src/templates/prompts/PROMPT_verify.md.tmpl +72 -0
  225. package/src/templates/root/.gitignore.tmpl +5 -0
  226. package/src/templates/root/LEARNINGS.md.tmpl +24 -0
  227. package/src/templates/root/README.md.tmpl +61 -0
  228. package/src/templates/scripts/feature-loop.sh.tmpl +267 -0
  229. package/src/templates/scripts/loop.sh.tmpl +59 -0
  230. package/src/templates/scripts/ralph-monitor.sh.tmpl +244 -0
  231. package/src/templates/specs/README.md.tmpl +57 -0
  232. package/src/templates/specs/_example.md.tmpl +71 -0
  233. package/src/utils/config.ts +221 -0
  234. package/src/utils/header.ts +15 -0
  235. package/src/utils/logger.ts +28 -0
  236. package/tsconfig.json +19 -0
@@ -0,0 +1,83 @@
1
+ ## Context
2
+ Study @.ralph/AGENTS.md for commands and patterns.
3
+ Study @.ralph/specs/README.md for spec structure.
4
+ Study @.ralph/specs/$FEATURE.md for feature specification.
5
+ {{#if frameworkVariant}}For detailed architecture, see @{{appDir}}/.claude/CLAUDE.md{{/if}}
6
+
7
+ ## Search
8
+ - Use `mgrep "query"` to analyze existing codebase patterns
9
+ - Use Context7 MCP to lookup library APIs and best practices
10
+
11
+ ## Phase: Planning
12
+ 1. Read the spec file: @.ralph/specs/$FEATURE.md
13
+ 2. Analyze codebase to identify what exists vs what's needed
14
+ 3. Create @.ralph/specs/$FEATURE-implementation-plan.md with tasks
15
+
16
+ ## Implementation Plan Format
17
+ ```markdown
18
+ # $FEATURE Implementation Plan
19
+
20
+ **Spec:** .ralph/specs/$FEATURE.md
21
+ **Branch:** feat/$FEATURE
22
+ **Status:** Planning | In Progress | PR Review | Completed
23
+
24
+ ## Tasks
25
+
26
+ ### Phase 1: Setup
27
+ - [ ] Task 1 - [complexity: S/M/L]
28
+ - [ ] Task 2
29
+
30
+ ### Phase 2: Core Implementation
31
+ - [ ] Task 3
32
+ - [ ] Task 4
33
+
34
+ ### Phase 3: Tests (Unit/Integration)
35
+ - [ ] Write tests for [component]
36
+ - [ ] Write tests for [feature]
37
+
38
+ ### Phase 4: Polish & Design
39
+ - [ ] Run design checklist from @.ralph/guides/FRONTEND.md (if UI changes)
40
+ - [ ] Verify responsive design (mobile/tablet/desktop)
41
+ - [ ] Add loading/empty/error states
42
+ - [ ] Verify hover/focus states on interactive elements
43
+ {{#if styling}}- [ ] For charts: use ChartContainer pattern with tooltips + legends{{/if}}
44
+ - [ ] Task N (additional polish)
45
+
46
+ ### Phase 5: E2E Testing
47
+ Browser-based tests executed via Playwright MCP tools.
48
+
49
+ - [ ] E2E: [Scenario name] - [brief description]
50
+ - **URL:** [starting URL, use {placeholders} for dynamic IDs]
51
+ - **Preconditions:** [setup requirements, e.g., "Survey must be published"]
52
+ - **Steps:**
53
+ 1. [Action] -> [expected result]
54
+ 2. [Action] -> [expected result]
55
+ - **Verify:** [final assertion text to check]
56
+ - **Database check:** [optional SQL query to verify data]
57
+
58
+ Example E2E scenario:
59
+ - [ ] E2E: Submit survey response - happy path
60
+ - **URL:** /survey/{surveyId}?utm_source=e2e_test
61
+ - **Preconditions:** Published survey with required questions
62
+ - **Steps:**
63
+ 1. Navigate to survey URL -> Form displays with all questions
64
+ 2. Fill required text field -> No validation error
65
+ 3. Select rating 4 -> Button shows selected state
66
+ 4. Click "Submit Survey" -> Loading state appears
67
+ 5. Wait for "Thank You!" -> Success card displays
68
+ - **Verify:** "successfully submitted" text visible
69
+ - **Database check:** SELECT * FROM survey_responses WHERE survey_id = '{surveyId}'
70
+
71
+ ## Done
72
+ - [x] Completed task - [commit hash]
73
+ - [x] E2E: Scenario name - PASSED
74
+ ```
75
+
76
+ ## Rules
77
+ - Plan only in this phase, do NOT implement
78
+ - One task = one commit-sized unit of work
79
+ - Every implementation task needs a corresponding test task
80
+ - Use Supabase MCP to check existing schema
81
+ - Use PostHog MCP to check existing analytics setup
82
+ - For UI-heavy features (new pages, dashboards, analytics, marketing pages), reference @.ralph/guides/FRONTEND.md
83
+ - Consider `/frontend-design` skill for features needing distinctive aesthetics
@@ -0,0 +1,167 @@
1
+ ## Context
2
+ Study @.ralph/AGENTS.md for commands and patterns.
3
+ Study @.ralph/specs/$FEATURE.md for feature specification.
4
+ Study @.ralph/specs/$FEATURE-implementation-plan.md for completed tasks.
5
+
6
+ ## Learnings
7
+ Read @.ralph/LEARNINGS.md for patterns from previous features.
8
+ Capture any review feedback patterns for future iterations.
9
+
10
+ ## Task
11
+ All implementation and E2E tasks are complete. Create PR and request review.
12
+
13
+ ### Step 1: Verify Ready State
14
+ 1. Check all tasks are complete in implementation plan (no `- [ ]` items)
15
+ 2. Verify tests pass: `cd {{appDir}} && {{testCommand}}`
16
+ 3. Verify build succeeds: `cd {{appDir}} && {{buildCommand}}`
17
+
18
+ If any fail, fix before proceeding.
19
+
20
+ ### Step 2: Check Git Status
21
+ ```bash
22
+ cd {{appDir}} && git status
23
+ cd {{appDir}} && git log --oneline -5
24
+ ```
25
+
26
+ Ensure:
27
+ - On branch `feat/$FEATURE`
28
+ - All changes are committed
29
+ - Branch is pushed to remote
30
+
31
+ If uncommitted changes exist:
32
+ ```bash
33
+ git -C {{appDir}} add -A && git -C {{appDir}} commit -m "chore($FEATURE): final cleanup"
34
+ git -C {{appDir}} push origin feat/$FEATURE
35
+ ```
36
+
37
+ ### Step 3: Create PR
38
+ Check if PR already exists:
39
+ ```bash
40
+ cd {{appDir}} && gh pr list --head feat/$FEATURE
41
+ ```
42
+
43
+ If no PR exists, create one:
44
+ ```bash
45
+ cd {{appDir}} && gh pr create --base main --head feat/$FEATURE \
46
+ --title "feat($FEATURE): [read description from spec]" \
47
+ --body "$(cat <<'EOF'
48
+ ## Summary
49
+ [Read from spec Purpose section]
50
+
51
+ ## Changes
52
+ [Read from implementation plan - list completed phases]
53
+
54
+ ## Testing
55
+ - [x] Unit/integration tests: 97 passing
56
+ - [x] E2E tests: All scenarios passed via Playwright MCP
57
+ - [x] Build succeeds
58
+
59
+ ## E2E Test Results
60
+ [Copy from implementation plan Phase 9]
61
+
62
+ Generated with Claude Code
63
+ EOF
64
+ )"
65
+ ```
66
+
67
+ ### Step 4: Request Codex Review
68
+
69
+ Run automated code review using Codex CLI:
70
+
71
+ ```bash
72
+ # Check if Codex CLI is installed
73
+ if ! command -v codex &> /dev/null; then
74
+ echo "WARNING: Codex CLI not installed. Manual review needed."
75
+ cd {{appDir}} && gh pr comment --body "Manual review requested - Codex CLI not available. Install: brew install openai/tap/codex"
76
+ else
77
+ echo "Running Codex code review..."
78
+ # Get diff summary for context
79
+ DIFF_SUMMARY=$(cd {{appDir}} && git diff main --stat | head -50)
80
+
81
+ # Use codex exec for non-interactive review
82
+ echo "Code Review Request for $FEATURE feature.
83
+
84
+ ## Changed Files:
85
+ $DIFF_SUMMARY
86
+
87
+ ## Review Checklist:
88
+ - Code quality and patterns consistency
89
+ - Test coverage adequacy
90
+ - Potential bugs or edge cases
91
+ - Security concerns (injection, XSS, etc.)
92
+ - Performance implications
93
+ - Error handling completeness
94
+
95
+ Please review and respond with:
96
+ - APPROVED if everything looks good
97
+ - Or list specific issues that need to be fixed" | cd {{appDir}} && codex exec --full-auto -
98
+ fi
99
+ ```
100
+
101
+ **Handle review feedback:**
102
+ - If Codex outputs "APPROVED" -> Proceed to Step 5 (rebase and merge)
103
+ - If Codex lists issues:
104
+ 1. Address each issue with code fixes
105
+ 2. Commit: `git -C {{appDir}} add -A && git -C {{appDir}} commit -m "fix($FEATURE): address review feedback"`
106
+ 3. Push: `git -C {{appDir}} push origin feat/$FEATURE`
107
+ 4. Re-run the `codex review` command above
108
+ - Max 3 review iterations before requiring manual intervention
109
+
110
+ ### Step 5: Rebase Before Merge (for Parallel Execution)
111
+ Before merging, ensure branch is up-to-date with main:
112
+ ```bash
113
+ cd {{appDir}} && git fetch origin main
114
+ cd {{appDir}} && git rebase origin/main
115
+ ```
116
+
117
+ If rebase has conflicts:
118
+ 1. Resolve conflicts in affected files
119
+ 2. `git add .` the resolved files
120
+ 3. `git rebase --continue`
121
+ 4. Re-run tests: `{{testCommand}} && {{buildCommand}}`
122
+
123
+ Push rebased branch:
124
+ ```bash
125
+ cd {{appDir}} && git push --force-with-lease origin feat/$FEATURE
126
+ ```
127
+
128
+ ### Step 6: Merge PR
129
+ When Codex review is approved and branch is rebased:
130
+ ```bash
131
+ cd {{appDir}} && gh pr merge --squash --delete-branch
132
+ ```
133
+
134
+ ### Step 7: Post-Merge Cleanup
135
+ 1. If using worktree, remove it:
136
+ ```bash
137
+ # Only if this feature used a worktree ({{appDir}}-$FEATURE directory exists)
138
+ git -C {{appDir}} worktree remove "../{{appDir}}-$FEATURE" 2>/dev/null || true
139
+ ```
140
+ 2. Checkout main and pull:
141
+ ```bash
142
+ git -C {{appDir}} checkout main && git -C {{appDir}} pull
143
+ ```
144
+
145
+ Note: Spec status updates are handled in the Spec Verification phase before PR creation.
146
+
147
+ ## Rules
148
+ - Do NOT merge without Codex approval
149
+ - Address ALL review comments before merging
150
+ - Use squash merge to keep history clean
151
+ - If gh CLI fails, check authentication: `gh auth status`
152
+ - Keep review conversation focused and professional
153
+
154
+ ## Troubleshooting
155
+ - **gh: command not found** -> Install GitHub CLI: `brew install gh`
156
+ - **gh auth error** -> Run: `gh auth login`
157
+ - **PR already exists** -> Use: `gh pr view` to see status
158
+ - **Codex CLI not installed** -> Install with: `brew install openai/tap/codex`, then `codex login`
159
+ - **Rebase conflicts** -> Resolve carefully, re-run all tests after
160
+
161
+ ## Learning Capture
162
+ If the review revealed patterns worth remembering, append to @.ralph/LEARNINGS.md:
163
+ - Code quality feedback -> Add under "## Anti-Patterns" or "## Patterns"
164
+ - Common review issues -> Add under "## Anti-Patterns"
165
+ - Good practices identified -> Add under "## Patterns"
166
+
167
+ Format: `- [YYYY-MM-DD] [$FEATURE] Brief description`
@@ -0,0 +1,72 @@
1
+ ## Context
2
+ Study @.ralph/specs/$FEATURE.md for original specification.
3
+ Study @.ralph/specs/$FEATURE-implementation-plan.md for completed tasks.
4
+
5
+ ## Learnings
6
+ Read @.ralph/LEARNINGS.md for verification patterns from previous features.
7
+
8
+ ## Task
9
+ Verify that the implementation meets the spec requirements. Update spec files accordingly.
10
+
11
+ ### Step 1: Review Requirements
12
+ Read @.ralph/specs/$FEATURE.md and for each requirement under "## Requirements":
13
+ - Check if it was implemented (review implementation plan tasks)
14
+ - Mark as `[x]` if complete
15
+ - Leave as `[ ]` if not implemented, add note explaining why
16
+
17
+ ### Step 2: Review Acceptance Criteria
18
+ For each item under "## Acceptance Criteria":
19
+ - Verify against E2E test results in implementation plan
20
+ - Mark as `[x]` if verified
21
+ - Leave as `[ ]` with note if not met
22
+
23
+ ### Step 3: Update Spec Status
24
+ Change `**Status:** Planned` (or `Draft`) to:
25
+ - `**Status:** Completed` if all requirements met
26
+ - `**Status:** Partial` if some requirements not met (with notes)
27
+
28
+ Update `**Last Updated:**` to today's date.
29
+
30
+ ### Step 4: Update README.md
31
+ Update @.ralph/specs/README.md Active Specs table:
32
+ - Change status from "Planned" to "Completed" (or "Partial")
33
+ - Update Last Updated date
34
+
35
+ ### Step 5: Document Gaps (if any)
36
+ If any requirements were not fully met, add a section to the spec:
37
+
38
+ ```markdown
39
+ ## Implementation Notes
40
+ - [Requirement X] - Deferred: [reason]
41
+ - [Acceptance Criteria Y] - Partial: [explanation]
42
+ ```
43
+
44
+ ### Step 6: Commit Changes
45
+ ```bash
46
+ git -C {{appDir}} add ../.ralph/specs/
47
+ git -C {{appDir}} commit -m "docs($FEATURE): verify spec requirements complete"
48
+ git -C {{appDir}} push origin feat/$FEATURE
49
+ ```
50
+
51
+ ## Verification Checklist
52
+ Before marking complete, ensure:
53
+ - [ ] All requirements in spec have been reviewed
54
+ - [ ] All acceptance criteria have been reviewed
55
+ - [ ] Spec status updated appropriately
56
+ - [ ] README.md table updated
57
+ - [ ] Any gaps documented with clear explanations
58
+ - [ ] Changes committed and pushed
59
+
60
+ ## Rules
61
+ - Be thorough - check every requirement and acceptance criterion
62
+ - Be honest - don't mark incomplete items as complete
63
+ - Document gaps clearly for future reference
64
+ - If a requirement was intentionally deferred, explain why
65
+
66
+ ## Learning Capture
67
+ If verification revealed patterns worth remembering, append to @.ralph/LEARNINGS.md:
68
+ - Common gaps between spec and implementation -> Add under "## Anti-Patterns"
69
+ - Useful spec writing patterns -> Add under "## Patterns"
70
+ - Verification tips -> Add under "## Tool Usage"
71
+
72
+ Format: `- [YYYY-MM-DD] [$FEATURE] Brief description`
@@ -0,0 +1,5 @@
1
+ # Ralph working files
2
+ *.log
3
+ *.tmp
4
+
5
+ # Don't ignore anything else - all ralph files should be committed
@@ -0,0 +1,24 @@
1
+ # Learnings
2
+
3
+ Accumulated knowledge from feature implementations. Reference before starting new tasks.
4
+
5
+ ## Patterns (What Works)
6
+
7
+ <!-- Add successful patterns here -->
8
+ - [YYYY-MM-DD] [feature] Pattern description
9
+
10
+ ## Anti-Patterns (What to Avoid)
11
+
12
+ <!-- Add mistakes and issues to avoid -->
13
+ - [YYYY-MM-DD] [feature] Anti-pattern description
14
+
15
+ ### E2E Pitfalls
16
+ <!-- E2E testing specific issues -->
17
+
18
+ ## Tool Usage
19
+
20
+ <!-- Tips for using MCP tools and CLI -->
21
+
22
+ ## Codebase Conventions
23
+
24
+ <!-- Project-specific conventions discovered -->
@@ -0,0 +1,61 @@
1
+ # .ralph - AI Development Configuration
2
+
3
+ This directory contains configuration and guidance for AI-assisted development of **{{projectName}}**.
4
+
5
+ ## Structure
6
+
7
+ ```
8
+ .ralph/
9
+ |-- AGENTS.md # Commands, patterns, and coding rules
10
+ |-- LEARNINGS.md # Accumulated knowledge from iterations
11
+ |-- prompts/ # Task-specific prompts
12
+ | |-- PROMPT.md # Main implementation prompt
13
+ | |-- PROMPT_feature.md # Feature planning prompt
14
+ | |-- PROMPT_e2e.md # E2E testing prompt
15
+ | |-- PROMPT_verify.md # Verification prompt
16
+ | |-- PROMPT_review.md # PR review prompt
17
+ |-- guides/ # Reference documentation
18
+ | |-- FRONTEND.md # UI/UX patterns and checklist
19
+ | |-- SECURITY.md # Security review checklist
20
+ | |-- PERFORMANCE.md # Performance patterns
21
+ |-- specs/ # Feature specifications
22
+ | |-- README.md # Spec template and index
23
+ | |-- _example.md # Example specification
24
+ |-- scripts/ # Automation scripts
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ ### For Claude Code / AI Assistants
30
+
31
+ Reference these files in your prompts:
32
+ - `@.ralph/AGENTS.md` - Stack info, commands, coding rules
33
+ - `@.ralph/prompts/PROMPT.md` - Implementation workflow
34
+ - `@.ralph/guides/FRONTEND.md` - UI development guide
35
+
36
+ ### Feature Loop
37
+
38
+ 1. **Plan**: Use `PROMPT_feature.md` to create implementation plan
39
+ 2. **Implement**: Use `PROMPT.md` for iterative task completion
40
+ 3. **Test**: Use `PROMPT_e2e.md` for browser-based testing
41
+ 4. **Verify**: Use `PROMPT_verify.md` to verify spec requirements
42
+ 5. **Review**: Use `PROMPT_review.md` to create PR and get review
43
+
44
+ ### Specs
45
+
46
+ Add new feature specs to `.ralph/specs/`:
47
+ 1. Copy `_example.md` as starting point
48
+ 2. Fill in requirements and acceptance criteria
49
+ 3. Use `PROMPT_feature.md` to create implementation plan
50
+
51
+ ## Detected Stack
52
+
53
+ - **Framework:** {{framework}}{{#if frameworkVersion}} {{frameworkVersion}}{{/if}}{{#if frameworkVariant}} ({{frameworkVariant}}){{/if}}
54
+ - **Package Manager:** {{packageManager}}
55
+ - **Styling:** {{styling}}
56
+ {{#if unitTest}}- **Unit Testing:** {{unitTest}}{{/if}}
57
+ {{#if e2eTest}}- **E2E Testing:** {{e2eTest}}{{/if}}
58
+
59
+ ## Configuration
60
+
61
+ See `ralph.config.js` in project root for full configuration.
@@ -0,0 +1,267 @@
1
+ #!/bin/bash
2
+ # feature-loop.sh - Full feature workflow: branch -> implement -> E2E test -> PR -> review -> merge
3
+ # Generated by ralph-cli for {{projectName}}
4
+ # Usage: ./feature-loop.sh <feature-name> [max-iterations] [max-e2e-attempts] [--worktree] [--resume] [--model MODEL]
5
+ #
6
+ # Options:
7
+ # --worktree Use git worktree for isolation (enables parallel execution)
8
+ # --resume Resume an interrupted loop (reuses existing branch/worktree)
9
+ # --model MODEL Claude model to use (e.g., opus, sonnet, claude-sonnet-4-5-20250514)
10
+
11
+ set -e
12
+ set -o pipefail
13
+
14
+ # Get script directory
15
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
16
+
17
+ # Load config from ralph.config.js if available
18
+ if [ -f "$SCRIPT_DIR/../ralph.config.js" ]; then
19
+ RALPH_ROOT=$(node -e "console.log(require('$SCRIPT_DIR/../ralph.config.js').paths?.root || '.ralph')" 2>/dev/null || echo ".ralph")
20
+ SPEC_DIR=$(node -e "console.log(require('$SCRIPT_DIR/../ralph.config.js').paths?.specs || '.ralph/specs')" 2>/dev/null || echo ".ralph/specs")
21
+ PROMPTS_DIR=$(node -e "console.log(require('$SCRIPT_DIR/../ralph.config.js').paths?.prompts || '.ralph/prompts')" 2>/dev/null || echo ".ralph/prompts")
22
+ DEFAULT_MODEL=$(node -e "console.log(require('$SCRIPT_DIR/../ralph.config.js').loop?.defaultModel || 'sonnet')" 2>/dev/null || echo "sonnet")
23
+ PLANNING_MODEL=$(node -e "console.log(require('$SCRIPT_DIR/../ralph.config.js').loop?.planningModel || 'opus')" 2>/dev/null || echo "opus")
24
+ DEFAULT_MAX_ITERATIONS=$(node -e "console.log(require('$SCRIPT_DIR/../ralph.config.js').loop?.maxIterations || 10)" 2>/dev/null || echo "10")
25
+ DEFAULT_MAX_E2E=$(node -e "console.log(require('$SCRIPT_DIR/../ralph.config.js').loop?.maxE2eAttempts || 5)" 2>/dev/null || echo "5")
26
+ elif [ -f "$SCRIPT_DIR/../../ralph.config.js" ]; then
27
+ RALPH_ROOT=$(node -e "console.log(require('$SCRIPT_DIR/../../ralph.config.js').paths?.root || '.ralph')" 2>/dev/null || echo ".ralph")
28
+ SPEC_DIR=$(node -e "console.log(require('$SCRIPT_DIR/../../ralph.config.js').paths?.specs || '.ralph/specs')" 2>/dev/null || echo ".ralph/specs")
29
+ PROMPTS_DIR=$(node -e "console.log(require('$SCRIPT_DIR/../../ralph.config.js').paths?.prompts || '.ralph/prompts')" 2>/dev/null || echo ".ralph/prompts")
30
+ DEFAULT_MODEL=$(node -e "console.log(require('$SCRIPT_DIR/../../ralph.config.js').loop?.defaultModel || 'sonnet')" 2>/dev/null || echo "sonnet")
31
+ PLANNING_MODEL=$(node -e "console.log(require('$SCRIPT_DIR/../../ralph.config.js').loop?.planningModel || 'opus')" 2>/dev/null || echo "opus")
32
+ DEFAULT_MAX_ITERATIONS=$(node -e "console.log(require('$SCRIPT_DIR/../../ralph.config.js').loop?.maxIterations || 10)" 2>/dev/null || echo "10")
33
+ DEFAULT_MAX_E2E=$(node -e "console.log(require('$SCRIPT_DIR/../../ralph.config.js').loop?.maxE2eAttempts || 5)" 2>/dev/null || echo "5")
34
+ else
35
+ # Default paths
36
+ RALPH_ROOT=".ralph"
37
+ SPEC_DIR=".ralph/specs"
38
+ PROMPTS_DIR=".ralph/prompts"
39
+ DEFAULT_MODEL="sonnet"
40
+ PLANNING_MODEL="opus"
41
+ DEFAULT_MAX_ITERATIONS="10"
42
+ DEFAULT_MAX_E2E="5"
43
+ fi
44
+
45
+ # Navigate to project root (parent of .ralph)
46
+ cd "$SCRIPT_DIR/../.."
47
+
48
+ # Parse arguments
49
+ USE_WORKTREE=false
50
+ RESUME=false
51
+ MODEL=""
52
+ POSITIONAL=()
53
+ while [[ $# -gt 0 ]]; do
54
+ case $1 in
55
+ --worktree)
56
+ USE_WORKTREE=true
57
+ shift
58
+ ;;
59
+ --resume)
60
+ RESUME=true
61
+ shift
62
+ ;;
63
+ --model)
64
+ MODEL="$2"
65
+ shift 2
66
+ ;;
67
+ *)
68
+ POSITIONAL+=("$1")
69
+ shift
70
+ ;;
71
+ esac
72
+ done
73
+ set -- "${POSITIONAL[@]}"
74
+
75
+ # Build claude commands
76
+ CLAUDE_CMD_OPUS="claude -p --dangerously-skip-permissions --model ${PLANNING_MODEL}"
77
+ CLAUDE_CMD_IMPL="claude -p --dangerously-skip-permissions --model ${MODEL:-$DEFAULT_MODEL}"
78
+
79
+ # Token tracking
80
+ TOKENS_FILE="/tmp/ralph-loop-${1}.tokens"
81
+ CLAUDE_OUTPUT="/tmp/ralph-loop-${1}.output"
82
+
83
+ # Initialize token tracking
84
+ init_tokens() {
85
+ echo "0|0" > "$TOKENS_FILE"
86
+ }
87
+
88
+ # Parse and accumulate tokens
89
+ parse_and_accumulate_tokens() {
90
+ local output_file="$1"
91
+ local input_tokens=$({ grep -oE "input[^0-9]*([0-9,]+)" "$output_file" 2>/dev/null || true; } | { grep -oE "[0-9,]+" || true; } | tr -d ',' | tail -1)
92
+ local output_tokens=$({ grep -oE "output[^0-9]*([0-9,]+)" "$output_file" 2>/dev/null || true; } | { grep -oE "[0-9,]+" || true; } | tr -d ',' | tail -1)
93
+
94
+ input_tokens=${input_tokens:-0}
95
+ output_tokens=${output_tokens:-0}
96
+
97
+ if [ -f "$TOKENS_FILE" ]; then
98
+ local current=$(cat "$TOKENS_FILE")
99
+ local current_input=$(echo "$current" | cut -d'|' -f1)
100
+ local current_output=$(echo "$current" | cut -d'|' -f2)
101
+ [[ "$current_input" =~ ^[0-9]+$ ]] || current_input=0
102
+ [[ "$current_output" =~ ^[0-9]+$ ]] || current_output=0
103
+ else
104
+ current_input=0
105
+ current_output=0
106
+ fi
107
+
108
+ local new_input=$((current_input + input_tokens))
109
+ local new_output=$((current_output + output_tokens))
110
+ echo "${new_input}|${new_output}" > "$TOKENS_FILE"
111
+ }
112
+
113
+ # Initialize tokens
114
+ init_tokens
115
+
116
+ FEATURE="${1:?Usage: ./feature-loop.sh <feature-name> [max-iterations] [max-e2e-attempts] [--worktree] [--resume] [--model MODEL]}"
117
+ MAX_ITERATIONS="${2:-$DEFAULT_MAX_ITERATIONS}"
118
+ MAX_E2E_ATTEMPTS="${3:-$DEFAULT_MAX_E2E}"
119
+ ITERATION=0
120
+
121
+ # Paths
122
+ SPEC_FILE="$SPEC_DIR/${FEATURE}.md"
123
+ PLAN_FILE="$SPEC_DIR/${FEATURE}-implementation-plan.md"
124
+ BRANCH="feat/${FEATURE}"
125
+ APP_DIR="$(pwd)"
126
+
127
+ echo "=========================================="
128
+ echo "Ralph Loop: $FEATURE"
129
+ echo "Spec: $SPEC_FILE"
130
+ echo "Plan: $PLAN_FILE"
131
+ echo "Branch: $BRANCH"
132
+ echo "App dir: $APP_DIR"
133
+ echo "Worktree mode: $USE_WORKTREE"
134
+ echo "Resume mode: $RESUME"
135
+ echo "Model (planning): $PLANNING_MODEL"
136
+ echo "Model (impl): ${MODEL:-$DEFAULT_MODEL}"
137
+ echo "Max iterations: $MAX_ITERATIONS"
138
+ echo "Max E2E attempts: $MAX_E2E_ATTEMPTS"
139
+ echo "=========================================="
140
+
141
+ # Phase 1: Validate spec exists
142
+ if [ ! -f "$SPEC_FILE" ]; then
143
+ echo "ERROR: Spec file not found: $SPEC_FILE"
144
+ echo "Create the spec first: ralph new $FEATURE"
145
+ exit 1
146
+ fi
147
+
148
+ # Phase 2: Create branch if not exists
149
+ CURRENT_BRANCH=$(git branch --show-current)
150
+ if [ "$CURRENT_BRANCH" != "$BRANCH" ]; then
151
+ if git rev-parse --verify "$BRANCH" >/dev/null 2>&1; then
152
+ if [ "$RESUME" = true ]; then
153
+ echo "Resuming on existing branch: $BRANCH"
154
+ git checkout "$BRANCH"
155
+ else
156
+ echo "Creating/switching to branch: $BRANCH"
157
+ git checkout -B "$BRANCH" main 2>/dev/null || git checkout -B "$BRANCH" master
158
+ fi
159
+ else
160
+ echo "Creating branch: $BRANCH"
161
+ git checkout -b "$BRANCH" main 2>/dev/null || git checkout -b "$BRANCH" master
162
+ fi
163
+ else
164
+ echo "Already on branch: $BRANCH"
165
+ fi
166
+
167
+ # Create output file for monitoring
168
+ touch "$CLAUDE_OUTPUT"
169
+
170
+ # Phase 3: Planning (if no implementation plan exists)
171
+ if [ ! -f "$PLAN_FILE" ]; then
172
+ echo "======================== PLANNING PHASE ========================"
173
+ export FEATURE APP_DIR SPEC_DIR PROMPTS_DIR
174
+ cat "$PROMPTS_DIR/PROMPT_feature.md" | envsubst | $CLAUDE_CMD_OPUS 2>&1 | tee "$CLAUDE_OUTPUT" || {
175
+ echo "ERROR: Planning phase failed"
176
+ exit 1
177
+ }
178
+ parse_and_accumulate_tokens "$CLAUDE_OUTPUT"
179
+ fi
180
+
181
+ # Phase 4: Implementation loop
182
+ echo "======================== IMPLEMENTATION PHASE ========================"
183
+ while true; do
184
+ if [ $ITERATION -ge $MAX_ITERATIONS ]; then
185
+ echo "Reached max iterations: $MAX_ITERATIONS"
186
+ exit 1
187
+ fi
188
+
189
+ ITERATION=$((ITERATION + 1))
190
+ echo "$ITERATION|$MAX_ITERATIONS|$(date +%s)" > "/tmp/ralph-loop-${FEATURE}.status"
191
+ echo "------------------------ Iteration $ITERATION ------------------------"
192
+
193
+ # Check if implementation tasks are done
194
+ PENDING_IMPL=$({ grep "^- \[ \]" "$PLAN_FILE" 2>/dev/null || true; } | { grep -v "E2E:" || true; } | wc -l | tr -d ' ')
195
+ if [ "$PENDING_IMPL" -eq 0 ]; then
196
+ echo "All implementation tasks completed!"
197
+ break
198
+ fi
199
+
200
+ echo "Pending implementation tasks: $PENDING_IMPL"
201
+ export FEATURE APP_DIR SPEC_DIR PROMPTS_DIR
202
+ cat "$PROMPTS_DIR/PROMPT.md" | envsubst | $CLAUDE_CMD_IMPL 2>&1 | tee "$CLAUDE_OUTPUT" || true
203
+ parse_and_accumulate_tokens "$CLAUDE_OUTPUT"
204
+
205
+ sleep 2
206
+ done
207
+
208
+ # Phase 5: E2E Testing
209
+ echo "======================== E2E TESTING PHASE ========================"
210
+ E2E_TOTAL=$({ grep "^- \[.\].*E2E:" "$PLAN_FILE" 2>/dev/null || true; } | wc -l | tr -d ' ')
211
+ if [ "$E2E_TOTAL" -eq 0 ]; then
212
+ echo "No E2E scenarios defined, skipping E2E phase."
213
+ else
214
+ E2E_ATTEMPT=0
215
+ while [ $E2E_ATTEMPT -lt $MAX_E2E_ATTEMPTS ]; do
216
+ E2E_ATTEMPT=$((E2E_ATTEMPT + 1))
217
+ echo "------------------------ E2E Attempt $E2E_ATTEMPT of $MAX_E2E_ATTEMPTS ------------------------"
218
+
219
+ export FEATURE APP_DIR SPEC_DIR PROMPTS_DIR
220
+ cat "$PROMPTS_DIR/PROMPT_e2e.md" | envsubst | $CLAUDE_CMD_IMPL 2>&1 | tee "$CLAUDE_OUTPUT" || true
221
+ parse_and_accumulate_tokens "$CLAUDE_OUTPUT"
222
+
223
+ # Check if all E2E tests passed
224
+ E2E_FAILED=$({ grep "^- \[ \].*E2E:.*FAILED" "$PLAN_FILE" 2>/dev/null || true; } | wc -l | tr -d ' ')
225
+ E2E_PENDING=$({ grep "^- \[ \].*E2E:" "$PLAN_FILE" 2>/dev/null || true; } | { grep -v "FAILED" || true; } | wc -l | tr -d ' ')
226
+
227
+ if [ "$E2E_FAILED" -eq 0 ] && [ "$E2E_PENDING" -eq 0 ]; then
228
+ echo "All E2E tests passed!"
229
+ break
230
+ fi
231
+
232
+ if [ $E2E_ATTEMPT -lt $MAX_E2E_ATTEMPTS ]; then
233
+ echo "E2E tests have failures. Running fix iteration..."
234
+ cat "$PROMPTS_DIR/PROMPT.md" | envsubst | $CLAUDE_CMD_IMPL 2>&1 | tee "$CLAUDE_OUTPUT" || true
235
+ parse_and_accumulate_tokens "$CLAUDE_OUTPUT"
236
+ fi
237
+ done
238
+ fi
239
+
240
+ # Phase 6: Spec Verification
241
+ echo "======================== SPEC VERIFICATION PHASE ========================"
242
+ export FEATURE APP_DIR SPEC_DIR PROMPTS_DIR
243
+ cat "$PROMPTS_DIR/PROMPT_verify.md" | envsubst | $CLAUDE_CMD_OPUS 2>&1 | tee "$CLAUDE_OUTPUT" || true
244
+ parse_and_accumulate_tokens "$CLAUDE_OUTPUT"
245
+
246
+ # Phase 7: PR and Review
247
+ echo "======================== PR & REVIEW PHASE ========================"
248
+ export FEATURE APP_DIR SPEC_DIR PROMPTS_DIR
249
+ cat "$PROMPTS_DIR/PROMPT_review.md" | envsubst | $CLAUDE_CMD_OPUS 2>&1 | tee "$CLAUDE_OUTPUT" || true
250
+ parse_and_accumulate_tokens "$CLAUDE_OUTPUT"
251
+
252
+ # Cleanup temp files
253
+ rm -f "/tmp/ralph-loop-${FEATURE}.status" 2>/dev/null || true
254
+ rm -f "/tmp/ralph-loop-${FEATURE}.output" 2>/dev/null || true
255
+
256
+ # Print final token usage
257
+ if [ -f "/tmp/ralph-loop-${FEATURE}.tokens" ]; then
258
+ echo ""
259
+ echo "=========================================="
260
+ echo "Final Token Usage:"
261
+ cat "/tmp/ralph-loop-${FEATURE}.tokens" | awk -F'|' '{printf " Input: %s tokens\n Output: %s tokens\n Total: %s tokens\n", $1, $2, $1+$2}'
262
+ echo "=========================================="
263
+ fi
264
+
265
+ echo "=========================================="
266
+ echo "Ralph loop completed: $FEATURE"
267
+ echo "=========================================="