diff options
| author | Adam Malczewski <[email protected]> | 2026-06-01 09:28:21 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-01 09:28:21 +0900 |
| commit | 5e72191cac9469c2ade91aaba1e62f69fa1ad94a (patch) | |
| tree | bfa21aa2841277b8861bd05a0e2472211bed0aa9 /packages/api/src | |
| parent | 97c1b40ead19cdfe54b9a7aeb2c0fdcc1c9653b1 (diff) | |
| download | dispatch-5e72191cac9469c2ade91aaba1e62f69fa1ad94a.tar.gz dispatch-5e72191cac9469c2ade91aaba1e62f69fa1ad94a.zip | |
feat(core): ntfy.sh notification dispatcher module
Adds a transport-agnostic NotificationDispatcher and a fire-and-forget
ntfy.sh transport (no SDK; just fetch). Configuration is persisted as a
single global JSON blob under the 'ntfy_config' settings key.
Event taxonomy (per-event toggles):
- turn-completed — assistant turn finished cleanly
- turn-error — final turn error (after all fallbacks)
- permission-required — new permission prompt was created
- agent-spawned — top-level user-agent tab spawned via 'summon'
Design:
- Single internal notify(event) interface so a future transport (email,
webhook) plugs in without changing call sites.
- attachToAgentManager + attachToPermissionManager subscribe to the
existing event streams via narrow listener interfaces (no @dispatch/api
dependency back into core).
- 5s in-memory dedupe window on dedupeKey suppresses permission re-emits.
- 10s per-request abort timeout so a hung ntfy server can't pin a worker.
- All sends are fire-and-forget: void Promise.resolve(...).catch(warn).
Tests (39 new):
- ntfy transport: URL/headers/body/auth/click, header sanitization,
per-event-type defaults, error paths.
- config: defaults, normalization tolerance, round-trip, redaction.
- dispatcher: master switch, per-event toggle, dedupe, agent/permission
hookups, top-level-only filtering for agent-spawned, dispose.
Diffstat (limited to 'packages/api/src')
0 files changed, 0 insertions, 0 deletions
