nightralph 0.0.32 → 0.0.34

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/dist/index.js CHANGED
@@ -1152,30 +1152,110 @@ function findReadyTickets(tickets) {
1152
1152
  });
1153
1153
  }
1154
1154
  __name(findReadyTickets, "findReadyTickets");
1155
- var COMPLETED_RE = /^\[x\]\s+(.+)$/i;
1155
+ var COMPLETED_RE = /^\s*[-*+]?\s*\[x\]\s+(.+)$/i;
1156
1156
  var TOOL_USE_RE = /^\[[\w.]+\]/;
1157
+ var CHECKBOX_RE = /^(\s*[-*+] )\[( |x|X)\]( .*)$/;
1158
+ var UNCHECKED_BOX_RE = /^(\s*[-*+] )\[( )\]/;
1159
+ function normalizeItemText(s) {
1160
+ return s.replace(/\s+/g, " ").trim().toLowerCase();
1161
+ }
1162
+ __name(normalizeItemText, "normalizeItemText");
1163
+ function stripCheckboxPrefix(s) {
1164
+ return s.replace(/^\s*[-*+]?\s*\[[ xX]\]\s+/, "");
1165
+ }
1166
+ __name(stripCheckboxPrefix, "stripCheckboxPrefix");
1167
+ function parseChecklistItems(lines) {
1168
+ const items = [];
1169
+ let inFence = false;
1170
+ let i = 0;
1171
+ while (i < lines.length) {
1172
+ if (/^\s*```/.test(lines[i])) {
1173
+ inFence = !inFence;
1174
+ i++;
1175
+ continue;
1176
+ }
1177
+ if (inFence) {
1178
+ i++;
1179
+ continue;
1180
+ }
1181
+ const m = lines[i].match(CHECKBOX_RE);
1182
+ if (!m) {
1183
+ i++;
1184
+ continue;
1185
+ }
1186
+ const start = i;
1187
+ let text = m[3];
1188
+ i++;
1189
+ while (i < lines.length && /^\s+\S/.test(lines[i]) && !CHECKBOX_RE.test(lines[i])) {
1190
+ text += " " + lines[i].trim();
1191
+ i++;
1192
+ }
1193
+ items.push({
1194
+ start,
1195
+ text: normalizeItemText(text)
1196
+ });
1197
+ }
1198
+ return items;
1199
+ }
1200
+ __name(parseChecklistItems, "parseChecklistItems");
1157
1201
  function checkItems(ticket, completedItems) {
1158
1202
  if (completedItems.length === 0) return;
1159
- let body = ticket.body;
1160
- for (const item of completedItems) {
1161
- const escaped = item.replace(
1162
- /[.*+?^${}()|[\]\\]/g,
1163
- "\\$&"
1164
- );
1165
- body = body.replace(
1166
- new RegExp(
1167
- `- \\[ \\] ${escaped}`,
1168
- "i"
1169
- ),
1170
- `- [x] ${item}`
1203
+ let body;
1204
+ try {
1205
+ body = readFileSync4(ticket.filepath, "utf8");
1206
+ } catch {
1207
+ body = ticket.body;
1208
+ }
1209
+ const wanted = new Set(
1210
+ completedItems.map(
1211
+ (item) => normalizeItemText(stripCheckboxPrefix(item))
1212
+ )
1213
+ );
1214
+ const lines = body.split("\n");
1215
+ let changed = false;
1216
+ for (const item of parseChecklistItems(lines)) {
1217
+ if (!wanted.has(item.text)) continue;
1218
+ const flipped = lines[item.start].replace(
1219
+ UNCHECKED_BOX_RE,
1220
+ "$1[x]"
1171
1221
  );
1222
+ if (flipped !== lines[item.start]) {
1223
+ lines[item.start] = flipped;
1224
+ changed = true;
1225
+ }
1172
1226
  }
1227
+ if (!changed) return;
1228
+ body = lines.join("\n");
1173
1229
  writeFileSync3(ticket.filepath, body);
1174
1230
  ticket.body = body;
1175
1231
  }
1176
1232
  __name(checkItems, "checkItems");
1233
+ function checkAllItems(body) {
1234
+ const lines = body.split("\n");
1235
+ let inFence = false;
1236
+ for (let i = 0; i < lines.length; i++) {
1237
+ if (/^\s*```/.test(lines[i])) {
1238
+ inFence = !inFence;
1239
+ continue;
1240
+ }
1241
+ if (inFence) continue;
1242
+ lines[i] = lines[i].replace(
1243
+ UNCHECKED_BOX_RE,
1244
+ "$1[x]"
1245
+ );
1246
+ }
1247
+ return lines.join("\n");
1248
+ }
1249
+ __name(checkAllItems, "checkAllItems");
1177
1250
  function markDone(ticket) {
1178
- const updated = ticket.body.replace(
1251
+ let body;
1252
+ try {
1253
+ body = readFileSync4(ticket.filepath, "utf8");
1254
+ } catch {
1255
+ body = ticket.body;
1256
+ }
1257
+ body = checkAllItems(body);
1258
+ const updated = body.replace(
1179
1259
  /\*\*Status:\*\*\s*.+/i,
1180
1260
  "**Status:** done"
1181
1261
  );
@@ -1513,14 +1593,21 @@ function killProcessGroup(pid) {
1513
1593
  try {
1514
1594
  process.kill(-pid, "SIGKILL");
1515
1595
  } catch {
1596
+ try {
1597
+ process.kill(pid, "SIGKILL");
1598
+ } catch {
1599
+ }
1516
1600
  }
1517
1601
  }
1518
1602
  __name(killProcessGroup, "killProcessGroup");
1519
1603
  var runningAgents = /* @__PURE__ */ new Set();
1520
1604
  function killRunningAgents() {
1605
+ let killed = 0;
1521
1606
  for (const pid of runningAgents) {
1522
1607
  killProcessGroup(pid);
1608
+ killed++;
1523
1609
  }
1610
+ return killed;
1524
1611
  }
1525
1612
  __name(killRunningAgents, "killRunningAgents");
1526
1613
  function spawnAgent(opts) {
@@ -1583,9 +1670,16 @@ function spawnAgent(opts) {
1583
1670
  proc.stdout.pipe(logStream);
1584
1671
  const piFormatter = isPi ? createPiStreamFormatter() : null;
1585
1672
  const completedItems = [];
1673
+ const seenItems = /* @__PURE__ */ new Set();
1586
1674
  function collectCompleted(text) {
1587
- const match = text.match(COMPLETED_RE);
1588
- if (match) completedItems.push(match[1]);
1675
+ for (const line of text.split("\n")) {
1676
+ const match = line.match(COMPLETED_RE);
1677
+ if (!match) continue;
1678
+ const item = match[1].trim();
1679
+ if (!item || seenItems.has(item)) continue;
1680
+ seenItems.add(item);
1681
+ completedItems.push(item);
1682
+ }
1589
1683
  }
1590
1684
  __name(collectCompleted, "collectCompleted");
1591
1685
  const rl = createInterface({ input: proc.stdout });
@@ -2515,6 +2609,7 @@ async function runWavesIsolated(opts) {
2515
2609
  }
2516
2610
  }
2517
2611
  } else {
2612
+ failedNums.add(ticket.num);
2518
2613
  d.log(
2519
2614
  ` ${ticket.filename}: merge failed, staying ready-for-agent`
2520
2615
  );