Files
mission-control-v2/frontend/dist/assets/AuftragsbuchView-DnGEkS0J.js
T
HitonabiandClaude Opus 5 5aa5a484a7 feat(frontend): v3-Umbau P3 — ein Store, eine Statusleiste, endlich aria-live
Vierte Etappe. Der Client-Zustand hatte bisher keinen Ort: zwei handgebaute
useSyncExternalStore-Speicher, drei CustomEvent-Kanaele und ein localStorage-Griff
mitten in einem useState — verteilt ueber fuenf Dateien.

## Ein Store (Befund B-08/B-09)

app/store.ts (Zustand, 1,2 kB gzip) haelt genau vier Dinge: Bedienvorlieben
(Schiene, Expertenmodus, Palette), die Lage des Ereignisstroms und die
Meldungs-Warteschlange. Der Kopfkommentar nennt die Regel, nach der etwas dort
landen darf — und ein Test prueft sie: gespeichert werden AUSSCHLIESSLICH
Schienen- und Expertenmodus-Zustand, kein Strom, keine Meldungen, kein Geheimnis.

Der Metrik-Verlauf bleibt bewusst DRAUSSEN (lib/metricsStore.ts): Er nimmt ab P4
jede Sekunde einen Messpunkt entgegen, ein Store-Update pro Sekunde wuerde jede
abonnierende Komponente neu rendern.

Die drei CustomEvent-Kanaele sind ERSATZLOS weg — `grep -r dispatchEvent src`
liefert nichts mehr. Wer die Schublade oeffnen will, setzt `?system=`; wer springen
will, navigiert. Auch der letzte Rest von P2 (`mc-palette-open`) ist aufgeloest.

## Statusleiste (Spezifikation §4.1)

Der Zustand der Box stand bisher verstreut: die Ampel unten in der Sidebar, die
Auslastung nur im Cockpit, das aktive Modell nur im Modell-Manager. Wer in der
Konsole arbeitete, sah gar nichts.

Jetzt eine feste Leiste ueber allen Ansichten: Motor/Hirn-Ampel (klickbar zum
Agenten) · aktive Rolle + Durchsatz mit Sparkline · geteilter Speicher ALS BALKEN
(nicht als Prozent — 128 GB Unified Memory ist die Kernzahl dieser Box) · CPU/GPU
· Temperatur (ab 85 °C bernstein) · Betriebszeit · Token-Summe · Live-Anzeige.

Die Sparklines sind eigenes SVG, ~20 Zeilen. Fuer eine 56-Pixel-Linie waere eine
Diagramm-Bibliothek Verschwendung.

Dafuer neu im Backend: `uptime_s` in /api/system/status (psutil.boot_time).
Gehoert dorthin, weil die Box sich woechentlich selbst neu startet — dann ist
"laeuft seit 20 Minuten" die Antwort auf eine ganze Klasse von Fragen.
Liefert psutil nichts, steht dort None und die Leiste blendet das Feld aus,
statt eine Zahl zu erfinden.

## aria-live (Befund B-11) — und diesmal mit Absender

Im ganzen Frontend gab es KEIN einziges aria-live. app/shell/Meldungen.tsx ist
jetzt die eine Stelle fuer beilaeufige Rueckmeldungen; Fehler bekommen
`assertive` und bleiben stehen, alles andere `polite` und raeumt sich weg.

Wichtig: Die Region ist keine Attrappe. Gespeist wird sie von den Uebergaengen des
Ereignisstroms und vom Konsolen-Neustart (mit dem echten Grund aus ApiError.detail).
Der erste Verbindungsaufbau wird bewusst NICHT gemeldet — sonst begruesst jede
Seite den Nutzer mit "Verbindung wieder da".

## Ehrliche Anzeige statt stillem Altern (Befund B-15/B-18)

lib/events.ts fuehrt die Stromlage jetzt im Store: live · nachlauf · getrennt.
Beim Wechsel wird EINMAL invalidiert — vorher las relax() den Zustand erst beim
naechsten Refetch, nach einem Riss blieb die UI bis zu 150 s im langsamen Modus.

## Bahnbreiten-Deckel (Befund B-10)

