afmail CLI reference

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.

afmail is compiled from a closed cli-spec-v1 registry: one source for argv parsing, typed invocation values, which parameter combinations are legal, output contracts, and help. An invocation runs only when it matches exactly one registered combination.

Global arguments

AFDATA registers these itself, so the syntax in Commands leaves them out.

ArgumentWhereWhat it does
--helpevery commandEvery legal shape of that command, complete, plus its subcommands. JSON by default; --output plain for a terminal.
--versionafmail onlyName, version, and build identity as one protocol result.
--docsafmail onlyThis document, rendered from the registry.
--output <FORMAT>per output contractRender as json, yaml, plain (default json).
--output-to <DESTINATION>per output contractRoute results and diagnostics to split, stdout, stderr (default split).
--stdout-file <PATH>, --stderr-file <PATH>per output contractAppend that stream to a file instead.

Success output is protocol events, on those terms, unless a command’s own Output line says otherwise.

A shape is one legal set of arguments that may appear together, under a stable id. Where a command has more than one, each id is a heading below. --help returns them all at once, so discovering a command costs one call; there is no recursive mode across commands, and this document is that view.

Commands

afmail api export

Write the generated OpenAPI document and standalone JSON Schemas.

afmail api export [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--directory <DIR>] [--force]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--directoryDestination directory
--forceReplace existing generated files

afmail api serve

Serve the typed afmail HTTP API and its OpenAPI/JSON Schema documents.

afmail api serve [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--mode <local|lan>] [--port <PORT>] [--access-token-secret <SOURCE>]

