.vault-tools (ohne trading-plattform-pruefung und watermarks-remover), .claude/agents, .claude/skills, .claude/workflows, .claude/settings.json. Co-Authored-By: Claude Opus 5.5 <[email protected]>
114 lines
4.0 KiB
Python
114 lines
4.0 KiB
Python
#!/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())
|