6.6 KiB
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:
/
├── 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 on0.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 intocrabidy-server(see cbd-web/README.md).
Quick start
The toolchain is managed by devenv:
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 |
ytdy.toml |
YouTube | ytdy/README.md |
fsdy.toml |
local fs | 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.
cbd-tui.toml
Configuration of the TUI (and the TUI half of cbd):
# 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.
[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. / filters the current pane (library or queue)
live as you type — Enter keeps the filter, Esc clears it.
wsaves the selection as a bookmark (links; needs the source provider to replay) or, in the queue pane, saves the queue.Wcaptures the selection: the subtree is mirrored under/captures/<name>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,ddeletes any folder or single track from disk (audio included) after ay/Nconfirmation.
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://<server>: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:
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 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.