Skip to content

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:

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:

sh
/run-workflow quick-fix "Fix the login button not responding on mobile"

Weave will:

  1. Switch to shuttle and inject the fix prompt with your goal
  2. When Shuttle signals completion, automatically switch to weft for review
  3. 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:

LocationScopeDescription
.opencode/workflows/ProjectShared with your team via version control
~/.config/opencode/workflows/UserYour 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:

FieldTypeRequiredDescription
namestringYesUnique identifier — lowercase alphanumeric with hyphens (e.g., "quick-fix")
descriptionstringNoHuman-readable summary of what the workflow does
versionnumberYesSchema version — currently always 1
stepsarrayYesOrdered list of steps (at least one)

Step Schema

Each step in the steps array defines one stage of the pipeline:

FieldTypeRequiredDescription
idstringYesUnique step ID — lowercase alphanumeric with hyphens
namestringYesHuman-readable step name
typestringYesStep execution type — see Step Types
agentstringYesAgent to activate for this step (e.g., "shuttle", "weft", or a custom agent)
promptstringYesPrompt template — supports template variables
completionobjectYesHow to detect step completion — see Completion Methods
artifactsobjectNoDeclare inputs/outputs for context threading — see Artifacts
on_rejectstringNoGate steps only — "pause" (default) or "fail"

Step Types

Each step has a type that determines how it executes:

TypeDescriptionUser InputAuto-Advances
autonomousAgent works independently until signaling completionNoYes
interactiveAgent works with user collaborationYesWhen user confirms
gateAgent produces an APPROVE/REJECT verdictNoOn 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.

jsonc
{
  "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.

jsonc
{
  "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).

jsonc
{
  "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:

MethodDescriptionUse With
agent_signalAgent signals it's done (detected automatically)Autonomous coding/build steps
user_confirmUser confirms the step is completeInteractive review/discussion steps
plan_createdA plan file is created at .weave/plans/{plan_name}.mdPlanning steps
plan_completeAll checkboxes in a plan file are checkedImplementation steps
review_verdictAgent responds with [APPROVE] or [REJECT]Gate/review steps

Plan-Based Completion

For plan_created and plan_complete, specify the plan name:

jsonc
{
  "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:

jsonc
{
  "completion": {
    "method": "user_confirm",
    "keywords": ["ship it", "looks good", "approved"]
  }
}

Template Variables

Step prompts support template variables using double-brace syntax ({{namespace.key}}):

VariableDescriptionExample 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}}.

jsonc
{
  "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:

jsonc
{
  "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:

jsonc
// 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:

jsonc
// 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:

jsonc
// 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

sh
/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:

KeywordWhat It Does
workflow pause or pause workflowPauses the workflow at the current step
skip step or workflow skipSkips the current step and advances to the next
abort workflow or workflow abortCancels the workflow entirely
workflow statusShows 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:

jsonc
{
  "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:

jsonc
{
  "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:

sh
/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:

jsonc
// 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:

jsonc
{
  "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:

sh
/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:

jsonc
{
  "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:

sh
/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

Released under the MIT License.