Konzept nachschaerfen: Rueckmeldung statt nur annehmen-oder-wegwerfen

Nach dem Lesen eines Konzepts gab es bisher nur zwei Wege: "Gefaellt mir" oder
archivieren. Der haeufige Fall fehlte komplett — EIN Punkt passt nicht und der
Commander hat einen besseren Vorschlag.

- POST /api/ideen/nachschaerfen -> konzept_ueberarbeiten(): legt eine neue
  Idee-Karte an (kein Bau), verkettet an die Quell-Karte, mit dem Wortlaut der
  Rueckmeldung. Auftrag: bestehendes Konzept lesen, genannte Punkte UND deren
  Folgewirkungen aendern, Rest stehen lassen, kurzer Haertetest nur auf die
  geaenderten Teile. Schafft der Vorschlag ein Problem: einbauen UND die Folge
  sichtbar in die Risiken schreiben — nicht uebergehen, nicht schoenreden.
  Die neue Fassung geht an DIESELBE Stelle (Repo-Commit bzw. Datei + .bak), so
  zeigt "Konzept" ueberall den frischen Stand. Beliebig oft wiederholbar, weil
  die Ueberarbeitung selbst wieder eine Idee-Karte ist.
- UI: Rueckmeldefeld direkt unter dem gelesenen Konzept, ueber dem
  Gefaellt-mir-Weg (der haeufigere Fall gehoert nach oben und offen sichtbar).
- SOUL: neuer Sonderfall UEBERARBEITUNG (Schritt 2 entfaellt, kein zweites Repo).

Zwei Fehler nebenbei gefunden und behoben:
- _wo_liegt(): der Auftrag verwechselte "Repo bekannt" mit "Konzept kommt aus
  dem Repo". Faellt MC2 auf die lokale Datei zurueck, stand vorher "liegt im
  Repo als <lokaler Dateiname>" im Auftrag — eine Datei, die es dort nie gab.
- SOUL-Regel 4: der Push gilt erst als erledigt, wenn `git ls-remote` ihn
  BEWEIST. Ein Worker hat am 21.07. genau hier abgekuerzt, Erfolg gemeldet, und
  das Repo war nachher nicht auffindbar.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-07-21 09:05:34 +02:00
parent 94dc3fba9b
commit 0cea01c699
29 changed files with 286 additions and 118 deletions
+42 -15
View File
@@ -734,22 +734,20 @@ function KonzeptPanel({ id, istIdee, onWeiter }: {
)
}
// „Gefällt mir" — aus der geprüften Idee ein IDE-Projekt machen. Ohne das war die Idee
// eine Sackgasse (Titel neu eintippen, Konzept von vorn denken lassen). Die neue Karte
// bekommt das fertige Konzept als Vorlage und hängt als Kette an der Idee.
// Was nach dem Lesen passieren kann. Zwei Wege, bewusst nebeneinander statt hintereinander:
// nachschärfen (ein Punkt passt nicht — häufiger Fall, darum oben und offen) oder annehmen.
function WeiterLeiste({ id, onFertig }: { id: string; onFertig?: () => void }) {
const [ziel, setZiel] = useState<"lxc" | "docker">("lxc")
const [tiefe, setTiefe] = useState<"simpel" | "gruendlich">("simpel")
const [busy, setBusy] = useState(false)
const [neu, setNeu] = useState<string | null>(null)
const [neu, setNeu] = useState<{ id: string; art: "projekt" | "runde" } | null>(null)
const [fehler, setFehler] = useState("")
const los = async () => {
const [hinweis, setHinweis] = useState("")
const ruf = async (pfad: string, rumpf: object, art: "projekt" | "runde") => {
setBusy(true); setFehler("")
try {
const r = await api<{ id: string }>("/api/ideen/weiterfuehren", {
method: "POST", body: JSON.stringify({ id, ziel, tiefe }),
})
setNeu(r.id)
const r = await api<{ id: string }>(pfad, { method: "POST", body: JSON.stringify(rumpf) })
setNeu({ id: r.id, art })
onFertig?.()
} catch (e: any) {
setFehler(String(e?.message || e))
@@ -760,16 +758,45 @@ function WeiterLeiste({ id, onFertig }: { id: string; onFertig?: () => void }) {
if (neu) {
return (
<p className="mt-3 border-t border-violet-500/20 pt-2 text-[11px] text-emerald-300">
Projekt-Karte <span className="font-mono">{neu}</span> ist angelegt die Box bereitet das
Repo vor (Konzept übernimmt sie, sie denkt es nicht neu). Danach öffnest du es in Zed.
{neu.art === "projekt" ? (
<>Projekt-Karte <span className="font-mono">{neu.id}</span> ist angelegt die Box bereitet
das Repo vor (Konzept übernimmt sie, sie denkt es nicht neu). Danach öffnest du es in Zed.</>
) : (
<>Überarbeitung <span className="font-mono">{neu.id}</span> läuft die Box arbeitet deine
Rückmeldung ein und schreibt die neue Fassung an dieselbe Stelle. Danach hier wieder
Konzept" öffnen.</>
)}
</p>
)
}
return (
<div className="mt-3 space-y-2 border-t border-violet-500/20 pt-2.5">
<div className="mt-3 space-y-3 border-t border-violet-500/20 pt-2.5">
<div className="space-y-1.5">
<p className="text-[11px] text-muted-foreground">
<b className="text-sky-300/90">Passt etwas nicht?</b> Schreib hin, was anders werden soll —
die Box arbeitet es ein und lässt den Rest stehen. Beliebig oft wiederholbar.
</p>
<div className="flex gap-2">
<input
value={hinweis}
onChange={(e) => setHinweis(e.target.value)}
onKeyDown={(e) => { if (e.key === "Enter" && hinweis.trim().length >= 3 && !busy) ruf("/api/ideen/nachschaerfen", { id, hinweis }, "runde") }}
placeholder="z. B. Punkt 3: kein WebSocket, das ist mir zu fragil nimm Polling"
maxLength={2000}
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"
/>
<button
onClick={() => ruf("/api/ideen/nachschaerfen", { id, hinweis }, "runde")}
disabled={busy || hinweis.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">
{busy ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <RefreshCw className="h-3.5 w-3.5" />}
Nachschärfen
</button>
</div>
</div>
<p className="text-[11px] text-muted-foreground">
Gefällt dir das? Dann macht die Box daraus ein <b className="text-violet-300/90">startklares
Repo</b> Konzept wird übernommen (nicht neu gedacht), dazu Roadmap, AGENTS.md &amp; Co.
<b className="text-violet-300/90">Passt es so?</b> Dann macht die Box daraus ein startklares
Repo — Konzept wird übernommen (nicht neu gedacht), dazu Roadmap, AGENTS.md &amp; Co.
Gebaut wird danach von dir in Zed.
</p>
<div className="flex flex-wrap items-center gap-x-3 gap-y-2">
@@ -798,7 +825,7 @@ function WeiterLeiste({ id, onFertig }: { id: string; onFertig?: () => void }) {
))}
</div>
<button
onClick={los}
onClick={() => ruf("/api/ideen/weiterfuehren", { id, ziel, tiefe }, "projekt")}
disabled={busy}
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">
{busy ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Code2 className="h-3.5 w-3.5" />}