It's like mopidy but good.
Go to file
Test User c4abadc8e4 CLI quality gates and plan (stages 3-4)
quality/cli.md: gates for parsing/defaults, guard/scan/auth, remote
commands, assets, and error/secret handling. plan/cli.md: ordered
implementation checklist.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 11:50:03 +02:00
.gitea Clean up a bit 2023-06-13 10:12:26 +02:00
architecture Design a comprehensive clap-derive CLI (architecture/cli.md) 2026-07-22 11:45:05 +02:00
audio-player Implement mute (it was a stub) 2026-07-22 00:20:01 +02:00
cbd Give cbd its own config file, separate from cbd-tui 2026-07-21 22:57:43 +02:00
cbd-cli Add cbd-cli crate: shared clap CLI definitions + executor stub 2026-07-22 11:48:30 +02:00
cbd-tui Implement the crabidy content store and single /crabidy provider 2026-07-22 11:34:40 +02:00
cbd-web Design the crabidy content store; add wire + fsdy foundations 2026-07-22 10:58:11 +02:00
crabidy-core Design the crabidy content store; add wire + fsdy foundations 2026-07-22 10:58:11 +02:00
crabidy-server Implement the crabidy content store and single /crabidy provider 2026-07-22 11:34:40 +02:00
fsdy Design the crabidy content store; add wire + fsdy foundations 2026-07-22 10:58:11 +02:00
plan CLI quality gates and plan (stages 3-4) 2026-07-22 11:50:03 +02:00
quality CLI quality gates and plan (stages 3-4) 2026-07-22 11:50:03 +02:00
tidaldy Implement the crabidy content store and single /crabidy provider 2026-07-22 11:34:40 +02:00
ytdy Implement the crabidy content store and single /crabidy provider 2026-07-22 11:34:40 +02:00
.editorconfig Add cross compile release flow 2023-06-12 09:38:19 +02:00
.gitignore Add devenv-based dev environment and README 2026-07-19 21:29:23 +02:00
Cargo.lock Add cbd-cli crate: shared clap CLI definitions + executor stub 2026-07-22 11:48:30 +02:00
Cargo.toml Add cbd-cli crate: shared clap CLI definitions + executor stub 2026-07-22 11:48:30 +02:00
Cross.toml Generate x86_64 target 2023-06-12 18:21:58 +02:00
README.md Implement the crabidy content store and single /crabidy provider 2026-07-22 11:34:40 +02:00
aarch64-unknown-linux-gnu-Dockerfile Try to add release files 2023-06-12 18:06:00 +02:00
armv7-unknown-linux-gnueabihf-Dockerfile Try to add release files 2023-06-12 18:06:00 +02:00
devenv-rust.nix Add devenv-based dev environment and README 2026-07-19 21:29:23 +02:00
devenv.lock Add devenv-based dev environment and README 2026-07-19 21:29:23 +02:00
devenv.nix Add a Leptos web client served by the server 2026-07-21 22:43:06 +02:00
devenv.yaml Add devenv-based dev environment and README 2026-07-19 21:29:23 +02:00
rust-toolchain.toml Add devenv-based dev environment and README 2026-07-19 21:29:23 +02:00
x86_64-unknown-linux-gnu-Dockerfile Generate x86_64 target 2023-06-12 18:21:58 +02:00

README.md

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)
└── crabidy      your saves: queues, bookmarks (`w`), and captures (`W`),
                 managed by the server (see architecture/crabidy-store.md)

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).

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 cbd-tui below
cbd.toml cbd below (same options as cbd-tui.toml)
crabidy-server.toml server below (never auto-created)

The server-managed crabidy provider does not live under ~/.config. Its track-file tree (saved queues, bookmarks, and captures) lives in ~/.local/state/crabidy/ (the platform state directory) and the audio it captures lives in a single content-addressed store under ~/.local/share/crabidy/ (the data directory), shared and de-duplicated across saves. Neither needs configuration; see architecture/crabidy-store.md.

cbd-tui.toml and cbd.toml

Client configuration. cbd-tui (the standalone terminal client) reads cbd-tui.toml; cbd (server + TUI in one process) reads its own cbd.toml. They are separate files with the same options so the two can run side by side on one machine — a common setup is cbd playing locally against its in-process server while cbd-tui points at a remote server (e.g. a Raspberry Pi). A shared file would force one to follow the other's address.

# Where to find the server. Default (both files): localhost, which is
# what cbd's own in-process server listens on. Point cbd-tui.toml at a
# remote server to use it as a remote control.
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 = ""

# Show the frequency-spectrum bars under the track progress. Default true.
spectrum = true

Every option is also available as a command-line flag (cbd-tui --address ..., cbd --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.

  • w saves the selection (a library subtree, or in the queue pane the queue) as a new folder under /crabidy/<name> of link files — needs the source provider to replay. On a name that already exists the save is refused with a warning; delete the old folder and save again.
  • W captures the selection into /crabidy/<name>: same as w, but every track's audio is fetched into the shared content store under ~/.local/share/crabidy/ and the saved tomls link to it — fully local playback afterwards. Works on a library subtree and on the queue (no need to save it first). Audio is de-duplicated: capturing the same track again (from a playlist, a search, another save) reuses the stored file instead of downloading it twice, matched first by provider id and then by content hash. Tracks already local (from /fs) are copied into the store rather than re-downloaded. A source that genuinely cannot be captured is recorded as skipped (red in the UI, skipped by playback). Download captures can take long; progress is shown in the library pane.
  • Captured rows are marked with a leading | — visible even while browsing another provider, so you can see what you already have.
  • Inside /crabidy, d deletes a folder or track immediately (no confirmation): it removes only the metadata toml, never the shared store audio, which other saves may reference.

Press ? for the full binding table.

A row of frequency-spectrum bars is drawn under the track progress while audio plays (the server taps its own output, runs the FFT, and streams the bars, so it works whether the server is local or remote). Turn it off with spectrum = false in the client config.

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.