claude.rs

 1use language_models::provider::anthropic::AnthropicLanguageModelProvider;
 2use settings::SettingsStore;
 3use std::any::Any;
 4use std::path::Path;
 5use std::rc::Rc;
 6
 7use anyhow::Result;
 8use gpui::{App, AppContext as _, SharedString, Task};
 9
10use crate::{AgentServer, AgentServerDelegate, AllAgentServersSettings};
11use acp_thread::AgentConnection;
12
13#[derive(Clone)]
14pub struct ClaudeCode;
15
16impl ClaudeCode {
17    const BINARY_NAME: &'static str = "claude-code-acp";
18    const PACKAGE_NAME: &'static str = "@zed-industries/claude-code-acp";
19}
20
21impl AgentServer for ClaudeCode {
22    fn telemetry_id(&self) -> &'static str {
23        "claude-code"
24    }
25
26    fn name(&self) -> SharedString {
27        "Claude Code".into()
28    }
29
30    fn logo(&self) -> ui::IconName {
31        ui::IconName::AiClaude
32    }
33
34    fn connect(
35        &self,
36        root_dir: &Path,
37        delegate: AgentServerDelegate,
38        cx: &mut App,
39    ) -> Task<Result<Rc<dyn AgentConnection>>> {
40        let root_dir = root_dir.to_path_buf();
41        let server_name = self.name();
42        let settings = cx.read_global(|settings: &SettingsStore, _| {
43            settings.get::<AllAgentServersSettings>(None).claude.clone()
44        });
45
46        cx.spawn(async move |cx| {
47            let mut command = if let Some(settings) = settings {
48                settings.command
49            } else {
50                cx.update(|cx| {
51                    delegate.get_or_npm_install_builtin_agent(
52                        Self::BINARY_NAME.into(),
53                        Self::PACKAGE_NAME.into(),
54                        format!("node_modules/{}/dist/index.js", Self::PACKAGE_NAME).into(),
55                        true,
56                        None,
57                        cx,
58                    )
59                })?
60                .await?
61            };
62
63            if let Some(api_key) = cx
64                .update(AnthropicLanguageModelProvider::api_key)?
65                .await
66                .ok()
67            {
68                command
69                    .env
70                    .get_or_insert_default()
71                    .insert("ANTHROPIC_API_KEY".to_owned(), api_key.key);
72            }
73
74            crate::acp::connect(server_name, command.clone(), &root_dir, cx).await
75        })
76    }
77
78    fn into_any(self: Rc<Self>) -> Rc<dyn Any> {
79        self
80    }
81}