claude-evolve 1.3.7 → 1.3.8

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.
@@ -145,55 +145,20 @@ if [[ ! -f "$FULL_ALGORITHM_PATH" ]]; then
145
145
  exit 1
146
146
  fi
147
147
 
148
- # Find oldest pending row (pure shell)
148
+ # Find oldest pending row (using CSV helper)
149
149
  find_empty_row() {
150
- local row_num=2 # Start after header
151
- local csv_id csv_based_on csv_desc csv_perf csv_status
152
- while IFS=, read -r csv_id csv_based_on csv_desc csv_perf csv_status; do
153
- # Look for rows with pending status or empty status (but not complete/failed/running/timeout)
154
- # Treat blank status as pending
155
- if [[ $csv_status == "pending" || -z $csv_status || $csv_status == '""' ]]; then
156
- # Skip if status is explicitly complete, failed, running, or timeout
157
- if [[ $csv_status == "complete" || $csv_status == "failed" || $csv_status == "running" || $csv_status == "timeout" ]]; then
158
- ((row_num++))
159
- continue
160
- fi
161
- echo $row_num
162
- return 0
163
- fi
164
- ((row_num++))
165
- done < <(tail -n +2 "$FULL_CSV_PATH")
166
- return 1
150
+ "$PYTHON_CMD" "$SCRIPT_DIR/../lib/csv_helper.py" find_pending "$FULL_CSV_PATH"
167
151
  }
168
152
 
169
- # Get CSV row (pure shell)
170
- get_csv_row() {
171
- sed -n "${1}p" "$FULL_CSV_PATH"
172
- }
153
+ # Get CSV row - replaced by csv_helper.py
173
154
 
174
- # Update CSV row (pure shell with temp file)
155
+ # Update CSV row (using CSV helper)
175
156
  update_csv_row() {
176
157
  local row_num="$1"
177
158
  local performance="$2"
178
159
  local status="$3"
179
-
180
- # Read CSV and update specific row
181
- local temp_file="${FULL_CSV_PATH}.tmp"
182
- local current_row=1
183
- local csv_id csv_based_on csv_desc csv_perf csv_stat
184
-
185
- while IFS=, read -r csv_id csv_based_on csv_desc csv_perf csv_stat; do
186
- if [[ $current_row -eq $row_num ]]; then
187
- # Update this row
188
- echo "$csv_id,$csv_based_on,$csv_desc,$performance,$status"
189
- else
190
- # Keep original row
191
- echo "$csv_id,$csv_based_on,$csv_desc,$csv_perf,$csv_stat"
192
- fi
193
- ((current_row++))
194
- done <"$FULL_CSV_PATH" >"$temp_file"
195
-
196
- mv "$temp_file" "$FULL_CSV_PATH"
160
+
161
+ "$PYTHON_CMD" "$SCRIPT_DIR/../lib/csv_helper.py" update_row "$FULL_CSV_PATH" "$row_num" "$performance" "$status"
197
162
  }
198
163
 
199
164
  # Auto-recovery mechanism for common failures
@@ -298,21 +263,18 @@ while true; do
298
263
  # Create log file for this iteration
299
264
  LOGFILE="logs/claude-$(date +%Y%m%d_%H%M%S).txt"
300
265
 
301
- # Get row data
302
- row_data=$(get_csv_row "$row_num")
303
- IFS=, read -r id based_on_id description performance status <<<"$row_data"
266
+ # Get row data using CSV helper
267
+ eval "$("$PYTHON_CMD" "$SCRIPT_DIR/../lib/csv_helper.py" get_row "$FULL_CSV_PATH" "$row_num")"
268
+
269
+ # Variables are now set: id, basedOnId, description, performance, status
270
+ based_on_id="$basedOnId" # Convert to expected variable name
304
271
 
305
272
  # Check if ID is empty
306
273
  if [[ -z $id ]]; then
307
274
  echo "[ERROR] Empty ID found at row $row_num. CSV may be malformed." >&2
308
- echo "[ERROR] Row data: $row_data" >&2
309
275
  exit 1
310
276
  fi
311
277
 
