Hermes Agent d7fc7606ec fix(receiver): revert indicator to framesWithQR/accepted/needed with correct math
- framesWithQR now counts ALL frames with a valid QR (including duplicates),
  not just deduplicated ones. Moved increment before dedup check.
- acceptedPackets already correctly counts linearly-independent packets
  (rank increase), capped at K per generation by the decoder.
- neededPackets = K * sourceGenerations, computed from constants.
- Keep generation count (solvedGens/sourceGens) as secondary indicator.

This gives an honest rough progress bar: useful can approach or briefly
touch required while some generations are still partially filled, but the
generation count is the definitive completion signal.
2026-05-04 14:36:39 +00:00
2026-05-04 13:32:50 +00:00

QR Stream

Transfer files and text between devices by displaying an animated sequence of QR codes and reading it with a camera. No network, no Bluetooth, no cables — just light.

Live demo: https://230590.xyz/hermes-web-demos/qr-transfer/


Installation

npm

npm install -g qr-stream

Bun

bun install -g qr-stream

You can also run it directly without installing:

npx qr-stream [file]
bunx qr-stream [file]

CLI Usage

Encode text or a file into a looping QR sequence

# Read from file
qr-stream document.pdf

# Read from stdin
echo "Hello, world!" | qr-stream

# Pipe file contents
base64 image.png | qr-stream

The terminal clears, enters an alternate screen buffer, and displays the QR frames in a loop at 10 FPS. Press q or Ctrl-C to quit.

Start the web app preview server

qr-stream --serve

Serves the built web UI on http://localhost:3000 (default). Change the port with the PORT environment variable:

PORT=8080 qr-stream --serve

The server resolves the dist/ directory automatically, so it works from both the bundled CLI and a local checkout.

CLI flags

Flag Description
-h, --help Show usage information
-s, --serve Start the web preview server

Development Setup

Prerequisites

  • Node.js >= 18
  • Bun (optional, for faster installs)

Install dependencies

npm install

Start the dev server

npm run dev

Starts Vite with hot reload on http://localhost:5173.

Build

npm run build

Produces:

  • dist/index.html and dist/assets/* — the web app
  • dist/qr-stream.js — the self-contained CLI bundle

Preview the production build

npm run preview

Serves the contents of dist/ locally exactly as it will run in production.

Run tests

npm test

Runs the full test suite (57 tests) via Vitest.

Run the CLI from source

bun run src/cli/qr-stream.ts
# or
npm run cli

Build the CLI only

npm run build:cli

How It Works

  1. Sender compresses your data, splits it into chunks, and wraps each chunk in a QR code.
  2. The QR codes are shown as an animated sequence (in the terminal or as a GIF in the browser).
  3. Receiver scans the sequence with a camera or uploads a GIF, decodes the frames, and reassembles the original file or text.

The protocol uses fountain coding (RLNC over GF(256)) so the transfer survives frame loss, glare, and partial obstructions without needing every single frame.

For a deep dive into the packet format, algorithms, and design decisions, see ARCHITECTURE.md.


License

MIT — built for fun and utility.

Languages
TypeScript 85.9%
JavaScript 8.2%
Python 5.4%
HTML 0.5%