claude-evolve 1.3.38 → 1.3.40

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.
@@ -0,0 +1,220 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ # Load configuration
6
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7
+ # shellcheck source=../lib/config.sh
8
+ source "$SCRIPT_DIR/../lib/config.sh"
9
+
10
+ # Use CLAUDE_EVOLVE_CONFIG if set, otherwise default
11
+ if [[ -n ${CLAUDE_EVOLVE_CONFIG:-} ]]; then
12
+ load_config "$CLAUDE_EVOLVE_CONFIG"
13
+ else
14
+ load_config
15
+ fi
16
+
17
+ # Validate configuration
18
+ if ! validate_config; then
19
+ echo "[ERROR] Configuration validation failed" >&2
20
+ exit 1
21
+ fi
22
+
23
+ # Function to show help
24
+ show_help() {
25
+ cat <<EOF
26
+ claude-evolve status - Show evolution progress and current leader
27
+
28
+ USAGE:
29
+ claude-evolve status [OPTIONS]
30
+
31
+ OPTIONS:
32
+ --brief Show only summary stats (no per-generation breakdown)
33
+ --winner Show only the current best performer
34
+ --help Show this help message
35
+
36
+ DESCRIPTION:
37
+ Displays evolution progress by generation including:
38
+ - Candidate counts by status (pending, complete, failed, running)
39
+ - Current best performer across all generations
40
+ - Generation-by-generation breakdown
41
+
42
+ EXAMPLES:
43
+ claude-evolve status # Full status report
44
+ claude-evolve status --brief # Just totals and winner
45
+ claude-evolve status --winner # Just the best performer
46
+ EOF
47
+ }
48
+
49
+ # Parse arguments
50
+ SHOW_BRIEF=false
51
+ SHOW_WINNER_ONLY=false
52
+
53
+ while [[ $# -gt 0 ]]; do
54
+ case $1 in
55
+ --brief)
56
+ SHOW_BRIEF=true
57
+ shift
58
+ ;;
59
+ --winner)
60
+ SHOW_WINNER_ONLY=true
61
+ shift
62
+ ;;
63
+ --help)
64
+ show_help
65
+ exit 0
66
+ ;;
67
+ *)
68
+ echo "[ERROR] Unknown option: $1" >&2
69
+ exit 1
70
+ ;;
71
+ esac
72
+ done
73
+
74
+ # Check if CSV exists
75
+ if [[ ! -f "$FULL_CSV_PATH" ]]; then
76
+ echo "[ERROR] Evolution CSV not found: $FULL_CSV_PATH" >&2
77
+ echo "Run 'claude-evolve setup' first or navigate to the correct directory" >&2
78
+ exit 1
79
+ fi
80
+
81
+ # Determine what we're evolving based on paths
82
+ EVOLUTION_CONTEXT=""
83
+ if [[ -n "$EVOLUTION_DIR" ]]; then
84
+ # Get the evolution directory name (e.g., "evolution-atr" -> "ATR")
85
+ EVOLUTION_NAME=$(basename "$EVOLUTION_DIR")
86
+ EVOLUTION_CONTEXT="${EVOLUTION_NAME#evolution-}"
87
+ EVOLUTION_CONTEXT=$(echo "$EVOLUTION_CONTEXT" | tr '[:lower:]' '[:upper:]')
88
+ fi
89
+
90
+ # If we can't determine from evolution dir, try from algorithm path
91
+ if [[ -z "$EVOLUTION_CONTEXT" && -n "$ALGORITHM_PATH" ]]; then
92
+ # Get parent directory name or algorithm file name
93
+ if [[ -f "$FULL_ALGORITHM_PATH" ]]; then
94
+ ALGO_NAME=$(basename "$FULL_ALGORITHM_PATH" .py)
95
+ EVOLUTION_CONTEXT="$ALGO_NAME"
96
+ fi
97
+ fi
98
+
99
+ # Default if we still can't determine
100
+ if [[ -z "$EVOLUTION_CONTEXT" ]]; then
101
+ EVOLUTION_CONTEXT="Algorithm"
102
+ fi
103
+
104
+ # Main status reporting using Python
105
+ "$PYTHON_CMD" -c "
106
+ import csv
107
+ import sys
108
+
109
+ csv_file = '$FULL_CSV_PATH'
110
+ show_brief = '$SHOW_BRIEF' == 'true'
111
+ show_winner_only = '$SHOW_WINNER_ONLY' == 'true'
112
+ evolution_context = '$EVOLUTION_CONTEXT'
113
+
114
+ try:
115
+ with open(csv_file, 'r') as f:
116
+ reader = csv.reader(f)
117
+ rows = list(reader)
118
+
119
+ if len(rows) <= 1:
120
+ print('No evolution candidates found')
121
+ sys.exit(0)
122
+
123
+ header = rows[0]
124
+
125
+ # Collect all candidates with scores and statuses
126
+ all_candidates = []
127
+ stats_by_gen = {}
128
+ total_stats = {'pending': 0, 'complete': 0, 'failed': 0, 'running': 0}
129
+
130
+ for row in rows[1:]:
131
+ if len(row) >= 1 and row[0]: # Must have an ID
132
+ candidate_id = row[0]
133
+
134
+ # Extract generation (e.g., 'gen03' from 'gen03-001')
135
+ if '-' in candidate_id:
136
+ gen = candidate_id.split('-')[0]
137
+
138
+ # Get status and performance
139
+ status = row[4] if len(row) > 4 and row[4] else 'pending'
140
+ performance = row[3] if len(row) > 3 and row[3] else ''
141
+
142
+ # Track by generation
143
+ if gen not in stats_by_gen:
144
+ stats_by_gen[gen] = {'pending': 0, 'complete': 0, 'failed': 0, 'running': 0}
145
+
146
+ if status in stats_by_gen[gen]:
147
+ stats_by_gen[gen][status] += 1
148
+ total_stats[status] += 1
149
+ else:
150
+ stats_by_gen[gen]['pending'] += 1
151
+ total_stats['pending'] += 1
152
+
153
+ # Collect for winner analysis (only completed with valid scores)
154
+ if status == 'complete' and performance:
155
+ try:
156
+ score = float(performance)
157
+ description = row[2] if len(row) > 2 else 'No description'
158
+ all_candidates.append((candidate_id, description, score))
159
+ except ValueError:
160
+ pass
161
+
162
+ # Find the winner
163
+ winner = None
164
+ if all_candidates:
165
+ winner = max(all_candidates, key=lambda x: x[2])
166
+
167
+ # Show winner only
168
+ if show_winner_only:
169
+ if winner:
170
+ print(f'🏆 CURRENT LEADER: {winner[0]} (score: {winner[2]:.4f})')
171
+ print(f' {winner[1]}')
172
+ else:
173
+ print('No completed candidates found')
174
+ sys.exit(0)
175
+
176
+ # Show header
177
+ print(f'🧬 Evolution Status Report - {evolution_context}')
178
+ print('=' * 50)
179
+
180
+ # Show overall stats
181
+ total_candidates = sum(total_stats.values())
182
+ if total_candidates > 0:
183
+ print(f'📊 OVERALL: {total_candidates} total candidates')
184
+ print(f' • {total_stats[\"pending\"]} pending')
185
+ print(f' • {total_stats[\"complete\"]} complete')
186
+ print(f' • {total_stats[\"failed\"]} failed')
187
+ print(f' • {total_stats[\"running\"]} running')
188
+ print()
189
+
190
+ # Show current winner
191
+ if winner:
192
+ print(f'🏆 CURRENT LEADER: {winner[0]} (score: {winner[2]:.4f})')
193
+ print(f' {winner[1]}')
194
+ print()
195
+ else:
196
+ print('🏆 CURRENT LEADER: None (no completed candidates)')
197
+ print()
198
+
199
+ # Show per-generation breakdown (unless brief mode)
200
+ if not show_brief and stats_by_gen:
201
+ print('📈 BY GENERATION:')
202
+ for gen in sorted(stats_by_gen.keys()):
203
+ data = stats_by_gen[gen]
204
+ total = sum(data.values())
205
+
206
+ # Find best performer in this generation
207
+ gen_candidates = [c for c in all_candidates if c[0].startswith(gen + '-')]
208
+ gen_best = max(gen_candidates, key=lambda x: x[2]) if gen_candidates else None
209
+
210
+ status_str = f'{data[\"pending\"]}p {data[\"complete\"]}c {data[\"failed\"]}f {data[\"running\"]}r'
211
+
212
+ if gen_best:
213
+ print(f' {gen}: {total} total ({status_str}) - best: {gen_best[0]} ({gen_best[2]:.4f})')
214
+ else:
215
+ print(f' {gen}: {total} total ({status_str}) - best: none')
216
+
217
+ except Exception as e:
218
+ print(f'Error reading evolution status: {e}')
219
+ sys.exit(1)
220
+ "
@@ -4,6 +4,20 @@
4
4
 
