Communitygithub.com

crm.cli

Gérez contacts, entreprises, affaires et pipeline avec crm.cli — un CRM headless orienté CLI reposant sur SQLite avec une interface de système de fichiers virtuel.

Qu'est-ce que crm.cli ?

crm.cli est un CRM headless, orienté CLI, conçu pour les développeurs et les agents IA. Il stocke contacts, affaires et pipeline dans un seul fichier SQLite, interrogeable depuis le terminal, composable avec les outils Unix et montable en tant que système de fichiers virtuel. Cette conception permet aux agents IA (comme Claude Code, Cursor, Codex, et autres) d'accéder aux données CRM par lecture/écriture de fichiers JSON, offrant une intégration fluide sans dépendre d'API REST. Le système supporte les recherches riches (texte intégral FTS5, fuzzy/sémantique), la détection de doublons, l'import/export CSV/JSON, des rapports de pipeline, le logging d'activités, des champs personnalisés et des hooks shell configurables. Il est multiplateforme (Linux via FUSE, macOS via serveur NFS) et optimisé pour les opérations en bloc via `--format ids`. crm.cli s'installe via un script shell unique et se configure via un fichier TOML, le rendant idéal pour les workflows CLI, les pipelines CI/CD et les environnements d'agents IA nécessitant un CRM léger et automatisable.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/dzhng/crm.cli/tree/HEAD/skills

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Que fait crm.cli ?

Un CRM headless, orienté CLI. Contacts, affaires et pipeline dans un seul fichier SQLite — interrogeable depuis votre terminal, composable avec les outils Unix et montable en tant que système de fichiers virtuel.

Installation

curl -fsSL https://raw.githubusercontent.com/dzhng/crm.cli/main/install.sh | sh