Output: protocol events; --output json/yaml/plain (default json), --output-to stdout/stderr (default stdout); redirect with --stdout-file or --stderr-file.

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--modeNetwork exposure mode
--portTCP port. Use 0 to let the operating system choose an available port.
--access-token-secretBearer credential; falls back to AFMAIL_API_ACCESS_TOKEN_SECRET. (the value, or where to read it: env:NAME, file[+FORMAT]:PATH#DOT_PATH, literal:VALUE)

afmail case add

Add a message to this existing case.

afmail case add [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <MESSAGE_ID>... [--summary <TEXT>] [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
MESSAGE_IDMessage ids to add
--summaryShort summary for this message in the case
--reasonWhy this message belongs in this case; required by default

afmail case archive

Archive this active case.

afmail case archive [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
--reasonWhy this case is ready to archive; required by default

afmail case create

Create a new case and return its stable UID/ref.

afmail case create [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] --name <NAME> --group <GROUP> [--message <MESSAGE_ID>] [--summary <TEXT>] [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
--nameHuman-readable case name used in case.md and the directory suffix
--groupCase category/group, for example support, invoice, 客服, 发票, 合同, or 退款
--messageFirst message to add to the case
--summaryShort summary for the first message
--reasonWhy this case is being created

afmail case delete

Delete an empty case.

afmail case delete [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> [--allow-notes] [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
--allow-notesAlso delete notes.md when it contains user-authored notes
--reasonWhy this case should be deleted; required by default

afmail case draft attach

Copy or reference a file and add it to a draft’s attachments.

afmail case draft attach [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <DRAFT_NAME> <PATH>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
DRAFT_NAMEDraft markdown file under the case drafts directory
PATHLocal file path to attach

afmail case draft change

Change an existing editable draft in place.

case-draft-change-recipients-body — Keep or replace Cc and Bcc, with an optional inline body

afmail case draft change [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <DRAFT_NAME> [--subject <TEXT>] [--to <ADDRESS>...] [--identity <SLUG>] [--cc <ADDRESS>...] [--bcc <ADDRESS>...] [--body <TEXT>]

case-draft-change-recipients-body-file — Keep or replace Cc and Bcc, with the body read from a file

afmail case draft change [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <DRAFT_NAME> [--subject <TEXT>] [--to <ADDRESS>...] [--identity <SLUG>] [--cc <ADDRESS>...] [--bcc <ADDRESS>...] --body-file <PATH>

case-draft-change-clear-cc-body — Clear Cc and keep or replace Bcc, with an optional inline body

afmail case draft change [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <DRAFT_NAME> [--subject <TEXT>] [--to <ADDRESS>...] [--identity <SLUG>] --clear-cc [--bcc <ADDRESS>...] [--body <TEXT>]

case-draft-change-clear-cc-body-file — Clear Cc and keep or replace Bcc, with the body read from a file

afmail case draft change [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <DRAFT_NAME> [--subject <TEXT>] [--to <ADDRESS>...] [--identity <SLUG>] --clear-cc [--bcc <ADDRESS>...] --body-file <PATH>

case-draft-change-clear-bcc-body — Clear Bcc and keep or replace Cc, with an optional inline body

afmail case draft change [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <DRAFT_NAME> [--subject <TEXT>] [--to <ADDRESS>...] [--identity <SLUG>] [--cc <ADDRESS>...] --clear-bcc [--body <TEXT>]

case-draft-change-clear-bcc-body-file — Clear Bcc and keep or replace Cc, with the body read from a file

afmail case draft change [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <DRAFT_NAME> [--subject <TEXT>] [--to <ADDRESS>...] [--identity <SLUG>] [--cc <ADDRESS>...] --clear-bcc --body-file <PATH>

case-draft-change-clear-cc-bcc-body — Clear Cc and Bcc, with an optional inline body

afmail case draft change [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <DRAFT_NAME> [--subject <TEXT>] [--to <ADDRESS>...] [--identity <SLUG>] --clear-cc --clear-bcc [--body <TEXT>]

case-draft-change-clear-cc-bcc-body-file — Clear Cc and Bcc, with the body read from a file

afmail case draft change [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <DRAFT_NAME> [--subject <TEXT>] [--to <ADDRESS>...] [--identity <SLUG>] --clear-cc --clear-bcc --body-file <PATH>

Arguments across every shape above:

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
DRAFT_NAMEDraft markdown file under the case drafts directory
--subjectReplacement subject
--toReplacement To list; when provided it replaces all To recipients
--identityWorkspace identity slug to send as. Defaults to the configured default identity.
--ccReplacement Cc list; when provided it replaces all Cc recipients
--clear-ccClear all Cc recipients
--bccReplacement Bcc list; when provided it replaces all Bcc recipients
--clear-bccClear all Bcc recipients
--bodyReplacement draft body text
--body-filePath to a file whose contents replace the draft body

afmail case draft list

List local drafts with their current status.

afmail case draft list [--workspace <PATH>] [--log <startup|request|progress|retry>...] <CASE_REF>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix

afmail case draft new

Scaffold a new outbound draft (not a reply) in this case.

case-draft-new-to-inline-body — Visible recipient with an inline body or the default template

afmail case draft new [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> --to <ADDRESS>... --subject <TEXT> [--cc <ADDRESS>...] [--bcc <ADDRESS>...] [--identity <SLUG>] [--body <TEXT>]

case-draft-new-to-body-file — Visible recipient with the body read from a file

afmail case draft new [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> --to <ADDRESS>... --subject <TEXT> [--cc <ADDRESS>...] [--bcc <ADDRESS>...] [--identity <SLUG>] --body-file <PATH>

case-draft-new-bcc-only-inline-body — Only blind recipients, with an inline body or the default template

afmail case draft new [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> --subject <TEXT> [--cc <ADDRESS>...] --bcc <ADDRESS>... [--identity <SLUG>] [--body <TEXT>]

case-draft-new-bcc-only-body-file — Only blind recipients, with the body read from a file

afmail case draft new [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> --subject <TEXT> [--cc <ADDRESS>...] --bcc <ADDRESS>... [--identity <SLUG>] --body-file <PATH>

Arguments across every shape above:

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
--toRecipient address; repeat for more than one
--subjectDraft subject
--ccCc address; repeat for more than one
--bccBcc address; repeat for more than one
--identityWorkspace identity slug to send as. Defaults to the configured default identity.
--bodyDraft body text
--body-filePath to a file whose contents become the draft body

afmail case draft remove

Remove a local draft and any queued outbound item for it.

afmail case draft remove [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <DRAFT_NAME> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
DRAFT_NAMEDraft markdown file under the case drafts directory
--reasonWhy this draft should be removed; required by default

afmail case draft reply

Scaffold a reply draft to a message, prefilled and quoting the original.

case-draft-reply-inline-body — Body given inline, or left to the default reply template

afmail case draft reply [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <MESSAGE_ID> [--identity <SLUG>] [--all] [--bcc <ADDRESS>...] [--body <TEXT>]

case-draft-reply-body-file — Body read from a file; the inline –body is absent here

afmail case draft reply [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <MESSAGE_ID> [--identity <SLUG>] [--all] [--bcc <ADDRESS>...] --body-file <PATH>

Arguments across every shape above:

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
MESSAGE_IDMessage id in this case to reply to
--identityWorkspace identity slug to send as. Defaults to the configured default identity.
--allReply to all original recipients (To and Cc), not just the sender
--bccBcc address; repeat for more than one
--bodyDraft body text. Replaces the default reply template when provided.
--body-filePath to a file whose contents become the draft body

afmail case draft review

Open a review session for this draft.

afmail case draft review [--workspace <PATH>] [--log <startup|request|progress|retry>...] <CASE_REF> <DRAFT_NAME> [--mode <window|link|session>]

Output: protocol events; --output json/yaml/plain (default json), --output-to stdout/stderr (default stdout); redirect with --stdout-file or --stderr-file.

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
DRAFT_NAMEDraft markdown file under the case drafts directory
--modeHow this reaches the person: window a browser window is open on this machine; link the page is reachable from this machine’s network at the link URL; session the session is registered only; open it with afui session open or reach it through afui session serve. Falls back to AFUI_DELIVERY, then window

afmail case draft send

Queue this draft to be sent and recorded in the case after push succeeds.

afmail case draft send [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <DRAFT_NAME>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
DRAFT_NAMEDraft markdown file under the case drafts directory

afmail case draft show

Show an existing draft as a typed render document.

afmail case draft show [--workspace <PATH>] [--log <startup|request|progress|retry>...] <CASE_REF> <DRAFT_NAME>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
DRAFT_NAMEDraft markdown file under the case drafts directory

afmail case draft upload

Queue this draft to be uploaded to the remote Drafts mailbox.

afmail case draft upload [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <DRAFT_NAME>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
DRAFT_NAMEDraft markdown file under the case drafts directory

afmail case draft validate

Validate a draft under the case drafts directory.

afmail case draft validate [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <DRAFT_NAME>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
DRAFT_NAMEDraft markdown file under the case drafts directory

afmail case list

List compact case locators.

case-list-active — List active cases; this is the default

afmail case list [--workspace <PATH>] [--log <startup|request|progress|retry>...]

case-list-archived — List archived cases only

afmail case list [--workspace <PATH>] [--log <startup|request|progress|retry>...] --archived

case-list-all — List active and archived cases together

afmail case list [--workspace <PATH>] [--log <startup|request|progress|retry>...] --all

Arguments across every shape above:

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--archivedList archived cases instead of active cases
--allList active and archived cases together

afmail case merge

Merge another case into this case.

afmail case merge [--workspace <PATH>] [--log <startup|request|progress|retry>...] <CASE_REF> <OTHER_CASE_REF> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
OTHER_CASE_REFCase ref to merge into the primary case
--reasonWhy these cases should be merged; required by default

afmail case move

Move this case to another group.

afmail case move [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> --group <GROUP> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
--groupDestination group
--reasonWhy this group better represents the case; required by default

afmail case notes append

Append text to case notes markdown.

afmail case notes append [--workspace <PATH>] [--log <startup|request|progress|retry>...] <CASE_REF> [--request-id <ID>] --text <TEXT>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
--textMarkdown text to append

afmail case notes replace

Replace case notes markdown with text.

afmail case notes replace [--workspace <PATH>] [--log <startup|request|progress|retry>...] <CASE_REF> [--request-id <ID>] --text <TEXT>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
--textMarkdown text to write

afmail case notes show

Show case notes markdown.

afmail case notes show [--workspace <PATH>] [--log <startup|request|progress|retry>...] <CASE_REF>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix

afmail case remove

Remove one message from this case and return it to triage.

afmail case remove [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <MESSAGE_ID> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
MESSAGE_IDMessage id to remove
--reasonWhy this message does not belong in this case; required by default

afmail case rename

Rename this case’s human-readable name without changing its UID.

afmail case rename [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> --name <NAME> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
--nameNew human-readable case name
--reasonWhy this name better represents the case; required by default

afmail case review

Open a review session for this case, including editable notes.

afmail case review [--workspace <PATH>] [--log <startup|request|progress|retry>...] <CASE_REF> [--mode <window|link|session>]

Output: protocol events; --output json/yaml/plain (default json), --output-to stdout/stderr (default stdout); redirect with --stdout-file or --stderr-file.

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
--modeHow this reaches the person: window a browser window is open on this machine; link the page is reachable from this machine’s network at the link URL; session the session is registered only; open it with afui session open or reach it through afui session serve. Falls back to AFUI_DELIVERY, then window

afmail case set-summary

Set or replace one case entry summary.

afmail case set-summary [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <MESSAGE_ID> --summary <TEXT> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
MESSAGE_IDMessage id whose summary should be changed
--summaryNew summary text
--reasonWhy this summary is useful; required by default

afmail case show

Show the exact typed case collection document used by Markdown and Review.

afmail case show [--workspace <PATH>] [--log <startup|request|progress|retry>...] <CASE_REF>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix

afmail case suggestion clear

Clear exactly the current suggestion round.

afmail case suggestion clear [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> --agent-suggestion-uid <UID>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
--agent-suggestion-uidUID returned by the current suggestion set command

afmail case suggestion set

Replace the current suggestion and clear any human review of the prior round.

case-suggestion-set-archive — Suggest archiving this case

afmail case suggestion set [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> --case-review-base-hash <HASH> --reason <TEXT> [--confidence-percent <PERCENT>] --action archive

case-suggestion-set-unarchive — Suggest unarchiving this case into a group

afmail case suggestion set [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> --case-review-base-hash <HASH> --reason <TEXT> [--confidence-percent <PERCENT>] --action unarchive --group <GROUP>

case-suggestion-set-move — Suggest moving this case to another group

afmail case suggestion set [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> --case-review-base-hash <HASH> --reason <TEXT> [--confidence-percent <PERCENT>] --action move --group <GROUP>

case-suggestion-set-rename — Suggest renaming this case

afmail case suggestion set [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> --case-review-base-hash <HASH> --reason <TEXT> [--confidence-percent <PERCENT>] --action rename --name <NAME>

case-suggestion-set-tag — Suggest adding a tag

afmail case suggestion set [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> --case-review-base-hash <HASH> --reason <TEXT> [--confidence-percent <PERCENT>] --action tag --tag <TAG>

case-suggestion-set-untag — Suggest removing a tag

afmail case suggestion set [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> --case-review-base-hash <HASH> --reason <TEXT> [--confidence-percent <PERCENT>] --action untag --tag <TAG>

case-suggestion-set-trash — Suggest trashing every message in this case

afmail case suggestion set [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> --case-review-base-hash <HASH> --reason <TEXT> [--confidence-percent <PERCENT>] --action trash

case-suggestion-set-delete — Suggest deleting this case

afmail case suggestion set [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> --case-review-base-hash <HASH> --reason <TEXT> [--confidence-percent <PERCENT>] --action delete [--allow-notes]

Arguments across every shape above:

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
--case-review-base-hashCurrent hash returned by afmail case show
--reasonWhy this complete action is being suggested
--confidence-percentOptional confidence from 0 through 100
--actionThe complete action being suggested; it decides which other arguments apply
--groupDestination case group
--nameNew human-readable case name
--tagCase organization tag
--allow-notesAlso delete notes.md when it contains user-authored notes

afmail case tag

Add a case organization tag.

afmail case tag [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <TAG> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
TAGCase organization tag
--reasonWhy this tag is useful; required by default

afmail case trash

Move every message in this case to local trash and queue Trash moves.

afmail case trash [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
--reasonWhy this whole case should be discarded; required by default

afmail case unarchive

Move this archived case back to an active case group.

afmail case unarchive [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> --group <GROUP> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
--groupActive case group to unarchive into
--reasonWhy this case needs active attention again; required by default

afmail case untag

Remove a case organization tag.

afmail case untag [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CASE_REF> <TAG> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CASE_REFCase ref: cYYYYMMDDNNN or cYYYYMMDDNNN-any-suffix
TAGCase organization tag
--reasonWhy this tag should be removed; required by default

afmail config add

Add an element to a keyed list such as identities.

afmail config add [--workspace <PATH>] [--log <startup|request|progress|retry>...] <KEY> <SLUG> [<KEY=VALUE>...]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
KEYConfiguration key
SLUGStable slug identifying the element
KEY=VALUEElement field assignment

afmail config get

Get one config key.

afmail config get [--workspace <PATH>] [--log <startup|request|progress|retry>...] <KEY>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
KEYConfiguration key

afmail config remove

Remove a keyed-list element by its slug.

afmail config remove [--workspace <PATH>] [--log <startup|request|progress|retry>...] <KEY> <SLUG>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
KEYConfiguration key
SLUGSlug of the element to remove

afmail config set

Set one config key. Multiple values become an array for array keys.

afmail config set [--workspace <PATH>] [--log <startup|request|progress|retry>...] <KEY> [<VALUE>...]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
KEYConfiguration key
VALUEReplacement value; repeat for an array key

afmail config show

Show effective config after applying built-in defaults.

afmail config show [--workspace <PATH>] [--log <startup|request|progress|retry>...]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.

afmail contact create

Create a new contact record.

afmail contact create [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] --name <NAME> [--group <GROUP>] [--email <ADDRESS>...] [--phone <NUMBER>...] [--org <NAME>] [--role <ROLE>] [--tag <TAG>...] [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
--nameDisplay name for the contact
--groupGroup. Defaults to the configured default contact group.
--emailEmail address; repeat for more than one
--phonePhone number; repeat for more than one
--orgOrganization name
--roleRole or title
--tagTag; repeat for more than one
--reasonWhy this contact is being created; required by default

afmail contact delete

Delete a contact.

afmail contact delete [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CONTACT_REF> [--allow-notes] [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CONTACT_REFContact ref: pYYYYMMDDNNN or pYYYYMMDDNNN-any-suffix
--allow-notesAlso delete the contact body when it contains user-authored notes
--reasonWhy this contact should be deleted; required by default

afmail contact email add

Add an email address to the contact.

afmail contact email add [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CONTACT_REF> <EMAIL> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CONTACT_REFContact ref: pYYYYMMDDNNN or pYYYYMMDDNNN-any-suffix
EMAILEmail address to add
--reasonWhy this email should be associated with the contact; required by default

afmail contact email remove

Remove an email address from the contact.

afmail contact email remove [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CONTACT_REF> <EMAIL> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CONTACT_REFContact ref: pYYYYMMDDNNN or pYYYYMMDDNNN-any-suffix
EMAILEmail address to remove
--reasonWhy this email should be removed; required by default

afmail contact extract

Extract stub contacts from message senders not yet in the contact list.

contact-extract-triage — Extract from triage messages; this is the default source

afmail contact extract [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--group <GROUP>] [--from-triage]

contact-extract-case — Extract from one case’s messages

afmail contact extract [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--group <GROUP>] --from-case <CASE_REF>

contact-extract-all — Extract from every triage and case message

afmail contact extract [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--group <GROUP>] --all

Arguments across every shape above:

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--groupDestination group for created contacts. Defaults to contact.default_group.
--from-triageExtract from triage messages only
--from-caseExtract from a specific case’s messages
--allExtract from all triage and case messages

afmail contact list

List contacts, optionally filtered by group, tag, org, or role.

afmail contact list [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--group <GROUP>] [--tag <TAG>] [--org <NAME>] [--role <ROLE>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--groupFilter to a specific group
--tagFilter by tag
--orgFilter by organization
--roleFilter by role

afmail contact move

Move a contact to a different group.

afmail contact move [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CONTACT_REF> --group <GROUP> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CONTACT_REFContact ref: pYYYYMMDDNNN or pYYYYMMDDNNN-any-suffix
--groupDestination group
--reasonWhy this contact should move groups; required by default

afmail contact notes append

Append text to contact notes markdown.

afmail contact notes append [--workspace <PATH>] [--log <startup|request|progress|retry>...] <CONTACT_REF> [--request-id <ID>] --text <TEXT>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
CONTACT_REFContact ref: pYYYYMMDDNNN or pYYYYMMDDNNN-any-suffix
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
--textMarkdown text to append

afmail contact notes replace

Replace contact notes markdown with text.

afmail contact notes replace [--workspace <PATH>] [--log <startup|request|progress|retry>...] <CONTACT_REF> [--request-id <ID>] --text <TEXT>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
CONTACT_REFContact ref: pYYYYMMDDNNN or pYYYYMMDDNNN-any-suffix
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
--textMarkdown text to write

afmail contact notes show

Show the typed contact document with raw notes Markdown.

afmail contact notes show [--workspace <PATH>] [--log <startup|request|progress|retry>...] <CONTACT_REF>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
CONTACT_REFContact ref: pYYYYMMDDNNN or pYYYYMMDDNNN-any-suffix

afmail contact phone add

Add a phone number to the contact.

afmail contact phone add [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CONTACT_REF> <PHONE> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CONTACT_REFContact ref: pYYYYMMDDNNN or pYYYYMMDDNNN-any-suffix
PHONEPhone number to add
--reasonWhy this phone number should be associated with the contact; required by default

afmail contact phone remove

Remove a phone number from the contact.

afmail contact phone remove [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CONTACT_REF> <PHONE> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CONTACT_REFContact ref: pYYYYMMDDNNN or pYYYYMMDDNNN-any-suffix
PHONEPhone number to remove
--reasonWhy this phone number should be removed; required by default

afmail contact rename

Rename a contact’s display name.

afmail contact rename [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CONTACT_REF> --name <NAME> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CONTACT_REFContact ref: pYYYYMMDDNNN or pYYYYMMDDNNN-any-suffix
--nameNew display name
--reasonWhy this name better represents the contact; required by default

afmail contact show

Show the exact typed contact document used by its Markdown template.

afmail contact show [--workspace <PATH>] [--log <startup|request|progress|retry>...] <CONTACT_REF>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
CONTACT_REFContact ref: pYYYYMMDDNNN or pYYYYMMDDNNN-any-suffix

afmail contact tag

Add a tag to a contact.

afmail contact tag [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CONTACT_REF> <TAG> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CONTACT_REFContact ref: pYYYYMMDDNNN or pYYYYMMDDNNN-any-suffix
TAGTag to add
--reasonWhy this tag is useful; required by default

afmail contact untag

Remove a tag from a contact.

afmail contact untag [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <CONTACT_REF> <TAG> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
CONTACT_REFContact ref: pYYYYMMDDNNN or pYYYYMMDDNNN-any-suffix
TAGTag to remove
--reasonWhy this tag should be removed; required by default

afmail demo init

Create a normal workspace wired to the local demo mail server.

afmail demo init [--log <startup|request|progress|retry>...] [<PATH>] [--scenario <founder-inbox>] [--imap-port <PORT>] [--smtp-port <PORT>]
ArgumentMeaning
--logDiagnostic category to emit. Repeat the flag for more than one.
PATHWorkspace path under the current directory
--scenarioBuilt-in mailbox scenario
--imap-portLocal IMAP port
--smtp-portLocal SMTP port

afmail demo serve

Run the local demo IMAP and SMTP servers until interrupted.

afmail demo serve [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--verbose]

Output: protocol events; --output json/yaml/plain (default json), --output-to stdout/stderr (default stdout); redirect with --stdout-file or --stderr-file.

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--verboseAlso report every raw IMAP and SMTP protocol line the demo server sees

afmail doctor

Check afmail workspace consistency without inspecting Git.

afmail doctor [--workspace <PATH>] [--log <startup|request|progress|retry>...]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.

afmail doctor repair

Repair only unambiguous afmail-generated state.

afmail doctor repair [--workspace <PATH>] [--log <startup|request|progress|retry>...] --confirm
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--confirmApply the repair actions. Repair never runs without it, so it is part of the only registered shape.

afmail init

Initialize the current directory or a child path as an afmail workspace.

afmail init [--log <startup|request|progress|retry>...] [<PATH>]
ArgumentMeaning
--logDiagnostic category to emit. Repeat the flag for more than one.
PATHWorkspace path to initialize under the current directory

afmail log case

List events for one case id.

afmail log case [--workspace <PATH>] [--log <startup|request|progress|retry>...] <CASE_UID>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
CASE_UIDCase UID

afmail log list

List recent audit events.

afmail log list [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--limit <COUNT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--limitMaximum number of events to return

afmail log message

List events for one message id.

afmail log message [--workspace <PATH>] [--log <startup|request|progress|retry>...] <MESSAGE_ID>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
MESSAGE_IDMessage id

afmail log notification

List events for one notification collection.

afmail log notification [--workspace <PATH>] [--log <startup|request|progress|retry>...] <NOTIFICATION_UID>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
NOTIFICATION_UIDNotification UID

afmail log tail

Tail recent audit events as JSON data.

afmail log tail [--workspace <PATH>] [--log <startup|request|progress|retry>...]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.

afmail message attachment fetch

Fetch one attachment by MIME part id, or all attachments when omitted.

afmail message attachment fetch [--workspace <PATH>] [--log <startup|request|progress|retry>...] <MESSAGE_ID> [<PART_ID>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
MESSAGE_IDMessage id, for example message_inbox_607146690_22
PART_IDMIME part id; with none, every attachment is fetched

afmail message list

List messages by sender, subject, date, or workspace scope.

afmail message list [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--sender <TEXT>] [--subject-contains <TEXT>] [--since <DATE>] [--in <triage|case|notification|all>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--senderOnly include messages whose sender or from line contains this text
--subject-containsOnly include messages whose subject contains this text
--sinceOnly include messages on or after this date or RFC3339 timestamp
--inLimit results to one workspace scope

afmail message show

Show the exact typed message document used by Markdown and Review templates.

afmail message show [--workspace <PATH>] [--log <startup|request|progress|retry>...] <MESSAGE_ID>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
MESSAGE_IDMessage id, for example message_inbox_607146690_22

afmail message spam

Mark junk/phishing/malware/suspicious mail locally, show it under spam/, and queue a Junk move.

afmail message spam [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <MESSAGE_ID>... [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
MESSAGE_IDMessage ids, for example message_inbox_607146690_22
--reasonWhy this disposition is correct; required by default

afmail message trash

Explicitly discard this message locally, show it under trash/, and queue a Trash move.

afmail message trash [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <MESSAGE_ID>... [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
MESSAGE_IDMessage ids, for example message_inbox_607146690_22
--reasonWhy this disposition is correct; required by default

afmail message unspam

Mark a spam false positive as triage and queue a move out of Junk when needed.

afmail message unspam [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <MESSAGE_ID>... [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
MESSAGE_IDMessage ids, for example message_inbox_607146690_22
--reasonWhy this message is not spam; required by default

afmail message untrash

Mark a trash false positive as triage and queue a move out of Trash when needed.

afmail message untrash [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <MESSAGE_ID>... [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
MESSAGE_IDMessage ids, for example message_inbox_607146690_22
--reasonWhy this message should not be trashed; required by default

afmail notification add

File an existing message into this notification collection.

afmail notification add [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <NOTIFICATION_REF> <MESSAGE_ID>... --summary <TEXT> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
NOTIFICATION_REFNotification ref: nYYYYMMDDNNN or nYYYYMMDDNNN-any-suffix
MESSAGE_IDMessage ids to file
--summaryHuman/agent-authored summary for this notification entry
--reasonWhy this message belongs in this notification; required by default

afmail notification create

Create a notification collection and optionally file one message.

notification-create-empty — Create an empty collection; with no message there is nothing to summarize

afmail notification create [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] --name <NAME> [--reason <TEXT>]

notification-create-with-message — Create the collection and file one message, which always needs a summary

afmail notification create [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] --name <NAME> [--reason <TEXT>] --message <MESSAGE_ID> --summary <TEXT>

Arguments across every shape above:

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
--nameHuman-readable notification name used in metadata and the directory suffix
--reasonWhy this notification collection is being created
--messageMessage to immediately file into the new collection
--summarySummary for the filed message’s notification entry

afmail notification delete

Delete an empty notification collection.

afmail notification delete [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <NOTIFICATION_REF> [--allow-notes] [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
NOTIFICATION_REFNotification ref: nYYYYMMDDNNN or nYYYYMMDDNNN-any-suffix
--allow-notesAlso delete notes.md when it contains user-authored notes
--reasonWhy this notification collection should be deleted; required by default

afmail notification list

List compact notification collections.

afmail notification list [--workspace <PATH>] [--log <startup|request|progress|retry>...]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.

afmail notification move

Move a notification message to another notification collection.

afmail notification move [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <NOTIFICATION_REF> <MESSAGE_ID> <NEW_NOTIFICATION_REF> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
NOTIFICATION_REFNotification ref: nYYYYMMDDNNN or nYYYYMMDDNNN-any-suffix
MESSAGE_IDMessage id to move
NEW_NOTIFICATION_REFDestination notification collection ref
--reasonWhy this collection is better; required by default

afmail notification notes append

Append text to notification notes markdown.

afmail notification notes append [--workspace <PATH>] [--log <startup|request|progress|retry>...] <NOTIFICATION_REF> [--request-id <ID>] --text <TEXT>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
NOTIFICATION_REFNotification ref: nYYYYMMDDNNN or nYYYYMMDDNNN-any-suffix
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
--textMarkdown text to append

afmail notification notes replace

Replace notification notes markdown with text.

afmail notification notes replace [--workspace <PATH>] [--log <startup|request|progress|retry>...] <NOTIFICATION_REF> [--request-id <ID>] --text <TEXT>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
NOTIFICATION_REFNotification ref: nYYYYMMDDNNN or nYYYYMMDDNNN-any-suffix
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
--textMarkdown text to write

afmail notification notes show

Show notification notes markdown.

afmail notification notes show [--workspace <PATH>] [--log <startup|request|progress|retry>...] <NOTIFICATION_REF>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
NOTIFICATION_REFNotification ref: nYYYYMMDDNNN or nYYYYMMDDNNN-any-suffix

afmail notification remove

Remove a notification message from this collection and return it to triage.

afmail notification remove [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <NOTIFICATION_REF> <MESSAGE_ID> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
NOTIFICATION_REFNotification ref: nYYYYMMDDNNN or nYYYYMMDDNNN-any-suffix
MESSAGE_IDMessage id to remove
--reasonWhy this message does not belong in this notification; required by default

afmail notification rename

Rename this notification collection’s human-readable name without changing its UID.

afmail notification rename [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <NOTIFICATION_REF> --name <NAME> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
NOTIFICATION_REFNotification ref: nYYYYMMDDNNN or nYYYYMMDDNNN-any-suffix
--nameNew human-readable notification name
--reasonWhy this name better represents the collection; required by default

afmail notification review

Open a review session for this notification and its persisted suggestion.

afmail notification review [--workspace <PATH>] [--log <startup|request|progress|retry>...] <NOTIFICATION_REF> [--mode <window|link|session>]

Output: protocol events; --output json/yaml/plain (default json), --output-to stdout/stderr (default stdout); redirect with --stdout-file or --stderr-file.

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
NOTIFICATION_REFNotification ref: nYYYYMMDDNNN or nYYYYMMDDNNN-any-suffix
--modeHow this reaches the person: window a browser window is open on this machine; link the page is reachable from this machine’s network at the link URL; session the session is registered only; open it with afui session open or reach it through afui session serve. Falls back to AFUI_DELIVERY, then window

afmail notification set-summary

Set or replace one notification entry summary.

afmail notification set-summary [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <NOTIFICATION_REF> <MESSAGE_ID> --summary <TEXT> [--reason <TEXT>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
NOTIFICATION_REFNotification ref: nYYYYMMDDNNN or nYYYYMMDDNNN-any-suffix
MESSAGE_IDMessage id whose summary should be changed
--summaryNew summary text
--reasonWhy this summary is useful; required by default

afmail notification show

Show the exact typed notification document used by Markdown and Review.

afmail notification show [--workspace <PATH>] [--log <startup|request|progress|retry>...] <NOTIFICATION_REF>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
NOTIFICATION_REFNotification ref: nYYYYMMDDNNN or nYYYYMMDDNNN-any-suffix

afmail notification suggestion clear

Clear exactly the current suggestion round.

afmail notification suggestion clear [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <NOTIFICATION_REF> --agent-suggestion-uid <UID>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
NOTIFICATION_REFNotification ref: nYYYYMMDDNNN or nYYYYMMDDNNN-any-suffix
--agent-suggestion-uidUID returned by the current suggestion set command

afmail notification suggestion set

Replace the current suggestion and clear any human review of the prior round.

notification-suggestion-set-rename — Suggest renaming this collection

afmail notification suggestion set [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <NOTIFICATION_REF> --notification-review-base-hash <HASH> --reason <TEXT> [--confidence-percent <PERCENT>] --action rename --name <NAME>

notification-suggestion-set-delete — Suggest deleting this collection

afmail notification suggestion set [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <NOTIFICATION_REF> --notification-review-base-hash <HASH> --reason <TEXT> [--confidence-percent <PERCENT>] --action delete [--allow-notes]

Arguments across every shape above:

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
NOTIFICATION_REFNotification ref: nYYYYMMDDNNN or nYYYYMMDDNNN-any-suffix
--notification-review-base-hashCurrent hash returned by afmail notification show
--reasonWhy this complete action is being suggested
--confidence-percentOptional confidence from 0 through 100
--actionThe complete action being suggested; it decides which other arguments apply
--nameNew human-readable notification name
--allow-notesAlso delete notes.md when it contains user-authored notes

afmail pull

Read configured IMAP mailbox ids into local message files without changing remote mail.

pull-window — Pull a bounded window: the default initial window, or –since-days

afmail pull [--workspace <PATH>] [--log <startup|request|progress|retry>...] [<MAILBOX_ID>...] [--dry-run] [--max-new-messages <COUNT>] [--max-total-bytes <BYTES>] [--since-days <DAYS>]

pull-all-history — Pull every remote message; no window applies, so –since-days is absent here

afmail pull [--workspace <PATH>] [--log <startup|request|progress|retry>...] [<MAILBOX_ID>...] [--dry-run] [--max-new-messages <COUNT>] [--max-total-bytes <BYTES>] --all-history

Arguments across every shape above:

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
MAILBOX_IDConfigured mailbox ids to pull. With none, pulls actions.pull.default_mailbox_ids.
--dry-runEstimate remote candidates and budgets without downloading or writing locally
--max-new-messagesMaximum number of new messages stored across all selected mailboxes
--max-total-bytesMaximum new raw message bytes stored across all selected mailboxes
--since-daysLimit the remote candidate range to messages from the last DAYS days
--all-historyInclude all remote history instead of the default initial window

afmail purge

Permanently delete old local spam, trash, and remote-deleted records together.

afmail purge [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--older-than-days <DAYS>] [--confirm <PLAN_ID>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--older-than-daysOnly purge messages in a discard state at least this many days ago. Defaults to 30.
--confirmPermanently delete exactly the reviewed purge plan

afmail purge deleted

Permanently delete old local records whose remote message disappeared.

afmail purge deleted [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--older-than-days <DAYS>] [--confirm <PLAN_ID>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--older-than-daysOnly purge messages marked remote-deleted at least this many days ago. Defaults to 30.
--confirmPermanently delete exactly the reviewed purge plan

afmail purge spam

Permanently delete old local spam records.

afmail purge spam [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--older-than-days <DAYS>] [--confirm <PLAN_ID>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--older-than-daysOnly purge messages marked spam at least this many days ago. Defaults to 30.
--confirmPermanently delete exactly the reviewed purge plan

afmail purge trash

Permanently delete old local trash records.

afmail purge trash [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--older-than-days <DAYS>] [--confirm <PLAN_ID>]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--older-than-daysOnly purge messages marked trash at least this many days ago. Defaults to 30.
--confirmPermanently delete exactly the reviewed purge plan

afmail push

Push queued local work to IMAP and SMTP.

push-preview — Preview the plan; nothing is written, so no plan id is confirmed

afmail push [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--dry-run]

push-apply — Apply one reviewed plan; this shape writes, so –dry-run is absent

afmail push [--workspace <PATH>] [--log <startup|request|progress|retry>...] --confirm <PLAN_ID>

Arguments across every shape above:

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--dry-runShow planned push actions without IMAP/SMTP writes
--confirmApply exactly the reviewed plan returned by the push preview

afmail push list

Preview the complete resolved push plan without writing.

afmail push list [--workspace <PATH>] [--log <startup|request|progress|retry>...]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.

afmail remote folders

List IMAP folders/mailboxes.

afmail remote folders [--workspace <PATH>] [--log <startup|request|progress|retry>...]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.

afmail remote test

Test configured IMAP and SMTP access without sending mail.

afmail remote test [--workspace <PATH>] [--log <startup|request|progress|retry>...]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.

afmail render refresh

Rebuild generated case and notification read views.

afmail render refresh [--workspace <PATH>] [--log <startup|request|progress|retry>...]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.

afmail render templates

Export built-in language templates, keeping existing files unless forced.

afmail render templates [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--force]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--forceOverwrite existing workspace templates with built-in defaults

afmail skill install

Install the Agent-First Mail skill.

skill-install-every-agent — Target every agent that supports the scope

afmail skill install [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--agent all] [--scope <personal|workspace>] [--force]

skill-install-one-agent — Target one named agent; only this shape accepts –skills-dir

afmail skill install [--workspace <PATH>] [--log <startup|request|progress|retry>...] --agent <codex|claude-code|opencode|hermes> [--scope <personal|workspace>] [--skills-dir <DIR>] [--force]

Arguments across every shape above:

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--agentAgent to manage
--scopeSkill scope
--skills-dirDirectory that contains skill folders
--forceOverwrite or remove an unmanaged Agent-First Mail skill at the target path

afmail skill status

Show whether the Agent-First Mail skill is installed and valid.

skill-status-every-agent — Target every agent that supports the scope

afmail skill status [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--agent all] [--scope <personal|workspace>]

skill-status-one-agent — Target one named agent; only this shape accepts –skills-dir

afmail skill status [--workspace <PATH>] [--log <startup|request|progress|retry>...] --agent <codex|claude-code|opencode|hermes> [--scope <personal|workspace>] [--skills-dir <DIR>]

Arguments across every shape above:

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--agentAgent to manage
--scopeSkill scope
--skills-dirDirectory that contains skill folders

afmail skill uninstall

Remove an afmail-managed Agent-First Mail skill.

skill-uninstall-every-agent — Target every agent that supports the scope

afmail skill uninstall [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--agent all] [--scope <personal|workspace>] [--force]

skill-uninstall-one-agent — Target one named agent; only this shape accepts –skills-dir

afmail skill uninstall [--workspace <PATH>] [--log <startup|request|progress|retry>...] --agent <codex|claude-code|opencode|hermes> [--scope <personal|workspace>] [--skills-dir <DIR>] [--force]

Arguments across every shape above:

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--agentAgent to manage
--scopeSkill scope
--skills-dirDirectory that contains skill folders
--forceOverwrite or remove an unmanaged Agent-First Mail skill at the target path

afmail status

Report workspace health, counts, and latest pull/push progress.

afmail status [--workspace <PATH>] [--log <startup|request|progress|retry>...]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.

afmail triage list

List compact untriaged message locators.

afmail triage list [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--limit <COUNT>] [--details]
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--limitMaximum number of newest triage messages to return
--detailsInclude message metadata, related message ids, and case refs

afmail triage review

Open a review session for persisted triage suggestions.

afmail triage review [--workspace <PATH>] [--log <startup|request|progress|retry>...] [<MESSAGE_ID>...] [--mode <window|link|session>]

Output: protocol events; --output json/yaml/plain (default json), --output-to stdout/stderr (default stdout); redirect with --stdout-file or --stderr-file.

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
MESSAGE_IDMessage ids to review. With none, reviews the current triage queue, newest first, up to a bound; the result says if any were left out.
--modeHow this reaches the person: window a browser window is open on this machine; link the page is reachable from this machine’s network at the link URL; session the session is registered only; open it with afui session open or reach it through afui session serve. Falls back to AFUI_DELIVERY, then window

afmail triage suggestion clear

Clear exactly the current suggestion round.

afmail triage suggestion clear [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <MESSAGE_ID> --agent-suggestion-uid <UID>
ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
MESSAGE_IDMessage id whose current suggestion round should be cleared
--agent-suggestion-uidUID returned by the current suggestion set command

afmail triage suggestion set

Replace the current suggestion and clear any human review of the prior round.

triage-suggestion-set-case-create — Suggest creating a new case from this message

afmail triage suggestion set [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <MESSAGE_ID> --message-review-base-hash <HASH> --reason <TEXT> [--confidence-percent <PERCENT>] --action case-create --name <NAME> --group <GROUP>

triage-suggestion-set-case-add — Suggest adding this message to an existing case

afmail triage suggestion set [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <MESSAGE_ID> --message-review-base-hash <HASH> --reason <TEXT> [--confidence-percent <PERCENT>] --action case-add --case-ref <CASE_REF>

triage-suggestion-set-notification-create — Suggest creating a new notification collection from this message

afmail triage suggestion set [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <MESSAGE_ID> --message-review-base-hash <HASH> --reason <TEXT> [--confidence-percent <PERCENT>] --action notification-create --name <NAME> --summary <TEXT>

triage-suggestion-set-notification-add — Suggest filing this message into an existing notification collection

afmail triage suggestion set [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <MESSAGE_ID> --message-review-base-hash <HASH> --reason <TEXT> [--confidence-percent <PERCENT>] --action notification-add --notification-ref <NOTIFICATION_REF> --summary <TEXT>

triage-suggestion-set-spam — Suggest marking this message as spam

afmail triage suggestion set [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <MESSAGE_ID> --message-review-base-hash <HASH> --reason <TEXT> [--confidence-percent <PERCENT>] --action spam

triage-suggestion-set-trash — Suggest trashing this message

afmail triage suggestion set [--workspace <PATH>] [--log <startup|request|progress|retry>...] [--request-id <ID>] <MESSAGE_ID> --message-review-base-hash <HASH> --reason <TEXT> [--confidence-percent <PERCENT>] --action trash

Arguments across every shape above:

ArgumentMeaning
--workspaceExisting afmail workspace to operate on instead of discovering one from the current directory
--logDiagnostic category to emit. Repeat the flag for more than one.
--request-idIdempotency key; replaying it returns the first result instead of repeating the mutation
MESSAGE_IDMessage id currently in triage
--message-review-base-hashCurrent hash returned by afmail message show
--reasonWhy this complete action is being suggested
--confidence-percentOptional confidence from 0 through 100
--actionThe complete action being suggested; it decides which other arguments apply
--nameName for the suggested new case or notification
--groupGroup for the suggested new case
--case-refExisting case to add the message to
--notification-refExisting notification collection to file the message into
--summarySummary for the notification entry

Exit codes

CodeMeaning
0The command ran and succeeded.
1The command ran and failed. The event carries a domain error.code.
2The invocation was rejected before anything ran. error.code is one of the cli_* codes below.
3Some items in a batch succeeded and some failed. The remote effects that landed stay landed, so re-running the same call is not safe; read failures and re-queue from there.
4The command ran, but its output could not be written to the requested destination.

The split is the useful one for a caller: exit 2 means the call was never made, so retrying it unchanged cannot help, while exit 1 means it was.

CLI errors

Every structural failure emits one strict JSON kind:"error" event on stderr, leaves stdout empty, and exits 2. The code names the failure — cli_unknown_argument for an unknown spelling, cli_unregistered_combination for registered arguments in a mixture that is not, and one each for cli_unknown_command, cli_missing_argument_value, cli_invalid_argument_value, cli_duplicate_argument, cli_unexpected_positional, and cli_invalid_utf8. message identifies a safe argument spelling or the failure category and hint gives the command to run next; neither ever quotes a raw value, including secrets. These are decided before any config, secret source, filesystem, network, or domain I/O.

Two exit-1 codes describe the tool itself rather than the call: cli_invocation_invalid means the program misread its own resolved invocation — an unknown action id, or an argument id the selected combination cannot produce — and output_setup_failed means an output sink (--stdout-file, --stderr-file, stream redirection) could not be established. Both are defects to report, not inputs to correct; retrying the same command cannot help.

Domain failures (exit 1) carry their own stable error.code instead, drawn from whatever this tool defines rather than from the cli_* set. Error events are routinely logged, so a message never quotes a value that came from an argument able to carry a credential — a header, a cookie, a token, a password, a proxy URL, an environment value, a form field. Such an error names the argument and the shape that was wrong, and stops there. A value that cannot be a secret — a path, a dot-path, a session name — is quoted, because an error that cannot say which one it means is not worth logging either.