Was macht crm.cli?
Ein headless, CLI-zentriertes CRM. Kontakte, Deals und Pipeline in einer einzigen SQLite-Datei – abfragbar von deinem Terminal, kombinierbar mit Unix-Werkzeugen und bereitstellbar als virtuelles Dateisystem.
Installation
curl -fsSL https://raw.githubusercontent.com/dzhng/crm.cli/main/install.sh | sh
Dieses Skript lädt die vorkompilierte Binärdatei nach ~/.local/bin herunter und installiert die Mount-Abhängigkeiten (FUSE unter Linux, Rust Toolchain unter macOS für NFS).
Nach der Installation stelle sicher, dass sich ~/.local/bin in deinem PATH befindet:
export PATH="$HOME/.local/bin:$PATH"
Überprüfe:
crm --version
Konfiguration
Optional. Erstelle crm.toml in deinem Projektstammverzeichnis oder unter ~/.crm/config.toml:
[database]
path = "~/.crm/crm.db"
[pipeline]
stages = ["lead", "qualified", "proposal", "negotiation", "closed-won", "closed-lost"]
won_stage = "closed-won"
lost_stage = "closed-lost"
[defaults]
format = "table"
[phone]
default_country = "US"
display = "international"
[mount]
default_path = "~/crm"
Die Konfiguration wird automatisch durch Aufwärtssuchen ab dem aktuellen Verzeichnis gefunden. Überschreiben mit --config <Pfad> oder der Umgebungsvariable CRM_CONFIG.
Global Flags
Jeder Befehl akzeptiert:
--db <Pfad>— SQLite-Datenbankpfad (Standard:~/.crm/crm.db, Umgebung:CRM_DB)--format <Fmt>— Ausgabeformat:table,json,csv,tsv,ids--config <Pfad>— TOML-Konfigurationsdateipfad--no-color— Deaktiviere farbige Ausgabe
Kontakte
Kontakt erstellen
crm contact add --name "Jane Doe" \
--email [email protected] \
--phone "+1-212-555-1234" \
--linkedin linkedin.com/in/janedoe \
--company "Acme Corp" \
--tag hot-lead \
--set title=CTO
Alle Flags sind optional außer --name. Telefonnummern werden auf E.164 normalisiert, LinkedIn-URLs zu Handles extrahiert, Unternehmen werden automatisch erstellt, falls sie nicht existieren. --email, --phone, --company, --tag und --set sind alle wiederholbar.
Social-Handle-Flags: --linkedin, --x, --bluesky, --telegram. Alle akzeptieren rohe Handles oder vollständige URLs.
Kontakte auflisten
crm contact list
crm contact list --tag hot-lead --company "Acme Corp"
crm contact list --filter "title~=CTO AND company=Acme" --sort name --limit 20
crm contact list --format json | jq '.[].name'
Filter-Operatoren: =, !=, ~= (enthält), >, <. Kombinieren mit AND / OR.
Kontakt anzeigen
Nachschlagen per ID, E-Mail, Telefon oder Social-Handle:
crm contact show ct_01J8ZVXB3K...
crm contact show [email protected]
crm contact show "+12125551234"
crm contact show janedoe # LinkedIn-Handle
Kontakt bearbeiten
crm contact edit [email protected] --name "Jane Smith"
crm contact edit "+12125551234" --add-email [email protected] --rm-tag old-tag
crm contact edit janedoe --add-company "New Corp" --set title=CEO --unset source
Hinzufügen/Entfernen-Flags: --add-email, --rm-email, --add-phone, --rm-phone, --add-company, --rm-company, --add-tag, --rm-tag. Social-Handles werden direkt gesetzt: --linkedin, --x, --bluesky, --telegram.
Kontakt löschen
crm contact rm [email protected]
crm contact rm "+12125551234" --force # Bestätigung überspringen
crm contact rm janedoe # per Social-Handle
Kontakte zusammenführen
Zwei Kontakte zu einem zusammenführen. Der erste Kontakt bleibt bestehen, der zweite wird absorbiert und gelöscht. Akzeptiert jeden Referenztyp:
crm contact merge ct_01A... ct_01B...
crm contact merge [email protected] [email protected]
crm contact merge "+12125551234" "+14155559876"
crm contact merge janedoe jane-doe-linkedin
Kombiniert E-Mails, Telefonnummern, Unternehmen, Tags, benutzerdefinierte Felder und verknüpft alle Deals und Aktivitäten neu.
Unternehmen
Unternehmen erstellen
crm company add --name "Acme Corp" \
--website acme.com \
--phone "+1-800-555-0000" \
--tag enterprise \
--set industry=SaaS
--website, --phone, --tag, --set sind wiederholbar.
Auflisten / Anzeigen / Bearbeiten / Löschen
crm company list --tag enterprise
crm company show acme.com # per Website
crm company show "+18005550000" # per Telefon
crm company edit acme.com --name "Acme Inc" --add-website acme.io
crm company rm acme.com --force
Unternehmen zusammenführen
crm company merge co_01A... co_01B...
crm company merge acme.com acme.io
crm company merge "+18005550000" "+18005550001"
Verknüpft alle Kontakte und Deals vom zweiten zum ersten.
Deals
Deal erstellen
crm deal add --title "Acme Enterprise" \
--value 50000 \
--stage qualified \
--contact [email protected] \
--company acme.com \
--expected-close 2026-06-15 \
--probability 60 \
--tag enterprise
Kontakte und Unternehmen werden automatisch erstellt, falls sie nicht existieren. --contact und --tag sind wiederholbar.
Deals auflisten
crm deal list --stage qualified --min-value 10000
crm deal list --contact [email protected] --sort value --reverse
crm deal list --format ids | wc -l # Deals zählen
Deal durch die Pipeline bewegen
crm deal move dl_01... --stage proposal --note "Preisgestaltung gesendet"
crm deal move dl_01... --stage closed-won --note "2-Jahres-Vertrag unterschrieben"
Stufenübergänge werden als Aktivität mit Zeitstempeln aufgezeichnet. Verwende deal move, nicht deal edit --stage.
Bearbeiten / Löschen
crm deal edit dl_01... --value 75000 --add-contact [email protected] --probability 80
crm deal rm dl_01... --force
Pipeline-Übersicht
crm pipeline
Zeigt Anzahl, Gesamtwert und gewichteten Wert pro Stufe.
Aktivitätsprotokollierung
Aktivität protokollieren
crm log note "Mit Jane Kaffee getrunken, Q3-Expansion besprochen" --contact [email protected]
crm log call "Produkt vorgeführt, sie wünscht ein Angebot" --contact [email protected] --deal dl_01...
crm log meeting "Quartalsüberprüfung" --company acme.com --at 2026-04-01
crm log email "Follow-up mit Preisen gesendet" --contact [email protected] --set channel=outbound
Typen: note, call, meeting, email. Kontakte und Unternehmen werden automatisch erstellt. --contact ist wiederholbar. --at überschreibt den Zeitstempel.
Aktivitäten auflisten
crm activity list --contact [email protected] --since 2026-01-01
crm activity list --type call --limit 10
crm activity list --deal dl_01... --format json
Tags
crm tag [email protected] hot-lead enterprise # Tags hinzufügen
crm untag [email protected] old-tag # Tags entfernen
crm tag list # Alle Tags mit Zählwerten
crm tag list --type contact # Nur Kontakt-Tags
Tags funktionieren für Kontakte, Unternehmen und Deals.
Suche
Exakte Stichwortsuche (FTS5)
crm search "acme CTO"
crm search "jane" --type contact
Fuzzy / Semantische Suche
crm find "Fintech-Startup London"
crm find "diesen CTO, den ich auf der Konferenz getroffen habe" --limit 5 --threshold 0.3
Suchindex neu aufbauen
crm index rebuild
crm index status
Der Index wird automatisch bei Schreibvorgängen aktualisiert. Ein manueller Wiederaufbau ist nur nach Korruption erforderlich.
Duplikaterkennung
crm dupes
crm dupes --type contact --threshold 0.5
crm dupes --type company --limit 20
Verwendet kombinierte Levenshtein-Dice-Koeffizient-Ähnlichkeit. Erkennt: ähnliche Namen, gemeinsame E-Mails, gemeinsame Telefonnummern, gemeinsame Websites, gemeinsame Social-Handles. Überprüfen und dann zusammenführen:
crm dupes --type contact
# → Jane Doe ↔ J. Doe: ähnlicher Name, gemeinsame E-Mail
crm contact merge ct_01A... ct_01B...
Berichte
crm report pipeline # Stufenzählwerte und -werte
crm report activity --period 30d --by type # Aktivitätsvolumen
crm report stale --days 14 --type contact # Keine aktuelle Aktivität
crm report conversion --since 2026-01-01 # Stufendurchlaufraten
crm report velocity --won-only # Zeit pro Stufe
crm report forecast --period 2026-Q2 # Gewichtete Prognose
crm report won --period 90d # Zusammenfassung abgeschlossene Gewinne
crm report lost --period 90d # Zusammenfassung abgeschlossene Verluste
Import / Export
Import aus CSV oder JSON
crm import contacts leads.csv
crm import contacts leads.json --update # Vorhandene per E-Mail-Übereinstimmung aktualisieren
crm import companies companies.csv --dry-run
crm import deals deals.csv --skip-errors
cat data.json | crm import contacts - # Import aus stdin
CSV-Header: name, email/emails, phone/phones, company/companies, tags, linkedin, x, bluesky, telegram. Nicht erkannte Spalten werden zu benutzerdefinierten Feldern.
Export
crm export contacts --format csv > contacts.csv
crm export companies --format json > companies.json
crm export deals --format tsv
crm export all --format json > full-backup.json
Virtuelles Dateisystem (Mount)
Mounte das CRM als lebendiges Lese-/Schreib-Dateisystem. Jedes Tool, das Dateien liest, erhält vollen CRM-Zugriff – KI-Agenten, grep, jq, vim, Skripte.
Mounten
crm mount ~/crm
crm mount ~/crm --readonly
Unter Linux verwendet dies FUSE. Unter macOS wird ein NFS v3-Server verwendet (keine Kernel-Erweiterungen erforderlich).
Dateisystemstruktur
~/crm/
├── llm.txt # Anleitungen für KI-Agenten
├── contacts/
│ ├── ct_01...jane-doe.json # Kontakt-JSON-Dateien
│ ├── _by-email/ # Nachschlagen per E-Mail
│ ├── _by-phone/ # Nachschlagen per E.164-Telefon
│ ├── _by-linkedin/ # Nachschlagen per LinkedIn-Handle
│ ├── _by-x/ # Nachschlagen per X-Handle
│ ├── _by-company/ # Gruppiert nach Unternehmen
│ └── _by-tag/ # Gruppiert nach Tag
├── companies/
│ ├── co_01...acme-corp.json
│ ├── _by-website/
│ ├── _by-phone/
│ └── _by-tag/
├── deals/
│ ├── dl_01...acme-enterprise.json
│ ├── _by-stage/
│ ├── _by-company/
│ └── _by-tag/
├── activities/
│ ├── _by-contact/
│ ├── _by-company/
│ ├── _by-deal/
│ └── _by-type/
├── reports/ # Vorberechnete Analysen
│ ├── pipeline.json
│ ├── forecast.json
│ ├── stale.json
│ ├── conversion.json
│ ├── velocity.json
│ ├── won.json
│ └── lost.json
├── pipeline.json # Schnelle Pipeline-Übersicht
├── tags.json # Alle Tags mit Zählwerten
└── search/ # Suche durch Lesen von Dateien
└── <query>.json # cat search/"acme CTO".json
Über das Dateisystem lesen
ls ~/crm/contacts/
cat ~/crm/contacts/ct_01...jane-doe.json | jq .
cat ~/crm/contacts/_by-email/[email protected]
cat ~/crm/deals/_by-stage/qualified/
cat ~/crm/reports/forecast.json
cat ~/crm/search/"enterprise deals".json
Über das Dateisystem schreiben
# Einen Kontakt erstellen
echo '{"name":"Bob Smith","emails":["[email protected]"]}' > ~/crm/contacts/new.json
# Aktualisieren (lesen → ändern → zurückschreiben)
cat ~/crm/contacts/ct_01...jane-doe.json | jq '.tags += ["vip"]' > ~/crm/contacts/ct_01...jane-doe.json
# Löschen
rm ~/crm/contacts/ct_01...jane-doe.json
Aushängen
crm unmount ~/crm
Statischer Export (kein Mount erforderlich)
crm export-fs ./crm-snapshot
Exportiert dieselbe Verzeichnisstruktur als statische Kopie – nützlich in Containern oder Sandboxes, wo FUSE nicht verfügbar ist.
Bulk-Operationen
Verwende --format ids zur Weiterleitung in andere Befehle:
# Alle Kontakte von Acme als enterprise taggen
crm contact list --company "Acme Corp" --format ids | xargs -I{} crm tag {} enterprise
# Alle qualifizierten Deals über 50.000 $ nach proposal verschieben
crm deal list --stage qualified --min-value 50000 --format ids | \
xargs -I{} crm deal move {} --stage proposal
# Alle veralteten Kontakte löschen
crm report stale --days 90 --type contact --format ids | xargs -I{} crm contact rm {} --force
Benutzerdefinierte Felder
Alle Entitäten unterstützen beliebige Schlüssel-Wert-Felder:
crm contact add --name "Jane" --set title=CTO --set source=conference
crm contact edit [email protected] --set "json:score=85" --set "json:verified=true"
crm contact edit [email protected] --unset source
crm contact list --filter "title~=CTO"
Präfix mit json: für typisierte Werte (Zahlen, Booleans, Arrays).
Hooks
Konfiguriere Shell-Hooks in crm.toml, die bei Mutationen ausgelöst werden:
[hooks]
post-contact-add = "~/.crm/hooks/notify-slack.sh"
post-deal-stage-change = "~/.crm/hooks/deal-moved.sh"
pre-contact-rm = "~/.crm/hooks/confirm-delete.sh"
Entitätsdaten werden als JSON über stdin übergeben. Pre-Hooks brechen bei einem Exit-Code ungleich Null ab.
Verfügbare Hooks: {pre,post}-{contact,company,deal}-{add,edit,rm}, {pre,post}-deal-stage-change, {pre,post}-activity-add.
Tipps für KI-Agenten
- Zuerst mounten:
crm mount ~/crmgibt dir Dateisystemzugriff – lies JSON-Dateien direkt anstatt CLI-Befehle auszuführen llm.txtlesen: Die Mount-Point enthältllm.txtmit Strukturdokumentation und Tipps_by-*-Verzeichnisse verwenden für schnelles Nachschlagen:_by-email,_by-phone,_by-linkedin,_by-tag,_by-stage--format jsonverwenden für alle CLI-Ausgaben bei programmatischer Verarbeitung--format ids+xargsfür Bulk-Operationen verwendenreports/lesen für vorberechnete Analysen – nicht aus Rohdaten neu berechnen- Suche über das Dateisystem:
cat ~/crm/search/"deine Anfrage".json - Schreiben über das Dateisystem: Erstelle/aktualisiere Entitäten durch Schreiben von JSON-Dateien
- Alle JSON-Dateien sind in sich abgeschlossen – kein Zusammenführen über Dateien hinweg erforderlich
- Telefonnummern akzeptieren jedes Format bei der Eingabe; intern als E.164 gespeichert
- Social-Handles akzeptieren vollständige URLs; als saubere Handles gespeichert