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.
| 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. | 1 | /** |
| 2 | * What the Marketplace's pages read: the agent catalog's roles with the | |
| 3 | * workspace's agents, and what the workspace has connected. Each part that | |
| 4 | * does not answer comes back null, and the page says so. | |
| 5 | */ | |
| 6 | import type { AgentTemplate, User, WorkspaceAgent } from "@g1t/contracts"; | |
| 7 | ||
| 8 | import type { ConnectedState } from "./connectors"; | |
| 9 | import { connectedStates } from "./connected.server"; | |
| 10 | import { workspaceAgents } from "./services.server"; | |
| 11 | ||
| 12 | /** An agent as the Marketplace needs it: who it is and which role it was hired into. */ | |
| 13 | export type HiredAgent = Pick<WorkspaceAgent, "id" | "handle" | "display_name" | "template" | "archived_at">; | |
| 14 | ||
| 15 | export async function loadCatalog(slug: string, viewer: User): Promise<{ templates: AgentTemplate[] | null; agents: HiredAgent[] | null }> { | |
| 16 | const [templates, agents] = await Promise.all([ | |
| 17 | workspaceAgents.templates().catch(() => null), | |
| 18 | workspaceAgents | |
| 19 | .list(slug, viewer) | |
| 20 | .then((result) => (result.ok ? result.value.map(({ id, handle, display_name, template, archived_at }) => ({ id, handle, display_name, template, archived_at })) : null)) | |
| 21 | .catch(() => null), | |
| 22 | ]); | |
| 23 | return { templates, agents }; | |
| 24 | } | |
| 25 | ||
| 26 | export async function loadConnected(slug: string, viewer: User): Promise<Record<string, ConnectedState>> { | |
| 27 | return connectedStates(slug, viewer); | |
| 28 | } |