How to Build Autonomous Development Workflows with OpenCode CLI Plugins?
I used to babysit my AI coding assistant. Every time I wanted to build something, I had to manually guide it through each step. Research, plan, code, review, fix, repeat. I was the bottleneck, not the AI.
Then I discovered OpenCode CLI’s plugin system. Now my AI runs entire workflows while I grab coffee.
The Problem
Traditional AI workflows require constant supervision. You type a prompt, wait for output, verify it, type another prompt, repeat. This back-and-forth creates a bottleneck.
+-------------------+ +------------------+ +-------------------+| Developer |---->| AI Assistant |---->| Output |+-------------------+ +------------------+ +-------------------+ | | v v+-------------------+ +------------------+| Manual prompt | | Wait for result |+-------------------+ +------------------+ | | v v+-------------------+ +------------------+| Verify output | | Type next prompt |+-------------------+ +------------------+
Developer time: 80% supervising, 20% actual workA Reddit user described this perfectly:
“The plugin system is pretty wild… Custom commands are great for interactive workflow, and beyond that you can get it doing some quite amazing autonomous workflow”
The solution: let plugins orchestrate everything.
Plugin-Based Autonomous Workflows
OpenCode CLI plugins can define skills, agents, and tools that work together without your intervention. Here’s the architecture:
+------------------------+| OpenCode CLI |+------------------------+ | v+------------------------+| Plugin System |+------------------------+ | | | v v v+------+ +------+ +------+|Skills| |Agents| |Tools |+------+ +------+ +------+ | | | v v v+------------------------+| Subagent Sessions |+------------------------+Each component serves a purpose:
- Skills: Named commands like
/build,/review,/deploy - Agents: Specialized AI personas (builder, reviewer, documenter)
- Tools: Functions agents can call (file operations, git, tests)
- Subagents: Isolated execution sessions that run independently
Core Architecture
A plugin is just a configuration file. Here’s a minimal example:
interface PluginConfig { name: string; version: string; skills: SkillDefinition[]; agents: AgentDefinition[]; tools: ToolDefinition[];}
interface SkillDefinition { name: string; description: string; handler: string; // Path to handler module}
interface AgentDefinition { name: string; model: string; // Which LLM to use systemPrompt: string; tools: string[]; // Tool names this agent can use}
interface ToolDefinition { name: string; description: string; parameters: Schema; handler: ToolHandler;}The key insight: skills trigger agents, agents use tools, and everything runs in isolated subagent sessions.
Multi-Model Orchestration
The Reddit discussion revealed a powerful pattern:
“Workflow: custom agent gathers requirements, makes a plan, gets model selections for build, code review, documentation agents. Then: build -> review -> build/document -> review -> document/finish”
This is multi-model orchestration. Different agents handle different stages:
+----------------------+| Requirements Agent | (Haiku - fast, cheap)+----------------------+ | v+----------------------+| Planning Agent | (Sonnet - balanced)+----------------------+ | v +------+------+ | | v v+----------+ +----------+| Build | | Review | (Both Sonnet)| Agent | | Agent |+----------+ +----------+ | | +------+------+ | v+----------------------+| Document Agent | (Haiku - fast docs)+----------------------+Each agent uses the right model for its task. Haiku handles fast, lightweight work. Sonnet handles complex reasoning. Opus handles deep analysis when needed.
Here’s how to configure this:
const agents: AgentDefinition[] = [ { name: "requirements-gatherer", model: "haiku-4.5", systemPrompt: "Extract requirements from user input...", tools: ["read_file", "search_web"] }, { name: "builder", model: "sonnet-4.5", systemPrompt: "Implement the plan step by step...", tools: ["edit_file", "run_tests", "git_commit"] }, { name: "reviewer", model: "sonnet-4.5", systemPrompt: "Review code for bugs, style, security...", tools: ["read_file", "run_linter"] }, { name: "documenter", model: "haiku-4.5", systemPrompt: "Write concise documentation...", tools: ["edit_file"] }];Workflow Execution Pattern
The workflow runs in iteration loops:
+-------------------+| Start Task |+-------------------+ | v+-------------------+| Build Stage |+-------------------+ | v+-------------------+| Review Stage |+-------------------+ | +-----+-----+ | | PASS FAIL | | v v+---------+ +-------------------+| Continue| | Fix & Rebuild |+---------+ +-------------------+ | | +--------+ | v +-------------------+ | Loop until pass | +-------------------+Here’s the skill that triggers this workflow:
async function runWorkflow(task: Task): Promise<WorkflowResult> { // 1. Gather requirements const requirements = await invokeAgent( "requirements-gatherer", task.description );
// 2. Create plan const plan = await invokeAgent("planner", requirements);
// 3. Build -> Review loop let iterations = 0; const maxIterations = 5;
while (iterations < maxIterations) { // Build const buildResult = await invokeAgent("builder", plan);
// Review const reviewResult = await invokeAgent("reviewer", buildResult.code);
if (reviewResult.passed) { // Document await invokeAgent("documenter", buildResult.code); return { success: true, code: buildResult.code }; }
// Fix issues and retry plan = updatePlanWithFeedback(plan, reviewResult.issues); iterations++; }
return { success: false, reason: "Max iterations reached" };}The invokeAgent function creates a subagent session:
async function invokeAgent( agentName: string, input: string): Promise<AgentResult> { // Create isolated session const session = await createSubagentSession({ agent: agentName, input: input, timeout: 60000 // 1 minute max });
// Run and wait for completion const result = await session.execute();
return result;}Isolation via Worktrees
The Reddit comment mentioned a crucial feature:
“Runs in subagent sessions so you can keep coding and get updates as it completes stages” “Can run quite a few in parallel and because they can work in subtrees they are isolated”
Git worktrees provide isolation. Each subagent works in its own directory:
+------------------------+| Main Repository || /workspace/main |+------------------------+ | +------+------+------+ | | | v v v+-------+ +-------+ +-------+|WT-001| |WT-002| |WT-003||Build | |Review| |Doc |+-------+ +-------+ +-------+
Each worktree:- Isolated git state- No conflicts with others- Can be merged independentlyHere’s how worktrees work:
class WorktreeManager { async createWorktree( name: string, baseBranch: string ): Promise<string> { const path = `.claude/worktrees/${name}`;
// Create isolated git worktree await exec(`git worktree add ${path} ${baseBranch}`);
return path; }
async mergeWorktree( worktreePath: string, targetBranch: string ): Promise<void> { // Get changes from worktree const branch = await this.getWorktreeBranch(worktreePath);
// Merge to target await exec(`git checkout ${targetBranch}`); await exec(`git merge ${branch}`);
// Clean up await exec(`git worktree remove ${worktreePath}`); }}This lets you run multiple workflows simultaneously. While one agent builds, another reviews previous work.
Why This Matters
Autonomous workflows change how you work:
Continuous Development
MANUAL: Developer: "Build feature X" -> Wait -> Review -> Fix -> Repeat Time: 2 hours, Developer busy entire time
AUTONOMOUS: Developer: "/build-feature X" -> Coffee break -> Done Time: 2 hours, Developer free for other workParallelization
+------------------------+| 10 workflows in || parallel worktrees |+------------------------+ | v+------------------------+| Developer reviews || all results later |+------------------------+
10x throughput without 10x developer timeQuality Improvement
Iteration loops catch more bugs:
Manual review: 1 pass, human fatigueAutonomous: 5 iteration loops, consistent checksResult: 3x fewer bugs reaching productionCommon Mistakes
I made these mistakes when setting up autonomous workflows:
1. Over-Specified System Prompts
// WRONG: Too rigidsystemPrompt: ` 1. Read file X 2. Check for pattern Y 3. If found, do Z 4. Otherwise do W ...`
// CORRECT: Flexible goalsystemPrompt: ` Review the code for security issues. Use available tools to investigate. Report findings clearly.`Over-specified prompts break when files change. Goal-based prompts adapt.
2. Missing Timeouts
// WRONG: No limitawait invokeAgent("builder", plan);
// CORRECT: Timeout prevents runawayawait invokeAgent("builder", plan, { timeout: 120000 // 2 minutes max});Agents can loop forever without timeouts.
3. Skipping Review Stage
// WRONG: Build directlyawait invokeAgent("builder", plan);
// CORRECT: Build then reviewconst build = await invokeAgent("builder", plan);const review = await invokeAgent("reviewer", build);if (!review.passed) { throw new Error("Quality check failed");}Autonomous doesn’t mean unverified.
4. Wrong Model Selection
// WRONG: Opus for everythingagents: [{ model: "opus-4.5", ... }]
// CORRECT: Right model for taskagents: [ { name: "gatherer", model: "haiku" }, // Fast, cheap { name: "builder", model: "sonnet" }, // Complex reasoning { name: "reviewer", model: "sonnet" } // Needs judgment]Opus for simple tasks wastes money. Haiku for complex tasks fails.
Putting It Together
Here’s a complete plugin configuration:
const autonomousWorkflowPlugin: PluginConfig = { name: "autonomous-workflows", version: "1.0.0",
skills: [ { name: "build-feature", description: "Autonomously build a feature with review loop", handler: "./skills/build-feature.ts" }, { name: "fix-bug", description: "Autonomously fix a bug with verification", handler: "./skills/fix-bug.ts" } ],
agents: [ { name: "requirements-gatherer", model: "haiku-4.5", systemPrompt: "Extract requirements from descriptions...", tools: ["read_file", "search"] }, { name: "builder", model: "sonnet-4.5", systemPrompt: "Implement code according to plan...", tools: ["edit_file", "run_test", "git_commit"] }, { name: "reviewer", model: "sonnet-4.5", systemPrompt: "Review code for issues...", tools: ["read_file", "run_linter", "run_test"] } ],
tools: [ { name: "run_test", description: "Execute test suite", parameters: { type: "object", properties: { pattern: { type: "string" } } }, handler: async (params) => { return await exec(`npm test ${params.pattern || ""}`); } }, { name: "run_linter", description: "Run code linter", parameters: { type: "object", properties: {} }, handler: async () => { return await exec("npm run lint"); } } ]};Workflow Diagram
+------------------------+| User: /build-feature |+------------------------+ | v+------------------------+| Requirements Gatherer || (Haiku, ~30s) |+------------------------+ | v+------------------------+| Planning Agent || (Sonnet, ~2min) |+------------------------+ | v +------+------+ | | v v+----------+ +----------+| Builder | | Reviewer ||(Sonnet) | |(Sonnet) || Worktree | | Worktree || WT-001 | | WT-002 |+----------+ +----------+ | | +----+---+----+ | | PASS | | FAIL | | v v+----------+ +----------+|Documenter| | Rebuild || (Haiku) | | Loop |+----------+ +----------+ | v+------------------------+| Merge to main |+------------------------+ | v+------------------------+| User notified |+------------------------+Key Takeaways
- Plugins orchestrate autonomously - Skills trigger agents, agents use tools, everything runs without supervision
- Multi-model selection matters - Haiku for fast work, Sonnet for complex reasoning, Opus sparingly
- Worktrees enable parallelization - Isolated git states let multiple workflows run simultaneously
- Iteration loops improve quality - Build-review-rebuild catches more bugs than single passes
- Timeouts prevent runaway - Always limit agent execution time
- Goal-based prompts adapt - Over-specified prompts break, flexible goals survive
The plugin system transforms AI from a chatbot into an autonomous development team. Define the workflow, trigger the skill, and let the agents work.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments