Regelwerk, Agenten, Skills und Werkzeuge veröffentlichen

Erster Stand des öffentlichen Ausschnitts aus dem Vault. Die .gitignore
arbeitet als Positivliste: ausgeschlossen ist alles, eingeschlossen nur,
was ausdrücklich wieder aufgenommen wird. Notizen, Projekte, Finanzen,
das Sitzungsgedächtnis und settings.local.json bleiben damit außen vor.

Der Kundenname in AI/Regelwerk/seo.md ist durch eine neutrale
Bezeichnung ersetzt; die Regeln selbst sind unverändert.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
Pascal MichelandClaude Opus 5 committed 2026-09-17 22:38:15 +02:00
commit 2c9a4475fc
97 files changed
+14627

No files matched your search

@@ -0,0 +1,113 @@
#!/usr/bin/env python3
"""Legt eine neue Notiz aus einem Template an — mit korrektem Frontmatter,
korrektem Ordner und stabiler uid.
Von Hand geschriebenes Frontmatter driftet; deshalb dieser Weg. Bestehende
Dateien werden nie überschrieben.
Beispiele:
python3 scripts/new_note.py --type project-code --title "Auth Service" \\
--tags go,oidc --summary "OIDC-Auth für die interne Toolchain"
python3 scripts/new_note.py --type research --title "Rate Limiting Strategien" \\
--project auth-service
python3 scripts/new_note.py --type decision --title "Postgres statt Mongo" \\
--project auth-service
"""
from __future__ import annotations
import argparse
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import vaultlib as V # noqa: E402
SKILL_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEMPLATE_DIR = os.path.join(SKILL_DIR, "assets", "templates")
# type -> (Zielpfad-Muster, eigener Ordner?)
TARGETS = {
"project-code": ("10_Projects/{slug}/index.md", True),
"template-project": ("40_Templates/project-templates/{slug}/index.md", True),
"research": ("30_Research/{slug}.md", False),
"area": ("20_Areas/{slug}.md", False),
"resource": ("50_Resources/{slug}.md", False),
"moc": ("20_Areas/{slug}.md", False),
"decision": ("10_Projects/{project}/decisions/{slug}.md", False),
"inbox": ("00_Inbox/{slug}.md", False),
}
DEFAULT_STATUS = {
"project-code": "active", "research": "active", "area": "reference",
"resource": "reference", "moc": "reference", "decision": "done",
"template-project": "reference", "inbox": "idea",
}
def main() -> int:
ap = argparse.ArgumentParser(description="Notiz aus Template anlegen")
ap.add_argument("--vault", default=".")
ap.add_argument("--type", required=True, choices=sorted(TARGETS))
ap.add_argument("--title", required=True)
ap.add_argument("--summary", default="")
ap.add_argument("--tags", default="")
ap.add_argument("--status", default="")
ap.add_argument("--project", default="", help="Projekt-Slug (Pflicht bei --type decision)")
ap.add_argument("--out", default="", help="Zielpfad relativ zum Vault überschreiben")
ap.add_argument("--print-only", action="store_true", help="Inhalt ausgeben statt schreiben")
args = ap.parse_args()
vault = os.path.abspath(os.path.expanduser(args.vault))
slug = V.slugify(args.title)
pattern, _ = TARGETS[args.type]
if args.out:
rel = args.out
else:
if "{project}" in pattern and not args.project:
print("--project ist bei diesem Typ erforderlich", file=sys.stderr)
return 2
rel = pattern.format(slug=slug, project=V.slugify(args.project or "misc"))
dest = os.path.join(vault, rel)
if os.path.exists(dest) and not args.print_only:
print(f"Existiert bereits: {rel} — nichts geschrieben.", file=sys.stderr)
return 1
tpl_path = os.path.join(TEMPLATE_DIR, f"{args.type}.md")
if not os.path.exists(tpl_path):
tpl_path = os.path.join(TEMPLATE_DIR, "resource.md")
with open(tpl_path, "r", encoding="utf-8") as fh:
tpl = fh.read()
today = V.today()
values = {
"{{uid}}": f"{today.replace('-', '')}-{slug[:40]}",
"{{title}}": args.title,
"{{summary}}": args.summary or "TODO: ein Satz, worum es geht.",
"{{status}}": args.status or DEFAULT_STATUS.get(args.type, "active"),
"{{tags}}": ", ".join(V.as_list(args.tags)),
"{{project}}": args.project,
"{{date}}": today,
"{{slug}}": slug,
}
content = tpl
for k, v in values.items():
content = content.replace(k, v)
if args.print_only:
print(content)
return 0
os.makedirs(os.path.dirname(dest), exist_ok=True)
with open(dest, "w", encoding="utf-8") as fh:
fh.write(content)
print(rel)
print("Angelegt. Danach: summary prüfen, Referenzen ergänzen, "
"build_index.py laufen lassen.")
return 0
if __name__ == "__main__":
raise SystemExit(main())