Building Integrations
Create custom clients using the DorkOS Transport interface
Building Integrations
DorkOS uses a hexagonal (ports & adapters) architecture centered on the Transport interface. You can build custom clients by implementing this interface or by using the REST/SSE API directly.
The Transport Interface
The Transport interface (packages/shared/src/transport.ts) defines all client-server communication:
interface Transport {
createSession(opts: CreateSessionRequest): Promise<Session>;
listSessions(cwd?: string): Promise<Session[]>;
getSession(id: string, cwd?: string): Promise<Session>;
updateSession(id: string, opts: UpdateSessionRequest, cwd?: string): Promise<Session>;
getMessages(sessionId: string, cwd?: string): Promise<{ messages: HistoryMessage[] }>;
sendMessage(sessionId, content, onEvent, signal?, cwd?): Promise<void>;
approveTool(sessionId: string, toolCallId: string): Promise<{ ok: boolean }>;
denyTool(sessionId: string, toolCallId: string): Promise<{ ok: boolean }>;
submitAnswers(sessionId, toolCallId, answers): Promise<{ ok: boolean }>;
getTasks(sessionId: string, cwd?: string): Promise<{ tasks: TaskItem[] }>;
browseDirectory(dirPath?, showHidden?): Promise<BrowseDirectoryResponse>;
getDefaultCwd(): Promise<{ path: string }>;
getCommands(refresh?: boolean, cwd?: string): Promise<CommandRegistry>;
listFiles(cwd: string): Promise<FileListResponse>;
getGitStatus(cwd?: string): Promise<GitStatusResponse | GitStatusError>;
health(): Promise<HealthResponse>;
getConfig(): Promise<ServerConfig>;
}Built-in Implementations
HttpTransport is used by the standalone web client and communicates with the Express server over HTTP and SSE:
- Standard
fetch()for CRUD operations - Server-Sent Events for streaming in
sendMessage() - Parses SSE events into
StreamEventobjects - Includes
X-Client-Idheader for session locking
DirectTransport is used by the Obsidian plugin and calls service instances directly in the same process:
- No HTTP, no port binding, no network serialization
- Iterates
AsyncGenerator<StreamEvent>from the Agent SDK - Lower latency, ideal for embedded contexts
Building a Custom Client
Choose the approach that best fits your platform and requirements:
Use the REST API directly for any language or platform:
# List sessions
GET /api/sessions
# Create a session
POST /api/sessions
Content-Type: application/json
{ "cwd": "/path/to/project" }
# Send a message (returns SSE stream)
POST /api/sessions/:id/messages
Content-Type: application/json
{ "content": "Hello", "cwd": "/path/to/project" }
# Approve a tool call
POST /api/sessions/:id/approve
Content-Type: application/json
{ "toolCallId": "tc_123" }The full REST API is documented interactively at /api/docs (Scalar UI) when the server is running, or see the API Reference.
Implement the Transport interface for deeper integration:
import type { Transport } from '@dorkos/shared/transport';
class MyCustomTransport implements Transport {
async listSessions() {
// Your implementation
}
async sendMessage(sessionId, content, onEvent, signal, cwd) {
// Connect to your backend
// Call onEvent() for each StreamEvent
}
// ... implement remaining methods
}All methods in the Transport interface must be implemented. TypeScript will report compile-time errors for any missing methods.
If building a React app, inject your Transport via context:
import { TransportProvider } from '@dorkos/shared';
const transport = new MyCustomTransport();
function App() {
return (
<TransportProvider transport={transport}>
<YourApp />
</TransportProvider>
);
}All DorkOS hooks (useSessions, useChatSession, etc.) consume the Transport from context, so your custom implementation powers the entire UI automatically.
StreamEvent Types
Events emitted during message streaming:
Prop
Type