# socket api

While hrdx runs it serves a control API on a unix socket next to the state file (hrdx.sock), so scripts, editors, and coding agents can inspect and drive a running session. Disable with --api=false. The protocol is newline-delimited JSON: one request per line, one response line with the same id.

# macOS
$ SOCK="$HOME/Library/Application Support/hrdx/hrdx.sock"
 
# Linux
$ SOCK="$XDG_CONFIG_HOME/hrdx/hrdx.sock"
 
# inspect and drive the running session
$ echo '{"id": "1", "method": "status"}' | nc -U "$SOCK"
$ echo '{"id": "2", "method": "workspace.create", "params": {"path": "~/Developer/api", "agent": "claude"}}' | nc -U "$SOCK"
$ echo '{"id": "3", "method": "pane.create", "params": {"workspace": "api", "kind": "shell", "split": "down"}}' | nc -U "$SOCK"
$ echo '{"id": "3b", "method": "pane.create", "params": {"workspace": "api", "kind": "shell", "split": "float", "anchor": "center", "width_pct": 40, "height_pct": 30}}' | nc -U "$SOCK"
$ echo '{"id": "4", "method": "pane.send_text", "params": {"pane_id": 3, "text": "run the tests", "enter": true}}' | nc -U "$SOCK"
$ echo '{"id": "5", "method": "pane.wait", "params": {"pane_id": 3, "until": "idle"}}' | nc -U "$SOCK"
$ echo '{"id": "6", "method": "pane.read", "params": {"pane_id": 3}}' | nc -U "$SOCK"
$ echo '{"id": "7", "method": "menu.register", "params": {"target": "pane", "label": "Run linter", "action_id": "custom.run_linter"}}' | nc -U "$SOCK"
methodeffect
pingliveness check, returns pong
statusworkspaces, tabs, and panes with id, kind, and state
workspace.createopen a directory as a workspace
workspace.closeclose a workspace by name or path
pane.createadd a pane (split: right, down, tab, float)
pane.send_texttype into a pane, optionally press enter
pane.readthe pane's visible screen as plain text
pane.waitblock until a pane's agent is idle or busy
pane.closeclose a pane by id
menu.registeradd a process-local pane, tab, or sidebar context-menu entry
events.subscribekeep the connection open and push events

## events

After events.subscribe the connection stays open and hrdx pushes lines like:

{"event": "pane.busy_changed", "data": {"pane_id": 3, "busy": false}}

Events: workspace.created, workspace.closed, pane.created, pane.closed, pane.busy_changed, and menu.action, so a script can react the moment an agent finishes or a custom menu action is selected instead of polling. pane.wait plus pane.send_text is enough to build simple agent pipelines: prompt an agent, wait until it is idle, read the screen, move on.

## floating panes

Create a tab-scoped pane above the split layout with split set to float. width_pct and height_pct are required integers from 1 through 100. anchor defaults to center and also accepts top, bottom, left, or right.

{"id":"3b","method":"pane.create","params":{"workspace":"api","kind":"shell","split":"float","anchor":"center","width_pct":40,"height_pct":30}}

Floating panes do not change split ratios and are not shown in the sidebar or restored after hrdx restarts. Multiple panes stack in creation or focus order. Close one through its title-bar x or with pane.close. The status response marks them with floating, anchor, width_pct, and height_pct fields.

## custom menu actions

Register an ephemeral item in the pane, tab, or sidebar context menu. The item appears after the built-in actions. Re-registering the same action_id replaces it; registrations last until hrdx exits.

{"id":"7","method":"menu.register","params":{"target":"pane","label":"Run linter","action_id":"custom.run_linter"}}

Selecting the item publishes a best-effort menu.action event to event subscribers. It includes the selected target's pane, tab, and workspace context when applicable.

{"event":"menu.action","data":{"action_id":"custom.run_linter","target":"pane","pane_id":3,"workspace":"api","path":"/path/to/api","tab_index":0}}