Install and develop built-in plugins
Install a built extension into Provision, verify its Service Worker, add a toolbar popup, and update or remove plugins safely.
A built-in SDK plugin is a Chrome extension loaded from <Provision root>/Extensions/<plugin-name>. Built-in plugins are installed automatically; use --show-component-extension-options to display them on chrome://extensions. Installing a plugin does not grant its License capabilities.
Install an existing plugin
- Fully quit the browser installation's running instances.
- Obtain the plugin's built extension files, including its Chrome
manifest.json, JavaScript, and referenced assets. Extract archives first; do not copy a.zipor.crxas the plugin directory. - Copy the directory into
Extensionsunder the actual Provision root. - Check that
Extensions/my-plugin/manifest.jsonexists directly. Avoid an accidental extra level such asmy-plugin/dist/manifest.json. - Keep the supplied directory name, install the required License capabilities and EP configuration, then relaunch.
Extensions/
chrovia-infra/
manifest.json
background.js
my-plugin/
manifest.json
background.js
popup.html
popup.jsKeep chrovia-infra for online License renewal. Other bundled plugins vary by archive; check Extensions and the plugin's documentation before using them.
Do not use Load unpacked to install a License. A normally loaded development extension also does not automatically receive Provision Service Worker identity. Use the Provision path for this guide.
Minimal plugin with a popup
This example needs extendedPrefs. The popup requests only one operation from its Service Worker; it never reads the privileged API directly.
manifest.json:
{
"manifest_version": 3,
"name": "My SDK Plugin",
"version": "1.0.0",
"background": { "service_worker": "background.js" },
"action": { "default_popup": "popup.html" },
"toolbar_pin": "default_pinned"
}toolbar_pin: "default_pinned" pins the toolbar icon whenever the Provision plugin loads, including after you manually unpin it and restart. Add standard permissions or host_permissions only for the Chrome APIs and external origins you actually use.
background.js:
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (sender.id !== chrome.runtime.id || message?.type !== 'read-label') {
return;
}
const prefs = globalThis.chrovia?.prefs;
if (!prefs) {
sendResponse({ error: 'extendedPrefs unavailable' });
return;
}
prefs.get('internal.instance_appearance.label').then(
label => sendResponse({ label: typeof label === 'string' ? label : '' }),
() => sendResponse({ error: 'Unable to read label' }),
);
return true;
});popup.html:
<!doctype html>
<html>
<body>
<p id="label">Loading...</p>
<script src="popup.js"></script>
</body>
</html>popup.js:
chrome.runtime.sendMessage({ type: 'read-label' }).then(
result => {
document.getElementById('label').textContent = result.error || result.label || 'No label';
},
() => {
document.getElementById('label').textContent = 'Service Worker unavailable';
},
);Configure the label using instance appearance. Reading its field uses extendedPrefs; displaying the browser badge also needs instanceAppearance. Store rendering text with textContent, and do not expose a generic privileged-method dispatcher to arbitrary messages.
Verify installation
Launch with --show-component-extension-options, open chrome://extensions, enable Developer mode, and inspect your plugin's Service Worker. Run globalThis.chrovia there. A missing root object usually indicates the wrong context or installation location; a missing domain indicates its entitlement is absent.
A popup or extension tab does not get chrovia by default. Do not enable unrestrictedApi merely to fix a popup; use the message pattern above. Ensure your debugging instance does not enable disable_devtools.
Update and remove
For updates, keep the directory name stable, replace the built files while the browser is closed, increment the extension manifest version for release tracking, and relaunch. Changing only source files or only the root Provision manifest does not update the installed script. Check the executable actually launched, especially if a desktop client extracted its own browser copy.
To remove a plugin, close the browser, remove its immediate directory from Extensions, then relaunch. Confirm that the plugin is no longer listed after restarting. Removal does not guarantee erasure of all extension settings or product data. Do not remove Infra from a lease-based distribution without a working authorized renewal integration.
Service Workers can restart. Register handlers each time the script executes, not only in onInstalled. Avoid multiple plugins claiming the single network interceptor or the same startup reply channel.