Plume is a command-line file-sharing tool. Before a file leaves your machine it runs a pre-flight intelligence pass - an offline scan for secrets and personal data, a lightweight data/text profile, and sentiment - then turns those signals into a risk level and a suggested link lifetime. It serves the file over a self-destructing link (LAN out of the box, or a free internet tunnel) with a QR code and a neat browser download page.
No accounts. No third-party storage. No API keys. The intelligence pass is fully offline.
pipx install plumefile # or: uv tool install plumefile
plume share q3-report.pdf # scans it, then prints a code, a link and a QRplume scan inspects a file and prints one insight card. Here it is on a config file with a
planted AWS key, a Stripe key and a private key block:
And on a clean CSV of product reviews - it profiles the table and reads the tone instead:
Want a live recording? Install VHS and run
vhs assets/readme/demo.tapeto generateassets/readme/demo.giffrom the real CLI.
pipx install plumefile # isolated, recommended
uv tool install plumefile # if you use uv
pip install plumefile # into the current environmentAll three give you two equivalent commands: plume (short) and plumefile.
From source:
git clone https://github.com/1mystic/plumefile
cd plumefile
uv venv .venv
uv pip install --python .venv/Scripts/python.exe -e ".[dev]" # Windows
# uv pip install --python .venv/bin/python -e ".[dev]" # macOS / Linux# 1. Inspect a file without sharing it
plume scan customers.csv
# 2. Share a file. Plume scans it, suggests an expiry, prints a code, a link and a QR.
plume share report.pdf
plume share ./project-folder # a folder is zipped into one archive
plume share a.txt b.txt notes/ # several paths become one archive
plume share secrets.env --tunnel # also expose a free public URL (needs cloudflared)
# 3. Receive on another machine, by link or by code
plume get http://192.168.1.7:8737/amber-otter-42
plume get amber-otter-42 --host 192.168.1.7:8737 --out ./downloadsOr just open the link in a browser: you get a countdown page with a download button and a QR.
Run the pre-flight intelligence pass and print the insight card. Pure local, no networking.
| Flag | Description |
|---|---|
--quiet, -q |
Skip the banner. |
Scan, then seed the file(s) over a self-destructing link with a QR code. One file is served as-is; multiple paths or a folder are zipped into a single archive first (the staged zip is deleted when the link closes).
| Flag | Default | Description |
|---|---|---|
--expire, -e |
the scan's suggestion | Link lifetime: 2m, 5m, 10m, 1h, or a value like 45s. |
--port, -p |
8737 |
Port to seed on. |
--tunnel, -t |
off | Also expose a free public *.trycloudflare.com URL (needs cloudflared). |
--no-scan |
off | Skip the pre-flight scan. |
--yes, -y |
off | Do not prompt to tighten the expiry when the scan wants a shorter one. |
Download a shared file with a progress bar and an ETA.
| Flag | Description |
|---|---|
--host, -h |
host:port to use when you pass a bare code instead of a URL. |
--out, -o |
Directory to save into (default: current directory). |
Run a persistent serving host for any shares already registered on this machine.
| Flag | Default | Description |
|---|---|---|
--port, -p |
8737 |
Port to listen on. |
Print the installed version.
Every scan (and every share of a single file) produces one insight card. The whole pass is
offline and degrades per signal: anything that does not apply to a file is skipped, never fatal.
| Signal | What it does |
|---|---|
| Secret / PII scan | Regex ruleset for private keys, cloud keys (AWS, Google, Stripe), GitHub and Slack tokens, JWTs, password assignments, emails, IPs and Luhn-checked card numbers. Findings are redacted before display. |
| Data profiling | CSV / TSV / JSON records get row and column counts, dtypes and null counts (pandas / numpy). |
| Text profiling | Any text file gets line and word counts and a readability score. |
| Sentiment | Offline VADER lexicon sentiment for prose (skipped on data and code). |
| Risk + expiry | A deterministic cascade maps the signals to low / medium / high and a suggested link lifetime. A live-looking credential forces high and a 2 minute default. |
- LAN, out of the box.
plume sharestarts a small local server and prints a link on your LAN address plus a QR. Anyone on the same network opens it in a browser or withplume get. - Internet, optionally, for free.
--tunnelshells out tocloudflaredto open a public*.trycloudflare.comURL: no account, no cost, no Plume-run servers. Ifcloudflaredis not installed, Plume says so and stays LAN-only. - Self-destructing. The link stops working at its expiry, with a 15 minute grace window so a slow or in-flight download still finishes. Share state is disk-backed, so a restart does not lose live shares.
- Chunked. Files stream in 256 KB chunks; a 1.5 GB size cap guards against accidents.
Nothing is uploaded to a third-party server. The file is served straight from your machine.
Two terminals on the same machine, both pointed at localhost:
# terminal 1 - start sharing (short expiry so it self-destructs quickly)
plume share README.md --expire 2m -y
# copy the printed link, then in terminal 2 - download it
plume get http://127.0.0.1:8737/<the-printed-code> --out ./downloadsOpen the same link in a browser to see the receiver page: a live countdown, a download button and a QR. Let the timer run out to watch the link self-destruct.
uv pip install --python .venv/Scripts/python.exe -e ".[dev]"
.venv/Scripts/python.exe -m pytest -q # the full test suiteHouse rules: every user-visible string uses plain hyphens (never em dashes); every fix ships with a regression test; transfer changes are verified against a real running server.
uv build # builds sdist + wheel into dist/
uv publish # upload to PyPI (needs a token)
# then cut a GitHub release and attach dist/* as assets:
gh release create v0.1.0 dist/* --generate-notesThe receiver web page ships inside the wheel, so an installed plume serves the same UI.
Plume warns you about secrets before you share, but it is a convenience scanner, not a
guarantee. It does not scan inside archives, and no regex catches everything. Review the card,
and prefer a short expiry (or keep --tunnel off) for anything sensitive.
MIT licensed. See LICENSE.