* feat(plugins): panels talk to their own worker, read storage, settings and events
- plugin.request (host API 1.2): a panel or editor asks its plugin's worker, which answers with
orca.panels.handle(name); the worker pushes with orca.panels.post. Same plugin only, JSON
checked, 1 MiB answers, 256 KiB/200-per-10s posts, a deadline and the panel's lifetime.
- Panels and editors get storage.*, settings.* and secrets.* behind the same capabilities, and
storage/settings onDidChange on every surface; events.subscribe delivers workspace and agent
events to panels that hold the read capability.
- contributes.settings: typed settings (a JSON Schema subset) with defaults and value checks.
- Frames get orca.plugin/storage/settings/secrets; components panels import plugin, storage,
settings, secrets from 'orca', and atom(key, init, { persist: 'storage' }) shares a value with
the worker. Workers get orca.panels/storage/settings/secrets sugar.
- One typed contract: declare module 'orca' { interface PluginRequests / PluginPanelEvents }.
- Desktop push channel per open panel session (plugins:openPanelPush).
* feat(plugins): Orca Settings shows and edits a plugin's contributes.settings
The plugin page lists declared settings with Orca's own controls (switch, picker, text and
number fields, Reset to default). Edits are checked against the declaration in main, written to
the plugin's settings, and reach open panels and the running worker through onDidChange.
* docs(plugins): hello-tsx talks to its worker; authoring guide covers panels, workers and data
The example now uses one of each: plugin.request answered by orca.panels.handle, a worker post
heard with plugin.on, a persist: 'storage' atom the worker watches, two contributes.settings and
agent.status.changed in the panel, all typed by one src/protocol.ts. The build-less TSX e2e
drives the whole loop.
* fix(plugins): typed bridge overloads, panel call budget, settings IPC and catalog keys
- PluginBridgeApi/PanelsApi use overloads: declared names are typed (and complete), any other
name carries JSON; no never-unions for the type-aware lint.
- The per-plugin panel call budget is 120 per 10 s, since a panel loading storage atoms,
settings and its first requests makes a burst; the hostile fixture floods past it.
- Settings IPC builds its host per call; the settings section's strings are in en.json.
* test(plugins): the example's declared settings show under the plugin with the person's value
* refactor(plugins): keep hello-tsx the minimal starter; the bridge demo is hello-worker-panel
hello-tsx goes back to a sandboxed-ui panel with no worker or capabilities. The worker, protocol,
storage atom, settings and events move to examples/plugins/hello-worker-panel, with their own
e2e (plugin-worker-panel) and PR route.
* feat(plugins): test kit covers the panel bridge and plugin data
mockHost keeps the plugin's storage, settings and secrets in memory (seeded with storage,
settings, secrets; read with host.data()) and fakes the worker with requests, so plugin.request,
storage/settings/secrets and persist: 'storage' atoms work under mount(), writes reach
onDidChange, and panel.post(event, payload) is what plugin.on hears. Typed by PluginRequests and
PluginPanelEvents.
* test(plugins): focusInGuest waits for the guest and retries focusing as one step
Under load the custom-editor guest could still be attaching, so executeJavaScript threw
'dom-ready' before the focus poll began. Wait for waitForGuestReady, then retry focusing the
webview and the element together, tolerating a guest that is still attaching or remounts.
* docs(plugins): the authoring skill covers panels, workers and data; persistence leaves the renderer
- skill-guides/orca-plugin-authoring.md gains Panels, workers and data (plugin.request/on,
orca.panels.handle/post, persist: 'storage', contributes.settings, panel events, test kit), and
its generated references read orca-services.d.ts for shell, files, on and the bridge types.
- After the dev-loop rebase, persisted-atom wiring (queue plus storage sync) moves to
createDeclarativePersistence so the renderer stays under max-lines.
* feat(plugins): panels show agents: agents.list, terminal ids on agent events, workspace.changed
- agents.list (agent:read, every surface): the focused workspace's agents with terminalId,
title, agent kind, state and stateStartedAt, from the hook server's store.
- agent.status.changed carries terminalId and title: paneKey mapped through the runtime's
terminal list (tabId:leafId) or the status's terminal handle; looked up only while a plugin
listens, in arrival order.
- workspace.readContext terminals carry title; workspace.changed (workspace:read) fires after
workspace session writes when the focused workspace or its terminals change.
- Event subscriptions are kept per panel session, so one made before the push channel opens
still counts.
- shell.openExternal never prompts on a hidden or minimized window: it settles
{ opened: false, reason: 'consent-unavailable' } and says so in the plugin log, which also
notes 'waiting for the person to confirm' while a prompt is up; the rate budget is spent only
when Orca acts. e2e launches never open a real browser or mail client.
- A worker may export activate as default or by name; docs, typings and the authoring skill
document the entry, the agent events and a live agent status recipe.
* fix(plugins): the plugin page names the workspace.changed subscription
* fix(plugins): workers activate only by default export, and say so when it is named
Orca calls the worker module's default export. A module with a named `activate` and no default
now fails to start with an error naming the fix (`export default function activate(orca)`),
instead of being called by a fallback; docs, typings and the skill say default export.
hello-worker-panel gains a picker setting (suggestionOrder) the worker reads.
25 KiB
Orca plugin manifest reference
The orca-plugin.json file at the root of an Orca plugin (manifest format 2).
Add "$schema": "https://raw.githubusercontent.com/stablyai/orca/main/docs/schemas/plugins/orca-plugin.v2.schema.json" to orca-plugin.json for completion and inline errors in your editor.
Since is the first Orca release that reads the field; raise engines.orca when you use a newer one.
Fields
| Field | Type | Required | Since | Description |
|---|---|---|---|---|
$schema |
string | no | 1.4.245 | JSON Schema URL for editor completion. Ignored by Orca. |
manifestVersion |
2 |
yes | 1.4.245 | Manifest format. Use 2 for new plugins. |
execution |
"data" | "declarative" | "sandboxed-ui" | "trusted-worker" |
yes | 1.4.245 | Most authority the plugin needs, least first: data (themes, syntaxes, translations), declarative (commands, shortcuts, recipes), sandboxed-ui (panels), trusted-worker (main and events). Contributions beyond it fail validation. Example: "data" |
id |
string | yes | 1.4.160 | Plugin id, kebab-case. The install identity is <publisher>.<id>, where Orca derives the publisher from the repository owner. The reserved names constructor and prototype are refused. Example: "gleam-syntax" |
publisher |
string | no | 1.4.160 | Deprecated: leave it out. Orca derives the publisher from where the plugin comes from, the way a Go module is named by its repository path: the repository owner for the official and community catalogs and for Git URL installs (acme for github.com/acme/gleam-syntax), and local for a folder. A value here is ignored for catalog and Git installs. Leaving it out needs engines.orca of at least >=1.4.246, because older Orca requires it; if you keep it for older Orca, it must equal the repository owner. Reserved owners (stablyai, official, anthropic, openai, github and any starting orca) and ids starting orca- install only from Orca's official catalog. Example: "acme" |
name |
string | yes | 1.4.160 | Display name. Example: "Gleam" |
version |
string | yes | 1.4.160 | Plugin version, semver. Example: "1.2.0" |
description |
string | no | 1.4.160 | One or two sentences shown in the plugin list. |
author |
object | no | 1.4.160 | Who maintains the plugin. |
author.name |
string | yes | 1.4.160 | Author or organization name. Example: "Acme" |
author.url |
string | no | 1.4.160 | Author homepage. Example: "https://example.com" |
repository |
string | no | 1.4.160 | Source repository URL. Example: "https://github.com/acme/orca-gleam-syntax" |
license |
string | no | 1.4.245 | SPDX license expression. Example: "MIT" |
homepage |
string | no | 1.4.245 | Project homepage, https only. Example: "https://example.com/gleam" |
icon |
string | no | 1.4.160 | Square image shown beside the plugin name. PNG, WEBP, static, at least 128×128, square, at most 256 KB. Relative to the plugin root; .. segments and Windows device names such as CON are refused. Example: "assets/icon.png" |
engines |
object | yes | 1.4.160 | Host versions this plugin supports. Older hosts refuse to load it. |
engines.orca |
string | yes | 1.4.160 | Oldest Orca release this plugin runs on, as >=x.y.z. Raise it to the newest "Since" of any field you use; a format 2 manifest needs at least >=1.4.245, because older Orca cannot read format 2. Example: ">=1.4.245" |
main |
string | no | 1.4.160 | Node entry run in an out-of-process plugin worker: a .js/.mjs module, or a .ts/.mts module that Orca transpiles when it loads (needs engines.orca >=1.4.246). Requires the trusted-worker execution profile, and is required by it, by contributes.events and by any command without an action. Relative to the plugin root; .. segments and Windows device names such as CON are refused. Example: "dist/main.mjs" |
contributes |
object | no | 1.4.160 | What the plugin adds to Orca. Every point defaults to empty. |
contributes.panels |
PanelContribution[] | no | 1.4.160 | Sidebar panels. At most 64. |
contributes.commands |
CommandContribution[] | no | 1.4.160 | Command palette entries. At most 256. |
contributes.events |
EventContribution[] | no | 1.4.160 | Events delivered to the plugin worker. At most 4. |
contributes.languagePacks |
LanguagePackContribution[] | no | 1.4.160 | Interface translations. At most 16. |
contributes.keybindings |
KeybindingContribution[] | no | 1.4.160 | Keyboard shortcuts for contributed commands. At most 256. |
contributes.vmRecipes |
VmRecipeContribution[] | no | 1.4.160 | Virtual machine environment recipes. At most 64. |
contributes.themes |
ThemeContribution[] | no | 1.4.245 | App color themes. At most 64. |
contributes.terminalThemes |
ThemeContribution[] | no | 1.4.245 | Terminal ANSI palettes. At most 64. |
contributes.iconThemes |
ThemeContribution[] | no | 1.4.245 | File icon themes. At most 32. |
contributes.syntaxes |
SyntaxContribution[] | no | 1.4.245 | Syntax highlighting for editor languages. At most 16. |
contributes.customEditors |
CustomEditorContribution[] | no | 1.4.245 | Editors that open files of given types in the editor tab. At most 16. |
contributes.newFiles |
NewFileContribution[] | no | 1.4.245 | Untitled files the user can create from the + menu and the command palette. At most 16. |
contributes.settings |
SettingContribution[] | no | 1.4.246 | Settings Orca shows under the plugin in Settings; code reads them with settings.get (settings:own). At most 64. |
contributes.agentHarnesses |
any[] | no | 1.4.245 | Reserved for coding-agent harness definitions; must be empty until their format is defined. |
contributes.skills |
any[] | no | 1.4.245 | Reserved for agent skills; must be empty until their format is defined. |
contributes.mcpServers |
any[] | no | 1.4.245 | Reserved for MCP server definitions; must be empty until their format is defined. |
contributes.hooks |
any[] | no | 1.4.245 | Reserved for agent hooks; must be empty until their format is defined. |
contributes.taskSources |
any[] | no | 1.4.245 | Reserved for task sources; must be empty until their format is defined. |
contributes.connections |
any[] | no | 1.4.245 | Reserved for account connections; must be empty until their format is defined. |
contributes.statusBarItems |
any[] | no | 1.4.245 | Reserved for status bar items; must be empty until their format is defined. |
contributes.sidebarCards |
any[] | no | 1.4.245 | Reserved for sidebar cards; must be empty until their format is defined. |
capabilities |
Capability[] | no | 1.4.160 | Host APIs the plugin asks the user to grant. At most 32. |
cover |
object | no | 1.4.245 | Wide image at the top of the plugin page. |
cover.path |
string | yes | 1.4.245 | Cover image shown on the plugin page, 16:10 recommended (1600×1000). PNG, JPEG, WEBP, static, at least 800×500, at most 1024 KB. Relative to the plugin root; .. segments and Windows device names such as CON are refused. Example: "images/cover.png" |
cover.alt |
string | yes | 1.4.245 | What the image shows, for screen readers. Required. Example: "The Dusk theme on a terminal" |
screenshots |
Screenshot[] | no | 1.4.245 | Screenshots for the plugin page, at most 6. All images together may be at most 8 MB. |
pluginApi |
1 |
no | 1.4.160 | Major version of the plugin host API this plugin targets. Optional (defaults to 1), and refused on data and declarative plugins, which never call it. |
PanelContribution
A sidebar panel. Requires the sandboxed-ui execution profile or higher.
| Field | Type | Required | Since | Description |
|---|---|---|---|---|
id |
string | yes | 1.4.160 | Panel id, unique among this plugin's panels. The reserved names constructor and prototype are refused. Example: "dashboard" |
title |
string | yes | 1.4.160 | Title shown on the panel tab and its tooltip. Example: "Dashboard" |
icon |
"activity" | "bar-chart-3" | "bell" | "blocks" | "book" | "bot" | "bug" | "calendar" | "cloud" | "code" | "database" | "file-text" | "flag" | "folder" | "gauge" | "globe" | "hammer" | "layers" | "lightbulb" | "package" | "plug" | "puzzle" | "rocket" | "star" | "terminal" | "wrench" | "zap" | "add" | "remove" | "delete" | "edit" | "refresh" | "search" | "settings" | "check" | "close" | "info" | "warning" | "error" | "open-external" | "copy" | "download" | "upload" | "play" | "pause" | "stop" | "more" | "expand" | "collapse" | "next" | "filter" | "branch" | "file" | "agent" | "link" |
no | 1.4.160 | Icon shown in the right-sidebar activity bar. Defaults to plug. Example: "database" |
entry |
string | yes | 1.4.160 | What the panel runs: an HTML page for ui: "html", a .js/.mjs module for ui: "components". Either may instead be a .ts/.tsx/.mts/.jsx file, which Orca transpiles when it loads (needs engines.orca >=1.4.246; an html panel then gets a generated page around it). It is trusted code: install panels you trust. Relative to the plugin root; .. segments and Windows device names such as CON are refused. Example: "dist/panel.html" |
ui |
"html" | "components" |
no | 1.4.246 | How the panel draws its UI. html (default) shows entry as a web page in an isolated frame; components runs entry as a hidden module and Orca draws the component tree it returns with its own controls. Example: "components" |
CommandContribution
A command palette entry. Requires the declarative execution profile or higher.
| Field | Type | Required | Since | Description |
|---|---|---|---|---|
id |
string | yes | 1.4.160 | Command id, unique among this plugin's commands. Dotted namespaces are allowed. Example: "jupyter.restartKernel" |
title |
string | yes | 1.4.160 | Title shown in the command palette. Example: "Restart kernel" |
when |
"global" | "workspace" |
no | 1.4.160 | Where the command is available. workspace hides it when no workspace is active. Defaults to global. |
action |
"worktree.history.back" | "worktree.history.forward" | "sidebar.left.toggle" | "sidebar.sleepingWorkspaces.toggle" | "floatingWorkspace.maximize" | "tab.rename" | "workspace.rename" | "workspace.openBoard" | "view.tasks" | "sidebar.right.toggle" | "sidebar.explorer.toggle" | "sidebar.search.toggle" | "sidebar.sourceControl.toggle" | "sidebar.checks.toggle" | "sidebar.ports.toggle" |
no | 1.4.160 | Built-in Orca action this command runs. A command with an action is declarative and never starts the plugin worker; one without needs main. Example: "view.tasks" |
EventContribution
An event subscription. Requires main, the trusted-worker execution profile and the capability of the event's domain: workspace:read for workspace events, agent:read for agent events.
| Field | Type | Required | Since | Description |
|---|---|---|---|---|
on |
"workspace.created" | "workspace.removed" | "agent.status.changed" | "workspace.changed" |
yes | 1.4.160 | Event delivered to the plugin worker. |
LanguagePackContribution
An interface translation.
| Field | Type | Required | Since | Description |
|---|---|---|---|---|
locale |
string | yes | 1.4.160 | BCP 47 locale the pack translates Orca into. Each locale appears once, ignoring case. Example: "pt-BR" |
path |
string | yes | 1.4.160 | JSON file of translated interface strings. Relative to the plugin root; .. segments and Windows device names such as CON are refused. Example: "locales/pt-BR.json" |
displayName |
string | no | 1.4.245 | Native-language name for the Settings picker. Omitted packs show {locale} — {pluginKey}. Example: "Português (Brasil)" |
KeybindingContribution
A keyboard shortcut for a command.
| Field | Type | Required | Since | Description |
|---|---|---|---|---|
command |
string | yes | 1.4.160 | Id of a command this plugin contributes in contributes.commands. Example: "jupyter.restartKernel" |
key |
string | yes | 1.4.160 | Key chord Orca recognizes, such as Mod+Shift+K. Mod is Cmd on macOS and Ctrl elsewhere. Each chord may be bound once on every platform. Example: "Mod+Shift+K" |
when |
"global" | "workspace" |
no | 1.4.160 | Where the shortcut is active; must match its command's when. |
VmRecipeContribution
A virtual machine environment recipe.
| Field | Type | Required | Since | Description |
|---|---|---|---|---|
path |
string | yes | 1.4.160 | JSON environment recipe file, listed once. Relative to the plugin root; .. segments and Windows device names such as CON are refused. Example: "recipes/ubuntu.json" |
ThemeContribution
A titled theme file.
| Field | Type | Required | Since | Description |
|---|---|---|---|---|
id |
string | yes | 1.4.245 | Theme id, unique within its family in this plugin. The reserved names constructor and prototype are refused. Example: "dusk" |
title |
string | yes | 1.4.245 | Name shown in the theme picker. Example: "Dusk" |
path |
string | yes | 1.4.245 | JSON theme file, at most 16 KiB. Relative to the plugin root; .. segments and Windows device names such as CON are refused. Example: "themes/dusk.json" |
SyntaxContribution
Syntax highlighting for one language.
| Field | Type | Required | Since | Description |
|---|---|---|---|---|
id |
string | yes | 1.4.245 | Language id, unique among this plugin's syntaxes. The reserved names constructor and prototype are refused. Example: "gleam" |
title |
string | yes | 1.4.245 | Language name shown in the editor. Example: "Gleam" |
scopeName |
string | yes | 1.4.245 | The grammar's root TextMate scope, unique among this plugin's syntaxes. Example: "source.gleam" |
path |
string | yes | 1.4.245 | TextMate grammar JSON file. Relative to the plugin root; .. segments and Windows device names such as CON are refused. Example: "syntaxes/gleam.tmLanguage.json" |
configuration |
string | no | 1.4.245 | Language configuration JSON file: comments, brackets and auto-closing pairs. Relative to the plugin root; .. segments and Windows device names such as CON are refused. Example: "syntaxes/language-configuration.json" |
extensions |
string[] | no | 1.4.245 | File-name suffixes, with the dot, this language opens, ignoring case. A longer suffix such as .excalidraw.json wins over a shorter one, and a file named only the suffix never matches. At most 32. Example: [".gleam"] |
filenames |
string[] | no | 1.4.245 | Exact file names this language opens, ignoring case; a name beats any extension. Names must be portable: no path separators, ., .. or characters Windows forbids. At most 32. Example: ["gleam.toml"] |
CustomEditorContribution
An editor for the listed files, shown in the editor tab beside Source. It must list at least one extension or file name. Requires the sandboxed-ui execution profile or higher.
| Field | Type | Required | Since | Description |
|---|---|---|---|---|
id |
string | yes | 1.4.245 | Editor id, unique among this plugin's custom editors. The reserved names constructor and prototype are refused. Example: "excalidraw" |
title |
string | yes | 1.4.245 | Name shown in the editor's view toggle beside Source, and on the tab of a file it opens. Example: "Excalidraw" |
icon |
string | no | 1.4.245 | Square image shown on the tab of a file this editor opens. Defaults to the plugin icon. PNG, WEBP, static, at least 128×128, square, at most 256 KB. Relative to the plugin root; .. segments and Windows device names such as CON are refused. Example: "images/editor-icon.png" |
extensions |
string[] | no | 1.4.245 | File-name suffixes, with the dot, this editor opens, ignoring case. A longer suffix such as .excalidraw.json wins over a shorter one, and a file named only the suffix never matches. At most 32. Example: [".excalidraw",".excalidraw.json"] |
filenames |
string[] | no | 1.4.245 | Exact file names this editor opens, ignoring case; a name beats any extension. Names must be portable: no path separators, ., .. or characters Windows forbids. At most 32. Example: [] |
entry |
string | yes | 1.4.245 | HTML file rendered inside an editor frame, like a panel, or a .ts/.tsx module that Orca transpiles and loads in a generated page (needs engines.orca >=1.4.246). It receives the open document and posts edits back; it never gets a file path or file system. It is trusted code: install editors you trust. Relative to the plugin root; .. segments and Windows device names such as CON are refused. Example: "editor/index.html" |
priority |
"default" | "option" |
no | 1.4.245 | default (the default) opens matching files in this editor; option only offers it in the view toggle, so files open in Source. Files Orca opens itself (such as .json, .ts, .md, .csv, .yaml, lockfiles and .env files) always behave as option. Example: "default" |
contentKind |
"text" | "bytes" |
no | 1.4.245 | text (the default) sends the file as text and accepts full-text edits. bytes sends the file's raw bytes, for binary formats such as spreadsheets, and accepts full-byte edits. Example: "bytes" |
NewFileContribution
A kind of untitled file the user can create from the tab bar + menu or the command palette, in the active workspace.
| Field | Type | Required | Since | Description |
|---|---|---|---|---|
id |
string | yes | 1.4.245 | New-file id, unique among this plugin's new files. The reserved names constructor and prototype are refused. Example: "drawing" |
title |
string | yes | 1.4.245 | Menu item shown in the tab bar + menu and the command palette. Example: "New Excalidraw drawing" |
extension |
string | yes | 1.4.245 | Suffix, with the dot, of the untitled file it creates. The file opens in whatever editor takes that suffix, such as a custom editor from this plugin. Example: ".excalidraw" |
template |
string | no | 1.4.245 | UTF-8 file copied into the new file, at most 256 KB. Without one the file starts empty. Relative to the plugin root; .. segments and Windows device names such as CON are refused. Example: "templates/empty.excalidraw" |
icon |
string | no | 1.4.245 | Square image shown beside the menu item. Defaults to the plugin icon. PNG, WEBP, static, at least 128×128, square, at most 256 KB. Relative to the plugin root; .. segments and Windows device names such as CON are refused. Example: "images/editor-icon.png" |
SettingContribution
A setting shown under the plugin in Settings. Requires the settings:own capability, which is also how code reads it.
| Field | Type | Required | Since | Description |
|---|---|---|---|---|
key |
string | yes | 1.4.246 | Key code reads and writes, unique in this plugin. Example: "apiUrl" |
title |
string | yes | 1.4.246 | Label shown in Settings. Example: "Server URL" |
description |
string | no | 1.4.246 | Help text shown under the label. |
type |
"string" | "number" | "integer" | "boolean" |
yes | 1.4.246 | JSON Schema type of the value. Example: "string" |
default |
string | number | boolean | no | 1.4.246 | Value read while the person has not set one. |
enum |
(string | number)[] | no | 1.4.246 | Allowed values; Settings shows a picker. |
enumLabels |
string[] | no | 1.4.246 | Picker labels, one per enum value. |
minimum |
number | no | 1.4.246 | Numbers: smallest value. |
maximum |
number | no | 1.4.246 | Numbers: largest value. |
maxLength |
integer | no | 1.4.246 | Strings: most characters. |
multiline |
boolean | no | 1.4.246 | Strings: a multi-line text box. |
placeholder |
string | no | 1.4.246 | Strings and numbers: hint shown while empty. |
Capability
A host API the plugin may call once the user consents.
| Field | Type | Required | Since | Description |
|---|---|---|---|---|
kind |
"workspace:read" | "agent:read" | "terminal:send" | "notifications:show" | "storage:own" | "secrets:own" | "settings:own" |
yes | 1.4.160 | Capability granted on user consent. |
Screenshot
One screenshot of the plugin in use.
| Field | Type | Required | Since | Description |
|---|---|---|---|---|
path |
string | yes | 1.4.245 | Screenshot, 16:10 recommended (up to 2560×1600). PNG, JPEG, WEBP, static, at least 1280×800, at most 1536 KB. Relative to the plugin root; .. segments and Windows device names such as CON are refused. Example: "images/editor.png" |
alt |
string | yes | 1.4.245 | What the image shows, for screen readers. Required. Example: "The Dusk theme on a terminal" |
caption |
string | no | 1.4.245 | Short caption under the screenshot. Example: "Gleam in the editor" |
theme |
"light" | "dark" |
no | 1.4.245 | Show this screenshot only with a light or dark Orca theme. |
Versions and compatibility
- What runs is strict. Orca refuses a manifest with any key it does not know, at every level, so an older Orca never silently ignores something a plugin relies on.
engines.orcais the only version gate. It must be at least the newestSinceof every field and every value (capability, event, built-in action) the manifest uses.pnpm validate:pluginand catalog CI enforce it, so an older Orca can always say "requires Orca >=X (this is Y)" instead of listing unknown fields.pluginApiis optional. It names the major version of the host API (reference), which only grows within major 1; Orca refuses a major it does not implement. Onlysandboxed-uiandtrusted-workerplugins call that API, sodataanddeclarativeplugins must leave it out.terminal:sendneedstrusted-worker. Panels get no host method that types into a terminal, so Orca refuses the capability on any other profile instead of asking the user to grant something the plugin can never use.- New fields, contribution points and values are additive. They arrive with a
Sinceversion; nothing else changes.manifestVersionrises only if an existing field changes meaning. - Deprecation. A field to be removed is marked deprecated here and keeps working for at least one release; it is removed only together with a higher
engines.orcarequirement, and its name is never reused. - Reserved contribution points.
contributes.agentHarnesses,skills,mcpServers,hooks,taskSources,connections,statusBarItemsandsidebarCardsare held for planned features and must stay empty until their format is defined. Each will arrive as an additive point with its ownSince, without a new manifest format.skills,mcpServersandhookskeep the meaning agent-plugin formats such as Claude Code's give them;agentsstays unclaimed because those formats use it for subagent files.
Planned contribution points
Each reserved point is planned as declared data that Orca renders and enforces, never arbitrary plugin UI. The intended shapes, which may still change:
taskSources: Issue and task providers such as Asana, Linear or Jira, declared as data that a worker fills with tasks.connections: Account providers with a host-run sign-in, so a plugin never handles credentials itself.agentHarnesses: New coding-agent harnesses described as data: how to launch them and read their status.statusBarItems: Declarative status bar widgets (label, icon, tooltip) whose values a worker updates.sidebarCards: Declarative left-sidebar cards with fixed layouts whose values a worker updates.mcpServers: MCP server definitions that Orca offers to the agents it launches.skills: Agent skills shipped as files that Orca installs for the agents it launches.hooks: Agent lifecycle hooks, such as before and after a tool call, for the agents Orca launches.
Legacy format 1
Orca still loads "manifestVersion": 1 manifests (read since 1.4.160), but new plugins should use format 2. Format 1 differs in three ways:
- It has no
executionfield. Orca derives the least profile that can run what the manifest declares. - Unknown top-level keys are ignored instead of rejected.
- The published JSON Schema does not describe it, so editors offer no completion for it.