* Support conflict-safe private storage in plugin panels * Update frame and worker tests for host API 1.1 * Use required braces in storage conflict guard * Update renderer handshake expectation for panel storage API * Clarify null comparisons and exclude inherited storage keys
6.8 KiB
Orca plugin host API reference
Host API 1.1 ("pluginApi": 1). Workers call a method with await orca.host.call(name, params); panels and custom editors call the same methods through window.orca.host.call(name, params). Each method lists the surfaces allowed to call it; any other surface gets not_permitted. orca.host.has(name) answers synchronously whether this Orca offers a method on the current surface, and orca.api is { major, minor }. See Plugin authoring for the frame API.
Every call is checked against the capabilities the user approved, and params are validated before Orca runs anything: params are strict, so a field this Orca does not know is refused with invalid_params instead of being dropped. Mutations are recorded in the audit log as plugin:<publisher>.<id>.
Methods
| Method | Capability | Surfaces | Mutation | Since | Summary |
|---|---|---|---|---|---|
workspace.readContext |
workspace:read |
worker, panel, editor | no | 1.0 | Branch, name and terminal ids of the focused workspace, or null when none is focused. |
terminal.sendText |
terminal:send |
worker | yes | 1.0 | Types text into one terminal named by id, optionally pressing Enter. |
notifications.show |
notifications:show |
worker, panel, editor | yes | 1.0 | Shows a desktop notification. |
storage.get |
storage:own |
worker, panel, editor | no | 1.0 | Reads a JSON value from the plugin's private store; null when absent. |
storage.compareAndSet |
storage:own |
worker, panel, editor | yes | 1.1 | Atomically writes a private JSON value only if it still matches expected; absent keys compare as null. |
storage.set |
storage:own |
worker | yes | 1.0 | Writes a JSON value to the plugin's private store. |
storage.delete |
storage:own |
worker | yes | 1.0 | Removes a key from the plugin's private store. |
storage.keys |
storage:own |
worker | no | 1.0 | Lists the keys in the plugin's private store. |
secrets.get |
secrets:own |
worker | no | 1.0 | Reads a secret from the plugin's encrypted secrets file; null when absent. |
secrets.set |
secrets:own |
worker | yes | 1.0 | Stores a secret in the plugin's encrypted secrets file. |
secrets.delete |
secrets:own |
worker | yes | 1.0 | Removes a secret from the plugin's encrypted secrets file. |
settings.get |
settings:own |
worker | no | 1.0 | Reads every setting the plugin owns. |
settings.set |
settings:own |
worker | yes | 1.0 | Writes one setting the plugin owns. |
workspace.readContext
Branch, name and terminal ids of the focused workspace, or null when none is focused.
(params: {}) => { branch: string; displayName: string; terminals: { id: string }[] } | null
terminal.sendText
Types text into one terminal named by id, optionally pressing Enter.
(params: { terminalId: string; text: string; enter?: boolean }) => { accepted: boolean }
notifications.show
Shows a desktop notification.
(params: { title: string; body?: string }) => { delivered: boolean }
storage.get
Reads a JSON value from the plugin's private store; null when absent.
(params: { key: string }) => { value: JSON }
storage.compareAndSet
Atomically writes a private JSON value only if it still matches expected; absent keys compare as null.
(params: { key: string; expected: JSON; value: JSON }) => { swapped: boolean }
storage.set
Writes a JSON value to the plugin's private store.
(params: { key: string; value: JSON }) => { ok: true }
storage.delete
Removes a key from the plugin's private store.
(params: { key: string }) => { ok: true }
storage.keys
Lists the keys in the plugin's private store.
(params: {}) => { keys: string[] }
secrets.get
Reads a secret from the plugin's encrypted secrets file; null when absent.
(params: { key: string }) => { value: string | null }
secrets.set
Stores a secret in the plugin's encrypted secrets file.
(params: { key: string; value: string }) => { ok: true }
secrets.delete
Removes a secret from the plugin's encrypted secrets file.
(params: { key: string }) => { ok: true }
settings.get
Reads every setting the plugin owns.
(params: {}) => { settings: Record<string, JSON> }
settings.set
Writes one setting the plugin owns.
(params: { key: string; value: JSON }) => { ok: true }
Errors
A failed call rejects with an Error carrying code, message, retryable and, for rate_limited, retryAfterMs. Treat a code not listed here as action_failed:
invalid_request: the call itself is malformed.invalid_params: params do not match the method, including a field this Orca does not know; the message names it.unknown_method: the method does not exist in this Orca.capability_denied: the manifest does not declare the capability.consent_required: the plugin is disabled or the user has not approved this version.not_permitted: the method or document is not available here, e.g. a worker-only method from a panel.rate_limited: calls arrive faster than the budget;retryAfterMssays when to try again.unavailable: the service behind the method is not running yet.action_failed: the method ran and failed.cancelled: the caller aborted the call through itssignal.timeout: Orca gave up waiting.conflict: the call was made against a stale version, e.g. an editor edit after an outside change.too_large: the message is larger than Orca accepts.
Stability and deprecation
Plugins are in Alpha: the manifest v2 format and catalog format are stable contracts; items listed as experimental in Plugin authoring may change.
- Host API 1 is frozen. Within
pluginApi1, methods, params and results only grow: a new method or a new optional param arrives with a higherSinceminor, and nothing listed here is removed, renamed or narrowed. - Deprecation. A method to be retired is marked deprecated in this table and keeps working for the rest of the major.
- New majors. A breaking change ships as a new
pluginApimajor beside the old one. Orca refuses a manifest whosepluginApinames a major it does not implement, with "update Orca", instead of loading it against the wrong API. - Detect, do not assume. Check
orca.host.has(name)ororca.api.minorbefore calling a method newer than the oldest Orca you support; a call that slips through fails withunknown_method.