Files
vdm/docs/agents/AGENT-GUI.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

57 lines
3.0 KiB
Markdown

# Agent brief — GUI (`velox-gui`)
**Starts the day PROTO freezes the contract. You never wait for the daemon — you develop
entirely against `tools/mockd`.**
## You own
```
gui/**
```
Read `contracts/`, `docs/`. Never write in `core/`, `daemon/`, or `extension/`.
## Read first
`docs/03-gui-spec.md` — it is the spec, screen by screen. Build in the order below.
## Build order
1. **`rpc/` client** — wrap the generated C++ client: async calls on a worker thread,
Qt signals on the main thread, auto-reconnect with exponential backoff, an offline
banner instead of a modal error, and a "Connected/Reconnecting" dot in the status bar.
Get this right first; everything else depends on it.
2. **`models/DownloadTableModel`** — `QAbstractItemModel` over `TaskSummary`. Apply
`event.task.progress` batches as **row patches with narrow `dataChanged` ranges**.
Never `beginResetModel()` on a progress tick. Sorting/filtering via `QSortFilterProxyModel`
per category tree selection.
3. **Main window** — menus, toolbar, splitter, category tree, table, status bar, column
persistence in `QSettings`.
4. **`widgets/ProgressDelegate`** — the in-cell progress bar; also
`SegmentBarsWidget` and `SpeedGraphWidget` (60 s rolling, 1 Hz, painted with
`QPainterPath`, no per-frame allocation).
5. **Dialogs**, in this order: Add URL → Download File Info (async probe, spinner while it
resolves) → Download Progress → Options (all tabs, every control bound to a
`settings.*` key that exists in the schema) → Scheduler → Speed Limiter → Batch →
Grabber wizard.
6. **Tray + floating drop target** — frameless always-on-top drop widget accepting dropped
URLs and text; position persisted.
7. **Clipboard**`clipboard/monitor.*`, but read `docs/06` R2 first: this is
best-effort under Wayland. Implement the **explicit** paths (Add-URL prefill, portal
global shortcut) as the primary UX and treat passive monitoring as a bonus that spike S2
may or may not unlock. **Don't advertise it in the UI until S2 answers.**
8. **Theming**`resources/qss/idm-like.qss` + `dark.qss`, colours in one variables block,
follow `QStyleHints::colorScheme()`.
## Definition of done (M1)
- Every screen in `docs/03-gui-spec.md` exists and is driven **only** by `mockd`.
- 10 000 synthetic rows: scrolling holds 60 fps, memory flat over 10 minutes of progress
events (`mockd --tasks 10000`).
- Unhappy paths handled: `mockd --slow`, `--flaky`, `--drop-connection` produce a banner
and a clean recovery, never a freeze or a crash.
- Zero download logic in `gui/` — grep for `curl`, `pwrite`, `sqlite` must return nothing.
- All strings wrapped in `tr()`; a stub Arabic `.ts` proves the RTL layout survives.
- No blocking call on the UI thread: verified with a 200 ms watchdog in debug builds.
## Icons
Ship an **original or compatibly-licensed** icon set (Papirus/Breeze-derived is fine) laid
out in IDM's positions. Do not copy IDM's artwork. Record the icon licence in
`gui/resources/icons/LICENSE`.