Skip to content
587 linesCodeBlameRaw

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.

Get started on mission control1/**
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
Sidebar: the panels really slide4 * feeds timelines, webhooks and workflows.
Get started on mission control5 *
6 * The envelope follows CloudEvents: `type` says what happened, `subject`
7 * says to what, `data` is the type-specific payload.
8 */
9
Merge Actions: cross-repo workflows and actions, release and deployment triggers, step timeouts10import type { Release } from "./about";
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look11import type { RepoRole } from "./access";
Merge checks: statuses and check runs on every commit12import type { CheckRunEventData, CheckSuiteEventData, StatusEventData } from "./checks";
Merge branch 'mirroring' into artifacts-mode13import type { RepoMirror } from "./mirrors";
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9714import type { DeploymentStatus, RepoDeployment } from "./deployments";
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar15import type { TeamRole, TeamVisibility } from "./teams";
Cards you act on in chat; agents comment and review as themselves; names shown cleanly; commits on the calendar16import type { AgentRef, Confidence, Verdict } from "./work";
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look17
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member18/** What every `package.*` event names. */
19export type PackageEventData = {
20 packageId: string;
21 workspace: string;
22 ecosystem: string;
23 name: string;
24 repoId: string | null;
25};
26
Events: review requests, assignments, stops and deployments are published27/** What `deployment.succeeded` and `deployment.failed` carry. */
28export type DeploymentEventData = {
29 deploymentId: string;
30 projectId: string;
31 repoId: string;
32 workspace: string;
33 project: string;
34 kind: "production" | "preview";
35 branch: string | null;
36 number: number | null;
37 commit: string;
38 path: string;
39 error: string | null;
40 recovered: boolean;
41 /** A username, or `g1t`. */
42 triggeredBy: string;
43};
44
Merge Actions: cross-repo workflows and actions, release and deployment triggers, step timeouts45/** What every `release.*` event carries. */
46export type ReleaseEventData = {
47 releaseId: string;
48 repoId: string;
49 tagName: string;
50 release: Release;
51 /** On `release.edited`: what the title and notes were before. */
52 changes?: { name?: { from: string | null }; body?: { from: string } };
53 /** Set when a workflow job's token made the change: the run's id. */
54 causedByJob?: string;
55};
56
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look57/** The payload of the `repo.collaborator_*` events. */
58export type RepoCollaboratorData = {
59 repoId: string;
60 namespace: string;
61 name: string;
62 username: string;
63 role: RepoRole | null;
64 previousRole: RepoRole | null;
65};
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar66/** A team asked to review a pull request. */
67export type TeamRequested = { team: string; notified: string[]; assigned: string[] };
68
69/** The payload of the `team.*` events; each sets the fields that apply. */
70export type TeamChangedData = {
71 workspace: string;
72 teamId: string;
73 team: string;
74 name: string;
75 visibility: TeamVisibility | null;
76 parent?: string;
77 changes?: string[];
78 username?: string;
79 role?: TeamRole;
80 previousRole?: TeamRole;
81 repoId?: string;
82 repo?: string;
83 repoRole?: RepoRole;
84 previousRepoRole?: RepoRole;
85};
86
Get started on mission control87export type EventPayloads = {
88 "repo.created": { repoId: string; namespace: string; name: string; isPrivate: boolean };
89 "repo.forked": { repoId: string; sourceRepoId: string; pullId: string };
90 /**
Search across all of g1t, Explore, and a command palette91 * A repository's description, topics or visibility changed.
92 * `visibilityChanged` says whether it went public or private, which
93 * `repo.visibility_changed` also announces on its own.
94 */
95 "repo.updated": { repoId: string; namespace: string; name: string; isPrivate: boolean; visibilityChanged: boolean };
96 "repo.visibility_changed": { repoId: string; isPrivate: boolean };
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look97 /**
98 * A repository's name changed within its workspace `namespace`, from
99 * `from` to `to`, keeping its id. A path change like `repo.transferred`:
100 * services move rows kept under its path to its *current* path (see
101 * `repoMove`, `currentMovedPath`).
102 */
103 "repo.renamed": { repoId: string; namespace: string; from: string; to: string };
104 /**
105 * A repository was deleted. It is hidden and git refuses it, but it can
106 * be restored until `purgeAfter`: services stop what runs for it and hide
107 * it, and keep their rows until `repo.purged`.
108 */
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member109 "repo.deleted": {
110 repoId: string;
111 namespace: string;
112 name: string;
113 isPrivate: boolean;
114 purgeAfter: string;
115 /** It went with its workspace (`workspace.deleting`); deployments leaves it to that. */
116 withWorkspace?: boolean;
117 };
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look118 /** A deleted repository is back, as it was. Services start again what they stopped. */
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member119 "repo.restored": {
120 repoId: string;
121 namespace: string;
122 name: string;
123 isPrivate: boolean;
124 /** It came back with its workspace (`workspace.restored`). */
125 withWorkspace?: boolean;
126 };
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look127 /**
128 * A deleted repository is gone for good, its git data with it. Services
129 * drop every row they keep for it, except a workspace's history (ledgers,
130 * invoices, the audit log).
131 */
132 "repo.purged": { repoId: string; namespace: string; name: string };
133 /**
134 * A repository was archived (read-only: pushes, merges, agents and
135 * workflows refused; issues and pull requests locked; deployments keep
136 * serving), or unarchived.
137 */
138 "repo.archived": { repoId: string; namespace: string; name: string; archived: true };
139 "repo.unarchived": { repoId: string; namespace: string; name: string; archived: false };
140 /** The default branch is now `to`; `renamed` when `from` was renamed to it. */
141 "repo.default_branch_changed": { repoId: string; from: string; to: string; renamed: boolean };
142 /** A branch was renamed. Pull requests from it follow. */
143 "branch.renamed": { repoId: string; from: string; to: string; defaultBranch: boolean };
Search across all of g1t, Explore, and a command palette144 /** An account was made, or changed what its profile shows. Ask identity for the profile. */
145 "user.updated": { username: string };
Merge account deletion: soft delete for 30 days, staff restore and purge, ghost for what remains (identity 0037)146 /**
147 * An account was deleted, by the person or by g1t's staff; staff can
148 * restore it until `purgeAfter`. Its sessions, tokens and keys have ended
149 * and it has left every workspace. Services stop what they do for it and
150 * keep their rows; `user.restored` undoes that, and `user.deleted` follows
151 * once `purgeAfter` passes.
152 */
153 "user.deleting": { userId: string; username: string; byStaff: boolean; purgeAfter: string };
154 /** Staff brought a deleted account back. Services undo what they did on `user.deleting`. */
155 "user.restored": { userId: string; username: string };
156 /**
157 * An account is gone for good. Services drop what they keep for it alone
158 * and show what it wrote as `ghost` (`GHOST_USERNAME`, `GHOST_ID`).
159 * Ledgers, invoices and audit logs keep its username, which is never given
160 * to anyone again.
161 */
162 "user.deleted": { userId: string; username: string };
Search across all of g1t, Explore, and a command palette163 /** A workspace was made, or its name, description or icon changed. */
164 "workspace.updated": { workspaceId: string; slug: string };
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look165 /** Someone, or g1t staff, made an invite. Never the code or the address. */
166 "invite.created": { inviteId: string; inviterId: string | null; workspaceId: string | null; bound: boolean };
167 /** An invite was used: by a new account, or by an account joining a workspace. */
168 "invite.redeemed": {
169 inviteId: string;
170 userId: string;
171 inviterId: string | null;
172 workspaceId: string | null;
173 createdAccount: boolean;
174 };
175 /** Someone asked for access while registration is invite-only. The address is not in the event. */
176 "waitlist.requested": { entryId: string };
Search across all of g1t, Explore, and a command palette177 /**
Get started on mission control178 * One branch moved by a push. `ref` is the full ref, `after` the commit it
179 * points to now, and `defaultBranch` whether it is the default branch.
180 */
g1t is the stored author of what it opens; the person who asked is requested_by and keeps the author's rights181 /**
Merge leftovers: plan activity filtered in the query, pushes counted by account, ghost during the deletion window, profile time zones (identity 0039)182 * `before` is where the ref pointed before; absent for a new branch or
183 * tag. `causedByJob` is set when a workflow job's token pushed: the run's id.
184 */
Merge branch 'mirroring' into artifacts-mode185 "git.push": {
186 repoId: string;
187 ref: string;
188 before?: string;
189 after: string;
190 defaultBranch: boolean;
191 causedByJob?: string;
192 /** Set when it was copied in from the remote a mirror follows, not made on g1t. */
193 mirrored?: boolean;
194 /** The repository's mirror state when it landed; absent for one that leads. */
195 mirror?: RepoMirror;
196 };
Merge leftovers: plan activity filtered in the query, pushes counted by account, ghost during the deletion window, profile time zones (identity 0039)197 /**
g1t is the stored author of what it opens; the person who asked is requested_by and keeps the author's rights198 * `author` is who opened it: g1t, for one its agent filed while at work,
199 * with `requestedBy` the person it was working for. Every issue and pull
200 * request event carries both.
201 */
202 "issue.opened": {
203 issueId: string;
204 repoId: string;
205 number: number;
206 title: string;
207 author?: { id: string; username: string };
208 requestedBy?: { id: string; username: string };
209 };
Get started on mission control210 "issue.updated": { issueId: string; repoId: string; number: number };
Events: review requests, assignments, stops and deployments are published211 /** The people an issue is assigned to changed; `assignees` is the new set, `added` those newly assigned. */
212 "issue.assigned": { issueId: string; repoId: string; number: number; assignees: string[]; added?: string[] };
Get started on mission control213 /** `resolvedBy` is the number of the pull request whose merge closed it. */
214 "issue.closed": {
215 issueId: string;
216 repoId: string;
217 number: number;
218 reason: "completed" | "not_planned";
219 resolvedBy?: number;
220 };
221 "issue.reopened": { issueId: string; repoId: string; number: number };
g1t is the stored author of what it opens; the person who asked is requested_by and keeps the author's rights222 /**
223 * `issue` is the number of the issue the pull request is for. `author` is
224 * who opened it: g1t, for a change g1t made, with `requestedBy` the person
225 * who asked for it.
226 */
227 "pull.opened": {
228 pullId: string;
229 repoId: string;
230 number: number;
231 issue?: number;
232 agent: string;
233 author?: { id: string; username: string };
234 requestedBy?: { id: string; username: string };
235 };
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step236 /** `confidence`, on a g1t agent's change once g1t has worked it out, is on every pull request event. */
237 "pull.ready": { pullId: string; repoId: string; number: number; issue?: number; confidence?: Confidence };
Get started on mission control238 /** A push moved the head of a pull request that is ready for review. */
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step239 "pull.updated": { pullId: string; repoId: string; number: number; issue?: number; commit: string; confidence?: Confidence };
Get started on mission control240 /** A merge was asked for while the pull request was behind; it has to catch up first. */
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step241 "pull.merge_requested": { pullId: string; repoId: string; number: number; issue?: number; confidence?: Confidence };
242 "pull.closed": { pullId: string; repoId: string; number: number; issue?: number; confidence?: Confidence };
Merge Actions: cross-repo workflows and actions, release and deployment triggers, step timeouts243 /** A closed pull request was opened again. `commit` is its head. */
244 "pull.reopened": { pullId: string; repoId: string; number: number; issue?: number; commit?: string; confidence?: Confidence };
245 /** A pull request that was ready for review was turned back into a draft. */
246 "pull.converted_to_draft": { pullId: string; repoId: string; number: number; issue?: number; confidence?: Confidence };
Events: review requests, assignments, stops and deployments are published247 /** People were assigned to a pull request: `assignees` is the new set, `added` those newly assigned. */
248 "pull.assigned": { pullId: string; repoId: string; number: number; issue?: number; assignees: string[]; added: string[] };
249 /** Reviewers were asked for a pull request (`reviewers`), or no longer are. */
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar250 "pull.review_requested": {
251 pullId: string;
252 repoId: string;
253 number: number;
254 issue?: number;
255 reviewers?: string[];
256 /** Teams asked: `team` is `workspace/slug`, `notified` who is told, `assigned` who review assignment picked. */
257 teams?: TeamRequested[];
258 /** Asked because they own files it changes (its CODEOWNERS file). */
259 codeOwners?: boolean;
260 };
261 "pull.review_request_removed": {
262 pullId: string;
263 repoId: string;
264 number: number;
265 issue?: number;
266 reviewers?: string[];
267 teams?: TeamRequested[];
268 };
Events: review requests, assignments, stops and deployments are published269 /** g1t stopped seeing a pull request through until a person steps in; `detail` says why. */
270 "pull.stalled": { pullId: string; repoId: string; number: number; issue?: number; detail: string };
271 /** A pull request g1t had stopped on is going again. */
272 "pull.resumed": { pullId: string; repoId: string; number: number; issue?: number };
Agents and memory, checks and conflicts, profiles, slug renames, custom domains273 /**
274 * The pull request's head or its target moved and the files both changed
275 * overlap: a sandbox should find out whether it still merges cleanly.
276 * `commit` is its head.
277 */
278 "pull.mergecheck": { pullId: string; repoId: string; number: number; issue?: number; commit: string };
279 /** Whether the pull request merges cleanly was settled. */
280 "pull.mergeability": { pullId: string; repoId: string; number: number; issue?: number };
Agents asked while not at work are woken to answer281 /** Another agent asked the agent on a pull request, which was not at work, a question or handed it work. */
282 "agent.asked": { pullId: string; repoId: string; number: number; issue?: number };
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step283 "pull.merged": { pullId: string; repoId: string; number: number; issue?: number; commit: string; confidence?: Confidence };
Get started on mission control284 /** A run of the acceptance checks finished. `commit` is what was checked. */
285 "checks.completed": {
286 pullId: string;
287 repoId: string;
288 number: number;
289 status: "passed" | "failed" | "errored";
290 commit: string;
291 };
Merge checks: statuses and check runs on every commit292 /** A status was set on a commit through the API. */
293 "status.created": StatusEventData;
294 /** A check run was reported on a commit through the API, completed, asked to run again, or had one of its buttons pressed (`requestedAction`). */
295 "check_run.created": CheckRunEventData;
296 "check_run.completed": CheckRunEventData;
297 "check_run.rerequested": CheckRunEventData;
298 "check_run.requested_action": CheckRunEventData;
299 /** A reporter's check runs on a commit all completed, or it was asked to run them again. */
300 "check_suite.completed": CheckSuiteEventData;
301 "check_suite.rerequested": CheckSuiteEventData;
Get started on mission control302 /** A g1t agent finished reviewing a pull request; no verdict if it could not. */
303 "review.completed": {
304 pullId: string;
305 repoId: string;
306 number: number;
307 verdict?: "approve" | "request_changes";
308 };
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look309 /** A person was given a role on one repository directly, had it changed, or lost it. `role` is null once removed. */
310 "repo.collaborator_added": RepoCollaboratorData;
311 "repo.collaborator_removed": RepoCollaboratorData;
312 "repo.collaborator_role_changed": RepoCollaboratorData;
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar313 /** A team of a workspace was created, changed (`changes` says what) or deleted. */
314 "team.created": TeamChangedData;
315 "team.edited": TeamChangedData;
316 "team.deleted": TeamChangedData;
317 /** Someone joined a team, had their role in it changed, or left it. */
318 "team.member_added": TeamChangedData;
319 "team.member_role_changed": TeamChangedData;
320 "team.member_removed": TeamChangedData;
321 /** A team was given a role on a repository, had it changed, or lost it. */
322 "team.repo_added": TeamChangedData;
323 "team.repo_role_changed": TeamChangedData;
324 "team.repo_removed": TeamChangedData;
Get started on mission control325 /** A repository's merge queue gained, lost or settled an entry. */
326 "queue.changed": { repoId: string };
327 /** `number` is the issue or pull request commented on. */
328 "comment.created": {
329 commentId: string;
330 repoId: string;
331 number: number;
332 /** Set when the comment is on a pull request. */
333 pullId?: string;
334 /** Set when the comment is a review. */
335 verdict?: Verdict;
Cards you act on in chat; agents comment and review as themselves; names shown cleanly; commits on the calendar336 /**
337 * Set when one of the workspace's agents wrote it, as itself; the
338 * event's actor is then the person it acted for (`actingFor`).
339 */
340 agent?: AgentRef;
341 actingFor?: { id: string; username: string };
342 /** An agent's review: its verdict is advisory and counts toward nothing. */
343 advisory?: boolean;
Get started on mission control344 };
Merge Actions: cross-repo workflows and actions, release and deployment triggers, step timeouts345 /** A comment's text changed; `changes.body.from` is what it said before. */
346 "comment.edited": {
347 commentId: string;
348 repoId: string;
349 number: number;
350 /** Set when the comment is on a pull request. */
351 pullId?: string;
352 changes: { body: { from: string } };
353 };
354 /** A comment was deleted; `comment` is the comment as it was. */
355 "comment.deleted": {
356 commentId: string;
357 repoId: string;
358 number: number;
359 /** Set when the comment was on a pull request. */
360 pullId?: string;
361 comment: {
362 id: string;
363 body: string;
364 author: { id: string; username: string };
365 createdAt: string;
366 path: string | null;
367 line: number | null;
368 };
369 };
Get started on mission control370 "session.appended": { pullId: string; repoId: string; number: number; count: number };
Agents and memory, checks and conflicts, profiles, slug renames, custom domains371 /**
Events: review requests, assignments, stops and deployments are published372 * A build of a project finished, for production or one pull request's
373 * preview (`number`). `path` is the deployment's page on the site;
374 * `recovered`, on a success, says the build before it failed.
375 */
376 "deployment.succeeded": DeploymentEventData;
377 "deployment.failed": DeploymentEventData;
378 /**
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97379 * A deployment was made, wherever it runs: reported through the API, by
380 * a g1t Actions job with an `environment:`, or a g1t.page build. Its
381 * `payload` is left out: read the deployment for it.
382 */
Merge Actions: cross-repo workflows and actions, release and deployment triggers, step timeouts383 "deployment.created": { repoId: string; deployment: Omit<RepoDeployment, "payload">; causedByJob?: string };
384 /**
385 * A deployment has a new status; `deployment` is as it is now.
386 * `causedByJob` (as on every event a workflow job's token causes) is the
387 * run whose job made it, so no workflow starts for it.
388 */
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97389 "deployment_status.created": {
390 repoId: string;
391 deployment: Omit<RepoDeployment, "payload">;
392 deploymentStatus: DeploymentStatus;
Merge Actions: cross-repo workflows and actions, release and deployment triggers, step timeouts393 causedByJob?: string;
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97394 };
395 /**
Merge Actions: cross-repo workflows and actions, release and deployment triggers, step timeouts396 * A release changed, one event per GitHub release activity it amounts
397 * to: made (`created`; a published one is also `published`, and
398 * `released` or `prereleased`), a draft published, edited, made a draft
399 * again (`unpublished`) or deleted. `release` is as it is now (as it was,
400 * for `release.deleted`).
401 */
402 "release.created": ReleaseEventData;
403 "release.published": ReleaseEventData;
404 "release.released": ReleaseEventData;
405 "release.prereleased": ReleaseEventData;
406 "release.edited": ReleaseEventData;
407 "release.unpublished": ReleaseEventData;
408 "release.deleted": ReleaseEventData;
409 /**
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member410 * A package version was published, such as an image pushed by
411 * `docker push`. `tags` are the tags that now point to it; `repoId` (and
412 * the event's) is the repository the package is linked to, if any.
413 */
414 "package.published": PackageEventData & { version: string; digest: string; size: number; tags: string[] };
415 /** One version of a package was deleted, with the tags that pointed to it. */
416 "package.version_deleted": PackageEventData & { version: string; digest: string };
417 /** A package was deleted with every version it had. */
418 "package.deleted": PackageEventData;
419 /** A package became public or private. */
420 "package.visibility_changed": PackageEventData & { visibility: "public" | "private" };
421 /**
Agents and memory, checks and conflicts, profiles, slug renames, custom domains422 * A workspace's slug changed from `from` to `to`. Services that store a
423 * slug move their rows to the workspace's *current* slug (see
424 * `currentWorkspaceSlug`), so a repeated or late delivery after a second
425 * rename still lands in the right place.
426 */
427 "workspace.renamed": { workspaceId: string; from: string; to: string };
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API428 /**
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look429 * A repository moved from workspace `from` to `to`, keeping its id and
430 * name. Services that store its path or its workspace's slug move those
431 * rows to its *current* path (ask repos `path_by_id`), so a repeated or
432 * late delivery after a second transfer still lands in the right place.
433 */
434 "repo.transferred": { repoId: string; name: string; from: string; to: string };
435 /**
436 * A workspace is gone. Services drop what they keep for it alone; ledgers,
437 * invoices and the audit log stay under its slug, which is never reused.
438 */
439 "workspace.deleted": { workspaceId: string; slug: string };
440 /**
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member441 * An owner deleted a workspace; staff can restore it until `purgeAfter`,
442 * and nobody can reach it meanwhile. Services hide what they keep for it
443 * and stop what runs for it, keeping their rows: repos deletes its
444 * repositories softly (`repo.deleted` with `withWorkspace`), deployments
445 * pauses its apps, search drops it. `workspace.restored` undoes exactly
446 * that; `workspace.deleted` follows once `purgeAfter` passes. `by` is the
447 * owner's username.
448 */
449 "workspace.deleting": { workspaceId: string; slug: string; by: string; purgeAfter: string };
450 /**
451 * Staff brought a deleted workspace back with its members and tokens.
452 * Services undo what they did on `workspace.deleting`, and only that.
453 */
454 "workspace.restored": { workspaceId: string; slug: string };
455 /**
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API456 * A memory was added, changed, reviewed or forgotten. No text: ask the
457 * work service for it by id. `repoId` is the project's, or null for the
458 * workspace's memory. `status` is `deleted` once forgotten.
459 */
460 "memory.changed": { memoryId: string; workspace: string; status: "candidate" | "kept" | "dismissed" | "deleted" };
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look461 /**
462 * A sandbox was stopped because it looked like it was mining: CPU pinned
463 * with little I/O and no progress, or a miner seen by name. For g1t's
464 * staff, in sudo; published with no `repoId` so it never reaches a
465 * repository's timeline or webhooks. `metrics` is what the sandbox
466 * measured (`Verdict` in crates/runner abuse.rs), or null if it could
467 * not say.
468 */
469 "abuse.flagged": {
470 workspace: string;
471 repo: string | null;
472 /** The agent run, when the sandbox had one. */
473 run: string | null;
474 /** What the sandbox was for: agent, checks, queue, actions, deploy... */
475 kind: string;
476 sandbox: string;
477 metrics: Record<string, unknown> | null;
478 };
Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store479 /**
480 * Docs (services/docs): a page was made. Published with no `repoId`, so
481 * a page (which may be in a private space) never reaches a repository's
482 * timeline or webhooks; `actor` is the user's or agent's id. Readers
483 * check access with the docs service before showing anything of it.
484 */
485 "doc.page.created": DocPageEventData;
486 /**
487 * A page's content changed: at most once per page every ten minutes of
488 * editing (when its history records a version), and for every agent
489 * edit, accepted suggestion and restore. `authors` are member keys
490 * (`user:<id>`, `agent:<id>`) of everyone whose changes are in it.
491 */
492 "doc.page.updated": DocPageEventData & { versionId: string; kind: "edit" | "agent" | "suggestion" | "restore"; authors: string[] };
493 /** A page went to the trash (with every page under it; one event for the page asked about). */
494 "doc.page.archived": DocPageEventData;
495 /**
496 * A page became possibly out of date: a merged pull request or a push to
497 * a repository's default branch changed code it cites. `repoId` is in
498 * `data`, not on the event, for the same reason as above. `owners` are
499 * member keys; an agent that owns the page can update it
500 * (`stalePagesForAgent` in docs.ts).
501 */
502 "doc.page.stale": DocPageEventData & { repoId: string; repo: string; commit: string; pull: number | null; paths: string[]; owners: string[] };
Artifacts contracts: folios, their four kinds, dashboard datasets, folio events and the artifacts scopes are typed and validated the same in TypeScript and Rust, with nothing using them yet503 /**
504 * Artifacts (folios, services/docs): a folio was made. Like `doc.page.*`,
505 * published with no `repoId`, never offered to webhooks, and readers check
The artifacts plan records what Phase 1 decided, self-hosting and the deploy list name the g1t-folios index and the trash cron, and folio events are listed as published but never offered to webhooks.506 * access with the docs service before showing anything of it.
Artifacts contracts: folios, their four kinds, dashboard datasets, folio events and the artifacts scopes are typed and validated the same in TypeScript and Rust, with nothing using them yet507 */
508 "folio.created": FolioEventData;
509 /** A folio's content changed: a version (`versionKind`) with everyone whose changes are in it. */
510 "folio.updated": FolioEventData & { versionId: string; versionKind: "edit" | "agent" | "suggestion" | "proposal" | "restore"; authors: string[] };
511 /** A folio went to the trash (with everything under it; one event for the folio asked about). */
512 "folio.trashed": FolioEventData;
513 "folio.restored": FolioEventData;
514 /** Someone was given access: who (member keys) and the role. Never content. */
515 "folio.shared": FolioEventData & { principals: string[]; role: "view" | "comment" | "edit" | "manage" };
516 /** Code a folio cites changed. The repository is in `data` as `owner/name` only. */
517 "folio.stale": FolioEventData & { repo: string; commit: string; pull: number | null; paths: string[]; owners: string[] };
518};
519
520/**
521 * What every `folio.*` event carries. `title` is null unless every member
522 * of the workspace can read the folio, so a private folio's name never
523 * travels.
524 */
525export type FolioEventData = {
526 workspace: string;
527 workspaceId: string;
528 folioId: string;
529 kind: "doc" | "slides" | "design" | "dashboard";
530 spaceId: string | null;
531 title: string | null;
Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store532};
533
534/** What every `doc.page.*` event carries. */
535export type DocPageEventData = {
536 workspace: string;
537 workspaceId: string;
538 pageId: string;
539 spaceId: string;
540 title: string;
541 /** The page's address on the site. */
542 path: string;
Get started on mission control543};
544
545export type EventType = keyof EventPayloads;
546
547export type G1tEvent<T extends EventType = EventType> = {
548 [K in T]: {
549 id: string;
550 type: K;
551 /** The service that published it. */
552 source: string;
553 /** RFC 3339. */
554 time: string;
555 /** The repo the event concerns, used to scope timelines and deliveries. */
556 repoId: string | null;
557 /** The user or agent that caused it, if any. */
558 actor: string | null;
559 data: EventPayloads[K];
560 };
561}[T];
562
563/** What a publisher supplies; the bus fills in `id` and `time`. */
564export type NewEvent<T extends EventType = EventType> = {
565 [K in T]: Omit<G1tEvent<K>, "id" | "time">;
566}[T];
567
568export type EventQuery = {
569 repoId?: string;
570 types?: EventType[];
571 /** Return events older than this event id. */
572 before?: string;
Merge leftovers: plan activity filtered in the query, pushes counted by account, ghost during the deletion window, profile time zones (identity 0039)573 /** Only events by this account id. */
574 actor?: string;
575 /** Only events about these issues or pull requests (`number`, or the `issue` a comment or review is on). */
576 numbers?: number[];
577 /** Only events at or after this RFC 3339 time. */
578 since?: string;
Get started on mission control579 limit?: number;
580};
581
582/** The event bus and its durable log. */
583export interface EventsApi {
584 publish(events: NewEvent[]): Promise<void>;
585 /** Newest first. */
586 list(query: EventQuery): Promise<G1tEvent[]>;
587}

This file's history is long; its oldest lines are credited to the oldest commit read.