Skip to content
679 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.

Deployments work end to end: fixes from the first live run1/**
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 workflows.
5 *
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
Deployments work end to end: fixes from the first live run87export 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 /**
Deployments work end to end: fixes from the first live run178 * 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;
Home says what people did as well as what agents did. Since you were last here now has a People column and an Agents column: who pushed how many commits to which projects, pull requests opened, merged and reviewed, issues opened and closed, docs edited, messages sent and deploys that went out, each line a link to where those are listed, with the agents' acceptance (first time, after review, didn't finish) kept as a row of their column; the sentence under the heading sums it up honestly, and says when a part of g1t could not be read, or that the span was quiet. Landed counts merged pull requests, commits pushed straight to a default branch, production deploys that went live, releases and packages, newest first; Running now adds workflow runs. Behind it, the events service answers an activity digest over a span in one round trip from its existing indexes, every push now records how many commits it carried, and chat counts the messages sent in the conversations you can read. The Home guide defines every line, and says how this scales.196 /**
197 * How many commits the push brought to the branch, along its
198 * first-parent line from `after` back to `before` (a merge commit is
199 * one), at most 50; one for a new branch. Absent when it was not
200 * counted: a tag, a branch deleted, a pull request landed, a push the
201 * store could not read back, or one from before this was recorded.
202 */
203 commits?: number;
Merge branch 'mirroring' into artifacts-mode204 };
Merge leftovers: plan activity filtered in the query, pushes counted by account, ghost during the deletion window, profile time zones (identity 0039)205 /**
g1t is the stored author of what it opens; the person who asked is requested_by and keeps the author's rights206 * `author` is who opened it: g1t, for one its agent filed while at work,
207 * with `requestedBy` the person it was working for. Every issue and pull
208 * request event carries both.
209 */
210 "issue.opened": {
211 issueId: string;
212 repoId: string;
213 number: number;
214 title: string;
215 author?: { id: string; username: string };
216 requestedBy?: { id: string; username: string };
217 };
Deployments work end to end: fixes from the first live run218 "issue.updated": { issueId: string; repoId: string; number: number };
Events: review requests, assignments, stops and deployments are published219 /** The people an issue is assigned to changed; `assignees` is the new set, `added` those newly assigned. */
220 "issue.assigned": { issueId: string; repoId: string; number: number; assignees: string[]; added?: string[] };
Deployments work end to end: fixes from the first live run221 /** `resolvedBy` is the number of the pull request whose merge closed it. */
222 "issue.closed": {
223 issueId: string;
224 repoId: string;
225 number: number;
226 reason: "completed" | "not_planned";
227 resolvedBy?: number;
228 };
229 "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 rights230 /**
231 * `issue` is the number of the issue the pull request is for. `author` is
232 * who opened it: g1t, for a change g1t made, with `requestedBy` the person
233 * who asked for it.
234 */
235 "pull.opened": {
236 pullId: string;
237 repoId: string;
238 number: number;
239 issue?: number;
240 agent: string;
241 author?: { id: string; username: string };
242 requestedBy?: { id: string; username: string };
243 };
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step244 /** `confidence`, on a g1t agent's change once g1t has worked it out, is on every pull request event. */
245 "pull.ready": { pullId: string; repoId: string; number: number; issue?: number; confidence?: Confidence };
Deployments work end to end: fixes from the first live run246 /** 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 step247 "pull.updated": { pullId: string; repoId: string; number: number; issue?: number; commit: string; confidence?: Confidence };
Deployments work end to end: fixes from the first live run248 /** 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 step249 "pull.merge_requested": { pullId: string; repoId: string; number: number; issue?: number; confidence?: Confidence };
250 "pull.closed": { pullId: string; repoId: string; number: number; issue?: number; confidence?: Confidence };
Merge Actions: cross-repo workflows and actions, release and deployment triggers, step timeouts251 /** A closed pull request was opened again. `commit` is its head. */
252 "pull.reopened": { pullId: string; repoId: string; number: number; issue?: number; commit?: string; confidence?: Confidence };
253 /** A pull request that was ready for review was turned back into a draft. */
254 "pull.converted_to_draft": { pullId: string; repoId: string; number: number; issue?: number; confidence?: Confidence };
Events: review requests, assignments, stops and deployments are published255 /** People were assigned to a pull request: `assignees` is the new set, `added` those newly assigned. */
256 "pull.assigned": { pullId: string; repoId: string; number: number; issue?: number; assignees: string[]; added: string[] };
257 /** 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 bar258 "pull.review_requested": {
259 pullId: string;
260 repoId: string;
261 number: number;
262 issue?: number;
263 reviewers?: string[];
264 /** Teams asked: `team` is `workspace/slug`, `notified` who is told, `assigned` who review assignment picked. */
265 teams?: TeamRequested[];
266 /** Asked because they own files it changes (its CODEOWNERS file). */
267 codeOwners?: boolean;
268 };
269 "pull.review_request_removed": {
270 pullId: string;
271 repoId: string;
272 number: number;
273 issue?: number;
274 reviewers?: string[];
275 teams?: TeamRequested[];
276 };
Events: review requests, assignments, stops and deployments are published277 /** g1t stopped seeing a pull request through until a person steps in; `detail` says why. */
278 "pull.stalled": { pullId: string; repoId: string; number: number; issue?: number; detail: string };
279 /** A pull request g1t had stopped on is going again. */
280 "pull.resumed": { pullId: string; repoId: string; number: number; issue?: number };
Agents and memory, checks and conflicts, profiles, slug renames, custom domains281 /**
282 * The pull request's head or its target moved and the files both changed
283 * overlap: a sandbox should find out whether it still merges cleanly.
284 * `commit` is its head.
285 */
286 "pull.mergecheck": { pullId: string; repoId: string; number: number; issue?: number; commit: string };
287 /** Whether the pull request merges cleanly was settled. */
288 "pull.mergeability": { pullId: string; repoId: string; number: number; issue?: number };
Deployments work end to end: fixes from the first live run289 /** Another agent asked the agent on a pull request, which was not at work, a question or handed it work. */
290 "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 step291 "pull.merged": { pullId: string; repoId: string; number: number; issue?: number; commit: string; confidence?: Confidence };
Deployments work end to end: fixes from the first live run292 /** A run of the acceptance checks finished. `commit` is what was checked. */
293 "checks.completed": {
294 pullId: string;
295 repoId: string;
296 number: number;
297 status: "passed" | "failed" | "errored";
298 commit: string;
299 };
Merge checks: statuses and check runs on every commit300 /** A status was set on a commit through the API. */
301 "status.created": StatusEventData;
302 /** A check run was reported on a commit through the API, completed, asked to run again, or had one of its buttons pressed (`requestedAction`). */
303 "check_run.created": CheckRunEventData;
304 "check_run.completed": CheckRunEventData;
305 "check_run.rerequested": CheckRunEventData;
306 "check_run.requested_action": CheckRunEventData;
307 /** A reporter's check runs on a commit all completed, or it was asked to run them again. */
308 "check_suite.completed": CheckSuiteEventData;
309 "check_suite.rerequested": CheckSuiteEventData;
Deployments work end to end: fixes from the first live run310 /** A g1t agent finished reviewing a pull request; no verdict if it could not. */
311 "review.completed": {
312 pullId: string;
313 repoId: string;
314 number: number;
315 verdict?: "approve" | "request_changes";
316 };
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look317 /** A person was given a role on one repository directly, had it changed, or lost it. `role` is null once removed. */
318 "repo.collaborator_added": RepoCollaboratorData;
319 "repo.collaborator_removed": RepoCollaboratorData;
320 "repo.collaborator_role_changed": RepoCollaboratorData;
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar321 /** A team of a workspace was created, changed (`changes` says what) or deleted. */
322 "team.created": TeamChangedData;
323 "team.edited": TeamChangedData;
324 "team.deleted": TeamChangedData;
325 /** Someone joined a team, had their role in it changed, or left it. */
326 "team.member_added": TeamChangedData;
327 "team.member_role_changed": TeamChangedData;
328 "team.member_removed": TeamChangedData;
329 /** A team was given a role on a repository, had it changed, or lost it. */
330 "team.repo_added": TeamChangedData;
331 "team.repo_role_changed": TeamChangedData;
332 "team.repo_removed": TeamChangedData;
Deployments work end to end: fixes from the first live run333 /** A repository's merge queue gained, lost or settled an entry. */
334 "queue.changed": { repoId: string };
335 /** `number` is the issue or pull request commented on. */
336 "comment.created": {
337 commentId: string;
338 repoId: string;
339 number: number;
340 /** Set when the comment is on a pull request. */
341 pullId?: string;
342 /** Set when the comment is a review. */
343 verdict?: Verdict;
Cards you act on in chat; agents comment and review as themselves; names shown cleanly; commits on the calendar344 /**
345 * Set when one of the workspace's agents wrote it, as itself; the
346 * event's actor is then the person it acted for (`actingFor`).
347 */
348 agent?: AgentRef;
349 actingFor?: { id: string; username: string };
350 /** An agent's review: its verdict is advisory and counts toward nothing. */
351 advisory?: boolean;
Deployments work end to end: fixes from the first live run352 };
Merge Actions: cross-repo workflows and actions, release and deployment triggers, step timeouts353 /** A comment's text changed; `changes.body.from` is what it said before. */
354 "comment.edited": {
355 commentId: string;
356 repoId: string;
357 number: number;
358 /** Set when the comment is on a pull request. */
359 pullId?: string;
360 changes: { body: { from: string } };
361 };
362 /** A comment was deleted; `comment` is the comment as it was. */
363 "comment.deleted": {
364 commentId: string;
365 repoId: string;
366 number: number;
367 /** Set when the comment was on a pull request. */
368 pullId?: string;
369 comment: {
370 id: string;
371 body: string;
372 author: { id: string; username: string };
373 createdAt: string;
374 path: string | null;
375 line: number | null;
376 };
377 };
Deployments work end to end: fixes from the first live run378 "session.appended": { pullId: string; repoId: string; number: number; count: number };
Agents and memory, checks and conflicts, profiles, slug renames, custom domains379 /**
Events: review requests, assignments, stops and deployments are published380 * A build of a project finished, for production or one pull request's
381 * preview (`number`). `path` is the deployment's page on the site;
382 * `recovered`, on a success, says the build before it failed.
383 */
384 "deployment.succeeded": DeploymentEventData;
385 "deployment.failed": DeploymentEventData;
386 /**
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97387 * A deployment was made, wherever it runs: reported through the API, by
388 * a g1t Actions job with an `environment:`, or a g1t.page build. Its
389 * `payload` is left out: read the deployment for it.
390 */
Merge Actions: cross-repo workflows and actions, release and deployment triggers, step timeouts391 "deployment.created": { repoId: string; deployment: Omit<RepoDeployment, "payload">; causedByJob?: string };
392 /**
393 * A deployment has a new status; `deployment` is as it is now.
394 * `causedByJob` (as on every event a workflow job's token causes) is the
395 * run whose job made it, so no workflow starts for it.
396 */
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97397 "deployment_status.created": {
398 repoId: string;
399 deployment: Omit<RepoDeployment, "payload">;
400 deploymentStatus: DeploymentStatus;
Merge Actions: cross-repo workflows and actions, release and deployment triggers, step timeouts401 causedByJob?: string;
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97402 };
403 /**
Merge Actions: cross-repo workflows and actions, release and deployment triggers, step timeouts404 * A release changed, one event per GitHub release activity it amounts
405 * to: made (`created`; a published one is also `published`, and
406 * `released` or `prereleased`), a draft published, edited, made a draft
407 * again (`unpublished`) or deleted. `release` is as it is now (as it was,
408 * for `release.deleted`).
409 */
410 "release.created": ReleaseEventData;
411 "release.published": ReleaseEventData;
412 "release.released": ReleaseEventData;
413 "release.prereleased": ReleaseEventData;
414 "release.edited": ReleaseEventData;
415 "release.unpublished": ReleaseEventData;
416 "release.deleted": ReleaseEventData;
417 /**
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member418 * A package version was published, such as an image pushed by
419 * `docker push`. `tags` are the tags that now point to it; `repoId` (and
420 * the event's) is the repository the package is linked to, if any.
421 */
422 "package.published": PackageEventData & { version: string; digest: string; size: number; tags: string[] };
423 /** One version of a package was deleted, with the tags that pointed to it. */
424 "package.version_deleted": PackageEventData & { version: string; digest: string };
425 /** A package was deleted with every version it had. */
426 "package.deleted": PackageEventData;
427 /** A package became public or private. */
428 "package.visibility_changed": PackageEventData & { visibility: "public" | "private" };
429 /**
Agents and memory, checks and conflicts, profiles, slug renames, custom domains430 * A workspace's slug changed from `from` to `to`. Services that store a
431 * slug move their rows to the workspace's *current* slug (see
432 * `currentWorkspaceSlug`), so a repeated or late delivery after a second
433 * rename still lands in the right place.
434 */
435 "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 API436 /**
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look437 * A repository moved from workspace `from` to `to`, keeping its id and
438 * name. Services that store its path or its workspace's slug move those
439 * rows to its *current* path (ask repos `path_by_id`), so a repeated or
440 * late delivery after a second transfer still lands in the right place.
441 */
442 "repo.transferred": { repoId: string; name: string; from: string; to: string };
443 /**
444 * A workspace is gone. Services drop what they keep for it alone; ledgers,
445 * invoices and the audit log stay under its slug, which is never reused.
446 */
447 "workspace.deleted": { workspaceId: string; slug: string };
448 /**
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member449 * An owner deleted a workspace; staff can restore it until `purgeAfter`,
450 * and nobody can reach it meanwhile. Services hide what they keep for it
451 * and stop what runs for it, keeping their rows: repos deletes its
452 * repositories softly (`repo.deleted` with `withWorkspace`), deployments
453 * pauses its apps, search drops it. `workspace.restored` undoes exactly
454 * that; `workspace.deleted` follows once `purgeAfter` passes. `by` is the
455 * owner's username.
456 */
457 "workspace.deleting": { workspaceId: string; slug: string; by: string; purgeAfter: string };
458 /**
459 * Staff brought a deleted workspace back with its members and tokens.
460 * Services undo what they did on `workspace.deleting`, and only that.
461 */
462 "workspace.restored": { workspaceId: string; slug: string };
463 /**
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API464 * A memory was added, changed, reviewed or forgotten. No text: ask the
465 * work service for it by id. `repoId` is the project's, or null for the
466 * workspace's memory. `status` is `deleted` once forgotten.
467 */
468 "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 look469 /**
470 * A sandbox was stopped because it looked like it was mining: CPU pinned
471 * with little I/O and no progress, or a miner seen by name. For g1t's
472 * staff, in sudo; published with no `repoId` so it never reaches a
473 * repository's timeline or webhooks. `metrics` is what the sandbox
474 * measured (`Verdict` in crates/runner abuse.rs), or null if it could
475 * not say.
476 */
477 "abuse.flagged": {
478 workspace: string;
479 repo: string | null;
480 /** The agent run, when the sandbox had one. */
481 run: string | null;
482 /** What the sandbox was for: agent, checks, queue, actions, deploy... */
483 kind: string;
484 sandbox: string;
485 metrics: Record<string, unknown> | null;
486 };
Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store487 /**
The artifacts service is services/artifacts, the Worker g1t-artifacts, bound as ARTIFACTS by the API, the site and the agents; its live rooms move to it with a Durable Object transfer from g1t-docs-service, and its database, bucket, indexes and queue keep their names. The git store's binding and settings are GITSTORE, its ops scripts gitstore-*, and workflow run artifacts keep their compatible API under run_artifacts modules. The deploy tool puts a Worker that has never deployed before the Workers in its stage that bind to it, and the deploy guide gives the cutover runbook.488 * Docs (services/artifacts): a page was made. Published with no `repoId`, so
Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store489 * a page (which may be in a private space) never reaches a repository's
490 * timeline or webhooks; `actor` is the user's or agent's id. Readers
The artifacts service is services/artifacts, the Worker g1t-artifacts, bound as ARTIFACTS by the API, the site and the agents; its live rooms move to it with a Durable Object transfer from g1t-docs-service, and its database, bucket, indexes and queue keep their names. The git store's binding and settings are GITSTORE, its ops scripts gitstore-*, and workflow run artifacts keep their compatible API under run_artifacts modules. The deploy tool puts a Worker that has never deployed before the Workers in its stage that bind to it, and the deploy guide gives the cutover runbook.491 * check access with the artifacts service before showing anything of it.
Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store492 */
493 "doc.page.created": DocPageEventData;
494 /**
495 * A page's content changed: at most once per page every ten minutes of
496 * editing (when its history records a version), and for every agent
497 * edit, accepted suggestion and restore. `authors` are member keys
498 * (`user:<id>`, `agent:<id>`) of everyone whose changes are in it.
499 */
500 "doc.page.updated": DocPageEventData & { versionId: string; kind: "edit" | "agent" | "suggestion" | "restore"; authors: string[] };
501 /** A page went to the trash (with every page under it; one event for the page asked about). */
502 "doc.page.archived": DocPageEventData;
503 /**
504 * A page became possibly out of date: a merged pull request or a push to
505 * a repository's default branch changed code it cites. `repoId` is in
506 * `data`, not on the event, for the same reason as above. `owners` are
507 * member keys; an agent that owns the page can update it
508 * (`stalePagesForAgent` in docs.ts).
509 */
510 "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 yet511 /**
The artifacts service is services/artifacts, the Worker g1t-artifacts, bound as ARTIFACTS by the API, the site and the agents; its live rooms move to it with a Durable Object transfer from g1t-docs-service, and its database, bucket, indexes and queue keep their names. The git store's binding and settings are GITSTORE, its ops scripts gitstore-*, and workflow run artifacts keep their compatible API under run_artifacts modules. The deploy tool puts a Worker that has never deployed before the Workers in its stage that bind to it, and the deploy guide gives the cutover runbook.512 * Artifacts (folios, services/artifacts): a folio was made. Like `doc.page.*`,
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 yet513 * published with no `repoId`, never offered to webhooks, and readers check
The artifacts service is services/artifacts, the Worker g1t-artifacts, bound as ARTIFACTS by the API, the site and the agents; its live rooms move to it with a Durable Object transfer from g1t-docs-service, and its database, bucket, indexes and queue keep their names. The git store's binding and settings are GITSTORE, its ops scripts gitstore-*, and workflow run artifacts keep their compatible API under run_artifacts modules. The deploy tool puts a Worker that has never deployed before the Workers in its stage that bind to it, and the deploy guide gives the cutover runbook.514 * access with the artifacts 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 yet515 */
516 "folio.created": FolioEventData;
517 /** A folio's content changed: a version (`versionKind`) with everyone whose changes are in it. */
518 "folio.updated": FolioEventData & { versionId: string; versionKind: "edit" | "agent" | "suggestion" | "proposal" | "restore"; authors: string[] };
519 /** A folio went to the trash (with everything under it; one event for the folio asked about). */
520 "folio.trashed": FolioEventData;
521 "folio.restored": FolioEventData;
522 /** Someone was given access: who (member keys) and the role. Never content. */
523 "folio.shared": FolioEventData & { principals: string[]; role: "view" | "comment" | "edit" | "manage" };
524 /** Code a folio cites changed. The repository is in `data` as `owner/name` only. */
525 "folio.stale": FolioEventData & { repo: string; commit: string; pull: number | null; paths: string[]; owners: string[] };
526};
527
528/**
529 * What every `folio.*` event carries. `title` is null unless every member
530 * of the workspace can read the folio, so a private folio's name never
531 * travels.
532 */
533export type FolioEventData = {
534 workspace: string;
535 workspaceId: string;
536 folioId: string;
537 kind: "doc" | "slides" | "design" | "dashboard";
538 spaceId: string | null;
539 title: string | null;
Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store540};
541
542/** What every `doc.page.*` event carries. */
543export type DocPageEventData = {
544 workspace: string;
545 workspaceId: string;
546 pageId: string;
547 spaceId: string;
548 title: string;
549 /** The page's address on the site. */
550 path: string;
Deployments work end to end: fixes from the first live run551};
552
553export type EventType = keyof EventPayloads;
554
555export type G1tEvent<T extends EventType = EventType> = {
556 [K in T]: {
557 id: string;
558 type: K;
559 /** The service that published it. */
560 source: string;
561 /** RFC 3339. */
562 time: string;
563 /** The repo the event concerns, used to scope timelines and deliveries. */
564 repoId: string | null;
565 /** The user or agent that caused it, if any. */
566 actor: string | null;
567 data: EventPayloads[K];
568 };
569}[T];
570
571/** What a publisher supplies; the bus fills in `id` and `time`. */
572export type NewEvent<T extends EventType = EventType> = {
573 [K in T]: Omit<G1tEvent<K>, "id" | "time">;
574}[T];
575
576export type EventQuery = {
577 repoId?: string;
578 types?: EventType[];
579 /** Return events older than this event id. */
580 before?: string;
Merge leftovers: plan activity filtered in the query, pushes counted by account, ghost during the deletion window, profile time zones (identity 0039)581 /** Only events by this account id. */
582 actor?: string;
583 /** Only events about these issues or pull requests (`number`, or the `issue` a comment or review is on). */
584 numbers?: number[];
585 /** Only events at or after this RFC 3339 time. */
586 since?: string;
Deployments work end to end: fixes from the first live run587 limit?: number;
588};
589
Home says what people did as well as what agents did. Since you were last here now has a People column and an Agents column: who pushed how many commits to which projects, pull requests opened, merged and reviewed, issues opened and closed, docs edited, messages sent and deploys that went out, each line a link to where those are listed, with the agents' acceptance (first time, after review, didn't finish) kept as a row of their column; the sentence under the heading sums it up honestly, and says when a part of g1t could not be read, or that the span was quiet. Landed counts merged pull requests, commits pushed straight to a default branch, production deploys that went live, releases and packages, newest first; Running now adds workflow runs. Behind it, the events service answers an activity digest over a span in one round trip from its existing indexes, every push now records how many commits it carried, and chat counts the messages sent in the conversations you can read. The Home guide defines every line, and says how this scales.590/**
591 * `activity_digest`: what happened in some repositories, and to a
592 * workspace's artifacts, over `[from, until)`, counted by who did it. Home
593 * reads it for what people and agents did since you were last there.
594 * snake_case, as the Rust service reads it
595 * (`g1t_contracts::events::ActivityDigestArgs`).
596 */
597export type ActivityDigestArgs = {
598 /** By id; the caller has checked the viewer may read each. At most `MAX_DIGEST_REPOS` are read. */
599 repo_ids: string[];
600 /** The workspace's slug, for its `folio.*` events (which carry no repository); null leaves artifacts out. */
601 workspace: string | null;
602 /** RFC 3339, inclusive. */
603 from: string;
604 /** RFC 3339, exclusive. */
605 until: string;
606};
607
608/** The most repositories one digest reads. */
609export const MAX_DIGEST_REPOS = 50;
610
611/**
612 * How many times one actor did something. The actor is a member key:
613 * `user:<id>` for a person (or g1t, `user:usr_g1t_agent`), `agent:<id>` for
614 * one of the workspace's agents acting as itself, or `""` when the event
615 * named nobody (a push copied in by a mirror).
616 */
617export type ActorCount = { actor: string; count: number };
618
619/** Pushes by one actor, with the commits they brought. */
620export type PushesBy = { actor: string; count: number; commits: number };
621
622/** Pushes to a repository's branches (tags are not pushes here). A push whose commits were not counted counts as one commit. */
623export type PushDigest = {
624 count: number;
625 commits: number;
626 /** The branches pushed to, by name, sorted. */
627 branches: string[];
628 /** Most pushes first. */
629 by: PushesBy[];
630 /** Of those, the pushes straight to the default branch: what landed without a pull request. */
631 default_branch: { count: number; commits: number; by: PushesBy[]; last_at: string | null };
632};
633
634export type RepoDigest = {
635 repo_id: string;
636 pushes: PushDigest;
637 /** Pull requests opened, merged and closed without merging, each by who did it. */
638 pulls: { opened: ActorCount[]; merged: ActorCount[]; closed: ActorCount[] };
639 issues: { opened: ActorCount[]; closed: ActorCount[] };
640 /** `review.completed` (g1t's), and a comment with a verdict (a person's). */
641 reviews: ActorCount[];
642 /** Comments without a verdict; one by an agent as itself is the agent's. */
643 comments: ActorCount[];
644 /** Builds that finished, by who set them off; `production` is how many successes were production. */
645 deployments: { succeeded: ActorCount[]; failed: ActorCount[]; production: number };
646 /** Releases published, newest first, at most 50. */
647 releases: { tag: string; name: string | null; actor: string; at: string }[];
648 /** Package versions published, newest first, at most 50. */
649 packages: { ecosystem: string; name: string; version: string; actor: string; at: string }[];
650};
651
652/** A workspace's artifacts over the span. Never a title. */
653export type FolioDigest = {
654 created: ActorCount[];
655 /** Each folio whose content changed, once, with everyone whose changes are in it (member keys); at most 50. */
656 edited: { folio_id: string; kind: "doc" | "slides" | "design" | "dashboard" | string; authors: string[] }[];
657 /** How many folios changed, counting those past the cap. */
658 edited_count: number;
659};
660
661export type ActivityDigest = {
662 from: string;
663 until: string;
664 /** One per repository that had any event counted; none for a quiet one. */
665 repos: RepoDigest[];
666 /** When a workspace was named. */
667 folios: FolioDigest | null;
668 /** False when more events fell in the span than were read, or more repositories were named than are read, so counts are low. */
669 complete: boolean;
670};
671
Deployments work end to end: fixes from the first live run672/** The event bus and its durable log. */
673export interface EventsApi {
674 publish(events: NewEvent[]): Promise<void>;
675 /** Newest first. */
676 list(query: EventQuery): Promise<G1tEvent[]>;
Home says what people did as well as what agents did. Since you were last here now has a People column and an Agents column: who pushed how many commits to which projects, pull requests opened, merged and reviewed, issues opened and closed, docs edited, messages sent and deploys that went out, each line a link to where those are listed, with the agents' acceptance (first time, after review, didn't finish) kept as a row of their column; the sentence under the heading sums it up honestly, and says when a part of g1t could not be read, or that the span was quiet. Landed counts merged pull requests, commits pushed straight to a default branch, production deploys that went live, releases and packages, newest first; Running now adds workflow runs. Behind it, the events service answers an activity digest over a span in one round trip from its existing indexes, every push now records how many commits it carried, and chat counts the messages sent in the conversations you can read. The Home guide defines every line, and says how this scales.677 /** A span of some repositories' and a workspace's artifacts' events, counted by who did it. */
678 activityDigest(args: ActivityDigestArgs): Promise<ActivityDigest>;
Deployments work end to end: fixes from the first live run679}

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