Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 1 | /** |
| Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell. | 2 | * The rail's built-in apps, the apps a workspace added in Customize, and |
| 3 | * the ones each person pins to their 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. | 4 | * |
| 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. | 5 | * Built-in apps (Home, Chat, Notifications, Agents, Code, Artifacts, |
| 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. | 6 | * People and Workspace) are always in the rail; their own pages (Projects, |
| 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. | 7 | * Usage, Teams and the rest) are in their sidebars. Apps are what the |
| Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell. | 8 | * workspace added in Customize: the plugins it installed (each opening its |
| 9 | * page), the connectors it connected, and the integrations it connected, | |
| 10 | * each opening where it is looked after. Each person pins the ones they | |
| 11 | * want. | |
| 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. | 12 | * |
| 13 | * An installed app's key says what it is: `int-<connector>` for an | |
| Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell. | 14 | * integration (@g1t/contracts/connectors), `plg-<install>` for a plugin, |
| 15 | * `con-<connector>` for a connector. Only integrations are pinned: they | |
| 16 | * are known from the catalog alone, so a pin can be read without asking a | |
| 17 | * service. A key that names nothing pinnable (a built-in page pinned | |
| 18 | * before Apps were Customize's, an extension from before plugins) is | |
| 19 | * dropped wherever pins are read. | |
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 20 | * |
| The apps you pin to your dock are kept with your account, per workspace and in your order, so the dock is the same on every device: identity keeps them in dock_pins and answers dock_pins and set_dock_pins, the dock reads them with the rest of the page, pins kept only on this device carry over with your first change, this device's copy still draws the dock when identity can't be reached, a pin that can't be saved says so, and they go when you or the workspace do; the workspaces guide says how. | 21 | * Pins are each person's own, per workspace, in the order they set, and |
| 22 | * kept with their account by the identity service (`dock_pins`), so the | |
| 23 | * dock is the same on every device (lib/dock.server.ts). A cookie | |
| 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. | 24 | * (`g1t_dock`) keeps a copy on each device: the rail still draws from it |
| The apps you pin to your dock are kept with your account, per workspace and in your order, so the dock is the same on every device: identity keeps them in dock_pins and answers dock_pins and set_dock_pins, the dock reads them with the rest of the page, pins kept only on this device carry over with your first change, this device's copy still draws the dock when identity can't be reached, a pin that can't be saved says so, and they go when you or the workspace do; the workspaces guide says how. | 25 | * when identity cannot be reached, and pins from before they were kept |
| 26 | * with the account carry over from it until the first change. | |
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 27 | * No Workers or React imports, so it can be tested under Node. |
| 28 | */ | |
| Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell. | 29 | import type { PluginInstall, WorkspaceConnector } from "@g1t/contracts"; |
| 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. | 30 | import { CONNECTORS, type Connector, connectorPath } from "@g1t/contracts/connectors"; |
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 31 | |
| Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell. | 32 | import { connectorPagePath, pluginPath } from "./customize.ts"; |
| 33 | ||
| 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. | 34 | /** The apps that are always in the rail. */ |
| 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. | 35 | export type BuiltinApp = "home" | "chat" | "notifications" | "agents" | "code" | "artifacts" | "people" | "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. | 36 | |
| 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. | 37 | export type BuiltinInfo = { |
| 38 | key: BuiltinApp; | |
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 39 | name: string; |
| 40 | /** Its page in the workspace `slug`. */ | |
| 41 | path: (slug: string) => string; | |
| 42 | /** Part of Code: only for members with Code access. */ | |
| 43 | code?: boolean; | |
| 44 | }; | |
| 45 | ||
| 46 | const under = (page: string) => (slug: string) => `/${slug}/-/${page}`; | |
| 47 | ||
| 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. | 48 | /** The rail's built-in apps, in its order. */ |
| 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. | 49 | export const BUILTINS: BuiltinInfo[] = [ |
| 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. | 50 | { key: "home", name: "Home", path: under("home") }, |
| 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. | 51 | { key: "chat", name: "Chat", path: under("chat") }, |
| 52 | { key: "notifications", name: "Notifications", path: () => "/notifications" }, | |
| 53 | { key: "agents", name: "Agents", path: under("agents") }, | |
| 54 | { key: "code", name: "Code", path: under("overview"), code: true }, | |
| 55 | { key: "artifacts", name: "Artifacts", path: under("artifacts") }, | |
| 56 | { key: "people", name: "People", path: under("people") }, | |
| 57 | { key: "workspace", name: "Workspace", path: under("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. | 58 | ]; |
| 59 | ||
| 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. | 60 | /** The built-in app `key`. */ |
| 61 | export function appOf(key: BuiltinApp): BuiltinInfo { | |
| 62 | return BUILTINS.find((app) => app.key === key)!; | |
| 63 | } | |
| 64 | ||
| 65 | /** An installed app's key, as pins and forms carry it: `int-sentry`. */ | |
| 66 | export type PinnableApp = string; | |
| 67 | ||
| Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell. | 68 | /** An app the workspace added in Customize. */ |
| 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. | 69 | export type InstalledApp = { |
| 70 | key: PinnableApp; | |
| 71 | name: string; | |
| 72 | /** What it is, in a few words. */ | |
| 73 | about: string; | |
| Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell. | 74 | /** The listing it was added from: `integration:sentry`, `plugin:pdf@anthropic-agent-skills`, `connector:con_…`. */ |
| 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. | 75 | listing: string; |
| Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell. | 76 | /** Where it is from, in a word or two: g1t, its marketplace, or Connector. */ |
| 77 | from: string; | |
| 78 | /** What draws its mark: a connector's id and name, and its provider when it has one. */ | |
| 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. | 79 | connector: Pick<Connector, "id" | "name" | "provider">; |
| 80 | /** Its page in the workspace `slug`. */ | |
| 81 | path: (slug: string) => string; | |
| 82 | /** | |
| 83 | * Whether the person can open it. Every member can open an integration's | |
| 84 | * page; an app limited to some people shows Request access to the rest. | |
| 85 | */ | |
| 86 | usable: boolean; | |
| Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell. | 87 | /** Whether it can be pinned to the rail: only what the catalog alone knows. */ |
| 88 | pinnable: boolean; | |
| 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. | 89 | }; |
| 90 | ||
| 91 | /** Where an integration is looked after: its setup page, by kind, or its own page. */ | |
| 92 | const SECTION_BY_CATEGORY: Partial<Record<Connector["category"], string>> = { ai: "models", monitoring: "alerts", issues: "trackers" }; | |
| 93 | ||
| 94 | function integrationPath(connector: Connector): (slug: string) => string { | |
| 95 | const section = connector.provider ? SECTION_BY_CATEGORY[connector.category] : undefined; | |
| 96 | if (section) return under(`integrations/${section}`); | |
| 97 | const href = connector.href?.workspace; | |
| 98 | return href ? (slug) => connectorPath(href, slug) : under("integrations"); | |
| 99 | } | |
| 100 | ||
| 101 | /** Identity keeps keys of at most this many characters (MAX_DOCK_APP_KEY). */ | |
| 102 | const MAX_KEY = 32; | |
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 103 | |
| 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. | 104 | /** The installed-app key for an integration: `int-sentry`. */ |
| 105 | export function integrationAppKey(connectorId: string): PinnableApp { | |
| 106 | return `int-${connectorId}`; | |
| 107 | } | |
| 108 | ||
| 109 | /** | |
| 110 | * The app a key names, from the catalog alone (no service is asked), or | |
| 111 | * null when it names nothing that can be installed: a retired key, a | |
| 112 | * built-in page, or a connector that is not available for a workspace. | |
| 113 | */ | |
| 114 | export function installedAppOf(key: string): InstalledApp | null { | |
| Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell. | 115 | if (key.length > MAX_KEY || !/^int-[a-z0-9][a-z0-9-]*$/.test(key)) return null; |
| 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. | 116 | const connector = CONNECTORS.find((c) => c.id === key.slice(4)); |
| 117 | if (!connector || connector.status !== "available" || !connector.scopes.includes("workspace")) return null; | |
| 118 | return { | |
| 119 | key, | |
| 120 | name: connector.name, | |
| 121 | about: connector.description, | |
| 122 | listing: `integration:${connector.id}`, | |
| Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell. | 123 | from: "g1t", |
| 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. | 124 | connector: { id: connector.id, name: connector.name, provider: connector.provider }, |
| 125 | path: integrationPath(connector), | |
| 126 | usable: true, | |
| Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell. | 127 | pinnable: true, |
| 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. | 128 | }; |
| 129 | } | |
| 130 | ||
| Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell. | 131 | /** An installed plugin as an app: its page in Customize. Switched off (the kill switch), it isn't an app until it is on again. */ |
| 132 | export function pluginApp(install: Pick<PluginInstall, "id" | "ref" | "name" | "display_name" | "description" | "marketplace" | "enabled">): InstalledApp | null { | |
| 133 | if (!install.enabled) return null; | |
| 134 | const name = install.display_name ?? install.name; | |
| 135 | return { | |
| 136 | key: `plg-${install.id}`, | |
| 137 | name, | |
| 138 | about: install.description, | |
| 139 | listing: `plugin:${install.ref}`, | |
| 140 | from: install.marketplace, | |
| 141 | connector: { id: install.ref, name, provider: undefined }, | |
| 142 | path: (slug) => pluginPath(slug, install.ref), | |
| 143 | usable: true, | |
| 144 | pinnable: false, | |
| 145 | }; | |
| 146 | } | |
| 147 | ||
| 148 | /** A workspace connector as an app: its page in Customize. */ | |
| 149 | export function connectorApp(connector: Pick<WorkspaceConnector, "id" | "title" | "about" | "url">): InstalledApp { | |
| 150 | return { | |
| 151 | key: `con-${connector.id}`, | |
| 152 | name: connector.title, | |
| 153 | about: connector.about ?? connector.url, | |
| 154 | listing: `connector:${connector.id}`, | |
| 155 | from: "Connector", | |
| 156 | connector: { id: connector.id, name: connector.title, provider: undefined }, | |
| 157 | path: (slug) => connectorPagePath(slug, connector.id), | |
| 158 | usable: true, | |
| 159 | pinnable: false, | |
| 160 | }; | |
| 161 | } | |
| 162 | ||
| 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. | 163 | /** Whether `key` names an app that can be pinned. */ |
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 164 | export function isPinnable(key: string): key is PinnableApp { |
| 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. | 165 | return installedAppOf(key) != 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. | 166 | } |
| 167 | ||
| 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. | 168 | /** |
| Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell. | 169 | * The apps the workspace added: its plugins that are on, its connectors, |
| 170 | * and the integrations it has connected (by connector id, | |
| 171 | * lib/connected.server.ts) in catalog order. `manage`, when a connection | |
| 172 | * has one, is where its app opens. | |
| 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. | 173 | */ |
| 174 | export function installedApps( | |
| 175 | connected: Record<string, { manage: string | null }>, | |
| Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell. | 176 | installs: readonly Parameters<typeof pluginApp>[0][] = [], |
| 177 | connectors: readonly Parameters<typeof connectorApp>[0][] = [], | |
| 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. | 178 | ): InstalledApp[] { |
| 179 | const integrations = CONNECTORS.filter((connector) => connected[connector.id]).map((connector) => { | |
| 180 | const app = installedAppOf(integrationAppKey(connector.id)); | |
| 181 | const manage = connected[connector.id]?.manage; | |
| 182 | return app && manage ? { ...app, path: () => manage } : app; | |
| 183 | }); | |
| Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell. | 184 | return [...installs.map(pluginApp), ...connectors.map(connectorApp), ...integrations].filter((app): app is InstalledApp => app != 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. | 185 | } |
| 186 | ||
| 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. | 187 | /** An app as a loader sends it: everything but its path, which is worked out for the workspace. */ |
| 188 | export type InstalledAppData = Omit<InstalledApp, "path"> & { href: string }; | |
| 189 | ||
| 190 | export function appData(app: InstalledApp, slug: string): InstalledAppData { | |
| 191 | const { path, ...rest } = app; | |
| 192 | return { ...rest, href: path(slug) }; | |
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 193 | } |
| 194 | ||
| The apps you pin to your dock are kept with your account, per workspace and in your order, so the dock is the same on every device: identity keeps them in dock_pins and answers dock_pins and set_dock_pins, the dock reads them with the rest of the page, pins kept only on this device carry over with your first change, this device's copy still draws the dock when identity can't be reached, a pin that can't be saved says so, and they go when you or the workspace do; the workspaces guide says how. | 195 | /** The cookie that keeps this device's copy of each person's pins, per 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. | 196 | export const DOCK_COOKIE = "g1t_dock"; |
| 197 | ||
| The apps you pin to your dock are kept with your account, per workspace and in your order, so the dock is the same on every device: identity keeps them in dock_pins and answers dock_pins and set_dock_pins, the dock reads them with the rest of the page, pins kept only on this device carry over with your first change, this device's copy still draws the dock when identity can't be reached, a pin that can't be saved says so, and they go when you or the workspace do; the workspaces guide says how. | 198 | /** |
| 199 | * Most workspaces the cookie remembers pins for, and most pins in each. | |
| 200 | * Identity keeps up to 24 (`MAX_DOCK_PINS`); this stays under it. | |
| 201 | */ | |
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 202 | const MAX_WORKSPACES = 20; |
| 203 | export const MAX_APP_PINS = 12; | |
| 204 | ||
| The apps you pin to your dock are kept with your account, per workspace and in your order, so the dock is the same on every device: identity keeps them in dock_pins and answers dock_pins and set_dock_pins, the dock reads them with the rest of the page, pins kept only on this device carry over with your first change, this device's copy still draws the dock when identity can't be reached, a pin that can't be saved says so, and they go when you or the workspace do; the workspaces guide says how. | 205 | /** |
| 206 | * Pins as identity keeps them, read against the apps there are: keys that | |
| 207 | * are not an app people pin (one since retired, say) are dropped, repeats | |
| 208 | * too, in the order they were set. | |
| 209 | */ | |
| 210 | export function pinsFrom(keys: readonly string[]): PinnableApp[] { | |
| 211 | return [...new Set(keys.filter(isPinnable))].slice(0, MAX_APP_PINS); | |
| 212 | } | |
| 213 | ||
| 214 | /** | |
| 215 | * The pins to draw in the workspace `slug`: the account's when identity | |
| 216 | * has them (`stored`), else this device's cookie, for pins never saved to | |
| 217 | * the account or when identity could not be asked. | |
| 218 | */ | |
| 219 | export function pinsToShow(stored: readonly string[] | null | undefined, cookie: string | null | undefined, slug: string): PinnableApp[] { | |
| 220 | return stored ? pinsFrom(stored) : pinsIn(cookie, slug); | |
| 221 | } | |
| 222 | ||
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 223 | /** Every workspace's pins, from the cookie's value: `acme:projects.usage,beta:teams`. */ |
| 224 | export function readDock(value: string | null | undefined): Record<string, PinnableApp[]> { | |
| 225 | const dock: Record<string, PinnableApp[]> = {}; | |
| 226 | for (const entry of (value ?? "").split(",")) { | |
| 227 | const [slug, keys] = entry.split(":"); | |
| 228 | if (!slug || !/^[a-z0-9-]+$/.test(slug) || keys === undefined) continue; | |
| 229 | const pins = [...new Set(keys.split(".").filter(isPinnable))].slice(0, MAX_APP_PINS); | |
| 230 | dock[slug] = pins; | |
| 231 | } | |
| 232 | return dock; | |
| 233 | } | |
| 234 | ||
| 235 | /** The pins in the workspace `slug`, in the order they were pinned. */ | |
| 236 | export function pinsIn(value: string | null | undefined, slug: string): PinnableApp[] { | |
| 237 | return readDock(value)[slug.toLowerCase()] ?? []; | |
| 238 | } | |
| 239 | ||
| 240 | /** The cookie's value with the workspace `slug`'s pins set to `pins`: the latest workspace first. */ | |
| 241 | export function writeDock(value: string | null | undefined, slug: string, pins: PinnableApp[]): string { | |
| 242 | const dock = readDock(value); | |
| 243 | const key = slug.toLowerCase(); | |
| 244 | delete dock[key]; | |
| 245 | const entries = [[key, [...new Set(pins.filter(isPinnable))].slice(0, MAX_APP_PINS)] as const, ...Object.entries(dock)].slice(0, MAX_WORKSPACES); | |
| 246 | return entries.map(([name, keys]) => `${name}:${keys.join(".")}`).join(","); | |
| 247 | } | |
| 248 | ||
| 249 | /** One change to someone's pins, as the pin buttons post it; null when it asks for nothing that makes sense. */ | |
| 250 | export function appPinFromForm(form: FormData): { app: PinnableApp; pinned: boolean } | null { | |
| 251 | const app = String(form.get("app") ?? ""); | |
| 252 | const intent = form.get("intent"); | |
| 253 | if (!isPinnable(app) || (intent !== "pin" && intent !== "unpin")) return null; | |
| 254 | return { app, pinned: intent === "pin" }; | |
| 255 | } | |
| 256 | ||
| 257 | /** The pins after pinning or unpinning `app`: a new pin goes at the end. */ | |
| 258 | export function withPin(pins: PinnableApp[], app: PinnableApp, pinned: boolean): PinnableApp[] { | |
| 259 | const rest = pins.filter((key) => key !== app); | |
| 260 | return pinned ? [...rest, app] : rest; | |
| 261 | } | |
| 262 | ||
| 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. | 263 | /** The Set-Cookie header that keeps the rail, for a year. */ |
| g1t is described as the product it is in alpha, and its shell takes the new shape: the README, the docs home and docs/PLAN.md label every feature Live, Preview or Coming; a floating dock with the g1t mark, Today, Chat, Notifications, Agents, Code, Artifacts, your pinned apps and the Apps launcher, with People, Workspace and the account menu (now holding help) at its foot; the workspace's logo and switcher heading a flat sidebar that folds away with Ctrl B, or leading the header's breadcrumbs where there is none; the page in a rounded panel with a full-width header; Today as the front page, with first-time acceptance of agents' pull requests, what needs you and what's at stake, spend today and one item to start with, every number from a service; Notifications in place of the Inbox at /notifications; a bottom bar and More sheet on phones; and sign-in, sign-up, two-factor, reset, invites and choosing a workspace on standalone pages with no app around them. | 264 | export function dockCookie(value: string, secure: boolean): string { |
| 265 | return `${DOCK_COOKIE}=${encodeURIComponent(value)}; Path=/; Max-Age=31536000; SameSite=Lax${secure ? "; Secure" : ""}`; | |
| 266 | } | |
| 267 | ||
| 268 | /** The cookie that remembers whether the in-context sidebar is folded away on a computer. */ | |
| 269 | export const SIDEBAR_COOKIE = "g1t_sidebar"; | |
| 270 | ||
| 271 | /** Whether the sidebar is folded away, from the cookie's value. */ | |
| 272 | export function sidebarClosed(value: string | null | undefined): boolean { | |
| 273 | return value === "closed"; | |
| 274 | } | |
| 275 | ||
| 276 | /** The cookie, as the page sets it when the sidebar is folded away or brought back. */ | |
| 277 | export function sidebarCookie(closed: boolean, secure: boolean): string { | |
| 278 | return `${SIDEBAR_COOKIE}=${closed ? "closed" : "open"}; Path=/; Max-Age=31536000; SameSite=Lax${secure ? "; Secure" : ""}`; | |
| 279 | } |
This file's history is long; its oldest lines are credited to the oldest commit read.