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

10
PLAN.md
View File

@@ -178,23 +178,23 @@ Private helpers (e.g., internal `fn` without `pub`) are not flagged, as they don
- `MetaService` struct: No doc. - `MetaService` struct: No doc.
- Methods (`new`, `get_plugins`, `initialize_plugins`, etc.): Partial. - Methods (`new`, `get_plugins`, `initialize_plugins`, etc.): Partial.
28. **src/modes/server/mcp/mod.rs** 28. **src/modes/server/mcp/mod.rs** [DONE]
- Duplicate of mcp.rs; `handle_mcp_request()`: No doc. - Duplicate of mcp.rs; `handle_mcp_request()`: No doc.
29. **src/modes/generate_config.rs** 29. **src/modes/generate_config.rs** [DONE]
- Structs (`DefaultConfig`, etc.): No docs. - Structs (`DefaultConfig`, etc.): No docs.
- `mode_generate_config()` function: No doc. - `mode_generate_config()` function: No doc.
- Helper `convert_outputs_to_string_map()`: No doc. - Helper `convert_outputs_to_string_map()`: No doc.
30. **src/services/async_item_service.rs** 30. **src/services/async_item_service.rs** [DONE]
- `AsyncItemService` struct: Partial. - `AsyncItemService` struct: Partial.
- Many async methods (`get_item`, `get_item_content`, etc.): Partial or no docs. - Many async methods (`get_item`, `get_item_content`, etc.): Partial or no docs.
31. **src/modes/status_plugins.rs** 31. **src/modes/status_plugins.rs** [DONE]
- `mode_status_plugins()` function: Partial. - `mode_status_plugins()` function: Partial.
- Helper builders (`build_meta_plugin_table`, etc.): No docs. - Helper builders (`build_meta_plugin_table`, etc.): No docs.
32. **src/meta_plugin/env.rs** 32. **src/meta_plugin/env.rs** [DONE]
- `EnvMetaPlugin` struct: No doc. - `EnvMetaPlugin` struct: No doc.
- `new()` function: Partial. - `new()` function: Partial.
- Impl `MetaPlugin` methods: No docs. - Impl `MetaPlugin` methods: No docs.

View File

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

View File

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

View File

@@ -11,6 +11,22 @@ use crate::services::item_service::ItemService;
use chrono::prelude::*; use chrono::prelude::*;
use comfy_table::{Cell, Attribute}; 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( pub fn mode_info(
cmd: &mut Command, cmd: &mut Command,
settings: &config::Settings, settings: &config::Settings,
@@ -37,7 +53,8 @@ pub fn mode_info(
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct ItemInfo { /// Structured representation of item information for JSON/YAML output.
pub struct ItemInfo {
id: i64, id: i64,
timestamp: String, timestamp: String,
path: String, path: String,
@@ -55,6 +72,17 @@ fn show_item(
settings: &config::Settings, settings: &config::Settings,
data_path: PathBuf, data_path: PathBuf,
) -> Result<()> { ) -> 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); let output_format = crate::modes::common::settings_output_format(settings);
if output_format != OutputFormat::Table { if output_format != OutputFormat::Table {
@@ -135,6 +163,18 @@ fn show_item_structured(
data_path: PathBuf, data_path: PathBuf,
output_format: OutputFormat, output_format: OutputFormat,
) -> Result<()> { ) -> 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 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 meta_map = item_with_meta.meta_as_map();
let item = item_with_meta.item; let item = item_with_meta.item;

View File

@@ -5,15 +5,43 @@ use crate::modes::server::common::AppState;
use super::tools::{KeepTools, ToolError}; use super::tools::{KeepTools, ToolError};
#[derive(Clone)] #[derive(Clone)]
/// Server handler for MCP (Model Context Protocol) requests.
///
/// Routes requests to appropriate tools and handles responses.
pub struct KeepMcpServer { pub struct KeepMcpServer {
state: AppState, state: AppState,
} }
impl KeepMcpServer { 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 { pub fn new(state: AppState) -> Self {
Self { state } 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> { pub async fn handle_request(&self, method: &str, params: Option<Value>) -> Result<String, ToolError> {
debug!("MCP: Handling request '{}' with params: {:?}", method, params); debug!("MCP: Handling request '{}' with params: {:?}", method, params);

View File

@@ -3,7 +3,18 @@ use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
use log::debug; 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 { fn convert_json_to_yaml_value(value: &serde_json::Value) -> serde_yaml::Value {
match value { match value {
serde_json::Value::Null => serde_yaml::Value::Null, 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 { 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); let mut meta_plugin_table = crate::modes::common::create_table(true);
meta_plugin_table.set_header(vec![ 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 { 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); let mut compression_table = crate::modes::common::create_table(true);
compression_table.set_header(vec![ 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 { 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); let mut filter_plugin_table = crate::modes::common::create_table(true);
filter_plugin_table.set_header(vec![ filter_plugin_table.set_header(vec![