Skip to content

salmonumbrella/beeper-cli

Repository files navigation

💬 Beeper CLI — Messaging in your terminal.

Manage chats, send messages, and control Beeper Desktop from the command line.

Features

  • Authentication - browser-based login with secure keyring storage
  • Chat management - list, search, archive, and organize conversations
  • Desktop control - focus Beeper window, navigate to chats, pre-fill drafts
  • Messaging - send messages, search history, and view conversations
  • Assets - upload files, resolve download paths, and stream media to stdout or disk
  • Local-first - everything stays on your device via Beeper Desktop’s local API
  • Multi-network support - WhatsApp, Signal, Telegram, Discord, Google Messages, Google Chat, Google Voice, Slack, X (Twitter DMs), LinkedIn, Instagram, Messenger (Facebook Messenger)
  • Upcoming networks - LINE, Hinge, Snapchat (coming soon)
  • Reminders - set and clear chat reminders

Supported Networks

Currently supported chat networks:

  • WhatsApp
  • Signal
  • Telegram
  • Discord
  • Google Messages
  • Google Chat
  • Google Voice
  • Slack
  • X (Twitter DMs)
  • LinkedIn
  • Instagram
  • Messenger (Facebook Messenger)

Installation

Homebrew

brew install salmonumbrella/tap/beeper-cli

Go Install

go install github.com/salmonumbrella/beeper-cli/cmd/beeper@latest

Build from Source

git clone https://github.com/salmonumbrella/beeper-cli
cd beeper-cli
make build && make install

Quick Start

1. Enable Local API

Open Beeper Desktop → Settings → Developers → Enable Local API

2. Authenticate

beeper auth login

This opens your browser to authenticate with Beeper and securely stores the token in your system keyring.

Prefer to paste a token directly?

beeper auth add --token "<token>"

3. Test Connection

beeper auth test

4. Start Using

beeper accounts              # List connected networks
beeper chats list            # Show recent chats
beeper messages search "hi"  # Search message history
beeper assets serve --url "mxc://example.org/id" --output ./asset.bin
beeper c ls                  # Short alias: chats list
beeper m s "hi"              # Short alias: messages search

Go SDK

The repo now ships a supported Go client at github.com/salmonumbrella/beeper-cli/pkg/beeper for the local Desktop API.

Install or import it from this module:

go get github.com/salmonumbrella/beeper-cli

Minimal example:

package main

import (
  "context"
  "log"

  "github.com/salmonumbrella/beeper-cli/pkg/beeper"
)

func main() {
  client := beeper.NewClient("http://localhost:23373", "<token>")
  accounts, err := client.ListAccounts(context.Background())
  if err != nil {
    log.Fatal(err)
  }
  log.Printf("accounts=%d", len(accounts))
}

Runnable SDK examples:

go run ./examples/fetch_accounts
go run ./examples/fetch_chats
go run ./examples/fetch_messages
go run ./examples/search
go run ./examples/send_message

The examples read:

  • BEEPER_TEST_URL
  • BEEPER_TEST_TOKEN
  • BEEPER_TEST_CHAT_ID for message list/send examples
  • BEEPER_TEST_QUERY for search
  • BEEPER_TEST_MESSAGE_TEXT for send
  • BEEPER_TEST_RUN_SEND_EXAMPLE=1 to opt into the mutating send example smoke

Agent Mode

Beeper CLI is optimized for automation. The following features are designed to reduce agent friction:

  • beeper schema [command path] - JSON schema for commands/flags
  • beeper schema --show-key-map - Include machine-readable light short-key map
  • beeper examples - Canonical usage examples
  • beeper agent guidelines - Store local agent instructions
  • beeper agent smoke - Read-only smoke plan for key flows
  • beeper agent state - Inspect/clear persisted handle state
  • --handles / BEEPER_AGENT_HANDLES=1 - Emit handle tokens like @chat:1 and @msg:2
  • beeper agent tools list|run - Run user-defined tool definitions
  • beeper agent tools schema|validate - Tool definition schema + validation

The assets serve step in beeper agent smoke expects a seeded BEEPER_TEST_ASSET_URL when you want to exercise asset streaming manually.

Handle tokens persist to a local state file (see Environment Variables) so agents can reference @chat:1 later.

Message commands support --include-chat to bundle chat metadata in JSON output.

