effect-herdr-sdk 0.0.0-stage → 0.0.1-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,444 @@
1
+ // GENERATED by scripts/gen from schema/herdr-api.schema.json — do not edit.
2
+ // herdr protocol 22, schema_version 1.
3
+
4
+ export type AgentInfo = { "agent"?: string | null; "agent_session"?: (AgentSessionInfo) | (null); "agent_status": AgentStatus; "cwd"?: string | null; "display_agent"?: string | null; "focused": boolean; "foreground_cwd"?: string | null; "interactive_ready"?: boolean; "launch_pending"?: boolean; "name"?: string | null; "pane_id": string; "revision": number; "screen_detection_skipped"?: boolean; "state_change_seq"?: number; "state_labels"?: { [key: string]: string; }; "tab_id": string; "terminal_id": string; "terminal_title"?: string | null; "terminal_title_stripped"?: string | null; "title"?: string | null; "tokens"?: { [key: string]: string; }; "workspace_id": string; };
5
+
6
+ export type AgentManifestInfo = { "active_version"?: string | null; "agent": string; "cached_remote_version"?: string | null; "local_override_shadowing_remote": boolean; "remote_last_checked_unix"?: number | null; "remote_update_error"?: string | null; "remote_update_result"?: string | null; "source": string; "source_kind": string; "warning"?: string | null; };
7
+
8
+ export type AgentSessionInfo = { "agent": string; "kind": AgentSessionRefKind; "source": string; "value": string; };
9
+
10
+ export type AgentSessionRefKind = "id" | "path";
11
+
12
+ export type AgentStatus = "idle" | "working" | "blocked" | "done" | "unknown";
13
+
14
+ export type ClientWindowTitleReason = "set" | "cleared" | "no_foreground_client";
15
+
16
+ export type ConfigReloadStatus = "applied" | "partial" | "failed";
17
+
18
+ export type EventData = ({ "type": "workspace_created"; "workspace": WorkspaceInfo; }) | ({ "type": "workspace_updated"; "workspace": WorkspaceInfo; }) | ({ "type": "workspace_metadata_updated"; "workspace": WorkspaceInfo; }) | ({ "type": "workspace_closed"; "workspace"?: (WorkspaceInfo) | (null); "workspace_id": string; }) | ({ "label": string; "type": "workspace_renamed"; "workspace_id": string; }) | ({ "insert_index": number; "type": "workspace_moved"; "workspace_id": string; "workspaces": Array<WorkspaceInfo>; }) | ({ "before_workspace_id"?: string | null; "type": "workspace_reordered"; "workspace_ids": Array<string>; "workspaces": Array<WorkspaceInfo>; }) | ({ "type": "workspace_focused"; "workspace_id": string; }) | ({ "type": "worktree_created"; "workspace": WorkspaceInfo; "worktree": WorktreeInfo; }) | ({ "already_open": boolean; "type": "worktree_opened"; "workspace": WorkspaceInfo; "worktree": WorktreeInfo; }) | ({ "forced": boolean; "type": "worktree_removed"; "workspace"?: (WorkspaceInfo) | (null); "workspace_id": string; "worktree": WorktreeInfo; }) | ({ "tab": TabInfo; "type": "tab_created"; }) | ({ "tab_id": string; "type": "tab_closed"; "workspace_id": string; }) | ({ "label": string; "tab_id": string; "type": "tab_renamed"; "workspace_id": string; }) | ({ "insert_index": number; "tab_id": string; "tabs": Array<TabInfo>; "type": "tab_moved"; "workspace_id": string; }) | ({ "tab_id": string; "type": "tab_focused"; "workspace_id": string; }) | ({ "pane": PaneInfo; "type": "pane_created"; }) | ({ "pane_id": string; "type": "pane_closed"; "workspace_id": string; }) | ({ "pane": PaneInfo; "type": "pane_updated"; }) | ({ "pane_id": string; "type": "pane_focused"; "workspace_id": string; }) | ({ "closed_tab_id"?: string | null; "closed_workspace_id"?: string | null; "created_tab"?: (TabInfo) | (null); "created_workspace"?: (WorkspaceInfo) | (null); "pane": PaneInfo; "previous_pane_id": string; "previous_tab_id": string; "previous_workspace_id": string; "type": "pane_moved"; }) | ({ "pane_id": string; "revision": number; "type": "pane_output_changed"; "workspace_id": string; }) | ({ "pane_id": string; "type": "pane_exited"; "workspace_id": string; }) | ({ "agent"?: string | null; "final_status"?: (AgentStatus) | (null); "pane_id": string; "released"?: boolean; "type": "pane_agent_detected"; "workspace_id": string; }) | ({ "agent"?: string | null; "agent_status": AgentStatus; "display_agent"?: string | null; "pane_id": string; "state_labels"?: { [key: string]: string; }; "title"?: string | null; "type": "pane_agent_status_changed"; "workspace_id": string; }) | ({ "layout": PaneLayoutSnapshot; "type": "layout_updated"; });
19
+
20
+ export type EventEnvelope = { "data": EventData; "event": EventKind; };
21
+
22
+ export type EventKind = "workspace_created" | "workspace_updated" | "workspace_metadata_updated" | "workspace_closed" | "workspace_renamed" | "workspace_moved" | "workspace_reordered" | "workspace_focused" | "worktree_created" | "worktree_opened" | "worktree_removed" | "tab_created" | "tab_closed" | "tab_renamed" | "tab_moved" | "tab_focused" | "pane_created" | "pane_closed" | "pane_updated" | "pane_focused" | "pane_moved" | "pane_output_changed" | "pane_exited" | "pane_agent_detected" | "pane_agent_status_changed" | "layout_updated";
23
+
24
+ export type InstalledPluginInfo = { "actions"?: Array<PluginManifestAction>; "build"?: Array<PluginManifestBuild>; "description"?: string | null; "enabled": boolean; "events"?: Array<PluginManifestEventHook>; "link_handlers"?: Array<PluginManifestLinkHandler>; "manifest_path": string; "min_herdr_version"?: string; "name": string; "panes"?: Array<PluginManifestPane>; "platforms"?: Array<PluginPlatform> | null; "plugin_id": string; "plugin_root": string; "source"?: PluginSourceInfo; "startup"?: Array<PluginManifestStartup>; "version": string; /** Warnings collected at link time or on registry load (e.g. unknown event names,
25
+ missing manifest file). Non-fatal — the entry is kept and surfaced by plugin.list. */ "warnings"?: Array<string>; };
26
+
27
+ export type IntegrationInfo = { "available": boolean; "command": string; "label": string; "state": IntegrationState; "target": IntegrationTarget; };
28
+
29
+ export type IntegrationInstallResult = { "messages": Array<string>; };
30
+
31
+ export type IntegrationState = "not_installed" | "current" | "outdated";
32
+
33
+ export type IntegrationTarget = "pi" | "omp" | "claude" | "codex" | "copilot" | "devin" | "droid" | "kimi" | "opencode" | "kilo" | "hermes" | "qodercli" | "qwen" | "cursor" | "mastracode" | "antigravity_cli" | "grok";
34
+
35
+ export type IntegrationUninstallResult = { "messages": Array<string>; };
36
+
37
+ export type LayoutDescription = { "focused_pane_id": string; "root": LayoutNode; "tab_id": string; "workspace_id": string; "zoomed": boolean; };
38
+
39
+ export type LayoutNode = ({ "command"?: Array<string> | null; "cwd"?: string | null; "env"?: { [key: string]: string; }; "label"?: string | null; "pane_id"?: string | null; "type": "pane"; }) | ({ "direction": SplitDirection; "first": LayoutNode; "ratio": number; "second": LayoutNode; "type": "split"; });
40
+
41
+ export type NotificationShowReason = "shown" | "disabled" | "rate_limited" | "no_foreground_client" | "busy";
42
+
43
+ export type PaneDirection = "left" | "right" | "up" | "down";
44
+
45
+ export type PaneEdgesResult = { "down": boolean; "layout": PaneLayoutSnapshot; "left": boolean; "pane_id": string; "right": boolean; "up": boolean; };
46
+
47
+ export type PaneFocusDirectionReason = "no_neighbor";
48
+
49
+ export type PaneFocusDirectionResult = { "changed": boolean; "focused_pane_id"?: string | null; "layout": PaneLayoutSnapshot; "reason"?: (PaneFocusDirectionReason) | (null); "source_pane_id": string; };
50
+
51
+ export type PaneInfo = { "agent"?: string | null; "agent_session"?: (AgentSessionInfo) | (null); "agent_status": AgentStatus; "cwd"?: string | null; "display_agent"?: string | null; "focused": boolean; "foreground_cwd"?: string | null; "label"?: string | null; "pane_id": string; "revision": number; "scroll"?: (PaneScrollInfo) | (null); "state_labels"?: { [key: string]: string; }; "tab_id": string; "terminal_id": string; "terminal_title"?: string | null; "terminal_title_stripped"?: string | null; "title"?: string | null; "tokens"?: { [key: string]: string; }; "workspace_id": string; };
52
+
53
+ export type PaneLayoutPane = { "focused": boolean; "pane_id": string; "rect": PaneLayoutRect; };
54
+
55
+ export type PaneLayoutRect = { "height": number; "width": number; "x": number; "y": number; };
56
+
57
+ export type PaneLayoutSnapshot = { "area": PaneLayoutRect; "focused_pane_id": string; "panes": Array<PaneLayoutPane>; "splits": Array<PaneLayoutSplit>; "tab_id": string; "workspace_id": string; "zoomed": boolean; };
58
+
59
+ export type PaneLayoutSplit = { "direction": SplitDirection; "id": string; "ratio": number; "rect": PaneLayoutRect; };
60
+
61
+ /** Inclusive display-cell columns on a pane's current viewport. */
62
+ export type PaneLinkRegion = { "end_col": number; "row": number; "start_col": number; };
63
+
64
+ export type PaneMoveReason = "same_tab" | "zoomed_tab";
65
+
66
+ export type PaneMoveResult = { "changed": boolean; "closed_tab_id"?: string | null; "closed_workspace_id"?: string | null; "created_tab"?: (TabInfo) | (null); "created_workspace"?: (WorkspaceInfo) | (null); "focused_pane_id": string; "pane": PaneInfo; "previous_pane_id": string; "previous_tab_id": string; "previous_workspace_id": string; "reason"?: (PaneMoveReason) | (null); "source_layout"?: (PaneLayoutSnapshot) | (null); "target_layout": PaneLayoutSnapshot; };
67
+
68
+ export type PaneNeighborResult = { "direction": PaneDirection; "layout": PaneLayoutSnapshot; "neighbor_pane_id"?: string | null; "pane_id": string; };
69
+
70
+ export type PaneProcessInfo = { "foreground_process_group_id"?: number | null; "foreground_processes"?: Array<PaneProcessInfoProcess>; "pane_id": string; "shell_pid"?: number | null; "tty"?: string | null; };
71
+
72
+ export type PaneProcessInfoProcess = { "argv"?: Array<string> | null; "argv0"?: string | null; "cmdline"?: string | null; "cwd"?: string | null; "name": string; "pid": number; };
73
+
74
+ export type PaneReadResult = { "format": ReadFormat; "pane_id": string; "revision": number; "source": ReadSource; "tab_id": string; "text": string; "truncated": boolean; "workspace_id": string; };
75
+
76
+ export type PaneResizeReason = "unchanged";
77
+
78
+ export type PaneResizeResult = { "changed": boolean; "focused_pane_id": string; "layout": PaneLayoutSnapshot; "pane_id": string; "reason"?: (PaneResizeReason) | (null); };
79
+
80
+ export type PaneScrollInfo = { "max_offset_from_bottom": number; "offset_from_bottom": number; "viewport_rows": number; };
81
+
82
+ export type PaneSwapReason = "no_neighbor" | "same_pane" | "not_found" | "cross_tab";
83
+
84
+ export type PaneSwapResult = { "changed": boolean; "focused_pane_id": string; "layout": PaneLayoutSnapshot; "reason"?: (PaneSwapReason) | (null); "source_pane_id": string; "target_pane_id"?: string | null; };
85
+
86
+ export type PaneTextPoint = { "col": number; "row": number; };
87
+
88
+ export type PaneTextRange = { "end": PaneTextPoint; "start": PaneTextPoint; };
89
+
90
+ export type PaneZoomReason = "single_pane" | "already_zoomed" | "already_unzoomed";
91
+
92
+ export type PaneZoomResult = { "changed": boolean; "focus_changed": boolean; "focused_pane_id": string; "layout": PaneLayoutSnapshot; "pane_id": string; "reason"?: (PaneZoomReason) | (null); "zoom_changed": boolean; "zoomed": boolean; };
93
+
94
+ export type PluginActionContext = "global" | "workspace" | "tab" | "pane" | "selection";
95
+
96
+ export type PluginActionInfo = { "action_id": string; "command": Array<string>; "contexts"?: Array<PluginActionContext>; "description"?: string | null; "platforms"?: Array<PluginPlatform> | null; "plugin_id": string; "title": string; };
97
+
98
+ export type PluginCommandLogInfo = { "action_id"?: string | null; "command": Array<string>; "error"?: string | null; "event"?: string | null; "exit_code"?: number | null; "finished_unix_ms"?: number | null; "log_id": string; "plugin_id": string; "started_unix_ms": number; "status": PluginCommandStatus; "stderr"?: string | null; "stdout"?: string | null; };
99
+
100
+ export type PluginCommandStatus = "running" | "succeeded" | "failed";
101
+
102
+ export type PluginInvocationContext = { "clicked_url"?: string | null; "correlation_id"?: string | null; "focused_pane_agent"?: string | null; "focused_pane_cwd"?: string | null; "focused_pane_id"?: string | null; "focused_pane_status"?: (AgentStatus) | (null); "invocation_source"?: string | null; "link_handler_id"?: string | null; "selected_text"?: string | null; "tab_id"?: string | null; "tab_label"?: string | null; "workspace_cwd"?: string | null; "workspace_id"?: string | null; "workspace_label"?: string | null; "worktree"?: (WorkspaceWorktreeInfo) | (null); };
103
+
104
+ export type PluginManifestAction = { "command": Array<string>; "contexts"?: Array<PluginActionContext>; "description"?: string | null; "id": string; "platforms"?: Array<PluginPlatform> | null; "title": string; };
105
+
106
+ export type PluginManifestBuild = { "command": Array<string>; "platforms"?: Array<PluginPlatform> | null; };
107
+
108
+ export type PluginManifestEventHook = { "command": Array<string>; "on": string; "platforms"?: Array<PluginPlatform> | null; };
109
+
110
+ export type PluginManifestLinkHandler = { "action": string; "id": string; "pattern": string; "platforms"?: Array<PluginPlatform> | null; "title": string; };
111
+
112
+ export type PluginManifestPane = { "command": Array<string>; "description"?: string | null; "height"?: (PopupSize) | (null); "id": string; "placement"?: PluginPanePlacement; "platforms"?: Array<PluginPlatform> | null; "title": string; "width"?: (PopupSize) | (null); };
113
+
114
+ export type PluginManifestStartup = { "command": Array<string>; "platforms"?: Array<PluginPlatform> | null; };
115
+
116
+ export type PluginPaneInfo = { "entrypoint": string; "pane": PaneInfo; "plugin_id": string; };
117
+
118
+ export type PluginPanePlacement = "overlay" | "popup" | "split" | "tab" | "zoomed";
119
+
120
+ export type PluginPlatform = "linux" | "macos" | "windows";
121
+
122
+ export type PluginSourceInfo = { "installed_unix_ms"?: number | null; "kind"?: PluginSourceKind; "managed_path"?: string | null; "owner"?: string | null; "repo"?: string | null; "requested_ref"?: string | null; "resolved_commit"?: string | null; "subdir"?: string | null; };
123
+
124
+ export type PluginSourceKind = "local" | "github";
125
+
126
+ export type PopupSize = (number) | (string);
127
+
128
+ export type ReadFormat = "text" | "ansi";
129
+
130
+ export type ReadSource = "visible" | "recent" | "recent_unwrapped" | "detection";
131
+
132
+ export type ServerCapabilities = { "detached_server_daemon"?: boolean; /** Stable client-owned endpoint generation supported by this server. */ "endpoint_protocol_generation"?: number | null; /** Whether this server supports endpoint health probes. */ "health_check"?: boolean; "live_handoff": boolean; /** Whether this server supports explicit client-shell surface interest. */ "surface_interest"?: boolean; };
133
+
134
+ export type SessionSnapshot = { "agents": Array<AgentInfo>; "focused_pane_id"?: string | null; "focused_tab_id"?: string | null; "focused_workspace_id"?: string | null; "layouts": Array<PaneLayoutSnapshot>; "panes": Array<PaneInfo>; "protocol": number; "tabs": Array<TabInfo>; "version": string; "workspaces": Array<WorkspaceInfo>; };
135
+
136
+ export type SplitDirection = "right" | "down";
137
+
138
+ export type TabInfo = { "agent_status": AgentStatus; "focused": boolean; "label": string; "number": number; "pane_count": number; "tab_id": string; "workspace_id": string; };
139
+
140
+ export type WorkspaceInfo = { "active_tab_id": string; "agent_status": AgentStatus; "focused": boolean; "label": string; "number": number; "pane_count": number; "tab_count": number; "tokens"?: { [key: string]: string; }; "workspace_id": string; "worktree"?: (WorkspaceWorktreeInfo) | (null); };
141
+
142
+ export type WorkspaceWorktreeInfo = { "checkout_path": string; "is_linked_worktree": boolean; "repo_key": string; "repo_name": string; "repo_root": string; };
143
+
144
+ export type WorktreeInfo = { "branch"?: string | null; "is_bare": boolean; "is_detached": boolean; "is_linked_worktree": boolean; "is_prunable": boolean; "label": string; "open_workspace_id"?: string | null; "path": string; };
145
+
146
+ export type WorktreeSourceInfo = { "repo_key": string; "repo_name": string; "repo_root": string; "source_checkout_path": string; "source_workspace_id"?: string | null; };
147
+
148
+ export type Result_pong = { "capabilities"?: (ServerCapabilities) | (null); "protocol": number; "type": "pong"; "version": string; };
149
+
150
+ export type Result_session_snapshot = { "snapshot": SessionSnapshot; "type": "session_snapshot"; };
151
+
152
+ export type Result_workspace_info = { "type": "workspace_info"; "workspace": WorkspaceInfo; };
153
+
154
+ export type Result_workspace_created = { "root_pane": PaneInfo; "tab": TabInfo; "type": "workspace_created"; "workspace": WorkspaceInfo; };
155
+
156
+ export type Result_workspace_list = { "type": "workspace_list"; "workspaces": Array<WorkspaceInfo>; };
157
+
158
+ export type Result_worktree_list = { "source": WorktreeSourceInfo; "type": "worktree_list"; "worktrees": Array<WorktreeInfo>; };
159
+
160
+ export type Result_worktree_created = { "root_pane": PaneInfo; "tab": TabInfo; "type": "worktree_created"; "workspace": WorkspaceInfo; "worktree": WorktreeInfo; };
161
+
162
+ export type Result_worktree_opened = { "already_open": boolean; "root_pane": PaneInfo; "tab": TabInfo; "type": "worktree_opened"; "workspace": WorkspaceInfo; "worktree": WorktreeInfo; };
163
+
164
+ export type Result_worktree_removed = { "forced": boolean; "path": string; "type": "worktree_removed"; "workspace_id": string; };
165
+
166
+ export type Result_tab_info = { "tab": TabInfo; "type": "tab_info"; };
167
+
168
+ export type Result_tab_created = { "root_pane": PaneInfo; "tab": TabInfo; "type": "tab_created"; };
169
+
170
+ export type Result_tab_list = { "tabs": Array<TabInfo>; "type": "tab_list"; };
171
+
172
+ export type Result_agent_info = { "agent": AgentInfo; "type": "agent_info"; };
173
+
174
+ export type Result_agent_started = { "agent": AgentInfo; "argv": Array<string>; "type": "agent_started"; };
175
+
176
+ export type Result_agent_prompted = { "agent": AgentInfo; "type": "agent_prompted"; };
177
+
178
+ export type Result_agent_list = { "agents": Array<AgentInfo>; "type": "agent_list"; };
179
+
180
+ export type Result_agent_view = { "active": boolean; "label"?: string | null; "source"?: string | null; "type": "agent_view"; };
181
+
182
+ export type Result_pane_info = { "pane": PaneInfo; "type": "pane_info"; };
183
+
184
+ export type Result_pane_list = { "panes": Array<PaneInfo>; "type": "pane_list"; };
185
+
186
+ export type Result_pane_current = { "pane": PaneInfo; "type": "pane_current"; };
187
+
188
+ export type Result_pane_swap = { "swap": PaneSwapResult; "type": "pane_swap"; };
189
+
190
+ export type Result_pane_move = { "move_result": PaneMoveResult; "type": "pane_move"; };
191
+
192
+ export type Result_pane_zoom = { "type": "pane_zoom"; "zoom": PaneZoomResult; };
193
+
194
+ export type Result_pane_layout = { "layout": PaneLayoutSnapshot; "type": "pane_layout"; };
195
+
196
+ export type Result_pane_process_info = { "process_info": PaneProcessInfo; "type": "pane_process_info"; };
197
+
198
+ export type Result_layout_export = { "layout": LayoutDescription; "type": "layout_export"; };
199
+
200
+ export type Result_layout_apply = { "layout": LayoutDescription; "type": "layout_apply"; };
201
+
202
+ export type Result_layout_split_ratio_set = { "layout": LayoutDescription; "type": "layout_split_ratio_set"; };
203
+
204
+ export type Result_pane_neighbor = { "neighbor": PaneNeighborResult; "type": "pane_neighbor"; };
205
+
206
+ export type Result_pane_edges = { "edges": PaneEdgesResult; "type": "pane_edges"; };
207
+
208
+ export type Result_pane_focus_direction = { "focus": PaneFocusDirectionResult; "type": "pane_focus_direction"; };
209
+
210
+ export type Result_pane_resize = { "resize": PaneResizeResult; "type": "pane_resize"; };
211
+
212
+ export type Result_pane_read = { "read": PaneReadResult; "type": "pane_read"; };
213
+
214
+ export type Result_pane_selection = { "pane_id": string; "text": string; "type": "pane_selection"; };
215
+
216
+ export type Result_pane_copy_motion = { "content_revision": number; "cursor": PaneTextPoint; "pane_id": string; "type": "pane_copy_motion"; };
217
+
218
+ export type Result_pane_copy_search = { "content_revision": number; "current"?: number | null; "current_global"?: number | null; "matches": Array<PaneTextRange>; "pane_id": string; "total": number; "type": "pane_copy_search"; };
219
+
220
+ export type Result_pane_graphics_frame_ack = { "revision": number; "sequence": number; "type": "pane_graphics_frame_ack"; };
221
+
222
+ export type Result_pane_graphics_info = { "cell_height_px": number; "cell_width_px": number; /** Accepts damage metadata while still consuming a complete canonical file. */ "file_frame_damage"?: boolean; "file_frame_direct_max_bytes"?: number | null; "file_frame_directory"?: string | null; "file_frame_formats"?: Array<string>; "file_frame_max_bytes"?: number | null; "file_frame_transport"?: string | null; "max_layers_per_pane"?: number; /** True only when this pane is on the currently rendered terminal surface. */ "pane_visible": boolean; "pixel_mouse"?: boolean; "type": "pane_graphics_info"; };
223
+
224
+ export type Result_agent_explain = { "explain": unknown; "type": "agent_explain"; };
225
+
226
+ export type Result_subscription_started = { "type": "subscription_started"; };
227
+
228
+ export type Result_wait_matched = { "event": EventEnvelope; "type": "wait_matched"; };
229
+
230
+ export type Result_output_matched = { "matched_line"?: string | null; "pane_id": string; "read": PaneReadResult; "revision": number; "type": "output_matched"; };
231
+
232
+ export type Result_notification_show = { "reason": NotificationShowReason; "shown": boolean; "type": "notification_show"; };
233
+
234
+ export type Result_client_window_title = { "changed": boolean; "reason": ClientWindowTitleReason; "type": "client_window_title"; };
235
+
236
+ export type Result_integration_list = { "integrations": Array<IntegrationInfo>; "type": "integration_list"; };
237
+
238
+ export type Result_integration_install = { "details": IntegrationInstallResult; "target": IntegrationTarget; "type": "integration_install"; };
239
+
240
+ export type Result_integration_uninstall = { "details": IntegrationUninstallResult; "target": IntegrationTarget; "type": "integration_uninstall"; };
241
+
242
+ export type Result_agent_manifest_reload = { "manifests": Array<AgentManifestInfo>; "type": "agent_manifest_reload"; };
243
+
244
+ export type Result_agent_manifest_status = { "last_check_unix"?: number | null; "last_result"?: string | null; "manifests": Array<AgentManifestInfo>; "type": "agent_manifest_status"; };
245
+
246
+ export type Result_plugin_linked = { "plugin": InstalledPluginInfo; "type": "plugin_linked"; };
247
+
248
+ export type Result_plugin_list = { "plugins": Array<InstalledPluginInfo>; "type": "plugin_list"; };
249
+
250
+ export type Result_plugin_unlinked = { "plugin_id": string; "removed": boolean; "type": "plugin_unlinked"; };
251
+
252
+ export type Result_plugin_enabled = { "plugin": InstalledPluginInfo; "type": "plugin_enabled"; };
253
+
254
+ export type Result_plugin_disabled = { "plugin": InstalledPluginInfo; "type": "plugin_disabled"; };
255
+
256
+ export type Result_plugin_action_list = { "actions": Array<PluginActionInfo>; "type": "plugin_action_list"; };
257
+
258
+ export type Result_plugin_action_invoked = { "action": PluginActionInfo; "context": PluginInvocationContext; "log": PluginCommandLogInfo; "type": "plugin_action_invoked"; };
259
+
260
+ export type Result_pane_link_resolved = { "regions": Array<PaneLinkRegion>; "type": "pane_link_resolved"; };
261
+
262
+ export type Result_pane_link_activated = { "handled": boolean; "type": "pane_link_activated"; "url"?: string | null; };
263
+
264
+ export type Result_plugin_log_list = { "logs": Array<PluginCommandLogInfo>; "type": "plugin_log_list"; };
265
+
266
+ export type Result_plugin_pane_opened = { "plugin_pane": PluginPaneInfo; "type": "plugin_pane_opened"; };
267
+
268
+ export type Result_plugin_pane_focused = { "plugin_pane": PluginPaneInfo; "type": "plugin_pane_focused"; };
269
+
270
+ export type Result_plugin_pane_closed = { "pane_id": string; "type": "plugin_pane_closed"; };
271
+
272
+ export type Result_config_reload = { "diagnostics": Array<string>; "status": ConfigReloadStatus; "type": "config_reload"; };
273
+
274
+ export type Result_client_shell_surface_set = { "active": boolean; "projection_revision": number; "type": "client_shell_surface_set"; };
275
+
276
+ export type Result_ok = { "type": "ok"; };
277
+
278
+ /** The full union of every result shape the server can return. */
279
+ export type ResponseResult =
280
+ | Result_pong
281
+ | Result_session_snapshot
282
+ | Result_workspace_info
283
+ | Result_workspace_created
284
+ | Result_workspace_list
285
+ | Result_worktree_list
286
+ | Result_worktree_created
287
+ | Result_worktree_opened
288
+ | Result_worktree_removed
289
+ | Result_tab_info
290
+ | Result_tab_created
291
+ | Result_tab_list
292
+ | Result_agent_info
293
+ | Result_agent_started
294
+ | Result_agent_prompted
295
+ | Result_agent_list
296
+ | Result_agent_view
297
+ | Result_pane_info
298
+ | Result_pane_list
299
+ | Result_pane_current
300
+ | Result_pane_swap
301
+ | Result_pane_move
302
+ | Result_pane_zoom
303
+ | Result_pane_layout
304
+ | Result_pane_process_info
305
+ | Result_layout_export
306
+ | Result_layout_apply
307
+ | Result_layout_split_ratio_set
308
+ | Result_pane_neighbor
309
+ | Result_pane_edges
310
+ | Result_pane_focus_direction
311
+ | Result_pane_resize
312
+ | Result_pane_read
313
+ | Result_pane_selection
314
+ | Result_pane_copy_motion
315
+ | Result_pane_copy_search
316
+ | Result_pane_graphics_frame_ack
317
+ | Result_pane_graphics_info
318
+ | Result_agent_explain
319
+ | Result_subscription_started
320
+ | Result_wait_matched
321
+ | Result_output_matched
322
+ | Result_notification_show
323
+ | Result_client_window_title
324
+ | Result_integration_list
325
+ | Result_integration_install
326
+ | Result_integration_uninstall
327
+ | Result_agent_manifest_reload
328
+ | Result_agent_manifest_status
329
+ | Result_plugin_linked
330
+ | Result_plugin_list
331
+ | Result_plugin_unlinked
332
+ | Result_plugin_enabled
333
+ | Result_plugin_disabled
334
+ | Result_plugin_action_list
335
+ | Result_plugin_action_invoked
336
+ | Result_pane_link_resolved
337
+ | Result_pane_link_activated
338
+ | Result_plugin_log_list
339
+ | Result_plugin_pane_opened
340
+ | Result_plugin_pane_focused
341
+ | Result_plugin_pane_closed
342
+ | Result_config_reload
343
+ | Result_client_shell_surface_set
344
+ | Result_ok;
345
+
346
+ /** Result shape, keyed by its `type` tag. */
347
+ export interface ResultByTag {
348
+ "pong": Result_pong;
349
+ "session_snapshot": Result_session_snapshot;
350
+ "workspace_info": Result_workspace_info;
351
+ "workspace_created": Result_workspace_created;
352
+ "workspace_list": Result_workspace_list;
353
+ "worktree_list": Result_worktree_list;
354
+ "worktree_created": Result_worktree_created;
355
+ "worktree_opened": Result_worktree_opened;
356
+ "worktree_removed": Result_worktree_removed;
357
+ "tab_info": Result_tab_info;
358
+ "tab_created": Result_tab_created;
359
+ "tab_list": Result_tab_list;
360
+ "agent_info": Result_agent_info;
361
+ "agent_started": Result_agent_started;
362
+ "agent_prompted": Result_agent_prompted;
363
+ "agent_list": Result_agent_list;
364
+ "agent_view": Result_agent_view;
365
+ "pane_info": Result_pane_info;
366
+ "pane_list": Result_pane_list;
367
+ "pane_current": Result_pane_current;
368
+ "pane_swap": Result_pane_swap;
369
+ "pane_move": Result_pane_move;
370
+ "pane_zoom": Result_pane_zoom;
371
+ "pane_layout": Result_pane_layout;
372
+ "pane_process_info": Result_pane_process_info;
373
+ "layout_export": Result_layout_export;
374
+ "layout_apply": Result_layout_apply;
375
+ "layout_split_ratio_set": Result_layout_split_ratio_set;
376
+ "pane_neighbor": Result_pane_neighbor;
377
+ "pane_edges": Result_pane_edges;
378
+ "pane_focus_direction": Result_pane_focus_direction;
379
+ "pane_resize": Result_pane_resize;
380
+ "pane_read": Result_pane_read;
381
+ "pane_selection": Result_pane_selection;
382
+ "pane_copy_motion": Result_pane_copy_motion;
383
+ "pane_copy_search": Result_pane_copy_search;
384
+ "pane_graphics_frame_ack": Result_pane_graphics_frame_ack;
385
+ "pane_graphics_info": Result_pane_graphics_info;
386
+ "agent_explain": Result_agent_explain;
387
+ "subscription_started": Result_subscription_started;
388
+ "wait_matched": Result_wait_matched;
389
+ "output_matched": Result_output_matched;
390
+ "notification_show": Result_notification_show;
391
+ "client_window_title": Result_client_window_title;
392
+ "integration_list": Result_integration_list;
393
+ "integration_install": Result_integration_install;
394
+ "integration_uninstall": Result_integration_uninstall;
395
+ "agent_manifest_reload": Result_agent_manifest_reload;
396
+ "agent_manifest_status": Result_agent_manifest_status;
397
+ "plugin_linked": Result_plugin_linked;
398
+ "plugin_list": Result_plugin_list;
399
+ "plugin_unlinked": Result_plugin_unlinked;
400
+ "plugin_enabled": Result_plugin_enabled;
401
+ "plugin_disabled": Result_plugin_disabled;
402
+ "plugin_action_list": Result_plugin_action_list;
403
+ "plugin_action_invoked": Result_plugin_action_invoked;
404
+ "pane_link_resolved": Result_pane_link_resolved;
405
+ "pane_link_activated": Result_pane_link_activated;
406
+ "plugin_log_list": Result_plugin_log_list;
407
+ "plugin_pane_opened": Result_plugin_pane_opened;
408
+ "plugin_pane_focused": Result_plugin_pane_focused;
409
+ "plugin_pane_closed": Result_plugin_pane_closed;
410
+ "config_reload": Result_config_reload;
411
+ "client_shell_surface_set": Result_client_shell_surface_set;
412
+ "ok": Result_ok;
413
+ }
414
+
415
+ export type ResultTag = keyof ResultByTag;
416
+
417
+ /** See scripts/gen/method-result-map.ts. */
418
+ export const METHOD_RESULT = {
419
+ "ping": "pong",
420
+ "session.snapshot": "session_snapshot",
421
+ "workspace.create": "workspace_created",
422
+ "workspace.list": "workspace_list",
423
+ "workspace.get": "workspace_info",
424
+ "worktree.list": "worktree_list",
425
+ "worktree.create": "worktree_created",
426
+ "worktree.open": "worktree_opened",
427
+ "worktree.remove": "worktree_removed",
428
+ "tab.create": "tab_created",
429
+ "tab.list": "tab_list",
430
+ "tab.get": "tab_info",
431
+ "agent.list": "agent_list",
432
+ "agent.get": "agent_info",
433
+ "agent.read": "pane_read",
434
+ "agent.start": "agent_started",
435
+ "agent.prompt": "agent_prompted",
436
+ "agent.wait": "agent_info",
437
+ "agent.view.set": "agent_view",
438
+ "agent.view.clear": "agent_view",
439
+ "pane.list": "pane_list",
440
+ "pane.current": "pane_current",
441
+ "pane.get": "pane_info",
442
+ "pane.read": "pane_read",
443
+ "events.subscribe": "subscription_started"
444
+ } as const;
package/src/herdr.ts ADDED
@@ -0,0 +1,142 @@
1
+ // Effect-native client for the herdr socket API.
2
+ // Wire facts (herdr 0.9, protocol 22): newline-delimited JSON; `{id, method, params}` → `{id, result}` | `{id, error}`;
3
+ // the server closes after one response, so every call is its own connection. `events.subscribe` acks with
4
+ // `subscription_started` and then keeps the connection open, streaming `{event, data}` frames.
5
+ import { Cause, Config, Context, Effect, Layer, Option, type Path, Random, Schema, Stream } from "effect"
6
+ import * as Socket from "effect/socket/Socket"
7
+ import type { PushFrame } from "./generated/events.js"
8
+ import { PROTOCOL } from "./generated/index.js"
9
+ import type { Method, MethodParams, Subscription } from "./generated/params.js"
10
+ import type { METHOD_RESULT, ResponseResult, ResultByTag } from "./generated/results.js"
11
+ import { SocketConnector } from "./socket-connector.js"
12
+ import { defaultSocketPath, socketEndpoint, type SocketPathOptions } from "./socket-path.js"
13
+
14
+ export type ResultOf<M extends Method> = M extends keyof typeof METHOD_RESULT ? ResultByTag[(typeof METHOD_RESULT)[M]] : ResponseResult
15
+ export type ParamsOf<M extends Method> = MethodParams[M]
16
+
17
+ /** The server answered `{ error }`. `code` is herdr's machine-readable code (`timeout`, `agent_pane_busy`, …). */
18
+ export class HerdrError extends Schema.TaggedError<HerdrError>()("HerdrError", {
19
+ method: Schema.String,
20
+ code: Schema.String,
21
+ message: Schema.String,
22
+ }) {}
23
+
24
+ /** Socket missing, refused, or closed before a response. */
25
+ export class HerdrTransportError extends Schema.TaggedError<HerdrTransportError>()("HerdrTransportError", {
26
+ method: Schema.String,
27
+ message: Schema.String,
28
+ }) {}
29
+
30
+ export type HerdrFailure = HerdrError | HerdrTransportError
31
+
32
+ /** The server speaks a different protocol than the one this SDK's types were generated for (`PROTOCOL`). */
33
+ export class HerdrProtocolMismatch extends Schema.TaggedError<HerdrProtocolMismatch>()("HerdrProtocolMismatch", {
34
+ socketPath: Schema.String,
35
+ expected: Schema.Number,
36
+ actual: Schema.Number,
37
+ serverVersion: Schema.String,
38
+ }) {}
39
+
40
+ export interface HerdrShape {
41
+ readonly socketPath: string
42
+ readonly call: <M extends Method>(method: M, params: ParamsOf<M>) => Effect.Effect<ResultOf<M>, HerdrFailure>
43
+ /** Long-lived push stream. Ends when the server closes the connection. */
44
+ readonly subscribe: (subscriptions: ReadonlyArray<Subscription>) => Stream.Stream<PushFrame, HerdrFailure>
45
+ }
46
+
47
+ export class Herdr extends Context.Service<Herdr, HerdrShape>()("effect-herdr-sdk/Herdr") {
48
+ /**
49
+ * The handshake every consumer runs before trusting a server: the generated types (and the unchecked casts that
50
+ * hand them out, see `call` / `subscribe`) are only true for the protocol they were generated from.
51
+ */
52
+ static readonly verifyProtocol = (herdr: HerdrShape): Effect.Effect<void, HerdrFailure | HerdrProtocolMismatch> =>
53
+ herdr.call("ping", {}).pipe(
54
+ Effect.flatMap((pong) =>
55
+ pong.protocol === PROTOCOL
56
+ ? Effect.void
57
+ : Effect.fail(new HerdrProtocolMismatch({ socketPath: herdr.socketPath, expected: PROTOCOL, actual: pong.protocol, serverVersion: pong.version })),
58
+ ),
59
+ )
60
+
61
+ /** A client for `socketPath`, dialing through the provided `SocketConnector`. */
62
+ static readonly make = (socketPath: string): Effect.Effect<HerdrShape, never, SocketConnector> =>
63
+ Effect.map(SocketConnector, (connect) => makeClient(socketPath, connect))
64
+ /** Socket from `options.socketPath`, else herdr's own resolution (HERDR_SOCKET_PATH, XDG_CONFIG_HOME, HOME …) read through Config. */
65
+ static readonly layer = (
66
+ options: { socketPath?: string } & SocketPathOptions = {},
67
+ ): Layer.Layer<Herdr, Config.ConfigError, SocketConnector | Path.Path> =>
68
+ Layer.effect(
69
+ Herdr,
70
+ (options.socketPath ? Effect.succeed(options.socketPath) : defaultSocketPath(options)).pipe(Effect.flatMap(Herdr.make)),
71
+ )
72
+ }
73
+
74
+ // Wire frames (herdr protocol 22). `id: ""` = the server could not parse our request; still ours.
75
+ const Response = Schema.Struct({
76
+ id: Schema.String,
77
+ result: Schema.optional(Schema.Unknown),
78
+ error: Schema.optional(Schema.Struct({ code: Schema.String, message: Schema.String })),
79
+ })
80
+ const Push = Schema.Struct({ event: Schema.String, data: Schema.Unknown })
81
+ const decodeLine = Schema.decodeUnknownEffect(Schema.fromJsonString(Schema.Union([Response, Push])))
82
+ const Request = Schema.Struct({ id: Schema.String, method: Schema.String, params: Schema.Unknown })
83
+ const encodeRequest = Schema.encodeEffect(Schema.fromJsonString(Request))
84
+ const isResponse = (m: typeof Response.Type | typeof Push.Type): m is typeof Response.Type => "id" in m
85
+
86
+ const requestId = (prefix: string) => Random.nextIntBetween(0, 2 ** 31).pipe(Effect.map((n) => `${prefix}-${n.toString(36)}`))
87
+
88
+ function makeClient(socketPath: string, connect: SocketConnector["Service"]): HerdrShape {
89
+ const transport = (method: string) => (e: { readonly message: string }) => new HerdrTransportError({ method, message: e.message })
90
+ const serverError = (method: string, error: { code: string; message: string }) => new HerdrError({ method, code: error.code, message: error.message })
91
+
92
+ /** Open a connection, send one request line, and expose the decoded response lines. Scoped: closing the scope closes the socket. */
93
+ const open = (method: string, request: typeof Request.Type) =>
94
+ Effect.gen(function* () {
95
+ const socket = yield* connect(socketEndpoint(socketPath))
96
+ // Acquiring the reader dials; the writer waits on that, so writing first would hang forever.
97
+ const pull = yield* Socket.readerString(socket)
98
+ const writer = yield* socket.writer
99
+ yield* writer.write(`${yield* encodeRequest(request).pipe(Effect.orDie)}\n`)
100
+ // Every close surfaces as a SocketError; a clean close is just the end of the stream.
101
+ const text = pull.pipe(Effect.catchIf((e) => e.reason._tag === "SocketCloseError", () => Cause.done()))
102
+ return Stream.fromPull(Effect.succeed(text)).pipe(
103
+ Stream.splitLines,
104
+ Stream.filter((l) => l.length > 0),
105
+ Stream.mapEffect((line) => decodeLine(line)),
106
+ Stream.mapError(transport(method)),
107
+ )
108
+ }).pipe(Effect.mapError(transport(method)))
109
+
110
+ const call = <M extends Method>(method: M, params: ParamsOf<M>) =>
111
+ Effect.gen(function* () {
112
+ const id = yield* requestId("omac")
113
+ const lines = yield* open(method, { id, method, params })
114
+ const found = yield* lines.pipe(
115
+ Stream.filter(isResponse),
116
+ Stream.filter((m) => m.id === id || m.id === ""),
117
+ Stream.runHead,
118
+ )
119
+ if (Option.isNone(found)) return yield* new HerdrTransportError({ method, message: "connection closed before a response" })
120
+ if (found.value.error) return yield* serverError(method, found.value.error)
121
+ // Not decoded at runtime: the shape is herdr's contract for PROTOCOL, checked once per server by verifyProtocol.
122
+ return found.value.result as ResultOf<M>
123
+ }).pipe(Effect.scoped)
124
+
125
+ /** herdr acks with a response first and only then pushes frames, so no ack state is needed. */
126
+ const subscribe = (subscriptions: ReadonlyArray<Subscription>): Stream.Stream<PushFrame, HerdrFailure> => {
127
+ const method = "events.subscribe"
128
+ return Effect.gen(function* () {
129
+ const id = yield* requestId("sub")
130
+ const lines = yield* open(method, { id, method, params: { subscriptions } })
131
+ return lines.pipe(
132
+ Stream.flatMap((m): Stream.Stream<PushFrame, HerdrFailure> =>
133
+ isResponse(m)
134
+ ? (m.id === id || m.id === "") && m.error ? Stream.fail(serverError(method, m.error)) : Stream.empty
135
+ : Stream.make(m as PushFrame), // herdr's contract for PROTOCOL, as in `call`
136
+ ),
137
+ )
138
+ }).pipe(Stream.unwrap)
139
+ }
140
+
141
+ return { socketPath, call, subscribe }
142
+ }
package/src/index.ts ADDED
@@ -0,0 +1,10 @@
1
+ export * from "./herdr.js"
2
+ export { SocketConnector } from "./socket-connector.js"
3
+ export { configDir, defaultSocketPath, socketEndpoint, type SocketPathOptions } from "./socket-path.js"
4
+ export * as params from "./generated/params.js"
5
+ export * as results from "./generated/results.js"
6
+ export * as events from "./generated/events.js"
7
+ export type { Method, MethodParams, Subscription } from "./generated/params.js"
8
+ export type { ResponseResult, ResultByTag, ResultTag } from "./generated/results.js"
9
+ export type { AgentStatus, EventFrame, EventKind, PushFrame, SubscriptionEventFrame, SubscriptionEventKind } from "./generated/events.js"
10
+ export { PROTOCOL, SCHEMA_VERSION } from "./generated/index.js"
@@ -0,0 +1,9 @@
1
+ // The one runtime capability the client needs and `effect` has no service for: dial a local socket.
2
+ // The core only names this service; `effect-herdr-sdk/bun` (or another runtime's layer) provides it.
3
+ import { Context, type Effect } from "effect"
4
+ import type * as Socket from "effect/socket/Socket"
5
+
6
+ /** Dial `endpoint` (a unix socket path, or `\\.\pipe\…` on Windows). Like `WebSocketConstructor`, for local sockets. */
7
+ export class SocketConnector extends Context.Service<SocketConnector, (endpoint: string) => Effect.Effect<Socket.Socket>>()(
8
+ "effect-herdr-sdk/SocketConnector",
9
+ ) {}