Skip to content

justinabrahms/frm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

frm

Maintain meaningful relationships -- a CLI personal CRM backed by CardDAV.

Single binary, no database -- your contacts live in your existing address book, interaction history in a local JSONL file. Built to be driven by AI agents.

Read the docs | Getting Started | Command Reference | Agent Integration

frm demo

Install

Download a prebuilt binary from Releases, or install with Go:

go install github.com/justinabrahms/frm@latest

Quick start

  1. frm init to connect your CardDAV server (iCloud, Fastmail, or custom)
  2. frm triage to categorize your contacts
  3. frm check to see who you're overdue to reach out to
  4. frm log "Alice" --note "caught up over coffee" after you talk to someone

Agent integration

frm is designed for AI agents to drive your relationship maintenance. Every command supports --json for structured output and --dry-run for safe previews.

# 1. Who needs attention?
frm check --json

# 2. Prep context before a meeting
frm context "Sarah Chen" --json

# 3. After the interaction, log it
frm log "Sarah Chen" --note "discussed Q2 roadmap"

# 4. Bulk-categorize new contacts
frm triage --json --limit -1
# then for each: frm track "<name>" --every 2w  OR  frm ignore "<name>"

See the Agent Integration Guide and SKILL.md for a complete reference.

Usage

frm list                           List tracked contacts with due dates
frm list --all                     Include untracked contacts
frm check                          Show overdue contacts
frm context "Alice"                Pre-meeting prep: summary + recent emails
frm log "Alice" --note "coffee"    Log an interaction
frm log "Alice" --when 2026-02-15  Backdate an interaction
frm triage                         Walk through untagged contacts interactively
frm triage --json                  List untriaged contacts as JSON (for agents)
frm track "Alice" --every 2w       Track Alice every 2 weeks
frm untrack "Alice"                Stop tracking
frm ignore "Alice"                 Permanently hide from triage and check
frm unignore "Alice"               Reverse an ignore
frm snooze "Alice" --until 2m      Temporarily suppress from check
frm unsnooze "Alice"               Remove a snooze
frm spread                         Preview staggered snoozes for new imports
frm spread --apply                 Apply the spread
frm add "Alice" --email a@b.com    Create a new contact
frm edit "Alice" --phone "555"     Update contact fields
frm history "Alice"                Show interaction log
frm stats                          Dashboard
frm group set "Alice" friends      Assign to a group
frm group unset "Alice"            Remove from group
frm group list                     List all groups
frm group members friends          List contacts in a group

All commands support --json for machine-readable output and --dry-run for previewing changes.

Duration format

  • 3d -- every 3 days
  • 2w -- every 2 weeks
  • 1m -- every month (30 days)

Setup

Create ~/.frm/config.json with at least one CardDAV service, or run frm init for the interactive wizard.

iCloud

  1. Go to account.apple.com > Sign-In and Security > App-Specific Passwords
  2. Generate a new password
{
  "services": [
    {
      "type": "carddav",
      "endpoint": "https://contacts.icloud.com",
      "username": "you@icloud.com",
      "password": "xxxx-xxxx-xxxx-xxxx"
    }
  ]
}

Fastmail

{
  "type": "carddav",
  "endpoint": "https://carddav.fastmail.com/dav/addressbooks/user/you@example.com/Default",
  "username": "you@example.com",
  "password": "your-app-password"
}

Google Contacts

{
  "type": "carddav",
  "endpoint": "https://www.googleapis.com/.well-known/carddav",
  "username": "you@gmail.com",
  "password": "your-app-password"
}

Multiple accounts and JMAP email context

You can combine multiple CardDAV accounts and add a JMAP provider for email context in frm context and frm triage:

{
  "services": [
    {
      "type": "carddav",
      "endpoint": "https://contacts.icloud.com",
      "username": "you@icloud.com",
      "password": "xxxx-xxxx-xxxx-xxxx"
    },
    {
      "type": "jmap",
      "session_endpoint": "https://api.fastmail.com/jmap/session",
      "token": "your-jmap-token",
      "max_results": 3
    }
  ]
}

You can override the config directory with FRM_CONFIG_DIR.

How it works

Contacts and metadata live in your CardDAV server via custom vCard fields:

  • X-FRM-FREQUENCY -- tracking interval (e.g. 2w, 1m)
  • X-FRM-IGNORE -- "true" to permanently hide
  • X-FRM-GROUP -- freeform group tag
  • X-FRM-SNOOZE-UNTIL -- date to suppress until

Interaction history is stored locally in ~/.frm/log.jsonl. This is the only local state -- back it up or symlink it to a synced directory.

License

MIT

About

CLI for managing personal contacts. Can be agent-driven. Uses CardDAV (apple/fastmail contacts). Your AI agent (or you) checks who you're overdue to contact, preps context for meetings, and logs interactions.

Topics

Resources

License

Stars

Watchers

Forks

Contributors