pinakes-core: expose plugin UI pages via PluginManager

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Ic58a0174e6592303e863f51fb237220e6a6a6964
This commit is contained in:
raf 2026-03-09 19:59:21 +03:00
commit 0525ea6c60
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
2 changed files with 33 additions and 1 deletions

View file

@ -599,6 +599,36 @@ impl PluginManager {
&self.enforcer
}
/// List all UI pages provided by loaded plugins.
///
/// Returns a vector of `(plugin_id, page)` tuples for all enabled plugins
/// that have the `ui_page` kind and provide pages in their manifests.
pub async fn list_ui_pages(
&self,
) -> Vec<(String, pinakes_plugin_api::UiPage)> {
let registry = self.registry.read().await;
let mut pages = Vec::new();
for plugin in registry.list_all() {
if !plugin.enabled {
continue;
}
for entry in &plugin.manifest.ui.pages {
let page = match entry {
pinakes_plugin_api::manifest::UiPageEntry::Inline(page) => {
(**page).clone()
},
pinakes_plugin_api::manifest::UiPageEntry::File { .. } => {
// File-referenced pages require a base path to resolve;
// skip them here as they should have been loaded at startup.
continue;
},
};
pages.push((plugin.id.clone(), page));
}
}
pages
}
/// Check if a plugin is loaded and enabled
pub async fn is_plugin_enabled(&self, plugin_id: &str) -> bool {
let registry = self.registry.read().await;

View file

@ -493,7 +493,9 @@ impl HostFunctions {
if let Some(ref allowed) =
caller.data().context.capabilities.network.allowed_domains
{
let parsed = if let Ok(u) = url::Url::parse(&url_str) { u } else {
let parsed = if let Ok(u) = url::Url::parse(&url_str) {
u
} else {
tracing::warn!(url = %url_str, "plugin provided invalid URL");
return -1;
};