@cleocode/adapters
Unified provider adapters for CLEO - Claude Code, OpenCode, Cursor integration.
Overview
This package provides standardized adapters for integrating CLEO with various AI coding assistants and providers. Each adapter implements a common interface, allowing CLEO to work seamlessly across different environments.
Supported Providers
| Claude Code | ✅ Production | Full integration with statusline sync, context monitoring |
| OpenCode | ✅ Production | Spawn hooks, task synchronization |
| Cursor | ✅ Production | Basic adapter with install hooks |
Installation
npm install @cleocode/adapters
pnpm add @cleocode/adapters
yarn add @cleocode/adapters
API Overview
Provider Adapters
Each provider has its own adapter class with specialized capabilities:
Claude Code Adapter
import {
ClaudeCodeAdapter,
createClaudeCodeAdapter,
ClaudeCodeContextMonitorProvider,
ClaudeCodeHookProvider,
ClaudeCodeInstallProvider,
ClaudeCodePathProvider,
ClaudeCodeSpawnProvider,
ClaudeCodeTransportProvider,
checkStatuslineIntegration,
getSetupInstructions,
getStatuslineConfig
} from '@cleocode/adapters';
const adapter = createClaudeCodeAdapter({
projectPath: './my-project'
});
const status = await checkStatuslineIntegration('./my-project');
const instructions = getSetupInstructions();
OpenCode Adapter
import {
OpenCodeAdapter,
createOpenCodeAdapter,
OpenCodeHookProvider,
OpenCodeInstallProvider,
OpenCodeSpawnProvider
} from '@cleocode/adapters';
const adapter = createOpenCodeAdapter({
projectPath: './my-project'
});
Cursor Adapter
import {
CursorAdapter,
createCursorAdapter,
CursorHookProvider,
CursorInstallProvider
} from '@cleocode/adapters';
const adapter = createCursorAdapter({
projectPath: './my-project'
});
Registry
Discover and manage provider manifests:
import {
discoverProviders,
getProviderManifests,
type AdapterManifest
} from '@cleocode/adapters';
const providers = await discoverProviders('./my-project');
const manifests = getProviderManifests();
const claudeManifest = manifests.find(m => m.name === 'claude-code');
Adapter Capabilities
Each provider adapter implements specific capability interfaces:
Install Provider
Handles installation and setup:
import type { AdapterInstallProvider, InstallOptions, InstallResult } from '@cleocode/contracts';
const installProvider: AdapterInstallProvider = {
async install(options: InstallOptions): Promise<InstallResult> {
return { success: true, installed: ['file1', 'file2'] };
},
async detect(projectPath: string): Promise<boolean> {
return fs.existsSync(path.join(projectPath, '.claude'));
}
};
Hook Provider
Provides lifecycle hooks:
import type { AdapterHookProvider } from '@cleocode/contracts';
const hookProvider: AdapterHookProvider = {
async onTaskCreate(context) {
},
async onTaskComplete(context) {
},
async onSessionStart(context) {
},
async onSessionEnd(context) {
}
};
Spawn Provider
Handles subagent spawning:
import type { AdapterSpawnProvider, SpawnContext, SpawnResult } from '@cleocode/contracts';
const spawnProvider: AdapterSpawnProvider = {
async spawn(context: SpawnContext): Promise<SpawnResult> {
return {
pid: 12345,
stdout: process.stdout,
stderr: process.stderr,
exitCode: 0
};
}
};
Context Monitor Provider
Monitors provider context:
import type { AdapterContextMonitorProvider } from '@cleocode/contracts';
const contextProvider: AdapterContextMonitorProvider = {
async getContext(projectPath: string) {
return {
activeTask: 'T1234',
sessionId: 'session-abc',
memoryUsage: 1024000
};
}
};
Transport Provider
Handles communication:
import type { AdapterTransportProvider } from '@cleocode/contracts';
const transportProvider: AdapterTransportProvider = {
async send(message) {
},
async receive() {
return { type: 'response', data: {} };
}
};
Path Provider
Provides provider-specific paths:
import type { AdapterPathProvider } from '@cleocode/contracts';
const pathProvider: AdapterPathProvider = {
getConfigPath(projectPath: string) {
return path.join(projectPath, '.claude', 'settings.json');
},
getDataPath(projectPath: string) {
return path.join(projectPath, '.claude', 'data');
}
};
Task Sync Provider
Synchronizes tasks with provider:
import type { AdapterTaskSyncProvider, ReconcileOptions, ReconcileResult } from '@cleocode/contracts';
const syncProvider: AdapterTaskSyncProvider = {
async getExternalTasks(projectPath: string) {
return [];
},
async reconcile(options: ReconcileOptions): Promise<ReconcileResult> {
return {
actions: [],
conflicts: []
};
}
};
Usage Examples
Detecting Available Providers
import { discoverProviders, getProviderManifests } from '@cleocode/adapters';
async function detectProviders() {
const projectPath = './my-project';
const available = await discoverProviders(projectPath);
console.log('Available providers:');
for (const provider of available) {
console.log(` - ${provider.name}: ${provider.version}`);
}
const manifests = getProviderManifests();
for (const manifest of manifests) {
console.log(`\n${manifest.name}:`);
console.log(` Capabilities: ${manifest.capabilities.join(', ')}`);
console.log(` Patterns: ${manifest.patterns.join(', ')}`);
}
}
Setting Up Claude Code Integration
import {
createClaudeCodeAdapter,
checkStatuslineIntegration,
getSetupInstructions
} from '@cleocode/adapters';
async function setupClaudeCode() {
const projectPath = './my-project';
const status = await checkStatuslineIntegration(projectPath);
if (!status.integrated) {
console.log('Claude Code not yet integrated');
console.log(getSetupInstructions());
const adapter = createClaudeCodeAdapter({ projectPath });
const result = await adapter.install({ force: false });
if (result.success) {
console.log('Claude Code integration installed');
}
} else {
console.log('Claude Code is already integrated ✓');
}
}
Working with Hooks
import { createClaudeCodeAdapter } from '@cleocode/adapters';
async function setupHooks() {
const adapter = createClaudeCodeAdapter({
projectPath: './my-project'
});
adapter.hooks.register('onTaskCreate', async (context) => {
console.log(`Task ${context.taskId} created in Claude Code`);
await adapter.updateStatusline({ activeTask: context.taskId });
});
adapter.hooks.register('onTaskComplete', async (context) => {
console.log(`Task ${context.taskId} completed`);
await adapter.updateStatusline({ activeTask: null });
});
}
Spawning Subagents
import { createClaudeCodeAdapter } from '@cleocode/adapters';
async function spawnSubagent() {
const adapter = createClaudeCodeAdapter({
projectPath: './my-project'
});
const result = await adapter.spawn({
taskId: 'T1234',
context: {
instructions: 'Implement the authentication endpoint',
files: ['src/auth.ts', 'src/routes.ts']
}
});
if (result.pid) {
console.log(`Spawned subagent with PID ${result.pid}`);
result.stdout?.on('data', (data) => {
console.log(`Output: ${data}`);
});
}
}
Synchronizing Tasks
import { createClaudeCodeAdapter } from '@cleocode/adapters';
async function syncTasks() {
const adapter = createClaudeCodeAdapter({
projectPath: './my-project'
});
const externalTasks = await adapter.getExternalTasks();
const result = await adapter.reconcile({
conflictPolicy: 'prefer-external',
dryRun: false
});
console.log(`Reconciliation complete:`);
console.log(` Created: ${result.created.length}`);
console.log(` Updated: ${result.updated.length}`);
console.log(` Conflicts: ${result.conflicts.length}`);
}
Custom Provider Adapter
import type {
CLEOProviderAdapter,
AdapterCapabilities,
AdapterHealthStatus
} from '@cleocode/contracts';
class MyCustomAdapter implements CLEOProviderAdapter {
name = 'my-custom-provider';
version = '1.0.0';
getCapabilities(): AdapterCapabilities {
return {
spawn: true,
hooks: true,
install: true,
contextMonitor: false,
transport: true,
paths: true,
taskSync: false
};
}
async healthCheck(projectPath: string): Promise<AdapterHealthStatus> {
const isInstalled = await this.detect(projectPath);
return {
healthy: isInstalled,
message: isInstalled ? 'Ready' : 'Not installed'
};
}
async detect(projectPath: string): Promise<boolean> {
return fs.existsSync(path.join(projectPath, '.my-provider'));
}
}
import { discoverProviders } from '@cleocode/adapters';
discoverProviders.register(new MyCustomAdapter());
Provider Manifest Format
Adapters expose their capabilities through manifests:
interface AdapterManifest {
name: string;
version: string;
description: string;
capabilities: Array<'spawn' | 'hooks' | 'install' | 'contextMonitor' | 'transport' | 'paths' | 'taskSync'>;
patterns: DetectionPattern[];
}
interface DetectionPattern {
type: 'file' | 'directory' | 'config';
path: string;
content?: string;
}
Example manifest:
{
"name": "claude-code",
"version": "1.0.0",
"description": "Claude Code integration",
"capabilities": ["spawn", "hooks", "install", "contextMonitor", "transport", "paths", "taskSync"],
"patterns": [
{ "type": "directory", "path": ".claude" },
{ "type": "file", "path": ".claude/CLAUDE.md" }
]
}
Dependencies
Production Dependencies
@cleocode/contracts - Type definitions and interfaces
Development Dependencies
@types/node - Node.js type definitions
License
MIT License - see LICENSE for details.