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.
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 1 | import assert from "node:assert/strict"; |
| 2 | import { test } from "node:test"; | |
| 3 | ||
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 4 | import { frameOf, projectPageAt, projectPages } from "./chrome.ts"; |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 5 | |
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 6 | const visitor = { signedIn: false, workspace: false }; |
| 7 | const member = { signedIn: true, workspace: true }; | |
| 8 | const newcomer = { signedIn: true, workspace: false }; | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 9 | |
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 10 | test("signing in, signing up and choosing a workspace stand alone, for everyone", () => { |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 11 | for (const path of [ |
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 12 | "/login", |
| 13 | "/login/two-factor", | |
| 14 | "/register", | |
| 15 | "/register/", | |
| 16 | "/invite/abc123", | |
| 17 | "/verify", | |
| 18 | "/confirm-email", | |
| 19 | "/forgot", | |
| 20 | "/reset", | |
| 21 | "/device", | |
| 22 | "/oauth/authorize", | |
| 23 | "/auth/github/callback", | |
| 24 | "/auth/github/username", | |
| 25 | "/workspaces/new", | |
| 26 | "/workspaces/new.data", | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 27 | ]) { |
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 28 | for (const viewer of [visitor, member, newcomer]) assert.equal(frameOf(path, viewer), "standalone", path); |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 29 | } |
| 30 | }); | |
| 31 | ||
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 32 | test("answering an invitation stands alone until you belong to a workspace", () => { |
| 33 | assert.equal(frameOf("/invitations", newcomer), "standalone"); | |
| 34 | assert.equal(frameOf("/invitations", member), "app"); | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 35 | }); |
| 36 | ||
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 37 | test("someone signed in gets the app everywhere else, public pages included", () => { |
| 38 | for (const path of ["/", "/explore", "/u/ada", "/other/web", "/acme/-/today", "/notifications", "/pricing", "/does/not/exist"]) { | |
| 39 | assert.equal(frameOf(path, member), "app", path); | |
| 40 | assert.equal(frameOf(path, newcomer), "app", path); | |
| Chat controls, public profiles, shadcn selects, and no Docs tab in a project | 41 | } |
| 42 | }); | |
| 43 | ||
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 44 | test("a visitor gets the public frame everywhere else", () => { |
| 45 | for (const path of ["/", "/explore", "/search", "/u/ada", "/acme", "/acme/web", "/acme/web/issues/4", "/policies/privacy", "/nothing/here/at/all"]) { | |
| 46 | assert.equal(frameOf(path, visitor), "public", path); | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 47 | } |
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 48 | // A workspace named like a page is still a workspace, and still public to a visitor. |
| 49 | assert.equal(frameOf("/loginx", visitor), "public"); | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 50 | }); |
| 51 | ||
| 52 | test("a project's menu hides member-only pages from everyone else", () => { | |
| 53 | const visitor = projectPages(false); | |
| 54 | assert.deepEqual(visitor.slice(0, 5), ["code", "issues", "pulls", "agents", "actions"]); | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 55 | for (const page of ["security", "settings"] as const) { |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 56 | assert.ok(!visitor.includes(page), page); |
| 57 | assert.ok(projectPages(true).includes(page), page); | |
| 58 | } | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 59 | // Security needs push once the role is known: Read and Triage do not see it. |
| 60 | assert.ok(!projectPages(true, { push: false }).includes("security")); | |
| 61 | assert.ok(projectPages(true, { push: true }).includes("security")); | |
| 62 | // Anyone who can read a repository sees its deployments. | |
| 63 | assert.ok(visitor.includes("deployments") && projectPages(true).includes("deployments")); | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 64 | }); |
| 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 bar | 65 | |
| 66 | test("the phone's project strip lights the page a path is under", () => { | |
| 67 | assert.equal(projectPageAt(""), "overview"); | |
| 68 | assert.equal(projectPageAt("blob/main/README.md"), "code"); | |
| 69 | assert.equal(projectPageAt("commit/abc123"), "code"); | |
| 70 | assert.equal(projectPageAt("issues/12"), "issues"); | |
| 71 | assert.equal(projectPageAt("milestones"), "issues"); | |
| 72 | assert.equal(projectPageAt("pull/3/files"), "pulls"); | |
| 73 | assert.equal(projectPageAt("queue"), "pulls"); | |
| 74 | assert.equal(projectPageAt("sessions/abc"), "agents"); | |
| 75 | assert.equal(projectPageAt("actions/runs/9"), "actions"); | |
| 76 | assert.equal(projectPageAt("security/secret-scanning"), "security"); | |
| 77 | assert.equal(projectPageAt("stargazers"), "insights"); | |
| 78 | assert.equal(projectPageAt("settings/branches"), "settings"); | |
| 79 | assert.equal(projectPageAt("soon/logs", { logs: "observability" }), "observability"); | |
| 80 | assert.equal(projectPageAt("soon/boards", { boards: "issues" }), "issues"); | |
| 81 | assert.equal(projectPageAt("pulse"), null); | |
| 82 | }); |