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.
| Integrations are a directory of connectors, for a workspace and for each person | 1 | import { redirect } from "react-router"; |
| 2 | ||
| 3 | import { type Provider, PROVIDERS } 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. | 4 | import { connectorsFor } from "@g1t/contracts/connectors"; |
| Integrations are a directory of connectors, for a workspace and for each person | 5 | |
| 6 | import type { Route } from "./+types/integrations-directory"; | |
| 7 | import { ConnectorDirectory, ScopeNote } from "../../components/connectors"; | |
| 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. | 8 | import { connectedStates } from "../../lib/connected.server"; |
| Integrations are a directory of connectors, for a workspace and for each person | 9 | import { integrationsSection } from "../../lib/integration-sections"; |
| 10 | import { page } from "../../lib/meta"; | |
| Merge branch 'browser-pass' into fast-push | 11 | import { requireUser, roleIn } from "../../lib/session.server"; |
| Integrations are a directory of connectors, for a workspace and for each person | 12 | |
| 13 | export function meta({ params, ...args }: Route.MetaArgs) { | |
| 14 | return page(args, { title: `Integrations · ${params.owner} · g1t` }); | |
| 15 | } | |
| 16 | ||
| 17 | /** | |
| 18 | * The workspace's integrations: every connector g1t has or will have, by | |
| 19 | * category, with what this workspace has connected first. Each one is set | |
| 20 | * up on its own page (the model providers, alerts and trackers pages, the | |
| 21 | * GitHub import, webhooks); this page only finds them. | |
| 22 | */ | |
| 23 | export async function loader({ params, context, request }: Route.LoaderArgs) { | |
| Merge branch 'browser-pass' into fast-push | 24 | // Signed out, sign in first (as Chat and Docs do), rather than a 404. |
| 25 | const viewer = requireUser(context, request); | |
| Integrations are a directory of connectors, for a workspace and for each person | 26 | const role = roleIn(viewer, params.owner); |
| 27 | if (!role || !viewer) throw new Response(null, { status: 404 }); | |
| 28 | const slug = params.owner.toLowerCase(); | |
| 29 | ||
| 30 | // An older link to one provider's form (`?add=sentry`): its own page now. | |
| 31 | const add = new URL(request.url).searchParams.get("add"); | |
| 32 | if (add && add in PROVIDERS) { | |
| 33 | throw redirect(`/${slug}/-/integrations/${integrationsSection(PROVIDERS[add as Provider].kind)}?add=${add}#add`); | |
| 34 | } | |
| 35 | ||
| 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. | 36 | return { slug, owner: role === "owner", connected: await connectedStates(slug, viewer) }; |
| Integrations are a directory of connectors, for a workspace and for each person | 37 | } |
| 38 | ||
| 39 | export default function WorkspaceIntegrationsDirectory({ loaderData }: Route.ComponentProps) { | |
| 40 | const { slug, owner, connected } = loaderData; | |
| 41 | return ( | |
| 42 | <div> | |
| 43 | <ScopeNote scope="workspace" workspace={slug} /> | |
| 44 | <ConnectorDirectory | |
| 45 | scope="workspace" | |
| 46 | views={connectorsFor("workspace")} | |
| 47 | connected={connected} | |
| 48 | workspace={slug} | |
| 49 | canManage={owner} | |
| 50 | /> | |
| 51 | </div> | |
| 52 | ); | |
| 53 | } |
This file's history is long; its oldest lines are credited to the oldest commit read.