Share → Queue → Media

How a "share a link from my phone and process it later" system would work — plan & mockup, nothing built.

The short answer: you don't need a new app or an MCP server. Your Dictate PWA already declares an Android share target, and your Mac already runs a 20-second watcher loop that turns queued items into articles, infographics, decks and sends. A shared YouTube link is just a new source kind for that same machine. Net new work is roughly two files: fix the share handler to accept a URL, and add one resolver module.

Annotated architecture: Android share sheet to PWA share-target to Vercel Blob queue to Mac watcher shares.py resolver to existing actions to inbox
Green = already built & running · Amber = the ~2 files of new work. Open full-size diagram →

How it works, end to end

  1. You tap Share in YouTube / a browser / a PDF and pick your tool. Android renders that sheet — you get essentially one tap, no custom UI.
  2. The PWA /share-target receives the payload. REUSE the manifest already declares it — NEW the handler currently only reads audio files and silently drops links; it needs to also read the url/text field. (This is the one true P0 — a shared link goes nowhere today.)
  3. It writes share-queue/<id>.json to Vercel Blob as queued. Capture is done; the phone can sleep. REUSE
  4. The Mac watcher (already looping every 20s, server-side) claims it and runs a new shares.py resolver: NEW turn the URL into text — YouTube captions first (falling back to yt-dlp + Whisper), articles via Trafilatura/Jina Reader, PDFs via PyMuPDF/Gemini.
  5. Resolved text flows into your existing "⏱ When ready" actions — Summarize, Draft Article, Infographic (Nano Banana), Presentation, Send ▸ Telegram/Email — and lands in the Inbox as artifacts. REUSE

The interaction (what you'd actually do)

Default is frictionless capture: sharing just drops the item in an Inbox as queued; you assign or auto-fire actions later. On top of that, the moment you share, the app opens to the new card with an optional 3-chip route row💾 Just save · ✍ Transcribe + article · 🗂 Media pile — defaulting to your last choice.

FlowTapsResult
YouTube video → article3 (Share → your tool → "Transcribe + article")Drafts server-side, delivery fires when ready — phone closed
Report / PDF → read later2 (Share → your tool; do nothing)Sits in "Ready to triage," zero processing cost

A safety rule both reviewers insisted on: an idle timeout only ever lands an item as saved — an active agent never fires on a timeout, only on an explicit tap.

What the personas said

🏛 Architect / computer scientist

Verdict: extend the watcher, don't build a service. Everything hard here (yt-dlp, ffmpeg, Whisper, headless Chromium, long transcriptions) is native-binary and long-running — exactly what Vercel functions are bad at and the Mac watcher is already for.

  • Two-phase record: resolve → act, with resolved_text made immutable, so an action retry never re-hits yt-dlp and a resolve retry never re-runs a paid infographic.
  • Captions before download — lowest ToS/IP exposure; --cookies-from-browser from your harvested session beats the bot-check.
  • Quality gate before any LLM — if a paywall returns junk, save the link, never fabricate.
  • Scope v1 to YouTube + article + PDF; degrade Twitter/paywalls to "saved link" on purpose.

📱 Android / UX designer

Verdict: fold into Dictate, but re-shell it. The engine is identical; a second app means a second install, share-target registration, auth and a split inbox.

  • Rename the mental model from "voice notes" to Capture / Pile; voice, link and PDF become kinds, each with a chip.
  • Write-first, render-second share handler so a slow cold start never loses the item; confirm with a system notification.
  • Inbox grouped by status (Resolving / Ready / Done); swipe-right to file; live global progress pill.
  • Watch three known Android gotchas: share icon not appearing until the PWA is "engaged," cold-start latency, ambiguous success feedback.

The record & state machine

Mirrors your dictate-queue style, one doc per item:

queued → resolving → resolved → running(actions) → done  · errors back off with an attempts counter, then parked for review; stale claims are reclaimed after a TTL so a crash never wedges the loop. Fields: id, source_url, url_hash, kind, resolver, status, stage, progress, resolved_text/ref, quality, pending_actions[], artifacts[], attempts, error, timestamps.

Top risks & how the design handles them

RiskMitigation
yt-dlp breaks / YouTube bot-blockCaptions API first (no download); auto-updated yt-dlp; cookies from your session; back off; degrade to saved link. Never kills the loop.
Poison item (3-hr video, 500-pg scan)Per-item try/except; hard subprocess timeouts; duration/size caps; chunk + map-reduce; cheap Gemini for bulk, Fable for final prose.
Garbage scraped text → confident wrong articleQuality gate (word count + boilerplate ratio) before any LLM; fallback ladder; if all fail, save the link.
/share-target swallows the URLAccept both url and text (many launchers send links as text), regex the first URL; test across Chrome/YouTube/Twitter apps.

Two calls that are yours to make

1 · Fold into Dictate, or a new surface? Both reviewers say fold it in — same queue, watcher, actions, zero new plumbing. The only snag is the name: "Dictate / voice notes" is wrong once the input is a YouTube URL. Recommendation: rename the shell to a "Capture" model (voice/link/PDF are just kinds) and update its info.arnao.ai card per your auto-catalog rule. Building a second app is cost with no capability gain.

2 · v1 scope. Ship YouTube + article + PDF solid; deliberately let Twitter threads and hard paywalls degrade to "saved link" rather than chase a scraping treadmill. Expand later if you actually miss them.

Related

Plan & mockup only — nothing was built or deployed into the live Dictate app. Personas: senior systems architect / computer scientist and senior Android UX designer. Diagram rendered with Nano Banana Pro (Gemini 3 Pro Image). Prepared for Byron · 2026-08-08 · noindex.