Skip to content
102 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 *
5 * g1t is a sidebar site: projects, Explore, Search, profiles and
6 * not-found pages are drawn in the app's sidebar for everyone, so a
7 * visitor browsing public projects finds their way the same as a member.
8 * Only the front page and the pages about signing in or paying keep the
9 * marketing header and footer.
10 */
11
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look12import type { Abilities, Capability } from "@g1t/contracts";
13
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put14/** Pages a visitor sees in the marketing frame. */
15const MARKETING = new Set([
16 "/",
17 "/pricing",
18 "/login",
19 "/register",
20 "/logout",
21 "/verify",
Merge email confirmation gate: a code and a link, nothing until confirmed (identity 0036)22 "/confirm-email",
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put23 "/forgot",
24 "/reset",
25 "/device",
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look26 // Who makes g1t, and the promises it keeps: the policies, security,
27 // support and status.
28 "/policies",
29 "/security",
30 "/support",
31 "/status",
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put32 // These send a visitor to sign in; the frame matters only for a moment.
33 "/new",
34 "/settings",
35 "/workspaces/new",
36]);
37
38/** Whether the page is drawn in the app's sidebar frame. */
39export function usesAppShell(pathname: string, signedIn: boolean): boolean {
40 if (signedIn) return true;
41 const path = pathname.length > 1 ? pathname.replace(/\/+$/, "") : pathname;
42 if (MARKETING.has(path)) return false;
43 if (path === "/oauth" || path.startsWith("/oauth/")) return false;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look44 // An invite link is the front door: the marketing frame, like /register.
45 if (path.startsWith("/invite/")) return false;
46 if (path.startsWith("/policies/")) return false;
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas47 // Your settings pages, like /settings: a visitor is sent to sign in.
48 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 put49 return true;
50}
51
52export type SidebarItem = { label: string; to: string };
53
54/** The visitor's sidebar menu: where to browse from. */
55export const VISITOR_LINKS: SidebarItem[] = [
56 { label: "Explore", to: "/explore" },
57 { label: "Search", to: "/search" },
58];
59
60/** The project pages the sidebar lists, by key, for a member or not. */
61export type ProjectPage =
62 | "code"
63 | "issues"
64 | "pulls"
65 | "agents"
66 | "actions"
67 | "deployments"
68 | "observability"
69 | "security"
70 | "insights"
71 | "settings";
72
73/**
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look74 * What a page needs beyond a role on the repository, once what the viewer
75 * may do is known: Security's findings are for people who can push.
76 */
77export const PAGE_NEEDS: Partial<Record<ProjectPage, Capability>> = { security: "push" };
78
79/**
80 * A project's menu, in order. Security and Settings are for people with a
81 * role on its repository, and a page in `PAGE_NEEDS` only for those whose
82 * role has its capability (`can`, once the repository's page has loaded);
83 * 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 put84 */
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look85export 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 put86 const pages: (ProjectPage | false)[] = [
87 "code",
88 "issues",
89 "pulls",
90 "agents",
91 "actions",
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look92 // A public repository's deployments and build logs are for anyone, as its code is.
93 "deployments",
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put94 "observability",
95 member && "security",
96 "insights",
97 member && "settings",
98 ];
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look99 return pages.filter(
100 (page): page is ProjectPage => page !== false && (!can || !PAGE_NEEDS[page] || Boolean(can[PAGE_NEEDS[page]!])),
101 );
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put102}

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