feat(cli): add cli subcommands - #1680
Conversation
Attachment is about to be exposed through the CLI's --json output. Give it explicit snake_case field names and exclude the raw Data bytes so scripted consumers never receive megabytes of base64.
Expose provider search through the service layer: a Search method on daemonclient.Service (daemon and direct implementations), a Search RPC method with handler, and NewCLIClient(cfg, autoStart) so one-shot CLI invocations can fall back to direct mode instead of forking a daemon. The mark-read handler previously logged per-UID failures but reported success over RPC; it now joins and returns them, matching the other mutating handlers and direct-mode semantics.
Round out the non-interactive CLI beyond send: list a folder, read a message body (with --json attachment metadata), search with the same query DSL the TUI uses, list folders, and manage mail (archive, delete, mark-read, mark-unread, move). Shared plumbing lives in cli/util.go: account resolution by --from (case-insensitive on Email with a FetchEmail fallback), tabular and JSON email rendering, folder-name normalization, and interspersed flag parsing so flags may follow positionals. Commands write through hookable Out/ErrOut writers, which the existing contacts-export, config, and upgrade commands now also use for package consistency. All commands connect with autoStart disabled: a one-shot invocation uses a running daemon when present and otherwise falls back to a direct connection rather than spawning a daemon.
Route folders, list, read, search, archive, delete, mark-read, mark-unread and move through the cli package; errors print to stderr and exit 1.
|
This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR might be rejected due to its size. |
floatpanebot
left a comment
There was a problem hiding this comment.
Hi @Robin-Everaars! Please fix the following issues with your PR:
- Title: Is too long (76 characters). The PR title must be strictly under 40 characters.
Benchmark report — no significant changeMetrics worse: 0 · better: 0 (threshold: ±3%). benchstat outputauto-generated by benchmarks.yml |
floatpanebot
left a comment
There was a problem hiding this comment.
Hi @Robin-Everaars! Please fix the following issues with your PR:
- Title: Is too long (42 characters). The PR title must be strictly under 40 characters.
Formatting issues have been resolved. Thank you!
|
I've seen the linting issues. I'll work on them later today (thought I could quickly open the PR in between other things). |
Address the golangci-lint findings on the new CLI files: - errcheck: route CLI stdout/stderr writes through fprintln/fprintf/ fprint helpers that discard the unactionable write error, and check the previously-ignored fs.Parse and svc.Close returns. - goconst: hoist the repeated "INBOX" and management subcommand names into constants. - gocritic (unlambda): assign daemonclient.NewCLIClient directly instead of wrapping it in a pass-through closure. - revive (blank-imports): justify the i18n/languages blank import. No behaviour change; build and tests remain green.
|
This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR might be rejected due to its size. |
|
@Robin-Everaars this PR is way too big and will not backport to v1 automatically, requiring the team to remake this change on Please, remake this PR on |
|
@andrinoff understood, I'll have a go at it sometime soon. Otherwise happy with the general direction? |
|
And I'll close this PR to create several smaller, separate new PRs later |
What?
Adds a non-interactive CLI to Matcha so mail can be handled from scripts and one-off commands without entering the TUI. New subcommands:
list <folder>: list messages in a folder (tabular, or--json)read <uid>: print a message body;--jsonincludes attachment metadatasearch <query>: search using the same query DSL the TUI usesfolders: list available foldersarchive,delete,mark-read,mark-unread,moveSupporting changes:
SearchRPC (service method + handler).NewCLIClient(cfg, autoStart)lets a one-shot invocation use a running daemon when present and otherwise fall back to a direct connection, rather than forking a daemon.Attachmentgains explicit snake_case JSON tags and excludes the rawDatabytes, so scripted--jsonconsumers never receive megabytes of base64.mark-readhandler previously logged per-UID failures but reported success over RPC; it now joins and returns them, matching the other mutating handlers and direct-mode semantics.Out/ErrOutwriters; the existingcontacts-export,config, andupgradecommands were moved onto the same writers for consistency and testability. Shared plumbing (account resolution by--from, tabular/JSON rendering, folder-name normalization, interspersed flag parsing) lives incli/util.go.Every new command ships with unit tests.
Why?
Matcha is TUI-only today, which makes it awkward to use from scripts, cron jobs, or other tooling. The CLI docs already promise these commands "work without launching the TUI and are ideal for scripts, cron jobs, and AI agent integration," but on the mail side only
matcha sendwas actually exposed. This closes that gap: the core mailbox operations (list / read / search / folders, plus manage) become non-interactive subcommands, making Matcha scriptable and composable with the rest of a shell workflow, while reusing the existing daemon and query DSL so behaviour stays consistent with the TUI.Closes #1642.