Skip to content
2,168 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 front page is Home: where you're needed comes first, however long ago it started, with what's at stake and how long it has waited; then what happened since you were last here, in words, with the agent work that settled, what landed, what deployed, what was decided and what was spent, switchable to the last 24 hours or 7 days; then what's running now. Your last visit is kept with your account, so it's the same on every device; Today's old address leads here. The home guide says how.1import { Activity, BarChart3, Building2, MessagesSquare, Bell, BookMarked, BookOpen, Bookmark, Blocks, Bot, Box, Check, ChevronDown, ChevronLeft, ChevronRight, CircleDot, GripVertical, CircleUserRound, Code2, Coins, Compass, CreditCard, Fingerprint, GanttChart, Gauge, GitBranch, GitPullRequest, Globe, History, KanbanSquare, Keyboard, KeyRound, Layers, LayoutDashboard, LayoutGrid, LifeBuoy, ListTree, Lock, LogOut, Mail, Network, Package, PanelLeft, PlayCircle, Plug, Plus, Rocket, Search, ServerCog, Settings, Shapes, ShieldCheck, Scale, Smile, Sparkles, Store, House, Ticket, TrendingUp, UserPlus, UserRoundKey, Users, UsersRound, Webhook, X, ArrowLeftRight } from "lucide-react";
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.2import { Fragment, type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from "react";
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar3import { Link, NavLink, useFetcher, useLocation, useNavigation, useRouteLoaderData, useSubmit } from "react-router";
Usage while free is shown at cost; agents get rustfmt and clippy4
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers5import { type Abilities, type ChatSidebarEntry, type InboxCounts, type WorkspaceAgent, type Membership, type Spike, type User, hasCodeAccess, mayCreateTeams, shownUsername } from "@g1t/contracts";
Usage while free is shown at cost; agents get rustfmt and clippy6
Not found and error pages have one main landmark: their own when signed out, the shell's when signed in7import { InMain } from "./landmark";
Usage, Billing settings and prepaid AI credit; fixes from the UX audit8import { CommandPalette, type PaletteCommand, PaletteKey, usePaletteShortcut } from "./command-palette";
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.9import { NotificationsBell } from "./inbox";
The Spend page says what a workspace spent, where it went and the budgets that hold it, in Workspace under Money: spent at price, agents' spend and the spend limit; by day; by agent, person, channel, model, kind of work and product; budgets from the workspace down to each person, agent and task, with what happens at 100%; the costliest tasks, each with a receipt of every session at the provider's price and what was charged; and how it's priced. Everyone sees what agents spent for them, and owners and billing managers the whole workspace; each person can have a monthly budget agents keep to, and the spend pill in the top bar shows your month or the workspace's against its limit. The spend guide says how.10import { SpendPill } from "./spend";
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar11import { PinButton } from "./pin-button";
Merge branch 'worktree-agent-ae1299e92e4462012'12import { Hint } from "./ui/hint";
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.13import { Sheet, SheetContent, SheetTitle } from "./ui/sheet";
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas14import { StatusDot, useSiteStatus } from "./footer";
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.15import { Logo, MarkGlyph } from "./logo";
Usage, Billing settings and prepaid AI credit; fixes from the UX audit16import { Avatar, SoonPill } from "./ui";
Fast pages, required checks on the branch, self-hosted runners, honest incidents17import { Skeleton } from "./ui/skeleton";
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.18import { Button } from "./ui/button";
19import { Separator } from "./ui/separator";
20import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from "./ui/breadcrumb";
Usage while free is shown at cost; agents get rustfmt and clippy21import {
22 DropdownMenu,
23 DropdownMenuContent,
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas24 DropdownMenuGroup,
Usage while free is shown at cost; agents get rustfmt and clippy25 DropdownMenuItem,
26 DropdownMenuLabel,
27 DropdownMenuSeparator,
28 DropdownMenuTrigger,
29} from "./ui/dropdown-menu";
Merge branch 'worktree-agent-ad7c6d88d93adc817'30import { type RoadmapItem, roadmapIn, roadmapItem } from "../lib/roadmap";
The front page is Home: where you're needed comes first, however long ago it started, with what's at stake and how long it has waited; then what happened since you were last here, in words, with the agent work that settled, what landed, what deployed, what was decided and what was spent, switchable to the last 24 hours or 7 days; then what's running now. Your last visit is kept with your account, so it's the same on every device; Today's old address leads here. The home guide says how.31import { type ModeKey, SETTINGS_PAGES, homePagePath, modeOf } from "../lib/workspace-nav";
Chat and workspace agents: channels, DMs and named agents you talk to32import { AgentsSidebar } from "./agents-mode";
33import { ChatSidebar } from "./chat/sidebar";
Artifacts is a mode in the rail, the shell and the phone's tab bar in place of Docs: its home lists everything you can open by day or as cards under All, Yours and Shared with you, with search, filters and tiles to start a doc (slides, designs and dashboards say they are coming soon), and its sidebar holds favorites, spaces, Private, Shared, projects' docs and the trash.34import { FoliosSidebar } from "./folios/sidebar";
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.35import { Dock, ShortcutsDialog, WorkspaceSwitcher, sidebarKeyLabel } from "./dock";
36import { BottomBar, isConversation, useVisualViewport } from "./mobile";
Chat and workspace agents: channels, DMs and named agents you talk to37import { useChatSidebar } from "./chat/actions";
38import { unreadTotals } from "../lib/chat";
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look39import { SETTINGS_CAPABILITY, type ViewerAccess, seesSettings } from "../lib/access";
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.40import { projectPages } from "../lib/chrome";
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas41import { ACCOUNT_SETTINGS, type AccountSettingsPage, FIRST_SETTINGS_PAGE, accountSettingsPage } from "../lib/account-settings";
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.42import { type PinnableApp, sidebarCookie } from "../lib/apps";
43import { REASON_FILTERS, inboxReason, inboxView } from "../lib/inbox";
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas44import { GithubMark } from "./github";
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.45import { useInviteOnly } from "../lib/registration";
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas46import { STATUS_URL, statusTitle } from "../lib/status";
Navigation: the workspace's own page with tabs, pins and recent in the sidebar47import { type ShortcutProject, movedPin, recentWith } from "../lib/pins";
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas48import type { AccountMenuData } from "../routes/settings-menu-json";
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)49import { useLiveBadges } from "../lib/notify-client";
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers50import { OwnPresenceDot, OwnPresenceItems, StatusDialog } from "./presence";
You choose how g1t looks: Auto follows your system, Light and Dark stay put, set from the account menu, the phone's You and help sheet, Settings → Account or the command palette; the page is drawn in your choice from the first byte, every colour has a light value that reads at 4.5:1 or better, code and diffs are highlighted for both, diagrams and the document editor follow along, the product tour and the g1t mark's avatar stay dark, and Dark is what you see until you choose; the workspaces guide says how.51import { THEME_COMMANDS, ThemeMenuSwitch } from "./theme-switch";
Usage while free is shown at cost; agents get rustfmt and clippy52
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put53/**
54 * What the sidebar needs, worked out by the root loader. For a visitor who
55 * is not signed in there is no workspace, no projects and no usage: only
56 * the project being looked at, if they can see it.
57 */
Usage while free is shown at cost; agents get rustfmt and clippy58export type ShellData = {
59 /** The workspace the sidebar is about: the one being looked at, or their first. */
Workspace names and icons, and a component kit for every control60 workspace: Membership | null;
Navigation: the workspace's own page with tabs, pins and recent in the sidebar61 /** All its projects, by name, for the palette: `name` is the slug in their address. */
62 repos: ShortcutProject[];
63 /** The person's pinned projects in it, in their order (lib/pins.ts). */
64 pinned?: ShortcutProject[];
65 /** What they opened there last, latest first, leaving out the pinned. */
66 recent?: ShortcutProject[];
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look67 /** Repositories shared with them in workspaces they do not belong to. */
68 shared?: { namespace: string; name: string; isPrivate: boolean }[];
Projects: what a workspace builds and runs, first on every page69 /** The project being looked at, if any, whoever owns it. */
Usage while free is shown at cost; agents get rustfmt and clippy70 repo: {
71 namespace: string;
72 name: string;
73 member: boolean;
74 issues: number;
75 pulls: number;
76 } | null;
Billing accounts, terms and enterprises; g1t is no longer free77 /** Where the workspace stands against its usage limit, if billing is on. */
78 limit: {
79 exposureMicros: number;
80 ceilingMicros: number | null;
81 state: "ok" | "warning" | "stopped";
82 comped: boolean;
83 } | null;
Usage while free is shown at cost; agents get rustfmt and clippy84 /** Whether g1t charges nothing for now, while it is being built out. */
85 free?: boolean;
86 /** What its agents have cost since the start of the month. */
87 /** This month's usage: charged, or at cost while g1t is free. */
88 monthUsageMicros: number | null;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look89 /** Whether new compute is paused (a spend spike or a hold), and whether the viewer can answer it. */
90 compute?: { paused: string | null; spike: Spike | null; owner: boolean } | null;
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.91 /** What is unread in their notifications, for the dock and the bell. Absent for a visitor. */
Inbox: a bell in the top bar opens it beside the page, and /inbox holds it all92 inbox?: InboxCounts | null;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)93 /**
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.94 * Chat, for the dock's badge: what is unread, and the
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)95 * starred and latest conversations. Null when chat did not answer in time.
96 */
97 chat?: { unread: number; mentions: number; starred?: ChatSidebarEntry[]; recent?: ChatSidebarEntry[] } | null;
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.98 /** The workspace's agents, g1t first, for the Agents sidebar; null when not known. */
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)99 agents?: ShellAgent[] | null;
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.100 /** The apps this person pinned to their dock in the workspace (lib/apps.ts). */
101 pins?: PinnableApp[];
Usage while free is shown at cost; agents get rustfmt and clippy102};
103
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)104/** An agent as the shell lists it. */
105export type ShellAgent = Pick<
106 WorkspaceAgent,
An agent is on teams the way a person is: through team membership, with no team or department of its own. Add it to teams when you create it, from its profile or from the team's page; the Agents sidebar groups agents by the teams they're on, with those on none last; what an agent is told about its teammates, team budgets, skills reach, Spend's By team and the People pages all read memberships. Agents with an old team name matching a team are moved onto it once; the rest are left off a team. Templates name a role only. The agents, teams and people guides say how.107 "id" | "handle" | "display_name" | "avatar" | "avatar_seed" | "role" | "status" | "title" | "builtin"
108> & {
109 scope?: WorkspaceAgent["scope"];
110 /** The visible teams it is on (team memberships); absent when they couldn't be read. */
111 teams?: { slug: string; name: string }[];
112};
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)113
Usage while free is shown at cost; agents get rustfmt and clippy114function SidebarLink({
115 to,
116 icon,
117 end,
118 count,
119 also,
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look120 drill,
Merge branch 'worktree-agent-ad7c6d88d93adc817'121 current: lit,
Usage while free is shown at cost; agents get rustfmt and clippy122 children,
123}: {
124 to: string;
125 icon: ReactNode;
126 end?: boolean;
127 count?: number;
Projects: what a workspace builds and runs, first on every page128 /** Other path prefixes under which this link is the current one. */
129 also?: string | string[];
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look130 /** It opens a list of its own: a chevron says so, always or on hover. */
131 drill?: boolean | "hover";
Merge branch 'worktree-agent-ad7c6d88d93adc817'132 /** Whether it is the current row, when the list works that out itself. */
133 current?: boolean;
Usage while free is shown at cost; agents get rustfmt and clippy134 children: ReactNode;
135}) {
136 const { pathname } = useLocation();
Opening Notifications lights only the row you chose: a sidebar whose rows differ only by their query shows a row as loading only when the page on its way is that row's, not every row on the same path.137 const navigation = useNavigation();
138 // NavLink's own pending state compares paths only, so a list whose rows
139 // differ by query (Notifications' views and reasons) would light every
140 // row while one loads. Where the list says which row is current, a row
141 // is pending only when the page on its way is that row's, query and all.
142 const loading = navigation.location;
143 const pendingHere = loading != null && `${loading.pathname}${loading.search}` === to;
Usage while free is shown at cost; agents get rustfmt and clippy144 return (
145 <NavLink
146 to={to}
147 end={end}
148 prefetch="intent"
149 className={({ isActive, isPending }) => {
Projects: what a workspace builds and runs, first on every page150 const current =
Merge branch 'worktree-agent-ad7c6d88d93adc817'151 lit ??
152 (isActive || [also ?? []].flat().some((prefix) => pathname === prefix || pathname.startsWith(prefix + "/")));
Opening Notifications lights only the row you chose: a sidebar whose rows differ only by their query shows a row as loading only when the page on its way is that row's, not every row on the same path.153 const pending = lit === undefined ? isPending : pendingHere;
Usage while free is shown at cost; agents get rustfmt and clippy154 return `group flex h-8 items-center gap-2.5 rounded-md px-2 text-[0.8125rem] transition-colors ${
155 current
156 ? "bg-raised font-medium text-fg"
Opening Notifications lights only the row you chose: a sidebar whose rows differ only by their query shows a row as loading only when the page on its way is that row's, not every row on the same path.157 : pending
Usage while free is shown at cost; agents get rustfmt and clippy158 ? "bg-raised/60 text-fg"
159 : "text-muted hover:bg-raised/60 hover:text-fg"
160 }`;
161 }}
162 >
163 <span className="shrink-0 text-faint group-hover:text-muted">{icon}</span>
164 <span className="min-w-0 grow truncate">{children}</span>
165 {count != null && count > 0 && (
166 <span className="rounded bg-line px-1.5 text-[0.6875rem] tabular-nums text-muted">
167 {count}
168 </span>
169 )}
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look170 {drill && (
171 <ChevronRight
172 size={14}
173 aria-hidden="true"
174 className={`-mr-0.5 shrink-0 text-faint transition-opacity ${drill === "hover" ? "opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100" : ""}`}
175 />
176 )}
Usage while free is shown at cost; agents get rustfmt and clippy177 </NavLink>
178 );
179}
180
Pull requests say where they are live; the project menu shows what is coming181/**
182 * Something a project will have, shown where it will live so people can
183 * see where g1t is going. Not a link: nothing is behind it yet.
184 */
185function SidebarSoon({ icon, children, about }: { icon: ReactNode; children: ReactNode; about: string }) {
186 return (
Merge branch 'worktree-agent-ae1299e92e4462012'187 <Hint label={about} side="right">
188 <div aria-disabled="true" className="flex h-8 cursor-default items-center gap-2.5 rounded-md px-2 text-[0.8125rem] text-faint">
189 <span className="shrink-0 opacity-70">{icon}</span>
190 <span className="grow truncate">{children}</span>
191 <span className="sr-only">{about}</span>
192 <SoonPill />
193 </div>
194 </Hint>
Pull requests say where they are live; the project menu shows what is coming195 );
196}
197
The project menu opens by section, and the workspace has its own panel198/**
A flat project menu with Code first, views as tabs, and Stripe for every owner199 * A page that is coming, as a link to its roadmap page: faint, with Soon,
200 * and marked current on any of its section's Soon pages.
The project menu opens by section, and the workspace has its own panel201 */
A flat project menu with Code first, views as tabs, and Stripe for every owner202function SidebarSoonLink({
The project menu opens by section, and the workspace has its own panel203 to,
204 also,
A flat project menu with Code first, views as tabs, and Stripe for every owner205 icon,
206 about,
Merge branch 'worktree-agent-ad7c6d88d93adc817'207 current: lit,
The project menu opens by section, and the workspace has its own panel208 children,
209}: {
210 to: string;
A flat project menu with Code first, views as tabs, and Stripe for every owner211 also?: string[];
212 icon: ReactNode;
213 about: string;
Merge branch 'worktree-agent-ad7c6d88d93adc817'214 /** Whether it is the current row, when the list works that out itself. */
215 current?: boolean;
The project menu opens by section, and the workspace has its own panel216 children: ReactNode;
217}) {
218 const { pathname } = useLocation();
219 return (
Sidebar: soon rows and the project row keep their styles inside a hint; tiny amounts read as zero220 // The hint wraps a plain box: Radix's asChild merges className as a
221 // string, which would break NavLink's className function.
Merge branch 'worktree-agent-ae1299e92e4462012'222 <Hint label={about} side="right">
Sidebar: soon rows and the project row keep their styles inside a hint; tiny amounts read as zero223 <div>
The project menu opens by section, and the workspace has its own panel224 <NavLink
225 to={to}
226 prefetch="intent"
A flat project menu with Code first, views as tabs, and Stripe for every owner227 className={({ isActive }) => {
Merge branch 'worktree-agent-ad7c6d88d93adc817'228 const current = lit ?? (isActive || (also ?? []).some((prefix) => pathname === prefix || pathname.startsWith(prefix + "/")));
A flat project menu with Code first, views as tabs, and Stripe for every owner229 return `group flex h-8 items-center gap-2.5 rounded-md px-2 text-[0.8125rem] transition-colors ${
230 current ? "bg-raised font-medium text-fg" : "text-faint hover:bg-raised/60 hover:text-muted"
The project menu opens by section, and the workspace has its own panel231 }`;
232 }}
233 >
A flat project menu with Code first, views as tabs, and Stripe for every owner234 <span className="shrink-0 opacity-80">{icon}</span>
The project menu opens by section, and the workspace has its own panel235 <span className="min-w-0 grow truncate">{children}</span>
Usage, Billing settings and prepaid AI credit; fixes from the UX audit236 <SoonPill />
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales237 </NavLink>
Sidebar: soon rows and the project row keep their styles inside a hint; tiny amounts read as zero238 </div>
Merge branch 'worktree-agent-ae1299e92e4462012'239 </Hint>
The project menu opens by section, and the workspace has its own panel240 );
241}
242
A flat project menu with Code first, views as tabs, and Stripe for every owner243/** Icons for what spans projects. */
244const WORKSPACE_ICONS: Record<string, ReactNode> = {
245 board: <KanbanSquare size={15} />,
246 roadmap: <GanttChart size={15} />,
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member247 teams: <UsersRound size={15} />,
A flat project menu with Code first, views as tabs, and Stripe for every owner248 packages: <Package size={15} />,
249 fleet: <Bot size={15} />,
250};
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales251
A flat project menu with Code first, views as tabs, and Stripe for every owner252/** The Soon pages of a section, as paths, so its link is current on them. */
253function soonPaths(base: string, section: RoadmapItem["section"]): string[] {
254 return roadmapIn(section).map((item) => `${base}/soon/${item.key}`);
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales255}
256
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look257function SidebarGroup({
258 title,
259 action,
260 className = "",
261 children,
262}: {
263 title: string;
264 action?: ReactNode;
265 className?: string;
266 children: ReactNode;
267}) {
Usage while free is shown at cost; agents get rustfmt and clippy268 return (
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look269 <section className={className}>
Usage while free is shown at cost; agents get rustfmt and clippy270 <div className="mb-1 flex h-6 items-center justify-between px-2">
271 <h2 className="text-xs font-medium text-faint">{title}</h2>
272 {action}
273 </div>
274 <div className="space-y-px">{children}</div>
275 </section>
276 );
277}
278
Workspace names and icons, and a component kit for every control279/** What a workspace is called where people read it: its display name, else its slug. */
280function displayName(membership: Membership): string {
281 return membership.name?.trim() || membership.slug;
Usage while free is shown at cost; agents get rustfmt and clippy282}
283
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas284/**
285 * The fine print, as one quiet row at the foot of the account menu and the
286 * visitor's panel: each link a full-height target, left-aligned. In the
287 * menu each is a menu item, so the arrow keys reach it.
288 */
289const LEGAL_LINKS: [string, string][] = [
290 ["Policies", "/policies"],
291 ["Privacy", "/policies/privacy"],
292 ["Security", "/security"],
293];
294const LEGAL_LINK = "flex h-7 items-center rounded px-1.5 text-xs text-faint outline-none transition-colors";
295
296function MenuLegalRow() {
297 return (
298 <div role="group" aria-label="Legal" className="flex items-center gap-0.5 px-0.5 pt-0.5">
299 {LEGAL_LINKS.map(([label, to], index) => (
300 <span key={to} className="flex items-center gap-0.5">
301 {index > 0 && (
302 <span aria-hidden="true" className="text-[0.625rem] text-line-strong">
303 ·
304 </span>
305 )}
306 <DropdownMenuItem asChild className={`${LEGAL_LINK} py-0 data-highlighted:bg-line data-highlighted:text-fg`}>
307 <Link to={to}>{label}</Link>
308 </DropdownMenuItem>
309 </span>
310 ))}
311 </div>
312 );
313}
314
315/** Status's row: the live dot and two or three words, fetched when the menu opens. */
316function StatusSummary({ open }: { open: boolean }) {
317 const status = useSiteStatus(open);
318 const words = statusTitle(status);
319 return (
320 <span className="ml-auto flex min-w-0 items-center gap-1.5 pl-2 text-xs text-faint">
321 {/* The words say it; the dot's own words for screen readers would repeat them. */}
322 <span aria-hidden="true" className="flex">
323 <StatusDot state={status?.overall.state ?? null} />
324 </span>
Fast pages, required checks on the branch, self-hosted runners, honest incidents325 {words ? <span className="truncate">{words}</span> : <Skeleton className="h-3 w-20" />}
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas326 </span>
327 );
328}
329
330/** A menu row: an icon, words, and whatever sits at its end. */
331const MENU_ROW = "h-9 gap-2.5 px-2.5 text-[0.8125rem]";
332
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.333/**
334 * Your account, at the foot of the dock (or in the header, before you have
335 * a workspace): who you are and your status, your profile and settings,
336 * and help: the documentation, support, status and the keyboard's
337 * shortcuts; then signing out and the fine print.
338 */
339function AccountMenu({ user, side = "right" }: { user: User; side?: "right" | "bottom" }) {
Usage while free is shown at cost; agents get rustfmt and clippy340 const submit = useSubmit();
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas341 const [open, setOpen] = useState(false);
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.342 const [keys, setKeys] = useState(false);
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers343 // Your status's dialog: outside the menu, so the menu closes behind it.
344 const [editing, setEditing] = useState(false);
Fast pages, required checks on the branch, self-hosted runners, honest incidents345 // Name, primary address and invites left: asked for once, as soon as the
346 // pointer or focus reaches the button, so they are there when it opens.
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas347 const details = useFetcher<AccountMenuData | null>({ key: "account-menu" });
Fast pages, required checks on the branch, self-hosted runners, honest incidents348 const prefetch = () => {
349 if (details.state === "idle" && details.data === undefined) details.load("/settings/menu.json");
350 };
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas351 useEffect(() => {
Fast pages, required checks on the branch, self-hosted runners, honest incidents352 if (open) prefetch();
353 // eslint-disable-next-line react-hooks/exhaustive-deps
354 }, [open]);
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas355 const me = details.data ?? null;
Fast pages, required checks on the branch, self-hosted runners, honest incidents356 // Still on its way: shapes where the words will be, the same size.
357 const loading = details.data === undefined && details.state !== "idle";
Merge two kinds of invite, kept apart: an invite to g1t (Settings, invite-only only, no workspace unless asked) and an invitation to a workspace (its People page)358 // While anyone can sign up, listed once the data says there are invites to look back on.
359 const invitesListed = useInviteOnly() || me?.invites_page === true;
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas360 const profile = `/u/${user.username}`;
Usage while free is shown at cost; agents get rustfmt and clippy361 return (
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers362 <>
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas363 <DropdownMenu open={open} onOpenChange={setOpen}>
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.364 {/* The avatar alone, with a dot that says how others see you (components/presence.tsx). */}
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas365 <DropdownMenuTrigger
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers366 aria-label={`Account menu for ${shownUsername(user)}`}
Fast pages, required checks on the branch, self-hosted runners, honest incidents367 onPointerEnter={prefetch}
368 onFocus={prefetch}
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.369 className="relative flex rounded-full outline-none transition-transform hover:scale-[1.04] focus-visible:ring-2 focus-visible:ring-accent data-[state=open]:ring-2 data-[state=open]:ring-line-strong"
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas370 >
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.371 <Avatar name={user.username} image={user.avatar} size={side === "right" ? 32 : 28} />
372 <OwnPresenceDot ring={side === "right" ? "var(--color-dock)" : "var(--color-bg)"} className="absolute -right-0.5 -bottom-0.5" />
Usage while free is shown at cost; agents get rustfmt and clippy373 </DropdownMenuTrigger>
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.374 <DropdownMenuContent align="end" side={side} sideOffset={side === "right" ? 14 : 6} collisionPadding={8} className="w-[17.5rem] p-1.5">
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas375 {/* Who is signed in, and a way to their profile. */}
376 <DropdownMenuItem asChild className="gap-3 px-2 py-2">
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers377 <Link to={profile} aria-label={`${me?.name ?? shownUsername(user)} (@${shownUsername(user)}), your profile`}>
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas378 <Avatar name={user.username} image={user.avatar} size={36} />
Fast pages, required checks on the branch, self-hosted runners, honest incidents379 <span className="flex min-w-0 grow flex-col leading-tight" aria-busy={loading}>
380 {loading ? (
381 <Skeleton className="my-[0.1875rem] h-3.5 w-28" />
382 ) : (
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers383 <span className="truncate text-sm font-medium text-fg">{me?.name ?? shownUsername(user)}</span>
Fast pages, required checks on the branch, self-hosted runners, honest incidents384 )}
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers385 <span className="truncate font-mono text-xs text-muted">@{shownUsername(user)}</span>
Fast pages, required checks on the branch, self-hosted runners, honest incidents386 {loading ? (
387 <Skeleton className="mt-1 h-3 w-40" />
388 ) : (
389 me?.email && <span className="mt-0.5 truncate text-xs text-faint">{me.email}</span>
390 )}
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas391 </span>
Usage while free is shown at cost; agents get rustfmt and clippy392 </Link>
393 </DropdownMenuItem>
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas394 <DropdownMenuSeparator className="my-1.5" />
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers395 {/* Your status, away, and pausing notifications. */}
396 <DropdownMenuGroup>
397 <OwnPresenceItems className="min-h-9 py-1.5 text-[0.8125rem]" onEdit={() => setEditing(true)} />
398 </DropdownMenuGroup>
399 <DropdownMenuSeparator className="my-1.5" />
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas400 <DropdownMenuGroup>
401 <DropdownMenuItem asChild className={MENU_ROW}>
402 <Link to={profile}>
403 <CircleUserRound />
404 Your profile
405 </Link>
406 </DropdownMenuItem>
407 <DropdownMenuItem asChild className={MENU_ROW}>
408 <Link to={FIRST_SETTINGS_PAGE}>
409 <Settings />
410 Your settings
411 </Link>
412 </DropdownMenuItem>
Merge two kinds of invite, kept apart: an invite to g1t (Settings, invite-only only, no workspace unless asked) and an invitation to a workspace (its People page)413 {invitesListed && (
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas414 <DropdownMenuItem asChild className={MENU_ROW}>
415 <Link to="/settings/invites">
416 <Ticket />
Merge two kinds of invite, kept apart: an invite to g1t (Settings, invite-only only, no workspace unless asked) and an invitation to a workspace (its People page)417 {ACCOUNT_SETTINGS.invites.title}
Fast pages, required checks on the branch, self-hosted runners, honest incidents418 {loading && <Skeleton className="ml-auto h-4 w-12 rounded-full" />}
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas419 {me?.invites_left != null && (
420 <span className="ml-auto rounded-full bg-line px-1.5 text-[0.6875rem] tabular-nums text-muted">
421 {me.invites_left} left
422 </span>
423 )}
424 </Link>
425 </DropdownMenuItem>
Merge two kinds of invite, kept apart: an invite to g1t (Settings, invite-only only, no workspace unless asked) and an invitation to a workspace (its People page)426 )}
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas427 </DropdownMenuGroup>
428 <DropdownMenuSeparator className="my-1.5" />
You choose how g1t looks: Auto follows your system, Light and Dark stay put, set from the account menu, the phone's You and help sheet, Settings → Account or the command palette; the page is drawn in your choice from the first byte, every colour has a light value that reads at 4.5:1 or better, code and diffs are highlighted for both, diagrams and the document editor follow along, the product tour and the g1t mark's avatar stay dark, and Dark is what you see until you choose; the workspaces guide says how.429 {/* Auto, Light or Dark, switched in place (lib/theme.ts). */}
430 <ThemeMenuSwitch />
431 <DropdownMenuSeparator className="my-1.5" />
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas432 <DropdownMenuGroup>
433 <DropdownMenuItem asChild className={MENU_ROW}>
434 <a href="https://docs.g1t.sh/">
435 <BookOpen />
436 Documentation
437 </a>
438 </DropdownMenuItem>
439 <DropdownMenuItem asChild className={MENU_ROW}>
440 <Link to="/support">
441 <LifeBuoy />
442 Support
443 </Link>
444 </DropdownMenuItem>
445 <DropdownMenuItem asChild className={MENU_ROW}>
446 <a href={STATUS_URL}>
447 <Activity />
448 Status
449 <StatusSummary open={open} />
450 </a>
451 </DropdownMenuItem>
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.452 <DropdownMenuItem className={MENU_ROW} onSelect={() => setKeys(true)}>
453 <Keyboard />
454 Keyboard shortcuts
455 <PaletteKey className="ml-auto font-sans text-xs text-faint" />
456 </DropdownMenuItem>
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas457 </DropdownMenuGroup>
458 <DropdownMenuSeparator className="my-1.5" />
Usage while free is shown at cost; agents get rustfmt and clippy459 {/* Submitted from here: the menu closes on select, and a button
460 that has left the page cannot submit a form. */}
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas461 <DropdownMenuItem className={MENU_ROW} onSelect={() => submit(null, { method: "post", action: "/logout" })}>
Usage while free is shown at cost; agents get rustfmt and clippy462 <LogOut />
463 Sign out
464 </DropdownMenuItem>
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas465 <DropdownMenuSeparator className="my-1.5" />
466 <MenuLegalRow />
Usage while free is shown at cost; agents get rustfmt and clippy467 </DropdownMenuContent>
468 </DropdownMenu>
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers469 <StatusDialog open={editing} onOpenChange={setEditing} />
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.470 <ShortcutsDialog open={keys} onOpenChange={setKeys} />
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers471 </>
Usage while free is shown at cost; agents get rustfmt and clippy472 );
473}
474
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look475/**
Mission control counts people's own changes as theirs; a shorter sidebar with setup under Settings, and a 56px top bar476 * A workspace's settings pages, which the sidebar drills into: how it is
The Runners page shows the machines a workspace's agents and workflow jobs run on, in Workspace under Compute: g1t's cloud beside your own runners, what each is running now with a link to it, what's waiting, this month's machine time and its cost (your own runners' free), where agent work and workflow jobs run, adding a runner, and groups; runner_activity in Actions says what runs where, work handed to your runners keeps its agent run, and the self-hosted runners guide says how.477 * set up and connected (guardrails, secrets, integrations,
Mission control counts people's own changes as theirs; a shorter sidebar with setup under Settings, and a 56px top bar478 * webhooks), what it pays, its repositories, tokens and record. The main
479 * list keeps the places work happens and who belongs; every member can
480 * still open these.
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look481 */
Mission control counts people's own changes as theirs; a shorter sidebar with setup under Settings, and a 56px top bar482const SETTINGS_PAGE =
Merge branch 'worktree-agent-ad7c6d88d93adc817'483 new RegExp(`^/([^/]+)/-/(${SETTINGS_PAGES.join("|")})(/|$)`);
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look484/** A project's settings pages, which the project's menu drills into. */
Project settings move into the sidebar, grouped, with a heading per page485const REPO_SETTINGS_PAGE = /^\/([^/]+)\/([^/-][^/]*)\/settings(\/|$)/;
Usage while free is shown at cost; agents get rustfmt and clippy486
487/**
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look488 * The sidebar's lists are a stack, the way a phone pushes a screen: one
489 * drilled into slides in from the right over the full width, while the one
490 * it covers drifts a quarter of the way left and fades, both on one long
Usage while free is shown at cost; agents get rustfmt and clippy491 * ease-out, the fade quicker than the move so the two never blur together.
492 * Going back reverses it.
493 */
494const LAYER =
495 "absolute inset-0 [transition:translate_380ms_cubic-bezier(0.32,0.72,0,1),opacity_220ms_ease-out] will-change-[translate,opacity] motion-reduce:transition-none";
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look496/** One list, filling its layer. */
Usage while free is shown at cost; agents get rustfmt and clippy497const PANEL = "h-full overflow-y-auto px-2 pb-4";
498
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look499/** One list in the stack: what it is, and its rows. */
500type Level = { key: string; node: ReactNode };
501
502/** True once the page has hydrated, so what the server drew never animates in. */
503function useHydrated(): boolean {
504 const [hydrated, setHydrated] = useState(false);
505 useEffect(() => setHydrated(true), []);
506 return hydrated;
507}
508
509/**
510 * Drilling in and out of the sidebar's lists. `trail` is the way from the
511 * main list to the one shown, worked out from the address, so a link
512 * straight to a settings page opens the sidebar already drilled in, and
513 * leaving it comes back out. Lists deeper than the one shown stay in
514 * place, off to the right, so going back slides them away rather than
515 * dropping them. Moving to a list at the same depth (a workspace's settings
516 * to a project) fades the new one in where it is.
517 */
518function Drill({ trail }: { trail: Level[] }) {
519 const depth = trail.length - 1;
520 const hydrated = useHydrated();
521 const stack = useRef<Level[]>(trail);
522 const before = stack.current;
523 const within = trail.every((level, index) => before[index]?.key === level.key);
524 stack.current = within ? [...trail, ...before.slice(trail.length)] : trail;
525 const levels = stack.current;
526 // What was showing last time, to tell drilling in from moving across.
527 const shown = useRef({ depth, keys: levels.map((level) => level.key) });
528 useEffect(() => {
529 shown.current = { depth, keys: levels.map((level) => level.key) };
530 });
Usage while free is shown at cost; agents get rustfmt and clippy531 return (
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look532 <div className="relative min-h-0 grow overflow-hidden">
533 {levels.map((level, index) => {
534 const current = index === depth;
535 const place =
536 index < depth
537 ? "pointer-events-none -translate-x-1/4 opacity-0"
538 : current
539 ? "translate-x-0 opacity-100"
540 : "pointer-events-none translate-x-full opacity-0";
541 // A list that was not there before arrives: from the right when
542 // drilling in, in place when moving across.
543 const arriving = hydrated && current && !shown.current.keys.includes(level.key);
544 const enter = arriving
545 ? depth > shown.current.depth
546 ? "starting:translate-x-full starting:opacity-0"
547 : "starting:opacity-0"
548 : "";
549 return (
550 <div key={level.key} className={`${LAYER} ${place} ${enter}`} inert={!current} aria-hidden={!current || undefined}>
551 {level.node}
552 </div>
553 );
554 })}
555 </div>
556 );
557}
558
559/**
560 * The row at the top of a list drilled into: the list's name, which goes
561 * back out, and what it belongs to, faint at the end.
562 */
563function BackRow({ to, label, context }: { to: string; label: ReactNode; context?: ReactNode }) {
564 return (
565 <Link
566 to={to}
567 prefetch="intent"
568 className="group mt-3 flex h-8 items-center gap-1.5 rounded-md pr-2 pl-1 text-[0.8125rem] font-medium text-fg transition-colors hover:bg-raised/60"
Usage while free is shown at cost; agents get rustfmt and clippy569 >
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look570 <ChevronLeft size={16} className="shrink-0 text-faint transition-transform group-hover:-translate-x-0.5 group-hover:text-muted" />
571 <span className="min-w-0 shrink-0 truncate">{label}</span>
572 {context && (
573 <span className="ml-auto min-w-0 truncate pl-2 font-mono text-[0.6875rem] font-normal text-faint">{context}</span>
574 )}
575 </Link>
576 );
577}
578
579/** A thin rule between groups of a list. */
580function Rule() {
581 return <div role="separator" className="mx-2 my-2.5 h-px bg-line" />;
582}
583
Navigation: the workspace's own page with tabs, pins and recent in the sidebar584/** A quiet heading inside a group: Pinned, Recent. */
585function SidebarSubhead({ children }: { children: ReactNode }) {
586 return <h3 className="px-2 pt-1.5 pb-0.5 text-[0.6875rem] font-medium tracking-wide text-faint">{children}</h3>;
587}
588
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look589/**
Navigation: the workspace's own page with tabs, pins and recent in the sidebar590 * The workspace's projects as the sidebar keeps them, however many there
591 * are: the person's pins in their order, what they opened last, and the
592 * way to all of them. Pins move by dragging, or with Alt and the arrow
593 * keys; the projects service keeps the order.
594 */
Merge branch 'worktree-agent-ad7c6d88d93adc817'595function SidebarProjects({ slug, shell, current }: { slug: string; shell: ShellData; current: boolean }) {
Navigation: the workspace's own page with tabs, pins and recent in the sidebar596 const reorder = useFetcher({ key: `pins:${slug}` });
597 const saved = shell.pinned ?? [];
598 // While a new order is on its way, it shows as made.
599 const asked = reorder.formData?.get("intent") === "reorder" ? reorder.formData.getAll("slug").map(String) : null;
600 const pinned = asked
601 ? asked.map((name) => saved.find((project) => project.name === name)).filter((project): project is ShortcutProject => project != null)
602 : saved;
603 const active = shell.repo ? { namespace: shell.repo.namespace, name: shell.repo.name, isPrivate: false } : null;
604 const recent = recentWith(shell.recent ?? [], pinned, active, slug);
605 const [dragging, setDragging] = useState<number | null>(null);
606 const move = (from: number, by: number) => {
607 const next = movedPin(pinned, from, by);
608 if (!next) return;
609 const form = new FormData();
610 form.set("intent", "reorder");
611 for (const project of next) form.append("slug", project.name);
612 reorder.submit(form, { method: "post", action: `/${slug}/-/pins` });
613 };
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar614 // Each row pins or unpins in place: the pin shows on hover or focus, and
615 // stays shown on a pinned row's hover so it reads as "unpin".
616 const row = (project: ShortcutProject, isPinned: boolean) => (
617 <div className="group/row relative">
618 <SidebarLink to={`/${project.namespace}/${project.name}`} icon={project.isPrivate ? <Lock size={15} /> : <Box size={15} />} drill="hover">
619 <span className="block truncate pr-6">{project.title ?? project.name}</span>
620 </SidebarLink>
621 <PinButton
622 workspace={slug}
623 slug={project.name}
624 name={project.title ?? project.name}
625 pinned={isPinned}
626 small
627 className="absolute top-1/2 right-6 -translate-y-1/2 opacity-0 transition-opacity group-hover/row:opacity-100 focus-within:opacity-100 [@media(hover:none)]:opacity-100"
628 />
629 </div>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar630 );
631 return (
632 <SidebarGroup
633 title="Projects"
634 action={
New project and Import from GitHub work in the workspace you're in, as the sidebar shows it, with no workspace to pick on the page; a link that names another of your workspaces switches you to it first. The projects guide says so.635 <Link to="/new" aria-label="New project" className="rounded p-0.5 text-faint hover:bg-raised hover:text-fg">
Navigation: the workspace's own page with tabs, pins and recent in the sidebar636 <Plus size={13} />
637 </Link>
638 }
639 >
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar640 {/* Only there once something is pinned: each row below has its own pin. */}
641 {pinned.length > 0 && (
642 <>
643 <SidebarSubhead>Pinned</SidebarSubhead>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar644 <ul aria-label="Pinned projects" className="space-y-px">
645 {pinned.map((project, index) => (
646 <li
647 key={project.name}
648 draggable={pinned.length > 1}
649 onDragStart={(event) => {
650 setDragging(index);
651 event.dataTransfer.effectAllowed = "move";
652 }}
653 onDragOver={(event) => {
654 if (dragging != null) event.preventDefault();
655 }}
656 onDrop={(event) => {
657 event.preventDefault();
658 if (dragging != null && dragging !== index) move(dragging, index - dragging);
659 setDragging(null);
660 }}
661 onDragEnd={() => setDragging(null)}
662 onKeyDown={(event) => {
663 if (!event.altKey || (event.key !== "ArrowUp" && event.key !== "ArrowDown")) return;
664 event.preventDefault();
665 move(index, event.key === "ArrowUp" ? -1 : 1);
666 }}
667 className={`group/pin relative ${dragging === index ? "opacity-50" : ""}`}
668 >
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar669 {row(project, true)}
Navigation: the workspace's own page with tabs, pins and recent in the sidebar670 {pinned.length > 1 && (
Merge branch 'worktree-agent-ae1299e92e4462012'671 <Hint label="Drag, or Alt and an arrow key, to reorder" side="right">
672 <span className="absolute top-1/2 -left-1.5 -translate-y-1/2 cursor-grab text-faint opacity-0 transition-opacity group-hover/pin:opacity-100">
673 <GripVertical size={12} aria-hidden="true" />
674 </span>
675 </Hint>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar676 )}
677 </li>
678 ))}
679 </ul>
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar680 </>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar681 )}
682 {recent.length > 0 && (
683 <>
684 <SidebarSubhead>Recent</SidebarSubhead>
685 {recent.map((project) => (
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar686 <div key={`${project.namespace}/${project.name}`}>{row(project, false)}</div>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar687 ))}
688 </>
689 )}
690 <div className="pt-1">
Merge branch 'worktree-agent-ad7c6d88d93adc817'691 <SidebarLink to={`/${slug}/-/projects`} icon={<LayoutGrid size={15} />} count={shell.repos.length} current={current}>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar692 All projects
693 </SidebarLink>
694 </div>
695 </SidebarGroup>
696 );
697}
698
Merge branch 'worktree-agent-ad7c6d88d93adc817'699/** Insights, coming: the workspace's own page says what it will be. */
700const INSIGHTS = roadmapItem("insights");
701
Usage while free is shown at cost; agents get rustfmt and clippy702/**
703 * What the repository menu needs. Known from the address before the page's
704 * data arrives, so the menu is right from the first frame; the counts fill
705 * in once it does.
706 */
707type MenuRepo = {
708 namespace: string;
709 name: string;
710 member: boolean;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look711 /** Whether they see its settings; from the repository's page once it loads. */
712 settings?: boolean;
713 /** What they may do there, once the repository's page loads. */
714 can?: Abilities;
Usage while free is shown at cost; agents get rustfmt and clippy715 issues?: number;
716 pulls?: number;
717};
718
719function sameRepo(a: { namespace: string; name: string } | null, b: { namespace: string; name: string } | null) {
720 return (
721 a != null &&
722 b != null &&
723 a.namespace.toLowerCase() === b.namespace.toLowerCase() &&
724 a.name.toLowerCase() === b.name.toLowerCase()
725 );
726}
727
728/**
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look729 * A project's own list, drilled into while you are in it: everything about
730 * the project, running and its code, and nothing else, with the way back
731 * out to all of them.
Usage while free is shown at cost; agents get rustfmt and clippy732 */
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put733function RepoMenu({
734 repo,
735 isPrivate,
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look736 back,
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put737}: {
738 repo: MenuRepo;
739 isPrivate: boolean;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look740 /** Where the way back leads: the workspace's projects, mission control, or Explore. */
741 back: { to: string; label: string };
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put742}) {
Usage while free is shown at cost; agents get rustfmt and clippy743 const base = `/${repo.namespace}/${repo.name}`;
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put744 // What a member sees, and what everyone who can see the project does.
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look745 const shows = new Set(projectPages(repo.member, repo.can));
Usage while free is shown at cost; agents get rustfmt and clippy746 return (
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look747 <nav aria-label={`${repo.namespace}/${repo.name}`} className={PANEL}>
748 <BackRow to={back.to} label={back.label} />
Merge branch 'worktree-agent-ae1299e92e4462012'749 <Hint label="Overview" side="right">
Sidebar: soon rows and the project row keep their styles inside a hint; tiny amounts read as zero750 <div>
A flat project menu with Code first, views as tabs, and Stripe for every owner751 <NavLink
Usage while free is shown at cost; agents get rustfmt and clippy752 to={base}
A flat project menu with Code first, views as tabs, and Stripe for every owner753 end
Fast pages, required checks on the branch, self-hosted runners, honest incidents754 prefetch="intent"
A flat project menu with Code first, views as tabs, and Stripe for every owner755 className={({ isActive }) =>
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look756 `mt-2 flex items-center gap-2 rounded-md px-2 py-1.5 transition-colors ${isActive ? "bg-raised" : "hover:bg-raised/60"}`
A flat project menu with Code first, views as tabs, and Stripe for every owner757 }
Usage while free is shown at cost; agents get rustfmt and clippy758 >
759 <span className="flex size-6 shrink-0 items-center justify-center rounded-md bg-raised text-muted ring-1 ring-line">
Projects: what a workspace builds and runs, first on every page760 {isPrivate ? <Lock size={13} /> : <Box size={13} />}
Usage while free is shown at cost; agents get rustfmt and clippy761 </span>
762 <span className="min-w-0 truncate font-mono text-[0.8125rem]">
763 <span className="text-faint">{repo.namespace}/</span>
764 <span className="font-semibold text-fg">{repo.name}</span>
765 </span>
A flat project menu with Code first, views as tabs, and Stripe for every owner766 </NavLink>
Sidebar: soon rows and the project row keep their styles inside a hint; tiny amounts read as zero767 </div>
Merge branch 'worktree-agent-ae1299e92e4462012'768 </Hint>
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look769 {/* A project's pages, in the order people use them. A page with more
770 than one view shows them as tabs across its top. */}
771 <Rule />
772 <div className="space-y-px">
Compare: any two branches, the commits one has that the other does not, and the diff, with Open a pull request773 <SidebarLink to={`${base}/code`} also={[`${base}/tree`, `${base}/blob`, `${base}/commits`, `${base}/commit`, `${base}/branches`, `${base}/tags`, `${base}/compare`, ...soonPaths(base, "Code")]} icon={<Code2 size={15} />}>
A flat project menu with Code first, views as tabs, and Stripe for every owner774 Code
775 </SidebarLink>
Usage, Billing settings and prepaid AI credit; fixes from the UX audit776 <SidebarLink to={`${base}/issues`} also={[`${base}/plans`, `${base}/milestones`, `${base}/labels`, ...soonPaths(base, "Issues")]} icon={<CircleDot size={15} />} count={repo.issues}>
A flat project menu with Code first, views as tabs, and Stripe for every owner777 Issues
778 </SidebarLink>
779 <SidebarLink to={`${base}/pulls`} also={[`${base}/pull`, `${base}/queue`]} icon={<GitPullRequest size={15} />} count={repo.pulls}>
780 Pull requests
781 </SidebarLink>
Agents and memory, checks and conflicts, profiles, slug renames, custom domains782 <SidebarLink to={`${base}/agents`} also={[`${base}/sessions`, `${base}/memory`, ...soonPaths(base, "Agents")]} icon={<Bot size={15} />}>
A flat project menu with Code first, views as tabs, and Stripe for every owner783 Agents
Agents and memory, checks and conflicts, profiles, slug renames, custom domains784 </SidebarLink>
A flat project menu with Code first, views as tabs, and Stripe for every owner785 <SidebarLink to={`${base}/actions`} icon={<PlayCircle size={15} />}>
786 Workflows
Projects: what a workspace builds and runs, first on every page787 </SidebarLink>
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look788 </div>
789 <Rule />
790 <div className="space-y-px">
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put791 {shows.has("deployments") ? (
A flat project menu with Code first, views as tabs, and Stripe for every owner792 <SidebarLink to={`${base}/deployments`} also={soonPaths(base, "Deployments")} icon={<Rocket size={15} />}>
793 Deployments
794 </SidebarLink>
795 ) : null}
Observability gets its own page; tabs never overflow796 <SidebarSoonLink to={`${base}/soon/logs`} also={soonPaths(base, "Observability")} icon={<Activity size={15} />} about="Logs, errors, uptime and analytics of the project's deployed apps.">
797 Observability
A flat project menu with Code first, views as tabs, and Stripe for every owner798 </SidebarSoonLink>
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put799 {shows.has("security") ? (
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API800 <SidebarLink to={`${base}/security`} also={soonPaths(base, "Security")} icon={<ShieldCheck size={15} />}>
801 Security
802 </SidebarLink>
803 ) : null}
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97804 <SidebarLink
805 to={`${base}/contributors`}
806 also={[`${base}/activity`, `${base}/stargazers`, ...soonPaths(base, "Insights")]}
807 icon={<BarChart3 size={15} />}
808 >
A flat project menu with Code first, views as tabs, and Stripe for every owner809 Insights
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97810 </SidebarLink>
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look811 </div>
812 {(repo.settings ?? shows.has("settings")) && (
813 <>
814 <Rule />
815 <SidebarLink to={`${base}/settings`} icon={<Settings size={15} />} drill>
A flat project menu with Code first, views as tabs, and Stripe for every owner816 Settings
817 </SidebarLink>
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look818 </>
819 )}
Usage while free is shown at cost; agents get rustfmt and clippy820 </nav>
821 );
822}
823
Project settings move into the sidebar, grouped, with a heading per page824/**
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look825 * A project's settings, drilled into from its list: what is about running
826 * it, then its agents, then its code and who can reach it. The way back
827 * leads to the project.
Project settings move into the sidebar, grouped, with a heading per page828 */
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look829function RepoSettingsMenu({ repo }: { repo: MenuRepo }) {
Project settings move into the sidebar, grouped, with a heading per page830 const base = `/${repo.namespace}/${repo.name}`;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look831 // Each page shows to the roles that can use it, once the role is known.
832 const shows = (page: string) => !repo.can || repo.can[SETTINGS_CAPABILITY[page] ?? "administer"];
833 const running = shows("deployments");
834 const agents = shows("agents") || shows("guardrails");
Project settings move into the sidebar, grouped, with a heading per page835 return (
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look836 <nav aria-label={`${repo.namespace}/${repo.name} settings`} className={PANEL}>
837 <BackRow to={base} label="Settings" context={`${repo.namespace}/${repo.name}`} />
838 {shows("") && (
839 <div className="mt-2 space-y-px">
840 <SidebarLink to={`${base}/settings`} end icon={<Settings size={15} />}>
841 General
842 </SidebarLink>
843 </div>
844 )}
845 {running && (
846 <>
847 {shows("") && <Rule />}
848 <div className={shows("") ? "space-y-px" : "mt-2 space-y-px"}>
849 <SidebarLink to={`${base}/settings/deployments`} icon={<Rocket size={15} />}>
850 Deployments
851 </SidebarLink>
852 <SidebarLink to={`${base}/settings/domains`} icon={<Globe size={15} />}>
853 Domains
854 </SidebarLink>
855 </div>
856 </>
857 )}
858 {agents && (
859 <>
860 <Rule />
861 <div className="space-y-px">
862 {shows("agents") && (
863 <SidebarLink to={`${base}/settings/agents`} icon={<Bot size={15} />}>
864 Agents
865 </SidebarLink>
866 )}
867 {shows("guardrails") && (
868 <SidebarLink to={`${base}/settings/guardrails`} icon={<ShieldCheck size={15} />}>
869 Guardrails
870 </SidebarLink>
871 )}
872 </div>
873 </>
874 )}
875 <Rule />
876 <div className="space-y-px">
877 {shows("repository") && (
878 <SidebarLink to={`${base}/settings/repository`} icon={<BookMarked size={15} />}>
879 Repository
880 </SidebarLink>
881 )}
Merge branch 'mirroring' into artifacts-mode882 {shows("mirroring") && (
883 <SidebarLink to={`${base}/settings/mirroring`} icon={<ArrowLeftRight size={15} />}>
884 Mirroring
885 </SidebarLink>
886 )}
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look887 {shows("access") && (
888 <SidebarLink to={`${base}/settings/access`} icon={<Users size={15} />}>
889 Access
890 </SidebarLink>
891 )}
Merge branch 'worktree-agent-a5a5de74d8863d554' into worktree-agent-a16631325aecf58ca892 {shows("keys") && (
893 <SidebarLink to={`${base}/settings/keys`} icon={<KeyRound size={15} />}>
894 Deploy keys
895 </SidebarLink>
896 )}
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look897 {shows("branches") && (
898 <SidebarLink to={`${base}/settings/branches`} icon={<GitBranch size={15} />}>
899 Branches and merging
900 </SidebarLink>
901 )}
Merge rulesets: branch and tag rules, agent-first, enforced on push and merge902 {shows("rules") && (
903 <SidebarLink to={`${base}/settings/rules`} icon={<Scale size={15} />}>
904 Rules
905 </SidebarLink>
906 )}
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look907 {shows("secrets") && (
908 <SidebarLink to={`${base}/settings/secrets`} icon={<Lock size={15} />}>
909 Secrets and variables
910 </SidebarLink>
911 )}
Merge branch 'worktree-agent-a3abfcce648e87dca'912 {shows("actions") && (
913 <SidebarLink to={`${base}/settings/actions`} icon={<PlayCircle size={15} />}>
914 Actions
915 </SidebarLink>
916 )}
917 {shows("environments") && (
918 <SidebarLink to={`${base}/settings/environments`} icon={<Layers size={15} />}>
919 Environments
920 </SidebarLink>
921 )}
Fast pages, required checks on the branch, self-hosted runners, honest incidents922 {shows("runners") && (
923 <SidebarLink to={`${base}/settings/runners`} icon={<ServerCog size={15} />}>
924 Runners
925 </SidebarLink>
926 )}
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look927 {shows("webhooks") && (
928 <SidebarLink to={`${base}/settings/webhooks`} icon={<Webhook size={15} />}>
929 Webhooks
930 </SidebarLink>
931 )}
932 </div>
Project settings move into the sidebar, grouped, with a heading per page933 </nav>
934 );
935}
936
Merge two kinds of invite, kept apart: an invite to g1t (Settings, invite-only only, no workspace unless asked) and an invitation to a workspace (its People page)937/**
938 * Whether the menus list Settings → Invites (invites to g1t): always while
939 * sign-up takes an invite; once anyone can sign up, only for someone with
940 * invites already made to look back on, which the account menu's data says.
941 */
942function useInvitesListed(): boolean {
943 const inviteOnly = useInviteOnly();
944 const details = useFetcher<AccountMenuData | null>({ key: "account-menu" });
945 useEffect(() => {
946 if (!inviteOnly && details.state === "idle" && details.data === undefined) details.load("/settings/menu.json");
947 // eslint-disable-next-line react-hooks/exhaustive-deps
948 }, [inviteOnly]);
949 return inviteOnly || details.data?.invites_page === true;
950}
951
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas952/** Your own settings, drilled into from Your settings: one page each. */
953function AccountSettingsMenu({ username }: { username: string }) {
Merge two kinds of invite, kept apart: an invite to g1t (Settings, invite-only only, no workspace unless asked) and an invitation to a workspace (its People page)954 const invites = useInvitesListed();
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas955 const link = (page: AccountSettingsPage, icon: ReactNode) => (
956 <SidebarLink to={`/settings/${page}`} icon={icon}>
957 {ACCOUNT_SETTINGS[page].title}
958 </SidebarLink>
Usage while free is shown at cost; agents get rustfmt and clippy959 );
960 return (
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look961 <nav aria-label="Your settings" className={PANEL}>
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas962 <BackRow to="/" label="Your settings" context={username} />
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look963 <div className="mt-2 space-y-px">
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas964 {link("profile", <CircleUserRound size={15} />)}
965 {link("emails", <Mail size={15} />)}
Merge two kinds of invite, kept apart: an invite to g1t (Settings, invite-only only, no workspace unless asked) and an invitation to a workspace (its People page)966 {invites && link("invites", <Ticket size={15} />)}
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas967 </div>
968 <Rule />
969 <div className="space-y-px">
970 {link("keys", <Fingerprint size={15} />)}
971 {link("tokens", <KeyRound size={15} />)}
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look972 </div>
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas973 <Rule />
974 <div className="space-y-px">
Integrations are a directory of connectors, for a workspace and for each person975 {link("integrations", <Blocks size={15} />)}
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas976 {link("github", <GithubMark className="size-[15px]" />)}
977 {link("applications", <Plug size={15} />)}
978 </div>
979 <Rule />
980 <div className="space-y-px">
Merge main (membership, two-factor, GitHub repo roles) into tokens981 {link("two-factor", <ShieldCheck size={15} />)}
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas982 {link("security-log", <History size={15} />)}
983 </div>
Usage while free is shown at cost; agents get rustfmt and clippy984 </nav>
985 );
986}
987
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put988/**
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.989 * Code's sidebar: its Overview, the projects, what spans them and what is
990 * coming; in a project, drilled into the project's own list, and its
991 * settings one level further in. The address says which, so a link
992 * straight to a project opens the sidebar already drilled in.
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put993 */
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.994function CodeSidebar({
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look995 user,
996 shell,
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas997 missing = false,
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look998}: {
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.999 user: User;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1000 shell: ShellData;
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1001 /** The page is a 404: the address names nothing the viewer can see. */
1002 missing?: boolean;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1003}) {
Usage while free is shown at cost; agents get rustfmt and clippy1004 const ws = shell.workspace;
1005 const { pathname } = useLocation();
1006 const going = useNavigation().location?.pathname;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1007 // Where the sidebar is drilled to follows the page being gone to, so it
1008 // moves as the link is followed, not once the page arrives.
1009 const target = going ?? pathname;
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1010 // On a 404, the address is not a place: no list is drilled into from it,
1011 // except the project's own when the project is real and visible and only
1012 // something inside it is missing (a file, a commit, an issue).
1013 const lost = missing && going == null;
Usage while free is shown at cost; agents get rustfmt and clippy1014 const active = shell.repo;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1015 // In a repository, or on the way into one, its own list.
Usage while free is shown at cost; agents get rustfmt and clippy1016 const repoPath = /^\/([^/]+)\/([^/-][^/]*)(\/|$)/.exec(target);
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.1017 const reserved = new Set(["settings", "explore", "search", "new", "u", "pricing", "avatars", "workspaces", "login", "logout", "register", "verify", "forgot", "reset", "device", "oauth", "policies", "security", "support", "status", "invite", "notifications", "inbox", ".well-known"]);
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1018 // An invitation to a repository is answered before its menu means anything.
1019 const inRepo =
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1020 repoPath != null &&
1021 !reserved.has(repoPath[1]) &&
1022 repoPath[2] !== "-" &&
1023 !/^\/[^/]+\/[^/]+\/invitations\/?$/.test(target) &&
1024 (!lost || sameRepo(active, { namespace: repoPath[1]!, name: repoPath[2]! }));
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1025 // A project's settings, one level further in.
Project settings move into the sidebar, grouped, with a heading per page1026 const inRepoSettings = inRepo && REPO_SETTINGS_PAGE.test(target);
Usage while free is shown at cost; agents get rustfmt and clippy1027 // The repository the menu is for: the one loaded if it is the one being
1028 // gone to, else what the address says, at once.
1029 const targetRepo = inRepo && repoPath ? { namespace: repoPath[1], name: repoPath[2] } : null;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1030 const guessed: MenuRepo | null = targetRepo
Usage while free is shown at cost; agents get rustfmt and clippy1031 ? sameRepo(active, targetRepo)
1032 ? active
1033 : {
1034 ...targetRepo,
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.1035 member: (user.workspaces ?? []).some((m) => m.slug === targetRepo.namespace.toLowerCase()),
Usage while free is shown at cost; agents get rustfmt and clippy1036 }
1037 : null;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1038 // The viewer's role there, from the repository's page once it has loaded.
1039 const page = useRouteLoaderData("routes/repo/layout") as
1040 | { repo?: { namespace: string; name: string }; access?: ViewerAccess }
1041 | undefined;
1042 const menuRepo: MenuRepo | null =
1043 guessed && page?.access && page.repo && sameRepo(page.repo, guessed)
1044 ? { ...guessed, member: page.access.insider, settings: seesSettings(page.access), can: page.access.can }
1045 : guessed;
1046
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.1047 // The way from Code's list to the one shown.
1048 const trail: Level[] = [{ key: "main", node: ws ? <CodeMenu shell={shell} slug={ws.slug} /> : null }];
1049 if (menuRepo) {
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1050 const key = `repo:${menuRepo.namespace}/${menuRepo.name}`.toLowerCase();
1051 // Out of a project: to its workspace's projects when they are yours.
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.1052 const home = (user.workspaces ?? []).find((m) => m.slug === menuRepo.namespace.toLowerCase());
1053 const back = home ? { to: `/${home.slug}/-/projects`, label: "All projects" } : { to: ws ? `/${ws.slug}/-/overview` : "/explore", label: "Code" };
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1054 trail.push({
1055 key,
1056 node: (
1057 <RepoMenu
1058 repo={menuRepo}
1059 isPrivate={[...shell.repos, ...(shell.shared ?? [])].some((repo) => sameRepo(repo, menuRepo) && repo.isPrivate)}
1060 back={back}
1061 />
1062 ),
1063 });
1064 if (inRepoSettings) trail.push({ key: `${key}:settings`, node: <RepoSettingsMenu repo={menuRepo} /> });
1065 }
1066
Usage while free is shown at cost; agents get rustfmt and clippy1067 return (
1068 <div className="flex h-full flex-col">
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.1069 <ModeHeader title="Code" />
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1070 <Drill trail={trail} />
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1071 </div>
1072 );
1073}
1074
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.1075/**
1076 * A mode's sidebar heading: its name, quiet, under the workspace's
1077 * switcher, with what it makes at the end.
1078 */
1079export function ModeHeader({ title, action }: { title: ReactNode; action?: ReactNode }) {
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1080 return (
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.1081 <div className="flex h-9 shrink-0 items-center gap-1 pr-1 pl-3">
1082 <h2 className="min-w-0 grow truncate text-xs font-medium text-faint">{title}</h2>
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1083 {action}
1084 </div>
1085 );
1086}
1087
1088/**
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.1089 * Code's own list (beside the dock): only code. Its Overview (Mission
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1090 * control's code panels), the projects, what spans them, and what is
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.1091 * coming. The workspace's people, money and settings are elsewhere;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1092 * agents, context and memory are Agents'.
1093 */
1094function CodeMenu({ shell, slug }: { shell: ShellData; slug: string }) {
1095 const { pathname } = useLocation();
1096 const going = useNavigation().location?.pathname;
1097 const path = going ?? pathname;
1098 const at = (page: string) => path === `/${slug}/-/${page}` || path.startsWith(`/${slug}/-/${page}/`);
1099 const shared = shell.shared ?? [];
1100 return (
1101 <nav aria-label="Code" className={PANEL}>
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.1102 <div className="space-y-px">
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1103 <SidebarLink to={`/${slug}/-/overview`} icon={<LayoutDashboard size={15} />} current={at("overview")}>
1104 Overview
1105 </SidebarLink>
1106 </div>
1107 <div className="mt-3">
1108 <SidebarProjects slug={slug} shell={shell} current={at("projects")} />
1109 </div>
1110 <Rule />
1111 <div className="space-y-px">
1112 <SidebarLink to={`/${slug}/-/security`} icon={<ShieldCheck size={15} />} current={at("security") && !at("security/settings")}>
1113 Security
1114 </SidebarLink>
1115 <SidebarLink to={`/${slug}/-/packages`} icon={<Package size={15} />} current={at("packages")}>
1116 Packages
1117 </SidebarLink>
1118 {INSIGHTS && (
1119 <SidebarSoonLink to={`/${slug}/-/insights`} icon={<TrendingUp size={15} />} about={INSIGHTS.summary} current={at("insights")}>
1120 {INSIGHTS.title}
1121 </SidebarSoonLink>
1122 )}
1123 {roadmapIn("Workspace")
1124 .filter((item) => item.key !== "insights" && item.key !== "teams" && item.key !== "fleet")
1125 .map((item) => (
1126 <SidebarSoonLink key={item.key} to={`/${slug}/-/soon/${item.key}`} icon={WORKSPACE_ICONS[item.key] ?? <Sparkles size={15} />} about={item.summary}>
1127 {item.title === "Board" ? "Boards" : item.title}
1128 </SidebarSoonLink>
1129 ))}
1130 </div>
1131 {shared.length > 0 && (
1132 <>
1133 <Rule />
1134 <SidebarGroup title="Shared with you">
1135 {shared.map((repo) => (
1136 <SidebarLink
1137 key={`${repo.namespace}/${repo.name}`}
1138 to={`/${repo.namespace}/${repo.name}`}
1139 icon={repo.isPrivate ? <Lock size={15} /> : <Box size={15} />}
1140 drill="hover"
1141 >
1142 <span className="font-mono text-faint">{repo.namespace}/</span>
1143 {repo.name}
1144 </SidebarLink>
1145 ))}
1146 </SidebarGroup>
1147 </>
1148 )}
1149 </nav>
1150 );
1151}
1152
1153/** Workspace pages that sit in its Settings list, drilled into from the Workspace sidebar. */
The Runners page shows the machines a workspace's agents and workflow jobs run on, in Workspace under Compute: g1t's cloud beside your own runners, what each is running now with a link to it, what's waiting, this month's machine time and its cost (your own runners' free), where agent work and workflow jobs run, adding a runner, and groups; runner_activity in Actions says what runs where, work handed to your runners keeps its agent run, and the self-hosted runners guide says how.1154const WORKSPACE_SETTINGS = ["settings", "repositories", "tokens", "personal-access-tokens", "secrets", "actions", "webhooks", "emoji"];
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1155
1156/**
1157 * The Workspace mode's sidebar: the workspace itself, for every member.
The Runners page shows the machines a workspace's agents and workflow jobs run on, in Workspace under Compute: g1t's cloud beside your own runners, what each is running now with a link to it, what's waiting, this month's machine time and its cost (your own runners' free), where agent work and workflow jobs run, adding a runner, and groups; runner_activity in Actions says what runs where, work handed to your runners keeps its agent run, and the self-hosted runners guide says how.1158 * Its overview, money, machines, connections, policies and record, then its
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1159 * settings as a list of their own. Owner-only pages stay owner-only.
1160 */
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.1161export function WorkspaceSidebar({ slug, owner }: { slug: string; owner: boolean }) {
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1162 const { pathname } = useLocation();
1163 const going = useNavigation().location?.pathname;
1164 const path = going ?? pathname;
1165 const page = path.startsWith(`/${slug}/-/`) ? path.slice(`/${slug}/-/`.length) : "";
1166 const top = page.split("/")[0] ?? "";
1167 const at = (...pages: string[]) => pages.some((p) => page === p || page.startsWith(`${p}/`));
1168 const inSettings = WORKSPACE_SETTINGS.includes(top);
1169 const main = (
1170 <nav aria-label="Workspace" className={PANEL}>
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.1171 <div className="space-y-px">
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1172 <SidebarLink to={`/${slug}/-/workspace`} icon={<LayoutGrid size={15} />} current={at("workspace")}>
1173 Overview
1174 </SidebarLink>
1175 </div>
The Spend page says what a workspace spent, where it went and the budgets that hold it, in Workspace under Money: spent at price, agents' spend and the spend limit; by day; by agent, person, channel, model, kind of work and product; budgets from the workspace down to each person, agent and task, with what happens at 100%; the costliest tasks, each with a receipt of every session at the provider's price and what was charged; and how it's priced. Everyone sees what agents spent for them, and owners and billing managers the whole workspace; each person can have a monthly budget agents keep to, and the spend pill in the top bar shows your month or the workspace's against its limit. The spend guide says how.1176 <SidebarGroup title="Money" className="mt-3">
1177 <SidebarLink to={`/${slug}/-/spend`} icon={<Coins size={15} />} current={at("spend")}>
1178 Spend
1179 </SidebarLink>
The Marketplace is where a workspace finds what to add, reached from Apps: the agent catalog of roles with who already does each job and Add to workspace; every integration with whether it's connected; g1t's own extensions, listed as Soon; and requests, where members ask and owners add or turn down, each told by a notification. Underneath, an extension is a manifest (publisher and tier, source and version from a tag, scopes, the domains its data goes to, its page on g1tusercontent.com, no price) and an install pins its version with an off switch, a budget and the audit log. Apps lists only what was added from the Marketplace, with pins; g1t's own pages stay in their sidebars, and AI Gateway joins Workspace's. The marketplace guide says how.1180 <SidebarLink to={`/${slug}/-/usage`} icon={<BarChart3 size={15} />} current={at("usage")}>
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1181 Usage
1182 </SidebarLink>
The Marketplace is where a workspace finds what to add, reached from Apps: the agent catalog of roles with who already does each job and Add to workspace; every integration with whether it's connected; g1t's own extensions, listed as Soon; and requests, where members ask and owners add or turn down, each told by a notification. Underneath, an extension is a manifest (publisher and tier, source and version from a tag, scopes, the domains its data goes to, its page on g1tusercontent.com, no price) and an install pins its version with an off switch, a budget and the audit log. Apps lists only what was added from the Marketplace, with pins; g1t's own pages stay in their sidebars, and AI Gateway joins Workspace's. The marketplace guide says how.1183 <SidebarLink to={`/${slug}/-/gateway`} icon={<Network size={15} />} current={at("gateway")}>
1184 AI Gateway
1185 </SidebarLink>
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1186 <SidebarLink to={`/${slug}/-/billing`} icon={<CreditCard size={15} />} current={at("billing")}>
1187 Billing and plans
1188 </SidebarLink>
1189 </SidebarGroup>
The Runners page shows the machines a workspace's agents and workflow jobs run on, in Workspace under Compute: g1t's cloud beside your own runners, what each is running now with a link to it, what's waiting, this month's machine time and its cost (your own runners' free), where agent work and workflow jobs run, adding a runner, and groups; runner_activity in Actions says what runs where, work handed to your runners keeps its agent run, and the self-hosted runners guide says how.1190 {owner && (
1191 <SidebarGroup title="Compute" className="mt-3">
1192 <SidebarLink to={`/${slug}/-/runners`} icon={<ServerCog size={15} />} current={at("runners")}>
1193 Runners
1194 </SidebarLink>
1195 </SidebarGroup>
1196 )}
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1197 <SidebarGroup title="Connections" className="mt-3">
1198 <SidebarLink to={`/${slug}/-/integrations`} icon={<Plug size={15} />} current={at("integrations")}>
1199 Integrations
1200 </SidebarLink>
1201 </SidebarGroup>
1202 <SidebarGroup title="Security policies" className="mt-3">
1203 <SidebarLink to={`/${slug}/-/security/settings`} icon={<ShieldCheck size={15} />} current={at("security/settings")}>
1204 Security settings
1205 </SidebarLink>
1206 <SidebarLink to={`/${slug}/-/guardrails`} icon={<Gauge size={15} />} current={at("guardrails")}>
1207 Guardrails
1208 </SidebarLink>
1209 <SidebarLink to={`/${slug}/-/rules`} icon={<Scale size={15} />} current={at("rules")}>
1210 Rules
1211 </SidebarLink>
1212 </SidebarGroup>
1213 <Rule />
1214 <div className="space-y-px">
1215 <SidebarLink to={`/${slug}/-/audit`} icon={<History size={15} />} current={at("audit")}>
1216 Audit log
1217 </SidebarLink>
1218 <SidebarLink to={owner ? `/${slug}/-/settings` : `/${slug}/-/repositories`} icon={<Settings size={15} />} drill current={inSettings}>
1219 Settings
1220 </SidebarLink>
1221 </div>
1222 </nav>
1223 );
1224 const settings = (
1225 <nav aria-label="Workspace settings" className={PANEL}>
1226 <BackRow to={`/${slug}/-/workspace`} label="Settings" context={slug} />
1227 <div className="mt-2 space-y-px">
1228 {owner && (
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1229 <SidebarLink to={`/${slug}/-/settings`} icon={<Settings size={15} />} end>
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1230 General
1231 </SidebarLink>
1232 )}
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1233 <SidebarLink to={`/${slug}/-/settings/chat`} icon={<MessagesSquare size={15} />}>
1234 Chat
1235 </SidebarLink>
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1236 <SidebarLink to={`/${slug}/-/repositories`} icon={<BookMarked size={15} />}>
1237 Repositories
1238 </SidebarLink>
1239 <SidebarLink to={`/${slug}/-/tokens`} icon={<KeyRound size={15} />}>
1240 Access tokens
1241 </SidebarLink>
1242 {owner && (
1243 <SidebarLink to={`/${slug}/-/personal-access-tokens`} icon={<UserRoundKey size={15} />}>
1244 Personal access tokens
1245 </SidebarLink>
1246 )}
1247 <SidebarLink to={`/${slug}/-/webhooks`} icon={<Webhook size={15} />}>
1248 Webhooks
1249 </SidebarLink>
1250 <SidebarLink to={`/${slug}/-/emoji`} icon={<Smile size={15} />}>
1251 Emoji
1252 </SidebarLink>
1253 </div>
1254 <SidebarGroup title="Runs" className="mt-3">
1255 <SidebarLink to={`/${slug}/-/secrets`} icon={<Lock size={15} />}>
1256 Secrets and variables
1257 </SidebarLink>
1258 <SidebarLink to={`/${slug}/-/actions`} icon={<PlayCircle size={15} />}>
1259 Actions
1260 </SidebarLink>
1261 </SidebarGroup>
1262 </nav>
1263 );
1264 const trail: Level[] = [{ key: "workspace", node: main }];
1265 if (inSettings) trail.push({ key: "workspace:settings", node: settings });
1266 return (
1267 <div className="flex h-full flex-col">
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.1268 <ModeHeader title="Workspace" />
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1269 <Drill trail={trail} />
1270 </div>
1271 );
1272}
1273
People and teams are front and centre: one directory of people and agents with presence, local time, titles, teams and what each owns; profiles with manager and reports and the agents they work with; an org chart with each team's agents beside the person who leads it; and teams of any mix, with a lead, a channel, a budget agents keep to and the agents on them. Every agent is told its teams each turn (who leads, who owns what, who's around and who to page), and the team page shows exactly what. Member management is Members and invites; the people and teams guide says how.1274/**
1275 * People's sidebar: everyone in the workspace, people and agents; its
1276 * teams; the org chart; and, to manage who belongs, members and invites.
1277 */
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.1278function PeopleSidebar({ slug }: { slug: string }) {
1279 const { pathname } = useLocation();
1280 const going = useNavigation().location?.pathname;
1281 const path = going ?? pathname;
1282 const at = (page: string) => path === `/${slug}/-/${page}` || path.startsWith(`/${slug}/-/${page}/`);
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1283 return (
1284 <div className="flex h-full flex-col">
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.1285 <ModeHeader title="People" />
1286 <nav aria-label="People" className={PANEL}>
1287 <div className="space-y-px">
1288 <SidebarLink to={`/${slug}/-/people`} icon={<Users size={15} />} current={at("people")}>
1289 Everyone
1290 </SidebarLink>
1291 <SidebarLink to={`/${slug}/-/teams`} icon={<UsersRound size={15} />} current={at("teams")}>
1292 Teams
1293 </SidebarLink>
People and teams are front and centre: one directory of people and agents with presence, local time, titles, teams and what each owns; profiles with manager and reports and the agents they work with; an org chart with each team's agents beside the person who leads it; and teams of any mix, with a lead, a channel, a budget agents keep to and the agents on them. Every agent is told its teams each turn (who leads, who owns what, who's around and who to page), and the team page shows exactly what. Member management is Members and invites; the people and teams guide says how.1294 <SidebarLink to={`/${slug}/-/org-chart`} icon={<Network size={15} />} current={at("org-chart")}>
1295 Org chart
1296 </SidebarLink>
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.1297 </div>
People and teams are front and centre: one directory of people and agents with presence, local time, titles, teams and what each owns; profiles with manager and reports and the agents they work with; an org chart with each team's agents beside the person who leads it; and teams of any mix, with a lead, a channel, a budget agents keep to and the agents on them. Every agent is told its teams each turn (who leads, who owns what, who's around and who to page), and the team page shows exactly what. Member management is Members and invites; the people and teams guide says how.1298 <SidebarGroup title="Membership" className="mt-3">
1299 <SidebarLink to={`/${slug}/-/members`} icon={<UserPlus size={15} />} current={at("members")}>
1300 Members and invites
1301 </SidebarLink>
1302 </SidebarGroup>
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.1303 </nav>
1304 </div>
1305 );
1306}
1307
1308/**
1309 * Notifications' sidebar: what you have not finished with, what you saved
1310 * and what is done; then why you were told, which narrows any of them.
1311 */
1312function NotificationsSidebar({ counts }: { counts: InboxCounts | null }) {
1313 const { search } = useLocation();
1314 const params = new URLSearchParams(search);
1315 const view = inboxView(params.get("view"));
1316 const reason = inboxReason(params.get("reason"));
1317 const tab = params.get("tab");
1318 const address = (changes: Record<string, string | null>) => {
1319 const merged: Record<string, string | null> = { tab, view: view === "inbox" ? null : view, reason, ...changes };
1320 const next = new URLSearchParams();
1321 for (const [name, value] of Object.entries(merged)) if (value) next.set(name, value);
1322 const query = next.toString();
1323 return query ? `/notifications?${query}` : "/notifications";
1324 };
1325 const views = [
1326 { view: "inbox", label: "Everything", icon: <Bell size={15} />, count: counts?.unread },
1327 { view: "saved", label: "Saved", icon: <Bookmark size={15} /> },
1328 { view: "done", label: "Done", icon: <Check size={15} /> },
1329 ] as const;
1330 return (
1331 <div className="flex h-full flex-col">
1332 <ModeHeader title="Notifications" />
1333 <nav aria-label="Notifications" className={PANEL}>
1334 <div className="space-y-px">
1335 {views.map((entry) => (
1336 <SidebarLink
1337 key={entry.view}
1338 to={address({ view: entry.view === "inbox" ? null : entry.view, before: null })}
1339 icon={entry.icon}
1340 count={"count" in entry ? (entry.count ?? undefined) : undefined}
1341 current={view === entry.view}
1342 >
1343 {entry.label}
1344 </SidebarLink>
1345 ))}
1346 </div>
1347 <SidebarGroup title="Why you were told" className="mt-4">
1348 {REASON_FILTERS.map((entry) => (
1349 <SidebarLink
1350 key={entry.reason ?? "any"}
1351 to={address({ reason: entry.reason, before: null })}
1352 icon={<span className="block size-[15px]" />}
1353 current={reason === entry.reason}
1354 >
1355 {entry.reason == null ? "Any reason" : entry.label}
1356 </SidebarLink>
1357 ))}
1358 </SidebarGroup>
1359 </nav>
1360 </div>
1361 );
1362}
1363
1364/** Your own settings, beside the page: under the account menu, not any workspace's. */
1365export function AccountSidebar({ username }: { username: string }) {
1366 return (
1367 <div className="flex h-full flex-col">
1368 <ModeHeader title="Your account" />
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1369 <div className="min-h-0 grow">
1370 <AccountSettingsMenu username={username} />
Usage while free is shown at cost; agents get rustfmt and clippy1371 </div>
1372 </div>
1373 );
1374}
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1375
Usage while free is shown at cost; agents get rustfmt and clippy1376/** Words for the sections a path can end in. */
1377const SECTIONS: Record<string, string> = {
1378 issues: "Issues",
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1379 milestones: "Milestones",
1380 labels: "Labels",
Usage while free is shown at cost; agents get rustfmt and clippy1381 pulls: "Pull requests",
1382 queue: "Merge queue",
1383 commits: "Commits",
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales1384 plans: "Outcomes",
1385 actions: "Workflows",
1386 soon: "Soon",
Deployments: a preview for every pull request, production on g1t.page1387 deployments: "Deployments",
Projects: what a workspace builds and runs, first on every page1388 repository: "Repository",
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1389 access: "Access",
1390 invitations: "Invitation",
1391 repositories: "Repositories",
Branches and Tags pages, each file's last commit, and the branch menu on files1392 branches: "Branches",
1393 tags: "Tags",
Compare: any two branches, the commits one has that the other does not, and the diff, with Open a pull request1394 compare: "Compare",
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales1395 code: "Files",
Usage while free is shown at cost; agents get rustfmt and clippy1396 secrets: "Secrets and variables",
1397 settings: "Settings",
Navigation: the workspace's own page with tabs, pins and recent in the sidebar1398 people: "People",
People and teams are front and centre: one directory of people and agents with presence, local time, titles, teams and what each owns; profiles with manager and reports and the agents they work with; an org chart with each team's agents beside the person who leads it; and teams of any mix, with a lead, a channel, a budget agents keep to and the agents on them. Every agent is told its teams each turn (who leads, who owns what, who's around and who to page), and the team page shows exactly what. Member management is Members and invites; the people and teams guide says how.1399 "org-chart": "Org chart",
1400 members: "Members and invites",
Navigation: the workspace's own page with tabs, pins and recent in the sidebar1401 projects: "Projects",
1402 teams: "Teams",
Usage while free is shown at cost; agents get rustfmt and clippy1403 tokens: "Access tokens",
Settings: fine-grained tokens, workspace token Admin, workspace personal access token rules1404 "personal-access-tokens": "Personal access tokens",
The Spend page says what a workspace spent, where it went and the budgets that hold it, in Workspace under Money: spent at price, agents' spend and the spend limit; by day; by agent, person, channel, model, kind of work and product; budgets from the workspace down to each person, agent and task, with what happens at 100%; the costliest tasks, each with a receipt of every session at the provider's price and what was charged; and how it's priced. Everyone sees what agents spent for them, and owners and billing managers the whole workspace; each person can have a monthly budget agents keep to, and the spend pill in the top bar shows your month or the workspace's against its limit. The spend guide says how.1405 spend: "Spend",
1406 receipts: "Receipts",
Usage while free is shown at cost; agents get rustfmt and clippy1407 usage: "Usage",
Site: the AI Gateway page's breadcrumb reads "AI Gateway"1408 gateway: "AI Gateway",
Secrets and variables: one list, rows per environment, for workflows and deployments1409 billing: "Billing and plans",
Usage while free is shown at cost; agents get rustfmt and clippy1410 integrations: "Integrations",
1411 webhooks: "Webhooks",
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1412 emoji: "Emoji",
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1413 domains: "Domains",
1414 guardrails: "Guardrails",
Merge rulesets: branch and tag rules, agent-first, enforced on push and merge1415 rules: "Rules",
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1416 audit: "Audit log",
Files pages say Files in the trail and keep the description in About only1417 tree: "Files",
1418 blob: "Files",
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail1419 agents: "Agents",
1420 context: "Context",
1421 memory: "Memory",
1422 security: "Security",
1423 packages: "Packages",
1424 runners: "Runners",
Merge branch 'worktree-agent-a3abfcce648e87dca'1425 environments: "Environments",
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail1426 workflows: "Workflows",
1427 observability: "Observability",
1428 insights: "Insights",
1429 sessions: "Sessions",
Chat and workspace agents: channels, DMs and named agents you talk to1430 chat: "Chat",
Artifacts is a mode in the rail, the shell and the phone's tab bar in place of Docs: its home lists everything you can open by day or as cards under All, Yours and Shared with you, with search, filters and tiles to start a doc (slides, designs and dashboards say they are coming soon), and its sidebar holds favorites, spaces, Private, Shared, projects' docs and the trash.1431 artifacts: "Artifacts",
The front page is Home: where you're needed comes first, however long ago it started, with what's at stake and how long it has waited; then what happened since you were last here, in words, with the agent work that settled, what landed, what deployed, what was decided and what was spent, switchable to the last 24 hours or 7 days; then what's running now. Your last visit is kept with your account, so it's the same on every device; Today's old address leads here. The home guide says how.1432 home: "Home",
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.1433 apps: "Apps",
The Marketplace is where a workspace finds what to add, reached from Apps: the agent catalog of roles with who already does each job and Add to workspace; every integration with whether it's connected; g1t's own extensions, listed as Soon; and requests, where members ask and owners add or turn down, each told by a notification. Underneath, an extension is a manifest (publisher and tier, source and version from a tag, scopes, the domains its data goes to, its page on g1tusercontent.com, no price) and an install pins its version with an off switch, a budget and the audit log. Apps lists only what was added from the Marketplace, with pins; g1t's own pages stay in their sidebars, and AI Gateway joins Workspace's. The marketplace guide says how.1434 marketplace: "Marketplace",
Chat and workspace agents: channels, DMs and named agents you talk to1435 "code-access": "Code access",
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1436 overview: "Overview",
1437 workspace: "Workspace",
Usage while free is shown at cost; agents get rustfmt and clippy1438};
1439
Merge branch 'worktree-agent-a3abfcce648e87dca'1440/** Settings pages whose name differs from the section's of the same word. */
1441const SETTINGS_SECTIONS: Record<string, string> = { branches: "Branches and merging", actions: "Actions" };
1442
Usage while free is shown at cost; agents get rustfmt and clippy1443/** Where the page is, as a trail of links: workspace / repository / section. */
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.1444function Breadcrumbs({
1445 pathname,
1446 missing,
1447 repo,
1448 workspace,
1449}: {
1450 pathname: string;
1451 missing?: boolean;
1452 repo?: ShellData["repo"];
1453 /** The workspace you are in: the switcher names it, so the trail starts after it. */
1454 workspace: string | null;
1455}) {
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1456 // A 404 names nothing from the address, unless the project is real and
1457 // visible and only something inside it is missing.
1458 const visibleRepo = /^\/([^/]+)\/([^/-][^/]*)(\/|$)/.exec(pathname);
1459 if (missing && !(visibleRepo && sameRepo(repo ?? null, { namespace: visibleRepo[1]!, name: visibleRepo[2]! }))) {
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1460 return <Here>Not found</Here>;
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1461 }
Usage while free is shown at cost; agents get rustfmt and clippy1462 const parts = pathname.split("/").filter(Boolean);
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.1463 const reserved = ["settings", "explore", "new", "search", "workspaces", "policies", "security", "support", "status", "invite", "notifications"];
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1464 if (parts.length === 0) return <Here>Home</Here>;
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1465 // Your settings: Settings / Emails.
1466 if (parts[0] === "settings") {
1467 const page = accountSettingsPage(pathname);
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1468 return <Trail trail={[{ label: "Settings", to: FIRST_SETTINGS_PAGE }, ...(page ? [{ label: ACCOUNT_SETTINGS[page].title, to: `/settings/${page}` }] : [])]} />;
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1469 }
Usage while free is shown at cost; agents get rustfmt and clippy1470 if (reserved.includes(parts[0]!)) {
1471 const words: Record<string, string> = {
1472 settings: "Account",
1473 explore: "Explore",
Projects live: fixes from walking them end to end1474 new: "New project",
Usage while free is shown at cost; agents get rustfmt and clippy1475 search: "Search",
1476 workspaces: "New workspace",
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1477 policies: "Policies",
1478 security: "Security",
1479 support: "Support",
1480 status: "Status",
1481 invite: "Invite",
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.1482 notifications: "Notifications",
Usage while free is shown at cost; agents get rustfmt and clippy1483 };
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1484 return <Here>{words[parts[0]!]}</Here>;
Usage while free is shown at cost; agents get rustfmt and clippy1485 }
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put1486 // A person's profile, by their handle.
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1487 if (parts[0] === "u" && parts[1]) return <ProfileCrumb username={parts[1]} />;
Usage while free is shown at cost; agents get rustfmt and clippy1488 const [owner, second, third, fourth] = parts;
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.1489 const ours = workspace != null && owner!.toLowerCase() === workspace.toLowerCase();
1490 const trail: Crumb[] = ours ? [] : [{ label: owner!, to: `/${owner}`, mono: true }];
Usage while free is shown at cost; agents get rustfmt and clippy1491 if (second === "-") {
1492 const page = `/${owner}/-/${third}`;
1493 if (third && SETTINGS_PAGE.test(page)) {
1494 trail.push({ label: "Settings", to: `/${owner}/-/settings` });
1495 trail.push({ label: third === "settings" ? "General" : (SECTIONS[third] ?? third), to: page });
The Marketplace is where a workspace finds what to add, reached from Apps: the agent catalog of roles with who already does each job and Add to workspace; every integration with whether it's connected; g1t's own extensions, listed as Soon; and requests, where members ask and owners add or turn down, each told by a notification. Underneath, an extension is a manifest (publisher and tier, source and version from a tag, scopes, the domains its data goes to, its page on g1tusercontent.com, no price) and an install pins its version with an off switch, a budget and the audit log. Apps lists only what was added from the Marketplace, with pins; g1t's own pages stay in their sidebars, and AI Gateway joins Workspace's. The marketplace guide says how.1496 } else if (third) {
1497 trail.push({ label: SECTIONS[third] ?? third, to: page });
The Marketplace adds what g1t doesn't do and connects what you already use: extensions (Mail, Support, CRM, Recruiting, On-call, and bridges to a helpdesk, CRM or ERP you run, all Soon), starter kits, and integrations connected by the workspace or by each person; agents aren't installed there. Agent templates live in Agents, as starting points you configure, at Agents → Templates, and the Marketplace's old agent addresses lead there. The marketplace and agents guides say how.1498 // The Marketplace names its tab (Marketplace / Extensions), and Agents its templates.
1499 const tabs: Record<string, string> =
1500 third === "marketplace" ? { integrations: "Integrations", extensions: "Extensions", requests: "Requests" } : third === "agents" ? { templates: "Templates" } : {};
1501 const tab = fourth ? tabs[fourth] : undefined;
The Marketplace is where a workspace finds what to add, reached from Apps: the agent catalog of roles with who already does each job and Add to workspace; every integration with whether it's connected; g1t's own extensions, listed as Soon; and requests, where members ask and owners add or turn down, each told by a notification. Underneath, an extension is a manifest (publisher and tier, source and version from a tag, scopes, the domains its data goes to, its page on g1tusercontent.com, no price) and an install pins its version with an off switch, a budget and the audit log. Apps lists only what was added from the Marketplace, with pins; g1t's own pages stay in their sidebars, and AI Gateway joins Workspace's. The marketplace guide says how.1502 if (tab) trail.push({ label: tab, to: `${page}/${fourth}` });
1503 }
Usage while free is shown at cost; agents get rustfmt and clippy1504 } else if (second) {
1505 const repo = `/${owner}/${second}`;
1506 trail.push({ label: second, to: repo, mono: true });
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1507 if (third === "pull" && fourth) trail.push({ label: `Pull request #${fourth}`, short: `#${fourth}`, to: `${repo}/pull/${fourth}` });
1508 else if (third === "issues" && fourth && fourth !== "new") trail.push({ label: `Issue #${fourth}`, short: `#${fourth}`, to: `${repo}/issues/${fourth}` });
Usage while free is shown at cost; agents get rustfmt and clippy1509 else if (third === "commit" && fourth) trail.push({ label: fourth.slice(0, 7), to: `${repo}/commit/${fourth}`, mono: true });
Secrets and variables: one list, rows per environment, for workflows and deployments1510 else if (third && SECTIONS[third]) {
1511 trail.push({ label: SECTIONS[third]!, to: `${repo}/${third}` });
1512 // A settings page names which one: Settings / Secrets and variables.
1513 if (third === "settings" && fourth && SECTIONS[fourth]) {
Merge branch 'worktree-agent-a3abfcce648e87dca'1514 trail.push({ label: SETTINGS_SECTIONS[fourth] ?? SECTIONS[fourth]!, to: `${repo}/settings/${fourth}` });
Secrets and variables: one list, rows per environment, for workflows and deployments1515 }
1516 }
Usage while free is shown at cost; agents get rustfmt and clippy1517 }
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.1518 if (trail.length === 0) trail.push({ label: "Overview", to: `/${owner}` });
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1519 return <Trail trail={trail} />;
1520}
1521
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1522/** A profile's place in the top bar: the person's avatar and @handle, from the page once it has loaded. */
1523function ProfileCrumb({ username }: { username: string }) {
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers1524 const page = useRouteLoaderData("routes/user") as { profile?: { username: string; displayUsername?: string | null; avatar: string | null } } | undefined;
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1525 const profile = page?.profile?.username.toLowerCase() === username.toLowerCase() ? page.profile : null;
1526 return (
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1527 <Breadcrumb className="min-w-0">
1528 <BreadcrumbList>
1529 <BreadcrumbItem>
1530 <BreadcrumbPage asChild className="flex items-center gap-2 hover:bg-raised">
1531 <Link to={`/u/${profile?.username ?? username}`}>
1532 <Avatar name={profile?.username ?? username} image={profile?.avatar ?? null} size={20} />
1533 <span className="truncate font-mono text-[0.8125rem]">@{profile ? shownUsername(profile) : username}</span>
1534 </Link>
1535 </BreadcrumbPage>
1536 </BreadcrumbItem>
1537 </BreadcrumbList>
1538 </Breadcrumb>
1539 );
1540}
1541
1542/** A page with no trail to it, such as Today or Search: its name alone. */
1543function Here({ children }: { children: ReactNode }) {
1544 return (
1545 <Breadcrumb className="min-w-0">
1546 <BreadcrumbList>
1547 <BreadcrumbItem>
1548 <BreadcrumbPage>{children}</BreadcrumbPage>
1549 </BreadcrumbItem>
1550 </BreadcrumbList>
1551 </Breadcrumb>
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1552 );
1553}
1554
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1555/** One link of the trail; `short` is what a phone shows when it is the page itself. */
1556type Crumb = { label: string; to: string; mono?: boolean; short?: string };
1557
1558/**
1559 * The trail of links. On a phone there is room for one: the page itself,
1560 * with a way back to where it sits; the whole trail from a wider screen up.
1561 */
1562function Trail({ trail }: { trail: Crumb[] }) {
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1563 // Up on a phone, unless up is the workspace itself: its pages are the tabs.
1564 const up = trail.length > 1 && !/^\/[^/]+$/.test(trail[trail.length - 2]!.to) ? trail[trail.length - 2]! : null;
Usage while free is shown at cost; agents get rustfmt and clippy1565 return (
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1566 <Breadcrumb className="flex min-w-0 items-center">
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1567 {up && (
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1568 <Button asChild variant="ghost" size="icon-bar" className="-ml-1 sm:hidden">
1569 <Link to={up.to} prefetch="intent" aria-label={`Back to ${up.label}`}>
1570 <ChevronLeft size={16} />
1571 </Link>
1572 </Button>
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1573 )}
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1574 <BreadcrumbList>
1575 {trail.map((crumb, index) => {
1576 const last = index === trail.length - 1;
1577 const label =
1578 last && crumb.short ? (
1579 <>
1580 <span className="sm:hidden">{crumb.short}</span>
1581 <span className="hidden sm:inline">{crumb.label}</span>
1582 </>
1583 ) : (
1584 crumb.label
1585 );
1586 const mono = crumb.mono ? "font-mono text-[0.8125rem]" : "";
1587 return (
1588 <Fragment key={index}>
1589 {index > 0 && <BreadcrumbSeparator className="max-sm:hidden" />}
1590 <BreadcrumbItem className={last ? "" : "max-sm:hidden"}>
1591 {last ? (
1592 // The page you are on is still a link: to its own top, as the trail always was.
1593 <BreadcrumbPage asChild className={`hover:bg-raised ${mono}`}>
1594 <Link to={crumb.to} prefetch="intent">
1595 {label}
1596 </Link>
1597 </BreadcrumbPage>
1598 ) : (
1599 <BreadcrumbLink asChild className={mono}>
1600 <Link to={crumb.to} prefetch="intent">
1601 {label}
1602 </Link>
1603 </BreadcrumbLink>
1604 )}
1605 </BreadcrumbItem>
1606 </Fragment>
1607 );
1608 })}
1609 </BreadcrumbList>
1610 </Breadcrumb>
Usage while free is shown at cost; agents get rustfmt and clippy1611 );
1612}
1613
Search across all of g1t, Explore, and a command palette1614type Command = PaletteCommand;
Usage while free is shown at cost; agents get rustfmt and clippy1615
1616/** Everything the palette can jump to, from what the sidebar already knows. */
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.1617function commandsFor(user: User, shell: ShellData): Command[] {
1618 const ws = shell.workspace;
Usage while free is shown at cost; agents get rustfmt and clippy1619 const commands: Command[] = [
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.1620 ...(ws
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1621 ? [
The front page is Home: where you're needed comes first, however long ago it started, with what's at stake and how long it has waited; then what happened since you were last here, in words, with the agent work that settled, what landed, what deployed, what was decided and what was spent, switchable to the last 24 hours or 7 days; then what's running now. Your last visit is kept with your account, so it's the same on every device; Today's old address leads here. The home guide says how.1622 { label: "Home", to: homePagePath(ws.slug), icon: <House size={15} /> },
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.1623 { label: "Chat", to: `/${ws.slug}/-/chat`, icon: <MessagesSquare size={15} /> },
1624 { label: "Agents", to: `/${ws.slug}/-/agents`, icon: <Sparkles size={15} /> },
1625 ...(hasCodeAccess(ws) ? [{ label: "Code overview", to: `/${ws.slug}/-/overview`, icon: <Code2 size={15} /> }] : []),
1626 { label: "Artifacts", to: `/${ws.slug}/-/artifacts`, icon: <Shapes size={15} /> },
1627 { label: "Apps", hint: "Everything installed that you can use", to: `/${ws.slug}/-/apps`, icon: <LayoutGrid size={15} /> },
The Marketplace adds what g1t doesn't do and connects what you already use: extensions (Mail, Support, CRM, Recruiting, On-call, and bridges to a helpdesk, CRM or ERP you run, all Soon), starter kits, and integrations connected by the workspace or by each person; agents aren't installed there. Agent templates live in Agents, as starting points you configure, at Agents → Templates, and the Marketplace's old agent addresses lead there. The marketplace and agents guides say how.1628 { label: "Marketplace", hint: "Extensions and integrations to add", to: `/${ws.slug}/-/marketplace`, icon: <Store size={15} /> },
1629 { label: "Agent templates", hint: "Starting points for a new agent", to: `/${ws.slug}/-/agents/templates`, icon: <Bot size={15} /> },
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.1630 { label: "Workspace", hint: "Billing, policies, settings", to: `/${ws.slug}/-/workspace`, icon: <Building2 size={15} /> },
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1631 ]
1632 : []),
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step1633 ...(shell.repos.length > 0
g1t is one name: its agent's work, commits and comments show as @g1t, and nobody can claim g1t or g1t-agent1634 ? [{ label: "Put an agent on it", hint: "Open an issue and assign g1t", to: "/?agent=new", icon: <Sparkles size={15} /> }]
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step1635 : []),
Usage while free is shown at cost; agents get rustfmt and clippy1636 { label: "Explore repositories", to: "/explore", icon: <Compass size={15} /> },
Search across all of g1t, Explore, and a command palette1637 { label: "Search g1t", hint: "Repositories, code, issues, people", to: "/search", icon: <Search size={15} /> },
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.1638 { label: "Notifications", hint: "What needs you", to: "/notifications", icon: <Bell size={15} /> },
Projects: what a workspace builds and runs, first on every page1639 { label: "New project", to: "/new", icon: <Plus size={15} /> },
Usage while free is shown at cost; agents get rustfmt and clippy1640 { label: "New workspace", to: "/workspaces/new", icon: <Plus size={15} /> },
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1641 { label: "Your settings", to: FIRST_SETTINGS_PAGE, icon: <Settings size={15} /> },
1642 ...(Object.keys(ACCOUNT_SETTINGS) as AccountSettingsPage[])
1643 .filter((page) => page !== "profile")
1644 .map((page) => ({ label: ACCOUNT_SETTINGS[page].title, hint: "Your settings", to: `/settings/${page}`, icon: <Settings size={15} /> })),
You choose how g1t looks: Auto follows your system, Light and Dark stay put, set from the account menu, the phone's You and help sheet, Settings → Account or the command palette; the page is drawn in your choice from the first byte, every colour has a light value that reads at 4.5:1 or better, code and diffs are highlighted for both, diagrams and the document editor follow along, the product tour and the g1t mark's avatar stay dark, and Dark is what you see until you choose; the workspaces guide says how.1645 ...THEME_COMMANDS,
Usage while free is shown at cost; agents get rustfmt and clippy1646 ];
1647 const repo = shell.repo;
1648 if (repo) {
1649 const base = `/${repo.namespace}/${repo.name}`;
1650 const name = `${repo.namespace}/${repo.name}`;
1651 commands.unshift(
Projects: what a workspace builds and runs, first on every page1652 { label: "Overview", hint: name, to: base, icon: <LayoutGrid size={15} /> },
1653 { label: "Code", hint: name, to: `${base}/code`, icon: <Code2 size={15} /> },
Usage while free is shown at cost; agents get rustfmt and clippy1654 { label: "Issues", hint: name, to: `${base}/issues`, icon: <CircleDot size={15} /> },
1655 { label: "New issue", hint: name, to: `${base}/issues/new`, icon: <Plus size={15} /> },
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step1656 ...(repo.member
1657 ? [{ label: `Put an agent on ${repo.name}`, hint: name, to: `${base}/issues/new?agent=1`, icon: <Sparkles size={15} /> }]
1658 : []),
Usage while free is shown at cost; agents get rustfmt and clippy1659 { label: "Pull requests", hint: name, to: `${base}/pulls`, icon: <GitPullRequest size={15} /> },
1660 { label: "Commits", hint: name, to: `${base}/commits`, icon: <History size={15} /> },
1661 ...(repo.member
1662 ? [
1663 { label: "Plan work", hint: name, to: `${base}/plans`, icon: <ListTree size={15} /> },
Projects: what a workspace builds and runs, first on every page1664 { label: "Deployments", hint: name, to: `${base}/deployments`, icon: <Rocket size={15} /> },
1665 { label: "Secrets and variables", hint: name, to: `${base}/settings/secrets`, icon: <Lock size={15} /> },
1666 { label: "Project settings", hint: name, to: `${base}/settings`, icon: <Settings size={15} /> },
1667 { label: "Repository settings", hint: name, to: `${base}/settings/repository`, icon: <Settings size={15} /> },
Usage while free is shown at cost; agents get rustfmt and clippy1668 ]
1669 : []),
1670 );
1671 }
1672 for (const membership of user.workspaces ?? []) {
1673 commands.push(
Workspace names and icons, and a component kit for every control1674 { label: displayName(membership), hint: `Workspace · ${membership.slug}`, to: `/${membership.slug}`, icon: <Avatar name={membership.slug} image={membership.avatar} size={15} square /> },
Navigation: the workspace's own page with tabs, pins and recent in the sidebar1675 { label: "All projects", hint: membership.slug, to: `/${membership.slug}/-/projects`, icon: <LayoutGrid size={15} /> },
1676 { label: "People", hint: membership.slug, to: `/${membership.slug}/-/people`, icon: <Users size={15} /> },
The Spend page says what a workspace spent, where it went and the budgets that hold it, in Workspace under Money: spent at price, agents' spend and the spend limit; by day; by agent, person, channel, model, kind of work and product; budgets from the workspace down to each person, agent and task, with what happens at 100%; the costliest tasks, each with a receipt of every session at the provider's price and what was charged; and how it's priced. Everyone sees what agents spent for them, and owners and billing managers the whole workspace; each person can have a monthly budget agents keep to, and the spend pill in the top bar shows your month or the workspace's against its limit. The spend guide says how.1677 { label: "Spend", hint: `${membership.slug} · Budgets and receipts`, to: `/${membership.slug}/-/spend`, icon: <Coins size={15} /> },
Usage while free is shown at cost; agents get rustfmt and clippy1678 { label: "Usage", hint: membership.slug, to: `/${membership.slug}/-/usage`, icon: <BarChart3 size={15} /> },
Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens1679 { label: "AI Gateway", hint: `${membership.slug} · Usage`, to: `/${membership.slug}/-/gateway`, icon: <Network size={15} /> },
Projects: what a workspace builds and runs, first on every page1680 { label: "Billing and plans", hint: `${membership.slug} · Settings`, to: `/${membership.slug}/-/billing`, icon: <CreditCard size={15} /> },
Usage while free is shown at cost; agents get rustfmt and clippy1681 { label: "Access tokens", hint: `${membership.slug} · Settings`, to: `/${membership.slug}/-/tokens`, icon: <KeyRound size={15} /> },
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1682 { label: "Integrations", hint: membership.slug, to: `/${membership.slug}/-/integrations`, icon: <Plug size={15} /> },
Usage while free is shown at cost; agents get rustfmt and clippy1683 );
1684 }
1685 for (const listed of shell.repos) {
1686 commands.push({
Projects: what a workspace builds and runs, first on every page1687 label: listed.title ?? listed.name,
1688 hint: `${listed.namespace} · Project`,
Usage while free is shown at cost; agents get rustfmt and clippy1689 to: `/${listed.namespace}/${listed.name}`,
Projects: what a workspace builds and runs, first on every page1690 icon: <Box size={15} />,
Usage while free is shown at cost; agents get rustfmt and clippy1691 });
1692 }
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step1693 // "Put an agent on …": one per project, after the projects themselves.
1694 for (const listed of shell.repos) {
1695 if (repo && listed.namespace === repo.namespace && listed.name === repo.name) continue;
1696 commands.push({
1697 label: `Put an agent on ${listed.title ?? listed.name}`,
1698 hint: `${listed.namespace}/${listed.name}`,
1699 to: `/${listed.namespace}/${listed.name}/issues/new?agent=1`,
1700 icon: <Sparkles size={15} />,
1701 });
1702 }
Usage while free is shown at cost; agents get rustfmt and clippy1703 return commands;
1704}
1705
1706/**
Merge branch 'worktree-agent-aca4790ea223aa235'1707 * The page while the next one loads: after a moment it dims, under the
1708 * bar below, so it is plainly on its way out rather than frozen, and the
1709 * next page fades up from there. Sending a form does not dim it: the
1710 * form's button says it is working. Spread on the element holding the page.
1711 */
1712export function useLeaving() {
1713 const navigation = useNavigation();
1714 const method = navigation.formMethod?.toUpperCase();
1715 const leaving = navigation.state === "loading" && (method == null || method === "GET");
1716 return {
1717 "aria-busy": leaving || undefined,
1718 className: `transition-opacity motion-reduce:transition-none ${leaving ? "opacity-60 delay-200 duration-300" : "duration-150"}`,
1719 };
1720}
1721
1722/**
Usage while free is shown at cost; agents get rustfmt and clippy1723 * A bar across the top of the page while the next one loads, as GitHub
1724 * has: it appears at once, creeps towards the end while waiting, then fills
1725 * and fades when the page arrives.
1726 */
1727export function Progress() {
1728 const navigation = useNavigation();
1729 const busy = navigation.state !== "idle";
1730 const [width, setWidth] = useState(0);
1731 const [visible, setVisible] = useState(false);
1732 useEffect(() => {
1733 if (busy) {
1734 setVisible(true);
1735 setWidth(12);
1736 // Slows as it goes, never quite arriving until the page does.
1737 const timer = setInterval(() => setWidth((now) => now + (90 - now) * 0.12), 200);
1738 return () => clearInterval(timer);
1739 }
1740 setWidth((now) => (now > 0 ? 100 : 0));
1741 const fade = setTimeout(() => setVisible(false), 250);
1742 const reset = setTimeout(() => setWidth(0), 550);
1743 return () => {
1744 clearTimeout(fade);
1745 clearTimeout(reset);
1746 };
1747 }, [busy]);
1748 return (
1749 <div
1750 aria-hidden="true"
1751 className={`pointer-events-none fixed inset-x-0 top-0 z-[60] h-[3px] transition-opacity duration-300 ${
1752 visible ? "opacity-100" : "opacity-0"
1753 }`}
1754 >
1755 <div
1756 className="h-full bg-accent shadow-[0_0_10px_var(--color-accent)] transition-[width] duration-200 ease-out"
1757 style={{ width: `${width}%` }}
1758 />
1759 </div>
1760 );
1761}
1762
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1763/**
1764 * The top bar's way to g1t: the direct message with the workspace's
1765 * orchestrator, opened or made. The one tinted control in the bar: the
1766 * lavender pixel 1 bare beside its words, on a wash of the accent.
1767 */
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1768function AskG1tButton({ slug }: { slug: string }) {
1769 return (
1770 <Hint label="Ask g1t">
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1771 <Button asChild variant="soft" size="bar" className="gap-2 lg:px-3">
1772 <Link to={`/${slug}/-/chat?agent=g1t`} aria-label="Ask g1t">
1773 <MarkGlyph className="h-3.5" />
1774 <span className="max-lg:hidden">Ask g1t</span>
1775 </Link>
1776 </Button>
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1777 </Hint>
1778 );
1779}
1780
Usage while free is shown at cost; agents get rustfmt and clippy1781/**
The front page is Home: where you're needed comes first, however long ago it started, with what's at stake and how long it has waited; then what happened since you were last here, in words, with the agent work that settled, what landed, what deployed, what was decided and what was spent, switchable to the last 24 hours or 7 days; then what's running now. Your last visit is kept with your account, so it's the same on every device; Today's old address leads here. The home guide says how.1782 * Which sidebar sits beside the page: each mode's own, or none. Home and
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.1783 * Apps are pages at full width, and so are g1t's public pages, such as a
1784 * profile, which are no workspace's. Without a workspace, only your own
1785 * settings and Notifications have one.
Chat and workspace agents: channels, DMs and named agents you talk to1786 */
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.1787function sidebarFor(mode: ModeKey, workspace: boolean): Panel | null {
1788 if (!workspace) return mode === "account" || mode === "notifications" ? mode : null;
The front page is Home: where you're needed comes first, however long ago it started, with what's at stake and how long it has waited; then what happened since you were last here, in words, with the agent work that settled, what landed, what deployed, what was decided and what was spent, switchable to the last 24 hours or 7 days; then what's running now. Your last visit is kept with your account, so it's the same on every device; Today's old address leads here. The home guide says how.1789 if (mode === "home" || mode === "apps" || mode === "site") return null;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1790 return mode;
Chat and workspace agents: channels, DMs and named agents you talk to1791}
1792
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.1793/** The sidebars that sit beside the page, one per mode that has one. */
1794type Panel = "chat" | "artifacts" | "agents" | "code" | "notifications" | "people" | "workspace" | "account";
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1795
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.1796/** Each sidebar's name, for the button that opens it on a phone. */
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 bar1797const MODE_MENU: Record<Panel, string> = {
1798 chat: "Chat",
Artifacts is a mode in the rail, the shell and the phone's tab bar in place of Docs: its home lists everything you can open by day or as cards under All, Yours and Shared with you, with search, filters and tiles to start a doc (slides, designs and dashboards say they are coming soon), and its sidebar holds favorites, spaces, Private, Shared, projects' docs and the trash.1799 artifacts: "Artifacts",
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 bar1800 agents: "Agents",
1801 code: "Code",
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.1802 notifications: "Notifications",
1803 people: "People",
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 bar1804 workspace: "Workspace",
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.1805 account: "Your account",
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 bar1806};
1807
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.1808/** Whether a key press happened in something you type into, where Ctrl B is the editor's. */
1809function typing(target: EventTarget | null): boolean {
1810 if (!(target instanceof HTMLElement)) return false;
1811 return target.isContentEditable || target.closest("input, textarea, select, [contenteditable=''], [contenteditable='true'], [role='textbox']") != null;
1812}
1813
1814/** Ctrl B (⌘B on a Mac) shows or hides the sidebar, except while typing. */
1815function useSidebarShortcut(toggle: () => void) {
1816 useEffect(() => {
1817 const onKey = (event: KeyboardEvent) => {
1818 if (event.key.toLowerCase() !== "b" || event.altKey || event.shiftKey || !(event.ctrlKey || event.metaKey)) return;
1819 if (event.defaultPrevented || typing(event.target)) return;
1820 event.preventDefault();
1821 toggle();
1822 };
1823 window.addEventListener("keydown", onKey);
1824 return () => window.removeEventListener("keydown", onKey);
1825 }, [toggle]);
1826}
1827
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1828/**
1829 * Search or jump to: the command palette. On a computer it looks like the
1830 * field it opens, with its shortcut; on a phone, a magnifier.
1831 */
1832function SearchButton({ onClick }: { onClick: () => void }) {
1833 return (
1834 <>
1835 <Button variant="ghost" size="icon-bar" aria-label="Search or jump to" onClick={onClick} className="md:hidden">
1836 <Search size={18} />
1837 </Button>
1838 <Button
1839 variant="outline"
1840 size="sm"
1841 aria-label="Search or jump to"
1842 onClick={onClick}
1843 className="mr-1 w-[min(18rem,26vw)] justify-start bg-surface font-normal text-faint hover:bg-surface hover:text-muted max-md:hidden"
1844 >
1845 <Search size={15} />
1846 <span className="grow truncate text-left">Search or jump to</span>
1847 <PaletteKey className="rounded border border-line bg-bg px-1.5 font-mono text-[0.625rem] leading-4 text-muted" />
1848 </Button>
1849 </>
1850 );
1851}
1852
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.1853/** The button that shows or hides the sidebar. */
1854function SidebarToggle({ onClick, open, className = "" }: { onClick: () => void; open: boolean; className?: string }) {
1855 const key = sidebarKeyLabel(typeof navigator === "undefined" ? null : navigator.platform);
1856 return (
1857 <Hint label={`Toggle sidebar (${key})`}>
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1858 <Button variant="ghost" size="icon-sm" aria-label={open ? "Hide the sidebar" : "Show the sidebar"} aria-expanded={open} onClick={onClick} className={className}>
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.1859 <PanelLeft size={17} />
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1860 </Button>
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.1861 </Hint>
1862 );
1863}
1864
Chat and workspace agents: channels, DMs and named agents you talk to1865/**
The docs folder is gone, and what it held lives where people read it: how a self-hosted g1t runs and how to deploy g1t to Cloudflare are pages on docs.g1t.sh under Run g1t yourself, and speed, rate limits and operating g1t.sh are sections of CONTRIBUTING.md; code that cited a file in docs/ now points to the page or section that covers it, or says what it means itself, and applied migrations and the runner images are left as they were.1866 * The app: three surfaces that never blur
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.1867 * together. The dock, a floating bar of apps down the left; the mode's
1868 * sidebar, flat on the background beside it, which folds away with Ctrl B
1869 * and is a drawer below 1024px; and the page, a rounded panel inset from
1870 * the window, with its header across the top: the sidebar's toggle, where
1871 * you are, search, Ask g1t and Create new. On a phone the dock is a bar
1872 * along the bottom. Only for someone signed in; without a workspace yet,
1873 * there is no dock.
Usage while free is shown at cost; agents get rustfmt and clippy1874 */
1875export function AppShell({
1876 user,
1877 shell,
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1878 missing = false,
Usage while free is shown at cost; agents get rustfmt and clippy1879 banner,
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.1880 sidebarClosed = false,
Usage while free is shown at cost; agents get rustfmt and clippy1881 children,
1882}: {
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.1883 user: User;
Usage while free is shown at cost; agents get rustfmt and clippy1884 shell: ShellData;
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.1885 /** The page is a 404 (see CodeSidebar). */
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1886 missing?: boolean;
Usage while free is shown at cost; agents get rustfmt and clippy1887 banner?: ReactNode;
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.1888 /** Whether the person folded the sidebar away, as their cookie says. */
1889 sidebarClosed?: boolean;
Usage while free is shown at cost; agents get rustfmt and clippy1890 children: ReactNode;
1891}) {
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.1892 const { pathname } = useLocation();
Usage while free is shown at cost; agents get rustfmt and clippy1893 const [drawer, setDrawer] = useState(false);
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.1894 const [closed, setClosed] = useState(sidebarClosed);
Usage while free is shown at cost; agents get rustfmt and clippy1895 const [palette, setPalette] = useState(false);
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.1896 const commands = useMemo(() => commandsFor(user, shell), [user, shell]);
Usage while free is shown at cost; agents get rustfmt and clippy1897
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.1898 // A new page closes the drawer.
Usage while free is shown at cost; agents get rustfmt and clippy1899 useEffect(() => setDrawer(false), [pathname]);
Search across all of g1t, Explore, and a command palette1900 usePaletteShortcut(() => setPalette((open) => !open));
Merge branch 'worktree-agent-aca4790ea223aa235'1901 const leaving = useLeaving();
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1902 useVisualViewport();
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1903 // Whether the page has scrolled under the top bar, which then draws its line (see data-page-head).
1904 const [scrolled, setScrolled] = useState(false);
1905 useEffect(() => {
1906 const onScroll = () => setScrolled(window.scrollY > 2);
1907 onScroll();
1908 window.addEventListener("scroll", onScroll, { passive: true });
1909 return () => window.removeEventListener("scroll", onScroll);
1910 }, []);
Usage while free is shown at cost; agents get rustfmt and clippy1911
Chat and workspace agents: channels, DMs and named agents you talk to1912 const going = useNavigation().location?.pathname;
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.1913 const ws = shell.workspace;
1914 const mode = modeOf(going ?? pathname, ws?.slug ?? null);
1915 const panel = sidebarFor(mode, ws != null);
1916 const code = ws ? hasCodeAccess(ws) : false;
Chat and workspace agents: channels, DMs and named agents you talk to1917 const { sidebar: chatSidebar } = useChatSidebar();
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1918 // Notify: the feed socket's live counts (lib/notify-client.ts) once it has them; the page's until then.
1919 const live = useLiveBadges(ws?.slug);
1920 const chatUnread = chatSidebar
1921 ? unreadTotals(chatSidebar.entries)
1922 : live?.chat != null
1923 ? { unread: live.chat, mentions: live.mentions ?? 0 }
1924 : (shell.chat ?? { unread: 0, mentions: 0 });
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.1925 const notificationsUnread = live?.inbox ?? shell.inbox?.unread ?? 0;
1926 const unread = { notifications: notificationsUnread, chat: chatUnread.unread, mentions: chatUnread.mentions };
1927
1928 // Folding the sidebar away on a computer is remembered, so the next page is drawn the same from the server.
1929 const toggleSidebar = useCallback(() => {
1930 if (!window.matchMedia("(min-width: 1024px)").matches) {
1931 setDrawer((open) => !open);
1932 return;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1933 }
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.1934 setClosed((was) => {
1935 document.cookie = sidebarCookie(!was, window.location.protocol === "https:");
1936 return !was;
1937 });
1938 }, []);
1939 useSidebarShortcut(useCallback(() => {
1940 if (panel) toggleSidebar();
1941 }, [panel, toggleSidebar]));
1942
1943 const inline = panel != null && !closed;
1944 const sidebarNode = () => {
1945 if (!panel) return null;
1946 if (!ws) return panel === "notifications" ? <NotificationsSidebar counts={shell.inbox ?? null} /> : <AccountSidebar username={user.username} />;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1947 switch (panel) {
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.1948 case "code":
1949 return <CodeSidebar user={user} shell={shell} missing={missing} />;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1950 case "chat":
1951 return <ChatSidebar slug={ws.slug} />;
Artifacts is a mode in the rail, the shell and the phone's tab bar in place of Docs: its home lists everything you can open by day or as cards under All, Yours and Shared with you, with search, filters and tiles to start a doc (slides, designs and dashboards say they are coming soon), and its sidebar holds favorites, spaces, Private, Shared, projects' docs and the trash.1952 case "artifacts":
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.1953 return <FoliosSidebar slug={ws.slug} />;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1954 case "agents":
1955 return <AgentsSidebar slug={ws.slug} shellAgents={shell.agents ?? null} code={code} owner={ws.role === "owner"} />;
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.1956 case "notifications":
1957 return <NotificationsSidebar counts={shell.inbox ?? null} />;
1958 case "people":
1959 return <PeopleSidebar slug={ws.slug} />;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1960 case "workspace":
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.1961 return <WorkspaceSidebar slug={ws.slug} owner={ws.role === "owner"} />;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1962 case "account":
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.1963 return <AccountSidebar username={user.username} />;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1964 }
1965 };
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.1966 // The sidebar's top row: the workspace and its switcher, and the way to fold the sidebar or close the drawer.
1967 const sidebarTop = (inDrawer: boolean) => (
1968 <div className="flex h-14 shrink-0 items-center gap-1 pr-1 pl-1">
1969 {ws ? (
1970 <WorkspaceSwitcher user={user} workspace={ws} />
1971 ) : (
1972 <Link to="/" aria-label="g1t" className="mr-auto flex h-9 items-center rounded-md px-2">
1973 <Logo className="text-[1.125rem]" />
1974 </Link>
1975 )}
1976 {inDrawer ? (
1977 <button type="button" aria-label="Close menu" onClick={() => setDrawer(false)} className="flex size-8 shrink-0 items-center justify-center rounded-md text-faint hover:bg-raised hover:text-fg">
1978 <X size={16} />
1979 </button>
1980 ) : (
1981 <SidebarToggle open onClick={toggleSidebar} />
1982 )}
1983 </div>
1984 );
1985
1986 // On a phone (below 768px): the bottom bar, and a conversation full screen.
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1987 const conversation = isConversation(going ?? pathname);
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.1988 // Where the page panel starts: 8px past the dock (88px), or right after the sidebar (260px) when it is open.
1989 const left = ws ? (inline ? "md:left-24 lg:left-[21.75rem]" : "md:left-24") : inline ? "md:left-2 lg:left-[16.75rem]" : "md:left-2";
1990 const pad = ws ? (inline ? "md:pl-24 lg:pl-[21.75rem]" : "md:pl-24") : inline ? "md:pl-2 lg:pl-[16.75rem]" : "md:pl-2";
Chat and workspace agents: channels, DMs and named agents you talk to1991
Usage while free is shown at cost; agents get rustfmt and clippy1992 return (
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.1993 // The drawer is a sheet: a dialog that holds focus, closes on Escape or
1994 // a tap outside, and gives focus back to the button that opened it.
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1995 <Sheet open={drawer} onOpenChange={setDrawer}>
Usage while free is shown at cost; agents get rustfmt and clippy1996 <Progress />
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.1997 {ws && (
1998 <div className="fixed top-2 bottom-2 left-2 z-40 hidden w-20 md:block">
1999 <Dock
2000 workspace={ws}
2001 pins={shell.pins ?? []}
2002 unread={unread}
2003 account={<AccountMenu user={user} />}
2004 />
2005 </div>
2006 )}
2007 {panel && (
2008 <aside
2009 aria-label={`${MODE_MENU[panel]} sidebar`}
2010 className={`fixed inset-y-0 z-40 hidden w-[16.25rem] flex-col pr-0.5 pl-1.5 ${ws ? "left-[5.5rem]" : "left-0"} ${inline ? "lg:flex" : ""}`}
2011 >
2012 {sidebarTop(false)}
2013 <div className="min-h-0 grow">{sidebarNode()}</div>
2014 </aside>
2015 )}
Chat and workspace agents: channels, DMs and named agents you talk to2016 <SheetContent
2017 side="left"
2018 showClose={false}
2019 aria-describedby={undefined}
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.2020 // Focus would land on the workspace's switcher and open its menu's hint; the sheet itself takes it instead.
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)2021 onOpenAutoFocus={(event) => {
2022 event.preventDefault();
2023 (event.currentTarget as HTMLElement | null)?.focus();
2024 }}
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.2025 className="flex w-[min(18.5rem,86vw)] flex-col border-line bg-shell px-1.5 pb-[env(safe-area-inset-bottom)] max-md:[&_nav_a]:min-h-10"
Chat and workspace agents: channels, DMs and named agents you talk to2026 >
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.2027 <SheetTitle className="sr-only">{panel ? `${MODE_MENU[panel]} menu` : "Menu"}</SheetTitle>
2028 {sidebarTop(true)}
2029 <div className="min-h-0 grow">{sidebarNode()}</div>
Usage, Billing settings and prepaid AI credit; fixes from the UX audit2030 </SheetContent>
Usage while free is shown at cost; agents get rustfmt and clippy2031
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.2032 <div className={`min-h-dvh px-1.5 pt-(--frame-top) pb-(--tabbar-h) md:pr-2 ${pad}`}>
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.2033 {/* A page whose own header sits right under this bar (data-page-head: a conversation's, a project's) reads as one
2034 block with it: no line between them until the page scrolls under the bar. A sticky one (data-page-head="sticky",
2035 an open artifact's) stays under the bar, so the line is always its. */}
2036 <div className="flex min-h-[calc(100dvh-var(--frame-top)-var(--tabbar-h))] min-w-0 flex-col rounded-[14px] bg-bg [&:has([data-page-head])>header:not([data-scrolled])]:border-b-transparent [&:has([data-page-head=sticky])>header]:border-b-transparent">
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.2037 <header
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.2038 data-scrolled={scrolled || undefined}
2039 className={`sticky top-(--frame-top) z-30 flex h-14 items-center gap-1 rounded-t-[14px] border-b border-line bg-bg pr-2 pl-2 transition-[border-color] duration-150 sm:pr-3 ${inline ? "lg:pl-3.5" : ""} ${conversation ? "max-md:hidden" : ""}`}
Usage while free is shown at cost; agents get rustfmt and clippy2040 >
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.2041 {panel && (
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.2042 <SidebarToggle open={drawer} onClick={toggleSidebar} className={`max-md:size-11 ${inline ? "lg:hidden" : ""}`} />
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.2043 )}
2044 {ws && (
2045 <span className={`flex min-w-0 shrink items-center gap-1.5 ${inline ? "lg:hidden" : ""}`}>
2046 <WorkspaceSwitcher user={user} workspace={ws} compact />
2047 <span aria-hidden="true" className="text-line-strong">
2048 /
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)2049 </span>
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.2050 </span>
Inbox: a bell in the top bar opens it beside the page, and /inbox holds it all2051 )}
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.2052 <Breadcrumbs pathname={pathname} missing={missing} repo={shell.repo} workspace={ws?.slug ?? null} />
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.2053 {/* Search, then what's yours (spend, Ask g1t), then the bell and Create new: one height, one rhythm. */}
2054 <div className="ml-auto flex shrink-0 items-center gap-1 md:gap-1.5">
2055 <SearchButton onClick={() => setPalette(true)} />
The Spend page says what a workspace spent, where it went and the budgets that hold it, in Workspace under Money: spent at price, agents' spend and the spend limit; by day; by agent, person, channel, model, kind of work and product; budgets from the workspace down to each person, agent and task, with what happens at 100%; the costliest tasks, each with a receipt of every session at the provider's price and what was charged; and how it's priced. Everyone sees what agents spent for them, and owners and billing managers the whole workspace; each person can have a monthly budget agents keep to, and the spend pill in the top bar shows your month or the workspace's against its limit. The spend guide says how.2056 {/* Your spend this month, or the workspace's for owners and billing managers; on a phone it is on Spend. */}
2057 {ws && (
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.2058 <span className="flex max-md:hidden">
The Spend page says what a workspace spent, where it went and the budgets that hold it, in Workspace under Money: spent at price, agents' spend and the spend limit; by day; by agent, person, channel, model, kind of work and product; budgets from the workspace down to each person, agent and task, with what happens at 100%; the costliest tasks, each with a receipt of every session at the provider's price and what was charged; and how it's priced. Everyone sees what agents spent for them, and owners and billing managers the whole workspace; each person can have a monthly budget agents keep to, and the spend pill in the top bar shows your month or the workspace's against its limit. The spend guide says how.2059 <SpendPill slug={ws.slug} mayWorkspace={ws.role === "owner" || !!ws.org_roles?.includes("billing_manager")} />
2060 </span>
2061 )}
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.2062 {ws && <AskG1tButton slug={ws.slug} />}
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.2063 <Separator orientation="vertical" className="mx-1 data-[orientation=vertical]:h-5 max-md:hidden" />
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.2064 {/* On a phone, Notifications is in the bottom bar. */}
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.2065 <span className="flex max-md:hidden">
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.2066 <NotificationsBell counts={shell.inbox ? { ...shell.inbox, unread: notificationsUnread } : null} />
2067 </span>
2068 <CreateMenu shell={shell} />
2069 {/* Without a workspace there is no dock: the account is here. */}
2070 {!ws && <AccountMenu user={user} side="bottom" />}
2071 </div>
2072 </header>
2073 {banner}
2074 <main id="content" tabIndex={-1} {...leaving} className={`min-w-0 grow outline-none ${leaving.className}`}>
2075 <InMain.Provider value={true}>{children}</InMain.Provider>
2076 </main>
2077 </div>
Usage while free is shown at cost; agents get rustfmt and clippy2078 </div>
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.2079 {/* The panel's edge: a rounded frame over the page, with the background beyond it, so what scrolls stays inside.
2080 Every page has it, a conversation too; only a phone's conversation, full screen over everything, goes without. */}
2081 <div
2082 aria-hidden="true"
2083 className={`pointer-events-none fixed top-(--frame-top) right-1.5 bottom-(--tabbar-h) left-1.5 z-[35] rounded-[14px] shadow-[0_0_0_1px_var(--color-line),0_0_0_100vmax_var(--color-shell)] md:right-2 ${left} ${conversation ? "max-md:hidden" : ""}`}
2084 />
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.2085 {ws && <BottomBar user={user} workspace={ws} pins={shell.pins ?? []} unread={unread} onReselect={panel ? () => setDrawer(true) : undefined} />}
2086 <CommandPalette open={palette} onOpenChange={setPalette} commands={commands} repo={shell.repo ? `${shell.repo.namespace}/${shell.repo.name}` : null} />
Usage, Billing settings and prepaid AI credit; fixes from the UX audit2087 </Sheet>
Usage while free is shown at cost; agents get rustfmt and clippy2088 );
2089}
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.2090
2091/** Create new: a project, an issue in the one you are in, a workspace or a team. */
2092function CreateMenu({ shell }: { shell: ShellData }) {
2093 return (
2094 <DropdownMenu>
2095 <Hint label="Create new">
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.2096 <DropdownMenuTrigger asChild>
2097 <Button variant="ghost" size="bar" aria-label="Create new" className="gap-0.5 px-1.5 text-fg/90">
2098 <Plus size={17} className="max-md:size-5" />
2099 <ChevronDown size={12} className="text-faint max-md:hidden" />
2100 </Button>
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.2101 </DropdownMenuTrigger>
2102 </Hint>
2103 <DropdownMenuContent align="end" className="min-w-52">
2104 {shell.repo && (
2105 <>
2106 <DropdownMenuLabel className="truncate">In {shell.repo.name}</DropdownMenuLabel>
2107 <DropdownMenuItem asChild>
2108 <Link to={`/${shell.repo.namespace}/${shell.repo.name}/issues/new`}>
2109 <CircleDot />
2110 New issue
2111 </Link>
2112 </DropdownMenuItem>
2113 {shell.repo.member && (
2114 <DropdownMenuItem asChild>
2115 <Link to={`/${shell.repo.namespace}/${shell.repo.name}/plans`}>
2116 <ListTree />
2117 Plan work
2118 </Link>
2119 </DropdownMenuItem>
2120 )}
2121 <DropdownMenuSeparator />
2122 </>
2123 )}
2124 <DropdownMenuItem asChild>
2125 <Link to="/?agent=new">
2126 <Sparkles />
2127 Put an agent on it
2128 </Link>
2129 </DropdownMenuItem>
2130 <DropdownMenuItem asChild>
2131 <Link to="/new">
2132 <Box />
2133 New project
2134 </Link>
2135 </DropdownMenuItem>
2136 <DropdownMenuItem asChild>
2137 <Link to="/new/github">
2138 <GitBranch />
2139 Import from GitHub
2140 </Link>
2141 </DropdownMenuItem>
2142 <DropdownMenuSeparator />
2143 <DropdownMenuItem asChild>
2144 <Link to="/workspaces/new">
2145 <Users />
2146 New workspace
2147 </Link>
2148 </DropdownMenuItem>
2149 {/* A team in the workspace you are in, for whoever it lets create one. */}
2150 {shell.workspace &&
2151 (mayCreateTeams(shell.workspace.team_creation, shell.workspace.role) ? (
2152 <DropdownMenuItem asChild>
2153 <Link to={`/${shell.workspace.slug}/-/teams/new`}>
2154 <UsersRound />
2155 New team
2156 </Link>
2157 </DropdownMenuItem>
2158 ) : (
2159 <DropdownMenuItem disabled>
2160 <UsersRound />
2161 New team
2162 <span className="ml-auto pl-3 text-xs text-faint">Owners only</span>
2163 </DropdownMenuItem>
2164 ))}
2165 </DropdownMenuContent>
2166 </DropdownMenu>
2167 );
2168}

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