Manifest reference
Every bundle has a manifest named desktop-overlays.config.json at the root of its folder. It holds the metadata, the capabilities the bundle requests, the surfaces it can show, and the controls in its settings panel.
Full example
{
"name": "Audio Waves",
"version": "1.0.0",
"author": "your-name",
"description": "An FFT visualizer",
"thumbnail": "thumb.png",
"ignore": ["node_modules", "src/**", "*.map"],
"permissions": [
{ "scope": "sdk.audio", "reason": "Visualizes sound with an FFT" },
{ "scope": "sdk.media", "reason": "Shows the playing track title" },
{ "scope": "sdk.size", "reason": "Resizes itself to fit its content" },
{ "scope": "network.http", "value": "https://api.example.com/*", "reason": "Fetches score data" }
],
"content": [
{ "name": "main", "entrypoint": "index.html", "type": "overlay",
"width": 320, "height": 200, "condition": "$.options.mode == 'wave'" },
{ "name": "full", "entrypoint": "full.html", "type": "fullscreen",
"condition": "$.app.fullscreen == true" }
],
"options": [
{ "key": "mode", "name": "Mode", "type": "input", "kind": "select",
"choices": [ { "label": "Wave", "value": "wave" },
{ "label": "Bars", "value": "bars" } ] }
]
}Top-level fields
| Field | Required | Description |
|---|---|---|
name | yes | Display name shown in the library, the options panel, and the Workshop. |
version | yes | The bundle version, for example 1.0.0. Bump it when you publish an update. |
author | yes | Your name or handle. |
description | no | Free text shown under the name in the library and the options panel. |
thumbnail | no | Path to a thumbnail image, relative to the bundle root. Used in the library and Workshop. |
ignore | no | Glob patterns for files to leave out when the bundle is packaged and published. See ignore. |
permissions | yes | The capabilities the bundle requests. See Permissions. |
content | yes | The surfaces the bundle can show. See content. |
options | no | The controls in the settings panel. See Options. |
content
content is a list of surfaces the bundle can render. Most bundles have exactly one. When more than one is listed, the app picks the first whose condition matches the current state. If none match, the overlay is hidden.
{ "name": "main", "entrypoint": "index.html", "type": "overlay",
"width": 320, "height": 200, "condition": "$.options.mode == 'wave'" }| Field | Required | Description |
|---|---|---|
name | yes | A unique name for this surface within the bundle. |
entrypoint | yes | Path to the file to load, relative to the bundle root. See Entry point types. |
type | yes | overlay or fullscreen. See Surface types. |
width | no | Initial width in pixels. Only used for type: overlay. |
height | no | Initial height in pixels. Only used for type: overlay. |
condition | no | An expression that decides whether this surface is active. If omitted, the surface is always eligible. See Conditions. |
Entry point types
- If
entrypointends in.htmlor.htm, it runs as a web page inside a sandboxed iframe. The SDK and the content security policy are injected for it. This is the normal case. - If
entrypointis a supported media file (img,gif,mp4,webm, and similar), it is drawn directly as an image or video, like a plain media overlay. The SDK is not available for media entry points.
Because both forms accept condition, type, width, and height, you can switch between an interactive surface and a static media surface based on state.
Surface types
overlay: a positionable, anchorable box. This is the normal overlay behavior.widthandheightset the initial box size; the bundle can resize itself at runtime withDesktopOverlaysAPI.size.set()if it has thesdk.sizepermission.fullscreen: a surface that covers the whole display, for visualizers or wallpapers.widthandheightare ignored.
The ignore field
ignore is a list of glob patterns. When the app packages and publishes the bundle, any file that matches a pattern is left out. Use it to keep development files out of the published bundle: source folders, node_modules, build output, source maps, and so on.
*matches within a single path segment.**matches across path segments.?matches a single character.- A pattern with no slash, such as
node_modulesor*.map, matches at any depth, like a.gitignorerule.
desktop-overlays.config.json is always kept, even if a pattern would match it.
Validation
The manifest is validated before the bundle installs. These are rejected:
- A
permissionsentry with an unknownscope. - A
network.*permission with novalue. - A permission with an empty
reason.
See Permissions for the permission rules and Conditions for the condition language used by content, options, and choices.