aboutsummaryrefslogtreecommitdiff
path: root/website/src/content/docs/socket-api.mdx
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-07-15 19:23:30 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-07-15 19:25:20 +0300
commit17208b0641a702af60d96e15004f72f226bac0de (patch)
tree2912b4a7d59f1ceecd73b4db80d352d1e730bc80 /website/src/content/docs/socket-api.mdx
parenta0678a38b9426b011f66e1b88ff7aaa9bf877104 (diff)
docs: finalize next release documentation
Diffstat (limited to 'website/src/content/docs/socket-api.mdx')
-rw-r--r--website/src/content/docs/socket-api.mdx87
1 files changed, 67 insertions, 20 deletions
diff --git a/website/src/content/docs/socket-api.mdx b/website/src/content/docs/socket-api.mdx
index 600238b9..cc8d5675 100644
--- a/website/src/content/docs/socket-api.mdx
+++ b/website/src/content/docs/socket-api.mdx
@@ -100,10 +100,11 @@ Raw socket method names use dot notation:
| Notification | `notification.show` |
| Client | `client.window_title.set`, `client.window_title.clear` |
| Session | `session.snapshot` |
-| Workspace | `workspace.create`, `workspace.list`, `workspace.get`, `workspace.focus`, `workspace.rename`, `workspace.move`, `workspace.close` |
+| Workspace | `workspace.create`, `workspace.list`, `workspace.get`, `workspace.focus`, `workspace.rename`, `workspace.move`, `workspace.report_metadata`, `workspace.close` |
| Worktree | `worktree.list`, `worktree.create`, `worktree.open`, `worktree.remove` |
| Tab | `tab.create`, `tab.list`, `tab.get`, `tab.focus`, `tab.rename`, `tab.move`, `tab.close` |
-| Pane | `pane.split`, `pane.swap`, `pane.move`, `pane.zoom`, `pane.layout`, `pane.process_info`, `pane.neighbor`, `pane.edges`, `pane.focus_direction`, `pane.resize`, `pane.list`, `pane.current`, `pane.get`, `pane.rename`, `pane.send_text`, `pane.send_keys`, `pane.send_input`, `pane.read`, `pane.report_agent`, `pane.report_agent_session`, `pane.report_metadata`, `pane.clear_agent_authority`, `pane.release_agent`, `pane.close`, `pane.wait_for_output` |
+| Pane | `pane.split`, `pane.swap`, `pane.move`, `pane.zoom`, `pane.layout`, `pane.process_info`, `pane.neighbor`, `pane.edges`, `pane.focus_direction`, `pane.resize`, `pane.list`, `pane.current`, `pane.get`, `pane.rename`, `pane.send_text`, `pane.send_keys`, `pane.send_input`, `pane.read`, `pane.graphics.info`, `pane.graphics.set`, `pane.graphics.clear`, `pane.graphics.stream`, `pane.report_agent`, `pane.report_agent_session`, `pane.report_metadata`, `pane.clear_agent_authority`, `pane.release_agent`, `pane.close`, `pane.wait_for_output` |
+| Popup | `popup.close` |
| Layout | `layout.export`, `layout.apply`, `layout.set_split_ratio` |
| Agent | `agent.list`, `agent.get`, `agent.read`, `agent.explain`, `agent.send`, `agent.rename`, `agent.focus`, `agent.start` |
| Events | `events.subscribe`, `events.wait` |
@@ -162,6 +163,31 @@ pane.
Clients can treat `offset_from_bottom == 0` as at-bottom state.
+### Experimental pane graphics
+
+Pane graphics let a plugin place image data over a pane. They are available
+only when `[experimental].kitty_graphics = true`; otherwise every pane graphics
+method returns `feature_disabled`. Calling `pane.graphics.info` returns the
+attached client's cell width and height in pixels without creating a graphics
+layer. `pane.graphics.set` accepts `png`, `rgb`, or `rgba` data in `data_base64`,
+and `pane.graphics.clear` removes the layer.
+
+```json
+{"id":"graphics_info","method":"pane.graphics.info","params":{"pane_id":"w1:p1"}}
+{"id":"graphics_set","method":"pane.graphics.set","params":{"pane_id":"w1:p1","format":"png","image_width":800,"image_height":600,"data_base64":"...","placement":{"viewport_col":0,"viewport_row":0,"grid_cols":80,"grid_rows":30}}}
+{"id":"graphics_clear","method":"pane.graphics.clear","params":{"pane_id":"w1:p1"}}
+```
+
+For repeated frames, open a dedicated socket with `pane.graphics.stream`. After
+Herdr replies with `ok`, send one JSON header and then exactly `data_length` raw
+bytes per frame. A stream owns that pane's graphics layer until the socket
+closes; concurrent set, clear, or stream requests return `stream_conflict`.
+
+```json
+{"id":"graphics_stream","method":"pane.graphics.stream","params":{"pane_id":"w1:p1"}}
+{"format":"png","image_width":800,"image_height":600,"data_length":12345,"placement":{"viewport_col":0,"viewport_row":0,"grid_cols":80,"grid_rows":30}}
+```
+
`pane.layout` returns the tab layout snapshot with `workspace_id`, `tab_id`,
`zoomed`, outer `area`, `focused_pane_id`, pane rects, and split rects/ratios.
`pane.neighbor` and `pane.edges` include that same layout snapshot so clients
@@ -479,12 +505,20 @@ Open a managed terminal UI:
`plugin.pane.open` requires an installed, enabled, platform-compatible plugin,
then launches the requested manifest `[[panes]]` entrypoint as an argv-backed
terminal pane. Manifest pane `placement` defaults to `overlay`; request
-`placement` overrides the manifest with `overlay`, `split`, `tab`, or `zoomed`.
-Overlay panes target the active pane. Split and zoomed panes target an existing
-pane; tab panes can target a workspace. The pane
-behaves like a normal Herdr pane, but `plugin.pane.focus` and
-`plugin.pane.close` only operate on panes opened through the plugin API. Focus
-returns `plugin_pane_focused`; close returns `plugin_pane_closed`.
+`placement` overrides the manifest with `overlay`, `popup`, `split`, `tab`, or
+`zoomed`. Overlay and popup placements use the active tiled pane as launch
+context. Popup terminals are session-modal and do not change the tab layout;
+optional `width` and `height` fields set their outer size as terminal cells or
+percentages such as `"80%"`. Omitted dimensions default to half the terminal
+size, with too-small values clamped to the popup minimum. A popup has no pane
+ID, remains outside all `pane.*` and agent APIs, emits no pane lifecycle events,
+leaves plugin focus context on the underlying tiled pane, and does not export
+`HERDR_PANE_ID` to its process. Popup launch returns `ok`; `popup.close` closes
+the active popup and returns
+`popup_not_open` when none exists. Split and zoomed panes target an existing
+pane; tab panes can target a workspace. Split, tab, zoomed, and overlay panes
+behave like normal Herdr panes, and `plugin.pane.focus` and `plugin.pane.close`
+continue to operate on those panes.
## Socket transport
@@ -542,15 +576,12 @@ Integrations report agent state with `pane.report_agent`.
"source": "custom:docs",
"agent": "docs-bot",
"state": "working",
- "message": "building docs",
- "custom_status": "indexing"
+ "message": "building docs"
}
}
```
-`state` is semantic. It affects waits, notifications, and rollups.
-
-`custom_status` is visual. It can show a short activity label like `indexing` without changing semantic behavior.
+`state` is semantic. It affects waits, notifications, and rollups. Report display-only values separately through metadata.
Session-only official integrations report native session references with `pane.report_agent_session`. State-reporting integrations can still include native session references in `pane.report_agent`. State-independent session reports do not affect waits, notifications, or rollups.
@@ -584,6 +615,8 @@ If no native session reference is stored, the field is omitted.
`pane.get`, `pane.list`, `agent.get`, and `agent.list` also expose `foreground_cwd` when Herdr can resolve the cwd of the process currently controlling the pane PTY. The existing `cwd` field remains the pane/workspace cwd used for labels, follow-cwd behavior, and restored session state.
+`PaneInfo` and `AgentInfo` expose optional `terminal_title` and `terminal_title_stripped` fields. `terminal_title` is the latest OSC 0/2 title after safety normalization. `terminal_title_stripped` removes one recognized leading activity or spinner glyph and following whitespace. These server-owned values are ephemeral across a cold restart and are independent of the metadata `title` and semantic agent state.
+
Use `pane.report_metadata` when a user hook wants to customize presentation without taking over lifecycle state from a Herdr integration.
```json
@@ -596,26 +629,39 @@ Use `pane.report_metadata` when a user hook wants to customize presentation with
"agent": "claude",
"title": "Refactor auth middleware",
"display_agent": "Claude: auth",
- "custom_status": "refactor auth",
"state_labels": {
"working": "refactoring auth",
"idle": "ready",
"done": "review ready"
},
+ "tokens": {
+ "summary": "refactor auth",
+ "model": "opus"
+ },
"ttl_ms": 3600000
}
}
```
-Metadata reports are display-only. Valid metadata can override the pane title, displayed agent name, compact activity label, and visible state labels. `working`, `blocked`, `idle`, waits, notifications, and rollups still come from semantic state. Native session restore comes from stored official session references. `agent` is an optional guard for the authoritative agent label; `applies_to_source` is an optional guard for the active lifecycle authority source. Use `display_agent` to change the visible name. `state_labels` keys must be `idle`, `working`, `blocked`, `done`, or `unknown`. Use clear fields such as `clear_custom_status: true` with the same `source` to remove one presentation override.
+Metadata reports are display-only. Valid metadata can override the pane title, displayed agent name, visible state labels, and arbitrary named tokens. `working`, `blocked`, `idle`, waits, notifications, and rollups still come from semantic state. Native session restore comes from stored official session references. `agent` is an optional guard for presentation fields against the authoritative agent label; `applies_to_source` similarly guards presentation fields against the active lifecycle authority source. These guards do not apply to token patches: token reporters own clearing and TTL refresh. Use `display_agent` to change the visible name. `state_labels` keys must be `idle`, `working`, `blocked`, `done`, or `unknown`.
+
+Token maps are per-resource patches. A string sets a key, JSON `null` clears it, and omitted keys remain unchanged. The latest accepted update wins. Optional TTL applies independently to token keys updated by that report. Pane tokens are exposed by pane and agent get/list responses and can be rendered as `$name` in Agent sidebar rows. A report may mention at most 16 token keys, and a pane or workspace may retain at most 32 keys. Token names are 1–32 ASCII letters, digits, underscores, or hyphens.
+
+Workspace tokens use the same contract:
+
+```json
+{"id":"req_3","method":"workspace.report_metadata","params":{"workspace_id":"w1","source":"user:jj","tokens":{"jj_status":"2 changes","old":null},"ttl_ms":5000}}
+```
+
+Workspace get/list responses expose the resulting `tokens` map, and Space sidebar rows can render values such as `$jj_status`. Changes and TTL expiry emit `workspace.metadata_updated` with the latest workspace snapshot. This metadata event is available to API subscribers but does not invoke plugin event hooks.
-Presentation text is normalized before storage. Herdr trims surrounding whitespace, removes control characters, caps `custom_status` at 32 characters, and caps `title`, `display_agent`, and each state label at 80 characters. Empty normalized values are ignored.
+Presentation text is normalized before storage. Herdr trims surrounding whitespace, removes control characters, and caps `title`, `display_agent`, each state label, and token values at 80 characters. Empty normalized token values clear that key.
`source` and `applies_to_source` are source identifiers. They must be 80 characters or fewer and may contain only ASCII letters, digits, colon, dot, underscore, and hyphen.
-Use `ttl_ms` for short-lived metadata. It must be between `1` and `86400000` milliseconds. Omit `ttl_ms` for metadata that should stay until replaced, cleared, or the pane closes. When the TTL expires, Herdr removes that source's metadata and emits a presentation change if the visible pane presentation changed.
+Use `ttl_ms` for short-lived metadata. It must be between `1` and `86400000` milliseconds. Omit `ttl_ms` for metadata that should stay until replaced, cleared, or the pane/workspace closes. Presentation fields retain their existing source-scoped expiry behavior; each token updated by the call receives its own deadline. Token metadata is not restored after a server restart.
-Use `seq` when a hook may send updates out of order. For the same `source`, reports with a sequence number less than or equal to the last accepted sequence are accepted by the API but ignored by the pane state.
+Use `seq` when a hook may send updates out of order. For the same `source`, reports with a sequence number less than or equal to the last accepted sequence are accepted by the API but ignored by the pane state. A pane or workspace accepts sequenced token reports from at most 32 distinct sources during its lifetime; clearing or expiry does not release those source slots.
## Event subscriptions
@@ -635,14 +681,15 @@ Subscribe to events when you need a long-lived stream:
The first response acknowledges the subscription. Later lines are pushed events.
-Workspace event subscriptions include `workspace.created`, `workspace.updated`, `workspace.renamed`, `workspace.moved`, `workspace.closed`, and `workspace.focused`. Workspace events describe Herdr UI/runtime lifecycle. `workspace.created` includes optional `workspace.worktree` provenance when the workspace belongs to a worktree group. `workspace.moved` includes the moved `workspace_id`, requested `insert_index`, and updated ordered `workspaces` list. `workspace.closed` includes a final `workspace` snapshot when Herdr can still identify it before removal.
+Workspace event subscriptions include `workspace.created`, `workspace.updated`, `workspace.metadata_updated`, `workspace.renamed`, `workspace.moved`, `workspace.closed`, and `workspace.focused`. `workspace.metadata_updated` reports token changes and TTL expiry without invoking plugin event hooks. Other workspace events describe Herdr UI/runtime lifecycle. `workspace.created` includes optional `workspace.worktree` provenance when the workspace belongs to a worktree group. `workspace.moved` includes the moved `workspace_id`, requested `insert_index`, and updated ordered `workspaces` list. `workspace.closed` includes a final `workspace` snapshot when Herdr can still identify it before removal.
Tab event subscriptions include `tab.created`, `tab.closed`, `tab.focused`,
`tab.renamed`, and `tab.moved`. `tab.moved` includes the moved `tab_id`,
`workspace_id`, requested `insert_index`, and updated ordered `tabs` list for
that workspace.
-Pane event subscriptions include `pane.created`, `pane.closed`, `pane.focused`,
+Pane event subscriptions include `pane.created`, `pane.updated`, `pane.closed`, `pane.focused`,
`pane.moved`, `pane.exited`, `pane.agent_detected`,
`pane.output_matched`, `pane.agent_status_changed`, and `pane.scroll_changed`.
+Terminal-title changes can emit `pane.updated`, but spinner-only raw-title changes do not emit it when `terminal_title_stripped` is unchanged.
`pane.scroll_changed` is scoped to one `pane_id` and emits `pane_id`,
`workspace_id`, and the current `scroll` metrics whenever Herdr observes a
changed scroll snapshot.