Skip to main content

systemprompt_cli/commands/plugins/capabilities/
roles.rs

1use clap::Args;
2
3use crate::CliConfig;
4use crate::commands::plugins::discover_registry;
5use crate::commands::plugins::types::{RoleWithExtension, RolesListOutput};
6use crate::shared::CommandOutput;
7
8#[derive(Debug, Clone, Args)]
9pub struct RolesArgs {
10    #[arg(long, help = "Filter by extension ID")]
11    pub extension: Option<String>,
12}
13
14pub fn execute(args: &RolesArgs, _config: &CliConfig) -> CommandOutput {
15    let registry = discover_registry();
16
17    let roles: Vec<RoleWithExtension> = registry
18        .extensions()
19        .iter()
20        .filter(|ext| args.extension.as_ref().is_none_or(|f| ext.id().contains(f)))
21        .flat_map(|ext| {
22            ext.roles()
23                .iter()
24                .map(|role| RoleWithExtension {
25                    extension_id: systemprompt_identifiers::PluginId::new(ext.id()),
26                    extension_name: ext.name().to_owned(),
27                    role_name: role.name.clone(),
28                    display_name: role.display_name.clone(),
29                    description: role.description.clone(),
30                    permissions: role.permissions.clone(),
31                })
32                .collect::<Vec<_>>()
33        })
34        .collect();
35
36    let total = roles.len();
37
38    let output = RolesListOutput { roles, total };
39
40    CommandOutput::table_of(
41        vec!["extension_id", "role_name", "display_name", "description"],
42        &output.roles,
43    )
44    .with_title("Roles Across Extensions")
45}