Add unpacked extension support

Adds an extension manager that loads unpacked extensions from the user data extensions directory, persists enabled state, and injects matching content scripts on page load. The settings Plugins page now shows installed extensions, supports reload/toggle actions, and includes an example Hello Nebula extension.
This commit is contained in:
Andrew Zambazos
2026-07-12 20:21:32 +12:00
parent 487c5fc1ae
commit 924529807f
15 changed files with 861 additions and 16 deletions
@@ -0,0 +1,10 @@
Copy this folder into Nebula's extensions directory to install:
%LOCALAPPDATA%\Nebula\User Data\extensions\hello-nebula\
Then open Settings > Plugins and click Reload Plugins (or restart Nebula).
manifest.json fields:
id, name, version, description, enabled
content_scripts[].matches (e.g. "*://*/*", "*://*.youtube.com/*", "<all_urls>")
content_scripts[].js / css (paths relative to this folder)
@@ -0,0 +1,20 @@
#nebula-hello-badge {
position: fixed;
right: 16px;
bottom: 16px;
z-index: 2147483646;
padding: 10px 14px;
border-radius: 10px;
background: #101820;
color: #e8f7ff;
font: 600 13px/1.3 Segoe UI, sans-serif;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28);
opacity: 1;
transition: opacity 0.4s ease, transform 0.4s ease;
pointer-events: none;
}
#nebula-hello-badge.nebula-hello-badge--hide {
opacity: 0;
transform: translateY(8px);
}
@@ -0,0 +1,15 @@
(function () {
if (document.getElementById('nebula-hello-badge')) {
return;
}
const badge = document.createElement('div');
badge.id = 'nebula-hello-badge';
badge.textContent = 'Nebula extension loaded';
badge.title = 'hello-nebula sample extension';
document.documentElement.appendChild(badge);
window.setTimeout(() => {
badge.classList.add('nebula-hello-badge--hide');
}, 3500);
})();
@@ -0,0 +1,15 @@
{
"id": "hello-nebula",
"name": "Hello Nebula",
"version": "1.0.0",
"description": "Sample Nebula extension. Shows a small badge on every page.",
"enabled": true,
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["content.js"],
"css": ["content.css"],
"run_at": "document_end"
}
]
}