claude-evolve 1.3.1 → 1.3.3

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.
@@ -29,6 +29,10 @@ while [[ $# -gt 0 ]]; do
29
29
  force_sequential="true"
30
30
  shift
31
31
  ;;
32
+ --keep-awake|--caffeinate)
33
+ use_caffeinate="true"
34
+ shift
35
+ ;;
32
36
  --help)
33
37
  cat <<EOF
34
38
  claude-evolve run - Execute evolution candidates
@@ -40,6 +44,7 @@ OPTIONS:
40
44
  --timeout <sec> Kill evaluator after specified seconds (default: no timeout)
41
45
  --parallel Force parallel execution mode
42
46
  --sequential Force sequential execution mode
47
+ --keep-awake Prevent system sleep during execution (macOS only)
43
48
  --help Show this help message
44
49
 
45
50
  DESCRIPTION:
@@ -59,6 +64,13 @@ EOF
59
64
  esac
60
65
  done
61
66
 
67
+ # Check if caffeinate should be used
68
+ if [[ "$use_caffeinate" == "true" ]] && command -v caffeinate >/dev/null 2>&1; then
69
+ echo "[INFO] Using caffeinate to prevent system sleep"
70
+ # Re-run this script with caffeinate
71
+ exec caffeinate -dims "$0" "$@"
72
+ fi
73
+
62
74
  # Determine execution mode
63
75
  use_parallel=false
64
76
  if [[ "$force_parallel" == "true" ]]; then
@@ -68,8 +68,16 @@ start_worker() {
68
68
  echo "[DISPATCHER] Starting worker..."
69
69
  $worker_cmd &
70
70
  local pid=$!
71
- worker_pids+=($pid)
72
- echo "[DISPATCHER] Worker $pid started"
71
+
72
+ # Verify worker started successfully
73
+ sleep 0.1
74
+ if kill -0 "$pid" 2>/dev/null; then
75
+ worker_pids+=($pid)
76
+ echo "[DISPATCHER] Worker $pid started"
77
+ else
78
+ echo "[ERROR] Worker failed to start" >&2
79
+ ((consecutive_failures++))
80
+ fi
73
81
  }
74
82
 
75
83
  # Check worker exit status and handle accordingly
@@ -144,17 +152,78 @@ shutdown_workers() {
144
152
  exit 0
145
153
  }
146
154
 
