import { GlitchMcpConfig } from "./config.js"; import { FetchLike } from "./http.js"; import { SseMessage } from "./sse.js"; export type JsonObject = Record; export interface TitleSelectionStore { get(): string | undefined; set(titleId: string): void; } /** * In-memory title selection for stdio sessions. * * Remote hosted MCP deployments should generally rely on OAuth scopes and * explicit title_id arguments. The local stdio proxy can safely keep a selected * title for the lifetime of one developer's MCP process. */ export declare class MemoryTitleSelectionStore implements TitleSelectionStore { private selectedTitleId?; get(): string | undefined; set(titleId: string): void; } export interface GlitchClientOptions { /** * Per-session bearer token that overrides config.token. * * The Streamable HTTP transport sets this from each incoming request's * Authorization header so a hosted, multi-tenant deployment forwards the * caller's own credential instead of a single shared operator token. The * stdio proxy leaves this undefined and falls back to config.token. */ readonly authToken?: string; /** * Whether glitch_upload_file may read files from the local disk. * * Defaults to config.allowLocalFileReads, then false. The stdio transport * passes true (developer's own machine); the shared HTTP transport leaves it * false so it never reads the server's filesystem from a tool argument. */ readonly allowLocalFileReads?: boolean; } export declare class GlitchClient { private readonly config; private readonly http; private readonly titles; /** Whether the upload tool may read local file paths in this session. */ readonly canReadLocalFiles: boolean; /** Optional real-path roots that local file uploads must stay inside. */ readonly uploadAllowedRoots: readonly string[]; constructor(config: GlitchMcpConfig, fetchFn?: FetchLike, titles?: TitleSelectionStore, options?: GlitchClientOptions); get selectedTitleId(): string | undefined; dashboardUrl(kind: "title" | "run" | "action" | "billing" | "hosting", input: { titleId: string; runId?: string; actionId?: string; }): string; resolveTitleId(inputTitleId?: string): string; authStatus(titleId?: string): Promise; listTitles(includeArchived?: boolean): Promise; selectTitle(titleId: string): Promise; titleContext(titleId: string): Promise; /** Public genre taxonomy used by the game-design blueprint generator. */ listGameGenres(): Promise; /** * Generate a public mechanics/core-loop blueprint. * * OpenAI-backed generation can take longer than ordinary API requests, so * this call receives at least two minutes while preserving a larger caller * configured timeout. */ generateGameDesignBlueprint(body: JsonObject): Promise; analyticsCapabilities(titleId: string): Promise; analyticsQuery(titleId: string, body: JsonObject): Promise; billingStatus(titleId: string): Promise; hostingDashboard(titleId: string): Promise; hostingChannelAnalytics(titleId: string, query?: JsonObject): Promise; createHostingSite(titleId: string, body: JsonObject): Promise; updateHostingSite(titleId: string, siteId: string, body: JsonObject): Promise; hostingReleases(titleId: string, siteId: string, query?: JsonObject): Promise; createHostingRelease(titleId: string, siteId: string, body: JsonObject): Promise; promoteHostingRelease(titleId: string, siteId: string, releaseId: string): Promise; connectHostingDomain(titleId: string, siteId: string, hostname: string): Promise; verifyHostingDomain(titleId: string, siteId: string, domainId: string): Promise; hostingAiInstructions(titleId: string, siteId: string, body: JsonObject): Promise; listHostingServices(titleId: string, siteId: string): Promise; estimateHostingServices(titleId: string, siteId: string, body: JsonObject): Promise; applyHostingServices(titleId: string, siteId: string, body: JsonObject): Promise; checkHostingDomainAvailability(titleId: string, hostname: string): Promise; purchaseHostingDomain(titleId: string, siteId: string, body: JsonObject): Promise; changeHostingPlan(titleId: string, body: JsonObject): Promise; confirmHostingCheckout(titleId: string, checkoutSessionId: string): Promise; listHostingDatabases(titleId: string, siteId: string, query?: JsonObject): Promise; getHostingDatabase(titleId: string, siteId: string, databaseId: string): Promise; createHostingDatabase(titleId: string, siteId: string, body: JsonObject): Promise; updateHostingDatabase(titleId: string, siteId: string, databaseId: string, body: JsonObject): Promise; retryHostingDatabase(titleId: string, siteId: string, databaseId: string, body: JsonObject): Promise; deleteHostingDatabase(titleId: string, siteId: string, databaseId: string, confirmation: string): Promise; waitForDeploymentReady(titleId: string, buildId: string, timeoutMs: number, pollIntervalMs: number): Promise; waitForHostingReleaseReady(titleId: string, siteId: string, releaseId: string, timeoutMs: number, pollIntervalMs: number): Promise; socialCapabilities(titleId: string): Promise; socialOperation(titleId: string, operation: string, args: JsonObject, confirm?: boolean): Promise; startRun(titleId: string, body: JsonObject): Promise; getRun(titleId: string, runId: string): Promise; waitForRun(titleId: string, runId: string, timeoutMs: number, pollIntervalMs: number): Promise; runEvents(titleId: string, runId: string, query: JsonObject): Promise; /** * Open the run's SSE stream and forward each event to onMessage. * * Resolves with the settled run payload when a `settled` event arrives, or * undefined if the stream closes/times out first. Throws GlitchMcpError if the * stream cannot be opened (e.g. an older backend without the endpoint) so the * caller can fall back to polling. */ streamRunEvents(titleId: string, runId: string, options?: { signal?: AbortSignal; afterSeq?: number; onMessage?: (message: SseMessage) => void | Promise; }): Promise; /** * Wait for a run to settle, streaming live events when possible. * * Prefers the SSE stream (forwarding each event to onEvent for live progress) * and transparently falls back to polling if streaming is unavailable or the * stream ends before the run settles. */ waitForRunStreaming(titleId: string, runId: string, options: { timeoutMs: number; pollIntervalMs: number; signal?: AbortSignal; onEvent?: (message: SseMessage) => void | Promise; }): Promise; finalReport(titleId: string, runId: string): Promise; artifacts(titleId: string, runId: string): Promise; pendingActions(titleId: string, query: JsonObject): Promise; approveAction(titleId: string, actionId: string, body: JsonObject): Promise; rejectAction(titleId: string, actionId: string, body: JsonObject): Promise; executeAction(titleId: string, actionId: string, body: JsonObject): Promise; guidance(titleId: string, query: JsonObject): Promise; answerGuidance(titleId: string, guidanceId: string, body: JsonObject): Promise; createUploadUrl(titleId: string, body: JsonObject): Promise; /** * Upload a file directly to the MCP facade using multipart/form-data. * * The hosted facade re-checks the title scope, subscription, and allowed mime * types, and stores the file behind the prompt-injection boundary. */ uploadFile(titleId: string, input: { bytes: Uint8Array; fileName: string; mimeType: string; agentRunId?: string; }): Promise; /** * Upload a developer-selected screenshot, clip, trailer, or marketing export as * first-class Glitch Media so existing AI media processing and social library * workflows can handle it. */ uploadMediaAsset(titleId: string, input: { bytes: Uint8Array; fileName: string; mimeType: string; agentRunId?: string; createTitleUpdate?: boolean; titlePromotionScheduleId?: string; platforms?: readonly string[]; sourceMetadata?: JsonObject; }): Promise; listMultiplayerLobbies(titleId: string, query?: JsonObject): Promise; createMultiplayerLobby(titleId: string, body: JsonObject): Promise; browseMultiplayerServers(titleId: string, query?: JsonObject): Promise; listMultiplayerRealms(titleId: string, query?: JsonObject): Promise; createInstall(titleId: string, body: JsonObject): Promise; validateInstall(titleId: string, installId: string, body?: JsonObject): Promise; listCloudSaves(titleId: string, installId: string, query?: JsonObject): Promise; storeCloudSave(titleId: string, installId: string, body: JsonObject): Promise; resolveCloudSaveConflict(titleId: string, installId: string, saveId: string, body: JsonObject): Promise; submitProgression(titleId: string, installId: string, body: JsonObject): Promise; listLeaderboardDefinitions(titleId: string): Promise; readLeaderboard(titleId: string, apiKey: string, query?: JsonObject): Promise; listAchievementDefinitions(titleId: string): Promise; listPlayerAchievements(titleId: string, installId: string): Promise; listDeployments(titleId: string, query?: JsonObject): Promise; updateDeploymentStatus(titleId: string, buildId: string, body: JsonObject): Promise; initiateDeploymentUpload(titleId: string, body?: JsonObject): Promise; getDeploymentPartUrls(titleId: string, body: JsonObject): Promise; completeDeploymentUpload(titleId: string, body: JsonObject): Promise; confirmDeployment(titleId: string, body: JsonObject): Promise; /** * PUT one part to its S3 pre-signed URL and return the ETag S3 assigns. * The ETag (quoted) is required, in PartNumber order, to complete the upload. */ uploadDeploymentPart(presignedUrl: string, bytes: Uint8Array): Promise; /** * PUT a whole object to a single pre-signed URL (the local/dev fallback the * initiate endpoint returns as { upload_url, is_local }). No ETag is required. */ putDeploymentObject(presignedUrl: string, bytes: Uint8Array): Promise; } export declare function isRunSettled(status: string): boolean; /** * Decide whether a run payload represents a settled run. * * Prefers the backend-provided is_settled flag (authoritative, drift-proof) and * falls back to matching the status string when an older backend omits it. */ export declare function runIsSettled(run: JsonObject): boolean; export declare function segment(value: string): string;