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 QR
See it work
plume 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.
Install
pipx install plumefile # isolated, recommended
uv tool install plumefile # if you use uv
pip install plumefile # into the current environment
All 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
Quickstart
# 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 ./downloads
Or just open the link in a browser: you get a countdown page with a download button and a QR.
Command reference
plume scan <path>
Run the pre-flight intelligence pass and print the insight card. Pure local, no networking.
| Flag | Description |
|---|---|
--quiet, -q |
Skip the banner. |
plume share <paths...>
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. |
plume get <url|code>
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). |
plume serve
Run a persistent serving host for any shares already registered on this machine.
| Flag | Default | Description |
|---|---|---|
--port, -p |
8737 |
Port to listen on. |
plume version
Print the installed version.
The pre-flight intelligence pass
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. |
How sharing works (free, over the network)
- 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.
Try it locally
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 ./downloads
Open 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.
Development
uv pip install --python .venv/Scripts/python.exe -e ".[dev]"
.venv/Scripts/python.exe -m pytest -q # the full test suite
House 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.
Releasing (maintainers)
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-notes
The receiver web page ships inside the wheel, so an installed plume serves the same UI.
Privacy note
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.
License
MIT licensed. See LICENSE.
Metadata
Release files for plumefile 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| plumefile-0.1.1.tar.gz | 49.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| plumefile-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 87.1 kB
Release files / plumefile-0.1.1.tar.gz
| Download URL | plumefile-0.1.1.tar.gz |
|---|---|
| Size | 49.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
721f5b6ce48b5b84fe1963b5a86eda0a1334db14cd8c5b8e56c98229ead19d3c
|
|
BLAKE2b-256 checksum How to use checksums |
a59c0305f88bae0100e57abfaed179c69f60637ec9ba44920ff8d8bc904781a1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.25 {"installer":{"name":"uv","version":"0.9.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / plumefile-0.1.1-py3-none-any.whl
| Download URL | plumefile-0.1.1-py3-none-any.whl |
|---|---|
| Size | 37.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d365532a48a525483b1658ce3962a9627fba96bb4015e9f599a363dbc8de6cc8
|
|
BLAKE2b-256 checksum How to use checksums |
1d067a66819b96d7c1aaaecab23cbf41c3710213ded8f5e86b460d1fcee0af87
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.25 {"installer":{"name":"uv","version":"0.9.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|