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