#!/usr/bin/env node import * as NodeRuntime from "@effect/platform-node/NodeRuntime";import * as NodeServices from "@effect/platform-node/NodeServices";import { make as makeJsonSchemaGenerator } from "@effect/openapi-generator/JsonSchemaGenerator";import * as Effect from "effect/Effect";import * as FileSystem from "effect/FileSystem";import * as Layer from "effect/Layer";import * as Logger from "effect/Logger";import * as Path from "effect/Path";import * as Schema from "effect/Schema";import { FetchHttpClient, HttpClient, HttpClientRequest, HttpClientResponse,} from "effect/unstable/http";import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"; const UPSTREAM_REF = "678157acaa819d5510adfe359abb5d0392cfe461";const USER_AGENT = "effect-codex-app-server-generator";const GITHUB_API_BASE = "https://api.github.com/repos/openai/codex/contents/codex-rs/app-server-protocol"; const GithubContentEntries = Schema.Array( Schema.Struct({ name: Schema.String, path: Schema.String, download_url: Schema.NullOr(Schema.String), type: Schema.String, }),);type GithubContentEntry = (typeof GithubContentEntries.Type)[number]; const JsonSchemaDocument = Schema.StructWithRest( Schema.Struct({ definitions: Schema.optionalKey(Schema.Record(Schema.String, Schema.Json)), }), [Schema.Record(Schema.String, Schema.Json)],);const decodeGithubContentEntries = Schema.decodeEffect(Schema.fromJsonString(GithubContentEntries));const decodeJsonSchemaDocument = Schema.decodeEffect(Schema.fromJsonString(JsonSchemaDocument)); interface GeneratedPaths { readonly generatedDir: string; readonly schemaOutputPath: string; readonly metaOutputPath: string; readonly namespacesOutputPath: string;} interface MethodEntry { readonly method: string; readonly paramsType?: string;} interface JsonSchemaFile { readonly namespace?: string; readonly exportName: string; readonly fileName: string; readonly downloadUrl: string; readonly qualifiedName: string;} class GeneratorError extends Schema.TaggedErrorClass<GeneratorError>()("GeneratorError", { detail: Schema.String, cause: Schema.optional(Schema.Defect()),}) { override get message() { return this.detail; }} const ManualSchemas: Record<string, Schema.Json> = { GetAuthStatusParams: { type: "object", title: "GetAuthStatusParams", properties: { includeToken: { anyOf: [{ type: "boolean" }, { type: "null" }], }, refreshToken: { anyOf: [{ type: "boolean" }, { type: "null" }], }, }, }, GetConversationSummaryParams: { title: "GetConversationSummaryParams", oneOf: [ { type: "object", properties: { rolloutPath: { type: "string" }, }, required: ["rolloutPath"], }, { type: "object", properties: { conversationId: { type: "string" }, }, required: ["conversationId"], }, ], }, GetConversationSummaryResponse: { type: "object", title: "GetConversationSummaryResponse", properties: { summary: {}, }, required: ["summary"], }, GitDiffToRemoteParams: { type: "object", title: "GitDiffToRemoteParams", properties: { cwd: { type: "string" }, }, required: ["cwd"], }, GitDiffToRemoteResponse: { type: "object", title: "GitDiffToRemoteResponse", properties: { sha: { type: "string" }, diff: { type: "string" }, }, required: ["sha", "diff"], }, GetAuthStatusResponse: { type: "object", title: "GetAuthStatusResponse", properties: { authMethod: { anyOf: [{}, { type: "null" }], }, authToken: { anyOf: [{ type: "string" }, { type: "null" }], }, requiresOpenaiAuth: { anyOf: [{ type: "boolean" }, { type: "null" }], }, }, required: ["authMethod", "authToken", "requiresOpenaiAuth"], },}; // Codex 0.150 added these multi-agent values before our next full protocol// refresh. Keep every generated response namespace compatible with them.const Codex0150DefinitionSchemas: Record<string, Schema.Json> = { CollabAgentTool: { type: "string", enum: [ "spawnAgent", "sendInput", "resumeAgent", "wait", "closeAgent", "sendMessage", "followupTask", "interruptAgent", "listAgents", ], }, CollabAgentToolCallStatus: { type: "string", enum: ["inProgress", "completed", "failed", "interrupted"], }, PlanType: { type: "string", enum: [ "free", "go", "plus", "pro", "prolite", "team", "self_serve_business_prolite", "self_serve_business_usage_based", "business", "ent26", "enterprise_cbp_automation", "enterprise_cbp_usage_based", "enterprise", "edu", "edu_plus", "edu_pro", "unknown", ], }, SubAgentActivityKind: { type: "string", enum: ["started", "interacted", "interrupted", "completed"], },}; function applyCodex0151DefinitionCompatibility( exportName: string, definitionName: string, definitionSchema: Schema.Json,): Schema.Json { const isThreadResponse = exportName === "V2ThreadReadResponse" || exportName === "V2ThreadResumeResponse" || exportName === "V2ThreadRollbackResponse"; if ( !isThreadResponse || definitionName !== "CodexErrorInfo" || typeof definitionSchema !== "object" ) { return definitionSchema; } const schema = definitionSchema as { readonly oneOf?: ReadonlyArray<{ readonly enum?: ReadonlyArray<string> }>; }; const [firstVariant, ...remainingVariants] = schema.oneOf ?? []; if (!firstVariant?.enum || firstVariant.enum.includes("rateLimitExceeded")) { return definitionSchema; } return { ...definitionSchema, oneOf: [ { ...firstVariant, enum: [...firstVariant.enum, "rateLimitExceeded"] }, ...remainingVariants, ], };} const getGeneratedPaths = Effect.fn("getGeneratedPaths")(function* () { const path = yield* Path.Path; const generatedDir = path.join(import.meta.dirname, "..", "src", "_generated"); return { generatedDir, schemaOutputPath: path.join(generatedDir, "schema.gen.ts"), metaOutputPath: path.join(generatedDir, "meta.gen.ts"), namespacesOutputPath: path.join(generatedDir, "namespaces.gen.ts"), } satisfies GeneratedPaths;}); const ensureGeneratedDir = Effect.fn("ensureGeneratedDir")(function* () { const fs = yield* FileSystem.FileSystem; const { generatedDir } = yield* getGeneratedPaths(); yield* fs.makeDirectory(generatedDir, { recursive: true });}); const fetchText = Effect.fn("fetchText")(function* (url: string) { return yield* HttpClientRequest.get(url).pipe( HttpClientRequest.setHeader("user-agent", USER_AGENT), HttpClient.execute, Effect.flatMap(HttpClientResponse.filterStatusOk), Effect.flatMap((okResponse) => okResponse.text), Effect.mapError( (cause) => new GeneratorError({ detail: `Failed to fetch ${url}`, cause, }), ), );}); const fetchDirectoryEntries = Effect.fn("fetchDirectoryEntries")(function* (path: string) { const raw = yield* fetchText(`${GITHUB_API_BASE}/${path}?ref=${UPSTREAM_REF}`); return yield* decodeGithubContentEntries(raw);}); function collectSchemaEntries( chunk: string,): ReadonlyArray<{ readonly name: string; readonly code: string }> { const lines = chunk .split("\n") .map((line) => line.trim()) .filter((line) => line.length > 0 && !line.startsWith("//")); const entries: Array<{ name: string; code: string }> = []; for (let index = 0; index < lines.length; index += 1) { const typeLine = lines[index]; if (!typeLine?.startsWith("export type ")) { continue; } const constLine = lines[index + 1]; if (!constLine?.startsWith("export const ")) { throw new Error(`Malformed generator output near: ${typeLine}`); } const match = /^export type ([A-Za-z0-9_]+)/.exec(typeLine); if (!match?.[1]) { throw new Error(`Could not extract schema name from: ${typeLine}`); } entries.push({ name: match[1], code: `${typeLine}\n${constLine}`, }); index += 1; } return entries;} function normalizeNullableTypes(value: Schema.Json): Schema.Json { if (Array.isArray(value)) { return value.map(normalizeNullableTypes); } if (value === null || typeof value !== "object") { return value; } const normalizedEntries = Object.entries(value).map(([key, child]) => [ key, normalizeNullableTypes(child), ]); const normalizedObject = Object.fromEntries(normalizedEntries) as Record<string, Schema.Json>; const typeValue = normalizedObject.type; if (!Array.isArray(typeValue)) { return normalizedObject; } const normalizedTypes = typeValue.filter((entry): entry is string => typeof entry === "string"); if (normalizedTypes.length !== typeValue.length || !normalizedTypes.includes("null")) { return normalizedObject; } const nonNullTypes = normalizedTypes.filter((entry) => entry !== "null"); if (nonNullTypes.length !== 1) { return normalizedObject; } const nonNullType = nonNullTypes[0]!; const nextObject: Record<string, Schema.Json> = {}; for (const [key, child] of Object.entries(normalizedObject)) { if (key !== "type") { nextObject[key] = child; } } return { anyOf: [ { ...nextObject, type: nonNullType, }, { type: "null" }, ], };} function stripNullDefaults(value: Schema.Json): Schema.Json { if (Array.isArray(value)) { return value.map(stripNullDefaults); } if (value === null || typeof value !== "object") { return value; } return Object.fromEntries( Object.entries(value) .filter(([key, child]) => !(key === "default" && child === null)) .map(([key, child]) => [key, stripNullDefaults(child)]), ) as Schema.Json;} // Codex 0.153 adds async questions to agent messages. Keep older protocol// fields until the next full refresh, including every thread history namespace.function addAsyncQuestionFields(value: Schema.Json): Schema.Json { if (Array.isArray(value)) { return value.map(addAsyncQuestionFields); } if (value === null || typeof value !== "object") { return value; } const properties = "properties" in value ? value.properties : undefined; const itemType = properties && typeof properties === "object" && "type" in properties ? properties.type : undefined; if ( properties && typeof properties === "object" && itemType && typeof itemType === "object" && "enum" in itemType && Array.isArray(itemType.enum) && itemType.enum.includes("agentMessage") ) { return { ...value, properties: { ...properties, delivery: { anyOf: [{ type: "string", enum: ["async"] }, { type: "null" }] }, questions: { anyOf: [ { type: "array", items: { type: "object", properties: { title: { type: "string" }, options: { anyOf: [{ type: "array", items: { type: "string" } }, { type: "null" }], }, }, required: ["title"], }, }, { type: "null" }, ], }, }, }; } return Object.fromEntries( Object.entries(value).map(([key, child]) => [key, addAsyncQuestionFields(child)]), );} function toPascalCaseMethod(method: string) { return method .split("/") .flatMap((segment) => segment.split(/(?=[A-Z])/)) .flatMap((segment) => segment.split(/[-_]/)) .filter(Boolean) .map((segment) => segment[0]!.toUpperCase() + segment.slice(1)) .join("");} function parseRequestEntries(fileContents: string): ReadonlyArray<MethodEntry> { const entryPattern = /\{\s*"method":\s*"([^"]+)",\s*id:\s*RequestId,\s*params:\s*([^,}]+)/g; const entries: Array<MethodEntry> = []; let match: RegExpExecArray | null; while ((match = entryPattern.exec(fileContents)) !== null) { entries.push({ method: match[1]!, paramsType: match[2]!.trim(), }); } return entries;} function parseNotificationEntries(fileContents: string): ReadonlyArray<MethodEntry> { const entryPattern = /\{\s*"method":\s*"([^"]+)"(?:,\s*"params":\s*([^ }]+))?\s*\}/g; const entries: Array<MethodEntry> = []; let match: RegExpExecArray | null; while ((match = entryPattern.exec(fileContents)) !== null) { entries.push({ method: match[1]!, ...(match[2] ? { paramsType: match[2].trim() } : {}), }); } return entries;} function resolveSchemaTypeName( rawTypeName: string, generatedSchemaNames: ReadonlySet<string>,): string { if (rawTypeName === "undefined") { return "undefined"; } const candidates = [ rawTypeName, `V2${rawTypeName}`, `V1${rawTypeName}`, `SerdeJson${rawTypeName}`, ]; for (const candidate of candidates) { if (generatedSchemaNames.has(candidate)) { return candidate; } } throw new Error(`Unable to resolve schema type name: ${rawTypeName}`);} function resolveResponseTypeName( method: string, paramsType: string | undefined, generatedSchemaNames: ReadonlySet<string>,): string { const overrides: Record<string, string> = { "account/logout": "LogoutAccountResponse", "account/rateLimits/read": "GetAccountRateLimitsResponse", "account/usage/read": "GetAccountTokenUsageResponse", "account/workspaceMessages/read": "GetWorkspaceMessagesResponse", "config/batchWrite": "ConfigWriteResponse", "config/mcpServer/reload": "McpServerRefreshResponse", "config/value/write": "ConfigWriteResponse", "configRequirements/read": "ConfigRequirementsReadResponse", "externalAgentConfig/import/readHistories": "ExternalAgentConfigImportHistoriesReadResponse", }; const override = overrides[method]; if (override) { return resolveSchemaTypeName(override, generatedSchemaNames); }Lines 1–500 of 917. Load more
#!/usr/bin/env node import * as NodeRuntime from "@effect/platform-node/NodeRuntime"; import * as NodeServices from "@effect/platform-node/NodeServices"; import { make as makeJsonSchemaGenerator } from "@effect/openapi-generator/JsonSchemaGenerator"; import * as Effect from "effect/Effect"; import * as FileSystem from "effect/FileSystem"; import * as Layer from "effect/Layer"; import * as Logger from "effect/Logger"; import * as Path from "effect/Path"; import * as Schema from "effect/Schema"; import { FetchHttpClient, HttpClient, HttpClientRequest, HttpClientResponse, } from "effect/unstable/http"; import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"; const UPSTREAM_REF = "678157acaa819d5510adfe359abb5d0392cfe461"; const USER_AGENT = "effect-codex-app-server-generator"; const GITHUB_API_BASE = "https://api.github.com/repos/openai/codex/contents/codex-rs/app-server-protocol"; const GithubContentEntries = Schema.Array( Schema.Struct({ name: Schema.String, path: Schema.String, download_url: Schema.NullOr(Schema.String), type: Schema.String, }), ); type GithubContentEntry = (typeof GithubContentEntries.Type)[number]; const JsonSchemaDocument = Schema.StructWithRest( Schema.Struct({ definitions: Schema.optionalKey(Schema.Record(Schema.String, Schema.Json)), }), [Schema.Record(Schema.String, Schema.Json)], ); const decodeGithubContentEntries = Schema.decodeEffect(Schema.fromJsonString(GithubContentEntries)); const decodeJsonSchemaDocument = Schema.decodeEffect(Schema.fromJsonString(JsonSchemaDocument)); interface GeneratedPaths { readonly generatedDir: string; readonly schemaOutputPath: string; readonly metaOutputPath: string; readonly namespacesOutputPath: string; } interface MethodEntry { readonly method: string; readonly paramsType?: string; } interface JsonSchemaFile { readonly namespace?: string; readonly exportName: string; readonly fileName: string; readonly downloadUrl: string; readonly qualifiedName: string; } class GeneratorError extends Schema.TaggedErrorClass<GeneratorError>()("GeneratorError", { detail: Schema.String, cause: Schema.optional(Schema.Defect()), }) { override get message() { return this.detail; } } const ManualSchemas: Record<string, Schema.Json> = { GetAuthStatusParams: { type: "object", title: "GetAuthStatusParams", properties: { includeToken: { anyOf: [{ type: "boolean" }, { type: "null" }], }, refreshToken: { anyOf: [{ type: "boolean" }, { type: "null" }], }, }, }, GetConversationSummaryParams: { title: "GetConversationSummaryParams", oneOf: [ { type: "object", properties: { rolloutPath: { type: "string" }, }, required: ["rolloutPath"], }, { type: "object", properties: { conversationId: { type: "string" }, }, required: ["conversationId"], }, ], }, GetConversationSummaryResponse: { type: "object", title: "GetConversationSummaryResponse", properties: { summary: {}, }, required: ["summary"], }, GitDiffToRemoteParams: { type: "object", title: "GitDiffToRemoteParams", properties: { cwd: { type: "string" }, }, required: ["cwd"], }, GitDiffToRemoteResponse: { type: "object", title: "GitDiffToRemoteResponse", properties: { sha: { type: "string" }, diff: { type: "string" }, }, required: ["sha", "diff"], }, GetAuthStatusResponse: { type: "object", title: "GetAuthStatusResponse", properties: { authMethod: { anyOf: [{}, { type: "null" }], }, authToken: { anyOf: [{ type: "string" }, { type: "null" }], }, requiresOpenaiAuth: { anyOf: [{ type: "boolean" }, { type: "null" }], }, }, required: ["authMethod", "authToken", "requiresOpenaiAuth"], }, }; // Codex 0.150 added these multi-agent values before our next full protocol // refresh. Keep every generated response namespace compatible with them. const Codex0150DefinitionSchemas: Record<string, Schema.Json> = { CollabAgentTool: { type: "string", enum: [ "spawnAgent", "sendInput", "resumeAgent", "wait", "closeAgent", "sendMessage", "followupTask", "interruptAgent", "listAgents", ], }, CollabAgentToolCallStatus: { type: "string", enum: ["inProgress", "completed", "failed", "interrupted"], }, PlanType: { type: "string", enum: [ "free", "go", "plus", "pro", "prolite", "team", "self_serve_business_prolite", "self_serve_business_usage_based", "business", "ent26", "enterprise_cbp_automation", "enterprise_cbp_usage_based", "enterprise", "edu", "edu_plus", "edu_pro", "unknown", ], }, SubAgentActivityKind: { type: "string", enum: ["started", "interacted", "interrupted", "completed"], }, }; function applyCodex0151DefinitionCompatibility( exportName: string, definitionName: string, definitionSchema: Schema.Json, ): Schema.Json { const isThreadResponse = exportName === "V2ThreadReadResponse" || exportName === "V2ThreadResumeResponse" || exportName === "V2ThreadRollbackResponse"; if ( !isThreadResponse || definitionName !== "CodexErrorInfo" || typeof definitionSchema !== "object" ) { return definitionSchema; } const schema = definitionSchema as { readonly oneOf?: ReadonlyArray<{ readonly enum?: ReadonlyArray<string> }>; }; const [firstVariant, ...remainingVariants] = schema.oneOf ?? []; if (!firstVariant?.enum || firstVariant.enum.includes("rateLimitExceeded")) { return definitionSchema; } return { ...definitionSchema, oneOf: [ { ...firstVariant, enum: [...firstVariant.enum, "rateLimitExceeded"] }, ...remainingVariants, ], }; } const getGeneratedPaths = Effect.fn("getGeneratedPaths")(function* () { const path = yield* Path.Path; const generatedDir = path.join(import.meta.dirname, "..", "src", "_generated"); return { generatedDir, schemaOutputPath: path.join(generatedDir, "schema.gen.ts"), metaOutputPath: path.join(generatedDir, "meta.gen.ts"), namespacesOutputPath: path.join(generatedDir, "namespaces.gen.ts"), } satisfies GeneratedPaths; }); const ensureGeneratedDir = Effect.fn("ensureGeneratedDir")(function* () { const fs = yield* FileSystem.FileSystem; const { generatedDir } = yield* getGeneratedPaths(); yield* fs.makeDirectory(generatedDir, { recursive: true }); }); const fetchText = Effect.fn("fetchText")(function* (url: string) { return yield* HttpClientRequest.get(url).pipe( HttpClientRequest.setHeader("user-agent", USER_AGENT), HttpClient.execute, Effect.flatMap(HttpClientResponse.filterStatusOk), Effect.flatMap((okResponse) => okResponse.text), Effect.mapError( (cause) => new GeneratorError({ detail: `Failed to fetch ${url}`, cause, }), ), ); }); const fetchDirectoryEntries = Effect.fn("fetchDirectoryEntries")(function* (path: string) { const raw = yield* fetchText(`${GITHUB_API_BASE}/${path}?ref=${UPSTREAM_REF}`); return yield* decodeGithubContentEntries(raw); }); function collectSchemaEntries( chunk: string, ): ReadonlyArray<{ readonly name: string; readonly code: string }> { const lines = chunk .split("\n") .map((line) => line.trim()) .filter((line) => line.length > 0 && !line.startsWith("//")); const entries: Array<{ name: string; code: string }> = []; for (let index = 0; index < lines.length; index += 1) { const typeLine = lines[index]; if (!typeLine?.startsWith("export type ")) { continue; } const constLine = lines[index + 1]; if (!constLine?.startsWith("export const ")) { throw new Error(`Malformed generator output near: ${typeLine}`); } const match = /^export type ([A-Za-z0-9_]+)/.exec(typeLine); if (!match?.[1]) { throw new Error(`Could not extract schema name from: ${typeLine}`); } entries.push({ name: match[1], code: `${typeLine}\n${constLine}`, }); index += 1; } return entries; } function normalizeNullableTypes(value: Schema.Json): Schema.Json { if (Array.isArray(value)) { return value.map(normalizeNullableTypes); } if (value === null || typeof value !== "object") { return value; } const normalizedEntries = Object.entries(value).map(([key, child]) => [ key, normalizeNullableTypes(child), ]); const normalizedObject = Object.fromEntries(normalizedEntries) as Record<string, Schema.Json>; const typeValue = normalizedObject.type; if (!Array.isArray(typeValue)) { return normalizedObject; } const normalizedTypes = typeValue.filter((entry): entry is string => typeof entry === "string"); if (normalizedTypes.length !== typeValue.length || !normalizedTypes.includes("null")) { return normalizedObject; } const nonNullTypes = normalizedTypes.filter((entry) => entry !== "null"); if (nonNullTypes.length !== 1) { return normalizedObject; } const nonNullType = nonNullTypes[0]!; const nextObject: Record<string, Schema.Json> = {}; for (const [key, child] of Object.entries(normalizedObject)) { if (key !== "type") { nextObject[key] = child; } } return { anyOf: [ { ...nextObject, type: nonNullType, }, { type: "null" }, ], }; } function stripNullDefaults(value: Schema.Json): Schema.Json { if (Array.isArray(value)) { return value.map(stripNullDefaults); } if (value === null || typeof value !== "object") { return value; } return Object.fromEntries( Object.entries(value) .filter(([key, child]) => !(key === "default" && child === null)) .map(([key, child]) => [key, stripNullDefaults(child)]), ) as Schema.Json; } // Codex 0.153 adds async questions to agent messages. Keep older protocol // fields until the next full refresh, including every thread history namespace. function addAsyncQuestionFields(value: Schema.Json): Schema.Json { if (Array.isArray(value)) { return value.map(addAsyncQuestionFields); } if (value === null || typeof value !== "object") { return value; } const properties = "properties" in value ? value.properties : undefined; const itemType = properties && typeof properties === "object" && "type" in properties ? properties.type : undefined; if ( properties && typeof properties === "object" && itemType && typeof itemType === "object" && "enum" in itemType && Array.isArray(itemType.enum) && itemType.enum.includes("agentMessage") ) { return { ...value, properties: { ...properties, delivery: { anyOf: [{ type: "string", enum: ["async"] }, { type: "null" }] }, questions: { anyOf: [ { type: "array", items: { type: "object", properties: { title: { type: "string" }, options: { anyOf: [{ type: "array", items: { type: "string" } }, { type: "null" }], }, }, required: ["title"], }, }, { type: "null" }, ], }, }, }; } return Object.fromEntries( Object.entries(value).map(([key, child]) => [key, addAsyncQuestionFields(child)]), ); } function toPascalCaseMethod(method: string) { return method .split("/") .flatMap((segment) => segment.split(/(?=[A-Z])/)) .flatMap((segment) => segment.split(/[-_]/)) .filter(Boolean) .map((segment) => segment[0]!.toUpperCase() + segment.slice(1)) .join(""); } function parseRequestEntries(fileContents: string): ReadonlyArray<MethodEntry> { const entryPattern = /\{\s*"method":\s*"([^"]+)",\s*id:\s*RequestId,\s*params:\s*([^,}]+)/g; const entries: Array<MethodEntry> = []; let match: RegExpExecArray | null; while ((match = entryPattern.exec(fileContents)) !== null) { entries.push({ method: match[1]!, paramsType: match[2]!.trim(), }); } return entries; } function parseNotificationEntries(fileContents: string): ReadonlyArray<MethodEntry> { const entryPattern = /\{\s*"method":\s*"([^"]+)"(?:,\s*"params":\s*([^ }]+))?\s*\}/g; const entries: Array<MethodEntry> = []; let match: RegExpExecArray | null; while ((match = entryPattern.exec(fileContents)) !== null) { entries.push({ method: match[1]!, ...(match[2] ? { paramsType: match[2].trim() } : {}), }); } return entries; } function resolveSchemaTypeName( rawTypeName: string, generatedSchemaNames: ReadonlySet<string>, ): string { if (rawTypeName === "undefined") { return "undefined"; } const candidates = [ rawTypeName, `V2${rawTypeName}`, `V1${rawTypeName}`, `SerdeJson${rawTypeName}`, ]; for (const candidate of candidates) { if (generatedSchemaNames.has(candidate)) { return candidate; } } throw new Error(`Unable to resolve schema type name: ${rawTypeName}`); } function resolveResponseTypeName( method: string, paramsType: string | undefined, generatedSchemaNames: ReadonlySet<string>, ): string { const overrides: Record<string, string> = { "account/logout": "LogoutAccountResponse", "account/rateLimits/read": "GetAccountRateLimitsResponse", "account/usage/read": "GetAccountTokenUsageResponse", "account/workspaceMessages/read": "GetWorkspaceMessagesResponse", "config/batchWrite": "ConfigWriteResponse", "config/mcpServer/reload": "McpServerRefreshResponse", "config/value/write": "ConfigWriteResponse", "configRequirements/read": "ConfigRequirementsReadResponse", "externalAgentConfig/import/readHistories": "ExternalAgentConfigImportHistoriesReadResponse", }; const override = overrides[method]; if (override) { return resolveSchemaTypeName(override, generatedSchemaNames); }