Browse documentation
DocsExtensionsV1

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
  one

The 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.

FieldRequiredHost rule
schemaVersionyesMust be 1.
idyesASCII letters, digits, ., _, -. No /, \, or ... At most 128 characters. Must match the folder name.
nameyesNon-empty. Shown in Settings.
versionyesNon-empty. Shown in Settings. Not semver-checked.
commandyesExecutable. Relative paths resolve from the extension directory. Absolute paths are used as given.
argsnoExtra argv before the host-injected flags.
contributesnoReserved. 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/one

Flat — 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 1

The 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=1

Production 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.

14 documentation articles available.