Packaging
Each v1 extension is one directory. Studio does not ship a template. You drop the files in, or install a zip from Settings.
On disk
<app data>/extensions/v1/com.example.one/
manifest.json
oneThe folder name must equal the manifest id. Open that tree from Settings, Extensions, then the Finder / Explorer / folder button. Reload rediscovers whatever is there.
Manifest
schemaVersion must be 1. Any other value is refused as unsupported manifest schemaVersion.
{
"schemaVersion": 1,
"id": "com.example.one",
"name": "Example One",
"version": "0.1.0",
"command": "one",
"args": [],
"contributes": {}
}That object is the on-disk file the host parses. contributes defaults to {} if omitted.
| Field | Required | Host rule |
|---|---|---|
schemaVersion | yes | Must be 1. |
id | yes | ASCII letters, digits, ., _, -. No /, \, or ... At most 128 characters. Must match the folder name. |
name | yes | Non-empty. Shown in Settings. |
version | yes | Non-empty. Shown in Settings. Not semver-checked. |
command | yes | Executable. Relative paths resolve from the extension directory. Absolute paths are used as given. |
args | no | Extra argv before the host-injected flags. |
contributes | no | Reserved. v1 does not read it. |
A folder whose id does not match is invalid. Settings still lists it, with connection: "failed" and the mismatch error.
Zip
Settings, Extensions, Install (or drop a .zip onto that page) extracts into the v1 root, then reloads.
Two layouts are accepted:
Wrapped — one top-level folder named as the id:
com.example.one/manifest.json
com.example.one/oneFlat — manifest.json at the zip root.
Encrypted entries, symbolic links, absolute paths, .. segments, and a zip with two candidate extensions are refused. A failed install does not replace a live folder. Replacing the same id swaps directories so the previous copy remains if the new one cannot load.
Launch
When the item is enabled, Studio binds 127.0.0.1:0 and spawns command with working directory set to the extension folder.
Injected argv, after your args:
--mx-host 127.0.0.1:9
--mx-extension-id com.example.one
--mx-protocol 1The same host, id, and protocol values are also in the environment. The hello token is not an argv flag. Read it from MX_EXTENSION_TOKEN only:
MX_EXTENSION_HOST=127.0.0.1:9
MX_EXTENSION_TOKEN=abc
MX_EXTENSION_ID=com.example.one
MX_EXTENSION_PROTOCOL=1Production tokens are 32 random bytes, hex-encoded (64 characters). The host unit tests use abc. stdin is closed. stdout and stderr inherit Studio. On Windows the process is created without a console window (CREATE_NO_WINDOW).
You have 15 seconds to connect and send a valid host.v1.hello. Miss that and Settings shows extension did not connect to the host. The hello token is one-shot for that launch of that id on that socket.
A connected item in Settings looks like the host snapshot the UI already uses:
{
"id": "com.example.one",
"name": "Example One",
"version": "0.1.0",
"enabled": true,
"listening": true,
"bind": "127.0.0.1:9",
"connection": "connected",
"status": {
"state": "ready",
"message": "watching",
"version": "0.1.0",
"protocolVersion": 1,
"capabilities": ["runtime.v1"]
},
"error": null
}connection is stopped, starting, connected, or failed. status.state is ready, degraded, or failed.