Skip to content

Repository files navigation

opencode-dictatorship

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.

Requirements

  • Node.js >=20.0.0.
  • OpenCode with plugin support.
  • pnpm is 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 mcps is configured.

Installation

Install the beta package:

pnpm add @mrjmpl3/opencode-dictatorship@beta

Install the bundled skills so OpenCode discovers them at startup. The package ships TypeScript source, so this step requires Bun:

bunx @mrjmpl3/opencode-dictatorship install

The 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"]
}

Quick configuration

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

Configuration resolution checks these locations in order:

  1. <project-directory>/opencode-dictatorship.json
  2. ~/.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.

Main options

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.

Presets

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" }
    }
  }
}

MCPs and permissions

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

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.

Resume

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.

Transport and timeouts

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" }
    }
  }
}

How the workflow works

This section describes the user-visible decisions behind the plugin. It is not a replacement for the configuration reference below.

1. Intake and configuration

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.

2. Bootstrap and agent construction

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.

3. Commander routing

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.

4. Specialist lanes

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.

5. The contract lifecycle

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.

6. Background tasks

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.

7. Prompts and system hooks

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.

8. Context, tools, and MCPs

  • When preemptive_compaction is enabled and its hooks are eligible, compaction preserves active background state and autocontinue may resume active work.
  • session_list, session_read, and session_search inspect sessions, and cancel_task stops tracked background work.
  • /code-audit, /propose-structure, /agents-md, and /readme are 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, and websearch are optional built-in MCPs controlled by disabled_mcp_internal.

Which path should I choose?

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

High-level maintenance map

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" }
    }
  }
}

Agents

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

Commands

The plugin registers these commands unless a user-defined command with the same name already exists:

  • /code-audit
  • /propose-structure
  • /agents-md generates or updates hierarchical AGENTS.md files by applying the bundled init-deep-in-mrjmpl3-style skill.
  • /readme generates or updates the README and its translated variants by applying the bundled readme-in-mrjmpl3-style skill.

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.

Tools

The plugin registers:

  • cancel_task for cancelling tracked background work.
  • session_list, session_read, and session_search for session inspection.

Context, images, and background tasks

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.

Development

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:generate

build 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/.

Troubleshooting

  • No Commander appears: confirm the plugin entry, the selected preset, and that setDefaultAgent has 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 mcps permissions.
  • Surveillance does not receive images: the plugin does not route image attachments. Delegate media analysis to surveillance by adding it back from disabled_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.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages