@runcore-sh/runcore 0.4.0 → 0.5.1

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 (351) hide show
  1. package/dictionary.json +2 -2
  2. package/dist/activity/log.js +2 -2
  3. package/dist/activity/log.js.map +1 -1
  4. package/dist/agents/governed-spawn.d.ts.map +1 -1
  5. package/dist/cli.js +101 -11
  6. package/dist/cli.js.map +1 -1
  7. package/dist/extensions/cache.d.ts +57 -0
  8. package/dist/extensions/cache.d.ts.map +1 -0
  9. package/dist/extensions/cache.js +173 -0
  10. package/dist/extensions/cache.js.map +1 -0
  11. package/dist/extensions/client.d.ts +55 -0
  12. package/dist/extensions/client.d.ts.map +1 -0
  13. package/dist/extensions/client.js +120 -0
  14. package/dist/extensions/client.js.map +1 -0
  15. package/dist/extensions/index.d.ts +13 -0
  16. package/dist/extensions/index.d.ts.map +1 -0
  17. package/dist/extensions/index.js +12 -0
  18. package/dist/extensions/index.js.map +1 -0
  19. package/dist/extensions/loader.d.ts +50 -0
  20. package/dist/extensions/loader.d.ts.map +1 -0
  21. package/dist/extensions/loader.js +166 -0
  22. package/dist/extensions/loader.js.map +1 -0
  23. package/dist/extensions/manifest.d.ts +38 -0
  24. package/dist/extensions/manifest.d.ts.map +1 -0
  25. package/dist/extensions/manifest.js +17 -0
  26. package/dist/extensions/manifest.js.map +1 -0
  27. package/dist/extensions/stubs.d.ts +27 -0
  28. package/dist/extensions/stubs.d.ts.map +1 -0
  29. package/dist/extensions/stubs.js +45 -0
  30. package/dist/extensions/stubs.js.map +1 -0
  31. package/dist/lib/audit.js +2 -2
  32. package/dist/lib/audit.js.map +1 -1
  33. package/dist/lib/brain-migrate.d.ts +21 -0
  34. package/dist/lib/brain-migrate.d.ts.map +1 -0
  35. package/dist/lib/brain-migrate.js +137 -0
  36. package/dist/lib/brain-migrate.js.map +1 -0
  37. package/dist/lib/paths.d.ts +27 -0
  38. package/dist/lib/paths.d.ts.map +1 -1
  39. package/dist/lib/paths.js +65 -0
  40. package/dist/lib/paths.js.map +1 -1
  41. package/dist/llm/call-log.d.ts +40 -0
  42. package/dist/llm/call-log.d.ts.map +1 -0
  43. package/dist/llm/call-log.js +35 -0
  44. package/dist/llm/call-log.js.map +1 -0
  45. package/dist/llm/complete.d.ts +6 -0
  46. package/dist/llm/complete.d.ts.map +1 -1
  47. package/dist/llm/complete.js +27 -0
  48. package/dist/llm/complete.js.map +1 -1
  49. package/dist/mcp-server.js +118 -2
  50. package/dist/mcp-server.js.map +1 -1
  51. package/dist/memory/file-backed.d.ts +4 -0
  52. package/dist/memory/file-backed.d.ts.map +1 -1
  53. package/dist/memory/file-backed.js +4 -0
  54. package/dist/memory/file-backed.js.map +1 -1
  55. package/dist/memory/vector-index.d.ts +4 -12
  56. package/dist/memory/vector-index.d.ts.map +1 -1
  57. package/dist/memory/vector-index.js +11 -93
  58. package/dist/memory/vector-index.js.map +1 -1
  59. package/dist/search/brain-docs.d.ts +17 -7
  60. package/dist/search/brain-docs.d.ts.map +1 -1
  61. package/dist/search/brain-docs.js +170 -52
  62. package/dist/search/brain-docs.js.map +1 -1
  63. package/dist/search/brain-rag.d.ts +45 -0
  64. package/dist/search/brain-rag.d.ts.map +1 -0
  65. package/dist/search/brain-rag.js +275 -0
  66. package/dist/search/brain-rag.js.map +1 -0
  67. package/dist/search/chunker.d.ts +24 -0
  68. package/dist/search/chunker.d.ts.map +1 -0
  69. package/dist/search/chunker.js +95 -0
  70. package/dist/search/chunker.js.map +1 -0
  71. package/dist/search/embedder.d.ts +16 -0
  72. package/dist/search/embedder.d.ts.map +1 -0
  73. package/dist/search/embedder.js +108 -0
  74. package/dist/search/embedder.js.map +1 -0
  75. package/dist/search/file-watcher.d.ts +11 -0
  76. package/dist/search/file-watcher.d.ts.map +1 -0
  77. package/dist/search/file-watcher.js +86 -0
  78. package/dist/search/file-watcher.js.map +1 -0
  79. package/dist/server.d.ts.map +1 -1
  80. package/dist/server.js +814 -472
  81. package/dist/server.js.map +1 -1
  82. package/dist/sessions/store.d.ts +9 -0
  83. package/dist/sessions/store.d.ts.map +1 -1
  84. package/dist/sessions/store.js.map +1 -1
  85. package/dist/settings.d.ts +26 -0
  86. package/dist/settings.d.ts.map +1 -1
  87. package/dist/settings.js +78 -2
  88. package/dist/settings.js.map +1 -1
  89. package/dist/tracing/init.d.ts +1 -1
  90. package/dist/tracing/init.d.ts.map +1 -1
  91. package/dist/utils/logger.js +2 -2
  92. package/dist/utils/logger.js.map +1 -1
  93. package/module-tiers.json +164 -0
  94. package/package.json +9 -13
  95. package/public/avatar/cache/1184385ec5522b57.mp4 +0 -0
  96. package/public/avatar/cache/1f15f6a1ebd7e439.mp4 +0 -0
  97. package/public/avatar/cache/2c7e47ff0bdeb8d1.mp4 +0 -0
  98. package/public/avatar/cache/5f308566f7abb8f2.mp4 +0 -0
  99. package/public/avatar/cache/62f9cfba848d724e.mp4 +0 -0
  100. package/public/avatar/cache/6d64e657e6bf2aab.mp4 +0 -0
  101. package/public/avatar/cache/763ad0349e0b6f26.mp4 +0 -0
  102. package/public/avatar/cache/81a516cfd461b2b9.mp4 +0 -0
  103. package/public/avatar/cache/9366de15fd6910ca.mp4 +0 -0
  104. package/public/avatar/cache/ade41a846b283895.mp4 +0 -0
  105. package/public/avatar/cache/b6066e5c65383eec.mp4 +0 -0
  106. package/public/avatar/cache/edadb75d37891fc7.mp4 +0 -0
  107. package/public/avatar/cache/f0ae159640621dd9.mp4 +0 -0
  108. package/public/avatar/cache/fc2e5419adf29d96.mp4 +0 -0
  109. package/public/index.html +379 -59
  110. package/dist/agents/autonomous.js +0 -749
  111. package/dist/agents/autonomous.js.map +0 -1
  112. package/dist/agents/commit.js +0 -113
  113. package/dist/agents/commit.js.map +0 -1
  114. package/dist/agents/continue.js +0 -158
  115. package/dist/agents/continue.js.map +0 -1
  116. package/dist/agents/cooldown.js +0 -397
  117. package/dist/agents/cooldown.js.map +0 -1
  118. package/dist/agents/dedup-guard.js +0 -131
  119. package/dist/agents/dedup-guard.js.map +0 -1
  120. package/dist/agents/feed.js +0 -176
  121. package/dist/agents/feed.js.map +0 -1
  122. package/dist/agents/governance.js +0 -292
  123. package/dist/agents/governance.js.map +0 -1
  124. package/dist/agents/governed-spawn.js +0 -192
  125. package/dist/agents/governed-spawn.js.map +0 -1
  126. package/dist/agents/heartbeat.js +0 -324
  127. package/dist/agents/heartbeat.js.map +0 -1
  128. package/dist/agents/instance-manager.js +0 -850
  129. package/dist/agents/instance-manager.js.map +0 -1
  130. package/dist/agents/issue-reporter.js +0 -123
  131. package/dist/agents/issue-reporter.js.map +0 -1
  132. package/dist/agents/issues.js +0 -141
  133. package/dist/agents/issues.js.map +0 -1
  134. package/dist/agents/locks.js +0 -234
  135. package/dist/agents/locks.js.map +0 -1
  136. package/dist/agents/memory.js +0 -93
  137. package/dist/agents/memory.js.map +0 -1
  138. package/dist/agents/monitor.js +0 -235
  139. package/dist/agents/monitor.js.map +0 -1
  140. package/dist/agents/orchestration.js +0 -715
  141. package/dist/agents/orchestration.js.map +0 -1
  142. package/dist/agents/recover.js +0 -166
  143. package/dist/agents/recover.js.map +0 -1
  144. package/dist/agents/reflection.js +0 -199
  145. package/dist/agents/reflection.js.map +0 -1
  146. package/dist/agents/runtime/bus.js +0 -174
  147. package/dist/agents/runtime/bus.js.map +0 -1
  148. package/dist/agents/runtime/config.js +0 -101
  149. package/dist/agents/runtime/config.js.map +0 -1
  150. package/dist/agents/runtime/driver.js +0 -214
  151. package/dist/agents/runtime/driver.js.map +0 -1
  152. package/dist/agents/runtime/errors.js +0 -40
  153. package/dist/agents/runtime/errors.js.map +0 -1
  154. package/dist/agents/runtime/index.js +0 -54
  155. package/dist/agents/runtime/index.js.map +0 -1
  156. package/dist/agents/runtime/lifecycle.js +0 -116
  157. package/dist/agents/runtime/lifecycle.js.map +0 -1
  158. package/dist/agents/runtime/manager.js +0 -948
  159. package/dist/agents/runtime/manager.js.map +0 -1
  160. package/dist/agents/runtime/registry.js +0 -195
  161. package/dist/agents/runtime/registry.js.map +0 -1
  162. package/dist/agents/runtime/resources.js +0 -146
  163. package/dist/agents/runtime/resources.js.map +0 -1
  164. package/dist/agents/runtime/types.js +0 -24
  165. package/dist/agents/runtime/types.js.map +0 -1
  166. package/dist/agents/spawn-policy.js +0 -202
  167. package/dist/agents/spawn-policy.js.map +0 -1
  168. package/dist/agents/spawn.js +0 -970
  169. package/dist/agents/spawn.js.map +0 -1
  170. package/dist/agents/triage.js +0 -81
  171. package/dist/agents/triage.js.map +0 -1
  172. package/dist/agents/workflow.js +0 -543
  173. package/dist/agents/workflow.js.map +0 -1
  174. package/dist/avatar/client.js +0 -172
  175. package/dist/avatar/client.js.map +0 -1
  176. package/dist/avatar/sidecar.js +0 -125
  177. package/dist/avatar/sidecar.js.map +0 -1
  178. package/dist/browser/sessions.js +0 -122
  179. package/dist/browser/sessions.js.map +0 -1
  180. package/dist/capabilities/definitions/browser.js +0 -242
  181. package/dist/capabilities/definitions/browser.js.map +0 -1
  182. package/dist/channels/whatsapp.js +0 -200
  183. package/dist/channels/whatsapp.js.map +0 -1
  184. package/dist/credentials/store.js +0 -189
  185. package/dist/credentials/store.js.map +0 -1
  186. package/dist/files/deep-index.js +0 -337
  187. package/dist/files/deep-index.js.map +0 -1
  188. package/dist/files/extract.js +0 -33
  189. package/dist/files/extract.js.map +0 -1
  190. package/dist/files/gdrive.js +0 -246
  191. package/dist/files/gdrive.js.map +0 -1
  192. package/dist/github/client.js +0 -408
  193. package/dist/github/client.js.map +0 -1
  194. package/dist/github/commit-analysis.js +0 -276
  195. package/dist/github/commit-analysis.js.map +0 -1
  196. package/dist/github/contributor-stats.js +0 -119
  197. package/dist/github/contributor-stats.js.map +0 -1
  198. package/dist/github/issue-sla.js +0 -220
  199. package/dist/github/issue-sla.js.map +0 -1
  200. package/dist/github/issue-triage.js +0 -286
  201. package/dist/github/issue-triage.js.map +0 -1
  202. package/dist/github/pr-readiness.js +0 -197
  203. package/dist/github/pr-readiness.js.map +0 -1
  204. package/dist/github/pr-review.js +0 -410
  205. package/dist/github/pr-review.js.map +0 -1
  206. package/dist/github/release-notes.js +0 -227
  207. package/dist/github/release-notes.js.map +0 -1
  208. package/dist/github/repo-health.js +0 -303
  209. package/dist/github/repo-health.js.map +0 -1
  210. package/dist/github/retry.js +0 -117
  211. package/dist/github/retry.js.map +0 -1
  212. package/dist/github/types.js +0 -8
  213. package/dist/github/types.js.map +0 -1
  214. package/dist/github/webhooks.js +0 -153
  215. package/dist/github/webhooks.js.map +0 -1
  216. package/dist/google/auth.js +0 -325
  217. package/dist/google/auth.js.map +0 -1
  218. package/dist/google/calendar-timer.js +0 -91
  219. package/dist/google/calendar-timer.js.map +0 -1
  220. package/dist/google/calendar.js +0 -270
  221. package/dist/google/calendar.js.map +0 -1
  222. package/dist/google/docs.js +0 -309
  223. package/dist/google/docs.js.map +0 -1
  224. package/dist/google/gmail-send.js +0 -219
  225. package/dist/google/gmail-send.js.map +0 -1
  226. package/dist/google/gmail-timer.js +0 -223
  227. package/dist/google/gmail-timer.js.map +0 -1
  228. package/dist/google/gmail.js +0 -470
  229. package/dist/google/gmail.js.map +0 -1
  230. package/dist/google/plugin.js +0 -169
  231. package/dist/google/plugin.js.map +0 -1
  232. package/dist/google/tasks-timer.js +0 -107
  233. package/dist/google/tasks-timer.js.map +0 -1
  234. package/dist/google/tasks.js +0 -331
  235. package/dist/google/tasks.js.map +0 -1
  236. package/dist/google/temporal.js +0 -176
  237. package/dist/google/temporal.js.map +0 -1
  238. package/dist/integrations/gate.js +0 -100
  239. package/dist/integrations/gate.js.map +0 -1
  240. package/dist/integrations/github.js +0 -331
  241. package/dist/integrations/github.js.map +0 -1
  242. package/dist/integrations/google-tasks.js +0 -432
  243. package/dist/integrations/google-tasks.js.map +0 -1
  244. package/dist/mdns.js +0 -110
  245. package/dist/mdns.js.map +0 -1
  246. package/dist/notifications/channel.js +0 -83
  247. package/dist/notifications/channel.js.map +0 -1
  248. package/dist/notifications/channels/adapter.js +0 -55
  249. package/dist/notifications/channels/adapter.js.map +0 -1
  250. package/dist/notifications/channels/index.js +0 -6
  251. package/dist/notifications/channels/index.js.map +0 -1
  252. package/dist/notifications/channels/log.js +0 -29
  253. package/dist/notifications/channels/log.js.map +0 -1
  254. package/dist/notifications/email.js +0 -72
  255. package/dist/notifications/email.js.map +0 -1
  256. package/dist/notifications/engine.js +0 -198
  257. package/dist/notifications/engine.js.map +0 -1
  258. package/dist/notifications/index.js +0 -24
  259. package/dist/notifications/index.js.map +0 -1
  260. package/dist/notifications/phone.js +0 -48
  261. package/dist/notifications/phone.js.map +0 -1
  262. package/dist/notifications/sms.js +0 -65
  263. package/dist/notifications/sms.js.map +0 -1
  264. package/dist/notifications/types.js +0 -14
  265. package/dist/notifications/types.js.map +0 -1
  266. package/dist/notifications/webhook.js +0 -65
  267. package/dist/notifications/webhook.js.map +0 -1
  268. package/dist/resend/inbox.js +0 -199
  269. package/dist/resend/inbox.js.map +0 -1
  270. package/dist/resend/webhooks.js +0 -244
  271. package/dist/resend/webhooks.js.map +0 -1
  272. package/dist/search/browse.js +0 -225
  273. package/dist/search/browse.js.map +0 -1
  274. package/dist/search/perplexity.js +0 -41
  275. package/dist/search/perplexity.js.map +0 -1
  276. package/dist/slack/channels.js +0 -277
  277. package/dist/slack/channels.js.map +0 -1
  278. package/dist/slack/client.js +0 -468
  279. package/dist/slack/client.js.map +0 -1
  280. package/dist/slack/retry.js +0 -100
  281. package/dist/slack/retry.js.map +0 -1
  282. package/dist/slack/types.js +0 -52
  283. package/dist/slack/types.js.map +0 -1
  284. package/dist/slack/webhooks.js +0 -285
  285. package/dist/slack/webhooks.js.map +0 -1
  286. package/dist/stt/client.js +0 -66
  287. package/dist/stt/client.js.map +0 -1
  288. package/dist/stt/sidecar.js +0 -115
  289. package/dist/stt/sidecar.js.map +0 -1
  290. package/dist/tracing/bridge.js +0 -70
  291. package/dist/tracing/bridge.js.map +0 -1
  292. package/dist/tracing/correlation.js +0 -49
  293. package/dist/tracing/correlation.js.map +0 -1
  294. package/dist/tracing/index.js +0 -18
  295. package/dist/tracing/index.js.map +0 -1
  296. package/dist/tracing/init.js +0 -81
  297. package/dist/tracing/init.js.map +0 -1
  298. package/dist/tracing/instrument.js +0 -145
  299. package/dist/tracing/instrument.js.map +0 -1
  300. package/dist/tracing/middleware.js +0 -69
  301. package/dist/tracing/middleware.js.map +0 -1
  302. package/dist/tracing/tracer.js +0 -327
  303. package/dist/tracing/tracer.js.map +0 -1
  304. package/dist/tts/client.js +0 -48
  305. package/dist/tts/client.js.map +0 -1
  306. package/dist/tts/sidecar.js +0 -148
  307. package/dist/tts/sidecar.js.map +0 -1
  308. package/dist/twilio/call.js +0 -79
  309. package/dist/twilio/call.js.map +0 -1
  310. package/dist/vault/matcher.js +0 -197
  311. package/dist/vault/matcher.js.map +0 -1
  312. package/dist/vault/personal.js +0 -163
  313. package/dist/vault/personal.js.map +0 -1
  314. package/dist/vault/policy.js +0 -159
  315. package/dist/vault/policy.js.map +0 -1
  316. package/dist/vault/store.js +0 -122
  317. package/dist/vault/store.js.map +0 -1
  318. package/dist/vault/transfer.js +0 -188
  319. package/dist/vault/transfer.js.map +0 -1
  320. package/dist/volumes/index.js +0 -2
  321. package/dist/volumes/index.js.map +0 -1
  322. package/dist/volumes/manager.js +0 -462
  323. package/dist/volumes/manager.js.map +0 -1
  324. package/dist/volumes/types.js +0 -8
  325. package/dist/volumes/types.js.map +0 -1
  326. package/dist/webhooks/config.js +0 -214
  327. package/dist/webhooks/config.js.map +0 -1
  328. package/dist/webhooks/event-log.js +0 -132
  329. package/dist/webhooks/event-log.js.map +0 -1
  330. package/dist/webhooks/handler.js +0 -103
  331. package/dist/webhooks/handler.js.map +0 -1
  332. package/dist/webhooks/handlers.js +0 -231
  333. package/dist/webhooks/handlers.js.map +0 -1
  334. package/dist/webhooks/index.js +0 -33
  335. package/dist/webhooks/index.js.map +0 -1
  336. package/dist/webhooks/mount.js +0 -400
  337. package/dist/webhooks/mount.js.map +0 -1
  338. package/dist/webhooks/registry.js +0 -143
  339. package/dist/webhooks/registry.js.map +0 -1
  340. package/dist/webhooks/relay.js +0 -53
  341. package/dist/webhooks/relay.js.map +0 -1
  342. package/dist/webhooks/retry.js +0 -270
  343. package/dist/webhooks/retry.js.map +0 -1
  344. package/dist/webhooks/router.js +0 -290
  345. package/dist/webhooks/router.js.map +0 -1
  346. package/dist/webhooks/twilio.js +0 -129
  347. package/dist/webhooks/twilio.js.map +0 -1
  348. package/dist/webhooks/types.js +0 -8
  349. package/dist/webhooks/types.js.map +0 -1
  350. package/dist/webhooks/verify.js +0 -154
  351. package/dist/webhooks/verify.js.map +0 -1
@@ -1,219 +0,0 @@
1
- /**
2
- * Gmail send client.
3
- * Composes RFC 2822 messages and sends via Gmail API.
4
- * Raw fetch via googlePost — no SDK.
5
- * All functions return { ok, data?, message } — never throw.
6
- */
7
- import { readFile } from "node:fs/promises";
8
- import { basename } from "node:path";
9
- import { getAccessToken, isGoogleAuthenticated } from "./auth.js";
10
- import { createLogger } from "../utils/logger.js";
11
- const log = createLogger("google.gmail-send");
12
- const GMAIL_API = "https://www.googleapis.com/gmail/v1/users/me";
13
- const DEFAULT_FROM = process.env.GMAIL_FROM ?? "noreply@example.com";
14
- // --- Helpers ---
15
- /**
16
- * Encode a Buffer to URL-safe base64 (Gmail's required format).
17
- */
18
- function toBase64Url(buf) {
19
- return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
20
- }
21
- /**
22
- * Join an address list into a comma-separated string.
23
- */
24
- function joinAddresses(addr) {
25
- return Array.isArray(addr) ? addr.join(", ") : addr;
26
- }
27
- /**
28
- * Generate a MIME boundary string.
29
- */
30
- function generateBoundary() {
31
- return `----=_Part_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
32
- }
33
- /**
34
- * Build a complete RFC 2822 message as a string.
35
- * Supports plain text, HTML alternative, and file attachments.
36
- */
37
- function buildRfc2822(options) {
38
- const from = options.from ?? DEFAULT_FROM;
39
- const to = joinAddresses(options.to);
40
- const headers = [
41
- `From: ${from}`,
42
- `To: ${to}`,
43
- `Subject: ${options.subject}`,
44
- `MIME-Version: 1.0`,
45
- `Date: ${new Date().toUTCString()}`,
46
- ];
47
- if (options.cc)
48
- headers.push(`Cc: ${joinAddresses(options.cc)}`);
49
- if (options.bcc)
50
- headers.push(`Bcc: ${joinAddresses(options.bcc)}`);
51
- if (options.inReplyTo)
52
- headers.push(`In-Reply-To: ${options.inReplyTo}`);
53
- if (options.references)
54
- headers.push(`References: ${options.references}`);
55
- const hasAttachments = options.attachments && options.attachments.length > 0;
56
- const hasHtml = !!options.htmlBody;
57
- // Simple plain text — no MIME parts needed
58
- if (!hasAttachments && !hasHtml) {
59
- headers.push(`Content-Type: text/plain; charset="UTF-8"`);
60
- headers.push(`Content-Transfer-Encoding: 7bit`);
61
- return headers.join("\r\n") + "\r\n\r\n" + options.body;
62
- }
63
- // With HTML but no attachments — multipart/alternative
64
- if (!hasAttachments && hasHtml) {
65
- const altBoundary = generateBoundary();
66
- headers.push(`Content-Type: multipart/alternative; boundary="${altBoundary}"`);
67
- const parts = [
68
- `--${altBoundary}\r\nContent-Type: text/plain; charset="UTF-8"\r\nContent-Transfer-Encoding: 7bit\r\n\r\n${options.body}`,
69
- `--${altBoundary}\r\nContent-Type: text/html; charset="UTF-8"\r\nContent-Transfer-Encoding: 7bit\r\n\r\n${options.htmlBody}`,
70
- `--${altBoundary}--`,
71
- ];
72
- return headers.join("\r\n") + "\r\n\r\n" + parts.join("\r\n");
73
- }
74
- // With attachments — multipart/mixed
75
- const mixedBoundary = generateBoundary();
76
- headers.push(`Content-Type: multipart/mixed; boundary="${mixedBoundary}"`);
77
- const parts = [];
78
- // Text body (or alternative text+html)
79
- if (hasHtml) {
80
- const altBoundary = generateBoundary();
81
- parts.push(`--${mixedBoundary}\r\nContent-Type: multipart/alternative; boundary="${altBoundary}"\r\n\r\n` +
82
- `--${altBoundary}\r\nContent-Type: text/plain; charset="UTF-8"\r\nContent-Transfer-Encoding: 7bit\r\n\r\n${options.body}\r\n` +
83
- `--${altBoundary}\r\nContent-Type: text/html; charset="UTF-8"\r\nContent-Transfer-Encoding: 7bit\r\n\r\n${options.htmlBody}\r\n` +
84
- `--${altBoundary}--`);
85
- }
86
- else {
87
- parts.push(`--${mixedBoundary}\r\nContent-Type: text/plain; charset="UTF-8"\r\nContent-Transfer-Encoding: 7bit\r\n\r\n${options.body}`);
88
- }
89
- // Attachments
90
- for (const att of options.attachments) {
91
- const encoded = att.content.toString("base64");
92
- parts.push(`--${mixedBoundary}\r\n` +
93
- `Content-Type: ${att.mimeType}; name="${att.filename}"\r\n` +
94
- `Content-Disposition: attachment; filename="${att.filename}"\r\n` +
95
- `Content-Transfer-Encoding: base64\r\n\r\n` +
96
- encoded);
97
- }
98
- parts.push(`--${mixedBoundary}--`);
99
- return headers.join("\r\n") + "\r\n\r\n" + parts.join("\r\n");
100
- }
101
- // --- Public API ---
102
- /**
103
- * Check if Gmail sending is ready (Google authenticated).
104
- */
105
- export function isGmailSendAvailable() {
106
- return isGoogleAuthenticated();
107
- }
108
- /**
109
- * Send an email via Gmail API.
110
- * Builds an RFC 2822 message, base64url-encodes it, and POSTs to the send endpoint.
111
- */
112
- export async function sendEmail(options) {
113
- if (!isGoogleAuthenticated()) {
114
- log.warn("Send attempted without authentication");
115
- return { ok: false, message: "Google not authenticated — connect Google first" };
116
- }
117
- // Validate required fields
118
- if (!options.to || (Array.isArray(options.to) && options.to.length === 0)) {
119
- return { ok: false, message: "No recipient specified" };
120
- }
121
- if (!options.subject) {
122
- return { ok: false, message: "No subject specified" };
123
- }
124
- if (!options.body) {
125
- return { ok: false, message: "No body specified" };
126
- }
127
- const toStr = joinAddresses(options.to);
128
- log.info("Sending email", { to: toStr, subject: options.subject, hasAttachments: !!(options.attachments?.length), threadId: options.threadId });
129
- try {
130
- const raw = buildRfc2822(options);
131
- const encoded = toBase64Url(Buffer.from(raw, "utf-8"));
132
- const payload = { raw: encoded };
133
- if (options.threadId)
134
- payload.threadId = options.threadId;
135
- // Use raw fetch instead of googlePost because the Gmail send endpoint
136
- // returns the created message directly and we need tight control
137
- const auth = await getAccessToken();
138
- if (!auth.ok)
139
- return { ok: false, message: auth.message };
140
- const res = await fetch(`${GMAIL_API}/messages/send`, {
141
- method: "POST",
142
- headers: {
143
- Authorization: `Bearer ${auth.token}`,
144
- "Content-Type": "application/json",
145
- },
146
- body: JSON.stringify(payload),
147
- signal: AbortSignal.timeout(30_000), // Longer timeout for attachments
148
- });
149
- if (!res.ok) {
150
- const text = await res.text();
151
- log.error("Email send failed", { to: toStr, status: res.status, error: text });
152
- return { ok: false, message: `Gmail send error (${res.status}): ${text}` };
153
- }
154
- const data = (await res.json());
155
- log.info("Email sent successfully", { to: toStr, messageId: data.id, threadId: data.threadId });
156
- return {
157
- ok: true,
158
- data: { id: data.id, threadId: data.threadId, labelIds: data.labelIds },
159
- message: `Email sent to ${toStr} — ID: ${data.id}`,
160
- };
161
- }
162
- catch (err) {
163
- log.error("Email send exception", { to: toStr, error: err.message });
164
- return { ok: false, message: `Gmail send failed: ${err.message}` };
165
- }
166
- }
167
- /**
168
- * Load a file from disk and return it as an EmailAttachment.
169
- * Infers MIME type from extension.
170
- */
171
- export async function attachmentFromFile(filePath) {
172
- try {
173
- log.debug("Loading attachment from file", { filePath });
174
- const content = await readFile(filePath);
175
- const filename = basename(filePath);
176
- const mimeType = inferMimeType(filename);
177
- log.debug("Attachment loaded", { filename, mimeType, sizeBytes: content.length });
178
- return {
179
- ok: true,
180
- attachment: { filename, mimeType, content },
181
- message: `Loaded ${filename} (${content.length} bytes)`,
182
- };
183
- }
184
- catch (err) {
185
- log.error("Failed to read attachment", { filePath, error: err.message });
186
- return { ok: false, message: `Failed to read attachment: ${err.message}` };
187
- }
188
- }
189
- /**
190
- * Infer MIME type from file extension.
191
- */
192
- function inferMimeType(filename) {
193
- const ext = filename.split(".").pop()?.toLowerCase() ?? "";
194
- const types = {
195
- pdf: "application/pdf",
196
- doc: "application/msword",
197
- docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
198
- xls: "application/vnd.ms-excel",
199
- xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
200
- ppt: "application/vnd.ms-powerpoint",
201
- pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
202
- png: "image/png",
203
- jpg: "image/jpeg",
204
- jpeg: "image/jpeg",
205
- gif: "image/gif",
206
- svg: "image/svg+xml",
207
- webp: "image/webp",
208
- txt: "text/plain",
209
- csv: "text/csv",
210
- html: "text/html",
211
- json: "application/json",
212
- zip: "application/zip",
213
- mp3: "audio/mpeg",
214
- mp4: "video/mp4",
215
- wav: "audio/wav",
216
- };
217
- return types[ext] ?? "application/octet-stream";
218
- }
219
- //# sourceMappingURL=gmail-send.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gmail-send.js","sourceRoot":"","sources":["../../src/google/gmail-send.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,GAAG,GAAG,YAAY,CAAC,mBAAmB,CAAC,CAAC;AAE9C,MAAM,SAAS,GAAG,8CAA8C,CAAC;AACjE,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,qBAAqB,CAAC;AA0CrE,kBAAkB;AAElB;;GAEG;AACH,SAAS,WAAW,CAAC,GAAW;IAC9B,OAAO,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC3F,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,IAAuB;IAC5C,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACtD,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB;IACvB,OAAO,cAAc,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AAC/E,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,OAAyB;IAC7C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,YAAY,CAAC;IAC1C,MAAM,EAAE,GAAG,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACrC,MAAM,OAAO,GAAa;QACxB,SAAS,IAAI,EAAE;QACf,OAAO,EAAE,EAAE;QACX,YAAY,OAAO,CAAC,OAAO,EAAE;QAC7B,mBAAmB;QACnB,SAAS,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE;KACpC,CAAC;IAEF,IAAI,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,IAAI,CAAC,OAAO,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACjE,IAAI,OAAO,CAAC,GAAG;QAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACpE,IAAI,OAAO,CAAC,SAAS;QAAE,OAAO,CAAC,IAAI,CAAC,gBAAgB,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACzE,IAAI,OAAO,CAAC,UAAU;QAAE,OAAO,CAAC,IAAI,CAAC,eAAe,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAE1E,MAAM,cAAc,GAAG,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;IAC7E,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;IAEnC,2CAA2C;IAC3C,IAAI,CAAC,cAAc,IAAI,CAAC,OAAO,EAAE,CAAC;QAChC,OAAO,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QAChD,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAC1D,CAAC;IAED,uDAAuD;IACvD,IAAI,CAAC,cAAc,IAAI,OAAO,EAAE,CAAC;QAC/B,MAAM,WAAW,GAAG,gBAAgB,EAAE,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,kDAAkD,WAAW,GAAG,CAAC,CAAC;QAC/E,MAAM,KAAK,GAAG;YACZ,KAAK,WAAW,2FAA2F,OAAO,CAAC,IAAI,EAAE;YACzH,KAAK,WAAW,0FAA0F,OAAO,CAAC,QAAQ,EAAE;YAC5H,KAAK,WAAW,IAAI;SACrB,CAAC;QACF,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChE,CAAC;IAED,qCAAqC;IACrC,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;IACzC,OAAO,CAAC,IAAI,CAAC,4CAA4C,aAAa,GAAG,CAAC,CAAC;IAE3E,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,uCAAuC;IACvC,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,WAAW,GAAG,gBAAgB,EAAE,CAAC;QACvC,KAAK,CAAC,IAAI,CACR,KAAK,aAAa,sDAAsD,WAAW,WAAW;YAC9F,KAAK,WAAW,2FAA2F,OAAO,CAAC,IAAI,MAAM;YAC7H,KAAK,WAAW,0FAA0F,OAAO,CAAC,QAAQ,MAAM;YAChI,KAAK,WAAW,IAAI,CACrB,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CACR,KAAK,aAAa,2FAA2F,OAAO,CAAC,IAAI,EAAE,CAC5H,CAAC;IACJ,CAAC;IAED,cAAc;IACd,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,WAAY,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC/C,KAAK,CAAC,IAAI,CACR,KAAK,aAAa,MAAM;YACxB,iBAAiB,GAAG,CAAC,QAAQ,WAAW,GAAG,CAAC,QAAQ,OAAO;YAC3D,8CAA8C,GAAG,CAAC,QAAQ,OAAO;YACjE,2CAA2C;YAC3C,OAAO,CACR,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAK,aAAa,IAAI,CAAC,CAAC;IACnC,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAChE,CAAC;AAED,qBAAqB;AAErB;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,qBAAqB,EAAE,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAyB;IACvD,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC;QAC7B,GAAG,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;QAClD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,iDAAiD,EAAE,CAAC;IACnF,CAAC;IAED,2BAA2B;IAC3B,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;QAC1E,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,wBAAwB,EAAE,CAAC;IAC1D,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC;IACxD,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC;IACrD,CAAC;IAED,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACxC,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAEhJ,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;QAEvD,MAAM,OAAO,GAA2B,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;QACzD,IAAI,OAAO,CAAC,QAAQ;YAAE,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QAE1D,sEAAsE;QACtE,iEAAiE;QACjE,MAAM,IAAI,GAAG,MAAM,cAAc,EAAE,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;QAE1D,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,SAAS,gBAAgB,EAAE;YACpD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;gBACrC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;YAC7B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,iCAAiC;SACvE,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,GAAG,CAAC,KAAK,CAAC,mBAAmB,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/E,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,qBAAqB,GAAG,CAAC,MAAM,MAAM,IAAI,EAAE,EAAE,CAAC;QAC7E,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAsB,CAAC;QACrD,GAAG,CAAC,IAAI,CAAC,yBAAyB,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAChG,OAAO;YACL,EAAE,EAAE,IAAI;YACR,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE;YACvE,OAAO,EAAE,iBAAiB,KAAK,UAAU,IAAI,CAAC,EAAE,EAAE;SACnD,CAAC;IACJ,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,GAAG,CAAC,KAAK,CAAC,sBAAsB,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACrE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,sBAAsB,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;IACrE,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,QAAgB;IAKvD,IAAI,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,8BAA8B,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACpC,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;QAEzC,GAAG,CAAC,KAAK,CAAC,mBAAmB,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAClF,OAAO;YACL,EAAE,EAAE,IAAI;YACR,UAAU,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE;YAC3C,OAAO,EAAE,UAAU,QAAQ,KAAK,OAAO,CAAC,MAAM,SAAS;SACxD,CAAC;IACJ,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,GAAG,CAAC,KAAK,CAAC,2BAA2B,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACzE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,8BAA8B,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;IAC7E,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,QAAgB;IACrC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IAC3D,MAAM,KAAK,GAA2B;QACpC,GAAG,EAAE,iBAAiB;QACtB,GAAG,EAAE,oBAAoB;QACzB,IAAI,EAAE,yEAAyE;QAC/E,GAAG,EAAE,0BAA0B;QAC/B,IAAI,EAAE,mEAAmE;QACzE,GAAG,EAAE,+BAA+B;QACpC,IAAI,EAAE,2EAA2E;QACjF,GAAG,EAAE,WAAW;QAChB,GAAG,EAAE,YAAY;QACjB,IAAI,EAAE,YAAY;QAClB,GAAG,EAAE,WAAW;QAChB,GAAG,EAAE,eAAe;QACpB,IAAI,EAAE,YAAY;QAClB,GAAG,EAAE,YAAY;QACjB,GAAG,EAAE,UAAU;QACf,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,kBAAkB;QACxB,GAAG,EAAE,iBAAiB;QACtB,GAAG,EAAE,YAAY;QACjB,GAAG,EAAE,WAAW;QAChB,GAAG,EAAE,WAAW;KACjB,CAAC;IACF,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,0BAA0B,CAAC;AAClD,CAAC"}
@@ -1,223 +0,0 @@
1
- /**
2
- * Background inbox polling timer.
3
- * Checks for new messages every 5 minutes.
4
- * Pushes notifications for new unread messages.
5
- * Emails with the instance name in the subject are processed as chat and replied to automatically.
6
- * Follows src/goals/timer.ts pattern: module-level state, idempotent start/stop.
7
- */
8
- import { getRecentMessages, getMessage, isGmailAvailable } from "./gmail.js";
9
- import { pushNotification } from "../goals/notifications.js";
10
- import { logActivity } from "../activity/log.js";
11
- import { createLogger } from "../utils/logger.js";
12
- import { getInstanceName, getInstanceNameLower } from "../instance.js";
13
- const log = createLogger("gmail");
14
- const DEFAULT_INTERVAL_MS = parseInt(process.env.GMAIL_POLL_INTERVAL_MS ?? "", 10) || 5 * 60 * 1000; // default 5 min, override with GMAIL_POLL_INTERVAL_MS
15
- let timer = null;
16
- const seenMessageIds = new Set(); // Track seen messages to avoid duplicates
17
- let initialized = false;
18
- let dashEmailHandler = null;
19
- /** The subject-line pattern that triggers instance email processing. */
20
- const DASH_SUBJECT_PATTERN = new RegExp(`\\b${getInstanceNameLower()}\\b`, "i");
21
- /**
22
- * Register a handler for instance-addressed emails.
23
- * When the timer finds new unread emails with the instance name in the subject,
24
- * it fetches the full body and calls this handler.
25
- */
26
- export function onDashEmail(handler) {
27
- dashEmailHandler = handler;
28
- }
29
- /** Alias for onDashEmail — preferred name for generic instances. */
30
- export const onInstanceEmail = onDashEmail;
31
- /**
32
- * Start the Gmail polling timer. Idempotent.
33
- */
34
- export function startGmailTimer(intervalMs) {
35
- if (timer)
36
- return;
37
- const interval = intervalMs ?? DEFAULT_INTERVAL_MS;
38
- // Run an initial check to seed the seen set (don't notify on first run)
39
- (async () => {
40
- if (!isGmailAvailable())
41
- return;
42
- try {
43
- const result = await getRecentMessages(1);
44
- if (result.ok && result.messages) {
45
- for (const msg of result.messages) {
46
- seenMessageIds.add(msg.id);
47
- }
48
- }
49
- initialized = true;
50
- }
51
- catch {
52
- initialized = true; // Continue even if initial seed fails
53
- }
54
- })();
55
- timer = setInterval(async () => {
56
- if (!isGmailAvailable() || !initialized)
57
- return;
58
- try {
59
- const result = await getRecentMessages(1); // Last hour
60
- if (!result.ok || !result.messages)
61
- return;
62
- const newMessages = result.messages.filter((m) => m.isUnread && !seenMessageIds.has(m.id));
63
- // Track all seen IDs
64
- for (const msg of result.messages) {
65
- seenMessageIds.add(msg.id);
66
- }
67
- if (newMessages.length > 0) {
68
- // Separate instance-addressed emails from regular notifications
69
- const dashEmails = [];
70
- const regularEmails = [];
71
- for (const m of newMessages) {
72
- if (DASH_SUBJECT_PATTERN.test(m.subject)) {
73
- dashEmails.push(m);
74
- }
75
- else {
76
- regularEmails.push(m);
77
- }
78
- }
79
- // Process instance-addressed emails (fetch body, run through AI, reply)
80
- if (dashEmails.length > 0 && dashEmailHandler) {
81
- for (const m of dashEmails) {
82
- processDashEmail(m).catch((err) => {
83
- const errMsg = err instanceof Error ? err.message : String(err);
84
- log.error(`Failed to process ${getInstanceName()} email`, { messageId: m.id, error: errMsg });
85
- logActivity({ source: "gmail", summary: `Failed to process ${getInstanceName()} email from ${m.from}: ${errMsg}` });
86
- });
87
- }
88
- }
89
- // Fetch full body for regular emails and push rich notifications
90
- if (regularEmails.length > 0) {
91
- for (const m of regularEmails) {
92
- fetchAndNotify(m).catch((err) => {
93
- const errMsg = err instanceof Error ? err.message : String(err);
94
- log.warn("Failed to fetch email body for notification", { messageId: m.id, error: errMsg });
95
- // Fall back to snippet-only notification
96
- pushNotification({
97
- timestamp: new Date().toISOString(),
98
- source: "gmail",
99
- message: `New email from ${m.from}: "${m.subject}"\n${m.snippet}`,
100
- });
101
- });
102
- }
103
- logActivity({
104
- source: "gmail",
105
- summary: `${regularEmails.length} new unread email(s)`,
106
- });
107
- }
108
- // Separate log for instance-addressed emails
109
- if (dashEmails.length > 0) {
110
- logActivity({
111
- source: "gmail",
112
- summary: `${dashEmails.length} ${getInstanceName()}-addressed email(s) detected — processing`,
113
- });
114
- }
115
- }
116
- // Prune old seen IDs (keep max 500)
117
- if (seenMessageIds.size > 500) {
118
- const arr = [...seenMessageIds];
119
- const toRemove = arr.slice(0, arr.length - 500);
120
- for (const id of toRemove)
121
- seenMessageIds.delete(id);
122
- }
123
- }
124
- catch (err) {
125
- const msg = err instanceof Error ? err.message : String(err);
126
- logActivity({ source: "gmail", summary: `Poll error: ${msg}` });
127
- }
128
- }, interval);
129
- const mins = Math.round(interval / 60_000);
130
- log.info(`Gmail poll: every ${mins} min`);
131
- }
132
- /**
133
- * Fetch full email body and push a rich notification so the instance can reason about it in chat.
134
- * Truncates body to keep notification size reasonable.
135
- */
136
- async function fetchAndNotify(m) {
137
- const full = await getMessage(m.id);
138
- const body = full.ok && full.message?.body?.trim()
139
- ? full.message.body.trim()
140
- : m.snippet;
141
- // Truncate body to ~500 chars for notification context
142
- const truncated = body.length > 500 ? body.slice(0, 500) + "..." : body;
143
- const senderName = m.from.split("<")[0].trim();
144
- pushNotification({
145
- timestamp: new Date().toISOString(),
146
- source: "gmail",
147
- message: [
148
- `New email from ${senderName}: "${m.subject}" [threadId: ${m.threadId}]`,
149
- truncated,
150
- ].join("\n"),
151
- });
152
- }
153
- /**
154
- * Fetch full email body and run through the instance email handler.
155
- */
156
- async function processDashEmail(m) {
157
- if (!dashEmailHandler)
158
- return;
159
- // Fetch full message with body
160
- const full = await getMessage(m.id);
161
- if (!full.ok || !full.message) {
162
- log.error(`Failed to fetch full ${getInstanceName()} email`, { messageId: m.id });
163
- return;
164
- }
165
- const emailBody = full.message.body?.trim();
166
- if (!emailBody) {
167
- log.warn(`${getInstanceName()} email has no body`, { messageId: m.id, subject: m.subject });
168
- return;
169
- }
170
- log.info(`Processing ${getInstanceName()} email`, { from: m.from, subject: m.subject, bodyLength: emailBody.length });
171
- const reply = await dashEmailHandler(full.message);
172
- if (!reply) {
173
- log.warn(`${getInstanceName()} email handler returned no reply`, { messageId: m.id });
174
- return;
175
- }
176
- // Send reply via sendEmail (imported dynamically to avoid circular deps)
177
- const { sendEmail } = await import("./gmail-send.js");
178
- const senderEmail = extractEmail(m.from);
179
- const subject = m.subject.startsWith("Re:") ? m.subject : `Re: ${m.subject}`;
180
- const result = await sendEmail({
181
- to: senderEmail,
182
- subject,
183
- body: reply,
184
- threadId: m.threadId,
185
- inReplyTo: m.rfc822MessageId,
186
- });
187
- if (result.ok) {
188
- log.info(`Replied to ${getInstanceName()} email`, { to: senderEmail, subject });
189
- logActivity({ source: "gmail", summary: `${getInstanceName()} replied to email from ${senderEmail}: "${m.subject}"`, actionLabel: "AUTONOMOUS", reason: `${getInstanceName()}-addressed email auto-reply` });
190
- pushNotification({
191
- timestamp: new Date().toISOString(),
192
- source: "gmail",
193
- message: `Replied to email from **${m.from.split("<")[0].trim()}**: "${m.subject}"`,
194
- });
195
- }
196
- else {
197
- log.error(`Failed to reply to ${getInstanceName()} email`, { to: senderEmail, error: result.message });
198
- logActivity({ source: "gmail", summary: `Failed to reply to ${getInstanceName()} email: ${result.message}`, actionLabel: "AUTONOMOUS", reason: `${getInstanceName()}-addressed email auto-reply failed` });
199
- }
200
- }
201
- /** Extract email address from "Name <email>" format. */
202
- function extractEmail(from) {
203
- const match = from.match(/<(.+?)>/);
204
- return match ? match[1] : from.trim();
205
- }
206
- /**
207
- * Stop the Gmail polling timer.
208
- */
209
- export function stopGmailTimer() {
210
- if (timer) {
211
- clearInterval(timer);
212
- timer = null;
213
- }
214
- seenMessageIds.clear();
215
- initialized = false;
216
- }
217
- /**
218
- * Check if the Gmail timer is running.
219
- */
220
- export function isGmailTimerRunning() {
221
- return timer !== null;
222
- }
223
- //# sourceMappingURL=gmail-timer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gmail-timer.js","sourceRoot":"","sources":["../../src/google/gmail-timer.ts"],"names":[],"mappings":"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"}