Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh
233 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.

The sidebar asks billing whether it is on, not for the account, so no page waits on the card processor1import type { User, Viewer } from "./identity";
2import type { RepoPath } from "./repos";
3import type { Result } from "./result";
4
5/**
6 * Projects: the thing a workspace builds and runs. A project has exactly
7 * one source, where its code lives; everything about running it
8 * (deployments, environments, domains, secrets and variables) belongs to
9 * the project, while branches, pull requests and review stay with the
10 * repository. One repository may carry several projects, each from its own
11 * root directory. Every repository on g1t gets a project of its own name.
12 */
13
14/** Where a project's code lives. */
15export type ProjectSource =
16 /** A repository hosted on g1t. */
17 | { kind: "hosted"; repoId: string; repo: RepoPath; rootDir: string; defaultBranch: string }
18 /** Mirrored from another host; coming next. */
19 | { kind: "mirror"; provider: "github" | "gitlab" | "bitbucket"; url: string; rootDir: string };
20
21export type Project = {
22 id: string;
23 /** The workspace's slug. */
24 workspace: string;
25 /** Unique in its workspace; the project's address is `g1t.sh/<workspace>/<slug>`. */
26 slug: string;
27 name: string;
28 /** The project's own description, or its repository's while it has none. */
29 description: string | null;
30 /** Whether `description` is its repository's, following it as it changes. */
31 descriptionInherited: boolean;
32 source: ProjectSource;
33 /** Whether its repository is private: only people with a role on it can see it. */
34 private: boolean;
35 /** Whether its repository is archived: read-only, kept for reference. */
36 archived: boolean;
37 /** Whether it is the project its repository's workflows read secrets from. */
38 primary: boolean;
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9739 /** What a person set it to be; each part null while it is left to detection. */
40 setting: ProjectSetting;
41 /** What it is: from `setting`, or for what is left out, from its deployments, packages and files. */
A project is an app or a library: libraries show their package and how to ship a release, not production42 kind: ProjectKind;
43 /** Why it is that kind. */
44 kindReason: KindReason;
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9745 /**
46 * Where it runs: `g1t` when g1t deploys it (Deployments, on g1t.page),
47 * `elsewhere` when it is deployed by other means, at `productionUrl`.
48 * Null for what is not deployed (a library, a tool) and for an app nobody
49 * has said yet while Deployments are off.
50 */
51 runs: ProjectRuns | null;
52 /** Where production is when it runs elsewhere; null when nobody has given one. */
53 productionUrl: string | null;
Merge branch 'worktree-agent-a5b0d9e2733e9e382'54 /**
55 * An image of production someone uploaded, shown on its overview when
56 * there is no screenshot, or instead of one when `preferred`. Null when
57 * none was uploaded.
58 */
59 productionImage: ProductionImage | null;
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9760 /** What detection decides, whatever the setting is, to show beside it. */
A project is an app or a library: libraries show their package and how to ship a release, not production61 detected: { kind: ProjectKind; reason: KindReason };
62 /** The ecosystem its files say it publishes to, for how to publish; null when none says. */
63 ecosystem: ProjectEcosystem | null;
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9764 /** Its homepage, docs and other links, shown wherever the project is. */
65 links: ProjectLinks;
The sidebar asks billing whether it is on, not for the account, so no page waits on the card processor66 createdBy: string;
67 /** RFC 3339. */
68 createdAt: string;
69 updatedAt: string;
Projects: when each was last pushed, and how active it is lately70 /** RFC 3339: when its repository was last pushed to; null until it is, after projects began keeping it. */
71 pushedAt: string | null;
72 /**
73 * How active it is lately: each push, issue or pull request opened or
74 * closed, review, comment and deployment counts one, halving every week.
75 * 0 for none.
76 */
77 activity: number;
The sidebar asks billing whether it is on, not for the account, so no page waits on the card processor78};
79
A project is an app or a library: libraries show their package and how to ship a release, not production80/**
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9781 * What a project is. An app (or a site) runs somewhere and gets a
82 * production card; a library is published and installed; a tool, such as
83 * a CLI, ships as releases people install; docs are documentation or site
84 * content; other is anything else, such as configuration or research.
A project is an app or a library: libraries show their package and how to ship a release, not production85 */
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9786export type ProjectKind = "app" | "library" | "tool" | "docs" | "other";
A project is an app or a library: libraries show their package and how to ship a release, not production87
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9788/** Every kind, in the order pages offer them. */
89export const PROJECT_KINDS: readonly ProjectKind[] = ["app", "library", "tool", "docs", "other"];
90
91/** Where an app or a site runs: deployed by g1t on g1t.page, or deployed by other means. */
92export type ProjectRuns = "g1t" | "elsewhere";
93
94/** What a person set; null for each part left to detection. */
95export type ProjectSetting = { kind: ProjectKind | null; runs: ProjectRuns | null };
96
97/** One of a project's own links: a label and an http(s) address. */
98export type ProjectLink = { label: string; url: string };
99
100export type ProjectLinks = {
101 /** Its homepage: its own, or its repository's website while it has none. */
102 homepage: string | null;
103 /** Whether `homepage` is its repository's website, following it as it changes. */
104 homepageInherited: boolean;
105 /** Where its documentation is read. */
106 docs: string | null;
107 /** Any others, in the order given, at most `MAX_PROJECT_LINKS`. */
108 custom: ProjectLink[];
109};
110
Merge branch 'worktree-agent-a5b0d9e2733e9e382'111/**
112 * An uploaded image of a project's production. `file` is the SHA-256 of
113 * its bytes: it is served from the usercontent origin at
114 * `/production-images/<file>`.
115 */
116export type ProductionImage = { file: string; contentType: string; preferred: boolean };
117
118/** The largest production image taken, in bytes. */
119export const MAX_PRODUCTION_IMAGE_BYTES = 5 * 1024 * 1024;
120
121/** The types a production image may be, read from its bytes. */
122export const PRODUCTION_IMAGE_TYPES: readonly string[] = ["image/png", "image/jpeg", "image/webp"];
123
124/**
125 * A change to a project's production image. `image` is the new one's bytes
126 * in base64, or null to remove it (and with it the preference); left out,
127 * it stays. `preferred` shows it instead of a screenshot.
128 */
129export type ProductionImageChange = { image?: string | null; preferred?: boolean };
130
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97131/** How many links of its own a project keeps besides its homepage and docs. */
132export const MAX_PROJECT_LINKS = 10;
133/** The longest link label. */
134export const MAX_LINK_LABEL = 40;
135/** The longest link address. */
136export const MAX_LINK_URL = 255;
137
138/** A change to a project; only what is given changes. */
139export type ProjectChanges = {
140 name?: string;
141 /** Null or blank goes back to the repository's. */
142 description?: string | null;
143 rootDir?: string;
144 /** What it is; `auto` leaves it to detection. Anything but an app or docs stops it running anywhere. */
145 kind?: ProjectKind | "auto";
146 /** Where it runs; `auto` leaves it to Deployments. Setting it makes it an app unless it is docs. */
147 runs?: ProjectRuns | "auto";
148 /** Production's address when it runs elsewhere; null or blank clears it. */
149 productionUrl?: string | null;
150 /** Null or blank goes back to the repository's website. */
151 homepage?: string | null;
152 /** Null or blank clears it. */
153 docsUrl?: string | null;
154 /** Replaces its other links. */
155 links?: ProjectLink[];
156};
157
A project is an app or a library: libraries show their package and how to ship a release, not production158/**
159 * What decided the kind: the setting, Deployments being on, a package its
160 * repository publishes, its files, or nothing (an app, by default).
161 * `detail` says it in a sentence.
162 */
163export type KindReason = { by: "set" | "deployments" | "packages" | "files" | "default"; detail: string };
164
165/** Where a library's files say it is published. */
166export type ProjectEcosystem = "composer" | "npm" | "cargo" | "go" | "python";
167
The sidebar asks billing whether it is on, not for the account, so no page waits on the card processor168export type NewProject = {
169 name: string;
170 description?: string | null;
171 /** The hosted repository it builds from. */
172 repo: RepoPath;
173 /** Where in the repository it lives; empty for the whole repository. */
174 rootDir?: string;
175};
176
Projects: pinned and recent projects, per person per workspace177/**
178 * What a person keeps at hand in a workspace: the projects they pinned, in
179 * their order, then the ones they opened last that they have not pinned.
180 * Only projects they can still see.
181 */
182export type ProjectShortcuts = { pinned: Project[]; recent: Project[] };
183
The sidebar asks billing whether it is on, not for the account, so no page waits on the card processor184export interface ProjectsApi {
185 /** A workspace's projects, by name. Members, or anyone for public repositories. */
186 list(workspace: string, viewer: Viewer): Promise<Result<Project[]>>;
187 get(workspace: string, slug: string, viewer: Viewer): Promise<Result<Project>>;
188 /** The projects built from a repository, its primary one first. For services. */
189 byRepo(repoId: string): Promise<Project[]>;
190 /** Members only. */
191 create(actor: User, workspace: string, input: NewProject): Promise<Result<Project>>;
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97192 /**
193 * Members with a role that may change its settings. Making it something
194 * that does not run (a library, a tool, other) while Deployments are on
195 * is refused: they are turned off first.
196 */
197 update(actor: User, workspace: string, slug: string, changes: ProjectChanges): Promise<Result<Project>>;
Merge branch 'worktree-agent-a5b0d9e2733e9e382'198 /**
199 * Uploads, replaces or removes its production image, or says whether it
200 * is shown instead of a screenshot. Whoever may change the project's
201 * settings, as for its production address.
202 */
203 setProductionImage(actor: User, workspace: string, slug: string, change: ProductionImageChange): Promise<Result<Project>>;
204 /**
205 * For the screenshot service's daily refresh: every production address
206 * of a project deployed elsewhere that shows a screenshot (not an
207 * uploaded image instead), once each.
208 */
209 externalProductions(): Promise<string[]>;
A project is an app or a library: libraries show their package and how to ship a release, not production210 /** For deployments: Deployments were turned on or off for the project. */
211 deploymentsChanged(projectId: string, enabled: boolean): Promise<void>;
Projects: pinned and recent projects, per person per workspace212 /** A person's pinned and recent projects in a workspace. Empty for anyone else. */
213 shortcuts(workspace: string, viewer: Viewer): Promise<ProjectShortcuts>;
214 /**
215 * Pins a project the person can see, at `position` (0 first) or at the
216 * end; pinning one already pinned moves it. A person's own, at most 8 a
217 * workspace. Returns their pins, in order.
218 */
219 pin(actor: User, workspace: string, slug: string, position?: number | null): Promise<Result<Project[]>>;
220 /** Unpins it. Returns their pins, in order. */
221 unpin(actor: User, workspace: string, slug: string): Promise<Result<Project[]>>;
222 /** Puts their pins in this order: every pinned project's slug, once. */
223 reorderPins(actor: User, workspace: string, slugs: string[]): Promise<Result<Project[]>>;
224 /** The person opened the project: it leads their recent ones. */
225 visited(actor: User, projectId: string): Promise<void>;
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97226 /**
227 * For lists of public repositories, such as Explore: each one's own
228 * project's address to show, by `namespace/name` in lower case:
229 * production when it is deployed elsewhere, else its homepage, else its
230 * docs. Repositories without one are left out. At most 100 asked at once.
231 */
232 publicLinks(repos: RepoPath[]): Promise<Record<string, string>>;
The sidebar asks billing whether it is on, not for the account, so no page waits on the card processor233}

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