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.
@@ -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
@@ -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 " /idea 'your feature' # Generate a PRD"
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. **Idea** - Run `/idea "feature description"` to brainstorm
253
- 2. **Approve** - Review the idea file, then approve
254
- 3. **PRD** - Review generated stories in `.ralph/prd.json`
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
@@ -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`.