Skip to main content

tracevault_cli/hooks/
mod.rs

1use std::path::Path;
2use tracevault_core::streaming::StreamEventRequest;
3
4// Adapter modules contain stubs for future stream command integration.
5#[allow(dead_code)]
6pub mod claude_code;
7#[allow(dead_code)]
8pub mod cursor;
9
10#[allow(dead_code)]
11pub trait HookAdapter: Send + Sync {
12    fn tool_name(&self) -> &str;
13    fn parse_event(&self, raw: &str) -> Result<StreamEventRequest, String>;
14    fn parse_transcript(&self, path: &Path) -> Result<Vec<serde_json::Value>, String>;
15}
16
17#[derive(Debug, Clone, Copy)]
18pub enum DetectedTool {
19    ClaudeCode,
20    Cursor,
21}
22
23impl DetectedTool {
24    pub fn name(&self) -> &str {
25        match self {
26            DetectedTool::ClaudeCode => "claude-code",
27            DetectedTool::Cursor => "cursor",
28        }
29    }
30
31    #[allow(dead_code)]
32    pub fn adapter(&self) -> Box<dyn HookAdapter> {
33        match self {
34            DetectedTool::ClaudeCode => Box::new(claude_code::ClaudeCodeAdapter),
35            DetectedTool::Cursor => Box::new(cursor::CursorAdapter),
36        }
37    }
38}
39
40pub fn detect_tools(cwd: &Path) -> Vec<DetectedTool> {
41    let mut tools = vec![];
42    if cwd.join(".claude").exists() {
43        tools.push(DetectedTool::ClaudeCode);
44    }
45    if cwd.join(".cursor").exists() {
46        tools.push(DetectedTool::Cursor);
47    }
48    tools
49}