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.
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 1 | import type { ServiceBinding } from "./clients"; |
| 2 | import type { User } from "./identity"; | |
| 3 | import type { Result } from "./result"; | |
| 4 | ||
| 5 | /** | |
| 6 | * GitHub: signing in with a GitHub account, and bringing repositories | |
| 7 | * across through g1t's GitHub App. Mirrors `crates/contracts/src/github.rs`. | |
| 8 | * | |
| 9 | * The identity service keeps linked accounts and their user tokens; the | |
| Merge main into rm-agents: mirroring removal, open signups, free-tier limits, the g1t CLI and runner fixes, with the agent removal kept. The CLI's table of operations is regenerated from the API without the agent, customize and AI credit operations; no CLI command used them. | 10 | * integrations service keeps installations, the repositories imported |
| 11 | * through them and the app's webhook. With no app configured, `enabled`/`configured` are false | |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 12 | * and the site shows no GitHub buttons. |
| 13 | */ | |
| 14 | ||
| 15 | export type GithubPurpose = "sign_in" | "link"; | |
| 16 | ||
| 17 | /** How a return from GitHub ended. */ | |
| 18 | export type GithubFinished = | |
| Merge main (membership, two-factor, GitHub repo roles) into tokens | 19 | | { |
| 20 | kind: "signed_in"; | |
| 21 | /** `twoFactorChallenge` is set, and `sessionToken` empty, while the account's two-factor code is still to come. */ | |
| 22 | signedIn: { user: User; sessionToken: string; twoFactorChallenge?: string | null }; | |
| 23 | created: boolean; | |
| 24 | next: string; | |
| 25 | } | |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 26 | | { kind: "linked"; login: string; next: string } |
| 27 | /** An account has one of its verified emails: sign in to it, then claim. */ | |
| 28 | | { kind: "needs_link"; pending: string; login: string; next: string } | |
| Merge main into rm-agents: mirroring removal, open signups, free-tier limits, the g1t CLI and runner fixes, with the agent removal kept. The CLI's table of operations is regenerated from the API without the agent, customize and AI credit operations; no CLI command used them. | 29 | /** A new account waiting on a username. */ |
| 30 | | { kind: "needs_username"; pending: string; login: string; suggestion: string; next: string }; | |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 31 | |
| 32 | export type GithubPending = { | |
| 33 | login: string; | |
| 34 | kind: "link" | "username"; | |
| 35 | suggestion: string | null; | |
| 36 | next: string; | |
| 37 | }; | |
| 38 | ||
| 39 | export type GithubAccount = { | |
| 40 | githubId: number; | |
| 41 | login: string; | |
| 42 | linkedAt: string; | |
| 43 | /** Whether g1t holds a working user token for it. */ | |
| 44 | authorized: boolean; | |
| 45 | }; | |
| 46 | ||
| 47 | export type GithubAccountView = { | |
| 48 | enabled: boolean; | |
| 49 | account: GithubAccount | null; | |
| 50 | hasPassword: boolean; | |
| 51 | }; | |
| 52 | ||
| 53 | export type GithubInstallation = { | |
| 54 | id: number; | |
| 55 | workspace: string; | |
| 56 | account: string; | |
| 57 | accountType: string; | |
| 58 | repositorySelection: "all" | "selected" | string; | |
| 59 | suspended: boolean; | |
| 60 | settingsUrl: string; | |
| 61 | createdAt: string; | |
| 62 | }; | |
| 63 | ||
| A GitHub App installed straight on GitHub can be added to a workspace: Import from GitHub lists the installations your GitHub account can see that this workspace hasn't added, each with Add for owners, and coming back from GitHub without g1t's own start asks which of your workspaces to add it to instead of stopping; the GitHub guide says how. | 64 | /** |
| 65 | * An installation of the app the person's own GitHub account can see, | |
| 66 | * from `github_visible_installations`: how one installed on GitHub | |
| 67 | * directly is found and added to a workspace. | |
| 68 | */ | |
| 69 | export type GithubVisibleInstallation = { | |
| 70 | id: number; | |
| 71 | account: string; | |
| 72 | accountType: string; | |
| 73 | repositorySelection: "all" | "selected" | string; | |
| 74 | suspended: boolean; | |
| 75 | settingsUrl: string; | |
| 76 | /** The person's workspaces it is recorded in already. */ | |
| 77 | recordedIn: string[]; | |
| 78 | }; | |
| 79 | ||
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 80 | export type GithubAppStatus = { |
| 81 | configured: boolean; | |
| 82 | installUrl: string | null; | |
| 83 | linked: boolean; | |
| 84 | installations: GithubInstallation[]; | |
| 85 | }; | |
| 86 | ||
| 87 | export type GithubRepository = { | |
| 88 | id: number; | |
| 89 | fullName: string; | |
| 90 | name: string; | |
| 91 | private: boolean; | |
| 92 | description: string | null; | |
| 93 | defaultBranch: string; | |
| Merge main into rm-agents: mirroring removal, open signups, free-tier limits, the g1t CLI and runner fixes, with the agent removal kept. The CLI's table of operations is regenerated from the API without the agent, customize and AI credit operations; no CLI command used them. | 94 | /** The g1t repository already imported from it, as `workspace/name`. */ |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 95 | linkedTo: string | null; |
| 96 | }; | |
| 97 | ||
| 98 | export type GithubRepositories = { | |
| 99 | repositories: GithubRepository[]; | |
| 100 | total: number; | |
| 101 | page: number; | |
| 102 | perPage: number; | |
| 103 | }; | |
| 104 | ||
| Merge main into rm-agents: mirroring removal, open signups, free-tier limits, the g1t CLI and runner fixes, with the agent removal kept. The CLI's table of operations is regenerated from the API without the agent, customize and AI credit operations; no CLI command used them. | 105 | /** Where a g1t repository was imported from on GitHub. The import is copied once: the g1t repository is then its own. */ |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 106 | export type GithubRepoLink = { |
| 107 | repoId: string; | |
| 108 | repo: string; | |
| 109 | installationId: number; | |
| 110 | githubRepoId: number; | |
| 111 | fullName: string; | |
| Merge main into rm-agents: mirroring removal, open signups, free-tier limits, the g1t CLI and runner fixes, with the agent removal kept. The CLI's table of operations is regenerated from the API without the agent, customize and AI credit operations; no CLI command used them. | 112 | /** RFC 3339: when it was imported. */ |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 113 | syncedAt: string | null; |
| 114 | lastError: string | null; | |
| 115 | issuesImported: number; | |
| 116 | }; | |
| 117 | ||
| 118 | export type GithubImportInput = { | |
| 119 | installationId: number; | |
| 120 | githubRepoId: number; | |
| 121 | name?: string; | |
| 122 | private?: boolean; | |
| 123 | issues: boolean; | |
| 124 | }; | |
| 125 | ||
| 126 | async function rpc<T>(service: ServiceBinding, method: string, args: object): Promise<T> { | |
| 127 | const response = await service.fetch(`https://service/rpc/${method}`, { | |
| 128 | method: "POST", | |
| 129 | headers: { "content-type": "application/json" }, | |
| 130 | body: JSON.stringify(args), | |
| 131 | }); | |
| 132 | if (!response.ok) throw new Error(`${method} failed with status ${response.status}`); | |
| 133 | return (await response.json()) as T; | |
| 134 | } | |
| 135 | ||
| 136 | /** Signing in with GitHub: methods of the identity service. */ | |
| 137 | export function githubSignInClient(identity: ServiceBinding) { | |
| 138 | const call = <T>(method: string, args: object) => rpc<T>(identity, method, args); | |
| 139 | return { | |
| 140 | enabled: () => call<boolean>("github_enabled", {}), | |
| 141 | start: (input: { purpose: GithubPurpose; user?: User | null; redirectUri: string; next: string; inviteCode?: string | null }) => | |
| 142 | call<Result<{ authorizeUrl: string; state: string }>>("github_start", input), | |
| 143 | finish: (state: string, code: string) => call<Result<GithubFinished>>("github_finish", { state, code }), | |
| 144 | pending: (pending: string) => call<Result<GithubPending>>("github_pending", { pending }), | |
| Merge main into rm-agents: mirroring removal, open signups, free-tier limits, the g1t CLI and runner fixes, with the agent removal kept. The CLI's table of operations is regenerated from the API without the agent, customize and AI credit operations; no CLI command used them. | 145 | signUp: (pending: string, username: string) => |
| 146 | call<Result<{ user: User; sessionToken: string }>>("github_sign_up", { pending, username }), | |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 147 | claim: (pending: string, user: User) => call<Result<GithubAccount>>("github_claim", { pending, user }), |
| 148 | account: (user: User) => call<GithubAccountView>("github_account", { user }), | |
| 149 | unlink: (user: User) => call<Result<boolean>>("github_unlink", { user }), | |
| 150 | }; | |
| 151 | } | |
| 152 | ||
| 153 | /** g1t's GitHub App: methods of the integrations service. */ | |
| 154 | export function githubAppClient(integrations: ServiceBinding) { | |
| 155 | const call = <T>(method: string, args: object) => rpc<T>(integrations, method, args); | |
| 156 | return { | |
| 157 | status: (viewer: User, workspace: string) => call<Result<GithubAppStatus>>("github_status", { viewer, workspace }), | |
| 158 | addInstallation: (actor: User, workspace: string, installationId: number) => | |
| 159 | call<Result<GithubInstallation>>("github_add_installation", { actor, workspace, installationId }), | |
| A GitHub App installed straight on GitHub can be added to a workspace: Import from GitHub lists the installations your GitHub account can see that this workspace hasn't added, each with Add for owners, and coming back from GitHub without g1t's own start asks which of your workspaces to add it to instead of stopping; the GitHub guide says how. | 160 | visibleInstallations: (actor: User) => call<Result<GithubVisibleInstallation[]>>("github_visible_installations", { actor }), |
| Checkout tries a failed fetch twice more, after 2 s and 5 s | 161 | removeInstallation: (actor: User, workspace: string, installationId: number) => |
| 162 | call<Result<boolean>>("github_remove_installation", { actor, workspace, installationId }), | |
| 163 | repositories: (actor: User, workspace: string, installationId: number, page?: number) => | |
| 164 | call<Result<GithubRepositories>>("github_repositories", { actor, workspace, installationId, page: page ?? null }), | |
| 165 | import: (actor: User, workspace: string, input: GithubImportInput) => | |
| 166 | call<Result<GithubRepoLink>>("github_import", { actor, workspace, ...input }), | |
| 167 | link: (repoId: string) => call<GithubRepoLink | null>("github_link", { repoId }), | |
| 168 | }; | |
| 169 | } |
This file's history is long; its oldest lines are credited to the oldest commit read.