Cela télécharge le binaire précompilé dans ~/.local/bin et installe les dépendances de montage (FUSE sur Linux, chaîne d'outils Rust sur macOS pour NFS).

Après installation, assurez-vous que ~/.local/bin est dans votre PATH :

export PATH="$HOME/.local/bin:$PATH"

Vérifiez :

crm --version

Configuration

Optionnelle. Créez crm.toml dans la racine de votre projet ou dans ~/.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"

La configuration est auto-découverte en remontant depuis le répertoire courant. Remplacez-la avec --config <chemin> ou la variable d'environnement CRM_CONFIG.

Indicateurs globaux

Chaque commande accepte :

  • --db <chemin> — Chemin de la base de données SQLite (par défaut : ~/.crm/crm.db, env : CRM_DB)
  • --format <fmt> — Format de sortie : table, json, csv, tsv, ids
  • --config <chemin> — Chemin du fichier de configuration TOML
  • --no-color — Désactive la sortie colorée

Contacts

Créer un contact

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

Tous les indicateurs sont optionnels sauf --name. Les téléphones sont normalisés au format E.164, les URLs LinkedIn sont extraites en identifiants, les entreprises sont créées automatiquement si elles n'existent pas. --email, --phone, --company, --tag et --set sont tous répétables.

Indicateurs de réseaux sociaux : --linkedin, --x, --bluesky, --telegram. Tous acceptent les identifiants bruts ou les URLs complètes.

Lister les contacts

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'

Opérateurs de filtre : =, !=, ~= (contient), >, <. Combinez avec AND / OR.

Afficher un contact

Recherche par ID, email, téléphone ou identifiant social :

crm contact show ct_01J8ZVXB3K...
crm contact show [email protected]
crm contact show "+12125551234"
crm contact show janedoe          # Identifiant LinkedIn

Modifier un contact

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

Indicateurs d'ajout/suppression : --add-email, --rm-email, --add-phone, --rm-phone, --add-company, --rm-company, --add-tag, --rm-tag. Les identifiants sociaux se définissent directement : --linkedin, --x, --bluesky, --telegram.

Supprimer un contact

crm contact rm [email protected]
crm contact rm "+12125551234" --force    # Ignorer la confirmation
crm contact rm janedoe                   # Par identifiant social

Fusionner des contacts

Fusionne deux contacts en un seul. Le premier contact survit, le second est absorbé et supprimé. Accepte tout type de référence :

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

Combine les emails, téléphones, entreprises, étiquettes, champs personnalisés, et relie toutes les affaires et activités.

Entreprises

Créer une entreprise

crm company add --name "Acme Corp" \
  --website acme.com \
  --phone "+1-800-555-0000" \
  --tag enterprise \
  --set industry=SaaS

--website, --phone, --tag, --set sont répétables.

Lister / afficher / modifier / supprimer

crm company list --tag enterprise
crm company show acme.com                        # Par site web
crm company show "+18005550000"                  # Par téléphone
crm company edit acme.com --name "Acme Inc" --add-website acme.io
crm company rm acme.com --force

Fusionner des entreprises

crm company merge co_01A... co_01B...
crm company merge acme.com acme.io
crm company merge "+18005550000" "+18005550001"

Relie tous les contacts et affaires de la seconde à la première.

Affaires

Créer une affaire

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

Les contacts et entreprises sont créés automatiquement s'ils n'existent pas. --contact et --tag sont répétables.

Lister les affaires

crm deal list --stage qualified --min-value 10000
crm deal list --contact [email protected] --sort value --reverse
crm deal list --format ids | wc -l    # Compter les affaires

Avancer une affaire dans le pipeline

crm deal move dl_01... --stage proposal --note "Devis envoyé"
crm deal move dl_01... --stage closed-won --note "Contrat 2 ans signé"

Les transitions d'étape sont enregistrées comme activités avec horodatage. Utilisez deal move, pas deal edit --stage.

Modifier / supprimer

crm deal edit dl_01... --value 75000 --add-contact [email protected] --probability 80
crm deal rm dl_01... --force

Aperçu du pipeline

crm pipeline

Affiche le nombre, la valeur totale et la valeur pondérée par étape.

Journalisation des activités

Enregistrer une activité

crm log note "Café avec Jane, discussion sur l'expansion Q3" --contact [email protected]
crm log call "Démo du produit, elle veut une proposition" --contact [email protected] --deal dl_01...
crm log meeting "Revue trimestrielle" --company acme.com --at 2026-04-01
crm log email "Suivi des prix envoyé" --contact [email protected] --set channel=outbound

Types : note, call, meeting, email. Les contacts et entreprises sont créés automatiquement. --contact est répétable. --at remplace l'horodatage.

Lister les activités

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

Étiquettes

crm tag [email protected] hot-lead enterprise      # Ajouter des étiquettes
crm untag [email protected] old-tag                 # Supprimer des étiquettes
crm tag list                                     # Toutes les étiquettes avec compteurs
crm tag list --type contact                      # Étiquettes de contacts uniquement

Les étiquettes fonctionnent sur les contacts, entreprises et affaires.

Recherche

Recherche exacte par mot-clé (FTS5)

crm search "acme CTO"
crm search "jane" --type contact

Recherche floue / sémantique

crm find "fintech startup London"
crm find "ce CTO que j'ai rencontré à la conférence" --limit 5 --threshold 0.3

Reconstruire l'index de recherche

crm index rebuild
crm index status

L'index se met à jour automatiquement lors des écritures. Reconstruire manuellement uniquement après corruption.

Détection des doublons

crm dupes
crm dupes --type contact --threshold 0.5
crm dupes --type company --limit 20

Utilise la similarité combinée Levenshtein + coefficient de Dice. Détecte : noms similaires, emails partagés, téléphones partagés, sites web partagés, identifiants sociaux partagés. Examinez puis fusionnez :

crm dupes --type contact
# → Jane Doe ↔ J. Doe : nom similaire, email partagé
crm contact merge ct_01A... ct_01B...

Rapports

crm report pipeline                                  # Comptes et valeurs par étape
crm report activity --period 30d --by type           # Volume d'activité
crm report stale --days 14 --type contact            # Aucune activité récente
crm report conversion --since 2026-01-01             # Taux étape par étape
crm report velocity --won-only                       # Temps par étape
crm report forecast --period 2026-Q2                 # Prévision pondérée
crm report won --period 90d                          # Résumé des clôtures gagnées
crm report lost --period 90d                         # Résumé des clôtures perdues

Import / Export

Importer depuis CSV ou JSON

crm import contacts leads.csv
crm import contacts leads.json --update     # Mettre à jour par correspondance email
crm import companies companies.csv --dry-run
crm import deals deals.csv --skip-errors
cat data.json | crm import contacts -        # Importer depuis stdin

En-têtes CSV : name, email/emails, phone/phones, company/companies, tags, linkedin, x, bluesky, telegram. Les colonnes non reconnues deviennent des champs personnalisés.

Exporter

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

Système de fichiers virtuel (Montage)

Montez le CRM en tant que système de fichiers actif en lecture/écriture. Tout outil lisant des fichiers obtient un accès complet au CRM — agents IA, grep, jq, vim, scripts.

Monter

crm mount ~/crm
crm mount ~/crm --readonly

Sur Linux, ceci utilise FUSE. Sur macOS, ceci utilise un serveur NFS v3 (aucune extension noyau nécessaire).

Structure du système de fichiers

~/crm/
├── llm.txt                           # Instructions pour les agents IA
├── contacts/
│   ├── ct_01...jane-doe.json         # Fichiers JSON des contacts
│   ├── _by-email/                    # Recherche par email
│   ├── _by-phone/                    # Recherche par téléphone E.164
│   ├── _by-linkedin/                 # Recherche par identifiant LinkedIn
│   ├── _by-x/                        # Recherche par identifiant X
│   ├── _by-company/                  # Regroupés par entreprise
│   └── _by-tag/                      # Regroupés par étiquette
├── 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/                          # Analyses pré-calculées
│   ├── pipeline.json
│   ├── forecast.json
│   ├── stale.json
│   ├── conversion.json
│   ├── velocity.json
│   ├── won.json
│   └── lost.json
├── pipeline.json                     # Aperçu rapide du pipeline
├── tags.json                         # Toutes les étiquettes avec compteurs
└── search/                           # Recherche en lisant des fichiers
    └── <requete>.json                  # cat search/"acme CTO".json

Lire via le système de fichiers

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

Écrire via le système de fichiers

# Créer un contact
echo '{"name":"Bob Smith","emails":["[email protected]"]}' > ~/crm/contacts/new.json

# Mettre à jour (lire → modifier → réécrire)
cat ~/crm/contacts/ct_01...jane-doe.json | jq '.tags += ["vip"]' > ~/crm/contacts/ct_01...jane-doe.json

# Supprimer
rm ~/crm/contacts/ct_01...jane-doe.json

Démontage

crm unmount ~/crm

Export statique (sans montage)

crm export-fs ./crm-snapshot

Exporte la même structure de répertoires en copie statique — utile dans les conteneurs ou environnements sandbox où FUSE n'est pas disponible.

Opérations en bloc

Utilisez --format ids pour chaîner avec d'autres commandes :

# Étiqueter tous les contacts d'Acme comme enterprise
crm contact list --company "Acme Corp" --format ids | xargs -I{} crm tag {} enterprise

# Déplacer toutes les affaires qualifiées à plus de 50k$ vers proposition
crm deal list --stage qualified --min-value 50000 --format ids | \
  xargs -I{} crm deal move {} --stage proposal

# Supprimer tous les contacts inactifs
crm report stale --days 90 --type contact --format ids | xargs -I{} crm contact rm {} --force

Champs personnalisés

Toutes les entités supportent des champs clé-valeur arbitraires :

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éfixez avec json: pour des valeurs typées (nombres, booléens, tableaux).

Hooks

Configurez des hooks shell dans crm.toml qui se déclenchent lors des mutations :

[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"

Les données d'entité sont passées en JSON sur stdin. Les pré-hooks interrompent l'opération en cas de sortie non nulle.

Hooks disponibles : {pre,post}-{contact,company,deal}-{add,edit,rm}, {pre,post}-deal-stage-change, {pre,post}-activity-add.

Conseils pour les agents IA

  • Montez d'abord : crm mount ~/crm vous donne un accès au système de fichiers — lisez directement les fichiers JSON au lieu d'exécuter des commandes CLI
  • Lisez llm.txt : Le point de montage contient llm.txt avec la documentation de la structure et des astuces
  • Utilisez les répertoires _by-* pour des recherches rapides : _by-email, _by-phone, _by-linkedin, _by-tag, _by-stage
  • Utilisez --format json pour toutes les sorties CLI lors d'un traitement programmatique
  • Utilisez --format ids + xargs pour les opérations en bloc
  • Lisez reports/ pour les analyses pré-calculées — ne recalculez pas à partir des données brutes
  • Recherchez via le système de fichiers : cat ~/crm/search/"votre requête".json
  • Écrivez via le système de fichiers : Créez/mettez à jour des entités en écrivant des fichiers JSON
  • Tous les fichiers JSON sont autonomes — pas besoin de faire des jointures entre fichiers
  • Les numéros de téléphone acceptent tout format en entrée ; stockés en E.164 en interne
  • Les identifiants sociaux acceptent les URLs complètes ; stockés en tant qu'identifiants propres

Skills associés