Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .surface
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,11 @@ hey snippet update --name
hey spam
hey stop-ignoring
hey thread
hey thread list
hey thread list --all
hey thread list --in
hey thread list --limit
hey thread list --page
hey thread read
hey thread read --allow-partial
hey timetrack
Expand Down
14 changes: 13 additions & 1 deletion API-COVERAGE.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# API Coverage

Mapping of HEY API endpoints used by the CLI. API interactions use the HEY SDK (`hey-sdk/go`).
Every endpoint below is read as JSON through a typed SDK operation; nothing parses HTML.
Every endpoint below is read as JSON through the SDK; the Client column names its typed
operation except where a narrow generic document read is called out. Nothing parses HTML.

**`/topics/{id}/entries.json` cannot be paged by number.** `Topics::EntriesController` uses
`set_page_and_extract_portion_from`, so like every other list here its `page` is
Expand All @@ -11,6 +12,13 @@ is the SDK read that keeps that header; `hey thread read` and `hey attachment li
through `internal/threadload`. The drafts index (`/entries/drafts.json`) pages the same way,
which is what `Entries().ListDraftsPage` and `hey draft list --page` exist for.

The four system topic views also use geared_pagination cursors from `Link`. The SDK's
`Topics().GetSent`, `GetSpam`, `GetTrash` and `GetEverything` methods return the generated
body but discard that header in v0.29.0. `hey thread list` therefore reads the same fixed
routes through the SDK document client, decodes `generated.TopicListResponse`, and retains
only the opaque `page` value from the next link. Authentication, account scoping, caching,
request limits and hooks still stay inside the SDK.

| Endpoint | Method | Client | CLI Command | Status |
|----------|--------|--------|-------------|--------|
| `/boxes.json` | GET | SDK `Boxes().List` | `hey box list` | covered |
Expand All @@ -22,6 +30,10 @@ which is what `Entries().ListDraftsPage` and `hey draft list --page` exist for.
| `/asidebox.json` | GET | SDK `Boxes().GetAsidebox` | `hey box view asidebox` | covered |
| `/laterbox.json` | GET | SDK `Boxes().GetLaterbox` | `hey box view laterbox` | covered |
| `/bubblebox.json` | GET | SDK `Boxes().GetBubblebox` | `hey box view bubblebox`, `hey bubble list` (scheduled bucket) | covered |
| `/topics/sent.json` | GET | SDK `Client.Get` + `generated.TopicListResponse` | `hey thread list --in sent` | covered |
| `/topics/spam.json` | GET | SDK `Client.Get` + `generated.TopicListResponse` | `hey thread list --in spam` | covered |
| `/topics/trash.json` | GET | SDK `Client.Get` + `generated.TopicListResponse` | `hey thread list --in trash` | covered |
| `/topics/everything.json` | GET | SDK `Client.Get` + `generated.TopicListResponse` | `hey thread list --in everything` | covered |
| `/imbox/bubbled_up` | GET | — | — | not served: HTML only; the Imbox JSON orders bubbled-up threads first, so `hey bubble list` reads that prefix instead |
| `/my/navigation.json` | GET | SDK `Identity().GetNavigation` | `hey label list`, Mail TUI navigation | covered |
| `/folders/{id}.json` | GET | SDK `Folders().GetPage` | `hey label view <id>`, Mail TUI labels | covered |
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ screen a moment later.

```bash
hey box view imbox # threads in a box
hey thread list --in sent # sent threads; also spam, trash, or everything
hey thread read 12345 # a whole thread, as Markdown
hey reply 12345 -m "Friday works for me."
hey compose --to alice@example.com --subject "Lunch?" -m "Thursday at noon?"
Expand Down
16 changes: 14 additions & 2 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ hey box list --quiet --jq '.[].id'
Listing commands also answer `--markdown` for a table, `--styled` to force the human
rendering when the output is piped, `--ids-only` for one ID per line, and `--count` for a
bare number. `--ids-only` and `--count` need list data, so they work on `hey box list`,
`hey box view`, `hey bundle view`, `hey label list`, `hey label view`, `hey collection list`, `hey collection view`,
`hey box view`, `hey bundle view`, `hey thread list`, `hey label list`, `hey label view`, `hey collection list`, `hey collection view`,
`hey workflow list`, `hey workflow view`, `hey clip list`, `hey snippet list`, `hey draft list`, `hey search`, `hey contact list`, `hey contact threads`, `hey screener list`, `hey screener history`, `hey calendar list`,
`hey event list`, `hey event day`, `hey event week`, `hey todo list`, `hey habit list`,
`hey timetrack list` and `hey journal list`.
Expand Down Expand Up @@ -155,6 +155,10 @@ or through the direct-form escape (`hey box -- list`).
```bash
hey box list # list mailboxes
hey box view imbox # list email threads in a box (by name or ID)
hey thread list --in sent # list sent threads
hey thread list --in spam # list threads in Spam without changing them
hey thread list --in trash # list threads in Trash without changing them
hey thread list --in everything # list every thread
hey bundle view 456 # list the unseen threads a bundle row groups
hey label list # list labels and their IDs
hey label view 789 --all # list all email threads with a label
Expand Down Expand Up @@ -255,6 +259,14 @@ hey ignore 12345 # ignore future activity on a thread
hey stop-ignoring 12345 # resume attention for a thread
```

