claude-evolve 1.3.6 → 1.3.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.
@@ -145,49 +145,20 @@ if [[ ! -f "$FULL_ALGORITHM_PATH" ]]; then
145
145
  exit 1
146
146
  fi
147
147
 
148
- # Find oldest pending row (pure shell)
148
+ # Find oldest pending row (using CSV helper)
149
149
  find_empty_row() {
150
- local row_num=2 # Start after header
151
- local csv_id csv_based_on csv_desc csv_perf csv_status
152
- while IFS=, read -r csv_id csv_based_on csv_desc csv_perf csv_status; do
153
- # Look for rows with pending status or empty status (but not complete/failed/running)
154
- if [[ $csv_status == "pending" || (-z $csv_perf && -z $csv_status) ]]; then
155
- echo $row_num
156
- return 0
157
- fi
158
- ((row_num++))
159
- done < <(tail -n +2 "$FULL_CSV_PATH")
160
- return 1
150
+ "$PYTHON_CMD" "$SCRIPT_DIR/../lib/csv_helper.py" find_pending "$FULL_CSV_PATH"
161
151
  }
162
152
 
163
- # Get CSV row (pure shell)
164
- get_csv_row() {
165
- sed -n "${1}p" "$FULL_CSV_PATH"
166
- }
153
+ # Get CSV row - replaced by csv_helper.py
167
154
 
168
- # Update CSV row (pure shell with temp file)
155
+ # Update CSV row (using CSV helper)
169
156
  update_csv_row() {
170
157
  local row_num="$1"
171
158
  local performance="$2"
172
159
  local status="$3"
173
-
174
- # Read CSV and update specific row
175
- local temp_file="${FULL_CSV_PATH}.tmp"
176
- local current_row=1
177
- local csv_id csv_based_on csv_desc csv_perf csv_stat
178
-
179
- while IFS=, read -r csv_id csv_based_on csv_desc csv_perf csv_stat; do
180
- if [[ $current_row -eq $row_num ]]; then
181
- # Update this row
182
- echo "$csv_id,$csv_based_on,$csv_desc,$performance,$status"
183
- else
184
- # Keep original row
185
- echo "$csv_id,$csv_based_on,$csv_desc,$csv_perf,$csv_stat"
186
- fi
187
- ((current_row++))
188
- done <"$FULL_CSV_PATH" >"$temp_file"
189
-
190
- mv "$temp_file" "$FULL_CSV_PATH"
160
+
161
+ "$PYTHON_CMD" "$SCRIPT_DIR/../lib/csv_helper.py" update_row "$FULL_CSV_PATH" "$row_num" "$performance" "$status"
191
162
  }
192
163
 
193
164
  # Auto-recovery mechanism for common failures
