Communitygithub.com

dzhng/crm.cli

管理聯絡人、公司、交易與銷售管道,使用 crm.cli —— 一個以 SQLite 為基礎、無頭式 CLI 優先的 CRM,並提供虛擬檔案系統介面。

crm.cli 是什麼?

crm.cli 是一個專為開發者與 AI 代理設計的 CLI 優先 CRM,以單一 SQLite 檔案儲存聯絡人、公司、交易與銷售管道。其設計核心在於與 Unix 工具鏈的無縫整合,並支援將 CRM 資料掛載為虛擬檔案系統,讓任何可讀取檔案的程式(如 grep、jq、vim)都能直接存取。此技能提供完整的 CRUD 操作、活動日誌記錄、標籤管理、模糊與語意搜尋、重複資料偵測、報告分析以及 CSV/JSON 匯入匯出功能。它特別適合在 Claude Code、Cursor、Codex 等 AI 代理環境中使用——代理可以透過掛載檔案系統直接讀取 JSON 檔案進行查詢,或寫入 JSON 檔案來新增/修改資料,從而減少 CLI 指令呼叫次數,提升工作效率。此外,它支援 FUSE(Linux)與 NFS(macOS)掛載,以及靜態匯出功能,確保在容器或沙箱環境中也能正常運作。

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

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

crm.cli 是做什麼的?

一個無頭、CLI 優先的 CRM。聯絡人、交易與銷售管道全部存放在單一 SQLite 檔案中——可從終端機查詢、可與 Unix 工具鏈組合、可掛載為虛擬檔案系統。

安裝

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

這會將預編譯的二進位檔下載至 ~/.local/bin,並安裝掛載相依套件(Linux 上為 FUSE,macOS 上透過 Rust 工具鏈安裝 NFS)。

安裝後,請確認 ~/.local/bin 已加入你的 PATH:

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

驗證安裝:

crm --version

組態設定

選擇性。在專案根目錄或 ~/.crm/config.toml 建立 crm.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"

組態會自動從目前目錄往上搜尋。可使用 --config <path> 或 CRM_CONFIG 環境變數覆蓋。

全域旗標

每個指令都接受:

  • --db <path> — SQLite 資料庫路徑(預設:~/.crm/crm.db,環境變數:CRM_DB)
  • --format <fmt> — 輸出格式:table、json、csv、tsv、ids
  • --config <path> — TOML 組態檔案路徑
  • --no-color — 停用彩色輸出

聯絡人

建立聯絡人

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

除了 --name 外,所有旗標皆為選填。電話號碼會正規化為 E.164 格式,LinkedIn URL 會擷取為使用者名稱,公司若不存在則會自動建立。--email、--phone、--company、--tag 與 --set 均可重複使用。

社交帳號旗標:--linkedin、--x、--bluesky、--telegram。可接受原始使用者名稱或完整 URL。

列出聯絡人

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'

篩選運算子:=、!=、~=(包含)、>、<。可使用 AND / OR 組合。

顯示聯絡人

透過 ID、Email、電話或社交帳號查詢:

crm contact show ct_01J8ZVXB3K...
crm contact show [email protected]
crm contact show "+12125551234"
crm contact show janedoe          # LinkedIn 使用者名稱

編輯聯絡人

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

新增/移除旗標:--add-email、--rm-email、--add-phone、--rm-phone、--add-company、--rm-company、--add-tag、--rm-tag。社交帳號直接設定:--linkedin、--x、--bluesky、--telegram。

刪除聯絡人

crm contact rm [email protected]
crm contact rm "+12125551234" --force    # 跳過確認
crm contact rm janedoe                   # 依社交帳號

合併聯絡人

將兩個聯絡人合併為一個。第一個聯絡人保留,第二個被吸收並刪除。可接受任何參照類型:

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

會合併 Email、電話、公司、標籤、自訂欄位,並重新連結所有交易與活動。

公司

建立公司

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

--website、--phone、--tag、--set 均可重複使用。

列出 / 顯示 / 編輯 / 刪除

crm company list --tag enterprise
crm company show acme.com                        # 依網站
crm company show "+18005550000"                  # 依電話
crm company edit acme.com --name "Acme Inc" --add-website acme.io
crm company rm acme.com --force

合併公司

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

將第二家公司的所有聯絡人與交易重新連結至第一家。

交易

建立交易

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

若聯絡人或公司不存在,會自動建立。--contact 與 --tag 可重複使用。

列出交易

crm deal list --stage qualified --min-value 10000
crm deal list --contact [email protected] --sort value --reverse
crm deal list --format ids | wc -l    # 計算交易數量

在銷售管道中移動交易

crm deal move dl_01... --stage proposal --note "已寄出報價單"
crm deal move dl_01... --stage closed-won --note "已簽署兩年合約"

階段轉換會記錄為活動(含時間戳記)。請使用 deal move,而非 deal edit --stage。

編輯 / 刪除

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

銷售管道概覽

crm pipeline

顯示每個階段的數量、總值與加權值。

活動記錄

記錄活動

crm log note "與 Jane 喝咖啡,討論 Q3 擴展計畫" --contact [email protected]
crm log call "展示產品,她希望拿到報價" --contact [email protected] --deal dl_01...
crm log meeting "季度檢討" --company acme.com --at 2026-04-01
crm log email "寄出後續報價" --contact [email protected] --set channel=outbound

類型:note、call、meeting、email。聯絡人與公司會自動建立。--contact 可重複使用。--at 可覆蓋時間戳記。

列出活動

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

標籤

crm tag [email protected] hot-lead enterprise      # 新增標籤
crm untag [email protected] old-tag                 # 移除標籤
crm tag list                                     # 顯示所有標籤及其計數
crm tag list --type contact                      # 僅顯示聯絡人標籤

標籤適用於聯絡人、公司與交易。

搜尋

精確關鍵字搜尋(FTS5)

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

模糊 / 語意搜尋

crm find "倫敦金融科技新創"
crm find "我在會議上遇到的那位 CTO" --limit 5 --threshold 0.3

重建搜尋索引

crm index rebuild
crm index status

索引會在寫入時自動更新。只在索引損毀時才需要手動重建。

重複資料偵測

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

使用 Levenshtein + Dice 係數結合的相似度比對。可偵測:相似名稱、共用 Email、共用電話、共用網站、共用社交帳號。檢視後進行合併:

crm dupes --type contact
# → Jane Doe ↔ J. Doe:名稱相似,共用 Email
crm contact merge ct_01A... ct_01B...

報告

crm report pipeline                                  # 階段數量與金額
crm report activity --period 30d --by type           # 活動量
crm report stale --days 14 --type contact            # 近期無活動
crm report conversion --since 2026-01-01             # 階段轉換率
crm report velocity --won-only                       # 每階段平均停留時間
crm report forecast --period 2026-Q2                 # 加權預測
crm report won --period 90d                          # 已成交總結
crm report lost --period 90d                         # 已失單總結

匯入 / 匯出

從 CSV 或 JSON 匯入

crm import contacts leads.csv
crm import contacts leads.json --update     # 依 Email 比對更新現有資料
crm import companies companies.csv --dry-run
crm import deals deals.csv --skip-errors
cat data.json | crm import contacts -        # 從標準輸入匯入

CSV 標頭:name、email/emails、phone/phones、company/companies、tags、linkedin、x、bluesky、telegram。無法辨識的欄位會成為自訂欄位。

匯出

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

虛擬檔案系統(掛載)

將 CRM 掛載為一個即時的讀寫檔案系統。任何能讀取檔案的工具都將取得完整的 CRM 存取權限——AI 代理、grep、jq、vim、指令稿等。

掛載

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

