Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| Initial g1t: services, event bus, intents and attempts | 1 | import type { User, Viewer } from "./identity"; |
| 2 | import type { RepoPath } from "./repos"; | |
| 3 | import type { Result } from "./result"; | |
| 4 | ||
| Issues and pull requests replace intents and attempts | 5 | /** |
| 6 | * The filter on lists of issues and pull requests. An open pull request is | |
| 7 | * a draft or one ready for review; a closed one was merged or closed | |
| 8 | * without merging. | |
| 9 | */ | |
| 10 | export type State = "open" | "closed"; | |
| 11 | ||
| 12 | /** Why an issue was closed. */ | |
| 13 | export type IssueReason = "completed" | "not_planned"; | |
| Initial g1t: services, event bus, intents and attempts | 14 | |
| Issues and pull requests replace intents and attempts | 15 | /** |
| 16 | * Something that should change in a repository: a bug, a feature, a | |
| 17 | * question. Opened by a person, an agent or an integration. Pull requests | |
| 18 | * are made against it; the one that is merged resolves it. | |
| 19 | * | |
| 20 | * Issues and pull requests share one sequence of numbers per repository. | |
| 21 | */ | |
| 22 | export type Issue = { | |
| Initial g1t: services, event bus, intents and attempts | 23 | id: string; |
| 24 | repoId: string; | |
| Issues and pull requests replace intents and attempts | 25 | /** Shown as `#12`. */ |
| Initial g1t: services, event bus, intents and attempts | 26 | number: number; |
| 27 | title: string; | |
| Issues and pull requests replace intents and attempts | 28 | /** Markdown. Also what an agent is given to work from. */ |
| 29 | body: string; | |
| 30 | labels: string[]; | |
| 31 | /** Commands that must pass for a pull request to be accepted. */ | |
| Initial g1t: services, event bus, intents and attempts | 32 | checks: string[]; |
| Issues and pull requests replace intents and attempts | 33 | state: State; |
| 34 | /** Set when closed. */ | |
| 35 | reason: IssueReason | null; | |
| 36 | /** The number of the pull request whose merge closed this issue. */ | |
| 37 | resolvedBy: number | null; | |
| Initial g1t: services, event bus, intents and attempts | 38 | author: User; |
| Work service in Rust, with RFC 3339 timestamps | 39 | /** RFC 3339. */ |
| 40 | createdAt: string; | |
| Issues and pull requests replace intents and attempts | 41 | /** RFC 3339. */ |
| 42 | updatedAt: string; | |
| 43 | /** RFC 3339. */ | |
| 44 | closedAt: string | null; | |
| 45 | /** Pull requests made against this issue, in any state. */ | |
| 46 | pullCount: number; | |
| 47 | commentCount: number; | |
| Initial g1t: services, event bus, intents and attempts | 48 | }; |
| 49 | ||
| Issues and pull requests replace intents and attempts | 50 | /** `draft` is still being worked on; `open` is ready for review. */ |
| 51 | export type PullStatus = "draft" | "open" | "merged" | "closed"; | |
| Initial g1t: services, event bus, intents and attempts | 52 | |
| 53 | /** Where the agent runs: on g1t's sandboxes, or in someone's own session. */ | |
| Issues and pull requests replace intents and attempts | 54 | export type Runtime = "hosted" | "external"; |
| Initial g1t: services, event bus, intents and attempts | 55 | |
| Pull requests from branches | 56 | /** |
| 57 | * A proposed change. It is made either in a fork created for it, which is | |
| 58 | * how agents work, or on a branch pushed to the repository itself. | |
| 59 | */ | |
| Issues and pull requests replace intents and attempts | 60 | export type Pull = { |
| Initial g1t: services, event bus, intents and attempts | 61 | id: string; |
| 62 | repoId: string; | |
| Issues and pull requests replace intents and attempts | 63 | /** Shown as `#12`. */ |
| Initial g1t: services, event bus, intents and attempts | 64 | number: number; |
| Issues and pull requests replace intents and attempts | 65 | /** The number of the issue this is for, if any. */ |
| 66 | issue: number | null; | |
| 67 | title: string; | |
| 68 | /** Markdown: what changed and why. Set when marked ready. */ | |
| 69 | body: string | null; | |
| Initial g1t: services, event bus, intents and attempts | 70 | /** A label for the agent doing the work, e.g. `claude-code`. */ |
| 71 | agent: string; | |
| Issues and pull requests replace intents and attempts | 72 | runtime: Runtime; |
| 73 | status: PullStatus; | |
| Pull requests from branches | 74 | /** The fork holding the change, unless it is on a branch. */ |
| 75 | fork: RepoPath | null; | |
| Diffs on attempts; hosted agent presented as the g1t agent | 76 | /** The fork's repository id. */ |
| Pull requests from branches | 77 | forkRepoId: string | null; |
| 78 | /** The branch of the repository holding the change, unless it is in a fork. */ | |
| 79 | branch: string | null; | |
| Initial g1t: services, event bus, intents and attempts | 80 | headCommit: string | null; |
| Diffs on attempts; hosted agent presented as the g1t agent | 81 | /** |
| Issues and pull requests replace intents and attempts | 82 | * For a merged pull request, what the branch pointed to before the merge. |
| 83 | * Comparing against it shows what the pull request changed. | |
| 84 | */ | |
| 85 | mergeBase: string | null; | |
| 86 | /** Username of whoever merged it. */ | |
| 87 | mergedBy: string | null; | |
| 88 | /** RFC 3339. */ | |
| 89 | mergedAt: string | null; | |
| 90 | /** | |
| 91 | * Set on a pull request closed because another one for the same issue was | |
| 92 | * merged: that one's number. | |
| Diffs on attempts; hosted agent presented as the g1t agent | 93 | */ |
| Issues and pull requests replace intents and attempts | 94 | supersededBy: number | null; |
| Acceptance checks in sandboxes, line comments and review verdicts | 95 | /** |
| 96 | * Where the latest run of the issue's acceptance checks stands, if there | |
| 97 | * has been one against the current head. | |
| 98 | */ | |
| 99 | checkStatus: CheckStatus | null; | |
| Issues and pull requests replace intents and attempts | 100 | author: User; |
| Work service in Rust, with RFC 3339 timestamps | 101 | /** RFC 3339. */ |
| 102 | createdAt: string; | |
| 103 | /** RFC 3339. */ | |
| 104 | updatedAt: string; | |
| Initial g1t: services, event bus, intents and attempts | 105 | }; |
| 106 | ||
| Acceptance checks in sandboxes, line comments and review verdicts | 107 | /** `queued` waits for a sandbox; `errored` means the checks could not be run. */ |
| 108 | export type CheckStatus = "queued" | "running" | "passed" | "failed" | "errored"; | |
| 109 | ||
| 110 | /** How one acceptance check went. */ | |
| 111 | export type CheckResult = { | |
| 112 | command: string; | |
| 113 | passed: boolean; | |
| 114 | /** Null when the command was stopped for taking too long. */ | |
| 115 | exitCode: number | null; | |
| 116 | /** What the command printed; the end of it, when there was a lot. */ | |
| 117 | output: string; | |
| 118 | durationMs: number; | |
| 119 | }; | |
| 120 | ||
| 121 | /** | |
| 122 | * One run of an issue's acceptance checks against a pull request's head, in | |
| 123 | * a sandbox that holds nothing but that commit. | |
| 124 | */ | |
| 125 | export type CheckRun = { | |
| 126 | id: string; | |
| 127 | /** The commit that was checked. */ | |
| 128 | headCommit: string; | |
| 129 | status: CheckStatus; | |
| 130 | results: CheckResult[]; | |
| 131 | /** Why the checks could not be run, when `status` is `errored`. */ | |
| 132 | error: string | null; | |
| 133 | /** RFC 3339. */ | |
| 134 | createdAt: string; | |
| 135 | /** RFC 3339. */ | |
| 136 | finishedAt: string | null; | |
| 137 | }; | |
| 138 | ||
| 139 | /** A reviewer's decision on a pull request. */ | |
| 140 | export type Verdict = "approve" | "request_changes"; | |
| 141 | ||
| 142 | /** | |
| 143 | * A comment on an issue or a pull request. On a pull request it can sit on | |
| 144 | * one line of the change, and it can carry a reviewer's verdict. | |
| 145 | */ | |
| Issues and pull requests replace intents and attempts | 146 | export type Comment = { |
| 147 | id: string; | |
| 148 | author: User; | |
| 149 | /** Markdown. */ | |
| 150 | body: string; | |
| Acceptance checks in sandboxes, line comments and review verdicts | 151 | /** The file commented on, for a comment on a line. */ |
| 152 | path: string | null; | |
| 153 | /** The line of that file, as numbered after the change. */ | |
| 154 | line: number | null; | |
| 155 | verdict: Verdict | null; | |
| Issues and pull requests replace intents and attempts | 156 | /** RFC 3339. */ |
| 157 | createdAt: string; | |
| 158 | }; | |
| 159 | ||
| Acceptance checks in sandboxes, line comments and review verdicts | 160 | export type NewComment = { |
| 161 | /** May be empty when approving. */ | |
| 162 | body: string; | |
| 163 | path?: string; | |
| 164 | line?: number; | |
| 165 | verdict?: Verdict; | |
| 166 | }; | |
| 167 | ||
| 168 | /** What a sandbox needs to carry out a check run. */ | |
| 169 | export type CheckJob = { | |
| 170 | runId: string; | |
| 171 | /** Lets the sandbox, and nothing else, report this run's results. */ | |
| 172 | token: string; | |
| 173 | commands: string[]; | |
| 174 | /** The repository holding the commit: the fork, or the repository itself. */ | |
| 175 | source: RepoPath; | |
| 176 | commit: string; | |
| 177 | /** Who opened the pull request, and so can read its source. */ | |
| 178 | author: User; | |
| 179 | /** Username of whoever wrote the checks: the issue's author. */ | |
| 180 | requestedBy: string; | |
| 181 | repo: RepoPath; | |
| 182 | number: number; | |
| 183 | }; | |
| 184 | ||
| 185 | export type CheckReport = { results?: CheckResult[]; error?: string; skip?: boolean }; | |
| 186 | ||
| Initial g1t: services, event bus, intents and attempts | 187 | export type SessionEntryKind = "prompt" | "message" | "tool_call" | "tool_result" | "note"; |
| 188 | ||
| Issues and pull requests replace intents and attempts | 189 | /** One step of an agent's session: the "why" behind a pull request's commits. */ |
| Initial g1t: services, event bus, intents and attempts | 190 | export type SessionEntry = { |
| 191 | seq: number; | |
| 192 | kind: SessionEntryKind; | |
| 193 | text: string; | |
| 194 | /** For tool calls and results. */ | |
| 195 | tool: string | null; | |
| 196 | /** The fork's head commit when this entry was recorded, if known. */ | |
| 197 | commit: string | null; | |
| Work service in Rust, with RFC 3339 timestamps | 198 | /** RFC 3339. */ |
| 199 | at: string; | |
| Initial g1t: services, event bus, intents and attempts | 200 | }; |
| 201 | ||
| 202 | export type NewSessionEntry = Pick<SessionEntry, "kind" | "text"> & | |
| Work service in Rust, with RFC 3339 timestamps | 203 | Partial<Pick<SessionEntry, "tool" | "commit">>; |
| Initial g1t: services, event bus, intents and attempts | 204 | |
| Issues and pull requests replace intents and attempts | 205 | export type IssueDetail = { |
| 206 | issue: Issue; | |
| 207 | /** Every pull request made against it, oldest first. */ | |
| 208 | pulls: Pull[]; | |
| 209 | comments: Comment[]; | |
| 210 | }; | |
| Initial g1t: services, event bus, intents and attempts | 211 | |
| Issues and pull requests replace intents and attempts | 212 | export type PullDetail = { |
| 213 | pull: Pull; | |
| 214 | /** The issue it is for, if any. */ | |
| 215 | issue: Issue | null; | |
| 216 | comments: Comment[]; | |
| Acceptance checks in sandboxes, line comments and review verdicts | 217 | /** The latest run of the issue's acceptance checks. */ |
| 218 | checks: CheckRun | null; | |
| Issues and pull requests replace intents and attempts | 219 | }; |
| Initial g1t: services, event bus, intents and attempts | 220 | |
| Issues and pull requests replace intents and attempts | 221 | export type OpenIssueInput = { |
| 222 | title: string; | |
| 223 | body: string; | |
| 224 | labels?: string[]; | |
| 225 | checks?: string[]; | |
| 226 | }; | |
| 227 | ||
| 228 | export type UpdateIssueInput = { title?: string; body?: string; labels?: string[] }; | |
| 229 | ||
| 230 | export type OpenPullInput = { | |
| 231 | /** The number of the issue this is for. */ | |
| 232 | issue?: number; | |
| 233 | /** Defaults to the issue's title; required without an issue. */ | |
| 234 | title?: string; | |
| Pull requests from branches | 235 | /** What changed and why. Usually set later, when a draft is marked ready. */ |
| 236 | body?: string; | |
| 237 | /** | |
| 238 | * A branch of the repository that already holds the change. The pull | |
| 239 | * request is then ready for review at once and has no fork. | |
| 240 | */ | |
| 241 | branch?: string; | |
| Issues and pull requests replace intents and attempts | 242 | agent: string; |
| 243 | runtime: Runtime; | |
| 244 | }; | |
| Initial g1t: services, event bus, intents and attempts | 245 | |
| Issues and pull requests replace intents and attempts | 246 | /** Issues, pull requests, comments and sessions. */ |
| Work service in Rust, with RFC 3339 timestamps | 247 | export interface WorkApi { |
| Issues and pull requests replace intents and attempts | 248 | openIssue(actor: User, repo: RepoPath, input: OpenIssueInput): Promise<Result<Issue>>; |
| 249 | /** Newest first. */ | |
| 250 | listIssues( | |
| 251 | repo: RepoPath, | |
| 252 | viewer: Viewer, | |
| 253 | filter?: { state?: State; label?: string }, | |
| 254 | ): Promise<Result<Issue[]>>; | |
| 255 | getIssue(repo: RepoPath, number: number, viewer: Viewer): Promise<Result<IssueDetail>>; | |
| 256 | /** The author or a member of the workspace may. */ | |
| 257 | updateIssue(actor: User, repo: RepoPath, number: number, input: UpdateIssueInput): Promise<Result<Issue>>; | |
| 258 | closeIssue(actor: User, repo: RepoPath, number: number, reason?: IssueReason): Promise<Result<Issue>>; | |
| 259 | reopenIssue(actor: User, repo: RepoPath, number: number): Promise<Result<Issue>>; | |
| 260 | /** The default labels, then every other label in use on the repository. */ | |
| 261 | listLabels(repo: RepoPath, viewer: Viewer): Promise<Result<string[]>>; | |
| 262 | /** How many issues and pull requests are open. */ | |
| 263 | counts(repo: RepoPath, viewer: Viewer): Promise<Result<{ issues: number; pulls: number }>>; | |
| Initial g1t: services, event bus, intents and attempts | 264 | |
| Acceptance checks in sandboxes, line comments and review verdicts | 265 | /** |
| 266 | * On an issue or a pull request. On a pull request it may name a line of | |
| 267 | * the change and carry a verdict; nobody can give a verdict on their own. | |
| 268 | */ | |
| 269 | addComment(actor: User, repo: RepoPath, number: number, comment: NewComment): Promise<Result<Comment>>; | |
| 270 | ||
| 271 | /** | |
| 272 | * Begins a run of the acceptance checks for a pull request that is ready | |
| 273 | * for review. For the runner service, which starts the sandbox. | |
| 274 | */ | |
| 275 | startChecks(pullId: string): Promise<Result<CheckJob>>; | |
| 276 | /** | |
| 277 | * What a sandbox says about its run. With no results and no error it has | |
| 278 | * started; `skip` forgets a run that will not be carried out. | |
| 279 | */ | |
| 280 | reportChecks(runId: string, token: string, report: CheckReport): Promise<Result<CheckRun>>; | |
| Issues and pull requests replace intents and attempts | 281 | |
| Pull requests from branches | 282 | /** |
| 283 | * Opens a pull request: a draft with a fork to push to, or, given a | |
| 284 | * branch, one ready for review. | |
| 285 | */ | |
| Issues and pull requests replace intents and attempts | 286 | openPull(actor: User, repo: RepoPath, input: OpenPullInput): Promise<Result<Pull>>; |
| 287 | /** Newest first. */ | |
| 288 | listPulls(repo: RepoPath, viewer: Viewer, state?: State): Promise<Result<Pull[]>>; | |
| 289 | getPull(repo: RepoPath, number: number, viewer: Viewer): Promise<Result<PullDetail>>; | |
| 290 | /** Marks a draft ready for review and sets its description. */ | |
| 291 | readyPull(actor: User, repo: RepoPath, number: number, summary: string): Promise<Result<Pull>>; | |
| 292 | closePull(actor: User, repo: RepoPath, number: number): Promise<Result<Pull>>; | |
| Rust repos service with shipping; pull requests kept in the model | 293 | /** |
| Issues and pull requests replace intents and attempts | 294 | * Lands the pull request on the repository's default branch. Unless |
| 295 | * `keepIssueOpen`, that resolves the issue it was for: the issue closes | |
| 296 | * naming this pull request, and the others still in progress for it close | |
| 297 | * as superseded. Only members of the repository's workspace may merge. | |
| Rust repos service with shipping; pull requests kept in the model | 298 | */ |
| Acceptance checks in sandboxes, line comments and review verdicts | 299 | mergePull( |
| 300 | actor: User, | |
| 301 | repo: RepoPath, | |
| 302 | number: number, | |
| 303 | options?: { | |
| 304 | keepIssueOpen?: boolean; | |
| 305 | /** Merge although the acceptance checks have not passed. */ | |
| 306 | ignoreChecks?: boolean; | |
| 307 | }, | |
| 308 | ): Promise<Result<Pull>>; | |
| Issues and pull requests replace intents and attempts | 309 | /** Drafts and open pull requests the viewer started, most recently active first. */ |
| 310 | listActivePulls(viewer: Viewer): Promise<{ pull: Pull; issue: Issue | null }[]>; | |
| Initial g1t: services, event bus, intents and attempts | 311 | |
| Issues and pull requests replace intents and attempts | 312 | appendSession(actor: User, repo: RepoPath, number: number, entries: NewSessionEntry[]): Promise<Result<{ count: number }>>; |
| 313 | readSession(repo: RepoPath, number: number, viewer: Viewer, afterSeq?: number): Promise<Result<SessionEntry[]>>; | |
| Initial g1t: services, event bus, intents and attempts | 314 | } |
| Pull requests from branches | 315 | |
| 316 | /** | |
| 317 | * What to pass `ReposApi.compare` to see what a pull request changes. | |
| 318 | * | |
| 319 | * A fork is compared as a whole. A branch is compared by name while the | |
| 320 | * pull request is open, and by the commit it was merged or closed at | |
| 321 | * afterwards, so later pushes to the branch do not change the record. | |
| 322 | */ | |
| 323 | export function pullComparison(pull: Pull): { | |
| 324 | repoId: string; | |
| 325 | base: string | null; | |
| 326 | head: string | null; | |
| 327 | } { | |
| 328 | if (pull.forkRepoId) return { repoId: pull.forkRepoId, base: pull.mergeBase, head: null }; | |
| 329 | const settled = pull.status === "merged" || pull.status === "closed"; | |
| 330 | return { | |
| 331 | repoId: pull.repoId, | |
| 332 | base: pull.mergeBase, | |
| 333 | head: (settled && pull.headCommit) || pull.branch, | |
| 334 | }; | |
| 335 | } |