Communitygithub.com

crm.cli

Gerencie contatos, empresas, negócios e pipeline com crm.cli — um CRM headless, focado em CLI, com suporte a SQLite e interface de sistema de arquivos virtual.

O que é crm.cli?

O crm.cli é uma ferramenta de CRM headless e orientada a linha de comando, que armazena contatos, negócios e pipeline em um único arquivo SQLite. Sua principal vantagem é permitir consultas diretas do terminal, composição com ferramentas Unix e montagem como um sistema de arquivos virtual (FUSE no Linux ou NFS no macOS), o que facilita a integração com agentes de IA, scripts e editores. Compatível com busca textual (FTS5) e semântica fuzzy, detecção de duplicatas e hooks personalizados, ele oferece suporte a plataformas como Linux e macOS. Ideal para desenvolvedores que desejam automação, bulk operations e análises de pipeline diretamente no terminal, sem depender de interface gráfica.

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

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

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 ~/crm dá acesso ao sistema de arquivos — leia arquivos JSON diretamente em vez de executar comandos CLI
  • Leia llm.txt: O ponto de montagem contém llm.txt com 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 json para toda saída CLI ao processar programaticamente
  • Use --format ids + xargs para 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

Habilidades Relacionadas