agent-first-mail 0.3.0

Let your AI agent work your inbox — email pulled into plain files it reads, sorts, and drafts on your machine, with nothing sent until you confirm.
Documentation
use super::*;

pub(super) fn actions_for(
    root: &Path,
    config: &MailConfig,
    item: &PushItem,
) -> Result<Vec<String>> {
    if let Some(payload) = item.message_action() {
        return Ok(payload.steps.iter().map(step_label).collect());
    }
    if let Some(outbound) = item.outbound() {
        let steps = match outbound.action {
            OutboundAction::SaveDraft => &config.actions.draft_save.steps,
            OutboundAction::Send => &config.actions.draft_send.steps,
        };
        if !steps.is_empty() {
            return Ok(filter_reply_to_steps(root, item, steps.clone())?
                .iter()
                .map(step_label)
                .collect());
        }
        return Ok(match outbound.action {
            OutboundAction::Send => {
                vec![
                    "smtp_send".to_string(),
                    "append_to_mailbox_id_sent".to_string(),
                ]
            }
            OutboundAction::SaveDraft => vec!["append_to_mailbox_id_drafts".to_string()],
        });
    }
    Ok(Vec::new())
}

pub(super) fn item_summary_label(item: &PushItem) -> &str {
    match &item.payload {
        PushPayload::Outbound(_) => "drafts",
        PushPayload::MessageAction(payload) => payload.action.mode_label(),
    }
}

pub(super) fn step_label(step: &ActionStep) -> String {
    if !step.add_flags.is_empty() {
        let target = step.on.map(|on| format!(":{on:?}")).unwrap_or_default();
        return format!("add_flags{target}");
    }
    if let Some(mailbox_id) = &step.move_to_mailbox_id {
        return format!("move_to_mailbox_id_{mailbox_id}");
    }
    if let Some(mailbox_id) = &step.append_to_mailbox_id {
        return format!("append_to_mailbox_id_{mailbox_id}");
    }
    if step.smtp_send.is_some() {
        return "smtp_send".to_string();
    }
    "noop".to_string()
}