Skip to content

isocialPractice/vscode-emailClient

Repository files navigation

Email Client for VS Code

Read, preview, compose, and send email without leaving VS Code. The extension bridges globally installed extractemail and sendemail CLI tools behind a single three-pane mail interface, and ships a built-in mock email server so the entire UI works out of the box with no account, no credentials, and no network access.

Status: 0.1.0-alpha - early preview. The mock backend is fully functional; the live backend is experimental. See CHANGELOG.md.

Features

  • Three-pane mail UI - mailbox sidebar, message list, and reading pane in a VS Code webview panel that follows your color theme (light and dark).
  • Compose, reply, drafts - modal composer that sends as HTML, wraps messages in a <div>, generates quoted-reply blockquotes, and supports Ctrl+Enter to send.
  • Mock email server - a local, file-backed email server storing messages as simplified JMAP (RFC 8621) JSON. Use it for UI preview, automated tests, debugging, previewing email rendering, and mock sending.
  • Account registry with a management UI - configure real accounts as one-stop JSON in accounts/<name>.json containing IMAP and SMTP credentials. Email Client: Manage Accounts lists every account with Add, Edit, and Delete. Email Client: Create Account File opens the same Add Account form directly. See docs/ACCOUNTS.md.
  • Account profiles - alternatively, define named accounts in VS Code settings (emailClient.accounts) or as JSON files in a workspace folder's settings/accounts/ directory. Each profile bundles a backend with its configuration and identity; switch with Email Client: Select Account.
  • Live mode (experimental) - fetch real mail through the globally installed extractemail CLI (npm install -g extract-email) and send through the globally installed sendemail CLI (npm install -g send-email). No VS Code path settings are required when the tools are on PATH. Messages are opened with --html for full HTML rendering. Deleting a message moves it server-side to the Trash folder via --move trash.
  • Per-account folders - an account can declare the IMAP folders it wants in the sidebar ("folders": ["Sent", "Drafts", "Trash"] in its account file, profile, or the flat emailClient.folders setting). Each folder is read through extractemail --check "<folder>" and loads lazily the first time it is opened.
  • Safe HTML rendering - email bodies are sanitized in the extension host and rendered under a strict Content-Security-Policy. Scripts never run and remote images are blocked by default, matching desktop mail client privacy norms.
  • Unread badge - a status bar item shows the inbox unread count and opens the client on click.
  • Search and keyboard navigation - client-side filtering over sender, subject, and preview text; arrow-key navigation in the message list; full focus-visible support.

Quick Start (no account needed)

New here? QUICKSTART.md walks through first launch, the core flows, and connecting a real account in about five minutes.

  1. Clone the repository and install dependencies:

    npm install
    npm run build
  2. Open the folder in VS Code and press F5 (Run Extension). A new Extension Development Host window opens.

  3. In that window, run Email Client: Open from the Command Palette (Ctrl+Shift+P).

The client opens on the mock inbox with sample conversations between placeholder people (Jane Doe, John Smith, Alice, Bob) at example.com. Everything works immediately: read messages, flag them, reply, save drafts, delete to trash, and "send" mail that lands in the mock Sent folder.

Commands

Command Description
Email Client: Open Open (or focus) the mail panel.
Email Client: Compose Email Open the panel with the composer ready.
Email Client: Refresh Mailboxes Re-read mailboxes from the active backend.
Email Client: Switch Backend (Mock / Live) Toggle between the mock server and live mode (flat settings).
Email Client: Select Account Pick an account profile (or the default flat settings).
Email Client: Create Account File Open the Add Account form (same as Manage Accounts) to create a new accounts/<name>.json.
Email Client: Manage Accounts Open the account manager: list, add, edit, and delete accounts.
Email Client: Open Mock Server Data Folder Reveal the writable mock data folder in your file explorer.
Email Client: Reset Mock Server Data Restore the bundled sample mailboxes (discards local changes).

Full details: docs/COMMANDS.md.

Settings

