frigg 0.4.2

Local-first MCP server for code understanding.
Documentation
use serde::{Deserialize, Serialize};
use serde_json::Value;

use crate::mcp::server::FriggMcpServer;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum DeepSearchStepTool {
    ListRepositories,
    ReadFile,
    SearchText,
    SearchSymbol,
    FindReferences,
}

impl DeepSearchStepTool {
    const ALL: [Self; 5] = [
        Self::ListRepositories,
        Self::ReadFile,
        Self::SearchText,
        Self::SearchSymbol,
        Self::FindReferences,
    ];

    fn from_tool_name(tool_name: &str) -> Option<Self> {
        match tool_name {
            "list_repositories" => Some(Self::ListRepositories),
            "read_file" => Some(Self::ReadFile),
            "search_text" => Some(Self::SearchText),
            "search_symbol" => Some(Self::SearchSymbol),
            "find_references" => Some(Self::FindReferences),
            _ => None,
        }
    }

    pub(crate) const fn as_str(self) -> &'static str {
        match self {
            Self::ListRepositories => "list_repositories",
            Self::ReadFile => "read_file",
            Self::SearchText => "search_text",
            Self::SearchSymbol => "search_symbol",
            Self::FindReferences => "find_references",
        }
    }
}

pub(crate) fn allowed_step_tools() -> &'static [&'static str] {
    const ALLOWED_STEP_TOOLS: [&str; 5] = [
        DeepSearchStepTool::ALL[0].as_str(),
        DeepSearchStepTool::ALL[1].as_str(),
        DeepSearchStepTool::ALL[2].as_str(),
        DeepSearchStepTool::ALL[3].as_str(),
        DeepSearchStepTool::ALL[4].as_str(),
    ];
    &ALLOWED_STEP_TOOLS
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct DeepSearchPlaybook {
    pub playbook_id: String,
    pub steps: Vec<DeepSearchPlaybookStep>,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct DeepSearchPlaybookStep {
    pub step_id: String,
    pub tool_name: String,
    #[serde(default)]
    pub params: Value,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct DeepSearchTraceArtifact {
    pub trace_schema: String,
    pub playbook_id: String,
    pub step_count: usize,
    pub steps: Vec<DeepSearchTraceStep>,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct DeepSearchTraceStep {
    pub step_index: usize,
    pub step_id: String,
    pub tool_name: String,
    pub params_json: String,
    pub outcome: DeepSearchTraceOutcome,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(tag = "status", rename_all = "snake_case")]
pub enum DeepSearchTraceOutcome {
    Ok {
        response_json: String,
    },
    Err {
        code: String,
        message: String,
        error_code: Option<String>,
    },
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct DeepSearchReplayCheck {
    pub matches: bool,
    pub diff: Option<String>,
    pub replayed: DeepSearchTraceArtifact,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct DeepSearchCitationPayload {
    pub answer_schema: String,
    pub playbook_id: String,
    pub answer: String,
    pub claims: Vec<DeepSearchClaim>,
    pub citations: Vec<DeepSearchCitation>,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct DeepSearchClaim {
    pub claim_id: String,
    pub text: String,
    pub citation_ids: Vec<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct DeepSearchCitation {
    pub citation_id: String,
    pub tool_call_id: String,
    pub tool_name: String,
    pub repository_id: String,
    pub path: String,
    pub span: DeepSearchFileSpan,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct DeepSearchFileSpan {
    pub start_line: usize,
    pub start_column: usize,
    pub end_line: usize,
    pub end_column: usize,
}

#[derive(Clone)]
pub struct DeepSearchHarness {
    server: FriggMcpServer,
}

#[path = "deep_search/runtime.rs"]
mod runtime;
#[cfg(test)]
#[path = "deep_search/tests.rs"]
mod tests;