add a transmission sidecar and ui
officer-transmission is a new pm2 peer that owns the transmission rpc
connection and exposes a curated /_officer/* contract instead of proxying
raw rpc. it absorbs the three quirks callers otherwise have to know about:
the 409 x-transmission-session-id handshake, failures returned as
{"result": "..."} inside http 200, and basic auth where an empty username
must send no header at all.
/transmission is the ui, on the workspace/panel framework: a filter nav and
three sections (torrents, stats, settings). the torrent list is virtualised
with 30 available columns, multi-select, and a right-click menu; the detail
pane covers general, files as a real tree, peers and trackers. filters and
the open torrent live in the url, so a filtered view is a link.
phase 1 goal was parity with _references/transmission-web. follow-up work is
recorded in TODO.md.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -72,6 +72,36 @@ Deferred work. Context: Officer is collapsing from multi-tenant / open-source-re
|
||||
as one of the tabs (main view).
|
||||
- Open question: tabs vs. some other view switcher; which view is default.
|
||||
|
||||
## Transmission
|
||||
|
||||
Phase 1 (parity with `_references/transmission-web`) shipped 2026-07-30: the `officer-transmission`
|
||||
sidecar plus `/transmission` (torrents / stats / settings). Everything below is **phase 2** — none of
|
||||
it exists in the reference app, so none of it was in scope for parity.
|
||||
|
||||
### Probably needed regardless
|
||||
|
||||
- [ ] **Resizable detail pane.** `TorrentsView` pins it at `DETAIL_HEIGHT = '45%'`, which is a guess.
|
||||
Either a drag handle or a persisted height in `useLocalStorageState`, alongside the column set.
|
||||
- [ ] **Revisit `DEFAULT_VISIBLE_COLUMNS`.** Eleven of thirty, chosen before ever seeing the table
|
||||
rendered against the real 43-torrent library. Likely wrong in both directions.
|
||||
- [ ] **Files tab on huge torrents.** `detail/FilesTab.tsx` builds the whole tree and renders every
|
||||
node — no virtualisation. Fine at 14 files; unknown at a few thousand. If it stalls, the fix is
|
||||
`useVirtualizer` over a flattened visible-node list, the same shape as `TorrentTable`.
|
||||
|
||||
### Ideas, unprioritised
|
||||
|
||||
- [ ] **Container→host path mapping.** The daemon reports its own namespace (`/downloads/complete`),
|
||||
which is not a path on this host. A mapping table (`/downloads` → `~/hdds/08_TB_01/Torrents`,
|
||||
`/downloadsTV` → `14_TB_02/Torrents`) would make locations clickable through to `/files` and
|
||||
make "Set location" offer real destinations. Deliberately dropped from phase 1: the reference
|
||||
app has no such feature, so it would have been config nothing read.
|
||||
- [ ] **Push instead of poll.** Transmission RPC has no push channel, so `useTransmissionData` polls
|
||||
every 5s. The sidecar could poll once and fan out over a WebSocket, which is both cheaper and
|
||||
what every other live surface in the platform already does.
|
||||
- [ ] **Cross-surface links.** Soulseek and `download-media` both land files in the same library;
|
||||
Transmission is the third door to it. Worth a think about whether they should know about each
|
||||
other at all.
|
||||
|
||||
## Known bugs
|
||||
|
||||
- [ ] **`bootstrap.ts` runs `npm install -g` for Pi on every boot.** `findPiPackageDir` checks stale
|
||||
|
||||
Reference in New Issue
Block a user