bijux-cli 0.4.1

Command-line runtime for automation, plugin-driven tools, and interactive workflows with structured output.
Documentation
//! Official app delegation helpers across binary, Python, and embedded mounts.

use std::process::Command;

use serde_json::json;

use crate::contracts::{known_bijux_tool_by_query, KnownBijuxTool, ProductEntrypointKind};
use crate::features::apps::{resolve_control_command, resolve_runtime_command, ResolvedAppCommand};

use super::AppRunResult;

#[derive(Debug, Clone, PartialEq, Eq)]
struct DelegatedKnownToolCommand {
    resolved: ResolvedAppCommand,
    install_commands: Vec<String>,
    public_help_binary: Option<String>,
    command_surface: String,
    forwarded_args: Vec<String>,
}

fn is_global_flag_without_value(token: &str) -> bool {
    matches!(token, "--quiet" | "-q" | "--pretty" | "--no-pretty" | "--json" | "--text")
}

fn is_global_flag_with_value(token: &str) -> bool {
    matches!(token, "--format" | "-f" | "--log-level" | "--color" | "--config-path")
}

fn is_global_flag_with_equals(token: &str) -> bool {
    token.starts_with("--format=")
        || token.starts_with("--log-level=")
        || token.starts_with("--color=")
        || token.starts_with("--config-path=")
}

fn skip_root_globals(argv: &[String]) -> usize {
    let mut idx = 1;
    while idx < argv.len() {
        let token = argv[idx].as_str();
        if is_global_flag_without_value(token) || is_global_flag_with_equals(token) {
            idx += 1;
            continue;
        }
        if is_global_flag_with_value(token) {
            idx += 2;
            continue;
        }
        break;
    }
    idx
}

fn locate_known_tool_route(argv: &[String]) -> Option<(bool, String, usize)> {
    let command_start = skip_root_globals(argv);
    let first = argv.get(command_start)?;
    if first == "dev" {
        let query = argv.get(command_start + 1)?;
        known_bijux_tool_by_query(query).map(|_| (true, query.clone(), command_start + 2))
    } else {
        if known_bijux_tool_by_query(first).is_some() || resolve_runtime_command(first).is_some() {
            Some((false, first.clone(), command_start + 1))
        } else {
            None
        }
    }
}

fn render_embedded_descriptor_help(command_surface: &str, resolved: &ResolvedAppCommand) -> String {
    let aliases =
        resolved.descriptor.aliases.iter().map(|alias| alias.0.as_str()).collect::<Vec<_>>();
    let alias_line = if aliases.is_empty() {
        String::new()
    } else {
        format!("\nAliases:\n  {}\n", aliases.join(", "))
    };
    let version_line = resolved
        .descriptor
        .version
        .as_ref()
        .map(|value| format!("\nVersion:\n  {value}\n"))
        .unwrap_or_default();
    let capabilities = if resolved.descriptor.capabilities.is_empty() {
        "  (none)\n".to_string()
    } else {
        format!("  {}\n", resolved.descriptor.capabilities.join(", "))
    };

    format!(
        "Usage: {command_surface} [status|version|--help]\n\n{}\n{}\nCapabilities:\n{}{}",
        resolved.descriptor.help.summary,
        alias_line.trim_end(),
        capabilities,
        version_line
    )
}

fn run_embedded_descriptor_shell(
    resolved: &ResolvedAppCommand,
    command_surface: &str,
    forwarded_args: &[String],
) -> AppRunResult {
    let first = forwarded_args.first().map(String::as_str);
    if forwarded_args.iter().any(|arg| matches!(arg.as_str(), "--help" | "-h"))
        || matches!(first, Some("help"))
    {
        return AppRunResult {
            exit_code: 0,
            stdout: format!(
                "{}\n",
                render_embedded_descriptor_help(command_surface, resolved).trim_end()
            ),
            stderr: String::new(),
        };
    }

    if matches!(first, Some("version")) {
        let version = resolved
            .descriptor
            .version
            .clone()
            .unwrap_or_else(|| format!("{} embedded", resolved.namespace));
        return AppRunResult {
            exit_code: 0,
            stdout: format!("{version}\n"),
            stderr: String::new(),
        };
    }

    if forwarded_args.is_empty() || matches!(first, Some("status")) {
        let payload = json!({
            "status": "ok",
            "namespace": resolved.namespace,
            "mode": "embedded_rust",
            "handler": resolved.command,
            "summary": resolved.descriptor.help.summary,
            "capabilities": resolved.descriptor.capabilities,
        });
        return AppRunResult {
            exit_code: 0,
            stdout: format!(
                "{}\n",
                serde_json::to_string_pretty(&payload).unwrap_or_else(|_| payload.to_string())
            ),
            stderr: String::new(),
        };
    }

    AppRunResult {
        exit_code: 2,
        stdout: String::new(),
        stderr: format!(
            "embedded handler `{}` for `{command_surface}` does not support `{}`\n",
            resolved.command,
            forwarded_args.join(" ")
        ),
    }
}

