Skip to main content

systemprompt_cli/commands/core/files/
mod.rs

1//! `core files` command group: manage stored file uploads.
2//!
3//! Dispatches the [`FilesCommands`] subcommands — list/show/search/stats,
4//! upload/delete, validate/config, and the `ai` sub-group. On a
5//! `--database-url` invocation only the read-only commands are served; upload,
6//! delete, validate, config, and ai require a full profile context.
7//!
8//! Copyright (c) systemprompt.io — Business Source License 1.1.
9//! See <https://systemprompt.io> for licensing details.
10
11pub mod types;
12
13mod config;
14pub mod delete;
15mod list;
16mod search;
17mod show;
18mod stats;
19pub mod upload;
20mod validate;
21
22pub mod ai;
23
24use anyhow::{Context, Result, bail};
25use clap::Subcommand;
26
27use crate::context::CommandContext;
28use crate::shared::render_result;
29
30#[derive(Debug, Subcommand)]
31pub enum FilesCommands {
32    #[command(about = "List files with pagination and filtering")]
33    List(list::ListArgs),
34
35    #[command(about = "Show detailed file information")]
36    Show(show::ShowArgs),
37
38    #[command(about = "Upload a file from the local filesystem")]
39    Upload(upload::UploadArgs),
40
41    #[command(about = "Delete a file")]
42    Delete(delete::DeleteArgs),
43
44    #[command(about = "Validate a file before upload")]
45    Validate(validate::ValidateArgs),
46
47    #[command(about = "Show file upload configuration")]
48    Config(config::ConfigArgs),
49
50    #[command(about = "Search files by path pattern")]
51    Search(search::SearchArgs),
52
53    #[command(about = "Show file storage statistics")]
54    Stats(stats::StatsArgs),
55
56    #[command(subcommand, about = "AI-generated images operations")]
57    Ai(ai::AiCommands),
58}
59
60pub async fn execute(cmd: FilesCommands, ctx: &CommandContext) -> Result<()> {
61    if ctx.is_database_scoped()
62        && matches!(
63            cmd,
64            FilesCommands::Upload(_)
65                | FilesCommands::Delete(_)
66                | FilesCommands::Validate(_)
67                | FilesCommands::Config(_)
68                | FilesCommands::Ai(_)
69        )
70    {
71        bail!("This files command requires full profile context");
72    }
73
74    match cmd {
75        FilesCommands::List(args) => {
76            let result = list::execute(args, ctx)
77                .await
78                .context("Failed to list files")?;
79            render_result(&result, &ctx.cli);
80            Ok(())
81        },
82        FilesCommands::Show(args) => {
83            let result = show::execute(args, ctx)
84                .await
85                .context("Failed to show file")?;
86            render_result(&result, &ctx.cli);
87            Ok(())
88        },
89        FilesCommands::Upload(args) => {
90            let result = upload::execute(args, &ctx.cli)
91                .await
92                .context("Failed to upload file")?;
93            render_result(&result, &ctx.cli);
94            Ok(())
95        },
96        FilesCommands::Delete(args) => {
97            let result = delete::execute(args, ctx.prompter(), &ctx.cli)
98                .await
99                .context("Failed to delete file")?;
100            render_result(&result, &ctx.cli);
101            Ok(())
102        },
103        FilesCommands::Validate(args) => {
104            let result = validate::execute(&args, &ctx.cli).context("Failed to validate file")?;
105            render_result(&result, &ctx.cli);
106            Ok(())
107        },
108        FilesCommands::Config(args) => {
109            let result = config::execute(args, &ctx.cli).context("Failed to get file config")?;
110            render_result(&result, &ctx.cli);
111            Ok(())
112        },
113        FilesCommands::Search(args) => {
114            let result = search::execute(args, ctx)
115                .await
116                .context("Failed to search files")?;
117            render_result(&result, &ctx.cli);
118            Ok(())
119        },
120        FilesCommands::Stats(args) => {
121            let result = stats::execute(args, ctx)
122                .await
123                .context("Failed to get file stats")?;
124            render_result(&result, &ctx.cli);
125            Ok(())
126        },
127        FilesCommands::Ai(cmd) => ai::execute(cmd, &ctx.cli).await,
128    }
129}