`hey thread list` is the read-only index for HEY's Sent, Spam, Trash and Everything
views. Its JSON data is an array of topics; each row carries `topic_id` explicitly, and
both `id` and `topic_id` on these rows are thread IDs for `hey thread read`, `hey reply`,
`hey forward`, `hey share` and `hey attachment list` — neither is a box item ID for
organization commands. `--limit` reads only enough pages for the requested result count,
`--all` follows up to 100 pages, and `--page <next_page>` continues from the opaque cursor
reported by an earlier listing of the same view. A page number does not name a position.

`hey thread read` reads a whole thread, oldest entry first, however many pages HEY serves it in — within limits it states: a hundred pages past the first, two thousand entries, as many bodies, 64 MiB of content and two minutes in all. A thread that could only be read in part — a body HEY would not serve, a limit reached — is refused rather than passed off as whole; `--allow-partial` takes what was read, with a `notice` saying what is missing and each entry's `body_state` saying whether its body was `hydrated`, `bodyless` (HEY served none), `over_limit` or `failed`. `--count` and `--ids-only` read the entry index and no bodies, so only a truncated index can make them partial. `--markdown` writes the thread as one Markdown document — a heading per entry naming the sender, date and ID, then the body — which is the shape to hand an agent or a notes app. `hey attachment list` reads the bodies in every format, since that is where attachment metadata lives, and answers a partial thread the same way. `hey reply` answers the thread's latest entry and addresses the reply the way HEY does: it asks HEY for the reply's recipients — everyone that entry was addressed to, its sender moved onto the To line, and your own addresses, aliases and catch-alls excluded — falling back to computing them from the entry when that read is unavailable.

Email bodies come back as Markdown. `hey thread read` and the TUI render that Markdown for the terminal — headings, emphasis, lists, quotes, tables and code survive, and links keep their URLs and stay clickable where the terminal supports it. `--json` carries the same Markdown in `body`, so an agent reading a thread sees the structure a human sees rather than a flattened wall of text. `--html` still returns HEY's original HTML.
Expand All @@ -275,7 +287,7 @@ The Screener is where first-time senders wait. `hey screener list` returns clear

`--attach` is repeatable on `hey compose`, `hey reply`, and `hey bulk-reply send`, and attachment-only messages are supported. The CLI validates and uploads every file before sending the email. `hey attachment list <thread-id>` returns every named downloadable file, including named inline images. Direct files keep stable message-and-position IDs such as `456:1`; files inside embedded HTML receive opaque IDs scoped to their message. Pass either returned ID to `hey attachment save`. Saving uses the original filename by default, accepts `--output` for a file or directory, and preserves existing files unless `--force` is set.

Organization actions take the `id` values returned by `hey box view --json`, `hey label view --json`, or `hey search --json`. Reading, replying to, and forwarding a thread take its `topic_id` instead, which `hey box view --json`, `hey label view --json`, `hey collection view --json` and `hey search --json` all carry alongside `id`. `hey box view` also returns `next_page` and accepts `--page <next_page>` to continue a box listing; it keeps `next_history_url` for the sync clients that read it, and `--page` accepts that URL as readily as the cursor inside it. Label IDs come from `hey label list`; `hey label view` returns `next_page` and `total_count`, accepts `--page <next_page>` for continuation, and supports `--all` for complete traversal. HEY creates a label while adding it to at least one thread, so `hey label create` requires thread item IDs.
Organization actions take the `id` values returned by `hey box view --json`, `hey label view --json`, or `hey search --json`. Reading, replying to, and forwarding a thread take its `topic_id` instead, which `hey thread list --json`, `hey box view --json`, `hey label view --json`, `hey collection view --json` and `hey search --json` carry. A `hey thread list` row is the exception to the two-ID shape: its `id` is already a topic ID, and `topic_id` repeats it to make that unambiguous. `hey box view` also returns `next_page` and accepts `--page <next_page>` to continue a box listing; it keeps `next_history_url` for the sync clients that read it, and `--page` accepts that URL as readily as the cursor inside it. Label IDs come from `hey label list`; `hey label view` returns `next_page` and `total_count`, accepts `--page <next_page>` for continuation, and supports `--all` for complete traversal. HEY creates a label while adding it to at least one thread, so `hey label create` requires thread item IDs.

Collection IDs come from `hey collection list`. `hey collection view` returns both each posting `id` and its `topic_id`, plus `next_page` and `total_count`. Collection membership commands take `topic_id`; posting organization commands continue to take `id`. Creating a collection returns a confirmed mutation, and `hey collection list` provides its ID for subsequent commands. Collection updates accept a non-empty name, summary, or both.

Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/help_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ USAGE
CORE COMMANDS
tui Launch the interactive terminal UI
box List HEY boxes and their email threads
thread Read email threads
thread List and read email threads
reply Reply to a thread
compose Write and send a new email
search Search email threads and messages
Expand Down
Loading
Loading