claude-evolve 1.3.1 → 1.3.2
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.
- package/bin/claude-evolve-run +12 -0
- package/bin/claude-evolve-run-parallel +99 -5
- package/package.json +1 -1
package/bin/claude-evolve-run
CHANGED
|
@@ -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
|
-
|
|
72
|
-
|
|
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,11 +152,75 @@ shutdown_workers() {
|
|
|
144
152
|
exit 0
|
|
145
153
|
}
|
|
146
154
|
|
|
147
|
-
|
|
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
225
|
# Check if too many consecutive failures
|
|
154
226
|
if [[ $consecutive_failures -ge $MAX_FAILURES ]]; then
|
|
@@ -164,7 +236,7 @@ while true; do
|
|
|
164
236
|
fi
|
|
165
237
|
|
|
166
238
|
# Count pending work
|
|
167
|
-
pending_count=$(count_pending)
|
|
239
|
+
pending_count=$(count_pending || echo "0")
|
|
168
240
|
active_workers=${#worker_pids[@]}
|
|
169
241
|
|
|
170
242
|
echo "[DISPATCHER] Status: $pending_count pending, $active_workers active workers"
|
|
@@ -180,6 +252,7 @@ while true; do
|
|
|
180
252
|
if [[ $pending_count -eq 0 && $active_workers -eq 0 ]]; then
|
|
181
253
|
echo "[DISPATCHER] No pending candidates found. Evolution complete."
|
|
182
254
|
echo "[DISPATCHER] Run 'claude-evolve ideate' to generate more candidates."
|
|
255
|
+
echo "[DISPATCHER] Exiting main loop: no work remaining" >&2
|
|
183
256
|
break
|
|
184
257
|
fi
|
|
185
258
|
|
|
@@ -210,10 +283,31 @@ while true; do
|
|
|
210
283
|
handle_worker_exit "$pid" "$exit_code"
|
|
211
284
|
fi
|
|
212
285
|
done
|
|
286
|
+
|
|
287
|
+
# Safety check - if we have workers but the array is corrupted
|
|
288
|
+
if [[ ${#worker_pids[@]} -eq 0 ]] && jobs -r | grep -q .; then
|
|
289
|
+
echo "[DISPATCHER] Warning: Lost track of workers but jobs still running!" >&2
|
|
290
|
+
echo "[DISPATCHER] Attempting to recover..." >&2
|
|
291
|
+
|
|
292
|
+
# Try to recover PIDs from jobs
|
|
293
|
+
while read -r job_info; do
|
|
294
|
+
if [[ $job_info =~ \[([0-9]+)\][[:space:]]+([0-9]+) ]]; then
|
|
295
|
+
local recovered_pid="${BASH_REMATCH[2]}"
|
|
296
|
+
echo "[DISPATCHER] Recovered worker PID: $recovered_pid" >&2
|
|
297
|
+
worker_pids+=($recovered_pid)
|
|
298
|
+
fi
|
|
299
|
+
done < <(jobs -l)
|
|
300
|
+
fi
|
|
213
301
|
else
|
|
214
302
|
# No active workers but we might be waiting for ideation or have pending work
|
|
215
303
|
sleep 1
|
|
216
304
|
fi
|
|
217
305
|
done
|
|
218
306
|
|
|
219
|
-
echo "[DISPATCHER] Evolution run complete"
|
|
307
|
+
echo "[DISPATCHER] Evolution run complete"
|
|
308
|
+
|
|
309
|
+
# Final cleanup check
|
|
310
|
+
if [[ ${#worker_pids[@]} -gt 0 ]]; then
|
|
311
|
+
echo "[DISPATCHER] Warning: ${#worker_pids[@]} workers still active at exit"
|
|
312
|
+
shutdown_workers
|
|
313
|
+
fi
|