kura-cli 0.1.16

Kura Training CLI for interacting with the Kura API and MCP runtime.
Documentation
use clap::{Args, Subcommand};

use crate::commands::agent;

#[derive(Subcommand)]
pub enum ReadCommands {
    /// Deterministic startup read plan via /v1/agent/context/section-index
    Startup(ReadStartupArgs),
    /// Fetch exactly one context section by id via /v1/agent/context/section-fetch
    Section(ReadSectionArgs),
    /// Compatibility bundled context read via /v1/agent/context
    Bundle(ReadBundleArgs),
}

#[derive(Args)]
pub struct ReadStartupArgs {
    /// Max exercise_progression projections to include (default: 5)
    #[arg(long)]
    exercise_limit: Option<u32>,
    /// Max strength_inference projections to include (default: 5)
    #[arg(long)]
    strength_limit: Option<u32>,
    /// Max custom projections to include (default: 10)
    #[arg(long)]
    custom_limit: Option<u32>,
    /// Optional task intent used for startup section derivation
    #[arg(long)]
    task_intent: Option<String>,
    /// Include deployment-static system config in response payload (default: API default=true)
    #[arg(long)]
    include_system: Option<bool>,
    /// Optional response token budget hint (min 400, max 12000)
    #[arg(long)]
    budget_tokens: Option<u32>,
}

#[derive(Args)]
pub struct ReadSectionArgs {
    /// Stable section id from read startup
    #[arg(long)]
    section: String,
    /// Optional page size for paged sections (1..200)
    #[arg(long)]
    limit: Option<u32>,
    /// Optional opaque cursor for paged sections
    #[arg(long)]
    cursor: Option<String>,
    /// Optional comma-separated top-level fields to project
    #[arg(long)]
    fields: Option<String>,
    /// Optional task intent for startup section derivation
    #[arg(long)]
    task_intent: Option<String>,
}

#[derive(Args)]
pub struct ReadBundleArgs {
    /// Max exercise_progression projections to include (default: 5)
    #[arg(long)]
    exercise_limit: Option<u32>,
    /// Max strength_inference projections to include (default: 5)
    #[arg(long)]
    strength_limit: Option<u32>,
    /// Max custom projections to include (default: 10)
    #[arg(long)]
    custom_limit: Option<u32>,
    /// Optional task intent used for context ranking
    #[arg(long)]
    task_intent: Option<String>,
    /// Include deployment-static system config in response payload (default: API default=true)
    #[arg(long)]
    include_system: Option<bool>,
    /// Optional response token budget hint (min 400, max 12000)
    #[arg(long)]
    budget_tokens: Option<u32>,
}

pub async fn run(api_url: &str, token: Option<&str>, command: ReadCommands) -> i32 {
    match command {
        ReadCommands::Startup(args) => {
            agent::section_index(
                api_url,
                token,
                args.exercise_limit,
                args.strength_limit,
                args.custom_limit,
                args.task_intent,
                args.include_system,
                args.budget_tokens,
            )
            .await
        }
        ReadCommands::Section(args) => {
            agent::section_fetch(
                api_url,
                token,
                args.section,
                args.limit,
                args.cursor,
                args.fields,
                args.task_intent,
            )
            .await
        }
        ReadCommands::Bundle(args) => {
            agent::context(
                api_url,
                token,
                args.exercise_limit,
                args.strength_limit,
                args.custom_limit,
                args.task_intent,
                args.include_system,
                args.budget_tokens,
            )
            .await
        }
    }
}