2026-07-04 OpenRouter Interceptor Queries UX Features

What I set out to do

Add three UX features to the openrouter-interceptor Firefox extension’s sidebar: (1) a per-analysis model dropdown in the Custom Analysis modal, (2) a reload button on query cards to resend an analysis in place, and (3) character images on Network and Query cards.

What I actually did

Ran the full Superpowers flow: brainstorm → spec → plan → subagent-driven execution. Spec and plan committed under docs/superpowers/. Execution used a fresh implementer subagent per task with a two-verdict review (spec + quality) and fix loops, then a final whole-branch review, across 7 tasks / 9 commits.

Shipped:

  • Shared openrouter-models util — fetch + price-sort + storage.local cache; the options page was refactored to reuse it (killed the duplicated inline fetch/sort/label logic).
  • Model dropdown in the Custom Analysis modal — one-off override that never rewrites the saved default.
  • REANALYZE_QUERY background handler — re-runs a stored query in place (same id), reproducing its persisted customPrompt, optionally on a different model; errors cleanly when the original capture was evicted (100-FIFO). Extracted shared buildAnalysisPrompt / runAnalysis helpers so it can’t drift from ANALYZE_CAPTURE.
  • getCaptureAvatar util + avatar→favicon→placeholder thumbnails on both card types.

Merged to main (fast-forward). typecheck + build + 340 Vitest unit tests green. The two added Playwright assertions are browser-based and still need a run in the real Firefox dev profile.

What was striking

The review layers each caught a real bug the plan’s own reference code carried:

  • Response race in REANALYZE_QUERY — returning the live query object while fire-and-forget runAnalysis mutated query.status; the caller could see completed instead of pending. Fixed by snapshotting { ...query }. ANALYZE_CAPTURE was safe because it calls sendResponse synchronously first.
  • Lit .value-on-<select> desync — Lit commits the parent .value before option children exist, so the dropdown could display a different model than state, and clicking the already-highlighted option fires no change. Fixed with per-option ?selected binding.
  • Missing reload cooldown — the final review flagged that reload had no debounce (unlike analyze), so rapid clicks meant multiple billed OpenRouter calls + leaked poll intervals. Fixed by reusing the existing 2s cooldown and disabling Reload while pending.

Good reminder that “the plan has complete code” doesn’t mean the code is correct — the adversarial review passes earn their keep.

Top 3 tomorrow

  1. Run npm test (Playwright) in the Firefox dev profile to exercise the two new visual assertions.
  2. Manually sanity-check the reload flow end-to-end against a live capture (model switch + evicted-capture error toast).
  3. Consider a one-line test for the untested REANALYZE_QUERY “no system prompt in capture” branch.

Extension project (no vault project note yet). Related prior OpenRouter work is the homelab LLM proxy, which is a separate effort.