fluxmail 0.0.1 → 0.2.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.
Files changed (92) hide show
  1. package/README.md +37 -10
  2. package/dist/accounts/googleAuth.d.ts +31 -0
  3. package/dist/accounts/googleAuth.d.ts.map +1 -0
  4. package/dist/accounts/googleAuth.js +147 -0
  5. package/dist/accounts/googleAuth.js.map +1 -0
  6. package/dist/accounts/registry.d.ts +37 -0
  7. package/dist/accounts/registry.d.ts.map +1 -0
  8. package/dist/accounts/registry.js +278 -0
  9. package/dist/accounts/registry.js.map +1 -0
  10. package/dist/cli.d.ts +3 -0
  11. package/dist/cli.d.ts.map +1 -0
  12. package/dist/cli.js +629 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/config.d.ts +40 -0
  15. package/dist/config.d.ts.map +1 -0
  16. package/dist/config.js +216 -0
  17. package/dist/config.js.map +1 -0
  18. package/dist/context.d.ts +15 -0
  19. package/dist/context.d.ts.map +1 -0
  20. package/dist/context.js +15 -0
  21. package/dist/context.js.map +1 -0
  22. package/dist/http/app.d.ts +16 -0
  23. package/dist/http/app.d.ts.map +1 -0
  24. package/dist/http/app.js +118 -0
  25. package/dist/http/app.js.map +1 -0
  26. package/dist/index.d.ts +14 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +14 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/licensing/activation.d.ts +5 -0
  31. package/dist/licensing/activation.d.ts.map +1 -0
  32. package/dist/licensing/activation.js +11 -0
  33. package/dist/licensing/activation.js.map +1 -0
  34. package/dist/licensing/client.d.ts +52 -0
  35. package/dist/licensing/client.d.ts.map +1 -0
  36. package/dist/licensing/client.js +75 -0
  37. package/dist/licensing/client.js.map +1 -0
  38. package/dist/licensing/entitlements.d.ts +55 -0
  39. package/dist/licensing/entitlements.d.ts.map +1 -0
  40. package/dist/licensing/entitlements.js +116 -0
  41. package/dist/licensing/entitlements.js.map +1 -0
  42. package/dist/licensing/lease.d.ts +47 -0
  43. package/dist/licensing/lease.d.ts.map +1 -0
  44. package/dist/licensing/lease.js +103 -0
  45. package/dist/licensing/lease.js.map +1 -0
  46. package/dist/licensing/refresher.d.ts +46 -0
  47. package/dist/licensing/refresher.d.ts.map +1 -0
  48. package/dist/licensing/refresher.js +150 -0
  49. package/dist/licensing/refresher.js.map +1 -0
  50. package/dist/mcp/buildServer.d.ts +28 -0
  51. package/dist/mcp/buildServer.d.ts.map +1 -0
  52. package/dist/mcp/buildServer.js +414 -0
  53. package/dist/mcp/buildServer.js.map +1 -0
  54. package/dist/scheduler/sendScheduler.d.ts +38 -0
  55. package/dist/scheduler/sendScheduler.d.ts.map +1 -0
  56. package/dist/scheduler/sendScheduler.js +128 -0
  57. package/dist/scheduler/sendScheduler.js.map +1 -0
  58. package/dist/service/emailService.d.ts +139 -0
  59. package/dist/service/emailService.d.ts.map +1 -0
  60. package/dist/service/emailService.js +380 -0
  61. package/dist/service/emailService.js.map +1 -0
  62. package/dist/storage/apiKeys.d.ts +27 -0
  63. package/dist/storage/apiKeys.d.ts.map +1 -0
  64. package/dist/storage/apiKeys.js +49 -0
  65. package/dist/storage/apiKeys.js.map +1 -0
  66. package/dist/storage/crypto.d.ts +4 -0
  67. package/dist/storage/crypto.d.ts.map +1 -0
  68. package/dist/storage/crypto.js +21 -0
  69. package/dist/storage/crypto.js.map +1 -0
  70. package/dist/storage/db.d.ts +1041 -0
  71. package/dist/storage/db.d.ts.map +1 -0
  72. package/dist/storage/db.js +211 -0
  73. package/dist/storage/db.js.map +1 -0
  74. package/dist/storage/imapState.d.ts +15 -0
  75. package/dist/storage/imapState.d.ts.map +1 -0
  76. package/dist/storage/imapState.js +89 -0
  77. package/dist/storage/imapState.js.map +1 -0
  78. package/dist/storage/members.d.ts +29 -0
  79. package/dist/storage/members.d.ts.map +1 -0
  80. package/dist/storage/members.js +67 -0
  81. package/dist/storage/members.js.map +1 -0
  82. package/dist/storage/scheduledSends.d.ts +60 -0
  83. package/dist/storage/scheduledSends.d.ts.map +1 -0
  84. package/dist/storage/scheduledSends.js +169 -0
  85. package/dist/storage/scheduledSends.js.map +1 -0
  86. package/dist/version.d.ts +2 -0
  87. package/dist/version.d.ts.map +1 -0
  88. package/dist/version.js +7 -0
  89. package/dist/version.js.map +1 -0
  90. package/package.json +49 -15
  91. package/bin/fluxmail.js +0 -4
  92. package/src/cli.js +0 -36
@@ -0,0 +1,169 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ import { and, eq, lte, or } from 'drizzle-orm';
3
+ import { EmailError } from '@fluxmail/core';
4
+ import { scheduledSends } from './db.js';
5
+ function toRow(r) {
6
+ return { ...r, status: r.status };
7
+ }
8
+ export function createScheduledSend(db, input) {
9
+ const id = `sch_${randomBytes(6).toString('hex')}`;
10
+ const createdAt = Date.now();
11
+ return db.transaction((tx) => {
12
+ const existing = tx
13
+ .select()
14
+ .from(scheduledSends)
15
+ .where(and(eq(scheduledSends.accountId, input.accountId), eq(scheduledSends.draftId, input.draftId), eq(scheduledSends.status, 'pending')))
16
+ .get();
17
+ if (existing) {
18
+ throw new EmailError('invalid_request', `Draft ${input.draftId} is already scheduled to send at ${new Date(existing.sendAt).toISOString()}; cancel it first to reschedule`);
19
+ }
20
+ const row = {
21
+ id,
22
+ accountId: input.accountId,
23
+ draftId: input.draftId,
24
+ sendAt: input.sendAt,
25
+ createdAt,
26
+ status: 'pending',
27
+ attempts: 0,
28
+ lastError: null,
29
+ sentMessageId: null,
30
+ sentThreadId: null,
31
+ subject: input.subject ?? null,
32
+ toRecipients: input.toRecipients ?? null,
33
+ claimToken: null,
34
+ claimUntil: null,
35
+ };
36
+ tx.insert(scheduledSends).values(row).run();
37
+ return toRow(row);
38
+ });
39
+ }
40
+ export function getScheduledSend(db, id) {
41
+ const row = db.select().from(scheduledSends).where(eq(scheduledSends.id, id)).get();
42
+ return row ? toRow(row) : undefined;
43
+ }
44
+ /** All schedules, pending first by due time, then the rest newest-first. */
45
+ export function listScheduledSends(db, accountId) {
46
+ const rows = accountId
47
+ ? db.select().from(scheduledSends).where(eq(scheduledSends.accountId, accountId)).all()
48
+ : db.select().from(scheduledSends).all();
49
+ return rows.map(toRow).sort((a, b) => {
50
+ if ((a.status === 'pending') !== (b.status === 'pending'))
51
+ return a.status === 'pending' ? -1 : 1;
52
+ return a.status === 'pending' ? a.sendAt - b.sendAt : b.createdAt - a.createdAt;
53
+ });
54
+ }
55
+ export function listPending(db) {
56
+ return db.select().from(scheduledSends).where(eq(scheduledSends.status, 'pending')).all().map(toRow);
57
+ }
58
+ export function listActive(db) {
59
+ return db
60
+ .select()
61
+ .from(scheduledSends)
62
+ .where(or(eq(scheduledSends.status, 'pending'), eq(scheduledSends.status, 'sending')))
63
+ .all()
64
+ .map(toRow);
65
+ }
66
+ export function findPendingByDraft(db, accountId, draftId) {
67
+ const row = db
68
+ .select()
69
+ .from(scheduledSends)
70
+ .where(and(eq(scheduledSends.accountId, accountId), eq(scheduledSends.draftId, draftId), eq(scheduledSends.status, 'pending')))
71
+ .get();
72
+ return row ? toRow(row) : undefined;
73
+ }
74
+ export function markSent(db, id, result) {
75
+ db.update(scheduledSends)
76
+ .set({ status: 'sent', sentMessageId: result.id, sentThreadId: result.threadId, lastError: null })
77
+ .where(eq(scheduledSends.id, id))
78
+ .run();
79
+ }
80
+ /** Atomically claim a due row so only one scheduler process can dispatch it. */
81
+ export function claimScheduledSend(db, id, now, leaseMs) {
82
+ const token = randomBytes(12).toString('hex');
83
+ const result = db
84
+ .update(scheduledSends)
85
+ .set({ status: 'sending', claimToken: token, claimUntil: now + leaseMs })
86
+ .where(and(eq(scheduledSends.id, id), or(eq(scheduledSends.status, 'pending'), and(eq(scheduledSends.status, 'sending'), lte(scheduledSends.claimUntil, now)))))
87
+ .run();
88
+ if (result.changes === 0)
89
+ return undefined;
90
+ return { row: getScheduledSend(db, id), token };
91
+ }
92
+ export function completeClaim(db, id, token, result) {
93
+ db.update(scheduledSends)
94
+ .set({
95
+ status: 'sent',
96
+ sentMessageId: result.id,
97
+ sentThreadId: result.threadId,
98
+ lastError: null,
99
+ claimToken: null,
100
+ claimUntil: null,
101
+ })
102
+ .where(and(eq(scheduledSends.id, id), eq(scheduledSends.claimToken, token)))
103
+ .run();
104
+ }
105
+ export function failClaim(db, id, token, error) {
106
+ db.update(scheduledSends)
107
+ .set({ status: 'failed', lastError: error, claimToken: null, claimUntil: null })
108
+ .where(and(eq(scheduledSends.id, id), eq(scheduledSends.claimToken, token)))
109
+ .run();
110
+ }
111
+ export function retryClaim(db, id, token, error) {
112
+ const row = getScheduledSend(db, id);
113
+ if (!row || row.claimToken !== token)
114
+ return;
115
+ db.update(scheduledSends)
116
+ .set({
117
+ status: 'pending',
118
+ attempts: row.attempts + 1,
119
+ lastError: error,
120
+ claimToken: null,
121
+ claimUntil: null,
122
+ })
123
+ .where(and(eq(scheduledSends.id, id), eq(scheduledSends.claimToken, token)))
124
+ .run();
125
+ }
126
+ export function listClaimable(db, now) {
127
+ return db
128
+ .select()
129
+ .from(scheduledSends)
130
+ .where(or(eq(scheduledSends.status, 'pending'), and(eq(scheduledSends.status, 'sending'), lte(scheduledSends.claimUntil, now))))
131
+ .all()
132
+ .map(toRow);
133
+ }
134
+ export function markFailed(db, id, error) {
135
+ db.update(scheduledSends).set({ status: 'failed', lastError: error }).where(eq(scheduledSends.id, id)).run();
136
+ }
137
+ /** Record why a pending send is held (e.g. plan quota) without consuming an attempt. */
138
+ export function holdPending(db, id, error) {
139
+ db.update(scheduledSends)
140
+ .set({ lastError: error })
141
+ .where(and(eq(scheduledSends.id, id), eq(scheduledSends.status, 'pending')))
142
+ .run();
143
+ }
144
+ /** Record a retryable failure: bump attempts, keep the row pending. */
145
+ export function recordAttempt(db, id, error) {
146
+ const row = db.select().from(scheduledSends).where(eq(scheduledSends.id, id)).get();
147
+ if (!row)
148
+ return;
149
+ db.update(scheduledSends)
150
+ .set({ attempts: row.attempts + 1, lastError: error })
151
+ .where(eq(scheduledSends.id, id))
152
+ .run();
153
+ }
154
+ /** Only pending schedules can be canceled; returns false otherwise. */
155
+ export function cancelScheduledSend(db, id) {
156
+ const result = db
157
+ .update(scheduledSends)
158
+ .set({ status: 'canceled' })
159
+ .where(and(eq(scheduledSends.id, id), eq(scheduledSends.status, 'pending')))
160
+ .run();
161
+ return result.changes > 0;
162
+ }
163
+ export function countPending(db) {
164
+ const rows = listActive(db);
165
+ if (!rows.length)
166
+ return { pending: 0 };
167
+ return { pending: rows.length, nextSendAt: Math.min(...rows.map((r) => r.sendAt)) };
168
+ }
169
+ //# sourceMappingURL=scheduledSends.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduledSends.js","sourceRoot":"","sources":["../../src/storage/scheduledSends.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const VERSION: string;
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,OAAO,QAAmB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { readFileSync } from 'node:fs';
2
+ const manifest = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
3
+ if (typeof manifest.version !== 'string' || manifest.version.length === 0) {
4
+ throw new Error('The fluxmail package manifest must define a version.');
5
+ }
6
+ export const VERSION = manifest.version;
7
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAMvC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAoB,CAAC;AAElH,IAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,QAAQ,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IAC1E,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC"}
package/package.json CHANGED
@@ -1,25 +1,59 @@
1
1
  {
2
2
  "name": "fluxmail",
3
- "version": "0.0.1",
4
- "description": "Fluxmail CLI",
3
+ "version": "0.2.0",
4
+ "description": "Fluxmail MCP server: unified email tools over Gmail and IMAP/SMTP",
5
+ "homepage": "https://github.com/churichard/fluxmail-mcp#readme",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/churichard/fluxmail-mcp.git",
9
+ "directory": "packages/server"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/churichard/fluxmail-mcp/issues"
13
+ },
5
14
  "type": "module",
15
+ "main": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
6
17
  "bin": {
7
- "fluxmail": "bin/fluxmail.js"
18
+ "fluxmail": "./dist/cli.js"
19
+ },
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/index.d.ts",
23
+ "default": "./dist/index.js"
24
+ }
8
25
  },
9
26
  "files": [
10
- "bin",
11
- "src"
27
+ "dist"
12
28
  ],
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
13
32
  "engines": {
14
- "node": ">=18"
33
+ "node": ">=20.19"
15
34
  },
16
- "scripts": {
17
- "start": "node bin/fluxmail.js"
35
+ "dependencies": {
36
+ "@hono/node-server": "^1.14.3",
37
+ "@modelcontextprotocol/sdk": "^1.13.0",
38
+ "better-sqlite3": "^11.10.0",
39
+ "commander": "^13.1.0",
40
+ "drizzle-orm": "^0.45.2",
41
+ "google-auth-library": "10.5.0",
42
+ "hono": "^4.7.11",
43
+ "zod": "^3.25.67",
44
+ "@fluxmail/core": "0.2.0",
45
+ "@fluxmail/provider-imap": "0.2.0",
46
+ "@fluxmail/provider-gmail": "0.2.0"
18
47
  },
19
- "keywords": [
20
- "cli",
21
- "fluxmail",
22
- "email"
23
- ],
24
- "license": "MIT"
25
- }
48
+ "devDependencies": {
49
+ "@types/better-sqlite3": "^7.6.13",
50
+ "@types/node": "^22.15.0",
51
+ "imapflow": "^1.4.7"
52
+ },
53
+ "scripts": {
54
+ "build": "tsc -p tsconfig.json",
55
+ "typecheck": "tsc -p tsconfig.json --noEmit",
56
+ "test": "vitest run",
57
+ "dev": "tsc -p tsconfig.json --watch"
58
+ }
59
+ }
package/bin/fluxmail.js DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env node
2
- import { run } from "../src/cli.js";
3
-
4
- run(process.argv.slice(2));
package/src/cli.js DELETED
@@ -1,36 +0,0 @@
1
- import { createRequire } from "node:module";
2
-
3
- const require = createRequire(import.meta.url);
4
- const { version } = require("../package.json");
5
-
6
- const HELP = `fluxmail — CLI
7
-
8
- Usage:
9
- fluxmail <command> [options]
10
-
11
- Commands:
12
- help Show this help
13
- version Print the version
14
-
15
- Options:
16
- -h, --help Show this help
17
- -v, --version Print the version
18
- `;
19
-
20
- export function run(argv = []) {
21
- const [command] = argv;
22
-
23
- if (argv.includes("-v") || argv.includes("--version") || command === "version") {
24
- console.log(version);
25
- return;
26
- }
27
-
28
- if (!command || argv.includes("-h") || argv.includes("--help") || command === "help") {
29
- console.log(HELP);
30
- return;
31
- }
32
-
33
- console.error(`fluxmail: unknown command '${command}'`);
34
- console.error("Run 'fluxmail help' for usage.");
35
- process.exitCode = 1;
36
- }