@uicnz/cast
v0.1.6
Published
Secure, relay-assisted file transfer for humans and agent harnesses
Readme
cast
Secure, end-to-end encrypted file transfer from a terminal or TypeScript application. Send files, folders, text, or streams using a short, freshly generated transfer code.
- npm:
@uicnz/cast - source:
uicnz/cast - public relay:
cast.aria.bot
Send and receive
You do not need to install anything globally or configure a relay.
1. Send
On the sending computer:
npx --yes @uicnz/cast send ./artifact.binThe sender prints the file size, a new transfer code, and both forms of the receive command:
Sending 'artifact.bin' (42.7 MB)
Code is: 5665-studio-albert-laura
On the receiving computer run:
cast 5665-studio-albert-laura
Or, without installing:
npx --yes @uicnz/cast 5665-studio-albert-laura
To accept without prompting:
cast --yes 5665-studio-albert-laura
npx --yes @uicnz/cast --yes 5665-studio-albert-lauraKeep the sender running and share the complete code with the recipient. The
code above is only an example; every ordinary send generates a different code.
When clipboard integration is available, cast copies the code and prints
Code copied to clipboard! after the copy succeeds. --extended-clipboard
instead copies a complete private receive command and confirms it with
Receive command copied to clipboard!.
2. Receive
On the receiving computer, change to the directory where the content should be written and append the exact generated code to the command:
cd ~/Downloads
npx --yes @uicnz/cast 5665-studio-albert-lauraThe receiver shows what is being offered and asks for confirmation. The first
--yes in npx --yes belongs to npm and only approves running the package; it
is not passed to cast. Put cast's own --yes after @uicnz/cast to accept
non-interactively:
npx --yes @uicnz/cast --yes 5665-studio-albert-lauraEvery normal invocation first identifies the running command and version, for
example cast 0.1.6. After acceptance, both terminals show the current file, a
Unicode progress bar, percentage, transferred and total bytes, and transfer
rate. An interactive TTY redraws one progress line in place. Redirected stderr
emits bounded line updates at percentage-bucket changes instead of writing one
line per transfer event. The startup identity, progress, route, offer,
clipboard, and completion status always use stderr so received bytes on stdout
remain clean. --quiet suppresses all of this status rendering while preserving
the transfer.
You can select the destination without changing directories:
npx --yes @uicnz/cast --out ./received 5665-studio-albert-lauraFiles, folders, and collections
The send command accepts one or more paths. Directories are transferred recursively.
npx --yes @uicnz/cast send ./report.pdf
npx --yes @uicnz/cast send ./project-folder
npx --yes @uicnz/cast send ./report.pdf ./photos ./notes.txtGlobal installation
Install once if you prefer the shorter command:
npm install --global @uicnz/castThen send and receive with:
cast send ./artifact.bin
cast 5665-studio-albert-lauraHow connections work
By default, cast makes the transfer available through two routes:
- the public relay at
cast.aria.bot; - a direct local-network route when both peers can use it.
The first successful route wins. Users do not need to supply --relay or a
relay password. Transfer content is encrypted between the sender and receiver;
the relay only forwards the encrypted byte stream.
The transfer code is a credential. Treat it like a temporary password and send it through a trusted channel. Generated codes are not persisted.
Common commands
Force the hosted relay and disable local-network discovery:
npx --yes @uicnz/cast send --no-local ./artifact.bin
npx --yes @uicnz/cast --no-local 5665-studio-albert-lauraKeep a transfer on the local network:
npx --yes @uicnz/cast send --local ./artifact.bin
npx --yes @uicnz/cast --local 5665-studio-albert-lauraSend text:
npx --yes @uicnz/cast send --text "hello from cast"Send piped input and write the received bytes to stdout:
cat ./artifact.bin | npx --yes @uicnz/cast send
npx --yes @uicnz/cast --stdout --yes 5665-studio-albert-laura > artifact.binArchive directories before sending while leaving ordinary files unchanged:
npx --yes @uicnz/cast send --zip ./project-folder ./notes.txtRender the generated code as a terminal QR symbol:
npx --yes @uicnz/cast send --qrcode ./artifact.binGenerate shell completion:
npx --yes @uicnz/cast completion zsh
npx --yes @uicnz/cast completion bash
npx --yes @uicnz/cast completion fishRun npx --yes @uicnz/cast --help, send --help, or relay --help for the
complete command-line reference.
TypeScript API
Install the library:
bun add @uicnz/cast
# or
npm install @uicnz/castThe programmatic API exposes the same transfer engine used by the CLI:
import {
parseCastInvitation,
receive,
send,
serializeCastInvitation,
} from "@uicnz/cast";
// Sender
const offer = await send(["./artifact.bin"]);
const serialized = serializeCastInvitation(offer.invitation);
// Deliver `serialized` to the other harness through your control plane.
// Receiver
const invitation = parseCastInvitation(serialized);
const receiving = receive(invitation.code, {
outputDir: "./received",
conflict: () => "resume",
});
await Promise.all([offer.completed, receiving]);Every long-running primitive accepts an AbortSignal. Invitations exclude file
content and relay passwords. The package also exports text, readable-stream,
stdout, local-routing, relay, and cancellable handle APIs.
Self-host a relay
The public relay is the default; self-hosting is optional. Start a private relay with a password supplied through the environment:
CAST_PASS='replace-with-a-strong-secret' \
npx --yes @uicnz/cast relay --host 0.0.0.0 --ports 9009,9010,9011Point both peers at it:
CAST_PASS='replace-with-a-strong-secret' \
npx --yes @uicnz/cast send --relay relay.example.com:9009 ./artifact.bin
CAST_PASS='replace-with-a-strong-secret' \
npx --yes @uicnz/cast --relay relay.example.com:9009 5665-studio-albert-lauraProduction systemd deployment and health-check instructions are in
deploy/README.md.
Troubleshooting
sh: cast: command not found while using npx
npm can shadow the published package when npx @uicnz/cast is run from inside
this repository's own source checkout. Run the public-package command from a
different directory:
cd /tmp
npx --yes @uicnz/cast --versionThis source-checkout edge case does not affect normal users or global installs.
Force a remote transfer
If two terminals are on the same computer and you specifically want to test the
public relay, add --no-local on both sides.
Receive without a positional code
Run npx --yes @uicnz/cast with no code to open the bounded interactive code
prompt.
Development
Development requires Bun 1.3.14 or newer. The ESM library supports Node 24 or newer.
bun install
bun run check
bun run typecheck
bun run test
bun run fuzz:regressionThe implementation checkpoints and release evidence are maintained in
rfcs/ and COMPATIBILITY.md.
