← Commit history

0.9.349 notes and the status operations test

John Lauer ·8104c741ea ·1mo ago ·parent 44395ac
2 files changed +34
RELEASE_NOTES.md+12
@@ -10,6 +10,18 @@ unnamed. These entries were reconstructed after the fact from the work they contain, which is exactly the situation the mandatory-notes gate now prevents. Treat them as accurate but secondhand. +## 0.9.349  (2026-09-09 13:17 UTC)++kicad_status carries operation state for timeout recovery (#87)++## 0.9.349 (2026-09-09): kicad_status answers "did my operation finish?" (#87)++- `kicad_status` is the manifest's statusVerb, the verb ab tells a caller to poll after its 130 s+  budget runs out. It carried plugin inventory only. It now also carries `operations`: every phase+  in flight (all callers, each frame named), the last finished runs with ok/error and finishedAt,+  and `yours` filtered to the caller. The run log records the caller and the error text of a failed+  run so that answer is exact. Plugin liveness is unchanged.+ ## 0.9.348  (2026-09-08 20:32 UTC)  Focus guardian identity survives hwnd reuse; editors spawn without activation (pre-promotion run findings)
tests/test_status_operations.pyadded+22
@@ -0,0 +1,22 @@+import json, sys, tempfile, time, unittest+from pathlib import Path+from unittest.mock import patch+sys.path.insert(0, str(Path(__file__).resolve().parents[1]))+from handlers import progress++class Recent(unittest.TestCase):+    def test_recent_reports_outcome_newest_first(self):+        with tempfile.TemporaryDirectory() as d:+            with patch.object(progress, "_runlog_path", return_value=Path(d) / "runs.jsonl"), \+                 patch.object(progress, "_caller", return_value="thread A"), \+                 patch.object(progress, "record", lambda *a, **k: None):+                progress.log_run("install_symbol", 63.8, ok=True)+                progress.log_run("open_board", 2.0, ok=False, note="File not found: x.kicad_pcb", caller="thread B")+                rows = progress.recent()+                self.assertEqual([r["verb"] for r in rows], ["open_board", "install_symbol"])+                self.assertEqual(rows[0]["error"], "File not found: x.kicad_pcb"); self.assertFalse(rows[0]["ok"])+                self.assertIsNone(rows[1]["error"]); self.assertTrue(rows[1]["ok"]); self.assertEqual(rows[1]["caller"], "thread A")+                self.assertEqual([r["verb"] for r in progress.recent(caller="thread A")], ["install_symbol"])++if __name__ == "__main__":+    unittest.main()