Files
mission-control-v2/frontend/dist/assets/IdeenView-CJpoHezH.js
T
Hitonabi 20d4f40ed9
Ampel / ampel (push) Successful in 24s
Ideen: zwei Bereiche, drei Karten — Durchdenken nach vorn
User-Befund, und er trifft einen echten Modellierungsfehler von gestern: "Eine
durchgedachte Idee wird ja sowieso mit meinem Ja zu einem IDE-Repo." Stimmt —
/ideen/weiterfuehren macht aus der durchdachten Idee GENAU die IDE-Projekt-Karte,
die der Repo-Weg direkt anlegt. Es sind zwei Stufen EINES Weges, keine zwei Achsen.

Der Haken von gestern war deshalb falsch: "Die Box, allein" + "nur denken" war
anklickbar, submit() setzte dann aber still welt:"ide" und schob einen in die
Zed-Welt, ohne das zu sagen. Genau die versteckte Umschaltung, die anderswo in
diesem Repo als Fassade gilt.

Jetzt GENAU EINE Auswahl aus drei, in zwei Bereichen:
  Du baust selbst, in Zed   [Erst durchdenken] [Direkt ein Repo]
  Oder die Box macht es     [Die Box baut allein]
Die falsche Kombination ist damit strukturell unmoeglich, nicht nur unwahrscheinlich.

Nebengewinn: beim Durchdenken entfallen Tiefe und Ziel am Eingang. Die
Weiter-Leiste fragt beides ohnehin beim "gefaellt mir" — und dann weiss man, was
das Ding ueberhaupt wird. Vorher entschied man LXC-oder-Docker, bevor ein Konzept
existierte.

Ausgewaehlt ist immer eine KARTE, nie ein Bereich — der Bereich gruppiert nur, was
denselben Weg geht. Voreinstellung ist "Erst durchdenken": die Wahl, die am
wenigsten anlegt. Der Einordner ueberschreibt sie ohnehin in ~500 ms.

API unveraendert; alle drei Abbildungen gegen den alten Vertrag geprueft.

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