5
5
  set -e
6
6
 
7
+ # Track temp file for cleanup
8
+ temp_file=""
9
+
10
+ # Cleanup function for temp files
11
+ cleanup_temp() {
12
+ if [[ -n "$temp_file" && -f "$temp_file" ]]; then
13
+ rm -f "$temp_file"
14
+ echo "[WORKER-$$] Cleaned up temp file: $temp_file" >&2
15
+ fi
16
+ }
17
+
18
+ # Set trap to clean up temp files on exit
19
+ trap cleanup_temp EXIT INT TERM
20
+
7
21
  # Load configuration
8
22
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9
23
  # shellcheck source=../lib/config.sh
@@ -47,7 +61,7 @@ done
47
61
  if [[ -z $candidate_id ]]; then
48
62
  candidate_id=$(find_next_pending_with_lock)
49
63
  if [[ -z $candidate_id ]]; then
50
- echo "[INFO] No pending candidates found"
64
+ echo "[DEBUG] No pending candidates found" >&2
51
65
  exit 0
52
66
  fi
53
67
  else
@@ -130,27 +144,35 @@ else
130
144
  fi
131
145
  fi
132
146
 
133
- # Generate output file
147
+ # Generate output file path
134
148
  if [[ $id =~ ^[0-9]+$ ]]; then
