diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-13 03:26:03 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-13 03:30:13 +0300 |
| commit | 5cfe5e5e730246948b0c9428ad876b6938590aad (patch) | |
| tree | 53d4bbe1aff6887f63f279eed1b5e4e11e7331b7 /src/api/schema | |
| parent | 7f3364a468f7dcfd8c9c84e5737fe5699f0e3a93 (diff) | |
feat: add configurable sidebar metadata tokens
Diffstat (limited to 'src/api/schema')
| -rw-r--r-- | src/api/schema/agents.rs | 9 | ||||
| -rw-r--r-- | src/api/schema/common.rs | 22 | ||||
| -rw-r--r-- | src/api/schema/events.rs | 22 | ||||
| -rw-r--r-- | src/api/schema/panes.rs | 19 | ||||
| -rw-r--r-- | src/api/schema/tests.rs | 10 | ||||
| -rw-r--r-- | src/api/schema/workspaces.rs | 16 |
6 files changed, 82 insertions, 16 deletions
diff --git a/src/api/schema/agents.rs b/src/api/schema/agents.rs index e5f319e0..969383c4 100644 --- a/src/api/schema/agents.rs +++ b/src/api/schema/agents.rs @@ -57,14 +57,19 @@ pub struct AgentInfo { #[serde(default, skip_serializing_if = "Option::is_none")] pub title: Option<String>, #[serde(default, skip_serializing_if = "Option::is_none")] + pub terminal_title: Option<String>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub terminal_title_stripped: Option<String>, + #[serde(default, skip_serializing_if = "Option::is_none")] pub display_agent: Option<String>, pub agent_status: AgentStatus, #[serde(default, skip_serializing_if = "super::is_false")] pub screen_detection_skipped: bool, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub custom_status: Option<String>, #[serde(default, skip_serializing_if = "HashMap::is_empty")] pub state_labels: HashMap<String, String>, + #[serde(default, skip_serializing_if = "HashMap::is_empty")] + #[schemars(schema_with = "super::common::metadata_token_values_schema")] + pub tokens: HashMap<String, String>, #[serde(default, skip_serializing_if = "Option::is_none")] pub agent_session: Option<AgentSessionInfo>, pub workspace_id: String, diff --git a/src/api/schema/common.rs b/src/api/schema/common.rs index 3d8376ed..e22fa1b3 100644 --- a/src/api/schema/common.rs +++ b/src/api/schema/common.rs @@ -1,5 +1,27 @@ use serde::{Deserialize, Serialize}; +pub(super) fn metadata_token_patch_schema( + _generator: &mut schemars::SchemaGenerator, +) -> schemars::Schema { + schemars::json_schema!({ + "type": "object", + "maxProperties": 16, + "propertyNames": { "pattern": "^[A-Za-z0-9_-]{1,32}$" }, + "additionalProperties": { "type": ["string", "null"] } + }) +} + +pub(super) fn metadata_token_values_schema( + _generator: &mut schemars::SchemaGenerator, +) -> schemars::Schema { + schemars::json_schema!({ + "type": "object", + "maxProperties": 32, + "propertyNames": { "pattern": "^[A-Za-z0-9_-]{1,32}$" }, + "additionalProperties": { "type": "string" } + }) +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, schemars::JsonSchema, Default)] pub struct EmptyParams {} diff --git a/src/api/schema/events.rs b/src/api/schema/events.rs index 41b9907d..25ccc8ec 100644 --- a/src/api/schema/events.rs +++ b/src/api/schema/events.rs @@ -20,6 +20,8 @@ pub enum Subscription { WorkspaceCreated {}, #[serde(rename = "workspace.updated")] WorkspaceUpdated {}, + #[serde(rename = "workspace.metadata_updated")] + WorkspaceMetadataUpdated {}, #[serde(rename = "workspace.renamed")] WorkspaceRenamed {}, #[serde(rename = "workspace.moved")] @@ -48,6 +50,8 @@ pub enum Subscription { PaneCreated {}, #[serde(rename = "pane.closed")] PaneClosed {}, + #[serde(rename = "pane.updated")] + PaneUpdated {}, #[serde(rename = "pane.focused")] PaneFocused {}, #[serde(rename = "pane.moved")] @@ -188,6 +192,7 @@ pub enum EventMatch { pub enum EventKind { WorkspaceCreated, WorkspaceUpdated, + WorkspaceMetadataUpdated, WorkspaceClosed, WorkspaceRenamed, WorkspaceMoved, @@ -202,6 +207,7 @@ pub enum EventKind { TabFocused, PaneCreated, PaneClosed, + PaneUpdated, PaneFocused, PaneMoved, PaneOutputChanged, @@ -216,6 +222,7 @@ impl EventKind { match self { EventKind::WorkspaceCreated => "workspace.created", EventKind::WorkspaceUpdated => "workspace.updated", + EventKind::WorkspaceMetadataUpdated => "workspace.metadata_updated", EventKind::WorkspaceClosed => "workspace.closed", EventKind::WorkspaceRenamed => "workspace.renamed", EventKind::WorkspaceMoved => "workspace.moved", @@ -230,6 +237,7 @@ impl EventKind { EventKind::TabFocused => "tab.focused", EventKind::PaneCreated => "pane.created", EventKind::PaneClosed => "pane.closed", + EventKind::PaneUpdated => "pane.updated", EventKind::PaneFocused => "pane.focused", EventKind::PaneMoved => "pane.moved", EventKind::PaneOutputChanged => "pane.output_changed", @@ -245,6 +253,7 @@ impl EventKind { pub const KNOWN_EVENT_KINDS: &[EventKind] = &[ EventKind::WorkspaceCreated, EventKind::WorkspaceUpdated, + EventKind::WorkspaceMetadataUpdated, EventKind::WorkspaceClosed, EventKind::WorkspaceRenamed, EventKind::WorkspaceMoved, @@ -259,6 +268,7 @@ pub const KNOWN_EVENT_KINDS: &[EventKind] = &[ EventKind::TabFocused, EventKind::PaneCreated, EventKind::PaneClosed, + EventKind::PaneUpdated, EventKind::PaneFocused, EventKind::PaneMoved, EventKind::PaneOutputChanged, @@ -336,6 +346,8 @@ mod known_event_name_tests { let names = plugin_hook_event_names(); assert!(!names.contains(&"pane.output_changed")); assert!(!names.contains(&"layout.updated")); + assert!(!names.contains(&"workspace.metadata_updated")); + assert!(!names.contains(&"pane.updated")); assert!(names.contains(&"pane.moved")); } } @@ -385,8 +397,6 @@ pub struct PaneAgentStatusChangedEvent { #[serde(default, skip_serializing_if = "Option::is_none")] pub agent: Option<String>, #[serde(default, skip_serializing_if = "Option::is_none")] - pub custom_status: Option<String>, - #[serde(default, skip_serializing_if = "Option::is_none")] pub title: Option<String>, #[serde(default, skip_serializing_if = "Option::is_none")] pub display_agent: Option<String>, @@ -410,6 +420,9 @@ pub enum EventData { WorkspaceUpdated { workspace: WorkspaceInfo, }, + WorkspaceMetadataUpdated { + workspace: WorkspaceInfo, + }, WorkspaceClosed { workspace_id: String, #[serde(default, skip_serializing_if = "Option::is_none")] @@ -472,6 +485,9 @@ pub enum EventData { pane_id: String, workspace_id: String, }, + PaneUpdated { + pane: PaneInfo, + }, PaneFocused { pane_id: String, workspace_id: String, @@ -515,8 +531,6 @@ pub enum EventData { title: Option<String>, #[serde(default, skip_serializing_if = "Option::is_none")] display_agent: Option<String>, - #[serde(default, skip_serializing_if = "Option::is_none")] - custom_status: Option<String>, #[serde(default, skip_serializing_if = "HashMap::is_empty")] state_labels: HashMap<String, String>, }, diff --git a/src/api/schema/panes.rs b/src/api/schema/panes.rs index 42a640ef..2e37e734 100644 --- a/src/api/schema/panes.rs +++ b/src/api/schema/panes.rs @@ -266,8 +266,6 @@ pub struct PaneReportAgentParams { #[serde(default, skip_serializing_if = "Option::is_none")] pub message: Option<String>, #[serde(default, skip_serializing_if = "Option::is_none")] - pub custom_status: Option<String>, - #[serde(default, skip_serializing_if = "Option::is_none")] pub seq: Option<u64>, #[serde(default, skip_serializing_if = "Option::is_none")] pub agent_session_id: Option<String>, @@ -302,21 +300,21 @@ pub struct PaneReportMetadataParams { pub title: Option<String>, #[serde(default, skip_serializing_if = "Option::is_none")] pub display_agent: Option<String>, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub custom_status: Option<String>, #[serde(default, skip_serializing_if = "HashMap::is_empty")] pub state_labels: HashMap<String, String>, + #[serde(default, skip_serializing_if = "HashMap::is_empty")] + #[schemars(schema_with = "super::common::metadata_token_patch_schema")] + pub tokens: HashMap<String, Option<String>>, #[serde(default)] pub clear_title: bool, #[serde(default)] pub clear_display_agent: bool, #[serde(default)] - pub clear_custom_status: bool, - #[serde(default)] pub clear_state_labels: bool, #[serde(default, skip_serializing_if = "Option::is_none")] pub seq: Option<u64>, #[serde(default, skip_serializing_if = "Option::is_none")] + #[schemars(range(min = 1, max = 86_400_000))] pub ttl_ms: Option<u64>, } @@ -356,12 +354,17 @@ pub struct PaneInfo { #[serde(default, skip_serializing_if = "Option::is_none")] pub title: Option<String>, #[serde(default, skip_serializing_if = "Option::is_none")] + pub terminal_title: Option<String>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub terminal_title_stripped: Option<String>, + #[serde(default, skip_serializing_if = "Option::is_none")] pub display_agent: Option<String>, pub agent_status: AgentStatus, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub custom_status: Option<String>, #[serde(default, skip_serializing_if = "HashMap::is_empty")] pub state_labels: HashMap<String, String>, + #[serde(default, skip_serializing_if = "HashMap::is_empty")] + #[schemars(schema_with = "super::common::metadata_token_values_schema")] + pub tokens: HashMap<String, String>, #[serde(default, skip_serializing_if = "Option::is_none")] pub agent_session: Option<AgentSessionInfo>, #[serde(default, skip_serializing_if = "Option::is_none")] diff --git a/src/api/schema/tests.rs b/src/api/schema/tests.rs index 5f603a18..adc7e61c 100644 --- a/src/api/schema/tests.rs +++ b/src/api/schema/tests.rs @@ -596,6 +596,7 @@ fn worktree_request_and_response_round_trip() { tab_count: 1, active_tab_id: "w_1:1".into(), agent_status: AgentStatus::Unknown, + tokens: HashMap::new(), worktree: Some(WorkspaceWorktreeInfo { repo_key: "/repo/herdr/.git".into(), repo_name: "herdr".into(), @@ -624,10 +625,12 @@ fn worktree_request_and_response_round_trip() { label: None, agent: None, title: None, + terminal_title: None, + terminal_title_stripped: None, display_agent: None, agent_status: AgentStatus::Unknown, - custom_status: None, state_labels: HashMap::new(), + tokens: HashMap::new(), agent_session: None, scroll: None, revision: 0, @@ -679,6 +682,7 @@ fn worktree_lifecycle_events_round_trip() { tab_count: 1, active_tab_id: "w_2:1".into(), agent_status: AgentStatus::Unknown, + tokens: HashMap::new(), worktree: Some(WorkspaceWorktreeInfo { repo_key: "/repo/herdr/.git".into(), repo_name: "herdr".into(), @@ -1032,10 +1036,12 @@ fn create_response_round_trips_with_root_pane() { label: None, agent: None, title: None, + terminal_title: None, + terminal_title_stripped: None, display_agent: None, agent_status: AgentStatus::Unknown, - custom_status: None, state_labels: HashMap::new(), + tokens: HashMap::new(), agent_session: None, scroll: None, revision: 0, diff --git a/src/api/schema/workspaces.rs b/src/api/schema/workspaces.rs index 6934539c..a6177982 100644 --- a/src/api/schema/workspaces.rs +++ b/src/api/schema/workspaces.rs @@ -29,6 +29,19 @@ pub struct WorkspaceMoveParams { } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, schemars::JsonSchema)] +pub struct WorkspaceReportMetadataParams { + pub workspace_id: String, + pub source: String, + #[schemars(schema_with = "super::common::metadata_token_patch_schema")] + pub tokens: HashMap<String, Option<String>>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub seq: Option<u64>, + #[serde(default, skip_serializing_if = "Option::is_none")] + #[schemars(range(min = 1, max = 86_400_000))] + pub ttl_ms: Option<u64>, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, schemars::JsonSchema)] pub struct WorkspaceInfo { pub workspace_id: String, pub number: usize, @@ -38,6 +51,9 @@ pub struct WorkspaceInfo { pub tab_count: usize, pub active_tab_id: String, pub agent_status: AgentStatus, + #[serde(default, skip_serializing_if = "HashMap::is_empty")] + #[schemars(schema_with = "super::common::metadata_token_values_schema")] + pub tokens: HashMap<String, String>, #[serde(default, skip_serializing_if = "Option::is_none")] pub worktree: Option<WorkspaceWorktreeInfo>, } |
