Erik Thiele 11eb770c8b Add a collapsible Markdown cheat sheet to the prompt input
A short, native <details>/<summary> reference (no JS) next to the
hint text, listing the basic syntax the new markdown rendering
supports: headings, bold/italic, lists, quotes, inline code, code
blocks, links.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-30 14:55:59 +02:00

LinkVault

KI-gestützte Sammlung für Links und Prompts: eingeben → automatisch kategorisieren, in Kategorien / Hersteller / Tags einsortieren und schnell wiederfinden. Beide Sammlungen laufen in derselben App und Datenbank, per Menü umschaltbar.

Funktionen

  • 🔗 Link hinzufügen Seite wird geladen und der Textinhalt extrahiert.
  • Prompt hinzufügen eigener Bereich für KI-Prompts, per Kopf-Menü zwischen „Links" und „Prompts" umschaltbar. Prompts werden ebenfalls automatisch kategorisiert und getaggt, lassen sich per Kategorie/Volltext durchsuchen und mit einem Klick in die Zwischenablage kopieren. Der Prompt-Text unterstützt Markdown (Überschriften, Listen, Fett/Kursiv, Codeblöcke, Zitate) in der Karten-Vorschau wird das gerendert, beim Kopieren landet der rohe Markdown-Text (für Struktur in der Ziel-KI) in der Zwischenablage.
  • 🤖 Automatische KI-Analyse (OpenAI) Titel, Zusammenfassung/Kategorie und Tags werden erzeugt. Bestehende Kategorien werden wiederverwendet, damit die Sammlung konsistent bleibt.
  • Bearbeiten alle Felder lassen sich jederzeit manuell anpassen. Alternativ kann die KI Links/Prompts neu beschreiben bzw. neu kategorisieren lassen.
  • 🗂️ Filtern nach Kategorie (Links zusätzlich nach Hersteller) über die Seitenleiste.
  • 🔍 Suche klassische Textsuche, bei Links zusätzlich optionale semantische KI-Suche (findet auch sinnverwandte Treffer via Embeddings).
  • ↕️ Sortieren nach Datum (neueste/älteste zuerst) oder Name (AZ / ZA).
  • 🔖 Merkliste Links lassen sich zur späteren Durchsicht markieren.
  • 🕓 Hinzufügedatum wird pro Eintrag angezeigt.
  • 📤 Export/Import (Einstellungen) Links als CSV oder SQL-Dump exportieren, SQL-Dump auch wieder importieren.
  • 🌗 Dark/Light-Modus über den Umschalter im Kopfbereich.
  • 👥 Mehrbenutzer Registrierung/Login, jeder Nutzer sieht nur seine eigenen Links und Prompts.

Die Fußzeile zeigt Autor, Version und den Hostnamen des Servers. Die Version lässt sich über APP_VERSION in der .env setzen.

Technik

  • Backend: FastAPI (Python)
  • Frontend: HTML + HTMX (kein Node.js nötig)
  • Datenbank: SQLite (Standard, konfigurierbar über DATABASE_URL)
  • KI: OpenAI (gpt-4o-mini + text-embedding-3-small, konfigurierbar)

Schnellstart

./run.sh

Das Skript legt eine virtuelle Umgebung an, installiert die Abhängigkeiten, erstellt bei Bedarf eine .env und startet den Server auf http://127.0.0.1:8000.

Danach in .env den OPENAI_API_KEY eintragen und den Server neu starten.

