sandbox-agent/foundry/packages/frontend/src/lib/mock-app.ts
Nathan Flurry d75e8c31d1
Rename Foundry handoffs to tasks (#239)
* Restore foundry onboarding stack

* Consolidate foundry rename

* Create foundry tasks without prompts

* Rename Foundry handoffs to tasks
2026-03-11 13:23:54 -07:00

68 lines
2.6 KiB
TypeScript

import { useSyncExternalStore } from "react";
import {
createFoundryAppClient,
currentFoundryOrganization,
currentFoundryUser,
eligibleFoundryOrganizations,
type FoundryAppClient,
} from "@sandbox-agent/foundry-client";
import type { FoundryAppSnapshot, FoundryOrganization } from "@sandbox-agent/foundry-shared";
import { backendClient } from "./backend";
import { frontendClientMode } from "./env";
const REMOTE_APP_SESSION_STORAGE_KEY = "sandbox-agent-foundry:remote-app-session";
const appClient: FoundryAppClient = createFoundryAppClient({
mode: frontendClientMode,
backend: frontendClientMode === "remote" ? backendClient : undefined,
});
export function useMockAppSnapshot(): FoundryAppSnapshot {
return useSyncExternalStore(appClient.subscribe.bind(appClient), appClient.getSnapshot.bind(appClient), appClient.getSnapshot.bind(appClient));
}
export function useMockAppClient(): FoundryAppClient {
return appClient;
}
export const activeMockUser = currentFoundryUser;
export const activeMockOrganization = currentFoundryOrganization;
export const eligibleOrganizations = eligibleFoundryOrganizations;
// Track whether the remote client has delivered its first real snapshot.
// Before the first fetch completes the snapshot is the default empty signed_out state,
// so we show a loading screen. Once the fetch returns we know the truth.
let firstSnapshotDelivered = false;
// The remote client notifies listeners after refresh(), which sets `firstSnapshotDelivered`.
const origSubscribe = appClient.subscribe.bind(appClient);
appClient.subscribe = (listener: () => void): (() => void) => {
const wrappedListener = () => {
firstSnapshotDelivered = true;
listener();
};
return origSubscribe(wrappedListener);
};
export function isAppSnapshotBootstrapping(snapshot: FoundryAppSnapshot): boolean {
if (frontendClientMode !== "remote" || typeof window === "undefined") {
return false;
}
const hasStoredSession = window.localStorage.getItem(REMOTE_APP_SESSION_STORAGE_KEY)?.trim().length;
if (!hasStoredSession) {
return false;
}
// If the backend has already responded and we're still signed_out, the session is stale.
if (firstSnapshotDelivered) {
return false;
}
// Still waiting for the initial fetch — show the loading screen.
return snapshot.auth.status === "signed_out" && snapshot.users.length === 0 && snapshot.organizations.length === 0;
}
export function getMockOrganizationById(snapshot: FoundryAppSnapshot, organizationId: string): FoundryOrganization | null {
return snapshot.organizations.find((organization) => organization.id === organizationId) ?? null;
}