agentic-loop 3.23.0 → 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/README.md CHANGED
@@ -12,34 +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: Claude CLI │ TERMINAL 2: Execute │
15
+ │ TERMINAL 1: Plan & Generate │ TERMINAL 2: Execute │
16
16
  ├────────────────────────────────────────┼─────────────────────────────────────────┤
17
17
  │ │ │
18
- │ claude
19
- |(--dangerously-skip-permissions) │ npx agentic-loop run │
18
+ │ claude --dangerously-skip-permissions npx agentic-loop run
20
19
  │ │ │
21
- PLAN FEATURES │ ┌─ prd-check (once) ───────────────┐ │
22
- /idea 'your feature or bugfix' │ │ Validate all stories upfront │ │
23
- Claude asks questions │ │ Auto-fix missing test steps │ │
24
- Explores codebase │ └──────────────────────────────────┘ │
25
- Generates PRD │ ↓ │
26
- | (using claude code plan mode?)
27
- | use /prd filename.md
28
- | on the plan file generated by claude|
29
- ENHANCE AS YOU LEARN ──────────────────────────────────
30
- → Add signs when Ralph repeats │ │ Read prd.json get next story │ │
31
- the same mistake │ │ Load PROMPT.md, signs, config │ │
32
- Tune timeouts, retries, checks │ │ Load last_failure.txt (if retry) │ │
33
- Refine test commands for your │ │ Build prompt with full context │ │
34
- stack │ │ Spawn Claude → write code │ │
35
- │ │ │ │ │
36
- (OPTIONAL) CUSTOMIZE YOUR LOOP │ │ code-check: │ │
37
- │ /my-dna → your coding style │ │ [1] Lint │ │
38
- │ /styleguide → UI consistency │ │ [2] Tests │ │
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 │ │
39
36
  │ /sign → teach patterns │ │ [3] PRD test steps │ │
40
- config.json tune your setup │ │ [4] API smoke │ │
41
- │ │ [5] Frontend smoke │ │
42
- │ │ │ │
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 │ │ │ │
43
42
  │ │ │ Pass → commit, next story │ │
44
43
  │ │ │ Fail → save to last_failure.txt, │ │
45
44
  │ │ │ retry │ │
