Detailed changes
@@ -2553,7 +2553,7 @@ fn setup_context_server(
let mut settings = ProjectSettings::get_global(cx).clone();
settings.context_servers.insert(
name.into(),
- project::project_settings::ContextServerSettings::Custom {
+ project::project_settings::ContextServerSettings::Stdio {
enabled: true,
command: ContextServerCommand {
path: "somebinary".into(),
@@ -182,7 +182,7 @@ impl ConfigurationSource {
parse_input(&editor.read(cx).text(cx)).map(|(id, command)| {
(
id,
- ContextServerSettings::Custom {
+ ContextServerSettings::Stdio {
enabled: true,
command,
},
@@ -403,7 +403,7 @@ impl ConfigureContextServerModal {
window.spawn(cx, async move |cx| {
let target = match settings {
- ContextServerSettings::Custom {
+ ContextServerSettings::Stdio {
enabled: _,
command,
} => Some(ConfigurationTarget::Existing {
@@ -635,7 +635,6 @@ impl ConfigureContextServerModal {
}
fn render_modal_content(&self, cx: &App) -> AnyElement {
- // All variants now use single editor approach
let editor = match &self.source {
ConfigurationSource::New { editor, .. } => editor,
ConfigurationSource::Existing { editor, .. } => editor,
@@ -712,12 +711,12 @@ impl ConfigureContextServerModal {
)
} else if let ConfigurationSource::New { is_http, .. } = &self.source {
let label = if *is_http {
- "Run command"
+ "Configure Local"
} else {
- "Connect via HTTP"
+ "Configure Remote"
};
let tooltip = if *is_http {
- "Configure an MCP serevr that runs on stdin/stdout."
+ "Configure an MCP server that runs on stdin/stdout."
} else {
"Configure an MCP server that you connect to over HTTP"
};
@@ -972,7 +972,7 @@ impl ExtensionImports for WasmState {
});
match settings {
- project::project_settings::ContextServerSettings::Custom {
+ project::project_settings::ContextServerSettings::Stdio {
enabled: _,
command,
} => Ok(serde_json::to_string(&settings::ContextServerSettings {
@@ -147,3 +147,9 @@ pub(crate) mod m_2025_11_20 {
pub(crate) use settings::SETTINGS_PATTERNS;
}
+
+pub(crate) mod m_2025_11_25 {
+ mod settings;
+
+ pub(crate) use settings::remove_context_server_source;
+}
@@ -0,0 +1,17 @@
+use anyhow::Result;
+use serde_json::Value;
+
+pub fn remove_context_server_source(settings: &mut Value) -> Result<()> {
+ if let Some(obj) = settings.as_object_mut() {
+ if let Some(context_servers) = obj.get_mut("context_servers") {
+ if let Some(servers) = context_servers.as_object_mut() {
+ for (_, server) in servers.iter_mut() {
+ if let Some(server_obj) = server.as_object_mut() {
+ server_obj.remove("source");
+ }
+ }
+ }
+ }
+ }
+ Ok(())
+}
@@ -223,6 +223,7 @@ pub fn migrate_settings(text: &str) -> Result<Option<String>> {
migrations::m_2025_11_20::SETTINGS_PATTERNS,
&SETTINGS_QUERY_2025_11_20,
),
+ MigrationType::Json(migrations::m_2025_11_25::remove_context_server_source),
];
run_migrations(text, migrations)
}
@@ -1334,7 +1335,6 @@ mod tests {
r#"{
"context_servers": {
"some-mcp-server": {
- "source": "custom",
"command": {
"path": "npx",
"args": [
@@ -1354,7 +1354,6 @@ mod tests {
r#"{
"context_servers": {
"some-mcp-server": {
- "source": "custom",
"command": "npx",
"args": [
"-y",
@@ -1376,7 +1375,6 @@ mod tests {
r#"{
"context_servers": {
"server-with-extras": {
- "source": "custom",
"command": {
"path": "/usr/bin/node",
"args": ["server.js"]
@@ -1389,7 +1387,6 @@ mod tests {
r#"{
"context_servers": {
"server-with-extras": {
- "source": "custom",
"command": "/usr/bin/node",
"args": ["server.js"],
"settings": {}
@@ -1404,7 +1401,6 @@ mod tests {
r#"{
"context_servers": {
"simple-server": {
- "source": "custom",
"command": {
"path": "simple-mcp-server"
}
@@ -1415,7 +1411,6 @@ mod tests {
r#"{
"context_servers": {
"simple-server": {
- "source": "custom",
"command": "simple-mcp-server"
}
}
@@ -2311,4 +2306,52 @@ mod tests {
),
);
}
+
+ #[test]
+ fn test_remove_context_server_source() {
+ assert_migrate_settings(
+ &r#"
+ {
+ "context_servers": {
+ "extension_server": {
+ "source": "extension",
+ "settings": {
+ "foo": "bar"
+ }
+ },
+ "custom_server": {
+ "source": "custom",
+ "command": "foo",
+ "args": ["bar"],
+ "env": {
+ "FOO": "BAR"
+ }
+ },
+ }
+ }
+ "#
+ .unindent(),
+ Some(
+ &r#"
+ {
+ "context_servers": {
+ "extension_server": {
+ "settings": {
+ "foo": "bar"
+ }
+ },
+ "custom_server": {
+ "command": "foo",
+ "args": ["bar"],
+ "env": {
+ "FOO": "BAR"
+ }
+ },
+ }
+ }
+ "#
+ .unindent(),
+ ),
+ );
+ }
}
@@ -122,7 +122,7 @@ impl ContextServerConfiguration {
cx: &AsyncApp,
) -> Option<Self> {
match settings {
- ContextServerSettings::Custom {
+ ContextServerSettings::Stdio {
enabled: _,
command,
} => Some(ContextServerConfiguration::Custom { command }),
@@ -1003,7 +1003,7 @@ mod tests {
),
(
server_2_id.0.clone(),
- settings::ContextServerSettingsContent::Custom {
+ settings::ContextServerSettingsContent::Stdio {
enabled: true,
command: ContextServerCommand {
path: "somebinary".into(),
@@ -1044,7 +1044,7 @@ mod tests {
),
(
server_2_id.0.clone(),
- settings::ContextServerSettingsContent::Custom {
+ settings::ContextServerSettingsContent::Stdio {
enabled: true,
command: ContextServerCommand {
path: "somebinary".into(),
@@ -1127,7 +1127,7 @@ mod tests {
json!({"code.rs": ""}),
vec![(
SERVER_1_ID.into(),
- ContextServerSettings::Custom {
+ ContextServerSettings::Stdio {
enabled: true,
command: ContextServerCommand {
path: "somebinary".into(),
@@ -1180,7 +1180,7 @@ mod tests {
set_context_server_configuration(
vec![(
server_1_id.0.clone(),
- settings::ContextServerSettingsContent::Custom {
+ settings::ContextServerSettingsContent::Stdio {
enabled: false,
command: ContextServerCommand {
path: "somebinary".into(),
@@ -1209,7 +1209,7 @@ mod tests {
set_context_server_configuration(
vec![(
server_1_id.0.clone(),
- settings::ContextServerSettingsContent::Custom {
+ settings::ContextServerSettingsContent::Stdio {
enabled: true,
command: ContextServerCommand {
path: "somebinary".into(),
@@ -1328,7 +1328,7 @@ mod tests {
}
fn dummy_server_settings() -> ContextServerSettings {
- ContextServerSettings::Custom {
+ ContextServerSettings::Stdio {
enabled: true,
command: ContextServerCommand {
path: "somebinary".into(),
@@ -117,7 +117,7 @@ pub struct GlobalLspSettings {
#[derive(Deserialize, Serialize, Clone, PartialEq, Eq, JsonSchema, Debug)]
#[serde(tag = "source", rename_all = "snake_case")]
pub enum ContextServerSettings {
- Custom {
+ Stdio {
/// Whether the context server is enabled.
#[serde(default = "default_true")]
enabled: bool,
@@ -125,16 +125,6 @@ pub enum ContextServerSettings {
#[serde(flatten)]
command: ContextServerCommand,
},
- Extension {
- /// Whether the context server is enabled.
- #[serde(default = "default_true")]
- enabled: bool,
- /// The settings for this context server specified by the extension.
- ///
- /// Consult the documentation for the context server to see what settings
- /// are supported.
- settings: serde_json::Value,
- },
Http {
/// Whether the context server is enabled.
#[serde(default = "default_true")]
@@ -145,13 +135,23 @@ pub enum ContextServerSettings {
#[serde(skip_serializing_if = "HashMap::is_empty", default)]
headers: HashMap<String, String>,
},
+ Extension {
+ /// Whether the context server is enabled.
+ #[serde(default = "default_true")]
+ enabled: bool,
+ /// The settings for this context server specified by the extension.
+ ///
+ /// Consult the documentation for the context server to see what settings
+ /// are supported.
+ settings: serde_json::Value,
+ },
}
impl From<settings::ContextServerSettingsContent> for ContextServerSettings {
fn from(value: settings::ContextServerSettingsContent) -> Self {
match value {
- settings::ContextServerSettingsContent::Custom { enabled, command } => {
- ContextServerSettings::Custom { enabled, command }
+ settings::ContextServerSettingsContent::Stdio { enabled, command } => {
+ ContextServerSettings::Stdio { enabled, command }
}
settings::ContextServerSettingsContent::Extension { enabled, settings } => {
ContextServerSettings::Extension { enabled, settings }
@@ -171,8 +171,8 @@ impl From<settings::ContextServerSettingsContent> for ContextServerSettings {
impl Into<settings::ContextServerSettingsContent> for ContextServerSettings {
fn into(self) -> settings::ContextServerSettingsContent {
match self {
- ContextServerSettings::Custom { enabled, command } => {
- settings::ContextServerSettingsContent::Custom { enabled, command }
+ ContextServerSettings::Stdio { enabled, command } => {
+ settings::ContextServerSettingsContent::Stdio { enabled, command }
}
ContextServerSettings::Extension { enabled, settings } => {
settings::ContextServerSettingsContent::Extension { enabled, settings }
@@ -200,17 +200,17 @@ impl ContextServerSettings {
pub fn enabled(&self) -> bool {
match self {
- ContextServerSettings::Custom { enabled, .. } => *enabled,
- ContextServerSettings::Extension { enabled, .. } => *enabled,
+ ContextServerSettings::Stdio { enabled, .. } => *enabled,
ContextServerSettings::Http { enabled, .. } => *enabled,
+ ContextServerSettings::Extension { enabled, .. } => *enabled,
}
}
pub fn set_enabled(&mut self, enabled: bool) {
match self {
- ContextServerSettings::Custom { enabled: e, .. } => *e = enabled,
- ContextServerSettings::Extension { enabled: e, .. } => *e = enabled,
+ ContextServerSettings::Stdio { enabled: e, .. } => *e = enabled,
ContextServerSettings::Http { enabled: e, .. } => *e = enabled,
+ ContextServerSettings::Extension { enabled: e, .. } => *e = enabled,
}
}
}
@@ -192,7 +192,7 @@ pub struct SessionSettingsContent {
#[derive(Deserialize, Serialize, Clone, PartialEq, Eq, JsonSchema, MergeFrom, Debug)]
#[serde(untagged, rename_all = "snake_case")]
pub enum ContextServerSettingsContent {
- Custom {
+ Stdio {
/// Whether the context server is enabled.
#[serde(default = "default_true")]
enabled: bool,
@@ -225,7 +225,7 @@ pub enum ContextServerSettingsContent {
impl ContextServerSettingsContent {
pub fn set_enabled(&mut self, enabled: bool) {
match self {
- ContextServerSettingsContent::Custom {
+ ContextServerSettingsContent::Stdio {
enabled: custom_enabled,
..
} => {
@@ -568,7 +568,7 @@ impl VsCodeSettings {
.filter_map(|(k, v)| {
Some((
k.clone().into(),
- ContextServerSettingsContent::Custom {
+ ContextServerSettingsContent::Stdio {
enabled: true,
command: serde_json::from_value::<VsCodeContextServerCommand>(v.clone())
.ok()
@@ -4686,6 +4686,133 @@ mod tests {
});
}
+ /// Checks that action namespaces are the expected set. The purpose of this is to prevent typos
+ /// and let you know when introducing a new namespace.
+ #[gpui::test]
+ async fn test_action_namespaces(cx: &mut gpui::TestAppContext) {
+ use itertools::Itertools;
+
+ init_keymap_test(cx);
+ cx.update(|cx| {
+ let all_actions = cx.all_action_names();
+
+ let mut actions_without_namespace = Vec::new();
+ let all_namespaces = all_actions
+ .iter()
+ .filter_map(|action_name| {
+ let namespace = action_name
+ .split("::")
+ .collect::<Vec<_>>()
+ .into_iter()
+ .rev()
+ .skip(1)
+ .rev()
+ .join("::");
+ if namespace.is_empty() {
+ actions_without_namespace.push(*action_name);
+ }
+ if &namespace == "test_only" || &namespace == "stories" {
+ None
+ } else {
+ Some(namespace)
+ }
+ })
+ .sorted()
+ .dedup()
+ .collect::<Vec<_>>();
+ assert_eq!(actions_without_namespace, Vec::<&str>::new());
+
+ let expected_namespaces = vec![
+ "action",
+ "activity_indicator",
+ "agent",
+ #[cfg(not(target_os = "macos"))]
+ "app_menu",
+ "assistant",
+ "assistant2",
+ "auto_update",
+ "bedrock",
+ "branches",
+ "buffer_search",
+ "channel_modal",
+ "cli",
+ "client",
+ "collab",
+ "collab_panel",
+ "command_palette",
+ "console",
+ "context_server",
+ "copilot",
+ "debug_panel",
+ "debugger",
+ "dev",
+ "diagnostics",
+ "edit_prediction",
+ "editor",
+ "feedback",
+ "file_finder",
+ "git",
+ "git_onboarding",
+ "git_panel",
+ "go_to_line",
+ "icon_theme_selector",
+ "journal",
+ "keymap_editor",
+ "keystroke_input",
+ "language_selector",
+ "line_ending_selector",
+ "lsp_tool",
+ "markdown",
+ "menu",
+ "notebook",
+ "notification_panel",
+ "onboarding",
+ "outline",
+ "outline_panel",
+ "pane",
+ "panel",
+ "picker",
+ "project_panel",
+ "project_search",
+ "project_symbols",
+ "projects",
+ "repl",
+ "rules_library",
+ "search",
+ "settings_editor",
+ "settings_profile_selector",
+ "snippets",
+ "stash_picker",
+ "supermaven",
+ "svg",
+ "syntax_tree_view",
+ "tab_switcher",
+ "task",
+ "terminal",
+ "terminal_panel",
+ "theme_selector",
+ "toast",
+ "toolchain",
+ "variable_list",
+ "vim",
+ "window",
+ "workspace",
+ "zed",
+ "zed_actions",
+ "zed_predict_onboarding",
+ "zeta",
+ ];
+ assert_eq!(
+ all_namespaces,
+ expected_namespaces
+ .into_iter()
+ .map(|namespace| namespace.to_string())
+ .sorted()
+ .collect::<Vec<_>>()
+ );
+ });
+ }
+
#[gpui::test]
fn test_bundled_settings_and_themes(cx: &mut App) {
cx.text_system()
@@ -40,12 +40,12 @@ You can connect them by adding their commands directly to your `settings.json`,
```json [settings]
{
"context_servers": {
- "run-command": {
+ "local-mcp-server": {
"command": "some-command",
"args": ["arg-1", "arg-2"],
"env": {}
},
- "over-http": {
+ "remote-mcp-server": {
"url": "custom",
"headers": { "Authorization": "Bearer <token>" }
}