Skip to content
88 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.

Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar1import { data, useFetcher } from "react-router";
2
3import type { Route } from "./+types/security-settings";
4import { page } from "../../lib/meta";
5import { ActivationPrompt, CARD } from "../../components/security-suite";
6import { WorkspaceSecurityHeading, WorkspaceSecurityTabs } from "../../components/workspace-security-tabs";
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.7import { Button } from "../../components/ui/button";
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar8import { Switch } from "../../components/ui/switch";
9import { securitySuite } from "../../lib/services.server";
Merge main (membership, two-factor, GitHub repo roles) into tokens10import { assertSameOrigin, getViewer, managesSecurity, requireUser, roleIn, unwrap } from "../../lib/session.server";
Pricing says it plainly: models at the provider's price, the agent rate for what g1t runs around every model call (the gateway, secrets, routing, context and pass-through to your own provider, so your own keys too), everything else at cost plus 20%, your own runners free, no seats; Security and quality comes with the plan with no separate fee, and live activations end. Each agent has an effort setting, Auto to Max, with what a typical task has cost at each level, and Spend's Spend less, keep quality suggests a lower level only when the agent's own past work shows quality held, to apply or dismiss. The pricing, spend and agents guides say how.11import { planPrice } from "../../lib/security-suite.server";
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar12
13export function meta({ params, ...args }: Route.MetaArgs) {
14 return page(args, { title: `Security settings · ${params.owner} · g1t` });
15}
16
17export async function loader({ params, context }: Route.LoaderArgs) {
18 const viewer = getViewer(context);
19 const role = roleIn(viewer, params.owner);
20 if (!role) throw data(null, { status: 404 });
Pricing says it plainly: models at the provider's price, the agent rate for what g1t runs around every model call (the gateway, secrets, routing, context and pass-through to your own provider, so your own keys too), everything else at cost plus 20%, your own runners free, no seats; Security and quality comes with the plan with no separate fee, and live activations end. Each agent has an effort setting, Auto to Max, with what a typical task has cost at each level, and Spend's Spend less, keep quality suggests a lower level only when the agent's own past work shows quality held, to apply or dismiss. The pricing, spend and agents guides say how.21 const [view, price] = await Promise.all([securitySuite.workspaceSettings(params.owner, viewer), planPrice(params.owner, viewer)]);
Merge main (membership, two-factor, GitHub repo roles) into tokens22 return { view: unwrap(view), price, owner: managesSecurity(viewer, params.owner) };
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar23}
24
25export async function action({ params, context, request }: Route.ActionArgs) {
26 assertSameOrigin(request);
27 const user = requireUser(context, request);
28 const form = await request.formData();
29 const saved = await securitySuite.setWorkspaceSettings(user, params.owner, {
30 delegatedBypass: form.get("delegatedBypass") === "on",
31 validityChecks: form.get("validityChecks") === "on",
32 });
33 return saved.ok ? { ok: true } : { ok: false, error: saved.error.message };
34}
35
36function Row({ name, title, about, checked, disabled }: { name: string; title: string; about: string; checked: boolean; disabled: boolean }) {
37 return (
38 <label className={`${CARD} flex items-start justify-between gap-4 p-4 ${disabled ? "opacity-60" : ""}`}>
39 <span>
40 <span className="block text-sm font-medium">{title}</span>
41 <span className="mt-1 block text-sm text-muted">{about}</span>
42 </span>
43 <Switch name={name} defaultChecked={checked} disabled={disabled} className="mt-0.5" />
44 </label>
45 );
46}
47
48export default function WorkspaceSecuritySettings({ loaderData, params }: Route.ComponentProps) {
49 const { view, price, owner } = loaderData;
50 const fetcher = useFetcher<{ ok: boolean; error?: string }>();
51 const disabled = !owner;
52 return (
53 <div>
54 <WorkspaceSecurityHeading title="Security settings" about="How push protection treats bypasses, and whether g1t asks secrets' issuers if they still work, in every repository of the workspace." />
55 <WorkspaceSecurityTabs owner={params.owner} />
56 {!view.activated && (
57 <div className="mb-4">
58 <ActivationPrompt workspace={params.owner} feature="Delegated bypass and validity checks" monthlyCents={price} isOwner={owner} />
59 </div>
60 )}
61 <fetcher.Form method="post" className="space-y-3">
62 <Row
63 name="delegatedBypass"
64 title="Delegated bypass"
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.65 about="Someone who pushes a blocked secret asks to push it anyway, and an owner or the repository's admins approve or deny the request, told in their notifications. Off: they bypass it themselves, with a reason."
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar66 checked={view.settings.delegatedBypass}
67 disabled={disabled}
68 />
69 <Row
70 name="validityChecks"
71 title="Validity checks"
72 about="Ask each secret's issuer whether it still works (GitHub, GitLab, Stripe, Slack, npm, OpenAI, Anthropic and SendGrid tokens), weekly and on request, and mark the alert active or inactive. The check is the issuer's own read-only call, over HTTPS; the secret goes nowhere else."
73 checked={view.settings.validityChecks}
74 disabled={disabled}
75 />
76 <div className="flex items-center gap-3 pt-1">
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.77 <Button type="submit" disabled={disabled || fetcher.state !== "idle"}>
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar78 {fetcher.state !== "idle" ? "Saving…" : "Save"}
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.79 </Button>
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar80 {!owner && <span className="text-sm text-muted">Only an owner can change these.</span>}
Merge branch 'worktree-agent-ad7c6d88d93adc817'81 {fetcher.data?.ok && <span className="text-sm text-success">Saved.</span>}
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar82 {fetcher.data?.error && <span className="text-sm text-danger">{fetcher.data.error}</span>}
83 </div>
84 </fetcher.Form>
Pricing says it plainly: models at the provider's price, the agent rate for what g1t runs around every model call (the gateway, secrets, routing, context and pass-through to your own provider, so your own keys too), everything else at cost plus 20%, your own runners free, no seats; Security and quality comes with the plan with no separate fee, and live activations end. Each agent has an effort setting, Auto to Max, with what a typical task has cost at each level, and Spend's Spend less, keep quality suggests a lower level only when the agent's own past work shows quality held, to apply or dismiss. The pricing, spend and agents guides say how.85 <p className="mt-4 text-xs text-faint">On private repositories both come with the g1t plan; on public ones they are free.</p>
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar86 </div>
87 );
88}

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