fn delegate_to_embedded_handler(
    resolved: &ResolvedAppCommand,
    command_surface: &str,
    forwarded_args: &[String],
) -> AppRunResult {
    match resolved.command.as_str() {
        "descriptor-shell" => {
            run_embedded_descriptor_shell(resolved, command_surface, forwarded_args)
        }
        other => AppRunResult {
            exit_code: 2,
            stdout: String::new(),
            stderr: format!(
                "embedded handler `{other}` for `{command_surface}` is not registered\n"
            ),
        },
    }
}

fn delegate_to_resolved_command(
    resolved: &ResolvedAppCommand,
    install_commands: &[String],
    public_help_binary: Option<&str>,
    command_surface: &str,
    forwarded_args: &[String],
) -> AppRunResult {
    if matches!(resolved.kind, ProductEntrypointKind::EmbeddedRust) {
        return delegate_to_embedded_handler(resolved, command_surface, forwarded_args);
    }

    match Command::new(&resolved.command).args(&resolved.args).args(forwarded_args).output() {
        Ok(output) => AppRunResult {
            exit_code: output.status.code().unwrap_or(1),
            stdout: String::from_utf8_lossy(&output.stdout).into_owned(),
            stderr: String::from_utf8_lossy(&output.stderr).into_owned(),
        },
        Err(error) => {
            let mut message = format!(
                "failed to run `{command_surface}` via `{}`: {error}\n",
                resolved.display_command
            );
            if !install_commands.is_empty() {
                message.push_str("install with:\n");
                for command in install_commands {
                    message.push_str(&format!("  {command}\n"));
                }
            }
            if let Some(public_help_binary) = public_help_binary {
                message.push_str(&format!(
                    "use `{public_help_binary} --help` for the public command surface\n"
                ));
            }
            AppRunResult { exit_code: 1, stdout: String::new(), stderr: message }
        }
    }
}

fn install_commands_for_known_tool(tool: &KnownBijuxTool, control_plane: bool) -> Vec<String> {
    let package_name =
        if control_plane { tool.control_package_name } else { tool.runtime_package_name };
    match tool.language {
        "python" => vec![format!("pip install {package_name}")],
        _ => vec![format!("cargo install {package_name}")],
    }
}

fn delegated_known_bijux_tool_command(argv: &[String]) -> Option<DelegatedKnownToolCommand> {
    let (control_plane, query, forwarded_start) = locate_known_tool_route(argv)?;

    if control_plane {
        let tool = known_bijux_tool_by_query(&query)?;
        Some(DelegatedKnownToolCommand {
            resolved: resolve_control_command(&query).unwrap_or_else(|| ResolvedAppCommand {
                command: tool.control_binary(),
                args: Vec::new(),
                display_command: tool.control_binary(),
                source: crate::features::apps::AppDiscoverySource::CompiledOfficialRegistry,
                kind: ProductEntrypointKind::Binary,
                namespace: tool.namespace.to_string(),
                descriptor: tool.descriptor(),
            }),
            install_commands: install_commands_for_known_tool(tool, true),
            public_help_binary: None,
            command_surface: format!("bijux dev {}", tool.namespace),
            forwarded_args: argv[forwarded_start..].to_vec(),
        })
    } else {
        let tool = known_bijux_tool_by_query(&query);
        let resolved = if let Some(tool) = known_bijux_tool_by_query(&query) {
            resolve_runtime_command(&query).unwrap_or_else(|| ResolvedAppCommand {
                command: tool.runtime_binary(),
                args: Vec::new(),
                display_command: tool.runtime_binary(),
                source: crate::features::apps::AppDiscoverySource::CompiledOfficialRegistry,
                kind: ProductEntrypointKind::Binary,
                namespace: tool.namespace.to_string(),
                descriptor: tool.descriptor(),
            })
        } else {
            resolve_runtime_command(&query)?
        };
        Some(DelegatedKnownToolCommand {
            command_surface: format!("bijux {}", resolved.namespace),
            install_commands: tool
                .map(|tool| install_commands_for_known_tool(tool, false))
                .unwrap_or_default(),
            public_help_binary: tool.map(|tool| tool.runtime_binary_name.to_string()),
            resolved,
            forwarded_args: argv[forwarded_start..].to_vec(),
        })
    }
}

pub(super) fn is_known_bijux_tool_route(path: &[String]) -> bool {
    match path {
        [dev, namespace, ..] => dev == "dev" && known_bijux_tool_by_query(namespace).is_some(),
        [namespace, ..] => resolve_runtime_command(namespace).is_some(),
        [] => false,
    }
}

pub(super) fn delegated_command_surface(argv: &[String]) -> Option<String> {
    delegated_known_bijux_tool_command(argv).map(|command| command.command_surface)
}

pub(super) fn try_delegate_known_bijux_tool(argv: &[String]) -> Option<AppRunResult> {
    let command = delegated_known_bijux_tool_command(argv)?;
    Some(delegate_to_resolved_command(
        &command.resolved,
        &command.install_commands,
        command.public_help_binary.as_deref(),
        &command.command_surface,
        &command.forwarded_args,
    ))
}