Skip to main content

systemprompt_cli/commands/plugins/capabilities/
templates.rs

1use clap::Args;
2
3use crate::CliConfig;
4use crate::commands::plugins::discover_registry;
5use crate::commands::plugins::types::{TemplateWithExtension, TemplatesListOutput};
6use crate::shared::CommandOutput;
7
8#[derive(Debug, Clone, Args)]
9pub struct TemplatesArgs {
10    #[arg(long, help = "Filter by extension ID")]
11    pub extension: Option<String>,
12}
13
14pub fn execute(args: &TemplatesArgs, _config: &CliConfig) -> CommandOutput {
15    let registry = discover_registry();
16
17    let templates: Vec<TemplateWithExtension> = 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            let ext_id = ext.id().to_owned();
23            let ext_name = ext.name().to_owned();
24
25            ext.template_providers()
26                .iter()
27                .flat_map(|provider| {
28                    provider
29                        .templates()
30                        .iter()
31                        .map(|t| (t.name.clone(), t.content_types.join(", ")))
32                        .collect::<Vec<_>>()
33                })
34                .map(|(name, desc)| TemplateWithExtension {
35                    extension_id: systemprompt_identifiers::PluginId::new(ext_id.clone()),
36                    extension_name: ext_name.clone(),
37                    template_name: name,
38                    description: desc,
39                })
40                .collect::<Vec<_>>()
41        })
42        .collect();
43
44    let total = templates.len();
45
46    let output = TemplatesListOutput { templates, total };
47
48    CommandOutput::table_of(
49        vec!["extension_id", "template_name", "description"],
50        &output.templates,
51    )
52    .with_title("Templates Across Extensions")
53}