fs-mail 2.3.0: everyday command reference
=======================================

The examples use the command fs-mail on PATH and a single account rooted at
~/email. Substitute your configured root. With named accounts, add -a NAME to
select one; otherwise ordinary runs process all configured accounts.

HELP

    fs-mail -h
    fs-mail --manual | less
    fs-mail --config-help | less

-h and --help are equivalent. The embedded manual and configuration catalog
work before setup and make no network connection or mail-state changes.

SET UP ONCE

    sh install.sh
    ~/.local/bin/fs-mail --init
    vi ~/.config/fs-mail/accounts.ini
    vi ~/.config/fs-mail/config.ini
    ~/.local/bin/fs-mail --check-config

--init creates config.ini for behavior and accounts.ini for account definitions,
plus inbox/outbox/drafts directories. It refuses to overwrite either INI.
Set the account's from address, root, and actual IMAP/SMTP settings in
accounts.ini. Put shared behavior defaults in config.ini's [mail] section.
--accounts FILE chooses a different account file; by default it is accounts.ini
beside the chosen -c FILE. Upgrading does not require --init.

Existing combined INIs remain usable. To split one while retaining an exact
private backup named config.ini.pre-split:

    fs-mail --migrate-config
    fs-mail --check-config

Migration does not connect, read passwords, or change the mail root or state.
An already split configuration is left as it is. See the full manual before
choosing alternate migration destinations or recovering interrupted migration.

The installed program is ~/.local/bin/fs-mail. Add ~/.local/bin to PATH if
you prefer the short command. The installed manpage is available through:

    man -M "$HOME/.local/share/man" fs-mail

INSPECT CONFIGURATION WITHOUT CONNECTING

    fs-mail --check-config
    fs-mail --show-config
    fs-mail --list-accounts
    fs-mail -c ~/.config/fs-mail/config.ini -a work --show-config

These commands do not create mail roots, open mail state, read passwords, or
run credential commands. --show-config emits JSON with credential commands
redacted. Hosts, usernames, and paths remain visible. It is an inspection
record, not an INI export. Unknown INI settings and sections are errors.

READ MAIL WITH A LIMITED DOWNLOAD PASS

    fs-mail --receive-only --set download_folders=INBOX \
        --set max_download_mb_per_run=25
    ls ~/email/inbox/
    less ~/email/inbox/message.txt

Replace message.txt with an actual listed filename. --receive-only downloads
without sending outbox mail or applying local moves, deletions, or flags to
IMAP. The example restricts new downloads to Inbox and a 25 MiB raw-message
payload budget for each account.

Current downloads retrieve whole messages, including attachments. The default
folder pattern is * and the default byte budget is unlimited. Header-only and
on-demand MIME-part downloads remain proposed; --download-folder and
--download-attachments are not current commands. Use supported settings shown
here to constrain actual download work. Protocol overhead is outside the
raw-message payload budget.

PREVIEW AND INSPECT LOCALLY

    fs-mail --status
    fs-mail -n
    fs-mail -n --send-only
    fs-mail -n --sync-only
    fs-mail -n --receive-only --set download_folders=INBOX

--status shows the queue, local IMAP differences, and stored holds. -n is
--dry-run: it also validates queued message content and attachment files.
Direction options restrict the inspection to outgoing or IMAP work. The
receive-only preview shows the configured policy without opening state or
creating roots; it cannot discover server messages while offline.

Ordinary local status/dry-run checks may update private recovery state and
error logs, and may restore an interrupted local file replacement. They do
not send mail or change the remote server.

COMPOSE AND SEND

Create ~/email/drafts/note.txt in a text editor. Its contents can be:

    To: recipient@example.net
    Cc:
    Bcc:
    Attachments: /home/user/Documents/report.pdf
    Subject: A short note

    Here is the report.

Use actual recipient addresses and an existing absolute attachment path.
Leave Attachments empty or omit it when no file is attached. To must be the
first line, Subject must be nonempty, and a blank line separates the headers
from the body. Cc, Bcc, and Attachments are optional after To.

When the draft is ready:

    mv ~/email/drafts/note.txt ~/email/outbox/
    fs-mail -n --send-only
    fs-mail --send-only

Moving a file into outbox authorizes sending on the next sending run, including
a scheduled one. Finish editing in drafts. Successful submission creates a
sent-local copy and removes the queued file. Unknown delivery stays held for
explicit resolution; renaming it does not authorize another submission.

REPLY

    export EDITOR='vi -n'
    fs-mail --reply ~/email/inbox/message.txt

The command prepares recipients, Subject, threading, and quoted text in a new
draft, then starts EDITOR. VISUAL is the next fallback, then vi and nano on
PATH. Editor values are parsed as arguments without a shell. Closing the
editor does not send or queue the reply. Move the finished draft to outbox.
Original attachments are not included automatically.
If a tracked view hides sender or threading fields, --reply can recover them
from that account's verified raw archive. Explicit visible fields take
precedence, and the quoted body keeps local text edits. Exported text files
need their own visible sender information.

