pub(super) fn handle_docs_search(
query: &str,
limit: usize,
project_path: &PathBuf,
format: &QueryOutputFormat,
quiet: bool,
) -> anyhow::Result<()> {
let doc_results = run_document_query(query, limit, project_path, quiet)?;
match format {
QueryOutputFormat::Json => {
let json = serde_json::to_string_pretty(&doc_results)
.map_err(|e| anyhow::anyhow!("JSON serialize: {e}"))?;
println!("{json}");
}
_ => {
print_document_results(&doc_results, false);
}
}
Ok(())
}
pub(super) fn emit_docs_section(
query: &str,
limit: usize,
project_path: &PathBuf,
format: &QueryOutputFormat,
quiet: bool,
) -> anyhow::Result<()> {
let doc_results = run_document_query(query, limit, project_path, quiet)?;
if doc_results.is_empty() {
return Ok(());
}
match format {
QueryOutputFormat::Json => {
let json = serde_json::json!({ "documents": doc_results });
println!(
"{}",
serde_json::to_string_pretty(&json)
.map_err(|e| anyhow::anyhow!("JSON serialize: {e}"))?
);
}
_ => {
print_document_results(&doc_results, true);
}
}
Ok(())
}
fn run_document_query(
query: &str,
limit: usize,
project_path: &PathBuf,
quiet: bool,
) -> anyhow::Result<Vec<crate::services::agent_context::DocumentResult>> {
use crate::services::agent_context::document_index::{build_document_index, query_documents};
use crate::services::agent_context::function_index::sqlite_backend::open_db;
let db_path = project_path.join(".pmat").join("context.db");
if !db_path.exists() {
std::fs::create_dir_all(project_path.join(".pmat"))
.map_err(|e| anyhow::anyhow!("Failed to create .pmat dir: {e}"))?;
}
let conn = open_db(&db_path).map_err(|e| anyhow::anyhow!("{e}"))?;
crate::services::agent_context::document_index::create_documents_schema(&conn)
.map_err(|e| anyhow::anyhow!("{e}"))?;
if !quiet {
eprint!("{DIM}Building document index...{RESET}");
}
let build_result =
build_document_index(&conn, project_path).map_err(|e| anyhow::anyhow!("{e}"))?;
if !quiet {
eprintln!(
"\r{DIM}Documents: {} scanned, {} indexed, {} cached{RESET}",
build_result.files_scanned, build_result.files_indexed, build_result.files_skipped
);
for err in &build_result.errors {
eprintln!("{DIM}{YELLOW} warn: {err}{RESET}");
}
}
let results = query_documents(&conn, query, limit).map_err(|e| anyhow::anyhow!("{e}"))?;
Ok(results)
}
pub(super) fn print_document_results(
results: &[crate::services::agent_context::DocumentResult],
show_separator: bool,
) {
if results.is_empty() {
eprintln!("{DIM}No document matches found.{RESET}");
return;
}
if show_separator {
println!("\n{BOLD}-- Document Results --{RESET}\n");
}
for (i, r) in results.iter().enumerate() {
let doc_type_badge = match r.doc_type.as_str() {
"pdf" => format!("{RED}PDF{RESET}"),
"svg" => format!("{GREEN}SVG{RESET}"),
"image" => format!("{YELLOW}IMG{RESET}"),
"markdown" => format!("{CYAN}MD{RESET}"),
"plaintext" => format!("{DIM}TXT{RESET}"),
other => other.to_string(),
};
let location = if let Some(page) = r.page_number {
format!(" p.{page}")
} else if let Some(ref heading) = r.section_heading {
format!(" \u{00a7} {heading}")
} else {
String::new()
};
let quality_bar = if r.extraction_quality >= 0.8 {
format!("{GREEN}\u{25cf}{RESET}")
} else if r.extraction_quality >= 0.5 {
format!("{YELLOW}\u{25cf}{RESET}")
} else {
format!("{RED}\u{25cb}{RESET}")
};
println!(
"{DIM}{:>3}.{RESET} [{doc_type_badge}] {quality_bar} {BOLD}{}{RESET}{DIM}{location}{RESET}",
i + 1,
r.file_path,
);
let snippet = if r.snippet.len() > 200 {
format!("{}...", &r.snippet[..200])
} else {
r.snippet.clone()
};
println!(" {DIM}{snippet}{RESET}");
}
println!(
"\n{DIM}Found {} document match{}{RESET}",
results.len(),
if results.len() == 1 { "" } else { "es" }
);
}
pub(super) fn apply_coverage_diff(
results: &mut [QueryResult],
project_path: &std::path::Path,
diff_path: &std::path::Path,
quiet: bool,
) {
match std::fs::read_to_string(diff_path) {
Ok(json) => match build_coverage_map(&json, project_path) {
Ok(baseline) => {
enrich_with_coverage_diff(results, &baseline);
}
Err(e) => {
if !quiet {
eprintln!("Warning: Could not parse coverage baseline: {}", e);
}
}
},
Err(e) => {
if !quiet {
eprintln!(
"Warning: Could not read coverage baseline {}: {}",
diff_path.display(),
e
);
}
}
}
}