g1t/packages/contracts/src/events.ts

76 lines2,969 bytesCodeBlame

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Initial g1t: services, event bus, intents and attempts1/**
2 * Every state change in g1t is published as an event. Services react to
3 * each other through events rather than direct calls, and the same stream
4 * feeds timelines, webhooks and automations.
5 *
6 * The envelope follows CloudEvents: `type` says what happened, `subject`
7 * says to what, `data` is the type-specific payload.
8 */
9export type EventPayloads = {
10 "repo.created": { repoId: string; namespace: string; name: string; isPrivate: boolean };
Issues and pull requests replace intents and attempts11 "repo.forked": { repoId: string; sourceRepoId: string; pullId: string };
Initial g1t: services, event bus, intents and attempts12 /** `after` is the commit the ref points to once the push has landed. */
13 "git.push": { repoId: string; ref: string; after: string };
Issues and pull requests replace intents and attempts14 "issue.opened": { issueId: string; repoId: string; number: number; title: string };
15 "issue.updated": { issueId: string; repoId: string; number: number };
16 /** `resolvedBy` is the number of the pull request whose merge closed it. */
17 "issue.closed": {
18 issueId: string;
19 repoId: string;
20 number: number;
21 reason: "completed" | "not_planned";
22 resolvedBy?: number;
23 };
24 "issue.reopened": { issueId: string; repoId: string; number: number };
25 /** `issue` is the number of the issue the pull request is for. */
26 "pull.opened": { pullId: string; repoId: string; number: number; issue?: number; agent: string };
27 "pull.ready": { pullId: string; repoId: string; number: number; issue?: number };
28 "pull.closed": { pullId: string; repoId: string; number: number; issue?: number };
29 "pull.merged": { pullId: string; repoId: string; number: number; issue?: number; commit: string };
30 /** `number` is the issue or pull request commented on. */
31 "comment.created": { commentId: string; repoId: string; number: number };
32 "session.appended": { pullId: string; repoId: string; number: number; count: number };
Initial g1t: services, event bus, intents and attempts33};
34
35export type EventType = keyof EventPayloads;
36
37export type G1tEvent<T extends EventType = EventType> = {
38 [K in T]: {
39 id: string;
40 type: K;
41 /** The service that published it. */
42 source: string;
43 /** Milliseconds since the epoch. */
44 time: number;
45 /** The repo the event concerns, used to scope timelines and deliveries. */
46 repoId: string | null;
47 /** The user or agent that caused it, if any. */
48 actor: string | null;
49 data: EventPayloads[K];
50 };
51}[T];
52
53/** What a publisher supplies; the bus fills in `id` and `time`. */
54export type NewEvent<T extends EventType = EventType> = {
55 [K in T]: Omit<G1tEvent<K>, "id" | "time">;
56}[T];
57
58export type EventQuery = {
59 repoId?: string;
60 types?: EventType[];
61 /** Return events older than this event id. */
62 before?: string;
63 limit?: number;
64};
65
66/** The event bus and its durable log. */
67export interface EventsApi {
68 publish(events: NewEvent[]): Promise<void>;
69 /** Newest first. */
70 list(query: EventQuery): Promise<G1tEvent[]>;
71}
72
73/** Implemented by services that consume events from the bus. */
74export interface EventSubscriber {
75 onEvents(events: G1tEvent[]): Promise<void>;
76}