claude-evolve 1.8.19 → 1.8.20
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-ideate +69 -36
- package/bin/claude-evolve-run +14 -7
- package/bin/claude-evolve-worker +29 -8
- package/lib/ai-cli.sh +29 -21
- package/package.json +1 -1
- package/lib/config.sh.backup +0 -337
package/bin/claude-evolve-ideate
CHANGED
|
@@ -36,6 +36,24 @@ if [[ -n "${FULL_EVOLUTION_DIR:-}" ]]; then
|
|
|
36
36
|
echo "[IDEATE-$$] Logging to: $LOG_FILE"
|
|
37
37
|
fi
|
|
38
38
|
|
|
39
|
+
# AIDEV-NOTE: Directory restoration helper to prevent working directory corruption
|
|
40
|
+
# Critical for preventing the bug where Ctrl+C during ideation leaves the shell in wrong directory
|
|
41
|
+
# Helper to safely change directory with automatic restoration
|
|
42
|
+
safe_pushd() {
|
|
43
|
+
SAFE_PUSHD_ORIGINAL_PWD=$(pwd)
|
|
44
|
+
cd "$1" || return 1
|
|
45
|
+
# Set trap to restore directory on any exit, error, or interrupt
|
|
46
|
+
trap 'cd "$SAFE_PUSHD_ORIGINAL_PWD" 2>/dev/null || true' EXIT INT TERM ERR
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
safe_popd() {
|
|
50
|
+
if [[ -n "${SAFE_PUSHD_ORIGINAL_PWD:-}" ]]; then
|
|
51
|
+
cd "$SAFE_PUSHD_ORIGINAL_PWD" || true
|
|
52
|
+
# Clear the trap since we're explicitly returning
|
|
53
|
+
trap - EXIT INT TERM ERR
|
|
54
|
+
fi
|
|
55
|
+
}
|
|
56
|
+
|
|
39
57
|
# Helper function to call AI with limit check
|
|
40
58
|
call_ai_with_limit_check() {
|
|
41
59
|
local prompt="$1"
|
|
@@ -1104,12 +1122,15 @@ CRITICAL: Do NOT use any git commands (git add, git commit, git reset, etc.). On
|
|
|
1104
1122
|
|
|
1105
1123
|
# Debug prompt size and context (removed - no longer needed)
|
|
1106
1124
|
|
|
1107
|
-
# Change to evolution directory so AI can access files
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1125
|
+
# Change to evolution directory so AI can access files (with safe restoration on interrupt)
|
|
1126
|
+
safe_pushd "$FULL_EVOLUTION_DIR" || {
|
|
1127
|
+
echo "[ERROR] Failed to change to evolution directory" >&2
|
|
1128
|
+
rm -f "$temp_csv"
|
|
1129
|
+
return 1
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1111
1132
|
# Debug: Show files in evolution directory
|
|
1112
|
-
|
|
1133
|
+
|
|
1113
1134
|
# Get AI to directly edit the CSV file
|
|
1114
1135
|
local ai_response
|
|
1115
1136
|
local stderr_file="stderr-$$.txt"
|
|
@@ -1117,14 +1138,14 @@ CRITICAL: Do NOT use any git commands (git add, git commit, git reset, etc.). On
|
|
|
1117
1138
|
if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$count" "$temp_csv_basename"); then
|
|
1118
1139
|
echo "[ERROR] All AI models failed to generate novel ideas" >&2
|
|
1119
1140
|
cat "$stderr_file" >&2
|
|
1120
|
-
|
|
1141
|
+
safe_popd
|
|
1121
1142
|
rm -f "$temp_csv" "$stderr_file"
|
|
1122
1143
|
return 1
|
|
1123
1144
|
fi
|
|
1124
1145
|
rm -f "$stderr_file"
|
|
1125
|
-
|
|
1146
|
+
|
|
1126
1147
|
# Restore working directory
|
|
1127
|
-
|
|
1148
|
+
safe_popd
|
|
1128
1149
|
|
|
1129
1150
|
# Validate that the CSV file was actually modified with correct IDs
|
|
1130
1151
|
# Pass original_csv_lines to prevent race conditions
|
|
@@ -1255,10 +1276,13 @@ CRITICAL INSTRUCTIONS:
|
|
|
1255
1276
|
8. CRITICAL: When editing, preserve the CSV formatting with proper quoting
|
|
1256
1277
|
9. DO NOT use any git commands (git add, git commit, git reset, etc.). Only modify the file directly."
|
|
1257
1278
|
|
|
1258
|
-
# Change to evolution directory so AI can access files
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1279
|
+
# Change to evolution directory so AI can access files (with safe restoration on interrupt)
|
|
1280
|
+
safe_pushd "$FULL_EVOLUTION_DIR" || {
|
|
1281
|
+
echo "[ERROR] Failed to change to evolution directory" >&2
|
|
1282
|
+
rm -f "$temp_csv"
|
|
1283
|
+
return 1
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1262
1286
|
# Get AI to directly edit the CSV file
|
|
1263
1287
|
local ai_response
|
|
1264
1288
|
local stderr_file="stderr-$$.txt"
|
|
@@ -1266,14 +1290,14 @@ CRITICAL INSTRUCTIONS:
|
|
|
1266
1290
|
if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$count" "$temp_csv_basename"); then
|
|
1267
1291
|
echo "[ERROR] All AI models failed to generate hill climbing ideas" >&2
|
|
1268
1292
|
cat "$stderr_file" >&2
|
|
1269
|
-
|
|
1293
|
+
safe_popd
|
|
1270
1294
|
rm -f "$temp_csv" "$stderr_file"
|
|
1271
1295
|
return 1
|
|
1272
1296
|
fi
|
|
1273
1297
|
rm -f "$stderr_file"
|
|
1274
|
-
|
|
1298
|
+
|
|
1275
1299
|
# Restore working directory
|
|
1276
|
-
|
|
1300
|
+
safe_popd
|
|
1277
1301
|
|
|
1278
1302
|
# Validate that the CSV file was actually modified with correct IDs
|
|
1279
1303
|
# Pass original_csv_lines to prevent race conditions
|
|
@@ -1394,10 +1418,13 @@ CRITICAL INSTRUCTIONS:
|
|
|
1394
1418
|
8. CRITICAL: When editing, preserve the CSV formatting with proper quoting
|
|
1395
1419
|
9. DO NOT use any git commands (git add, git commit, git reset, etc.). Only modify the file directly."
|
|
1396
1420
|
|
|
1397
|
-
# Change to evolution directory so AI can access files
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1421
|
+
# Change to evolution directory so AI can access files (with safe restoration on interrupt)
|
|
1422
|
+
safe_pushd "$FULL_EVOLUTION_DIR" || {
|
|
1423
|
+
echo "[ERROR] Failed to change to evolution directory" >&2
|
|
1424
|
+
rm -f "$temp_csv"
|
|
1425
|
+
return 1
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1401
1428
|
# Get AI to directly edit the CSV file
|
|
1402
1429
|
local ai_response
|
|
1403
1430
|
local stderr_file="stderr-$$.txt"
|
|
@@ -1405,14 +1432,14 @@ CRITICAL INSTRUCTIONS:
|
|
|
1405
1432
|
if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$count" "$temp_csv_basename"); then
|
|
1406
1433
|
echo "[ERROR] All AI models failed to generate structural mutation ideas" >&2
|
|
1407
1434
|
cat "$stderr_file" >&2
|
|
1408
|
-
|
|
1435
|
+
safe_popd
|
|
1409
1436
|
rm -f "$temp_csv" "$stderr_file"
|
|
1410
1437
|
return 1
|
|
1411
1438
|
fi
|
|
1412
1439
|
rm -f "$stderr_file"
|
|
1413
|
-
|
|
1440
|
+
|
|
1414
1441
|
# Restore working directory
|
|
1415
|
-
|
|
1442
|
+
safe_popd
|
|
1416
1443
|
|
|
1417
1444
|
# Validate that the CSV file was actually modified with correct IDs
|
|
1418
1445
|
# Pass original_csv_lines to prevent race conditions
|
|
@@ -1533,10 +1560,13 @@ CRITICAL INSTRUCTIONS:
|
|
|
1533
1560
|
8. CRITICAL: When editing, preserve the CSV formatting with proper quoting
|
|
1534
1561
|
9. DO NOT use any git commands (git add, git commit, git reset, etc.). Only modify the file directly."
|
|
1535
1562
|
|
|
1536
|
-
# Change to evolution directory so AI can access files
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1563
|
+
# Change to evolution directory so AI can access files (with safe restoration on interrupt)
|
|
1564
|
+
safe_pushd "$FULL_EVOLUTION_DIR" || {
|
|
1565
|
+
echo "[ERROR] Failed to change to evolution directory" >&2
|
|
1566
|
+
rm -f "$temp_csv"
|
|
1567
|
+
return 1
|
|
1568
|
+
}
|
|
1569
|
+
|
|
1540
1570
|
# Get AI to directly edit the CSV file
|
|
1541
1571
|
local ai_response
|
|
1542
1572
|
local stderr_file="stderr-$$.txt"
|
|
@@ -1544,14 +1574,14 @@ CRITICAL INSTRUCTIONS:
|
|
|
1544
1574
|
if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$count" "$temp_csv_basename"); then
|
|
1545
1575
|
echo "[ERROR] All AI models failed to generate crossover hybrid ideas" >&2
|
|
1546
1576
|
cat "$stderr_file" >&2
|
|
1547
|
-
|
|
1577
|
+
safe_popd
|
|
1548
1578
|
rm -f "$temp_csv" "$stderr_file"
|
|
1549
1579
|
return 1
|
|
1550
1580
|
fi
|
|
1551
1581
|
rm -f "$stderr_file"
|
|
1552
|
-
|
|
1582
|
+
|
|
1553
1583
|
# Restore working directory
|
|
1554
|
-
|
|
1584
|
+
safe_popd
|
|
1555
1585
|
|
|
1556
1586
|
# Validate that the CSV file was actually modified with correct IDs
|
|
1557
1587
|
# Pass original_csv_lines to prevent race conditions
|
|
@@ -1650,24 +1680,27 @@ IMPORTANT: You must APPEND new rows to the existing CSV file. DO NOT replace the
|
|
|
1650
1680
|
CRITICAL: You must use your file editing tools (Edit/MultiEdit) to modify the CSV file. DO NOT return CSV text - use your tools to edit the file directly.
|
|
1651
1681
|
CRITICAL: Do NOT use any git commands (git add, git commit, git reset, etc.). Only modify the file directly."
|
|
1652
1682
|
|
|
1653
|
-
# Change to evolution directory so AI can access files
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1683
|
+
# Change to evolution directory so AI can access files (with safe restoration on interrupt)
|
|
1684
|
+
safe_pushd "$FULL_EVOLUTION_DIR" || {
|
|
1685
|
+
echo "[ERROR] Failed to change to evolution directory" >&2
|
|
1686
|
+
rm -f "$temp_csv"
|
|
1687
|
+
return 1
|
|
1688
|
+
}
|
|
1689
|
+
|
|
1657
1690
|
# Get AI to directly edit the CSV file
|
|
1658
1691
|
local ai_response
|
|
1659
1692
|
local stderr_file="stderr-$$.txt"
|
|
1660
1693
|
if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$TOTAL_IDEAS" "$temp_csv_basename" 2>"$stderr_file"); then
|
|
1661
1694
|
echo "[ERROR] All AI models failed to generate ideas" >&2
|
|
1662
1695
|
cat "$stderr_file" >&2
|
|
1663
|
-
|
|
1696
|
+
safe_popd
|
|
1664
1697
|
rm -f "$temp_csv" "$stderr_file"
|
|
1665
1698
|
return 1
|
|
1666
1699
|
fi
|
|
1667
1700
|
rm -f "$stderr_file"
|
|
1668
|
-
|
|
1701
|
+
|
|
1669
1702
|
# Restore working directory
|
|
1670
|
-
|
|
1703
|
+
safe_popd
|
|
1671
1704
|
|
|
1672
1705
|
# Validate that the CSV file was actually modified
|
|
1673
1706
|
# Pass original_csv_lines to prevent race conditions
|
package/bin/claude-evolve-run
CHANGED
|
@@ -646,8 +646,8 @@ except Exception as e:
|
|
|
646
646
|
if [[ $pending_count -eq 0 && $active_workers -eq 0 ]]; then
|
|
647
647
|
echo "[DISPATCHER] No pending candidates found."
|
|
648
648
|
|
|
649
|
-
# Before
|
|
650
|
-
echo "[DISPATCHER] Performing final verification for stuck candidates..."
|
|
649
|
+
# Before triggering ideation, do final check AND RESET stuck work (immediate, not periodic)
|
|
650
|
+
echo "[DISPATCHER] Performing final verification and cleanup for stuck candidates..."
|
|
651
651
|
stuck_work_count=$("$PYTHON_CMD" -c "
|
|
652
652
|
import sys
|
|
653
653
|
sys.path.insert(0, '$SCRIPT_DIR/..')
|
|
@@ -655,18 +655,25 @@ from lib.evolution_csv import EvolutionCSV
|
|
|
655
655
|
|
|
656
656
|
try:
|
|
657
657
|
with EvolutionCSV('$FULL_CSV_PATH') as csv:
|
|
658
|
+
# First count stuck candidates
|
|
658
659
|
stuck = csv.count_stuck_candidates()
|
|
660
|
+
|
|
661
|
+
# If any found, reset them immediately
|
|
662
|
+
if stuck > 0:
|
|
663
|
+
print(f'[DISPATCHER] Found {stuck} stuck candidates, resetting to pending...', file=sys.stderr)
|
|
664
|
+
reset_count = csv.reset_stuck_candidates()
|
|
665
|
+
print(f'[DISPATCHER] Reset {reset_count} stuck candidates to pending', file=sys.stderr)
|
|
666
|
+
|
|
659
667
|
print(stuck)
|
|
660
668
|
except Exception as e:
|
|
661
|
-
print(f'[ERROR] Failed to
|
|
669
|
+
print(f'[ERROR] Failed to check/reset stuck candidates: {e}', file=sys.stderr)
|
|
662
670
|
print('0') # Default to 0 on error
|
|
663
671
|
" 2>/dev/null || echo "0")
|
|
664
672
|
|
|
665
673
|
if [[ $stuck_work_count -gt 0 ]]; then
|
|
666
|
-
echo "[DISPATCHER]
|
|
667
|
-
#
|
|
668
|
-
|
|
669
|
-
continue # Go back to top of loop to trigger cleanup
|
|
674
|
+
echo "[DISPATCHER] Reset $stuck_work_count stuck candidates to pending"
|
|
675
|
+
# Don't trigger ideation - go back to check pending count again
|
|
676
|
+
continue # Go back to top of loop to re-count pending
|
|
670
677
|
fi
|
|
671
678
|
|
|
672
679
|
# Check if auto ideation is enabled
|
package/bin/claude-evolve-worker
CHANGED
|
@@ -18,6 +18,24 @@ if [[ -n "${FULL_EVOLUTION_DIR:-}" ]]; then
|
|
|
18
18
|
echo "[WORKER-$$] Logging to: $LOG_FILE"
|
|
19
19
|
fi
|
|
20
20
|
|
|
21
|
+
# AIDEV-NOTE: Directory restoration helper to prevent working directory corruption
|
|
22
|
+
# Critical for preventing the bug where Ctrl+C during worker leaves the shell in wrong directory
|
|
23
|
+
# Helper to safely change directory with automatic restoration
|
|
24
|
+
safe_pushd() {
|
|
25
|
+
SAFE_PUSHD_ORIGINAL_PWD=$(pwd)
|
|
26
|
+
cd "$1" || return 1
|
|
27
|
+
# Set trap to restore directory on any exit, error, or interrupt
|
|
28
|
+
trap 'cd "$SAFE_PUSHD_ORIGINAL_PWD" 2>/dev/null || true' EXIT INT TERM ERR
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
safe_popd() {
|
|
32
|
+
if [[ -n "${SAFE_PUSHD_ORIGINAL_PWD:-}" ]]; then
|
|
33
|
+
cd "$SAFE_PUSHD_ORIGINAL_PWD" || true
|
|
34
|
+
# Clear the trap since we're explicitly returning
|
|
35
|
+
trap - EXIT INT TERM ERR
|
|
36
|
+
fi
|
|
37
|
+
}
|
|
38
|
+
|
|
21
39
|
# Track current candidate for cleanup
|
|
22
40
|
CURRENT_CANDIDATE_ID=""
|
|
23
41
|
TERMINATION_SIGNAL=""
|
|
@@ -343,23 +361,26 @@ This is especially important for models with smaller context windows (like GLM).
|
|
|
343
361
|
CRITICAL: If you do not know how to implement what was asked for, or if the requested change is unclear or not feasible, you MUST refuse to make any changes. DO NOT modify the code if you are uncertain about the implementation. Simply respond that you cannot implement the requested change and explain why. It is better to refuse than to make incorrect or random changes.
|
|
344
362
|
|
|
345
363
|
CRITICAL: Do NOT use any git commands (git add, git commit, git reset, etc.). Only modify the file directly."
|
|
346
|
-
|
|
364
|
+
|
|
347
365
|
if [[ "$is_baseline" != "true" ]]; then
|
|
348
|
-
# Change to evolution directory so AI can access files
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
366
|
+
# Change to evolution directory so AI can access files (with safe restoration on interrupt)
|
|
367
|
+
safe_pushd "$FULL_EVOLUTION_DIR" || {
|
|
368
|
+
echo "[WORKER-$$] ERROR: Failed to change to evolution directory" >&2
|
|
369
|
+
rm -f "$target_file"
|
|
370
|
+
return 1
|
|
371
|
+
}
|
|
372
|
+
|
|
352
373
|
# Try AI models with round-robin based on candidate ID
|
|
353
374
|
if ! call_ai_for_evolution "$evolution_prompt" "$candidate_id"; then
|
|
354
375
|
echo "[WORKER-$$] ERROR: All AI models failed to generate code - leaving as pending for retry" >&2
|
|
355
|
-
|
|
376
|
+
safe_popd
|
|
356
377
|
rm -f "$target_file" # Clean up on failure
|
|
357
378
|
# Return with special code to indicate AI failure (should remain pending)
|
|
358
379
|
return 77
|
|
359
380
|
fi
|
|
360
|
-
|
|
381
|
+
|
|
361
382
|
# Restore working directory
|
|
362
|
-
|
|
383
|
+
safe_popd
|
|
363
384
|
|
|
364
385
|
echo "[WORKER-$$] Evolution applied successfully"
|
|
365
386
|
|
package/lib/ai-cli.sh
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# Centralized AI CLI invocation library for claude-evolve
|
|
3
|
+
#
|
|
4
|
+
# AIDEV-NOTE: All timeout commands use -k flag to ensure process termination
|
|
5
|
+
# The -k flag sends SIGKILL if the process doesn't respond to SIGTERM within
|
|
6
|
+
# the grace period (30 seconds). This prevents AI CLI processes from hanging
|
|
7
|
+
# indefinitely when they ignore the initial SIGTERM signal.
|
|
8
|
+
# Example: timeout -k 30 600 means:
|
|
9
|
+
# - Wait 600 seconds, then send SIGTERM
|
|
10
|
+
# - If still running after 30 more seconds, send SIGKILL (force kill)
|
|
3
11
|
|
|
4
12
|
# Source config to get LLM_CLI array and model lists
|
|
5
13
|
# This will be sourced after config.sh in the main scripts
|
|
@@ -19,12 +27,12 @@ call_ai_model_configured() {
|
|
|
19
27
|
case "$model_name" in
|
|
20
28
|
opus)
|
|
21
29
|
local ai_output
|
|
22
|
-
ai_output=$(timeout 300 claude --dangerously-skip-permissions --mcp-config '' --model opus -p "$prompt" 2>&1)
|
|
30
|
+
ai_output=$(timeout -k 30 300 claude --dangerously-skip-permissions --mcp-config '' --model opus -p "$prompt" 2>&1)
|
|
23
31
|
local ai_exit_code=$?
|
|
24
32
|
;;
|
|
25
33
|
sonnet)
|
|
26
34
|
local ai_output
|
|
27
|
-
ai_output=$(timeout 300 claude --dangerously-skip-permissions --mcp-config '' --model sonnet -p "$prompt" 2>&1)
|
|
35
|
+
ai_output=$(timeout -k 30 300 claude --dangerously-skip-permissions --mcp-config '' --model sonnet -p "$prompt" 2>&1)
|
|
28
36
|
local ai_exit_code=$?
|
|
29
37
|
;;
|
|
30
38
|
sonnet-think)
|
|
@@ -33,7 +41,7 @@ call_ai_model_configured() {
|
|
|
33
41
|
local think_prompt="ultrathink
|
|
34
42
|
|
|
35
43
|
$prompt"
|
|
36
|
-
ai_output=$(timeout 600 claude --dangerously-skip-permissions --mcp-config '' --model sonnet -p "$think_prompt" 2>&1)
|
|
44
|
+
ai_output=$(timeout -k 30 600 claude --dangerously-skip-permissions --mcp-config '' --model sonnet -p "$think_prompt" 2>&1)
|
|
37
45
|
local ai_exit_code=$?
|
|
38
46
|
;;
|
|
39
47
|
opus-think)
|
|
@@ -42,97 +50,97 @@ $prompt"
|
|
|
42
50
|
local think_prompt="ultrathink
|
|
43
51
|
|
|
44
52
|
$prompt"
|
|
45
|
-
ai_output=$(timeout 600 claude --dangerously-skip-permissions --mcp-config '' --model opus -p "$think_prompt" 2>&1)
|
|
53
|
+
ai_output=$(timeout -k 30 600 claude --dangerously-skip-permissions --mcp-config '' --model opus -p "$think_prompt" 2>&1)
|
|
46
54
|
local ai_exit_code=$?
|
|
47
55
|
;;
|
|
48
56
|
haiku)
|
|
49
57
|
local ai_output
|
|
50
|
-
ai_output=$(timeout 300 claude --dangerously-skip-permissions --mcp-config '' --model haiku -p "$prompt" 2>&1)
|
|
58
|
+
ai_output=$(timeout -k 30 300 claude --dangerously-skip-permissions --mcp-config '' --model haiku -p "$prompt" 2>&1)
|
|
51
59
|
local ai_exit_code=$?
|
|
52
60
|
;;
|
|
53
61
|
gpt5high)
|
|
54
62
|
local ai_output
|
|
55
|
-
ai_output=$(timeout 600 codex exec -m gpt-5 -c model_reasoning_effort="high" --dangerously-bypass-approvals-and-sandbox "$prompt" 2>&1)
|
|
63
|
+
ai_output=$(timeout -k 30 600 codex exec -m gpt-5 -c model_reasoning_effort="high" --dangerously-bypass-approvals-and-sandbox "$prompt" 2>&1)
|
|
56
64
|
local ai_exit_code=$?
|
|
57
65
|
;;
|
|
58
66
|
gpt5)
|
|
59
67
|
local ai_output
|
|
60
|
-
ai_output=$(timeout 600 codex exec -m gpt-5 --dangerously-bypass-approvals-and-sandbox "$prompt" 2>&1)
|
|
68
|
+
ai_output=$(timeout -k 30 600 codex exec -m gpt-5 --dangerously-bypass-approvals-and-sandbox "$prompt" 2>&1)
|
|
61
69
|
local ai_exit_code=$?
|
|
62
70
|
;;
|
|
63
71
|
o3high)
|
|
64
72
|
local ai_output
|
|
65
|
-
ai_output=$(timeout 600 codex exec -m o3-mini -c model_reasoning_effort="high" --dangerously-bypass-approvals-and-sandbox "$prompt" 2>&1)
|
|
73
|
+
ai_output=$(timeout -k 30 600 codex exec -m o3-mini -c model_reasoning_effort="high" --dangerously-bypass-approvals-and-sandbox "$prompt" 2>&1)
|
|
66
74
|
local ai_exit_code=$?
|
|
67
75
|
;;
|
|
68
76
|
gemini-pro)
|
|
69
77
|
local ai_output
|
|
70
78
|
# Gemini needs longer timeout as it streams output while working (20 minutes)
|
|
71
|
-
ai_output=$(timeout 1800 gemini -y -m gemini-2.5-pro -p "$prompt" 2>&1)
|
|
79
|
+
ai_output=$(timeout -k 30 1800 gemini -y -m gemini-2.5-pro -p "$prompt" 2>&1)
|
|
72
80
|
local ai_exit_code=$?
|
|
73
81
|
;;
|
|
74
82
|
gemini-flash)
|
|
75
83
|
local ai_output
|
|
76
84
|
# Gemini needs longer timeout as it streams output while working (20 minutes)
|
|
77
|
-
ai_output=$(timeout 1200 gemini -y -m gemini-2.5-flash -p "$prompt" 2>&1)
|
|
85
|
+
ai_output=$(timeout -k 30 1200 gemini -y -m gemini-2.5-flash -p "$prompt" 2>&1)
|
|
78
86
|
local ai_exit_code=$?
|
|
79
87
|
;;
|
|
80
88
|
cursor-sonnet)
|
|
81
89
|
local ai_output
|
|
82
|
-
ai_output=$(timeout 600 cursor-agent sonnet-4.5 -p "$prompt" 2>&1)
|
|
90
|
+
ai_output=$(timeout -k 30 600 cursor-agent sonnet-4.5 -p "$prompt" 2>&1)
|
|
83
91
|
local ai_exit_code=$?
|
|
84
92
|
;;
|
|
85
93
|
cursor-opus)
|
|
86
94
|
local ai_output
|
|
87
|
-
ai_output=$(timeout 600 cursor-agent opus -p "$prompt" 2>&1)
|
|
95
|
+
ai_output=$(timeout -k 30 600 cursor-agent opus -p "$prompt" 2>&1)
|
|
88
96
|
local ai_exit_code=$?
|
|
89
97
|
;;
|
|
90
98
|
glm-openrouter)
|
|
91
99
|
local ai_output
|
|
92
|
-
ai_output=$(timeout 600 opencode -m openrouter/z-ai/glm-4.6 run "$prompt" 2>&1)
|
|
100
|
+
ai_output=$(timeout -k 30 600 opencode -m openrouter/z-ai/glm-4.6 run "$prompt" 2>&1)
|
|
93
101
|
local ai_exit_code=$?
|
|
94
102
|
;;
|
|
95
103
|
glm-zai)
|
|
96
104
|
# GLM -- can be slow sometimes
|
|
97
105
|
local ai_output
|
|
98
|
-
ai_output=$(timeout 1800 opencode -m zai-coding-plan/glm-4.6 run "$prompt" 2>&1)
|
|
106
|
+
ai_output=$(timeout -k 30 1800 opencode -m zai-coding-plan/glm-4.6 run "$prompt" 2>&1)
|
|
99
107
|
local ai_exit_code=$?
|
|
100
108
|
;;
|
|
101
109
|
deepseek-openrouter)
|
|
102
110
|
local ai_output
|
|
103
|
-
ai_output=$(timeout 600 opencode -m openrouter/deepseek/deepseek-v3.1-terminus run "$prompt" 2>&1)
|
|
111
|
+
ai_output=$(timeout -k 30 600 opencode -m openrouter/deepseek/deepseek-v3.1-terminus run "$prompt" 2>&1)
|
|
104
112
|
local ai_exit_code=$?
|
|
105
113
|
;;
|
|
106
114
|
grok-code-fast-openrouter)
|
|
107
115
|
local ai_output
|
|
108
|
-
ai_output=$(timeout 600 opencode -m openrouter/x-ai/grok-code-fast-1 run "$prompt" 2>&1)
|
|
116
|
+
ai_output=$(timeout -k 30 600 opencode -m openrouter/x-ai/grok-code-fast-1 run "$prompt" 2>&1)
|
|
109
117
|
local ai_exit_code=$?
|
|
110
118
|
;;
|
|
111
119
|
grok-4-openrouter)
|
|
112
120
|
local ai_output
|
|
113
|
-
ai_output=$(timeout 600 opencode -m openrouter/x-ai/grok-4 run "$prompt" 2>&1)
|
|
121
|
+
ai_output=$(timeout -k 30 600 opencode -m openrouter/x-ai/grok-4 run "$prompt" 2>&1)
|
|
114
122
|
local ai_exit_code=$?
|
|
115
123
|
;;
|
|
116
124
|
opus-openrouter)
|
|
117
125
|
local ai_output
|
|
118
|
-
ai_output=$(timeout 600 opencode -m openrouter/anthropic/claude-opus-4.1 run "$prompt" 2>&1)
|
|
126
|
+
ai_output=$(timeout -k 30 600 opencode -m openrouter/anthropic/claude-opus-4.1 run "$prompt" 2>&1)
|
|
119
127
|
local ai_exit_code=$?
|
|
120
128
|
;;
|
|
121
129
|
kimi-k2-think-moonshot)
|
|
122
130
|
local ai_output
|
|
123
|
-
ai_output=$(timeout 600 opencode -m moonshotai/kimi-k2-thinking run "$prompt" 2>&1)
|
|
131
|
+
ai_output=$(timeout -k 30 600 opencode -m moonshotai/kimi-k2-thinking run "$prompt" 2>&1)
|
|
124
132
|
local ai_exit_code=$?
|
|
125
133
|
;;
|
|
126
134
|
codex-oss-local)
|
|
127
135
|
# Codex-OSS via Codex CLI with Ollama backend
|
|
128
136
|
local ai_output
|
|
129
|
-
ai_output=$(timeout 2400 codex exec --dangerously-bypass-approvals-and-sandbox --skip-git-repo-check --oss "$prompt" 2>&1)
|
|
137
|
+
ai_output=$(timeout -k 30 2400 codex exec --dangerously-bypass-approvals-and-sandbox --skip-git-repo-check --oss "$prompt" 2>&1)
|
|
130
138
|
local ai_exit_code=$?
|
|
131
139
|
;;
|
|
132
140
|
deepseek-v3-llamacloud)
|
|
133
141
|
# Deepseek via Codex CLI with Ollama cloud backend
|
|
134
142
|
local ai_output
|
|
135
|
-
ai_output=$(timeout 600 codex exec --dangerously-bypass-approvals-and-sandbox --skip-git-repo-check --oss -m deepseek-v3.1:671b-cloud "$prompt" 2>&1)
|
|
143
|
+
ai_output=$(timeout -k 30 600 codex exec --dangerously-bypass-approvals-and-sandbox --skip-git-repo-check --oss -m deepseek-v3.1:671b-cloud "$prompt" 2>&1)
|
|
136
144
|
local ai_exit_code=$?
|
|
137
145
|
;;
|
|
138
146
|
esac
|
package/package.json
CHANGED
package/lib/config.sh.backup
DELETED
|
@@ -1,337 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Configuration loader for claude-evolve
|
|
3
|
-
|
|
4
|
-
# Default configuration values
|
|
5
|
-
DEFAULT_EVOLUTION_DIR="evolution"
|
|
6
|
-
DEFAULT_ALGORITHM_FILE="algorithm.py"
|
|
7
|
-
DEFAULT_EVALUATOR_FILE="evaluator.py"
|
|
8
|
-
DEFAULT_BRIEF_FILE="BRIEF.md"
|
|
9
|
-
DEFAULT_EVOLUTION_CSV="evolution.csv"
|
|
10
|
-
DEFAULT_OUTPUT_DIR=""
|
|
11
|
-
DEFAULT_PARENT_SELECTION="best"
|
|
12
|
-
# Detect Python command based on platform
|
|
13
|
-
detect_python_cmd() {
|
|
14
|
-
# Try python3 first (macOS, Linux)
|
|
15
|
-
if command -v python3 >/dev/null 2>&1; then
|
|
16
|
-
echo "python3"
|
|
17
|
-
# Try python (Windows, some Linux)
|
|
18
|
-
elif command -v python >/dev/null 2>&1; then
|
|
19
|
-
# Verify it's Python 3
|
|
20
|
-
if python -c "import sys; sys.exit(0 if sys.version_info[0] >= 3 else 1)" 2>/dev/null; then
|
|
21
|
-
echo "python"
|
|
22
|
-
else
|
|
23
|
-
echo "python3" # Fallback
|
|
24
|
-
fi
|
|
25
|
-
else
|
|
26
|
-
echo "python3" # Default fallback
|
|
27
|
-
fi
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
DEFAULT_PYTHON_CMD="$(detect_python_cmd)"
|
|
31
|
-
|
|
32
|
-
# Default ideation strategy values
|
|
33
|
-
DEFAULT_TOTAL_IDEAS=15
|
|
34
|
-
DEFAULT_NOVEL_EXPLORATION=3
|
|
35
|
-
DEFAULT_HILL_CLIMBING=5
|
|
36
|
-
DEFAULT_STRUCTURAL_MUTATION=3
|
|
37
|
-
DEFAULT_CROSSOVER_HYBRID=4
|
|
38
|
-
DEFAULT_NUM_ELITES=3
|
|
39
|
-
DEFAULT_NUM_REVOLUTION=2 # Number of top novel candidates to include
|
|
40
|
-
|
|
41
|
-
# Default parallel execution values
|
|
42
|
-
DEFAULT_PARALLEL_ENABLED=false
|
|
43
|
-
DEFAULT_MAX_WORKERS=4
|
|
44
|
-
DEFAULT_LOCK_TIMEOUT=10
|
|
45
|
-
|
|
46
|
-
# Default auto ideation value
|
|
47
|
-
DEFAULT_AUTO_IDEATE=true
|
|
48
|
-
|
|
49
|
-
# Default retry value
|
|
50
|
-
DEFAULT_MAX_RETRIES=3
|
|
51
|
-
|
|
52
|
-
# Default memory limit (in MB, 0 means no limit)
|
|
53
|
-
# Set to reasonable limit for ML workloads - about half of available system RAM
|
|
54
|
-
DEFAULT_MEMORY_LIMIT_MB=12288
|
|
55
|
-
|
|
56
|
-
# Default LLM CLI configuration - use simple variables instead of arrays
|
|
57
|
-
# Run: 100% local with qwen3 via Codex+Ollama (more reliable than aider)
|
|
58
|
-
DEFAULT_LLM_RUN="codex-qwen3 codex-oss gemini-flash"
|
|
59
|
-
# Ideate: Commercial models for idea generation + local fallback
|
|
60
|
-
DEFAULT_LLM_IDEATE="gemini sonnet-think gpt5high glm grok-4 codex-qwen3 codex-oss"
|
|
61
|
-
|
|
62
|
-
# Load configuration from a YAML file and update variables
|
|
63
|
-
_load_yaml_config() {
|
|
64
|
-
local config_file="$1"
|
|
65
|
-
if [[ ! -f "$config_file" ]]; then
|
|
66
|
-
return 0 # File does not exist, nothing to load
|
|
67
|
-
fi
|
|
68
|
-
|
|
69
|
-
echo "[DEBUG] Loading configuration from: $config_file" >&2
|
|
70
|
-
|
|
71
|
-
local in_ideation_section=false
|
|
72
|
-
local in_parallel_section=false
|
|
73
|
-
local in_llm_cli_section=false
|
|
74
|
-
local llm_cli_subsection=""
|
|
75
|
-
|
|
76
|
-
while IFS='' read -r line; do
|
|
77
|
-
[[ $line =~ ^[[:space:]]*# ]] || [[ -z $line ]] && continue
|
|
78
|
-
|
|
79
|
-
if [[ ! $line =~ ^([^:]+):(.*)$ ]]; then
|
|
80
|
-
continue
|
|
81
|
-
fi
|
|
82
|
-
local key="${BASH_REMATCH[1]}"
|
|
83
|
-
local value="${BASH_REMATCH[2]}"
|
|
84
|
-
|
|
85
|
-
local is_indented=false
|
|
86
|
-
[[ $key =~ ^[[:space:]]+ ]] && is_indented=true
|
|
87
|
-
|
|
88
|
-
key=$(echo "$key" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
|
89
|
-
value=$(echo "$value" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
|
90
|
-
|
|
91
|
-
if [[ "${DEBUG_CONFIG:-}" == "true" ]]; then
|
|
92
|
-
echo "[CONFIG DEBUG] Before comment removal: key='$key' value='$value'" >&2
|
|
93
|
-
fi
|
|
94
|
-
|
|
95
|
-
value=$(echo "$value" | sed 's/[[:space:]]*#.*$//')
|
|
96
|
-
value=$(echo "$value" | sed 's/^"//;s/"$//')
|
|
97
|
-
|
|
98
|
-
if [[ $key == "ideation_strategies" ]]; then
|
|
99
|
-
in_ideation_section=true
|
|
100
|
-
in_parallel_section=false
|
|
101
|
-
in_llm_cli_section=false
|
|
102
|
-
continue
|
|
103
|
-
elif [[ $key == "parallel" ]]; then
|
|
104
|
-
in_parallel_section=true
|
|
105
|
-
in_ideation_section=false
|
|
106
|
-
in_llm_cli_section=false
|
|
107
|
-
continue
|
|
108
|
-
elif [[ $key == "llm_cli" ]]; then
|
|
109
|
-
in_llm_cli_section=true
|
|
110
|
-
in_ideation_section=false
|
|
111
|
-
in_parallel_section=false
|
|
112
|
-
llm_cli_subsection=""
|
|
113
|
-
continue
|
|
114
|
-
elif [[ $is_indented == false ]] && [[ $in_ideation_section == true || $in_parallel_section == true || $in_llm_cli_section == true ]]; then
|
|
115
|
-
in_ideation_section=false
|
|
116
|
-
in_parallel_section=false
|
|
117
|
-
in_llm_cli_section=false
|
|
118
|
-
llm_cli_subsection=""
|
|
119
|
-
fi
|
|
120
|
-
|
|
121
|
-
if [[ $in_ideation_section == true ]]; then
|
|
122
|
-
case $key in
|
|
123
|
-
total_ideas) TOTAL_IDEAS="$value" ;;
|
|
124
|
-
novel_exploration) NOVEL_EXPLORATION="$value" ;;
|
|
125
|
-
hill_climbing) HILL_CLIMBING="$value" ;;
|
|
126
|
-
structural_mutation) STRUCTURAL_MUTATION="$value" ;;
|
|
127
|
-
crossover_hybrid) CROSSOVER_HYBRID="$value" ;;
|
|
128
|
-
num_elites) NUM_ELITES="$value" ;;
|
|
129
|
-
num_revolution) NUM_REVOLUTION="$value" ;;
|
|
130
|
-
esac
|
|
131
|
-
elif [[ $in_parallel_section == true ]]; then
|
|
132
|
-
case $key in
|
|
133
|
-
enabled) PARALLEL_ENABLED="$value" ;;
|
|
134
|
-
max_workers) MAX_WORKERS="$value" ;;
|
|
135
|
-
lock_timeout) LOCK_TIMEOUT="$value" ;;
|
|
136
|
-
esac
|
|
137
|
-
elif [[ $in_llm_cli_section == true ]]; then
|
|
138
|
-
if [[ $key == "run" || $key == "ideate" ]]; then
|
|
139
|
-
case $key in
|
|
140
|
-
run) LLM_RUN="$value" ;;
|
|
141
|
-
ideate) LLM_IDEATE="$value" ;;
|
|
142
|
-
esac
|
|
143
|
-
else
|
|
144
|
-
value=$(echo "$value" | sed "s/^'//;s/'$//")
|
|
145
|
-
local var_key=$(echo "$key" | sed 's/-/_/g')
|
|
146
|
-
if [[ "${DEBUG_CONFIG:-}" == "true" ]]; then
|
|
147
|
-
echo "[CONFIG DEBUG] Setting LLM_CLI_${var_key} = '$value'" >&2
|
|
148
|
-
fi
|
|
149
|
-
eval "LLM_CLI_${var_key}=\"$value\""
|
|
150
|
-
fi
|
|
151
|
-
else
|
|
152
|
-
case $key in
|
|
153
|
-
algorithm_file) ALGORITHM_FILE="$value" ;;
|
|
154
|
-
evaluator_file) EVALUATOR_FILE="$value" ;;
|
|
155
|
-
brief_file) BRIEF_FILE="$value" ;;
|
|
156
|
-
evolution_csv) EVOLUTION_CSV="$value" ;;
|
|
157
|
-
output_dir) OUTPUT_DIR="$value" ;;
|
|
158
|
-
parent_selection) PARENT_SELECTION="$value" ;;
|
|
159
|
-
python_cmd) PYTHON_CMD="$value" ;;
|
|
160
|
-
auto_ideate) AUTO_IDEATE="$value" ;;
|
|
161
|
-
max_retries) MAX_RETRIES="$value" ;;
|
|
162
|
-
memory_limit_mb) MEMORY_LIMIT_MB="$value" ;;
|
|
163
|
-
evolution_dir):
|
|
164
|
-
echo "[WARN] evolution_dir in config is ignored - automatically inferred from config file location" >&2
|
|
165
|
-
;;
|
|
166
|
-
esac
|
|
167
|
-
fi
|
|
168
|
-
done < "$config_file"
|
|
169
|
-
# Keep track of the last config file loaded to infer evolution_dir
|
|
170
|
-
LAST_CONFIG_FILE_LOADED="$config_file"
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
load_config() {
|
|
174
|
-
echo "[DEBUG] $1 at start of load_config: '$1'" >&2
|
|
175
|
-
echo "[DEBUG] DEFAULT_EVOLUTION_DIR: $DEFAULT_EVOLUTION_DIR" >&2
|
|
176
|
-
# Set defaults first
|
|
177
|
-
EVOLUTION_DIR="$DEFAULT_EVOLUTION_DIR" # Initialize with default
|
|
178
|
-
ALGORITHM_FILE="$DEFAULT_ALGORITHM_FILE"
|
|
179
|
-
EVALUATOR_FILE="$DEFAULT_EVALUATOR_FILE"
|
|
180
|
-
BRIEF_FILE="$DEFAULT_BRIEF_FILE"
|
|
181
|
-
EVOLUTION_CSV="$DEFAULT_EVOLUTION_CSV"
|
|
182
|
-
OUTPUT_DIR="$DEFAULT_OUTPUT_DIR"
|
|
183
|
-
PARENT_SELECTION="$DEFAULT_PARENT_SELECTION"
|
|
184
|
-
PYTHON_CMD="$DEFAULT_PYTHON_CMD"
|
|
185
|
-
|
|
186
|
-
# Determine EVOLUTION_DIR based on specified logic, overriding default if found
|
|
187
|
-
if [[ -n "$CLAUDE_EVOLVE_WORKING_DIR" ]]; then
|
|
188
|
-
echo "[DEBUG] EVOLUTION_DIR set by CLAUDE_EVOLVE_WORKING_DIR: $CLAUDE_EVOLVE_WORKING_DIR" >&2
|
|
189
|
-
EVOLUTION_DIR="$CLAUDE_EVOLVE_WORKING_DIR"
|
|
190
|
-
elif [[ -f "evolution/evolution.csv" ]]; then
|
|
191
|
-
echo "[DEBUG] EVOLUTION_DIR set by evolution/evolution.csv: evolution" >&2
|
|
192
|
-
EVOLUTION_DIR="evolution"
|
|
193
|
-
elif [[ -f "./evolution.csv" ]]; then
|
|
194
|
-
echo "[DEBUG] EVOLUTION_DIR set by ./evolution.csv: ." >&2
|
|
195
|
-
EVOLUTION_DIR="."
|
|
196
|
-
else
|
|
197
|
-
echo "[DEBUG] EVOLUTION_DIR defaulting to: $DEFAULT_EVOLUTION_DIR" >&2
|
|
198
|
-
fi
|
|
199
|
-
echo "[DEBUG] EVOLUTION_DIR after initial determination: $EVOLUTION_DIR" >&2
|
|
200
|
-
|
|
201
|
-
TOTAL_IDEAS="$DEFAULT_TOTAL_IDEAS"
|
|
202
|
-
NOVEL_EXPLORATION="$DEFAULT_NOVEL_EXPLORATION"
|
|
203
|
-
HILL_CLIMBING="$DEFAULT_HILL_CLIMBING"
|
|
204
|
-
STRUCTURAL_MUTATION="$DEFAULT_STRUCTURAL_MUTATION"
|
|
205
|
-
CROSSOVER_HYBRID="$DEFAULT_CROSSOVER_HYBRID"
|
|
206
|
-
NUM_ELITES="$DEFAULT_NUM_ELITES"
|
|
207
|
-
NUM_REVOLUTION="$DEFAULT_NUM_REVOLUTION"
|
|
208
|
-
|
|
209
|
-
PARALLEL_ENABLED="$DEFAULT_PARALLEL_ENABLED"
|
|
210
|
-
MAX_WORKERS="$DEFAULT_MAX_WORKERS"
|
|
211
|
-
LOCK_TIMEOUT="$DEFAULT_LOCK_TIMEOUT"
|
|
212
|
-
|
|
213
|
-
AUTO_IDEATE="$DEFAULT_AUTO_IDEATE"
|
|
214
|
-
MAX_RETRIES="$DEFAULT_MAX_RETRIES"
|
|
215
|
-
MEMORY_LIMIT_MB="$DEFAULT_MEMORY_LIMIT_MB"
|
|
216
|
-
|
|
217
|
-
LLM_CLI_gpt5high='codex exec --profile gpt5high --dangerously-bypass-approvals-and-sandbox "{{PROMPT}}"'
|
|
218
|
-
LLM_CLI_o3high='codex exec --profile o3high --dangerously-bypass-approvals-and-sandbox "{{PROMPT}}"'
|
|
219
|
-
LLM_CLI_codex='codex exec --dangerously-bypass-approvals-and-sandbox "{{PROMPT}}"'
|
|
220
|
-
LLM_CLI_gemini='gemini -y -p "{{PROMPT}}"'
|
|
221
|
-
LLM_CLI_gemini_flash='gemini -y -p "{{PROMPT}}" --model gemini-2.5-flash'
|
|
222
|
-
LLM_CLI_opus='claude --dangerously-skip-permissions --mcp-config "" --model opus -p "{{PROMPT}}"'
|
|
223
|
-
LLM_CLI_opus_think='claude --dangerously-skip-permissions --mcp-config "" --model opus -p "ultrathink\n\n{{PROMPT}}"'
|
|
224
|
-
LLM_CLI_sonnet='claude --dangerously-skip-permissions --mcp-config "" --model sonnet -p "{{PROMPT}}"'
|
|
225
|
-
LLM_CLI_sonnet_think='claude --dangerously-skip-permissions --mcp-config "" --model sonnet -p "ultrathink\n\n{{PROMPT}}"'
|
|
226
|
-
LLM_CLI_cursor_sonnet='cursor-agent sonnet -p "{{PROMPT}}"'
|
|
227
|
-
LLM_CLI_cursor_opus='cursor-agent opus -p "{{PROMPT}}"'
|
|
228
|
-
LLM_CLI_glm='opencode -m openrouter/z-ai/glm-4.6 run "{{PROMPT}}"'
|
|
229
|
-
LLM_CLI_deepseek='opencode -m openrouter/deepseek/deepseek-v3.1-terminus run "{{PROMPT}}"'
|
|
230
|
-
LLM_CLI_ollama-cloud-gpt-oss='codex exec --dangerously-bypass-approvals-and-sandbox --skip-git-repo-check --oss --model gpt-oss:20b-cloud "{{PROMPT}}"' LLM_CLI_ollama-cloud-kimi-k2='codex exec --dangerously-bypass-approvals-and-sandbox --skip-git-repo-check --oss --model kimi-k2:1t-cloud "{{PROMPT}}"' LLM_RUN="$DEFAULT_LLM_RUN"
|
|
231
|
-
LLM_IDEATE="$DEFAULT_LLM_IDEATE"
|
|
232
|
-
|
|
233
|
-
# Determine local config file path relative to EVOLUTION_DIR
|
|
234
|
-
local local_config_file="$EVOLUTION_DIR/config.yaml"
|
|
235
|
-
|
|
236
|
-
# Load local config
|
|
237
|
-
_load_yaml_config "$local_config_file"
|
|
238
|
-
|
|
239
|
-
# Load global config (overrides local config)
|
|
240
|
-
local global_config_file="$HOME/.config/claude-evolve/config.yaml"
|
|
241
|
-
_load_yaml_config "$global_config_file"
|
|
242
|
-
|
|
243
|
-
echo "[DEBUG] EVOLUTION_DIR before FULL_EVOLUTION_DIR calculation: $EVOLUTION_DIR" >&2
|
|
244
|
-
|
|
245
|
-
# Create full paths - ALL paths are relative to EVOLUTION_DIR
|
|
246
|
-
# Make EVOLUTION_DIR absolute if it\'s relative
|
|
247
|
-
if [[ "$EVOLUTION_DIR" = /* ]]; then
|
|
248
|
-
FULL_EVOLUTION_DIR="$EVOLUTION_DIR"
|
|
249
|
-
else
|
|
250
|
-
FULL_EVOLUTION_DIR="$(cd "$EVOLUTION_DIR" 2>/dev/null && pwd)" || FULL_EVOLUTION_DIR="$EVOLUTION_DIR"
|
|
251
|
-
fi
|
|
252
|
-
|
|
253
|
-
FULL_ALGORITHM_PATH="$FULL_EVOLUTION_DIR/$ALGORITHM_FILE"
|
|
254
|
-
FULL_EVALUATOR_PATH="$FULL_EVOLUTION_DIR/$EVALUATOR_FILE"
|
|
255
|
-
FULL_BRIEF_PATH="$FULL_EVOLUTION_DIR/$BRIEF_FILE"
|
|
256
|
-
FULL_CSV_PATH="$FULL_EVOLUTION_DIR/$EVOLUTION_CSV"
|
|
257
|
-
|
|
258
|
-
if [[ -n $OUTPUT_DIR ]]; then
|
|
259
|
-
FULL_OUTPUT_DIR="$FULL_EVOLUTION_DIR/$OUTPUT_DIR"
|
|
260
|
-
else
|
|
261
|
-
FULL_OUTPUT_DIR="$FULL_EVOLUTION_DIR"
|
|
262
|
-
fi
|
|
263
|
-
echo "[DEBUG] FULL_EVOLUTION_DIR at end of load_config: $FULL_EVOLUTION_DIR" >&2
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
# Validate configuration
|
|
267
|
-
validate_config() {
|
|
268
|
-
local errors=0
|
|
269
|
-
|
|
270
|
-
if [[ ! -d "$FULL_EVOLUTION_DIR" ]]; then
|
|
271
|
-
echo "[ERROR] Evolution directory not found: $FULL_EVOLUTION_DIR" >&2
|
|
272
|
-
((errors++))
|
|
273
|
-
fi
|
|
274
|
-
|
|
275
|
-
if [[ ! -f "$FULL_ALGORITHM_PATH" ]]; then
|
|
276
|
-
echo "[ERROR] Algorithm file not found: $FULL_ALGORITHM_PATH" >&2
|
|
277
|
-
((errors++))
|
|
278
|
-
fi
|
|
279
|
-
|
|
280
|
-
if [[ ! -f "$FULL_EVALUATOR_PATH" ]]; then
|
|
281
|
-
echo "[ERROR] Evaluator file not found: $FULL_EVALUATOR_PATH" >&2
|
|
282
|
-
((errors++))
|
|
283
|
-
fi
|
|
284
|
-
|
|
285
|
-
if [[ ! -f "$FULL_BRIEF_PATH" ]]; then
|
|
286
|
-
echo "[ERROR] Brief file not found: $FULL_BRIEF_PATH" >&2
|
|
287
|
-
((errors++))
|
|
288
|
-
fi
|
|
289
|
-
|
|
290
|
-
if ! command -v "$PYTHON_CMD" >/dev/null 2>&1; then
|
|
291
|
-
echo "[ERROR] Python command not found: $PYTHON_CMD" >&2
|
|
292
|
-
echo "[ERROR] Please install Python 3.x or set python_cmd in config.yaml" >&2
|
|
293
|
-
echo "[ERROR] Examples: python_cmd: \"python\" or python_cmd: \"C:\\Python39\\python.exe\"" >&2
|
|
294
|
-
((errors++))
|
|
295
|
-
else
|
|
296
|
-
# Verify Python version is 3.x
|
|
297
|
-
if ! "$PYTHON_CMD" -c "import sys; sys.exit(0 if sys.version_info[0] >= 3 else 1)" 2>/dev/null; then
|
|
298
|
-
echo "[ERROR] Python 3.x required, but $PYTHON_CMD appears to be Python 2" >&2
|
|
299
|
-
echo "[ERROR] Please set python_cmd in config.yaml to point to Python 3" >&2
|
|
300
|
-
((errors++))
|
|
301
|
-
fi
|
|
302
|
-
fi
|
|
303
|
-
|
|
304
|
-
return $errors
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
# Show current configuration
|
|
308
|
-
show_config() {
|
|
309
|
-
echo "Current claude-evolve configuration:"
|
|
310
|
-
echo " Evolution directory: $FULL_EVOLUTION_DIR"
|
|
311
|
-
echo " Algorithm file: $FULL_ALGORITHM_PATH"
|
|
312
|
-
echo " Evaluator file: $FULL_EVALUATOR_PATH"
|
|
313
|
-
echo " Brief file: $FULL_BRIEF_PATH"
|
|
314
|
-
echo " CSV file: $FULL_CSV_PATH"
|
|
315
|
-
echo " Output directory: $FULL_OUTPUT_DIR"
|
|
316
|
-
echo " Parent selection: $PARENT_SELECTION"
|
|
317
|
-
echo " Python command: $PYTHON_CMD"
|
|
318
|
-
echo " Parallel enabled: $PARALLEL_ENABLED"
|
|
319
|
-
echo " Max workers: $MAX_WORKERS"
|
|
320
|
-
echo " Lock timeout: $LOCK_TIMEOUT"
|
|
321
|
-
echo " Auto ideate: $AUTO_IDEATE"
|
|
322
|
-
echo " Max retries: $MAX_RETRIES"
|
|
323
|
-
echo " Memory limit: ${MEMORY_LIMIT_MB}MB"
|
|
324
|
-
echo " LLM configuration:"
|
|
325
|
-
# Show LLM configurations using dynamic variable names
|
|
326
|
-
for model in gpt5high o3high codex gemini opus opus_think sonnet sonnet_think cursor_sonnet cursor_opus glm deepseek; do
|
|
327
|
-
var_name="LLM_CLI_${model}"
|
|
328
|
-
var_value=$(eval echo "\$$var_name")
|
|
329
|
-
if [[ -n "$var_value" ]]; then
|
|
330
|
-
# Convert underscore back to dash for display
|
|
331
|
-
display_name=$(echo "$model" | sed 's/_/-/g')
|
|
332
|
-
echo " $display_name: $var_value"
|
|
333
|
-
fi
|
|
334
|
-
done
|
|
335
|
-
echo " LLM for run: $LLM_RUN"
|
|
336
|
-
echo " LLM for ideate: $LLM_IDEATE"
|
|
337
|
-
}
|