claude-evolve 1.7.21 → 1.7.23
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 +18 -15
- package/bin/claude-evolve-ideate-py +97 -0
- package/lib/ideation_helper.py +745 -0
- package/package.json +1 -1
- package/bin/claude-evolve-ideate.debug +0 -907
package/bin/claude-evolve-ideate
CHANGED
|
@@ -107,7 +107,7 @@ call_ai_for_ideation() {
|
|
|
107
107
|
|
|
108
108
|
# Get the current row count before any modifications (from the pre-populated file with stubs)
|
|
109
109
|
local original_csv_count
|
|
110
|
-
original_csv_count=$(grep -v '^[[:space:]]*$' "$temp_csv_file" | tail -n +2 | wc -l)
|
|
110
|
+
original_csv_count=$(grep -v '^[[:space:]]*$' "$temp_csv_file" | tail -n +2 | wc -l | tr -d '[:space:]')
|
|
111
111
|
|
|
112
112
|
echo "[DEBUG] Pre-populated temp CSV has $original_csv_count rows (includes stub rows with placeholders)" >&2
|
|
113
113
|
|
|
@@ -152,7 +152,7 @@ call_ai_for_ideation() {
|
|
|
152
152
|
# Check if the file was modified correctly
|
|
153
153
|
if [[ -f "$temp_csv_file" ]]; then
|
|
154
154
|
local new_csv_count
|
|
155
|
-
new_csv_count=$(grep -v '^[[:space:]]*$' "$temp_csv_file" | tail -n +2 | wc -l)
|
|
155
|
+
new_csv_count=$(grep -v '^[[:space:]]*$' "$temp_csv_file" | tail -n +2 | wc -l | tr -d '[:space:]')
|
|
156
156
|
local added_count=$((new_csv_count - original_csv_count))
|
|
157
157
|
|
|
158
158
|
echo "[DEBUG] After $model: original=$original_csv_count, new=$new_csv_count, added=$added_count" >&2
|
|
@@ -162,6 +162,9 @@ call_ai_for_ideation() {
|
|
|
162
162
|
# Count remaining placeholders - there should be none if AI did its job
|
|
163
163
|
local placeholder_count
|
|
164
164
|
placeholder_count=$(grep -c "PLACEHOLDER" "$temp_csv_file" 2>/dev/null || echo "0")
|
|
165
|
+
# Strip whitespace and ensure we have a clean integer
|
|
166
|
+
placeholder_count=$(echo "$placeholder_count" | tr -d '[:space:]')
|
|
167
|
+
placeholder_count=${placeholder_count:-0}
|
|
165
168
|
|
|
166
169
|
if [[ $placeholder_count -eq 0 ]]; then
|
|
167
170
|
echo "[INFO] CSV modified by $model: filled $expected_count placeholder rows ✓" >&2
|
|
@@ -377,11 +380,11 @@ validate_direct_csv_modification() {
|
|
|
377
380
|
# We need to track this before the AI runs by reading from the beginning state
|
|
378
381
|
# First, get a fresh count from the current main CSV (which reflects any previous operations in this session)
|
|
379
382
|
local current_original_count
|
|
380
|
-
current_original_count=$(grep -v '^[[:space:]]*$' "$FULL_CSV_PATH" | tail -n +2 | wc -l)
|
|
383
|
+
current_original_count=$(grep -v '^[[:space:]]*$' "$FULL_CSV_PATH" | tail -n +2 | wc -l | tr -d '[:space:]')
|
|
381
384
|
|
|
382
385
|
# Count data rows in the modified temp CSV
|
|
383
386
|
local new_count
|
|
384
|
-
new_count=$(grep -v '^[[:space:]]*$' "$temp_csv" | tail -n +2 | wc -l)
|
|
387
|
+
new_count=$(grep -v '^[[:space:]]*$' "$temp_csv" | tail -n +2 | wc -l | tr -d '[:space:]')
|
|
385
388
|
|
|
386
389
|
|
|
387
390
|
# Check if AI overwrote the file instead of appending
|
|
@@ -442,7 +445,7 @@ validate_direct_csv_modification() {
|
|
|
442
445
|
fi
|
|
443
446
|
|
|
444
447
|
# Get just the new entries (skip header and existing entries)
|
|
445
|
-
local original_line_count=$(wc -l < "$FULL_CSV_PATH")
|
|
448
|
+
local original_line_count=$(wc -l < "$FULL_CSV_PATH" | tr -d '[:space:]')
|
|
446
449
|
|
|
447
450
|
# Append only the new lines from temp CSV to the main CSV
|
|
448
451
|
tail -n +$((original_line_count + 1)) "$temp_csv" >> "$FULL_CSV_PATH"
|
|
@@ -514,9 +517,9 @@ validate_and_apply_csv_modification_old() {
|
|
|
514
517
|
|
|
515
518
|
# Validate the modified CSV has more entries than original
|
|
516
519
|
local original_count
|
|
517
|
-
original_count=$(wc -l < "$FULL_CSV_PATH")
|
|
520
|
+
original_count=$(wc -l < "$FULL_CSV_PATH" | tr -d '[:space:]')
|
|
518
521
|
local new_count
|
|
519
|
-
new_count=$(wc -l < "$temp_csv")
|
|
522
|
+
new_count=$(wc -l < "$temp_csv" | tr -d '[:space:]')
|
|
520
523
|
|
|
521
524
|
|
|
522
525
|
if [[ $new_count -le $original_count ]]; then
|
|
@@ -543,7 +546,7 @@ validate_and_apply_csv_modification_old() {
|
|
|
543
546
|
fi
|
|
544
547
|
|
|
545
548
|
# Get just the new entries (skip header and existing entries)
|
|
546
|
-
local original_line_count=$(wc -l < "$FULL_CSV_PATH")
|
|
549
|
+
local original_line_count=$(wc -l < "$FULL_CSV_PATH" | tr -d '[:space:]')
|
|
547
550
|
|
|
548
551
|
# Append only the new lines from temp CSV to the main CSV
|
|
549
552
|
tail -n +$((original_line_count + 1)) "$temp_csv" >> "$FULL_CSV_PATH"
|
|
@@ -665,9 +668,9 @@ IMPORTANT: Output the complete modified CSV file. Do not add any explanation or
|
|
|
665
668
|
|
|
666
669
|
# Validate the modified CSV has more entries than original
|
|
667
670
|
local original_count
|
|
668
|
-
original_count=$(wc -l < "$FULL_CSV_PATH")
|
|
671
|
+
original_count=$(wc -l < "$FULL_CSV_PATH" | tr -d '[:space:]')
|
|
669
672
|
local new_count
|
|
670
|
-
new_count=$(wc -l < "$temp_csv")
|
|
673
|
+
new_count=$(wc -l < "$temp_csv" | tr -d '[:space:]')
|
|
671
674
|
|
|
672
675
|
|
|
673
676
|
if [[ $new_count -le $original_count ]]; then
|
|
@@ -696,7 +699,7 @@ IMPORTANT: Output the complete modified CSV file. Do not add any explanation or
|
|
|
696
699
|
fi
|
|
697
700
|
|
|
698
701
|
# Get just the new entries (skip header and existing entries)
|
|
699
|
-
local original_line_count=$(wc -l < "$FULL_CSV_PATH")
|
|
702
|
+
local original_line_count=$(wc -l < "$FULL_CSV_PATH" | tr -d '[:space:]')
|
|
700
703
|
|
|
701
704
|
# Append only the new lines from temp CSV to the main CSV
|
|
702
705
|
tail -n +$((original_line_count + 1)) "$temp_csv" >> "$FULL_CSV_PATH"
|
|
@@ -1007,7 +1010,7 @@ generate_novel_ideas_direct() {
|
|
|
1007
1010
|
|
|
1008
1011
|
# Count total lines in temp CSV (including header)
|
|
1009
1012
|
local total_lines
|
|
1010
|
-
total_lines=$(wc -l < "$temp_csv")
|
|
1013
|
+
total_lines=$(wc -l < "$temp_csv" | tr -d '[:space:]')
|
|
1011
1014
|
local read_offset=$((total_lines - 25))
|
|
1012
1015
|
if [[ $read_offset -lt 1 ]]; then
|
|
1013
1016
|
read_offset=1
|
|
@@ -1145,7 +1148,7 @@ generate_hill_climbing_direct() {
|
|
|
1145
1148
|
|
|
1146
1149
|
# Count total lines in temp CSV (including header)
|
|
1147
1150
|
local total_lines
|
|
1148
|
-
total_lines=$(wc -l < "$temp_csv")
|
|
1151
|
+
total_lines=$(wc -l < "$temp_csv" | tr -d '[:space:]')
|
|
1149
1152
|
local read_offset=$((total_lines - 25))
|
|
1150
1153
|
if [[ $read_offset -lt 1 ]]; then
|
|
1151
1154
|
read_offset=1
|
|
@@ -1274,7 +1277,7 @@ generate_structural_mutation_direct() {
|
|
|
1274
1277
|
|
|
1275
1278
|
# Count total lines in temp CSV (including header)
|
|
1276
1279
|
local total_lines
|
|
1277
|
-
total_lines=$(wc -l < "$temp_csv")
|
|
1280
|
+
total_lines=$(wc -l < "$temp_csv" | tr -d '[:space:]')
|
|
1278
1281
|
local read_offset=$((total_lines - 25))
|
|
1279
1282
|
if [[ $read_offset -lt 1 ]]; then
|
|
1280
1283
|
read_offset=1
|
|
@@ -1394,7 +1397,7 @@ generate_crossover_direct() {
|
|
|
1394
1397
|
|
|
1395
1398
|
# Count total lines in temp CSV (including header)
|
|
1396
1399
|
local total_lines
|
|
1397
|
-
total_lines=$(wc -l < "$temp_csv")
|
|
1400
|
+
total_lines=$(wc -l < "$temp_csv" | tr -d '[:space:]')
|
|
1398
1401
|
local read_offset=$((total_lines - 25))
|
|
1399
1402
|
if [[ $read_offset -lt 1 ]]; then
|
|
1400
1403
|
read_offset=1
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Python-based ideation wrapper for claude-evolve
|
|
3
|
+
# This is a simple wrapper that calls the Python ideation helper
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
# Load configuration to ensure paths are set up
|
|
8
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
9
|
+
# shellcheck source=../lib/config.sh
|
|
10
|
+
source "$SCRIPT_DIR/../lib/config.sh"
|
|
11
|
+
|
|
12
|
+
# Use CLAUDE_EVOLVE_CONFIG if set, otherwise default
|
|
13
|
+
if [[ -n ${CLAUDE_EVOLVE_CONFIG:-} ]]; then
|
|
14
|
+
load_config "$CLAUDE_EVOLVE_CONFIG"
|
|
15
|
+
else
|
|
16
|
+
# Check if config.yaml exists in current directory
|
|
17
|
+
if [[ -f "config.yaml" ]]; then
|
|
18
|
+
CONFIG_FILE="$(pwd)/config.yaml"
|
|
19
|
+
load_config "$CONFIG_FILE"
|
|
20
|
+
else
|
|
21
|
+
load_config
|
|
22
|
+
fi
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# Setup logging to file
|
|
26
|
+
if [[ -n "${FULL_EVOLUTION_DIR:-}" ]]; then
|
|
27
|
+
LOG_DIR="$FULL_EVOLUTION_DIR/logs"
|
|
28
|
+
mkdir -p "$LOG_DIR"
|
|
29
|
+
LOG_FILE="$LOG_DIR/ideate-py-$$-$(date +%Y%m%d-%H%M%S).log"
|
|
30
|
+
|
|
31
|
+
# Log to both terminal and file with timestamps
|
|
32
|
+
exec > >(while IFS= read -r line; do echo "$(date '+%Y-%m-%d %H:%M:%S'): $line"; done | tee -a "$LOG_FILE") 2>&1
|
|
33
|
+
echo "[IDEATE-PY-$$] Logging to: $LOG_FILE"
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Parse arguments
|
|
37
|
+
use_strategies=true
|
|
38
|
+
|
|
39
|
+
while [[ $# -gt 0 ]]; do
|
|
40
|
+
case $1 in
|
|
41
|
+
--help)
|
|
42
|
+
cat <<EOF
|
|
43
|
+
claude-evolve ideate (Python version) - Generate new algorithm ideas
|
|
44
|
+
|
|
45
|
+
USAGE:
|
|
46
|
+
claude-evolve ideate-py [--legacy N]
|
|
47
|
+
|
|
48
|
+
OPTIONS:
|
|
49
|
+
--legacy N Use legacy mode with N ideas (ignores strategy config)
|
|
50
|
+
--help Show this help message
|
|
51
|
+
|
|
52
|
+
DESCRIPTION:
|
|
53
|
+
Python-based ideation that uses MD5 hashing to verify AI actually modified files.
|
|
54
|
+
This solves the problem where AIs claim they edited files but didn't.
|
|
55
|
+
|
|
56
|
+
Uses multi-strategy evolutionary approach:
|
|
57
|
+
- Novel exploration: Pure creativity, global search
|
|
58
|
+
- Hill climbing: Parameter tuning of top performers
|
|
59
|
+
- Structural mutation: Algorithmic changes to top performers
|
|
60
|
+
- Crossover hybrid: Combine successful approaches
|
|
61
|
+
|
|
62
|
+
Strategy distribution is configured in evolution/config.yaml
|
|
63
|
+
EOF
|
|
64
|
+
exit 0
|
|
65
|
+
;;
|
|
66
|
+
--legacy)
|
|
67
|
+
use_strategies=false
|
|
68
|
+
shift
|
|
69
|
+
if [[ $1 =~ ^[0-9]+$ ]]; then
|
|
70
|
+
export LEGACY_IDEA_COUNT=$1
|
|
71
|
+
shift
|
|
72
|
+
else
|
|
73
|
+
echo "[ERROR] --legacy requires a number" >&2
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
;;
|
|
77
|
+
*)
|
|
78
|
+
echo "[ERROR] Unknown option: $1" >&2
|
|
79
|
+
exit 1
|
|
80
|
+
;;
|
|
81
|
+
esac
|
|
82
|
+
done
|
|
83
|
+
|
|
84
|
+
# Check workspace using config
|
|
85
|
+
if [[ ! -d "$FULL_EVOLUTION_DIR" ]]; then
|
|
86
|
+
echo "[ERROR] Evolution workspace not found: $FULL_EVOLUTION_DIR. Run 'claude-evolve setup' first." >&2
|
|
87
|
+
exit 1
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
# Call Python helper
|
|
91
|
+
echo "[INFO] Using Python ideation helper (more reliable AI result verification)"
|
|
92
|
+
|
|
93
|
+
if [[ $use_strategies == true ]]; then
|
|
94
|
+
exec "$PYTHON_CMD" "$SCRIPT_DIR/../lib/ideation_helper.py" run
|
|
95
|
+
else
|
|
96
|
+
exec "$PYTHON_CMD" "$SCRIPT_DIR/../lib/ideation_helper.py" run --legacy "$LEGACY_IDEA_COUNT"
|
|
97
|
+
fi
|