claude-evolve 1.5.14 → 1.5.16

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.
@@ -167,7 +167,7 @@ class AutoStatus:
167
167
  # Track by generation
168
168
  if gen not in stats_by_gen:
169
169
  stats_by_gen[gen] = {
170
- "pending": 0, "complete": 0, "failed": 0, "running": 0,
170
+ "pending": 0, "complete": 0, "failed": 0, "running": 0, "skipped": 0,
171
171
  "candidates": []
172
172
  }
173
173
 
@@ -266,8 +266,8 @@ class AutoStatus:
266
266
  if generations:
267
267
  # Table header
268
268
  self.display.move_cursor(row, 1)
269
- header_fmt = "{:<10} | {:^20} | {:>10} | {:>8} | {}".format(
270
- "Generation", "Stats (p/c/f/r)", "Top ID", "Score", "Description"
269
+ header_fmt = "{:<10} | {:^25} | {:>10} | {:>8} | {}".format(
270
+ "Generation", "Stats (p/c/f/r/s)", "Top ID", "Score", "Description"
271
271
  )
272
272
  print("\033[1m" + header_fmt[:self.display.cols] + "\033[0m")
273
273
  row += 1
@@ -302,6 +302,8 @@ class AutoStatus:
302
302
 
303
303
  gen_data = generations[gen]
304
304
  stats_str = f"{gen_data['\''pending'\'']}/{gen_data['\''complete'\'']}/{gen_data['\''failed'\'']}/{gen_data['\''running'\'']}"
305
+ if gen_data['\''skipped'\''] > 0:
306
+ stats_str += f"/{gen_data['\''skipped'\'']}"
305
307
 
306
308
  self.display.move_cursor(row, 1)
307
309
 
@@ -314,15 +316,15 @@ class AutoStatus:
314
316
 
315
317
  # Highlight if this is the overall leader
316
318
  if data["leader"] and best_id == data["leader"][0]:
317
- line = "{:<10} | {:^20} | \033[32m{:>10}\033[0m | {:>8.4f} | {}".format(
319
+ line = "{:<10} | {:^25} | \033[32m{:>10}\033[0m | {:>8.4f} | {}".format(
318
320
  gen, stats_str, best_id, best_score, best_desc
319
321
  )
320
322
  else:
321
- line = "{:<10} | {:^20} | {:>10} | {:>8.4f} | {}".format(
323
+ line = "{:<10} | {:^25} | {:>10} | {:>8.4f} | {}".format(
322
324
  gen, stats_str, best_id, best_score, best_desc
323
325
  )
324
326
  else:
325
- line = "{:<10} | {:^20} | {:>10} | {:>8} | {}".format(
327
+ line = "{:<10} | {:^25} | {:>10} | {:>8} | {}".format(
326
328
  gen, stats_str, "-", "-", "No completed candidates"
327
329
  )
328
330
 
@@ -39,11 +39,13 @@ SELECTORS:
39
39
  complete Target all candidates with complete status
40
40
  pending Target all candidates with pending status
41
41
  running Target all candidates with running status
42
+ skipped Target all candidates with skipped status
42
43
 
43
44
  ACTIONS:
44
45
  failed Mark candidates as failed (keeps scores)
45
- complete Mark candidates as complete (keeps scores)
46
+ complete Mark candidates as complete (keeps scores)
46
47
  pending Mark candidates as pending (clears all data)
48
+ skipped Mark candidates as skipped (keeps scores)
47
49
  failed-retry1 Mark candidates for retry attempt 1 (bug fixing)
48
50
  failed-retry2 Mark candidates for retry attempt 2 (bug fixing)
49
51
  failed-retry3 Mark candidates for retry attempt 3 (bug fixing)
@@ -53,6 +55,7 @@ ACTIONS:
53
55
  EXAMPLES:
54
56
  claude-evolve edit gen03 failed # Mark all gen03 as failed
55
57
  claude-evolve edit failed pending # Reset all failed candidates to pending
58
+ claude-evolve edit pending skipped # Skip all pending candidates
56
59
  claude-evolve edit --recent-generations=15 failed pending # Reset only recent 15 gen failures
57
60
  claude-evolve edit --recent-generations=5 complete failed # Re-run recent 5 gen completions
58
61
  claude-evolve edit failed failed-retry1 # Convert failed to retry status (bug fixing)
@@ -109,16 +112,16 @@ if ! validate_config; then
109
112
  fi
110
113
 
111
114
  # Validate selector format
112
- if [[ "$SELECTOR" != "all" && ! "$SELECTOR" =~ ^gen[0-9]+$ && "$SELECTOR" != "failed" && "$SELECTOR" != "complete" && "$SELECTOR" != "pending" && "$SELECTOR" != "running" ]]; then
113
- echo "[ERROR] Selector must be 'all', 'genXX' (e.g., gen01), or status ('failed', 'complete', 'pending', 'running')" >&2
115
+ if [[ "$SELECTOR" != "all" && ! "$SELECTOR" =~ ^gen[0-9]+$ && "$SELECTOR" != "failed" && "$SELECTOR" != "complete" && "$SELECTOR" != "pending" && "$SELECTOR" != "running" && "$SELECTOR" != "skipped" ]]; then
116
+ echo "[ERROR] Selector must be 'all', 'genXX' (e.g., gen01), or status ('failed', 'complete', 'pending', 'running', 'skipped')" >&2
114
117
  exit 1
115
118
  fi
116
119
 
117
120
  # Validate action
118
121
  case "$ACTION" in
119
- failed|complete|pending|failed-retry1|failed-retry2|failed-retry3|reboot|delete) ;;
122
+ failed|complete|pending|skipped|failed-retry1|failed-retry2|failed-retry3|reboot|delete) ;;
120
123
  *)
121
- echo "[ERROR] Action must be one of: failed, complete, pending, failed-retry1, failed-retry2, failed-retry3, reboot, delete" >&2
124
+ echo "[ERROR] Action must be one of: failed, complete, pending, skipped, failed-retry1, failed-retry2, failed-retry3, reboot, delete" >&2
122
125
  exit 1
123
126
  ;;
124
127
  esac
@@ -210,7 +213,7 @@ try:
210
213
  elif selector.startswith('gen') and '-' in candidate_id:
211
214
  # Generation selector (e.g., gen01, gen02)
212
215
  matches = candidate_id.startswith(selector + '-')
213
- elif selector in ['failed', 'complete', 'pending', 'running']:
216
+ elif selector in ['failed', 'complete', 'pending', 'running', 'skipped']:
214
217
  # Status selector
215
218
  if selector == 'pending':
216
219
  matches = current_status == '' or current_status == 'pending'
@@ -362,6 +365,8 @@ try:
362
365
  matches = current_status == '' or current_status == 'pending'
363
366
  elif selector == 'failed':
364
367
  matches = current_status.startswith('failed')
368
+ elif selector == 'skipped':
369
+ matches = current_status == 'skipped'
365
370
  else:
366
371
  matches = current_status == selector
367
372
 
@@ -480,6 +485,8 @@ with EvolutionCSV('$FULL_CSV_PATH') as csv:
480
485
  matches = current_status == '' or current_status == 'pending'
481
486
  elif selector == 'failed':
482
487
  matches = current_status.startswith('failed')
488
+ elif selector == 'skipped':
489
+ matches = current_status == 'skipped'
483
490
  else:
484
491
  matches = current_status == selector
485
492
 
@@ -525,6 +532,9 @@ case "$ACTION" in
525
532
  pending)
