Commit Graph

647 Commits

Author SHA1 Message Date
CyberMind
63c1321446
Merge pull request #10 from gkerma/release/v0.15.0
Release/v0.15.0
2026-01-25 06:31:46 +01:00
baa43f5027 fix(metabolizer): Set portal path to /www (root)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 06:27:07 +01:00
ab254bfdca fix(hexojs): Set portal path to /www (root)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 06:19:27 +01:00
12cc8eae39 feat(hexojs): Add generate alias and fix publish commands
- Add 'generate' as alias for 'build' command
- Rename cmd_publish for drafts to cmd_publish_draft
- Fix duplicate cmd_publish functions
- Add portal config section with /www/blog path
- publish draft <slug> for drafts, publish for portal
- Metabolizer integration now working

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 06:17:32 +01:00
7a3b3eca23 fix(haproxy): Parse inline servers and enable port editing
- RPCD _add_backend now parses inline 'server' option format
- Servers embedded in backend response with inline flag
- update_server converts inline servers to separate UCI sections
- delete_server handles both inline and separate server sections
- API and UI pass inline flag for proper handling

Fixes server port editing in LuCI backends interface.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 06:01:44 +01:00
3a5655451e feat(haproxy): Add edit functionality for backends, servers, and vhosts
- Add showEditVhostModal() for editing virtual host properties
- Add showEditBackendModal() for editing backend configuration
- Add showEditServerModal() for editing server properties
- Modern card-based UI with inline edit/delete actions
- Toggle enable/disable for backends
- Fix haproxyctl to read server option from backend UCI sections
- Add debug logging to container startup script

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 05:56:03 +01:00
b793ccb0d6 chore: Bump package releases
- luci-app-haproxy: r4 → r5
- secubox-app-haproxy: r1 → r2
- secubox-app-hexojs: r5 → r6

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 15:42:31 +01:00
b7b6332112 fix(hexojs): Remove /blog root path, use / as root
Change all hardcoded /blog/ paths to use / as root:

Theme configuration:
- _config.yml: Menu paths now /cybersecurity/ instead of /blog/cybersecurity/
- Blog submenu path changed to /categories/

Layout templates:
- post.ejs: Category link uses url_for with root path
- index.ejs: "Voir le blog" links to /categories/
- category.ejs: Breadcrumb and back links use /categories/

Scripts:
- dynamic-blog.js: Category paths now /{slug}/ instead of /blog/{slug}/
- Menu blog path changed to /categories/

Presets:
- tech.yml: Menu paths updated
- portfolio.yml: Blog link updated

hexoctl:
- Default portal_path changed from /www/blog to /www
- Help text updated

This allows the blog to be served from the root URL with categories
at /{category}/ paths.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 15:37:01 +01:00
172fd42072 fix(secubox-app-haproxy): Consistent pidfile name in init.d
Change pidfile from haproxy-lxc.pid to haproxy.pid for consistency
with the actual container name.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 15:34:01 +01:00
47b2e1b8e1 fix(luci-app-haproxy): Correct container name in RPCD backend
Change container references from 'haproxy-lxc' to 'haproxy' to match
the actual container name used by secubox-app-haproxy. This fixes
the LuCI status view showing container_running: false.

Fixes affected methods:
- method_status: container existence and state checks
- method_get_stats: container running check

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 15:31:58 +01:00
a91bd48c3a fix(hexojs): Use url_for() for all internal links in theme
Templates now properly use Hexo's url_for() helper:
- apps.ejs: navigation links
- category.ejs: breadcrumb, apps, services, blog links
- showcase.ejs: contact, portfolio, apps, services links

This ensures all links work correctly when root is set to a
subdirectory (e.g., /blog/ instead of /)