31 lines
36 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import{c as O,j as e,e as S,ac as je,u as ke,b as Ne,r as l,g as z,af as we,a9 as F,L as D,X as q,ag as de,M as T,V as ce,C as ye,D as J,T as ve,ad as Se,ah as he,q as De,a3 as me}from"./index-BITRSHQi.js";import{S as Ke,H as Q}from"./SectionLabel-CxnAJzn3.js";import{S as ue}from"./send-ByEkObSZ.js";import{C as X}from"./code-xml-B8Mgduyw.js";import{L as Ce}from"./layers-C0bwoJh5.js";import{R as ze}from"./rotate-ccw-Bqk2RuMY.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 Le=O("ArrowDown",[["path",{d:"M12 5v14",key:"s699le"}],["path",{d:"m19 12-7 7-7-7",key:"1idqje"}]]);/**
* @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 Ee=O("ArrowUp",[["path",{d:"m5 12 7-7 7 7",key:"hav0vg"}],["path",{d:"M12 19V5",key:"x0mq9r"}]]);/**
* @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 Pe=O("ClipboardCheck",[["rect",{width:"8",height:"4",x:"8",y:"2",rx:"1",ry:"1",key:"tgr4d6"}],["path",{d:"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2",key:"116196"}],["path",{d:"m9 14 2 2 4-4",key:"df797q"}]]);/**
* @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 pe=O("GitFork",[["circle",{cx:"12",cy:"18",r:"3",key:"1mpf1b"}],["circle",{cx:"6",cy:"6",r:"3",key:"1lh9wr"}],["circle",{cx:"18",cy:"6",r:"3",key:"1h7g24"}],["path",{d:"M18 9v2c0 .6-.4 1-1 1H7c-.6 0-1-.4-1-1V9",key:"1uq4wg"}],["path",{d:"M12 12v3",key:"158kv8"}]]);/**
* @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 Ae=O("Square",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}]]);function Re({text:r,className:c}){const k=(r||"").split(`
`),s=[];let m=[],p=null;const x=g=>{m.length&&(s.push(e.jsx("ul",{className:"mb-3 ml-4 list-disc space-y-1",children:m},g)),m=[])};return k.forEach((g,h)=>{const i=`l${h}`;if(p!==null){g.trimEnd()==="```"?(s.push(e.jsx("pre",{className:"mb-3 overflow-x-auto rounded-xl border border-border/50 bg-background/50 p-3 font-mono text-[11px] leading-relaxed text-foreground/85",children:p.join(`
`)},i)),p=null):p.push(g);return}if(g.trimStart().startsWith("```")){x(i),p=[];return}const j=g.trimEnd();if(!j.trim()){x(i);return}const w=j.match(/^(#{1,4})\s+(.*)$/);if(w){x(i);const N=w[1].length,u=N===1?"text-base font-bold mt-1 mb-2":N===2?"text-sm font-bold mt-4 mb-1.5":"text-xs font-bold mt-3 mb-1 uppercase tracking-wide text-muted-foreground";s.push(e.jsx("p",{className:S(u,"font-space text-foreground"),children:Z(w[2],i)},i));return}const y=j.match(/^\s*[-*•]\s+(.*)$/);if(y){m.push(e.jsx("li",{className:"text-xs leading-relaxed text-foreground/85",children:Z(y[1],i)},i));return}const a=j.match(/^\s*\d+\.\s+(.*)$/);if(a){m.push(e.jsx("li",{className:"text-xs leading-relaxed text-foreground/85",children:Z(a[1],i)},i));return}x(i),s.push(e.jsx("p",{className:"mb-2 text-xs leading-relaxed text-foreground/85",children:Z(j,i)},i))}),x("end"),p!==null&&s.push(e.jsx("pre",{className:"mb-3 overflow-x-auto rounded-xl border border-border/50 bg-background/50 p-3 font-mono text-[11px]",children:p.join(`
`)},"code-end")),e.jsx("div",{className:S("max-w-3xl",c),children:s})}function Z(r,c){return r.split(/(\*\*[^*]+\*\*|\*[^*]+\*|`[^`]+`)/g).map((s,m)=>{const p=`${c}-${m}`;return/^\*\*[^*]+\*\*$/.test(s)?e.jsx("b",{className:"font-semibold text-foreground",children:s.slice(2,-2)},p):/^\*[^*]+\*$/.test(s)?e.jsx("i",{children:s.slice(1,-1)},p):/^`[^`]+`$/.test(s)?e.jsx("code",{className:"rounded bg-background/50 px-1 font-mono text-[11px] text-foreground/90",children:s.slice(1,-1)},p):e.jsx("span",{children:s},p)})}const We={triage:{label:"wird ausgearbeitet …",cls:"text-violet-300 border-violet-500/40 bg-violet-500/10",spin:!0},todo:{label:"wartet",cls:"text-muted-foreground border-border/60 bg-background/30"},scheduled:{label:"geplant",cls:"text-muted-foreground border-border/60 bg-background/30"},ready:{label:"gleich dran",cls:"text-sky-300/80 border-sky-500/30 bg-sky-500/5"},running:{label:"in Arbeit …",cls:"text-sky-300 border-sky-500/40 bg-sky-500/10",spin:!0},review:{label:"im Review",cls:"text-amber-300 border-amber-500/40 bg-amber-500/10"},blocked:{label:"hängt — braucht dich",cls:"text-red-300 border-red-500/40 bg-red-500/10"},done:{label:"fertig ✓",cls:"text-emerald-300 border-emerald-500/40 bg-emerald-500/10"}},$e={box:{label:"BOX",icon:Q,cls:"border-border/60 bg-background/40 text-muted-foreground",title:"Box-Welt: die Werkstatt baut das selbst. Das Ergebnis kommt als Patch-Vorschlag zurück — nichts geht ohne deinen Klick live."},idee:{label:"IDEE",icon:F,cls:"border-sky-500/40 bg-sky-500/10 text-sky-300",title:"Nur durchdacht: die Box hat die Produkt-Idee mit voller Denk-Kaskade zu einem Konzept ausgearbeitet. Kein Gerüst, kein Bau — du liest es und entscheidest, ob ein Projekt draus wird."},projekt:{label:"IDE",icon:X,cls:"border-violet-500/40 bg-violet-500/10 text-violet-300",title:"IDE-Welt: die Box bereitet nur vor (Konzept + Repo + Doku, kein Code). Gebaut wird von dir in Zed."}},Be={needs_input:"Die Box hat eine Frage:",capability:"Die Box kam hier nicht weiter:",transient:"Die Aufgabe hakt:"};function Te(){var ne,ae;const{data:r,isLoading:c}=je(),k=ke(),{showAlert:s,showConfirm:m,dialogElement:p}=Ne(),[x,g]=l.useState(""),[h,i]=l.useState("denken"),[j,w]=l.useState("schlank"),[y,a]=l.useState(!1),N=h!=="box",u=h==="repo",[P,G]=l.useState("lxc"),[K,U]=l.useState(!1),[v,L]=l.useState({}),[$,ge]=l.useState(null),[M,fe]=l.useState(null),[_,Y]=l.useState({}),A=(r==null?void 0:r.items)??[],R=()=>k.invalidateQueries({queryKey:De.ideen});l.useEffect(()=>{const t=x.trim();if(t.length<12){a(!1);return}let n=!1;const d=setTimeout(async()=>{try{const f=await z("/api/ideen/einordnen",{method:"POST",body:JSON.stringify({text:t})});if(n||!(f!=null&&f.ok))return;i(f.nur_denken?"denken":f.wer==="zed"?"repo":"box"),f.tiefe&&w(f.tiefe),a(!0)}catch{}},700);return()=>{n=!0,clearTimeout(d)}},[x]);const ee=$!==null&&(((ne=r==null?void 0:r.items.find(t=>t.id===$))==null?void 0:ne.status)==="triage"||((ae=r==null?void 0:r.items.find(t=>t.id===$))==null?void 0:ae.status)==="running"),B=we($??"",ee);async function te(){const t=x.trim();if(!(t.length<3||K)){U(!0);try{const n=t.length>160?t.slice(0,157)+"…":t;await z("/api/ideen",{method:"POST",body:JSON.stringify({titel:n,notiz:t.length>160?t:"",welt:N?"ide":"box",tiefe:u?j==="gruendlich"?"gruendlich":"simpel":"",ziel:u?P:"",art:h==="denken"?"idee":"projekt"})}),g(""),a(!1),R()}catch(n){s("Das hat nicht geklappt",String((n==null?void 0:n.message)||n))}finally{U(!1)}}}function re(t,n,d){m(`${n} fertige Karte${n===1?"":"n"} wegräumen?`,`${d} verschwindet aus der Liste. Gelöscht wird nichts — die Karten wandern ins Archiv der Queue und bleiben dort lesbar. Laufende, hängende und wartende Karten bleiben unberührt.`,async()=>{var b;const f="arch:"+(t||"*");L(o=>({...o,[f]:!0}));try{const o=await z("/api/ideen/archivieren-alle",{method:"POST",body:JSON.stringify({projekt:t})});(b=o.fehlgeschlagen)!=null&&b.length&&s("Teilweise erledigt",`${o.archiviert} weggeräumt, ${o.fehlgeschlagen.length} nicht: `+o.fehlgeschlagen.map(E=>E.titel).join(", ")),R()}catch(o){s("Das hat nicht geklappt",String((o==null?void 0:o.message)||o))}finally{L(o=>({...o,[f]:!1}))}})}async function be(t){L(n=>({...n,[t]:!0}));try{await z("/api/ideen/archivieren",{method:"POST",body:JSON.stringify({id:t})}),R()}catch(n){s("Das hat nicht geklappt",String((n==null?void 0:n.message)||n))}finally{L(n=>({...n,[t]:!1}))}}async function I(t,n,d,f){L(b=>({...b,[t+n]:!0}));try{await z(d,{method:"POST",body:JSON.stringify(f)}),R()}catch(b){s("Das hat nicht geklappt",String((b==null?void 0:b.message)||b))}finally{L(b=>({...b,[t+n]:!1}))}}async function se(t){const n=(_[t]||"").trim();if(!(n.length<1||v["ans:"+t])){L(d=>({...d,["ans:"+t]:!0}));try{await z("/api/ideen/antwort",{method:"POST",body:JSON.stringify({id:t,antwort:n})}),Y(d=>({...d,[t]:""})),R()}catch(d){s("Das hat nicht geklappt",String((d==null?void 0:d.message)||d))}finally{L(d=>({...d,["ans:"+t]:!1}))}}}const V=t=>{var ie,le;const n=We[t.status]??{label:t.status,cls:"text-muted-foreground border-border/60 bg-background/30"},d=$===t.id,f=t.status==="triage"||t.status==="running"||t.status==="done",b=t.status==="blocked",o=!!v["ans:"+t.id],E=t.status==="running"&&(t.puls_alter??0)>600,oe=t.status==="todo"||t.status==="ready"||t.status==="scheduled";return e.jsxs("li",{className:S("flex flex-col gap-2 rounded-xl border bg-background/30 px-3 py-2",b?"border-red-500/30":E?"border-amber-500/40":"border-border/40"),children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:S("flex shrink-0 items-center gap-1.5 rounded-lg border px-2 py-0.5 text-[10px] font-bold",n.cls),children:[n.spin&&e.jsx(D,{className:"h-3 w-3 animate-spin"}),n.label]}),E&&e.jsxs("span",{className:"flex shrink-0 items-center gap-1 rounded-lg border border-amber-500/40 bg-amber-500/10 px-2 py-0.5 text-[10px] font-bold text-amber-300",title:"Der Worker lebt, gibt aber kein Lebenszeichen mehr — vermutlich wartet er auf etwas, das nie kommt. „Neuer Versuch“ startet die Karte frisch.",children:[e.jsx(ve,{className:"h-3 w-3"})," ",Math.round((t.puls_alter??0)/60)," min ohne Regung"]}),(t.prio??0)!==0&&e.jsxs("span",{className:"shrink-0 rounded bg-background/50 px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground",title:"Priorität — höher kommt zuerst dran (bei gleicher Prio: Erstellzeit)",children:["P",t.prio]}),(()=>{const C=$e[t.art||(t.welt==="ide"?"projekt":"box")];if(!C)return null;const H=C.icon;return e.jsxs("span",{className:S("flex shrink-0 items-center gap-1 rounded-lg border px-2 py-0.5 text-[10px] font-bold",C.cls),title:C.title,children:[e.jsx(H,{className:"h-3 w-3"})," ",C.label]})})(),e.jsx("span",{className:"min-w-0 flex-1 truncate text-xs text-foreground",title:t.titel,children:t.titel}),e.jsxs("span",{className:"flex shrink-0 items-center gap-1 text-[10px] text-muted-foreground/70",children:[e.jsx(ce,{className:"h-3 w-3"}),Se(t.erstellt)]}),oe&&e.jsxs("span",{className:"flex shrink-0 items-center",children:[e.jsx("button",{disabled:!!v["pr:"+t.id],onClick:()=>I("pr:",t.id,"/api/ideen/prio",{id:t.id,richtung:"hoch"}),title:"Vorziehen (Prio +1)",className:"rounded-md p-1 text-muted-foreground/60 transition-colors hover:text-foreground cursor-pointer disabled:opacity-50",children:e.jsx(Ee,{className:"h-3.5 w-3.5"})}),e.jsx("button",{disabled:!!v["pr:"+t.id],onClick:()=>I("pr:",t.id,"/api/ideen/prio",{id:t.id,richtung:"runter"}),title:"Zurückstellen (Prio 1)",className:"rounded-md p-1 text-muted-foreground/60 transition-colors hover:text-foreground cursor-pointer disabled:opacity-50",children:e.jsx(Le,{className:"h-3.5 w-3.5"})})]}),(t.status==="running"||b)&&e.jsx("button",{disabled:!!v["rt:"+t.id],onClick:()=>m("Neuer Versuch?",t.status==="running"?`Der laufende Worker von '${t.titel.slice(0,60)}' wird beendet (samt gestarteter Test-Prozesse) und die Karte frisch gestartet. Bisheriger Zwischenstand im Workspace bleibt liegen.`:`Die Karte '${t.titel.slice(0,60)}' wird entsperrt und läuft weiter, sobald ein Platz frei ist.`,()=>I("rt:",t.id,"/api/ideen/retry",{id:t.id})),title:"Neuer Versuch — Karte frisch starten",className:S("shrink-0 rounded-md p-1 transition-colors cursor-pointer disabled:opacity-50",E?"text-amber-300 hover:text-amber-200":"text-muted-foreground/60 hover:text-foreground"),children:v["rt:"+t.id]?e.jsx(D,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(ze,{className:"h-3.5 w-3.5"})}),(t.status==="running"||oe||t.status==="triage")&&e.jsx("button",{disabled:!!v["st:"+t.id],onClick:()=>m("Karte stoppen?",`'${t.titel.slice(0,60)}' wird angehalten${t.status==="running"?" und der laufende Worker beendet":""}. Sie bleibt als gestoppt im Board und kann jederzeit per „Neuer Versuch“ weiterlaufen.`,()=>I("st:",t.id,"/api/ideen/stopp",{id:t.id})),title:"Stoppen — Karte anhalten",className:"shrink-0 rounded-md p-1 text-muted-foreground/60 transition-colors hover:text-red-300 cursor-pointer disabled:opacity-50",children:v["st:"+t.id]?e.jsx(D,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(Ae,{className:"h-3.5 w-3.5"})}),(t.status==="done"||b)&&e.jsx("button",{disabled:!!v[t.id],onClick:()=>be(t.id),title:b?"Aufgeben und aus der Liste räumen (wandert ins Kanban-Archiv)":"Aus der Liste räumen (wandert ins Kanban-Archiv)",className:"shrink-0 rounded-md p-1 text-muted-foreground/60 transition-colors hover:text-foreground cursor-pointer disabled:opacity-50",children:v[t.id]?e.jsx(D,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(q,{className:"h-3.5 w-3.5"})}),t.welt==="ide"&&(t.status==="running"||t.status==="done")&&e.jsxs("button",{onClick:()=>fe(M===t.id?null:t.id),title:"Konzept ansehen (das ausgearbeitete KONZEPT.md)",className:S("flex shrink-0 items-center gap-1 rounded-md px-1.5 py-1 text-[10px] font-bold transition-colors cursor-pointer",M===t.id?"text-violet-300":"text-violet-300/70 hover:text-violet-200"),children:[e.jsx(he,{className:"h-3.5 w-3.5"})," Konzept"]}),f&&e.jsx("button",{onClick:()=>ge(d?null:t.id),title:t.status==="done"?"Ergebnis anzeigen":"Worker-Log anzeigen",className:"shrink-0 rounded-md p-1 text-muted-foreground/60 transition-colors hover:text-foreground cursor-pointer",children:d?e.jsx(J,{className:"h-3.5 w-3.5"}):e.jsx(T,{className:"h-3.5 w-3.5"})})]}),M===t.id&&e.jsx(Ie,{id:t.id,istIdee:t.art==="idee"&&t.status==="done",onWeiter:R}),t.status==="running"&&t.notiz&&e.jsxs("p",{className:"-mt-1 ml-1 text-[11px] italic leading-relaxed text-sky-200/80",title:"Jüngste Zwischenmeldung des Workers (Heartbeat)",children:["„",t.notiz,"“"]}),(t.status==="todo"||t.status==="scheduled"||t.status==="ready")&&(((ie=t.wartet_auf)==null?void 0:ie.length)??0)>0&&e.jsxs("p",{className:"-mt-1 ml-1 text-[10px] text-muted-foreground/70",children:["→ wartet auf: ",t.wartet_auf.join(" · ")]}),b&&e.jsxs("div",{className:"space-y-2 border-t border-red-500/20 pt-2",children:[e.jsxs("p",{className:"flex items-start gap-1.5 text-[11px] leading-relaxed text-red-200/90",children:[e.jsx(de,{className:"mt-0.5 h-3.5 w-3.5 shrink-0 text-red-300"}),e.jsxs("span",{children:[e.jsx("b",{children:Be[t.frage_kind||""]??"Die Aufgabe hängt und wartet auf dich:"})," ",t.frage?e.jsx("span",{className:"text-foreground/90",children:t.frage}):e.jsx("span",{className:"text-muted-foreground italic",children:"kein genauer Grund hinterlegt — antworte einfach mit einer Entscheidung, dann läuft sie weiter."})]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{value:_[t.id]||"",onChange:C=>Y(H=>({...H,[t.id]:C.target.value})),onKeyDown:C=>{C.key==="Enter"&&se(t.id)},placeholder:"Deine Antwort — die Box macht damit weiter",maxLength:2e3,className:"h-8 min-w-0 flex-1 rounded-lg border border-border/60 bg-background/60 px-2.5 text-xs text-foreground placeholder:text-muted-foreground/50 focus:border-red-400/50 focus:outline-none"}),e.jsxs("button",{onClick:()=>se(t.id),disabled:o||(_[t.id]||"").trim().length<1,className:"flex h-8 shrink-0 items-center gap-1.5 rounded-lg border border-emerald-500/40 bg-emerald-500/10 px-3 text-[10px] font-bold uppercase tracking-wide text-emerald-300 transition-all hover:bg-emerald-500/20 cursor-pointer disabled:opacity-50",children:[o?e.jsx(D,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(ue,{className:"h-3.5 w-3.5"})," Antworten & weiter"]})]})]}),d&&f&&t.status!=="done"&&e.jsx("div",{className:"ml-2 -mt-1",children:e.jsx("div",{className:"rounded-lg border border-border/50 bg-background/50 p-2",children:ee&&B.isLoading?e.jsx("p",{className:"text-[10px] text-muted-foreground animate-pulse",children:"Log wird geladen …"}):B.error?e.jsx("p",{className:"text-[10px] text-red-400",children:"Log nicht ladbar"}):(le=B.data)!=null&&le.available&&B.data.lines.length>0?e.jsx("pre",{className:"max-h-64 overflow-auto font-mono text-[10px] leading-relaxed text-foreground/80 whitespace-pre-wrap",children:B.data.lines.join(`
`)}):e.jsx("p",{className:"text-[10px] text-muted-foreground",children:"Kein Log verfügbar"})})}),d&&t.status==="done"&&e.jsx(Ze,{id:t.id})]},t.id)};return r&&!r.available?null:e.jsxs("section",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx(Ke,{icon:F,children:(()=>{if(!r)return"Ideen-Queue";const t=d=>A.filter(f=>d.includes(f.status)).length,n=[t(["blocked"])>0?`${t(["blocked"])} braucht dich`:"",t(["running","triage","review"])>0?`${t(["running","triage","review"])} in Arbeit`:"",t(["todo","scheduled","ready"])>0?`${t(["todo","scheduled","ready"])} wartet`:"",t(["done"])>0?`${t(["done"])} fertig`:""].filter(Boolean);return n.length?n.join(" · "):"noch nichts in der Queue"})()}),(()=>{const t=A.filter(n=>n.status==="done").length;return t===0?null:e.jsxs("button",{disabled:!!v["arch:*"],onClick:()=>re("",t,`Alle ${t} fertigen Karten`),title:"Räumt ALLE fertigen Karten weg — auch die in abgeschlossenen Projekt-Ketten. Laufende, hängende und wartende bleiben unberührt.",className:"flex shrink-0 items-center gap-1.5 rounded-lg border border-border/60 px-2.5 py-1 text-[11px] font-semibold text-muted-foreground transition-all hover:border-primary/40 hover:text-foreground disabled:opacity-50 cursor-pointer",children:[v["arch:*"]?e.jsx(D,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(q,{className:"h-3.5 w-3.5"}),t," fertige wegräumen"]})})()]}),e.jsxs("div",{className:"mc-card p-4 space-y-4",children:[e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{value:x,onChange:t=>{g(t.target.value),a(!1)},onKeyDown:t=>{t.key==="Enter"&&te()},placeholder:"Was soll entstehen?",className:"h-10 min-w-0 flex-1 rounded-lg border border-border/60 bg-background/50 px-3 text-sm text-foreground placeholder:text-muted-foreground/50 focus:border-primary/50 focus:outline-none"}),e.jsxs("button",{onClick:te,disabled:K||x.trim().length<3,className:"flex h-10 shrink-0 items-center gap-1.5 rounded-lg border border-primary/40 bg-primary/10 px-4 text-xs font-semibold text-primary transition-all hover:bg-primary/20 disabled:opacity-40 cursor-pointer",children:[K?e.jsx(D,{className:"h-4 w-4 animate-spin"}):e.jsx(ue,{className:"h-4 w-4"}),"Los"]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"mb-2 text-[11px] text-muted-foreground/70",children:"Was soll damit passieren?"}),e.jsxs("div",{className:"rounded-xl border border-border/40 bg-background/20 p-3",children:[e.jsxs("div",{className:"mb-2 flex items-center gap-2",children:[e.jsx(X,{className:"h-4 w-4 shrink-0 text-muted-foreground"}),e.jsx("span",{className:"text-[11px] font-semibold uppercase tracking-wider text-muted-foreground",children:"Du baust selbst, in Zed"})]}),e.jsx("div",{className:"grid gap-2 sm:grid-cols-2",children:[{id:"denken",icon:F,titel:"Erst durchdenken",text:"Du bekommst ein Konzept. Gefällt es dir, wird auf Klick ein Repo daraus."},{id:"repo",icon:pe,titel:"Direkt ein Repo",text:"Konzept und Gitea-Repo in einem Zug — wenn du es ohnehin bauen willst."}].map(t=>e.jsx(xe,{k:t,aktiv:h===t.id,vorgeschlagen:y,onWahl:()=>{i(t.id),a(!1)}},t.id))}),h==="repo"&&e.jsxs("div",{className:"mt-3 flex flex-wrap items-center gap-x-3 gap-y-2 border-t border-border/30 pt-3",children:[e.jsx("span",{className:"text-[11px] text-muted-foreground/70",children:"Wie gründlich?"}),e.jsx("div",{className:"flex rounded-lg border border-border/60 p-0.5",children:[["schlank","schlank"],["gruendlich","gründlich"]].map(([t,n])=>e.jsx("button",{onClick:()=>{w(t),a(!1)},className:S("rounded px-2.5 py-1 text-[10px] font-bold uppercase tracking-wide transition-all cursor-pointer",j===t?"bg-primary/15 text-primary":"text-muted-foreground/60 hover:text-foreground"),children:n},t))}),e.jsx("span",{className:"text-[10px] text-muted-foreground/60",children:j==="gruendlich"?"mehrere Fach-Rollen, bis zu 3 Denk-Runden, mehrfacher Härtetest":"2 Rollen, eine Denk-Runde — ein paar Minuten"}),e.jsxs("span",{className:"ml-auto flex items-center gap-1.5",children:[e.jsx("span",{className:"text-[11px] text-muted-foreground/70",children:"Läuft als"}),e.jsx("div",{className:"flex rounded-lg border border-border/40 p-0.5",children:[["lxc","LXC"],["docker","Docker"]].map(([t,n])=>e.jsx("button",{onClick:()=>G(t),title:t==="lxc"?"Dienst in einem eigenen Proxmox-LXC (systemd, kein Docker). Wird vom Backup-Server automatisch mitgesichert.":"Natives Docker: Dockerfile + compose, portabel und pipeline-tauglich.",className:S("rounded px-2 py-0.5 text-[10px] font-semibold transition-all cursor-pointer",P===t?"bg-foreground/10 text-foreground":"text-muted-foreground/50 hover:text-foreground/80"),children:n},t))})]})]}),h==="denken"&&e.jsxs("p",{className:"mt-2.5 flex items-start gap-1.5 border-t border-border/30 pt-2.5 text-[10px] leading-relaxed text-muted-foreground/60",children:[e.jsx(de,{className:"mt-px h-3 w-3 shrink-0"}),'Wie gründlich und wo es läuft, fragt die Box erst beim „gefällt mir" — dann weißt du mehr.']})]}),e.jsxs("div",{className:"mt-2 rounded-xl border border-border/40 bg-background/20 p-3",children:[e.jsxs("div",{className:"mb-2 flex items-center gap-2",children:[e.jsx(Q,{className:"h-4 w-4 shrink-0 text-muted-foreground"}),e.jsx("span",{className:"text-[11px] font-semibold uppercase tracking-wider text-muted-foreground",children:"Oder die Box macht es"})]}),e.jsx(xe,{k:{id:"box",icon:Q,titel:"Die Box baut allein",text:"Für dein Heimlabor — Mission Control, Lucy, Rippy, Wartung, Doku. Das Ergebnis kommt als Patch-Vorschlag ins Auftragsbuch; nichts geht ohne deinen Klick live."},aktiv:h==="box",vorgeschlagen:y,onWahl:()=>{i("box"),a(!1)}})]})]}),c&&e.jsxs("p",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[e.jsx(D,{className:"h-3.5 w-3.5 animate-spin"})," Queue wird geladen …"]}),(r==null?void 0:r.fehler)&&e.jsx("p",{className:"text-xs text-amber-300",children:"Queue gerade nicht lesbar — neuer Versuch läuft."}),A.length>0&&e.jsxs("div",{className:"space-y-3",children:[((r==null?void 0:r.projekte)??[]).map(t=>e.jsx(Oe,{projekt:t,karten:A.filter(n=>n.projekt===t.key),zeile:V,onArchivAlle:re,raeumt:!!v["arch:"+t.key]},t.key)),(()=>{const t=new Set(((r==null?void 0:r.projekte)??[]).map(o=>o.key)),n=A.filter(o=>!o.projekt||!t.has(o.projekt));if(n.length===0)return null;const d=n.filter(o=>W[o.status]!==void 0).sort((o,E)=>W[o.status]-W[E.status]||(o.erstellt??0)-(E.erstellt??0)),f=n.filter(o=>["todo","scheduled"].includes(o.status)),b=n.filter(o=>o.status==="done");return e.jsxs("div",{className:"space-y-2",children:[d.length>0&&e.jsx("ul",{className:"space-y-1.5",children:d.map(o=>V(o))}),f.length>0&&e.jsxs("details",{className:"group",children:[e.jsxs("summary",{className:"flex cursor-pointer list-none items-center gap-1.5 py-1 text-[11px] text-muted-foreground/70 hover:text-foreground",children:[e.jsx(T,{className:"h-3 w-3 transition-transform group-open:rotate-90"}),e.jsx(ce,{className:"h-3 w-3"})," Wartet (",f.length,")"]}),e.jsx("ul",{className:"mt-1.5 space-y-1.5",children:f.map(o=>V(o))})]}),b.length>0&&e.jsxs("details",{className:"group",children:[e.jsxs("summary",{className:"flex cursor-pointer list-none items-center gap-1.5 py-1 text-[11px] text-muted-foreground/70 hover:text-foreground",children:[e.jsx(T,{className:"h-3 w-3 transition-transform group-open:rotate-90"}),e.jsx(ye,{className:"h-3 w-3 text-emerald-400/70"})," Fertig (",b.length,")"]}),e.jsx("ul",{className:"mt-1.5 space-y-1.5",children:b.map(o=>V(o))})]})]})})()]}),(r==null?void 0:r.available)&&!c&&A.length===0&&e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-[11px] text-muted-foreground/70",children:"Noch nichts hier. Zum Beispiel:"}),["Ein kleines Werkzeug, das meine Fotos nach Aufnahmedatum in Ordner sortiert","Rippy soll die Untertitel-Spur automatisch auswählen statt zu fragen","Lohnt sich ein Dashboard für die Stromzähler, oder reicht Home Assistant?"].map(t=>e.jsxs("button",{onClick:()=>g(t),className:"flex w-full items-center gap-2 rounded-lg border border-border/40 bg-background/20 px-3 py-2 text-left text-xs text-muted-foreground transition-all hover:border-primary/40 hover:text-foreground cursor-pointer",children:[e.jsx(F,{className:"h-3.5 w-3.5 shrink-0 text-muted-foreground/50"}),t]},t))]})]}),p]})}function xe({k:r,aktiv:c,vorgeschlagen:k,onWahl:s}){return e.jsxs("button",{onClick:s,className:S("rounded-xl border p-3 text-left transition-all cursor-pointer",c?"border-primary/60 bg-primary/5":"border-border/50 hover:border-border"),children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(r.icon,{className:S("h-4 w-4 shrink-0",c?"text-primary":"text-muted-foreground")}),e.jsx("span",{className:"text-xs font-semibold text-foreground",children:r.titel}),c&&k&&e.jsx("span",{className:"ml-auto shrink-0 rounded border border-primary/40 bg-primary/10 px-1.5 py-0.5 text-[10px] font-bold text-primary",children:"Vorschlag"})]}),e.jsx("p",{className:"mt-1 text-[11px] leading-relaxed text-muted-foreground",children:r.text})]})}const W={blocked:0,running:1,review:2,ready:3,triage:4};function Oe({projekt:r,karten:c,zeile:k,onArchivAlle:s,raeumt:m}){const[p,x]=l.useState(!1),[g,h]=l.useState(!1),i=c.filter(a=>W[a.status]!==void 0).sort((a,N)=>W[a.status]-W[N.status]||(a.erstellt??0)-(N.erstellt??0)),j=c.filter(a=>a.status==="todo"||a.status==="scheduled").sort((a,N)=>{var u,P;return((u=a.wartet_auf)!=null&&u.length?1:0)-((P=N.wartet_auf)!=null&&P.length?1:0)||(a.erstellt??0)-(N.erstellt??0)}),w=c.filter(a=>a.status==="done").sort((a,N)=>(N.fertig??0)-(a.fertig??0)),y=r.gesamt>0?Math.round(r.fertig/r.gesamt*100):0;return e.jsxs("div",{className:"space-y-2 rounded-xl border border-border/50 bg-background/20 p-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ce,{className:"h-4 w-4 shrink-0 text-primary/70"}),e.jsx("p",{className:"min-w-0 flex-1 truncate text-xs font-semibold text-foreground",title:r.titel,children:r.titel}),e.jsxs("span",{className:"shrink-0 text-[10px] text-muted-foreground",children:[r.fertig," von ",r.gesamt," fertig"]})]}),e.jsx("div",{className:"h-1 overflow-hidden rounded-full bg-background/60",title:`${y}%`,children:e.jsx("div",{className:"h-1 rounded-full bg-primary/70 transition-all",style:{width:`${y}%`}})}),i.length>0&&e.jsx("ul",{className:"space-y-1.5",children:i.map(a=>k(a))}),j.length>0&&e.jsxs("div",{children:[e.jsxs("button",{onClick:()=>x(a=>!a),className:"flex items-center gap-1.5 text-[11px] font-semibold text-muted-foreground hover:text-foreground transition-colors cursor-pointer",children:[p?e.jsx(J,{className:"h-3.5 w-3.5"}):e.jsx(T,{className:"h-3.5 w-3.5"}),j.length," Karte",j.length===1?"":"n"," in der Kette — laufen automatisch der Reihe nach"]}),p&&e.jsx("ul",{className:"mt-1.5 space-y-1.5",children:j.map(a=>k(a))})]}),w.length>0&&e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("button",{onClick:()=>h(a=>!a),className:"flex items-center gap-1.5 text-[11px] font-semibold text-emerald-300/70 hover:text-emerald-300 transition-colors cursor-pointer",children:[g?e.jsx(J,{className:"h-3.5 w-3.5"}):e.jsx(T,{className:"h-3.5 w-3.5"}),w.length," fertig"]}),s&&e.jsxs("button",{disabled:m,onClick:()=>s(r.key,w.length,`${r.titel}"`),title:"Räumt die fertigen Karten dieser Kette weg (Archiv, nichts wird gelöscht).",className:"flex items-center gap-1 text-[11px] text-muted-foreground/60 transition-colors hover:text-foreground disabled:opacity-50 cursor-pointer",children:[m?e.jsx(D,{className:"h-3 w-3 animate-spin"}):e.jsx(q,{className:"h-3 w-3"}),"wegräumen"]})]}),g&&e.jsx("ul",{className:"mt-1.5 space-y-1.5",children:w.map(a=>k(a))})]})]})}function Ie({id:r,istIdee:c,onWeiter:k}){const[s,m]=l.useState(null),[p,x]=l.useState(!1),[g,h]=l.useState(0);return l.useEffect(()=>{let i=!1;return m(null),x(!1),z(`/api/ideen/${r}/konzept`).then(j=>{i||m(j)}).catch(()=>{i||x(!0)}),()=>{i=!0}},[r,g]),e.jsx("div",{className:"ml-2 -mt-1",children:e.jsxs("div",{className:"rounded-lg border border-violet-500/25 bg-violet-500/[0.04] p-3",children:[e.jsxs("div",{className:"mb-2 flex items-center gap-2",children:[e.jsxs("p",{className:"flex items-center gap-1.5 text-[10px] font-bold uppercase tracking-wide text-violet-300",children:[e.jsx(he,{className:"h-3 w-3"})," Konzept"]}),(s==null?void 0:s.repo)&&e.jsxs("a",{href:`https://git.tobisniceshomelab.ddnsfree.com/${s.repo}`,className:"flex items-center gap-1 text-[10px] text-violet-300/70 hover:text-violet-200",children:[e.jsx(pe,{className:"h-3 w-3"})," ",s.repo]}),!(s!=null&&s.repo)&&(s==null?void 0:s.quelle)==="datei"&&e.jsx("span",{className:"truncate font-mono text-[10px] text-muted-foreground/70",title:"Der Worker hat kein Repo angelegt — das Konzept liegt als Datei auf der Box.",children:s.pfad}),e.jsx("button",{onClick:()=>h(i=>i+1),title:"Neu laden",className:"ml-auto rounded p-0.5 text-muted-foreground/50 hover:text-foreground cursor-pointer",children:e.jsx(me,{className:"h-3 w-3"})})]}),p?e.jsx("p",{className:"text-[11px] text-red-400",children:"Konzept nicht ladbar — später nochmal versuchen."}):s===null?e.jsx("p",{className:"text-[10px] text-muted-foreground animate-pulse",children:"Konzept wird geladen …"}):s.konzept?e.jsx("div",{className:"max-h-[28rem] overflow-y-auto pr-1",children:e.jsx(Re,{text:s.konzept})}):e.jsx("p",{className:"text-[11px] text-muted-foreground italic",children:s.error||"Noch kein Konzept — das Projekt wird gerade vorbereitet."}),c&&(s==null?void 0:s.konzept)&&e.jsx(Ve,{id:r,onFertig:k})]})})}function Ve({id:r,onFertig:c}){const[k,s]=l.useState("lxc"),[m,p]=l.useState("simpel"),[x,g]=l.useState(!1),[h,i]=l.useState(null),[j,w]=l.useState(""),[y,a]=l.useState(""),N=async(u,P,G)=>{g(!0),w("");try{const K=await z(u,{method:"POST",body:JSON.stringify(P)});i({id:K.id,art:G}),c==null||c()}catch(K){w(String((K==null?void 0:K.message)||K))}finally{g(!1)}};return h?e.jsx("p",{className:"mt-3 border-t border-violet-500/20 pt-2 text-[11px] text-emerald-300",children:h.art==="projekt"?e.jsxs(e.Fragment,{children:["Projekt-Karte ",e.jsx("span",{className:"font-mono",children:h.id})," ist angelegt — die Box bereitet das Repo vor (Konzept übernimmt sie, sie denkt es nicht neu). Danach öffnest du es in Zed."]}):e.jsxs(e.Fragment,{children:["Überarbeitung ",e.jsx("span",{className:"font-mono",children:h.id}),' läuft — die Box arbeitet deine Rückmeldung ein und schreibt die neue Fassung an dieselbe Stelle. Danach hier wieder „Konzept" öffnen.']})}):e.jsxs("div",{className:"mt-3 space-y-3 border-t border-violet-500/20 pt-2.5",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("p",{className:"text-[11px] text-muted-foreground",children:[e.jsx("b",{className:"text-sky-300/90",children:"Passt etwas nicht?"})," Schreib hin, was anders werden soll — die Box arbeitet es ein und lässt den Rest stehen. Beliebig oft wiederholbar."]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{value:y,onChange:u=>a(u.target.value),onKeyDown:u=>{u.key==="Enter"&&y.trim().length>=3&&!x&&N("/api/ideen/nachschaerfen",{id:r,hinweis:y},"runde")},placeholder:"z. B. „Punkt 3: kein WebSocket, das ist mir zu fragil — nimm Polling“",maxLength:2e3,className:"h-8 min-w-0 flex-1 rounded-lg border border-border/60 bg-background/60 px-2.5 text-xs text-foreground placeholder:text-muted-foreground/50 focus:border-sky-400/50 focus:outline-none"}),e.jsxs("button",{onClick:()=>N("/api/ideen/nachschaerfen",{id:r,hinweis:y},"runde"),disabled:x||y.trim().length<3,className:"flex h-8 shrink-0 items-center gap-1.5 rounded-lg border border-sky-500/40 bg-sky-500/10 px-3 text-[10px] font-bold uppercase tracking-wide text-sky-300 transition-all hover:bg-sky-500/20 cursor-pointer disabled:opacity-50",children:[x?e.jsx(D,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(me,{className:"h-3.5 w-3.5"}),"Nachschärfen"]})]})]}),e.jsxs("p",{className:"text-[11px] text-muted-foreground",children:[e.jsx("b",{className:"text-violet-300/90",children:"Passt es so?"})," Dann macht die Box daraus ein startklares Repo — Konzept wird übernommen (nicht neu gedacht), dazu Roadmap, AGENTS.md & Co. Gebaut wird danach von dir in Zed."]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-2",children:[e.jsx("span",{className:"text-[11px] text-muted-foreground/70",children:"Ziel"}),e.jsx("div",{className:"flex rounded-lg border border-border/40 p-0.5",children:["lxc","docker"].map(u=>e.jsx("button",{onClick:()=>s(u),title:u==="lxc"?"Dienst in einem eigenen Proxmox-LXC (systemd, kein Docker) — wird automatisch mitgesichert.":"Natives Docker: Dockerfile + compose, portabel und pipeline-tauglich.",className:S("rounded px-2 py-0.5 text-[10px] font-semibold transition-all cursor-pointer",k===u?"bg-foreground/10 text-foreground":"text-muted-foreground/50 hover:text-foreground/80"),children:u==="lxc"?"LXC":"Docker"},u))}),e.jsx("span",{className:"text-[11px] text-muted-foreground/70",children:"Aufwand"}),e.jsx("div",{className:"flex rounded-lg border border-border/40 p-0.5",children:["simpel","gruendlich"].map(u=>e.jsx("button",{onClick:()=>p(u),title:u==="simpel"?"Konzept ist schon gehärtet — nur kurz auf die Bau-Sicht nachschärfen (empfohlen).":"Nochmal volle Kaskade über die Bau-Sicht: mehrere Rollen, Härtetests. Dauert entsprechend.",className:S("rounded px-2 py-0.5 text-[10px] font-semibold transition-all cursor-pointer",m===u?"bg-foreground/10 text-foreground":"text-muted-foreground/50 hover:text-foreground/80"),children:u==="simpel"?"schlank":"gründlich"},u))}),e.jsxs("button",{onClick:()=>N("/api/ideen/weiterfuehren",{id:r,ziel:k,tiefe:m},"projekt"),disabled:x,className:"ml-auto flex h-8 shrink-0 items-center gap-1.5 rounded-lg border border-violet-500/40 bg-violet-500/10 px-3 text-[10px] font-bold uppercase tracking-wide text-violet-300 transition-all hover:bg-violet-500/20 cursor-pointer disabled:opacity-50",children:[x?e.jsx(D,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(X,{className:"h-3.5 w-3.5"}),"Gefällt mir — Projekt daraus machen"]})]}),j&&e.jsx("p",{className:"text-[11px] text-red-400",children:j})]})}function Ze({id:r}){const[c,k]=l.useState(null),[s,m]=l.useState(!1),[p,x]=l.useState(0);l.useEffect(()=>{let h=!1;return m(!1),k(null),z(`/api/ideen/${r}/ergebnis`).then(i=>{h||k(i)}).catch(()=>{h||m(!0)}),()=>{h=!0}},[r,p]);const g=c?c.summary||c.result:"";return e.jsx("div",{className:"ml-2 -mt-1",children:e.jsxs("div",{className:"rounded-lg border border-emerald-500/25 bg-emerald-500/5 p-2.5",children:[e.jsxs("p",{className:"mb-1 flex items-center gap-1.5 text-[10px] font-bold uppercase tracking-wide text-emerald-300",children:[e.jsx(Pe,{className:"h-3 w-3"})," Ergebnis des Workers"]}),s?e.jsx("button",{type:"button",onClick:()=>x(h=>h+1),className:"text-[10px] text-red-400 underline decoration-dotted underline-offset-2 hover:text-red-300",children:"Ergebnis nicht ladbar — nochmal versuchen"}):c===null?e.jsx("p",{className:"text-[10px] text-muted-foreground animate-pulse",children:"Wird geladen …"}):g?e.jsx("p",{className:"max-h-64 overflow-y-auto whitespace-pre-wrap text-xs leading-relaxed text-foreground/85",children:g}):e.jsx("p",{className:"text-[10px] text-muted-foreground italic",children:"Der Worker hat keine Abschluss-Zusammenfassung hinterlassen (ältere Karte oder Protokollverstoß)."})]})})}function Je(){return e.jsxs("div",{className:"space-y-6",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:"Ideen"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Schreib hin, was entstehen soll — die Box arbeitet es aus. Je nach Modus baut sie es selbst, denkt es nur durch, oder legt dir ein startklares Repo fuer Zed an."})]}),e.jsx(Te,{})]})}export{Je as IdeenView};