CLI / @jackmorgan/phaser-cli

CLI — terminal-first Phaser

A Go binary distributed on npm. Browse the catalog, mint API keys, and upload tracks from your shell. Signs EIP-4361 challenges locally — byte-identical to viem.

@jackmorgan/phaser-cli v0.1.0 Go · 6 prebuilt targets
~/music/releases — phaser Live demo

Install

The npm postinstall pulls the prebuilt binary for your OS/arch. Skip with PHASER_CLI_SKIP_INSTALL=1.

npm (recommended)
$ npm i -g @jackmorgan/phaser-cli

Supported: darwin/arm64, darwin/amd64, linux/arm64, linux/amd64, windows/arm64, windows/amd64. Config at ~/.phaser/config.json.

Authentication

Two credential types. The CLI picks the right one per command automatically — you don't have to think about it.

API key

Read-only, long-lived

Paste one from the web app or mint via keys create. Good for CI, scripts, and browsing the catalog.

USED BY · catalog · albums get · health
JWT (SIWE)

Wallet-signed, 1-hour

Run auth siwe — the CLI derives your address, fetches a challenge, signs it locally, and stores the JWT. Private key never leaves your machine.

USED BY · keys · tracks · albums · artists init
🔐 SIWE SIGNING
Signatures are byte-identical to viem.signMessage. Pure Go, no cgo. Private key resolved via --private-key flag → --private-key-file$PHASER_PRIVATE_KEY → interactive masked prompt.

Browse (read-only)

shell
$ phaser catalog tracks --genre synthwave --sort newest --limit 10
$ phaser catalog track trk_abc123
$ phaser catalog search "velour static"
$ phaser catalog genres
$ phaser albums get alb_xyz

Add -o json on any command for machine-readable output. --cursor + --limit for pagination.

Artist flow

Sign in once, mint a key, init your artist profile, then upload forever.

STEP 01 · SIWE

Sign in with Ethereum

CLI derives your address, signs the EIP-4361 challenge locally, stores the JWT.

$ phaser auth siwe
STEP 02 · ARTIST

Create your profile

One artist per wallet. This is your public page at /a/<slug>.

$ phaser artists init --name "Velour Static" --slug velour-static
STEP 03 · KEY

Mint an API key

--save writes it to config so subsequent commands pick it up automatically.

$ phaser keys create --name cli --save
STEP 04 · UPLOAD

Publish a track

Single command — multipart upload, cover art, pricing, publish — all at once.

$ phaser tracks upload song.mp3 --title "Neon" --price 0.05 --publish

Track uploads

Two paths depending on file size. Under ~100 MB: single multipart POST. Anything larger: presign → PUT to S3 → finalize.

shell
$ phaser tracks upload song.mp3 \
    --title "Track 1" \
    --genre synthwave \
    --price 0.05 \
    --cover art.jpg \
    --album-id <uuid> \
    --track-number 1 \
    --release-date 2026-04-20 \
    --publish
$ phaser tracks presign \
    --title "Track 2" \
    --audio big.flac \
    --cover cover.jpg \
    --upload

$ phaser tracks finalize --track-id <id> --publish
$ phaser tracks presign \
    --title "Track 2" \
    --audio-content-type audio/flac \
    -o json

# then PUT it yourself:
$ curl -X PUT --data-binary @big.flac \
    -H "Content-Type: audio/flac" \
    "<upload_url>"

$ phaser tracks finalize --track-id <id> \
    --source-audio-key <key>

All commands

CommandWhat it does
phaser healthPing the API
phaser auth login / siwe / logout / statusCredentials
phaser config show / pathInspect config
phaser catalog tracks / track / search / genres / artistsBrowse
phaser albums get / create / updateAlbums
phaser artists initCreate artist profile
phaser keys list / create / revokeAPI keys
phaser tracks upload / presign / finalize / update / publish / deleteTracks
phaser storage balance / invoicesCredit ledger
phaser analyticsStreams + revenue
phaser completion <shell>Shell completions (bash/zsh/fish)

Upload progress

When stdout is a TTY, uploads print a live progress line to stderr. CI and piped output stay silent.

stderr
uploading   47.32%  47.32 MB / 100.00 MB  8.12 MB/s