af-notify 0.2.0

Notification dispatcher + Sender trait seam (Telegram/email/Discord are pluggable adapters). Typed blocks + plain-text renderer.
Documentation

af-notify — notification dispatcher + transport seam. Port of the reusable core of agent_core/notifications/.

The governance rule that carries over: every outbound message goes through the dispatcher, never a raw api.telegram.org/... POST. A product builds a typed [Notification] (transport-agnostic blocks) and dispatches it; each [Sender] renders the blocks its own way (a chat transport flattens to text, a rich transport keeps structure).

Transports (Telegram / email / Discord) are pluggable adapters that implement [Sender] — the core never depends on a specific provider.

use af_notify::{Block, Dispatcher, LogSender, Notification};
use std::sync::Arc;

# tokio_test(async {
let mut d = Dispatcher::new();
d.register(Arc::new(LogSender));
let notif = Notification::new()
    .title("Run finished")
    .block(Block::text("Your workflow completed."))
    .block(Block::fields(vec![("duration".into(), "1.2s".into())]));
d.dispatch("log", "ops", &notif).await.unwrap();
# });
# fn tokio_test<F: std::future::Future>(_: F) {}