MC2: Live-Log-Blick - Worker-Log laufender Ideen im Auftragsbuch aufklappbar machen
Backend:
- backend/services/ideen.py: neue Funktion log_of(task_id)
- ruft 'hermes kanban log <id>'
- validiert task_id mit _TASK_ID_RX
- strippt ANSI-Steuerzeichen (\x1b\[[0-9;]*m)
- gibt letzte ~120 Zeilen zurück
- kurzer Cache (~4s)
- auf Windows/available=False leer zurück, nie crashen
- backend/routers/ideen.py: GET /api/ideen/{id}/log -> ideen.log_of(id)
Frontend:
- frontend/src/views/AuftragsbuchView.tsx: IdeenSection
- Ideen mit status 'triage' oder 'running' per Klick aufklappbar
- im aufgeklappten Zustand /api/ideen/{id}/log alle ~4s pollen
- Log monospace/<pre> in scrollbaren, höhenbegrenztem Kasten
- vorhandenes api()-Muster + react-query nutzen
- frontend/dist mitgebaut und committet
Branch: feature/live-log-blick
This commit is contained in:
@@ -31,6 +31,10 @@ _TASK_ID_RX = re.compile(r"^t_[0-9a-f]{4,16}$")
|
||||
_list_cache: dict = {"ts": 0.0, "data": None}
|
||||
_LIST_EVERY = 15.0 # s
|
||||
|
||||
# Cache für worker log
|
||||
_log_cache: dict = {"ts": 0.0, "task_id": None, "data": None}
|
||||
_LOG_EVERY = 4.0 # s
|
||||
|
||||
|
||||
def _available() -> bool:
|
||||
return os.name == "posix" and HERMES.is_file()
|
||||
@@ -136,3 +140,39 @@ def archive_task(task_id: str) -> dict:
|
||||
return {"ok": False, "error": (r.stderr or r.stdout or "Archivieren fehlgeschlagen").strip()[:300]}
|
||||
_list_cache["ts"] = 0.0
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
def log_of(task_id: str) -> dict:
|
||||
"""Worker-Log einer Idee (hermes kanban log <id>), ANSI entfernt, letzte ~120 Zeilen."""
|
||||
if not _available():
|
||||
return {"available": False, "lines": []}
|
||||
if not _TASK_ID_RX.match(task_id or ""):
|
||||
return {"available": True, "lines": []}
|
||||
|
||||
now = time.time()
|
||||
if (
|
||||
_log_cache["data"] is not None
|
||||
and _log_cache["task_id"] == task_id
|
||||
and now - _log_cache["ts"] < _LOG_EVERY
|
||||
):
|
||||
return _log_cache["data"]
|
||||
|
||||
try:
|
||||
r = _hermes(["log", task_id])
|
||||
except Exception as exc:
|
||||
log.warning("ideen: kanban log fehlgeschlagen", exc_info=True)
|
||||
return {"available": True, "lines": []}
|
||||
if r.returncode != 0:
|
||||
log.warning("ideen: kanban log exit=%s stderr=%s", r.returncode, r.stderr)
|
||||
return {"available": True, "lines": []}
|
||||
|
||||
raw = r.stdout or ""
|
||||
# ANSI-Steuerzeichen entfernen
|
||||
ansi = re.compile(r"\x1b\[[0-9;]*m")
|
||||
cleaned = ansi.sub("", raw)
|
||||
|
||||
# Letzte ~120 Zeilen
|
||||
lines = cleaned.strip().splitlines()[-120:]
|
||||
data = {"available": True, "lines": lines}
|
||||
_log_cache.update(ts=now, task_id=task_id, data=data)
|
||||
return data
|
||||
|
||||
Reference in New Issue
Block a user