Plugins
Extend ocra with VCS adapters, runtimes, reviewers, rules, tools and listeners.
Everything in ocra is a plugin: the local Git and GitHub adapters, the OpenCode runtime, the correctness, security, performance, docs and agents-md reviewers and the session log ship as built-in plugins. Your plugins use the same contract.
Writing a plugin
A plugin is a module that exports an object as default (or plugin):
// tools/ocra-team-rules.mjs
export default {
name: "team-rules",
configure(ctx) {
ctx.registerRules([
{
path: "services/**",
rule: `Owned by ${ctx.settings.team}: check idempotency keys on every write.`,
},
]);
},
};Register it in .ocra/config.json:
{
"plugins": ["./tools/ocra-team-rules.mjs"],
"pluginSettings": { "team-rules": { "team": "payments" } }
}Plugins are resolved from the repository's own dependencies (package names) or from file paths, resolved from the repository root (they may point outside it: the configuration is yours to trust). Plugins run code, so they load only from a repository's own config in local reviews, never for pull requests or with --no-repo-config.
Lifecycle
| Hook | Runs | On failure |
|---|---|---|
bootstrap(ctx) | All plugins concurrently | Warning; the review continues |
configure(ctx) | In load order | The review stops, naming the plugin |
postConfigure(ctx) | Concurrently, after all registrations | The review stops |
Use bootstrap for work that may fail harmlessly, such as fetching remote settings.
What a plugin can register
| Method | Contributes |
|---|---|
registerVcs(name, factory) | A code host adapter |
registerRuntime(name, factory) | An agent runtime |
registerReviewer(definition) | A reviewer with its own prompt and model tier |
registerRules(rules) | Path-scoped review rules |
registerTool(tool) | A tool reviewers can call, with a Zod input schema |
onEvent(listener) | A listener for every review event (telemetry, notifications). A listener that throws is disabled with one warning; the review continues |
A runtime factory receives the model chains, the environment, the declared providers and, when configured, sampling (temperature, seed); a runtime says what it sends in its sampling property, listing in notApplied what it cannot pass on. A runtime without that property is reported as applying none of it. A task's spec carries the effort its reviewer asks for, and a completion request names its agent (the reviewer of a plan call, or verifier, judge or helper) and effort; both are absent when no effort is configured. A runtime that sends the effort implements appliedTo(agent), returning whether every call of that agent sent it and, in notApplied, the sampling settings those calls left out. A runtime without it is reported as sending no effort, and the run warns once.
Plugins receive only their own settings (ctx.settings), validated by an optional settingsSchema. Registering a name twice, using a reserved tool name, or registering after configure fails with an error naming the plugin.
Security
A plugin runs code. Load plugins only from repositories you trust; to review someone else's branch, run ocra review --no-repo-config, which ignores the repository's config and plugins. In CI, read configuration from the protected base branch, never from the pull request under review.