FILE AND MARK RECEIVED MAIL

    mkdir -p ~/email/Archive
    mv ~/email/inbox/message.txt ~/email/Archive/
    fs-mail --status
    fs-mail --sync-only

Renames, folder moves, deletions, and Flags edits are compared with the saved
baseline and applied during a normal or --sync-only run. For example, edit
the received message's Flags line to:

    Flags: seen, flagged

Opening a file does not automatically mark it read. Preserve Local-ID,
Account-ID, and Raw-Message. Keep .fs-mail with the account when backing up.
Deleting a tracked message requests deletion from IMAP on the next sync.

CHOOSE THE RECEIVED HEADER LAYOUT

Set this in config.ini's [mail], or override it in an accounts.ini account:

    view_headers = To,From,Subject,Date,Attachments

It applies to newly received views. To must come first, Subject must remain,
and the mandatory Local-ID and Account-ID are appended if not listed. Existing
files retain their layout. The manual's RECEIVED HEADERS section explains all
selectable fields, including reply/threading fields and the raw-message path.

If Flags is omitted from new views, synchronization retains it in private state.
Add a Flags line to a message when you want to change its flags. Preserve an
existing tracked Flags line; deleting it is held as a conflict. Omitting
Attachments or Raw-Message does not avoid their downloads or storage.

CUSTOMIZE ONE RUN

    fs-mail -a work --receive-only --set max_messages_per_run=10
    fs-mail -a work --sync-only --set timeout=120
    fs-mail -a work --show-config --set 'filename_format={sender}_{date}_{id}.txt'

Repeat --set KEY=VALUE as needed; the last value for a key wins. The optional
mail. prefix works, for example --set mail.timeout=120. Settings apply to all
selected accounts. No INI file is changed. Precedence is:

    built-in defaults < shared [mail] < [account NAME] < --set

--config-help lists keys, ranges, and defaults. Account identity, root/from,
server credentials, and endpoints stay in the INI; they are not --set keys.
The dedicated --root DIR option remains available for one selected account.

For persistent download controls, use [mail] or [account NAME]:

    download_folders = INBOX, Archive
    download_exclude = Trash, Junk
    max_download_mb_per_run = 25

Folder patterns refer to remote IMAP names. Exclusions win. Existing local
files are kept, and normal synchronization still reconciles tracked mail in
excluded folders. Use --receive-only if the run must not mutate remote mail.

RUN FROM CRON OR A SUPERVISOR

Keep a configured private credential file for unattended use, or configure
an environment/command source. A missing credential file prompts in a terminal;
--non-interactive prevents prompting and reports a missing-source error.
Credential files must belong to your user and have mode 600.

A user crontab example, substituting the actual home path:

    */5 * * * * /home/user/.local/bin/fs-mail --non-interactive --quiet

A foreground watcher for a supervisor:

    fs-mail --non-interactive --watch 300

Watch mode reloads the INI and reapplies CLI settings. --watch with no interval
uses each account's poll_interval. An explicit interval overrides it. ChromeOS
must have its Linux environment running for this Linux process to run.

FIND ERRORS AND RESOLVE HOLDS

    fs-mail --status
    tail -n 40 ~/email/errors.log

Errors go to stderr and the selected account's errors.log. --quiet suppresses
routine progress. Resolve a reported SMTP JOB_ID only after checking delivery:

    fs-mail -a work --resolve JOB_ID --result sent
    fs-mail -a work --resolve JOB_ID --result retry

The first confirms known acceptance; the second explicitly authorizes a later
retry and can duplicate mail if the earlier delivery was actually accepted.
Do not use both as a sequence. For a reported IMAP Local-ID conflict, choose
one preference and then synchronize:

    fs-mail -a work --resolve-sync LOCAL_ID --prefer remote
    fs-mail -a work --sync-only

Use --prefer local to request the local state instead. The full manual explains
ambiguous MOVE recovery and other cases that remain held for verification.

COMMAND CONVENTIONS

- -c means --config; -a means --account; -n means --dry-run; -q means --quiet.
- --accounts chooses the account-definition file independently of -c.
- Repeat -a to select several accounts. With no selector, ordinary runs use all.
- Quote paths and --set values normally through the shell.
- Use complete long-option names. Unrecognized or incompatible options error.
- Routine output is on stdout; diagnostics are on stderr.
- Exit 0 means the requested action succeeded without a reported hold.
  Failures return nonzero; see the manual for the full exit-status list.
- The program is a command. Your editor, pager, scheduler, JSON tools, and
  file manager remain independent choices.
