|
@@ -6,7 +6,7 @@ use std::path::{Path, PathBuf};
|
|
|
use crate::json::JsonValue;
|
|
use crate::json::JsonValue;
|
|
|
use crate::sandbox::{FilesystemIsolationMode, SandboxConfig};
|
|
use crate::sandbox::{FilesystemIsolationMode, SandboxConfig};
|
|
|
|
|
|
|
|
-pub const CLAUDE_CODE_SETTINGS_SCHEMA_NAME: &str = "SettingsSchema";
|
|
|
|
|
|
|
+pub const CLAW_SETTINGS_SCHEMA_NAME: &str = "SettingsSchema";
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
|
|
pub enum ConfigSource {
|
|
pub enum ConfigSource {
|
|
@@ -78,7 +78,7 @@ pub enum McpTransport {
|
|
|
Http,
|
|
Http,
|
|
|
Ws,
|
|
Ws,
|
|
|
Sdk,
|
|
Sdk,
|
|
|
- ClaudeAiProxy,
|
|
|
|
|
|
|
+ ManagedProxy,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
@@ -88,7 +88,7 @@ pub enum McpServerConfig {
|
|
|
Http(McpRemoteServerConfig),
|
|
Http(McpRemoteServerConfig),
|
|
|
Ws(McpWebSocketServerConfig),
|
|
Ws(McpWebSocketServerConfig),
|
|
|
Sdk(McpSdkServerConfig),
|
|
Sdk(McpSdkServerConfig),
|
|
|
- ClaudeAiProxy(McpClaudeAiProxyServerConfig),
|
|
|
|
|
|
|
+ ManagedProxy(McpManagedProxyServerConfig),
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
@@ -119,7 +119,7 @@ pub struct McpSdkServerConfig {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
|
-pub struct McpClaudeAiProxyServerConfig {
|
|
|
|
|
|
|
+pub struct McpManagedProxyServerConfig {
|
|
|
pub url: String,
|
|
pub url: String,
|
|
|
pub id: String,
|
|
pub id: String,
|
|
|
}
|
|
}
|
|
@@ -183,18 +183,18 @@ impl ConfigLoader {
|
|
|
#[must_use]
|
|
#[must_use]
|
|
|
pub fn default_for(cwd: impl Into<PathBuf>) -> Self {
|
|
pub fn default_for(cwd: impl Into<PathBuf>) -> Self {
|
|
|
let cwd = cwd.into();
|
|
let cwd = cwd.into();
|
|
|
- let config_home = std::env::var_os("CLAUDE_CONFIG_HOME")
|
|
|
|
|
|
|
+ let config_home = std::env::var_os("CLAW_CONFIG_HOME")
|
|
|
.map(PathBuf::from)
|
|
.map(PathBuf::from)
|
|
|
- .or_else(|| std::env::var_os("HOME").map(|home| PathBuf::from(home).join(".claude")))
|
|
|
|
|
- .unwrap_or_else(|| PathBuf::from(".claude"));
|
|
|
|
|
|
|
+ .or_else(|| std::env::var_os("HOME").map(|home| PathBuf::from(home).join(".claw")))
|
|
|
|
|
+ .unwrap_or_else(|| PathBuf::from(".claw"));
|
|
|
Self { cwd, config_home }
|
|
Self { cwd, config_home }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[must_use]
|
|
#[must_use]
|
|
|
pub fn discover(&self) -> Vec<ConfigEntry> {
|
|
pub fn discover(&self) -> Vec<ConfigEntry> {
|
|
|
let user_legacy_path = self.config_home.parent().map_or_else(
|
|
let user_legacy_path = self.config_home.parent().map_or_else(
|
|
|
- || PathBuf::from(".claude.json"),
|
|
|
|
|
- |parent| parent.join(".claude.json"),
|
|
|
|
|
|
|
+ || PathBuf::from(".claw.json"),
|
|
|
|
|
+ |parent| parent.join(".claw.json"),
|
|
|
);
|
|
);
|
|
|
vec![
|
|
vec![
|
|
|
ConfigEntry {
|
|
ConfigEntry {
|
|
@@ -207,15 +207,15 @@ impl ConfigLoader {
|
|
|
},
|
|
},
|
|
|
ConfigEntry {
|
|
ConfigEntry {
|
|
|
source: ConfigSource::Project,
|
|
source: ConfigSource::Project,
|
|
|
- path: self.cwd.join(".claude.json"),
|
|
|
|
|
|
|
+ path: self.cwd.join(".claw.json"),
|
|
|
},
|
|
},
|
|
|
ConfigEntry {
|
|
ConfigEntry {
|
|
|
source: ConfigSource::Project,
|
|
source: ConfigSource::Project,
|
|
|
- path: self.cwd.join(".claude").join("settings.json"),
|
|
|
|
|
|
|
+ path: self.cwd.join(".claw").join("settings.json"),
|
|
|
},
|
|
},
|
|
|
ConfigEntry {
|
|
ConfigEntry {
|
|
|
source: ConfigSource::Local,
|
|
source: ConfigSource::Local,
|
|
|
- path: self.cwd.join(".claude").join("settings.local.json"),
|
|
|
|
|
|
|
+ path: self.cwd.join(".claw").join("settings.local.json"),
|
|
|
},
|
|
},
|
|
|
]
|
|
]
|
|
|
}
|
|
}
|
|
@@ -450,7 +450,7 @@ impl McpServerConfig {
|
|
|
Self::Http(_) => McpTransport::Http,
|
|
Self::Http(_) => McpTransport::Http,
|
|
|
Self::Ws(_) => McpTransport::Ws,
|
|
Self::Ws(_) => McpTransport::Ws,
|
|
|
Self::Sdk(_) => McpTransport::Sdk,
|
|
Self::Sdk(_) => McpTransport::Sdk,
|
|
|
- Self::ClaudeAiProxy(_) => McpTransport::ClaudeAiProxy,
|
|
|
|
|
|
|
+ Self::ManagedProxy(_) => McpTransport::ManagedProxy,
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -458,7 +458,7 @@ impl McpServerConfig {
|
|
|
fn read_optional_json_object(
|
|
fn read_optional_json_object(
|
|
|
path: &Path,
|
|
path: &Path,
|
|
|
) -> Result<Option<BTreeMap<String, JsonValue>>, ConfigError> {
|
|
) -> Result<Option<BTreeMap<String, JsonValue>>, ConfigError> {
|
|
|
- let is_legacy_config = path.file_name().and_then(|name| name.to_str()) == Some(".claude.json");
|
|
|
|
|
|
|
+ let is_legacy_config = path.file_name().and_then(|name| name.to_str()) == Some(".claw.json");
|
|
|
let contents = match fs::read_to_string(path) {
|
|
let contents = match fs::read_to_string(path) {
|
|
|
Ok(contents) => contents,
|
|
Ok(contents) => contents,
|
|
|
Err(error) if error.kind() == std::io::ErrorKind::NotFound => return Ok(None),
|
|
Err(error) if error.kind() == std::io::ErrorKind::NotFound => return Ok(None),
|
|
@@ -684,8 +684,8 @@ fn parse_mcp_server_config(
|
|
|
"sdk" => Ok(McpServerConfig::Sdk(McpSdkServerConfig {
|
|
"sdk" => Ok(McpServerConfig::Sdk(McpSdkServerConfig {
|
|
|
name: expect_string(object, "name", context)?.to_string(),
|
|
name: expect_string(object, "name", context)?.to_string(),
|
|
|
})),
|
|
})),
|
|
|
- "claudeai-proxy" => Ok(McpServerConfig::ClaudeAiProxy(
|
|
|
|
|
- McpClaudeAiProxyServerConfig {
|
|
|
|
|
|
|
+ "managed-proxy" => Ok(McpServerConfig::ManagedProxy(
|
|
|
|
|
+ McpManagedProxyServerConfig {
|
|
|
url: expect_string(object, "url", context)?.to_string(),
|
|
url: expect_string(object, "url", context)?.to_string(),
|
|
|
id: expect_string(object, "id", context)?.to_string(),
|
|
id: expect_string(object, "id", context)?.to_string(),
|
|
|
},
|
|
},
|
|
@@ -872,7 +872,7 @@ fn deep_merge_objects(
|
|
|
mod tests {
|
|
mod tests {
|
|
|
use super::{
|
|
use super::{
|
|
|
ConfigLoader, ConfigSource, McpServerConfig, McpTransport, ResolvedPermissionMode,
|
|
ConfigLoader, ConfigSource, McpServerConfig, McpTransport, ResolvedPermissionMode,
|
|
|
- CLAUDE_CODE_SETTINGS_SCHEMA_NAME,
|
|
|
|
|
|
|
+ CLAW_SETTINGS_SCHEMA_NAME,
|
|
|
};
|
|
};
|
|
|
use crate::json::JsonValue;
|
|
use crate::json::JsonValue;
|
|
|
use crate::sandbox::FilesystemIsolationMode;
|
|
use crate::sandbox::FilesystemIsolationMode;
|
|
@@ -891,7 +891,7 @@ mod tests {
|
|
|
fn rejects_non_object_settings_files() {
|
|
fn rejects_non_object_settings_files() {
|
|
|
let root = temp_dir();
|
|
let root = temp_dir();
|
|
|
let cwd = root.join("project");
|
|
let cwd = root.join("project");
|
|
|
- let home = root.join("home").join(".claude");
|
|
|
|
|
|
|
+ let home = root.join("home").join(".claw");
|
|
|
fs::create_dir_all(&home).expect("home config dir");
|
|
fs::create_dir_all(&home).expect("home config dir");
|
|
|
fs::create_dir_all(&cwd).expect("project dir");
|
|
fs::create_dir_all(&cwd).expect("project dir");
|
|
|
fs::write(home.join("settings.json"), "[]").expect("write bad settings");
|
|
fs::write(home.join("settings.json"), "[]").expect("write bad settings");
|
|
@@ -907,15 +907,15 @@ mod tests {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
|
- fn loads_and_merges_claude_code_config_files_by_precedence() {
|
|
|
|
|
|
|
+ fn loads_and_merges_claw_config_files_by_precedence() {
|
|
|
let root = temp_dir();
|
|
let root = temp_dir();
|
|
|
let cwd = root.join("project");
|
|
let cwd = root.join("project");
|
|
|
- let home = root.join("home").join(".claude");
|
|
|
|
|
- fs::create_dir_all(cwd.join(".claude")).expect("project config dir");
|
|
|
|
|
|
|
+ let home = root.join("home").join(".claw");
|
|
|
|
|
+ fs::create_dir_all(cwd.join(".claw")).expect("project config dir");
|
|
|
fs::create_dir_all(&home).expect("home config dir");
|
|
fs::create_dir_all(&home).expect("home config dir");
|
|
|
|
|
|
|
|
fs::write(
|
|
fs::write(
|
|
|
- home.parent().expect("home parent").join(".claude.json"),
|
|
|
|
|
|
|
+ home.parent().expect("home parent").join(".claw.json"),
|
|
|
r#"{"model":"haiku","env":{"A":"1"},"mcpServers":{"home":{"command":"uvx","args":["home"]}}}"#,
|
|
r#"{"model":"haiku","env":{"A":"1"},"mcpServers":{"home":{"command":"uvx","args":["home"]}}}"#,
|
|
|
)
|
|
)
|
|
|
.expect("write user compat config");
|
|
.expect("write user compat config");
|
|
@@ -925,17 +925,17 @@ mod tests {
|
|
|
)
|
|
)
|
|
|
.expect("write user settings");
|
|
.expect("write user settings");
|
|
|
fs::write(
|
|
fs::write(
|
|
|
- cwd.join(".claude.json"),
|
|
|
|
|
|
|
+ cwd.join(".claw.json"),
|
|
|
r#"{"model":"project-compat","env":{"B":"2"}}"#,
|
|
r#"{"model":"project-compat","env":{"B":"2"}}"#,
|
|
|
)
|
|
)
|
|
|
.expect("write project compat config");
|
|
.expect("write project compat config");
|
|
|
fs::write(
|
|
fs::write(
|
|
|
- cwd.join(".claude").join("settings.json"),
|
|
|
|
|
|
|
+ cwd.join(".claw").join("settings.json"),
|
|
|
r#"{"env":{"C":"3"},"hooks":{"PostToolUse":["project"],"PostToolUseFailure":["project-failure"]},"permissions":{"ask":["Edit"]},"mcpServers":{"project":{"command":"uvx","args":["project"]}}}"#,
|
|
r#"{"env":{"C":"3"},"hooks":{"PostToolUse":["project"],"PostToolUseFailure":["project-failure"]},"permissions":{"ask":["Edit"]},"mcpServers":{"project":{"command":"uvx","args":["project"]}}}"#,
|
|
|
)
|
|
)
|
|
|
.expect("write project settings");
|
|
.expect("write project settings");
|
|
|
fs::write(
|
|
fs::write(
|
|
|
- cwd.join(".claude").join("settings.local.json"),
|
|
|
|
|
|
|
+ cwd.join(".claw").join("settings.local.json"),
|
|
|
r#"{"model":"opus","permissionMode":"acceptEdits"}"#,
|
|
r#"{"model":"opus","permissionMode":"acceptEdits"}"#,
|
|
|
)
|
|
)
|
|
|
.expect("write local settings");
|
|
.expect("write local settings");
|
|
@@ -944,7 +944,7 @@ mod tests {
|
|
|
.load()
|
|
.load()
|
|
|
.expect("config should load");
|
|
.expect("config should load");
|
|
|
|
|
|
|
|
- assert_eq!(CLAUDE_CODE_SETTINGS_SCHEMA_NAME, "SettingsSchema");
|
|
|
|
|
|
|
+ assert_eq!(CLAW_SETTINGS_SCHEMA_NAME, "SettingsSchema");
|
|
|
assert_eq!(loaded.loaded_entries().len(), 5);
|
|
assert_eq!(loaded.loaded_entries().len(), 5);
|
|
|
assert_eq!(loaded.loaded_entries()[0].source, ConfigSource::User);
|
|
assert_eq!(loaded.loaded_entries()[0].source, ConfigSource::User);
|
|
|
assert_eq!(
|
|
assert_eq!(
|
|
@@ -996,12 +996,12 @@ mod tests {
|
|
|
fn parses_sandbox_config() {
|
|
fn parses_sandbox_config() {
|
|
|
let root = temp_dir();
|
|
let root = temp_dir();
|
|
|
let cwd = root.join("project");
|
|
let cwd = root.join("project");
|
|
|
- let home = root.join("home").join(".claude");
|
|
|
|
|
- fs::create_dir_all(cwd.join(".claude")).expect("project config dir");
|
|
|
|
|
|
|
+ let home = root.join("home").join(".claw");
|
|
|
|
|
+ fs::create_dir_all(cwd.join(".claw")).expect("project config dir");
|
|
|
fs::create_dir_all(&home).expect("home config dir");
|
|
fs::create_dir_all(&home).expect("home config dir");
|
|
|
|
|
|
|
|
fs::write(
|
|
fs::write(
|
|
|
- cwd.join(".claude").join("settings.local.json"),
|
|
|
|
|
|
|
+ cwd.join(".claw").join("settings.local.json"),
|
|
|
r#"{
|
|
r#"{
|
|
|
"sandbox": {
|
|
"sandbox": {
|
|
|
"enabled": true,
|
|
"enabled": true,
|
|
@@ -1034,8 +1034,8 @@ mod tests {
|
|
|
fn parses_typed_mcp_and_oauth_config() {
|
|
fn parses_typed_mcp_and_oauth_config() {
|
|
|
let root = temp_dir();
|
|
let root = temp_dir();
|
|
|
let cwd = root.join("project");
|
|
let cwd = root.join("project");
|
|
|
- let home = root.join("home").join(".claude");
|
|
|
|
|
- fs::create_dir_all(cwd.join(".claude")).expect("project config dir");
|
|
|
|
|
|
|
+ let home = root.join("home").join(".claw");
|
|
|
|
|
+ fs::create_dir_all(cwd.join(".claw")).expect("project config dir");
|
|
|
fs::create_dir_all(&home).expect("home config dir");
|
|
fs::create_dir_all(&home).expect("home config dir");
|
|
|
|
|
|
|
|
fs::write(
|
|
fs::write(
|
|
@@ -1072,7 +1072,7 @@ mod tests {
|
|
|
)
|
|
)
|
|
|
.expect("write user settings");
|
|
.expect("write user settings");
|
|
|
fs::write(
|
|
fs::write(
|
|
|
- cwd.join(".claude").join("settings.local.json"),
|
|
|
|
|
|
|
+ cwd.join(".claw").join("settings.local.json"),
|
|
|
r#"{
|
|
r#"{
|
|
|
"mcpServers": {
|
|
"mcpServers": {
|
|
|
"remote-server": {
|
|
"remote-server": {
|
|
@@ -1125,7 +1125,7 @@ mod tests {
|
|
|
fn rejects_invalid_mcp_server_shapes() {
|
|
fn rejects_invalid_mcp_server_shapes() {
|
|
|
let root = temp_dir();
|
|
let root = temp_dir();
|
|
|
let cwd = root.join("project");
|
|
let cwd = root.join("project");
|
|
|
- let home = root.join("home").join(".claude");
|
|
|
|
|
|
|
+ let home = root.join("home").join(".claw");
|
|
|
fs::create_dir_all(&home).expect("home config dir");
|
|
fs::create_dir_all(&home).expect("home config dir");
|
|
|
fs::create_dir_all(&cwd).expect("project dir");
|
|
fs::create_dir_all(&cwd).expect("project dir");
|
|
|
fs::write(
|
|
fs::write(
|