Skip to content
109 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/**
2 * Which frame a page is drawn in, and what the sidebar offers someone who
3 * is not signed in.
4 *
Chat controls, public profiles, shadcn selects, and no Docs tab in a project5 * Someone signed in always gets the app's frame: the rail and its modes.
6 * A visitor gets it on projects, workspaces and not-found pages, where the
7 * sidebar is the project's own menu. g1t's public pages that belong to no
8 * workspace (a person's profile, Explore, Search) are drawn for a visitor
9 * in the public frame instead: the top bar with the mark, search and
10 * signing in, the page at full width, and the footer. So do the front page
11 * and the pages about signing in, paying and trust.
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put12 */
13
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look14import type { Abilities, Capability } from "@g1t/contracts";
15
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put16/** Pages a visitor sees in the marketing frame. */
17const MARKETING = new Set([
18 "/",
19 "/pricing",
20 "/login",
21 "/register",
22 "/logout",
23 "/verify",
Merge email confirmation gate: a code and a link, nothing until confirmed (identity 0036)24 "/confirm-email",
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put25 "/forgot",
26 "/reset",
27 "/device",
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look28 // Who makes g1t, and the promises it keeps: the policies, security,
29 // support and status.
30 "/policies",
31 "/security",
32 "/support",
33 "/status",
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put34 // These send a visitor to sign in; the frame matters only for a moment.
35 "/new",
36 "/settings",
37 "/workspaces/new",
38]);
39
Chat controls, public profiles, shadcn selects, and no Docs tab in a project40/** g1t's public pages that are no workspace's: a visitor reads them in the public frame. */
41const PUBLIC_PAGES = new Set(["/explore", "/search"]);
42
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put43/** Whether the page is drawn in the app's sidebar frame. */
44export function usesAppShell(pathname: string, signedIn: boolean): boolean {
45 if (signedIn) return true;
46 const path = pathname.length > 1 ? pathname.replace(/\/+$/, "") : pathname;
Chat controls, public profiles, shadcn selects, and no Docs tab in a project47 if (MARKETING.has(path) || PUBLIC_PAGES.has(path)) return false;
48 // A person's profile: theirs, not any workspace's.
49 if (/^\/u\/[^/]+$/.test(path)) return false;
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put50 if (path === "/oauth" || path.startsWith("/oauth/")) return false;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look51 // An invite link is the front door: the marketing frame, like /register.
52 if (path.startsWith("/invite/")) return false;
53 if (path.startsWith("/policies/")) return false;
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas54 // Your settings pages, like /settings: a visitor is sent to sign in.
55 if (path.startsWith("/settings/")) return false;
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put56 return true;
57}
58
59export type SidebarItem = { label: string; to: string };
60
61/** The visitor's sidebar menu: where to browse from. */
62export const VISITOR_LINKS: SidebarItem[] = [
63 { label: "Explore", to: "/explore" },
64 { label: "Search", to: "/search" },
65];
66
67/** The project pages the sidebar lists, by key, for a member or not. */
68export type ProjectPage =
69 | "code"
70 | "issues"
71 | "pulls"
72 | "agents"
73 | "actions"
74 | "deployments"
75 | "observability"
76 | "security"
77 | "insights"
78 | "settings";
79
80/**
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look81 * What a page needs beyond a role on the repository, once what the viewer
82 * may do is known: Security's findings are for people who can push.
83 */
84export const PAGE_NEEDS: Partial<Record<ProjectPage, Capability>> = { security: "push" };
85
86/**
87 * A project's menu, in order. Security and Settings are for people with a
88 * role on its repository, and a page in `PAGE_NEEDS` only for those whose
89 * role has its capability (`can`, once the repository's page has loaded);
90 * 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 put91 */
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look92export 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 put93 const pages: (ProjectPage | false)[] = [
94 "code",
95 "issues",
96 "pulls",
97 "agents",
98 "actions",
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look99 // A public repository's deployments and build logs are for anyone, as its code is.
100 "deployments",
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put101 "observability",
102 member && "security",
103 "insights",
104 member && "settings",
105 ];
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look106 return pages.filter(
107 (page): page is ProjectPage => page !== false && (!can || !PAGE_NEEDS[page] || Boolean(can[PAGE_NEEDS[page]!])),
108 );
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put109}

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