mindnet/scripts/make_test_vault.py
Lars e9532e8878
All checks were successful
Deploy mindnet to llm-node / deploy (push) Successful in 4s
script_Überprüfung und Kommentarheader
2025-12-28 10:40:28 +01:00

243 lines
6.8 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
FILE: scripts/make_test_vault.py
VERSION: 2.1.0 (2025-12-15)
STATUS: Active (Test-Tool)
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
Zweck:
-------
Erzeugt einen minimalen, nachvollziehbaren Test-Vault für Entwicklung und Tests.
Enthält verschiedene Szenarien: leere Links, externe Links, verschiedene Note-Typen.
Funktionsweise:
---------------
1. Erstellt Verzeichnisstruktur (concepts, experiences, projects)
2. Generiert Test-Notizen mit vollständigem Frontmatter:
- concept-alpha.md (Basis-Concept)
- exp-one.md (verlinkt auf concept-alpha und missing-note)
- exp-two.md (verlinkt auf concept-alpha + externe Links)
- project-demo.md (verlinkt auf concept-alpha und exp-one)
3. Optional: Erstellt missing-note (mit --with-missing)
Ergebnis-Interpretation:
------------------------
- Ausgabe: Erfolgsmeldung mit erstellten Dateien
- Exit-Code 0: Erfolgreich
- Exit-Code 1: Fehler (z.B. Verzeichnis existiert bereits ohne --force)
Verwendung:
-----------
- Entwicklung und Testing
- Demo und Dokumentation
- CI/CD-Tests
Hinweise:
---------
- Erstellt realistische Test-Daten mit verschiedenen Edge-Szenarien
- Enthält "Red Links" (missing-note) für Link-Auflösungs-Tests
- Externe Links für Chunk-Payload-Tests
Aufruf:
-------
python3 -m scripts.make_test_vault --out ./test_vault
python3 -m scripts.make_test_vault --out ./test_vault --force --with-missing
Parameter:
----------
--out PATH Zielverzeichnis (Default: ./test_vault)
--force Löscht bestehenden Ordner und legt neu an
--with-missing Erstellt auch missing-note direkt (Standard: erst im 2. Lauf)
Änderungen:
-----------
v2.1.0 (2025-12-15): Dokumentation aktualisiert
v1.2 (2025-09-09): Externe Links hinzugefügt
v1.0.0: Initial Release
"""
from __future__ import annotations
import argparse
import os
import shutil
from datetime import datetime, timezone
def iso_now() -> str:
# ISO 8601 mit Offset; als String zurückgeben
return datetime.now(timezone.utc).astimezone().isoformat(timespec="seconds")
def q(s: str) -> str:
# Sicheres Quoten für YAML-Frontmatter
return f"\"{s}\""
TEMPLATE_CONCEPT = """---
title: "Concept Alpha"
id: "concept-alpha"
type: "concept"
status: "active"
created: {created}
updated: {updated}
tags: ["area/mindnet","type/concept","topic/test"]
---
## Beschreibung
Dies ist ein einfaches Konzept für Testzwecke. Es wird von anderen Notizen referenziert.
## Mögliche Verbindungen
- [[exp-one]]
- [[project-demo]]
"""
TEMPLATE_EXP_ONE = """---
title: "Experience One"
id: "exp-one"
type: "experience"
status: "active"
created: {created}
updated: {updated}
tags: ["area/mindnet","type/experience","topic/test"]
---
## Kontext
Diese Notiz verlinkt auf ein existierendes Konzept und auf eine noch **fehlende** Note.
## Beobachtung
- Bezug zu [[concept-alpha]]
- Offener Verweis auf [[missing-note]]
## Interpretation
Wenn später eine Datei für 'missing-note' angelegt wird, sollte der Importer die Kanten nachziehen.
## Mögliche Verbindungen
- [[concept-alpha]]
- [[missing-note]]
"""
TEMPLATE_EXP_TWO = """---
title: "Experience Two"
id: "exp-two"
type: "experience"
status: "active"
created: {created}
updated: {updated}
tags: ["area/mindnet","type/experience","topic/test"]
---
## Kontext
Zweite Experience, die auf dasselbe Konzept verweist, ergänzt um **externe Links**.
## Beobachtung
Verweis auf [[concept-alpha]]. Zusätzliche Ressourcen:
- Link: [Beispielseite](https://example.com "Referenz")
- Kontakt: [E-Mail](mailto:info@example.com)
## Mögliche Verbindungen
- [[concept-alpha]]
"""
TEMPLATE_PROJECT = """---
title: "Project Demo"
id: "project-demo"
type: "project"
status: "active"
created: {created}
updated: {updated}
tags: ["area/mindnet","type/project","topic/test"]
---
## Scope
Ein kleines Demo-Projekt, das andere Notizen referenziert.
## Arbeitspakete
- AP-1: Zusammenhang erklären (siehe [[concept-alpha]])
- AP-2: Ereignis berücksichtigen (siehe [[exp-one]])
## Mögliche Verbindungen
- [[concept-alpha]]
- [[exp-one]]
"""
TEMPLATE_MISSING = """---
title: "Missing Note (jetzt angelegt)"
id: "missing-note"
type: "concept"
status: "active"
created: {created}
updated: {updated}
tags: ["area/mindnet","type/concept","topic/test"]
---
## Kontext
Diese Notiz wurde **nachträglich** erstellt, um einen zuvor offenen Link zu schließen.
## Mögliche Verbindungen
- [[exp-one]]
"""
def write_file(path: str, content: str) -> None:
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, "w", encoding="utf-8") as f:
f.write(content)
def build_vault(base: str, include_missing_note: bool) -> None:
created = q(iso_now())
updated = q(iso_now())
# 40_concepts
write_file(
os.path.join(base, "40_concepts", "concept-alpha.md"),
TEMPLATE_CONCEPT.format(created=created, updated=updated),
)
# 20_experiences
write_file(
os.path.join(base, "20_experiences", "exp-one.md"),
TEMPLATE_EXP_ONE.format(created=created, updated=updated),
)
write_file(
os.path.join(base, "20_experiences", "exp-two.md"),
TEMPLATE_EXP_TWO.format(created=created, updated=updated),
)
# 30_projects
write_file(
os.path.join(base, "30_projects", "project-demo.md"),
TEMPLATE_PROJECT.format(created=created, updated=updated),
)
# Optional: zunächst NICHT anlegen (Szenario „leerer Link“),
# später für den 2. Testlauf anlegen.
if include_missing_note:
write_file(
os.path.join(base, "40_concepts", "missing-note.md"),
TEMPLATE_MISSING.format(created=created, updated=updated),
)
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--out", default="./test_vault", help="Zielverzeichnis für den Test-Vault")
ap.add_argument("--force", action="store_true", help="Falls vorhanden: Verzeichnis löschen und neu anlegen")
ap.add_argument("--with-missing", action="store_true",
help="Auch die 'missing-note' direkt anlegen (Standard: erst im 2. Lauf)")
args = ap.parse_args()
base = os.path.abspath(args.out)
if os.path.exists(base):
if args.force:
shutil.rmtree(base)
else:
print(f"Ziel existiert bereits: {base}\nNutze --force zum Überschreiben.")
return
build_vault(base, include_missing_note=args.with_missing)
print(f"Test-Vault erstellt unter: {base}")
print("Hinweis:")
print(" 1) Zuerst ohne missing-note anlegen (Standard), importieren, Edges prüfen.")
print(" 2) Dann erneut ausführen mit --force --with-missing (missing-note wird erzeugt),")
print(" und Import wiederholen → Edges/Backlinks sollten nachgezogen werden.")
print(" 3) In exp-two.md sind **externe Links** enthalten → prüfe `external_links` in Chunk-Payloads.")
if __name__ == "__main__":
main()