You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(mechanic): isolate status file in tests + Force override for stuck runs (#100)
The real bug behind 'Run does nothing': the orchestration tests call the
real run_mechanic_cycle, which wrote progress to the PRODUCTION status
file (a test item 'Blow up mid-run', left non-terminal by the exception
test) — the run guard read that ghost and refused every click. Isolate
mechanic_status._STATUS_FILE per test so the suite never touches the file
the server's panel reads.
Also add an escape hatch: POST /api/mechanic/run?force=true overrides the
one-at-a-time guard (an agent is silent for minutes, so age can't prove a
run is dead). The panel offers 'force a new run?' on already_running.
mechanic.js -> ?v=4.
+tests: status isolated, force overrides the guard. Full suite 1801
passing; ruff clean.
Co-Authored-By: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: src/project_forge/web/static/mechanic.js
+25-12Lines changed: 25 additions & 12 deletions
Original file line number
Diff line number
Diff line change
@@ -104,20 +104,33 @@
104
104
pollOnce();
105
105
}
106
106
107
+
asyncfunctiondoRun(force){
108
+
runBtn.disabled=true;
109
+
startedAt=Date.now();
110
+
setStatus('⏱ starting — this takes a few minutes (clone → Claude implements → full test suite → PR). Leave this open; the PR appears below when done.','loading');
if(confirm('A mechanic run is already in progress'+item+'. Agents run silently for several minutes, so it may still be working. Force a NEW run anyway?')){
118
+
returndoRun(true);
119
+
}
120
+
startPolling();// just show the in-progress run's live status
121
+
return;
122
+
}
123
+
startPolling();
124
+
}catch(e){
125
+
setStatus('failed to start: '+e.message,'error');
126
+
runBtn.disabled=false;
127
+
}
128
+
}
129
+
107
130
if(runBtn&&statusEl){
108
-
runBtn.addEventListener('click',asyncfunction(){
131
+
runBtn.addEventListener('click',function(){
109
132
if(!confirm('Run one mechanic cycle now? It implements the top Think Tank item on your subscription and opens a PR here. Takes several minutes — leave the page open.'))return;
110
-
runBtn.disabled=true;
111
-
startedAt=Date.now();
112
-
setStatus('⏱ starting — this takes a few minutes (clone → Claude implements → full test suite → PR). Leave this open; the PR appears below when done.','loading');
0 commit comments