import type { FoundryAppSnapshot, FoundryBillingPlanId, FoundryOrganization, FoundryUser, UpdateFoundryOrganizationProfileInput, } from "@sandbox-agent/foundry-shared"; import type { BackendClient } from "./backend-client.js"; import { getMockFoundryAppClient } from "./mock-app.js"; import { createRemoteFoundryAppClient } from "./remote/app-client.js"; export interface FoundryAppClient { getSnapshot(): FoundryAppSnapshot; subscribe(listener: () => void): () => void; signInWithGithub(userId?: string): Promise; signOut(): Promise; skipStarterRepo(): Promise; starStarterRepo(organizationId: string): Promise; selectOrganization(organizationId: string): Promise; updateOrganizationProfile(input: UpdateFoundryOrganizationProfileInput): Promise; triggerGithubSync(organizationId: string): Promise; completeHostedCheckout(organizationId: string, planId: FoundryBillingPlanId): Promise; openBillingPortal(organizationId: string): Promise; cancelScheduledRenewal(organizationId: string): Promise; resumeSubscription(organizationId: string): Promise; reconnectGithub(organizationId: string): Promise; recordSeatUsage(organizationId: string): Promise; } export interface CreateFoundryAppClientOptions { mode: "mock" | "remote"; backend?: BackendClient; } export function createFoundryAppClient(options: CreateFoundryAppClientOptions): FoundryAppClient { if (options.mode === "mock") { return getMockFoundryAppClient() as unknown as FoundryAppClient; } if (!options.backend) { throw new Error("Remote app client requires a backend client"); } return createRemoteFoundryAppClient({ backend: options.backend }); } export function currentFoundryUser(snapshot: FoundryAppSnapshot): FoundryUser | null { if (!snapshot.auth.currentUserId) { return null; } return snapshot.users.find((candidate) => candidate.id === snapshot.auth.currentUserId) ?? null; } export function currentFoundryOrganization(snapshot: FoundryAppSnapshot): FoundryOrganization | null { if (!snapshot.activeOrganizationId) { return null; } return snapshot.organizations.find((candidate) => candidate.id === snapshot.activeOrganizationId) ?? null; } export function eligibleFoundryOrganizations(snapshot: FoundryAppSnapshot): FoundryOrganization[] { const user = currentFoundryUser(snapshot); if (!user) { return []; } const eligible = new Set(user.eligibleOrganizationIds); return snapshot.organizations.filter((organization) => eligible.has(organization.id)); }