Skip to content
2,169 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";
New workspaces are told to connect a model, before anything fails4
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";
New workspaces are told to connect a model, before anything fails6
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";
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.16import { SoonPill } from "./ui";
17import { Avatar } from "./ui/avatar";
Fast pages, required checks on the branch, self-hosted runners, honest incidents18import { 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.19import { Button } from "./ui/button";
20import { Separator } from "./ui/separator";
21import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from "./ui/breadcrumb";
New workspaces are told to connect a model, before anything fails22import {
23 DropdownMenu,
24 DropdownMenuContent,
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas25 DropdownMenuGroup,
New workspaces are told to connect a model, before anything fails26 DropdownMenuItem,
27 DropdownMenuLabel,
28 DropdownMenuSeparator,
29 DropdownMenuTrigger,
30} from "./ui/dropdown-menu";
Merge branch 'worktree-agent-ad7c6d88d93adc817'31import { 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.32import { type ModeKey, SETTINGS_PAGES, homePagePath, modeOf } from "../lib/workspace-nav";
Chat and workspace agents: channels, DMs and named agents you talk to33import { AgentsSidebar } from "./agents-mode";
34import { 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.35import { 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.36import { Dock, ShortcutsDialog, WorkspaceSwitcher, sidebarKeyLabel } from "./dock";
37import { BottomBar, isConversation, useVisualViewport } from "./mobile";
Chat and workspace agents: channels, DMs and named agents you talk to38import { useChatSidebar } from "./chat/actions";
39import { unreadTotals } from "../lib/chat";
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look40import { 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.41import { projectPages } from "../lib/chrome";
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas42import { 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.43import { type PinnableApp, sidebarCookie } from "../lib/apps";
44import { 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 quotas45import { 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.46import { useInviteOnly } from "../lib/registration";
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas47import { STATUS_URL, statusTitle } from "../lib/status";
Navigation: the workspace's own page with tabs, pins and recent in the sidebar48import { 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 quotas49import 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)50import { 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 managers51import { 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.52import { THEME_COMMANDS, ThemeMenuSwitch } from "./theme-switch";
New workspaces are told to connect a model, before anything fails53
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put54/**
55 * What the sidebar needs, worked out by the root loader. For a visitor who
56 * is not signed in there is no workspace, no projects and no usage: only
57 * the project being looked at, if they can see it.
58 */
New workspaces are told to connect a model, before anything fails59export type ShellData = {
60 /** The workspace the sidebar is about: the one being looked at, or their first. */
Workspace names and icons, and a component kit for every control61 workspace: Membership | null;
Navigation: the workspace's own page with tabs, pins and recent in the sidebar62 /** All its projects, by name, for the palette: `name` is the slug in their address. */
63 repos: ShortcutProject[];
64 /** The person's pinned projects in it, in their order (lib/pins.ts). */
65 pinned?: ShortcutProject[];
66 /** What they opened there last, latest first, leaving out the pinned. */
67 recent?: ShortcutProject[];
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look68 /** Repositories shared with them in workspaces they do not belong to. */
69 shared?: { namespace: string; name: string; isPrivate: boolean }[];
Projects: what a workspace builds and runs, first on every page70 /** The project being looked at, if any, whoever owns it. */
New workspaces are told to connect a model, before anything fails71 repo: {
72 namespace: string;
73 name: string;
74 member: boolean;
75 issues: number;
76 pulls: number;
77 } | null;
Billing accounts, terms and enterprises; g1t is no longer free78 /** Where the workspace stands against its usage limit, if billing is on. */
79 limit: {
80 exposureMicros: number;
81 ceilingMicros: number | null;
82 state: "ok" | "warning" | "stopped";
83 comped: boolean;
84 } | null;
New workspaces are told to connect a model, before anything fails85 /** Whether g1t charges nothing for now, while it is being built out. */
86 free?: boolean;
87 /** What its agents have cost since the start of the month. */
88 /** This month's usage: charged, or at cost while g1t is free. */
89 monthUsageMicros: number | null;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look90 /** Whether new compute is paused (a spend spike or a hold), and whether the viewer can answer it. */
91 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.92 /** 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 all93 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)94 /**
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.95 * 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)96 * starred and latest conversations. Null when chat did not answer in time.
97 */
98 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.99 /** 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)100 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.101 /** The apps this person pinned to their dock in the workspace (lib/apps.ts). */
102 pins?: PinnableApp[];
New workspaces are told to connect a model, before anything fails103};
104
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)105/** An agent as the shell lists it. */
106export type ShellAgent = Pick<
107 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.108 "id" | "handle" | "display_name" | "avatar" | "avatar_seed" | "role" | "status" | "title" | "builtin"
109> & {
110 scope?: WorkspaceAgent["scope"];
111 /** The visible teams it is on (team memberships); absent when they couldn't be read. */
112 teams?: { slug: string; name: string }[];
113};
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)114
New workspaces are told to connect a model, before anything fails115function SidebarLink({
116 to,
117 icon,
118 end,
119 count,
120 also,
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look121 drill,
Merge branch 'worktree-agent-ad7c6d88d93adc817'122 current: lit,
New workspaces are told to connect a model, before anything fails123 children,
124}: {
125 to: string;
126 icon: ReactNode;
127 end?: boolean;
128 count?: number;
Projects: what a workspace builds and runs, first on every page129 /** Other path prefixes under which this link is the current one. */
130 also?: string | string[];
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look131 /** It opens a list of its own: a chevron says so, always or on hover. */
132 drill?: boolean | "hover";
Merge branch 'worktree-agent-ad7c6d88d93adc817'133 /** Whether it is the current row, when the list works that out itself. */
134 current?: boolean;
New workspaces are told to connect a model, before anything fails135 children: ReactNode;
136}) {
137 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.138 const navigation = useNavigation();
139 // NavLink's own pending state compares paths only, so a list whose rows
140 // differ by query (Notifications' views and reasons) would light every
141 // row while one loads. Where the list says which row is current, a row
142 // is pending only when the page on its way is that row's, query and all.
143 const loading = navigation.location;
144 const pendingHere = loading != null && `${loading.pathname}${loading.search}` === to;
New workspaces are told to connect a model, before anything fails145 return (
146 <NavLink
147 to={to}
148 end={end}
149 prefetch="intent"
150 className={({ isActive, isPending }) => {
Projects: what a workspace builds and runs, first on every page151 const current =
Merge branch 'worktree-agent-ad7c6d88d93adc817'152 lit ??
153 (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.154 const pending = lit === undefined ? isPending : pendingHere;
New workspaces are told to connect a model, before anything fails155 return `group flex h-8 items-center gap-2.5 rounded-md px-2 text-[0.8125rem] transition-colors ${
156 current
157 ? "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.158 : pending
New workspaces are told to connect a model, before anything fails159 ? "bg-raised/60 text-fg"
160 : "text-muted hover:bg-raised/60 hover:text-fg"
161 }`;
162 }}
163 >
164 <span className="shrink-0 text-faint group-hover:text-muted">{icon}</span>
165 <span className="min-w-0 grow truncate">{children}</span>
166 {count != null && count > 0 && (
167 <span className="rounded bg-line px-1.5 text-[0.6875rem] tabular-nums text-muted">
168 {count}
169 </span>
170 )}
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look171 {drill && (
172 <ChevronRight
173 size={14}
174 aria-hidden="true"
175 className={`-mr-0.5 shrink-0 text-faint transition-opacity ${drill === "hover" ? "opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100" : ""}`}
176 />
177 )}
New workspaces are told to connect a model, before anything fails178 </NavLink>
179 );
180}
181
Pull requests say where they are live; the project menu shows what is coming182/**
183 * Something a project will have, shown where it will live so people can
184 * see where g1t is going. Not a link: nothing is behind it yet.
185 */
186function SidebarSoon({ icon, children, about }: { icon: ReactNode; children: ReactNode; about: string }) {
187 return (
Merge branch 'worktree-agent-ae1299e92e4462012'188 <Hint label={about} side="right">
189 <div aria-disabled="true" className="flex h-8 cursor-default items-center gap-2.5 rounded-md px-2 text-[0.8125rem] text-faint">
190 <span className="shrink-0 opacity-70">{icon}</span>
191 <span className="grow truncate">{children}</span>
192 <span className="sr-only">{about}</span>
193 <SoonPill />
194 </div>
195 </Hint>
Pull requests say where they are live; the project menu shows what is coming196 );
197}
198
The project menu opens by section, and the workspace has its own panel199/**
A flat project menu with Code first, views as tabs, and Stripe for every owner200 * A page that is coming, as a link to its roadmap page: faint, with Soon,
201 * and marked current on any of its section's Soon pages.
The project menu opens by section, and the workspace has its own panel202 */
A flat project menu with Code first, views as tabs, and Stripe for every owner203function SidebarSoonLink({
The project menu opens by section, and the workspace has its own panel204 to,
205 also,
A flat project menu with Code first, views as tabs, and Stripe for every owner206 icon,
207 about,
Merge branch 'worktree-agent-ad7c6d88d93adc817'208 current: lit,
The project menu opens by section, and the workspace has its own panel209 children,
210}: {
211 to: string;
A flat project menu with Code first, views as tabs, and Stripe for every owner212 also?: string[];
213 icon: ReactNode;
214 about: string;
Merge branch 'worktree-agent-ad7c6d88d93adc817'215 /** Whether it is the current row, when the list works that out itself. */
216 current?: boolean;
The project menu opens by section, and the workspace has its own panel217 children: ReactNode;
218}) {
219 const { pathname } = useLocation();
220 return (
Sidebar: soon rows and the project row keep their styles inside a hint; tiny amounts read as zero221 // The hint wraps a plain box: Radix's asChild merges className as a
222 // string, which would break NavLink's className function.
Merge branch 'worktree-agent-ae1299e92e4462012'223 <Hint label={about} side="right">
Sidebar: soon rows and the project row keep their styles inside a hint; tiny amounts read as zero224 <div>
The project menu opens by section, and the workspace has its own panel225 <NavLink
226 to={to}
227 prefetch="intent"
A flat project menu with Code first, views as tabs, and Stripe for every owner228 className={({ isActive }) => {
Merge branch 'worktree-agent-ad7c6d88d93adc817'229 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 owner230 return `group flex h-8 items-center gap-2.5 rounded-md px-2 text-[0.8125rem] transition-colors ${
231 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 panel232 }`;
233 }}
234 >
A flat project menu with Code first, views as tabs, and Stripe for every owner235 <span className="shrink-0 opacity-80">{icon}</span>
The project menu opens by section, and the workspace has its own panel236 <span className="min-w-0 grow truncate">{children}</span>
Usage, Billing settings and prepaid AI credit; fixes from the UX audit237 <SoonPill />
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales238 </NavLink>
Sidebar: soon rows and the project row keep their styles inside a hint; tiny amounts read as zero239 </div>
Merge branch 'worktree-agent-ae1299e92e4462012'240 </Hint>
The project menu opens by section, and the workspace has its own panel241 );
242}
243
A flat project menu with Code first, views as tabs, and Stripe for every owner244/** Icons for what spans projects. */
245const WORKSPACE_ICONS: Record<string, ReactNode> = {
246 board: <KanbanSquare size={15} />,
247 roadmap: <GanttChart size={15} />,
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member248 teams: <UsersRound size={15} />,
A flat project menu with Code first, views as tabs, and Stripe for every owner249 packages: <Package size={15} />,
250 fleet: <Bot size={15} />,
251};
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales252
A flat project menu with Code first, views as tabs, and Stripe for every owner253/** The Soon pages of a section, as paths, so its link is current on them. */
254function soonPaths(base: string, section: RoadmapItem["section"]): string[] {
255 return roadmapIn(section).map((item) => `${base}/soon/${item.key}`);
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales256}
257
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look258function SidebarGroup({
259 title,
260 action,
261 className = "",
262 children,
263}: {
264 title: string;
265 action?: ReactNode;
266 className?: string;
267 children: ReactNode;
268}) {
New workspaces are told to connect a model, before anything fails269 return (
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look270 <section className={className}>
New workspaces are told to connect a model, before anything fails271 <div className="mb-1 flex h-6 items-center justify-between px-2">
272 <h2 className="text-xs font-medium text-faint">{title}</h2>
273 {action}
274 </div>
275 <div className="space-y-px">{children}</div>
276 </section>
277 );
278}
279
Workspace names and icons, and a component kit for every control280/** What a workspace is called where people read it: its display name, else its slug. */
281function displayName(membership: Membership): string {
282 return membership.name?.trim() || membership.slug;
New workspaces are told to connect a model, before anything fails283}
284
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas285/**
286 * The fine print, as one quiet row at the foot of the account menu and the
287 * visitor's panel: each link a full-height target, left-aligned. In the
288 * menu each is a menu item, so the arrow keys reach it.
289 */
290const LEGAL_LINKS: [string, string][] = [
291 ["Policies", "/policies"],
292 ["Privacy", "/policies/privacy"],
293 ["Security", "/security"],
294];
295const LEGAL_LINK = "flex h-7 items-center rounded px-1.5 text-xs text-faint outline-none transition-colors";
296
297function MenuLegalRow() {
298 return (
299 <div role="group" aria-label="Legal" className="flex items-center gap-0.5 px-0.5 pt-0.5">
300 {LEGAL_LINKS.map(([label, to], index) => (
301 <span key={to} className="flex items-center gap-0.5">
302 {index > 0 && (
303 <span aria-hidden="true" className="text-[0.625rem] text-line-strong">
304 ·
305 </span>
306 )}
307 <DropdownMenuItem asChild className={`${LEGAL_LINK} py-0 data-highlighted:bg-line data-highlighted:text-fg`}>
308 <Link to={to}>{label}</Link>
309 </DropdownMenuItem>
310 </span>
311 ))}
312 </div>
313 );
314}
315
316/** Status's row: the live dot and two or three words, fetched when the menu opens. */
317function StatusSummary({ open }: { open: boolean }) {
318 const status = useSiteStatus(open);
319 const words = statusTitle(status);
320 return (
321 <span className="ml-auto flex min-w-0 items-center gap-1.5 pl-2 text-xs text-faint">
322 {/* The words say it; the dot's own words for screen readers would repeat them. */}
323 <span aria-hidden="true" className="flex">
324 <StatusDot state={status?.overall.state ?? null} />
325 </span>
Fast pages, required checks on the branch, self-hosted runners, honest incidents326 {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 quotas327 </span>
328 );
329}
330
331/** A menu row: an icon, words, and whatever sits at its end. */
332const MENU_ROW = "h-9 gap-2.5 px-2.5 text-[0.8125rem]";
333
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.334/**
335 * Your account, at the foot of the dock (or in the header, before you have
336 * a workspace): who you are and your status, your profile and settings,
337 * and help: the documentation, support, status and the keyboard's
338 * shortcuts; then signing out and the fine print.
339 */
340function AccountMenu({ user, side = "right" }: { user: User; side?: "right" | "bottom" }) {
New workspaces are told to connect a model, before anything fails341 const submit = useSubmit();
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas342 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.343 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 managers344 // Your status's dialog: outside the menu, so the menu closes behind it.
345 const [editing, setEditing] = useState(false);
Fast pages, required checks on the branch, self-hosted runners, honest incidents346 // Name, primary address and invites left: asked for once, as soon as the
347 // 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 quotas348 const details = useFetcher<AccountMenuData | null>({ key: "account-menu" });
Fast pages, required checks on the branch, self-hosted runners, honest incidents349 const prefetch = () => {
350 if (details.state === "idle" && details.data === undefined) details.load("/settings/menu.json");
351 };
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas352 useEffect(() => {
Fast pages, required checks on the branch, self-hosted runners, honest incidents353 if (open) prefetch();
354 // eslint-disable-next-line react-hooks/exhaustive-deps
355 }, [open]);
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas356 const me = details.data ?? null;
Fast pages, required checks on the branch, self-hosted runners, honest incidents357 // Still on its way: shapes where the words will be, the same size.
358 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)359 // While anyone can sign up, listed once the data says there are invites to look back on.
360 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 quotas361 const profile = `/u/${user.username}`;
New workspaces are told to connect a model, before anything fails362 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 managers363 <>
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas364 <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.365 {/* 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 quotas366 <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 managers367 aria-label={`Account menu for ${shownUsername(user)}`}
Fast pages, required checks on the branch, self-hosted runners, honest incidents368 onPointerEnter={prefetch}
369 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.370 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 quotas371 >
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.372 <Avatar name={user.username} image={user.avatar} size={side === "right" ? 32 : 28} />
373 <OwnPresenceDot ring={side === "right" ? "var(--color-dock)" : "var(--color-bg)"} className="absolute -right-0.5 -bottom-0.5" />
New workspaces are told to connect a model, before anything fails374 </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.375 <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 quotas376 {/* Who is signed in, and a way to their profile. */}
377 <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 managers378 <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 quotas379 <Avatar name={user.username} image={user.avatar} size={36} />
Fast pages, required checks on the branch, self-hosted runners, honest incidents380 <span className="flex min-w-0 grow flex-col leading-tight" aria-busy={loading}>
381 {loading ? (
382 <Skeleton className="my-[0.1875rem] h-3.5 w-28" />
383 ) : (
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers384 <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 incidents385 )}
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers386 <span className="truncate font-mono text-xs text-muted">@{shownUsername(user)}</span>
Fast pages, required checks on the branch, self-hosted runners, honest incidents387 {loading ? (
388 <Skeleton className="mt-1 h-3 w-40" />
389 ) : (
390 me?.email && <span className="mt-0.5 truncate text-xs text-faint">{me.email}</span>
391 )}
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas392 </span>
New workspaces are told to connect a model, before anything fails393 </Link>
394 </DropdownMenuItem>
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas395 <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 managers396 {/* Your status, away, and pausing notifications. */}
397 <DropdownMenuGroup>
398 <OwnPresenceItems className="min-h-9 py-1.5 text-[0.8125rem]" onEdit={() => setEditing(true)} />
399 </DropdownMenuGroup>
400 <DropdownMenuSeparator className="my-1.5" />
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas401 <DropdownMenuGroup>
402 <DropdownMenuItem asChild className={MENU_ROW}>
403 <Link to={profile}>
404 <CircleUserRound />
405 Your profile
406 </Link>
407 </DropdownMenuItem>
408 <DropdownMenuItem asChild className={MENU_ROW}>
409 <Link to={FIRST_SETTINGS_PAGE}>
410 <Settings />
411 Your settings
412 </Link>
413 </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)414 {invitesListed && (
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas415 <DropdownMenuItem asChild className={MENU_ROW}>
416 <Link to="/settings/invites">
417 <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)418 {ACCOUNT_SETTINGS.invites.title}
Fast pages, required checks on the branch, self-hosted runners, honest incidents419 {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 quotas420 {me?.invites_left != null && (
421 <span className="ml-auto rounded-full bg-line px-1.5 text-[0.6875rem] tabular-nums text-muted">
422 {me.invites_left} left
423 </span>
424 )}
425 </Link>
426 </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)427 )}
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas428 </DropdownMenuGroup>
429 <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.430 {/* Auto, Light or Dark, switched in place (lib/theme.ts). */}
431 <ThemeMenuSwitch />
432 <DropdownMenuSeparator className="my-1.5" />
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas433 <DropdownMenuGroup>
434 <DropdownMenuItem asChild className={MENU_ROW}>
435 <a href="https://docs.g1t.sh/">
436 <BookOpen />
437 Documentation
438 </a>
439 </DropdownMenuItem>
440 <DropdownMenuItem asChild className={MENU_ROW}>
441 <Link to="/support">
442 <LifeBuoy />
443 Support
444 </Link>
445 </DropdownMenuItem>
446 <DropdownMenuItem asChild className={MENU_ROW}>
447 <a href={STATUS_URL}>
448 <Activity />
449 Status
450 <StatusSummary open={open} />
451 </a>
452 </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.453 <DropdownMenuItem className={MENU_ROW} onSelect={() => setKeys(true)}>
454 <Keyboard />
455 Keyboard shortcuts
456 <PaletteKey className="ml-auto font-sans text-xs text-faint" />
457 </DropdownMenuItem>
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas458 </DropdownMenuGroup>
459 <DropdownMenuSeparator className="my-1.5" />
New workspaces are told to connect a model, before anything fails460 {/* Submitted from here: the menu closes on select, and a button
461 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 quotas462 <DropdownMenuItem className={MENU_ROW} onSelect={() => submit(null, { method: "post", action: "/logout" })}>
New workspaces are told to connect a model, before anything fails463 <LogOut />
464 Sign out
465 </DropdownMenuItem>
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas466 <DropdownMenuSeparator className="my-1.5" />
467 <MenuLegalRow />
New workspaces are told to connect a model, before anything fails468 </DropdownMenuContent>
469 </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 managers470 <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.471 <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 managers472 </>
New workspaces are told to connect a model, before anything fails473 );
474}
475
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look476/**
Mission control counts people's own changes as theirs; a shorter sidebar with setup under Settings, and a 56px top bar477 * 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.478 * 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 bar479 * webhooks), what it pays, its repositories, tokens and record. The main
480 * list keeps the places work happens and who belongs; every member can
481 * still open these.
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look482 */
Mission control counts people's own changes as theirs; a shorter sidebar with setup under Settings, and a 56px top bar483const SETTINGS_PAGE =
Merge branch 'worktree-agent-ad7c6d88d93adc817'484 new RegExp(`^/([^/]+)/-/(${SETTINGS_PAGES.join("|")})(/|$)`);
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look485/** A project's settings pages, which the project's menu drills into. */
Project settings move into the sidebar, grouped, with a heading per page486const REPO_SETTINGS_PAGE = /^\/([^/]+)\/([^/-][^/]*)\/settings(\/|$)/;
New workspaces are told to connect a model, before anything fails487
488/**
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look489 * The sidebar's lists are a stack, the way a phone pushes a screen: one
490 * drilled into slides in from the right over the full width, while the one
491 * it covers drifts a quarter of the way left and fades, both on one long
New workspaces are told to connect a model, before anything fails492 * ease-out, the fade quicker than the move so the two never blur together.
493 * Going back reverses it.
494 */
495const LAYER =
496 "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 look497/** One list, filling its layer. */
New workspaces are told to connect a model, before anything fails498const PANEL = "h-full overflow-y-auto px-2 pb-4";
499
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look500/** One list in the stack: what it is, and its rows. */
501type Level = { key: string; node: ReactNode };
502
503/** True once the page has hydrated, so what the server drew never animates in. */
504function useHydrated(): boolean {
505 const [hydrated, setHydrated] = useState(false);
506 useEffect(() => setHydrated(true), []);
507 return hydrated;
508}
509
510/**
511 * Drilling in and out of the sidebar's lists. `trail` is the way from the
512 * main list to the one shown, worked out from the address, so a link
513 * straight to a settings page opens the sidebar already drilled in, and
514 * leaving it comes back out. Lists deeper than the one shown stay in
515 * place, off to the right, so going back slides them away rather than
516 * dropping them. Moving to a list at the same depth (a workspace's settings
517 * to a project) fades the new one in where it is.
518 */
519function Drill({ trail }: { trail: Level[] }) {
520 const depth = trail.length - 1;
521 const hydrated = useHydrated();
522 const stack = useRef<Level[]>(trail);
523 const before = stack.current;
524 const within = trail.every((level, index) => before[index]?.key === level.key);
525 stack.current = within ? [...trail, ...before.slice(trail.length)] : trail;
526 const levels = stack.current;
527 // What was showing last time, to tell drilling in from moving across.
528 const shown = useRef({ depth, keys: levels.map((level) => level.key) });
529 useEffect(() => {
530 shown.current = { depth, keys: levels.map((level) => level.key) };
531 });
New workspaces are told to connect a model, before anything fails532 return (
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look533 <div className="relative min-h-0 grow overflow-hidden">
534 {levels.map((level, index) => {
535 const current = index === depth;
536 const place =
537 index < depth
538 ? "pointer-events-none -translate-x-1/4 opacity-0"
539 : current
540 ? "translate-x-0 opacity-100"
541 : "pointer-events-none translate-x-full opacity-0";
542 // A list that was not there before arrives: from the right when
543 // drilling in, in place when moving across.
544 const arriving = hydrated && current && !shown.current.keys.includes(level.key);
545 const enter = arriving
546 ? depth > shown.current.depth
547 ? "starting:translate-x-full starting:opacity-0"
548 : "starting:opacity-0"
549 : "";
550 return (
551 <div key={level.key} className={`${LAYER} ${place} ${enter}`} inert={!current} aria-hidden={!current || undefined}>
552 {level.node}
553 </div>
554 );
555 })}
556 </div>
557 );
558}
559
560/**
561 * The row at the top of a list drilled into: the list's name, which goes
562 * back out, and what it belongs to, faint at the end.
563 */
564function BackRow({ to, label, context }: { to: string; label: ReactNode; context?: ReactNode }) {
565 return (
566 <Link
567 to={to}
568 prefetch="intent"
569 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"
New workspaces are told to connect a model, before anything fails570 >
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look571 <ChevronLeft size={16} className="shrink-0 text-faint transition-transform group-hover:-translate-x-0.5 group-hover:text-muted" />
572 <span className="min-w-0 shrink-0 truncate">{label}</span>
573 {context && (
574 <span className="ml-auto min-w-0 truncate pl-2 font-mono text-[0.6875rem] font-normal text-faint">{context}</span>
575 )}
576 </Link>
577 );
578}
579
580/** A thin rule between groups of a list. */
581function Rule() {
582 return <div role="separator" className="mx-2 my-2.5 h-px bg-line" />;
583}
584
Navigation: the workspace's own page with tabs, pins and recent in the sidebar585/** A quiet heading inside a group: Pinned, Recent. */
586function SidebarSubhead({ children }: { children: ReactNode }) {
587 return <h3 className="px-2 pt-1.5 pb-0.5 text-[0.6875rem] font-medium tracking-wide text-faint">{children}</h3>;
588}
589
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look590/**
Navigation: the workspace's own page with tabs, pins and recent in the sidebar591 * The workspace's projects as the sidebar keeps them, however many there
592 * are: the person's pins in their order, what they opened last, and the
593 * way to all of them. Pins move by dragging, or with Alt and the arrow
594 * keys; the projects service keeps the order.
595 */
Merge branch 'worktree-agent-ad7c6d88d93adc817'596function SidebarProjects({ slug, shell, current }: { slug: string; shell: ShellData; current: boolean }) {
Navigation: the workspace's own page with tabs, pins and recent in the sidebar597 const reorder = useFetcher({ key: `pins:${slug}` });
598 const saved = shell.pinned ?? [];
599 // While a new order is on its way, it shows as made.
600 const asked = reorder.formData?.get("intent") === "reorder" ? reorder.formData.getAll("slug").map(String) : null;
601 const pinned = asked
602 ? asked.map((name) => saved.find((project) => project.name === name)).filter((project): project is ShortcutProject => project != null)
603 : saved;
604 const active = shell.repo ? { namespace: shell.repo.namespace, name: shell.repo.name, isPrivate: false } : null;
605 const recent = recentWith(shell.recent ?? [], pinned, active, slug);
606 const [dragging, setDragging] = useState<number | null>(null);
607 const move = (from: number, by: number) => {
608 const next = movedPin(pinned, from, by);
609 if (!next) return;
610 const form = new FormData();
611 form.set("intent", "reorder");
612 for (const project of next) form.append("slug", project.name);
613 reorder.submit(form, { method: "post", action: `/${slug}/-/pins` });
614 };
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar615 // Each row pins or unpins in place: the pin shows on hover or focus, and
616 // stays shown on a pinned row's hover so it reads as "unpin".
617 const row = (project: ShortcutProject, isPinned: boolean) => (
618 <div className="group/row relative">
619 <SidebarLink to={`/${project.namespace}/${project.name}`} icon={project.isPrivate ? <Lock size={15} /> : <Box size={15} />} drill="hover">
620 <span className="block truncate pr-6">{project.title ?? project.name}</span>
621 </SidebarLink>
622 <PinButton
623 workspace={slug}
624 slug={project.name}
625 name={project.title ?? project.name}
626 pinned={isPinned}
627 small
628 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"
629 />
630 </div>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar631 );
632 return (
633 <SidebarGroup
634 title="Projects"
635 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.636 <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 sidebar637 <Plus size={13} />
638 </Link>
639 }
640 >
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar641 {/* Only there once something is pinned: each row below has its own pin. */}
642 {pinned.length > 0 && (
643 <>
644 <SidebarSubhead>Pinned</SidebarSubhead>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar645 <ul aria-label="Pinned projects" className="space-y-px">
646 {pinned.map((project, index) => (
647 <li
648 key={project.name}
649 draggable={pinned.length > 1}
650 onDragStart={(event) => {
651 setDragging(index);
652 event.dataTransfer.effectAllowed = "move";
653 }}
654 onDragOver={(event) => {
655 if (dragging != null) event.preventDefault();
656 }}
657 onDrop={(event) => {
658 event.preventDefault();
659 if (dragging != null && dragging !== index) move(dragging, index - dragging);
660 setDragging(null);
661 }}
662 onDragEnd={() => setDragging(null)}
663 onKeyDown={(event) => {
664 if (!event.altKey || (event.key !== "ArrowUp" && event.key !== "ArrowDown")) return;
665 event.preventDefault();
666 move(index, event.key === "ArrowUp" ? -1 : 1);
667 }}
668 className={`group/pin relative ${dragging === index ? "opacity-50" : ""}`}
669 >
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar670 {row(project, true)}
Navigation: the workspace's own page with tabs, pins and recent in the sidebar671 {pinned.length > 1 && (
Merge branch 'worktree-agent-ae1299e92e4462012'672 <Hint label="Drag, or Alt and an arrow key, to reorder" side="right">
673 <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">
674 <GripVertical size={12} aria-hidden="true" />
675 </span>
676 </Hint>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar677 )}
678 </li>
679 ))}
680 </ul>
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar681 </>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar682 )}
683 {recent.length > 0 && (
684 <>
685 <SidebarSubhead>Recent</SidebarSubhead>
686 {recent.map((project) => (
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar687 <div key={`${project.namespace}/${project.name}`}>{row(project, false)}</div>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar688 ))}
689 </>
690 )}
691 <div className="pt-1">
Merge branch 'worktree-agent-ad7c6d88d93adc817'692 <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 sidebar693 All projects
694 </SidebarLink>
695 </div>
696 </SidebarGroup>
697 );
698}
699
Merge branch 'worktree-agent-ad7c6d88d93adc817'700/** Insights, coming: the workspace's own page says what it will be. */
701const INSIGHTS = roadmapItem("insights");
702
New workspaces are told to connect a model, before anything fails703/**
704 * What the repository menu needs. Known from the address before the page's
705 * data arrives, so the menu is right from the first frame; the counts fill
706 * in once it does.
707 */
708type MenuRepo = {
709 namespace: string;
710 name: string;
711 member: boolean;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look712 /** Whether they see its settings; from the repository's page once it loads. */
713 settings?: boolean;
714 /** What they may do there, once the repository's page loads. */
715 can?: Abilities;
New workspaces are told to connect a model, before anything fails716 issues?: number;
717 pulls?: number;
718};
719
720function sameRepo(a: { namespace: string; name: string } | null, b: { namespace: string; name: string } | null) {
721 return (
722 a != null &&
723 b != null &&
724 a.namespace.toLowerCase() === b.namespace.toLowerCase() &&
725 a.name.toLowerCase() === b.name.toLowerCase()
726 );
727}
728
729/**
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look730 * A project's own list, drilled into while you are in it: everything about
731 * the project, running and its code, and nothing else, with the way back
732 * out to all of them.
New workspaces are told to connect a model, before anything fails733 */
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put734function RepoMenu({
735 repo,
736 isPrivate,
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look737 back,
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put738}: {
739 repo: MenuRepo;
740 isPrivate: boolean;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look741 /** Where the way back leads: the workspace's projects, mission control, or Explore. */
742 back: { to: string; label: string };
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put743}) {
New workspaces are told to connect a model, before anything fails744 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 put745 // 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 look746 const shows = new Set(projectPages(repo.member, repo.can));
New workspaces are told to connect a model, before anything fails747 return (
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look748 <nav aria-label={`${repo.namespace}/${repo.name}`} className={PANEL}>
749 <BackRow to={back.to} label={back.label} />
Merge branch 'worktree-agent-ae1299e92e4462012'750 <Hint label="Overview" side="right">
Sidebar: soon rows and the project row keep their styles inside a hint; tiny amounts read as zero751 <div>
A flat project menu with Code first, views as tabs, and Stripe for every owner752 <NavLink
New workspaces are told to connect a model, before anything fails753 to={base}
A flat project menu with Code first, views as tabs, and Stripe for every owner754 end
Fast pages, required checks on the branch, self-hosted runners, honest incidents755 prefetch="intent"
A flat project menu with Code first, views as tabs, and Stripe for every owner756 className={({ isActive }) =>
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look757 `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 owner758 }
New workspaces are told to connect a model, before anything fails759 >
760 <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 page761 {isPrivate ? <Lock size={13} /> : <Box size={13} />}
New workspaces are told to connect a model, before anything fails762 </span>
763 <span className="min-w-0 truncate font-mono text-[0.8125rem]">
764 <span className="text-faint">{repo.namespace}/</span>
765 <span className="font-semibold text-fg">{repo.name}</span>
766 </span>
A flat project menu with Code first, views as tabs, and Stripe for every owner767 </NavLink>
Sidebar: soon rows and the project row keep their styles inside a hint; tiny amounts read as zero768 </div>
Merge branch 'worktree-agent-ae1299e92e4462012'769 </Hint>
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look770 {/* A project's pages, in the order people use them. A page with more
771 than one view shows them as tabs across its top. */}
772 <Rule />
773 <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 request774 <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 owner775 Code
776 </SidebarLink>
Usage, Billing settings and prepaid AI credit; fixes from the UX audit777 <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 owner778 Issues
779 </SidebarLink>
780 <SidebarLink to={`${base}/pulls`} also={[`${base}/pull`, `${base}/queue`]} icon={<GitPullRequest size={15} />} count={repo.pulls}>
781 Pull requests
782 </SidebarLink>
Agents and memory, checks and conflicts, profiles, slug renames, custom domains783 <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 owner784 Agents
Agents and memory, checks and conflicts, profiles, slug renames, custom domains785 </SidebarLink>
A flat project menu with Code first, views as tabs, and Stripe for every owner786 <SidebarLink to={`${base}/actions`} icon={<PlayCircle size={15} />}>
787 Workflows
Projects: what a workspace builds and runs, first on every page788 </SidebarLink>
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look789 </div>
790 <Rule />
791 <div className="space-y-px">
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put792 {shows.has("deployments") ? (
A flat project menu with Code first, views as tabs, and Stripe for every owner793 <SidebarLink to={`${base}/deployments`} also={soonPaths(base, "Deployments")} icon={<Rocket size={15} />}>
794 Deployments
795 </SidebarLink>
796 ) : null}
Observability gets its own page; tabs never overflow797 <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.">
798 Observability
A flat project menu with Code first, views as tabs, and Stripe for every owner799 </SidebarSoonLink>
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put800 {shows.has("security") ? (
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API801 <SidebarLink to={`${base}/security`} also={soonPaths(base, "Security")} icon={<ShieldCheck size={15} />}>
802 Security
803 </SidebarLink>
804 ) : null}
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97805 <SidebarLink
806 to={`${base}/contributors`}
807 also={[`${base}/activity`, `${base}/stargazers`, ...soonPaths(base, "Insights")]}
808 icon={<BarChart3 size={15} />}
809 >
A flat project menu with Code first, views as tabs, and Stripe for every owner810 Insights
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97811 </SidebarLink>
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look812 </div>
813 {(repo.settings ?? shows.has("settings")) && (
814 <>
815 <Rule />
816 <SidebarLink to={`${base}/settings`} icon={<Settings size={15} />} drill>
A flat project menu with Code first, views as tabs, and Stripe for every owner817 Settings
818 </SidebarLink>
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look819 </>
820 )}
New workspaces are told to connect a model, before anything fails821 </nav>
822 );
823}
824
Project settings move into the sidebar, grouped, with a heading per page825/**
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look826 * A project's settings, drilled into from its list: what is about running
827 * it, then its agents, then its code and who can reach it. The way back
828 * leads to the project.
Project settings move into the sidebar, grouped, with a heading per page829 */
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look830function RepoSettingsMenu({ repo }: { repo: MenuRepo }) {
Project settings move into the sidebar, grouped, with a heading per page831 const base = `/${repo.namespace}/${repo.name}`;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look832 // Each page shows to the roles that can use it, once the role is known.
833 const shows = (page: string) => !repo.can || repo.can[SETTINGS_CAPABILITY[page] ?? "administer"];
834 const running = shows("deployments");
835 const agents = shows("agents") || shows("guardrails");
Project settings move into the sidebar, grouped, with a heading per page836 return (
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look837 <nav aria-label={`${repo.namespace}/${repo.name} settings`} className={PANEL}>
838 <BackRow to={base} label="Settings" context={`${repo.namespace}/${repo.name}`} />
839 {shows("") && (
840 <div className="mt-2 space-y-px">
841 <SidebarLink to={`${base}/settings`} end icon={<Settings size={15} />}>
842 General
843 </SidebarLink>
844 </div>
845 )}
846 {running && (
847 <>
848 {shows("") && <Rule />}
849 <div className={shows("") ? "space-y-px" : "mt-2 space-y-px"}>
850 <SidebarLink to={`${base}/settings/deployments`} icon={<Rocket size={15} />}>
851 Deployments
852 </SidebarLink>
853 <SidebarLink to={`${base}/settings/domains`} icon={<Globe size={15} />}>
854 Domains
855 </SidebarLink>
856 </div>
857 </>
858 )}
859 {agents && (
860 <>
861 <Rule />
862 <div className="space-y-px">
863 {shows("agents") && (
864 <SidebarLink to={`${base}/settings/agents`} icon={<Bot size={15} />}>
865 Agents
866 </SidebarLink>
867 )}
868 {shows("guardrails") && (
869 <SidebarLink to={`${base}/settings/guardrails`} icon={<ShieldCheck size={15} />}>
870 Guardrails
871 </SidebarLink>
872 )}
873 </div>
874 </>
875 )}
876 <Rule />
877 <div className="space-y-px">
878 {shows("repository") && (
879 <SidebarLink to={`${base}/settings/repository`} icon={<BookMarked size={15} />}>
880 Repository
881 </SidebarLink>
882 )}
Merge branch 'mirroring' into artifacts-mode883 {shows("mirroring") && (
884 <SidebarLink to={`${base}/settings/mirroring`} icon={<ArrowLeftRight size={15} />}>
885 Mirroring
886 </SidebarLink>
887 )}
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look888 {shows("access") && (
889 <SidebarLink to={`${base}/settings/access`} icon={<Users size={15} />}>
890 Access
891 </SidebarLink>
892 )}
Merge branch 'worktree-agent-a5a5de74d8863d554' into worktree-agent-a16631325aecf58ca893 {shows("keys") && (
894 <SidebarLink to={`${base}/settings/keys`} icon={<KeyRound size={15} />}>
895 Deploy keys
896 </SidebarLink>
897 )}
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look898 {shows("branches") && (
899 <SidebarLink to={`${base}/settings/branches`} icon={<GitBranch size={15} />}>
900 Branches and merging
901 </SidebarLink>
902 )}
Merge rulesets: branch and tag rules, agent-first, enforced on push and merge903 {shows("rules") && (
904 <SidebarLink to={`${base}/settings/rules`} icon={<Scale size={15} />}>
905 Rules
906 </SidebarLink>
907 )}
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look908 {shows("secrets") && (
909 <SidebarLink to={`${base}/settings/secrets`} icon={<Lock size={15} />}>
910 Secrets and variables
911 </SidebarLink>
912 )}
Merge branch 'worktree-agent-a3abfcce648e87dca'913 {shows("actions") && (
914 <SidebarLink to={`${base}/settings/actions`} icon={<PlayCircle size={15} />}>
915 Actions
916 </SidebarLink>
917 )}
918 {shows("environments") && (
919 <SidebarLink to={`${base}/settings/environments`} icon={<Layers size={15} />}>
920 Environments
921 </SidebarLink>
922 )}
Fast pages, required checks on the branch, self-hosted runners, honest incidents923 {shows("runners") && (
924 <SidebarLink to={`${base}/settings/runners`} icon={<ServerCog size={15} />}>
925 Runners
926 </SidebarLink>
927 )}
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look928 {shows("webhooks") && (
929 <SidebarLink to={`${base}/settings/webhooks`} icon={<Webhook size={15} />}>
930 Webhooks
931 </SidebarLink>
932 )}
933 </div>
Project settings move into the sidebar, grouped, with a heading per page934 </nav>
935 );
936}
937
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)938/**
939 * Whether the menus list Settings → Invites (invites to g1t): always while
940 * sign-up takes an invite; once anyone can sign up, only for someone with
941 * invites already made to look back on, which the account menu's data says.
942 */
943function useInvitesListed(): boolean {
944 const inviteOnly = useInviteOnly();
945 const details = useFetcher<AccountMenuData | null>({ key: "account-menu" });
946 useEffect(() => {
947 if (!inviteOnly && details.state === "idle" && details.data === undefined) details.load("/settings/menu.json");
948 // eslint-disable-next-line react-hooks/exhaustive-deps
949 }, [inviteOnly]);
950 return inviteOnly || details.data?.invites_page === true;
951}
952
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas953/** Your own settings, drilled into from Your settings: one page each. */
954function 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)955 const invites = useInvitesListed();
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas956 const link = (page: AccountSettingsPage, icon: ReactNode) => (
957 <SidebarLink to={`/settings/${page}`} icon={icon}>
958 {ACCOUNT_SETTINGS[page].title}
959 </SidebarLink>
New workspaces are told to connect a model, before anything fails960 );
961 return (
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look962 <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 quotas963 <BackRow to="/" label="Your settings" context={username} />
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look964 <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 quotas965 {link("profile", <CircleUserRound size={15} />)}
966 {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)967 {invites && link("invites", <Ticket size={15} />)}
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas968 </div>
969 <Rule />
970 <div className="space-y-px">
971 {link("keys", <Fingerprint size={15} />)}
972 {link("tokens", <KeyRound size={15} />)}
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look973 </div>
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas974 <Rule />
975 <div className="space-y-px">
Integrations are a directory of connectors, for a workspace and for each person976 {link("integrations", <Blocks size={15} />)}
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas977 {link("github", <GithubMark className="size-[15px]" />)}
978 {link("applications", <Plug size={15} />)}
979 </div>
980 <Rule />
981 <div className="space-y-px">
Merge main (membership, two-factor, GitHub repo roles) into tokens982 {link("two-factor", <ShieldCheck size={15} />)}
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas983 {link("security-log", <History size={15} />)}
984 </div>
New workspaces are told to connect a model, before anything fails985 </nav>
986 );
987}
988
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put989/**
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.990 * Code's sidebar: its Overview, the projects, what spans them and what is
991 * coming; in a project, drilled into the project's own list, and its
992 * settings one level further in. The address says which, so a link
993 * 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 put994 */
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.995function CodeSidebar({
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look996 user,
997 shell,
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas998 missing = false,
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look999}: {
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.1000 user: User;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1001 shell: ShellData;
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1002 /** The page is a 404: the address names nothing the viewer can see. */
1003 missing?: boolean;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1004}) {
New workspaces are told to connect a model, before anything fails1005 const ws = shell.workspace;
1006 const { pathname } = useLocation();
1007 const going = useNavigation().location?.pathname;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1008 // Where the sidebar is drilled to follows the page being gone to, so it
1009 // moves as the link is followed, not once the page arrives.
1010 const target = going ?? pathname;
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1011 // On a 404, the address is not a place: no list is drilled into from it,
1012 // except the project's own when the project is real and visible and only
1013 // something inside it is missing (a file, a commit, an issue).
1014 const lost = missing && going == null;
New workspaces are told to connect a model, before anything fails1015 const active = shell.repo;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1016 // In a repository, or on the way into one, its own list.
New workspaces are told to connect a model, before anything fails1017 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.1018 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 look1019 // An invitation to a repository is answered before its menu means anything.
1020 const inRepo =
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1021 repoPath != null &&
1022 !reserved.has(repoPath[1]) &&
1023 repoPath[2] !== "-" &&
1024 !/^\/[^/]+\/[^/]+\/invitations\/?$/.test(target) &&
1025 (!lost || sameRepo(active, { namespace: repoPath[1]!, name: repoPath[2]! }));
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1026 // A project's settings, one level further in.
Project settings move into the sidebar, grouped, with a heading per page1027 const inRepoSettings = inRepo && REPO_SETTINGS_PAGE.test(target);
New workspaces are told to connect a model, before anything fails1028 // The repository the menu is for: the one loaded if it is the one being
1029 // gone to, else what the address says, at once.
1030 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 look1031 const guessed: MenuRepo | null = targetRepo
New workspaces are told to connect a model, before anything fails1032 ? sameRepo(active, targetRepo)
1033 ? active
1034 : {
1035 ...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.1036 member: (user.workspaces ?? []).some((m) => m.slug === targetRepo.namespace.toLowerCase()),
New workspaces are told to connect a model, before anything fails1037 }
1038 : null;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1039 // The viewer's role there, from the repository's page once it has loaded.
1040 const page = useRouteLoaderData("routes/repo/layout") as
1041 | { repo?: { namespace: string; name: string }; access?: ViewerAccess }
1042 | undefined;
1043 const menuRepo: MenuRepo | null =
1044 guessed && page?.access && page.repo && sameRepo(page.repo, guessed)
1045 ? { ...guessed, member: page.access.insider, settings: seesSettings(page.access), can: page.access.can }
1046 : guessed;
1047
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.1048 // The way from Code's list to the one shown.
1049 const trail: Level[] = [{ key: "main", node: ws ? <CodeMenu shell={shell} slug={ws.slug} /> : null }];
1050 if (menuRepo) {
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1051 const key = `repo:${menuRepo.namespace}/${menuRepo.name}`.toLowerCase();
1052 // 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.1053 const home = (user.workspaces ?? []).find((m) => m.slug === menuRepo.namespace.toLowerCase());
1054 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 look1055 trail.push({
1056 key,
1057 node: (
1058 <RepoMenu
1059 repo={menuRepo}
1060 isPrivate={[...shell.repos, ...(shell.shared ?? [])].some((repo) => sameRepo(repo, menuRepo) && repo.isPrivate)}
1061 back={back}
1062 />
1063 ),
1064 });
1065 if (inRepoSettings) trail.push({ key: `${key}:settings`, node: <RepoSettingsMenu repo={menuRepo} /> });
1066 }
1067
New workspaces are told to connect a model, before anything fails1068 return (
1069 <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.1070 <ModeHeader title="Code" />
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1071 <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)1072 </div>
1073 );
1074}
1075
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.1076/**
1077 * A mode's sidebar heading: its name, quiet, under the workspace's
1078 * switcher, with what it makes at the end.
1079 */
1080export 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)1081 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.1082 <div className="flex h-9 shrink-0 items-center gap-1 pr-1 pl-3">
1083 <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)1084 {action}
1085 </div>
1086 );
1087}
1088
1089/**
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.1090 * 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)1091 * 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.1092 * 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)1093 * agents, context and memory are Agents'.
1094 */
1095function CodeMenu({ shell, slug }: { shell: ShellData; slug: string }) {
1096 const { pathname } = useLocation();
1097 const going = useNavigation().location?.pathname;
1098 const path = going ?? pathname;
1099 const at = (page: string) => path === `/${slug}/-/${page}` || path.startsWith(`/${slug}/-/${page}/`);
1100 const shared = shell.shared ?? [];
1101 return (
1102 <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.1103 <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)1104 <SidebarLink to={`/${slug}/-/overview`} icon={<LayoutDashboard size={15} />} current={at("overview")}>
1105 Overview
1106 </SidebarLink>
1107 </div>
1108 <div className="mt-3">
1109 <SidebarProjects slug={slug} shell={shell} current={at("projects")} />
1110 </div>
1111 <Rule />
1112 <div className="space-y-px">
1113 <SidebarLink to={`/${slug}/-/security`} icon={<ShieldCheck size={15} />} current={at("security") && !at("security/settings")}>
1114 Security
1115 </SidebarLink>
1116 <SidebarLink to={`/${slug}/-/packages`} icon={<Package size={15} />} current={at("packages")}>
1117 Packages
1118 </SidebarLink>
1119 {INSIGHTS && (
1120 <SidebarSoonLink to={`/${slug}/-/insights`} icon={<TrendingUp size={15} />} about={INSIGHTS.summary} current={at("insights")}>
1121 {INSIGHTS.title}
1122 </SidebarSoonLink>
1123 )}
1124 {roadmapIn("Workspace")
1125 .filter((item) => item.key !== "insights" && item.key !== "teams" && item.key !== "fleet")
1126 .map((item) => (
1127 <SidebarSoonLink key={item.key} to={`/${slug}/-/soon/${item.key}`} icon={WORKSPACE_ICONS[item.key] ?? <Sparkles size={15} />} about={item.summary}>
1128 {item.title === "Board" ? "Boards" : item.title}
1129 </SidebarSoonLink>
1130 ))}
1131 </div>
1132 {shared.length > 0 && (
1133 <>
1134 <Rule />
1135 <SidebarGroup title="Shared with you">
1136 {shared.map((repo) => (
1137 <SidebarLink
1138 key={`${repo.namespace}/${repo.name}`}
1139 to={`/${repo.namespace}/${repo.name}`}
1140 icon={repo.isPrivate ? <Lock size={15} /> : <Box size={15} />}
1141 drill="hover"
1142 >
1143 <span className="font-mono text-faint">{repo.namespace}/</span>
1144 {repo.name}
1145 </SidebarLink>
1146 ))}
1147 </SidebarGroup>
1148 </>
1149 )}
1150 </nav>
1151 );
1152}
1153
1154/** 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.1155const 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)1156
1157/**
1158 * 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.1159 * 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)1160 * settings as a list of their own. Owner-only pages stay owner-only.
1161 */
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.1162export 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)1163 const { pathname } = useLocation();
1164 const going = useNavigation().location?.pathname;
1165 const path = going ?? pathname;
1166 const page = path.startsWith(`/${slug}/-/`) ? path.slice(`/${slug}/-/`.length) : "";
1167 const top = page.split("/")[0] ?? "";
1168 const at = (...pages: string[]) => pages.some((p) => page === p || page.startsWith(`${p}/`));
1169 const inSettings = WORKSPACE_SETTINGS.includes(top);
1170 const main = (
1171 <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.1172 <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)1173 <SidebarLink to={`/${slug}/-/workspace`} icon={<LayoutGrid size={15} />} current={at("workspace")}>
1174 Overview
1175 </SidebarLink>
1176 </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.1177 <SidebarGroup title="Money" className="mt-3">
1178 <SidebarLink to={`/${slug}/-/spend`} icon={<Coins size={15} />} current={at("spend")}>
1179 Spend
1180 </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.1181 <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)1182 Usage
1183 </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.1184 <SidebarLink to={`/${slug}/-/gateway`} icon={<Network size={15} />} current={at("gateway")}>
1185 AI Gateway
1186 </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)1187 <SidebarLink to={`/${slug}/-/billing`} icon={<CreditCard size={15} />} current={at("billing")}>
1188 Billing and plans
1189 </SidebarLink>
1190 </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.1191 {owner && (
1192 <SidebarGroup title="Compute" className="mt-3">
1193 <SidebarLink to={`/${slug}/-/runners`} icon={<ServerCog size={15} />} current={at("runners")}>
1194 Runners
1195 </SidebarLink>
1196 </SidebarGroup>
1197 )}
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)1198 <SidebarGroup title="Connections" className="mt-3">
1199 <SidebarLink to={`/${slug}/-/integrations`} icon={<Plug size={15} />} current={at("integrations")}>
1200 Integrations
1201 </SidebarLink>
1202 </SidebarGroup>
1203 <SidebarGroup title="Security policies" className="mt-3">
1204 <SidebarLink to={`/${slug}/-/security/settings`} icon={<ShieldCheck size={15} />} current={at("security/settings")}>
1205 Security settings
1206 </SidebarLink>
1207 <SidebarLink to={`/${slug}/-/guardrails`} icon={<Gauge size={15} />} current={at("guardrails")}>
1208 Guardrails
1209 </SidebarLink>
1210 <SidebarLink to={`/${slug}/-/rules`} icon={<Scale size={15} />} current={at("rules")}>
1211 Rules
1212 </SidebarLink>
1213 </SidebarGroup>
1214 <Rule />
1215 <div className="space-y-px">
1216 <SidebarLink to={`/${slug}/-/audit`} icon={<History size={15} />} current={at("audit")}>
1217 Audit log
1218 </SidebarLink>
1219 <SidebarLink to={owner ? `/${slug}/-/settings` : `/${slug}/-/repositories`} icon={<Settings size={15} />} drill current={inSettings}>
1220 Settings
1221 </SidebarLink>
1222 </div>
1223 </nav>
1224 );
1225 const settings = (
1226 <nav aria-label="Workspace settings" className={PANEL}>
1227 <BackRow to={`/${slug}/-/workspace`} label="Settings" context={slug} />
1228 <div className="mt-2 space-y-px">
1229 {owner && (
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1230 <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)1231 General
1232 </SidebarLink>
1233 )}
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1234 <SidebarLink to={`/${slug}/-/settings/chat`} icon={<MessagesSquare size={15} />}>
1235 Chat
1236 </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)1237 <SidebarLink to={`/${slug}/-/repositories`} icon={<BookMarked size={15} />}>
1238 Repositories
1239 </SidebarLink>
1240 <SidebarLink to={`/${slug}/-/tokens`} icon={<KeyRound size={15} />}>
1241 Access tokens
1242 </SidebarLink>
1243 {owner && (
1244 <SidebarLink to={`/${slug}/-/personal-access-tokens`} icon={<UserRoundKey size={15} />}>
1245 Personal access tokens
1246 </SidebarLink>
1247 )}
1248 <SidebarLink to={`/${slug}/-/webhooks`} icon={<Webhook size={15} />}>
1249 Webhooks
1250 </SidebarLink>
1251 <SidebarLink to={`/${slug}/-/emoji`} icon={<Smile size={15} />}>
1252 Emoji
1253 </SidebarLink>
1254 </div>
1255 <SidebarGroup title="Runs" className="mt-3">
1256 <SidebarLink to={`/${slug}/-/secrets`} icon={<Lock size={15} />}>
1257 Secrets and variables
1258 </SidebarLink>
1259 <SidebarLink to={`/${slug}/-/actions`} icon={<PlayCircle size={15} />}>
1260 Actions
1261 </SidebarLink>
1262 </SidebarGroup>
1263 </nav>
1264 );
1265 const trail: Level[] = [{ key: "workspace", node: main }];
1266 if (inSettings) trail.push({ key: "workspace:settings", node: settings });
1267 return (
1268 <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.1269 <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)1270 <Drill trail={trail} />
1271 </div>
1272 );
1273}
1274
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.1275/**
1276 * People's sidebar: everyone in the workspace, people and agents; its
1277 * teams; the org chart; and, to manage who belongs, members and invites.
1278 */
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.1279function PeopleSidebar({ slug }: { slug: string }) {
1280 const { pathname } = useLocation();
1281 const going = useNavigation().location?.pathname;
1282 const path = going ?? pathname;
1283 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)1284 return (
1285 <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.1286 <ModeHeader title="People" />
1287 <nav aria-label="People" className={PANEL}>
1288 <div className="space-y-px">
1289 <SidebarLink to={`/${slug}/-/people`} icon={<Users size={15} />} current={at("people")}>
1290 Everyone
1291 </SidebarLink>
1292 <SidebarLink to={`/${slug}/-/teams`} icon={<UsersRound size={15} />} current={at("teams")}>
1293 Teams
1294 </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.1295 <SidebarLink to={`/${slug}/-/org-chart`} icon={<Network size={15} />} current={at("org-chart")}>
1296 Org chart
1297 </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.1298 </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.1299 <SidebarGroup title="Membership" className="mt-3">
1300 <SidebarLink to={`/${slug}/-/members`} icon={<UserPlus size={15} />} current={at("members")}>
1301 Members and invites
1302 </SidebarLink>
1303 </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.1304 </nav>
1305 </div>
1306 );
1307}
1308
1309/**
1310 * Notifications' sidebar: what you have not finished with, what you saved
1311 * and what is done; then why you were told, which narrows any of them.
1312 */
1313function NotificationsSidebar({ counts }: { counts: InboxCounts | null }) {
1314 const { search } = useLocation();
1315 const params = new URLSearchParams(search);
1316 const view = inboxView(params.get("view"));
1317 const reason = inboxReason(params.get("reason"));
1318 const tab = params.get("tab");
1319 const address = (changes: Record<string, string | null>) => {
1320 const merged: Record<string, string | null> = { tab, view: view === "inbox" ? null : view, reason, ...changes };
1321 const next = new URLSearchParams();
1322 for (const [name, value] of Object.entries(merged)) if (value) next.set(name, value);
1323 const query = next.toString();
1324 return query ? `/notifications?${query}` : "/notifications";
1325 };
1326 const views = [
1327 { view: "inbox", label: "Everything", icon: <Bell size={15} />, count: counts?.unread },
1328 { view: "saved", label: "Saved", icon: <Bookmark size={15} /> },
1329 { view: "done", label: "Done", icon: <Check size={15} /> },
1330 ] as const;
1331 return (
1332 <div className="flex h-full flex-col">
1333 <ModeHeader title="Notifications" />
1334 <nav aria-label="Notifications" className={PANEL}>
1335 <div className="space-y-px">
1336 {views.map((entry) => (
1337 <SidebarLink
1338 key={entry.view}
1339 to={address({ view: entry.view === "inbox" ? null : entry.view, before: null })}
1340 icon={entry.icon}
1341 count={"count" in entry ? (entry.count ?? undefined) : undefined}
1342 current={view === entry.view}
1343 >
1344 {entry.label}
1345 </SidebarLink>
1346 ))}
1347 </div>
1348 <SidebarGroup title="Why you were told" className="mt-4">
1349 {REASON_FILTERS.map((entry) => (
1350 <SidebarLink
1351 key={entry.reason ?? "any"}
1352 to={address({ reason: entry.reason, before: null })}
1353 icon={<span className="block size-[15px]" />}
1354 current={reason === entry.reason}
1355 >
1356 {entry.reason == null ? "Any reason" : entry.label}
1357 </SidebarLink>
1358 ))}
1359 </SidebarGroup>
1360 </nav>
1361 </div>
1362 );
1363}
1364
1365/** Your own settings, beside the page: under the account menu, not any workspace's. */
1366export function AccountSidebar({ username }: { username: string }) {
1367 return (
1368 <div className="flex h-full flex-col">
1369 <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)1370 <div className="min-h-0 grow">
1371 <AccountSettingsMenu username={username} />
New workspaces are told to connect a model, before anything fails1372 </div>
1373 </div>
1374 );
1375}
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)1376
New workspaces are told to connect a model, before anything fails1377/** Words for the sections a path can end in. */
1378const SECTIONS: Record<string, string> = {
1379 issues: "Issues",
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1380 milestones: "Milestones",
1381 labels: "Labels",
New workspaces are told to connect a model, before anything fails1382 pulls: "Pull requests",
1383 queue: "Merge queue",
1384 commits: "Commits",
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales1385 plans: "Outcomes",
1386 actions: "Workflows",
1387 soon: "Soon",
Deployments: a preview for every pull request, production on g1t.page1388 deployments: "Deployments",
Projects: what a workspace builds and runs, first on every page1389 repository: "Repository",
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1390 access: "Access",
1391 invitations: "Invitation",
1392 repositories: "Repositories",
Branches and Tags pages, each file's last commit, and the branch menu on files1393 branches: "Branches",
1394 tags: "Tags",
Compare: any two branches, the commits one has that the other does not, and the diff, with Open a pull request1395 compare: "Compare",
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales1396 code: "Files",
New workspaces are told to connect a model, before anything fails1397 secrets: "Secrets and variables",
1398 settings: "Settings",
Navigation: the workspace's own page with tabs, pins and recent in the sidebar1399 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.1400 "org-chart": "Org chart",
1401 members: "Members and invites",
Navigation: the workspace's own page with tabs, pins and recent in the sidebar1402 projects: "Projects",
1403 teams: "Teams",
New workspaces are told to connect a model, before anything fails1404 tokens: "Access tokens",
Settings: fine-grained tokens, workspace token Admin, workspace personal access token rules1405 "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.1406 spend: "Spend",
1407 receipts: "Receipts",
New workspaces are told to connect a model, before anything fails1408 usage: "Usage",
Site: the AI Gateway page's breadcrumb reads "AI Gateway"1409 gateway: "AI Gateway",
Secrets and variables: one list, rows per environment, for workflows and deployments1410 billing: "Billing and plans",
New workspaces are told to connect a model, before anything fails1411 integrations: "Integrations",
1412 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)1413 emoji: "Emoji",
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1414 domains: "Domains",
1415 guardrails: "Guardrails",
Merge rulesets: branch and tag rules, agent-first, enforced on push and merge1416 rules: "Rules",
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1417 audit: "Audit log",
Files pages say Files in the trail and keep the description in About only1418 tree: "Files",
1419 blob: "Files",
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail1420 agents: "Agents",
1421 context: "Context",
1422 memory: "Memory",
1423 security: "Security",
1424 packages: "Packages",
1425 runners: "Runners",
Merge branch 'worktree-agent-a3abfcce648e87dca'1426 environments: "Environments",
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail1427 workflows: "Workflows",
1428 observability: "Observability",
1429 insights: "Insights",
1430 sessions: "Sessions",
Chat and workspace agents: channels, DMs and named agents you talk to1431 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.1432 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.1433 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.1434 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.1435 marketplace: "Marketplace",
Chat and workspace agents: channels, DMs and named agents you talk to1436 "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)1437 overview: "Overview",
1438 workspace: "Workspace",
New workspaces are told to connect a model, before anything fails1439};
1440
Merge branch 'worktree-agent-a3abfcce648e87dca'1441/** Settings pages whose name differs from the section's of the same word. */
1442const SETTINGS_SECTIONS: Record<string, string> = { branches: "Branches and merging", actions: "Actions" };
1443
New workspaces are told to connect a model, before anything fails1444/** 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.1445function Breadcrumbs({
1446 pathname,
1447 missing,
1448 repo,
1449 workspace,
1450}: {
1451 pathname: string;
1452 missing?: boolean;
1453 repo?: ShellData["repo"];
1454 /** The workspace you are in: the switcher names it, so the trail starts after it. */
1455 workspace: string | null;
1456}) {
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1457 // A 404 names nothing from the address, unless the project is real and
1458 // visible and only something inside it is missing.
1459 const visibleRepo = /^\/([^/]+)\/([^/-][^/]*)(\/|$)/.exec(pathname);
1460 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.1461 return <Here>Not found</Here>;
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1462 }
New workspaces are told to connect a model, before anything fails1463 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.1464 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.1465 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 quotas1466 // Your settings: Settings / Emails.
1467 if (parts[0] === "settings") {
1468 const page = accountSettingsPage(pathname);
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1469 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 quotas1470 }
New workspaces are told to connect a model, before anything fails1471 if (reserved.includes(parts[0]!)) {
1472 const words: Record<string, string> = {
1473 settings: "Account",
1474 explore: "Explore",
Projects live: fixes from walking them end to end1475 new: "New project",
New workspaces are told to connect a model, before anything fails1476 search: "Search",
1477 workspaces: "New workspace",
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1478 policies: "Policies",
1479 security: "Security",
1480 support: "Support",
1481 status: "Status",
1482 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.1483 notifications: "Notifications",
New workspaces are told to connect a model, before anything fails1484 };
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.1485 return <Here>{words[parts[0]!]}</Here>;
New workspaces are told to connect a model, before anything fails1486 }
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put1487 // A person's profile, by their handle.
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1488 if (parts[0] === "u" && parts[1]) return <ProfileCrumb username={parts[1]} />;
New workspaces are told to connect a model, before anything fails1489 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.1490 const ours = workspace != null && owner!.toLowerCase() === workspace.toLowerCase();
1491 const trail: Crumb[] = ours ? [] : [{ label: owner!, to: `/${owner}`, mono: true }];
New workspaces are told to connect a model, before anything fails1492 if (second === "-") {
1493 const page = `/${owner}/-/${third}`;
1494 if (third && SETTINGS_PAGE.test(page)) {
1495 trail.push({ label: "Settings", to: `/${owner}/-/settings` });
1496 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.1497 } else if (third) {
1498 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.1499 // The Marketplace names its tab (Marketplace / Extensions), and Agents its templates.
1500 const tabs: Record<string, string> =
1501 third === "marketplace" ? { integrations: "Integrations", extensions: "Extensions", requests: "Requests" } : third === "agents" ? { templates: "Templates" } : {};
1502 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.1503 if (tab) trail.push({ label: tab, to: `${page}/${fourth}` });
1504 }
New workspaces are told to connect a model, before anything fails1505 } else if (second) {
1506 const repo = `/${owner}/${second}`;
1507 trail.push({ label: second, to: repo, mono: true });
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1508 if (third === "pull" && fourth) trail.push({ label: `Pull request #${fourth}`, short: `#${fourth}`, to: `${repo}/pull/${fourth}` });
1509 else if (third === "issues" && fourth && fourth !== "new") trail.push({ label: `Issue #${fourth}`, short: `#${fourth}`, to: `${repo}/issues/${fourth}` });
New workspaces are told to connect a model, before anything fails1510 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 deployments1511 else if (third && SECTIONS[third]) {
1512 trail.push({ label: SECTIONS[third]!, to: `${repo}/${third}` });
1513 // A settings page names which one: Settings / Secrets and variables.
1514 if (third === "settings" && fourth && SECTIONS[fourth]) {
Merge branch 'worktree-agent-a3abfcce648e87dca'1515 trail.push({ label: SETTINGS_SECTIONS[fourth] ?? SECTIONS[fourth]!, to: `${repo}/settings/${fourth}` });
Secrets and variables: one list, rows per environment, for workflows and deployments1516 }
1517 }
New workspaces are told to connect a model, before anything fails1518 }
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.1519 if (trail.length === 0) trail.push({ label: "Overview", to: `/${owner}` });
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1520 return <Trail trail={trail} />;
1521}
1522
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1523/** A profile's place in the top bar: the person's avatar and @handle, from the page once it has loaded. */
1524function 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 managers1525 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 project1526 const profile = page?.profile?.username.toLowerCase() === username.toLowerCase() ? page.profile : null;
1527 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.1528 <Breadcrumb className="min-w-0">
1529 <BreadcrumbList>
1530 <BreadcrumbItem>
1531 <BreadcrumbPage asChild className="flex items-center gap-2 hover:bg-raised">
1532 <Link to={`/u/${profile?.username ?? username}`}>
1533 <Avatar name={profile?.username ?? username} image={profile?.avatar ?? null} size={20} />
1534 <span className="truncate font-mono text-[0.8125rem]">@{profile ? shownUsername(profile) : username}</span>
1535 </Link>
1536 </BreadcrumbPage>
1537 </BreadcrumbItem>
1538 </BreadcrumbList>
1539 </Breadcrumb>
1540 );
1541}
1542
1543/** A page with no trail to it, such as Today or Search: its name alone. */
1544function Here({ children }: { children: ReactNode }) {
1545 return (
1546 <Breadcrumb className="min-w-0">
1547 <BreadcrumbList>
1548 <BreadcrumbItem>
1549 <BreadcrumbPage>{children}</BreadcrumbPage>
1550 </BreadcrumbItem>
1551 </BreadcrumbList>
1552 </Breadcrumb>
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1553 );
1554}
1555
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1556/** One link of the trail; `short` is what a phone shows when it is the page itself. */
1557type Crumb = { label: string; to: string; mono?: boolean; short?: string };
1558
1559/**
1560 * The trail of links. On a phone there is room for one: the page itself,
1561 * with a way back to where it sits; the whole trail from a wider screen up.
1562 */
1563function 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)1564 // Up on a phone, unless up is the workspace itself: its pages are the tabs.
1565 const up = trail.length > 1 && !/^\/[^/]+$/.test(trail[trail.length - 2]!.to) ? trail[trail.length - 2]! : null;
New workspaces are told to connect a model, before anything fails1566 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.1567 <Breadcrumb className="flex min-w-0 items-center">
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1568 {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.1569 <Button asChild variant="ghost" size="icon-bar" className="-ml-1 sm:hidden">
1570 <Link to={up.to} prefetch="intent" aria-label={`Back to ${up.label}`}>
1571 <ChevronLeft size={16} />
1572 </Link>
1573 </Button>
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1574 )}
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.1575 <BreadcrumbList>
1576 {trail.map((crumb, index) => {
1577 const last = index === trail.length - 1;
1578 const label =
1579 last && crumb.short ? (
1580 <>
1581 <span className="sm:hidden">{crumb.short}</span>
1582 <span className="hidden sm:inline">{crumb.label}</span>
1583 </>
1584 ) : (
1585 crumb.label
1586 );
1587 const mono = crumb.mono ? "font-mono text-[0.8125rem]" : "";
1588 return (
1589 <Fragment key={index}>
1590 {index > 0 && <BreadcrumbSeparator className="max-sm:hidden" />}
1591 <BreadcrumbItem className={last ? "" : "max-sm:hidden"}>
1592 {last ? (
1593 // The page you are on is still a link: to its own top, as the trail always was.
1594 <BreadcrumbPage asChild className={`hover:bg-raised ${mono}`}>
1595 <Link to={crumb.to} prefetch="intent">
1596 {label}
1597 </Link>
1598 </BreadcrumbPage>
1599 ) : (
1600 <BreadcrumbLink asChild className={mono}>
1601 <Link to={crumb.to} prefetch="intent">
1602 {label}
1603 </Link>
1604 </BreadcrumbLink>
1605 )}
1606 </BreadcrumbItem>
1607 </Fragment>
1608 );
1609 })}
1610 </BreadcrumbList>
1611 </Breadcrumb>
New workspaces are told to connect a model, before anything fails1612 );
1613}
1614
Search across all of g1t, Explore, and a command palette1615type Command = PaletteCommand;
New workspaces are told to connect a model, before anything fails1616
1617/** 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.1618function commandsFor(user: User, shell: ShellData): Command[] {
1619 const ws = shell.workspace;
New workspaces are told to connect a model, before anything fails1620 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.1621 ...(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)1622 ? [
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.1623 { 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.1624 { label: "Chat", to: `/${ws.slug}/-/chat`, icon: <MessagesSquare size={15} /> },
1625 { label: "Agents", to: `/${ws.slug}/-/agents`, icon: <Sparkles size={15} /> },
1626 ...(hasCodeAccess(ws) ? [{ label: "Code overview", to: `/${ws.slug}/-/overview`, icon: <Code2 size={15} /> }] : []),
1627 { label: "Artifacts", to: `/${ws.slug}/-/artifacts`, icon: <Shapes size={15} /> },
1628 { 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.1629 { label: "Marketplace", hint: "Extensions and integrations to add", to: `/${ws.slug}/-/marketplace`, icon: <Store size={15} /> },
1630 { 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.1631 { 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)1632 ]
1633 : []),
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step1634 ...(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-agent1635 ? [{ 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 step1636 : []),
New workspaces are told to connect a model, before anything fails1637 { label: "Explore repositories", to: "/explore", icon: <Compass size={15} /> },
Search across all of g1t, Explore, and a command palette1638 { 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.1639 { label: "Notifications", hint: "What needs you", to: "/notifications", icon: <Bell size={15} /> },
Projects: what a workspace builds and runs, first on every page1640 { label: "New project", to: "/new", icon: <Plus size={15} /> },
New workspaces are told to connect a model, before anything fails1641 { 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 quotas1642 { label: "Your settings", to: FIRST_SETTINGS_PAGE, icon: <Settings size={15} /> },
1643 ...(Object.keys(ACCOUNT_SETTINGS) as AccountSettingsPage[])
1644 .filter((page) => page !== "profile")
1645 .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.1646 ...THEME_COMMANDS,
New workspaces are told to connect a model, before anything fails1647 ];
1648 const repo = shell.repo;
1649 if (repo) {
1650 const base = `/${repo.namespace}/${repo.name}`;
1651 const name = `${repo.namespace}/${repo.name}`;
1652 commands.unshift(
Projects: what a workspace builds and runs, first on every page1653 { label: "Overview", hint: name, to: base, icon: <LayoutGrid size={15} /> },
1654 { label: "Code", hint: name, to: `${base}/code`, icon: <Code2 size={15} /> },
New workspaces are told to connect a model, before anything fails1655 { label: "Issues", hint: name, to: `${base}/issues`, icon: <CircleDot size={15} /> },
1656 { 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 step1657 ...(repo.member
1658 ? [{ label: `Put an agent on ${repo.name}`, hint: name, to: `${base}/issues/new?agent=1`, icon: <Sparkles size={15} /> }]
1659 : []),
New workspaces are told to connect a model, before anything fails1660 { label: "Pull requests", hint: name, to: `${base}/pulls`, icon: <GitPullRequest size={15} /> },
1661 { label: "Commits", hint: name, to: `${base}/commits`, icon: <History size={15} /> },
1662 ...(repo.member
1663 ? [
1664 { label: "Plan work", hint: name, to: `${base}/plans`, icon: <ListTree size={15} /> },
Projects: what a workspace builds and runs, first on every page1665 { label: "Deployments", hint: name, to: `${base}/deployments`, icon: <Rocket size={15} /> },
1666 { label: "Secrets and variables", hint: name, to: `${base}/settings/secrets`, icon: <Lock size={15} /> },
1667 { label: "Project settings", hint: name, to: `${base}/settings`, icon: <Settings size={15} /> },
1668 { label: "Repository settings", hint: name, to: `${base}/settings/repository`, icon: <Settings size={15} /> },
New workspaces are told to connect a model, before anything fails1669 ]
1670 : []),
1671 );
1672 }
1673 for (const membership of user.workspaces ?? []) {
1674 commands.push(
Workspace names and icons, and a component kit for every control1675 { 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 sidebar1676 { label: "All projects", hint: membership.slug, to: `/${membership.slug}/-/projects`, icon: <LayoutGrid size={15} /> },
1677 { 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.1678 { label: "Spend", hint: `${membership.slug} · Budgets and receipts`, to: `/${membership.slug}/-/spend`, icon: <Coins size={15} /> },
New workspaces are told to connect a model, before anything fails1679 { 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 tokens1680 { 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 page1681 { label: "Billing and plans", hint: `${membership.slug} · Settings`, to: `/${membership.slug}/-/billing`, icon: <CreditCard size={15} /> },
New workspaces are told to connect a model, before anything fails1682 { 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 look1683 { label: "Integrations", hint: membership.slug, to: `/${membership.slug}/-/integrations`, icon: <Plug size={15} /> },
New workspaces are told to connect a model, before anything fails1684 );
1685 }
1686 for (const listed of shell.repos) {
1687 commands.push({
Projects: what a workspace builds and runs, first on every page1688 label: listed.title ?? listed.name,
1689 hint: `${listed.namespace} · Project`,
New workspaces are told to connect a model, before anything fails1690 to: `/${listed.namespace}/${listed.name}`,
Projects: what a workspace builds and runs, first on every page1691 icon: <Box size={15} />,
New workspaces are told to connect a model, before anything fails1692 });
1693 }
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step1694 // "Put an agent on …": one per project, after the projects themselves.
1695 for (const listed of shell.repos) {
1696 if (repo && listed.namespace === repo.namespace && listed.name === repo.name) continue;
1697 commands.push({
1698 label: `Put an agent on ${listed.title ?? listed.name}`,
1699 hint: `${listed.namespace}/${listed.name}`,
1700 to: `/${listed.namespace}/${listed.name}/issues/new?agent=1`,
1701 icon: <Sparkles size={15} />,
1702 });
1703 }
New workspaces are told to connect a model, before anything fails1704 return commands;
1705}
1706
1707/**
Merge branch 'worktree-agent-aca4790ea223aa235'1708 * The page while the next one loads: after a moment it dims, under the
1709 * bar below, so it is plainly on its way out rather than frozen, and the
1710 * next page fades up from there. Sending a form does not dim it: the
1711 * form's button says it is working. Spread on the element holding the page.
1712 */
1713export function useLeaving() {
1714 const navigation = useNavigation();
1715 const method = navigation.formMethod?.toUpperCase();
1716 const leaving = navigation.state === "loading" && (method == null || method === "GET");
1717 return {
1718 "aria-busy": leaving || undefined,
1719 className: `transition-opacity motion-reduce:transition-none ${leaving ? "opacity-60 delay-200 duration-300" : "duration-150"}`,
1720 };
1721}
1722
1723/**
New workspaces are told to connect a model, before anything fails1724 * A bar across the top of the page while the next one loads, as GitHub
1725 * has: it appears at once, creeps towards the end while waiting, then fills
1726 * and fades when the page arrives.
1727 */
1728export function Progress() {
1729 const navigation = useNavigation();
1730 const busy = navigation.state !== "idle";
1731 const [width, setWidth] = useState(0);
1732 const [visible, setVisible] = useState(false);
1733 useEffect(() => {
1734 if (busy) {
1735 setVisible(true);
1736 setWidth(12);
1737 // Slows as it goes, never quite arriving until the page does.
1738 const timer = setInterval(() => setWidth((now) => now + (90 - now) * 0.12), 200);
1739 return () => clearInterval(timer);
1740 }
1741 setWidth((now) => (now > 0 ? 100 : 0));
1742 const fade = setTimeout(() => setVisible(false), 250);
1743 const reset = setTimeout(() => setWidth(0), 550);
1744 return () => {
1745 clearTimeout(fade);
1746 clearTimeout(reset);
1747 };
1748 }, [busy]);
1749 return (
1750 <div
1751 aria-hidden="true"
1752 className={`pointer-events-none fixed inset-x-0 top-0 z-[60] h-[3px] transition-opacity duration-300 ${
1753 visible ? "opacity-100" : "opacity-0"
1754 }`}
1755 >
1756 <div
1757 className="h-full bg-accent shadow-[0_0_10px_var(--color-accent)] transition-[width] duration-200 ease-out"
1758 style={{ width: `${width}%` }}
1759 />
1760 </div>
1761 );
1762}
1763
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.1764/**
1765 * The top bar's way to g1t: the direct message with the workspace's
1766 * orchestrator, opened or made. The one tinted control in the bar: the
1767 * lavender pixel 1 bare beside its words, on a wash of the accent.
1768 */
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)1769function AskG1tButton({ slug }: { slug: string }) {
1770 return (
1771 <Hint label="Ask g1t">
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.1772 <Button asChild variant="soft" size="bar" className="gap-2 max-md:ring-0 lg:px-3">
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.1773 <Link to={`/${slug}/-/chat?agent=g1t`} aria-label="Ask g1t">
1774 <MarkGlyph className="h-3.5" />
1775 <span className="max-lg:hidden">Ask g1t</span>
1776 </Link>
1777 </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)1778 </Hint>
1779 );
1780}
1781
New workspaces are told to connect a model, before anything fails1782/**
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.1783 * 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.1784 * Apps are pages at full width, and so are g1t's public pages, such as a
1785 * profile, which are no workspace's. Without a workspace, only your own
1786 * settings and Notifications have one.
Chat and workspace agents: channels, DMs and named agents you talk to1787 */
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.1788function sidebarFor(mode: ModeKey, workspace: boolean): Panel | null {
1789 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.1790 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)1791 return mode;
Chat and workspace agents: channels, DMs and named agents you talk to1792}
1793
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.1794/** The sidebars that sit beside the page, one per mode that has one. */
1795type 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)1796
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.1797/** 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 bar1798const MODE_MENU: Record<Panel, string> = {
1799 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.1800 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 bar1801 agents: "Agents",
1802 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.1803 notifications: "Notifications",
1804 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 bar1805 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.1806 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 bar1807};
1808
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.1809/** Whether a key press happened in something you type into, where Ctrl B is the editor's. */
1810function typing(target: EventTarget | null): boolean {
1811 if (!(target instanceof HTMLElement)) return false;
1812 return target.isContentEditable || target.closest("input, textarea, select, [contenteditable=''], [contenteditable='true'], [role='textbox']") != null;
1813}
1814
1815/** Ctrl B (⌘B on a Mac) shows or hides the sidebar, except while typing. */
1816function useSidebarShortcut(toggle: () => void) {
1817 useEffect(() => {
1818 const onKey = (event: KeyboardEvent) => {
1819 if (event.key.toLowerCase() !== "b" || event.altKey || event.shiftKey || !(event.ctrlKey || event.metaKey)) return;
1820 if (event.defaultPrevented || typing(event.target)) return;
1821 event.preventDefault();
1822 toggle();
1823 };
1824 window.addEventListener("keydown", onKey);
1825 return () => window.removeEventListener("keydown", onKey);
1826 }, [toggle]);
1827}
1828
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.1829/**
1830 * Search or jump to: the command palette. On a computer it looks like the
1831 * field it opens, with its shortcut; on a phone, a magnifier.
1832 */
1833function SearchButton({ onClick }: { onClick: () => void }) {
1834 return (
1835 <>
1836 <Button variant="ghost" size="icon-bar" aria-label="Search or jump to" onClick={onClick} className="md:hidden">
1837 <Search size={18} />
1838 </Button>
1839 <Button
1840 variant="outline"
1841 size="sm"
1842 aria-label="Search or jump to"
1843 onClick={onClick}
1844 className="mr-1 w-[min(18rem,26vw)] justify-start bg-surface font-normal text-faint hover:bg-surface hover:text-muted max-md:hidden"
1845 >
1846 <Search size={15} />
1847 <span className="grow truncate text-left">Search or jump to</span>
1848 <PaletteKey className="rounded border border-line bg-bg px-1.5 font-mono text-[0.625rem] leading-4 text-muted" />
1849 </Button>
1850 </>
1851 );
1852}
1853
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.1854/** The button that shows or hides the sidebar. */
1855function SidebarToggle({ onClick, open, className = "" }: { onClick: () => void; open: boolean; className?: string }) {
1856 const key = sidebarKeyLabel(typeof navigator === "undefined" ? null : navigator.platform);
1857 return (
1858 <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.1859 <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.1860 <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.1861 </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.1862 </Hint>
1863 );
1864}
1865
Chat and workspace agents: channels, DMs and named agents you talk to1866/**
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.1867 * 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.1868 * together. The dock, a floating bar of apps down the left; the mode's
1869 * sidebar, flat on the background beside it, which folds away with Ctrl B
1870 * and is a drawer below 1024px; and the page, a rounded panel inset from
1871 * the window, with its header across the top: the sidebar's toggle, where
1872 * you are, search, Ask g1t and Create new. On a phone the dock is a bar
1873 * along the bottom. Only for someone signed in; without a workspace yet,
1874 * there is no dock.
New workspaces are told to connect a model, before anything fails1875 */
1876export function AppShell({
1877 user,
1878 shell,
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1879 missing = false,
New workspaces are told to connect a model, before anything fails1880 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.1881 sidebarClosed = false,
New workspaces are told to connect a model, before anything fails1882 children,
1883}: {
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.1884 user: User;
New workspaces are told to connect a model, before anything fails1885 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.1886 /** 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 quotas1887 missing?: boolean;
New workspaces are told to connect a model, before anything fails1888 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.1889 /** Whether the person folded the sidebar away, as their cookie says. */
1890 sidebarClosed?: boolean;
New workspaces are told to connect a model, before anything fails1891 children: ReactNode;
1892}) {
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.1893 const { pathname } = useLocation();
New workspaces are told to connect a model, before anything fails1894 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.1895 const [closed, setClosed] = useState(sidebarClosed);
New workspaces are told to connect a model, before anything fails1896 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.1897 const commands = useMemo(() => commandsFor(user, shell), [user, shell]);
New workspaces are told to connect a model, before anything fails1898
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.1899 // A new page closes the drawer.
New workspaces are told to connect a model, before anything fails1900 useEffect(() => setDrawer(false), [pathname]);
Search across all of g1t, Explore, and a command palette1901 usePaletteShortcut(() => setPalette((open) => !open));
Merge branch 'worktree-agent-aca4790ea223aa235'1902 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)1903 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.1904 // Whether the page has scrolled under the top bar, which then draws its line (see data-page-head).
1905 const [scrolled, setScrolled] = useState(false);
1906 useEffect(() => {
1907 const onScroll = () => setScrolled(window.scrollY > 2);
1908 onScroll();
1909 window.addEventListener("scroll", onScroll, { passive: true });
1910 return () => window.removeEventListener("scroll", onScroll);
1911 }, []);
New workspaces are told to connect a model, before anything fails1912
Chat and workspace agents: channels, DMs and named agents you talk to1913 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.1914 const ws = shell.workspace;
1915 const mode = modeOf(going ?? pathname, ws?.slug ?? null);
1916 const panel = sidebarFor(mode, ws != null);
1917 const code = ws ? hasCodeAccess(ws) : false;
Chat and workspace agents: channels, DMs and named agents you talk to1918 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)1919 // Notify: the feed socket's live counts (lib/notify-client.ts) once it has them; the page's until then.
1920 const live = useLiveBadges(ws?.slug);
1921 const chatUnread = chatSidebar
1922 ? unreadTotals(chatSidebar.entries)
1923 : live?.chat != null
1924 ? { unread: live.chat, mentions: live.mentions ?? 0 }
1925 : (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.1926 const notificationsUnread = live?.inbox ?? shell.inbox?.unread ?? 0;
1927 const unread = { notifications: notificationsUnread, chat: chatUnread.unread, mentions: chatUnread.mentions };
1928
1929 // Folding the sidebar away on a computer is remembered, so the next page is drawn the same from the server.
1930 const toggleSidebar = useCallback(() => {
1931 if (!window.matchMedia("(min-width: 1024px)").matches) {
1932 setDrawer((open) => !open);
1933 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)1934 }
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.1935 setClosed((was) => {
1936 document.cookie = sidebarCookie(!was, window.location.protocol === "https:");
1937 return !was;
1938 });
1939 }, []);
1940 useSidebarShortcut(useCallback(() => {
1941 if (panel) toggleSidebar();
1942 }, [panel, toggleSidebar]));
1943
1944 const inline = panel != null && !closed;
1945 const sidebarNode = () => {
1946 if (!panel) return null;
1947 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)1948 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.1949 case "code":
1950 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)1951 case "chat":
1952 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.1953 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.1954 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)1955 case "agents":
1956 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.1957 case "notifications":
1958 return <NotificationsSidebar counts={shell.inbox ?? null} />;
1959 case "people":
1960 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)1961 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.1962 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)1963 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.1964 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)1965 }
1966 };
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.1967 // The sidebar's top row: the workspace and its switcher, and the way to fold the sidebar or close the drawer.
1968 const sidebarTop = (inDrawer: boolean) => (
1969 <div className="flex h-14 shrink-0 items-center gap-1 pr-1 pl-1">
1970 {ws ? (
1971 <WorkspaceSwitcher user={user} workspace={ws} />
1972 ) : (
1973 <Link to="/" aria-label="g1t" className="mr-auto flex h-9 items-center rounded-md px-2">
1974 <Logo className="text-[1.125rem]" />
1975 </Link>
1976 )}
1977 {inDrawer ? (
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.1978 <Button type="button" aria-label="Close menu" onClick={() => setDrawer(false)} variant="ghost" size="icon-sm" className="text-faint">
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.1979 <X size={16} />
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.1980 </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.1981 ) : (
1982 <SidebarToggle open onClick={toggleSidebar} />
1983 )}
1984 </div>
1985 );
1986
1987 // 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)1988 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.1989 // Where the page panel starts: 8px past the dock (88px), or right after the sidebar (260px) when it is open.
1990 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";
1991 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 to1992
New workspaces are told to connect a model, before anything fails1993 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.1994 // The drawer is a sheet: a dialog that holds focus, closes on Escape or
1995 // a tap outside, and gives focus back to the button that opened it.
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1996 <Sheet open={drawer} onOpenChange={setDrawer}>
New workspaces are told to connect a model, before anything fails1997 <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.1998 {ws && (
1999 <div className="fixed top-2 bottom-2 left-2 z-40 hidden w-20 md:block">
2000 <Dock
2001 workspace={ws}
2002 pins={shell.pins ?? []}
2003 unread={unread}
2004 account={<AccountMenu user={user} />}
2005 />
2006 </div>
2007 )}
2008 {panel && (
2009 <aside
2010 aria-label={`${MODE_MENU[panel]} sidebar`}
2011 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" : ""}`}
2012 >
2013 {sidebarTop(false)}
2014 <div className="min-h-0 grow">{sidebarNode()}</div>
2015 </aside>
2016 )}
Chat and workspace agents: channels, DMs and named agents you talk to2017 <SheetContent
2018 side="left"
2019 showClose={false}
2020 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.2021 // 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)2022 onOpenAutoFocus={(event) => {
2023 event.preventDefault();
2024 (event.currentTarget as HTMLElement | null)?.focus();
2025 }}
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.2026 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 to2027 >
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.2028 <SheetTitle className="sr-only">{panel ? `${MODE_MENU[panel]} menu` : "Menu"}</SheetTitle>
2029 {sidebarTop(true)}
2030 <div className="min-h-0 grow">{sidebarNode()}</div>
Usage, Billing settings and prepaid AI credit; fixes from the UX audit2031 </SheetContent>
New workspaces are told to connect a model, before anything fails2032
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.2033 <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.2034 {/* A page whose own header sits right under this bar (data-page-head: a conversation's, a project's) reads as one
2035 block with it: no line between them until the page scrolls under the bar. A sticky one (data-page-head="sticky",
2036 an open artifact's) stays under the bar, so the line is always its. */}
2037 <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.2038 <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.2039 data-scrolled={scrolled || undefined}
2040 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" : ""}`}
New workspaces are told to connect a model, before anything fails2041 >
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.2042 {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.2043 <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.2044 )}
2045 {ws && (
2046 <span className={`flex min-w-0 shrink items-center gap-1.5 ${inline ? "lg:hidden" : ""}`}>
2047 <WorkspaceSwitcher user={user} workspace={ws} compact />
2048 <span aria-hidden="true" className="text-line-strong">
2049 /
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)2050 </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.2051 </span>
Inbox: a bell in the top bar opens it beside the page, and /inbox holds it all2052 )}
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.2053 <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.2054 {/* Search, then what's yours (spend, Ask g1t), then the bell and Create new: one height, one rhythm. */}
2055 <div className="ml-auto flex shrink-0 items-center gap-1 md:gap-1.5">
2056 <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.2057 {/* Your spend this month, or the workspace's for owners and billing managers; on a phone it is on Spend. */}
2058 {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.2059 <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.2060 <SpendPill slug={ws.slug} mayWorkspace={ws.role === "owner" || !!ws.org_roles?.includes("billing_manager")} />
2061 </span>
2062 )}
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.2063 {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.2064 <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.2065 {/* 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.2066 <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.2067 <NotificationsBell counts={shell.inbox ? { ...shell.inbox, unread: notificationsUnread } : null} />
2068 </span>
2069 <CreateMenu shell={shell} />
2070 {/* Without a workspace there is no dock: the account is here. */}
2071 {!ws && <AccountMenu user={user} side="bottom" />}
2072 </div>
2073 </header>
2074 {banner}
2075 <main id="content" tabIndex={-1} {...leaving} className={`min-w-0 grow outline-none ${leaving.className}`}>
2076 <InMain.Provider value={true}>{children}</InMain.Provider>
2077 </main>
2078 </div>
New workspaces are told to connect a model, before anything fails2079 </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.2080 {/* The panel's edge: a rounded frame over the page, with the background beyond it, so what scrolls stays inside.
2081 Every page has it, a conversation too; only a phone's conversation, full screen over everything, goes without. */}
2082 <div
2083 aria-hidden="true"
2084 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" : ""}`}
2085 />
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.2086 {ws && <BottomBar user={user} workspace={ws} pins={shell.pins ?? []} unread={unread} onReselect={panel ? () => setDrawer(true) : undefined} />}
2087 <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 audit2088 </Sheet>
New workspaces are told to connect a model, before anything fails2089 );
2090}
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.2091
2092/** Create new: a project, an issue in the one you are in, a workspace or a team. */
2093function CreateMenu({ shell }: { shell: ShellData }) {
2094 return (
2095 <DropdownMenu>
2096 <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.2097 <DropdownMenuTrigger asChild>
2098 <Button variant="ghost" size="bar" aria-label="Create new" className="gap-0.5 px-1.5 text-fg/90">
2099 <Plus size={17} className="max-md:size-5" />
2100 <ChevronDown size={12} className="text-faint max-md:hidden" />
2101 </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.2102 </DropdownMenuTrigger>
2103 </Hint>
2104 <DropdownMenuContent align="end" className="min-w-52">
2105 {shell.repo && (
2106 <>
2107 <DropdownMenuLabel className="truncate">In {shell.repo.name}</DropdownMenuLabel>
2108 <DropdownMenuItem asChild>
2109 <Link to={`/${shell.repo.namespace}/${shell.repo.name}/issues/new`}>
2110 <CircleDot />
2111 New issue
2112 </Link>
2113 </DropdownMenuItem>
2114 {shell.repo.member && (
2115 <DropdownMenuItem asChild>
2116 <Link to={`/${shell.repo.namespace}/${shell.repo.name}/plans`}>
2117 <ListTree />
2118 Plan work
2119 </Link>
2120 </DropdownMenuItem>
2121 )}
2122 <DropdownMenuSeparator />
2123 </>
2124 )}
2125 <DropdownMenuItem asChild>
2126 <Link to="/?agent=new">
2127 <Sparkles />
2128 Put an agent on it
2129 </Link>
2130 </DropdownMenuItem>
2131 <DropdownMenuItem asChild>
2132 <Link to="/new">
2133 <Box />
2134 New project
2135 </Link>
2136 </DropdownMenuItem>
2137 <DropdownMenuItem asChild>
2138 <Link to="/new/github">
2139 <GitBranch />
2140 Import from GitHub
2141 </Link>
2142 </DropdownMenuItem>
2143 <DropdownMenuSeparator />
2144 <DropdownMenuItem asChild>
2145 <Link to="/workspaces/new">
2146 <Users />
2147 New workspace
2148 </Link>
2149 </DropdownMenuItem>
2150 {/* A team in the workspace you are in, for whoever it lets create one. */}
2151 {shell.workspace &&
2152 (mayCreateTeams(shell.workspace.team_creation, shell.workspace.role) ? (
2153 <DropdownMenuItem asChild>
2154 <Link to={`/${shell.workspace.slug}/-/teams/new`}>
2155 <UsersRound />
2156 New team
2157 </Link>
2158 </DropdownMenuItem>
2159 ) : (
2160 <DropdownMenuItem disabled>
2161 <UsersRound />
2162 New team
2163 <span className="ml-auto pl-3 text-xs text-faint">Owners only</span>
2164 </DropdownMenuItem>
2165 ))}
2166 </DropdownMenuContent>
2167 </DropdownMenu>
2168 );
2169}

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