collet 0.1.0

Relentless agentic coding orchestrator with zero-drop agent loops
Documentation
//! Symbol map and tools listing endpoints.

use std::sync::Arc;

use axum::Router;
use axum::extract::State;
use axum::response::Json;
use axum::routing::get;
use serde::Serialize;

use crate::project_cache;

use super::state::AppState;

pub fn router() -> Router<Arc<AppState>> {
    Router::new()
        .route("/api/symbols", get(symbols))
        .route("/api/tools", get(tools))
}

// ── Symbols ──────────────────────────────────────────────────────────────

#[derive(Serialize)]
struct SymbolsResponse {
    map_string: String,
    file_count: usize,
    symbol_count: usize,
}

async fn symbols(State(state): State<Arc<AppState>>) -> Json<SymbolsResponse> {
    let working_dir = state.working_dir().await;

    let (map_string, file_count, symbol_count) = tokio::task::spawn_blocking({
        let dir = working_dir.clone();
        move || {
            let snap = project_cache::snapshot(&dir);
            (snap.map_string, snap.file_count, snap.symbol_count)
        }
    })
    .await
    .unwrap_or_else(|_| (String::new(), 0, 0));

    Json(SymbolsResponse {
        map_string,
        file_count,
        symbol_count,
    })
}

// ── Tools ────────────────────────────────────────────────────────────────

#[derive(Serialize)]
struct ToolsResponse {
    tools: Vec<&'static str>,
}

async fn tools() -> Json<ToolsResponse> {
    Json(ToolsResponse {
        tools: vec![
            "bash",
            "file_read",
            "file_write",
            "git_patch",
            "search",
            "skill",
            "subagent",
        ],
    })
}