Files
orca/docs/reference
NeilandClaude ac8c1125f0 feat(plugins): hooks that can change or block terminal sends and workspace creation (#37287)
* plugins: contributes.hooks runtime with terminal.send and workspace.create hooks

Workers register orca.hooks.on(hook, (event, next) => ...). Orca runs listed
plugins in order before it acts: next(event) continues with allowed fields
changed, { deny } stops, nothing passes. A plugin past its 2 s deadline, or
one that throws, crashes or is disabled, counts as passing and is logged with
plugin, hook and duration. First hooks: terminal.send (runtime sendTerminal),
workspace.create.before (IPC and runtime creates, folders included) and
observe-only workspace.create.after. orca/testing mountWorker gains
hooks.fire. Needs main + trusted-worker and engines.orca >=1.4.248.

Co-Authored-By: Claude <noreply@anthropic.com>

* plugins: keep hook plugins' workers started; bound start-up separately from the hook deadline

Workers of enabled plugins that list hooks start as soon as they are approved
and are never idle-reaped; crash restarts follow the manager's policy. A hook
waits up to the worker ready timeout for start-up, then gives the handler its
full 2 s, so a cold worker no longer lets the first hooked action through.

Co-Authored-By: Claude <noreply@anthropic.com>

* plugins: give hook workers their own soft cap instead of the active-worker cap

Always-running hook workers no longer hold slots of the shared 5-worker cap, so
many hook plugins cannot starve the rest. They have a soft cap of 16; past it a
hook worker waits for another to stop, logged once.

Co-Authored-By: Claude <noreply@anthropic.com>

* test(plugins): type the hook warmer's ensureWorker mock

* plugins: address hook review: ordering, human input, overflow, revalidation, folder creates

- Hook workers past the soft cap start as overflow (logged once) instead of
  waiting, so reconciliation, disable and uninstall never hang.
- Writes to one terminal stay in order while terminal.send decides, so a later
  Enter cannot submit the previous line.
- terminal.send runs only for programmatic sends (main, plugins, the CLI);
  desktop, mobile and legacy client input is a person's typing.
- Text a hook rewrote passes the AI Vault resume check again.
- Project-group folder workspace creates (RPC, agent launch, window) run the
  workspace.create hooks through one boundary.
- A decision from a plugin disabled or changed while it ran is discarded.

Co-Authored-By: Claude <noreply@anthropic.com>

* test(plugins): drive hook start-up timing with fake-timer deferreds, no real sleeps

Co-Authored-By: Claude <noreply@anthropic.com>

* plugins: only the hook decision holds a terminal's write order

A delivery that waits (a permission prompt, the launch composer) no longer
blocks later writes, and a person's input, interrupts and query replies never
wait behind a pending decision.

Co-Authored-By: Claude <noreply@anthropic.com>

* plugins: hook DX: onError deny, denied_by_plugin, a Hooks reference, --template hook

- contributes.hooks[].onError: "deny" makes a throw, timeout, crash or bad
  answer refuse the action, naming the plugin; the default still passes.
  orca/testing mountWorker honours it, and mockHost answers fire-and-forget
  methods (result { ok: true }) with success by default.
- A plugin denial reaches RPC clients as denied_by_plugin with the plugin and
  reason, and the CLI no longer suggests a retry for it.
- The skill's host-api reference gains a generated Hooks section (event, what
  next may change, stop result); the recipe passes sends through unchanged and
  warns against awaiting other calls before deciding.
- orca plugin create --template hook: a worker-only terminal.send guard that
  fails closed, with a test.

Co-Authored-By: Claude <noreply@anthropic.com>

* plugins: regenerate hook docs on main; bind the plugin runtime and its hook runner in one call

Keeps main-process-plugins.ts under 300 lines now that status bar items landed.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-11-01 21:12:57 -08:00
..