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.
- package/LICENSE +21 -0
- package/README.md +341 -0
- package/bin/ralph.js +8 -0
- package/dist/ai/enhancer.d.ts +100 -0
- package/dist/ai/enhancer.d.ts.map +1 -0
- package/dist/ai/enhancer.js +233 -0
- package/dist/ai/enhancer.js.map +1 -0
- package/dist/ai/index.d.ts +8 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +11 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/prompts.d.ts +26 -0
- package/dist/ai/prompts.d.ts.map +1 -0
- package/dist/ai/prompts.js +201 -0
- package/dist/ai/prompts.js.map +1 -0
- package/dist/ai/providers.d.ts +35 -0
- package/dist/ai/providers.d.ts.map +1 -0
- package/dist/ai/providers.js +104 -0
- package/dist/ai/providers.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +196 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/init.d.ts +16 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +124 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/monitor.d.ts +17 -0
- package/dist/commands/monitor.d.ts.map +1 -0
- package/dist/commands/monitor.js +342 -0
- package/dist/commands/monitor.js.map +1 -0
- package/dist/commands/new.d.ts +19 -0
- package/dist/commands/new.d.ts.map +1 -0
- package/dist/commands/new.js +272 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/commands/run.d.ts +16 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +175 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/generator/config.d.ts +59 -0
- package/dist/generator/config.d.ts.map +1 -0
- package/dist/generator/config.js +68 -0
- package/dist/generator/config.js.map +1 -0
- package/dist/generator/index.d.ts +64 -0
- package/dist/generator/index.d.ts.map +1 -0
- package/dist/generator/index.js +147 -0
- package/dist/generator/index.js.map +1 -0
- package/dist/generator/templates.d.ts +70 -0
- package/dist/generator/templates.d.ts.map +1 -0
- package/dist/generator/templates.js +296 -0
- package/dist/generator/templates.js.map +1 -0
- package/dist/generator/writer.d.ts +93 -0
- package/dist/generator/writer.d.ts.map +1 -0
- package/dist/generator/writer.js +213 -0
- package/dist/generator/writer.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/scanner/detectors/core/framework.d.ts +11 -0
- package/dist/scanner/detectors/core/framework.d.ts.map +1 -0
- package/dist/scanner/detectors/core/framework.js +275 -0
- package/dist/scanner/detectors/core/framework.js.map +1 -0
- package/dist/scanner/detectors/core/packageManager.d.ts +11 -0
- package/dist/scanner/detectors/core/packageManager.d.ts.map +1 -0
- package/dist/scanner/detectors/core/packageManager.js +74 -0
- package/dist/scanner/detectors/core/packageManager.js.map +1 -0
- package/dist/scanner/detectors/core/styling.d.ts +12 -0
- package/dist/scanner/detectors/core/styling.d.ts.map +1 -0
- package/dist/scanner/detectors/core/styling.js +230 -0
- package/dist/scanner/detectors/core/styling.js.map +1 -0
- package/dist/scanner/detectors/core/testing.d.ts +12 -0
- package/dist/scanner/detectors/core/testing.d.ts.map +1 -0
- package/dist/scanner/detectors/core/testing.js +190 -0
- package/dist/scanner/detectors/core/testing.js.map +1 -0
- package/dist/scanner/detectors/data/api.d.ts +12 -0
- package/dist/scanner/detectors/data/api.d.ts.map +1 -0
- package/dist/scanner/detectors/data/api.js +261 -0
- package/dist/scanner/detectors/data/api.js.map +1 -0
- package/dist/scanner/detectors/data/database.d.ts +12 -0
- package/dist/scanner/detectors/data/database.d.ts.map +1 -0
- package/dist/scanner/detectors/data/database.js +213 -0
- package/dist/scanner/detectors/data/database.js.map +1 -0
- package/dist/scanner/detectors/data/orm.d.ts +12 -0
- package/dist/scanner/detectors/data/orm.d.ts.map +1 -0
- package/dist/scanner/detectors/data/orm.js +160 -0
- package/dist/scanner/detectors/data/orm.js.map +1 -0
- package/dist/scanner/detectors/frontend/formHandling.d.ts +12 -0
- package/dist/scanner/detectors/frontend/formHandling.d.ts.map +1 -0
- package/dist/scanner/detectors/frontend/formHandling.js +211 -0
- package/dist/scanner/detectors/frontend/formHandling.js.map +1 -0
- package/dist/scanner/detectors/frontend/stateManagement.d.ts +12 -0
- package/dist/scanner/detectors/frontend/stateManagement.d.ts.map +1 -0
- package/dist/scanner/detectors/frontend/stateManagement.js +221 -0
- package/dist/scanner/detectors/frontend/stateManagement.js.map +1 -0
- package/dist/scanner/detectors/frontend/uiComponents.d.ts +12 -0
- package/dist/scanner/detectors/frontend/uiComponents.d.ts.map +1 -0
- package/dist/scanner/detectors/frontend/uiComponents.js +285 -0
- package/dist/scanner/detectors/frontend/uiComponents.js.map +1 -0
- package/dist/scanner/detectors/infra/deployment.d.ts +12 -0
- package/dist/scanner/detectors/infra/deployment.d.ts.map +1 -0
- package/dist/scanner/detectors/infra/deployment.js +301 -0
- package/dist/scanner/detectors/infra/deployment.js.map +1 -0
- package/dist/scanner/detectors/infra/monorepo.d.ts +12 -0
- package/dist/scanner/detectors/infra/monorepo.d.ts.map +1 -0
- package/dist/scanner/detectors/infra/monorepo.js +219 -0
- package/dist/scanner/detectors/infra/monorepo.js.map +1 -0
- package/dist/scanner/detectors/mcp/mcpProject.d.ts +12 -0
- package/dist/scanner/detectors/mcp/mcpProject.d.ts.map +1 -0
- package/dist/scanner/detectors/mcp/mcpProject.js +154 -0
- package/dist/scanner/detectors/mcp/mcpProject.js.map +1 -0
- package/dist/scanner/detectors/mcp/mcpServers.d.ts +17 -0
- package/dist/scanner/detectors/mcp/mcpServers.d.ts.map +1 -0
- package/dist/scanner/detectors/mcp/mcpServers.js +193 -0
- package/dist/scanner/detectors/mcp/mcpServers.js.map +1 -0
- package/dist/scanner/detectors/services/analytics.d.ts +12 -0
- package/dist/scanner/detectors/services/analytics.d.ts.map +1 -0
- package/dist/scanner/detectors/services/analytics.js +236 -0
- package/dist/scanner/detectors/services/analytics.js.map +1 -0
- package/dist/scanner/detectors/services/auth.d.ts +12 -0
- package/dist/scanner/detectors/services/auth.d.ts.map +1 -0
- package/dist/scanner/detectors/services/auth.js +217 -0
- package/dist/scanner/detectors/services/auth.js.map +1 -0
- package/dist/scanner/detectors/services/email.d.ts +12 -0
- package/dist/scanner/detectors/services/email.d.ts.map +1 -0
- package/dist/scanner/detectors/services/email.js +211 -0
- package/dist/scanner/detectors/services/email.js.map +1 -0
- package/dist/scanner/detectors/services/payments.d.ts +12 -0
- package/dist/scanner/detectors/services/payments.d.ts.map +1 -0
- package/dist/scanner/detectors/services/payments.js +185 -0
- package/dist/scanner/detectors/services/payments.js.map +1 -0
- package/dist/scanner/detectors/utils.d.ts +160 -0
- package/dist/scanner/detectors/utils.d.ts.map +1 -0
- package/dist/scanner/detectors/utils.js +222 -0
- package/dist/scanner/detectors/utils.js.map +1 -0
- package/dist/scanner/index.d.ts +42 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +282 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/scanner/registry.d.ts +43 -0
- package/dist/scanner/registry.d.ts.map +1 -0
- package/dist/scanner/registry.js +243 -0
- package/dist/scanner/registry.js.map +1 -0
- package/dist/scanner/types.d.ts +112 -0
- package/dist/scanner/types.d.ts.map +1 -0
- package/dist/scanner/types.js +6 -0
- package/dist/scanner/types.js.map +1 -0
- package/dist/templates/config/ralph.config.js.tmpl +38 -0
- package/dist/templates/guides/AGENTS.md.tmpl +100 -0
- package/dist/templates/guides/FRONTEND.md.tmpl +523 -0
- package/dist/templates/guides/PERFORMANCE.md.tmpl +264 -0
- package/dist/templates/guides/SECURITY.md.tmpl +100 -0
- package/dist/templates/prompts/PROMPT.md.tmpl +77 -0
- package/dist/templates/prompts/PROMPT_e2e.md.tmpl +234 -0
- package/dist/templates/prompts/PROMPT_feature.md.tmpl +83 -0
- package/dist/templates/prompts/PROMPT_review.md.tmpl +167 -0
- package/dist/templates/prompts/PROMPT_verify.md.tmpl +72 -0
- package/dist/templates/root/.gitignore.tmpl +5 -0
- package/dist/templates/root/LEARNINGS.md.tmpl +24 -0
- package/dist/templates/root/README.md.tmpl +61 -0
- package/dist/templates/scripts/feature-loop.sh.tmpl +267 -0
- package/dist/templates/scripts/loop.sh.tmpl +59 -0
- package/dist/templates/scripts/ralph-monitor.sh.tmpl +244 -0
- package/dist/templates/specs/README.md.tmpl +57 -0
- package/dist/templates/specs/_example.md.tmpl +71 -0
- package/dist/utils/config.d.ts +95 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +148 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/header.d.ts +5 -0
- package/dist/utils/header.d.ts.map +1 -0
- package/dist/utils/header.js +15 -0
- package/dist/utils/header.js.map +1 -0
- package/dist/utils/logger.d.ts +11 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +24 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +44 -0
- package/src/ai/enhancer.ts +350 -0
- package/src/ai/index.ts +38 -0
- package/src/ai/prompts.ts +217 -0
- package/src/ai/providers.ts +136 -0
- package/src/cli.ts +255 -0
- package/src/commands/init.ts +149 -0
- package/src/commands/monitor.ts +412 -0
- package/src/commands/new.ts +312 -0
- package/src/commands/run.ts +214 -0
- package/src/generator/config.ts +116 -0
- package/src/generator/index.ts +227 -0
- package/src/generator/templates.ts +412 -0
- package/src/generator/writer.ts +293 -0
- package/src/index.ts +41 -0
- package/src/scanner/detectors/core/framework.ts +332 -0
- package/src/scanner/detectors/core/packageManager.ts +91 -0
- package/src/scanner/detectors/core/styling.ts +261 -0
- package/src/scanner/detectors/core/testing.ts +221 -0
- package/src/scanner/detectors/data/api.ts +303 -0
- package/src/scanner/detectors/data/database.ts +245 -0
- package/src/scanner/detectors/data/orm.ts +180 -0
- package/src/scanner/detectors/frontend/formHandling.ts +244 -0
- package/src/scanner/detectors/frontend/stateManagement.ts +261 -0
- package/src/scanner/detectors/frontend/uiComponents.ts +328 -0
- package/src/scanner/detectors/infra/deployment.ts +343 -0
- package/src/scanner/detectors/infra/monorepo.ts +251 -0
- package/src/scanner/detectors/mcp/mcpProject.ts +176 -0
- package/src/scanner/detectors/mcp/mcpServers.ts +237 -0
- package/src/scanner/detectors/services/analytics.ts +273 -0
- package/src/scanner/detectors/services/auth.ts +254 -0
- package/src/scanner/detectors/services/email.ts +244 -0
- package/src/scanner/detectors/services/payments.ts +213 -0
- package/src/scanner/detectors/utils.ts +251 -0
- package/src/scanner/index.ts +354 -0
- package/src/scanner/registry.ts +301 -0
- package/src/scanner/types.ts +152 -0
- package/src/templates/config/ralph.config.js.tmpl +38 -0
- package/src/templates/guides/AGENTS.md.tmpl +100 -0
- package/src/templates/guides/FRONTEND.md.tmpl +523 -0
- package/src/templates/guides/PERFORMANCE.md.tmpl +264 -0
- package/src/templates/guides/SECURITY.md.tmpl +100 -0
- package/src/templates/prompts/PROMPT.md.tmpl +77 -0
- package/src/templates/prompts/PROMPT_e2e.md.tmpl +234 -0
- package/src/templates/prompts/PROMPT_feature.md.tmpl +83 -0
- package/src/templates/prompts/PROMPT_review.md.tmpl +167 -0
- package/src/templates/prompts/PROMPT_verify.md.tmpl +72 -0
- package/src/templates/root/.gitignore.tmpl +5 -0
- package/src/templates/root/LEARNINGS.md.tmpl +24 -0
- package/src/templates/root/README.md.tmpl +61 -0
- package/src/templates/scripts/feature-loop.sh.tmpl +267 -0
- package/src/templates/scripts/loop.sh.tmpl +59 -0
- package/src/templates/scripts/ralph-monitor.sh.tmpl +244 -0
- package/src/templates/specs/README.md.tmpl +57 -0
- package/src/templates/specs/_example.md.tmpl +71 -0
- package/src/utils/config.ts +221 -0
- package/src/utils/header.ts +15 -0
- package/src/utils/logger.ts +28 -0
- 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,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 "=========================================="
|