feat: prominente Abschluss-Notifications + Widget-Update für /optimize und /shipit

This commit is contained in:
Dieter Schlüter 2026-05-20 02:08:09 +02:00
commit b19c189e2e

View file

@ -456,6 +456,28 @@ async function runUpdateDoku(pi: ExtensionAPI, ctx: ExtensionCommandContext): Pr
ctx.ui.notify("Dokumentations-Phase abgeschlossen. Commit angelegt.", "info"); ctx.ui.notify("Dokumentations-Phase abgeschlossen. Commit angelegt.", "info");
} }
// Prominente Abschluss-Notification + Widget-Update mit Uhrzeit und Ergebnis.
function finalNotify(
ctx: ExtensionCommandContext,
verdict: string,
detail: string
): void {
const timestamp = new Date().toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit" });
const level = verdict.includes("SHIP") && !verdict.includes("NO-SHIP") ? "warning"
: verdict.includes("NO-SHIP") ? "error"
: verdict.includes("⚠") ? "warning"
: "info";
ctx.ui.notify(`${verdict}: ${detail}`, level);
ctx.ui.setWidget("coder-judge", [
`Letzter Lauf: ${verdict}${detail} (${timestamp})`,
"─────────────────────────────────────────",
"Workflow: /coder <auftrag> | /judge | /fix | /shipit",
"Auto-Loop: /optimize <auftrag> [--rounds N] [--with-doku] [--continue]",
"Kleine Änderung: /patch <änderung> → /quick_check [was]",
"Finale Doku: /update_doku | Neues Projekt: /new_project <pfad>",
]);
}
// ── Extension ──────────────────────────────────────────────────────────────── // ── Extension ────────────────────────────────────────────────────────────────
export default function (pi: ExtensionAPI) { export default function (pi: ExtensionAPI) {
@ -540,6 +562,7 @@ export default function (pi: ExtensionAPI) {
description: "Finale Freigabe gegen TASK.md + git log → qwen3.5-judge (:8002).", description: "Finale Freigabe gegen TASK.md + git log → qwen3.5-judge (:8002).",
handler: async function (args: string, ctx: ExtensionCommandContext) { handler: async function (args: string, ctx: ExtensionCommandContext) {
await switchModel(pi, ctx, "llama-cpp-judge", "qwen3.5-judge"); await switchModel(pi, ctx, "llama-cpp-judge", "qwen3.5-judge");
ctx.ui.notify("Judge prüft finale Freigabe — Ergebnis erscheint im Chat (SHIP / NO-SHIP)", "info");
pi.sendUserMessage(shipitPrompt(args || "")); pi.sendUserMessage(shipitPrompt(args || ""));
} }
}); });
@ -593,7 +616,6 @@ export default function (pi: ExtensionAPI) {
if (verdict === "PASS" || verdict === "PASS WITH CONCERNS") { if (verdict === "PASS" || verdict === "PASS WITH CONCERNS") {
await tickTaskMdStatus(pi, ctx, "Review bestanden (PASS)"); await tickTaskMdStatus(pi, ctx, "Review bestanden (PASS)");
ctx.ui.setStatus("optimize", `${verdict} nach Runde ${round}`); ctx.ui.setStatus("optimize", `${verdict} nach Runde ${round}`);
ctx.ui.notify(`Optimierung abgeschlossen: ${verdict} nach ${round} Runde(n)`, "info");
break; break;
} }
@ -601,17 +623,14 @@ export default function (pi: ExtensionAPI) {
const currentBlockers = parseBlockers(judgeText); const currentBlockers = parseBlockers(judgeText);
if (currentBlockers && currentBlockers === lastBlockers) { if (currentBlockers && currentBlockers === lastBlockers) {
ctx.ui.setStatus("optimize", "⚠ Schleife: gleicher Blocker manuelle Intervention nötig"); ctx.ui.setStatus("optimize", "⚠ Schleife: gleicher Blocker manuelle Intervention nötig");
ctx.ui.notify( finalNotify(ctx, "⚠ Schleife", "Gleicher Blocker zweimal manuelle Intervention nötig");
"Derselbe Blocker tritt erneut auf Schleife abgebrochen. Bitte manuell prüfen.",
"warning"
);
return; return;
} }
lastBlockers = currentBlockers; lastBlockers = currentBlockers;
if (round === maxRounds) { if (round === maxRounds) {
ctx.ui.setStatus("optimize", `⚠ Max. ${maxRounds} Runden ohne PASS`); ctx.ui.setStatus("optimize", `⚠ Max. ${maxRounds} Runden ohne PASS`);
ctx.ui.notify(`${maxRounds} Runden durchlaufen ohne PASS. Bitte manuell prüfen.`, "warning"); finalNotify(ctx, "⚠ Kein PASS", `${maxRounds} Runden ohne PASS bitte /judge und /fix manuell`);
return; return;
} }
@ -632,6 +651,7 @@ export default function (pi: ExtensionAPI) {
if (shipVerdict === "SHIP") { if (shipVerdict === "SHIP") {
ctx.ui.setStatus("optimize", "🚀 SHIP produktionsreif"); ctx.ui.setStatus("optimize", "🚀 SHIP produktionsreif");
finalNotify(ctx, "🚀 SHIP", "Programm ist produktionsreif");
if (withDoku) { if (withDoku) {
await runUpdateDoku(pi, ctx); await runUpdateDoku(pi, ctx);
} else { } else {
@ -639,8 +659,10 @@ export default function (pi: ExtensionAPI) {
} }
} else if (shipVerdict === "NO-SHIP") { } else if (shipVerdict === "NO-SHIP") {
ctx.ui.setStatus("optimize", "⛔ NO-SHIP noch nicht bereit"); ctx.ui.setStatus("optimize", "⛔ NO-SHIP noch nicht bereit");
finalNotify(ctx, "⛔ NO-SHIP", "Noch Blocker offen bitte /judge und /fix manuell");
} else { } else {
ctx.ui.setStatus("optimize", "ShipIt abgeschlossen"); ctx.ui.setStatus("optimize", "ShipIt abgeschlossen");
finalNotify(ctx, "ShipIt", "Kein klares Urteil Antwort im Chat prüfen");
} }
} }
} }