991c9a2f82
Ampel / ampel (push) Successful in 22s
Die Queue war 703 der 1147 Zeilen in AuftragsbuchView — die MEHRHEIT einer Seite,
die nach etwas anderem benannt ist. Und sie laufen gegenlaeufig: Auftragsbuch =
die Box schlaegt DIR vor (Eingang), Ideen = DU beauftragst die Box (Ausgang).
Seit dem Umbau ist Idee -> Konzept -> Repo -> Zed der Haupteingang des Systems
und gehoert in die Seitenleiste, nicht in einen Unterabschnitt.
Umzug (reines Verschieben, kein Logik-Umbau):
AuftragsbuchView 1147 -> 406 Zeilen Bundle 51,0 -> 17,8 KB
IdeenView neu, 785 Zeilen Bundle 32,7 KB, laedt nur bei Bedarf
fmtWhen -> lib/format.ts (dessen Kopf genau davor warnt: "vorher in
einzelnen Views dupliziert")
SectionLabel -> components/ui/ (beide Seiten brauchen sie jetzt)
Zwei inhaltliche Aenderungen:
1. Die flache Einzelkarten-Liste wird gruppiert — mit der Ordnung, die
ProjektGruppe fuer Ketten LAENGST benutzt (AKTIV_RANG): aktiv zuerst,
Wartende und Fertige eingeklappt. Bei 19 Karten, davon 16 fertig, gingen die
drei relevanten in der Erstellzeit-Liste unter.
2. Die Kopfzeile sagt jetzt "1 braucht dich · 2 in Arbeit · 16 fertig" statt
einer nackten Gesamtzahl.
Das Auftragsbuch zaehlte im gruenen "Nichts zu entscheiden" bisher haengende
Ideen mit, damit es nicht luegt, waehrend direkt darunter eine Karte haengt.
Nach der Trennung wird daraus ein anklickbarer Querverweis auf die Ideen-Seite —
dieselbe Ehrlichkeit, jetzt mit Weg dorthin.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
31 lines
34 KiB
JavaScript
31 lines
34 KiB
JavaScript
import{c as $,j as e,e as N,ac as ue,u as xe,b as he,r as l,af as me,a9 as Z,L as K,M as A,V as se,C as pe,g as z,D as _,T as ge,ad as be,X as fe,ag as ae,ah as ke,q as je,a3 as oe}from"./index-CoRdA_gp.js";import{S as Ne,H as ie}from"./SectionLabel-DLTvFJ7b.js";import{C as W}from"./code-xml-qgfASNHl.js";import{S as ne}from"./send-Dt2f8lfr.js";import{L as we}from"./layers-Dh094O1c.js";import{R as ve}from"./rotate-ccw-BHsRFGD7.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 ye=$("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 De=$("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 Se=$("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 Ce=$("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 Ke=$("Square",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}]]);function ze({text:r,className:m}){const j=(r||"").split(`
|
||
`),s=[];let p=[],d=null;const u=g=>{p.length&&(s.push(e.jsx("ul",{className:"mb-3 ml-4 list-disc space-y-1",children:p},g)),p=[])};return j.forEach((g,o)=>{const i=`l${o}`;if(d!==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:d.join(`
|
||
`)},i)),d=null):d.push(g);return}if(g.trimStart().startsWith("```")){u(i),d=[];return}const b=g.trimEnd();if(!b.trim()){u(i);return}const n=b.match(/^(#{1,4})\s+(.*)$/);if(n){u(i);const y=n[1].length,c=y===1?"text-base font-bold mt-1 mb-2":y===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:N(c,"font-space text-foreground"),children:G(n[2],i)},i));return}const f=b.match(/^\s*[-*•]\s+(.*)$/);if(f){p.push(e.jsx("li",{className:"text-xs leading-relaxed text-foreground/85",children:G(f[1],i)},i));return}const v=b.match(/^\s*\d+\.\s+(.*)$/);if(v){p.push(e.jsx("li",{className:"text-xs leading-relaxed text-foreground/85",children:G(v[1],i)},i));return}u(i),s.push(e.jsx("p",{className:"mb-2 text-xs leading-relaxed text-foreground/85",children:G(b,i)},i))}),u("end"),d!==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:d.join(`
|
||
`)},"code-end")),e.jsx("div",{className:N("max-w-3xl",m),children:s})}function G(r,m){return r.split(/(\*\*[^*]+\*\*|\*[^*]+\*|`[^`]+`)/g).map((s,p)=>{const d=`${m}-${p}`;return/^\*\*[^*]+\*\*$/.test(s)?e.jsx("b",{className:"font-semibold text-foreground",children:s.slice(2,-2)},d):/^\*[^*]+\*$/.test(s)?e.jsx("i",{children:s.slice(1,-1)},d):/^`[^`]+`$/.test(s)?e.jsx("code",{className:"rounded bg-background/50 px-1 font-mono text-[11px] text-foreground/90",children:s.slice(1,-1)},d):e.jsx("span",{children:s},d)})}const Pe={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"}},Ee={box:{label:"BOX",icon:ie,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:Z,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:W,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 Ie(){var U,Y;const{data:r,isLoading:m}=ue(),j=xe(),{showAlert:s,showConfirm:p,dialogElement:d}=he(),[u,g]=l.useState(""),[o,i]=l.useState("box"),b=o==="idee",n=o==="simpel"||o==="gruendlich",f=b||n,[v,y]=l.useState("lxc"),[c,T]=l.useState(!1),[D,w]=l.useState({}),[B,le]=l.useState(null),[O,de]=l.useState(null),[M,q]=l.useState({}),I=(r==null?void 0:r.items)??[],L=()=>j.invalidateQueries({queryKey:je.ideen}),Q=B!==null&&(((U=r==null?void 0:r.items.find(t=>t.id===B))==null?void 0:U.status)==="triage"||((Y=r==null?void 0:r.items.find(t=>t.id===B))==null?void 0:Y.status)==="running"),R=me(B??"",Q);async function X(){const t=u.trim();if(!(t.length<3||c)){T(!0);try{const a=t.length>160?t.slice(0,157)+"…":t;await z("/api/ideen",{method:"POST",body:JSON.stringify({titel:a,notiz:t.length>160?t:"",welt:f?"ide":"box",tiefe:n?o:"",ziel:n?v:"",art:b?"idee":"projekt"})}),g(""),L()}catch(a){s("Das hat nicht geklappt",String((a==null?void 0:a.message)||a))}finally{T(!1)}}}async function ce(t){w(a=>({...a,[t]:!0}));try{await z("/api/ideen/archivieren",{method:"POST",body:JSON.stringify({id:t})}),L()}catch(a){s("Das hat nicht geklappt",String((a==null?void 0:a.message)||a))}finally{w(a=>({...a,[t]:!1}))}}async function F(t,a,x,S){w(k=>({...k,[t+a]:!0}));try{await z(x,{method:"POST",body:JSON.stringify(S)}),L()}catch(k){s("Das hat nicht geklappt",String((k==null?void 0:k.message)||k))}finally{w(k=>({...k,[t+a]:!1}))}}async function J(t){const a=(M[t]||"").trim();if(!(a.length<1||D["ans:"+t])){w(x=>({...x,["ans:"+t]:!0}));try{await z("/api/ideen/antwort",{method:"POST",body:JSON.stringify({id:t,antwort:a})}),q(x=>({...x,[t]:""})),L()}catch(x){s("Das hat nicht geklappt",String((x==null?void 0:x.message)||x))}finally{w(x=>({...x,["ans:"+t]:!1}))}}}const V=t=>{var te,re;const a=Pe[t.status]??{label:t.status,cls:"text-muted-foreground border-border/60 bg-background/30"},x=B===t.id,S=t.status==="triage"||t.status==="running"||t.status==="done",k=t.status==="blocked",h=!!D["ans:"+t.id],P=t.status==="running"&&(t.puls_alter??0)>600,ee=t.status==="todo"||t.status==="ready"||t.status==="scheduled";return e.jsxs("li",{className:N("flex flex-col gap-2 rounded-xl border bg-background/30 px-3 py-2",k?"border-red-500/30":P?"border-amber-500/40":"border-border/40"),children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:N("flex shrink-0 items-center gap-1.5 rounded-lg border px-2 py-0.5 text-[10px] font-bold",a.cls),children:[a.spin&&e.jsx(K,{className:"h-3 w-3 animate-spin"}),a.label]}),P&&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(ge,{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=Ee[t.art||(t.welt==="ide"?"projekt":"box")];if(!C)return null;const H=C.icon;return e.jsxs("span",{className:N("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(se,{className:"h-3 w-3"}),be(t.erstellt)]}),ee&&e.jsxs("span",{className:"flex shrink-0 items-center",children:[e.jsx("button",{disabled:!!D["pr:"+t.id],onClick:()=>F("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(De,{className:"h-3.5 w-3.5"})}),e.jsx("button",{disabled:!!D["pr:"+t.id],onClick:()=>F("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(ye,{className:"h-3.5 w-3.5"})})]}),(t.status==="running"||k)&&e.jsx("button",{disabled:!!D["rt:"+t.id],onClick:()=>p("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.`,()=>F("rt:",t.id,"/api/ideen/retry",{id:t.id})),title:"Neuer Versuch — Karte frisch starten",className:N("shrink-0 rounded-md p-1 transition-colors cursor-pointer disabled:opacity-50",P?"text-amber-300 hover:text-amber-200":"text-muted-foreground/60 hover:text-foreground"),children:D["rt:"+t.id]?e.jsx(K,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(ve,{className:"h-3.5 w-3.5"})}),(t.status==="running"||ee||t.status==="triage")&&e.jsx("button",{disabled:!!D["st:"+t.id],onClick:()=>p("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.`,()=>F("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:D["st:"+t.id]?e.jsx(K,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(Ke,{className:"h-3.5 w-3.5"})}),(t.status==="done"||k)&&e.jsx("button",{disabled:!!D[t.id],onClick:()=>ce(t.id),title:k?"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:D[t.id]?e.jsx(K,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(fe,{className:"h-3.5 w-3.5"})}),t.welt==="ide"&&(t.status==="running"||t.status==="done")&&e.jsxs("button",{onClick:()=>de(O===t.id?null:t.id),title:"Konzept ansehen (das ausgearbeitete KONZEPT.md)",className:N("flex shrink-0 items-center gap-1 rounded-md px-1.5 py-1 text-[10px] font-bold transition-colors cursor-pointer",O===t.id?"text-violet-300":"text-violet-300/70 hover:text-violet-200"),children:[e.jsx(ae,{className:"h-3.5 w-3.5"})," Konzept"]}),S&&e.jsx("button",{onClick:()=>le(x?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:x?e.jsx(_,{className:"h-3.5 w-3.5"}):e.jsx(A,{className:"h-3.5 w-3.5"})})]}),O===t.id&&e.jsx(Re,{id:t.id,istIdee:t.art==="idee"&&t.status==="done",onWeiter:L}),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")&&(((te=t.wartet_auf)==null?void 0:te.length)??0)>0&&e.jsxs("p",{className:"-mt-1 ml-1 text-[10px] text-muted-foreground/70",children:["→ wartet auf: ",t.wartet_auf.join(" · ")]}),k&&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(ke,{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:M[t.id]||"",onChange:C=>q(H=>({...H,[t.id]:C.target.value})),onKeyDown:C=>{C.key==="Enter"&&J(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:()=>J(t.id),disabled:h||(M[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:[h?e.jsx(K,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(ne,{className:"h-3.5 w-3.5"})," Antworten & weiter"]})]})]}),x&&S&&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:Q&&R.isLoading?e.jsx("p",{className:"text-[10px] text-muted-foreground animate-pulse",children:"Log wird geladen …"}):R.error?e.jsx("p",{className:"text-[10px] text-red-400",children:"Log nicht ladbar"}):(re=R.data)!=null&&re.available&&R.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:R.data.lines.join(`
|
||
`)}):e.jsx("p",{className:"text-[10px] text-muted-foreground",children:"Kein Log verfügbar"})})}),x&&t.status==="done"&&e.jsx(We,{id:t.id})]},t.id)};return r&&!r.available?null:e.jsxs("section",{className:"space-y-3",children:[e.jsx(Ne,{icon:Z,children:(()=>{if(!r)return"Ideen-Queue";const t=x=>I.filter(S=>x.includes(S.status)).length,a=[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`Ideen-Queue${a.length?" — "+a.join(" · "):""}`})()}),e.jsxs("div",{className:"mc-card p-4 space-y-3",children:[e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{value:u,onChange:t=>g(t.target.value),onKeyDown:t=>{t.key==="Enter"&&X()},placeholder:"Neue Idee — einfach hinschreiben, die Box macht den Rest",className:"h-9 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:X,disabled:c||u.trim().length<3,className:N("flex h-9 shrink-0 items-center gap-1.5 rounded-lg border px-3 text-[11px] font-bold uppercase tracking-wide transition-all cursor-pointer disabled:opacity-50",o==="gruendlich"?"border-amber-500/40 bg-amber-500/10 text-amber-300 hover:bg-amber-500/20":o==="simpel"?"border-violet-500/40 bg-violet-500/10 text-violet-300 hover:bg-violet-500/20":b?"border-sky-500/40 bg-sky-500/10 text-sky-300 hover:bg-sky-500/20":"border-primary/40 bg-primary/10 text-primary hover:bg-primary/20"),children:[c?e.jsx(K,{className:"h-3.5 w-3.5 animate-spin"}):b?e.jsx(Z,{className:"h-3.5 w-3.5"}):n?e.jsx(W,{className:"h-3.5 w-3.5"}):e.jsx(ne,{className:"h-3.5 w-3.5"}),b?"Durchdenken":n?"Vorbereiten":"In die Queue"]})]}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-[11px] text-muted-foreground/70",children:"Modus"}),e.jsxs("div",{className:"flex rounded-lg border border-border/60 p-0.5",children:[e.jsxs("button",{onClick:()=>i("box"),className:N("flex items-center gap-1 rounded px-2 py-1 text-[10px] font-bold uppercase tracking-wide transition-all cursor-pointer",o==="box"?"bg-primary/15 text-primary":"text-muted-foreground/60 hover:text-foreground"),children:[e.jsx(ie,{className:"h-3 w-3"})," Box"]}),e.jsxs("button",{onClick:()=>i("idee"),title:"Produkt-Idee erst einmal durchdenken lassen: Was ist es, für wen, was gibt es schon, was spricht dagegen? Ergebnis ist ein Konzept — kein Projekt, kein Bau-Druck.",className:N("flex items-center gap-1 rounded px-2 py-1 text-[10px] font-bold uppercase tracking-wide transition-all cursor-pointer",o==="idee"?"bg-sky-500/15 text-sky-300":"text-muted-foreground/60 hover:text-foreground"),children:[e.jsx(Z,{className:"h-3 w-3"})," Idee"]}),e.jsxs("button",{onClick:()=>i("simpel"),title:"IDE-Projekt, schnell vorbereitet: knappes Konzept, wenige Denk-Runden. Für kleine, klar umrissene Sachen.",className:N("flex items-center gap-1 rounded px-2 py-1 text-[10px] font-bold uppercase tracking-wide transition-all cursor-pointer",o==="simpel"?"bg-violet-500/15 text-violet-300":"text-muted-foreground/60 hover:text-foreground"),children:[e.jsx(W,{className:"h-3 w-3"})," IDE: simpel"]}),e.jsxs("button",{onClick:()=>i("gruendlich"),title:"IDE-Projekt, gründlich durchdacht: volle Kaskade mit mehreren Rollen und Härtetests. Für große/ambitionierte Projekte.",className:N("flex items-center gap-1 rounded px-2 py-1 text-[10px] font-bold uppercase tracking-wide transition-all cursor-pointer",o==="gruendlich"?"bg-amber-500/15 text-amber-300":"text-muted-foreground/60 hover:text-foreground"),children:[e.jsx(W,{className:"h-3 w-3"})," IDE: gründlich"]})]})]}),e.jsxs("p",{className:"text-[10px] leading-relaxed text-muted-foreground/60",children:[e.jsx("b",{className:"text-primary/80",children:"Box"}),", wenn die Box es selbst bauen soll (dein Heimlabor, MC2, Lucy — Ergebnis kommt als Patch-Vorschlag zurück). ·"," ",e.jsx("b",{className:"text-sky-300/80",children:"Idee"}),", wenn du noch nicht weißt, ob es das überhaupt wert ist — erst durchdenken, entscheiden kannst du danach. ·"," ",e.jsx("b",{className:"text-violet-300/80",children:"IDE"}),", wenn du es selbst in Zed bauen willst und dafür ein startklares Repo brauchst."]}),n&&e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-[11px] text-muted-foreground/70",children:"Ziel"}),e.jsxs("div",{className:"flex rounded-lg border border-border/40 p-0.5",children:[e.jsx("button",{onClick:()=>y("lxc"),title:"Läuft als Dienst in einem eigenen Proxmox-LXC (systemd, kein Docker). Wird vom Backup-Server automatisch mitgesichert.",className:N("rounded px-2 py-0.5 text-[10px] font-semibold transition-all cursor-pointer",v==="lxc"?"bg-foreground/10 text-foreground":"text-muted-foreground/50 hover:text-foreground/80"),children:"LXC"}),e.jsx("button",{onClick:()=>y("docker"),title:"Natives Docker nach Standard-Praxis: Dockerfile + compose, portabel, über Gitea-/GitLab-Pipelines baubar. Für Projekte, die bewusst außerhalb der LXC-Welt leben.",className:N("rounded px-2 py-0.5 text-[10px] font-semibold transition-all cursor-pointer",v==="docker"?"bg-foreground/10 text-foreground":"text-muted-foreground/50 hover:text-foreground/80"),children:"Docker"})]}),e.jsx("span",{className:"text-[10px] text-muted-foreground/50",children:v==="lxc"?"Dienst im Proxmox-Container (deine Heimat)":"natives Docker, portabel & pipeline-tauglich"})]}),e.jsx("p",{className:"text-[11px] text-muted-foreground",children:b?e.jsxs(e.Fragment,{children:[e.jsx("b",{className:"text-sky-300/90",children:"Idee durchdenken:"})," Die Box arbeitet deine Produkt-Idee mit Produkt-Blick aus — was ist es genau, für wen, was gibt es dafür schon, was wäre der kleinste sinnvolle Wurf und was spricht dagegen. Volle Denk-Kaskade mit Kritiker, Ergebnis ist ",e.jsx("b",{children:"nur ein Konzept"})," (kein Gerüst, keine Roadmap, kein Bau-Druck) — du liest es hier und entscheidest danach, ob ein Projekt draus wird."]}):n?e.jsxs(e.Fragment,{children:[e.jsxs("b",{className:o==="gruendlich"?"text-amber-300/90":"text-violet-300/90",children:["IDE-Welt",o==="gruendlich"?" · gründlich":" · simpel",":"]})," ","Die Box denkt das Konzept durch",o==="gruendlich"?" — volle Kaskade: mehrere Fach-Rollen, bis zu 3 Denk-Runden, mehrfacher Kritiker-Härtetest (für große/ambitionierte Projekte, dauert entsprechend)":" — schlank: 2 Rollen, 1 Denk-Runde (für kleine, klar umrissene Projekte, ein paar Minuten)",", legt ein leeres Gitea-Repo an und füllt es nur mit den wichtigen Dokumenten (Konzept, Roadmap, AGENTS.md, .aiexclude) — ",e.jsx("b",{children:"kein Code"}),". Danach öffnest du das Repo in Zed und baust selbst."]}):e.jsx(e.Fragment,{children:"Eine Queue, alle Türen: hier, per Telegram oder im Gespräch mit Lucy. Die Box arbeitet Ideen selbst aus und baut — Code-Ergebnisse erscheinen als Karte unter „Patch-Vorschläge“, nichts davon geht ohne deinen Klick live. Nur reine Doku-Bagatellen zieht die Box nachts selbst ein (mit Fangnetz und Meldung)."})}),m&&e.jsxs("p",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[e.jsx(K,{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."}),I.length>0&&e.jsxs("div",{className:"space-y-3",children:[((r==null?void 0:r.projekte)??[]).map(t=>e.jsx(Le,{projekt:t,karten:I.filter(a=>a.projekt===t.key),zeile:V},t.key)),(()=>{const t=new Set(((r==null?void 0:r.projekte)??[]).map(h=>h.key)),a=I.filter(h=>!h.projekt||!t.has(h.projekt));if(a.length===0)return null;const x=a.filter(h=>E[h.status]!==void 0).sort((h,P)=>E[h.status]-E[P.status]||(h.erstellt??0)-(P.erstellt??0)),S=a.filter(h=>["todo","scheduled"].includes(h.status)),k=a.filter(h=>h.status==="done");return e.jsxs("div",{className:"space-y-2",children:[x.length>0&&e.jsx("ul",{className:"space-y-1.5",children:x.map(h=>V(h))}),S.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(A,{className:"h-3 w-3 transition-transform group-open:rotate-90"}),e.jsx(se,{className:"h-3 w-3"})," Wartet (",S.length,")"]}),e.jsx("ul",{className:"mt-1.5 space-y-1.5",children:S.map(h=>V(h))})]}),k.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(A,{className:"h-3 w-3 transition-transform group-open:rotate-90"}),e.jsx(pe,{className:"h-3 w-3 text-emerald-400/70"})," Fertig (",k.length,")"]}),e.jsx("ul",{className:"mt-1.5 space-y-1.5",children:k.map(h=>V(h))})]})]})})()]}),(r==null?void 0:r.available)&&!m&&I.length===0&&e.jsx("p",{className:"text-xs text-muted-foreground/70",children:"Queue ist leer — wirf der Box eine Idee zu."})]}),d]})}const E={blocked:0,running:1,review:2,ready:3,triage:4};function Le({projekt:r,karten:m,zeile:j}){const[s,p]=l.useState(!1),[d,u]=l.useState(!1),g=m.filter(n=>E[n.status]!==void 0).sort((n,f)=>E[n.status]-E[f.status]||(n.erstellt??0)-(f.erstellt??0)),o=m.filter(n=>n.status==="todo"||n.status==="scheduled").sort((n,f)=>{var v,y;return((v=n.wartet_auf)!=null&&v.length?1:0)-((y=f.wartet_auf)!=null&&y.length?1:0)||(n.erstellt??0)-(f.erstellt??0)}),i=m.filter(n=>n.status==="done").sort((n,f)=>(f.fertig??0)-(n.fertig??0)),b=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(we,{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:`${b}%`,children:e.jsx("div",{className:"h-1 rounded-full bg-primary/70 transition-all",style:{width:`${b}%`}})}),g.length>0&&e.jsx("ul",{className:"space-y-1.5",children:g.map(n=>j(n))}),o.length>0&&e.jsxs("div",{children:[e.jsxs("button",{onClick:()=>p(n=>!n),className:"flex items-center gap-1.5 text-[11px] font-semibold text-muted-foreground hover:text-foreground transition-colors cursor-pointer",children:[s?e.jsx(_,{className:"h-3.5 w-3.5"}):e.jsx(A,{className:"h-3.5 w-3.5"}),o.length," Karte",o.length===1?"":"n"," in der Kette — laufen automatisch der Reihe nach"]}),s&&e.jsx("ul",{className:"mt-1.5 space-y-1.5",children:o.map(n=>j(n))})]}),i.length>0&&e.jsxs("div",{children:[e.jsxs("button",{onClick:()=>u(n=>!n),className:"flex items-center gap-1.5 text-[11px] font-semibold text-emerald-300/70 hover:text-emerald-300 transition-colors cursor-pointer",children:[d?e.jsx(_,{className:"h-3.5 w-3.5"}):e.jsx(A,{className:"h-3.5 w-3.5"}),i.length," fertig"]}),d&&e.jsx("ul",{className:"mt-1.5 space-y-1.5",children:i.map(n=>j(n))})]})]})}function Re({id:r,istIdee:m,onWeiter:j}){const[s,p]=l.useState(null),[d,u]=l.useState(!1),[g,o]=l.useState(0);return l.useEffect(()=>{let i=!1;return p(null),u(!1),z(`/api/ideen/${r}/konzept`).then(b=>{i||p(b)}).catch(()=>{i||u(!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(ae,{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(Ce,{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:()=>o(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(oe,{className:"h-3 w-3"})})]}),d?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(ze,{text:s.konzept})}):e.jsx("p",{className:"text-[11px] text-muted-foreground italic",children:s.error||"Noch kein Konzept — das Projekt wird gerade vorbereitet."}),m&&(s==null?void 0:s.konzept)&&e.jsx(Ae,{id:r,onFertig:j})]})})}function Ae({id:r,onFertig:m}){const[j,s]=l.useState("lxc"),[p,d]=l.useState("simpel"),[u,g]=l.useState(!1),[o,i]=l.useState(null),[b,n]=l.useState(""),[f,v]=l.useState(""),y=async(c,T,D)=>{g(!0),n("");try{const w=await z(c,{method:"POST",body:JSON.stringify(T)});i({id:w.id,art:D}),m==null||m()}catch(w){n(String((w==null?void 0:w.message)||w))}finally{g(!1)}};return o?e.jsx("p",{className:"mt-3 border-t border-violet-500/20 pt-2 text-[11px] text-emerald-300",children:o.art==="projekt"?e.jsxs(e.Fragment,{children:["Projekt-Karte ",e.jsx("span",{className:"font-mono",children:o.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:o.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:f,onChange:c=>v(c.target.value),onKeyDown:c=>{c.key==="Enter"&&f.trim().length>=3&&!u&&y("/api/ideen/nachschaerfen",{id:r,hinweis:f},"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:()=>y("/api/ideen/nachschaerfen",{id:r,hinweis:f},"runde"),disabled:u||f.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:[u?e.jsx(K,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(oe,{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(c=>e.jsx("button",{onClick:()=>s(c),title:c==="lxc"?"Dienst in einem eigenen Proxmox-LXC (systemd, kein Docker) — wird automatisch mitgesichert.":"Natives Docker: Dockerfile + compose, portabel und pipeline-tauglich.",className:N("rounded px-2 py-0.5 text-[10px] font-semibold transition-all cursor-pointer",j===c?"bg-foreground/10 text-foreground":"text-muted-foreground/50 hover:text-foreground/80"),children:c==="lxc"?"LXC":"Docker"},c))}),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(c=>e.jsx("button",{onClick:()=>d(c),title:c==="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:N("rounded px-2 py-0.5 text-[10px] font-semibold transition-all cursor-pointer",p===c?"bg-foreground/10 text-foreground":"text-muted-foreground/50 hover:text-foreground/80"),children:c==="simpel"?"schlank":"gründlich"},c))}),e.jsxs("button",{onClick:()=>y("/api/ideen/weiterfuehren",{id:r,ziel:j,tiefe:p},"projekt"),disabled:u,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:[u?e.jsx(K,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(W,{className:"h-3.5 w-3.5"}),"Gefällt mir — Projekt daraus machen"]})]}),b&&e.jsx("p",{className:"text-[11px] text-red-400",children:b})]})}function We({id:r}){const[m,j]=l.useState(null),[s,p]=l.useState(!1),[d,u]=l.useState(0);l.useEffect(()=>{let o=!1;return p(!1),j(null),z(`/api/ideen/${r}/ergebnis`).then(i=>{o||j(i)}).catch(()=>{o||p(!0)}),()=>{o=!0}},[r,d]);const g=m?m.summary||m.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(Se,{className:"h-3 w-3"})," Ergebnis des Workers"]}),s?e.jsx("button",{type:"button",onClick:()=>u(o=>o+1),className:"text-[10px] text-red-400 underline decoration-dotted underline-offset-2 hover:text-red-300",children:"Ergebnis nicht ladbar — nochmal versuchen"}):m===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 Oe(){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(Ie,{})]})}export{Oe as IdeenView};
|