526
533
  update_candidates_status "$SELECTOR" "pending" "true" # Clear all data and set to pending
527
534
  ;;
535
+ skipped)
536
+ update_candidates_status "$SELECTOR" "skipped" "false" # Keep scores and set to skipped
537
+ ;;
528
538
  failed-retry1)
529
539
  update_candidates_status "$SELECTOR" "failed-retry1" "false"
530
540
  ;;
@@ -145,7 +145,7 @@ try:
145
145
  all_candidates = []
146
146
  stats_by_gen = {}
147
147
  winners_by_gen = {}
148
- total_stats = {'pending': 0, 'complete': 0, 'failed': 0, 'running': 0}
148
+ total_stats = {'pending': 0, 'complete': 0, 'failed': 0, 'running': 0, 'skipped': 0}
149
149
  retry_count = 0
150
150
 
151
151
  def parse_candidate_id(cid):
@@ -184,7 +184,7 @@ try:
184
184
 
185
185
  # Track by generation
186
186
  if gen not in stats_by_gen:
187
- stats_by_gen[gen] = {'pending': 0, 'complete': 0, 'failed': 0, 'running': 0}
187
+ stats_by_gen[gen] = {'pending': 0, 'complete': 0, 'failed': 0, 'running': 0, 'skipped': 0}
188
188
 
