Changed default visibility from public to private for new Gitea
repositories created by metablogizerctl and streamlitctl.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
MetaBlogizer uses per-site uhttpd instances, not LXC containers.
The watchdog was incorrectly treating it as an LXC service and
constantly trying to restart a non-existent container.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add automatic Gitea push after upload_finalize in Streamlit RPCD
- Add automatic Gitea push after upload_finalize in MetaBlogizer RPCD
- Fix MetaBlogizer to use site name instead of UCI section ID for push
- Fix metablogizerctl to read Gitea config from dedicated gitea section
Uploaded files via LuCI are now automatically synced to Gitea repos.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Streamlit:
- App create/deploy now auto-pushes to Gitea when enabled
- Add 'gitea init-all' command to initialize repos for all existing apps
- Scans all app directories and creates Gitea repos
MetaBlogizer:
- Site create now auto-pushes to Gitea when token configured
- Add 'gitea init-all' command to initialize repos for all existing sites
- Iterates over UCI site configs and syncs to Gitea
Usage:
# Configure Gitea once
uci set streamlit.gitea.enabled=1
uci set streamlit.gitea.url='http://192.168.255.1:3000'
uci set streamlit.gitea.user='admin'
uci set streamlit.gitea.token='<token>'
uci commit streamlit
# Initialize all existing apps/sites
streamlitctl gitea init-all
metablogizerctl gitea init-all
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Streamlit/MetaBlogizer:
- Add 'gitea push <name>' command to both streamlitctl and metablogizerctl
- Auto-creates Gitea repo via API if it doesn't exist
- Initializes git, commits all files, and pushes to Gitea
- Stores repo reference in UCI for future syncs
Tor Shield:
- Add 'wan_input_allow' option for server preset
- Server mode now properly allows WAN inbound (ports 80, 443, 8443)
- Uses nftables rules to integrate with OpenWrt firewall4
- Outbound traffic still routed through Tor (kill_switch)
- Cleanup nftables rules on stop/disable
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace failing awk-based JSON parsing with jsonfilter per-alert extraction.
Alerts now correctly populate in CrowdSec dashboard.
Changes:
- Use jsonfilter to extract created_at, scenario, source_ip per alert
- Loop through up to 8 alerts with index-based access
- Remove Python dependency (not available on OpenWrt)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend uses timestamp/source_ip but JS was looking for time/ip.
Fixed field mappings:
- timestamp -> time display
- source_ip -> ip display
- request -> details fallback
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Alerts data was loaded but not displayed. Added new section showing:
- Time, IP, country, type, severity, details
- Limited to 25 most recent alerts
- Clear alerts button
- Proper severity colors and icons
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add HAProxy multi-domain SSL certificate matching issue
- Document crt-list solution for SNI issues
- Minor updates to settings and streamlit readme
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add TRUSTED_PATH_PREFIXES for LuCI, ubus, and CGI paths
- Fix moderate mode to always require threshold (3 attempts in 5 min)
instead of immediate ban on critical threats
- Add WireGuard endpoint whitelist support to prevent VPN peer bans
- New script: mitmproxy-sync-wg-endpoints extracts peer IPs from UCI
- Bump version to v2.4
Prevents accidental bans from legitimate external LuCI login attempts.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Shows all CrowdSec bans with:
- IP address, reason, source (WAF/CrowdSec), country, expiration
- Summary counts: total, WAF autobans, CrowdSec detections
- Unban button for each entry with confirmation dialog
- Empty state when no bans active
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New methods for threats monitor dashboard:
- bans: Get CrowdSec decisions with counts by source
Returns total, mitmproxy_autoban, crowdsec counts + full bans array
- unban: Remove ban by IP address
Updates ACL to include new methods for LuCI access.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New haproxyctl path commands:
- path list: Show all path ACLs with patterns and backends
- path sync <prefix> <host>: Auto-generate ACLs from all backends
Extracts short name from backend (metablog_X -> X, streamlit_Y -> Y)
Skips existing ACLs, only adds new ones
- path add: Manually add single path ACL
- path remove: Remove specific path ACL
- path clear: Remove all ACLs matching prefix
This enables dynamic route updates when backends change.
Example: haproxyctl path sync /gk2 secubox.in
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Path-based ACLs are now sorted by pattern length (longest first) before
being emitted to haproxy.cfg. This ensures specific paths like /gk2/evolution
match before general paths like /gk2.
Two-phase approach:
- _collect_path_acl() stores ACL data with pattern length prefix
- _emit_sorted_path_acls() sorts by length descending and emits rules
Enables apex domain path routing: secubox.in/gk2/** instead of *.gk2.secubox.in
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add _add_path_acl() function to process UCI 'acl' sections
- Support path_beg, path_end, path, path_reg, path_dir match types
- Path ACLs are processed before vhost ACLs (higher priority)
- Fix http_request list handling to avoid duplicate output
- Enables gk2.secubox.in/evolution routing to streamlit_evolution
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Support suffix matching for wildcard domains (*.domain.tld)
- Add match_type option: exact, suffix, regex
- Enable subdomain-to-path mapping for mesh publishing
- Prepare infrastructure for distributed Vortex DNS nodes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Display per-subdomain request/threat counts
- Show protocol distribution (HTTP/HTTPS)
- Show top URIs and countries per domain
- Sort by request count, limit to top 25
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Track requests, threats, protocols per subdomain
- Record HTTP methods, status codes, top URIs, countries
- New RPCD method: subdomain_metrics
- Metrics auto-saved to /tmp/secubox-subdomain-metrics.json
- Add wan_setup/wan_clear to ACL write permissions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add vhost for presse.cybermood.eu
- Add backend cybermood_presse on port 4001
- Add ACME certificate entry
- Add ACL routing rules
- Fix backends to use LAN IP (192.168.255.1) instead of localhost
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add vhost entries for cybermood.eu and www.cybermood.eu
- Add backend configuration (cybermood_web on port 4000)
- Add ACME certificate entries for SSL
- Add ACL routing rules in template
- Switch to crt-list for multi-certificate SNI support
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Changed fetch_file() TTL from 300s to 60s
- All tabs now refresh every minute like Devel tab
- Updated footer to reflect unified refresh interval
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- New "🚀 Devel" tab with live GitHub commit activity (1-min cache)
- Metrics: Commits Today, This Week, Contributors, Stars
- Commit type distribution (feat/fix/docs/refactor/chore)
- Recent commits list with hash, message, author, relative time
- Repository stats: forks, watchers, open issues
- Cyberpunk-themed commit cards with color-coding
- Pulsing live indicator animation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The HAProxy LXC container was missing lxc.mount.auto = proc:mixed sys:ro
which caused lxc-attach to fail with "mount -t proc proc /proc" error.
This prevented the LED watchdog from checking HAProxy status via
lxc-attach -n haproxy -- pgrep haproxy, triggering false SPUNK alerts.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add secubox-landing script to generate landing pages from HAProxy vhosts
- Integrate landing command into secubox CLI
- Add boot hook to regenerate landing pages on startup
- Fix HAProxy multi-cert SNI using crt-list instead of directory mode
- Fix backend IPs from 127.0.0.1 to 192.168.255.1 for LXC compatibility
- Auto-convert localhost IPs in RPCD handler and CLI tools
Landing page features:
- Groups all services by zone with stats header
- Shows SSL certificate status per domain
- Categorizes by type: Streamlit, Blog, Admin, Media, Dev, etc.
- Regenerates at boot (30s after startup)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
SecuBox Fabricator - Universal Constructor for SecuBox Components:
- Main dashboard with live stats from UCI and JSON cache
- Collectors page: manage stats scripts, view/run collectors, JSON cache
- Apps page: Streamlit instance management with test/restart/deploy
- Blogs page: MetaBlogizer site management from UCI config
- Services page: HAProxy vhosts/backends, Peek/Poke/Emancipate
- Widgets page: dashboard widget designer with live stats preview
All pages now use actual live data from UCI configs and /tmp/secubox/*.json
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add DNS resolution test to heartbeat status
- Include BIND, CrowdSec, HAProxy, mitmproxy service checks
- Add security metrics (crowdsec_bans, dns_response)
- Improve health score calculation with all services
Router changes (not in repo):
- Enabled BIND recursion with forwarders (9.9.9.9, 1.1.1.1)
- Added BIND query/security logging
- Added CrowdSec acquisition for BIND logs
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add extract_zip_flatten() to Streamlit RPCD for nested ZIP handling
- Add bot whitelist to mitmproxy WAF (Facebook, Google, Bing crawlers)
- Skip threat detection for whitelisted legitimate crawlers
- Track Fabricator app and stats evolution in HISTORY.md
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Creates double-buffered JSON caches with last N entries
- Caches: threats, kernel, syslog, crowdsec details
- Writes to /tmp/secubox and /www for LuCI access
- Cron runs every minute for real-time updates
- Usage: secubox-detail-collector [count] [type]
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
parseCountries() now correctly handles countries as array of objects
[{country: "US", count: 67}, ...] instead of only plain {US: 67} format.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create cyberpunk-style End of Internet page for unknown domains
- Add http-request UCI option support in haproxyctl generator
- Support path rewriting backends with http-request set-path
- Configure end_of_internet as default backend for both frontends
- Update docs with HAProxy enhancements (entry #59)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add validation in _add_vhost_acl() to detect when vhost backend
is set to IP:port format instead of a proper backend name.
This prevents haproxy config generation errors like:
[ALERT] unable to find required use_backend: '127.0.0.1:8081'
When detected, logs a warning and skips the vhost instead of
generating invalid config that crashes HAProxy.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Stats Collection:
- Add unified secubox-stats-collector for crowdsec/mitmproxy/firewall
- Add secubox-status-json and metablogizer-json for landing page
- JSON cache files in /tmp/secubox/ for double-buffer status
LED Pulse Daemon:
- Tri-color status sync matching control panel (Health/CPU/Memory)
- SPUNK ALERT mode for critical service failures (HAProxy/CrowdSec down)
- Integrated into secubox-core init.d for auto-start on boot
Landing Page:
- Add Blogaliser section with MetaBlogizer sites
- Add health indicators (green/yellow/red status dots)
- Add security stats (dropped, bans, connections)
Streamlit Enhancements:
- Add test_upload RPCD method for upload validation
- Add reupload button for replacing existing apps
- Add secubox_control.py reading from cache (LXC-compatible)
- Update ACL and API for new methods
HAProxy Fixes:
- Fix invalid use_backend entries (IP:port -> backend names)
- Add streamlit_hello backend
- Save routing to UCI config for persistence
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changed LED heartbeat tick interval from 0.15s to 0.33s for more
visible pulse pattern. Adjusted cycle pause from 8 to 6 ticks.
Triple-pulse cycle now spans ~4 seconds total:
- 3 beats + 2 gaps + 6 rest = 11 ticks × 0.33s = ~3.6s
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds full exposure workflow for Streamlit apps:
- DNS A record registration (Gandi/OVH via dnsctl)
- Vortex DNS mesh publication
- HAProxy vhost with SSL and backend creation
- ACME certificate request
- Zero-downtime HAProxy reload
Usage: streamlitctl emancipate <app> [domain]
Domain auto-generated from vortex wildcard if not specified.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Track avahi-publish PID in /tmp/secubox-avahi-mesh.pid and check if process
is still running before spawning a new one. Prevents process accumulation
when discover_peers() is called repeatedly.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change mount point from var/mail to home/vmail for proper Dovecot integration
- Update virtual_mailbox_base from /var/mail to /home/vmail
- Create Maildir/{cur,new,tmp} structure matching Dovecot's mail_location
- Fix vmailbox entries to include Maildir/ suffix
- Update vmail user home directory to /home/vmail
This resolves the issue where emails delivered by Postfix were not visible
in Roundcube because Dovecot was looking in ~/Maildir/ subdirectory.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
LED assignment for MochaBin:
- led1: Global health status (green/yellow/red with pulse variations)
- led2: Security threat meter (CrowdSec + mitmproxy activity)
- led3: Global capacity (CPU + Network combined, color gradient)
- mmc0: Classic heartbeat when stable, rapid blink on state changes
Features:
- Fast 1.5s heartbeat loop for reactive visual feedback
- Health score from services (HAProxy, CrowdSec) + memory/disk
- Threat level from CrowdSec alerts and mitmproxy stats
- Combined CPU load + network throughput capacity meter
- Event pulse system for config/task/alert notifications
- State change detection for mmc0 stability indicator
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Interactive Streamlit landing page showing project evolution:
- Real-time sync with GitHub master (HISTORY.md, WIP.md, TODO.md, README.md)
- Milestone tracking with dates and timeline view
- Full-text search across all project files
- Feature distribution charts
- Dark cyberpunk theme matching SecuBox design
Deployed on port 8510, added to GK2 landing page.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add LED heartbeat to secubox-core daemon using MochaBin's RGB LEDs (led1)
- Green flash: system healthy
- Double red flash: warning state
- Long red flash: error state
- Blue flash: boot/startup
- LED pulses once per watchdog cycle (default 60s)
- New UCI options: led_heartbeat (default 1), watchdog_interval (default 60)
- Add "Node Services" section to Vortex DNS LuCI dashboard showing published sites
- Bump secubox-core version to 0.10.0-r12
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add -z/--zone option to dnsctl for zone override
- Detect correct DNS zone from domain suffix (secubox.in, maegia.tv, cybermind.fr)
- Register on both published domain zone AND vortex node subdomain
- Fix hyphenated site names (e.g., bazi-weekly) in UCI lookups
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Emancipate button to dashboard sites table
- Implement async RPC with job polling to avoid XHR timeout
- Add emancipate + emancipate_status RPCD methods
- Add ACL permissions for new RPC methods
- Change HAProxy reload to restart for clean state
- Document RPCD ACL requirements in CLAUDE.md
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add `metablogizerctl emancipate <name>` command for one-command full
exposure workflow:
1. DNS A record via dnsctl (Gandi/OVH based on availability)
2. Vortex DNS mesh publication
3. HAProxy vhost with SSL/ACME enabled
4. SSL certificate request (webroot mode)
5. Zero-downtime HAProxy reload
Usage:
metablogizerctl create myblog blog.example.com
metablogizerctl emancipate myblog
Bump version to 1.1.0.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- user_passwd now updates /etc/dovecot/users inside container
- user_add also syncs new users to Dovecot
- Fixes password reset not working (was only updating host file)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Reset Password button to user table
- Add showResetPasswordModal with password confirmation
- Add callUserPasswd RPC declaration
- Fix RPCD handler to read JSON from stdin or $3
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace bash arrays with POSIX loops in scoring.sh
- Replace bc with shell arithmetic (bc not available on OpenWrt)
- Wrap RPCD handlers in functions for local keyword compatibility
- Fix process substitution < <() to use pipe instead
Tested on router: CLI and RPCD working, score calculation correct.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Network Anomaly Agent (secubox-network-anomaly):
- 5 detection modules: bandwidth, connection flood, port scan, DNS, protocol
- EMA-based baseline comparison
- LocalAI integration for threat assessment
- network-anomalyctl CLI
LocalRecall Memory System (secubox-localrecall):
- Persistent memory for AI agents
- Categories: threats, decisions, patterns, configs, conversations
- EMA-based importance scoring
- LocalAI integration for summarization
- localrecallctl CLI with 13 commands
AI Insights Dashboard (luci-app-ai-insights):
- Unified view across all AI agents
- Security posture scoring (0-100)
- Agent status grid with alert counts
- Aggregated alerts from all agents
- Run All Agents and AI Analysis actions
LuCI Dashboards:
- luci-app-network-anomaly with real-time stats
- luci-app-localrecall with memory management
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- LocalAI inference takes 30-60s on ARM64 hardware
- Changed RPCD chat handler to async pattern:
- Returns poll_id immediately
- Background process runs AI query (120s timeout)
- Saves result to /var/lib/threat-analyst/chat_*.json
- Client polls with poll_id to get result
- Updated api.js with chatAsync() that polls automatically
- Changed default LocalAI port from 8081 to 8091
- Frontend shows "Thinking..." message with spinner during inference
- Uses curl instead of wget (BusyBox wget doesn't support --post-data=-)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add init.d script for daemon mode with procd integration
- Update Makefile to install init script
- Add packages to bonus feed (secubox-vortex-dns, luci-app-vortex-dns)
- Update tracking files with completion status
Features:
- Master/slave hierarchical DNS delegation
- Wildcard domain management (*.domain)
- First Peek auto-registration of services
- Gossip-based exposure config sync via secubox-p2p
- Submastering for nested hierarchies
- LuCI dashboard with mode detection and action buttons
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New RPCD method: reset_password
- Resets Domoticz admin password via SQLite
- Accessible from LuCI dashboard
- MD5 hashes the password before storing
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
mydestination included $mydomain which caused "User unknown in local
recipient table" errors because Postfix treated the domain as local
instead of virtual.
Changes:
- Remove $mydomain from mydestination in setup.sh
- Update fix-postfix command to also fix this issue
- Ensure vdomains file is properly created
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Alpine Linux's Postfix is compiled with LMDB support, not BerkeleyDB
hash support. This caused "Temporary lookup failure" errors on send.
Changes:
- Changed virtual_alias_maps and virtual_mailbox_maps to lmdb: prefix
- Copy resolv.conf to Postfix chroot for DNS resolution
- Added `mailctl fix-postfix` command to repair existing installations
Root cause: virtual_alias_maps was configured as hash:/etc/postfix/virtual
but the hash map type is not supported on Alpine, only lmdb.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Port status now checks inside container (not localhost)
- Added report command: generate, send, enable, disable
- Daily report includes server status, mail queue, logs, storage
- Cron job setup for automated daily reports at 7 AM
- Report sent to admin_email configured in UCI
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
All-in-one LuCI interface for:
- Mail server status and control
- User/alias management with modals
- Port status monitoring
- DNS/SSL setup actions
- Webmail configuration
- Mesh backup integration
RPCD handler with 17 methods for full mail management.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New packages:
- secubox-app-backup: Unified backup for LXC containers, UCI config, services
- luci-app-backup: KISS dashboard with container list and backup history
- secubox-app-mailserver: Custom Postfix+Dovecot in LXC with mesh backup
Enhanced dnsctl with:
- generate: Auto-create subdomain A records
- suggest: Name suggestions by category
- mail-setup: MX, SPF, DMARC record creation
- dkim-add: DKIM TXT record management
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New packages:
- secubox-threat-analyst: AI-powered threat analysis with CrowdSec integration
- luci-app-threat-analyst: LuCI dashboard for threat intelligence
- secubox-dns-guard: DNS security monitoring and blocking
- secubox-mcp-server: Model Context Protocol server for AI assistant integration
Enhancements:
- dns-provider: Add DynDNS support (dyndns, get, update, domains commands)
- gandi.sh: Full DynDNS with WAN IP detection and record updates
- luci-app-dnsguard: Upgrade to v1.1.0 with improved dashboard
Infrastructure:
- BIND9 DNS setup for secubox.in with CAA records
- Wildcard SSL certificates via DNS-01 challenge
- HAProxy config fixes for secubox.in subdomains
- Mail server setup with Roundcube webmail
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Upgrade LocalAI from v2.25.0 to v3.9.0 with new features:
- **Agent Jobs Panel**: Schedule and manage background agentic tasks
- **Memory Reclaimer**: LRU eviction for loaded models, automatic VRAM cleanup
- **VibeVoice backend**: New voice synthesis support
Update README with:
- v3.9 feature highlights
- Complete CLI command reference
- Model presets table (tinyllama, phi2, mistral, gte-small)
- API endpoints documentation
- SecuBox Couche 2 integration notes
This is part of the v0.18 AI Gateway roadmap.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Build and add secubox-app-mac-guardian_0.5.0-r1_all.ipk
- Build and add luci-app-mac-guardian_0.5.0-r1_all.ipk
- Sync luci-app-mac-guardian to local-feed for SDK building
- Update apps-local.json catalog with proper metadata:
- Category: security, Icon: wifi
- Descriptions for frontend and backend packages
- Rebuild all bonus feed packages
Package features:
- WiFi MAC address spoofing detection
- OUI anomaly detection for device fingerprinting
- MAC flood protection via hotplug.d integration
- CrowdSec scenarios for automated threat response
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add 4-step modal wizard for first-time configuration
- Step 1: Welcome with Docker/container status checks
- Step 2: Add/remove media library paths with type presets
- Step 3: Network configuration (domain, HAProxy, ACME)
- Step 4: Complete with link to Jellyfin Web UI
- Add RPCD methods: get_wizard_status, set_wizard_complete,
add_media_path, remove_media_path, get_media_paths
- Auto-trigger wizard when installed but not configured
- Add wizard.css with step indicators and form styling
- Update Makefile to install CSS resources
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add emancipate/revoke/get_emancipated RPCD methods
- Add Mesh toggle column with blue theme styling
- Add Emancipate button in header with multi-channel modal
- Modal allows selecting Tor/DNS/Mesh channels
- Add mesh badge to header stats
- Update ACL and API wrapper for new methods
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add animated "Collecting data..." overlay with pulsing dots during
5-second chart warmup period
- Chart legend transitions from "Waiting" to "Live" when data arrives
- Add formatBits() helper for network rate display (Kbps/Mbps/Gbps)
- Network rates now use SI units (bits) instead of bytes
- Cyberpunk theme support for empty state styling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
SecuNav.renderTabs() now automatically initializes theme and loads CSS,
eliminating boilerplate from views. Added renderCompactTabs() for nested
modules and renderBreadcrumb() for back-navigation.
Updated module navs: cdn-cache, client-guardian, crowdsec-dashboard,
media-flow, mqtt-bridge, system-hub. Removed ~1000 lines of duplicate CSS.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Switch from Docker to LXC with Debian bookworm rootfs and native
Domoticz binary from GitHub releases (latest/download pattern)
- Fix LXC cgroup2 terminal allocation: add lxc.tty.max, lxc.pty.max,
cgroup2 device permissions for standard char devices, disable seccomp
- Fix PID 1 issue: run domoticz as child process with signal forwarding
- Use quoted heredoc with sed placeholders for start script generation
- Update LuCI view: Docker → LXC references, add memory usage display
- Remove Docker image UCI option, update catalog runtime to "lxc"
- Fix streamlit LXC config: same cgroup2/terminal/seccomp fixes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New luci-app-domoticz package with RPCD handler (12 methods), LuCI overview
(status, IoT integration, MQTT, HAProxy, mesh, logs), and full service lifecycle.
Enhanced domoticzctl with configure-mqtt (auto Mosquitto+Z2M bridge), configure-haproxy,
backup/restore, mesh-register, and uninstall commands. UCI extended with mqtt/network/mesh
sections. Catalog updated with LuCI package and IoT tags. MirrorNetworking strategic
document noted in planning files.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The z2m 2.x breaking changes required three fixes discovered during
live deployment testing on the router:
- Adapter renamed from `ezsp` to `ember` in zigbee-herdsman 4.0.0
- Config format needs `version: 4` and nested `homeassistant.enabled`
- Start script needs `ZIGBEE2MQTT_DATA` env var for correct config path
- Add `mosquitto-nossl` as package dependency (MQTT broker required)
- Direct `/dev/ttyUSB0` passthrough works; socat TCP bridge does not
Also updates project planning files (HISTORY.md, TODO.md, WIP.md,
CLAUDE.md) and rebuilds bonus feed with latest IPKs.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace Docker-based zigbee2mqtt with a KISS LXC approach using Alpine
Linux container with Node.js + zigbee2mqtt, matching the HAProxy LXC
pattern. Adds USB serial passthrough for Sonoff Dongle Lite MG21.
- zigbee2mqttctl: Full LXC lifecycle (install, update, check, shell)
- RPCD: LXC diagnostics (lxc, cp210x, serial, container, service)
- api.js: Fix callApply missing params (payload was silently dropped)
- overview.js: Match new LXC diagnostics, fix applyConfig call
- Makefiles: Replace +dockerd +docker +containerd with +lxc +kmod-usb-serial-cp210x
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Includes rebuilt packages with RPCD function wrapper fix, crowdsec
decisions fix, and new secubox-app-jellyfin package.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Services with HAProxy DNS domains are now displayed at the top of the
table sorted alphabetically by domain, followed by remaining services
sorted by port number.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Includes device-intel, dns-provider, crowdsec-dashboard, and jellyfin
packages plus updated Packages index.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The callDecisions RPC declaration used expect: { alerts: [] } but the
backend returns { decisions: [...] }, causing the unwrapped result to
always be empty. Also removed leftover console.log debug statements.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
BusyBox ash rejects `local` outside a function. Both RPCD handlers used
`local` directly in the case block, causing "not in a function" errors
and silent RPC failures (empty responses).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change menu action type from "firstchildview" to "firstchild" to fix runtime exception
- Remove null handleSaveApply/handleSave/handleReset so form.Map default save works
- Update Gandi API link from defunct account.gandi.net to admin.gandi.net PAT page
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace bash-only $((16#hex)) with printf "%d" 0x for ash
- Fix client-guardian collector to use actual UCI fields (name, zone,
status, first_seen, last_seen)
- Add ARP table collector for IP resolution and online detection
- Fix di_get_summary jsonfilter counting (use per-field extraction)
- Rename uci_get to di_ctl_get to avoid collision with OpenWrt's
/lib/functions.sh which overwrites it
- Replace rx_bytes/tx_bytes/risk_score with first_seen/last_seen
timeline in show command
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>