import * as NodeOS from "node:os";import type { CursorSettings, ModelCapabilities, ProviderOptionSelection, ServerProvider, ServerProviderAuth, ServerProviderModel, ServerProviderState,} from "@t3tools/contracts";import type * as EffectAcpSchema from "effect-acp/schema";import { causeErrorTag } from "@t3tools/shared/observability";import * as Crypto from "effect/Crypto";import * as DateTime from "effect/DateTime";import * as Effect from "effect/Effect";import * as Exit from "effect/Exit";import * as FileSystem from "effect/FileSystem";import * as Layer from "effect/Layer";import * as Option from "effect/Option";import * as Path from "effect/Path";import * as Result from "effect/Result";import * as Schema from "effect/Schema";import { HttpClient } from "effect/unstable/http";import * as ChildProcess from "effect/unstable/process/ChildProcess";import * as ChildProcessSpawner from "effect/unstable/process/ChildProcessSpawner";import { createModelCapabilities, getProviderOptionBooleanSelectionValue, getProviderOptionStringSelectionValue,} from "@t3tools/shared/model";import { resolveSpawnCommand } from "@t3tools/shared/shell"; import { buildBooleanOptionDescriptor, buildSelectOptionDescriptor, buildServerProvider, collectStreamAsString, isCommandMissingCause, providerModelsFromSettings, type CommandResult, type ServerProviderDraft,} from "../providerSnapshot.ts";import { enrichProviderSnapshotWithVersionAdvisory, type ProviderMaintenanceCapabilities,} from "../providerMaintenance.ts";import * as AcpSessionRuntime from "../acp/AcpSessionRuntime.ts";import { CursorListAvailableModelsResponse } from "../acp/CursorAcpExtension.ts"; const decodeCursorListAvailableModelsResponse = Schema.decodeUnknownEffect( CursorListAvailableModelsResponse,);const CURSOR_PRESENTATION = { displayName: "Cursor", badgeLabel: "Early Access", showInteractionModeToggle: true,} as const;const EMPTY_CAPABILITIES: ModelCapabilities = createModelCapabilities({ optionDescriptors: [],}); const CURSOR_ACP_MODEL_DISCOVERY_TIMEOUT_MS = 15_000;const CURSOR_PARAMETERIZED_MODEL_PICKER_MIN_VERSION_DATE = 2026_04_08;const CURSOR_CLI_INSTALLATION_DOCS_URL = "https://cursor.com/docs/cli/installation";const CURSOR_ACP_MODEL_DISCOVERY_FAILED_MESSAGE = [ "Cursor ACP model discovery failed.", "Cursor CLI setup may be incomplete; install or enable the Cursor CLI, restart T3 Code, and try again.", `See ${CURSOR_CLI_INSTALLATION_DOCS_URL}.`, "Check server logs for ACP details.",].join(" ");export const CURSOR_PARAMETERIZED_MODEL_PICKER_CAPABILITIES = { _meta: { parameterizedModelPicker: true, },} satisfies NonNullable<EffectAcpSchema.InitializeRequest["clientCapabilities"]>; export function buildInitialCursorProviderSnapshot( cursorSettings: CursorSettings,): Effect.Effect<ServerProviderDraft> { return Effect.gen(function* () { const checkedAt = yield* Effect.map(DateTime.now, DateTime.formatIso); const models = getCursorFallbackModels(cursorSettings); if (!cursorSettings.enabled) { return buildServerProvider({ presentation: CURSOR_PRESENTATION, enabled: false, checkedAt, models, probe: { installed: false, version: null, status: "warning", auth: { status: "unknown" }, message: "Cursor is disabled in T3 Code settings.", }, }); } return buildServerProvider({ presentation: CURSOR_PRESENTATION, enabled: true, checkedAt, models, probe: { installed: true, version: null, status: "warning", auth: { status: "unknown" }, message: "Checking Cursor Agent availability...", }, }); });} interface CursorSessionSelectOption { readonly value: string; readonly name: string;} interface CursorAcpDiscoveredModel { readonly slug: string; readonly name: string; readonly capabilities: ModelCapabilities;} function flattenSessionConfigSelectOptions( configOption: EffectAcpSchema.SessionConfigOption | undefined,): ReadonlyArray<CursorSessionSelectOption> { if (!configOption || configOption.type !== "select") { return []; } return configOption.options.flatMap((entry) => "value" in entry ? [ { value: entry.value.trim(), name: entry.name.trim(), } satisfies CursorSessionSelectOption, ] : entry.options.map( (option) => ({ value: option.value.trim(), name: option.name.trim(), }) satisfies CursorSessionSelectOption, ), );} function normalizeCursorReasoningValue(value: string | null | undefined): string | undefined { const normalized = value?.trim().toLowerCase(); switch (normalized) { case "low": case "medium": case "high": case "max": return normalized; case "xhigh": case "extra-high": case "extra high": return "xhigh"; default: return undefined; }} function getCursorConfigOptionCategory(option: EffectAcpSchema.SessionConfigOption): string { return option.category?.trim().toLowerCase() ?? "";} function isCursorEffortConfigOption(option: EffectAcpSchema.SessionConfigOption): boolean { const id = option.id.trim().toLowerCase(); const name = option.name.trim().toLowerCase(); return ( id === "effort" || id === "reasoning" || name === "effort" || name === "reasoning" || name.includes("effort") || name.includes("reasoning") );} function findCursorEffortConfigOption( configOptions: ReadonlyArray<EffectAcpSchema.SessionConfigOption>,): EffectAcpSchema.SessionConfigOption | undefined { const candidates = configOptions.filter( (option) => option.type === "select" && isCursorEffortConfigOption(option), ); return ( candidates.find((option) => getCursorConfigOptionCategory(option) === "model_option") ?? candidates.find((option) => option.id.trim().toLowerCase() === "effort") ?? candidates.find((option) => getCursorConfigOptionCategory(option) === "thought_level") ?? candidates[0] );} function isCursorContextConfigOption(option: EffectAcpSchema.SessionConfigOption): boolean { const id = option.id.trim().toLowerCase(); const name = option.name.trim().toLowerCase(); return id === "context" || id === "context_size" || name.includes("context");} function isCursorFastConfigOption(option: EffectAcpSchema.SessionConfigOption): boolean { const id = option.id.trim().toLowerCase(); const name = option.name.trim().toLowerCase(); return id === "fast" || name === "fast" || name.includes("fast mode");} function isCursorThinkingConfigOption(option: EffectAcpSchema.SessionConfigOption): boolean { const id = option.id.trim().toLowerCase(); const name = option.name.trim().toLowerCase(); return id === "thinking" || name.includes("thinking");} function isBooleanLikeConfigOption(option: EffectAcpSchema.SessionConfigOption): boolean { if (option.type === "boolean") { return true; } if (option.type !== "select") { return false; } const values = new Set( flattenSessionConfigSelectOptions(option).map((entry) => entry.value.trim().toLowerCase()), ); return values.has("true") && values.has("false");} function getBooleanCurrentValue( option: EffectAcpSchema.SessionConfigOption | undefined,): boolean | undefined { if (!option) { return undefined; } if (option.type === "boolean") { return option.currentValue; } if (option.type !== "select") { return undefined; } const normalized = option.currentValue?.trim().toLowerCase(); if (normalized === "true") { return true; } if (normalized === "false") { return false; } return undefined;} export function buildCursorCapabilitiesFromConfigOptions( configOptions: ReadonlyArray<EffectAcpSchema.SessionConfigOption> | null | undefined,): ModelCapabilities { if (!configOptions || configOptions.length === 0) { return EMPTY_CAPABILITIES; } const reasoningConfig = findCursorEffortConfigOption(configOptions); const reasoningEffortLevels = reasoningConfig?.type === "select" ? flattenSessionConfigSelectOptions(reasoningConfig).flatMap((entry) => { const normalizedValue = normalizeCursorReasoningValue(entry.value); if (!normalizedValue) { return []; } return [ { value: normalizedValue, label: entry.name, ...(normalizeCursorReasoningValue(reasoningConfig.currentValue) === normalizedValue ? { isDefault: true } : {}), }, ]; }) : []; const contextOption = configOptions.find( (option) => option.category === "model_config" && isCursorContextConfigOption(option), ); const contextWindowOptions = contextOption?.type === "select" ? flattenSessionConfigSelectOptions(contextOption).map((entry) => { if (contextOption.currentValue === entry.value) { return { value: entry.value, label: entry.name, isDefault: true, }; } return { value: entry.value, label: entry.name, }; }) : []; const fastOption = configOptions.find( (option) => option.category === "model_config" && isCursorFastConfigOption(option), ); const thinkingOption = configOptions.find( (option) => option.category === "model_config" && isCursorThinkingConfigOption(option), ); const fastCurrentValue = getBooleanCurrentValue(fastOption); const thinkingCurrentValue = getBooleanCurrentValue(thinkingOption); const optionDescriptors = [ ...(reasoningEffortLevels.length > 0 ? [ buildSelectOptionDescriptor({ id: "reasoning", label: reasoningConfig?.name?.trim() || "Reasoning", options: reasoningEffortLevels, }), ] : []), ...(contextWindowOptions.length > 0 ? [ buildSelectOptionDescriptor({ id: "contextWindow", label: contextOption?.name?.trim() || "Context Window", options: contextWindowOptions, }), ] : []), ...(fastOption && isBooleanLikeConfigOption(fastOption) ? [ typeof fastCurrentValue === "boolean" ? buildBooleanOptionDescriptor({ id: "fastMode", label: fastOption.name?.trim() || "Fast Mode", currentValue: fastCurrentValue, }) : buildBooleanOptionDescriptor({ id: "fastMode", label: fastOption.name?.trim() || "Fast Mode", }), ] : []), ...(thinkingOption && isBooleanLikeConfigOption(thinkingOption) ? [ typeof thinkingCurrentValue === "boolean" ? buildBooleanOptionDescriptor({ id: "thinking", label: thinkingOption.name?.trim() || "Thinking", currentValue: thinkingCurrentValue, }) : buildBooleanOptionDescriptor({ id: "thinking", label: thinkingOption.name?.trim() || "Thinking", }), ] : []), ]; return createModelCapabilities({ optionDescriptors, });} function buildCursorDiscoveredModels( discoveredModels: ReadonlyArray<CursorAcpDiscoveredModel>,): ReadonlyArray<ServerProviderModel> { const seen = new Set<string>(); return discoveredModels.flatMap((model) => { if (!model.slug || seen.has(model.slug)) { return []; } seen.add(model.slug); return [ { slug: model.slug, name: model.name, isCustom: false, capabilities: model.capabilities, } satisfies ServerProviderModel, ]; });} function buildCursorDiscoveredModelsFromAvailableModelsResponse( response: typeof CursorListAvailableModelsResponse.Type,): ReadonlyArray<ServerProviderModel> { return buildCursorDiscoveredModels( response.models.flatMap((model) => { const slug = model.value.trim(); const name = model.name.trim(); if (!slug || !name) { return []; } return [ { slug, name, capabilities: buildCursorCapabilitiesFromConfigOptions(model.configOptions), }, ]; }), );} const makeCursorAcpProbeRuntime = ( cursorSettings: CursorSettings, environment?: NodeJS.ProcessEnv,) => Effect.gen(function* () { const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; const acpContext = yield* Layer.build( AcpSessionRuntime.layer({ spawn: { command: cursorSettings.binaryPath, args: [ ...(cursorSettings.apiEndpoint ? (["-e", cursorSettings.apiEndpoint] as const) : []), "acp", ], cwd: process.cwd(), ...(environment ? { env: environment } : {}), }, cwd: process.cwd(), clientInfo: { name: "t3-code-provider-probe", version: "0.0.0" }, authMethodId: "cursor_login", clientCapabilities: CURSOR_PARAMETERIZED_MODEL_PICKER_CAPABILITIES, }).pipe(Layer.provide(Layer.succeed(ChildProcessSpawner.ChildProcessSpawner, spawner))), ); return yield* Effect.service(AcpSessionRuntime.AcpSessionRuntime).pipe( Effect.provide(acpContext), ); }); const withCursorAcpProbeRuntime = <A, E, R>( cursorSettings: CursorSettings, useRuntime: (acp: AcpSessionRuntime.AcpSessionRuntime["Service"]) => Effect.Effect<A, E, R>, environment?: NodeJS.ProcessEnv,) => makeCursorAcpProbeRuntime(cursorSettings, environment).pipe( Effect.flatMap(useRuntime), Effect.scoped, ); function normalizeCursorConfigOptionToken(value: string | null | undefined): string { return ( value ?.trim() .toLowerCase() .replace(/[\s_-]+/g, "-") ?? "" );} function findCursorSelectOptionValue( configOption: EffectAcpSchema.SessionConfigOption | undefined, matcher: (option: CursorSessionSelectOption) => boolean,): string | undefined { return flattenSessionConfigSelectOptions(configOption).find(matcher)?.value;} function findCursorBooleanConfigValue( configOption: EffectAcpSchema.SessionConfigOption | undefined, requested: boolean,): string | boolean | undefined { if (!configOption) { return undefined; } if (configOption.type === "boolean") { return requested; } return findCursorSelectOptionValue( configOption, (option) => normalizeCursorConfigOptionToken(option.value) === String(requested), );} export function resolveCursorAcpBaseModelId(model: string | null | undefined): string { const trimmed = model?.trim(); const base = trimmed && trimmed.length > 0 ? trimmed : "default"; return base.includes("[") ? base.slice(0, base.indexOf("[")) : base;} export function resolveCursorAcpConfigUpdates( configOptions: ReadonlyArray<EffectAcpSchema.SessionConfigOption> | null | undefined, selections: ReadonlyArray<ProviderOptionSelection> | null | undefined,): ReadonlyArray<{ readonly configId: string; readonly value: string | boolean;}> { if (!configOptions || configOptions.length === 0) { return []; } const updates: Array<{ readonly configId: string; readonly value: string | boolean; }> = []; const reasoningOption = findCursorEffortConfigOption(configOptions); const requestedReasoning = normalizeCursorReasoningValue( getProviderOptionStringSelectionValue(selections, "reasoning"), ); if (reasoningOption && requestedReasoning) { const value = findCursorSelectOptionValue(reasoningOption, (option) => {Lines 1–500 of 1153. Load more
import * as NodeOS from "node:os"; import type { CursorSettings, ModelCapabilities, ProviderOptionSelection, ServerProvider, ServerProviderAuth, ServerProviderModel, ServerProviderState, } from "@t3tools/contracts"; import type * as EffectAcpSchema from "effect-acp/schema"; import { causeErrorTag } from "@t3tools/shared/observability"; import * as Crypto from "effect/Crypto"; import * as DateTime from "effect/DateTime"; import * as Effect from "effect/Effect"; import * as Exit from "effect/Exit"; import * as FileSystem from "effect/FileSystem"; import * as Layer from "effect/Layer"; import * as Option from "effect/Option"; import * as Path from "effect/Path"; import * as Result from "effect/Result"; import * as Schema from "effect/Schema"; import { HttpClient } from "effect/unstable/http"; import * as ChildProcess from "effect/unstable/process/ChildProcess"; import * as ChildProcessSpawner from "effect/unstable/process/ChildProcessSpawner"; import { createModelCapabilities, getProviderOptionBooleanSelectionValue, getProviderOptionStringSelectionValue, } from "@t3tools/shared/model"; import { resolveSpawnCommand } from "@t3tools/shared/shell"; import { buildBooleanOptionDescriptor, buildSelectOptionDescriptor, buildServerProvider, collectStreamAsString, isCommandMissingCause, providerModelsFromSettings, type CommandResult, type ServerProviderDraft, } from "../providerSnapshot.ts"; import { enrichProviderSnapshotWithVersionAdvisory, type ProviderMaintenanceCapabilities, } from "../providerMaintenance.ts"; import * as AcpSessionRuntime from "../acp/AcpSessionRuntime.ts"; import { CursorListAvailableModelsResponse } from "../acp/CursorAcpExtension.ts"; const decodeCursorListAvailableModelsResponse = Schema.decodeUnknownEffect( CursorListAvailableModelsResponse, ); const CURSOR_PRESENTATION = { displayName: "Cursor", badgeLabel: "Early Access", showInteractionModeToggle: true, } as const; const EMPTY_CAPABILITIES: ModelCapabilities = createModelCapabilities({ optionDescriptors: [], }); const CURSOR_ACP_MODEL_DISCOVERY_TIMEOUT_MS = 15_000; const CURSOR_PARAMETERIZED_MODEL_PICKER_MIN_VERSION_DATE = 2026_04_08; const CURSOR_CLI_INSTALLATION_DOCS_URL = "https://cursor.com/docs/cli/installation"; const CURSOR_ACP_MODEL_DISCOVERY_FAILED_MESSAGE = [ "Cursor ACP model discovery failed.", "Cursor CLI setup may be incomplete; install or enable the Cursor CLI, restart T3 Code, and try again.", `See ${CURSOR_CLI_INSTALLATION_DOCS_URL}.`, "Check server logs for ACP details.", ].join(" "); export const CURSOR_PARAMETERIZED_MODEL_PICKER_CAPABILITIES = { _meta: { parameterizedModelPicker: true, }, } satisfies NonNullable<EffectAcpSchema.InitializeRequest["clientCapabilities"]>; export function buildInitialCursorProviderSnapshot( cursorSettings: CursorSettings, ): Effect.Effect<ServerProviderDraft> { return Effect.gen(function* () { const checkedAt = yield* Effect.map(DateTime.now, DateTime.formatIso); const models = getCursorFallbackModels(cursorSettings); if (!cursorSettings.enabled) { return buildServerProvider({ presentation: CURSOR_PRESENTATION, enabled: false, checkedAt, models, probe: { installed: false, version: null, status: "warning", auth: { status: "unknown" }, message: "Cursor is disabled in T3 Code settings.", }, }); } return buildServerProvider({ presentation: CURSOR_PRESENTATION, enabled: true, checkedAt, models, probe: { installed: true, version: null, status: "warning", auth: { status: "unknown" }, message: "Checking Cursor Agent availability...", }, }); }); } interface CursorSessionSelectOption { readonly value: string; readonly name: string; } interface CursorAcpDiscoveredModel { readonly slug: string; readonly name: string; readonly capabilities: ModelCapabilities; } function flattenSessionConfigSelectOptions( configOption: EffectAcpSchema.SessionConfigOption | undefined, ): ReadonlyArray<CursorSessionSelectOption> { if (!configOption || configOption.type !== "select") { return []; } return configOption.options.flatMap((entry) => "value" in entry ? [ { value: entry.value.trim(), name: entry.name.trim(), } satisfies CursorSessionSelectOption, ] : entry.options.map( (option) => ({ value: option.value.trim(), name: option.name.trim(), }) satisfies CursorSessionSelectOption, ), ); } function normalizeCursorReasoningValue(value: string | null | undefined): string | undefined { const normalized = value?.trim().toLowerCase(); switch (normalized) { case "low": case "medium": case "high": case "max": return normalized; case "xhigh": case "extra-high": case "extra high": return "xhigh"; default: return undefined; } } function getCursorConfigOptionCategory(option: EffectAcpSchema.SessionConfigOption): string { return option.category?.trim().toLowerCase() ?? ""; } function isCursorEffortConfigOption(option: EffectAcpSchema.SessionConfigOption): boolean { const id = option.id.trim().toLowerCase(); const name = option.name.trim().toLowerCase(); return ( id === "effort" || id === "reasoning" || name === "effort" || name === "reasoning" || name.includes("effort") || name.includes("reasoning") ); } function findCursorEffortConfigOption( configOptions: ReadonlyArray<EffectAcpSchema.SessionConfigOption>, ): EffectAcpSchema.SessionConfigOption | undefined { const candidates = configOptions.filter( (option) => option.type === "select" && isCursorEffortConfigOption(option), ); return ( candidates.find((option) => getCursorConfigOptionCategory(option) === "model_option") ?? candidates.find((option) => option.id.trim().toLowerCase() === "effort") ?? candidates.find((option) => getCursorConfigOptionCategory(option) === "thought_level") ?? candidates[0] ); } function isCursorContextConfigOption(option: EffectAcpSchema.SessionConfigOption): boolean { const id = option.id.trim().toLowerCase(); const name = option.name.trim().toLowerCase(); return id === "context" || id === "context_size" || name.includes("context"); } function isCursorFastConfigOption(option: EffectAcpSchema.SessionConfigOption): boolean { const id = option.id.trim().toLowerCase(); const name = option.name.trim().toLowerCase(); return id === "fast" || name === "fast" || name.includes("fast mode"); } function isCursorThinkingConfigOption(option: EffectAcpSchema.SessionConfigOption): boolean { const id = option.id.trim().toLowerCase(); const name = option.name.trim().toLowerCase(); return id === "thinking" || name.includes("thinking"); } function isBooleanLikeConfigOption(option: EffectAcpSchema.SessionConfigOption): boolean { if (option.type === "boolean") { return true; } if (option.type !== "select") { return false; } const values = new Set( flattenSessionConfigSelectOptions(option).map((entry) => entry.value.trim().toLowerCase()), ); return values.has("true") && values.has("false"); } function getBooleanCurrentValue( option: EffectAcpSchema.SessionConfigOption | undefined, ): boolean | undefined { if (!option) { return undefined; } if (option.type === "boolean") { return option.currentValue; } if (option.type !== "select") { return undefined; } const normalized = option.currentValue?.trim().toLowerCase(); if (normalized === "true") { return true; } if (normalized === "false") { return false; } return undefined; } export function buildCursorCapabilitiesFromConfigOptions( configOptions: ReadonlyArray<EffectAcpSchema.SessionConfigOption> | null | undefined, ): ModelCapabilities { if (!configOptions || configOptions.length === 0) { return EMPTY_CAPABILITIES; } const reasoningConfig = findCursorEffortConfigOption(configOptions); const reasoningEffortLevels = reasoningConfig?.type === "select" ? flattenSessionConfigSelectOptions(reasoningConfig).flatMap((entry) => { const normalizedValue = normalizeCursorReasoningValue(entry.value); if (!normalizedValue) { return []; } return [ { value: normalizedValue, label: entry.name, ...(normalizeCursorReasoningValue(reasoningConfig.currentValue) === normalizedValue ? { isDefault: true } : {}), }, ]; }) : []; const contextOption = configOptions.find( (option) => option.category === "model_config" && isCursorContextConfigOption(option), ); const contextWindowOptions = contextOption?.type === "select" ? flattenSessionConfigSelectOptions(contextOption).map((entry) => { if (contextOption.currentValue === entry.value) { return { value: entry.value, label: entry.name, isDefault: true, }; } return { value: entry.value, label: entry.name, }; }) : []; const fastOption = configOptions.find( (option) => option.category === "model_config" && isCursorFastConfigOption(option), ); const thinkingOption = configOptions.find( (option) => option.category === "model_config" && isCursorThinkingConfigOption(option), ); const fastCurrentValue = getBooleanCurrentValue(fastOption); const thinkingCurrentValue = getBooleanCurrentValue(thinkingOption); const optionDescriptors = [ ...(reasoningEffortLevels.length > 0 ? [ buildSelectOptionDescriptor({ id: "reasoning", label: reasoningConfig?.name?.trim() || "Reasoning", options: reasoningEffortLevels, }), ] : []), ...(contextWindowOptions.length > 0 ? [ buildSelectOptionDescriptor({ id: "contextWindow", label: contextOption?.name?.trim() || "Context Window", options: contextWindowOptions, }), ] : []), ...(fastOption && isBooleanLikeConfigOption(fastOption) ? [ typeof fastCurrentValue === "boolean" ? buildBooleanOptionDescriptor({ id: "fastMode", label: fastOption.name?.trim() || "Fast Mode", currentValue: fastCurrentValue, }) : buildBooleanOptionDescriptor({ id: "fastMode", label: fastOption.name?.trim() || "Fast Mode", }), ] : []), ...(thinkingOption && isBooleanLikeConfigOption(thinkingOption) ? [ typeof thinkingCurrentValue === "boolean" ? buildBooleanOptionDescriptor({ id: "thinking", label: thinkingOption.name?.trim() || "Thinking", currentValue: thinkingCurrentValue, }) : buildBooleanOptionDescriptor({ id: "thinking", label: thinkingOption.name?.trim() || "Thinking", }), ] : []), ]; return createModelCapabilities({ optionDescriptors, }); } function buildCursorDiscoveredModels( discoveredModels: ReadonlyArray<CursorAcpDiscoveredModel>, ): ReadonlyArray<ServerProviderModel> { const seen = new Set<string>(); return discoveredModels.flatMap((model) => { if (!model.slug || seen.has(model.slug)) { return []; } seen.add(model.slug); return [ { slug: model.slug, name: model.name, isCustom: false, capabilities: model.capabilities, } satisfies ServerProviderModel, ]; }); } function buildCursorDiscoveredModelsFromAvailableModelsResponse( response: typeof CursorListAvailableModelsResponse.Type, ): ReadonlyArray<ServerProviderModel> { return buildCursorDiscoveredModels( response.models.flatMap((model) => { const slug = model.value.trim(); const name = model.name.trim(); if (!slug || !name) { return []; } return [ { slug, name, capabilities: buildCursorCapabilitiesFromConfigOptions(model.configOptions), }, ]; }), ); } const makeCursorAcpProbeRuntime = ( cursorSettings: CursorSettings, environment?: NodeJS.ProcessEnv, ) => Effect.gen(function* () { const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; const acpContext = yield* Layer.build( AcpSessionRuntime.layer({ spawn: { command: cursorSettings.binaryPath, args: [ ...(cursorSettings.apiEndpoint ? (["-e", cursorSettings.apiEndpoint] as const) : []), "acp", ], cwd: process.cwd(), ...(environment ? { env: environment } : {}), }, cwd: process.cwd(), clientInfo: { name: "t3-code-provider-probe", version: "0.0.0" }, authMethodId: "cursor_login", clientCapabilities: CURSOR_PARAMETERIZED_MODEL_PICKER_CAPABILITIES, }).pipe(Layer.provide(Layer.succeed(ChildProcessSpawner.ChildProcessSpawner, spawner))), ); return yield* Effect.service(AcpSessionRuntime.AcpSessionRuntime).pipe( Effect.provide(acpContext), ); }); const withCursorAcpProbeRuntime = <A, E, R>( cursorSettings: CursorSettings, useRuntime: (acp: AcpSessionRuntime.AcpSessionRuntime["Service"]) => Effect.Effect<A, E, R>, environment?: NodeJS.ProcessEnv, ) => makeCursorAcpProbeRuntime(cursorSettings, environment).pipe( Effect.flatMap(useRuntime), Effect.scoped, ); function normalizeCursorConfigOptionToken(value: string | null | undefined): string { return ( value ?.trim() .toLowerCase() .replace(/[\s_-]+/g, "-") ?? "" ); } function findCursorSelectOptionValue( configOption: EffectAcpSchema.SessionConfigOption | undefined, matcher: (option: CursorSessionSelectOption) => boolean, ): string | undefined { return flattenSessionConfigSelectOptions(configOption).find(matcher)?.value; } function findCursorBooleanConfigValue( configOption: EffectAcpSchema.SessionConfigOption | undefined, requested: boolean, ): string | boolean | undefined { if (!configOption) { return undefined; } if (configOption.type === "boolean") { return requested; } return findCursorSelectOptionValue( configOption, (option) => normalizeCursorConfigOptionToken(option.value) === String(requested), ); } export function resolveCursorAcpBaseModelId(model: string | null | undefined): string { const trimmed = model?.trim(); const base = trimmed && trimmed.length > 0 ? trimmed : "default"; return base.includes("[") ? base.slice(0, base.indexOf("[")) : base; } export function resolveCursorAcpConfigUpdates( configOptions: ReadonlyArray<EffectAcpSchema.SessionConfigOption> | null | undefined, selections: ReadonlyArray<ProviderOptionSelection> | null | undefined, ): ReadonlyArray<{ readonly configId: string; readonly value: string | boolean; }> { if (!configOptions || configOptions.length === 0) { return []; } const updates: Array<{ readonly configId: string; readonly value: string | boolean; }> = []; const reasoningOption = findCursorEffortConfigOption(configOptions); const requestedReasoning = normalizeCursorReasoningValue( getProviderOptionStringSelectionValue(selections, "reasoning"), ); if (reasoningOption && requestedReasoning) { const value = findCursorSelectOptionValue(reasoningOption, (option) => {