Concepts

Events

How code forges deliver changes, and how providers turn them into one event type.

A ForgeEvent describes something that happened, such as a comment, a push, a review or a label change. Providers produce events from three sources:

SourceHow it worksCapability
webhookThe forge sends an HTTP request to your server.sources.webhook
pollYou list notifications or thread events on a schedule.sources.poll
subscribeYou keep a connection open and receive events as they happen.sources.subscribe

event.source tells you which one delivered an event. Most forges support webhooks. Tangled also offers subscribe through Jetstream. GitHub, GitLab, Forgejo, Gitea and Gitee can be polled.

Shape of an event

FieldContent
kindWhat kind of thing happened, such as comment, review, state_change, label, push or release
actionThe verb, such as opened, closed, merged, created or labelled
summaryOne line that suits a list row
actor, repo, threadWho did it, and where, when the event has them
detailTyped fields for the kind, discriminated by detail.type
occurredAtA Date
payloadThe unnormalised delivery

Raw names stay available

The normalised kind and action come from a forge's own event name and verb, which stay in kindRaw and actionRaw. When a forge uses wording that has no equivalent, action is other and the raw name still tells you what happened.

On GitLab, event kinds for some thread changes come from the text of system notes rather than a field. That provider reports eventKinds: 'heuristic' in its capabilities. For an unrecognised note, kind can be other, and kindRaw and payload stay exact.

Subscriptions

sources.subscribe() returns an async iterable of { event, cursor }. Save the cursor and pass it back to resume. The provider doesn't reconnect when the connection drops. It throws SubscriptionClosedError with the last cursor, and you call subscribe() again:

for await (const { event, cursor } of reader.sources.subscribe({
  cursor: saved,
  signal,
})) {
  console.log(event.kind, event.summary)
  saved = cursor
}

Next steps

Copyright © 2026