Skip to content
1,389 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.

Merge checks: statuses and check runs on every commit1import type { ChecksApi } from "./checks";
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar2import type { CodeownersReport, PullCodeOwners } from "./codeowners";
Redraw the opening artwork3import type { User, Viewer } from "./identity";
Catching up with main takes seconds when the two sides touched different files4import type { PullBranchUpdate, RepoPath } from "./repos";
Redraw the opening artwork5import type { Result } from "./result";
Merge rulesets: branch and tag rules, agent-first, enforced on push and merge6import type { MergeRules, RulesApi } from "./rules";
Redraw the opening artwork7
8/**
9 * The filter on lists of issues and pull requests. An open pull request is
10 * a draft or one ready for review; a closed one was merged or closed
11 * without merging.
12 */
13export type State = "open" | "closed";
14
15/** Why an issue was closed. */
16export type IssueReason = "completed" | "not_planned";
17
18/**
19 * Something that should change in a repository: a bug, a feature, a
20 * question. Opened by a person, an agent or an integration. Pull requests
21 * are made against it; the one that is merged resolves it.
22 *
23 * Issues and pull requests share one sequence of numbers per repository.
24 */
25export type Issue = {
26 id: string;
27 repoId: string;
28 /** Shown as `#12`. */
29 number: number;
30 title: string;
31 /** Markdown. Also what an agent is given to work from. */
32 body: string;
33 labels: string[];
34 state: State;
35 /** Set when closed. */
36 reason: IssueReason | null;
37 /** The number of the pull request whose merge closed this issue. */
38 resolvedBy: number | null;
g1t is the stored author of what it opens; the person who asked is requested_by and keeps the author's rights39 /** Who opened it: a person, an integration, or g1t (`kind` `agent`) for one its agent filed while at work. */
Redraw the opening artwork40 author: User;
g1t is the stored author of what it opens; the person who asked is requested_by and keeps the author's rights41 /**
42 * For an issue g1t's agent filed: the person it was working for. They may
43 * manage it as its author could. See `workOwner`.
44 */
45 requestedBy: User | null;
Redraw the opening artwork46 /** RFC 3339. */
47 createdAt: string;
48 /** RFC 3339. */
49 updatedAt: string;
50 /** RFC 3339. */
51 closedAt: string | null;
52 /** Pull requests made against this issue, in any state. */
53 pullCount: number;
54 commentCount: number;
55 /** Usernames of the people it is assigned to. */
56 assignees: string[];
57 /** The numbers of the issues that have to be merged before this one is worked on. */
58 blockedBy: number[];
59 /**
60 * Whether a g1t agent takes it as soon as it can: at once, or when what it
61 * is blocked by has merged.
62 */
63 queued: boolean;
64 /**
65 * The agent working on it now: the one behind its newest pull request
g1t is one name: its agent's work, commits and comments show as @g1t, and nobody can claim g1t or g1t-agent66 * that is still in progress in a fork, such as `g1t`.
Redraw the opening artwork67 */
68 agent: string | null;
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar69 /** The milestone it is in, if any. */
70 milestone?: MilestoneRef | null;
Redraw the opening artwork71};
72
g1t is the stored author of what it opens; the person who asked is requested_by and keeps the author's rights73/**
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar74 * A label of a repository: a name, a color and what it means. Issues and
75 * pull requests carry labels by name; names are lowercase.
76 */
77export type Label = {
78 name: string;
79 /** Six hex digits, without `#`. */
80 color: string;
81 description: string;
82 /** How many issues carry it, open or closed. */
83 issues: number;
84 /** How many pull requests carry it, in any state. */
85 pulls: number;
86};
87
88/** A milestone, as an issue or pull request names it. */
89export type MilestoneRef = { number: number; title: string };
90
91/**
92 * A goal, with an optional due date, that issues and pull requests are
93 * gathered under. Its progress is how many of them are closed.
94 */
95export type Milestone = {
96 /** Numbered from 1 in each repository, apart from issues. */
97 number: number;
98 title: string;
99 /** Markdown. */
100 description: string;
101 /** `YYYY-MM-DD`. */
102 dueOn: string | null;
103 state: State;
104 /** Open issues and pull requests in it. */
105 openItems: number;
106 /** Closed issues, and merged or closed pull requests, in it. */
107 closedItems: number;
108 createdAt: string;
109 updatedAt: string;
110 closedAt: string | null;
111};
112
113/** One milestone and what is in it, newest first. */
114export type MilestoneDetail = { milestone: Milestone; issues: Issue[]; pulls: Pull[] };
115
116/** How `setLabels` changes an item's labels. */
117export type LabelChange = "set" | "add" | "remove";
118
119/**
g1t is the stored author of what it opens; the person who asked is requested_by and keeps the author's rights120 * Whose an issue or a pull request is to answer for: whoever asked g1t for
121 * it, or its author. They may change, close and steer it, are never asked to
122 * review it and cannot approve it, and see it as theirs. Mirrors
123 * `Pull::owner` in the Rust contracts.
124 */
125export function workOwner(item: Pick<Pull, "author" | "requestedBy">): User {
126 return item.requestedBy ?? item.author;
127}
128
Redraw the opening artwork129/** `draft` is still being worked on; `open` is ready for review. */
130export type PullStatus = "draft" | "open" | "merged" | "closed";
131
132/** Where the agent runs: on g1t's sandboxes, or in someone's own session. */
133export type Runtime = "hosted" | "external";
134
135/**
136 * A proposed change. It is made either in a fork created for it, which is
137 * how agents work, or on a branch pushed to the repository itself.
138 */
139export type Pull = {
140 id: string;
141 repoId: string;
142 /** Shown as `#12`. */
143 number: number;
144 /** The number of the issue this is for, if any. */
145 issue: number | null;
146 title: string;
147 /** Markdown: what changed and why. Set when marked ready. */
148 body: string | null;
149 /** A label for the agent doing the work, e.g. `claude-code`. */
150 agent: string;
151 runtime: Runtime;
152 status: PullStatus;
153 /** The fork holding the change, unless it is on a branch. */
154 fork: RepoPath | null;
155 /** The fork's repository id. */
156 forkRepoId: string | null;
157 /** The branch of the repository holding the change, unless it is in a fork. */
158 branch: string | null;
159 headCommit: string | null;
160 /**
161 * For a merged pull request, what the branch pointed to before the merge.
162 * Comparing against it shows what the pull request changed.
163 */
164 mergeBase: string | null;
165 /** Username of whoever merged it. */
166 mergedBy: string | null;
167 /** RFC 3339. */
168 mergedAt: string | null;
169 /**
170 * Set on a pull request closed because another one for the same issue was
171 * merged: that one's number.
172 */
173 supersededBy: number | null;
174 /**
175 * Where the latest run of the issue's acceptance checks stands, if there
176 * has been one against the current head.
177 */
178 checkStatus: CheckStatus | null;
179 /** The files it changes, as of its latest push. */
180 files: ChangedFile[];
181 /** Usernames of the people it is assigned to. */
182 assignees: string[];
183 /**
g1t is one name: its agent's work, commits and comments show as @g1t, and nobody can claim g1t or g1t-agent184 * Those whose review was asked for: usernames, and `g1t` when a g1t
Redraw the opening artwork185 * agent was asked.
186 */
187 reviewers: string[];
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar188 /**
189 * Teams whose review was asked for, as `workspace/slug`. A team stays here
190 * after review assignment picks people from it, who are in `reviewers`.
191 */
192 teamReviewers?: string[];
193 /** The labels it carries, by name. */
194 labels?: string[];
195 /** The milestone it is in, if any. */
196 milestone?: MilestoneRef | null;
197 /**
198 * The branch it merges into. Lists and `getPull` name it; null only in
199 * what services pass between themselves, for the default branch.
200 */
201 base?: string | null;
g1t is the stored author of what it opens; the person who asked is requested_by and keeps the author's rights202 /** Who opened it: a person, or g1t (`kind` `agent`, username `g1t`) for a change g1t made. */
Redraw the opening artwork203 author: User;
g1t is the stored author of what it opens; the person who asked is requested_by and keeps the author's rights204 /**
205 * For a change g1t made: the person who asked for it, by assigning an issue
206 * or handing g1t the work. They answer for it as its author would. See
207 * `workOwner`.
208 */
209 requestedBy: User | null;
Redraw the opening artwork210 /** RFC 3339. */
211 createdAt: string;
212 /** RFC 3339. */
213 updatedAt: string;
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step214 /**
215 * How sure g1t is of a g1t agent's change, from what it can observe, once
216 * the agent has finished it. Absent before then, and on changes g1t is
217 * not seeing through.
218 */
219 confidence?: Confidence | null;
Merge rulesets: branch and tag rules, agent-first, enforced on push and merge220 /** Who last moved its head (a user id), and when; absent until a push after rulesets arrived. */
221 headPushedBy?: string;
222 headPushedAt?: string;
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step223};
224
225/** How sure g1t is that an agent's change is right. */
226export type ConfidenceLevel = "low" | "medium" | "high";
227
228/**
229 * How sure g1t is of a change an agent made, worked out from what can be
230 * observed: its checks, how often it was sent back, the reviewer agent's
231 * verdict, whether it touched tests, its size, where it reached, how close
232 * it came to its guardrails, and what it asked without an answer. The
233 * agent's own word can only lower it.
234 */
235export type Confidence = {
236 level: ConfidenceLevel;
237 /** A few words each, most telling first: what lowered it, or for `high`, what it rests on. */
238 reasons: string[];
239 /** What the agent said of its own change, if it said. */
240 selfReported: ConfidenceLevel | null;
241 /** What the agent said it was unsure about. */
242 uncertainAbout: string[];
243 /** The agent run it was worked out after. */
244 runId: string | null;
245 /** RFC 3339. */
246 assessedAt: string;
247};
248
249/** What became of the agent when an issue was opened and handed to it in one step. */
250export type AgentStartStatus = "started" | "queued" | "not_started";
251
252/** Whether the agent started, and if not, why and what fixes it. */
253export type AgentStart = {
254 status: AgentStartStatus;
255 /**
256 * Why it did not start: `not_paid`, `trial_used`, `limit`, `paused`,
257 * `issue_cap`, `billing_unavailable` or `no_model`; `waiting` when queued.
258 */
259 code: string | null;
260 /** What happened, in a sentence or two, with what to do. */
261 message: string | null;
262 /** Where the fix is: the workspace's billing or model settings. */
263 fixUrl: string | null;
Redraw the opening artwork264};
265
g1t is one name: its agent's work, commits and comments show as @g1t, and nobody can claim g1t or g1t-agent266/** An issue opened and handed to g1t in one step. The issue exists whatever became of the agent. */
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step267export type Delegated = {
268 issue: Issue;
269 /** The pull request the agent opened, when it started. */
270 pull: Pull | null;
271 agent: AgentStart;
272};
273
Fast pages, required checks on the branch, self-hosted runners, honest incidents274/**
275 * What to put an agent on: an issue's title, and what to do in plain words,
276 * with what done means if you like (a "Definition of done" section). What
277 * has to pass before it merges is the branch's required checks.
278 */
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step279export type DelegateInput = {
280 title: string;
281 body: string;
282 labels?: string[];
Fast pages, required checks on the branch, self-hosted runners, honest incidents283 /** Deprecated: commands, added to the body under "Definition of done". */
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step284 checks?: string[];
285};
286
Redraw the opening artwork287/** One file a pull request changes, and by how much. */
288export type ChangedFile = { path: string; additions: number; deletions: number };
289
290/**
291 * Another pull request in progress that changes some of the same files. Two
292 * for the same issue are alternatives; two for different issues are heading
293 * for a conflict.
294 */
295export type Overlap = {
296 number: number;
297 title: string;
298 /** The number of the issue the other pull request is for. */
299 issue: number | null;
300 /** The files both change. */
301 paths: string[];
302};
303
Fast pages, required checks on the branch, self-hosted runners, honest incidents304/**
305 * On a pull request, `failed` means the merge queue took it out, until its
306 * head moves. The other states are from runs of commands written on issues,
307 * which g1t no longer runs.
308 */
Redraw the opening artwork309export type CheckStatus = "queued" | "running" | "passed" | "failed" | "errored";
310
Fast pages, required checks on the branch, self-hosted runners, honest incidents311/** How one command went, in a run recorded before checks were workflows. */
Redraw the opening artwork312export type CheckResult = {
313 command: string;
314 passed: boolean;
315 /** Null when the command was stopped for taking too long. */
316 exitCode: number | null;
317 /** What the command printed; the end of it, when there was a lot. */
318 output: string;
319 durationMs: number;
320};
321
322/**
Fast pages, required checks on the branch, self-hosted runners, honest incidents323 * A record against a pull request's head: the merge queue taking it out,
324 * with why, or an earlier run of commands written on its issue.
Redraw the opening artwork325 */
326export type CheckRun = {
327 id: string;
328 /** The commit that was checked. */
329 headCommit: string;
330 status: CheckStatus;
331 results: CheckResult[];
332 /** Why the checks could not be run, when `status` is `errored`. */
333 error: string | null;
334 /** RFC 3339. */
335 createdAt: string;
336 /** RFC 3339. */
337 finishedAt: string | null;
338};
339
340/** A reviewer's decision on a pull request. */
341export type Verdict = "approve" | "request_changes";
342
343/**
344 * A comment on an issue or a pull request. On a pull request it can sit on
345 * one line of the change, and it can carry a reviewer's verdict.
346 */
347export type Comment = {
348 id: string;
349 /**
350 * Something a person or an agent wrote, or something that happened: an
351 * assignment, a review asked for, a close.
352 */
353 kind: "comment" | "event";
354 author: User;
355 /**
356 * Markdown. For an event, what its author did, as the rest of a sentence
357 * that starts with their name: "assigned ana".
358 */
359 body: string;
360 /** The file commented on, for a comment on a line. */
361 path: string | null;
362 /** The line of that file, as numbered after the change. */
363 line: number | null;
364 verdict: Verdict | null;
365 /** RFC 3339. */
366 createdAt: string;
Merge Actions: cross-repo workflows and actions, release and deployment triggers, step timeouts367 /** When its text was last edited, RFC 3339; absent if it never was. */
368 editedAt?: string;
Cards you act on in chat; agents comment and review as themselves; names shown cleanly; commits on the calendar369 /**
370 * Set when one of the workspace's agents wrote it, as itself. `author`
371 * is then the agent (its id, its handle as `username`, kind `agent`):
372 * show it by `agent.displayName` with an Agent badge, never as a person.
373 */
374 agent?: AgentRef;
375 /** Who the agent acted for, whose access capped it. Set with `agent`. */
376 actingFor?: User;
377 /**
378 * An agent's review. Its `verdict` (none for a review that only
379 * comments) is shown but advisory: it never counts toward required
380 * approvals or code owners, and never blocks a merge.
381 */
382 advisory?: boolean;
383};
384
385/**
386 * One of a workspace's own agents as a comment or review it wrote shows
387 * it: Margo (@margo), with the pixel face drawn from `avatarSeed`. Its page
388 * is `/<workspace>/-/agents/<handle>`.
389 */
390export type AgentRef = {
391 id: string;
392 handle: string;
393 displayName: string;
394 avatarSeed: string;
Redraw the opening artwork395};
396
Cards you act on in chat; agents comment and review as themselves; names shown cleanly; commits on the calendar397/** An agent's review: all of them advisory. */
398export type AgentVerdict = "comment" | "approve" | "request_changes";
399
400/** How many comments and reviews one agent may write on one issue or pull request an hour. */
401export const AGENT_COMMENTS_PER_HOUR = 5;
402
403/** An agent as its comments name it, from the agents service's record of it. */
404export function agentRef(agent: { id: string; handle: string; display_name: string; avatar_seed: string }): AgentRef {
405 return { id: agent.id, handle: agent.handle, displayName: agent.display_name, avatarSeed: agent.avatar_seed };
406}
407
Redraw the opening artwork408export type NewComment = {
409 /** May be empty when approving. */
410 body: string;
411 path?: string;
412 line?: number;
413 verdict?: Verdict;
414};
415
416/** What a sandbox needs to carry out a check run. */
417export type CheckJob = {
418 runId: string;
419 /** Lets the sandbox, and nothing else, report this run's results. */
420 token: string;
421 commands: string[];
422 /** The repository holding the commit: the fork, or the repository itself. */
423 source: RepoPath;
424 commit: string;
g1t is the stored author of what it opens; the person who asked is requested_by and keeps the author's rights425 /** Who the pull request is for (`workOwner`: whoever asked g1t for it, or its author), and so can read its source. */
Redraw the opening artwork426 author: User;
427 /** Username of whoever wrote the checks: the issue's author. */
428 requestedBy: string;
429 repo: RepoPath;
430 number: number;
431};
432
433export type CheckReport = { results?: CheckResult[]; error?: string; skip?: boolean };
434
435export type SessionEntryKind = "prompt" | "message" | "tool_call" | "tool_result" | "note";
436
437/** One step of an agent's session: the "why" behind a pull request's commits. */
438export type SessionEntry = {
439 seq: number;
440 kind: SessionEntryKind;
441 text: string;
442 /** For tool calls and results. */
443 tool: string | null;
444 /** The fork's head commit when this entry was recorded, if known. */
445 commit: string | null;
446 /** RFC 3339. */
447 at: string;
448};
449
450export type NewSessionEntry = Pick<SessionEntry, "kind" | "text"> &
451 Partial<Pick<SessionEntry, "tool" | "commit">>;
452
453export type IssueDetail = {
454 issue: Issue;
455 /** Every pull request made against it, oldest first. */
456 pulls: Pull[];
457 comments: Comment[];
458};
459
460export type PullDetail = {
461 pull: Pull;
462 /** The issue it is for, if any. */
463 issue: Issue | null;
464 comments: Comment[];
Fast pages, required checks on the branch, self-hosted runners, honest incidents465 /** The latest record against its head: the merge queue taking it out. */
Redraw the opening artwork466 checks: CheckRun | null;
467 /** Other pull requests in progress that change the same files. */
468 overlaps: Overlap[];
469 /**
470 * Whether the branch it would merge into has moved on without it, so that
471 * it has to catch up before it can merge.
472 */
473 behind: boolean;
474 /** Whether a g1t agent is reviewing it right now. */
475 reviewPending: boolean;
476 /**
477 * Where it stands on its way to being merged, for a pull request g1t is
478 * seeing through. Null on anyone else's.
479 */
480 lifecycle: Lifecycle | null;
481 /**
482 * A merge was asked for while it was behind: g1t is bringing it up to
483 * date and will then land it.
484 */
485 landing: boolean;
486 /** Why g1t stopped working on it, if it did. */
487 stalled: string | null;
488 /** Messages people sent the agent while it worked, oldest first. */
489 messages: AgentMessage[];
GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs490 /** What workflow runs said about its head commit, one per workflow. */
491 statuses?: CommitStatus[];
Agents and memory, checks and conflicts, profiles, slug renames, custom domains492 /**
493 * Whether it merges cleanly into the branch it targets, worked out ahead
494 * of time whenever either side moves.
495 */
496 mergeable?: Mergeable;
497 /** When `mergeable` is `conflicting`: the files that conflict. */
498 conflicts?: string[];
Fast pages, required checks on the branch, self-hosted runners, honest incidents499 /** Earlier records like `checks`, newest first, without their output. */
Agents and memory, checks and conflicts, profiles, slug renames, custom domains500 earlierChecks?: CheckRun[];
Fast pages, required checks on the branch, self-hosted runners, honest incidents501 /**
502 * The checks the default branch's protection requires, each as it stands
503 * on the head commit. Empty when none are required.
504 */
505 requiredChecks?: RequiredCheck[];
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar506 /**
507 * Who owns the files it changes (the CODEOWNERS file of the branch it
508 * merges into) and whose approval is still needed. Absent without one.
509 */
510 codeOwners?: PullCodeOwners | null;
Merge rulesets: branch and tag rules, agent-first, enforced on push and merge511 /**
512 * The rules of the branch it merges into it does not meet yet, for whoever
513 * is looking: what refuses the merge, what they may bypass, and what rulesets
514 * in evaluate would refuse. Absent once it is closed or merged.
515 */
516 rules?: MergeRules | null;
Fast pages, required checks on the branch, self-hosted runners, honest incidents517};
518
519/** Where a required check stands on a commit; `expected` when nothing has reported it yet. */
520export type RequiredState = "success" | "failure" | "pending" | "expected";
521
522/** One check a branch's protection requires, as it stands on a commit. */
523export type RequiredCheck = {
524 /** A workflow's name, such as `CI`, or another status's context. */
525 name: string;
526 state: RequiredState;
527 description: string | null;
528 /** Where to see more: the workflow run, for one a workflow reported. */
529 targetUrl: string | null;
Agents and memory, checks and conflicts, profiles, slug renames, custom domains530};
531
Fast pages, required checks on the branch, self-hosted runners, honest incidents532/** A check name reported on a repository's commits lately, for choosing required checks. */
533export type SeenCheck = {
534 name: string;
535 /** The events it was reported for, such as `pull_request`; empty for a status that names none. */
536 events: string[];
537 /** RFC 3339. */
538 lastSeen: string;
539};
540
Agents and memory, checks and conflicts, profiles, slug renames, custom domains541/**
Fast pages, required checks on the branch, self-hosted runners, honest incidents542 * A status context's check name: `CI / pull_request` is the `CI` check,
543 * reported for a `pull_request` event. A context that does not end in an
544 * event, such as `g1t / deploy`, is its own name. As the work service reads it.
545 */
546export function checkName(context: string): string {
547 const at = context.lastIndexOf(" / ");
548 if (at <= 0) return context;
549 return STATUS_EVENTS.has(context.slice(at + 3)) ? context.slice(0, at) : context;
550}
551
552const STATUS_EVENTS = new Set([
553 "push",
554 "pull_request",
555 "pull_request_target",
556 "pull_request_review",
557 "merge_group",
558 "workflow_dispatch",
559 "workflow_run",
560 "workflow_call",
561 "schedule",
562 "release",
563 "issues",
564 "issue_comment",
565 "repository_dispatch",
566]);
567
568/**
Agents and memory, checks and conflicts, profiles, slug renames, custom domains569 * Whether a pull request merges cleanly into the branch it targets:
570 * `unknown` when it was never worked out or could not be, `checking` while
571 * a probe merges the two.
572 */
573export type Mergeable = "clean" | "conflicting" | "unknown" | "checking";
574
575/** What a sandbox needs to find out whether a pull request merges cleanly. */
576export type MergecheckJob = {
577 pullId: string;
578 /** Lets the sandbox, and nothing else, report this probe. */
579 token: string;
580 repo: RepoPath;
581 number: number;
582 defaultBranch: string;
583 /** The default branch's commit to merge into. */
584 base: string;
585 /** The repository holding the change: its fork, or the repository. */
586 source: RepoPath;
587 /** The branch of `source` holding it. */
588 branch: string;
589 /** The change's commit. */
590 head: string;
g1t is the stored author of what it opens; the person who asked is requested_by and keeps the author's rights591 /** Who the pull request is for (`workOwner`: whoever asked g1t for it, or its author), and so can read its source. */
Agents and memory, checks and conflicts, profiles, slug renames, custom domains592 author: User;
GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs593};
594
595/** What a workflow run (or another tool) says about a commit. */
596export type CommitStatus = {
597 /** What reported it, such as `CI / push`. */
598 context: string;
599 state: "pending" | "success" | "failure" | "error";
600 description: string | null;
601 targetUrl: string | null;
602 updatedAt: string;
Merge checks: statuses and check runs on every commit603 /** The integration that reported it: `actions`, `deployments`, `security`, `g1t` or `api`. */
604 source?: string;
605 /** Set on the status a check run stands as: the check run's id. */
606 checkRunId?: string;
Redraw the opening artwork607};
608
609/**
610 * A step on the way from an assigned issue to a pull request that is ready
611 * to merge. g1t takes each one without being asked: `working` (the agent is
612 * making the change), `checking`, `reviewing`, `revising` (the agent is
613 * addressing failed checks or a review), `catching_up` (merging in the
Agents asked while not at work are woken to answer614 * branch it would land on), `answering` (woken to answer another agent),
615 * then `ready` for a person to merge. `needs_you`
Redraw the opening artwork616 * means g1t has stopped and a person decides what happens next.
617 */
618export type Stage =
619 | "working"
620 | "checking"
621 | "reviewing"
622 | "revising"
623 | "catching_up"
Agents asked while not at work are woken to answer624 | "answering"
Redraw the opening artwork625 | "queued"
626 | "ready"
627 | "needs_you";
628
629export type Lifecycle = {
630 stage: Stage;
631 /** One sentence saying what is happening, or why it stopped. */
632 detail: string;
633 /** How many times the agent has been sent back to revise it. */
634 revisions: number;
635};
636
637/** What the runner needs to carry out a step of a pull request's lifecycle. */
638export type LifecycleJob = {
639 pullId: string;
640 repo: RepoPath;
641 number: number;
g1t is the stored author of what it opens; the person who asked is requested_by and keeps the author's rights642 /** Who the pull request belongs to (`workOwner`: whoever asked g1t for it, or its author). Sandboxes act as them. */
Redraw the opening artwork643 author: User;
644 /** The repository holding the change: its fork, or the repository itself. */
645 source: RepoPath;
646 /** The branch of the source holding the change; its default branch when null. */
647 branch: string | null;
648 defaultBranch: string;
649 title: string;
650 description: string;
651 issue: Issue | null;
652 /** For a revision: the failed checks or the review to address. */
653 feedback: string;
654 /** For a revision: which one this is, from 1. */
655 round: number;
656};
657
Agents asked while not at work are woken to answer658/** An agent woken to answer what other agents sent it while it was not at work. */
659export type Wake = { job: LifecycleJob; messages: AgentMessage[] };
660
Redraw the opening artwork661/**
662 * `planning` while an agent reads the repository and writes it; `ready` for
663 * a person to read and apply; `failed` if it could not be written;
664 * `applied` once its issues are open.
665 */
666export type PlanStatus = "planning" | "ready" | "failed" | "applied";
667
668/** One issue a plan proposes. */
669export type PlannedIssue = {
670 title: string;
671 /** Markdown: what to change, where, and why. */
672 body: string;
673 labels: string[];
Fast pages, required checks on the branch, self-hosted runners, honest incidents674 /** What is true once it is done, in plain words; added to the issue's body under "Definition of done". */
675 done: string[];
Redraw the opening artwork676 /** The files it will most likely change. */
677 files: string[];
678 /**
679 * The positions, counting from 1, of earlier issues in the plan that have
680 * to be merged first.
681 */
682 dependsOn: number[];
683 /** Its number, once the plan has been applied and it was kept. */
684 number: number | null;
685};
686
687/** An outcome someone wrote, and the issues an agent proposes to get there. */
688export type Plan = {
689 id: string;
690 repoId: string;
691 /** The outcome wanted, as written. */
692 brief: string;
693 status: PlanStatus;
694 /** The agent's account of how it split the work. */
695 summary: string;
696 issues: PlannedIssue[];
697 /** Why it could not be written, when `status` is `failed`. */
698 error: string | null;
699 author: User;
700 /** RFC 3339. */
701 createdAt: string;
702 /** RFC 3339. */
703 finishedAt: string | null;
704 /** Once applied: where each issue it opened stands now, in plan order. */
705 progress: IssueProgress[];
706 /** Questions and handoffs between its pull requests' agents, newest first. */
707 exchanges: AgentMessage[];
708};
709
710/** What a sandbox needs to write a plan. */
711export type PlanJob = {
712 planId: string;
713 /** Lets the sandbox, and nothing else, report this plan. */
714 token: string;
715 brief: string;
716 repo: RepoPath;
717};
718
719/** An issue waiting for a g1t agent that can be given one now. */
720export type ReadyIssue = {
721 repo: RepoPath;
722 number: number;
723 /** Who queued it, on whose say-so the agent works. */
724 actor: User;
725};
726
727/**
728 * How a repository wants its pull requests handled. A repository that has
729 * changed nothing has the defaults.
730 */
731export type RepoSettings = {
732 /**
733 * Land a g1t agent's pull request without a person once it is ready:
734 * checks passed and approved as the settings below require.
735 */
736 autoMerge: boolean;
737 /**
Fast pages, required checks on the branch, self-hosted runners, honest incidents738 * The checks that must pass on a pull request's head before it may merge
739 * into the default branch, by name: a workflow's name (`CI`) or another
740 * status's context (`g1t / deploy`). The same for people and agents, and
741 * for the merge queue.
742 */
743 requiredChecks: string[];
744 /**
Redraw the opening artwork745 * Refuse to merge a pull request that does not contain the default
746 * branch's latest commits, so that what merges is what was checked. When
747 * off, merging one that is behind brings it up to date first.
748 */
749 requireUpToDate: boolean;
750 /**
751 * How many approving reviews a pull request needs before it may merge. A
752 * reviewer who has since asked for changes blocks it.
753 */
754 requiredApprovals: number;
755 /** Whether a g1t agent's approval counts towards `requiredApprovals`. */
756 countAgentApprovals: boolean;
Fast pages, required checks on the branch, self-hosted runners, honest incidents757 /** Whether someone who may merge can bypass required checks that have not passed. */
Redraw the opening artwork758 allowIgnoringChecks: boolean;
759 /** Whether a g1t agent's pull request is reviewed by a second agent unasked. */
760 agentReview: boolean;
761 /**
762 * How many times a g1t agent is sent back to its pull request before a
763 * person is asked instead.
764 */
765 maxRevisions: number;
766 /**
767 * Merge through a queue: pull requests are tested together with those
768 * ahead of them, and only a combination that passed reaches the default
769 * branch.
770 */
771 mergeQueue: boolean;
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step772 /**
773 * Ask a person before merging a g1t agent's change whose confidence is
774 * low: auto-merge and the merge queue leave it until a person approves it.
775 */
776 holdLowConfidence: boolean;
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar777 /**
778 * Refuse to merge until the code owners of every file it changes have
779 * approved, as many as each section asks. People only; `g1t` only where
780 * the file names `@g1t`.
781 */
782 requireCodeOwnerReview?: boolean;
Redraw the opening artwork783 /** Username of the member who last changed the settings, if anyone has. */
784 updatedBy: string | null;
785 /** RFC 3339. */
786 updatedAt: string | null;
787};
788
789/** The settings a member can change. */
790export type RepoSettingsInput = Omit<RepoSettings, "updatedBy" | "updatedAt">;
791
792/** The next step for a pull request g1t is seeing through, already claimed. */
793export type Advance =
794 | { action: "none" }
795 | { action: "review" | "revise" | "catch_up"; job: LifecycleJob };
796
797/** What a sandbox needs to review a pull request. */
798export type ReviewJob = {
799 runId: string;
800 /** Lets the sandbox, and nothing else, report this review. */
801 token: string;
802 /** The repository holding the commit: the fork, or the repository itself. */
803 source: RepoPath;
804 commit: string;
805 repo: RepoPath;
806 defaultBranch: string;
807 number: number;
808 title: string;
809 description: string;
810 /** The issue the pull request is for, which says what it should achieve. */
811 issue: Issue | null;
g1t is the stored author of what it opens; the person who asked is requested_by and keeps the author's rights812 /** Who the pull request is for (`workOwner`: whoever asked g1t for it, or its author), and so can read its source. */
Redraw the opening artwork813 author: User;
Auto model routing: the cheapest tier that can do each piece of work, a retry goes up a tier, and each run records its tier814 /**
815 * The files it changes, as of its latest push: how large the change is,
816 * which decides the model that reviews it.
817 */
818 files: ChangedFile[];
819 /**
820 * What among them runs, configures or guards things (CI workflows,
821 * secrets, infrastructure), once each. Any sends the review to the
822 * larger model.
823 */
824 sensitive: string[];
Redraw the opening artwork825};
826
827export type OpenIssueInput = {
828 title: string;
829 body: string;
830 labels?: string[];
Fast pages, required checks on the branch, self-hosted runners, honest incidents831 /** Deprecated: commands, added to the body under "Definition of done". */
Redraw the opening artwork832 checks?: string[];
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar833 /** The number of the milestone to put it in. Needs the Triage role. */
834 milestone?: number;
Redraw the opening artwork835};
836
837export type UpdateIssueInput = {
838 title?: string;
839 body?: string;
840 labels?: string[];
841 /** Usernames of the people it is assigned to; replaces the whole set. */
842 assignees?: string[];
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar843 /** The number of the milestone to put it in; 0 takes it out. */
844 milestone?: number;
Redraw the opening artwork845};
846
847export type OpenPullInput = {
848 /** The number of the issue this is for. */
849 issue?: number;
850 /** Defaults to the issue's title; required without an issue. */
851 title?: string;
852 /** What changed and why. Usually set later, when a draft is marked ready. */
853 body?: string;
854 /**
855 * A branch of the repository that already holds the change. The pull
856 * request is then ready for review at once and has no fork.
857 */
858 branch?: string;
859 agent: string;
860 runtime: Runtime;
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar861 /** The branch to merge into: the default branch when left out. */
862 base?: string;
Open a pull request as a draft: it can't merge, and agents' review routines wait, until it is marked ready863 /**
864 * Opened from a branch as a draft, still being worked on: it can't merge,
865 * and agents' review routines wait, until it is marked ready.
866 */
867 draft?: boolean;
Redraw the opening artwork868};
869
Fast pages, required checks on the branch, self-hosted runners, honest incidents870/** One repository's pull requests from `pullsForRepos`, newest first. */
871export type RepoPulls = {
872 repoId: string;
873 /** Draft and open. */
874 open: Pull[];
875 /** Merged and closed. */
876 closed: Pull[];
877};
878
Redraw the opening artwork879/** Issues, pull requests, comments and sessions. */
Merge checks: statuses and check runs on every commit880export interface WorkApi extends RulesApi, ChecksApi {
Redraw the opening artwork881 openIssue(actor: User, repo: RepoPath, input: OpenIssueInput): Promise<Result<Issue>>;
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step882 /**
g1t is one name: its agent's work, commits and comments show as @g1t, and nobody can claim g1t or g1t-agent883 * Opens an issue to put g1t on at once: refused, with nothing
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step884 * opened, unless `actor` may put agents to work in `repo`. The runner's
885 * `delegate` calls it, then starts the agent.
886 */
887 delegateIssue(actor: User, repo: RepoPath, input: DelegateInput): Promise<Result<Issue>>;
Redraw the opening artwork888 /** Newest first. */
889 listIssues(
890 repo: RepoPath,
891 viewer: Viewer,
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar892 filter?: { state?: State; label?: string; milestone?: number },
Redraw the opening artwork893 ): Promise<Result<Issue[]>>;
894 getIssue(repo: RepoPath, number: number, viewer: Viewer): Promise<Result<IssueDetail>>;
895 /** The author or a member of the workspace may. */
896 updateIssue(actor: User, repo: RepoPath, number: number, input: UpdateIssueInput): Promise<Result<Issue>>;
897 closeIssue(actor: User, repo: RepoPath, number: number, reason?: IssueReason): Promise<Result<Issue>>;
898 reopenIssue(actor: User, repo: RepoPath, number: number): Promise<Result<Issue>>;
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar899 /** A repository's labels, by name, each with how many issues and pull requests carry it. */
900 listLabels(repo: RepoPath, viewer: Viewer): Promise<Result<Label[]>>;
901 /**
902 * Creates a label, or with `name` changes one; renaming it renames it on
903 * everything that carries it. Needs the Triage role.
904 */
905 saveLabel(
906 actor: User,
907 repo: RepoPath,
908 label: { name?: string; newName?: string; color?: string; description?: string },
909 ): Promise<Result<Label>>;
910 /** Removes a label from the repository and everything carrying it. */
911 deleteLabel(actor: User, repo: RepoPath, name: string): Promise<Result<boolean>>;
912 /** Adds the default labels the repository does not have yet; returns them all. */
913 addDefaultLabels(actor: User, repo: RepoPath): Promise<Result<Label[]>>;
914 /**
915 * The labels of an issue or a pull request, replaced, added to or taken
916 * from. Labels the repository lacks are created for someone with the
917 * Triage role. Returns its labels now.
918 */
919 setLabels(
920 actor: User,
921 repo: RepoPath,
922 number: number,
923 labels: string[],
924 change?: LabelChange,
925 ): Promise<Result<string[]>>;
926 /** Open ones by due date, then closed ones; both unless `state` says. */
927 listMilestones(repo: RepoPath, viewer: Viewer, state?: State): Promise<Result<Milestone[]>>;
928 getMilestone(repo: RepoPath, number: number, viewer: Viewer): Promise<Result<MilestoneDetail>>;
929 /** Creates a milestone, or with `number` changes the fields given. Needs the Triage role. */
930 saveMilestone(
931 actor: User,
932 repo: RepoPath,
933 milestone: { number?: number; title?: string; description?: string; dueOn?: string; state?: State },
934 ): Promise<Result<Milestone>>;
935 deleteMilestone(actor: User, repo: RepoPath, number: number): Promise<Result<boolean>>;
Redraw the opening artwork936 /** How many issues and pull requests are open. */
937 counts(repo: RepoPath, viewer: Viewer): Promise<Result<{ issues: number; pulls: number }>>;
938
939 /**
940 * On an issue or a pull request. On a pull request it may name a line of
941 * the change and carry a verdict; nobody can give a verdict on their own.
942 */
943 addComment(actor: User, repo: RepoPath, number: number, comment: NewComment): Promise<Result<Comment>>;
Merge Actions: cross-repo workflows and actions, release and deployment triggers, step timeouts944 /**
945 * Changes a comment's text. Its author may, and so may anyone with the
946 * Maintain role or higher; notes of what happened cannot be changed.
947 */
948 editComment(actor: User, repo: RepoPath, commentId: string, body: string): Promise<Result<Comment>>;
949 /**
950 * Deletes a comment: its author, or anyone with the Maintain role or
951 * higher. A review that gave a verdict cannot be deleted, only edited.
952 */
953 deleteComment(actor: User, repo: RepoPath, commentId: string): Promise<Result<boolean>>;
Cards you act on in chat; agents comment and review as themselves; names shown cleanly; commits on the calendar954 /**
955 * One of the workspace's agents comments on an issue or a pull request
956 * as itself, on behalf of `actingFor`: the person whose access caps it.
957 * The checks a person's comment has apply to them (verified, can read
958 * the repository, not archived). At most `AGENT_COMMENTS_PER_HOUR`
959 * comments and reviews per agent per issue or pull request
960 * (`conflict` past it). Publishes `comment.created` with `agent`. For
961 * the agents service only: never reachable with a person's token.
962 */
963 workspaceAgentComment(
964 repo: RepoPath,
965 number: number,
966 agent: AgentRef,
967 actingFor: User,
968 body: string,
969 ): Promise<Result<Comment>>;
970 /**
971 * One of the workspace's agents reviews a pull request as itself, on
972 * behalf of `actingFor`. Advisory: the verdict is shown but never counts
973 * toward required approvals or code owners, and never blocks a merge.
974 * Refused on a draft and on a closed or merged pull request (`conflict`);
975 * `body` may be empty only when approving. Same checks and limit as
976 * `workspaceAgentComment`. Publishes `comment.created` with `agent`,
977 * `advisory` and the verdict.
978 */
979 workspaceAgentReview(
980 repo: RepoPath,
981 number: number,
982 agent: AgentRef,
983 actingFor: User,
984 verdict: AgentVerdict,
985 body: string,
986 ): Promise<Result<Comment>>;
Redraw the opening artwork987
988 /**
Fast pages, required checks on the branch, self-hosted runners, honest incidents989 * Always refused now: a pull request's checks are the workflows run on
990 * it. Kept for a runner from before.
Redraw the opening artwork991 */
992 startChecks(pullId: string): Promise<Result<CheckJob>>;
993 /**
Fast pages, required checks on the branch, self-hosted runners, honest incidents994 * What a sandbox says about a run from before checks were workflows: so
995 * one still finishing is recorded.
Redraw the opening artwork996 */
997 reportChecks(runId: string, token: string, report: CheckReport): Promise<Result<CheckRun>>;
998 /** Begins a review by a g1t agent. For the runner service. */
999 startReview(pullId: string): Promise<Result<ReviewJob>>;
1000 /** Records that a review could not be written. For the runner service. */
1001 failReview(runId: string, token: string, error: string): Promise<Result<boolean>>;
Agents and memory, checks and conflicts, profiles, slug renames, custom domains1002 /**
1003 * Claims the probe of whether a pull request merges cleanly that a
1004 * `pull.mergecheck` event asked for. Refused when it is no longer wanted
1005 * or the repository has as many running as it may. For the runner service.
1006 */
1007 startMergecheck(pullId: string): Promise<Result<MergecheckJob>>;
1008 /** Records that a probe could not be carried out. For the runner service. */
1009 failMergecheck(pullId: string, token: string, error: string): Promise<Result<Mergeable>>;
Redraw the opening artwork1010
1011 /**
1012 * Works out the next step for a pull request g1t is seeing through and,
1013 * if there is one to take now, claims it, so that it is taken once
1014 * however often this is called. For the runner service.
1015 */
1016 advance(pullId: string): Promise<Advance>;
1017 /** Records that a step could not be carried out, so a person is asked. */
1018 stall(pullId: string, reason: string): Promise<boolean>;
1019 /** Ids of the open pull requests g1t is seeing through. */
1020 managedPulls(repoId?: string): Promise<string[]>;
1021
1022 /** A repository's merge queue: what is in it, in order, and what recently left. */
1023 queue(repo: RepoPath, viewer: Viewer): Promise<Result<QueueView>>;
1024 /**
1025 * The next batch of combined states to test for a repository, one per
1026 * entry; empty while a batch is being tested or nothing waits.
1027 */
1028 queueBuild(repoId: string): Promise<QueueJob[]>;
1029 /** Reports that a combined state could not be built or checked. */
1030 failQueue(entryId: string, token: string, error: string): Promise<Result<QueueState>>;
1031 /** Sends the agent working on a pull request a message, for its next step. */
1032 messageAgent(actor: User, repo: RepoPath, number: number, body: string): Promise<Result<AgentMessage>>;
1033 /** Takes a pull request out of the merge queue. Members only. */
1034 removeFromQueue(actor: User, repo: RepoPath, number: number): Promise<Result<Pull>>;
1035
1036 getSettings(repo: RepoPath, viewer: Viewer): Promise<Result<RepoSettings>>;
Fast pages, required checks on the branch, self-hosted runners, honest incidents1037 /** The check names reported on the repository's commits in the last 30 days, most recent first. */
1038 seenChecks(repo: RepoPath, viewer: Viewer): Promise<Result<SeenCheck[]>>;
Redraw the opening artwork1039 /** Members of the repository's workspace only. */
1040 updateSettings(actor: User, repo: RepoPath, settings: RepoSettingsInput): Promise<Result<RepoSettings>>;
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar1041 /** The CODEOWNERS file at a branch (the default when left out), checked. Needs Read. */
1042 codeownersErrors(repo: RepoPath, viewer: Viewer, ref?: string | null): Promise<Result<CodeownersReport>>;
Redraw the opening artwork1043 /**
1044 * What the runner needs to bring a pull request up to date because a
1045 * merge of it was asked for. Null if none was.
1046 */
1047 catchUpJob(pullId: string): Promise<LifecycleJob | null>;
Agents asked while not at work are woken to answer1048 /**
1049 * Claims a short step for the agent on a pull request to answer the
1050 * questions and handoffs it was sent while not at work, and hands them
1051 * over, marked read. Null when there is nothing waiting or it cannot
1052 * take a step now.
1053 */
1054 wakeForMessages(pullId: string): Promise<Wake | null>;
Redraw the opening artwork1055
1056 /**
1057 * Opens a pull request: a draft with a fork to push to, or, given a
1058 * branch, one ready for review.
1059 */
1060 openPull(actor: User, repo: RepoPath, input: OpenPullInput): Promise<Result<Pull>>;
1061 /** Newest first. */
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar1062 listPulls(
1063 repo: RepoPath,
1064 viewer: Viewer,
1065 state?: State,
1066 filter?: { label?: string; milestone?: number; base?: string },
1067 ): Promise<Result<Pull[]>>;
Fast pages, required checks on the branch, self-hosted runners, honest incidents1068 /**
1069 * The newest `limit` open and closed pull requests of each repository,
1070 * in one call. Repositories the viewer cannot read, and forks, are left
1071 * out: ask those with `listPulls`.
1072 */
1073 pullsForRepos(repoIds: string[], viewer: Viewer, limit: number): Promise<RepoPulls[]>;
Redraw the opening artwork1074 getPull(repo: RepoPath, number: number, viewer: Viewer): Promise<Result<PullDetail>>;
1075 /**
1076 * Changes who a pull request is assigned to and whose review is asked
g1t is one name: its agent's work, commits and comments show as @g1t, and nobody can claim g1t or g1t-agent1077 * for; each list given replaces the whole set. Asking for `g1t`'s
Redraw the opening artwork1078 * review does not by itself start one: the runner's `review` does.
1079 */
1080 updatePull(
1081 actor: User,
1082 repo: RepoPath,
1083 number: number,
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar1084 changes: {
1085 assignees?: string[];
1086 reviewers?: string[];
1087 labels?: string[];
1088 /** 0 takes it out of its milestone. */
1089 milestone?: number;
1090 /** The branch it merges into. Needs the Write role. */
1091 base?: string;
1092 },
Redraw the opening artwork1093 ): Promise<Result<Pull>>;
Catching up with main takes seconds when the two sides touched different files1094 /**
1095 * Brings a pull request up to date with the default branch in seconds,
1096 * without a sandbox, when the two changed different files: the merge
1097 * commit is pushed to its branch as `actor`, who must be whoever opened
1098 * it (for a fork) or a member (for a branch). Otherwise `needs_agent`, and
1099 * nothing is pushed: the runner's `update` is the way on.
1100 */
1101 catchUpPull(actor: User, repo: RepoPath, number: number): Promise<Result<PullBranchUpdate>>;
Redraw the opening artwork1102 /** Marks a draft ready for review and sets its description. */
1103 readyPull(actor: User, repo: RepoPath, number: number, summary: string): Promise<Result<Pull>>;
1104 closePull(actor: User, repo: RepoPath, number: number): Promise<Result<Pull>>;
Merge Actions: cross-repo workflows and actions, release and deployment triggers, step timeouts1105 /** Opens a closed pull request again, as the draft it was if it was closed as one. Never a merged one. */
1106 reopenPull(actor: User, repo: RepoPath, number: number): Promise<Result<Pull>>;
1107 /** Turns an open pull request back into a draft; it leaves the merge queue. */
1108 convertPullToDraft(actor: User, repo: RepoPath, number: number): Promise<Result<Pull>>;
Redraw the opening artwork1109 /**
1110 * Lands the pull request on the repository's default branch. Unless
1111 * `keepIssueOpen`, that resolves the issue it was for: the issue closes
1112 * naming this pull request, and the others still in progress for it close
1113 * as superseded. Only members of the repository's workspace may merge.
1114 *
1115 * If the default branch has moved, the pull request is brought up to date
1116 * first and lands when that is done; it comes back still open, and
1117 * `PullDetail.landing` is true meanwhile. A repository that requires pull
1118 * requests to be up to date refuses instead.
1119 */
1120 mergePull(
1121 actor: User,
1122 repo: RepoPath,
1123 number: number,
1124 options?: {
1125 keepIssueOpen?: boolean;
Merge rulesets: branch and tag rules, agent-first, enforced on push and merge1126 /** Merge although required checks have not passed, where the rule requiring them allows it. */
Redraw the opening artwork1127 ignoreChecks?: boolean;
Merge rulesets: branch and tag rules, agent-first, enforced on push and merge1128 /** Merge past rules a ruleset lets the actor bypass. Recorded as a bypass. */
1129 bypassRules?: boolean;
Redraw the opening artwork1130 },
1131 ): Promise<Result<Pull>>;
1132 /**
1133 * Drafts and open pull requests the viewer started, most recently active
1134 * first, each with where it stands if g1t is seeing it through.
1135 */
1136 listActivePulls(
1137 viewer: Viewer,
1138 ): Promise<{ pull: Pull; issue: Issue | null; lifecycle: Lifecycle | null }[]>;
Agents and memory, checks and conflicts, profiles, slug renames, custom domains1139 /**
1140 * The issues and pull requests a person opened, a page at a time, only
1141 * on repositories the viewer may read. Not found for no such account.
1142 */
1143 byAuthor(username: string, viewer: Viewer, filter?: AuthoredFilter): Promise<Result<Authored>>;
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1144 /**
1145 * What a person did each day of the last year (issues and pull requests
1146 * opened, reviews given), only on repositories the viewer may read: the
1147 * calendar on their profile. Not found for no such account.
1148 */
1149 contributions(username: string, viewer: Viewer): Promise<Result<Contributions>>;
Redraw the opening artwork1150
1151 /**
1152 * Records an outcome to plan for. Members only. For the runner service,
1153 * which starts the sandbox in which an agent writes the plan.
1154 */
1155 startPlan(actor: User, repo: RepoPath, brief: string): Promise<Result<PlanJob>>;
1156 /** Records that a plan could not be written. For the runner service. */
1157 failPlan(planId: string, token: string, error: string): Promise<Result<boolean>>;
1158 /** Members only. */
1159 getPlan(repo: RepoPath, viewer: Viewer, id: string): Promise<Result<Plan>>;
1160 /** Newest first. Members only. */
1161 listPlans(repo: RepoPath, viewer: Viewer): Promise<Result<Plan[]>>;
1162 /**
1163 * Opens a plan's issues, each blocked by the ones it depends on. With
1164 * `assign`, each is queued for a g1t agent. `keep` holds the positions,
1165 * from 1, of the issues to open; all of them when absent. Once.
1166 */
1167 applyPlan(
1168 actor: User,
1169 repo: RepoPath,
1170 id: string,
1171 options?: { assign?: boolean; keep?: number[] },
1172 ): Promise<Result<Plan>>;
1173 /** Asks for a g1t agent to take an issue as soon as it can, or withdraws that. */
1174 queueIssue(actor: User, repo: RepoPath, number: number, queued: boolean): Promise<Result<boolean>>;
1175 /** Issues waiting for a g1t agent that can be given one now. For the runner. */
1176 readyIssues(repoId?: string): Promise<ReadyIssue[]>;
1177
1178 /** Open issues assigned to the viewer, most recently changed first. */
1179 listAssignedIssues(viewer: Viewer): Promise<Issue[]>;
1180
1181 appendSession(actor: User, repo: RepoPath, number: number, entries: NewSessionEntry[]): Promise<Result<{ count: number }>>;
1182 readSession(repo: RepoPath, number: number, viewer: Viewer, afterSeq?: number): Promise<Result<SessionEntry[]>>;
1183}
1184
1185/**
1186 * What to pass `ReposApi.compare` to see what a pull request changes.
1187 *
1188 * A fork is compared as a whole. A branch is compared by name while the
1189 * pull request is open, and by the commit it was merged or closed at
1190 * afterwards, so later pushes to the branch do not change the record.
1191 */
1192export function pullComparison(pull: Pull): {
1193 repoId: string;
1194 base: string | null;
1195 head: string | null;
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar1196 /** The branch it merges into, which it is compared from. */
1197 baseBranch: string | null;
Redraw the opening artwork1198} {
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar1199 const baseBranch = pull.base ?? null;
1200 if (pull.forkRepoId) return { repoId: pull.forkRepoId, base: pull.mergeBase, head: null, baseBranch };
Redraw the opening artwork1201 const settled = pull.status === "merged" || pull.status === "closed";
1202 return {
1203 repoId: pull.repoId,
1204 base: pull.mergeBase,
1205 head: (settled && pull.headCommit) || pull.branch,
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar1206 baseBranch,
Redraw the opening artwork1207 };
1208}
1209
1210
1211/** Where a pull request in a merge queue stands. */
1212/** Where one issue of an applied plan stands. */
1213export type IssueProgress = {
1214 number: number;
1215 title: string;
1216 /**
1217 * `blocked`, `waiting` (for an agent), `open`, a lifecycle stage,
1218 * `landed` or `closed`.
1219 */
1220 state: string;
1221 detail: string;
1222 /** The issues it is waiting on that are still open. */
1223 blockedBy: number[];
1224 pull: number | null;
1225 agent: string | null;
1226};
1227
1228/** A message a person sent an agent at work on a pull request. */
1229export type AgentMessage = {
1230 id: string;
1231 author: string;
1232 body: string;
1233 createdAt: string;
1234 /** When the agent received it; null until then. */
1235 deliveredAt: string | null;
1236 /** `message` from a person; from an agent a `question`, `handoff` or `answer`. */
1237 kind: "message" | "question" | "handoff" | "answer";
1238 /** The pull request whose agent sent it, when an agent did. */
1239 fromNumber: number | null;
1240 /** The pull request it was sent to. */
1241 toNumber: number;
1242 /** The reply to a question or handoff, once there is one. */
1243 answer: string | null;
1244 declined: boolean;
1245 /** For the sending agent: what to expect when the one it asked is not at work. */
1246 hint?: string;
1247};
1248
1249export type QueueState = "waiting" | "testing" | "passed" | "failed" | "landed" | "removed";
1250
1251/** One pull request's place in a merge queue. */
1252export type QueueEntry = {
1253 id: string;
1254 number: number;
1255 title: string;
1256 agent: string;
1257 state: QueueState;
1258 /** The pull requests merged ahead of it in the state being tested, in order. */
1259 ahead: number[];
1260 baseCommit: string | null;
1261 combinedCommit: string | null;
1262 error: string | null;
1263 results: CheckResult[];
1264 /** Username of whoever merged it into the queue: a person, or `g1t`. */
1265 enqueuedBy: string;
1266 /** RFC 3339. */
1267 createdAt: string;
1268 /** RFC 3339. */
1269 finishedAt: string | null;
1270};
1271
1272/** A repository's merge queue: what is in it, in order, and what recently left. */
1273export type QueueView = {
1274 enabled: boolean;
1275 active: QueueEntry[];
1276 /** Newest first. */
1277 recent: QueueEntry[];
1278};
1279
1280export type QueueStackItem = {
1281 number: number;
1282 title: string;
1283 /** The repository holding the change, and its branch. */
1284 source: RepoPath;
1285 branch: string;
1286 commit: string;
1287};
1288
1289/** What a sandbox needs to build and check one combined state. */
1290export type QueueJob = {
1291 entryId: string;
1292 token: string;
1293 repo: RepoPath;
1294 defaultBranch: string;
1295 baseCommit: string;
1296 branch: string;
1297 stack: QueueStackItem[];
Fast pages, required checks on the branch, self-hosted runners, honest incidents1298 /** Always empty: the state is checked by the merge_group workflows run on it. */
Redraw the opening artwork1299 checks: string[];
Fast pages, required checks on the branch, self-hosted runners, honest incidents1300 /** Always empty, as `checks`. */
Redraw the opening artwork1301 contractChecks: string[];
1302 actor: User;
1303};
Agents and memory, checks and conflicts, profiles, slug renames, custom domains1304
1305// --- A person's work ---------------------------------------------------------
1306// Mirrors the `Authored*` types in `crates/contracts/src/work.rs`.
1307
1308export type AuthoredKind = "issue" | "pull";
1309/** `closed` takes in merged pull requests too; `merged` is only those. */
1310export type AuthoredState = "open" | "closed" | "merged";
1311/** `created` is newest first, `updated` most recently changed, `oldest` oldest first. */
1312export type AuthoredSort = "created" | "updated" | "oldest";
1313
1314/** The most items one `byAuthor` page holds. */
1315export const AUTHORED_PAGE = 25;
1316
1317export type AuthoredFilter = {
1318 kind?: AuthoredKind;
1319 state?: AuthoredState;
1320 /** `namespace/name`. */
1321 repo?: string;
1322 sort?: AuthoredSort;
1323 /** The `next` of the page before. */
1324 before?: string;
1325 limit?: number;
1326};
1327
1328export type AuthoredItem = {
1329 kind: AuthoredKind;
1330 repo: RepoPath;
1331 number: number;
1332 title: string;
1333 /** A merged pull request is closed. */
1334 state: State;
1335 /** A pull request's own status; null on an issue. */
1336 status: PullStatus | null;
1337 /** Why an issue was closed. */
1338 reason: IssueReason | null;
1339 draft: boolean;
1340 merged: boolean;
1341 /** RFC 3339. */
1342 createdAt: string;
1343 /** RFC 3339. */
1344 updatedAt: string;
1345 /** RFC 3339. */
1346 mergedAt: string | null;
1347};
1348
1349/** Over every repository the viewer may read, whatever the filters. */
1350export type AuthoredCounts = {
1351 pullsMerged: number;
1352 pullsOpen: number;
1353 pulls: number;
1354 issues: number;
1355 issuesOpen: number;
1356};
1357
1358export type Authored = {
1359 items: AuthoredItem[];
1360 /** Pass as `before` for the next page; null on the last. */
1361 next: string | null;
1362 counts: AuthoredCounts;
1363 /** The repositories they worked in that the viewer may read, most work first. */
1364 repos: { repo: RepoPath; count: number }[];
1365};
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1366
1367// Mirrors `Contributions` in `crates/contracts/src/work.rs`.
1368
1369/** How many days `contributions` covers: today and the 364 before it. */
1370export const CONTRIBUTION_DAYS = 365;
1371
1372/** One day with something on it; days with nothing are left out. */
Cards you act on in chat; agents comment and review as themselves; names shown cleanly; commits on the calendar1373export type ContributionDay = {
1374 /** `YYYY-MM-DD`, UTC. */
1375 date: string;
1376 /** Everything that day, commits included. */
1377 count: number;
1378 /** How many of `count` are commits they pushed to a default branch. */
1379 commits?: number;
1380};
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1381
1382/** A person's year, as far as the viewer may see. */
1383export type Contributions = {
1384 /** Oldest first. */
1385 days: ContributionDay[];
1386 total: number;
1387 /** The first day counted, `YYYY-MM-DD`; the last is today (UTC). */
1388 from: string;
1389};

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