No description
  • Go 98.2%
  • Makefile 1.1%
  • Shell 0.7%
Find a file
Daniel Malik 0bbb5d7183
All checks were successful
CI / Test & build (push) Successful in 57s
Release / Release binaries & Go module (push) Successful in 1m55s
chore: point protos at official Project.is_admin
2026-07-25 03:46:31 +02:00
.forgejo/workflows fix: ci 2026-07-10 16:37:08 +02:00
cmd/btx feat: expansion 2026-07-10 02:36:01 +02:00
docs feat: project access overrides, flag gates, and is_admin 2026-07-25 03:41:06 +02:00
internal feat: project access overrides, flag gates, and is_admin 2026-07-25 03:41:06 +02:00
protos@cde5ae3af5 chore: point protos at official Project.is_admin 2026-07-25 03:46:31 +02:00
scripts fix: ci 2026-07-10 16:13:48 +02:00
.gitignore fix: protos as sot 2026-07-10 03:46:55 +02:00
.gitmodules fix: ci 2026-07-10 03:36:29 +02:00
buf.gen.yaml feat: initialize repository 2026-07-10 00:23:29 +02:00
buf.yaml feat: initialize repository 2026-07-10 00:23:29 +02:00
go.mod feat: expansion 2026-07-10 02:36:01 +02:00
go.sum feat: expansion 2026-07-10 02:36:01 +02:00
Makefile fix: ci 2026-07-10 16:13:48 +02:00
README.md feat: project access overrides, flag gates, and is_admin 2026-07-25 03:41:06 +02:00

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+
  • protoc 35.1 + protoc-gen-go v1.36.11 + protoc-gen-go-grpc v1.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.

  1. Create a PAT in the Binary Transfer web UI
  2. Provide it via BTX_TOKEN, btx auth set-token, or config/keyring
  3. 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_concurrencyparallel_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 committedmake 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/.