Dynamic multi-agent workflows for OpenCode, implemented as a shareable OpenCode plugin.
This plugin brings a Claude Code-style dynamic workflow pattern to OpenCode: a main agent can design a workflow, then the plugin runs bounded worker sessions in parallel or sequential phases, collects their outputs, optionally synthesizes each phase, and returns a concise report.
The implementation intentionally uses a safe JSON DSL instead of executing arbitrary model-generated JavaScript.
workflow_runtool for running JSON-defined multi-agent workflowsworkflow_list,workflow_show, andworkflow_run_savedtools for saved workflows- Automatic
/workflowcommand injection - Automatic
/deep-researchcommand injection - Parallel and sequential workflow phases
- Optional phase synthesis workers
- Worker recursion protection by disabling workflow tools inside child sessions
- Concurrency and total-agent limits
- Run history persisted to
.opencode/workflows/runs/ - Saved workflow specs persisted to
.opencode/workflows/
- OpenCode 1.15 or newer
- Bun or npm for local development
- At least one configured OpenCode model provider
After the package is published to npm, install it with OpenCode's plugin installer:
opencode plugin opencode-dynamic-workflows --globalUse --force when upgrading an existing install:
opencode plugin opencode-dynamic-workflows --global --forceRestart OpenCode after installation. The installer downloads the npm package and updates your global OpenCode config.
Equivalent manual config:
Note:
opencode plugininstalls npm modules. For local development or unpublished commits, use the local path setup below.
Clone the repository somewhere stable:
git clone https://github.com/vogtsw/opencode-dynamic-workflows.git
cd opencode-dynamic-workflows
bun install
bun run buildThen reference the local path in opencode.json. This is the recommended development install before a release is published to npm:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["/absolute/path/to/opencode-dynamic-workflows"]
}On Windows, use an escaped absolute path:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["D:\\test\\mygithub\\opencode-dynamic-workflows"]
}Build and pack the plugin:
bun install
bun run build
npm packThis creates a file like:
opencode-dynamic-workflows-1.0.0.tgz
Send that .tgz file to another user. They can unpack it or install it into a stable directory, then reference that directory from opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["/absolute/path/to/opencode-dynamic-workflows"]
}This repository includes a GitHub Actions workflow at .github/workflows/publish-npm.yml.
To make every release installable through opencode plugin:
- Create an npm automation token with publish access.
- Add it to the GitHub repository secrets as
NPM_TOKEN. - Bump
package.json'sversion. - Merge the release commit.
- Create and publish a GitHub Release for the matching tag.
When the GitHub Release is published, the workflow runs:
bun install --frozen-lockfile
bun test
bun run build
npm pack --dry-run
npm publish --access public
After npm publish completes, users can install the release with:
opencode plugin opencode-dynamic-workflows --global --forceManual publish flow:
bun install
bun run build
bun test
npm pack --dry-run
npm publishAfter publishing, other users can also install it by adding this to their OpenCode config:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-dynamic-workflows"]
}Check that OpenCode loaded the plugin:
opencode debug configYou should see:
{
"command": {
"workflow": {},
"deep-research": {}
}
}Check that the workflow tools are available to an agent:
opencode debug agent buildYou should see these tools:
workflow_run
workflow_list
workflow_run_saved
workflow_show
Run a dry-run smoke test:
opencode run --model provider/model "Call the workflow_run tool once with dryRun=true and a one-task workflow spec."If the plugin is working, the tool output includes:
# Dry Run:
Asks the active model to design a workflow spec and call workflow_run.
Example:
/workflow audit this repository for risky file writes and missing tests
Asks the active model to split a research question into multiple investigation angles, run them as a workflow, and synthesize the findings.
Example:
/deep-research what is the best migration path from library A to library B in this codebase?
Runs a workflow from a JSON spec.
| Argument | Type | Description |
|---|---|---|
goal |
string | Workflow goal |
spec |
string | JSON workflow spec. If omitted, a default workflow is generated from goal. |
concurrency |
number | Max concurrent worker sessions. Default 4, max 16. |
maxAgents |
number | Max total worker and synthesis sessions. Default 100, max 1000. |
saveAs |
string | Save the spec for later reuse under this name. |
dryRun |
boolean | Validate and print the plan without running workers. |
agent |
string | Default OpenCode agent for worker sessions. |
model |
string | Default model in provider/model format. |
Lists saved workflow specs and recent run records.
Shows a saved workflow spec.
Loads a saved workflow by name and runs it.
{
"name": "audit-security",
"goal": "Audit the project for security vulnerabilities",
"phases": [
{
"id": "scan",
"title": "Parallel Scan",
"strategy": "parallel",
"tasks": [
{
"id": "secrets",
"description": "Scan for leaked secrets",
"prompt": "Scan all files for hardcoded API keys and credentials."
},
{
"id": "deps",
"description": "Audit dependencies",
"prompt": "Check dependencies for known security concerns."
}
],
"synthesisPrompt": "Combine the findings, rank them by severity, and note conflicts."
},
{
"id": "remediate",
"title": "Sequential Remediation",
"strategy": "sequential",
"tasks": [
{
"id": "plan",
"description": "Create fix plan",
"prompt": "Based on the scan results, create a prioritized remediation plan."
},
{
"id": "apply",
"description": "Apply fixes",
"prompt": "Implement the remediation plan from the previous step."
}
]
}
]
}| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Workflow name. Also used when saving specs. |
goal |
string | Yes | Human-readable workflow goal. |
phases |
array | Yes | Ordered list of workflow phases. |
| Field | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Unique phase ID. |
title |
string | No | Human-readable phase title. Defaults to id. |
strategy |
parallel or sequential |
No | Execution strategy. Defaults to parallel. |
tasks |
array | Yes | Tasks in this phase. |
synthesisPrompt |
string | No | Optional prompt for an extra synthesis worker after phase tasks finish. |
| Field | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Unique task ID. |
description |
string | No | Short task description. Defaults to id. |
prompt |
string | Yes | Worker prompt. Make this self-contained. |
agent |
string | No | OpenCode agent override for this task. |
model |
string | No | Model override in provider/model format. |
Saved workflow specs:
.opencode/workflows/<name>.json
Run records:
.opencode/workflows/runs/<run-id>.json
The path is relative to the OpenCode worktree used by the current session.
- The plugin does not execute arbitrary model-generated JavaScript.
- The workflow language is JSON only.
- Worker sessions get workflow tools disabled to reduce accidental recursion.
concurrencyis clamped to1..16.maxAgentsis clamped to1..1000.- Saved workflow names are sanitized before writing files.
- Task failures are captured in the report instead of crashing the whole run when possible.
Install dependencies:
bun installBuild:
bun run buildTest:
bun testPackage dry run:
npm pack --dry-runsrc/
commands.ts Injects /workflow and /deep-research commands
index.ts OpenCode plugin entrypoint
persistence.ts Saved specs and run records
report.ts Markdown report rendering
runner.ts Worker-session orchestration
spec-parser.ts JSON DSL validation and normalization
tools.ts OpenCode tool definitions
types.ts Shared TypeScript types
tests/
*.test.ts Unit tests
dist/
*.js Built plugin JavaScript used by OpenCode
MIT
{ "$schema": "https://opencode.ai/config.json", "plugin": ["opencode-dynamic-workflows"] }