Soulseek matches a query against the filenames peers happen to have, and the name a user gives is usually more specific than any of them: a mix suffix that is not in the file, a diacritic the uploader typed as ASCII, an ampersand where the file has a space. Searched verbatim that is exit 4 for a track dozens of people share. Adds a four-rung ladder (as written, without the version suffix, folded to ASCII without featured artists, then the rarest two or three words), stopping at the first rung that returns anything, and then matching results back against what was actually asked for, since widening finds candidates but does not choose. Reconciled with the rate-limit rule: a wider query is a different query, repeating one is not. Also fixes an inconsistency the concurrency numbers had grown: the subagent route capped transfers per peer but never overall, while the batch route said -c 5, so the same skill gave two answers. There is now one table covering subagents, searches on the wire, transfers, transfers per peer, and rungs per track. Five searches against ten subagents is deliberate, because the server rate-limits searches harder than peers rate-limit uploads. Checked against agents given only this file: 2/2 climb the ladder rather than reporting failure on the first empty search, stop at four rungs, and verify the result is the track that was asked for.
soulseek-rs
A Soulseek client for the terminal: a full-screen TUI, and a one-shot command surface built for scripts and agents.
Website: https://re-invention.nl/soulseek-rs/
Installation
brew install michel/tap/soulseek-rs # macOS and Linux, prebuilt
cargo install soulseek-rs # anywhere with a Rust toolchain
Usage
Run it with no subcommand for the interactive TUI:
soulseek-rs
Anything else is a one-shot command that runs headless. stdout carries records only, stderr carries progress, and the exit code carries the verdict:
soulseek-rs search <QUERY> # print matching files
soulseek-rs get <QUERY> # search, pick the best, download
soulseek-rs download <USER> <PATH> # fetch one known file
soulseek-rs download --stdin # fetch files listed on stdin
soulseek-rs browse <USER> # list a user's shared files
soulseek-rs serve [--follow] # stay online sharing, stream uploads
soulseek-rs whoami # confirm credentials and connection
soulseek-rs user <NAME> # a peer's status and share counts
soulseek-rs room list|say|users|listen
soulseek-rs message send|read
soulseek-rs shares list|add|remove|status|reindex
soulseek-rs config path|list|get|set
soulseek-rs portmap # test automatic port mapping
soulseek-rs completions install # tab completion for bash/zsh/fish
Add --json for newline-delimited JSON instead of tab-separated text, so
commands compose:
soulseek-rs search "rjd2" --json \
| jq -c 'select(.size > 5000000 and .free_slot)' \
| soulseek-rs download --stdin
Exit codes: 0 success, 2 usage or config, 3 connect or login, 4 nothing
found, 5 timed out, 6 transfer failed, 7 session lost mid-command, 1
unexpected error.
The full README documents every
command, record shape, flag, environment variable and config.toml key.
Building from Source
git clone https://github.com/michel/soulseek-rs.git
cd soulseek-rs
cargo build --release
Library
To build your own Soulseek client, use the soulseek-rs-lib crate: the protocol implementation this client is built on.