docs: Add comprehensive documentation for modes, services, and plugins

Co-authored-by: aider (openai/andrew/openrouter/sonoma-sky-alpha) <aider@aider.chat>
This commit is contained in:
Andrew Phillips
2025-09-10 14:29:16 -03:00
parent d44f3fbb5b
commit 88c7290a7b
6 changed files with 146 additions and 12 deletions

View File

@@ -3,6 +3,9 @@ use std::io::{Result, Read, Write, BufRead};
use regex::Regex;
/// A filter that matches lines against a regular expression pattern.
///
/// Outputs only lines that match the given regex.
#[derive(Debug, Clone)]
pub struct GrepFilter {
regex: Regex,
}
@@ -16,7 +19,7 @@ impl GrepFilter {
///
/// # Errors
///
/// Returns an `io::Error` if the regex pattern is invalid.
/// Returns an `io::Error` with `InvalidInput` if the regex pattern is invalid.
pub fn new(pattern: String) -> Result<Self> {
let regex = Regex::new(&pattern)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?;
@@ -29,6 +32,8 @@ impl GrepFilter {
impl FilterPlugin for GrepFilter {
/// Filters the input by writing only lines that match the regex pattern.
///
/// Reads lines from the input and writes matching lines to the output, preserving newlines.
///
/// # Arguments
///
/// * `reader` - A boxed mutable reference to the input reader providing the data stream.
@@ -37,6 +42,10 @@ impl FilterPlugin for GrepFilter {
/// # Returns
///
/// Returns `Ok(())` on success, or an `io::Error` if reading or writing fails.
///
/// # Errors
///
/// Propagates `io::Error` from reading lines or writing output.
fn filter(&mut self, mut reader: Box<&mut dyn Read>, mut writer: Box<&mut dyn Write>) -> Result<()> {
let mut buf_reader = std::io::BufReader::new(&mut *reader);
for line in buf_reader.by_ref().lines() {
@@ -50,6 +59,8 @@ impl FilterPlugin for GrepFilter {
/// Clones this filter into a new boxed instance.
///
/// Creates a new GrepFilter with the same regex pattern.
///
/// # Returns
///
/// A new `Box<dyn FilterPlugin>` representing a clone of this filter.
@@ -61,6 +72,8 @@ impl FilterPlugin for GrepFilter {
/// Returns the configuration options for this filter.
///
/// The only option is the required "pattern" for the regex.
///
/// # Returns
///
/// A vector of `FilterOption` describing the filter's configurable parameters.

View File

@@ -1,6 +1,7 @@
use super::{MetaPlugin, MetaPluginType, process_metadata_outputs};
#[derive(Debug, Clone)]
/// Meta plugin that extracts environment variables prefixed with KEEP_META_ as metadata.
pub struct EnvMetaPlugin {
is_finalized: bool,
outputs: std::collections::HashMap<String, serde_yaml::Value>,
@@ -10,10 +11,12 @@ pub struct EnvMetaPlugin {
impl EnvMetaPlugin {
/// Creates a new `EnvMetaPlugin` instance.
///
/// Collects environment variables starting with KEEP_META_ and sets up default output mappings.
///
/// # Arguments
///
/// * `_options` - Optional configuration options for the plugin (unused in this implementation).
/// * `outputs` - Optional output mappings for metadata.
/// * `outputs` - Optional output mappings for metadata (overrides defaults).
///
/// # Returns
///
@@ -83,6 +86,8 @@ impl MetaPlugin for EnvMetaPlugin {
/// Initializes the plugin, processing environment variables.
///
/// Processes all KEEP_META_* variables and generates metadata using output mappings.
///
/// # Returns
///
/// A `MetaPluginResponse` with environment metadata and finalized state set to `true`.
@@ -118,13 +123,15 @@ impl MetaPlugin for EnvMetaPlugin {
/// Updates the plugin with new data (unused in this implementation).
///
/// This plugin does not process streaming data; returns empty response.
///
/// # Arguments
///
/// * `_data` - The data chunk (unused).
///
/// # Returns
///
/// A `MetaPluginResponse` with empty metadata and finalized state.
/// A `MetaPluginResponse` with empty metadata and current finalized state.
fn update(&mut self, _data: &[u8]) -> crate::meta_plugin::MetaPluginResponse {
// If already finalized, don't process more data
if self.is_finalized {
@@ -142,6 +149,8 @@ impl MetaPlugin for EnvMetaPlugin {
/// Finalizes the plugin, calling initialize if not already done.
///
/// Ensures environment metadata is processed if not previously initialized.
///
/// # Returns
///
/// A `MetaPluginResponse` with environment metadata if not finalized, or empty if already done.
@@ -179,7 +188,7 @@ impl MetaPlugin for EnvMetaPlugin {
///
/// # Returns
///
/// A vector of environment variable names.
/// A vector of environment variable names (stripped of KEEP_META_ prefix).
fn default_outputs(&self) -> Vec<String> {
self.env_vars.iter()
.map(|(name, _)| name.clone())
@@ -188,6 +197,8 @@ impl MetaPlugin for EnvMetaPlugin {
/// Returns a reference to the options mapping (empty for this plugin).
///
/// This plugin has no configurable options.
///
/// # Returns
///
/// An empty `HashMap`.
@@ -209,7 +220,7 @@ impl MetaPlugin for EnvMetaPlugin {
}
use crate::meta_plugin::register_meta_plugin;
// Register the plugin at module initialization time
/// Registers the EnvMetaPlugin with the global registry at module initialization.
#[ctor::ctor]
fn register_env_plugin() {
register_meta_plugin(MetaPluginType::Env, |options, outputs| {

View File

@@ -11,6 +11,22 @@ use crate::services::item_service::ItemService;
use chrono::prelude::*;
use comfy_table::{Cell, Attribute};
/// Displays detailed information about an item or the last item if no ID/tags specified.
///
/// Supports table, JSON, or YAML output formats.
///
/// # Arguments
///
/// * `cmd` - Mutable Clap command for error handling.
/// * `settings` - Application settings.
/// * `ids` - Mutable vector of item IDs (at most one).
/// * `tags` - Mutable vector of tags (mutually exclusive with IDs).
/// * `conn` - Mutable database connection.
/// * `data_path` - Path to data directory.
///
/// # Returns
///
/// `Ok(())` on success, or Result with error.
pub fn mode_info(
cmd: &mut Command,
settings: &config::Settings,
@@ -37,7 +53,8 @@ pub fn mode_info(
}
#[derive(Debug, Serialize, Deserialize)]
struct ItemInfo {
/// Structured representation of item information for JSON/YAML output.
pub struct ItemInfo {
id: i64,
timestamp: String,
path: String,
@@ -55,6 +72,17 @@ fn show_item(
settings: &config::Settings,
data_path: PathBuf,
) -> Result<()> {
/// Displays item information in table format or delegates to structured output.
///
/// # Arguments
///
/// * `item_with_meta` - Item with associated metadata and tags.
/// * `settings` - Application settings for formatting.
/// * `data_path` - Path to data directory for file size calculation.
///
/// # Returns
///
/// `Ok(())` on success.
let output_format = crate::modes::common::settings_output_format(settings);
if output_format != OutputFormat::Table {
@@ -135,6 +163,18 @@ fn show_item_structured(
data_path: PathBuf,
output_format: OutputFormat,
) -> Result<()> {
/// Displays item information in structured JSON or YAML format.
///
/// # Arguments
///
/// * `item_with_meta` - Item with metadata and tags.
/// * `settings` - Settings for size formatting.
/// * `data_path` - Data path for file size.
/// * `output_format` - JSON or YAML.
///
/// # Returns
///
/// `Ok(())` on success.
let item_tags: Vec<String> = item_with_meta.tags.iter().map(|t| t.name.clone()).collect();
let meta_map = item_with_meta.meta_as_map();
let item = item_with_meta.item;

View File

@@ -5,15 +5,43 @@ use crate::modes::server::common::AppState;
use super::tools::{KeepTools, ToolError};
#[derive(Clone)]
/// Server handler for MCP (Model Context Protocol) requests.
///
/// Routes requests to appropriate tools and handles responses.
pub struct KeepMcpServer {
state: AppState,
}
impl KeepMcpServer {
/// Creates a new `KeepMcpServer` instance.
///
/// # Arguments
///
/// * `state` - The application state containing DB and config.
///
/// # Returns
///
/// A new `KeepMcpServer`.
pub fn new(state: AppState) -> Self {
Self { state }
}
/// Handles an MCP request by routing to the appropriate tool.
///
/// Supports methods like save_item, get_item, etc.
///
/// # Arguments
///
/// * `method` - The MCP method name.
/// * `params` - Optional JSON parameters.
///
/// # Returns
///
/// JSON string response on success, or ToolError.
///
/// # Errors
///
/// Returns ToolError::UnknownTool for unsupported methods.
pub async fn handle_request(&self, method: &str, params: Option<Value>) -> Result<String, ToolError> {
debug!("MCP: Handling request '{}' with params: {:?}", method, params);

View File

@@ -3,7 +3,18 @@ use std::path::PathBuf;
use std::str::FromStr;
use log::debug;
// Helper function to convert serde_json::Value to serde_yaml::Value
/// Helper function to convert serde_json::Value to serde_yaml::Value.
///
/// Recursively converts JSON values to equivalent YAML values, handling null, bool, number,
/// string, array, and object types.
///
/// # Arguments
///
/// * `value` - Reference to the JSON value to convert.
///
/// # Returns
///
/// The equivalent YAML value.
fn convert_json_to_yaml_value(value: &serde_json::Value) -> serde_yaml::Value {
match value {
serde_json::Value::Null => serde_yaml::Value::Null,
@@ -49,6 +60,17 @@ use crate::common::status::{MetaPluginInfo, CompressionInfo};
fn build_meta_plugin_table(meta_plugin_info: &std::collections::HashMap<String, MetaPluginInfo>) -> Table {
/// Builds a formatted table displaying meta plugin information.
///
/// Sorts plugins by name and displays options as YAML and outputs as a list.
///
/// # Arguments
///
/// * `meta_plugin_info` - HashMap of meta plugin information.
///
/// # Returns
///
/// A formatted `comfy_table::Table`.
let mut meta_plugin_table = crate::modes::common::create_table(true);
meta_plugin_table.set_header(vec![
@@ -110,6 +132,15 @@ fn build_meta_plugin_table(meta_plugin_info: &std::collections::HashMap<String,
}
fn build_compression_table(compression_info: &Vec<CompressionInfo>) -> Table {
/// Builds a formatted table displaying compression plugin information.
///
/// # Arguments
///
/// * `compression_info` - Vector of compression info.
///
/// # Returns
///
/// A formatted `comfy_table::Table`.
let mut compression_table = crate::modes::common::create_table(true);
compression_table.set_header(vec![
@@ -142,6 +173,17 @@ fn build_compression_table(compression_info: &Vec<CompressionInfo>) -> Table {
}
fn build_filter_plugin_table(filter_plugins: &Vec<crate::common::status::FilterPluginInfo>) -> Table {
/// Builds a formatted table displaying filter plugin information.
///
/// Sorts plugins by name and formats options as YAML sequence.
///
/// # Arguments
///
/// * `filter_plugins` - Vector of filter plugin info.
///
/// # Returns
///
/// A formatted `comfy_table::Table`.
let mut filter_plugin_table = crate::modes::common::create_table(true);
filter_plugin_table.set_header(vec![