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.
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 1 | /** |
| 2 | * Your own settings: one page for each part, at `/settings/<page>`, so the | |
| 3 | * docs, emails and messages can link to exactly the one they mean. | |
| 4 | */ | |
| 5 | ||
| 6 | export type AccountSettingsPage = | |
| 7 | | "profile" | |
| 8 | | "emails" | |
| Inbox on the site: reasons, a reason filter, Subscribe, Watch and settings | 9 | | "notifications" |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 10 | | "invites" |
| 11 | | "keys" | |
| 12 | | "tokens" | |
| Integrations are a directory of connectors, for a workspace and for each person | 13 | | "integrations" |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 14 | | "github" |
| 15 | | "applications" | |
| Merge main (membership, two-factor, GitHub repo roles) into tokens | 16 | | "two-factor" |
| Merge account deletion: soft delete for 30 days, staff restore and purge, ghost for what remains (identity 0037) | 17 | | "security-log" |
| 18 | | "account"; | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 19 | |
| 20 | /** Each page's name and what it is for, in the sidebar's order. */ | |
| 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) | 21 | export const ACCOUNT_SETTINGS: Record<AccountSettingsPage, { title: string; about: string; heading?: string }> = { |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 22 | profile: { title: "Profile", about: "Your picture, and what everyone sees on your profile." }, |
| 23 | emails: { | |
| 24 | title: "Emails", | |
| 25 | about: | |
| 26 | "Your primary address gets account mail and password resets. Any confirmed address signs you in and can reset your password, and commits that carry it are shown as yours.", | |
| 27 | }, | |
| Inbox on the site: reasons, a reason filter, Subscribe, Watch and settings | 28 | notifications: { |
| 29 | title: "Notifications", | |
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 30 | about: "What you are also emailed for, and how you watch repositories. Everything comes to your notifications either way.", |
| Inbox on the site: reasons, a reason filter, Subscribe, Watch and settings | 31 | }, |
| 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) | 32 | // The invite to g1t, not a workspace's invitation (lib/invites.ts, G1T_INVITES). |
| 33 | invites: { | |
| 34 | title: "Invites to g1t", | |
| 35 | heading: "Invite people to g1t", | |
| 36 | about: | |
| 37 | "An invite to g1t lets one person make an account. It does not add them to any workspace: their account starts with a workspace of its own.", | |
| 38 | }, | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 39 | keys: { title: "SSH keys", about: "Keys that let git on your computers reach g1t as you." }, |
| 40 | tokens: { | |
| 41 | title: "Access tokens", | |
| 42 | about: | |
| 43 | "Use a token as the password when git asks for one over HTTPS, and to authenticate agents and the API. A token here acts as you.", | |
| 44 | }, | |
| Integrations are a directory of connectors, for a workspace and for each person | 45 | integrations: { |
| 46 | title: "Integrations", | |
| 47 | heading: "Your integrations", | |
| 48 | about: | |
| 49 | "Your own accounts, connected just for you and working in every workspace you belong to, such as your calendar setting your status. Tools the whole team shares are a workspace's.", | |
| 50 | }, | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 51 | github: { |
| 52 | title: "GitHub", | |
| 53 | about: "Sign in with your GitHub account, and import or mirror repositories you can reach there.", | |
| 54 | }, | |
| 55 | applications: { | |
| 56 | title: "Connected applications", | |
| 57 | about: | |
| 58 | "Applications you signed in to through your browser, such as an agent connected to the g1t MCP server. Signing one out ends its access at once.", | |
| 59 | }, | |
| Merge main (membership, two-factor, GitHub repo roles) into tokens | 60 | "two-factor": { |
| 61 | title: "Two-factor authentication", | |
| 62 | about: | |
| 63 | "A code from an app on your phone as well as your password when you sign in. Workspaces can require it of their members.", | |
| 64 | }, | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 65 | "security-log": { |
| 66 | title: "Security log", | |
| 67 | about: | |
| Merge main (membership, two-factor, GitHub repo roles) into tokens | 68 | "Changes to your addresses, password, two-factor authentication, keys, tokens and applications, by you or by g1t staff. If you do not recognise one, reset your password.", |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 69 | }, |
| Merge account deletion: soft delete for 30 days, staff restore and purge, ghost for what remains (identity 0037) | 70 | account: { |
| 71 | title: "Account", | |
| 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. | 72 | about: "Your username, how g1t looks to you, and deleting your account.", |
| Merge account deletion: soft delete for 30 days, staff restore and purge, ghost for what remains (identity 0037) | 73 | }, |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 74 | }; |
| 75 | ||
| 76 | /** Where the first page is: `/settings` goes there. */ | |
| 77 | export const FIRST_SETTINGS_PAGE = "/settings/profile"; | |
| 78 | ||
| 79 | /** | |
| 80 | * The sections of the old single settings page, by their `#anchor`, and | |
| 81 | * the page each now has. Links like `g1t.sh/settings#emails` in old email | |
| 82 | * and bookmarks still land in the right place. | |
| 83 | */ | |
| 84 | const OLD_ANCHORS: Record<string, AccountSettingsPage> = { | |
| 85 | picture: "profile", | |
| 86 | profile: "profile", | |
| 87 | emails: "emails", | |
| 88 | github: "github", | |
| 89 | invites: "invites", | |
| 90 | "ssh-keys": "keys", | |
| 91 | tokens: "tokens", | |
| 92 | applications: "applications", | |
| 93 | "security-log": "security-log", | |
| 94 | }; | |
| 95 | ||
| 96 | /** The page an old `#anchor` of the settings page now lives at, if it was one. */ | |
| 97 | export function settingsPathForHash(hash: string): string | null { | |
| 98 | const page = OLD_ANCHORS[hash.replace(/^#/, "")]; | |
| 99 | return page ? `/settings/${page}` : null; | |
| 100 | } | |
| 101 | ||
| One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers | 102 | /** Which settings page a path is, or null when it is none. A page within one (a token under Access tokens) is that page's. */ |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 103 | export function accountSettingsPage(pathname: string): AccountSettingsPage | null { |
| One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers | 104 | const match = /^\/settings\/([^/]+)(?:\/.*)?$/.exec(pathname); |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 105 | const page = match?.[1]; |
| 106 | return page && page in ACCOUNT_SETTINGS ? (page as AccountSettingsPage) : null; | |
| 107 | } |
This file's history is long; its oldest lines are credited to the oldest commit read.