@@ -48,10 +47,10 @@ You describe what you want to build. Claude Code writes a PRD (Product Requireme
48
47
  └────────────────────────────────────────┴─────────────────────────────────────────┘
49
48
  ```
50
49
 
51
- **Terminal 1** is where you shape *what* gets built and *how* Ralph builds it.
52
- **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.
53
52
 
54
- Your loop gets smarter over time. When Ralph struggles with something, add a sign. When tests flake, tune the config. The customization never really stops—it's how you make Ralph work for *your* project.
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`.
55
54
 
56
55
  ---
57
56
 
@@ -64,26 +63,29 @@ npm install agentic-loop
64
63
  npx agentic-loop setup
65
64
  ```
66
65
 
67
- **Terminal 1 - Claude Code:**
66
+ **Terminal 1 Plan and generate with Claude:**
68
67
  ```bash
69
- claude (optinally you cna use, but you don't need it --dangerously-skip-permissions)
70
- /tour # Guided walkthrough (recommended first time)
71
- /idea 'your feature' # Generate a PRD
68
+ claude --dangerously-skip-permissions
72
69
 
73
- ---
74
- # Already have an idea/plan/PRD file?
75
- /prd #Run the /prd command to turn any file into a prd.json
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
76
78
  ```
77
79
 
78
- **Terminal 2 - Ralph Loop:**
80
+ **Terminal 2 Run the loop:**
79
81
  ```bash
80
- npx agentic-loop run # Execute PRDs autonomously (Spins up claude -p)
82
+ npx agentic-loop run # Execute PRDs autonomously (spins up claude -p)
81
83
  npx agentic-loop run --quiet # Same, but suppress activity feed
82
84
  ```
83
85
 
84
- 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.
85
87
 
86
- > **Tip:** Use two terminals. Plan with Claude in one, run Ralph in the other.
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.
87
89
 
88
90
  ---
89
91
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-loop",
3
- "version": "3.23.0",
3
+ "version": "3.26.0",
4
4
  "description": "Autonomous AI coding loop - PRD-driven development with Claude Code",
5
5
  "author": "Allie Jones <allie@allthrive.ai>",
6
6
  "license": "MIT",
@@ -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
- # Build hooks config with actual path
112
- HOOKS_CONFIG=$(cat <<EOF
113
- {
114
- "PostToolUse": [
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
- EOF
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: /idea 'feature description' (brainstorm + architecture + scalability)"
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 /idea to brainstorm big features. Claude saves your ideas to
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: /idea "your feature description"
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
- /idea <description> Thorough brainstorm (in Claude Code)
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
- /idea "Add user authentication with OAuth"
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 " /idea \"your feature description\""
844
+ echo " /prd \"your feature description\""
724
845
  echo ""
725
- echo " Note: /idea is a Claude skill — it only works inside an active"
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 /idea to brainstorm your next feature."
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
  }
@@ -119,7 +119,7 @@ validate_prd() {
119
119
  print_error "prd.json is not valid JSON."
120
120
  echo ""
121
121
  echo "Fix it manually or regenerate with:"
122
- echo " /idea 'your feature'"
122
+ echo " /prd 'your feature'"
123
123
  echo ""
124
124
  return 1
125
125
  fi
@@ -131,7 +131,7 @@ validate_prd() {
131
131
  print_error "prd.json is missing .feature.name"
132
132
  echo ""
133
133
  echo "Add a feature name to your PRD or regenerate with:"
134
- echo " /idea 'your feature'"
134
+ echo " /prd 'your feature'"
135
135
  echo ""
136
136
  return 1
137
137
  fi
@@ -140,7 +140,7 @@ validate_prd() {
140
140
  if ! jq -e '.stories' "$prd_file" >/dev/null 2>&1; then
141
141
  print_error "prd.json is missing 'stories' array."
142
142
  echo ""
143
- echo "Regenerate with: /idea 'your feature'"
143
+ echo "Regenerate with: /prd 'your feature'"
144
144
  echo ""
145
145
  return 1
146
146
  fi
@@ -151,7 +151,7 @@ validate_prd() {
151
151
  if [[ "$story_count" == "0" ]]; then
152
152
  print_error "prd.json has no stories."
153
153
  echo ""
154
- echo "Regenerate with: /idea 'your feature'"
154
+ echo "Regenerate with: /prd 'your feature'"
155
155
  echo ""
156
156
  return 1
157
157
  fi
@@ -163,7 +163,7 @@ validate_prd() {
163
163
  print_error "Some stories are missing required fields (id, title):"
164
164
  echo "$invalid_stories" | head -5
165
165
  echo ""
166
- echo "Fix the PRD or regenerate with: /idea 'your feature'"
166
+ echo "Fix the PRD or regenerate with: /prd 'your feature'"
167
167
  echo ""
168
168
  return 1
169
169
  fi
package/ralph/prd.sh CHANGED
@@ -118,7 +118,7 @@ ralph_prd() {
118
118
  printf '%s\n' ' "acceptanceCriteria": ["AC 1", "AC 2"],' >> "$prompt_file"
119
119
  printf '%s\n' ' "errorHandling": ["what happens on failure"],' >> "$prompt_file"
120
120
  printf '%s\n' ' "testSteps": ["executable shell commands only"],' >> "$prompt_file"
121
- printf '%s\n' ' "contextFiles": ["docs/ideas/feature.md"],' >> "$prompt_file"
121
+ printf '%s\n' ' "contextFiles": ["docs/ideas/feature.md", "docs/plans/feature-plan.md"],' >> "$prompt_file"
122
122
  printf '%s\n' ' "notes": ""' >> "$prompt_file"
123
123
  printf '%s\n' ' }' >> "$prompt_file"
124
124
  printf '%s\n' ' ]' >> "$prompt_file"
@@ -130,7 +130,7 @@ demo_skills() {
130
130
 
131
131
  echo -e " ${BOLD}In Claude Code, type these commands:${NC}\n"
132
132
 
133
- echo -e " ${CYAN}/idea${NC} Brainstorm → PRD → Ready for Ralph"
133
+ echo -e " ${CYAN}/prd${NC} Brainstorm → PRD → Ready for Ralph"
134
134
  sleep 0.1
135
135
  echo -e " ${CYAN}/vibe-help${NC} Quick reference cheatsheet"
136
136
  sleep 0.1
@@ -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}/idea${NC} Brainstorm → PRD → Ready for Ralph"
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 (/idea → Ralph → Ship)${NC}"
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}/idea, /vibe-help, /tour, /vibe-check, /review, /explain, /styleguide${NC}"
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
@@ -186,7 +186,7 @@ ralph_setup() {
186
186
  echo " --- Terminal 1: Claude Code ---"
187
187
  echo " claude --dangerously-skip-permissions"
188
188
  echo " /tour # Guided walkthrough"
189
- echo " /idea 'your feature' # Generate a PRD"
189
+ echo " /prd 'your feature' # Generate a PRD"
190
190
  echo ""
191
191
  echo " --- Terminal 2: Ralph Loop ---"
192
192
  echo " npx agentic-loop run # Execute PRDs autonomously"
@@ -198,7 +198,7 @@ setup_ralph_dir() {
198
198
  local pkg_root="$1"
199
199
 
200
200
  echo "Creating .ralph/ directory..."
201
- mkdir -p ".ralph/archive" ".ralph/screenshots"
201
+ mkdir -p ".ralph/archive" ".ralph/screenshots" ".ralph/hooks"
202
202
 
203
203
  # Copy config template based on detected project type
204
204
  if [[ ! -f ".ralph/config.json" ]]; then
@@ -402,26 +402,34 @@ setup_claude_hooks() {
402
402
  inject_context=$(_resolve_hook "inject-context.sh")
403
403
  save_learnings=$(_resolve_hook "save-learnings.sh")
404
404
 
405
+ # Wrap hook path with existence check so missing files don't produce errors.
406
+ # If the hook script is deleted after setup (git clean, etc.), this prevents
407
+ # "No such file or directory" errors on every Claude session end.
408
+ _safe_cmd() {
409
+ local path="$1"
410
+ printf 'if [ -f "%s" ]; then "%s"; else echo '"'"'{"continue": true}'"'"'; fi' "$path" "$path"
411
+ }
412
+
405
413
  # Build hooks arrays using jq for proper JSON
406
414
  local post_edit_hooks post_all_hooks session_start_hooks stop_hooks
407
415
 
408
416
  # PostToolUse: warn-* hooks on Edit|Write
409
417
  post_edit_hooks="[]"
410
418
  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}]')
419
+ [[ -n "$hook_path" ]] && post_edit_hooks=$(echo "$post_edit_hooks" | jq --arg cmd "$(_safe_cmd "$hook_path")" '. + [{"type": "command", "command": $cmd, "timeout": 5}]')
412
420
  done
413
421
 
414
422
  # PostToolUse: log-tools on all
415
423
  post_all_hooks="[]"
416
- [[ -n "$log_tools" ]] && post_all_hooks=$(jq -n --arg cmd "$log_tools" '[{"type": "command", "command": $cmd, "timeout": 3}]')
424
+ [[ -n "$log_tools" ]] && post_all_hooks=$(jq -n --arg cmd "$(_safe_cmd "$log_tools")" '[{"type": "command", "command": $cmd, "timeout": 3}]')
417
425
 
418
426
  # SessionStart: inject-context
419
427
  session_start_hooks="[]"
420
- [[ -n "$inject_context" ]] && session_start_hooks=$(jq -n --arg cmd "$inject_context" '[{"type": "command", "command": $cmd, "timeout": 5}]')
428
+ [[ -n "$inject_context" ]] && session_start_hooks=$(jq -n --arg cmd "$(_safe_cmd "$inject_context")" '[{"type": "command", "command": $cmd, "timeout": 5}]')
421
429
 
422
430
  # Stop: save-learnings
423
431
  stop_hooks="[]"
424
- [[ -n "$save_learnings" ]] && stop_hooks=$(jq -n --arg cmd "$save_learnings" '[{"type": "command", "command": $cmd, "timeout": 10}]')
432
+ [[ -n "$save_learnings" ]] && stop_hooks=$(jq -n --arg cmd "$(_safe_cmd "$save_learnings")" '[{"type": "command", "command": $cmd, "timeout": 10}]')
425
433
 
426
434
  # Build the complete hooks config
427
435
  local hooks_config