Skip to content

FEAT: Round out the non-interactive CLI (read + manage mail, not just send) #1642

Description

@Robin-Everaars

Is your feature request related to a problem?

The CLI docs open with "these work without launching the TUI and are ideal for scripts, cron jobs, and AI agent integration," but on the mail side the only thing you can actually do non-interactively today is matcha send. Reading and managing mail still needs the TUI, so there's no way to script "list what's in this folder", "print this message", or "archive/mark these" without driving the interactive UI. That's the gap between what the docs promise and what's exposed.

Describe the solution you'd like

Expose the read and manage operations as subcommands, following the same pattern matcha send already uses. I'm filing this as one request rather than piecemeal because the groundwork is basically all there: the operations already exist as plain package-level functions in fetcher/ that take a *config.Account and run directly (no daemon needed), which is what runSendCLI calls today. For example:

  • fetcher.FetchFolders
  • fetcher.FetchFolderEmails / FetchFolderEmailBody
  • fetcher.MarkEmailAsReadInMailbox / MarkEmailAsUnreadInMailbox
  • fetcher.ArchiveEmailFromMailbox / DeleteEmailFromMailbox / MoveEmailsToFolder
  • fetcher.SearchMailbox

So a first cut is mostly flag parsing plus an output formatter. Rough shape, mirroring matcha send:

matcha folders [--account <email>]
matcha list    --folder INBOX [--account <email>] [--limit 50] [--offset 0]
matcha read    --folder INBOX --uid <n> [--account <email>]
matcha search  --folder INBOX --query "..." [--account <email>]
matcha mark-read | mark-unread --folder INBOX --uid <n> [--account <email>]
matcha archive | delete --folder INBOX --uid <n> [--account <email>]
matcha move    --uid <n> --from INBOX --to Archive [--account <email>]

A --json option on the read commands (list, read, folders, search) would make this genuinely usable from scripts and agents, which the docs already name as a goal. Default to a human-readable table, JSON when asked. Account selection could reuse the same --from matching send already has (login + fetch email).

Describe alternatives you've considered

Scripting the TUI with expect-style input (brittle, breaks on any UI change), or talking to the daemon socket directly (daemonrpc is internal and not a stable contract). Neither is a real substitute for first-class subcommands.

Additional context

runSendCLI in main.go is the template to copy (parse flags, LoadConfig, resolve account, call the fetcher/sender function, print), and new commands slot into cli/ next to config.go, contacts_export.go, dict.go, etc., wired through the os.Args dispatch in main(). matcha also has the daemonclient.Service interface (used by the TUI and daemon) wrapping these same operations mode-agnostically, if routing the CLI through that is preferred for daemon-awareness. Either way the underlying operations already exist, so this is mostly surface work.

Before I build anything though I'd like your read on it: is this something you'd want, and is the command/flag shape roughly right? If it looks good to you I'll take it on and open a PR.

Version: matcha 0.43.0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/buildBuild system / Makefile / packagingarea/cliCLI flags / commandsarea/configConfiguration / settingsarea/daemonDaemon / RPCarea/docsDocs site / READMEarea/fetcherIMAP fetch / IDLE / searcharea/senderSMTP send patharea/tuiTerminal UI / view layerciCI / build pipelinedocumentationDocumentation changes

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions