[feat-010] Pre-render PDFs at upload + shimmer chip + send-button gate
After a PDF upload completes, fire a fire-and-forget vision pre-render
in the background. By the time the user opens a chat against the doc,
the R2 cache is warm and the chat skips the ~10s pdftoppm cost
entirely. Combined with feat-009's caches, first chat against a
freshly-uploaded doc is now near-instant from the user's perspective.
UX:
- Attachment chip in ChatInput shows immediately on attach
- Shimmer overlay (chip-shimmer keyframe in globals.css) plays while
pre-render is in flight - clear visual signal that the chat isn't
quite ready yet
- Send button disabled while ANY attached PDF is pending; tooltip
explains why. Belt-and-braces in handleSubmit so Enter doesn't
sneak past the disabled button
Backend:
- lib/visionPrerender.ts: in-process pending-renders map + R2 lookup
fallback so status survives restarts. kickOffVisionPrerender is
idempotent (no-op if already pending or ready).
- routes/documents.ts (handleDocumentUpload + version upload):
fire-and-forget kick-off after the documents.update completes.
Only PDFs - DOCX vision mode isn't wired.
- routes/projects.ts (project upload): same.
- GET /single-documents/:id/vision-status: returns
{status: pending|ready|failed|missing}. Cheap - combines memory
map with R2 manifest existence check.
Frontend:
- hooks/useVisionStatus.ts: polls vision-status every 1s per attached
PDF until status resolves; caps at 60 attempts so the UI never
locks if the backend goes weird.
- ChatInput uses the hook to drive shimmer + button-disable.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Repository | nwhitehouse/mike |
|---|---|
| Author | Nick Whitehouse <nick.whitehouse@mccarthyfinch.com> |
| Authored | |
| Parents | 4f480f20 |
| Stats | 6 files changed , +453 , -3 |
| Part of | Vision mode: PDF page images → Olava (feat-007a / 008 / 009 / 010 / bug-005) |
Capture this commit into my fork
Download a Markdown prompt that tells Claude how to port this
exact commit into your working tree. Run it via
claude -p < capture-commit-b2840147.md
from inside the repo you want the change in.