oneconsole-client-sdk
v0.4.0
Published
Client SDK for integrating node programs with OneConsole — WebSocket transport, command dispatch, webhook events, and HTTP API wrappers.
Maintainers
Readme
oneconsole-client-sdk
Node.js SDK for integrating node programs with OneConsole. It encapsulates all communication details: WebSocket transport with auto-reconnect and auth handshake, plugin-style command dispatch with automatic acks, GitHub webhook event handling, and HTTP API wrappers.
Install
npm install oneconsole-client-sdkRequires Node.js ≥ 18 (uses the global fetch).
Quick start
import { OneConsoleClient, createAssignRepoHandler, createGithubWebhookHandler } from 'oneconsole-client-sdk';
import os from 'node:os';
const client = new OneConsoleClient({
url: 'https://oneconsole.example.workers.dev',
nodeId: 'node_abc',
apiKey: 'sk_...',
heartbeatIntervalMs: 30_000,
});
// Plugin-style command registration — adding a new command type no longer
// requires touching WebSocket dispatch logic.
client.onCommand('assign_repo', createAssignRepoHandler({
clone: async ({ owner, repo }) => { /* git clone ... */ },
}));
// GitHub webhook events forwarded by OneConsole.
client.onWebhookEvent(createGithubWebhookHandler({
push: async (e) => { /* run CI */ },
pull_request: async (e) => { /* check PR */ },
}));
client.on((e) => {
if (e.event === 'auth_failed') console.error('auth failed:', e.error);
if (e.event === 'reconnect') console.log(`reconnecting (attempt ${e.attempt}) in ${e.delayMs}ms`);
});
await client.start({ heartbeat: { version: '1.0.0', hostname: os.hostname() } });
// HTTP API is also available directly:
const valid = await client.verify();
await client.reportLogs([{ level: 'info', message: 'booted' }]);
await client.reportTaskFailed({ taskId: 123, taskType: 'issue_resolver', repoOwner: 'acme', repoName: 'widget', errorLog: 'Git command failed', fixCycleCount: 3, maxCycles: 3, failedAt: new Date().toISOString() });Configuration
| Option | Type | Default | Description |
| --- | --- | --- | --- |
| url | string | — | Base URL of the OneConsole deployment. |
| nodeId | string | — | Node id registered in OneConsole. |
| apiKey | string | — | API key issued for the node. |
| heartbeatIntervalMs | number | 30000 | Periodic HTTP heartbeat interval. |
| autoReconnect | boolean | true | Reconnect with exponential backoff on drop. |
| reconnectDelayMs | number | 5000 | Base reconnect delay. |
| maxReconnectDelayMs | number | 60000 | Backoff cap. |
| requestTimeoutMs | number | 10000 | HTTP request timeout. |
| authTimeoutMs | number | 10000 | WebSocket auth handshake timeout. |
All timing options must be positive integers (>= 1); 0 is rejected to
prevent heartbeat/reconnect storms.
API
new OneConsoleClient(config)
Lifecycle
start(opts?)— connect, authenticate, begin periodic heartbeats. Resolves once the auth handshake succeeds. Rejects on auth timeout, socket close during handshake, or invalid credentials. Auth failure is terminal and is not retried (bad credentials would only hammer the server); a transport drop after a successful handshake is retried whenautoReconnectis on.stop()— cancel timers, close the socket, disable reconnect. Safe to call whilestart()is still in-flight (it unblocks the handshake).connected—trueonce authenticated.nodeId— the configured node id.
Command dispatch
onCommand(type, handler)— register an async handler for a command type. The SDK auto-acks with the handler's{ status, result }; a thrown error becomes a failed ack.
Webhook events
onWebhookEvent(handler)— register a GitHub webhook event handler (multiple allowed).
HTTP API
verify()→Promise<boolean>heartbeat(version?, hostname?)→Promise<void>reportLogs(logs)→Promise<void>reportTaskFailed(report)→Promise<void>
The HTTP wrappers do not retry. A transient failure rejects (and, for the periodic heartbeat, emits an
errorevent); the caller is responsible for any retry policy.
Events
on(listener)— subscribe to lifecycle events (state,auth_ok,auth_failed,command,webhook,reconnect,error,close). Returns an unsubscribe function.
Wire protocol
The SDK speaks the protocol implemented by the OneConsole backend
(src/do/node-connection.ts, src/routes/node-routes.ts):
Breaking change. Commands are sent as
{ type: 'command', id, command_type, payload? }. Older hand-written clients that readtypeto determine the command kind will not work — the outertypeis now the message kind ('command'), and the command kind lives incommand_type. Existing node programs (e.g. OneResolve) must migrate to this SDK (or otherwise readcommand_type) when upgrading the backend.
WebSocket (/api/v1?node_id=<id>):
| Direction | Message |
| --- | --- |
| client → server | { type: 'auth', api_key } |
| server → client | { type: 'auth_result', ok, node_id?, error? } |
| server → client | { type: 'command', id, command_type, payload? } |
| client → server | { type: 'ack', command_id, status, result? } |
| server → client | { type: 'github_webhook', event, delivery, payload? } |
| server → client | { type: 'ping' } → client replies { type: 'pong' } |
HTTP (auth via X-Node-Api-Key header where noted):
POST /api/v1/node/verify—{ node_id, api_key }POST /api/v1/node/heartbeat—X-Node-Api-Key, body{ version, hostname, load? }POST /api/v1/node/logs—X-Node-Api-Key, body{ logs: [{ level, message, timestamp? }] }POST /api/v1/node/task-failed—X-Node-Api-Key, bodyTaskFailureReport
Development
npm run typecheck # tsc --noEmit
npm run build # emit to dist/