agentic-loop 3.23.0 → 3.27.1
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 +76 -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/prd/SKILL.md +118 -37
- 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 +40 -38
- package/bin/ralph.sh +6 -0
- package/package.json +1 -1
- package/ralph/hooks/install.sh +47 -63
- package/ralph/init.sh +6 -6
- package/ralph/loop.sh +131 -5
- package/ralph/prd-check.sh +5 -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 +60 -7
- package/ralph/utils.sh +67 -0
- package/templates/examples/CLAUDE-fullstack.md +3 -3
- package/.claude/commands/idea.md +0 -216
- package/.claude/skills/idea/SKILL.md +0 -272
package/ralph/setup/tutorial.sh
CHANGED
|
@@ -83,7 +83,7 @@ lesson_slash_commands() {
|
|
|
83
83
|
echo ""
|
|
84
84
|
echo -e " ${BOLD}Custom commands${NC} (from ${DIM}.claude/skills/${NC}):"
|
|
85
85
|
echo ""
|
|
86
|
-
echo -e " ${CYAN}/
|
|
86
|
+
echo -e " ${CYAN}/prd${NC} Brainstorm → PRD → Ready for Ralph"
|
|
87
87
|
echo -e " ${CYAN}/vibe-check${NC} Code quality audit"
|
|
88
88
|
echo -e " ${CYAN}/review${NC} Code review with security checks"
|
|
89
89
|
echo ""
|
|
@@ -135,7 +135,7 @@ lesson_integration() {
|
|
|
135
135
|
|
|
136
136
|
echo -e " ${BOLD}agentic-loop${NC} adds superpowers to Claude Code:"
|
|
137
137
|
echo ""
|
|
138
|
-
echo -e " ${BOLD}1. The Workflow (/
|
|
138
|
+
echo -e " ${BOLD}1. The Workflow (/prd → Ralph → Ship)${NC}"
|
|
139
139
|
echo -e " ${DIM}Brainstorm ideas, generate PRDs, execute autonomously${NC}"
|
|
140
140
|
echo ""
|
|
141
141
|
echo -e " ${BOLD}2. Code Quality (/vibe-check)${NC}"
|
|
@@ -145,7 +145,7 @@ lesson_integration() {
|
|
|
145
145
|
echo -e " ${DIM}Automatically blocks problematic commits${NC}"
|
|
146
146
|
echo ""
|
|
147
147
|
echo -e " ${BOLD}4. Slash Commands (7 included)${NC}"
|
|
148
|
-
echo -e " ${DIM}/
|
|
148
|
+
echo -e " ${DIM}/prd, /vibe-help, /tour, /vibe-check, /review, /explain, /styleguide${NC}"
|
|
149
149
|
echo ""
|
|
150
150
|
echo -e " ${BOLD}5. MCP Configuration${NC}"
|
|
151
151
|
echo -e " ${DIM}Chrome DevTools for visual verification${NC}"
|
package/ralph/setup.sh
CHANGED
|
@@ -118,6 +118,50 @@ _migrate_credentials_to_env() {
|
|
|
118
118
|
echo ""
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
# Lightweight refresh after auto-update — syncs files from the new package version
|
|
122
|
+
# without re-running interactive or first-time-only setup steps.
|
|
123
|
+
setup_refresh() {
|
|
124
|
+
local pkg_root
|
|
125
|
+
pkg_root="$(cd "$RALPH_LIB/.." && pwd)"
|
|
126
|
+
|
|
127
|
+
echo " Syncing updated files..."
|
|
128
|
+
|
|
129
|
+
# Re-copy slash commands/skills
|
|
130
|
+
setup_slash_commands "$pkg_root"
|
|
131
|
+
|
|
132
|
+
# Re-copy hooks (scripts + settings.json wiring)
|
|
133
|
+
setup_claude_hooks "$pkg_root"
|
|
134
|
+
|
|
135
|
+
# Merge any new default signs
|
|
136
|
+
if [[ -f ".ralph/signs.json" ]] && [[ -f "$pkg_root/templates/signs.json" ]] && command -v jq &>/dev/null; then
|
|
137
|
+
local existing_ids new_signs_added=0
|
|
138
|
+
existing_ids=$(jq -r '.signs[].id // empty' ".ralph/signs.json" 2>/dev/null | tr '\n' '|')
|
|
139
|
+
|
|
140
|
+
while IFS= read -r sign; do
|
|
141
|
+
local sign_id
|
|
142
|
+
sign_id=$(echo "$sign" | jq -r '.id // empty')
|
|
143
|
+
if [[ -n "$sign_id" && ! "$existing_ids" =~ "$sign_id" ]]; then
|
|
144
|
+
local tmp_file
|
|
145
|
+
tmp_file=$(mktemp)
|
|
146
|
+
jq --argjson new_sign "$sign" '.signs += [$new_sign]' ".ralph/signs.json" > "$tmp_file"
|
|
147
|
+
mv "$tmp_file" ".ralph/signs.json"
|
|
148
|
+
((new_signs_added++)) || true
|
|
149
|
+
fi
|
|
150
|
+
done < <(jq -c '.signs[]' "$pkg_root/templates/signs.json" 2>/dev/null)
|
|
151
|
+
|
|
152
|
+
if [[ $new_signs_added -gt 0 ]]; then
|
|
153
|
+
echo " Merged $new_signs_added new sign(s)"
|
|
154
|
+
fi
|
|
155
|
+
fi
|
|
156
|
+
|
|
157
|
+
# Append any new PROMPT.md sections
|
|
158
|
+
if [[ -f "PROMPT.md" ]] && [[ -f "$pkg_root/templates/PROMPT.md" ]]; then
|
|
159
|
+
append_prompt_sections "$pkg_root/templates/PROMPT.md" "PROMPT.md"
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
print_success " Setup refreshed"
|
|
163
|
+
}
|
|
164
|
+
|
|
121
165
|
ralph_setup() {
|
|
122
166
|
echo ""
|
|
123
167
|
echo " _ _ _ _ "
|
|
@@ -186,7 +230,7 @@ ralph_setup() {
|
|
|
186
230
|
echo " --- Terminal 1: Claude Code ---"
|
|
187
231
|
echo " claude --dangerously-skip-permissions"
|
|
188
232
|
echo " /tour # Guided walkthrough"
|
|
189
|
-
echo " /
|
|
233
|
+
echo " /prd 'your feature' # Generate a PRD"
|
|
190
234
|
echo ""
|
|
191
235
|
echo " --- Terminal 2: Ralph Loop ---"
|
|
192
236
|
echo " npx agentic-loop run # Execute PRDs autonomously"
|
|
@@ -198,7 +242,7 @@ setup_ralph_dir() {
|
|
|
198
242
|
local pkg_root="$1"
|
|
199
243
|
|
|
200
244
|
echo "Creating .ralph/ directory..."
|
|
201
|
-
mkdir -p ".ralph/archive" ".ralph/screenshots"
|
|
245
|
+
mkdir -p ".ralph/archive" ".ralph/screenshots" ".ralph/hooks"
|
|
202
246
|
|
|
203
247
|
# Copy config template based on detected project type
|
|
204
248
|
if [[ ! -f ".ralph/config.json" ]]; then
|
|
@@ -252,7 +296,7 @@ setup_ralph_dir() {
|
|
|
252
296
|
tmp_file=$(mktemp)
|
|
253
297
|
jq --argjson new_sign "$sign" '.signs += [$new_sign]' ".ralph/signs.json" > "$tmp_file"
|
|
254
298
|
mv "$tmp_file" ".ralph/signs.json"
|
|
255
|
-
((new_signs_added++))
|
|
299
|
+
((new_signs_added++)) || true
|
|
256
300
|
fi
|
|
257
301
|
done < <(jq -c '.signs[]' "$pkg_root/templates/signs.json" 2>/dev/null)
|
|
258
302
|
|
|
@@ -312,6 +356,7 @@ setup_gitignore() {
|
|
|
312
356
|
".ralph/tool-log.txt"
|
|
313
357
|
".ralph/suggested-signs.txt"
|
|
314
358
|
".ralph/.preflight_cache"
|
|
359
|
+
".ralph/.last_version"
|
|
315
360
|
".ralph/.lock"
|
|
316
361
|
".backups/"
|
|
317
362
|
".claude/settings.json"
|
|
@@ -402,26 +447,34 @@ setup_claude_hooks() {
|
|
|
402
447
|
inject_context=$(_resolve_hook "inject-context.sh")
|
|
403
448
|
save_learnings=$(_resolve_hook "save-learnings.sh")
|
|
404
449
|
|
|
450
|
+
# Wrap hook path with existence check so missing files don't produce errors.
|
|
451
|
+
# If the hook script is deleted after setup (git clean, etc.), this prevents
|
|
452
|
+
# "No such file or directory" errors on every Claude session end.
|
|
453
|
+
_safe_cmd() {
|
|
454
|
+
local path="$1"
|
|
455
|
+
printf 'if [ -f "%s" ]; then "%s"; else echo '"'"'{"continue": true}'"'"'; fi' "$path" "$path"
|
|
456
|
+
}
|
|
457
|
+
|
|
405
458
|
# Build hooks arrays using jq for proper JSON
|
|
406
459
|
local post_edit_hooks post_all_hooks session_start_hooks stop_hooks
|
|
407
460
|
|
|
408
461
|
# PostToolUse: warn-* hooks on Edit|Write
|
|
409
462
|
post_edit_hooks="[]"
|
|
410
463
|
for hook_path in "$warn_debug" "$warn_secrets" "$warn_urls" "$warn_empty_catch"; do
|
|
411
|
-
[[ -n "$hook_path" ]] && post_edit_hooks=$(echo "$post_edit_hooks" | jq --arg cmd "$hook_path" '. + [{"type": "command", "command": $cmd, "timeout": 5}]')
|
|
464
|
+
[[ -n "$hook_path" ]] && post_edit_hooks=$(echo "$post_edit_hooks" | jq --arg cmd "$(_safe_cmd "$hook_path")" '. + [{"type": "command", "command": $cmd, "timeout": 5}]')
|
|
412
465
|
done
|
|
413
466
|
|
|
414
467
|
# PostToolUse: log-tools on all
|
|
415
468
|
post_all_hooks="[]"
|
|
416
|
-
[[ -n "$log_tools" ]] && post_all_hooks=$(jq -n --arg cmd "$log_tools" '[{"type": "command", "command": $cmd, "timeout": 3}]')
|
|
469
|
+
[[ -n "$log_tools" ]] && post_all_hooks=$(jq -n --arg cmd "$(_safe_cmd "$log_tools")" '[{"type": "command", "command": $cmd, "timeout": 3}]')
|
|
417
470
|
|
|
418
471
|
# SessionStart: inject-context
|
|
419
472
|
session_start_hooks="[]"
|
|
420
|
-
[[ -n "$inject_context" ]] && session_start_hooks=$(jq -n --arg cmd "$inject_context" '[{"type": "command", "command": $cmd, "timeout": 5}]')
|
|
473
|
+
[[ -n "$inject_context" ]] && session_start_hooks=$(jq -n --arg cmd "$(_safe_cmd "$inject_context")" '[{"type": "command", "command": $cmd, "timeout": 5}]')
|
|
421
474
|
|
|
422
475
|
# Stop: save-learnings
|
|
423
476
|
stop_hooks="[]"
|
|
424
|
-
[[ -n "$save_learnings" ]] && stop_hooks=$(jq -n --arg cmd "$save_learnings" '[{"type": "command", "command": $cmd, "timeout": 10}]')
|
|
477
|
+
[[ -n "$save_learnings" ]] && stop_hooks=$(jq -n --arg cmd "$(_safe_cmd "$save_learnings")" '[{"type": "command", "command": $cmd, "timeout": 10}]')
|
|
425
478
|
|
|
426
479
|
# Build the complete hooks config
|
|
427
480
|
local hooks_config
|
package/ralph/utils.sh
CHANGED
|
@@ -34,6 +34,7 @@ readonly BROWSER_PAGE_TIMEOUT_MS=30000
|
|
|
34
34
|
readonly CURL_TIMEOUT_SECONDS=10
|
|
35
35
|
readonly SIGN_EXTRACTION_TIMEOUT_SECONDS=30
|
|
36
36
|
readonly PREFLIGHT_CACHE_TTL_SECONDS=600
|
|
37
|
+
readonly UPDATE_CHECK_TTL_SECONDS=86400 # Check for updates once per day
|
|
37
38
|
|
|
38
39
|
# Common project directories (avoid duplication across files)
|
|
39
40
|
readonly FRONTEND_DIRS=("apps/web" "frontend" "client" "web")
|
|
@@ -49,6 +50,70 @@ YELLOW='\033[1;33m'
|
|
|
49
50
|
BLUE='\033[0;34m'
|
|
50
51
|
NC='\033[0m' # No Color
|
|
51
52
|
|
|
53
|
+
# Terminal background theming for Ralph
|
|
54
|
+
# Saves original background color and applies a teal tint to visually
|
|
55
|
+
# distinguish the Ralph terminal from Claude Code.
|
|
56
|
+
# Only works in macOS Terminal.app — no-op on Linux, iTerm2, VS Code, etc.
|
|
57
|
+
# Note: AppleScript targets "front window" (focused window) not the specific
|
|
58
|
+
# window running the script. In practice this works because the user just
|
|
59
|
+
# ran the command, but rapid window switching can cause a mismatch.
|
|
60
|
+
_ORIGINAL_TERMINAL_BG=""
|
|
61
|
+
_ORIGINAL_TERMINAL_FG=""
|
|
62
|
+
|
|
63
|
+
set_terminal_bg() {
|
|
64
|
+
local hex="${1:-#1a2e2e}" # Default: subtle dark teal
|
|
65
|
+
|
|
66
|
+
# Only works in Terminal.app
|
|
67
|
+
[[ "$TERM_PROGRAM" != "Apple_Terminal" ]] && return 0
|
|
68
|
+
|
|
69
|
+
# Save current background and text colors for restore
|
|
70
|
+
_ORIGINAL_TERMINAL_BG=$(osascript -e 'tell application "Terminal" to get background color of front window' 2>/dev/null) || return 0
|
|
71
|
+
_ORIGINAL_TERMINAL_FG=$(osascript -e 'tell application "Terminal" to get normal text color of front window' 2>/dev/null) || true
|
|
72
|
+
|
|
73
|
+
# Parse hex to 16-bit RGB values (Terminal.app uses 0-65535 range)
|
|
74
|
+
local r=$((16#${hex:1:2} * 257))
|
|
75
|
+
local g=$((16#${hex:3:2} * 257))
|
|
76
|
+
local b=$((16#${hex:5:2} * 257))
|
|
77
|
+
|
|
78
|
+
osascript -e "tell application \"Terminal\" to set background color of front window to {$r, $g, $b}" 2>/dev/null || true
|
|
79
|
+
|
|
80
|
+
# If the background is dark, ensure text is light enough to read
|
|
81
|
+
# Calculate perceived brightness: (R*299 + G*587 + B*114) / 1000 (8-bit scale)
|
|
82
|
+
local r8=$((16#${hex:1:2}))
|
|
83
|
+
local g8=$((16#${hex:3:2}))
|
|
84
|
+
local b8=$((16#${hex:5:2}))
|
|
85
|
+
local brightness=$(( (r8 * 299 + g8 * 587 + b8 * 114) / 1000 ))
|
|
86
|
+
|
|
87
|
+
if [[ $brightness -lt 128 ]]; then
|
|
88
|
+
# Dark background — set light text (soft white: #e0e0e0)
|
|
89
|
+
osascript -e 'tell application "Terminal" to set normal text color of front window to {57568, 57568, 57568}' 2>/dev/null || true
|
|
90
|
+
fi
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
restore_terminal_bg() {
|
|
94
|
+
[[ -z "$_ORIGINAL_TERMINAL_BG" ]] && return 0
|
|
95
|
+
[[ "$TERM_PROGRAM" != "Apple_Terminal" ]] && return 0
|
|
96
|
+
|
|
97
|
+
osascript -e "tell application \"Terminal\" to set background color of front window to {$_ORIGINAL_TERMINAL_BG}" 2>/dev/null || true
|
|
98
|
+
_ORIGINAL_TERMINAL_BG=""
|
|
99
|
+
|
|
100
|
+
if [[ -n "$_ORIGINAL_TERMINAL_FG" ]]; then
|
|
101
|
+
osascript -e "tell application \"Terminal\" to set normal text color of front window to {$_ORIGINAL_TERMINAL_FG}" 2>/dev/null || true
|
|
102
|
+
_ORIGINAL_TERMINAL_FG=""
|
|
103
|
+
fi
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
# Set terminal tab title (works in Terminal.app, iTerm2, and most xterm-compatible terminals)
|
|
107
|
+
set_tab_title() {
|
|
108
|
+
local title="$1"
|
|
109
|
+
printf '\033]0;%s\007' "$title" >&2
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
# Restore tab title to default (empty = terminal decides)
|
|
113
|
+
restore_tab_title() {
|
|
114
|
+
printf '\033]0;\007' >&2
|
|
115
|
+
}
|
|
116
|
+
|
|
52
117
|
# Get existing frontend directories in this project
|
|
53
118
|
get_frontend_dirs() {
|
|
54
119
|
local dirs=()
|
|
@@ -410,6 +475,8 @@ create_temp_file() {
|
|
|
410
475
|
|
|
411
476
|
# Clean up only tracked temp files on exit
|
|
412
477
|
cleanup() {
|
|
478
|
+
restore_tab_title
|
|
479
|
+
restore_terminal_bg
|
|
413
480
|
if [[ ${#RALPH_TEMP_FILES[@]} -gt 0 ]]; then
|
|
414
481
|
for f in "${RALPH_TEMP_FILES[@]}"; do
|
|
415
482
|
rm -f "$f" 2>/dev/null
|
|
@@ -249,9 +249,9 @@ make typecheck # Check TypeScript types
|
|
|
249
249
|
|
|
250
250
|
## Workflow
|
|
251
251
|
|
|
252
|
-
1. **
|
|
253
|
-
2. **
|
|
254
|
-
3. **
|
|
252
|
+
1. **PRD** - Run `/prd "feature description"` to generate stories
|
|
253
|
+
2. **Review** - Review generated stories in `.ralph/prd.json`
|
|
254
|
+
3. **Validate** - PRD validation checks story coherence
|
|
255
255
|
4. **Run** - Execute `ralph run` for autonomous coding
|
|
256
256
|
5. **Audit** - Run `/vibe-check` before shipping
|
|
257
257
|
6. **Commit** - Pre-commit hooks catch remaining issues
|
package/.claude/commands/idea.md
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Brainstorm a feature idea, then generate PRDs for Ralph autonomous execution.
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# /idea - From Brainstorm to PRD
|
|
6
|
-
|
|
7
|
-
You are helping the user go from a rough idea to executable PRDs for Ralph.
|
|
8
|
-
|
|
9
|
-
**CRITICAL: This command does NOT write code. It produces documentation files only.**
|
|
10
|
-
|
|
11
|
-
## When to Use
|
|
12
|
-
|
|
13
|
-
| Workflow | Best For |
|
|
14
|
-
|----------|----------|
|
|
15
|
-
| **`/idea`** | Structured brainstorming with guided questions - Claude leads |
|
|
16
|
-
| **Plan mode → save to `docs/ideas/`** | Free-form exploration - you lead the thinking |
|
|
17
|
-
| **`/prd "description"`** | Quick PRD, no docs artifact needed |
|
|
18
|
-
|
|
19
|
-
**Both `/idea` and plan mode can produce `docs/ideas/*.md` files.** The difference is who drives the conversation:
|
|
20
|
-
- `/idea` asks you structured questions (scope, UX, edge cases, etc.)
|
|
21
|
-
- Plan mode lets you explore freely with Claude's help
|
|
22
|
-
|
|
23
|
-
Use `/idea` when you want the structured checklist. Use plan mode when you prefer to think through it your way.
|
|
24
|
-
|
|
25
|
-
## User Input
|
|
26
|
-
|
|
27
|
-
```text
|
|
28
|
-
$ARGUMENTS
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Workflow
|
|
32
|
-
|
|
33
|
-
### Step 1: Start Brainstorming
|
|
34
|
-
|
|
35
|
-
If `$ARGUMENTS` is empty, ask: "What feature or idea would you like to brainstorm?"
|
|
36
|
-
|
|
37
|
-
If `$ARGUMENTS` has content, acknowledge it and proceed.
|
|
38
|
-
|
|
39
|
-
Say: "Let's brainstorm this idea. I'll help you think it through, then we'll create documentation for Ralph to execute."
|
|
40
|
-
|
|
41
|
-
### Step 2: Explore and Ask Questions
|
|
42
|
-
|
|
43
|
-
Help the user flesh out the idea through conversation:
|
|
44
|
-
|
|
45
|
-
1. **Understand the goal** - What problem does this solve? Who benefits?
|
|
46
|
-
2. **Explore the codebase** - Use Glob/Grep/Read to understand what exists and what patterns to follow
|
|
47
|
-
3. **Ask clarifying questions** about:
|
|
48
|
-
|
|
49
|
-
**Scope & UX:**
|
|
50
|
-
- What's in scope vs out of scope?
|
|
51
|
-
- What does the user see/do? (ask for mockup if UI)
|
|
52
|
-
- What are the edge cases?
|
|
53
|
-
|
|
54
|
-
**Security (IMPORTANT - ask if feature involves):**
|
|
55
|
-
- Authentication: Who can access this? Login required?
|
|
56
|
-
- Passwords: How stored? (must be hashed, never plain text)
|
|
57
|
-
- User input: What validation needed? (SQL injection, XSS, command injection)
|
|
58
|
-
- Sensitive data: What should NEVER be in API responses?
|
|
59
|
-
- Rate limiting: Should this be rate limited? (login attempts, API calls)
|
|
60
|
-
|
|
61
|
-
**Scale (IMPORTANT - ask if feature involves lists/data):**
|
|
62
|
-
- How many items expected? (10s, 1000s, millions?)
|
|
63
|
-
- Pagination needed? What's the max per page?
|
|
64
|
-
- Caching needed? How fresh must data be?
|
|
65
|
-
- Database indexes: What will be queried/sorted frequently?
|
|
66
|
-
|
|
67
|
-
### Step 3: Summarize Before Writing
|
|
68
|
-
|
|
69
|
-
When you have enough information, summarize what you've learned:
|
|
70
|
-
|
|
71
|
-
Say: "Here's what I understand about the feature:
|
|
72
|
-
|
|
73
|
-
**Problem:** [summary]
|
|
74
|
-
**Solution:** [summary]
|
|
75
|
-
**Key decisions:** [list]
|
|
76
|
-
|
|
77
|
-
Ready to write this to `docs/ideas/{feature-name}.md`? Say **'yes'** or tell me what to adjust."
|
|
78
|
-
|
|
79
|
-
**STOP and wait for user confirmation before writing any files.**
|
|
80
|
-
|
|
81
|
-
### Step 4: Write the Idea File
|
|
82
|
-
|
|
83
|
-
Once the user confirms, write the idea file:
|
|
84
|
-
|
|
85
|
-
1. Create the directory if needed:
|
|
86
|
-
```bash
|
|
87
|
-
mkdir -p docs/ideas
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
2. Write to `docs/ideas/{feature-name}.md` with this structure:
|
|
91
|
-
```markdown
|
|
92
|
-
# {Feature Name}
|
|
93
|
-
|
|
94
|
-
## Problem
|
|
95
|
-
What problem does this solve?
|
|
96
|
-
|
|
97
|
-
## Solution
|
|
98
|
-
High-level description of the solution.
|
|
99
|
-
|
|
100
|
-
## User Stories
|
|
101
|
-
- As a [user], I want to [action] so that [benefit]
|
|
102
|
-
- ...
|
|
103
|
-
|
|
104
|
-
## Scope
|
|
105
|
-
### In Scope
|
|
106
|
-
- ...
|
|
107
|
-
|
|
108
|
-
### Out of Scope
|
|
109
|
-
- ...
|
|
110
|
-
|
|
111
|
-
## Architecture
|
|
112
|
-
### Directory Structure
|
|
113
|
-
- Where new files should go (be specific: `src/components/forms/`, not just `src/`)
|
|
114
|
-
|
|
115
|
-
### Patterns to Follow
|
|
116
|
-
- Existing components/utilities to reuse
|
|
117
|
-
- Naming conventions
|
|
118
|
-
|
|
119
|
-
### Do NOT Create
|
|
120
|
-
- List things that already exist (avoid duplication)
|
|
121
|
-
|
|
122
|
-
## Security Requirements
|
|
123
|
-
- **Authentication**: Who can access? Login required?
|
|
124
|
-
- **Password handling**: Must be hashed with bcrypt (cost 10+), never in responses
|
|
125
|
-
- **Input validation**: What must be validated/sanitized?
|
|
126
|
-
- **Rate limiting**: What should be rate limited?
|
|
127
|
-
- **Sensitive data**: What must NEVER appear in logs/responses?
|
|
128
|
-
|
|
129
|
-
## Scale Requirements
|
|
130
|
-
- **Expected volume**: How many users/items/requests?
|
|
131
|
-
- **Pagination**: Max items per page (recommend 100)
|
|
132
|
-
- **Caching**: What can be cached? For how long?
|
|
133
|
-
- **Database**: What indexes are needed?
|
|
134
|
-
|
|
135
|
-
## UI Mockup (if applicable)
|
|
136
|
-
```
|
|
137
|
-
┌─────────────────────────────────┐
|
|
138
|
-
│ [ASCII mockup of the UI] │
|
|
139
|
-
└─────────────────────────────────┘
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
## Open Questions
|
|
143
|
-
- Any unresolved decisions
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
3. Say: "I've written the idea to `docs/ideas/{feature-name}.md`.
|
|
147
|
-
|
|
148
|
-
Review it and let me know:
|
|
149
|
-
- **'approved'** - Ready to generate PRD
|
|
150
|
-
- **'edit [changes]'** - Tell me what to change"
|
|
151
|
-
|
|
152
|
-
**STOP and wait for user response. Do not proceed until they say 'approved' or 'done'.**
|
|
153
|
-
|
|
154
|
-
### Step 5: Generate PRD
|
|
155
|
-
|
|
156
|
-
**Only proceed here after user explicitly approves the idea file.**
|
|
157
|
-
|
|
158
|
-
Say: "Now I'll generate the PRD from your idea file."
|
|
159
|
-
|
|
160
|
-
**Use the Skill tool** to invoke `/prd` with the idea file path:
|
|
161
|
-
```
|
|
162
|
-
Skill: prd
|
|
163
|
-
Args: docs/ideas/{feature-name}.md
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
This hands off to `/prd` which handles:
|
|
167
|
-
- Reading the idea file
|
|
168
|
-
- Splitting into stories
|
|
169
|
-
- Writing `.ralph/prd.json`
|
|
170
|
-
- All PRD schema details (testing, testSteps, MCP tools, etc.)
|
|
171
|
-
|
|
172
|
-
**DO NOT duplicate the PRD schema or guidelines here - /prd is the single source of truth.**
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
|
-
## Error Handling
|
|
177
|
-
|
|
178
|
-
- If user provides no arguments, ask what they want to brainstorm
|
|
179
|
-
- If user abandons mid-flow, the idea file is still saved for later
|
|
180
|
-
- If /prd fails, check the idea file has enough detail
|
|
181
|
-
|
|
182
|
-
---
|
|
183
|
-
|
|
184
|
-
## Guidelines
|
|
185
|
-
|
|
186
|
-
### Idea File Quality
|
|
187
|
-
|
|
188
|
-
A good idea file has:
|
|
189
|
-
- **Clear problem statement** - What's broken or missing?
|
|
190
|
-
- **Specific solution** - Not vague ("improve UX") but concrete ("add inline validation")
|
|
191
|
-
- **Scope boundaries** - What's explicitly out of scope?
|
|
192
|
-
- **Architecture hints** - Where do files go? What patterns to follow?
|
|
193
|
-
|
|
194
|
-
### ASCII Art for UI
|
|
195
|
-
|
|
196
|
-
If the feature involves UI, include ASCII mockups in the idea file:
|
|
197
|
-
|
|
198
|
-
```
|
|
199
|
-
┌─────────────────────────────────────┐
|
|
200
|
-
│ Dashboard [⚙️] │
|
|
201
|
-
├─────────────────────────────────────┤
|
|
202
|
-
│ │
|
|
203
|
-
│ ┌─────────┐ ┌─────────┐ │
|
|
204
|
-
│ │ Card 1 │ │ Card 2 │ │
|
|
205
|
-
│ │ $1,234 │ │ 89% │ │
|
|
206
|
-
│ └─────────┘ └─────────┘ │
|
|
207
|
-
│ │
|
|
208
|
-
│ ┌─────────────────────────────┐ │
|
|
209
|
-
│ │ Recent Activity │ │
|
|
210
|
-
│ │ • Item 1 │ │
|
|
211
|
-
│ │ • Item 2 │ │
|
|
212
|
-
│ └─────────────────────────────┘ │
|
|
213
|
-
└─────────────────────────────────────┘
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
Ralph will read these from the idea file via `story.contextFiles`.
|