312
- # Clean up description (remove quotes)
313
- description=${description#\"}
314
- description=${description%\"}
315
-
316
278
  echo "[INFO] Processing candidate ID: $id"
317
279
  echo "[INFO] Description: $description"
318
280
  echo "[INFO] Based on ID: $based_on_id"
@@ -0,0 +1,116 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ CSV helper for claude-evolve to properly handle CSV parsing with quoted fields.
4
+ """
5
+ import csv
6
+ import sys
7
+ import json
8
+
9
+ def find_pending_row(csv_path):
10
+ """Find the first pending row in the CSV."""
11
+ with open(csv_path, 'r') as f:
12
+ reader = csv.reader(f)
13
+ next(reader) # Skip header
14
+ for row_num, row in enumerate(reader, start=2):
15
+ # Ensure row has at least 5 fields
16
+ while len(row) < 5:
17
+ row.append('')
18
+
19
+ status = row[4].strip()
20
+ # Check if status is pending or empty
21
+ if status == 'pending' or status == '':
22
+ return row_num
23
+ return None
24
+
25
+ def get_row_data(csv_path, row_num):
26
+ """Get data from a specific row."""
27
+ with open(csv_path, 'r') as f:
28
+ reader = csv.reader(f)
29
+ for i, row in enumerate(reader, start=1):
30
+ if i == row_num:
31
+ # Ensure row has at least 5 fields
32
+ while len(row) < 5:
33
+ row.append('')
34
+ return {
35
+ 'id': row[0],
36
+ 'basedOnId': row[1],
37
+ 'description': row[2],
38
+ 'performance': row[3],
39
+ 'status': row[4]
40
+ }
41
+ return None
42
+
43
+ def update_row(csv_path, row_num, performance, status):
44
+ """Update a specific row in the CSV."""
45
+ rows = []
46
+ with open(csv_path, 'r') as f:
47
+ reader = csv.reader(f)
48
+ rows = list(reader)
49
+
50
+ # Update the specific row
51
+ if row_num <= len(rows):
52
+ row = rows[row_num - 1]
53
+ # Ensure row has at least 5 fields
54
+ while len(row) < 5:
55
+ row.append('')
56
+ row[3] = performance # performance field
57
+ row[4] = status # status field
58
+
59
+ # Write back
60
+ with open(csv_path, 'w', newline='') as f:
61
+ writer = csv.writer(f)
62
+ writer.writerows(rows)
63
+
64
+ if __name__ == '__main__':
65
+ if len(sys.argv) < 3:
66
+ print("Usage: csv_helper.py <command> <csv_path> [args...]", file=sys.stderr)
67
+ sys.exit(1)
68
+
69
+ command = sys.argv[1]
70
+ csv_path = sys.argv[2]
71
+
72
+ try:
73
+ if command == 'find_pending':
74
+ row_num = find_pending_row(csv_path)
75
+ if row_num:
76
+ print(row_num)
77
+ sys.exit(0)
78
+ else:
79
+ sys.exit(1)
80
+
81
+ elif command == 'get_row':
82
+ if len(sys.argv) < 4:
83
+ print("Usage: csv_helper.py get_row <csv_path> <row_num>", file=sys.stderr)
84
+ sys.exit(1)
85
+ row_num = int(sys.argv[3])
86
+ data = get_row_data(csv_path, row_num)
87
+ if data:
88
+ # Output as shell variable assignments
89
+ for key, value in data.items():
90
+ # Escape special characters for shell
91
+ value = value.replace('\\', '\\\\')
92
+ value = value.replace('"', '\\"')
93
+ value = value.replace('$', '\\$')
94
+ value = value.replace('`', '\\`')
95
+ print(f'{key}="{value}"')
96
+ sys.exit(0)
97
+ else:
98
+ sys.exit(1)
99
+
100
+ elif command == 'update_row':
101
+ if len(sys.argv) < 6:
102
+ print("Usage: csv_helper.py update_row <csv_path> <row_num> <performance> <status>", file=sys.stderr)
103
+ sys.exit(1)
104
+ row_num = int(sys.argv[3])
105
+ performance = sys.argv[4]
106
+ status = sys.argv[5]
107
+ update_row(csv_path, row_num, performance, status)
108
+ sys.exit(0)
109
+
110
+ else:
111
+ print(f"Unknown command: {command}", file=sys.stderr)
112
+ sys.exit(1)
113
+
114
+ except Exception as e:
115
+ print(f"Error: {e}", file=sys.stderr)
116
+ sys.exit(1)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-evolve",
3
- "version": "1.3.7",
3
+ "version": "1.3.8",
4
4
  "bin": {
5
5
  "claude-evolve": "./bin/claude-evolve",
6
6
  "claude-evolve-main": "./bin/claude-evolve-main",