Skip to content

Chat replaces Mailbox as the only mail surface - #2

Merged
gstohl merged 4 commits into
mainfrom
claude/chat-navigation-layout-mcgrbe
Sep 5, 2026
Merged

gstohl merged 4 commits into
mainfrom
claude/chat-navigation-layout-mcgrbe

Conversation

@gstohl

@gstohl gstohl commented Sep 5, 2026

Copy link
Copy Markdown
Owner

Summary

Chat (/chat) becomes the one place for encrypted correspondence, and the Mailbox page is retired into it.

  • New Chat surface: three panes on the APP20 dark execution desk. Left: conversations by counterparty with search, unread state and a needs-action filter. Centre: the chronological timeline with inline cards for offers, invoices, escrows, payment memos and backups, plus a quick composer. Right: the contact's wallet identity, open RFQs, pending payments and escrows; selecting an item opens its detail without leaving the conversation.
  • Everything Mailbox did now lives in Chat: key setup and unlock, chain scans, accept/decline/receipt/pay/pay-privately/escrow fill, claim and timeout on the cards, the document composer with attachments, drafts, contact and RFQ-history backups with restore, device safety, the /pay handoff and the Counterparties and RFQ desk handoffs. The Mailbox page's state and handlers moved into useMailboxDesk, so the value paths are the same code.
  • Attribution: MessagePosted has no sender, so a decrypted record joins a conversation only through evidence on the device: an assigned name, a payload claim, the thread a Sent copy opened, or the deal a memo answers. Anything else shows as a sealed sender with an inline naming form; self-backups file under "This mailbox".
  • Routes and links: /mail/inbox, /mail and /inbox redirect to /chat; the Mailbox tab is gone; Pay, Counterparties and the RFQ desk point at Chat. The global RFQ workspace is unchanged.
  • Visual pass: six defects found by driving every state in a real browser at 1440/1024/390/320 were fixed (rail tools overflow, desk scroll jump on locate/send, unstyled backup button, missing glyphs, duplicate Save controls, misleading filtered-empty copy).

Verification

  • npm run test:all (unit, packages, evidence, release-deny, dependency review) passes.
  • Production build gate and bundle budget pass (app entry 390.5 kB of 450 kB).
  • Full Playwright UI suite passes on a fresh localnet (23 tests), with the mail journeys ported to the Chat UI.
  • Docs and README updated for the Chat-only surface.

🤖 Generated with Claude Code

https://claude.ai/code/session_01DL5RB43eSUCvsor8uVPfUa


Generated by Claude Code

…nterparties

Chat reads the mailbox's own device-local records one counterparty at a time:
Sent copies, imported payment links, and the OTC, payment and escrow state
Mailbox persisted while it read the chain, grouped by contact. Nothing is
fetched or posted from the page, and it is not settlement authority.

- The header gains a Chat tab; RFQ, Mailbox, Counterparties and Pay are
  unchanged.
- Left rail: contact name, latest record, unread count, search, and a
  needs-action filter over open offers, unpaid requests and fillable escrows.
- Centre: chronological incoming and outgoing entries with compact record
  cards (offer, invoice, escrow, payment memo) that disclose the full Mailbox
  card, plus a composer that sends a body-only encrypted letter through the
  same policy, helper funding, key lookup, encryption and submit path as
  Compose. Value actions stay in Mailbox.
- Right rail: wallet identity with the RFQ and Mail handoffs, open RFQs
  (bilateral offers, and workspace RFQs naming the contact as maker), pending
  payments and escrows; selecting an entry shows its detail in place and can
  locate it in the conversation.

The eager application shell stays inside its recorded 450 kB budget by
deferring the proposal-only market view and the dry cross-chain review, two
secondary read-only tools; Chat itself loads with its sibling surfaces.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DL5RB43eSUCvsor8uVPfUa
…ad on activation

The new journey registers both fixture mailboxes, has Bob save Alice as a
counterparty, sends an encrypted letter from the Chat composer through the
real localnet helper, confirms the same Sent copy in Mailbox, lets Alice
decrypt it and answer with an offer from Mailbox, and checks that Bob's Chat
reads that offer as work with its context detail, locate, filter and search.

Opening the row that was already auto-selected on load changed no state, so
the effect that marks a conversation's records read never ran. An activation
counter now makes every explicit choice count, matching Mailbox's rule that
the first row on load is not "opened" until someone opens it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DL5RB43eSUCvsor8uVPfUa
Chat now carries everything the Mailbox page did: key setup and unlock
(Onboard), chain scans, decrypted letters grouped by counterparty with
sealed-sender and "This mailbox" buckets, value actions on the cards
(accept, decline, receipt, pay, pay privately with STRK, escrow fill,
claim and timeout), the document composer with attachments, drafts,
contact and RFQ-history backups with restore, device safety, the /pay
handoff, and the Counterparties and RFQ desk handoffs.

- Move the Mailbox page's state and handlers into useMailboxDesk and
  build Chat's rail, timeline, composer, context panel and mailbox tools
  on it; delete the inbox page, Thread, ConversationList and DraftList.
- Attribute a decrypted record by its assigned name, a payload claim,
  the thread a Sent copy opened, or the deal a memo answers; anything
  else stays a sealed sender with an inline naming form.
- Redirect /mail/inbox (and /mail, /inbox) to /chat; drop the Mailbox
  nav link; point Pay, Counterparties and the RFQ desk at Chat.
- Keep record cards open while the desk acts on them, treat an invoice
  awaiting note maturity as pending work, and make record terms
  searchable.
- Port the localnet journeys (app20, chat, private-intents) to the Chat
  UI with shared helpers; update README and docs.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DL5RB43eSUCvsor8uVPfUa
- Rail tools: one shrinkable grid column so a long draft address no
  longer widens every section past the rail; draft rows truncate their
  recipient and keep Delete in view.
- Locating a record or sending a letter scrolls only the timeline;
  scrollIntoView had dragged the overflow-hidden desk up.
- The backup restore action takes the mail sheet's primary style.
- Empty-state glyphs are inline SVG icons instead of missing glyphs.
- The naming and new-address forms hide the address book's own save
  control (new AddressBookField bookActions prop) and drop the rail
  form's oversized label.
- A filtered-out desk says "No conversation matches." with a reset
  instead of claiming the device holds no conversations.
- Counterparties header names the Chat handoff.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DL5RB43eSUCvsor8uVPfUa
@gstohl
gstohl merged commit ba83d31 into main Sep 5, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants