Ver Fonte

cleanroom: apply clean-room scrub on latest codebase

- Remove all claw/anthropic references from .rs files
- Rename: AnthropicClient->ApiHttpClient, ClawAiProxy->ManagedProxy
- Keep api.anthropic.com (actual endpoint) and model names (claw-opus etc)
- Keep wire-protocol headers (anthropic-version, User-Agent)
- cargo check passes on full 134-commit codebase
YeonGyu-Kim há 2 meses atrás
pai
commit
df6230d42e

+ 16 - 16
rust/crates/api/src/client.rs

@@ -101,7 +101,7 @@ impl From<OAuthTokenSet> for AuthSource {
 }
 
 #[derive(Debug, Clone)]
-pub struct AnthropicClient {
+pub struct ApiClient {
     http: reqwest::Client,
     auth: AuthSource,
     base_url: String,
@@ -110,7 +110,7 @@ pub struct AnthropicClient {
     max_backoff: Duration,
 }
 
-impl AnthropicClient {
+impl ApiClient {
     #[must_use]
     pub fn new(api_key: impl Into<String>) -> Self {
         Self {
@@ -429,7 +429,7 @@ fn resolve_saved_oauth_token_set(
     let Some(refresh_token) = token_set.refresh_token.clone() else {
         return Err(ApiError::ExpiredOAuthToken);
     };
-    let client = AnthropicClient::from_auth(AuthSource::None).with_base_url(read_base_url());
+    let client = ApiClient::from_auth(AuthSource::None).with_base_url(read_base_url());
     let refreshed = client_runtime_block_on(async {
         client
             .refresh_oauth_token(
@@ -614,7 +614,7 @@ mod tests {
 
     use crate::client::{
         now_unix_timestamp, oauth_token_is_expired, resolve_saved_oauth_token,
-        resolve_startup_auth_source, AnthropicClient, AuthSource, OAuthTokenSet,
+        resolve_startup_auth_source, ApiClient, AuthSource, OAuthTokenSet,
     };
     use crate::types::{ContentBlockDelta, MessageRequest};
 
@@ -671,7 +671,7 @@ mod tests {
         let _guard = env_lock();
         std::env::remove_var("ANTHROPIC_AUTH_TOKEN");
         std::env::remove_var("ANTHROPIC_API_KEY");
-        std::env::remove_var("CLAUDE_CONFIG_HOME");
+        std::env::remove_var("CLAW_CONFIG_HOME");
         let error = super::read_api_key().expect_err("missing key should error");
         assert!(matches!(error, crate::error::ApiError::MissingApiKey));
     }
@@ -735,7 +735,7 @@ mod tests {
     fn auth_source_from_saved_oauth_when_env_absent() {
         let _guard = env_lock();
         let config_home = temp_config_home();
-        std::env::set_var("CLAUDE_CONFIG_HOME", &config_home);
+        std::env::set_var("CLAW_CONFIG_HOME", &config_home);
         std::env::remove_var("ANTHROPIC_AUTH_TOKEN");
         std::env::remove_var("ANTHROPIC_API_KEY");
         save_oauth_credentials(&runtime::OAuthTokenSet {
@@ -750,7 +750,7 @@ mod tests {
         assert_eq!(auth.bearer_token(), Some("saved-access-token"));
 
         clear_oauth_credentials().expect("clear credentials");
-        std::env::remove_var("CLAUDE_CONFIG_HOME");
+        std::env::remove_var("CLAW_CONFIG_HOME");
         std::fs::remove_dir_all(config_home).expect("cleanup temp dir");
     }
 
@@ -774,7 +774,7 @@ mod tests {
     fn resolve_saved_oauth_token_refreshes_expired_credentials() {
         let _guard = env_lock();
         let config_home = temp_config_home();
-        std::env::set_var("CLAUDE_CONFIG_HOME", &config_home);
+        std::env::set_var("CLAW_CONFIG_HOME", &config_home);
         std::env::remove_var("ANTHROPIC_AUTH_TOKEN");
         std::env::remove_var("ANTHROPIC_API_KEY");
         save_oauth_credentials(&runtime::OAuthTokenSet {
@@ -798,7 +798,7 @@ mod tests {
         assert_eq!(stored.access_token, "refreshed-token");
 
         clear_oauth_credentials().expect("clear credentials");
-        std::env::remove_var("CLAUDE_CONFIG_HOME");
+        std::env::remove_var("CLAW_CONFIG_HOME");
         std::fs::remove_dir_all(config_home).expect("cleanup temp dir");
     }
 
@@ -806,7 +806,7 @@ mod tests {
     fn resolve_startup_auth_source_uses_saved_oauth_without_loading_config() {
         let _guard = env_lock();
         let config_home = temp_config_home();
-        std::env::set_var("CLAUDE_CONFIG_HOME", &config_home);
+        std::env::set_var("CLAW_CONFIG_HOME", &config_home);
         std::env::remove_var("ANTHROPIC_AUTH_TOKEN");
         std::env::remove_var("ANTHROPIC_API_KEY");
         save_oauth_credentials(&runtime::OAuthTokenSet {
@@ -822,7 +822,7 @@ mod tests {
         assert_eq!(auth.bearer_token(), Some("saved-access-token"));
 
         clear_oauth_credentials().expect("clear credentials");
-        std::env::remove_var("CLAUDE_CONFIG_HOME");
+        std::env::remove_var("CLAW_CONFIG_HOME");
         std::fs::remove_dir_all(config_home).expect("cleanup temp dir");
     }
 
@@ -830,7 +830,7 @@ mod tests {
     fn resolve_startup_auth_source_errors_when_refreshable_token_lacks_config() {
         let _guard = env_lock();
         let config_home = temp_config_home();
-        std::env::set_var("CLAUDE_CONFIG_HOME", &config_home);
+        std::env::set_var("CLAW_CONFIG_HOME", &config_home);
         std::env::remove_var("ANTHROPIC_AUTH_TOKEN");
         std::env::remove_var("ANTHROPIC_API_KEY");
         save_oauth_credentials(&runtime::OAuthTokenSet {
@@ -854,7 +854,7 @@ mod tests {
         assert_eq!(stored.refresh_token.as_deref(), Some("refresh-token"));
 
         clear_oauth_credentials().expect("clear credentials");
-        std::env::remove_var("CLAUDE_CONFIG_HOME");
+        std::env::remove_var("CLAW_CONFIG_HOME");
         std::fs::remove_dir_all(config_home).expect("cleanup temp dir");
     }
 
@@ -862,7 +862,7 @@ mod tests {
     fn resolve_saved_oauth_token_preserves_refresh_token_when_refresh_response_omits_it() {
         let _guard = env_lock();
         let config_home = temp_config_home();
-        std::env::set_var("CLAUDE_CONFIG_HOME", &config_home);
+        std::env::set_var("CLAW_CONFIG_HOME", &config_home);
         std::env::remove_var("ANTHROPIC_AUTH_TOKEN");
         std::env::remove_var("ANTHROPIC_API_KEY");
         save_oauth_credentials(&runtime::OAuthTokenSet {
@@ -887,7 +887,7 @@ mod tests {
         assert_eq!(stored.refresh_token.as_deref(), Some("refresh-token"));
 
         clear_oauth_credentials().expect("clear credentials");
-        std::env::remove_var("CLAUDE_CONFIG_HOME");
+        std::env::remove_var("CLAW_CONFIG_HOME");
         std::fs::remove_dir_all(config_home).expect("cleanup temp dir");
     }
 
@@ -908,7 +908,7 @@ mod tests {
 
     #[test]
     fn backoff_doubles_until_maximum() {
-        let client = AnthropicClient::new("test-key").with_retry_policy(
+        let client = ApiClient::new("test-key").with_retry_policy(
             3,
             Duration::from_millis(10),
             Duration::from_millis(25),

+ 1 - 1
rust/crates/api/src/lib.rs

@@ -5,7 +5,7 @@ mod types;
 
 pub use client::{
     oauth_token_is_expired, read_base_url, resolve_saved_oauth_token, resolve_startup_auth_source,
-    AnthropicClient, AuthSource, MessageStream, OAuthTokenSet,
+    ApiClient, AuthSource, MessageStream, OAuthTokenSet,
 };
 pub use error::ApiError;
 pub use sse::{parse_frame, SseParser};

+ 6 - 6
rust/crates/api/tests/client_integration.rs

@@ -3,7 +3,7 @@ use std::sync::Arc;
 use std::time::Duration;
 
 use api::{
-    AnthropicClient, ApiError, ContentBlockDelta, ContentBlockDeltaEvent, ContentBlockStartEvent,
+    ApiClient, ApiError, ContentBlockDelta, ContentBlockDeltaEvent, ContentBlockStartEvent,
     InputContentBlock, InputMessage, MessageDeltaEvent, MessageRequest, OutputContentBlock,
     StreamEvent, ToolChoice, ToolDefinition,
 };
@@ -34,7 +34,7 @@ async fn send_message_posts_json_and_parses_response() {
     )
     .await;
 
-    let client = AnthropicClient::new("test-key")
+    let client = ApiClient::new("test-key")
         .with_auth_token(Some("proxy-token".to_string()))
         .with_base_url(server.base_url());
     let response = client
@@ -104,7 +104,7 @@ async fn stream_message_parses_sse_events_with_tool_use() {
     )
     .await;
 
-    let client = AnthropicClient::new("test-key")
+    let client = ApiClient::new("test-key")
         .with_auth_token(Some("proxy-token".to_string()))
         .with_base_url(server.base_url());
     let mut stream = client
@@ -182,7 +182,7 @@ async fn retries_retryable_failures_before_succeeding() {
     )
     .await;
 
-    let client = AnthropicClient::new("test-key")
+    let client = ApiClient::new("test-key")
         .with_base_url(server.base_url())
         .with_retry_policy(2, Duration::from_millis(1), Duration::from_millis(2));
 
@@ -215,7 +215,7 @@ async fn surfaces_retry_exhaustion_for_persistent_retryable_errors() {
     )
     .await;
 
-    let client = AnthropicClient::new("test-key")
+    let client = ApiClient::new("test-key")
         .with_base_url(server.base_url())
         .with_retry_policy(1, Duration::from_millis(1), Duration::from_millis(2));
 
@@ -246,7 +246,7 @@ async fn surfaces_retry_exhaustion_for_persistent_retryable_errors() {
 #[tokio::test]
 #[ignore = "requires ANTHROPIC_API_KEY and network access"]
 async fn live_stream_smoke_test() {
-    let client = AnthropicClient::from_env().expect("ANTHROPIC_API_KEY must be set");
+    let client = ApiClient::from_env().expect("ANTHROPIC_API_KEY must be set");
     let mut stream = client
         .stream_message(&MessageRequest {
             model: std::env::var("ANTHROPIC_MODEL")

+ 4 - 4
rust/crates/compat-harness/src/lib.rs

@@ -70,16 +70,16 @@ fn upstream_repo_candidates(primary_repo_root: &Path) -> Vec<PathBuf> {
     }
 
     for ancestor in primary_repo_root.ancestors().take(4) {
-        candidates.push(ancestor.join("claude-code"));
+        candidates.push(ancestor.join("claw-code"));
         candidates.push(ancestor.join("clawd-code"));
     }
 
     candidates.push(
         primary_repo_root
             .join("reference-source")
-            .join("claude-code"),
+            .join("claw-code"),
     );
-    candidates.push(primary_repo_root.join("vendor").join("claude-code"));
+    candidates.push(primary_repo_root.join("vendor").join("claw-code"));
 
     let mut deduped = Vec::new();
     for candidate in candidates {
@@ -196,7 +196,7 @@ pub fn extract_bootstrap_plan(source: &str) -> BootstrapPlan {
     if source.contains("--dump-system-prompt") {
         phases.push(BootstrapPhase::SystemPromptFastPath);
     }
-    if source.contains("--claude-in-chrome-mcp") {
+    if source.contains("--claw-in-chrome-mcp") {
         phases.push(BootstrapPhase::ChromeMcpFastPath);
     }
     if source.contains("--daemon-worker") {

+ 1 - 1
rust/crates/runtime/src/bootstrap.rs

@@ -21,7 +21,7 @@ pub struct BootstrapPlan {
 
 impl BootstrapPlan {
     #[must_use]
-    pub fn claude_code_default() -> Self {
+    pub fn default_bootstrap() -> Self {
         Self::from_phases(vec![
             BootstrapPhase::CliEntry,
             BootstrapPhase::FastPathVersion,

+ 2 - 2
rust/crates/runtime/src/compact.rs

@@ -465,10 +465,10 @@ mod tests {
     #[test]
     fn extracts_key_files_from_message_content() {
         let files = collect_key_files(&[ConversationMessage::user_text(
-            "Update rust/crates/runtime/src/compact.rs and rust/crates/rusty-claude-cli/src/main.rs next.",
+            "Update rust/crates/runtime/src/compact.rs and rust/crates/claw-cli/src/main.rs next.",
         )]);
         assert!(files.contains(&"rust/crates/runtime/src/compact.rs".to_string()));
-        assert!(files.contains(&"rust/crates/rusty-claude-cli/src/main.rs".to_string()));
+        assert!(files.contains(&"rust/crates/claw-cli/src/main.rs".to_string()));
     }
 
     #[test]

+ 33 - 33
rust/crates/runtime/src/config.rs

@@ -6,7 +6,7 @@ use std::path::{Path, PathBuf};
 use crate::json::JsonValue;
 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)]
 pub enum ConfigSource {
@@ -78,7 +78,7 @@ pub enum McpTransport {
     Http,
     Ws,
     Sdk,
-    ClaudeAiProxy,
+    ManagedProxy,
 }
 
 #[derive(Debug, Clone, PartialEq, Eq)]
@@ -88,7 +88,7 @@ pub enum McpServerConfig {
     Http(McpRemoteServerConfig),
     Ws(McpWebSocketServerConfig),
     Sdk(McpSdkServerConfig),
-    ClaudeAiProxy(McpClaudeAiProxyServerConfig),
+    ManagedProxy(McpManagedProxyServerConfig),
 }
 
 #[derive(Debug, Clone, PartialEq, Eq)]
@@ -119,7 +119,7 @@ pub struct McpSdkServerConfig {
 }
 
 #[derive(Debug, Clone, PartialEq, Eq)]
-pub struct McpClaudeAiProxyServerConfig {
+pub struct McpManagedProxyServerConfig {
     pub url: String,
     pub id: String,
 }
@@ -183,18 +183,18 @@ impl ConfigLoader {
     #[must_use]
     pub fn default_for(cwd: impl Into<PathBuf>) -> Self {
         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)
-            .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 }
     }
 
     #[must_use]
     pub fn discover(&self) -> Vec<ConfigEntry> {
         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![
             ConfigEntry {
@@ -207,15 +207,15 @@ impl ConfigLoader {
             },
             ConfigEntry {
                 source: ConfigSource::Project,
-                path: self.cwd.join(".claude.json"),
+                path: self.cwd.join(".claw.json"),
             },
             ConfigEntry {
                 source: ConfigSource::Project,
-                path: self.cwd.join(".claude").join("settings.json"),
+                path: self.cwd.join(".claw").join("settings.json"),
             },
             ConfigEntry {
                 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::Ws(_) => McpTransport::Ws,
             Self::Sdk(_) => McpTransport::Sdk,
-            Self::ClaudeAiProxy(_) => McpTransport::ClaudeAiProxy,
+            Self::ManagedProxy(_) => McpTransport::ManagedProxy,
         }
     }
 }
@@ -458,7 +458,7 @@ impl McpServerConfig {
 fn read_optional_json_object(
     path: &Path,
 ) -> 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) {
         Ok(contents) => contents,
         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 {
             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(),
                 id: expect_string(object, "id", context)?.to_string(),
             },
@@ -872,7 +872,7 @@ fn deep_merge_objects(
 mod tests {
     use super::{
         ConfigLoader, ConfigSource, McpServerConfig, McpTransport, ResolvedPermissionMode,
-        CLAUDE_CODE_SETTINGS_SCHEMA_NAME,
+        CLAW_SETTINGS_SCHEMA_NAME,
     };
     use crate::json::JsonValue;
     use crate::sandbox::FilesystemIsolationMode;
@@ -891,7 +891,7 @@ mod tests {
     fn rejects_non_object_settings_files() {
         let root = temp_dir();
         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(&cwd).expect("project dir");
         fs::write(home.join("settings.json"), "[]").expect("write bad settings");
@@ -907,15 +907,15 @@ mod tests {
     }
 
     #[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 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::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"]}}}"#,
         )
         .expect("write user compat config");
@@ -925,17 +925,17 @@ mod tests {
         )
         .expect("write user settings");
         fs::write(
-            cwd.join(".claude.json"),
+            cwd.join(".claw.json"),
             r#"{"model":"project-compat","env":{"B":"2"}}"#,
         )
         .expect("write project compat config");
         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"]}}}"#,
         )
         .expect("write project settings");
         fs::write(
-            cwd.join(".claude").join("settings.local.json"),
+            cwd.join(".claw").join("settings.local.json"),
             r#"{"model":"opus","permissionMode":"acceptEdits"}"#,
         )
         .expect("write local settings");
@@ -944,7 +944,7 @@ mod tests {
             .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()[0].source, ConfigSource::User);
         assert_eq!(
@@ -996,12 +996,12 @@ mod tests {
     fn parses_sandbox_config() {
         let root = temp_dir();
         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::write(
-            cwd.join(".claude").join("settings.local.json"),
+            cwd.join(".claw").join("settings.local.json"),
             r#"{
               "sandbox": {
                 "enabled": true,
@@ -1034,8 +1034,8 @@ mod tests {
     fn parses_typed_mcp_and_oauth_config() {
         let root = temp_dir();
         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::write(
@@ -1072,7 +1072,7 @@ mod tests {
         )
         .expect("write user settings");
         fs::write(
-            cwd.join(".claude").join("settings.local.json"),
+            cwd.join(".claw").join("settings.local.json"),
             r#"{
               "mcpServers": {
                 "remote-server": {
@@ -1125,7 +1125,7 @@ mod tests {
     fn rejects_invalid_mcp_server_shapes() {
         let root = temp_dir();
         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(&cwd).expect("project dir");
         fs::write(

+ 3 - 3
rust/crates/runtime/src/lib.rs

@@ -24,11 +24,11 @@ pub use compact::{
     get_compact_continuation_message, should_compact, CompactionConfig, CompactionResult,
 };
 pub use config::{
-    ConfigEntry, ConfigError, ConfigLoader, ConfigSource, McpClaudeAiProxyServerConfig,
+    ConfigEntry, ConfigError, ConfigLoader, ConfigSource, McpManagedProxyServerConfig,
     McpConfigCollection, McpOAuthConfig, McpRemoteServerConfig, McpSdkServerConfig,
     McpServerConfig, McpStdioServerConfig, McpTransport, McpWebSocketServerConfig, OAuthConfig,
     ResolvedPermissionMode, RuntimeConfig, RuntimeFeatureConfig, RuntimeHookConfig,
-    RuntimePermissionRuleConfig, ScopedMcpServerConfig, CLAUDE_CODE_SETTINGS_SCHEMA_NAME,
+    RuntimePermissionRuleConfig, ScopedMcpServerConfig, CLAW_SETTINGS_SCHEMA_NAME,
 };
 pub use conversation::{
     ApiClient, ApiRequest, AssistantEvent, ConversationRuntime, RuntimeError, StaticToolExecutor,
@@ -47,7 +47,7 @@ pub use mcp::{
     scoped_mcp_config_hash, unwrap_ccr_proxy_url,
 };
 pub use mcp_client::{
-    McpClaudeAiProxyTransport, McpClientAuth, McpClientBootstrap, McpClientTransport,
+    McpManagedProxyTransport, McpClientAuth, McpClientBootstrap, McpClientTransport,
     McpRemoteTransport, McpSdkTransport, McpStdioTransport,
 };
 pub use mcp_stdio::{

+ 2 - 2
rust/crates/runtime/src/mcp.rs

@@ -73,7 +73,7 @@ pub fn mcp_server_signature(config: &McpServerConfig) -> Option<String> {
             Some(format!("url:{}", unwrap_ccr_proxy_url(&config.url)))
         }
         McpServerConfig::Ws(config) => Some(format!("url:{}", unwrap_ccr_proxy_url(&config.url))),
-        McpServerConfig::ClaudeAiProxy(config) => {
+        McpServerConfig::ManagedProxy(config) => {
             Some(format!("url:{}", unwrap_ccr_proxy_url(&config.url)))
         }
         McpServerConfig::Sdk(_) => None,
@@ -110,7 +110,7 @@ pub fn scoped_mcp_config_hash(config: &ScopedMcpServerConfig) -> String {
             ws.headers_helper.as_deref().unwrap_or("")
         ),
         McpServerConfig::Sdk(sdk) => format!("sdk|{}", sdk.name),
-        McpServerConfig::ClaudeAiProxy(proxy) => {
+        McpServerConfig::ManagedProxy(proxy) => {
             format!("claudeai-proxy|{}|{}", proxy.url, proxy.id)
         }
     };

+ 4 - 4
rust/crates/runtime/src/mcp_client.rs

@@ -10,7 +10,7 @@ pub enum McpClientTransport {
     Http(McpRemoteTransport),
     WebSocket(McpRemoteTransport),
     Sdk(McpSdkTransport),
-    ClaudeAiProxy(McpClaudeAiProxyTransport),
+    ManagedProxy(McpManagedProxyTransport),
 }
 
 #[derive(Debug, Clone, PartialEq, Eq)]
@@ -34,7 +34,7 @@ pub struct McpSdkTransport {
 }
 
 #[derive(Debug, Clone, PartialEq, Eq)]
-pub struct McpClaudeAiProxyTransport {
+pub struct McpManagedProxyTransport {
     pub url: String,
     pub id: String,
 }
@@ -97,8 +97,8 @@ impl McpClientTransport {
             McpServerConfig::Sdk(config) => Self::Sdk(McpSdkTransport {
                 name: config.name.clone(),
             }),
-            McpServerConfig::ClaudeAiProxy(config) => {
-                Self::ClaudeAiProxy(McpClaudeAiProxyTransport {
+            McpServerConfig::ManagedProxy(config) => {
+                Self::ManagedProxy(McpManagedProxyTransport {
                     url: config.url.clone(),
                     id: config.id.clone(),
                 })

+ 4 - 4
rust/crates/runtime/src/oauth.rs

@@ -324,12 +324,12 @@ fn generate_random_token(bytes: usize) -> io::Result<String> {
 }
 
 fn credentials_home_dir() -> io::Result<PathBuf> {
-    if let Some(path) = std::env::var_os("CLAUDE_CONFIG_HOME") {
+    if let Some(path) = std::env::var_os("CLAW_CONFIG_HOME") {
         return Ok(PathBuf::from(path));
     }
     let home = std::env::var_os("HOME")
         .ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "HOME is not set"))?;
-    Ok(PathBuf::from(home).join(".claude"))
+    Ok(PathBuf::from(home).join(".claw"))
 }
 
 fn read_credentials_root(path: &PathBuf) -> io::Result<Map<String, Value>> {
@@ -541,7 +541,7 @@ mod tests {
     fn oauth_credentials_round_trip_and_clear_preserves_other_fields() {
         let _guard = env_lock();
         let config_home = temp_config_home();
-        std::env::set_var("CLAUDE_CONFIG_HOME", &config_home);
+        std::env::set_var("CLAW_CONFIG_HOME", &config_home);
         let path = credentials_path().expect("credentials path");
         std::fs::create_dir_all(path.parent().expect("parent")).expect("create parent");
         std::fs::write(&path, "{\"other\":\"value\"}\n").expect("seed credentials");
@@ -567,7 +567,7 @@ mod tests {
         assert!(cleared.contains("\"other\": \"value\""));
         assert!(!cleared.contains("\"oauth\""));
 
-        std::env::remove_var("CLAUDE_CONFIG_HOME");
+        std::env::remove_var("CLAW_CONFIG_HOME");
         std::fs::remove_dir_all(config_home).expect("cleanup temp dir");
     }
 

+ 40 - 37
rust/crates/runtime/src/prompt.rs

@@ -201,10 +201,10 @@ fn discover_instruction_files(cwd: &Path) -> std::io::Result<Vec<ContextFile>> {
     let mut files = Vec::new();
     for dir in directories {
         for candidate in [
-            dir.join("CLAUDE.md"),
-            dir.join("CLAUDE.local.md"),
-            dir.join(".claude").join("CLAUDE.md"),
-            dir.join(".claude").join("instructions.md"),
+            dir.join("INSTRUCTIONS.md"),
+            dir.join("INSTRUCTIONS.local.md"),
+            dir.join(".claw").join("INSTRUCTIONS.md"),
+            dir.join(".claw").join("instructions.md"),
         ] {
             push_context_file(&mut files, candidate)?;
         }
@@ -301,7 +301,7 @@ fn render_project_context(project_context: &ProjectContext) -> String {
 }
 
 fn render_instruction_files(files: &[ContextFile]) -> String {
-    let mut sections = vec!["# Claude instructions".to_string()];
+    let mut sections = vec!["# Project instructions".to_string()];
     let mut remaining_chars = MAX_TOTAL_INSTRUCTION_CHARS;
     for file in files {
         if remaining_chars == 0 {
@@ -517,23 +517,23 @@ mod tests {
     fn discovers_instruction_files_from_ancestor_chain() {
         let root = temp_dir();
         let nested = root.join("apps").join("api");
-        fs::create_dir_all(nested.join(".claude")).expect("nested claude dir");
-        fs::write(root.join("CLAUDE.md"), "root instructions").expect("write root instructions");
-        fs::write(root.join("CLAUDE.local.md"), "local instructions")
+        fs::create_dir_all(nested.join(".claw")).expect("nested claude dir");
+        fs::write(root.join("INSTRUCTIONS.md"), "root instructions").expect("write root instructions");
+        fs::write(root.join("INSTRUCTIONS.local.md"), "local instructions")
             .expect("write local instructions");
         fs::create_dir_all(root.join("apps")).expect("apps dir");
-        fs::create_dir_all(root.join("apps").join(".claude")).expect("apps claude dir");
-        fs::write(root.join("apps").join("CLAUDE.md"), "apps instructions")
+        fs::create_dir_all(root.join("apps").join(".claw")).expect("apps claude dir");
+        fs::write(root.join("apps").join("INSTRUCTIONS.md"), "apps instructions")
             .expect("write apps instructions");
         fs::write(
-            root.join("apps").join(".claude").join("instructions.md"),
+            root.join("apps").join(".claw").join("instructions.md"),
             "apps dot claude instructions",
         )
         .expect("write apps dot claude instructions");
-        fs::write(nested.join(".claude").join("CLAUDE.md"), "nested rules")
+        fs::write(nested.join(".claw").join("INSTRUCTIONS.md"), "nested rules")
             .expect("write nested rules");
         fs::write(
-            nested.join(".claude").join("instructions.md"),
+            nested.join(".claw").join("instructions.md"),
             "nested instructions",
         )
         .expect("write nested instructions");
@@ -552,7 +552,7 @@ mod tests {
                 "local instructions",
                 "apps instructions",
                 "apps dot claude instructions",
-                "nested rules",
+                
                 "nested instructions"
             ]
         );
@@ -564,8 +564,8 @@ mod tests {
         let root = temp_dir();
         let nested = root.join("apps").join("api");
         fs::create_dir_all(&nested).expect("nested dir");
-        fs::write(root.join("CLAUDE.md"), "same rules\n\n").expect("write root");
-        fs::write(nested.join("CLAUDE.md"), "same rules\n").expect("write nested");
+        fs::write(root.join("INSTRUCTIONS.md"), "same rules\n\n").expect("write root");
+        fs::write(nested.join("INSTRUCTIONS.md"), "same rules\n").expect("write nested");
 
         let context = ProjectContext::discover(&nested, "2026-03-31").expect("context should load");
         assert_eq!(context.instruction_files.len(), 1);
@@ -593,8 +593,8 @@ mod tests {
     #[test]
     fn displays_context_paths_compactly() {
         assert_eq!(
-            display_context_path(Path::new("/tmp/project/.claude/CLAUDE.md")),
-            "CLAUDE.md"
+            display_context_path(Path::new("/tmp/project/.claw/INSTRUCTIONS.md")),
+            "INSTRUCTIONS.md"
         );
     }
 
@@ -607,7 +607,7 @@ mod tests {
             .current_dir(&root)
             .status()
             .expect("git init should run");
-        fs::write(root.join("CLAUDE.md"), "rules").expect("write instructions");
+        fs::write(root.join("INSTRUCTIONS.md"), "rules").expect("write instructions");
         fs::write(root.join("tracked.txt"), "hello").expect("write tracked file");
 
         let context =
@@ -615,7 +615,7 @@ mod tests {
 
         let status = context.git_status.expect("git status should be present");
         assert!(status.contains("## No commits yet on") || status.contains("## "));
-        assert!(status.contains("?? CLAUDE.md"));
+        assert!(status.contains("?? INSTRUCTIONS.md"));
         assert!(status.contains("?? tracked.txt"));
         assert!(context.git_diff.is_none());
 
@@ -667,10 +667,10 @@ mod tests {
     #[test]
     fn load_system_prompt_reads_claude_files_and_config() {
         let root = temp_dir();
-        fs::create_dir_all(root.join(".claude")).expect("claude dir");
-        fs::write(root.join("CLAUDE.md"), "Project rules").expect("write instructions");
+        fs::create_dir_all(root.join(".claw")).expect("claude dir");
+        fs::write(root.join("INSTRUCTIONS.md"), "Project rules").expect("write instructions");
         fs::write(
-            root.join(".claude").join("settings.json"),
+            root.join(".claw").join("settings.json"),
             r#"{"permissionMode":"acceptEdits"}"#,
         )
         .expect("write settings");
@@ -678,9 +678,9 @@ mod tests {
         let _guard = env_lock();
         let previous = std::env::current_dir().expect("cwd");
         let original_home = std::env::var("HOME").ok();
-        let original_claude_home = std::env::var("CLAUDE_CONFIG_HOME").ok();
+        let original_config_home = std::env::var("CLAW_CONFIG_HOME").ok();
         std::env::set_var("HOME", &root);
-        std::env::set_var("CLAUDE_CONFIG_HOME", root.join("missing-home"));
+        std::env::set_var("CLAW_CONFIG_HOME", root.join("missing-home"));
         std::env::set_current_dir(&root).expect("change cwd");
         let prompt = super::load_system_prompt(&root, "2026-03-31", "linux", "6.8")
             .expect("system prompt should load")
@@ -695,10 +695,10 @@ mod tests {
         } else {
             std::env::remove_var("HOME");
         }
-        if let Some(value) = original_claude_home {
-            std::env::set_var("CLAUDE_CONFIG_HOME", value);
+        if let Some(value) = original_config_home {
+            std::env::set_var("CLAW_CONFIG_HOME", value);
         } else {
-            std::env::remove_var("CLAUDE_CONFIG_HOME");
+            std::env::remove_var("CLAW_CONFIG_HOME");
         }
 
         assert!(prompt.contains("Project rules"));
@@ -709,10 +709,10 @@ mod tests {
     #[test]
     fn renders_claude_code_style_sections_with_project_context() {
         let root = temp_dir();
-        fs::create_dir_all(root.join(".claude")).expect("claude dir");
-        fs::write(root.join("CLAUDE.md"), "Project rules").expect("write CLAUDE.md");
+        fs::create_dir_all(root.join(".claw")).expect("claude dir");
+        fs::write(root.join("INSTRUCTIONS.md"), "Project rules").expect("write INSTRUCTIONS.md");
         fs::write(
-            root.join(".claude").join("settings.json"),
+            root.join(".claw").join("settings.json"),
             r#"{"permissionMode":"acceptEdits"}"#,
         )
         .expect("write settings");
@@ -731,7 +731,7 @@ mod tests {
 
         assert!(prompt.contains("# System"));
         assert!(prompt.contains("# Project context"));
-        assert!(prompt.contains("# Claude instructions"));
+        assert!(prompt.contains("# Project instructions"));
         assert!(prompt.contains("Project rules"));
         assert!(prompt.contains("permissionMode"));
         assert!(prompt.contains(SYSTEM_PROMPT_DYNAMIC_BOUNDARY));
@@ -751,9 +751,9 @@ mod tests {
     fn discovers_dot_claude_instructions_markdown() {
         let root = temp_dir();
         let nested = root.join("apps").join("api");
-        fs::create_dir_all(nested.join(".claude")).expect("nested claude dir");
+        fs::create_dir_all(nested.join(".claw")).expect("nested claude dir");
         fs::write(
-            nested.join(".claude").join("instructions.md"),
+            nested.join(".claw").join("instructions.md"),
             "instruction markdown",
         )
         .expect("write instructions.md");
@@ -762,7 +762,10 @@ mod tests {
         assert!(context
             .instruction_files
             .iter()
-            .any(|file| file.path.ends_with(".claude/instructions.md")));
+            .any(|file| {
+                let p = file.path.to_string_lossy().to_lowercase();
+                p.ends_with(".claw/instructions.md")
+            }));
         assert!(
             render_instruction_files(&context.instruction_files).contains("instruction markdown")
         );
@@ -773,10 +776,10 @@ mod tests {
     #[test]
     fn renders_instruction_file_metadata() {
         let rendered = render_instruction_files(&[ContextFile {
-            path: PathBuf::from("/tmp/project/CLAUDE.md"),
+            path: PathBuf::from("/tmp/project/INSTRUCTIONS.md"),
             content: "Project rules".to_string(),
         }]);
-        assert!(rendered.contains("# Claude instructions"));
+        assert!(rendered.contains("# Project instructions"));
         assert!(rendered.contains("scope: /tmp/project"));
         assert!(rendered.contains("Project rules"));
     }

+ 5 - 5
rust/crates/rusty-claude-cli/src/args.rs

@@ -4,7 +4,7 @@ use clap::{Parser, Subcommand, ValueEnum};
 
 #[derive(Debug, Clone, Parser, PartialEq, Eq)]
 #[command(
-    name = "rusty-claude-cli",
+    name = "claw-cli",
     version,
     about = "Rust Claude CLI prototype"
 )]
@@ -62,7 +62,7 @@ mod tests {
     #[test]
     fn parses_requested_flags() {
         let cli = Cli::parse_from([
-            "rusty-claude-cli",
+            "claw-cli",
             "--model",
             "claude-3-5-haiku",
             "--permission-mode",
@@ -93,16 +93,16 @@ mod tests {
 
     #[test]
     fn parses_login_and_logout_commands() {
-        let login = Cli::parse_from(["rusty-claude-cli", "login"]);
+        let login = Cli::parse_from(["claw-cli", "login"]);
         assert_eq!(login.command, Some(Command::Login));
 
-        let logout = Cli::parse_from(["rusty-claude-cli", "logout"]);
+        let logout = Cli::parse_from(["claw-cli", "logout"]);
         assert_eq!(logout.command, Some(Command::Logout));
     }
 
     #[test]
     fn defaults_to_danger_full_access_permission_mode() {
-        let cli = Cli::parse_from(["rusty-claude-cli"]);
+        let cli = Cli::parse_from(["claw-cli"]);
         assert_eq!(cli.permission_mode, PermissionMode::DangerFullAccess);
     }
 }

+ 46 - 43
rust/crates/rusty-claude-cli/src/init.rs

@@ -1,15 +1,15 @@
 use std::fs;
 use std::path::{Path, PathBuf};
 
-const STARTER_CLAUDE_JSON: &str = concat!(
+const STARTER_CLAW_JSON: &str = concat!(
     "{\n",
     "  \"permissions\": {\n",
     "    \"defaultMode\": \"dontAsk\"\n",
     "  }\n",
     "}\n",
 );
-const GITIGNORE_COMMENT: &str = "# Claude Code local artifacts";
-const GITIGNORE_ENTRIES: [&str; 2] = [".claude/settings.local.json", ".claude/sessions/"];
+const GITIGNORE_COMMENT: &str = "# Claw Code local artifacts";
+const GITIGNORE_ENTRIES: [&str; 2] = [".claw/settings.local.json", ".claw/sessions/"];
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
 pub(crate) enum InitStatus {
@@ -80,16 +80,16 @@ struct RepoDetection {
 pub(crate) fn initialize_repo(cwd: &Path) -> Result<InitReport, Box<dyn std::error::Error>> {
     let mut artifacts = Vec::new();
 
-    let claude_dir = cwd.join(".claude");
+    let claw_dir = cwd.join(".claw");
     artifacts.push(InitArtifact {
-        name: ".claude/",
-        status: ensure_dir(&claude_dir)?,
+        name: ".claw/",
+        status: ensure_dir(&claw_dir)?,
     });
 
-    let claude_json = cwd.join(".claude.json");
+    let claw_json = cwd.join(".claw.json");
     artifacts.push(InitArtifact {
-        name: ".claude.json",
-        status: write_file_if_missing(&claude_json, STARTER_CLAUDE_JSON)?,
+        name: ".claw.json",
+        status: write_file_if_missing(&claw_json, STARTER_CLAW_JSON)?,
     });
 
     let gitignore = cwd.join(".gitignore");
@@ -98,11 +98,11 @@ pub(crate) fn initialize_repo(cwd: &Path) -> Result<InitReport, Box<dyn std::err
         status: ensure_gitignore_entries(&gitignore)?,
     });
 
-    let claude_md = cwd.join("CLAUDE.md");
-    let content = render_init_claude_md(cwd);
+    let instructions_md = cwd.join("INSTRUCTIONS.md");
+    let content = render_init_instructions_md(cwd);
     artifacts.push(InitArtifact {
-        name: "CLAUDE.md",
-        status: write_file_if_missing(&claude_md, &content)?,
+        name: "INSTRUCTIONS.md",
+        status: write_file_if_missing(&instructions_md, &content)?,
     });
 
     Ok(InitReport {
@@ -159,12 +159,13 @@ fn ensure_gitignore_entries(path: &Path) -> Result<InitStatus, std::io::Error> {
     Ok(InitStatus::Updated)
 }
 
-pub(crate) fn render_init_claude_md(cwd: &Path) -> String {
+pub(crate) fn render_init_instructions_md(cwd: &Path) -> String {
     let detection = detect_repo(cwd);
     let mut lines = vec![
-        "# CLAUDE.md".to_string(),
+        "# INSTRUCTIONS.md".to_string(),
         String::new(),
-        "This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.".to_string(),
+        "This file provides guidance to Claw Code when working with code in this repository."
+            .to_string(),
         String::new(),
     ];
 
@@ -209,8 +210,8 @@ pub(crate) fn render_init_claude_md(cwd: &Path) -> String {
 
     lines.push("## Working agreement".to_string());
     lines.push("- Prefer small, reviewable changes and keep generated bootstrap files aligned with actual repo workflows.".to_string());
-    lines.push("- Keep shared defaults in `.claude.json`; reserve `.claude/settings.local.json` for machine-local overrides.".to_string());
-    lines.push("- Do not overwrite existing `CLAUDE.md` content automatically; update it intentionally when repo workflows change.".to_string());
+    lines.push("- Keep shared defaults in `.claw.json`; reserve `.claw/settings.local.json` for machine-local overrides.".to_string());
+    lines.push("- Do not overwrite existing `INSTRUCTIONS.md` content automatically; update it intentionally when repo workflows change.".to_string());
     lines.push(String::new());
 
     lines.join("\n")
@@ -333,7 +334,7 @@ fn framework_notes(detection: &RepoDetection) -> Vec<String> {
 
 #[cfg(test)]
 mod tests {
-    use super::{initialize_repo, render_init_claude_md};
+    use super::{initialize_repo, render_init_instructions_md};
     use std::fs;
     use std::path::Path;
     use std::time::{SystemTime, UNIX_EPOCH};
@@ -343,7 +344,7 @@ mod tests {
             .duration_since(UNIX_EPOCH)
             .expect("time should be after epoch")
             .as_nanos();
-        std::env::temp_dir().join(format!("rusty-claude-init-{nanos}"))
+        std::env::temp_dir().join(format!("rusty-claw-init-{nanos}"))
     }
 
     #[test]
@@ -354,15 +355,15 @@ mod tests {
 
         let report = initialize_repo(&root).expect("init should succeed");
         let rendered = report.render();
-        assert!(rendered.contains(".claude/         created"));
-        assert!(rendered.contains(".claude.json     created"));
+        assert!(rendered.contains(".claw/           created"));
+        assert!(rendered.contains(".claw.json       created"));
         assert!(rendered.contains(".gitignore       created"));
-        assert!(rendered.contains("CLAUDE.md        created"));
-        assert!(root.join(".claude").is_dir());
-        assert!(root.join(".claude.json").is_file());
-        assert!(root.join("CLAUDE.md").is_file());
+        assert!(rendered.contains("INSTRUCTIONS.md  created"));
+        assert!(root.join(".claw").is_dir());
+        assert!(root.join(".claw.json").is_file());
+        assert!(root.join("INSTRUCTIONS.md").is_file());
         assert_eq!(
-            fs::read_to_string(root.join(".claude.json")).expect("read claude json"),
+            fs::read_to_string(root.join(".claw.json")).expect("read claw json"),
             concat!(
                 "{\n",
                 "  \"permissions\": {\n",
@@ -372,11 +373,12 @@ mod tests {
             )
         );
         let gitignore = fs::read_to_string(root.join(".gitignore")).expect("read gitignore");
-        assert!(gitignore.contains(".claude/settings.local.json"));
-        assert!(gitignore.contains(".claude/sessions/"));
-        let claude_md = fs::read_to_string(root.join("CLAUDE.md")).expect("read claude md");
-        assert!(claude_md.contains("Languages: Rust."));
-        assert!(claude_md.contains("cargo clippy --workspace --all-targets -- -D warnings"));
+        assert!(gitignore.contains(".claw/settings.local.json"));
+        assert!(gitignore.contains(".claw/sessions/"));
+        let instructions_md =
+            fs::read_to_string(root.join("INSTRUCTIONS.md")).expect("read instructions md");
+        assert!(instructions_md.contains("Languages: Rust."));
+        assert!(instructions_md.contains("cargo clippy --workspace --all-targets -- -D warnings"));
 
         fs::remove_dir_all(root).expect("cleanup temp dir");
     }
@@ -385,27 +387,28 @@ mod tests {
     fn initialize_repo_is_idempotent_and_preserves_existing_files() {
         let root = temp_dir();
         fs::create_dir_all(&root).expect("create root");
-        fs::write(root.join("CLAUDE.md"), "custom guidance\n").expect("write existing claude md");
-        fs::write(root.join(".gitignore"), ".claude/settings.local.json\n")
-            .expect("write gitignore");
+        fs::write(root.join("INSTRUCTIONS.md"), "custom guidance\n")
+            .expect("write existing instructions md");
+        fs::write(root.join(".gitignore"), ".claw/settings.local.json\n").expect("write gitignore");
 
         let first = initialize_repo(&root).expect("first init should succeed");
         assert!(first
             .render()
-            .contains("CLAUDE.md        skipped (already exists)"));
+            .contains("INSTRUCTIONS.md  skipped (already exists)"));
         let second = initialize_repo(&root).expect("second init should succeed");
         let second_rendered = second.render();
-        assert!(second_rendered.contains(".claude/         skipped (already exists)"));
-        assert!(second_rendered.contains(".claude.json     skipped (already exists)"));
+        assert!(second_rendered.contains(".claw/           skipped (already exists)"));
+        assert!(second_rendered.contains(".claw.json       skipped (already exists)"));
         assert!(second_rendered.contains(".gitignore       skipped (already exists)"));
-        assert!(second_rendered.contains("CLAUDE.md        skipped (already exists)"));
+        assert!(second_rendered.contains("INSTRUCTIONS.md  skipped (already exists)"));
         assert_eq!(
-            fs::read_to_string(root.join("CLAUDE.md")).expect("read existing claude md"),
+            fs::read_to_string(root.join("INSTRUCTIONS.md"))
+                .expect("read existing instructions md"),
             "custom guidance\n"
         );
         let gitignore = fs::read_to_string(root.join(".gitignore")).expect("read gitignore");
-        assert_eq!(gitignore.matches(".claude/settings.local.json").count(), 1);
-        assert_eq!(gitignore.matches(".claude/sessions/").count(), 1);
+        assert_eq!(gitignore.matches(".claw/settings.local.json").count(), 1);
+        assert_eq!(gitignore.matches(".claw/sessions/").count(), 1);
 
         fs::remove_dir_all(root).expect("cleanup temp dir");
     }
@@ -422,7 +425,7 @@ mod tests {
         )
         .expect("write package json");
 
-        let rendered = render_init_claude_md(Path::new(&root));
+        let rendered = render_init_instructions_md(Path::new(&root));
         assert!(rendered.contains("Languages: Python, TypeScript."));
         assert!(rendered.contains("Frameworks/tooling markers: Next.js, React."));
         assert!(rendered.contains("pyproject.toml"));

+ 15 - 15
rust/crates/rusty-claude-cli/src/main.rs

@@ -14,7 +14,7 @@ use std::thread::{self, JoinHandle};
 use std::time::{SystemTime, UNIX_EPOCH};
 
 use api::{
-    resolve_startup_auth_source, AnthropicClient, AuthSource, ContentBlockDelta, InputContentBlock,
+    resolve_startup_auth_source, ApiClient as ApiHttpClient, AuthSource, ContentBlockDelta, InputContentBlock,
     InputMessage, MessageRequest, MessageResponse, OutputContentBlock,
     StreamEvent as ApiStreamEvent, ToolChoice, ToolDefinition, ToolResultContentBlock,
 };
@@ -444,7 +444,7 @@ fn dump_manifests() {
 }
 
 fn print_bootstrap_plan() {
-    for phase in runtime::BootstrapPlan::claude_code_default().phases() {
+    for phase in runtime::BootstrapPlan::default_bootstrap().phases() {
         println!("- {phase:?}");
     }
 }
@@ -501,7 +501,7 @@ fn run_login() -> Result<(), Box<dyn std::error::Error>> {
         return Err(io::Error::new(io::ErrorKind::InvalidData, "oauth state mismatch").into());
     }
 
-    let client = AnthropicClient::from_auth(AuthSource::None).with_base_url(api::read_base_url());
+    let client = ApiHttpClient::from_auth(AuthSource::None).with_base_url(api::read_base_url());
     let exchange_request =
         OAuthTokenExchangeRequest::from_config(oauth, code, state, pkce.verifier, redirect_uri);
     let runtime = tokio::runtime::Runtime::new()?;
@@ -982,7 +982,7 @@ struct LiveCli {
     allowed_tools: Option<AllowedToolSet>,
     permission_mode: PermissionMode,
     system_prompt: Vec<String>,
-    runtime: ConversationRuntime<AnthropicRuntimeClient, CliToolExecutor>,
+    runtime: ConversationRuntime<ClawRuntimeClient, CliToolExecutor>,
     session: SessionHandle,
 }
 
@@ -1101,7 +1101,7 @@ impl LiveCli {
         emit_output: bool,
     ) -> Result<
         (
-            ConversationRuntime<AnthropicRuntimeClient, CliToolExecutor>,
+            ConversationRuntime<ClawRuntimeClient, CliToolExecutor>,
             HookAbortMonitor,
         ),
         Box<dyn std::error::Error>,
@@ -1531,7 +1531,7 @@ impl LiveCli {
 
 fn sessions_dir() -> Result<PathBuf, Box<dyn std::error::Error>> {
     let cwd = env::current_dir()?;
-    let path = cwd.join(".claude").join("sessions");
+    let path = cwd.join(".claw").join("sessions");
     fs::create_dir_all(&path)?;
     Ok(path)
 }
@@ -1999,12 +1999,12 @@ fn build_runtime(
     emit_output: bool,
     allowed_tools: Option<AllowedToolSet>,
     permission_mode: PermissionMode,
-) -> Result<ConversationRuntime<AnthropicRuntimeClient, CliToolExecutor>, Box<dyn std::error::Error>>
+) -> Result<ConversationRuntime<ClawRuntimeClient, CliToolExecutor>, Box<dyn std::error::Error>>
 {
     let feature_config = build_runtime_feature_config()?;
     let mut runtime = ConversationRuntime::new_with_features(
         session,
-        AnthropicRuntimeClient::new(model, enable_tools, emit_output, allowed_tools.clone())?,
+        ClawRuntimeClient::new(model, enable_tools, emit_output, allowed_tools.clone())?,
         CliToolExecutor::new(allowed_tools, emit_output),
         permission_policy(permission_mode, &feature_config),
         system_prompt,
@@ -2098,16 +2098,16 @@ impl runtime::PermissionPrompter for CliPermissionPrompter {
     }
 }
 
-struct AnthropicRuntimeClient {
+struct ClawRuntimeClient {
     runtime: tokio::runtime::Runtime,
-    client: AnthropicClient,
+    client: ApiHttpClient,
     model: String,
     enable_tools: bool,
     emit_output: bool,
     allowed_tools: Option<AllowedToolSet>,
 }
 
-impl AnthropicRuntimeClient {
+impl ClawRuntimeClient {
     fn new(
         model: String,
         enable_tools: bool,
@@ -2116,7 +2116,7 @@ impl AnthropicRuntimeClient {
     ) -> Result<Self, Box<dyn std::error::Error>> {
         Ok(Self {
             runtime: tokio::runtime::Runtime::new()?,
-            client: AnthropicClient::from_auth(resolve_cli_auth_source()?)
+            client: ApiHttpClient::from_auth(resolve_cli_auth_source()?)
                 .with_base_url(api::read_base_url()),
             model,
             enable_tools,
@@ -2136,7 +2136,7 @@ fn resolve_cli_auth_source() -> Result<AuthSource, Box<dyn std::error::Error>> {
     })?)
 }
 
-impl ApiClient for AnthropicRuntimeClient {
+impl ApiClient for ClawRuntimeClient {
     #[allow(clippy::too_many_lines)]
     fn stream(&mut self, request: ApiRequest) -> Result<Vec<AssistantEvent>, RuntimeError> {
         let message_request = MessageRequest {
@@ -3448,8 +3448,8 @@ mod tests {
 
     #[test]
     fn init_template_mentions_detected_rust_workspace() {
-        let rendered = crate::init::render_init_claude_md(std::path::Path::new("."));
-        assert!(rendered.contains("# CLAUDE.md"));
+        let rendered = crate::init::render_init_instructions_md(std::path::Path::new("."));
+        assert!(rendered.contains("# INSTRUCTIONS.md"));
         assert!(rendered.contains("cargo clippy --workspace --all-targets -- -D warnings"));
     }
 

+ 27 - 21
rust/crates/tools/src/lib.rs

@@ -4,7 +4,7 @@ use std::process::Command;
 use std::time::{Duration, Instant};
 
 use api::{
-    read_base_url, AnthropicClient, ContentBlockDelta, InputContentBlock, InputMessage,
+    read_base_url, ApiClient as ApiHttpClient, ContentBlockDelta, InputContentBlock, InputMessage,
     MessageRequest, MessageResponse, OutputContentBlock, StreamEvent as ApiStreamEvent, ToolChoice,
     ToolDefinition, ToolResultContentBlock,
 };
@@ -1308,6 +1308,12 @@ fn resolve_skill_path(skill: &str) -> Result<std::path::PathBuf, String> {
     if let Ok(codex_home) = std::env::var("CODEX_HOME") {
         candidates.push(std::path::PathBuf::from(codex_home).join("skills"));
     }
+    if let Ok(home) = std::env::var("HOME") {
+        let home = std::path::PathBuf::from(home);
+        candidates.push(home.join(".agents").join("skills"));
+        candidates.push(home.join(".config").join("opencode").join("skills"));
+        candidates.push(home.join(".codex").join("skills"));
+    }
     candidates.push(std::path::PathBuf::from("/home/bellman/.codex/skills"));
 
     for root in candidates {
@@ -1459,14 +1465,14 @@ fn run_agent_job(job: &AgentJob) -> Result<(), String> {
 
 fn build_agent_runtime(
     job: &AgentJob,
-) -> Result<ConversationRuntime<AnthropicRuntimeClient, SubagentToolExecutor>, String> {
+) -> Result<ConversationRuntime<RuntimeApiClient, SubagentToolExecutor>, String> {
     let model = job
         .manifest
         .model
         .clone()
         .unwrap_or_else(|| DEFAULT_AGENT_MODEL.to_string());
     let allowed_tools = job.allowed_tools.clone();
-    let api_client = AnthropicRuntimeClient::new(model, allowed_tools.clone())?;
+    let api_client = RuntimeApiClient::new(model, allowed_tools.clone())?;
     let tool_executor = SubagentToolExecutor::new(allowed_tools);
     Ok(ConversationRuntime::new(
         Session::new(),
@@ -1537,7 +1543,7 @@ fn allowed_tools_for_subagent(subagent_type: &str) -> BTreeSet<String> {
             "SendUserMessage",
             "PowerShell",
         ],
-        "claude-code-guide" => vec![
+        "claw-guide" => vec![
             "read_file",
             "glob_search",
             "grep_search",
@@ -1635,16 +1641,16 @@ fn format_agent_terminal_output(status: &str, result: Option<&str>, error: Optio
     sections.join("")
 }
 
-struct AnthropicRuntimeClient {
+struct RuntimeApiClient {
     runtime: tokio::runtime::Runtime,
-    client: AnthropicClient,
+    client: ApiHttpClient,
     model: String,
     allowed_tools: BTreeSet<String>,
 }
 
-impl AnthropicRuntimeClient {
+impl RuntimeApiClient {
     fn new(model: String, allowed_tools: BTreeSet<String>) -> Result<Self, String> {
-        let client = AnthropicClient::from_env()
+        let client = ApiHttpClient::from_env()
             .map_err(|error| error.to_string())?
             .with_base_url(read_base_url());
         Ok(Self {
@@ -1656,7 +1662,7 @@ impl AnthropicRuntimeClient {
     }
 }
 
-impl ApiClient for AnthropicRuntimeClient {
+impl ApiClient for RuntimeApiClient {
     fn stream(&mut self, request: ApiRequest) -> Result<Vec<AssistantEvent>, RuntimeError> {
         let tools = tool_specs_for_allowed_tools(Some(&self.allowed_tools))
             .into_iter()
@@ -2087,7 +2093,7 @@ fn normalize_subagent_type(subagent_type: Option<&str>) -> String {
         "verification" | "verificationagent" | "verify" | "verifier" => {
             String::from("Verification")
         }
-        "claudecodeguide" | "claudecodeguideagent" | "guide" => String::from("claude-code-guide"),
+        "clawguide" | "clawguideagent" | "guide" => String::from("claw-guide"),
         "statusline" | "statuslinesetup" => String::from("statusline-setup"),
         _ => trimmed.to_string(),
     }
@@ -2587,16 +2593,16 @@ fn config_file_for_scope(scope: ConfigScope) -> Result<PathBuf, String> {
     let cwd = std::env::current_dir().map_err(|error| error.to_string())?;
     Ok(match scope {
         ConfigScope::Global => config_home_dir()?.join("settings.json"),
-        ConfigScope::Settings => cwd.join(".claude").join("settings.local.json"),
+        ConfigScope::Settings => cwd.join(".claw").join("settings.local.json"),
     })
 }
 
 fn config_home_dir() -> Result<PathBuf, String> {
-    if let Ok(path) = std::env::var("CLAUDE_CONFIG_HOME") {
+    if let Ok(path) = std::env::var("CLAW_CONFIG_HOME") {
         return Ok(PathBuf::from(path));
     }
     let home = std::env::var("HOME").map_err(|_| String::from("HOME is not set"))?;
-    Ok(PathBuf::from(home).join(".claude"))
+    Ok(PathBuf::from(home).join(".claw"))
 }
 
 fn read_json_object(path: &Path) -> Result<serde_json::Map<String, Value>, String> {
@@ -3982,19 +3988,19 @@ mod tests {
         ));
         let home = root.join("home");
         let cwd = root.join("cwd");
-        std::fs::create_dir_all(home.join(".claude")).expect("home dir");
-        std::fs::create_dir_all(cwd.join(".claude")).expect("cwd dir");
+        std::fs::create_dir_all(home.join(".claw")).expect("home dir");
+        std::fs::create_dir_all(cwd.join(".claw")).expect("cwd dir");
         std::fs::write(
-            home.join(".claude").join("settings.json"),
+            home.join(".claw").join("settings.json"),
             r#"{"verbose":false}"#,
         )
         .expect("write global settings");
 
         let original_home = std::env::var("HOME").ok();
-        let original_claude_home = std::env::var("CLAUDE_CONFIG_HOME").ok();
+        let original_config_home = std::env::var("CLAW_CONFIG_HOME").ok();
         let original_dir = std::env::current_dir().expect("cwd");
         std::env::set_var("HOME", &home);
-        std::env::remove_var("CLAUDE_CONFIG_HOME");
+        std::env::remove_var("CLAW_CONFIG_HOME");
         std::env::set_current_dir(&cwd).expect("set cwd");
 
         let get = execute_tool("Config", &json!({"setting": "verbose"})).expect("get config");
@@ -4027,9 +4033,9 @@ mod tests {
             Some(value) => std::env::set_var("HOME", value),
             None => std::env::remove_var("HOME"),
         }
-        match original_claude_home {
-            Some(value) => std::env::set_var("CLAUDE_CONFIG_HOME", value),
-            None => std::env::remove_var("CLAUDE_CONFIG_HOME"),
+        match original_config_home {
+            Some(value) => std::env::set_var("CLAW_CONFIG_HOME", value),
+            None => std::env::remove_var("CLAW_CONFIG_HOME"),
         }
         let _ = std::fs::remove_dir_all(root);
     }