Files
vdm/docs/agents/AGENT-EXT.md
T
samiandClaude Opus 5 8bb683b09d scaffold: project structure, wire contract, roadmap and agent briefs
Lays out Velox Download Manager (IDM-class download manager for Ubuntu
26.04) as a monorepo ready for parallel lane development. No implementation
code by design.

- docs/: architecture, roadmap M0-M7, IDM-parity GUI spec, engine design,
  Firefox extension spec, risks/spikes, packaging
- contracts/: wire-contract skeleton (JSON Schema + fixture templates) —
  the single synchronization point between lanes
- docs/agents/: one brief per lane (PROTO, CORE, DAEMON, GUI, EXT, PKG/QA)
  with owned directories, build order and definition of done
- CLAUDE.md: rules of engagement — lane ownership, layering, non-negotiables
- CMake scaffolding with dev/tsan/release/ci presets

Two environment findings shape the design: Firefox here is the Mozilla snap
(native-messaging risk, so the extension carries a loopback-WebSocket
fallback), and Wayland forbids passive clipboard monitoring (so clipboard
capture is explicit-action-first).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-09 18:21:11 +04:00

68 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Agent brief — EXT (Firefox extension)
**Starts the day PROTO freezes the contract. Develops against `tools/mockd` over the
WebSocket transport — you never wait for `veloxd`.**
## You own
```
extension/**
```
Read `contracts/`, `docs/`. Never write in `core/`, `daemon/`, `gui/`, or `nmhost/`
(the native host belongs to DAEMON; if you need a change there, file it).
## Read first
`docs/05-extension-spec.md` in full, then `docs/06` R1 (snap Firefox) and R3 (AMO).
## Your first task is a spike, not code
**Spike S1 (2 days, blocks nothing else):** on a clean Ubuntu 26.04 VM with snap Firefox,
determine empirically which of the four native-messaging manifest locations actually work,
and whether the launched host can reach `$XDG_RUNTIME_DIR`. Write
`docs/adr/0003-native-messaging-under-snap.md`. Then build the WebSocket transport first
regardless of the answer — it is the one that is known to work here
(`snap connections firefox` shows `network`/`network-bind` connected).
## Build order
1. **`transport/`** — the `Transport` interface, `WebSocketTransport` (port discovery over
5200052016 + `session.hello` verification), pairing flow with token in
`browser.storage.local`, reconnect with backoff, then `NativeTransport`, then
`transport/index.ts` picking at runtime with a manual override in Options.
2. **`capture/headers.ts`** — `onBeforeSendHeaders` stash keyed by `requestId`, ring buffer,
5-minute TTL, bounded size (a leak here eats the browser's memory).
3. **`capture/rules.ts`** — `shouldCapture()` exactly as specified in `docs/05` §2.
**Table-driven tests before implementation.** This function is where the bugs will be:
too eager and you hijack page navigations; too shy and you're not a download manager.
4. **`capture/index.ts`** — the `onHeadersReceived` blocking hook: gather cookies, call
`capture.offer` with a **750 ms budget**, `{cancel: true}` only on `take`.
**Fail-open is a hard requirement** — daemon down, slow, or erroring means Firefox
downloads normally. Write that test before the feature.
5. **`capture/downloads-api.ts`** — the `downloads.onCreated` safety net for what slips past.
6. **`context-menus.ts`**, **`popup/`** (live progress from relayed events, pause/resume,
status dot), **`options/`** (transport, pairing/unpair, monitored types synced via
`capture.getRules`, min size, exclusions, default category, bypass modifier).
7. **`content/` media detection** — `.m3u8`/`.mpd`/MIME sniffing plus a `MediaSource`
observer; in-page "Download this video ▾" panel listing variants from
`media.listVariants`. **The extension never parses manifests** — the daemon does.
Detect DRM/EME and grey the button out with "Protected content".
## Definition of done (M1)
- Intercepts a real download in real Firefox and hands it to `mockd`.
- **Fail-open proven by an automated test:** kill the mock mid-flow, the file still
downloads through Firefox, no error dialog, no lost download.
- Pairing works, unpair revokes, token survives a browser restart, and a wrong token is
rejected and rate-limited.
- `web-ext lint` clean; no remote code, no `eval`, no CDN script — AMO rejects those.
- `shouldCapture` test table covers: attachment, monitored extension, monitored MIME,
size threshold, excluded host, HTML navigation, blob URL, bypass modifier held,
streaming media, and a range request the page itself issued.
- Popup shows live progress at ≤ 4 Hz without pinning a core.
- Permission justification written and committed for AMO submission.
## Do not
- Do not implement any download logic in the extension. You collect URL + headers + cookies
and hand them over. That's the whole job.
- Do not add a framework (React/Vue) for a popup and an options page; plain TS keeps the
AMO review and the bundle small.
- Do not invent protocol fields — file a request with PROTO.