Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3.9 KiB
joelclaw SDK (@joelclaw/sdk)
Programmatic access to joelclaw command contracts.
Purpose
Use the SDK when software needs typed access to joelclaw behavior without reimplementing CLI parsing and process control.
The SDK now supports both subprocess and in-process execution:
transport: "subprocess"— always shell out tojoelclawtransport: "inprocess"— never shell out; uses SDK capability adapters directly (currentlyotel,recall,deploy,log,secrets,notify,mail,subscribe,heal)transport: "hybrid"(default) — in-process first for supported capabilities, subprocess fallback otherwise
Installation (workspace)
import { createJoelclawClient } from "@joelclaw/sdk"
Client setup
const client = createJoelclawClient({
bin: process.env.JOELCLAW_BIN, // optional, defaults to JOELCLAW_BIN or "joelclaw"
cwd: process.cwd(), // optional working directory
timeoutMs: 20_000, // optional per-call default timeout
transport: "inprocess", // "subprocess" | "inprocess" | "hybrid"
})
Core methods
Generic
run(args, options)— returns parsed envelope, does not throw onok:falserunOrThrow(args, options)— throwsJoelclawEnvelopeErroronok:falserunText(args, options)— raw stdout for non-envelope commands
Typed convenience routes
status()deployWorker(options)logWrite({ action, tool, detail, reason? })notifySend({ message, channel?, priority?, context?, type?, source?, telegramOnly? })— compatibility surface; the acting gateway maps it to contract v2, while routing remains centralized by message kindsecretsStatus/lease/revoke/audit/envotelList/search/stats/emitrecall(query, options)recallRaw(query, options)vaultRead/search/ls/treevaultAdrList/collisions/audit/rank
Direct capability runtime
The SDK exports capability adapters and a runtime entrypoint:
executeSdkCapabilityCommand({ capability, subcommand, args })- adapters:
typesenseOtelAdapter,typesenseRecallAdapter,scriptedDeployAdapter,slogCliAdapter,secretsCliAdapter,gatewayRedisNotifyAdapter,mcpAgentMailAdapter,redisSubscriptionsAdapter,runbookHealAdapter
This is the canonical in-process path now used by SDK transport and reused by CLI adapter wrappers.
notifySend() remains the simple-text compatibility API. Producers that need an explicit memory|alert|digest|ask|receipt kind, replyTo, or reaction/reply correlation use contract v2 at the gateway composition root and retain the returned flowId. Do not add new platform-routing flags to the SDK method.
Error model
JoelclawProcessError- command timed out, binary missing, non-zero exit, or non-envelope output where envelope expected
- includes
bin,args,exitCode,signal,stdout,stderr
JoelclawEnvelopeError- command returned a valid envelope with
ok:false - includes full
envelope
- command returned a valid envelope with
JoelclawCapabilityError- in-process capability execution failed (
transport: "inprocess") - includes capability, subcommand, code, and fix guidance
- in-process capability execution failed (
OTEL emit examples
await client.otelEmit("system.sdk.ping")
await client.otelEmit({
action: "system.sdk.ping",
source: "sdk",
component: "integration-test",
level: "info",
success: true,
metadata: { suite: "smoke" },
})
otelList() and otelSearch() also accept exact session / system filters, which map to sessionId / systemId in the Typesense-backed OTEL capability adapter.
Notes
- Envelope schema mirrors CLI contract in
packages/cli/src/response.ts. - OTEL/recall/deploy/log/secrets/notify/mail/subscribe/heal adapter logic now lives in
packages/sdk/src/capabilities/adapters/*and is consumed by CLI wrapper adapters. - Keep docs/cli.md and this file updated whenever SDK routes, capability adapters, or transport semantics change.