From 786348d01c6424816c71f5b8aff7fe4d3a7648ed Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 8 Nov 2026 09:24:15 +0000 Subject: [PATCH 1/3] Remove unused helpers with no callers. Repo-wide search finds each removed symbol only at its definition. Live callers, including providerServicesForEnv, resolveSessionAccess, and the workflow node executors, stay in place. Co-authored-by: Jonathan Beckman --- .../src/server/background/auth/github-app.ts | 7 --- .../src/server/background/provider-catalog.ts | 27 --------- .../src/server/background/session/access.ts | 13 ----- .../src/server/background/session/types.ts | 15 ----- .../server/background/workflows/nodes/http.ts | 5 -- .../workflows/nodes/notification.ts | 6 -- .../background/workflows/nodes/registry.ts | 6 -- .../background/workflows/nodes/session.ts | 5 -- .../background/workflows/nodes/storage.ts | 12 ---- .../src/server/effect/db/control-plane-db.ts | 7 --- .../effect/handlers/shared/control-plane.ts | 15 ----- .../src/server/effect/services/providers.ts | 18 ------ packages/shared/src/agent-runtime.ts | 11 ---- packages/shared/src/session-tools.ts | 55 ------------------- packages/shared/src/stageMetadata.ts | 40 -------------- 15 files changed, 242 deletions(-) diff --git a/packages/api/src/server/background/auth/github-app.ts b/packages/api/src/server/background/auth/github-app.ts index eed05559..c4a6648a 100644 --- a/packages/api/src/server/background/auth/github-app.ts +++ b/packages/api/src/server/background/auth/github-app.ts @@ -95,13 +95,6 @@ export function getGitHubAppConfig(env: { ) } -export function getGitHubAppConfigOrThrow( - env: Parameters[0], - message: string, -): GitHubAppConfig { - return Option.getOrThrowWith(getGitHubAppConfig(env), () => new GitHubAppError({ message })) -} - function fetchWithTimeout( input: RequestInfo | URL, init: RequestInit, diff --git a/packages/api/src/server/background/provider-catalog.ts b/packages/api/src/server/background/provider-catalog.ts index 7c98f1e8..ae6dea17 100644 --- a/packages/api/src/server/background/provider-catalog.ts +++ b/packages/api/src/server/background/provider-catalog.ts @@ -25,7 +25,6 @@ import { type RuntimeProviderCatalog, type RuntimeProviderCatalogEntry, type SharedProviderDefinition, - type UserCustomProviderSettings, } from "@solzero/shared" import * as Arr from "effect/Array" import * as Match from "effect/Match" @@ -525,19 +524,6 @@ function isProviderAvailable(provider: ResolvedProviderRecord): boolean { return provider.credentialSource === "binding" || isNonEmptyString(provider.apiKey) } -export async function isVisibleModelForUser( - env: Env, - userId: string, - model: string, -): Promise { - const catalog = await buildRuntimeProviderCatalog(env, userId) - const runtimeModelId = normalizeModelId(model) - - return catalog.modelOptions.some((group) => - group.models.some((item) => item.id === runtimeModelId), - ) -} - export function getUserProviderSettingsSnapshot( env: Env, userId: string, @@ -948,16 +934,3 @@ function splitRuntimeModelId(runtimeModelId: string) { modelId: rest.join("/"), } } - -export function toEditableCustomProviderSettings( - provider: UserCustomProviderSettings, -): UserCustomProviderSettings { - return { - providerId: provider.providerId, - name: provider.name, - npm: provider.npm, - options: provider.options, - models: provider.models, - hasApiKey: provider.hasApiKey, - } -} diff --git a/packages/api/src/server/background/session/access.ts b/packages/api/src/server/background/session/access.ts index aede1ca4..13bd3314 100644 --- a/packages/api/src/server/background/session/access.ts +++ b/packages/api/src/server/background/session/access.ts @@ -1,5 +1,4 @@ import * as Effect from "effect/Effect" -import { runOptionPromise } from "../../lib/effect-promise" import * as Match from "effect/Match" import * as Option from "effect/Option" import type { SessionIndexRecord, SessionIndexStore } from "../db/session-index" @@ -45,15 +44,3 @@ export const resolveSessionAccess = Effect.fn("session.resolveSessionAccess")(fu ), ) }) - -/** - * Promise bridge for non-Effect callers: resolves to - * the access grant or `null` so imperative request plumbing can branch without importing Effect. - */ -export function resolveSessionAccessPromise( - store: SessionAccessStore, - sessionId: string, - userId: string, -): Promise { - return runOptionPromise(resolveSessionAccess(store, sessionId, userId)) -} diff --git a/packages/api/src/server/background/session/types.ts b/packages/api/src/server/background/session/types.ts index 65753dd1..15974c44 100644 --- a/packages/api/src/server/background/session/types.ts +++ b/packages/api/src/server/background/session/types.ts @@ -177,21 +177,6 @@ export function toRuntimeActivityRow(row: SandboxActivityRow): RuntimeActivityRo } } -export function toSandboxActivityRow(row: RuntimeActivityRow): SandboxActivityRow { - return { - id: row.id, - sandbox_id: row.runtimeId, - type: row.type, - summary: row.summary, - status_from: row.statusFrom, - status_to: row.statusTo, - keep_alive: row.keepAlive == null ? null : row.keepAlive ? 1 : 0, - reason: row.reason, - data: row.dataJson, - created_at: row.createdAt, - } -} - export interface PromptDispatchResult { success: boolean error?: string diff --git a/packages/api/src/server/background/workflows/nodes/http.ts b/packages/api/src/server/background/workflows/nodes/http.ts index 4d4e79c5..c1472026 100644 --- a/packages/api/src/server/background/workflows/nodes/http.ts +++ b/packages/api/src/server/background/workflows/nodes/http.ts @@ -19,14 +19,9 @@ import * as Result from "effect/Result" export type WorkflowHttpNodeExecutionInput = WorkflowNodeExecutionInput -const workflowHttpNodeTypes = new Set(["http-request"]) const workflowHttpMethods = new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]) const workflowResponseTypes = new Set(["auto", "json", "text"]) -export function isWorkflowHttpNodeType(nodeType: string): boolean { - return workflowHttpNodeTypes.has(nodeType) -} - const requireString = (value: Option.Option, message: string) => Option.match(value, { onNone: () => workflowNodeFail(message), diff --git a/packages/api/src/server/background/workflows/nodes/notification.ts b/packages/api/src/server/background/workflows/nodes/notification.ts index f7c68747..d8469153 100644 --- a/packages/api/src/server/background/workflows/nodes/notification.ts +++ b/packages/api/src/server/background/workflows/nodes/notification.ts @@ -5,12 +5,6 @@ import * as Match from "effect/Match" export type WorkflowNotificationNodeExecutionInput = WorkflowNodeExecutionInput -const workflowNotificationNodeTypes = new Set(["email-notification"]) - -export function isWorkflowNotificationNodeType(nodeType: string): boolean { - return workflowNotificationNodeTypes.has(nodeType) -} - export const executeWorkflowNotificationNode = Effect.fn("workflows.executeNotificationNode")( function* (input: WorkflowNotificationNodeExecutionInput) { return yield* Match.value(input.node.type).pipe( diff --git a/packages/api/src/server/background/workflows/nodes/registry.ts b/packages/api/src/server/background/workflows/nodes/registry.ts index 2ac2481d..6bca6a44 100644 --- a/packages/api/src/server/background/workflows/nodes/registry.ts +++ b/packages/api/src/server/background/workflows/nodes/registry.ts @@ -40,12 +40,6 @@ const workflowNodeAdapters: Partial type AdapterRuntimeSupport = Extract diff --git a/packages/api/src/server/background/workflows/nodes/session.ts b/packages/api/src/server/background/workflows/nodes/session.ts index f4e5ed7d..6b35d184 100644 --- a/packages/api/src/server/background/workflows/nodes/session.ts +++ b/packages/api/src/server/background/workflows/nodes/session.ts @@ -51,7 +51,6 @@ import * as Option from "effect/Option" export type WorkflowSessionNodeExecutionInput = WorkflowNodeExecutionInput -const workflowSessionNodeTypes = new Set(["isolate-session", "sandbox-session"]) const MIN_WORKFLOW_SESSION_CACHE_TTL_SECONDS = 60 function runWorkflowLog(action: () => void) { @@ -98,10 +97,6 @@ interface WorkflowSessionRunResponse extends WorkflowSessionCacheEntry { createdSession?: boolean } -export function isWorkflowSessionNodeType(nodeType: string): boolean { - return workflowSessionNodeTypes.has(nodeType) -} - export const executeWorkflowSessionNode = Effect.fn("workflows.executeSessionNode")(function* ( input: WorkflowSessionNodeExecutionInput, ) { diff --git a/packages/api/src/server/background/workflows/nodes/storage.ts b/packages/api/src/server/background/workflows/nodes/storage.ts index faf645b0..98b11f1e 100644 --- a/packages/api/src/server/background/workflows/nodes/storage.ts +++ b/packages/api/src/server/background/workflows/nodes/storage.ts @@ -28,14 +28,6 @@ import * as Result from "effect/Result" export type WorkflowStorageNodeExecutionInput = WorkflowNodeExecutionInput -const workflowStorageNodeTypes = new Set([ - "r2-put-object", - "r2-get-object", - "kv-put", - "kv-get", - "get-secret", -]) - const workflowR2BucketIds = new Set( WORKFLOW_R2_BUCKET_OPTIONS.map((bucket) => bucket.binding), ) @@ -52,10 +44,6 @@ const workflowStorageEncodings = new Set( const R2_CONTENT_ENCODING_MANIFEST_VERSION = 2 -export function isWorkflowStorageNodeType(nodeType: string): boolean { - return workflowStorageNodeTypes.has(nodeType) -} - const requireString = (value: Option.Option, message: string) => Option.match(value, { onNone: () => workflowNodeFail(message), diff --git a/packages/api/src/server/effect/db/control-plane-db.ts b/packages/api/src/server/effect/db/control-plane-db.ts index 566412e5..199b7da7 100644 --- a/packages/api/src/server/effect/db/control-plane-db.ts +++ b/packages/api/src/server/effect/db/control-plane-db.ts @@ -74,13 +74,6 @@ export function resolveControlPlaneHandle(db: AppDrizzleDatabase | ControlPlaneD ) } -export function controlPlaneDialectForEngine(engine: S0DatabaseEngine): ControlPlaneDialect { - return Match.value(engine).pipe( - Match.when("planetscale", () => "postgres" as const), - Match.orElse(() => "sqlite" as const), - ) -} - interface DatabaseEngineSource { readonly [DATABASE_ENV]?: unknown } diff --git a/packages/api/src/server/effect/handlers/shared/control-plane.ts b/packages/api/src/server/effect/handlers/shared/control-plane.ts index 1aacff91..c13cd6d9 100644 --- a/packages/api/src/server/effect/handlers/shared/control-plane.ts +++ b/packages/api/src/server/effect/handlers/shared/control-plane.ts @@ -300,21 +300,6 @@ function buildSetupUrl(env: ApiEnv, extraParams?: Record): strin ) } -export function buildSetupResponse( - env: ApiEnv, - message: string, - status: number, - extraParams?: Record, -): Response { - return json( - { - error: message, - setupUrl: buildSetupUrl(env, extraParams), - }, - status, - ) -} - export const failSetup = ( env: ApiEnv, message: string, diff --git a/packages/api/src/server/effect/services/providers.ts b/packages/api/src/server/effect/services/providers.ts index 4e59f04c..db6df987 100644 --- a/packages/api/src/server/effect/services/providers.ts +++ b/packages/api/src/server/effect/services/providers.ts @@ -1,6 +1,5 @@ import * as Context from "effect/Context" import * as Effect from "effect/Effect" -import * as Layer from "effect/Layer" import * as Match from "effect/Match" import * as Option from "effect/Option" import type { ApiEnv } from "infra/types/env" @@ -224,16 +223,6 @@ export const MockGitHubProvider: GitHubProviderService = { }, } -export const LiveProviderLayer = Layer.mergeAll( - Layer.succeed(IdentityProvider, LiveIdentityProvider), - Layer.succeed(GitHubProvider, LiveGitHubProvider), -) - -export const MockProviderLayer = Layer.mergeAll( - Layer.succeed(IdentityProvider, MockIdentityProvider), - Layer.succeed(GitHubProvider, MockGitHubProvider), -) - export function providerServicesForEnv(env: ApiEnv) { return Match.value(env.S0_PROVIDER_LAYER === "mock").pipe( Match.when(true, () => ({ @@ -246,10 +235,3 @@ export function providerServicesForEnv(env: ApiEnv) { })), ) } - -export function providerLayerForEnv(env: ApiEnv) { - return Match.value(env.S0_PROVIDER_LAYER === "mock").pipe( - Match.when(true, () => MockProviderLayer), - Match.orElse(() => LiveProviderLayer), - ) -} diff --git a/packages/shared/src/agent-runtime.ts b/packages/shared/src/agent-runtime.ts index 4ba1583c..71d8cea8 100644 --- a/packages/shared/src/agent-runtime.ts +++ b/packages/shared/src/agent-runtime.ts @@ -45,13 +45,6 @@ const PROVIDER_COMPATIBILITY: Record< (providerId === "cloudflare-ai-gateway" && providerApi === "messages"), } -const MODEL_COMPATIBILITY_DESCRIPTIONS: Record = { - isolate: "any configured model", - opencode: "Cloudflare AI Gateway or LiteLLM models", - codex: "Cloudflare AI Gateway OpenAI Responses or LiteLLM OpenAI-compatible models", - "claude-code": "Cloudflare AI Gateway or LiteLLM Anthropic Messages models", -} - const AGENT_RUNTIME_LABELS: Record = { isolate: "Isolate", opencode: "OpenCode", @@ -67,10 +60,6 @@ export function isAgentRuntimeCompatibleWithProvider( return PROVIDER_COMPATIBILITY[agentRuntime](providerId, providerApi) } -export function describeAgentRuntimeModelCompatibility(agentRuntime: AgentRuntime): string { - return MODEL_COMPATIBILITY_DESCRIPTIONS[agentRuntime] -} - export function formatAgentRuntimeLabel(agentRuntime: AgentRuntime): string { return AGENT_RUNTIME_LABELS[agentRuntime] } diff --git a/packages/shared/src/session-tools.ts b/packages/shared/src/session-tools.ts index 12b7d38b..c2a369ff 100644 --- a/packages/shared/src/session-tools.ts +++ b/packages/shared/src/session-tools.ts @@ -90,33 +90,6 @@ export function isCustomMcpServerId(id: string): boolean { return id.startsWith(CUSTOM_MCP_SERVER_ID_PREFIX) } -export function parseCustomMcpServerId(id: string): { - serverName: string - hash: string -} | null { - if (!isCustomMcpServerId(id)) { - return null - } - - const body = id.slice(CUSTOM_MCP_SERVER_ID_PREFIX.length) - const separatorIndex = body.lastIndexOf(CUSTOM_MCP_SERVER_ID_HASH_SEPARATOR) - - if (separatorIndex <= 0) { - return null - } - - const hashStart = separatorIndex + CUSTOM_MCP_SERVER_ID_HASH_SEPARATOR.length - - if (hashStart >= body.length) { - return null - } - - return { - serverName: body.slice(0, separatorIndex), - hash: body.slice(hashStart), - } -} - export function parseCustomMcpToolKey(toolKey: string): { serverName: string | null mcpToolName: string @@ -731,22 +704,6 @@ export function resolveSessionTools(input: ResolveSessionToolsInput): SessionToo return normalizeSessionTools(combined) } -export function encodeSessionToolQueryValue(tool: SessionToolSpec): string { - if (tool.kind === "github_repo") { - return `${tool.kind}:${formatGitHubRepoTool(tool)}` - } - - if (tool.kind === "workflow_builder") { - return tool.kind - } - - if (tool.kind === MCPCF_SESSION_TOOL_KIND) { - return `${tool.kind}:${tool.serverId}` - } - - return `${tool.kind}:${tool.sourceId}` -} - export function decodeSessionToolQueryValue(value: string): SessionToolSpec { if (value === "workflow_builder") { return { kind: "workflow_builder" } @@ -799,18 +756,6 @@ export function parseSessionToolsFromSearchParams( return normalizeSessionTools(searchParams.getAll(paramName).map(decodeSessionToolQueryValue)) } -export function appendSessionToolsToSearchParams( - searchParams: URLSearchParams, - tools: readonly SessionToolSpec[] | null | undefined, - paramName = SESSION_TOOL_QUERY_PARAM, -): URLSearchParams { - normalizeSessionTools(tools).forEach((tool) => { - searchParams.append(paramName, encodeSessionToolQueryValue(tool)) - }) - - return searchParams -} - export function stringifySessionTools( tools: readonly SessionToolSpec[] | null | undefined, ): string { diff --git a/packages/shared/src/stageMetadata.ts b/packages/shared/src/stageMetadata.ts index bf857868..acf8e439 100644 --- a/packages/shared/src/stageMetadata.ts +++ b/packages/shared/src/stageMetadata.ts @@ -217,46 +217,6 @@ function invalidStageError(stageStr: string): InvalidStageError { }) } -export function getAppStageMetadataFromStr( - stageStr: string, -): Result.Result { - const lowerCaseStage = stageStr.toLowerCase() - - return Match.value(lowerCaseStage).pipe( - Match.when("dev", () => Result.succeed({ name: "dev", app: Dev.app })), - Match.when("test", () => Result.succeed({ name: "test", app: Test.app })), - Match.when("prod", () => Result.succeed({ name: "prod", app: Prod.app })), - Match.when( - (stage) => stage === "pre" || stage.startsWith("pre-"), - (stage) => Result.succeed({ name: stage, app: Pre.app }), - ), - Match.orElse(() => Result.fail(invalidStageError(stageStr))), - ) -} - -const appStageMetadataFromBinding = ({ name, app }: StageMetadataBinding): AppStageMetadata => ({ - name, - app, -}) - -function appStageMetadataFromEnv(env: StageMetadataEnv) { - return Option.match(Option.fromUndefinedOr(env.S0_STAGE_METADATA), { - onNone: () => getAppStageMetadataFromStr(env.STAGE), - onSome: (binding) => - Result.succeed(appStageMetadataFromBinding(decodeStageMetadataBinding(binding))), - }) -} - -/** App metadata is deterministic and resolves no infrastructure, so browser and Worker callers read it synchronously. */ -export function getAppStageMetadataSync(input: string | StageMetadataEnv): AppStageMetadata { - return Match.value(input).pipe( - Match.when(Match.string, getAppStageMetadataFromStr), - Match.orElse(appStageMetadataFromEnv), - // oxlint-disable-next-line effect/avoid-option-getorthrow -- Synchronous boundary for non-Effect callers: invalid input throws the typed error by contract. - Result.getOrThrow, - ) -} - function localInfraStageProps( config: StageInfraConfig, consoleOutputEnabled: boolean, From de66d15a0cd9de28351d75403d99279715b43342 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 8 Nov 2026 09:31:41 +0000 Subject: [PATCH 2/3] Retry validation after the actionlint download returned 504. Co-authored-by: Jonathan Beckman From 62f389d9ccb1aa1e5e300c4b4bff8bd7305c41cf Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 8 Nov 2026 09:34:51 +0000 Subject: [PATCH 3/3] Retry validation now that the actionlint installer responds. Co-authored-by: Jonathan Beckman