Skip to main content

Plugin Development Guide

Creating a plugin for Agent Orchestrator is straightforward: implement one of the core interfaces and export it as a PluginModule. This guide walks you through the process.

Prerequisites

Before creating a plugin:
  1. Understand the interface - Read packages/core/src/types.ts to understand the interface you’ll implement
  2. Study examples - Look at existing plugins in packages/plugins/ for patterns
  3. Set up TypeScript - Use TypeScript with strict mode enabled

Plugin Module Structure

Every plugin must export a PluginModule with two properties:
1

Manifest

Plugin metadata describing the plugin:
2

Create Function

Factory function that returns the plugin implementation:
3

Default Export with Type Safety

Export the module with type checking:
The satisfies operator ensures compile-time type safety without type widening.

Complete Plugin Template

Here’s a complete plugin template for a Runtime plugin:

Interface Requirements by Slot

Runtime Plugin

Required methods:
  • create(config) - Create a new execution environment
  • destroy(handle) - Destroy the environment
  • sendMessage(handle, message) - Send input to the agent
  • getOutput(handle, lines?) - Capture recent output
  • isAlive(handle) - Check if environment is alive
Optional methods:
  • getMetrics(handle) - Return resource metrics
  • getAttachInfo(handle) - Return attachment info for Terminal plugin

Agent Plugin

Required methods:
  • getLaunchCommand(config) - Generate shell command to launch agent
  • getEnvironment(config) - Return environment variables
  • detectActivity(terminalOutput) - Classify activity from output (deprecated)
  • getActivityState(session, threshold?) - Get current activity state
  • isProcessRunning(handle) - Check if agent process is alive
  • getSessionInfo(session) - Extract summary and cost info
Optional methods:
  • getRestoreCommand(session, project) - Generate command to resume session
  • postLaunchSetup(session) - Run setup after agent launches
  • setupWorkspaceHooks(workspacePath, config) - Install hooks for metadata updates
Properties:
  • name - Plugin name
  • processName - Process name to look for (e.g., “claude”, “aider”)
  • promptDelivery - “inline” or “post-launch” for prompt delivery

Workspace Plugin

Required methods:
  • create(config) - Create isolated workspace
  • destroy(workspacePath) - Remove workspace
  • list(projectId) - List existing workspaces
Optional methods:
  • postCreate(info, project) - Run hooks after creation (symlinks, installs)
  • exists(workspacePath) - Check if workspace is valid
  • restore(config, workspacePath) - Recreate workspace from existing data

Tracker Plugin

Required methods:
  • getIssue(identifier, project) - Fetch issue details
  • isCompleted(identifier, project) - Check if issue is closed
  • issueUrl(identifier, project) - Generate issue URL
  • branchName(identifier, project) - Generate branch name from issue
  • generatePrompt(identifier, project) - Generate agent prompt
Optional methods:
  • issueLabel(url, project) - Extract human-readable label from URL
  • listIssues(filters, project) - List issues with filters
  • updateIssue(identifier, update, project) - Update issue state
  • createIssue(input, project) - Create new issue

SCM Plugin

Required methods:
  • detectPR(session, project) - Detect PR by branch name
  • getPRState(pr) - Get PR state (open/merged/closed)
  • mergePR(pr, method?) - Merge a PR
  • closePR(pr) - Close PR without merging
  • getCIChecks(pr) - Get individual CI checks
  • getCISummary(pr) - Get overall CI status
  • getReviews(pr) - Get all reviews
  • getReviewDecision(pr) - Get overall review decision
  • getPendingComments(pr) - Get unresolved comments
  • getAutomatedComments(pr) - Get bot comments
  • getMergeability(pr) - Check merge readiness
Optional methods:
  • getPRSummary(pr) - Get PR summary with stats

Notifier Plugin

Required methods:
  • notify(event) - Push notification to human
Optional methods:
  • notifyWithActions(event, actions) - Notification with action buttons
  • post(message, context?) - Post to channel (for team notifiers)

Terminal Plugin

Required methods:
  • openSession(session) - Open single session for human
  • openAll(sessions) - Open all sessions for a project
Optional methods:
  • isSessionOpen(session) - Check if session is already open

Code Conventions

These conventions are enforced by ESLint and Prettier. Follow them to avoid CI failures.

TypeScript Standards

  1. ESM modules - Use "type": "module" in package.json
  2. .js extensions - Include in all local imports: import { foo } from "./bar.js"
  3. node: prefix - Use for built-ins: import { readFile } from "node:fs/promises"
  4. Strict mode - Enable "strict": true in tsconfig
  5. Type imports - Use import type for type-only imports
  6. No any - Use unknown + type guards instead
  7. Prefer const - Use let only for reassignment, never var

Security Requirements

1

Always use execFile

NEVER use exec - it’s vulnerable to shell injection.
2

Always add timeouts

Set timeouts for all external commands:
3

Never interpolate user input

Pass user input as array arguments, not string templates:
4

Validate external data

Guard against malformed API responses:

Error Handling

  1. Throw typed errors - Don’t return error codes
  2. Plugins throw - If they can’t do their job
  3. Core services catch - Handle plugin errors gracefully
  4. Wrap JSON.parse - Corrupted data shouldn’t crash
  5. Best-effort cleanup - Don’t throw during cleanup/destroy

Testing Your Plugin

Unit Tests

Create tests in __tests__/ or co-located .test.ts files:

Integration Testing

  1. Local testing - Install your plugin locally:
  2. Configure - Add to agent-orchestrator.yaml:
  3. Test spawn - Spawn a session:

Publishing Your Plugin

Package Structure

package.json

Publishing to npm

1

Build

2

Test

3

Publish

Using Published Plugin

Users can install and use your plugin:

Plugin Checklist

Before publishing, verify:
  • Implements complete interface (no missing methods)
  • Uses satisfies PluginModule<T> for type safety
  • Follows security conventions (execFile, timeouts, no interpolation)
  • Includes error handling (try/catch, typed errors)
  • Has unit tests covering core functionality
  • Tested locally with real Agent Orchestrator config
  • Has README with usage examples
  • Uses semantic versioning
  • Declares @composio/ao-core as peer dependency

Common Patterns

Config Extraction

Process Execution

Caching

Path Safety

Resources

Core Types

Complete interface definitions

Example Plugins

Browse built-in plugin implementations

CLAUDE.md

Code conventions and architecture

Community Plugins

Discover community plugins

Getting Help

If you run into issues:
  1. Check existing plugin implementations for patterns
  2. Review packages/core/src/types.ts for interface details
  3. Open an issue on GitHub for questions
  4. Join discussions in the community
Contributions are welcome! Consider submitting your plugin to the official plugin repository via pull request.