feat(catalog): Add Streamlit Forge and RezApp Forge to KISS Apps
- luci-app-streamlit-forge: Streamlit app publishing platform - Category: productivity, runtime: lxc - Templates, SSL exposure, mesh publishing - luci-app-rezapp: Docker to LXC app converter - Category: system, runtime: native - Catalog browsing, package generation - Updated new_releases section - Total plugins: 37 → 39 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
31ca0d7618
commit
66b58c74d6
@ -1,6 +1,6 @@
|
||||
# SecuBox UI & Theme History
|
||||
|
||||
_Last updated: 2026-03-09 (HAProxy Routes Health Check, WAF Routing)_
|
||||
_Last updated: 2026-03-11 (RezApp Forge, Streamlit Forge)_
|
||||
|
||||
1. **Unified Dashboard Refresh (2025-12-20)**
|
||||
- Dashboard received the "sh-page-header" layout, hero stats, and SecuNav top tabs.
|
||||
@ -4531,3 +4531,78 @@ git checkout HEAD -- index.html
|
||||
- Modified haproxy_router.py to allow port 8081 routes (was blocked)
|
||||
- Domain now accessible via HTTPS through WAF with proper access control
|
||||
- Web Terminal (ttyd shell access)
|
||||
|
||||
81. **RezApp Forge - Docker to SecuBox App Converter (2026-03-11)**
|
||||
- Package: `secubox-app-rezapp` with `rezappctl` CLI
|
||||
- UCI configuration: `/etc/config/rezapp` with catalog sources
|
||||
- Supported catalogs: Docker Hub, LinuxServer.io, GitHub Container Registry
|
||||
- CLI commands:
|
||||
- `rezappctl catalog list/add/remove` - Manage catalog sources
|
||||
- `rezappctl search <query>` - Search Docker images across catalogs
|
||||
- `rezappctl info <image>` - Show image details (tags, arch, ENV)
|
||||
- `rezappctl convert <image>` - Docker → LXC conversion
|
||||
- `rezappctl package <app>` - Generate SecuBox package structure
|
||||
- `rezappctl publish <app>` - Add to SecuBox addon catalog
|
||||
- Conversion workflow: pull → export → extract → generate LXC config
|
||||
- Templates: Makefile.tpl, init.d.tpl, ctl.tpl, config.tpl, start-lxc.tpl, lxc-config.tpl, manifest.tpl
|
||||
- Auto-generates procd init scripts, management CLIs, and UCI configs
|
||||
- Enables one-command Docker app deployment: convert → package → install
|
||||
|
||||
82. **Streamlit Forge Plan (2026-03-11)**
|
||||
- Comprehensive Streamlit app publishing platform specification
|
||||
- Features planned:
|
||||
- App upload and source management via Gitea
|
||||
- Multiple running instances with isolated configs
|
||||
- Auto-publishing to SecuBox dedicated spaces
|
||||
- Miniature preview/thumbnail generation
|
||||
- UCI configuration synchronization
|
||||
- Mesh AppStore publishing
|
||||
- Author workspace with blog integration
|
||||
- Templates: basic, dashboard, data-viewer, research-paper, slides, portfolio
|
||||
- Integration with: Gitea, HAProxy, Mitmproxy, MetaBlogizer, SecuBox P2P
|
||||
- Plan: `/home/reepost/.claude/plans/streamlit-forge.md`
|
||||
|
||||
83. **HAProxy Vhost Rename Feature (2026-03-11)**
|
||||
- Added `haproxyctl vhost rename <old> <new>` command
|
||||
- Renames vhost UCI section and all related configurations
|
||||
- Tested: MC360_Streamlit_BPM_v2.gk2.secubox.in → mc360.gk2.secubox.in
|
||||
|
||||
84. **Streamlit Forge - App Publishing Platform (2026-03-11)**
|
||||
- Package: `secubox-app-streamlit-forge` with `slforge` CLI
|
||||
- UCI configuration at `/etc/config/streamlit-forge`
|
||||
- 3 app templates: basic, dashboard, data-viewer
|
||||
- CLI commands:
|
||||
- `slforge create <name> --from-template <tpl>` - Create from template
|
||||
- `slforge start/stop/restart <app>` - Instance control
|
||||
- `slforge status/info/list` - Status and information
|
||||
- `slforge expose <app> --domain <d>` - HAProxy vhost + SSL
|
||||
- `slforge publish/unpublish <app>` - Mesh catalog management
|
||||
- Runs apps in Streamlit LXC container (mount: /srv/apps/)
|
||||
- Port-based status detection (works across LXC namespaces)
|
||||
- Wrapper script approach for reliable container execution
|
||||
- LuCI: `luci-app-streamlit-forge` with RPCD backend
|
||||
- Status dashboard with running/total/LXC cards
|
||||
- Create dialog with template selection
|
||||
- App table with Start/Stop/Open/Expose/Publish/Delete actions
|
||||
- Auto-refresh polling (10s interval)
|
||||
|
||||
85. **RezApp Forge LuCI Dashboard (2026-03-11)**
|
||||
- Package: `luci-app-rezapp` with RPCD backend
|
||||
- Menu: Services > RezApp Forge
|
||||
- Features:
|
||||
- Status cards (converted apps, catalogs, Docker status)
|
||||
- Docker Hub search with star ratings and descriptions
|
||||
- Convert dialog (name, tag, memory options)
|
||||
- Converted apps table with Package/Publish/Delete actions
|
||||
- RPCD methods: status, catalogs, apps, search, info, convert, package, publish, delete
|
||||
- ACL permissions for read/write operations
|
||||
|
||||
86. **SecuBox KISS Apps Catalog Update (2026-03-11)**
|
||||
- Added `luci-app-streamlit-forge` to catalog (productivity, lxc runtime)
|
||||
- Streamlit app publishing with templates, SSL exposure, mesh publishing
|
||||
- Featured as new release
|
||||
- Added `luci-app-rezapp` to catalog (system, native runtime)
|
||||
- Docker to LXC converter with catalog browsing, package generation
|
||||
- Featured as new release
|
||||
- Updated `new_releases` section with both apps
|
||||
- Total plugins: 37 → 39
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# Work In Progress (Claude)
|
||||
|
||||
_Last updated: 2026-03-10 (PeerTube Routing Fix)_
|
||||
_Last updated: 2026-03-11 (Forge LuCI Apps + Documentation)_
|
||||
|
||||
> **Architecture Reference**: SecuBox Fanzine v3 — Les 4 Couches
|
||||
|
||||
@ -8,6 +8,61 @@ _Last updated: 2026-03-10 (PeerTube Routing Fix)_
|
||||
|
||||
## Recently Completed
|
||||
|
||||
### 2026-03-11
|
||||
|
||||
- **RezApp Forge - Docker to SecuBox App Converter**
|
||||
- Package: `secubox-app-rezapp` with `rezappctl` CLI
|
||||
- UCI config: `/etc/config/rezapp` with catalog sources (Docker Hub, LinuxServer.io, GHCR)
|
||||
- Commands: catalog, search, info, convert, package, publish, list
|
||||
- Docker to LXC workflow: pull → export → extract → generate LXC config
|
||||
- Templates: Makefile.tpl, init.d.tpl, ctl.tpl, config.tpl, start-lxc.tpl, lxc-config.tpl, manifest.tpl
|
||||
- Plan: `/home/reepost/.claude/plans/tingly-rolling-sky.md`
|
||||
|
||||
- **Streamlit Forge Phase 1** (implemented)
|
||||
- Package: `secubox-app-streamlit-forge` with `slforge` CLI
|
||||
- UCI config for app management
|
||||
- 3 templates: basic, dashboard, data-viewer
|
||||
- Commands: create, start, stop, restart, status, list, info, delete, templates
|
||||
- Runs apps in Streamlit LXC container with proper mount paths
|
||||
- Port-based status detection (container PID namespaces)
|
||||
- HAProxy expose integration
|
||||
- Mesh catalog publish
|
||||
- **LuCI dashboard**: `luci-app-streamlit-forge` with create/start/stop/expose/publish
|
||||
|
||||
- **RezApp Forge LuCI**
|
||||
- Package: `luci-app-rezapp`
|
||||
- Dashboard with Docker search, conversion dialog
|
||||
- Converted apps table with Package/Publish/Delete
|
||||
- Status cards for apps count, catalogs, Docker status
|
||||
|
||||
- **SecuBox KISS Apps Catalog Update**
|
||||
- Added `luci-app-streamlit-forge` and `luci-app-rezapp` to catalog.json
|
||||
- Category: productivity (Streamlit), system (RezApp)
|
||||
- Featured in new_releases section
|
||||
- Total plugins: 37 → 39
|
||||
|
||||
- **HAProxy Vhost Rename Feature**
|
||||
- Added `haproxyctl vhost rename <old> <new>` command
|
||||
- Renamed MC360_Streamlit_BPM_v2.gk2.secubox.in → mc360.gk2.secubox.in
|
||||
|
||||
- **Lyrion Music Server Upgrade (9.0.3 → 9.1.1)**
|
||||
- Diagnosed library showing 0 tracks (Perl XS module version mismatches)
|
||||
- Root cause: Alpine 3.19 Perl 5.038 incompatible with bundled modules
|
||||
- **Solution**: Rebuilt LXC container from official Docker image
|
||||
- Pulled `lmscommunity/lyrionmusicserver:stable` (Debian Bookworm based)
|
||||
- Exported Docker to tarball, extracted to LXC rootfs
|
||||
- Created `/start-lxc.sh` wrapper for LXC execution
|
||||
- Updated LXC config: UID 499 (squeezeboxserver), new paths
|
||||
- Fixed /srv/lyrion ownership for new UID
|
||||
- Library scan working: 81,430 files discovered
|
||||
- Preserved config in /srv/lyrion (prefs, logs, cache)
|
||||
|
||||
- **Metablogizer Package Conflict**
|
||||
- opkg install fails: `/etc/config/metablogizer` file conflict
|
||||
- Both `secubox-app-metablogizer` and `luci-app-metablogizer` provide same file
|
||||
- Workaround: Deploy scripts directly via SCP instead of package install
|
||||
- TODO: Fix package to use conffiles properly
|
||||
|
||||
### 2026-03-10
|
||||
|
||||
- **PeerTube Routing Fix**
|
||||
@ -298,6 +353,9 @@ _Last updated: 2026-03-10 (PeerTube Routing Fix)_
|
||||
|
||||
## In Progress
|
||||
|
||||
- **Streamlit Forge Phase 2** - Preview generation, Gitea push/pull
|
||||
- **RezApp Forge Full Test** - Test Docker → LXC conversion workflow
|
||||
|
||||
- **RTTY Remote Control Module (Phase 4 - Session Replay)**
|
||||
- Avatar-tap integration for session capture
|
||||
- Replay captured sessions to target nodes
|
||||
|
||||
27
package/secubox/luci-app-rezapp/Makefile
Normal file
27
package/secubox/luci-app-rezapp/Makefile
Normal file
@ -0,0 +1,27 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-rezapp
|
||||
PKG_VERSION:=1.0.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
LUCI_TITLE:=LuCI RezApp Forge - Docker to LXC Converter
|
||||
LUCI_DEPENDS:=+secubox-app-rezapp
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
define Package/luci-app-rezapp/install
|
||||
$(INSTALL_DIR) $(1)/usr/share/luci/menu.d
|
||||
$(INSTALL_DATA) ./root/usr/share/luci/menu.d/luci-app-rezapp.json $(1)/usr/share/luci/menu.d/
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/share/rpcd/acl.d
|
||||
$(INSTALL_DATA) ./root/usr/share/rpcd/acl.d/luci-app-rezapp.json $(1)/usr/share/rpcd/acl.d/
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/libexec/rpcd
|
||||
$(INSTALL_BIN) ./root/usr/libexec/rpcd/luci.rezapp $(1)/usr/libexec/rpcd/
|
||||
|
||||
$(INSTALL_DIR) $(1)/www/luci-static/resources/view/rezapp
|
||||
$(INSTALL_DATA) ./htdocs/luci-static/resources/view/rezapp/*.js $(1)/www/luci-static/resources/view/rezapp/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,luci-app-rezapp))
|
||||
@ -0,0 +1,396 @@
|
||||
'use strict';
|
||||
'require view';
|
||||
'require rpc';
|
||||
'require ui';
|
||||
'require poll';
|
||||
|
||||
var callStatus = rpc.declare({
|
||||
object: 'luci.rezapp',
|
||||
method: 'status',
|
||||
expect: {}
|
||||
});
|
||||
|
||||
var callCatalogs = rpc.declare({
|
||||
object: 'luci.rezapp',
|
||||
method: 'catalogs',
|
||||
expect: {}
|
||||
});
|
||||
|
||||
var callApps = rpc.declare({
|
||||
object: 'luci.rezapp',
|
||||
method: 'apps',
|
||||
expect: {}
|
||||
});
|
||||
|
||||
var callSearch = rpc.declare({
|
||||
object: 'luci.rezapp',
|
||||
method: 'search',
|
||||
params: ['query'],
|
||||
expect: {}
|
||||
});
|
||||
|
||||
var callInfo = rpc.declare({
|
||||
object: 'luci.rezapp',
|
||||
method: 'info',
|
||||
params: ['image'],
|
||||
expect: {}
|
||||
});
|
||||
|
||||
var callConvert = rpc.declare({
|
||||
object: 'luci.rezapp',
|
||||
method: 'convert',
|
||||
params: ['image', 'name', 'tag', 'memory'],
|
||||
expect: {}
|
||||
});
|
||||
|
||||
var callPackage = rpc.declare({
|
||||
object: 'luci.rezapp',
|
||||
method: 'package',
|
||||
params: ['name'],
|
||||
expect: {}
|
||||
});
|
||||
|
||||
var callPublish = rpc.declare({
|
||||
object: 'luci.rezapp',
|
||||
method: 'publish',
|
||||
params: ['name'],
|
||||
expect: {}
|
||||
});
|
||||
|
||||
var callDelete = rpc.declare({
|
||||
object: 'luci.rezapp',
|
||||
method: 'delete',
|
||||
params: ['name'],
|
||||
expect: {}
|
||||
});
|
||||
|
||||
return view.extend({
|
||||
status: {},
|
||||
catalogs: [],
|
||||
apps: [],
|
||||
searchResults: [],
|
||||
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
callStatus(),
|
||||
callCatalogs(),
|
||||
callApps()
|
||||
]);
|
||||
},
|
||||
|
||||
render: function(data) {
|
||||
var self = this;
|
||||
this.status = data[0] || {};
|
||||
this.catalogs = (data[1] && data[1].catalogs) || [];
|
||||
this.apps = (data[2] && data[2].apps) || [];
|
||||
|
||||
var view = E('div', { 'class': 'cbi-map' }, [
|
||||
E('h2', {}, 'RezApp Forge'),
|
||||
E('div', { 'class': 'cbi-map-descr' },
|
||||
'Convert Docker images to SecuBox LXC apps.'),
|
||||
|
||||
// Status cards
|
||||
E('div', { 'class': 'sh-stats', 'style': 'display:flex;gap:1rem;margin:1rem 0;flex-wrap:wrap;' }, [
|
||||
this.renderStatCard('Converted Apps', this.status.apps || 0, '#2196f3'),
|
||||
this.renderStatCard('Catalogs', this.status.catalogs || 0, '#9c27b0'),
|
||||
this.renderStatCard('Docker', this.status.docker_status || 'unknown',
|
||||
this.status.docker_status === 'running' ? '#4caf50' : '#ff9800')
|
||||
]),
|
||||
|
||||
// Search section
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
E('h3', {}, 'Search Docker Hub'),
|
||||
E('div', { 'style': 'display:flex;gap:0.5rem;margin-bottom:1rem;' }, [
|
||||
E('input', {
|
||||
'type': 'text',
|
||||
'id': 'search-query',
|
||||
'class': 'cbi-input-text',
|
||||
'placeholder': 'Search images (e.g., nginx, heimdall)',
|
||||
'style': 'flex:1;'
|
||||
}),
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-action',
|
||||
'click': ui.createHandlerFn(this, 'handleSearch')
|
||||
}, 'Search')
|
||||
]),
|
||||
E('div', { 'id': 'search-results' })
|
||||
]),
|
||||
|
||||
// Converted apps section
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
E('h3', {}, 'Converted Apps'),
|
||||
E('div', { 'id': 'apps-table' }, this.renderAppsTable())
|
||||
])
|
||||
]);
|
||||
|
||||
poll.add(L.bind(this.pollApps, this), 15);
|
||||
|
||||
return view;
|
||||
},
|
||||
|
||||
renderStatCard: function(label, value, color) {
|
||||
return E('div', {
|
||||
'style': 'background:#1a1a2e;border-left:4px solid ' + color + ';padding:1rem;min-width:120px;border-radius:4px;'
|
||||
}, [
|
||||
E('div', { 'style': 'font-size:1.5rem;font-weight:bold;color:' + color }, String(value)),
|
||||
E('div', { 'style': 'color:#888;font-size:0.85rem;' }, label)
|
||||
]);
|
||||
},
|
||||
|
||||
renderAppsTable: function() {
|
||||
if (!this.apps.length) {
|
||||
return E('p', { 'class': 'cbi-value-description' },
|
||||
'No converted apps yet. Search and convert a Docker image to get started.');
|
||||
}
|
||||
|
||||
var rows = this.apps.map(L.bind(function(app) {
|
||||
var statusBadge = E('span', {
|
||||
'class': 'badge',
|
||||
'style': 'background:' + (app.lxc_status === 'running' ? '#4caf50' : app.lxc_status === 'stopped' ? '#ff9800' : '#666') + ';color:#fff;padding:2px 8px;border-radius:10px;font-size:0.8rem;'
|
||||
}, app.lxc_status || 'none');
|
||||
|
||||
var packageBadge = E('span', {
|
||||
'style': 'color:' + (app.packaged === 'yes' ? '#4caf50' : '#666')
|
||||
}, app.packaged === 'yes' ? 'Yes' : 'No');
|
||||
|
||||
var actions = E('div', { 'style': 'display:flex;gap:4px;flex-wrap:wrap;' }, [
|
||||
app.packaged !== 'yes' ?
|
||||
E('button', {
|
||||
'class': 'cbi-button',
|
||||
'style': 'padding:4px 8px;font-size:0.8rem;',
|
||||
'click': ui.createHandlerFn(this, 'handlePackage', app.name)
|
||||
}, 'Package') : '',
|
||||
E('button', {
|
||||
'class': 'cbi-button',
|
||||
'style': 'padding:4px 8px;font-size:0.8rem;',
|
||||
'click': ui.createHandlerFn(this, 'handlePublish', app.name)
|
||||
}, 'Publish'),
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-remove',
|
||||
'style': 'padding:4px 8px;font-size:0.8rem;',
|
||||
'click': ui.createHandlerFn(this, 'handleDelete', app.name)
|
||||
}, 'Delete')
|
||||
]);
|
||||
|
||||
return E('tr', {}, [
|
||||
E('td', {}, app.name),
|
||||
E('td', { 'style': 'font-size:0.85rem;color:#888;' }, app.source_image || '-'),
|
||||
E('td', {}, statusBadge),
|
||||
E('td', {}, packageBadge),
|
||||
E('td', { 'style': 'font-size:0.85rem;' }, app.converted_at || '-'),
|
||||
E('td', {}, actions)
|
||||
]);
|
||||
}, this));
|
||||
|
||||
return E('table', { 'class': 'table cbi-section-table' }, [
|
||||
E('tr', { 'class': 'tr table-titles' }, [
|
||||
E('th', { 'class': 'th' }, 'Name'),
|
||||
E('th', { 'class': 'th' }, 'Source Image'),
|
||||
E('th', { 'class': 'th' }, 'LXC Status'),
|
||||
E('th', { 'class': 'th' }, 'Packaged'),
|
||||
E('th', { 'class': 'th' }, 'Converted'),
|
||||
E('th', { 'class': 'th' }, 'Actions')
|
||||
])
|
||||
].concat(rows));
|
||||
},
|
||||
|
||||
renderSearchResults: function() {
|
||||
var container = document.getElementById('search-results');
|
||||
if (!container) return;
|
||||
|
||||
if (!this.searchResults.length) {
|
||||
container.innerHTML = '';
|
||||
return;
|
||||
}
|
||||
|
||||
var rows = this.searchResults.map(L.bind(function(result) {
|
||||
return E('tr', {}, [
|
||||
E('td', {}, [
|
||||
E('strong', {}, result.image),
|
||||
E('span', { 'style': 'margin-left:0.5rem;color:#ffd700;' }, result.stars ? result.stars + '*' : '')
|
||||
]),
|
||||
E('td', { 'style': 'font-size:0.85rem;color:#888;max-width:300px;overflow:hidden;text-overflow:ellipsis;' },
|
||||
result.description || ''),
|
||||
E('td', {}, [
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-action',
|
||||
'style': 'padding:4px 8px;font-size:0.8rem;',
|
||||
'click': ui.createHandlerFn(this, 'handleConvert', result.image)
|
||||
}, 'Convert')
|
||||
])
|
||||
]);
|
||||
}, this));
|
||||
|
||||
var table = E('table', { 'class': 'table cbi-section-table', 'style': 'margin-top:1rem;' }, [
|
||||
E('tr', { 'class': 'tr table-titles' }, [
|
||||
E('th', { 'class': 'th' }, 'Image'),
|
||||
E('th', { 'class': 'th' }, 'Description'),
|
||||
E('th', { 'class': 'th' }, 'Action')
|
||||
])
|
||||
].concat(rows));
|
||||
|
||||
container.innerHTML = '';
|
||||
container.appendChild(table);
|
||||
},
|
||||
|
||||
pollApps: function() {
|
||||
var self = this;
|
||||
return callApps().then(function(data) {
|
||||
self.apps = (data && data.apps) || [];
|
||||
var container = document.getElementById('apps-table');
|
||||
if (container) {
|
||||
container.innerHTML = '';
|
||||
container.appendChild(self.renderAppsTable());
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
handleSearch: function() {
|
||||
var self = this;
|
||||
var query = document.getElementById('search-query').value.trim();
|
||||
|
||||
if (!query) {
|
||||
ui.addNotification(null, E('p', 'Please enter a search query'));
|
||||
return;
|
||||
}
|
||||
|
||||
var container = document.getElementById('search-results');
|
||||
container.innerHTML = '<p class="spinning">Searching Docker Hub...</p>';
|
||||
|
||||
return callSearch(query).then(function(res) {
|
||||
if (res.code !== 0) {
|
||||
container.innerHTML = '<p style="color:#f44336;">Search failed</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
self.searchResults = res.results || [];
|
||||
self.renderSearchResults();
|
||||
|
||||
if (!self.searchResults.length) {
|
||||
container.innerHTML = '<p>No results found for "' + query + '"</p>';
|
||||
}
|
||||
}).catch(function(err) {
|
||||
container.innerHTML = '<p style="color:#f44336;">Error: ' + err.message + '</p>';
|
||||
});
|
||||
},
|
||||
|
||||
handleConvert: function(image) {
|
||||
var self = this;
|
||||
|
||||
// Extract default name from image
|
||||
var defaultName = image.split('/').pop().split(':')[0].replace(/[^a-zA-Z0-9_-]/g, '_');
|
||||
|
||||
ui.showModal('Convert Docker Image', [
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
E('p', {}, ['Converting: ', E('strong', {}, image)]),
|
||||
E('div', { 'class': 'cbi-value' }, [
|
||||
E('label', { 'class': 'cbi-value-title' }, 'App Name'),
|
||||
E('div', { 'class': 'cbi-value-field' }, [
|
||||
E('input', { 'type': 'text', 'id': 'convert-name', 'class': 'cbi-input-text', 'value': defaultName })
|
||||
])
|
||||
]),
|
||||
E('div', { 'class': 'cbi-value' }, [
|
||||
E('label', { 'class': 'cbi-value-title' }, 'Tag'),
|
||||
E('div', { 'class': 'cbi-value-field' }, [
|
||||
E('input', { 'type': 'text', 'id': 'convert-tag', 'class': 'cbi-input-text', 'value': 'latest', 'placeholder': 'latest' })
|
||||
])
|
||||
]),
|
||||
E('div', { 'class': 'cbi-value' }, [
|
||||
E('label', { 'class': 'cbi-value-title' }, 'Memory Limit'),
|
||||
E('div', { 'class': 'cbi-value-field' }, [
|
||||
E('select', { 'id': 'convert-memory', 'class': 'cbi-input-select' }, [
|
||||
E('option', { 'value': '256M' }, '256 MB'),
|
||||
E('option', { 'value': '512M', 'selected': true }, '512 MB'),
|
||||
E('option', { 'value': '1G' }, '1 GB'),
|
||||
E('option', { 'value': '2G' }, '2 GB')
|
||||
])
|
||||
])
|
||||
])
|
||||
]),
|
||||
E('div', { 'class': 'right' }, [
|
||||
E('button', { 'class': 'cbi-button', 'click': ui.hideModal }, 'Cancel'),
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-positive',
|
||||
'click': function() {
|
||||
var name = document.getElementById('convert-name').value.trim();
|
||||
var tag = document.getElementById('convert-tag').value.trim() || 'latest';
|
||||
var memory = document.getElementById('convert-memory').value;
|
||||
|
||||
if (!name) {
|
||||
ui.addNotification(null, E('p', 'Please enter an app name'));
|
||||
return;
|
||||
}
|
||||
|
||||
ui.hideModal();
|
||||
ui.showModal('Converting...', [
|
||||
E('p', { 'class': 'spinning' }, 'Converting ' + image + ':' + tag + '...'),
|
||||
E('p', { 'style': 'color:#888;font-size:0.85rem;' }, 'This may take several minutes. Please wait...')
|
||||
]);
|
||||
|
||||
callConvert(image, name, tag, memory).then(function(res) {
|
||||
ui.hideModal();
|
||||
if (res.code === 0) {
|
||||
ui.addNotification(null, E('p', 'Conversion complete!'));
|
||||
self.pollApps();
|
||||
} else {
|
||||
ui.addNotification(null, E('p', 'Error: ' + (res.output || 'Conversion failed')));
|
||||
}
|
||||
}).catch(function(err) {
|
||||
ui.hideModal();
|
||||
ui.addNotification(null, E('p', 'Error: ' + err.message));
|
||||
});
|
||||
}
|
||||
}, 'Convert')
|
||||
])
|
||||
]);
|
||||
},
|
||||
|
||||
handlePackage: function(name) {
|
||||
var self = this;
|
||||
ui.showModal('Generating Package...', [
|
||||
E('p', { 'class': 'spinning' }, 'Generating SecuBox package for ' + name + '...')
|
||||
]);
|
||||
|
||||
return callPackage(name).then(function(res) {
|
||||
ui.hideModal();
|
||||
if (res.code === 0) {
|
||||
ui.addNotification(null, E('p', 'Package generated!'));
|
||||
self.pollApps();
|
||||
} else {
|
||||
ui.addNotification(null, E('p', 'Error: ' + (res.output || 'Package generation failed')));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
handlePublish: function(name) {
|
||||
var self = this;
|
||||
ui.showModal('Publishing...', [
|
||||
E('p', { 'class': 'spinning' }, 'Publishing ' + name + ' to catalog...')
|
||||
]);
|
||||
|
||||
return callPublish(name).then(function(res) {
|
||||
ui.hideModal();
|
||||
if (res.code === 0) {
|
||||
ui.addNotification(null, E('p', 'Published to catalog!'));
|
||||
} else {
|
||||
ui.addNotification(null, E('p', 'Error: ' + (res.output || 'Publish failed')));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
handleDelete: function(name) {
|
||||
var self = this;
|
||||
if (!confirm('Delete converted app "' + name + '"? This cannot be undone.')) {
|
||||
return;
|
||||
}
|
||||
|
||||
return callDelete(name).then(function(res) {
|
||||
if (res.code === 0) {
|
||||
ui.addNotification(null, E('p', 'Deleted ' + name));
|
||||
self.pollApps();
|
||||
} else {
|
||||
ui.addNotification(null, E('p', 'Error deleting'));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,265 @@
|
||||
#!/bin/sh
|
||||
# RPCD backend for RezApp Forge LuCI app
|
||||
|
||||
. /lib/functions.sh
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
APPS_DIR="/srv/rezapp/apps"
|
||||
CACHE_DIR="/srv/rezapp/cache"
|
||||
OUTPUT_DIR="/srv/rezapp/generated"
|
||||
|
||||
# Get status overview
|
||||
get_status() {
|
||||
local apps=0
|
||||
local catalogs=0
|
||||
local docker_status="unknown"
|
||||
|
||||
# Count converted apps
|
||||
[ -d "$APPS_DIR" ] && apps=$(ls -1 "$APPS_DIR" 2>/dev/null | wc -l)
|
||||
|
||||
# Count enabled catalogs
|
||||
config_load rezapp
|
||||
config_foreach count_catalog catalog
|
||||
catalogs=$_catalog_count
|
||||
|
||||
# Check Docker status
|
||||
if pgrep dockerd >/dev/null 2>&1; then
|
||||
docker_status="running"
|
||||
else
|
||||
docker_status="stopped"
|
||||
fi
|
||||
|
||||
json_init
|
||||
json_add_int "apps" "$apps"
|
||||
json_add_int "catalogs" "$catalogs"
|
||||
json_add_string "docker_status" "$docker_status"
|
||||
json_dump
|
||||
}
|
||||
|
||||
_catalog_count=0
|
||||
count_catalog() {
|
||||
local enabled
|
||||
config_get enabled "$1" enabled '0'
|
||||
[ "$enabled" = "1" ] && _catalog_count=$((_catalog_count + 1))
|
||||
}
|
||||
|
||||
# Get enabled catalogs
|
||||
get_catalogs() {
|
||||
json_init
|
||||
json_add_array "catalogs"
|
||||
|
||||
config_load rezapp
|
||||
config_foreach add_catalog catalog
|
||||
|
||||
json_close_array
|
||||
json_dump
|
||||
}
|
||||
|
||||
add_catalog() {
|
||||
local section="$1"
|
||||
local name type url namespace enabled
|
||||
|
||||
config_get name "$section" name "$section"
|
||||
config_get type "$section" type 'dockerhub'
|
||||
config_get url "$section" url ''
|
||||
config_get namespace "$section" namespace ''
|
||||
config_get enabled "$section" enabled '0'
|
||||
|
||||
[ "$enabled" = "1" ] || return
|
||||
|
||||
json_add_object ""
|
||||
json_add_string "id" "$section"
|
||||
json_add_string "name" "$name"
|
||||
json_add_string "type" "$type"
|
||||
json_add_string "url" "$url"
|
||||
json_add_string "namespace" "$namespace"
|
||||
json_close_object
|
||||
}
|
||||
|
||||
# Get converted apps
|
||||
get_apps() {
|
||||
json_init
|
||||
json_add_array "apps"
|
||||
|
||||
[ -d "$APPS_DIR" ] || { json_close_array; json_dump; return; }
|
||||
|
||||
for app_dir in "$APPS_DIR"/*/; do
|
||||
[ -d "$app_dir" ] || continue
|
||||
local name=$(basename "$app_dir")
|
||||
|
||||
local source_image=""
|
||||
local converted_at=""
|
||||
|
||||
if [ -f "$app_dir/metadata.json" ]; then
|
||||
source_image=$(jsonfilter -i "$app_dir/metadata.json" -e '@.source_image' 2>/dev/null)
|
||||
converted_at=$(jsonfilter -i "$app_dir/metadata.json" -e '@.converted_at' 2>/dev/null)
|
||||
fi
|
||||
|
||||
# Check if package exists
|
||||
local packaged="no"
|
||||
[ -d "$OUTPUT_DIR/secubox-app-$name" ] && packaged="yes"
|
||||
|
||||
# Check if LXC container exists
|
||||
local lxc_status="none"
|
||||
if [ -d "/srv/lxc/$name" ]; then
|
||||
if lxc-info -n "$name" 2>/dev/null | grep -q "RUNNING"; then
|
||||
lxc_status="running"
|
||||
else
|
||||
lxc_status="stopped"
|
||||
fi
|
||||
fi
|
||||
|
||||
json_add_object ""
|
||||
json_add_string "name" "$name"
|
||||
json_add_string "source_image" "$source_image"
|
||||
json_add_string "converted_at" "$converted_at"
|
||||
json_add_string "packaged" "$packaged"
|
||||
json_add_string "lxc_status" "$lxc_status"
|
||||
json_close_object
|
||||
done
|
||||
|
||||
json_close_array
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Search Docker Hub
|
||||
do_search() {
|
||||
local query="$1"
|
||||
[ -z "$query" ] && { echo '{"error":"Query required"}'; return; }
|
||||
|
||||
local output
|
||||
output=$(rezappctl search "$query" 2>&1)
|
||||
local rc=$?
|
||||
|
||||
# Parse output into JSON
|
||||
json_init
|
||||
json_add_int "code" "$rc"
|
||||
json_add_array "results"
|
||||
|
||||
echo "$output" | grep -E "^\s+" | while read -r line; do
|
||||
local image=$(echo "$line" | awk '{print $1}')
|
||||
local stars=$(echo "$line" | awk '{print $2}' | tr -d '*')
|
||||
local desc=$(echo "$line" | cut -d' ' -f3-)
|
||||
|
||||
[ -n "$image" ] || continue
|
||||
|
||||
json_add_object ""
|
||||
json_add_string "image" "$image"
|
||||
json_add_string "stars" "$stars"
|
||||
json_add_string "description" "$desc"
|
||||
json_close_object
|
||||
done
|
||||
|
||||
json_close_array
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Get image info
|
||||
get_info() {
|
||||
local image="$1"
|
||||
[ -z "$image" ] && { echo '{"error":"Image required"}'; return; }
|
||||
|
||||
local output
|
||||
output=$(rezappctl info "$image" 2>&1)
|
||||
local rc=$?
|
||||
|
||||
# Extract tags
|
||||
local tags=""
|
||||
tags=$(echo "$output" | grep -A100 "Available Tags:" | grep "^\s*-" | sed 's/^\s*-\s*//' | head -10 | tr '\n' ',')
|
||||
|
||||
json_init
|
||||
json_add_int "code" "$rc"
|
||||
json_add_string "image" "$image"
|
||||
json_add_string "tags" "$tags"
|
||||
json_add_string "raw_output" "$output"
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Convert Docker image
|
||||
do_convert() {
|
||||
local image="$1"
|
||||
local name="$2"
|
||||
local tag="$3"
|
||||
local memory="$4"
|
||||
|
||||
[ -z "$image" ] && { echo '{"error":"Image required"}'; return; }
|
||||
|
||||
local cmd="rezappctl convert $image"
|
||||
[ -n "$name" ] && cmd="$cmd --name $name"
|
||||
[ -n "$tag" ] && cmd="$cmd --tag $tag"
|
||||
[ -n "$memory" ] && cmd="$cmd --memory $memory"
|
||||
|
||||
local output
|
||||
output=$(eval "$cmd" 2>&1)
|
||||
local rc=$?
|
||||
|
||||
json_init
|
||||
json_add_int "code" "$rc"
|
||||
json_add_string "output" "$output"
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Generate package
|
||||
do_package() {
|
||||
local name="$1"
|
||||
[ -z "$name" ] && { echo '{"error":"App name required"}'; return; }
|
||||
|
||||
local output
|
||||
output=$(rezappctl package "$name" 2>&1)
|
||||
local rc=$?
|
||||
|
||||
json_init
|
||||
json_add_int "code" "$rc"
|
||||
json_add_string "output" "$output"
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Publish to catalog
|
||||
do_publish() {
|
||||
local name="$1"
|
||||
[ -z "$name" ] && { echo '{"error":"App name required"}'; return; }
|
||||
|
||||
local output
|
||||
output=$(rezappctl publish "$name" 2>&1)
|
||||
local rc=$?
|
||||
|
||||
json_init
|
||||
json_add_int "code" "$rc"
|
||||
json_add_string "output" "$output"
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Delete converted app
|
||||
do_delete() {
|
||||
local name="$1"
|
||||
[ -z "$name" ] && { echo '{"error":"App name required"}'; return; }
|
||||
|
||||
# Remove app directory
|
||||
rm -rf "$APPS_DIR/$name"
|
||||
rm -rf "$OUTPUT_DIR/secubox-app-$name"
|
||||
rm -rf "$OUTPUT_DIR/luci-app-$name"
|
||||
|
||||
json_init
|
||||
json_add_int "code" 0
|
||||
json_add_string "message" "Deleted $name"
|
||||
json_dump
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
list)
|
||||
echo '{"status":{},"catalogs":{},"apps":{},"search":{"query":"String"},"info":{"image":"String"},"convert":{"image":"String","name":"String","tag":"String","memory":"String"},"package":{"name":"String"},"publish":{"name":"String"},"delete":{"name":"String"}}'
|
||||
;;
|
||||
call)
|
||||
case "$2" in
|
||||
status) get_status ;;
|
||||
catalogs) get_catalogs ;;
|
||||
apps) get_apps ;;
|
||||
search) read input; json_load "$input"; json_get_var query query; do_search "$query" ;;
|
||||
info) read input; json_load "$input"; json_get_var image image; get_info "$image" ;;
|
||||
convert) read input; json_load "$input"; json_get_var image image; json_get_var name name; json_get_var tag tag; json_get_var memory memory; do_convert "$image" "$name" "$tag" "$memory" ;;
|
||||
package) read input; json_load "$input"; json_get_var name name; do_package "$name" ;;
|
||||
publish) read input; json_load "$input"; json_get_var name name; do_publish "$name" ;;
|
||||
delete) read input; json_load "$input"; json_get_var name name; do_delete "$name" ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
@ -0,0 +1,14 @@
|
||||
{
|
||||
"admin/services/rezapp": {
|
||||
"title": "RezApp Forge",
|
||||
"order": 86,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "rezapp/overview"
|
||||
},
|
||||
"depends": {
|
||||
"acl": ["luci-app-rezapp"],
|
||||
"uci": { "rezapp": true }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
{
|
||||
"luci-app-rezapp": {
|
||||
"description": "Grant access to RezApp Forge",
|
||||
"read": {
|
||||
"ubus": {
|
||||
"luci.rezapp": ["status", "catalogs", "apps", "search", "info"]
|
||||
},
|
||||
"uci": ["rezapp"]
|
||||
},
|
||||
"write": {
|
||||
"ubus": {
|
||||
"luci.rezapp": ["convert", "package", "publish", "delete"]
|
||||
},
|
||||
"uci": ["rezapp"]
|
||||
}
|
||||
}
|
||||
}
|
||||
27
package/secubox/luci-app-streamlit-forge/Makefile
Normal file
27
package/secubox/luci-app-streamlit-forge/Makefile
Normal file
@ -0,0 +1,27 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-streamlit-forge
|
||||
PKG_VERSION:=1.0.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
LUCI_TITLE:=LuCI Streamlit Forge - App Publishing Platform
|
||||
LUCI_DEPENDS:=+secubox-app-streamlit-forge
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
define Package/luci-app-streamlit-forge/install
|
||||
$(INSTALL_DIR) $(1)/usr/share/luci/menu.d
|
||||
$(INSTALL_DATA) ./root/usr/share/luci/menu.d/luci-app-streamlit-forge.json $(1)/usr/share/luci/menu.d/
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/share/rpcd/acl.d
|
||||
$(INSTALL_DATA) ./root/usr/share/rpcd/acl.d/luci-app-streamlit-forge.json $(1)/usr/share/rpcd/acl.d/
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/libexec/rpcd
|
||||
$(INSTALL_BIN) ./root/usr/libexec/rpcd/luci.streamlit-forge $(1)/usr/libexec/rpcd/
|
||||
|
||||
$(INSTALL_DIR) $(1)/www/luci-static/resources/view/streamlit-forge
|
||||
$(INSTALL_DATA) ./htdocs/luci-static/resources/view/streamlit-forge/*.js $(1)/www/luci-static/resources/view/streamlit-forge/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,luci-app-streamlit-forge))
|
||||
@ -0,0 +1,383 @@
|
||||
'use strict';
|
||||
'require view';
|
||||
'require rpc';
|
||||
'require ui';
|
||||
'require form';
|
||||
'require poll';
|
||||
|
||||
var callList = rpc.declare({
|
||||
object: 'luci.streamlit-forge',
|
||||
method: 'list',
|
||||
expect: {}
|
||||
});
|
||||
|
||||
var callStatus = rpc.declare({
|
||||
object: 'luci.streamlit-forge',
|
||||
method: 'status',
|
||||
expect: {}
|
||||
});
|
||||
|
||||
var callTemplates = rpc.declare({
|
||||
object: 'luci.streamlit-forge',
|
||||
method: 'templates',
|
||||
expect: {}
|
||||
});
|
||||
|
||||
var callCreate = rpc.declare({
|
||||
object: 'luci.streamlit-forge',
|
||||
method: 'create',
|
||||
params: ['name', 'template'],
|
||||
expect: {}
|
||||
});
|
||||
|
||||
var callStart = rpc.declare({
|
||||
object: 'luci.streamlit-forge',
|
||||
method: 'start',
|
||||
params: ['name'],
|
||||
expect: {}
|
||||
});
|
||||
|
||||
var callStop = rpc.declare({
|
||||
object: 'luci.streamlit-forge',
|
||||
method: 'stop',
|
||||
params: ['name'],
|
||||
expect: {}
|
||||
});
|
||||
|
||||
var callDelete = rpc.declare({
|
||||
object: 'luci.streamlit-forge',
|
||||
method: 'delete',
|
||||
params: ['name'],
|
||||
expect: {}
|
||||
});
|
||||
|
||||
var callExpose = rpc.declare({
|
||||
object: 'luci.streamlit-forge',
|
||||
method: 'expose',
|
||||
params: ['name', 'domain'],
|
||||
expect: {}
|
||||
});
|
||||
|
||||
var callPublish = rpc.declare({
|
||||
object: 'luci.streamlit-forge',
|
||||
method: 'publish',
|
||||
params: ['name'],
|
||||
expect: {}
|
||||
});
|
||||
|
||||
return view.extend({
|
||||
apps: [],
|
||||
templates: [],
|
||||
status: {},
|
||||
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
callList(),
|
||||
callStatus(),
|
||||
callTemplates()
|
||||
]);
|
||||
},
|
||||
|
||||
render: function(data) {
|
||||
var self = this;
|
||||
this.apps = (data[0] && data[0].apps) || [];
|
||||
this.status = data[1] || {};
|
||||
this.templates = (data[2] && data[2].templates) || [];
|
||||
|
||||
var view = E('div', { 'class': 'cbi-map' }, [
|
||||
E('h2', {}, 'Streamlit Forge'),
|
||||
E('div', { 'class': 'cbi-map-descr' },
|
||||
'Create, manage, and publish Streamlit applications.'),
|
||||
|
||||
// Status cards
|
||||
E('div', { 'class': 'sh-stats', 'style': 'display:flex;gap:1rem;margin:1rem 0;flex-wrap:wrap;' }, [
|
||||
this.renderStatCard('Running', this.status.running || 0, '#4caf50'),
|
||||
this.renderStatCard('Total Apps', this.status.total || 0, '#2196f3'),
|
||||
this.renderStatCard('LXC Container', this.status.lxc_status || 'unknown',
|
||||
this.status.lxc_status === 'running' ? '#4caf50' : '#ff9800')
|
||||
]),
|
||||
|
||||
// Actions
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
E('h3', {}, 'Actions'),
|
||||
E('div', { 'style': 'display:flex;gap:0.5rem;flex-wrap:wrap;' }, [
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-add',
|
||||
'click': ui.createHandlerFn(this, 'handleCreate')
|
||||
}, '+ Create App'),
|
||||
E('button', {
|
||||
'class': 'cbi-button',
|
||||
'click': ui.createHandlerFn(this, 'handleRefresh')
|
||||
}, 'Refresh')
|
||||
])
|
||||
]),
|
||||
|
||||
// Apps table
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
E('h3', {}, 'Applications'),
|
||||
this.renderAppsTable()
|
||||
])
|
||||
]);
|
||||
|
||||
poll.add(L.bind(this.pollStatus, this), 10);
|
||||
|
||||
return view;
|
||||
},
|
||||
|
||||
renderStatCard: function(label, value, color) {
|
||||
return E('div', {
|
||||
'style': 'background:#1a1a2e;border-left:4px solid ' + color + ';padding:1rem;min-width:120px;border-radius:4px;'
|
||||
}, [
|
||||
E('div', { 'style': 'font-size:1.5rem;font-weight:bold;color:' + color }, String(value)),
|
||||
E('div', { 'style': 'color:#888;font-size:0.85rem;' }, label)
|
||||
]);
|
||||
},
|
||||
|
||||
renderAppsTable: function() {
|
||||
if (!this.apps.length) {
|
||||
return E('p', { 'class': 'cbi-value-description' },
|
||||
'No apps found. Click "Create App" to get started.');
|
||||
}
|
||||
|
||||
var rows = this.apps.map(L.bind(function(app) {
|
||||
var isRunning = app.status === 'running';
|
||||
var statusBadge = E('span', {
|
||||
'class': 'badge',
|
||||
'style': 'background:' + (isRunning ? '#4caf50' : '#666') + ';color:#fff;padding:2px 8px;border-radius:10px;font-size:0.8rem;'
|
||||
}, isRunning ? 'Running' : 'Stopped');
|
||||
|
||||
var actions = E('div', { 'style': 'display:flex;gap:4px;flex-wrap:wrap;' }, [
|
||||
isRunning ?
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-remove',
|
||||
'style': 'padding:4px 8px;font-size:0.8rem;',
|
||||
'click': ui.createHandlerFn(this, 'handleStop', app.name)
|
||||
}, 'Stop') :
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-apply',
|
||||
'style': 'padding:4px 8px;font-size:0.8rem;',
|
||||
'click': ui.createHandlerFn(this, 'handleStart', app.name)
|
||||
}, 'Start'),
|
||||
isRunning && app.port ?
|
||||
E('a', {
|
||||
'class': 'cbi-button',
|
||||
'style': 'padding:4px 8px;font-size:0.8rem;text-decoration:none;',
|
||||
'href': 'http://' + window.location.hostname + ':' + app.port,
|
||||
'target': '_blank'
|
||||
}, 'Open') : '',
|
||||
!app.domain ?
|
||||
E('button', {
|
||||
'class': 'cbi-button',
|
||||
'style': 'padding:4px 8px;font-size:0.8rem;',
|
||||
'click': ui.createHandlerFn(this, 'handleExpose', app.name)
|
||||
}, 'Expose') : '',
|
||||
E('button', {
|
||||
'class': 'cbi-button',
|
||||
'style': 'padding:4px 8px;font-size:0.8rem;',
|
||||
'click': ui.createHandlerFn(this, 'handlePublish', app.name)
|
||||
}, 'Publish'),
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-remove',
|
||||
'style': 'padding:4px 8px;font-size:0.8rem;',
|
||||
'click': ui.createHandlerFn(this, 'handleDelete', app.name)
|
||||
}, 'Delete')
|
||||
]);
|
||||
|
||||
return E('tr', {}, [
|
||||
E('td', {}, app.name),
|
||||
E('td', {}, statusBadge),
|
||||
E('td', {}, app.port || '-'),
|
||||
E('td', {}, app.domain ? E('a', { 'href': 'https://' + app.domain, 'target': '_blank' }, app.domain) : '-'),
|
||||
E('td', {}, app.created || '-'),
|
||||
E('td', {}, actions)
|
||||
]);
|
||||
}, this));
|
||||
|
||||
return E('table', { 'class': 'table cbi-section-table' }, [
|
||||
E('tr', { 'class': 'tr table-titles' }, [
|
||||
E('th', { 'class': 'th' }, 'Name'),
|
||||
E('th', { 'class': 'th' }, 'Status'),
|
||||
E('th', { 'class': 'th' }, 'Port'),
|
||||
E('th', { 'class': 'th' }, 'Domain'),
|
||||
E('th', { 'class': 'th' }, 'Created'),
|
||||
E('th', { 'class': 'th' }, 'Actions')
|
||||
])
|
||||
].concat(rows));
|
||||
},
|
||||
|
||||
pollStatus: function() {
|
||||
var self = this;
|
||||
return Promise.all([callList(), callStatus()]).then(function(data) {
|
||||
self.apps = (data[0] && data[0].apps) || [];
|
||||
self.status = data[1] || {};
|
||||
|
||||
var container = document.querySelector('.cbi-map');
|
||||
if (container) {
|
||||
var statsDiv = container.querySelector('.sh-stats');
|
||||
if (statsDiv) {
|
||||
statsDiv.innerHTML = '';
|
||||
statsDiv.appendChild(self.renderStatCard('Running', self.status.running || 0, '#4caf50'));
|
||||
statsDiv.appendChild(self.renderStatCard('Total Apps', self.status.total || 0, '#2196f3'));
|
||||
statsDiv.appendChild(self.renderStatCard('LXC Container', self.status.lxc_status || 'unknown',
|
||||
self.status.lxc_status === 'running' ? '#4caf50' : '#ff9800'));
|
||||
}
|
||||
|
||||
var tableSection = container.querySelectorAll('.cbi-section')[1];
|
||||
if (tableSection) {
|
||||
var oldTable = tableSection.querySelector('table, p');
|
||||
if (oldTable) {
|
||||
oldTable.replaceWith(self.renderAppsTable());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
handleRefresh: function() {
|
||||
return this.pollStatus();
|
||||
},
|
||||
|
||||
handleCreate: function() {
|
||||
var self = this;
|
||||
var templates = this.templates;
|
||||
|
||||
var templateOptions = templates.map(function(t) {
|
||||
return E('option', { 'value': t.name }, t.name + ' - ' + (t.description || 'No description'));
|
||||
});
|
||||
|
||||
ui.showModal('Create New App', [
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
E('div', { 'class': 'cbi-value' }, [
|
||||
E('label', { 'class': 'cbi-value-title' }, 'App Name'),
|
||||
E('div', { 'class': 'cbi-value-field' }, [
|
||||
E('input', { 'type': 'text', 'id': 'new-app-name', 'class': 'cbi-input-text', 'placeholder': 'myapp' })
|
||||
])
|
||||
]),
|
||||
E('div', { 'class': 'cbi-value' }, [
|
||||
E('label', { 'class': 'cbi-value-title' }, 'Template'),
|
||||
E('div', { 'class': 'cbi-value-field' }, [
|
||||
E('select', { 'id': 'new-app-template', 'class': 'cbi-input-select' }, templateOptions)
|
||||
])
|
||||
])
|
||||
]),
|
||||
E('div', { 'class': 'right' }, [
|
||||
E('button', {
|
||||
'class': 'cbi-button',
|
||||
'click': ui.hideModal
|
||||
}, 'Cancel'),
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-positive',
|
||||
'click': function() {
|
||||
var name = document.getElementById('new-app-name').value.trim();
|
||||
var template = document.getElementById('new-app-template').value;
|
||||
|
||||
if (!name) {
|
||||
ui.addNotification(null, E('p', 'Please enter an app name'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name)) {
|
||||
ui.addNotification(null, E('p', 'Invalid app name. Use letters, numbers, underscore, hyphen.'));
|
||||
return;
|
||||
}
|
||||
|
||||
ui.hideModal();
|
||||
ui.showModal('Creating App...', [
|
||||
E('p', { 'class': 'spinning' }, 'Creating ' + name + ' from ' + template + ' template...')
|
||||
]);
|
||||
|
||||
callCreate(name, template).then(function(res) {
|
||||
ui.hideModal();
|
||||
if (res.code === 0) {
|
||||
ui.addNotification(null, E('p', 'App created successfully!'));
|
||||
self.pollStatus();
|
||||
} else {
|
||||
ui.addNotification(null, E('p', 'Error: ' + (res.output || 'Unknown error')));
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 'Create')
|
||||
])
|
||||
]);
|
||||
},
|
||||
|
||||
handleStart: function(name) {
|
||||
var self = this;
|
||||
ui.showModal('Starting App...', [
|
||||
E('p', { 'class': 'spinning' }, 'Starting ' + name + '...')
|
||||
]);
|
||||
|
||||
return callStart(name).then(function(res) {
|
||||
ui.hideModal();
|
||||
if (res.code === 0) {
|
||||
ui.addNotification(null, E('p', 'App started!'));
|
||||
} else {
|
||||
ui.addNotification(null, E('p', 'Error: ' + (res.output || 'Failed to start')));
|
||||
}
|
||||
return self.pollStatus();
|
||||
});
|
||||
},
|
||||
|
||||
handleStop: function(name) {
|
||||
var self = this;
|
||||
return callStop(name).then(function(res) {
|
||||
if (res.code === 0) {
|
||||
ui.addNotification(null, E('p', 'App stopped'));
|
||||
}
|
||||
return self.pollStatus();
|
||||
});
|
||||
},
|
||||
|
||||
handleDelete: function(name) {
|
||||
var self = this;
|
||||
if (!confirm('Delete app "' + name + '"? This cannot be undone.')) {
|
||||
return;
|
||||
}
|
||||
|
||||
return callDelete(name).then(function(res) {
|
||||
if (res.code === 0) {
|
||||
ui.addNotification(null, E('p', 'App deleted'));
|
||||
} else {
|
||||
ui.addNotification(null, E('p', 'Error: ' + (res.output || 'Failed to delete')));
|
||||
}
|
||||
return self.pollStatus();
|
||||
});
|
||||
},
|
||||
|
||||
handleExpose: function(name) {
|
||||
var self = this;
|
||||
var domain = prompt('Enter domain for ' + name + ' (leave empty for auto):', name + '.apps.secubox.in');
|
||||
if (domain === null) return;
|
||||
|
||||
ui.showModal('Exposing App...', [
|
||||
E('p', { 'class': 'spinning' }, 'Creating vhost and SSL certificate...')
|
||||
]);
|
||||
|
||||
return callExpose(name, domain || '').then(function(res) {
|
||||
ui.hideModal();
|
||||
if (res.code === 0) {
|
||||
ui.addNotification(null, E('p', 'App exposed at ' + (domain || 'auto-domain')));
|
||||
} else {
|
||||
ui.addNotification(null, E('p', 'Error: ' + (res.output || 'Failed to expose')));
|
||||
}
|
||||
return self.pollStatus();
|
||||
});
|
||||
},
|
||||
|
||||
handlePublish: function(name) {
|
||||
var self = this;
|
||||
ui.showModal('Publishing...', [
|
||||
E('p', { 'class': 'spinning' }, 'Publishing to mesh catalog...')
|
||||
]);
|
||||
|
||||
return callPublish(name).then(function(res) {
|
||||
ui.hideModal();
|
||||
if (res.code === 0) {
|
||||
ui.addNotification(null, E('p', 'App published to mesh catalog'));
|
||||
} else {
|
||||
ui.addNotification(null, E('p', 'Error: ' + (res.output || 'Failed to publish')));
|
||||
}
|
||||
return self.pollStatus();
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,365 @@
|
||||
#!/bin/sh
|
||||
# RPCD backend for Streamlit Forge LuCI app
|
||||
|
||||
. /lib/functions.sh
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
APPS_DIR="/srv/streamlit/apps"
|
||||
|
||||
# Get list of apps with status
|
||||
get_apps() {
|
||||
json_init
|
||||
json_add_array "apps"
|
||||
|
||||
config_load streamlit-forge
|
||||
config_get apps_dir main apps_dir '/srv/streamlit/apps'
|
||||
|
||||
for app_dir in "$apps_dir"/*/; do
|
||||
[ -d "$app_dir" ] || continue
|
||||
local name=$(basename "$app_dir")
|
||||
[ "$name" = "." ] || [ "$name" = ".." ] && continue
|
||||
[ -f "$app_dir/.slforge-start.sh" ] && continue
|
||||
|
||||
local enabled port domain entrypoint memory created status
|
||||
|
||||
config_get enabled "$name" enabled '0'
|
||||
config_get port "$name" port ''
|
||||
config_get domain "$name" domain ''
|
||||
config_get entrypoint "$name" entrypoint 'app.py'
|
||||
config_get memory "$name" memory '512M'
|
||||
config_get created "$name" created ''
|
||||
|
||||
# Check status by port
|
||||
status="stopped"
|
||||
if [ -n "$port" ] && netstat -tln 2>/dev/null | grep -q ":$port "; then
|
||||
status="running"
|
||||
fi
|
||||
|
||||
json_add_object ""
|
||||
json_add_string "name" "$name"
|
||||
json_add_string "enabled" "$enabled"
|
||||
json_add_string "port" "$port"
|
||||
json_add_string "domain" "$domain"
|
||||
json_add_string "entrypoint" "$entrypoint"
|
||||
json_add_string "memory" "$memory"
|
||||
json_add_string "created" "$created"
|
||||
json_add_string "status" "$status"
|
||||
json_close_object
|
||||
done
|
||||
|
||||
json_close_array
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Get app info
|
||||
get_info() {
|
||||
local name="$1"
|
||||
[ -z "$name" ] && { echo '{"error":"App name required"}'; return; }
|
||||
|
||||
config_load streamlit-forge
|
||||
config_get apps_dir main apps_dir '/srv/streamlit/apps'
|
||||
|
||||
local app_dir="$apps_dir/$name"
|
||||
[ -d "$app_dir" ] || { echo '{"error":"App not found"}'; return; }
|
||||
|
||||
local enabled port domain entrypoint memory created status
|
||||
|
||||
config_get enabled "$name" enabled '0'
|
||||
config_get port "$name" port ''
|
||||
config_get domain "$name" domain ''
|
||||
config_get entrypoint "$name" entrypoint 'app.py'
|
||||
config_get memory "$name" memory '512M'
|
||||
config_get created "$name" created ''
|
||||
|
||||
status="stopped"
|
||||
if [ -n "$port" ] && netstat -tln 2>/dev/null | grep -q ":$port "; then
|
||||
status="running"
|
||||
fi
|
||||
|
||||
# Get files
|
||||
local files=""
|
||||
if [ -d "$app_dir/src" ]; then
|
||||
files=$(ls -1 "$app_dir/src" 2>/dev/null | head -20 | tr '\n' ',')
|
||||
fi
|
||||
|
||||
json_init
|
||||
json_add_string "name" "$name"
|
||||
json_add_string "enabled" "$enabled"
|
||||
json_add_string "port" "$port"
|
||||
json_add_string "domain" "$domain"
|
||||
json_add_string "entrypoint" "$entrypoint"
|
||||
json_add_string "memory" "$memory"
|
||||
json_add_string "created" "$created"
|
||||
json_add_string "status" "$status"
|
||||
json_add_string "files" "$files"
|
||||
json_add_string "directory" "$app_dir"
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Get available templates
|
||||
get_templates() {
|
||||
json_init
|
||||
json_add_array "templates"
|
||||
|
||||
local tpl_dir="/usr/share/streamlit-forge/templates"
|
||||
for tpl in "$tpl_dir"/*/; do
|
||||
[ -d "$tpl" ] || continue
|
||||
local name=$(basename "$tpl")
|
||||
local desc=""
|
||||
[ -f "$tpl/README.md" ] && desc=$(head -1 "$tpl/README.md" | sed 's/^#\s*//')
|
||||
|
||||
json_add_object ""
|
||||
json_add_string "name" "$name"
|
||||
json_add_string "description" "$desc"
|
||||
json_close_object
|
||||
done
|
||||
|
||||
json_close_array
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Get global status
|
||||
get_status() {
|
||||
local running=0
|
||||
local total=0
|
||||
|
||||
config_load streamlit-forge
|
||||
config_get apps_dir main apps_dir '/srv/streamlit/apps'
|
||||
|
||||
for app_dir in "$apps_dir"/*/; do
|
||||
[ -d "$app_dir" ] || continue
|
||||
local name=$(basename "$app_dir")
|
||||
[ "$name" = "." ] || [ "$name" = ".." ] && continue
|
||||
[ -f "$app_dir/.slforge-start.sh" ] && continue
|
||||
|
||||
total=$((total + 1))
|
||||
|
||||
local port
|
||||
config_get port "$name" port ''
|
||||
if [ -n "$port" ] && netstat -tln 2>/dev/null | grep -q ":$port "; then
|
||||
running=$((running + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
# Check LXC container
|
||||
local lxc_status="stopped"
|
||||
if lxc-info -n streamlit 2>/dev/null | grep -q "RUNNING"; then
|
||||
lxc_status="running"
|
||||
fi
|
||||
|
||||
json_init
|
||||
json_add_int "total" "$total"
|
||||
json_add_int "running" "$running"
|
||||
json_add_string "lxc_status" "$lxc_status"
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Create app
|
||||
do_create() {
|
||||
local name="$1"
|
||||
local template="$2"
|
||||
|
||||
[ -z "$name" ] && { echo '{"error":"App name required"}'; return; }
|
||||
[ -z "$template" ] && template="basic"
|
||||
|
||||
local output
|
||||
output=$(slforge create "$name" --from-template "$template" 2>&1)
|
||||
local rc=$?
|
||||
|
||||
json_init
|
||||
json_add_int "code" "$rc"
|
||||
json_add_string "output" "$output"
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Delete app
|
||||
do_delete() {
|
||||
local name="$1"
|
||||
[ -z "$name" ] && { echo '{"error":"App name required"}'; return; }
|
||||
|
||||
local output
|
||||
output=$(slforge delete "$name" 2>&1)
|
||||
local rc=$?
|
||||
|
||||
json_init
|
||||
json_add_int "code" "$rc"
|
||||
json_add_string "output" "$output"
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Start app
|
||||
do_start() {
|
||||
local name="$1"
|
||||
[ -z "$name" ] && { echo '{"error":"App name required"}'; return; }
|
||||
|
||||
local output
|
||||
output=$(slforge start "$name" 2>&1)
|
||||
local rc=$?
|
||||
|
||||
json_init
|
||||
json_add_int "code" "$rc"
|
||||
json_add_string "output" "$output"
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Stop app
|
||||
do_stop() {
|
||||
local name="$1"
|
||||
[ -z "$name" ] && { echo '{"error":"App name required"}'; return; }
|
||||
|
||||
local output
|
||||
output=$(slforge stop "$name" 2>&1)
|
||||
local rc=$?
|
||||
|
||||
json_init
|
||||
json_add_int "code" "$rc"
|
||||
json_add_string "output" "$output"
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Restart app
|
||||
do_restart() {
|
||||
local name="$1"
|
||||
[ -z "$name" ] && { echo '{"error":"App name required"}'; return; }
|
||||
|
||||
local output
|
||||
output=$(slforge restart "$name" 2>&1)
|
||||
local rc=$?
|
||||
|
||||
json_init
|
||||
json_add_int "code" "$rc"
|
||||
json_add_string "output" "$output"
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Expose app
|
||||
do_expose() {
|
||||
local name="$1"
|
||||
local domain="$2"
|
||||
|
||||
[ -z "$name" ] && { echo '{"error":"App name required"}'; return; }
|
||||
|
||||
local output
|
||||
if [ -n "$domain" ]; then
|
||||
output=$(slforge expose "$name" --domain "$domain" 2>&1)
|
||||
else
|
||||
output=$(slforge expose "$name" 2>&1)
|
||||
fi
|
||||
local rc=$?
|
||||
|
||||
json_init
|
||||
json_add_int "code" "$rc"
|
||||
json_add_string "output" "$output"
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Hide app
|
||||
do_hide() {
|
||||
local name="$1"
|
||||
[ -z "$name" ] && { echo '{"error":"App name required"}'; return; }
|
||||
|
||||
local output
|
||||
output=$(slforge hide "$name" 2>&1)
|
||||
local rc=$?
|
||||
|
||||
json_init
|
||||
json_add_int "code" "$rc"
|
||||
json_add_string "output" "$output"
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Publish to mesh
|
||||
do_publish() {
|
||||
local name="$1"
|
||||
[ -z "$name" ] && { echo '{"error":"App name required"}'; return; }
|
||||
|
||||
local output
|
||||
output=$(slforge publish "$name" 2>&1)
|
||||
local rc=$?
|
||||
|
||||
json_init
|
||||
json_add_int "code" "$rc"
|
||||
json_add_string "output" "$output"
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Unpublish from mesh
|
||||
do_unpublish() {
|
||||
local name="$1"
|
||||
[ -z "$name" ] && { echo '{"error":"App name required"}'; return; }
|
||||
|
||||
local output
|
||||
output=$(slforge unpublish "$name" 2>&1)
|
||||
local rc=$?
|
||||
|
||||
json_init
|
||||
json_add_int "code" "$rc"
|
||||
json_add_string "output" "$output"
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Set config
|
||||
do_set_config() {
|
||||
local name="$1"
|
||||
local key="$2"
|
||||
local value="$3"
|
||||
|
||||
[ -z "$name" ] && { echo '{"error":"App name required"}'; return; }
|
||||
[ -z "$key" ] && { echo '{"error":"Key required"}'; return; }
|
||||
|
||||
uci set streamlit-forge."$name"."$key"="$value"
|
||||
uci commit streamlit-forge
|
||||
|
||||
json_init
|
||||
json_add_int "code" 0
|
||||
json_add_string "message" "Config updated"
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Get config
|
||||
get_config() {
|
||||
local name="$1"
|
||||
[ -z "$name" ] && { echo '{"error":"App name required"}'; return; }
|
||||
|
||||
json_init
|
||||
config_load streamlit-forge
|
||||
|
||||
local enabled port domain entrypoint memory
|
||||
config_get enabled "$name" enabled '0'
|
||||
config_get port "$name" port ''
|
||||
config_get domain "$name" domain ''
|
||||
config_get entrypoint "$name" entrypoint 'app.py'
|
||||
config_get memory "$name" memory '512M'
|
||||
|
||||
json_add_string "enabled" "$enabled"
|
||||
json_add_string "port" "$port"
|
||||
json_add_string "domain" "$domain"
|
||||
json_add_string "entrypoint" "$entrypoint"
|
||||
json_add_string "memory" "$memory"
|
||||
json_dump
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
list)
|
||||
echo '{"list":{},"status":{},"info":{"name":"String"},"templates":{},"config":{"name":"String"},"create":{"name":"String","template":"String"},"delete":{"name":"String"},"start":{"name":"String"},"stop":{"name":"String"},"restart":{"name":"String"},"expose":{"name":"String","domain":"String"},"hide":{"name":"String"},"publish":{"name":"String"},"unpublish":{"name":"String"},"set_config":{"name":"String","key":"String","value":"String"}}'
|
||||
;;
|
||||
call)
|
||||
case "$2" in
|
||||
list) get_apps ;;
|
||||
status) get_status ;;
|
||||
info) read input; json_load "$input"; json_get_var name name; get_info "$name" ;;
|
||||
templates) get_templates ;;
|
||||
config) read input; json_load "$input"; json_get_var name name; get_config "$name" ;;
|
||||
create) read input; json_load "$input"; json_get_var name name; json_get_var template template; do_create "$name" "$template" ;;
|
||||
delete) read input; json_load "$input"; json_get_var name name; do_delete "$name" ;;
|
||||
start) read input; json_load "$input"; json_get_var name name; do_start "$name" ;;
|
||||
stop) read input; json_load "$input"; json_get_var name name; do_stop "$name" ;;
|
||||
restart) read input; json_load "$input"; json_get_var name name; do_restart "$name" ;;
|
||||
expose) read input; json_load "$input"; json_get_var name name; json_get_var domain domain; do_expose "$name" "$domain" ;;
|
||||
hide) read input; json_load "$input"; json_get_var name name; do_hide "$name" ;;
|
||||
publish) read input; json_load "$input"; json_get_var name name; do_publish "$name" ;;
|
||||
unpublish) read input; json_load "$input"; json_get_var name name; do_unpublish "$name" ;;
|
||||
set_config) read input; json_load "$input"; json_get_var name name; json_get_var key key; json_get_var value value; do_set_config "$name" "$key" "$value" ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
@ -0,0 +1,14 @@
|
||||
{
|
||||
"admin/services/streamlit-forge": {
|
||||
"title": "Streamlit Forge",
|
||||
"order": 85,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "streamlit-forge/overview"
|
||||
},
|
||||
"depends": {
|
||||
"acl": ["luci-app-streamlit-forge"],
|
||||
"uci": { "streamlit-forge": true }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
{
|
||||
"luci-app-streamlit-forge": {
|
||||
"description": "Grant access to Streamlit Forge",
|
||||
"read": {
|
||||
"ubus": {
|
||||
"luci.streamlit-forge": ["list", "status", "info", "templates", "config"]
|
||||
},
|
||||
"uci": ["streamlit-forge"]
|
||||
},
|
||||
"write": {
|
||||
"ubus": {
|
||||
"luci.streamlit-forge": ["create", "delete", "start", "stop", "restart", "expose", "hide", "publish", "unpublish", "set_config"]
|
||||
},
|
||||
"uci": ["streamlit-forge"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,7 +7,7 @@ Architecture: all
|
||||
Installed-Size: 61440
|
||||
Description: Data Sovereignty Engine with multi-tier classification for ANSSI CSPN compliance
|
||||
Filename: luci-app-ai-gateway_1.0.0-r1_all.ipk
|
||||
Size: 10787
|
||||
Size: 10789
|
||||
|
||||
Package: luci-app-ai-insights
|
||||
Version: 1.0.0-r1
|
||||
@ -22,7 +22,7 @@ Description: Unified AI security insights dashboard for SecuBox.
|
||||
DNS Guard, Network Anomaly, CVE Triage, and LocalRecall.
|
||||
Provides security posture scoring and AI-powered analysis.
|
||||
Filename: luci-app-ai-insights_1.0.0-r1_all.ipk
|
||||
Size: 11635
|
||||
Size: 11638
|
||||
|
||||
Package: luci-app-auth-guardian
|
||||
Version: 0.4.0-r3
|
||||
@ -34,7 +34,7 @@ Architecture: all
|
||||
Installed-Size: 71680
|
||||
Description: Comprehensive authentication and session management with captive portal, OAuth2/OIDC integration, voucher system, and time-based access control
|
||||
Filename: luci-app-auth-guardian_0.4.0-r3_all.ipk
|
||||
Size: 12393
|
||||
Size: 12391
|
||||
|
||||
Package: luci-app-backup
|
||||
Version: 1.0.0-r1
|
||||
@ -46,7 +46,7 @@ Architecture: all
|
||||
Installed-Size: 30720
|
||||
Description: LuCI Backup Manager
|
||||
Filename: luci-app-backup_1.0.0-r1_all.ipk
|
||||
Size: 4535
|
||||
Size: 4532
|
||||
|
||||
Package: luci-app-bandwidth-manager
|
||||
Version: 0.5.0-r2
|
||||
@ -58,7 +58,7 @@ Architecture: all
|
||||
Installed-Size: 337920
|
||||
Description: Advanced bandwidth management with QoS rules, client quotas, and SQM integration
|
||||
Filename: luci-app-bandwidth-manager_0.5.0-r2_all.ipk
|
||||
Size: 61684
|
||||
Size: 61683
|
||||
|
||||
Package: luci-app-cdn-cache
|
||||
Version: 0.5.0-r3
|
||||
@ -70,7 +70,7 @@ Architecture: all
|
||||
Installed-Size: 122880
|
||||
Description: Dashboard for managing local CDN caching proxy on OpenWrt
|
||||
Filename: luci-app-cdn-cache_0.5.0-r3_all.ipk
|
||||
Size: 24252
|
||||
Size: 24256
|
||||
|
||||
Package: luci-app-client-guardian
|
||||
Version: 0.4.0-r7
|
||||
@ -82,7 +82,7 @@ Architecture: all
|
||||
Installed-Size: 276480
|
||||
Description: Network Access Control with client monitoring, zone management, captive portal, parental controls, and SMS/email alerts
|
||||
Filename: luci-app-client-guardian_0.4.0-r7_all.ipk
|
||||
Size: 52682
|
||||
Size: 52687
|
||||
|
||||
Package: luci-app-cloner
|
||||
Version: 1.0.0-r1
|
||||
@ -93,7 +93,7 @@ Architecture: all
|
||||
Installed-Size: 102400
|
||||
Description: SecuBox cloning station for building and deploying clone images
|
||||
Filename: luci-app-cloner_1.0.0-r1_all.ipk
|
||||
Size: 19431
|
||||
Size: 19434
|
||||
|
||||
Package: luci-app-config-advisor
|
||||
Version: 1.0.0-r1
|
||||
@ -105,7 +105,7 @@ Architecture: all
|
||||
Installed-Size: 51200
|
||||
Description: ANSSI CSPN compliance checking and security configuration advisor
|
||||
Filename: luci-app-config-advisor_1.0.0-r1_all.ipk
|
||||
Size: 8858
|
||||
Size: 8857
|
||||
|
||||
Package: luci-app-cookie-tracker
|
||||
Version: 1.0.0-r1
|
||||
@ -116,7 +116,7 @@ Architecture: all
|
||||
Installed-Size: 30720
|
||||
Description: LuCI Cookie Tracker Dashboard
|
||||
Filename: luci-app-cookie-tracker_1.0.0-r1_all.ipk
|
||||
Size: 5657
|
||||
Size: 5655
|
||||
|
||||
Package: luci-app-crowdsec-dashboard
|
||||
Version: 0.8.0-r1
|
||||
@ -140,7 +140,7 @@ Architecture: all
|
||||
Installed-Size: 30720
|
||||
Description: LuCI CVE Triage Dashboard
|
||||
Filename: luci-app-cve-triage_1.0.0-r1_all.ipk
|
||||
Size: 5942
|
||||
Size: 5941
|
||||
|
||||
Package: luci-app-cyberfeed
|
||||
Version: 0.1.1-r1
|
||||
@ -152,7 +152,7 @@ Architecture: all
|
||||
Installed-Size: 71680
|
||||
Description: Cyberpunk-themed RSS feed aggregator dashboard with social media support
|
||||
Filename: luci-app-cyberfeed_0.1.1-r1_all.ipk
|
||||
Size: 12884
|
||||
Size: 12882
|
||||
|
||||
Package: luci-app-device-intel
|
||||
Version: 1.0.0-r1
|
||||
@ -183,7 +183,7 @@ Description: SecuBox DNS Guard provides privacy-focused DNS management with AI-
|
||||
- Real-time alerts and blocklist management
|
||||
- Domain analysis with LocalAI integration
|
||||
Filename: luci-app-dnsguard_1.1.0-r1_all.ipk
|
||||
Size: 12446
|
||||
Size: 12449
|
||||
|
||||
Package: luci-app-dns-provider
|
||||
Version: 1.0.0-r1
|
||||
@ -195,7 +195,7 @@ Architecture: all
|
||||
Installed-Size: 40960
|
||||
Description: LuCI DNS Provider Manager
|
||||
Filename: luci-app-dns-provider_1.0.0-r1_all.ipk
|
||||
Size: 7166
|
||||
Size: 7167
|
||||
|
||||
Package: luci-app-domoticz
|
||||
Version: 1.0.0-r1
|
||||
@ -207,7 +207,7 @@ Architecture: all
|
||||
Installed-Size: 40960
|
||||
Description: LuCI Domoticz Home Automation Configuration
|
||||
Filename: luci-app-domoticz_1.0.0-r1_all.ipk
|
||||
Size: 7122
|
||||
Size: 7123
|
||||
|
||||
Package: luci-app-exposure
|
||||
Version: 1.0.0-r3
|
||||
@ -219,7 +219,7 @@ Architecture: all
|
||||
Installed-Size: 71680
|
||||
Description: LuCI SecuBox Service Exposure Manager
|
||||
Filename: luci-app-exposure_1.0.0-r3_all.ipk
|
||||
Size: 11699
|
||||
Size: 11695
|
||||
|
||||
Package: luci-app-gitea
|
||||
Version: 1.0.0-r2
|
||||
@ -231,7 +231,7 @@ Architecture: all
|
||||
Installed-Size: 92160
|
||||
Description: Modern dashboard for Gitea Platform management on OpenWrt
|
||||
Filename: luci-app-gitea_1.0.0-r2_all.ipk
|
||||
Size: 16620
|
||||
Size: 16621
|
||||
|
||||
Package: luci-app-glances
|
||||
Version: 1.0.0-r2
|
||||
@ -243,7 +243,7 @@ Architecture: all
|
||||
Installed-Size: 51200
|
||||
Description: Modern dashboard for Glances system monitoring with SecuBox theme
|
||||
Filename: luci-app-glances_1.0.0-r2_all.ipk
|
||||
Size: 7017
|
||||
Size: 7015
|
||||
|
||||
Package: luci-app-gotosocial
|
||||
Version: 0.1.0-r1
|
||||
@ -255,7 +255,7 @@ Architecture: all
|
||||
Installed-Size: 51200
|
||||
Description: LuCI app for GoToSocial Fediverse Server
|
||||
Filename: luci-app-gotosocial_0.1.0-r1_all.ipk
|
||||
Size: 8208
|
||||
Size: 8206
|
||||
|
||||
Package: luci-app-haproxy
|
||||
Version: 1.0.0-r8
|
||||
@ -267,7 +267,7 @@ Architecture: all
|
||||
Installed-Size: 225280
|
||||
Description: Web interface for managing HAProxy load balancer with vhosts, SSL certificates, and backend routing
|
||||
Filename: luci-app-haproxy_1.0.0-r8_all.ipk
|
||||
Size: 35342
|
||||
Size: 35339
|
||||
|
||||
Package: luci-app-hexojs
|
||||
Version: 1.0.0-r3
|
||||
@ -279,7 +279,7 @@ Architecture: all
|
||||
Installed-Size: 194560
|
||||
Description: Modern dashboard for Hexo static site generator on OpenWrt
|
||||
Filename: luci-app-hexojs_1.0.0-r3_all.ipk
|
||||
Size: 30451
|
||||
Size: 30453
|
||||
|
||||
Package: luci-app-iot-guard
|
||||
Version: 1.0.0-r1
|
||||
@ -291,7 +291,7 @@ Architecture: all
|
||||
Installed-Size: 61440
|
||||
Description: IoT device isolation and security monitoring interface
|
||||
Filename: luci-app-iot-guard_1.0.0-r1_all.ipk
|
||||
Size: 10535
|
||||
Size: 10533
|
||||
|
||||
Package: luci-app-ipblocklist
|
||||
Version: 1.0.0-r1
|
||||
@ -303,7 +303,7 @@ Architecture: all
|
||||
Installed-Size: 40960
|
||||
Description: SecuBox IP Blocklist - Static threat defense dashboard
|
||||
Filename: luci-app-ipblocklist_1.0.0-r1_all.ipk
|
||||
Size: 6528
|
||||
Size: 6529
|
||||
|
||||
Package: luci-app-jabber
|
||||
Version: 0
|
||||
@ -315,7 +315,7 @@ Architecture: all
|
||||
Installed-Size: 61440
|
||||
Description: LuCI Jabber/XMPP Server (Prosody)
|
||||
Filename: luci-app-jabber_0_all.ipk
|
||||
Size: 9308
|
||||
Size: 9311
|
||||
|
||||
Package: luci-app-jellyfin
|
||||
Version: 1.0.0-r1
|
||||
@ -327,7 +327,7 @@ Architecture: all
|
||||
Installed-Size: 51200
|
||||
Description: LuCI Jellyfin Media Server Configuration
|
||||
Filename: luci-app-jellyfin_1.0.0-r1_all.ipk
|
||||
Size: 10486
|
||||
Size: 10483
|
||||
|
||||
Package: luci-app-jitsi
|
||||
Version: 1.0.0-r1
|
||||
@ -339,7 +339,7 @@ Architecture: all
|
||||
Installed-Size: 30720
|
||||
Description: LuCI Jitsi Meet Configuration
|
||||
Filename: luci-app-jitsi_1.0.0-r1_all.ipk
|
||||
Size: 5175
|
||||
Size: 5173
|
||||
|
||||
Package: luci-app-ksm-manager
|
||||
Version: 0.4.0-r2
|
||||
@ -351,7 +351,7 @@ Architecture: all
|
||||
Installed-Size: 112640
|
||||
Description: Centralized cryptographic key management with hardware security module (HSM) support for Nitrokey and YubiKey devices. Provides secure key storage, certificate management, SSH key handling, and secret storage with audit logging.
|
||||
Filename: luci-app-ksm-manager_0.4.0-r2_all.ipk
|
||||
Size: 18778
|
||||
Size: 18780
|
||||
|
||||
Package: luci-app-localai
|
||||
Version: 0.1.0-r15
|
||||
@ -375,7 +375,7 @@ Architecture: all
|
||||
Installed-Size: 40960
|
||||
Description: LuCI LocalRecall AI Memory Dashboard
|
||||
Filename: luci-app-localrecall_1.0.0-r1_all.ipk
|
||||
Size: 8415
|
||||
Size: 8413
|
||||
|
||||
Package: luci-app-lyrion
|
||||
Version: 1.0.0-r1
|
||||
@ -387,7 +387,7 @@ Architecture: all
|
||||
Installed-Size: 40960
|
||||
Description: LuCI support for Lyrion Music Server
|
||||
Filename: luci-app-lyrion_1.0.0-r1_all.ipk
|
||||
Size: 6841
|
||||
Size: 6837
|
||||
|
||||
Package: luci-app-mac-guardian
|
||||
Version: 0.5.0-r1
|
||||
@ -399,7 +399,7 @@ Architecture: all
|
||||
Installed-Size: 40960
|
||||
Description: LuCI MAC Guardian - WiFi MAC Security Monitor
|
||||
Filename: luci-app-mac-guardian_0.5.0-r1_all.ipk
|
||||
Size: 6660
|
||||
Size: 6667
|
||||
|
||||
Package: luci-app-magicmirror2
|
||||
Version: 0.4.0-r6
|
||||
@ -411,7 +411,7 @@ Architecture: all
|
||||
Installed-Size: 71680
|
||||
Description: Modern dashboard for MagicMirror2 smart display platform with module manager and SecuBox theme
|
||||
Filename: luci-app-magicmirror2_0.4.0-r6_all.ipk
|
||||
Size: 12359
|
||||
Size: 12358
|
||||
|
||||
Package: luci-app-mailinabox
|
||||
Version: 1.0.0-r1
|
||||
@ -423,7 +423,7 @@ Architecture: all
|
||||
Installed-Size: 30720
|
||||
Description: LuCI support for Mail-in-a-Box
|
||||
Filename: luci-app-mailinabox_1.0.0-r1_all.ipk
|
||||
Size: 5484
|
||||
Size: 5482
|
||||
|
||||
Package: luci-app-mailserver
|
||||
Version: 1.0.0-r1
|
||||
@ -435,7 +435,7 @@ Architecture: all
|
||||
Installed-Size: 40960
|
||||
Description: LuCI Mail Server Manager
|
||||
Filename: luci-app-mailserver_1.0.0-r1_all.ipk
|
||||
Size: 6515
|
||||
Size: 6510
|
||||
|
||||
Package: luci-app-master-link
|
||||
Version: 1.0.0-r1
|
||||
@ -447,7 +447,7 @@ Architecture: all
|
||||
Installed-Size: 30720
|
||||
Description: LuCI SecuBox Master-Link Mesh Management
|
||||
Filename: luci-app-master-link_1.0.0-r1_all.ipk
|
||||
Size: 6305
|
||||
Size: 6309
|
||||
|
||||
Package: luci-app-matrix
|
||||
Version: 1.0.0-r1
|
||||
@ -459,7 +459,7 @@ Architecture: all
|
||||
Installed-Size: 40960
|
||||
Description: LuCI Matrix Homeserver Dashboard
|
||||
Filename: luci-app-matrix_1.0.0-r1_all.ipk
|
||||
Size: 7524
|
||||
Size: 7518
|
||||
|
||||
Package: luci-app-media-flow
|
||||
Version: 0.6.4-r1
|
||||
@ -471,7 +471,7 @@ Architecture: all
|
||||
Installed-Size: 133120
|
||||
Description: Real-time detection and monitoring of streaming services (Netflix, YouTube, Spotify, etc.) with quality estimation, history tracking, and alerts. Supports nDPId local DPI and netifyd.
|
||||
Filename: luci-app-media-flow_0.6.4-r1_all.ipk
|
||||
Size: 25380
|
||||
Size: 25379
|
||||
|
||||
Package: luci-app-metablogizer
|
||||
Version: 1.1.0-r1
|
||||
@ -483,7 +483,7 @@ Architecture: all
|
||||
Installed-Size: 133120
|
||||
Description: LuCI support for MetaBlogizer Static Site Publisher
|
||||
Filename: luci-app-metablogizer_1.1.0-r1_all.ipk
|
||||
Size: 26205
|
||||
Size: 26203
|
||||
|
||||
Package: luci-app-metabolizer
|
||||
Version: 1.0.0-r2
|
||||
@ -495,7 +495,7 @@ Architecture: all
|
||||
Installed-Size: 30720
|
||||
Description: LuCI support for Metabolizer CMS
|
||||
Filename: luci-app-metabolizer_1.0.0-r2_all.ipk
|
||||
Size: 4825
|
||||
Size: 4822
|
||||
|
||||
Package: luci-app-mitmproxy
|
||||
Version: 0.5.0-r2
|
||||
@ -519,7 +519,7 @@ Architecture: all
|
||||
Installed-Size: 51200
|
||||
Description: Web interface for MMPM - MagicMirror Package Manager
|
||||
Filename: luci-app-mmpm_0.2.0-r3_all.ipk
|
||||
Size: 7969
|
||||
Size: 7968
|
||||
|
||||
Package: luci-app-mqtt-bridge
|
||||
Version: 0.4.0-r4
|
||||
@ -531,7 +531,7 @@ Architecture: all
|
||||
Installed-Size: 122880
|
||||
Description: USB-to-MQTT IoT hub with SecuBox theme
|
||||
Filename: luci-app-mqtt-bridge_0.4.0-r4_all.ipk
|
||||
Size: 22691
|
||||
Size: 22688
|
||||
|
||||
Package: luci-app-ndpid
|
||||
Version: 1.1.2-r2
|
||||
@ -567,7 +567,7 @@ Architecture: all
|
||||
Installed-Size: 40960
|
||||
Description: LuCI Network Anomaly Detection Dashboard
|
||||
Filename: luci-app-network-anomaly_1.0.0-r1_all.ipk
|
||||
Size: 7646
|
||||
Size: 7641
|
||||
|
||||
Package: luci-app-network-modes
|
||||
Version: 0.5.0-r3
|
||||
@ -579,7 +579,7 @@ Architecture: all
|
||||
Installed-Size: 286720
|
||||
Description: Configure OpenWrt for different network modes: Sniffer, Access Point, Relay, Router
|
||||
Filename: luci-app-network-modes_0.5.0-r3_all.ipk
|
||||
Size: 54227
|
||||
Size: 54225
|
||||
|
||||
Package: luci-app-network-tweaks
|
||||
Version: 1.0.0-r7
|
||||
@ -591,7 +591,7 @@ Architecture: all
|
||||
Installed-Size: 81920
|
||||
Description: Unified network services dashboard with DNS/hosts sync, CDN cache control, and WPAD auto-proxy configuration
|
||||
Filename: luci-app-network-tweaks_1.0.0-r7_all.ipk
|
||||
Size: 15947
|
||||
Size: 15943
|
||||
|
||||
Package: luci-app-nextcloud
|
||||
Version: 1.0.0-r1
|
||||
@ -603,7 +603,7 @@ Architecture: all
|
||||
Installed-Size: 51200
|
||||
Description: LuCI support for Nextcloud LXC
|
||||
Filename: luci-app-nextcloud_1.0.0-r1_all.ipk
|
||||
Size: 10351
|
||||
Size: 10347
|
||||
|
||||
Package: luci-app-ollama
|
||||
Version: 0.1.0-r1
|
||||
@ -615,7 +615,7 @@ Architecture: all
|
||||
Installed-Size: 71680
|
||||
Description: Modern dashboard for Ollama LLM management on OpenWrt
|
||||
Filename: luci-app-ollama_0.1.0-r1_all.ipk
|
||||
Size: 14333
|
||||
Size: 14337
|
||||
|
||||
Package: luci-app-openclaw
|
||||
Version: 1.0.0-r1
|
||||
@ -627,7 +627,7 @@ Architecture: all
|
||||
Installed-Size: 40960
|
||||
Description: Web interface for OpenClaw personal AI with Claude/OpenAI/Ollama support
|
||||
Filename: luci-app-openclaw_1.0.0-r1_all.ipk
|
||||
Size: 8412
|
||||
Size: 8409
|
||||
|
||||
Package: luci-app-peertube
|
||||
Version: 0
|
||||
@ -639,7 +639,7 @@ Architecture: all
|
||||
Installed-Size: 30720
|
||||
Description: LuCI PeerTube Video Platform
|
||||
Filename: luci-app-peertube_0_all.ipk
|
||||
Size: 5757
|
||||
Size: 5755
|
||||
|
||||
Package: luci-app-picobrew
|
||||
Version: 1.0.0-r1
|
||||
@ -651,7 +651,7 @@ Architecture: all
|
||||
Installed-Size: 51200
|
||||
Description: Modern dashboard for PicoBrew Server management on OpenWrt
|
||||
Filename: luci-app-picobrew_1.0.0-r1_all.ipk
|
||||
Size: 9535
|
||||
Size: 9531
|
||||
|
||||
Package: luci-app-secubox
|
||||
Version: 0.7.1-r4
|
||||
@ -663,7 +663,7 @@ Architecture: all
|
||||
Installed-Size: 440320
|
||||
Description: Central control hub for all SecuBox modules. Provides unified dashboard, module status, system health monitoring, and quick actions.
|
||||
Filename: luci-app-secubox_0.7.1-r4_all.ipk
|
||||
Size: 82095
|
||||
Size: 82094
|
||||
|
||||
Package: luci-app-secubox-admin
|
||||
Version: 1.0.0-r19
|
||||
@ -686,7 +686,7 @@ Architecture: all
|
||||
Installed-Size: 81920
|
||||
Description: LuCI SecuBox CrowdSec Dashboard
|
||||
Filename: luci-app-secubox-crowdsec_1.0.0-r3_all.ipk
|
||||
Size: 13916
|
||||
Size: 13921
|
||||
|
||||
Package: luci-app-secubox-mirror
|
||||
Version: 0.1.0-r1
|
||||
@ -698,7 +698,7 @@ Architecture: all
|
||||
Installed-Size: 40960
|
||||
Description: LuCI MirrorNet Dashboard
|
||||
Filename: luci-app-secubox-mirror_0.1.0-r1_all.ipk
|
||||
Size: 5847
|
||||
Size: 5848
|
||||
|
||||
Package: luci-app-secubox-netdiag
|
||||
Version: 1.0.0-r1
|
||||
@ -710,7 +710,7 @@ Architecture: all
|
||||
Installed-Size: 81920
|
||||
Description: Real-time DSA switch port statistics, error monitoring, and network health diagnostics
|
||||
Filename: luci-app-secubox-netdiag_1.0.0-r1_all.ipk
|
||||
Size: 15344
|
||||
Size: 15342
|
||||
|
||||
Package: luci-app-secubox-netifyd
|
||||
Version: 1.2.1-r1
|
||||
@ -722,7 +722,7 @@ Architecture: all
|
||||
Installed-Size: 194560
|
||||
Description: Complete LuCI interface for netifyd DPI engine with real-time flow monitoring, application detection, network analytics, and flow action plugins
|
||||
Filename: luci-app-secubox-netifyd_1.2.1-r1_all.ipk
|
||||
Size: 36720
|
||||
Size: 36715
|
||||
|
||||
Package: luci-app-secubox-p2p
|
||||
Version: 0.1.0-r1
|
||||
@ -734,7 +734,7 @@ Architecture: all
|
||||
Installed-Size: 245760
|
||||
Description: LuCI SecuBox P2P Hub
|
||||
Filename: luci-app-secubox-p2p_0.1.0-r1_all.ipk
|
||||
Size: 46832
|
||||
Size: 46830
|
||||
|
||||
Package: luci-app-secubox-portal
|
||||
Version: 0.7.0-r3
|
||||
@ -758,7 +758,7 @@ Architecture: all
|
||||
Installed-Size: 61440
|
||||
Description: Unified dashboard integrating netifyd DPI threats with CrowdSec intelligence for real-time threat monitoring and automated blocking
|
||||
Filename: luci-app-secubox-security-threats_1.0.0-r4_all.ipk
|
||||
Size: 10656
|
||||
Size: 10657
|
||||
|
||||
Package: luci-app-secubox-users
|
||||
Version: 1.0.0-r1
|
||||
@ -769,7 +769,7 @@ Architecture: all
|
||||
Installed-Size: 30720
|
||||
Description: LuCI SecuBox User Management
|
||||
Filename: luci-app-secubox-users_1.0.0-r1_all.ipk
|
||||
Size: 5144
|
||||
Size: 5141
|
||||
|
||||
Package: luci-app-service-registry
|
||||
Version: 1.0.0-r1
|
||||
@ -781,7 +781,7 @@ Architecture: all
|
||||
Installed-Size: 194560
|
||||
Description: Unified service aggregation with HAProxy vhosts, Tor hidden services, and QR-coded landing page
|
||||
Filename: luci-app-service-registry_1.0.0-r1_all.ipk
|
||||
Size: 39952
|
||||
Size: 39953
|
||||
|
||||
Package: luci-app-simplex
|
||||
Version: 1.0.0-r1
|
||||
@ -793,7 +793,7 @@ Architecture: all
|
||||
Installed-Size: 40960
|
||||
Description: LuCI SimpleX Chat Server Configuration
|
||||
Filename: luci-app-simplex_1.0.0-r1_all.ipk
|
||||
Size: 7035
|
||||
Size: 7033
|
||||
|
||||
Package: luci-app-streamlit
|
||||
Version: 1.0.0-r11
|
||||
@ -805,7 +805,7 @@ Architecture: all
|
||||
Installed-Size: 112640
|
||||
Description: Multi-instance Streamlit management with Gitea integration
|
||||
Filename: luci-app-streamlit_1.0.0-r11_all.ipk
|
||||
Size: 20565
|
||||
Size: 20567
|
||||
|
||||
Package: luci-app-system-hub
|
||||
Version: 0.5.2-r2
|
||||
@ -817,7 +817,7 @@ Architecture: all
|
||||
Installed-Size: 327680
|
||||
Description: Central system control with monitoring, services, logs, and backup
|
||||
Filename: luci-app-system-hub_0.5.2-r2_all.ipk
|
||||
Size: 64292
|
||||
Size: 64290
|
||||
|
||||
Package: luci-app-threat-analyst
|
||||
Version: 1.0.0-r1
|
||||
@ -829,7 +829,7 @@ Architecture: all
|
||||
Installed-Size: 51200
|
||||
Description: LuCI Threat Analyst Dashboard
|
||||
Filename: luci-app-threat-analyst_1.0.0-r1_all.ipk
|
||||
Size: 10142
|
||||
Size: 10143
|
||||
|
||||
Package: luci-app-tor
|
||||
Version: 1.0.0-r1
|
||||
@ -865,7 +865,7 @@ Architecture: all
|
||||
Installed-Size: 81920
|
||||
Description: Advanced traffic shaping with TC/CAKE for precise bandwidth control
|
||||
Filename: luci-app-traffic-shaper_0.4.0-r2_all.ipk
|
||||
Size: 14587
|
||||
Size: 14589
|
||||
|
||||
Package: luci-app-vhost-manager
|
||||
Version: 0.5.0-r5
|
||||
@ -877,7 +877,7 @@ Architecture: all
|
||||
Installed-Size: 153600
|
||||
Description: Nginx reverse proxy manager with Let's Encrypt SSL certificates, authentication, and WebSocket support
|
||||
Filename: luci-app-vhost-manager_0.5.0-r5_all.ipk
|
||||
Size: 26278
|
||||
Size: 26282
|
||||
|
||||
Package: luci-app-voip
|
||||
Version: 1.0.0-r1
|
||||
@ -889,7 +889,7 @@ Architecture: all
|
||||
Installed-Size: 81920
|
||||
Description: LuCI VoIP PBX Management
|
||||
Filename: luci-app-voip_1.0.0-r1_all.ipk
|
||||
Size: 11040
|
||||
Size: 11048
|
||||
|
||||
Package: luci-app-vortex-dns
|
||||
Version: 1.0.0-r1
|
||||
@ -901,7 +901,7 @@ Architecture: all
|
||||
Installed-Size: 40960
|
||||
Description: LuCI Vortex DNS Dashboard
|
||||
Filename: luci-app-vortex-dns_1.0.0-r1_all.ipk
|
||||
Size: 6074
|
||||
Size: 6080
|
||||
|
||||
Package: luci-app-vortex-firewall
|
||||
Version: 1.0.0-r1
|
||||
@ -913,7 +913,7 @@ Architecture: all
|
||||
Installed-Size: 30720
|
||||
Description: LuCI Vortex DNS Firewall Dashboard
|
||||
Filename: luci-app-vortex-firewall_1.0.0-r1_all.ipk
|
||||
Size: 5452
|
||||
Size: 5453
|
||||
|
||||
Package: luci-app-wazuh
|
||||
Version: 1.0.0-r1
|
||||
@ -924,7 +924,7 @@ Architecture: all
|
||||
Installed-Size: 71680
|
||||
Description: Unified security monitoring dashboard for Wazuh SIEM/XDR integration
|
||||
Filename: luci-app-wazuh_1.0.0-r1_all.ipk
|
||||
Size: 11068
|
||||
Size: 11072
|
||||
|
||||
Package: luci-app-wireguard-dashboard
|
||||
Version: 0.7.0-r5
|
||||
@ -936,7 +936,7 @@ Architecture: all
|
||||
Installed-Size: 215040
|
||||
Description: Modern dashboard for WireGuard VPN monitoring on OpenWrt
|
||||
Filename: luci-app-wireguard-dashboard_0.7.0-r5_all.ipk
|
||||
Size: 42284
|
||||
Size: 42285
|
||||
|
||||
Package: luci-app-zigbee2mqtt
|
||||
Version: 1.0.0-r2
|
||||
@ -960,7 +960,7 @@ Architecture: all
|
||||
Installed-Size: 491520
|
||||
Description: Global CyberMood design system (CSS/JS/i18n) shared by all SecuBox dashboards.
|
||||
Filename: luci-theme-secubox_0.4.8-r1_all.ipk
|
||||
Size: 121588
|
||||
Size: 121590
|
||||
|
||||
Package: secubox-ai-gateway
|
||||
Version: 1.0.0-r1
|
||||
@ -985,7 +985,7 @@ Description: SecuBox AI Gateway implements the Data Classifier (Sovereignty Eng
|
||||
|
||||
All cloud providers are opt-in. Local tier always active.
|
||||
Filename: secubox-ai-gateway_1.0.0-r1_all.ipk
|
||||
Size: 13665
|
||||
Size: 13662
|
||||
|
||||
Package: secubox-app
|
||||
Version: 1.0.0-r2
|
||||
@ -996,7 +996,7 @@ Installed-Size: 92160
|
||||
Description: Command line helper for SecuBox App Store manifests. Installs /usr/sbin/secubox-app
|
||||
and ships the default manifests under /usr/share/secubox/plugins/.
|
||||
Filename: secubox-app_1.0.0-r2_all.ipk
|
||||
Size: 11185
|
||||
Size: 11186
|
||||
|
||||
Package: secubox-app-adguardhome
|
||||
Version: 1.0.0-r2
|
||||
@ -1010,7 +1010,7 @@ Description: Installer, configuration, and service manager for running AdGuard
|
||||
inside Docker on SecuBox-powered OpenWrt systems. Network-wide ad blocker
|
||||
with DNS-over-HTTPS/TLS support and detailed analytics.
|
||||
Filename: secubox-app-adguardhome_1.0.0-r2_all.ipk
|
||||
Size: 2881
|
||||
Size: 2882
|
||||
|
||||
Package: secubox-app-auth-logger
|
||||
Version: 1.2.2-r1
|
||||
@ -1028,7 +1028,7 @@ Description: Logs authentication failures from LuCI/rpcd and Dropbear SSH
|
||||
- JavaScript hook to intercept login failures
|
||||
- CrowdSec parser and bruteforce scenario
|
||||
Filename: secubox-app-auth-logger_1.2.2-r1_all.ipk
|
||||
Size: 9371
|
||||
Size: 9376
|
||||
|
||||
Package: secubox-app-crowdsec-custom
|
||||
Version: 1.1.0-r1
|
||||
@ -1053,7 +1053,7 @@ Description: Custom CrowdSec configurations for SecuBox web interface protectio
|
||||
- Insider WAF: LAN threat detection (C2, exfiltration, lateral movement)
|
||||
- Whitelist for trusted networks
|
||||
Filename: secubox-app-crowdsec-custom_1.1.0-r1_all.ipk
|
||||
Size: 6946
|
||||
Size: 6942
|
||||
|
||||
Package: secubox-app-cs-firewall-bouncer
|
||||
Version: 0.0.31-r4
|
||||
@ -1080,7 +1080,7 @@ Description: SecuBox CrowdSec Firewall Bouncer for OpenWrt.
|
||||
- Automatic restart on firewall reload
|
||||
- procd service management
|
||||
Filename: secubox-app-cs-firewall-bouncer_0.0.31-r4_aarch64_cortex-a72.ipk
|
||||
Size: 5049324
|
||||
Size: 5049323
|
||||
|
||||
Package: secubox-app-cyberfeed
|
||||
Version: 0.2.1-r1
|
||||
@ -1094,7 +1094,7 @@ Description: Cyberpunk-themed RSS feed aggregator for OpenWrt/SecuBox.
|
||||
Features emoji injection, neon styling, and RSS-Bridge support
|
||||
for social media feeds (Facebook, Twitter, Mastodon).
|
||||
Filename: secubox-app-cyberfeed_0.2.1-r1_all.ipk
|
||||
Size: 12450
|
||||
Size: 12449
|
||||
|
||||
Package: secubox-app-device-intel
|
||||
Version: 1.0.0-r1
|
||||
@ -1108,7 +1108,7 @@ Description: Unified device inventory aggregating mac-guardian, client-guardian
|
||||
P2P mesh, and exposure scanner data. Includes heuristic classification
|
||||
and pluggable emulator modules for MQTT, Zigbee, and USB devices.
|
||||
Filename: secubox-app-device-intel_1.0.0-r1_all.ipk
|
||||
Size: 13098
|
||||
Size: 13101
|
||||
|
||||
Package: secubox-app-dns-provider
|
||||
Version: 1.0.0-r1
|
||||
@ -1122,7 +1122,7 @@ Description: Programmatic DNS record management via provider APIs (OVH, Gandi
|
||||
Cloudflare). Provides the dnsctl CLI for record CRUD, zone sync
|
||||
DNS propagation verification, and ACME DNS-01 challenge support.
|
||||
Filename: secubox-app-dns-provider_1.0.0-r1_all.ipk
|
||||
Size: 8258
|
||||
Size: 8259
|
||||
|
||||
Package: secubox-app-domoticz
|
||||
Version: 1.0.0-r4
|
||||
@ -1135,7 +1135,7 @@ Installed-Size: 30720
|
||||
Description: Installer, configuration, and service manager for running Domoticz
|
||||
inside an LXC Alpine container on SecuBox-powered OpenWrt systems.
|
||||
Filename: secubox-app-domoticz_1.0.0-r4_all.ipk
|
||||
Size: 7513
|
||||
Size: 7508
|
||||
|
||||
Package: secubox-app-exposure
|
||||
Version: 1.0.0-r1
|
||||
@ -1173,7 +1173,7 @@ Description: Gitea Git Platform - Self-hosted lightweight Git service
|
||||
Runs in LXC container with Alpine Linux.
|
||||
Configure in /etc/config/gitea.
|
||||
Filename: secubox-app-gitea_1.0.0-r5_all.ipk
|
||||
Size: 9436
|
||||
Size: 9435
|
||||
|
||||
Package: secubox-app-gk2hub
|
||||
Version: 0.1.0-r1
|
||||
@ -1187,7 +1187,7 @@ Description: Dynamic landing page generator for GK2 SecuBox services.
|
||||
Aggregates Streamlit apps, MetaBlogizer sites, and infrastructure
|
||||
services into a single service directory page.
|
||||
Filename: secubox-app-gk2hub_0.1.0-r1_all.ipk
|
||||
Size: 4060
|
||||
Size: 4061
|
||||
|
||||
Package: secubox-app-glances
|
||||
Version: 1.0.0-r1
|
||||
@ -1210,7 +1210,7 @@ Description: Glances - Cross-platform system monitoring tool for SecuBox.
|
||||
Runs in LXC container for isolation and security.
|
||||
Configure in /etc/config/glances.
|
||||
Filename: secubox-app-glances_1.0.0-r1_all.ipk
|
||||
Size: 6142
|
||||
Size: 6137
|
||||
|
||||
Package: secubox-app-guacamole
|
||||
Version: 1.0.0-r1
|
||||
@ -1224,7 +1224,7 @@ Description: Apache Guacamole clientless remote desktop gateway.
|
||||
Runs in an LXC Debian container with guacd and Tomcat.
|
||||
Supports SSH, VNC, and RDP connections via web browser.
|
||||
Filename: secubox-app-guacamole_1.0.0-r1_all.ipk
|
||||
Size: 6942
|
||||
Size: 6941
|
||||
|
||||
Package: secubox-app-haproxy
|
||||
Version: 1.0.0-r24
|
||||
@ -1268,7 +1268,7 @@ Description: Hexo CMS - Self-hosted static blog generator for OpenWrt
|
||||
Runs in LXC container with Alpine Linux.
|
||||
Configure in /etc/config/hexojs.
|
||||
Filename: secubox-app-hexojs_1.0.0-r8_all.ipk
|
||||
Size: 100054
|
||||
Size: 100059
|
||||
|
||||
Package: secubox-app-ipblocklist
|
||||
Version: 1.0.0-r1
|
||||
@ -1283,7 +1283,7 @@ Description: Pre-emptive IP blocklist defense layer for SecuBox.
|
||||
Maintainer: Gandalf <gandalf@cybermind.fr>
|
||||
License: Apache-2.0
|
||||
Filename: secubox-app-ipblocklist_1.0.0-r1_all.ipk
|
||||
Size: 4701
|
||||
Size: 4699
|
||||
|
||||
Package: secubox-app-jabber
|
||||
Version: 1.0.0-r1
|
||||
@ -1297,7 +1297,7 @@ Description: Jabber/XMPP instant messaging server based on Prosody.
|
||||
Runs in an LXC Debian container with full XMPP support.
|
||||
Features multi-user chat (MUC), file uploads, and S2S federation.
|
||||
Filename: secubox-app-jabber_1.0.0-r1_all.ipk
|
||||
Size: 13277
|
||||
Size: 13276
|
||||
|
||||
Package: secubox-app-jellyfin
|
||||
Version: 3.0.0-r1
|
||||
@ -1310,7 +1310,7 @@ Installed-Size: 20480
|
||||
Description: Jellyfin media server running in LXC container.
|
||||
Free media server for streaming movies, TV shows, music, and photos.
|
||||
Filename: secubox-app-jellyfin_3.0.0-r1_all.ipk
|
||||
Size: 4755
|
||||
Size: 4753
|
||||
|
||||
Package: secubox-app-jitsi
|
||||
Version: 1.0.0-r1
|
||||
@ -1335,7 +1335,7 @@ Description: Jitsi Meet - Secure, fully featured video conferencing for SecuBox
|
||||
Integrates with HAProxy for SSL termination.
|
||||
Configure in /etc/config/jitsi.
|
||||
Filename: secubox-app-jitsi_1.0.0-r1_all.ipk
|
||||
Size: 8926
|
||||
Size: 8920
|
||||
|
||||
Package: secubox-app-localai
|
||||
Version: 3.9.0-r1
|
||||
@ -1401,7 +1401,7 @@ Description: Lyrion Media Server (formerly Logitech Media Server / Squeezebox S
|
||||
Auto-detects available runtime, preferring LXC for lower resource usage.
|
||||
Configure runtime in /etc/config/lyrion.
|
||||
Filename: secubox-app-lyrion_2.0.2-r1_all.ipk
|
||||
Size: 8127
|
||||
Size: 8125
|
||||
|
||||
Package: secubox-app-mac-guardian
|
||||
Version: 0.5.0-r1
|
||||
@ -1416,7 +1416,7 @@ Description: WiFi MAC address security monitor for SecuBox.
|
||||
and spoofing. Integrates with CrowdSec and provides
|
||||
real-time hostapd hotplug detection.
|
||||
Filename: secubox-app-mac-guardian_0.5.0-r1_all.ipk
|
||||
Size: 12097
|
||||
Size: 12093
|
||||
|
||||
Package: secubox-app-magicmirror2
|
||||
Version: 0.4.0-r8
|
||||
@ -1463,7 +1463,7 @@ Description: Complete email server solution using docker-mailserver for SecuBox
|
||||
|
||||
Commands: mailinaboxctl --help
|
||||
Filename: secubox-app-mailinabox_2.0.0-r1_all.ipk
|
||||
Size: 7569
|
||||
Size: 7572
|
||||
|
||||
Package: secubox-app-mailserver
|
||||
Version: 2.0.0-r1
|
||||
@ -1476,7 +1476,7 @@ Installed-Size: 20480
|
||||
Description: Postfix + Dovecot mail server running in LXC container.
|
||||
Supports IMAP/SMTP with SSL/TLS.
|
||||
Filename: secubox-app-mailserver_2.0.0-r1_all.ipk
|
||||
Size: 5704
|
||||
Size: 5694
|
||||
|
||||
Package: secubox-app-matrix
|
||||
Version: 1.0.0-r1
|
||||
@ -1490,7 +1490,7 @@ Description: Matrix homeserver based on Conduit - a lightweight, high-performan
|
||||
Matrix server written in Rust. Runs in an LXC Debian container.
|
||||
Features E2EE messaging, federation, and mesh integration.
|
||||
Filename: secubox-app-matrix_1.0.0-r1_all.ipk
|
||||
Size: 10448
|
||||
Size: 10451
|
||||
|
||||
Package: secubox-app-metabolizer
|
||||
Version: 1.0.0-r3
|
||||
@ -1511,7 +1511,7 @@ Description: Metabolizer Blog Pipeline - Integrated CMS with Git-based workflow
|
||||
|
||||
Pipeline: Edit in Streamlit -> Push to Gitea -> Build with Hexo -> Publish
|
||||
Filename: secubox-app-metabolizer_1.0.0-r3_all.ipk
|
||||
Size: 13979
|
||||
Size: 13976
|
||||
|
||||
Package: secubox-app-mitmproxy
|
||||
Version: 0.5.0-r19
|
||||
@ -1538,7 +1538,7 @@ Description: mitmproxy - Interactive HTTPS proxy for SecuBox-powered OpenWrt sy
|
||||
Runs in LXC container for isolation and security.
|
||||
Configure in /etc/config/mitmproxy.
|
||||
Filename: secubox-app-mitmproxy_0.5.0-r19_all.ipk
|
||||
Size: 22956
|
||||
Size: 22957
|
||||
|
||||
Package: secubox-app-mmpm
|
||||
Version: 0.2.0-r5
|
||||
@ -1573,7 +1573,7 @@ Description: Nextcloud file sync and collaboration platform running in a Debian
|
||||
LXC container with MariaDB, Redis, and Nginx. Features HAProxy SSL
|
||||
integration, automated backups, and KISS LuCI dashboard.
|
||||
Filename: secubox-app-nextcloud_1.0.0-r2_all.ipk
|
||||
Size: 9675
|
||||
Size: 9673
|
||||
|
||||
Package: secubox-app-ollama
|
||||
Version: 0.1.0-r1
|
||||
@ -1595,7 +1595,7 @@ Description: Ollama - Simple local LLM runtime for SecuBox-powered OpenWrt syst
|
||||
Runs in Docker/Podman container.
|
||||
Configure in /etc/config/ollama.
|
||||
Filename: secubox-app-ollama_0.1.0-r1_all.ipk
|
||||
Size: 5735
|
||||
Size: 5731
|
||||
|
||||
Package: secubox-app-picobrew
|
||||
Version: 1.0.0-r7
|
||||
@ -1617,7 +1617,19 @@ Description: PicoBrew Server - Self-hosted brewing controller for PicoBrew devi
|
||||
Runs in LXC container with Python/Flask backend.
|
||||
Configure in /etc/config/picobrew.
|
||||
Filename: secubox-app-picobrew_1.0.0-r7_all.ipk
|
||||
Size: 5539
|
||||
Size: 5537
|
||||
|
||||
Package: secubox-app-rezapp
|
||||
Version: 1.0.0-r1
|
||||
Depends: docker, lxc, lxc-common, curl, wget-ssl, jsonfilter
|
||||
Section: secubox
|
||||
Architecture: all
|
||||
Installed-Size: 40960
|
||||
Description: RezApp Forge converts Docker images to LXC containers and generates
|
||||
SecuBox addon packages. Browse Docker Hub, GHCR, and LinuxServer.io
|
||||
catalogs, convert images to LXC, and publish to the SecuBox app store.
|
||||
Filename: secubox-app-rezapp_1.0.0-r1_all.ipk
|
||||
Size: 8625
|
||||
|
||||
Package: secubox-app-rustdesk
|
||||
Version: 1.0.0-r1
|
||||
@ -1630,7 +1642,7 @@ Installed-Size: 20480
|
||||
Description: Self-hosted RustDesk relay server for remote desktop access.
|
||||
Downloads and manages hbbs (ID server) and hbbr (relay server) binaries.
|
||||
Filename: secubox-app-rustdesk_1.0.0-r1_all.ipk
|
||||
Size: 4463
|
||||
Size: 4461
|
||||
|
||||
Package: secubox-app-simplex
|
||||
Version: 1.0.0-r1
|
||||
@ -1695,7 +1707,20 @@ Description: Streamlit App Platform - Self-hosted Python data app platform
|
||||
|
||||
Configure in /etc/config/streamlit.
|
||||
Filename: secubox-app-streamlit_1.0.0-r5_all.ipk
|
||||
Size: 16514
|
||||
Size: 16512
|
||||
|
||||
Package: secubox-app-streamlit-forge
|
||||
Version: 1.0.0-r1
|
||||
Depends: python3, python3-pip, lxc, lxc-common, curl, wget-ssl, jsonfilter
|
||||
Section: secubox
|
||||
Architecture: all
|
||||
Installed-Size: 51200
|
||||
Description: Streamlit Forge is a comprehensive platform for creating, managing
|
||||
and publishing Streamlit applications. Features include Gitea source
|
||||
management, preview generation, UCI configuration sync, and mesh
|
||||
appstore publishing.
|
||||
Filename: secubox-app-streamlit-forge_1.0.0-r1_all.ipk
|
||||
Size: 10814
|
||||
|
||||
Package: secubox-app-tor
|
||||
Version: 1.0.0-r1
|
||||
@ -1718,7 +1743,7 @@ Description: SecuBox Tor Shield - One-click Tor anonymization for OpenWrt
|
||||
|
||||
Configure in /etc/config/tor-shield.
|
||||
Filename: secubox-app-tor_1.0.0-r1_all.ipk
|
||||
Size: 7367
|
||||
Size: 7369
|
||||
|
||||
Package: secubox-app-voip
|
||||
Version: 1.0.0-r1
|
||||
@ -1732,7 +1757,7 @@ Description: VoIP PBX solution with Asterisk in LXC container.
|
||||
Features OVH SIP trunk integration, WebRTC support
|
||||
and Jabber/XMPP relay for SMS and voicemail notifications.
|
||||
Filename: secubox-app-voip_1.0.0-r1_all.ipk
|
||||
Size: 11955
|
||||
Size: 11951
|
||||
|
||||
Package: secubox-app-webapp
|
||||
Version: 1.5.0-r7
|
||||
@ -1763,7 +1788,7 @@ Installed-Size: 20480
|
||||
Description: Installer, configuration, and service manager for running Zigbee2MQTT
|
||||
inside an Alpine LXC container on SecuBox-powered OpenWrt systems.
|
||||
Filename: secubox-app-zigbee2mqtt_1.0.0-r3_all.ipk
|
||||
Size: 5539
|
||||
Size: 5540
|
||||
|
||||
Package: secubox-config-advisor
|
||||
Version: 0.1.0-r1
|
||||
@ -1782,7 +1807,7 @@ Description: AI-powered configuration security advisor for SecuBox.
|
||||
- LocalAI integration for intelligent analysis
|
||||
- Automated remediation suggestions
|
||||
Filename: secubox-config-advisor_0.1.0-r1_all.ipk
|
||||
Size: 14847
|
||||
Size: 14842
|
||||
|
||||
Package: secubox-content-pkg
|
||||
Version: 1.0.0-r1
|
||||
@ -1795,7 +1820,7 @@ Installed-Size: 20480
|
||||
Description: Package Metablogizer sites and Streamlit apps as IPKs for P2P distribution.
|
||||
Auto-publishes content to the mesh feed for peer auto-sync.
|
||||
Filename: secubox-content-pkg_1.0.0-r1_all.ipk
|
||||
Size: 3909
|
||||
Size: 3907
|
||||
|
||||
Package: secubox-cookie-tracker
|
||||
Version: 1.0.0-r1
|
||||
@ -1818,7 +1843,7 @@ Description: Cookie Tracker for SecuBox InterceptoR.
|
||||
|
||||
Works with secubox-app-mitmproxy for transparent interception.
|
||||
Filename: secubox-cookie-tracker_1.0.0-r1_all.ipk
|
||||
Size: 10643
|
||||
Size: 10639
|
||||
|
||||
Package: secubox-core
|
||||
Version: 0.10.0-r16
|
||||
@ -1838,7 +1863,7 @@ Description: SecuBox Core Framework provides the foundational infrastructure fo
|
||||
- Unified CLI interface
|
||||
- ubus RPC backend
|
||||
Filename: secubox-core_0.10.0-r16_all.ipk
|
||||
Size: 127204
|
||||
Size: 127202
|
||||
|
||||
Package: secubox-cve-triage
|
||||
Version: 1.0.0-r1
|
||||
@ -1858,7 +1883,7 @@ Description: AI-powered CVE analysis and vulnerability management agent for Sec
|
||||
- Approval workflow for patch recommendations
|
||||
- LXC and Docker package monitoring
|
||||
Filename: secubox-cve-triage_1.0.0-r1_all.ipk
|
||||
Size: 11829
|
||||
Size: 11826
|
||||
|
||||
Package: secubox-dns-guard
|
||||
Version: 1.0.0-r1
|
||||
@ -1877,7 +1902,7 @@ Description: SecuBox DNS Guard provides AI-powered DNS anomaly detection using
|
||||
- Unusual TLD pattern detection
|
||||
- Automatic blocklist generation with approval workflow
|
||||
Filename: secubox-dns-guard_1.0.0-r1_all.ipk
|
||||
Size: 12482
|
||||
Size: 12480
|
||||
|
||||
Package: secubox-identity
|
||||
Version: 0.1.0-r1
|
||||
@ -1896,7 +1921,7 @@ Description: Decentralized identity management for SecuBox mesh nodes.
|
||||
- Peer identity verification
|
||||
- Trust scoring integration
|
||||
Filename: secubox-identity_0.1.0-r1_all.ipk
|
||||
Size: 8090
|
||||
Size: 8089
|
||||
|
||||
Package: secubox-iot-guard
|
||||
Version: 1.0.0-r1
|
||||
@ -1912,7 +1937,7 @@ Description: IoT device isolation, classification, and security monitoring.
|
||||
risk scoring. Orchestrates Client Guardian, MAC Guardian
|
||||
Vortex Firewall, and Bandwidth Manager for IoT protection.
|
||||
Filename: secubox-iot-guard_1.0.0-r1_all.ipk
|
||||
Size: 13363
|
||||
Size: 13370
|
||||
|
||||
Package: secubox-localrecall
|
||||
Version: 1.0.0-r1
|
||||
@ -1927,7 +1952,7 @@ Description: Persistent memory system for SecuBox AI agents.
|
||||
for context across sessions. LocalAI integration for
|
||||
semantic search and AI-powered summarization.
|
||||
Filename: secubox-localrecall_1.0.0-r1_all.ipk
|
||||
Size: 7793
|
||||
Size: 7798
|
||||
|
||||
Package: secubox-master-link
|
||||
Version: 1.0.0-r1
|
||||
@ -1949,7 +1974,7 @@ Description: Secure mesh onboarding for SecuBox nodes via master/peer link.
|
||||
|
||||
Configure in /etc/config/master-link.
|
||||
Filename: secubox-master-link_1.0.0-r1_all.ipk
|
||||
Size: 15034
|
||||
Size: 15036
|
||||
|
||||
Package: secubox-mcp-server
|
||||
Version: 1.0.0-r1
|
||||
@ -1977,7 +2002,7 @@ Description: Model Context Protocol (MCP) server for SecuBox.
|
||||
- ai.explain_ban (Explain CrowdSec decisions)
|
||||
- ai.security_posture (Security assessment)
|
||||
Filename: secubox-mcp-server_1.0.0-r1_all.ipk
|
||||
Size: 11428
|
||||
Size: 11427
|
||||
|
||||
Package: secubox-mirrornet
|
||||
Version: 0.1.0-r1
|
||||
@ -1995,7 +2020,7 @@ Description: MirrorNet core mesh orchestration for SecuBox.
|
||||
- Mesh health monitoring and anomaly detection
|
||||
- DID-based identity (did:plc compatible)
|
||||
Filename: secubox-mirrornet_0.1.0-r1_all.ipk
|
||||
Size: 15305
|
||||
Size: 15303
|
||||
|
||||
Package: secubox-network-anomaly
|
||||
Version: 1.0.0-r1
|
||||
@ -2067,7 +2092,7 @@ Description: Autonomous threat analysis agent for SecuBox.
|
||||
|
||||
Part of SecuBox AI Gateway (Couche 2).
|
||||
Filename: secubox-threat-analyst_1.0.0-r1_all.ipk
|
||||
Size: 9866
|
||||
Size: 9865
|
||||
|
||||
Package: secubox-vortex-dns
|
||||
Version: 1.0.0-r1
|
||||
@ -2086,7 +2111,7 @@ Description: Meshed multi-dynamic subdomain delegation system for SecuBox.
|
||||
- Gossip-based exposure config sync
|
||||
- Submastering for nested hierarchies
|
||||
Filename: secubox-vortex-dns_1.0.0-r1_all.ipk
|
||||
Size: 5439
|
||||
Size: 5441
|
||||
|
||||
Package: secubox-vortex-firewall
|
||||
Version: 1.0.0-r1
|
||||
|
||||
Binary file not shown.
@ -1,12 +1,12 @@
|
||||
{
|
||||
"feed_url": "/secubox-feed",
|
||||
"generated": "2026-03-04T07:36:19+01:00",
|
||||
"generated": "2026-03-11T08:34:40+01:00",
|
||||
"packages": [
|
||||
{
|
||||
"name": "luci-app-ai-gateway",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-ai-gateway_1.0.0-r1_all.ipk",
|
||||
"size": 10787,
|
||||
"size": 10789,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -18,7 +18,7 @@
|
||||
"name": "luci-app-ai-insights",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-ai-insights_1.0.0-r1_all.ipk",
|
||||
"size": 11635,
|
||||
"size": 11638,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -30,7 +30,7 @@
|
||||
"name": "luci-app-auth-guardian",
|
||||
"version": "0.4.0-r3",
|
||||
"filename": "luci-app-auth-guardian_0.4.0-r3_all.ipk",
|
||||
"size": 12393,
|
||||
"size": 12391,
|
||||
"category": "security",
|
||||
"icon": "key",
|
||||
"description": "Authentication management",
|
||||
@ -42,7 +42,7 @@
|
||||
"name": "luci-app-backup",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-backup_1.0.0-r1_all.ipk",
|
||||
"size": 4535,
|
||||
"size": 4532,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -54,7 +54,7 @@
|
||||
"name": "luci-app-bandwidth-manager",
|
||||
"version": "0.5.0-r2",
|
||||
"filename": "luci-app-bandwidth-manager_0.5.0-r2_all.ipk",
|
||||
"size": 61684,
|
||||
"size": 61683,
|
||||
"category": "network",
|
||||
"icon": "activity",
|
||||
"description": "Bandwidth monitoring and control",
|
||||
@ -66,7 +66,7 @@
|
||||
"name": "luci-app-cdn-cache",
|
||||
"version": "0.5.0-r3",
|
||||
"filename": "luci-app-cdn-cache_0.5.0-r3_all.ipk",
|
||||
"size": 24252,
|
||||
"size": 24256,
|
||||
"category": "network",
|
||||
"icon": "globe",
|
||||
"description": "CDN caching",
|
||||
@ -78,7 +78,7 @@
|
||||
"name": "luci-app-client-guardian",
|
||||
"version": "0.4.0-r7",
|
||||
"filename": "luci-app-client-guardian_0.4.0-r7_all.ipk",
|
||||
"size": 52682,
|
||||
"size": 52687,
|
||||
"category": "network",
|
||||
"icon": "users",
|
||||
"description": "Client management and monitoring",
|
||||
@ -90,7 +90,7 @@
|
||||
"name": "luci-app-cloner",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-cloner_1.0.0-r1_all.ipk",
|
||||
"size": 19431,
|
||||
"size": 19434,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -102,7 +102,7 @@
|
||||
"name": "luci-app-config-advisor",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-config-advisor_1.0.0-r1_all.ipk",
|
||||
"size": 8858,
|
||||
"size": 8857,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -114,7 +114,7 @@
|
||||
"name": "luci-app-cookie-tracker",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-cookie-tracker_1.0.0-r1_all.ipk",
|
||||
"size": 5657,
|
||||
"size": 5655,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -138,7 +138,7 @@
|
||||
"name": "luci-app-cve-triage",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-cve-triage_1.0.0-r1_all.ipk",
|
||||
"size": 5942,
|
||||
"size": 5941,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -150,7 +150,7 @@
|
||||
"name": "luci-app-cyberfeed",
|
||||
"version": "0.1.1-r1",
|
||||
"filename": "luci-app-cyberfeed_0.1.1-r1_all.ipk",
|
||||
"size": 12884,
|
||||
"size": 12882,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -174,7 +174,7 @@
|
||||
"name": "luci-app-dnsguard",
|
||||
"version": "1.1.0-r1",
|
||||
"filename": "luci-app-dnsguard_1.1.0-r1_all.ipk",
|
||||
"size": 12446,
|
||||
"size": 12449,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -186,7 +186,7 @@
|
||||
"name": "luci-app-dns-provider",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-dns-provider_1.0.0-r1_all.ipk",
|
||||
"size": 7166,
|
||||
"size": 7167,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -198,7 +198,7 @@
|
||||
"name": "luci-app-domoticz",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-domoticz_1.0.0-r1_all.ipk",
|
||||
"size": 7122,
|
||||
"size": 7123,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -210,7 +210,7 @@
|
||||
"name": "luci-app-exposure",
|
||||
"version": "1.0.0-r3",
|
||||
"filename": "luci-app-exposure_1.0.0-r3_all.ipk",
|
||||
"size": 11699,
|
||||
"size": 11695,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -222,7 +222,7 @@
|
||||
"name": "luci-app-gitea",
|
||||
"version": "1.0.0-r2",
|
||||
"filename": "luci-app-gitea_1.0.0-r2_all.ipk",
|
||||
"size": 16620,
|
||||
"size": 16621,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -234,7 +234,7 @@
|
||||
"name": "luci-app-glances",
|
||||
"version": "1.0.0-r2",
|
||||
"filename": "luci-app-glances_1.0.0-r2_all.ipk",
|
||||
"size": 7017,
|
||||
"size": 7015,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -246,7 +246,7 @@
|
||||
"name": "luci-app-gotosocial",
|
||||
"version": "0.1.0-r1",
|
||||
"filename": "luci-app-gotosocial_0.1.0-r1_all.ipk",
|
||||
"size": 8208,
|
||||
"size": 8206,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -258,7 +258,7 @@
|
||||
"name": "luci-app-haproxy",
|
||||
"version": "1.0.0-r8",
|
||||
"filename": "luci-app-haproxy_1.0.0-r8_all.ipk",
|
||||
"size": 35342,
|
||||
"size": 35339,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -270,7 +270,7 @@
|
||||
"name": "luci-app-hexojs",
|
||||
"version": "1.0.0-r3",
|
||||
"filename": "luci-app-hexojs_1.0.0-r3_all.ipk",
|
||||
"size": 30451,
|
||||
"size": 30453,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -282,7 +282,7 @@
|
||||
"name": "luci-app-iot-guard",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-iot-guard_1.0.0-r1_all.ipk",
|
||||
"size": 10535,
|
||||
"size": 10533,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -294,7 +294,7 @@
|
||||
"name": "luci-app-ipblocklist",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-ipblocklist_1.0.0-r1_all.ipk",
|
||||
"size": 6528,
|
||||
"size": 6529,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -306,7 +306,7 @@
|
||||
"name": "luci-app-jabber",
|
||||
"version": "0",
|
||||
"filename": "luci-app-jabber_0_all.ipk",
|
||||
"size": 9308,
|
||||
"size": 9311,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -318,7 +318,7 @@
|
||||
"name": "luci-app-jellyfin",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-jellyfin_1.0.0-r1_all.ipk",
|
||||
"size": 10486,
|
||||
"size": 10483,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -330,7 +330,7 @@
|
||||
"name": "luci-app-jitsi",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-jitsi_1.0.0-r1_all.ipk",
|
||||
"size": 5175,
|
||||
"size": 5173,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -342,7 +342,7 @@
|
||||
"name": "luci-app-ksm-manager",
|
||||
"version": "0.4.0-r2",
|
||||
"filename": "luci-app-ksm-manager_0.4.0-r2_all.ipk",
|
||||
"size": 18778,
|
||||
"size": 18780,
|
||||
"category": "system",
|
||||
"icon": "cpu",
|
||||
"description": "Kernel memory management",
|
||||
@ -366,7 +366,7 @@
|
||||
"name": "luci-app-localrecall",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-localrecall_1.0.0-r1_all.ipk",
|
||||
"size": 8415,
|
||||
"size": 8413,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -378,7 +378,7 @@
|
||||
"name": "luci-app-lyrion",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-lyrion_1.0.0-r1_all.ipk",
|
||||
"size": 6841,
|
||||
"size": 6837,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -390,7 +390,7 @@
|
||||
"name": "luci-app-mac-guardian",
|
||||
"version": "0.5.0-r1",
|
||||
"filename": "luci-app-mac-guardian_0.5.0-r1_all.ipk",
|
||||
"size": 6660,
|
||||
"size": 6667,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -402,7 +402,7 @@
|
||||
"name": "luci-app-magicmirror2",
|
||||
"version": "0.4.0-r6",
|
||||
"filename": "luci-app-magicmirror2_0.4.0-r6_all.ipk",
|
||||
"size": 12359,
|
||||
"size": 12358,
|
||||
"category": "iot",
|
||||
"icon": "monitor",
|
||||
"description": "Smart mirror display",
|
||||
@ -414,7 +414,7 @@
|
||||
"name": "luci-app-mailinabox",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-mailinabox_1.0.0-r1_all.ipk",
|
||||
"size": 5484,
|
||||
"size": 5482,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -426,7 +426,7 @@
|
||||
"name": "luci-app-mailserver",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-mailserver_1.0.0-r1_all.ipk",
|
||||
"size": 6515,
|
||||
"size": 6510,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -438,7 +438,7 @@
|
||||
"name": "luci-app-master-link",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-master-link_1.0.0-r1_all.ipk",
|
||||
"size": 6305,
|
||||
"size": 6309,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -450,7 +450,7 @@
|
||||
"name": "luci-app-matrix",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-matrix_1.0.0-r1_all.ipk",
|
||||
"size": 7524,
|
||||
"size": 7518,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -462,7 +462,7 @@
|
||||
"name": "luci-app-media-flow",
|
||||
"version": "0.6.4-r1",
|
||||
"filename": "luci-app-media-flow_0.6.4-r1_all.ipk",
|
||||
"size": 25380,
|
||||
"size": 25379,
|
||||
"category": "media",
|
||||
"icon": "film",
|
||||
"description": "Media streaming",
|
||||
@ -474,7 +474,7 @@
|
||||
"name": "luci-app-metablogizer",
|
||||
"version": "1.1.0-r1",
|
||||
"filename": "luci-app-metablogizer_1.1.0-r1_all.ipk",
|
||||
"size": 26205,
|
||||
"size": 26203,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -486,7 +486,7 @@
|
||||
"name": "luci-app-metabolizer",
|
||||
"version": "1.0.0-r2",
|
||||
"filename": "luci-app-metabolizer_1.0.0-r2_all.ipk",
|
||||
"size": 4825,
|
||||
"size": 4822,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -510,7 +510,7 @@
|
||||
"name": "luci-app-mmpm",
|
||||
"version": "0.2.0-r3",
|
||||
"filename": "luci-app-mmpm_0.2.0-r3_all.ipk",
|
||||
"size": 7969,
|
||||
"size": 7968,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -522,7 +522,7 @@
|
||||
"name": "luci-app-mqtt-bridge",
|
||||
"version": "0.4.0-r4",
|
||||
"filename": "luci-app-mqtt-bridge_0.4.0-r4_all.ipk",
|
||||
"size": 22691,
|
||||
"size": 22688,
|
||||
"category": "iot",
|
||||
"icon": "message-square",
|
||||
"description": "MQTT bridge",
|
||||
@ -558,7 +558,7 @@
|
||||
"name": "luci-app-network-anomaly",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-network-anomaly_1.0.0-r1_all.ipk",
|
||||
"size": 7646,
|
||||
"size": 7641,
|
||||
"category": "network",
|
||||
"icon": "wifi",
|
||||
"description": "Network configuration",
|
||||
@ -570,7 +570,7 @@
|
||||
"name": "luci-app-network-modes",
|
||||
"version": "0.5.0-r3",
|
||||
"filename": "luci-app-network-modes_0.5.0-r3_all.ipk",
|
||||
"size": 54227,
|
||||
"size": 54225,
|
||||
"category": "network",
|
||||
"icon": "wifi",
|
||||
"description": "Network configuration",
|
||||
@ -582,7 +582,7 @@
|
||||
"name": "luci-app-network-tweaks",
|
||||
"version": "1.0.0-r7",
|
||||
"filename": "luci-app-network-tweaks_1.0.0-r7_all.ipk",
|
||||
"size": 15947,
|
||||
"size": 15943,
|
||||
"category": "network",
|
||||
"icon": "wifi",
|
||||
"description": "Network configuration",
|
||||
@ -594,7 +594,7 @@
|
||||
"name": "luci-app-nextcloud",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-nextcloud_1.0.0-r1_all.ipk",
|
||||
"size": 10351,
|
||||
"size": 10347,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -606,7 +606,7 @@
|
||||
"name": "luci-app-ollama",
|
||||
"version": "0.1.0-r1",
|
||||
"filename": "luci-app-ollama_0.1.0-r1_all.ipk",
|
||||
"size": 14333,
|
||||
"size": 14337,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -618,7 +618,7 @@
|
||||
"name": "luci-app-openclaw",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-openclaw_1.0.0-r1_all.ipk",
|
||||
"size": 8412,
|
||||
"size": 8409,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -630,7 +630,7 @@
|
||||
"name": "luci-app-peertube",
|
||||
"version": "0",
|
||||
"filename": "luci-app-peertube_0_all.ipk",
|
||||
"size": 5757,
|
||||
"size": 5755,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -642,7 +642,7 @@
|
||||
"name": "luci-app-picobrew",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-picobrew_1.0.0-r1_all.ipk",
|
||||
"size": 9535,
|
||||
"size": 9531,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -654,7 +654,7 @@
|
||||
"name": "luci-app-secubox",
|
||||
"version": "0.7.1-r4",
|
||||
"filename": "luci-app-secubox_0.7.1-r4_all.ipk",
|
||||
"size": 82095,
|
||||
"size": 82094,
|
||||
"category": "system",
|
||||
"icon": "box",
|
||||
"description": "SecuBox system component",
|
||||
@ -678,7 +678,7 @@
|
||||
"name": "luci-app-secubox-crowdsec",
|
||||
"version": "1.0.0-r3",
|
||||
"filename": "luci-app-secubox-crowdsec_1.0.0-r3_all.ipk",
|
||||
"size": 13916,
|
||||
"size": 13921,
|
||||
"category": "system",
|
||||
"icon": "box",
|
||||
"description": "SecuBox system component",
|
||||
@ -690,7 +690,7 @@
|
||||
"name": "luci-app-secubox-mirror",
|
||||
"version": "0.1.0-r1",
|
||||
"filename": "luci-app-secubox-mirror_0.1.0-r1_all.ipk",
|
||||
"size": 5847,
|
||||
"size": 5848,
|
||||
"category": "system",
|
||||
"icon": "box",
|
||||
"description": "SecuBox system component",
|
||||
@ -702,7 +702,7 @@
|
||||
"name": "luci-app-secubox-netdiag",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-secubox-netdiag_1.0.0-r1_all.ipk",
|
||||
"size": 15344,
|
||||
"size": 15342,
|
||||
"category": "system",
|
||||
"icon": "box",
|
||||
"description": "SecuBox system component",
|
||||
@ -714,7 +714,7 @@
|
||||
"name": "luci-app-secubox-netifyd",
|
||||
"version": "1.2.1-r1",
|
||||
"filename": "luci-app-secubox-netifyd_1.2.1-r1_all.ipk",
|
||||
"size": 36720,
|
||||
"size": 36715,
|
||||
"category": "system",
|
||||
"icon": "box",
|
||||
"description": "SecuBox system component",
|
||||
@ -726,7 +726,7 @@
|
||||
"name": "luci-app-secubox-p2p",
|
||||
"version": "0.1.0-r1",
|
||||
"filename": "luci-app-secubox-p2p_0.1.0-r1_all.ipk",
|
||||
"size": 46832,
|
||||
"size": 46830,
|
||||
"category": "system",
|
||||
"icon": "box",
|
||||
"description": "SecuBox system component",
|
||||
@ -750,7 +750,7 @@
|
||||
"name": "luci-app-secubox-security-threats",
|
||||
"version": "1.0.0-r4",
|
||||
"filename": "luci-app-secubox-security-threats_1.0.0-r4_all.ipk",
|
||||
"size": 10656,
|
||||
"size": 10657,
|
||||
"category": "system",
|
||||
"icon": "box",
|
||||
"description": "SecuBox system component",
|
||||
@ -762,7 +762,7 @@
|
||||
"name": "luci-app-secubox-users",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-secubox-users_1.0.0-r1_all.ipk",
|
||||
"size": 5144,
|
||||
"size": 5141,
|
||||
"category": "system",
|
||||
"icon": "box",
|
||||
"description": "SecuBox system component",
|
||||
@ -774,7 +774,7 @@
|
||||
"name": "luci-app-service-registry",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-service-registry_1.0.0-r1_all.ipk",
|
||||
"size": 39952,
|
||||
"size": 39953,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -786,7 +786,7 @@
|
||||
"name": "luci-app-simplex",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-simplex_1.0.0-r1_all.ipk",
|
||||
"size": 7035,
|
||||
"size": 7033,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -798,7 +798,7 @@
|
||||
"name": "luci-app-streamlit",
|
||||
"version": "1.0.0-r11",
|
||||
"filename": "luci-app-streamlit_1.0.0-r11_all.ipk",
|
||||
"size": 20565,
|
||||
"size": 20567,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -810,7 +810,7 @@
|
||||
"name": "luci-app-system-hub",
|
||||
"version": "0.5.2-r2",
|
||||
"filename": "luci-app-system-hub_0.5.2-r2_all.ipk",
|
||||
"size": 64292,
|
||||
"size": 64290,
|
||||
"category": "system",
|
||||
"icon": "settings",
|
||||
"description": "System management",
|
||||
@ -822,7 +822,7 @@
|
||||
"name": "luci-app-threat-analyst",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-threat-analyst_1.0.0-r1_all.ipk",
|
||||
"size": 10142,
|
||||
"size": 10143,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -858,7 +858,7 @@
|
||||
"name": "luci-app-traffic-shaper",
|
||||
"version": "0.4.0-r2",
|
||||
"filename": "luci-app-traffic-shaper_0.4.0-r2_all.ipk",
|
||||
"size": 14587,
|
||||
"size": 14589,
|
||||
"category": "network",
|
||||
"icon": "filter",
|
||||
"description": "Traffic shaping and QoS",
|
||||
@ -870,7 +870,7 @@
|
||||
"name": "luci-app-vhost-manager",
|
||||
"version": "0.5.0-r5",
|
||||
"filename": "luci-app-vhost-manager_0.5.0-r5_all.ipk",
|
||||
"size": 26278,
|
||||
"size": 26282,
|
||||
"category": "network",
|
||||
"icon": "server",
|
||||
"description": "Virtual host management",
|
||||
@ -882,7 +882,7 @@
|
||||
"name": "luci-app-voip",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-voip_1.0.0-r1_all.ipk",
|
||||
"size": 11040,
|
||||
"size": 11048,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -894,7 +894,7 @@
|
||||
"name": "luci-app-vortex-dns",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-vortex-dns_1.0.0-r1_all.ipk",
|
||||
"size": 6074,
|
||||
"size": 6080,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -906,7 +906,7 @@
|
||||
"name": "luci-app-vortex-firewall",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-vortex-firewall_1.0.0-r1_all.ipk",
|
||||
"size": 5452,
|
||||
"size": 5453,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -918,7 +918,7 @@
|
||||
"name": "luci-app-wazuh",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "luci-app-wazuh_1.0.0-r1_all.ipk",
|
||||
"size": 11068,
|
||||
"size": 11072,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -930,7 +930,7 @@
|
||||
"name": "luci-app-wireguard-dashboard",
|
||||
"version": "0.7.0-r5",
|
||||
"filename": "luci-app-wireguard-dashboard_0.7.0-r5_all.ipk",
|
||||
"size": 42284,
|
||||
"size": 42285,
|
||||
"category": "vpn",
|
||||
"icon": "shield",
|
||||
"description": "WireGuard VPN dashboard",
|
||||
@ -954,7 +954,7 @@
|
||||
"name": "luci-theme-secubox",
|
||||
"version": "0.4.8-r1",
|
||||
"filename": "luci-theme-secubox_0.4.8-r1_all.ipk",
|
||||
"size": 121588,
|
||||
"size": 121590,
|
||||
"category": "theme",
|
||||
"icon": "palette",
|
||||
"description": "LuCI theme",
|
||||
@ -966,7 +966,7 @@
|
||||
"name": "secubox-ai-gateway",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-ai-gateway_1.0.0-r1_all.ipk",
|
||||
"size": 13665,
|
||||
"size": 13662,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -978,7 +978,7 @@
|
||||
"name": "secubox-app",
|
||||
"version": "1.0.0-r2",
|
||||
"filename": "secubox-app_1.0.0-r2_all.ipk",
|
||||
"size": 11185,
|
||||
"size": 11186,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -990,7 +990,7 @@
|
||||
"name": "secubox-app-adguardhome",
|
||||
"version": "1.0.0-r2",
|
||||
"filename": "secubox-app-adguardhome_1.0.0-r2_all.ipk",
|
||||
"size": 2881,
|
||||
"size": 2882,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1002,7 +1002,7 @@
|
||||
"name": "secubox-app-auth-logger",
|
||||
"version": "1.2.2-r1",
|
||||
"filename": "secubox-app-auth-logger_1.2.2-r1_all.ipk",
|
||||
"size": 9371,
|
||||
"size": 9376,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1014,7 +1014,7 @@
|
||||
"name": "secubox-app-crowdsec-custom",
|
||||
"version": "1.1.0-r1",
|
||||
"filename": "secubox-app-crowdsec-custom_1.1.0-r1_all.ipk",
|
||||
"size": 6946,
|
||||
"size": 6942,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1026,7 +1026,7 @@
|
||||
"name": "secubox-app-cs-firewall-bouncer",
|
||||
"version": "0.0.31-r4_aarch64",
|
||||
"filename": "secubox-app-cs-firewall-bouncer_0.0.31-r4_aarch64_cortex-a72.ipk",
|
||||
"size": 5049324,
|
||||
"size": 5049323,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1038,7 +1038,7 @@
|
||||
"name": "secubox-app-cyberfeed",
|
||||
"version": "0.2.1-r1",
|
||||
"filename": "secubox-app-cyberfeed_0.2.1-r1_all.ipk",
|
||||
"size": 12450,
|
||||
"size": 12449,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1050,7 +1050,7 @@
|
||||
"name": "secubox-app-device-intel",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-app-device-intel_1.0.0-r1_all.ipk",
|
||||
"size": 13098,
|
||||
"size": 13101,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1062,7 +1062,7 @@
|
||||
"name": "secubox-app-dns-provider",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-app-dns-provider_1.0.0-r1_all.ipk",
|
||||
"size": 8258,
|
||||
"size": 8259,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1074,7 +1074,7 @@
|
||||
"name": "secubox-app-domoticz",
|
||||
"version": "1.0.0-r4",
|
||||
"filename": "secubox-app-domoticz_1.0.0-r4_all.ipk",
|
||||
"size": 7513,
|
||||
"size": 7508,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1098,7 +1098,7 @@
|
||||
"name": "secubox-app-gitea",
|
||||
"version": "1.0.0-r5",
|
||||
"filename": "secubox-app-gitea_1.0.0-r5_all.ipk",
|
||||
"size": 9436,
|
||||
"size": 9435,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1110,7 +1110,7 @@
|
||||
"name": "secubox-app-gk2hub",
|
||||
"version": "0.1.0-r1",
|
||||
"filename": "secubox-app-gk2hub_0.1.0-r1_all.ipk",
|
||||
"size": 4060,
|
||||
"size": 4061,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1122,7 +1122,7 @@
|
||||
"name": "secubox-app-glances",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-app-glances_1.0.0-r1_all.ipk",
|
||||
"size": 6142,
|
||||
"size": 6137,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1134,7 +1134,7 @@
|
||||
"name": "secubox-app-guacamole",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-app-guacamole_1.0.0-r1_all.ipk",
|
||||
"size": 6942,
|
||||
"size": 6941,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1158,7 +1158,7 @@
|
||||
"name": "secubox-app-hexojs",
|
||||
"version": "1.0.0-r8",
|
||||
"filename": "secubox-app-hexojs_1.0.0-r8_all.ipk",
|
||||
"size": 100054,
|
||||
"size": 100059,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1170,7 +1170,7 @@
|
||||
"name": "secubox-app-ipblocklist",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-app-ipblocklist_1.0.0-r1_all.ipk",
|
||||
"size": 4701,
|
||||
"size": 4699,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1182,7 +1182,7 @@
|
||||
"name": "secubox-app-jabber",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-app-jabber_1.0.0-r1_all.ipk",
|
||||
"size": 13277,
|
||||
"size": 13276,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1194,7 +1194,7 @@
|
||||
"name": "secubox-app-jellyfin",
|
||||
"version": "3.0.0-r1",
|
||||
"filename": "secubox-app-jellyfin_3.0.0-r1_all.ipk",
|
||||
"size": 4755,
|
||||
"size": 4753,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1206,7 +1206,7 @@
|
||||
"name": "secubox-app-jitsi",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-app-jitsi_1.0.0-r1_all.ipk",
|
||||
"size": 8926,
|
||||
"size": 8920,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1242,7 +1242,7 @@
|
||||
"name": "secubox-app-lyrion",
|
||||
"version": "2.0.2-r1",
|
||||
"filename": "secubox-app-lyrion_2.0.2-r1_all.ipk",
|
||||
"size": 8127,
|
||||
"size": 8125,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1254,7 +1254,7 @@
|
||||
"name": "secubox-app-mac-guardian",
|
||||
"version": "0.5.0-r1",
|
||||
"filename": "secubox-app-mac-guardian_0.5.0-r1_all.ipk",
|
||||
"size": 12097,
|
||||
"size": 12093,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1278,7 +1278,7 @@
|
||||
"name": "secubox-app-mailinabox",
|
||||
"version": "2.0.0-r1",
|
||||
"filename": "secubox-app-mailinabox_2.0.0-r1_all.ipk",
|
||||
"size": 7569,
|
||||
"size": 7572,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1290,7 +1290,7 @@
|
||||
"name": "secubox-app-mailserver",
|
||||
"version": "2.0.0-r1",
|
||||
"filename": "secubox-app-mailserver_2.0.0-r1_all.ipk",
|
||||
"size": 5704,
|
||||
"size": 5694,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1302,7 +1302,7 @@
|
||||
"name": "secubox-app-matrix",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-app-matrix_1.0.0-r1_all.ipk",
|
||||
"size": 10448,
|
||||
"size": 10451,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1314,7 +1314,7 @@
|
||||
"name": "secubox-app-metabolizer",
|
||||
"version": "1.0.0-r3",
|
||||
"filename": "secubox-app-metabolizer_1.0.0-r3_all.ipk",
|
||||
"size": 13979,
|
||||
"size": 13976,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1326,7 +1326,7 @@
|
||||
"name": "secubox-app-mitmproxy",
|
||||
"version": "0.5.0-r19",
|
||||
"filename": "secubox-app-mitmproxy_0.5.0-r19_all.ipk",
|
||||
"size": 22956,
|
||||
"size": 22957,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1350,7 +1350,7 @@
|
||||
"name": "secubox-app-nextcloud",
|
||||
"version": "1.0.0-r2",
|
||||
"filename": "secubox-app-nextcloud_1.0.0-r2_all.ipk",
|
||||
"size": 9675,
|
||||
"size": 9673,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1362,7 +1362,7 @@
|
||||
"name": "secubox-app-ollama",
|
||||
"version": "0.1.0-r1",
|
||||
"filename": "secubox-app-ollama_0.1.0-r1_all.ipk",
|
||||
"size": 5735,
|
||||
"size": 5731,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1374,19 +1374,31 @@
|
||||
"name": "secubox-app-picobrew",
|
||||
"version": "1.0.0-r7",
|
||||
"filename": "secubox-app-picobrew_1.0.0-r7_all.ipk",
|
||||
"size": 5539,
|
||||
"size": 5537,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
"installed": false,
|
||||
"luci_app": "luci-app-picobrew"
|
||||
}
|
||||
,
|
||||
{
|
||||
"name": "secubox-app-rezapp",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-app-rezapp_1.0.0-r1_all.ipk",
|
||||
"size": 8625,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
"installed": false,
|
||||
"luci_app": "luci-app-rezapp"
|
||||
}
|
||||
,
|
||||
{
|
||||
"name": "secubox-app-rustdesk",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-app-rustdesk_1.0.0-r1_all.ipk",
|
||||
"size": 4463,
|
||||
"size": 4461,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1422,19 +1434,31 @@
|
||||
"name": "secubox-app-streamlit",
|
||||
"version": "1.0.0-r5",
|
||||
"filename": "secubox-app-streamlit_1.0.0-r5_all.ipk",
|
||||
"size": 16514,
|
||||
"size": 16512,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
"installed": false,
|
||||
"luci_app": "luci-app-streamlit"
|
||||
}
|
||||
,
|
||||
{
|
||||
"name": "secubox-app-streamlit-forge",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-app-streamlit-forge_1.0.0-r1_all.ipk",
|
||||
"size": 10814,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
"installed": false,
|
||||
"luci_app": "luci-app-streamlit-forge"
|
||||
}
|
||||
,
|
||||
{
|
||||
"name": "secubox-app-tor",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-app-tor_1.0.0-r1_all.ipk",
|
||||
"size": 7367,
|
||||
"size": 7369,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1446,7 +1470,7 @@
|
||||
"name": "secubox-app-voip",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-app-voip_1.0.0-r1_all.ipk",
|
||||
"size": 11955,
|
||||
"size": 11951,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1470,7 +1494,7 @@
|
||||
"name": "secubox-app-zigbee2mqtt",
|
||||
"version": "1.0.0-r3",
|
||||
"filename": "secubox-app-zigbee2mqtt_1.0.0-r3_all.ipk",
|
||||
"size": 5539,
|
||||
"size": 5540,
|
||||
"category": "secubox",
|
||||
"icon": "package",
|
||||
"description": "SecuBox backend service",
|
||||
@ -1482,7 +1506,7 @@
|
||||
"name": "secubox-config-advisor",
|
||||
"version": "0.1.0-r1",
|
||||
"filename": "secubox-config-advisor_0.1.0-r1_all.ipk",
|
||||
"size": 14847,
|
||||
"size": 14842,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -1494,7 +1518,7 @@
|
||||
"name": "secubox-content-pkg",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-content-pkg_1.0.0-r1_all.ipk",
|
||||
"size": 3909,
|
||||
"size": 3907,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -1506,7 +1530,7 @@
|
||||
"name": "secubox-cookie-tracker",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-cookie-tracker_1.0.0-r1_all.ipk",
|
||||
"size": 10643,
|
||||
"size": 10639,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -1518,7 +1542,7 @@
|
||||
"name": "secubox-core",
|
||||
"version": "0.10.0-r16",
|
||||
"filename": "secubox-core_0.10.0-r16_all.ipk",
|
||||
"size": 127204,
|
||||
"size": 127202,
|
||||
"category": "system",
|
||||
"icon": "box",
|
||||
"description": "SecuBox core components",
|
||||
@ -1530,7 +1554,7 @@
|
||||
"name": "secubox-cve-triage",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-cve-triage_1.0.0-r1_all.ipk",
|
||||
"size": 11829,
|
||||
"size": 11826,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -1542,7 +1566,7 @@
|
||||
"name": "secubox-dns-guard",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-dns-guard_1.0.0-r1_all.ipk",
|
||||
"size": 12482,
|
||||
"size": 12480,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -1554,7 +1578,7 @@
|
||||
"name": "secubox-identity",
|
||||
"version": "0.1.0-r1",
|
||||
"filename": "secubox-identity_0.1.0-r1_all.ipk",
|
||||
"size": 8090,
|
||||
"size": 8089,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -1566,7 +1590,7 @@
|
||||
"name": "secubox-iot-guard",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-iot-guard_1.0.0-r1_all.ipk",
|
||||
"size": 13363,
|
||||
"size": 13370,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -1578,7 +1602,7 @@
|
||||
"name": "secubox-localrecall",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-localrecall_1.0.0-r1_all.ipk",
|
||||
"size": 7793,
|
||||
"size": 7798,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -1590,7 +1614,7 @@
|
||||
"name": "secubox-master-link",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-master-link_1.0.0-r1_all.ipk",
|
||||
"size": 15034,
|
||||
"size": 15036,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -1602,7 +1626,7 @@
|
||||
"name": "secubox-mcp-server",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-mcp-server_1.0.0-r1_all.ipk",
|
||||
"size": 11428,
|
||||
"size": 11427,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -1614,7 +1638,7 @@
|
||||
"name": "secubox-mirrornet",
|
||||
"version": "0.1.0-r1",
|
||||
"filename": "secubox-mirrornet_0.1.0-r1_all.ipk",
|
||||
"size": 15305,
|
||||
"size": 15303,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -1662,7 +1686,7 @@
|
||||
"name": "secubox-threat-analyst",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-threat-analyst_1.0.0-r1_all.ipk",
|
||||
"size": 9866,
|
||||
"size": 9865,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
@ -1674,7 +1698,7 @@
|
||||
"name": "secubox-vortex-dns",
|
||||
"version": "1.0.0-r1",
|
||||
"filename": "secubox-vortex-dns_1.0.0-r1_all.ipk",
|
||||
"size": 5439,
|
||||
"size": 5441,
|
||||
"category": "utility",
|
||||
"icon": "package",
|
||||
"description": "SecuBox package",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user