Default landing content in all 14 locale files used JSON \n for
paragraph breaks. These rendered as literal \n\n on Tor Browser
(no JS). Now uses <br><br> tags directly in the locale strings.
User-entered content from the editor still gets \n→<br> conversion
at build time via cli.py.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
The Debian Bookworm SSL/TLS stack (both OpenSSL for curl and GnuTLS
for git) frequently fails or hangs against GitHub. This overhaul:
- Adds wget as fallback downloader (different TLS codepath)
- Wraps all git/network ops with `timeout` to prevent hangs
- Reorders strategies: binary → tarball → shallow clone → pipx → pip
(tarball now before git-based methods since it needs no git protocol)
- Each download retries 3x with both curl and wget before giving up
- Installs wget as a system dep on apt-based distros
- Final error message gives manual download instructions
Co-Authored-By: Claude Opus 4.6 <[email protected]>
A failed binary download (or leftover from a previous install) at
~/.local/bin/voxvera shadows the pipx/pip entrypoint script. Now all
non-binary strategies detect and remove stale ELF/Mach-O binaries
before declaring success.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Add GIT_HTTP_LOW_SPEED_LIMIT/TIME to prevent git clones from hanging
- Force TLS 1.2 to work around GnuTLS negotiation bugs on older Debian
- Add curl retries, timeouts, and --retry-connrefused
- Add GitHub tarball fallback (no git clone needed at all)
- Add shallow clone (--depth 1) as final fallback
- Refactor install strategies into a clean cascade: binary → pipx →
pip git → tarball → shallow clone
Co-Authored-By: Claude Opus 4.6 <[email protected]>
User-entered line breaks were rendering as literal \n\n in the content
box because the static HTML injection didn't convert newlines to <br>
tags. Since Tor Browser disables JS, the fix must be server-side.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Sites now survive terminal close and can start automatically on boot:
- subprocess.Popen uses start_new_session=True (Unix) or
CREATE_NEW_PROCESS_GROUP (Windows) so onionshare-cli processes
are fully detached and immune to SIGHUP when the terminal exits
- New `voxvera start-all` / `stop-all` commands for non-interactive
batch control of all configured sites
- New `voxvera autostart` installs platform-appropriate boot service:
- Linux: systemd user service + loginctl enable-linger
- macOS: launchd LaunchAgent
- Windows: schtasks scheduled task on login
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Root cause: user-local werkzeug 2.0.3 in ~/.local/lib/python3.11/
site-packages shadows the system werkzeug 2.2.2, breaking Flask's
LocalProxy.unbound_message for the system onionshare-cli.
The pip3 show-based cleanup was unreliable (shows system package,
skips user-local). Two-pronged fix:
1. Set PYTHONNOUSERSITE=1 in the env passed to onionshare-cli so it
never loads packages from ~/.local — uses only system packages.
2. Install script now directly rm -rf's conflicting packages from
~/.local/lib/python3.*/site-packages/ instead of relying on pip3.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Previous pip --user installs left werkzeug 2.0.3 in ~/.local which
shadows the system werkzeug and breaks the system onionshare-cli
(Flask 2.2.2 requires werkzeug >= 2.2 for LocalProxy.unbound_message).
Changes:
- Remove flask, werkzeug, and onionshare-cli from voxvera's own
dependencies — they are onionshare's transitive deps, not ours
- Install script now cleans up stale user-local packages (werkzeug,
flask, flask-socketio, onionshare-cli, voxvera) before installing
- Prevents pip --user packages from poisoning system Python environment
Co-Authored-By: Claude Opus 4.6 <[email protected]>
The previous fix only used the system binary for non-frozen (pip/pipx)
installs. But the PyInstaller binary also needs this — it downloads
successfully but its bundled onionshare_cli import still crashes on
'No module named pkg_resources'.
Now both serve() and _internal_onionshare() unconditionally prefer the
system onionshare-cli/onionshare binary via shutil.which(), falling
back to the Python import only if no system binary exists.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Major fixes:
- Use system onionshare-cli binary directly (subprocess/execvp) instead of
importing it as a Python module, avoiding pkg_resources crashes in pipx venvs
- get_servers() now only searches DATA_DIR/host (single source of truth);
bundled example sites are seeded on first manage run then fully user-owned
- delete_server() now permanently removes sites (no ghost re-appearance)
- DATA_DIR defaults to ~/ instead of cwd, preventing sites from scattering
across directories
- Fix attachment URL logic that incorrectly overwrote valid onion URLs
Co-Authored-By: Claude Opus 4.6 <[email protected]>
The vendor directory was unconditionally prepended to sys.path, causing
pip/pipx installs to load incomplete vendored setuptools (missing data
files like Lorem ipsum.txt) instead of the system package. Now the
vendor path is only added for PyInstaller frozen builds, and the
force-import block in cli.py is similarly guarded behind sys.frozen.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
pipx can omit setuptools at runtime even when listed as a dependency,
causing onionshare-cli to crash on `from pkg_resources import resource_filename`.
Add explicit `pipx inject` after install and ensure setuptools is in deps.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Separated internal ROOT from persistent DATA_DIR to prevent user sites from being saved to the volatile PyInstaller _MEIPASS temp directory.
- Updated unit tests to correctly mock DATA_DIR and ensure complete isolation between tests.
- Fixed binaries.yml and requirements.txt to correctly bundle the pinned Flask/Werkzeug versions, preventing onionshare-cli import failures in the standalone binary.
- Pinned Flask<2.3.0 and Werkzeug<3.0.0 to fix TypeError in LocalProxy.
- Prepended vendor directory to sys.path for maximum robustness.
- Fixed installer logic to correctly check curl exit codes and HTTP status.
- Standardized binary names across all scripts.
- Updated ci/test-e2e.sh to manually inject the live Onion URL into config.json.
- Re-runs voxvera build after URL generation to ensure QR codes reflect the live address.
- Fixes verification failure where the URL wasn't being correctly propagated in CI.
- Removed unsupported --tor-mode argument from onionshare-cli calls in E2E script and tests.
- Fixed NameError: name 'os' is not defined in tests/test_e2e.py.
- Removed trailing whitespace in voxvera/cli.py.
- Verified all tests pass locally including E2E.
- Use ubuntu-20.04 for Linux builds to ensure compatibility with older GLIBC (like Debian 12).
- Standardized binary names to include architecture (voxvera-linux-x86_64).
- Improved install scripts to handle 404 errors and prevent empty file installation.
- Switched Linux build runner to ubuntu-22.04 for better glibc compatibility.
- Improved OnionShare URL detection in ci/test-e2e.sh using grep -a and extra stabilization.
- Explicitly set TOR_BINARY environment variable in voxvera/cli.py when using bundled Tor.
- Standardized artifact handling and release flattening in binaries.yml.
- Fixed hardcoded paths in build_appimage.sh and build_flatpak.sh to honor command-line arguments.
- Enhanced ci/test-e2e.sh to stop system Tor and manage a fresh instance on default ports for consistent testing.
- Explicitly configured OnionShare to use unmanaged Tor mode and specific ports in E2E script and tests.
- Improved Tor bootstrapping and reachability verification in CI.
- Optimized binaries.yml: split build and publish jobs, used unique artifact names, and added a flattening step for release assets.
- Enabled network-dependent E2E tests in e2e.yml.
- Improved ci/test-e2e.sh: used a dedicated Tor instance on custom ports (9052/9053) to avoid conflicts, increased timeouts, and added circuit stabilization delays.
- Improved Tor handling in ci/test-e2e.sh to coexist with system Tor.
- Increased OnionShare URL detection timeout to 120s with better logging.
- Added 5-attempt retry logic for Tor reachability verification.
- Added timeout-minutes to all CI/CD workflows to prevent hangs.
- Standardized installation and path handling in E2E script.
- Changed E2E site folder from demosite to voxvera to match the default configuration in voxvera/src/config.json and ensure tests verify the correct build output.
- Rewrote binaries.yml to use a two-job structure (build and publish) to avoid race conditions during release uploads.
- Added a 15-second initialization sleep to ci/test-e2e.sh to ensure OnionShare URLs are fully generated before verification.
- Use unique artifact names in binaries.yml to avoid upload conflicts.
- Standardize pip installation in ci/test-e2e.sh.
- Fix hardcoded paths in ci/test-e2e.sh and ensure it uses correct demosite folder.
- Ensure E2E tests in tests/test_e2e.py correctly patch _locale_res and use absolute paths for source assets.
- Updated binaries.yml to use ubuntu-latest for Linux packaging.
- Fixed Linux-specific build triggers (.deb, AppImage, Flatpak).
- Standardized binary preparation for packaging scripts.
- Improved dependency installation in ci.yml and e2e.yml using test/e2e extras.
- Synchronized and improved install.sh and voxvera-install.sh for better binary/pip fallback.
- Modified voxvera/cli.py to avoid overriding localized landing content if user config matches English defaults.
- Synchronized voxvera/src/config.json with site/config.json defaults for reliable comparison.
- Refreshed site/index.html and source bundle to reflect these changes.