> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reflecto.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# CLI

> Stream your phone's notifications to your terminal — read, dismiss, and reply without leaving the keyboard.

The **Reflecto CLI** (`reflecto`) is a paired device, like the Chrome
extension or web app. It mirrors your phone's notifications into your terminal
in real time and lets you dismiss or reply to them. Everything is end-to-end
encrypted — the server only routes opaque blobs and never sees plaintext.

<Note>
  The CLI is a **receiver**, not a sender. It is unrelated to the `/v1/send` API
  (see the [Quickstart](/guides/quickstart)) and does not use `rfk_live_…`
  tokens — it pairs with your phone using a 6-digit code and derives its own
  encryption keys locally.
</Note>

## Install

<CodeGroup>
  ```bash Homebrew (macOS / Linux) theme={null}
  brew tap reflectoapp/cli
  brew install reflecto
  ```

  ```bash Install script (macOS / Linux) theme={null}
  curl -fsSL https://reflectoapp.github.io/reflecto-binaries/install.sh | sh
  ```
</CodeGroup>

Windows users can download `reflecto-windows-x64.exe` directly from the
[releases page](https://github.com/reflectoapp/reflecto-binaries/releases).

Verify the install:

```bash theme={null}
reflecto --help
```

## Pair with your phone

```bash theme={null}
reflecto pair
```

This generates a 6-digit code and waits. On your phone, open Reflecto, tap
**Add a device**, and enter the code. The code expires after 5 minutes —
re-run `reflecto pair` if it does.

Once confirmed, the CLI stores its credentials in `~/.config/reflecto/cli.json`
(created `chmod 600`). The two devices compute a shared secret via
Diffie–Hellman locally; the server cannot derive it.

```
✓ Phone:        Pixel 8
✓ Encryption:   X25519 + XSalsa20-Poly1305
✓ Token saved:  ~/.config/reflecto/cli.json (chmod 600)   # your resolved path
```

<Note>
  You can only pair one phone at a time. Run `reflecto unpair` before pairing
  again — silently overwriting the config would orphan the old device on the
  server.
</Note>

## Stream notifications

```bash theme={null}
reflecto tail
```

`tail` opens a live stream and renders each notification as a boxed card with
its sender, full body, category glyph, and available actions:

```
┌─ 12:34  💬 WhatsApp  ───────────────────────── #a3f2c1d ─┐
│ Alice Smith                                              │
│ Hey, can you take a look at the design?                  │
│                                                          │
│ [1] ↩ Reply   [2] ✓ Mark read                            │
└──────────────────────────────────────────────────────────┘
```

Press `1`–`9` to invoke the corresponding numbered action on the most recent
card with actions; a reply action opens an inline prompt. `d` dismisses that
card without leaving the stream, `r` prints a one-time hint (in card view)
pointing you at the numbered keys, and `q` (or `Ctrl-C`) quits.
Conversation-style notifications (WhatsApp, Telegram, Messages) cluster:
follow-up messages within 60s of the same thread render as `╰─` continuations
rather than fresh cards.

### `tail` options

| Flag                 | Description                                                          |
| -------------------- | -------------------------------------------------------------------- |
| `--app <names>`      | Comma-separated apps to allow (case-insensitive).                    |
| `--exclude <names>`  | Comma-separated apps to block.                                       |
| `--grep <pattern>`   | Substring, or `/regex/`, matched on title + body.                    |
| `--since <duration>` | Replay backlog first, e.g. `30m`, `1h`, `2d`.                        |
| `--json`             | Emit newline-delimited JSON instead of cards.                        |
| `--auto-dismiss`     | Auto-dismiss each notification on your phone after rendering.        |
| `--notify`           | Also fire a native desktop notification.                             |
| `--oneline`          | Force the single-line format.                                        |
| `--no-oneline`       | Force card view even when piped (overrides the non-TTY auto-switch). |

`tail` auto-switches to the single-line format when stdout is not a TTY, so
piping to `grep`, `jq`, or a file stays readable. Pass `--no-oneline` to keep
card view even when piped.

```bash theme={null}
# Only WhatsApp and Telegram, replaying the last hour
reflecto tail --app whatsapp,telegram --since 1h

# Everything except Slack, as JSON, piped to jq
reflecto tail --exclude slack --json | jq .
```

## Dismiss and reply

```bash theme={null}
# Dismiss a notification by its message id (UUID)
reflecto dismiss <id>

# Reply (apps that expose a RemoteInput action: WhatsApp, SMS, Telegram…)
reflecto reply <id> "On my way"
```

Both take the **full** message id (a UUID). The `#a3f2c1d` tag in a card header
is only the last 7 characters, shown to disambiguate scrolled-past cards — it
is **not** a valid argument. Get the full id from the `id` field of
`reflecto tail --json`:

```bash theme={null}
reflecto tail --json | jq -r .id   # full UUIDs, one per line
```

Replies are encrypted to your phone, which executes the action on your behalf.
A reply only lands if the original notification exposed a reply slot — `reflecto
reply` always prints a note on stderr reminding you of that requirement, and a
reply to a button-only notification has no effect on the phone.

## Status and unpair

```bash theme={null}
reflecto status   # phone, pairing date, server, connection, backlog, token path, crypto, version
reflecto unpair   # release this device on the server and clear local credentials
```

`unpair` removes only this CLI; any sibling devices (extension, web) paired
with the same phone stay connected.

## Configuration

The CLI always connects to the production server — there is no server
override. Behavior is controlled entirely through these environment variables:

| Variable           | Effect                                                                                                       |
| ------------------ | ------------------------------------------------------------------------------------------------------------ |
| `REFLECTO_CONFIG`  | Override the config-file path (default `~/.config/reflecto/cli.json`).                                       |
| `XDG_CONFIG_HOME`  | Base directory for the default config path.                                                                  |
| `REFLECTO_ASCII=1` | Force ASCII tags (`[msg]`, `[mail]`, …) instead of glyphs.                                                   |
| `NO_COLOR`         | Disable color output (the [NO\_COLOR](https://no-color.org) convention; the `--no-color` flag just sets it). |

Glyphs also fall back to ASCII automatically when stdout is not a TTY (e.g.
piped to `jq` or a file) or when the locale isn't UTF-8.
