Spezialisierung gehört zum Thema, Hinweise zur Version
Thema „Game Design“ plus Spezialisierung „digitale Sammelkartenspiele“ wird zur Bezeichnung „Game Design – digitale Sammelkartenspiele“ (Ordner, Liste). Die Prompts bekommen das Hauptthema und die Spezialisierung getrennt. „Neue Version“ ändert nur noch die Hinweise. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
13
API.md
13
API.md
@@ -12,13 +12,14 @@ Ohne `v2` gilt die neueste Version.
|
|||||||
|
|
||||||
## Themen und Versionen
|
## Themen und Versionen
|
||||||
|
|
||||||
- `GET /api/themen` → `[{slug, name, titel, hinweise, spezialisierung, angelegt, status, laeuft, stufe, versionen: [{v, status, laeuft, stufe, angelegt, kosten_usd}]}]`
|
- `GET /api/themen` → `[{slug, name, thema, spezialisierung, titel, hinweise, angelegt, status, laeuft, stufe, versionen: [{v, status, laeuft, stufe, angelegt, kosten_usd}]}]`
|
||||||
– `status/laeuft/stufe` gelten für die neueste Version; `status`: `neu | laeuft | pausiert | fertig | fehler`
|
– `status/laeuft/stufe` gelten für die neueste Version; `status`: `neu | laeuft | pausiert | fertig | fehler`
|
||||||
- `POST /api/themen` `{name, hinweise, spezialisierung}` → Thema wie oben (legt `v1` an)
|
- `POST /api/themen` `{name, hinweise, spezialisierung}` → Thema wie oben (legt `v1` an)
|
||||||
– `hinweise`: wie das Thema zu verstehen ist (fügt hinzu); `spezialisierung`: Grenze des Umfangs, nur was dafür gebraucht wird (nimmt weg)
|
– `name`: Hauptthema; `spezialisierung`: grenzt es ein, nur was dafür gebraucht wird; die Bezeichnung (`name` in der Antwort, Ordner) wird „Thema – Spezialisierung“
|
||||||
|
– `hinweise`: wie das Thema zu verstehen ist; gelten je Version und sind bei einer neuen Version änderbar
|
||||||
- `GET /api/themen/{slug}` → Thema wie oben
|
- `GET /api/themen/{slug}` → Thema wie oben
|
||||||
- `DELETE /api/themen/{slug}` – ganzes Thema
|
- `DELETE /api/themen/{slug}` – ganzes Thema
|
||||||
- `POST /api/themen/{slug}/versionen` `{hinweise?, spezialisierung?}` → `{"v": N}` – nächste Version ohne Start; fehlende Felder übernimmt sie von der neuesten Version
|
- `POST /api/themen/{slug}/versionen` `{hinweise?}` → `{"v": N}` – nächste Version ohne Start; ohne Angabe übernimmt sie die Hinweise der neuesten Version
|
||||||
- `DELETE /api/themen/{slug}/v{N}` – nur diese Version
|
- `DELETE /api/themen/{slug}/v{N}` – nur diese Version
|
||||||
- `POST /api/themen/{slug}/v{N}/start` – startet oder setzt fort (resümiert an der offenen Stufe)
|
- `POST /api/themen/{slug}/v{N}/start` – startet oder setzt fort (resümiert an der offenen Stufe)
|
||||||
- `POST /api/themen/{slug}/v{N}/pause` – bricht laufende Agenten ab; Neustart mit `start`
|
- `POST /api/themen/{slug}/v{N}/pause` – bricht laufende Agenten ab; Neustart mit `start`
|
||||||
@@ -38,7 +39,7 @@ Alte Zustände ohne diese Stufe bekommen sie beim Laden nachgetragen.
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"slug": "godot-4", "name": "Godot 4", "version": 1, "titel": "Godot 4", "hinweise": "…", "spezialisierung": "", // Eingaben dieser Version
|
"slug": "godot-4", "name": "Godot 4", "version": 1, "thema": "Godot 4", "spezialisierung": "", "titel": "Godot 4", "hinweise": "…", // hinweise: die dieser Version
|
||||||
"status": "laeuft", "grund": "", "stufe": "schreiben", "angelegt": "2026-09-28T10:00:00Z",
|
"status": "laeuft", "grund": "", "stufe": "schreiben", "angelegt": "2026-09-28T10:00:00Z",
|
||||||
"deutung": {"titel": "Godot 4", "untertitel": "…", "deutung": "…", "buchtyp": "werkzeug|wissen", "zielgruppe": "…"},
|
"deutung": {"titel": "Godot 4", "untertitel": "…", "deutung": "…", "buchtyp": "werkzeug|wissen", "zielgruppe": "…"},
|
||||||
"stufen": [
|
"stufen": [
|
||||||
@@ -92,9 +93,9 @@ Solange ein Lauf läuft, enthält `buch` die bereits geschriebenen Kapitel (Stat
|
|||||||
|
|
||||||
```
|
```
|
||||||
storage/<Thema>/
|
storage/<Thema>/
|
||||||
thema.json {name, slug, titel, hinweise, spezialisierung, angelegt}
|
thema.json {name, thema, spezialisierung, slug, titel, hinweise, angelegt} – name = „Thema – Spezialisierung“
|
||||||
v1/, v2/, … je Version:
|
v1/, v2/, … je Version:
|
||||||
state.json Zustand wie oben (ohne Buch), mit hinweise und spezialisierung der Version
|
state.json Zustand wie oben (ohne Buch), mit den Hinweisen der Version
|
||||||
deutung.json vom Recherche-Agenten
|
deutung.json vom Recherche-Agenten
|
||||||
position.json Leseposition
|
position.json Leseposition
|
||||||
quellen/ QUELLEN.md + geklonte/geladene Quellen
|
quellen/ QUELLEN.md + geklonte/geladene Quellen
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# buchwerk
|
# buchwerk
|
||||||
|
|
||||||
Aus einem Thema (plus optionalen Hinweisen und einer optionalen Spezialisierung, die den Umfang begrenzt) entsteht ein deutschsprachiges Sachbuch. Ein Python-Backend
|
Aus einem Thema (plus optionaler Spezialisierung, die es eingrenzt, und optionalen Hinweisen) entsteht ein deutschsprachiges Sachbuch. Ein Python-Backend
|
||||||
steuert Agenten des Claude Agent SDK (Opus 5.5): Recherche und Deutung, Gliederung, Kapitel parallel
|
steuert Agenten des Claude Agent SDK (Opus 5.5): Recherche und Deutung, Gliederung, Kapitel parallel
|
||||||
schreiben, jedes Kapitel durch einen unabhängigen Agenten prüfen, Querverweise abgleichen, Vorwort,
|
schreiben, jedes Kapitel durch einen unabhängigen Agenten prüfen, Querverweise abgleichen, Vorwort,
|
||||||
Montage (Markdown, README, PDF). Das Buch wird im Browser als Leseansicht gezeigt.
|
Montage (Markdown, README, PDF). Das Buch wird im Browser als Leseansicht gezeigt.
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ class ThemaNeu(BaseModel):
|
|||||||
|
|
||||||
class VersionNeu(BaseModel):
|
class VersionNeu(BaseModel):
|
||||||
hinweise: str | None = None # None: wie die bisherige Version
|
hinweise: str | None = None # None: wie die bisherige Version
|
||||||
spezialisierung: str | None = None
|
|
||||||
|
|
||||||
|
|
||||||
class Position(BaseModel):
|
class Position(BaseModel):
|
||||||
@@ -73,7 +72,8 @@ def _thema_info(t: dict) -> dict | None:
|
|||||||
if not vs:
|
if not vs:
|
||||||
return None
|
return None
|
||||||
neueste = vs[-1]
|
neueste = vs[-1]
|
||||||
return {"slug": t["slug"], "name": t["name"], "titel": t["titel"], "hinweise": t.get("hinweise", ""), "spezialisierung": t.get("spezialisierung", ""),
|
return {"slug": t["slug"], "name": t["name"], "thema": t.get("thema") or t["name"], "spezialisierung": t.get("spezialisierung", ""),
|
||||||
|
"titel": t["titel"], "hinweise": t.get("hinweise", ""),
|
||||||
"angelegt": t.get("angelegt", ""), "status": neueste["status"], "laeuft": neueste["laeuft"],
|
"angelegt": t.get("angelegt", ""), "status": neueste["status"], "laeuft": neueste["laeuft"],
|
||||||
"stufe": neueste["stufe"], "versionen": vs}
|
"stufe": neueste["stufe"], "versionen": vs}
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ async def themen():
|
|||||||
@app.post("/api/themen")
|
@app.post("/api/themen")
|
||||||
async def thema_anlegen(body: ThemaNeu):
|
async def thema_anlegen(body: ThemaNeu):
|
||||||
name = body.name.strip()
|
name = body.name.strip()
|
||||||
if not state.name_ok(name):
|
if not state.name_ok(name) or not state.name_ok(state.bezeichnung(name, body.spezialisierung.strip())):
|
||||||
raise HTTPException(400, "Ungültiger Name")
|
raise HTTPException(400, "Ungültiger Name")
|
||||||
try:
|
try:
|
||||||
return _thema_info(state.anlegen(name, body.hinweise, body.spezialisierung))
|
return _thema_info(state.anlegen(name, body.hinweise, body.spezialisierung))
|
||||||
@@ -110,9 +110,9 @@ async def thema_loeschen(slug: str):
|
|||||||
|
|
||||||
@app.post("/api/themen/{slug}/versionen")
|
@app.post("/api/themen/{slug}/versionen")
|
||||||
async def version_anlegen(slug: str, body: VersionNeu | None = None):
|
async def version_anlegen(slug: str, body: VersionNeu | None = None):
|
||||||
"""Neue Version: frischer Lauf ohne Wissen über die Vorgänger; Hinweise und Spezialisierung wahlweise geändert."""
|
"""Neue Version: frischer Lauf ohne Wissen über die Vorgänger; Hinweise wahlweise geändert."""
|
||||||
b = body or VersionNeu()
|
b = body or VersionNeu()
|
||||||
key = state.version_anlegen(_thema(slug)["name"], b.hinweise, b.spezialisierung)
|
key = state.version_anlegen(_thema(slug)["name"], b.hinweise)
|
||||||
return {"v": int(key.rsplit("/v", 1)[1])}
|
return {"v": int(key.rsplit("/v", 1)[1])}
|
||||||
|
|
||||||
|
|
||||||
@@ -121,8 +121,8 @@ async def zustand(slug: str, n: int):
|
|||||||
key = _key(slug, n)
|
key = _key(slug, n)
|
||||||
t = _thema(slug)
|
t = _thema(slug)
|
||||||
st = state.zustand(key)
|
st = state.zustand(key)
|
||||||
h, sp = state.eingaben(key)
|
return {"slug": slug, "name": t["name"], "thema": t.get("thema") or t["name"], "version": n, "titel": t["titel"], **st,
|
||||||
return {"slug": slug, "name": t["name"], "version": n, "titel": t["titel"], **st, "hinweise": h, "spezialisierung": sp,
|
"hinweise": state.hinweise_von(key), "spezialisierung": state.spezialisierung_von(key),
|
||||||
"deutung": st.get("deutung") or state.deutung(key), "ereignisse": st["ereignisse"][-100:]}
|
"deutung": st.get("deutung") or state.deutung(key), "ereignisse": st["ereignisse"][-100:]}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -73,9 +73,9 @@ def _offen(name: str) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def _thema(name: str) -> tuple[str, str, str]:
|
def _thema(name: str) -> tuple[str, str, str]:
|
||||||
"""Titel, Hinweise, Spezialisierung – die Eingaben gelten je Version."""
|
"""Hauptthema (ohne Spezialisierung), Hinweise der Version, Spezialisierung des Themas."""
|
||||||
t = state.thema(name) or {}
|
t = state.thema(name) or {}
|
||||||
return (t.get("titel") or name, *state.eingaben(name))
|
return t.get("thema") or state.thema_von(name), state.hinweise_von(name), state.spezialisierung_von(name)
|
||||||
|
|
||||||
|
|
||||||
def _kapitel(name: str) -> list[dict]:
|
def _kapitel(name: str) -> list[dict]:
|
||||||
|
|||||||
@@ -55,32 +55,32 @@ def name_von_slug(sl: str) -> str | None:
|
|||||||
return next((t["name"] for t in themen() if t.get("slug") == sl), None)
|
return next((t["name"] for t in themen() if t.get("slug") == sl), None)
|
||||||
|
|
||||||
|
|
||||||
def version_anlegen(name: str, hinweise: str | None = None, spezialisierung: str | None = None) -> str:
|
def version_anlegen(name: str, hinweise: str | None = None) -> str:
|
||||||
"""Neue Version; ohne Angabe übernimmt sie Hinweise und Spezialisierung der neuesten Version (bzw. des Themas)."""
|
"""Neue Version; ohne Angabe übernimmt sie die Hinweise der neuesten Version (bzw. des Themas)."""
|
||||||
vs = versionen(name)
|
vs = versionen(name)
|
||||||
alt_h, alt_s = eingaben(f"{name}/v{vs[-1]}") if vs else _eingaben_thema(name)
|
alt = hinweise_von(f"{name}/v{vs[-1]}") if vs else (thema(name) or {}).get("hinweise", "")
|
||||||
key = f"{name}/v{(vs or [0])[-1] + 1}"
|
key = f"{name}/v{(vs or [0])[-1] + 1}"
|
||||||
v = verzeichnis(key)
|
v = verzeichnis(key)
|
||||||
for u in ("quellen", "buch", "berichte", "arbeit"):
|
for u in ("quellen", "buch", "berichte", "arbeit"):
|
||||||
(v / u).mkdir(parents=True)
|
(v / u).mkdir(parents=True)
|
||||||
st = leerer_zustand()
|
_schreiben(v / "state.json", {**leerer_zustand(), "hinweise": (alt if hinweise is None else hinweise).strip()})
|
||||||
st["hinweise"] = (alt_h if hinweise is None else hinweise).strip()
|
|
||||||
st["spezialisierung"] = (alt_s if spezialisierung is None else spezialisierung).strip()
|
|
||||||
_schreiben(v / "state.json", st)
|
|
||||||
return key
|
return key
|
||||||
|
|
||||||
|
|
||||||
def _eingaben_thema(name: str) -> tuple[str, str]:
|
def hinweise_von(key: str) -> str:
|
||||||
t = thema(name) or {}
|
"""Hinweise gelten je Version; alte Versionen ohne eigene nehmen die des Themas."""
|
||||||
return t.get("hinweise", ""), t.get("spezialisierung", "")
|
|
||||||
|
|
||||||
|
|
||||||
def eingaben(key: str) -> tuple[str, str]:
|
|
||||||
"""Hinweise und Spezialisierung einer Version; alte Versionen ohne eigene Eingaben nehmen die des Themas."""
|
|
||||||
st = zustand(key)
|
st = zustand(key)
|
||||||
if "hinweise" in st:
|
return st["hinweise"] if "hinweise" in st else (thema(key) or {}).get("hinweise", "")
|
||||||
return st["hinweise"], st.get("spezialisierung", "")
|
|
||||||
return _eingaben_thema(key)
|
|
||||||
|
def spezialisierung_von(key: str) -> str:
|
||||||
|
"""Die Spezialisierung gehört zum Thema: eine andere Spezialisierung ist ein anderes Buch."""
|
||||||
|
return (thema(key) or {}).get("spezialisierung", "")
|
||||||
|
|
||||||
|
|
||||||
|
def bezeichnung(name: str, spezialisierung: str) -> str:
|
||||||
|
"""Ordner- und Anzeigename: „Game Design – digitale Sammelkartenspiele“."""
|
||||||
|
return f"{name} – {spezialisierung}" if spezialisierung else name
|
||||||
|
|
||||||
|
|
||||||
def version_loeschen(key: str) -> None:
|
def version_loeschen(key: str) -> None:
|
||||||
@@ -138,13 +138,17 @@ def themen() -> list[dict]:
|
|||||||
|
|
||||||
|
|
||||||
def anlegen(name: str, hinweise: str, spezialisierung: str = "") -> dict:
|
def anlegen(name: str, hinweise: str, spezialisierung: str = "") -> dict:
|
||||||
d = config.STORAGE / name
|
"""name ist das Hauptthema („Game Design“), die Spezialisierung grenzt es ein; beides zusammen bildet die Bezeichnung."""
|
||||||
|
spezialisierung = spezialisierung.strip()
|
||||||
|
bez = bezeichnung(name, spezialisierung)
|
||||||
|
d = config.STORAGE / bez
|
||||||
if d.exists():
|
if d.exists():
|
||||||
raise ValueError("Thema existiert schon")
|
raise ValueError("Thema existiert schon")
|
||||||
d.mkdir(parents=True)
|
d.mkdir(parents=True)
|
||||||
t = {"name": name, "slug": slug_frei(name), "titel": name, "hinweise": hinweise.strip(), "spezialisierung": spezialisierung.strip(), "angelegt": jetzt()}
|
t = {"name": bez, "thema": name, "spezialisierung": spezialisierung, "slug": slug_frei(bez), "titel": bez,
|
||||||
|
"hinweise": hinweise.strip(), "angelegt": jetzt()}
|
||||||
_schreiben(d / "thema.json", t)
|
_schreiben(d / "thema.json", t)
|
||||||
version_anlegen(name)
|
version_anlegen(bez)
|
||||||
return t
|
return t
|
||||||
|
|
||||||
|
|
||||||
@@ -156,14 +160,14 @@ def loeschen(name: str) -> None:
|
|||||||
|
|
||||||
def zuruecksetzen(key: str) -> None:
|
def zuruecksetzen(key: str) -> None:
|
||||||
v = verzeichnis(key)
|
v = verzeichnis(key)
|
||||||
h, s = eingaben(key)
|
h = hinweise_von(key)
|
||||||
_cache.pop(key, None)
|
_cache.pop(key, None)
|
||||||
for u in ("quellen", "buch", "berichte", "arbeit"):
|
for u in ("quellen", "buch", "berichte", "arbeit"):
|
||||||
shutil.rmtree(v / u, ignore_errors=True)
|
shutil.rmtree(v / u, ignore_errors=True)
|
||||||
(v / u).mkdir()
|
(v / u).mkdir()
|
||||||
for f in ("deutung.json", "log.jsonl", "state.json", "position.json"):
|
for f in ("deutung.json", "log.jsonl", "state.json", "position.json"):
|
||||||
(v / f).unlink(missing_ok=True)
|
(v / f).unlink(missing_ok=True)
|
||||||
_schreiben(v / "state.json", {**leerer_zustand(), "hinweise": h, "spezialisierung": s})
|
_schreiben(v / "state.json", {**leerer_zustand(), "hinweise": h})
|
||||||
|
|
||||||
|
|
||||||
def thema(key: str) -> dict | None:
|
def thema(key: str) -> dict | None:
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ function tokens(n) { return n >= 1e6 ? (n / 1e6).toFixed(1) + 'M' : n >= 1e3 ? M
|
|||||||
<div class="neu">
|
<div class="neu">
|
||||||
<input v-model="neuName" placeholder="Thema, z. B. Godot 4" @keyup.enter="anlegen" />
|
<input v-model="neuName" placeholder="Thema, z. B. Godot 4" @keyup.enter="anlegen" />
|
||||||
<input v-model="neuHinweise" placeholder="Hinweise (optional), z. B. für Entwickler, ab Version 4.6" @keyup.enter="anlegen" />
|
<input v-model="neuHinweise" placeholder="Hinweise (optional), z. B. für Entwickler, ab Version 4.6" @keyup.enter="anlegen" />
|
||||||
<input v-model="neuSpezialisierung" placeholder="Spezialisierung (optional), z. B. Kartenspiel gegen KI" title="Begrenzt den Umfang: nur, was dafür gebraucht wird" @keyup.enter="anlegen" />
|
<input v-model="neuSpezialisierung" placeholder="Spezialisierung (optional), z. B. digitale Sammelkartenspiele" title="Grenzt das Thema ein; Bezeichnung wird „Thema – Spezialisierung“" @keyup.enter="anlegen" />
|
||||||
<button @click="anlegen">Anlegen</button>
|
<button @click="anlegen">Anlegen</button>
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|||||||
@@ -36,12 +36,11 @@ const gruppen = computed(() => {
|
|||||||
const ereignisse = computed(() => (props.state?.ereignisse || []).slice(-100).reverse())
|
const ereignisse = computed(() => (props.state?.ereignisse || []).slice(-100).reverse())
|
||||||
|
|
||||||
function reset() { if (confirm('Lauf zurücksetzen? Alles außer dem Thema wird gelöscht.')) emit('reset') }
|
function reset() { if (confirm('Lauf zurücksetzen? Alles außer dem Thema wird gelöscht.')) emit('reset') }
|
||||||
// Neue Version: Formular mit den Eingaben dieser Version vorbelegt; Thema bleibt, Hinweise und Spezialisierung sind änderbar.
|
// Neue Version: Formular mit den Hinweisen dieser Version vorbelegt; Thema und Spezialisierung bleiben.
|
||||||
const neuOffen = ref(false)
|
const neuOffen = ref(false)
|
||||||
const neuHinweise = ref('')
|
const neuHinweise = ref('')
|
||||||
const neuSpezialisierung = ref('')
|
function neuOeffnen() { neuHinweise.value = props.state.hinweise || ''; neuOffen.value = true }
|
||||||
function neuOeffnen() { neuHinweise.value = props.state.hinweise || ''; neuSpezialisierung.value = props.state.spezialisierung || ''; neuOffen.value = true }
|
function neuStarten() { neuOffen.value = false; emit('neue-version', { hinweise: neuHinweise.value.trim() }) }
|
||||||
function neuStarten() { neuOffen.value = false; emit('neue-version', { hinweise: neuHinweise.value.trim(), spezialisierung: neuSpezialisierung.value.trim() }) }
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -50,7 +49,7 @@ function neuStarten() { neuOffen.value = false; emit('neue-version', { hinweise:
|
|||||||
<button v-if="!laeuft && !fertig" @click="emit('start')">{{ begonnen ? 'Fortsetzen' : 'Buch erzeugen' }}</button>
|
<button v-if="!laeuft && !fertig" @click="emit('start')">{{ begonnen ? 'Fortsetzen' : 'Buch erzeugen' }}</button>
|
||||||
<button v-if="laeuft" class="sekundaer" @click="emit('pause')">Pause</button>
|
<button v-if="laeuft" class="sekundaer" @click="emit('pause')">Pause</button>
|
||||||
<button v-if="!laeuft && begonnen && !fertig" class="sekundaer" @click="reset">Zurücksetzen</button>
|
<button v-if="!laeuft && begonnen && !fertig" class="sekundaer" @click="reset">Zurücksetzen</button>
|
||||||
<button v-if="!laeuft && begonnen" class="sekundaer" title="Gleiches Thema, kompletter neuer Lauf; Hinweise und Spezialisierung änderbar" @click="neuOeffnen">Neue Version</button>
|
<button v-if="!laeuft && begonnen" class="sekundaer" title="Gleiches Thema, kompletter neuer Lauf; Hinweise änderbar" @click="neuOeffnen">Neue Version</button>
|
||||||
<span class="spacer"></span>
|
<span class="spacer"></span>
|
||||||
<span class="badge" :class="statusFarbe[state.status]">{{ statusText[state.status] || state.status }}<template v-if="state.stufe && laeuft"> · {{ state.stufe }}</template></span>
|
<span class="badge" :class="statusFarbe[state.status]">{{ statusText[state.status] || state.status }}<template v-if="state.stufe && laeuft"> · {{ state.stufe }}</template></span>
|
||||||
<span class="badge">{{ usd(state.kosten_usd) }}</span>
|
<span class="badge">{{ usd(state.kosten_usd) }}</span>
|
||||||
@@ -61,14 +60,13 @@ function neuStarten() { neuOffen.value = false; emit('neue-version', { hinweise:
|
|||||||
<div v-if="neuOffen" class="neu-version">
|
<div v-if="neuOffen" class="neu-version">
|
||||||
<div class="titel">Neue Version von „{{ state.name }}“</div>
|
<div class="titel">Neue Version von „{{ state.name }}“</div>
|
||||||
<input v-model="neuHinweise" placeholder="Hinweise (optional), z. B. für Entwickler, ab Version 4.6" @keyup.enter="neuStarten" />
|
<input v-model="neuHinweise" placeholder="Hinweise (optional), z. B. für Entwickler, ab Version 4.6" @keyup.enter="neuStarten" />
|
||||||
<input v-model="neuSpezialisierung" placeholder="Spezialisierung (optional), z. B. Kartenspiel gegen KI" title="Begrenzt den Umfang: nur, was dafür gebraucht wird" @keyup.enter="neuStarten" />
|
|
||||||
<div class="knoepfe"><button @click="neuStarten">Buch erzeugen</button><button class="sekundaer" @click="neuOffen = false">Abbrechen</button></div>
|
<div class="knoepfe"><button @click="neuStarten">Buch erzeugen</button><button class="sekundaer" @click="neuOffen = false">Abbrechen</button></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="eingaben">
|
<div class="eingaben">
|
||||||
<b>Thema</b><span>{{ state.name }}</span>
|
<b>Thema</b><span>{{ state.thema }}</span>
|
||||||
<b>Hinweise</b><span>{{ state.hinweise || '–' }}</span>
|
|
||||||
<b>Spezialisierung</b><span>{{ state.spezialisierung || '–' }}</span>
|
<b>Spezialisierung</b><span>{{ state.spezialisierung || '–' }}</span>
|
||||||
|
<b>Hinweise</b><span>{{ state.hinweise || '–' }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="state.deutung" class="deutung">
|
<div v-if="state.deutung" class="deutung">
|
||||||
|
|||||||
Reference in New Issue
Block a user