Open a bundle's mail from the CLI with hey bundle view and hey contact threads - #378
Open a bundle's mail from the CLI with hey bundle view and hey contact threads#378jeremy wants to merge 3 commits into
Conversation
…t threads A bundle row names a contact rather than a thread, so hey box view listed it with no topic_id and nothing could read it — a third of a bundled Imbox was unreachable outside the TUI. The SDK operations the TUI proved out now back two CLI listings: hey bundle view <box-item-id> pages the unseen threads a bundle groups, and hey contact threads <contact-id> pages every thread with its sender, which is where a read-through bundle's mail lives. Both ride the existing postings listing through two new mail.Source kinds, so they answer every output format and cursor the box, label and collection listings do. A bundle with no unseen threads says where its mail went instead of showing an empty page. The failure stops lying too: hey thread read handed a bundle row's own id used to 404 as "not found", which agents read as "no content". A not-found now gets checked against the bundle route, and when it answers, the error names the bundle and both commands that read it.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
Pull request overview
Adds CLI access to bundled mail, fixing #156 by reusing mail.Source pagination and improving bundle-ID errors.
Changes:
- Adds
hey bundle viewandhey contact threads. - Extends mail sources and pagination for bundles and contacts.
- Improves help, diagnostics, tests, and command-surface snapshots.
Tip
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
.surface |
Records new commands and flags. |
AGENTS.md |
Documents bundle and contact sources. |
internal/cmd/box.go |
Adds bundle guidance to box listings. |
internal/cmd/bundle.go |
Implements bundle listing commands. |
internal/cmd/bundle_test.go |
Tests new CLI behavior and errors. |
internal/cmd/contacts.go |
Registers contact threads. |
internal/cmd/contacts_show.go |
Cross-references contact threads. |
internal/cmd/contacts_threads.go |
Implements contact-thread listings. |
internal/cmd/help.go |
Adds bundle to MAIL help. |
internal/cmd/help_test.go |
Updates help snapshot. |
internal/cmd/postings_listing.go |
Supports meaningful empty-list notices. |
internal/cmd/root.go |
Registers the bundle command. |
internal/cmd/thread_source.go |
Diagnoses bundle IDs used as thread IDs. |
internal/mail/page.go |
Reads bundle and contact pages. |
internal/mail/page_test.go |
Tests the added page readers. |
internal/mail/source.go |
Adds bundle and contact source kinds. |
internal/mail/source_test.go |
Tests the new source constructors. |
internal/tui/mail.go |
Handles new source kinds in navigation switches. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7aba839d4f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The README's listing inventory and Email examples now carry hey bundle view and hey contact threads, per the command-documentation rule. Smoke coverage discovers a bundle row in the Imbox — bundling an Imbox sender when the seed data has none — and exercises bundle view, the thread-read misread error, and contact threads with its pagination flags. The contact fixture's real-domain address becomes a reserved example domain.
There was a problem hiding this comment.
All reported issues were addressed across 4 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
There was a problem hiding this comment.
1 issue found and verified against the latest diff
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="internal/mail/page.go">
<violation number="1" location="internal/mail/page.go:153">
P2: When HEY returns `X-Total-Count` for a bundle or contact page, these readers discard it and report `Page.Total == 0`. Preserve `result.TotalCount` in both new `Page` values so generic listings can report accurate totals and truncation notices.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
A contact picked off the contact list may have no threads at all, which reads as a pass without listing anything. An Imbox sender has at least one thread on record, so the listing is asserted non-empty as well.
Fixes #156. Tracking: Basecamp card
A bundle row names a contact rather than a thread:
hey box viewlists it with notopic_id, and every plausible read —hey thread readwith the posting id or the contact id — answered not-found. In the reporter's 500-posting Imbox sample, a third of the box was unreachable from the CLI. The TUI fixed this (f22746a…782e536) through two SDK operations,Postings().BundleUnseenPageandContacts().ThreadsPage, and until now the TUI was their only caller.hey bundle view <box-item-id>lists the unseen threads a bundle groups — the case the web app opens as the bundle view. The JSON carries the bundled contact next to the postings, because the contact id is what reads the rest once these threads are seen. A bundle with no unseen threads is not shown as an empty page; the notice says everything has been read and points at the contact's list.hey contact threads <contact-id>lists every thread with a contact, seen and unseen — HEY's "All threads with …" list, and the only place a read-through bundle's mail lives, since a read bundle names no topic. This also replaces the undocumented single-page workaround throughhey contact show's embedded postings, whichcontact shownow cross-references.Both are new
mail.Sourcekinds riding the existing postings listing, so they answer--json,--styled,--markdown,--ids-only,--count, and the--limit/--all/--pagecursors exactly as the box, label and collection listings do.The failure stops lying. The sharpest point in #156: an agent that substitutes the bundle row's own id into
hey thread readgot a bare 404 and reported "no content" — silently wrong on exactly the senders worth automating. A thread-read not-found is now checked against the bundle route (one extra request, on the error path alone); when it answers, the error says the id is a bundle, names the sender, and gives both commands that read it. Any other id 404s on the probe too and keeps its original error.Box listings and agent notes now say what a
kind: "bundle"row is and how to open it, andhey bundlesits in the MAIL help category.TMPDIR=/tmp/t make checkgreen, including the regenerated.surface.Summary by cubic
Fixes #156. The CLI can now open a bundle's mail, which
hey box viewlisted but nothing could read — a bundled Imbox was unreachable outside the TUI.hey bundle view <box-item-id>lists a bundle's unseen threads, andhey contact threads <contact-id>lists every thread with a contact, seen and unseen — the only place a read-through bundle's mail lives.Both ride the existing postings listing, so they answer
--json,--styled,--markdown,--ids-only,--count, and the--limit/--all/--pagecursors like the box, label, and collection listings do. A bundle with no unseen threads says where its mail lives instead of showing an empty page. README and agent notes document the new commands, and smoke tests cover them against a real server.Error path
hey thread readwith a bundle row's own id no longer answers bare "not found"; the 404 is probed against the bundle route and the error names the bundle and both commands that read it.hey contact threadsreplaces the single-page workaround viahey contact showembedded postings, which now cross-references it.kind: "bundle"rows, andhey bundlesits in the MAIL help category.Written for commit d3032fb. Summary will update on new commits.