From afaeaa0d43749f5cae25a4aab145b029b663c32b Mon Sep 17 00:00:00 2001 From: Luna Date: Fri, 10 Jul 2026 06:44:03 -0700 Subject: [PATCH] docs: spec for kind-aware remote editor (phase 2) Inherits the federation-editor spec; adds RemoteClientKind enum (catacomb | peertube), kind selector + conditional username field in both editors, kind in the API, kind-branched test-connection, and a phase-3 stopgap for browsing PeerTube remotes. Co-Authored-By: Claude Opus 4.8 --- ...eration-editor-phase2-kind-aware-design.md | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 docs/superpowers/specs/2026-07-10-federation-editor-phase2-kind-aware-design.md diff --git a/docs/superpowers/specs/2026-07-10-federation-editor-phase2-kind-aware-design.md b/docs/superpowers/specs/2026-07-10-federation-editor-phase2-kind-aware-design.md new file mode 100644 index 0000000..cda56ea --- /dev/null +++ b/docs/superpowers/specs/2026-07-10-federation-editor-phase2-kind-aware-design.md @@ -0,0 +1,146 @@ +# Kind-aware remote editor (phase 2) + +**Date:** 2026-07-10 +**Status:** Approved design, ready for implementation plan +**Scope:** Desktop GUI + web server. Sub-project 2 of the PeerTube federation work. + +## Context + +Phase 2 of three (see `2026-07-10-peertube-client-backend-design.md` §Context). +Phase 1 (backend `PeerTubeClient` + `RemoteKind`/`username` config) is **done**. +This phase adds the in-UI editor to manage remotes of *both* kinds, applied +live. + +**Inherits** `2026-07-10-federation-remote-editor-design.md` wholesale for the +unchanged editor mechanics — read it first. Unchanged from that spec: +- `WebState.remotes` becomes a `std::sync::RwLock<…>`; browse endpoints + read-lock, the editor save write-locks (live-apply). +- Dedicated `/api/remotes/*` endpoints (not folded into `SettingsPayload`): + extended `GET`, new `PUT` (whole-list replace), new `POST /api/remotes/test`. +- Web passwords are masked / write-only; blank on save keeps the stored secret, + matched by URL (`merge_remote_passwords`, pure + unit-tested). Desktop shows + passwords in the clear (local). +- Config source of truth is `state.config` (`state.config.lock_recover()`); + save via `config.save`; on save error, don't swap the live list; drop the + config lock before taking the remotes lock. +- After any edit, both UIs refetch the list and clear the current selection. + +This document specifies only the **kind-aware deltas**. + +## Delta 1 — Multi-kind live storage + +New enum in `src/remote.rs`: + +```rust +pub enum RemoteClientKind { + Catacomb(RemoteClient), + Peertube(crate::peertube::PeerTubeClient), +} + +impl RemoteClientKind { + pub fn from_section(cfg: &crate::config::RemoteSection) -> Self { + match cfg.kind { + crate::config::RemoteKind::Catacomb => Self::Catacomb(RemoteClient::new(cfg)), + crate::config::RemoteKind::Peertube => Self::Peertube(crate::peertube::PeerTubeClient::new(cfg)), + } + } + pub fn name(&self) -> &str { + match self { Self::Catacomb(c) => &c.name, Self::Peertube(p) => &p.name } + } + pub fn kind(&self) -> crate::config::RemoteKind { + match self { + Self::Catacomb(_) => crate::config::RemoteKind::Catacomb, + Self::Peertube(_) => crate::config::RemoteKind::Peertube, + } + } +} +``` + +- `App.remotes: Vec>` (desktop; mutable App, no lock). +- `WebState.remotes: RwLock>>` (web; per inherited + spec). Built at startup with `RemoteClientKind::from_section` per config + remote. +- Both fronts rebuild the whole `Vec` on editor save. + +`RemoteClient.name` must be `pub` (it already is); `PeerTubeClient.name` is `pub` +(phase 1). + +## Delta 2 — Browse dispatch (phase-2 stopgap) + +The existing browse call-sites match on the enum: + +- **Web** `get_remote_library` (positional `:id`): read-lock; match the entry: + - `Catacomb(c)` → `c.library_json()` (unchanged behavior). + - `Peertube(_)` → `501 Not Implemented` / body `"PeerTube browsing arrives in + phase 3"`. +- **Desktop** `start_remote_fetch(idx)`: match the entry: + - `Catacomb(c)` → spawn the existing `c.library()` fetch (unchanged). + - `Peertube(_)` → set `remote_status = "PeerTube browsing arrives in a later + update"`, no fetch. + +So a PeerTube remote is fully manageable (add/edit/test/save) in phase 2; +*browsing* it is phase 3. Catacomb browsing is untouched. + +## Delta 3 — Editor UI + +The inherited "Federation peers" Settings section, each row gaining: +- a **kind** selector — Catacomb / PeerTube (`egui::ComboBox` desktop; `