pr_01m47d15m3e54sn21z27rpy5n9/packages/contracts/src/work.ts

335 lines11,276 bytesCodeBlame

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

Initial g1t: services, event bus, intents and attempts1import type { User, Viewer } from "./identity";
2import type { RepoPath } from "./repos";
3import type { Result } from "./result";
4
Issues and pull requests replace intents and attempts5/**
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 */
10export type State = "open" | "closed";
11
12/** Why an issue was closed. */
13export type IssueReason = "completed" | "not_planned";
Initial g1t: services, event bus, intents and attempts14
Issues and pull requests replace intents and attempts15/**
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 */
22export type Issue = {
Initial g1t: services, event bus, intents and attempts23 id: string;
24 repoId: string;
Issues and pull requests replace intents and attempts25 /** Shown as `#12`. */
Initial g1t: services, event bus, intents and attempts26 number: number;
27 title: string;
Issues and pull requests replace intents and attempts28 /** 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 attempts32 checks: string[];
Issues and pull requests replace intents and attempts33 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 attempts38 author: User;
Work service in Rust, with RFC 3339 timestamps39 /** RFC 3339. */
40 createdAt: string;
Issues and pull requests replace intents and attempts41 /** 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 attempts48};
49
Issues and pull requests replace intents and attempts50/** `draft` is still being worked on; `open` is ready for review. */
51export type PullStatus = "draft" | "open" | "merged" | "closed";
Initial g1t: services, event bus, intents and attempts52
53/** Where the agent runs: on g1t's sandboxes, or in someone's own session. */
Issues and pull requests replace intents and attempts54export type Runtime = "hosted" | "external";
Initial g1t: services, event bus, intents and attempts55
Pull requests from branches56/**
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 attempts60export type Pull = {
Initial g1t: services, event bus, intents and attempts61 id: string;
62 repoId: string;
Issues and pull requests replace intents and attempts63 /** Shown as `#12`. */
Initial g1t: services, event bus, intents and attempts64 number: number;
Issues and pull requests replace intents and attempts65 /** 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 attempts70 /** A label for the agent doing the work, e.g. `claude-code`. */
71 agent: string;
Issues and pull requests replace intents and attempts72 runtime: Runtime;
73 status: PullStatus;
Pull requests from branches74 /** The fork holding the change, unless it is on a branch. */
75 fork: RepoPath | null;
Diffs on attempts; hosted agent presented as the g1t agent76 /** The fork's repository id. */
Pull requests from branches77 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 attempts80 headCommit: string | null;
Diffs on attempts; hosted agent presented as the g1t agent81 /**
Issues and pull requests replace intents and attempts82 * 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 agent93 */
Issues and pull requests replace intents and attempts94 supersededBy: number | null;
Acceptance checks in sandboxes, line comments and review verdicts95 /**
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 attempts100 author: User;
Work service in Rust, with RFC 3339 timestamps101 /** RFC 3339. */
102 createdAt: string;
103 /** RFC 3339. */
104 updatedAt: string;
Initial g1t: services, event bus, intents and attempts105};
106
Acceptance checks in sandboxes, line comments and review verdicts107/** `queued` waits for a sandbox; `errored` means the checks could not be run. */
108export type CheckStatus = "queued" | "running" | "passed" | "failed" | "errored";
109
110/** How one acceptance check went. */
111export 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 */
125export 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. */
140export 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 attempts146export type Comment = {
147 id: string;
148 author: User;
149 /** Markdown. */
150 body: string;
Acceptance checks in sandboxes, line comments and review verdicts151 /** 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 attempts156 /** RFC 3339. */
157 createdAt: string;
158};
159
Acceptance checks in sandboxes, line comments and review verdicts160export 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. */
169export 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
185export type CheckReport = { results?: CheckResult[]; error?: string; skip?: boolean };
186
Initial g1t: services, event bus, intents and attempts187export type SessionEntryKind = "prompt" | "message" | "tool_call" | "tool_result" | "note";
188
Issues and pull requests replace intents and attempts189/** One step of an agent's session: the "why" behind a pull request's commits. */
Initial g1t: services, event bus, intents and attempts190export 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 timestamps198 /** RFC 3339. */
199 at: string;
Initial g1t: services, event bus, intents and attempts200};
201
202export type NewSessionEntry = Pick<SessionEntry, "kind" | "text"> &
Work service in Rust, with RFC 3339 timestamps203 Partial<Pick<SessionEntry, "tool" | "commit">>;
Initial g1t: services, event bus, intents and attempts204
Issues and pull requests replace intents and attempts205export 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 attempts211
Issues and pull requests replace intents and attempts212export 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 verdicts217 /** The latest run of the issue's acceptance checks. */
218 checks: CheckRun | null;
Issues and pull requests replace intents and attempts219};
Initial g1t: services, event bus, intents and attempts220
Issues and pull requests replace intents and attempts221export type OpenIssueInput = {
222 title: string;
223 body: string;
224 labels?: string[];
225 checks?: string[];
226};
227
228export type UpdateIssueInput = { title?: string; body?: string; labels?: string[] };
229
230export 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 branches235 /** 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 attempts242 agent: string;
243 runtime: Runtime;
244};
Initial g1t: services, event bus, intents and attempts245
Issues and pull requests replace intents and attempts246/** Issues, pull requests, comments and sessions. */
Work service in Rust, with RFC 3339 timestamps247export interface WorkApi {
Issues and pull requests replace intents and attempts248 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 attempts264
Acceptance checks in sandboxes, line comments and review verdicts265 /**
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 attempts281
Pull requests from branches282 /**
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 attempts286 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 model293 /**
Issues and pull requests replace intents and attempts294 * 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 model298 */
Acceptance checks in sandboxes, line comments and review verdicts299 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 attempts309 /** 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 attempts311
Issues and pull requests replace intents and attempts312 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 attempts314}
Pull requests from branches315
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 */
323export 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}