Die Arbeitsflaeche endet bei 1600 px. Ohne Deckel zog sich das Cockpit auf einem
3440-px-Ultrawide auf ueber 3 000 px, waehrend die Wurzel-Schriftgroesse mitwuchs
und die Zeilen GROESSER statt lesbarer machte.

## Nebenbei

Der Buendel-Budget-Check aus P0 war fragil: `ls dist/assets/index-*.js | head -1`
kann den falschen treffen, weil Rollup auch kleine geteilte Module "index-*.js"
nennt (gemessen: ein 67-Byte-Chunk neben dem 374-kB-Einstieg). Er waere dann still
immer gruen gewesen. Beide Ampel-Dateien lesen den Einstieg jetzt aus index.html.

## Verifiziert im Browser

  Statusleiste: alle Felder mit Live-Daten, "Laeuft seit 1 Std 10 min"
  Backend abgewuergt  -> Leiste springt auf "Nachlauf" UND die aria-live-Region
                         meldet "Verbindung zur Zentrale verloren" (polite)
  Backend zurueck     -> "Live", ohne Begruessungs-Meldung
  Cockpit-Kachel      -> /cockpit?system=logs, Schublade offen, Reiter "System-Logs"
  Arbeitsflaeche      -> max-width 1600 px

33/33 Tests gruen (7 neue fuer den Store) · ESLint 0 Fehler · tsc sauber ·
Einstieg 118 153 B gzip / Budget 125 000.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 09:07:09 +02:00

16 lines
19 KiB
JavaScript

