plugin.json describes the package before any code runs. It must be valid JSON. Unknown fields are rejected, including a $schema field or a dependencies field. Use the JSON schema through your editor’s schema association settings.
Complete manifest example
Section titled “Complete manifest example”This manifest shows every contribution type. To build it, provide the view, command and fill implementations, plus view.css and theme/theme.jsonc included in assets. See Commands and interface contributions for command and button registration.
{ "schemaVersion": 1, "hostApi": 1, "id": "example.workspace-info", "name": "Workspace info", "version": "0.1.0", "description": "Show the active project and workspace.", "entry": "dist/index.js", "activation": "startup", "stylesheets": [ "view.css" ], "contributes": { "views": [ { "id": "example.workspace-info.view", "title": "Workspace info", "placement": "central", "multiple": false, "stateVersion": 1 } ], "commands": [ { "id": "example.workspace-info.open", "label": "Workspace info", "description": "Open workspace information.", "context": { "workspace": true } } ], "keybindings": [ { "command": "example.workspace-info.open", "shortcut": "Ctrl+Alt+KeyI" } ], "fills": [ { "id": "example.workspace-info.status", "slot": "statusbar", "label": "Open workspace information" } ], "themes": [ { "id": "example.workspace-info.theme", "path": "theme" } ] }}Top-level fields
Section titled “Top-level fields”| Field | Required | Meaning |
|---|---|---|
schemaVersion |
Yes | Manifest format. Must be 1. |
hostApi |
Yes | Host API version. Must be 1. |
id |
Yes | Namespaced package ID, up to 100 characters. |
name |
Yes | Display name, up to 160 characters. |
version |
Yes | major.minor.patch, with an optional prerelease suffix. Up to 80 characters. |
description |
Yes | Non-empty description, up to 2000 characters. |
entry |
For executable contributions | Relative path to a prebuilt .js or .mjs ESM module. |
activation |
No | lazy by default, or startup. |
stylesheets |
No | Up to 16 distinct relative .css paths. |
contributes |
No | Declared views, commands, keybindings, fills and themes. |
The version parser accepts 1.2.3 and 1.2.3-beta.1. Build metadata such as 1.2.3+build.4 is not accepted.
Identifiers
Section titled “Identifiers”Use lower-case names with at least one dot, such as example.workspace-info. Each dot-separated segment starts with a letter and can contain lower-case letters, digits and hyphens.
Contribution IDs must begin with the complete package ID and another dot. For example, example.workspace-info.panel belongs to example.workspace-info. Contribution IDs are limited to 160 characters and must be unique across views, commands, fills and themes. A keybinding references an existing command ID; each command can have one manifest keybinding.
Contributions
Section titled “Contributions”Each list below accepts at most 128 entries.
| List | Fields |
|---|---|
views |
id, title, placement, multiple, stateVersion |
commands |
id, label, description, optional context |
keybindings |
command, shortcut |
fills |
id, slot, label |
themes |
id, path |
Views use placement: "central" or "sidebar". Sidebars require multiple: false. stateVersion is an integer from 1 to 1000 and must match a restored panel exactly.
Command context accepts workspace, viewTypes and textInput. See commands and interface slots for execution rules and shortcut syntax.
Fills target statusbar, sidebar-actions or view-actions. Their label must describe the control. Theme path values point to folders containing theme.jsonc or a supported legacy theme.json.
A package containing only themes may omit entry. Views, commands, keybindings and fills require an executable entry. Declaring a contribution does not register its implementation: activate() must call the matching SDK registration method.
Contribution field reference
Section titled “Contribution field reference”| Contribution field | Type / limit | Meaning |
|---|---|---|
views[].id |
ID, 160 characters | Used by registerView() and openView() |
views[].title |
Nonempty text, 160 characters | Initial panel title |
views[].placement |
central or sidebar |
View location |
views[].multiple |
Required boolean | Whether to create new instances; sidebars require false |
views[].stateVersion |
Integer 1-1000 | This view’s saved state format |
commands[].id |
ID, 160 characters | Registration, shortcut and execution identity |
commands[].label |
Nonempty text, 160 characters | Command display name |
commands[].description |
Nonempty text, 2000 characters | What the command does |
commands[].context.workspace |
Optional boolean | true requires a workspace |
commands[].context.viewTypes |
Up to 128 strings, each at most 160 characters | Allowed active panel types; omission allows any type |
commands[].context.textInput |
Optional boolean | true permits the shortcut while typing in a field |
keybindings[].command |
ID of an owned declared command | One default assignment per command |
keybindings[].shortcut |
Valid shortcut or null |
null means no default shortcut |
fills[].id |
ID, 160 characters | Used by registerFill() |
fills[].slot |
One of three supported names | Control location |
fills[].label |
Nonempty text, 160 characters | Contribution label; buttons still need accessible names |
themes[].id |
ID, 160 characters | Theme identity |
themes[].path |
Relative path, 512 characters | Theme directory inside the package |
Names and descriptions cannot contain control characters. Unknown fields are rejected inside contributions too. Every contribution list is optional. The full parser checks relationships that editor JSON Schema validation alone cannot verify.
Four independent versions
Section titled “Four independent versions”schemaVersiondescribes theplugin.jsonformat.hostApiselects the application contract.versionidentifies the plugin release.stateVersiondescribes one view type’s saved state format.
The SDK package version is another independent number. Increasing the plugin version does not change APIs or migrate state. Keep IDs stable across releases: they connect packages with retained panels and user shortcuts.
Editor schema association
Section titled “Editor schema association”The generator creates .vscode/settings.json referencing the installed SDK schema. In a manual project, add:
{ "json.schemas": [ { "fileMatch": ["plugin.json"], "url": "./node_modules/@lomi-dev/plugin-sdk/plugin.schema.json" } ]}Declare npm dependencies in package.json. Manifest v1 has no permissions, inter-plugin dependencies or application version ranges. Do not add these fields yourself. Tools and native import validation complement the schema.
Package paths
Section titled “Package paths”Use relative paths with /, such as dist/index.js or themes/graphite. Absolute paths, . and .. segments, backslashes, encoded paths, symlinks, Windows reserved names and alternate streams are rejected. Paths are limited to 512 characters. The importer verifies that the referenced entry, stylesheets and theme files exist.
Source: manifest validation, native validation.