(*--------------------------------------------------------------------------- Copyright (c) 2026 Anil Madhavapeddy . All rights reserved. SPDX-License-Identifier: ISC ---------------------------------------------------------------------------*) (** Combined loop for change detection, broadcast, and message handling. This module implements a polling loop that periodically checks for new changes in the monorepo and broadcasts them to Zulip. It also runs a concurrent message handler to respond to DMs and mentions while the broadcast loop sleeps. *) val run : sw:Eio.Switch.t -> env:< clock : float Eio.Time.clock_ty Eio.Resource.t ; fs : Eio.Fs.dir_ty Eio.Path.t ; net : [ `Generic | `Unix ] Eio.Net.ty Eio.Resource.t ; process_mgr : _ Eio.Process.mgr ; .. > -> config:Config.t -> zulip_config:Zulip_bot.Config.t -> handler:Zulip_bot.Bot.handler -> interval:int -> unit (** [run ~sw ~env ~config ~zulip_config ~handler ~interval] starts both the polling loop and the message handler concurrently. The broadcast loop flow: 1. Pull latest changes from remote (git pull --ff-only) 2. Check if git HEAD has changed (compare with stored last_git_head) 3. If changed: - Get commits since last HEAD via git log - Fetch channel members for mention matching - Generate narrative changelog using Claude - Send to Zulip channel - Update last_broadcast_time and last_git_head in storage 4. Sleep for interval seconds 5. Repeat Concurrently, the message handler listens for incoming Zulip messages (DMs and mentions) and processes them using the provided handler. @param sw Eio switch for resource management @param env Eio environment @param config Poe configuration @param zulip_config Zulip bot configuration @param handler Message handler function @param interval Seconds between broadcast checks (default: 3600) *)