cosh-tools 0.1.4

Tools crate for cosh - coding agent for the terminal
Documentation
//! All public and internal types for the skill reader tool.

use std::path::PathBuf;

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use thiserror::Error;

// Public types

/// Input for `skills_read`.
#[derive(Debug, Clone, Deserialize, JsonSchema)]
pub struct SkillsReadInput {
    /// Name of the skill to read.
    pub name: String,
}

/// Input for `skills_read_asset`.
#[derive(Debug, Clone, Deserialize, JsonSchema)]
pub struct SkillsReadAssetInput {
    /// Name of the skill that owns the asset.
    pub name: String,
    /// Relative path to the asset file within the skill directory.
    pub asset_path: String,
}

/// Input for `skills_match_skills`.
#[derive(Debug, Clone, Deserialize, JsonSchema)]
pub struct SkillsMatchInput {
    /// File paths to match against skill glob patterns.
    pub match_paths: Vec<String>,
}

/// Lightweight metadata returned in list / match results and system prompts.
#[derive(Debug, Clone, Serialize)]
pub struct SkillInfo {
    pub name: String,
    pub description: String,
}

/// Full skill content returned by the `read` action.
#[derive(Debug, Clone, Serialize)]
pub struct SkillContent {
    pub info: SkillInfo,
    /// SKILL.md body with frontmatter stripped.
    pub body: String,
}

/// Where to look for skills.
#[derive(Debug, Clone)]
pub enum SkillSource {
    /// A directory on the local filesystem that contains skill subdirectories.
    Directory { path: String },
    /// An in-memory skill provided directly by the caller.
    Embedded { skill: EmbeddedSkill },
}

/// An inline skill that does not require filesystem access.
#[derive(Debug, Clone)]
pub struct EmbeddedSkill {
    pub name: String,
    pub description: String,
    /// Full SKILL.md content, including frontmatter and body.
    pub content: String,
    pub globs: Vec<String>,
    pub always_apply: bool,
}

/// Actions the tool can perform.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SkillAction {
    List,
    Read,
    ReadAsset,
    Match,
}

/// The schema passed by the caller — carries all policy.
///
/// Zero hardcoded paths, names, or policies. Everything is supplied here.
#[derive(Debug, Clone)]
pub struct SkillSchema {
    pub action: SkillAction,
    /// Ordered list of sources. First source wins on name collision.
    pub sources: Vec<SkillSource>,
    /// Target skill name for `read` / `read_asset`.
    pub skill_name: Option<String>,
    /// Relative sub-path inside a skill directory for `read_asset`.
    pub asset_path: Option<String>,
    /// Active file paths to match skill globs against.
    pub match_paths: Vec<String>,
    /// Whether to scan directories recursively.
    pub recursive: bool,
    /// Glob-style skill name exclusions.
    pub ignore: Vec<String>,
    /// Allowlist — when non-empty, only skills whose name appears here are
    /// returned. Empty means all skills pass.
    pub include: Vec<String>,
}

/// Output of a skill tool invocation.
#[derive(Debug, Clone, Serialize)]
pub enum SkillOutput {
    List { skills: Vec<SkillInfo> },
    Read { skill: SkillContent },
    ReadAsset { content: String },
    Match { matched: Vec<SkillInfo> },
}

/// Error type for skill operations.
#[derive(Debug, Error)]
pub enum SkillError {
    #[error("skill not found: {0}")]
    NotFound(String),
    #[error("path traversal detected: {0}")]
    PathTraversal(String),
    #[error("invalid action: {0}")]
    InvalidAction(String),
    #[error("invalid source: {0}")]
    InvalidSource(String),
}

// Internal types (shared across sub-modules)

/// Parsed frontmatter metadata from a SKILL.md file.
#[derive(Debug, Default)]
pub struct Frontmatter {
    pub name: Option<String>,
    pub description: Option<String>,
    pub globs: Vec<String>,
    pub always_apply: bool,
}

/// A discovered skill before dedup and output conversion.
#[derive(Debug, Clone)]
pub struct RawSkill {
    pub source_key: String,
    pub name: String,
    pub description: String,
    /// Directory containing SKILL.md (base for asset resolution).
    pub base_dir: PathBuf,
    /// Body with frontmatter stripped.
    pub body: String,
    pub globs: Vec<String>,
    pub always_apply: bool,
}