Comma Agents
@comma-agents/tuiHooks

useDaemon

Access the daemon WebSocket context, send typed commands, and subscribe to typed events.

The daemon hooks provide a layered API for communicating with the daemon over WebSocket. Three hooks cover different levels of abstraction:

HookPurpose
useDaemonRaw context access -- send, on, off, connection status
useDaemonCommandSend a specific command type with auto-generated requestId
useDaemonSubscriptionSubscribe to a specific message type with auto-cleanup

All require <DaemonContextProvider> in the tree.

useDaemon

Access the raw daemon context:

import { useDaemon } from "@comma-agents/tui";

const { status, send, on, off } = useDaemon();

// Connection status
if (status === "connected") { /* daemon is reachable */ }

// Send a raw message
send({ type: "ping" });

// Register a typed listener -- returns unsubscribe
const unsub = on("agent_streaming", (message) => {
  // message is narrowed to the agent_streaming variant
});

// Remove a listener explicitly
off("agent_streaming", myListener);
FieldTypeDescription
statusWebSocketStatus"disconnected" | "connecting" | "connected" | "error"
send(message: Record<string, unknown>) => booleanSend a JSON message; returns false if socket is closed
on<T>(type, listener) => () => voidRegister a listener; returns unsubscribe function
off<T>(type, listener) => voidRemove a previously registered listener

useDaemonCommand

Returns a typed send function for a specific command type that auto-injects type and requestId:

import { useDaemonCommand } from "@comma-agents/tui";

const prepareRun = useDaemonCommand("prepare_run");
const startRun = useDaemonCommand("start_run");
const stopRun = useDaemonCommand("stop_run");
const sendInput = useDaemonCommand("user_input");

// Returns the generated requestId, or null if the socket is not open
const id = startStrategy({
  strategyPath: "path/to/strategy.json",
  input: "Build a calculator",
});

useDaemonSubscription

Subscribe to a specific daemon message type with automatic cleanup on unmount:

import { useDaemonSubscription } from "@comma-agents/tui";

useDaemonSubscription("strategy_completed", (message) => {
  // message has type: StrategyCompletedMessage
  console.log(`Run ${message.runId} completed: ${message.summary}`);
});

Optionally scope the subscription to a specific run:

useDaemonSubscription(
  "agent_streaming",
  (message) => { /* Only receives streaming events for this run */ },
  session.daemonRunId,
);

Typed Helpers

import type {
  DaemonMessageOf,
  ClientMessageOf,
  DaemonMessageListener,
} from "@comma-agents/tui";
  • DaemonMessageOf<"agent_streaming"> -- Narrows to the streaming variant
  • ClientMessageOf<"prepare_run"> -- Narrows to the prepare command variant
  • DaemonMessageListener<"strategy_completed"> -- Typed listener callback

On this page