Skip to main content

systemprompt_cli/commands/admin/
mod.rs

1//! `admin` command tree: privileged platform administration.
2//!
3//! [`AdminCommands`] groups user, agent, configuration, session, bridge,
4//! access-control, and signing-key management plus the setup and bootstrap
5//! flows. [`execute`] dispatches commands that resolve their own context;
6//! [`execute_with_db`] serves the subset that requires a shared
7//! [`systemprompt_runtime::DatabaseContext`].
8
9pub mod access_control;
10pub mod agents;
11pub mod bootstrap;
12pub mod bridge;
13pub mod config;
14pub mod keys;
15pub mod session;
16pub mod setup;
17pub mod users;
18
19use anyhow::Result;
20use clap::Subcommand;
21use systemprompt_runtime::DatabaseContext;
22
23use crate::CliConfig;
24use crate::shared::render_result;
25
26#[derive(Debug, Subcommand)]
27pub enum AdminCommands {
28    #[command(subcommand, about = "User management and IP banning")]
29    Users(users::UsersCommands),
30
31    #[command(subcommand, about = "Agent management")]
32    Agents(agents::AgentsCommands),
33
34    #[command(subcommand, about = "Configuration management and rate limits")]
35    Config(config::ConfigCommands),
36
37    #[command(about = "Interactive setup wizard for local development environment")]
38    Setup(setup::SetupArgs),
39
40    #[command(
41        about = "Idempotently ensure the platform admin user exists with the admin role. Required \
42                 by every install recipe before services start."
43    )]
44    Bootstrap(bootstrap::BootstrapArgs),
45
46    #[command(subcommand, about = "Manage CLI session and profile switching")]
47    Session(session::SessionCommands),
48
49    #[command(
50        subcommand,
51        about = "Bridge helper enrollment (device certs, exchange codes)"
52    )]
53    Bridge(bridge::BridgeCommands),
54
55    #[command(
56        subcommand,
57        name = "access-control",
58        about = "Access-control baseline operations (DB → YAML export)"
59    )]
60    AccessControl(access_control::AccessControlCommands),
61
62    #[command(
63        subcommand,
64        about = "RSA signing-key generation for the federated JWT plane"
65    )]
66    Keys(keys::KeysCommands),
67}
68
69pub async fn execute(cmd: AdminCommands, config: &CliConfig) -> Result<()> {
70    match cmd {
71        AdminCommands::Users(cmd) => users::execute(cmd, config).await,
72        AdminCommands::Agents(cmd) => agents::execute(cmd).await,
73        AdminCommands::Config(cmd) => config::execute(cmd, config).await,
74        AdminCommands::Setup(args) => {
75            let result = setup::execute(args, config).await?;
76            render_result(&result);
77            Ok(())
78        },
79        AdminCommands::Bootstrap(args) => {
80            let result = bootstrap::execute(args, config).await?;
81            render_result(&result);
82            Ok(())
83        },
84        AdminCommands::Session(cmd) => session::execute(cmd, config).await,
85        AdminCommands::Bridge(cmd) => bridge::execute(cmd, config).await,
86        AdminCommands::AccessControl(cmd) => access_control::execute(cmd, config).await,
87        AdminCommands::Keys(cmd) => keys::execute(cmd).await,
88    }
89}
90
91pub async fn execute_with_db(
92    cmd: AdminCommands,
93    db_ctx: &DatabaseContext,
94    config: &CliConfig,
95) -> Result<()> {
96    match cmd {
97        AdminCommands::Users(cmd) => users::execute_with_db(cmd, db_ctx, config).await,
98        _ => anyhow::bail!("This command requires full profile context"),
99    }
100}