Skip to content
2,060 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.

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.1import { Activity, BarChart3, Building2, MessagesSquare, Bell, BookMarked, BookOpen, Bookmark, Blocks, Bot, Box, Check, ChevronDown, ChevronLeft, ChevronRight, CircleDot, GripVertical, CircleUserRound, Code2, 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, Sun, Ticket, TrendingUp, UserRoundKey, Users, UsersRound, Webhook, X, ArrowLeftRight } from "lucide-react";
2import { 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";
Docs: automations4
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";
Docs: automations6
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";
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar10import { PinButton } from "./pin-button";
Merge branch 'worktree-agent-ae1299e92e4462012'11import { 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.12import { Sheet, SheetContent, SheetTitle } from "./ui/sheet";
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas13import { StatusDot, useSiteStatus } from "./footer";
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.14import { Logo } from "./logo";
Usage, Billing settings and prepaid AI credit; fixes from the UX audit15import { Avatar, SoonPill } from "./ui";
Fast pages, required checks on the branch, self-hosted runners, honest incidents16import { Skeleton } from "./ui/skeleton";
Docs: automations17import {
18 DropdownMenu,
19 DropdownMenuContent,
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas20 DropdownMenuGroup,
Docs: automations21 DropdownMenuItem,
22 DropdownMenuLabel,
23 DropdownMenuSeparator,
24 DropdownMenuTrigger,
25} from "./ui/dropdown-menu";
Merge branch 'worktree-agent-ad7c6d88d93adc817'26import { type RoadmapItem, roadmapIn, roadmapItem } from "../lib/roadmap";
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.27import { type ModeKey, SETTINGS_PAGES, modeOf, todayPath } from "../lib/workspace-nav";
Chat and workspace agents: channels, DMs and named agents you talk to28import { AgentsSidebar } from "./agents-mode";
29import { 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.30import { 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.31import { Dock, ShortcutsDialog, WorkspaceSwitcher, sidebarKeyLabel } from "./dock";
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)32import { G1tMark } from "./orchestrator";
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.33import { BottomBar, isConversation, useVisualViewport } from "./mobile";
Chat and workspace agents: channels, DMs and named agents you talk to34import { useChatSidebar } from "./chat/actions";
35import { unreadTotals } from "../lib/chat";
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look36import { 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.37import { projectPages } from "../lib/chrome";
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas38import { 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.39import { type PinnableApp, sidebarCookie } from "../lib/apps";
40import { 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 quotas41import { 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.42import { useInviteOnly } from "../lib/registration";
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas43import { STATUS_URL, statusTitle } from "../lib/status";
Navigation: the workspace's own page with tabs, pins and recent in the sidebar44import { 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 quotas45import 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)46import { 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 managers47import { 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.48import { THEME_COMMANDS, ThemeMenuSwitch } from "./theme-switch";
Docs: automations49
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put50/**
51 * What the sidebar needs, worked out by the root loader. For a visitor who
52 * is not signed in there is no workspace, no projects and no usage: only
53 * the project being looked at, if they can see it.
54 */
Docs: automations55export type ShellData = {
56 /** The workspace the sidebar is about: the one being looked at, or their first. */
Workspace names and icons, and a component kit for every control57 workspace: Membership | null;
Navigation: the workspace's own page with tabs, pins and recent in the sidebar58 /** All its projects, by name, for the palette: `name` is the slug in their address. */
59 repos: ShortcutProject[];
60 /** The person's pinned projects in it, in their order (lib/pins.ts). */
61 pinned?: ShortcutProject[];
62 /** What they opened there last, latest first, leaving out the pinned. */
63 recent?: ShortcutProject[];
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look64 /** Repositories shared with them in workspaces they do not belong to. */
65 shared?: { namespace: string; name: string; isPrivate: boolean }[];
Projects: what a workspace builds and runs, first on every page66 /** The project being looked at, if any, whoever owns it. */
Docs: automations67 repo: {
68 namespace: string;
69 name: string;
70 member: boolean;
71 issues: number;
72 pulls: number;
73 } | null;
Billing accounts, terms and enterprises; g1t is no longer free74 /** Where the workspace stands against its usage limit, if billing is on. */
75 limit: {
76 exposureMicros: number;
77 ceilingMicros: number | null;
78 state: "ok" | "warning" | "stopped";
79 comped: boolean;
80 } | null;
Free while g1t is being built out; agents can check out their own forks81 /** Whether g1t charges nothing for now, while it is being built out. */
82 free?: boolean;
Docs: automations83 /** What its agents have cost since the start of the month. */
Usage while free is shown at cost; agents get rustfmt and clippy84 /** This month's usage: charged, or at cost while g1t is free. */
85 monthUsageMicros: number | null;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look86 /** Whether new compute is paused (a spend spike or a hold), and whether the viewer can answer it. */
87 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.88 /** 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 all89 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)90 /**
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.91 * 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)92 * starred and latest conversations. Null when chat did not answer in time.
93 */
94 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.95 /** 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)96 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.97 /** The apps this person pinned to their dock in the workspace (lib/apps.ts). */
98 pins?: PinnableApp[];
Docs: automations99};
100
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)101/** An agent as the shell lists it. */
102export type ShellAgent = Pick<
103 WorkspaceAgent,
104 "id" | "handle" | "display_name" | "avatar" | "avatar_seed" | "role" | "status" | "title" | "team" | "department" | "builtin"
105>;
106
Docs: automations107function SidebarLink({
108 to,
109 icon,
110 end,
111 count,
112 also,
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look113 drill,
Merge branch 'worktree-agent-ad7c6d88d93adc817'114 current: lit,
Docs: automations115 children,
116}: {
117 to: string;
118 icon: ReactNode;
119 end?: boolean;
120 count?: number;
Projects: what a workspace builds and runs, first on every page121 /** Other path prefixes under which this link is the current one. */
122 also?: string | string[];
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look123 /** It opens a list of its own: a chevron says so, always or on hover. */
124 drill?: boolean | "hover";
Merge branch 'worktree-agent-ad7c6d88d93adc817'125 /** Whether it is the current row, when the list works that out itself. */
126 current?: boolean;
Docs: automations127 children: ReactNode;
128}) {
129 const { pathname } = useLocation();
130 return (
131 <NavLink
132 to={to}
133 end={end}
134 prefetch="intent"
135 className={({ isActive, isPending }) => {
Projects: what a workspace builds and runs, first on every page136 const current =
Merge branch 'worktree-agent-ad7c6d88d93adc817'137 lit ??
138 (isActive || [also ?? []].flat().some((prefix) => pathname === prefix || pathname.startsWith(prefix + "/")));
Docs: automations139 return `group flex h-8 items-center gap-2.5 rounded-md px-2 text-[0.8125rem] transition-colors ${
140 current
141 ? "bg-raised font-medium text-fg"
142 : isPending
143 ? "bg-raised/60 text-fg"
144 : "text-muted hover:bg-raised/60 hover:text-fg"
145 }`;
146 }}
147 >
148 <span className="shrink-0 text-faint group-hover:text-muted">{icon}</span>
149 <span className="min-w-0 grow truncate">{children}</span>
150 {count != null && count > 0 && (
151 <span className="rounded bg-line px-1.5 text-[0.6875rem] tabular-nums text-muted">
152 {count}
153 </span>
154 )}
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look155 {drill && (
156 <ChevronRight
157 size={14}
158 aria-hidden="true"
159 className={`-mr-0.5 shrink-0 text-faint transition-opacity ${drill === "hover" ? "opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100" : ""}`}
160 />
161 )}
Docs: automations162 </NavLink>
163 );
164}
165
Pull requests say where they are live; the project menu shows what is coming166/**
167 * Something a project will have, shown where it will live so people can
168 * see where g1t is going. Not a link: nothing is behind it yet.
169 */
170function SidebarSoon({ icon, children, about }: { icon: ReactNode; children: ReactNode; about: string }) {
171 return (
Merge branch 'worktree-agent-ae1299e92e4462012'172 <Hint label={about} side="right">
173 <div aria-disabled="true" className="flex h-8 cursor-default items-center gap-2.5 rounded-md px-2 text-[0.8125rem] text-faint">
174 <span className="shrink-0 opacity-70">{icon}</span>
175 <span className="grow truncate">{children}</span>
176 <span className="sr-only">{about}</span>
177 <SoonPill />
178 </div>
179 </Hint>
Pull requests say where they are live; the project menu shows what is coming180 );
181}
182
The project menu opens by section, and the workspace has its own panel183/**
A flat project menu with Code first, views as tabs, and Stripe for every owner184 * A page that is coming, as a link to its roadmap page: faint, with Soon,
185 * and marked current on any of its section's Soon pages.
The project menu opens by section, and the workspace has its own panel186 */
A flat project menu with Code first, views as tabs, and Stripe for every owner187function SidebarSoonLink({
The project menu opens by section, and the workspace has its own panel188 to,
189 also,
A flat project menu with Code first, views as tabs, and Stripe for every owner190 icon,
191 about,
Merge branch 'worktree-agent-ad7c6d88d93adc817'192 current: lit,
The project menu opens by section, and the workspace has its own panel193 children,
194}: {
195 to: string;
A flat project menu with Code first, views as tabs, and Stripe for every owner196 also?: string[];
197 icon: ReactNode;
198 about: string;
Merge branch 'worktree-agent-ad7c6d88d93adc817'199 /** Whether it is the current row, when the list works that out itself. */
200 current?: boolean;
The project menu opens by section, and the workspace has its own panel201 children: ReactNode;
202}) {
203 const { pathname } = useLocation();
204 return (
Sidebar: soon rows and the project row keep their styles inside a hint; tiny amounts read as zero205 // The hint wraps a plain box: Radix's asChild merges className as a
206 // string, which would break NavLink's className function.
Merge branch 'worktree-agent-ae1299e92e4462012'207 <Hint label={about} side="right">
Sidebar: soon rows and the project row keep their styles inside a hint; tiny amounts read as zero208 <div>
The project menu opens by section, and the workspace has its own panel209 <NavLink
210 to={to}
211 prefetch="intent"
A flat project menu with Code first, views as tabs, and Stripe for every owner212 className={({ isActive }) => {
Merge branch 'worktree-agent-ad7c6d88d93adc817'213 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 owner214 return `group flex h-8 items-center gap-2.5 rounded-md px-2 text-[0.8125rem] transition-colors ${
215 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 panel216 }`;
217 }}
218 >
A flat project menu with Code first, views as tabs, and Stripe for every owner219 <span className="shrink-0 opacity-80">{icon}</span>
The project menu opens by section, and the workspace has its own panel220 <span className="min-w-0 grow truncate">{children}</span>
Usage, Billing settings and prepaid AI credit; fixes from the UX audit221 <SoonPill />
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales222 </NavLink>
Sidebar: soon rows and the project row keep their styles inside a hint; tiny amounts read as zero223 </div>
Merge branch 'worktree-agent-ae1299e92e4462012'224 </Hint>
The project menu opens by section, and the workspace has its own panel225 );
226}
227
A flat project menu with Code first, views as tabs, and Stripe for every owner228/** Icons for what spans projects. */
229const WORKSPACE_ICONS: Record<string, ReactNode> = {
230 board: <KanbanSquare size={15} />,
231 roadmap: <GanttChart size={15} />,
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member232 teams: <UsersRound size={15} />,
A flat project menu with Code first, views as tabs, and Stripe for every owner233 packages: <Package size={15} />,
234 fleet: <Bot size={15} />,
235};
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales236
A flat project menu with Code first, views as tabs, and Stripe for every owner237/** The Soon pages of a section, as paths, so its link is current on them. */
238function soonPaths(base: string, section: RoadmapItem["section"]): string[] {
239 return roadmapIn(section).map((item) => `${base}/soon/${item.key}`);
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales240}
241
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look242function SidebarGroup({
243 title,
244 action,
245 className = "",
246 children,
247}: {
248 title: string;
249 action?: ReactNode;
250 className?: string;
251 children: ReactNode;
252}) {
Docs: automations253 return (
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look254 <section className={className}>
Docs: automations255 <div className="mb-1 flex h-6 items-center justify-between px-2">
256 <h2 className="text-xs font-medium text-faint">{title}</h2>
257 {action}
258 </div>
259 <div className="space-y-px">{children}</div>
260 </section>
261 );
262}
263
Workspace names and icons, and a component kit for every control264/** What a workspace is called where people read it: its display name, else its slug. */
265function displayName(membership: Membership): string {
266 return membership.name?.trim() || membership.slug;
Docs: automations267}
268
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas269/**
270 * The fine print, as one quiet row at the foot of the account menu and the
271 * visitor's panel: each link a full-height target, left-aligned. In the
272 * menu each is a menu item, so the arrow keys reach it.
273 */
274const LEGAL_LINKS: [string, string][] = [
275 ["Policies", "/policies"],
276 ["Privacy", "/policies/privacy"],
277 ["Security", "/security"],
278];
279const LEGAL_LINK = "flex h-7 items-center rounded px-1.5 text-xs text-faint outline-none transition-colors";
280
281function MenuLegalRow() {
282 return (
283 <div role="group" aria-label="Legal" className="flex items-center gap-0.5 px-0.5 pt-0.5">
284 {LEGAL_LINKS.map(([label, to], index) => (
285 <span key={to} className="flex items-center gap-0.5">
286 {index > 0 && (
287 <span aria-hidden="true" className="text-[0.625rem] text-line-strong">
288 ·
289 </span>
290 )}
291 <DropdownMenuItem asChild className={`${LEGAL_LINK} py-0 data-highlighted:bg-line data-highlighted:text-fg`}>
292 <Link to={to}>{label}</Link>
293 </DropdownMenuItem>
294 </span>
295 ))}
296 </div>
297 );
298}
299
300/** Status's row: the live dot and two or three words, fetched when the menu opens. */
301function StatusSummary({ open }: { open: boolean }) {
302 const status = useSiteStatus(open);
303 const words = statusTitle(status);
304 return (
305 <span className="ml-auto flex min-w-0 items-center gap-1.5 pl-2 text-xs text-faint">
306 {/* The words say it; the dot's own words for screen readers would repeat them. */}
307 <span aria-hidden="true" className="flex">
308 <StatusDot state={status?.overall.state ?? null} />
309 </span>
Fast pages, required checks on the branch, self-hosted runners, honest incidents310 {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 quotas311 </span>
312 );
313}
314
315/** A menu row: an icon, words, and whatever sits at its end. */
316const MENU_ROW = "h-9 gap-2.5 px-2.5 text-[0.8125rem]";
317
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.318/**
319 * Your account, at the foot of the dock (or in the header, before you have
320 * a workspace): who you are and your status, your profile and settings,
321 * and help: the documentation, support, status and the keyboard's
322 * shortcuts; then signing out and the fine print.
323 */
324function AccountMenu({ user, side = "right" }: { user: User; side?: "right" | "bottom" }) {
Docs: automations325 const submit = useSubmit();
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas326 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.327 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 managers328 // Your status's dialog: outside the menu, so the menu closes behind it.
329 const [editing, setEditing] = useState(false);
Fast pages, required checks on the branch, self-hosted runners, honest incidents330 // Name, primary address and invites left: asked for once, as soon as the
331 // 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 quotas332 const details = useFetcher<AccountMenuData | null>({ key: "account-menu" });
Fast pages, required checks on the branch, self-hosted runners, honest incidents333 const prefetch = () => {
334 if (details.state === "idle" && details.data === undefined) details.load("/settings/menu.json");
335 };
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas336 useEffect(() => {
Fast pages, required checks on the branch, self-hosted runners, honest incidents337 if (open) prefetch();
338 // eslint-disable-next-line react-hooks/exhaustive-deps
339 }, [open]);
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas340 const me = details.data ?? null;
Fast pages, required checks on the branch, self-hosted runners, honest incidents341 // Still on its way: shapes where the words will be, the same size.
342 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)343 // While anyone can sign up, listed once the data says there are invites to look back on.
344 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 quotas345 const profile = `/u/${user.username}`;
Docs: automations346 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 managers347 <>
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas348 <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.349 {/* 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 quotas350 <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 managers351 aria-label={`Account menu for ${shownUsername(user)}`}
Fast pages, required checks on the branch, self-hosted runners, honest incidents352 onPointerEnter={prefetch}
353 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.354 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 quotas355 >
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.356 <Avatar name={user.username} image={user.avatar} size={side === "right" ? 32 : 28} />
357 <OwnPresenceDot ring={side === "right" ? "var(--color-dock)" : "var(--color-bg)"} className="absolute -right-0.5 -bottom-0.5" />
Docs: automations358 </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.359 <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 quotas360 {/* Who is signed in, and a way to their profile. */}
361 <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 managers362 <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 quotas363 <Avatar name={user.username} image={user.avatar} size={36} />
Fast pages, required checks on the branch, self-hosted runners, honest incidents364 <span className="flex min-w-0 grow flex-col leading-tight" aria-busy={loading}>
365 {loading ? (
366 <Skeleton className="my-[0.1875rem] h-3.5 w-28" />
367 ) : (
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers368 <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 incidents369 )}
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers370 <span className="truncate font-mono text-xs text-muted">@{shownUsername(user)}</span>
Fast pages, required checks on the branch, self-hosted runners, honest incidents371 {loading ? (
372 <Skeleton className="mt-1 h-3 w-40" />
373 ) : (
374 me?.email && <span className="mt-0.5 truncate text-xs text-faint">{me.email}</span>
375 )}
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas376 </span>
Docs: automations377 </Link>
378 </DropdownMenuItem>
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas379 <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 managers380 {/* Your status, away, and pausing notifications. */}
381 <DropdownMenuGroup>
382 <OwnPresenceItems className="min-h-9 py-1.5 text-[0.8125rem]" onEdit={() => setEditing(true)} />
383 </DropdownMenuGroup>
384 <DropdownMenuSeparator className="my-1.5" />
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas385 <DropdownMenuGroup>
386 <DropdownMenuItem asChild className={MENU_ROW}>
387 <Link to={profile}>
388 <CircleUserRound />
389 Your profile
390 </Link>
391 </DropdownMenuItem>
392 <DropdownMenuItem asChild className={MENU_ROW}>
393 <Link to={FIRST_SETTINGS_PAGE}>
394 <Settings />
395 Your settings
396 </Link>
397 </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)398 {invitesListed && (
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas399 <DropdownMenuItem asChild className={MENU_ROW}>
400 <Link to="/settings/invites">
401 <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)402 {ACCOUNT_SETTINGS.invites.title}
Fast pages, required checks on the branch, self-hosted runners, honest incidents403 {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 quotas404 {me?.invites_left != null && (
405 <span className="ml-auto rounded-full bg-line px-1.5 text-[0.6875rem] tabular-nums text-muted">
406 {me.invites_left} left
407 </span>
408 )}
409 </Link>
410 </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)411 )}
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas412 </DropdownMenuGroup>
413 <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.414 {/* Auto, Light or Dark, switched in place (lib/theme.ts). */}
415 <ThemeMenuSwitch />
416 <DropdownMenuSeparator className="my-1.5" />
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas417 <DropdownMenuGroup>
418 <DropdownMenuItem asChild className={MENU_ROW}>
419 <a href="https://docs.g1t.sh/">
420 <BookOpen />
421 Documentation
422 </a>
423 </DropdownMenuItem>
424 <DropdownMenuItem asChild className={MENU_ROW}>
425 <Link to="/support">
426 <LifeBuoy />
427 Support
428 </Link>
429 </DropdownMenuItem>
430 <DropdownMenuItem asChild className={MENU_ROW}>
431 <a href={STATUS_URL}>
432 <Activity />
433 Status
434 <StatusSummary open={open} />
435 </a>
436 </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.437 <DropdownMenuItem className={MENU_ROW} onSelect={() => setKeys(true)}>
438 <Keyboard />
439 Keyboard shortcuts
440 <PaletteKey className="ml-auto font-sans text-xs text-faint" />
441 </DropdownMenuItem>
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas442 </DropdownMenuGroup>
443 <DropdownMenuSeparator className="my-1.5" />
Docs: automations444 {/* Submitted from here: the menu closes on select, and a button
445 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 quotas446 <DropdownMenuItem className={MENU_ROW} onSelect={() => submit(null, { method: "post", action: "/logout" })}>
Docs: automations447 <LogOut />
448 Sign out
449 </DropdownMenuItem>
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas450 <DropdownMenuSeparator className="my-1.5" />
451 <MenuLegalRow />
Docs: automations452 </DropdownMenuContent>
453 </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 managers454 <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.455 <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 managers456 </>
Docs: automations457 );
458}
459
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look460/**
Mission control counts people's own changes as theirs; a shorter sidebar with setup under Settings, and a 56px top bar461 * A workspace's settings pages, which the sidebar drills into: how it is
462 * set up and connected (guardrails, secrets, runners, integrations,
463 * webhooks), what it pays, its repositories, tokens and record. The main
464 * list keeps the places work happens and who belongs; every member can
465 * still open these.
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look466 */
Mission control counts people's own changes as theirs; a shorter sidebar with setup under Settings, and a 56px top bar467const SETTINGS_PAGE =
Merge branch 'worktree-agent-ad7c6d88d93adc817'468 new RegExp(`^/([^/]+)/-/(${SETTINGS_PAGES.join("|")})(/|$)`);
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look469/** A project's settings pages, which the project's menu drills into. */
Project settings move into the sidebar, grouped, with a heading per page470const REPO_SETTINGS_PAGE = /^\/([^/]+)\/([^/-][^/]*)\/settings(\/|$)/;
Docs: automations471
472/**
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look473 * The sidebar's lists are a stack, the way a phone pushes a screen: one
474 * drilled into slides in from the right over the full width, while the one
475 * it covers drifts a quarter of the way left and fades, both on one long
Sidebar: the panels really slide476 * ease-out, the fade quicker than the move so the two never blur together.
477 * Going back reverses it.
Docs: automations478 */
Sidebar: no settings flash on the way into a repository, and a better slide479const LAYER =
Sidebar: the panels really slide480 "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 look481/** One list, filling its layer. */
Sidebar: no settings flash on the way into a repository, and a better slide482const PANEL = "h-full overflow-y-auto px-2 pb-4";
Docs: automations483
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look484/** One list in the stack: what it is, and its rows. */
485type Level = { key: string; node: ReactNode };
486
487/** True once the page has hydrated, so what the server drew never animates in. */
488function useHydrated(): boolean {
489 const [hydrated, setHydrated] = useState(false);
490 useEffect(() => setHydrated(true), []);
491 return hydrated;
492}
493
494/**
495 * Drilling in and out of the sidebar's lists. `trail` is the way from the
496 * main list to the one shown, worked out from the address, so a link
497 * straight to a settings page opens the sidebar already drilled in, and
498 * leaving it comes back out. Lists deeper than the one shown stay in
499 * place, off to the right, so going back slides them away rather than
500 * dropping them. Moving to a list at the same depth (a workspace's settings
501 * to a project) fades the new one in where it is.
502 */
503function Drill({ trail }: { trail: Level[] }) {
504 const depth = trail.length - 1;
505 const hydrated = useHydrated();
506 const stack = useRef<Level[]>(trail);
507 const before = stack.current;
508 const within = trail.every((level, index) => before[index]?.key === level.key);
509 stack.current = within ? [...trail, ...before.slice(trail.length)] : trail;
510 const levels = stack.current;
511 // What was showing last time, to tell drilling in from moving across.
512 const shown = useRef({ depth, keys: levels.map((level) => level.key) });
513 useEffect(() => {
514 shown.current = { depth, keys: levels.map((level) => level.key) };
515 });
Docs: automations516 return (
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look517 <div className="relative min-h-0 grow overflow-hidden">
518 {levels.map((level, index) => {
519 const current = index === depth;
520 const place =
521 index < depth
522 ? "pointer-events-none -translate-x-1/4 opacity-0"
523 : current
524 ? "translate-x-0 opacity-100"
525 : "pointer-events-none translate-x-full opacity-0";
526 // A list that was not there before arrives: from the right when
527 // drilling in, in place when moving across.
528 const arriving = hydrated && current && !shown.current.keys.includes(level.key);
529 const enter = arriving
530 ? depth > shown.current.depth
531 ? "starting:translate-x-full starting:opacity-0"
532 : "starting:opacity-0"
533 : "";
534 return (
535 <div key={level.key} className={`${LAYER} ${place} ${enter}`} inert={!current} aria-hidden={!current || undefined}>
536 {level.node}
537 </div>
538 );
539 })}
540 </div>
541 );
542}
543
544/**
545 * The row at the top of a list drilled into: the list's name, which goes
546 * back out, and what it belongs to, faint at the end.
547 */
548function BackRow({ to, label, context }: { to: string; label: ReactNode; context?: ReactNode }) {
549 return (
550 <Link
551 to={to}
552 prefetch="intent"
553 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"
Docs: automations554 >
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look555 <ChevronLeft size={16} className="shrink-0 text-faint transition-transform group-hover:-translate-x-0.5 group-hover:text-muted" />
556 <span className="min-w-0 shrink-0 truncate">{label}</span>
557 {context && (
558 <span className="ml-auto min-w-0 truncate pl-2 font-mono text-[0.6875rem] font-normal text-faint">{context}</span>
559 )}
560 </Link>
561 );
562}
563
564/** A thin rule between groups of a list. */
565function Rule() {
566 return <div role="separator" className="mx-2 my-2.5 h-px bg-line" />;
567}
568
Navigation: the workspace's own page with tabs, pins and recent in the sidebar569/** A quiet heading inside a group: Pinned, Recent. */
570function SidebarSubhead({ children }: { children: ReactNode }) {
571 return <h3 className="px-2 pt-1.5 pb-0.5 text-[0.6875rem] font-medium tracking-wide text-faint">{children}</h3>;
572}
573
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look574/**
Navigation: the workspace's own page with tabs, pins and recent in the sidebar575 * The workspace's projects as the sidebar keeps them, however many there
576 * are: the person's pins in their order, what they opened last, and the
577 * way to all of them. Pins move by dragging, or with Alt and the arrow
578 * keys; the projects service keeps the order.
579 */
Merge branch 'worktree-agent-ad7c6d88d93adc817'580function SidebarProjects({ slug, shell, current }: { slug: string; shell: ShellData; current: boolean }) {
Navigation: the workspace's own page with tabs, pins and recent in the sidebar581 const reorder = useFetcher({ key: `pins:${slug}` });
582 const saved = shell.pinned ?? [];
583 // While a new order is on its way, it shows as made.
584 const asked = reorder.formData?.get("intent") === "reorder" ? reorder.formData.getAll("slug").map(String) : null;
585 const pinned = asked
586 ? asked.map((name) => saved.find((project) => project.name === name)).filter((project): project is ShortcutProject => project != null)
587 : saved;
588 const active = shell.repo ? { namespace: shell.repo.namespace, name: shell.repo.name, isPrivate: false } : null;
589 const recent = recentWith(shell.recent ?? [], pinned, active, slug);
590 const [dragging, setDragging] = useState<number | null>(null);
591 const move = (from: number, by: number) => {
592 const next = movedPin(pinned, from, by);
593 if (!next) return;
594 const form = new FormData();
595 form.set("intent", "reorder");
596 for (const project of next) form.append("slug", project.name);
597 reorder.submit(form, { method: "post", action: `/${slug}/-/pins` });
598 };
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar599 // Each row pins or unpins in place: the pin shows on hover or focus, and
600 // stays shown on a pinned row's hover so it reads as "unpin".
601 const row = (project: ShortcutProject, isPinned: boolean) => (
602 <div className="group/row relative">
603 <SidebarLink to={`/${project.namespace}/${project.name}`} icon={project.isPrivate ? <Lock size={15} /> : <Box size={15} />} drill="hover">
604 <span className="block truncate pr-6">{project.title ?? project.name}</span>
605 </SidebarLink>
606 <PinButton
607 workspace={slug}
608 slug={project.name}
609 name={project.title ?? project.name}
610 pinned={isPinned}
611 small
612 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"
613 />
614 </div>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar615 );
616 return (
617 <SidebarGroup
618 title="Projects"
619 action={
620 <Link to={`/new?workspace=${slug}`} aria-label="New project" className="rounded p-0.5 text-faint hover:bg-raised hover:text-fg">
621 <Plus size={13} />
622 </Link>
623 }
624 >
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar625 {/* Only there once something is pinned: each row below has its own pin. */}
626 {pinned.length > 0 && (
627 <>
628 <SidebarSubhead>Pinned</SidebarSubhead>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar629 <ul aria-label="Pinned projects" className="space-y-px">
630 {pinned.map((project, index) => (
631 <li
632 key={project.name}
633 draggable={pinned.length > 1}
634 onDragStart={(event) => {
635 setDragging(index);
636 event.dataTransfer.effectAllowed = "move";
637 }}
638 onDragOver={(event) => {
639 if (dragging != null) event.preventDefault();
640 }}
641 onDrop={(event) => {
642 event.preventDefault();
643 if (dragging != null && dragging !== index) move(dragging, index - dragging);
644 setDragging(null);
645 }}
646 onDragEnd={() => setDragging(null)}
647 onKeyDown={(event) => {
648 if (!event.altKey || (event.key !== "ArrowUp" && event.key !== "ArrowDown")) return;
649 event.preventDefault();
650 move(index, event.key === "ArrowUp" ? -1 : 1);
651 }}
652 className={`group/pin relative ${dragging === index ? "opacity-50" : ""}`}
653 >
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar654 {row(project, true)}
Navigation: the workspace's own page with tabs, pins and recent in the sidebar655 {pinned.length > 1 && (
Merge branch 'worktree-agent-ae1299e92e4462012'656 <Hint label="Drag, or Alt and an arrow key, to reorder" side="right">
657 <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">
658 <GripVertical size={12} aria-hidden="true" />
659 </span>
660 </Hint>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar661 )}
662 </li>
663 ))}
664 </ul>
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar665 </>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar666 )}
667 {recent.length > 0 && (
668 <>
669 <SidebarSubhead>Recent</SidebarSubhead>
670 {recent.map((project) => (
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar671 <div key={`${project.namespace}/${project.name}`}>{row(project, false)}</div>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar672 ))}
673 </>
674 )}
675 <div className="pt-1">
Merge branch 'worktree-agent-ad7c6d88d93adc817'676 <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 sidebar677 All projects
678 </SidebarLink>
679 </div>
680 </SidebarGroup>
681 );
682}
683
Merge branch 'worktree-agent-ad7c6d88d93adc817'684/** Insights, coming: the workspace's own page says what it will be. */
685const INSIGHTS = roadmapItem("insights");
686
Sidebar: no settings flash on the way into a repository, and a better slide687/**
688 * What the repository menu needs. Known from the address before the page's
689 * data arrives, so the menu is right from the first frame; the counts fill
690 * in once it does.
691 */
692type MenuRepo = {
693 namespace: string;
694 name: string;
695 member: boolean;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look696 /** Whether they see its settings; from the repository's page once it loads. */
697 settings?: boolean;
698 /** What they may do there, once the repository's page loads. */
699 can?: Abilities;
Sidebar: no settings flash on the way into a repository, and a better slide700 issues?: number;
701 pulls?: number;
702};
703
704function sameRepo(a: { namespace: string; name: string } | null, b: { namespace: string; name: string } | null) {
705 return (
706 a != null &&
707 b != null &&
708 a.namespace.toLowerCase() === b.namespace.toLowerCase() &&
709 a.name.toLowerCase() === b.name.toLowerCase()
710 );
711}
A repository has its own sidebar, as settings do712
713/**
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look714 * A project's own list, drilled into while you are in it: everything about
715 * the project, running and its code, and nothing else, with the way back
716 * out to all of them.
A repository has its own sidebar, as settings do717 */
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put718function RepoMenu({
719 repo,
720 isPrivate,
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look721 back,
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put722}: {
723 repo: MenuRepo;
724 isPrivate: boolean;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look725 /** Where the way back leads: the workspace's projects, mission control, or Explore. */
726 back: { to: string; label: string };
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put727}) {
A repository has its own sidebar, as settings do728 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 put729 // 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 look730 const shows = new Set(projectPages(repo.member, repo.can));
A repository has its own sidebar, as settings do731 return (
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look732 <nav aria-label={`${repo.namespace}/${repo.name}`} className={PANEL}>
733 <BackRow to={back.to} label={back.label} />
Merge branch 'worktree-agent-ae1299e92e4462012'734 <Hint label="Overview" side="right">
Sidebar: soon rows and the project row keep their styles inside a hint; tiny amounts read as zero735 <div>
A flat project menu with Code first, views as tabs, and Stripe for every owner736 <NavLink
A repository has its own sidebar, as settings do737 to={base}
A flat project menu with Code first, views as tabs, and Stripe for every owner738 end
Fast pages, required checks on the branch, self-hosted runners, honest incidents739 prefetch="intent"
A flat project menu with Code first, views as tabs, and Stripe for every owner740 className={({ isActive }) =>
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look741 `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 owner742 }
A repository has its own sidebar, as settings do743 >
744 <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 page745 {isPrivate ? <Lock size={13} /> : <Box size={13} />}
A repository has its own sidebar, as settings do746 </span>
747 <span className="min-w-0 truncate font-mono text-[0.8125rem]">
748 <span className="text-faint">{repo.namespace}/</span>
749 <span className="font-semibold text-fg">{repo.name}</span>
750 </span>
A flat project menu with Code first, views as tabs, and Stripe for every owner751 </NavLink>
Sidebar: soon rows and the project row keep their styles inside a hint; tiny amounts read as zero752 </div>
Merge branch 'worktree-agent-ae1299e92e4462012'753 </Hint>
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look754 {/* A project's pages, in the order people use them. A page with more
755 than one view shows them as tabs across its top. */}
756 <Rule />
757 <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 request758 <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 owner759 Code
760 </SidebarLink>
Usage, Billing settings and prepaid AI credit; fixes from the UX audit761 <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 owner762 Issues
763 </SidebarLink>
764 <SidebarLink to={`${base}/pulls`} also={[`${base}/pull`, `${base}/queue`]} icon={<GitPullRequest size={15} />} count={repo.pulls}>
765 Pull requests
766 </SidebarLink>
Agents and memory, checks and conflicts, profiles, slug renames, custom domains767 <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 owner768 Agents
Agents and memory, checks and conflicts, profiles, slug renames, custom domains769 </SidebarLink>
A flat project menu with Code first, views as tabs, and Stripe for every owner770 <SidebarLink to={`${base}/actions`} icon={<PlayCircle size={15} />}>
771 Workflows
Projects: what a workspace builds and runs, first on every page772 </SidebarLink>
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look773 </div>
774 <Rule />
775 <div className="space-y-px">
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put776 {shows.has("deployments") ? (
A flat project menu with Code first, views as tabs, and Stripe for every owner777 <SidebarLink to={`${base}/deployments`} also={soonPaths(base, "Deployments")} icon={<Rocket size={15} />}>
778 Deployments
779 </SidebarLink>
780 ) : null}
Observability gets its own page; tabs never overflow781 <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.">
782 Observability
A flat project menu with Code first, views as tabs, and Stripe for every owner783 </SidebarSoonLink>
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put784 {shows.has("security") ? (
Agents get guardrails, run credentials, an audit log, a context hub, repository instructions and mentions; security upkeep; snake_case API785 <SidebarLink to={`${base}/security`} also={soonPaths(base, "Security")} icon={<ShieldCheck size={15} />}>
786 Security
787 </SidebarLink>
788 ) : null}
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97789 <SidebarLink
790 to={`${base}/contributors`}
791 also={[`${base}/activity`, `${base}/stargazers`, ...soonPaths(base, "Insights")]}
792 icon={<BarChart3 size={15} />}
793 >
A flat project menu with Code first, views as tabs, and Stripe for every owner794 Insights
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97795 </SidebarLink>
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look796 </div>
797 {(repo.settings ?? shows.has("settings")) && (
798 <>
799 <Rule />
800 <SidebarLink to={`${base}/settings`} icon={<Settings size={15} />} drill>
A flat project menu with Code first, views as tabs, and Stripe for every owner801 Settings
802 </SidebarLink>
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look803 </>
804 )}
A repository has its own sidebar, as settings do805 </nav>
806 );
807}
808
Project settings move into the sidebar, grouped, with a heading per page809/**
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look810 * A project's settings, drilled into from its list: what is about running
811 * it, then its agents, then its code and who can reach it. The way back
812 * leads to the project.
Project settings move into the sidebar, grouped, with a heading per page813 */
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look814function RepoSettingsMenu({ repo }: { repo: MenuRepo }) {
Project settings move into the sidebar, grouped, with a heading per page815 const base = `/${repo.namespace}/${repo.name}`;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look816 // Each page shows to the roles that can use it, once the role is known.
817 const shows = (page: string) => !repo.can || repo.can[SETTINGS_CAPABILITY[page] ?? "administer"];
818 const running = shows("deployments");
819 const agents = shows("agents") || shows("guardrails");
Project settings move into the sidebar, grouped, with a heading per page820 return (
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look821 <nav aria-label={`${repo.namespace}/${repo.name} settings`} className={PANEL}>
822 <BackRow to={base} label="Settings" context={`${repo.namespace}/${repo.name}`} />
823 {shows("") && (
824 <div className="mt-2 space-y-px">
825 <SidebarLink to={`${base}/settings`} end icon={<Settings size={15} />}>
826 General
827 </SidebarLink>
828 </div>
829 )}
830 {running && (
831 <>
832 {shows("") && <Rule />}
833 <div className={shows("") ? "space-y-px" : "mt-2 space-y-px"}>
834 <SidebarLink to={`${base}/settings/deployments`} icon={<Rocket size={15} />}>
835 Deployments
836 </SidebarLink>
837 <SidebarLink to={`${base}/settings/domains`} icon={<Globe size={15} />}>
838 Domains
839 </SidebarLink>
840 </div>
841 </>
842 )}
843 {agents && (
844 <>
845 <Rule />
846 <div className="space-y-px">
847 {shows("agents") && (
848 <SidebarLink to={`${base}/settings/agents`} icon={<Bot size={15} />}>
849 Agents
850 </SidebarLink>
851 )}
852 {shows("guardrails") && (
853 <SidebarLink to={`${base}/settings/guardrails`} icon={<ShieldCheck size={15} />}>
854 Guardrails
855 </SidebarLink>
856 )}
857 </div>
858 </>
859 )}
860 <Rule />
861 <div className="space-y-px">
862 {shows("repository") && (
863 <SidebarLink to={`${base}/settings/repository`} icon={<BookMarked size={15} />}>
864 Repository
865 </SidebarLink>
866 )}
Merge branch 'mirroring' into artifacts-mode867 {shows("mirroring") && (
868 <SidebarLink to={`${base}/settings/mirroring`} icon={<ArrowLeftRight size={15} />}>
869 Mirroring
870 </SidebarLink>
871 )}
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look872 {shows("access") && (
873 <SidebarLink to={`${base}/settings/access`} icon={<Users size={15} />}>
874 Access
875 </SidebarLink>
876 )}
Merge branch 'worktree-agent-a5a5de74d8863d554' into worktree-agent-a16631325aecf58ca877 {shows("keys") && (
878 <SidebarLink to={`${base}/settings/keys`} icon={<KeyRound size={15} />}>
879 Deploy keys
880 </SidebarLink>
881 )}
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look882 {shows("branches") && (
883 <SidebarLink to={`${base}/settings/branches`} icon={<GitBranch size={15} />}>
884 Branches and merging
885 </SidebarLink>
886 )}
Merge rulesets: branch and tag rules, agent-first, enforced on push and merge887 {shows("rules") && (
888 <SidebarLink to={`${base}/settings/rules`} icon={<Scale size={15} />}>
889 Rules
890 </SidebarLink>
891 )}
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look892 {shows("secrets") && (
893 <SidebarLink to={`${base}/settings/secrets`} icon={<Lock size={15} />}>
894 Secrets and variables
895 </SidebarLink>
896 )}
Merge branch 'worktree-agent-a3abfcce648e87dca'897 {shows("actions") && (
898 <SidebarLink to={`${base}/settings/actions`} icon={<PlayCircle size={15} />}>
899 Actions
900 </SidebarLink>
901 )}
902 {shows("environments") && (
903 <SidebarLink to={`${base}/settings/environments`} icon={<Layers size={15} />}>
904 Environments
905 </SidebarLink>
906 )}
Fast pages, required checks on the branch, self-hosted runners, honest incidents907 {shows("runners") && (
908 <SidebarLink to={`${base}/settings/runners`} icon={<ServerCog size={15} />}>
909 Runners
910 </SidebarLink>
911 )}
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look912 {shows("webhooks") && (
913 <SidebarLink to={`${base}/settings/webhooks`} icon={<Webhook size={15} />}>
914 Webhooks
915 </SidebarLink>
916 )}
917 </div>
Project settings move into the sidebar, grouped, with a heading per page918 </nav>
919 );
920}
921
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)922/**
923 * Whether the menus list Settings → Invites (invites to g1t): always while
924 * sign-up takes an invite; once anyone can sign up, only for someone with
925 * invites already made to look back on, which the account menu's data says.
926 */
927function useInvitesListed(): boolean {
928 const inviteOnly = useInviteOnly();
929 const details = useFetcher<AccountMenuData | null>({ key: "account-menu" });
930 useEffect(() => {
931 if (!inviteOnly && details.state === "idle" && details.data === undefined) details.load("/settings/menu.json");
932 // eslint-disable-next-line react-hooks/exhaustive-deps
933 }, [inviteOnly]);
934 return inviteOnly || details.data?.invites_page === true;
935}
936
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas937/** Your own settings, drilled into from Your settings: one page each. */
938function 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)939 const invites = useInvitesListed();
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas940 const link = (page: AccountSettingsPage, icon: ReactNode) => (
941 <SidebarLink to={`/settings/${page}`} icon={icon}>
942 {ACCOUNT_SETTINGS[page].title}
943 </SidebarLink>
Docs: automations944 );
945 return (
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look946 <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 quotas947 <BackRow to="/" label="Your settings" context={username} />
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look948 <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 quotas949 {link("profile", <CircleUserRound size={15} />)}
950 {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)951 {invites && link("invites", <Ticket size={15} />)}
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas952 </div>
953 <Rule />
954 <div className="space-y-px">
955 {link("keys", <Fingerprint size={15} />)}
956 {link("tokens", <KeyRound size={15} />)}
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look957 </div>
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas958 <Rule />
959 <div className="space-y-px">
Integrations are a directory of connectors, for a workspace and for each person960 {link("integrations", <Blocks size={15} />)}
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas961 {link("github", <GithubMark className="size-[15px]" />)}
962 {link("applications", <Plug size={15} />)}
963 </div>
964 <Rule />
965 <div className="space-y-px">
Merge main (membership, two-factor, GitHub repo roles) into tokens966 {link("two-factor", <ShieldCheck size={15} />)}
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas967 {link("security-log", <History size={15} />)}
968 </div>
Docs: automations969 </nav>
970 );
971}
972
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put973/**
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.974 * Code's sidebar: its Overview, the projects, what spans them and what is
975 * coming; in a project, drilled into the project's own list, and its
976 * settings one level further in. The address says which, so a link
977 * 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 put978 */
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.979function CodeSidebar({
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look980 user,
981 shell,
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas982 missing = false,
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look983}: {
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.984 user: User;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look985 shell: ShellData;
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas986 /** The page is a 404: the address names nothing the viewer can see. */
987 missing?: boolean;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look988}) {
Docs: automations989 const ws = shell.workspace;
990 const { pathname } = useLocation();
991 const going = useNavigation().location?.pathname;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look992 // Where the sidebar is drilled to follows the page being gone to, so it
993 // moves as the link is followed, not once the page arrives.
994 const target = going ?? pathname;
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas995 // On a 404, the address is not a place: no list is drilled into from it,
996 // except the project's own when the project is real and visible and only
997 // something inside it is missing (a file, a commit, an issue).
998 const lost = missing && going == null;
A repository has its own sidebar, as settings do999 const active = shell.repo;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1000 // In a repository, or on the way into one, its own list.
A repository has its own sidebar, as settings do1001 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.1002 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 look1003 // An invitation to a repository is answered before its menu means anything.
1004 const inRepo =
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1005 repoPath != null &&
1006 !reserved.has(repoPath[1]) &&
1007 repoPath[2] !== "-" &&
1008 !/^\/[^/]+\/[^/]+\/invitations\/?$/.test(target) &&
1009 (!lost || sameRepo(active, { namespace: repoPath[1]!, name: repoPath[2]! }));
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1010 // A project's settings, one level further in.
Project settings move into the sidebar, grouped, with a heading per page1011 const inRepoSettings = inRepo && REPO_SETTINGS_PAGE.test(target);
Sidebar: no settings flash on the way into a repository, and a better slide1012 // The repository the menu is for: the one loaded if it is the one being
1013 // gone to, else what the address says, at once.
1014 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 look1015 const guessed: MenuRepo | null = targetRepo
Sidebar: no settings flash on the way into a repository, and a better slide1016 ? sameRepo(active, targetRepo)
1017 ? active
1018 : {
1019 ...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.1020 member: (user.workspaces ?? []).some((m) => m.slug === targetRepo.namespace.toLowerCase()),
Sidebar: no settings flash on the way into a repository, and a better slide1021 }
1022 : null;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1023 // The viewer's role there, from the repository's page once it has loaded.
1024 const page = useRouteLoaderData("routes/repo/layout") as
1025 | { repo?: { namespace: string; name: string }; access?: ViewerAccess }
1026 | undefined;
1027 const menuRepo: MenuRepo | null =
1028 guessed && page?.access && page.repo && sameRepo(page.repo, guessed)
1029 ? { ...guessed, member: page.access.insider, settings: seesSettings(page.access), can: page.access.can }
1030 : guessed;
1031
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.1032 // The way from Code's list to the one shown.
1033 const trail: Level[] = [{ key: "main", node: ws ? <CodeMenu shell={shell} slug={ws.slug} /> : null }];
1034 if (menuRepo) {
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1035 const key = `repo:${menuRepo.namespace}/${menuRepo.name}`.toLowerCase();
1036 // 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.1037 const home = (user.workspaces ?? []).find((m) => m.slug === menuRepo.namespace.toLowerCase());
1038 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 look1039 trail.push({
1040 key,
1041 node: (
1042 <RepoMenu
1043 repo={menuRepo}
1044 isPrivate={[...shell.repos, ...(shell.shared ?? [])].some((repo) => sameRepo(repo, menuRepo) && repo.isPrivate)}
1045 back={back}
1046 />
1047 ),
1048 });
1049 if (inRepoSettings) trail.push({ key: `${key}:settings`, node: <RepoSettingsMenu repo={menuRepo} /> });
1050 }
1051
Docs: automations1052 return (
1053 <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.1054 <ModeHeader title="Code" />
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1055 <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)1056 </div>
1057 );
1058}
1059
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.1060/**
1061 * A mode's sidebar heading: its name, quiet, under the workspace's
1062 * switcher, with what it makes at the end.
1063 */
1064export 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)1065 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.1066 <div className="flex h-9 shrink-0 items-center gap-1 pr-1 pl-3">
1067 <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)1068 {action}
1069 </div>
1070 );
1071}
1072
1073/**
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.1074 * 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)1075 * 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.1076 * 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)1077 * agents, context and memory are Agents'.
1078 */
1079function CodeMenu({ shell, slug }: { shell: ShellData; slug: string }) {
1080 const { pathname } = useLocation();
1081 const going = useNavigation().location?.pathname;
1082 const path = going ?? pathname;
1083 const at = (page: string) => path === `/${slug}/-/${page}` || path.startsWith(`/${slug}/-/${page}/`);
1084 const shared = shell.shared ?? [];
1085 return (
1086 <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.1087 <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)1088 <SidebarLink to={`/${slug}/-/overview`} icon={<LayoutDashboard size={15} />} current={at("overview")}>
1089 Overview
1090 </SidebarLink>
1091 </div>
1092 <div className="mt-3">
1093 <SidebarProjects slug={slug} shell={shell} current={at("projects")} />
1094 </div>
1095 <Rule />
1096 <div className="space-y-px">
1097 <SidebarLink to={`/${slug}/-/security`} icon={<ShieldCheck size={15} />} current={at("security") && !at("security/settings")}>
1098 Security
1099 </SidebarLink>
1100 <SidebarLink to={`/${slug}/-/packages`} icon={<Package size={15} />} current={at("packages")}>
1101 Packages
1102 </SidebarLink>
1103 {INSIGHTS && (
1104 <SidebarSoonLink to={`/${slug}/-/insights`} icon={<TrendingUp size={15} />} about={INSIGHTS.summary} current={at("insights")}>
1105 {INSIGHTS.title}
1106 </SidebarSoonLink>
1107 )}
1108 {roadmapIn("Workspace")
1109 .filter((item) => item.key !== "insights" && item.key !== "teams" && item.key !== "fleet")
1110 .map((item) => (
1111 <SidebarSoonLink key={item.key} to={`/${slug}/-/soon/${item.key}`} icon={WORKSPACE_ICONS[item.key] ?? <Sparkles size={15} />} about={item.summary}>
1112 {item.title === "Board" ? "Boards" : item.title}
1113 </SidebarSoonLink>
1114 ))}
1115 </div>
1116 {shared.length > 0 && (
1117 <>
1118 <Rule />
1119 <SidebarGroup title="Shared with you">
1120 {shared.map((repo) => (
1121 <SidebarLink
1122 key={`${repo.namespace}/${repo.name}`}
1123 to={`/${repo.namespace}/${repo.name}`}
1124 icon={repo.isPrivate ? <Lock size={15} /> : <Box size={15} />}
1125 drill="hover"
1126 >
1127 <span className="font-mono text-faint">{repo.namespace}/</span>
1128 {repo.name}
1129 </SidebarLink>
1130 ))}
1131 </SidebarGroup>
1132 </>
1133 )}
1134 </nav>
1135 );
1136}
1137
1138/** Workspace pages that sit in its Settings list, drilled into from the Workspace sidebar. */
1139const WORKSPACE_SETTINGS = ["settings", "repositories", "tokens", "personal-access-tokens", "secrets", "actions", "runners", "webhooks", "emoji"];
1140
1141/**
1142 * The Workspace mode's sidebar: the workspace itself, for every member.
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.1143 * Its overview, money, 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)1144 * settings as a list of their own. Owner-only pages stay owner-only.
1145 */
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.1146export 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)1147 const { pathname } = useLocation();
1148 const going = useNavigation().location?.pathname;
1149 const path = going ?? pathname;
1150 const page = path.startsWith(`/${slug}/-/`) ? path.slice(`/${slug}/-/`.length) : "";
1151 const top = page.split("/")[0] ?? "";
1152 const at = (...pages: string[]) => pages.some((p) => page === p || page.startsWith(`${p}/`));
1153 const inSettings = WORKSPACE_SETTINGS.includes(top);
1154 const main = (
1155 <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.1156 <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)1157 <SidebarLink to={`/${slug}/-/workspace`} icon={<LayoutGrid size={15} />} current={at("workspace")}>
1158 Overview
1159 </SidebarLink>
1160 </div>
1161 <SidebarGroup title="Usage and billing" className="mt-3">
1162 <SidebarLink to={`/${slug}/-/usage`} icon={<BarChart3 size={15} />} current={at("usage", "gateway")}>
1163 Usage
1164 </SidebarLink>
1165 <SidebarLink to={`/${slug}/-/billing`} icon={<CreditCard size={15} />} current={at("billing")}>
1166 Billing and plans
1167 </SidebarLink>
1168 </SidebarGroup>
1169 <SidebarGroup title="Connections" className="mt-3">
1170 <SidebarLink to={`/${slug}/-/integrations`} icon={<Plug size={15} />} current={at("integrations")}>
1171 Integrations
1172 </SidebarLink>
1173 </SidebarGroup>
1174 <SidebarGroup title="Security policies" className="mt-3">
1175 <SidebarLink to={`/${slug}/-/security/settings`} icon={<ShieldCheck size={15} />} current={at("security/settings")}>
1176 Security settings
1177 </SidebarLink>
1178 <SidebarLink to={`/${slug}/-/guardrails`} icon={<Gauge size={15} />} current={at("guardrails")}>
1179 Guardrails
1180 </SidebarLink>
1181 <SidebarLink to={`/${slug}/-/rules`} icon={<Scale size={15} />} current={at("rules")}>
1182 Rules
1183 </SidebarLink>
1184 </SidebarGroup>
1185 <Rule />
1186 <div className="space-y-px">
1187 <SidebarLink to={`/${slug}/-/audit`} icon={<History size={15} />} current={at("audit")}>
1188 Audit log
1189 </SidebarLink>
1190 <SidebarLink to={owner ? `/${slug}/-/settings` : `/${slug}/-/repositories`} icon={<Settings size={15} />} drill current={inSettings}>
1191 Settings
1192 </SidebarLink>
1193 </div>
1194 </nav>
1195 );
1196 const settings = (
1197 <nav aria-label="Workspace settings" className={PANEL}>
1198 <BackRow to={`/${slug}/-/workspace`} label="Settings" context={slug} />
1199 <div className="mt-2 space-y-px">
1200 {owner && (
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1201 <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)1202 General
1203 </SidebarLink>
1204 )}
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1205 <SidebarLink to={`/${slug}/-/settings/chat`} icon={<MessagesSquare size={15} />}>
1206 Chat
1207 </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)1208 <SidebarLink to={`/${slug}/-/repositories`} icon={<BookMarked size={15} />}>
1209 Repositories
1210 </SidebarLink>
1211 <SidebarLink to={`/${slug}/-/tokens`} icon={<KeyRound size={15} />}>
1212 Access tokens
1213 </SidebarLink>
1214 {owner && (
1215 <SidebarLink to={`/${slug}/-/personal-access-tokens`} icon={<UserRoundKey size={15} />}>
1216 Personal access tokens
1217 </SidebarLink>
1218 )}
1219 <SidebarLink to={`/${slug}/-/webhooks`} icon={<Webhook size={15} />}>
1220 Webhooks
1221 </SidebarLink>
1222 <SidebarLink to={`/${slug}/-/emoji`} icon={<Smile size={15} />}>
1223 Emoji
1224 </SidebarLink>
1225 </div>
1226 <SidebarGroup title="Runs" className="mt-3">
1227 <SidebarLink to={`/${slug}/-/secrets`} icon={<Lock size={15} />}>
1228 Secrets and variables
1229 </SidebarLink>
1230 <SidebarLink to={`/${slug}/-/actions`} icon={<PlayCircle size={15} />}>
1231 Actions
1232 </SidebarLink>
1233 {owner && (
1234 <SidebarLink to={`/${slug}/-/runners`} icon={<ServerCog size={15} />}>
1235 Runners
1236 </SidebarLink>
1237 )}
1238 </SidebarGroup>
1239 </nav>
1240 );
1241 const trail: Level[] = [{ key: "workspace", node: main }];
1242 if (inSettings) trail.push({ key: "workspace:settings", node: settings });
1243 return (
1244 <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.1245 <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)1246 <Drill trail={trail} />
1247 </div>
1248 );
1249}
1250
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.1251/** People's sidebar: everyone in the workspace, and its teams. */
1252function PeopleSidebar({ slug }: { slug: string }) {
1253 const { pathname } = useLocation();
1254 const going = useNavigation().location?.pathname;
1255 const path = going ?? pathname;
1256 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)1257 return (
1258 <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.1259 <ModeHeader title="People" />
1260 <nav aria-label="People" className={PANEL}>
1261 <div className="space-y-px">
1262 <SidebarLink to={`/${slug}/-/people`} icon={<Users size={15} />} current={at("people")}>
1263 Everyone
1264 </SidebarLink>
1265 <SidebarLink to={`/${slug}/-/teams`} icon={<UsersRound size={15} />} current={at("teams")}>
1266 Teams
1267 </SidebarLink>
1268 </div>
1269 </nav>
1270 </div>
1271 );
1272}
1273
1274/**
1275 * Notifications' sidebar: what you have not finished with, what you saved
1276 * and what is done; then why you were told, which narrows any of them.
1277 */
1278function NotificationsSidebar({ counts }: { counts: InboxCounts | null }) {
1279 const { search } = useLocation();
1280 const params = new URLSearchParams(search);
1281 const view = inboxView(params.get("view"));
1282 const reason = inboxReason(params.get("reason"));
1283 const tab = params.get("tab");
1284 const address = (changes: Record<string, string | null>) => {
1285 const merged: Record<string, string | null> = { tab, view: view === "inbox" ? null : view, reason, ...changes };
1286 const next = new URLSearchParams();
1287 for (const [name, value] of Object.entries(merged)) if (value) next.set(name, value);
1288 const query = next.toString();
1289 return query ? `/notifications?${query}` : "/notifications";
1290 };
1291 const views = [
1292 { view: "inbox", label: "Everything", icon: <Bell size={15} />, count: counts?.unread },
1293 { view: "saved", label: "Saved", icon: <Bookmark size={15} /> },
1294 { view: "done", label: "Done", icon: <Check size={15} /> },
1295 ] as const;
1296 return (
1297 <div className="flex h-full flex-col">
1298 <ModeHeader title="Notifications" />
1299 <nav aria-label="Notifications" className={PANEL}>
1300 <div className="space-y-px">
1301 {views.map((entry) => (
1302 <SidebarLink
1303 key={entry.view}
1304 to={address({ view: entry.view === "inbox" ? null : entry.view, before: null })}
1305 icon={entry.icon}
1306 count={"count" in entry ? (entry.count ?? undefined) : undefined}
1307 current={view === entry.view}
1308 >
1309 {entry.label}
1310 </SidebarLink>
1311 ))}
1312 </div>
1313 <SidebarGroup title="Why you were told" className="mt-4">
1314 {REASON_FILTERS.map((entry) => (
1315 <SidebarLink
1316 key={entry.reason ?? "any"}
1317 to={address({ reason: entry.reason, before: null })}
1318 icon={<span className="block size-[15px]" />}
1319 current={reason === entry.reason}
1320 >
1321 {entry.reason == null ? "Any reason" : entry.label}
1322 </SidebarLink>
1323 ))}
1324 </SidebarGroup>
1325 </nav>
1326 </div>
1327 );
1328}
1329
1330/** Your own settings, beside the page: under the account menu, not any workspace's. */
1331export function AccountSidebar({ username }: { username: string }) {
1332 return (
1333 <div className="flex h-full flex-col">
1334 <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)1335 <div className="min-h-0 grow">
1336 <AccountSettingsMenu username={username} />
Docs: automations1337 </div>
1338 </div>
1339 );
1340}
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)1341
Docs: automations1342/** Words for the sections a path can end in. */
1343const SECTIONS: Record<string, string> = {
1344 issues: "Issues",
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1345 milestones: "Milestones",
1346 labels: "Labels",
Docs: automations1347 pulls: "Pull requests",
1348 queue: "Merge queue",
1349 commits: "Commits",
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales1350 plans: "Outcomes",
1351 actions: "Workflows",
1352 soon: "Soon",
Deployments: a preview for every pull request, production on g1t.page1353 deployments: "Deployments",
Projects: what a workspace builds and runs, first on every page1354 repository: "Repository",
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1355 access: "Access",
1356 invitations: "Invitation",
1357 repositories: "Repositories",
Branches and Tags pages, each file's last commit, and the branch menu on files1358 branches: "Branches",
1359 tags: "Tags",
Compare: any two branches, the commits one has that the other does not, and the diff, with Open a pull request1360 compare: "Compare",
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales1361 code: "Files",
GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs1362 secrets: "Secrets and variables",
Docs: automations1363 settings: "Settings",
Navigation: the workspace's own page with tabs, pins and recent in the sidebar1364 people: "People",
1365 projects: "Projects",
1366 teams: "Teams",
Docs: automations1367 tokens: "Access tokens",
Settings: fine-grained tokens, workspace token Admin, workspace personal access token rules1368 "personal-access-tokens": "Personal access tokens",
Docs: automations1369 usage: "Usage",
Site: the AI Gateway page's breadcrumb reads "AI Gateway"1370 gateway: "AI Gateway",
Secrets and variables: one list, rows per environment, for workflows and deployments1371 billing: "Billing and plans",
Docs: automations1372 integrations: "Integrations",
1373 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)1374 emoji: "Emoji",
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1375 domains: "Domains",
1376 guardrails: "Guardrails",
Merge rulesets: branch and tag rules, agent-first, enforced on push and merge1377 rules: "Rules",
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1378 audit: "Audit log",
Files pages say Files in the trail and keep the description in About only1379 tree: "Files",
1380 blob: "Files",
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail1381 agents: "Agents",
1382 context: "Context",
1383 memory: "Memory",
1384 security: "Security",
1385 packages: "Packages",
1386 runners: "Runners",
Merge branch 'worktree-agent-a3abfcce648e87dca'1387 environments: "Environments",
Security matches the workspace's other pages and leaves out deleted repositories; every section has a name in the trail1388 workflows: "Workflows",
1389 observability: "Observability",
1390 insights: "Insights",
1391 sessions: "Sessions",
Chat and workspace agents: channels, DMs and named agents you talk to1392 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.1393 artifacts: "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.1394 today: "Today",
1395 apps: "Apps",
Chat and workspace agents: channels, DMs and named agents you talk to1396 "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)1397 overview: "Overview",
1398 workspace: "Workspace",
Docs: automations1399};
1400
Merge branch 'worktree-agent-a3abfcce648e87dca'1401/** Settings pages whose name differs from the section's of the same word. */
1402const SETTINGS_SECTIONS: Record<string, string> = { branches: "Branches and merging", actions: "Actions" };
1403
Docs: automations1404/** 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.1405function Breadcrumbs({
1406 pathname,
1407 missing,
1408 repo,
1409 workspace,
1410}: {
1411 pathname: string;
1412 missing?: boolean;
1413 repo?: ShellData["repo"];
1414 /** The workspace you are in: the switcher names it, so the trail starts after it. */
1415 workspace: string | null;
1416}) {
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1417 // A 404 names nothing from the address, unless the project is real and
1418 // visible and only something inside it is missing.
1419 const visibleRepo = /^\/([^/]+)\/([^/-][^/]*)(\/|$)/.exec(pathname);
1420 if (missing && !(visibleRepo && sameRepo(repo ?? null, { namespace: visibleRepo[1]!, name: visibleRepo[2]! }))) {
1421 return <span className="text-sm font-medium">Not found</span>;
1422 }
Docs: automations1423 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.1424 const reserved = ["settings", "explore", "new", "search", "workspaces", "policies", "security", "support", "status", "invite", "notifications"];
1425 if (parts.length === 0) return <span className="text-sm font-medium">Today</span>;
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1426 // Your settings: Settings / Emails.
1427 if (parts[0] === "settings") {
1428 const page = accountSettingsPage(pathname);
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1429 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 quotas1430 }
Docs: automations1431 if (reserved.includes(parts[0]!)) {
1432 const words: Record<string, string> = {
1433 settings: "Account",
1434 explore: "Explore",
Projects live: fixes from walking them end to end1435 new: "New project",
Docs: automations1436 search: "Search",
1437 workspaces: "New workspace",
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1438 policies: "Policies",
1439 security: "Security",
1440 support: "Support",
1441 status: "Status",
1442 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.1443 notifications: "Notifications",
Docs: automations1444 };
1445 return <span className="text-sm font-medium">{words[parts[0]!]}</span>;
1446 }
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put1447 // A person's profile, by their handle.
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1448 if (parts[0] === "u" && parts[1]) return <ProfileCrumb username={parts[1]} />;
Docs: automations1449 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.1450 const ours = workspace != null && owner!.toLowerCase() === workspace.toLowerCase();
1451 const trail: Crumb[] = ours ? [] : [{ label: owner!, to: `/${owner}`, mono: true }];
Docs: automations1452 if (second === "-") {
1453 const page = `/${owner}/-/${third}`;
1454 if (third && SETTINGS_PAGE.test(page)) {
1455 trail.push({ label: "Settings", to: `/${owner}/-/settings` });
1456 trail.push({ label: third === "settings" ? "General" : (SECTIONS[third] ?? third), to: page });
1457 } else if (third) trail.push({ label: SECTIONS[third] ?? third, to: page });
1458 } else if (second) {
1459 const repo = `/${owner}/${second}`;
1460 trail.push({ label: second, to: repo, mono: true });
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1461 if (third === "pull" && fourth) trail.push({ label: `Pull request #${fourth}`, short: `#${fourth}`, to: `${repo}/pull/${fourth}` });
1462 else if (third === "issues" && fourth && fourth !== "new") trail.push({ label: `Issue #${fourth}`, short: `#${fourth}`, to: `${repo}/issues/${fourth}` });
Docs: automations1463 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 deployments1464 else if (third && SECTIONS[third]) {
1465 trail.push({ label: SECTIONS[third]!, to: `${repo}/${third}` });
1466 // A settings page names which one: Settings / Secrets and variables.
1467 if (third === "settings" && fourth && SECTIONS[fourth]) {
Merge branch 'worktree-agent-a3abfcce648e87dca'1468 trail.push({ label: SETTINGS_SECTIONS[fourth] ?? SECTIONS[fourth]!, to: `${repo}/settings/${fourth}` });
Secrets and variables: one list, rows per environment, for workflows and deployments1469 }
1470 }
Docs: automations1471 }
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.1472 if (trail.length === 0) trail.push({ label: "Overview", to: `/${owner}` });
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1473 return <Trail trail={trail} />;
1474}
1475
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1476/** A profile's place in the top bar: the person's avatar and @handle, from the page once it has loaded. */
1477function 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 managers1478 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 project1479 const profile = page?.profile?.username.toLowerCase() === username.toLowerCase() ? page.profile : null;
1480 return (
1481 <Link to={`/u/${profile?.username ?? username}`} aria-current="page" className="flex min-w-0 items-center gap-2 rounded px-1 py-0.5 transition-colors hover:bg-raised">
1482 <Avatar name={profile?.username ?? username} image={profile?.avatar ?? null} size={20} />
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers1483 <span className="truncate font-mono text-[0.8125rem] font-medium">@{profile ? shownUsername(profile) : username}</span>
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1484 </Link>
1485 );
1486}
1487
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1488/** One link of the trail; `short` is what a phone shows when it is the page itself. */
1489type Crumb = { label: string; to: string; mono?: boolean; short?: string };
1490
1491/**
1492 * The trail of links. On a phone there is room for one: the page itself,
1493 * with a way back to where it sits; the whole trail from a wider screen up.
1494 */
1495function 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)1496 // Up on a phone, unless up is the workspace itself: its pages are the tabs.
1497 const up = trail.length > 1 && !/^\/[^/]+$/.test(trail[trail.length - 2]!.to) ? trail[trail.length - 2]! : null;
Docs: automations1498 return (
1499 <nav aria-label="Where you are" className="flex min-w-0 items-center gap-1.5 text-sm">
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1500 {up && (
1501 <Link
1502 to={up.to}
1503 prefetch="intent"
1504 aria-label={`Back to ${up.label}`}
1505 className="-ml-1 flex size-8 shrink-0 items-center justify-center rounded-md text-muted transition-colors hover:bg-raised hover:text-fg sm:hidden"
1506 >
1507 <ChevronLeft size={16} />
1508 </Link>
1509 )}
1510 {trail.map((crumb, index) => {
1511 const last = index === trail.length - 1;
1512 return (
1513 <span key={index} className={`min-w-0 items-center gap-1.5 ${last ? "flex" : "hidden sm:flex"}`}>
1514 {index > 0 && <span className="hidden text-line-strong sm:inline">/</span>}
1515 <Link
1516 to={crumb.to}
1517 prefetch="intent"
1518 aria-current={last ? "page" : undefined}
1519 className={`truncate rounded px-1 py-0.5 transition-colors hover:bg-raised ${
1520 last ? "font-medium text-fg" : "text-muted hover:text-fg"
1521 } ${crumb.mono ? "font-mono text-[0.8125rem]" : ""}`}
1522 >
1523 {last && crumb.short ? (
1524 <>
1525 <span className="sm:hidden">{crumb.short}</span>
1526 <span className="hidden sm:inline">{crumb.label}</span>
1527 </>
1528 ) : (
1529 crumb.label
1530 )}
1531 </Link>
1532 </span>
1533 );
1534 })}
Docs: automations1535 </nav>
1536 );
1537}
1538
Search across all of g1t, Explore, and a command palette1539type Command = PaletteCommand;
Docs: automations1540
1541/** 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.1542function commandsFor(user: User, shell: ShellData): Command[] {
1543 const ws = shell.workspace;
Docs: automations1544 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.1545 ...(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)1546 ? [
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.1547 { label: "Today", to: todayPath(ws.slug), icon: <Sun size={15} /> },
1548 { label: "Chat", to: `/${ws.slug}/-/chat`, icon: <MessagesSquare size={15} /> },
1549 { label: "Agents", to: `/${ws.slug}/-/agents`, icon: <Sparkles size={15} /> },
1550 ...(hasCodeAccess(ws) ? [{ label: "Code overview", to: `/${ws.slug}/-/overview`, icon: <Code2 size={15} /> }] : []),
1551 { label: "Artifacts", to: `/${ws.slug}/-/artifacts`, icon: <Shapes size={15} /> },
1552 { label: "Apps", hint: "Everything installed that you can use", to: `/${ws.slug}/-/apps`, icon: <LayoutGrid size={15} /> },
1553 { 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)1554 ]
1555 : []),
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step1556 ...(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-agent1557 ? [{ 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 step1558 : []),
Docs: automations1559 { label: "Explore repositories", to: "/explore", icon: <Compass size={15} /> },
Search across all of g1t, Explore, and a command palette1560 { 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.1561 { label: "Notifications", hint: "What needs you", to: "/notifications", icon: <Bell size={15} /> },
Projects: what a workspace builds and runs, first on every page1562 { label: "New project", to: "/new", icon: <Plus size={15} /> },
Docs: automations1563 { 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 quotas1564 { label: "Your settings", to: FIRST_SETTINGS_PAGE, icon: <Settings size={15} /> },
1565 ...(Object.keys(ACCOUNT_SETTINGS) as AccountSettingsPage[])
1566 .filter((page) => page !== "profile")
1567 .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.1568 ...THEME_COMMANDS,
Docs: automations1569 ];
1570 const repo = shell.repo;
1571 if (repo) {
1572 const base = `/${repo.namespace}/${repo.name}`;
1573 const name = `${repo.namespace}/${repo.name}`;
1574 commands.unshift(
Projects: what a workspace builds and runs, first on every page1575 { label: "Overview", hint: name, to: base, icon: <LayoutGrid size={15} /> },
1576 { label: "Code", hint: name, to: `${base}/code`, icon: <Code2 size={15} /> },
Docs: automations1577 { label: "Issues", hint: name, to: `${base}/issues`, icon: <CircleDot size={15} /> },
1578 { 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 step1579 ...(repo.member
1580 ? [{ label: `Put an agent on ${repo.name}`, hint: name, to: `${base}/issues/new?agent=1`, icon: <Sparkles size={15} /> }]
1581 : []),
Docs: automations1582 { label: "Pull requests", hint: name, to: `${base}/pulls`, icon: <GitPullRequest size={15} /> },
1583 { label: "Commits", hint: name, to: `${base}/commits`, icon: <History size={15} /> },
1584 ...(repo.member
1585 ? [
1586 { label: "Plan work", hint: name, to: `${base}/plans`, icon: <ListTree size={15} /> },
Projects: what a workspace builds and runs, first on every page1587 { label: "Deployments", hint: name, to: `${base}/deployments`, icon: <Rocket size={15} /> },
1588 { label: "Secrets and variables", hint: name, to: `${base}/settings/secrets`, icon: <Lock size={15} /> },
1589 { label: "Project settings", hint: name, to: `${base}/settings`, icon: <Settings size={15} /> },
1590 { label: "Repository settings", hint: name, to: `${base}/settings/repository`, icon: <Settings size={15} /> },
Docs: automations1591 ]
1592 : []),
1593 );
1594 }
1595 for (const membership of user.workspaces ?? []) {
1596 commands.push(
Workspace names and icons, and a component kit for every control1597 { 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 sidebar1598 { label: "All projects", hint: membership.slug, to: `/${membership.slug}/-/projects`, icon: <LayoutGrid size={15} /> },
1599 { label: "People", hint: membership.slug, to: `/${membership.slug}/-/people`, icon: <Users size={15} /> },
Docs: automations1600 { 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 tokens1601 { 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 page1602 { label: "Billing and plans", hint: `${membership.slug} · Settings`, to: `/${membership.slug}/-/billing`, icon: <CreditCard size={15} /> },
Docs: automations1603 { 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 look1604 { label: "Integrations", hint: membership.slug, to: `/${membership.slug}/-/integrations`, icon: <Plug size={15} /> },
Docs: automations1605 );
1606 }
1607 for (const listed of shell.repos) {
1608 commands.push({
Projects: what a workspace builds and runs, first on every page1609 label: listed.title ?? listed.name,
1610 hint: `${listed.namespace} · Project`,
Docs: automations1611 to: `/${listed.namespace}/${listed.name}`,
Projects: what a workspace builds and runs, first on every page1612 icon: <Box size={15} />,
Docs: automations1613 });
1614 }
Thirteen MCP tools and classic token scopes; agents rate their confidence and can be put on an issue in one step1615 // "Put an agent on …": one per project, after the projects themselves.
1616 for (const listed of shell.repos) {
1617 if (repo && listed.namespace === repo.namespace && listed.name === repo.name) continue;
1618 commands.push({
1619 label: `Put an agent on ${listed.title ?? listed.name}`,
1620 hint: `${listed.namespace}/${listed.name}`,
1621 to: `/${listed.namespace}/${listed.name}/issues/new?agent=1`,
1622 icon: <Sparkles size={15} />,
1623 });
1624 }
Docs: automations1625 return commands;
1626}
1627
1628/**
Merge branch 'worktree-agent-aca4790ea223aa235'1629 * The page while the next one loads: after a moment it dims, under the
1630 * bar below, so it is plainly on its way out rather than frozen, and the
1631 * next page fades up from there. Sending a form does not dim it: the
1632 * form's button says it is working. Spread on the element holding the page.
1633 */
1634export function useLeaving() {
1635 const navigation = useNavigation();
1636 const method = navigation.formMethod?.toUpperCase();
1637 const leaving = navigation.state === "loading" && (method == null || method === "GET");
1638 return {
1639 "aria-busy": leaving || undefined,
1640 className: `transition-opacity motion-reduce:transition-none ${leaving ? "opacity-60 delay-200 duration-300" : "duration-150"}`,
1641 };
1642}
1643
1644/**
Docs: automations1645 * A bar across the top of the page while the next one loads, as GitHub
1646 * has: it appears at once, creeps towards the end while waiting, then fills
1647 * and fades when the page arrives.
1648 */
1649export function Progress() {
1650 const navigation = useNavigation();
1651 const busy = navigation.state !== "idle";
1652 const [width, setWidth] = useState(0);
1653 const [visible, setVisible] = useState(false);
1654 useEffect(() => {
1655 if (busy) {
1656 setVisible(true);
1657 setWidth(12);
1658 // Slows as it goes, never quite arriving until the page does.
1659 const timer = setInterval(() => setWidth((now) => now + (90 - now) * 0.12), 200);
1660 return () => clearInterval(timer);
1661 }
1662 setWidth((now) => (now > 0 ? 100 : 0));
1663 const fade = setTimeout(() => setVisible(false), 250);
1664 const reset = setTimeout(() => setWidth(0), 550);
1665 return () => {
1666 clearTimeout(fade);
1667 clearTimeout(reset);
1668 };
1669 }, [busy]);
1670 return (
1671 <div
1672 aria-hidden="true"
1673 className={`pointer-events-none fixed inset-x-0 top-0 z-[60] h-[3px] transition-opacity duration-300 ${
1674 visible ? "opacity-100" : "opacity-0"
1675 }`}
1676 >
1677 <div
1678 className="h-full bg-accent shadow-[0_0_10px_var(--color-accent)] transition-[width] duration-200 ease-out"
1679 style={{ width: `${width}%` }}
1680 />
1681 </div>
1682 );
1683}
1684
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)1685/** The top bar's way to g1t: the direct message with the workspace's orchestrator, opened or made. */
1686function AskG1tButton({ slug }: { slug: string }) {
1687 return (
1688 <Hint label="Ask g1t">
1689 <Link
1690 to={`/${slug}/-/chat?agent=g1t`}
1691 aria-label="Ask g1t"
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.1692 className="flex h-8 items-center gap-1.5 rounded-md border border-line px-1.5 text-sm text-fg/90 transition-colors hover:border-line-strong hover:bg-raised hover:text-fg sm:px-2.5"
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)1693 >
1694 <G1tMark size={18} />
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.1695 <span className="hidden lg:inline">Ask g1t</span>
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)1696 </Link>
1697 </Hint>
1698 );
1699}
1700
Docs: automations1701/**
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.1702 * Which sidebar sits beside the page: each mode's own, or none. Today and
1703 * Apps are pages at full width, and so are g1t's public pages, such as a
1704 * profile, which are no workspace's. Without a workspace, only your own
1705 * settings and Notifications have one.
Chat and workspace agents: channels, DMs and named agents you talk to1706 */
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.1707function sidebarFor(mode: ModeKey, workspace: boolean): Panel | null {
1708 if (!workspace) return mode === "account" || mode === "notifications" ? mode : null;
1709 if (mode === "today" || 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)1710 return mode;
Chat and workspace agents: channels, DMs and named agents you talk to1711}
1712
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.1713/** The sidebars that sit beside the page, one per mode that has one. */
1714type 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)1715
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.1716/** 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 bar1717const MODE_MENU: Record<Panel, string> = {
1718 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.1719 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 bar1720 agents: "Agents",
1721 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.1722 notifications: "Notifications",
1723 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 bar1724 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.1725 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 bar1726};
1727
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.1728/** Whether a key press happened in something you type into, where Ctrl B is the editor's. */
1729function typing(target: EventTarget | null): boolean {
1730 if (!(target instanceof HTMLElement)) return false;
1731 return target.isContentEditable || target.closest("input, textarea, select, [contenteditable=''], [contenteditable='true'], [role='textbox']") != null;
1732}
1733
1734/** Ctrl B (⌘B on a Mac) shows or hides the sidebar, except while typing. */
1735function useSidebarShortcut(toggle: () => void) {
1736 useEffect(() => {
1737 const onKey = (event: KeyboardEvent) => {
1738 if (event.key.toLowerCase() !== "b" || event.altKey || event.shiftKey || !(event.ctrlKey || event.metaKey)) return;
1739 if (event.defaultPrevented || typing(event.target)) return;
1740 event.preventDefault();
1741 toggle();
1742 };
1743 window.addEventListener("keydown", onKey);
1744 return () => window.removeEventListener("keydown", onKey);
1745 }, [toggle]);
1746}
1747
1748/** The button that shows or hides the sidebar. */
1749function SidebarToggle({ onClick, open, className = "" }: { onClick: () => void; open: boolean; className?: string }) {
1750 const key = sidebarKeyLabel(typeof navigator === "undefined" ? null : navigator.platform);
1751 return (
1752 <Hint label={`Toggle sidebar (${key})`}>
1753 <button
1754 type="button"
1755 aria-label={open ? "Hide the sidebar" : "Show the sidebar"}
1756 aria-expanded={open}
1757 onClick={onClick}
1758 className={`flex size-8 shrink-0 items-center justify-center rounded-md text-muted outline-none transition-colors hover:bg-raised hover:text-fg focus-visible:ring-2 focus-visible:ring-accent ${className}`}
1759 >
1760 <PanelLeft size={17} />
1761 </button>
1762 </Hint>
1763 );
1764}
1765
Chat and workspace agents: channels, DMs and named agents you talk to1766/**
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.1767 * 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.1768 * together. The dock, a floating bar of apps down the left; the mode's
1769 * sidebar, flat on the background beside it, which folds away with Ctrl B
1770 * and is a drawer below 1024px; and the page, a rounded panel inset from
1771 * the window, with its header across the top: the sidebar's toggle, where
1772 * you are, search, Ask g1t and Create new. On a phone the dock is a bar
1773 * along the bottom. Only for someone signed in; without a workspace yet,
1774 * there is no dock.
Docs: automations1775 */
1776export function AppShell({
1777 user,
1778 shell,
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1779 missing = false,
Docs: automations1780 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.1781 sidebarClosed = false,
Docs: automations1782 children,
1783}: {
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 user: User;
Docs: automations1785 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.1786 /** 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 quotas1787 missing?: boolean;
Docs: automations1788 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.1789 /** Whether the person folded the sidebar away, as their cookie says. */
1790 sidebarClosed?: boolean;
Docs: automations1791 children: ReactNode;
1792}) {
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1793 const { pathname } = useLocation();
Docs: automations1794 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.1795 const [closed, setClosed] = useState(sidebarClosed);
Docs: automations1796 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.1797 const commands = useMemo(() => commandsFor(user, shell), [user, shell]);
Docs: automations1798
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.1799 // A new page closes the drawer.
Docs: automations1800 useEffect(() => setDrawer(false), [pathname]);
Search across all of g1t, Explore, and a command palette1801 usePaletteShortcut(() => setPalette((open) => !open));
Merge branch 'worktree-agent-aca4790ea223aa235'1802 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)1803 useVisualViewport();
Docs: automations1804
Chat and workspace agents: channels, DMs and named agents you talk to1805 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.1806 const ws = shell.workspace;
1807 const mode = modeOf(going ?? pathname, ws?.slug ?? null);
1808 const panel = sidebarFor(mode, ws != null);
1809 const code = ws ? hasCodeAccess(ws) : false;
Chat and workspace agents: channels, DMs and named agents you talk to1810 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)1811 // Notify: the feed socket's live counts (lib/notify-client.ts) once it has them; the page's until then.
1812 const live = useLiveBadges(ws?.slug);
1813 const chatUnread = chatSidebar
1814 ? unreadTotals(chatSidebar.entries)
1815 : live?.chat != null
1816 ? { unread: live.chat, mentions: live.mentions ?? 0 }
1817 : (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.1818 const notificationsUnread = live?.inbox ?? shell.inbox?.unread ?? 0;
1819 const unread = { notifications: notificationsUnread, chat: chatUnread.unread, mentions: chatUnread.mentions };
1820
1821 // Folding the sidebar away on a computer is remembered, so the next page is drawn the same from the server.
1822 const toggleSidebar = useCallback(() => {
1823 if (!window.matchMedia("(min-width: 1024px)").matches) {
1824 setDrawer((open) => !open);
1825 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)1826 }
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.1827 setClosed((was) => {
1828 document.cookie = sidebarCookie(!was, window.location.protocol === "https:");
1829 return !was;
1830 });
1831 }, []);
1832 useSidebarShortcut(useCallback(() => {
1833 if (panel) toggleSidebar();
1834 }, [panel, toggleSidebar]));
1835
1836 const inline = panel != null && !closed;
1837 const sidebarNode = () => {
1838 if (!panel) return null;
1839 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)1840 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.1841 case "code":
1842 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)1843 case "chat":
1844 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.1845 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.1846 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)1847 case "agents":
1848 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.1849 case "notifications":
1850 return <NotificationsSidebar counts={shell.inbox ?? null} />;
1851 case "people":
1852 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)1853 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.1854 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)1855 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.1856 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)1857 }
1858 };
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1859 // The sidebar's top row: the workspace and its switcher, and the way to fold the sidebar or close the drawer.
1860 const sidebarTop = (inDrawer: boolean) => (
1861 <div className="flex h-14 shrink-0 items-center gap-1 pr-1 pl-1">
1862 {ws ? (
1863 <WorkspaceSwitcher user={user} workspace={ws} />
1864 ) : (
1865 <Link to="/" aria-label="g1t" className="mr-auto flex h-9 items-center rounded-md px-2">
1866 <Logo className="text-[1.125rem]" />
1867 </Link>
1868 )}
1869 {inDrawer ? (
1870 <button type="button" aria-label="Close menu" onClick={() => setDrawer(false)} className="flex size-8 shrink-0 items-center justify-center rounded-md text-faint hover:bg-raised hover:text-fg">
1871 <X size={16} />
1872 </button>
1873 ) : (
1874 <SidebarToggle open onClick={toggleSidebar} />
1875 )}
1876 </div>
1877 );
1878
1879 // 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)1880 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.1881 // Where the page panel starts: 8px past the dock (88px), or right after the sidebar (260px) when it is open.
1882 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";
1883 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 to1884
Docs: automations1885 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.1886 // The drawer is a sheet: a dialog that holds focus, closes on Escape or
1887 // a tap outside, and gives focus back to the button that opened it.
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1888 <Sheet open={drawer} onOpenChange={setDrawer}>
Docs: automations1889 <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.1890 {ws && (
1891 <div className="fixed top-2 bottom-2 left-2 z-40 hidden w-20 md:block">
1892 <Dock
1893 workspace={ws}
1894 pins={shell.pins ?? []}
1895 unread={unread}
1896 account={<AccountMenu user={user} />}
1897 />
1898 </div>
1899 )}
1900 {panel && (
1901 <aside
1902 aria-label={`${MODE_MENU[panel]} sidebar`}
1903 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" : ""}`}
1904 >
1905 {sidebarTop(false)}
1906 <div className="min-h-0 grow">{sidebarNode()}</div>
1907 </aside>
1908 )}
Chat and workspace agents: channels, DMs and named agents you talk to1909 <SheetContent
1910 side="left"
1911 showClose={false}
1912 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.1913 // 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)1914 onOpenAutoFocus={(event) => {
1915 event.preventDefault();
1916 (event.currentTarget as HTMLElement | null)?.focus();
1917 }}
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.1918 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 to1919 >
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.1920 <SheetTitle className="sr-only">{panel ? `${MODE_MENU[panel]} menu` : "Menu"}</SheetTitle>
1921 {sidebarTop(true)}
1922 <div className="min-h-0 grow">{sidebarNode()}</div>
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1923 </SheetContent>
Docs: automations1924
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1925 <div className={`min-h-dvh px-1.5 pt-(--frame-top) pb-(--tabbar-h) md:pr-2 ${pad}`}>
1926 <div className="flex min-h-[calc(100dvh-var(--frame-top)-var(--tabbar-h))] min-w-0 flex-col rounded-[14px] bg-bg">
1927 <header
1928 className={`sticky top-(--frame-top) z-30 flex h-14 items-center gap-1.5 rounded-t-[14px] border-b border-line bg-bg pr-2 pl-2 sm:gap-2 sm:pr-3 ${conversation ? "max-md:hidden" : ""}`}
Docs: automations1929 >
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.1930 {panel && (
1931 <SidebarToggle open={drawer} onClick={toggleSidebar} className={inline ? "lg:hidden" : ""} />
1932 )}
1933 {ws && (
1934 <span className={`flex min-w-0 shrink items-center gap-1.5 ${inline ? "lg:hidden" : ""}`}>
1935 <WorkspaceSwitcher user={user} workspace={ws} compact />
1936 <span aria-hidden="true" className="text-line-strong">
1937 /
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)1938 </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.1939 </span>
Inbox: a bell in the top bar opens it beside the page, and /inbox holds it all1940 )}
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.1941 <Breadcrumbs pathname={pathname} missing={missing} repo={shell.repo} workspace={ws?.slug ?? null} />
1942 <div className="ml-auto flex shrink-0 items-center gap-1.5">
1943 <button
1944 type="button"
1945 aria-label="Search or jump to"
1946 onClick={() => setPalette(true)}
1947 className="flex h-8 items-center gap-2 rounded-md text-faint transition-colors hover:text-muted max-md:w-8 max-md:justify-center max-md:hover:bg-raised md:w-[min(17rem,26vw)] md:border md:border-line md:bg-surface md:px-2.5 md:hover:border-line-strong"
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put1948 >
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 <Search size={15} className="shrink-0" />
1950 <span className="hidden grow truncate text-left text-[0.8125rem] md:inline">Search or jump to</span>
1951 <PaletteKey className="hidden rounded bg-raised px-1.5 font-mono text-[0.625rem] text-muted ring-1 ring-line md:inline" />
1952 </button>
1953 {ws && <AskG1tButton slug={ws.slug} />}
1954 {/* On a phone, Notifications is in the bottom bar. */}
1955 <span className="max-md:hidden">
1956 <NotificationsBell counts={shell.inbox ? { ...shell.inbox, unread: notificationsUnread } : null} />
1957 </span>
1958 <CreateMenu shell={shell} />
1959 {/* Without a workspace there is no dock: the account is here. */}
1960 {!ws && <AccountMenu user={user} side="bottom" />}
1961 </div>
1962 </header>
1963 {banner}
1964 <main id="content" tabIndex={-1} {...leaving} className={`min-w-0 grow outline-none ${leaving.className}`}>
1965 <InMain.Provider value={true}>{children}</InMain.Provider>
1966 </main>
1967 </div>
Docs: automations1968 </div>
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.1969 {/* The panel's edge: a rounded frame over the page, with the background beyond it, so what scrolls stays inside. */}
1970 {!conversation && (
1971 <div
1972 aria-hidden="true"
1973 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}`}
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 bar1974 />
1975 )}
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.1976 {ws && <BottomBar user={user} workspace={ws} pins={shell.pins ?? []} unread={unread} onReselect={panel ? () => setDrawer(true) : undefined} />}
1977 <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 audit1978 </Sheet>
Docs: automations1979 );
1980}
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/** Create new: a project, an issue in the one you are in, a workspace or a team. */
1983function CreateMenu({ shell }: { shell: ShellData }) {
1984 return (
1985 <DropdownMenu>
1986 <Hint label="Create new">
1987 <DropdownMenuTrigger
1988 aria-label="Create new"
1989 className="flex h-8 items-center gap-1 rounded-md border border-line px-1.5 text-fg/90 outline-none transition-colors hover:border-line-strong hover:bg-raised hover:text-fg focus-visible:ring-2 focus-visible:ring-accent data-[state=open]:bg-raised sm:px-2"
1990 >
1991 <Plus size={16} />
1992 <ChevronDown size={13} className="text-muted max-sm:hidden" />
1993 </DropdownMenuTrigger>
1994 </Hint>
1995 <DropdownMenuContent align="end" className="min-w-52">
1996 {shell.repo && (
1997 <>
1998 <DropdownMenuLabel className="truncate">In {shell.repo.name}</DropdownMenuLabel>
1999 <DropdownMenuItem asChild>
2000 <Link to={`/${shell.repo.namespace}/${shell.repo.name}/issues/new`}>
2001 <CircleDot />
2002 New issue
2003 </Link>
2004 </DropdownMenuItem>
2005 {shell.repo.member && (
2006 <DropdownMenuItem asChild>
2007 <Link to={`/${shell.repo.namespace}/${shell.repo.name}/plans`}>
2008 <ListTree />
2009 Plan work
2010 </Link>
2011 </DropdownMenuItem>
2012 )}
2013 <DropdownMenuSeparator />
2014 </>
2015 )}
2016 <DropdownMenuItem asChild>
2017 <Link to="/?agent=new">
2018 <Sparkles />
2019 Put an agent on it
2020 </Link>
2021 </DropdownMenuItem>
2022 <DropdownMenuItem asChild>
2023 <Link to="/new">
2024 <Box />
2025 New project
2026 </Link>
2027 </DropdownMenuItem>
2028 <DropdownMenuItem asChild>
2029 <Link to="/new/github">
2030 <GitBranch />
2031 Import from GitHub
2032 </Link>
2033 </DropdownMenuItem>
2034 <DropdownMenuSeparator />
2035 <DropdownMenuItem asChild>
2036 <Link to="/workspaces/new">
2037 <Users />
2038 New workspace
2039 </Link>
2040 </DropdownMenuItem>
2041 {/* A team in the workspace you are in, for whoever it lets create one. */}
2042 {shell.workspace &&
2043 (mayCreateTeams(shell.workspace.team_creation, shell.workspace.role) ? (
2044 <DropdownMenuItem asChild>
2045 <Link to={`/${shell.workspace.slug}/-/teams/new`}>
2046 <UsersRound />
2047 New team
2048 </Link>
2049 </DropdownMenuItem>
2050 ) : (
2051 <DropdownMenuItem disabled>
2052 <UsersRound />
2053 New team
2054 <span className="ml-auto pl-3 text-xs text-faint">Owners only</span>
2055 </DropdownMenuItem>
2056 ))}
2057 </DropdownMenuContent>
2058 </DropdownMenu>
2059 );
2060}

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