# crabidy A client/server music player. A headless gRPC server owns the library, the play queue, and audio output; a terminal UI connects to it over localhost (or the network). Media comes from pluggable **providers**, each mounted as a subtree of one library: ```text / ├── tidal Tidal streaming (see tidaldy/README.md) ├── youtube YouTube search & playlists (see ytdy/README.md) ├── fs a local music folder (see fsdy/README.md) ├── queues saved play queues (managed by the server) ├── bookmarks link snapshots of library subtrees (`w`) └── captures downloaded snapshots with local audio (`W`) ``` ## Binaries - `crabidy-server` — the server: providers, queue, playback, gRPC on `0.0.0.0:50051`. Also serves the web client at that address (see below). - `cbd-tui` — the terminal client. Press `?` inside for all key bindings. - `cbd` — both in one process: starts the server, waits until it accepts connections, then runs the TUI. Adopts an already-running server instead of failing on an occupied port. - `cbd-web` — the browser client (Leptos/WASM), with the same functionality as the TUI. Not run directly: it is built to a bundle and embedded into `crabidy-server` (see [cbd-web/README.md](cbd-web/README.md)). ## Quick start The toolchain is managed by [devenv](https://devenv.sh): ```sh devenv shell # provides rust, yt-dlp, and friends cargo run -p cbd # server + TUI in one process ``` Or run the halves separately: `cargo run -p crabidy-server` and, in another terminal, `cargo run -p cbd-tui`. ## Configuration All configuration lives in `~/.config/crabidy/` (the platform config directory). Every file is optional; missing providers simply do not mount. Files are created/rewritten on first start with their defaults filled in. | File | Component | Documentation | | -------------------- | --------- | -------------------------------------- | | `tidaly.toml` | Tidal | [tidaldy/README.md](tidaldy/README.md) | | `ytdy.toml` | YouTube | [ytdy/README.md](ytdy/README.md) | | `fsdy.toml` | local fs | [fsdy/README.md](fsdy/README.md) | | `cbd-tui.toml` | TUI / cbd | below | | `crabidy-server.toml`| server | below (never auto-created) | The server-managed folders (`queues/`, `bookmarks/`, `captures/`) also live in `~/.config/crabidy/`; they need no configuration and hold plain folders of track files in the format documented in [fsdy/README.md](fsdy/README.md). ### `cbd-tui.toml` Configuration of the TUI (and the TUI half of `cbd`): ```toml # Where to find the server. Default shown. address = "http://127.0.0.1:50051" # Credentials, when the server has [auth] configured (see below). # `user` is the role name; leave both empty against an open server. # The password is stored in plaintext — keep this file private. user = "" password = "" ``` Every option is also available as a command-line flag (`cbd-tui --address ...`). ### `crabidy-server.toml` — roles and rights By default the server is open: everyone who can reach the port has full control. Adding an `[auth]` section turns on HTTP basic auth for every RPC and hands out *roles* (see `architecture/roles-auth.md`): - **owner** — everything (the normal user). - **queue-owner** — anything on the queue and playback, but no library writes: no bookmarks (`w`), captures (`W`), queue saving, renames or deletes. - **queue-appender** — may browse/search and append tracks to the queue; nothing else. ```toml [auth] # One PHC hash per role; omit a role to disable it. Generate with: # crabidy-server hash-password (reads the password from stdin) owner = "$argon2id$v=19$m=19456,t=2,p=1$..." queue_owner = "$argon2id$..." queue_appender = "$argon2id$..." ``` Clients authenticate with the role name as the basic-auth user (see `cbd-tui.toml` above). A malformed `crabidy-server.toml` aborts server startup rather than silently running open. Note that the transport is plain HTTP/2: fine on a trusted home network, but anything exposed further needs TLS termination (reverse proxy, VPN) in front. ## Using the library Navigation is vim-style: `j`/`k` select, `l` enters the selected folder, `h` goes to the parent, `Tab` switches between library and queue, `Enter` replaces the queue with the selection. `%` creates a node where the pane title shows `% to add` (e.g. a search term), `e` renames, `d` deletes. - `w` saves the selection as a **bookmark** (links; needs the source provider to replay) or, in the queue pane, saves the queue. - `W` **captures** the selection: the subtree is mirrored under `/captures/` with every track's audio downloaded next to its metadata — fully local playback afterwards. Captures are incremental: re-capturing the same name resumes and completes it; tracks whose source cannot be captured are recorded as *skipped* (red in the UI, skipped by playback). Download captures can take long; progress is shown in the library pane. Inside `/captures`, `d` deletes any folder or single track *from disk* (audio included) after a `y/N` confirmation. Press `?` for the full binding table. ## Web client `crabidy-server` serves a browser client with the same functionality as the TUI at its own address (`http://:50051/`) — same navigation, same keys (`j`/`k`/`h`/`l`, `%`, `e`, `d`, `w`, `W`, queue and playback controls, `?` for help), plus clickable equivalents and a light/dark theme toggle. It talks gRPC-web to the same service the TUI uses, so it honors the same `[auth]` roles (it shows a login form when the server requires credentials). It is compiled to a WASM bundle and embedded into the server binary, behind the default-on `web-ui` cargo feature. A plain `cargo build` needs no WASM toolchain — it embeds a "not built" placeholder page until you build the bundle: ```sh devenv shell -- build-web # writes cbd-web/dist cargo build -p crabidy-server # embeds it ``` Build the server with `--no-default-features` for a headless, gRPC-only binary. See [cbd-web/README.md](cbd-web/README.md) for the dev loop and details. ## Logs `cbd` and `cbd-tui` log to `~/.local/state/crabidy/` (daily files); `crabidy-server` logs to stderr. Stream URLs and credentials are redacted from logs by design. ## Development Design documents live in `architecture/`, per-feature quality gates in `quality/`, and implementation plans in `plan/`. See `CLAUDE.md` / `AGENTS.md` for the development workflow and coding rules.