claude-evolve 1.1.3 → 1.2.0

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.
@@ -9,54 +9,56 @@ source "$SCRIPT_DIR/../lib/config.sh"
9
9
  load_config
10
10
 
11
11
  # Parse arguments
12
- count=20
12
+ use_strategies=true
13
13
  no_ai=false
14
14
 
15
15
  while [[ $# -gt 0 ]]; do
16
16
  case $1 in
17
17
  --help)
18
18
  cat <<EOF
19
- claude-evolve ideate - Generate new algorithm ideas
19
+ claude-evolve ideate - Generate new algorithm ideas using evolutionary strategies
20
20
 
21
21
  USAGE:
22
- claude-evolve ideate [N] [--no-ai]
23
-
24
- ARGUMENTS:
25
- N Number of ideas to generate (default: 20, max: 50)
22
+ claude-evolve ideate [--legacy N] [--no-ai]
26
23
 
27
24
  OPTIONS:
28
- --no-ai Use manual entry mode instead of AI generation
29
- --help Show this help message
25
+ --legacy N Use legacy mode with N ideas (ignores strategy config)
26
+ --no-ai Use manual entry mode instead of AI generation
27
+ --help Show this help message
30
28
 
31
29
  DESCRIPTION:
32
- Generates new algorithm variations by prompting Claude with context
33
- from the project BRIEF.md and top performers from evolution.csv.
34
- Falls back to manual entry if --no-ai is specified or Claude fails.
30
+ Generates algorithm ideas using multi-strategy evolutionary approach:
31
+ - Novel exploration: Pure creativity, global search
32
+ - Hill climbing: Parameter tuning of top performers
33
+ - Structural mutation: Algorithmic changes to top performers
34
+ - Crossover hybrid: Combine successful approaches
35
+
36
+ Strategy distribution is configured in evolution/config.yaml
35
37
  EOF
36
38
  exit 0
37
39
  ;;
38
- --no-ai)
39
- no_ai=true
40
+ --legacy)
41
+ use_strategies=false
40
42
  shift
41
- ;;
42
- *)
43
43
  if [[ $1 =~ ^[0-9]+$ ]]; then
44
- count=$1
44
+ TOTAL_IDEAS=$1
45
+ shift
45
46
  else
46
- echo "[ERROR] Invalid number of ideas: $1" >&2
47
+ echo "[ERROR] --legacy requires a number" >&2
47
48
  exit 1
48
49
  fi
50
+ ;;
51
+ --no-ai)
52
+ no_ai=true
49
53
  shift
50
54
  ;;
55
+ *)
56
+ echo "[ERROR] Unknown option: $1" >&2
57
+ exit 1
58
+ ;;
51
59
  esac
52
60
  done
53
61
 
54
- # Validate count
55
- if [[ $count -lt 1 || $count -gt 50 ]]; then
56
- echo "[ERROR] Number of ideas must be between 1 and 50" >&2
57
- exit 1
58
- fi
59
-
60
62
  # Check workspace using config
61
63
  if [[ ! -d "$FULL_EVOLUTION_DIR" ]]; then
62
64
  echo "[ERROR] Evolution workspace not found: $FULL_EVOLUTION_DIR. Run 'claude-evolve setup' first." >&2
@@ -68,6 +70,16 @@ if [[ ! -f "$FULL_CSV_PATH" ]]; then
68
70
  echo "id,basedOnId,description,performance,status" >"$FULL_CSV_PATH"
69
71
  fi
70
72
 
73
+ # Validate strategy configuration
74
+ if [[ $use_strategies == true ]]; then
75
+ local total_check=$((NOVEL_EXPLORATION + HILL_CLIMBING + STRUCTURAL_MUTATION + CROSSOVER_HYBRID))
76
+ if [[ $total_check -ne $TOTAL_IDEAS ]]; then
77
+ echo "[ERROR] Strategy counts don't sum to total_ideas ($total_check != $TOTAL_IDEAS)" >&2
78
+ echo "Check your evolution/config.yaml configuration" >&2
79
+ exit 1
80
+ fi
81
+ fi
82
+
71
83
  # Get next ID
