Only remove dictionary entries for turbo/mozjpeg versions in setup.py
(they need cmake-generated headers). Keep the if blocks intact - they
safely evaluate to False for standard libjpeg versions.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
APIs changed between libjpeg versions, so each version directory
needs its matching headers:
- 6b gets 6b headers
- 7 gets 7 headers
- 8-8d get 8d headers
- 9-9f get 9f headers
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The setup.py has broken include_dirs that reference 'jpeglib/cjpeglib'
but the source files are in 'src/jpeglib/cjpeglib'. Create a symlink
to fix the include path resolution.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The PyPI source tarball is missing both jpeglib's own headers
(cjpeglib_common.h, etc.) and libjpeg headers. Clone from GitHub
which has the jpeglib headers, then download libjpeg headers.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
jpeglib has no pre-built ARM64 wheel and the source tarball is missing
libjpeg header files. This adds a workaround that downloads the official
libjpeg headers before building.
- Add rpi/patches/jpeglib/install-jpeglib-arm64.sh helper script
- Update setup.sh to download headers when building from source
- Downloads headers for libjpeg 6b, 7-9f, turbo, and mozjpeg versions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rewrite setup.sh to use system Python instead of pyenv
- Add Python version check (3.11-3.14 supported)
- Remove jpegio build steps (jpeglib installs cleanly via pip)
- Simplify prebuilt tarball (just venv, no pyenv)
- Reduce install time: 5-10 min from source (was 15-20 min)
- Update README.md and BUILD_IMAGE.md accordingly
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Default branch: 4.1 → 4.2
- Update prebuilt URL to v4.2.0
- Update example filenames to 4.2.0
- Remove jpegio references (now using jpeglib)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create stegasoo-api.service for FastAPI on port 8000
- Prompt user during setup with security warning (no auth)
- Default to disabled (recommended)
- Update help text and start commands for both services
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Run on Pi after from-source build to create:
stegasoo-rpi-runtime-env-arm64.tar.zst (~50-60MB)
Contains pyenv + Python 3.12 + venv with all deps.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Step 3 now offers three choices:
- Skip (public mode)
- Generate new key
- Enter existing key (for joining team deployments)
Validates entered keys using Python channel module before accepting.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove pv (showed read progress, not write progress)
- Use dd status=progress for actual write progress
- Reduce block size to 1M (better for slow SD cards)
- Remove conv=fsync (sync at end instead, faster)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Run fsck.vfat on boot partition and e2fsck on root partition
after flashing to catch and fix any corruption.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
resize2fs only fills the partition. Need growpart first to
expand the partition to fill the disk, then resize2fs to
expand the filesystem.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Instead of a hidden systemd service, expand the filesystem
visibly during the first-boot wizard so users can see it
happening.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
rpi-imager was doing something that prevented the auto-expand
service from working. Simplify to just dd with optional pv
for progress.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move the partition wipe to after user types 'yes' so they can
still abort without having already wiped the device.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Create a systemd oneshot service that expands the rootfs on first boot
after flashing. The service self-destructs after running.
This ensures release images fill the SD card while keeping the
download size small (16GB shrunk image).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The shrinking is only for faster image downloads. After flashing,
the image should auto-expand to fill the SD card.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove --compress/--algorithm CLI options (not wired to encode flow)
- Add man page installation to rpi/setup.sh
- Document man page installation in README.md and CLI.md
- Update man page to remove compression options
Compression will be properly implemented in v4.1.8.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Channel keys saved to config files are now encrypted using the
machine's identity (/etc/machine-id), so:
- Not stored in plaintext
- Tied to specific machine (can't copy file to another device)
- Legacy plaintext keys still work (auto-detected)
Changes:
- Added _encrypt_for_storage() and _decrypt_from_storage()
- set_channel_key() now encrypts before writing
- get_channel_key() decrypts when reading (handles legacy plaintext)
- Pi setup saves encrypted key to ~/.stegasoo/channel.key
- CLI `stegasoo info` now shows channel status correctly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
No more browser warnings! mkcert creates locally-trusted certs.
Pi Setup:
- Auto-install mkcert during setup
- Generate trusted certs when HTTPS enabled
- Copy CA to /static/ca/rootCA.pem for easy device setup
- New devices can download CA via HTTP and install it
Docker:
- docker-entrypoint.sh checks for mkcert, falls back to openssl
- Shows instructions for CA distribution to other devices
Scripts:
- Added setup-trusted-certs.sh helper for local dev
- Installs mkcert, generates certs, shows device setup instructions
To trust on new devices:
1. Download: http://stegasoo.local/static/ca/rootCA.pem
2. Install as trusted CA in browser/OS
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Docker:
- HTTPS enabled by default (generates self-signed cert)
- Added docker-entrypoint.sh for SSL cert generation
- Gunicorn now starts with --certfile/--keyfile when HTTPS enabled
- Install curl/openssl in web container for healthcheck and certs
- Updated docs to reflect HTTPS default
Smoke Test:
- Moved from rpi/ to scripts/ (works for Pi, Docker, and dev)
- Updated header and examples
- Added to .gitignore exceptions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Comprehensive test suite for Pi deployments:
- Connectivity check
- Auto-setup if first boot (admin/stegasoo)
- Login and session handling
- All page accessibility
- LSB encode/decode round trip
- DCT encode/decode round trip
- Tools API (capacity, EXIF)
Usage: ./rpi/smoke-test.sh [host] [port] [user] [pass]
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Simplified Pi build script:
- No imaging step (assumes SD card already flashed)
- Waits for Pi to be reachable via SSH
- Installs deps (including ca-certificates for git SSL)
- Clones from main branch (has updated tarball name)
- Copies pre-built tarball if available
- Runs setup and tests
Usage: ./remote-build-pi.sh [host] [user] [pass]
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
More descriptive name for the pre-built pyenv + venv bundle.
Updated all scripts and docs to use new filename.
Also bumped PREBUILT_URL to v4.1.5.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Unmounts and resizes partition to exactly 16GB
- Handles both shrinking (large cards) and expanding (small cards)
- Disables Pi OS auto-expand service
- Consistent image size regardless of source SD card
- 16GB = minimum disk requirement = image size
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Documents easy 3-command update process for existing installations.
Most updates just need git pull + systemctl restart since we use
editable pip installs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The code now explains itself like a friend teaching you crypto:
- DCT module: Why mid-frequency? What's QIM? Why is scipy being weird?
- Steganography: How LSB actually works with visual examples
- Crypto: The multi-factor security model with ASCII art diagrams
Also adds kickoff-pi-test.sh - one command to flash, wait, setup, test.
No more manual steps between flashing and seeing if it works.
Comments should teach, not just describe. If you're reading the code
trying to understand how DCT steganography works, these comments
should actually help. Novel concept, I know.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix TEMP_NUM/TEMP_EMOJI variables (no escaping in quoted heredoc)
- Shorten /etc/motd to one-liner with license path reference
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adjust spacing between MHz and thermometer emoji for proper
column alignment in terminal.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create rpi/banner.sh with print_banner, print_gradient_line,
print_logo, print_starfield, print_complete_banner functions
- Update setup.sh to source banner.sh (with inline fallback for curl)
- Update first-boot-wizard.sh to use banner functions
- Update sanitize-for-image.sh to use banner functions
- Fix MOTD thermometer spacing alignment
Single source of truth for ASCII banner styling.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>