chore: rename JMAP Webmail to Bulwark Webmail and update all URLs

This commit is contained in:
Linus Rath
2026-03-13 13:14:08 +01:00
parent 02344d169c
commit e85d0b946e
14 changed files with 74 additions and 74 deletions
+3 -3
View File
@@ -1,4 +1,4 @@
# JMAP Webmail — Production Configuration
# Bulwark Webmail — Production Configuration
# Copy this file to .env.local and fill in your values.
# For development with the built-in mock server, see .env.dev.example instead.
@@ -7,7 +7,7 @@
# =============================================================================
# App name displayed in the UI
APP_NAME=JMAP Webmail
APP_NAME=Bulwark Webmail
# URL of your JMAP-compatible mail server (required)
JMAP_SERVER_URL=https://your-jmap-server.com
@@ -94,5 +94,5 @@ JMAP_SERVER_URL=https://your-jmap-server.com
# These are baked into the bundle at build time. The runtime variables above
# take priority when both are set.
#
# NEXT_PUBLIC_APP_NAME=JMAP Webmail
# NEXT_PUBLIC_APP_NAME=Bulwark Webmail
# NEXT_PUBLIC_JMAP_SERVER_URL=https://your-jmap-server.com
+6 -6
View File
@@ -1,6 +1,6 @@
# Contributing to JMAP Webmail
# Contributing to Bulwark Webmail
Thank you for your interest in contributing to JMAP Webmail! This document provides guidelines and information for contributors.
Thank you for your interest in contributing to Bulwark Webmail! This document provides guidelines and information for contributors.
## Getting Started
@@ -8,8 +8,8 @@ Thank you for your interest in contributing to JMAP Webmail! This document provi
1. **Fork and clone** the repository:
```bash
git clone https://github.com/root-fr/jmap-webmail.git
cd jmap-webmail
git clone https://github.com/bulwarkmail/webmail.git
cd webmail
```
2. **Install dependencies**:
@@ -156,7 +156,7 @@ docs: update README with keyboard shortcuts
## Project Structure
```
jmap-webmail/
webmail/
├── app/ # Next.js App Router pages
│ └── [locale]/ # Locale-aware routing
├── components/ # React components
@@ -187,4 +187,4 @@ If you have questions about contributing, feel free to:
- Open an issue for discussion
- Check existing issues and pull requests
Thank you for helping improve JMAP Webmail!
Thank you for helping improve Bulwark Webmail!
+3 -3
View File
@@ -8,10 +8,10 @@ RUN npx next build --webpack
FROM node:24-alpine AS runner
LABEL org.opencontainers.image.title="JMAP Webmail"
LABEL org.opencontainers.image.title="Bulwark Webmail"
LABEL org.opencontainers.image.description="Modern webmail client built with Next.js and the JMAP protocol"
LABEL org.opencontainers.image.source="https://github.com/root-fr/jmap-webmail"
LABEL org.opencontainers.image.url="https://github.com/root-fr/jmap-webmail"
LABEL org.opencontainers.image.source="https://github.com/bulwarkmail/webmail"
LABEL org.opencontainers.image.url="https://github.com/bulwarkmail/webmail"
LABEL org.opencontainers.image.licenses="MIT"
LABEL org.opencontainers.image.vendor="root.cloud"
+8 -8
View File
@@ -1,4 +1,4 @@
# JMAP Webmail
# Bulwark Webmail
A webmail client for [Stalwart Mail Server](https://stalw.art/), built with Next.js and the JMAP protocol.
@@ -126,7 +126,7 @@ Stalwart is a mail server written in Rust with native JMAP support, not IMAP/SMT
### Deployment
- Pre-built Docker images on [Docker Hub](https://hub.docker.com/r/rootfr/jmap-webmail) and [GHCR](https://ghcr.io/root-fr/jmap-webmail) (amd64/arm64)
- Pre-built Docker images on [Docker Hub](https://hub.docker.com/r/bulwarkmail/webmail) and [GHCR](https://ghcr.io/bulwarkmail/webmail) (amd64/arm64)
- Multi-stage build with standalone output
- Runtime environment variables (no rebuild needed)
- Health check endpoint
@@ -153,8 +153,8 @@ Stalwart is a mail server written in Rust with native JMAP support, not IMAP/SMT
### Installation
```bash
git clone https://github.com/root-fr/jmap-webmail.git
cd jmap-webmail
git clone https://github.com/bulwarkmail/webmail.git
cd webmail
npm install
cp .env.example .env.local
```
@@ -215,10 +215,10 @@ npm start
```bash
# Pre-built image
docker run -p 3000:3000 -e JMAP_SERVER_URL=https://mail.example.com rootfr/jmap-webmail:latest
docker run -p 3000:3000 -e JMAP_SERVER_URL=https://mail.example.com bulwarkmail/webmail:latest
# From GHCR
docker run -p 3000:3000 -e JMAP_SERVER_URL=https://mail.example.com ghcr.io/root-fr/jmap-webmail:latest
docker run -p 3000:3000 -e JMAP_SERVER_URL=https://mail.example.com ghcr.io/bulwarkmail/webmail:latest
# With docker compose
cp .env.example .env.local
@@ -226,8 +226,8 @@ cp .env.example .env.local
docker compose up -d
# Build from source
docker build -t jmap-webmail .
docker run -p 3000:3000 -e JMAP_SERVER_URL=https://mail.example.com jmap-webmail
docker build -t bulwark-webmail .
docker run -p 3000:3000 -e JMAP_SERVER_URL=https://mail.example.com bulwark-webmail
```
## Keyboard shortcuts
+3 -3
View File
@@ -1,6 +1,6 @@
# JMAP Webmail - Roadmap
# Bulwark Webmail - Roadmap
This document tracks the development status and planned features for JMAP Webmail.
This document tracks the development status and planned features for Bulwark Webmail.
## Completed Features
@@ -230,7 +230,7 @@ This document tracks the development status and planned features for JMAP Webmai
- [x] Health check endpoint
- [x] Docker support (multi-stage build, docker-compose, standalone output)
- [x] Structured server-side logger (text/JSON format, configurable level)
- [x] Pre-built Docker image on [Docker Hub](https://hub.docker.com/r/rootfr/jmap-webmail) and [GHCR](https://ghcr.io/root-fr/jmap-webmail) with multi-arch support (amd64/arm64)
- [x] Pre-built Docker image on [Docker Hub](https://hub.docker.com/r/bulwarkmail/webmail) and [GHCR](https://ghcr.io/bulwarkmail/webmail) with multi-arch support (amd64/arm64)
- [x] GitHub Actions CI/CD for automated image publishing on releases
- [x] CVE remediation: remove npm from production image, upgrade Alpine packages
- [x] Server-side update check (logs newer version availability on startup)
+13 -13
View File
@@ -108,14 +108,14 @@ const emails: MockEmail[] = [
id: 'email-001', threadId: 'thread-001', mailboxIds: { 'mb-inbox': true }, keywords: {}, size: 4200, receivedAt: daysAgo(0),
from: [{ name: 'Sophie Müller', email: 'sophie@eurotech.example' }],
to: [{ name: 'Dev User', email: 'dev@localhost' }], cc: [],
subject: 'Willkommen bei JMAP Webmail!',
preview: 'Hallo! This is a sample email to help you get started with the JMAP Webmail development environment.',
subject: 'Willkommen bei Bulwark Webmail!',
preview: 'Hallo! This is a sample email to help you get started with the Bulwark Webmail development environment.',
hasAttachment: false,
textBody: [{ partId: 'p1', blobId: 'blob-001', size: 280, type: 'text/plain' }],
htmlBody: [{ partId: 'p2', blobId: 'blob-002', size: 420, type: 'text/html' }],
bodyValues: {
p1: { value: 'Hallo!\n\nThis is a sample email to help you get started with the JMAP Webmail development environment.\n\nFeel free to explore the UI — all data here is mock data.\n\nBeste Grüße,\nSophie' },
p2: { value: '<p>Hallo!</p><p>This is a sample email to help you get started with the <strong>JMAP Webmail</strong> development environment.</p><p>Feel free to explore the UI — all data here is mock data.</p><p>Beste Grüße,<br>Sophie</p>' },
p1: { value: 'Hallo!\n\nThis is a sample email to help you get started with the Bulwark Webmail development environment.\n\nFeel free to explore the UI — all data here is mock data.\n\nBeste Grüße,\nSophie' },
p2: { value: '<p>Hallo!</p><p>This is a sample email to help you get started with the <strong>Bulwark Webmail</strong> development environment.</p><p>Feel free to explore the UI — all data here is mock data.</p><p>Beste Grüße,<br>Sophie</p>' },
},
},
{
@@ -154,7 +154,7 @@ const emails: MockEmail[] = [
id: 'email-004', threadId: 'thread-004', mailboxIds: { 'mb-inbox': true }, keywords: { '$label:red': true }, size: 6200, receivedAt: daysAgo(0),
from: [{ name: 'GitHub Notifications', email: 'notifications@github.com' }],
to: [{ name: 'Dev User', email: 'dev@localhost' }], cc: [],
subject: '[jmap-webmail] New issue: Add dark mode toggle (#42)',
subject: '[bulwark-webmail] New issue: Add dark mode toggle (#42)',
preview: 'A new issue has been opened by @contributor. It would be great to have a dark mode toggle in the settings panel.',
hasAttachment: false,
textBody: [{ partId: 'p1', blobId: 'blob-007', size: 350, type: 'text/plain' }],
@@ -236,8 +236,8 @@ const emails: MockEmail[] = [
textBody: [{ partId: 'p1', blobId: 'blob-034', size: 380, type: 'text/plain' }],
htmlBody: [{ partId: 'p2', blobId: 'blob-035', size: 520, type: 'text/html' }],
bodyValues: {
p1: { value: 'Salut,\n\nI just pushed the contact vCard import feature (JMAP-342). Could you review when you get a chance?\n\nPR: https://github.example/jmap-webmail/pull/342\n\nKey changes:\n- New vCard parser with v3/v4 support\n- Batch import with progress indicator\n- Duplicate detection and merge UI\n- Unit tests for edge cases\n\nMerci d\'avance,\nÉlise' },
p2: { value: '<p>Salut,</p><p>I just pushed the contact vCard import feature (<code>JMAP-342</code>). Could you review when you get a chance?</p><p>PR: <a href="#">jmap-webmail/pull/342</a></p><h4>Key changes:</h4><ul><li>New vCard parser with v3/v4 support</li><li>Batch import with progress indicator</li><li>Duplicate detection and merge UI</li><li>Unit tests for edge cases</li></ul><p>Merci d\'avance,<br>Élise</p>' },
p1: { value: 'Salut,\n\nI just pushed the contact vCard import feature (JMAP-342). Could you review when you get a chance?\n\nPR: https://github.example/bulwark-webmail/pull/342\n\nKey changes:\n- New vCard parser with v3/v4 support\n- Batch import with progress indicator\n- Duplicate detection and merge UI\n- Unit tests for edge cases\n\nMerci d\'avance,\nÉlise' },
p2: { value: '<p>Salut,</p><p>I just pushed the contact vCard import feature (<code>JMAP-342</code>). Could you review when you get a chance?</p><p>PR: <a href="#">bulwark-webmail/pull/342</a></p><h4>Key changes:</h4><ul><li>New vCard parser with v3/v4 support</li><li>Batch import with progress indicator</li><li>Duplicate detection and merge UI</li><li>Unit tests for edge cases</li></ul><p>Merci d\'avance,<br>Élise</p>' },
},
},
{
@@ -407,7 +407,7 @@ const emails: MockEmail[] = [
textBody: [{ partId: 'p1', blobId: 'blob-063', size: 350, type: 'text/plain' }],
htmlBody: [],
bodyValues: {
p1: { value: '¡Hola!\n\nThe new brand guidelines are finalized. Key updates:\n\n- Primary color shifted to #7c3aed (from #6366f1)\n- New typography scale (Inter for body, Cal Sans for headings)\n- Updated icon set (Lucide → custom icon font)\n- Dark mode color tokens added\n\nI\'ve also updated the Figma component library. Link: figma.example/jmap-webmail-v2\n\nBrand guidelines PDF attached.\n\nMaría' },
p1: { value: '¡Hola!\n\nThe new brand guidelines are finalized. Key updates:\n\n- Primary color shifted to #7c3aed (from #6366f1)\n- New typography scale (Inter for body, Cal Sans for headings)\n- Updated icon set (Lucide → custom icon font)\n- Dark mode color tokens added\n\nI\'ve also updated the Figma component library. Link: figma.example/bulwark-webmail-v2\n\nBrand guidelines PDF attached.\n\nMaría' },
},
attachments: [
{ partId: 'att10', blobId: 'blob-att-010', size: 3200000, name: 'Markenrichtlinien-v2.pdf', type: 'application/pdf' },
@@ -430,14 +430,14 @@ const emails: MockEmail[] = [
id: 'email-039', threadId: 'thread-034', mailboxIds: { 'mb-inbox': true }, keywords: {}, size: 3400, receivedAt: hoursAgo(0.25),
from: [{ name: 'CI/CD Pipeline', email: 'ci@github.example' }],
to: [{ name: 'Dev User', email: 'dev@localhost' }], cc: [],
subject: '❌ Build failed: main — jmap-webmail #1337',
subject: '❌ Build failed: main — bulwark-webmail #1337',
preview: 'Build #1337 on branch main failed. 2 test(s) failed in email-sanitization.test.ts.',
hasAttachment: false,
textBody: [{ partId: 'p1', blobId: 'blob-060', size: 450, type: 'text/plain' }],
htmlBody: [{ partId: 'p2', blobId: 'blob-061', size: 600, type: 'text/html' }],
bodyValues: {
p1: { value: '❌ Build #1337 FAILED\n\nRepository: jmap-webmail\nBranch: main\nCommit: a3f9c21 "fix: sanitize CSS in email body"\nTriggered by: @elise-moreau\n\nFailed tests:\n ✗ email-sanitization.test.ts > should strip javascript: URLs\n ✗ email-sanitization.test.ts > should handle nested style tags\n\nPassed: 247 | Failed: 2 | Skipped: 0\nDuration: 42.0s\n\nView full logs: https://github.example/jmap-webmail/actions/runs/1337' },
p2: { value: '<h3>❌ Build #1337 FAILED</h3><table><tr><td>Repository</td><td>jmap-webmail</td></tr><tr><td>Branch</td><td><code>main</code></td></tr><tr><td>Commit</td><td><code>a3f9c21</code> "fix: sanitize CSS in email body"</td></tr></table><h4>Failed tests:</h4><ul><li>❌ <code>email-sanitization.test.ts</code> &gt; should strip javascript: URLs</li><li>❌ <code>email-sanitization.test.ts</code> &gt; should handle nested style tags</li></ul><p><strong>Passed: 247</strong> | <strong style="color:red">Failed: 2</strong> | Skipped: 0</p>' },
p1: { value: '❌ Build #1337 FAILED\n\nRepository: bulwark-webmail\nBranch: main\nCommit: a3f9c21 "fix: sanitize CSS in email body"\nTriggered by: @elise-moreau\n\nFailed tests:\n ✗ email-sanitization.test.ts > should strip javascript: URLs\n ✗ email-sanitization.test.ts > should handle nested style tags\n\nPassed: 247 | Failed: 2 | Skipped: 0\nDuration: 42.0s\n\nView full logs: https://github.example/bulwark-webmail/actions/runs/1337' },
p2: { value: '<h3>❌ Build #1337 FAILED</h3><table><tr><td>Repository</td><td>bulwark-webmail</td></tr><tr><td>Branch</td><td><code>main</code></td></tr><tr><td>Commit</td><td><code>a3f9c21</code> "fix: sanitize CSS in email body"</td></tr></table><h4>Failed tests:</h4><ul><li>❌ <code>email-sanitization.test.ts</code> &gt; should strip javascript: URLs</li><li>❌ <code>email-sanitization.test.ts</code> &gt; should handle nested style tags</li></ul><p><strong>Passed: 247</strong> | <strong style="color:red">Failed: 2</strong> | Skipped: 0</p>' },
},
},
// =====================================================================
@@ -729,8 +729,8 @@ const IDENTITIES = [
email: 'dev@localhost',
replyTo: null,
bcc: null,
textSignature: '-- \nDev User\nJMAP Webmail Developer',
htmlSignature: '<p>--<br>Dev User<br><em>JMAP Webmail Developer</em></p>',
textSignature: '-- \nDev User\nBulwark Webmail Developer',
htmlSignature: '<p>--<br>Dev User<br><em>Bulwark Webmail Developer</em></p>',
mayDelete: false,
},
];
+1 -1
View File
@@ -15,7 +15,7 @@ const geistMono = Geist_Mono({
});
export const metadata: Metadata = {
title: "JMAP Webmail",
title: "Bulwark Webmail",
description: "Minimalist webmail client using JMAP protocol",
};
+1 -1
View File
@@ -1,6 +1,6 @@
services:
webmail:
image: ghcr.io/rathlinus/jmap-webmail:latest
image: ghcr.io/bulwarkmail/webmail:latest
ports:
- "3000:3000"
env_file:
+3 -3
View File
@@ -1,7 +1,7 @@
import { readFileSync } from "fs";
const VERSION_CHECK_URL =
"https://raw.githubusercontent.com/root-fr/jmap-webmail/main/VERSION";
"https://raw.githubusercontent.com/bulwarkmail/webmail/main/VERSION";
const SEMVER_RE = /^\d+\.\d+\.\d+$/;
@@ -19,7 +19,7 @@ const pkg = JSON.parse(
readFileSync(`${process.cwd()}/package.json`, "utf-8")
);
const current: string = pkg.version ?? "0.0.0";
console.info(`JMAP Webmail v${current}`);
console.info(`Bulwark Webmail v${current}`);
if (process.env.NODE_ENV === "production") {
fetch(VERSION_CHECK_URL, {
@@ -36,7 +36,7 @@ if (process.env.NODE_ENV === "production") {
if (!SEMVER_RE.test(remote)) return;
if (compareVersions(current, remote) > 0) {
console.info(
`Update available: v${remote} — https://github.com/root-fr/jmap-webmail`
`Update available: v${remote} — https://github.com/bulwarkmail/webmail`
);
}
})
+2 -2
View File
@@ -1,11 +1,11 @@
{
"name": "jmap-webmail",
"name": "bulwark-webmail",
"version": "1.1.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "jmap-webmail",
"name": "bulwark-webmail",
"version": "1.1.2",
"license": "MIT",
"dependencies": {
+5 -5
View File
@@ -1,16 +1,16 @@
{
"name": "jmap-webmail",
"name": "bulwark-webmail",
"version": "1.1.2",
"description": "A modern JMAP webmail client built for Stalwart Mail Server",
"description": "Bulwark Webmail — a modern webmail client built for Stalwart Mail Server",
"author": "Matthieu MALVACHE <matthieu@root.cloud>",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/root-fr/jmap-webmail.git"
"url": "git+https://github.com/bulwarkmail/webmail.git"
},
"homepage": "https://github.com/root-fr/jmap-webmail",
"homepage": "https://github.com/bulwarkmail/webmail",
"bugs": {
"url": "https://github.com/root-fr/jmap-webmail/issues"
"url": "https://github.com/bulwarkmail/webmail/issues"
},
"keywords": [
"jmap",
+16 -16
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
# =============================================================================
# JMAP Webmail - Interactive Setup Script
# Bulwark Webmail - Interactive Setup Script
# =============================================================================
set -euo pipefail
@@ -51,7 +51,7 @@ set -u
ENV_FILE="${SCRIPT_DIR}/.env.local"
# Config values (defaults)
CFG_APP_NAME="JMAP Webmail"
CFG_APP_NAME="Bulwark Webmail"
CFG_JMAP_SERVER_URL=""
CFG_STALWART_FEATURES="true"
CFG_OAUTH_ENABLED="false"
@@ -396,9 +396,9 @@ draw_header() {
echo ""
if [[ "$DRY_RUN" == true ]]; then
box "JMAP WEBMAIL SETUP -- DRY RUN" "$MAGENTA"
box "BULWARK WEBMAIL SETUP -- DRY RUN" "$MAGENTA"
else
box "JMAP WEBMAIL SETUP" "$CYAN"
box "BULWARK WEBMAIL SETUP" "$CYAN"
fi
echo ""
@@ -444,7 +444,7 @@ screen_welcome() {
local version
version=$(cat "${SCRIPT_DIR}/VERSION" 2>/dev/null || echo "dev")
print_center "${BOLD}Welcome to JMAP Webmail${RESET}"
print_center "${BOLD}Welcome to Bulwark Webmail${RESET}"
print_center "${DIM}v${version}${RESET}"
echo ""
echo ""
@@ -542,7 +542,7 @@ screen_server_config() {
draw_header
section_header 1 "Server Configuration" \
"Point JMAP Webmail at your mail server."
"Point Bulwark Webmail at your mail server."
echo -e " ${BOLD}General${RESET}"
echo -e " ${DIM}This name appears in the browser tab and on the login page.${RESET}"
@@ -719,7 +719,7 @@ screen_logging_config() {
draw_header
section_header 4 "Logging" \
"Control how JMAP Webmail writes logs."
"Control how Bulwark Webmail writes logs."
echo -e " ${BOLD}Log Format${RESET}"
echo ""
@@ -788,7 +788,7 @@ screen_deployment() {
draw_header
section_header 6 "Deployment Method" \
"Choose how you want to run JMAP Webmail."
"Choose how you want to run Bulwark Webmail."
local docker_available=false
command -v docker &>/dev/null && docker_available=true
@@ -940,7 +940,7 @@ write_env_file() {
cat > "$ENV_FILE" << ENVEOF
# =============================================================================
# JMAP Webmail -- Configuration
# Bulwark Webmail -- Configuration
# Generated by setup.sh on $(date '+%Y-%m-%d %H:%M:%S')
# =============================================================================
@@ -1026,7 +1026,7 @@ run_deployment() {
echo -e " ${DIM}[dry-run] Would start: npm start (port ${CFG_PORT})${RESET}"
;;
"docker")
echo -e " ${DIM}[dry-run] Would run: docker pull ghcr.io/rathlinus/jmap-webmail:latest${RESET}"
echo -e " ${DIM}[dry-run] Would run: docker pull ghcr.io/bulwarkmail/webmail:latest${RESET}"
echo -e " ${DIM}[dry-run] Would start: container on port ${CFG_PORT}${RESET}"
;;
"compose")
@@ -1063,8 +1063,8 @@ run_deployment() {
"docker")
echo -e " ${BOLD}Pulling Docker image...${RESET}"
echo ""
(docker pull ghcr.io/rathlinus/jmap-webmail:latest 2>&1) &
spinner $! "Pulling ghcr.io/rathlinus/jmap-webmail:latest"
(docker pull ghcr.io/bulwarkmail/webmail:latest 2>&1) &
spinner $! "Pulling ghcr.io/bulwarkmail/webmail:latest"
echo ""
echo -e " ${OK} Image pulled!"
@@ -1072,11 +1072,11 @@ run_deployment() {
echo -e " ${BOLD}To run the container:${RESET}"
echo ""
echo -e " ${CYAN}docker run -d \\${RESET}"
echo -e " ${CYAN} --name jmap-webmail \\${RESET}"
echo -e " ${CYAN} --name bulwark-webmail \\${RESET}"
echo -e " ${CYAN} -p ${CFG_PORT}:3000 \\${RESET}"
echo -e " ${CYAN} --env-file .env.local \\${RESET}"
echo -e " ${CYAN} --restart unless-stopped \\${RESET}"
echo -e " ${CYAN} ghcr.io/rathlinus/jmap-webmail:latest${RESET}"
echo -e " ${CYAN} ghcr.io/bulwarkmail/webmail:latest${RESET}"
;;
"compose")
@@ -1136,7 +1136,7 @@ screen_complete() {
echo ""
hr
echo ""
print_center "${DIM}Thank you for using JMAP Webmail!${RESET}"
print_center "${DIM}Thank you for using Bulwark Webmail!${RESET}"
echo ""
}
@@ -1217,7 +1217,7 @@ elif [[ -r /dev/tty ]] 2>/dev/null && (echo < /dev/tty) 2>/dev/null; then
else
echo "Error: No interactive terminal available."
echo "Download and run the script directly instead:"
echo " curl -fsSL https://raw.githubusercontent.com/rathlinus/jmap-webmail/main/setup.sh -o setup.sh"
echo " curl -fsSL https://raw.githubusercontent.com/bulwarkmail/webmail/main/setup.sh -o setup.sh"
echo " bash setup.sh --dry-run"
exit 1
fi
+6 -6
View File
@@ -24,7 +24,7 @@
## 1. Overview
This document describes a system that allows the JMAP Webmail application to be extended through **themes** (visual customization) and **plugins** (functional extensions). Together, these are called **addons**.
This document describes a system that allows the Bulwark Webmail application to be extended through **themes** (visual customization) and **plugins** (functional extensions). Together, these are called **addons**.
### Design Goals
@@ -240,7 +240,7 @@ A plugin exports a single `activate` function and optionally a `deactivate` func
```ts
// index.ts — Plugin entry point
import type { PluginContext } from "@jmap-webmail/addon-api";
import type { PluginContext } from "@bulwarkmail/addon-api";
export function activate(ctx: PluginContext) {
// Register a sidebar section
@@ -817,7 +817,7 @@ Some hooks allow plugins to transform data flowing through them. For example, `e
ctx.hooks.on("email:compose:before-send", (draft) => {
return {
...draft,
htmlBody: draft.htmlBody + "<p>Sent from JMAP Webmail</p>",
htmlBody: draft.htmlBody + "<p>Sent from Bulwark Webmail</p>",
};
});
```
@@ -866,8 +866,8 @@ useHostTheme(): { mode: "light" | "dark"; resolvedMode: "light" | "dark" };
### Phase 3: Developer Experience
- [ ] Create `@jmap-webmail/addon-api` — TypeScript type definitions package.
- [ ] Create `create-jmap-addon` CLI scaffolding tool.
- [ ] Create `@bulwarkmail/addon-api` — TypeScript type definitions package.
- [ ] Create `create-bulwark-addon` CLI scaffolding tool.
- [ ] Write addon developer documentation with examples.
- [ ] Build a sample plugin (e.g., email translation) as a reference.
- [ ] Add dev mode: hot-reload addons from local filesystem.
@@ -896,7 +896,7 @@ nord-theme/
`addon.json`:
```json
{
"id": "org.nordtheme.jmap-webmail",
"id": "org.nordtheme.bulwark-webmail",
"name": "Nord",
"version": "1.0.0",
"type": "theme",
+4 -4
View File
@@ -1280,8 +1280,8 @@ export const useEmailStore = create<EmailStore>((set, get) => ({
receivedAt: new Date().toISOString(),
from: [{ name: "GitHub", email: "notifications@github.com" }],
to: [{ email: "you@example.com" }],
subject: "[jmap-webmail] New pull request #42: Add OAuth2 module",
preview: "dependabot[bot] opened a pull request in root-fr/jmap-webmail. This PR adds a comprehensive authentication module with OAuth2 PKCE support...",
subject: "[bulwark-webmail] New pull request #42: Add OAuth2 module",
preview: "dependabot[bot] opened a pull request in bulwarkmail/webmail. This PR adds a comprehensive authentication module with OAuth2 PKCE support...",
hasAttachment: false,
},
{
@@ -1358,8 +1358,8 @@ export const useEmailStore = create<EmailStore>((set, get) => ({
receivedAt: new Date(Date.now() - 172800000).toISOString(),
from: [{ name: "Vercel", email: "notifications@vercel.com" }],
to: [{ email: "you@example.com" }],
subject: "Deployment successful: jmap-webmail \u2192 Production",
preview: "Your project jmap-webmail has been deployed to production. Build completed in 47s. All checks passed. Preview: https://jmap-webmail.vercel.app...",
subject: "Deployment successful: bulwark-webmail \u2192 Production",
preview: "Your project bulwark-webmail has been deployed to production. Build completed in 47s. All checks passed. Preview: https://bulwark-webmail.vercel.app...",
hasAttachment: false,
},
{