import { NetService } from "@t3tools/shared/Net";import { parsePersistedServerObservabilitySettings } from "@t3tools/shared/serverSettings";import { AuthSessionId, CommandId, OrchestrationReadModel, ProjectId, type ClientOrchestrationCommand,} from "@t3tools/contracts";import { Config, Console, Duration, Effect, Exit, FileSystem, Layer, LogLevel, Option, Path, References, Schema, SchemaIssue, SchemaTransformation,} from "effect";import { Argument, Command, Flag, GlobalFlag } from "effect/unstable/cli";import { FetchHttpClient, HttpClient, HttpClientRequest, HttpClientResponse,} from "effect/unstable/http"; import { DEFAULT_PORT, deriveServerPaths, ensureServerDirectories, resolveStaticDir, ServerConfig, RuntimeMode, type ServerConfigShape, type StartupPresentation,} from "./config.ts";import { readBootstrapEnvelope } from "./bootstrap.ts";import { expandHomePath, resolveBaseDir } from "./os-jank.ts";import { runServer } from "./server.ts";import { AuthControlPlaneRuntimeLive } from "./auth/Layers/AuthControlPlane.ts";import { formatIssuedPairingCredential, formatIssuedSession, formatPairingCredentialList, formatSessionList,} from "./cliAuthFormat.ts";import { AuthControlPlane } from "./auth/Services/AuthControlPlane.ts";import type { AuthControlPlaneShape } from "./auth/Services/AuthControlPlane.ts";import { OrchestrationEngineService } from "./orchestration/Services/OrchestrationEngine.ts";import { ProjectionSnapshotQuery } from "./orchestration/Services/ProjectionSnapshotQuery.ts";import { OrchestrationLayerLive } from "./orchestration/runtimeLayer.ts";import { layerConfig as SqlitePersistenceLayerLive } from "./persistence/Layers/Sqlite.ts";import { RepositoryIdentityResolverLive } from "./project/Layers/RepositoryIdentityResolver.ts";import { getAutoBootstrapDefaultModelSelection } from "./serverRuntimeStartup.ts";import { clearPersistedServerRuntimeState, readPersistedServerRuntimeState,} from "./serverRuntimeState.ts";import { WorkspacePaths } from "./workspace/Services/WorkspacePaths.ts";import { WorkspacePathsLive } from "./workspace/Layers/WorkspacePaths.ts"; const PortSchema = Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 65535 })); const BootstrapEnvelopeSchema = Schema.Struct({ mode: Schema.optional(RuntimeMode), port: Schema.optional(PortSchema), host: Schema.optional(Schema.String), t3Home: Schema.optional(Schema.String), devUrl: Schema.optional(Schema.URLFromString), noBrowser: Schema.optional(Schema.Boolean), desktopBootstrapToken: Schema.optional(Schema.String), autoBootstrapProjectFromCwd: Schema.optional(Schema.Boolean), logWebSocketEvents: Schema.optional(Schema.Boolean), tailscaleServeEnabled: Schema.optional(Schema.Boolean), tailscaleServePort: Schema.optional(PortSchema), otlpTracesUrl: Schema.optional(Schema.String), otlpMetricsUrl: Schema.optional(Schema.String),}); const modeFlag = Flag.choice("mode", RuntimeMode.literals).pipe( Flag.withDescription("Runtime mode. `desktop` keeps loopback defaults unless overridden."), Flag.optional,);const portFlag = Flag.integer("port").pipe( Flag.withSchema(PortSchema), Flag.withDescription("Port for the HTTP/WebSocket server."), Flag.optional,);const hostFlag = Flag.string("host").pipe( Flag.withDescription("Host/interface to bind (for example 127.0.0.1, 0.0.0.0, or a Tailnet IP)."), Flag.optional,);const baseDirFlag = Flag.string("base-dir").pipe( Flag.withDescription("Base directory path (equivalent to T3CODE_HOME)."), Flag.optional,);const devUrlFlag = Flag.string("dev-url").pipe( Flag.withSchema(Schema.URLFromString), Flag.withDescription("Dev web URL to proxy/redirect to (equivalent to VITE_DEV_SERVER_URL)."), Flag.optional,);const noBrowserFlag = Flag.boolean("no-browser").pipe( Flag.withDescription("Disable automatic browser opening."), Flag.optional,);const bootstrapFdFlag = Flag.integer("bootstrap-fd").pipe( Flag.withSchema(Schema.Int), Flag.withDescription("Read one-time bootstrap secrets from the given file descriptor."), Flag.optional,);const autoBootstrapProjectFromCwdFlag = Flag.boolean("auto-bootstrap-project-from-cwd").pipe( Flag.withDescription( "Create a project for the current working directory on startup when missing.", ), Flag.optional,);const logWebSocketEventsFlag = Flag.boolean("log-websocket-events").pipe( Flag.withDescription( "Emit server-side logs for outbound WebSocket push traffic (equivalent to T3CODE_LOG_WS_EVENTS).", ), Flag.withAlias("log-ws-events"), Flag.optional,);const tailscaleServeFlag = Flag.boolean("tailscale-serve").pipe( Flag.withDescription( "Configure Tailscale Serve to expose this backend over HTTPS on the Tailnet.", ), Flag.optional,);const tailscaleServePortFlag = Flag.integer("tailscale-serve-port").pipe( Flag.withSchema(PortSchema), Flag.withDescription("HTTPS port for Tailscale Serve when --tailscale-serve is enabled."), Flag.optional,); const EnvServerConfig = Config.all({ logLevel: Config.logLevel("T3CODE_LOG_LEVEL").pipe(Config.withDefault("Info")), traceMinLevel: Config.logLevel("T3CODE_TRACE_MIN_LEVEL").pipe(Config.withDefault("Info")), traceTimingEnabled: Config.boolean("T3CODE_TRACE_TIMING_ENABLED").pipe(Config.withDefault(true)), traceFile: Config.string("T3CODE_TRACE_FILE").pipe( Config.option, Config.map(Option.getOrUndefined), ), traceMaxBytes: Config.int("T3CODE_TRACE_MAX_BYTES").pipe(Config.withDefault(10 * 1024 * 1024)), traceMaxFiles: Config.int("T3CODE_TRACE_MAX_FILES").pipe(Config.withDefault(10)), traceBatchWindowMs: Config.int("T3CODE_TRACE_BATCH_WINDOW_MS").pipe(Config.withDefault(200)), otlpTracesUrl: Config.string("T3CODE_OTLP_TRACES_URL").pipe( Config.option, Config.map(Option.getOrUndefined), ), otlpMetricsUrl: Config.string("T3CODE_OTLP_METRICS_URL").pipe( Config.option, Config.map(Option.getOrUndefined), ), otlpExportIntervalMs: Config.int("T3CODE_OTLP_EXPORT_INTERVAL_MS").pipe( Config.withDefault(10_000), ), otlpServiceName: Config.string("T3CODE_OTLP_SERVICE_NAME").pipe(Config.withDefault("t3-server")), mode: Config.schema(RuntimeMode, "T3CODE_MODE").pipe( Config.option, Config.map(Option.getOrUndefined), ), port: Config.port("T3CODE_PORT").pipe(Config.option, Config.map(Option.getOrUndefined)), host: Config.string("T3CODE_HOST").pipe(Config.option, Config.map(Option.getOrUndefined)), t3Home: Config.string("T3CODE_HOME").pipe(Config.option, Config.map(Option.getOrUndefined)), devUrl: Config.url("VITE_DEV_SERVER_URL").pipe(Config.option, Config.map(Option.getOrUndefined)), noBrowser: Config.boolean("T3CODE_NO_BROWSER").pipe( Config.option, Config.map(Option.getOrUndefined), ), bootstrapFd: Config.int("T3CODE_BOOTSTRAP_FD").pipe( Config.option, Config.map(Option.getOrUndefined), ), autoBootstrapProjectFromCwd: Config.boolean("T3CODE_AUTO_BOOTSTRAP_PROJECT_FROM_CWD").pipe( Config.option, Config.map(Option.getOrUndefined), ), logWebSocketEvents: Config.boolean("T3CODE_LOG_WS_EVENTS").pipe( Config.option, Config.map(Option.getOrUndefined), ), tailscaleServeEnabled: Config.boolean("T3CODE_TAILSCALE_SERVE").pipe( Config.option, Config.map(Option.getOrUndefined), ), tailscaleServePort: Config.port("T3CODE_TAILSCALE_SERVE_PORT").pipe( Config.option, Config.map(Option.getOrUndefined), ),}); interface CliServerFlags { readonly mode: Option.Option<RuntimeMode>; readonly port: Option.Option<number>; readonly host: Option.Option<string>; readonly baseDir: Option.Option<string>; readonly cwd: Option.Option<string>; readonly devUrl: Option.Option<URL>; readonly noBrowser: Option.Option<boolean>; readonly bootstrapFd: Option.Option<number>; readonly autoBootstrapProjectFromCwd: Option.Option<boolean>; readonly logWebSocketEvents: Option.Option<boolean>; readonly tailscaleServeEnabled: Option.Option<boolean>; readonly tailscaleServePort: Option.Option<number>;} interface CliAuthLocationFlags { readonly baseDir: Option.Option<string>; readonly devUrl?: Option.Option<URL>;} const resolveOptionPrecedence = <Value>( ...values: ReadonlyArray<Option.Option<Value>>): Option.Option<Value> => Option.firstSomeOf(values); const loadPersistedObservabilitySettings = Effect.fn(function* (settingsPath: string) { const fs = yield* FileSystem.FileSystem; const exists = yield* fs.exists(settingsPath).pipe(Effect.orElseSucceed(() => false)); if (!exists) { return { otlpTracesUrl: undefined, otlpMetricsUrl: undefined }; } const raw = yield* fs.readFileString(settingsPath).pipe(Effect.orElseSucceed(() => "")); return parsePersistedServerObservabilitySettings(raw);}); export const resolveServerConfig = ( flags: CliServerFlags, cliLogLevel: Option.Option<LogLevel.LogLevel>, options?: { readonly startupPresentation?: StartupPresentation; readonly forceAutoBootstrapProjectFromCwd?: boolean; },) => Effect.gen(function* () { const { findAvailablePort } = yield* NetService; const path = yield* Path.Path; const fs = yield* FileSystem.FileSystem; const env = yield* EnvServerConfig; const normalizedFlags = { mode: flags.mode ?? Option.none(), port: flags.port ?? Option.none(), host: flags.host ?? Option.none(), baseDir: flags.baseDir ?? Option.none(), cwd: flags.cwd ?? Option.none(), devUrl: flags.devUrl ?? Option.none(), noBrowser: flags.noBrowser ?? Option.none(), bootstrapFd: flags.bootstrapFd ?? Option.none(), autoBootstrapProjectFromCwd: flags.autoBootstrapProjectFromCwd ?? Option.none(), logWebSocketEvents: flags.logWebSocketEvents ?? Option.none(), tailscaleServeEnabled: flags.tailscaleServeEnabled ?? Option.none(), tailscaleServePort: flags.tailscaleServePort ?? Option.none(), } satisfies CliServerFlags; const bootstrapFd = Option.getOrUndefined(normalizedFlags.bootstrapFd) ?? env.bootstrapFd; const bootstrapEnvelope = bootstrapFd !== undefined ? yield* readBootstrapEnvelope(BootstrapEnvelopeSchema, bootstrapFd) : Option.none(); const bootstrap = Option.getOrUndefined(bootstrapEnvelope); const mode: RuntimeMode = Option.getOrElse( resolveOptionPrecedence( normalizedFlags.mode, Option.fromUndefinedOr(env.mode), Option.fromUndefinedOr(bootstrap?.mode), ), () => "web", ); const port = yield* Option.match( resolveOptionPrecedence( normalizedFlags.port, Option.fromUndefinedOr(env.port), Option.fromUndefinedOr(bootstrap?.port), ), { onSome: (value) => Effect.succeed(value), onNone: () => { if (mode === "desktop") { return Effect.succeed(DEFAULT_PORT); } return findAvailablePort(DEFAULT_PORT); }, }, ); const devUrl = Option.getOrElse( resolveOptionPrecedence( normalizedFlags.devUrl, Option.fromUndefinedOr(env.devUrl), Option.fromUndefinedOr(bootstrap?.devUrl), ), () => undefined, ); const baseDir = yield* resolveBaseDir( Option.getOrUndefined( resolveOptionPrecedence( normalizedFlags.baseDir, Option.fromUndefinedOr(env.t3Home), Option.fromUndefinedOr(bootstrap?.t3Home), ), ), ); const rawCwd = Option.getOrElse(normalizedFlags.cwd, () => process.cwd()); const cwd = path.resolve(yield* expandHomePath(rawCwd.trim())); yield* fs.makeDirectory(cwd, { recursive: true }); const derivedPaths = yield* deriveServerPaths(baseDir, devUrl); yield* ensureServerDirectories(derivedPaths); const persistedObservabilitySettings = yield* loadPersistedObservabilitySettings( derivedPaths.settingsPath, ); const serverTracePath = env.traceFile ?? derivedPaths.serverTracePath; yield* fs.makeDirectory(path.dirname(serverTracePath), { recursive: true }); const startupPresentation = options?.startupPresentation ?? "browser"; const isHeadlessStartup = startupPresentation === "headless"; const noBrowser = Option.getOrElse( resolveOptionPrecedence( isHeadlessStartup ? Option.some(true) : Option.none(), normalizedFlags.noBrowser, Option.fromUndefinedOr(env.noBrowser), Option.fromUndefinedOr(bootstrap?.noBrowser), ), () => mode === "desktop", ); const desktopBootstrapToken = bootstrap?.desktopBootstrapToken; const autoBootstrapProjectFromCwd = Option.getOrElse( resolveOptionPrecedence( Option.fromUndefinedOr(options?.forceAutoBootstrapProjectFromCwd), isHeadlessStartup ? Option.some(false) : Option.none(), normalizedFlags.autoBootstrapProjectFromCwd, Option.fromUndefinedOr(env.autoBootstrapProjectFromCwd), Option.fromUndefinedOr(bootstrap?.autoBootstrapProjectFromCwd), ), () => mode === "web", ); const logWebSocketEvents = Option.getOrElse( resolveOptionPrecedence( normalizedFlags.logWebSocketEvents, Option.fromUndefinedOr(env.logWebSocketEvents), Option.fromUndefinedOr(bootstrap?.logWebSocketEvents), ), () => Boolean(devUrl), ); const tailscaleServeEnabled = Option.getOrElse( resolveOptionPrecedence( normalizedFlags.tailscaleServeEnabled, Option.fromUndefinedOr(env.tailscaleServeEnabled), Option.fromUndefinedOr(bootstrap?.tailscaleServeEnabled), ), () => false, ); const tailscaleServePort = Option.getOrElse( resolveOptionPrecedence( normalizedFlags.tailscaleServePort, Option.fromUndefinedOr(env.tailscaleServePort), Option.fromUndefinedOr(bootstrap?.tailscaleServePort), ), () => 443, ); const staticDir = devUrl ? undefined : yield* resolveStaticDir(); const host = Option.getOrElse( resolveOptionPrecedence( normalizedFlags.host, Option.fromUndefinedOr(env.host), Option.fromUndefinedOr(bootstrap?.host), ), () => (mode === "desktop" ? "127.0.0.1" : undefined), ); const logLevel = Option.getOrElse(cliLogLevel, () => env.logLevel); const config: ServerConfigShape = { logLevel, traceMinLevel: env.traceMinLevel, traceTimingEnabled: env.traceTimingEnabled, traceBatchWindowMs: env.traceBatchWindowMs, traceMaxBytes: env.traceMaxBytes, traceMaxFiles: env.traceMaxFiles, otlpTracesUrl: env.otlpTracesUrl ?? bootstrap?.otlpTracesUrl ?? persistedObservabilitySettings.otlpTracesUrl, otlpMetricsUrl: env.otlpMetricsUrl ?? bootstrap?.otlpMetricsUrl ?? persistedObservabilitySettings.otlpMetricsUrl, otlpExportIntervalMs: env.otlpExportIntervalMs, otlpServiceName: env.otlpServiceName, mode, port, cwd, baseDir, ...derivedPaths, serverTracePath, host, staticDir, devUrl, noBrowser, startupPresentation, desktopBootstrapToken, autoBootstrapProjectFromCwd, logWebSocketEvents, tailscaleServeEnabled, tailscaleServePort, }; return config; }); const resolveCliAuthConfig = ( flags: CliAuthLocationFlags, cliLogLevel: Option.Option<LogLevel.LogLevel>,) => resolveServerConfig( { mode: Option.none(), port: Option.none(), host: Option.none(), baseDir: flags.baseDir, cwd: Option.none(), devUrl: flags.devUrl ?? Option.none(), noBrowser: Option.none(), bootstrapFd: Option.none(), autoBootstrapProjectFromCwd: Option.none(), logWebSocketEvents: Option.none(), tailscaleServeEnabled: Option.none(), tailscaleServePort: Option.none(), }, cliLogLevel, ); const DurationShorthandPattern = /^(?<value>\d+)(?<unit>ms|s|m|h|d|w)$/i; const parseDurationInput = (value: string): Duration.Duration | null => { const trimmed = value.trim(); if (trimmed.length === 0) return null; const shorthand = DurationShorthandPattern.exec(trimmed); const normalizedInput = shorthand?.groups ? (() => { const amountText = shorthand.groups.value; const unitText = shorthand.groups.unit; if (typeof amountText !== "string" || typeof unitText !== "string") { return null; } const amount = Number.parseInt(amountText, 10); if (!Number.isFinite(amount)) return null; switch (unitText.toLowerCase()) { case "ms": return `${amount} millis`; case "s": return `${amount} seconds`; case "m": return `${amount} minutes`; case "h": return `${amount} hours`; case "d": return `${amount} days`; case "w": return `${amount} weeks`; default: return null; } })() : (trimmed as Duration.Input); if (normalizedInput === null) return null; const decoded = Duration.fromInput(normalizedInput as Duration.Input); return Option.isSome(decoded) ? decoded.value : null;}; const DurationFromString = Schema.String.pipe( Schema.decodeTo( Schema.Duration, SchemaTransformation.transformOrFail({ decode: (value) => { const duration = parseDurationInput(value); if (duration !== null) { return Effect.succeed(duration); } return Effect.fail( new SchemaIssue.InvalidValue(Option.some(value), { message: "Invalid duration. Use values like 5m, 1h, 30d, or 15 minutes.", }), ); }, encode: (duration) => Effect.succeed(Duration.format(duration)), }), ),); Lines 1–500 of 1180. Load more
import { NetService } from "@t3tools/shared/Net"; import { parsePersistedServerObservabilitySettings } from "@t3tools/shared/serverSettings"; import { AuthSessionId, CommandId, OrchestrationReadModel, ProjectId, type ClientOrchestrationCommand, } from "@t3tools/contracts"; import { Config, Console, Duration, Effect, Exit, FileSystem, Layer, LogLevel, Option, Path, References, Schema, SchemaIssue, SchemaTransformation, } from "effect"; import { Argument, Command, Flag, GlobalFlag } from "effect/unstable/cli"; import { FetchHttpClient, HttpClient, HttpClientRequest, HttpClientResponse, } from "effect/unstable/http"; import { DEFAULT_PORT, deriveServerPaths, ensureServerDirectories, resolveStaticDir, ServerConfig, RuntimeMode, type ServerConfigShape, type StartupPresentation, } from "./config.ts"; import { readBootstrapEnvelope } from "./bootstrap.ts"; import { expandHomePath, resolveBaseDir } from "./os-jank.ts"; import { runServer } from "./server.ts"; import { AuthControlPlaneRuntimeLive } from "./auth/Layers/AuthControlPlane.ts"; import { formatIssuedPairingCredential, formatIssuedSession, formatPairingCredentialList, formatSessionList, } from "./cliAuthFormat.ts"; import { AuthControlPlane } from "./auth/Services/AuthControlPlane.ts"; import type { AuthControlPlaneShape } from "./auth/Services/AuthControlPlane.ts"; import { OrchestrationEngineService } from "./orchestration/Services/OrchestrationEngine.ts"; import { ProjectionSnapshotQuery } from "./orchestration/Services/ProjectionSnapshotQuery.ts"; import { OrchestrationLayerLive } from "./orchestration/runtimeLayer.ts"; import { layerConfig as SqlitePersistenceLayerLive } from "./persistence/Layers/Sqlite.ts"; import { RepositoryIdentityResolverLive } from "./project/Layers/RepositoryIdentityResolver.ts"; import { getAutoBootstrapDefaultModelSelection } from "./serverRuntimeStartup.ts"; import { clearPersistedServerRuntimeState, readPersistedServerRuntimeState, } from "./serverRuntimeState.ts"; import { WorkspacePaths } from "./workspace/Services/WorkspacePaths.ts"; import { WorkspacePathsLive } from "./workspace/Layers/WorkspacePaths.ts"; const PortSchema = Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 65535 })); const BootstrapEnvelopeSchema = Schema.Struct({ mode: Schema.optional(RuntimeMode), port: Schema.optional(PortSchema), host: Schema.optional(Schema.String), t3Home: Schema.optional(Schema.String), devUrl: Schema.optional(Schema.URLFromString), noBrowser: Schema.optional(Schema.Boolean), desktopBootstrapToken: Schema.optional(Schema.String), autoBootstrapProjectFromCwd: Schema.optional(Schema.Boolean), logWebSocketEvents: Schema.optional(Schema.Boolean), tailscaleServeEnabled: Schema.optional(Schema.Boolean), tailscaleServePort: Schema.optional(PortSchema), otlpTracesUrl: Schema.optional(Schema.String), otlpMetricsUrl: Schema.optional(Schema.String), }); const modeFlag = Flag.choice("mode", RuntimeMode.literals).pipe( Flag.withDescription("Runtime mode. `desktop` keeps loopback defaults unless overridden."), Flag.optional, ); const portFlag = Flag.integer("port").pipe( Flag.withSchema(PortSchema), Flag.withDescription("Port for the HTTP/WebSocket server."), Flag.optional, ); const hostFlag = Flag.string("host").pipe( Flag.withDescription("Host/interface to bind (for example 127.0.0.1, 0.0.0.0, or a Tailnet IP)."), Flag.optional, ); const baseDirFlag = Flag.string("base-dir").pipe( Flag.withDescription("Base directory path (equivalent to T3CODE_HOME)."), Flag.optional, ); const devUrlFlag = Flag.string("dev-url").pipe( Flag.withSchema(Schema.URLFromString), Flag.withDescription("Dev web URL to proxy/redirect to (equivalent to VITE_DEV_SERVER_URL)."), Flag.optional, ); const noBrowserFlag = Flag.boolean("no-browser").pipe( Flag.withDescription("Disable automatic browser opening."), Flag.optional, ); const bootstrapFdFlag = Flag.integer("bootstrap-fd").pipe( Flag.withSchema(Schema.Int), Flag.withDescription("Read one-time bootstrap secrets from the given file descriptor."), Flag.optional, ); const autoBootstrapProjectFromCwdFlag = Flag.boolean("auto-bootstrap-project-from-cwd").pipe( Flag.withDescription( "Create a project for the current working directory on startup when missing.", ), Flag.optional, ); const logWebSocketEventsFlag = Flag.boolean("log-websocket-events").pipe( Flag.withDescription( "Emit server-side logs for outbound WebSocket push traffic (equivalent to T3CODE_LOG_WS_EVENTS).", ), Flag.withAlias("log-ws-events"), Flag.optional, ); const tailscaleServeFlag = Flag.boolean("tailscale-serve").pipe( Flag.withDescription( "Configure Tailscale Serve to expose this backend over HTTPS on the Tailnet.", ), Flag.optional, ); const tailscaleServePortFlag = Flag.integer("tailscale-serve-port").pipe( Flag.withSchema(PortSchema), Flag.withDescription("HTTPS port for Tailscale Serve when --tailscale-serve is enabled."), Flag.optional, ); const EnvServerConfig = Config.all({ logLevel: Config.logLevel("T3CODE_LOG_LEVEL").pipe(Config.withDefault("Info")), traceMinLevel: Config.logLevel("T3CODE_TRACE_MIN_LEVEL").pipe(Config.withDefault("Info")), traceTimingEnabled: Config.boolean("T3CODE_TRACE_TIMING_ENABLED").pipe(Config.withDefault(true)), traceFile: Config.string("T3CODE_TRACE_FILE").pipe( Config.option, Config.map(Option.getOrUndefined), ), traceMaxBytes: Config.int("T3CODE_TRACE_MAX_BYTES").pipe(Config.withDefault(10 * 1024 * 1024)), traceMaxFiles: Config.int("T3CODE_TRACE_MAX_FILES").pipe(Config.withDefault(10)), traceBatchWindowMs: Config.int("T3CODE_TRACE_BATCH_WINDOW_MS").pipe(Config.withDefault(200)), otlpTracesUrl: Config.string("T3CODE_OTLP_TRACES_URL").pipe( Config.option, Config.map(Option.getOrUndefined), ), otlpMetricsUrl: Config.string("T3CODE_OTLP_METRICS_URL").pipe( Config.option, Config.map(Option.getOrUndefined), ), otlpExportIntervalMs: Config.int("T3CODE_OTLP_EXPORT_INTERVAL_MS").pipe( Config.withDefault(10_000), ), otlpServiceName: Config.string("T3CODE_OTLP_SERVICE_NAME").pipe(Config.withDefault("t3-server")), mode: Config.schema(RuntimeMode, "T3CODE_MODE").pipe( Config.option, Config.map(Option.getOrUndefined), ), port: Config.port("T3CODE_PORT").pipe(Config.option, Config.map(Option.getOrUndefined)), host: Config.string("T3CODE_HOST").pipe(Config.option, Config.map(Option.getOrUndefined)), t3Home: Config.string("T3CODE_HOME").pipe(Config.option, Config.map(Option.getOrUndefined)), devUrl: Config.url("VITE_DEV_SERVER_URL").pipe(Config.option, Config.map(Option.getOrUndefined)), noBrowser: Config.boolean("T3CODE_NO_BROWSER").pipe( Config.option, Config.map(Option.getOrUndefined), ), bootstrapFd: Config.int("T3CODE_BOOTSTRAP_FD").pipe( Config.option, Config.map(Option.getOrUndefined), ), autoBootstrapProjectFromCwd: Config.boolean("T3CODE_AUTO_BOOTSTRAP_PROJECT_FROM_CWD").pipe( Config.option, Config.map(Option.getOrUndefined), ), logWebSocketEvents: Config.boolean("T3CODE_LOG_WS_EVENTS").pipe( Config.option, Config.map(Option.getOrUndefined), ), tailscaleServeEnabled: Config.boolean("T3CODE_TAILSCALE_SERVE").pipe( Config.option, Config.map(Option.getOrUndefined), ), tailscaleServePort: Config.port("T3CODE_TAILSCALE_SERVE_PORT").pipe( Config.option, Config.map(Option.getOrUndefined), ), }); interface CliServerFlags { readonly mode: Option.Option<RuntimeMode>; readonly port: Option.Option<number>; readonly host: Option.Option<string>; readonly baseDir: Option.Option<string>; readonly cwd: Option.Option<string>; readonly devUrl: Option.Option<URL>; readonly noBrowser: Option.Option<boolean>; readonly bootstrapFd: Option.Option<number>; readonly autoBootstrapProjectFromCwd: Option.Option<boolean>; readonly logWebSocketEvents: Option.Option<boolean>; readonly tailscaleServeEnabled: Option.Option<boolean>; readonly tailscaleServePort: Option.Option<number>; } interface CliAuthLocationFlags { readonly baseDir: Option.Option<string>; readonly devUrl?: Option.Option<URL>; } const resolveOptionPrecedence = <Value>( ...values: ReadonlyArray<Option.Option<Value>> ): Option.Option<Value> => Option.firstSomeOf(values); const loadPersistedObservabilitySettings = Effect.fn(function* (settingsPath: string) { const fs = yield* FileSystem.FileSystem; const exists = yield* fs.exists(settingsPath).pipe(Effect.orElseSucceed(() => false)); if (!exists) { return { otlpTracesUrl: undefined, otlpMetricsUrl: undefined }; } const raw = yield* fs.readFileString(settingsPath).pipe(Effect.orElseSucceed(() => "")); return parsePersistedServerObservabilitySettings(raw); }); export const resolveServerConfig = ( flags: CliServerFlags, cliLogLevel: Option.Option<LogLevel.LogLevel>, options?: { readonly startupPresentation?: StartupPresentation; readonly forceAutoBootstrapProjectFromCwd?: boolean; }, ) => Effect.gen(function* () { const { findAvailablePort } = yield* NetService; const path = yield* Path.Path; const fs = yield* FileSystem.FileSystem; const env = yield* EnvServerConfig; const normalizedFlags = { mode: flags.mode ?? Option.none(), port: flags.port ?? Option.none(), host: flags.host ?? Option.none(), baseDir: flags.baseDir ?? Option.none(), cwd: flags.cwd ?? Option.none(), devUrl: flags.devUrl ?? Option.none(), noBrowser: flags.noBrowser ?? Option.none(), bootstrapFd: flags.bootstrapFd ?? Option.none(), autoBootstrapProjectFromCwd: flags.autoBootstrapProjectFromCwd ?? Option.none(), logWebSocketEvents: flags.logWebSocketEvents ?? Option.none(), tailscaleServeEnabled: flags.tailscaleServeEnabled ?? Option.none(), tailscaleServePort: flags.tailscaleServePort ?? Option.none(), } satisfies CliServerFlags; const bootstrapFd = Option.getOrUndefined(normalizedFlags.bootstrapFd) ?? env.bootstrapFd; const bootstrapEnvelope = bootstrapFd !== undefined ? yield* readBootstrapEnvelope(BootstrapEnvelopeSchema, bootstrapFd) : Option.none(); const bootstrap = Option.getOrUndefined(bootstrapEnvelope); const mode: RuntimeMode = Option.getOrElse( resolveOptionPrecedence( normalizedFlags.mode, Option.fromUndefinedOr(env.mode), Option.fromUndefinedOr(bootstrap?.mode), ), () => "web", ); const port = yield* Option.match( resolveOptionPrecedence( normalizedFlags.port, Option.fromUndefinedOr(env.port), Option.fromUndefinedOr(bootstrap?.port), ), { onSome: (value) => Effect.succeed(value), onNone: () => { if (mode === "desktop") { return Effect.succeed(DEFAULT_PORT); } return findAvailablePort(DEFAULT_PORT); }, }, ); const devUrl = Option.getOrElse( resolveOptionPrecedence( normalizedFlags.devUrl, Option.fromUndefinedOr(env.devUrl), Option.fromUndefinedOr(bootstrap?.devUrl), ), () => undefined, ); const baseDir = yield* resolveBaseDir( Option.getOrUndefined( resolveOptionPrecedence( normalizedFlags.baseDir, Option.fromUndefinedOr(env.t3Home), Option.fromUndefinedOr(bootstrap?.t3Home), ), ), ); const rawCwd = Option.getOrElse(normalizedFlags.cwd, () => process.cwd()); const cwd = path.resolve(yield* expandHomePath(rawCwd.trim())); yield* fs.makeDirectory(cwd, { recursive: true }); const derivedPaths = yield* deriveServerPaths(baseDir, devUrl); yield* ensureServerDirectories(derivedPaths); const persistedObservabilitySettings = yield* loadPersistedObservabilitySettings( derivedPaths.settingsPath, ); const serverTracePath = env.traceFile ?? derivedPaths.serverTracePath; yield* fs.makeDirectory(path.dirname(serverTracePath), { recursive: true }); const startupPresentation = options?.startupPresentation ?? "browser"; const isHeadlessStartup = startupPresentation === "headless"; const noBrowser = Option.getOrElse( resolveOptionPrecedence( isHeadlessStartup ? Option.some(true) : Option.none(), normalizedFlags.noBrowser, Option.fromUndefinedOr(env.noBrowser), Option.fromUndefinedOr(bootstrap?.noBrowser), ), () => mode === "desktop", ); const desktopBootstrapToken = bootstrap?.desktopBootstrapToken; const autoBootstrapProjectFromCwd = Option.getOrElse( resolveOptionPrecedence( Option.fromUndefinedOr(options?.forceAutoBootstrapProjectFromCwd), isHeadlessStartup ? Option.some(false) : Option.none(), normalizedFlags.autoBootstrapProjectFromCwd, Option.fromUndefinedOr(env.autoBootstrapProjectFromCwd), Option.fromUndefinedOr(bootstrap?.autoBootstrapProjectFromCwd), ), () => mode === "web", ); const logWebSocketEvents = Option.getOrElse( resolveOptionPrecedence( normalizedFlags.logWebSocketEvents, Option.fromUndefinedOr(env.logWebSocketEvents), Option.fromUndefinedOr(bootstrap?.logWebSocketEvents), ), () => Boolean(devUrl), ); const tailscaleServeEnabled = Option.getOrElse( resolveOptionPrecedence( normalizedFlags.tailscaleServeEnabled, Option.fromUndefinedOr(env.tailscaleServeEnabled), Option.fromUndefinedOr(bootstrap?.tailscaleServeEnabled), ), () => false, ); const tailscaleServePort = Option.getOrElse( resolveOptionPrecedence( normalizedFlags.tailscaleServePort, Option.fromUndefinedOr(env.tailscaleServePort), Option.fromUndefinedOr(bootstrap?.tailscaleServePort), ), () => 443, ); const staticDir = devUrl ? undefined : yield* resolveStaticDir(); const host = Option.getOrElse( resolveOptionPrecedence( normalizedFlags.host, Option.fromUndefinedOr(env.host), Option.fromUndefinedOr(bootstrap?.host), ), () => (mode === "desktop" ? "127.0.0.1" : undefined), ); const logLevel = Option.getOrElse(cliLogLevel, () => env.logLevel); const config: ServerConfigShape = { logLevel, traceMinLevel: env.traceMinLevel, traceTimingEnabled: env.traceTimingEnabled, traceBatchWindowMs: env.traceBatchWindowMs, traceMaxBytes: env.traceMaxBytes, traceMaxFiles: env.traceMaxFiles, otlpTracesUrl: env.otlpTracesUrl ?? bootstrap?.otlpTracesUrl ?? persistedObservabilitySettings.otlpTracesUrl, otlpMetricsUrl: env.otlpMetricsUrl ?? bootstrap?.otlpMetricsUrl ?? persistedObservabilitySettings.otlpMetricsUrl, otlpExportIntervalMs: env.otlpExportIntervalMs, otlpServiceName: env.otlpServiceName, mode, port, cwd, baseDir, ...derivedPaths, serverTracePath, host, staticDir, devUrl, noBrowser, startupPresentation, desktopBootstrapToken, autoBootstrapProjectFromCwd, logWebSocketEvents, tailscaleServeEnabled, tailscaleServePort, }; return config; }); const resolveCliAuthConfig = ( flags: CliAuthLocationFlags, cliLogLevel: Option.Option<LogLevel.LogLevel>, ) => resolveServerConfig( { mode: Option.none(), port: Option.none(), host: Option.none(), baseDir: flags.baseDir, cwd: Option.none(), devUrl: flags.devUrl ?? Option.none(), noBrowser: Option.none(), bootstrapFd: Option.none(), autoBootstrapProjectFromCwd: Option.none(), logWebSocketEvents: Option.none(), tailscaleServeEnabled: Option.none(), tailscaleServePort: Option.none(), }, cliLogLevel, ); const DurationShorthandPattern = /^(?<value>\d+)(?<unit>ms|s|m|h|d|w)$/i; const parseDurationInput = (value: string): Duration.Duration | null => { const trimmed = value.trim(); if (trimmed.length === 0) return null; const shorthand = DurationShorthandPattern.exec(trimmed); const normalizedInput = shorthand?.groups ? (() => { const amountText = shorthand.groups.value; const unitText = shorthand.groups.unit; if (typeof amountText !== "string" || typeof unitText !== "string") { return null; } const amount = Number.parseInt(amountText, 10); if (!Number.isFinite(amount)) return null; switch (unitText.toLowerCase()) { case "ms": return `${amount} millis`; case "s": return `${amount} seconds`; case "m": return `${amount} minutes`; case "h": return `${amount} hours`; case "d": return `${amount} days`; case "w": return `${amount} weeks`; default: return null; } })() : (trimmed as Duration.Input); if (normalizedInput === null) return null; const decoded = Duration.fromInput(normalizedInput as Duration.Input); return Option.isSome(decoded) ? decoded.value : null; }; const DurationFromString = Schema.String.pipe( Schema.decodeTo( Schema.Duration, SchemaTransformation.transformOrFail({ decode: (value) => { const duration = parseDurationInput(value); if (duration !== null) { return Effect.succeed(duration); } return Effect.fail( new SchemaIssue.InvalidValue(Option.some(value), { message: "Invalid duration. Use values like 5m, 1h, 30d, or 15 minutes.", }), ); }, encode: (duration) => Effect.succeed(Duration.format(duration)), }), ), );