O que crm.cli faz?
Um CRM headless, focado em CLI. Contatos, negócios e pipeline em um único arquivo SQLite — consultável pelo terminal, combinável com ferramentas Unix e montável como sistema de arquivos virtual.
Instalação
curl -fsSL https://raw.githubusercontent.com/dzhng/crm.cli/main/install.sh | sh
Isso baixa o binário pré-compilado para ~/.local/bin e instala dependências de montagem (FUSE no Linux, Rust toolchain no macOS para NFS).
Após a instalação, certifique-se de que ~/.local/bin está no seu PATH:
export PATH="$HOME/.local/bin:$PATH"
Verifique:
crm --version
Configuração
Opcional. Crie crm.toml na raiz do seu projeto ou em ~/.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"
A configuração é descoberta automaticamente subindo a partir do diretório atual. Substitua com --config <caminho> ou a variável de ambiente CRM_CONFIG.
Flags Globais
Todo comando aceita:
--db <caminho>— Caminho do banco SQLite (padrão:~/.crm/crm.db, env:CRM_DB)--format <formato>— Formato de saída:table,json,csv,tsv,ids--config <caminho>— Caminho do arquivo de configuração TOML--no-color— Desativa saída colorida
Contatos
Criar um contato
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
Todas as flags são opcionais, exceto --name. Telefones são normalizados para E.164, URLs do LinkedIn são extraídas para handles, empresas são criadas automaticamente se não existirem. --email, --phone, --company, --tag e --set são repetíveis.
Flags de redes sociais: --linkedin, --x, --bluesky, --telegram. Todas aceitam handles puros ou URLs completas.
Listar contatos
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'
Operadores de filtro: =, !=, ~= (contém), >, <. Combine com AND / OR.
Exibir um contato
Pesquise por ID, email, telefone ou handle de rede social:
crm contact show ct_01J8ZVXB3K...
crm contact show [email protected]
crm contact show "+12125551234"
crm contact show janedoe # Handle LinkedIn
Editar um contato
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
Flags de adicionar/remover: --add-email, --rm-email, --add-phone, --rm-phone, --add-company, --rm-company, --add-tag, --rm-tag. Handles de redes sociais são definidos diretamente: --linkedin, --x, --bluesky, --telegram.
Deletar um contato
crm contact rm [email protected]
crm contact rm "+12125551234" --force # pula confirmação
crm contact rm janedoe # por handle social
Mesclar contatos
Mescla dois contatos em um. O primeiro contato sobrevive, o segundo é absorvido e deletado. Aceita qualquer tipo de referência:
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
Combina emails, telefones, empresas, tags, campos personalizados e religa todos os negócios e atividades.
Empresas
Criar uma empresa
crm company add --name "Acme Corp" \
--website acme.com \
--phone "+1-800-555-0000" \
--tag enterprise \
--set industry=SaaS
--website, --phone, --tag, --set são repetíveis.
Listar / exibir / editar / deletar
crm company list --tag enterprise
crm company show acme.com # por website
crm company show "+18005550000" # por telefone
crm company edit acme.com --name "Acme Inc" --add-website acme.io
crm company rm acme.com --force
Mesclar empresas
crm company merge co_01A... co_01B...
crm company merge acme.com acme.io
crm company merge "+18005550000" "+18005550001"
Religa todos os contatos e negócios da segunda para a primeira.
Negócios
Criar um negócio
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
Contatos e empresas são criados automaticamente se não existirem. --contact e --tag são repetíveis.
Listar negócios
crm deal list --stage qualified --min-value 10000
crm deal list --contact [email protected] --sort value --reverse
crm deal list --format ids | wc -l # conta negócios
Mover um negócio pelo pipeline
crm deal move dl_01... --stage proposal --note "Enviado deck de preços"
crm deal move dl_01... --stage closed-won --note "Contrato de 2 anos assinado"
Transições de estágio são registradas como atividades com timestamps. Use deal move, não deal edit --stage.
Editar / deletar
crm deal edit dl_01... --value 75000 --add-contact [email protected] --probability 80
crm deal rm dl_01... --force
Visão geral do pipeline
crm pipeline
Mostra contagem, valor total e valor ponderado por estágio.
Registro de Atividades
Registrar uma atividade
crm log note "Tomei café com a Jane, discutimos expansão no Q3" --contact [email protected]
crm log call "Demonstrei o produto, ela quer uma proposta" --contact [email protected] --deal dl_01...
crm log meeting "Revisão trimestral" --company acme.com --at 2026-04-01
crm log email "Enviei follow-up de preços" --contact [email protected] --set channel=outbound
Tipos: note, call, meeting, email. Contatos e empresas são criados automaticamente. --contact é repetível. --at substitui o timestamp.
Listar atividades
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 # adicionar tags
crm untag [email protected] old-tag # remover tags
crm tag list # todas as tags com contagens
crm tag list --type contact # apenas tags de contato
Tags funcionam em contatos, empresas e negócios.
Pesquisa
Pesquisa exata por palavra-chave (FTS5)
crm search "acme CTO"
crm search "jane" --type contact
Pesquisa fuzzy / semântica
crm find "fintech startup Londres"
crm find "aquele CTO que conheci na conferência" --limit 5 --threshold 0.3
Reconstruir índice de pesquisa
crm index rebuild
crm index status
O índice é atualizado automaticamente nas escritas. Reconstrução manual só é necessária após corrupção.
Detecção de Duplicatas
crm dupes
crm dupes --type contact --threshold 0.5
crm dupes --type company --limit 20
Usa similaridade combinada de Levenshtein + coeficiente Dice. Detecta: nomes semelhantes, emails compartilhados, telefones compartilhados, websites compartilhados, handles sociais compartilhados. Revise e depois mescle:
crm dupes --type contact
# → Jane Doe ↔ J. Doe: nome semelhante, email compartilhado
crm contact merge ct_01A... ct_01B...
Relatórios
crm report pipeline # contagens e valores por estágio
crm report activity --period 30d --by type # volume de atividade
crm report stale --days 14 --type contact # sem atividade recente
crm report conversion --since 2026-01-01 # taxas estágio-a-estágio
crm report velocity --won-only # tempo por estágio
crm report forecast --period 2026-Q2 # previsão ponderada
crm report won --period 90d # resumo de fechados-ganhos
crm report lost --period 90d # resumo de fechados-perdidos
Importação / Exportação
Importar de CSV ou JSON
crm import contacts leads.csv
crm import contacts leads.json --update # atualizar existentes por correspondência de email
crm import companies companies.csv --dry-run
crm import deals deals.csv --skip-errors
cat data.json | crm import contacts - # importar do stdin
Cabeçalhos CSV: name, email/emails, phone/phones, company/companies, tags, linkedin, x, bluesky, telegram. Colunas não reconhecidas tornam-se campos personalizados.
Exportar
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
Sistema de Arquivos Virtual (Montagem)
Monte o CRM como um sistema de arquivos ao vivo de leitura/escrita. Qualquer ferramenta que lê arquivos obtém acesso completo ao CRM — agentes de IA, grep, jq, vim, scripts.
Montar
crm mount ~/crm
crm mount ~/crm --readonly
No Linux, isso usa FUSE. No macOS, usa um servidor NFS v3 (sem necessidade de extensões de kernel).
Estrutura do sistema de arquivos
~/crm/
├── llm.txt # Instruções para agentes de IA
├── contacts/
│ ├── ct_01...jane-doe.json # Arquivos JSON de contato
│ ├── _by-email/ # Pesquisa por email
│ ├── _by-phone/ # Pesquisa por telefone E.164
│ ├── _by-linkedin/ # Pesquisa por handle LinkedIn
│ ├── _by-x/ # Pesquisa por handle X
│ ├── _by-company/ # Agrupado por empresa
│ └── _by-tag/ # Agrupado por 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/ # Análises pré-calculadas
│ ├── pipeline.json
│ ├── forecast.json
│ ├── stale.json
│ ├── conversion.json
│ ├── velocity.json
│ ├── won.json
│ └── lost.json
├── pipeline.json # Visão rápida do pipeline
├── tags.json # Todas as tags com contagens
└── search/ # Pesquisa lendo arquivos
└── <query>.json # cat search/"acme CTO".json
Ler via sistema de arquivos
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
Escrever via sistema de arquivos
# Criar um contato
echo '{"name":"Bob Smith","emails":["[email protected]"]}' > ~/crm/contacts/new.json
# Atualizar (ler → modificar → escrever de volta)
cat ~/crm/contacts/ct_01...jane-doe.json | jq '.tags += ["vip"]' > ~/crm/contacts/ct_01...jane-doe.json
# Deletar
rm ~/crm/contacts/ct_01...jane-doe.json
Desmontar
crm unmount ~/crm
Exportação estática (sem necessidade de montagem)
crm export-fs ./crm-snapshot
Exporta a mesma estrutura de diretórios como cópia estática — útil em contêineres ou sandboxes onde FUSE não está disponível.
Operações em Lote
Use --format ids para canalizar para outros comandos:
# Marcar todos os contatos da Acme como enterprise
crm contact list --company "Acme Corp" --format ids | xargs -I{} crm tag {} enterprise
# Mover todos os negócios qualificados acima de $50k para proposal
crm deal list --stage qualified --min-value 50000 --format ids | \
xargs -I{} crm deal move {} --stage proposal
# Deletar todos os contatos antigos
crm report stale --days 90 --type contact --format ids | xargs -I{} crm contact rm {} --force
Campos Personalizados
Todas as entidades suportam campos chave-valor arbitrários:
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"
Prefixe com json: para valores tipados (números, booleanos, arrays).
Hooks
Configure hooks de shell no crm.toml que disparam em mutações:
[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"
Dados da entidade são passados como JSON no stdin. Pré-hooks abortam em saída não-zero.
Hooks disponíveis: {pre,post}-{contact,company,deal}-{add,edit,rm}, {pre,post}-deal-stage-change, {pre,post}-activity-add.
Dicas para Agentes de IA
- Monte primeiro:
crm mount ~/crmdá acesso ao sistema de arquivos — leia arquivos JSON diretamente em vez de executar comandos CLI - Leia
llm.txt: O ponto de montagem contémllm.txtcom documentação da estrutura e dicas - Use diretórios
_by-*para consultas rápidas:_by-email,_by-phone,_by-linkedin,_by-tag,_by-stage - Use
--format jsonpara toda saída CLI ao processar programaticamente - Use
--format ids+xargspara operações em lote - Leia
reports/para análises pré-calculadas — não recalcule a partir de dados brutos - Pesquise via sistema de arquivos:
cat ~/crm/search/"sua consulta".json - Escreva via sistema de arquivos: Crie/atualize entidades escrevendo arquivos JSON
- Todos os arquivos JSON são autocontidos — sem necessidade de junções entre arquivos
- Números de telefone aceitam qualquer formato na entrada; armazenados como E.164 internamente
- Handles de redes sociais aceitam URLs completas; armazenados como handles limpos