- Add MENU_CACHE_FILE for persistent cache across restarts
- Add _menu_cache in-memory cache for instant responses
- Add _refresh_menu_cache() background task (30s interval)
- Add _compute_menu_sync() for thread-pool execution
- Load cache from file on startup for fast navbar display
- Menu endpoint now responds in ~80ms vs previous slow computation
Fixes navbar latency issue on ESPRESSObin.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Changed field_validator to validator for Pydantic 1.x
- Changed model_dump() to dict() for v1 compat
- Services deployed: crowdsec, haproxy, waf, dns on ports 8010-8013
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Applied LXC memory limit to fix Gitea memory leak on MOCHAbin.
Load average dropped from 6.80 to 4.07.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Session 79: Added benchmark suite for ARM64 optimization including
api-latency.py, memory-baseline.sh, startup-time.sh, cpu-profile.sh,
and locustfile.py. Documented performance targets and MOCHAbin analysis.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace hard drive icon with classic 3.5" floppy disk icon for the
DISK metric on Eye Remote display. More recognizable and nostalgic.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Compact all metric symbols to fit within the 30px targeting glow:
- CPU: 20px chip with shorter pins
- MEM: 36x16px RAM stick
- DISK: 24px disk with spindle
- LOAD: 28px gauge arc
- TEMP: 30px thermometer
- WiFi: 22px signal arcs
Symbols only appear when ONLINE and radar targets module.
Offline mode (local metrics) unchanged - shows module icons.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When the radar sweep targets a module icon, temporarily replace
the module icon with a metric symbol representing its function:
- AUTH → CPU chip with pins
- WALL → RAM stick with chips
- BOOT → Hard drive cylinder
- MIND → Gauge with dynamic needle
- ROOT → Thermometer with level
- MESH → WiFi signal arcs
Symbols are drawn using PIL primitives for crisp rendering.
Original module icon returns when radar moves away.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Clean up display by removing module label/value text overlays.
Only icons and rings are shown now for a cleaner look.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Switch from HTTP:8000 to HTTPS:443 (nginx reverse proxy)
- Add SSL context for self-signed certificate bypass
- Handle ESPRESSObin field names (memory_used_percent, disk_used_percent)
- Add synchronous initial fetch on OFFLINE→ONLINE transition
- Fix race condition: don't overwrite API values with local metrics
- Add /api/v1/eye-remote/api/system/info as primary endpoint
- Add ESPRESSObin main network IP (192.168.255.250) as fallback
- Network: Pi Zero W (10.55.0.2) ← OTG USB → ESPRESSObin (10.55.0.1)
This fixes the issue where Pi Zero W display showed local metrics
instead of remote ESPRESSObin metrics when connected via OTG.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The 'validate' field name in ImportRequest shadows Pydantic's BaseModel
validate method, causing NameError on Pydantic 1.x. Renamed to 'do_validate'.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added service exclusion capability to migration-export.sh:
- New --exclude-services parameter accepts comma-separated list
- Skips specified /srv/* directories during export
- Useful for excluding large services (nextcloud, peertube, gitea, lxc)
Example: --exclude-services "nextcloud,peertube,gitea,lxc,photoprism"
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
All fixes for VM-x64 kiosk issues are in place:
- Chromium sandbox: --no-sandbox flag
- Unix socket: Changed to TCP port 8001
- Menu endpoint: Added public /api/v1/hub/public/menu
- Pydantic 1.x: Optional[HTTPAuthorizationCredentials] syntax
Closes#34
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Menu/sidebar "Invalid menu data" error is now FIXED
- Added resolution steps and explanation
- Reference commit b2c9f01 for the fix
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add /api/v1/hub/public/menu endpoint (no auth required)
- Update sidebar.js to use public menu endpoint
- Resolves "Failed to load menu: Invalid menu data" error
- The protected /api/v1/hub/menu endpoint still requires JWT
The WebUI sidebar needs to load the menu before user authentication.
This adds a public version of the menu endpoint that returns the
same data without requiring a JWT token.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Eye Remote Interactive UI enhancements:
- TTY mode: Serial terminal display from /dev/ttyGS0
- Flash mode: Progress bar with speed/ETA for USB transfers
- Auth mode: QR code generation for backup authentication
- Mode detection via /etc/secubox/gadget-mode
Hub service VM compatibility fix:
- Changed from Unix socket to TCP port 8001
- Updated nginx configs for TCP proxy
- Fixes 502 errors in VirtualBox VMs
Also includes:
- FAQ/Troubleshooting wiki page with GitHub issue links
- Kiosk launcher --no-sandbox fix for VMs
- Profile Generator GUI mockup
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The require_jwt dependency used Python 3.10+ union syntax
(HTTPAuthorizationCredentials | None) with Annotated, which
causes FastAPI 0.92/Pydantic 1.10 to incorrectly require a
request body on GET endpoints.
Changed to Optional[HTTPAuthorizationCredentials] = Depends(_bearer)
which is compatible with older FastAPI/Pydantic versions.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add CORS headers to nginx secubox-proxy.conf for cross-origin API requests
- Fix login.html endpoints: /auth/login -> /login
- Upgrade Python deps in build scripts: pydantic>=2.0, fastapi>=0.100, uvicorn>=0.25
- Add pip upgrade in secubox-core postinst for Debian bookworm compatibility
- Fix display/__init__.py to import existing modules only
Fixes authentication and API issues in VBox and ebin builds.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Each colored arc now points toward its corresponding icon
- Fixed green/purple and red/yellow position mapping
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Icons in circle: rouge, orange, jaune, vert, bleu, violet
- Color fixes: BOOT=red, AUTH=orange, WALL=yellow
- Direct radar targeting sync (no offset)
- Complementary colors opposite each other
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove old display modes (mode_dashboard, mode_flash, mode_gateway, mode_local, renderer)
- Add display_manager.py with boot/halt splash screens
- Update fallback_manager.py with double-buffered API fetch
- Fix icon/radar alignment (-1 offset)
- Enable ONLINE mode with local metrics fallback when API unavailable
- Add logo_fallback.py for endless animated logo
- Bump version to 2.3.0
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fetch metrics from SecuBox gateway API (OTG/WiFi fallback)
- Radar sweep targets icons - highlights current module
- Display specific metrics for targeted module in center
- OFFLINE: single centered icon cycling with its metric value
- ONLINE: all icons with targeted one highlighted + metrics
- Module-specific metrics mapping (CPU/MEM/DISK/LOAD/TEMP/NET)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use 48px PNG icons (double size) for better visibility
- Icons positioned further from center (r=62)
- OFFLINE mode: same radar with single cycling icon (2s interval)
- ONLINE mode: all 6 icons displayed in hexagon
- Remove central texts (SECUBOX, time, status)
- Add cursor hiding on framebuffer console
- Tube-style metric arcs (darker outside, lighter inside)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Thinner rings (14px) with larger center area
- Tube effect: darker outside, lighter inside highlight
- Load PNG icons (22px) for center and cube faces
- Radar sweep colored by crossed metric rings
- Static icon positions in ONLINE mode (no rotation)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove all shadow effects for CPU efficiency
- Remove garbage dots at arc endpoints
- Remove alpha transparency (causes rendering issues)
- Simplify sweep line rendering
- Add metric-blended color to radar sweep
- Clean center hub and icon rendering
- Keep dice for OFFLINE, icons for ONLINE modes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Display improvements:
- Real Pi Zero metrics (CPU, MEM, DISK, LOAD, TEMP, NET)
- Logarithmic scale for LOAD and NETWORK metrics
- 2.5D depth effect with shadows and highlights
- Sweep line acts as dynamic moving light source
- Shadows cast opposite to sweep direction
- Specular highlights intensify when facing light
- Rainbow clock dots with 3D sphere effect
- Inset center hub with glossy edge
- Status LED with glass reflection
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Display priority system:
1. First boot sensor - touchpad noise calibration
2. Fallback manager - main OFFLINE/ONLINE dashboard
3. Logo fallback - endless breathing phoenix animation
Logo is the ultimate fallback when all dashboards stop.
Display manager auto-restarts crashed displays.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Display system for Pi Zero Eye Remote (HyperPixel 2.1 Round 480x480):
Splash Screen (splash.py):
- Animated phoenix logo for boot/halt/start/reboot states
- Pulsing glow effects with fire colors
- Progress indicator ring with rotating dots
- Fallback phoenix symbol if logo image missing
Fallback Display Manager (fallback_manager.py):
- Connection state detection (OTG 10.55.0.1, WiFi secubox.local)
- Four modes: OFFLINE, CONNECTING, ONLINE, COMMUNICATING
- Local metrics radar with 6 concentric rings
- 3D rotating cube with module icons when connected
- Rainbow sweep line animation
Touch Analysis Tools:
- touch_analyzer.py: Noise pattern analysis (Y-axis oscillation at stable X)
- touch_calibrate.py: Corner target display for manual calibration
- touch_filter.py: X-stable noise filtering
Radar Variants:
- radar_flashy.py: Vibrant colors with 3D cube
- radar_concentric.py: Balanced metric arcs centered at 12 o'clock
- radar_rainbow.py: Rainbow colorization with sweep
- radar_full.py: Complete feature set
Also includes:
- Hardware Smart-Strip module specs (SBX-STR-01)
- Host configuration for USB OTG network
- Systemd service for USB auto-mode
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
HyperPixel 2.1 Round uses 32-bit BGRA framebuffer, not 16-bit RGB565.
The renderer now auto-detects the bits-per-pixel and converts:
- 32 bpp: BGRA32 (HyperPixel DPI displays)
- 24 bpp: BGR
- 16 bpp: RGB565
This fixes the "two small circles" display bug.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Build script improvements:
- Copy agent/display/, agent/secubox/, agent/system/, agent/web/
subdirectories (were missing, causing import errors)
- Add pip install for httpx, fastapi, uvicorn, websockets
(not available in Debian repos)
- Disable old fb-dashboard service (use secubox-eye-agent instead)
- Add vt.global_cursor_default=0 to cmdline.txt to hide cursor
(keeps tty for console access)
This fixes the agent crash loop on first boot.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Eye Remote is a standalone gadget addon - it should not install
SecuBox packages. It connects to SecuBox via USB OTG and displays
metrics from the main appliance.
Changes:
- Remove entire SecuBox package slipstream section (was erroneously
trying to install amd64 packages on armhf Pi Zero)
- Add APT/dpkg cleanup before package installation to fix corruption
from previous failed builds
- Fix removes/cleans corrupted apt lists and dpkg status
This fixes GitHub Actions builds that were failing due to APT errors
in the QEMU chroot environment.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix glob pattern in bash test (glob in [[ -f ]] doesn't work correctly)
- Use find command instead of glob for reliable kernel detection
- Add fallback to extract ARM64 kernel from live USB image if not in rootfs
- Add verification step in GitHub Actions to check boot files after build
- Sort kernel files by version to get latest when multiple exist
Fixes missing vmlinuz/Image on multiboot USB issue.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Download latest multiboot image from GitHub releases
- SHA256 checksum verification
- Flash to USB with progress and confirmation
- Supports --list, --download, --release, --force options
- Document in scripts/README.md
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Device-Categories.md documenting AUTH→MESH Hamiltonian path
- Document color palette, HID mapping, I²C registers
- Update _Sidebar.md with new WALL — Hardware section
- Link to Smart-Strip and Eye-Remote device pages
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
python3-cryptography and python3-jose fail during debootstrap due
to complex dependencies. Moving to post-debootstrap apt-get install.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
python3-zmq has complex dependencies that fail during debootstrap.
Moving it to post-debootstrap apt-get installation resolves this.
Also removed from INCLUDE_PKGS in build-image.sh - installed via pip.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The 'arping' and 'iputils-arping' packages conflict with each other.
Using iputils-arping which provides the arping command needed by
the network fallback scripts.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Install live-boot package and rebuild initramfs with live-boot scripts
- Create squashfs filesystem (878MB) on data partition sda4
- Update boot.scr with live boot parameters (boot=live, toram)
- Fix wiki sidebar links from [[Page|Display]] to [Display](Page)
- Add Eye-Remote wiki page documentation
- Add sync-wiki.sh script for wiki repository sync
- Add patch-multiboot-efi.sh for post-build EFI patching
Partition layout:
- sda1 (512MB): EFI with kernel, initrd, dtbs, boot.scr
- sda2 (3GB): ARM64 rootfs reference
- sda3 (3GB): x86 rootfs for VirtualBox/QEMU
- sda4 (9.5GB): Data + /live/filesystem.squashfs
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add announcement banner on wiki home for v2.2.3 multiboot release
- Create wiki/Multiboot.md with full multiboot documentation
- Add Multiboot and Eye Remote links to sidebar navigation
- Update sidebar version to v2.2.3
- Document Eye Remote Pi Zero as USB gadget for ESPRESSObin boot
- Add partition layout, boot flow, and troubleshooting docs
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Changed [[ -z "$VAR" ]] && err to if/then/fi pattern
- This prevents early exit when condition is false with set -e
- Removed --minimal flag to install full SecuBox packages
Note: SecuBox packages on AMD64 still require apt.secubox.in SSL fix
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The auth router has routes like /login, so needs prefix="/auth"
to create proper /auth/login endpoint.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- postinst creates /etc/haproxy if haproxy package not installed
- Remove RuntimeDirectory=haproxy to avoid NAMESPACE errors
- Fixes systemd namespace setup failure when haproxy not present
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move directory creation from import-time to startup event
- Add try/except to handle permission errors gracefully
- Create haproxy data directories in postinst
- Increase RestartSec from 5s to 30s
- Add StartLimitBurst to prevent rapid restart spam
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extended mv88e6xxx blacklist to include mv88e6085 subdriver and added
initcall_blacklist for built-in driver scenarios. Fixes detection loop
on ESPRESSObin v7 during USB boot via Eye Remote.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Home.md: SecuBox OS as main product with full documentation
- _Sidebar.md: Eye Remote moved to "Addons" section
- Eye-Remote.md: Marked as optional addon, not main feature
The wiki now presents SecuBox OS as the core product with:
- Complete module stack (125 modules)
- ARM64 + x86_64 support
- Security features (firewall, IDS, WAF, DPI)
- Eye Remote as optional monitoring addon
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- docs/TOOLS.md: Complete reference of all build/generation tools
- scripts/README.md: Documentation for scripts directory
- remote-ui/README.md: Documentation for remote-ui module
Also fix build-storage-img.sh to use same slipstream logic as
build-ebin-live-usb.sh:
- Search packages in output/debs AND ~/.cache/secubox/debs
- Use dpkg -i --force-depends --force-overwrite (faster)
- Install all packages at once instead of per-package apt
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Copy SecuBox .deb packages from output/debs into chroot
- Install secubox-core first as dependency
- Install remaining packages with dpkg --force-depends
- Fix broken dependencies with apt-get -f install
Note: amd64 packages will fail on armhf (expected behavior)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove stdbuf from chroot commands (doesn't work with chroot)
- Add dpkg --configure -a before apt operations to fix interrupted state
- Fix losetup stderr warning polluting LOOP_DEV variable
- Expand Pi Zero image to 3.5GB+ to fit embedded 2.4GB storage.img
- Replace 'timeout | tee' with tail -f background + direct redirect
Fixes:
- QEMU chroot hangs due to buffering issues
- /dev/zero, /dev/null missing after aggressive umount cleanup
- "No space left on device" when embedding storage.img
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace 'timeout | tee' pattern with tail -f background + direct redirect
(timeout only applies to left side of pipe, tee can block indefinitely)
- Add stdbuf -oL -eL to force line-buffered output under QEMU emulation
- Remove 2>/dev/null from apt-get to prevent output suppression stalls
- Remove -qq flag from apt-get update to allow progress output
- Add progress counters for package installation
The root cause was that when QEMU produces slow/bursty output, tee buffers
it and can hang waiting for more data, but timeout doesn't kill the pipeline
because tee (not the timed command) is the blocking process.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add 5 min timeout per package in dpkg-buildpackage calls
- Add 10-20 min timeout for QEMU chroot apt operations
- Add 45 min timeout for sub-script execution
- Add 15 min timeout with retries for wget downloads
- Fix pipe to tail pattern that swallowed exit codes
- Add progress logging for QEMU package installation
- Use writable log directory (output/logs) instead of /tmp
- Add --verbose flag to build-eye-remote-full.sh
- Export VERBOSE for sub-scripts
Fixes hangs caused by:
- dpkg-buildpackage | tail -5 buffering issues
- QEMU chroot apt-get with no timeout
- Network operations with no timeout
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix callback signature for on_menu_render (wrap with lambda)
- Fix fleet status access to use cached data synchronously
- Fix Dict type annotation in device_status_message
- Fix unused lambda parameter naming
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add comprehensive command line argument parsing:
--config, --port, --no-display, --simulate, --verbose, --version
- Integrate all new components:
- ModeManager for 4 operating modes (Dashboard/Local/Flash/Gateway)
- FailoverMonitor for connection monitoring and graceful degradation
- System controllers (WifiManager, BluetoothManager, DisplayController)
- DeviceManager and FleetAggregator for SecuBox management
- WebServer for HTTP API
- Display renderers for each mode
- Add proper signal handling for graceful shutdown
- Export all renderers from display/__init__.py
- Fix import handling to work both as package and as script
- Version: 2.1.0
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add WebSocket endpoint at /ws for real-time communication with connected
web clients. Includes ConnectionManager for tracking connections and
broadcasting updates, plus helper functions for creating standardized
messages for mode changes, metrics, alerts, and device status.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add mobile-friendly web control interface for touchless control from phone/tablet.
Features:
- Sticky header with connection status and current mode badge
- Mode selector (Dashboard, Local, Flash, Gateway)
- WiFi panel with scan, connect, and disconnect
- Bluetooth panel with enable/disable toggle, scan, pair, forget
- Display panel with brightness slider and timeout settings
- SecuBox panel showing metrics and alerts (Dashboard mode only)
- System panel with info and reboot functionality
- Toast notifications for user feedback
- Confirmation modal for reboot action
Styling uses SecuBox cyberpunk palette (dark theme).
File size: ~49KB, under 50KB limit.
Vanilla JS with no external dependencies.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements FleetAggregator class that combines metrics and alerts from
multiple SecuBox devices for unified dashboard view. Features include:
- FleetMetrics dataclass with aggregated stats (avg/max CPU, memory, disk)
- DeviceStatus dataclass for per-device status summary
- Background polling with configurable intervals
- Thread-safe operations via asyncio.Lock
- Aggregated alerts sorted by timestamp across all devices
- Manual device refresh capability
- Automatic online/offline tracking with DeviceManager integration
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add async HTTP client for communicating with SecuBox devices via REST API.
Provides methods for fetching metrics, alerts, module status, and issuing
commands like module restart and security lockdown.
Components:
- SecuBoxClient: Async httpx-based client with JWT auth support
- SecuBoxMetrics: Dataclass for system metrics (CPU, mem, disk, temp)
- SecuBoxModule: Dataclass for security module status
- SecuBoxAlert: Dataclass for security alerts
Features:
- Context manager support for proper resource cleanup
- Configurable timeout and token authentication
- Graceful error handling for connection/timeout issues
- 19 comprehensive unit tests
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Connect WifiManager, BluetoothManager, and DisplayController to
FastAPI routes, replacing stub implementations with real controller
calls. Controllers are injected into app.state in create_app() and
WebServer, creating defaults if not provided.
Routes now properly delegate to controllers for:
- WiFi: status, networks, scan, connect, disconnect
- Bluetooth: status, devices, scan, enable, disable, pair, forget
- Display: settings, brightness, timeout, wake, sleep
All routes include proper error handling with HTTPException(500)
on failures.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add BluetoothManager class that wraps bluetoothctl commands to provide
an async interface for Bluetooth device management on Pi Zero W.
Features:
- scan(): Discover nearby Bluetooth devices
- pair()/connect()/disconnect(): Device pairing and connection
- list_devices(): List paired devices
- forget(): Remove paired devices
- status(): Get adapter status (powered, discovering, pairable)
- enable()/disable(): Power adapter on/off
- trust()/untrust(): Manage device trust for auto-reconnect
Includes comprehensive test suite with 39 tests covering all methods,
edge cases, error handling, and timeout scenarios.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add DisplayController class that provides async control of display brightness
and power for the HyperPixel 2.1 Round display on Eye Remote devices.
Features:
- Brightness control (0-100%) via sysfs backlight interface
- Power management (sleep/wake) via bl_power
- Timeout-based auto-sleep with activity tracking
- Simulation mode when hardware not available (graceful fallback)
- Thread-safe async operations with locking
- Support for custom backlight devices
Includes 31 comprehensive tests covering:
- Brightness get/set operations
- Power state transitions
- Timeout functionality
- Simulation mode behavior
- Edge cases and error handling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements WifiManager class for managing WiFi connections using nmcli
commands. Includes scan, connect, disconnect, status, and network
caching functionality with proper error handling and timeouts.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement Task 10 - FastAPI server foundation for Eye Remote web control.
New files:
- web/__init__.py: Package exports (create_app, WebServer)
- web/server.py: FastAPI app factory with embedded control HTML
- web/routes/mode.py: Mode control endpoints (GET/POST /api/mode)
- web/routes/wifi.py: WiFi status and configuration stubs
- web/routes/bluetooth.py: Bluetooth management stubs
- web/routes/display.py: Display settings endpoints
- web/routes/devices.py: SecuBox fleet management stubs
- web/routes/system.py: System info and control endpoints
- web/routes/secubox.py: SecuBox connection and metrics stubs
- web/static/.gitkeep: Placeholder for custom control.html
Features:
- Health endpoint at /api/health
- Control page at /control with embedded responsive UI
- Mode routes with actual ModeManager integration
- All other routes as stubs for future implementation
- WebServer class for uvicorn lifecycle management
- 29 comprehensive tests for all endpoints
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add assert statements for _frame not None before return
- Fix tuple type handling in mode_dashboard.py with explicit unpacking
- Fix unused variable warnings (_ctx parameter)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create DashboardRenderer class extending DisplayRenderer
- Render 6 concentric metric rings (AUTH/WALL/BOOT/MIND/ROOT/MESH)
- Normalize metrics for CPU%, MEM%, DISK%, LOAD avg, TEMP°C, WiFi dBm
- Display time, hostname, uptime in center
- Show system status (NOMINAL/WARNING/CRITICAL)
- Handle connection states (connected/degraded/stale/disconnected)
- Add pulsing animation effect for stale state
- Include comprehensive test suite with 30 test cases
- Cover metrics, normalization, connection states, animation, edge cases
Implement FlashRenderer class that displays USB storage status and flash
progress for ESPRESSObin recovery operations. Includes comprehensive test
suite covering progress bar rendering, storage detection, and edge cases.
Files:
- remote-ui/round/agent/display/mode_flash.py: Flash mode display implementation
- remote-ui/round/tests/test_mode_flash.py: 27 test cases
- remote-ui/round/agent/display/__init__.py: Export FlashRenderer
All tests passing (27/27). Ready for integration with mode manager.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement Task 5: Extend Config for New Settings with comprehensive
configuration support for the Eye Remote Swiss Army dashboard:
- Added DisplayConfig: brightness, timeout, theme settings
- Added ModeConfig: default mode, auto-fallback, reconnect timing
- Added WebConfig: web server port and binding configuration
- Refactored SecuBoxConfig into SecuBoxesConfig fleet container
- Updated load_config() to parse all new sections from TOML
- Maintained backward compatibility with old [[secubox]] array format
- Created /etc/secubox/eye-remote/eye-remote.toml example config
- Updated DeviceManager to work with new config structure
- Added 11 new test cases covering all config sections
- All 22 config+device tests passing
Files changed:
- remote-ui/round/agent/config.py: Extended with new dataclasses
- remote-ui/round/agent/device_manager.py: Fixed imports, updated iteration
- remote-ui/round/files/etc/secubox/eye-remote/eye-remote.toml: New config template
- remote-ui/round/tests/test_config.py: 11 new tests
- remote-ui/round/tests/test_device_manager.py: Updated fixtures
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create Mode enum with 4 operating modes: DASHBOARD, LOCAL, FLASH, GATEWAY
- Implement ModeManager class with async state machine
- Add support for mode listeners and transitions
- Implement flag file checking for forced modes (FORCE_FLASH, FORCE_GATEWAY)
- Add API availability detection and auto-mode selection
- Include comprehensive test suite with 12 test cases covering:
- Enum values validation
- Manager initialization
- Mode transitions (sync and concurrent)
- Listener management and error handling
- Flag file detection
- Initial mode determination based on API availability
This provides the foundation for Eye Remote Swiss Army Dashboard
to switch between display modes based on system state.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 4 operating modes: Dashboard, Local, Flash, Gateway
- Web Remote control at :8080 (touchless)
- Auto-detect + flag file override for mode switching
- Staged failover with visual feedback
- Unified Python Agent architecture
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add logging to show which display mode is being rendered
(DASHBOARD, MENU, UBOOT) to help debug display issues.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add TOUCH_ENABLED flag (set to False) to completely disable touch
input on HyperPixel 2.1 Round displays with defective ft5x06 controller.
When disabled, system stays in dashboard mode permanently.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add DASHBOARD mode rendering with live metrics display
- Add UBOOT mode with correct ESPRESSObin v7 flash commands
- Start in DASHBOARD mode by default (not menu)
- Disable menu access when touchscreen is disabled
- Update metrics display on each poll cycle
- Fix U-Boot gzwrite command for eMMC flashing
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Expand mass storage from 64MB to 2GB to accommodate full SecuBox
live USB images for ESPRESSObin deployment.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add 64MB FAT32 storage image at /var/lib/secubox/eye-remote/storage.img
- Configure mass_storage.usb0 function with removable flag
- Create storage image automatically on first boot using sparse file
- Update gadget status to report storage state
- Bump version to 2.3.0
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Hardware investigation confirmed HyperPixel 2.1 Round ghost touch issue
is a known hardware defect (Pimoroni forums). Driver sysfs parameters
(threshold/gain) are read-only on this variant.
Changes:
- Add SWIPE_UP from bottom as menu trigger (replaces unreliable long press)
- Add long press accumulator for ghost-interrupted touches
- Expand CENTER_RADIUS to 220px for scattered touch positions
- Add position consistency and duration checks
- Lower thresholds for ghost-heavy hardware
- Add debug logging for SWIPE_UP detection
Note: Touch disabled on this unit due to hardware defect. Unit needs
warranty replacement for functional touch input.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The ft5x06 capacitive touch controller on HyperPixel 2.1 Round generates
spurious touch events due to EMI/display interference. This adds software
filtering to handle the noise without blocking legitimate touches.
Filtering strategies:
- Minimum touch duration (50ms) filters ultra-short phantom touches
- Debounce period (200ms) between gestures
- Edge zone filtering (8px margin) catches edge ghost touches
- Contact rate limiting (5/sec max) prevents rapid false contacts
- Position validation catches Y=0 ghost touch pattern
The hardware generates ~200 events/sec of noise, but the filter now
correctly blocks all false gestures while allowing real user input.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Pi-side fixes:
- Add DNS config (8.8.8.8) to usb-network-up.sh
- Add secubox-fb-dashboard.service with console disable
- Disable vtcon1 to prevent text overlay on display
Host-side fixes:
- Add NAT/masquerade for Pi internet access
- Auto-detect default interface for routing
Tested: Full connectivity Pi <-> Host <-> Internet
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Prevent NetworkManager on host from managing the USB gadget
interface, which was clearing the static IP configuration.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Interface name changes from usb0 to enxXXX after rename.
Script now finds interface by MAC address instead of relying
on udev-passed kernel name.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Automatically configures 10.55.0.1/30 on host when Pi Zero gadget
connects. Install on SecuBox host with:
sudo cp host-install/etc/udev/rules.d/* /etc/udev/rules.d/
sudo cp host-install/usr/local/bin/* /usr/local/bin/
sudo udevadm control --reload-rules
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
NetworkManager was fighting with static IP configuration, causing
the usb0 interface to cycle and drop connectivity.
Changes:
- Add 99-secubox-unmanaged.conf to exclude usb0/usb1 from NM
- Add interfaces.d/usb0 for ifupdown static config
- Update usb-network.service and usb-network-up.sh
Tested: ping to 10.55.0.2 now works reliably over USB OTG.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Root cause: symlink paths were wrong. Using `ln -sf ../../functions/ecm.usb0`
instead of `ln -sf functions/ecm.usb0` (relative to gadget root).
Changes:
- Simplified script to ~100 lines (was ~300+)
- Removed UDC wait loop (not needed with proper service ordering)
- Removed complex MAC generation (use simple valid MACs)
- Removed optional mass_storage (can add back later)
- Fixed symlink paths: relative to gadget root, not configs/c.1
- Added proper cleanup in gadget_down()
- Version 2.2.0
Tested: USB gadget now works - host sees CDC Ethernet + ACM serial.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The gadget-setup.sh was failing because it checked for UDC immediately
after boot, before dwc2 had time to initialize. Now it waits up to 15
seconds with polling for the UDC to become available.
Changes:
- Add wait loop (30 × 0.5s) for UDC in check_prerequisites()
- Add dwc2 modprobe to service ExecStartPre
- Add sys-kernel-config.mount dependency
- Increase TimeoutStartSec to 60s
- Better logging for debug
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Make mass storage optional in gadget-setup.sh (ECM+ACM only if no boot media)
- Fix UDC detection using ls instead of find (sysfs symlinks issue)
- Add modprobe.d config for dwc2 dr_mode=peripheral
- Revert to original RGBA icons in radial_renderer.py (colored icons on colored slices)
- Add comment in build script about dr_mode modprobe config
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Sidebar: Clear separation between SecuBox and Eye Remote sections
- Home: SecuBox focused with Eye Remote as compact subsection
- Eye-Remote.md: New index page for all Eye Remote docs
- Clean navbar structure with module colors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Convert icons to white using alpha channel as mask
- Icons now visible on colored slice backgrounds
- Simplified icon loading with absolute path
- Radial positioning for icons and labels
- Added wiki page documenting all icons
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
ProtectSystem=strict was blocking access to /sys/class/udc which is
needed for USB gadget UDC detection and binding.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The "find -type l ! -exec test -e" approach deletes symlinks that point
to /lib/systemd/system/* because they appear "broken" from the host
perspective, but are valid on the target system.
Replace with explicit service enabling for all required services:
- pigpiod, ssh (core)
- hyperpixel2r-init (display)
- secubox-eye-gadget, secubox-eye-agent, usb-network (eye-remote)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Base Raspberry Pi OS image has services enabled that aren't installed.
These broken symlinks can cause boot failures. Now cleaned up during build.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
configfs in fstab causes boot hang if module isn't loaded early enough.
The gadget-setup.sh already handles mounting configfs on demand.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
USB OTG Network:
- Add usb-network.service and usb-network-up.sh to sources
- Handle both usb0 and usb1 interfaces (ECM creates usb1 on some kernels)
- Update build script to use file copies instead of inline heredocs
Touch Input:
- Add main_standalone.py v1.3 with touch debouncing
- DEBOUNCE_MS=500, MIN_TOUCH_MS=50 to filter phantom touches
- Filter (0,0) coordinate touches
- Add deploy_to_sd.sh for quick SD card updates
Display:
- Add icon directory logging to radial_renderer.py
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Try relative, system, and alternative icon directories
- Add null check for icon name
- Improve logging for icon loading
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Read bpp from /sys/class/graphics/fb0/bits_per_pixel
- Read dimensions from /sys/class/graphics/fb0/virtual_size
- Handle 16/24/32 bit depth with proper byte ordering
- Fix RGB565 little-endian format for HyperPixel 2.1 Round
- Auto-resize image to match actual framebuffer dimensions
- Add traceback logging for debugging framebuffer issues
Fixes double-image and color issues on HyperPixel display.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The HyperPixel 2.1 Round display uses RGB565 (16-bit) format, not
RGB888. Convert each pixel from RGB888 to RGB565 before writing
to /dev/fb0.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The dashboard was not displaying because _render_menu() was only
called on touch events or menu state changes. Added initial render
call after touch handler setup to display the menu on boot.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add remote.py with non-blocking SSH connection to Eye Remote
- Add /api/v1/remote/* endpoints for device control
- Add /dashboard with real-time metrics, services, and command execution
- Support both emulator and remote device modes
- Add service restart, log viewing, and device info endpoints
The gateway now serves as the primary testing interface for Eye Remote
without TTY blocking issues.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add test-menu-system job for pytest validation
- Update VERSION to 2.2.0
- Add create_release manual trigger option
- Update release notes with radial menu features
- Change tag pattern to eye-remote-v* for clarity
- Add PR trigger for CI on changes
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add python3-evdev package for touch gesture detection
- Install menu system icons to /usr/lib/secubox-eye/assets/icons/
- Add radial menu usage instructions to build output
- Bump version to 2.2.0
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Update test_complete_navigation_flow to accept either "Eye Remote" in
message or "SecuBox" in data.name, since ActionExecutor now delegates
to LocalAPI.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- ActionExecutor: Add local_api parameter to constructor
- ActionExecutor: Delegate local actions to LocalAPI when available
- radial_renderer: Move math import to module level
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add comprehensive integration tests for the complete menu navigation flow:
- TestFullMenuFlow test class with 7 integration test cases
- test_complete_navigation_flow: Navigate ROOT → LOCAL → ABOUT and execute action
- test_back_navigation: Test breadcrumb stack and back navigation
- test_action_executor_routing: Verify correct action handler routing
- test_menu_confirmation_flow: Test confirmation dialogs and cancellation
- test_menu_exit_to_dashboard: Test emergency exit via 3-finger tap
- test_menu_rotation: Test rotating selection through menu items
- test_full_session_simulation: Simulate complete user session flow
All 46 tests pass (39 existing + 7 new integration tests).
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add menu navigator, action executor, and render callback fields
- Implement _handle_menu_toggle() for long press center
- Implement _handle_slice_tap() for menu item selection
- Implement _handle_emergency_exit() for 3-finger exit
- Modify _execute_gesture() to route gestures based on menu mode
- In menu mode: TAP selects slice, SWIPE rotates selection
- Long press center toggles menu/dashboard mode
- 3-finger tap exits to dashboard from any state
- Fallback to device list if menu navigator not configured
Tests:
- test_long_press_center_enters_menu: toggles menu mode
- test_tap_slice_in_menu_mode: selects menu items via slice tap
- test_three_finger_exits_menu: emergency exit to dashboard
- All 39 tests pass (36 existing + 3 new)
Task 9 complete: menu integration in TouchHandler.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Create MenuState dataclass with MenuMode enum to track:
- Current display mode (DASHBOARD, MENU, CONFIRM, LOADING, RESULT)
- Active menu and selected radial slice index
- Navigation breadcrumb for back navigation
- Animation frame counter and pending action state
- Result message display with success flag
Add TestMenuState test suite (3 tests):
- test_initial_dashboard_mode: verify default state
- test_enter_menu_mode: mode switching
- test_breadcrumb_tracking: navigation history
All 10 tests pass (7 existing + 3 new).
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- MenuItem dataclass with label, icon, action, submenu, and confirm fields
- MenuID enum for all menu identifiers (ROOT, DEVICES, SECUBOX, etc)
- Minimal TDD implementation with passing tests
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
13-task TDD implementation plan covering:
- MenuItem and MenuState data models
- Static menu definitions for 6-slice radial menus
- MenuNavigator state machine
- Slice detection from touch coordinates
- RadialRenderer for framebuffer display
- ActionExecutor with LocalAPI integration
- TouchHandler menu mode integration
- Component wiring in main.py
- Menu icon generation
- Comprehensive test coverage
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Comprehensive design for radial menu touch interface:
- 6-slice pie navigation optimized for circular display
- Dual-scope control (local Pi Zero + remote SecuBox)
- Gesture-based interaction (tap, swipe, long press)
- Hierarchical menu structure with dynamic data loading
- Error handling and visual feedback patterns
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add load_module_icon() to load 48px PNG icons from assets
- Add get_critical_module() to determine most critical metric
- Display contextual icon in center based on highest metric value
- Show module name + value below icon (e.g., "AUTH 85%")
- Reorganize center layout: icon → mode → value → status → hostname
The center now shows the icon of the module with the most critical
metric, providing immediate visual feedback about system status.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- HISTORY.md: Document usb0→usb1 ECM fix for Linux hosts
- WIP.md: Mark USB OTG fix as completed v2.1.1
- TODO.md: Add P11-R17 checkbox for USB OTG fix
- Eye-Remote-Bootstrap.md: Update to v2.1.1 with fix note
The USB composite gadget creates usb0 (RNDIS) and usb1 (ECM).
Linux hosts use cdc_ether driver which maps to usb1.
Fixed by configuring only usb1 to avoid asymmetric routing.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Repositioned the 6 module pods to form a proper hexagonal ring pattern
around the center display at 60° intervals with radius ~150px.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The USB composite gadget creates two network interfaces:
- usb0: RNDIS function (for Windows hosts)
- usb1: ECM function (for Linux/Mac hosts via cdc_ether driver)
Previously, both interfaces were configured with the same IP (10.55.0.2/30),
causing asymmetric routing issues where packets received on usb1 could be
replied via usb0.
Fix: Configure only usb1 (ECM) since that's what Linux hosts use.
Falls back to usb0 if usb1 is not present (e.g., single-function gadget).
Changes:
- secubox-otg-gadget.sh: Wait for and configure usb1 instead of usb0
- gadget-setup.sh: Same fix for eye-remote variant
- agent/main.py: Update ensure_usb_network() to prefer usb1
- agent/network_debug.py: New debug script for USB network troubleshooting
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Pydantic v1.10.14 is the installed version which doesn't have model_dump()
- Changed device.model_dump(mode='json') to device.dict()
- All 36 tests now passing successfully
- Add "Bootstrap Role (v2.1.0)" section to Eye-Remote-Implementation.md with capabilities, use cases, architecture, configuration, workflow, and security considerations
- Update Table of Contents in Eye-Remote-Implementation.md to include bootstrap section
- Add bootstrap reference to Eye Remote section in Home.md
- Add bootstrap functionality note to Architecture-Boot.md with cross-reference to Eye-Remote-Bootstrap.md
This cross-references the new Eye-Remote-Bootstrap feature across related documentation pages.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive wiki documentation covering:
- System architecture with USB OTG gadget (ECM/ACM/mass storage)
- Double-buffer 4R boot media management
- Complete REST API specification with examples
- Boot workflow diagrams and state machine
- TFTP shadow channel for testing
- Image requirements and validation rules
- Troubleshooting guide for common issues
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Implements libcomposite configfs management for USB OTG gadget with:
- ECM (Ethernet Control Model) for network over USB
- ACM (Abstract Control Model) for serial console
- Mass Storage with LUN for boot media swapping
Subcommands:
up/start : Create gadget tree and bind UDC
down/stop : Unbind UDC and tear down cleanly
swap-lun : Force-eject and re-attach mass storage
status : Output JSON with UDC and function state
Key features:
- Idempotent operations (safe to call multiple times)
- Deterministic MAC generation from RPi serial
- Proper error handling with clear diagnostics
- Follows SecuBox bash conventions (set -euo pipefail)
Boot media directory: /var/lib/secubox/eye-remote/boot-media/
Active symlink: /var/lib/secubox/eye-remote/boot-media/active
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
SecuBox side (websocket.py):
- WebSocket endpoint /api/v1/eye-remote/ws/{device_id}
- Device authentication via token
- Command types: screenshot, reboot, config_update, lockdown, unlock, service_restart, ota_update
- Connection manager for device and WebUI client tracking
- REST convenience endpoints for sending commands
- Heartbeat/ping-pong support
Eye Remote side (command_handler.py):
- CommandHandler class for executing local commands
- Screenshot capture via framebuffer (/dev/fb0) with scrot fallback
- Service restart (whitelist-protected)
- System reboot via shutdown
- Config update with TOML merge
- OTA update trigger
- WebSocketClient for SecuBox connection
- Automatic reconnection on disconnect
- Metrics and status broadcasting
Integration:
- Updated api/main.py to include websocket router
- Updated agent/main.py to use WebSocketClient
- Added command_handler to agent __init__.py exports
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- index.html: Complete single-file dashboard with cyberpunk theme
- Device list with transport badges (OTG/WiFi/Offline)
- QR code pairing section with countdown timer
- Stats bar (Total/OTG/WiFi/Offline counts)
- Auto-refresh every 10s with visual indicator
- Toast notifications for user feedback
- Responsive design for mobile/desktop
- js/eye-remote.js: Vanilla JS API integration
- Health check, device list, unpair, QR generation
- qrcode.js CDN integration for QR display
- French timestamp formatting
- XSS-safe HTML escaping
Closes part of #31
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix CDC-ECM only mode (disable RNDIS for Linux compatibility)
- Add OTG detection based on usb0 interface state
- Add framebuffer format auto-detection (16/24/32bpp)
- Fix Python relative imports for agent scripts
- Add mock_secubox_api.py for testing without hardware
- Add configfs mount for USB gadget
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Pi Zero W (BCM2835) doesn't support KMS, so the hyperpixel2r overlay
alone doesn't configure DPI output. Explicit timing parameters are
required to create the framebuffer.
Added to config.txt:
- enable_dpi_lcd=1
- display_default_lcd=1
- dpi_group=2, dpi_mode=87
- dpi_output_format=0x7f216
- dpi_timings for 480x480 @ 60Hz
- framebuffer_width/height=480
Combined with previous fix (disable i2c_arm/spi), display now works.
Tested: Display confirmed working on Pi Zero W + HyperPixel 2.1 Round
Fixes#32
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use PACKAGES array dynamically instead of hardcoded package list
- Write package list to file for xargs in chroot
- Increase framebuffer mode expansion from 512MB to 768MB
- Make nginx configuration conditional (browser mode only)
- Properly apply --no-install-recommends to all packages
This fixes the "No space left on device" error when building
framebuffer mode images by avoiding X11/GTK dependencies.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update Home.md with full SecuBox system overview
- Add Architecture-Boot.md (5-layer boot chain, CSPN compliance)
- Add Design-System.md (6-module color system, typography)
- Add Developer-Guide.md (stack, conventions, patterns)
- Add Modules.md (all 125 modules with screenshots)
- Update _Sidebar.md with comprehensive navigation
- Fix fb_dashboard.py type hint for _read_from_socket
Wiki now covers: system overview, architecture, modules, security,
development guidelines, Eye Remote, and all hardware platforms.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Display OTG/WiFi/SIM mode prominently in center
- Remove clock and date from display
- Remove text labels from ring circles
- Minimal design: rings + mode + hostname + host
- Apply same design to both test and production dashboards
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Gateway emulator returns transport: "otg" field
- Test dashboard shows "● USB OTG" with neon green
- Shows "CONNECTED" status and host address
- Properly reads transport from API response
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create Home.md with links to Eye Remote pages
- Add _Sidebar.md for GitHub wiki navigation
- Quick start guide and build instructions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add hostname, uptime_seconds to metrics output
- Add field aliases: mem_percent, cpu_temp, load_avg_1, wifi_rssi
- Add test-dashboard-amd64.py for testing on x86_64 with pygame
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add --framebuffer / --browser build modes (framebuffer is default)
- Lightweight framebuffer mode skips Chromium (~200MB smaller)
- Add systemd services for eye-agent and fb-dashboard
- Update fb_dashboard.py:
- Display OTG status mode and connected device host
- Show SecuBox device name at top
- Neon fluorescent colors (arc-en-ciel phosphorescent)
- Return host and device_name from metrics sources
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Eye-Remote-Hardware.md: GPIO pinout, USB OTG, DPI timings, gadget modes
- Update CI workflow to v2.0.0
- Fix build script: add DNS for chroot network access
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- README.md: Quick start, architecture, configuration, troubleshooting
- Eye-Remote-Implementation.md: Full wiki with timeline, components,
build system, display config, API reference, lessons learned
Documents the complete Eye Remote v2.0.0 framework implementation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Pi Zero W does not support KMS properly. This commit adds the working
HyperPixel 2.1 Round configuration using legacy DPI mode:
- hyperpixel2r.dtbo: Legacy overlay (not KMS version)
- hyperpixel2r-init: ST7701S LCD init script using pigpio
- config.txt: DPI timings for 480x480 display
- LightDM autologin + openbox kiosk configuration
The build script now forces legacy DPI mode instead of preferring KMS.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Complete testing guide covering:
- Gateway emulator installation and usage
- Unit test execution (13 tests)
- Agent-gateway integration testing
- API module verification
- Troubleshooting section
Part of Eye Remote v2.0.0 implementation (Task 14).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add complete Debian packaging for the Eye Remote management module:
- debian/control: Package metadata and dependencies
- debian/rules: Build script for installing api/core/models/www
- debian/postinst: Service enablement and directory creation
- debian/prerm: Clean service shutdown
- debian/changelog: Initial v2.0.0 release
- debian/secubox-eye-remote.service: Systemd unit with uvicorn
- nginx/eye-remote.conf: Reverse proxy with WebSocket support
- menu.d/50-eye-remote.json: SecuBox dashboard menu entry
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- pairing.py: Remove unused 'secrets' import, use timedelta for safe arithmetic,
make port configurable via SECUBOX_EYE_REMOTE_PORT env var
- devices.py: Add UnpairResponse model for proper OpenAPI documentation
- build-eye-remote-image.sh: Fix glob quoting, add file validation, use symlink
pattern for service enablement, secure config permissions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add FastAPI routers for Eye Remote module:
- devices.py: CRUD operations for paired devices with JWT auth
- pairing.py: QR code generation, discovery, and device pairing
- metrics.py: System metrics endpoint with device token validation
Update main.py to include routers at /api/v1/eye-remote prefix.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add SecuBox Eye Gateway development tool for testing Eye Remote
without a physical SecuBox device. Features:
- Emulation profiles (idle, normal, busy, stressed) with realistic drift
- EmulatedMetrics dataclass with homeostatic drift behavior
- SecuBoxEmulator class for device simulation
- FastAPI server with CORS for development
- CLI with Click for easy configuration
- Endpoints: health, metrics, eye-remote metrics, discovery
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Eye Agent installation to the SD card image builder. The agent
provides a local API bridge for the framebuffer dashboard to fetch
SecuBox metrics over OTG or WiFi connections.
Changes:
- VERSION bumped from 1.11.0 to 2.0.0
- Install agent Python modules to /usr/lib/secubox-eye/agent/
- Copy config.toml.example to /etc/secubox-eye/config.toml
- Install and enable secubox-eye-agent.service
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements DeviceRegistry class for managing paired Eye Remote devices:
- CRUD operations (add, get, remove, list)
- Thread-safe access via Lock
- JSON file persistence at /var/lib/secubox/eye-remote/devices.json
- Token validation and last_seen timestamp updates
- Singleton pattern for global access
Includes test suite with 8 passing tests covering all operations.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add AgentMetricsSource class that connects to Eye Agent via Unix socket
at /run/secubox-eye/metrics.sock to fetch real metrics. Falls back to
SimulatedMetrics when agent is unavailable.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Generate secure device tokens using secrets.token_hex
- Hash tokens with SHA256 (never store plain tokens)
- Verify tokens with constant-time comparison
- Generate 6-char pairing codes
- Create QR code URLs for pairing
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Create the SecuBox-side secubox-eye-remote module structure:
- api/main.py: FastAPI application with health check
- models/device.py: Pydantic models for device management
- Directory structure for routers, core, tests, debian, nginx, www
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- EyeAgent class coordinates DeviceManager and MetricsBridge
- Async polling loop with configurable interval from SecuBox config
- Signal handlers (SIGTERM, SIGINT) for graceful shutdown
- PID file management in /run/secubox-eye/
- Executable wrapper script for convenience
- systemd service unit with auto-restart and RuntimeDirectory
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements DeviceManager class that:
- Connects to the active SecuBox using SecuBoxClient
- Supports switching between multiple configured SecuBoxes
- Polls metrics from active SecuBox
- Notifies listeners on metric updates
- Lists all configured SecuBoxes with active status
Task 4 of Eye Remote v2.0.0 implementation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements SecuBoxClient for fetching metrics from SecuBox API:
- Async HTTP client using aiohttp
- Bearer token authentication
- Primary/fallback host for network resilience
- Health checking endpoint
- Transport type detection (OTG vs WiFi)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements MetricsBridge class that provides a Unix socket server
for sharing metrics with the dashboard. The dashboard connects,
reads the current state as JSON, and disconnects (stateless).
Features:
- Serves metrics, SecuBox info, and alerts over Unix socket
- Handles multiple concurrent clients
- Socket at /run/secubox-eye/metrics.sock by default
- World-readable permissions for dashboard access
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements the foundation config module for Eye Remote v2.0.0 agent:
- DeviceConfig, SecuBoxConfig, and Config dataclasses
- load_config() to parse TOML configuration files
- get_active_secubox() and set_active_secubox() for multi-SecuBox support
- Example config file with OTG and WiFi connection templates
- Comprehensive test suite (7 tests) following TDD
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Pi Zero W (ARMv6) cannot run Chromium (requires NEON SIMD).
Added Python framebuffer dashboard that renders directly to /dev/fb0.
New files:
- fb_dashboard.py: PIL-based dashboard renderer
- Circular rings for AUTH/WALL/BOOT/MIND/ROOT/MESH modules
- Real-time clock, hostname, uptime display
- Simulated metrics (API integration ready)
- OTG/WiFi/SIM mode indicator
- secubox-fb-dashboard.service: systemd service
Build script updated to install framebuffer dashboard
instead of Chromium kiosk.
Tested on hardware - display shows animated dashboard with
6 module rings and live metrics.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Complete rewrite of build-eye-remote-image.sh for pure offline boot:
- Use QEMU ARM chroot to pre-install all packages at build time
- Expand image by 1GB for pre-installed packages (~500MB)
- Pre-installed: chromium, nginx, lightdm, openbox, python3-pil
- Configure lightdm autologin, openbox autostart, nginx in chroot
- Create secubox user with all groups during build
- No rc.local/firstrun needed - boots directly into kiosk
Build requirements: qemu-user-static, binfmt-support
Boot time comparison:
- v1.8.x: ~10 min (package download required)
- v1.9.0: ~60 sec (ready immediately, no internet)
Closes#30
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Detect vc4-kms-dpi-hyperpixel2r.dtbo in base image (no init needed)
- Fall back to legacy hyperpixel2r.dtbo with init script if KMS missing
- Use variable expansion for overlay name in config.txt
This ensures clean boot on modern Raspberry Pi OS Lite images while
maintaining backwards compatibility with older images.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Copy hyperpixel2r.dtbo to boot overlays (no network required)
- Remove incorrect dwc2,dr_mode=host from base image
- Use dtoverlay=hyperpixel2r (local) instead of vc4-kms-dpi-hyperpixel2r
- Fixes boot hang when no WiFi configured
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Downloads RPi OS Lite automatically
- Builds complete Eye Remote SD card image
- Compresses with xz and generates checksums
- Uploads to releases on version tags
- Supports manual trigger with WiFi/hostname options
- Part of Eye Remote v1.8.0
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Creates ready-to-flash SD image for RPi Zero W + HyperPixel 2.1 Round
- Supports WiFi pre-configuration and SSH key injection
- Installs HyperPixel + USB OTG drivers and SecuBox gadget scripts
- Includes dashboard and all Eye Remote systemd services
- Part of Eye Remote v1.8.0
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add 5 USB gadget modes: Normal, Flash, Debug, TTY, Auth
- Add HID keyboard emulation for U-Boot automation
- Add FIDO2/U2F security key mode (Eye Remote)
- Add x64/amd64 live boot support
- Update README.md with Eye Remote documentation
- Update WIKI.md with mode mockups and technical details
- Add INFOGRAPHIC-PROMPT.md for Claude.ai image generation
- Bump version from 1.7.0 to 1.8.0
New files:
- secubox-hid-keyboard.sh: Virtual HID keyboard driver
- INFOGRAPHIC-PROMPT.md: 7 prompts for publicity infographics
Eye Remote transforms the Round UI from a status display
into a full remote control device with debugging, flashing,
and authentication capabilities.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add LogsDirectory=secubox to systemd services for proper logging
- Fix systemd service security sandboxing (remove PrivateTmp issues)
- Replace text icons with emojis in menu.d JSON files
- Fixes navbar display issues (overlapping text from icon names)
Services updated:
- secubox-system, secubox-hub, secubox-portal, secubox-watchdog
- ~70 other services with LogsDirectory directive
Menu icons fixed:
- ipblock, interceptor, cookies, dns-provider, homeassistant, etc.
- Changed from text strings to emojis for proper sidebar display
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Module discovery: Use systemctl list-units instead of list-unit-files
to show only active/loaded modules, not all installed
- Auth router: Remove duplicate /auth prefix (secubox_core.auth already has it)
- Package versions: Cache batch queries to avoid blocking on slow ARM devices
- API paths (api.js): Fix frontend paths to match FastAPI routes
- getStatus -> status
- getModules -> modules
- get_dashboard_data -> dashboard
- etc.
Deployed and verified on EspressoBin V7.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Complete Remote UI implementation for SecuBox status display:
- Python/PIL dashboard with direct framebuffer rendering (no Chromium)
- KMS overlay support (vc4-kms-dpi-hyperpixel2r) - tested working
- USB OTG composite gadget (CDC-ECM + CDC-ACM) for host connection
- 6 concentric rings showing CPU, MEM, DISK, LOAD, TEMP, WiFi metrics
- Auto-start systemd service (secubox-dashboard.service)
- install_zerow.sh for SD card preparation with all fixes
Key fixes discovered during debugging:
- Use KMS overlay, not non-KMS (GPIO conflicts on Bookworm)
- Framebuffer is RGB565 (16-bit), not BGRA
- RPi OS Bookworm requires userconf file for SSH credentials
- NetworkManager ignores ifupdown; use direct IP config
Files:
- secubox_dashboard.py: PIL-based live metrics dashboard
- install_zerow.sh: SD card flasher with KMS overlay
- secubox-dashboard.service: Auto-start systemd unit
- 24 module icons (AUTH/WALL/BOOT/MIND/ROOT/MESH)
Tested on: RPi Zero W + HyperPixel 2.1 Round 480x480
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Dark theme with cyan/teal country highlighting by threat density
- Clickable countries with sidebar showing threat details
- Stats bar: total threats, countries, regions, critical
- Color legend: 1-3, 4-9, 10-19, 20+ threats
- Zoom controls (+/-)
- Continent/country filtering via dropdowns and URL params
- Country flags emoji in sidebar
- Enhanced /map/threats API with filtering support
- SVG map with 30+ countries across 6 continents
Inspired by privacynex.org/map interactive style.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Same fix as build-live-usb.sh X11 setup - the kiosk launcher was also
creating X11 config files that corrupted on bare metal.
- Skip config creation entirely for bare metal (vm_type=none)
- Intel/AMD/NVIDIA auto-detection works perfectly without configs
- Sanitize gpu_info for VMs (remove special chars)
- Only create explicit driver configs for VMs that need them
Fixes: "M2G_" parse error in /etc/X11/xorg.conf.d/10-kiosk.conf
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The fallback script was pinging 192.168.255.1 (dummy0 interface) and
thinking it found a gateway, then assigning 192.168.255.250 to the
ethernet interface - which doesn't provide internet connectivity.
- Add check to skip gateway IPs that are already assigned locally
- Verify ARP discovery results aren't local IPs
- Prevents self-discovery of dummy0 (192.168.255.1)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add iputils-arping for ARP-based gateway discovery
- Add arp_discover() function to scan for responding devices
- Expand gateway probe list: .254 variants, 10.x, 172.16.x subnets
- Try ARP discovery before slower ping-based gateway probing
- More reliable network auto-configuration on diverse networks
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- X11 setup now exits early for bare metal (VM_TYPE=none) without
creating config files - Intel/AMD/NVIDIA auto-detect perfectly
- Remove static fallback 10-modesetting.conf that caused conflicts
- Sanitize GPU_INFO in config comments to remove special chars
- Disable PrivateTmp and ProtectSystem for haproxy, metrics, threats
services - causes Python symlink namespace errors on some kernels
- Add fix-namespace-errors.sh script for quick fixes on running systems
Fixes: X11 "no screens found" on Intel HD Graphics 630
Fixes: "Failed to set up mount namespacing" for Python services
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Lead with value proposition and features
- Simple quick start for VirtualBox, USB, and dedicated hardware
- Default credentials prominently displayed
- Support links section
- Technical reference moved to collapsible <details> section
- Reduced from 368 to 150 lines visible by default
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add UI Design Guidelines section with cyberpunk/hermetic palette
- Document CSS variables for colors, typography
- Add design principles for dark-first interfaces
- Update version references to v1.7.0
- Update package count to 126 modules
- Add CI badges
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- build-all-live-usb.yml: Check for .img.gz first since build-image.sh
already compresses and removes the .img file
- build-rpi-usb.sh: Handle multiple kernel/initrd files by selecting
the latest version instead of globbing which breaks cp
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create secubox-x11-setup.service for boot-time VM/driver detection
- VirtualBox VMSVGA controller requires vmware X11 driver (not modesetting)
- Add driver selection: VBox+VMSVGA→vmware, VBox+VBoxVGA→modesetting
- Update secubox-kiosk.service to depend on x11-setup service
- Update secubox-kiosk-launcher v3.3 to defer to setup service
- Change SLIPSTREAM_DEBS default to 1 (126 packages by default)
- Fix EspressoBin live USB boot partition sizing for embedded images
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use find instead of glob to locate DTB directory reliably
- Copy only EspressoBin DTBs (armada-3720-espressobin*.dtb)
- Add logging for DTB count and warning if missing
- Fixes boot failure due to missing device tree files
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix $HOME issue when running with sudo by using SUDO_USER to get
original user's home directory for cache lookup
- Change ls to find to avoid set -e failures when no files match
- Add error handling for dpkg installation step
- Fix grep in package count verification to prevent pipefail
Both AMD64 (8GB) and EspressoBin V7 (2GB) live USB images now build
successfully with all 126 SecuBox packages slipstreamed.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add IP address discovery to network_summary API endpoint
- Add _get_package_version() helper for fetching installed versions
- Update _svc() to include package versions in status data
- Fix loadNetwork() to use API data instead of hardcoded IPs
- Add loadMemory() and loadDisk() functions for actual used/total values
- Update modules table to display real versions from dpkg
- Make EspressoBin build consistent with AMD64 slipstream (check cache too)
Fixes dashboard showing placeholder values (Memory: -/-, Storage: -/-, etc.)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fixed bug where discover_lan() function existed but was never called
- Now probes common gateways (192.168.1.1, 192.168.0.1, etc.) before link-local
- Only falls back to link-local (169.254.1.1) if gateway discovery also fails
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add ARP-based IP collision detection for multi-device environments
- MAC-based pseudo-random IP offset to spread devices across range
- Gratuitous ARP announcement to prevent IP conflicts
- Fix EspressoBin DSA network: target wan interface, not eth0 CPU port
- Static IP fallback 192.168.255.250 when DHCP unavailable
- Sync all build scripts to version 1.7.0
- Add screenshot script with 90+ module URLs
- Add mock HTML screenshots for documentation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Noto Color Emoji font-family to all icon elements
- Separate category icon into .cat-icon element with emoji font
- Put 'Noto Color Emoji' first in font stack (installed on live USB)
- Add explicit emoji font installation in build script
- Update both light and dark sidebar themes
Fixes emoji/icon boxes showing as empty squares on real hardware.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Dashboard footer: version, boot mode, auth mode, uptime
- Login page: auth mode badge + version display
- Plymouth splash: version v1.7.0 + boot mode indicator
- GRUB menu: descriptive echo messages for each boot option
- New API endpoints: /boot_mode, /auth_mode, /public/info
- Version bump to 1.7.0 across all components
Phase 11 tasks completed: P11-01 through P11-04, P11-07 through P11-09
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Problem: VirtualBox with VMSVGA shows as "VMware SVGA" in lspci,
causing wrong driver selection and X11 failure.
Fix: Use systemd-detect-virt as primary VM detection:
- "oracle" → VirtualBox → vboxvideo driver
- "vmware" → VMware → vmware driver
- "kvm"/"qemu" → KVM/QEMU → modesetting driver
- Fall back to lspci for bare metal
Also loads vboxsf module for shared folders support.
Addresses #27
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes:
- Add fallback EFI bootloader at /EFI/BOOT/BOOTX64.EFI for Lenovo/HP/Dell
- Add --slipstream flag to build-live-usb.sh (CI fix)
- Fix banner alignment in secubox-flash-disk
- Update kiosk launcher to v1.6.7.12
Wiki:
- Use generic /releases/latest/download/ URLs (no more hardcoded versions)
- Fix script paths (scripts/ → image/)
- Update all languages (EN, FR, DE, ZH)
Tested: Lenovo hardware install - PASSED
Closes#26
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
GitHub Actions doesn't allow matrix.* in job-level 'if' conditions.
Moved platform filtering to step-level with skip output variable.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Root cause: GRUB Kiosk entry used systemd.unit=graphical.target
but no display manager was installed. systemd waited forever
for graphical.target → getty never started → no keyboard input.
Fixes:
- Remove systemd.unit=graphical.target from Kiosk GRUB entry
- Revert getty Type=idle to simple service (v1.6.7.3)
- Enable backup TTYs (tty2-6) for emergency access
Closes#24
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add generate_debug_report() to secubox-kiosk-launcher
- Capture system info, virtualization, graphics hardware
- Log DRM/KMS devices, kernel modules, Xorg status
- Enhanced error reporting with dmesg and VT status
- Debug reports saved to /tmp/kiosk-debug-*.log
- Add v1.6.7.2 overlay installer scripts
- Add emoji font fixes for navbar icons
- Add screenshots for v1.6.7.1
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove prefix="/auth" from secubox_core/auth.py router definition
- Add prefix="/auth" when including auth_router in hub main.py
- Fixes login endpoint from /auth/auth/login to /auth/login
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-12 21:09:21 +02:00
669 changed files with 121293 additions and 1115 deletions
-`.claude/plans/eye-remote-otg-features.md` — 5 features roadmap:
1. Real Metrics Display (implemented)
2. OTG Tools Dashboard
3. Gadget Parameters Control
4. Storage Sync for Configs
5. Self-Setup Portal
---
### Session 71 — Eye Remote Display System v2.3.0
**Feature:** Complete display state machine with fallback, splash, and radar modes
**Description:**
Implemented full Eye Remote display system with multiple visualization modes for Pi Zero W HyperPixel 2.1 Round (480x480). Includes connection state detection, animated splash screens, and local metrics radar visualization.
**Components Created:**
1.**Splash Screen System** (`display/splash.py`)
- Animated phoenix logo for boot/halt/start/reboot states
### Session 70 — Live Boot Complete Setup (v2.2.4-live)
**Feature:** Full live-boot implementation with squashfs and RAM boot
**Description:**
Completed full live-boot setup for Pi Zero Eye Remote storage.img. Installed live-boot package, rebuilt initramfs with live-boot scripts, created squashfs filesystem, and updated boot.scr with proper live boot parameters.
**Changes Made:**
1. Installed `live-boot` and `busybox` packages on ARM64 rootfs
2. Rebuilt initramfs with live-boot scripts included
3. Created `/live/filesystem.squashfs` (878MB) on data partition (sda4)
**Wiki Fix:** Fixed sidebar link syntax from `[[Page|Display]]` to `[Display](Page)`
**Version:** v2.2.4-live
---
### Session 69 — Live RAM Boot Cmdline Fix (v2.2.4-pre2)
**Fix:** Added missing `boot=live live-media-path=/live` parameters to bootargs
**Description:**
Fixed critical issue where multiboot image was not configured for live RAM boot. The kernel command line was missing the required `boot=live` and `live-media-path=/live` parameters that the live-boot initramfs needs to work properly.
**Files Modified:**
-`image/multiboot/build-multiboot.sh` — Added live boot parameters to setenv bootargs
**Feature:** Fixed ARM64 kernel installation and added interactive boot menu
**Description:**
Fixed critical bug where ARM64 kernel, initrd, and DTB files were not being copied to the EFI partition. Added interactive dual boot menu with 5-second timeout, offering Live RAM Boot (default) or Flash to eMMC option.
**Files Modified:**
-`image/multiboot/build-multiboot.sh` — Major fixes:
- Fixed loop device release bug in `install_arm64_rootfs()` (was releasing before copying kernel)
- Added `build_arm64_rootfs_debootstrap()` function with kernel installation
- Added `copy_arm64_kernel_to_efi()` function to properly copy Image, initrd, DTBs
- Updated boot.scr with interactive dual boot menu (5s timeout)
- Added qemu-debootstrap and other optional dependency warnings
-`.github/workflows/build-multiboot.yml` — Added prerelease support, bumped version
-`wiki/_Sidebar.md` — Bumped version to v2.2.4-pre1
**Feature:** Wiki documentation for multiboot live OS and Eye Remote integration
**Description:**
Added comprehensive wiki documentation for the multi-architecture boot system, including the new Multiboot wiki page, home page announcement banner, and sidebar navigation updates.
**Files Created:**
-`wiki/Multiboot.md` — Full documentation for multiboot live OS
**Files Modified:**
-`wiki/Home.md` — Added announcement banner for v2.2.3 multiboot
-`wiki/_Sidebar.md` — Added Multiboot and Eye Remote links, bumped version
- Eye Remote Pi Zero architecture documented with ASCII diagrams
- Partition layout and boot flow explained
- Build instructions and GitHub Actions CI docs
- Troubleshooting section for common boot issues
---
### Session 66 — Multiboot GitHub Action (v2.2.3)
**Feature:** GitHub Actions workflow for automated multiboot image builds
**Description:**
Created automated CI/CD pipeline for building the multiboot live OS image with all SecuBox packages slipstreamed. Workflow builds .deb packages first, then creates the 16GB multiboot image with ARM64 and AMD64 rootfs partitions.
**Files Created:**
-`.github/workflows/build-multiboot.yml` — CI workflow for multiboot image
**Workflow Features:**
- Manual dispatch with configurable image size (8/16/32GB)
- Optional desktop environment inclusion
- Automatic .deb package builds from packages/
- Debootstrap-based ARM64 and AMD64 rootfs creation
- QEMU user-mode emulation for cross-arch chroot
- XZ compression for releases
- GitHub Release integration
**Version:** v2.2.3
---
### Session 65 — Multi-Boot Storage System (v2.2.2)
**Feature:** Multi-architecture boot system for Pi Zero Eye Remote storage
**Description:**
Created a multi-boot storage system that supports ARM64 (ESPRESSObin/MOCHAbin via U-Boot) and AMD64 (UEFI systems via GRUB) from a single USB storage device, with shared application data across both architectures.
**Partition Layout (16GB+):**
- P1: EFI/FAT32 (512MB) — Boot files for both architectures
- P2: ext4 (3GB) — ARM64 SecuBox rootfs
- P3: ext4 (3GB) — AMD64 SecuBox rootfs
- P4: ext4 (remaining) — Shared data partition
**Features:**
- U-Boot boot.scr with USB/MMC auto-detection for ARM64
- GRUB BOOTX64.EFI for AMD64 UEFI boot
- Shared data partition with bind mounts for /etc/secubox, /var/lib/secubox, /srv/secubox
- eMMC flasher image included for ARM64 installation
- Debootstrap-based AMD64 rootfs builder with SecuBox packages
**Files Created:**
-`image/multiboot/README.md` — Documentation
-`image/multiboot/build-multiboot.sh` — Main build script
-`5cf69c0` — feat(multiboot): Add multi-architecture boot system with shared data
**Version:** v2.2.2
---
### Session 65 — Eye Remote USB Boot Fix (v2.2.1)
**Issue:** ESPRESSObin would not boot from Eye Remote USB mass storage. mv88e6xxx driver in infinite detection loop.
**Root Cause:** Live USB kernel had mv88e6xxx built-in (not a module), making `modprobe.blacklist` ineffective. The eMMC kernel has mv88e6xxx as a loadable module where blacklist works.
**Fix:**
- Replaced storage.img boot partition with eMMC kernel/initrd/DTB
- Replaced storage.img rootfs with working eMMC rootfs
- Updated boot scripts with extended blacklist for future builds
**Files Modified:**
-`board/espressobin-v7/boot-live-usb.cmd`
-`board/espressobin-v7/boot-usb.cmd`
-`board/espressobin-v7/boot.cmd`
**Commits:**
-`942196b` — fix(boot): Add mv88e6085 and initcall_blacklist to boot scripts
**Version:** v2.2.1
### Session 65 — HAProxy Service Restart Loop Fix
**Issue:**`secubox-haproxy.service` in restart loop with NAMESPACE error.
**Root Cause:**`RuntimeDirectory=haproxy` triggers systemd namespace setup which expects `/etc/haproxy` to exist. HAProxy is `Recommends:` not `Depends:`.
**Fix:**
- postinst creates `/etc/haproxy` if not present
- Removed `RuntimeDirectory=haproxy` from service
- Moved directory creation from import-time to startup event
- Increased RestartSec 5→30s
**Commits:**
-`4321a7c` — fix(haproxy): Prevent service restart loop
-`9f47e54` — fix(haproxy): Create /etc/haproxy and remove RuntimeDirectory=haproxy
**Issue:** USB OTG network connection showed NO-CARRIER on Linux hosts despite Pi Zero interface being UP.
**Root Cause Analysis:**
The USB composite gadget creates two network interfaces on the Pi Zero:
-`usb0` → RNDIS function (Windows compatible)
-`usb1` → ECM function (Linux/Mac via cdc_ether driver)
Linux hosts use the ECM driver which maps to `usb1`. The old scripts configured `usb0` only, or both interfaces with the same IP (10.55.0.2/30), causing asymmetric routing where packets received on `usb1` could be replied via `usb0`.
**Fix Applied:**
- Configure only `usb1` (ECM) for Linux host compatibility
- Fallback to `usb0` only if `usb1` doesn't exist
**Files Modified:**
-`remote-ui/round/secubox-otg-gadget.sh` — Wait for and configure usb1
-`remote-ui/round/files/etc/secubox/eye-remote/gadget-setup.sh` — Same fix
**Goal:** Extend Eye Remote Pi Zero W to provide full Marvell board recovery capabilities via USB serial emulation, including kwboot, U-Boot flashing, and automated recovery workflows.
<pclass="subtitle">How should the Eye Remote switch between different operating modes?</p>
<divclass="section">
<p>You mentioned several modes: <strong>metrics display</strong> (when SecuBox API available), <strong>icons mode</strong> (RPi Zero standalone), <strong>storage-only</strong> vs <strong>multi-gadget</strong>. Let's clarify the primary operating modes.</p>
<li><strong>eye-web</strong> — Web Remote + System controls (optional)</li>
<li>Communication via shared JSON file + signals</li>
</ul>
<divclass="pros-cons">
<divclass="pros"><h4>Pros</h4><ul><li>Display works even if web crashes</li><li>Web can be disabled to save resources</li><li>Simple IPC (file + SIGHUP)</li></ul></div>
<divclass="cons"><h4>Cons</h4><ul><li>State sync complexity</li><li>Two processes to manage</li></ul></div>
</div>
</div>
</div>
</div>
<pclass="subtitle"style="margin-top: 1.5rem;">I recommend <strong>A (Unified Python Agent)</strong> for Pi Zero's limited resources. Which approach?</p>
<h2>Eye Remote Swiss Army Dashboard — Design Overview</h2>
<pclass="subtitle">Complete design summary for approval</p>
<divclass="section">
<h3>🎯 Core Concept</h3>
<p>Transform Eye Remote from a simple metrics display into a <strong>Swiss Army multi-tool</strong> with 4 operating modes, touchless web-based control, and intelligent failover — all running on Pi Zero W with HyperPixel 2.1 Round (480x480).</p>
<li><strong>API Loss:</strong> Stale data + "OFFLINE" badge → 15s gray fade → 60s Local mode</li>
<li><strong>USB Replug:</strong> "Connecting..." spinner → green flash on success</li>
<li><strong>Auto-reconnect:</strong> Background probe every 10s, silent recovery</li>
</ul>
</div>
<divclass="section">
<h3>🏗️ Architecture</h3>
<p><strong>Unified Python Agent</strong> — Single process extending existing code:</p>
<ulstyle="font-size: 13px; color: #ccc;">
<li><code>fb_dashboard.py</code> → Extended with mode state machine</li>
<li>Embedded FastAPI server for Web Remote (:8080)</li>
<li>Async event loop handles display + web + SecuBox comms</li>
<li>System controls via subprocess (nmcli, bluetoothctl, etc.)</li>
</ul>
</div>
<pclass="subtitle"style="margin-top: 2rem; color: #0f0;">Does this overview look correct? Type "ok" to continue to detailed sections, or raise concerns.</p>
**Your Network Security Appliance — Plug, Protect, Peace of Mind**
Port complet de [SecuBox OpenWrt](https://github.com/gkerma/secubox-openwrt) vers **Debian bookworm arm64/amd64** pour les boards **MOCHAbin** (Armada 7040), **ESPRESSObin** (Armada 3720), et **VMs x86_64**.
SecuBox transforms any compatible device into a complete network security appliance with VPN, firewall, intrusion detection, and web dashboard — all preconfigured and ready to use.
---
## Architecture
## What You Get
- **VPN Server** — WireGuard with QR codes for mobile devices
- **Intrusion Detection** — CrowdSec IDS/IPS with automatic threat blocking
- **Network Monitoring** — Real-time traffic analysis and bandwidth control
- **Web Dashboard** — Modern dark-themed interface accessible from any browser