Skip to content
132 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.

Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put1/**
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.2 * Which frame a page is drawn in.
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put3 *
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.4 * - `standalone`: signing in, signing up and choosing a workspace. The
5 * page alone, centred, with the logo and a quiet row of links at the
6 * foot: no header, no sidebar, no dock.
7 * - `app`: someone signed in, everywhere else. The dock, the mode's
8 * sidebar and the page in its panel, always about their current
9 * workspace, even on public pages such as Explore, a profile or another
10 * workspace's public project.
11 * - `public`: a visitor who is not signed in (or has not confirmed their
12 * address yet), on every other page: a plain header with the logo,
13 * Explore, Docs and signing in, the page at full width, and the footer.
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put14 */
15
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look16import type { Abilities, Capability } from "@g1t/contracts";
17
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.18export type Frame = "standalone" | "public" | "app";
19
20/** Pages that are drawn on their own, whoever opens them. */
21const STANDALONE = new Set([
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put22 "/login",
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.23 "/login/two-factor",
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put24 "/register",
25 "/logout",
26 "/verify",
Merge email confirmation gate: a code and a link, nothing until confirmed (identity 0036)27 "/confirm-email",
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put28 "/forgot",
29 "/reset",
30 "/device",
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.31 "/oauth/authorize",
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put32 "/workspaces/new",
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.33 "/integrations/github/setup",
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put34]);
35
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.36/** The page's path without a trailing slash or a click's `.data`. */
37function framePath(pathname: string): string {
38 const path = pathname.replace(/\.data$/, "");
39 return path.length > 1 ? path.replace(/\/+$/, "") : path;
40}
Chat controls, public profiles, shadcn selects, and no Docs tab in a project41
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.42/**
43 * The frame for `pathname`. `viewer` says whether someone is signed in and
44 * confirmed (`signedIn`), and whether they belong to a workspace yet: until
45 * they do, answering an invitation is part of getting started too.
46 */
47export function frameOf(pathname: string, viewer: { signedIn: boolean; workspace: boolean }): Frame {
48 const path = framePath(pathname);
49 if (STANDALONE.has(path)) return "standalone";
50 // An invite link, and signing in with GitHub, are the front door.
51 if (path.startsWith("/invite/") || path === "/auth/github" || path.startsWith("/auth/github/")) return "standalone";
52 if (path === "/invitations" && viewer.signedIn && !viewer.workspace) return "standalone";
53 return viewer.signedIn ? "app" : "public";
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put54}
55
56/** The project pages the sidebar lists, by key, for a member or not. */
57export type ProjectPage =
58 | "code"
59 | "issues"
60 | "pulls"
61 | "agents"
62 | "actions"
63 | "deployments"
64 | "observability"
65 | "security"
66 | "insights"
67 | "settings";
68
69/**
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look70 * What a page needs beyond a role on the repository, once what the viewer
71 * may do is known: Security's findings are for people who can push.
72 */
73export const PAGE_NEEDS: Partial<Record<ProjectPage, Capability>> = { security: "push" };
74
75/**
76 * A project's menu, in order. Security and Settings are for people with a
77 * role on its repository, and a page in `PAGE_NEEDS` only for those whose
78 * role has its capability (`can`, once the repository's page has loaded);
79 * everyone who can see the project sees the rest.
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put80 */
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look81export function projectPages(member: boolean, can?: Partial<Abilities>): ProjectPage[] {
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put82 const pages: (ProjectPage | false)[] = [
83 "code",
84 "issues",
85 "pulls",
86 "agents",
87 "actions",
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look88 // A public repository's deployments and build logs are for anyone, as its code is.
89 "deployments",
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put90 "observability",
91 member && "security",
92 "insights",
93 member && "settings",
94 ];
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look95 return pages.filter(
96 (page): page is ProjectPage => page !== false && (!can || !PAGE_NEEDS[page] || Boolean(can[PAGE_NEEDS[page]!])),
97 );
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put98}
Phones reach every page: each mode's menu from the top bar or by tapping the tab you're on, Docs first in the avatar sheet, a project's pages as a swipeable strip; dialogs as bottom sheets above the keyboard, safe areas, menus kept on screen, 40px targets, touch-visible controls, save bars above the tab bar99
100/**
101 * A project's pages as the phone's strip of tabs under its name names them
102 * (routes/repo/layout.tsx): the sidebar's words, and the paths under the
103 * project at which each is the current one.
104 */
105export const PROJECT_PAGE_LINKS: Record<ProjectPage, { label: string; path: string; also: string[]; soon?: boolean }> = {
106 code: { label: "Code", path: "code", also: ["tree", "blob", "commits", "commit", "branches", "tags", "releases", "compare"] },
107 issues: { label: "Issues", path: "issues", also: ["plans", "milestones", "labels"] },
108 pulls: { label: "Pull requests", path: "pulls", also: ["pull", "queue"] },
109 agents: { label: "Agents", path: "agents", also: ["sessions", "memory"] },
110 actions: { label: "Workflows", path: "actions", also: [] },
111 deployments: { label: "Deployments", path: "deployments", also: [] },
112 observability: { label: "Observability", path: "soon/logs", also: [], soon: true },
113 security: { label: "Security", path: "security", also: [] },
114 insights: { label: "Insights", path: "contributors", also: ["activity", "stargazers"] },
115 settings: { label: "Settings", path: "settings", also: [] },
116};
117
118/**
119 * Which of a project's pages `rest` (the path under the project, no
120 * leading slash) is on: "overview" for the project itself. `soon` says
121 * which page a roadmap page (`soon/<key>`) sits under.
122 */
123export function projectPageAt(rest: string, soon: Record<string, ProjectPage> = {}): ProjectPage | "overview" | null {
124 const path = rest.replace(/^\/+|\/+$/g, "");
125 if (path === "") return "overview";
126 const soonKey = /^soon\/([^/]+)/.exec(path)?.[1];
127 if (soonKey && soon[soonKey]) return soon[soonKey]!;
128 for (const [page, link] of Object.entries(PROJECT_PAGE_LINKS) as [ProjectPage, (typeof PROJECT_PAGE_LINKS)[ProjectPage]][]) {
129 if ([link.path, ...link.also].some((prefix) => path === prefix || path.startsWith(`${prefix}/`))) return page;
130 }
131 return null;
132}

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