135
149
  output_file="$FULL_OUTPUT_DIR/evolution_id${id}.py"
136
150
  else
137
151
  output_file="$FULL_OUTPUT_DIR/evolution_${id}.py"
138
152
  fi
139
153
 
154
+ # Use temp file for mutations to avoid partial/failed edits
155
+ temp_file="${output_file}.tmp$$"
156
+
140
157
  # Check if processing should be skipped using common logic
141
158
  eval "$("$PYTHON_CMD" "$SCRIPT_DIR/../lib/evolution_processor.py" "$id" "$based_on_id" "$FULL_OUTPUT_DIR" "$ROOT_DIR" "$parent_file" "$output_file")"
142
159
 
143
- # Handle copy operation
160
+ # Handle copy operation to temp file
144
161
  if [[ "$skip_copy" == "True" ]]; then
145
162
  echo "[WORKER-$$] ⚠️ Skipping copy - $reason"
146
163
  else
147
- cp "$parent_file" "$output_file"
148
- echo "[WORKER-$$] Copied parent to: $output_file"
164
+ cp "$parent_file" "$temp_file"
165
+ echo "[WORKER-$$] Copied parent to temp file: $temp_file"
149
166
  fi
150
167
 
151
168
  # Handle Claude mutation based on skip flags
152
169
  if [[ "$skip_claude" == "True" ]]; then
153
170
  echo "[WORKER-$$] ⚠️ Skipping Claude processing - $reason"
171
+ # If we have a temp file but are skipping Claude, move it to final location
172
+ if [[ -f "$temp_file" ]]; then
173
+ mv "$temp_file" "$output_file"
174
+ echo "[WORKER-$$] Moved temp file to final location (no Claude processing)"
175
+ fi
154
176
  else
155
177
  # Check for claude CLI
156
178
  claude_cmd="${CLAUDE_CMD:-claude}"
@@ -164,7 +186,7 @@ else
164
186
  echo "[WORKER-$$] Using Claude $CLAUDE_MODEL for mutation"
165
187
 
166
188
  # Create mutation prompt
167
- prompt="Edit the file $output_file to implement this specific change: $description
189
+ prompt="Edit the file $temp_file to implement this specific change: $description
168
190
 
169
191
  Requirements:
170
192
  - Edit the file directly (don't just provide comments or suggestions)
@@ -189,9 +211,14 @@ The file currently contains the parent algorithm. Modify it according to the des
189
211
  claude_output=$(echo "$prompt" | "$claude_cmd" --dangerously-skip-permissions --model $CLAUDE_MODEL -p 2>&1 | tee -a "$LOGFILE")
190
212
  claude_exit_code=${PIPESTATUS[1]}
191
213
 
192
- # Check for rate limit
193
- if echo "$claude_output" | grep -q "Claude AI usage limit reached"; then
214
+ # Check for rate limit (multiple possible messages)
215
+ if echo "$claude_output" | grep -q -E "(usage limit|rate limit|limit reached|too many requests)"; then
194
216
  echo "[ERROR] Claude API rate limit reached" >&2
217
+ # Clean up the temp file
218
+ if [[ -f "$temp_file" ]]; then
219
+ rm "$temp_file"
220
+ echo "[WORKER-$$] Cleaned up temp file due to rate limit" >&2
221
+ fi
195
222
  # Reset to pending so it can be retried later
196
223
  update_csv_row_with_lock "$candidate_id" "status" "pending"
197
224
  exit 2 # Special exit code for rate limit
@@ -199,9 +226,42 @@ The file currently contains the parent algorithm. Modify it according to the des
199
226
 
200
227
  if [[ $claude_exit_code -ne 0 ]]; then
201
228
  echo "[ERROR] Claude failed to mutate algorithm" >&2
229
+ # Clean up the temp file
230
+ if [[ -f "$temp_file" ]]; then
231
+ rm "$temp_file"
232
+ echo "[WORKER-$$] Cleaned up temp file due to Claude failure" >&2
233
+ fi
202
234
  update_csv_row_with_lock "$candidate_id" "status" "failed"
203
235
  exit 1
204
236
  fi
237
+
238
+ # Verify that Claude actually modified the file
239
+ if [[ -f "$temp_file" && -f "$parent_file" ]]; then
240
+ if cmp -s "$temp_file" "$parent_file"; then
241
+ echo "" >&2
242
+ echo "🚨🚨🚨 RED ALERT: UNCHANGED ALGORITHM DETECTED 🚨🚨🚨" >&2
243
+ echo "ERROR: Temp file is IDENTICAL to parent algorithm!" >&2
244
+ echo "ERROR: Claude failed to make any changes" >&2
245
+ echo "ERROR: Marking as failed - no evaluation will run" >&2
246
+ echo "🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨" >&2
247
+ echo "" >&2
248
+
249
+ # Clean up temp file and mark as failed
250
+ rm "$temp_file"
251
+ update_csv_row_with_lock "$candidate_id" "status" "failed"
252
+ exit 1
253
+ else
254
+ # Changes were made - move temp file to final location
255
+ mv "$temp_file" "$output_file"
256
+ echo "[WORKER-$$] Changes detected - moved to: $output_file"
257
+ fi
258
+ else
259
+ # If we can't compare, assume it's okay and move the file
260
+ if [[ -f "$temp_file" ]]; then
261
+ mv "$temp_file" "$output_file"
262
+ echo "[WORKER-$$] Moved temp file to: $output_file"
263
+ fi
264
+ fi
205
265
  fi
206
266
 
207
267
  # Run evaluator
@@ -244,7 +304,7 @@ if [[ $eval_exit_code -eq 0 ]]; then
244
304
  # First, check if output is just a plain number
245
305
  if [[ $eval_output =~ ^[[:space:]]*-?[0-9]+\.?[0-9]*[[:space:]]*$ ]]; then
246
306
  score=$(echo "$eval_output" | tr -d ' ')
247
- if (( $(echo "$score == 0" | bc -l) )); then
307
+ if [[ $(echo "$score == 0" | bc -l) == "1" ]]; then
248
308
  update_csv_row_with_lock "$candidate_id" "status" "failed"
249
309
  update_csv_row_with_lock "$candidate_id" "performance" "$score"
250
310
  echo "[WORKER-$$] ✗ Evaluation failed with score 0"
@@ -286,7 +346,7 @@ if [[ $eval_exit_code -eq 0 ]]; then
286
346
  # Fallback: Try simple grep for score/performance fields
287
347
  if score=$(echo "$eval_output" | grep -o '"score"[[:space:]]*:[[:space:]]*[0-9.]*' | cut -d: -f2 | tr -d ' '); then
288
348
  if [[ -n $score ]]; then
289
- if (( $(echo "$score == 0" | bc -l) )); then
349
+ if [[ $(echo "$score == 0" | bc -l) == "1" ]]; then
290
350
  update_csv_row_with_lock "$candidate_id" "status" "failed"
291
351
  update_csv_row_with_lock "$candidate_id" "performance" "$score"
292
352
  echo "[WORKER-$$] ✗ Evaluation failed with score 0"
@@ -303,7 +363,7 @@ if [[ $eval_exit_code -eq 0 ]]; then
303
363
  # Try "performance" field
304
364
  if score=$(echo "$eval_output" | grep -o '"performance"[[:space:]]*:[[:space:]]*[0-9.]*' | cut -d: -f2 | tr -d ' '); then
305
365
  if [[ -n $score ]]; then
306
- if (( $(echo "$score == 0" | bc -l) )); then
366
+ if [[ $(echo "$score == 0" | bc -l) == "1" ]]; then
307
367
  update_csv_row_with_lock "$candidate_id" "status" "failed"
308
368
  update_csv_row_with_lock "$candidate_id" "performance" "$score"
309
369
  echo "[WORKER-$$] ✗ Evaluation failed with score 0"
@@ -319,6 +379,8 @@ if [[ $eval_exit_code -eq 0 ]]; then
319
379
 
320
380
  echo "[ERROR] No score found in evaluator output" >&2
321
381
  echo "[ERROR] Expected: plain number (e.g., 1.23) or JSON with 'score' or 'performance' field" >&2
382
+ echo "[ERROR] Actual evaluator output was:" >&2
383
+ echo "$eval_output" >&2
322
384
  update_csv_row_with_lock "$candidate_id" "status" "failed"
323
385
  exit 1
324
386
  else
package/lib/config.sh CHANGED
@@ -78,7 +78,7 @@ load_config() {
78
78
 
79
79
  # Load config if found
80
80
  if [[ -f "$config_file" ]]; then
81
- echo "[INFO] Loading configuration from: $config_file"
81
+ echo "[DEBUG] Loading configuration from: $config_file" >&2
82
82
  # Simple YAML parsing for key: value pairs and nested structures
83
83
  local in_ideation_section=false
84
84
  local in_parallel_section=false
@@ -143,7 +143,6 @@ load_config() {
143
143
  else
144
144
  # Handle top-level keys
145
145
  case $key in
146
- evolution_dir) EVOLUTION_DIR="$value" ;;
147
146
  algorithm_file) ALGORITHM_FILE="$value" ;;
148
147
  evaluator_file) EVALUATOR_FILE="$value" ;;