147
- trap shutdown_workers INT TERM
155
+ # Better signal handling with logging
156
+ handle_signal() {
157
+ local signal="$1"
158
+ echo "[DISPATCHER] Received signal: $signal" >&2
159
+ echo "[DISPATCHER] Active workers: ${#worker_pids[@]}" >&2
160
+
161
+ # For expensive workers, give option to continue
162
+ if [[ ${#worker_pids[@]} -gt 0 ]]; then
163
+ echo "[DISPATCHER] Warning: ${#worker_pids[@]} expensive workers are still running!" >&2
164
+ echo "[DISPATCHER] Press Ctrl+C again within 5 seconds to force shutdown, or wait..." >&2
165
+
166
+ # Give 5 seconds to reconsider
167
+ local count=5
168
+ while [[ $count -gt 0 ]]; do
169
+ sleep 1
170
+ ((count--))
171
+ # Check if we got another signal
172
+ if [[ -f /tmp/evolve-force-shutdown-$$ ]]; then
173
+ echo "[DISPATCHER] Force shutdown requested" >&2
174
+ rm -f /tmp/evolve-force-shutdown-$$
175
+ shutdown_workers
176
+ exit 1
177
+ fi
178
+ done
179
+
180
+ echo "[DISPATCHER] Continuing with active workers..." >&2
181
+ return
182
+ fi
183
+
184
+ shutdown_workers
185
+ }
186
+
187
+ # Set up signal handlers
188
+ trap 'handle_signal INT' INT
189
+ trap 'handle_signal TERM' TERM
190
+ trap 'echo "[DISPATCHER] Exiting with code $?" >&2' EXIT
191
+
192
+ # Check for stuck "running" candidates from previous runs
193
+ check_stuck_candidates() {
194
+ if read_csv_with_lock csv_content; then
195
+ local stuck_count=$(echo "$csv_content" | awk -F',' 'NR>1 && $5 == "running" { count++ } END { print count+0 }')
196
+ if [[ $stuck_count -gt 0 ]]; then
197
+ echo "[DISPATCHER] Found $stuck_count candidates stuck in 'running' status"
198
+ echo "[DISPATCHER] Resetting them to 'pending' for retry..."
199
+
200
+ # Reset stuck candidates
201
+ if acquire_csv_lock; then
202
+ awk -F',' -v OFS=',' '
203
+ NR==1 { print }
204
+ NR>1 {
205
+ if ($5 == "running") $5 = "pending"
206
+ print
207
+ }
208
+ ' "$FULL_CSV_PATH" > "${FULL_CSV_PATH}.tmp" && mv -f "${FULL_CSV_PATH}.tmp" "$FULL_CSV_PATH"
209
+ release_csv_lock
210
+ fi
211
+ fi
212
+ fi
213
+ }
148
214
 
149
215
  # Main dispatcher loop
150
216
  echo "[DISPATCHER] Starting main dispatch loop"
151
217
 
218
+ # Check for stuck candidates from previous runs
219
+ check_stuck_candidates
220
+
221
+ # Set error handling
222
+ set +e # Don't exit on error in the main loop
223
+
152
224
  while true; do
153
- # Check if too many consecutive failures
154
- if [[ $consecutive_failures -ge $MAX_FAILURES ]]; then
155
- echo "[ERROR] Too many consecutive failures ($consecutive_failures). Stopping." >&2
156
- break
157
- fi
225
+ # In parallel mode, let individual algorithm failures happen
226
+ # The generation is finite, so worst case it just completes with many failures
158
227
 
159
228
  # Check if rate limit was hit
160
229
  if [[ $rate_limit_hit == true ]]; then
@@ -164,7 +233,7 @@ while true; do
164
233
  fi
165
234
 
166
235
  # Count pending work
167
- pending_count=$(count_pending)
236
+ pending_count=$(count_pending || echo "0")
168
237
  active_workers=${#worker_pids[@]}
169
238
 
170
239
  echo "[DISPATCHER] Status: $pending_count pending, $active_workers active workers"
@@ -180,6 +249,7 @@ while true; do
180
249
  if [[ $pending_count -eq 0 && $active_workers -eq 0 ]]; then
181
250
  echo "[DISPATCHER] No pending candidates found. Evolution complete."
182
251
  echo "[DISPATCHER] Run 'claude-evolve ideate' to generate more candidates."
252
+ echo "[DISPATCHER] Exiting main loop: no work remaining" >&2
183
253
  break
184
254
  fi
185
255
 
@@ -210,10 +280,31 @@ while true; do
210
280
  handle_worker_exit "$pid" "$exit_code"
211
281
  fi
212
282
  done
283
+
284
+ # Safety check - if we have workers but the array is corrupted
285
+ if [[ ${#worker_pids[@]} -eq 0 ]] && jobs -r | grep -q .; then
286
+ echo "[DISPATCHER] Warning: Lost track of workers but jobs still running!" >&2
287
+ echo "[DISPATCHER] Attempting to recover..." >&2
288
+
289
+ # Try to recover PIDs from jobs
290
+ while read -r job_info; do
291
+ if [[ $job_info =~ \[([0-9]+)\][[:space:]]+([0-9]+) ]]; then
292
+ local recovered_pid="${BASH_REMATCH[2]}"
293
+ echo "[DISPATCHER] Recovered worker PID: $recovered_pid" >&2
294
+ worker_pids+=($recovered_pid)
295
+ fi
296
+ done < <(jobs -l)
297
+ fi
213
298
  else
214
299
  # No active workers but we might be waiting for ideation or have pending work
215
300
  sleep 1
216
301
  fi
217
302
  done
218
303
 
219
- echo "[DISPATCHER] Evolution run complete"
304
+ echo "[DISPATCHER] Evolution run complete"
305
+
306
+ # Final cleanup check
307
+ if [[ ${#worker_pids[@]} -gt 0 ]]; then
308
+ echo "[DISPATCHER] Warning: ${#worker_pids[@]} workers still active at exit"
309
+ shutdown_workers
310
+ fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-evolve",
3
- "version": "1.3.1",
3
+ "version": "1.3.3",
4
4
  "bin": {
5
5
  "claude-evolve": "./bin/claude-evolve",
6
6
  "claude-evolve-main": "./bin/claude-evolve-main",