Create Codebolt providers that connect applications to external environments running remote executors. Providers abstract environment management (Docker, AWS EC2, WSL, SSH, Kubernetes, Git worktree, or any custom environment) and handle all communication with agents. Use when: (1) Building new providers for any environment type, (2) Implementing environment lifecycle management, (3) Setting up remote executor communication, (4) Handling file operations through remote environments, (5) Configuring heartbeat monitoring for health checks.
A Provider is the bridge between the Codebolt application and an external environment running agents. It has three core responsibilities:
┌─────────────────┐ ┌──────────────┐ ┌─────────────────┐
│ Codebolt │ ◄─────► │ Provider │ ◄─────► │ Remote Executor │
│ Application │ WS │ │ WS │ (Agents) │
└─────────────────┘ └──────────────┘ └─────────────────┘
Copy the provider template from assets/provider-template/ to start a new provider.
import { BaseProvider } from '@codebolt/provider';
import codebolt from '@codebolt/codeboltjs';
class MyProvider extends BaseProvider {
constructor() {
super({
agentServerPort: 3001,
agentServerHost: 'localhost',
transport: 'websocket',
});
}
// REQUIRED: Create your external environment
protected async setupEnvironment(initVars: ProviderInitVars): Promise<void> {
// Create container, VM, worktree, SSH connection, etc.
this.state.workspacePath = '/path/to/environment';
}
// REQUIRED: Set the project path
protected async resolveProjectContext(initVars: ProviderInitVars): Promise<void> {
this.state.projectPath = initVars.projectPath || process.cwd();
}
// REQUIRED: Return changed files info
async onGetDiffFiles(): Promise<any> {
return { files: [], hasChanges: false };
}
// OPTIONAL: Clean up environment
protected async teardownEnvironment(): Promise<void> {
// Stop container, remove worktree, close SSH, etc.
}
}
const provider = new MyProvider();
const handlers = provider.getEventHandlers();
// Lifecycle
codebolt.onProviderStart((vars) => handlers.onProviderStart(vars));
codebolt.onProviderAgentStart((msg) => handlers.onProviderAgentStart(msg));
codebolt.onProviderStop((vars) => handlers.onProviderStop(vars));
codebolt.onCloseSignal(() => handlers.onCloseSignal());
codebolt.onRawMessage((msg) => handlers.onRawMessage(msg));
// File operations
codebolt.onReadFile(async (path) => /* read from environment */);
codebolt.onWriteFile(async (path, content) => /* write to environment */);
// ... more handlers
class MyProvider extends BaseProvider {
constructor() {
super({
agentServerPort: 3001, // Port where agent server runs
agentServerHost: 'localhost', // Host (localhost for local, IP for remote)
transport: 'websocket', // Communication method
reconnectAttempts: 10, // Connection retry count
reconnectDelay: 1000, // Delay between retries (ms)
wsRegistrationTimeout: 10000, // WebSocket registration timeout (ms)
timeouts: {
agentServerStartup: 60000, // Agent server startup timeout
connection: 30000, // Connection timeout
cleanup: 15000, // Cleanup timeout
},
});
}
}
The setupEnvironment method creates your isolated environment:
protected async setupEnvironment(initVars: ProviderInitVars): Promise<void> {
// initVars contains:
// - environmentName: string (unique identifier)
// - type: string (provider type)
// - projectPath?: string (optional project path)
// - ...custom properties
// YOUR LOGIC: Create environment based on your type
// - Docker: docker.createContainer()
// - SSH: ssh.connect()
// - Git worktree: git worktree add
// - AWS EC2: ec2.runInstances()
// Set the workspace path for file operations
this.state.workspacePath = '/path/to/environment/workspace';
}
The teardownEnvironment method cleans up:
protected async teardownEnvironment(): Promise<void> {
// YOUR LOGIC: Clean up environment
// - Docker: container.stop(), container.remove()
// - SSH: ssh.end()
// - Git worktree: git worktree remove
// - AWS EC2: ec2.terminateInstances()
}
See message-handlers.md for the complete list.
When onProviderStart is called:
1. resetState() - Clear previous state
2. resolveProjectContext() - Set this.state.projectPath
3. resolveWorkspacePath() - Set this.state.workspacePath
4. ensureAgentServer() - Start/verify agent server
5. setupEnvironment() - Create external environment
6. ensureTransportConnection() - Connect WebSocket
7. afterConnected() - Post-connection hook (start heartbeats)
When onProviderStop or onCloseSignal is called:
1. beforeClose() - Pre-cleanup hook (stop heartbeats)
2. disconnectTransport() - Close WebSocket
3. teardownEnvironment() - Clean up environment
For detailed lifecycle patterns, see lifecycle-patterns.md.
The provider connects to the agent server via WebSocket:
// URL format