Skip to main content

clickup_cli/commands/
attachment.rs

1use crate::client::ClickUpClient;
2use crate::commands::auth::resolve_token;
3use crate::error::CliError;
4use crate::git;
5use crate::output::OutputConfig;
6use crate::Cli;
7use clap::Subcommand;
8
9#[derive(Subcommand)]
10pub enum AttachmentCommands {
11    /// Upload a file attachment to a task
12    Upload {
13        /// Path to the file to upload
14        file: std::path::PathBuf,
15        /// Task ID (auto-detected from git branch if omitted)
16        #[arg(long)]
17        task: Option<String>,
18    },
19    /// List attachments on a task (extracted from the Get Task response)
20    List {
21        /// Task ID (auto-detected from git branch if omitted)
22        #[arg(long)]
23        task: Option<String>,
24    },
25}
26
27const ATTACHMENT_FIELDS: &[&str] = &["id", "title", "url", "date"];
28
29pub async fn execute(command: AttachmentCommands, cli: &Cli) -> Result<(), CliError> {
30    let token = resolve_token(cli)?;
31    let client = ClickUpClient::new(&token, cli.timeout)?;
32    let output = OutputConfig::from_cli(&cli.output, &cli.fields, cli.no_header, cli.quiet);
33
34    match command {
35        AttachmentCommands::Upload { task, file } => {
36            let task = git::require_task(cli, task.as_deref(), true)?;
37            let resp = client
38                .upload_file(&format!("/v2/task/{}/attachment", task.id), &file)
39                .await?;
40            output.print_single(&resp, ATTACHMENT_FIELDS, "id");
41            Ok(())
42        }
43        AttachmentCommands::List { task } => {
44            // ClickUp has no dedicated list-attachments endpoint. The `attachments`
45            // array is returned inline by GET /v2/task/{id}, per the API docs.
46            let task = git::require_task(cli, task.as_deref(), true)?;
47            let resp = client.get(&format!("/v2/task/{}", task.id)).await?;
48            let attachments = resp
49                .get("attachments")
50                .and_then(|a| a.as_array())
51                .cloned()
52                .unwrap_or_default();
53            output.print_items(&attachments, ATTACHMENT_FIELDS, "id");
54            Ok(())
55        }
56    }
57}