Default agent files live under the Beeper CLI config directory:

  • Agent state: agent-state.json (or agent-state.<profile>.json)
  • Agent trace: agent-trace.jsonl

MCP Server Mode

Run a local read-only MCP server over stdio:

beeper mcp serve --source db --local-only

The initial MCP surface is intentionally small:

  • list_conversations
  • read_messages
  • search_messages

Privacy posture for the first release:

  • local DB reads only by default
  • no write-capable MCP tools
  • tool inputs and outputs stay in memory for the lifetime of the process

Example MCP client configuration:

{
  "command": "beeper",
  "args": ["mcp", "serve", "--source", "db", "--local-only", "--max-results", "50"]
}

Configuration

Authentication

Credentials are checked in this order:

  1. BEEPER_TOKEN, BEEPER_API_TOKEN, or BEEPER_ACCESS_TOKEN
  2. --profile / BEEPER_PROFILE
  3. Stored keychain token (default or the only configured profile)

When present, Beeper CLI auto-loads a .env file from its config directory before resolving flag defaults. Override that location with BEEPER_ENV_FILE.

Account Filtering

Filter commands by specific chat networks:

# Via flag
beeper chats list --account whatsapp

# Multiple networks
beeper messages search "invoice" --account whatsapp,telegram

Get account IDs from beeper accounts, or set a default with BEEPER_ACCOUNT.

Profile Selection

If you have multiple auth tokens saved, select one with --profile:

beeper --profile personal chats list

You can set a default profile with BEEPER_PROFILE.

Aliases

Create shortcuts for frequently used chat IDs:

beeper alias add work "!abc123:beeper.local"
beeper alias add family "!xyz789:beeper.local"
beeper alias list

Use aliases anywhere a chat name or ID is accepted:

beeper messages send --to work --text "Shipping now"
beeper focus --chat family --draft "On my way"

Reserved keywords are also supported:

beeper messages send --to myself --text "Remember to follow up"

