IDE-Welt: Vorbereiten-Bahn — Idee → Konzept + leeres Repo + Doku, Bau in Zed

Neue Intake-Weiche Box/IDE. IDE-Ideen gehen direkt an das neue Profil
'projektstart' (am Triage/Auto-Zerleger vorbei, kein Werkstatt-Bau): es
haertet via konzept-fliessband ein Konzept, legt ein leeres Gitea-Repo an
und fuellt es NUR mit Doku (Konzept/Roadmap/AGENTS.md/.aiexclude). Ergebnis
ist ein vorbereitetes Projekt, das der Commander in Zed selbst baut.
UI: Toggle 'Box baut / Ich bau in Zed', IDE-Badge auf Karten.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-07-20 14:17:43 +02:00
parent 8153d14d9f
commit 77ae504b58
29 changed files with 160 additions and 101 deletions
+1
View File
@@ -514,6 +514,7 @@ export interface IdeenItem {
body: string
status: string // triage | todo | ready | running | blocked | review | done
assignee: string | null
welt?: string // "box" = Werkstatt baut · "ide" = für Zed vorbereitet
erstellt: number | null
fertig: number | null
von: string | null
+44 -7
View File
@@ -2,7 +2,7 @@ import { useEffect, useState } from "react"
import {
Inbox, Check, X, GitBranch, FileDiff, Loader2, AlertTriangle, Sparkles,
ChevronDown, ChevronRight, Clock, ClipboardCheck, Hammer, RefreshCw, Layers, Lightbulb, Send, HelpCircle,
RotateCcw, Square, ArrowUp, ArrowDown,
RotateCcw, Square, ArrowUp, ArrowDown, Code2,
} from "lucide-react"
import { api, type AuftragItem, type IdeenErgebnis, type IdeenItem, type IdeenProjekt, type SkillKandidat } from "@/lib/api"
import { useAuftragsbuch, useIdeen, useIdeenLog, useQueryClient, qk } from "@/lib/queries"
@@ -163,6 +163,7 @@ function IdeenSection() {
const qc = useQueryClient()
const { showAlert, showConfirm, dialogElement } = useDialog()
const [text, setText] = useState("")
const [welt, setWelt] = useState<"box" | "ide">("box")
const [sending, setSending] = useState(false)
const [busy, setBusy] = useState<Record<string, boolean>>({})
const [openLog, setOpenLog] = useState<string | null>(null)
@@ -183,7 +184,7 @@ function IdeenSection() {
// Lange Eingaben: Kurzfassung als Titel, alles als Notiz — der Specifier der Box
// macht daraus ohnehin einen sauberen Auftrag.
const titel = t.length > 160 ? t.slice(0, 157) + "…" : t
await api("/api/ideen", { method: "POST", body: JSON.stringify({ titel, notiz: t.length > 160 ? t : "" }) })
await api("/api/ideen", { method: "POST", body: JSON.stringify({ titel, notiz: t.length > 160 ? t : "", welt }) })
setText("")
reload()
} catch (e: any) {
@@ -266,6 +267,12 @@ function IdeenSection() {
<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)">P{it.prio}</span>
)}
{it.welt === "ide" && (
<span className="flex shrink-0 items-center gap-1 rounded-lg border border-violet-500/40 bg-violet-500/10 px-2 py-0.5 text-[10px] font-bold text-violet-300"
title="IDE-Welt: die Box bereitet nur vor (Konzept + Repo + Doku, kein Code). Gebaut wird von dir in Zed.">
<Code2 className="h-3 w-3" /> IDE
</span>
)}
<span className="min-w-0 flex-1 truncate text-xs text-foreground" title={it.body || it.titel}>{it.titel}</span>
<span className="flex shrink-0 items-center gap-1 text-[10px] text-muted-foreground/70"><Clock className="h-3 w-3" />{fmtWhen(it.erstellt)}</span>
{wartend && (
@@ -416,14 +423,44 @@ function IdeenSection() {
<button
onClick={submit}
disabled={sending || text.trim().length < 3}
className="flex h-9 shrink-0 items-center gap-1.5 rounded-lg border border-primary/40 bg-primary/10 px-3 text-[11px] font-bold uppercase tracking-wide text-primary transition-all hover:bg-primary/20 cursor-pointer disabled:opacity-50">
{sending ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Send className="h-3.5 w-3.5" />} In die Queue
className={cn("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",
welt === "ide" ? "border-violet-500/40 bg-violet-500/10 text-violet-300 hover:bg-violet-500/20" : "border-primary/40 bg-primary/10 text-primary hover:bg-primary/20")}>
{sending ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : welt === "ide" ? <Code2 className="h-3.5 w-3.5" /> : <Send className="h-3.5 w-3.5" />}
{welt === "ide" ? "Vorbereiten" : "In die Queue"}
</button>
</div>
<div className="flex items-center gap-1.5">
<span className="text-[11px] text-muted-foreground/70">Wer baut das?</span>
<div className="flex rounded-lg border border-border/60 p-0.5">
<button
onClick={() => setWelt("box")}
className={cn("flex items-center gap-1 rounded px-2 py-1 text-[10px] font-bold uppercase tracking-wide transition-all cursor-pointer",
welt === "box" ? "bg-primary/15 text-primary" : "text-muted-foreground/60 hover:text-foreground")}>
<Hammer className="h-3 w-3" /> Box baut
</button>
<button
onClick={() => setWelt("ide")}
className={cn("flex items-center gap-1 rounded px-2 py-1 text-[10px] font-bold uppercase tracking-wide transition-all cursor-pointer",
welt === "ide" ? "bg-violet-500/15 text-violet-300" : "text-muted-foreground/60 hover:text-foreground")}>
<Code2 className="h-3 w-3" /> Ich bau in Zed
</button>
</div>
</div>
<p className="text-[11px] text-muted-foreground">
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).
{welt === "ide" ? (
<>
<b className="text-violet-300/90">IDE-Welt:</b> Die Box denkt das Konzept wasserdicht durch
(mehrere Denk-Runden mit Kritiker), legt ein leeres Gitea-Repo an und füllt es nur mit den
wichtigen Dokumenten (Konzept, Roadmap, AGENTS.md, .aiexclude) <b>kein Code</b>. Danach öffnest
du das Repo in Zed und baust selbst. Das Vorbereiten dauert ein paar Minuten.
</>
) : (
<>
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).
</>
)}
</p>
{isLoading && (