@zaclinley/dsh-mailharbor 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,38 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
5
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.1.0] - 2026-11-06
10
+
11
+ First public release: the core mail workspace, rebuilt on a real build pipeline.
12
+
13
+ ### Added
14
+
15
+ - Multi-account mailbox model: per-account data directory, IMAP/SMTP settings, drafts and read state.
16
+ - Local backup engine: incremental IMAP → SQLite by UID range, UIDVALIDITY handling, batched
17
+ transactions, content-addressed attachment files and a trigram full-text index.
18
+ - Read-only mail database view with paging, search and attachment streaming.
19
+ - Live server mode over IMAP (imapflow) with a recycled, serialized connection per account.
20
+ - Sending over SMTP through nodemailer: text + HTML alternatives, attachments, reply headers.
21
+ - Browser panel: folder/search list, reader (sandboxed HTML, remote images opt-in), composer with a
22
+ rich-text toolbar, drafts and explicit send confirmation.
23
+ - DSH Settings section: accounts, connection checks, signature, read-on-open, list size, AI model.
24
+ - Sidebar entry with an unread badge.
25
+ - Agent tools: `mail_status`, `mail_list`, `mail_read`, `mail_search`, `mail_drafts`, `mail_draft`,
26
+ `mail_backup`.
27
+ - Cross-platform credential storage: macOS Keychain, libsecret, Windows Credential Locker.
28
+ - Build pipeline (esbuild) that emits the DSH module-loader client bundle with the package id, plus a
29
+ Vitest suite (unit, HTTP integration, bundle contract).
30
+ - GitHub Actions CI and a Changesets release workflow with npm provenance.
31
+
32
+ ### Fixed (relative to the previous unpublished prototype)
33
+
34
+ - The client bundle now registers under the exact package name, which the DSH module loader keys
35
+ boot-graph rows by; the previous bundle id no longer matched after the package rename.
36
+ - The backup engine asks the server only for UIDs above the last committed one instead of listing
37
+ every UID on each run.
38
+ - SMTP is handled by nodemailer instead of a hand-written RFC 5322/MIME implementation.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Zac Linley
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,148 @@
1
- # Temporary Holding Version
1
+ # MailHarbor
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **A multi-account IMAP/SMTP mail workspace for [DeepSeek Harness](https://github.com/Zac-Linley/dsh-plugin-mailharbor).**
4
+
5
+ MailHarbor adds a **Mail** entry to the DSH sidebar and a full mail workspace to the main panel:
6
+ browse a local backup or live server mail, search, read HTML safely, write and send, keep drafts,
7
+ and let the model read mail through `mail_*` tools. Every account keeps its own database, drafts
8
+ and read state.
9
+
10
+ - Package: `@zaclinley/dsh-mailharbor`
11
+ - Requirements: **DSH `>=0.2.2-0 <0.3.0`**, Node **>=24.9** (the runtime bundled with DSH is fine)
12
+ - License: MIT
13
+ - Status: **v0.1.0 — core mail workspace**. OAuth2, AI actions and CalDAV are on the roadmap (see [Roadmap](#roadmap)).
14
+
15
+ ## Features
16
+
17
+ | Area | What you get |
18
+ | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
19
+ | Accounts | Any IMAP/SMTP mailbox; password or app password; per-account data directory; switch accounts from the top bar |
20
+ | Local backup | Incremental IMAP → SQLite backup with UIDVALIDITY handling, batched transactions, content-addressed attachments and a trigram full-text index |
21
+ | Browse | Folders, paging, search across subject/sender/recipients/body/attachment names |
22
+ | Live server | Read the newest messages straight from IMAP, with a **backed up / not backed up** marker per row |
23
+ | Reader | Sandboxed HTML rendering with a strict CSP, remote images off by default, plain-text fallback, attachment download |
24
+ | Compose | Rich-text body, attachments (8 MB), reply / reply-all / forward with `In-Reply-To` and `References`, save-as-draft, explicit send confirmation |
25
+ | Credentials | macOS Keychain, libsecret on Linux, Windows Credential Locker; passwords never enter `config.json` |
26
+ | Agent tools | `mail_status`, `mail_list`, `mail_read`, `mail_search`, `mail_drafts`, `mail_draft`, `mail_backup` |
27
+ | Settings | A **MailHarbor** section in DSH Settings: accounts, servers, connection checks, signature, read behaviour, list size, AI provider/model |
28
+ | Updates | A real build pipeline, GitHub Actions CI, Changesets versioning, and npm provenance |
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ dsh plugin --profile desktop add @zaclinley/dsh-mailharbor
34
+ ```
35
+
36
+ Reload the app window (or restart DSH) once so the browser bundle is picked up. The bundle layer in
37
+ `cordis.patch.yml` inserts the `mailharbor` row automatically.
38
+
39
+ From a local checkout:
40
+
41
+ ```bash
42
+ git clone https://github.com/Zac-Linley/dsh-plugin-mailharbor.git
43
+ cd dsh-plugin-mailharbor
44
+ npm ci && npm run build
45
+ dsh plugin --profile desktop add link:$PWD
46
+ ```
47
+
48
+ > If you previously installed the older `dsh-plugin-mail` package, remove that row first — both
49
+ > plugins claim the `/mail-plugin` HTTP prefix, and only one can own it.
50
+
51
+ ## First run
52
+
53
+ 1. Open the **MailHarbor** panel from the sidebar.
54
+ 2. Add an account: address + password (or app password). **Advanced** lets you set IMAP/SMTP hosts,
55
+ ports and TLS. The account is verified against IMAP before it is saved.
56
+ 3. Browse **Local backup** right away; press **Backup** to pull mail from the server.
57
+ 4. Switch to **Server live** for the newest messages. Press **Write** to compose.
58
+
59
+ ### Gmail, Outlook, and other providers
60
+
61
+ - Gmail: enable IMAP in Gmail settings and use an **app password** (2-Step Verification required).
62
+ OAuth2 sign-in arrives in v0.2.
63
+ - Microsoft 365: basic auth is disabled; use an app password only if your tenant still allows IMAP
64
+ AUTH, otherwise wait for the OAuth2 release.
65
+ - Yahoo: app password. Self-hosted: any IMAP/SMTP endpoints with STARTTLS or implicit TLS.
66
+
67
+ ## Data and privacy
68
+
69
+ | What | Where |
70
+ | ----------------------- | ------------------------------------------------------------------------------------ |
71
+ | Plugin state | `~/.dsh/mailharbor` (`DSH_MAILHARBOR_DATA_DIR`) |
72
+ | Config (no secrets) | `~/.dsh/mailharbor/config.json` (`DSH_MAILHARBOR_CONFIG`) |
73
+ | Per-account mail backup | `~/.dsh/mailharbor/accounts/<id>/mail.db` + `attachments/` |
74
+ | Drafts / read state | `<account>/drafts.json`, `<account>/read-state.json` |
75
+ | Passwords | OS credential store only; `DSH_MAILHARBOR_PASSWORD_<ACCOUNT_ID>` for scripted setups |
76
+
77
+ - The backup database is opened **read-only** by the panel and tools; only the backup engine writes.
78
+ - HTML mail renders in a `sandbox` iframe with `default-src 'none'`; scripts and forms never run, and
79
+ remote images are blocked until you ask for them.
80
+ - The HTTP API listens on DSH's own loopback server and rejects cross-site writes (`403`).
81
+ - `mail_*` tools never send mail: there is no `mail_send` tool. Sending is a user action in the panel.
82
+
83
+ ## Agent tools
84
+
85
+ | Tool | Purpose |
86
+ | ---------------------------- | ------------------------------------------------------ |
87
+ | `mail_status` | Account, login state, local total, last backup |
88
+ | `mail_list` | List local or server messages (folder, keyword, limit) |
89
+ | `mail_read` | Read one message, with attachment metadata |
90
+ | `mail_search` | Full-text search over the local backup |
91
+ | `mail_drafts` / `mail_draft` | List and write local drafts — never sends |
92
+ | `mail_backup` | Start an incremental backup in the background |
93
+
94
+ ## Development
95
+
96
+ ```bash
97
+ npm ci
98
+ npm run build # lib/index.js (Host) + lib/client.js (browser bundle)
99
+ npm run dev # rebuild on change; DSH hot-reloads the bundle
100
+ npm run typecheck
101
+ npm run lint
102
+ npm test # Vitest: unit + HTTP integration + bundle contract
103
+ npm run check # typecheck + lint + build + test + pack check
104
+ ```
105
+
106
+ Architecture:
107
+
108
+ ```
109
+ src/host/ Node half: config, credentials, IMAP, SMTP, SQLite, backup, HTTP API, tools
110
+ src/client/ Browser half: panel, reader, composer, settings, styles
111
+ src/shared/ Wire types shared by both halves
112
+ scripts/ build.mjs (esbuild), sync-version.mjs
113
+ test/ Vitest suites (fixtures are generated, no real mailbox needed)
114
+ ```
115
+
116
+ The browser bundle is built by esbuild into the DSH module-loader format
117
+ (`window.__ModuleLoader__.load({ id, factory })`), with `id` equal to the package name. React and
118
+ React DOM come from the shell's shared module table and are never bundled.
119
+
120
+ ### Releasing
121
+
122
+ Versions are managed with [Changesets](https://github.com/changesets/changesets):
123
+
124
+ ```bash
125
+ npx changeset # describe the change and pick a bump
126
+ npm run version # writes CHANGELOG.md and bumps package.json + VERSION constants
127
+ ```
128
+
129
+ CI publishes from `main` through `.github/workflows/release.yml`; the `NPM_TOKEN` repository secret
130
+ must be able to publish `@zaclinley/*`. See [CONTRIBUTING.md](CONTRIBUTING.md).
131
+
132
+ ## Roadmap
133
+
134
+ | Version | Scope |
135
+ | --------- | ---------------------------------------------------------------------------- |
136
+ | **0.1.x** | Core mail workspace, backup, tools, settings, publishing pipeline |
137
+ | 0.2 | OAuth2 + XOAUTH2 (Gmail loopback/PKCE, Microsoft device code), token refresh |
138
+ | 0.3 | AI summaries, compose assist, natural-language search, writing style profile |
139
+ | 0.4 | CalDAV tasks, Markdown/PDF reports |
140
+ | Later | Export/import, onboarding, richer attachments |
141
+
142
+ ## Star history
143
+
144
+ If MailHarbor is useful, a star helps other DSH users find it.
145
+
146
+ ## License
147
+
148
+ [MIT](LICENSE) © 2026 Zac Linley
package/README.zh.md ADDED
@@ -0,0 +1,140 @@
1
+ # MailHarbor(邮件港)
2
+
3
+ **把多个 IMAP/SMTP 邮箱接进 [DeepSeek Harness](https://github.com/Zac-Linley/dsh-plugin-mailharbor) 的邮件工作区。**
4
+
5
+ MailHarbor 在 DSH 左侧栏加一个「邮件」入口,主面板里是完整的收发邮件工作区:浏览本地备份或
6
+ 服务器实时邮件、搜索、安全地渲染 HTML 正文、写邮件与回复、保存草稿,也可以让模型通过
7
+ `mail_*` 工具直接读信。每个账号有独立的数据目录、草稿和已读状态。
8
+
9
+ - 包名:`@zaclinley/dsh-mailharbor`
10
+ - 要求:**DSH `>=0.2.2-0 <0.3.0`**,Node **>=24.9**(DSH 自带运行时即可)
11
+ - 许可证:MIT
12
+ - 状态:**v0.1.0 — 核心邮件工作区**。OAuth2、AI 动作和 CalDAV 在路线图中(见[路线图](#路线图))。
13
+
14
+ ## 功能
15
+
16
+ | 区域 | 能做什么 |
17
+ | ---------- | ----------------------------------------------------------------------------------------------------- |
18
+ | 账号 | 任意 IMAP/SMTP 邮箱;密码或应用专用密码;每账号独立数据目录;顶栏切换账号 |
19
+ | 本地备份 | 增量 IMAP → SQLite:UIDVALIDITY 处理、分批事务、内容寻址附件、trigram 全文索引 |
20
+ | 浏览 | 文件夹、分页、按主题/发件人/收件人/正文/附件名搜索 |
21
+ | 服务器实时 | 直接从 IMAP 读取最新邮件,每行标注「已备份 / 未备份」 |
22
+ | 阅读 | sandbox iframe + 严格 CSP 渲染 HTML,远程图片默认拦截,纯文本回退,附件下载 |
23
+ | 写邮件 | 富文本正文、附件(8 MB)、回复/全部回复/转发(`In-Reply-To` 与 `References`)、存草稿、二次确认后发送 |
24
+ | 凭据 | macOS 钥匙串、Linux libsecret、Windows Credential Locker;密码不写入 `config.json` |
25
+ | Agent 工具 | `mail_status`、`mail_list`、`mail_read`、`mail_search`、`mail_drafts`、`mail_draft`、`mail_backup` |
26
+ | 设置页 | DSH 设置里的「MailHarbor」:账号与服务器、连接检查、签名、已读行为、列表数量、AI 模型 |
27
+ | 工程化 | 真实构建链、GitHub Actions CI、Changesets 版本管理、npm provenance |
28
+
29
+ ## 安装
30
+
31
+ ```bash
32
+ dsh plugin --profile desktop add @zaclinley/dsh-mailharbor
33
+ ```
34
+
35
+ 安装后重新加载窗口(或重启 DSH),浏览器端插件包才会加载。包内的 `cordis.patch.yml`
36
+ 会自动插入 `mailharbor` 这一行。
37
+
38
+ 从本地仓库安装:
39
+
40
+ ```bash
41
+ git clone https://github.com/Zac-Linley/dsh-plugin-mailharbor.git
42
+ cd dsh-plugin-mailharbor
43
+ npm ci && npm run build
44
+ dsh plugin --profile desktop add link:$PWD
45
+ ```
46
+
47
+ > 如果之前装过旧的 `dsh-plugin-mail`,请先移除那一行:两个插件都占用 `/mail-plugin`
48
+ > 的 HTTP 前缀,只能有一个生效。
49
+
50
+ ## 第一次使用
51
+
52
+ 1. 从左侧栏打开 **MailHarbor**。
53
+ 2. 添加账号:邮箱地址 + 密码(或应用专用密码)。「高级设置」里可改 IMAP/SMTP 主机、端口和 TLS;
54
+ 保存前会真实连接一次 IMAP 校验。
55
+ 3. 先浏览 **本地备份**;点顶部「备份」把服务器邮件同步下来。
56
+ 4. 切到 **服务器实时** 看最新邮件,点「写邮件」开始写信。
57
+
58
+ ### Gmail、Outlook 与其他服务商
59
+
60
+ - Gmail:在 Gmail 设置里启用 IMAP,使用**应用专用密码**(需先开启两步验证)。OAuth2 登录在 v0.2 提供。
61
+ - Microsoft 365:基本认证已停用;只有租户仍允许 IMAP AUTH 时才能用应用专用密码,否则等 OAuth2 版本。
62
+ - Yahoo:应用专用密码。自建邮箱:任何支持 STARTTLS 或隐式 TLS 的 IMAP/SMTP 都可以。
63
+
64
+ ## 数据与隐私
65
+
66
+ | 内容 | 位置 |
67
+ | ---------------- | --------------------------------------------------------------------- |
68
+ | 插件状态 | `~/.dsh/mailharbor`(`DSH_MAILHARBOR_DATA_DIR`) |
69
+ | 配置(不含密码) | `~/.dsh/mailharbor/config.json`(`DSH_MAILHARBOR_CONFIG`) |
70
+ | 每账号备份库 | `~/.dsh/mailharbor/accounts/<id>/mail.db` + `attachments/` |
71
+ | 草稿 / 已读 | `<account>/drafts.json`、`<account>/read-state.json` |
72
+ | 密码 | 只进系统凭据库;脚本化场景可用 `DSH_MAILHARBOR_PASSWORD_<ACCOUNT_ID>` |
73
+
74
+ - 面板和工具以**只读**方式打开备份库,只有备份引擎会写入。
75
+ - HTML 邮件在 `sandbox` iframe 中渲染,CSP 为 `default-src 'none'`;脚本、表单不执行,远程图片默认不加载。
76
+ - HTTP 接口只监听 DSH 自己的回环端口,跨站写请求返回 `403`。
77
+ - `mail_*` 工具不能发信:没有 `mail_send`,发送必须由用户在面板里确认。
78
+
79
+ ## Agent 工具
80
+
81
+ | 工具 | 用途 |
82
+ | ---------------------------- | -------------------------------------------- |
83
+ | `mail_status` | 账号、登录状态、本地邮件数、上次备份 |
84
+ | `mail_list` | 列出本地或服务器邮件(文件夹、关键词、条数) |
85
+ | `mail_read` | 读一封邮件全文,带附件元数据 |
86
+ | `mail_search` | 本地备份全文搜索 |
87
+ | `mail_drafts` / `mail_draft` | 列出、新建或更新本地草稿——永不发送 |
88
+ | `mail_backup` | 后台启动一次增量备份 |
89
+
90
+ ## 开发
91
+
92
+ ```bash
93
+ npm ci
94
+ npm run build # lib/index.js(Host)+ lib/client.js(浏览器包)
95
+ npm run dev # 监听改动,DSH 自动热重载
96
+ npm run typecheck
97
+ npm run lint
98
+ npm test # Vitest:单元 + HTTP 集成 + 构建产物契约
99
+ npm run check # typecheck + lint + build + test + pack 检查
100
+ ```
101
+
102
+ 目录结构:
103
+
104
+ ```
105
+ src/host/ Node 端:配置、凭据、IMAP、SMTP、SQLite、备份、HTTP API、工具
106
+ src/client/ 浏览器端:面板、阅读页、写信、设置、样式
107
+ src/shared/ 两端共享的协议类型
108
+ scripts/ build.mjs(esbuild)、sync-version.mjs
109
+ test/ Vitest 测试(fixture 自动生成,不需要真实邮箱)
110
+ ```
111
+
112
+ 浏览器包由 esbuild 构建成 DSH 的模块加载格式
113
+ (`window.__ModuleLoader__.load({ id, factory })`),`id` 必须等于包名。React / React DOM
114
+ 来自宿主共享模块表,不打进包里。
115
+
116
+ ### 发布
117
+
118
+ 版本用 [Changesets](https://github.com/changesets/changesets) 管理:
119
+
120
+ ```bash
121
+ npx changeset # 描述改动并选择 bump 级别
122
+ npm run version # 写 CHANGELOG.md,更新 package.json 与 VERSION 常量
123
+ ```
124
+
125
+ CI 会在 `main` 上通过 `.github/workflows/release.yml` 发布;仓库需要配置有 `@zaclinley/*`
126
+ 发布权限的 `NPM_TOKEN` secret。详见 [CONTRIBUTING.md](CONTRIBUTING.md)。
127
+
128
+ ## 路线图
129
+
130
+ | 版本 | 范围 |
131
+ | --------- | --------------------------------------------------------------------- |
132
+ | **0.1.x** | 核心邮件工作区、备份、工具、设置、发布流水线 |
133
+ | 0.2 | OAuth2 + XOAUTH2(Gmail loopback/PKCE、Microsoft 设备码)、token 刷新 |
134
+ | 0.3 | AI 摘要、起草辅助、自然语言搜索、写作风格档案 |
135
+ | 0.4 | CalDAV 任务、Markdown/PDF 报告 |
136
+ | 以后 | 导出/导入、引导流程、更完整的附件支持 |
137
+
138
+ ## 许可证
139
+
140
+ [MIT](LICENSE) © 2026 Zac Linley
@@ -0,0 +1,5 @@
1
+ # MailHarbor bundle layer: mount the mail workspace in a DSH profile.
2
+ # `dsh plugin add @zaclinley/dsh-mailharbor` applies this layer automatically.
3
+ - insert:
4
+ - id: mailharbor
5
+ name: '@zaclinley/dsh-mailharbor'