Environment Variables

  • BEEPER_TOKEN - API token to use directly from the environment
  • BEEPER_API_TOKEN - Alias for BEEPER_TOKEN
  • BEEPER_ACCESS_TOKEN - Alias for BEEPER_TOKEN
  • BEEPER_OUTPUT - Output format: agent (default), text, json, json-pretty, or jsonl
  • BEEPER_COLOR - Color mode: auto (default), always, or never
  • NO_COLOR - Set to any value to disable colors (standard convention)
  • BEEPER_PROFILE - Default auth profile name
  • BEEPER_ACCOUNT - Default account filter
  • BEEPER_BASE_URL - Override API base URL (default: http://localhost:23373)
  • BEEPER_URL - Alias for BEEPER_BASE_URL
  • BEEPER_ENV_FILE - Override the auto-loaded dotenv file path
  • BEEPER_SOURCE - Backend source: api (default), db, or auto
  • BEEPER_DB - Path to Beeper index.db (implies --source db)
  • BEEPER_AGENT_HANDLES - Emit handle tokens like @chat:1 / @msg:2
  • BEEPER_AGENT_STATE - Override the agent state file path
  • BEEPER_AGENT_TRACE - Enable trace logging (set to a path or truthy value)
  • BEEPER_AGENT_TOOLS_DIR - Override the agent tools directory

DB Backend (Read-Only)

For faster local search, you can use the DB backend which reads Beeper’s local SQLite database directly. This is read-only and does not support sending or modifying data.

Requirements

  • CGO-enabled Go toolchain
  • SQLite3 library available on your system

Usage

# Use DB backend explicitly
beeper --source db messages search "invoice"

# Or point directly at the database (implies db backend)
beeper --db ~/Library/Application\ Support/BeeperTexts/index.db messages search "invoice"

# Include context around search hits
beeper --source db messages search "invoice" --context 2 --window 30m

# Auto mode (API first, DB fallback for search)
beeper --source auto messages search "invoice"

# Inspect all discovered local-store candidates
beeper db discover

You can add extra discovery hints in the config dir at localstores.json:

{
  "database_paths": [
    "/path/to/index.db"
  ],
  "max_results": 10
}

Security

Credential Storage

Tokens are stored securely in your system's keychain:

  • macOS: Keychain Access
  • Linux: Secret Service (GNOME Keyring, KWallet)
  • Windows: Credential Manager

If you prefer to bypass keychain lookups, place BEEPER_TOKEN=... in the auto-loaded dotenv file or export it in your shell. BEEPER_API_TOKEN and BEEPER_ACCESS_TOKEN work as compatible aliases.

Commands

Authentication

beeper auth login            # Authenticate via browser (opens browser)
beeper auth add              # Add a token (interactive or --token)
beeper auth add --token "<token>"
beeper auth add work         # Add a token with a profile name
beeper auth status           # Show auth source, token status, and config paths
beeper auth show             # Alias for auth status
beeper auth list             # List configured tokens
beeper auth remove <name>    # Remove a token
beeper auth test             # Test current env or keychain token
beeper auth test work        # Test a named token

Aliases

beeper alias list
beeper alias add <name> <chat-id>
beeper alias show <name>
beeper alias remove <name>

Accounts

beeper accounts              # List connected chat networks

Chats

beeper chats list                           # List recent chats
beeper chats list --unread                  # Only unread chats
beeper chats list --all                     # List ALL chats (pagination via search)
beeper chats list --all --include-muted     # Include muted chats
beeper chats list --pinned                  # Only pinned chats
beeper chats list --muted                   # Only muted chats
beeper chats list --archived                # Only archived chats
beeper chats list --inbox primary           # Filter by inbox
beeper chats list --inbox archive           # Show archived chats
beeper chats list --account whatsapp        # Filter by network
beeper chats list --type dm                 # Filter by chat type (dm or group)
beeper chats list --cursor <cursor>         # Paginate (recent or all)
beeper chats list --direction before        # Paginate direction
beeper --source db chats list               # List chats via local DB (read-only)
beeper chats get <chat-id>                  # Get chat details
beeper chats search <query>                 # Search for chats by name
beeper chats search <query> --limit 50      # Limit search results
beeper chats archive <chat-id>              # Archive a chat
beeper chats archive --chat "John"          # Archive by name
beeper chats archive --unarchive <chat-id>  # Unarchive
beeper chats archive-read                   # Archive all read chats
beeper chats archive-read --dry-run         # Preview what would be archived
beeper chats archive-read --yes             # Skip confirmation prompt

Messages

beeper messages list <chat-id>              # List messages in a chat
beeper messages list --chat "John"          # List by chat name
beeper messages list <chat-id> --limit 50   # Limit results
beeper messages list --unread               # Only unread messages
beeper messages list --cursor <cursor>      # Paginate from cursor
beeper messages list --direction before     # Paginate direction
beeper messages search <query>              # Search all messages
beeper messages search "invoice" --account telegram
beeper messages search "invoice" --after 2024-01-01
beeper messages search "invoice" --after "2h ago"
beeper messages search "invoice" --chat <chat-id>
beeper messages search "invoice" --limit 50
beeper messages send <chat-id> --text "Hello!"
beeper messages send --to "John" --text "Meeting at 3pm"
beeper messages send --to "John" --stdin
beeper messages send --to "John" --file ./message.txt
beeper messages send --to "John" --reply-to <message-id>
beeper messages tail <chat-id>              # Follow new messages
beeper messages tail --chat "John"          # Follow by chat name
beeper messages tail --interval 2s          # Polling interval
beeper messages tail --limit 20             # Show last N before following
beeper messages delete <message-id> --chat "John"
beeper messages delete <message-id> --chat-id <chat-id> --yes
beeper messages read --chat "John"
beeper messages read --chat-id <chat-id>
beeper messages react <message-id> --chat "John" --emoji "👍"
beeper messages react <message-id> --chat-id <chat-id> --emoji "👍"
beeper messages get <message-id> --chat "John" --context 3
beeper messages get <message-id> --chat-id <chat-id>

Events

beeper events tail                         # Stream live Desktop API events
beeper events tail --type message.upserted # Filter by event type
beeper events tail --chat "Team"           # Resolve a chat name, then filter server-side
beeper events tail --raw                   # Show raw websocket envelopes
beeper events tail --timeout 10s -o jsonl  # Exit after a bounded live capture

Shortcuts (Verb-First)

These are shortcuts for common flows (same flags/behavior as the canonical commands):

beeper send|snd ...   # = beeper messages send ...
beeper tail|tl ...    # = beeper messages tail ...
beeper search|s ...   # = beeper messages search ...
beeper reply|r ...    # reply to a message (infers chat via handle state / DB)
beeper open|o ...     # = beeper focus ... (with extra copy/paste affordances)
beeper unread|ib      # = beeper inbox

Short Aliases

For token savings, common resource and subcommand aliases are available:

beeper c ls                 # chats list
beeper c s "team"           # chats search
beeper m ls --chat "Team"   # messages list
beeper m g "$msg123" --chat "Team"  # messages get
beeper ct s "alex"          # contacts search

DB backend search options:

beeper --source db messages search "invoice" --days 7
beeper --source db messages search "invoice" --context 2 --window 30m
beeper --source db messages search "invoice" --message-format plain
beeper --source db messages search "invoice" --media image,video

Contacts

beeper contacts list                         # List DM contacts
beeper contacts list --limit 50              # Limit results
beeper contacts search <query>               # Search contacts by name
beeper contacts search <query> --limit 50    # Limit search results

Search Capabilities

Both contacts search and chats search use fuzzy matching with smart ranking:

  • Fuzzy matching - tolerates typos and approximate spelling
    beeper contacts search "damnznd"           # Finds "Damnzand"
    beeper chats search "boxing"               # Finds "Boxing Club" etc.
  • Multi-term search - multiple words use AND logic (all terms must match)
    beeper contacts search "john signal"       # Matches contacts named John on Signal
  • Field-weighted scoring - exact name matches rank higher than participant matches
  • Activity sorting - when scores are tied, most recently active results appear first
  • Group sender hints - when no DM contacts match, matching participants in group chats are shown on stderr
    beeper contacts search "alex"
    # stderr: hint: "Alex" found as sender in group "Team Chat"

Inbox

beeper inbox                                 # Show unread messages
beeper inbox --limit 10                      # Limit chats shown
beeper inbox --dm                            # Only DM conversations
beeper inbox --since 1h                      # Messages since duration
beeper inbox --watch --interval 3s           # Stream new messages

Reminders

beeper reminders set <chat-id> --at "2024-12-25 10:00"
beeper reminders set --chat "John" --at "2024-12-25 10:00"
beeper reminders set --chat "John" --at "30m"
beeper reminders clear <chat-id>

Agent

beeper agent guidelines              # Show current agent guidelines
beeper agent guidelines --init       # Create a starter guidelines file
beeper agent guidelines --path       # Print the guidelines file path

Guidelines are stored in your config directory. When using --profile, a profile-specific guidelines file is used.

Focus (Desktop Control)

beeper focus                                # Bring Beeper to foreground
beeper focus --chat "John"                  # Open specific chat
beeper focus --chat-id <chat-id>            # Open specific chat by ID
beeper focus --chat "John" --draft "Hi!"    # Open with pre-filled draft
beeper focus --chat "John" --message <id>   # Jump to a message
beeper focus --chat "John" --attachment /path/to/file

Version

beeper version                              # Print version info
beeper version --check                      # Check for updates

Doctor

beeper status                               # Show concise CLI health
beeper db discover                          # List discovered local stores
beeper db info                              # Inspect local DB + bridge discovery
beeper doctor                               # Run diagnostics

Completion

beeper completion [bash|zsh|fish|powershell]

Output Formats

Text

Human-readable tables with colors and formatting:

$ beeper chats list
ID                    NAME              NETWORK     UNREAD  LAST ACTIVITY
!abc123...            John Smith        WhatsApp            3:42 PM
!def456...            Team Chat         Telegram    5       2:15 PM
!ghi789...            Mom               iMessage    2       Yesterday

Agent

Compact, ID-embedded output for automation:

$ beeper chats list -o agent
[chat:!abc123] Team Chat (slack) - 2 unread [group]
[chat:!def456] Alice (whatsapp)

$ beeper messages list --chat "Team Chat" -o agent
[chat:!abc123] Team Chat
10:23   Alex: Standup in 5 [id:$msg1]
10:25 → You: On it [id:$msg2]

JSON

Machine-readable output:

$ beeper chats list -o json
{
  "items": [
    {
      "id": "!abc123...",
      "title": "John Smith",
      "network": "WhatsApp",
      "unreadCount": 0,
      "lastActivity": "2024-12-25T15:42:00Z"
    }
  ],
  "total": 1,
  "hasMore": false
}

Data goes to stdout, errors and progress to stderr for clean piping.

When using -o json, -o jsonl, or -o json-pretty, errors are also emitted as a single JSON object on stderr.

If you want only the array for piping to tools like jq, use --results-only:

beeper chats list -o json --results-only | jq '.[0]'

Pretty JSON

Readable JSON formatting:

beeper chats list -o json-pretty

Template Output

Customize text output with Go templates (applies per item for list commands):

beeper chats list --format '{{.Title}}\t{{.Network}}'

JSON Lines (JSONL)

Streaming commands emit one JSON object per line when -o json or -o jsonl is set. For list outputs, -o jsonl emits one object per line:

# Follow a chat and stream JSON events
beeper messages tail --chat "Team" -o jsonl | jq -c .

# Stream Desktop API websocket events as JSON lines
beeper events tail --type message.upserted -o jsonl | jq -c .

# Watch inbox updates as JSON lines
beeper inbox --watch -o jsonl

# List chats as JSON lines
beeper chats list -o jsonl

Sample event payloads:

{"chatID":"!abc123:beeper.com","chatTitle":"Team","network":"Slack","chatType":"group","message":"Standup in 5","sender":"Alex","timestamp":"2025-01-12T10:15:00Z"}
{"id":"$event:1","chatID":"!abc123:beeper.com","accountID":"acct1","senderID":"@alex:beeper.com","sender":"Alex","senderName":"Alex","text":"Hello","timestamp":"2025-01-12T10:15:00Z","isMe":false}

Fields by stream:

  • beeper inbox --watch -o json
    • chatID, chatTitle, network, chatType, message, sender, timestamp
  • beeper messages tail -o json
    • id, chatID, accountID, senderID, sender, senderName, text, timestamp, isMe, attachments, reactions, replyTo
  • beeper events tail -o json
    • type, seq, timestamp, chatID, ids, entries

beeper messages tail still polls chat history on an interval. beeper events tail uses the Desktop API websocket directly, supports --type, --chat, --raw, and reconnects after transient disconnects.

Streaming filters:

# Print only message text from a live stream
beeper messages tail --chat "Team" -o json | jq -r '.text'

# Print event type + chat ID from the websocket stream
beeper events tail -o json | jq -r '"\(.type) \(.chatID)"'

# Print inbox sender + message
beeper inbox --watch -o json | jq -r '"\(.sender): \(.message)"'

List output schema (JSON):

  • beeper chats list -o json
    • items[] with chat fields (id, title, network, unreadCount, lastActivity, type, accountID, isArchived, isMuted, isPinned, preview)
    • total, hasMore, cursor, newestCursor, oldestCursor
  • beeper messages list -o json
    • items[] with message fields (id, chatID, accountID, senderID, sender, senderName, text, timestamp, isMe, attachments, reactions, replyTo)
  • beeper messages search -o json
    • messages[] with message fields, chats{} lookup, hasMore, cursor
  • beeper inbox -o json
    • chatID, chatTitle, network, chatType, message, sender, timestamp
  • beeper contacts list -o json
    • id, title, network, lastActivity
  • beeper contacts search -o json
    • items[] with chat fields (DMs), hasMore, cursor
  • beeper accounts -o json
    • id, network, user
  • beeper reminders set/clear -o json
    • status, chat_id, reminder_at (for set)
  • beeper focus -o json
    • status, chat_id, draft

Examples

Archive all read chats

# Preview first
beeper chats archive-read --dry-run

# Then execute
beeper chats archive-read

Send a quick message

beeper messages send --to "John" --text "Running 5 mins late!"

Follow a chat

beeper messages tail --chat "Team" --interval 2s

Inspect websocket events

beeper events tail --type message.upserted --timeout 10s -o jsonl

Search messages across networks

beeper messages search "pdf" --account whatsapp -o json | jq '.messages[]'

Search with relative dates (DB or API)

beeper messages search "invoice" --after "yesterday"

Search attachments (DB backend)

beeper --source db messages search "invoice" --media file

Use aliases and "myself"

beeper alias add work "!abc123:beeper.local"
beeper messages send --to work --text "Shipped"
beeper messages send --to myself --text "Follow up tomorrow"

Focus chat with draft from clipboard

beeper focus --chat "Team" --draft "$(pbpaste)"

Disambiguate chat names

beeper messages send --to "Project" --exact --text "Shipping now"
beeper chats archive --chat "Family" --first
beeper reminders set --chat "Alex" --dm --at "2024-12-25 10:00"

Automation

Use -o json for scripting and --dry-run to preview changes:

# Count unread chats
beeper chats list -o json | jq '[.items[] | select(.unreadCount > 0)] | length'

# Get all Telegram chat IDs
beeper chats list --account telegram -o json --query '.items[].id'

# Notify on unread count
unread=$(beeper chats list -o json | jq '[.items[] | select(.unreadCount > 0)] | length')
[ "$unread" -gt 10 ] && osascript -e "display notification \"$unread unread\" with title \"Beeper\""

Debug Mode

Enable verbose output for troubleshooting:

beeper --debug chats list
# Shows: api request method=GET url=http://localhost:9988/...
# Shows: api response status=200 content_length=1234

JQ Filtering

Filter JSON output with JQ expressions:

# Get only unread chats
beeper chats list -o json --query '.items[] | select(.unreadCount > 0)'

# Extract chat IDs
beeper chats list -o json --query '.items[].id'

# Get chats from specific network
beeper chats list -o json --query '.items[] | select(.network == "Telegram")'

Global Flags

All commands support these flags:

  • --account <id> - Filter by account/network ID
  • --profile <name> - Auth profile name (from beeper auth list)
  • --base-url <url> - Override API base URL
  • -o, --output <format> - Output format: agent, text, json, json-pretty, or jsonl (default: agent)
  • --color <mode> - Color mode: auto, always, or never (default: auto)
  • --debug - Enable debug output (shows API requests/responses)
  • --query <expr> - JQ filter expression for JSON output
  • --results-only - For JSON output, return only the results array (strip envelope)
  • --compact-json, --cj - Prefer compact JSON in JSON modes (forces single-line output for json-pretty)
  • --format <template> - Go template for text output (applies per item for lists)
  • --source <api|db|auto> - Backend source (db is read-only)
  • --db <path> - Path to Beeper index.db (implies db backend)
  • --help - Show help for any command
  • --version - Show version information

Commands that support local --light (--li) auto-switch to -o json when output was not explicitly set, and default --compact-json to true unless --compact-json/--cj was explicitly provided.

In light mode, JSON payloads use short field keys to reduce token usage. Key map:

  • chats: id, ti (title), nw (network), ty (type), ur (unread), ts (last activity), pv (preview)
  • messages: id, ch (chat id), sn (sender), tx (text), ts (timestamp), me (is me)
  • chats messages: same key map as messages (uses MessageLight)
  • inbox: ch (chat id), ti (chat title), sn (sender), tx (message), ts (timestamp)

For programmatic discovery, run:

beeper schema --show-key-map -o json --query '.lightKeyMap'

API Limitations

The Beeper Desktop local API does not currently expose endpoints for:

  • Muting, pinning, or renaming chats

The CLI now exposes real-time websocket events via beeper events tail, but beeper messages tail remains a polling command because the Desktop API does not currently expose a chat-scoped "follow messages" endpoint with the same payload shape.

API Limits

Some endpoints have server-side limits:

Endpoint Max --limit Notes
messages search 20 Use --cursor to paginate for more results
chats search 20 Use --cursor to paginate for more results
contacts search 20 Use --cursor to paginate for more results

The DB backend (--source db) does not have these limits.

Shell Quoting

Chat IDs start with ! which has special meaning in bash/zsh (history expansion). Prefer single quotes around chat IDs:

# Correct
beeper messages list '!abc123:beeper.local'
beeper chats get '!abc123:beeper.local'

# Also correct (escaped)
beeper messages list "\\!abc123:beeper.local"
beeper chats get "\\!abc123:beeper.local"

# Wrong - may fail or behave unexpectedly
beeper messages list "!abc123:beeper.local"
beeper messages list !abc123:beeper.local

Copy/Paste Tokens (Agent Output)

In addition to raw IDs, most commands accept identifiers copied directly from output:

  • Chat tokens: [chat:!abc123] ... or chat:!abc123
  • Message tokens: ... [id:$msg123] ..., id:$msg123, or ↩$msg123
  • Handle refs (when enabled): @chat:1, @msg:2 (also works as [@chat:1] / [@msg:2])

When piping to jq, avoid != which can trigger history expansion. Use jq's truthy check instead:

# Correct - jq treats null as falsy
beeper messages list "!chat:id" -o json | jq '.items[] | select(.text)'

# Problematic in some shells
beeper messages list "!chat:id" -o json | jq '.items[] | select(.text != null)'

Shell Completions

Generate shell completions for your preferred shell:

Bash

# macOS (Homebrew):
beeper completion bash > $(brew --prefix)/etc/bash_completion.d/beeper

# Linux:
beeper completion bash > /etc/bash_completion.d/beeper

# Or source directly:
source <(beeper completion bash)

Zsh

beeper completion zsh > "${fpath[1]}/_beeper"

Fish

beeper completion fish > ~/.config/fish/completions/beeper.fish

PowerShell

beeper completion powershell | Out-String | Invoke-Expression

Development

After cloning, install git hooks:

make setup

This installs lefthook pre-commit and pre-push hooks for linting and testing.

Manual Checks

go test ./pkg/beeper ./examples/...
go test ./internal/cmd ./internal/service -run 'TestLive' -v
go test ./examples -run 'TestLive' -v
beeper auth status
beeper doctor
beeper status
beeper db discover
beeper db info --no-bridge
beeper events tail --type message.upserted --timeout 5s --raw
printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | beeper mcp serve --source db --local-only
beeper alias add work "!abc123:beeper.local"
beeper alias list
beeper messages send --to myself --text "ping"
beeper messages search "invoice" --after "2h ago"
beeper --source db messages search "invoice" --media image

Live SDK Test

The public Go SDK smoke test is env-gated and skipped by default:

BEEPER_TEST_URL=http://localhost:23373 \
BEEPER_TEST_TOKEN=... \
go test ./pkg/beeper -run 'TestLive' -v

TestLiveListAccounts and TestLiveListChats only need the URL/token. TestLiveListMessages also reads BEEPER_TEST_CHAT_ID, and TestLiveSearchMessages reads BEEPER_TEST_QUERY.

There is also a manual GitHub Actions path in .github/workflows/ci.yml via workflow_dispatch with run_live_sdk=true, and it requires BEEPER_TEST_CHAT_ID and BEEPER_TEST_QUERY so the full SDK smoke runs instead of partially skipping.

Live CLI Smoke

The CLI now has env-gated subprocess smoke coverage for the shipped command surfaces:

BEEPER_TEST_URL=http://localhost:23373 \
BEEPER_TEST_TOKEN=... \
go test ./internal/cmd ./internal/service -run 'TestLive' -v

That smoke suite exercises:

  • beeper auth status -o json
  • beeper status -o json
  • beeper db discover -o json
  • beeper db info --no-bridge -o json
  • beeper events tail --timeout 2s --raw -o jsonl
  • beeper mcp serve --source db --local-only
  • beeper assets serve --output ...

The assets serve smoke uploads a tiny temporary text asset first, then verifies the CLI can stream it back to disk.

That same run also includes the low-level live websocket event stream smoke from ./internal/service.

There is also a workflow_dispatch path in .github/workflows/ci.yml with run_live_cli=true.

Live Example Smoke

The runnable SDK example programs are also covered by env-gated smoke tests:

BEEPER_TEST_URL=http://localhost:23373 \
BEEPER_TEST_TOKEN=... \
BEEPER_TEST_CHAT_ID=... \
BEEPER_TEST_QUERY=... \
go test ./examples -run 'TestLive' -v

That covers fetch_accounts, fetch_chats, fetch_messages, and search. send_message is intentionally opt-in because it mutates state:

BEEPER_TEST_URL=http://localhost:23373 \
BEEPER_TEST_TOKEN=... \
BEEPER_TEST_CHAT_ID=... \
BEEPER_TEST_MESSAGE_TEXT="ping" \
BEEPER_TEST_RUN_SEND_EXAMPLE=1 \
go test ./examples -run 'TestLiveSendMessageExample' -v

There is also a workflow_dispatch path in .github/workflows/ci.yml with run_live_examples=true. That path also requires BEEPER_TEST_CHAT_ID and BEEPER_TEST_QUERY so fetch_messages and search do not silently skip.

Live Event Test

The websocket integration test is opt-in and requires a live Desktop API token:

BEEPER_TEST_URL=http://localhost:23373 \
BEEPER_TEST_TOKEN=... \
go test ./internal/service -run 'TestLiveEventStream' -v

License

MIT

Links

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors