reasonkit-mem 0.1.7

High-performance vector database & RAG memory layer - hybrid search, embeddings, RAPTOR trees, BM25 fusion, and semantic retrieval for AI systems
//! vdream_cli_clap — Command-line interface for vDreamTeam memory operations (clap version)
//!
//! Migrated from manual parsing to clap with ReasonKit CLI standards.

use anyhow::{anyhow, Context};
use clap::{Parser, Subcommand};
use dirs;
use std::env;
use std::path::PathBuf;

#[cfg(feature = "vdreamteam")]
use reasonkit_mem::vdreamteam::{Consultation, PxPEntry, VDreamMemory};

// Import ReasonKit CLI standards
use reasonkit_cli::branding::{format_banner_with_color, should_enable_color};
use reasonkit_cli::{setup_logging, CliBase, OutputFormat};

#[derive(Parser)]
#[command(name = "vdream-cli", about = "vDreamTeam memory operations", version)]
struct Cli {
    #[command(flatten)]
    base: CliBase,

    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// Show memory statistics
    Stats,

    /// Query memory (constitutional or role-specific)
    Query {
        /// Memory layer (constitutional|role)
        layer: String,

        /// Section or role ID
        target: String,

        /// Query type (optional)
        query_type: Option<String>,
    },

    /// Check constraint applicability
    Check {
        /// Constraint ID (e.g., CONS-001)
        constraint_id: String,

        /// Proposed action to check (optional)
        proposed_action: Option<String>,
    },

    /// Log PxP (Prompt x Protocol) event
    LogPxp {
        /// Role ID
        role_id: String,

        /// Decision context
        decision_context: String,

        /// Model used (optional)
        model: Option<String>,
    },

    /// List all roles
    Roles,

    /// List all constraints  
    Constraints,
}

fn get_agents_path() -> PathBuf {
    env::var("VDREAM_AGENTS_PATH")
        .map(PathBuf::from)
        .unwrap_or_else(|_| {
            if let Some(home) = dirs::home_dir() {
                let rk_agents = home.join("RK-PROJECT").join(".agents");
                if rk_agents.exists() {
                    return rk_agents;
                }
            }
            PathBuf::from(".agents")
        })
}

#[cfg(feature = "vdreamteam")]
async fn cmd_stats(agents_path: &PathBuf) -> anyhow::Result<()> {
    let memory = VDreamMemory::load(agents_path).await?;

    println!("vDreamTeam Memory Statistics");
    println!("============================");
    println!("Agents Path: {}", agents_path.display());
    println!();

    // Constitutional layer
    match memory.constitutional().await {
        Ok(constitutional) => {
            println!("Constitutional Layer: LOADED");
            println!("  Identity: {}", constitutional.identity.organization.name);
            println!(
                "  Constraints: {} defined",
                constitutional.constraints.len()
            );
            println!(
                "  Boundaries: {} OSS, {} proprietary, {} never-OSS",
                constitutional.boundaries.oss_projects.len(),
                constitutional.boundaries.proprietary_projects.len(),
                constitutional.boundaries.never_oss.len()
            );
            println!(
                "  Quality Gates: {} defined",
                constitutional.quality_gates.len()
            );
        }
        Err(e) => {
            println!("Constitutional Layer: ERROR - {}", e);
        }
    }

    println!();

    // Roles
    let roles = memory.roles().await?;
    println!("Role Memory: {} roles", roles.len());
    for role in roles {
        println!("  - {} (Agent: {})", role.id, role.config.agent_name);
    }

    Ok(())
}

#[cfg(feature = "vdreamteam")]
async fn cmd_query(
    agents_path: &PathBuf,
    layer: &str,
    target: &str,
    query_type: Option<&str>,
) -> anyhow::Result<()> {
    todo!("Implement query command migration");
}

#[cfg(feature = "vdreamteam")]
async fn cmd_check(
    agents_path: &PathBuf,
    constraint_id: &str,
    proposed_action: Option<&str>,
) -> anyhow::Result<()> {
    todo!("Implement check command migration");
}

#[cfg(feature = "vdreamteam")]
async fn cmd_log_pxp(
    agents_path: &PathBuf,
    role_id: &str,
    decision_context: &str,
    model: Option<&str>,
) -> anyhow::Result<()> {
    todo!("Implement log-pxp command migration");
}

#[cfg(feature = "vdreamteam")]
async fn cmd_roles(agents_path: &PathBuf) -> anyhow::Result<()> {
    todo!("Implement roles command migration");
}

#[cfg(feature = "vdreamteam")]
async fn cmd_constraints(agents_path: &PathBuf) -> anyhow::Result<()> {
    todo!("Implement constraints command migration");
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let cli = Cli::parse();
    setup_logging(cli.base.verbose);
    let enable_color = should_enable_color(cli.base.color);

    // Print banner for verbosity >= 1
    if cli.base.verbose >= 1 {
        println!(
            "{}",
            format_banner_with_color("vDreamTeam", "1.0.0", enable_color)
        );
    }

    let agents_path = get_agents_path();

    #[cfg(feature = "vdreamteam")]
    match cli.command {
        Commands::Stats => {
            cmd_stats(&agents_path).await?;
        }
        Commands::Query {
            layer,
            target,
            query_type,
        } => {
            cmd_query(&agents_path, &layer, &target, query_type.as_deref()).await?;
        }
        Commands::Check {
            constraint_id,
            proposed_action,
        } => {
            cmd_check(&agents_path, &constraint_id, proposed_action.as_deref()).await?;
        }
        Commands::LogPxp {
            role_id,
            decision_context,
            model,
        } => {
            cmd_log_pxp(&agents_path, &role_id, &decision_context, model.as_deref()).await?;
        }
        Commands::Roles => {
            cmd_roles(&agents_path).await?;
        }
        Commands::Constraints => {
            cmd_constraints(&agents_path).await?;
        }
    }

    #[cfg(not(feature = "vdreamteam"))]
    {
        println!("vdream-cli requires 'vdreamteam' feature");
        println!("Build with: cargo build --bin vdream-cli --features vdreamteam");
    }

    Ok(())
}