- Go 98.2%
- Makefile 1.1%
- Shell 0.7%
| .forgejo/workflows | ||
| cmd/btx | ||
| docs | ||
| internal | ||
| protos@cde5ae3af5 | ||
| scripts | ||
| .gitignore | ||
| .gitmodules | ||
| buf.gen.yaml | ||
| buf.yaml | ||
| go.mod | ||
| go.sum | ||
| Makefile | ||
| README.md | ||
btx — Binary Transfer CLI
CLI for Binary Transfer. gRPC handles all daily operations; authenticate with a personal access token (PAT). File bytes go direct to S3 via presigned URLs.
Requirements
- Go 1.26+
protoc35.1 +protoc-gen-gov1.36.11 +protoc-gen-go-grpcv1.6.2 (for stub regeneration)- Git submodules initialized (
protos/)
Quick start
git submodule update --init --recursive
make btx
export BTX_TOKEN=btx_pat_... # create PAT in the web UI
btx auth set-token btx_pat_... # or rely on BTX_TOKEN / keyring
btx workspace use my-team
btx upload ./file.pdf # workspace-visible (shared with team)
btx upload ./secret.pdf --private # owner-only
btx upload ./file.bin --project demo # upload into a project
btx upload ./v2.pdf --replace SHARE_KEY # new version, same share link
btx files ls # includes teammates' workspace-visible files
btx files download 42 -o file.bin
btx cp 42 ./file.bin # download alias
btx shares ls
btx project ls # EDIT flag; --wide also shows MANAGE
btx whoami
Uploads are workspace-visible by default (discoverable by all members of the current workspace). Use --private / -p for owner-only files. Set workspace context with btx workspace use SLUG or BTX_WORKSPACE_ID.
Projects & permissions: workspace members inherit edit on workspace projects (upload, rename/patch, move, upload-version). Delete share/file needs manage (or file ownership). Only the project owner (is_admin) can delete a project (ADMIN_REQUIRED otherwise). btx project create requires a workspace (WORKSPACE_REQUIRED if unset).
btx project members ls merges the workspace roster (inherited access) with ProjectMember overrides (elevations, usually manage). Use --overrides for override rows only. btx project members add elevates a workspace member to manage — not read/edit.
# optional env aliases
export BTX_WORKSPACE_ID=<uuid>
Authentication
The CLI is PAT-only — no login, OIDC, or token creation in the CLI.
- Create a PAT in the Binary Transfer web UI
- Provide it via
BTX_TOKEN,btx auth set-token, or config/keyring - Daily commands use gRPC metadata:
authorization: Bearer …,x-workspace-id: …
btx auth token list and btx auth token revoke manage existing tokens over gRPC (they do not create tokens).
Public (no auth): btx share get KEY, btx share download KEY
Command tree
btx
├── logout
├── auth
│ ├── set-token
│ ├── logout
│ └── token list|revoke
├── doctor
├── whoami
├── workspace|ws list|get|use|current|create|update|members …
├── settings expiration show|set / preferences show|set
├── upload PATH [project[/folder]] # --private / --replace SHARE_KEY / --project
├── cp SRC DST # upload local→project or download ID→local
├── sessions|sess list|in-progress|status|watch|resume|parts|sync-plan|check|teardown|refresh-token
├── files|file ls|get|download|mv|lock|unlock
├── shares|share ls|get|edit|rm|upload-version|download|tags …
├── project|proj ls|get|create|update|delete|move|fav|unfav|files|shares|download|tags|pin|unpin|pins|members …
└── download KEY|FILE_ID|URL
See docs/rpc-coverage.md for the full RPC ↔ command matrix.
Global flags
| Flag | Description |
|---|---|
--host |
API/gRPC host |
--grpc-port |
gRPC port (default 50051 dev / 60051 prod) |
--workspace |
Workspace UUID (x-workspace-id) |
--output |
table | json | yaml | quiet |
-v / --verbose |
Verbose output |
--no-progress |
Disable progress bars |
--no-color |
Disable Unicode/color in tables |
BTX_DEBUG=1 |
Log gRPC method + latency |
List table flags
Many list commands (files ls, shares ls, sessions list, project ls, …) support:
| Flag | Description |
|---|---|
--columns id,name,... |
Show/reorder columns |
--wide |
Show all columns |
--limit N / --offset N |
Client-side pagination |
--project SLUG |
Filter by project (client-side on files/shares) |
--search TEXT |
Filter rows by filename/key (where supported) |
--sort FIELD / --sort-order asc|desc |
Client-side sort (where supported) |
Examples:
btx files ls --columns id,owner,visibility,access,filename
btx files ls --visibility private
btx shares ls --wide --project team
btx files ls demo/inbox --limit 20
btx sessions list --status in_progress
Positional project/folder targets:
btx files ls demo/inbox
btx upload ./report.pdf demo/archive
btx upload ./notes.pdf --private
btx upload ./report-v2.pdf --replace abc123
btx shares upload-version abc123 ./report-v2.pdf
btx project create --name Demo --slug demo # needs workspace context
Configuration
~/.config/btx/config.yaml (or $BTX_CONFIG):
grpc_addr: "localhost:50051"
tls: false
token: ""
workspace_id: ""
default_project: ""
default_output: "table"
parallel_parts: 4
part_size_mb: 8
Environment:
| Variable | Maps to |
|---|---|
BTX_TOKEN |
PAT |
BTX_HOST |
grpc_host |
BTX_WORKSPACE / BTX_WORKSPACE_ID |
workspace_id |
BTX_GRPC_ADDR |
grpc_addr |
BTX_UPLOAD_CONCURRENCY |
parallel_parts |
BTX_ENV=dev |
local dev defaults |
Config key alias: upload_concurrency → parallel_parts
Shell completion
The completion script is multi-line. Always quote command substitution in zsh/bash:
# zsh (~/.zshrc)
eval "$(btx completion zsh)"
# bash (~/.bashrc)
eval "$(btx completion bash)"
# fish
btx completion fish | source
Wrong (breaks the script — completions will not load):
eval $(btx completion zsh) # missing quotes
Protos
Protos live in the protos/ git submodule. Generated Go stubs under gen/ are not committed — make build, make test, and CI run make generate (alias make proto-go) from the submodule.
git submodule update --init --recursive
make btx # generates gen/ then builds
Local requirements: protoc 35.1, protoc-gen-go v1.36.11, protoc-gen-go-grpc v1.6.2 (see Makefile for install hints).
To bump API definitions: update the protos/ submodule ref only — no separate gen/ commit.
Development
make test
make lint
make btx
Integration tests (requires API docker-compose):
BTX_INTEGRATION=1 go test -tags=integration ./internal/integration/...
Architecture
btx ──gRPC──► Transfer / File / Share / Project / Workspace / User / Settings
│
└──HTTP PUT/GET──► S3 presigned URLs (User-Agent: btx/version on share download)
CI
| Workflow | Trigger | Purpose |
|---|---|---|
ci.yaml |
push, PR | vet, test, build |
integration.yaml |
manual | optional integration tests |
release.yaml |
tag v* |
cross-compile + release |
Install
GOPROXY=https://git.binarycollective.de/api/packages/binary/go \
go install git.binarycollective.de/binary/binary-transfer-cli/cmd/btx@latest
Or make cross for platform binaries in dist/.