From 544c7ebebbc1db65a2949642d367edc446ae559b Mon Sep 17 00:00:00 2001 From: Ogulcan Celik Date: Thu, 2 Apr 2026 23:59:54 +0300 Subject: feat: add tabs to socket api --- src/api/mod.rs | 16 +++++++++ src/api/schema.rs | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) (limited to 'src/api') diff --git a/src/api/mod.rs b/src/api/mod.rs index bf95bf29..2e7692a4 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -430,6 +430,22 @@ impl ActiveSubscription { event_kind: crate::api::schema::EventKind::WorkspaceFocused, last_sequence: 0, })), + Subscription::TabCreated {} => Ok(Self::Event(ActiveEventSubscription { + event_kind: crate::api::schema::EventKind::TabCreated, + last_sequence: 0, + })), + Subscription::TabClosed {} => Ok(Self::Event(ActiveEventSubscription { + event_kind: crate::api::schema::EventKind::TabClosed, + last_sequence: 0, + })), + Subscription::TabFocused {} => Ok(Self::Event(ActiveEventSubscription { + event_kind: crate::api::schema::EventKind::TabFocused, + last_sequence: 0, + })), + Subscription::TabRenamed {} => Ok(Self::Event(ActiveEventSubscription { + event_kind: crate::api::schema::EventKind::TabRenamed, + last_sequence: 0, + })), Subscription::PaneCreated {} => Ok(Self::Event(ActiveEventSubscription { event_kind: crate::api::schema::EventKind::PaneCreated, last_sequence: 0, diff --git a/src/api/schema.rs b/src/api/schema.rs index a187a889..5a27b01b 100644 --- a/src/api/schema.rs +++ b/src/api/schema.rs @@ -24,6 +24,18 @@ pub enum Method { WorkspaceRename(WorkspaceRenameParams), #[serde(rename = "workspace.close")] WorkspaceClose(WorkspaceTarget), + #[serde(rename = "tab.create")] + TabCreate(TabCreateParams), + #[serde(rename = "tab.list")] + TabList(TabListParams), + #[serde(rename = "tab.get")] + TabGet(TabTarget), + #[serde(rename = "tab.focus")] + TabFocus(TabTarget), + #[serde(rename = "tab.rename")] + TabRename(TabRenameParams), + #[serde(rename = "tab.close")] + TabClose(TabTarget), #[serde(rename = "pane.split")] PaneSplit(PaneSplitParams), #[serde(rename = "pane.list")] @@ -68,6 +80,11 @@ pub struct PaneTarget { pub pane_id: String, } +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct TabTarget { + pub tab_id: String, +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct WorkspaceCreateParams { #[serde(default, skip_serializing_if = "Option::is_none")] @@ -82,6 +99,28 @@ pub struct WorkspaceRenameParams { pub label: String, } +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct TabCreateParams { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub workspace_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cwd: Option, + #[serde(default)] + pub focus: bool, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] +pub struct TabListParams { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub workspace_id: Option, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct TabRenameParams { + pub tab_id: String, + pub label: String, +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct PaneSplitParams { #[serde(default, skip_serializing_if = "Option::is_none")] @@ -174,6 +213,14 @@ pub enum Subscription { WorkspaceClosed {}, #[serde(rename = "workspace.focused")] WorkspaceFocused {}, + #[serde(rename = "tab.created")] + TabCreated {}, + #[serde(rename = "tab.closed")] + TabClosed {}, + #[serde(rename = "tab.focused")] + TabFocused {}, + #[serde(rename = "tab.renamed")] + TabRenamed {}, #[serde(rename = "pane.created")] PaneCreated {}, #[serde(rename = "pane.closed")] @@ -247,6 +294,23 @@ pub enum EventMatch { WorkspaceFocused { workspace_id: String, }, + TabCreated { + #[serde(default, skip_serializing_if = "Option::is_none")] + tab_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + workspace_id: Option, + }, + TabClosed { + tab_id: String, + }, + TabRenamed { + tab_id: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + label: Option, + }, + TabFocused { + tab_id: String, + }, PaneCreated { #[serde(default, skip_serializing_if = "Option::is_none")] pane_id: Option, @@ -285,6 +349,10 @@ pub enum EventKind { WorkspaceClosed, WorkspaceRenamed, WorkspaceFocused, + TabCreated, + TabClosed, + TabRenamed, + TabFocused, PaneCreated, PaneClosed, PaneFocused, @@ -324,6 +392,12 @@ pub enum ResponseResult { WorkspaceList { workspaces: Vec, }, + TabInfo { + tab: TabInfo, + }, + TabList { + tabs: Vec, + }, PaneInfo { pane: PaneInfo, }, @@ -348,6 +422,19 @@ pub enum ResponseResult { #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct WorkspaceInfo { + pub workspace_id: String, + pub number: usize, + pub label: String, + pub focused: bool, + pub pane_count: usize, + pub tab_count: usize, + pub active_tab_id: String, + pub agent_state: PaneAgentState, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct TabInfo { + pub tab_id: String, pub workspace_id: String, pub number: usize, pub label: String, @@ -360,6 +447,7 @@ pub struct WorkspaceInfo { pub struct PaneInfo { pub pane_id: String, pub workspace_id: String, + pub tab_id: String, pub focused: bool, #[serde(default, skip_serializing_if = "Option::is_none")] pub cwd: Option, @@ -373,6 +461,7 @@ pub struct PaneInfo { pub struct PaneReadResult { pub pane_id: String, pub workspace_id: String, + pub tab_id: String, pub source: ReadSource, pub text: String, pub revision: u64, @@ -438,6 +527,22 @@ pub enum EventData { WorkspaceFocused { workspace_id: String, }, + TabCreated { + tab: TabInfo, + }, + TabClosed { + tab_id: String, + workspace_id: String, + }, + TabRenamed { + tab_id: String, + workspace_id: String, + label: String, + }, + TabFocused { + tab_id: String, + workspace_id: String, + }, PaneCreated { pane: PaneInfo, }, @@ -682,6 +787,7 @@ mod tests { read: PaneReadResult { pane_id: "p_1_1".into(), workspace_id: "w_1".into(), + tab_id: "t_1_1".into(), source: ReadSource::Recent, text: "auth: received\n".into(), revision: 0, -- cgit v1.2.3