Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh
2,213 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.

Merge branch 'worktree-agent-aefe9db9851cfafd8'1import { Activity, BarChart3, Building2, MessagesSquare, Bell, BookMarked, BookOpen, Bookmark, Blocks, Box, Brain, Check, ChevronDown, ChevronLeft, ChevronRight, CircleDot, GripVertical, CircleUserRound, Code2, Compass, CreditCard, Fingerprint, Gauge, GitBranch, GitPullRequest, Globe, History, Keyboard, KeyRound, Layers, LayoutDashboard, LayoutGrid, LifeBuoy, Lock, LogOut, Mail, MonitorCog, MonitorDown, Package, PlayCircle, Plug, Plus, Rocket, Search, ServerCog, Settings, Shapes, Shield, ShieldCheck, Scale, Smile, Sparkles, Star, House, TrendingUp, UserRoundKey, Users, UsersRound, Webhook, X } from "lucide-react";
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.2import { Fragment, type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from "react";
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.3import { Link, useFetcher, useLocation, useNavigation, useRouteLoaderData, useSubmit } from "react-router";
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists4
Merge main into rm-agents: mirroring removal, open signups, free-tier limits, the g1t CLI and runner fixes, with the agent removal kept. The CLI's table of operations is regenerated from the API without the agent, customize and AI credit operations; no CLI command used them.5import { type Abilities, type ChatSidebarEntry, type InboxCounts, type Membership, type Spike, type User, hasCodeAccess, mayCreateTeams, shownUsername } from "@g1t/contracts";
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists6
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";
Every page loads again: the top bar's Ask loads its panel the first time it is wanted instead of with every page. The shell imported the whole answer stack (AI Elements, Streamdown and its highlighter, the chat helpers) for the Ask panel, and the bundler's shared groups put the chat chunk and the shell's chunk each importing the other; a page that loaded the chat chunk first ran the shell's module before the chat chunk had finished, and its repository tabs read an array still undefined (`Cannot read properties of undefined (reading 'flatMap')`). components/ask-button.tsx is the button alone, in the shell; the panel (components/ask-composer.tsx, now AskSheet) is a lazy chunk, fetched when the pointer comes near the button or it takes focus, shown with a skeleton until it arrives, and kept mounted once loaded so the conversation stays while it is closed. A question asked from the panel also says the browser's time zone. Checked: a production build of the site has no import cycle between those two chunks any more (scripted over the built chunks), the site's typecheck and its 888 tests.9import { AskButton } from "./ask-button";
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.10import { NotificationsBell } from "./inbox";
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r911import { desktopBridge, useDesktopApp, useTitleBarSearch } from "../lib/notify-client";
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar12import { PinButton } from "./pin-button";
Merge branch 'worktree-agent-ae1299e92e4462012'13import { Hint } from "./ui/hint";
Workspace is the workspace's settings, in one place. Its sidebar is grouped, General, Access, Money, Compute, Code, Agents, Chat, Artifacts, Security and Integrations, every page one click away with no settings inside settings, the groups folding and the owner-only pages hidden from members; what is not here yet is marked Soon with a hint. Members is a list with search and filters for role, two-factor and team, and Invite opens a dialog: who, by username, name or email, their role and a note that goes into the invitation; nothing is filled in inline any more. Invitations is its own page with All, Pending, Accepted, Declined, Expired and Revoked filters that say how many, and each row's menu can copy the link, send it again or revoke it; identity learned to send an invitation again and to carry the note. Permissions gathers every rule about who may do what, by part: Code's base permission and member privileges, who creates teams, who creates channels, and, marked Soon with what applies today, forking private repositories, adding agents to conversations, messaging agents directly, creating spaces and default sharing, creating workspace agents and raising budgets, deploying to production and publishing packages. General lost what moved. The permissions guide is new, and the workspaces, people and teams, access, chat, teams, authentication and billing guides say where things are now.14import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "./ui/collapsible";
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.15import {
16 Sidebar,
17 SidebarGroup,
18 SidebarGroupAction,
19 SidebarGroupContent,
20 SidebarGroupLabel,
21 SidebarHeader,
22 SidebarMenu,
23 SidebarMenuBadge,
24 SidebarMenuButton,
25 SidebarMenuItem,
26 SidebarMobile,
27 SidebarProvider,
28 SidebarSeparator,
29 SidebarTrigger,
30} from "./ui/sidebar";
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists31import { StatusDot, useSiteStatus } from "./footer";
The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404.32import { Logo } from "./logo";
The site is built from its shared components: one Button with its variants and sizes, one Badge, Card for every panel, Alert for notices, Kbd for keys, Table for the security tables, and Avatar, Command, Progress, ScrollArea, ToggleGroup, Collapsible and Accordion in the kit; raw buttons, hand-drawn cards and pills and per-file button class lists are gone, outline buttons stand the same height as filled ones, and the phone's Ask g1t loses its tile. Every page was compared pixel by pixel before and after.33import { SoonPill } from "./ui";
34import { Avatar } from "./ui/avatar";
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists35import { Skeleton } from "./ui/skeleton";
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.36import { Button } from "./ui/button";
37import { Separator } from "./ui/separator";
38import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from "./ui/breadcrumb";
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists39import {
40 DropdownMenu,
41 DropdownMenuContent,
42 DropdownMenuGroup,
43 DropdownMenuItem,
44 DropdownMenuLabel,
45 DropdownMenuSeparator,
46 DropdownMenuTrigger,
47} from "./ui/dropdown-menu";
Merge branch 'worktree-agent-ad7c6d88d93adc817'48import { type RoadmapItem, roadmapIn, roadmapItem } from "../lib/roadmap";
Merge branch 'worktree-agent-aefe9db9851cfafd8'49import {
50 type BrowsedOwner,
51 type ModeKey,
52 WORKSPACE_SETTINGS_GROUPS,
53 type WorkspaceSettingsPage,
54 browsingOf,
55 homePagePath,
56 modeOf,
57 pagePath,
58 workspaceSettingsPage,
59} from "../lib/workspace-nav";
Chat and workspace agents: channels, DMs and named agents you talk to60import { 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.61import { FoliosSidebar } from "./folios/sidebar";
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.62import { Rail, ShortcutsDialog, WorkspaceSwitcher, sidebarKeyLabel } from "./rail";
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.63import { BottomBar, isConversation, useVisualViewport } from "./mobile";
Chat and workspace agents: channels, DMs and named agents you talk to64import { useChatSidebar } from "./chat/actions";
65import { unreadTotals } from "../lib/chat";
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists66import { 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.67import { projectPages } from "../lib/chrome";
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists68import { 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.69import { type PinnableApp, sidebarCookie } from "../lib/apps";
70import { REASON_FILTERS, inboxReason, inboxView } from "../lib/inbox";
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists71import { GithubMark } from "./github";
72import { STATUS_URL, statusTitle } from "../lib/status";
Navigation: the workspace's own page with tabs, pins and recent in the sidebar73import { type ShortcutProject, movedPin, recentWith } from "../lib/pins";
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists74import 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)75import { 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 managers76import { 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.77import { THEME_COMMANDS, ThemeMenuSwitch } from "./theme-switch";
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists78
79/**
80 * What the sidebar needs, worked out by the root loader. For a visitor who
81 * is not signed in there is no workspace, no projects and no usage: only
82 * the project being looked at, if they can see it.
83 */
84export type ShellData = {
85 /** The workspace the sidebar is about: the one being looked at, or their first. */
86 workspace: Membership | null;
Navigation: the workspace's own page with tabs, pins and recent in the sidebar87 /** All its projects, by name, for the palette: `name` is the slug in their address. */
88 repos: ShortcutProject[];
89 /** The person's pinned projects in it, in their order (lib/pins.ts). */
90 pinned?: ShortcutProject[];
91 /** What they opened there last, latest first, leaving out the pinned. */
92 recent?: ShortcutProject[];
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists93 /** Repositories shared with them in workspaces they do not belong to. */
94 shared?: { namespace: string; name: string; isPrivate: boolean }[];
95 /** The project being looked at, if any, whoever owns it. */
96 repo: {
97 namespace: string;
98 name: string;
99 member: boolean;
100 issues: number;
101 pulls: number;
102 } | null;
103 /** Where the workspace stands against its usage limit, if billing is on. */
104 limit: {
105 exposureMicros: number;
106 ceilingMicros: number | null;
107 state: "ok" | "warning" | "stopped";
108 comped: boolean;
109 } | null;
110 /** Whether g1t charges nothing for now, while it is being built out. */
111 free?: boolean;
112 /** This month's usage: charged, or at cost while g1t is free. */
113 monthUsageMicros: number | null;
114 /** Whether new compute is paused (a spend spike or a hold), and whether the viewer can answer it. */
115 compute?: { paused: string | null; spike: Spike | null; owner: boolean } | null;
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.116 /** What is unread in their notifications, for the rail and the bell. Absent for a visitor. */
Inbox: a bell in the top bar opens it beside the page, and /inbox holds it all117 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)118 /**
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.119 * Chat, for the rail'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)120 * starred and latest conversations. Null when chat did not answer in time.
121 */
122 chat?: { unread: number; mentions: number; starred?: ChatSidebarEntry[]; recent?: ChatSidebarEntry[] } | null;
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.123 /** The apps this person pinned to their rail in the workspace (lib/apps.ts). */
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.124 pins?: PinnableApp[];
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists125};
126
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.127/** Whether `pathname` is `to` or a page under it (`end`: only `to` itself), the query left aside. */
128function under(pathname: string, to: string, end = false): boolean {
129 const path = to.split("?")[0]!;
130 return pathname === path || (!end && pathname.startsWith(path.endsWith("/") ? path : `${path}/`));
131}
132
133/**
134 * Where a row is current and where it is on its way to. A row's page is
135 * current under its own address and any `also` prefix, unless the list
136 * says itself (`current`). Rows that differ by query alone (Notifications'
137 * views and reasons) are pending only when the page on its way is that
138 * row's, query and all.
139 */
140function useRowState(to: string, { end, also, current: lit }: { end?: boolean; also?: string | string[]; current?: boolean }) {
141 const { pathname } = useLocation();
142 const going = useNavigation().location;
143 const current = lit ?? (under(pathname, to, end) || [also ?? []].flat().some((prefix) => under(pathname, prefix)));
144 const pending =
145 going != null && !current && (lit === undefined ? under(going.pathname, to, end) : `${going.pathname}${going.search}` === to);
146 return { current, pending };
147}
148
149/**
150 * One row of a mode's sidebar: an icon, its words, how many it lists
151 * (`count`) and, for a row that opens a list of its own (`drill`), a
152 * chevron, always or on hover.
153 */
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists154function SidebarLink({
155 to,
156 icon,
157 end,
158 count,
159 also,
160 drill,
Merge branch 'worktree-agent-ad7c6d88d93adc817'161 current: lit,
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.162 action,
163 bare = false,
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists164 children,
165}: {
166 to: string;
167 icon: ReactNode;
168 end?: boolean;
169 count?: number;
170 /** Other path prefixes under which this link is the current one. */
171 also?: string | string[];
172 /** It opens a list of its own: a chevron says so, always or on hover. */
173 drill?: boolean | "hover";
Merge branch 'worktree-agent-ad7c6d88d93adc817'174 /** Whether it is the current row, when the list works that out itself. */
175 current?: boolean;
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.176 /** A small button at the row's end, beside the words (a pin). */
177 action?: ReactNode;
178 /** The row alone, for a list item that is drawn by the list (a pinned project, which drags). */
179 bare?: boolean;
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists180 children: ReactNode;
181}) {
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.182 const { current, pending } = useRowState(to, { end, also, current: lit });
183 const Item = bare ? Fragment : SidebarMenuItem;
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists184 return (
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.185 <Item>
186 <SidebarMenuButton asChild isActive={current} isPending={pending} className={action ? "pr-7" : undefined}>
187 <Link to={to} prefetch="intent" aria-current={current ? "page" : undefined}>
188 {icon}
189 <span className="min-w-0 grow truncate">{children}</span>
190 {count != null && count > 0 && <SidebarMenuBadge>{count}</SidebarMenuBadge>}
191 {drill && (
192 <ChevronRight
193 aria-hidden="true"
194 className={`-mr-0.5 size-3.5! shrink-0 text-faint transition-opacity ${drill === "hover" ? "opacity-0 group-hover/menu-button:opacity-100 group-focus-visible/menu-button:opacity-100" : ""}`}
195 />
196 )}
197 </Link>
198 </SidebarMenuButton>
199 {action}
200 </Item>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists201 );
202}
203
204/**
205 * A page that is coming, as a link to its roadmap page: faint, with Soon,
206 * and marked current on any of its section's Soon pages.
207 */
208function SidebarSoonLink({
209 to,
210 also,
211 icon,
212 about,
Merge branch 'worktree-agent-ad7c6d88d93adc817'213 current: lit,
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists214 children,
215}: {
216 to: string;
217 also?: string[];
218 icon: ReactNode;
219 about: string;
Merge branch 'worktree-agent-ad7c6d88d93adc817'220 /** Whether it is the current row, when the list works that out itself. */
221 current?: boolean;
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists222 children: ReactNode;
223}) {
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.224 const { current, pending } = useRowState(to, { also, current: lit });
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists225 return (
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.226 <SidebarMenuItem>
227 <Hint label={about} side="right">
228 <SidebarMenuButton asChild variant="faint" isActive={current} isPending={pending}>
229 <Link to={to} prefetch="intent" aria-current={current ? "page" : undefined}>
230 {icon}
231 <span className="min-w-0 grow truncate">{children}</span>
232 <SoonPill />
233 </Link>
234 </SidebarMenuButton>
235 </Hint>
236 </SidebarMenuItem>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists237 );
238}
239
240/** The Soon pages of a section, as paths, so its link is current on them. */
241function soonPaths(base: string, section: RoadmapItem["section"]): string[] {
242 return roadmapIn(section).map((item) => `${base}/soon/${item.key}`);
243}
244
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.245/** A titled group of rows: its name in small capitals, what it makes at the end, and its menu. */
246function NavGroup({
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists247 title,
248 action,
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.249 className,
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists250 children,
251}: {
252 title: string;
The phone app: Chat in full with phone notifications, plus Code and Customize (#4)253 /** A small button at the label's end, in its row: what the group makes (a `SidebarGroupAction` with `relative top-auto right-auto`). */
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists254 action?: ReactNode;
255 className?: string;
256 children: ReactNode;
257}) {
258 return (
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.259 <SidebarGroup className={className}>
The phone app: Chat in full with phone notifications, plus Code and Customize (#4)260 <div className="flex items-center justify-between gap-2 pr-1">
261 <SidebarGroupLabel asChild>
262 <h2>{title}</h2>
263 </SidebarGroupLabel>
264 {action}
265 </div>
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.266 <SidebarGroupContent>
267 <SidebarMenu>{children}</SidebarMenu>
268 </SidebarGroupContent>
269 </SidebarGroup>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists270 );
271}
272
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.273/** Rows with no name over them: the first of a list, or a run between rules. */
274function NavRows({ className, children }: { className?: string; children: ReactNode }) {
275 return (
276 <SidebarGroup className={className}>
277 <SidebarGroupContent>
278 <SidebarMenu>{children}</SidebarMenu>
279 </SidebarGroupContent>
280 </SidebarGroup>
281 );
282}
283
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists284/** What a workspace is called where people read it: its display name, else its slug. */
285function displayName(membership: Membership): string {
286 return membership.name?.trim() || membership.slug;
287}
288
289/**
290 * The fine print, as one quiet row at the foot of the account menu and the
291 * visitor's panel: each link a full-height target, left-aligned. In the
292 * menu each is a menu item, so the arrow keys reach it.
293 */
294const LEGAL_LINKS: [string, string][] = [
295 ["Policies", "/policies"],
296 ["Privacy", "/policies/privacy"],
297 ["Security", "/security"],
298];
299const LEGAL_LINK = "flex h-7 items-center rounded px-1.5 text-xs text-faint outline-none transition-colors";
300
301function MenuLegalRow() {
302 return (
303 <div role="group" aria-label="Legal" className="flex items-center gap-0.5 px-0.5 pt-0.5">
304 {LEGAL_LINKS.map(([label, to], index) => (
305 <span key={to} className="flex items-center gap-0.5">
306 {index > 0 && (
307 <span aria-hidden="true" className="text-[0.625rem] text-line-strong">
308 ·
309 </span>
310 )}
311 <DropdownMenuItem asChild className={`${LEGAL_LINK} py-0 data-highlighted:bg-line data-highlighted:text-fg`}>
312 <Link to={to}>{label}</Link>
313 </DropdownMenuItem>
314 </span>
315 ))}
316 </div>
317 );
318}
319
320/** Status's row: the live dot and two or three words, fetched when the menu opens. */
321function StatusSummary({ open }: { open: boolean }) {
322 const status = useSiteStatus(open);
323 const words = statusTitle(status);
324 return (
325 <span className="ml-auto flex min-w-0 items-center gap-1.5 pl-2 text-xs text-faint">
326 {/* The words say it; the dot's own words for screen readers would repeat them. */}
327 <span aria-hidden="true" className="flex">
328 <StatusDot state={status?.overall.state ?? null} />
329 </span>
330 {words ? <span className="truncate">{words}</span> : <Skeleton className="h-3 w-20" />}
331 </span>
332 );
333}
334
335/** A menu row: an icon, words, and whatever sits at its end. */
336const MENU_ROW = "h-9 gap-2.5 px-2.5 text-[0.8125rem]";
337
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.338/**
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.339 * Your account, at the foot of the rail (or in the header, before you have
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.340 * a workspace): who you are and your status, your profile and settings,
341 * and help: the documentation, support, status and the keyboard's
342 * shortcuts; then signing out and the fine print.
343 */
344function AccountMenu({ user, side = "right" }: { user: User; side?: "right" | "bottom" }) {
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists345 const submit = useSubmit();
346 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.347 const [keys, setKeys] = useState(false);
preparing for cloud work348 // Inside the desktop app there is nothing to get.
349 const inApp = useDesktopApp();
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers350 // Your status's dialog: outside the menu, so the menu closes behind it.
351 const [editing, setEditing] = useState(false);
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists352 // Name, primary address and invites left: asked for once, as soon as the
353 // pointer or focus reaches the button, so they are there when it opens.
354 const details = useFetcher<AccountMenuData | null>({ key: "account-menu" });
355 const prefetch = () => {
356 if (details.state === "idle" && details.data === undefined) details.load("/settings/menu.json");
357 };
358 useEffect(() => {
359 if (open) prefetch();
360 // eslint-disable-next-line react-hooks/exhaustive-deps
361 }, [open]);
362 const me = details.data ?? null;
363 // Still on its way: shapes where the words will be, the same size.
364 const loading = details.data === undefined && details.state !== "idle";
365 const profile = `/u/${user.username}`;
366 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 managers367 <>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists368 <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.369 {/* The avatar alone, with a dot that says how others see you (components/presence.tsx). */}
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.370 <Hint label={side === "right" ? "Your account" : undefined} side="right">
371 <DropdownMenuTrigger
372 aria-label={`Account menu for ${shownUsername(user)}`}
373 onPointerEnter={prefetch}
374 onFocus={prefetch}
375 className={
376 side === "right"
377 ? // At the foot of the rail: a 40px rounded square, as the rail's icons are.
378 "relative flex size-10 items-center justify-center rounded-[10px] outline-none transition-colors hover:bg-sidebar-accent focus-visible:ring-2 focus-visible:ring-accent data-[state=open]:bg-sidebar-accent"
379 : "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"
380 }
381 >
382 <Avatar name={user.username} image={user.avatar} size={side === "right" ? 40 : 28} square={side === "right"} />
383 <OwnPresenceDot ring={side === "right" ? "var(--color-rail)" : "var(--color-bg)"} className={side === "right" ? "absolute -right-1 -bottom-1" : "absolute -right-0.5 -bottom-0.5"} />
384 </DropdownMenuTrigger>
385 </Hint>
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r9386 <DropdownMenuContent align="end" side={side} sideOffset={side === "right" ? 14 : 6} collisionPadding={8} className="w-70 p-1.5">
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists387 {/* Who is signed in, and a way to their profile. */}
388 <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 managers389 <Link to={profile} aria-label={`${me?.name ?? shownUsername(user)} (@${shownUsername(user)}), your profile`}>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists390 <Avatar name={user.username} image={user.avatar} size={36} />
391 <span className="flex min-w-0 grow flex-col leading-tight" aria-busy={loading}>
392 {loading ? (
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r9393 <Skeleton className="my-0.75 h-3.5 w-28" />
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists394 ) : (
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers395 <span className="truncate text-sm font-medium text-fg">{me?.name ?? shownUsername(user)}</span>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists396 )}
One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers397 <span className="truncate font-mono text-xs text-muted">@{shownUsername(user)}</span>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists398 {loading ? (
399 <Skeleton className="mt-1 h-3 w-40" />
400 ) : (
401 me?.email && <span className="mt-0.5 truncate text-xs text-faint">{me.email}</span>
402 )}
403 </span>
404 </Link>
405 </DropdownMenuItem>
406 <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 managers407 {/* Your status, away, and pausing notifications. */}
408 <DropdownMenuGroup>
409 <OwnPresenceItems className="min-h-9 py-1.5 text-[0.8125rem]" onEdit={() => setEditing(true)} />
410 </DropdownMenuGroup>
411 <DropdownMenuSeparator className="my-1.5" />
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists412 <DropdownMenuGroup>
413 <DropdownMenuItem asChild className={MENU_ROW}>
414 <Link to={profile}>
415 <CircleUserRound />
416 Your profile
417 </Link>
418 </DropdownMenuItem>
419 <DropdownMenuItem asChild className={MENU_ROW}>
420 <Link to={FIRST_SETTINGS_PAGE}>
421 <Settings />
422 Your settings
423 </Link>
424 </DropdownMenuItem>
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r9425 {/* The app's own: starting with the computer, closing to the tray, the badge (apps/desktop). */}
426 {inApp && desktopBridge()?.openSettings && (
427 <DropdownMenuItem className={MENU_ROW} onSelect={() => desktopBridge()?.openSettings?.()}>
428 <MonitorCog />
429 Desktop app settings
430 </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)431 )}
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists432 </DropdownMenuGroup>
433 <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.434 {/* Auto, Light or Dark, switched in place (lib/theme.ts). */}
435 <ThemeMenuSwitch />
436 <DropdownMenuSeparator className="my-1.5" />
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists437 <DropdownMenuGroup>
438 <DropdownMenuItem asChild className={MENU_ROW}>
439 <a href="https://docs.g1t.sh/">
440 <BookOpen />
441 Documentation
442 </a>
443 </DropdownMenuItem>
444 <DropdownMenuItem asChild className={MENU_ROW}>
445 <Link to="/support">
446 <LifeBuoy />
447 Support
448 </Link>
449 </DropdownMenuItem>
450 <DropdownMenuItem asChild className={MENU_ROW}>
451 <a href={STATUS_URL}>
452 <Activity />
453 Status
454 <StatusSummary open={open} />
455 </a>
456 </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.457 <DropdownMenuItem className={MENU_ROW} onSelect={() => setKeys(true)}>
458 <Keyboard />
459 Keyboard shortcuts
460 <PaletteKey className="ml-auto font-sans text-xs text-faint" />
461 </DropdownMenuItem>
preparing for cloud work462 {!inApp && (
463 <DropdownMenuItem asChild className={MENU_ROW}>
464 <Link to="/download">
465 <MonitorDown />
466 Get the desktop app
467 </Link>
468 </DropdownMenuItem>
469 )}
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists470 </DropdownMenuGroup>
471 <DropdownMenuSeparator className="my-1.5" />
472 {/* Submitted from here: the menu closes on select, and a button
473 that has left the page cannot submit a form. */}
474 <DropdownMenuItem className={MENU_ROW} onSelect={() => submit(null, { method: "post", action: "/logout" })}>
475 <LogOut />
476 Sign out
477 </DropdownMenuItem>
478 <DropdownMenuSeparator className="my-1.5" />
479 <MenuLegalRow />
480 </DropdownMenuContent>
481 </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 managers482 <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.483 <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 managers484 </>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists485 );
486}
487
488/** A project's settings pages, which the project's menu drills into. */
489const REPO_SETTINGS_PAGE = /^\/([^/]+)\/([^/-][^/]*)\/settings(\/|$)/;
490
491/**
492 * The sidebar's lists are a stack, the way a phone pushes a screen: one
493 * drilled into slides in from the right over the full width, while the one
494 * it covers drifts a quarter of the way left and fades, both on one long
495 * ease-out, the fade quicker than the move so the two never blur together.
496 * Going back reverses it.
497 */
498const LAYER =
499 "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";
500/** One list, filling its layer. */
People wear their own avatars wherever g1t knows them only by name, and a workspace is never shown as a person. The activity feeds, recent changes, home's most active faces, issue and pull request authors, assignees, comments and the audit log drew a person from their username alone, so everyone got their letter avatar instead of the picture they uploaded. An avatar given no picture now draws the letter at once and lays the person's own picture over it once it loads, from /-/avatar/user/<username> (routes/avatar-user.ts): a redirect to the picture on the usercontent origin, or not found, read from identity's people only, so a workspace's icon can never stand in for someone. Kept five minutes, public like the profile. Agents, the product tour's people, "someone" and workspaces' square avatars are never looked up (image null), so an account with the same name never lends them its face.501const PANEL = "h-full overflow-y-auto px-1 pt-1 pb-4 scrollbar-thin";
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists502
503/** One list in the stack: what it is, and its rows. */
504type Level = { key: string; node: ReactNode };
505
506/** True once the page has hydrated, so what the server drew never animates in. */
507function useHydrated(): boolean {
508 const [hydrated, setHydrated] = useState(false);
509 useEffect(() => setHydrated(true), []);
510 return hydrated;
511}
512
513/**
514 * Drilling in and out of the sidebar's lists. `trail` is the way from the
515 * main list to the one shown, worked out from the address, so a link
516 * straight to a settings page opens the sidebar already drilled in, and
517 * leaving it comes back out. Lists deeper than the one shown stay in
518 * place, off to the right, so going back slides them away rather than
519 * dropping them. Moving to a list at the same depth (a workspace's settings
520 * to a project) fades the new one in where it is.
521 */
522function Drill({ trail }: { trail: Level[] }) {
523 const depth = trail.length - 1;
524 const hydrated = useHydrated();
525 const stack = useRef<Level[]>(trail);
526 const before = stack.current;
527 const within = trail.every((level, index) => before[index]?.key === level.key);
528 stack.current = within ? [...trail, ...before.slice(trail.length)] : trail;
529 const levels = stack.current;
530 // What was showing last time, to tell drilling in from moving across.
531 const shown = useRef({ depth, keys: levels.map((level) => level.key) });
532 useEffect(() => {
533 shown.current = { depth, keys: levels.map((level) => level.key) };
534 });
535 return (
536 <div className="relative min-h-0 grow overflow-hidden">
537 {levels.map((level, index) => {
538 const current = index === depth;
539 const place =
540 index < depth
541 ? "pointer-events-none -translate-x-1/4 opacity-0"
542 : current
543 ? "translate-x-0 opacity-100"
544 : "pointer-events-none translate-x-full opacity-0";
545 // A list that was not there before arrives: from the right when
546 // drilling in, in place when moving across.
547 const arriving = hydrated && current && !shown.current.keys.includes(level.key);
548 const enter = arriving
549 ? depth > shown.current.depth
550 ? "starting:translate-x-full starting:opacity-0"
551 : "starting:opacity-0"
552 : "";
553 return (
554 <div key={level.key} className={`${LAYER} ${place} ${enter}`} inert={!current} aria-hidden={!current || undefined}>
555 {level.node}
556 </div>
557 );
558 })}
559 </div>
560 );
561}
562
563/**
564 * The row at the top of a list drilled into: the list's name, which goes
565 * back out, and what it belongs to, faint at the end.
566 */
567function BackRow({ to, label, context }: { to: string; label: ReactNode; context?: ReactNode }) {
568 return (
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.569 <NavRows className="mt-1">
570 <SidebarMenuItem>
571 <SidebarMenuButton asChild className="gap-1.5 pl-1 font-medium text-fg">
572 <Link to={to} prefetch="intent">
573 <ChevronLeft className="text-faint transition-transform group-hover/menu-button:-translate-x-0.5 group-hover/menu-button:text-muted" />
574 <span className="min-w-0 shrink-0 truncate">{label}</span>
575 {context && <span className="ml-auto min-w-0 truncate pl-2 font-mono text-[0.6875rem] font-normal text-faint">{context}</span>}
576 </Link>
577 </SidebarMenuButton>
578 </SidebarMenuItem>
579 </NavRows>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists580 );
581}
582
583/** A thin rule between groups of a list. */
584function Rule() {
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.585 return <SidebarSeparator className="my-1.5" />;
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists586}
587
Navigation: the workspace's own page with tabs, pins and recent in the sidebar588/** A quiet heading inside a group: Pinned, Recent. */
589function SidebarSubhead({ children }: { children: ReactNode }) {
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.590 return (
591 <SidebarGroupLabel asChild className="h-6 pt-0.5">
592 <h3>{children}</h3>
593 </SidebarGroupLabel>
594 );
Navigation: the workspace's own page with tabs, pins and recent in the sidebar595}
596
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists597/**
Navigation: the workspace's own page with tabs, pins and recent in the sidebar598 * The workspace's projects as the sidebar keeps them, however many there
599 * are: the person's pins in their order, what they opened last, and the
600 * way to all of them. Pins move by dragging, or with Alt and the arrow
601 * keys; the projects service keeps the order.
602 */
Merge branch 'worktree-agent-ad7c6d88d93adc817'603function SidebarProjects({ slug, shell, current }: { slug: string; shell: ShellData; current: boolean }) {
Navigation: the workspace's own page with tabs, pins and recent in the sidebar604 const reorder = useFetcher({ key: `pins:${slug}` });
605 const saved = shell.pinned ?? [];
606 // While a new order is on its way, it shows as made.
607 const asked = reorder.formData?.get("intent") === "reorder" ? reorder.formData.getAll("slug").map(String) : null;
608 const pinned = asked
609 ? asked.map((name) => saved.find((project) => project.name === name)).filter((project): project is ShortcutProject => project != null)
610 : saved;
611 const active = shell.repo ? { namespace: shell.repo.namespace, name: shell.repo.name, isPrivate: false } : null;
612 const recent = recentWith(shell.recent ?? [], pinned, active, slug);
613 const [dragging, setDragging] = useState<number | null>(null);
614 const move = (from: number, by: number) => {
615 const next = movedPin(pinned, from, by);
616 if (!next) return;
617 const form = new FormData();
618 form.set("intent", "reorder");
619 for (const project of next) form.append("slug", project.name);
620 reorder.submit(form, { method: "post", action: `/${slug}/-/pins` });
621 };
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar622 // Each row pins or unpins in place: the pin shows on hover or focus, and
623 // stays shown on a pinned row's hover so it reads as "unpin".
624 const row = (project: ShortcutProject, isPinned: boolean) => (
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.625 <SidebarLink
626 to={`/${project.namespace}/${project.name}`}
627 icon={project.isPrivate ? <Lock /> : <Box />}
628 bare={isPinned}
Navigation: the workspace's own page with tabs, pins and recent in the sidebar629 action={
A project's pin sits at the end of its row in the sidebar, and shows only on hover or keyboard focus. It was set in from the end to leave room for a chevron that only showed on hover, and it stayed lit after a click, since it showed on any focus and a clicked button keeps the mouse's. The rows drop the chevron; the pin is their hover action.630 // At the row's end, where the row's other actions sit, and only on
631 // hover or keyboard focus: a pin clicked keeps the mouse's focus,
632 // and showing it on any focus left it lit on a row no one was over.
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.633 <PinButton
634 workspace={slug}
635 slug={project.name}
636 name={project.title ?? project.name}
637 pinned={isPinned}
638 small
A project's pin sits at the end of its row in the sidebar, and shows only on hover or keyboard focus. It was set in from the end to leave room for a chevron that only showed on hover, and it stayed lit after a click, since it showed on any focus and a clicked button keeps the mouse's. The rows drop the chevron; the pin is their hover action.639 className="absolute top-1/2 right-1 -translate-y-1/2 opacity-0 transition-opacity group-hover/menu-item:opacity-100 has-focus-visible:opacity-100 [@media(hover:none)]:opacity-100"
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.640 />
Navigation: the workspace's own page with tabs, pins and recent in the sidebar641 }
642 >
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.643 {project.title ?? project.name}
644 </SidebarLink>
645 );
646 return (
647 <SidebarGroup>
The phone app: Chat in full with phone notifications, plus Code and Customize (#4)648 {/* The label and its button share a row, so the button stays level with the words at any text size. */}
649 <div className="flex items-center justify-between gap-2 pr-1">
650 <SidebarGroupLabel asChild>
651 <h2>Projects</h2>
652 </SidebarGroupLabel>
653 <Hint label="New project">
654 <SidebarGroupAction asChild className="relative top-auto right-auto">
655 <Link to="/new" aria-label="New project">
656 <Plus />
657 </Link>
658 </SidebarGroupAction>
659 </Hint>
660 </div>
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.661 <SidebarGroupContent>
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar662 {/* Only there once something is pinned: each row below has its own pin. */}
663 {pinned.length > 0 && (
664 <>
665 <SidebarSubhead>Pinned</SidebarSubhead>
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.666 <SidebarMenu aria-label="Pinned projects">
Navigation: the workspace's own page with tabs, pins and recent in the sidebar667 {pinned.map((project, index) => (
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.668 <SidebarMenuItem
Navigation: the workspace's own page with tabs, pins and recent in the sidebar669 key={project.name}
670 draggable={pinned.length > 1}
671 onDragStart={(event) => {
672 setDragging(index);
673 event.dataTransfer.effectAllowed = "move";
674 }}
675 onDragOver={(event) => {
676 if (dragging != null) event.preventDefault();
677 }}
678 onDrop={(event) => {
679 event.preventDefault();
680 if (dragging != null && dragging !== index) move(dragging, index - dragging);
681 setDragging(null);
682 }}
683 onDragEnd={() => setDragging(null)}
684 onKeyDown={(event) => {
685 if (!event.altKey || (event.key !== "ArrowUp" && event.key !== "ArrowDown")) return;
686 event.preventDefault();
687 move(index, event.key === "ArrowUp" ? -1 : 1);
688 }}
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.689 className={`group/pin ${dragging === index ? "opacity-50" : ""}`}
Navigation: the workspace's own page with tabs, pins and recent in the sidebar690 >
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar691 {row(project, true)}
Navigation: the workspace's own page with tabs, pins and recent in the sidebar692 {pinned.length > 1 && (
Merge branch 'worktree-agent-ae1299e92e4462012'693 <Hint label="Drag, or Alt and an arrow key, to reorder" side="right">
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.694 <span className="absolute top-1/2 -left-2 -translate-y-1/2 cursor-grab text-faint opacity-0 transition-opacity group-hover/pin:opacity-100">
Merge branch 'worktree-agent-ae1299e92e4462012'695 <GripVertical size={12} aria-hidden="true" />
696 </span>
697 </Hint>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar698 )}
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.699 </SidebarMenuItem>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar700 ))}
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.701 </SidebarMenu>
Previews build from any branch; Agent in place of Ask AI; pin from the sidebar702 </>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar703 )}
704 {recent.length > 0 && (
705 <>
706 <SidebarSubhead>Recent</SidebarSubhead>
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.707 <SidebarMenu aria-label="Recent projects">
708 {recent.map((project) => (
709 <Fragment key={`${project.namespace}/${project.name}`}>{row(project, false)}</Fragment>
710 ))}
711 </SidebarMenu>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar712 </>
713 )}
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.714 <SidebarMenu className="pt-1">
715 <SidebarLink to={`/${slug}/-/projects`} icon={<LayoutGrid />} count={shell.repos.length} current={current}>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar716 All projects
717 </SidebarLink>
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.718 </SidebarMenu>
719 </SidebarGroupContent>
Navigation: the workspace's own page with tabs, pins and recent in the sidebar720 </SidebarGroup>
721 );
722}
723
Merge branch 'worktree-agent-ad7c6d88d93adc817'724/** Insights, coming: the workspace's own page says what it will be. */
725const INSIGHTS = roadmapItem("insights");
726
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists727/**
728 * What the repository menu needs. Known from the address before the page's
729 * data arrives, so the menu is right from the first frame; the counts fill
730 * in once it does.
731 */
732type MenuRepo = {
733 namespace: string;
734 name: string;
735 member: boolean;
736 /** Whether they see its settings; from the repository's page once it loads. */
737 settings?: boolean;
738 /** What they may do there, once the repository's page loads. */
739 can?: Abilities;
740 issues?: number;
741 pulls?: number;
742};
743
744function sameRepo(a: { namespace: string; name: string } | null, b: { namespace: string; name: string } | null) {
745 return (
746 a != null &&
747 b != null &&
748 a.namespace.toLowerCase() === b.namespace.toLowerCase() &&
749 a.name.toLowerCase() === b.name.toLowerCase()
750 );
751}
752
753/**
754 * A project's own list, drilled into while you are in it: everything about
755 * the project, running and its code, and nothing else, with the way back
756 * out to all of them.
757 */
758function RepoMenu({
759 repo,
760 isPrivate,
761 back,
762}: {
763 repo: MenuRepo;
764 isPrivate: boolean;
Merge branch 'worktree-agent-aefe9db9851cfafd8'765 /** Where the way back leads: the workspace's projects, mission control, or the projects of the workspace being browsed. */
766 back: { to: string; label: string; context?: string };
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists767}) {
768 const base = `/${repo.namespace}/${repo.name}`;
Merge main into rm-agents: mirroring removal, open signups, free-tier limits, the g1t CLI and runner fixes, with the agent removal kept. The CLI's table of operations is regenerated from the API without the agent, customize and AI credit operations; no CLI command used them.769 // What a member sees, and what everyone who can see the project does
770 // (lib/chrome.ts).
771 const shows = new Set(projectPages(repo.member, repo.can));
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.772 const { current: atOverview, pending: toOverview } = useRowState(base, { end: true });
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists773 return (
774 <nav aria-label={`${repo.namespace}/${repo.name}`} className={PANEL}>
Merge branch 'worktree-agent-aefe9db9851cfafd8'775 <BackRow to={back.to} label={back.label} context={back.context} />
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.776 <NavRows className="mt-1">
777 <SidebarMenuItem>
778 <Hint label="Overview" side="right">
779 <SidebarMenuButton asChild size="lg" isActive={atOverview} isPending={toOverview} className="gap-2 font-normal">
780 <Link to={base} prefetch="intent" aria-current={atOverview ? "page" : undefined}>
781 <span className="flex size-6 shrink-0 items-center justify-center rounded-md bg-raised text-muted ring-1 ring-line [&>svg]:size-3.5">
782 {isPrivate ? <Lock /> : <Box />}
783 </span>
784 <span className="min-w-0 truncate font-mono text-[0.8125rem]">
785 <span className="text-faint">{repo.namespace}/</span>
786 <span className="font-semibold text-fg">{repo.name}</span>
787 </span>
788 </Link>
789 </SidebarMenuButton>
790 </Hint>
791 </SidebarMenuItem>
792 </NavRows>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists793 {/* A project's pages, in the order people use them. A page with more
794 than one view shows them as tabs across its top. */}
795 <Rule />
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.796 <NavRows>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists797 <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} />}>
798 Code
799 </SidebarLink>
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.800 {shows.has("issues") && (
The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404.801 <SidebarLink to={`${base}/issues`} also={[`${base}/milestones`, `${base}/labels`, ...soonPaths(base, "Issues")]} icon={<CircleDot size={15} />} count={repo.issues}>
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.802 Issues
803 </SidebarLink>
804 )}
805 {shows.has("pulls") && (
Merge branch 'worktree-agent-aa68cf6ecc03dffaf'806 <SidebarLink to={`${base}/pulls`} also={[`${base}/pull`, `${base}/work`, `${base}/queue`, `${base}/sessions`]} icon={<GitPullRequest size={15} />} count={repo.pulls}>
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.807 Pull requests
808 </SidebarLink>
809 )}
The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404.810 {repo.member && (
811 <SidebarLink to={`${base}/memory`} icon={<Brain size={15} />}>
812 Memory
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.813 </SidebarLink>
814 )}
815 {shows.has("actions") && (
816 <SidebarLink to={`${base}/actions`} icon={<PlayCircle size={15} />}>
817 Workflows
818 </SidebarLink>
819 )}
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.820 </NavRows>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists821 <Rule />
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.822 <NavRows>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists823 {shows.has("deployments") ? (
824 <SidebarLink to={`${base}/deployments`} also={soonPaths(base, "Deployments")} icon={<Rocket size={15} />}>
825 Deployments
826 </SidebarLink>
827 ) : null}
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.828 {shows.has("observability") && (
Projects have Observability: their requests, logs, traces, metrics and errors, from apps on g1t.page with nothing to set up, and from software anywhere else over OpenTelemetry.829 <SidebarLink to={`${base}/observability`} also={soonPaths(base, "Observability")} icon={<Activity size={15} />}>
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.830 Observability
Projects have Observability: their requests, logs, traces, metrics and errors, from apps on g1t.page with nothing to set up, and from software anywhere else over OpenTelemetry.831 </SidebarLink>
A desktop release goes out with what can be built. Linux is built on g1t's machines in every release; Windows and macOS each wait on a repository variable: a machine registered for them, or for Windows a cross build on Linux once aka.ms and download.visualstudio.microsoft.com are workflow-only domains, which is where the first release stopped. A platform with no machine is skipped and the download page says it is coming, with a word for the visitor whose platform this release lacks. The guide and CONTRIBUTING say so.832 )}
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists833 {shows.has("security") ? (
834 <SidebarLink to={`${base}/security`} also={soonPaths(base, "Security")} icon={<ShieldCheck size={15} />}>
835 Security
836 </SidebarLink>
837 ) : null}
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97838 <SidebarLink
839 to={`${base}/contributors`}
840 also={[`${base}/activity`, `${base}/stargazers`, ...soonPaths(base, "Insights")]}
841 icon={<BarChart3 size={15} />}
842 >
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists843 Insights
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97844 </SidebarLink>
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.845 </NavRows>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists846 {(repo.settings ?? shows.has("settings")) && (
847 <>
848 <Rule />
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.849 <NavRows>
850 <SidebarLink to={`${base}/settings`} icon={<Settings size={15} />} drill>
851 Settings
852 </SidebarLink>
853 </NavRows>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists854 </>
855 )}
856 </nav>
857 );
858}
859
860/**
861 * A project's settings, drilled into from its list: what is about running
The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404.862 * it, then its sandboxes, then its code and who can reach it. The way back
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists863 * leads to the project.
864 */
865function RepoSettingsMenu({ repo }: { repo: MenuRepo }) {
866 const base = `/${repo.namespace}/${repo.name}`;
867 // Each page shows to the roles that can use it, once the role is known.
868 const shows = (page: string) => !repo.can || repo.can[SETTINGS_CAPABILITY[page] ?? "administer"];
869 const running = shows("deployments");
The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404.870 const guarded = shows("guardrails");
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists871 return (
872 <nav aria-label={`${repo.namespace}/${repo.name} settings`} className={PANEL}>
873 <BackRow to={base} label="Settings" context={`${repo.namespace}/${repo.name}`} />
874 {shows("") && (
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.875 <NavRows className="mt-2">
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists876 <SidebarLink to={`${base}/settings`} end icon={<Settings size={15} />}>
877 General
878 </SidebarLink>
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.879 </NavRows>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists880 )}
881 {running && (
882 <>
883 {shows("") && <Rule />}
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.884 <NavRows className={shows("") ? undefined : "mt-2"}>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists885 <SidebarLink to={`${base}/settings/deployments`} icon={<Rocket size={15} />}>
886 Deployments
887 </SidebarLink>
888 <SidebarLink to={`${base}/settings/domains`} icon={<Globe size={15} />}>
889 Domains
890 </SidebarLink>
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.891 </NavRows>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists892 </>
893 )}
The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404.894 {guarded && (
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists895 <>
896 <Rule />
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.897 <NavRows>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists898 {shows("guardrails") && (
899 <SidebarLink to={`${base}/settings/guardrails`} icon={<ShieldCheck size={15} />}>
900 Guardrails
901 </SidebarLink>
902 )}
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.903 </NavRows>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists904 </>
905 )}
906 <Rule />
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.907 <NavRows>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists908 {shows("repository") && (
909 <SidebarLink to={`${base}/settings/repository`} icon={<BookMarked size={15} />}>
910 Repository
Merge branch 'mirroring' into artifacts-mode911 </SidebarLink>
912 )}
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists913 {shows("access") && (
914 <SidebarLink to={`${base}/settings/access`} icon={<Users size={15} />}>
915 Access
916 </SidebarLink>
917 )}
Merge branch 'worktree-agent-a5a5de74d8863d554' into worktree-agent-a16631325aecf58ca918 {shows("keys") && (
919 <SidebarLink to={`${base}/settings/keys`} icon={<KeyRound size={15} />}>
920 Deploy keys
921 </SidebarLink>
922 )}
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists923 {shows("branches") && (
924 <SidebarLink to={`${base}/settings/branches`} icon={<GitBranch size={15} />}>
925 Branches and merging
926 </SidebarLink>
927 )}
Merge rulesets: branch and tag rules, agent-first, enforced on push and merge928 {shows("rules") && (
929 <SidebarLink to={`${base}/settings/rules`} icon={<Scale size={15} />}>
930 Rules
931 </SidebarLink>
932 )}
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists933 {shows("secrets") && (
934 <SidebarLink to={`${base}/settings/secrets`} icon={<Lock size={15} />}>
935 Secrets and variables
936 </SidebarLink>
937 )}
Merge branch 'worktree-agent-a3abfcce648e87dca'938 {shows("actions") && (
939 <SidebarLink to={`${base}/settings/actions`} icon={<PlayCircle size={15} />}>
940 Actions
941 </SidebarLink>
942 )}
943 {shows("environments") && (
944 <SidebarLink to={`${base}/settings/environments`} icon={<Layers size={15} />}>
945 Environments
946 </SidebarLink>
947 )}
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists948 {shows("runners") && (
949 <SidebarLink to={`${base}/settings/runners`} icon={<ServerCog size={15} />}>
950 Runners
951 </SidebarLink>
952 )}
953 {shows("webhooks") && (
954 <SidebarLink to={`${base}/settings/webhooks`} icon={<Webhook size={15} />}>
955 Webhooks
956 </SidebarLink>
957 )}
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.958 </NavRows>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists959 </nav>
960 );
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)961}
962
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists963/** Your own settings, drilled into from Your settings: one page each. */
964function AccountSettingsMenu({ username }: { username: string }) {
965 const link = (page: AccountSettingsPage, icon: ReactNode) => (
966 <SidebarLink to={`/settings/${page}`} icon={icon}>
967 {ACCOUNT_SETTINGS[page].title}
968 </SidebarLink>
969 );
970 return (
971 <nav aria-label="Your settings" className={PANEL}>
972 <BackRow to="/" label="Your settings" context={username} />
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.973 <NavRows className="mt-2">
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists974 {link("profile", <CircleUserRound size={15} />)}
975 {link("emails", <Mail size={15} />)}
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.976 </NavRows>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists977 <Rule />
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.978 <NavRows>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists979 {link("keys", <Fingerprint size={15} />)}
980 {link("tokens", <KeyRound size={15} />)}
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.981 </NavRows>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists982 <Rule />
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.983 <NavRows>
Integrations are a directory of connectors, for a workspace and for each person984 {link("integrations", <Blocks size={15} />)}
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r9985 {link("github", <GithubMark className="size-3.75" />)}
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists986 {link("applications", <Plug size={15} />)}
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.987 </NavRows>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists988 <Rule />
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.989 <NavRows>
Merge main (membership, two-factor, GitHub repo roles) into tokens990 {link("two-factor", <ShieldCheck size={15} />)}
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists991 {link("security-log", <History size={15} />)}
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.992 </NavRows>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists993 </nav>
994 );
995}
996
997/**
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.998 * Code's sidebar: its Overview, the projects, what spans them and what is
999 * coming; in a project, drilled into the project's own list, and its
1000 * settings one level further in. The address says which, so a link
1001 * straight to a project opens the sidebar already drilled in.
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1002 */
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1003function CodeSidebar({
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1004 user,
1005 shell,
1006 missing = false,
Merge branch 'worktree-agent-aefe9db9851cfafd8'1007 browsing = null,
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1008}: {
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1009 user: User;
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1010 shell: ShellData;
1011 /** The page is a 404: the address names nothing the viewer can see. */
1012 missing?: boolean;
Merge branch 'worktree-agent-aefe9db9851cfafd8'1013 /** g1t beyond the viewer's workspaces (lib/workspace-nav.ts `browsingOf`): Explore's list in place of Code's. */
1014 browsing?: { owner: BrowsedOwner | null } | null;
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1015}) {
1016 const ws = shell.workspace;
1017 const { pathname } = useLocation();
1018 const going = useNavigation().location?.pathname;
1019 // Where the sidebar is drilled to follows the page being gone to, so it
1020 // moves as the link is followed, not once the page arrives.
1021 const target = going ?? pathname;
1022 // On a 404, the address is not a place: no list is drilled into from it,
1023 // except the project's own when the project is real and visible and only
1024 // something inside it is missing (a file, a commit, an issue).
1025 const lost = missing && going == null;
1026 const active = shell.repo;
1027 // In a repository, or on the way into one, its own list.
1028 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.1029 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"]);
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1030 // An invitation to a repository is answered before its menu means anything.
1031 const inRepo =
1032 repoPath != null &&
1033 !reserved.has(repoPath[1]) &&
1034 repoPath[2] !== "-" &&
1035 !/^\/[^/]+\/[^/]+\/invitations\/?$/.test(target) &&
1036 (!lost || sameRepo(active, { namespace: repoPath[1]!, name: repoPath[2]! }));
1037 // A project's settings, one level further in.
1038 const inRepoSettings = inRepo && REPO_SETTINGS_PAGE.test(target);
1039 // The repository the menu is for: the one loaded if it is the one being
1040 // gone to, else what the address says, at once.
1041 const targetRepo = inRepo && repoPath ? { namespace: repoPath[1], name: repoPath[2] } : null;
1042 const guessed: MenuRepo | null = targetRepo
1043 ? sameRepo(active, targetRepo)
1044 ? active
1045 : {
1046 ...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.1047 member: (user.workspaces ?? []).some((m) => m.slug === targetRepo.namespace.toLowerCase()),
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1048 }
1049 : null;
1050 // The viewer's role there, from the repository's page once it has loaded.
1051 const page = useRouteLoaderData("routes/repo/layout") as
Merge main into rm-agents: mirroring removal, open signups, free-tier limits, the g1t CLI and runner fixes, with the agent removal kept. The CLI's table of operations is regenerated from the API without the agent, customize and AI credit operations; no CLI command used them.1052 | { repo?: { namespace: string; name: string }; access?: ViewerAccess }
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1053 | undefined;
1054 const menuRepo: MenuRepo | null =
1055 guessed && page?.access && page.repo && sameRepo(page.repo, guessed)
Merge main into rm-agents: mirroring removal, open signups, free-tier limits, the g1t CLI and runner fixes, with the agent removal kept. The CLI's table of operations is regenerated from the API without the agent, customize and AI credit operations; no CLI command used them.1056 ? { ...guessed, member: page.access.insider, settings: seesSettings(page.access), can: page.access.can }
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1057 : guessed;
1058
Merge branch 'worktree-agent-aefe9db9851cfafd8'1059 // The way from Code's list (or Explore's, browsing) to the one shown.
1060 const main = browsing ? <BrowseMenu user={user} owner={browsing.owner} /> : ws ? <CodeMenu shell={shell} slug={ws.slug} /> : null;
1061 const trail: Level[] = [{ key: browsing ? "browse" : "main", node: main }];
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1062 if (menuRepo) {
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1063 const key = `repo:${menuRepo.namespace}/${menuRepo.name}`.toLowerCase();
Merge branch 'worktree-agent-aefe9db9851cfafd8'1064 // Out of a project: to its workspace's projects when they are yours, or
1065 // when browsing, to the projects of the workspace it is in.
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More 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 const home = (user.workspaces ?? []).find((m) => m.slug === menuRepo.namespace.toLowerCase());
Merge branch 'worktree-agent-aefe9db9851cfafd8'1067 const back = home
1068 ? { to: `/${home.slug}/-/projects`, label: "All projects" }
1069 : browsing
1070 ? { to: `/${menuRepo.namespace}/-/projects`, label: "Projects", context: menuRepo.namespace }
1071 : { to: ws ? `/${ws.slug}/-/overview` : "/explore", label: "Code" };
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1072 trail.push({
1073 key,
1074 node: (
1075 <RepoMenu
1076 repo={menuRepo}
1077 isPrivate={[...shell.repos, ...(shell.shared ?? [])].some((repo) => sameRepo(repo, menuRepo) && repo.isPrivate)}
1078 back={back}
1079 />
1080 ),
1081 });
1082 if (inRepoSettings) trail.push({ key: `${key}:settings`, node: <RepoSettingsMenu repo={menuRepo} /> });
1083 }
1084
1085 return (
1086 <div className="flex h-full flex-col">
Merge branch 'worktree-agent-aefe9db9851cfafd8'1087 {browsing && ws && (
1088 <>
1089 <BackToWorkspace workspace={ws} />
1090 <Rule />
1091 </>
1092 )}
1093 <ModeHeader title={browsing ? "Explore" : "Code"} />
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1094 <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)1095 </div>
1096 );
1097}
1098
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1099/**
Merge branch 'worktree-agent-aefe9db9851cfafd8'1100 * Browsing, the way back to the workspace you are in: its Home, at the top
1101 * of Explore's sidebar, at every level of it.
1102 */
1103function BackToWorkspace({ workspace }: { workspace: Membership }) {
1104 const name = displayName(workspace);
1105 return (
1106 <NavRows className="pt-0">
1107 <SidebarMenuItem>
1108 <SidebarMenuButton asChild className="gap-2 pl-1 font-medium text-fg">
1109 <Link to={homePagePath(workspace.slug)} prefetch="intent" aria-label={`Back to ${name}: Home`}>
1110 <ChevronLeft className="text-faint transition-transform group-hover/menu-button:-translate-x-0.5 group-hover/menu-button:text-muted" />
1111 <Avatar name={workspace.slug} image={workspace.avatar} size={18} square />
1112 <span className="min-w-0 truncate">Back to {name}</span>
1113 </Link>
1114 </SidebarMenuButton>
1115 </SidebarMenuItem>
1116 </NavRows>
1117 );
1118}
1119
1120/** Whose page is being browsed, as the page itself names them once it has loaded: a workspace's or a person's. */
1121function useBrowsedOwner(owner: BrowsedOwner | null): { name: string; avatar: string | null } | null {
1122 const workspace = useRouteLoaderData("routes/workspace/layout") as { workspace?: { slug: string; name?: string | null; avatar?: string | null } } | undefined;
1123 const person = useRouteLoaderData("routes/user") as { profile?: { username: string; displayUsername?: string | null; avatar: string | null } } | undefined;
1124 if (!owner) return null;
1125 if (owner.kind === "person") {
1126 const profile = person?.profile?.username.toLowerCase() === owner.name.toLowerCase() ? person.profile : null;
1127 return { name: `@${profile ? shownUsername(profile) : owner.name}`, avatar: profile?.avatar ?? null };
1128 }
1129 const page = workspace?.workspace?.slug.toLowerCase() === owner.name.toLowerCase() ? workspace.workspace : null;
1130 return { name: page?.name?.trim() || owner.name, avatar: page?.avatar ?? null };
1131}
1132
1133/**
1134 * Explore's list, beside g1t beyond your workspaces (lib/workspace-nav.ts
1135 * `browsingOf`): public projects across g1t, recently active and new,
1136 * search, and what you starred; then whose page this is, with their own
1137 * pages. A project of theirs drills into its own list, as in Code.
1138 */
1139function BrowseMenu({ user, owner }: { user: User; owner: BrowsedOwner | null }) {
1140 const location = useLocation();
1141 const going = useNavigation().location;
1142 const path = pagePath((going ?? location).pathname);
1143 const query = new URLSearchParams((going ?? location).search);
1144 const atExplore = path === "/explore";
1145 const fresh = atExplore && query.get("sort") === "new";
1146 const mine = `/u/${user.username}`;
1147 const atMine = path.toLowerCase() === mine.toLowerCase();
1148 const stars = atMine && query.get("tab") === "stars";
1149 const shown = useBrowsedOwner(owner);
1150 const profileTab = query.get("tab");
1151 return (
1152 <nav aria-label="Explore" className={PANEL}>
1153 <NavRows>
1154 <SidebarLink to="/explore" icon={<Compass size={15} />} current={atExplore && !fresh}>
1155 Recently active
1156 </SidebarLink>
1157 <SidebarLink to="/explore?sort=new" icon={<Sparkles size={15} />} current={fresh}>
1158 New projects
1159 </SidebarLink>
1160 <SidebarLink to="/search" icon={<Search size={15} />} current={path === "/search"}>
1161 Search
1162 </SidebarLink>
1163 </NavRows>
1164 <Rule />
1165 <NavRows>
1166 <SidebarLink to={`${mine}?tab=stars`} icon={<Star size={15} />} current={stars}>
1167 Your stars
1168 </SidebarLink>
1169 <SidebarLink to={mine} icon={<CircleUserRound size={15} />} current={atMine && !stars}>
1170 Your profile
1171 </SidebarLink>
1172 </NavRows>
1173 {owner && shown && (
1174 <>
1175 <Rule />
1176 <NavGroup title="You are viewing">
1177 {owner.kind === "workspace" ? (
1178 <>
1179 <SidebarLink
1180 to={`/${owner.name}`}
1181 icon={<Avatar name={owner.name} image={shown.avatar} size={16} square />}
1182 current={path.toLowerCase() === `/${owner.name}`.toLowerCase()}
1183 >
1184 {shown.name}
1185 </SidebarLink>
1186 <SidebarLink to={`/${owner.name}/-/projects`} icon={<LayoutGrid size={15} />}>
1187 Projects
1188 </SidebarLink>
1189 </>
1190 ) : (
1191 <>
1192 <SidebarLink
1193 to={`/u/${owner.name}`}
1194 icon={<Avatar name={owner.name} image={shown.avatar} size={16} />}
1195 current={profileTab !== "stars"}
1196 >
1197 {shown.name}
1198 </SidebarLink>
1199 <SidebarLink to={`/u/${owner.name}?tab=stars`} icon={<Star size={15} />} current={profileTab === "stars"}>
1200 Stars
1201 </SidebarLink>
1202 </>
1203 )}
1204 </NavGroup>
1205 </>
1206 )}
1207 </nav>
1208 );
1209}
1210
1211/**
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1212 * A mode's sidebar heading: its name, quiet, under the workspace's
1213 * switcher, with what it makes at the end.
1214 */
1215export 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)1216 return (
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.1217 <div className="flex h-8 shrink-0 items-center gap-1 pr-2 pl-3">
1218 <SidebarGroupLabel asChild className="min-w-0 grow truncate px-1">
1219 <h2>{title}</h2>
1220 </SidebarGroupLabel>
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)1221 {action}
1222 </div>
1223 );
1224}
1225
1226/**
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.1227 * Code's own list (beside the rail): 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)1228 * control's code panels), the projects, what spans them, and what is
The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404.1229 * 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)1230 */
1231function CodeMenu({ shell, slug }: { shell: ShellData; slug: string }) {
1232 const { pathname } = useLocation();
1233 const going = useNavigation().location?.pathname;
1234 const path = going ?? pathname;
1235 const at = (page: string) => path === `/${slug}/-/${page}` || path.startsWith(`/${slug}/-/${page}/`);
1236 const shared = shell.shared ?? [];
1237 return (
1238 <nav aria-label="Code" className={PANEL}>
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.1239 <NavRows>
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)1240 <SidebarLink to={`/${slug}/-/overview`} icon={<LayoutDashboard size={15} />} current={at("overview")}>
1241 Overview
1242 </SidebarLink>
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.1243 </NavRows>
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)1244 <Rule />
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.1245 <SidebarProjects slug={slug} shell={shell} current={at("projects")} />
1246 <Rule />
1247 <NavRows>
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)1248 <SidebarLink to={`/${slug}/-/security`} icon={<ShieldCheck size={15} />} current={at("security") && !at("security/settings")}>
1249 Security
1250 </SidebarLink>
1251 <SidebarLink to={`/${slug}/-/packages`} icon={<Package size={15} />} current={at("packages")}>
1252 Packages
1253 </SidebarLink>
The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404.1254 <SidebarLink to={`/${slug}/-/memory`} icon={<Brain size={15} />} current={at("memory")}>
1255 Memory
1256 </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)1257 {INSIGHTS && (
1258 <SidebarSoonLink to={`/${slug}/-/insights`} icon={<TrendingUp size={15} />} about={INSIGHTS.summary} current={at("insights")}>
1259 {INSIGHTS.title}
1260 </SidebarSoonLink>
1261 )}
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.1262 </NavRows>
Code's sidebar has Explore, under its other pages, for public repositories beyond the workspace's own; it was only in the command palette.1263 <Rule />
1264 <NavRows>
1265 {/* Public repositories beyond this workspace's own. */}
1266 <SidebarLink to="/explore" icon={<Compass size={15} />} current={path === "/explore" || path.startsWith("/explore/")}>
1267 Explore
1268 </SidebarLink>
1269 </NavRows>
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1270 {shared.length > 0 && (
1271 <>
1272 <Rule />
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.1273 <NavGroup title="Shared with you">
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)1274 {shared.map((repo) => (
1275 <SidebarLink
1276 key={`${repo.namespace}/${repo.name}`}
1277 to={`/${repo.namespace}/${repo.name}`}
1278 icon={repo.isPrivate ? <Lock size={15} /> : <Box size={15} />}
1279 drill="hover"
1280 >
1281 <span className="font-mono text-faint">{repo.namespace}/</span>
1282 {repo.name}
1283 </SidebarLink>
1284 ))}
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.1285 </NavGroup>
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)1286 </>
1287 )}
1288 </nav>
1289 );
1290}
1291
Workspace is the workspace's settings, in one place. Its sidebar is grouped, General, Access, Money, Compute, Code, Agents, Chat, Artifacts, Security and Integrations, every page one click away with no settings inside settings, the groups folding and the owner-only pages hidden from members; what is not here yet is marked Soon with a hint. Members is a list with search and filters for role, two-factor and team, and Invite opens a dialog: who, by username, name or email, their role and a note that goes into the invitation; nothing is filled in inline any more. Invitations is its own page with All, Pending, Accepted, Declined, Expired and Revoked filters that say how many, and each row's menu can copy the link, send it again or revoke it; identity learned to send an invitation again and to carry the note. Permissions gathers every rule about who may do what, by part: Code's base permission and member privileges, who creates teams, who creates channels, and, marked Soon with what applies today, forking private repositories, adding agents to conversations, messaging agents directly, creating spaces and default sharing, creating workspace agents and raising budgets, deploying to production and publishing packages. General lost what moved. The permissions guide is new, and the workspaces, people and teams, access, chat, teams, authentication and billing guides say where things are now.1292/** The icon of each of Workspace mode's pages, by its key (lib/workspace-nav.ts). */
1293const WORKSPACE_PAGE_ICONS: Record<string, ReactNode> = {
1294 settings: <Settings size={15} />,
1295 members: <Users size={15} />,
1296 invitations: <Mail size={15} />,
1297 permissions: <ShieldCheck size={15} />,
1298 tokens: <KeyRound size={15} />,
1299 "personal-access-tokens": <UserRoundKey size={15} />,
1300 usage: <BarChart3 size={15} />,
1301 billing: <CreditCard size={15} />,
1302 runners: <ServerCog size={15} />,
1303 repositories: <BookMarked size={15} />,
1304 actions: <PlayCircle size={15} />,
1305 secrets: <Lock size={15} />,
1306 webhooks: <Webhook size={15} />,
1307 "chat-settings": <MessagesSquare size={15} />,
1308 emoji: <Smile size={15} />,
1309 "security-settings": <Shield size={15} />,
1310 guardrails: <Gauge size={15} />,
1311 rules: <Scale size={15} />,
1312 audit: <History size={15} />,
1313 integrations: <Plug size={15} />,
1314};
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)1315
1316/**
Workspace is the workspace's settings, in one place. Its sidebar is grouped, General, Access, Money, Compute, Code, Agents, Chat, Artifacts, Security and Integrations, every page one click away with no settings inside settings, the groups folding and the owner-only pages hidden from members; what is not here yet is marked Soon with a hint. Members is a list with search and filters for role, two-factor and team, and Invite opens a dialog: who, by username, name or email, their role and a note that goes into the invitation; nothing is filled in inline any more. Invitations is its own page with All, Pending, Accepted, Declined, Expired and Revoked filters that say how many, and each row's menu can copy the link, send it again or revoke it; identity learned to send an invitation again and to carry the note. Permissions gathers every rule about who may do what, by part: Code's base permission and member privileges, who creates teams, who creates channels, and, marked Soon with what applies today, forking private repositories, adding agents to conversations, messaging agents directly, creating spaces and default sharing, creating workspace agents and raising budgets, deploying to production and publishing packages. General lost what moved. The permissions guide is new, and the workspaces, people and teams, access, chat, teams, authentication and billing guides say where things are now.1317 * A group of Workspace mode's rows that folds: its name is the button, with
1318 * a chevron that turns when it is open. The group holding the current page
1319 * is always open, and its button does nothing. Every group starts open, so
1320 * the server and the browser draw the same list.
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)1321 */
Workspace is the workspace's settings, in one place. Its sidebar is grouped, General, Access, Money, Compute, Code, Agents, Chat, Artifacts, Security and Integrations, every page one click away with no settings inside settings, the groups folding and the owner-only pages hidden from members; what is not here yet is marked Soon with a hint. Members is a list with search and filters for role, two-factor and team, and Invite opens a dialog: who, by username, name or email, their role and a note that goes into the invitation; nothing is filled in inline any more. Invitations is its own page with All, Pending, Accepted, Declined, Expired and Revoked filters that say how many, and each row's menu can copy the link, send it again or revoke it; identity learned to send an invitation again and to carry the note. Permissions gathers every rule about who may do what, by part: Code's base permission and member privileges, who creates teams, who creates channels, and, marked Soon with what applies today, forking private repositories, adding agents to conversations, messaging agents directly, creating spaces and default sharing, creating workspace agents and raising budgets, deploying to production and publishing packages. General lost what moved. The permissions guide is new, and the workspaces, people and teams, access, chat, teams, authentication and billing guides say where things are now.1322function FoldingGroup({ title, current, children }: { title: string; current: boolean; children: ReactNode }) {
1323 const [open, setOpen] = useState(true);
1324 return (
1325 <Collapsible open={open || current} onOpenChange={setOpen}>
1326 <SidebarGroup>
1327 <CollapsibleTrigger
1328 disabled={current}
1329 aria-label={`${title}: ${open || current ? "fold" : "unfold"}`}
1330 className="flex h-7 w-full shrink-0 items-center justify-between rounded-md px-2 text-[0.6875rem] font-medium tracking-wide text-faint uppercase hover:text-muted focus-visible:ring-2 focus-visible:ring-accent disabled:cursor-default disabled:text-faint data-[state=open]:[&_svg]:rotate-90"
1331 >
1332 <span>{title}</span>
1333 {!current && <ChevronRight size={12} aria-hidden="true" className="text-faint/70" />}
1334 </CollapsibleTrigger>
1335 <CollapsibleContent>
1336 <SidebarGroupContent>
1337 <SidebarMenu>{children}</SidebarMenu>
1338 </SidebarGroupContent>
1339 </CollapsibleContent>
1340 </SidebarGroup>
1341 </Collapsible>
1342 );
1343}
1344
1345/**
1346 * The Workspace mode's sidebar: the workspace's settings area, every page
1347 * one click away. Its overview, then the groups in lib/workspace-nav.ts
Workspace settings promise only what exists: the Soon rows Deployments, Project defaults, Spaces and sharing and Applications are gone from Workspace mode's sidebar, with the Artifacts group they left empty, and the sidebar no longer draws Soon rows at all. None had a plan behind it. Permissions loses its five locked Soon settings (forking private repositories, who can create spaces, default sharing, who can deploy to production, who can publish packages), so every setting on it saves. The permissions and workspaces guides say the same. Checked: the site's typecheck, its tests and a production build, the deploy tool's tests and the docs build.1348 * (General, Access, Money, Compute, Code, Chat, Security, Integrations),
1349 * each folding, the one you are in held open. Pages only owners open are
1350 * left out for members, and a group with none left goes with them.
Workspace is the workspace's settings, in one place. Its sidebar is grouped, General, Access, Money, Compute, Code, Agents, Chat, Artifacts, Security and Integrations, every page one click away with no settings inside settings, the groups folding and the owner-only pages hidden from members; what is not here yet is marked Soon with a hint. Members is a list with search and filters for role, two-factor and team, and Invite opens a dialog: who, by username, name or email, their role and a note that goes into the invitation; nothing is filled in inline any more. Invitations is its own page with All, Pending, Accepted, Declined, Expired and Revoked filters that say how many, and each row's menu can copy the link, send it again or revoke it; identity learned to send an invitation again and to carry the note. Permissions gathers every rule about who may do what, by part: Code's base permission and member privileges, who creates teams, who creates channels, and, marked Soon with what applies today, forking private repositories, adding agents to conversations, messaging agents directly, creating spaces and default sharing, creating workspace agents and raising budgets, deploying to production and publishing packages. General lost what moved. The permissions guide is new, and the workspaces, people and teams, access, chat, teams, authentication and billing guides say where things are now.1351 */
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1352export 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)1353 const { pathname } = useLocation();
1354 const going = useNavigation().location?.pathname;
1355 const path = going ?? pathname;
Workspace is the workspace's settings, in one place. Its sidebar is grouped, General, Access, Money, Compute, Code, Agents, Chat, Artifacts, Security and Integrations, every page one click away with no settings inside settings, the groups folding and the owner-only pages hidden from members; what is not here yet is marked Soon with a hint. Members is a list with search and filters for role, two-factor and team, and Invite opens a dialog: who, by username, name or email, their role and a note that goes into the invitation; nothing is filled in inline any more. Invitations is its own page with All, Pending, Accepted, Declined, Expired and Revoked filters that say how many, and each row's menu can copy the link, send it again or revoke it; identity learned to send an invitation again and to carry the note. Permissions gathers every rule about who may do what, by part: Code's base permission and member privileges, who creates teams, who creates channels, and, marked Soon with what applies today, forking private repositories, adding agents to conversations, messaging agents directly, creating spaces and default sharing, creating workspace agents and raising budgets, deploying to production and publishing packages. General lost what moved. The permissions guide is new, and the workspaces, people and teams, access, chat, teams, authentication and billing guides say where things are now.1356 const here = workspaceSettingsPage(path, slug);
1357 const overview = path === `/${slug}/-/workspace` || path.startsWith(`/${slug}/-/workspace/`);
1358 const shown = (page: WorkspaceSettingsPage) => owner || !page.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)1359 return (
1360 <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.1361 <ModeHeader title="Workspace" />
Workspace is the workspace's settings, in one place. Its sidebar is grouped, General, Access, Money, Compute, Code, Agents, Chat, Artifacts, Security and Integrations, every page one click away with no settings inside settings, the groups folding and the owner-only pages hidden from members; what is not here yet is marked Soon with a hint. Members is a list with search and filters for role, two-factor and team, and Invite opens a dialog: who, by username, name or email, their role and a note that goes into the invitation; nothing is filled in inline any more. Invitations is its own page with All, Pending, Accepted, Declined, Expired and Revoked filters that say how many, and each row's menu can copy the link, send it again or revoke it; identity learned to send an invitation again and to carry the note. Permissions gathers every rule about who may do what, by part: Code's base permission and member privileges, who creates teams, who creates channels, and, marked Soon with what applies today, forking private repositories, adding agents to conversations, messaging agents directly, creating spaces and default sharing, creating workspace agents and raising budgets, deploying to production and publishing packages. General lost what moved. The permissions guide is new, and the workspaces, people and teams, access, chat, teams, authentication and billing guides say where things are now.1362 <nav aria-label="Workspace" className={PANEL}>
1363 <NavRows>
1364 <SidebarLink to={`/${slug}/-/workspace`} icon={<LayoutGrid size={15} />} current={overview}>
1365 Overview
1366 </SidebarLink>
1367 </NavRows>
1368 {WORKSPACE_SETTINGS_GROUPS.filter((group) => group.pages.some(shown)).map((group) => (
1369 <Fragment key={group.key}>
1370 <Rule />
1371 <FoldingGroup title={group.title} current={here?.group === group.key}>
Workspace settings promise only what exists: the Soon rows Deployments, Project defaults, Spaces and sharing and Applications are gone from Workspace mode's sidebar, with the Artifacts group they left empty, and the sidebar no longer draws Soon rows at all. None had a plan behind it. Permissions loses its five locked Soon settings (forking private repositories, who can create spaces, default sharing, who can deploy to production, who can publish packages), so every setting on it saves. The permissions and workspaces guides say the same. Checked: the site's typecheck, its tests and a production build, the deploy tool's tests and the docs build.1372 {group.pages.filter(shown).map((page) => (
1373 <SidebarLink
1374 key={page.key}
1375 to={`/${slug}/-/${page.path}`}
1376 icon={WORKSPACE_PAGE_ICONS[page.key] ?? <Settings size={15} />}
1377 current={here?.page === page.key}
1378 >
1379 {page.label}
1380 </SidebarLink>
1381 ))}
Workspace is the workspace's settings, in one place. Its sidebar is grouped, General, Access, Money, Compute, Code, Agents, Chat, Artifacts, Security and Integrations, every page one click away with no settings inside settings, the groups folding and the owner-only pages hidden from members; what is not here yet is marked Soon with a hint. Members is a list with search and filters for role, two-factor and team, and Invite opens a dialog: who, by username, name or email, their role and a note that goes into the invitation; nothing is filled in inline any more. Invitations is its own page with All, Pending, Accepted, Declined, Expired and Revoked filters that say how many, and each row's menu can copy the link, send it again or revoke it; identity learned to send an invitation again and to carry the note. Permissions gathers every rule about who may do what, by part: Code's base permission and member privileges, who creates teams, who creates channels, and, marked Soon with what applies today, forking private repositories, adding agents to conversations, messaging agents directly, creating spaces and default sharing, creating workspace agents and raising budgets, deploying to production and publishing packages. General lost what moved. The permissions guide is new, and the workspaces, people and teams, access, chat, teams, authentication and billing guides say where things are now.1382 </FoldingGroup>
1383 </Fragment>
1384 ))}
1385 </nav>
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)1386 </div>
1387 );
1388}
1389
People and teams are front and centre: one directory of people and agents with presence, local time, titles, teams and what each owns; profiles with manager and reports and the agents they work with; an org chart with each team's agents beside the person who leads it; and teams of any mix, with a lead, a channel, a budget agents keep to and the agents on them. Every agent is told its teams each turn (who leads, who owns what, who's around and who to page), and the team page shows exactly what. Member management is Members and invites; the people and teams guide says how.1390/**
The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404.1391 * People's sidebar: everyone in the workspace and its teams. Who belongs, and
Merge branch 'rm-orgchart-getstarted'1392 * inviting people, is the workspace's: Workspace mode's Access group.
People and teams are front and centre: one directory of people and agents with presence, local time, titles, teams and what each owns; profiles with manager and reports and the agents they work with; an org chart with each team's agents beside the person who leads it; and teams of any mix, with a lead, a channel, a budget agents keep to and the agents on them. Every agent is told its teams each turn (who leads, who owns what, who's around and who to page), and the team page shows exactly what. Member management is Members and invites; the people and teams guide says how.1393 */
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1394function PeopleSidebar({ slug }: { slug: string }) {
1395 const { pathname } = useLocation();
1396 const going = useNavigation().location?.pathname;
1397 const path = going ?? pathname;
1398 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)1399 return (
1400 <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.1401 <ModeHeader title="People" />
1402 <nav aria-label="People" className={PANEL}>
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.1403 <NavRows>
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1404 <SidebarLink to={`/${slug}/-/people`} icon={<Users size={15} />} current={at("people")}>
1405 Everyone
1406 </SidebarLink>
1407 <SidebarLink to={`/${slug}/-/teams`} icon={<UsersRound size={15} />} current={at("teams")}>
1408 Teams
1409 </SidebarLink>
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.1410 </NavRows>
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1411 </nav>
1412 </div>
1413 );
1414}
1415
1416/**
1417 * Notifications' sidebar: what you have not finished with, what you saved
1418 * and what is done; then why you were told, which narrows any of them.
1419 */
1420function NotificationsSidebar({ counts }: { counts: InboxCounts | null }) {
1421 const { search } = useLocation();
1422 const params = new URLSearchParams(search);
1423 const view = inboxView(params.get("view"));
1424 const reason = inboxReason(params.get("reason"));
1425 const tab = params.get("tab");
1426 const address = (changes: Record<string, string | null>) => {
1427 const merged: Record<string, string | null> = { tab, view: view === "inbox" ? null : view, reason, ...changes };
1428 const next = new URLSearchParams();
1429 for (const [name, value] of Object.entries(merged)) if (value) next.set(name, value);
1430 const query = next.toString();
1431 return query ? `/notifications?${query}` : "/notifications";
1432 };
1433 const views = [
1434 { view: "inbox", label: "Everything", icon: <Bell size={15} />, count: counts?.unread },
1435 { view: "saved", label: "Saved", icon: <Bookmark size={15} /> },
1436 { view: "done", label: "Done", icon: <Check size={15} /> },
1437 ] as const;
1438 return (
1439 <div className="flex h-full flex-col">
1440 <ModeHeader title="Notifications" />
1441 <nav aria-label="Notifications" className={PANEL}>
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.1442 <NavRows>
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More 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 {views.map((entry) => (
1444 <SidebarLink
1445 key={entry.view}
1446 to={address({ view: entry.view === "inbox" ? null : entry.view, before: null })}
1447 icon={entry.icon}
1448 count={"count" in entry ? (entry.count ?? undefined) : undefined}
1449 current={view === entry.view}
1450 >
1451 {entry.label}
1452 </SidebarLink>
1453 ))}
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.1454 </NavRows>
1455 <Rule />
1456 <NavGroup title="Why you were told">
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1457 {REASON_FILTERS.map((entry) => (
1458 <SidebarLink
1459 key={entry.reason ?? "any"}
1460 to={address({ reason: entry.reason, before: null })}
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r91461 icon={<span className="block size-3.75" />}
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1462 current={reason === entry.reason}
1463 >
1464 {entry.reason == null ? "Any reason" : entry.label}
1465 </SidebarLink>
1466 ))}
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.1467 </NavGroup>
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1468 </nav>
1469 </div>
1470 );
1471}
1472
1473/** Your own settings, beside the page: under the account menu, not any workspace's. */
1474export function AccountSidebar({ username }: { username: string }) {
1475 return (
1476 <div className="flex h-full flex-col">
1477 <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)1478 <div className="min-h-0 grow">
1479 <AccountSettingsMenu username={username} />
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1480 </div>
1481 </div>
1482 );
1483}
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)1484
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1485/** Words for the sections a path can end in. */
1486const SECTIONS: Record<string, string> = {
1487 issues: "Issues",
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1488 milestones: "Milestones",
1489 labels: "Labels",
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1490 pulls: "Pull requests",
1491 queue: "Merge queue",
1492 commits: "Commits",
1493 actions: "Workflows",
1494 soon: "Soon",
1495 deployments: "Deployments",
1496 repository: "Repository",
1497 access: "Access",
1498 invitations: "Invitation",
1499 repositories: "Repositories",
1500 branches: "Branches",
1501 tags: "Tags",
1502 compare: "Compare",
1503 code: "Files",
1504 secrets: "Secrets and variables",
1505 settings: "Settings",
Navigation: the workspace's own page with tabs, pins and recent in the sidebar1506 people: "People",
Workspace is the workspace's settings, in one place. Its sidebar is grouped, General, Access, Money, Compute, Code, Agents, Chat, Artifacts, Security and Integrations, every page one click away with no settings inside settings, the groups folding and the owner-only pages hidden from members; what is not here yet is marked Soon with a hint. Members is a list with search and filters for role, two-factor and team, and Invite opens a dialog: who, by username, name or email, their role and a note that goes into the invitation; nothing is filled in inline any more. Invitations is its own page with All, Pending, Accepted, Declined, Expired and Revoked filters that say how many, and each row's menu can copy the link, send it again or revoke it; identity learned to send an invitation again and to carry the note. Permissions gathers every rule about who may do what, by part: Code's base permission and member privileges, who creates teams, who creates channels, and, marked Soon with what applies today, forking private repositories, adding agents to conversations, messaging agents directly, creating spaces and default sharing, creating workspace agents and raising budgets, deploying to production and publishing packages. General lost what moved. The permissions guide is new, and the workspaces, people and teams, access, chat, teams, authentication and billing guides say where things are now.1507 members: "Members",
1508 permissions: "Permissions",
Navigation: the workspace's own page with tabs, pins and recent in the sidebar1509 projects: "Projects",
1510 teams: "Teams",
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1511 tokens: "Access tokens",
Settings: fine-grained tokens, workspace token Admin, workspace personal access token rules1512 "personal-access-tokens": "Personal access tokens",
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1513 usage: "Usage",
1514 billing: "Billing and plans",
1515 integrations: "Integrations",
1516 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)1517 emoji: "Emoji",
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1518 domains: "Domains",
1519 guardrails: "Guardrails",
Merge rulesets: branch and tag rules, agent-first, enforced on push and merge1520 rules: "Rules",
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1521 audit: "Audit log",
1522 tree: "Files",
1523 blob: "Files",
1524 memory: "Memory",
1525 security: "Security",
1526 packages: "Packages",
1527 runners: "Runners",
Merge branch 'worktree-agent-a3abfcce648e87dca'1528 environments: "Environments",
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1529 workflows: "Workflows",
1530 observability: "Observability",
1531 insights: "Insights",
1532 sessions: "Sessions",
Merge branch 'worktree-agent-aa68cf6ecc03dffaf'1533 work: "Work",
Chat and workspace agents: channels, DMs and named agents you talk to1534 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.1535 artifacts: "Artifacts",
The front page is Home: where you're needed comes first, however long ago it started, with what's at stake and how long it has waited; then what happened since you were last here, in words, with the agent work that settled, what landed, what deployed, what was decided and what was spent, switchable to the last 24 hours or 7 days; then what's running now. Your last visit is kept with your account, so it's the same on every device; Today's old address leads here. The home guide says how.1536 home: "Home",
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1537 apps: "Apps",
Chat and workspace agents: channels, DMs and named agents you talk to1538 "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)1539 overview: "Overview",
1540 workspace: "Workspace",
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1541};
1542
Merge branch 'worktree-agent-a3abfcce648e87dca'1543/** Settings pages whose name differs from the section's of the same word. */
1544const SETTINGS_SECTIONS: Record<string, string> = { branches: "Branches and merging", actions: "Actions" };
1545
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1546/** 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.1547function Breadcrumbs({
1548 pathname,
1549 missing,
1550 repo,
1551 workspace,
1552}: {
1553 pathname: string;
1554 missing?: boolean;
1555 repo?: ShellData["repo"];
1556 /** The workspace you are in: the switcher names it, so the trail starts after it. */
1557 workspace: string | null;
1558}) {
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1559 // A 404 names nothing from the address, unless the project is real and
1560 // visible and only something inside it is missing.
1561 const visibleRepo = /^\/([^/]+)\/([^/-][^/]*)(\/|$)/.exec(pathname);
1562 if (missing && !(visibleRepo && sameRepo(repo ?? null, { namespace: visibleRepo[1]!, name: visibleRepo[2]! }))) {
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1563 return <Here>Not found</Here>;
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1564 }
1565 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.1566 const reserved = ["settings", "explore", "new", "search", "workspaces", "policies", "security", "support", "status", "invite", "notifications"];
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1567 if (parts.length === 0) return <Here>Home</Here>;
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1568 // Your settings: Settings / Emails.
1569 if (parts[0] === "settings") {
1570 const page = accountSettingsPage(pathname);
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1571 return <Trail trail={[{ label: "Settings", to: FIRST_SETTINGS_PAGE }, ...(page ? [{ label: ACCOUNT_SETTINGS[page].title, to: `/settings/${page}` }] : [])]} />;
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1572 }
1573 if (reserved.includes(parts[0]!)) {
1574 const words: Record<string, string> = {
1575 settings: "Account",
1576 explore: "Explore",
1577 new: "New project",
1578 search: "Search",
1579 workspaces: "New workspace",
1580 policies: "Policies",
1581 security: "Security",
1582 support: "Support",
1583 status: "Status",
1584 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.1585 notifications: "Notifications",
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1586 };
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1587 return <Here>{words[parts[0]!]}</Here>;
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1588 }
1589 // A person's profile, by their handle.
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1590 if (parts[0] === "u" && parts[1]) return <ProfileCrumb username={parts[1]} />;
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1591 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.1592 const ours = workspace != null && owner!.toLowerCase() === workspace.toLowerCase();
1593 const trail: Crumb[] = ours ? [] : [{ label: owner!, to: `/${owner}`, mono: true }];
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1594 if (second === "-") {
1595 const page = `/${owner}/-/${third}`;
Workspace is the workspace's settings, in one place. Its sidebar is grouped, General, Access, Money, Compute, Code, Agents, Chat, Artifacts, Security and Integrations, every page one click away with no settings inside settings, the groups folding and the owner-only pages hidden from members; what is not here yet is marked Soon with a hint. Members is a list with search and filters for role, two-factor and team, and Invite opens a dialog: who, by username, name or email, their role and a note that goes into the invitation; nothing is filled in inline any more. Invitations is its own page with All, Pending, Accepted, Declined, Expired and Revoked filters that say how many, and each row's menu can copy the link, send it again or revoke it; identity learned to send an invitation again and to carry the note. Permissions gathers every rule about who may do what, by part: Code's base permission and member privileges, who creates teams, who creates channels, and, marked Soon with what applies today, forking private repositories, adding agents to conversations, messaging agents directly, creating spaces and default sharing, creating workspace agents and raising budgets, deploying to production and publishing packages. General lost what moved. The permissions guide is new, and the workspaces, people and teams, access, chat, teams, authentication and billing guides say where things are now.1596 if (third === "settings" && fourth === "chat") {
1597 // Chat settings is a page of its own, not one of General's.
1598 trail.push({ label: "Chat settings", to: `${page}/chat` });
1599 } else if (third) {
1600 // The workspace's settings pages each stand alone: General, Members, Permissions.
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1601 trail.push({ label: third === "settings" ? "General" : (SECTIONS[third] ?? third), to: page });
The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404.1602 // Members names its invitations.
1603 const tabs: Record<string, string> = third === "members" ? { invitations: "Invitations" } : {};
The Marketplace adds what g1t doesn't do and connects what you already use: extensions (Mail, Support, CRM, Recruiting, On-call, and bridges to a helpdesk, CRM or ERP you run, all Soon), starter kits, and integrations connected by the workspace or by each person; agents aren't installed there. Agent templates live in Agents, as starting points you configure, at Agents → Templates, and the Marketplace's old agent addresses lead there. The marketplace and agents guides say how.1604 const tab = fourth ? tabs[fourth] : undefined;
The Marketplace is where a workspace finds what to add, reached from Apps: the agent catalog of roles with who already does each job and Add to workspace; every integration with whether it's connected; g1t's own extensions, listed as Soon; and requests, where members ask and owners add or turn down, each told by a notification. Underneath, an extension is a manifest (publisher and tier, source and version from a tag, scopes, the domains its data goes to, its page on g1tusercontent.com, no price) and an install pins its version with an off switch, a budget and the audit log. Apps lists only what was added from the Marketplace, with pins; g1t's own pages stay in their sidebars, and AI Gateway joins Workspace's. The marketplace guide says how.1605 if (tab) trail.push({ label: tab, to: `${page}/${fourth}` });
1606 }
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1607 } else if (second) {
1608 const repo = `/${owner}/${second}`;
1609 trail.push({ label: second, to: repo, mono: true });
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1610 if (third === "pull" && fourth) trail.push({ label: `Pull request #${fourth}`, short: `#${fourth}`, to: `${repo}/pull/${fourth}` });
1611 else if (third === "issues" && fourth && fourth !== "new") trail.push({ label: `Issue #${fourth}`, short: `#${fourth}`, to: `${repo}/issues/${fourth}` });
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1612 else if (third === "commit" && fourth) trail.push({ label: fourth.slice(0, 7), to: `${repo}/commit/${fourth}`, mono: true });
1613 else if (third && SECTIONS[third]) {
1614 trail.push({ label: SECTIONS[third]!, to: `${repo}/${third}` });
1615 // A settings page names which one: Settings / Secrets and variables.
1616 if (third === "settings" && fourth && SECTIONS[fourth]) {
Merge branch 'worktree-agent-a3abfcce648e87dca'1617 trail.push({ label: SETTINGS_SECTIONS[fourth] ?? SECTIONS[fourth]!, to: `${repo}/settings/${fourth}` });
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1618 }
1619 }
1620 }
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1621 if (trail.length === 0) trail.push({ label: "Overview", to: `/${owner}` });
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1622 return <Trail trail={trail} />;
1623}
1624
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1625/** A profile's place in the top bar: the person's avatar and @handle, from the page once it has loaded. */
1626function 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 managers1627 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 project1628 const profile = page?.profile?.username.toLowerCase() === username.toLowerCase() ? page.profile : null;
1629 return (
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1630 <Breadcrumb className="min-w-0">
1631 <BreadcrumbList>
1632 <BreadcrumbItem>
1633 <BreadcrumbPage asChild className="flex items-center gap-2 hover:bg-raised">
1634 <Link to={`/u/${profile?.username ?? username}`}>
1635 <Avatar name={profile?.username ?? username} image={profile?.avatar ?? null} size={20} />
1636 <span className="truncate font-mono text-[0.8125rem]">@{profile ? shownUsername(profile) : username}</span>
1637 </Link>
1638 </BreadcrumbPage>
1639 </BreadcrumbItem>
1640 </BreadcrumbList>
1641 </Breadcrumb>
1642 );
1643}
1644
1645/** A page with no trail to it, such as Today or Search: its name alone. */
1646function Here({ children }: { children: ReactNode }) {
1647 return (
1648 <Breadcrumb className="min-w-0">
1649 <BreadcrumbList>
1650 <BreadcrumbItem>
1651 <BreadcrumbPage>{children}</BreadcrumbPage>
1652 </BreadcrumbItem>
1653 </BreadcrumbList>
1654 </Breadcrumb>
Chat controls, public profiles, shadcn selects, and no Docs tab in a project1655 );
1656}
1657
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1658/** One link of the trail; `short` is what a phone shows when it is the page itself. */
1659type Crumb = { label: string; to: string; mono?: boolean; short?: string };
1660
1661/**
1662 * The trail of links. On a phone there is room for one: the page itself,
1663 * with a way back to where it sits; the whole trail from a wider screen up.
1664 */
1665function 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)1666 // Up on a phone, unless up is the workspace itself: its pages are the tabs.
1667 const up = trail.length > 1 && !/^\/[^/]+$/.test(trail[trail.length - 2]!.to) ? trail[trail.length - 2]! : null;
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1668 return (
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1669 <Breadcrumb className="flex min-w-0 items-center">
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1670 {up && (
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1671 <Button asChild variant="ghost" size="icon-bar" className="-ml-1 sm:hidden">
1672 <Link to={up.to} prefetch="intent" aria-label={`Back to ${up.label}`}>
1673 <ChevronLeft size={16} />
1674 </Link>
1675 </Button>
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1676 )}
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1677 <BreadcrumbList>
1678 {trail.map((crumb, index) => {
1679 const last = index === trail.length - 1;
1680 const label =
1681 last && crumb.short ? (
1682 <>
1683 <span className="sm:hidden">{crumb.short}</span>
1684 <span className="hidden sm:inline">{crumb.label}</span>
1685 </>
1686 ) : (
1687 crumb.label
1688 );
1689 const mono = crumb.mono ? "font-mono text-[0.8125rem]" : "";
1690 return (
1691 <Fragment key={index}>
1692 {index > 0 && <BreadcrumbSeparator className="max-sm:hidden" />}
1693 <BreadcrumbItem className={last ? "" : "max-sm:hidden"}>
1694 {last ? (
1695 // The page you are on is still a link: to its own top, as the trail always was.
1696 <BreadcrumbPage asChild className={`hover:bg-raised ${mono}`}>
1697 <Link to={crumb.to} prefetch="intent">
1698 {label}
1699 </Link>
1700 </BreadcrumbPage>
1701 ) : (
1702 <BreadcrumbLink asChild className={mono}>
1703 <Link to={crumb.to} prefetch="intent">
1704 {label}
1705 </Link>
1706 </BreadcrumbLink>
1707 )}
1708 </BreadcrumbItem>
1709 </Fragment>
1710 );
1711 })}
1712 </BreadcrumbList>
1713 </Breadcrumb>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1714 );
1715}
1716
1717type Command = PaletteCommand;
1718
1719/** 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.1720function commandsFor(user: User, shell: ShellData): Command[] {
1721 const ws = shell.workspace;
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1722 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.1723 ...(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)1724 ? [
The front page is Home: where you're needed comes first, however long ago it started, with what's at stake and how long it has waited; then what happened since you were last here, in words, with the agent work that settled, what landed, what deployed, what was decided and what was spent, switchable to the last 24 hours or 7 days; then what's running now. Your last visit is kept with your account, so it's the same on every device; Today's old address leads here. The home guide says how.1725 { label: "Home", to: homePagePath(ws.slug), icon: <House size={15} /> },
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1726 { label: "Chat", to: `/${ws.slug}/-/chat`, icon: <MessagesSquare size={15} /> },
1727 ...(hasCodeAccess(ws) ? [{ label: "Code overview", to: `/${ws.slug}/-/overview`, icon: <Code2 size={15} /> }] : []),
1728 { label: "Artifacts", to: `/${ws.slug}/-/artifacts`, icon: <Shapes size={15} /> },
1729 { label: "Apps", hint: "Everything installed that you can use", to: `/${ws.slug}/-/apps`, icon: <LayoutGrid size={15} /> },
1730 { 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)1731 ]
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1732 : []),
1733 { label: "Explore repositories", to: "/explore", icon: <Compass size={15} /> },
1734 { 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.1735 { label: "Notifications", hint: "What needs you", to: "/notifications", icon: <Bell size={15} /> },
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1736 { label: "New project", to: "/new", icon: <Plus size={15} /> },
1737 { label: "Your settings", to: FIRST_SETTINGS_PAGE, icon: <Settings size={15} /> },
1738 ...(Object.keys(ACCOUNT_SETTINGS) as AccountSettingsPage[])
1739 .filter((page) => page !== "profile")
1740 .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.1741 ...THEME_COMMANDS,
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1742 ];
1743 const repo = shell.repo;
1744 if (repo) {
1745 const base = `/${repo.namespace}/${repo.name}`;
1746 const name = `${repo.namespace}/${repo.name}`;
1747 commands.unshift(
1748 { label: "Overview", hint: name, to: base, icon: <LayoutGrid size={15} /> },
1749 { label: "Code", hint: name, to: `${base}/code`, icon: <Code2 size={15} /> },
1750 { label: "Issues", hint: name, to: `${base}/issues`, icon: <CircleDot size={15} /> },
1751 { label: "New issue", hint: name, to: `${base}/issues/new`, icon: <Plus size={15} /> },
1752 { label: "Pull requests", hint: name, to: `${base}/pulls`, icon: <GitPullRequest size={15} /> },
1753 { label: "Commits", hint: name, to: `${base}/commits`, icon: <History size={15} /> },
1754 ...(repo.member
1755 ? [
1756 { label: "Deployments", hint: name, to: `${base}/deployments`, icon: <Rocket size={15} /> },
1757 { label: "Secrets and variables", hint: name, to: `${base}/settings/secrets`, icon: <Lock size={15} /> },
1758 { label: "Project settings", hint: name, to: `${base}/settings`, icon: <Settings size={15} /> },
1759 { label: "Repository settings", hint: name, to: `${base}/settings/repository`, icon: <Settings size={15} /> },
1760 ]
1761 : []),
1762 );
1763 }
1764 for (const membership of user.workspaces ?? []) {
1765 commands.push(
1766 { 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 sidebar1767 { label: "All projects", hint: membership.slug, to: `/${membership.slug}/-/projects`, icon: <LayoutGrid size={15} /> },
1768 { label: "People", hint: membership.slug, to: `/${membership.slug}/-/people`, icon: <Users size={15} /> },
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1769 { label: "Usage", hint: membership.slug, to: `/${membership.slug}/-/usage`, icon: <BarChart3 size={15} /> },
1770 { label: "Billing and plans", hint: `${membership.slug} · Settings`, to: `/${membership.slug}/-/billing`, icon: <CreditCard size={15} /> },
1771 { label: "Access tokens", hint: `${membership.slug} · Settings`, to: `/${membership.slug}/-/tokens`, icon: <KeyRound size={15} /> },
1772 { label: "Integrations", hint: membership.slug, to: `/${membership.slug}/-/integrations`, icon: <Plug size={15} /> },
Workspace is the workspace's settings, in one place. Its sidebar is grouped, General, Access, Money, Compute, Code, Agents, Chat, Artifacts, Security and Integrations, every page one click away with no settings inside settings, the groups folding and the owner-only pages hidden from members; what is not here yet is marked Soon with a hint. Members is a list with search and filters for role, two-factor and team, and Invite opens a dialog: who, by username, name or email, their role and a note that goes into the invitation; nothing is filled in inline any more. Invitations is its own page with All, Pending, Accepted, Declined, Expired and Revoked filters that say how many, and each row's menu can copy the link, send it again or revoke it; identity learned to send an invitation again and to carry the note. Permissions gathers every rule about who may do what, by part: Code's base permission and member privileges, who creates teams, who creates channels, and, marked Soon with what applies today, forking private repositories, adding agents to conversations, messaging agents directly, creating spaces and default sharing, creating workspace agents and raising budgets, deploying to production and publishing packages. General lost what moved. The permissions guide is new, and the workspaces, people and teams, access, chat, teams, authentication and billing guides say where things are now.1773 { label: "Members", hint: `${membership.slug} · Access`, to: `/${membership.slug}/-/members`, icon: <Users size={15} /> },
1774 ...(membership.role === "owner"
1775 ? [
1776 { label: "Invitations", hint: `${membership.slug} · Access`, to: `/${membership.slug}/-/members/invitations`, icon: <Mail size={15} /> },
1777 { label: "Permissions", hint: `${membership.slug} · Access`, to: `/${membership.slug}/-/permissions`, icon: <ShieldCheck size={15} /> },
1778 ]
1779 : []),
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1780 );
1781 }
1782 for (const listed of shell.repos) {
1783 commands.push({
1784 label: listed.title ?? listed.name,
1785 hint: `${listed.namespace} · Project`,
1786 to: `/${listed.namespace}/${listed.name}`,
1787 icon: <Box size={15} />,
1788 });
1789 }
1790 return commands;
1791}
1792
1793/**
Merge branch 'worktree-agent-aca4790ea223aa235'1794 * The page while the next one loads: after a moment it dims, under the
1795 * bar below, so it is plainly on its way out rather than frozen, and the
1796 * next page fades up from there. Sending a form does not dim it: the
1797 * form's button says it is working. Spread on the element holding the page.
1798 */
1799export function useLeaving() {
1800 const navigation = useNavigation();
1801 const method = navigation.formMethod?.toUpperCase();
1802 const leaving = navigation.state === "loading" && (method == null || method === "GET");
1803 return {
1804 "aria-busy": leaving || undefined,
1805 className: `transition-opacity motion-reduce:transition-none ${leaving ? "opacity-60 delay-200 duration-300" : "duration-150"}`,
1806 };
1807}
1808
1809/**
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1810 * A bar across the top of the page while the next one loads, as GitHub
1811 * has: it appears at once, creeps towards the end while waiting, then fills
1812 * and fades when the page arrives.
1813 */
1814export function Progress() {
1815 const navigation = useNavigation();
1816 const busy = navigation.state !== "idle";
1817 const [width, setWidth] = useState(0);
1818 const [visible, setVisible] = useState(false);
1819 useEffect(() => {
1820 if (busy) {
1821 setVisible(true);
1822 setWidth(12);
1823 // Slows as it goes, never quite arriving until the page does.
1824 const timer = setInterval(() => setWidth((now) => now + (90 - now) * 0.12), 200);
1825 return () => clearInterval(timer);
1826 }
1827 setWidth((now) => (now > 0 ? 100 : 0));
1828 const fade = setTimeout(() => setVisible(false), 250);
1829 const reset = setTimeout(() => setWidth(0), 550);
1830 return () => {
1831 clearTimeout(fade);
1832 clearTimeout(reset);
1833 };
1834 }, [busy]);
1835 return (
1836 <div
1837 aria-hidden="true"
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r91838 className={`pointer-events-none fixed inset-x-0 top-0 z-60 h-0.75 transition-opacity duration-300 ${
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1839 visible ? "opacity-100" : "opacity-0"
1840 }`}
1841 >
1842 <div
1843 className="h-full bg-accent shadow-[0_0_10px_var(--color-accent)] transition-[width] duration-200 ease-out"
1844 style={{ width: `${width}%` }}
1845 />
1846 </div>
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 );
1848}
1849
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1850/**
The front page is Home: where you're needed comes first, however long ago it started, with what's at stake and how long it has waited; then what happened since you were last here, in words, with the agent work that settled, what landed, what deployed, what was decided and what was spent, switchable to the last 24 hours or 7 days; then what's running now. Your last visit is kept with your account, so it's the same on every device; Today's old address leads here. The home guide says how.1851 * Which sidebar sits beside the page: each mode's own, or none. Home and
Merge branch 'worktree-agent-aefe9db9851cfafd8'1852 * Apps are pages at full width, and so are g1t's own pages, such as its
1853 * policies, which are no workspace's. g1t beyond your workspaces (Explore,
1854 * a profile, another workspace's projects) has Explore's. Without a
1855 * workspace, only your own settings and Notifications have one.
Chat and workspace agents: channels, DMs and named agents you talk to1856 */
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1857function sidebarFor(mode: ModeKey, workspace: boolean): Panel | null {
1858 if (!workspace) return mode === "account" || mode === "notifications" ? mode : null;
The front page is Home: where you're needed comes first, however long ago it started, with what's at stake and how long it has waited; then what happened since you were last here, in words, with the agent work that settled, what landed, what deployed, what was decided and what was spent, switchable to the last 24 hours or 7 days; then what's running now. Your last visit is kept with your account, so it's the same on every device; Today's old address leads here. The home guide says how.1859 if (mode === "home" || mode === "apps" || mode === "site") return null;
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1860 return mode;
Chat and workspace agents: channels, DMs and named agents you talk to1861}
1862
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1863/** The sidebars that sit beside the page, one per mode that has one. */
Merge branch 'worktree-agent-aefe9db9851cfafd8'1864type Panel = "chat" | "artifacts" | "code" | "notifications" | "people" | "workspace" | "account" | "browse";
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)1865
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1866/** 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 bar1867const MODE_MENU: Record<Panel, string> = {
Merge branch 'worktree-agent-aefe9db9851cfafd8'1868 browse: "Explore",
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 bar1869 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.1870 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 bar1871 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.1872 notifications: "Notifications",
1873 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 bar1874 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.1875 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 bar1876};
1877
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1878/** Whether a key press happened in something you type into, where Ctrl B is the editor's. */
1879function typing(target: EventTarget | null): boolean {
1880 if (!(target instanceof HTMLElement)) return false;
1881 return target.isContentEditable || target.closest("input, textarea, select, [contenteditable=''], [contenteditable='true'], [role='textbox']") != null;
1882}
1883
1884/** Ctrl B (⌘B on a Mac) shows or hides the sidebar, except while typing. */
1885function useSidebarShortcut(toggle: () => void) {
1886 useEffect(() => {
1887 const onKey = (event: KeyboardEvent) => {
1888 if (event.key.toLowerCase() !== "b" || event.altKey || event.shiftKey || !(event.ctrlKey || event.metaKey)) return;
1889 if (event.defaultPrevented || typing(event.target)) return;
1890 event.preventDefault();
1891 toggle();
1892 };
1893 window.addEventListener("keydown", onKey);
1894 return () => window.removeEventListener("keydown", onKey);
1895 }, [toggle]);
1896}
1897
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1898/**
1899 * Search or jump to: the command palette. On a computer it looks like the
1900 * field it opens, with its shortcut; on a phone, a magnifier.
1901 */
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.1902function SearchButton({ onClick, place }: { onClick: () => void; place: "bar" | "sidebar" }) {
1903 const field = (
1904 <Button
1905 variant="outline"
1906 size="sm"
1907 aria-label="Search or jump to"
1908 onClick={onClick}
1909 className={
1910 place === "sidebar"
1911 ? "w-full justify-start bg-bg font-normal text-faint hover:bg-bg hover:text-muted"
1912 : "mr-1 w-[min(18rem,26vw)] justify-start bg-surface font-normal text-faint hover:bg-surface hover:text-muted max-md:hidden"
1913 }
1914 >
1915 <Search size={15} />
1916 <span className="grow truncate text-left">Search or jump to</span>
1917 <PaletteKey className="px-1.5 text-[0.625rem] leading-4 text-muted" />
1918 </Button>
1919 );
1920 if (place === "sidebar") return field;
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1921 return (
1922 <>
1923 <Button variant="ghost" size="icon-bar" aria-label="Search or jump to" onClick={onClick} className="md:hidden">
1924 <Search size={18} />
1925 </Button>
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.1926 {field}
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.1927 </>
1928 );
1929}
1930
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.1931/** The sidebar's shortcut, for the hint on its toggle. */
1932function useSidebarKey(): string {
1933 return sidebarKeyLabel(typeof navigator === "undefined" ? null : navigator.platform);
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1934}
1935
Chat and workspace agents: channels, DMs and named agents you talk to1936/**
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.1937 * The app: three surfaces that never blur together. The rail, a narrow
1938 * column of icons down the window's left edge; the mode's sidebar, flat
1939 * against it with a hairline between, which folds away with Ctrl B and is
The page sits flat against the sidebar. On a computer it fills the rest of the window with no inset, no rounded corners and no frame around it, and its top bar always draws the line under itself, so a page's own header, a conversation's or a project's, sits beneath it as its own band instead of merging with it; the scroll watcher that used to decide when the line appeared is gone. A phone keeps its rounded panel above the bottom bar. The workspaces guide says so.1940 * a drawer below 1024px; and the page, flat against the sidebar and
1941 * filling the rest of the window, with its top bar across the top and a
Merge branch 'ask-g1t'1942 * line under it: the sidebar's toggle, where you are, search, Ask, the bell and
The page sits flat against the sidebar. On a computer it fills the rest of the window with no inset, no rounded corners and no frame around it, and its top bar always draws the line under itself, so a page's own header, a conversation's or a project's, sits beneath it as its own band instead of merging with it; the scroll watcher that used to decide when the line appeared is gone. A phone keeps its rounded panel above the bottom bar. The workspaces guide says so.1943 * Create new. On a phone the rail is a bar along the bottom and the page
The phone app: Chat in full with phone notifications, plus Code and Customize (#4)1944 * fills the window above it, flat as well. Only for someone signed in; without a workspace yet, there
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.1945 * is no rail. The rail and the sidebar are drawn from the sidebar kit
1946 * (components/ui/sidebar.tsx): one provider holds whether the sidebar is
1947 * open on a computer and whether the drawer is.
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1948 */
1949export function AppShell({
1950 user,
1951 shell,
1952 missing = false,
1953 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.1954 sidebarClosed = false,
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1955 children,
1956}: {
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1957 user: User;
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1958 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.1959 /** The page is a 404 (see CodeSidebar). */
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1960 missing?: boolean;
1961 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.1962 /** Whether the person folded the sidebar away, as their cookie says. */
1963 sidebarClosed?: boolean;
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1964 children: ReactNode;
1965}) {
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1966 const { pathname } = useLocation();
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1967 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.1968 const [closed, setClosed] = useState(sidebarClosed);
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1969 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.1970 const commands = useMemo(() => commandsFor(user, shell), [user, shell]);
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1971
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.1972 // A new page closes the drawer.
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists1973 useEffect(() => setDrawer(false), [pathname]);
1974 usePaletteShortcut(() => setPalette((open) => !open));
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r91975 // In the desktop app, search is in the middle of its title bar, as in Slack, and not in the top bar too.
1976 const titleSearch = useTitleBarSearch(`Search ${shell.workspace?.name ?? shell.workspace?.slug ?? "g1t"}`, () => setPalette(true));
Merge branch 'worktree-agent-aca4790ea223aa235'1977 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)1978 useVisualViewport();
Chat and workspace agents: channels, DMs and named agents you talk to1979 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.1980 const ws = shell.workspace;
Merge branch 'worktree-agent-aefe9db9851cfafd8'1981 // Beyond your workspaces (Explore, a profile, another workspace's
1982 // projects), the shell is Explore's; anything of yours is its mode's.
1983 const browsing = browsingOf(going ?? pathname, {
1984 slug: ws?.slug ?? null,
1985 memberships: (user.workspaces ?? []).map((membership) => membership.slug),
1986 shared: shell.shared,
1987 username: user.username,
1988 });
1989 const mode: ModeKey = browsing ? "browse" : modeOf(going ?? pathname, ws?.slug ?? 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.1990 const panel = sidebarFor(mode, ws != null);
Chat and workspace agents: channels, DMs and named agents you talk to1991 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)1992 // Notify: the feed socket's live counts (lib/notify-client.ts) once it has them; the page's until then.
1993 const live = useLiveBadges(ws?.slug);
1994 const chatUnread = chatSidebar
1995 ? unreadTotals(chatSidebar.entries)
1996 : live?.chat != null
1997 ? { unread: live.chat, mentions: live.mentions ?? 0 }
1998 : (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.1999 const notificationsUnread = live?.inbox ?? shell.inbox?.unread ?? 0;
2000 const unread = { notifications: notificationsUnread, chat: chatUnread.unread, mentions: chatUnread.mentions };
2001
2002 // Folding the sidebar away on a computer is remembered, so the next page is drawn the same from the server.
2003 const toggleSidebar = useCallback(() => {
2004 if (!window.matchMedia("(min-width: 1024px)").matches) {
2005 setDrawer((open) => !open);
2006 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)2007 }
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.2008 setClosed((was) => {
2009 document.cookie = sidebarCookie(!was, window.location.protocol === "https:");
2010 return !was;
2011 });
2012 }, []);
2013 useSidebarShortcut(useCallback(() => {
2014 if (panel) toggleSidebar();
2015 }, [panel, toggleSidebar]));
2016
2017 const inline = panel != null && !closed;
2018 const sidebarNode = () => {
2019 if (!panel) return null;
2020 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)2021 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.2022 case "code":
2023 return <CodeSidebar user={user} shell={shell} missing={missing} />;
Merge branch 'worktree-agent-aefe9db9851cfafd8'2024 case "browse":
2025 return <CodeSidebar user={user} shell={shell} missing={missing} browsing={browsing} />;
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)2026 case "chat":
2027 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.2028 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.2029 return <FoliosSidebar slug={ws.slug} />;
2030 case "notifications":
2031 return <NotificationsSidebar counts={shell.inbox ?? null} />;
2032 case "people":
2033 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)2034 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.2035 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)2036 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.2037 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)2038 }
2039 };
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.2040 const sidebarKey = useSidebarKey();
2041 // Search or jump to sits at the top of the sidebar, except in Chat and
2042 // Artifacts, whose sidebars search their own lists: there it stays in the bar.
2043 const sidebarSearch = panel != null && panel !== "chat" && panel !== "artifacts";
2044 // The sidebar's head: the workspace and its switcher, the way to fold the
2045 // sidebar or close the drawer, and search, which opens the 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.2046 const sidebarTop = (inDrawer: boolean) => (
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.2047 <SidebarHeader className="gap-1 px-2 pt-0 pb-2">
2048 <div className="flex h-14 shrink-0 items-center gap-1">
2049 {ws ? (
2050 <WorkspaceSwitcher user={user} workspace={ws} />
2051 ) : (
2052 <Link to="/" aria-label="g1t" className="mr-auto flex h-9 items-center rounded-md px-2">
2053 <Logo className="text-[1.125rem]" />
2054 </Link>
2055 )}
2056 {inDrawer ? (
2057 <Button type="button" aria-label="Close menu" onClick={() => setDrawer(false)} variant="ghost" size="icon-sm" className="text-faint">
2058 <X size={16} />
2059 </Button>
2060 ) : (
2061 <SidebarTrigger hint={`Hide the sidebar (${sidebarKey})`} className="text-faint" />
2062 )}
2063 </div>
2064 {sidebarSearch && <SearchButton place="sidebar" onClick={() => setPalette(true)} />}
2065 </SidebarHeader>
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.2066 );
2067
2068 // 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)2069 const conversation = isConversation(going ?? pathname);
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.2070 // Where the page panel starts: 8px past the rail (56px), or 8px past the sidebar (56 + 240px) when it is open.
The page sits flat against the sidebar. On a computer it fills the rest of the window with no inset, no rounded corners and no frame around it, and its top bar always draws the line under itself, so a page's own header, a conversation's or a project's, sits beneath it as its own band instead of merging with it; the scroll watcher that used to decide when the line appeared is gone. A phone keeps its rounded panel above the bottom bar. The workspaces guide says so.2071 // The page starts where the rail (3.5rem) and, open, the sidebar (15rem) end.
People wear their own avatars wherever g1t knows them only by name, and a workspace is never shown as a person. The activity feeds, recent changes, home's most active faces, issue and pull request authors, assignees, comments and the audit log drew a person from their username alone, so everyone got their letter avatar instead of the picture they uploaded. An avatar given no picture now draws the letter at once and lays the person's own picture over it once it loads, from /-/avatar/user/<username> (routes/avatar-user.ts): a redirect to the picture on the usercontent origin, or not found, read from identity's people only, so a workspace's icon can never stand in for someone. Kept five minutes, public like the profile. Agents, the product tour's people, "someone" and workspaces' square avatars are never looked up (image null), so an account with the same name never lends them its face.2072 const pad = ws ? (inline ? "md:pl-14 lg:pl-74" : "md:pl-14") : inline ? "lg:pl-60" : "";
Chat and workspace agents: channels, DMs and named agents you talk to2073
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists2074 return (
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.2075 <SidebarProvider open={!closed} onOpenChange={(open) => setClosed(!open)} openMobile={drawer} onOpenMobileChange={setDrawer} toggleSidebar={toggleSidebar}>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists2076 <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.2077 {ws && (
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r92078 <div className="fixed top-(--frame-top) bottom-0 left-0 z-40 hidden md:block">
Merge branch 'worktree-agent-aefe9db9851cfafd8'2079 <Rail workspace={ws} mode={mode} pins={shell.pins ?? []} unread={unread} account={<AccountMenu user={user} />} />
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.2080 </div>
2081 )}
2082 {panel && (
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.2083 <Sidebar
2084 role="complementary"
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.2085 aria-label={`${MODE_MENU[panel]} sidebar`}
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r92086 className={`fixed top-(--frame-top) bottom-0 z-40 max-lg:hidden ${ws ? "left-14" : "left-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.2087 >
2088 {sidebarTop(false)}
2089 <div className="min-h-0 grow">{sidebarNode()}</div>
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.2090 </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.2091 )}
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.2092 {/* The drawer is a sheet: a dialog that holds focus, closes on Escape or
2093 a tap outside, and gives focus back to the button that opened it. */}
2094 {panel && (
2095 <SidebarMobile title={`${MODE_MENU[panel]} menu`} className="pb-[env(safe-area-inset-bottom)] max-md:[&_nav_a]:min-h-10">
2096 {sidebarTop(true)}
2097 <div className="min-h-0 grow">{sidebarNode()}</div>
2098 </SidebarMobile>
2099 )}
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists2100
The phone app: Chat in full with phone notifications, plus Code and Customize (#4)2101 <div className={`min-h-dvh pt-(--frame-top) pb-(--tabbar-h) ${pad}`}>
The page sits flat against the sidebar. On a computer it fills the rest of the window with no inset, no rounded corners and no frame around it, and its top bar always draws the line under itself, so a page's own header, a conversation's or a project's, sits beneath it as its own band instead of merging with it; the scroll watcher that used to decide when the line appeared is gone. A phone keeps its rounded panel above the bottom bar. The workspaces guide says so.2102 {/* The top bar always has its line, so a page's own header (data-page-head: a conversation's, a project's,
2103 a sticky one under an open artifact) sits under it as its own band. */}
The phone app: Chat in full with phone notifications, plus Code and Customize (#4)2104 <div className="flex min-h-[calc(100dvh-var(--frame-top)-var(--tabbar-h))] min-w-0 flex-col bg-bg">
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.2105 <header
The phone app: Chat in full with phone notifications, plus Code and Customize (#4)2106 className={`sticky top-(--frame-top) z-30 flex h-14 items-center gap-1 border-b border-line bg-bg pr-2 pl-2 sm:pr-3 ${inline ? "lg:pl-3.5" : ""} ${conversation ? "max-md:hidden" : ""}`}
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists2107 >
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.2108 {panel && (
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.2109 <SidebarTrigger
2110 hint={`Show the sidebar (${sidebarKey})`}
2111 aria-label={drawer ? "Hide the sidebar" : "Show the sidebar"}
2112 aria-expanded={drawer}
2113 className={`max-md:size-11 ${inline ? "lg:hidden" : ""}`}
2114 />
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.2115 )}
2116 {ws && (
2117 <span className={`flex min-w-0 shrink items-center gap-1.5 ${inline ? "lg:hidden" : ""}`}>
2118 <WorkspaceSwitcher user={user} workspace={ws} compact />
2119 <span aria-hidden="true" className="text-line-strong">
2120 /
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)2121 </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.2122 </span>
Inbox: a bell in the top bar opens it beside the page, and /inbox holds it all2123 )}
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.2124 <Breadcrumbs pathname={pathname} missing={missing} repo={shell.repo} workspace={ws?.slug ?? null} />
Merge branch 'ask-g1t'2125 {/* Search, Ask, then the bell and Create new: one height, one rhythm. */}
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.2126 <div className="ml-auto flex shrink-0 items-center gap-1 md:gap-1.5">
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.2127 {/* With the sidebar open, search is at its top. */}
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r92128 {!titleSearch && (
2129 <span className={`flex ${inline && sidebarSearch ? "lg:hidden" : ""}`}>
2130 <SearchButton place="bar" onClick={() => setPalette(true)} />
2131 </span>
2132 )}
Merge branch 'ask-g1t'2133 {ws && <AskButton key={ws.slug} slug={ws.slug} />}
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.2134 <Separator orientation="vertical" className="mx-1 data-[orientation=vertical]:h-5 max-md:hidden" />
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.2135 {/* On a phone, Notifications is in the bottom bar. */}
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.2136 <span className="flex max-md:hidden">
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.2137 <NotificationsBell counts={shell.inbox ? { ...shell.inbox, unread: notificationsUnread } : null} />
2138 </span>
2139 <CreateMenu shell={shell} />
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.2140 {/* Without a workspace there is no rail: the account is here. */}
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.2141 {!ws && <AccountMenu user={user} side="bottom" />}
2142 </div>
2143 </header>
2144 {banner}
2145 <main id="content" tabIndex={-1} {...leaving} className={`min-w-0 grow outline-none ${leaving.className}`}>
2146 <InMain.Provider value={true}>{children}</InMain.Provider>
2147 </main>
2148 </div>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists2149 </div>
Merge branch 'worktree-agent-aefe9db9851cfafd8'2150 {ws && <BottomBar user={user} workspace={ws} mode={mode} pins={shell.pins ?? []} unread={unread} onReselect={panel ? () => setDrawer(true) : 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.2151 <CommandPalette open={palette} onOpenChange={setPalette} commands={commands} repo={shell.repo ? `${shell.repo.namespace}/${shell.repo.name}` : null} />
The left-hand navigation takes less room and reads at a glance. The dock becomes a rail: a 56-pixel column of icons with the g1t mark on top, the current app marked by a filled square, hover hints naming each with its shortcut, the apps you pinned in a scrolling band, and Apps, People, Workspace and your account at the foot. Each mode's sidebar sits flush against it, 240 pixels wide, opening on Search or jump to and listing its groups under small labels in 36-pixel rows; Ctrl B hides it and the page grows into the room. Every mode's list is built on the shadcn Sidebar now in the kit, so Workspace, Code, People, Notifications, account settings, Chat, Artifacts and Agents all share one frame; the phone keeps its bottom bar and drawer. The workspaces guide describes the rail, the sidebar and the page.2152 </SidebarProvider>
Identity: a password reset for a known address that fails to save or send is logged, never answered, so the reply never says an account exists2153 );
2154}
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.2155
2156/** Create new: a project, an issue in the one you are in, a workspace or a team. */
2157function CreateMenu({ shell }: { shell: ShellData }) {
2158 return (
2159 <DropdownMenu>
2160 <Hint label="Create new">
The top of every page is one surface: the breadcrumb, search, spend, Ask g1t, bell and + share one height, corners and spacing, Ask g1t is a plain tinted button with the g1t mark drawn on whole pixels, a page's own header sits directly under the bar at the same left edge, and every section, conversations and open artifacts included, draws the same rounded panel. Tables written in chat render as tables, and the site's file, checkbox, radio, number and date controls are the design system's. Button, Separator, Breadcrumb, Table and FileDrop join the shared components; the chat guide says how tables work.2161 <DropdownMenuTrigger asChild>
2162 <Button variant="ghost" size="bar" aria-label="Create new" className="gap-0.5 px-1.5 text-fg/90">
2163 <Plus size={17} className="max-md:size-5" />
2164 <ChevronDown size={12} className="text-faint max-md:hidden" />
2165 </Button>
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.2166 </DropdownMenuTrigger>
2167 </Hint>
2168 <DropdownMenuContent align="end" className="min-w-52">
2169 {shell.repo && (
2170 <>
2171 <DropdownMenuLabel className="truncate">In {shell.repo.name}</DropdownMenuLabel>
2172 <DropdownMenuItem asChild>
2173 <Link to={`/${shell.repo.namespace}/${shell.repo.name}/issues/new`}>
2174 <CircleDot />
2175 New issue
2176 </Link>
2177 </DropdownMenuItem>
2178 <DropdownMenuSeparator />
2179 </>
2180 )}
2181 <DropdownMenuItem asChild>
2182 <Link to="/new">
2183 <Box />
2184 New project
2185 </Link>
2186 </DropdownMenuItem>
2187 <DropdownMenuItem asChild>
2188 <Link to="/new/github">
2189 <GitBranch />
2190 Import from GitHub
2191 </Link>
2192 </DropdownMenuItem>
Merge remote-tracking branch 'origin/claude/cool-newton-7nm8r9' into claude/cool-newton-7nm8r92193 {/* A team in the workspace you are in, for whoever it lets create one. A new workspace is made from the workspace switcher in the rail. */}
2194 {shell.workspace && <DropdownMenuSeparator />}
g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them.2195 {shell.workspace &&
2196 (mayCreateTeams(shell.workspace.team_creation, shell.workspace.role) ? (
2197 <DropdownMenuItem asChild>
2198 <Link to={`/${shell.workspace.slug}/-/teams/new`}>
2199 <UsersRound />
2200 New team
2201 </Link>
2202 </DropdownMenuItem>
2203 ) : (
2204 <DropdownMenuItem disabled>
2205 <UsersRound />
2206 New team
2207 <span className="ml-auto pl-3 text-xs text-faint">Owners only</span>
2208 </DropdownMenuItem>
2209 ))}
2210 </DropdownMenuContent>
2211 </DropdownMenu>
2212 );
2213}

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