Agent orchestration plugin for OpenCode. Version 0.0.1-beta.2.
This is a beta release and its configuration and behavior may change.
The plugin adds a Commander and specialist agents, background-task tracking and compaction, session tools, built-in MCP definitions, and commands for common maintenance workflows.
- Node.js
>=20.0.0. - OpenCode with plugin support.
pnpmis recommended for development and package management.- Optional host-managed MCPs, if you want to provide additional services. The plugin works without
them, preserves user-registered MCPs, and can grant agent permissions when
mcpsis configured.
Install the beta package:
pnpm add @mrjmpl3/opencode-dictatorship@betaInstall the bundled skills so OpenCode discovers them at startup. The package ships TypeScript source, so this step requires Bun:
bunx @mrjmpl3/opencode-dictatorship installThe default target is ~/.config/opencode/skills. Use the --project flag to install into the
current project's .opencode/skills instead. Reinstalling refreshes plugin-managed copies; a
copy whose managed marker line was removed is user-owned and never overwritten.
Register it in the project's opencode.json:
{
"plugin": ["@mrjmpl3/opencode-dictatorship"]
}For local development, clone the repository, run pnpm install, and use a file:// plugin entry:
{
"plugin": ["file:///absolute/path/to/opencode-dictatorship"]
}Create opencode-dictatorship.json in the project directory, or in
~/.config/opencode/ for a global configuration:
{
"$schema": "https://raw.githubusercontent.com/MrJmpl3/opencode-dictatorship/main/schema/opencode-dictatorship.schema.json",
"preset": "default",
"agents": {
"commander": { "model": "provider/model-id" },
"operative": { "model": "provider/model-id" }
}
}The model IDs are provider-specific. Replace the example values with models available to your
OpenCode installation. The active Commander is commander-default unless preset is changed.
Configuration resolution checks these locations in order:
<project-directory>/opencode-dictatorship.json~/.config/opencode/opencode-dictatorship.json
The loader uses the first existing file that parses and passes schema validation. If a project-local file is invalid, it continues with the global file. If no valid file is found, it uses built-in defaults. The published JSON Schema documents the accepted shape.
| Option | Default | Purpose |
|---|---|---|
preset |
"default" |
Selects the active named preset. |
presets |
unset | Defines named agent configurations. |
agents |
unset | Applies an override to a base agent across presets. |
disabled_agents |
["surveillance"] |
Disables agents by base name or suffixed name. Commander cannot be disabled. |
setDefaultAgent |
true |
Sets OpenCode's default agent to the active Commander when enabled. |
disabled_mcp_internal |
unset | Disables built-in context7, gh_grep, or websearch. It does not control optional host-managed MCPs. |
preemptive_compaction |
enabled | When enabled and the relevant hooks are eligible, preserves background-task state across compaction and may autocontinue active work. |
Agent overrides support model, temperature (0 to 2), variant, mcps, prompt,
appendPrompt, options, displayName, and permission. orchestratorPrompt is not supported
on Commander overrides. Permissions use ask, allow, or deny and can be set per tool.
Each entry in presets creates a complete set of suffixed agents, such as
commander-economy and operative-economy. Set preset to choose the default Commander. Bare
agents.<name> overrides take precedence over the corresponding preset override.
{
"preset": "economy",
"presets": {
"economy": {
"commander": { "model": "provider/fast-model" },
"operative": { "model": "provider/fast-model" }
},
"quality": {
"commander": { "model": "provider/strong-model" }
}
}
}The plugin defines optional built-in MCPs: context7 for library documentation, gh_grep for
repository code search, and websearch for web search. They can be disabled with
disabled_mcp_internal. Credentials and server availability are handled by the relevant MCP
configuration.
Optional host-managed MCPs are supported but are not required. The plugin preserves user-registered
MCPs, can grant agents access through mcps when configured, and adds no provider-specific prompt
or availability gate.
Cross-CLI delegation is experimental and its behavior and configuration may change.
Herdr is required for cross-CLI delegation. There is no fallback to spawning external CLIs directly
(claude -p, agy -p, codex exec). Every cross-CLI lane routes through a Herdr bridge.
A specialist can run against an external CLI instead of an in-process OpenCode subagent. Add a
crossCli override for that agent in opencode-dictatorship.json. The commander then delegates it
with the delegate_cross_cli tool, which launches the external CLI through Herdr as a bridge and
returns the result as the lane text.
{
"agents": {
"operative": { "crossCli": { "backend": "antigravity", "model": "gemini-3.5-flash-medium" } }
}
}Supported backends are claude, antigravity, and codex. Each override takes a model to pass
to the backend at spawn, an optional extraArgs list, and an optional resume mode. A cross-CLI
specialist is not instantiated as a native OpenCode agent, so it uses an available Herdr server
running on the host.
The per-agent crossCli.resume and the top-level crossCli.resume both accept auto, manual,
and off. Resolution per delegation: an explicit resume/conversationId tool arg wins, then the
per-agent crossCli.resume, then the top-level crossCli.resume, then auto. In auto and
manual, delegate_cross_cli remembers the last external conversation id in an on-disk
ConversationStore and re-attaches the lane to it; a resume that lands blocked or unknown retries
once fresh. off always starts fresh.
crossCli.transport selects how the delegate tool spawns an agent. cli (the default) shells out
to the herdr binary per call. socket talks to the Herdr daemon with NDJSON v2.0 over the Unix
socket at $HERDR_SOCKET_PATH or ~/.config/herdr/herdr.sock, keeps a 30s server.ping
heartbeat, and reconnects with capped exponential backoff. Its stop path stays on the CLI, because
the socket protocol exposes no agent-level stop. A third option, direct, skips Herdr and spawns the
external CLI (claude, agy, or codex) straight from the plugin. agy needs a pseudo-TTY, because
agy -p writes empty output when stdout is not a TTY. Resume is deferred in v1, so a direct lane
always starts fresh.
Each delegation defaults to a DEFAULT_CROSS_CLI_TIMEOUT_MS of 600000 ms (10 min), overridable with
timeoutMs. The top-level crossCli.maxLaneMs default 1_800_000 (30 min) is a wall-clock safety
ceiling for long lanes.
Example combining a socket transport and an auto-resume specialist:
{
"crossCli": { "transport": "socket" },
"agents": {
"operative": {
"crossCli": { "backend": "antigravity", "model": "gemini-3.5-flash-medium", "resume": "auto" }
}
}
}This section describes the user-visible decisions behind the plugin. It is not a replacement for the configuration reference below.
OpenCode loads the plugin, then the plugin resolves configuration from the project file first and
the global file second. It uses the first file that parses and passes PluginConfigSchema; an
invalid project file therefore falls through to a valid global file. If neither file is valid, the
built-in defaults apply. The selected preset, agent overrides, disabled lists, and feature flags
form the effective configuration.
src/index.ts is the package facade and re-exports the runtime assembled in src/plugin/index.ts.
src/plugin/config/loader.ts and src/shared/config/schema/plugin-config.ts load and validate
configuration. The registry in src/shared/config/agent-registry.ts defines names, categories,
lanes, and write capability. src/plugin/agents/registry.ts maps specialist names to factories,
while src/plugin/agents/commander/orchestrator.ts builds Commander variants. A preset creates
suffixed agents such as commander-economy and operative-economy. Each definition receives its
configured model when available; model selection remains provider-specific. Commander is always
protected, and unavailable or disabled specialists are not delegated to.
Commander classifies the request by intent, chooses a task category and candidate specialist, then
checks the effective agent name, disabled agents, permissions, and lane rules. It can keep a task
in the foreground for an inline result or dispatch it through the background task mechanism when
parallel or long-running work is appropriate. The routing descriptions are generated by
buildAgentDescriptions in
src/plugin/agents/commander/orchestrator-prompt/agent-descriptions.ts.
| Path | Choose it for | Lane |
|---|---|---|
recon |
Codebase discovery and broad symbol or file searches | Read-only |
intelligence |
Current library, API, version, or unfamiliar external behavior | Read-only |
strategist |
High-risk architecture, trade-offs, or persistent debugging | Read-only |
operative |
Bounded non-trivial implementation | Writable |
designer |
UI, UX, responsive, interaction, or visual work | Writable |
surveillance |
Images, screenshots, PDFs, and diagrams | Read-only |
auditor, examiner, sentinel, warden |
Maintainability, behavior, operations, or security review | Read-only |
inquisitor, dissenter |
Critical finding validation or idea validation | Read-only |
Read-only lanes investigate and report. Writable lanes may edit files. This split lets a user ask for evidence before an edit and keeps visual or security judgments with the relevant specialist.
Specialists return the public LaneResult shape from src/shared/contracts/lane-result.ts:
status, summary, optional evidence, optional payload, and optional nextSteps. The task
lifecycle adapts it with laneResultToContract from src/plugin/agents/shared/prompts.ts into the
internal PlanContractRegistry in src/plugin/background-tasks/shared/contract.ts.
The normal path is:
PLAN -> EXECUTE -> VERIFY
Plans declare criteria, dependencies, ownership, and a retry budget. Execution can return a
completed, blocked, failed, or skipped lane. Acceptance requires evidence for implemented or
returned work. Verification must map evidence to every declared criterion and cannot leave
remaining work. A failed or rejected lane becomes needs-rework or blocked; retries must add
changed scope or evidence and stop when the budget is exhausted. If a required agent is disabled,
missing, unauthorized, or cannot produce a valid result, the route fails closed and reports the
unavailable or blocked state instead of pretending it was verified.
Background launches are recorded by BackgroundJobBoard and
src/plugin/background-tasks/hooks/task-lifecycle.ts. A launch receives a task session ID and a
stable alias that can be used as task_id for an allowed reuse or recovery. Terminal results are
fed back to the parent session and, when applicable, to PlanContractRegistry; cancellation marks
a lane non-resumable. Running lanes cannot receive duplicate work, cancelled lanes cannot be
resumed, and an alias that is no longer known fails instead of silently creating a new session.
Idle reconciliation can close a stale running lane, and terminal sessions are reconciled once.
idle, completed, and verified describe different things: task lifecycle completion does not
prove that contract criteria and evidence passed verification.
COMMANDER_PROMPT_SENTINEL and variant sentinels let createSystemTransformHook detect an
already-injected prompt and avoid duplicate or conflicting Commander identity blocks. If a custom
prompt is supplied, it is used as the Commander prompt; otherwise the generated prompt is rebuilt
with the effective preset and enabled agents. A custom configured description is untrusted content:
it cannot override the Commander boundary, contract rules, evidence requirements, retry budget, or
unavailable-agent disclosure. Custom orchestratorPrompt is rejected for Commander by the schema.
- When
preemptive_compactionis enabled and its hooks are eligible, compaction preserves active background state and autocontinue may resume active work. session_list,session_read, andsession_searchinspect sessions, andcancel_taskstops tracked background work./code-audit,/propose-structure,/agents-md, and/readmeare registered commands. User-defined commands with the same name take precedence.- Optional host-managed MCPs are supported but not required. The plugin preserves user-registered
servers and can grant agent access when configured.
context7,gh_grep, andwebsearchare optional built-in MCPs controlled bydisabled_mcp_internal.
| Request | First path | Why |
|---|---|---|
| "Find where this behavior is implemented" | recon |
Discovery before a decision or edit |
| "Check the current SDK/API behavior" | intelligence |
External documentation and versions |
| "Choose between two architectural fixes" | strategist |
Trade-off analysis before implementation |
| "Implement this bounded change" | operative |
Writable implementation lane |
| "Improve this component's interaction" | designer |
Visual and interaction ownership |
| "Review this diff for security or retries" | warden or sentinel |
Security or operations lens |
| "Analyze this screenshot or PDF" | surveillance |
Media analysis lane |
| "Validate the whole change" | examiner plus the relevant review lane |
Behavior and focused review |
This high-level map lists public, decision-defining architecture surfaces and behavioral boundaries. Private helpers and implementation paths may change without notice.
| Surface | Location |
|---|---|
| Plugin facade | src/index.ts (package main and exports) |
| Plugin runtime assembly | src/plugin/index.ts |
| Plugin domains | src/plugin/{config,agents,background-tasks,bootstrap,integrations,commands,tools,infrastructure}/ |
| Config resolution and schema | src/plugin/config/ and src/shared/config/ |
| Agent registry and route categories | src/shared/config/agent-registry.ts |
| Commander prompt and routing | src/plugin/agents/commander/ |
| Public result boundary | src/shared/contracts/lane-result.ts |
| Acceptance contract boundary | src/plugin/background-tasks/shared/contract.ts |
| Background lifecycle boundary | src/plugin/background-tasks/ |
| Bun CLI entrypoint | src/cli/index.ts (package bin) |
| CLI implementation | src/cli/{install,host-config,skills,sanitize}/ |
| Shared filesystem and skill content | src/shared/{fs.ts,skills/} |
Example permission override:
{
"agents": {
"recon": {
"permission": { "bash": "deny", "edit": "deny", "read": "allow" }
}
}
}The current roster is:
| Agent | Role | Lane |
|---|---|---|
commander |
Orchestration, routing, synthesis | Orchestrator |
recon |
Codebase discovery | Read-only |
strategist |
Architecture and debugging strategy | Read-only |
intelligence |
External library and API research | Read-only |
operative |
Implementation | Writable |
designer |
UI and UX work | Writable |
surveillance |
Visual and media analysis | Read-only, disabled by default |
auditor |
Maintainability review | Read-only |
inquisitor |
Validation of critical findings | Read-only |
examiner |
Behavior and regression review | Read-only |
sentinel |
Reliability and operations review | Read-only |
warden |
Security review | Read-only |
dissenter |
Idea validation | Read-only |
The plugin registers these commands unless a user-defined command with the same name already exists:
/code-audit/propose-structure/agents-mdgenerates or updates hierarchical AGENTS.md files by applying the bundledinit-deep-in-mrjmpl3-styleskill./readmegenerates or updates the README and its translated variants by applying the bundledreadme-in-mrjmpl3-styleskill.
Both commands rely on bundled skills installed by the CLI installer (see Installation). Each installed file carries a plugin-managed marker line: while the marker is present, reinstalling refreshes the copy, and removing the marker line takes ownership, after which the installer never overwrites that copy.
The plugin registers:
cancel_taskfor cancelling tracked background work.session_list,session_read, andsession_searchfor session inspection.
When preemptive_compaction.enabled is true, the compaction hook can inject active background-task
state into compaction prompts. The autocontinue hook can resume a session only when it is enabled,
its eligibility conditions are met, and active tasks remain. Configure these behaviors with
preemptive_compaction; active tasks alone do not guarantee either behavior.
Background tasks launched through OpenCode's background task mechanism are tracked by the job
board, including lifecycle status, aliases, terminal listeners, and cancellation. The
cancel_task tool operates on a task ID or alias.
pnpm install
pnpm run typecheck
pnpm run test:unit
pnpm run test
pnpm run lint
pnpm run format:check
pnpm run build
pnpm run schema:generatebuild runs tsc --noEmit. test includes coverage; test:unit does not. The plugin runtime is in
src/plugin/, the Bun CLI is in src/cli/, shared config/contracts/filesystem/skills are in
src/shared/, and the package facade is src/index.ts. TypeScript aliases are @plugin/* and
@shared/*. The generated schema remains outside src/ in schema/. Tests live in test/plugin/,
test/cli/, test/shared/, test/integration/, and test/support/.
- No Commander appears: confirm the plugin entry, the selected
preset, and thatsetDefaultAgenthas not been disabled. Commander is protected and cannot be disabled. - An optional host-managed MCP is unavailable: the plugin works without it. If you registered
one, check OpenCode's MCP configuration and the effective agent's
mcpspermissions. - Surveillance does not receive images: the plugin does not route image attachments. Delegate
media analysis to
surveillanceby adding it back fromdisabled_agents, giving it a vision-capable model, and choosing a model that accepts image parts. - A command is missing: check whether OpenCode already has a command with that name; user commands take precedence.
- Configuration is ignored: check the project-local file first, then the global file, and validate it against the published schema.
MIT