在 Linux 上使用 FUSE。在 macOS 上使用 NFS v3 伺服器(無需核心擴充套件)。

檔案系統結構

~/crm/
├── llm.txt                           # 提供 AI 代理的操作說明
├── contacts/
│   ├── ct_01...jane-doe.json         # 聯絡人 JSON 檔案
│   ├── _by-email/                    # 依 Email 查詢
│   ├── _by-phone/                    # 依 E.164 電話查詢
│   ├── _by-linkedin/                 # 依 LinkedIn 使用者名稱查詢
│   ├── _by-x/                        # 依 X 使用者名稱查詢
│   ├── _by-company/                  # 依公司分組
│   └── _by-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/                          # 預先計算的分析報告
│   ├── pipeline.json
│   ├── forecast.json
│   ├── stale.json
│   ├── conversion.json
│   ├── velocity.json
│   ├── won.json
│   └── lost.json
├── pipeline.json                     # 快速銷售管道概覽
├── tags.json                         # 所有標籤及其計數
└── search/                           # 透過讀取檔案進行搜尋
    └── <query>.json                  # cat search/"acme CTO".json

透過檔案系統讀取

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

透過檔案系統寫入

# 建立聯絡人
echo '{"name":"Bob Smith","emails":["[email protected]"]}' > ~/crm/contacts/new.json

# 更新(讀取 → 修改 → 寫回)
cat ~/crm/contacts/ct_01...jane-doe.json | jq '.tags += ["vip"]' > ~/crm/contacts/ct_01...jane-doe.json

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

卸載

crm unmount ~/crm

靜態匯出(無需掛載)

crm export-fs ./crm-snapshot

將相同目錄結構匯出為靜態副本——適合在容器或沙箱等無法使用 FUSE 的環境中使用。

批次操作

使用 --format ids 將輸出傳遞給其他指令:

# 為所有 Acme 的聯絡人加上 enterprise 標籤
crm contact list --company "Acme Corp" --format ids | xargs -I{} crm tag {} enterprise

# 將所有 qualified 階段且金額超過 $50k 的交易移至 proposal 階段
crm deal list --stage qualified --min-value 50000 --format ids | \
  xargs -I{} crm deal move {} --stage proposal

# 刪除所有久未聯繫的聯絡人
crm report stale --days 90 --type contact --format ids | xargs -I{} crm contact rm {} --force

自訂欄位

所有實體都支援任意的鍵值對欄位:

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"

使用 json: 前綴來設定帶有型別的值(數字、布林值、陣列)。

鉤子

在 crm.toml 中設定當資料變更時觸發的 shell 鉤子:

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

實體資料會以 JSON 格式透過標準輸入傳遞。前置鉤子若回傳非零值則會中止操作。

可用的鉤子:{pre,post}-{contact,company,deal}-{add,edit,rm}、{pre,post}-deal-stage-change、{pre,post}-activity-add。

給 AI 代理的提示

  • 先掛載: crm mount ~/crm 可讓你直接透過檔案系統存取——直接讀取 JSON 檔案,無需執行 CLI 指令
  • 閱讀 llm.txt: 掛載點內含 llm.txt,提供結構文件與使用技巧
  • 使用 _by-* 目錄 進行快速查詢:_by-email、_by-phone、_by-linkedin、_by-tag、_by-stage
  • 進行程式化處理時,所有 CLI 輸出都使用 --format json
  • 使用 --format ids + xargs 進行批次操作
  • 讀取 reports/ 取得預先計算的分析報告——不要從原始資料重新計算
  • 透過檔案系統搜尋: cat ~/crm/search/"your query".json
  • 透過檔案系統寫入: 直接寫入 JSON 檔案來新增/更新實體
  • 所有 JSON 檔案都是自包含的——無需跨檔案關聯
  • 電話號碼 輸入時接受任何格式;內部儲存為 E.164
  • 社交帳號 接受完整 URL;內部儲存為純使用者名稱

相關技能