docs: LICENCE.md-Feature, .gitignore, Single-GPU-Doku

- pi-coder-judge-extension.ts: licenceMd() + writeLicenceMd() — erzeugt
  proprietäre LICENCE.md in der Doku-Phase (nur wenn noch nicht vorhanden)
- tests: Guards und pure-logic-Tests für LICENCE.md ergänzt (38 Tests, alle grün)
- .gitignore: Node, TypeScript-Artefakte, Backups, Editor-Dateien, OS-Metadaten
- README.md + BEDIENUNGSANLEITUNG.md: vollständig auf Single-GPU-Architektur
  aktualisiert (ein Server, System-Prompt-Rollen, kein Quick-Judge,
  PASS WITH CONCERNS-Verhalten, LICENCE.md in /update_doku, start-single.sh)
- SINGLE_SERVER_PLAN.md: entfernt (umgesetzt, kein Mehrwert mehr)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-15 05:03:50 +02:00
commit 485ab30265
7 changed files with 297 additions and 357 deletions

View file

@ -324,6 +324,45 @@ function planPrompt(task: string): string {
// ── Hilfsfunktionen ─────────────────────────────────────────────────────────
// Proprietäre Default-Lizenz ("Alle Rechte vorbehalten"), deutsch — passend zur übrigen Doku.
// Reine Template-Funktion (deterministisch): Lizenztext wird NIE vom LLM generiert.
function licenceMd(year: string, holder: string): string {
return [
"# Lizenz",
"",
`Copyright (c) ${year} ${holder}`,
"",
"Alle Rechte vorbehalten.",
"",
"Diese Software und der zugehörige Quellcode sind urheberrechtlich geschützt.",
"Kein Teil dieser Software darf ohne vorherige ausdrückliche schriftliche",
"Genehmigung des Rechteinhabers kopiert, verändert, weitergegeben, veröffentlicht,",
"unterlizenziert oder anderweitig genutzt werden.",
"",
"DIE SOFTWARE WIRD OHNE MÄNGELGEWÄHR UND OHNE JEGLICHE AUSDRÜCKLICHE ODER",
"KONKLUDENTE GEWÄHRLEISTUNG BEREITGESTELLT. DER RECHTEINHABER HAFTET NICHT FÜR",
"SCHÄDEN, DIE AUS DER NUTZUNG DIESER SOFTWARE ENTSTEHEN.",
""
].join("\n");
}
// Legt LICENCE.md mit der proprietären Default-Lizenz an — nur wenn noch keine existiert
// (eine vorhandene Lizenz wird nie überschrieben). Inhaber aus 'git config user.name',
// sonst Platzhalter; Jahr aus dem aktuellen Datum.
async function writeLicenceMd(pi: ExtensionAPI, ctx: ExtensionCommandContext): Promise<void> {
const check = await pi.exec("bash", ["-c", "test -f LICENCE.md && echo exists"], { cwd: ctx.cwd });
if (check.stdout.trim() === "exists") {
ctx.ui.notify("LICENCE.md existiert bereits — unverändert.", "info");
return;
}
const who = await pi.exec("bash", ["-c", "git config user.name 2>/dev/null"], { cwd: ctx.cwd });
const holder = who.stdout.trim() || "[Rechteinhaber eintragen]";
const year = String(new Date().getFullYear());
// content als Argument ($1), nicht interpoliert — kein Shell-Escaping-Problem.
await pi.exec("bash", ["-c", `printf "%s" "$1" > LICENCE.md`, "_", licenceMd(year, holder)], { cwd: ctx.cwd });
ctx.ui.notify(`LICENCE.md angelegt (proprietär, © ${year} ${holder}).`, "info");
}
// Legt TASK.md neu an oder hängt einen Zusatzauftrag an.
async function writeTaskMd(
pi: ExtensionAPI,
@ -703,10 +742,18 @@ async function runUpdateDoku(pi: ExtensionAPI, ctx: ExtensionCommandContext): Pr
ctx.ui.notify(`3/3 BEDIENUNGSANLEITUNG.md fehlgeschlagen: ${String(e?.message ?? e)}`, "error");
}
// LICENCE.md: deterministisch anlegen (nur wenn nicht vorhanden) — kein LLM.
try {
ctx.ui.setStatus("update_doku", "LICENCE.md wird geprüft…");
await writeLicenceMd(pi, ctx);
} catch (e: any) {
ctx.ui.notify(`LICENCE.md fehlgeschlagen: ${String(e?.message ?? e)}`, "error");
}
// Abschließender Dokumentations-Commit (immer, auch bei Teilfehlern)
await pi.exec(
"bash",
["-c", "git add -A && git commit -m 'docs: update comments, README, BEDIENUNGSANLEITUNG' || true"],
["-c", "git add -A && git commit -m 'docs: update comments, README, BEDIENUNGSANLEITUNG, LICENCE' || true"],
{ cwd: ctx.cwd }
);
@ -1331,7 +1378,7 @@ export default function (pi: ExtensionAPI) {
if (withDoku) {
await runUpdateDoku(pi, ctx);
} else {
ctx.ui.notify("Nächster Schritt: /update_doku für Code-Kommentare, README.md und BEDIENUNGSANLEITUNG.md", "info");
ctx.ui.notify("Nächster Schritt: /update_doku für Code-Kommentare, README.md, BEDIENUNGSANLEITUNG.md und LICENCE.md", "info");
}
}
} catch (e: any) {
@ -1387,7 +1434,7 @@ export default function (pi: ExtensionAPI) {
// ── Dokumentations-Phase ─────────────────────────────────────────────────
pi.registerCommand("update_doku", {
description: "Inkrementelle Code-Kommentare + README.md + BEDIENUNGSANLEITUNG.md via Git-Tags.",
description: "Inkrementelle Code-Kommentare + README.md + BEDIENUNGSANLEITUNG.md via Git-Tags; legt LICENCE.md an (proprietär, falls fehlend).",
handler: async function (_args: string, ctx: ExtensionCommandContext) {
await runUpdateDoku(pi, ctx);
}
@ -1484,7 +1531,7 @@ export default function (pi: ExtensionAPI) {
"/patch <änderung> Gezielte Minimaländerung → Coder",
"/quick_check [was] Schnelle OK/PROBLEM-Prüfung → Judge",
"/plan <auftrag> Implementierungsplan in PLAN.md → Coder",
"/update_doku Code-Kommentare + README.md + BEDIENUNGSANLEITUNG.md",
"/update_doku Code-Kommentare + README.md + BEDIENUNGSANLEITUNG.md + LICENCE.md",
"/version Versionsnummer erhöhen (SemVer + Git-Tag)",
"/discard Verwirft PLAN.md",
"/new_project <pfad> Projektverzeichnis + git init + .gitignore",