Skip to main content

Imap

@shrug/imapv2026.10.14.1· MIT· 10d agoBEHAVIORS
01README

Provider-agnostic IMAP inspection + gated-write model built on imapflow. Phase 1 (read-only): listFolders enumerates the folder tree with per-folder message counts and sizes; sync snapshots message envelopes plus a fixed header set (From, To, Cc, Subject, Date, Message-ID, In-Reply-To, References, List-ID, List-Unsubscribe, List-Post, Reply-To, Auto-Submitted, Precedence) with flags and size into versioned data -- HEADERS ONLY, never bodies. fetchMessage (read-only, EXAMINE) is the one method that pulls FULL bodies, for ONE folder per call (an IMAP UID is unique only within one folder+UIDVALIDITY): it uses a pre-fetch size gate (one {uid,size} fetch to partition the UID set against MAX_BODY_BYTES, then one source fetch for the under-cap UIDs only, never a per-UID loop), decodes with postal-mime, and writes one messageBody record per UID (text/html, attachment metadata only, extracted http/https links, an error field). An over-cap body is deliberately NOT pulled (truncated=true, sourceBytes=server size, null bodies) so oversized sources are never buffered; a no-server-size body over the cap is byte-truncated; each decode is isolated so one malformed message cannot abort the batch; a null-UID or absent UID is skipped. html is stored UNSANITIZED. messageBody records have a FINITE (30d) lifetime. It performs ZERO mutation and is structurally read-only like sync (EXAMINE; no peek knob). Mailboxes are opened read-only (EXAMINE) for these methods. Phase 3 (gated write): addKeywords/removeKeywords/move fan out one STORE/MOVE command over a UID set, dryRun-gated, uidValidity-guarded, verified by a post-mutation re-FETCH. applyTagPlan (Reconcile-B) reads the latest tagPlan record from a @shrug/mail-ontology instance and applies it over the same safety core, fanned out by (folder,keyword) and (folder,destination) group. createFolder (imap-create-folder) ensures a LIST of mailbox paths exist in one call (imapflow mailboxCreate), idempotent on ALREADYEXISTS, verified by a post-creation re-LIST; it is mailbox-level and needs no UID/uidValidity machinery. The mailbox credential is resolved from a swamp vault via CEL; it is never inlined.

02Behaviors1
@shrug/imapv2026.10.14.1extensions/models/imap.ts
fn listFolders()
Enumerate the folder tree and attach each folder's message count and
fn sync()
Snapshot message envelopes and a fixed set of headers (From, To, Cc,
fn fetchMessage(folder: string, uids: array, uidValidity?: number)
Fetch and DECODE the FULL body of specific messages by UID in ONE
ArgumentTypeDescription
folderstringThe ONE folder to fetch from (e.g. a sync snapshot:<folder>)
uidsarrayUIDs to fetch; de-duplicated, capped at MAX_FETCH_UIDS, fanned out
uidValidity?numberIf given, must match the folder's live UIDVALIDITY or the call
fn addKeywords(folder: string, uids: array, keywords: array, dryRun?: boolean, uidValidity?: number)
Add custom IMAP keywords to a UID selection in one fan-out STORE
ArgumentTypeDescription
folderstringMailbox to select
uidsarrayUIDs to act on (e.g. from a P1 snapshot:<folder>)
keywordsarrayCustom keywords to add; validated against the IMAP atom grammar
dryRun?booleantrue (default): preview only, zero mutation. false: mutate.
uidValidity?numberIf given, must match the mailbox's live UIDVALIDITY or the call
fn removeKeywords(folder: string, uids: array, keywords: array, dryRun?: boolean, uidValidity?: number)
Remove custom IMAP keywords from a UID selection in one fan-out
ArgumentTypeDescription
folderstringMailbox to select
uidsarrayUIDs to act on (e.g. from a P1 snapshot:<folder>)
keywordsarrayCustom keywords to remove; validated against the IMAP atom grammar
dryRun?booleantrue (default): preview only, zero mutation. false: mutate.
uidValidity?numberIf given, must match the mailbox's live UIDVALIDITY or the call
fn move(folder: string, uids: array, destination: string, dryRun?: boolean, uidValidity?: number)
Move a UID selection from `folder` to `destination` in one fan-out
ArgumentTypeDescription
folderstringSource mailbox to select
uidsarrayUIDs to move (e.g. from a P1 snapshot:<folder>)
destinationstringDestination mailbox path
dryRun?booleantrue (default): preview only, zero mutation. false: mutate.
uidValidity?numberIf given, must match the source mailbox's live UIDVALIDITY or
fn applyTagPlan(ontologyModel: string, dryRun?: boolean, folders?: array, applyMoves?: boolean)
Apply a @shrug/mail-ontology tagPlan: reads the LATEST `tagPlan`
ArgumentTypeDescription
ontologyModelstringThe @shrug/mail-ontology instance whose latest tagPlan to apply
dryRun?booleantrue (default): preview only, zero mutation. false: mutate.
folders?arrayRestrict to these source folders (optional; default is every
applyMoves?booleanSet false to tag-only and skip Finance moves entirely
fn createFolder(folders: array, dryRun?: boolean)
Ensure a list of mailbox paths exist, fanned out over the entire
ArgumentTypeDescription
foldersarrayMailbox paths to ensure exist; each validated (non-empty, no
dryRun?booleantrue (default): preview only, zero mutation. false: create

Resources

folders(infinite)— The folder tree with per-folder message counts and sizes
snapshot(infinite)— A header/envelope-only snapshot of one folder's messages (no bodies)
messageBody(30d)— One message's decoded FULL body by UID (fetchMessage): text/html,
wouldAffect(infinite)— A dryRun=true preview of a write method's effect; NO mutation performed
applied(infinite)— The result of a write method executed with dryRun=false
tagPlanPreview(infinite)— A consolidated dryRun=true preview of applying a @shrug/mail-ontology
tagPlanApplied(infinite)— The consolidated result of applying a @shrug/mail-ontology tagPlan
createFolderPreview(infinite)— A dryRun=true preview of createFolder; NO mutation performed
createFolderResult(infinite)— The result of createFolder executed with dryRun=false
03Stats
A
100 / 100
Downloads
9
Archive size
551.3 KB
  • Has README or module doc2/2earned
  • README has a code example1/1earned
  • README is substantive1/1earned
  • Most symbols documented1/1earned
  • No slow types (deprecated)1/1earned
  • Dependencies pass trust audit2/2earned
  • Has description1/1earned
  • Platform support declared (or universal)2/2earned
  • License2/2earned
  • Verified public repository2/2earned
04Platforms
05Labels