From f7492fec3ef0cfbe202fbb8f352345e7f5ab0133 Mon Sep 17 00:00:00 2001 From: JJ Date: Fri, 17 Jul 2026 13:15:23 +0800 Subject: [PATCH 01/36] docs(specs): widget 3-mode launcher, gallery, recording & share links design Co-Authored-By: Claude Fable 5 --- ...7-widget-modes-gallery-recording-design.md | 219 ++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 docs/superpowers/specs/2026-07-17-widget-modes-gallery-recording-design.md diff --git a/docs/superpowers/specs/2026-07-17-widget-modes-gallery-recording-design.md b/docs/superpowers/specs/2026-07-17-widget-modes-gallery-recording-design.md new file mode 100644 index 0000000..69a2e94 --- /dev/null +++ b/docs/superpowers/specs/2026-07-17-widget-modes-gallery-recording-design.md @@ -0,0 +1,219 @@ +# Widget 3-Mode Launcher, Media Gallery, Screen Recording & Share Links — Design + +**Date:** 2026-07-17 +**Status:** approved by user, ready for implementation planning +**Related:** +- `docs/superpowers/specs/2026-04-27-sdk-wizard-redesign-and-attachments-design.md` (current 3-step wizard + user attachments) +- `docs/superpowers/specs/2026-04-18-session-replay-design.md` (30s rolling DOM replay — unchanged here) +- `docs/superpowers/specs/2026-04-18-intake-anti-abuse-design.md` (rate limiting / origin allowlist reused by the media endpoint) + +--- + +## 1. Problem + +The widget today is single-purpose: the launcher opens the bug-report wizard, which force-fires the OS screenshot dialog before anything else. User feedback asks for a broader capture toolkit: + +- Capture a screenshot, annotate it, and *keep it* without filing a report. +- Record the screen (short clip, ≤ 5 minutes), trim the ends, and either attach it to a report or **share it as a link** (paste into Discord, a spreadsheet, a chat). +- Report a bug in two steps (Details → Review) choosing media from previously captured items, instead of being forced through capture-first. + +Nothing in the current stack supports video, local media persistence, or report-less uploads. + +## 2. Goals + +- Launcher opens a 3-option menu: **Capture**, **Record screen** (max 5:00), **Report bug**. +- Capture and Record flows end with **Save to gallery / Discard / Report bug with this**. +- A local, per-origin media gallery persists captures and recordings across page loads. +- Recordings support start/end trim. +- Report Bug becomes 2 steps (Details → Review) with a gallery media picker plus in-flow quick capture/record. +- Any gallery video can be turned into an unguessable public share URL served by the dashboard, with per-project retention and revocation. +- Diagnostic context (30s replay, console/network/system logs) still auto-attaches to every report exactly as today. +- Everything remains additive and backward compatible: old SDKs work against new servers; new SDKs degrade gracefully against old servers. + +## 3. Non-goals (v1) + +- Audio of any kind in recordings (no mic, no explicit tab-audio UX). +- Real video cutting (re-encode client- or server-side). Trim is playback metadata only. +- Cross-device or server-synced gallery; gallery is per browser profile + origin. +- Expo SDK screen recording (OS-level limitation; mobile keeps its current flow). +- Share links for images (videos only in v1 — images can already be attached to reports; extendable later). +- Share-link view analytics, password-protected links, link expiry UI beyond project retention. +- Editing recordings beyond trim (no crop, blur, zoom). + +## 4. Locked decisions + +1. **Gallery model: local-first, upload on demand.** Gallery lives in IndexedDB (per origin). Nothing uploads until the user attaches media to a report or mints a share link. +2. **Trim: metadata only.** In/out timestamps stored with the item; every player (gallery preview, dashboard report drawer, public share page) clamps playback to the range. The raw file keeps full length — a raw download shows everything; acceptable for v1 and called out in the share page footer. +3. **Report Bug: gallery picker + quick-capture.** No forced OS dialog on open. Details step offers gallery items plus "Capture now" / "Record now" detours that return with the new item pre-selected. +4. **Share links: unguessable public URL + retention.** No auth wall. Per-project toggle (default **on**) and retention window (default **30 days**), scheduled purge, revoke list in project settings. +5. **No audio in v1.** +6. **Recording bitrate capped** (~2.5 Mbps video) so a maxed 5:00 clip stays under ~100 MB. + +## 5. Architecture + +### 5.1 SDK — packages/core + +``` +packages/core/src/ +├── screen-record.ts # NEW — getDisplayMedia + MediaRecorder state machine +└── index.ts # public API additions +``` + +- `screen-record.ts` exposes `startScreenRecording(opts) → RecordingSession`: + - `getDisplayMedia({ video: true, audio: false })`; user gesture + secure context required — on rejection/unsupported, surface a friendly toast and abort. + - `MediaRecorder` with `videoBitsPerSecond: 2_500_000`, `timeslice: 1000`; chunks accumulate in memory. + - Auto-stop at 5:00 (constant `MAX_RECORDING_MS`), or on stream `ended` (user clicks browser's native "stop sharing"), or on explicit stop. + - `pagehide` handler: best-effort assembly of collected chunks into a gallery item so a mid-recording tab close doesn't lose everything. +- Public API additions on the handle returned by `init()`: + - `feedback.openMenu()` — opens the 3-option menu (launcher click and keyboard shortcut route here). + - `feedback.capture()` — jumps straight into the capture flow. + - `feedback.record()` — jumps straight into the record flow. + - `feedback.open()` — unchanged: opens Report Bug directly (backward compatible; the queued prefill API extends this later). + +### 5.2 SDK — packages/ui + +``` +packages/ui/src/ +├── menu.tsx # NEW — 3-option launcher menu +├── gallery/ +│ ├── store.ts # NEW — IndexedDB CRUD + quota eviction +│ ├── gallery-view.tsx # NEW — grid, preview, delete, copy-link, report-with +│ └── thumbnail.ts # NEW — image downscale / video poster frame +├── record/ +│ ├── control-bar.tsx # NEW — floating timer + stop/cancel while recording +│ ├── trim-screen.tsx # NEW —