Ohne API-Key läuft die App trotzdem Links werden dann nur ohne KI-Analyse gespeichert (Kategorie „Sonstiges", keine Zusammenfassung/semantische Suche).

Manuell

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env        # OPENAI_API_KEY eintragen
uvicorn app.main:app --reload --port 8000

Projektstruktur

app/
  main.py        FastAPI-App, Routen (Links & Prompts), Auth-Sessions
  config.py      Konfiguration aus .env
  database.py    SQLAlchemy Engine/Session
  models.py      User-, Link- und Prompt-Modelle
  security.py    Passwort-Hashing (bcrypt)
  scraper.py     Seiteninhalt laden & extrahieren (nur Links)
  ai.py          OpenAI: Kategorisierung (Links & Prompts), Embeddings
  search.py      Semantische Suche (Kosinus-Ähnlichkeit, nur Links)
  backup.py      CSV-/SQL-Export und sicherer SQL-Import (nur Links)
  mdrender.py    Sicheres Markdown-Rendering für Prompt-Inhalte
  templates/     Jinja2 + HTMX Oberfläche

Proxmox

Für den Betrieb in einem Proxmox-VE-LXC-Container gibt es ein Helper-Script (scripts/proxmox/install-linkvault.sh). Es legt automatisch einen Debian-12-Container an und richtet LinkVault darin als systemd-Service ein.

Installation

Auf dem Proxmox-Host (als root) ausführen:

bash <(curl -fsSL https://gitea.teamthiele.de/ethiele/linkvault/raw/branch/main/scripts/proxmox/install-linkvault.sh)

Falls das Repo (wieder) auf privat gestellt wird, zusätzlich ein Gitea Access Token verwenden (Einstellungen → Anwendungen → Neuen Token erzeugen, Scope read:repository genügt):

export GIT_TOKEN=<dein-token>
bash <(curl -fsSL -H "Authorization: token ${GIT_TOKEN}" \
  https://gitea.teamthiele.de/ethiele/linkvault/raw/branch/main/scripts/proxmox/install-linkvault.sh)

GIT_TOKEN wird automatisch an das Script weitergereicht und auch beim git clone innerhalb des LXC-Containers verwendet.

Alternativ, falls das Repo bereits lokal ausgecheckt ist:

bash scripts/proxmox/install-linkvault.sh

Das Script:

  1. lädt bei Bedarf das Debian-12-LXC-Template herunter,
  2. erstellt einen unprivilegierten LXC-Container,
  3. installiert darin Python, klont das Repo nach /opt/linkvault,
  4. legt ein venv an und installiert die Abhängigkeiten,
  5. erzeugt eine .env mit zufälligem SECRET_KEY,
  6. richtet LinkVault als systemd-Service (linkvault.service) ein und startet ihn.

Am Ende gibt das Script die URL des Containers sowie das generierte root-Passwort aus.

Konfiguration

Alle Einstellungen lassen sich per Umgebungsvariable vor dem Aufruf setzen (Defaults siehe Kopf des Scripts):

Variable Bedeutung Default
CTID Container-ID nächste freie ID
CT_HOSTNAME Hostname des Containers linkvault
CT_DISK_GB Größe der Root-Disk in GB 8
CT_MEMORY_MB RAM in MB 1024
CT_SWAP_MB Swap in MB 512
CT_CORES CPU-Kerne 2
CT_BRIDGE Netzwerk-Bridge vmbr0
CT_IP Statische IP (192.168.1.50/24) oder dhcp dhcp
CT_GW Gateway (nur bei statischer IP nötig)
CT_STORAGE Storage für die Root-Disk local-lvm
TEMPLATE_STORAGE Storage für das LXC-Template local
CT_PASSWORD root-Passwort des Containers zufällig generiert
REPO_URL Git-Repo, das geklont wird .../ethiele/linkvault.git
APP_PORT Port, auf dem uvicorn lauscht 8000
GIT_TOKEN Gitea Access Token (nur bei privatem Repo)

Beispiel mit statischer IP und fester Container-ID:

CTID=150 CT_HOSTNAME=linkvault CT_IP=192.168.1.50/24 CT_GW=192.168.1.1 \
  bash <(curl -fsSL https://gitea.teamthiele.de/ethiele/linkvault/raw/branch/main/scripts/proxmox/install-linkvault.sh)

Nach der Installation

In /opt/linkvault/.env innerhalb des Containers den OPENAI_API_KEY eintragen (siehe Schnellstart für weitere .env-Optionen), danach den Dienst neu starten:

pct exec <CTID> -- systemctl restart linkvault

Nützliche Befehle:

pct exec <CTID> -- systemctl status linkvault   # Status prüfen
pct exec <CTID> -- journalctl -u linkvault -f    # Logs verfolgen

Updaten

Wenn sich im Git-Repo etwas geändert hat, den Container mit scripts/proxmox/update-linkvault.sh auf den neuesten Stand bringen. Das Script zieht per git pull, aktualisiert die Python-Abhängigkeiten und startet den systemd-Service neu. Auf dem Proxmox-Host ausführen:

CTID=113 bash <(curl -fsSL https://gitea.teamthiele.de/ethiele/linkvault/raw/branch/main/scripts/proxmox/update-linkvault.sh)

(GIT_TOKEN nur nötig, falls das Repo privat ist siehe oben.)

Alternativ, falls das Repo bereits auf dem Proxmox-Host selbst per git clone ausgecheckt wurde (z.B. unter ~/linkvault) und du dich in diesem Verzeichnis befindest:

CTID=113 bash scripts/proxmox/update-linkvault.sh

Hinweise für den Produktivbetrieb

  • Einen zufälligen SECRET_KEY in .env setzen.
  • Hinter einem HTTPS-Reverse-Proxy betreiben (Session-Cookies).
  • Für mehr Last statt SQLite z.B. PostgreSQL via DATABASE_URL verwenden.
Description
No description provided
Readme 325 KiB
Languages
HTML 46.8%
Python 45.1%
Shell 7.3%
Dockerfile 0.8%