Skip to content

Releases: agentfirstkit/agent-first-mail

v0.11.0

Choose a tag to compare

@agentfirstkit agentfirstkit released this 23 Aug 17:08
  • Settle each review item the moment a person decides it, so closing the window ends the session instead of discarding unsettled work, and re-read the terminal result from the workspace afterwards — a process killed mid-session loses nothing already settled
  • Drop the session-level submitted/cancelled/dismissed vocabulary and the Deferred outcome, add Decided for a disposition the agent never proposed, and check the three outcome invariants right after deserialization instead of leaving each writer to remember them
  • Move stale-suggestion detection from a whole-session gate to a per-item flag, so one item whose message has moved on no longer refuses to open the rest of the queue
  • Open a draft's attachments through one primitive that checks the directory and the file separately, refuses non-regular files before any open, and compares the opened handle's identity with what was checked — a symlink under files/ can no longer be read, hashed and attached while the push plan shows a harmless case-relative path
  • Switch review delivery to AFUI's window|link|session and delete afmail's own LAN implementation and discovery, keeping the one-shot fifteen-minute link expiry and review_ready carrying review_url
  • Render the real page in doctor, one render per surface, so a frontend called healthy cannot still fail the escaping policy, rendered-markup guard and element contract that only the serving side applied
  • Declare the four review hooks a page cannot render without and check them before a window opens, leaving the other twenty-one undeclared because they belong to surfaces that legitimately lack them
  • Put the review page's routing, session channel and unload guard on AFUI's page kernel, keeping only what is afmail's: which update ends a turn, flushing dirty editors before a send, and selection clamping
  • Stop drawing a second head inside a framed session — the page hides its brand and saving line and sends up only what a frame cannot know, keeping the local-workspace pill
  • Bound triage review with no message ids to the current queue newest-first and say in the result whether any were left out, instead of implying every current suggestion is included
  • Pin the IMAP push contract with a recording test server, and pin the per-file locale overlay so a frontend overriding one template still gets the rest of the active language pack rather than falling back to English
  • Stop quoting values from credential-bearing arguments in error events, and run the local container gates on Apple's container runtime as well as Docker
  • Upgrade Agent-First Data to 0.34.0, Agent-First UI to 0.5.0 and Agent-First Slug to 0.7.1

v0.10.0

Choose a tag to compare

@agentfirstkit agentfirstkit released this 07 Aug 13:01
  • Move the human review window onto agent-first-ui: afmail's own TcpListener loop, request parser, urlencoded decoder, Chromium launcher, and profile guard are deleted, and the single action= form path becomes typed routes
  • Give each review surface its own ui_kind (triage_review, case_review, notification_review, draft_review) so replacing one frontend cannot silently replace the other three
  • Replace Review UI template overrides under workspace templates/ with AFUI frontends at .afui/frontends/afmail/<ui_kind>/, declared against Review UI API version 1, with per-file fallback to the built-in localized pack; content templates stay in the workspace tree
  • Report a LAN review plan that lapses unopened as outcome expired instead of dismissed, and record cancel as a completed decision, so a caller can tell 'nobody was there' from 'someone declined to answer'
  • Extend afmail doctor to smoke-render the Review UI that would actually serve each surface, reporting a broken or unloadable user frontend as its own issue rather than failing every other check
  • Collapse imap.password_secret_env and smtp.password_secret_env into imap.password_secret and smtp.password_secret, which now take the AFDATA source grammar (the value, env:NAME, file:PATH#DOT_PATH, literal:VALUE); stream sources are refused in config and afmail's credential-naming rule still applies to env sources
  • Accept the same source grammar for afmail api serve --access-token-secret
  • Upgrade agent-first-data to 0.32.1 and agent-first-ui to 0.3.1

v0.9.0

Choose a tag to compare

@agentfirstkit agentfirstkit released this 05 Aug 14:21
  • Compile the entire CLI from a closed-world registry of 106 commands and 140 legal argument shapes, replacing hand-written conflict rules, error-hint tables and raw-argv scanning with shapes the binary can enumerate
  • Require arguments to follow their command — there are no global flags before it — and remove -h along with every short flag
  • Make --log a repeatable closed enum, so --log a,b becomes --log a --log b
  • Replace the suggestion set sub-subcommands with an --action argument whose operands are named flags, so a triage, case or notification suggestion is one flat shape
  • Require --confirm on doctor repair as an argument shape rather than rejecting it as a business error
  • Make --help list every legal argument combination of that command at once, and --docs render the whole reference
  • Derive a message's identity from its raw RFC822 bytes instead of its Message-ID, so byte-identical copies converge on one record and a reused Message-ID no longer collides two unrelated mails
  • Refund the --max-new-messages and byte budget spent on cross-mailbox duplicates, and report candidate_count_is_upper_bound from pull --dry-run since recognizing a duplicate needs the body a dry run never fetches
  • Abort a push step with the new imap_uidvalidity_changed error before issuing any STORE or MOVE against stale UIDs
  • Detect a UIDVALIDITY reset during pull, discard the stale cursor, force a full reconcile, and report uid_validity_reset_count and the affected mailboxes
  • Move every remaining location of a multi-location message instead of skipping the whole move when one copy already sits in the target, and persist flag state after each location so a later failure keeps earlier progress
  • Reject conflicting per-mailbox archive steps with the new archive_action_conflict error as a preflight, before any notification or case write lands locally
  • Allocate a random opaque push id per draft-send lifecycle so re-sending a draft records new sent evidence instead of overwriting the earlier one
  • Stop escalating failures that provably preceded any remote call into the manual-reconciliation push_remote_outcome_unknown state
  • Support Bcc recipients — kept in the local draft, Review UI, push preview and the sender's private evidence, stripped from SMTP DATA, retained in the SMTP envelope
  • Stop re-rendering hand-edited contact and draft files from their structs; a frontmatter edit now moves only the keys whose values changed, preserving comments, key order, quote styles and body, including through contact rename
  • Report retryable: false on a partial push --confirm envelope, since exit 3 is never permission to retry a batch; per-item retryable inside failures remains the field that says what to re-queue
  • Stop printing "***" from config show for a secret that was never set, which had disagreed with config get and implied a credential was configured
  • Install the skill's bundled references/http-api.md alongside SKILL.md, which skill install had been dropping while SKILL.md pointed at it
  • Exit 0 on a broken pipe such as --docs | head, matching the AFDATA emitter
  • Document exit codes 3 and 4, the cli_invocation_invalid and output_setup_failed defect codes, the byte-exact identity model, and the fact that push ids are opaque
  • Relock onto agent-first-data 0.31.0 and agent-first-slug 0.6.2, and cover every declared shape with a synthetic-invocation test that fails when a builder arm reads an argument id its shape cannot supply

v0.8.0

Choose a tag to compare

@agentfirstkit agentfirstkit released this 29 Jul 16:44
  • Add blocking local and LAN review sessions for triage, cases, notifications, and drafts, returning one typed human decision that never authorizes a remote push.
  • Render generated Markdown, new scaffolds, and review HTML from one MiniJinja template system over typed render documents, with editable overrides and nine built-in language packs.
  • Expose the domain through a typed OpenAPI 3.2 HTTP API with committed, drift-tested contract and JSON Schema artifacts.
  • Add afmail demo: a loopback mock IMAP/SMTP server and seeded workspace that exercises the real pull, review, and confirmed push paths.
  • Gate the demo, api, and review surfaces behind cargo features, leaving an excluded command discoverable and returning a structured feature_disabled error.
  • Send replies before message moves within a push plan, so a reply is never stranded by a move that ran ahead of it.
  • Route protocol events with --output-to: finite commands split result from diagnostics, review and serve commands keep one ordered stream on stdout, and the -V short flag is gone.
  • Resolve config domain rules in one document path, fixing a cleared optional field falling back to a non-null default and config add identities failing on a fresh workspace.
  • Upgrade to agent-first-data 0.26.2 and agent-first-slug 0.5.0.

v0.7.1

Choose a tag to compare

@agentfirstkit agentfirstkit released this 19 Jul 12:02
  • Restore numeric rendering in generated Markdown: attachment byte sizes and message and attachment counts print as numbers again, not an arbitrary-precision wrapper object, after the afdata dependency enabled that globally.
  • Rework config editing to change .afmail/config.json in place through afdata's DocumentFile — validate the whole config before writing, commit atomically, and preserve on-disk key order — replacing the hand-written sparse-diff writer.
  • Migrate onto afdata 0.20, which absorbed the retired agent-first-config, adopting its redesigned config, document, version, and help APIs.
  • Bump the agent-first-slug dependency to 0.3.0.

v0.7.0

Choose a tag to compare

@agentfirstkit agentfirstkit released this 14 Jul 07:58
  • Adopt afdata protocol v1 end-to-end: commands emit typed, structured command results with flattened error fields via a semantic CLI emitter, replacing serialized output bags
  • Add request-idempotency across every state-changing command via a global --request-id key that records and replays outcomes so retries are deduplicated (message dispositions, case lifecycle, draft edits, contact edits/renames, membership, notes, summaries, local deletes, field edits)
  • Bind remote effects to reviewed plans: push and purge require a reviewed plan id before any remote effect runs, and case-archive lifecycle finalizes only after a successful push
  • Support explicit workspace selection via --workspace with a stable workspace identity, and make onboarding readiness an explicit reported state in afmail status
  • Harden untrusted-mail and privacy boundaries: bound IMAP body fetches by default, enforce render boundaries on untrusted content, and redact private startup argv shape and runtime log fields
  • Make network failures recoverable by marking IMAP connect and SMTP remote failures retryable with explicit retry phases and reason-required safe recovery
  • Add incremental pull with persisted cursors, plus mailbox pull budgeting via --max-new-messages and --max-total-bytes and pre-pull size estimation via --dry-run
  • Report workspace storage usage in bytes through afmail status and surface partial command outcomes
  • Make draft intent and content states explicit with separate lifecycle states, add a draft list command, and rename draft save to upload
  • Add batch operations and message list filters: batch message dispositions, batch case and notification additions requiring ids, require --group for case move, require contact reasons, and add case set-summary
  • Redesign the AFUI mail workspace to safely render full case conversations including archived views, load web packs, and show timezone-aware rendered times
  • Optimize the render pipeline, reorganize the workspace state directory layout, and order the push queue by persisted enqueue sequence

v0.6.0

Choose a tag to compare

@agentfirstkit agentfirstkit released this 03 Jul 14:18
  • Add notification delete command to remove an empty notification collection, with --allow-notes to permit deletion when user-authored notes are present
  • Split message restore into message unspam and message untrash with semantics specific to each disposition, queuing the appropriate remote move when needed
  • Replace contact archive/reopen lifecycle with a single contact delete command; remove case reopen in favor of case delete for empty active cases; add case remove to extract one message back to triage
  • Collapse the archive top-level subcommand into case — archived case list, show, restore, remove, and move are now available directly under case
  • Add case move support for archived cases, enabling reordering within the archive without requiring a full restore-and-re-archive cycle
  • Fall back to COPY+EXPUNGE when the IMAP server does not advertise the MOVE capability, requiring UIDPLUS for precise single-message targeting
  • Centralize all on-disk workspace directory names into a single layout module, eliminating scattered string literals across the codebase
  • Integrate afdata stream file redirection, allowing stdout/stderr to be redirected to a file via CLI args before any output is written

v0.5.0

Choose a tag to compare

@agentfirstkit agentfirstkit released this 01 Jul 04:49
  • Rename the standalone direct-message archive model to notification collections: file reference and notification mail with 'afmail notification create/add' under stable nYYYYMMDDNNN uids and read it via 'afmail notification list/show', leaving the archive command to mean archived cases only
  • Require an explicit case category on 'afmail case create --group' with no default and no 'open' catch-all, and nest archived cases under archive/cases// so the category survives archival
  • Block attachment fetches on spam-classified messages so an agent cannot be lured into pulling hostile payloads from mail it already flagged as spam
  • Queue remote trash for every mailbox a case's messages occupy, including Sent, so already-sent replies move to trash with the rest of the conversation when a case is discarded
  • Surface a structured audit_warnings entry when a confirmed push effect's audit record cannot be written, instead of silently dropping the lost record
  • Add index.md read views to the spam, trash, and deleted folders, and change the notification message-index default fields from sender to from
  • Make identity config setup idempotent, fix push incremental refresh, fix restore push cleanup and reply recipients, surface the contact command in CLI error hints, and upgrade dependencies

v0.4.0

Choose a tag to compare

@agentfirstkit agentfirstkit released this 27 Jun 14:23
  • Add fully localized render-template packs for Traditional Chinese, German, Spanish, French, Japanese, Korean, and Brazilian Portuguese, selected by workspace.language_bcp47
  • Move every human-language string out of the Rust code into the per-language template packs, so labels, headings, and disposition titles are translated in the templates and adding a language is just dropping a directory
  • Replace the hand-coded config dispatch with agent-first-config dot-path traversal, and add a prune command, imap-archive origin provenance, attachment MIME-type detection, and pending-push counts in status and triage output
  • Add archive case trash and restore commands
  • Show the full product name in --help headings and generated docs while keeping the short afmail binary name in usage strings
  • Resolve mailbox import rules in configured order and parse nonstandard message date headers
  • Speed up the pull render cache and report render sub-stage progress
  • Harden outbound push safety, support sparse config, and unify identity-config slug validation
  • Upgrade the IMAP client and other dependencies

v0.3.0

Choose a tag to compare

@agentfirstkit agentfirstkit released this 19 Jun 20:08
  • Add afmail contact subcommand for managing contact cards with CRUD operations, per-group organisation, email/phone fields, tags, archival, and extracting contacts from message senders; email addresses are globally unique across all contacts
  • Materialise sender contact links directly onto message views, refreshed automatically when a contact's emails or name change
  • Add identity registry: workspaces define named send personas in config with optional identities/.md footer notes; draft commands accept --identity SLUG and write footers into the draft body for review before push
  • Fix skill install to add each installed skill directory to the workspace .gitignore managed block, covering both .codex/ and .claude/ agent paths without duplication
  • Fix interrupted-transaction sentinel preservation so retried commands correctly detect and recover from previously-failed transactions
  • Roll back newly-created case and archive directories automatically if any step in the create command fails, preventing orphan directories in the workspace
  • Validate related-message constraint in archive message create before creating any files, and document in the skill that messages with related_message_ids must be grouped into a case