
Research
/Security News
PolinRider Spreads Through Compromised GitHub Accounts and Packagist
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.
@beremaran/opencode-agent-tree
Advanced tools
Force opencode to act as an orchestrator: every task is decomposed and delegated to subagents, with user-configurable models per agent.
An opencode plugin that turns the model into an orchestrator: every request is decomposed into subtasks and delegated to subagents via the task tool, never done by the orchestrator itself. You decide which model powers the subagents and which powers the orchestrator.
Renamed: this package was previously published as
opencode-agent-tree. It is now@beremaran/opencode-agent-tree; the old name is deprecated on npm.
general, explore) and any user-defined agents.Two independent enforcement layers:
permission config is set to deny for hands-on tools (edit, bash by default). The model physically cannot do the work itself.If a model ever ignores the directive, layer 2 still makes it delegate: the tools it would need to do the work directly are denied.
This is the directive template rendered into the orchestrator's system prompt (as configured in src/index.ts, orchestratorDirective). The block below is the rendered form with default settings (no instructions); the two runtime substitutions are listed after it.
# Orchestrator Mode (enforced by @beremaran/opencode-agent-tree)
You are the ORCHESTRATOR. You do not do hands-on work. You plan, decompose, delegate, and review.
## Non-negotiable rules
1. Treat every user request as a project: break it into discrete, independently verifiable subtasks before touching anything.
2. Delegate EVERY subtask with the `task` tool to a subagent. Never perform implementation work yourself.
3. You only: plan, write subtask briefs, dispatch agents, review their reports, and summarize results for the user.
4. Dispatch independent subtasks in parallel (multiple `task` calls in a single message). Never run dependent subtasks concurrently — wait for each result before dispatching the next.
5. Give each subagent a complete, self-contained brief: goal, constraints, files involved, verification steps, and exactly what to report back.
6. Review every subagent report. If work is incomplete or wrong, delegate the fix to a subagent — never fix it yourself.
7. Reuse a running subagent via its task_id when follow-up work belongs to the same context.
8. Keep the user informed: report what was delegated to whom, the results, blockers, and the final state.
## Tool discipline
- `task` for all work (mandatory), `todowrite` to track subtasks, `question` only to clarify genuinely ambiguous requests.
- `read`/`glob`/`grep`/`webfetch`/`websearch` only when needed to write a better brief or verify a result.
- Hands-on tools are hard-blocked for you (edit, bash). If a subagent lacks a tool it needs, tell the user instead of doing it yourself.
## Default delegation
- `explore` — codebase research, locating code, understanding existing implementations.
- `general` — implementation, refactoring, testing, and any task without a more specific subagent.
- Prefer the most specialized subagent for each subtask; fall back to `general`.
Two placeholders are substituted at runtime:
| Placeholder | Value |
|---|---|
blockedTools list | The blockedTools option joined with , (default: edit, bash) |
instructions | The instructions option, appended verbatim at the end |
As a local plugin (clone this repo, or point at your own copy):
{
"$schema": "https://opencode.ai/config.json",
"plugin": [
[
"./path/to/src/index.ts",
{ "subagentModel": "anthropic/claude-sonnet-4-6" }
]
]
}
From npm:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@beremaran/opencode-agent-tree", { "subagentModel": "anthropic/claude-sonnet-4-6" }]
}
Config is loaded at startup. Restart opencode after adding the plugin.
| Option | Type | Default | Description |
|---|---|---|---|
subagentModel | string | required | Model for all delegated work, e.g. "anthropic/claude-sonnet-4-6". Must be provider/model format. Agents with an explicit model in opencode.json are never overridden. See Model precedence. |
orchestratorModel | string | agent model, else model | Model for the orchestrator itself. Unconditionally overrides an explicit model on the orchestrator agent. |
orchestratorAgent | string | "Manager" | Which agent acts as the orchestrator. Created by the plugin if it does not exist (it shows up in the agent picker under this name). Built-in agents are left untouched by default; if you name an existing agent, the plugin converts it instead. |
agents | string[] | all subagent/all-mode agents | Only these agents get subagentModel. Disabled agents, primary-mode agents, and the orchestrator itself are filtered out even if listed. |
agentModels | Record<string,string> | {} | Per-agent overrides, wins over subagentModel. Never applies to the orchestrator agent (it is never routed). |
instructions | string | — | Extra rules appended verbatim to the orchestrator system prompt. |
blockedTools | string[] | ["edit", "bash"] | Tools hard-denied to the orchestrator. [] = prompt-only enforcement. Names must match [a-z0-9_-]+. |
The effective model for a delegated subagent is resolved in this order:
model set on the agent in opencode.jsonagentModels[name]subagentModelThe orchestrator is asymmetric:
orchestratorModel unconditionally overrides an explicit model on the
orchestrator agent.agentModels entry keyed to the orchestrator agent name is silently
ignored — the orchestrator is never routed.{
"$schema": "https://opencode.ai/config.json",
"plugin": [
[
"@beremaran/opencode-agent-tree",
{
"subagentModel": "anthropic/claude-sonnet-4-6",
"orchestratorModel": "anthropic/claude-opus-4-5",
"orchestratorAgent": "Manager",
"agents": ["general", "explore", "worker"],
"agentModels": { "explore": "anthropic/claude-haiku-4-5" },
"instructions": "Never delegate more than 3 subtasks at once."
}
]
]
}
At startup the plugin validates the configuration and reports self-contradictory
setups. Invalid configuration raises a config error (logged at error level via
app.log, then rethrown); the remaining cases log a warn message and
continue.
| Condition | Result |
|---|---|
The orchestrator agent named by orchestratorAgent is disabled | Config error |
subagentModel, orchestratorModel, or an agentModels value is not provider/model format (at least one /, non-empty on both sides; further slashes are allowed in the model part) | Config error |
A blockedTools name does not match [a-z0-9_-]+ (lowercase letters, digits, underscore, hyphen) | Config error |
blockedTools includes a directive-dependent tool (task, todowrite, question, read, glob, grep, webfetch, websearch) | Warning: the orchestrator is told to delegate with a tool it cannot use |
A blocked tool's existing permission on the orchestrator agent is overwritten with deny | Warning naming the tool and agent |
An explicit agents list omits both built-in subagents (general, explore) | Warning: routing and the directive diverge |
agents contains a name that is neither a built-in subagent nor an agent in opencode.json | Warning: a phantom agent entry is created (typo protection) |
The plugin enforces behavior through configuration, so its security surface is the configuration it runs with. Only use this plugin with config you control.
instructions is injected verbatim into the orchestrator's system
prompt. An untrusted config can append arbitrary prompt rules that the model
may follow.edit and bash.orchestratorModel can override an explicitly configured model on the
orchestrator agent.See SECURITY.md for how to report vulnerabilities.
task tool is assumed to be available to the orchestrator.>=1.18.11 <2 (per peerDependencies).opencode.json and restart opencode to apply them.Orchestrator "Manager" enabled; subagents -> <subagentModel>.The orchestrator agent "Manager" is disabled is a config error: the agent
named by orchestratorAgent has disable: true. Enable it or choose another
orchestrator.warn level naming the offending tool, agent, or config value; the config is
probably not doing what you intend.orchestratorModel unconditionally overrides it, and
agentModels entries keyed to it are ignored. For subagents, an explicit
model in opencode.json wins over agentModels and subagentModel by
design. See Model precedence.plan agent or another primary anytime.# Orchestrator Mode marker in the
prompt prevents re-appending if the config hook re-runs or opencode reloads
the plugin. This is deliberate.Manager
(visible in the agent picker under that name); no built-in agent is touched.
If you set orchestratorAgent to an existing agent (e.g. build), the plugin
converts that agent into the orchestrator instead.build
agent by default. That conversion is not undone on upgrade — build keeps the
# Orchestrator Mode directive in its prompt because the marker only prevents
re-appending, never removes. Either switch to the new Manager agent, or
remove the directive from build's prompt manually in your opencode config.npm install
npm run check
The plugin is a single config hook (src/index.ts): it mutates the merged opencode config at startup — routing subagent models, denying the orchestrator's hands-on tools, and installing the directive prompt. To verify against a live opencode, run from this repo (its opencode.json is pre-wired) and watch for the startup log line:
Orchestrator "Manager" enabled; subagents -> <subagentModel>
npm login
npm publish
The package ships raw TypeScript (main: src/index.ts) — opencode loads plugins with Bun, so no build step is needed. The repository and author metadata are already set in package.json.
MIT — see LICENSE.
FAQs
Force opencode to act as an orchestrator: every task is decomposed and delegated to subagents, with user-configurable models per agent.
The npm package @beremaran/opencode-agent-tree receives a total of 35 weekly downloads. As such, @beremaran/opencode-agent-tree popularity was classified as not popular.
We found that @beremaran/opencode-agent-tree demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.

Company News
Allow myself to introduce... myself.