recipes.md gains "A rich editor with a library" beside the hooks and status bar recipes: an isolated-frame custom editor that vendors its library behind an import map, syncs through orca.document.session with a merge by id, and tests that sync with mockEditorHost. host-api.md lists every --orca-* frame variable and what it paints, generated from the frame token allowlist.
11 KiB
name, description
| name | description |
|---|---|
| orca-plugin-authoring | Build, debug, test, and publish Orca plugins end to end: app, terminal, and icon themes, syntaxes, language packs, custom editors, HTML or TSX components sidebar panels, palette commands and shortcuts, and Node worker commands that react to workspace and agent events. Use when the user asks to make, change, fix, or ship an Orca plugin, to add a panel, command, theme, editor, or language to Orca, or works in a folder with an orca-plugin.json. Use `orca-cli` only to list, enable, or disable plugins that are already installed. |
Orca Plugin Authoring
ORCA is a placeholder for the executable you resolved in the stub; substitute it before running.
Pass --json to every ORCA plugin command and branch on error.code, not on wording.
Where things live
- Your files: a new folder, ideally its own Git repository, with
orca-plugin.jsonat its root, made byORCA plugin create(never overwrites). Paths are on the machine that runs Orca; with--environmentpass an absolute path on that server. - Types:
ORCA plugin types <dir>(also run bydev watch) writes.orca/types/for every surface; the plugin'stsconfig.jsonextends./.orca/types/tsconfig.json. Never edit.orca/. - Ground truth: the references below match this Orca. Read them instead of guessing.
Pick the shape
Use the lowest execution profile that covers the request; it decides what the user must approve.
| The user asks for | Build (manifest) | Start from |
|---|---|---|
| An app color theme | data; contributes.themes |
--template theme |
| A terminal color palette | data; contributes.terminalThemes |
--template terminal-theme |
| File icons | data; contributes.iconThemes |
--template icon-theme |
| Highlighting for a language | data; contributes.syntaxes (TextMate grammar) |
--template syntax; example orca-gleam-syntax |
| Orca's UI in another language | data; contributes.languagePacks |
--template language-pack |
| A custom view or editor for a file type | sandboxed-ui; contributes.customEditors, optionally newFiles |
--template editor |
| A sidebar panel of lists, forms, buttons, status | sandboxed-ui; panels entry .tsx with "ui": "components" |
--template components; example hello-tsx |
| A sidebar panel needing its own HTML, canvas or libraries | sandboxed-ui; panels entry .html (or .ts/.tsx) |
--template panel |
| A palette command or shortcut for a built-in Orca action | declarative; commands[].action, keybindings |
hand-written; fields in references/manifest.md |
| A command that runs code, storage, secrets, terminal text | trusted-worker; main, commands (no action), capabilities |
example hello-orca |
| A panel backed by its own Node code, storage or settings | trusted-worker; main, a panel, capabilities, settings |
--template worker-panel |
| Settings the user edits in Orca's Settings | contributes.settings and settings:own |
references/manifest.md |
| Reacting to workspace or agent status changes | trusted-worker; main, contributes.events, *:read capability |
example hello-orca |
| Changing or refusing terminal text, workspace creates or agent launches and prompts | trusted-worker; main, contributes.hooks |
--template hook; references/recipes.md |
| A virtual machine environment recipe | declarative; contributes.vmRecipes |
hand-written; fields in references/manifest.md |
| A status bar item (a worker can update it) | declarative; contributes.statusBarItems |
references/recipes.md |
Examples are in examples/plugins/ of github.com/stablyai/orca. Sidebar cards, task sources,
connections, MCP servers and skills are reserved and not buildable yet: say so instead of faking
them. A panel cannot type into a terminal; only a worker
with terminal:send can.
No build step
.ts,.tsx,.mtsand.jsxload as written; transpiling never type-checks, so runnpx tsc -p ..- Panels and frame scripts import only
orca,orca/*and relative files (./todosfindstodos.tsx,todos.ts, thentodos/index.*). A bare package such asreactfails: copy its ESM files in, or bundle with--external:orca --external:'orca/*'(examplehello-components). - A worker
mainis.js,.mjs,.tsor.mts. Bare imports resolve as Node does, but do not commitnode_modules/; bundle npm dependencies.orca/workeris types only:import type.
The loop
ORCA plugin create ./my-plugin --template components --json. Leave out--publisher.- In a background terminal, run
ORCA plugin dev watch ./my-plugin --check --shot ./my-plugin/.orca/shots --jsonand keep reading it (events inreferences/workflow.md). Consent exits3: see Approval. - Edit and save. Each save prints
reloaded, acheckof what each panel drew or threw, and ashotwhosepathis a PNG of the panel exactly as Orca draws it: read the image and fix what looks wrong. Fix everylogerror ([frame] <file>:<line>) andcheckissue. To see a state behind input,ORCA plugin shot <plugin-key> --act '<json>'types and presses first. ORCA plugin test <dir> --jsonafter changes, andORCA plugin check <dir> --jsonbefore you finish (it runs the worker; add states insrc/panel.check.ts, seereferences/workflow.md). For a worker,ORCA plugin dev emit . <event> --data '{...}'fires a test event andORCA plugin dev request . <name> --data '{...}'calls anorca.panels.handlehandler.- To show the user,
ORCA plugin open <plugin-key> --panel <id>. Ctrl-C stops the watch.
Ship
ORCA plugin validate <dir> --jsonuntil it exits0, and show the userORCA plugin inspect <dir> --json: what it contributes and the access it asks for.- Publish only when the user asks; it is public and uses their GitHub identity. Commit and push to
the repository that will own it, set
version, tagv<version>, add theorca-plugintopic, and for a catalog paste whatORCA plugin release-entry <dir> --jsonprints. The Git andghsteps:ORCA skills get orca-cli --reference references/plugins.md.
Approval
Content-only plugins (themes, icons, syntaxes, language packs) load without approval. Anything
that runs code or acts in Orca fails with approval_required (exit 3); error.data lists what it
would be granted and the command with --approve <fingerprint>. Approving grants real access on
the user's machine: show them that list, and re-run with --approve only when they asked for
exactly this plugin and this access. Never approve on their behalf otherwise, and never pass a
fingerprint Orca did not give you. New capabilities or changed commands print a new approval.
plugin_system_disabled: ask the user to click "Turn on plugins" in Settings → Plugins.
Gotchas
engines.orcamust cover the newestSinceyou use (references/manifest.md); components, build-less entries and leaving outpublisherneed>=1.4.246. Ids startingorca-are reserved.update(atom, fn)takes an updater only;set(atom, value)stores a value. Both throw while rendering. Components panels have no hooks and no DOM: state lives in atoms.- Keyed atoms (
atom('draft', '')) survive a hot reload; unkeyed ones and module variables reset.persistvalues must be plain JSON; bumpversion(withmigrate) when the shape changes. - Never poll for the time:
<RelativeTime at={ms} />and{ type: 'relative', at }cells tick. - A save that fails to load keeps the last good render with an inline
file:line:colerror. - No network: requests outside the plugin's files fail. Ship assets and load them relatively.
shell.openExternalandfiles.saveAsneed a press on a settled control; never call on load.- A worker's
mainmustexport default function activate(orca). - A worker save restarts the worker and drops its in-memory state; keep counters and caches you need across saves in
orca.storage. - A plugin holds at most 2,000 files and 50 MiB; each transpiled file 1 MiB.
- Custom editors: sync with
orca.document.session().plugin checkfails on an editor's syntax errors, missing files and refused imports without running it (and warns oneval); test its sync in Node withmockEditorHost({ text })fromorca/testing(replace,conflictNext,flush,edits).
Conditional references
Run ORCA skills get orca-plugin-authoring --reference references/<file>.md and read only what you
need (--references lists them; --full if --reference is rejected).
| Read when | Reference |
|---|---|
Reading dev watch events; shots, open, dev emit; test examples |
references/workflow.md |
The full test kit: mount, mountWorker, mockHost, every act |
references/testing.md |
| A worker panel, storage, settings; agent status; events; hooks; a rich custom editor | references/recipes.md |
Writing a components panel: components, props, atoms, host |
references/components.md |
| Calling the host from a worker, frame or panel; capabilities | references/host-api.md |
| Subscribing to worker, frame or panel events and their payloads | references/events.md |
Writing or fixing orca-plugin.json, choosing engines.orca |
references/manifest.md |
Running any ORCA plugin command you have not used in this task |
references/cli.md |