diff options
Diffstat (limited to 'makima')
| -rw-r--r-- | makima/src/bin/makima.rs | 13 | ||||
| -rw-r--r-- | makima/src/daemon/api/mod.rs | 2 | ||||
| -rw-r--r-- | makima/src/daemon/api/red_team.rs | 39 | ||||
| -rw-r--r-- | makima/src/daemon/cli/mod.rs | 57 | ||||
| -rw-r--r-- | makima/src/daemon/cli/red_team.rs | 26 |
5 files changed, 135 insertions, 2 deletions
diff --git a/makima/src/bin/makima.rs b/makima/src/bin/makima.rs index ffb9364..44fa590 100644 --- a/makima/src/bin/makima.rs +++ b/makima/src/bin/makima.rs @@ -6,7 +6,7 @@ use std::sync::Arc; use makima::daemon::api::{ApiClient, CreateContractRequest}; use makima::daemon::cli::{ - Cli, CliConfig, Commands, ConfigCommand, ContractCommand, SupervisorCommand, ViewArgs, + Cli, CliConfig, Commands, ConfigCommand, ContractCommand, RedTeamCommand, SupervisorCommand, ViewArgs, }; use makima::daemon::tui::{self, Action, App, ListItem, ViewType, TuiWsClient, WsEvent, OutputLine, OutputMessageType, WsConnectionState, RepositorySuggestion}; use makima::daemon::config::{DaemonConfig, RepoEntry}; @@ -30,6 +30,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> { Commands::Contract(cmd) => run_contract(cmd).await, Commands::View(args) => run_view(args).await, Commands::Config(cmd) => run_config(cmd).await, + Commands::RedTeam(cmd) => run_red_team(cmd).await, } } @@ -789,6 +790,16 @@ async fn run_config(cmd: ConfigCommand) -> Result<(), Box<dyn std::error::Error } } +/// Run red team commands. +async fn run_red_team(cmd: RedTeamCommand) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { + match cmd { + RedTeamCommand::Notify(args) => { + makima::daemon::cli::handle_notify(args).await?; + Ok(()) + } + } +} + /// Load contracts from API async fn load_contracts(client: &ApiClient) -> Result<Vec<ListItem>, Box<dyn std::error::Error + Send + Sync>> { let result = client.list_contracts().await?; diff --git a/makima/src/daemon/api/mod.rs b/makima/src/daemon/api/mod.rs index 49d80e0..92e34e9 100644 --- a/makima/src/daemon/api/mod.rs +++ b/makima/src/daemon/api/mod.rs @@ -2,7 +2,9 @@ pub mod client; pub mod contract; +pub mod red_team; pub mod supervisor; pub use client::ApiClient; pub use contract::CreateContractRequest; +pub use red_team::RedTeamNotifyRequest; diff --git a/makima/src/daemon/api/red_team.rs b/makima/src/daemon/api/red_team.rs new file mode 100644 index 0000000..6d3c969 --- /dev/null +++ b/makima/src/daemon/api/red_team.rs @@ -0,0 +1,39 @@ +//! Red team API methods. + +use serde::Serialize; +use uuid::Uuid; + +use super::client::{ApiClient, ApiError}; +use super::supervisor::JsonValue; + +/// Request body for red team notify endpoint. +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +pub struct RedTeamNotifyRequest { + /// The issue message + pub message: String, + + /// Severity level: low, medium, high, critical + pub severity: String, + + /// The specific task this relates to (optional) + #[serde(skip_serializing_if = "Option::is_none")] + pub related_task_id: Option<Uuid>, + + /// The file path where the issue was detected (optional) + #[serde(skip_serializing_if = "Option::is_none")] + pub file_path: Option<String>, + + /// Additional context about the issue (optional) + #[serde(skip_serializing_if = "Option::is_none")] + pub context: Option<String>, +} + +impl ApiClient { + /// Send a red team notification about an issue found during adversarial review. + /// + /// POST /api/v1/mesh/red-team/notify + pub async fn red_team_notify(&self, req: RedTeamNotifyRequest) -> Result<JsonValue, ApiError> { + self.post("/api/v1/mesh/red-team/notify", &req).await + } +} diff --git a/makima/src/daemon/cli/mod.rs b/makima/src/daemon/cli/mod.rs index 0805edd..c848e8e 100644 --- a/makima/src/daemon/cli/mod.rs +++ b/makima/src/daemon/cli/mod.rs @@ -3,15 +3,18 @@ pub mod config; pub mod contract; pub mod daemon; +pub mod red_team; pub mod server; pub mod supervisor; pub mod view; -use clap::{Parser, Subcommand}; +use clap::{Args, Parser, Subcommand}; +use uuid::Uuid; pub use config::CliConfig; pub use contract::ContractArgs; pub use daemon::DaemonArgs; +pub use red_team::handle_notify; pub use server::ServerArgs; pub use supervisor::SupervisorArgs; pub use view::ViewArgs; @@ -58,6 +61,10 @@ pub enum Commands { /// Saves configuration to ~/.makima/config.toml for use by CLI commands. #[command(subcommand)] Config(ConfigCommand), + + /// Red team commands for adversarial monitoring + #[command(name = "red-team", subcommand)] + RedTeam(RedTeamCommand), } /// Config subcommands for CLI configuration. @@ -196,6 +203,54 @@ pub enum ContractCommand { CreateFile(contract::CreateFileArgs), } +/// Red team subcommands for adversarial monitoring. +#[derive(Subcommand, Debug)] +pub enum RedTeamCommand { + /// Send a notification to the supervisor about a detected issue. + /// Only available to red team tasks. + Notify(RedTeamNotifyArgs), +} + +/// Arguments for red-team notify command. +#[derive(Args, Debug)] +pub struct RedTeamNotifyArgs { + /// API URL + #[arg(long, env = "MAKIMA_API_URL", default_value = "https://api.makima.jp")] + pub api_url: String, + + /// API key for authentication + #[arg(long, env = "MAKIMA_API_KEY")] + pub api_key: String, + + /// Current task ID (must be a red team task) + #[arg(long, env = "MAKIMA_TASK_ID")] + pub task_id: Uuid, + + /// Contract ID + #[arg(long, env = "MAKIMA_CONTRACT_ID")] + pub contract_id: Uuid, + + /// The notification message + #[arg(index = 1)] + pub message: String, + + /// Severity level: low, medium, high, critical + #[arg(long, default_value = "medium")] + pub severity: String, + + /// Related task ID (optional) + #[arg(long)] + pub task: Option<Uuid>, + + /// Related file path (optional) + #[arg(long)] + pub file: Option<String>, + + /// Additional context (optional) + #[arg(long)] + pub context: Option<String>, +} + impl Cli { /// Parse command-line arguments pub fn parse_args() -> Self { diff --git a/makima/src/daemon/cli/red_team.rs b/makima/src/daemon/cli/red_team.rs new file mode 100644 index 0000000..771aae4 --- /dev/null +++ b/makima/src/daemon/cli/red_team.rs @@ -0,0 +1,26 @@ +//! Red Team subcommand - adversarial review notification commands. + +use crate::daemon::api::{ApiClient, RedTeamNotifyRequest}; +use super::RedTeamNotifyArgs; + +/// Handle the red-team notify command. +pub async fn handle_notify(args: RedTeamNotifyArgs) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { + let client = ApiClient::new(args.api_url, args.api_key)?; + + // Use --task if provided, otherwise fall back to MAKIMA_TASK_ID + let related_task_id = args.task; + + let req = RedTeamNotifyRequest { + message: args.message, + severity: args.severity, + related_task_id, + file_path: args.file, + context: args.context, + }; + + eprintln!("Sending red team notification..."); + let result = client.red_team_notify(req).await?; + println!("{}", serde_json::to_string(&result.0)?); + + Ok(()) +} |
