()
| 40 | # ---------- task metadata ---------- |
| 41 | |
| 42 | def list_tasks() -> list[dict]: |
| 43 | out: list[dict] = [] |
| 44 | if not TASKS_DIR.exists(): |
| 45 | return out |
| 46 | for d in sorted(TASKS_DIR.iterdir()): |
| 47 | info_path = d / "task.json" |
| 48 | if not info_path.exists(): |
| 49 | continue |
| 50 | info = json.loads(info_path.read_text()) |
| 51 | info["short_id"] = d.name |
| 52 | out.append(info) |
| 53 | return out |
| 54 | |
| 55 | |
| 56 | # ---------- log + steps parsing ---------- |