149
148
  brief_file) BRIEF_FILE="$value" ;;
@@ -152,6 +151,9 @@ load_config() {
152
151
  parent_selection) PARENT_SELECTION="$value" ;;
153
152
  python_cmd) PYTHON_CMD="$value" ;;
154
153
  auto_ideate) AUTO_IDEATE="$value" ;;
154
+ evolution_dir)
155
+ echo "[WARN] evolution_dir in config is ignored - automatically inferred from config file location" >&2
156
+ ;;
155
157
  esac
156
158
  fi
157
159
  done < "$config_file"
@@ -163,7 +165,7 @@ load_config() {
163
165
  local config_dir=$(dirname "$config_file")
164
166
  if [[ "$config_dir" != "." && "$config_dir" != "" ]]; then
165
167
  EVOLUTION_DIR="$config_dir"
166
- echo "[INFO] Using evolution directory from config path: $EVOLUTION_DIR"
168
+ echo "[DEBUG] Using evolution directory from config path: $EVOLUTION_DIR" >&2
167
169
  fi
168
170
  fi
169
171
 
package/lib/csv-lock.sh CHANGED
@@ -110,7 +110,13 @@ release_csv_lock() {
110
110
  # Usage: read_csv_with_lock <variable_name>
111
111
  read_csv_with_lock() {
112
112
  local var_name="$1"
113
- local csv_file="${EVOLUTION_DIR:-evolution}/evolution.csv"
113
+
114
+ # Ensure we have the full CSV path set
115
+ if [[ -z "$FULL_CSV_PATH" ]]; then
116
+ echo "[ERROR] FULL_CSV_PATH not set in read_csv_with_lock" >&2
117
+ return 1
118
+ fi
119
+ local csv_file="$FULL_CSV_PATH"
114
120
 
115
121
  if ! acquire_csv_lock; then
116
122
  return 1
@@ -130,7 +136,12 @@ read_csv_with_lock() {
130
136
  # Write CSV with lock
131
137
  # Usage: echo "content" | write_csv_with_lock
132
138
  write_csv_with_lock() {
133
- local csv_file="${EVOLUTION_DIR:-evolution}/evolution.csv"
139
+ # Ensure we have the full CSV path set
140
+ if [[ -z "$FULL_CSV_PATH" ]]; then
141
+ echo "[ERROR] FULL_CSV_PATH not set in write_csv_with_lock" >&2
142
+ return 1
143
+ fi
144
+ local csv_file="$FULL_CSV_PATH"
134
145
  local temp_file="${csv_file}.tmp.$$"
135
146
 
136
147
  if ! acquire_csv_lock; then
@@ -153,7 +164,13 @@ update_csv_row_with_lock() {
153
164
  local target_id="$1"
154
165
  local field="$2"
155
166
  local value="$3"
156
- local csv_file="${FULL_CSV_PATH:-${EVOLUTION_DIR:-evolution}/evolution.csv}"
167
+
168
+ # Ensure we have the full CSV path set
169
+ if [[ -z "$FULL_CSV_PATH" ]]; then
170
+ echo "[ERROR] FULL_CSV_PATH not set in update_csv_row_with_lock" >&2
171
+ return 1
172
+ fi
173
+ local csv_file="$FULL_CSV_PATH"
157
174
 
158
175
  if ! acquire_csv_lock; then
159
176
  return 1
@@ -202,7 +219,12 @@ with open('${csv_file}.tmp', 'w', newline='') as f:
202
219
  # Find next pending candidate with lock
203
220
  # Usage: next_pending=$(find_next_pending_with_lock)
204
221
  find_next_pending_with_lock() {
205
- local csv_file="${FULL_CSV_PATH:-${EVOLUTION_DIR:-evolution}/evolution.csv}"
222
+ # Ensure we have the full CSV path set
223
+ if [[ -z "$FULL_CSV_PATH" ]]; then
224
+ echo "[ERROR] FULL_CSV_PATH not set in find_next_pending_with_lock" >&2
225
+ return 1
226
+ fi
227
+ local csv_file="$FULL_CSV_PATH"
206
228
 
207
229
  if ! acquire_csv_lock; then
208
230
  return 1
package/lib/csv_helper.py CHANGED
@@ -91,7 +91,7 @@ def main():
91
91
  performance = data.get('performance') or data.get('score', 0)
92
92
 
93
93
  # Build fields to update
94
- fields = {'performance': performance, 'status': 'complete' if performance > 0 else 'failed'}
94
+ fields = {'performance': performance, 'status': 'complete' if performance != 0 else 'failed'}
95
95
 
96
96
  # Add all other fields from the JSON
97
97
  for key, value in data.items():
package/package.json CHANGED
@@ -1,13 +1,12 @@
1
1
  {
2
2
  "name": "claude-evolve",
3
- "version": "1.3.38",
3
+ "version": "1.3.40",
4
4
  "bin": {
5
5
  "claude-evolve": "./bin/claude-evolve",
6
6
  "claude-evolve-main": "./bin/claude-evolve-main",
7
7
  "claude-evolve-setup": "./bin/claude-evolve-setup",
8
8
  "claude-evolve-ideate": "./bin/claude-evolve-ideate",
9
9
  "claude-evolve-run": "./bin/claude-evolve-run",
10
- "claude-evolve-run-parallel": "./bin/claude-evolve-run-parallel",
11
10
  "claude-evolve-worker": "./bin/claude-evolve-worker",
12
11
  "claude-evolve-analyze": "./bin/claude-evolve-analyze",
13
12
  "claude-evolve-config": "./bin/claude-evolve-config"
@@ -1,19 +1,20 @@
1
1
  # claude-evolve configuration file
2
2
  # This file defines paths and settings for the evolution process
3
+ #
4
+ # NOTE: The evolution directory is automatically inferred from this config file's location.
5
+ # For example, if this file is at /path/to/my-experiment/config.yaml,
6
+ # then the evolution directory will be /path/to/my-experiment/
3
7
 
4
- # Working directory for evolution files
5
- evolution_dir: "evolution"
6
-
7
- # Algorithm and evaluator file paths (relative to evolution_dir)
8
+ # Algorithm and evaluator file paths (relative to evolution directory)
8
9
  algorithm_file: "algorithm.py"
9
10
  evaluator_file: "evaluator.py"
10
11
  brief_file: "BRIEF.md"
11
12
 
12
- # CSV file for tracking evolution (relative to evolution_dir)
13
+ # CSV file for tracking evolution (relative to evolution directory)
13
14
  evolution_csv: "evolution.csv"
14
15
 
15
- # Output directory for generated algorithms (relative to evolution_dir)
16
- # Leave empty to use evolution_dir directly
16
+ # Output directory for generated algorithms (relative to evolution directory)
17
+ # Leave empty to use evolution directory directly
17
18
  output_dir: ""
18
19
 
19
20
  # Parent algorithm selection strategy