Major feature release implementing comprehensive state management, component registry, and admin control center with full UI integration. ## Backend Features (secubox-core v0.9.0-1) State Management System: - ✅ State database (state-db.json) with 15 states across 4 categories - ✅ State machine with transition matrix validation - ✅ secubox-state CLI (8 commands: get, set, history, list, validate, sync, freeze, clear-error) - ✅ state-machine.sh with atomic transitions using flock - ✅ State history tracking with timestamps and reasons - ✅ Error state handling with detailed error info - ✅ Frozen state support for system-critical components Component Registry System: - ✅ Component registry database (component-registry.json) - ✅ secubox-component CLI (7 commands: list, get, register, unregister, tree, affected, set-setting) - ✅ Component types: app, module, widget, service, composite - ✅ Dependency tracking (required/optional) - ✅ Recursive dependency tree resolution - ✅ Reverse dependency tracking - ✅ Component settings management - ✅ Profile tagging and filtering Auto-Sync System: - ✅ secubox-sync-registry CLI for catalog synchronization - ✅ Auto-populate from catalog.json - ✅ Plugin catalog directory scanning - ✅ Installed package detection - ✅ Automatic state initialization RPC Backend (luci.secubox): - ✅ 6 state management RPC methods - ✅ 5 component registry RPC methods - ✅ Bulk operations support - ✅ State validation endpoints ## Frontend Features (luci-app-secubox-admin v1.0.0-16) UI Components: - ✅ state-utils.js: 20+ utility functions, state config, transition validation - ✅ StateIndicator.js: 5 rendering modes (badge, compact, pill, dot, statistics) - ✅ StateTimeline.js: 4 visualization modes (vertical, horizontal, compact, transition diagram) - ✅ state-management.css: 600+ lines with animations, responsive design, accessibility Admin Control Center Dashboard: - ✅ System overview panel with health metrics - ✅ Component state summary with statistics - ✅ Recent state transitions timeline - ✅ Alerts panel for warnings and errors - ✅ Quick actions panel - ✅ Real-time updates (5-second polling) - ✅ Metric cards with hover effects - ✅ State distribution by category API Integration (api.js): - ✅ 11 RPC method declarations - ✅ Enhanced methods: getComponentWithState(), getAllComponentsWithStates() - ✅ Bulk operations: bulkSetComponentState() - ✅ State statistics: getStateStatistics() - ✅ Retry logic with exponential backoff - ✅ Promise-based async operations ## Documentation Comprehensive Documentation: - ✅ API-REFERENCE.md (1,200+ lines): Complete API docs for RPC, CLI, JS - ✅ EXAMPLES.md (800+ lines): 30+ usage examples, shell scripts, integration patterns - ✅ State definitions table (15 states) - ✅ State transition matrix - ✅ Component metadata schemas - ✅ Error codes reference - ✅ Testing examples ## State Definitions 15 States Across 4 Categories: - Persistent: available, installed, active, disabled, frozen - Transient: installing, configuring, activating, starting, stopping, uninstalling - Runtime: running, stopped - Error: error (with subtypes) State Transition Flow: available → installing → installed → configuring → configured → activating → active → starting → running → stopping → stopped ## Technical Details Files Created (10 backend + 8 frontend): Backend: - /usr/sbin/secubox-state (12KB, 8 commands) - /usr/sbin/secubox-component (12KB, 7 commands) - /usr/sbin/secubox-sync-registry (8.4KB) - /usr/share/secubox/state-machine.sh (5.2KB) - /var/lib/secubox/state-db.json (schema) - /var/lib/secubox/component-registry.json (schema) Frontend: - resources/secubox-admin/state-utils.js (~400 lines) - resources/secubox-admin/components/StateIndicator.js (~350 lines) - resources/secubox-admin/components/StateTimeline.js (~450 lines) - resources/secubox-admin/state-management.css (~600 lines) - resources/view/secubox-admin/control-center.js (~550 lines) - resources/secubox-admin/api.js (+145 lines) Documentation: - docs/admin-control-center/API-REFERENCE.md (1,200+ lines) - docs/admin-control-center/EXAMPLES.md (800+ lines) Files Modified (3): - package/secubox/secubox-core/Makefile (v0.8.0 → v0.9.0-1) - package/secubox/luci-app-secubox-admin/Makefile (release 15 → 16) - package/secubox/secubox-core/root/usr/libexec/rpcd/luci.secubox (+157 lines) ## Installation & Migration Makefile Updates: - Added 3 new CLI tools to install section - Added state-machine.sh to scripts - Updated package description - Enhanced postinst to initialize databases - Auto-sync registry on first install Postinst Features: - Automatic state-db.json initialization - Automatic component-registry.json initialization - Catalog sync on install - Version announcement with new features ## Performance & Security Performance: - File locking (flock) for atomic state transitions - State history limited to 100 entries per component - RPC retry logic with exponential backoff - Bulk operations use Promise.all for parallel execution - Component list caching (30 seconds) Security: - Frozen state prevents unauthorized modifications - All state changes logged with timestamp and reason - System-critical components have additional safeguards - Proper authentication required for state transitions ## Testing & Validation Features: - State transition validation - Component dependency resolution - Circular dependency detection - State consistency checker - Integration test scripts included in docs ## Breaking Changes None - Backward Compatible: - Existing RPC methods remain functional - State-aware methods are additive - Components without state default to 'available' - Migration is automatic on install ## Statistics Total Implementation: - Lines of Code: ~4,000 - Backend: ~1,800 (Bash + JSON) - Frontend: ~2,200 (JavaScript + CSS) - Documentation: ~2,000 (Markdown) - Functions/Commands: 40+ - RPC Methods: 11 - CLI Commands: 22 - UI Components: 5 - Documentation Pages: 2 ## Next Phase Remaining from Plan: - Phase 4: System Hub integration - Phase 5: Migration script (secubox-migrate-state) - Phase 6: Additional documentation (ARCHITECTURE.md, STATE-MANAGEMENT.md, etc.) - Phase 7: Additional UI views (components.js, state-manager.js, debug-panel.js) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
20 KiB
SecuBox Admin Control Center - API Reference
Complete API reference for state management, component registry, and control center features.
Table of Contents
RPC Backend API
All RPC methods are exposed through the luci.secubox object.
State Management Methods
get_component_state
Get the current state and metadata for a component.
Parameters:
component_id(string): Unique component identifier
Returns:
{
"component_id": "luci-app-auth-guardian",
"current_state": "running",
"previous_state": "starting",
"state_changed_at": "2026-01-05T10:30:00Z",
"error_details": {
"type": "runtime_error",
"message": "Service failed to start",
"code": "E_SERVICE_START"
},
"history": [
{
"state": "starting",
"timestamp": "2026-01-05T10:29:45Z",
"reason": "user_action"
}
],
"metadata": {
"installed_version": "1.0.0",
"catalog_version": "1.0.1"
}
}
Example:
L.resolveDefault(callGetComponentState('luci-app-auth-guardian'))
.then(function(state) {
console.log('Current state:', state.current_state);
});
set_component_state
Set a new state for a component with atomic transition validation.
Parameters:
component_id(string): Unique component identifiernew_state(string): Target state (see State Definitions)reason(string): Reason for state change
Returns:
{
"success": true,
"message": "State transition successful",
"previous_state": "stopped",
"new_state": "starting"
}
Errors:
- Invalid transition (returns
success: false) - Component not found
- State locked
Example:
L.resolveDefault(callSetComponentState('luci-app-auth-guardian', 'starting', 'user_request'))
.then(function(result) {
if (result.success) {
console.log('State changed successfully');
}
});
get_state_history
Get state transition history for a component.
Parameters:
component_id(string): Unique component identifierlimit(number, optional): Maximum number of history entries (default: 50)
Returns:
{
"history": [
{
"state": "running",
"timestamp": "2026-01-05T10:30:00Z",
"reason": "start_success",
"metadata": {}
},
{
"state": "starting",
"timestamp": "2026-01-05T10:29:45Z",
"reason": "user_action"
}
]
}
Example:
L.resolveDefault(callGetStateHistory('luci-app-auth-guardian', 10))
.then(function(result) {
result.history.forEach(function(entry) {
console.log(entry.state, entry.timestamp);
});
});
list_components
List all components with optional filters.
Parameters:
state_filter(string, optional): Filter by state (e.g., "running", "error")type_filter(string, optional): Filter by type (e.g., "app", "module")
Returns:
{
"components": [
{
"id": "luci-app-auth-guardian",
"type": "app",
"name": "Auth Guardian",
"current_state": "running",
"state_changed_at": "2026-01-05T10:30:00Z"
}
]
}
Example:
// Get all running apps
L.resolveDefault(callListComponents('running', 'app'))
.then(function(result) {
console.log('Running apps:', result.components.length);
});
freeze_component
Mark a component as frozen (locked state, no transitions allowed).
Parameters:
component_id(string): Unique component identifierreason(string): Reason for freezing
Returns:
{
"success": true,
"message": "Component frozen successfully"
}
Example:
L.resolveDefault(callFreezeComponent('luci-app-firewall', 'system_critical'))
.then(function(result) {
console.log('Component frozen');
});
clear_error_state
Clear error state and reset component to last known good state.
Parameters:
component_id(string): Unique component identifier
Returns:
{
"success": true,
"message": "Error state cleared",
"new_state": "stopped"
}
Example:
L.resolveDefault(callClearErrorState('luci-app-vpn-client'))
.then(function(result) {
console.log('Error cleared, new state:', result.new_state);
});
Component Registry Methods
get_component
Get full component metadata from registry.
Parameters:
component_id(string): Unique component identifier
Returns:
{
"id": "luci-app-auth-guardian",
"type": "app",
"name": "Auth Guardian",
"packages": ["luci-app-auth-guardian", "nodogsplash"],
"capabilities": ["authentication", "captive-portal"],
"dependencies": {
"required": ["luci-base"],
"optional": ["uhttpd-mod-lua"]
},
"settings": {
"enabled": true,
"auto_start": true
},
"profiles": ["home-security", "enterprise"],
"managed_services": ["nodogsplash"],
"state_ref": "luci-app-auth-guardian"
}
get_component_tree
Get component dependency tree (recursive).
Parameters:
component_id(string): Unique component identifier
Returns:
{
"component": {
"id": "luci-app-auth-guardian",
"name": "Auth Guardian",
"type": "app"
},
"dependencies": {
"required": [
{
"id": "luci-base",
"name": "LuCI Base",
"type": "module",
"dependencies": {...}
}
],
"optional": []
},
"reverse_dependencies": [
{
"id": "profile-home-security",
"type": "composite"
}
]
}
update_component_settings
Update component settings.
Parameters:
component_id(string): Unique component identifiersettings(object): Settings key-value pairs
Returns:
{
"success": true,
"updated_settings": {
"enabled": true,
"auto_start": false
}
}
validate_component_state
Validate component state consistency with system.
Parameters:
component_id(string): Unique component identifier
Returns:
{
"valid": true,
"inconsistencies": [],
"recommendations": []
}
CLI Tools
secubox-state
State management command-line interface.
Commands
get <component-id>
Get current state with metadata.
secubox-state get luci-app-auth-guardian
Output:
{
"component_id": "luci-app-auth-guardian",
"current_state": "running",
"previous_state": "starting",
"state_changed_at": "2026-01-05T10:30:00Z"
}
set <component-id> <state> [reason]
Set new state with atomic transition.
secubox-state set luci-app-auth-guardian starting user_request
Output:
Success: State transition: stopped -> starting
history <component-id> [limit]
View state history.
secubox-state history luci-app-auth-guardian 10
list [--state=STATE] [--type=TYPE]
List components by state/type.
secubox-state list --state=running --type=app
validate <component-id>
Validate state consistency.
secubox-state validate luci-app-auth-guardian
sync
Sync state DB with actual system state.
secubox-state sync
freeze <component-id> <reason>
Freeze component (lock state).
secubox-state freeze luci-app-firewall system_critical
clear-error <component-id>
Clear error state.
secubox-state clear-error luci-app-vpn-client
secubox-component
Component registry management CLI.
Commands
list [--type=TYPE] [--state=STATE] [--profile=PROFILE]
List components with filters.
secubox-component list --type=app --state=running
get <component-id>
Get component details.
secubox-component get luci-app-auth-guardian
register <component-id> <type> [metadata-json]
Register new component.
secubox-component register my-app app '{"name":"My App","packages":["my-app"]}'
Component Types:
app- LuCI applicationmodule- opkg packagewidget- Dashboard widgetservice- System servicecomposite- Group of components
unregister <component-id>
Remove component from registry.
secubox-component unregister my-app
tree <component-id>
Show dependency tree.
secubox-component tree luci-app-auth-guardian
affected <component-id>
Show reverse dependencies.
secubox-component affected luci-base
set-setting <component-id> <key> <value>
Update component setting.
secubox-component set-setting my-app enabled true
secubox-sync-registry
Auto-populate component registry from catalog.
Commands
sync
Full registry synchronization (default).
secubox-sync-registry sync
apps
Sync only apps from catalog.
secubox-sync-registry apps
plugins
Sync only plugins from catalog directory.
secubox-sync-registry plugins
packages
Sync only installed packages.
secubox-sync-registry packages
JavaScript Frontend API
State Management
api.getComponentState(component_id)
Get component state.
api.getComponentState('luci-app-auth-guardian')
.then(function(state) {
console.log('Current state:', state.current_state);
});
api.setComponentState(component_id, new_state, reason)
Set component state.
api.setComponentState('luci-app-auth-guardian', 'starting', 'user_action')
.then(function(result) {
if (result.success) {
console.log('State changed');
}
});
api.getStateHistory(component_id, limit)
Get state history.
api.getStateHistory('luci-app-auth-guardian', 10)
.then(function(history) {
history.forEach(function(entry) {
console.log(entry.state, entry.timestamp);
});
});
api.listComponents(state_filter, type_filter)
List components.
api.listComponents('running', 'app')
.then(function(components) {
console.log('Running apps:', components);
});
api.freezeComponent(component_id, reason)
Freeze component.
api.freezeComponent('luci-app-firewall', 'system_critical')
.then(function(result) {
console.log('Component frozen');
});
api.clearErrorState(component_id)
Clear error state.
api.clearErrorState('luci-app-vpn-client')
.then(function(result) {
console.log('Error cleared');
});
Component Management
api.getComponent(component_id)
Get component metadata.
api.getComponent('luci-app-auth-guardian')
.then(function(component) {
console.log('Component:', component.name);
});
api.getComponentTree(component_id)
Get dependency tree.
api.getComponentTree('luci-app-auth-guardian')
.then(function(tree) {
console.log('Dependencies:', tree.dependencies);
});
api.updateComponentSettings(component_id, settings)
Update settings.
api.updateComponentSettings('luci-app-auth-guardian', {
enabled: true,
auto_start: false
}).then(function(result) {
console.log('Settings updated');
});
Enhanced Methods
api.getComponentWithState(component_id)
Get component with state in single call.
api.getComponentWithState('luci-app-auth-guardian')
.then(function(component) {
console.log('Component:', component.name);
console.log('State:', component.state_info.current_state);
});
api.getAllComponentsWithStates(filters)
Get all components with states.
api.getAllComponentsWithStates({ state: 'running', type: 'app' })
.then(function(components) {
components.forEach(function(comp) {
console.log(comp.name, comp.state_info.current_state);
});
});
api.bulkSetComponentState(component_ids, new_state, reason)
Bulk state change.
api.bulkSetComponentState(
['app1', 'app2', 'app3'],
'stopped',
'bulk_shutdown'
).then(function(results) {
console.log('Bulk operation results:', results);
});
api.getStateStatistics()
Get state distribution statistics.
api.getStateStatistics()
.then(function(stats) {
console.log('Total components:', stats.total);
console.log('By state:', stats.by_state);
console.log('By type:', stats.by_type);
});
State Utilities
JavaScript utilities in state-utils.js.
Methods
getStateConfig(state)
Get full state configuration.
var config = stateUtils.getStateConfig('running');
// Returns: { color: '#10b981', icon: '▶', label: 'Running', category: 'runtime', description: '...' }
getStateColor(state)
Get CSS color for state.
var color = stateUtils.getStateColor('error');
// Returns: '#ef4444'
canTransition(fromState, toState)
Validate state transition.
var valid = stateUtils.canTransition('stopped', 'starting');
// Returns: true
getNextStates(currentState)
Get allowed next states.
var nextStates = stateUtils.getNextStates('stopped');
// Returns: ['starting', 'disabled', 'uninstalling']
formatHistoryEntry(historyEntry)
Format history for display.
var formatted = stateUtils.formatHistoryEntry({
state: 'running',
timestamp: '2026-01-05T10:30:00Z',
reason: 'user_action'
});
// Returns: "2026-01-05 10:30:00 - Running (User Action)"
getTimeAgo(timestamp)
Get relative time string.
var timeAgo = stateUtils.getTimeAgo('2026-01-05T10:30:00Z');
// Returns: "5 minutes ago"
getStateStatistics(components)
Calculate state distribution.
var stats = stateUtils.getStateStatistics(components);
// Returns: { total: 25, by_state: {...}, by_category: {...} }
UI Components
StateIndicator
Render state badges and indicators.
render(state, options)
Standard state badge.
var badge = StateIndicator.render('running', {
showIcon: true,
showLabel: true,
showTooltip: true
});
renderCompact(state, options)
Compact indicator (icon only).
var indicator = StateIndicator.renderCompact('error', {
customTooltip: 'Critical error occurred'
});
renderPill(state, metadata, options)
Full details pill.
var pill = StateIndicator.renderPill('running', {
timestamp: '2026-01-05T10:30:00Z'
}, {
showDescription: true
});
renderDot(state, options)
Minimal dot indicator.
var dot = StateIndicator.renderDot('running', {
size: '0.75rem'
});
renderStatistics(statistics, options)
State distribution cards.
var stats = StateIndicator.renderStatistics({
by_state: { running: 10, stopped: 5, error: 2 }
});
StateTimeline
Visualize state history.
render(history, options)
Vertical timeline.
var timeline = StateTimeline.render(historyEntries, {
limit: 20,
showRelativeTime: true,
showCategory: true
});
renderCompact(history, options)
Inline compact timeline.
var compact = StateTimeline.renderCompact(historyEntries, {
limit: 5
});
renderHorizontal(history, options)
Horizontal timeline.
var horizontal = StateTimeline.renderHorizontal(historyEntries, {
limit: 10
});
renderTransitionDiagram(currentState, options)
Interactive transition diagram.
var diagram = StateTimeline.renderTransitionDiagram('stopped', {
onTransitionClick: function(from, to) {
console.log('Transition:', from, '->', to);
}
});
Data Structures
State Definitions
| State | Category | Description | Color |
|---|---|---|---|
| available | persistent | Available for installation | #6b7280 |
| installing | transient | Installation in progress | #3b82f6 |
| installed | persistent | Installed but not active | #8b5cf6 |
| configuring | transient | Configuration in progress | #3b82f6 |
| configured | transient | Configuration completed | #8b5cf6 |
| activating | transient | Activation in progress | #3b82f6 |
| active | persistent | Active but not running | #06b6d4 |
| starting | transient | Service is starting | #3b82f6 |
| running | runtime | Service is running | #10b981 |
| stopping | transient | Service is stopping | #f59e0b |
| stopped | runtime | Service is stopped | #6b7280 |
| error | error | Component encountered an error | #ef4444 |
| frozen | persistent | Component is frozen (locked) | #06b6d4 |
| disabled | persistent | Component is disabled | #9ca3af |
| uninstalling | transient | Uninstallation in progress | #f59e0b |
State Transition Matrix
available → [installing]
installing → [installed, error]
installed → [configuring, uninstalling]
configuring → [configured, error]
configured → [activating, disabled]
activating → [active, error]
active → [starting, disabled, frozen]
starting → [running, error]
running → [stopping, error, frozen]
stopping → [stopped, error]
stopped → [starting, disabled, uninstalling]
error → [available, installed, stopped]
frozen → [active]
disabled → [active, uninstalling]
uninstalling → [available, error]
Component Metadata Structure
{
"id": "string",
"type": "app|module|widget|service|composite",
"name": "string",
"packages": ["string"],
"capabilities": ["string"],
"dependencies": {
"required": ["string"],
"optional": ["string"]
},
"settings": {
"key": "value"
},
"profiles": ["string"],
"managed_services": ["string"],
"state_ref": "string",
"metadata": {
"installed_version": "string",
"catalog_version": "string",
"auto_detected": boolean
}
}
State Database Structure
{
"components": {
"component-id": {
"current_state": "string",
"previous_state": "string",
"state_changed_at": "ISO8601",
"error_details": {
"type": "string",
"message": "string",
"code": "string"
},
"history": [
{
"state": "string",
"timestamp": "ISO8601",
"reason": "string",
"metadata": {}
}
],
"metadata": {}
}
},
"version": "1.0",
"last_updated": "ISO8601"
}
Error Codes
State Management Errors
E_INVALID_TRANSITION- Invalid state transitionE_COMPONENT_NOT_FOUND- Component not foundE_STATE_LOCKED- Component state is lockedE_VALIDATION_FAILED- State validation failed
Component Registry Errors
E_COMPONENT_EXISTS- Component already registeredE_INVALID_TYPE- Invalid component typeE_DEPENDENCY_MISSING- Required dependency not foundE_CIRCULAR_DEPENDENCY- Circular dependency detected
Performance Considerations
- State transitions use file locking (
flock) for atomicity - RPC methods have retry logic with exponential backoff
- State history is limited to 100 entries per component (configurable)
- Component list queries are cached for 30 seconds
- Bulk operations use Promise.all for parallel execution
Security Considerations
- State transitions require proper authentication
- Frozen components cannot be modified without admin privileges
- System-critical components have additional safeguards
- All state changes are logged with reason and timestamp
Migration and Compatibility
- Existing RPC methods (
get_appstore_apps, etc.) remain functional - State-aware methods are additive, not breaking changes
- Components without state entries default to 'available'
- Migration script auto-initializes states for existing components
See Also
Version: 1.0 Last Updated: 2026-01-05 Maintainer: SecuBox Development Team