@@ -259,46 +230,51 @@ attempt_recovery() {
259
230
  while true; do
260
231
  # Find next candidate
261
232
  if ! row_num=$(find_empty_row); then
262
- echo "[INFO] No more pending candidates found. Generating new ideas..."
233
+ echo "[INFO] No more pending candidates found."
263
234
 
264
- # Check if claude-evolve-ideate exists
265
- ideate_script="$SCRIPT_DIR/claude-evolve-ideate"
266
- if [[ ! -f "$ideate_script" ]]; then
267
- echo "[ERROR] claude-evolve-ideate script not found: $ideate_script" >&2
268
- echo "[INFO] Evolution run complete - no way to generate more ideas."
235
+ # Check if auto ideation is enabled
236
+ if [[ "$AUTO_IDEATE" == "true" || "$AUTO_IDEATE" == "1" ]]; then
237
+ echo "[INFO] Auto ideation is enabled. Generating new ideas..."
238
+
239
+ # Check if claude-evolve-ideate exists
240
+ ideate_script="$SCRIPT_DIR/claude-evolve-ideate"
241
+ if [[ ! -f "$ideate_script" ]]; then
242
+ echo "[ERROR] claude-evolve-ideate script not found: $ideate_script" >&2
243
+ echo "[INFO] Evolution run complete - no way to generate more ideas."
244
+ exit 0
245
+ fi
246
+
247
+ # Generate new ideas using the multi-strategy approach
248
+ echo "[INFO] Calling claude-evolve-ideate to generate new candidates..."
249
+ if ! "$ideate_script"; then
250
+ echo "[ERROR] Failed to generate new ideas" >&2
251
+ echo "[INFO] Evolution run complete - ideation failed."
252
+ exit 1
253
+ fi
254
+
255
+ echo "[INFO] New ideas generated successfully. Continuing evolution..."
256
+ continue # Go back to start of loop to find the new candidates
257
+ else
258
+ echo "[INFO] Auto ideation is disabled. Evolution run complete."
269
259
  exit 0
270
260
  fi
271
-
272
- # Generate new ideas using the multi-strategy approach
273
- echo "[INFO] Calling claude-evolve-ideate to generate new candidates..."
274
- if ! "$ideate_script"; then
275
- echo "[ERROR] Failed to generate new ideas" >&2
276
- echo "[INFO] Evolution run complete - ideation failed."
277
- exit 1
278
- fi
279
-
280
- echo "[INFO] New ideas generated successfully. Continuing evolution..."
281
- continue # Go back to start of loop to find the new candidates
282
261
  fi
283
262
 
284
263
  # Create log file for this iteration
285
264
  LOGFILE="logs/claude-$(date +%Y%m%d_%H%M%S).txt"
286
265
 
287
- # Get row data
288
- row_data=$(get_csv_row "$row_num")
289
- IFS=, read -r id based_on_id description performance status <<<"$row_data"
266
+ # Get row data using CSV helper
267
+ eval "$("$PYTHON_CMD" "$SCRIPT_DIR/../lib/csv_helper.py" get_row "$FULL_CSV_PATH" "$row_num")"
268
+
269
+ # Variables are now set: id, basedOnId, description, performance, status
270
+ based_on_id="$basedOnId" # Convert to expected variable name
290
271
 
291
272
  # Check if ID is empty
292
273
  if [[ -z $id ]]; then
293
274
  echo "[ERROR] Empty ID found at row $row_num. CSV may be malformed." >&2
294
- echo "[ERROR] Row data: $row_data" >&2
295
275
  exit 1
296
276
  fi
297
277
 
298
- # Clean up description (remove quotes)
299
- description=${description#\"}
300
- description=${description%\"}
301
-
302
278
  echo "[INFO] Processing candidate ID: $id"
303
279
  echo "[INFO] Description: $description"
304
280
  echo "[INFO] Based on ID: $based_on_id"
package/lib/config.sh CHANGED
@@ -24,6 +24,9 @@ DEFAULT_PARALLEL_ENABLED=false
24
24
  DEFAULT_MAX_WORKERS=4
25
25
  DEFAULT_LOCK_TIMEOUT=30
26
26
 
27
+ # Default auto ideation value
28
+ DEFAULT_AUTO_IDEATE=true
29
+
27
30
  # Load configuration from config file
28
31
  load_config() {
29
32
  # Accept config file path as parameter
@@ -52,6 +55,9 @@ load_config() {
52
55
  MAX_WORKERS="$DEFAULT_MAX_WORKERS"
53
56
  LOCK_TIMEOUT="$DEFAULT_LOCK_TIMEOUT"
54
57
 
58
+ # Set auto ideation default
59
+ AUTO_IDEATE="$DEFAULT_AUTO_IDEATE"
60
+
55
61
  # Load config if found
56
62
  if [[ -f "$config_file" ]]; then
57
63
  echo "[INFO] Loading configuration from: $config_file"
@@ -127,6 +133,7 @@ load_config() {
127
133
  output_dir) OUTPUT_DIR="$value" ;;
128
134
  parent_selection) PARENT_SELECTION="$value" ;;
129
135
  python_cmd) PYTHON_CMD="$value" ;;
136
+ auto_ideate) AUTO_IDEATE="$value" ;;
130
137
  esac
131
138
  fi
132
139
  done < "$config_file"
@@ -202,4 +209,5 @@ show_config() {
202
209
  echo " Parallel enabled: $PARALLEL_ENABLED"
203
210
  echo " Max workers: $MAX_WORKERS"
204
211
  echo " Lock timeout: $LOCK_TIMEOUT"
212
+ echo " Auto ideate: $AUTO_IDEATE"
205
213
  }
@@ -0,0 +1,116 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ CSV helper for claude-evolve to properly handle CSV parsing with quoted fields.
4
+ """
5
+ import csv
6
+ import sys
7
+ import json
8
+
9
+ def find_pending_row(csv_path):
10
+ """Find the first pending row in the CSV."""
11
+ with open(csv_path, 'r') as f:
12
+ reader = csv.reader(f)
13
+ next(reader) # Skip header
14
+ for row_num, row in enumerate(reader, start=2):
15
+ # Ensure row has at least 5 fields
16
+ while len(row) < 5:
17
+ row.append('')
18
+
19
+ status = row[4].strip()
20
+ # Check if status is pending or empty
21
+ if status == 'pending' or status == '':
22
+ return row_num
23
+ return None
24
+
25
+ def get_row_data(csv_path, row_num):
26
+ """Get data from a specific row."""
27
+ with open(csv_path, 'r') as f:
28
+ reader = csv.reader(f)
29
+ for i, row in enumerate(reader, start=1):
30
+ if i == row_num:
31
+ # Ensure row has at least 5 fields
32
+ while len(row) < 5:
33
+ row.append('')
34
+ return {
35
+ 'id': row[0],
36
+ 'basedOnId': row[1],
37
+ 'description': row[2],
38
+ 'performance': row[3],
39
+ 'status': row[4]
40
+ }
41
+ return None
42
+
43
+ def update_row(csv_path, row_num, performance, status):
44
+ """Update a specific row in the CSV."""
45
+ rows = []
46
+ with open(csv_path, 'r') as f:
47
+ reader = csv.reader(f)
48
+ rows = list(reader)
49
+
50
+ # Update the specific row
51
+ if row_num <= len(rows):
52
+ row = rows[row_num - 1]
53
+ # Ensure row has at least 5 fields
54
+ while len(row) < 5:
55
+ row.append('')
56
+ row[3] = performance # performance field
57
+ row[4] = status # status field
58
+
59
+ # Write back
60
+ with open(csv_path, 'w', newline='') as f:
61
+ writer = csv.writer(f)
62
+ writer.writerows(rows)
63
+
64
+ if __name__ == '__main__':
65
+ if len(sys.argv) < 3:
66
+ print("Usage: csv_helper.py <command> <csv_path> [args...]", file=sys.stderr)
67
+ sys.exit(1)
68
+
69
+ command = sys.argv[1]
70
+ csv_path = sys.argv[2]
71
+
72
+ try:
73
+ if command == 'find_pending':
74
+ row_num = find_pending_row(csv_path)
75
+ if row_num:
76
+ print(row_num)
77
+ sys.exit(0)
78
+ else:
79
+ sys.exit(1)
80
+
81
+ elif command == 'get_row':
82
+ if len(sys.argv) < 4:
83
+ print("Usage: csv_helper.py get_row <csv_path> <row_num>", file=sys.stderr)
84
+ sys.exit(1)
85
+ row_num = int(sys.argv[3])
86
+ data = get_row_data(csv_path, row_num)
87
+ if data:
88
+ # Output as shell variable assignments
89
+ for key, value in data.items():
90
+ # Escape special characters for shell
91
+ value = value.replace('\\', '\\\\')
92
+ value = value.replace('"', '\\"')
93
+ value = value.replace('$', '\\$')
94
+ value = value.replace('`', '\\`')
95
+ print(f'{key}="{value}"')
96
+ sys.exit(0)
97
+ else:
98
+ sys.exit(1)
99
+
100
+ elif command == 'update_row':
101
+ if len(sys.argv) < 6:
102
+ print("Usage: csv_helper.py update_row <csv_path> <row_num> <performance> <status>", file=sys.stderr)
103
+ sys.exit(1)
104
+ row_num = int(sys.argv[3])
105
+ performance = sys.argv[4]
106
+ status = sys.argv[5]
107
+ update_row(csv_path, row_num, performance, status)
108
+ sys.exit(0)
109
+
110
+ else:
111
+ print(f"Unknown command: {command}", file=sys.stderr)
112
+ sys.exit(1)
113
+
114
+ except Exception as e:
115
+ print(f"Error: {e}", file=sys.stderr)
116
+ sys.exit(1)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-evolve",
3
- "version": "1.3.6",
3
+ "version": "1.3.8",
4
4
  "bin": {
5
5
  "claude-evolve": "./bin/claude-evolve",
6
6
  "claude-evolve-main": "./bin/claude-evolve-main",
@@ -37,6 +37,10 @@ ideation_strategies:
37
37
  # Python command to use for evaluation
38
38
  python_cmd: "python3"
39
39
 
40
+ # Auto ideation configuration
41
+ # When true, automatically generate new ideas when no pending candidates remain
42
+ auto_ideate: true
43
+
40
44
  # Parallel execution configuration
41
45
  parallel:
42
46
  # Enable parallel execution of evolution candidates