agentic-loop 3.22.1 → 3.26.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/.claude/commands/color.md +74 -0
- package/.claude/commands/tab-rename.md +53 -0
- package/.claude/commands/tour.md +2 -2
- package/.claude/commands/vibe-help.md +1 -1
- package/.claude/commands/vibe-list.md +7 -7
- package/.claude/skills/color/SKILL.md +74 -0
- package/.claude/skills/my-dna/SKILL.md +3 -1
- package/.claude/skills/prd/SKILL.md +169 -22
- package/.claude/skills/prd-check/SKILL.md +67 -10
- package/.claude/skills/tour/SKILL.md +2 -2
- package/.claude/skills/vibe-help/SKILL.md +1 -1
- package/.claude/skills/vibe-list/SKILL.md +8 -8
- package/README.md +39 -30
- package/package.json +1 -1
- package/ralph/hooks/install.sh +47 -63
- package/ralph/init.sh +6 -6
- package/ralph/loop.sh +127 -3
- package/ralph/prd-check.sh +36 -5
- package/ralph/prd.sh +1 -1
- package/ralph/setup/feature-tour.sh +1 -1
- package/ralph/setup/tutorial.sh +3 -3
- package/ralph/setup.sh +152 -18
- package/ralph/utils.sh +48 -0
- package/templates/examples/CLAUDE-fullstack.md +3 -3
- package/templates/signs.json +7 -0
- package/.claude/commands/idea.md +0 -216
- package/.claude/skills/idea/SKILL.md +0 -272
|
@@ -4,7 +4,7 @@ description: Run PRD validation to check story quality, test coverage, and struc
|
|
|
4
4
|
|
|
5
5
|
# PRD Check
|
|
6
6
|
|
|
7
|
-
Run PRD validation on demand to check story quality, test coverage, and structure before starting the autonomous loop.
|
|
7
|
+
Run PRD validation on demand to check story quality, test coverage, and structure before starting the autonomous loop. Cross-references against learned signs and past failure patterns.
|
|
8
8
|
|
|
9
9
|
## Instructions
|
|
10
10
|
|
|
@@ -17,32 +17,89 @@ ls -la .ralph/prd.json 2>/dev/null || echo "NOT_FOUND"
|
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
If no PRD exists, tell the user:
|
|
20
|
-
> No PRD found at `.ralph/prd.json`. Generate one first with `/
|
|
20
|
+
> No PRD found at `.ralph/prd.json`. Generate one first with `/prd`.
|
|
21
21
|
|
|
22
22
|
**STOP** if no PRD found.
|
|
23
23
|
|
|
24
|
-
### Step 2:
|
|
24
|
+
### Step 2: Load Project Knowledge
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
Read the project's accumulated knowledge:
|
|
27
|
+
|
|
28
|
+
1. Read signs:
|
|
29
|
+
```bash
|
|
30
|
+
cat .ralph/signs.json 2>/dev/null
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
2. Read suggested signs (last 50 lines — file can be huge):
|
|
34
|
+
```bash
|
|
35
|
+
tail -50 .ralph/suggested-signs.txt 2>/dev/null
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
3. Read recent progress for failure patterns:
|
|
39
|
+
```bash
|
|
40
|
+
tail -100 .ralph/progress.txt 2>/dev/null
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Step 3: Run Structural Validation (dry-run)
|
|
27
44
|
|
|
28
45
|
```bash
|
|
29
46
|
npx ralph prd-check --dry-run 2>&1
|
|
30
47
|
```
|
|
31
48
|
|
|
32
|
-
|
|
49
|
+
Present any structural issues found.
|
|
50
|
+
|
|
51
|
+
### Step 4: Cross-Reference Against Signs
|
|
52
|
+
|
|
53
|
+
Read `.ralph/prd.json` and for each story, check if any sign applies:
|
|
54
|
+
|
|
55
|
+
- **Backend signs** → check against backend stories
|
|
56
|
+
- **Frontend signs** → check against frontend stories
|
|
57
|
+
- **General signs** → check against all stories
|
|
58
|
+
|
|
59
|
+
For each applicable sign, verify the story's `acceptanceCriteria`, `constraints`,
|
|
60
|
+
`notes`, or `testSteps` reflect the pattern. Flag stories that should account for
|
|
61
|
+
a sign but don't.
|
|
62
|
+
|
|
63
|
+
**Examples:**
|
|
64
|
+
- Sign: "Always use bcrypt cost 10+ for passwords" → Flag auth stories missing
|
|
65
|
+
bcrypt in acceptanceCriteria
|
|
66
|
+
- Sign: "Use date-fns instead of moment.js" → Flag frontend stories that create
|
|
67
|
+
date utilities without this constraint
|
|
68
|
+
- Sign: "Add data-testid for Playwright selectors" → Flag frontend stories missing
|
|
69
|
+
this in constraints
|
|
70
|
+
|
|
71
|
+
### Step 5: Check Against Suggested Learnings
|
|
72
|
+
|
|
73
|
+
Scan `suggested-signs.txt` for patterns relevant to the current PRD's feature area.
|
|
74
|
+
Flag any recurring failure patterns that the PRD's stories don't address.
|
|
75
|
+
|
|
76
|
+
### Step 6: Present Results
|
|
77
|
+
|
|
78
|
+
Summarize all findings in categories:
|
|
33
79
|
|
|
34
|
-
|
|
80
|
+
> **Structural Issues** (from prd-check):
|
|
81
|
+
> - [list]
|
|
82
|
+
>
|
|
83
|
+
> **Sign Conflicts** (stories that don't account for known patterns):
|
|
84
|
+
> - TASK-003: Missing sign "bcrypt cost 10+" in auth story
|
|
85
|
+
> - TASK-005: Missing sign "data-testid attributes" in frontend story
|
|
86
|
+
>
|
|
87
|
+
> **Suggested Improvements** (from past learnings):
|
|
88
|
+
> - [relevant patterns from suggested-signs.txt]
|
|
35
89
|
|
|
36
|
-
|
|
37
|
-
> "Would you like me to fix these issues in the PRD?"
|
|
90
|
+
Ask: "Would you like me to fix these issues in the PRD?"
|
|
38
91
|
|
|
39
92
|
**STOP and wait for user response.**
|
|
40
93
|
|
|
41
|
-
If
|
|
94
|
+
If yes, update `.ralph/prd.json`:
|
|
95
|
+
- Add missing sign patterns to relevant story `constraints` or `acceptanceCriteria`
|
|
96
|
+
- Fix structural issues per PRD best practices
|
|
97
|
+
- Write the fixed file back
|
|
42
98
|
|
|
43
99
|
## Notes
|
|
44
100
|
|
|
45
|
-
- This is the same validation that runs automatically at `ralph run` startup
|
|
101
|
+
- This is the same structural validation that runs automatically at `ralph run` startup
|
|
46
102
|
- `--dry-run` skips auto-fix so you have control over what changes
|
|
47
103
|
- Custom checks in `.ralph/checks/prd/` are also evaluated
|
|
104
|
+
- Signs cross-referencing catches patterns that structural validation can't
|
|
48
105
|
- Run this before `ralph run` to catch and fix issues interactively
|
|
@@ -337,7 +337,7 @@ Quick Reference
|
|
|
337
337
|
───────────────
|
|
338
338
|
|
|
339
339
|
Workflow:
|
|
340
|
-
/
|
|
340
|
+
/prd [feature] Brainstorm → PRD
|
|
341
341
|
npx ralph run Execute autonomously
|
|
342
342
|
npx ralph status Check progress
|
|
343
343
|
npx ralph stop Stop after current story
|
|
@@ -354,4 +354,4 @@ Other:
|
|
|
354
354
|
/vibe-help Full cheatsheet
|
|
355
355
|
```
|
|
356
356
|
|
|
357
|
-
Say: "You're all set! Run `/
|
|
357
|
+
Say: "You're all set! Run `/prd [your next feature]` to get started."
|
|
@@ -11,7 +11,7 @@ Print this cheatsheet for the user. Do not add any commentary or explanation.
|
|
|
11
11
|
## The Loop
|
|
12
12
|
|
|
13
13
|
```
|
|
14
|
-
/
|
|
14
|
+
/prd [feature] brainstorm & generate PRD
|
|
15
15
|
npx ralph run autonomous coding loop (live activity feed)
|
|
16
16
|
npx ralph run --quiet same, but suppress activity feed
|
|
17
17
|
npx ralph status check progress
|
|
@@ -12,8 +12,8 @@ Print this complete reference for the user. Do not add any commentary.
|
|
|
12
12
|
|
|
13
13
|
| Command | Description |
|
|
14
14
|
|---------|-------------|
|
|
15
|
-
| `/
|
|
16
|
-
| `/sign
|
|
15
|
+
| `/prd [feature]` | Brainstorm feature, generate executable PRD for Ralph |
|
|
16
|
+
| `/sign`| Add a learned pattern for Ralph to remember |
|
|
17
17
|
| `/my-dna` | Set up your personal style preferences |
|
|
18
18
|
| `/vibe-check` | Audit code quality before shipping |
|
|
19
19
|
| `/review` | Code review with OWASP security checks |
|
|
@@ -78,7 +78,7 @@ Print this complete reference for the user. Do not add any commentary.
|
|
|
78
78
|
## The Loop
|
|
79
79
|
|
|
80
80
|
```
|
|
81
|
-
/
|
|
81
|
+
/prd [feature] Brainstorm → PRD
|
|
82
82
|
npx ralph run Autonomous coding
|
|
83
83
|
npx ralph status Check progress
|
|
84
84
|
npx ralph stop Stop after current story
|
|
@@ -88,10 +88,10 @@ npx ralph stop Stop after current story
|
|
|
88
88
|
|
|
89
89
|
## Slash Command Details
|
|
90
90
|
|
|
91
|
-
### /
|
|
92
|
-
Brainstorm
|
|
93
|
-
-
|
|
94
|
-
-
|
|
91
|
+
### /prd [feature description]
|
|
92
|
+
Brainstorm feature, explore codebase, ask clarifying questions.
|
|
93
|
+
- Accepts a description, idea file (`docs/ideas/{name}.md`), or plan file (`docs/plans/{name}.md`)
|
|
94
|
+
- Splits into executable PRD stories
|
|
95
95
|
- Writes to `.ralph/prd.json`
|
|
96
96
|
|
|
97
97
|
### /review [file or selection]
|
|
@@ -194,7 +194,7 @@ npx ralph unsign "camelCase"
|
|
|
194
194
|
|
|
195
195
|
CLAUDE.md # Project standards (shared with team)
|
|
196
196
|
PROMPT.md # Base prompt for Ralph sessions
|
|
197
|
-
docs/ideas/ # Brainstorm outputs from /
|
|
197
|
+
docs/ideas/ # Brainstorm outputs from /prd
|
|
198
198
|
|
|
199
199
|
# Global files (your home directory)
|
|
200
200
|
~/.claude/
|
package/README.md
CHANGED
|
@@ -12,31 +12,33 @@ You describe what you want to build. Claude Code writes a PRD (Product Requireme
|
|
|
12
12
|
|
|
13
13
|
```
|
|
14
14
|
┌──────────────────────────────────────────────────────────────────────────────────┐
|
|
15
|
-
│ TERMINAL 1:
|
|
15
|
+
│ TERMINAL 1: Plan & Generate │ TERMINAL 2: Execute │
|
|
16
16
|
├────────────────────────────────────────┼─────────────────────────────────────────┤
|
|
17
17
|
│ │ │
|
|
18
18
|
│ claude --dangerously-skip-permissions │ npx agentic-loop run │
|
|
19
19
|
│ │ │
|
|
20
|
-
│
|
|
21
|
-
│
|
|
22
|
-
│
|
|
23
|
-
│
|
|
24
|
-
│
|
|
25
|
-
│ │
|
|
26
|
-
│
|
|
27
|
-
│
|
|
28
|
-
│
|
|
29
|
-
│
|
|
30
|
-
│
|
|
31
|
-
│
|
|
32
|
-
│
|
|
33
|
-
│
|
|
34
|
-
│
|
|
35
|
-
│
|
|
20
|
+
│ THE PIPELINE │ ┌─ prd-check (once) ───────────────┐ │
|
|
21
|
+
│ 1. Plan mode │ │ Validate all stories upfront │ │
|
|
22
|
+
│ → Think through the feature │ │ Auto-fix missing test steps │ │
|
|
23
|
+
│ → Claude explores codebase │ └──────────────────────────────────┘ │
|
|
24
|
+
│ → Plan saved to docs/plans/ │ ↓ │
|
|
25
|
+
│ │ │
|
|
26
|
+
│ 2. /prd plans/my-feature │ ┌──────────────────────────────────┐ │
|
|
27
|
+
│ → Hardening questions │ │ Read prd.json → get next story │ │
|
|
28
|
+
│ → Generates .ralph/prd.json │ │ Load PROMPT.md, signs, config │ │
|
|
29
|
+
│ │ │ Load last_failure.txt (if retry) │ │
|
|
30
|
+
│ 3. /prd-check │ │ Build prompt with full context │ │
|
|
31
|
+
│ → Validate stories │ │ Spawn Claude → write code │ │
|
|
32
|
+
│ → Cross-ref signs │ │ │ │
|
|
33
|
+
│ → Auto-fix issues │ │ code-check: │ │
|
|
34
|
+
│ │ │ [1] Lint │ │
|
|
35
|
+
│ ENHANCE AS YOU LEARN │ │ [2] Tests │ │
|
|
36
36
|
│ /sign → teach patterns │ │ [3] PRD test steps │ │
|
|
37
|
-
│
|
|
38
|
-
│
|
|
39
|
-
│
|
|
37
|
+
│ /my-dna → your coding style │ │ [4] API smoke │ │
|
|
38
|
+
│ /styleguide → UI consistency │ │ [5] Frontend smoke │ │
|
|
39
|
+
│ /color → terminal tint │ │ │ │
|
|
40
|
+
│ /tab-rename → name your tabs │ │ │ │
|
|
41
|
+
│ config.json → tune your setup │ │ │ │
|
|
40
42
|
│ │ │ Pass → commit, next story │ │
|
|
41
43
|
│ │ │ Fail → save to last_failure.txt, │ │
|
|
42
44
|
│ │ │ retry │ │
|
|
@@ -45,10 +47,10 @@ You describe what you want to build. Claude Code writes a PRD (Product Requireme
|
|
|
45
47
|
└────────────────────────────────────────┴─────────────────────────────────────────┘
|
|
46
48
|
```
|
|
47
49
|
|
|
48
|
-
**Terminal 1** is where you
|
|
49
|
-
**Terminal 2** is where Ralph executes autonomously.
|
|
50
|
+
**Terminal 1** is where you plan and generate. Plan mode lets you think through a feature with Claude before committing to code. `/prd` turns that plan into executable stories. `/prd-check` validates them.
|
|
51
|
+
**Terminal 2** is where Ralph executes autonomously — coding, testing, and committing each story in a loop.
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
The loop gets smarter over time. When Ralph struggles with something, teach it with `/sign`. Tune timeouts and checks in `config.json`. Capture your coding style with `/my-dna`.
|
|
52
54
|
|
|
53
55
|
---
|
|
54
56
|
|
|
@@ -61,22 +63,29 @@ npm install agentic-loop
|
|
|
61
63
|
npx agentic-loop setup
|
|
62
64
|
```
|
|
63
65
|
|
|
64
|
-
**Terminal 1
|
|
66
|
+
**Terminal 1 — Plan and generate with Claude:**
|
|
65
67
|
```bash
|
|
66
68
|
claude --dangerously-skip-permissions
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
|
|
70
|
+
# 1. Use plan mode to think through your feature
|
|
71
|
+
# Claude explores the codebase, you discuss, plan saved to docs/plans/
|
|
72
|
+
|
|
73
|
+
# 2. Turn the plan into executable stories
|
|
74
|
+
/prd plans/my-feature
|
|
75
|
+
|
|
76
|
+
# 3. Validate before running
|
|
77
|
+
/prd-check
|
|
69
78
|
```
|
|
70
79
|
|
|
71
|
-
**Terminal 2
|
|
80
|
+
**Terminal 2 — Run the loop:**
|
|
72
81
|
```bash
|
|
73
|
-
npx agentic-loop run # Execute PRDs autonomously
|
|
82
|
+
npx agentic-loop run # Execute PRDs autonomously (spins up claude -p)
|
|
74
83
|
npx agentic-loop run --quiet # Same, but suppress activity feed
|
|
75
84
|
```
|
|
76
85
|
|
|
77
|
-
Ralph shows a live activity feed as it works — what files it's reading, what code it's writing, and why. Use `--quiet` to suppress it.
|
|
86
|
+
Ralph shows a live activity feed as it works — what files it's reading, what code it's writing, and why. Use `--quiet` to suppress it. On macOS Terminal.app, Ralph tints the terminal background dark teal so you can tell the two terminals apart at a glance — the original color is restored when the loop ends.
|
|
78
87
|
|
|
79
|
-
> **Tip:**
|
|
88
|
+
> **Tip:** Plan first, then generate. Use plan mode to explore and think, `/prd` to create stories, `/prd-check` to validate, and `ralph run` to execute.
|
|
80
89
|
|
|
81
90
|
---
|
|
82
91
|
|
package/package.json
CHANGED
package/ralph/hooks/install.sh
CHANGED
|
@@ -108,70 +108,54 @@ if [[ "$FORCE" != "true" ]] && jq -e '.hooks' "$SETTINGS_FILE" > /dev/null 2>&1;
|
|
|
108
108
|
fi
|
|
109
109
|
fi
|
|
110
110
|
|
|
111
|
-
#
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
"
|
|
115
|
-
{
|
|
116
|
-
"matcher": "Edit|Write",
|
|
117
|
-
"hooks": [
|
|
118
|
-
{
|
|
119
|
-
"type": "command",
|
|
120
|
-
"command": "$SCRIPT_DIR/warn-debug.sh",
|
|
121
|
-
"timeout": 5
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
"type": "command",
|
|
125
|
-
"command": "$SCRIPT_DIR/warn-secrets.sh",
|
|
126
|
-
"timeout": 5
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
"type": "command",
|
|
130
|
-
"command": "$SCRIPT_DIR/warn-urls.sh",
|
|
131
|
-
"timeout": 5
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
"type": "command",
|
|
135
|
-
"command": "$SCRIPT_DIR/warn-empty-catch.sh",
|
|
136
|
-
"timeout": 5
|
|
137
|
-
}
|
|
138
|
-
]
|
|
139
|
-
},
|
|
140
|
-
{
|
|
141
|
-
"matcher": "*",
|
|
142
|
-
"hooks": [
|
|
143
|
-
{
|
|
144
|
-
"type": "command",
|
|
145
|
-
"command": "$SCRIPT_DIR/log-tools.sh",
|
|
146
|
-
"timeout": 3
|
|
147
|
-
}
|
|
148
|
-
]
|
|
149
|
-
}
|
|
150
|
-
],
|
|
151
|
-
"SessionStart": [
|
|
152
|
-
{
|
|
153
|
-
"hooks": [
|
|
154
|
-
{
|
|
155
|
-
"type": "command",
|
|
156
|
-
"command": "$SCRIPT_DIR/inject-context.sh",
|
|
157
|
-
"timeout": 5
|
|
158
|
-
}
|
|
159
|
-
]
|
|
160
|
-
}
|
|
161
|
-
],
|
|
162
|
-
"Stop": [
|
|
163
|
-
{
|
|
164
|
-
"hooks": [
|
|
165
|
-
{
|
|
166
|
-
"type": "command",
|
|
167
|
-
"command": "$SCRIPT_DIR/save-learnings.sh",
|
|
168
|
-
"timeout": 10
|
|
169
|
-
}
|
|
170
|
-
]
|
|
171
|
-
}
|
|
172
|
-
]
|
|
111
|
+
# Wrap hook path with existence check so missing files don't produce errors
|
|
112
|
+
_safe_cmd() {
|
|
113
|
+
local path="$1"
|
|
114
|
+
printf 'if [ -f "%s" ]; then "%s"; else echo '"'"'{"continue": true}'"'"'; fi' "$path" "$path"
|
|
173
115
|
}
|
|
174
|
-
|
|
116
|
+
|
|
117
|
+
# Build hooks config using jq for proper JSON escaping
|
|
118
|
+
HOOKS_CONFIG=$(jq -n \
|
|
119
|
+
--arg warn_debug "$(_safe_cmd "$SCRIPT_DIR/warn-debug.sh")" \
|
|
120
|
+
--arg warn_secrets "$(_safe_cmd "$SCRIPT_DIR/warn-secrets.sh")" \
|
|
121
|
+
--arg warn_urls "$(_safe_cmd "$SCRIPT_DIR/warn-urls.sh")" \
|
|
122
|
+
--arg warn_empty_catch "$(_safe_cmd "$SCRIPT_DIR/warn-empty-catch.sh")" \
|
|
123
|
+
--arg log_tools "$(_safe_cmd "$SCRIPT_DIR/log-tools.sh")" \
|
|
124
|
+
--arg inject_context "$(_safe_cmd "$SCRIPT_DIR/inject-context.sh")" \
|
|
125
|
+
--arg save_learnings "$(_safe_cmd "$SCRIPT_DIR/save-learnings.sh")" \
|
|
126
|
+
'{
|
|
127
|
+
"PostToolUse": [
|
|
128
|
+
{
|
|
129
|
+
"matcher": "Edit|Write",
|
|
130
|
+
"hooks": [
|
|
131
|
+
{"type": "command", "command": $warn_debug, "timeout": 5},
|
|
132
|
+
{"type": "command", "command": $warn_secrets, "timeout": 5},
|
|
133
|
+
{"type": "command", "command": $warn_urls, "timeout": 5},
|
|
134
|
+
{"type": "command", "command": $warn_empty_catch, "timeout": 5}
|
|
135
|
+
]
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"matcher": "*",
|
|
139
|
+
"hooks": [
|
|
140
|
+
{"type": "command", "command": $log_tools, "timeout": 3}
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
],
|
|
144
|
+
"SessionStart": [
|
|
145
|
+
{
|
|
146
|
+
"hooks": [
|
|
147
|
+
{"type": "command", "command": $inject_context, "timeout": 5}
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
],
|
|
151
|
+
"Stop": [
|
|
152
|
+
{
|
|
153
|
+
"hooks": [
|
|
154
|
+
{"type": "command", "command": $save_learnings, "timeout": 10}
|
|
155
|
+
]
|
|
156
|
+
}
|
|
157
|
+
]
|
|
158
|
+
}'
|
|
175
159
|
)
|
|
176
160
|
|
|
177
161
|
# Merge hooks into settings
|
package/ralph/init.sh
CHANGED
|
@@ -13,7 +13,7 @@ ralph_init() {
|
|
|
13
13
|
echo "Initializing ralph..."
|
|
14
14
|
|
|
15
15
|
# Create directory structure
|
|
16
|
-
mkdir -p "$RALPH_DIR/archive" "$RALPH_DIR/screenshots"
|
|
16
|
+
mkdir -p "$RALPH_DIR/archive" "$RALPH_DIR/screenshots" "$RALPH_DIR/hooks"
|
|
17
17
|
|
|
18
18
|
# Detect project type and generate appropriate config
|
|
19
19
|
local project_type
|
|
@@ -68,7 +68,7 @@ ralph_init() {
|
|
|
68
68
|
echo "Next steps:"
|
|
69
69
|
echo " 1. Review .ralph/config.json (test credentials, checks, etc.)"
|
|
70
70
|
echo " 2. Generate PRD:"
|
|
71
|
-
echo " - Thorough: /
|
|
71
|
+
echo " - Thorough: /prd 'feature description' (brainstorm + architecture + scalability)"
|
|
72
72
|
echo " - Quick: ralph prd 'feature description' (basic PRD)"
|
|
73
73
|
echo " 3. Start loop: ralph run"
|
|
74
74
|
}
|
|
@@ -677,7 +677,7 @@ What is this?
|
|
|
677
677
|
commands without asking permission each time. This enables fluid,
|
|
678
678
|
uninterrupted collaboration while you brainstorm and refine ideas.
|
|
679
679
|
|
|
680
|
-
Use /
|
|
680
|
+
Use /prd to brainstorm big features. Claude saves your ideas to
|
|
681
681
|
docs/ideas/, then breaks them into small, executable PRDs.
|
|
682
682
|
|
|
683
683
|
Terminal 2 - Ralph (autonomous execution):
|
|
@@ -690,7 +690,7 @@ What is this?
|
|
|
690
690
|
Quick Start:
|
|
691
691
|
1. npx agentic-loop setup
|
|
692
692
|
2. Terminal 1: claude --dangerously-skip-permissions
|
|
693
|
-
3. In Claude: /
|
|
693
|
+
3. In Claude: /prd "your feature description"
|
|
694
694
|
4. Terminal 2: npx agentic-loop run
|
|
695
695
|
5. Monitor Terminal 2 - it should be autonomous. If issues come up,
|
|
696
696
|
stop the loop (Ctrl+C) and paste the errors into Terminal 1.
|
|
@@ -729,12 +729,12 @@ Commands:
|
|
|
729
729
|
help Show this help message
|
|
730
730
|
|
|
731
731
|
PRD Generation:
|
|
732
|
-
/
|
|
732
|
+
/prd <description> Thorough brainstorm (in Claude Code)
|
|
733
733
|
npx agentic-loop prd <notes> Quick PRD generation
|
|
734
734
|
|
|
735
735
|
Examples:
|
|
736
736
|
npm install agentic-loop && npx agentic-loop setup
|
|
737
|
-
/
|
|
737
|
+
/prd "Add user authentication with OAuth"
|
|
738
738
|
npx agentic-loop prd "Add a contact form"
|
|
739
739
|
npx agentic-loop run
|
|
740
740
|
npx agentic-loop run --max 10
|
package/ralph/loop.sh
CHANGED
|
@@ -2,6 +2,107 @@
|
|
|
2
2
|
# shellcheck shell=bash
|
|
3
3
|
# loop.sh - The autonomous development loop
|
|
4
4
|
|
|
5
|
+
# Check for newer version on npm and offer to update
|
|
6
|
+
check_for_updates() {
|
|
7
|
+
local cache_file="$RALPH_DIR/.update_cache"
|
|
8
|
+
|
|
9
|
+
# Skip if checked recently (once per day)
|
|
10
|
+
if [[ -f "$cache_file" ]]; then
|
|
11
|
+
local cached_time
|
|
12
|
+
read -r cached_time _ < "$cache_file"
|
|
13
|
+
local now
|
|
14
|
+
now=$(date +%s)
|
|
15
|
+
if [[ $(( now - cached_time )) -lt $UPDATE_CHECK_TTL_SECONDS ]]; then
|
|
16
|
+
return 0
|
|
17
|
+
fi
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
local latest
|
|
21
|
+
latest=$(timeout 5 npm view agentic-loop version --json 2>/dev/null | tr -d '"' || echo "")
|
|
22
|
+
# Fall back to gtimeout on macOS if timeout isn't available
|
|
23
|
+
if [[ -z "$latest" ]] && command -v gtimeout &>/dev/null; then
|
|
24
|
+
latest=$(gtimeout 5 npm view agentic-loop version --json 2>/dev/null | tr -d '"' || echo "")
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# Write cache regardless of result (don't retry on failure)
|
|
28
|
+
echo "$(date +%s) $latest" > "$cache_file"
|
|
29
|
+
|
|
30
|
+
# If registry unreachable or empty, skip silently
|
|
31
|
+
[[ -z "$latest" ]] && return 0
|
|
32
|
+
|
|
33
|
+
# Compare versions — if already current or newer, skip
|
|
34
|
+
if [[ "$RALPH_VERSION" == "$latest" ]]; then
|
|
35
|
+
return 0
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# Simple semver comparison: split on dots and compare numerically
|
|
39
|
+
local IFS='.'
|
|
40
|
+
# shellcheck disable=SC2206 # Intentional word-split on IFS='.'
|
|
41
|
+
local -a current_parts=($RALPH_VERSION)
|
|
42
|
+
# shellcheck disable=SC2206
|
|
43
|
+
local -a latest_parts=($latest)
|
|
44
|
+
|
|
45
|
+
local i
|
|
46
|
+
for i in 0 1 2; do
|
|
47
|
+
local c="${current_parts[$i]:-0}"
|
|
48
|
+
local l="${latest_parts[$i]:-0}"
|
|
49
|
+
if [[ "$c" -gt "$l" ]]; then
|
|
50
|
+
return 0 # Current is ahead (dev build)
|
|
51
|
+
elif [[ "$c" -lt "$l" ]]; then
|
|
52
|
+
break # Current is behind — needs update
|
|
53
|
+
fi
|
|
54
|
+
done
|
|
55
|
+
|
|
56
|
+
echo ""
|
|
57
|
+
print_warning "Update available: v$RALPH_VERSION → v$latest"
|
|
58
|
+
|
|
59
|
+
# Detect install method to determine update command
|
|
60
|
+
local update_cmd=""
|
|
61
|
+
local script_path
|
|
62
|
+
script_path="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
63
|
+
|
|
64
|
+
if [[ "$script_path" == *"node_modules/agentic-loop"* ]]; then
|
|
65
|
+
# Local install
|
|
66
|
+
update_cmd="npm update agentic-loop"
|
|
67
|
+
elif npm list -g agentic-loop --depth=0 &>/dev/null 2>&1; then
|
|
68
|
+
# Global install
|
|
69
|
+
update_cmd="npm update -g agentic-loop"
|
|
70
|
+
else
|
|
71
|
+
# npx or unknown — use npx with latest
|
|
72
|
+
update_cmd="npx agentic-loop@latest"
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
read -r -p " Update now and restart? [Y/n] " response
|
|
76
|
+
if [[ "$response" =~ ^[Nn] ]]; then
|
|
77
|
+
echo " Skipping update. Run: $update_cmd"
|
|
78
|
+
echo ""
|
|
79
|
+
return 0
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
echo " Updating..."
|
|
83
|
+
if [[ "$update_cmd" == "npx agentic-loop@latest" ]]; then
|
|
84
|
+
# For npx users, clear the cache so next npx call fetches latest
|
|
85
|
+
local npx_cache
|
|
86
|
+
npx_cache=$(npm config get cache 2>/dev/null || echo "$HOME/.npm")
|
|
87
|
+
rm -rf "${npx_cache}/_npx" 2>/dev/null || true
|
|
88
|
+
print_success " npx cache cleared — restarting with v$latest..."
|
|
89
|
+
echo ""
|
|
90
|
+
exec npx agentic-loop@latest run "$@"
|
|
91
|
+
else
|
|
92
|
+
if $update_cmd 2>&1 | tail -3; then
|
|
93
|
+
print_success " Updated to v$latest — restarting..."
|
|
94
|
+
echo ""
|
|
95
|
+
# Re-exec ralph.sh with "run" + original args
|
|
96
|
+
local ralph_bin
|
|
97
|
+
ralph_bin="$(cd "$(dirname "${BASH_SOURCE[0]}")/../bin" && pwd)/ralph.sh"
|
|
98
|
+
exec "$ralph_bin" run "$@"
|
|
99
|
+
else
|
|
100
|
+
print_warning " Update failed. Run manually: $update_cmd"
|
|
101
|
+
echo ""
|
|
102
|
+
fi
|
|
103
|
+
fi
|
|
104
|
+
}
|
|
105
|
+
|
|
5
106
|
# Pre-loop checks to catch common issues before wasting iterations
|
|
6
107
|
preflight_checks() {
|
|
7
108
|
echo ""
|
|
@@ -621,6 +722,9 @@ _docker_safety_warning() {
|
|
|
621
722
|
}
|
|
622
723
|
|
|
623
724
|
run_loop() {
|
|
725
|
+
# Save original args for update restart
|
|
726
|
+
local _original_args=("$@")
|
|
727
|
+
|
|
624
728
|
# PID of the currently running Claude pipeline (used by trap to kill it)
|
|
625
729
|
_CLAUDE_PIPELINE_PID=""
|
|
626
730
|
|
|
@@ -630,6 +734,8 @@ run_loop() {
|
|
|
630
734
|
# pipeline in a background subshell and `wait`ing for it, which lets the trap
|
|
631
735
|
# fire immediately. The trap kills the subshell, touches .stop, then exits.
|
|
632
736
|
trap '
|
|
737
|
+
restore_tab_title
|
|
738
|
+
restore_terminal_bg
|
|
633
739
|
echo ""
|
|
634
740
|
print_warning "Ctrl+C received — stopping loop..."
|
|
635
741
|
[[ -n "$_CLAUDE_PIPELINE_PID" ]] && kill -TERM "$_CLAUDE_PIPELINE_PID" 2>/dev/null
|
|
@@ -638,6 +744,18 @@ run_loop() {
|
|
|
638
744
|
exit 130
|
|
639
745
|
' INT
|
|
640
746
|
|
|
747
|
+
# Tint terminal background so Ralph's terminal is visually distinct
|
|
748
|
+
local tint_color
|
|
749
|
+
tint_color=$(get_config '.terminalTint' "#1a2e2e")
|
|
750
|
+
if [[ "$tint_color" != "off" ]]; then
|
|
751
|
+
set_terminal_bg "$tint_color"
|
|
752
|
+
fi
|
|
753
|
+
|
|
754
|
+
# Set tab title to project name so the Ralph terminal is identifiable
|
|
755
|
+
local project_name
|
|
756
|
+
project_name=$(basename "$(pwd)")
|
|
757
|
+
set_tab_title "Ralph: $project_name"
|
|
758
|
+
|
|
641
759
|
local max_iterations="" # No cap by default — per-story circuit breaker is the safety net
|
|
642
760
|
local specific_story=""
|
|
643
761
|
local fast_mode=false
|
|
@@ -675,6 +793,9 @@ run_loop() {
|
|
|
675
793
|
# Validate prerequisites
|
|
676
794
|
check_dependencies
|
|
677
795
|
|
|
796
|
+
# Check for newer version on npm (once per day, non-blocking if offline)
|
|
797
|
+
check_for_updates "${_original_args[@]}"
|
|
798
|
+
|
|
678
799
|
# Warn if no Docker compose file (safety net for autonomous execution)
|
|
679
800
|
_docker_safety_warning
|
|
680
801
|
|
|
@@ -720,9 +841,9 @@ run_loop() {
|
|
|
720
841
|
echo ""
|
|
721
842
|
echo " 2. Inside Claude, type:"
|
|
722
843
|
echo ""
|
|
723
|
-
echo " /
|
|
844
|
+
echo " /prd \"your feature description\""
|
|
724
845
|
echo ""
|
|
725
|
-
echo " Note: /
|
|
846
|
+
echo " Note: /prd is a Claude skill — it only works inside an active"
|
|
726
847
|
echo " Claude session, not from your regular terminal."
|
|
727
848
|
echo ""
|
|
728
849
|
echo " See Step 4 of the Getting Started guide:"
|
|
@@ -938,6 +1059,9 @@ run_loop() {
|
|
|
938
1059
|
passed_stories=$(jq '[.stories[] | select(.passes==true)] | length' "$RALPH_DIR/prd.json")
|
|
939
1060
|
current_num=$((passed_stories + 1))
|
|
940
1061
|
|
|
1062
|
+
# Update tab title with current story
|
|
1063
|
+
set_tab_title "Ralph: $story — $story_title"
|
|
1064
|
+
|
|
941
1065
|
# Display dynamic banner (truncate long text to fit box)
|
|
942
1066
|
local max_width=53
|
|
943
1067
|
local display_title="$story_title"
|
|
@@ -1700,6 +1824,6 @@ archive_feature() {
|
|
|
1700
1824
|
echo "All stories passed! PRD kept at: $RALPH_DIR/prd.json"
|
|
1701
1825
|
echo ""
|
|
1702
1826
|
echo "Next:"
|
|
1703
|
-
echo " Start a Claude Code session and run /
|
|
1827
|
+
echo " Start a Claude Code session and run /prd to brainstorm your next feature."
|
|
1704
1828
|
echo " ralph status # See completed stories"
|
|
1705
1829
|
}
|