import{c as W,z as G,a1 as H,a2 as T,u as F,k as _,r as u,j as e,b as N,L as m,C as E,_ as O,a0 as z,a3 as R,X as I,T as B,G as V,n as K,a4 as P,q}from"./index-CB2Jz083.js";import{S,H as U}from"./SectionLabel-Dvaa0NeT.js";import{R as Q}from"./refresh-cw-BaiqRBZd.js";import{A as Z}from"./arrow-right-C2xQ80N8.js";import{C as $}from"./clock-BFJQZ7fi.js";import{C as M}from"./chevron-down-BVWIvMwj.js";/**
* @license lucide-react v0.460.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const J=W("FileDiff",[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M9 10h6",key:"9gxzsh"}],["path",{d:"M12 13V7",key:"h0r20n"}],["path",{d:"M9 17h6",key:"r8uit2"}]]);/**
* @license lucide-react v0.460.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const X=W("GitBranch",[["line",{x1:"6",x2:"6",y1:"3",y2:"15",key:"17qcm7"}],["circle",{cx:"18",cy:"6",r:"3",key:"1h7g24"}],["circle",{cx:"6",cy:"18",r:"3",key:"fqmcym"}],["path",{d:"M18 9a9 9 0 0 1-9 9",key:"n2h4wq"}]]),Y={wartung:"Werkstatt",orchestrator:"Orchestrator",doku:"Doku",feature:"Feature"},ee={laeuft:{label:"wird eingespielt …",cls:"text-sky-300 border-sky-500/40 bg-sky-500/10",spin:!0},rollback:{label:"Rollback läuft …",cls:"text-amber-300 border-amber-500/40 bg-amber-500/10",spin:!0},eingespielt:{label:"eingespielt ✓",cls:"text-emerald-300 border-emerald-500/40 bg-emerald-500/10"},fehlgeschlagen:{label:"fehlgeschlagen",cls:"text-red-300 border-red-500/40 bg-red-500/10"},zurueckgerollt:{label:"zurückgerollt",cls:"text-amber-300 border-amber-500/40 bg-amber-500/10"},kritisch:{label:"KRITISCH — Box prüfen",cls:"text-red-200 border-red-500/60 bg-red-500/20"},abgelehnt:{label:"abgelehnt",cls:"text-muted-foreground border-border/60 bg-background/30"}};function he(){const t=G(),{data:r,isLoading:n,refetch:b,isFetching:c}=H(),{data:o}=T(),p=F(),{showAlert:f,showConfirm:k,dialogElement:w}=_(),[v,g]=u.useState({}),y=()=>p.invalidateQueries({queryKey:q.auftragsbuch});async function A(a,L,D,j){g(l=>({...l,[a]:!0}));try{await K(L,{method:"POST",body:JSON.stringify(D)}),j&&f("Erledigt",j),y()}catch(l){f("Das hat nicht geklappt",String((l==null?void 0:l.message)||l))}finally{g(l=>({...l,[a]:!1}))}}const h=(r==null?void 0:r.items)??[],x=(r==null?void 0:r.skill_kandidaten)??[],d=o!=null&&o.available?o.items.filter(a=>a.status==="blocked").length:0,C=h.length===0&&x.length===0;return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"bg-gradient-to-r from-foreground via-foreground to-primary bg-clip-text font-space text-2xl font-bold tracking-tight text-transparent",children:"Auftragsbuch"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Was die Box gebaut oder sich ausgedacht hat — du entscheidest. Annehmen spielt es mit Fangnetz ein (Health-Check, automatischer Rollback)."})]}),e.jsxs("button",{onClick:()=>b(),className:"flex h-9 items-center gap-1.5 rounded-lg border border-border/60 bg-card/45 px-3 text-xs font-semibold text-muted-foreground hover:text-foreground hover:border-primary/40 transition-all cursor-pointer",children:[e.jsx(Q,{className:N("h-3.5 w-3.5",c&&"animate-spin")})," Aktualisieren"]})]}),r&&!r.available&&e.jsx("div",{className:"rounded-2xl border border-amber-500/30 bg-amber-500/5 p-4 text-xs text-amber-300",children:"Das Auftragsbuch lebt auf der Box (liest die Gitea-Branches dort). Im lokalen Dev-Modus ist hier nichts zu sehen."}),n&&e.jsxs("div",{className:"flex items-center gap-2 rounded-2xl border border-border/60 bg-card/30 p-6 text-xs text-muted-foreground",children:[e.jsx(m,{className:"h-4 w-4 animate-spin"})," Vorschläge werden geladen …"]}),(r==null?void 0:r.available)&&C&&e.jsxs("div",{className:"flex items-center gap-3 rounded-2xl border border-emerald-500/25 bg-emerald-500/5 p-5",children:[e.jsx(E,{className:"h-5 w-5 shrink-0 text-emerald-400"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-semibold text-foreground",children:"Nichts zu entscheiden"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Keine offenen Vorschläge. Werkstatt, Orchestrator und Traum melden sich hier, sobald es etwas gibt."})]})]}),d>0&&e.jsxs("button",{onClick:()=>t({to:"/ideen"}),className:"flex w-full items-center gap-3 rounded-2xl border border-red-500/30 bg-red-500/5 p-4 text-left transition-all hover:border-red-500/50 cursor-pointer",children:[e.jsx(O,{className:"h-5 w-5 shrink-0 text-red-300"}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("p",{className:"text-sm font-semibold text-foreground",children:d===1?"Eine Idee hängt und braucht dich":`${d} Ideen hängen und brauchen dich`}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Hier ist nichts zu tun — aber drüben in den Ideen wartet eine Frage auf deine Antwort."})]}),e.jsx(Z,{className:"h-4 w-4 shrink-0 text-red-300/70"})]}),h.length>0&&e.jsxs("section",{className:"space-y-3",children:[e.jsxs(S,{icon:X,children:["Patch-Vorschläge (",h.length,")"]}),h.map(a=>e.jsx(se,{item:a,busy:v,onAct:A,showConfirm:k},`${a.repo??"mc2"}:${a.branch}`))]}),x.length>0&&e.jsxs("section",{className:"space-y-3",children:[e.jsxs(S,{icon:z,children:["Skill-Kandidaten aus dem Traum (",x.length,")"]}),x.map(a=>e.jsx(ae,{k:a,busy:v,onAct:A,showConfirm:k},a.file))]}),w]})}function te({item:t}){const r=t.status;if(!r)return null;const n=ee[r.state];return n?e.jsxs("span",{className:N("flex items-center gap-1.5 rounded-lg border px-2 py-0.5 text-[10px] font-bold",n.cls),title:r.detail,children:[n.spin&&e.jsx(m,{className:"h-3 w-3 animate-spin"}),n.label]}):null}function re({item:t}){const r=t.ci_status;return r?r==="success"?e.jsxs("span",{className:"flex items-center gap-1 rounded-lg border border-emerald-500/30 bg-emerald-500/10 px-1.5 py-0.5 text-[10px] font-bold text-emerald-400",title:"CI-Ampel: Grün (Baut & läuft)",children:[e.jsx(E,{className:"h-3 w-3"})," CI Grün"]}):r==="failure"?e.jsxs("span",{className:"flex items-center gap-1 rounded-lg border border-red-500/30 bg-red-500/10 px-1.5 py-0.5 text-[10px] font-bold text-red-400",title:"CI-Ampel: Rot (Fehler)",children:[e.jsx(I,{className:"h-3 w-3"})," CI Rot"]}):r==="pending"?e.jsxs("span",{className:"flex items-center gap-1 rounded-lg border border-amber-500/30 bg-amber-500/10 px-1.5 py-0.5 text-[10px] font-bold text-amber-400",title:"CI-Ampel: Läuft",children:[e.jsx(m,{className:"h-3 w-3 animate-spin"})," CI Läuft"]}):null:null}function se({item:t,busy:r,onAct:n,showConfirm:b}){var D,j,l;const[c,o]=u.useState(!1),[p,f]=u.useState(null),[k,w]=u.useState(!1),[v,g]=u.useState(!1),[y,A]=u.useState(""),h=((D=t.status)==null?void 0:D.state)==="laeuft"||((j=t.status)==null?void 0:j.state)==="rollback",x=((l=t.status)==null?void 0:l.state)==="eingespielt",d=t.repo??"mc2",C=d==="lucy",a=`${d}:${t.branch}`;async function L(){const s=!c;if(o(s),s&&p===null){w(!0);try{const i=await K(`/api/auftragsbuch/diff?branch=${encodeURIComponent(t.branch)}&repo=${d}`);f(i.diff+(i.truncated?`
… (gekürzt)`:""))}catch(i){f(`(Diff nicht ladbar: ${(i==null?void 0:i.message)||i})`)}finally{w(!1)}}}return e.jsxs("div",{className:"mc-card p-4 space-y-3",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"rounded-md border border-primary/30 bg-primary/10 px-1.5 py-0.5 text-[10px] font-bold uppercase tracking-wider text-primary",children:Y[t.kind]??t.kind}),C&&e.jsx("span",{className:"rounded-md border border-pink-500/40 bg-pink-500/10 px-1.5 py-0.5 text-[10px] font-bold uppercase tracking-wider text-pink-300",title:"Vorschlag fürs Lucy-Repo — Annehmen baut die App am PC neu und startet sie neu, wenn sie läuft.",children:"Lucy"}),e.jsx("span",{className:"font-mono text-[11px] text-muted-foreground truncate",title:t.branch,children:t.branch}),e.jsxs("span",{className:"flex items-center gap-1 text-[10px] text-muted-foreground/70",children:[e.jsx($,{className:"h-3 w-3"}),R(t.ts)]}),e.jsx(re,{item:t}),e.jsx(te,{item:t})]}),e.jsx("p",{className:"mt-1.5 text-sm font-semibold text-foreground",children:t.subject||"(ohne Titel)"}),t.body&&e.jsx("p",{className:"mt-1 whitespace-pre-wrap text-xs leading-relaxed text-muted-foreground line-clamp-6",children:t.body}),t.empfehlung&&e.jsxs("p",{className:N("mt-1.5 flex items-start gap-1.5 rounded-lg border px-2 py-1 text-[11px]",t.empfehlung.empfehlung==="ANNEHMEN"&&"border-emerald-500/30 bg-emerald-500/5 text-emerald-300",t.empfehlung.empfehlung==="ABLEHNEN"&&"border-red-500/30 bg-red-500/5 text-red-300",t.empfehlung.empfehlung==="UNKLAR"&&"border-amber-500/30 bg-amber-500/5 text-amber-300"),title:`Nächtliches Kurz-Gutachten (${t.empfehlung.richter}) — eine Meinung, kein Muss. Die Entscheidung bleibt bei dir.`,children:[e.jsx(z,{className:"mt-0.5 h-3 w-3 shrink-0"}),e.jsxs("span",{children:[e.jsxs("b",{children:["Empfehlung: ",t.empfehlung.empfehlung==="ANNEHMEN"?"Annehmen":t.empfehlung.empfehlung==="ABLEHNEN"?"Ablehnen":"Unklar","."]})," ",t.empfehlung.satz]})]})]}),!h&&!x&&e.jsxs("div",{className:"flex shrink-0 items-center gap-2",children:[!t.verwaist&&e.jsxs("button",{disabled:!!r[a],onClick:()=>b("Vorschlag annehmen?",C?`'${t.branch}' wird im Lucy-Repo auf main gemergt, dann baut dein PC die App neu (dist) und startet Lucy neu, falls sie gerade läuft. Der PC muss dafür an sein. Schlägt Build oder Start fehl, dreht die Box den Merge automatisch zurück — die laufende Lucy bleibt die alte.`:`'${t.branch}' wird auf main gemergt und live eingespielt. Die Zentrale startet dabei kurz neu. Geht der Health-Check danach rot, rollt die Box automatisch zurück.${t.frontend_ohne_build?`
Achtung: Enthält Frontend-Quelltext ohne gebautes Bundle — die Oberfläche bleibt alt, bis am PC gebaut wird.`:""}`,()=>n(a,"/api/auftragsbuch/annehmen",{branch:t.branch,repo:d})),className:"flex h-9 items-center gap-1.5 rounded-lg border border-emerald-500/40 bg-emerald-500/10 px-3 text-[11px] font-bold uppercase tracking-wide text-emerald-300 transition-all hover:bg-emerald-500/20 cursor-pointer disabled:opacity-50",children:[r[a]?e.jsx(m,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(E,{className:"h-3.5 w-3.5"})," Annehmen"]}),e.jsxs("button",{disabled:!!r["ab:"+a],onClick:()=>g(s=>!s),className:"flex h-9 items-center gap-1.5 rounded-lg border border-red-500/30 bg-red-500/5 px-3 text-[11px] font-bold uppercase tracking-wide text-red-300/90 transition-all hover:bg-red-500/15 cursor-pointer disabled:opacity-50",children:[r["ab:"+a]?e.jsx(m,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(I,{className:"h-3.5 w-3.5"})," Ablehnen"]})]})]}),v&&!h&&!x&&e.jsxs("div",{className:"space-y-2 rounded-xl border border-red-500/25 bg-red-500/5 p-3",children:[e.jsxs("p",{className:"text-[11px] text-muted-foreground",children:["Der Branch '",t.branch,"' wird auf Gitea gelöscht (die Arbeit bleibt in der Historie). Sag der Box kurz ",e.jsx("b",{children:"warum"})," — dann schlägt sie dir so etwas nicht wieder vor."]}),e.jsx("input",{value:y,onChange:s=>A(s.target.value),placeholder:"Grund (optional) — z. B. „gibt es schon“ oder „will ich nicht“",maxLength:400,className:"w-full rounded-lg border border-border/60 bg-background/60 px-2.5 py-1.5 text-xs text-foreground placeholder:text-muted-foreground/50 focus:border-red-400/50 focus:outline-none"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("button",{disabled:!!r["ab:"+a],onClick:()=>{g(!1),n("ab:"+a,"/api/auftragsbuch/ablehnen",{branch:t.branch,repo:d,grund:y.trim()})},className:"flex h-8 items-center gap-1.5 rounded-lg border border-red-500/40 bg-red-500/10 px-3 text-[11px] font-bold uppercase tracking-wide text-red-300 transition-all hover:bg-red-500/20 cursor-pointer disabled:opacity-50",children:[e.jsx(I,{className:"h-3.5 w-3.5"})," Wirklich ablehnen"]}),e.jsx("button",{onClick:()=>g(!1),className:"flex h-8 items-center rounded-lg border border-border/60 bg-background/40 px-3 text-[11px] font-semibold text-muted-foreground transition-all hover:text-foreground cursor-pointer",children:"Abbrechen"})]})]}),t.status&&(h||!x)&&t.status.detail&&e.jsx("p",{className:"text-[11px] text-muted-foreground",children:t.status.detail}),t.verwaist&&e.jsxs("p",{className:"rounded-lg border border-red-500/30 bg-red-500/5 px-2 py-1.5 text-[11px] text-red-300/90",children:[e.jsx("b",{children:"Kaputt aufgesetzt:"})," Dieser Branch hat keinen gemeinsamen Ursprung mit main (der Werkstatt-Worker hat nicht richtig geklont) — Annehmen ist technisch unmöglich, deshalb fehlt der Knopf. Am besten ",e.jsx("b",{children:"ablehnen mit Grund"}),"; die Idee kann danach frisch in die Queue."]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-[11px] text-muted-foreground",children:[e.jsxs("span",{className:"rounded bg-background/40 px-1.5 py-0.5 font-mono",children:[t.ahead," Commit",t.ahead===1?"":"s"]}),t.shortstat&&e.jsx("span",{className:"rounded bg-background/40 px-1.5 py-0.5 font-mono",children:t.shortstat.trim()}),t.verwaist&&e.jsxs("span",{className:"flex items-center gap-1 rounded bg-red-500/10 px-1.5 py-0.5 text-red-300",title:"Kein gemeinsamer Vorfahre mit main — git kann diesen Branch niemals mergen.",children:[e.jsx(B,{className:"h-3 w-3"})," kein gemeinsamer Ursprung"]}),t.leer&&e.jsxs("span",{className:"flex items-center gap-1 rounded bg-amber-500/10 px-1.5 py-0.5 text-amber-300",title:"Der Diff gegen main ist leer — der Branch würde nichts verändern (Inhalt schon in main oder am Repo vorbei gearbeitet).",children:[e.jsx(B,{className:"h-3 w-3"})," Diff leer — bringt nichts"]}),t.behind>0&&!t.verwaist&&e.jsxs("span",{className:"flex items-center gap-1 rounded bg-amber-500/10 px-1.5 py-0.5 text-amber-300",title:"main ist seit diesem Vorschlag weitergelaufen — bei Konflikten versucht die Annahme automatisch einen Rebase.",children:[e.jsx(B,{className:"h-3 w-3"})," ",t.behind," hinter main"]}),t.frontend_ohne_build&&e.jsxs("span",{className:"flex items-center gap-1 rounded bg-amber-500/10 px-1.5 py-0.5 text-amber-300",title:"Die Box kann kein Frontend bauen (kein Node) — nach dem Annehmen bleibt die Oberfläche alt, bis am PC gebaut wird.",children:[e.jsx(B,{className:"h-3 w-3"})," Frontend ohne Build"]})]}),e.jsxs("div",{children:[e.jsxs("button",{onClick:L,className:"flex items-center gap-1.5 text-[11px] font-semibold text-muted-foreground hover:text-foreground transition-colors cursor-pointer",children:[c?e.jsx(M,{className:"h-3.5 w-3.5"}):e.jsx(V,{className:"h-3.5 w-3.5"}),e.jsx(J,{className:"h-3.5 w-3.5"})," ",t.files.length," Datei",t.files.length===1?"":"en"," — Änderungen ansehen"]}),c&&e.jsxs("div",{className:"mt-2 space-y-2",children:[e.jsxs("div",{className:"flex flex-wrap gap-1.5",children:[t.files.map(s=>e.jsxs("span",{className:"rounded bg-background/40 px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground",children:[e.jsx("b",{className:N(s.status.startsWith("A")&&"text-emerald-400",s.status.startsWith("D")&&"text-red-400",s.status.startsWith("M")&&"text-sky-400"),children:s.status})," ",s.path]},s.path)),t.files_truncated&&e.jsx("span",{className:"text-[10px] text-muted-foreground/60",children:"…"})]}),e.jsx("div",{className:"max-h-96 overflow-auto rounded-xl border border-border/50 bg-background/50 p-3",children:k?e.jsx("span",{className:"text-[11px] text-muted-foreground",children:"Diff wird geladen …"}):e.jsx("pre",{className:"text-[10px] leading-relaxed text-foreground/80 whitespace-pre",children:(p??"").split(`
`).map((s,i)=>e.jsx("span",{className:N("block",s.startsWith("+")&&!s.startsWith("+++")&&"text-emerald-300/90 bg-emerald-500/5",s.startsWith("-")&&!s.startsWith("---")&&"text-red-300/90 bg-red-500/5",(s.startsWith("@@")||s.startsWith("diff "))&&"text-sky-300/90"),children:s||" "},i))})})]})]})]})}function ae({k:t,busy:r,onAct:n,showConfirm:b}){const[c,o]=u.useState(!1);return e.jsxs("div",{className:"rounded-2xl border border-violet-500/25 bg-violet-500/[0.04] p-4 shadow-lg shadow-black/15 backdrop-blur-md space-y-3",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"rounded-md border border-violet-500/30 bg-violet-500/10 px-1.5 py-0.5 text-[10px] font-bold uppercase tracking-wider text-violet-300",children:"Traum-Idee"}),e.jsx("span",{className:"font-mono text-[11px] text-muted-foreground truncate",children:t.file}),e.jsxs("span",{className:"flex items-center gap-1 text-[10px] text-muted-foreground/70",children:[e.jsx($,{className:"h-3 w-3"}),R(t.mtime)]})]}),e.jsx("p",{className:"mt-1.5 text-sm font-semibold text-foreground",children:t.title})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-2",children:[e.jsxs("button",{disabled:!!r["sk:"+t.file],onClick:()=>b("Werkstatt beauftragen?",`Der Kandidat '${t.title}' geht als Auftrag an die Werkstatt (Orchestrator, propose-only). Das Ergebnis erscheint später als neuer Patch-Vorschlag hier im Auftragsbuch — nichts geht ungefragt live.`,()=>n("sk:"+t.file,"/api/auftragsbuch/skill/annehmen",{file:t.file},"Die Werkstatt arbeitet. Das Ergebnis taucht als neuer Vorschlag im Auftragsbuch auf (das kann einige Minuten dauern).")),className:"flex h-9 items-center gap-1.5 rounded-lg border border-violet-500/40 bg-violet-500/10 px-3 text-[11px] font-bold uppercase tracking-wide text-violet-300 transition-all hover:bg-violet-500/20 cursor-pointer disabled:opacity-50",children:[r["sk:"+t.file]?e.jsx(m,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(U,{className:"h-3.5 w-3.5"})," Beauftragen"]}),e.jsxs("button",{disabled:!!r["skab:"+t.file],onClick:()=>b("Kandidat verwerfen?",`'${t.title}' wandert ins Archiv des Wissens-Vaults (verworfen/). Der Traum schlägt ihn nicht erneut vor.`,()=>n("skab:"+t.file,"/api/auftragsbuch/skill/ablehnen",{file:t.file})),className:"flex h-9 items-center gap-1.5 rounded-lg border border-red-500/30 bg-red-500/5 px-3 text-[11px] font-bold uppercase tracking-wide text-red-300/90 transition-all hover:bg-red-500/15 cursor-pointer disabled:opacity-50",children:[r["skab:"+t.file]?e.jsx(m,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(I,{className:"h-3.5 w-3.5"})," Verwerfen"]})]})]}),e.jsxs("button",{onClick:()=>o(p=>!p),className:"flex items-center gap-1.5 text-[11px] font-semibold text-muted-foreground hover:text-foreground transition-colors cursor-pointer",children:[c?e.jsx(M,{className:"h-3.5 w-3.5"}):e.jsx(V,{className:"h-3.5 w-3.5"}),e.jsx(P,{className:"h-3.5 w-3.5"})," Vorschlag lesen"]}),c&&e.jsx("pre",{className:"max-h-72 overflow-auto rounded-xl border border-border/50 bg-background/50 p-3 text-[11px] leading-relaxed text-foreground/85 whitespace-pre-wrap",children:t.preview})]})}export{he as AuftragsbuchView};