acp/sync/adapters/
claude_code.rs1use std::path::Path;
4
5use crate::error::Result;
6use crate::sync::adapter::{BootstrapContext, DetectionResult, ToolAdapter};
7use crate::sync::content::generate_bootstrap_markdown;
8use crate::sync::tool::Tool;
9
10pub struct ClaudeCodeAdapter;
12
13impl ToolAdapter for ClaudeCodeAdapter {
14 fn tool(&self) -> Tool {
15 Tool::ClaudeCode
16 }
17
18 fn detect(&self, project_root: &Path) -> DetectionResult {
19 let claude_md = project_root.join("CLAUDE.md");
20
21 let claude_in_path = std::process::Command::new("which")
23 .arg("claude")
24 .output()
25 .map(|o| o.status.success())
26 .unwrap_or(false);
27
28 DetectionResult {
29 tool: Tool::ClaudeCode,
30 detected: claude_md.exists() || claude_in_path,
31 reason: if claude_md.exists() {
32 "CLAUDE.md exists".into()
33 } else if claude_in_path {
34 "claude CLI in PATH".into()
35 } else {
36 "Not detected".into()
37 },
38 existing_file: if claude_md.exists() {
39 Some(claude_md)
40 } else {
41 None
42 },
43 }
44 }
45
46 fn generate(&self, _context: &BootstrapContext) -> Result<String> {
47 let mut content = generate_bootstrap_markdown(Tool::ClaudeCode);
48
49 content.push_str("\n## Claude Code Notes\n\n");
51 content.push_str("If MCP is configured, use the `acp_*` tools directly.\n");
52 content.push_str("Otherwise, read `.acp/acp.cache.json` for full codebase context.\n");
53
54 Ok(content)
55 }
56}