Skip to content

feat: full Cloudflare email SDK surface (@mvrx/mail 1.0.0) - #1

Merged
owenob1 merged 1 commit into
mainfrom
feat/full-sdk
Jul 6, 2026
Merged

feat: full Cloudflare email SDK surface (@mvrx/mail 1.0.0)#1
owenob1 merged 1 commit into
mainfrom
feat/full-sdk

Conversation

@owenob1

@owenob1 owenob1 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Builds @mvrx/mail out from a thin @mvrx/aecs re-export into the complete AECS-SDK-1 surface. Every module implements against the interfaces already declared in adapters.ts.

Modules

Core (@mvrx/mail)

  • storaged1Init, d1Store, getThread, getMessage, listMessages (fixed §3.7 DDL, cursor-based §3.8 pagination, raw D1 prepared statements)
  • sendsendEmail
  • rulesevaluateRules + Rule/Condition/Action + D1 rule storage (§15)

Subpaths

  • /transportscfTransport, smtpTransport, r2BlobStore (§3.5)
  • /providers — 8 AI connectors: cf, openai, anthropic, gemini, mistral, azure, ollama, openai-compat (§6)
  • /tools — deterministic analysis (§7.1)
  • /ai-tools — summarize, classify, sentiment, extractEntities, extractAction, ask (§7.2)
  • /compose — draft, reply, improve, tone, translate, suggestSubjects, send, createCompose (§8)
  • /attachmentsattachmentsForAI, AttachmentProcessor, processors (chain, storeToR2, pdfToText, ocr, transcribe, cfPdfExtractor, runOcr, runTranscribe) (§9)
  • /hubUserHub Durable Object + publishEvent/hubRouter/hubBus, typed MailEvent union, SSE fan-out (§16)

Verification

  • 111 tests via @cloudflare/vitest-pool-workers — real D1/R2/Durable Object bindings in workerd, not mocks.
  • pnpm -r typecheck + pnpm -r build clean.
  • Example worker (examples/basic-worker) runs the full receive → store → rules → events → classify → reply loop and typechecks against the built package.

Notes / judgment calls

  • smtpTransport throws a clear "inject your own client" error rather than fake a send (no bundled SMTP socket).
  • Multimodal processors (ocr/transcribe/cfPdfExtractor) take the raw Ai binding, not the text-only AiChatProvider; real Workers-AI extraction is exercised on deploy (unit tests assert model + input shape via a mocked binding).
  • hub is SSE / fire-and-forget with no replay (§16.5) — events are "go refetch" signals; D1 is the source of truth.
  • Version 0.1.0 → 1.0.0 (Appendix C: full surface stable).

Related

Depends conceptually on mvrxapp/aecs#1 (§9.7 attachmentsInForAI), but this PR does not require it — @mvrx/mail/attachments ships its own attachmentsForAI().

Builds out @mvrx/mail from a thin @mvrx/aecs re-export into the complete
AECS-SDK-1 surface. All modules implement against the interfaces already
defined in adapters.ts.

Core (package root):
- storage: d1Init, d1Store, getThread, getMessage, listMessages
  (fixed §3.7 DDL, cursor-based §3.8 pagination, raw D1 prepared stmts)
- send: sendEmail
- rules: evaluateRules + Rule/Condition/Action types + D1 rule storage (§15)

Subpath entry points:
- /transports: cfTransport, smtpTransport, r2BlobStore (§3.5)
- /providers: 8 AI connectors — cf, openai, anthropic, gemini, mistral,
  azure, ollama, openai-compat (§6)
- /tools: deterministic analysis — extractAddresses, detectIntent,
  requiresReply, extractDates, extractLinks (§7.1)
- /ai-tools: summarize, classify, sentiment, extractEntities,
  extractAction, ask (§7.2)
- /compose: draft, reply, improve, tone, translate, suggestSubjects,
  send, createCompose (§8)
- /attachments: attachmentsForAI, AttachmentProcessor, processors
  (chain, storeToR2, pdfToText, ocr, transcribe, cfPdfExtractor,
  runOcr, runTranscribe) (§9)
- /hub: UserHub Durable Object + publishEvent/hubRouter/hubBus, typed
  MailEvent union, SSE fan-out, fire-and-forget (§16)

Tests: 111 passing via @cloudflare/vitest-pool-workers with real D1/R2/DO
bindings in workerd (not mocks). Example worker demonstrates the full
receive -> store -> rules -> events -> classify -> reply loop and
typechecks against the built package.

Version 0.1.0 -> 1.0.0 (Appendix C: full surface stable).

Signed-off-by: owenob1 <me@oweninnes.com>
@owenob1
owenob1 merged commit fb71ab8 into main Jul 6, 2026
2 checks passed
@owenob1
owenob1 deleted the feat/full-sdk branch July 6, 2026 16:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant