Workflows
Workflows let you define reusable, multi-step agent pipelines as JSONC files. Each step specifies which agent to use, what prompt to give it, and how to detect completion — Weave handles the rest, automatically advancing through steps and threading context between them.
Think of workflows as codified processes: "fix a bug and review it", "plan a feature, implement it, build it, review it". Instead of manually orchestrating agents, you define the pipeline once and run it with a single command.
Quick Start
1. Create a workflow file at .opencode/workflows/quick-fix.jsonc:
{
"name": "quick-fix",
"description": "Fix a bug and get it reviewed",
"version": 1,
"steps": [
{
"id": "fix",
"name": "Implement the fix",
"type": "autonomous",
"agent": "shuttle",
"prompt": "Fix the following issue: {{instance.goal}}. Identify the root cause, implement the fix, and write a test to prevent regression. Signal completion when done.",
"completion": {
"method": "agent_signal"
}
},
{
"id": "review",
"name": "Code review",
"type": "gate",
"agent": "weft",
"prompt": "Review the fix for: {{instance.goal}}. Verify the root cause was correctly identified, the fix is minimal and correct, and test coverage is adequate. Respond with [APPROVE] or [REJECT] with feedback.",
"completion": {
"method": "review_verdict"
},
"on_reject": "pause"
}
]
}2. Run it:
/run-workflow quick-fix "Fix the login button not responding on mobile"Weave will:
- Switch to
shuttleand inject the fix prompt with your goal - When Shuttle signals completion, automatically switch to
weftfor review - If Weft approves — workflow completes. If Weft rejects — workflow pauses so you can address feedback.
Where Workflows Live
Weave discovers workflow files from two locations:
| Location | Scope | Description |
|---|---|---|
.opencode/workflows/ | Project | Shared with your team via version control |
~/.config/opencode/workflows/ | User | Your personal workflow library |
Files must have a .jsonc or .json extension. Project workflows override user workflows with the same name.
Workflow Definition Schema
A workflow file contains a single JSON object with these top-level fields:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Unique identifier — lowercase alphanumeric with hyphens (e.g., "quick-fix") |
description | string | No | Human-readable summary of what the workflow does |
version | number | Yes | Schema version — currently always 1 |
steps | array | Yes | Ordered list of steps (at least one) |
Step Schema
Each step in the steps array defines one stage of the pipeline:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique step ID — lowercase alphanumeric with hyphens |
name | string | Yes | Human-readable step name |
type | string | Yes | Step execution type — see Step Types |
agent | string | Yes | Agent to activate for this step (e.g., "shuttle", "weft", or a custom agent) |
prompt | string | Yes | Prompt template — supports template variables |
completion | object | Yes | How to detect step completion — see Completion Methods |
artifacts | object | No | Declare inputs/outputs for context threading — see Artifacts |
on_reject | string | No | Gate steps only — "pause" (default) or "fail" |
Step Types
Each step has a type that determines how it executes:
| Type | Description | User Input | Auto-Advances |
|---|---|---|---|
autonomous | Agent works independently until signaling completion | No | Yes |
interactive | Agent works with user collaboration | Yes | When user confirms |
gate | Agent produces an APPROVE/REJECT verdict | No | On approve; pauses/fails on reject |
Autonomous Steps
The agent receives the prompt and works until it signals completion. Use for tasks like coding, building, or running tests.
{
"id": "implement",
"name": "Implement the feature",
"type": "autonomous",
"agent": "shuttle",
"prompt": "Implement: {{instance.goal}}",
"completion": { "method": "agent_signal" }
}Interactive Steps
The agent works with the user — asking questions, presenting options, waiting for feedback. The step completes when the user confirms they're satisfied.
{
"id": "review-plan",
"name": "Review the plan with user",
"type": "interactive",
"agent": "shuttle",
"prompt": "Present the plan at {{artifacts.plan_path}} for: {{instance.goal}}. Discuss any changes with the user.",
"completion": { "method": "user_confirm" }
}Gate Steps
The agent reviews work and produces a verdict. If it approves, the workflow advances. If it rejects, the workflow pauses (or fails, depending on on_reject).
{
"id": "security-review",
"name": "Security audit",
"type": "gate",
"agent": "warp",
"prompt": "Audit all changes for: {{instance.goal}}. Respond with [APPROVE] or [REJECT].",
"completion": { "method": "review_verdict" },
"on_reject": "pause"
}Completion Methods
The completion.method field tells Weave how to detect when a step is done:
| Method | Description | Use With |
|---|---|---|
agent_signal | Agent signals it's done (detected automatically) | Autonomous coding/build steps |
user_confirm | User confirms the step is complete | Interactive review/discussion steps |
plan_created | A plan file is created at .weave/plans/{plan_name}.md | Planning steps |
plan_complete | All checkboxes in a plan file are checked | Implementation steps |
review_verdict | Agent responds with [APPROVE] or [REJECT] | Gate/review steps |
Plan-Based Completion
For plan_created and plan_complete, specify the plan name:
{
"completion": {
"method": "plan_created",
"plan_name": "{{instance.slug}}"
}
}The plan_name supports template variables — {{instance.slug}} is derived from the user's goal, making each workflow instance produce a uniquely named plan.
Custom Confirm Keywords
For user_confirm steps, you can optionally specify custom keywords that trigger confirmation:
{
"completion": {
"method": "user_confirm",
"keywords": ["ship it", "looks good", "approved"]
}
}Template Variables
Step prompts support template variables using double-brace syntax ({{namespace.key}}):
| Variable | Description | Example Value |
|---|---|---|
{{instance.goal}} | The user's goal for this workflow run | "Add OAuth2 support" |
{{instance.slug}} | URL-safe slug derived from the goal | "add-oauth2-support" |
{{artifacts.X}} | Value of artifact X from a previous step | ".weave/plans/add-oauth2-support.md" |
{{step.name}} | Current step's display name | "Implement the feature" |
{{step.id}} | Current step's ID | "implement" |
Variable Resolution
Unrecognised variables (unknown namespaces or instance/step keys) are left as-is in the rendered prompt. Missing artifact references — where the artifact hasn't been produced yet — render as "(not yet available)".
Artifacts
Steps can declare inputs and outputs to create a data-flow between steps. When a step produces an artifact, subsequent steps can reference it via {{artifacts.name}}.
{
"id": "plan",
"name": "Create plan",
"type": "autonomous",
"agent": "pattern",
"prompt": "Create a plan for: {{instance.goal}}. Save it to .weave/plans/{{instance.slug}}.md",
"completion": {
"method": "plan_created",
"plan_name": "{{instance.slug}}"
},
"artifacts": {
"outputs": [
{ "name": "plan_path", "description": "Path to the generated plan file" }
]
}
}A later step can consume it:
{
"id": "implement",
"name": "Execute the plan",
"type": "autonomous",
"agent": "shuttle",
"prompt": "Execute the plan at {{artifacts.plan_path}} for: {{instance.goal}}.",
"completion": { "method": "plan_complete", "plan_name": "{{instance.slug}}" },
"artifacts": {
"inputs": [
{ "name": "plan_path", "description": "Path to the plan to execute" }
]
}
}Using Custom Agents in Workflows
Workflows can reference any agent — built-in or custom. Define your custom agent in the Weave config, then use its name in a workflow step's agent field.
For example, if you have a custom db-migrate agent:
// In weave.jsonc (config)
{
"custom_agents": {
"db-migrate": {
"display_name": "DB Migration",
"model": "anthropic/claude-sonnet-4",
"prompt": "You are a database migration specialist...",
"category": "specialist"
}
}
}Reference it in a workflow:
// In .opencode/workflows/migrate.jsonc
{
"name": "migrate",
"description": "Generate and review database migrations",
"version": 1,
"steps": [
{
"id": "generate",
"name": "Generate migration",
"type": "autonomous",
"agent": "db-migrate",
"prompt": "Generate a database migration for: {{instance.goal}}",
"completion": { "method": "agent_signal" }
},
{
"id": "review",
"name": "Review migration",
"type": "gate",
"agent": "weft",
"prompt": "Review the database migration for: {{instance.goal}}. Check for data loss risks, rollback safety, and index impact.",
"completion": { "method": "review_verdict" },
"on_reject": "pause"
}
]
}Using Custom Skills in Workflows
Custom skills integrate with workflows through the agents they're assigned to. When a workflow step activates an agent, that agent carries all its configured skills.
Assign skills to agents in your config — the workflow steps will automatically benefit:
// In weave.jsonc
{
"agents": {
"shuttle": {
"skills": ["testing", "company-standards"]
}
},
"custom_agents": {
"db-migrate": {
"skills": ["database-patterns"],
"prompt": "You are a database migration specialist..."
}
}
}When the workflow activates shuttle or db-migrate, each agent gets its skills prepended to the prompt — no additional workflow configuration needed.
Running Workflows
Start a Workflow
/run-workflow <workflow-name> "<goal>"The goal is a free-text description of what you want to accomplish. It gets injected into step prompts via {{instance.goal}}.
Managing a Running Workflow
While a workflow is running, you can control it using natural language keywords in chat:
| Keyword | What It Does |
|---|---|
workflow pause or pause workflow | Pauses the workflow at the current step |
skip step or workflow skip | Skips the current step and advances to the next |
abort workflow or workflow abort | Cancels the workflow entirely |
workflow status | Shows current progress, step states, and goal |
These are detected as keywords in your messages — they don't need to be exact. For example, "can you do a workflow pause please" works.
Resuming a Paused Workflow
When a workflow is paused (either manually or by a gate rejection), resume it by running /run-workflow again. The workflow picks up from where it left off — you don't need to re-specify the workflow name or goal.
Workflow Lifecycle
A running workflow moves through these states:
running → completed (all steps done)
running → paused (gate rejected, or user paused)
running → failed (gate rejected with on_reject: "fail")
running → cancelled (user aborted)
paused → running (resumed via /run-workflow)Workflow State
Active workflow state is stored at .weave/workflows/<instance-id>/state.json. Each instance tracks:
- Current step and its status
- Completed steps with summaries
- Accumulated artifacts
- Overall workflow status
Disabling Workflows
Disable specific workflows via the config:
{
"workflows": {
"disabled_workflows": ["secure-feature"]
}
}Disabled workflows won't appear in the /run-workflow command.
Example: Debug & Triage
A workflow for investigating bugs before fixing them. Unlike jumping straight to a fix, this pipeline explores the codebase first, presents findings for the user to confirm the diagnosis, then implements and verifies the fix:
{
"name": "debug-triage",
"description": "Investigate a bug, confirm the diagnosis, then fix it",
"version": 1,
"steps": [
{
"id": "investigate",
"name": "Investigate the issue",
"type": "autonomous",
"agent": "thread",
"prompt": "Investigate the following issue: {{instance.goal}}. Search the codebase for relevant code paths, recent changes, related tests, and error handling. Identify the likely root cause and any contributing factors. Summarize your findings with file paths and line numbers.",
"completion": { "method": "agent_signal" }
},
{
"id": "triage",
"name": "Triage with user",
"type": "interactive",
"agent": "shuttle",
"prompt": "Present the investigation findings for: {{instance.goal}}. Summarize the likely root cause, affected files, blast radius, and suggested fix approach. Discuss severity and priorities with the user. Confirm the approach before proceeding.",
"completion": { "method": "user_confirm" }
},
{
"id": "fix",
"name": "Implement the fix",
"type": "autonomous",
"agent": "shuttle",
"prompt": "Implement the agreed-upon fix for: {{instance.goal}}. Based on the investigation and triage discussion, apply a minimal, targeted fix. Write a regression test that would have caught this bug.",
"completion": { "method": "agent_signal" }
},
{
"id": "verify",
"name": "Verify the fix",
"type": "autonomous",
"agent": "shuttle",
"prompt": "Run the full test suite to verify the fix for: {{instance.goal}}. Ensure the new regression test passes, no existing tests broke, and the build is clean. Fix any issues before signaling completion.",
"completion": { "method": "agent_signal" }
},
{
"id": "review",
"name": "Review the fix",
"type": "gate",
"agent": "weft",
"prompt": "Review the fix for: {{instance.goal}}. Verify the root cause was correctly addressed, the fix is minimal and doesn't introduce side effects, and test coverage is adequate. Respond with [APPROVE] or [REJECT] with feedback.",
"completion": { "method": "review_verdict" },
"on_reject": "pause"
}
]
}Run it:
/run-workflow debug-triage "Users are seeing 500 errors on the /api/orders endpoint after the last deploy"The workflow investigates first, then pauses for you to confirm the diagnosis before any code is changed — so you're never surprised by the fix direction.
Example: Migration Pipeline
A workflow that uses a custom agent to generate database migrations, then verifies rollback safety. This shows how workflows become powerful when paired with domain specialists that Weave doesn't ship by default:
First, define a custom agent in your config:
// weave.jsonc
{
"custom_agents": {
"db-migrate": {
"display_name": "DB Migration",
"model": "anthropic/claude-sonnet-4",
"prompt": "You are a database migration specialist. You write safe, reversible migrations. Always consider: data preservation, index impact on large tables, backwards compatibility with the previous schema version, and rollback procedures.",
"category": "specialist"
}
}
}Then wire it into a workflow:
{
"name": "migrate",
"description": "Generate, verify, and review a database migration",
"version": 1,
"steps": [
{
"id": "generate",
"name": "Generate migration",
"type": "autonomous",
"agent": "db-migrate",
"prompt": "Generate a database migration for: {{instance.goal}}. Include both the up and down migration. Ensure the down migration fully reverses the up migration without data loss. Follow the project's existing migration conventions.",
"completion": { "method": "agent_signal" }
},
{
"id": "verify-rollback",
"name": "Verify rollback safety",
"type": "autonomous",
"agent": "db-migrate",
"prompt": "Review the migration just generated for: {{instance.goal}}. Verify the down migration correctly reverses all changes. Check for: data loss risks, missing index cleanup, foreign key constraint issues, and large-table locking concerns. Fix any issues found.",
"completion": { "method": "agent_signal" }
},
{
"id": "review",
"name": "Review migration",
"type": "gate",
"agent": "weft",
"prompt": "Review the database migration for: {{instance.goal}}. Check for data loss risks, rollback safety, index impact on large tables, and backwards compatibility. Respond with [APPROVE] or [REJECT] with specific concerns.",
"completion": { "method": "review_verdict" },
"on_reject": "pause"
}
]
}Run it:
/run-workflow migrate "Add a tags column to the projects table with a many-to-many join table"Example: Documentation-First
A workflow that inverts the usual flow — write documentation before writing code, then implement to match. This forces clear thinking about the API surface and user experience before any code exists:
{
"name": "docs-first",
"description": "Write docs first, then implement to match",
"version": 1,
"steps": [
{
"id": "write-docs",
"name": "Write the documentation",
"type": "autonomous",
"agent": "shuttle",
"prompt": "Write documentation for: {{instance.goal}}. Document the public API, expected behavior, configuration options, and usage examples. Write this as if the feature already exists — the implementation will follow. Save the docs following the project's documentation conventions.",
"completion": { "method": "agent_signal" }
},
{
"id": "review-docs",
"name": "Review docs with user",
"type": "interactive",
"agent": "shuttle",
"prompt": "Present the documentation written for: {{instance.goal}}. Walk through the API surface, behavior descriptions, and examples. This is the contract the implementation will follow — discuss any changes with the user before proceeding.",
"completion": { "method": "user_confirm" }
},
{
"id": "implement",
"name": "Implement to match docs",
"type": "autonomous",
"agent": "shuttle",
"prompt": "Implement: {{instance.goal}}. The documentation has already been written — your implementation must match the documented API, behavior, and examples exactly. Write tests that verify the documented behavior. If you find the docs need adjustment, update them to stay in sync.",
"completion": { "method": "agent_signal" }
},
{
"id": "verify",
"name": "Verify docs match implementation",
"type": "gate",
"agent": "weft",
"prompt": "Verify that the implementation of {{instance.goal}} matches its documentation. Check that all documented APIs exist, behave as described, and have the documented configuration options. Verify code examples in the docs actually work. Respond with [APPROVE] or [REJECT] with discrepancies.",
"completion": { "method": "review_verdict" },
"on_reject": "pause"
}
]
}Run it:
/run-workflow docs-first "Add a webhook notification system for order status changes"The interactive docs review step ensures you and the agent agree on what to build before any code is written — catching design issues early when they're cheap to fix.
Tips
Start Simple
Begin with 2-3 step workflows. Add complexity as you learn which patterns work best for your team.
Use Gate Steps for Quality Control
Gate steps with on_reject: "pause" are a natural checkpoint — the workflow pauses so you can address feedback and resume, rather than failing outright.
Combine with Custom Agents
Workflows become especially powerful when combined with custom agents — create domain specialists and wire them into purpose-built pipelines.
See Also
- Custom Agents — define new agents to use in workflow steps
- Skills — inject domain expertise into agents used by workflows
- Workflow Customization — reshape Weave's default delegation behavior
- Configuration Files — where config files live and how they're loaded