Setting Default Description
emailClient.accountsRoot "" Folder holding the account registry; empty searches workspace folders and the extension folder.
emailClient.activeAccount "" Name of the account profile to use; empty uses the flat settings below.
emailClient.accounts [] Account profiles; also definable as settings/accounts/*.json files per workspace folder.
emailClient.backend mock mock (local JSON mailboxes) or live.
emailClient.mockDataPath "" Custom mock data folder; empty uses a per-user writable copy of the bundled samples.
emailClient.extractEmailPath "" Path to a locally built extract-email installation. Leave empty when extractemail is on PATH.
emailClient.sendEmailPath "" Path to a locally built send-email installation. Leave empty when sendemail is on PATH.
emailClient.account "" Account name for the flat settings (not the registry).
emailClient.folders [] Extra IMAP folders (besides Inbox) listed in live mode with the flat settings.
emailClient.messageLimit 50 Messages loaded per mailbox.

Full details and live-mode setup: docs/CONFIGURATION.md.

The Mock Email Server

The mock server is a first-class feature, not a test shim. It stores each mailbox as one JSON file using a simplified JMAP Email shape:

{
  "id": "eml-1001",
  "from": [{ "name": "Jane Doe", "email": "jane.doe@example.com" }],
  "to": [{ "name": "Demo User", "email": "demo-user@example.com" }],
  "subject": "Welcome to Acme Corp - your onboarding checklist",
  "receivedAt": "2026-07-18T08:12:00Z",
  "keywords": { "$seen": false },
  "hasAttachment": false,
  "bodyValues": { "html": "<p>Welcome aboard!</p>" }
}

On first use the bundled samples are copied to a writable per-user location (VS Code global storage), so reading, flagging, sending, and deleting all persist between sessions without touching the shipped fixtures. Sending to bounce@example.com simulates a delivery failure so error handling can be exercised deliberately.

Format specification, data location, and fixture-authoring guide: docs/MOCK-SERVER.md.

Live Mode (experimental)

Live mode works with globally installed CLI tools. Install once:

Extract Email (extractEmail)

# outside of this directory
git clone https://github.com/isocialPractice/extractEmail.git
cd extractEmail
npm install
npm run build
npm link

Send Email (sendEmail)

# outside of this directory
git clone https://github.com/isocialPractice/sendEmail.git
cd sendEmail
npm install
npm run build
npm link

Then create an account in accounts/<name>.json:

{
  "myaccount": {
    "extract-email": {
      "imap": {
        "host": "imap.example.com",
        "port": 993,
        "user": "me@example.com",
        "password": "app-password",
        "tls": true
      }
    },
    "send-email": {
      "host": "smtp.example.com",
      "port": 587,
      "secure": false,
      "auth": { "user": "me@example.com", "pass": "app-password" }
    },
    "folders": ["Sent", "Drafts", "Trash"]
  }
}

The optional folders list adds those IMAP folders to the sidebar next to the inbox; leave it out for an inbox-only view.

Or use Email Client: Create Account File / Email Client: Manage Accounts to build this file through a GUI form. Then run Email Client: Select Account to activate it.

The extension calls extractemail --config=<name> <limit> to list messages, extractemail -n <N> --html --config=<name> to open individual messages in HTML, and extractemail -n <N> --move trash --config=<name> to delete. Folders other than the inbox are read by prepending --check "<folder>" to the same calls. Sending calls sendemail --send-to <addr> --subject <subject> --message-file <path> --force --account <name>.

No VS Code path settings are needed when the tools are on PATH. Set emailClient.extractEmailPath or emailClient.sendEmailPath only when pointing at a non-global local build.

Known alpha limitations: folders must be declared per account (the server's folder list is not auto-discovered), folder counts appear after a folder is first opened, IMAP flag changes other than trash-moves are session-local, and drafts require the mock backend. See docs/PORTING.md for the complete feature mapping.

Project Layout

├── src/
│   ├── extension.ts              Activation, commands, status bar
│   ├── panel/emailClientPanel.ts Webview panel and message pump
│   ├── services/
│   │   ├── backend.ts            EmailBackend interface
│   │   ├── mockEmailServer.ts    Mock server (file-backed backend)
│   │   ├── liveBackend.ts        Live backend (combines the bridges)
│   │   ├── extractEmailBridge.ts extract-email as an external API call
│   │   └── sendEmailBridge.ts    send-email engine as a dependency
│   ├── utils/                    Address parsing, HTML sanitizer, ESM import
│   ├── types.ts                  Domain model + webview protocol
│   └── test/                     node:test unit suites
├── media/                        Webview CSS and JS
├── mock-server/                  Bundled sample mailboxes (JMAP-style JSON)
└── docs/                         Detailed documentation

Documentation

Development

npm install         # install dev dependencies
npm run build       # compile TypeScript to dist/
npm run watch       # compile on change
npm test            # build + run unit tests (pure Node, no VS Code download)
npm run pre:publish # make file to install from vsix

Press F5 in VS Code to launch the Extension Development Host with the build task wired in.

Versioning note

The package version 0.1.0-alpha is a semver prerelease. The VS Code Marketplace requires a plain major.minor.patch version, so publishing will require bumping to (for example) 0.1.0. Local development and F5 runs are unaffected.

License

ISC

About

Read, preview, compose, and send email without leaving VS Code. The extension bridges globally installed `extractemail` and `sendemail` CLI tools behind a single three-pane mail interface, and ships a built-in **mock email server** so the entire UI works out of the box with no account, no credentials, and no network access.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors