Pilot SolidJS SDK
SolidJS primitives and components for Cuitty Pilot — reactive playbook management, run control, and real-time event streaming.
Pilot SolidJS SDK
@cuitty/pilot-solid provides SolidJS primitives and components for the Pilot API. It wraps @cuitty/pilot-sdk with idiomatic Solid patterns — context providers, createResource for data fetching, signals for run state, and automatic SSE cleanup.
Install
sfw bun add @cuitty/pilot-solid
# or
sfw npm install @cuitty/pilot-solid
Peer dependencies: solid-js>=1.8, @cuitty/pilot-sdk.
Quick start
import { PilotProvider, createPlaybooks, createRun, createRunEvents } from "@cuitty/pilot-solid";
import { For, Show, createSignal } from "solid-js";
function App() {
return (
<PilotProvider baseUrl="http://localhost:4320" auth={{ apiKey: "pk_..." }}>
<Dashboard />
</PilotProvider>
);
}
function Dashboard() {
const [playbooks] = createPlaybooks();
const [run, { start }] = createRun();
const events = createRunEvents(() => run()?.id);
return (
<div>
<For each={playbooks()}>
{(pb) => (
<button onClick={() => start({ playbookId: pb.id, mode: "autonomous" })}>
{pb.title}
</button>
)}
</For>
<For each={events()}>
{(e) => <div>{e.type} {e.stepId}</div>}
</For>
</div>
);
}
PilotProvider
Wraps your component tree with a PilotClient instance. Accepts all PilotClientConfig props plus children. The client is closed automatically via onCleanup.
import { PilotProvider } from "@cuitty/pilot-solid";
<PilotProvider
baseUrl="http://localhost:4320"
auth={{ token: "ey..." }}
timeout={15000}
>
{props.children}
</PilotProvider>
| Prop | Type | Description |
|---|---|---|
baseUrl | string | Pilot server URL |
auth | { token?: string; cookie?: string; apiKey?: string } | Authentication credentials |
timeout | number | Per-request timeout in ms (default 30000) |
children | JSX.Element | Child components |
usePilot()
Returns the PilotClient from context. Throws if used outside <PilotProvider>.
import { usePilot } from "@cuitty/pilot-solid";
const pilot = usePilot();
const health = await pilot.health();
Primitives
createPlaybooks(options?)
Reactive resource for listing playbooks. Wraps Solid’s createResource — re-fetches when the options accessor changes.
const [playbooks, { refetch }] = createPlaybooks();
const [cfOnly] = createPlaybooks(() => ({ target: "cloudflare" }));
| Param | Type | Description |
|---|---|---|
opts | () => ListPlaybooksOptions | undefined | Optional accessor returning filter options |
Returns a Solid Resource<PlaybookSummary[]> tuple: [accessor, { refetch, mutate }].
createRun()
Manages a single run lifecycle with signals for run state and loading.
const [run, { start, abort, loading }] = createRun();
// Start a new run
const result = await start({
playbookId: "cloudflare.dns.add-a-record",
mode: "interactive",
inputs: { zone: "example.com", record_name: "api", ip_address: "1.2.3.4" },
});
// Abort the active run
await abort();
| Return | Type | Description |
|---|---|---|
run | Accessor<Run | null> | Signal with the current run object |
start(req) | (StartRunRequest) => Promise<Run | null> | Start a run and fetch its full details |
abort() | () => Promise<void> | Abort the current run |
loading | Accessor<boolean> | Signal, true while starting |
createRunEvents(runId)
Subscribes to real-time SSE events for a run. Automatically unsubscribes via onCleanup and re-subscribes when runId changes.
const events = createRunEvents(() => run()?.id);
// events is Accessor<RunEvent[]>
<For each={events()}>
{(event) => <span>{event.type}</span>}
</For>
| Param | Type | Description |
|---|---|---|
runId | () => string | null | undefined | Accessor returning the run ID; null/undefined pauses subscription |
Returns Accessor<RunEvent[]> — accumulates all events since subscription started.
Components
RunStatusBadge
Renders a colored pill badge for a run status.
import { RunStatusBadge } from "@cuitty/pilot-solid";
<RunStatusBadge status="running" />
<RunStatusBadge status="completed" />
Supported statuses: queued, running, awaiting_approval, completed, failed, aborted.
RunTimeline
Renders a vertical timeline of run events using <For>, with color-coded borders (blue for in-progress, green for complete, red for failures). Uses <Show> for conditional step ID display.
import { RunTimeline } from "@cuitty/pilot-solid";
const events = createRunEvents(() => runId);
<RunTimeline events={events()} />
PlaybookCard
Displays a playbook summary card with an optional “Run” button. Uses <Show> to conditionally render the button.
import { PlaybookCard } from "@cuitty/pilot-solid";
<PlaybookCard
playbook={playbook}
onRun={(pb) => start({ playbookId: pb.id, mode: "autonomous" })}
/>
| Prop | Type | Description |
|---|---|---|
playbook | PlaybookSummary | Playbook to display |
onRun | (playbook: PlaybookSummary) => void | Optional callback when “Run” is clicked |
Error handling
Errors in createPlaybooks surface through the resource’s error state. For createRun, errors thrown during start() propagate to the caller. For direct PilotClient usage via usePilot(), catch typed errors from @cuitty/pilot-sdk.
import { PilotApiError, PilotConnectionError } from "@cuitty/pilot-sdk";
const pilot = usePilot();
try {
await pilot.runs.start({ playbookId: "nonexistent" });
} catch (err) {
if (err instanceof PilotApiError) {
console.error(`API ${err.status}: ${err.statusText}`, err.body);
} else if (err instanceof PilotConnectionError) {
console.error("Cannot reach Pilot:", err.message);
}
}
See also
- JavaScript SDK — underlying
PilotClientAPI reference - Playbook reference — YAML schema for playbook documents
- Quickstart — record and replay your first workflow