roadrunner (rr)
Use rr when the user explicitly wants to operate Beeper Desktop via the local API (send, search, list chats/messages, reminders, focus).
Prefer --agent for agent use (forces JSON, envelope, no-input, readonly).
Safety
- - Default to read-only commands unless the user explicitly requests a mutation in this turn.
- Require explicit recipient (chat ID) and message text before sending.
- Confirm or ask a clarifying question if the chat ID is ambiguous.
- Never paste raw rr command output (JSON dumps, chat lists, etc.) into outgoing messages. Treat tool output as private; summarize or extract only what the user needs.
- Use
--agent for safe agent defaults: INLINECODE3 - Use
--readonly to block writes: INLINECODE5 - Use
--enable-commands to allowlist: INLINECODE7 - Use
--envelope for structured errors: INLINECODE9 - Envelope errors may include
error.hint with next-step guidance for safe retries. - Never request, paste, or store raw auth tokens in chat. If auth is missing, ask the user to configure it locally.
- If sending message text through a shell, avoid interpolation/expansion (e.g.
$100/month or !). Prefer --stdin <<'EOF' ... EOF for safe literals.
Setup (once)
- -
rr auth set --stdin (recommended; token saved to ~/.config/beeper/config.json) - INLINECODE16
- INLINECODE17
Common commands
- - List accounts: INLINECODE18
- Capabilities: INLINECODE19
- Describe command/flags: INLINECODE20
- Connect metadata: INLINECODE21
- Live websocket events (experimental): INLINECODE22
- List contacts: INLINECODE23
- Search contacts: INLINECODE24
- Search contacts (flag): INLINECODE25
- Resolve contact: INLINECODE26
- Resolve contact (flag): INLINECODE27
- List chats: INLINECODE28
- List chats (JSON Lines): INLINECODE29
- Search chats: INLINECODE30
- Search chats (filters): INLINECODE31
- Search chats (activity): INLINECODE32
- Search by participant name: INLINECODE33
- Resolve chat: INLINECODE34
- Get chat: INLINECODE35
- Get chat (bounded participants): INLINECODE36
- Start/resolve DM from merged contact hints: INLINECODE37
- Default account for commands: INLINECODE38
- List messages: INLINECODE39
- List messages (all pages): INLINECODE40
- List messages (download media): INLINECODE41
- Search messages: INLINECODE42
- Search messages (JSON Lines): INLINECODE43
- Search messages (all pages): INLINECODE44
- Search messages (filters): INLINECODE45
- Add/remove reaction:
rr messages react "!chatid:beeper.com" "<message-id>" "👍" --json / INLINECODE47 - Tail messages (polling): INLINECODE48
- Wait for message: INLINECODE49
- Message context: INLINECODE50
- Draft message (pre-fill without sending): INLINECODE51
- Draft message from file: INLINECODE52
- Draft with attachment: INLINECODE53
- Download attachment: INLINECODE54
- Stream attachment bytes: INLINECODE55
- Focus app: INLINECODE56
- Global search: INLINECODE57
- Global search messages auto-page: INLINECODE58
- Status summary: INLINECODE59
- Status by account: INLINECODE60
- Unread rollup: INLINECODE61
- Global search includes
in_groups for participant matches.
Mutations (explicit user request only)
- - Message send: INLINECODE63
- Message edit: INLINECODE64
- Message react/unreact:
rr messages react "!chatid:beeper.com" "<message-id>" "👍" / INLINECODE66 - Upload + send file: INLINECODE67
- Create chat: INLINECODE68
- Start chat from merged contact hints: INLINECODE69
- Archive/unarchive:
rr chats archive "!chatid:beeper.com" / INLINECODE71 - Reminder mutations:
rr reminders set "!chatid:beeper.com" "2h" / INLINECODE73 - Asset uploads:
rr assets upload ./photo.jpg / INLINECODE75 - For retries on non-idempotent writes, use
--request-id and prefer --dedupe-window. - Use
--dry-run to validate mutating requests without API write side effects.
Pagination
- - Auto-page chats list/search:
rr chats list --all --max-items=1000 --json / INLINECODE80 - Auto-page messages list/search:
rr messages list "!chatid:beeper.com" --all --max-items=1000 --json / INLINECODE82 - Chats: INLINECODE83
- Messages list: INLINECODE84
- Messages search (max 20): INLINECODE85
- Messages search page: INLINECODE86
- Global search message paging (max 20): INLINECODE87
- Global search message page: INLINECODE88
Notes
- - Requires Beeper Desktop running; token from app settings.
- Token is stored in
~/.config/beeper/config.json via rr auth set (recommended). BEEPER_TOKEN overrides the config file. - INLINECODE92 sets the default account ID (aliases supported).
- INLINECODE93 prefers OAuth introspection (
/oauth/introspect) when available and falls back to account-list validation on older builds. - Message search is literal word match (not semantic).
- INLINECODE95 is strict and fails on ambiguous names; resolve by ID after
contacts search when needed. - If a DM title shows your own Matrix ID, use
--scope=participants to find by name. - JSON output includes
display_name for single chats (derived from participants). - Message JSON includes
message_type, linked_message_id, is_sender, is_unread, attachments, and reactions. - INLINECODE105 is only populated when
--download-media is used. - INLINECODE107 returns
pending_message_id (temporary ID). - Account
network may be missing in newer API builds; rr falls back to "unknown" in summaries/search output. - INLINECODE112 writes raw bytes to stdout unless
--dest is provided. - INLINECODE114 does exact matching and fails on ambiguous matches.
- Attachment overrides require
--attachment-upload-id; set --attachment-width and --attachment-height together. - INLINECODE118 has a safety cap (default 500 items, max 5000); use
--max-items to tune it. - Prefer
--json or --jsonl (and --no-input) for automation. - INLINECODE123 emits one JSON object per line and is supported on high-volume list/search commands.
- INLINECODE124 /
BEEPER_DRY_RUN validates mutating command inputs and prints preview output without sending write API requests. - INLINECODE126 overrides API base URL;
BEEPER_TIMEOUT sets timeout in seconds. - JSON/Plain output goes to stdout; errors/hints go to stderr.
- Destructive commands prompt unless
--force; --no-input/BEEPER_NO_INPUT fails without --force. - Use
--fail-if-empty on list/search commands to exit with code 1 if no results. - Use
--fields with --plain to select columns (comma-separated). - In bash/zsh,
! triggers history expansion. Prefer single quotes, or disable history expansion (set +H in bash, setopt NO_HIST_EXPAND in zsh). - INLINECODE138 returns
features array for capability discovery. - INLINECODE140 returns full CLI capability metadata.
- INLINECODE141 depends on experimental
/v1/ws support in Beeper Desktop; fall back to rr messages tail when unavailable. - Envelope error codes:
AUTH_ERROR, NOT_FOUND, VALIDATION_ERROR, CONNECTION_ERROR, INTERNAL_ERROR. - Retry policy: retry
CONNECTION_ERROR with backoff; do not blind-retry AUTH_ERROR/VALIDATION_ERROR; refresh IDs before retrying NOT_FOUND. - Non-idempotent writes:
messages send, messages send-file, chats create, chats start, assets upload, assets upload-base64. - Use
--request-id/BEEPER_REQUEST_ID to tag envelope metadata for cross-retry attempt tracing. - Use
--dedupe-window/BEEPER_DEDUPE_WINDOW to block duplicate non-idempotent writes with repeated request IDs. - Local smoke check:
make test-agent-smoke.
roadrunner (rr)
当用户明确希望通过本地API操作Beeper Desktop(发送、搜索、列出聊天/消息、提醒、聚焦)时,使用rr。
优先使用--agent进行代理操作(强制JSON、信封模式、无输入、只读)。
安全
- - 默认使用只读命令,除非用户在当前轮次中明确请求修改操作。
- 发送前需要明确的收件人(聊天ID)和消息文本。
- 如果聊天ID不明确,需确认或提出澄清性问题。
- 切勿将原始的rr命令输出(JSON转储、聊天列表等)粘贴到外发消息中。将工具输出视为私有信息;仅总结或提取用户所需内容。
- 使用--agent实现安全的代理默认设置:rr --agent --enable-commands=chats,messages,status chats list
- 使用--readonly阻止写入操作:rr --readonly chats list --json
- 使用--enable-commands设置允许列表:rr --enable-commands=chats,messages chats list --json
- 使用--envelope获取结构化错误信息:rr --json --envelope chats get !chatid
- 信封错误可能包含error.hint,提供安全重试的下一步指导。
- 切勿在聊天中请求、粘贴或存储原始认证令牌。如果缺少认证,请要求用户在本地配置。
- 如果通过shell发送消息文本,避免插值/扩展(例如$100/month或!)。优先使用--stdin <
设置(一次性)
- - rr auth set --stdin(推荐;令牌保存至~/.config/beeper/config.json)
- rr auth status --check
- rr doctor
常用命令
- - 列出账户:rr accounts list --json
- 功能能力:rr capabilities --json
- 描述命令/标志:rr describe messages send --json
- 连接元数据:rr connect info --json
- 实时WebSocket事件(实验性):rr events tail --all --stop-after 30s --json
- 列出联系人:rr contacts list --json
- 搜索联系人:rr contacts search Alice --json
- 搜索联系人(标志):rr contacts search Alice --account-id= --json
- 解析联系人:rr contacts resolve Alice --json
- 解析联系人(标志):rr contacts resolve Alice --account-id= --json
- 列出聊天:rr chats list --json
- 列出聊天(JSON Lines):rr chats list --jsonl
- 搜索聊天:rr chats search John --json
- 搜索聊天(筛选):rr chats search --inbox=primary --unread-only --json
- 搜索聊天(活动):rr chats search --last-activity-after=2024-07-01T00:00:00Z --json
- 按参与者名称搜索:rr chats search Jamie --scope=participants --json
- 解析聊天:rr chats resolve Jamie --json
- 获取聊天:rr chats get !chatid:beeper.com --json
- 获取聊天(限定参与者数量):rr chats get !chatid:beeper.com --max-participant-count=50 --json
- 从合并的联系人提示开始/解析私聊:rr chats start --email alice@example.com --full-name Alice --json
- 命令的默认账户:rr --account=imessage:+123 chats list --json
- 列出消息:rr messages list !chatid:beeper.com --json
- 列出消息(所有页面):rr messages list !chatid:beeper.com --all --max-items=1000 --json
- 列出消息(下载媒体):rr messages list !chatid:beeper.com --download-media --download-dir ./media --json
- 搜索消息:rr messages search dinner --json
- 搜索消息(JSON Lines):rr messages search dinner --jsonl
- 搜索消息(所有页面):rr messages search dinner --all --max-items=1000 --json
- 搜索消息(筛选):rr messages search --sender=me --date-after=2024-07-01T00:00:00Z --media-types=image --json
- 添加/移除反应:rr messages react !chatid:beeper.com 👍 --json / rr messages unreact !chatid:beeper.com 👍 --json
- 尾随消息(轮询):rr messages tail !chatid:beeper.com --interval 2s --stop-after 30s --json
- 等待消息:rr messages wait --chat-id=!chatid:beeper.com --contains deploy --wait-timeout 2m --json
- 消息上下文:rr messages context !chatid:beeper.com --before 5 --after 2 --json
- 草稿消息(预填充但不发送):rr focus --chat-id=!chatid:beeper.com --draft-text=Hello!
- 从文件创建草稿消息:rr focus --chat-id=!chatid:beeper.com --draft-text-file ./draft.txt
- 带附件的草稿:rr focus --chat-id=!chatid:beeper.com --draft-attachment=/path/to/file.jpg
- 下载附件:rr assets download mxc://example.org/abc123 --dest ./attachment.jpg
- 流式传输附件字节:rr assets serve mxc://example.org/abc123 --dest ./attachment.jpg --json
- 聚焦应用:rr focus
- 全局搜索:rr search dinner --json
- 全局搜索消息自动翻页:rr search dinner --messages-all --messages-max-items=500 --messages-limit=20 --json
- 状态摘要:rr status --json
- 按账户查看状态:rr status --by-account --json
- 未读汇总:rr unread --json
- 全局搜索包含in_groups用于参与者匹配。
修改操作(仅限用户明确请求)
- - 发送消息:rr messages send !chatid:beeper.com Hello!
- 编辑消息:rr messages edit !chatid:beeper.com Updated text
- 消息反应/取消反应:rr messages react !chatid:beeper.com 👍 / rr messages unreact !chatid:beeper.com 👍
- 上传并发送文件:rr messages send-file !chatid:beeper.com ./photo.jpg See attached
- 创建聊天:rr chats create --participant
- 从合并的联系人提示开始聊天:rr chats start --email alice@example.com --full-name Alice
- 归档/取消归档:rr chats archive !chatid:beeper.com / rr chats archive !chatid:beeper.com --unarchive
- 提醒修改:rr reminders set !chatid:beeper.com 2h / rr reminders clear !chatid:beeper.com
- 资产上传:rr assets upload ./photo.jpg / rr assets upload-base64 --content-file ./photo.b64
- 对于非幂等写入的重试,使用--request-id并优先使用--dedupe-window。
- 使用--dry-run验证修改请求,避免API写入副作用。
分页
- - 自动翻页聊天列表/搜索:rr chats list --all --max-items=1000 --json / rr chats search alice --all --max-items=1000 --json
- 自动翻页消息列表/搜索:rr messages list !chatid:beeper.com --all --max-items=1000 --json / rr messages search deploy --all --max-items=1000 --json
- 聊天:rr chats list --cursor= --direction=before --json
- 消息列表:rr messages list !chatid:beeper.com --cursor= --direction=before --json
- 消息搜索(最多20条):rr messages search project --limit=20 --json
- 消息搜索翻页:rr messages search project --cursor= --direction=before --json
- 全局搜索消息分页(最多20条):rr search dinner --messages-limit=20 --json