@diskd-ai/email-mcp 0.3.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 (295) hide show
  1. package/LICENSE +155 -0
  2. package/README.md +820 -0
  3. package/dist/cli/account-commands.d.ts +10 -0
  4. package/dist/cli/account-commands.d.ts.map +1 -0
  5. package/dist/cli/account-commands.js +703 -0
  6. package/dist/cli/account-commands.js.map +1 -0
  7. package/dist/cli/config-commands.d.ts +9 -0
  8. package/dist/cli/config-commands.d.ts.map +1 -0
  9. package/dist/cli/config-commands.js +156 -0
  10. package/dist/cli/config-commands.js.map +1 -0
  11. package/dist/cli/guard.d.ts +11 -0
  12. package/dist/cli/guard.d.ts.map +1 -0
  13. package/dist/cli/guard.js +18 -0
  14. package/dist/cli/guard.js.map +1 -0
  15. package/dist/cli/install-commands.d.ts +12 -0
  16. package/dist/cli/install-commands.d.ts.map +1 -0
  17. package/dist/cli/install-commands.js +320 -0
  18. package/dist/cli/install-commands.js.map +1 -0
  19. package/dist/cli/notify.d.ts +8 -0
  20. package/dist/cli/notify.d.ts.map +1 -0
  21. package/dist/cli/notify.js +143 -0
  22. package/dist/cli/notify.js.map +1 -0
  23. package/dist/cli/providers.d.ts +13 -0
  24. package/dist/cli/providers.d.ts.map +1 -0
  25. package/dist/cli/providers.js +180 -0
  26. package/dist/cli/providers.js.map +1 -0
  27. package/dist/cli/scheduler.d.ts +8 -0
  28. package/dist/cli/scheduler.d.ts.map +1 -0
  29. package/dist/cli/scheduler.js +268 -0
  30. package/dist/cli/scheduler.js.map +1 -0
  31. package/dist/cli/setup.d.ts +12 -0
  32. package/dist/cli/setup.d.ts.map +1 -0
  33. package/dist/cli/setup.js +15 -0
  34. package/dist/cli/setup.js.map +1 -0
  35. package/dist/cli/test.d.ts +7 -0
  36. package/dist/cli/test.d.ts.map +1 -0
  37. package/dist/cli/test.js +67 -0
  38. package/dist/cli/test.js.map +1 -0
  39. package/dist/config/loader.d.ts +34 -0
  40. package/dist/config/loader.d.ts.map +1 -0
  41. package/dist/config/loader.js +339 -0
  42. package/dist/config/loader.js.map +1 -0
  43. package/dist/config/schema.d.ts +351 -0
  44. package/dist/config/schema.d.ts.map +1 -0
  45. package/dist/config/schema.js +165 -0
  46. package/dist/config/schema.js.map +1 -0
  47. package/dist/config/xdg.d.ts +27 -0
  48. package/dist/config/xdg.d.ts.map +1 -0
  49. package/dist/config/xdg.js +30 -0
  50. package/dist/config/xdg.js.map +1 -0
  51. package/dist/connections/manager.d.ts +42 -0
  52. package/dist/connections/manager.d.ts.map +1 -0
  53. package/dist/connections/manager.js +266 -0
  54. package/dist/connections/manager.js.map +1 -0
  55. package/dist/connections/types.d.ts +13 -0
  56. package/dist/connections/types.d.ts.map +1 -0
  57. package/dist/connections/types.js +2 -0
  58. package/dist/connections/types.js.map +1 -0
  59. package/dist/logging.d.ts +46 -0
  60. package/dist/logging.d.ts.map +1 -0
  61. package/dist/logging.js +63 -0
  62. package/dist/logging.js.map +1 -0
  63. package/dist/main.d.ts +13 -0
  64. package/dist/main.d.ts.map +1 -0
  65. package/dist/main.js +206 -0
  66. package/dist/main.js.map +1 -0
  67. package/dist/prompts/actions.prompt.d.ts +9 -0
  68. package/dist/prompts/actions.prompt.d.ts.map +1 -0
  69. package/dist/prompts/actions.prompt.js +64 -0
  70. package/dist/prompts/actions.prompt.js.map +1 -0
  71. package/dist/prompts/calendar.prompt.d.ts +9 -0
  72. package/dist/prompts/calendar.prompt.d.ts.map +1 -0
  73. package/dist/prompts/calendar.prompt.js +55 -0
  74. package/dist/prompts/calendar.prompt.js.map +1 -0
  75. package/dist/prompts/cleanup.prompt.d.ts +9 -0
  76. package/dist/prompts/cleanup.prompt.d.ts.map +1 -0
  77. package/dist/prompts/cleanup.prompt.js +78 -0
  78. package/dist/prompts/cleanup.prompt.js.map +1 -0
  79. package/dist/prompts/compose.prompt.d.ts +8 -0
  80. package/dist/prompts/compose.prompt.d.ts.map +1 -0
  81. package/dist/prompts/compose.prompt.js +116 -0
  82. package/dist/prompts/compose.prompt.js.map +1 -0
  83. package/dist/prompts/register.d.ts +8 -0
  84. package/dist/prompts/register.d.ts.map +1 -0
  85. package/dist/prompts/register.js +20 -0
  86. package/dist/prompts/register.js.map +1 -0
  87. package/dist/prompts/thread.prompt.d.ts +9 -0
  88. package/dist/prompts/thread.prompt.d.ts.map +1 -0
  89. package/dist/prompts/thread.prompt.js +58 -0
  90. package/dist/prompts/thread.prompt.js.map +1 -0
  91. package/dist/prompts/triage.prompt.d.ts +9 -0
  92. package/dist/prompts/triage.prompt.d.ts.map +1 -0
  93. package/dist/prompts/triage.prompt.js +64 -0
  94. package/dist/prompts/triage.prompt.js.map +1 -0
  95. package/dist/resources/accounts.resource.d.ts +9 -0
  96. package/dist/resources/accounts.resource.d.ts.map +1 -0
  97. package/dist/resources/accounts.resource.js +26 -0
  98. package/dist/resources/accounts.resource.js.map +1 -0
  99. package/dist/resources/mailboxes.resource.d.ts +10 -0
  100. package/dist/resources/mailboxes.resource.d.ts.map +1 -0
  101. package/dist/resources/mailboxes.resource.js +33 -0
  102. package/dist/resources/mailboxes.resource.js.map +1 -0
  103. package/dist/resources/register.d.ts +12 -0
  104. package/dist/resources/register.d.ts.map +1 -0
  105. package/dist/resources/register.js +20 -0
  106. package/dist/resources/register.js.map +1 -0
  107. package/dist/resources/scheduled.resource.d.ts +9 -0
  108. package/dist/resources/scheduled.resource.d.ts.map +1 -0
  109. package/dist/resources/scheduled.resource.js +31 -0
  110. package/dist/resources/scheduled.resource.js.map +1 -0
  111. package/dist/resources/stats.resource.d.ts +10 -0
  112. package/dist/resources/stats.resource.d.ts.map +1 -0
  113. package/dist/resources/stats.resource.js +45 -0
  114. package/dist/resources/stats.resource.js.map +1 -0
  115. package/dist/resources/templates.resource.d.ts +9 -0
  116. package/dist/resources/templates.resource.d.ts.map +1 -0
  117. package/dist/resources/templates.resource.js +34 -0
  118. package/dist/resources/templates.resource.js.map +1 -0
  119. package/dist/resources/unread.resource.d.ts +11 -0
  120. package/dist/resources/unread.resource.d.ts.map +1 -0
  121. package/dist/resources/unread.resource.js +46 -0
  122. package/dist/resources/unread.resource.js.map +1 -0
  123. package/dist/safety/audit.d.ts +17 -0
  124. package/dist/safety/audit.d.ts.map +1 -0
  125. package/dist/safety/audit.js +50 -0
  126. package/dist/safety/audit.js.map +1 -0
  127. package/dist/safety/rate-limiter.d.ts +22 -0
  128. package/dist/safety/rate-limiter.d.ts.map +1 -0
  129. package/dist/safety/rate-limiter.js +52 -0
  130. package/dist/safety/rate-limiter.js.map +1 -0
  131. package/dist/safety/validation.d.ts +44 -0
  132. package/dist/safety/validation.d.ts.map +1 -0
  133. package/dist/safety/validation.js +113 -0
  134. package/dist/safety/validation.js.map +1 -0
  135. package/dist/server.d.ts +10 -0
  136. package/dist/server.d.ts.map +1 -0
  137. package/dist/server.js +25 -0
  138. package/dist/server.js.map +1 -0
  139. package/dist/services/calendar.service.d.ts +22 -0
  140. package/dist/services/calendar.service.d.ts.map +1 -0
  141. package/dist/services/calendar.service.js +115 -0
  142. package/dist/services/calendar.service.js.map +1 -0
  143. package/dist/services/event-bus.d.ts +28 -0
  144. package/dist/services/event-bus.d.ts.map +1 -0
  145. package/dist/services/event-bus.js +16 -0
  146. package/dist/services/event-bus.js.map +1 -0
  147. package/dist/services/hooks.service.d.ts +77 -0
  148. package/dist/services/hooks.service.d.ts.map +1 -0
  149. package/dist/services/hooks.service.js +498 -0
  150. package/dist/services/hooks.service.js.map +1 -0
  151. package/dist/services/imap.service.d.ts +133 -0
  152. package/dist/services/imap.service.d.ts.map +1 -0
  153. package/dist/services/imap.service.js +1393 -0
  154. package/dist/services/imap.service.js.map +1 -0
  155. package/dist/services/label-strategy.d.ts +20 -0
  156. package/dist/services/label-strategy.d.ts.map +1 -0
  157. package/dist/services/label-strategy.js +237 -0
  158. package/dist/services/label-strategy.js.map +1 -0
  159. package/dist/services/local-calendar.service.d.ts +126 -0
  160. package/dist/services/local-calendar.service.d.ts.map +1 -0
  161. package/dist/services/local-calendar.service.js +428 -0
  162. package/dist/services/local-calendar.service.js.map +1 -0
  163. package/dist/services/notifier.service.d.ts +69 -0
  164. package/dist/services/notifier.service.d.ts.map +1 -0
  165. package/dist/services/notifier.service.js +319 -0
  166. package/dist/services/notifier.service.js.map +1 -0
  167. package/dist/services/oauth.service.d.ts +47 -0
  168. package/dist/services/oauth.service.d.ts.map +1 -0
  169. package/dist/services/oauth.service.js +140 -0
  170. package/dist/services/oauth.service.js.map +1 -0
  171. package/dist/services/presets.d.ts +36 -0
  172. package/dist/services/presets.d.ts.map +1 -0
  173. package/dist/services/presets.js +173 -0
  174. package/dist/services/presets.js.map +1 -0
  175. package/dist/services/reminders.service.d.ts +63 -0
  176. package/dist/services/reminders.service.d.ts.map +1 -0
  177. package/dist/services/reminders.service.js +281 -0
  178. package/dist/services/reminders.service.js.map +1 -0
  179. package/dist/services/scheduler.service.d.ts +42 -0
  180. package/dist/services/scheduler.service.d.ts.map +1 -0
  181. package/dist/services/scheduler.service.js +260 -0
  182. package/dist/services/scheduler.service.js.map +1 -0
  183. package/dist/services/smtp.service.d.ts +40 -0
  184. package/dist/services/smtp.service.d.ts.map +1 -0
  185. package/dist/services/smtp.service.js +151 -0
  186. package/dist/services/smtp.service.js.map +1 -0
  187. package/dist/services/template.service.d.ts +33 -0
  188. package/dist/services/template.service.d.ts.map +1 -0
  189. package/dist/services/template.service.js +123 -0
  190. package/dist/services/template.service.js.map +1 -0
  191. package/dist/services/watcher.service.d.ts +36 -0
  192. package/dist/services/watcher.service.d.ts.map +1 -0
  193. package/dist/services/watcher.service.js +241 -0
  194. package/dist/services/watcher.service.js.map +1 -0
  195. package/dist/tools/accounts.tool.d.ts +7 -0
  196. package/dist/tools/accounts.tool.d.ts.map +1 -0
  197. package/dist/tools/accounts.tool.js +29 -0
  198. package/dist/tools/accounts.tool.js.map +1 -0
  199. package/dist/tools/analytics.tool.d.ts +9 -0
  200. package/dist/tools/analytics.tool.d.ts.map +1 -0
  201. package/dist/tools/analytics.tool.js +27 -0
  202. package/dist/tools/analytics.tool.js.map +1 -0
  203. package/dist/tools/attachments.tool.d.ts +7 -0
  204. package/dist/tools/attachments.tool.d.ts.map +1 -0
  205. package/dist/tools/attachments.tool.js +45 -0
  206. package/dist/tools/attachments.tool.js.map +1 -0
  207. package/dist/tools/bulk.tool.d.ts +7 -0
  208. package/dist/tools/bulk.tool.d.ts.map +1 -0
  209. package/dist/tools/bulk.tool.js +75 -0
  210. package/dist/tools/bulk.tool.js.map +1 -0
  211. package/dist/tools/calendar.tool.d.ts +19 -0
  212. package/dist/tools/calendar.tool.d.ts.map +1 -0
  213. package/dist/tools/calendar.tool.js +538 -0
  214. package/dist/tools/calendar.tool.js.map +1 -0
  215. package/dist/tools/contacts.tool.d.ts +7 -0
  216. package/dist/tools/contacts.tool.d.ts.map +1 -0
  217. package/dist/tools/contacts.tool.js +44 -0
  218. package/dist/tools/contacts.tool.js.map +1 -0
  219. package/dist/tools/drafts.tool.d.ts +8 -0
  220. package/dist/tools/drafts.tool.d.ts.map +1 -0
  221. package/dist/tools/drafts.tool.js +92 -0
  222. package/dist/tools/drafts.tool.js.map +1 -0
  223. package/dist/tools/emails.tool.d.ts +7 -0
  224. package/dist/tools/emails.tool.d.ts.map +1 -0
  225. package/dist/tools/emails.tool.js +400 -0
  226. package/dist/tools/emails.tool.js.map +1 -0
  227. package/dist/tools/folders.tool.d.ts +7 -0
  228. package/dist/tools/folders.tool.d.ts.map +1 -0
  229. package/dist/tools/folders.tool.js +111 -0
  230. package/dist/tools/folders.tool.js.map +1 -0
  231. package/dist/tools/health.tool.d.ts +10 -0
  232. package/dist/tools/health.tool.d.ts.map +1 -0
  233. package/dist/tools/health.tool.js +78 -0
  234. package/dist/tools/health.tool.js.map +1 -0
  235. package/dist/tools/label.tool.d.ts +11 -0
  236. package/dist/tools/label.tool.d.ts.map +1 -0
  237. package/dist/tools/label.tool.js +165 -0
  238. package/dist/tools/label.tool.js.map +1 -0
  239. package/dist/tools/locate.tool.d.ts +11 -0
  240. package/dist/tools/locate.tool.d.ts.map +1 -0
  241. package/dist/tools/locate.tool.js +59 -0
  242. package/dist/tools/locate.tool.js.map +1 -0
  243. package/dist/tools/mailboxes.tool.d.ts +7 -0
  244. package/dist/tools/mailboxes.tool.d.ts.map +1 -0
  245. package/dist/tools/mailboxes.tool.js +38 -0
  246. package/dist/tools/mailboxes.tool.js.map +1 -0
  247. package/dist/tools/manage.tool.d.ts +7 -0
  248. package/dist/tools/manage.tool.d.ts.map +1 -0
  249. package/dist/tools/manage.tool.js +125 -0
  250. package/dist/tools/manage.tool.js.map +1 -0
  251. package/dist/tools/register.d.ts +20 -0
  252. package/dist/tools/register.d.ts.map +1 -0
  253. package/dist/tools/register.js +53 -0
  254. package/dist/tools/register.js.map +1 -0
  255. package/dist/tools/scheduler.tool.d.ts +9 -0
  256. package/dist/tools/scheduler.tool.d.ts.map +1 -0
  257. package/dist/tools/scheduler.tool.js +104 -0
  258. package/dist/tools/scheduler.tool.js.map +1 -0
  259. package/dist/tools/send.tool.d.ts +7 -0
  260. package/dist/tools/send.tool.d.ts.map +1 -0
  261. package/dist/tools/send.tool.js +123 -0
  262. package/dist/tools/send.tool.js.map +1 -0
  263. package/dist/tools/templates.tool.d.ts +12 -0
  264. package/dist/tools/templates.tool.d.ts.map +1 -0
  265. package/dist/tools/templates.tool.js +140 -0
  266. package/dist/tools/templates.tool.js.map +1 -0
  267. package/dist/tools/thread.tool.d.ts +10 -0
  268. package/dist/tools/thread.tool.d.ts.map +1 -0
  269. package/dist/tools/thread.tool.js +146 -0
  270. package/dist/tools/thread.tool.js.map +1 -0
  271. package/dist/tools/watcher.tool.d.ts +9 -0
  272. package/dist/tools/watcher.tool.d.ts.map +1 -0
  273. package/dist/tools/watcher.tool.js +282 -0
  274. package/dist/tools/watcher.tool.js.map +1 -0
  275. package/dist/types/index.d.ts +271 -0
  276. package/dist/types/index.d.ts.map +1 -0
  277. package/dist/types/index.js +5 -0
  278. package/dist/types/index.js.map +1 -0
  279. package/dist/utils/calendar-notes.d.ts +31 -0
  280. package/dist/utils/calendar-notes.d.ts.map +1 -0
  281. package/dist/utils/calendar-notes.js +99 -0
  282. package/dist/utils/calendar-notes.js.map +1 -0
  283. package/dist/utils/calendar-state.d.ts +27 -0
  284. package/dist/utils/calendar-state.d.ts.map +1 -0
  285. package/dist/utils/calendar-state.js +85 -0
  286. package/dist/utils/calendar-state.js.map +1 -0
  287. package/dist/utils/conference-details.d.ts +12 -0
  288. package/dist/utils/conference-details.d.ts.map +1 -0
  289. package/dist/utils/conference-details.js +71 -0
  290. package/dist/utils/conference-details.js.map +1 -0
  291. package/dist/utils/meeting-url.d.ts +10 -0
  292. package/dist/utils/meeting-url.d.ts.map +1 -0
  293. package/dist/utils/meeting-url.js +30 -0
  294. package/dist/utils/meeting-url.js.map +1 -0
  295. package/package.json +108 -0
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Built-in hook presets — ready-to-use AI triage profiles.
3
+ *
4
+ * Each preset provides a system prompt template, suggested labels,
5
+ * and a description. Users select a preset in config.toml and can
6
+ * append their own `custom_instructions` for personalisation.
7
+ */
8
+ // ---------------------------------------------------------------------------
9
+ // Preset definitions
10
+ // ---------------------------------------------------------------------------
11
+ const inboxZero = {
12
+ id: 'inbox-zero',
13
+ name: 'Inbox Zero',
14
+ description: 'Aggressive categorisation and archival. Every email gets a label, newsletters and notifications are low-priority, urgent items are flagged.',
15
+ suggestedLabels: [
16
+ 'Newsletter',
17
+ 'Notification',
18
+ 'Updates',
19
+ 'Finance',
20
+ 'Social',
21
+ 'Promo',
22
+ 'Urgent',
23
+ 'Action Needed',
24
+ 'FYI',
25
+ ],
26
+ systemPrompt: `You are an email triage assistant following the Inbox Zero methodology.
27
+ Your goal is to help the user reach and maintain an empty inbox by categorising every email.
28
+
29
+ Guidelines:
30
+ - Newsletters, marketing, and automated notifications → low priority.
31
+ - Emails that require the user to DO something → "Action Needed" label + high/urgent priority.
32
+ - Financial emails (invoices, receipts, statements) → "Finance" label.
33
+ - Social notifications (LinkedIn, Twitter, etc.) → "Social" label.
34
+ - Promotional offers and sales → "Promo" label.
35
+ - Everything informational that needs no action → "FYI" label.
36
+ - Flag truly urgent or time-sensitive emails.
37
+
38
+ {{CUSTOM}}
39
+
40
+ Use ONLY these suggested labels when possible: {{LABELS}}
41
+
42
+ For each email respond with a JSON object:
43
+ - "priority": "urgent" | "high" | "normal" | "low"
44
+ - "labels": string[] (one or more labels from the suggested list)
45
+ - "flag": boolean (true only for urgent / time-sensitive)
46
+ - "action": string (brief suggested next step for the user)
47
+
48
+ Respond ONLY with a JSON array (one object per email, in order). No markdown, no extra text.`,
49
+ };
50
+ const gtd = {
51
+ id: 'gtd',
52
+ name: 'Getting Things Done (GTD)',
53
+ description: 'Organise emails by GTD contexts: @Action, @Waiting, @Reference, @Someday. Actionable items are flagged.',
54
+ suggestedLabels: ['@Action', '@Waiting', '@Reference', '@Someday', '@Delegated'],
55
+ systemPrompt: `You are an email triage assistant following the Getting Things Done (GTD) methodology.
56
+ Classify each email into the appropriate GTD context:
57
+
58
+ - @Action — requires the user to take a specific next action.
59
+ - @Waiting — the user is waiting for someone else to respond or deliver.
60
+ - @Delegated — the user has delegated this task to someone; track it.
61
+ - @Reference — useful information to keep but no action needed.
62
+ - @Someday — interesting but not actionable right now.
63
+
64
+ Flag emails that are actionable (@Action) so they stand out.
65
+ Priority should reflect urgency of the required action.
66
+
67
+ {{CUSTOM}}
68
+
69
+ Use ONLY these labels: {{LABELS}}
70
+
71
+ For each email respond with a JSON object:
72
+ - "priority": "urgent" | "high" | "normal" | "low"
73
+ - "labels": string[] (exactly one GTD context label)
74
+ - "flag": boolean (true for @Action items)
75
+ - "action": string (the specific next action the user should take)
76
+
77
+ Respond ONLY with a JSON array (one object per email, in order). No markdown, no extra text.`,
78
+ };
79
+ const priorityFocus = {
80
+ id: 'priority-focus',
81
+ name: 'Priority Focus',
82
+ description: 'Simple priority classification. No labels — just assigns priority and flags urgent emails. Good default.',
83
+ suggestedLabels: [],
84
+ systemPrompt: `You are an email triage assistant focused on priority classification.
85
+ Your only job is to determine how urgent/important each email is.
86
+
87
+ Guidelines:
88
+ - "urgent" — time-sensitive, needs attention within the hour (e.g. outage, deadline today).
89
+ - "high" — important, should be addressed today (e.g. direct request from a person).
90
+ - "normal" — standard email, can be handled in normal workflow.
91
+ - "low" — informational, automated, or bulk email that can wait.
92
+
93
+ Flag only urgent and high-priority emails.
94
+ Do NOT suggest labels unless something is clearly critical.
95
+
96
+ {{CUSTOM}}
97
+
98
+ For each email respond with a JSON object:
99
+ - "priority": "urgent" | "high" | "normal" | "low"
100
+ - "labels": string[] (usually empty, only add if critical)
101
+ - "flag": boolean (true for urgent/high)
102
+ - "action": string (brief suggested action)
103
+
104
+ Respond ONLY with a JSON array (one object per email, in order). No markdown, no extra text.`,
105
+ };
106
+ const notificationOnly = {
107
+ id: 'notification-only',
108
+ name: 'Notification Only',
109
+ description: 'No AI triage. New emails are logged as notifications without any automatic labelling or flagging.',
110
+ suggestedLabels: [],
111
+ systemPrompt: '', // Not used — this preset bypasses AI
112
+ };
113
+ const custom = {
114
+ id: 'custom',
115
+ name: 'Custom',
116
+ description: 'Full control. Provide your own system_prompt in config. The preset contributes nothing — you define everything.',
117
+ suggestedLabels: [],
118
+ systemPrompt: '', // Replaced entirely by user's system_prompt config
119
+ };
120
+ // ---------------------------------------------------------------------------
121
+ // Registry
122
+ // ---------------------------------------------------------------------------
123
+ const PRESETS = new Map([
124
+ [inboxZero.id, inboxZero],
125
+ [gtd.id, gtd],
126
+ [priorityFocus.id, priorityFocus],
127
+ [notificationOnly.id, notificationOnly],
128
+ [custom.id, custom],
129
+ ]);
130
+ export const DEFAULT_PRESET_ID = 'priority-focus';
131
+ /** Get a preset by id. Returns undefined for unknown ids. */
132
+ export function getPreset(id) {
133
+ return PRESETS.get(id);
134
+ }
135
+ /** List all available presets. */
136
+ export function listPresets() {
137
+ return [...PRESETS.values()];
138
+ }
139
+ /**
140
+ * Build the final system prompt for AI triage by combining:
141
+ * 1. The preset's system prompt template
142
+ * 2. The preset's suggested labels
143
+ * 3. The user's custom instructions (if any)
144
+ * 4. OR the user's full system_prompt override (if preset = "custom")
145
+ */
146
+ export function buildSystemPrompt(presetId, options = {}) {
147
+ // Full override for "custom" preset
148
+ if (presetId === 'custom') {
149
+ return (options.systemPrompt ??
150
+ `You are an email triage assistant.
151
+
152
+ ${options.customInstructions ?? ''}
153
+
154
+ For each email respond with a JSON object:
155
+ - "priority": "urgent" | "high" | "normal" | "low"
156
+ - "labels": string[]
157
+ - "flag": boolean
158
+ - "action": string (brief suggested action)
159
+
160
+ Respond ONLY with a JSON array (one object per email, in order). No markdown, no extra text.`);
161
+ }
162
+ const preset = getPreset(presetId) ?? getPreset(DEFAULT_PRESET_ID);
163
+ if (!preset?.systemPrompt)
164
+ return ''; // notification-only or missing
165
+ const labelsStr = preset.suggestedLabels.length > 0
166
+ ? preset.suggestedLabels.join(', ')
167
+ : '(no specific labels — use your best judgement)';
168
+ const customBlock = options.customInstructions
169
+ ? `\nAdditional context from the user:\n${options.customInstructions}\n`
170
+ : '';
171
+ return preset.systemPrompt.replace('{{LABELS}}', labelsStr).replace('{{CUSTOM}}', customBlock);
172
+ }
173
+ //# sourceMappingURL=presets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.js","sourceRoot":"","sources":["../../src/services/presets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * macOS Reminders.app integration via AppleScript.
3
+ *
4
+ * Lets the AI create reminders from email content — action items, deadlines,
5
+ * follow-ups, etc. — with a native confirmation dialog before adding.
6
+ *
7
+ * Linux: no-op (Reminders.app is macOS-only). Returns a clear error.
8
+ */
9
+ export type ReminderPriority = 'none' | 'low' | 'medium' | 'high';
10
+ export interface ReminderInput {
11
+ title: string;
12
+ notes?: string;
13
+ /** ISO date string for when the reminder should fire */
14
+ dueDate?: string;
15
+ priority?: ReminderPriority;
16
+ /** Name of the Reminders list to add to (default list if omitted) */
17
+ listName?: string;
18
+ }
19
+ export type AddReminderStatus = 'added' | 'cancelled' | 'timed_out' | 'no_display';
20
+ export interface AddReminderResult {
21
+ status: AddReminderStatus;
22
+ reminderId?: string;
23
+ listName?: string;
24
+ message: string;
25
+ }
26
+ export interface ReminderListInfo {
27
+ id: string;
28
+ name: string;
29
+ }
30
+ export interface ReminderSummary {
31
+ id: string;
32
+ title: string;
33
+ dueDate?: string;
34
+ completed: boolean;
35
+ priority: string;
36
+ list: string;
37
+ }
38
+ export interface ListRemindersOptions {
39
+ /** Filter reminders whose title contains this substring (case-insensitive). */
40
+ title?: string;
41
+ /** Restrict to a specific Reminders list by name. */
42
+ listName?: string;
43
+ /** Include completed reminders (default: false). */
44
+ includeCompleted?: boolean;
45
+ /** Maximum number of results (default 20). */
46
+ limit?: number;
47
+ }
48
+ export default class RemindersService {
49
+ private readonly platform;
50
+ get isSupported(): boolean;
51
+ checkPermissions(): Promise<{
52
+ granted: boolean;
53
+ platform: string;
54
+ instructions: string[];
55
+ }>;
56
+ listLists(): Promise<ReminderListInfo[]>;
57
+ addReminder(input: ReminderInput, opts?: {
58
+ confirm?: boolean;
59
+ }): Promise<AddReminderResult>;
60
+ /** List reminders matching the given filters. */
61
+ listReminders(opts?: ListRemindersOptions): Promise<ReminderSummary[]>;
62
+ }
63
+ //# sourceMappingURL=reminders.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reminders.service.d.ts","sourceRoot":"","sources":["../../src/services/reminders.service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAElE,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC;AAEnF,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA8RD,MAAM,CAAC,OAAO,OAAO,gBAAgB;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAE7C,IAAI,WAAW,IAAI,OAAO,CAEzB;IAEK,gBAAgB,IAAI,OAAO,CAAC;QAChC,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,EAAE,CAAC;KACxB,CAAC;IAsBI,SAAS,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAKxC,WAAW,CACf,KAAK,EAAE,aAAa,EACpB,IAAI,GAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAO,GAC/B,OAAO,CAAC,iBAAiB,CAAC;IAW7B,iDAAiD;IAC3C,aAAa,CAAC,IAAI,GAAE,oBAAyB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CAIjF"}
@@ -0,0 +1,281 @@
1
+ /**
2
+ * macOS Reminders.app integration via AppleScript.
3
+ *
4
+ * Lets the AI create reminders from email content — action items, deadlines,
5
+ * follow-ups, etc. — with a native confirmation dialog before adding.
6
+ *
7
+ * Linux: no-op (Reminders.app is macOS-only). Returns a clear error.
8
+ */
9
+ import { execFile as execFileCb } from 'node:child_process';
10
+ import { promisify } from 'node:util';
11
+ const execFile = promisify(execFileCb);
12
+ // ---------------------------------------------------------------------------
13
+ // AppleScript priority mapping: none=0, low=9, medium=5, high=1
14
+ // ---------------------------------------------------------------------------
15
+ const PRIORITY_MAP = {
16
+ none: 0,
17
+ low: 9,
18
+ medium: 5,
19
+ high: 1,
20
+ };
21
+ // ---------------------------------------------------------------------------
22
+ // Helper functions
23
+ // ---------------------------------------------------------------------------
24
+ function reminderStatusMessage(status, title, listName) {
25
+ switch (status) {
26
+ case 'added':
27
+ return `\u2705 Reminder added: "${title}" \u2192 ${listName ?? 'Reminders'}.`;
28
+ case 'cancelled':
29
+ return '\uD83D\uDEAB Cancelled \u2014 reminder was not added.';
30
+ case 'timed_out':
31
+ return '\u23F1\uFE0F Dialog timed out \u2014 reminder was not added. Try again.';
32
+ case 'no_display':
33
+ return '\u26A0\uFE0F Cannot add reminder: run check_calendar_permissions to verify access.';
34
+ default:
35
+ return `Unknown status: ${status}`;
36
+ }
37
+ }
38
+ async function checkPermissionsMacOS() {
39
+ const script = 'tell application "Reminders" to return count of lists';
40
+ try {
41
+ const { stdout } = await execFile('osascript', ['-e', script], {
42
+ timeout: 10_000,
43
+ });
44
+ return parseInt(stdout.trim(), 10) >= 0;
45
+ }
46
+ catch {
47
+ return false;
48
+ }
49
+ }
50
+ async function listListsMacOS() {
51
+ const script = 'tell application "Reminders" to return name of every list';
52
+ try {
53
+ const { stdout } = await execFile('osascript', ['-e', script], {
54
+ timeout: 10_000,
55
+ });
56
+ const raw = stdout.trim();
57
+ if (!raw)
58
+ return [];
59
+ return raw.split(', ').map((name) => ({ id: name, name }));
60
+ }
61
+ catch {
62
+ return [];
63
+ }
64
+ }
65
+ function escapeAS(s) {
66
+ return s
67
+ .replace(/\\/g, '\\\\')
68
+ .replace(/"/g, '\\"')
69
+ .replace(/\r\n/g, '\\n')
70
+ .replace(/\n/g, '\\n')
71
+ .replace(/\r/g, '\\r')
72
+ .replace(/\t/g, '\\t');
73
+ }
74
+ function buildReminderAppleScript(input, confirm) {
75
+ const priority = PRIORITY_MAP[input.priority ?? 'none'];
76
+ const title = escapeAS(input.title);
77
+ const notes = escapeAS(input.notes ?? '');
78
+ const dueDate = input.dueDate ?? '';
79
+ const listName = escapeAS(input.listName ?? '');
80
+ const lines = [];
81
+ if (confirm) {
82
+ const dlgParts = [`\uD83D\uDD14 ${title}`];
83
+ if (dueDate) {
84
+ dlgParts.push(`\uD83D\uDD50 Due: ${dueDate}`);
85
+ }
86
+ if (notes) {
87
+ const short = notes.length > 200 ? `${notes.substring(0, 200)}\u2026` : notes;
88
+ dlgParts.push(`\uD83D\uDCDD ${short}`);
89
+ }
90
+ if (listName) {
91
+ dlgParts.push(`\uD83D\uDCCB List: ${listName}`);
92
+ }
93
+ if (priority > 0) {
94
+ let pLabel = 'Low';
95
+ if (priority <= 2) {
96
+ pLabel = 'High';
97
+ }
98
+ else if (priority <= 6) {
99
+ pLabel = 'Medium';
100
+ }
101
+ dlgParts.push(`\u26A0\uFE0F Priority: ${pLabel}`);
102
+ }
103
+ lines.push(`set dialogText to "${escapeAS(dlgParts[0])}"`);
104
+ dlgParts.slice(1).forEach((dl) => {
105
+ lines.push(`set dialogText to dialogText & return & "${escapeAS(dl)}"`);
106
+ });
107
+ lines.push('try', ' display dialog dialogText with title "email-mcp \u2014 Add Reminder?" buttons {"Cancel", "Add Reminder"} default button "Add Reminder" cancel button "Cancel" giving up after 60', ' set dlgResult to button returned of result', ' if dlgResult is not "Add Reminder" then', ' return "{\\"status\\":\\"timed_out\\"}"', ' end if', 'on error', ' return "{\\"status\\":\\"cancelled\\"}"', 'end try', '');
108
+ }
109
+ lines.push('tell application "Reminders"');
110
+ if (listName) {
111
+ lines.push(' try', ` set targetList to list "${listName}"`, ' on error', ' set targetList to default list', ' end try');
112
+ }
113
+ else {
114
+ lines.push(' set targetList to default list');
115
+ }
116
+ const propsParts = [`name:"${title}", completed:false`];
117
+ if (notes) {
118
+ propsParts.push(`body:"${notes}"`);
119
+ }
120
+ if (priority > 0) {
121
+ propsParts.push(`priority:${priority}`);
122
+ }
123
+ const propsStr = `{${propsParts.join(', ')}}`;
124
+ lines.push(` set newReminder to make new reminder at end of reminders of targetList with properties ${propsStr}`);
125
+ if (dueDate) {
126
+ const d = new Date(dueDate);
127
+ lines.push(' try', ' set dueD to current date', ` set year of dueD to ${d.getFullYear()}`, ` set month of dueD to ${d.getMonth() + 1}`, ` set day of dueD to ${d.getDate()}`, ` set hours of dueD to ${d.getHours()}`, ` set minutes of dueD to ${d.getMinutes()}`, ` set seconds of dueD to ${d.getSeconds()}`, ' set due date of newReminder to dueD', ' end try');
128
+ }
129
+ lines.push(' set remId to id of newReminder', ' set finalList to name of targetList', 'end tell', '', 'return "{\\"status\\":\\"added\\",\\"reminderId\\":\\"" & remId & "\\",\\"listName\\":\\"" & finalList & "\\"}"');
130
+ return lines.join('\n');
131
+ }
132
+ async function addReminderMacOS(input, confirm) {
133
+ const script = buildReminderAppleScript(input, confirm);
134
+ try {
135
+ const { stdout } = await execFile('osascript', ['-e', script], {
136
+ timeout: 90_000,
137
+ });
138
+ const result = JSON.parse(stdout.trim());
139
+ return {
140
+ status: result.status,
141
+ reminderId: result.reminderId,
142
+ listName: result.listName,
143
+ message: reminderStatusMessage(result.status, input.title, result.listName),
144
+ };
145
+ }
146
+ catch (err) {
147
+ const msg = err instanceof Error ? err.message : String(err);
148
+ if (/user canceled|(-128)/i.test(msg)) {
149
+ return { status: 'cancelled', message: 'Cancelled by user.' };
150
+ }
151
+ if (/not authorized|access/i.test(msg)) {
152
+ return {
153
+ status: 'no_display',
154
+ message: 'Reminders access denied. Go to System Settings \u2192 Privacy \u2192 Reminders and enable Terminal.',
155
+ };
156
+ }
157
+ return { status: 'no_display', message: `Could not add reminder: ${msg}` };
158
+ }
159
+ }
160
+ async function listRemindersMacOS(opts) {
161
+ const limit = opts.limit ?? 20;
162
+ const titleFilter = opts.title ? escapeAS(opts.title) : '';
163
+ const listFilter = opts.listName ? escapeAS(opts.listName) : '';
164
+ const includeCompleted = opts.includeCompleted === true;
165
+ const script = `
166
+ set jsonResult to "["
167
+ set resultCount to 0
168
+ set maxResults to ${limit}
169
+ set titleFilter to "${titleFilter}"
170
+ set listFilter to "${listFilter}"
171
+ set includeCompleted to ${includeCompleted}
172
+
173
+ tell application "Reminders"
174
+ repeat with rl in lists
175
+ if resultCount \u2265 maxResults then exit repeat
176
+ set listName to name of rl
177
+ if listFilter is "" or listName is listFilter then
178
+ try
179
+ set rems to every reminder of rl
180
+ repeat with r in rems
181
+ if resultCount \u2265 maxResults then exit repeat
182
+ set isComp to completed of r
183
+ if includeCompleted or not isComp then
184
+ set rTitle to name of r
185
+ set matchesTitle to true
186
+ if titleFilter is not "" then
187
+ ignoring case
188
+ if rTitle does not contain titleFilter then set matchesTitle to false
189
+ end ignoring
190
+ end if
191
+ if matchesTitle then
192
+ set rId to id of r
193
+ set rDue to ""
194
+ try
195
+ set dd to due date of r
196
+ if dd is not missing value then
197
+ set rDue to (dd as text)
198
+ end if
199
+ end try
200
+ set rPriority to priority of r
201
+ set pLabel to "none"
202
+ if rPriority is 1 then set pLabel to "high"
203
+ if rPriority is 5 then set pLabel to "medium"
204
+ if rPriority is 9 then set pLabel to "low"
205
+ set compStr to "false"
206
+ if isComp then set compStr to "true"
207
+ if resultCount > 0 then set jsonResult to jsonResult & ","
208
+ set jsonResult to jsonResult & "{\\"id\\":\\"" & rId & "\\",\\"title\\":\\"" & rTitle & "\\",\\"dueDate\\":\\"" & rDue & "\\",\\"completed\\":" & compStr & ",\\"priority\\":\\"" & pLabel & "\\",\\"list\\":\\"" & listName & "\\"}"
209
+ set resultCount to resultCount + 1
210
+ end if
211
+ end if
212
+ end repeat
213
+ end try
214
+ end if
215
+ end repeat
216
+ end tell
217
+
218
+ set jsonResult to jsonResult & "]"
219
+ return jsonResult
220
+ `;
221
+ try {
222
+ const { stdout } = await execFile('osascript', ['-e', script], { timeout: 15_000 });
223
+ return JSON.parse(stdout.trim());
224
+ }
225
+ catch {
226
+ return [];
227
+ }
228
+ }
229
+ // ---------------------------------------------------------------------------
230
+ // Service
231
+ // ---------------------------------------------------------------------------
232
+ export default class RemindersService {
233
+ platform = process.platform;
234
+ get isSupported() {
235
+ return this.platform === 'darwin';
236
+ }
237
+ async checkPermissions() {
238
+ if (this.platform !== 'darwin') {
239
+ return {
240
+ granted: false,
241
+ platform: this.platform,
242
+ instructions: ['Reminders.app is only available on macOS.'],
243
+ };
244
+ }
245
+ const granted = await checkPermissionsMacOS();
246
+ if (granted)
247
+ return { granted: true, platform: 'darwin', instructions: [] };
248
+ return {
249
+ granted: false,
250
+ platform: 'darwin',
251
+ instructions: [
252
+ 'Reminders access was denied or unavailable.',
253
+ '1. Open System Settings \u2192 Privacy & Security \u2192 Reminders',
254
+ '2. Enable access for Terminal (or your terminal emulator)',
255
+ '3. Quit and restart the terminal, then try again.',
256
+ ],
257
+ };
258
+ }
259
+ async listLists() {
260
+ if (this.platform !== 'darwin')
261
+ return [];
262
+ return listListsMacOS();
263
+ }
264
+ async addReminder(input, opts = {}) {
265
+ if (this.platform !== 'darwin') {
266
+ return {
267
+ status: 'no_display',
268
+ message: 'Reminders.app is only available on macOS.',
269
+ };
270
+ }
271
+ const confirm = opts.confirm !== false;
272
+ return addReminderMacOS(input, confirm);
273
+ }
274
+ /** List reminders matching the given filters. */
275
+ async listReminders(opts = {}) {
276
+ if (this.platform !== 'darwin')
277
+ return [];
278
+ return listRemindersMacOS(opts);
279
+ }
280
+ }
281
+ //# sourceMappingURL=reminders.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reminders.service.js","sourceRoot":"","sources":["../../src/services/reminders.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Scheduler service — JSON file-based email scheduling queue.
3
+ *
4
+ * Manages scheduled emails with a local file queue.
5
+ * Source of truth is the JSON files in XDG state directory.
6
+ */
7
+ import type { ScheduledEmail } from '../types/index.js';
8
+ import type ImapService from './imap.service.js';
9
+ import type SmtpService from './smtp.service.js';
10
+ export default class SchedulerService {
11
+ private smtpService;
12
+ private imapService;
13
+ constructor(smtpService: SmtpService, imapService: ImapService);
14
+ schedule(account: string, options: {
15
+ to: string[];
16
+ subject: string;
17
+ body: string;
18
+ sendAt: string;
19
+ cc?: string[];
20
+ bcc?: string[];
21
+ html?: boolean;
22
+ inReplyTo?: string;
23
+ references?: string[];
24
+ }): Promise<ScheduledEmail>;
25
+ list(options?: {
26
+ account?: string;
27
+ status?: 'pending' | 'sent' | 'failed' | 'all';
28
+ }): Promise<ScheduledEmail[]>;
29
+ cancel(scheduleId: string): Promise<{
30
+ cancelled: boolean;
31
+ draftDeleted: boolean;
32
+ }>;
33
+ checkAndSend(): Promise<{
34
+ sent: number;
35
+ failed: number;
36
+ errors: string[];
37
+ }>;
38
+ private static ensureDirs;
39
+ private static writeScheduledFile;
40
+ private static readDir;
41
+ }
42
+ //# sourceMappingURL=scheduler.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.service.d.ts","sourceRoot":"","sources":["../../src/services/scheduler.service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AAQjD,MAAM,CAAC,OAAO,OAAO,gBAAgB;IAEjC,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,WAAW;gBADX,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,WAAW;IAO5B,QAAQ,CACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,EAAE,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;QACf,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;KACvB,GACA,OAAO,CAAC,cAAc,CAAC;IAkDpB,IAAI,CACR,OAAO,GAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAA;KAAO,GACjF,OAAO,CAAC,cAAc,EAAE,CAAC;IA+BtB,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,YAAY,EAAE,OAAO,CAAA;KAAE,CAAC;IA6ClF,YAAY,IAAI,OAAO,CAAC;QAC5B,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;mBAkHmB,UAAU;mBAKV,kBAAkB;mBAMlB,OAAO;CAmB7B"}