Adds the missing /usr/share/secubox/plugins/catalog/ directory that is
documented but was not created by the package installer.
Changes:
- Create plugins/catalog directory structure
- Update Makefile to install catalog directory
- Add README explaining module catalog format
- Add example module catalog JSON file as reference
Directory structure:
- /usr/share/secubox/modules/ - Runtime module metadata (empty by design)
- /usr/share/secubox/plugins/catalog/ - Module catalog manifests
- /usr/share/secubox/scripts/ - Shared helper scripts
This completes the directory structure documented in the README.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Resolves package conflict where both luci-app-secubox and secubox-core
were providing /usr/libexec/rpcd/luci.secubox.
Changes:
- Remove RPCD backend (luci.secubox) from luci-app-secubox
- Add secubox-core as a dependency
- Update Makefile to reflect new architecture
- Remove RPCD file references from helper scripts
- Update documentation
Architecture:
- secubox-core (v0.8.0): Provides framework + RPCD backend
- luci-app-secubox (v0.7.0): Provides LuCI web UI only
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The luci.magicmirror RPCD backend script needs executable permissions to function properly as an RPCD handler.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixed JavaScript syntax error caused by unescaped apostrophes in French text:
- "Détection d'intrusions" → "Détection d\'intrusions"
- "contrôle d'accès" → "contrôle d\'accès"
Fixes: SyntaxError: missing } after property list at line 90
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Replace manual CP commands with
- This ensures proper integration with luci.mk build system
- Fixes appstore files not being included in built packages
- Bump version to 0.7.0-6
The issue was that manually copying htdocs and root bypassed luci.mk's
install logic. Now we call the parent installer first, then add our
custom /usr/share/secubox directories.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The root cause of empty appstore was that Package/luci/install macro
was not installing files from usr/share/secubox/* directories.
Changes:
- Removed $(call Package/luci/install,$(1)) macro
- Manually implemented all install steps explicitly:
- Copy htdocs to /www
- Copy root/* to package root
- Explicitly create /usr/share/secubox directories
- Explicitly install appstore/apps.json
- Explicitly install profiles/*.json
This ensures data files are packaged correctly in the IPK.
Version: 0.7.0-5
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added debugging output to understand why appstore catalog isn't being
included in package builds. The install section now:
- Checks if source file exists before attempting install
- Shows full paths being used
- Displays directory contents if file is missing
- Exits with error if file not found (fail-fast)
This will help diagnose whether the issue is:
- Wrong CURDIR path during build
- Files not present in build directory
- Permissions issue preventing access
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The postinst script was failing installation (exit 1) when the appstore
catalog wasn't found, which prevented package upgrades from completing.
Changes:
1. Removed exit 1 - installation now continues even if file is missing
2. Added auto-recovery: tries to restore from /rom overlay if available
3. Provides clear status feedback (✓ or ✗) for appstore catalog
4. Gives helpful error message with recovery instructions
5. Always exits with 0 to allow installation to complete
This fixes upgrades from 0.7.0-r2 to 0.7.0-r4 where the directory
structure changed from .appstore to appstore.
Version: 0.7.0-4
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The build was failing with:
chown: cannot access '/usr/share/secubox': No such file or directory
This happened because PKG_FILE_MODES was trying to set permissions on
directories that don't exist at the time file modes are applied during
package creation.
Solution:
- Removed all directory entries from PKG_FILE_MODES
- Removed apps.json file entry (INSTALL_DATA sets 644 automatically)
- Kept only executable files that need explicit 755 permissions
How it works now:
- $(INSTALL_DIR) automatically creates directories with 755 permissions
- $(INSTALL_DATA) automatically installs files with 644 permissions
- PKG_FILE_MODES only specifies exceptions (executable scripts = 755)
- postinst script sets permissions again as safety measure
This follows OpenWrt package best practices where PKG_FILE_MODES
should only specify permissions that differ from the defaults set
by the installation macros.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Cleanup after renaming .appstore/ to appstore/ directory.
These files are now tracked in their new location.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Enhanced package installation to ensure appstore files are properly
installed with correct permissions during both fresh installs and upgrades.
Changes to Makefile:
1. Added explicit PKG_FILE_MODES for all data directories and files:
- /usr/share/secubox: 755
- /usr/share/secubox/appstore: 755
- /usr/share/secubox/appstore/apps.json: 644
- /usr/share/secubox/profiles: 755
2. Improved install section:
- Added file existence check before installing profiles
- Added install verification message for appstore catalog
- Better comments for clarity
3. Added postinst script:
- Verifies appstore catalog exists after installation
- Sets proper permissions on all data directories/files
- Reloads RPCD service to pick up new methods
- Provides installation feedback to user
- Fails with warning if appstore catalog missing
This ensures the appstore will be populated on fresh firmware installs
and properly updated during package upgrades.
Version: 0.7.0-3
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Renamed .appstore directory to appstore (without dot prefix) to ensure
proper inclusion in OpenWrt package builds. Hidden directories (starting
with .) can be problematic during tarball creation and package installation.
Changes:
- Renamed .appstore/ to appstore/
- Updated Makefile install path references
- Updated RPCD script APPSTORE_JSON path
- Fixed file permissions to 644 for apps.json
This fixes the issue where appstore appears empty on fresh firmware
installations.
New path: /usr/share/secubox/appstore/apps.json
Old path: /usr/share/secubox/.appstore/apps.json
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added debugMode flag that checks URL hash or localStorage setting.
Debug logging only outputs when enabled via:
- URL: /#/admin/secubox/apps#debug
- Console: localStorage.setItem('secubox_debug', 'true')
All debug logs prefixed with [AppStore] or [Modules] for clarity.
Warnings and errors remain in production for critical issues.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added a modal footer with a Close button in the app details view.
The footer includes:
- Styled separator line with border-top
- Right-aligned Close button
- Calls ui.hideModal() on click
This provides a clear way to dismiss the modal without needing to
click outside or use the escape key.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Updated package version from 0.6.1-0 to 0.7.0-1 to reflect:
- Fixed appstore race condition causing empty initial load
- Fixed RPC expect parameter for getAppstoreApps
- Improved error handling in apps and modules views
- Added debug logging for troubleshooting
- Fixed modules render data flow
Updated API version from 0.3.1 to 0.7.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixed appstore showing "No applications match the selected filter" by correcting
the RPC declaration expect parameter.
Issue: The RPC declaration had:
expect: { apps: [], categories: {} }
This caused the RPC framework to return only the apps array instead of the full
response object, resulting in:
- data = Array(5) instead of { apps: [...], categories: {...} }
- data.apps = undefined
- data.categories = undefined
Fix: Changed to:
expect: { }
This returns the full response object as-is from the backend, allowing proper
access to both data.apps and data.categories properties.
Also added extensive debug logging to troubleshoot the data flow.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixed issue where first page load would show empty apps/modules list, requiring
a refresh to display data.
Changes:
- Added error handling in refreshData() for both apps.js and modules.js
- Added null/empty data checks before storing results
- Fixed render() to use data parameter first, then fallback to cached instance data
- Added console logging for debugging empty responses
- Added user-friendly error notifications when API calls fail
The render function now properly uses:
var apps = (data && data.apps) || this.appsData || [];
var modules = (data && data.modules) || this.modulesData || [];
This ensures the data passed from load() is used on first render, preventing
the empty state on initial page load.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Updated package version from 0.4.1-3 to 0.5.0-1
Updated API version from 0.2.2 to 0.5.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Updated package version from 0.4.0-1 to 0.5.0-1 to reflect:
- Fixed ACL permissions (seccubox_logs, collect_debug)
- Fixed API module imports in all views
- Added missing API methods (getAllData, getCpu alias)
- Added utility functions (formatKB, getStatusClass, getTempClass)
- Resolved multiple "function not defined" errors
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added utility functions that views depend on:
- formatKB() - Format kilobytes with automatic unit conversion (KB/MB/GB/TB)
- getStatusClass() - Return CSS class based on percentage thresholds
(good: <50%, info: 50-74%, warning: 75-89%, critical: >=90%)
- getTempClass() - Return CSS class based on temperature in Celsius
(good: <60°C, info: 60-69°C, warning: 70-79°C, critical: >=80°C)
Resolves "API.formatKB is not a function", "API.getStatusClass is not a function",
and "API.getTempClass is not a function" errors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Added getAllData() method to fetch all system stats in one call
- Added getCpu() alias for getCPU() for consistency with view expectations
- getAllData() returns a combined object with stats, cpu, memory, disk, network, processes, and system data
This resolves "API.getAllData is not a function" and "API.getCpu is not a function" errors
by ensuring the API exports match what the views are calling.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Changed from 'require netdata-dashboard.api as api' to 'require netdata-dashboard/api as API'
- Updated all api. references to API. in realtime.js, system.js, network.js, and processes.js
- Resolves "api.getAllData is not a function" and "api.getCpu is not a function" errors
The dot notation (netdata-dashboard.api) doesn't work with LuCI's module loader.
The correct syntax uses slash (netdata-dashboard/api) and follows the convention
of uppercase API for consistency with other modules.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Added seccubox_logs to read permissions
- Added collect_debug to read permissions
- Resolves "Access denied" error for seccubox_logs endpoint
Note: The method name has a typo (seccubox instead of secubox) but
keeping it for consistency with the existing RPC handler implementation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Changed from L.require('client-guardian.api') to 'require client-guardian/api as API'
- Updated all api. references to API. in both files
- Resolves "api.getLogs is not a function" and "api.getAlerts is not a function" errors
The L.require() pattern doesn't work properly with async module loading in LuCI.
Using the proper 'require' directive ensures the module is loaded correctly.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Added 'require uci' to fix "uci is not defined" error
- Ensures UCI configuration can be loaded properly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The previous config used commented-out format which didn't actually
disable the packages, causing them to be built and fail.
Changes:
- Changed from: echo "# CONFIG_PACKAGE_lucihttp is not set"
- Changed to: echo "CONFIG_PACKAGE_lucihttp=n"
- Same for cgi-io
- Added CONFIG_BROKEN=y to allow missing dependencies
This matches the local-build.sh approach and prevents SDK from trying
to compile these problematic packages that our scripts don't need.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changed default OpenWrt version from 25.12.0-rc1 to 24.10.5 to match
local-build.sh configuration and ensure stable builds by default.
Changes in both workflows:
- build-openwrt-packages.yml: default and env fallback
- build-secubox-images.yml: default and env fallback
- Reordered options to show 24.10.5 first
Users can still manually select other versions when triggering workflows.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The packages were being copied to the SDK but not enabled in .config,
causing no artifacts to be generated for these packages.
Changes:
- Add CONFIG_PACKAGE_secubox-app=m to SDK .config
- Add CONFIG_PACKAGE_luci-theme-secubox=m to SDK .config
This ensures both packages are built when running the package build workflow.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>