Adds two new arms to the AttachmentPreview kind dispatcher:
* PDF — chip in the bubble, click opens the shared AttachmentLightbox
with a browser-native <embed type="application/pdf"> at 95vw/90vh.
Fetch+Blob+ObjectURL auth path matches AttachmentImage / Video. PDF.js
not pulled in; browser viewer is good enough for the desktop chat MVP
(Slack/Linear/Notion all gate full-page PDF behind a click for the
same reason). Falls back to AttachmentChip on fetch error.
* Text/code/JSON/YAML — first 10 lines in monospace <pre><code> right
in the bubble, "Show all N lines" expands to full content, with a
filename + ⬇ download header. Streams up to 256 KB then marks
truncated and offers a download chip; large logs don't crash the
bubble. No syntax highlighting in v1 — shiki adds 200-500 KB and is
pure polish.
Coverage: 5 new dispatch tests (PDF success → embed in lightbox,
PDF fetch fail → chip fallback, text inline render, text long content
→ Show-all-N-lines expand button, text fetch fail → chip fallback).
All 19 AttachmentPreview tests pass; tsc --noEmit clean.
Stacked on rfc-2991-pr-1-image-preview-lightbox (PR-2 already merged
into PR-1's branch). PR-1 ships first; this rebases onto staging
once it lands.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>