symbiont_ex/lib/symbiont/telepathy/supervisor.ex
Claude Opus 4.6 fe5896be2d feat: initial Telepathy Elixir port — GenServer + JMAP fetch loop
Adds the Telepathy email communication layer as an OTP subtree:

- Telepathy.JMAP: GenServer that discovers Fastmail JMAP session,
  periodically polls inbox for new emails, and provides send_email/3.
  Uses :httpc (no external HTTP dep). Deduplicates via seen_ids MapSet
  seeded from existing MessageStore entries.

- Telepathy.MessageStore: JSONL-backed message persistence, compatible
  with the existing Python messages.jsonl format. Supports store, unread,
  mark_read, list, count operations.

- Telepathy.Supervisor: rest_for_one supervisor (MessageStore then JMAP).

- Conditionally enabled via config (:telepathy, :enabled). Disabled in
  test env. Can be disabled at runtime via TELEPATHY_ENABLED=false.

Validated against live Fastmail: session discovery, inbox fetch (20
emails), message storage all working.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-19 06:11:13 +00:00

28 lines
786 B
Elixir

defmodule Symbiont.Telepathy.Supervisor do
@moduledoc """
Supervision subtree for Telepathy (email communication layer).
Children:
- MessageStore — JSONL-backed message persistence
- JMAP — Fastmail JMAP client with periodic inbox polling
"""
use Supervisor
def start_link(opts) do
Supervisor.start_link(__MODULE__, opts, name: __MODULE__)
end
@impl true
def init(opts) do
messages_path = Keyword.get(opts, :messages_path, "/data/telepathy/messages.jsonl")
poll_interval_ms = Keyword.get(opts, :poll_interval_ms, 60_000)
children = [
{Symbiont.Telepathy.MessageStore, path: messages_path},
{Symbiont.Telepathy.JMAP, poll_interval_ms: poll_interval_ms}
]
Supervisor.init(children, strategy: :rest_for_one)
end
end