Bumped release to r5

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 14:40:45 +01:00
21105f1ef1 feat(hexojs): Publish command auto-sets Hexo root for subdirectory
- Calculate web root from portal path (e.g., /www/blog → /blog/)
- Update _config.yml root setting before regenerating
- Run hexo clean && generate to apply new root
- Bumped release to r4

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 14:29:37 +01:00
549e189059 fix(luci-gitea): Fix list_repos subshell bug causing empty repos
- Piped while loop runs in subshell, JSON additions don't persist
- Use temp file + redirect to avoid subshell issue
- Also fix list_backups with same pattern
- Bumped release to r2

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 14:27:58 +01:00
b17da12677 fix(hexojs): Bind server to 0.0.0.0, add publish command
- Server now binds to 0.0.0.0 instead of localhost for external access
- Added publish command to copy static files to /www/blog/
- Startup script always regenerates to ensure correct binding
- Bumped release to r3

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 14:23:04 +01:00
CyberMind
a9026358c0
Merge pull request #9 from gkerma/release/v0.15.0
Release/v0.15.0
2026-01-24 13:51:52 +01:00
170f4a90e2 feat(luci-hexojs): Add Gitea integration to sync page
- Add gitea_status, gitea_sync, gitea_clone, gitea_save_config RPCD methods
- Add Gitea section to sync.js with config form and sync buttons
- Update ACL for new Gitea methods
- Fix luci-app-metabolizer install section for RPCD executable

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 13:00:05 +01:00
70358370f6 fix(luci-metabolizer): Add explicit install for RPCD executable
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 12:57:18 +01:00
f9b73ea62c feat(hexojs): Add Gitea integration for content sync
- Add gitea config section to /etc/config/hexojs
- Add hexoctl gitea {setup|clone|sync|status} commands
- Token-based authentication for content repo cloning
- Auto-sync from Gitea to Hexo source directory
- Add comprehensive README documentation

Also:
- Create luci-app-metabolizer package with dashboard
- Update CMS pages with emoji names for Streamlit sidebar
- Bump hexojs to r2, metabolizer to r3

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 12:51:34 +01:00
35957e34ab fix(metabolizer): Remove yaml dependency, make CMS container-friendly
- Remove yaml import, use simple string parsing for front matter
- Remove dependency on host metabolizerctl
- Use environment variables for paths (METABOLIZER_CONTENT)
- Remove switch_page calls that fail in container
- CMS now works standalone inside Streamlit container
- Bump to r2

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 12:32:15 +01:00
5a2ef2d6ff fix(gitea): Set PATH at startup and fix SCRIPT_TYPE
- Export PATH at top of startup script for git binary
- Export HOME=/data for proper environment
- Set SCRIPT_TYPE=sh in app.ini (no bash in Alpine)
- Bump to r5

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 11:32:34 +01:00
9eed3a50d1 fix(gitea): Create git group explicitly before user
Alpine's adduser wasn't creating the group properly, causing
chown git:git to fail with "unknown group".

- Add explicit addgroup -g 1000 git before adduser
- Use -G git flag to assign user to the group
- Bump to r4

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 11:26:04 +01:00
9a8395d79c fix(gitea): Fix git user creation in container startup
- Use /bin/sh instead of /bin/bash for git user shell
- Check for su-exec binary instead of marker file for deps
- Always recreate git user on startup (doesn't persist in container)
- Set explicit UID 1000 for git user
- Bump release to r3

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 11:18:49 +01:00
7386c1a691 chore(gitea): Bump release to r2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 11:13:02 +01:00
944a0f8418 fix(gitea): Fix /data directory permissions for git user
- chown -R git:git /data at startup to fix permission issues
- chmod 755 on key directories
- Add /data/log directory

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 11:09:15 +01:00
5590bf375b fix(gitea): Fix LXC container startup issues
- Create /data, /opt, /run directories in rootfs during install
- Simplify mount entries (single /data mount)
- Ensure host data directories exist before creating LXC config
- Install dependencies (git, su-exec, etc.) on first container run
- Create required subdirectories in startup script

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 11:03:30 +01:00
029733884b fix(gitea): Improve init.d status feedback and enable by default
- Add is_installed() and is_running() checks to init.d
- Show reason when service not running (disabled/not installed)
- Enable gitea by default in UCI config
- Require installation before starting

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 10:58:37 +01:00
2941398c07 docs(metabolizer): Add README with pipeline documentation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 10:36:44 +01:00
474fe7830d feat(metabolizer): Add blog CMS pipeline with Gitea, Streamlit, HexoJS
Metabolizer Blog Pipeline - integrated CMS for SecuBox:
- Gitea: Mirror GitHub repos, store blog content
- Streamlit: CMS app with markdown editor and live preview
- HexoJS: Static site generator (clean → generate → publish)
- Webhooks: Auto-rebuild on git push
- Portal: Static blog served at /blog/

Pipeline: Edit in Streamlit CMS → Push to Gitea → Build with Hexo → Publish

Packages:
- secubox-app-streamlit: Streamlit server with LXC container
- luci-app-streamlit: LuCI dashboard for Streamlit apps
- secubox-app-metabolizer: CMS pipeline orchestrator

CMS Features:
- Two-column markdown editor with live preview
- YAML front matter editor
- Post management (drafts, publish, unpublish)
- Media library with image upload
- Git sync and Hexo build controls
- Cyberpunk theme styling

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 10:35:21 +01:00
d43a02a397 feat(gitea): Add self-hosted Git platform for OpenWrt
Add secubox-app-gitea and luci-app-gitea packages:

secubox-app-gitea:
- LXC container with Alpine 3.21 rootfs
- Gitea 1.22.6 binary (auto-detect amd64/arm64/armv7)
- HTTP (3000) and SSH (2222) ports
- SQLite database (embedded)
- giteactl: install/uninstall/update/backup/restore

luci-app-gitea:
- Cyberpunk themed dashboard
- Repository browser with clone URLs
- User management interface
- Server and security settings
- Backup/restore functionality
- 18 RPCD methods

Resource requirements: 256MB RAM minimum, ~100MB storage

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 10:03:31 +01:00
814a85754d style(cyberfeed): Amber & green CRT color scheme for timeline
- Amber (#ffb000) for titles, borders, hover effects
- Green (#33ff33) for dates, sources, navigation
- Gradient timeline line (amber → green → amber)
- Glow effects on text and borders
- Audio items highlighted in green
- Status bar with item count and sync time
- Emojified content from AWK parser preserved

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 03:58:12 +01:00
d04c0c6355 feat(cyberfeed): Split timeline with 1/3 CRT monitor + 2/3 standard
- Left panel (1/3): CRT monitor style with:
  - Phosphor green text with glow effect
  - Scanlines overlay
  - Screen curvature effect
  - Power LED with pulse animation
  - VT323 monospace font
  - Scrollable latest 15 items

- Right panel (2/3): Standard cyberpunk timeline with:
  - Vertical timeline with neon gradient line
  - Date grouping
  - Audio player support
  - Source badges

- Responsive: stacks vertically on mobile (CRT on top)
- Auto-refresh every 3 minutes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 03:53:48 +01:00
d07d6c414c feat(cyberfeed): Add Star Wars crawl timeline and fix array handling
- Add Star Wars opening crawl style timeline with:
  - Starfield background with twinkling stars
  - "A long time ago in a network far, far away...." intro
  - CYBERFEED logo zoom animation
  - 3D perspective text crawl (rotateX transform)
  - Yellow text (#ffd700) with cyan accents (#0ff)
  - Auto-refresh every 3 minutes
  - Controls: PAUSE, RESET, HOME, REFRESH

- Fix LuCI API array handling in getFeeds/getItems:
  - RPC `expect` declarations auto-extract nested properties
  - Response IS the array, not res.feeds/res.items
  - Add Array.isArray check to handle both cases

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 23:50:51 +01:00
7f517b91ab fix(cyberfeed): Move emojification inside AWK parser, fix item count
- Move emoji injection inside AWK parser to avoid corrupting JSON keys
- Use grep -o | wc -l for accurate item count on single-line JSON
- Emojis now only applied to title and desc fields, not URLs or keys

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 22:36:13 +01:00
179565cfca fix(cyberfeed): BusyBox AWK compatibility and settings form fixes
- Rewrite RSS parser to use BusyBox-compatible AWK (no capture groups)
  - Use extract_tag() helper with substr() instead of match() capture
  - Use extract_attr() helper for XML attribute extraction
- Fix settings.js select elements to properly set initial value
  - Use sel.value = ... instead of selected attribute
- Add new UCI config options for enhanced features:
  - download_media, media_dir, history_file, generate_timeline
- Bump versions: secubox-app-cyberfeed 0.2.1, luci-app-cyberfeed 0.1.1

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 22:25:00 +01:00
19c30ddce9 feat(cyberfeed): Add radio and podcast presets
- Add Radio France presets (France Inter, France Culture, France Info, FIP, Mouv)
- Add international radio (BBC World, NPR)
- Add tech podcasts (Darknet Diaries, Changelog, Syntax.fm)
- Add 'radio' category to feed selector
- One-click quick-add buttons for all radio presets

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 22:17:11 +01:00
0607ed5628 fix(cyberfeed): Wrap RPCD array responses in objects for LuCI RPC
- get_feeds now returns {"feeds": [...]} instead of raw array
- get_items now returns {"items": [...]} instead of raw array
- Updated api.js to extract arrays from wrapped responses
- Fixes feed list not displaying in LuCI dashboard

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 22:15:31 +01:00
22f6f26a01 feat(cyberfeed): Add CyberFeed RSS aggregator packages for OpenWrt
New packages:
- secubox-app-cyberfeed: Core RSS aggregator service
  - Pure shell script, OpenWrt compatible
  - Cyberpunk emoji injection based on content keywords
  - Caching with configurable TTL
  - JSON and HTML output with neon/glitch effects
  - RSS-Bridge support for social media (Facebook, Twitter, YouTube)

- luci-app-cyberfeed: LuCI dashboard with cyberpunk theme
  - Dashboard with stats, quick actions, recent items
  - Feed management with add/delete
  - RSS-Bridge templates for easy social media setup
  - Preview with category filtering
  - Settings page for service configuration

Features:
- Auto-emojification (security, tech, mystical themes)
- Dark neon UI with scanlines and glitch effects
- RSS-Bridge integration for Facebook/Twitter/YouTube
- Category-based filtering
- Auto-refresh via cron (5 min default)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 22:02:07 +01:00
45c9a4b7dc fix(haproxy): Fix NodeList rendering error in overview dashboard
- Add pollRegistered flag to prevent duplicate poll registration
- Fix refreshDashboard to use replaceChild instead of dom.content
- Build content arrays explicitly to avoid null values in arrays
- Fix disabled attribute handling for action buttons

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 20:34:40 +01:00
500e020809 feat(haproxy): Enhanced dashboard with SecuBox theme design system
- Complete CSS redesign using SecuBox design system patterns (hp-* classes)
- Added dark/light mode support via CSS variables
- Overview page with:
  - Gradient page header with status badges
  - Stats grid with animated cards (vhosts, backends, certs, status)
  - Health check grid (container, HAProxy, config, ports, stats)
  - Vhosts/backends/certificates preview cards
  - Quick actions with icon buttons (start/stop/reload/validate/generate/stats)
  - Connection details panel
  - Auto-refresh polling every 30 seconds
  - Toast notifications for feedback
- Vhosts page with:
  - Clean form for adding new virtual hosts
  - Enhanced table with SSL/ACME badges
  - Toggle and delete actions with confirmation modals
- Responsive layout for mobile/tablet
- Inter + JetBrains Mono fonts for modern typography

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 20:27:10 +01:00
22bd4bd445 fix(haproxy): Use module-level RPC declarations in api.js
Fix TypeError "haproxy.api factory yields invalid constructor" by
refactoring api.js to use correct LuCI module pattern:
- Define RPC calls at module level with rpc.declare()
- Reference them in baseclass.extend() object
- Add getDashboardData helper function at module level

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 20:15:48 +01:00
f3fd676ad1 feat(haproxy): Add HAProxy load balancer packages for OpenWrt
- Add secubox-app-haproxy: LXC-containerized HAProxy service
  - Alpine Linux container with HAProxy
  - Multi-certificate SSL/TLS termination with SNI routing
  - ACME/Let's Encrypt auto-renewal
  - Virtual hosts management
  - Backend health checks and load balancing

- Add luci-app-haproxy: Full LuCI web interface
  - Overview dashboard with service status
  - Virtual hosts management with SSL options
  - Backends and servers configuration
  - SSL certificate management (ACME + import)
  - ACLs and URL-based routing rules
  - Statistics dashboard and logs
  - Settings for ports, timeouts, ACME

- Update luci-app-secubox-portal:
  - Add Services category with HAProxy, HexoJS, PicoBrew,
    Tor Shield, Jellyfin, Home Assistant, AdGuard Home, Nextcloud
  - Make portal dynamic - only shows installed apps
  - Add empty state UI for sections with no apps
  - Remove 404 errors for uninstalled apps

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 20:09:32 +01:00
CyberMind
e8ce20ee0d
Merge pull request #8 from gkerma/release/v0.15.0
Release/v0.15.0
2026-01-23 19:38:04 +01:00
c86feaa6b0 fix(hexojs): Fix container startup and Hexo server execution
- Add start-hexo.sh script as container init command
- Set PATH properly for hexo CLI in lxc_exec()
- Container now starts Hexo server automatically on boot
- Falls back to tail -f /dev/null if no site exists

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 19:08:36 +01:00
a4970edc6f feat(hexojs): Add Hexo CMS packages for OpenWrt
- secubox-app-hexojs: LXC-containerized Hexo service with Node.js
  - hexoctl control script for container/site management
  - Bundled CyberMind theme with dark/light mode
  - Theme presets (minimal, tech, portfolio)
  - Post/page scaffolds

- luci-app-hexojs: Full CMS dashboard
  - Overview with stats and quick actions
  - Post editor with Markdown toolbar and preview
  - Media library browser
  - Categories and tags management
  - Apps portfolio for CyberMind theme
  - Build and deploy to GitHub Pages
  - GitHub Sync wizard (clone, pull, push)
  - Theme configuration and presets
  - Site settings

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 18:58:57 +01:00
23dac58741 feat(tor): Add Tor Shield packages for OpenWrt
Add secubox-app-tor (backend) and luci-app-tor-shield (frontend) packages
for Tor anonymization on OpenWrt.

Backend features:
- UCI configuration with presets (anonymous, selective, censored)
- procd init script with iptables transparent proxy
- torctl CLI tool for status, enable/disable, circuits, leak-test
- DNS over Tor and kill switch support
- Hidden services and bridge management

Frontend features:
- Modern purple/onion themed dashboard
- One-click master toggle with visual status
- Real-time circuit visualization (Guard -> Middle -> Exit)
- Hidden services (.onion) management with copy/QR
- Bridge configuration (obfs4, snowflake, meek-azure)
- Leak detection tests
- Advanced settings for ports and exit node restrictions

Note: LuCI package renamed to luci-app-tor-shield to avoid conflict
with existing luci-app-tor package in OpenWrt LuCI feeds.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 17:20:13 +01:00
4d08f99222 fix(picobrew): Pin Flask 1.1.2 compatible dependencies
Flask 1.1.2 requires specific old versions of dependencies:
- Jinja2==2.11.3 (escape moved in 3.1)
- markupsafe==1.1.1
- itsdangerous==1.1.0 (json removed in 2.x)
- Werkzeug==1.0.1
- click==7.1.2
- pybeerxml<2.0.0 (Parser import changed in 2.x)
- marshmallow<4.0.0

Also:
- Use pip-installed package instead of git repo mount
- Simplify LXC mounts to just data directories

Tested and working on OpenWrt 24.10.5.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 16:48:56 +01:00
b69a84394b feat(picobrew): Add PicoBrew Server packages for OpenWrt
Add two new packages for self-hosted brewing controller support:

secubox-app-picobrew:
- LXC container-based PicoBrew Server installation
- Alpine Linux rootfs with Python/Flask environment
- UCI configuration for port, memory, brewing defaults
- procd service management with respawn
- Commands: install, uninstall, update, status, logs, shell

luci-app-picobrew:
- Modern dashboard UI with SecuBox styling
- Service controls (start/stop/restart/install/update)
- Real-time status monitoring and logs
- Settings page for server and brewing configuration
- RPCD backend with full API coverage

Supports PicoBrew Zymatic, Z, Pico C, and Pico Pro devices.
Repository: https://github.com/CyberMind-FR/picobrew-server

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 12:53:31 +01:00
14690ebe9e fix(wireguard-dashboard): Use qrcode module in wizard.js
The wizard.js was looking for a global QRCode object that doesn't exist.
Updated to import and use our qrcode module like other views do.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 12:42:16 +01:00
2a4423d036 fix(wireguard-dashboard): Fix QR library module export pattern
Changed from baseclass.extend() to simple object return pattern
to match other libraries (chart.js). The baseclass dependency
was causing the module to fail loading.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 12:39:20 +01:00
2f16875c4b fix(wireguard-dashboard): Upgrade QR code generator to support larger configs
The JavaScript QR code fallback was limited to Version 5 (106 bytes max),
but WireGuard configs are typically 200-250 bytes. This caused QR code
generation to fail when the backend qrencode binary is not installed.

Changes:
- Auto-select optimal QR version (1-20) based on data length
- Support up to 858 bytes (Version 20)
- Proper Reed-Solomon error correction with dynamic generator polynomials
- Data interleaving for multiple EC blocks
- Alignment patterns for all versions
- Version info encoding for version 7+
- Quiet zone in SVG output

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 12:35:34 +01:00