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:
werkstatt
2026-07-13 17:17:16 +02:00
parent 1427048f38
commit 9a41cce99b
26 changed files with 161 additions and 63 deletions
+7
View File
@@ -494,6 +494,10 @@ export interface IdeenItem {
fertig: number | null
von: string | null
}
export interface IdeenLogResp {
available: boolean
lines: string[]
}
export interface IdeenResp {
available: boolean
items: IdeenItem[]
@@ -588,3 +592,6 @@ export interface HermesBrainResp {
update_available: boolean
budget?: HermesBrainBudget | null
}
// ── Ideen-Log (Live Worker Log) ──────────────────────────────────────────────
export const getIdeenLog = (id: string) => api<IdeenLogResp>(`/api/ideen/${id}/log`)
+11
View File
@@ -15,6 +15,7 @@ import {
type GroupsResp,
type HermesBrainResp,
type Health,
type IdeenLogResp,
type IdeenResp,
type Job,
type Memory,
@@ -91,6 +92,16 @@ export const useIdeen = (refetchInterval: number = TAKT.gemuetlich) =>
refetchInterval,
})
// Ideen-Log (Live Worker Log): pollt nur solange Idee triage/running UND offen
export const useIdeenLog = (id: string, enabled: boolean = false) =>
useQuery({
queryKey: ["ideen-log", id],
queryFn: () => api<IdeenLogResp>(`/api/ideen/${id}/log`),
enabled,
refetchInterval: 4000, // alle ~4s
staleTime: 0,
})
export const useChronik = (limit = 150, refetchInterval: number = TAKT.gemuetlich) =>
useQuery({
queryKey: qk.chronik,