Skip to main content

systemprompt_cli/commands/core/content/
mod.rs

1pub mod analytics;
2pub mod delete;
3pub mod delete_source;
4mod edit;
5pub mod files;
6pub mod ingest;
7pub mod link;
8pub mod list;
9pub mod popular;
10pub mod publish;
11pub mod search;
12pub mod show;
13pub mod status;
14pub mod types;
15pub mod verify;
16
17use crate::cli_settings::{get_global_config, CliConfig};
18use crate::shared::render_result;
19use anyhow::{bail, Context, Result};
20use clap::Subcommand;
21use systemprompt_runtime::DatabaseContext;
22
23#[derive(Debug, Subcommand)]
24pub enum ContentCommands {
25    #[command(about = "List content with pagination")]
26    List(list::ListArgs),
27
28    #[command(about = "Show content details")]
29    Show(show::ShowArgs),
30
31    #[command(about = "Search content")]
32    Search(search::SearchArgs),
33
34    #[command(about = "Ingest markdown files from directory")]
35    Ingest(ingest::IngestArgs),
36
37    #[command(about = "Edit content fields")]
38    Edit(edit::EditArgs),
39
40    #[command(about = "Delete content by ID")]
41    Delete(delete::DeleteArgs),
42
43    #[command(name = "delete-source", about = "Delete all content from a source")]
44    DeleteSource(delete_source::DeleteSourceArgs),
45
46    #[command(about = "Get popular content")]
47    Popular(popular::PopularArgs),
48
49    #[command(about = "Verify content is published and accessible")]
50    Verify(verify::VerifyArgs),
51
52    #[command(about = "Show content health status for a source")]
53    Status(status::StatusArgs),
54
55    #[command(subcommand, about = "Link generation and management")]
56    Link(link::LinkCommands),
57
58    #[command(subcommand, about = "Content analytics")]
59    Analytics(analytics::AnalyticsCommands),
60
61    #[command(subcommand, about = "Content-file operations (link, unlink, featured)")]
62    Files(files::ContentFilesCommands),
63
64    #[command(about = "Publish static content (ingest, prerender, sitemap)")]
65    Publish(publish::PublishArgs),
66
67    #[command(about = "Alias for publish", hide = true)]
68    Generate(publish::PublishArgs),
69}
70
71pub async fn execute(command: ContentCommands) -> Result<()> {
72    let config = get_global_config();
73    execute_with_config(command, &config).await
74}
75
76pub async fn execute_with_config(command: ContentCommands, config: &CliConfig) -> Result<()> {
77    match command {
78        ContentCommands::List(args) => {
79            let result = list::execute(args, config)
80                .await
81                .context("Failed to list content")?;
82            render_result(&result);
83        },
84        ContentCommands::Show(args) => {
85            let result = show::execute(args, config)
86                .await
87                .context("Failed to show content")?;
88            render_result(&result);
89        },
90        ContentCommands::Search(args) => {
91            let result = search::execute(args, config)
92                .await
93                .context("Failed to search content")?;
94            render_result(&result);
95        },
96        ContentCommands::Ingest(args) => {
97            let result = ingest::execute(args, config)
98                .await
99                .context("Failed to ingest content")?;
100            match result {
101                ingest::IngestResult::Single(r) => render_result(&r),
102                ingest::IngestResult::All(r) => render_result(&r),
103            }
104        },
105        ContentCommands::Edit(args) => {
106            let result = edit::execute(args, config)
107                .await
108                .context("Failed to edit content")?;
109            render_result(&result);
110        },
111        ContentCommands::Delete(args) => {
112            let result = delete::execute(args, config)
113                .await
114                .context("Failed to delete content")?;
115            render_result(&result);
116        },
117        ContentCommands::DeleteSource(args) => {
118            let result = delete_source::execute(args, config)
119                .await
120                .context("Failed to delete source content")?;
121            render_result(&result);
122        },
123        ContentCommands::Popular(args) => {
124            let result = popular::execute(args, config)
125                .await
126                .context("Failed to get popular content")?;
127            render_result(&result);
128        },
129        ContentCommands::Verify(args) => {
130            let result = verify::execute(args, config)
131                .await
132                .context("Failed to verify content")?;
133            render_result(&result);
134        },
135        ContentCommands::Status(args) => {
136            let result = status::execute(args, config)
137                .await
138                .context("Failed to get content status")?;
139            render_result(&result);
140        },
141        ContentCommands::Link(cmd) => {
142            link::execute(cmd, config).await?;
143        },
144        ContentCommands::Analytics(cmd) => {
145            analytics::execute(cmd, config).await?;
146        },
147        ContentCommands::Files(cmd) => {
148            files::execute(cmd, config).await?;
149        },
150        ContentCommands::Publish(args) | ContentCommands::Generate(args) => {
151            let result = publish::execute(args, config)
152                .await
153                .context("Failed to publish content")?;
154            render_result(&result);
155        },
156    }
157    Ok(())
158}
159
160pub async fn execute_with_db(
161    command: ContentCommands,
162    db_ctx: &DatabaseContext,
163    config: &CliConfig,
164) -> Result<()> {
165    match command {
166        ContentCommands::List(args) => {
167            let result = list::execute_with_pool(args, db_ctx.db_pool(), config)
168                .await
169                .context("Failed to list content")?;
170            render_result(&result);
171        },
172        ContentCommands::Show(args) => {
173            let result = show::execute_with_pool(args, db_ctx.db_pool(), config)
174                .await
175                .context("Failed to show content")?;
176            render_result(&result);
177        },
178        ContentCommands::Search(args) => {
179            let result = search::execute_with_pool(args, db_ctx.db_pool(), config)
180                .await
181                .context("Failed to search content")?;
182            render_result(&result);
183        },
184        ContentCommands::Popular(args) => {
185            let result = popular::execute_with_pool(args, db_ctx.db_pool(), config)
186                .await
187                .context("Failed to get popular content")?;
188            render_result(&result);
189        },
190        ContentCommands::Status(args) => {
191            let result = status::execute_with_pool(args, db_ctx.db_pool(), config)
192                .await
193                .context("Failed to get content status")?;
194            render_result(&result);
195        },
196        ContentCommands::Analytics(cmd) => {
197            analytics::execute_with_pool(cmd, db_ctx.db_pool(), config).await?;
198        },
199        ContentCommands::Ingest(_)
200        | ContentCommands::Edit(_)
201        | ContentCommands::Delete(_)
202        | ContentCommands::DeleteSource(_)
203        | ContentCommands::Verify(_)
204        | ContentCommands::Link(_)
205        | ContentCommands::Files(_)
206        | ContentCommands::Publish(_)
207        | ContentCommands::Generate(_) => {
208            bail!("This content command requires full profile context")
209        },
210    }
211    Ok(())
212}