SmithersGatewayClient, live data hooks that read a run (or runs,
approvals, crons, scores, …) over TanStack DB collections, and action hooks
that launch, approve, and cancel. Most hooks share the
GatewayAsyncState shape, so knowing one means knowing
them all.
Everything here lives at the subpath
smthrs/gateway-react,
not the bare smthrs facade. Import from the subpath, or
the build fails.createGatewayReactRoot instead: it wires both
contexts (on-demand hooks and the live collections) in one call.
GatewayAsyncState
The return shape shared by the live data hooks; see field detail below.object
GatewayAsyncState.ts · See also Custom workflow UI
Provider & root
SmithersGatewayProvider
Holds oneSmithersGatewayClient in context for every hook below. Pass a ready
client, or options to construct one. The client is memoized on the content
of options, so an inline literal won’t trigger a reconnect storm while a
rotated credential or transport still rebuilds the client.
Clients the provider builds are the provider’s to dispose: it closes the
previous one when options rotate it in, and closes both the client and the
collection data client on unmount, so no abandoned socket or reconnect timer
survives the tree. A client passed as the client prop is never closed.
SmithersGatewayClient
A pre-built client. Takes precedence over
options. See the
Gateway Client reference.SmithersGatewayClientOptions
Client config (
baseUrl, token, …) used to construct a client when none is
passed.WorkspaceMode
Optional local or multiplayer collection mode. When omitted, local mode uses
the client’s base URL.
ReactNode
The provider mounts both the raw
SmithersGatewayClient context and the
TanStack DB collection provider, so every live and action hook below works
inside this one provider.SmithersGatewayProvider.ts · Tests SmithersGatewayProvider.test.ts
createGatewayReactRoot
Mounts a full custom UI in one call: builds a client, mountsSmithersGatewayProvider, creates the TanStack DB collection registry, and
renders your element. This is what a gateway-served ui entry uses.
ReactElement
required
The app root to render.
SmithersGatewayClientOptions & { rootId?: string }
Client options plus
rootId (the DOM element id to mount into; default
"root") and optional mode. Throws if the element is not found.object
The client it created, for imperative use outside React.
createGatewayReactRoot.ts · See also Custom UI
useSmithersGateway
Reads the rawSmithersGatewayClient from context, throwing if called outside
a provider: the escape hatch for client methods the hooks don’t wrap.
useSmithersGateway.ts · See also Gateway Client
SmithersCollectionsProvider
Advanced provider for supplying a customWorkspaceMode, SmithersDataClient,
or QueryClient. Most apps get this automatically from
SmithersGatewayProvider.
WorkspaceMode
Local mode uses the Gateway REST API and SSE invalidation. Multiplayer mode
uses Electric shapes for reads and the domain API for writes.
SmithersDataClient
Pre-built data client. Takes precedence over
mode.QueryClient
TanStack Query client. A default client is created when omitted.
SmithersCollectionsProvider.ts
useSmithersCollections
Read the TanStack DB collection registry and data client from context. Use this for customuseLiveQuery reads.
useSmithersCollections.ts · See also Sync
useGatewayConnectionStatus
The link’s connection lifecycle, derived from real transport traffic: RPC resolves and stream frames mark itonline, transport errors mark it offline,
auth failures mark it unauthorized.
"idle" | "connecting" | "online" | "offline" | "unauthorized"
Current connection state.
boolean
Shorthand for
status === "online".number
Epoch ms of the first failure in the current offline streak, when offline.
useGatewayConnectionStatus.ts · Tests sync.test.ts
Data hooks
Each hook reads one gateway resource as a live TanStack DB collection, sharing theGatewayAsyncState return shape unless noted. All may
be called unconditionally: pass undefined (or an empty runId) and the hook
resolves to an empty, stable state.
useGatewayRun
Live single-run record. Seeds fromgetRun, then each lifecycle frame upserts
the row without a whole-tree refetch.
string | undefined
required
The run to read.
undefined yields an empty state.object
See
GatewayAsyncState. data is the run record.useGatewayRun.ts · Tests gateway-react.test.ts
useGatewayRunEvents
Live, bounded run-event buffer (resilient stream withafterSeq resume).
Heartbeats are surfaced separately and never enter events; the array is capped
to maxEvents, most-recent wins. Returns its own shape, not GatewayAsyncState.
Frames reconstructed from persisted rows carry an optional timestampMs (epoch
millis from the stored row) so log UIs can render when an event happened without
a second lookup; those frames surface stateVersion: 0.
string | undefined
required
number
Drop events at or before this sequence number.
number
default:"1000"
Cap on the retained event buffer.
Array<GatewayEventFrame & { timestampMs?: number }>
Ordered, capped run events (heartbeats excluded).
timestampMs is set on
frames reconstructed from persisted rows.(GatewayEventFrame & { timestampMs?: number }) | undefined
The most recent heartbeat frame, surfaced apart from
events.Error | undefined
Set when the stream fails (offline / unauthorized).
boolean
True while the stream is live.
useGatewayRunEvents.ts · See also Event types
useGatewayRuns
Live run list. Seeds fromlistRuns, re-pulls on invalidate.
ListRunsRequest
Optional filters (status, workflow, paging). Defaults to all runs.
object
See
GatewayAsyncState. data is the run summaries.useGatewayRuns.ts · Tests gateway-react.test.ts
useGatewayWorkflows
Live registered-workflow list (listWorkflows).
ListWorkflowsRequest
Optional
filter.object
See
GatewayAsyncState.useGatewayWorkflows.ts
useGatewayApprovals
Live pending-approval list (listApprovals). Re-pulls when a run reaches
waiting-approval or after a submitApproval.
ListApprovalsRequest
Optional filters, e.g.
{ filter: { runId } } to scope to one run.object
See
GatewayAsyncState. data IS the array of pending
gates (ListApprovalsResponse = GatewayApprovalSummary[]); there is no
data.approvals wrapper. Each gate is
{ runId, nodeId, iteration, requestTitle?, requestSummary?, workflowKey?, requestedAtMs }
(the title is requestTitle, not title). Pass nodeId + iteration straight
into submitApproval.useGatewayApprovals.ts · See also useGatewayActions
useGatewayCrons
Live cron-schedule list (cronList). Includes enabled and disabled rows;
re-pulls after a cronCreate / cronDelete / cronRun.
CronListRequest
object
See
GatewayAsyncState.useGatewayCrons.ts
useGatewayMemoryFacts
Live cross-run memory facts (listMemoryFacts). Pass a namespace to scope;
omit it for every namespace. Read-only on the wire, so query-only.
string
Optional namespace filter.
object
See
GatewayAsyncState. refetch works; there is no
write RPC.useGatewayMemoryFacts.ts
useGatewayNodeOutput
On-demand output of one node (getNodeOutput). Built on
useGatewayRpc; disabled until both ids are set.
string | undefined
required
string | undefined
required
number
default:"0"
Loop iteration to read. Pass
0 for a normal (non-looping) task.object
See
GatewayAsyncState. data is a
{ status: "produced" | "pending" | "failed", row, schema, partial? } envelope;
the task’s output object is under data.row, not data itself. Destructure
defensively (some code paths hand you the row directly), the way .smithers/ui/vcs.tsx
does:useGatewayNodeOutput.ts
useGatewayScores
Live scorer/eval results for one run (listScores). Pass nodeId to scope one
node; an empty runId resolves to a stable empty collection. Read-only, so
query-only.
string
required
The run to score. Empty string yields an empty state.
string
Optional node scope.
object
See
GatewayAsyncState.useGatewayScores.ts
useGatewayTickets
Live work docs (tickets, plans, specs, proposals) vialistTickets. Tombstones
are filtered server-side, so every row is renderable. Pass a kind to scope.
ListTicketsRequest
Optional
kind and other filters.object
See
GatewayAsyncState.useGatewayTickets.ts
useGatewayPrompts
Live registered-prompt list (listPrompts, walked from .smithers/prompts/).
Read-only on the wire, so query-only; takes no arguments.
object
See
GatewayAsyncState.useGatewayPrompts.ts
useGatewayRpc
The generic escape hatch: call any gateway RPC by name and get its typed payload back inGatewayAsyncState. The typed hooks above wrap this; reach for
it when none exists. Disable with enabled: false (a disabled or key-changed
query clears stale data instead of surfacing it).
GatewayRpcMethod
required
The RPC method name.
GatewayRpcParams<Method>
required
Typed params for that method.
boolean
default:"true"
Skip the request when false.
readonly unknown[]
Re-fetch trigger. Defaults to the serialized
params.object
See
GatewayAsyncState.useGatewayRpc.ts · See also Gateway Client
useDelegationChain
Folded delegation-chain state for one run: the read model behind thedelegation-chain workflow UI. Enumerates every
physical dc:* node from the live run tree, fetches each node’s durable output
row once (re-checked on finish or failure), folds the rows through the pure
foldDelegation reducer, and returns the graph plus delegation actions.
Malformed or unknown rows surface in errors instead of throwing.
string | undefined
required
The run to fold.
undefined (or an empty string) yields an empty graph.DelegationGraph
Nodes keyed by logical id (status, version history, gates, attention
rollups), edges, the current phase, pending question forms, the refined
prompt, the predicted-vs-actual budget rollup, and run scores.
boolean
True until the run tree and the first output sweep have hydrated.
unknown[]
Fold issues (ignored rows) plus any tree/event/output fetch errors.
object
foldDelegation,
parseDelegationNodeId, delegationTableForNodeId) together with the
DelegationGraph and Dc*Row types, for tests and non-React consumers.
Source useDelegationChain.ts · See also <DelegationChain>
Action hooks
useGatewayActions
Bound, memoized mutation methods off the client: launch, resume, cancel, hijack, rewind, approve/deny, signal, and manage crons. Each takes the matching RPC params and returns a promise.object
useGatewayActions.ts · See also Gateway Client
useGatewayMutation
Typed mutation helper for supported domain writes. It calls the same domain API asuseGatewayActions, then invalidates the collection registry.
string
required
One of the supported domain mutations:
launchRun, resumeRun, cancelRun,
hijackRun, rewindRun, submitApproval, submitSignal, cronCreate,
cronDelete, cronRun, createTicket, updateTicket, or deleteTicket.readonly unknown[]
Reserved for compatibility. Successful mutations invalidate the collection
registry.
object
{ mutate, mutateSafe, isLoading, error }.useGatewayMutation.ts · See also useGatewayActions
Type exports
These types are exported from the same subpath for typing your own components.type
{ client, collections, queryClient } from
useSmithersCollections.type
Connection state used by
useGatewayConnectionStatus.index.ts · Tests gateway-react.test.ts
This is the UI side of the control plane. For the underlying transport and its imperative methods, see the Gateway Client reference. To embed a UI in a gateway-served workflow, see Custom UI and the Custom workflow UI guide.