Skip to main content

systemprompt_cli/commands/core/contexts/
delete.rs

1//! `core contexts delete` command.
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6use anyhow::{Context, Result, bail};
7use clap::Args;
8use systemprompt_agent::repository::context::ContextRepository;
9use systemprompt_logging::CliService;
10
11use super::resolve::resolve_context;
12use super::types::ContextDeletedOutput;
13use crate::context::CommandContext;
14use crate::session::get_or_create_session;
15use crate::shared::CommandOutput;
16
17#[derive(Debug, Args)]
18pub struct DeleteArgs {
19    #[arg(help = "Context ID (full, partial prefix, or name)")]
20    pub context: String,
21
22    #[arg(short = 'y', long, help = "Skip confirmation prompt")]
23    pub yes: bool,
24}
25
26pub(super) async fn execute(args: DeleteArgs, ctx: &CommandContext) -> Result<CommandOutput> {
27    let session_ctx = get_or_create_session(ctx).await?;
28    let pool = ctx.db_pool().await?;
29    execute_with_pool(args, &session_ctx.session, &pool, &ctx.cli, ctx.prompter()).await
30}
31
32pub async fn execute_with_pool(
33    args: DeleteArgs,
34    session: &systemprompt_cloud::CliSession,
35    pool: &systemprompt_database::DbPool,
36    config: &crate::cli_settings::CliConfig,
37    prompter: &dyn crate::interactive::Prompter,
38) -> Result<CommandOutput> {
39    let repo = ContextRepository::new(pool)?;
40
41    let context_id = resolve_context(&args.context, &session.user_id, &repo).await?;
42
43    if context_id == session.context_id {
44        bail!(
45            "Cannot delete the active context. Switch to a different context first with 'contexts \
46             use <id>'."
47        );
48    }
49
50    let context = repo
51        .get_context(&context_id, &session.user_id)
52        .await
53        .context("Failed to fetch context details")?;
54
55    if !args.yes && config.is_interactive() {
56        CliService::warning(&format!(
57            "You are about to delete context '{}' ({})",
58            context.name,
59            context_id.as_str()
60        ));
61
62        if !prompter.confirm("Are you sure?", false)? {
63            CliService::info("Deletion cancelled");
64            let cancelled = ContextDeletedOutput {
65                id: context_id,
66                message: "Deletion cancelled".to_owned(),
67            };
68            return Ok(CommandOutput::card_value(
69                "Context Delete Cancelled",
70                &cancelled,
71            ));
72        }
73    }
74
75    repo.delete_context(&context_id, &session.user_id)
76        .await
77        .context("Failed to delete context")?;
78
79    let output = ContextDeletedOutput {
80        id: context_id.clone(),
81        message: format!("Context '{}' deleted successfully", context.name),
82    };
83
84    if !config.is_json_output() {
85        CliService::success(&output.message);
86    }
87
88    Ok(CommandOutput::card_value("Context Deleted", &output))
89}