189
189
  if normalized_status in stats_by_gen[gen]:
190
190
  stats_by_gen[gen][normalized_status] += 1
@@ -244,7 +244,10 @@ try:
244
244
  if retry_count > 0:
245
245
  failed_display += f' ({retry_count} retries)'
246
246
  print(f' • {failed_display}')
247
- print(f' • {total_stats[\"running\"]} running')
247
+ if total_stats['running'] > 0:
248
+ print(f' • {total_stats[\"running\"]} running')
249
+ if total_stats['skipped'] > 0:
250
+ print(f' • {total_stats[\"skipped\"]} skipped')
248
251
  print()
249
252
 
250
253
  # Show current winner
@@ -290,6 +293,8 @@ try:
290
293
  gen_best = winners_by_gen.get(gen)
291
294
 
292
295
  status_str = f'{data[\"pending\"]}p {data[\"complete\"]}c {data[\"failed\"]}f {data[\"running\"]}r'
296
+ if data['skipped'] > 0:
297
+ status_str += f' {data[\"skipped\"]}s'
293
298
 
294
299
  if gen_best:
295
300
  # Check if this generation's best is the overall winner
@@ -133,19 +133,21 @@ class EvolutionCSV:
133
133
  return False
134
134
 
135
135
  def get_pending_candidates(self) -> List[Tuple[str, str]]:
136
- """Get list of pending candidate IDs and their current status."""
136
+ """Get list of pending candidate IDs and their current status (in reverse order)."""
137
137
  rows = self._read_csv()
138
138
  pending = []
139
-
139
+
140
140
  # Skip header row if it exists
141
141
  start_idx = 1 if rows and rows[0] and rows[0][0].lower() == 'id' else 0
142
-
143
- for row in rows[start_idx:]:
142
+
143
+ # Process in reverse order to match get_next_pending_candidate
144
+ for i in range(len(rows) - 1, start_idx - 1, -1):
145
+ row = rows[i]
144
146
  if self.is_pending_candidate(row):
145
147
  candidate_id = row[0].strip()
146
148
  current_status = row[4].strip() if len(row) > 4 else ''
147
149
  pending.append((candidate_id, current_status))
148
-
150
+
149
151
  return pending
150
152
 
151
153
  def count_pending_candidates(self) -> int:
@@ -156,33 +158,35 @@ class EvolutionCSV:
156
158
  """
157
159
  Get the next pending candidate and mark it as 'running'.
158
160
  Returns (candidate_id, original_status) or None if no pending work.
161
+ Processes candidates in REVERSE order (from end to beginning).
159
162
  """
160
163
  rows = self._read_csv()
161
164
  if not rows:
162
165
  return None
163
-
166
+
164
167
  # Skip header row if it exists
165
168
  start_idx = 1 if rows and rows[0] and rows[0][0].lower() == 'id' else 0
166
-
167
- for i in range(start_idx, len(rows)):
169
+
170
+ # Process in reverse order - from last row to first data row
171
+ for i in range(len(rows) - 1, start_idx - 1, -1):
168
172
  row = rows[i]
169
-
173
+
170
174
  if self.is_pending_candidate(row):
171
175
  candidate_id = row[0].strip()
172
176
  original_status = row[4].strip() if len(row) > 4 else ''
173
-
177
+
174
178
  # Ensure row has at least 5 columns
175
179
  while len(row) < 5:
176
180
  row.append('')
177
-
181
+
178
182
  # Mark as running
179
183
  row[4] = 'running'
180
-
184
+
181
185
  # Write back to CSV
182
186
  self._write_csv(rows)
183
-
187
+
184
188
  return (candidate_id, original_status)
185
-
189
+
186
190
  return None
187
191
 
188
192
  def update_candidate_status(self, candidate_id: str, new_status: str) -> bool:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-evolve",
3
- "version": "1.5.14",
3
+ "version": "1.5.16",
4
4
  "bin": {
5
5
  "claude-evolve": "./bin/claude-evolve",
6
6
  "claude-evolve-main": "./bin/claude-evolve-main",