claude-self-reflect 7.0.0 → 7.1.8

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.
@@ -93,7 +93,79 @@ find . -type f \( -name "*test_*.py" -o -name "test_*.py" -o -name "*benchmark*.
93
93
  echo "=== Suggest archiving to: tests/throwaway/ ==="
94
94
  ```
95
95
 
96
- ### 8. NPM Package Validation (Regression Check for #71)
96
+ ### 8. Ralph Loop Integration Validation (v7.1+)
97
+
98
+ **What is Ralph Loop?**
99
+ The Ralph Wiggum technique helps Claude maintain focus on long, complex tasks. With CSR integration, Ralph loops gain cross-session memory through hooks.
100
+
101
+ **CRITICAL: Runaway Loop Prevention**
102
+ - ALWAYS use `--max-iterations` (PLURAL!) as safety net
103
+ - `--max-iteration` (singular) is IGNORED - loop runs forever!
104
+ - Setting `active: false` does NOT stop loops - must DELETE file
105
+ - To stop: `rm .claude/ralph-loop.local.md`
106
+
107
+ **v7.1+ Enhanced Features:**
108
+ - **Error Signature Deduplication**: Normalizes errors to avoid storing duplicates
109
+ - **Output Decline Detection**: Circuit breaker pattern (detects >70% output drop)
110
+ - **Confidence-Based Exit**: 0-100 scoring for exit decisions
111
+ - **Anti-Pattern Injection**: "DON'T RETRY THESE" surfaced first
112
+ - **Work Type Tracking**: IMPLEMENTATION/TESTING/DEBUGGING/DOCUMENTATION
113
+ - **Error-Centric Search**: Find past sessions by error pattern, not just task
114
+
115
+ ```bash
116
+ # Check Ralph hooks in settings.json
117
+ echo "=== Ralph Hooks Validation ==="
118
+ grep -c "session_start_hook\|session_end_hook\|precompact" ~/.claude/settings.json && echo "✅ Hooks configured" || echo "❌ Hooks missing"
119
+
120
+ # Verify hook scripts exist
121
+ echo "=== Hook Scripts ==="
122
+ ls -la src/runtime/hooks/session_start_hook.py 2>/dev/null && echo "✅ SessionStart" || echo "❌ SessionStart missing"
123
+ ls -la src/runtime/hooks/session_end_hook.py 2>/dev/null && echo "✅ SessionEnd" || echo "❌ SessionEnd missing"
124
+ ls -la src/runtime/precompact-hook.sh 2>/dev/null && echo "✅ PreCompact" || echo "❌ PreCompact missing"
125
+
126
+ # Test RalphState import (NOT RalphStateParser)
127
+ python3 -c "
128
+ import sys
129
+ sys.path.insert(0, 'src/runtime/hooks')
130
+ from ralph_state import RalphState
131
+ print('✅ RalphState imports')
132
+ " || echo "❌ RalphState import failed"
133
+
134
+ # Check for Ralph-related CLI integration
135
+ grep -l "ralph" installer/setup-wizard-docker.js && echo "✅ CLI integration" || echo "❌ CLI missing Ralph"
136
+
137
+ # Test v7.1+ enhanced features
138
+ echo "=== Testing v7.1+ Enhanced Features ==="
139
+ python3 -c "
140
+ import sys
141
+ sys.path.insert(0, 'src/runtime/hooks')
142
+ from ralph_state import RalphState
143
+
144
+ # Quick feature check
145
+ state = RalphState.create_new('test', 'test')
146
+ state.add_error('Error at line 42')
147
+ state.track_output(1000)
148
+ state.update_confidence({'all_tasks_complete': True})
149
+ state.work_type = 'TESTING'
150
+
151
+ print('✅ Error dedup:', len(state.error_signatures), 'signatures')
152
+ print('✅ Output tracking:', len(state.output_lengths), 'samples')
153
+ print('✅ Confidence:', state.exit_confidence, '%')
154
+ print('✅ Work type:', state.work_type)
155
+ print('✅ All v7.1+ features work')
156
+ "
157
+ ```
158
+
159
+ **Test CSR Search for Ralph Sessions:**
160
+ ```python
161
+ # Search for past Ralph sessions
162
+ results = await csr_reflect_on_past("Ralph loop session", limit=3, min_score=0.3)
163
+
164
+ # Quick check
165
+ quick = await csr_quick_check("Ralph Wiggum")
166
+ ```
167
+
168
+ ### 9. NPM Package Validation (Regression Check for #71)
97
169
  ```bash
98
170
  echo "=== NPM Package Contents Check ==="
99
171
 
@@ -166,6 +238,20 @@ CodeRabbit Analysis: [PASS/FAIL]
166
238
  - PR feedback checked: [✓/✗]
167
239
  - Issues found: [none/list]
168
240
 
241
+ Ralph Loop Integration (v7.1+): [PASS/FAIL]
242
+ - Hooks in settings.json: [✓/✗]
243
+ - SessionStart hook: [✓/✗]
244
+ - SessionEnd hook: [✓/✗]
245
+ - PreCompact hook: [✓/✗]
246
+ - RalphState module: [✓/✗]
247
+ - CLI integration: [✓/✗]
248
+ - CSR search for Ralph: [✓/✗]
249
+ - v7.1+ Enhanced Features:
250
+ - Error signature dedup: [✓/✗]
251
+ - Output decline detection: [✓/✗]
252
+ - Confidence scoring: [✓/✗]
253
+ - Work type tracking: [✓/✗]
254
+
169
255
  Critical Issues: [none/list]
170
256
 
171
257
  CLEANUP NEEDED:
package/.env.example CHANGED
@@ -62,3 +62,18 @@ HOT_CHECK_INTERVAL_S=2 # Check hot files every N seconds
62
62
  NORMAL_CHECK_INTERVAL_S=60 # Normal check interval
63
63
  WARM_WINDOW_HOURS=24 # Files < N hours are warm
64
64
  MAX_COLD_FILES=5 # Max cold files per cycle
65
+
66
+ # ====================================================================================
67
+ # Evaluation System Configuration (OPTIONAL - Session Health Checks)
68
+ # ====================================================================================
69
+ # Automatically runs health checks on session start to verify MCP tools,
70
+ # search quality, and performance are functioning correctly
71
+
72
+ # Enable automatic evaluation at session start
73
+ EVAL_ON_STARTUP=false # Set to true for session-start health checks
74
+
75
+ # Evaluation timeout settings
76
+ EVAL_TIMEOUT_SECONDS=30 # Maximum time for evaluation run
77
+
78
+ # Performance targets
79
+ EVAL_PERFORMANCE_TARGET_MS=500 # Target search latency in milliseconds
package/README.md CHANGED
@@ -41,6 +41,7 @@ Claude starts fresh every conversation. You've solved complex bugs, designed arc
41
41
  - [Real Examples](#real-examples)
42
42
  - [NEW: Real-time Indexing Status](#new-real-time-indexing-status-in-your-terminal)
43
43
  - [Key Features](#key-features)
44
+ - [Ralph Loop Memory Integration](#ralph-loop-memory-integration)
44
45
  - [Code Quality Insights](#code-quality-insights)
45
46
  - [Architecture](#architecture)
46
47
  - [Requirements](#requirements)
@@ -324,6 +325,64 @@ Claude: [Searches across ALL your projects]
324
325
 
325
326
  </details>
326
327
 
328
+ <details>
329
+ <summary><b>Ralph Loop Memory Integration (v7.1+)</b></summary>
330
+
331
+ <div align="center">
332
+ <img src="docs/images/ralph-loop-csr.png" alt="Ralph Loop with CSR Memory - From hamster wheel to upward spiral" width="800"/>
333
+ </div>
334
+
335
+ Use the [ralph-wiggum plugin](https://github.com/anthropics/claude-code-plugins/tree/main/ralph-wiggum) for long tasks? CSR automatically gives Ralph loops **cross-session memory**:
336
+
337
+ **Core Features:**
338
+ - **Automatic backup** before context compaction
339
+ - **Past session retrieval** when starting new Ralph loops
340
+ - **Failed approach tracking** - never repeat the same mistakes
341
+ - **Success pattern learning** - reuse what worked before
342
+
343
+ **v7.1+ Enhanced Features:**
344
+ - **Error Signature Deduplication** - Normalizes errors (removes line numbers, paths, timestamps) to avoid redundant storage
345
+ - **Output Decline Detection** - Circuit breaker pattern that detects >70% drop in output length
346
+ - **Confidence-Based Exit** - 0-100 scoring based on signals (tasks complete, tests passing, no errors)
347
+ - **Anti-Pattern Injection** - "DON'T RETRY THESE" section surfaces failed approaches first
348
+ - **Work Type Tracking** - Categorizes sessions as IMPLEMENTATION/TESTING/DEBUGGING/DOCUMENTATION
349
+ - **Error-Centric Search** - Finds past sessions by error pattern, not just task description
350
+
351
+ **Setup (one-time):**
352
+ ```bash
353
+ ./scripts/ralph/install_hooks.sh # Install CSR hooks
354
+ ./scripts/ralph/install_hooks.sh --check # Verify installation
355
+ ```
356
+
357
+ **How it works:**
358
+ 1. Start a Ralph loop: `/ralph-wiggum:ralph-loop "Build feature X"`
359
+ 2. Work naturally - state is tracked in `.claude/ralph-loop.local.md`
360
+ 3. When compaction occurs, state is backed up to CSR
361
+ 4. New sessions retrieve past learnings from CSR automatically
362
+ 5. Anti-patterns and winning strategies are surfaced first
363
+
364
+ **Files created:**
365
+ - `.ralph_past_sessions.md` - Injected context from past sessions (auto-generated)
366
+
367
+ **Verified proof (2026-01-04):**
368
+ ```
369
+ # Session start hook injects past sessions:
370
+ INFO: Found 2 relevant results:
371
+ - Anti-patterns: 0
372
+ - Winning strategies: 0
373
+ - Similar tasks: 2
374
+
375
+ # Sessions stored in Qdrant:
376
+ {
377
+ "tags": ["ralph_session", "outcome_completed"],
378
+ "timestamp": "2026-01-04T18:13:03.711262+00:00"
379
+ }
380
+ ```
381
+
382
+ [Full documentation →](docs/development/ralph-memory-integration.md)
383
+
384
+ </details>
385
+
327
386
  <details>
328
387
  <summary><b>Memory Decay</b></summary>
329
388
 
@@ -3,14 +3,15 @@ volumes:
3
3
 
4
4
  services:
5
5
  # Fix permissions for config directory (UID 1001 matches appuser in Dockerfiles)
6
+ # Now runs by default since batch services are always-on
6
7
  init-permissions:
7
8
  image: alpine
8
- command: sh -c "chown -R 1001:1001 /config && chown -R 1001:1001 /batch_queue && chown -R 1001:1001 /batch_state"
9
+ command: sh -c "mkdir -p /config /batch_queue /batch_state && chown -R 1001:1001 /config && chown -R 1001:1001 /batch_queue && chown -R 1001:1001 /batch_state"
9
10
  volumes:
10
11
  - ${CONFIG_PATH:-${HOME}/.claude-self-reflect/config}:/config
11
12
  - ${CSR_BATCH_QUEUE_DIR:-${HOME}/.claude-self-reflect/batch_queue}:/batch_queue
12
13
  - ${CSR_BATCH_STATE_DIR:-${HOME}/.claude-self-reflect/batch_state}:/batch_state
13
- profiles: ["watch", "import", "async", "safe-watch", "batch-automation"]
14
+ # No profiles = starts by default (required for batch services)
14
15
 
15
16
  # Qdrant vector database - the heart of semantic search
16
17
  qdrant:
@@ -44,6 +45,7 @@ services:
44
45
  - ${CONFIG_PATH:-${HOME}/.claude-self-reflect/config}:/config
45
46
  environment:
46
47
  - QDRANT_URL=http://qdrant:6333
48
+ - HF_HUB_OFFLINE=1
47
49
  - STATE_FILE=/config/imported-files.json
48
50
  - LOGS_DIR=/logs
49
51
  - OPENAI_API_KEY=${OPENAI_API_KEY:-}
@@ -74,6 +76,7 @@ services:
74
76
  - /tmp:/tmp
75
77
  environment:
76
78
  - QDRANT_URL=http://qdrant:6333
79
+ - HF_HUB_OFFLINE=1
77
80
  - STATE_FILE=/config/imported-files.json
78
81
  - OPENAI_API_KEY=${OPENAI_API_KEY:-}
79
82
  - VOYAGE_API_KEY=${VOYAGE_API_KEY:-}
@@ -103,6 +106,7 @@ services:
103
106
  - ${CONFIG_PATH:-${HOME}/.claude-self-reflect/config}:/config
104
107
  environment:
105
108
  - QDRANT_URL=http://qdrant:6333
109
+ - HF_HUB_OFFLINE=1
106
110
  - STATE_FILE=/config/streaming-state.json # FIXED: Use streaming-specific state file
107
111
  - VOYAGE_API_KEY=${VOYAGE_API_KEY:-}
108
112
  - VOYAGE_KEY=${VOYAGE_KEY:-}
@@ -142,6 +146,7 @@ services:
142
146
  - ${CONFIG_PATH:-${HOME}/.claude-self-reflect/config}:/config
143
147
  environment:
144
148
  - QDRANT_URL=http://qdrant:6333
149
+ - HF_HUB_OFFLINE=1
145
150
  - STATE_FILE=/config/imported-files.json
146
151
  - VOYAGE_API_KEY=${VOYAGE_API_KEY:-}
147
152
  - VOYAGE_KEY=${VOYAGE_KEY:-}
@@ -177,6 +182,7 @@ services:
177
182
  - ${CONFIG_PATH:-${HOME}/.claude-self-reflect/config}:/config
178
183
  environment:
179
184
  - QDRANT_URL=http://qdrant:6333
185
+ - HF_HUB_OFFLINE=1
180
186
  - STATE_FILE=/config/csr-watcher.json
181
187
  - LOGS_DIR=/logs # Fixed: Point to mounted volume
182
188
  - VOYAGE_KEY=${VOYAGE_KEY:-}
@@ -212,6 +218,7 @@ services:
212
218
  - qdrant
213
219
  environment:
214
220
  - QDRANT_URL=http://qdrant:6333
221
+ - HF_HUB_OFFLINE=1
215
222
  - VOYAGE_KEY=${VOYAGE_KEY:-}
216
223
  - PREFER_LOCAL_EMBEDDINGS=${PREFER_LOCAL_EMBEDDINGS:-true}
217
224
  - ENABLE_MEMORY_DECAY=${ENABLE_MEMORY_DECAY:-true}
@@ -224,8 +231,8 @@ services:
224
231
  profiles: ["mcp"]
225
232
 
226
233
  # Batch watcher - Queues conversations and triggers batch narrative generation
227
- # OPTIONAL: Requires ANTHROPIC_API_KEY. Disabled by default.
228
- # Enable via CLI during installation or: docker compose --profile batch-automation up -d
234
+ # Requires ANTHROPIC_API_KEY for AI-powered narratives (9.3x better search quality)
235
+ # Now starts by default if ANTHROPIC_API_KEY is set
229
236
  batch-watcher:
230
237
  build:
231
238
  context: .
@@ -241,6 +248,7 @@ services:
241
248
  - ${CSR_BATCH_STATE_DIR:-${HOME}/.claude-self-reflect/batch_state}:/home/appuser/.claude-self-reflect/batch_state
242
249
  environment:
243
250
  - QDRANT_URL=http://qdrant:6333
251
+ - HF_HUB_OFFLINE=1
244
252
  - QDRANT_API_KEY=${QDRANT_API_KEY:-}
245
253
  - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
246
254
  - CSR_HOME=/home/appuser/.claude-self-reflect
@@ -257,11 +265,11 @@ services:
257
265
  - PYTHONUNBUFFERED=1
258
266
  - PYTHONPATH=/app
259
267
  restart: unless-stopped
260
- profiles: ["batch-automation"]
268
+ # profiles: ["batch-automation"] # REMOVED - now starts by default
261
269
  mem_limit: 2g
262
270
  memswap_limit: 2g
263
271
  healthcheck:
264
- test: ["CMD-SHELL", "ps aux | grep -q '[p]ython.*batch_watcher' || exit 1"]
272
+ test: ["CMD-SHELL", "kill -0 1 2>/dev/null || exit 1"]
265
273
  interval: 30s
266
274
  timeout: 10s
267
275
  retries: 3
@@ -274,7 +282,7 @@ services:
274
282
  labels: "service=batch-watcher"
275
283
 
276
284
  # Batch monitor - Monitors batch API jobs and triggers evaluations
277
- # OPTIONAL: Requires ANTHROPIC_API_KEY. Disabled by default.
285
+ # Requires ANTHROPIC_API_KEY. Now starts by default.
278
286
  batch-monitor:
279
287
  build:
280
288
  context: .
@@ -287,6 +295,7 @@ services:
287
295
  - ${CSR_BATCH_STATE_DIR:-${HOME}/.claude-self-reflect/batch_state}:/home/appuser/.claude-self-reflect/batch_state
288
296
  environment:
289
297
  - QDRANT_URL=http://qdrant:6333
298
+ - HF_HUB_OFFLINE=1
290
299
  - QDRANT_API_KEY=${QDRANT_API_KEY:-}
291
300
  - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
292
301
  - CSR_HOME=/home/appuser/.claude-self-reflect
@@ -295,11 +304,11 @@ services:
295
304
  - PYTHONUNBUFFERED=1
296
305
  - PYTHONPATH=/app
297
306
  restart: unless-stopped
298
- profiles: ["batch-automation"]
307
+ # profiles: ["batch-automation"] # REMOVED - now starts by default
299
308
  mem_limit: 512m
300
309
  memswap_limit: 512m
301
310
  healthcheck:
302
- test: ["CMD-SHELL", "ps aux | grep -q '[p]ython.*batch_monitor' || exit 1"]
311
+ test: ["CMD-SHELL", "kill -0 1 2>/dev/null || exit 1"]
303
312
  interval: 30s
304
313
  timeout: 10s
305
314
  retries: 3
@@ -680,28 +680,106 @@ async function startWatcher() {
680
680
  }
681
681
  }
682
682
 
683
+ async function setupRalphHooks() {
684
+ console.log('\n🐻 Ralph Loop Memory Integration (NEW!)...');
685
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
686
+ console.log('The Ralph Wiggum technique helps Claude maintain context across long sessions.');
687
+ console.log('With CSR integration, Ralph loops gain cross-session memory!');
688
+ console.log('');
689
+ console.log('📊 Benefits:');
690
+ console.log(' • Session state preserved across context compactions');
691
+ console.log(' • Past learnings automatically injected into new sessions');
692
+ console.log(' • Failed approaches remembered to avoid repeating mistakes');
693
+ console.log(' • Works with the ralph-wiggum Claude Code plugin');
694
+ console.log('');
695
+ console.log('📝 How It Works:');
696
+ console.log(' • SessionStart hook: Searches CSR for past Ralph sessions');
697
+ console.log(' • PreCompact hook: Backs up state before context is lost');
698
+ console.log(' • SessionEnd hook: Stores session narrative for future reference');
699
+ console.log('');
700
+ console.log('⚙️ Requirements:');
701
+ console.log(' • ralph-wiggum plugin (Claude Code plugin)');
702
+ console.log(' • Python 3.8+ (for hooks)');
703
+ console.log('');
704
+
705
+ const enableChoice = await question('Enable Ralph Loop memory integration? (y/n) [recommended]: ');
706
+
707
+ if (enableChoice.toLowerCase() === 'y') {
708
+ console.log('\n📦 Installing Ralph hooks...');
709
+
710
+ try {
711
+ // Check if Python 3 is available
712
+ try {
713
+ safeExec('python3', ['--version'], { stdio: 'pipe' });
714
+ } catch {
715
+ console.log('\n⚠️ Python 3 not found');
716
+ console.log(' Ralph hooks require Python 3.8+');
717
+ console.log(' Install Python and run: ./scripts/ralph/install_hooks.sh');
718
+ return;
719
+ }
720
+
721
+ // Run the hook installation script
722
+ const installScript = join(projectRoot, 'scripts', 'ralph', 'install_hooks.sh');
723
+
724
+ // Make sure the script is executable
725
+ try {
726
+ await fs.chmod(installScript, 0o755);
727
+ } catch {
728
+ // Ignore if already executable
729
+ }
730
+
731
+ safeExec('bash', [installScript], {
732
+ cwd: projectRoot,
733
+ stdio: 'inherit'
734
+ });
735
+
736
+ console.log('\n✅ Ralph hooks installed successfully!');
737
+ console.log('');
738
+ console.log('📋 To use Ralph loops with memory:');
739
+ console.log(' 1. Install ralph-wiggum plugin in Claude Code:');
740
+ console.log(' /plugin install ralph-wiggum@anthropics');
741
+ console.log(' 2. Start a loop: /ralph-wiggum:ralph-loop "Your task"');
742
+ console.log(' 3. Session state will be automatically backed up to CSR');
743
+ console.log('');
744
+ console.log('📊 Verify hook installation:');
745
+ console.log(' ./scripts/ralph/install_hooks.sh --check');
746
+
747
+ } catch (error) {
748
+ console.log('\n⚠️ Could not install Ralph hooks automatically');
749
+ console.log(` Error: ${error.message}`);
750
+ console.log(' You can install manually: ./scripts/ralph/install_hooks.sh');
751
+ }
752
+
753
+ } else {
754
+ console.log('\n📝 Skipping Ralph hooks installation.');
755
+ console.log(' You can install later: ./scripts/ralph/install_hooks.sh');
756
+ console.log(' Docs: https://github.com/ramakay/claude-self-reflect/blob/main/docs/development/ralph-memory-integration.md');
757
+ }
758
+ }
759
+
683
760
  async function showFinalInstructions() {
684
761
  console.log('\n✅ Setup complete!');
685
-
762
+
686
763
  console.log('\n🎯 Your Claude Self-Reflect System:');
687
764
  console.log(' • 🌐 Qdrant Dashboard: http://localhost:6333/dashboard/');
688
765
  console.log(' • 📊 Status: All services running');
689
766
  console.log(' • 🔍 Search: Semantic search with memory decay enabled');
690
767
  console.log(' • 🚀 Watcher: HOT/WARM/COLD prioritization active');
691
-
768
+
692
769
  console.log('\n📋 Quick Reference Commands:');
693
770
  console.log(' • Check status: docker compose ps');
694
771
  console.log(' • View logs: docker compose logs -f');
695
772
  console.log(' • Import conversations: docker compose run --rm importer');
696
773
  console.log(' • Enrich metadata: docker compose run --rm importer python /app/scripts/delta-metadata-update-safe.py');
697
774
  console.log(' • Start watcher: docker compose --profile watch up -d');
775
+ console.log(' • Ralph hooks: ./scripts/ralph/install_hooks.sh --check');
698
776
  console.log(' • Stop all: docker compose down');
699
-
777
+
700
778
  console.log('\n🎯 Next Steps:');
701
779
  console.log('1. Restart Claude Code');
702
780
  console.log('2. Look for "claude-self-reflect" in the MCP tools');
703
781
  console.log('3. Try: "Search my past conversations about Python"');
704
-
782
+
705
783
  console.log('\n📚 Documentation: https://github.com/ramakay/claude-self-reflect');
706
784
  }
707
785
 
@@ -787,7 +865,7 @@ async function main() {
787
865
 
788
866
  // Configure Claude
789
867
  await configureClaude();
790
-
868
+
791
869
  // Import conversations
792
870
  await importConversations();
793
871
 
@@ -797,9 +875,12 @@ async function main() {
797
875
  // Setup batch automation (new in v7.0)
798
876
  await setupBatchAutomation();
799
877
 
878
+ // Setup Ralph hooks (new in v7.1 - Memory-Augmented Ralph Loops)
879
+ await setupRalphHooks();
880
+
800
881
  // Start the watcher
801
882
  await startWatcher();
802
-
883
+
803
884
  // Show final instructions
804
885
  await showFinalInstructions();
805
886
 
@@ -94,6 +94,48 @@ class UpdateManager {
94
94
  }
95
95
  }
96
96
 
97
+ async checkRalphHooks() {
98
+ // Check if Ralph hooks are installed in ~/.claude/settings.json
99
+ const claudeSettings = path.join(this.homeDir, '.claude', 'settings.json');
100
+
101
+ try {
102
+ if (!fs.existsSync(claudeSettings)) {
103
+ return {
104
+ installed: false,
105
+ name: 'Ralph Memory Hooks',
106
+ critical: false, // Optional feature
107
+ fix: () => this.installRalphHooks()
108
+ };
109
+ }
110
+
111
+ const settings = JSON.parse(fs.readFileSync(claudeSettings, 'utf8'));
112
+
113
+ // Check for Ralph hooks in SessionStart or SessionEnd
114
+ const hasRalphHooks = settings.hooks &&
115
+ (
116
+ (settings.hooks.SessionStart &&
117
+ JSON.stringify(settings.hooks.SessionStart).includes('ralph')) ||
118
+ (settings.hooks.SessionEnd &&
119
+ JSON.stringify(settings.hooks.SessionEnd).includes('ralph'))
120
+ );
121
+
122
+ return {
123
+ installed: hasRalphHooks,
124
+ name: 'Ralph Memory Hooks',
125
+ critical: false, // Optional feature
126
+ fix: hasRalphHooks ? null : () => this.installRalphHooks()
127
+ };
128
+ } catch (error) {
129
+ return {
130
+ installed: false,
131
+ name: 'Ralph Memory Hooks',
132
+ critical: false,
133
+ fix: () => this.installRalphHooks(),
134
+ error: `Could not check Ralph hooks: ${error.message}`
135
+ };
136
+ }
137
+ }
138
+
97
139
  async checkDocker() {
98
140
  try {
99
141
  execSync('docker info', { stdio: 'ignore' });
@@ -265,6 +307,48 @@ class UpdateManager {
265
307
  }
266
308
  }
267
309
 
310
+ async installRalphHooks() {
311
+ this.log('Installing Ralph Memory Hooks...', 'info');
312
+
313
+ // Check if Python 3 is available
314
+ try {
315
+ execSync('python3 --version', { stdio: 'ignore' });
316
+ } catch {
317
+ this.log('Python 3 is required for Ralph hooks', 'error');
318
+ this.log('Install Python 3.8+ and run: ./scripts/ralph/install_hooks.sh', 'info');
319
+ return false;
320
+ }
321
+
322
+ const installScript = path.join(this.packageRoot, 'scripts', 'ralph', 'install_hooks.sh');
323
+
324
+ if (!fs.existsSync(installScript)) {
325
+ this.log(`Ralph hooks script not found: ${installScript}`, 'error');
326
+ return false;
327
+ }
328
+
329
+ try {
330
+ // Make sure the script is executable
331
+ fs.chmodSync(installScript, 0o755);
332
+
333
+ execSync(`bash "${installScript}"`, {
334
+ cwd: this.packageRoot,
335
+ stdio: 'inherit'
336
+ });
337
+
338
+ this.log('Ralph Memory Hooks installed successfully!', 'success');
339
+ this.log('', 'info');
340
+ this.log('To use Ralph loops with memory:', 'info');
341
+ this.log(' 1. Install plugin: /plugin install ralph-wiggum@anthropics', 'info');
342
+ this.log(' 2. Start a loop: /ralph-wiggum:ralph-loop "Your task"', 'info');
343
+ this.log(' 3. Session state will be automatically backed up to CSR', 'info');
344
+ return true;
345
+ } catch (error) {
346
+ this.log(`Failed to install Ralph hooks: ${error.message}`, 'error');
347
+ this.log('You can install manually: ./scripts/ralph/install_hooks.sh', 'info');
348
+ return false;
349
+ }
350
+ }
351
+
268
352
  async startQdrant() {
269
353
  this.log('Starting Qdrant...', 'info');
270
354
 
@@ -313,7 +397,8 @@ class UpdateManager {
313
397
  { name: 'Docker Config', fn: () => this.checkDockerComposeConfig() },
314
398
  { name: 'cc-statusline', fn: () => this.checkCCStatusline() },
315
399
  { name: 'csr-status', fn: () => this.checkCSRStatusScript() },
316
- { name: 'AST-Grep', fn: () => this.checkASTGrep() }
400
+ { name: 'AST-Grep', fn: () => this.checkASTGrep() },
401
+ { name: 'Ralph Hooks', fn: () => this.checkRalphHooks() }
317
402
  ];
318
403
 
319
404
  const settledResults = await Promise.allSettled(checks.map(c => c.fn()));
@@ -391,6 +476,8 @@ class UpdateManager {
391
476
  recheckResult = await this.checkCSRStatusScript();
392
477
  } else if (recheckName.includes('ast-grep')) {
393
478
  recheckResult = await this.checkASTGrep();
479
+ } else if (recheckName.includes('ralph')) {
480
+ recheckResult = await this.checkRalphHooks();
394
481
  }
395
482
 
396
483
  // Guard against undefined recheckResult (no matching verifier)