72
84
  get_next_id() {
73
85
  if [[ ! -f "$FULL_CSV_PATH" ]]; then
@@ -87,6 +99,7 @@ get_next_id() {
87
99
  # Add idea to CSV
88
100
  add_idea() {
89
101
  local description="$1"
102
+ local based_on_id="$2"
90
103
  local id
91
104
  id=$(get_next_id)
92
105
 
@@ -94,19 +107,33 @@ add_idea() {
94
107
  local escaped_desc="${description//\"/\"\"}"
95
108
 
96
109
  # Append to CSV
97
- echo "${id},,\"${escaped_desc}\",," >>"$FULL_CSV_PATH"
110
+ echo "${id},${based_on_id},\"${escaped_desc}\",," >>"$FULL_CSV_PATH"
98
111
  echo "[INFO] Added idea: $description"
99
112
  }
100
113
 
114
+ # Get top performers for parent selection
115
+ get_top_performers() {
116
+ local num_requested="$1"
117
+ if [[ ! -f "$FULL_CSV_PATH" ]]; then
118
+ echo ""
119
+ return
120
+ fi
121
+
122
+ # Get completed algorithms with performance scores, sort by performance descending
123
+ awk -F, 'NR > 1 && $4 != "" && $5 == "complete" { print $1 "," $3 "," $4 }' "$FULL_CSV_PATH" | \
124
+ sort -t, -k3 -nr | \
125
+ head -n "$num_requested"
126
+ }
127
+
101
128
  # Manual entry mode
102
129
  ideate_manual() {
103
130
  local ideas_added=0
104
131
 
105
- for ((i = 1; i <= count; i++)); do
106
- if [[ $count -eq 1 ]]; then
132
+ for ((i = 1; i <= TOTAL_IDEAS; i++)); do
133
+ if [[ $TOTAL_IDEAS -eq 1 ]]; then
107
134
  read -r -p "Enter algorithm idea (or empty to skip): " description
108
135
  else
109
- read -r -p "Enter algorithm idea $i/$count (or empty to skip): " description
136
+ read -r -p "Enter algorithm idea $i/$TOTAL_IDEAS (or empty to skip): " description
110
137
  fi
111
138
 
112
139
  if [[ -z $description ]]; then
@@ -114,10 +141,10 @@ ideate_manual() {
114
141
  continue
115
142
  fi
116
143
 
117
- add_idea "$description"
144
+ add_idea "$description" ""
118
145
  ((ideas_added++))
119
146
 
120
- if [[ $i -lt $count ]]; then
147
+ if [[ $i -lt $TOTAL_IDEAS ]]; then
121
148
  read -r -p "Add another idea? (y/N) " continue_adding
122
149
  if [[ $continue_adding != "y" && $continue_adding != "Y" ]]; then
123
150
  break
@@ -128,8 +155,169 @@ ideate_manual() {
128
155
  echo "[INFO] Added $ideas_added idea(s) to $EVOLUTION_CSV"
129
156
  }
130
157
 
131
- # AI generation mode
132
- ideate_ai() {
158
+ # Generate ideas using AI with multi-strategy approach
159
+ ideate_ai_strategies() {
160
+ # Check for claude CLI
161
+ if ! command -v claude >/dev/null 2>&1; then
162
+ echo "[WARN] Claude CLI not found. Falling back to manual entry."
163
+ return 1
164
+ fi
165
+
166
+ if [[ ! -f "$FULL_BRIEF_PATH" ]]; then
167
+ echo "[WARN] $BRIEF_FILE not found. Falling back to manual entry."
168
+ return 1
169
+ fi
170
+
171
+ # Get top performers
172
+ local top_performers
173
+ top_performers=$(get_top_performers "$NUM_ELITES")
174
+
175
+ if [[ -z $top_performers ]]; then
176
+ echo "[INFO] No completed algorithms found, using pure novel exploration"
177
+ # Generate all ideas as novel exploration
178
+ generate_novel_ideas "$TOTAL_IDEAS" ""
179
+ return 0
180
+ fi
181
+
182
+ echo "[INFO] Generating $TOTAL_IDEAS ideas using multi-strategy approach:"
183
+ echo " Novel exploration: $NOVEL_EXPLORATION"
184
+ echo " Hill climbing: $HILL_CLIMBING"
185
+ echo " Structural mutation: $STRUCTURAL_MUTATION"
186
+ echo " Crossover hybrid: $CROSSOVER_HYBRID"
187
+
188
+ # Generate each type of idea
189
+ [[ $NOVEL_EXPLORATION -gt 0 ]] && generate_novel_ideas "$NOVEL_EXPLORATION" ""
190
+ [[ $HILL_CLIMBING -gt 0 ]] && generate_hill_climbing_ideas "$HILL_CLIMBING" "$top_performers"
191
+ [[ $STRUCTURAL_MUTATION -gt 0 ]] && generate_structural_mutation_ideas "$STRUCTURAL_MUTATION" "$top_performers"
192
+ [[ $CROSSOVER_HYBRID -gt 0 ]] && generate_crossover_ideas "$CROSSOVER_HYBRID" "$top_performers"
193
+ }
194
+
195
+ # Generate novel exploration ideas
196
+ generate_novel_ideas() {
197
+ local count="$1"
198
+ local context="$2"
199
+
200
+ local prompt="Generate $count completely novel algorithm approaches for this problem.
201
+ Think outside the box - consider entirely different algorithmic paradigms, data structures, or mathematical approaches.
202
+
203
+ Project Brief:
204
+ $(cat "$FULL_BRIEF_PATH")
205
+
206
+ $context
207
+
208
+ Provide $count creative, innovative ideas that explore fundamentally different solution approaches.
209
+ Format: One idea per line, no numbering, no extra formatting."
210
+
211
+ generate_and_add_ideas "$prompt" "$count" ""
212
+ }
213
+
214
+ # Generate hill climbing ideas (parameter tuning)
215
+ generate_hill_climbing_ideas() {
216
+ local count="$1"
217
+ local top_performers="$2"
218
+
219
+ local prompt="Generate $count parameter optimization ideas based on these successful algorithms:
220
+
221
+ $top_performers
222
+
223
+ Project Brief:
224
+ $(cat "$FULL_BRIEF_PATH")
225
+
226
+ Focus on tuning parameters, constants, thresholds, sizes, iteration counts, and optimization parameters.
227
+ Make small incremental improvements to the existing successful approaches.
228
+ Format: One idea per line, no numbering, no extra formatting."
229
+
230
+ # Get the best performer's ID for basedOnId
231
+ local best_id
232
+ best_id=$(echo "$top_performers" | head -1 | cut -d, -f1)
233
+
234
+ generate_and_add_ideas "$prompt" "$count" "$best_id"
235
+ }
236
+
237
+ # Generate structural mutation ideas
238
+ generate_structural_mutation_ideas() {
239
+ local count="$1"
240
+ local top_performers="$2"
241
+
242
+ local prompt="Generate $count structural algorithm modifications based on these successful algorithms:
243
+
244
+ $top_performers
245
+
246
+ Project Brief:
247
+ $(cat "$FULL_BRIEF_PATH")
248
+
249
+ Keep the core algorithmic insights but redesign the implementation approach.
250
+ Consider: different data structures, alternative algorithms for sub-components, different execution patterns.
251
+ Format: One idea per line, no numbering, no extra formatting."
252
+
253
+ # Get the best performer's ID for basedOnId
254
+ local best_id
255
+ best_id=$(echo "$top_performers" | head -1 | cut -d, -f1)
256
+
257
+ generate_and_add_ideas "$prompt" "$count" "$best_id"
258
+ }
259
+
260
+ # Generate crossover hybrid ideas
261
+ generate_crossover_ideas() {
262
+ local count="$1"
263
+ local top_performers="$2"
264
+
265
+ local prompt="Generate $count hybrid algorithms that combine successful approaches from these top performers:
266
+
267
+ $top_performers
268
+
269
+ Project Brief:
270
+ $(cat "$FULL_BRIEF_PATH")
271
+
272
+ Create novel combinations that merge the best aspects of different successful algorithms.
273
+ Consider: what makes each successful? How could they complement each other?
274
+ Format: One idea per line, no numbering, no extra formatting."
275
+
276
+ # Use the top two performers for crossover
277
+ local parent_ids
278
+ parent_ids=$(echo "$top_performers" | head -2 | cut -d, -f1 | tr '\n' '+' | sed 's/+$//')
279
+
280
+ generate_and_add_ideas "$prompt" "$count" "$parent_ids"
281
+ }
282
+
283
+ # Helper function to generate and add ideas using Claude
284
+ generate_and_add_ideas() {
285
+ local prompt="$1"
286
+ local count="$2"
287
+ local based_on_id="$3"
288
+
289
+ # Call Claude and process response
290
+ local response
291
+ if ! response=$(echo "$prompt" | claude --dangerously-skip-permissions --model opus -p 2>&1); then
292
+ echo "[WARN] Claude API call failed for $count ideas" >&2
293
+ return 1
294
+ fi
295
+
296
+ local ideas_added=0
297
+ while IFS= read -r line; do
298
+ # Clean up line
299
+ line=$(echo "$line" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
300
+ [[ -z $line ]] && continue
301
+
302
+ # Remove numbering/bullets
303
+ line=$(echo "$line" | sed 's/^[0-9]*\. *//;s/^[-*] *//')
304
+
305
+ add_idea "$line" "$based_on_id"
306
+ ((ideas_added++))
307
+
308
+ [[ $ideas_added -ge $count ]] && break
309
+ done <<<"$response"
310
+
311
+ if [[ $ideas_added -eq 0 ]]; then
312
+ echo "[WARN] No valid ideas extracted from Claude response" >&2
313
+ return 1
314
+ fi
315
+
316
+ echo "[INFO] Generated $ideas_added ideas of requested type"
317
+ }
318
+
319
+ # Legacy AI generation mode (for backward compatibility)
320
+ ideate_ai_legacy() {
133
321
  # Check for claude CLI
134
322
  if ! command -v claude >/dev/null 2>&1; then
135
323
  echo "[WARN] Claude CLI not found. Falling back to manual entry."
@@ -150,7 +338,7 @@ ideate_ai() {
150
338
 
151
339
  # Build prompt
152
340
  local prompt
153
- prompt="It's time for your megathinking mode! You are helping with algorithm evolution. Generate exactly $count new algorithm idea(s) based on the following context.
341
+ prompt="It's time for your megathinking mode! You are helping with algorithm evolution. Generate exactly $TOTAL_IDEAS new algorithm idea(s) based on the following context.
154
342
 
155
343
  Project Brief:
156
344
  $(cat "$FULL_BRIEF_PATH")
@@ -164,12 +352,12 @@ $top_performers
164
352
  fi
165
353
 
166
354
  prompt+="
167
- Generate $count creative algorithm variation(s) that could potentially improve performance.
355
+ Generate $TOTAL_IDEAS creative algorithm variation(s) that could potentially improve performance.
168
356
  For each idea, provide a single line description that explains the approach.
169
357
  Base it on the top algorithms by their ID.
170
358
  Format: One idea per line, no numbering, no extra formatting."
171
359
 
172
- echo "[INFO] Generating $count idea(s) with Claude..."
360
+ echo "[INFO] Generating $TOTAL_IDEAS idea(s) with Claude (legacy mode)..."
173
361
 
174
362
  # Call Claude and process response
175
363
  local response
@@ -187,10 +375,10 @@ Format: One idea per line, no numbering, no extra formatting."
187
375
  # Remove numbering/bullets
188
376
  line=$(echo "$line" | sed 's/^[0-9]*\. *//;s/^[-*] *//')
189
377
 
190
- add_idea "$line"
378
+ add_idea "$line" ""
191
379
  ((ideas_added++))
192
380
 
193
- [[ $ideas_added -ge $count ]] && break
381
+ [[ $ideas_added -ge $TOTAL_IDEAS ]] && break
194
382
  done <<<"$response"
195
383
 
196
384
  if [[ $ideas_added -eq 0 ]]; then
@@ -205,9 +393,16 @@ Format: One idea per line, no numbering, no extra formatting."
205
393
  if [[ $no_ai == true ]]; then
206
394
  echo "[INFO] Manual entry mode"
207
395
  ideate_manual
208
- else
209
- if ! ideate_ai; then
396
+ elif [[ $use_strategies == true ]]; then
397
+ echo "[INFO] Multi-strategy AI generation mode"
398
+ if ! ideate_ai_strategies; then
210
399
  echo "[INFO] Falling back to manual entry"
211
400
  ideate_manual
212
401
  fi
213
- fi
402
+ else
403
+ echo "[INFO] Legacy AI generation mode"
404
+ if ! ideate_ai_legacy; then
405
+ echo "[INFO] Falling back to manual entry"
406
+ ideate_manual
407
+ fi
408
+ fi
package/lib/config.sh CHANGED
@@ -9,9 +9,16 @@ DEFAULT_BRIEF_FILE="BRIEF.md"
9
9
  DEFAULT_EVOLUTION_CSV="evolution.csv"
10
10
  DEFAULT_OUTPUT_DIR=""
11
11
  DEFAULT_PARENT_SELECTION="best"
12
- DEFAULT_MAX_IDEAS=50
13
12
  DEFAULT_PYTHON_CMD="python3"
14
13
 
14
+ # Default ideation strategy values
15
+ DEFAULT_TOTAL_IDEAS=15
16
+ DEFAULT_NOVEL_EXPLORATION=3
17
+ DEFAULT_HILL_CLIMBING=5
18
+ DEFAULT_STRUCTURAL_MUTATION=3
19
+ DEFAULT_CROSSOVER_HYBRID=4
20
+ DEFAULT_NUM_ELITES=3
21
+
15
22
  # Load configuration from config file
16
23
  load_config() {
17
24
  # Set defaults first
@@ -22,8 +29,15 @@ load_config() {
22
29
  EVOLUTION_CSV="$DEFAULT_EVOLUTION_CSV"
23
30
  OUTPUT_DIR="$DEFAULT_OUTPUT_DIR"
24
31
  PARENT_SELECTION="$DEFAULT_PARENT_SELECTION"
25
- MAX_IDEAS="$DEFAULT_MAX_IDEAS"
26
32
  PYTHON_CMD="$DEFAULT_PYTHON_CMD"
33
+
34
+ # Set ideation strategy defaults
35
+ TOTAL_IDEAS="$DEFAULT_TOTAL_IDEAS"
36
+ NOVEL_EXPLORATION="$DEFAULT_NOVEL_EXPLORATION"
37
+ HILL_CLIMBING="$DEFAULT_HILL_CLIMBING"
38
+ STRUCTURAL_MUTATION="$DEFAULT_STRUCTURAL_MUTATION"
39
+ CROSSOVER_HYBRID="$DEFAULT_CROSSOVER_HYBRID"
40
+ NUM_ELITES="$DEFAULT_NUM_ELITES"
27
41
 
28
42
  # Single config file location: evolution/config.yaml
29
43
  local config_file="evolution/config.yaml"
@@ -31,7 +45,8 @@ load_config() {
31
45
  # Load config if found
32
46
  if [[ -f "$config_file" ]]; then
33
47
  echo "[INFO] Loading configuration from: $config_file"
34
- # Simple YAML parsing for key: value pairs
48
+ # Simple YAML parsing for key: value pairs and nested structures
49
+ local in_ideation_section=false
35
50
  while IFS=': ' read -r key value; do
36
51
  # Skip comments and empty lines
37
52
  [[ $key =~ ^[[:space:]]*# ]] || [[ -z $key ]] && continue
@@ -43,17 +58,38 @@ load_config() {
43
58
  # Remove quotes from value
44
59
  value=$(echo "$value" | sed 's/^"//;s/"$//')
45
60
 
46
- case $key in
47
- evolution_dir) EVOLUTION_DIR="$value" ;;
48
- algorithm_file) ALGORITHM_FILE="$value" ;;
49
- evaluator_file) EVALUATOR_FILE="$value" ;;
50
- brief_file) BRIEF_FILE="$value" ;;
51
- evolution_csv) EVOLUTION_CSV="$value" ;;
52
- output_dir) OUTPUT_DIR="$value" ;;
53
- parent_selection) PARENT_SELECTION="$value" ;;
54
- max_ideas) MAX_IDEAS="$value" ;;
55
- python_cmd) PYTHON_CMD="$value" ;;
56
- esac
61
+ # Handle nested ideation_strategies section
62
+ if [[ $key == "ideation_strategies" ]]; then
63
+ in_ideation_section=true
64
+ continue
65
+ elif [[ $key =~ ^[a-z_]+ ]] && [[ $in_ideation_section == true ]]; then
66
+ # Top-level key found, exit ideation section
67
+ in_ideation_section=false
68
+ fi
69
+
70
+ if [[ $in_ideation_section == true ]]; then
71
+ # Handle indented keys in ideation_strategies
72
+ case $key in
73
+ total_ideas) TOTAL_IDEAS="$value" ;;
74
+ novel_exploration) NOVEL_EXPLORATION="$value" ;;
75
+ hill_climbing) HILL_CLIMBING="$value" ;;
76
+ structural_mutation) STRUCTURAL_MUTATION="$value" ;;
77
+ crossover_hybrid) CROSSOVER_HYBRID="$value" ;;
78
+ num_elites) NUM_ELITES="$value" ;;
79
+ esac
80
+ else
81
+ # Handle top-level keys
82
+ case $key in
83
+ evolution_dir) EVOLUTION_DIR="$value" ;;
84
+ algorithm_file) ALGORITHM_FILE="$value" ;;
85
+ evaluator_file) EVALUATOR_FILE="$value" ;;
86
+ brief_file) BRIEF_FILE="$value" ;;
87
+ evolution_csv) EVOLUTION_CSV="$value" ;;
88
+ output_dir) OUTPUT_DIR="$value" ;;
89
+ parent_selection) PARENT_SELECTION="$value" ;;
90
+ python_cmd) PYTHON_CMD="$value" ;;
91
+ esac
92
+ fi
57
93
  done < "$config_file"
58
94
  fi
59
95
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-evolve",
3
- "version": "1.1.3",
3
+ "version": "1.2.0",
4
4
  "bin": {
5
5
  "claude-evolve": "./bin/claude-evolve",
6
6
  "claude-evolve-main": "./bin/claude-evolve-main",
@@ -20,8 +20,19 @@ output_dir: ""
20
20
  # Options: "best", "random", "latest"
21
21
  parent_selection: "best"
22
22
 
23
- # Maximum number of ideas to generate at once
24
- max_ideas: 50
23
+ # Multi-strategy ideation configuration
24
+ ideation_strategies:
25
+ # Total ideas per generation
26
+ total_ideas: 15
27
+
28
+ # Strategy distribution (must sum to total_ideas)
29
+ novel_exploration: 3 # Pure creativity, global search
30
+ hill_climbing: 5 # Parameter tuning of top performers
31
+ structural_mutation: 3 # Algorithmic changes to top performers
32
+ crossover_hybrid: 4 # Combine successful approaches
33
+
34
+ # Number of top performers to use as parents
35
+ num_elites: 3
25
36
 
26
37
  # Python command to use for evaluation
27
38
  python_cmd: "python3"