(projectRoot, id, run = {}, options = {})
| 68 | } |
| 69 | |
| 70 | function appendLoopRun(projectRoot, id, run = {}, options = {}) { |
| 71 | const current = readLoop(projectRoot, id); |
| 72 | if (!current) throw new Error(`Loop not found: ${id}`); |
| 73 | const entry = { |
| 74 | attempt: Number(run.attempt || (current.runs || []).length + 1), |
| 75 | status: normalizeStatus(run.status || 'running'), |
| 76 | summary: run.summary || '', |
| 77 | command: run.command || null, |
| 78 | verifier: run.verifier || null, |
| 79 | exitCode: Number.isInteger(run.exitCode) ? run.exitCode : null, |
| 80 | startedAt: run.startedAt || nowIso(options), |
| 81 | completedAt: run.completedAt || nowIso(options), |
| 82 | evidence: run.evidence || [], |
| 83 | }; |
| 84 | current.runs = [...(current.runs || []), entry]; |
| 85 | current.status = entry.status; |
| 86 | current.updatedAt = nowIso(options); |
| 87 | writeJson(loopPath(projectRoot, id), current); |
| 88 | return current; |
| 89 | } |
| 90 | |
| 91 | function stopLoop(projectRoot, id, status = 'stopped', reason = '', options = {}) { |
| 92 | return updateLoop(projectRoot, id, { |
no test coverage detected