Plugin Development Guide
Creating a plugin for Agent Orchestrator is straightforward: implement one of the core interfaces and export it as aPluginModule. This guide walks you through the process.
Prerequisites
Before creating a plugin:- Understand the interface - Read
packages/core/src/types.tsto understand the interface you’ll implement - Study examples - Look at existing plugins in
packages/plugins/for patterns - Set up TypeScript - Use TypeScript with strict mode enabled
Plugin Module Structure
Every plugin must export aPluginModule 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 environmentdestroy(handle)- Destroy the environmentsendMessage(handle, message)- Send input to the agentgetOutput(handle, lines?)- Capture recent outputisAlive(handle)- Check if environment is alive
getMetrics(handle)- Return resource metricsgetAttachInfo(handle)- Return attachment info for Terminal plugin
Implementation Example: tmux Runtime
Implementation Example: tmux Runtime
Agent Plugin
Required methods:getLaunchCommand(config)- Generate shell command to launch agentgetEnvironment(config)- Return environment variablesdetectActivity(terminalOutput)- Classify activity from output (deprecated)getActivityState(session, threshold?)- Get current activity stateisProcessRunning(handle)- Check if agent process is alivegetSessionInfo(session)- Extract summary and cost info
getRestoreCommand(session, project)- Generate command to resume sessionpostLaunchSetup(session)- Run setup after agent launchessetupWorkspaceHooks(workspacePath, config)- Install hooks for metadata updates
name- Plugin nameprocessName- Process name to look for (e.g., “claude”, “aider”)promptDelivery- “inline” or “post-launch” for prompt delivery
Implementation Example: Agent Activity Detection
Implementation Example: Agent Activity Detection
Workspace Plugin
Required methods:create(config)- Create isolated workspacedestroy(workspacePath)- Remove workspacelist(projectId)- List existing workspaces
postCreate(info, project)- Run hooks after creation (symlinks, installs)exists(workspacePath)- Check if workspace is validrestore(config, workspacePath)- Recreate workspace from existing data
Implementation Example: Git Worktree
Implementation Example: Git Worktree
Tracker Plugin
Required methods:getIssue(identifier, project)- Fetch issue detailsisCompleted(identifier, project)- Check if issue is closedissueUrl(identifier, project)- Generate issue URLbranchName(identifier, project)- Generate branch name from issuegeneratePrompt(identifier, project)- Generate agent prompt
issueLabel(url, project)- Extract human-readable label from URLlistIssues(filters, project)- List issues with filtersupdateIssue(identifier, update, project)- Update issue statecreateIssue(input, project)- Create new issue
SCM Plugin
Required methods:detectPR(session, project)- Detect PR by branch namegetPRState(pr)- Get PR state (open/merged/closed)mergePR(pr, method?)- Merge a PRclosePR(pr)- Close PR without merginggetCIChecks(pr)- Get individual CI checksgetCISummary(pr)- Get overall CI statusgetReviews(pr)- Get all reviewsgetReviewDecision(pr)- Get overall review decisiongetPendingComments(pr)- Get unresolved commentsgetAutomatedComments(pr)- Get bot commentsgetMergeability(pr)- Check merge readiness
getPRSummary(pr)- Get PR summary with stats
Notifier Plugin
Required methods:notify(event)- Push notification to human
notifyWithActions(event, actions)- Notification with action buttonspost(message, context?)- Post to channel (for team notifiers)
Implementation Example: Desktop Notifier
Implementation Example: Desktop Notifier
Terminal Plugin
Required methods:openSession(session)- Open single session for humanopenAll(sessions)- Open all sessions for a project
isSessionOpen(session)- Check if session is already open
Code Conventions
TypeScript Standards
- ESM modules - Use
"type": "module"in package.json .jsextensions - Include in all local imports:import { foo } from "./bar.js"node:prefix - Use for built-ins:import { readFile } from "node:fs/promises"- Strict mode - Enable
"strict": truein tsconfig - Type imports - Use
import typefor type-only imports - No
any- Useunknown+ type guards instead - Prefer
const- Useletonly for reassignment, nevervar
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
- Throw typed errors - Don’t return error codes
- Plugins throw - If they can’t do their job
- Core services catch - Handle plugin errors gracefully
- Wrap JSON.parse - Corrupted data shouldn’t crash
- 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
-
Local testing - Install your plugin locally:
-
Configure - Add to
agent-orchestrator.yaml: -
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-coreas 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:- Check existing plugin implementations for patterns
- Review
packages/core/src/types.tsfor interface details - Open an issue on GitHub for questions
- Join discussions in the community
Contributions are welcome! Consider submitting your plugin to the official plugin repository via pull request.
