@opencode-ai/cli-linux-arm64
Advanced tools
Sorry, the diff of this file is too big to display
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/service/restart.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"os\"\nimport { Effect } from \"effect\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { ServiceConfig } from \"../../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.service.commands.restart,\n Effect.fn(\"cli.service.restart\")(function* () {\n const options = yield* ServiceConfig.options()\n yield* Service.stop(options)\n const transport = yield* Service.ensure(options)\n process.stdout.write(transport.url + EOL)\n }),\n)\n" | ||
| ], | ||
| "mappings": ";+0BAAA,mBAAS,gBAOT,SAAe,SAAQ,aACrB,OAAS,cAAS,aAAQ,cAAS,aACnC,OAAO,QAAG,0BAAqB,OAAE,cAAU,OAAG,MAC5C,SAAM,OAAU,WAAO,OAAc,aAAQ,EAC7C,MAAO,EAAQ,KAAK,CAAO,EAC3B,IAAM,EAAY,MAAO,EAAQ,OAAO,CAAO,EAC/C,QAAQ,OAAO,MAAM,EAAU,IAAM,CAAG,EACzC,CACH", | ||
| "debugId": "F4DFDB02865C6A0B64756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["../client/src/effect/service.ts"], | ||
| "sourcesContent": [ | ||
| "import { ServiceStatus } from \"@opencode-ai/protocol/groups/health\"\nimport { Effect, FileSystem, Option, Schedule, Schema } from \"effect\"\nimport { spawn, type ChildProcess } from \"node:child_process\"\nimport { homedir } from \"node:os\"\nimport { join } from \"node:path\"\nimport type {\n DiscoverOptions,\n Endpoint,\n EnsureOptions,\n StopOptions,\n} from \"../service.js\"\n\nexport * from \"../service.js\"\n/** Contents of the local service registration file. */\nexport type Info = import(\"../service.js\").Info\n\n// Find, start, and stop the local opencode background service.\n//\n// The service daemon advertises itself through a registration file in the\n// user's state directory: url, pid, version, and the private password, with\n// 0600 permissions. That file is the complete discovery contract — reading it\n// is all a client needs to connect. The daemon's own configuration (port,\n// persisted password) is CLI-owned and never read here.\n\ntype Contender = {\n readonly child: ChildProcess\n readonly error: () => Error | undefined\n}\n\n// Read-only lookup: registration file plus health check and version gate.\n// Never spawns; escalation to ensure() is the caller's policy.\n/** Discover a healthy, compatible local service without starting one. */\nexport const discover = Effect.fn(\"service.discover\")(function* (options: DiscoverOptions = {}) {\n return (yield* discoverLocal(options))?.endpoint\n})\n\nconst discoverLocal = Effect.fnUntraced(function* (options: DiscoverOptions) {\n const found = (yield* registered(options.file)).service\n if (found?.state !== \"ready\") return undefined\n if (options.version !== undefined && found.version !== options.version) return undefined\n return found\n})\n\n// Idempotent ensure-running: reuses a healthy compatible server, replaces a\n// version-mismatched one, and otherwise spawns small contenders until a server\n// becomes discoverable. A contender is never killed merely for slow startup.\n/** Ensure a healthy, compatible local service is running. */\nexport const ensure = Effect.fn(\"service.ensure\")(function* (options: EnsureOptions = {}) {\n const contenders = new Set<Contender>()\n let announced = false\n let lastSpawn = 0\n let spawnDelay = 5_000\n let ownerHeld = false\n const announce = (reason: \"missing\" | \"version-mismatch\", previousVersion?: string) =>\n Effect.sync(() => {\n if (announced) return\n announced = true\n options.onStart?.(reason, previousVersion)\n })\n const spawnContender = Effect.gen(function* () {\n const [command, ...args] = options.command ?? [\"opencode\", \"serve\", \"--service\"]\n if (command === undefined) return yield* Effect.fail(new Error(\"Missing service command\"))\n return yield* Effect.try({\n try: () => {\n const child = spawn(command, args, { detached: true, stdio: \"ignore\" })\n let error: Error | undefined\n child.once(\"error\", (cause) => {\n error = new Error(\"Failed to start server\", { cause })\n })\n child.unref()\n return { child, error: () => error }\n },\n catch: (cause) => new Error(\"Failed to start server\", { cause }),\n })\n })\n const found = yield* Effect.gen(function* () {\n const registration = yield* registered(options.file, true)\n const info = registration.info\n const service = registration.service\n if (service !== undefined) {\n ownerHeld = false\n spawnDelay = 5_000\n const compatible = !service.legacy && (options.version === undefined || service.version === options.version)\n if (compatible && service.state === \"ready\") return Option.some(service)\n if (compatible && service.state === \"failed\") return yield* Effect.fail(new Error(\"Background service failed to start\"))\n if (compatible) return Option.none<LocalService>()\n yield* announce(\"version-mismatch\", service.version)\n yield* kill(service, options).pipe(Effect.ignore)\n lastSpawn = 0\n return Option.none<LocalService>()\n } else if (lastSpawn === 0 && info !== undefined) lastSpawn = Date.now()\n\n const failure = [...contenders].map(contenderFailure).find((error): error is Error => error !== undefined)\n if (failure !== undefined) return yield* Effect.fail(failure)\n const finished = [...contenders].filter(contenderFinished)\n if (finished.some((item) => item.child.exitCode === 0)) {\n ownerHeld = true\n spawnDelay = Math.min(spawnDelay * 2, 30_000)\n }\n finished.forEach((item) => contenders.delete(item))\n // Keep one candidate plus one lock probe so a pre-lock stall cannot block recovery.\n if (contenders.size < 2 && Date.now() - lastSpawn >= spawnDelay) {\n yield* announce(\"missing\")\n contenders.add(yield* spawnContender)\n lastSpawn = Date.now()\n }\n return Option.none<LocalService>()\n }).pipe(Effect.repeat({ until: Option.isSome, schedule: Schedule.spaced(\"1 second\") }))\n return Option.getOrThrow(found).endpoint\n})\n\nfunction contenderFailure(contender: Contender) {\n const error = contender.error()\n if (error !== undefined) return error\n if (contender.child.exitCode !== null && contender.child.exitCode !== 0)\n return new Error(`Server process exited with code ${contender.child.exitCode}`)\n if (contender.child.signalCode !== null)\n return new Error(`Server process terminated by ${contender.child.signalCode}`)\n return undefined\n}\n\nfunction contenderFinished(contender: Contender) {\n return contender.error() !== undefined || contender.child.exitCode !== null || contender.child.signalCode !== null\n}\n\n/** Stop the registered local service. */\nexport const stop = Effect.fn(\"service.stop\")(function* (options: StopOptions = {}) {\n const existing = yield* find(options)\n if (existing !== undefined) yield* kill(existing, options)\n})\n\nfunction fallback() {\n const state = process.env[\"XDG_STATE_HOME\"] ?? join(homedir(), \".local\", \"state\")\n return join(state, \"opencode\", \"service.json\")\n}\n\n/** Create HTTP authentication headers for a service endpoint. */\nexport function headers(endpoint: Endpoint) {\n if (endpoint.auth === undefined) return undefined\n return { authorization: \"Basic \" + btoa(endpoint.auth.username + \":\" + endpoint.auth.password) }\n}\n\n/** Schema for the local service registration file. */\nexport const Info = Schema.Struct({\n id: Schema.optional(Schema.String),\n version: Schema.optional(Schema.String),\n url: Schema.String,\n pid: Schema.Int.check(Schema.isGreaterThan(0)),\n password: Schema.optional(Schema.String),\n})\n\nconst decode = Schema.decodeUnknownEffect(Schema.fromJsonString(Info))\nconst decodeHealth = Schema.decodeUnknownOption(ServiceStatus.Health)\nconst decodeLegacyHealth = Schema.decodeUnknownOption(Schema.Struct({ healthy: Schema.Literal(true) }))\n\n// A missing or corrupt file means no valid info; callers treat both\n// the same (the registering server self-evicts, clients rediscover).\nconst read = Effect.fnUntraced(function* (file?: string) {\n const fs = yield* FileSystem.FileSystem\n const text = yield* fs.readFileString(file ?? fallback()).pipe(Effect.option)\n if (Option.isNone(text)) return undefined\n return yield* decode(text.value).pipe(Effect.option, Effect.map(Option.getOrUndefined))\n})\n\ntype LocalService = {\n readonly info: Info\n readonly endpoint: Endpoint\n readonly version?: string\n readonly state: \"ready\" | \"waiting\" | \"failed\"\n readonly legacy: boolean\n}\n\nconst probe = Effect.fnUntraced(function* (info: Info, allowLegacy = false) {\n const endpoint = {\n url: info.url,\n auth:\n info.password === undefined\n ? undefined\n : { type: \"basic\" as const, username: \"opencode\", password: info.password },\n } satisfies Endpoint\n const response = yield* Effect.tryPromise(() =>\n fetch(new URL(\"/api/health\", info.url), {\n headers: headers(endpoint),\n signal: AbortSignal.timeout(2_000),\n }),\n ).pipe(Effect.option, Effect.map(Option.getOrUndefined))\n if (response === undefined) return undefined\n const body = yield* Effect.tryPromise(() => response.json()).pipe(Effect.option, Effect.map(Option.getOrUndefined))\n const health = decodeHealth(body)\n if (Option.isSome(health)) {\n if (health.value.pid !== info.pid) return undefined\n if (info.version !== undefined && health.value.version !== info.version) return undefined\n return {\n info,\n endpoint,\n version: health.value.version,\n state: response.ok ? \"ready\" : response.status === 500 ? \"failed\" : \"waiting\",\n legacy: false,\n } satisfies LocalService\n }\n if (\n !allowLegacy ||\n Option.isNone(decodeLegacyHealth(body)) ||\n (typeof body === \"object\" && body !== null && (\"version\" in body || \"pid\" in body))\n )\n return undefined\n return { info, endpoint, state: \"ready\", legacy: true } satisfies LocalService\n})\n\nconst registered = Effect.fnUntraced(function* (file?: string, allowLegacy = false) {\n const info = yield* read(file)\n if (info === undefined) return { info: undefined, service: undefined }\n return { info, service: yield* probe(info, allowLegacy) }\n})\n\n// Health-checked lookup without the version gate: lifecycle operations must be\n// able to see (and replace or stop) a server from a different version.\nconst find = Effect.fnUntraced(function* (options: { readonly file?: string }) {\n return (yield* registered(options.file, true)).service\n})\n\n// 50ms cadence bounded at ~5s, shared by stop escalation and each ensure\n// discovery window.\nconst poll = Schedule.spaced(\"50 millis\").pipe(Schedule.both(Schedule.recurs(100)))\n\nconst signal = (pid: number, name: NodeJS.Signals) =>\n Effect.try({ try: () => process.kill(pid, name), catch: (cause) => cause }).pipe(Effect.ignore)\n\nconst stopped = Effect.fnUntraced(function* (pid: number) {\n const running = yield* Effect.try({ try: () => process.kill(pid, 0), catch: () => false }).pipe(\n Effect.orElseSucceed(() => false),\n )\n if (!running) return true\n return yield* Effect.fail(new Error(`Server process ${pid} is still running`))\n})\n\nfunction same(left: Info, right: Info) {\n return left.id === right.id && left.version === right.version && left.url === right.url && left.pid === right.pid\n}\n\nconst kill = Effect.fnUntraced(function* (\n service: LocalService,\n options: { readonly file?: string },\n) {\n const requested = yield* requestStop(service)\n if (requested === \"rejected\") return\n if (requested === \"unsupported\") {\n // A stale registration may point at a reused PID. Authenticate again\n // immediately before the legacy signal fallback.\n const current = yield* find(options)\n if (current === undefined || !same(current.info, service.info)) return\n yield* signal(service.info.pid, \"SIGTERM\")\n }\n const done = yield* stopped(service.info.pid).pipe(Effect.retry(poll), Effect.option)\n if (Option.isSome(done)) return\n\n const latest = yield* find(options)\n if (latest === undefined || !same(latest.info, service.info)) return\n yield* signal(service.info.pid, \"SIGKILL\")\n yield* stopped(service.info.pid).pipe(Effect.retry(poll))\n})\n\nconst decodeStopResponse = Schema.decodeUnknownOption(ServiceStatus.StopResponse)\n\nconst requestStop = Effect.fnUntraced(function* (service: LocalService) {\n if (service.info.id === undefined || service.legacy) return \"unsupported\" as const\n const response = yield* Effect.tryPromise(() =>\n fetch(new URL(\"/api/service/stop\", service.info.url), {\n method: \"POST\",\n headers: { ...headers(service.endpoint), \"content-type\": \"application/json\" },\n body: JSON.stringify({ instanceID: service.info.id }),\n signal: AbortSignal.timeout(2_000),\n }),\n ).pipe(Effect.option, Effect.map(Option.getOrUndefined))\n if (response === undefined || response.status === 404 || response.status === 405) return \"unsupported\" as const\n const body = yield* Effect.tryPromise(() => response.json()).pipe(Effect.option, Effect.map(Option.getOrUndefined))\n const decoded = decodeStopResponse(body)\n if (!response.ok || Option.isNone(decoded) || !decoded.value.accepted) return \"rejected\" as const\n return \"accepted\" as const\n})\n\n/** Effect-based local service lifecycle operations. */\nexport const Service = { discover, ensure, stop, headers, Info }\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "007691B63A90C92F64756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/run.ts"], | ||
| "sourcesContent": [ | ||
| "import { Effect, Option } from \"effect\"\nimport { Commands } from \"../commands\"\nimport { Runtime } from \"../../framework/runtime\"\nimport { ServerConnection } from \"../../services/server-connection\"\n\nexport default Runtime.handler(Commands.commands.run, (input) =>\n Effect.gen(function* () {\n const { runNonInteractive } = yield* Effect.promise(() => import(\"../../mini\"))\n const separator = process.argv.indexOf(\"--\", 2)\n const server = yield* ServerConnection.resolve({\n server: Option.getOrUndefined(input.server),\n standalone: input.standalone,\n })\n yield* Effect.promise(() =>\n runNonInteractive({\n server,\n message: [...input.message, ...(separator === -1 ? [] : process.argv.slice(separator + 1))],\n continue: input.continue,\n session: Option.getOrUndefined(input.session),\n fork: input.fork,\n model: Option.getOrUndefined(input.model),\n agent: Option.getOrUndefined(input.agent),\n format: input.format,\n file: [...input.file],\n title: Option.getOrUndefined(input.title),\n thinking: input.thinking,\n auto: input.auto || input.yolo,\n }),\n )\n }),\n)\n" | ||
| ], | ||
| "mappings": ";+uCAKA,SAAe,SAAQ,aAAQ,OAAS,cAAS,SAAK,MAAC,SACrD,OAAO,SAAI,cAAU,OAAG,MACtB,SAAQ,0BAAsB,WAAO,OAAO,aAAQ,SAAa,wCAAa,OACxE,OAAY,aAAQ,UAAK,aAAQ,UAAM,MAAC,OACxC,OAAS,WAAO,OAAiB,aAAQ,MAC7C,YAAQ,OAAO,eAAe,EAAM,MAAM,EAC1C,WAAY,EAAM,UACpB,CAAC,EACD,MAAO,EAAO,QAAQ,IACpB,EAAkB,CAChB,SACA,QAAS,CAAC,GAAG,EAAM,QAAS,GAAI,IAAc,GAAK,CAAC,EAAI,QAAQ,KAAK,MAAM,EAAY,CAAC,CAAE,EAC1F,SAAU,EAAM,SAChB,QAAS,EAAO,eAAe,EAAM,OAAO,EAC5C,KAAM,EAAM,KACZ,MAAO,EAAO,eAAe,EAAM,KAAK,EACxC,MAAO,EAAO,eAAe,EAAM,KAAK,EACxC,OAAQ,EAAM,OACd,KAAM,CAAC,GAAG,EAAM,IAAI,EACpB,MAAO,EAAO,eAAe,EAAM,KAAK,EACxC,SAAU,EAAM,SAChB,KAAM,EAAM,MAAQ,EAAM,IAC5B,CAAC,CACH,EACD,CACH", | ||
| "debugId": "4FD7BD468F0220DB64756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/migrate.ts"], | ||
| "sourcesContent": [ | ||
| "import { Effect } from \"effect\"\nimport { Commands } from \"../commands\"\nimport { Runtime } from \"../../framework/runtime\"\n\nexport default Runtime.handler(Commands.commands.migrate, (_input) => Effect.log(\"No migrations to run.\"))\n" | ||
| ], | ||
| "mappings": ";+sBAIA,SAAe,SAAQ,aAAQ,OAAS,cAAS,aAAS,MAAC,SAAW,OAAO,SAAI,4BAAuB,MAAC", | ||
| "debugId": "0CDCF3045C0170C664756E2164756E21", | ||
| "names": [] | ||
| } |
Sorry, the diff of this file is too big to display
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/service/get.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"os\"\nimport { Effect, Option } from \"effect\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { ServiceConfig } from \"../../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.service.commands.get,\n Effect.fn(\"cli.service.get\")(function* (input) {\n process.stdout.write((yield* ServiceConfig.get(Option.getOrUndefined(input.key))) + EOL)\n }),\n)\n" | ||
| ], | ||
| "mappings": ";00BAAA,mBAAS,gBAMT,SAAe,SAAQ,aACrB,OAAS,cAAS,aAAQ,cAAS,SACnC,OAAO,QAAG,sBAAiB,OAAE,cAAU,MAAC,OAAO,MAC7C,aAAQ,YAAO,YAAO,WAAO,EAAc,IAAI,EAAO,eAAe,EAAM,GAAG,CAAC,GAAK,CAAG,EACxF,CACH", | ||
| "debugId": "F1F831C283E3AAE264756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["../simulation/src/backend/network.ts", "../simulation/src/backend/openai.ts", "../simulation/src/backend/simulated-provider.ts", "../simulation/src/backend/index.ts"], | ||
| "sourcesContent": [ | ||
| "import { Clock, Effect, Layer, Ref } from \"effect\"\nimport { HttpClient, HttpClientResponse, type HttpMethod } from \"effect/unstable/http\"\nimport { HttpClientError, TransportError } from \"effect/unstable/http/HttpClientError\"\nimport type { HttpClientRequest } from \"effect/unstable/http\"\nimport { SimulationProtocol } from \"../protocol\"\n\n/**\n * Simulated network.\n *\n * Replaces the `HttpClient.HttpClient` platform node in simulation mode. All\n * outbound HTTP resolves against an in-memory route table; unknown\n * destinations fail loudly with a transport error so no simulation run can\n * silently reach the real network. The scripted LLM is one registered route,\n * not a separate mechanism.\n *\n * Each acquired run owns its routes and request log.\n */\n\nexport interface Route {\n /** Return a response effect to claim the request, undefined to pass. */\n readonly match: (\n request: HttpClientRequest.HttpClientRequest,\n url: URL,\n ) => Effect.Effect<HttpClientResponse.HttpClientResponse, HttpClientError> | undefined\n}\n\nexport type LogEntry = SimulationProtocol.Backend.NetworkLogEntry\n\nconst LOG_LIMIT = 1000\n\n/** Static JSON route: exact method + origin/path match answered with a fixed body. */\nexport function json(method: HttpMethod.HttpMethod, url: string, body: unknown): Route {\n return {\n match: (request, requestUrl) => {\n if (request.method !== method) return undefined\n if (requestUrl.origin + requestUrl.pathname !== url) return undefined\n return Effect.sync(() =>\n HttpClientResponse.fromWeb(\n request,\n new Response(JSON.stringify(body), { status: 200, headers: { \"content-type\": \"application/json\" } }),\n ),\n )\n },\n }\n}\n\nexport interface Run {\n readonly client: HttpClient.HttpClient\n readonly log: () => Effect.Effect<readonly LogEntry[]>\n}\n\nexport const make = Effect.fn(\"SimulationNetwork.make\")(function* (routes: readonly Route[] = []) {\n const log = yield* Ref.make<readonly LogEntry[]>([])\n const client = HttpClient.make((request, url) =>\n Effect.gen(function* () {\n let matched: Effect.Effect<HttpClientResponse.HttpClientResponse, HttpClientError> | undefined\n for (const route of routes) {\n matched = route.match(request, url)\n if (matched) break\n }\n const entry = {\n time: yield* Clock.currentTimeMillis,\n method: request.method,\n url: url.toString(),\n matched: matched !== undefined,\n }\n yield* Ref.update(log, (entries) => [...entries, entry].slice(-LOG_LIMIT))\n if (matched) return yield* matched\n return yield* Effect.fail(\n new HttpClientError({\n reason: new TransportError({\n request,\n description: `Simulation denied unregistered network destination: ${request.method} ${url}`,\n }),\n }),\n )\n }),\n )\n return { client, log: () => Ref.get(log) } satisfies Run\n})\n\nexport const layer = (routes: readonly Route[] = []) =>\n Layer.effect(HttpClient.HttpClient, make(routes).pipe(Effect.map((run) => run.client)))\n\nexport * as SimulationNetwork from \"./network\"\n", | ||
| "import { Effect, Schema, Stream } from \"effect\"\nimport { HttpClientResponse } from \"effect/unstable/http\"\nimport { HttpClientError, TransportError } from \"effect/unstable/http/HttpClientError\"\nimport { OpenAIChatEvent, DEFAULT_BASE_URL, PATH } from \"@opencode-ai/ai/protocols/openai-chat\"\nimport { SimulationNetwork } from \"./network\"\nimport { SimulatedProvider } from \"./simulated-provider\"\n\n/**\n * Driver-answered OpenAI endpoint for the simulated network.\n *\n * Claims `POST {DEFAULT_BASE_URL}{PATH}` (the real openai-chat route\n * endpoint), invokes the simulated provider, and streams the driver's events back as\n * an OpenAI Chat SSE response terminated by `[DONE]`. Everything downstream\n * of the response bytes is the real pipeline: SSE framing, the OpenAIChat\n * event schema, the protocol state machine, and Lifecycle grammar.\n */\n\nconst encodeChunk = Schema.encodeUnknownSync(OpenAIChatEvent)\n\nconst encoder = new TextEncoder()\nconst decodeBody = Schema.decodeUnknownEffect(Schema.fromJsonString(Schema.Json))\n\n// The simulated model id is echoed back only in non-schema fields; the\n// protocol event schema ignores unknown fields, so id/object/model are\n// decorative wire realism.\ntype ProviderItem = Exclude<SimulatedProvider.ProviderResponseEvent, { readonly type: \"finish\" }>\ntype FinishReason = Extract<SimulatedProvider.ProviderResponseEvent, { readonly type: \"finish\" }>[\"reason\"]\n\nfunction chunkOf(item: ProviderItem): OpenAIChatEvent | unknown {\n if (item.type === \"textDelta\") return { choices: [{ delta: { content: item.text } }] }\n if (item.type === \"reasoningDelta\") return { choices: [{ delta: { reasoning_content: item.text } }] }\n if (item.type === \"toolCall\")\n return {\n choices: [\n {\n delta: {\n tool_calls: [\n {\n index: item.index,\n id: item.id,\n function: { name: item.name, arguments: JSON.stringify(item.input) },\n },\n ],\n },\n },\n ],\n }\n return item.chunk\n}\n\nconst finishReasonWire: Record<FinishReason, string> = {\n stop: \"stop\",\n \"tool-calls\": \"tool_calls\",\n length: \"length\",\n \"content-filter\": \"content_filter\",\n}\n\nfunction frame(payload: unknown): Uint8Array {\n return encoder.encode(`data: ${JSON.stringify(payload)}\\n\\n`)\n}\n\nfunction sseBody(\n events: Stream.Stream<SimulatedProvider.ProviderResponseEvent, SimulatedProvider.ProviderDisconnectedError>,\n): Stream.Stream<Uint8Array, SimulatedProvider.ProviderDisconnectedError> {\n return events.pipe(\n Stream.map((event) => {\n if (event.type === \"finish\")\n return frame(encodeChunk({ choices: [{ delta: {}, finish_reason: finishReasonWire[event.reason] }] }))\n if (event.type === \"raw\") return frame(event.chunk)\n return frame(encodeChunk(chunkOf(event)))\n }),\n Stream.concat(Stream.make(encoder.encode(\"data: [DONE]\\n\\n\"))),\n )\n}\n\nexport const route = (provider: SimulatedProvider.Interface): SimulationNetwork.Route => ({\n match: (request, url) => {\n if (request.method !== \"POST\") return undefined\n if (url.origin + url.pathname !== DEFAULT_BASE_URL + PATH) return undefined\n return Effect.gen(function* () {\n const body =\n request.body._tag === \"Uint8Array\"\n ? yield* decodeBody(new TextDecoder().decode(request.body.body)).pipe(\n Effect.mapError(\n (cause) =>\n new HttpClientError({\n reason: new TransportError({\n request,\n cause,\n description: \"Simulation received an invalid OpenAI request body\",\n }),\n }),\n ),\n )\n : {}\n return HttpClientResponse.fromWeb(\n request,\n new Response(Stream.toReadableStream(sseBody(provider.stream({ url: url.toString(), body }))), {\n status: 200,\n headers: { \"content-type\": \"text/event-stream\" },\n }),\n )\n })\n },\n})\n\nexport * as SimulationOpenAI from \"./openai\"\n", | ||
| "import { Cause, Context, Effect, Fiber, FiberSet, Layer, PubSub, Queue, Ref, Schema, Semaphore, Stream } from \"effect\"\nimport { SimulationControlServer } from \"../control-server\"\nimport { SimulationProtocol } from \"../protocol\"\n\nexport interface ProviderRequest {\n readonly url: string\n readonly body: unknown\n}\n\nexport type ProviderResponseEvent =\n | SimulationProtocol.Backend.Item\n | { readonly type: \"finish\"; readonly reason: SimulationProtocol.Backend.FinishReason }\n\nexport class ProviderDisconnectedError extends Schema.TaggedErrorClass<ProviderDisconnectedError>()(\n \"SimulatedProvider.ProviderDisconnectedError\",\n { message: Schema.String },\n) {}\n\nexport interface Interface {\n readonly stream: (request: ProviderRequest) => Stream.Stream<ProviderResponseEvent, ProviderDisconnectedError>\n}\n\nexport class Service extends Context.Service<Service, Interface>()(\"@opencode/simulation/SimulatedProvider\") {}\n\ninterface ProviderInvocation extends ProviderRequest {\n readonly id: string\n}\n\ninterface PendingInvocation extends ProviderInvocation {\n readonly responses: Queue.Queue<ProviderResponseEvent, ProviderDisconnectedError | Cause.Done>\n}\n\ninterface State {\n readonly counter: number\n readonly pending: ReadonlyMap<string, PendingInvocation>\n}\n\ninterface Driver {\n readonly requests: Stream.Stream<ProviderInvocation>\n readonly push: (\n id: string,\n items: readonly SimulationProtocol.Backend.Item[],\n ) => Effect.Effect<void, InvocationNotFoundError>\n readonly finish: (\n id: string,\n reason: SimulationProtocol.Backend.FinishReason,\n ) => Effect.Effect<void, InvocationNotFoundError>\n readonly disconnect: (id: string) => Effect.Effect<void, InvocationNotFoundError>\n readonly pending: () => Effect.Effect<readonly ProviderInvocation[]>\n}\n\nclass InvocationNotFoundError extends Schema.TaggedErrorClass<InvocationNotFoundError>()(\n \"SimulatedProvider.InvocationNotFoundError\",\n { id: Schema.String, message: Schema.String },\n) {}\n\nclass ControllerDisconnectedError extends Schema.TaggedErrorClass<ControllerDisconnectedError>()(\n \"SimulatedProvider.ControllerDisconnectedError\",\n { message: Schema.String },\n) {}\n\ntype ControlSocket = SimulationControlServer.Socket\n\nexport const layerDrive = (options: { readonly endpoint: string }) =>\n Layer.effect(\n Service,\n Effect.gen(function* () {\n const state = yield* Ref.make<State>({ counter: 0, pending: new Map() })\n const opened = yield* PubSub.unbounded<ProviderInvocation>()\n const lock = yield* Semaphore.make(1)\n\n const close = (invocation: PendingInvocation) =>\n Effect.gen(function* () {\n yield* Queue.shutdown(invocation.responses)\n yield* lock.withPermit(\n Ref.update(state, (current) =>\n current.pending.get(invocation.id) === invocation ? remove(current, invocation.id) : current,\n ),\n )\n })\n\n yield* Effect.addFinalizer(() =>\n Effect.gen(function* () {\n const current = yield* Ref.get(state)\n yield* Effect.forEach(current.pending.values(), (invocation) => Queue.shutdown(invocation.responses), {\n discard: true,\n })\n yield* PubSub.shutdown(opened)\n }),\n )\n\n const open = (request: ProviderRequest) =>\n lock.withPermit(\n Effect.gen(function* () {\n const current = yield* Ref.get(state)\n const id = `inv_${current.counter + 1}`\n const responses = yield* Queue.bounded<ProviderResponseEvent, ProviderDisconnectedError | Cause.Done>(256)\n const invocation: PendingInvocation = { id, ...request, responses }\n yield* Ref.set(state, {\n counter: current.counter + 1,\n pending: new Map(current.pending).set(id, invocation),\n })\n yield* PubSub.publish(opened, { id, ...request })\n return invocation\n }),\n )\n\n const requireInvocation = (id: string) =>\n Effect.gen(function* () {\n const current = yield* Ref.get(state)\n const invocation = current.pending.get(id)\n if (invocation) return invocation\n return yield* Effect.fail(\n new InvocationNotFoundError({\n id,\n message: `Simulated provider invocation not found or already finished: ${id}`,\n }),\n )\n })\n\n const remove = (current: State, id: string) => {\n const pending = new Map(current.pending)\n pending.delete(id)\n return { ...current, pending }\n }\n\n const driver: Driver = {\n requests: Stream.unwrap(\n lock.withPermit(\n Effect.gen(function* () {\n const subscription = yield* PubSub.subscribe(opened)\n const current = yield* Ref.get(state)\n const pending = Array.from(current.pending.values(), ({ id, url, body }) => ({ id, url, body }))\n return Stream.concat(Stream.fromIterable(pending), Stream.fromEffectRepeat(PubSub.take(subscription)))\n }),\n ),\n ),\n push: (id, items) =>\n Effect.gen(function* () {\n const invocation = yield* lock.withPermit(requireInvocation(id))\n yield* Queue.offerAll(invocation.responses, items)\n }),\n finish: (id, reason) =>\n Effect.gen(function* () {\n const invocation = yield* lock.withPermit(\n Effect.gen(function* () {\n const invocation = yield* requireInvocation(id)\n const current = yield* Ref.get(state)\n yield* Ref.set(state, remove(current, id))\n return invocation\n }),\n )\n yield* Queue.offer(invocation.responses, { type: \"finish\", reason })\n yield* Queue.end(invocation.responses)\n }),\n disconnect: (id) =>\n Effect.gen(function* () {\n const invocation = yield* lock.withPermit(\n Effect.gen(function* () {\n const invocation = yield* requireInvocation(id)\n const current = yield* Ref.get(state)\n yield* Ref.set(state, remove(current, id))\n return invocation\n }),\n )\n yield* Queue.fail(\n invocation.responses,\n new ProviderDisconnectedError({ message: \"Simulated model provider disconnected\" }),\n )\n }),\n pending: () =>\n lock.withPermit(\n Ref.get(state).pipe(\n Effect.map((current) => Array.from(current.pending.values(), ({ id, url, body }) => ({ id, url, body }))),\n ),\n ),\n }\n\n const fibers = yield* FiberSet.make<void, unknown>()\n const activeController = yield* Ref.make<Fiber.Fiber<void> | undefined>(undefined)\n const controllerLock = yield* Semaphore.make(1)\n yield* SimulationControlServer.start({\n endpoint: options.endpoint,\n label: \"opencode drive backend websocket\",\n data: () => ({}),\n decode: SimulationProtocol.Backend.decodeRequestEffect,\n handle: (socket, request) => handle(driver, fibers, activeController, controllerLock, socket, request),\n close: (socket) => releaseController(activeController, controllerLock, socket),\n })\n yield* Effect.sync(() => process.stderr.write(`opencode drive backend websocket: ${options.endpoint}\\n`))\n\n return Service.of({\n stream: (request) =>\n Stream.unwrap(\n Effect.acquireRelease(open(request), close).pipe(\n Effect.map((invocation) =>\n Stream.fromQueue(invocation.responses).pipe(Stream.takeUntil((event) => event.type === \"finish\")),\n ),\n ),\n ),\n })\n }),\n )\n\nfunction handle(\n driver: Driver,\n fibers: FiberSet.FiberSet<void, unknown>,\n activeController: Ref.Ref<Fiber.Fiber<void> | undefined>,\n controllerLock: Semaphore.Semaphore,\n socket: ControlSocket,\n request: SimulationProtocol.Backend.Request,\n) {\n switch (request.method) {\n case \"llm.attach\":\n return controllerLock.withPermit(\n Effect.gen(function* () {\n if (socket.data.closed)\n return yield* Effect.fail(\n new ControllerDisconnectedError({ message: \"Drive controller disconnected before attachment\" }),\n )\n const previous = yield* Ref.get(activeController)\n if (previous) yield* Fiber.interrupt(previous)\n const attachment = yield* FiberSet.run(\n fibers,\n driver.requests.pipe(\n Stream.runForEach((invocation) =>\n Effect.sync(() => {\n socket.send(JSON.stringify({ jsonrpc: \"2.0\", method: \"llm.request\", params: invocation }))\n }),\n ),\n ),\n )\n if (socket.data.closed) {\n yield* Fiber.interrupt(attachment)\n return yield* Effect.fail(\n new ControllerDisconnectedError({ message: \"Drive controller disconnected during attachment\" }),\n )\n }\n socket.data.attachment = attachment\n yield* Ref.set(activeController, attachment)\n return { attached: true }\n }),\n )\n case \"llm.chunk\":\n return driver.push(request.params.id, request.params.items).pipe(Effect.as({ ok: true }))\n case \"llm.finish\":\n return driver.finish(request.params.id, request.params.reason).pipe(Effect.as({ ok: true }))\n case \"llm.disconnect\":\n return driver.disconnect(request.params.id).pipe(Effect.as({ ok: true }))\n case \"llm.pending\":\n return driver.pending().pipe(Effect.map((invocations) => ({ invocations })))\n }\n}\n\nfunction releaseController(\n activeController: Ref.Ref<Fiber.Fiber<void> | undefined>,\n controllerLock: Semaphore.Semaphore,\n socket: ControlSocket,\n) {\n return controllerLock.withPermit(\n Effect.gen(function* () {\n const attachment = socket.data.attachment\n if (!attachment) return\n yield* Fiber.interrupt(attachment)\n yield* Ref.update(activeController, (active) => (active === attachment ? undefined : active))\n }),\n )\n}\n\nexport * as SimulatedProvider from \"./simulated-provider\"\n", | ||
| "import { LayerNode } from \"@opencode-ai/core/effect/layer-node\"\nimport { httpClient } from \"@opencode-ai/core/effect/app-node-platform\"\nimport { Config, Effect, Layer } from \"effect\"\nimport { HttpClient } from \"effect/unstable/http\"\nimport { DriveManifest } from \"../manifest\"\nimport { SimulationNetwork } from \"./network\"\nimport { SimulationOpenAI } from \"./openai\"\nimport { SimulatedProvider } from \"./simulated-provider\"\n\n/**\n * Layer replacements applied when the server is built in simulation mode.\n *\n * The server merges these into the app node build when `OPENCODE_SIMULATE`\n * is enabled, via a dynamic import so this module is never loaded eagerly.\n *\n * - Network: all outbound HTTP resolves against the simulated route table;\n * unknown destinations are denied. The driver-answered OpenAI endpoint is\n * registered here as the first route.\n *\n */\n\nexport const simulationReplacements = Effect.fn(\"Simulation.replacements\")(function* () {\n // ModelsDev dies when its catalog fetch fails, so simulation answers it with\n // an empty catalog; providers come from seeded config instead.\n const models = SimulationNetwork.json(\"GET\", \"https://models.dev/api.json\", {})\n const drive = yield* Config.string(\"OPENCODE_DRIVE\").pipe(Config.withDefault(undefined))\n if (!drive) return [[httpClient, SimulationNetwork.layer([models])]] satisfies LayerNode.Replacements\n\n const manifest = yield* DriveManifest.resolve()\n const networkLayer = Layer.effect(\n HttpClient.HttpClient,\n Effect.gen(function* () {\n const provider = yield* SimulatedProvider.Service\n const network = yield* SimulationNetwork.make([SimulationOpenAI.route(provider), models])\n return network.client\n }),\n ).pipe(\n Layer.provide(\n SimulatedProvider.layerDrive({\n endpoint: manifest.endpoints.backend,\n }),\n ),\n )\n return [[httpClient, networkLayer]] satisfies LayerNode.Replacements\n})\n\nexport * as Simulation from \"./index\"\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "2BCA89F5B276582664756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/mini/variant.shared.ts", "src/mini/session.shared.ts", "src/mini/theme.ts"], | ||
| "sourcesContent": [ | ||
| "// Model variant resolution and persistence.\n//\n// Variants are provider-specific reasoning effort levels (e.g., \"high\", \"max\").\n// Resolution priority: CLI --variant flag > saved preference > session history.\n//\n// The saved variant persists across sessions in ~/.local/state/opencode/model.json\n// so your last-used variant sticks. Cycling (ctrl+t) updates both the active\n// variant and the persisted file.\nimport path from \"path\"\nimport { FSUtil } from \"@opencode-ai/core/fs-util\"\nimport { AppNodeBuilder } from \"@opencode-ai/core/effect/app-node-builder\"\nimport { Context, Effect, Layer } from \"effect\"\nimport { LayerNode } from \"@opencode-ai/core/effect/layer-node\"\nimport { makeGlobalNode } from \"@opencode-ai/core/effect/app-node\"\nimport { makeRuntime } from \"@opencode-ai/core/effect/runtime\"\nimport { Global } from \"@opencode-ai/core/global\"\nimport { createSession, sessionVariant, type RunSession, type SessionMessages } from \"./session.shared\"\nimport type { RunInput, RunProvider } from \"./types\"\n\nconst MODEL_FILE = path.join(Global.Path.state, \"model.json\")\n\ntype ModelState = Record<string, unknown> & {\n variant?: Record<string, string | undefined>\n}\ntype VariantService = {\n readonly resolveSavedVariant: (model: RunInput[\"model\"]) => Effect.Effect<string | undefined>\n readonly saveVariant: (model: RunInput[\"model\"], variant: string | undefined) => Effect.Effect<void>\n}\ntype VariantRuntime = {\n resolveSavedVariant(model: RunInput[\"model\"]): Promise<string | undefined>\n saveVariant(model: RunInput[\"model\"], variant: string | undefined): Promise<void>\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === \"object\" && !Array.isArray(value)\n}\n\nclass Service extends Context.Service<Service, VariantService>()(\"@opencode/RunVariant\") {}\n\nfunction modelKey(provider: string, model: string): string {\n return `${provider}/${model}`\n}\n\nfunction variantKey(model: NonNullable<RunInput[\"model\"]>): string {\n return modelKey(model.providerID, model.modelID)\n}\n\nexport function modelInfo(providers: RunProvider[] | undefined, model: NonNullable<RunInput[\"model\"]>) {\n const provider = providers?.find((item) => item.id === model.providerID)\n return {\n provider: provider?.name ?? model.providerID,\n model: provider?.models[model.modelID]?.name ?? model.modelID,\n }\n}\n\nexport function formatModelLabel(\n model: NonNullable<RunInput[\"model\"]>,\n variant: string | undefined,\n providers?: RunProvider[],\n): string {\n const names = modelInfo(providers, model)\n const label = variant ? ` · ${variant}` : \"\"\n return `${names.model} · ${names.provider}${label}`\n}\n\nexport function cycleVariant(current: string | undefined, variants: string[]): string | undefined {\n if (variants.length === 0) {\n return undefined\n }\n\n if (!current) {\n return variants[0]\n }\n\n const idx = variants.indexOf(current)\n if (idx === -1 || idx === variants.length - 1) {\n return undefined\n }\n\n return variants[idx + 1]\n}\n\nexport function pickVariant(model: RunInput[\"model\"], input: RunSession | SessionMessages): string | undefined {\n return sessionVariant(Array.isArray(input) ? createSession(input) : input, model)\n}\n\nfunction fitVariant(value: string | undefined, variants: string[]): string | undefined {\n if (!value) {\n return undefined\n }\n\n if (variants.length === 0 || variants.includes(value)) {\n return value\n }\n\n return undefined\n}\n\n// Picks the active variant. CLI flag wins, then saved preference, then session\n// history. fitVariant() checks saved and session values against the available\n// variants list -- if the provider doesn't offer a variant, it drops.\nexport function resolveVariant(\n input: string | undefined,\n session: string | undefined,\n saved: string | undefined,\n variants: string[],\n): string | undefined {\n if (input !== undefined) {\n return input\n }\n\n const fallback = fitVariant(saved, variants)\n const current = fitVariant(session, variants)\n if (current !== undefined) {\n return current\n }\n\n return fallback\n}\n\nfunction state(value: unknown): ModelState {\n if (!isRecord(value)) {\n return {}\n }\n\n const variant = isRecord(value.variant)\n ? Object.fromEntries(\n Object.entries(value.variant).flatMap(([key, item]) => {\n if (typeof item !== \"string\") {\n return []\n }\n\n return [[key, item] as const]\n }),\n )\n : undefined\n\n return {\n ...value,\n variant,\n }\n}\n\nconst layer = Layer.fresh(\n Layer.effect(\n Service,\n Effect.gen(function* () {\n const file = yield* FSUtil.Service\n\n const read = Effect.fn(\"RunVariant.read\")(function* () {\n return yield* file.readJson(MODEL_FILE).pipe(\n Effect.map(state),\n Effect.catchCause(() => Effect.succeed(state(undefined))),\n )\n })\n\n const resolveSavedVariant = Effect.fn(\"RunVariant.resolveSavedVariant\")(function* (model: RunInput[\"model\"]) {\n if (!model) {\n return undefined\n }\n\n return (yield* read()).variant?.[variantKey(model)]\n })\n\n const saveVariant = Effect.fn(\"RunVariant.saveVariant\")(function* (\n model: RunInput[\"model\"],\n variant: string | undefined,\n ) {\n if (!model) {\n return\n }\n\n const current = yield* read()\n const next = {\n ...current.variant,\n }\n const key = variantKey(model)\n if (variant) {\n next[key] = variant\n }\n\n if (!variant) {\n delete next[key]\n }\n\n yield* file\n .writeJson(MODEL_FILE, {\n ...current,\n variant: next,\n })\n .pipe(Effect.orElseSucceed(() => undefined))\n })\n\n return Service.of({\n resolveSavedVariant,\n saveVariant,\n })\n }),\n ),\n)\n\nconst node = makeGlobalNode({ service: Service, layer, deps: [FSUtil.node] })\n\n/** @internal Exported for testing. */\nexport function createVariantRuntime(replacements?: readonly LayerNode.Replacement[]): VariantRuntime {\n const runtime = makeRuntime(Service, AppNodeBuilder.build(node, replacements))\n return {\n resolveSavedVariant: (model) => runtime.runPromise((svc) => svc.resolveSavedVariant(model)).catch(() => undefined),\n saveVariant: (model, variant) => runtime.runPromise((svc) => svc.saveVariant(model, variant)).catch(() => {}),\n }\n}\n\nconst runtime = createVariantRuntime()\n\nexport async function resolveSavedVariant(model: RunInput[\"model\"]): Promise<string | undefined> {\n return runtime.resolveSavedVariant(model)\n}\n\nexport function saveVariant(model: RunInput[\"model\"], variant: string | undefined): void {\n void runtime.saveVariant(model, variant)\n}\n", | ||
| "import type { SessionMessageInfo, SessionMessageUser } from \"@opencode-ai/client/promise\"\nimport { promptCopy, promptSame } from \"./prompt.shared\"\nimport type { RunInput, RunPrompt } from \"./types\"\n\nconst LIMIT = 200\n\nexport type SessionMessages = SessionMessageInfo[]\n\ntype Turn = {\n prompt: RunPrompt\n provider: string | undefined\n model: string | undefined\n variant: string | undefined\n}\n\nexport type RunSession = {\n first: boolean\n turns: Turn[]\n model?: NonNullable<RunInput[\"model\"]>\n variant?: string\n}\n\nfunction messagePrompt(message: SessionMessageUser): RunPrompt {\n return {\n text: message.text,\n parts: [\n ...(message.files ?? []).map((file) => ({\n type: \"file\" as const,\n url: file.source.type === \"uri\" ? file.source.uri : `data:${file.mime};base64,${file.data}`,\n mime: file.mime,\n filename: file.name,\n source: file.mention\n ? {\n type: \"file\",\n path: file.name ?? (file.source.type === \"uri\" ? file.source.uri : \"inline attachment\"),\n text: { start: file.mention.start, end: file.mention.end, value: file.mention.text },\n }\n : undefined,\n })),\n ...(message.agents ?? []).map((agent) => ({\n type: \"agent\" as const,\n name: agent.name,\n source: agent.mention\n ? { start: agent.mention.start, end: agent.mention.end, value: agent.mention.text }\n : undefined,\n })),\n ],\n }\n}\n\nexport function createSession(messages: SessionMessages): RunSession {\n return {\n first: messages.length === 0,\n turns: messages.flatMap((message) =>\n message.type === \"user\"\n ? [{ prompt: messagePrompt(message), provider: undefined, model: undefined, variant: undefined }]\n : [],\n ),\n }\n}\n\nexport async function resolveCurrentSession(\n sdk: RunInput[\"sdk\"],\n sessionID: string,\n limit = LIMIT,\n): Promise<RunSession> {\n const [response, session] = await Promise.all([\n sdk.message.list({ sessionID, limit, order: \"desc\" }),\n sdk.session.get({ sessionID }),\n ])\n const current = createSession(response.data.toReversed())\n return {\n ...current,\n turns: current.turns.map((turn) => ({\n ...turn,\n provider: session.model?.providerID,\n model: session.model?.id,\n variant: session.model?.variant,\n })),\n ...(session.model && {\n model: { providerID: session.model.providerID, modelID: session.model.id },\n variant: session.model.variant,\n }),\n }\n}\n\nexport function sessionHistory(session: RunSession, limit = LIMIT): RunPrompt[] {\n return session.turns\n .map((turn) => turn.prompt)\n .filter((prompt) => prompt.text.trim())\n .filter((prompt, index, prompts) => index === 0 || !promptSame(prompts[index - 1], prompt))\n .map(promptCopy)\n .slice(-limit)\n}\n\nexport function sessionVariant(session: RunSession, model: RunInput[\"model\"]): string | undefined {\n if (!model) return\n if (session.model?.providerID === model.providerID && session.model.modelID === model.modelID) return session.variant\n\n return session.turns.findLast((turn) => turn.provider === model.providerID && turn.model === model.modelID)?.variant\n}\n", | ||
| "// Theme resolution for direct interactive mode.\n//\n// Derives scrollback and footer colors from the terminal's actual palette.\n// resolveRunTheme() queries the renderer for the terminal's palette,\n// detects dark/light mode, builds a small system theme locally, and maps it to\n// the run footer + scrollback color model. Falls back to a hardcoded dark-mode\n// palette if detection fails.\nimport { RGBA, SyntaxStyle, type CliRenderer, type ColorInput, type TerminalColors } from \"@opentui/core\"\nimport type { TuiThemeCurrent } from \"@opencode-ai/plugin/tui\"\nimport type { EntryKind } from \"./types\"\n\ntype Tone = {\n body: ColorInput\n start?: ColorInput\n}\n\nexport type RunEntryTheme = Record<EntryKind, Tone>\n\nexport type RunSplashTheme = {\n left: ColorInput\n right: ColorInput\n leftShadow: ColorInput\n rightShadow: ColorInput\n}\n\nexport type RunFooterTheme = {\n highlight: ColorInput\n selected: ColorInput\n selectedText: ColorInput\n warning: ColorInput\n success: ColorInput\n error: ColorInput\n muted: ColorInput\n text: ColorInput\n status: ColorInput\n statusAccent: ColorInput\n shade: ColorInput\n surface: ColorInput\n pane: ColorInput\n border: ColorInput\n line: ColorInput\n}\n\nexport type RunBlockTheme = {\n highlight: ColorInput\n warning: ColorInput\n text: ColorInput\n muted: ColorInput\n syntax?: SyntaxStyle\n diffAdded: ColorInput\n diffRemoved: ColorInput\n diffAddedBg: ColorInput\n diffRemovedBg: ColorInput\n diffContextBg: ColorInput\n diffHighlightAdded: ColorInput\n diffHighlightRemoved: ColorInput\n diffLineNumber: ColorInput\n diffAddedLineNumberBg: ColorInput\n diffRemovedLineNumberBg: ColorInput\n}\n\nexport type RunTheme = {\n background: ColorInput\n footer: RunFooterTheme\n entry: RunEntryTheme\n splash: RunSplashTheme\n block: RunBlockTheme\n}\n\ntype ThemeColor = Exclude<keyof TuiThemeCurrent, \"thinkingOpacity\">\ntype HexColor = `#${string}`\ntype RefName = string\ntype Variant = {\n dark: HexColor | RefName\n light: HexColor | RefName\n}\ntype ColorValue = HexColor | RefName | Variant | RGBA | number\ntype ThemeJson = {\n defs?: Record<string, HexColor | RefName>\n theme: Omit<Record<ThemeColor, ColorValue>, \"selectedListItemText\" | \"backgroundMenu\"> & {\n selectedListItemText?: ColorValue\n backgroundMenu?: ColorValue\n thinkingOpacity?: number\n }\n}\n\ntype SharedSyntaxTheme = TuiThemeCurrent & {\n _hasSelectedListItemText: boolean\n}\n\nexport const transparent = RGBA.fromValues(0, 0, 0, 0)\n\nfunction alpha(color: RGBA, value: number): RGBA {\n return RGBA.fromValues(color.r, color.g, color.b, Math.max(0, Math.min(1, value)))\n}\n\nfunction rgba(hex: string, value?: number): RGBA {\n const color = RGBA.fromHex(hex)\n return value === undefined ? color : alpha(color, value)\n}\n\nfunction mode(bg: RGBA): \"dark\" | \"light\" {\n return luminance(bg) > 0.5 ? \"light\" : \"dark\"\n}\n\nfunction luminance(color: RGBA): number {\n return 0.299 * color.r + 0.587 * color.g + 0.114 * color.b\n}\n\nfunction fade(color: RGBA, base: RGBA, fallback: number, scale: number, limit: number): RGBA {\n if (color.a === 0) {\n return RGBA.fromValues(color.r, color.g, color.b, Math.max(0, Math.min(1, fallback)))\n }\n\n const target = Math.min(limit, color.a * scale)\n const mix = Math.min(1, target / color.a)\n\n return RGBA.fromValues(\n base.r + (color.r - base.r) * mix,\n base.g + (color.g - base.g) * mix,\n base.b + (color.b - base.b) * mix,\n color.a,\n )\n}\n\nfunction ansiToRgba(code: number): RGBA {\n if (code < 16) {\n const ansi = [\n \"#000000\",\n \"#800000\",\n \"#008000\",\n \"#808000\",\n \"#000080\",\n \"#800080\",\n \"#008080\",\n \"#c0c0c0\",\n \"#808080\",\n \"#ff0000\",\n \"#00ff00\",\n \"#ffff00\",\n \"#0000ff\",\n \"#ff00ff\",\n \"#00ffff\",\n \"#ffffff\",\n ]\n return RGBA.fromHex(ansi[code] ?? \"#000000\")\n }\n\n if (code < 232) {\n const index = code - 16\n const b = index % 6\n const g = Math.floor(index / 6) % 6\n const r = Math.floor(index / 36)\n const value = (x: number) => (x === 0 ? 0 : x * 40 + 55)\n return RGBA.fromInts(value(r), value(g), value(b))\n }\n\n if (code < 256) {\n const gray = (code - 232) * 10 + 8\n return RGBA.fromInts(gray, gray, gray)\n }\n\n return RGBA.fromInts(0, 0, 0)\n}\n\nfunction tint(base: RGBA, overlay: RGBA, value: number): RGBA {\n return RGBA.fromInts(\n Math.round((base.r + (overlay.r - base.r) * value) * 255),\n Math.round((base.g + (overlay.g - base.g) * value) * 255),\n Math.round((base.b + (overlay.b - base.b) * value) * 255),\n )\n}\n\nfunction chroma(color: RGBA) {\n return Math.max(color.r, color.g, color.b) - Math.min(color.r, color.g, color.b)\n}\n\nfunction indexedPalette(colors: TerminalColors, size: number = Math.max(colors.palette.length, 16)): RGBA[] {\n return Array.from({ length: size }, (_, index) => {\n const value = colors.palette[index]\n return RGBA.fromIndex(index, value ? RGBA.fromHex(value) : ansiToRgba(index))\n })\n}\n\nfunction srgbToLinear(value: number): number {\n if (value <= 0.04045) {\n return value / 12.92\n }\n\n return ((value + 0.055) / 1.055) ** 2.4\n}\n\nfunction oklab(color: RGBA) {\n const r = srgbToLinear(color.r)\n const g = srgbToLinear(color.g)\n const b = srgbToLinear(color.b)\n\n const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b)\n const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b)\n const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b)\n\n return {\n l: 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,\n a: 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,\n b: 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s,\n }\n}\n\nfunction nearestIndexed(indexed: RGBA[], rgba: RGBA): RGBA {\n const target = oklab(rgba)\n const hit = indexed.reduce(\n (best, item) => {\n const sample = oklab(item)\n const dl = sample.l - target.l\n const da = sample.a - target.a\n const db = sample.b - target.b\n const dist = dl * dl * 2 + da * da + db * db\n if (dist >= best.dist) return best\n return {\n dist,\n item,\n }\n },\n {\n dist: Number.POSITIVE_INFINITY,\n item: indexed[0]!,\n },\n )\n\n return RGBA.clone(hit.item)\n}\n\nfunction paletteColor(colors: TerminalColors, index: number): RGBA {\n const value = colors.palette[index]\n return value ? RGBA.fromHex(value) : ansiToRgba(index)\n}\n\nfunction splashShadow(indexed: RGBA[], base: RGBA, overlay: RGBA, value: number): RGBA {\n const mixed = tint(base, overlay, value)\n return nearestIndexed(indexed, mixed)\n}\n\nexport function resolveTheme(theme: ThemeJson, pick: \"dark\" | \"light\"): TuiThemeCurrent {\n const defs = theme.defs ?? {}\n\n const resolveColor = (value: ColorValue, chain: string[] = []): RGBA => {\n if (value instanceof RGBA) return value\n\n if (typeof value === \"number\") {\n return RGBA.fromIndex(value, ansiToRgba(value))\n }\n\n if (typeof value !== \"string\") {\n return resolveColor(value[pick], chain)\n }\n\n if (value === \"transparent\" || value === \"none\") {\n return RGBA.fromInts(0, 0, 0, 0)\n }\n\n if (value.startsWith(\"#\")) {\n return RGBA.fromHex(value)\n }\n\n if (chain.includes(value)) {\n throw new Error(`Circular color reference: ${[...chain, value].join(\" -> \")}`)\n }\n\n const next = defs[value] ?? theme.theme[value as ThemeColor]\n if (next === undefined) {\n throw new Error(`Color reference \"${value}\" not found in defs or theme`)\n }\n\n return resolveColor(next, [...chain, value])\n }\n\n const resolved = Object.fromEntries(\n Object.entries(theme.theme)\n .filter(([key]) => key !== \"selectedListItemText\" && key !== \"backgroundMenu\" && key !== \"thinkingOpacity\")\n .map(([key, value]) => [key, resolveColor(value as ColorValue)]),\n ) as Partial<Record<ThemeColor, RGBA>>\n\n return {\n ...(resolved as Record<ThemeColor, RGBA>),\n selectedListItemText:\n theme.theme.selectedListItemText === undefined\n ? resolved.background!\n : resolveColor(theme.theme.selectedListItemText),\n backgroundMenu:\n theme.theme.backgroundMenu === undefined ? resolved.backgroundElement! : resolveColor(theme.theme.backgroundMenu),\n thinkingOpacity: theme.theme.thinkingOpacity ?? 0.6,\n }\n}\n\nfunction generateGrayScale(bg: RGBA, isDark: boolean, map: (rgba: RGBA) => RGBA): Record<number, RGBA> {\n const r = bg.r * 255\n const g = bg.g * 255\n const b = bg.b * 255\n const lum = 0.299 * r + 0.587 * g + 0.114 * b\n const cast = 0.25 * (1 - chroma(bg)) ** 2\n\n const gray = (level: number) => {\n const factor = level / 12\n\n if (isDark && lum < 10) {\n const value = Math.floor(factor * 0.4 * 255)\n return map(RGBA.fromInts(value, value, value))\n }\n\n if (!isDark && lum > 245) {\n const value = Math.floor(255 - factor * 0.4 * 255)\n return map(RGBA.fromInts(value, value, value))\n }\n\n const value = isDark ? lum + (255 - lum) * factor * 0.4 : lum * (1 - factor * 0.4)\n const tone = RGBA.fromInts(Math.floor(value), Math.floor(value), Math.floor(value))\n if (cast === 0) return map(tone)\n\n const ratio = lum === 0 ? 0 : value / lum\n return map(\n tint(\n tone,\n RGBA.fromInts(\n Math.floor(Math.max(0, Math.min(r * ratio, 255))),\n Math.floor(Math.max(0, Math.min(g * ratio, 255))),\n Math.floor(Math.max(0, Math.min(b * ratio, 255))),\n ),\n cast,\n ),\n )\n }\n\n return Object.fromEntries(Array.from({ length: 12 }, (_, index) => [index + 1, gray(index + 1)]))\n}\n\nfunction generateMutedTextColor(bg: RGBA, isDark: boolean, map: (rgba: RGBA) => RGBA): RGBA {\n const lum = 0.299 * bg.r * 255 + 0.587 * bg.g * 255 + 0.114 * bg.b * 255\n const gray = isDark\n ? lum < 10\n ? 180\n : Math.min(Math.floor(160 + lum * 0.3), 200)\n : lum > 245\n ? 75\n : Math.max(Math.floor(100 - (255 - lum) * 0.2), 60)\n\n return map(RGBA.fromInts(gray, gray, gray))\n}\n\nexport function generateSystem(colors: TerminalColors, pick: \"dark\" | \"light\"): ThemeJson {\n const bg_snapshot = RGBA.fromHex(colors.defaultBackground ?? colors.palette[0]!)\n const fg_snapshot = RGBA.fromHex(colors.defaultForeground ?? colors.palette[7]!)\n const bg = RGBA.defaultBackground(bg_snapshot)\n const fg = RGBA.defaultForeground(fg_snapshot)\n const isDark = pick === \"dark\"\n\n const color = (index: number) => paletteColor(colors, index)\n\n const grays = generateGrayScale(bg_snapshot, isDark, (rgba) => rgba)\n const textMuted = generateMutedTextColor(bg_snapshot, isDark, (rgba) => rgba)\n\n const ansi = {\n red: color(1),\n green: color(2),\n yellow: color(3),\n blue: color(4),\n magenta: color(5),\n cyan: color(6),\n red_bright: color(9),\n green_bright: color(10),\n }\n\n const diff_alpha = isDark ? 0.22 : 0.14\n const diff_context_bg = grays[2]\n const primary = ansi.cyan\n const secondary = ansi.magenta\n\n return {\n theme: {\n primary,\n secondary,\n accent: primary,\n error: ansi.red,\n warning: ansi.yellow,\n success: ansi.green,\n info: ansi.cyan,\n text: fg,\n textMuted,\n selectedListItemText: bg,\n background: alpha(bg, 0),\n backgroundPanel: grays[2],\n backgroundElement: grays[3],\n backgroundMenu: grays[3],\n borderSubtle: grays[6],\n border: grays[7],\n borderActive: grays[8],\n diffAdded: ansi.green,\n diffRemoved: ansi.red,\n diffContext: grays[7],\n diffHunkHeader: grays[7],\n diffHighlightAdded: ansi.green_bright,\n diffHighlightRemoved: ansi.red_bright,\n diffAddedBg: tint(bg_snapshot, ansi.green, diff_alpha),\n diffRemovedBg: tint(bg_snapshot, ansi.red, diff_alpha),\n diffContextBg: diff_context_bg,\n diffLineNumber: textMuted,\n diffAddedLineNumberBg: tint(diff_context_bg, ansi.green, diff_alpha),\n diffRemovedLineNumberBg: tint(diff_context_bg, ansi.red, diff_alpha),\n markdownText: fg,\n markdownHeading: fg,\n markdownLink: ansi.blue,\n markdownLinkText: ansi.cyan,\n markdownCode: ansi.green,\n markdownBlockQuote: ansi.yellow,\n markdownEmph: ansi.yellow,\n markdownStrong: fg,\n markdownHorizontalRule: grays[7],\n markdownListItem: ansi.blue,\n markdownListEnumeration: ansi.cyan,\n markdownImage: ansi.blue,\n markdownImageText: ansi.cyan,\n markdownCodeBlock: fg,\n syntaxComment: textMuted,\n syntaxKeyword: ansi.magenta,\n syntaxFunction: ansi.blue,\n syntaxVariable: fg,\n syntaxString: ansi.green,\n syntaxNumber: ansi.yellow,\n syntaxType: ansi.cyan,\n syntaxOperator: ansi.cyan,\n syntaxPunctuation: fg,\n },\n }\n}\n\nfunction quantizeColor(indexed: RGBA[], rgba: RGBA): RGBA {\n if (rgba.a === 0 || rgba.intent === \"default\" || rgba.intent === \"indexed\") {\n return RGBA.clone(rgba)\n }\n\n return nearestIndexed(indexed, rgba)\n}\n\nfunction quantizeTheme(theme: TuiThemeCurrent, indexed: RGBA[]): TuiThemeCurrent {\n const resolved = Object.fromEntries(\n Object.entries(theme)\n .filter(([key]) => key !== \"thinkingOpacity\")\n .map(([key, value]) => [key, quantizeColor(indexed, value as RGBA)]),\n ) as Partial<Record<ThemeColor, RGBA>>\n\n return {\n ...(resolved as Record<ThemeColor, RGBA>),\n thinkingOpacity: theme.thinkingOpacity,\n }\n}\n\nfunction splashTheme(theme: TuiThemeCurrent, indexed: RGBA[]): RunSplashTheme {\n const left = nearestIndexed(indexed, theme.textMuted)\n const right = nearestIndexed(indexed, theme.text)\n return {\n left,\n right,\n leftShadow: splashShadow(indexed, theme.background, left, 0.14),\n rightShadow: splashShadow(indexed, theme.background, right, 0.14),\n }\n}\n\nfunction map(\n footerTheme: TuiThemeCurrent,\n scrollbackTheme: TuiThemeCurrent,\n splash: RunSplashTheme,\n syntax?: SyntaxStyle,\n): RunTheme {\n const footerBackground = alpha(footerTheme.background, 1)\n const footerMode = mode(footerBackground)\n const shade = fade(footerTheme.backgroundMenu, footerTheme.background, 0.12, 0.56, 0.72)\n const surface = fade(footerTheme.backgroundMenu, footerTheme.background, 0.18, 0.76, 0.9)\n const line = fade(footerTheme.backgroundMenu, footerTheme.background, 0.24, 0.9, 0.98)\n const statusBase = tint(footerBackground, rgba(\"#000000\"), footerMode === \"dark\" ? 0.12 : 0.06)\n const statusAccentBase =\n footerMode === \"dark\" ? tint(footerBackground, rgba(\"#ffffff\"), 0.06) : tint(statusBase, rgba(\"#000000\"), 0.04)\n const collapsedStatus = footerMode === \"dark\" && luminance(statusBase) <= 0.04\n // Pure-black backgrounds need a slight lift or the row disappears into the terminal background.\n const status = collapsedStatus ? tint(statusBase, statusAccentBase, 0.7) : statusBase\n const statusAccent = collapsedStatus ? tint(status, rgba(\"#ffffff\"), 0.06) : statusAccentBase\n\n return {\n background: footerTheme.background,\n footer: {\n highlight: footerTheme.primary,\n selected: footerTheme.backgroundElement,\n selectedText: footerTheme.selectedListItemText,\n warning: footerTheme.warning,\n success: footerTheme.success,\n error: footerTheme.error,\n muted: footerTheme.textMuted,\n text: footerTheme.text,\n status,\n statusAccent,\n shade,\n surface,\n pane: footerTheme.backgroundMenu,\n border: footerTheme.border,\n line,\n },\n entry: {\n system: {\n body: scrollbackTheme.textMuted,\n },\n user: {\n body: scrollbackTheme.primary,\n },\n assistant: {\n body: scrollbackTheme.text,\n },\n reasoning: {\n body: scrollbackTheme.textMuted,\n },\n tool: {\n body: scrollbackTheme.text,\n start: scrollbackTheme.textMuted,\n },\n error: {\n body: scrollbackTheme.error,\n },\n },\n splash,\n block: {\n highlight: scrollbackTheme.primary,\n warning: scrollbackTheme.warning,\n text: scrollbackTheme.text,\n muted: scrollbackTheme.textMuted,\n syntax,\n diffAdded: scrollbackTheme.diffAdded,\n diffRemoved: scrollbackTheme.diffRemoved,\n diffAddedBg: transparent,\n diffRemovedBg: transparent,\n diffContextBg: transparent,\n diffHighlightAdded: scrollbackTheme.diffHighlightAdded,\n diffHighlightRemoved: scrollbackTheme.diffHighlightRemoved,\n diffLineNumber: scrollbackTheme.diffLineNumber,\n diffAddedLineNumberBg: scrollbackTheme.diffAddedLineNumberBg,\n diffRemovedLineNumberBg: scrollbackTheme.diffRemovedLineNumberBg,\n },\n }\n}\n\nconst seed = {\n highlight: RGBA.fromIndex(6, rgba(\"#38bdf8\")),\n muted: RGBA.fromIndex(8, rgba(\"#64748b\")),\n text: RGBA.defaultForeground(rgba(\"#f8fafc\")),\n panel: rgba(\"#0f172a\"),\n success: RGBA.fromIndex(2, rgba(\"#22c55e\")),\n warning: RGBA.fromIndex(3, rgba(\"#f59e0b\")),\n error: RGBA.fromIndex(1, rgba(\"#ef4444\")),\n}\n\nfunction tone(body: ColorInput, start?: ColorInput): Tone {\n return {\n body,\n start,\n }\n}\n\nconst fallbackSplashIndexed = Array.from({ length: 256 }, (_, index) => RGBA.fromIndex(index))\nconst fallbackSplashLeft = RGBA.fromIndex(67)\nconst fallbackSplashRight = RGBA.fromIndex(110)\n\nexport const RUN_THEME_FALLBACK: RunTheme = {\n background: RGBA.fromValues(0, 0, 0, 0),\n footer: {\n highlight: seed.highlight,\n selected: seed.text,\n selectedText: seed.panel,\n warning: seed.warning,\n success: seed.success,\n error: seed.error,\n muted: seed.muted,\n text: seed.text,\n status: tint(seed.panel, rgba(\"#000000\"), 0.12),\n statusAccent: tint(seed.panel, rgba(\"#ffffff\"), 0.06),\n shade: alpha(seed.panel, 0.68),\n surface: alpha(seed.panel, 0.86),\n pane: seed.panel,\n border: seed.muted,\n line: alpha(seed.panel, 0.96),\n },\n entry: {\n system: tone(seed.muted),\n user: tone(seed.highlight),\n assistant: tone(seed.text),\n reasoning: tone(seed.muted),\n tool: tone(seed.text, seed.muted),\n error: tone(seed.error),\n },\n splash: {\n left: fallbackSplashLeft,\n right: fallbackSplashRight,\n leftShadow: splashShadow(fallbackSplashIndexed, RGBA.fromValues(0, 0, 0, 0), fallbackSplashLeft, 0.14),\n rightShadow: splashShadow(fallbackSplashIndexed, RGBA.fromValues(0, 0, 0, 0), fallbackSplashRight, 0.14),\n },\n block: {\n highlight: seed.highlight,\n warning: seed.warning,\n text: seed.text,\n muted: seed.muted,\n diffAdded: seed.success,\n diffRemoved: seed.error,\n diffAddedBg: alpha(seed.success, 0.18),\n diffRemovedBg: alpha(seed.error, 0.18),\n diffContextBg: alpha(seed.panel, 0.72),\n diffHighlightAdded: seed.success,\n diffHighlightRemoved: seed.error,\n diffLineNumber: seed.muted,\n diffAddedLineNumberBg: alpha(seed.success, 0.12),\n diffRemovedLineNumberBg: alpha(seed.error, 0.12),\n },\n}\n\nexport async function resolveRunTheme(renderer: CliRenderer): Promise<RunTheme> {\n try {\n const colors = await renderer.getPalette({\n size: 256,\n })\n const bg = colors.defaultBackground ?? colors.palette[0]\n if (!bg) {\n return RUN_THEME_FALLBACK\n }\n\n // Palette-only terminal reloads can leave renderer.themeMode stale, but\n // ANSI slot zero is not the terminal background when OSC 11 is absent.\n const pick = colors.defaultBackground\n ? mode(RGBA.fromHex(colors.defaultBackground))\n : (renderer.themeMode ?? mode(RGBA.fromHex(bg)))\n const footerTheme = resolveTheme(generateSystem(colors, pick), pick)\n const indexed = indexedPalette(colors, 256)\n const scrollbackTheme = quantizeTheme(footerTheme, indexed)\n const shared = await import(\"@opencode-ai/tui/context/theme\")\n const syntaxTheme: SharedSyntaxTheme = {\n ...scrollbackTheme,\n _hasSelectedListItemText: true,\n }\n const syntax = shared.generateSyntax(syntaxTheme)\n return map(footerTheme, scrollbackTheme, splashTheme(scrollbackTheme, indexed), syntax)\n } catch {\n return RUN_THEME_FALLBACK\n }\n}\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "D5EB78A2E04CBEE164756E2164756E21", | ||
| "names": [] | ||
| } |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| { | ||
| "version": 3, | ||
| "sources": ["../core/src/util/process-lock.ts", "src/server-process.ts", "src/commands/handlers/serve.ts"], | ||
| "sourcesContent": [ | ||
| "import { dlopen, read, type Pointer } from \"bun:ffi\"\nimport { closeSync, existsSync, mkdirSync, openSync } from \"node:fs\"\nimport { connect, createServer, type Server, type Socket } from \"node:net\"\nimport path from \"node:path\"\nimport { Effect, Schema } from \"effect\"\nimport { Hash } from \"./hash\"\n\nexport namespace ProcessLock {\n export class HeldError extends Schema.TaggedErrorClass<HeldError>()(\"ProcessLockHeldError\", {\n file: Schema.String,\n }) {\n override get message() {\n return `Process lock is already held: ${this.file}`\n }\n }\n\n export class SystemError extends Schema.TaggedErrorClass<SystemError>()(\"ProcessLockSystemError\", {\n file: Schema.String,\n operation: Schema.Literals([\"open\", \"acquire\"]),\n code: Schema.String,\n }) {\n override get message() {\n return `Process lock ${this.operation} failed for ${this.file}: ${this.code}`\n }\n }\n\n export type LockError = HeldError | SystemError\n\n const acquirePosix = Effect.fnUntraced(function* (file: string) {\n const fd = yield* Effect.try({\n try: () => {\n mkdirSync(path.dirname(file), { recursive: true })\n return openSync(file, \"a+\", 0o600)\n },\n catch: (cause) =>\n new SystemError({\n file,\n operation: \"open\",\n code: cause instanceof Error ? cause.message : String(cause),\n }),\n })\n const result = yield* Effect.try({\n try: () => lock(fd),\n catch: (cause) =>\n new SystemError({\n file,\n operation: \"acquire\",\n code: cause instanceof Error ? cause.message : String(cause),\n }),\n }).pipe(\n Effect.tapError(() =>\n Effect.sync(() => {\n closeSync(fd)\n }),\n ),\n )\n if (result.acquired) {\n return fd\n }\n closeSync(fd)\n return yield* result.held\n ? new HeldError({ file })\n : new SystemError({ file, operation: \"acquire\", code: String(result.code) })\n })\n\n export const acquire = Effect.fn(\"ProcessLock.acquire\")(function* (file: string) {\n if (process.platform === \"win32\") {\n yield* Effect.acquireRelease(acquireWindows(file), closeWindows)\n return\n }\n yield* Effect.acquireRelease(acquirePosix(file), (fd) =>\n Effect.sync(() => {\n closeSync(fd)\n }),\n )\n })\n}\n\ntype Result =\n | { readonly acquired: true }\n | { readonly acquired: false; readonly held: true }\n | { readonly acquired: false; readonly held: false; readonly code: number }\n\nconst LOCK_EX = 2\nconst LOCK_NB = 4\nconst DARWIN_EWOULDBLOCK = 35\nconst LINUX_EWOULDBLOCK = 11\n\nfunction lock(fd: number): Result {\n if (process.platform === \"darwin\") return lockDarwin(fd)\n if (process.platform === \"linux\") return lockLinux(fd)\n throw new Error(`Unsupported process lock platform: ${process.platform}`)\n}\n\nfunction lockDarwin(fd: number): Result {\n const library = dlopen(\"/usr/lib/libSystem.B.dylib\", {\n flock: { args: [\"i32\", \"i32\"], returns: \"i32\" },\n __error: { args: [], returns: \"ptr\" },\n })\n try {\n const result = library.symbols.flock(fd, LOCK_EX | LOCK_NB)\n const code = result === 0 ? 0 : errorCode(library.symbols.__error())\n if (result === 0) return { acquired: true }\n if (code === DARWIN_EWOULDBLOCK) return { acquired: false, held: true }\n return { acquired: false, held: false, code }\n } finally {\n library.close()\n }\n}\n\nfunction lockLinux(fd: number): Result {\n const musl = `/lib/libc.musl-${process.arch === \"arm64\" ? \"aarch64\" : \"x86_64\"}.so.1`\n const library = dlopen(existsSync(musl) ? musl : \"libc.so.6\", {\n flock: { args: [\"i32\", \"i32\"], returns: \"i32\" },\n __errno_location: { args: [], returns: \"ptr\" },\n })\n try {\n const result = library.symbols.flock(fd, LOCK_EX | LOCK_NB)\n const code = result === 0 ? 0 : errorCode(library.symbols.__errno_location())\n if (result === 0) return { acquired: true }\n if (code === LINUX_EWOULDBLOCK) return { acquired: false, held: true }\n return { acquired: false, held: false, code }\n } finally {\n library.close()\n }\n}\n\nfunction errorCode(pointer: Pointer | null) {\n if (pointer === null) throw new Error(\"Failed to read process lock error code\")\n return read.i32(pointer, 0)\n}\n\nfunction acquireWindows(file: string) {\n return Effect.callback<Server, ProcessLock.LockError>((resume) => {\n const server = createServer()\n let probe: Socket | undefined\n const pipe = `\\\\\\\\.\\\\pipe\\\\opencode-process-lock-${Hash.sha256(path.resolve(file).toLowerCase())}`\n const onError = (cause: NodeJS.ErrnoException) => {\n server.off(\"listening\", onListening)\n probe = connect(pipe)\n const onProbeError = () => {\n probe?.off(\"connect\", onConnect)\n resume(\n Effect.fail(\n new ProcessLock.SystemError({\n file,\n operation: \"acquire\",\n code: cause.code ?? cause.message,\n }),\n ),\n )\n }\n const onConnect = () => {\n probe?.off(\"error\", onProbeError)\n probe?.destroy()\n resume(Effect.fail(new ProcessLock.HeldError({ file })))\n }\n probe.once(\"connect\", onConnect)\n probe.once(\"error\", onProbeError)\n }\n const onListening = () => {\n server.off(\"error\", onError)\n resume(Effect.succeed(server))\n }\n server.once(\"error\", onError)\n server.once(\"listening\", onListening)\n server.on(\"connection\", (socket) => socket.destroy())\n server.listen(pipe)\n return Effect.sync(() => {\n probe?.destroy()\n server.close()\n })\n })\n}\n\nfunction closeWindows(server: Server) {\n return Effect.callback<void>((resume) => {\n if (!server.listening) return resume(Effect.void)\n server.close((error) => resume(error ? Effect.die(error) : Effect.void))\n })\n}\n", | ||
| "export * as ServerProcess from \"./server-process\"\n\nimport { NodeServices } from \"@effect/platform-node\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { AppNodeBuilder } from \"@opencode-ai/core/effect/app-node-builder\"\nimport { LayerNode } from \"@opencode-ai/core/effect/layer-node\"\nimport { Global } from \"@opencode-ai/core/global\"\nimport { InstallationVersion } from \"@opencode-ai/core/installation/version\"\nimport { AppProcess } from \"@opencode-ai/core/process\"\nimport { ProcessLock } from \"@opencode-ai/core/util/process-lock\"\nimport { randomBytes, randomUUID } from \"node:crypto\"\nimport path from \"node:path\"\nimport { Effect, FileSystem, Logger, Option, Redacted, Schedule, Schema } from \"effect\"\nimport { HttpServer } from \"effect/unstable/http\"\nimport { Env } from \"./env\"\nimport { ServiceConfig } from \"./services/service-config\"\nimport { Updater } from \"./services/updater\"\n\nexport type Mode = \"default\" | \"service\" | \"stdio\"\n\nexport type Options = {\n readonly mode: Mode\n readonly hostname?: string\n readonly port?: number\n}\n\nexport const run = Effect.fn(\"cli.server-process.run\")((options: Options) =>\n processEffect(options).pipe(\n Effect.provide(Updater.layer),\n Effect.provide(AppNodeBuilder.build(LayerNode.group([Global.node, AppProcess.node]))),\n Effect.provide(NodeServices.layer),\n ),\n)\n\nconst processEffect = Effect.fnUntraced(function* (options: Options) {\n if (options.mode === \"service\") yield* Effect.sync(() => process.chdir(Global.Path.home))\n return yield* Effect.scoped(\n Effect.gen(function* () {\n const serviceOptions = options.mode === \"service\" ? yield* ServiceConfig.options() : undefined\n if (serviceOptions !== undefined) {\n const acquired = yield* ProcessLock.acquire(serviceOptions.file + \".lock\").pipe(\n Effect.as(true),\n Effect.catchTag(\"ProcessLockHeldError\", () => Effect.succeed(false)),\n )\n if (!acquired) return yield* Effect.void\n if ((yield* Service.discover(serviceOptions)) !== undefined) return yield* Effect.void\n }\n const { start } = yield* Effect.promise(() => import(\"@opencode-ai/server/process\"))\n const environmentPassword = yield* Env.password\n // Keep the lease credential out of the environment inherited by tools.\n if (options.mode === \"stdio\") {\n delete process.env.OPENCODE_PASSWORD\n delete process.env.OPENCODE_SERVER_PASSWORD\n }\n const config = options.mode === \"service\" ? yield* ServiceConfig.read() : {}\n const password =\n options.mode === \"service\"\n ? yield* ServiceConfig.password()\n : environmentPassword\n ? Redacted.value(environmentPassword)\n : randomBytes(32).toString(\"base64url\")\n if (!password) return yield* Effect.fail(new Error(\"Missing server password\"))\n const instanceID = randomUUID()\n const server = yield* start({\n hostname: options.hostname ?? config.hostname ?? \"127.0.0.1\",\n port: Option.fromNullishOr(options.port ?? config.port),\n password,\n instanceID,\n service:\n serviceOptions === undefined\n ? undefined\n : { onListen: (address) => register(address, password, instanceID, serviceOptions.file) },\n }).pipe(Effect.provide(Logger.layer([], { mergeWithExisting: false })))\n const url = HttpServer.formatAddress(server.address)\n console.log(options.mode === \"stdio\" ? JSON.stringify({ url }) : `server listening on ${url}`)\n if (options.mode === \"default\" && !environmentPassword) console.log(`server password ${password}`)\n const updater = yield* Updater.Service\n yield* updater.check().pipe(Effect.schedule(Schedule.spaced(\"10 minutes\")), Effect.forkScoped)\n return yield* options.mode === \"service\"\n ? server.shutdown\n : options.mode === \"stdio\"\n ? waitForStdinClose()\n : Effect.never\n }).pipe(Effect.annotateLogs({ role: \"server\" })),\n )\n})\n\nconst infoJson = Schema.fromJsonString(Service.Info)\nconst encodeInfo = Schema.encodeEffect(infoJson)\nconst decodeInfo = Schema.decodeUnknownEffect(infoJson)\n\nconst register = Effect.fnUntraced(function* (\n address: HttpServer.Address,\n password: string,\n id: string,\n file: string,\n) {\n const fs = yield* FileSystem.FileSystem\n const temp = file + \".\" + id + \".tmp\"\n yield* fs.makeDirectory(path.dirname(file), { recursive: true })\n const info = {\n id,\n version: InstallationVersion,\n url: HttpServer.formatAddress(address),\n pid: process.pid,\n password,\n }\n const encoded = yield* encodeInfo(info)\n const publish = fs.writeFileString(temp, encoded, { mode: 0o600 }).pipe(Effect.andThen(fs.rename(temp, file)))\n yield* publish\n const current = fs.readFileString(file).pipe(\n Effect.flatMap(decodeInfo),\n Effect.orElseSucceed(() => undefined),\n )\n const assertRegistration = Effect.gen(function* () {\n const found = yield* current\n if (\n found !== undefined &&\n found.id === info.id &&\n found.version === info.version &&\n found.url === info.url &&\n found.pid === info.pid &&\n found.password === info.password\n )\n return\n yield* publish\n })\n yield* Effect.addFinalizer(() =>\n current.pipe(\n Effect.flatMap((current) => (current?.id === id ? fs.remove(file) : Effect.void)),\n Effect.ignore,\n ),\n )\n yield* assertRegistration.pipe(\n Effect.catchCause((cause) => Effect.logWarning(\"failed to reassert service registration\", { cause })),\n Effect.repeat(Schedule.spaced(\"5 seconds\")),\n Effect.forkScoped,\n )\n})\n\nfunction waitForStdinClose() {\n return Effect.callback<void>((resume) => {\n const close = () => resume(Effect.void)\n process.stdin.once(\"end\", close)\n process.stdin.once(\"close\", close)\n process.stdin.resume()\n if (process.stdin.readableEnded || process.stdin.destroyed) close()\n return Effect.sync(() => {\n process.stdin.off(\"end\", close)\n process.stdin.off(\"close\", close)\n process.stdin.pause()\n })\n })\n}\n", | ||
| "import { Effect, Option } from \"effect\"\nimport { Commands } from \"../commands\"\nimport { Runtime } from \"../../framework/runtime\"\nimport { ServerProcess } from \"../../server-process\"\n\nexport default Runtime.handler(\n Commands.commands.serve,\n Effect.fn(\"cli.serve\")(function* (input) {\n if (input.service && input.stdio) return yield* Effect.fail(new Error(\"--service and --stdio cannot be combined\"))\n return yield* ServerProcess.run({\n mode: input.service ? \"service\" : input.stdio ? \"stdio\" : \"default\",\n hostname: Option.getOrUndefined(input.hostname),\n port: Option.getOrUndefined(input.port),\n })\n }),\n)\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "2DECB21882F3EAEA64756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["../core/src/image/photon.ts"], | ||
| "sourcesContent": [ | ||
| "// @ts-ignore Bun's static file import is embedded by `bun build --compile`; some consumers also declare *.wasm.\nimport photonWasm from \"@silvia-odwyer/photon-node/photon_rs_bg.wasm\" with { type: \"file\" }\nimport { Effect } from \"effect\"\nimport path from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\nimport { FileSystem } from \"../filesystem\"\nimport { DecodeError, ResizerUnavailableError, SizeError } from \"../image\"\n\nconst JPEG_QUALITIES = [80, 85, 70, 55, 40]\n\nexport const make = Effect.gen(function* () {\n ;(globalThis as typeof globalThis & { __OPENCODE_PHOTON_WASM_PATH?: string }).__OPENCODE_PHOTON_WASM_PATH =\n path.isAbsolute(photonWasm) ? photonWasm : fileURLToPath(new URL(photonWasm, import.meta.url))\n const loadPhoton = yield* Effect.cached(\n Effect.tryPromise({\n try: () => import(\"@silvia-odwyer/photon-node\"),\n catch: () => new ResizerUnavailableError(),\n }),\n )\n return Effect.fn(\"Image.Photon.normalize\")(function* (\n resource: string,\n content: FileSystem.Content & { readonly encoding: \"base64\" },\n limits: {\n readonly autoResize: boolean\n readonly maxWidth: number\n readonly maxHeight: number\n readonly maxBase64Bytes: number\n },\n ) {\n const photon = yield* loadPhoton\n const decoded = yield* Effect.try({\n try: () => photon.PhotonImage.new_from_byteslice(Buffer.from(content.content, \"base64\")),\n catch: () => new DecodeError({ resource }),\n })\n try {\n const width = decoded.get_width()\n const height = decoded.get_height()\n const bytes = Buffer.byteLength(content.content, \"utf-8\")\n if (width <= limits.maxWidth && height <= limits.maxHeight && bytes <= limits.maxBase64Bytes) return content\n if (!limits.autoResize)\n return yield* new SizeError({\n resource,\n width,\n height,\n bytes,\n maxWidth: limits.maxWidth,\n maxHeight: limits.maxHeight,\n maxBytes: limits.maxBase64Bytes,\n })\n const scale = Math.min(1, limits.maxWidth / width, limits.maxHeight / height)\n const sizes = Array.from({ length: 32 }).reduce<Array<{ width: number; height: number }>>((acc) => {\n const previous = acc.at(-1) ?? {\n width: Math.max(1, Math.round(width * scale)),\n height: Math.max(1, Math.round(height * scale)),\n }\n const next =\n acc.length === 0\n ? previous\n : {\n width: previous.width === 1 ? 1 : Math.max(1, Math.floor(previous.width * 0.75)),\n height: previous.height === 1 ? 1 : Math.max(1, Math.floor(previous.height * 0.75)),\n }\n return acc.some((item) => item.width === next.width && item.height === next.height) ? acc : [...acc, next]\n }, [])\n for (const size of sizes) {\n const resized = photon.resize(decoded, size.width, size.height, photon.SamplingFilter.Lanczos3)\n try {\n const encoders: Array<readonly [mime: string, encode: () => Uint8Array]> = [\n [\"image/png\", () => resized.get_bytes()],\n ...JPEG_QUALITIES.map((quality) => [\"image/jpeg\", () => resized.get_bytes_jpeg(quality)] as const),\n ]\n for (const [mime, encode] of encoders) {\n const candidate = Buffer.from(encode()).toString(\"base64\")\n if (Buffer.byteLength(candidate, \"utf-8\") <= limits.maxBase64Bytes)\n return { ...content, content: candidate, encoding: \"base64\" as const, mime }\n }\n } finally {\n resized.free()\n }\n }\n return yield* new SizeError({\n resource,\n width,\n height,\n bytes,\n maxWidth: limits.maxWidth,\n maxHeight: limits.maxHeight,\n maxBytes: limits.maxBase64Bytes,\n })\n } finally {\n decoded.free()\n }\n })\n})\n" | ||
| ], | ||
| "mappings": ";yvBAGA,yBACA,6BAAS,iBAIT,SAAM,OAAiB,MAAC,QAAI,QAAI,QAAI,QAAI,OAAE,OAE7B,OAAO,OAAO,SAAI,cAAU,OAAG,MACxC,gBAA4E,0CAC5E,EAAK,WAAW,CAAU,EAAI,EAAa,EAAc,IAAI,IAAI,EAAY,YAAY,GAAG,CAAC,EAC/F,IAAM,EAAa,MAAO,EAAO,OAC/B,EAAO,WAAW,CAChB,IAAK,IAAa,yCAClB,MAAO,IAAM,IAAI,CACnB,CAAC,CACH,EACA,OAAO,EAAO,GAAG,wBAAwB,EAAE,SAAU,CACnD,EACA,EACA,EAMA,CACA,IAAM,EAAS,MAAO,EAChB,EAAU,MAAO,EAAO,IAAI,CAChC,IAAK,IAAM,EAAO,YAAY,mBAAmB,OAAO,KAAK,EAAQ,QAAS,QAAQ,CAAC,EACvF,MAAO,IAAM,IAAI,EAAY,CAAE,UAAS,CAAC,CAC3C,CAAC,EACD,GAAI,CACF,IAAM,EAAQ,EAAQ,UAAU,EAC1B,EAAS,EAAQ,WAAW,EAC5B,EAAQ,OAAO,WAAW,EAAQ,QAAS,OAAO,EACxD,GAAI,GAAS,EAAO,UAAY,GAAU,EAAO,WAAa,GAAS,EAAO,eAAgB,OAAO,EACrG,GAAI,CAAC,EAAO,WACV,OAAO,MAAO,IAAI,EAAU,CAC1B,WACA,QACA,SACA,QACA,SAAU,EAAO,SACjB,UAAW,EAAO,UAClB,SAAU,EAAO,cACnB,CAAC,EACH,IAAM,EAAQ,KAAK,IAAI,EAAG,EAAO,SAAW,EAAO,EAAO,UAAY,CAAM,EACtE,EAAQ,MAAM,KAAK,CAAE,OAAQ,EAAG,CAAC,EAAE,OAAiD,CAAC,IAAQ,CACjG,IAAM,EAAW,EAAI,GAAG,EAAE,GAAK,CAC7B,MAAO,KAAK,IAAI,EAAG,KAAK,MAAM,EAAQ,CAAK,CAAC,EAC5C,OAAQ,KAAK,IAAI,EAAG,KAAK,MAAM,EAAS,CAAK,CAAC,CAChD,EACM,EACJ,EAAI,SAAW,EACX,EACA,CACE,MAAO,EAAS,QAAU,EAAI,EAAI,KAAK,IAAI,EAAG,KAAK,MAAM,EAAS,MAAQ,IAAI,CAAC,EAC/E,OAAQ,EAAS,SAAW,EAAI,EAAI,KAAK,IAAI,EAAG,KAAK,MAAM,EAAS,OAAS,IAAI,CAAC,CACpF,EACN,OAAO,EAAI,KAAK,CAAC,IAAS,EAAK,QAAU,EAAK,OAAS,EAAK,SAAW,EAAK,MAAM,EAAI,EAAM,CAAC,GAAG,EAAK,CAAI,GACxG,CAAC,CAAC,EACL,QAAW,KAAQ,EAAO,CACxB,IAAM,EAAU,EAAO,OAAO,EAAS,EAAK,MAAO,EAAK,OAAQ,EAAO,eAAe,QAAQ,EAC9F,GAAI,CACF,IAAM,EAAqE,CACzE,CAAC,YAAa,IAAM,EAAQ,UAAU,CAAC,EACvC,GAAG,EAAe,IAAI,CAAC,IAAY,CAAC,aAAc,IAAM,EAAQ,eAAe,CAAO,CAAC,CAAU,CACnG,EACA,QAAY,EAAM,KAAW,EAAU,CACrC,IAAM,EAAY,OAAO,KAAK,EAAO,CAAC,EAAE,SAAS,QAAQ,EACzD,GAAI,OAAO,WAAW,EAAW,OAAO,GAAK,EAAO,eAClD,MAAO,IAAK,EAAS,QAAS,EAAW,SAAU,SAAmB,MAAK,UAE/E,CACA,EAAQ,KAAK,GAGjB,OAAO,MAAO,IAAI,EAAU,CAC1B,WACA,QACA,SACA,QACA,SAAU,EAAO,SACjB,UAAW,EAAO,UAClB,SAAU,EAAO,cACnB,CAAC,SACD,CACA,EAAQ,KAAK,GAEhB,EACF", | ||
| "debugId": "40613DB8D830CC1B64756E2164756E21", | ||
| "names": [] | ||
| } |
Sorry, the diff of this file is too big to display
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/service/set.ts"], | ||
| "sourcesContent": [ | ||
| "import { Effect } from \"effect\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { ServiceConfig } from \"../../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.service.commands.set,\n Effect.fn(\"cli.service.set\")(function* (input) {\n yield* ServiceConfig.set(input.key, input.value)\n }),\n)\n" | ||
| ], | ||
| "mappings": ";k0BAKA,SAAe,SAAQ,aACrB,OAAS,cAAS,aAAQ,cAAS,SACnC,OAAO,QAAG,sBAAiB,OAAE,cAAU,MAAC,OAAO,MAC7C,WAAO,OAAc,SAAI,OAAM,SAAK,OAAM,KAAK,EAChD,CACH", | ||
| "debugId": "C5CA3C33CCAFADF464756E2164756E21", | ||
| "names": [] | ||
| } |
Sorry, the diff of this file is too big to display
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/service/unset.ts"], | ||
| "sourcesContent": [ | ||
| "import { Effect } from \"effect\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { ServiceConfig } from \"../../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.service.commands.unset,\n Effect.fn(\"cli.service.unset\")(function* (input) {\n yield* ServiceConfig.unset(input.key)\n }),\n)\n" | ||
| ], | ||
| "mappings": ";k0BAKA,SAAe,SAAQ,aACrB,OAAS,cAAS,aAAQ,cAAS,WACnC,OAAO,QAAG,wBAAmB,OAAE,cAAU,MAAC,OAAO,MAC/C,WAAO,OAAc,WAAM,OAAM,QAAG,OACrC,CACH", | ||
| "debugId": "32D692CA46C9E83964756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/service/start.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"os\"\nimport { Effect } from \"effect\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { ServiceConfig } from \"../../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.service.commands.start,\n Effect.fn(\"cli.service.start\")(function* () {\n const transport = yield* Service.ensure(yield* ServiceConfig.options())\n process.stdout.write(transport.url + EOL)\n }),\n)\n" | ||
| ], | ||
| "mappings": ";+0BAAA,mBAAS,gBAOT,SAAe,SAAQ,aACrB,OAAS,cAAS,aAAQ,cAAS,WACnC,OAAO,QAAG,wBAAmB,OAAE,cAAU,OAAG,MAC1C,SAAM,OAAY,WAAO,OAAQ,YAAO,MAAO,EAAc,QAAQ,CAAC,EACtE,QAAQ,OAAO,MAAM,EAAU,IAAM,CAAG,EACzC,CACH", | ||
| "debugId": "2DBF0C40A4BDE07064756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/debug/agents.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"os\"\nimport { Effect } from \"effect\"\nimport { OpenCode } from \"@opencode-ai/client\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { ServiceConfig } from \"../../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.debug.commands.agents,\n Effect.fn(\"cli.debug.agents\")(function* () {\n const options = yield* ServiceConfig.options()\n const found = yield* Service.discover(options)\n const endpoint = found ?? (yield* Service.ensure(options))\n const client = OpenCode.make({ baseUrl: endpoint.url, headers: Service.headers(endpoint) })\n const response = yield* Effect.promise(() => client.agent.list({ location: { directory: process.cwd() } }))\n process.stdout.write(\n JSON.stringify(\n response.data.toSorted((a, b) => a.id.localeCompare(b.id)),\n null,\n 2,\n ) + EOL,\n )\n }),\n)\n" | ||
| ], | ||
| "mappings": ";83BAAA,mBAAS,gBAQT,SAAe,SAAQ,aACrB,OAAS,cAAS,WAAM,cAAS,YACjC,OAAO,QAAG,uBAAkB,OAAE,cAAU,OAAG,MACzC,SAAM,OAAU,WAAO,OAAc,aAAQ,OAEvC,GADQ,MAAO,EAAQ,SAAS,CAAO,KAClB,MAAO,EAAQ,OAAO,CAAO,GAClD,EAAS,EAAS,KAAK,CAAE,QAAS,EAAS,IAAK,QAAS,EAAQ,QAAQ,CAAQ,CAAE,CAAC,EACpF,EAAW,MAAO,EAAO,QAAQ,IAAM,EAAO,MAAM,KAAK,CAAE,SAAU,CAAE,UAAW,QAAQ,IAAI,CAAE,CAAE,CAAC,CAAC,EAC1G,QAAQ,OAAO,MACb,KAAK,UACH,EAAS,KAAK,SAAS,CAAC,EAAG,IAAM,EAAE,GAAG,cAAc,EAAE,EAAE,CAAC,EACzD,KACA,CACF,EAAI,CACN,EACD,CACH", | ||
| "debugId": "86C356217D397D6964756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/ui/timeline.tsx", "src/commands/handlers/console/login.ts"], | ||
| "sourcesContent": [ | ||
| "import { createComponent as _$createComponent } from \"@opentui/solid\";\nimport { effect as _$effect } from \"@opentui/solid\";\nimport { createTextNode as _$createTextNode } from \"@opentui/solid\";\nimport { insertNode as _$insertNode } from \"@opentui/solid\";\nimport { insert as _$insert } from \"@opentui/solid\";\nimport { setProp as _$setProp } from \"@opentui/solid\";\nimport { createElement as _$createElement } from \"@opentui/solid\";\n/** @jsxImportSource @opentui/solid */\nimport { createCliRenderer, RGBA } from \"@opentui/core\";\nimport { createScrollbackWriter, render, useKeyboard } from \"@opentui/solid\";\nimport { registerOpencodeSpinner } from \"@opencode-ai/tui/component/register-spinner\";\nimport { Show, createSignal } from \"solid-js\";\nregisterOpencodeSpinner();\nconst SPINNER_FRAMES = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\nconst IDLE_TIMEOUT = 1_000;\nconst COLORS = {\n accent: RGBA.fromIndex(6),\n error: RGBA.fromIndex(1),\n foreground: RGBA.defaultForeground(),\n muted: RGBA.fromIndex(8),\n success: RGBA.fromIndex(2)\n};\nconst ROWS = {\n intro: {\n marker: \"┌\",\n color: COLORS.muted,\n connector: true\n },\n item: {\n marker: \"●\",\n color: COLORS.accent,\n connector: true\n },\n success: {\n marker: \"◇\",\n color: COLORS.success,\n connector: true\n },\n failure: {\n marker: \"■\",\n color: COLORS.error,\n connector: false\n },\n outro: {\n marker: \"└\",\n color: COLORS.muted,\n connector: false\n }\n};\nfunction row(kind, value) {\n const style = ROWS[kind];\n return createScrollbackWriter(() => (() => {\n var _el$ = _$createElement(\"box\"),\n _el$2 = _$createElement(\"box\"),\n _el$3 = _$createElement(\"text\"),\n _el$4 = _$createElement(\"text\");\n _$insertNode(_el$, _el$2);\n _$setProp(_el$, \"width\", \"100%\");\n _$setProp(_el$, \"minHeight\", 1);\n _$setProp(_el$, \"flexDirection\", \"column\");\n _$insertNode(_el$2, _el$3);\n _$insertNode(_el$2, _el$4);\n _$setProp(_el$2, \"width\", \"100%\");\n _$setProp(_el$2, \"minHeight\", 1);\n _$setProp(_el$2, \"flexDirection\", \"row\");\n _$setProp(_el$2, \"gap\", 1);\n _$setProp(_el$3, \"flexShrink\", 0);\n _$insert(_el$3, () => style.marker);\n _$setProp(_el$4, \"wrapMode\", \"word\");\n _$insert(_el$4, value);\n _$insert(_el$, _$createComponent(Show, {\n get when() {\n return style.connector;\n },\n get children() {\n var _el$5 = _$createElement(\"text\");\n _$insertNode(_el$5, _$createTextNode(`│`));\n _$effect(_$p => _$setProp(_el$5, \"fg\", COLORS.muted, _$p));\n return _el$5;\n }\n }), null);\n _$effect(_p$ => {\n var _v$ = style.color,\n _v$2 = COLORS.foreground;\n _v$ !== _p$.e && (_p$.e = _$setProp(_el$3, \"fg\", _v$, _p$.e));\n _v$2 !== _p$.t && (_p$.t = _$setProp(_el$4, \"fg\", _v$2, _p$.t));\n return _p$;\n }, {\n e: undefined,\n t: undefined\n });\n return _el$;\n })(), {\n startOnNewLine: true,\n trailingNewline: !style.connector\n });\n}\nfunction TimelineFooter(props) {\n useKeyboard(event => {\n if (event.name !== \"escape\" && !(event.ctrl && event.name === \"c\")) return;\n event.preventDefault();\n props.cancel();\n });\n return (() => {\n var _el$7 = _$createElement(\"box\");\n _$setProp(_el$7, \"width\", \"100%\");\n _$setProp(_el$7, \"height\", 1);\n _$setProp(_el$7, \"flexDirection\", \"row\");\n _$setProp(_el$7, \"gap\", 1);\n _$insert(_el$7, _$createComponent(Show, {\n get when() {\n return props.pending();\n },\n children: text => [(() => {\n var _el$8 = _$createElement(\"spinner\");\n _$setProp(_el$8, \"frames\", SPINNER_FRAMES);\n _$setProp(_el$8, \"interval\", 80);\n _$effect(_$p => _$setProp(_el$8, \"color\", COLORS.accent, _$p));\n return _el$8;\n })(), (() => {\n var _el$9 = _$createElement(\"text\");\n _$setProp(_el$9, \"wrapMode\", \"none\");\n _$setProp(_el$9, \"truncate\", true);\n _$insert(_el$9, text);\n _$effect(_$p => _$setProp(_el$9, \"fg\", COLORS.foreground, _$p));\n return _el$9;\n })()]\n }));\n return _el$7;\n })();\n}\nfunction bounded(task) {\n return new Promise(resolve => {\n const timer = setTimeout(resolve, IDLE_TIMEOUT);\n timer.unref();\n const finish = () => {\n clearTimeout(timer);\n resolve();\n };\n void task.then(finish, finish);\n });\n}\nasync function shutdown(renderer) {\n await bounded(renderer.idle());\n try {\n renderer.externalOutputMode = \"passthrough\";\n } finally {\n try {\n renderer.screenMode = \"main-screen\";\n } finally {\n if (!renderer.isDestroyed) renderer.destroy();\n }\n }\n}\nexport async function createTimelineHost() {\n const stdout = process.stdout;\n const controller = new AbortController();\n const signals = [\"SIGINT\", \"SIGHUP\", \"SIGQUIT\"];\n const cancel = () => {\n if (!controller.signal.aborted) controller.abort();\n };\n signals.forEach(signal => process.on(signal, cancel));\n if (!stdout.isTTY || !process.stdin.isTTY) {\n let closed = false;\n let writing = false;\n let active;\n let closeTask;\n const write = async (kind, text) => {\n if (closed) throw new Error(\"timeline closed\");\n if (writing) throw new Error(\"timeline write already in progress\");\n writing = true;\n try {\n const style = kind === \"pending\" ? undefined : ROWS[kind];\n const marker = kind === \"pending\" ? \".\" : ROWS[kind].marker;\n const connector = style?.connector ? \"│\\n\" : \"\";\n active = new Promise((resolve, reject) => {\n stdout.write(`${marker} ${text}\\n${connector}`, error => error ? reject(error) : resolve());\n });\n await active;\n } finally {\n writing = false;\n active = undefined;\n }\n };\n const close = () => {\n if (closeTask) return closeTask;\n closed = true;\n closeTask = (async () => {\n await active?.catch(() => {});\n signals.forEach(signal => process.off(signal, cancel));\n })();\n return closeTask;\n };\n return {\n signal: controller.signal,\n intro: text => write(\"intro\", text),\n item: text => write(\"item\", text),\n pending: text => write(\"pending\", text),\n success: text => write(\"success\", text),\n failure: text => write(\"failure\", text),\n outro: text => write(\"outro\", text),\n close\n };\n }\n let renderer;\n try {\n // Start on a fresh row so delayed SSH cursor reports cannot make\n // split-footer overwrite the shell command.\n process.stdout.write(\"\\n\");\n renderer = await createCliRenderer({\n stdin: process.stdin,\n useMouse: false,\n autoFocus: false,\n openConsoleOnError: false,\n exitOnCtrlC: false,\n exitSignals: [],\n screenMode: \"split-footer\",\n footerHeight: 1,\n externalOutputMode: \"capture-stdout\",\n consoleMode: \"disabled\",\n clearOnShutdown: false\n });\n const activeRenderer = renderer;\n const [pending, setPending] = createSignal();\n const renderTask = render(() => _$createComponent(TimelineFooter, {\n pending: pending,\n cancel: cancel\n }), activeRenderer);\n void renderTask.catch(cancel);\n await bounded(activeRenderer.idle());\n let closed = false;\n let writing = false;\n let active;\n let closeTask;\n const write = (kind, text) => {\n if (closed) return Promise.reject(new Error(\"timeline closed\"));\n if (writing) return Promise.reject(new Error(\"timeline write already in progress\"));\n writing = true;\n active = (async () => {\n if (kind === \"pending\") {\n setPending(text);\n activeRenderer.requestRender();\n } else {\n if (kind === \"success\" || kind === \"failure\" || kind === \"outro\") setPending(undefined);\n activeRenderer.writeToScrollback(row(kind, text));\n activeRenderer.requestRender();\n }\n await bounded(activeRenderer.idle());\n })().finally(() => {\n writing = false;\n active = undefined;\n });\n return active;\n };\n const close = () => {\n if (closeTask) return closeTask;\n closed = true;\n closeTask = (async () => {\n await active?.catch(() => {});\n try {\n await shutdown(activeRenderer);\n await bounded(renderTask);\n } finally {\n signals.forEach(signal => process.off(signal, cancel));\n }\n })();\n return closeTask;\n };\n return {\n signal: controller.signal,\n intro: text => write(\"intro\", text),\n item: text => write(\"item\", text),\n pending: text => write(\"pending\", text),\n success: text => write(\"success\", text),\n failure: text => write(\"failure\", text),\n outro: text => write(\"outro\", text),\n close\n };\n } catch (error) {\n try {\n if (renderer) await shutdown(renderer);\n } finally {\n signals.forEach(signal => process.off(signal, cancel));\n }\n throw error;\n }\n}", | ||
| "import { Cause, Effect, Exit, Option } from \"effect\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { OpenCode, type OpenCodeClient } from \"@opencode-ai/client/promise\"\nimport { AppProcess } from \"@opencode-ai/core/process\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { ServiceConfig } from \"../../../services/service-config\"\nimport { createTimelineHost, type TimelineHost } from \"../../../ui/timeline\"\n\nconst integrationID = \"opencode\"\nconst location = { directory: process.cwd() }\n\nexport default Runtime.handler(\n Commands.commands.console.commands.login,\n Effect.fn(\"cli.console.login\")(function* (input) {\n const timeline = yield* Effect.acquireRelease(\n Effect.promise(() => createTimelineHost()),\n (value) => request(() => value.close()).pipe(Effect.ignore),\n )\n const exit = yield* login(timeline, Option.getOrUndefined(input.url)).pipe(\n Effect.raceFirst(AppProcess.waitForAbort(timeline.signal)),\n Effect.exit,\n )\n if (Exit.isSuccess(exit)) return\n\n const cancelled = timeline.signal.aborted\n yield* request(() => timeline.failure(cancelled ? \"Authorization cancelled\" : errorMessage(exit.cause))).pipe(\n Effect.ignore,\n )\n process.exitCode = cancelled ? 130 : 1\n }),\n)\n\nconst login = Effect.fn(\"cli.console.login.run\")(function* (timeline: TimelineHost, server?: string) {\n yield* request(() => timeline.intro(\"Log in\"))\n yield* request(() => timeline.pending(\"Connecting to OpenCode...\"))\n\n const endpoint = yield* Service.ensure(yield* ServiceConfig.options())\n const client = OpenCode.make({ baseUrl: endpoint.url, headers: Service.headers(endpoint) })\n const found = yield* request((signal) => client.integration.get({ integrationID, location }, { signal }))\n const integration = yield* required(found.data, \"OpenCode Console integration is unavailable\")\n const method = yield* required(\n integration.methods.find((candidate) => candidate.type === \"oauth\"),\n \"OpenCode Console login is unavailable\",\n )\n\n yield* request(() => timeline.pending(\"Starting authorization...\"))\n const started = yield* request((signal) =>\n client.integration.connect.oauth(\n {\n integrationID,\n methodID: method.id,\n inputs: server ? { server } : {},\n location,\n },\n { signal },\n ),\n )\n const attempt = started.data\n yield* Effect.addFinalizer(() =>\n request(() =>\n client.integration.attempt.cancel(\n { attemptID: attempt.attemptID, location },\n { signal: AbortSignal.timeout(5_000) },\n ),\n ).pipe(Effect.ignore),\n )\n if (attempt.mode !== \"auto\") yield* Effect.fail(new Error(\"OpenCode Console requires a device login\"))\n\n yield* request(() => timeline.item(`Go to: ${attempt.url}`))\n yield* request(() => timeline.item(attempt.instructions))\n yield* request(async () => {\n const { default: open } = await import(\"open\")\n await open(attempt.url)\n }).pipe(Effect.ignore)\n yield* request(() => timeline.pending(\"Waiting for authorization...\"))\n\n const status = yield* waitForConsoleLogin(client, attempt.attemptID)\n if (status.status === \"failed\") yield* Effect.fail(new Error(status.message))\n if (status.status === \"expired\") yield* Effect.fail(new Error(\"Device code expired\"))\n\n yield* request(() => timeline.success(\"Connected to OpenCode Console\"))\n yield* request(() => timeline.outro(\"Done\"))\n})\n\nconst waitForConsoleLogin = Effect.fn(\"cli.console.login.wait\")(function* (\n client: OpenCodeClient,\n attemptID: string,\n) {\n while (true) {\n const response = yield* request((signal) =>\n client.integration.attempt.status({ attemptID, location }, { signal }),\n )\n if (response.data.status !== \"pending\") return response.data\n yield* Effect.sleep(500)\n }\n})\n\nfunction request<A>(task: (signal: AbortSignal) => Promise<A>) {\n return Effect.tryPromise({\n try: task,\n catch: (cause) => cause,\n })\n}\n\nfunction required<A>(value: A | null | undefined, message: string) {\n return value === null || value === undefined ? Effect.fail(new Error(message)) : Effect.succeed(value)\n}\n\nfunction errorMessage(cause: Cause.Cause<unknown>) {\n const error = Cause.squash(cause)\n if (error instanceof Error) return error.message\n if (typeof error === \"object\" && error !== null && \"message\" in error && typeof error.message === \"string\") {\n return error.message\n }\n return String(error)\n}\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "E1A1193D9AFE5BE364756E2164756E21", | ||
| "names": [] | ||
| } |
Sorry, the diff of this file is too big to display
| { | ||
| "version": 3, | ||
| "sources": ["src/services/service-config.ts"], | ||
| "sourcesContent": [ | ||
| "import { Global } from \"@opencode-ai/core/global\"\nimport { InstallationChannel, InstallationVersion } from \"@opencode-ai/core/installation/version\"\nimport { Hash } from \"@opencode-ai/core/util/hash\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { Effect, FileSystem, Option, Schema } from \"effect\"\nimport { randomBytes } from \"crypto\"\nimport path from \"path\"\n\n// The CLI's service configuration file, plus the Service.EnsureOptions binding that\n// points the client package's service operations at this CLI: which\n// registration file (by channel), which version, and how to spawn opencode.\n\nexport const Info = Schema.Struct({\n hostname: Schema.optional(Schema.String),\n port: Schema.optional(Schema.Int.check(Schema.isGreaterThanOrEqualTo(1), Schema.isLessThanOrEqualTo(65_535))),\n password: Schema.optional(Schema.String),\n})\nexport type Info = typeof Info.Type\n\nconst keys = [\"hostname\", \"port\", \"password\"] as const\ntype Key = (typeof keys)[number]\n\nconst decodeInfo = Schema.decodeUnknownEffect(Schema.fromJsonString(Info))\nconst decodeRegistration = Schema.decodeUnknownEffect(Schema.fromJsonString(Service.Info))\n\nexport function filename(channel = InstallationChannel) {\n if (channel === \"latest\") return \"service.json\"\n if (channel === \"local\") return \"service-local.json\"\n return `service-${Hash.fast(channel)}.json`\n}\n\nexport function versionBelongsToChannel(\n version: string | undefined,\n channel = InstallationChannel,\n installedVersion = InstallationVersion,\n) {\n if (version === undefined) return false\n if (version === installedVersion) return true\n const prefix = `0.0.0-${channel}-`\n if (!version.startsWith(prefix)) return false\n return /^\\d+(?:\\.\\d+)?$/.test(version.slice(prefix.length))\n}\n\nexport const migrateRegistration = Effect.fnUntraced(function* (\n legacy: string,\n file: string,\n channel = InstallationChannel,\n installedVersion = InstallationVersion,\n) {\n if (channel === \"latest\" || channel === \"local\") return\n const fs = yield* FileSystem.FileSystem\n const text = yield* fs.readFileString(legacy).pipe(Effect.option)\n if (Option.isNone(text)) return\n const registration = yield* decodeRegistration(text.value).pipe(Effect.option)\n if (Option.isNone(registration)) return\n if (!versionBelongsToChannel(registration.value.version, channel, installedVersion)) return\n yield* fs.writeFileString(file, text.value, { flag: \"wx\", mode: 0o600 }).pipe(Effect.ignore)\n})\n\nfunction configKey(key: string): Key {\n if (key === \"hostname\" || key === \"port\" || key === \"password\") return key\n throw new Error(`Unknown service config key: ${key}`)\n}\n\nconst paths = Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem\n const global = yield* Global.Service\n const name = filename()\n const file = path.join(global.state, name)\n return {\n fs,\n file,\n legacyFile: path.join(global.state, \"service.json\"),\n configFile: path.join(global.config, name),\n }\n})\n\nexport const options = Effect.fnUntraced(function* () {\n const { file, legacyFile } = yield* paths\n yield* migrateRegistration(legacyFile, file)\n const compiled = path.basename(process.execPath).replace(/\\.exe$/, \"\") !== \"bun\"\n const entrypoint = compiled ? undefined : process.argv[1]\n if (!compiled && entrypoint === undefined) return yield* Effect.fail(new Error(\"Failed to resolve CLI entrypoint\"))\n return {\n file,\n version: InstallationVersion,\n command: [process.execPath, ...(entrypoint ? [entrypoint] : []), \"serve\", \"--service\"],\n }\n})\n\nexport const read = Effect.fn(\"cli.service-config.read\")(function* () {\n const { fs, configFile } = yield* paths\n return yield* fs.readFileString(configFile).pipe(\n Effect.flatMap(decodeInfo),\n Effect.catch(() => Effect.succeed({} as Info)),\n )\n})\n\nconst write = Effect.fn(\"cli.service-config.write\")(function* (value: Info) {\n const { fs, configFile } = yield* paths\n const temp = configFile + \".tmp\"\n yield* fs.makeDirectory(path.dirname(configFile), { recursive: true })\n yield* fs.writeFileString(temp, JSON.stringify(value, null, 2) + \"\\n\", { mode: 0o600 })\n yield* fs.rename(temp, configFile)\n})\n\nexport const password = Effect.fn(\"cli.service-config.password\")(function* (value?: string) {\n const existing = yield* read()\n if (value === undefined && existing.password) return existing.password\n const next = value ?? randomBytes(32).toString(\"base64url\")\n\n // Keep one private credential across server restarts so discovered clients\n // can reconnect without exposing a password flag or environment variable.\n yield* write({ ...existing, password: next })\n return next\n})\n\nexport const get = Effect.fn(\"cli.service-config.get\")(function* (key?: string) {\n if (key === undefined) {\n const { password: _password, ...safe } = yield* read()\n return JSON.stringify(safe, null, 2)\n }\n switch (configKey(key)) {\n case \"hostname\": {\n return (yield* read()).hostname ?? \"\"\n }\n case \"port\": {\n const port = (yield* read()).port\n return port === undefined ? \"\" : String(port)\n }\n case \"password\": {\n return yield* password()\n }\n }\n throw new Error(`Unknown service config key: ${key}`)\n})\n\nexport const set = Effect.fn(\"cli.service-config.set\")(function* (key: string, value: string) {\n switch (configKey(key)) {\n case \"hostname\": {\n yield* Service.stop(yield* options())\n yield* write({ ...(yield* read()), hostname: value })\n return\n }\n case \"port\": {\n const port = Number(value)\n if (!Number.isInteger(port) || port < 1 || port > 65_535) throw new Error(\"Port must be between 1 and 65535\")\n yield* Service.stop(yield* options())\n yield* write({ ...(yield* read()), port })\n return\n }\n case \"password\": {\n yield* Service.stop(yield* options())\n yield* password(value)\n return\n }\n }\n})\n\nexport const unset = Effect.fn(\"cli.service-config.unset\")(function* (key: string) {\n switch (configKey(key)) {\n case \"hostname\": {\n yield* Service.stop(yield* options())\n const { hostname: _hostname, ...next } = yield* read()\n yield* write(next)\n return\n }\n case \"port\": {\n yield* Service.stop(yield* options())\n const { port: _port, ...next } = yield* read()\n yield* write(next)\n return\n }\n case \"password\": {\n yield* Service.stop(yield* options())\n const { password: _password, ...next } = yield* read()\n yield* write(next)\n return\n }\n }\n})\n\nexport * as ServiceConfig from \"./service-config\"\n" | ||
| ], | ||
| "mappings": ";sdAKA,2BAAS,oBACT,yBAMO,SAAM,EAAO,EAAO,OAAO,CAChC,SAAU,EAAO,SAAS,EAAO,MAAM,EACvC,KAAM,EAAO,SAAS,EAAO,IAAI,MAAM,EAAO,uBAAuB,CAAC,EAAG,EAAO,oBAAoB,KAAM,CAAC,CAAC,EAC5G,SAAU,EAAO,SAAS,EAAO,MAAM,CACzC,CAAC,EAMD,IAAM,EAAa,EAAO,oBAAoB,EAAO,eAAe,CAAI,CAAC,EACnE,EAAqB,EAAO,oBAAoB,EAAO,eAAe,EAAQ,IAAI,CAAC,EAElF,SAAS,CAAQ,CAAC,EAAU,EAAqB,CACtD,GAAI,IAAY,SAAU,MAAO,eACjC,GAAI,IAAY,QAAS,MAAO,qBAChC,MAAO,WAAW,EAAK,KAAK,CAAO,SAG9B,SAAS,CAAuB,CACrC,EACA,EAAU,EACV,EAAmB,EACnB,CACA,GAAI,IAAY,OAAW,MAAO,GAClC,GAAI,IAAY,EAAkB,MAAO,GACzC,IAAM,EAAS,SAAS,KACxB,GAAI,CAAC,EAAQ,WAAW,CAAM,EAAG,MAAO,GACxC,MAAO,kBAAkB,KAAK,EAAQ,MAAM,EAAO,MAAM,CAAC,EAGrD,IAAM,EAAsB,EAAO,WAAW,SAAU,CAC7D,EACA,EACA,EAAU,EACV,EAAmB,EACnB,CACA,GAAI,IAAY,UAAY,IAAY,QAAS,OACjD,IAAM,EAAK,MAAO,EAAW,WACvB,EAAO,MAAO,EAAG,eAAe,CAAM,EAAE,KAAK,EAAO,MAAM,EAChE,GAAI,EAAO,OAAO,CAAI,EAAG,OACzB,IAAM,EAAe,MAAO,EAAmB,EAAK,KAAK,EAAE,KAAK,EAAO,MAAM,EAC7E,GAAI,EAAO,OAAO,CAAY,EAAG,OACjC,GAAI,CAAC,EAAwB,EAAa,MAAM,QAAS,EAAS,CAAgB,EAAG,OACrF,MAAO,EAAG,gBAAgB,EAAM,EAAK,MAAO,CAAE,KAAM,KAAM,KAAM,GAAM,CAAC,EAAE,KAAK,EAAO,MAAM,EAC5F,EAED,SAAS,CAAS,CAAC,EAAkB,CACnC,GAAI,IAAQ,YAAc,IAAQ,QAAU,IAAQ,WAAY,OAAO,EACvE,MAAU,MAAM,+BAA+B,GAAK,EAGtD,IAAM,EAAQ,EAAO,IAAI,SAAU,EAAG,CACpC,IAAM,EAAK,MAAO,EAAW,WACvB,EAAS,MAAO,EAAO,QACvB,EAAO,EAAS,EAChB,EAAO,EAAK,KAAK,EAAO,MAAO,CAAI,EACzC,MAAO,CACL,KACA,OACA,WAAY,EAAK,KAAK,EAAO,MAAO,cAAc,EAClD,WAAY,EAAK,KAAK,EAAO,OAAQ,CAAI,CAC3C,EACD,EAEY,EAAU,EAAO,WAAW,SAAU,EAAG,CACpD,IAAQ,OAAM,cAAe,MAAO,EACpC,MAAO,EAAoB,EAAY,CAAI,EAC3C,IAAM,EAAW,EAAK,SAAS,QAAQ,QAAQ,EAAE,QAAQ,SAAU,EAAE,IAAM,MACrE,EAAa,EAAW,OAAY,QAAQ,KAAK,GACvD,GAAI,CAAC,GAAY,IAAe,OAAW,OAAO,MAAO,EAAO,KAAS,MAAM,kCAAkC,CAAC,EAClH,MAAO,CACL,OACA,QAAS,EACT,QAAS,CAAC,QAAQ,SAAU,GAAI,EAAa,CAAC,CAAU,EAAI,CAAC,EAAI,QAAS,WAAW,CACvF,EACD,EAEY,EAAO,EAAO,GAAG,yBAAyB,EAAE,SAAU,EAAG,CACpE,IAAQ,KAAI,cAAe,MAAO,EAClC,OAAO,MAAO,EAAG,eAAe,CAAU,EAAE,KAC1C,EAAO,QAAQ,CAAU,EACzB,EAAO,MAAM,IAAM,EAAO,QAAQ,CAAC,CAAS,CAAC,CAC/C,EACD,EAEK,EAAQ,EAAO,GAAG,0BAA0B,EAAE,SAAU,CAAC,EAAa,CAC1E,IAAQ,KAAI,cAAe,MAAO,EAC5B,EAAO,EAAa,OAC1B,MAAO,EAAG,cAAc,EAAK,QAAQ,CAAU,EAAG,CAAE,UAAW,EAAK,CAAC,EACrE,MAAO,EAAG,gBAAgB,EAAM,KAAK,UAAU,EAAO,KAAM,CAAC,EAAI;AAAA,EAAM,CAAE,KAAM,GAAM,CAAC,EACtF,MAAO,EAAG,OAAO,EAAM,CAAU,EAClC,EAEY,EAAW,EAAO,GAAG,6BAA6B,EAAE,SAAU,CAAC,EAAgB,CAC1F,IAAM,EAAW,MAAO,EAAK,EAC7B,GAAI,IAAU,QAAa,EAAS,SAAU,OAAO,EAAS,SAC9D,IAAM,EAAO,GAAS,EAAY,EAAE,EAAE,SAAS,WAAW,EAK1D,OADA,MAAO,EAAM,IAAK,EAAU,SAAU,CAAK,CAAC,EACrC,EACR,EAEY,EAAM,EAAO,GAAG,wBAAwB,EAAE,SAAU,CAAC,EAAc,CAC9E,GAAI,IAAQ,OAAW,CACrB,IAAQ,SAAU,KAAc,GAAS,MAAO,EAAK,EACrD,OAAO,KAAK,UAAU,EAAM,KAAM,CAAC,EAErC,OAAQ,EAAU,CAAG,OACd,WACH,OAAQ,MAAO,EAAK,GAAG,UAAY,OAEhC,OAAQ,CACX,IAAM,GAAQ,MAAO,EAAK,GAAG,KAC7B,OAAO,IAAS,OAAY,GAAK,OAAO,CAAI,CAC9C,KACK,WACH,OAAO,MAAO,EAAS,EAG3B,MAAU,MAAM,+BAA+B,GAAK,EACrD,EAEY,EAAM,EAAO,GAAG,wBAAwB,EAAE,SAAU,CAAC,EAAa,EAAe,CAC5F,OAAQ,EAAU,CAAG,OACd,WAAY,CACf,MAAO,EAAQ,KAAK,MAAO,EAAQ,CAAC,EACpC,MAAO,EAAM,IAAM,MAAO,EAAK,EAAI,SAAU,CAAM,CAAC,EACpD,MACF,KACK,OAAQ,CACX,IAAM,EAAO,OAAO,CAAK,EACzB,GAAI,CAAC,OAAO,UAAU,CAAI,GAAK,EAAO,GAAK,EAAO,MAAQ,MAAU,MAAM,kCAAkC,EAC5G,MAAO,EAAQ,KAAK,MAAO,EAAQ,CAAC,EACpC,MAAO,EAAM,IAAM,MAAO,EAAK,EAAI,MAAK,CAAC,EACzC,MACF,KACK,WAAY,CACf,MAAO,EAAQ,KAAK,MAAO,EAAQ,CAAC,EACpC,MAAO,EAAS,CAAK,EACrB,MACF,GAEH,EAEY,EAAQ,EAAO,GAAG,0BAA0B,EAAE,SAAU,CAAC,EAAa,CACjF,OAAQ,EAAU,CAAG,OACd,WAAY,CACf,MAAO,EAAQ,KAAK,MAAO,EAAQ,CAAC,EACpC,IAAQ,SAAU,KAAc,GAAS,MAAO,EAAK,EACrD,MAAO,EAAM,CAAI,EACjB,MACF,KACK,OAAQ,CACX,MAAO,EAAQ,KAAK,MAAO,EAAQ,CAAC,EACpC,IAAQ,KAAM,KAAU,GAAS,MAAO,EAAK,EAC7C,MAAO,EAAM,CAAI,EACjB,MACF,KACK,WAAY,CACf,MAAO,EAAQ,KAAK,MAAO,EAAQ,CAAC,EACpC,IAAQ,SAAU,KAAc,GAAS,MAAO,EAAK,EACrD,MAAO,EAAM,CAAI,EACjB,MACF,GAEH", | ||
| "debugId": "342C32E4F719ABAB64756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/services/standalone.ts", "src/services/server-connection.ts"], | ||
| "sourcesContent": [ | ||
| "import { Service, type Endpoint } from \"@opencode-ai/client/effect/service\"\nimport { CrossSpawnSpawner } from \"@opencode-ai/core/cross-spawn-spawner\"\nimport { AppNodeBuilder } from \"@opencode-ai/core/effect/app-node-builder\"\nimport { Effect, Schema, Stream } from \"effect\"\nimport { ChildProcess, ChildProcessSpawner } from \"effect/unstable/process\"\nimport { randomBytes } from \"node:crypto\"\nimport path from \"node:path\"\n\nconst Ready = Schema.Struct({ url: Schema.String })\nconst decodeReady = Schema.decodeUnknownPromise(Schema.fromJsonString(Ready))\n\ntype Options = {\n readonly command?: ReadonlyArray<string>\n}\n\nfunction command(password: string, options: Options) {\n const compiled = path.basename(process.execPath).replace(/\\.exe$/, \"\") !== \"bun\"\n const entrypoint = compiled ? [] : process.argv[1] ? [process.argv[1]] : []\n if (!compiled && entrypoint.length === 0) throw new Error(\"Failed to resolve CLI entrypoint\")\n const [executable, ...args] = options.command ?? [process.execPath, ...entrypoint, \"serve\"]\n if (!executable) throw new Error(\"Failed to resolve standalone server command\")\n return ChildProcess.make(executable, [...args, \"--stdio\", \"--port\", \"0\"], {\n cwd: process.cwd(),\n // Explicit entry wins over anything inherited, so a user-exported\n // OPENCODE_PASSWORD cannot shadow the child's lease credential.\n env: { OPENCODE_PASSWORD: password },\n extendEnv: true,\n // The server treats EOF on this pipe as the end of its ownership lease.\n // The OS closes it even when the TUI is killed before Effect finalizers run.\n stdin: \"pipe\",\n stderr: \"ignore\",\n killSignal: \"SIGTERM\",\n forceKillAfter: \"3 seconds\",\n })\n}\n\nconst makeEndpoint = Effect.fn(\"cli.standalone.endpoint\")(\n function* (options: Options) {\n const password = randomBytes(32).toString(\"base64url\")\n const spawner = yield* ChildProcessSpawner.ChildProcessSpawner\n const proc = yield* spawner.spawn(command(password, options))\n const output = yield* proc.stdout.pipe(Stream.decodeText(), Stream.splitLines, Stream.take(1), Stream.mkString)\n if (!output) return yield* Effect.fail(new Error(\"Standalone server exited before reporting readiness\"))\n const ready = yield* Effect.tryPromise(() => decodeReady(output))\n return {\n url: ready.url,\n auth: { type: \"basic\" as const, username: \"opencode\", password },\n pid: proc.pid,\n } satisfies Endpoint & { readonly pid: number }\n },\n Effect.provide(AppNodeBuilder.build(CrossSpawnSpawner.node)),\n)\n\nexport function start(options: Options = {}) {\n return makeEndpoint(options)\n}\n\nexport * as Standalone from \"./standalone\"\n", | ||
| "import { Service, type Endpoint, type EnsureOptions } from \"@opencode-ai/client/effect/service\"\nimport { ClientError, isUnauthorizedError, OpenCode } from \"@opencode-ai/client/promise\"\nimport { InstallationVersion } from \"@opencode-ai/core/installation/version\"\nimport { Effect, Redacted } from \"effect\"\nimport { Env } from \"../env\"\nimport { ServiceConfig } from \"./service-config\"\nimport { Standalone } from \"./standalone\"\n\nexport type Args = {\n readonly server?: string\n readonly standalone?: boolean\n readonly mismatch?: \"replace\" | \"ignore\" | \"error\"\n readonly onStart?: EnsureOptions[\"onStart\"]\n}\n\nexport type Resolved = {\n readonly endpoint: Endpoint\n readonly service?: ReturnType<typeof managedService>\n}\n\nexport const resolve = Effect.fn(\"cli.server-connection.resolve\")(function* (args: Args) {\n if (args.server !== undefined && args.standalone)\n return yield* Effect.fail(new Error(\"--server and --standalone cannot be combined\"))\n if (args.server !== undefined) {\n const password = yield* Env.password\n const endpoint = {\n url: args.server,\n auth: password ? { type: \"basic\" as const, username: \"opencode\", password: Redacted.value(password) } : undefined,\n } satisfies Endpoint\n const client = OpenCode.make({ baseUrl: endpoint.url, headers: Service.headers(endpoint) })\n const health = yield* Effect.tryPromise({\n try: () => client.health.get({ signal: AbortSignal.timeout(5_000) }),\n catch: (cause) => connectError(endpoint, cause),\n })\n if (health.version !== InstallationVersion)\n process.stderr.write(\n `Warning: Server at ${endpoint.url} has version ${health.version}; this client is ${InstallationVersion}. Continuing anyway.\\n`,\n )\n return { endpoint } satisfies Resolved\n }\n if (args.standalone) {\n return { endpoint: yield* Standalone.start() } satisfies Resolved\n }\n\n const options = yield* ServiceConfig.options()\n return {\n endpoint: yield* resolveManaged({ ...options, onStart: args.onStart }, args.mismatch ?? \"replace\"),\n service: managedService(options),\n } satisfies Resolved\n})\n\nfunction managedService(options: EnsureOptions) {\n const reconnectOptions = { ...options, version: undefined }\n return {\n reconnect: () => Service.ensure(reconnectOptions),\n restart: () =>\n Effect.gen(function* () {\n yield* Service.stop(options)\n yield* Service.ensure(options)\n }),\n }\n}\n\nconst resolveManaged = Effect.fnUntraced(function* (\n options: EnsureOptions,\n mismatch: NonNullable<Args[\"mismatch\"]>,\n) {\n if (mismatch === \"replace\") return yield* Service.ensure(options)\n if (mismatch === \"ignore\") return yield* Service.ensure({ ...options, version: undefined })\n\n const compatible = yield* Service.discover(options)\n if (compatible !== undefined) return compatible\n const existing = yield* Service.discover({ ...options, version: undefined })\n if (existing !== undefined)\n return yield* Effect.fail(new Error(\"Background server version does not match this client\"))\n return yield* Service.ensure(options)\n})\n\nfunction connectError(endpoint: Endpoint, cause: unknown) {\n if (isUnauthorizedError(cause)) {\n return new Error(\n endpoint.auth === undefined\n ? `Server at ${endpoint.url} requires a password; set OPENCODE_PASSWORD`\n : `Server at ${endpoint.url} rejected the password`,\n { cause },\n )\n }\n if (cause instanceof ClientError && cause.reason === \"Transport\")\n return new Error(`Could not reach server at ${endpoint.url}`, { cause })\n return new Error(`Server at ${endpoint.url} did not provide a compatible V2 health response`, { cause })\n}\n\nexport * as ServerConnection from \"./server-connection\"\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "BA822F4F69BE290064756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/service/stop.ts"], | ||
| "sourcesContent": [ | ||
| "import { Effect } from \"effect\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { ServiceConfig } from \"../../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.service.commands.stop,\n Effect.fn(\"cli.service.stop\")(function* () {\n yield* Service.stop(yield* ServiceConfig.options())\n }),\n)\n" | ||
| ], | ||
| "mappings": ";+0BAMA,SAAe,SAAQ,aACrB,OAAS,cAAS,aAAQ,cAAS,UACnC,OAAO,QAAG,uBAAkB,OAAE,cAAU,OAAG,MACzC,WAAO,OAAQ,UAAK,WAAO,OAAc,aAAQ,MAAC,EACnD,CACH", | ||
| "debugId": "6A62854354DEF6D964756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["../ai/src/protocols/utils/openai-options.ts", "../ai/src/protocols/utils/lifecycle.ts", "../ai/src/protocols/utils/gemini-tool-schema.ts", "../ai/src/protocols/utils/tool-schema.ts", "../ai/src/protocols/utils/tool-stream.ts", "../ai/src/protocols/openai-chat.ts"], | ||
| "sourcesContent": [ | ||
| "import { Schema } from \"effect\"\nimport type { LLMRequest, TextVerbosity as TextVerbosityValue } from \"../../schema\"\nimport { ReasoningEfforts, TextVerbosity } from \"../../schema\"\n\nexport const OpenAIReasoningEfforts = ReasoningEfforts\nexport type OpenAIReasoningEffort = string\n\n// Mirrors OpenAI's `ResponseIncludable` union from the official SDK. Keep this\n// in lockstep with `openai-node/src/resources/responses/responses.ts`.\nexport const OpenAIResponseIncludables = [\n \"file_search_call.results\",\n \"web_search_call.results\",\n \"web_search_call.action.sources\",\n \"message.input_image.image_url\",\n \"computer_call_output.output.image_url\",\n \"code_interpreter_call.outputs\",\n \"reasoning.encrypted_content\",\n \"message.output_text.logprobs\",\n] as const\nexport type OpenAIResponseIncludable = (typeof OpenAIResponseIncludables)[number]\nexport const OpenAIServiceTiers = [\"auto\", \"default\", \"flex\", \"priority\"] as const\nexport type OpenAIServiceTier = (typeof OpenAIServiceTiers)[number]\n\nconst TEXT_VERBOSITY = new Set<string>([\"low\", \"medium\", \"high\"])\nconst INCLUDABLES = new Set<string>(OpenAIResponseIncludables)\nconst SERVICE_TIERS = new Set<string>(OpenAIServiceTiers)\n\nexport const OpenAIReasoningEffort = Schema.String\nexport const OpenAITextVerbosity = TextVerbosity\nexport const OpenAIResponseIncludable = Schema.Literals(OpenAIResponseIncludables)\nexport const OpenAIServiceTier = Schema.Literals(OpenAIServiceTiers)\n\nexport const isReasoningEffort = (effort: unknown): effort is OpenAIReasoningEffort => typeof effort === \"string\"\n\nconst isTextVerbosity = (value: unknown): value is TextVerbosityValue =>\n typeof value === \"string\" && TEXT_VERBOSITY.has(value)\n\nconst options = (request: LLMRequest) => request.providerOptions?.openai\n\nexport const store = (request: LLMRequest): boolean | undefined => {\n const value = options(request)?.store\n return typeof value === \"boolean\" ? value : undefined\n}\n\nexport const reasoningEffort = (request: LLMRequest): string | undefined => {\n const value = options(request)?.reasoningEffort\n return typeof value === \"string\" ? value : undefined\n}\n\nexport const reasoningSummary = (request: LLMRequest): \"auto\" | undefined =>\n options(request)?.reasoningSummary === \"auto\" ? \"auto\" : undefined\n\n// Resolve the OpenAI Responses `include` field. Filters out unknown\n// includable values defensively so a typo in upstream config drops the\n// invalid entry instead of poisoning the wire body. An empty array (either\n// passed directly or produced by filtering) is treated as \"no include\" and\n// returns undefined so the request body omits the field entirely.\nexport const include = (request: LLMRequest): ReadonlyArray<OpenAIResponseIncludable> | undefined => {\n const value = options(request)?.include\n if (!Array.isArray(value)) return undefined\n const filtered = value.filter((entry): entry is OpenAIResponseIncludable => INCLUDABLES.has(entry))\n return filtered.length > 0 ? filtered : undefined\n}\n\nexport const promptCacheKey = (request: LLMRequest) => {\n const value = options(request)?.promptCacheKey\n return typeof value === \"string\" ? value : undefined\n}\n\nexport const textVerbosity = (request: LLMRequest) => {\n const value = options(request)?.textVerbosity\n return isTextVerbosity(value) ? value : undefined\n}\n\nexport const serviceTier = (request: LLMRequest) => {\n const value = options(request)?.serviceTier\n return typeof value === \"string\" && SERVICE_TIERS.has(value) ? (value as OpenAIServiceTier) : undefined\n}\n\nexport const instructions = (request: LLMRequest) => {\n const value = options(request)?.instructions\n return typeof value === \"string\" ? value : undefined\n}\n\nexport * as OpenAIOptions from \"./openai-options\"\n", | ||
| "import { LLMEvent, type FinishReason, type ProviderMetadata, type Usage } from \"../../schema\"\n\nexport interface State {\n readonly stepStarted: boolean\n readonly text: ReadonlySet<string>\n readonly reasoning: ReadonlySet<string>\n}\n\nexport const initial = (): State => ({ stepStarted: false, text: new Set(), reasoning: new Set() })\n\nexport const stepStart = (state: State, events: LLMEvent[]): State => {\n if (state.stepStarted) return state\n events.push(LLMEvent.stepStart({ index: 0 }))\n return { ...state, stepStarted: true }\n}\n\nexport const textDelta = (state: State, events: LLMEvent[], id: string, text: string): State => {\n const stepped = stepStart(state, events)\n if (stepped.text.has(id)) {\n events.push(LLMEvent.textDelta({ id, text }))\n return stepped\n }\n events.push(LLMEvent.textStart({ id }), LLMEvent.textDelta({ id, text }))\n return { ...stepped, text: new Set([...stepped.text, id]) }\n}\n\nexport const reasoningStart = (\n state: State,\n events: LLMEvent[],\n id: string,\n providerMetadata?: ProviderMetadata,\n): State => {\n if (state.reasoning.has(id)) return state\n const stepped = stepStart(state, events)\n events.push(LLMEvent.reasoningStart({ id, providerMetadata }))\n return { ...stepped, reasoning: new Set([...stepped.reasoning, id]) }\n}\n\nexport const reasoningDelta = (\n state: State,\n events: LLMEvent[],\n id: string,\n text: string,\n providerMetadata?: ProviderMetadata,\n): State => {\n const started = reasoningStart(state, events, id, providerMetadata)\n events.push(LLMEvent.reasoningDelta({ id, text }))\n return started\n}\n\nexport const reasoningEnd = (\n state: State,\n events: LLMEvent[],\n id: string,\n providerMetadata?: ProviderMetadata,\n): State => {\n if (!state.reasoning.has(id)) return state\n const stepped = stepStart(state, events)\n events.push(LLMEvent.reasoningEnd({ id, providerMetadata }))\n const reasoning = new Set(stepped.reasoning)\n reasoning.delete(id)\n return { ...stepped, reasoning }\n}\n\nexport const textEnd = (state: State, events: LLMEvent[], id: string, providerMetadata?: ProviderMetadata): State => {\n if (!state.text.has(id)) return state\n const stepped = stepStart(state, events)\n events.push(LLMEvent.textEnd({ id, providerMetadata }))\n const text = new Set(stepped.text)\n text.delete(id)\n return { ...stepped, text }\n}\n\nconst closeOpenBlocks = (state: State, events: LLMEvent[]): State => {\n for (const id of state.reasoning) events.push(LLMEvent.reasoningEnd({ id }))\n for (const id of state.text) events.push(LLMEvent.textEnd({ id }))\n return { ...state, text: new Set(), reasoning: new Set() }\n}\n\nexport const finish = (\n state: State,\n events: LLMEvent[],\n input: {\n readonly reason: FinishReason\n readonly usage?: Usage\n readonly providerMetadata?: ProviderMetadata\n },\n): State => {\n const stepped = closeOpenBlocks(stepStart(state, events), events)\n events.push(\n LLMEvent.stepFinish({\n index: 0,\n reason: input.reason,\n usage: input.usage,\n providerMetadata: input.providerMetadata,\n }),\n LLMEvent.finish(input),\n )\n return { ...stepped, stepStarted: false }\n}\n\nexport * as Lifecycle from \"./lifecycle\"\n", | ||
| "import { isRecord } from \"../../utils/record\"\n\n// Gemini accepts a JSON Schema-like dialect for tool parameters, but rejects a\n// handful of common JSON Schema shapes. Keep this projection isolated so the\n// Gemini protocol file still reads like the other protocol modules.\nconst SCHEMA_INTENT_KEYS = [\n \"type\",\n \"properties\",\n \"items\",\n \"prefixItems\",\n \"enum\",\n \"const\",\n \"$ref\",\n \"additionalProperties\",\n \"patternProperties\",\n \"required\",\n \"not\",\n \"if\",\n \"then\",\n \"else\",\n]\n\nconst hasCombiner = (schema: unknown) =>\n isRecord(schema) && (Array.isArray(schema.anyOf) || Array.isArray(schema.oneOf) || Array.isArray(schema.allOf))\n\nconst hasSchemaIntent = (schema: unknown) =>\n isRecord(schema) && (hasCombiner(schema) || SCHEMA_INTENT_KEYS.some((key) => key in schema))\n\nconst sanitizeNode = (schema: unknown): unknown => {\n if (!isRecord(schema)) return Array.isArray(schema) ? schema.map(sanitizeNode) : schema\n\n const result: Record<string, unknown> = Object.fromEntries(\n Object.entries(schema).map(([key, value]) => [\n key,\n key === \"enum\" && Array.isArray(value) ? value.map(String) : sanitizeNode(value),\n ]),\n )\n\n if (Array.isArray(result.enum) && (result.type === \"integer\" || result.type === \"number\")) result.type = \"string\"\n\n const properties = result.properties\n if (result.type === \"object\" && isRecord(properties) && Array.isArray(result.required)) {\n result.required = result.required.filter((field) => typeof field === \"string\" && field in properties)\n }\n\n if (result.type === \"array\" && !hasCombiner(result)) {\n result.items = result.items ?? {}\n if (isRecord(result.items) && !hasSchemaIntent(result.items)) result.items = { ...result.items, type: \"string\" }\n }\n\n if (typeof result.type === \"string\" && result.type !== \"object\" && !hasCombiner(result)) {\n delete result.properties\n delete result.required\n }\n\n return result\n}\n\nconst emptyObjectSchema = (schema: Record<string, unknown>) =>\n schema.type === \"object\" &&\n (!isRecord(schema.properties) || Object.keys(schema.properties).length === 0) &&\n !schema.additionalProperties\n\nconst projectNode = (schema: unknown): Record<string, unknown> | undefined => {\n if (!isRecord(schema)) return undefined\n if (emptyObjectSchema(schema)) return undefined\n return Object.fromEntries(\n [\n [\"description\", schema.description],\n [\"required\", schema.required],\n [\"format\", schema.format],\n [\"type\", Array.isArray(schema.type) ? schema.type.filter((type) => type !== \"null\")[0] : schema.type],\n [\"nullable\", Array.isArray(schema.type) && schema.type.includes(\"null\") ? true : undefined],\n [\"enum\", schema.const !== undefined ? [schema.const] : schema.enum],\n [\n \"properties\",\n isRecord(schema.properties)\n ? Object.fromEntries(Object.entries(schema.properties).map(([key, value]) => [key, projectNode(value)]))\n : undefined,\n ],\n [\n \"items\",\n Array.isArray(schema.items)\n ? schema.items.map(projectNode)\n : schema.items === undefined\n ? undefined\n : projectNode(schema.items),\n ],\n [\"allOf\", Array.isArray(schema.allOf) ? schema.allOf.map(projectNode) : undefined],\n [\"anyOf\", Array.isArray(schema.anyOf) ? schema.anyOf.map(projectNode) : undefined],\n [\"oneOf\", Array.isArray(schema.oneOf) ? schema.oneOf.map(projectNode) : undefined],\n [\"minLength\", schema.minLength],\n ].filter((entry) => entry[1] !== undefined),\n )\n}\n\nexport const convert = (schema: unknown) => projectNode(sanitizeNode(schema))\n\nexport * as GeminiToolSchema from \"./gemini-tool-schema\"\n", | ||
| "import type { JsonSchema, ModelToolSchemaCompatibility } from \"../../schema\"\nimport { isRecord } from \"../../utils/record\"\nimport { GeminiToolSchema } from \"./gemini-tool-schema\"\n\nconst removeNullSchemas = (value: unknown): unknown => {\n if (Array.isArray(value)) return value.map(removeNullSchemas)\n if (!isRecord(value)) return value\n const fields = Object.fromEntries(\n Object.entries(value)\n .filter(([key]) => key !== \"anyOf\")\n .map(([key, field]) => [key, removeNullSchemas(field)]),\n )\n if (!Array.isArray(value.anyOf)) return fields\n const variants = value.anyOf.filter((variant) => !isRecord(variant) || variant.type !== \"null\").map(removeNullSchemas)\n if (variants.length === 1 && isRecord(variants[0])) return { ...fields, ...variants[0] }\n return { ...fields, anyOf: variants }\n}\n\nconst tupleItemsSchema = (items: ReadonlyArray<unknown>) => {\n const projected = items.map(moonshotNode)\n if (projected.length === 0) return {}\n if (projected.length === 1) return projected[0]\n return { anyOf: projected }\n}\n\nconst moonshotNode = (schema: unknown): unknown => {\n if (Array.isArray(schema)) return schema.map(moonshotNode)\n if (!isRecord(schema)) return schema\n if (typeof schema.$ref === \"string\") return { $ref: schema.$ref }\n return Object.fromEntries(\n Object.entries(schema).flatMap(([key, value]) => {\n if (key === \"items\" && Array.isArray(value)) return [[key, tupleItemsSchema(value)]]\n if (key === \"prefixItems\") {\n if (\"items\" in schema) return []\n return [[\"items\", tupleItemsSchema(Array.isArray(value) ? value : [])]]\n }\n if (key === \"unevaluatedItems\") return []\n return [[key, moonshotNode(value)]]\n }),\n )\n}\n\nconst moonshot = (schema: JsonSchema): JsonSchema => {\n const projected = moonshotNode(schema)\n return isRecord(projected) ? projected : {}\n}\n\nconst openAI = (schema: JsonSchema): JsonSchema => {\n const variants = Array.isArray(schema.anyOf) ? schema.anyOf.filter(isRecord) : []\n const flattened =\n variants.length === 0\n ? { ...schema, type: \"object\" }\n : {\n ...Object.fromEntries(Object.entries(schema).filter(([key]) => key !== \"anyOf\")),\n type: \"object\",\n properties: variants.reduce(\n (properties, variant) => ({ ...(isRecord(variant.properties) ? variant.properties : {}), ...properties }),\n {},\n ),\n additionalProperties: false,\n }\n const normalized = removeNullSchemas(flattened)\n return isRecord(normalized) ? normalized : { type: \"object\" }\n}\n\nconst gemini = (schema: JsonSchema): JsonSchema => GeminiToolSchema.convert(schema) ?? {}\n\nconst modelCompatibility = (\n schema: JsonSchema,\n compatibility: ModelToolSchemaCompatibility | undefined,\n): JsonSchema => {\n if (compatibility === undefined) return schema\n switch (compatibility) {\n case \"gemini\":\n return gemini(schema)\n case \"moonshot\":\n return moonshot(schema)\n }\n}\n\nexport const ToolSchemaProjection = {\n gemini,\n modelCompatibility,\n moonshot,\n openAI,\n} as const\n", | ||
| "import { Effect } from \"effect\"\nimport { LLMError, LLMEvent, type ProviderMetadata, type ToolCall } from \"../../schema\"\nimport { eventError, parseToolInput, type ToolAccumulator } from \"../shared\"\n\ntype StreamKey = string | number\n\n/**\n * One pending streamed tool call. Providers emit the tool identity and JSON\n * argument text across separate chunks; `input` is the raw JSON string collected\n * so far, not the parsed object.\n */\nexport interface PendingTool extends ToolAccumulator {\n readonly providerExecuted?: boolean\n readonly providerMetadata?: ProviderMetadata\n}\n\n/**\n * Sparse parser state keyed by the provider's stream-local tool identifier.\n *\n * This key is not the final tool-call id (`call_...`). It is the id/index the\n * provider uses while streaming a partial call: OpenAI Chat / Anthropic /\n * Bedrock use numeric content indexes, while OpenAI Responses uses string\n * `item_id`s. The generic keeps each protocol internally consistent.\n */\nexport type State<K extends StreamKey> = Partial<Record<K, PendingTool>>\n\n/**\n * Result of adding argument text to one pending tool call. It returns both the\n * next `tools` state and the updated `tool` because parsers often need the\n * current id/name immediately. `events` contains lifecycle and delta events\n * produced by the append; metadata-only deltas update identity without output.\n */\nexport interface AppendOutcome<K extends StreamKey> {\n readonly tools: State<K>\n readonly tool: PendingTool\n readonly events: ReadonlyArray<LLMEvent>\n}\n\n/** Create empty accumulator state for one provider stream. */\nexport const empty = <K extends StreamKey>(): State<K> => ({})\n\nconst withTool = <K extends StreamKey>(tools: State<K>, key: K, tool: PendingTool): State<K> => {\n return { ...tools, [key]: tool }\n}\n\nconst withoutTool = <K extends StreamKey>(tools: State<K>, key: K): State<K> => {\n const next = { ...tools }\n delete next[key]\n return next\n}\n\nconst inputStart = (tool: PendingTool) =>\n LLMEvent.toolInputStart({\n id: tool.id,\n name: tool.name,\n providerMetadata: tool.providerMetadata,\n })\n\nconst inputDelta = (tool: PendingTool, text: string) =>\n LLMEvent.toolInputDelta({\n id: tool.id,\n name: tool.name,\n text,\n })\n\nconst toolCall = (route: string, tool: PendingTool, inputOverride?: string) =>\n parseToolInput(route, tool.name, inputOverride ?? tool.input).pipe(\n Effect.map(\n (input): ToolCall =>\n LLMEvent.toolCall({\n id: tool.id,\n name: tool.name,\n input,\n providerExecuted: tool.providerExecuted ? true : undefined,\n providerMetadata: tool.providerMetadata,\n }),\n ),\n )\n\n/** Store the updated tool and produce the optional public delta event. */\nconst appendTool = <K extends StreamKey>(\n tools: State<K>,\n key: K,\n tool: PendingTool,\n text: string,\n): AppendOutcome<K> => {\n const events: LLMEvent[] = []\n if (!tools[key]) events.push(inputStart(tool))\n if (text.length > 0) events.push(inputDelta(tool, text))\n return {\n tools: withTool(tools, key, tool),\n tool,\n events,\n }\n}\n\nexport const isError = <K extends StreamKey>(result: AppendOutcome<K> | LLMError): result is LLMError =>\n result instanceof LLMError\n\n/**\n * Register a tool call whose start event arrived before any argument deltas.\n * Used by Anthropic `content_block_start`, Bedrock `contentBlockStart`, and\n * OpenAI Responses `response.output_item.added`.\n */\nexport const start = <K extends StreamKey>(\n tools: State<K>,\n key: K,\n tool: Omit<PendingTool, \"input\"> & { readonly input?: string },\n) => withTool(tools, key, { ...tool, input: tool.input ?? \"\" })\n\n/**\n * Append a streamed argument delta, starting the tool if this provider encodes\n * identity on the first delta instead of a separate start event. OpenAI Chat has\n * this shape: `tool_calls[].index` is the stream key, and `id` / `name` may only\n * appear on the first delta for that index.\n */\nexport const appendOrStart = <K extends StreamKey>(\n route: string,\n tools: State<K>,\n key: K,\n delta: { readonly id?: string; readonly name?: string; readonly text: string },\n missingToolMessage: string,\n): AppendOutcome<K> | LLMError => {\n const current = tools[key]\n const id = delta.id ?? current?.id\n const name = delta.name ?? current?.name\n if (!id || !name) return eventError(route, missingToolMessage)\n\n const tool = {\n id,\n name,\n input: `${current?.input ?? \"\"}${delta.text}`,\n providerExecuted: current?.providerExecuted,\n providerMetadata: current?.providerMetadata,\n }\n if (current && delta.text.length === 0 && current.id === id && current.name === name)\n return { tools, tool: current, events: [] }\n return appendTool(tools, key, tool, delta.text)\n}\n\n/**\n * Append argument text to a tool that must already have been started. This keeps\n * protocols honest when their stream grammar promises a start event before any\n * argument delta.\n */\nexport const appendExisting = <K extends StreamKey>(\n route: string,\n tools: State<K>,\n key: K,\n text: string,\n missingToolMessage: string,\n): AppendOutcome<K> | LLMError => {\n const current = tools[key]\n if (!current) return eventError(route, missingToolMessage)\n if (text.length === 0) return { tools, tool: current, events: [] }\n return appendTool(tools, key, { ...current, input: `${current.input}${text}` }, text)\n}\n\n/**\n * Finalize one pending tool call: parse the accumulated raw JSON, remove it\n * from state, and return the optional public `tool-call` event. Missing keys are\n * a no-op because some providers emit stop events for non-tool content blocks.\n */\nexport const finish = <K extends StreamKey>(route: string, tools: State<K>, key: K) =>\n Effect.gen(function* () {\n const tool = tools[key]\n if (!tool) return { tools }\n return {\n tools: withoutTool(tools, key),\n events: [\n LLMEvent.toolInputEnd({ id: tool.id, name: tool.name, providerMetadata: tool.providerMetadata }),\n yield* toolCall(route, tool),\n ],\n }\n })\n\n/**\n * Finalize one pending tool call with an authoritative final input string.\n * OpenAI Responses can send accumulated deltas and then repeat the completed\n * arguments on `response.output_item.done`; the final value wins.\n */\nexport const finishWithInput = <K extends StreamKey>(route: string, tools: State<K>, key: K, input: string) =>\n Effect.gen(function* () {\n const tool = tools[key]\n if (!tool) return { tools }\n return {\n tools: withoutTool(tools, key),\n events: [\n LLMEvent.toolInputEnd({ id: tool.id, name: tool.name, providerMetadata: tool.providerMetadata }),\n yield* toolCall(route, tool, input),\n ],\n }\n })\n\n/**\n * Finalize every pending tool call at once. OpenAI Chat has this shape: it does\n * not emit per-tool stop events, so all accumulated calls finish when the choice\n * receives a terminal `finish_reason`.\n */\nexport const finishAll = <K extends StreamKey>(route: string, tools: State<K>) =>\n Effect.gen(function* () {\n const pending = Object.values<PendingTool | undefined>(tools).filter(\n (tool): tool is PendingTool => tool !== undefined,\n )\n return {\n tools: empty<K>(),\n events: yield* Effect.forEach(pending, (tool) =>\n toolCall(route, tool).pipe(\n Effect.map((call) => [\n LLMEvent.toolInputEnd({ id: tool.id, name: tool.name, providerMetadata: tool.providerMetadata }),\n call,\n ]),\n ),\n ).pipe(Effect.map((events) => events.flat())),\n }\n })\n\nexport * as ToolStream from \"./tool-stream\"\n", | ||
| "import { Effect, Schema } from \"effect\"\nimport { Route } from \"../route/client\"\nimport { Auth } from \"../route/auth\"\nimport { Endpoint } from \"../route/endpoint\"\nimport { HttpTransport } from \"../route/transport\"\nimport { Protocol } from \"../route/protocol\"\nimport {\n LLMEvent,\n Usage,\n type FinishReason,\n type JsonSchema,\n type LLMRequest,\n type MediaPart,\n type ReasoningPart,\n type TextPart,\n type ToolCallPart,\n type ToolDefinition,\n type ToolContent,\n} from \"../schema\"\nimport { isRecord, JsonObject, optionalArray, optionalNull, ProviderShared } from \"./shared\"\nimport { OpenAIOptions } from \"./utils/openai-options\"\nimport { Lifecycle } from \"./utils/lifecycle\"\nimport { ToolSchemaProjection } from \"./utils/tool-schema\"\nimport { ToolStream } from \"./utils/tool-stream\"\n\nconst ADAPTER = \"openai-chat\"\nconst IMAGE_MIMES = new Set<string>(ProviderShared.IMAGE_MIMES)\nexport const DEFAULT_BASE_URL = \"https://api.openai.com/v1\"\nexport const PATH = \"/chat/completions\"\n\n// =============================================================================\n// Request Body Schema\n// =============================================================================\n// The body schema is the provider-native JSON body. `fromRequest` below builds\n// this shape from the common `LLMRequest`, then `Route.make` validates and\n// JSON-encodes it before transport.\nconst OpenAIChatFunction = Schema.Struct({\n name: Schema.String,\n description: Schema.String,\n parameters: JsonObject,\n})\n\nconst OpenAIChatTool = Schema.Struct({\n type: Schema.tag(\"function\"),\n function: OpenAIChatFunction,\n})\ntype OpenAIChatTool = Schema.Schema.Type<typeof OpenAIChatTool>\n\nconst OpenAIChatAssistantToolCall = Schema.Struct({\n id: Schema.String,\n type: Schema.tag(\"function\"),\n function: Schema.Struct({\n name: Schema.String,\n arguments: Schema.String,\n }),\n})\ntype OpenAIChatAssistantToolCall = Schema.Schema.Type<typeof OpenAIChatAssistantToolCall>\n\nconst OpenAIChatUserContent = Schema.Union([\n Schema.Struct({ type: Schema.Literal(\"text\"), text: Schema.String }),\n Schema.Struct({\n type: Schema.Literal(\"image_url\"),\n image_url: Schema.Struct({ url: Schema.String }),\n }),\n])\n\nconst OpenAIChatMessage = Schema.Union([\n Schema.Struct({ role: Schema.Literal(\"system\"), content: Schema.String }),\n Schema.Struct({\n role: Schema.Literal(\"user\"),\n content: Schema.Union([Schema.String, Schema.Array(OpenAIChatUserContent)]),\n }),\n Schema.Struct({\n role: Schema.Literal(\"assistant\"),\n content: Schema.NullOr(Schema.String),\n tool_calls: optionalArray(OpenAIChatAssistantToolCall),\n reasoning_content: Schema.optional(Schema.String),\n }),\n Schema.Struct({ role: Schema.Literal(\"tool\"), tool_call_id: Schema.String, content: Schema.String }),\n]).pipe(Schema.toTaggedUnion(\"role\"))\ntype OpenAIChatMessage = Schema.Schema.Type<typeof OpenAIChatMessage>\n\nconst OpenAIChatToolChoice = Schema.Union([\n Schema.Literals([\"auto\", \"none\", \"required\"]),\n Schema.Struct({\n type: Schema.tag(\"function\"),\n function: Schema.Struct({ name: Schema.String }),\n }),\n])\n\nexport const bodyFields = {\n model: Schema.String,\n messages: Schema.Array(OpenAIChatMessage),\n tools: optionalArray(OpenAIChatTool),\n tool_choice: Schema.optional(OpenAIChatToolChoice),\n stream: Schema.Literal(true),\n stream_options: Schema.optional(Schema.Struct({ include_usage: Schema.Boolean })),\n store: Schema.optional(Schema.Boolean),\n reasoning_effort: Schema.optional(OpenAIOptions.OpenAIReasoningEffort),\n max_tokens: Schema.optional(Schema.Number),\n temperature: Schema.optional(Schema.Number),\n top_p: Schema.optional(Schema.Number),\n frequency_penalty: Schema.optional(Schema.Number),\n presence_penalty: Schema.optional(Schema.Number),\n seed: Schema.optional(Schema.Number),\n stop: optionalArray(Schema.String),\n}\nconst OpenAIChatBody = Schema.Struct(bodyFields)\nexport type OpenAIChatBody = Schema.Schema.Type<typeof OpenAIChatBody>\n\n// =============================================================================\n// Streaming Event Schema\n// =============================================================================\n// The event schema is one decoded SSE `data:` payload. `Framing.sse` splits the\n// byte stream into strings, then `Protocol.jsonEvent` decodes each string into\n// this provider-native event shape.\nconst OpenAIChatUsage = Schema.Struct({\n prompt_tokens: Schema.optional(Schema.Number),\n completion_tokens: Schema.optional(Schema.Number),\n total_tokens: Schema.optional(Schema.Number),\n prompt_tokens_details: optionalNull(\n Schema.Struct({\n cached_tokens: Schema.optional(Schema.Number),\n }),\n ),\n completion_tokens_details: optionalNull(\n Schema.Struct({\n reasoning_tokens: Schema.optional(Schema.Number),\n }),\n ),\n})\n\nconst OpenAIChatToolCallDeltaFunction = Schema.Struct({\n name: optionalNull(Schema.String),\n arguments: optionalNull(Schema.String),\n})\n\nconst OpenAIChatToolCallDelta = Schema.Struct({\n index: Schema.Number,\n id: optionalNull(Schema.String),\n function: optionalNull(OpenAIChatToolCallDeltaFunction),\n})\ntype OpenAIChatToolCallDelta = Schema.Schema.Type<typeof OpenAIChatToolCallDelta>\n\nconst OpenAIChatDelta = Schema.Struct({\n content: optionalNull(Schema.String),\n reasoning_content: optionalNull(Schema.String),\n tool_calls: optionalNull(Schema.Array(OpenAIChatToolCallDelta)),\n})\n\nconst OpenAIChatChoice = Schema.Struct({\n delta: optionalNull(OpenAIChatDelta),\n finish_reason: optionalNull(Schema.String),\n})\n\nexport const OpenAIChatEvent = Schema.Struct({\n choices: Schema.Array(OpenAIChatChoice),\n usage: optionalNull(OpenAIChatUsage),\n})\nexport type OpenAIChatEvent = Schema.Schema.Type<typeof OpenAIChatEvent>\ntype OpenAIChatRequestMessage = LLMRequest[\"messages\"][number]\n\ninterface ParserState {\n readonly tools: ToolStream.State<number>\n readonly toolCallEvents: ReadonlyArray<LLMEvent>\n readonly usage?: Usage\n readonly finishReason?: FinishReason\n readonly lifecycle: Lifecycle.State\n}\n\n// =============================================================================\n// Request Lowering\n// =============================================================================\n// Lowering is the only place that knows how common LLM messages map onto the\n// OpenAI Chat wire format. Keep provider quirks here instead of leaking native\n// fields into `LLMRequest`.\nconst lowerTool = (tool: ToolDefinition, inputSchema: JsonSchema): OpenAIChatTool => ({\n type: \"function\",\n function: {\n name: tool.name,\n description: tool.description,\n parameters: ToolSchemaProjection.openAI(inputSchema),\n },\n})\n\nconst lowerToolChoice = (toolChoice: NonNullable<LLMRequest[\"toolChoice\"]>) =>\n ProviderShared.matchToolChoice(\"OpenAI Chat\", toolChoice, {\n auto: () => \"auto\" as const,\n none: () => \"none\" as const,\n required: () => \"required\" as const,\n tool: (name) => ({ type: \"function\" as const, function: { name } }),\n })\n\nconst lowerToolCall = (part: ToolCallPart): OpenAIChatAssistantToolCall => ({\n id: part.id,\n type: \"function\",\n function: {\n name: part.name,\n arguments: ProviderShared.encodeJson(part.input),\n },\n})\n\nconst lowerMedia = Effect.fn(\"OpenAIChat.lowerMedia\")(function* (part: MediaPart) {\n const media = yield* ProviderShared.validateMedia(\"OpenAI Chat\", part, IMAGE_MIMES)\n return { type: \"image_url\" as const, image_url: { url: media.dataUrl } }\n})\n\nconst openAICompatibleReasoningContent = (native: unknown) =>\n isRecord(native) && typeof native.reasoning_content === \"string\" ? native.reasoning_content : undefined\n\nconst lowerUserMessage = Effect.fn(\"OpenAIChat.lowerUserMessage\")(function* (message: OpenAIChatRequestMessage) {\n const content: Array<Schema.Schema.Type<typeof OpenAIChatUserContent>> = []\n for (const part of message.content) {\n if (part.type === \"text\") {\n content.push({ type: \"text\", text: part.text })\n continue\n }\n if (part.type === \"media\") {\n content.push(yield* lowerMedia(part))\n continue\n }\n return yield* ProviderShared.unsupportedContent(\"OpenAI Chat\", \"user\", [\"text\", \"media\"])\n }\n if (content.every((part) => part.type === \"text\"))\n return { role: \"user\" as const, content: content.map((part) => part.text).join(\"\") }\n return { role: \"user\" as const, content }\n})\n\nconst lowerAssistantMessage = Effect.fn(\"OpenAIChat.lowerAssistantMessage\")(function* (\n message: OpenAIChatRequestMessage,\n) {\n const content: TextPart[] = []\n const reasoning: ReasoningPart[] = []\n const toolCalls: OpenAIChatAssistantToolCall[] = []\n for (const part of message.content) {\n if (!ProviderShared.supportsContent(part, [\"text\", \"reasoning\", \"tool-call\"]))\n return yield* ProviderShared.unsupportedContent(\"OpenAI Chat\", \"assistant\", [\"text\", \"reasoning\", \"tool-call\"])\n if (part.type === \"text\") {\n content.push(part)\n continue\n }\n if (part.type === \"reasoning\") {\n reasoning.push(part)\n continue\n }\n if (part.type === \"tool-call\") {\n toolCalls.push(lowerToolCall(part))\n continue\n }\n }\n return {\n role: \"assistant\" as const,\n content: content.length === 0 ? null : ProviderShared.joinText(content),\n tool_calls: toolCalls.length === 0 ? undefined : toolCalls,\n reasoning_content:\n reasoning.length > 0\n ? reasoning.map((part) => part.text).join(\"\")\n : openAICompatibleReasoningContent(message.native?.openaiCompatible),\n }\n})\n\nconst lowerToolMessages = Effect.fn(\"OpenAIChat.lowerToolMessages\")(function* (message: OpenAIChatRequestMessage) {\n const messages: OpenAIChatMessage[] = []\n const images: Array<Schema.Schema.Type<typeof OpenAIChatUserContent>> = []\n for (const part of message.content) {\n if (!ProviderShared.supportsContent(part, [\"tool-result\"]))\n return yield* ProviderShared.unsupportedContent(\"OpenAI Chat\", \"tool\", [\"tool-result\"])\n if (part.result.type !== \"content\") {\n messages.push({ role: \"tool\", tool_call_id: part.id, content: ProviderShared.toolResultText(part) })\n continue\n }\n const content: ReadonlyArray<ToolContent> = part.result.value\n const text = content.filter((item) => item.type === \"text\").map((item) => item.text)\n messages.push({ role: \"tool\", tool_call_id: part.id, content: text.join(\"\\n\") })\n const files = content.filter((item) => item.type === \"file\")\n images.push(\n ...(yield* Effect.forEach(files, (item) =>\n lowerMedia({ type: \"media\", mediaType: item.mime, data: item.uri, filename: item.name }),\n )),\n )\n }\n return { messages, images }\n})\n\nconst lowerMessage = Effect.fn(\"OpenAIChat.lowerMessage\")(function* (message: OpenAIChatRequestMessage) {\n if (message.role === \"user\") return [yield* lowerUserMessage(message)]\n if (message.role === \"assistant\") return [yield* lowerAssistantMessage(message)]\n return (yield* lowerToolMessages(message)).messages\n})\n\nconst lowerMessages = Effect.fn(\"OpenAIChat.lowerMessages\")(function* (request: LLMRequest) {\n const system: OpenAIChatMessage[] =\n request.system.length === 0 ? [] : [{ role: \"system\", content: ProviderShared.joinText(request.system) }]\n const messages = [...system]\n const pendingImages: Array<Schema.Schema.Type<typeof OpenAIChatUserContent>> = []\n const flushImages = () => {\n if (pendingImages.length === 0) return\n messages.push({ role: \"user\", content: pendingImages.splice(0) })\n }\n for (const message of request.messages) {\n if (message.role === \"system\") {\n const part = yield* ProviderShared.wrappedSystemUpdate(\"OpenAI Chat\", message)\n if (pendingImages.length > 0) {\n messages.push({ role: \"user\", content: [...pendingImages.splice(0), { type: \"text\", text: part.text }] })\n continue\n }\n const previous = messages.at(-1)\n if (previous?.role === \"user\" && typeof previous.content === \"string\")\n messages[messages.length - 1] = { role: \"user\", content: `${previous.content}\\n${part.text}` }\n else if (previous?.role === \"user\" && Array.isArray(previous.content))\n messages[messages.length - 1] = {\n role: \"user\",\n content: [...previous.content, { type: \"text\", text: part.text }],\n }\n else messages.push({ role: \"user\", content: part.text })\n continue\n }\n if (message.role === \"tool\") {\n const lowered = yield* lowerToolMessages(message)\n messages.push(...lowered.messages)\n pendingImages.push(...lowered.images)\n continue\n }\n flushImages()\n messages.push(...(yield* lowerMessage(message)))\n }\n flushImages()\n return messages\n})\n\nconst lowerOptions = Effect.fn(\"OpenAIChat.lowerOptions\")(function* (request: LLMRequest) {\n const store = OpenAIOptions.store(request)\n const reasoningEffort = OpenAIOptions.reasoningEffort(request)\n return {\n ...(store !== undefined ? { store } : {}),\n ...(reasoningEffort ? { reasoning_effort: reasoningEffort } : {}),\n }\n})\n\nconst fromRequest = Effect.fn(\"OpenAIChat.fromRequest\")(function* (request: LLMRequest) {\n // `fromRequest` returns the provider body only. Endpoint, auth, framing,\n // validation, and HTTP execution are composed by `Route.make`.\n const generation = request.generation\n const toolSchemaCompatibility = request.model.compatibility?.toolSchema\n return {\n model: request.model.id,\n messages: yield* lowerMessages(request),\n tools:\n request.tools.length === 0\n ? undefined\n : request.tools.map((tool) =>\n lowerTool(tool, ToolSchemaProjection.modelCompatibility(tool.inputSchema, toolSchemaCompatibility)),\n ),\n tool_choice: request.toolChoice ? yield* lowerToolChoice(request.toolChoice) : undefined,\n stream: true as const,\n stream_options: { include_usage: true },\n max_tokens: generation?.maxTokens,\n temperature: generation?.temperature,\n top_p: generation?.topP,\n frequency_penalty: generation?.frequencyPenalty,\n presence_penalty: generation?.presencePenalty,\n seed: generation?.seed,\n stop: generation?.stop,\n ...(yield* lowerOptions(request)),\n }\n})\n\n// =============================================================================\n// Stream Parsing\n// =============================================================================\n// Streaming parsers are small state machines: every event returns a new state\n// plus the common `LLMEvent`s produced by that event. Tool calls are accumulated\n// because OpenAI streams JSON arguments across multiple deltas.\nconst mapFinishReason = (reason: string | null | undefined): FinishReason => {\n if (reason === \"stop\") return \"stop\"\n if (reason === \"length\") return \"length\"\n if (reason === \"content_filter\") return \"content-filter\"\n if (reason === \"function_call\" || reason === \"tool_calls\") return \"tool-calls\"\n return \"unknown\"\n}\n\n// OpenAI Chat reports `prompt_tokens` (inclusive total) with a\n// `cached_tokens` subset, and `completion_tokens` (inclusive total) with\n// a `reasoning_tokens` subset. We pass the inclusive totals through and\n// derive the non-cached breakdown so the `LLM.Usage` contract is\n// satisfied on both sides.\nconst mapUsage = (usage: OpenAIChatEvent[\"usage\"]): Usage | undefined => {\n if (!usage) return undefined\n const cached = usage.prompt_tokens_details?.cached_tokens\n const reasoning = usage.completion_tokens_details?.reasoning_tokens\n const nonCached = ProviderShared.subtractTokens(usage.prompt_tokens, cached)\n return new Usage({\n inputTokens: usage.prompt_tokens,\n outputTokens: usage.completion_tokens,\n nonCachedInputTokens: nonCached,\n cacheReadInputTokens: cached,\n reasoningTokens: reasoning,\n totalTokens: ProviderShared.totalTokens(usage.prompt_tokens, usage.completion_tokens, usage.total_tokens),\n providerMetadata: { openai: usage },\n })\n}\n\nconst step = (state: ParserState, event: OpenAIChatEvent) =>\n Effect.gen(function* () {\n const events: LLMEvent[] = []\n const usage = mapUsage(event.usage) ?? state.usage\n const choice = event.choices[0]\n const finishReason = choice?.finish_reason ? mapFinishReason(choice.finish_reason) : state.finishReason\n const delta = choice?.delta\n const toolDeltas = delta?.tool_calls ?? []\n let tools = state.tools\n\n let lifecycle = state.lifecycle\n\n if (delta?.reasoning_content)\n lifecycle = Lifecycle.reasoningDelta(lifecycle, events, \"reasoning-0\", delta.reasoning_content)\n\n if (delta?.content) {\n lifecycle = Lifecycle.reasoningEnd(lifecycle, events, \"reasoning-0\")\n lifecycle = Lifecycle.textDelta(lifecycle, events, \"text-0\", delta.content)\n }\n\n if (toolDeltas.length) lifecycle = Lifecycle.reasoningEnd(lifecycle, events, \"reasoning-0\")\n\n for (const tool of toolDeltas) {\n const result = ToolStream.appendOrStart(\n ADAPTER,\n tools,\n tool.index,\n { id: tool.id ?? undefined, name: tool.function?.name ?? undefined, text: tool.function?.arguments ?? \"\" },\n \"OpenAI Chat tool call delta is missing id or name\",\n )\n if (ToolStream.isError(result)) return yield* result\n tools = result.tools\n if (result.events.length) lifecycle = Lifecycle.stepStart(lifecycle, events)\n events.push(...result.events)\n }\n\n // Finalize accumulated tool inputs eagerly when finish_reason arrives so\n // JSON parse failures fail the stream at the boundary rather than at halt.\n const finished =\n finishReason !== undefined && state.finishReason === undefined && Object.keys(tools).length > 0\n ? yield* ToolStream.finishAll(ADAPTER, tools)\n : undefined\n\n return [\n {\n tools: finished?.tools ?? tools,\n toolCallEvents: finished?.events ?? state.toolCallEvents,\n usage,\n finishReason,\n lifecycle,\n },\n events,\n ] as const\n })\n\nconst finishEvents = (state: ParserState): ReadonlyArray<LLMEvent> => {\n const events: LLMEvent[] = []\n const hasToolCalls = state.toolCallEvents.length > 0\n const reason = state.finishReason === \"stop\" && hasToolCalls ? \"tool-calls\" : state.finishReason\n const lifecycle = state.toolCallEvents.length ? Lifecycle.stepStart(state.lifecycle, events) : state.lifecycle\n events.push(...state.toolCallEvents)\n if (reason) Lifecycle.finish(lifecycle, events, { reason, usage: state.usage })\n return events\n}\n\n// =============================================================================\n// Protocol And OpenAI Route\n// =============================================================================\n/**\n * The OpenAI Chat protocol — request body construction, body schema, and the\n * streaming-event state machine. Reused by every route that speaks OpenAI Chat\n * over HTTP+SSE: native OpenAI, DeepSeek, TogetherAI, Cerebras, Baseten,\n * Fireworks, DeepInfra, and (once added) Azure OpenAI Chat.\n */\nexport const protocol = Protocol.make({\n id: ADAPTER,\n body: {\n schema: OpenAIChatBody,\n from: fromRequest,\n },\n stream: {\n event: Protocol.jsonEvent(OpenAIChatEvent),\n initial: () => ({ tools: ToolStream.empty<number>(), toolCallEvents: [], lifecycle: Lifecycle.initial() }),\n step,\n onHalt: finishEvents,\n },\n})\n\nexport const httpTransport = HttpTransport.sseJson.with<OpenAIChatBody>()\n\nexport const route = Route.make({\n id: ADAPTER,\n provider: \"openai\",\n providerMetadataKey: \"openai\",\n protocol,\n endpoint: Endpoint.path(PATH, { baseURL: DEFAULT_BASE_URL }),\n auth: Auth.none,\n transport: httpTransport,\n})\n\nexport * as OpenAIChat from \"./openai-chat\"\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "23B209A1AF19695764756E2164756E21", | ||
| "names": [] | ||
| } |
Sorry, the diff of this file is too big to display
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/mcp/list.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"node:os\"\nimport { Effect } from \"effect\"\nimport { OpenCode, type McpServer } from \"@opencode-ai/client\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { ServiceConfig } from \"../../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.mcp.commands.list,\n Effect.fn(\"cli.mcp.list\")(function* () {\n const options = yield* ServiceConfig.options()\n const found = yield* Service.discover(options)\n const endpoint = found ?? (yield* Service.ensure(options))\n const client = OpenCode.make({ baseUrl: endpoint.url, headers: Service.headers(endpoint) })\n const response = yield* Effect.promise(() => client.mcp.list({ location: { directory: process.cwd() } }))\n const servers = response.data.toSorted((a, b) => a.name.localeCompare(b.name))\n if (servers.length === 0) {\n process.stdout.write(\"No MCP servers configured\" + EOL)\n return\n }\n const width = Math.max(...servers.map((server) => server.name.length))\n const lines = servers.map(\n (server) => `${icon(server.status)} ${server.name.padEnd(width)} ${describe(server.status)}`,\n )\n process.stdout.write(lines.join(EOL) + EOL)\n }),\n)\n\nfunction icon(status: McpServer[\"status\"]) {\n switch (status.status) {\n case \"connected\":\n return \"✓\"\n case \"needs_auth\":\n return \"⚠\"\n case \"failed\":\n case \"needs_client_registration\":\n return \"✗\"\n default:\n return \"○\"\n }\n}\n\nfunction describe(status: McpServer[\"status\"]) {\n switch (status.status) {\n case \"needs_auth\":\n return \"needs authentication\"\n case \"needs_client_registration\":\n return `needs client registration: ${status.error}`\n case \"failed\":\n return `failed: ${status.error}`\n default:\n return status.status\n }\n}\n" | ||
| ], | ||
| "mappings": ";83BAAA,mBAAS,gBAQT,SAAe,SAAQ,aACrB,OAAS,cAAS,SAAI,cAAS,UAC/B,OAAO,QAAG,mBAAc,OAAE,cAAU,OAAG,MACrC,SAAM,OAAU,WAAO,OAAc,aAAQ,OAEvC,GADQ,MAAO,EAAQ,SAAS,CAAO,KAClB,MAAO,EAAQ,OAAO,CAAO,GAClD,EAAS,EAAS,KAAK,CAAE,QAAS,EAAS,IAAK,QAAS,EAAQ,QAAQ,CAAQ,CAAE,CAAC,EAEpF,GADW,MAAO,EAAO,QAAQ,IAAM,EAAO,IAAI,KAAK,CAAE,SAAU,CAAE,UAAW,QAAQ,IAAI,CAAE,CAAE,CAAC,CAAC,GAC/E,KAAK,SAAS,CAAC,EAAG,IAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC,EAC7E,GAAI,EAAQ,SAAW,EAAG,CACxB,QAAQ,OAAO,MAAM,4BAA8B,CAAG,EACtD,OAEF,IAAM,EAAQ,KAAK,IAAI,GAAG,EAAQ,IAAI,CAAC,IAAW,EAAO,KAAK,MAAM,CAAC,EAC/D,EAAQ,EAAQ,IACpB,CAAC,IAAW,GAAG,EAAK,EAAO,MAAM,KAAK,EAAO,KAAK,OAAO,CAAK,MAAM,EAAS,EAAO,MAAM,GAC5F,EACA,QAAQ,OAAO,MAAM,EAAM,KAAK,CAAG,EAAI,CAAG,EAC3C,CACH,EAEA,SAAS,CAAI,CAAC,EAA6B,CACzC,OAAQ,EAAO,YACR,YACH,MAAO,aACJ,aACH,MAAO,aACJ,aACA,4BACH,MAAO,iBAEP,MAAO,UAIb,SAAS,CAAQ,CAAC,EAA6B,CAC7C,OAAQ,EAAO,YACR,aACH,MAAO,2BACJ,4BACH,MAAO,8BAA8B,EAAO,YACzC,SACH,MAAO,WAAW,EAAO,gBAEzB,OAAO,EAAO", | ||
| "debugId": "5577B2D4F97EA30064756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/mcp/add.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"node:os\"\nimport path from \"node:path\"\nimport { Effect, Option } from \"effect\"\nimport { applyEdits, modify } from \"jsonc-parser\"\nimport { Global } from \"@opencode-ai/core/global\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\n\nexport default Runtime.handler(\n Commands.commands.mcp.commands.add,\n Effect.fn(\"cli.mcp.add\")(function* (input) {\n const url = Option.getOrUndefined(input.url)\n const headers = Option.getOrUndefined(input.header)\n const environment = Option.getOrUndefined(input.env)\n // The CLI framework strands `--` operands on the root command, so read the local server command\n // straight from argv after `--`. This also lets the command carry its own flags (e.g. `npx -y`).\n const dash = process.argv.indexOf(\"--\")\n const command = dash === -1 ? [...input.command] : process.argv.slice(dash + 1)\n\n const hasCommand = command.length > 0\n if (url && hasCommand)\n return yield* Effect.fail(new Error(\"Provide either --url <url> or a command after --, not both\"))\n if (!url && !hasCommand) return yield* Effect.fail(new Error(\"Provide either --url <url> or a command after --\"))\n if (url && !URL.canParse(url)) return yield* Effect.fail(new Error(`Invalid URL: ${url}`))\n if (url && environment) return yield* Effect.fail(new Error(\"--env is only valid for local MCP servers\"))\n if (hasCommand && headers) return yield* Effect.fail(new Error(\"--header is only valid for remote MCP servers\"))\n\n const server = url\n ? { type: \"remote\" as const, url, ...(headers ? { headers } : {}) }\n : { type: \"local\" as const, command, ...(environment ? { environment } : {}) }\n\n const configPath = yield* Effect.promise(() => resolveConfigPath(input.global ? Global.Path.config : process.cwd()))\n yield* Effect.promise(() => write(configPath, input.name, server))\n process.stdout.write(`MCP server \"${input.name}\" added to ${configPath}` + EOL)\n }),\n)\n\nasync function resolveConfigPath(directory: string) {\n const candidates = [\n path.join(directory, \"opencode.json\"),\n path.join(directory, \"opencode.jsonc\"),\n path.join(directory, \".opencode\", \"opencode.json\"),\n path.join(directory, \".opencode\", \"opencode.jsonc\"),\n ]\n for (const candidate of candidates) {\n if (await Bun.file(candidate).exists()) return candidate\n }\n return candidates[0]\n}\n\nasync function write(configPath: string, name: string, server: unknown) {\n const file = Bun.file(configPath)\n const text = (await file.exists()) ? await file.text() : \"{}\"\n const edits = modify(text, [\"mcp\", \"servers\", name], server, {\n formattingOptions: { tabSize: 2, insertSpaces: true },\n })\n await Bun.write(configPath, applyEdits(text, edits))\n}\n" | ||
| ], | ||
| "mappings": ";yvBAAA,mBAAS,gBACT,yBAOA,SAAe,SAAQ,aACrB,OAAS,cAAS,SAAI,cAAS,SAC/B,OAAO,QAAG,kBAAa,OAAE,cAAU,MAAC,OAAO,MACzC,IAAM,EAAM,EAAO,eAAe,EAAM,GAAG,EACrC,EAAU,EAAO,eAAe,EAAM,MAAM,EAC5C,EAAc,EAAO,eAAe,EAAM,GAAG,EAG7C,EAAO,QAAQ,KAAK,QAAQ,IAAI,EAChC,EAAU,IAAS,GAAK,CAAC,GAAG,EAAM,OAAO,EAAI,QAAQ,KAAK,MAAM,EAAO,CAAC,EAExE,EAAa,EAAQ,OAAS,EACpC,GAAI,GAAO,EACT,OAAO,MAAO,EAAO,KAAS,MAAM,4DAA4D,CAAC,EACnG,GAAI,CAAC,GAAO,CAAC,EAAY,OAAO,MAAO,EAAO,KAAS,MAAM,kDAAkD,CAAC,EAChH,GAAI,GAAO,CAAC,IAAI,SAAS,CAAG,EAAG,OAAO,MAAO,EAAO,KAAS,MAAM,gBAAgB,GAAK,CAAC,EACzF,GAAI,GAAO,EAAa,OAAO,MAAO,EAAO,KAAS,MAAM,2CAA2C,CAAC,EACxG,GAAI,GAAc,EAAS,OAAO,MAAO,EAAO,KAAS,MAAM,+CAA+C,CAAC,EAE/G,IAAM,EAAS,EACX,CAAE,KAAM,SAAmB,SAAS,EAAU,CAAE,SAAQ,EAAI,CAAC,CAAG,EAChE,CAAE,KAAM,QAAkB,aAAa,EAAc,CAAE,aAAY,EAAI,CAAC,CAAG,EAEzE,EAAa,MAAO,EAAO,QAAQ,IAAM,EAAkB,EAAM,OAAS,EAAO,KAAK,OAAS,QAAQ,IAAI,CAAC,CAAC,EACnH,MAAO,EAAO,QAAQ,IAAM,EAAM,EAAY,EAAM,KAAM,CAAM,CAAC,EACjE,QAAQ,OAAO,MAAM,eAAe,EAAM,kBAAkB,IAAe,CAAG,EAC/E,CACH,EAEA,eAAe,CAAiB,CAAC,EAAmB,CAClD,IAAM,EAAa,CACjB,EAAK,KAAK,EAAW,eAAe,EACpC,EAAK,KAAK,EAAW,gBAAgB,EACrC,EAAK,KAAK,EAAW,YAAa,eAAe,EACjD,EAAK,KAAK,EAAW,YAAa,gBAAgB,CACpD,EACA,QAAW,KAAa,EACtB,GAAI,MAAM,IAAI,KAAK,CAAS,EAAE,OAAO,EAAG,OAAO,EAEjD,OAAO,EAAW,GAGpB,eAAe,CAAK,CAAC,EAAoB,EAAc,EAAiB,CACtE,IAAM,EAAO,IAAI,KAAK,CAAU,EAC1B,EAAQ,MAAM,EAAK,OAAO,EAAK,MAAM,EAAK,KAAK,EAAI,KACnD,EAAQ,EAAO,EAAM,CAAC,MAAO,UAAW,CAAI,EAAG,EAAQ,CAC3D,kBAAmB,CAAE,QAAS,EAAG,aAAc,EAAK,CACtD,CAAC,EACD,MAAM,IAAI,MAAM,EAAY,EAAW,EAAM,CAAK,CAAC", | ||
| "debugId": "2F63DD6101EF281264756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/mcp/logout.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"node:os\"\nimport { Effect } from \"effect\"\nimport { OpenCode } from \"@opencode-ai/client\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { ServiceConfig } from \"../../../services/service-config\"\nimport { resolveIntegration } from \"./resolve\"\n\nconst location = { directory: process.cwd() }\n\nexport default Runtime.handler(\n Commands.commands.mcp.commands.logout,\n Effect.fn(\"cli.mcp.logout\")(function* (input) {\n const options = yield* ServiceConfig.options()\n const found = yield* Service.discover(options)\n const endpoint = found ?? (yield* Service.ensure(options))\n const client = OpenCode.make({ baseUrl: endpoint.url, headers: Service.headers(endpoint) })\n\n const integration = yield* resolveIntegration(client, input.name, location)\n if (!integration) {\n process.stdout.write(`No stored credentials for ${input.name}` + EOL)\n return\n }\n\n const credentials = integration.connections.filter((connection) => connection.type === \"credential\")\n if (credentials.length === 0) {\n process.stdout.write(`No stored credentials for ${input.name}` + EOL)\n return\n }\n\n yield* Effect.forEach(\n credentials,\n (connection) => Effect.promise(() => client.credential.remove({ credentialID: connection.id, location })),\n { discard: true },\n )\n process.stdout.write(`Removed OAuth credentials for ${input.name}` + EOL)\n }),\n)\n" | ||
| ], | ||
| "mappings": ";46BAAA,mBAAS,gBAST,SAAM,OAAW,MAAE,eAAW,aAAQ,SAAI,MAAE,OAE7B,SAAQ,aACrB,OAAS,cAAS,SAAI,cAAS,YAC/B,OAAO,QAAG,qBAAgB,OAAE,cAAU,MAAC,OAAO,CAC5C,IAAM,EAAU,MAAO,EAAc,QAAQ,EAEvC,GADQ,MAAO,EAAQ,SAAS,CAAO,KAClB,MAAO,EAAQ,OAAO,CAAO,GAClD,EAAS,EAAS,KAAK,CAAE,QAAS,EAAS,IAAK,QAAS,EAAQ,QAAQ,CAAQ,CAAE,CAAC,EAEpF,EAAc,MAAO,EAAmB,EAAQ,EAAM,KAAM,CAAQ,EAC1E,GAAI,CAAC,EAAa,CAChB,QAAQ,OAAO,MAAM,6BAA6B,EAAM,OAAS,CAAG,EACpE,OAGF,IAAM,EAAc,EAAY,YAAY,OAAO,CAAC,IAAe,EAAW,OAAS,YAAY,EACnG,GAAI,EAAY,SAAW,EAAG,CAC5B,QAAQ,OAAO,MAAM,6BAA6B,EAAM,OAAS,CAAG,EACpE,OAGF,MAAO,EAAO,QACZ,EACA,CAAC,IAAe,EAAO,QAAQ,IAAM,EAAO,WAAW,OAAO,CAAE,aAAc,EAAW,GAAI,UAAS,CAAC,CAAC,EACxG,CAAE,QAAS,EAAK,CAClB,EACA,QAAQ,OAAO,MAAM,iCAAiC,EAAM,OAAS,CAAG,EACzE,CACH", | ||
| "debugId": "128E986EA0F6A45764756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/api.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"node:os\"\nimport { Effect, Option } from \"effect\"\nimport { Commands } from \"../commands\"\nimport { Runtime } from \"../../framework/runtime\"\nimport { Service, type Endpoint } from \"@opencode-ai/client/effect/service\"\nimport { ServerConnection } from \"../../services/server-connection\"\n\nconst methods = new Set([\"delete\", \"get\", \"head\", \"options\", \"patch\", \"post\", \"put\"])\n\ntype Operation = {\n operationId?: string\n}\n\ntype OpenApi = {\n paths?: Record<string, Record<string, Operation>>\n}\n\nexport default Runtime.handler(\n Commands.commands.api,\n Effect.fn(\"cli.api\")(function* (input) {\n const server = yield* ServerConnection.resolve({\n server: Option.getOrUndefined(input.server),\n standalone: input.standalone,\n mismatch: \"ignore\",\n })\n const endpoint = server.endpoint\n const params = Option.getOrElse(input.param, () => ({}))\n const request = yield* resolveRequest(endpoint, input.request, params)\n const headers = new Headers(Service.headers(endpoint))\n for (const header of input.header) {\n const index = header.indexOf(\":\")\n if (index < 1) return yield* Effect.fail(new Error(`Invalid header, expected name:value: ${header}`))\n headers.set(header.slice(0, index).trim(), header.slice(index + 1).trim())\n }\n const body = Option.getOrUndefined(input.data)\n if (body !== undefined && !headers.has(\"content-type\")) headers.set(\"content-type\", \"application/json\")\n\n const response = yield* Effect.tryPromise(() =>\n fetch(new URL(request.path, endpoint.url), {\n method: request.method,\n headers,\n body,\n }),\n )\n const output = yield* Effect.promise(() => response.text())\n if (output) process.stdout.write(output + (output.endsWith(EOL) ? \"\" : EOL))\n }),\n)\n\nexport function resolveOperation(spec: OpenApi, operationID: string, params: Record<string, string>) {\n for (const [path, operations] of Object.entries(spec.paths ?? {})) {\n for (const [method, operation] of Object.entries(operations)) {\n if (!methods.has(method) || operation.operationId !== operationID) continue\n return { method: method.toUpperCase(), path: interpolate(path, params) }\n }\n }\n throw new Error(`Operation not found: ${operationID}`)\n}\n\nexport function rawRequest(input: readonly string[]) {\n if (input.length !== 2 || !methods.has(input[0].toLowerCase()) || !input[1].startsWith(\"/\")) return\n return { method: input[0].toUpperCase(), path: input[1] }\n}\n\nfunction resolveRequest(endpoint: Endpoint, input: readonly string[], params: Record<string, string>) {\n const raw = rawRequest(input)\n if (raw) return Effect.succeed(raw)\n if (input.length !== 1) return Effect.fail(new Error(\"Expected an operation name or an HTTP method and path\"))\n return Effect.tryPromise(async () => {\n const response = await fetch(new URL(\"/openapi.json\", endpoint.url), { headers: Service.headers(endpoint) })\n if (!response.ok) throw new Error(`Failed to load OpenAPI document: HTTP ${response.status}`)\n return resolveOperation((await response.json()) as OpenApi, input[0], params)\n })\n}\n\nfunction interpolate(path: string, params: Record<string, string>) {\n const used = new Set<string>()\n const pathname = path.replaceAll(/\\{([^}]+)\\}/g, (_, name: string) => {\n const value = params[name]\n if (value === undefined) throw new Error(`Missing path parameter: ${name}`)\n used.add(name)\n return encodeURIComponent(value)\n })\n const query = new URLSearchParams(Object.entries(params).filter(([name]) => !used.has(name))).toString()\n return query ? `${pathname}?${query}` : pathname\n}\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "EFE42F8AE6803A2564756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/mini.ts"], | ||
| "sourcesContent": [ | ||
| "import { Effect, Option } from \"effect\"\nimport { Commands } from \"../commands\"\nimport { Runtime } from \"../../framework/runtime\"\nimport { ServerConnection } from \"../../services/server-connection\"\n\nexport default Runtime.handler(Commands.commands.mini, (input) =>\n Effect.gen(function* () {\n const { runMini, validateMiniTerminal } = yield* Effect.promise(() => import(\"../../mini\"))\n yield* Effect.promise(async () => validateMiniTerminal())\n const serverURL = Option.getOrUndefined(input.server)\n const server = yield* ServerConnection.resolve({ server: serverURL, standalone: input.standalone })\n yield* Effect.promise(() =>\n runMini({\n server,\n continue: input.continue,\n session: Option.getOrUndefined(input.session),\n fork: input.fork,\n model: Option.getOrUndefined(input.model),\n agent: Option.getOrUndefined(input.agent),\n prompt: Option.getOrUndefined(input.prompt),\n replay: input.replay,\n replayLimit: Option.getOrUndefined(input.replayLimit),\n demo: input.demo,\n }),\n )\n }),\n)\n" | ||
| ], | ||
| "mappings": ";+uCAKA,SAAe,SAAQ,aAAQ,OAAS,cAAS,UAAM,MAAC,SACtD,OAAO,SAAI,cAAU,OAAG,MACtB,SAAQ,eAAS,6BAAyB,WAAO,OAAO,aAAQ,SAAa,wCAAa,OAC1F,WAAO,OAAO,aAAQ,cAAY,OAAqB,MAAC,OACxD,SAAM,OAAY,OAAO,oBAAe,OAAM,WAAM,EAC9C,EAAS,MAAO,EAAiB,QAAQ,CAAE,OAAQ,EAAW,WAAY,EAAM,UAAW,CAAC,EAClG,MAAO,EAAO,QAAQ,IACpB,EAAQ,CACN,SACA,SAAU,EAAM,SAChB,QAAS,EAAO,eAAe,EAAM,OAAO,EAC5C,KAAM,EAAM,KACZ,MAAO,EAAO,eAAe,EAAM,KAAK,EACxC,MAAO,EAAO,eAAe,EAAM,KAAK,EACxC,OAAQ,EAAO,eAAe,EAAM,MAAM,EAC1C,OAAQ,EAAM,OACd,YAAa,EAAO,eAAe,EAAM,WAAW,EACpD,KAAM,EAAM,IACd,CAAC,CACH,EACD,CACH", | ||
| "debugId": "A547F1F6415682CA64756E2164756E21", | ||
| "names": [] | ||
| } |
Sorry, the diff of this file is too big to display
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/pair.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"os\"\nimport { Effect } from \"effect\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { OpenCode } from \"@opencode-ai/client/promise\"\nimport { renderUnicodeCompact } from \"uqr\"\nimport { Commands } from \"../commands\"\nimport { Runtime } from \"../../framework/runtime\"\nimport { ServiceConfig } from \"../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.pair,\n Effect.fn(\"cli.pair\")(function* () {\n const endpoint = yield* Service.ensure(yield* ServiceConfig.options())\n const password = yield* ServiceConfig.password()\n const server = yield* Effect.tryPromise(() =>\n OpenCode.make({ baseUrl: endpoint.url, headers: Service.headers(endpoint) }).server.get(),\n )\n const info = { urls: server.urls, username: \"opencode\", password }\n process.stdout.write(\n [\n \"\",\n ` URLs ${info.urls[0] ?? \"(none)\"}`,\n ...info.urls.slice(1).map((url) => ` ${url}`),\n ` Username ${info.username}`,\n ` Password ${info.password}`,\n \"\",\n \" Scan to pair\",\n \"\",\n renderUnicodeCompact(JSON.stringify(info), { border: 2 })\n .split(EOL)\n .map((line) => \" \" + line)\n .join(EOL),\n \"\",\n ].join(EOL) + EOL,\n )\n\n const hostname = new URL(endpoint.url).hostname\n if (![\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(hostname)) return\n process.stderr.write(\n ` Run \\`opencode service set hostname 0.0.0.0\\` to access the service remotely.${EOL}${EOL}`,\n )\n }),\n)\n" | ||
| ], | ||
| "mappings": ";46BAAA,mBAAS,gBAST,SAAe,SAAQ,aACrB,OAAS,cAAS,UAClB,OAAO,QAAG,eAAU,OAAE,cAAU,OAAG,MACjC,SAAM,OAAW,WAAO,OAAQ,YAAO,WAAO,OAAc,aAAQ,MAAC,EAC/D,EAAW,MAAO,EAAc,SAAS,EAIzC,EAAO,CAAE,MAHA,MAAO,EAAO,WAAW,IACtC,EAAS,KAAK,CAAE,QAAS,EAAS,IAAK,QAAS,EAAQ,QAAQ,CAAQ,CAAE,CAAC,EAAE,OAAO,IAAI,CAC1F,GAC4B,KAAM,SAAU,WAAY,UAAS,EACjE,QAAQ,OAAO,MACb,CACE,GACA,eAAe,EAAK,KAAK,IAAM,WAC/B,GAAG,EAAK,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,IAAQ,eAAe,GAAK,EACvD,eAAe,EAAK,WACpB,eAAe,EAAK,WACpB,GACA,iBACA,GACA,EAAqB,KAAK,UAAU,CAAI,EAAG,CAAE,OAAQ,CAAE,CAAC,EACrD,MAAM,CAAG,EACT,IAAI,CAAC,IAAS,KAAO,CAAI,EACzB,KAAK,CAAG,EACX,EACF,EAAE,KAAK,CAAG,EAAI,CAChB,EAEA,IAAM,EAAW,IAAI,IAAI,EAAS,GAAG,EAAE,SACvC,GAAI,CAAC,CAAC,YAAa,YAAa,OAAO,EAAE,SAAS,CAAQ,EAAG,OAC7D,QAAQ,OAAO,MACb,kFAAkF,IAAM,GAC1F,EACD,CACH", | ||
| "debugId": "9E845DD8991BA77364756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/service/status.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"os\"\nimport { Effect } from \"effect\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { ServiceConfig } from \"../../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.service.commands.status,\n Effect.fn(\"cli.service.status\")(function* () {\n const options = yield* ServiceConfig.options()\n const found = yield* Service.discover({ ...options, version: undefined })\n process.stdout.write((found?.url ?? \"stopped\") + EOL)\n }),\n)\n" | ||
| ], | ||
| "mappings": ";+0BAAA,mBAAS,gBAOT,SAAe,SAAQ,aACrB,OAAS,cAAS,aAAQ,cAAS,YACnC,OAAO,QAAG,yBAAoB,OAAE,cAAU,OAAG,MAC3C,SAAM,OAAU,WAAO,OAAc,aAAQ,EACvC,EAAQ,MAAO,EAAQ,SAAS,IAAK,EAAS,QAAS,MAAU,CAAC,EACxE,QAAQ,OAAO,OAAO,GAAO,KAAO,WAAa,CAAG,EACrD,CACH", | ||
| "debugId": "5FF059D372C6D11E64756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["../../node_modules/.bun/mime-types@3.0.2/node_modules/mime-types/mimeScore.js", "../core/src/fs-util.ts", "../../node_modules/.bun/mime-types@3.0.2/node_modules/mime-types/index.js", "../core/src/effect/service-use.ts"], | ||
| "sourcesContent": [ | ||
| "// 'mime-score' back-ported to CommonJS\n\n// Score RFC facets (see https://tools.ietf.org/html/rfc6838#section-3)\nvar FACET_SCORES = {\n 'prs.': 100,\n 'x-': 200,\n 'x.': 300,\n 'vnd.': 400,\n default: 900\n}\n\n// Score mime source (Logic originally from `jshttp/mime-types` module)\nvar SOURCE_SCORES = {\n nginx: 10,\n apache: 20,\n iana: 40,\n default: 30 // definitions added by `jshttp/mime-db` project?\n}\n\nvar TYPE_SCORES = {\n // prefer application/xml over text/xml\n // prefer application/rtf over text/rtf\n application: 1,\n\n // prefer font/woff over application/font-woff\n font: 2,\n\n // prefer video/mp4 over audio/mp4 over application/mp4\n // See https://www.rfc-editor.org/rfc/rfc4337.html#section-2\n audio: 2,\n video: 3,\n\n default: 0\n}\n\n/**\n * Get each component of the score for a mime type. The sum of these is the\n * total score. The higher the score, the more \"official\" the type.\n */\nmodule.exports = function mimeScore (mimeType, source = 'default') {\n if (mimeType === 'application/octet-stream') {\n return 0\n }\n\n const [type, subtype] = mimeType.split('/')\n\n const facet = subtype.replace(/(\\.|x-).*/, '$1')\n\n const facetScore = FACET_SCORES[facet] || FACET_SCORES.default\n const sourceScore = SOURCE_SCORES[source] || SOURCE_SCORES.default\n const typeScore = TYPE_SCORES[type] || TYPE_SCORES.default\n\n // All else being equal prefer shorter types\n const lengthScore = 1 - mimeType.length / 100\n\n return facetScore + sourceScore + typeScore + lengthScore\n}\n", | ||
| "import { NodeFileSystem } from \"@effect/platform-node\"\nimport path, { dirname, isAbsolute, join, relative, sep } from \"path\"\nimport { realpathSync } from \"fs\"\nimport { readdir } from \"fs/promises\"\nimport { lookup } from \"mime-types\"\nimport { Context, Effect, FileSystem, Layer, Schema } from \"effect\"\nimport type { PlatformError } from \"effect/PlatformError\"\nimport { Glob } from \"./util/glob\"\nimport { serviceUse } from \"./effect/service-use\"\nimport { makeGlobalNode } from \"./effect/app-node\"\nimport { filesystem } from \"./effect/app-node-platform\"\n\nexport namespace FSUtil {\n export class FileSystemError extends Schema.TaggedErrorClass<FileSystemError>()(\"FileSystemError\", {\n method: Schema.String,\n cause: Schema.optional(Schema.Defect()),\n }) {\n override get message() {\n const detail = this.cause instanceof Error ? this.cause.message : this.cause && String(this.cause)\n return `Filesystem operation failed: ${this.method}${detail ? `: ${detail}` : \"\"}`\n }\n }\n\n export type Error = PlatformError | FileSystemError\n\n export interface DirEntry {\n readonly name: string\n readonly type: \"file\" | \"directory\" | \"symlink\" | \"other\"\n }\n\n export interface Interface extends FileSystem.FileSystem {\n readonly isDir: (path: string) => Effect.Effect<boolean>\n readonly isFile: (path: string) => Effect.Effect<boolean>\n readonly existsSafe: (path: string) => Effect.Effect<boolean>\n readonly readFileStringSafe: (path: string) => Effect.Effect<string | undefined, Error>\n readonly readJson: (path: string) => Effect.Effect<unknown, Error>\n readonly writeJson: (path: string, data: unknown, mode?: number) => Effect.Effect<void, Error>\n readonly ensureDir: (path: string) => Effect.Effect<void, Error>\n readonly writeWithDirs: (path: string, content: string | Uint8Array, mode?: number) => Effect.Effect<void, Error>\n readonly readDirectoryEntries: (path: string) => Effect.Effect<DirEntry[], Error>\n readonly resolve: (path: string) => Effect.Effect<string>\n readonly findUp: (target: string, start: string, stop?: string) => Effect.Effect<string[], Error>\n readonly up: (options: { targets: string[]; start: string; stop?: string }) => Effect.Effect<string[], Error>\n readonly globUp: (pattern: string, start: string, stop?: string) => Effect.Effect<string[], Error>\n readonly glob: (pattern: string, options?: Glob.Options) => Effect.Effect<string[], Error>\n readonly globMatch: (pattern: string, filepath: string) => boolean\n }\n\n export class Service extends Context.Service<Service, Interface>()(\"@opencode/FileSystem\") {}\n\n export const use = serviceUse(Service)\n\n // Exported so simulation can wrap this layer and override the methods that\n // bypass the injected FileSystem (readDirectoryEntries, glob, globUp).\n export const layer = Layer.effect(\n Service,\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem\n\n const existsSafe = Effect.fn(\"FileSystem.existsSafe\")(function* (path: string) {\n return yield* fs.exists(path).pipe(Effect.orElseSucceed(() => false))\n })\n\n const readFileStringSafe = Effect.fn(\"FileSystem.readFileStringSafe\")(function* (path: string) {\n return yield* fs.readFileString(path).pipe(\n Effect.catchReason(\"PlatformError\", \"NotFound\", () => Effect.succeed(undefined)),\n Effect.catchReason(\"PlatformError\", \"PermissionDenied\", () => Effect.succeed(undefined)),\n )\n })\n\n const isDir = Effect.fn(\"FileSystem.isDir\")(function* (path: string) {\n const info = yield* fs.stat(path).pipe(Effect.catch(() => Effect.void))\n return info?.type === \"Directory\"\n })\n\n const isFile = Effect.fn(\"FileSystem.isFile\")(function* (path: string) {\n const info = yield* fs.stat(path).pipe(Effect.catch(() => Effect.void))\n return info?.type === \"File\"\n })\n\n const readDirectoryEntries = Effect.fn(\"FileSystem.readDirectoryEntries\")(function* (dirPath: string) {\n return yield* Effect.tryPromise({\n try: async () => {\n const entries = await readdir(dirPath, { withFileTypes: true })\n return entries.map(\n (e): DirEntry => ({\n name: e.name,\n type: e.isDirectory() ? \"directory\" : e.isSymbolicLink() ? \"symlink\" : e.isFile() ? \"file\" : \"other\",\n }),\n )\n },\n catch: (cause) => new FileSystemError({ method: \"readDirectoryEntries\", cause }),\n })\n })\n\n const resolve = Effect.fn(\"FileSystem.resolve\")(function* (input: string) {\n const resolved = path.resolve(windowsPath(input))\n return yield* fs.realPath(resolved).pipe(\n Effect.catchReason(\"PlatformError\", \"NotFound\", () => Effect.succeed(resolved)),\n Effect.orDie,\n )\n })\n\n const readJson = Effect.fn(\"FileSystem.readJson\")(function* (path: string) {\n const text = yield* fs.readFileString(path)\n return yield* Effect.try({\n try: () => JSON.parse(text),\n catch: (cause) => new FileSystemError({ method: \"readJson\", cause }),\n })\n })\n\n const writeJson = Effect.fn(\"FileSystem.writeJson\")(function* (path: string, data: unknown, mode?: number) {\n const content = JSON.stringify(data, null, 2)\n yield* fs.writeFileString(path, content)\n if (mode) yield* fs.chmod(path, mode)\n })\n\n const ensureDir = Effect.fn(\"FileSystem.ensureDir\")(function* (path: string) {\n yield* fs.makeDirectory(path, { recursive: true })\n })\n\n const writeWithDirs = Effect.fn(\"FileSystem.writeWithDirs\")(function* (\n path: string,\n content: string | Uint8Array,\n mode?: number,\n ) {\n const write = typeof content === \"string\" ? fs.writeFileString(path, content) : fs.writeFile(path, content)\n\n yield* write.pipe(\n Effect.catchIf(\n (e) => e.reason._tag === \"NotFound\",\n () =>\n Effect.gen(function* () {\n yield* fs.makeDirectory(dirname(path), { recursive: true })\n yield* write\n }),\n ),\n )\n if (mode) yield* fs.chmod(path, mode)\n })\n\n const glob = Effect.fn(\"FileSystem.glob\")(function* (pattern: string, options?: Glob.Options) {\n return yield* Effect.tryPromise({\n try: () => Glob.scan(pattern, options),\n catch: (cause) => new FileSystemError({ method: \"glob\", cause }),\n })\n })\n\n const findUp = Effect.fn(\"FileSystem.findUp\")(function* (target: string, start: string, stop?: string) {\n const result: string[] = []\n let current = start\n while (true) {\n const search = join(current, target)\n if (yield* fs.exists(search)) result.push(search)\n if (stop === current) break\n const parent = dirname(current)\n if (parent === current) break\n current = parent\n }\n return result\n })\n\n const up = Effect.fn(\"FileSystem.up\")(function* (options: { targets: string[]; start: string; stop?: string }) {\n const result: string[] = []\n let current = options.start\n while (true) {\n for (const target of options.targets) {\n const search = join(current, target)\n if (yield* fs.exists(search)) result.push(search)\n }\n if (options.stop === current) break\n const parent = dirname(current)\n if (parent === current) break\n current = parent\n }\n return result\n })\n\n const globUp = Effect.fn(\"FileSystem.globUp\")(function* (pattern: string, start: string, stop?: string) {\n const result: string[] = []\n let current = start\n while (true) {\n const matches = yield* glob(pattern, { cwd: current, absolute: true, include: \"file\", dot: true }).pipe(\n Effect.catch(() => Effect.succeed([] as string[])),\n )\n result.push(...matches)\n if (stop === current) break\n const parent = dirname(current)\n if (parent === current) break\n current = parent\n }\n return result\n })\n\n return Service.of({\n ...fs,\n existsSafe,\n readFileStringSafe,\n isDir,\n isFile,\n readDirectoryEntries,\n resolve,\n readJson,\n writeJson,\n ensureDir,\n writeWithDirs,\n findUp,\n up,\n globUp,\n glob,\n globMatch: Glob.match,\n })\n }),\n )\n\n export const node = makeGlobalNode({ service: Service, layer: layer, deps: [filesystem] })\n\n // Pure helpers that don't need Effect (path manipulation, sync operations)\n export function mimeType(p: string): string {\n return lookup(p) || \"application/octet-stream\"\n }\n\n export function normalizePath(p: string): string {\n if (process.platform !== \"win32\") return p\n const resolved = path.resolve(windowsPath(p))\n try {\n return realpathSync.native(resolved)\n } catch {\n return resolved\n }\n }\n\n export function normalizePathPattern(p: string): string {\n if (process.platform !== \"win32\") return p\n if (p === \"*\") return p\n const match = p.match(/^(.*)[\\\\/]\\*$/)\n if (!match) return normalizePath(p)\n const dir = /^[A-Za-z]:$/.test(match[1]) ? match[1] + \"\\\\\" : match[1]\n return join(normalizePath(dir), \"*\")\n }\n\n export function resolve(p: string): string {\n const resolved = path.resolve(windowsPath(p))\n try {\n return normalizePath(realpathSync(resolved))\n } catch (e: any) {\n if (e?.code === \"ENOENT\") return normalizePath(resolved)\n throw e\n }\n }\n\n export function windowsPath(p: string): string {\n if (process.platform !== \"win32\") return p\n return p\n .replace(/^\\/([a-zA-Z]):(?:[\\\\/]|$)/, (_, drive) => `${drive.toUpperCase()}:/`)\n .replace(/^\\/([a-zA-Z])(?:\\/|$)/, (_, drive) => `${drive.toUpperCase()}:/`)\n .replace(/^\\/cygdrive\\/([a-zA-Z])(?:\\/|$)/, (_, drive) => `${drive.toUpperCase()}:/`)\n .replace(/^\\/mnt\\/([a-zA-Z])(?:\\/|$)/, (_, drive) => `${drive.toUpperCase()}:/`)\n }\n\n export function overlaps(a: string, b: string) {\n return contains(a, b) || contains(b, a)\n }\n\n export function contains(parent: string, child: string) {\n const result = relative(parent, child)\n return result === \"\" || (!isAbsolute(result) && result !== \"..\" && !result.startsWith(`..${sep}`))\n }\n}\n", | ||
| "/*!\n * mime-types\n * Copyright(c) 2014 Jonathan Ong\n * Copyright(c) 2015 Douglas Christopher Wilson\n * MIT Licensed\n */\n\n'use strict'\n\n/**\n * Module dependencies.\n * @private\n */\n\nvar db = require('mime-db')\nvar extname = require('path').extname\nvar mimeScore = require('./mimeScore')\n\n/**\n * Module variables.\n * @private\n */\n\nvar EXTRACT_TYPE_REGEXP = /^\\s*([^;\\s]*)(?:;|\\s|$)/\nvar TEXT_TYPE_REGEXP = /^text\\//i\n\n/**\n * Module exports.\n * @public\n */\n\nexports.charset = charset\nexports.charsets = { lookup: charset }\nexports.contentType = contentType\nexports.extension = extension\nexports.extensions = Object.create(null)\nexports.lookup = lookup\nexports.types = Object.create(null)\nexports._extensionConflicts = []\n\n// Populate the extensions/types maps\npopulateMaps(exports.extensions, exports.types)\n\n/**\n * Get the default charset for a MIME type.\n *\n * @param {string} type\n * @return {false|string}\n */\n\nfunction charset (type) {\n if (!type || typeof type !== 'string') {\n return false\n }\n\n // TODO: use media-typer\n var match = EXTRACT_TYPE_REGEXP.exec(type)\n var mime = match && db[match[1].toLowerCase()]\n\n if (mime && mime.charset) {\n return mime.charset\n }\n\n // default text/* to utf-8\n if (match && TEXT_TYPE_REGEXP.test(match[1])) {\n return 'UTF-8'\n }\n\n return false\n}\n\n/**\n * Create a full Content-Type header given a MIME type or extension.\n *\n * @param {string} str\n * @return {false|string}\n */\n\nfunction contentType (str) {\n // TODO: should this even be in this module?\n if (!str || typeof str !== 'string') {\n return false\n }\n\n var mime = str.indexOf('/') === -1 ? exports.lookup(str) : str\n\n if (!mime) {\n return false\n }\n\n // TODO: use content-type or other module\n if (mime.indexOf('charset') === -1) {\n var charset = exports.charset(mime)\n if (charset) mime += '; charset=' + charset.toLowerCase()\n }\n\n return mime\n}\n\n/**\n * Get the default extension for a MIME type.\n *\n * @param {string} type\n * @return {false|string}\n */\n\nfunction extension (type) {\n if (!type || typeof type !== 'string') {\n return false\n }\n\n // TODO: use media-typer\n var match = EXTRACT_TYPE_REGEXP.exec(type)\n\n // get extensions\n var exts = match && exports.extensions[match[1].toLowerCase()]\n\n if (!exts || !exts.length) {\n return false\n }\n\n return exts[0]\n}\n\n/**\n * Lookup the MIME type for a file path/extension.\n *\n * @param {string} path\n * @return {false|string}\n */\n\nfunction lookup (path) {\n if (!path || typeof path !== 'string') {\n return false\n }\n\n // get the extension (\"ext\" or \".ext\" or full path)\n var extension = extname('x.' + path)\n .toLowerCase()\n .slice(1)\n\n if (!extension) {\n return false\n }\n\n return exports.types[extension] || false\n}\n\n/**\n * Populate the extensions and types maps.\n * @private\n */\n\nfunction populateMaps (extensions, types) {\n Object.keys(db).forEach(function forEachMimeType (type) {\n var mime = db[type]\n var exts = mime.extensions\n\n if (!exts || !exts.length) {\n return\n }\n\n // mime -> extensions\n extensions[type] = exts\n\n // extension -> mime\n for (var i = 0; i < exts.length; i++) {\n var extension = exts[i]\n types[extension] = _preferredType(extension, types[extension], type)\n\n // DELETE (eventually): Capture extension->type maps that change as a\n // result of switching to mime-score. This is just to help make reviewing\n // PR #119 easier, and can be removed once that PR is approved.\n const legacyType = _preferredTypeLegacy(\n extension,\n types[extension],\n type\n )\n if (legacyType !== types[extension]) {\n exports._extensionConflicts.push([extension, legacyType, types[extension]])\n }\n }\n })\n}\n\n// Resolve type conflict using mime-score\nfunction _preferredType (ext, type0, type1) {\n var score0 = type0 ? mimeScore(type0, db[type0].source) : 0\n var score1 = type1 ? mimeScore(type1, db[type1].source) : 0\n\n return score0 > score1 ? type0 : type1\n}\n\n// Resolve type conflict using pre-mime-score logic\nfunction _preferredTypeLegacy (ext, type0, type1) {\n var SOURCE_RANK = ['nginx', 'apache', undefined, 'iana']\n\n var score0 = type0 ? SOURCE_RANK.indexOf(db[type0].source) : 0\n var score1 = type1 ? SOURCE_RANK.indexOf(db[type1].source) : 0\n\n if (\n exports.types[extension] !== 'application/octet-stream' &&\n (score0 > score1 ||\n (score0 === score1 &&\n exports.types[extension]?.slice(0, 12) === 'application/'))\n ) {\n return type0\n }\n\n return score0 > score1 ? type0 : type1\n}\n", | ||
| "import { Context, Effect } from \"effect\"\n\ntype EffectMethod = (...args: ReadonlyArray<never>) => Effect.Effect<unknown, unknown, unknown>\n\ntype ServiceUse<Identifier, Shape> = {\n readonly [Key in keyof Shape as Shape[Key] extends EffectMethod ? Key : never]: Shape[Key] extends (\n ...args: infer Args\n ) => infer Return\n ? Args extends ReadonlyArray<unknown>\n ? Return extends Effect.Effect<infer A, infer E, infer R>\n ? (...args: Args) => Effect.Effect<A, E, R | Identifier>\n : never\n : never\n : never\n}\n\nexport const serviceUse = <Identifier, Shape>(tag: Context.Service<Identifier, Shape>) => {\n const cache = new Map<string, (...args: unknown[]) => Effect.Effect<unknown, unknown, unknown>>()\n // This is the only dynamic boundary: TypeScript knows the accessor shape,\n // but Proxy property names are runtime values.\n const access = new Proxy(\n {},\n {\n get: (_, key) => {\n if (typeof key !== \"string\") return undefined\n const cached = cache.get(key)\n if (cached) return cached\n const accessor = (...args: unknown[]) =>\n tag.use((service) => {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- Proxy keys are checked at runtime.\n const method = service[key as keyof Shape]\n if (typeof method !== \"function\") return Effect.die(new Error(`Service method not found: ${key}`))\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- ServiceUse exposes only Effect-returning methods.\n return (method as (...args: unknown[]) => Effect.Effect<unknown, unknown, unknown>)(...args)\n })\n cache.set(key, accessor)\n return accessor\n },\n },\n )\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- Proxy implements the mapped accessor surface lazily.\n return access as ServiceUse<Identifier, Shape>\n}\n" | ||
| ], | ||
| "mappings": ";2zlJAGA,SAAI,OAAe,MACjB,YAAQ,IACR,KAAM,IACN,KAAM,IACN,OAAQ,IACR,QAAS,GACX,EAGI,EAAgB,CAClB,MAAO,GACP,OAAQ,GACR,KAAM,GACN,QAAS,EACX,EAEI,EAAc,CAGhB,YAAa,EAGb,KAAM,EAIN,MAAO,EACP,MAAO,EAEP,QAAS,CACX,EAMA,EAAO,QAAU,QAAmB,CAAC,EAAU,EAAS,UAAW,CACjE,GAAI,IAAa,2BACf,MAAO,GAGT,IAAO,EAAM,GAAW,EAAS,MAAM,GAAG,EAEpC,EAAQ,EAAQ,QAAQ,YAAa,IAAI,EAEzC,EAAa,EAAa,IAAU,EAAa,QACjD,EAAc,EAAc,IAAW,EAAc,QACrD,EAAY,EAAY,IAAS,EAAY,QAG7C,EAAc,EAAI,EAAS,OAAS,IAE1C,OAAO,EAAa,EAAc,EAAY,KCtDhD,qBAAe,gBAAS,WAAY,cAAM,UAAU,cACpD,uBAAS,WACT,kBAAS,qBCIT;AAAA;AAAA;AAAA;AAAA;AAAA,GAOA,IAAI,MACA,cAA0B,QAC1B,MAOA,GAAsB,0BAY1B,IAAQ,EAAa,OAAO,OAAO,IAAI,EAC/B,EAAS,GACT,EAAQ,OAAO,OAAO,IAAI,EAC1B,EAAsB,CAAC,EAG/B,GAAqB,EAAoB,CAAK,EAiE9C,SAAS,CAAU,CAAC,EAAM,CACxB,GAAI,CAAC,GAAQ,OAAO,IAAS,SAC3B,MAAO,GAIT,IAAI,EAAQ,GAAoB,KAAK,CAAI,EAGrC,EAAO,GAAiB,EAAW,EAAM,GAAG,YAAY,GAE5D,GAAI,CAAC,GAAQ,CAAC,EAAK,OACjB,MAAO,GAGT,OAAO,EAAK,GAUd,SAAS,EAAO,CAAC,EAAM,CACrB,GAAI,CAAC,GAAQ,OAAO,IAAS,SAC3B,MAAO,GAIT,IAAI,EAAY,GAAQ,KAAO,CAAI,EAChC,YAAY,EACZ,MAAM,CAAC,EAEV,GAAI,CAAC,EACH,MAAO,GAGT,OAAe,EAAM,IAAc,GAQrC,SAAS,EAAa,CAAC,EAAY,EAAO,CACxC,OAAO,KAAK,CAAE,EAAE,QAAQ,QAAyB,CAAC,EAAM,CACtD,IAAI,EAAO,EAAG,GACV,EAAO,EAAK,WAEhB,GAAI,CAAC,GAAQ,CAAC,EAAK,OACjB,OAIF,EAAW,GAAQ,EAGnB,QAAS,EAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,CACpC,IAAI,EAAY,EAAK,GACrB,EAAM,GAAa,GAAe,EAAW,EAAM,GAAY,CAAI,EAKnE,IAAM,EAAa,GACjB,EACA,EAAM,GACN,CACF,EACA,GAAI,IAAe,EAAM,GACf,EAAoB,KAAK,CAAC,EAAW,EAAY,EAAM,EAAU,CAAC,GAG/E,EAIH,SAAS,EAAe,CAAC,EAAK,EAAO,EAAO,CAC1C,IAAI,EAAS,EAAQ,EAAU,EAAO,EAAG,GAAO,MAAM,EAAI,EACtD,EAAS,EAAQ,EAAU,EAAO,EAAG,GAAO,MAAM,EAAI,EAE1D,OAAO,EAAS,EAAS,EAAQ,EAInC,SAAS,EAAqB,CAAC,EAAK,EAAO,EAAO,CAChD,IAAI,EAAc,CAAC,QAAS,SAAU,OAAW,MAAM,EAEnD,EAAS,EAAQ,EAAY,QAAQ,EAAG,GAAO,MAAM,EAAI,EACzD,EAAS,EAAQ,EAAY,QAAQ,EAAG,GAAO,MAAM,EAAI,EAE7D,GACU,EAAM,KAAe,6BAC5B,EAAS,GACP,IAAW,GACF,EAAM,IAAY,MAAM,EAAG,EAAE,IAAM,gBAE/C,OAAO,EAGT,OAAO,EAAS,EAAS,EAAQ,ECjM5B,IAAM,EAAa,CAAoB,IAA4C,CACxF,IAAM,EAAQ,IAAI,IAwBlB,OArBe,IAAI,MACjB,CAAC,EACD,CACE,IAAK,CAAC,EAAG,IAAQ,CACf,GAAI,OAAO,IAAQ,SAAU,OAC7B,IAAM,EAAS,EAAM,IAAI,CAAG,EAC5B,GAAI,EAAQ,OAAO,EACnB,IAAM,EAAW,IAAI,IACnB,EAAI,IAAI,CAAC,IAAY,CAEnB,IAAM,EAAS,EAAQ,GACvB,GAAI,OAAO,IAAW,WAAY,OAAO,EAAO,IAAQ,MAAM,6BAA6B,GAAK,CAAC,EAEjG,OAAQ,EAA4E,GAAG,CAAI,EAC5F,EAEH,OADA,EAAM,IAAI,EAAK,CAAQ,EAChB,EAEX,CACF,GF3BK,IAAU,IAAV,CAAU,IAAV,CACE,MAAM,UAAwB,EAAO,iBAAkC,EAAE,kBAAmB,CACjG,OAAQ,EAAO,OACf,MAAO,EAAO,SAAS,EAAO,OAAO,CAAC,CACxC,CAAC,CAAE,IACY,QAAO,EAAG,CACrB,IAAM,EAAS,KAAK,iBAAiB,MAAQ,KAAK,MAAM,QAAU,KAAK,OAAS,OAAO,KAAK,KAAK,EACjG,MAAO,gCAAgC,KAAK,SAAS,EAAS,KAAK,IAAW,KAElF,CARO,EAAM,kBAmCN,MAAM,UAAgB,EAAQ,QAA4B,EAAE,sBAAsB,CAAE,CAAC,CAArF,EAAM,UAEA,MAAM,EAAW,CAAO,EAIxB,QAAQ,EAAM,OACzB,EACA,EAAO,IAAI,SAAU,EAAG,CACtB,IAAM,EAAK,MAAO,EAAW,WAEvB,EAAa,EAAO,GAAG,uBAAuB,EAAE,SAAU,CAAC,EAAc,CAC7E,OAAO,MAAO,EAAG,OAAO,CAAI,EAAE,KAAK,EAAO,cAAc,IAAM,EAAK,CAAC,EACrE,EAEK,EAAqB,EAAO,GAAG,+BAA+B,EAAE,SAAU,CAAC,EAAc,CAC7F,OAAO,MAAO,EAAG,eAAe,CAAI,EAAE,KACpC,EAAO,YAAY,gBAAiB,WAAY,IAAM,EAAO,QAAQ,MAAS,CAAC,EAC/E,EAAO,YAAY,gBAAiB,mBAAoB,IAAM,EAAO,QAAQ,MAAS,CAAC,CACzF,EACD,EAEK,EAAQ,EAAO,GAAG,kBAAkB,EAAE,SAAU,CAAC,EAAc,CAEnE,OADa,MAAO,EAAG,KAAK,CAAI,EAAE,KAAK,EAAO,MAAM,IAAM,EAAO,IAAI,CAAC,IACzD,OAAS,YACvB,EAEK,EAAS,EAAO,GAAG,mBAAmB,EAAE,SAAU,CAAC,EAAc,CAErE,OADa,MAAO,EAAG,KAAK,CAAI,EAAE,KAAK,EAAO,MAAM,IAAM,EAAO,IAAI,CAAC,IACzD,OAAS,OACvB,EAEK,EAAuB,EAAO,GAAG,iCAAiC,EAAE,SAAU,CAAC,EAAiB,CACpG,OAAO,MAAO,EAAO,WAAW,CAC9B,IAAK,SAAY,CAEf,OADgB,MAAM,GAAQ,EAAS,CAAE,cAAe,EAAK,CAAC,GAC/C,IACb,CAAC,KAAiB,CAChB,KAAM,EAAE,KACR,KAAM,EAAE,YAAY,EAAI,YAAc,EAAE,eAAe,EAAI,UAAY,EAAE,OAAO,EAAI,OAAS,OAC/F,EACF,GAEF,MAAO,CAAC,IAAU,IAAI,EAAgB,CAAE,OAAQ,uBAAwB,OAAM,CAAC,CACjF,CAAC,EACF,EAEK,EAAU,EAAO,GAAG,oBAAoB,EAAE,SAAU,CAAC,EAAe,CACxE,IAAM,EAAW,EAAK,QAAQ,EAAY,CAAK,CAAC,EAChD,OAAO,MAAO,EAAG,SAAS,CAAQ,EAAE,KAClC,EAAO,YAAY,gBAAiB,WAAY,IAAM,EAAO,QAAQ,CAAQ,CAAC,EAC9E,EAAO,KACT,EACD,EAEK,GAAW,EAAO,GAAG,qBAAqB,EAAE,SAAU,CAAC,EAAc,CACzE,IAAM,EAAO,MAAO,EAAG,eAAe,CAAI,EAC1C,OAAO,MAAO,EAAO,IAAI,CACvB,IAAK,IAAM,KAAK,MAAM,CAAI,EAC1B,MAAO,CAAC,IAAU,IAAI,EAAgB,CAAE,OAAQ,WAAY,OAAM,CAAC,CACrE,CAAC,EACF,EAEK,GAAY,EAAO,GAAG,sBAAsB,EAAE,SAAU,CAAC,EAAc,EAAe,EAAe,CACzG,IAAM,EAAU,KAAK,UAAU,EAAM,KAAM,CAAC,EAE5C,GADA,MAAO,EAAG,gBAAgB,EAAM,CAAO,EACnC,EAAM,MAAO,EAAG,MAAM,EAAM,CAAI,EACrC,EAEK,GAAY,EAAO,GAAG,sBAAsB,EAAE,SAAU,CAAC,EAAc,CAC3E,MAAO,EAAG,cAAc,EAAM,CAAE,UAAW,EAAK,CAAC,EAClD,EAEK,GAAgB,EAAO,GAAG,0BAA0B,EAAE,SAAU,CACpE,EACA,EACA,EACA,CACA,IAAM,EAAQ,OAAO,IAAY,SAAW,EAAG,gBAAgB,EAAM,CAAO,EAAI,EAAG,UAAU,EAAM,CAAO,EAY1G,GAVA,MAAO,EAAM,KACX,EAAO,QACL,CAAC,IAAM,EAAE,OAAO,OAAS,WACzB,IACE,EAAO,IAAI,SAAU,EAAG,CACtB,MAAO,EAAG,cAAc,EAAQ,CAAI,EAAG,CAAE,UAAW,EAAK,CAAC,EAC1D,MAAO,EACR,CACL,CACF,EACI,EAAM,MAAO,EAAG,MAAM,EAAM,CAAI,EACrC,EAEK,EAAO,EAAO,GAAG,iBAAiB,EAAE,SAAU,CAAC,EAAiB,EAAwB,CAC5F,OAAO,MAAO,EAAO,WAAW,CAC9B,IAAK,IAAM,EAAK,KAAK,EAAS,CAAO,EACrC,MAAO,CAAC,IAAU,IAAI,EAAgB,CAAE,OAAQ,OAAQ,OAAM,CAAC,CACjE,CAAC,EACF,EAEK,GAAS,EAAO,GAAG,mBAAmB,EAAE,SAAU,CAAC,EAAgB,EAAe,EAAe,CACrG,IAAM,EAAmB,CAAC,EACtB,EAAU,EACd,MAAO,GAAM,CACX,IAAM,EAAS,EAAK,EAAS,CAAM,EACnC,GAAI,MAAO,EAAG,OAAO,CAAM,EAAG,EAAO,KAAK,CAAM,EAChD,GAAI,IAAS,EAAS,MACtB,IAAM,EAAS,EAAQ,CAAO,EAC9B,GAAI,IAAW,EAAS,MACxB,EAAU,EAEZ,OAAO,EACR,EAEK,GAAK,EAAO,GAAG,eAAe,EAAE,SAAU,CAAC,EAA8D,CAC7G,IAAM,EAAmB,CAAC,EACtB,EAAU,EAAQ,MACtB,MAAO,GAAM,CACX,QAAW,KAAU,EAAQ,QAAS,CACpC,IAAM,EAAS,EAAK,EAAS,CAAM,EACnC,GAAI,MAAO,EAAG,OAAO,CAAM,EAAG,EAAO,KAAK,CAAM,EAElD,GAAI,EAAQ,OAAS,EAAS,MAC9B,IAAM,EAAS,EAAQ,CAAO,EAC9B,GAAI,IAAW,EAAS,MACxB,EAAU,EAEZ,OAAO,EACR,EAEK,GAAS,EAAO,GAAG,mBAAmB,EAAE,SAAU,CAAC,EAAiB,EAAe,EAAe,CACtG,IAAM,EAAmB,CAAC,EACtB,EAAU,EACd,MAAO,GAAM,CACX,IAAM,EAAU,MAAO,EAAK,EAAS,CAAE,IAAK,EAAS,SAAU,GAAM,QAAS,OAAQ,IAAK,EAAK,CAAC,EAAE,KACjG,EAAO,MAAM,IAAM,EAAO,QAAQ,CAAC,CAAa,CAAC,CACnD,EAEA,GADA,EAAO,KAAK,GAAG,CAAO,EAClB,IAAS,EAAS,MACtB,IAAM,EAAS,EAAQ,CAAO,EAC9B,GAAI,IAAW,EAAS,MACxB,EAAU,EAEZ,OAAO,EACR,EAED,OAAO,EAAQ,GAAG,IACb,EACH,aACA,qBACA,QACA,SACA,uBACA,UACA,YACA,aACA,aACA,iBACA,UACA,MACA,UACA,OACA,UAAW,EAAK,KAClB,CAAC,EACF,CACH,EAEa,OAAO,EAAe,CAAE,QAAS,EAAS,MAAO,QAAO,KAAM,CAAC,CAAU,CAAE,CAAC,EAGlF,SAAS,CAAQ,CAAC,EAAmB,CAC1C,OAAO,EAAO,CAAC,GAAK,2BADf,EAAS,WAIT,SAAS,CAAa,CAAC,EAAmB,CACb,OAAO,EADpC,EAAS,gBAUT,SAAS,CAAoB,CAAC,EAAmB,CACpB,OAAO,EADpC,EAAS,uBAST,SAAS,CAAO,CAAC,EAAmB,CACzC,IAAM,EAAW,EAAK,QAAQ,EAAY,CAAC,CAAC,EAC5C,GAAI,CACF,OAAO,EAAc,EAAa,CAAQ,CAAC,EAC3C,MAAO,EAAQ,CACf,GAAI,GAAG,OAAS,SAAU,OAAO,EAAc,CAAQ,EACvD,MAAM,GANH,EAAS,UAUT,SAAS,CAAW,CAAC,EAAmB,CACX,OAAO,EADpC,EAAS,cAST,SAAS,EAAQ,CAAC,EAAW,EAAW,CAC7C,OAAO,EAAS,EAAG,CAAC,GAAK,EAAS,EAAG,CAAC,EADjC,EAAS,YAIT,SAAS,CAAQ,CAAC,EAAgB,EAAe,CACtD,IAAM,EAAS,GAAS,EAAQ,CAAK,EACrC,OAAO,IAAW,IAAO,CAAC,GAAW,CAAM,GAAK,IAAW,MAAQ,CAAC,EAAO,WAAW,KAAK,IAAK,EAF3F,EAAS,aA5PD", | ||
| "debugId": "0F1065248EFB2F8064756E2164756E21", | ||
| "names": [] | ||
| } |
Sorry, the diff of this file is too big to display
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/mcp/auth.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"node:os\"\nimport { Effect } from \"effect\"\nimport {\n OpenCode,\n type IntegrationAttemptStatus,\n type IntegrationOAuthMethod,\n type OpenCodeClient,\n} from \"@opencode-ai/client\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { ServiceConfig } from \"../../../services/service-config\"\nimport { resolveIntegration } from \"./resolve\"\n\nconst location = { directory: process.cwd() }\n\nexport default Runtime.handler(\n Commands.commands.mcp.commands.auth,\n Effect.fn(\"cli.mcp.auth\")(function* (input) {\n const options = yield* ServiceConfig.options()\n const found = yield* Service.discover(options)\n const endpoint = found ?? (yield* Service.ensure(options))\n const client = OpenCode.make({ baseUrl: endpoint.url, headers: Service.headers(endpoint) })\n\n const integration = yield* resolveIntegration(client, input.name, location)\n if (!integration)\n return yield* Effect.fail(new Error(`MCP server \"${input.name}\" is not an OAuth-capable remote server`))\n const method = integration.methods.find(\n (candidate): candidate is IntegrationOAuthMethod => candidate.type === \"oauth\",\n )\n if (!method)\n return yield* Effect.fail(new Error(`MCP server \"${input.name}\" is not an OAuth-capable remote server`))\n\n const started = yield* Effect.promise(() =>\n client.integration.connect.oauth({ integrationID: integration.id, methodID: method.id, inputs: {}, location }),\n )\n const attempt = started.data\n if (attempt.mode === \"code\")\n return yield* Effect.fail(new Error(\"This server requires manual code entry, which the CLI does not support\"))\n\n process.stdout.write(attempt.instructions + EOL + attempt.url + EOL)\n\n const result = yield* poll(client, attempt.attemptID)\n if (result.status === \"complete\") {\n process.stdout.write(`Authenticated with ${input.name}` + EOL)\n return\n }\n const reason = result.status === \"failed\" ? `: ${result.message}` : \"\"\n return yield* Effect.fail(new Error(`Authentication ${result.status}${reason}`))\n }),\n)\n\nconst poll = (\n client: OpenCodeClient,\n attemptID: string,\n): Effect.Effect<Exclude<IntegrationAttemptStatus, { status: \"pending\" }>> =>\n Effect.gen(function* () {\n const status = yield* Effect.promise(() => client.integration.attempt.status({ attemptID, location })).pipe(\n Effect.map((result) => result.data),\n )\n if (status.status === \"pending\") {\n yield* Effect.sleep(\"1 second\")\n return yield* poll(client, attemptID)\n }\n return status\n })\n" | ||
| ], | ||
| "mappings": ";46BAAA,mBAAS,gBAcT,SAAM,OAAW,MAAE,eAAW,aAAQ,SAAI,MAAE,OAE7B,SAAQ,aACrB,OAAS,cAAS,SAAI,cAAS,UAC/B,OAAO,QAAG,mBAAc,OAAE,cAAU,MAAC,OAAO,CAC1C,IAAM,EAAU,MAAO,EAAc,QAAQ,EAEvC,GADQ,MAAO,EAAQ,SAAS,CAAO,KAClB,MAAO,EAAQ,OAAO,CAAO,GAClD,EAAS,EAAS,KAAK,CAAE,QAAS,EAAS,IAAK,QAAS,EAAQ,QAAQ,CAAQ,CAAE,CAAC,EAEpF,EAAc,MAAO,EAAmB,EAAQ,EAAM,KAAM,CAAQ,EAC1E,GAAI,CAAC,EACH,OAAO,MAAO,EAAO,KAAS,MAAM,eAAe,EAAM,6CAA6C,CAAC,EACzG,IAAM,EAAS,EAAY,QAAQ,KACjC,CAAC,IAAmD,EAAU,OAAS,OACzE,EACA,GAAI,CAAC,EACH,OAAO,MAAO,EAAO,KAAS,MAAM,eAAe,EAAM,6CAA6C,CAAC,EAKzG,IAAM,GAHU,MAAO,EAAO,QAAQ,IACpC,EAAO,YAAY,QAAQ,MAAM,CAAE,cAAe,EAAY,GAAI,SAAU,EAAO,GAAI,OAAQ,CAAC,EAAG,UAAS,CAAC,CAC/G,GACwB,KACxB,GAAI,EAAQ,OAAS,OACnB,OAAO,MAAO,EAAO,KAAS,MAAM,wEAAwE,CAAC,EAE/G,QAAQ,OAAO,MAAM,EAAQ,aAAe,EAAM,EAAQ,IAAM,CAAG,EAEnE,IAAM,EAAS,MAAO,EAAK,EAAQ,EAAQ,SAAS,EACpD,GAAI,EAAO,SAAW,WAAY,CAChC,QAAQ,OAAO,MAAM,sBAAsB,EAAM,OAAS,CAAG,EAC7D,OAEF,IAAM,EAAS,EAAO,SAAW,SAAW,KAAK,EAAO,UAAY,GACpE,OAAO,MAAO,EAAO,KAAS,MAAM,kBAAkB,EAAO,SAAS,GAAQ,CAAC,EAChF,CACH,EAEM,EAAO,CACX,EACA,IAEA,EAAO,IAAI,SAAU,EAAG,CACtB,IAAM,EAAS,MAAO,EAAO,QAAQ,IAAM,EAAO,YAAY,QAAQ,OAAO,CAAE,YAAW,UAAS,CAAC,CAAC,EAAE,KACrG,EAAO,IAAI,CAAC,IAAW,EAAO,IAAI,CACpC,EACA,GAAI,EAAO,SAAW,UAEpB,OADA,MAAO,EAAO,MAAM,UAAU,EACvB,MAAO,EAAK,EAAQ,CAAS,EAEtC,OAAO,EACR", | ||
| "debugId": "6FC79C44CEF46BE664756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/mini/mini.ts", "src/mini/run.ts", "src/mini/noninteractive.ts", "src/mini/ui.ts"], | ||
| "sourcesContent": [ | ||
| "import { Service } from \"@opencode-ai/client/effect/service\"\nimport { OpenCode, type OpenCodeClient } from \"@opencode-ai/client/promise\"\nimport { ServerConnection } from \"../services/server-connection\"\nimport { waitForCatalogReady } from \"./catalog.shared\"\nimport { INTERACTIVE_INPUT_ERROR, resolveInteractiveStdin } from \"./runtime.stdin\"\nimport type { RunInput, RunTuiConfig } from \"./types\"\n\nexport type MiniCommandInput = {\n server: ServerConnection.Resolved\n continue?: boolean\n session?: string\n fork?: boolean\n model?: string\n agent?: string\n prompt?: string\n replay?: boolean\n replayLimit?: number\n demo?: boolean\n tuiConfig?: RunTuiConfig | Promise<RunTuiConfig>\n}\n\ntype Session = Awaited<ReturnType<OpenCodeClient[\"session\"][\"get\"]>>\nexport async function runMini(input: MiniCommandInput) {\n validate(input)\n const initialInput = mergeInput(process.stdin.isTTY ? undefined : await Bun.stdin.text(), input.prompt)\n const runtimeTask = import(\"./runtime\")\n const directory = localDirectory()\n\n try {\n const sdk = OpenCode.make({\n baseUrl: input.server.endpoint.url,\n headers: Service.headers(input.server.endpoint),\n })\n const model = parseModel(input.model)\n let agentTask: Promise<string | undefined> | undefined\n const resolveAgent = () => {\n agentTask ??= validateAgent(sdk, directory, input.agent)\n return agentTask\n }\n const resolveSession = async () => {\n const [agent, selected] = await Promise.all([resolveAgent(), selectSession(sdk, directory, input)])\n const readyModel =\n model ?? (selected?.model ? { providerID: selected.model.providerID, modelID: selected.model.id } : undefined)\n if (readyModel) await waitForCatalogReady({ sdk, directory, model: readyModel })\n const session = selected ?? (await createSession(sdk, directory, agent, model))\n return { id: session.id, title: session.title, resume: selected !== undefined }\n }\n const create = (\n _sdk: OpenCodeClient,\n next: { agent: string | undefined; model: RunInput[\"model\"]; variant: string | undefined },\n ) => createSession(sdk, directory, next.agent, next.model, next.variant)\n const runtime = await runtimeTask\n await runtime.runInteractiveDeferredMode({\n sdk,\n directory,\n resolveAgent,\n session: resolveSession,\n createSession: create,\n agent: input.agent,\n model,\n variant: undefined,\n files: [],\n initialInput,\n thinking: true,\n replay: input.replay ?? true,\n replayLimit: input.replayLimit,\n demo: input.demo,\n tuiConfig: input.tuiConfig,\n })\n } catch (error) {\n if (error instanceof Error && error.message === INTERACTIVE_INPUT_ERROR) fail(error.message)\n throw error\n }\n}\n\nexport function validateMiniTerminal() {\n if (!process.stdout.isTTY) fail(\"opencode mini requires a TTY stdout\")\n}\n\n/** @internal Exported for testing. */\nexport function mergeInput(piped: string | undefined, prompt: string | undefined) {\n if (!prompt) return piped || undefined\n if (!piped) return prompt\n return piped + \"\\n\" + prompt\n}\n\nfunction validate(input: MiniCommandInput) {\n validateMiniTerminal()\n if (input.replayLimit !== undefined && (!Number.isInteger(input.replayLimit) || input.replayLimit <= 0)) {\n fail(\"--replay-limit must be a positive integer\")\n }\n if (input.fork && !input.continue && !input.session) fail(\"--fork requires --continue or --session\")\n resolveInteractiveStdin().cleanup?.()\n}\n\nfunction localDirectory(): string {\n const root = process.env.PWD ?? process.cwd()\n try {\n process.chdir(root)\n return process.cwd()\n } catch {\n fail(`Failed to change directory to ${root}`)\n }\n}\n\nfunction parseModel(value?: string): RunInput[\"model\"] {\n if (!value) return\n const [providerID, ...rest] = value.split(\"/\")\n const modelID = rest.join(\"/\")\n if (!providerID || !modelID) fail(\"--model must use the format provider/model\")\n return { providerID, modelID }\n}\n\nasync function validateAgent(sdk: OpenCodeClient, directory: string, name?: string) {\n if (!name) return\n const deadline = Date.now() + 5_000\n let agents: Awaited<ReturnType<OpenCodeClient[\"agent\"][\"list\"]>> | undefined\n while (Date.now() < deadline) {\n agents = await sdk.agent.list({ location: { directory } }).catch(() => undefined)\n const agent = agents?.data.find((item) => item.id === name)\n if (agent?.mode === \"subagent\") {\n warning(`agent \"${name}\" is a subagent, not a primary agent. Falling back to default agent`)\n return\n }\n if (agent) return name\n await Bun.sleep(25)\n }\n if (!agents) {\n warning(\"failed to list agents. Falling back to default agent\")\n return\n }\n warning(`agent \"${name}\" not found. Falling back to default agent`)\n}\n\nasync function selectSession(sdk: OpenCodeClient, directory: string, input: MiniCommandInput, preselected?: Session) {\n const selected =\n preselected ??\n (input.session\n ? await sdk.session.get({ sessionID: input.session }).catch(() => undefined)\n : input.continue\n ? await sdk.session\n .list({ directory, parentID: null, limit: 1, order: \"desc\" })\n .then((result) => result.data[0])\n : undefined)\n if (input.session && !selected) fail(\"Session not found\")\n if (!selected) return\n if (!input.fork) return selected\n return sdk.session.fork({ sessionID: selected.id })\n}\n\nasync function createSession(\n sdk: OpenCodeClient,\n directory: string,\n agent: string | undefined,\n model: RunInput[\"model\"],\n variant?: string,\n): Promise<Session> {\n if (model) await waitForCatalogReady({ sdk, directory, model })\n return sdk.session.create({\n agent,\n model: model ? { providerID: model.providerID, id: model.modelID, variant } : undefined,\n location: { directory },\n })\n}\n\nfunction warning(message: string) {\n process.stderr.write(`\\x1b[93m\\x1b[1m!\\x1b[0m ${message}\\n`)\n}\n\nfunction fail(message: string): never {\n process.stderr.write(`\\x1b[91m\\x1b[1mError: \\x1b[0m${message}\\n`)\n process.exit(1)\n}\n", | ||
| "import { Service, type Endpoint } from \"@opencode-ai/client/effect/service\"\nimport { OpenCode, type OpenCodeClient } from \"@opencode-ai/client/promise\"\nimport { FSUtil } from \"@opencode-ai/core/fs-util\"\nimport { Model } from \"@opencode-ai/schema/model\"\nimport { open } from \"node:fs/promises\"\nimport path from \"node:path\"\nimport { ServerConnection } from \"../services/server-connection\"\nimport { loadRunAgents, waitForCatalogReady } from \"./catalog.shared\"\nimport { runNonInteractivePrompt } from \"./noninteractive\"\nimport { toolInlineInfo } from \"./tool\"\nimport type { MiniToolPart } from \"./types\"\nimport { UI } from \"./ui\"\n\nexport type RunCommandInput = {\n server: ServerConnection.Resolved\n message: string[]\n continue?: boolean\n session?: string\n fork?: boolean\n model?: string\n agent?: string\n format: \"default\" | \"json\"\n file: string[]\n title?: string\n thinking?: boolean\n auto?: boolean\n}\n\ntype FilePart = {\n url: string\n filename: string\n mime: string\n}\n\ntype Prepared = {\n directory?: string\n message: string\n files: FilePart[]\n}\n\nconst ATTACH_FILE_MAX_BYTES = 10 * 1024 * 1024\n\nexport function runNonInteractive(input: RunCommandInput) {\n return run(input).catch((error) => reportError(input, error instanceof Error ? error.message : String(error)))\n}\n\nasync function run(input: RunCommandInput) {\n if (input.fork && !input.continue && !input.session) fail(\"--fork requires --continue or --session\")\n const root = process.env.PWD ?? process.cwd()\n const directory = localDirectory(root)\n const message = mergeInput(formatMessage(input.message), process.stdin.isTTY ? undefined : await Bun.stdin.text())\n if (!message?.trim()) fail(\"You must provide a message\")\n const files = await Promise.all(input.file.map((file) => prepareFile(file, root)))\n const prepared = { directory, message, files }\n return execute(input, prepared, input.server.endpoint)\n}\n\nasync function execute(input: RunCommandInput, prepared: Prepared, endpoint: Endpoint) {\n const client = OpenCode.make({ baseUrl: endpoint.url, headers: Service.headers(endpoint) })\n const requestedDirectory = prepared.directory ?? (await client.location.get()).directory\n if (!requestedDirectory) fail(\"Failed to resolve server directory\")\n const session = await selectSession(client, requestedDirectory, input)\n const cwd = session?.location.directory ?? requestedDirectory\n const workspace = session?.location.workspaceID\n const explicit = parseRunModel(input.model)\n const explicitModel = explicit?.model\n const variant = explicit?.variant\n const sessionModel = session?.model ? { providerID: session.model.providerID, modelID: session.model.id } : undefined\n const defaultModel =\n !explicitModel && !sessionModel\n ? await client.model\n .default({ location: { directory: cwd, workspace } })\n .then((result) => (result.data ? { providerID: result.data.providerID, modelID: result.data.id } : undefined))\n : undefined\n const model = pickRunModel(explicitModel, variant, sessionModel, defaultModel)\n if (variant && !model) return reportError(input, \"Cannot select a variant before selecting a model\", session?.id)\n if (model) {\n await waitForCatalogReady({ sdk: client, directory: cwd, workspace, model })\n const available = await client.model.list({ location: { directory: cwd, workspace } })\n if (!available.data.some((item) => item.providerID === model.providerID && item.id === model.modelID))\n return reportError(input, `Model unavailable: ${model.providerID}/${model.modelID}`, session?.id)\n }\n const agent = await validateAgent(client, cwd, input.agent)\n const selected =\n session ??\n (await client.session.create({\n agent,\n model: model ? { providerID: model.providerID, id: model.modelID, variant } : undefined,\n location: { directory: cwd },\n }))\n if (!session && input.title !== undefined) {\n await client.session.rename({\n sessionID: selected.id,\n title: input.title || prepared.message.slice(0, 50) + (prepared.message.length > 50 ? \"...\" : \"\"),\n })\n }\n\n await runNonInteractivePrompt({\n client,\n sessionID: selected.id,\n message: prepared.message,\n files: prepared.files,\n agent,\n model,\n variant,\n thinking: input.thinking ?? false,\n format: input.format,\n auto: input.auto ?? false,\n attached: true,\n renderTool,\n renderToolError,\n }).catch((error) => reportError(input, error instanceof Error ? error.message : String(error), selected.id))\n}\n\nexport function mergeInput(message: string | undefined, piped: string | undefined) {\n if (!message) return piped || undefined\n if (!piped) return message\n return message + \"\\n\" + piped\n}\n\nexport function pickRunModel(\n explicit: { providerID: string; modelID: string } | undefined,\n variant: string | undefined,\n session: { providerID: string; modelID: string } | undefined,\n fallback: { providerID: string; modelID: string } | undefined,\n) {\n if (explicit) return explicit\n if (!variant) return\n return session ?? fallback\n}\n\nfunction formatMessage(message: string[]) {\n const value = message.map((part) => (part.includes(\" \") ? `\"${part.replace(/\"/g, '\\\\\"')}\"` : part)).join(\" \")\n return value || undefined\n}\n\nfunction localDirectory(root: string) {\n try {\n process.chdir(root)\n return process.cwd()\n } catch {\n fail(`Failed to change directory to ${root}`)\n }\n}\n\nexport function parseRunModel(value?: string) {\n if (!value) return\n const ref = Model.Ref.parse(value)\n return {\n model: { providerID: ref.providerID, modelID: ref.id },\n variant: ref.variant,\n }\n}\n\nasync function validateAgent(client: OpenCodeClient, directory: string, name?: string) {\n if (!name) return\n const agents = await loadRunAgents(client, directory).catch(() => undefined)\n if (!agents) {\n warning(\"failed to list agents. Falling back to default agent\")\n return\n }\n const agent = agents.find((item) => item.id === name)\n if (!agent) {\n warning(`agent \"${name}\" not found. Falling back to default agent`)\n return\n }\n if (agent.mode === \"subagent\") {\n warning(`agent \"${name}\" is a subagent, not a primary agent. Falling back to default agent`)\n return\n }\n return name\n}\n\nasync function selectSession(client: OpenCodeClient, directory: string, input: RunCommandInput) {\n const selected = input.session\n ? await client.session.get({ sessionID: input.session }).catch(() => undefined)\n : input.continue\n ? await client.session\n .list({ directory, parentID: null, limit: 1, order: \"desc\" })\n .then((result) => result.data[0])\n : undefined\n if (input.session && !selected) fail(\"Session not found\")\n if (!selected || !input.fork) return selected\n return client.session.fork({ sessionID: selected.id })\n}\n\nasync function prepareFile(input: string, directory: string): Promise<FilePart> {\n const file = path.resolve(directory, input)\n const handle = await open(file, \"r\").catch(() => fail(`File not found: ${input}`))\n try {\n const stat = await handle.stat()\n if (!stat.isFile() || stat.size > ATTACH_FILE_MAX_BYTES)\n fail(`Cannot attach a directory, special file, or file larger than 10 MiB: ${input}`)\n const content = Buffer.alloc(Number(stat.size))\n let offset = 0\n while (offset < content.length) {\n const read = await handle.read(content, offset, content.length - offset, offset)\n if (read.bytesRead === 0) break\n offset += read.bytesRead\n }\n const bytes = content.subarray(0, offset)\n const detected = FSUtil.mimeType(file)\n const text = bytes.toString(\"utf8\")\n const mime =\n detected.startsWith(\"image/\") || detected === \"application/pdf\"\n ? detected\n : !isBinaryContent(bytes) && Buffer.from(text, \"utf8\").equals(bytes)\n ? \"text/plain\"\n : detected\n return {\n url: `data:${mime};base64,${bytes.toString(\"base64\")}`,\n filename: path.basename(file),\n mime,\n }\n } finally {\n await handle.close()\n }\n}\n\nfunction isBinaryContent(bytes: Uint8Array) {\n if (bytes.length === 0) return false\n if (bytes.includes(0)) return true\n return bytes.reduce((count, byte) => count + Number(byte < 9 || (byte > 13 && byte < 32)), 0) / bytes.length > 0.3\n}\n\nasync function renderTool(part: MiniToolPart) {\n const info = toolInlineInfo(part)\n if (info.mode === \"block\") {\n UI.empty()\n UI.println(UI.Style.TEXT_NORMAL + info.icon, UI.Style.TEXT_NORMAL + info.title)\n if (info.body?.trim()) UI.println(info.body)\n UI.empty()\n return\n }\n UI.println(\n UI.Style.TEXT_NORMAL + info.icon,\n UI.Style.TEXT_NORMAL + info.title,\n info.description ? UI.Style.TEXT_DIM + info.description + UI.Style.TEXT_NORMAL : \"\",\n )\n}\n\nasync function renderToolError(part: MiniToolPart) {\n const info = toolInlineInfo(part)\n UI.println(UI.Style.TEXT_NORMAL + \"✗\", UI.Style.TEXT_NORMAL + `${info.title} failed`)\n}\n\nfunction warning(message: string) {\n UI.println(UI.Style.TEXT_WARNING_BOLD + \"!\", UI.Style.TEXT_NORMAL, message)\n}\n\nfunction reportError(input: RunCommandInput, message: string, sessionID?: string) {\n process.exitCode = 1\n if (input.format === \"json\") {\n process.stdout.write(\n JSON.stringify({\n type: \"error\",\n timestamp: Date.now(),\n sessionID: sessionID ?? \"\",\n error: { type: \"unknown\", message },\n }) + \"\\n\",\n )\n return\n }\n UI.error(message)\n}\n\nfunction fail(message: string): never {\n throw new Error(message)\n}\n", | ||
| "import type { EventSubscribeOutput, OpenCodeClient } from \"@opencode-ai/client/promise\"\nimport { SessionMessage } from \"@opencode-ai/schema/session-message\"\nimport { EOL } from \"node:os\"\nimport { UI } from \"./ui\"\nimport type { MiniToolPart } from \"./types\"\n\ntype Model = {\n providerID: string\n modelID: string\n}\n\ntype File = {\n url: string\n filename: string\n mime: string\n}\n\ntype Input = {\n client: OpenCodeClient\n sessionID: string\n message: string\n files: File[]\n agent?: string\n model?: Model\n variant?: string\n thinking: boolean\n format: \"default\" | \"json\"\n auto: boolean\n /** True when the client is attached to a shared server rather than an exclusive in-process one. */\n attached: boolean\n renderTool: (part: MiniToolPart) => Promise<void>\n renderToolError: (part: MiniToolPart) => Promise<void>\n}\n\ntype StartedPart = {\n id: string\n timestamp: number\n}\n\ntype ToolState = StartedPart & {\n assistantMessageID: string\n tool: string\n input: Record<string, unknown>\n raw?: string\n provider?: unknown\n}\n\ntype V2Event = EventSubscribeOutput\ntype FormRequest = Extract<V2Event, { type: \"form.created\" }>[\"data\"][\"form\"]\n\n// MCP elicitations are temporarily owned by the \"global\" sentinel instead of a real\n// session. An exclusive local process may treat them as this run's blockers; an\n// attached client must not cancel input that may belong to another session.\nconst GLOBAL_FORM_SESSION_ID = \"global\"\n\nexport async function runNonInteractivePrompt(input: Input) {\n const controller = new AbortController()\n const stream = input.client.event.subscribe({ signal: controller.signal })[Symbol.asyncIterator]()\n const connected = await stream.next()\n if (connected.done) throw new Error(\"Event stream disconnected before prompt admission\")\n\n const messageID = SessionMessage.ID.create()\n const starts = new Map<string, StartedPart>()\n const tools = new Map<string, ToolState>()\n let submitted = false\n let promoted = false\n let emittedError = false\n let questionRejected = false\n let permissionRejected = false\n let formCancelled = false\n let interrupted = false\n let admission: AbortController | undefined\n\n const emit = (type: string, timestamp: number, data: Record<string, unknown>) => {\n if (input.format !== \"json\") return false\n process.stdout.write(JSON.stringify({ type, timestamp, sessionID: input.sessionID, ...data }) + EOL)\n return true\n }\n\n const writeText = (part: { text: string; [key: string]: unknown }, timestamp: number) => {\n if (emit(\"text\", timestamp, { part })) return\n const text = part.text.trim()\n if (!text) return\n if (!process.stdout.isTTY) {\n process.stdout.write(text + EOL)\n return\n }\n UI.empty()\n UI.println(text)\n UI.empty()\n }\n\n const replyPermission = async (request: { id: string; action: string; resources: ReadonlyArray<string> }) => {\n if (!input.auto) {\n permissionRejected = true\n UI.println(\n UI.Style.TEXT_WARNING_BOLD + \"!\",\n UI.Style.TEXT_NORMAL +\n `permission requested: ${request.action} (${request.resources.join(\", \")}); auto-rejecting`,\n )\n }\n await input.client.permission\n .reply({\n sessionID: input.sessionID,\n requestID: request.id,\n reply: input.auto ? \"once\" : \"reject\",\n })\n .catch(() => {})\n if (!input.auto) {\n await input.client.session.interrupt({ sessionID: input.sessionID }).catch(() => {})\n }\n }\n\n const rejectQuestion = async (request: { id: string }) => {\n questionRejected = true\n await input.client.question.reject({ sessionID: input.sessionID, requestID: request.id }).catch(() => {})\n }\n\n const cancelForm = async (request: Pick<FormRequest, \"id\" | \"sessionID\">) => {\n formCancelled = true\n await input.client.form.cancel({ sessionID: request.sessionID, formID: request.id }).catch(() => {})\n }\n\n const consume = async () => {\n while (!controller.signal.aborted) {\n const next = await stream.next().catch((error) => {\n if (!emittedError) throw error\n return { done: true as const, value: undefined }\n })\n if (next.done) {\n if (emittedError) return\n throw new Error(\"Event stream disconnected during prompt execution\")\n }\n const event = next.value\n\n if (event.type === \"permission.v2.asked\" && submitted && event.data.sessionID === input.sessionID) {\n await replyPermission(event.data)\n continue\n }\n if (event.type === \"question.v2.asked\" && submitted && event.data.sessionID === input.sessionID) {\n await rejectQuestion(event.data)\n continue\n }\n if (\n event.type === \"form.created\" &&\n submitted &&\n (event.data.form.sessionID === input.sessionID ||\n (!input.attached && event.data.form.sessionID === GLOBAL_FORM_SESSION_ID))\n ) {\n await cancelForm(event.data.form)\n continue\n }\n if (!(\"sessionID\" in event.data) || event.data.sessionID !== input.sessionID) continue\n const time = toMillis(\"created\" in event ? event.created : undefined)\n\n if (event.type === \"session.input.promoted\") {\n if (event.data.inputID === messageID) {\n promoted = true\n continue\n }\n }\n if (\n event.type === \"session.execution.interrupted\" &&\n event.data.reason === \"user\" &&\n (interrupted || permissionRejected || questionRejected || formCancelled)\n ) {\n return\n }\n if (!promoted) continue\n\n if (event.type === \"session.step.started\") {\n const part = {\n id: partID(event.id),\n sessionID: input.sessionID,\n messageID: event.data.assistantMessageID,\n type: \"step-start\",\n snapshot: event.data.snapshot,\n }\n if (!emit(\"step_start\", time, { part }) && input.format !== \"json\") {\n UI.empty()\n UI.println(`> ${event.data.agent} · ${event.data.model.id}`)\n UI.empty()\n }\n continue\n }\n\n if (event.type === \"session.text.started\") {\n starts.set(\"text\", { id: partID(event.id), timestamp: time })\n continue\n }\n if (event.type === \"session.text.ended\") {\n const started = starts.get(\"text\")\n starts.delete(\"text\")\n const part = {\n id: started?.id ?? partID(event.id),\n sessionID: input.sessionID,\n messageID: event.data.assistantMessageID,\n type: \"text\",\n text: event.data.text,\n time: { start: started?.timestamp ?? time, end: time },\n }\n writeText(part, time)\n continue\n }\n\n if (event.type === \"session.reasoning.started\") {\n starts.set(\"reasoning\", { id: partID(event.id), timestamp: time })\n continue\n }\n if (event.type === \"session.reasoning.ended\" && input.thinking) {\n const started = starts.get(\"reasoning\")\n starts.delete(\"reasoning\")\n const part = {\n id: started?.id ?? partID(event.id),\n sessionID: input.sessionID,\n messageID: event.data.assistantMessageID,\n type: \"reasoning\",\n text: event.data.text,\n metadata: event.data.state,\n time: { start: started?.timestamp ?? time, end: time },\n }\n if (emit(\"reasoning\", time, { part })) continue\n const text = part.text.trim()\n if (!text) continue\n const line = `Thinking: ${text}`\n if (!process.stdout.isTTY) {\n process.stdout.write(line + EOL)\n continue\n }\n UI.empty()\n UI.println(`${UI.Style.TEXT_DIM}\\u001b[3m${line}\\u001b[0m${UI.Style.TEXT_NORMAL}`)\n UI.empty()\n continue\n }\n\n if (event.type === \"session.tool.input.started\") {\n tools.set(event.data.callID, {\n id: partID(event.id),\n timestamp: time,\n assistantMessageID: event.data.assistantMessageID,\n tool: event.data.name,\n input: {},\n })\n continue\n }\n if (event.type === \"session.tool.input.ended\") {\n const current = tools.get(event.data.callID)\n if (current) current.raw = event.data.text\n continue\n }\n if (event.type === \"session.tool.called\") {\n const current = tools.get(event.data.callID)\n tools.set(event.data.callID, {\n id: current?.id ?? partID(event.id),\n timestamp: current?.timestamp ?? time,\n assistantMessageID: event.data.assistantMessageID,\n tool: current?.tool ?? \"tool\",\n input: event.data.input,\n raw: current?.raw,\n provider: { executed: event.data.executed, state: event.data.state },\n })\n continue\n }\n if (event.type === \"session.tool.success\") {\n const current = tools.get(event.data.callID) ?? fallbackTool(event)\n const part: MiniToolPart = {\n id: current.id,\n sessionID: input.sessionID,\n messageID: event.data.assistantMessageID,\n type: \"tool\",\n callID: event.data.callID,\n tool: current.tool,\n state: {\n status: \"completed\",\n input: current.input,\n output: event.data.content\n .filter((item) => item.type === \"text\")\n .map((item) => item.text)\n .join(\"\\n\"),\n title: current.tool,\n metadata: {\n structured: event.data.structured,\n content: event.data.content,\n result: event.data.result,\n providerCall: current.provider,\n providerResult: { executed: event.data.executed, state: event.data.resultState },\n rawInput: current.raw,\n },\n time: { start: current.timestamp, end: time },\n },\n }\n tools.delete(event.data.callID)\n if (!emit(\"tool_use\", time, { part })) await input.renderTool(part)\n continue\n }\n if (event.type === \"session.tool.failed\") {\n const current = tools.get(event.data.callID) ?? fallbackTool(event)\n const error = event.data.error.message\n const part: MiniToolPart = {\n id: current.id,\n sessionID: input.sessionID,\n messageID: event.data.assistantMessageID,\n type: \"tool\",\n callID: event.data.callID,\n tool: current.tool,\n state: {\n status: \"error\",\n input: current.input,\n error,\n metadata: {\n result: event.data.result,\n providerCall: current.provider,\n providerResult: { executed: event.data.executed, state: event.data.resultState },\n rawInput: current.raw,\n },\n time: { start: current.timestamp, end: time },\n },\n }\n tools.delete(event.data.callID)\n if (!emit(\"tool_use\", time, { part })) {\n await input.renderToolError(part)\n UI.error(error)\n }\n continue\n }\n\n if (event.type === \"session.step.ended\") {\n const part = {\n id: partID(event.id),\n sessionID: input.sessionID,\n messageID: event.data.assistantMessageID,\n type: \"step-finish\",\n reason: event.data.finish,\n snapshot: event.data.snapshot,\n cost: event.data.cost,\n tokens: event.data.tokens,\n }\n emit(\"step_finish\", time, { part })\n continue\n }\n if (event.type === \"session.step.failed\") {\n if (interrupted || permissionRejected || questionRejected || formCancelled) continue\n emittedError = true\n process.exitCode = 1\n if (!emit(\"error\", time, { error: event.data.error })) UI.error(event.data.error.message)\n continue\n }\n if (event.type === \"session.execution.failed\") {\n if (!emittedError && !questionRejected && !formCancelled) {\n emittedError = true\n process.exitCode = 1\n if (!emit(\"error\", time, { error: event.data.error })) UI.error(event.data.error.message)\n }\n return\n }\n if (event.type === \"session.execution.interrupted\") {\n if (event.data.reason === \"user\" && interrupted) process.exitCode = 130\n if (event.data.reason !== \"user\" && !emittedError) {\n emittedError = true\n process.exitCode = 1\n const error = { type: \"aborted\" as const, message: `Session interrupted: ${event.data.reason}` }\n if (!emit(\"error\", time, { error })) UI.error(error.message)\n }\n return\n }\n if (event.type === \"session.execution.succeeded\") return\n }\n }\n\n const interrupt = () => {\n if (interrupted) process.exit(130)\n interrupted = true\n process.exitCode = 130\n admission?.abort()\n void input.client.session.interrupt({ sessionID: input.sessionID }).catch(() => {})\n }\n process.on(\"SIGINT\", interrupt)\n\n let completed: Promise<void> | undefined\n try {\n if (input.agent) {\n await input.client.session.switchAgent({ sessionID: input.sessionID, agent: input.agent })\n }\n const selected = input.model\n ? { providerID: input.model.providerID, id: input.model.modelID, variant: input.variant }\n : input.variant\n ? await input.client.session\n .get({ sessionID: input.sessionID })\n .then((result) => result.model)\n .then(async (model) => {\n if (model) return { ...model, variant: input.variant }\n const result = await input.client.model.default()\n const fallback = result.data\n return fallback ? { providerID: fallback.providerID, id: fallback.id, variant: input.variant } : undefined\n })\n : undefined\n if (input.variant && !selected) throw new Error(\"Cannot select a variant before selecting a model\")\n if (selected) {\n await input.client.session.switchModel({ sessionID: input.sessionID, model: selected })\n }\n\n const prepared = await Promise.all(input.files.map(prepareFile))\n if (interrupted) return\n submitted = true\n completed = consume()\n admission = new AbortController()\n const response = await input.client.session\n .prompt(\n {\n sessionID: input.sessionID,\n id: messageID,\n text: [input.message, ...prepared.flatMap((file) => (file.text ? [file.text] : []))].join(\"\\n\\n\"),\n files: prepared.flatMap((file) => (file.attachment ? [file.attachment] : [])),\n delivery: \"steer\",\n },\n { signal: admission.signal },\n )\n .catch(async (error) => {\n if (interrupted) {\n await input.client.session.interrupt({ sessionID: input.sessionID }).catch(() => {})\n }\n controller.abort()\n await completed?.catch(() => {})\n if (interrupted || emittedError) return undefined\n throw error\n })\n admission = undefined\n if (!response) return\n if (interrupted) await input.client.session.interrupt({ sessionID: input.sessionID }).catch(() => {})\n\n const [permissions, questions, forms] = await Promise.all([\n input.client.permission.list({ sessionID: input.sessionID }).catch(() => undefined),\n input.client.question.list({ sessionID: input.sessionID }).catch(() => undefined),\n Promise.all(\n (input.attached ? [input.sessionID] : [input.sessionID, GLOBAL_FORM_SESSION_ID]).map((sessionID) =>\n input.client.form.list({ sessionID }).catch(() => undefined),\n ),\n ),\n ])\n await Promise.all([\n ...(permissions ?? []).map(replyPermission),\n ...(questions ?? []).map(rejectQuestion),\n ...forms.flatMap((response) => response ?? []).map(cancelForm),\n ])\n await completed\n } finally {\n process.off(\"SIGINT\", interrupt)\n controller.abort()\n await stream.return?.(undefined).catch(() => {})\n }\n}\n\nfunction partID(eventID: string) {\n return `prt_${eventID.replace(/^evt_/, \"\")}`\n}\n\nfunction fallbackTool(event: {\n id: string\n created: number\n data: { assistantMessageID: string; callID: string }\n}): ToolState {\n return {\n id: partID(event.id),\n timestamp: toMillis(event.created),\n assistantMessageID: event.data.assistantMessageID,\n tool: \"tool\",\n input: {},\n }\n}\n\nfunction toMillis(value: unknown) {\n if (typeof value === \"number\") return value\n if (typeof value === \"string\") return new Date(value).getTime()\n return Date.now()\n}\n\nasync function prepareFile(file: File) {\n if (file.mime !== \"text/plain\") {\n const uri = file.url.startsWith(\"data:\")\n ? file.url\n : `data:${file.mime};base64,${Buffer.from(await Bun.file(new URL(file.url)).arrayBuffer()).toString(\"base64\")}`\n return { attachment: { uri, mime: file.mime, name: file.filename } }\n }\n const content = file.url.startsWith(\"data:\")\n ? Buffer.from(file.url.slice(file.url.indexOf(\",\") + 1), \"base64\").toString(\"utf8\")\n : await Bun.file(new URL(file.url)).text()\n return { text: `<file name=\"${file.filename}\">\\n${content}\\n</file>` }\n}\n", | ||
| "import { EOL } from \"node:os\"\n\nexport const Style = {\n TEXT_DIM: \"\\x1b[90m\",\n TEXT_NORMAL: \"\\x1b[0m\",\n TEXT_WARNING_BOLD: \"\\x1b[93m\\x1b[1m\",\n TEXT_DANGER_BOLD: \"\\x1b[91m\\x1b[1m\",\n}\n\nexport function println(...message: string[]) {\n process.stderr.write(message.join(\" \") + EOL)\n}\n\nlet blank = false\n\nexport function empty() {\n if (blank) return\n println(Style.TEXT_NORMAL)\n blank = true\n}\n\nexport function error(message: string) {\n if (message.startsWith(\"Error: \")) message = message.slice(\"Error: \".length)\n println(Style.TEXT_DANGER_BOLD + \"Error: \" + Style.TEXT_NORMAL + message)\n}\n\nexport * as UI from \"./ui\"\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "9F855CE6CA039D0464756E2164756E21", | ||
| "names": [] | ||
| } |
+1
-1
| { | ||
| "name": "@opencode-ai/cli-linux-arm64", | ||
| "version": "0.0.0-next-15615", | ||
| "version": "0.0.0-next-15616", | ||
| "license": "MIT", | ||
@@ -5,0 +5,0 @@ "repository": { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/mcp/logout.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"node:os\"\nimport { Effect } from \"effect\"\nimport { OpenCode } from \"@opencode-ai/client\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { ServiceConfig } from \"../../../services/service-config\"\nimport { resolveIntegration } from \"./resolve\"\n\nconst location = { directory: process.cwd() }\n\nexport default Runtime.handler(\n Commands.commands.mcp.commands.logout,\n Effect.fn(\"cli.mcp.logout\")(function* (input) {\n const options = yield* ServiceConfig.options()\n const found = yield* Service.discover(options)\n const endpoint = found ?? (yield* Service.ensure(options))\n const client = OpenCode.make({ baseUrl: endpoint.url, headers: Service.headers(endpoint) })\n\n const integration = yield* resolveIntegration(client, input.name, location)\n if (!integration) {\n process.stdout.write(`No stored credentials for ${input.name}` + EOL)\n return\n }\n\n const credentials = integration.connections.filter((connection) => connection.type === \"credential\")\n if (credentials.length === 0) {\n process.stdout.write(`No stored credentials for ${input.name}` + EOL)\n return\n }\n\n yield* Effect.forEach(\n credentials,\n (connection) => Effect.promise(() => client.credential.remove({ credentialID: connection.id, location })),\n { discard: true },\n )\n process.stdout.write(`Removed OAuth credentials for ${input.name}` + EOL)\n }),\n)\n" | ||
| ], | ||
| "mappings": ";46BAAA,mBAAS,gBAST,SAAM,OAAW,MAAE,eAAW,aAAQ,SAAI,MAAE,OAE7B,SAAQ,aACrB,OAAS,cAAS,SAAI,cAAS,YAC/B,OAAO,QAAG,qBAAgB,OAAE,cAAU,MAAC,OAAO,CAC5C,IAAM,EAAU,MAAO,EAAc,QAAQ,EAEvC,GADQ,MAAO,EAAQ,SAAS,CAAO,KAClB,MAAO,EAAQ,OAAO,CAAO,GAClD,EAAS,EAAS,KAAK,CAAE,QAAS,EAAS,IAAK,QAAS,EAAQ,QAAQ,CAAQ,CAAE,CAAC,EAEpF,EAAc,MAAO,EAAmB,EAAQ,EAAM,KAAM,CAAQ,EAC1E,GAAI,CAAC,EAAa,CAChB,QAAQ,OAAO,MAAM,6BAA6B,EAAM,OAAS,CAAG,EACpE,OAGF,IAAM,EAAc,EAAY,YAAY,OAAO,CAAC,IAAe,EAAW,OAAS,YAAY,EACnG,GAAI,EAAY,SAAW,EAAG,CAC5B,QAAQ,OAAO,MAAM,6BAA6B,EAAM,OAAS,CAAG,EACpE,OAGF,MAAO,EAAO,QACZ,EACA,CAAC,IAAe,EAAO,QAAQ,IAAM,EAAO,WAAW,OAAO,CAAE,aAAc,EAAW,GAAI,UAAS,CAAC,CAAC,EACxG,CAAE,QAAS,EAAK,CAClB,EACA,QAAQ,OAAO,MAAM,iCAAiC,EAAM,OAAS,CAAG,EACzE,CACH", | ||
| "debugId": "128E986EA0F6A45764756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/debug/agents.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"os\"\nimport { Effect } from \"effect\"\nimport { OpenCode } from \"@opencode-ai/client\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { ServiceConfig } from \"../../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.debug.commands.agents,\n Effect.fn(\"cli.debug.agents\")(function* () {\n const options = yield* ServiceConfig.options()\n const found = yield* Service.discover(options)\n const endpoint = found ?? (yield* Service.ensure(options))\n const client = OpenCode.make({ baseUrl: endpoint.url, headers: Service.headers(endpoint) })\n const response = yield* Effect.promise(() => client.agent.list({ location: { directory: process.cwd() } }))\n process.stdout.write(\n JSON.stringify(\n response.data.toSorted((a, b) => a.id.localeCompare(b.id)),\n null,\n 2,\n ) + EOL,\n )\n }),\n)\n" | ||
| ], | ||
| "mappings": ";83BAAA,mBAAS,gBAQT,SAAe,SAAQ,aACrB,OAAS,cAAS,WAAM,cAAS,YACjC,OAAO,QAAG,uBAAkB,OAAE,cAAU,OAAG,MACzC,SAAM,OAAU,WAAO,OAAc,aAAQ,OAEvC,GADQ,MAAO,EAAQ,SAAS,CAAO,KAClB,MAAO,EAAQ,OAAO,CAAO,GAClD,EAAS,EAAS,KAAK,CAAE,QAAS,EAAS,IAAK,QAAS,EAAQ,QAAQ,CAAQ,CAAE,CAAC,EACpF,EAAW,MAAO,EAAO,QAAQ,IAAM,EAAO,MAAM,KAAK,CAAE,SAAU,CAAE,UAAW,QAAQ,IAAI,CAAE,CAAE,CAAC,CAAC,EAC1G,QAAQ,OAAO,MACb,KAAK,UACH,EAAS,KAAK,SAAS,CAAC,EAAG,IAAM,EAAE,GAAG,cAAc,EAAE,EAAE,CAAC,EACzD,KACA,CACF,EAAI,CACN,EACD,CACH", | ||
| "debugId": "86C356217D397D6964756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/service/restart.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"os\"\nimport { Effect } from \"effect\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { ServiceConfig } from \"../../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.service.commands.restart,\n Effect.fn(\"cli.service.restart\")(function* () {\n const options = yield* ServiceConfig.options()\n yield* Service.stop(options)\n const transport = yield* Service.ensure(options)\n process.stdout.write(transport.url + EOL)\n }),\n)\n" | ||
| ], | ||
| "mappings": ";+0BAAA,mBAAS,gBAOT,SAAe,SAAQ,aACrB,OAAS,cAAS,aAAQ,cAAS,aACnC,OAAO,QAAG,0BAAqB,OAAE,cAAU,OAAG,MAC5C,SAAM,OAAU,WAAO,OAAc,aAAQ,EAC7C,MAAO,EAAQ,KAAK,CAAO,EAC3B,IAAM,EAAY,MAAO,EAAQ,OAAO,CAAO,EAC/C,QAAQ,OAAO,MAAM,EAAU,IAAM,CAAG,EACzC,CACH", | ||
| "debugId": "F4DFDB02865C6A0B64756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/mcp/auth.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"node:os\"\nimport { Effect } from \"effect\"\nimport {\n OpenCode,\n type IntegrationAttemptStatus,\n type IntegrationOAuthMethod,\n type OpenCodeClient,\n} from \"@opencode-ai/client\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { ServiceConfig } from \"../../../services/service-config\"\nimport { resolveIntegration } from \"./resolve\"\n\nconst location = { directory: process.cwd() }\n\nexport default Runtime.handler(\n Commands.commands.mcp.commands.auth,\n Effect.fn(\"cli.mcp.auth\")(function* (input) {\n const options = yield* ServiceConfig.options()\n const found = yield* Service.discover(options)\n const endpoint = found ?? (yield* Service.ensure(options))\n const client = OpenCode.make({ baseUrl: endpoint.url, headers: Service.headers(endpoint) })\n\n const integration = yield* resolveIntegration(client, input.name, location)\n if (!integration)\n return yield* Effect.fail(new Error(`MCP server \"${input.name}\" is not an OAuth-capable remote server`))\n const method = integration.methods.find(\n (candidate): candidate is IntegrationOAuthMethod => candidate.type === \"oauth\",\n )\n if (!method)\n return yield* Effect.fail(new Error(`MCP server \"${input.name}\" is not an OAuth-capable remote server`))\n\n const started = yield* Effect.promise(() =>\n client.integration.connect.oauth({ integrationID: integration.id, methodID: method.id, inputs: {}, location }),\n )\n const attempt = started.data\n if (attempt.mode === \"code\")\n return yield* Effect.fail(new Error(\"This server requires manual code entry, which the CLI does not support\"))\n\n process.stdout.write(attempt.instructions + EOL + attempt.url + EOL)\n\n const result = yield* poll(client, attempt.attemptID)\n if (result.status === \"complete\") {\n process.stdout.write(`Authenticated with ${input.name}` + EOL)\n return\n }\n const reason = result.status === \"failed\" ? `: ${result.message}` : \"\"\n return yield* Effect.fail(new Error(`Authentication ${result.status}${reason}`))\n }),\n)\n\nconst poll = (\n client: OpenCodeClient,\n attemptID: string,\n): Effect.Effect<Exclude<IntegrationAttemptStatus, { status: \"pending\" }>> =>\n Effect.gen(function* () {\n const status = yield* Effect.promise(() => client.integration.attempt.status({ attemptID, location })).pipe(\n Effect.map((result) => result.data),\n )\n if (status.status === \"pending\") {\n yield* Effect.sleep(\"1 second\")\n return yield* poll(client, attemptID)\n }\n return status\n })\n" | ||
| ], | ||
| "mappings": ";46BAAA,mBAAS,gBAcT,SAAM,OAAW,MAAE,eAAW,aAAQ,SAAI,MAAE,OAE7B,SAAQ,aACrB,OAAS,cAAS,SAAI,cAAS,UAC/B,OAAO,QAAG,mBAAc,OAAE,cAAU,MAAC,OAAO,CAC1C,IAAM,EAAU,MAAO,EAAc,QAAQ,EAEvC,GADQ,MAAO,EAAQ,SAAS,CAAO,KAClB,MAAO,EAAQ,OAAO,CAAO,GAClD,EAAS,EAAS,KAAK,CAAE,QAAS,EAAS,IAAK,QAAS,EAAQ,QAAQ,CAAQ,CAAE,CAAC,EAEpF,EAAc,MAAO,EAAmB,EAAQ,EAAM,KAAM,CAAQ,EAC1E,GAAI,CAAC,EACH,OAAO,MAAO,EAAO,KAAS,MAAM,eAAe,EAAM,6CAA6C,CAAC,EACzG,IAAM,EAAS,EAAY,QAAQ,KACjC,CAAC,IAAmD,EAAU,OAAS,OACzE,EACA,GAAI,CAAC,EACH,OAAO,MAAO,EAAO,KAAS,MAAM,eAAe,EAAM,6CAA6C,CAAC,EAKzG,IAAM,GAHU,MAAO,EAAO,QAAQ,IACpC,EAAO,YAAY,QAAQ,MAAM,CAAE,cAAe,EAAY,GAAI,SAAU,EAAO,GAAI,OAAQ,CAAC,EAAG,UAAS,CAAC,CAC/G,GACwB,KACxB,GAAI,EAAQ,OAAS,OACnB,OAAO,MAAO,EAAO,KAAS,MAAM,wEAAwE,CAAC,EAE/G,QAAQ,OAAO,MAAM,EAAQ,aAAe,EAAM,EAAQ,IAAM,CAAG,EAEnE,IAAM,EAAS,MAAO,EAAK,EAAQ,EAAQ,SAAS,EACpD,GAAI,EAAO,SAAW,WAAY,CAChC,QAAQ,OAAO,MAAM,sBAAsB,EAAM,OAAS,CAAG,EAC7D,OAEF,IAAM,EAAS,EAAO,SAAW,SAAW,KAAK,EAAO,UAAY,GACpE,OAAO,MAAO,EAAO,KAAS,MAAM,kBAAkB,EAAO,SAAS,GAAQ,CAAC,EAChF,CACH,EAEM,EAAO,CACX,EACA,IAEA,EAAO,IAAI,SAAU,EAAG,CACtB,IAAM,EAAS,MAAO,EAAO,QAAQ,IAAM,EAAO,YAAY,QAAQ,OAAO,CAAE,YAAW,UAAS,CAAC,CAAC,EAAE,KACrG,EAAO,IAAI,CAAC,IAAW,EAAO,IAAI,CACpC,EACA,GAAI,EAAO,SAAW,UAEpB,OADA,MAAO,EAAO,MAAM,UAAU,EACvB,MAAO,EAAK,EAAQ,CAAS,EAEtC,OAAO,EACR", | ||
| "debugId": "6FC79C44CEF46BE664756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/service/get.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"os\"\nimport { Effect, Option } from \"effect\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { ServiceConfig } from \"../../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.service.commands.get,\n Effect.fn(\"cli.service.get\")(function* (input) {\n process.stdout.write((yield* ServiceConfig.get(Option.getOrUndefined(input.key))) + EOL)\n }),\n)\n" | ||
| ], | ||
| "mappings": ";00BAAA,mBAAS,gBAMT,SAAe,SAAQ,aACrB,OAAS,cAAS,aAAQ,cAAS,SACnC,OAAO,QAAG,sBAAiB,OAAE,cAAU,MAAC,OAAO,MAC7C,aAAQ,YAAO,YAAO,WAAO,EAAc,IAAI,EAAO,eAAe,EAAM,GAAG,CAAC,GAAK,CAAG,EACxF,CACH", | ||
| "debugId": "F1F831C283E3AAE264756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/mcp/list.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"node:os\"\nimport { Effect } from \"effect\"\nimport { OpenCode, type McpServer } from \"@opencode-ai/client\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { ServiceConfig } from \"../../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.mcp.commands.list,\n Effect.fn(\"cli.mcp.list\")(function* () {\n const options = yield* ServiceConfig.options()\n const found = yield* Service.discover(options)\n const endpoint = found ?? (yield* Service.ensure(options))\n const client = OpenCode.make({ baseUrl: endpoint.url, headers: Service.headers(endpoint) })\n const response = yield* Effect.promise(() => client.mcp.list({ location: { directory: process.cwd() } }))\n const servers = response.data.toSorted((a, b) => a.name.localeCompare(b.name))\n if (servers.length === 0) {\n process.stdout.write(\"No MCP servers configured\" + EOL)\n return\n }\n const width = Math.max(...servers.map((server) => server.name.length))\n const lines = servers.map(\n (server) => `${icon(server.status)} ${server.name.padEnd(width)} ${describe(server.status)}`,\n )\n process.stdout.write(lines.join(EOL) + EOL)\n }),\n)\n\nfunction icon(status: McpServer[\"status\"]) {\n switch (status.status) {\n case \"connected\":\n return \"✓\"\n case \"needs_auth\":\n return \"⚠\"\n case \"failed\":\n case \"needs_client_registration\":\n return \"✗\"\n default:\n return \"○\"\n }\n}\n\nfunction describe(status: McpServer[\"status\"]) {\n switch (status.status) {\n case \"needs_auth\":\n return \"needs authentication\"\n case \"needs_client_registration\":\n return `needs client registration: ${status.error}`\n case \"failed\":\n return `failed: ${status.error}`\n default:\n return status.status\n }\n}\n" | ||
| ], | ||
| "mappings": ";83BAAA,mBAAS,gBAQT,SAAe,SAAQ,aACrB,OAAS,cAAS,SAAI,cAAS,UAC/B,OAAO,QAAG,mBAAc,OAAE,cAAU,OAAG,MACrC,SAAM,OAAU,WAAO,OAAc,aAAQ,OAEvC,GADQ,MAAO,EAAQ,SAAS,CAAO,KAClB,MAAO,EAAQ,OAAO,CAAO,GAClD,EAAS,EAAS,KAAK,CAAE,QAAS,EAAS,IAAK,QAAS,EAAQ,QAAQ,CAAQ,CAAE,CAAC,EAEpF,GADW,MAAO,EAAO,QAAQ,IAAM,EAAO,IAAI,KAAK,CAAE,SAAU,CAAE,UAAW,QAAQ,IAAI,CAAE,CAAE,CAAC,CAAC,GAC/E,KAAK,SAAS,CAAC,EAAG,IAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC,EAC7E,GAAI,EAAQ,SAAW,EAAG,CACxB,QAAQ,OAAO,MAAM,4BAA8B,CAAG,EACtD,OAEF,IAAM,EAAQ,KAAK,IAAI,GAAG,EAAQ,IAAI,CAAC,IAAW,EAAO,KAAK,MAAM,CAAC,EAC/D,EAAQ,EAAQ,IACpB,CAAC,IAAW,GAAG,EAAK,EAAO,MAAM,KAAK,EAAO,KAAK,OAAO,CAAK,MAAM,EAAS,EAAO,MAAM,GAC5F,EACA,QAAQ,OAAO,MAAM,EAAM,KAAK,CAAG,EAAI,CAAG,EAC3C,CACH,EAEA,SAAS,CAAI,CAAC,EAA6B,CACzC,OAAQ,EAAO,YACR,YACH,MAAO,aACJ,aACH,MAAO,aACJ,aACA,4BACH,MAAO,iBAEP,MAAO,UAIb,SAAS,CAAQ,CAAC,EAA6B,CAC7C,OAAQ,EAAO,YACR,aACH,MAAO,2BACJ,4BACH,MAAO,8BAA8B,EAAO,YACzC,SACH,MAAO,WAAW,EAAO,gBAEzB,OAAO,EAAO", | ||
| "debugId": "5577B2D4F97EA30064756E2164756E21", | ||
| "names": [] | ||
| } |
Sorry, the diff of this file is too big to display
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/run.ts"], | ||
| "sourcesContent": [ | ||
| "import { Effect, Option } from \"effect\"\nimport { Commands } from \"../commands\"\nimport { Runtime } from \"../../framework/runtime\"\nimport { ServerConnection } from \"../../services/server-connection\"\n\nexport default Runtime.handler(Commands.commands.run, (input) =>\n Effect.gen(function* () {\n const { runNonInteractive } = yield* Effect.promise(() => import(\"../../mini\"))\n const separator = process.argv.indexOf(\"--\", 2)\n const server = yield* ServerConnection.resolve({\n server: Option.getOrUndefined(input.server),\n standalone: input.standalone,\n })\n yield* Effect.promise(() =>\n runNonInteractive({\n server,\n message: [...input.message, ...(separator === -1 ? [] : process.argv.slice(separator + 1))],\n continue: input.continue,\n session: Option.getOrUndefined(input.session),\n fork: input.fork,\n model: Option.getOrUndefined(input.model),\n agent: Option.getOrUndefined(input.agent),\n format: input.format,\n file: [...input.file],\n title: Option.getOrUndefined(input.title),\n thinking: input.thinking,\n auto: input.auto || input.yolo,\n }),\n )\n }),\n)\n" | ||
| ], | ||
| "mappings": ";+uCAKA,SAAe,SAAQ,aAAQ,OAAS,cAAS,SAAK,MAAC,SACrD,OAAO,SAAI,cAAU,OAAG,MACtB,SAAQ,0BAAsB,WAAO,OAAO,aAAQ,SAAa,wCAAa,OACxE,OAAY,aAAQ,UAAK,aAAQ,UAAM,MAAC,OACxC,OAAS,WAAO,OAAiB,aAAQ,MAC7C,YAAQ,OAAO,eAAe,EAAM,MAAM,EAC1C,WAAY,EAAM,UACpB,CAAC,EACD,MAAO,EAAO,QAAQ,IACpB,EAAkB,CAChB,SACA,QAAS,CAAC,GAAG,EAAM,QAAS,GAAI,IAAc,GAAK,CAAC,EAAI,QAAQ,KAAK,MAAM,EAAY,CAAC,CAAE,EAC1F,SAAU,EAAM,SAChB,QAAS,EAAO,eAAe,EAAM,OAAO,EAC5C,KAAM,EAAM,KACZ,MAAO,EAAO,eAAe,EAAM,KAAK,EACxC,MAAO,EAAO,eAAe,EAAM,KAAK,EACxC,OAAQ,EAAM,OACd,KAAM,CAAC,GAAG,EAAM,IAAI,EACpB,MAAO,EAAO,eAAe,EAAM,KAAK,EACxC,SAAU,EAAM,SAChB,KAAM,EAAM,MAAQ,EAAM,IAC5B,CAAC,CACH,EACD,CACH", | ||
| "debugId": "4FD7BD468F0220DB64756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["../client/src/effect/service.ts"], | ||
| "sourcesContent": [ | ||
| "import { ServiceStatus } from \"@opencode-ai/protocol/groups/health\"\nimport { Effect, FileSystem, Option, Schedule, Schema } from \"effect\"\nimport { spawn, type ChildProcess } from \"node:child_process\"\nimport { homedir } from \"node:os\"\nimport { join } from \"node:path\"\nimport type {\n DiscoverOptions,\n Endpoint,\n EnsureOptions,\n StopOptions,\n} from \"../service.js\"\n\nexport * from \"../service.js\"\n/** Contents of the local service registration file. */\nexport type Info = import(\"../service.js\").Info\n\n// Find, start, and stop the local opencode background service.\n//\n// The service daemon advertises itself through a registration file in the\n// user's state directory: url, pid, version, and the private password, with\n// 0600 permissions. That file is the complete discovery contract — reading it\n// is all a client needs to connect. The daemon's own configuration (port,\n// persisted password) is CLI-owned and never read here.\n\ntype Contender = {\n readonly child: ChildProcess\n readonly error: () => Error | undefined\n}\n\n// Read-only lookup: registration file plus health check and version gate.\n// Never spawns; escalation to ensure() is the caller's policy.\n/** Discover a healthy, compatible local service without starting one. */\nexport const discover = Effect.fn(\"service.discover\")(function* (options: DiscoverOptions = {}) {\n return (yield* discoverLocal(options))?.endpoint\n})\n\nconst discoverLocal = Effect.fnUntraced(function* (options: DiscoverOptions) {\n const found = (yield* registered(options.file)).service\n if (found?.state !== \"ready\") return undefined\n if (options.version !== undefined && found.version !== options.version) return undefined\n return found\n})\n\n// Idempotent ensure-running: reuses a healthy compatible server, replaces a\n// version-mismatched one, and otherwise spawns small contenders until a server\n// becomes discoverable. A contender is never killed merely for slow startup.\n/** Ensure a healthy, compatible local service is running. */\nexport const ensure = Effect.fn(\"service.ensure\")(function* (options: EnsureOptions = {}) {\n const contenders = new Set<Contender>()\n let announced = false\n let lastSpawn = 0\n let spawnDelay = 5_000\n let ownerHeld = false\n const announce = (reason: \"missing\" | \"version-mismatch\", previousVersion?: string) =>\n Effect.sync(() => {\n if (announced) return\n announced = true\n options.onStart?.(reason, previousVersion)\n })\n const spawnContender = Effect.gen(function* () {\n const [command, ...args] = options.command ?? [\"opencode\", \"serve\", \"--service\"]\n if (command === undefined) return yield* Effect.fail(new Error(\"Missing service command\"))\n return yield* Effect.try({\n try: () => {\n const child = spawn(command, args, { detached: true, stdio: \"ignore\" })\n let error: Error | undefined\n child.once(\"error\", (cause) => {\n error = new Error(\"Failed to start server\", { cause })\n })\n child.unref()\n return { child, error: () => error }\n },\n catch: (cause) => new Error(\"Failed to start server\", { cause }),\n })\n })\n const found = yield* Effect.gen(function* () {\n const registration = yield* registered(options.file, true)\n const info = registration.info\n const service = registration.service\n if (service !== undefined) {\n ownerHeld = false\n spawnDelay = 5_000\n const compatible = !service.legacy && (options.version === undefined || service.version === options.version)\n if (compatible && service.state === \"ready\") return Option.some(service)\n if (compatible && service.state === \"failed\") return yield* Effect.fail(new Error(\"Background service failed to start\"))\n if (compatible) return Option.none<LocalService>()\n yield* announce(\"version-mismatch\", service.version)\n yield* kill(service, options).pipe(Effect.ignore)\n lastSpawn = 0\n return Option.none<LocalService>()\n } else if (lastSpawn === 0 && info !== undefined) lastSpawn = Date.now()\n\n const failure = [...contenders].map(contenderFailure).find((error): error is Error => error !== undefined)\n if (failure !== undefined) return yield* Effect.fail(failure)\n const finished = [...contenders].filter(contenderFinished)\n if (finished.some((item) => item.child.exitCode === 0)) {\n ownerHeld = true\n spawnDelay = Math.min(spawnDelay * 2, 30_000)\n }\n finished.forEach((item) => contenders.delete(item))\n // Keep one candidate plus one lock probe so a pre-lock stall cannot block recovery.\n if (contenders.size < 2 && Date.now() - lastSpawn >= spawnDelay) {\n yield* announce(\"missing\")\n contenders.add(yield* spawnContender)\n lastSpawn = Date.now()\n }\n return Option.none<LocalService>()\n }).pipe(Effect.repeat({ until: Option.isSome, schedule: Schedule.spaced(\"1 second\") }))\n return Option.getOrThrow(found).endpoint\n})\n\nfunction contenderFailure(contender: Contender) {\n const error = contender.error()\n if (error !== undefined) return error\n if (contender.child.exitCode !== null && contender.child.exitCode !== 0)\n return new Error(`Server process exited with code ${contender.child.exitCode}`)\n if (contender.child.signalCode !== null)\n return new Error(`Server process terminated by ${contender.child.signalCode}`)\n return undefined\n}\n\nfunction contenderFinished(contender: Contender) {\n return contender.error() !== undefined || contender.child.exitCode !== null || contender.child.signalCode !== null\n}\n\n/** Stop the registered local service. */\nexport const stop = Effect.fn(\"service.stop\")(function* (options: StopOptions = {}) {\n const existing = yield* find(options)\n if (existing !== undefined) yield* kill(existing, options)\n})\n\nfunction fallback() {\n const state = process.env[\"XDG_STATE_HOME\"] ?? join(homedir(), \".local\", \"state\")\n return join(state, \"opencode\", \"service.json\")\n}\n\n/** Create HTTP authentication headers for a service endpoint. */\nexport function headers(endpoint: Endpoint) {\n if (endpoint.auth === undefined) return undefined\n return { authorization: \"Basic \" + btoa(endpoint.auth.username + \":\" + endpoint.auth.password) }\n}\n\n/** Schema for the local service registration file. */\nexport const Info = Schema.Struct({\n id: Schema.optional(Schema.String),\n version: Schema.optional(Schema.String),\n url: Schema.String,\n pid: Schema.Int.check(Schema.isGreaterThan(0)),\n password: Schema.optional(Schema.String),\n})\n\nconst decode = Schema.decodeUnknownEffect(Schema.fromJsonString(Info))\nconst decodeHealth = Schema.decodeUnknownOption(ServiceStatus.Health)\nconst decodeLegacyHealth = Schema.decodeUnknownOption(Schema.Struct({ healthy: Schema.Literal(true) }))\n\n// A missing or corrupt file means no valid info; callers treat both\n// the same (the registering server self-evicts, clients rediscover).\nconst read = Effect.fnUntraced(function* (file?: string) {\n const fs = yield* FileSystem.FileSystem\n const text = yield* fs.readFileString(file ?? fallback()).pipe(Effect.option)\n if (Option.isNone(text)) return undefined\n return yield* decode(text.value).pipe(Effect.option, Effect.map(Option.getOrUndefined))\n})\n\ntype LocalService = {\n readonly info: Info\n readonly endpoint: Endpoint\n readonly version?: string\n readonly state: \"ready\" | \"waiting\" | \"failed\"\n readonly legacy: boolean\n}\n\nconst probe = Effect.fnUntraced(function* (info: Info, allowLegacy = false) {\n const endpoint = {\n url: info.url,\n auth:\n info.password === undefined\n ? undefined\n : { type: \"basic\" as const, username: \"opencode\", password: info.password },\n } satisfies Endpoint\n const response = yield* Effect.tryPromise(() =>\n fetch(new URL(\"/api/health\", info.url), {\n headers: headers(endpoint),\n signal: AbortSignal.timeout(2_000),\n }),\n ).pipe(Effect.option, Effect.map(Option.getOrUndefined))\n if (response === undefined) return undefined\n const body = yield* Effect.tryPromise(() => response.json()).pipe(Effect.option, Effect.map(Option.getOrUndefined))\n const health = decodeHealth(body)\n if (Option.isSome(health)) {\n if (health.value.pid !== info.pid) return undefined\n if (info.version !== undefined && health.value.version !== info.version) return undefined\n return {\n info,\n endpoint,\n version: health.value.version,\n state: response.ok ? \"ready\" : response.status === 500 ? \"failed\" : \"waiting\",\n legacy: false,\n } satisfies LocalService\n }\n if (\n !allowLegacy ||\n Option.isNone(decodeLegacyHealth(body)) ||\n (typeof body === \"object\" && body !== null && (\"version\" in body || \"pid\" in body))\n )\n return undefined\n return { info, endpoint, state: \"ready\", legacy: true } satisfies LocalService\n})\n\nconst registered = Effect.fnUntraced(function* (file?: string, allowLegacy = false) {\n const info = yield* read(file)\n if (info === undefined) return { info: undefined, service: undefined }\n return { info, service: yield* probe(info, allowLegacy) }\n})\n\n// Health-checked lookup without the version gate: lifecycle operations must be\n// able to see (and replace or stop) a server from a different version.\nconst find = Effect.fnUntraced(function* (options: { readonly file?: string }) {\n return (yield* registered(options.file, true)).service\n})\n\n// 50ms cadence bounded at ~5s, shared by stop escalation and each ensure\n// discovery window.\nconst poll = Schedule.spaced(\"50 millis\").pipe(Schedule.both(Schedule.recurs(100)))\n\nconst signal = (pid: number, name: NodeJS.Signals) =>\n Effect.try({ try: () => process.kill(pid, name), catch: (cause) => cause }).pipe(Effect.ignore)\n\nconst stopped = Effect.fnUntraced(function* (pid: number) {\n const running = yield* Effect.try({ try: () => process.kill(pid, 0), catch: () => false }).pipe(\n Effect.orElseSucceed(() => false),\n )\n if (!running) return true\n return yield* Effect.fail(new Error(`Server process ${pid} is still running`))\n})\n\nfunction same(left: Info, right: Info) {\n return left.id === right.id && left.version === right.version && left.url === right.url && left.pid === right.pid\n}\n\nconst kill = Effect.fnUntraced(function* (\n service: LocalService,\n options: { readonly file?: string },\n) {\n const requested = yield* requestStop(service)\n if (requested === \"rejected\") return\n if (requested === \"unsupported\") {\n // A stale registration may point at a reused PID. Authenticate again\n // immediately before the legacy signal fallback.\n const current = yield* find(options)\n if (current === undefined || !same(current.info, service.info)) return\n yield* signal(service.info.pid, \"SIGTERM\")\n }\n const done = yield* stopped(service.info.pid).pipe(Effect.retry(poll), Effect.option)\n if (Option.isSome(done)) return\n\n const latest = yield* find(options)\n if (latest === undefined || !same(latest.info, service.info)) return\n yield* signal(service.info.pid, \"SIGKILL\")\n yield* stopped(service.info.pid).pipe(Effect.retry(poll))\n})\n\nconst decodeStopResponse = Schema.decodeUnknownOption(ServiceStatus.StopResponse)\n\nconst requestStop = Effect.fnUntraced(function* (service: LocalService) {\n if (service.info.id === undefined || service.legacy) return \"unsupported\" as const\n const response = yield* Effect.tryPromise(() =>\n fetch(new URL(\"/api/service/stop\", service.info.url), {\n method: \"POST\",\n headers: { ...headers(service.endpoint), \"content-type\": \"application/json\" },\n body: JSON.stringify({ instanceID: service.info.id }),\n signal: AbortSignal.timeout(2_000),\n }),\n ).pipe(Effect.option, Effect.map(Option.getOrUndefined))\n if (response === undefined || response.status === 404 || response.status === 405) return \"unsupported\" as const\n const body = yield* Effect.tryPromise(() => response.json()).pipe(Effect.option, Effect.map(Option.getOrUndefined))\n const decoded = decodeStopResponse(body)\n if (!response.ok || Option.isNone(decoded) || !decoded.value.accepted) return \"rejected\" as const\n return \"accepted\" as const\n})\n\n/** Effect-based local service lifecycle operations. */\nexport const Service = { discover, ensure, stop, headers, Info }\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "007691B63A90C92F64756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/mini.ts"], | ||
| "sourcesContent": [ | ||
| "import { Effect, Option } from \"effect\"\nimport { Commands } from \"../commands\"\nimport { Runtime } from \"../../framework/runtime\"\nimport { ServerConnection } from \"../../services/server-connection\"\n\nexport default Runtime.handler(Commands.commands.mini, (input) =>\n Effect.gen(function* () {\n const { runMini, validateMiniTerminal } = yield* Effect.promise(() => import(\"../../mini\"))\n yield* Effect.promise(async () => validateMiniTerminal())\n const serverURL = Option.getOrUndefined(input.server)\n const server = yield* ServerConnection.resolve({ server: serverURL, standalone: input.standalone })\n yield* Effect.promise(() =>\n runMini({\n server,\n continue: input.continue,\n session: Option.getOrUndefined(input.session),\n fork: input.fork,\n model: Option.getOrUndefined(input.model),\n agent: Option.getOrUndefined(input.agent),\n prompt: Option.getOrUndefined(input.prompt),\n replay: input.replay,\n replayLimit: Option.getOrUndefined(input.replayLimit),\n demo: input.demo,\n }),\n )\n }),\n)\n" | ||
| ], | ||
| "mappings": ";+uCAKA,SAAe,SAAQ,aAAQ,OAAS,cAAS,UAAM,MAAC,SACtD,OAAO,SAAI,cAAU,OAAG,MACtB,SAAQ,eAAS,6BAAyB,WAAO,OAAO,aAAQ,SAAa,wCAAa,OAC1F,WAAO,OAAO,aAAQ,cAAY,OAAqB,MAAC,OACxD,SAAM,OAAY,OAAO,oBAAe,OAAM,WAAM,EAC9C,EAAS,MAAO,EAAiB,QAAQ,CAAE,OAAQ,EAAW,WAAY,EAAM,UAAW,CAAC,EAClG,MAAO,EAAO,QAAQ,IACpB,EAAQ,CACN,SACA,SAAU,EAAM,SAChB,QAAS,EAAO,eAAe,EAAM,OAAO,EAC5C,KAAM,EAAM,KACZ,MAAO,EAAO,eAAe,EAAM,KAAK,EACxC,MAAO,EAAO,eAAe,EAAM,KAAK,EACxC,OAAQ,EAAO,eAAe,EAAM,MAAM,EAC1C,OAAQ,EAAM,OACd,YAAa,EAAO,eAAe,EAAM,WAAW,EACpD,KAAM,EAAM,IACd,CAAC,CACH,EACD,CACH", | ||
| "debugId": "A547F1F6415682CA64756E2164756E21", | ||
| "names": [] | ||
| } |
Sorry, the diff of this file is too big to display
| { | ||
| "version": 3, | ||
| "sources": ["src/mini/mini.ts", "src/mini/run.ts", "src/mini/noninteractive.ts", "src/mini/ui.ts"], | ||
| "sourcesContent": [ | ||
| "import { Service } from \"@opencode-ai/client/effect/service\"\nimport { OpenCode, type OpenCodeClient } from \"@opencode-ai/client/promise\"\nimport { ServerConnection } from \"../services/server-connection\"\nimport { waitForCatalogReady } from \"./catalog.shared\"\nimport { INTERACTIVE_INPUT_ERROR, resolveInteractiveStdin } from \"./runtime.stdin\"\nimport type { RunInput, RunTuiConfig } from \"./types\"\n\nexport type MiniCommandInput = {\n server: ServerConnection.Resolved\n continue?: boolean\n session?: string\n fork?: boolean\n model?: string\n agent?: string\n prompt?: string\n replay?: boolean\n replayLimit?: number\n demo?: boolean\n tuiConfig?: RunTuiConfig | Promise<RunTuiConfig>\n}\n\ntype Session = Awaited<ReturnType<OpenCodeClient[\"session\"][\"get\"]>>\nexport async function runMini(input: MiniCommandInput) {\n validate(input)\n const initialInput = mergeInput(process.stdin.isTTY ? undefined : await Bun.stdin.text(), input.prompt)\n const runtimeTask = import(\"./runtime\")\n const directory = localDirectory()\n\n try {\n const sdk = OpenCode.make({\n baseUrl: input.server.endpoint.url,\n headers: Service.headers(input.server.endpoint),\n })\n const model = parseModel(input.model)\n let agentTask: Promise<string | undefined> | undefined\n const resolveAgent = () => {\n agentTask ??= validateAgent(sdk, directory, input.agent)\n return agentTask\n }\n const resolveSession = async () => {\n const [agent, selected] = await Promise.all([resolveAgent(), selectSession(sdk, directory, input)])\n const readyModel =\n model ?? (selected?.model ? { providerID: selected.model.providerID, modelID: selected.model.id } : undefined)\n if (readyModel) await waitForCatalogReady({ sdk, directory, model: readyModel })\n const session = selected ?? (await createSession(sdk, directory, agent, model))\n return { id: session.id, title: session.title, resume: selected !== undefined }\n }\n const create = (\n _sdk: OpenCodeClient,\n next: { agent: string | undefined; model: RunInput[\"model\"]; variant: string | undefined },\n ) => createSession(sdk, directory, next.agent, next.model, next.variant)\n const runtime = await runtimeTask\n await runtime.runInteractiveDeferredMode({\n sdk,\n directory,\n resolveAgent,\n session: resolveSession,\n createSession: create,\n agent: input.agent,\n model,\n variant: undefined,\n files: [],\n initialInput,\n thinking: true,\n replay: input.replay ?? true,\n replayLimit: input.replayLimit,\n demo: input.demo,\n tuiConfig: input.tuiConfig,\n })\n } catch (error) {\n if (error instanceof Error && error.message === INTERACTIVE_INPUT_ERROR) fail(error.message)\n throw error\n }\n}\n\nexport function validateMiniTerminal() {\n if (!process.stdout.isTTY) fail(\"opencode mini requires a TTY stdout\")\n}\n\n/** @internal Exported for testing. */\nexport function mergeInput(piped: string | undefined, prompt: string | undefined) {\n if (!prompt) return piped || undefined\n if (!piped) return prompt\n return piped + \"\\n\" + prompt\n}\n\nfunction validate(input: MiniCommandInput) {\n validateMiniTerminal()\n if (input.replayLimit !== undefined && (!Number.isInteger(input.replayLimit) || input.replayLimit <= 0)) {\n fail(\"--replay-limit must be a positive integer\")\n }\n if (input.fork && !input.continue && !input.session) fail(\"--fork requires --continue or --session\")\n resolveInteractiveStdin().cleanup?.()\n}\n\nfunction localDirectory(): string {\n const root = process.env.PWD ?? process.cwd()\n try {\n process.chdir(root)\n return process.cwd()\n } catch {\n fail(`Failed to change directory to ${root}`)\n }\n}\n\nfunction parseModel(value?: string): RunInput[\"model\"] {\n if (!value) return\n const [providerID, ...rest] = value.split(\"/\")\n const modelID = rest.join(\"/\")\n if (!providerID || !modelID) fail(\"--model must use the format provider/model\")\n return { providerID, modelID }\n}\n\nasync function validateAgent(sdk: OpenCodeClient, directory: string, name?: string) {\n if (!name) return\n const deadline = Date.now() + 5_000\n let agents: Awaited<ReturnType<OpenCodeClient[\"agent\"][\"list\"]>> | undefined\n while (Date.now() < deadline) {\n agents = await sdk.agent.list({ location: { directory } }).catch(() => undefined)\n const agent = agents?.data.find((item) => item.id === name)\n if (agent?.mode === \"subagent\") {\n warning(`agent \"${name}\" is a subagent, not a primary agent. Falling back to default agent`)\n return\n }\n if (agent) return name\n await Bun.sleep(25)\n }\n if (!agents) {\n warning(\"failed to list agents. Falling back to default agent\")\n return\n }\n warning(`agent \"${name}\" not found. Falling back to default agent`)\n}\n\nasync function selectSession(sdk: OpenCodeClient, directory: string, input: MiniCommandInput, preselected?: Session) {\n const selected =\n preselected ??\n (input.session\n ? await sdk.session.get({ sessionID: input.session }).catch(() => undefined)\n : input.continue\n ? await sdk.session\n .list({ directory, parentID: null, limit: 1, order: \"desc\" })\n .then((result) => result.data[0])\n : undefined)\n if (input.session && !selected) fail(\"Session not found\")\n if (!selected) return\n if (!input.fork) return selected\n return sdk.session.fork({ sessionID: selected.id })\n}\n\nasync function createSession(\n sdk: OpenCodeClient,\n directory: string,\n agent: string | undefined,\n model: RunInput[\"model\"],\n variant?: string,\n): Promise<Session> {\n if (model) await waitForCatalogReady({ sdk, directory, model })\n return sdk.session.create({\n agent,\n model: model ? { providerID: model.providerID, id: model.modelID, variant } : undefined,\n location: { directory },\n })\n}\n\nfunction warning(message: string) {\n process.stderr.write(`\\x1b[93m\\x1b[1m!\\x1b[0m ${message}\\n`)\n}\n\nfunction fail(message: string): never {\n process.stderr.write(`\\x1b[91m\\x1b[1mError: \\x1b[0m${message}\\n`)\n process.exit(1)\n}\n", | ||
| "import { Service, type Endpoint } from \"@opencode-ai/client/effect/service\"\nimport { OpenCode, type OpenCodeClient } from \"@opencode-ai/client/promise\"\nimport { FSUtil } from \"@opencode-ai/core/fs-util\"\nimport { Model } from \"@opencode-ai/schema/model\"\nimport { open } from \"node:fs/promises\"\nimport path from \"node:path\"\nimport { ServerConnection } from \"../services/server-connection\"\nimport { loadRunAgents, waitForCatalogReady } from \"./catalog.shared\"\nimport { runNonInteractivePrompt } from \"./noninteractive\"\nimport { toolInlineInfo } from \"./tool\"\nimport type { MiniToolPart } from \"./types\"\nimport { UI } from \"./ui\"\n\nexport type RunCommandInput = {\n server: ServerConnection.Resolved\n message: string[]\n continue?: boolean\n session?: string\n fork?: boolean\n model?: string\n agent?: string\n format: \"default\" | \"json\"\n file: string[]\n title?: string\n thinking?: boolean\n auto?: boolean\n}\n\ntype FilePart = {\n url: string\n filename: string\n mime: string\n}\n\ntype Prepared = {\n directory?: string\n message: string\n files: FilePart[]\n}\n\nconst ATTACH_FILE_MAX_BYTES = 10 * 1024 * 1024\n\nexport function runNonInteractive(input: RunCommandInput) {\n return run(input).catch((error) => reportError(input, error instanceof Error ? error.message : String(error)))\n}\n\nasync function run(input: RunCommandInput) {\n if (input.fork && !input.continue && !input.session) fail(\"--fork requires --continue or --session\")\n const root = process.env.PWD ?? process.cwd()\n const directory = localDirectory(root)\n const message = mergeInput(formatMessage(input.message), process.stdin.isTTY ? undefined : await Bun.stdin.text())\n if (!message?.trim()) fail(\"You must provide a message\")\n const files = await Promise.all(input.file.map((file) => prepareFile(file, root)))\n const prepared = { directory, message, files }\n return execute(input, prepared, input.server.endpoint)\n}\n\nasync function execute(input: RunCommandInput, prepared: Prepared, endpoint: Endpoint) {\n const client = OpenCode.make({ baseUrl: endpoint.url, headers: Service.headers(endpoint) })\n const requestedDirectory = prepared.directory ?? (await client.location.get()).directory\n if (!requestedDirectory) fail(\"Failed to resolve server directory\")\n const session = await selectSession(client, requestedDirectory, input)\n const cwd = session?.location.directory ?? requestedDirectory\n const workspace = session?.location.workspaceID\n const explicit = parseRunModel(input.model)\n const explicitModel = explicit?.model\n const variant = explicit?.variant\n const sessionModel = session?.model ? { providerID: session.model.providerID, modelID: session.model.id } : undefined\n const defaultModel =\n !explicitModel && !sessionModel\n ? await client.model\n .default({ location: { directory: cwd, workspace } })\n .then((result) => (result.data ? { providerID: result.data.providerID, modelID: result.data.id } : undefined))\n : undefined\n const model = pickRunModel(explicitModel, variant, sessionModel, defaultModel)\n if (variant && !model) return reportError(input, \"Cannot select a variant before selecting a model\", session?.id)\n if (model) {\n await waitForCatalogReady({ sdk: client, directory: cwd, workspace, model })\n const available = await client.model.list({ location: { directory: cwd, workspace } })\n if (!available.data.some((item) => item.providerID === model.providerID && item.id === model.modelID))\n return reportError(input, `Model unavailable: ${model.providerID}/${model.modelID}`, session?.id)\n }\n const agent = await validateAgent(client, cwd, input.agent)\n const selected =\n session ??\n (await client.session.create({\n agent,\n model: model ? { providerID: model.providerID, id: model.modelID, variant } : undefined,\n location: { directory: cwd },\n }))\n if (!session && input.title !== undefined) {\n await client.session.rename({\n sessionID: selected.id,\n title: input.title || prepared.message.slice(0, 50) + (prepared.message.length > 50 ? \"...\" : \"\"),\n })\n }\n\n await runNonInteractivePrompt({\n client,\n sessionID: selected.id,\n message: prepared.message,\n files: prepared.files,\n agent,\n model,\n variant,\n thinking: input.thinking ?? false,\n format: input.format,\n auto: input.auto ?? false,\n attached: true,\n renderTool,\n renderToolError,\n }).catch((error) => reportError(input, error instanceof Error ? error.message : String(error), selected.id))\n}\n\nexport function mergeInput(message: string | undefined, piped: string | undefined) {\n if (!message) return piped || undefined\n if (!piped) return message\n return message + \"\\n\" + piped\n}\n\nexport function pickRunModel(\n explicit: { providerID: string; modelID: string } | undefined,\n variant: string | undefined,\n session: { providerID: string; modelID: string } | undefined,\n fallback: { providerID: string; modelID: string } | undefined,\n) {\n if (explicit) return explicit\n if (!variant) return\n return session ?? fallback\n}\n\nfunction formatMessage(message: string[]) {\n const value = message.map((part) => (part.includes(\" \") ? `\"${part.replace(/\"/g, '\\\\\"')}\"` : part)).join(\" \")\n return value || undefined\n}\n\nfunction localDirectory(root: string) {\n try {\n process.chdir(root)\n return process.cwd()\n } catch {\n fail(`Failed to change directory to ${root}`)\n }\n}\n\nexport function parseRunModel(value?: string) {\n if (!value) return\n const ref = Model.Ref.parse(value)\n return {\n model: { providerID: ref.providerID, modelID: ref.id },\n variant: ref.variant,\n }\n}\n\nasync function validateAgent(client: OpenCodeClient, directory: string, name?: string) {\n if (!name) return\n const agents = await loadRunAgents(client, directory).catch(() => undefined)\n if (!agents) {\n warning(\"failed to list agents. Falling back to default agent\")\n return\n }\n const agent = agents.find((item) => item.id === name)\n if (!agent) {\n warning(`agent \"${name}\" not found. Falling back to default agent`)\n return\n }\n if (agent.mode === \"subagent\") {\n warning(`agent \"${name}\" is a subagent, not a primary agent. Falling back to default agent`)\n return\n }\n return name\n}\n\nasync function selectSession(client: OpenCodeClient, directory: string, input: RunCommandInput) {\n const selected = input.session\n ? await client.session.get({ sessionID: input.session }).catch(() => undefined)\n : input.continue\n ? await client.session\n .list({ directory, parentID: null, limit: 1, order: \"desc\" })\n .then((result) => result.data[0])\n : undefined\n if (input.session && !selected) fail(\"Session not found\")\n if (!selected || !input.fork) return selected\n return client.session.fork({ sessionID: selected.id })\n}\n\nasync function prepareFile(input: string, directory: string): Promise<FilePart> {\n const file = path.resolve(directory, input)\n const handle = await open(file, \"r\").catch(() => fail(`File not found: ${input}`))\n try {\n const stat = await handle.stat()\n if (!stat.isFile() || stat.size > ATTACH_FILE_MAX_BYTES)\n fail(`Cannot attach a directory, special file, or file larger than 10 MiB: ${input}`)\n const content = Buffer.alloc(Number(stat.size))\n let offset = 0\n while (offset < content.length) {\n const read = await handle.read(content, offset, content.length - offset, offset)\n if (read.bytesRead === 0) break\n offset += read.bytesRead\n }\n const bytes = content.subarray(0, offset)\n const detected = FSUtil.mimeType(file)\n const text = bytes.toString(\"utf8\")\n const mime =\n detected.startsWith(\"image/\") || detected === \"application/pdf\"\n ? detected\n : !isBinaryContent(bytes) && Buffer.from(text, \"utf8\").equals(bytes)\n ? \"text/plain\"\n : detected\n return {\n url: `data:${mime};base64,${bytes.toString(\"base64\")}`,\n filename: path.basename(file),\n mime,\n }\n } finally {\n await handle.close()\n }\n}\n\nfunction isBinaryContent(bytes: Uint8Array) {\n if (bytes.length === 0) return false\n if (bytes.includes(0)) return true\n return bytes.reduce((count, byte) => count + Number(byte < 9 || (byte > 13 && byte < 32)), 0) / bytes.length > 0.3\n}\n\nasync function renderTool(part: MiniToolPart) {\n const info = toolInlineInfo(part)\n if (info.mode === \"block\") {\n UI.empty()\n UI.println(UI.Style.TEXT_NORMAL + info.icon, UI.Style.TEXT_NORMAL + info.title)\n if (info.body?.trim()) UI.println(info.body)\n UI.empty()\n return\n }\n UI.println(\n UI.Style.TEXT_NORMAL + info.icon,\n UI.Style.TEXT_NORMAL + info.title,\n info.description ? UI.Style.TEXT_DIM + info.description + UI.Style.TEXT_NORMAL : \"\",\n )\n}\n\nasync function renderToolError(part: MiniToolPart) {\n const info = toolInlineInfo(part)\n UI.println(UI.Style.TEXT_NORMAL + \"✗\", UI.Style.TEXT_NORMAL + `${info.title} failed`)\n}\n\nfunction warning(message: string) {\n UI.println(UI.Style.TEXT_WARNING_BOLD + \"!\", UI.Style.TEXT_NORMAL, message)\n}\n\nfunction reportError(input: RunCommandInput, message: string, sessionID?: string) {\n process.exitCode = 1\n if (input.format === \"json\") {\n process.stdout.write(\n JSON.stringify({\n type: \"error\",\n timestamp: Date.now(),\n sessionID: sessionID ?? \"\",\n error: { type: \"unknown\", message },\n }) + \"\\n\",\n )\n return\n }\n UI.error(message)\n}\n\nfunction fail(message: string): never {\n throw new Error(message)\n}\n", | ||
| "import type { EventSubscribeOutput, OpenCodeClient } from \"@opencode-ai/client/promise\"\nimport { SessionMessage } from \"@opencode-ai/schema/session-message\"\nimport { EOL } from \"node:os\"\nimport { UI } from \"./ui\"\nimport type { MiniToolPart } from \"./types\"\n\ntype Model = {\n providerID: string\n modelID: string\n}\n\ntype File = {\n url: string\n filename: string\n mime: string\n}\n\ntype Input = {\n client: OpenCodeClient\n sessionID: string\n message: string\n files: File[]\n agent?: string\n model?: Model\n variant?: string\n thinking: boolean\n format: \"default\" | \"json\"\n auto: boolean\n /** True when the client is attached to a shared server rather than an exclusive in-process one. */\n attached: boolean\n renderTool: (part: MiniToolPart) => Promise<void>\n renderToolError: (part: MiniToolPart) => Promise<void>\n}\n\ntype StartedPart = {\n id: string\n timestamp: number\n}\n\ntype ToolState = StartedPart & {\n assistantMessageID: string\n tool: string\n input: Record<string, unknown>\n raw?: string\n provider?: unknown\n}\n\ntype V2Event = EventSubscribeOutput\ntype FormRequest = Extract<V2Event, { type: \"form.created\" }>[\"data\"][\"form\"]\n\n// MCP elicitations are temporarily owned by the \"global\" sentinel instead of a real\n// session. An exclusive local process may treat them as this run's blockers; an\n// attached client must not cancel input that may belong to another session.\nconst GLOBAL_FORM_SESSION_ID = \"global\"\n\nexport async function runNonInteractivePrompt(input: Input) {\n const controller = new AbortController()\n const stream = input.client.event.subscribe({ signal: controller.signal })[Symbol.asyncIterator]()\n const connected = await stream.next()\n if (connected.done) throw new Error(\"Event stream disconnected before prompt admission\")\n\n const messageID = SessionMessage.ID.create()\n const starts = new Map<string, StartedPart>()\n const tools = new Map<string, ToolState>()\n let submitted = false\n let promoted = false\n let emittedError = false\n let questionRejected = false\n let permissionRejected = false\n let formCancelled = false\n let interrupted = false\n let admission: AbortController | undefined\n\n const emit = (type: string, timestamp: number, data: Record<string, unknown>) => {\n if (input.format !== \"json\") return false\n process.stdout.write(JSON.stringify({ type, timestamp, sessionID: input.sessionID, ...data }) + EOL)\n return true\n }\n\n const writeText = (part: { text: string; [key: string]: unknown }, timestamp: number) => {\n if (emit(\"text\", timestamp, { part })) return\n const text = part.text.trim()\n if (!text) return\n if (!process.stdout.isTTY) {\n process.stdout.write(text + EOL)\n return\n }\n UI.empty()\n UI.println(text)\n UI.empty()\n }\n\n const replyPermission = async (request: { id: string; action: string; resources: ReadonlyArray<string> }) => {\n if (!input.auto) {\n permissionRejected = true\n UI.println(\n UI.Style.TEXT_WARNING_BOLD + \"!\",\n UI.Style.TEXT_NORMAL +\n `permission requested: ${request.action} (${request.resources.join(\", \")}); auto-rejecting`,\n )\n }\n await input.client.permission\n .reply({\n sessionID: input.sessionID,\n requestID: request.id,\n reply: input.auto ? \"once\" : \"reject\",\n })\n .catch(() => {})\n if (!input.auto) {\n await input.client.session.interrupt({ sessionID: input.sessionID }).catch(() => {})\n }\n }\n\n const rejectQuestion = async (request: { id: string }) => {\n questionRejected = true\n await input.client.question.reject({ sessionID: input.sessionID, requestID: request.id }).catch(() => {})\n }\n\n const cancelForm = async (request: Pick<FormRequest, \"id\" | \"sessionID\">) => {\n formCancelled = true\n await input.client.form.cancel({ sessionID: request.sessionID, formID: request.id }).catch(() => {})\n }\n\n const consume = async () => {\n while (!controller.signal.aborted) {\n const next = await stream.next().catch((error) => {\n if (!emittedError) throw error\n return { done: true as const, value: undefined }\n })\n if (next.done) {\n if (emittedError) return\n throw new Error(\"Event stream disconnected during prompt execution\")\n }\n const event = next.value\n\n if (event.type === \"permission.v2.asked\" && submitted && event.data.sessionID === input.sessionID) {\n await replyPermission(event.data)\n continue\n }\n if (event.type === \"question.v2.asked\" && submitted && event.data.sessionID === input.sessionID) {\n await rejectQuestion(event.data)\n continue\n }\n if (\n event.type === \"form.created\" &&\n submitted &&\n (event.data.form.sessionID === input.sessionID ||\n (!input.attached && event.data.form.sessionID === GLOBAL_FORM_SESSION_ID))\n ) {\n await cancelForm(event.data.form)\n continue\n }\n if (!(\"sessionID\" in event.data) || event.data.sessionID !== input.sessionID) continue\n const time = toMillis(\"created\" in event ? event.created : undefined)\n\n if (event.type === \"session.input.promoted\") {\n if (event.data.inputID === messageID) {\n promoted = true\n continue\n }\n }\n if (\n event.type === \"session.execution.interrupted\" &&\n event.data.reason === \"user\" &&\n (interrupted || permissionRejected || questionRejected || formCancelled)\n ) {\n return\n }\n if (!promoted) continue\n\n if (event.type === \"session.step.started\") {\n const part = {\n id: partID(event.id),\n sessionID: input.sessionID,\n messageID: event.data.assistantMessageID,\n type: \"step-start\",\n snapshot: event.data.snapshot,\n }\n if (!emit(\"step_start\", time, { part }) && input.format !== \"json\") {\n UI.empty()\n UI.println(`> ${event.data.agent} · ${event.data.model.id}`)\n UI.empty()\n }\n continue\n }\n\n if (event.type === \"session.text.started\") {\n starts.set(\"text\", { id: partID(event.id), timestamp: time })\n continue\n }\n if (event.type === \"session.text.ended\") {\n const started = starts.get(\"text\")\n starts.delete(\"text\")\n const part = {\n id: started?.id ?? partID(event.id),\n sessionID: input.sessionID,\n messageID: event.data.assistantMessageID,\n type: \"text\",\n text: event.data.text,\n time: { start: started?.timestamp ?? time, end: time },\n }\n writeText(part, time)\n continue\n }\n\n if (event.type === \"session.reasoning.started\") {\n starts.set(\"reasoning\", { id: partID(event.id), timestamp: time })\n continue\n }\n if (event.type === \"session.reasoning.ended\" && input.thinking) {\n const started = starts.get(\"reasoning\")\n starts.delete(\"reasoning\")\n const part = {\n id: started?.id ?? partID(event.id),\n sessionID: input.sessionID,\n messageID: event.data.assistantMessageID,\n type: \"reasoning\",\n text: event.data.text,\n metadata: event.data.state,\n time: { start: started?.timestamp ?? time, end: time },\n }\n if (emit(\"reasoning\", time, { part })) continue\n const text = part.text.trim()\n if (!text) continue\n const line = `Thinking: ${text}`\n if (!process.stdout.isTTY) {\n process.stdout.write(line + EOL)\n continue\n }\n UI.empty()\n UI.println(`${UI.Style.TEXT_DIM}\\u001b[3m${line}\\u001b[0m${UI.Style.TEXT_NORMAL}`)\n UI.empty()\n continue\n }\n\n if (event.type === \"session.tool.input.started\") {\n tools.set(event.data.callID, {\n id: partID(event.id),\n timestamp: time,\n assistantMessageID: event.data.assistantMessageID,\n tool: event.data.name,\n input: {},\n })\n continue\n }\n if (event.type === \"session.tool.input.ended\") {\n const current = tools.get(event.data.callID)\n if (current) current.raw = event.data.text\n continue\n }\n if (event.type === \"session.tool.called\") {\n const current = tools.get(event.data.callID)\n tools.set(event.data.callID, {\n id: current?.id ?? partID(event.id),\n timestamp: current?.timestamp ?? time,\n assistantMessageID: event.data.assistantMessageID,\n tool: current?.tool ?? \"tool\",\n input: event.data.input,\n raw: current?.raw,\n provider: { executed: event.data.executed, state: event.data.state },\n })\n continue\n }\n if (event.type === \"session.tool.success\") {\n const current = tools.get(event.data.callID) ?? fallbackTool(event)\n const part: MiniToolPart = {\n id: current.id,\n sessionID: input.sessionID,\n messageID: event.data.assistantMessageID,\n type: \"tool\",\n callID: event.data.callID,\n tool: current.tool,\n state: {\n status: \"completed\",\n input: current.input,\n output: event.data.content\n .filter((item) => item.type === \"text\")\n .map((item) => item.text)\n .join(\"\\n\"),\n title: current.tool,\n metadata: {\n structured: event.data.structured,\n content: event.data.content,\n result: event.data.result,\n providerCall: current.provider,\n providerResult: { executed: event.data.executed, state: event.data.resultState },\n rawInput: current.raw,\n },\n time: { start: current.timestamp, end: time },\n },\n }\n tools.delete(event.data.callID)\n if (!emit(\"tool_use\", time, { part })) await input.renderTool(part)\n continue\n }\n if (event.type === \"session.tool.failed\") {\n const current = tools.get(event.data.callID) ?? fallbackTool(event)\n const error = event.data.error.message\n const part: MiniToolPart = {\n id: current.id,\n sessionID: input.sessionID,\n messageID: event.data.assistantMessageID,\n type: \"tool\",\n callID: event.data.callID,\n tool: current.tool,\n state: {\n status: \"error\",\n input: current.input,\n error,\n metadata: {\n result: event.data.result,\n providerCall: current.provider,\n providerResult: { executed: event.data.executed, state: event.data.resultState },\n rawInput: current.raw,\n },\n time: { start: current.timestamp, end: time },\n },\n }\n tools.delete(event.data.callID)\n if (!emit(\"tool_use\", time, { part })) {\n await input.renderToolError(part)\n UI.error(error)\n }\n continue\n }\n\n if (event.type === \"session.step.ended\") {\n const part = {\n id: partID(event.id),\n sessionID: input.sessionID,\n messageID: event.data.assistantMessageID,\n type: \"step-finish\",\n reason: event.data.finish,\n snapshot: event.data.snapshot,\n cost: event.data.cost,\n tokens: event.data.tokens,\n }\n emit(\"step_finish\", time, { part })\n continue\n }\n if (event.type === \"session.step.failed\") {\n if (interrupted || permissionRejected || questionRejected || formCancelled) continue\n emittedError = true\n process.exitCode = 1\n if (!emit(\"error\", time, { error: event.data.error })) UI.error(event.data.error.message)\n continue\n }\n if (event.type === \"session.execution.failed\") {\n if (!emittedError && !questionRejected && !formCancelled) {\n emittedError = true\n process.exitCode = 1\n if (!emit(\"error\", time, { error: event.data.error })) UI.error(event.data.error.message)\n }\n return\n }\n if (event.type === \"session.execution.interrupted\") {\n if (event.data.reason === \"user\" && interrupted) process.exitCode = 130\n if (event.data.reason !== \"user\" && !emittedError) {\n emittedError = true\n process.exitCode = 1\n const error = { type: \"aborted\" as const, message: `Session interrupted: ${event.data.reason}` }\n if (!emit(\"error\", time, { error })) UI.error(error.message)\n }\n return\n }\n if (event.type === \"session.execution.succeeded\") return\n }\n }\n\n const interrupt = () => {\n if (interrupted) process.exit(130)\n interrupted = true\n process.exitCode = 130\n admission?.abort()\n void input.client.session.interrupt({ sessionID: input.sessionID }).catch(() => {})\n }\n process.on(\"SIGINT\", interrupt)\n\n let completed: Promise<void> | undefined\n try {\n if (input.agent) {\n await input.client.session.switchAgent({ sessionID: input.sessionID, agent: input.agent })\n }\n const selected = input.model\n ? { providerID: input.model.providerID, id: input.model.modelID, variant: input.variant }\n : input.variant\n ? await input.client.session\n .get({ sessionID: input.sessionID })\n .then((result) => result.model)\n .then(async (model) => {\n if (model) return { ...model, variant: input.variant }\n const result = await input.client.model.default()\n const fallback = result.data\n return fallback ? { providerID: fallback.providerID, id: fallback.id, variant: input.variant } : undefined\n })\n : undefined\n if (input.variant && !selected) throw new Error(\"Cannot select a variant before selecting a model\")\n if (selected) {\n await input.client.session.switchModel({ sessionID: input.sessionID, model: selected })\n }\n\n const prepared = await Promise.all(input.files.map(prepareFile))\n if (interrupted) return\n submitted = true\n completed = consume()\n admission = new AbortController()\n const response = await input.client.session\n .prompt(\n {\n sessionID: input.sessionID,\n id: messageID,\n text: [input.message, ...prepared.flatMap((file) => (file.text ? [file.text] : []))].join(\"\\n\\n\"),\n files: prepared.flatMap((file) => (file.attachment ? [file.attachment] : [])),\n delivery: \"steer\",\n },\n { signal: admission.signal },\n )\n .catch(async (error) => {\n if (interrupted) {\n await input.client.session.interrupt({ sessionID: input.sessionID }).catch(() => {})\n }\n controller.abort()\n await completed?.catch(() => {})\n if (interrupted || emittedError) return undefined\n throw error\n })\n admission = undefined\n if (!response) return\n if (interrupted) await input.client.session.interrupt({ sessionID: input.sessionID }).catch(() => {})\n\n const [permissions, questions, forms] = await Promise.all([\n input.client.permission.list({ sessionID: input.sessionID }).catch(() => undefined),\n input.client.question.list({ sessionID: input.sessionID }).catch(() => undefined),\n Promise.all(\n (input.attached ? [input.sessionID] : [input.sessionID, GLOBAL_FORM_SESSION_ID]).map((sessionID) =>\n input.client.form.list({ sessionID }).catch(() => undefined),\n ),\n ),\n ])\n await Promise.all([\n ...(permissions ?? []).map(replyPermission),\n ...(questions ?? []).map(rejectQuestion),\n ...forms.flatMap((response) => response ?? []).map(cancelForm),\n ])\n await completed\n } finally {\n process.off(\"SIGINT\", interrupt)\n controller.abort()\n await stream.return?.(undefined).catch(() => {})\n }\n}\n\nfunction partID(eventID: string) {\n return `prt_${eventID.replace(/^evt_/, \"\")}`\n}\n\nfunction fallbackTool(event: {\n id: string\n created: number\n data: { assistantMessageID: string; callID: string }\n}): ToolState {\n return {\n id: partID(event.id),\n timestamp: toMillis(event.created),\n assistantMessageID: event.data.assistantMessageID,\n tool: \"tool\",\n input: {},\n }\n}\n\nfunction toMillis(value: unknown) {\n if (typeof value === \"number\") return value\n if (typeof value === \"string\") return new Date(value).getTime()\n return Date.now()\n}\n\nasync function prepareFile(file: File) {\n if (file.mime !== \"text/plain\") {\n const uri = file.url.startsWith(\"data:\")\n ? file.url\n : `data:${file.mime};base64,${Buffer.from(await Bun.file(new URL(file.url)).arrayBuffer()).toString(\"base64\")}`\n return { attachment: { uri, mime: file.mime, name: file.filename } }\n }\n const content = file.url.startsWith(\"data:\")\n ? Buffer.from(file.url.slice(file.url.indexOf(\",\") + 1), \"base64\").toString(\"utf8\")\n : await Bun.file(new URL(file.url)).text()\n return { text: `<file name=\"${file.filename}\">\\n${content}\\n</file>` }\n}\n", | ||
| "import { EOL } from \"node:os\"\n\nexport const Style = {\n TEXT_DIM: \"\\x1b[90m\",\n TEXT_NORMAL: \"\\x1b[0m\",\n TEXT_WARNING_BOLD: \"\\x1b[93m\\x1b[1m\",\n TEXT_DANGER_BOLD: \"\\x1b[91m\\x1b[1m\",\n}\n\nexport function println(...message: string[]) {\n process.stderr.write(message.join(\" \") + EOL)\n}\n\nlet blank = false\n\nexport function empty() {\n if (blank) return\n println(Style.TEXT_NORMAL)\n blank = true\n}\n\nexport function error(message: string) {\n if (message.startsWith(\"Error: \")) message = message.slice(\"Error: \".length)\n println(Style.TEXT_DANGER_BOLD + \"Error: \" + Style.TEXT_NORMAL + message)\n}\n\nexport * as UI from \"./ui\"\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "9F855CE6CA039D0464756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/mini/variant.shared.ts", "src/mini/session.shared.ts", "src/mini/theme.ts"], | ||
| "sourcesContent": [ | ||
| "// Model variant resolution and persistence.\n//\n// Variants are provider-specific reasoning effort levels (e.g., \"high\", \"max\").\n// Resolution priority: CLI --variant flag > saved preference > session history.\n//\n// The saved variant persists across sessions in ~/.local/state/opencode/model.json\n// so your last-used variant sticks. Cycling (ctrl+t) updates both the active\n// variant and the persisted file.\nimport path from \"path\"\nimport { FSUtil } from \"@opencode-ai/core/fs-util\"\nimport { AppNodeBuilder } from \"@opencode-ai/core/effect/app-node-builder\"\nimport { Context, Effect, Layer } from \"effect\"\nimport { LayerNode } from \"@opencode-ai/core/effect/layer-node\"\nimport { makeGlobalNode } from \"@opencode-ai/core/effect/app-node\"\nimport { makeRuntime } from \"@opencode-ai/core/effect/runtime\"\nimport { Global } from \"@opencode-ai/core/global\"\nimport { createSession, sessionVariant, type RunSession, type SessionMessages } from \"./session.shared\"\nimport type { RunInput, RunProvider } from \"./types\"\n\nconst MODEL_FILE = path.join(Global.Path.state, \"model.json\")\n\ntype ModelState = Record<string, unknown> & {\n variant?: Record<string, string | undefined>\n}\ntype VariantService = {\n readonly resolveSavedVariant: (model: RunInput[\"model\"]) => Effect.Effect<string | undefined>\n readonly saveVariant: (model: RunInput[\"model\"], variant: string | undefined) => Effect.Effect<void>\n}\ntype VariantRuntime = {\n resolveSavedVariant(model: RunInput[\"model\"]): Promise<string | undefined>\n saveVariant(model: RunInput[\"model\"], variant: string | undefined): Promise<void>\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === \"object\" && !Array.isArray(value)\n}\n\nclass Service extends Context.Service<Service, VariantService>()(\"@opencode/RunVariant\") {}\n\nfunction modelKey(provider: string, model: string): string {\n return `${provider}/${model}`\n}\n\nfunction variantKey(model: NonNullable<RunInput[\"model\"]>): string {\n return modelKey(model.providerID, model.modelID)\n}\n\nexport function modelInfo(providers: RunProvider[] | undefined, model: NonNullable<RunInput[\"model\"]>) {\n const provider = providers?.find((item) => item.id === model.providerID)\n return {\n provider: provider?.name ?? model.providerID,\n model: provider?.models[model.modelID]?.name ?? model.modelID,\n }\n}\n\nexport function formatModelLabel(\n model: NonNullable<RunInput[\"model\"]>,\n variant: string | undefined,\n providers?: RunProvider[],\n): string {\n const names = modelInfo(providers, model)\n const label = variant ? ` · ${variant}` : \"\"\n return `${names.model} · ${names.provider}${label}`\n}\n\nexport function cycleVariant(current: string | undefined, variants: string[]): string | undefined {\n if (variants.length === 0) {\n return undefined\n }\n\n if (!current) {\n return variants[0]\n }\n\n const idx = variants.indexOf(current)\n if (idx === -1 || idx === variants.length - 1) {\n return undefined\n }\n\n return variants[idx + 1]\n}\n\nexport function pickVariant(model: RunInput[\"model\"], input: RunSession | SessionMessages): string | undefined {\n return sessionVariant(Array.isArray(input) ? createSession(input) : input, model)\n}\n\nfunction fitVariant(value: string | undefined, variants: string[]): string | undefined {\n if (!value) {\n return undefined\n }\n\n if (variants.length === 0 || variants.includes(value)) {\n return value\n }\n\n return undefined\n}\n\n// Picks the active variant. CLI flag wins, then saved preference, then session\n// history. fitVariant() checks saved and session values against the available\n// variants list -- if the provider doesn't offer a variant, it drops.\nexport function resolveVariant(\n input: string | undefined,\n session: string | undefined,\n saved: string | undefined,\n variants: string[],\n): string | undefined {\n if (input !== undefined) {\n return input\n }\n\n const fallback = fitVariant(saved, variants)\n const current = fitVariant(session, variants)\n if (current !== undefined) {\n return current\n }\n\n return fallback\n}\n\nfunction state(value: unknown): ModelState {\n if (!isRecord(value)) {\n return {}\n }\n\n const variant = isRecord(value.variant)\n ? Object.fromEntries(\n Object.entries(value.variant).flatMap(([key, item]) => {\n if (typeof item !== \"string\") {\n return []\n }\n\n return [[key, item] as const]\n }),\n )\n : undefined\n\n return {\n ...value,\n variant,\n }\n}\n\nconst layer = Layer.fresh(\n Layer.effect(\n Service,\n Effect.gen(function* () {\n const file = yield* FSUtil.Service\n\n const read = Effect.fn(\"RunVariant.read\")(function* () {\n return yield* file.readJson(MODEL_FILE).pipe(\n Effect.map(state),\n Effect.catchCause(() => Effect.succeed(state(undefined))),\n )\n })\n\n const resolveSavedVariant = Effect.fn(\"RunVariant.resolveSavedVariant\")(function* (model: RunInput[\"model\"]) {\n if (!model) {\n return undefined\n }\n\n return (yield* read()).variant?.[variantKey(model)]\n })\n\n const saveVariant = Effect.fn(\"RunVariant.saveVariant\")(function* (\n model: RunInput[\"model\"],\n variant: string | undefined,\n ) {\n if (!model) {\n return\n }\n\n const current = yield* read()\n const next = {\n ...current.variant,\n }\n const key = variantKey(model)\n if (variant) {\n next[key] = variant\n }\n\n if (!variant) {\n delete next[key]\n }\n\n yield* file\n .writeJson(MODEL_FILE, {\n ...current,\n variant: next,\n })\n .pipe(Effect.orElseSucceed(() => undefined))\n })\n\n return Service.of({\n resolveSavedVariant,\n saveVariant,\n })\n }),\n ),\n)\n\nconst node = makeGlobalNode({ service: Service, layer, deps: [FSUtil.node] })\n\n/** @internal Exported for testing. */\nexport function createVariantRuntime(replacements?: readonly LayerNode.Replacement[]): VariantRuntime {\n const runtime = makeRuntime(Service, AppNodeBuilder.build(node, replacements))\n return {\n resolveSavedVariant: (model) => runtime.runPromise((svc) => svc.resolveSavedVariant(model)).catch(() => undefined),\n saveVariant: (model, variant) => runtime.runPromise((svc) => svc.saveVariant(model, variant)).catch(() => {}),\n }\n}\n\nconst runtime = createVariantRuntime()\n\nexport async function resolveSavedVariant(model: RunInput[\"model\"]): Promise<string | undefined> {\n return runtime.resolveSavedVariant(model)\n}\n\nexport function saveVariant(model: RunInput[\"model\"], variant: string | undefined): void {\n void runtime.saveVariant(model, variant)\n}\n", | ||
| "import type { SessionMessageInfo, SessionMessageUser } from \"@opencode-ai/client/promise\"\nimport { promptCopy, promptSame } from \"./prompt.shared\"\nimport type { RunInput, RunPrompt } from \"./types\"\n\nconst LIMIT = 200\n\nexport type SessionMessages = SessionMessageInfo[]\n\ntype Turn = {\n prompt: RunPrompt\n provider: string | undefined\n model: string | undefined\n variant: string | undefined\n}\n\nexport type RunSession = {\n first: boolean\n turns: Turn[]\n model?: NonNullable<RunInput[\"model\"]>\n variant?: string\n}\n\nfunction messagePrompt(message: SessionMessageUser): RunPrompt {\n return {\n text: message.text,\n parts: [\n ...(message.files ?? []).map((file) => ({\n type: \"file\" as const,\n url: file.source.type === \"uri\" ? file.source.uri : `data:${file.mime};base64,${file.data}`,\n mime: file.mime,\n filename: file.name,\n source: file.mention\n ? {\n type: \"file\",\n path: file.name ?? (file.source.type === \"uri\" ? file.source.uri : \"inline attachment\"),\n text: { start: file.mention.start, end: file.mention.end, value: file.mention.text },\n }\n : undefined,\n })),\n ...(message.agents ?? []).map((agent) => ({\n type: \"agent\" as const,\n name: agent.name,\n source: agent.mention\n ? { start: agent.mention.start, end: agent.mention.end, value: agent.mention.text }\n : undefined,\n })),\n ],\n }\n}\n\nexport function createSession(messages: SessionMessages): RunSession {\n return {\n first: messages.length === 0,\n turns: messages.flatMap((message) =>\n message.type === \"user\"\n ? [{ prompt: messagePrompt(message), provider: undefined, model: undefined, variant: undefined }]\n : [],\n ),\n }\n}\n\nexport async function resolveCurrentSession(\n sdk: RunInput[\"sdk\"],\n sessionID: string,\n limit = LIMIT,\n): Promise<RunSession> {\n const [response, session] = await Promise.all([\n sdk.message.list({ sessionID, limit, order: \"desc\" }),\n sdk.session.get({ sessionID }),\n ])\n const current = createSession(response.data.toReversed())\n return {\n ...current,\n turns: current.turns.map((turn) => ({\n ...turn,\n provider: session.model?.providerID,\n model: session.model?.id,\n variant: session.model?.variant,\n })),\n ...(session.model && {\n model: { providerID: session.model.providerID, modelID: session.model.id },\n variant: session.model.variant,\n }),\n }\n}\n\nexport function sessionHistory(session: RunSession, limit = LIMIT): RunPrompt[] {\n return session.turns\n .map((turn) => turn.prompt)\n .filter((prompt) => prompt.text.trim())\n .filter((prompt, index, prompts) => index === 0 || !promptSame(prompts[index - 1], prompt))\n .map(promptCopy)\n .slice(-limit)\n}\n\nexport function sessionVariant(session: RunSession, model: RunInput[\"model\"]): string | undefined {\n if (!model) return\n if (session.model?.providerID === model.providerID && session.model.modelID === model.modelID) return session.variant\n\n return session.turns.findLast((turn) => turn.provider === model.providerID && turn.model === model.modelID)?.variant\n}\n", | ||
| "// Theme resolution for direct interactive mode.\n//\n// Derives scrollback and footer colors from the terminal's actual palette.\n// resolveRunTheme() queries the renderer for the terminal's palette,\n// detects dark/light mode, builds a small system theme locally, and maps it to\n// the run footer + scrollback color model. Falls back to a hardcoded dark-mode\n// palette if detection fails.\nimport { RGBA, SyntaxStyle, type CliRenderer, type ColorInput, type TerminalColors } from \"@opentui/core\"\nimport type { TuiThemeCurrent } from \"@opencode-ai/plugin/tui\"\nimport type { EntryKind } from \"./types\"\n\ntype Tone = {\n body: ColorInput\n start?: ColorInput\n}\n\nexport type RunEntryTheme = Record<EntryKind, Tone>\n\nexport type RunSplashTheme = {\n left: ColorInput\n right: ColorInput\n leftShadow: ColorInput\n rightShadow: ColorInput\n}\n\nexport type RunFooterTheme = {\n highlight: ColorInput\n selected: ColorInput\n selectedText: ColorInput\n warning: ColorInput\n success: ColorInput\n error: ColorInput\n muted: ColorInput\n text: ColorInput\n status: ColorInput\n statusAccent: ColorInput\n shade: ColorInput\n surface: ColorInput\n pane: ColorInput\n border: ColorInput\n line: ColorInput\n}\n\nexport type RunBlockTheme = {\n highlight: ColorInput\n warning: ColorInput\n text: ColorInput\n muted: ColorInput\n syntax?: SyntaxStyle\n diffAdded: ColorInput\n diffRemoved: ColorInput\n diffAddedBg: ColorInput\n diffRemovedBg: ColorInput\n diffContextBg: ColorInput\n diffHighlightAdded: ColorInput\n diffHighlightRemoved: ColorInput\n diffLineNumber: ColorInput\n diffAddedLineNumberBg: ColorInput\n diffRemovedLineNumberBg: ColorInput\n}\n\nexport type RunTheme = {\n background: ColorInput\n footer: RunFooterTheme\n entry: RunEntryTheme\n splash: RunSplashTheme\n block: RunBlockTheme\n}\n\ntype ThemeColor = Exclude<keyof TuiThemeCurrent, \"thinkingOpacity\">\ntype HexColor = `#${string}`\ntype RefName = string\ntype Variant = {\n dark: HexColor | RefName\n light: HexColor | RefName\n}\ntype ColorValue = HexColor | RefName | Variant | RGBA | number\ntype ThemeJson = {\n defs?: Record<string, HexColor | RefName>\n theme: Omit<Record<ThemeColor, ColorValue>, \"selectedListItemText\" | \"backgroundMenu\"> & {\n selectedListItemText?: ColorValue\n backgroundMenu?: ColorValue\n thinkingOpacity?: number\n }\n}\n\ntype SharedSyntaxTheme = TuiThemeCurrent & {\n _hasSelectedListItemText: boolean\n}\n\nexport const transparent = RGBA.fromValues(0, 0, 0, 0)\n\nfunction alpha(color: RGBA, value: number): RGBA {\n return RGBA.fromValues(color.r, color.g, color.b, Math.max(0, Math.min(1, value)))\n}\n\nfunction rgba(hex: string, value?: number): RGBA {\n const color = RGBA.fromHex(hex)\n return value === undefined ? color : alpha(color, value)\n}\n\nfunction mode(bg: RGBA): \"dark\" | \"light\" {\n return luminance(bg) > 0.5 ? \"light\" : \"dark\"\n}\n\nfunction luminance(color: RGBA): number {\n return 0.299 * color.r + 0.587 * color.g + 0.114 * color.b\n}\n\nfunction fade(color: RGBA, base: RGBA, fallback: number, scale: number, limit: number): RGBA {\n if (color.a === 0) {\n return RGBA.fromValues(color.r, color.g, color.b, Math.max(0, Math.min(1, fallback)))\n }\n\n const target = Math.min(limit, color.a * scale)\n const mix = Math.min(1, target / color.a)\n\n return RGBA.fromValues(\n base.r + (color.r - base.r) * mix,\n base.g + (color.g - base.g) * mix,\n base.b + (color.b - base.b) * mix,\n color.a,\n )\n}\n\nfunction ansiToRgba(code: number): RGBA {\n if (code < 16) {\n const ansi = [\n \"#000000\",\n \"#800000\",\n \"#008000\",\n \"#808000\",\n \"#000080\",\n \"#800080\",\n \"#008080\",\n \"#c0c0c0\",\n \"#808080\",\n \"#ff0000\",\n \"#00ff00\",\n \"#ffff00\",\n \"#0000ff\",\n \"#ff00ff\",\n \"#00ffff\",\n \"#ffffff\",\n ]\n return RGBA.fromHex(ansi[code] ?? \"#000000\")\n }\n\n if (code < 232) {\n const index = code - 16\n const b = index % 6\n const g = Math.floor(index / 6) % 6\n const r = Math.floor(index / 36)\n const value = (x: number) => (x === 0 ? 0 : x * 40 + 55)\n return RGBA.fromInts(value(r), value(g), value(b))\n }\n\n if (code < 256) {\n const gray = (code - 232) * 10 + 8\n return RGBA.fromInts(gray, gray, gray)\n }\n\n return RGBA.fromInts(0, 0, 0)\n}\n\nfunction tint(base: RGBA, overlay: RGBA, value: number): RGBA {\n return RGBA.fromInts(\n Math.round((base.r + (overlay.r - base.r) * value) * 255),\n Math.round((base.g + (overlay.g - base.g) * value) * 255),\n Math.round((base.b + (overlay.b - base.b) * value) * 255),\n )\n}\n\nfunction chroma(color: RGBA) {\n return Math.max(color.r, color.g, color.b) - Math.min(color.r, color.g, color.b)\n}\n\nfunction indexedPalette(colors: TerminalColors, size: number = Math.max(colors.palette.length, 16)): RGBA[] {\n return Array.from({ length: size }, (_, index) => {\n const value = colors.palette[index]\n return RGBA.fromIndex(index, value ? RGBA.fromHex(value) : ansiToRgba(index))\n })\n}\n\nfunction srgbToLinear(value: number): number {\n if (value <= 0.04045) {\n return value / 12.92\n }\n\n return ((value + 0.055) / 1.055) ** 2.4\n}\n\nfunction oklab(color: RGBA) {\n const r = srgbToLinear(color.r)\n const g = srgbToLinear(color.g)\n const b = srgbToLinear(color.b)\n\n const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b)\n const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b)\n const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b)\n\n return {\n l: 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,\n a: 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,\n b: 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s,\n }\n}\n\nfunction nearestIndexed(indexed: RGBA[], rgba: RGBA): RGBA {\n const target = oklab(rgba)\n const hit = indexed.reduce(\n (best, item) => {\n const sample = oklab(item)\n const dl = sample.l - target.l\n const da = sample.a - target.a\n const db = sample.b - target.b\n const dist = dl * dl * 2 + da * da + db * db\n if (dist >= best.dist) return best\n return {\n dist,\n item,\n }\n },\n {\n dist: Number.POSITIVE_INFINITY,\n item: indexed[0]!,\n },\n )\n\n return RGBA.clone(hit.item)\n}\n\nfunction paletteColor(colors: TerminalColors, index: number): RGBA {\n const value = colors.palette[index]\n return value ? RGBA.fromHex(value) : ansiToRgba(index)\n}\n\nfunction splashShadow(indexed: RGBA[], base: RGBA, overlay: RGBA, value: number): RGBA {\n const mixed = tint(base, overlay, value)\n return nearestIndexed(indexed, mixed)\n}\n\nexport function resolveTheme(theme: ThemeJson, pick: \"dark\" | \"light\"): TuiThemeCurrent {\n const defs = theme.defs ?? {}\n\n const resolveColor = (value: ColorValue, chain: string[] = []): RGBA => {\n if (value instanceof RGBA) return value\n\n if (typeof value === \"number\") {\n return RGBA.fromIndex(value, ansiToRgba(value))\n }\n\n if (typeof value !== \"string\") {\n return resolveColor(value[pick], chain)\n }\n\n if (value === \"transparent\" || value === \"none\") {\n return RGBA.fromInts(0, 0, 0, 0)\n }\n\n if (value.startsWith(\"#\")) {\n return RGBA.fromHex(value)\n }\n\n if (chain.includes(value)) {\n throw new Error(`Circular color reference: ${[...chain, value].join(\" -> \")}`)\n }\n\n const next = defs[value] ?? theme.theme[value as ThemeColor]\n if (next === undefined) {\n throw new Error(`Color reference \"${value}\" not found in defs or theme`)\n }\n\n return resolveColor(next, [...chain, value])\n }\n\n const resolved = Object.fromEntries(\n Object.entries(theme.theme)\n .filter(([key]) => key !== \"selectedListItemText\" && key !== \"backgroundMenu\" && key !== \"thinkingOpacity\")\n .map(([key, value]) => [key, resolveColor(value as ColorValue)]),\n ) as Partial<Record<ThemeColor, RGBA>>\n\n return {\n ...(resolved as Record<ThemeColor, RGBA>),\n selectedListItemText:\n theme.theme.selectedListItemText === undefined\n ? resolved.background!\n : resolveColor(theme.theme.selectedListItemText),\n backgroundMenu:\n theme.theme.backgroundMenu === undefined ? resolved.backgroundElement! : resolveColor(theme.theme.backgroundMenu),\n thinkingOpacity: theme.theme.thinkingOpacity ?? 0.6,\n }\n}\n\nfunction generateGrayScale(bg: RGBA, isDark: boolean, map: (rgba: RGBA) => RGBA): Record<number, RGBA> {\n const r = bg.r * 255\n const g = bg.g * 255\n const b = bg.b * 255\n const lum = 0.299 * r + 0.587 * g + 0.114 * b\n const cast = 0.25 * (1 - chroma(bg)) ** 2\n\n const gray = (level: number) => {\n const factor = level / 12\n\n if (isDark && lum < 10) {\n const value = Math.floor(factor * 0.4 * 255)\n return map(RGBA.fromInts(value, value, value))\n }\n\n if (!isDark && lum > 245) {\n const value = Math.floor(255 - factor * 0.4 * 255)\n return map(RGBA.fromInts(value, value, value))\n }\n\n const value = isDark ? lum + (255 - lum) * factor * 0.4 : lum * (1 - factor * 0.4)\n const tone = RGBA.fromInts(Math.floor(value), Math.floor(value), Math.floor(value))\n if (cast === 0) return map(tone)\n\n const ratio = lum === 0 ? 0 : value / lum\n return map(\n tint(\n tone,\n RGBA.fromInts(\n Math.floor(Math.max(0, Math.min(r * ratio, 255))),\n Math.floor(Math.max(0, Math.min(g * ratio, 255))),\n Math.floor(Math.max(0, Math.min(b * ratio, 255))),\n ),\n cast,\n ),\n )\n }\n\n return Object.fromEntries(Array.from({ length: 12 }, (_, index) => [index + 1, gray(index + 1)]))\n}\n\nfunction generateMutedTextColor(bg: RGBA, isDark: boolean, map: (rgba: RGBA) => RGBA): RGBA {\n const lum = 0.299 * bg.r * 255 + 0.587 * bg.g * 255 + 0.114 * bg.b * 255\n const gray = isDark\n ? lum < 10\n ? 180\n : Math.min(Math.floor(160 + lum * 0.3), 200)\n : lum > 245\n ? 75\n : Math.max(Math.floor(100 - (255 - lum) * 0.2), 60)\n\n return map(RGBA.fromInts(gray, gray, gray))\n}\n\nexport function generateSystem(colors: TerminalColors, pick: \"dark\" | \"light\"): ThemeJson {\n const bg_snapshot = RGBA.fromHex(colors.defaultBackground ?? colors.palette[0]!)\n const fg_snapshot = RGBA.fromHex(colors.defaultForeground ?? colors.palette[7]!)\n const bg = RGBA.defaultBackground(bg_snapshot)\n const fg = RGBA.defaultForeground(fg_snapshot)\n const isDark = pick === \"dark\"\n\n const color = (index: number) => paletteColor(colors, index)\n\n const grays = generateGrayScale(bg_snapshot, isDark, (rgba) => rgba)\n const textMuted = generateMutedTextColor(bg_snapshot, isDark, (rgba) => rgba)\n\n const ansi = {\n red: color(1),\n green: color(2),\n yellow: color(3),\n blue: color(4),\n magenta: color(5),\n cyan: color(6),\n red_bright: color(9),\n green_bright: color(10),\n }\n\n const diff_alpha = isDark ? 0.22 : 0.14\n const diff_context_bg = grays[2]\n const primary = ansi.cyan\n const secondary = ansi.magenta\n\n return {\n theme: {\n primary,\n secondary,\n accent: primary,\n error: ansi.red,\n warning: ansi.yellow,\n success: ansi.green,\n info: ansi.cyan,\n text: fg,\n textMuted,\n selectedListItemText: bg,\n background: alpha(bg, 0),\n backgroundPanel: grays[2],\n backgroundElement: grays[3],\n backgroundMenu: grays[3],\n borderSubtle: grays[6],\n border: grays[7],\n borderActive: grays[8],\n diffAdded: ansi.green,\n diffRemoved: ansi.red,\n diffContext: grays[7],\n diffHunkHeader: grays[7],\n diffHighlightAdded: ansi.green_bright,\n diffHighlightRemoved: ansi.red_bright,\n diffAddedBg: tint(bg_snapshot, ansi.green, diff_alpha),\n diffRemovedBg: tint(bg_snapshot, ansi.red, diff_alpha),\n diffContextBg: diff_context_bg,\n diffLineNumber: textMuted,\n diffAddedLineNumberBg: tint(diff_context_bg, ansi.green, diff_alpha),\n diffRemovedLineNumberBg: tint(diff_context_bg, ansi.red, diff_alpha),\n markdownText: fg,\n markdownHeading: fg,\n markdownLink: ansi.blue,\n markdownLinkText: ansi.cyan,\n markdownCode: ansi.green,\n markdownBlockQuote: ansi.yellow,\n markdownEmph: ansi.yellow,\n markdownStrong: fg,\n markdownHorizontalRule: grays[7],\n markdownListItem: ansi.blue,\n markdownListEnumeration: ansi.cyan,\n markdownImage: ansi.blue,\n markdownImageText: ansi.cyan,\n markdownCodeBlock: fg,\n syntaxComment: textMuted,\n syntaxKeyword: ansi.magenta,\n syntaxFunction: ansi.blue,\n syntaxVariable: fg,\n syntaxString: ansi.green,\n syntaxNumber: ansi.yellow,\n syntaxType: ansi.cyan,\n syntaxOperator: ansi.cyan,\n syntaxPunctuation: fg,\n },\n }\n}\n\nfunction quantizeColor(indexed: RGBA[], rgba: RGBA): RGBA {\n if (rgba.a === 0 || rgba.intent === \"default\" || rgba.intent === \"indexed\") {\n return RGBA.clone(rgba)\n }\n\n return nearestIndexed(indexed, rgba)\n}\n\nfunction quantizeTheme(theme: TuiThemeCurrent, indexed: RGBA[]): TuiThemeCurrent {\n const resolved = Object.fromEntries(\n Object.entries(theme)\n .filter(([key]) => key !== \"thinkingOpacity\")\n .map(([key, value]) => [key, quantizeColor(indexed, value as RGBA)]),\n ) as Partial<Record<ThemeColor, RGBA>>\n\n return {\n ...(resolved as Record<ThemeColor, RGBA>),\n thinkingOpacity: theme.thinkingOpacity,\n }\n}\n\nfunction splashTheme(theme: TuiThemeCurrent, indexed: RGBA[]): RunSplashTheme {\n const left = nearestIndexed(indexed, theme.textMuted)\n const right = nearestIndexed(indexed, theme.text)\n return {\n left,\n right,\n leftShadow: splashShadow(indexed, theme.background, left, 0.14),\n rightShadow: splashShadow(indexed, theme.background, right, 0.14),\n }\n}\n\nfunction map(\n footerTheme: TuiThemeCurrent,\n scrollbackTheme: TuiThemeCurrent,\n splash: RunSplashTheme,\n syntax?: SyntaxStyle,\n): RunTheme {\n const footerBackground = alpha(footerTheme.background, 1)\n const footerMode = mode(footerBackground)\n const shade = fade(footerTheme.backgroundMenu, footerTheme.background, 0.12, 0.56, 0.72)\n const surface = fade(footerTheme.backgroundMenu, footerTheme.background, 0.18, 0.76, 0.9)\n const line = fade(footerTheme.backgroundMenu, footerTheme.background, 0.24, 0.9, 0.98)\n const statusBase = tint(footerBackground, rgba(\"#000000\"), footerMode === \"dark\" ? 0.12 : 0.06)\n const statusAccentBase =\n footerMode === \"dark\" ? tint(footerBackground, rgba(\"#ffffff\"), 0.06) : tint(statusBase, rgba(\"#000000\"), 0.04)\n const collapsedStatus = footerMode === \"dark\" && luminance(statusBase) <= 0.04\n // Pure-black backgrounds need a slight lift or the row disappears into the terminal background.\n const status = collapsedStatus ? tint(statusBase, statusAccentBase, 0.7) : statusBase\n const statusAccent = collapsedStatus ? tint(status, rgba(\"#ffffff\"), 0.06) : statusAccentBase\n\n return {\n background: footerTheme.background,\n footer: {\n highlight: footerTheme.primary,\n selected: footerTheme.backgroundElement,\n selectedText: footerTheme.selectedListItemText,\n warning: footerTheme.warning,\n success: footerTheme.success,\n error: footerTheme.error,\n muted: footerTheme.textMuted,\n text: footerTheme.text,\n status,\n statusAccent,\n shade,\n surface,\n pane: footerTheme.backgroundMenu,\n border: footerTheme.border,\n line,\n },\n entry: {\n system: {\n body: scrollbackTheme.textMuted,\n },\n user: {\n body: scrollbackTheme.primary,\n },\n assistant: {\n body: scrollbackTheme.text,\n },\n reasoning: {\n body: scrollbackTheme.textMuted,\n },\n tool: {\n body: scrollbackTheme.text,\n start: scrollbackTheme.textMuted,\n },\n error: {\n body: scrollbackTheme.error,\n },\n },\n splash,\n block: {\n highlight: scrollbackTheme.primary,\n warning: scrollbackTheme.warning,\n text: scrollbackTheme.text,\n muted: scrollbackTheme.textMuted,\n syntax,\n diffAdded: scrollbackTheme.diffAdded,\n diffRemoved: scrollbackTheme.diffRemoved,\n diffAddedBg: transparent,\n diffRemovedBg: transparent,\n diffContextBg: transparent,\n diffHighlightAdded: scrollbackTheme.diffHighlightAdded,\n diffHighlightRemoved: scrollbackTheme.diffHighlightRemoved,\n diffLineNumber: scrollbackTheme.diffLineNumber,\n diffAddedLineNumberBg: scrollbackTheme.diffAddedLineNumberBg,\n diffRemovedLineNumberBg: scrollbackTheme.diffRemovedLineNumberBg,\n },\n }\n}\n\nconst seed = {\n highlight: RGBA.fromIndex(6, rgba(\"#38bdf8\")),\n muted: RGBA.fromIndex(8, rgba(\"#64748b\")),\n text: RGBA.defaultForeground(rgba(\"#f8fafc\")),\n panel: rgba(\"#0f172a\"),\n success: RGBA.fromIndex(2, rgba(\"#22c55e\")),\n warning: RGBA.fromIndex(3, rgba(\"#f59e0b\")),\n error: RGBA.fromIndex(1, rgba(\"#ef4444\")),\n}\n\nfunction tone(body: ColorInput, start?: ColorInput): Tone {\n return {\n body,\n start,\n }\n}\n\nconst fallbackSplashIndexed = Array.from({ length: 256 }, (_, index) => RGBA.fromIndex(index))\nconst fallbackSplashLeft = RGBA.fromIndex(67)\nconst fallbackSplashRight = RGBA.fromIndex(110)\n\nexport const RUN_THEME_FALLBACK: RunTheme = {\n background: RGBA.fromValues(0, 0, 0, 0),\n footer: {\n highlight: seed.highlight,\n selected: seed.text,\n selectedText: seed.panel,\n warning: seed.warning,\n success: seed.success,\n error: seed.error,\n muted: seed.muted,\n text: seed.text,\n status: tint(seed.panel, rgba(\"#000000\"), 0.12),\n statusAccent: tint(seed.panel, rgba(\"#ffffff\"), 0.06),\n shade: alpha(seed.panel, 0.68),\n surface: alpha(seed.panel, 0.86),\n pane: seed.panel,\n border: seed.muted,\n line: alpha(seed.panel, 0.96),\n },\n entry: {\n system: tone(seed.muted),\n user: tone(seed.highlight),\n assistant: tone(seed.text),\n reasoning: tone(seed.muted),\n tool: tone(seed.text, seed.muted),\n error: tone(seed.error),\n },\n splash: {\n left: fallbackSplashLeft,\n right: fallbackSplashRight,\n leftShadow: splashShadow(fallbackSplashIndexed, RGBA.fromValues(0, 0, 0, 0), fallbackSplashLeft, 0.14),\n rightShadow: splashShadow(fallbackSplashIndexed, RGBA.fromValues(0, 0, 0, 0), fallbackSplashRight, 0.14),\n },\n block: {\n highlight: seed.highlight,\n warning: seed.warning,\n text: seed.text,\n muted: seed.muted,\n diffAdded: seed.success,\n diffRemoved: seed.error,\n diffAddedBg: alpha(seed.success, 0.18),\n diffRemovedBg: alpha(seed.error, 0.18),\n diffContextBg: alpha(seed.panel, 0.72),\n diffHighlightAdded: seed.success,\n diffHighlightRemoved: seed.error,\n diffLineNumber: seed.muted,\n diffAddedLineNumberBg: alpha(seed.success, 0.12),\n diffRemovedLineNumberBg: alpha(seed.error, 0.12),\n },\n}\n\nexport async function resolveRunTheme(renderer: CliRenderer): Promise<RunTheme> {\n try {\n const colors = await renderer.getPalette({\n size: 256,\n })\n const bg = colors.defaultBackground ?? colors.palette[0]\n if (!bg) {\n return RUN_THEME_FALLBACK\n }\n\n // Palette-only terminal reloads can leave renderer.themeMode stale, but\n // ANSI slot zero is not the terminal background when OSC 11 is absent.\n const pick = colors.defaultBackground\n ? mode(RGBA.fromHex(colors.defaultBackground))\n : (renderer.themeMode ?? mode(RGBA.fromHex(bg)))\n const footerTheme = resolveTheme(generateSystem(colors, pick), pick)\n const indexed = indexedPalette(colors, 256)\n const scrollbackTheme = quantizeTheme(footerTheme, indexed)\n const shared = await import(\"@opencode-ai/tui/context/theme\")\n const syntaxTheme: SharedSyntaxTheme = {\n ...scrollbackTheme,\n _hasSelectedListItemText: true,\n }\n const syntax = shared.generateSyntax(syntaxTheme)\n return map(footerTheme, scrollbackTheme, splashTheme(scrollbackTheme, indexed), syntax)\n } catch {\n return RUN_THEME_FALLBACK\n }\n}\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "D5EB78A2E04CBEE164756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/api.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"node:os\"\nimport { Effect, Option } from \"effect\"\nimport { Commands } from \"../commands\"\nimport { Runtime } from \"../../framework/runtime\"\nimport { Service, type Endpoint } from \"@opencode-ai/client/effect/service\"\nimport { ServerConnection } from \"../../services/server-connection\"\n\nconst methods = new Set([\"delete\", \"get\", \"head\", \"options\", \"patch\", \"post\", \"put\"])\n\ntype Operation = {\n operationId?: string\n}\n\ntype OpenApi = {\n paths?: Record<string, Record<string, Operation>>\n}\n\nexport default Runtime.handler(\n Commands.commands.api,\n Effect.fn(\"cli.api\")(function* (input) {\n const server = yield* ServerConnection.resolve({\n server: Option.getOrUndefined(input.server),\n standalone: input.standalone,\n mismatch: \"ignore\",\n })\n const endpoint = server.endpoint\n const params = Option.getOrElse(input.param, () => ({}))\n const request = yield* resolveRequest(endpoint, input.request, params)\n const headers = new Headers(Service.headers(endpoint))\n for (const header of input.header) {\n const index = header.indexOf(\":\")\n if (index < 1) return yield* Effect.fail(new Error(`Invalid header, expected name:value: ${header}`))\n headers.set(header.slice(0, index).trim(), header.slice(index + 1).trim())\n }\n const body = Option.getOrUndefined(input.data)\n if (body !== undefined && !headers.has(\"content-type\")) headers.set(\"content-type\", \"application/json\")\n\n const response = yield* Effect.tryPromise(() =>\n fetch(new URL(request.path, endpoint.url), {\n method: request.method,\n headers,\n body,\n }),\n )\n const output = yield* Effect.promise(() => response.text())\n if (output) process.stdout.write(output + (output.endsWith(EOL) ? \"\" : EOL))\n }),\n)\n\nexport function resolveOperation(spec: OpenApi, operationID: string, params: Record<string, string>) {\n for (const [path, operations] of Object.entries(spec.paths ?? {})) {\n for (const [method, operation] of Object.entries(operations)) {\n if (!methods.has(method) || operation.operationId !== operationID) continue\n return { method: method.toUpperCase(), path: interpolate(path, params) }\n }\n }\n throw new Error(`Operation not found: ${operationID}`)\n}\n\nexport function rawRequest(input: readonly string[]) {\n if (input.length !== 2 || !methods.has(input[0].toLowerCase()) || !input[1].startsWith(\"/\")) return\n return { method: input[0].toUpperCase(), path: input[1] }\n}\n\nfunction resolveRequest(endpoint: Endpoint, input: readonly string[], params: Record<string, string>) {\n const raw = rawRequest(input)\n if (raw) return Effect.succeed(raw)\n if (input.length !== 1) return Effect.fail(new Error(\"Expected an operation name or an HTTP method and path\"))\n return Effect.tryPromise(async () => {\n const response = await fetch(new URL(\"/openapi.json\", endpoint.url), { headers: Service.headers(endpoint) })\n if (!response.ok) throw new Error(`Failed to load OpenAPI document: HTTP ${response.status}`)\n return resolveOperation((await response.json()) as OpenApi, input[0], params)\n })\n}\n\nfunction interpolate(path: string, params: Record<string, string>) {\n const used = new Set<string>()\n const pathname = path.replaceAll(/\\{([^}]+)\\}/g, (_, name: string) => {\n const value = params[name]\n if (value === undefined) throw new Error(`Missing path parameter: ${name}`)\n used.add(name)\n return encodeURIComponent(value)\n })\n const query = new URLSearchParams(Object.entries(params).filter(([name]) => !used.has(name))).toString()\n return query ? `${pathname}?${query}` : pathname\n}\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "EFE42F8AE6803A2564756E2164756E21", | ||
| "names": [] | ||
| } |
Sorry, the diff of this file is too big to display
| { | ||
| "version": 3, | ||
| "sources": ["src/services/standalone.ts", "src/services/server-connection.ts"], | ||
| "sourcesContent": [ | ||
| "import { Service, type Endpoint } from \"@opencode-ai/client/effect/service\"\nimport { CrossSpawnSpawner } from \"@opencode-ai/core/cross-spawn-spawner\"\nimport { AppNodeBuilder } from \"@opencode-ai/core/effect/app-node-builder\"\nimport { Effect, Schema, Stream } from \"effect\"\nimport { ChildProcess, ChildProcessSpawner } from \"effect/unstable/process\"\nimport { randomBytes } from \"node:crypto\"\nimport path from \"node:path\"\n\nconst Ready = Schema.Struct({ url: Schema.String })\nconst decodeReady = Schema.decodeUnknownPromise(Schema.fromJsonString(Ready))\n\ntype Options = {\n readonly command?: ReadonlyArray<string>\n}\n\nfunction command(password: string, options: Options) {\n const compiled = path.basename(process.execPath).replace(/\\.exe$/, \"\") !== \"bun\"\n const entrypoint = compiled ? [] : process.argv[1] ? [process.argv[1]] : []\n if (!compiled && entrypoint.length === 0) throw new Error(\"Failed to resolve CLI entrypoint\")\n const [executable, ...args] = options.command ?? [process.execPath, ...entrypoint, \"serve\"]\n if (!executable) throw new Error(\"Failed to resolve standalone server command\")\n return ChildProcess.make(executable, [...args, \"--stdio\", \"--port\", \"0\"], {\n cwd: process.cwd(),\n // Explicit entry wins over anything inherited, so a user-exported\n // OPENCODE_PASSWORD cannot shadow the child's lease credential.\n env: { OPENCODE_PASSWORD: password },\n extendEnv: true,\n // The server treats EOF on this pipe as the end of its ownership lease.\n // The OS closes it even when the TUI is killed before Effect finalizers run.\n stdin: \"pipe\",\n stderr: \"ignore\",\n killSignal: \"SIGTERM\",\n forceKillAfter: \"3 seconds\",\n })\n}\n\nconst makeEndpoint = Effect.fn(\"cli.standalone.endpoint\")(\n function* (options: Options) {\n const password = randomBytes(32).toString(\"base64url\")\n const spawner = yield* ChildProcessSpawner.ChildProcessSpawner\n const proc = yield* spawner.spawn(command(password, options))\n const output = yield* proc.stdout.pipe(Stream.decodeText(), Stream.splitLines, Stream.take(1), Stream.mkString)\n if (!output) return yield* Effect.fail(new Error(\"Standalone server exited before reporting readiness\"))\n const ready = yield* Effect.tryPromise(() => decodeReady(output))\n return {\n url: ready.url,\n auth: { type: \"basic\" as const, username: \"opencode\", password },\n pid: proc.pid,\n } satisfies Endpoint & { readonly pid: number }\n },\n Effect.provide(AppNodeBuilder.build(CrossSpawnSpawner.node)),\n)\n\nexport function start(options: Options = {}) {\n return makeEndpoint(options)\n}\n\nexport * as Standalone from \"./standalone\"\n", | ||
| "import { Service, type Endpoint, type EnsureOptions } from \"@opencode-ai/client/effect/service\"\nimport { ClientError, isUnauthorizedError, OpenCode } from \"@opencode-ai/client/promise\"\nimport { InstallationVersion } from \"@opencode-ai/core/installation/version\"\nimport { Effect, Redacted } from \"effect\"\nimport { Env } from \"../env\"\nimport { ServiceConfig } from \"./service-config\"\nimport { Standalone } from \"./standalone\"\n\nexport type Args = {\n readonly server?: string\n readonly standalone?: boolean\n readonly mismatch?: \"replace\" | \"ignore\" | \"error\"\n readonly onStart?: EnsureOptions[\"onStart\"]\n}\n\nexport type Resolved = {\n readonly endpoint: Endpoint\n readonly service?: ReturnType<typeof managedService>\n}\n\nexport const resolve = Effect.fn(\"cli.server-connection.resolve\")(function* (args: Args) {\n if (args.server !== undefined && args.standalone)\n return yield* Effect.fail(new Error(\"--server and --standalone cannot be combined\"))\n if (args.server !== undefined) {\n const password = yield* Env.password\n const endpoint = {\n url: args.server,\n auth: password ? { type: \"basic\" as const, username: \"opencode\", password: Redacted.value(password) } : undefined,\n } satisfies Endpoint\n const client = OpenCode.make({ baseUrl: endpoint.url, headers: Service.headers(endpoint) })\n const health = yield* Effect.tryPromise({\n try: () => client.health.get({ signal: AbortSignal.timeout(5_000) }),\n catch: (cause) => connectError(endpoint, cause),\n })\n if (health.version !== InstallationVersion)\n process.stderr.write(\n `Warning: Server at ${endpoint.url} has version ${health.version}; this client is ${InstallationVersion}. Continuing anyway.\\n`,\n )\n return { endpoint } satisfies Resolved\n }\n if (args.standalone) {\n return { endpoint: yield* Standalone.start() } satisfies Resolved\n }\n\n const options = yield* ServiceConfig.options()\n return {\n endpoint: yield* resolveManaged({ ...options, onStart: args.onStart }, args.mismatch ?? \"replace\"),\n service: managedService(options),\n } satisfies Resolved\n})\n\nfunction managedService(options: EnsureOptions) {\n const reconnectOptions = { ...options, version: undefined }\n return {\n reconnect: () => Service.ensure(reconnectOptions),\n restart: () =>\n Effect.gen(function* () {\n yield* Service.stop(options)\n yield* Service.ensure(options)\n }),\n }\n}\n\nconst resolveManaged = Effect.fnUntraced(function* (\n options: EnsureOptions,\n mismatch: NonNullable<Args[\"mismatch\"]>,\n) {\n if (mismatch === \"replace\") return yield* Service.ensure(options)\n if (mismatch === \"ignore\") return yield* Service.ensure({ ...options, version: undefined })\n\n const compatible = yield* Service.discover(options)\n if (compatible !== undefined) return compatible\n const existing = yield* Service.discover({ ...options, version: undefined })\n if (existing !== undefined)\n return yield* Effect.fail(new Error(\"Background server version does not match this client\"))\n return yield* Service.ensure(options)\n})\n\nfunction connectError(endpoint: Endpoint, cause: unknown) {\n if (isUnauthorizedError(cause)) {\n return new Error(\n endpoint.auth === undefined\n ? `Server at ${endpoint.url} requires a password; set OPENCODE_PASSWORD`\n : `Server at ${endpoint.url} rejected the password`,\n { cause },\n )\n }\n if (cause instanceof ClientError && cause.reason === \"Transport\")\n return new Error(`Could not reach server at ${endpoint.url}`, { cause })\n return new Error(`Server at ${endpoint.url} did not provide a compatible V2 health response`, { cause })\n}\n\nexport * as ServerConnection from \"./server-connection\"\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "BA822F4F69BE290064756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/service/stop.ts"], | ||
| "sourcesContent": [ | ||
| "import { Effect } from \"effect\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { ServiceConfig } from \"../../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.service.commands.stop,\n Effect.fn(\"cli.service.stop\")(function* () {\n yield* Service.stop(yield* ServiceConfig.options())\n }),\n)\n" | ||
| ], | ||
| "mappings": ";+0BAMA,SAAe,SAAQ,aACrB,OAAS,cAAS,aAAQ,cAAS,UACnC,OAAO,QAAG,uBAAkB,OAAE,cAAU,OAAG,MACzC,WAAO,OAAQ,UAAK,WAAO,OAAc,aAAQ,MAAC,EACnD,CACH", | ||
| "debugId": "6A62854354DEF6D964756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["../core/src/util/process-lock.ts", "src/server-process.ts", "src/commands/handlers/serve.ts"], | ||
| "sourcesContent": [ | ||
| "import { dlopen, read, type Pointer } from \"bun:ffi\"\nimport { closeSync, existsSync, mkdirSync, openSync } from \"node:fs\"\nimport { connect, createServer, type Server, type Socket } from \"node:net\"\nimport path from \"node:path\"\nimport { Effect, Schema } from \"effect\"\nimport { Hash } from \"./hash\"\n\nexport namespace ProcessLock {\n export class HeldError extends Schema.TaggedErrorClass<HeldError>()(\"ProcessLockHeldError\", {\n file: Schema.String,\n }) {\n override get message() {\n return `Process lock is already held: ${this.file}`\n }\n }\n\n export class SystemError extends Schema.TaggedErrorClass<SystemError>()(\"ProcessLockSystemError\", {\n file: Schema.String,\n operation: Schema.Literals([\"open\", \"acquire\"]),\n code: Schema.String,\n }) {\n override get message() {\n return `Process lock ${this.operation} failed for ${this.file}: ${this.code}`\n }\n }\n\n export type LockError = HeldError | SystemError\n\n const acquirePosix = Effect.fnUntraced(function* (file: string) {\n const fd = yield* Effect.try({\n try: () => {\n mkdirSync(path.dirname(file), { recursive: true })\n return openSync(file, \"a+\", 0o600)\n },\n catch: (cause) =>\n new SystemError({\n file,\n operation: \"open\",\n code: cause instanceof Error ? cause.message : String(cause),\n }),\n })\n const result = yield* Effect.try({\n try: () => lock(fd),\n catch: (cause) =>\n new SystemError({\n file,\n operation: \"acquire\",\n code: cause instanceof Error ? cause.message : String(cause),\n }),\n }).pipe(\n Effect.tapError(() =>\n Effect.sync(() => {\n closeSync(fd)\n }),\n ),\n )\n if (result.acquired) {\n return fd\n }\n closeSync(fd)\n return yield* result.held\n ? new HeldError({ file })\n : new SystemError({ file, operation: \"acquire\", code: String(result.code) })\n })\n\n export const acquire = Effect.fn(\"ProcessLock.acquire\")(function* (file: string) {\n if (process.platform === \"win32\") {\n yield* Effect.acquireRelease(acquireWindows(file), closeWindows)\n return\n }\n yield* Effect.acquireRelease(acquirePosix(file), (fd) =>\n Effect.sync(() => {\n closeSync(fd)\n }),\n )\n })\n}\n\ntype Result =\n | { readonly acquired: true }\n | { readonly acquired: false; readonly held: true }\n | { readonly acquired: false; readonly held: false; readonly code: number }\n\nconst LOCK_EX = 2\nconst LOCK_NB = 4\nconst DARWIN_EWOULDBLOCK = 35\nconst LINUX_EWOULDBLOCK = 11\n\nfunction lock(fd: number): Result {\n if (process.platform === \"darwin\") return lockDarwin(fd)\n if (process.platform === \"linux\") return lockLinux(fd)\n throw new Error(`Unsupported process lock platform: ${process.platform}`)\n}\n\nfunction lockDarwin(fd: number): Result {\n const library = dlopen(\"/usr/lib/libSystem.B.dylib\", {\n flock: { args: [\"i32\", \"i32\"], returns: \"i32\" },\n __error: { args: [], returns: \"ptr\" },\n })\n try {\n const result = library.symbols.flock(fd, LOCK_EX | LOCK_NB)\n const code = result === 0 ? 0 : errorCode(library.symbols.__error())\n if (result === 0) return { acquired: true }\n if (code === DARWIN_EWOULDBLOCK) return { acquired: false, held: true }\n return { acquired: false, held: false, code }\n } finally {\n library.close()\n }\n}\n\nfunction lockLinux(fd: number): Result {\n const musl = `/lib/libc.musl-${process.arch === \"arm64\" ? \"aarch64\" : \"x86_64\"}.so.1`\n const library = dlopen(existsSync(musl) ? musl : \"libc.so.6\", {\n flock: { args: [\"i32\", \"i32\"], returns: \"i32\" },\n __errno_location: { args: [], returns: \"ptr\" },\n })\n try {\n const result = library.symbols.flock(fd, LOCK_EX | LOCK_NB)\n const code = result === 0 ? 0 : errorCode(library.symbols.__errno_location())\n if (result === 0) return { acquired: true }\n if (code === LINUX_EWOULDBLOCK) return { acquired: false, held: true }\n return { acquired: false, held: false, code }\n } finally {\n library.close()\n }\n}\n\nfunction errorCode(pointer: Pointer | null) {\n if (pointer === null) throw new Error(\"Failed to read process lock error code\")\n return read.i32(pointer, 0)\n}\n\nfunction acquireWindows(file: string) {\n return Effect.callback<Server, ProcessLock.LockError>((resume) => {\n const server = createServer()\n let probe: Socket | undefined\n const pipe = `\\\\\\\\.\\\\pipe\\\\opencode-process-lock-${Hash.sha256(path.resolve(file).toLowerCase())}`\n const onError = (cause: NodeJS.ErrnoException) => {\n server.off(\"listening\", onListening)\n probe = connect(pipe)\n const onProbeError = () => {\n probe?.off(\"connect\", onConnect)\n resume(\n Effect.fail(\n new ProcessLock.SystemError({\n file,\n operation: \"acquire\",\n code: cause.code ?? cause.message,\n }),\n ),\n )\n }\n const onConnect = () => {\n probe?.off(\"error\", onProbeError)\n probe?.destroy()\n resume(Effect.fail(new ProcessLock.HeldError({ file })))\n }\n probe.once(\"connect\", onConnect)\n probe.once(\"error\", onProbeError)\n }\n const onListening = () => {\n server.off(\"error\", onError)\n resume(Effect.succeed(server))\n }\n server.once(\"error\", onError)\n server.once(\"listening\", onListening)\n server.on(\"connection\", (socket) => socket.destroy())\n server.listen(pipe)\n return Effect.sync(() => {\n probe?.destroy()\n server.close()\n })\n })\n}\n\nfunction closeWindows(server: Server) {\n return Effect.callback<void>((resume) => {\n if (!server.listening) return resume(Effect.void)\n server.close((error) => resume(error ? Effect.die(error) : Effect.void))\n })\n}\n", | ||
| "export * as ServerProcess from \"./server-process\"\n\nimport { NodeServices } from \"@effect/platform-node\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { AppNodeBuilder } from \"@opencode-ai/core/effect/app-node-builder\"\nimport { LayerNode } from \"@opencode-ai/core/effect/layer-node\"\nimport { Global } from \"@opencode-ai/core/global\"\nimport { InstallationVersion } from \"@opencode-ai/core/installation/version\"\nimport { AppProcess } from \"@opencode-ai/core/process\"\nimport { ProcessLock } from \"@opencode-ai/core/util/process-lock\"\nimport { randomBytes, randomUUID } from \"node:crypto\"\nimport path from \"node:path\"\nimport { Effect, FileSystem, Logger, Option, Redacted, Schedule, Schema } from \"effect\"\nimport { HttpServer } from \"effect/unstable/http\"\nimport { Env } from \"./env\"\nimport { ServiceConfig } from \"./services/service-config\"\nimport { Updater } from \"./services/updater\"\n\nexport type Mode = \"default\" | \"service\" | \"stdio\"\n\nexport type Options = {\n readonly mode: Mode\n readonly hostname?: string\n readonly port?: number\n}\n\nexport const run = Effect.fn(\"cli.server-process.run\")((options: Options) =>\n processEffect(options).pipe(\n Effect.provide(Updater.layer),\n Effect.provide(AppNodeBuilder.build(LayerNode.group([Global.node, AppProcess.node]))),\n Effect.provide(NodeServices.layer),\n ),\n)\n\nconst processEffect = Effect.fnUntraced(function* (options: Options) {\n if (options.mode === \"service\") yield* Effect.sync(() => process.chdir(Global.Path.home))\n return yield* Effect.scoped(\n Effect.gen(function* () {\n const serviceOptions = options.mode === \"service\" ? yield* ServiceConfig.options() : undefined\n if (serviceOptions !== undefined) {\n const acquired = yield* ProcessLock.acquire(serviceOptions.file + \".lock\").pipe(\n Effect.as(true),\n Effect.catchTag(\"ProcessLockHeldError\", () => Effect.succeed(false)),\n )\n if (!acquired) return yield* Effect.void\n if ((yield* Service.discover(serviceOptions)) !== undefined) return yield* Effect.void\n }\n const { start } = yield* Effect.promise(() => import(\"@opencode-ai/server/process\"))\n const environmentPassword = yield* Env.password\n // Keep the lease credential out of the environment inherited by tools.\n if (options.mode === \"stdio\") {\n delete process.env.OPENCODE_PASSWORD\n delete process.env.OPENCODE_SERVER_PASSWORD\n }\n const config = options.mode === \"service\" ? yield* ServiceConfig.read() : {}\n const password =\n options.mode === \"service\"\n ? yield* ServiceConfig.password()\n : environmentPassword\n ? Redacted.value(environmentPassword)\n : randomBytes(32).toString(\"base64url\")\n if (!password) return yield* Effect.fail(new Error(\"Missing server password\"))\n const instanceID = randomUUID()\n const server = yield* start({\n hostname: options.hostname ?? config.hostname ?? \"127.0.0.1\",\n port: Option.fromNullishOr(options.port ?? config.port),\n password,\n instanceID,\n service:\n serviceOptions === undefined\n ? undefined\n : { onListen: (address) => register(address, password, instanceID, serviceOptions.file) },\n }).pipe(Effect.provide(Logger.layer([], { mergeWithExisting: false })))\n const url = HttpServer.formatAddress(server.address)\n console.log(options.mode === \"stdio\" ? JSON.stringify({ url }) : `server listening on ${url}`)\n if (options.mode === \"default\" && !environmentPassword) console.log(`server password ${password}`)\n const updater = yield* Updater.Service\n yield* updater.check().pipe(Effect.schedule(Schedule.spaced(\"10 minutes\")), Effect.forkScoped)\n return yield* options.mode === \"service\"\n ? server.shutdown\n : options.mode === \"stdio\"\n ? waitForStdinClose()\n : Effect.never\n }).pipe(Effect.annotateLogs({ role: \"server\" })),\n )\n})\n\nconst infoJson = Schema.fromJsonString(Service.Info)\nconst encodeInfo = Schema.encodeEffect(infoJson)\nconst decodeInfo = Schema.decodeUnknownEffect(infoJson)\n\nconst register = Effect.fnUntraced(function* (\n address: HttpServer.Address,\n password: string,\n id: string,\n file: string,\n) {\n const fs = yield* FileSystem.FileSystem\n const temp = file + \".\" + id + \".tmp\"\n yield* fs.makeDirectory(path.dirname(file), { recursive: true })\n const info = {\n id,\n version: InstallationVersion,\n url: HttpServer.formatAddress(address),\n pid: process.pid,\n password,\n }\n const encoded = yield* encodeInfo(info)\n const publish = fs.writeFileString(temp, encoded, { mode: 0o600 }).pipe(Effect.andThen(fs.rename(temp, file)))\n yield* publish\n const current = fs.readFileString(file).pipe(\n Effect.flatMap(decodeInfo),\n Effect.orElseSucceed(() => undefined),\n )\n const assertRegistration = Effect.gen(function* () {\n const found = yield* current\n if (\n found !== undefined &&\n found.id === info.id &&\n found.version === info.version &&\n found.url === info.url &&\n found.pid === info.pid &&\n found.password === info.password\n )\n return\n yield* publish\n })\n yield* Effect.addFinalizer(() =>\n current.pipe(\n Effect.flatMap((current) => (current?.id === id ? fs.remove(file) : Effect.void)),\n Effect.ignore,\n ),\n )\n yield* assertRegistration.pipe(\n Effect.catchCause((cause) => Effect.logWarning(\"failed to reassert service registration\", { cause })),\n Effect.repeat(Schedule.spaced(\"5 seconds\")),\n Effect.forkScoped,\n )\n})\n\nfunction waitForStdinClose() {\n return Effect.callback<void>((resume) => {\n const close = () => resume(Effect.void)\n process.stdin.once(\"end\", close)\n process.stdin.once(\"close\", close)\n process.stdin.resume()\n if (process.stdin.readableEnded || process.stdin.destroyed) close()\n return Effect.sync(() => {\n process.stdin.off(\"end\", close)\n process.stdin.off(\"close\", close)\n process.stdin.pause()\n })\n })\n}\n", | ||
| "import { Effect, Option } from \"effect\"\nimport { Commands } from \"../commands\"\nimport { Runtime } from \"../../framework/runtime\"\nimport { ServerProcess } from \"../../server-process\"\n\nexport default Runtime.handler(\n Commands.commands.serve,\n Effect.fn(\"cli.serve\")(function* (input) {\n if (input.service && input.stdio) return yield* Effect.fail(new Error(\"--service and --stdio cannot be combined\"))\n return yield* ServerProcess.run({\n mode: input.service ? \"service\" : input.stdio ? \"stdio\" : \"default\",\n hostname: Option.getOrUndefined(input.hostname),\n port: Option.getOrUndefined(input.port),\n })\n }),\n)\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "2DECB21882F3EAEA64756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["../simulation/src/backend/network.ts", "../simulation/src/backend/openai.ts", "../simulation/src/backend/simulated-provider.ts", "../simulation/src/backend/index.ts"], | ||
| "sourcesContent": [ | ||
| "import { Clock, Effect, Layer, Ref } from \"effect\"\nimport { HttpClient, HttpClientResponse, type HttpMethod } from \"effect/unstable/http\"\nimport { HttpClientError, TransportError } from \"effect/unstable/http/HttpClientError\"\nimport type { HttpClientRequest } from \"effect/unstable/http\"\nimport { SimulationProtocol } from \"../protocol\"\n\n/**\n * Simulated network.\n *\n * Replaces the `HttpClient.HttpClient` platform node in simulation mode. All\n * outbound HTTP resolves against an in-memory route table; unknown\n * destinations fail loudly with a transport error so no simulation run can\n * silently reach the real network. The scripted LLM is one registered route,\n * not a separate mechanism.\n *\n * Each acquired run owns its routes and request log.\n */\n\nexport interface Route {\n /** Return a response effect to claim the request, undefined to pass. */\n readonly match: (\n request: HttpClientRequest.HttpClientRequest,\n url: URL,\n ) => Effect.Effect<HttpClientResponse.HttpClientResponse, HttpClientError> | undefined\n}\n\nexport type LogEntry = SimulationProtocol.Backend.NetworkLogEntry\n\nconst LOG_LIMIT = 1000\n\n/** Static JSON route: exact method + origin/path match answered with a fixed body. */\nexport function json(method: HttpMethod.HttpMethod, url: string, body: unknown): Route {\n return {\n match: (request, requestUrl) => {\n if (request.method !== method) return undefined\n if (requestUrl.origin + requestUrl.pathname !== url) return undefined\n return Effect.sync(() =>\n HttpClientResponse.fromWeb(\n request,\n new Response(JSON.stringify(body), { status: 200, headers: { \"content-type\": \"application/json\" } }),\n ),\n )\n },\n }\n}\n\nexport interface Run {\n readonly client: HttpClient.HttpClient\n readonly log: () => Effect.Effect<readonly LogEntry[]>\n}\n\nexport const make = Effect.fn(\"SimulationNetwork.make\")(function* (routes: readonly Route[] = []) {\n const log = yield* Ref.make<readonly LogEntry[]>([])\n const client = HttpClient.make((request, url) =>\n Effect.gen(function* () {\n let matched: Effect.Effect<HttpClientResponse.HttpClientResponse, HttpClientError> | undefined\n for (const route of routes) {\n matched = route.match(request, url)\n if (matched) break\n }\n const entry = {\n time: yield* Clock.currentTimeMillis,\n method: request.method,\n url: url.toString(),\n matched: matched !== undefined,\n }\n yield* Ref.update(log, (entries) => [...entries, entry].slice(-LOG_LIMIT))\n if (matched) return yield* matched\n return yield* Effect.fail(\n new HttpClientError({\n reason: new TransportError({\n request,\n description: `Simulation denied unregistered network destination: ${request.method} ${url}`,\n }),\n }),\n )\n }),\n )\n return { client, log: () => Ref.get(log) } satisfies Run\n})\n\nexport const layer = (routes: readonly Route[] = []) =>\n Layer.effect(HttpClient.HttpClient, make(routes).pipe(Effect.map((run) => run.client)))\n\nexport * as SimulationNetwork from \"./network\"\n", | ||
| "import { Effect, Schema, Stream } from \"effect\"\nimport { HttpClientResponse } from \"effect/unstable/http\"\nimport { HttpClientError, TransportError } from \"effect/unstable/http/HttpClientError\"\nimport { OpenAIChatEvent, DEFAULT_BASE_URL, PATH } from \"@opencode-ai/llm/protocols/openai-chat\"\nimport { SimulationNetwork } from \"./network\"\nimport { SimulatedProvider } from \"./simulated-provider\"\n\n/**\n * Driver-answered OpenAI endpoint for the simulated network.\n *\n * Claims `POST {DEFAULT_BASE_URL}{PATH}` (the real openai-chat route\n * endpoint), invokes the simulated provider, and streams the driver's events back as\n * an OpenAI Chat SSE response terminated by `[DONE]`. Everything downstream\n * of the response bytes is the real pipeline: SSE framing, the OpenAIChat\n * event schema, the protocol state machine, and Lifecycle grammar.\n */\n\nconst encodeChunk = Schema.encodeUnknownSync(OpenAIChatEvent)\n\nconst encoder = new TextEncoder()\nconst decodeBody = Schema.decodeUnknownEffect(Schema.fromJsonString(Schema.Json))\n\n// The simulated model id is echoed back only in non-schema fields; the\n// protocol event schema ignores unknown fields, so id/object/model are\n// decorative wire realism.\ntype ProviderItem = Exclude<SimulatedProvider.ProviderResponseEvent, { readonly type: \"finish\" }>\ntype FinishReason = Extract<SimulatedProvider.ProviderResponseEvent, { readonly type: \"finish\" }>[\"reason\"]\n\nfunction chunkOf(item: ProviderItem): OpenAIChatEvent | unknown {\n if (item.type === \"textDelta\") return { choices: [{ delta: { content: item.text } }] }\n if (item.type === \"reasoningDelta\") return { choices: [{ delta: { reasoning_content: item.text } }] }\n if (item.type === \"toolCall\")\n return {\n choices: [\n {\n delta: {\n tool_calls: [\n {\n index: item.index,\n id: item.id,\n function: { name: item.name, arguments: JSON.stringify(item.input) },\n },\n ],\n },\n },\n ],\n }\n return item.chunk\n}\n\nconst finishReasonWire: Record<FinishReason, string> = {\n stop: \"stop\",\n \"tool-calls\": \"tool_calls\",\n length: \"length\",\n \"content-filter\": \"content_filter\",\n}\n\nfunction frame(payload: unknown): Uint8Array {\n return encoder.encode(`data: ${JSON.stringify(payload)}\\n\\n`)\n}\n\nfunction sseBody(\n events: Stream.Stream<SimulatedProvider.ProviderResponseEvent, SimulatedProvider.ProviderDisconnectedError>,\n): Stream.Stream<Uint8Array, SimulatedProvider.ProviderDisconnectedError> {\n return events.pipe(\n Stream.map((event) => {\n if (event.type === \"finish\")\n return frame(encodeChunk({ choices: [{ delta: {}, finish_reason: finishReasonWire[event.reason] }] }))\n if (event.type === \"raw\") return frame(event.chunk)\n return frame(encodeChunk(chunkOf(event)))\n }),\n Stream.concat(Stream.make(encoder.encode(\"data: [DONE]\\n\\n\"))),\n )\n}\n\nexport const route = (provider: SimulatedProvider.Interface): SimulationNetwork.Route => ({\n match: (request, url) => {\n if (request.method !== \"POST\") return undefined\n if (url.origin + url.pathname !== DEFAULT_BASE_URL + PATH) return undefined\n return Effect.gen(function* () {\n const body =\n request.body._tag === \"Uint8Array\"\n ? yield* decodeBody(new TextDecoder().decode(request.body.body)).pipe(\n Effect.mapError(\n (cause) =>\n new HttpClientError({\n reason: new TransportError({\n request,\n cause,\n description: \"Simulation received an invalid OpenAI request body\",\n }),\n }),\n ),\n )\n : {}\n return HttpClientResponse.fromWeb(\n request,\n new Response(Stream.toReadableStream(sseBody(provider.stream({ url: url.toString(), body }))), {\n status: 200,\n headers: { \"content-type\": \"text/event-stream\" },\n }),\n )\n })\n },\n})\n\nexport * as SimulationOpenAI from \"./openai\"\n", | ||
| "import { Cause, Context, Effect, Fiber, FiberSet, Layer, PubSub, Queue, Ref, Schema, Semaphore, Stream } from \"effect\"\nimport { SimulationControlServer } from \"../control-server\"\nimport { SimulationProtocol } from \"../protocol\"\n\nexport interface ProviderRequest {\n readonly url: string\n readonly body: unknown\n}\n\nexport type ProviderResponseEvent =\n | SimulationProtocol.Backend.Item\n | { readonly type: \"finish\"; readonly reason: SimulationProtocol.Backend.FinishReason }\n\nexport class ProviderDisconnectedError extends Schema.TaggedErrorClass<ProviderDisconnectedError>()(\n \"SimulatedProvider.ProviderDisconnectedError\",\n { message: Schema.String },\n) {}\n\nexport interface Interface {\n readonly stream: (request: ProviderRequest) => Stream.Stream<ProviderResponseEvent, ProviderDisconnectedError>\n}\n\nexport class Service extends Context.Service<Service, Interface>()(\"@opencode/simulation/SimulatedProvider\") {}\n\ninterface ProviderInvocation extends ProviderRequest {\n readonly id: string\n}\n\ninterface PendingInvocation extends ProviderInvocation {\n readonly responses: Queue.Queue<ProviderResponseEvent, ProviderDisconnectedError | Cause.Done>\n}\n\ninterface State {\n readonly counter: number\n readonly pending: ReadonlyMap<string, PendingInvocation>\n}\n\ninterface Driver {\n readonly requests: Stream.Stream<ProviderInvocation>\n readonly push: (\n id: string,\n items: readonly SimulationProtocol.Backend.Item[],\n ) => Effect.Effect<void, InvocationNotFoundError>\n readonly finish: (\n id: string,\n reason: SimulationProtocol.Backend.FinishReason,\n ) => Effect.Effect<void, InvocationNotFoundError>\n readonly disconnect: (id: string) => Effect.Effect<void, InvocationNotFoundError>\n readonly pending: () => Effect.Effect<readonly ProviderInvocation[]>\n}\n\nclass InvocationNotFoundError extends Schema.TaggedErrorClass<InvocationNotFoundError>()(\n \"SimulatedProvider.InvocationNotFoundError\",\n { id: Schema.String, message: Schema.String },\n) {}\n\nclass ControllerDisconnectedError extends Schema.TaggedErrorClass<ControllerDisconnectedError>()(\n \"SimulatedProvider.ControllerDisconnectedError\",\n { message: Schema.String },\n) {}\n\ntype ControlSocket = SimulationControlServer.Socket\n\nexport const layerDrive = (options: { readonly endpoint: string }) =>\n Layer.effect(\n Service,\n Effect.gen(function* () {\n const state = yield* Ref.make<State>({ counter: 0, pending: new Map() })\n const opened = yield* PubSub.unbounded<ProviderInvocation>()\n const lock = yield* Semaphore.make(1)\n\n const close = (invocation: PendingInvocation) =>\n Effect.gen(function* () {\n yield* Queue.shutdown(invocation.responses)\n yield* lock.withPermit(\n Ref.update(state, (current) =>\n current.pending.get(invocation.id) === invocation ? remove(current, invocation.id) : current,\n ),\n )\n })\n\n yield* Effect.addFinalizer(() =>\n Effect.gen(function* () {\n const current = yield* Ref.get(state)\n yield* Effect.forEach(current.pending.values(), (invocation) => Queue.shutdown(invocation.responses), {\n discard: true,\n })\n yield* PubSub.shutdown(opened)\n }),\n )\n\n const open = (request: ProviderRequest) =>\n lock.withPermit(\n Effect.gen(function* () {\n const current = yield* Ref.get(state)\n const id = `inv_${current.counter + 1}`\n const responses = yield* Queue.bounded<ProviderResponseEvent, ProviderDisconnectedError | Cause.Done>(256)\n const invocation: PendingInvocation = { id, ...request, responses }\n yield* Ref.set(state, {\n counter: current.counter + 1,\n pending: new Map(current.pending).set(id, invocation),\n })\n yield* PubSub.publish(opened, { id, ...request })\n return invocation\n }),\n )\n\n const requireInvocation = (id: string) =>\n Effect.gen(function* () {\n const current = yield* Ref.get(state)\n const invocation = current.pending.get(id)\n if (invocation) return invocation\n return yield* Effect.fail(\n new InvocationNotFoundError({\n id,\n message: `Simulated provider invocation not found or already finished: ${id}`,\n }),\n )\n })\n\n const remove = (current: State, id: string) => {\n const pending = new Map(current.pending)\n pending.delete(id)\n return { ...current, pending }\n }\n\n const driver: Driver = {\n requests: Stream.unwrap(\n lock.withPermit(\n Effect.gen(function* () {\n const subscription = yield* PubSub.subscribe(opened)\n const current = yield* Ref.get(state)\n const pending = Array.from(current.pending.values(), ({ id, url, body }) => ({ id, url, body }))\n return Stream.concat(Stream.fromIterable(pending), Stream.fromEffectRepeat(PubSub.take(subscription)))\n }),\n ),\n ),\n push: (id, items) =>\n Effect.gen(function* () {\n const invocation = yield* lock.withPermit(requireInvocation(id))\n yield* Queue.offerAll(invocation.responses, items)\n }),\n finish: (id, reason) =>\n Effect.gen(function* () {\n const invocation = yield* lock.withPermit(\n Effect.gen(function* () {\n const invocation = yield* requireInvocation(id)\n const current = yield* Ref.get(state)\n yield* Ref.set(state, remove(current, id))\n return invocation\n }),\n )\n yield* Queue.offer(invocation.responses, { type: \"finish\", reason })\n yield* Queue.end(invocation.responses)\n }),\n disconnect: (id) =>\n Effect.gen(function* () {\n const invocation = yield* lock.withPermit(\n Effect.gen(function* () {\n const invocation = yield* requireInvocation(id)\n const current = yield* Ref.get(state)\n yield* Ref.set(state, remove(current, id))\n return invocation\n }),\n )\n yield* Queue.fail(\n invocation.responses,\n new ProviderDisconnectedError({ message: \"Simulated model provider disconnected\" }),\n )\n }),\n pending: () =>\n lock.withPermit(\n Ref.get(state).pipe(\n Effect.map((current) => Array.from(current.pending.values(), ({ id, url, body }) => ({ id, url, body }))),\n ),\n ),\n }\n\n const fibers = yield* FiberSet.make<void, unknown>()\n const activeController = yield* Ref.make<Fiber.Fiber<void> | undefined>(undefined)\n const controllerLock = yield* Semaphore.make(1)\n yield* SimulationControlServer.start({\n endpoint: options.endpoint,\n label: \"opencode drive backend websocket\",\n data: () => ({}),\n decode: SimulationProtocol.Backend.decodeRequestEffect,\n handle: (socket, request) => handle(driver, fibers, activeController, controllerLock, socket, request),\n close: (socket) => releaseController(activeController, controllerLock, socket),\n })\n yield* Effect.sync(() => process.stderr.write(`opencode drive backend websocket: ${options.endpoint}\\n`))\n\n return Service.of({\n stream: (request) =>\n Stream.unwrap(\n Effect.acquireRelease(open(request), close).pipe(\n Effect.map((invocation) =>\n Stream.fromQueue(invocation.responses).pipe(Stream.takeUntil((event) => event.type === \"finish\")),\n ),\n ),\n ),\n })\n }),\n )\n\nfunction handle(\n driver: Driver,\n fibers: FiberSet.FiberSet<void, unknown>,\n activeController: Ref.Ref<Fiber.Fiber<void> | undefined>,\n controllerLock: Semaphore.Semaphore,\n socket: ControlSocket,\n request: SimulationProtocol.Backend.Request,\n) {\n switch (request.method) {\n case \"llm.attach\":\n return controllerLock.withPermit(\n Effect.gen(function* () {\n if (socket.data.closed)\n return yield* Effect.fail(\n new ControllerDisconnectedError({ message: \"Drive controller disconnected before attachment\" }),\n )\n const previous = yield* Ref.get(activeController)\n if (previous) yield* Fiber.interrupt(previous)\n const attachment = yield* FiberSet.run(\n fibers,\n driver.requests.pipe(\n Stream.runForEach((invocation) =>\n Effect.sync(() => {\n socket.send(JSON.stringify({ jsonrpc: \"2.0\", method: \"llm.request\", params: invocation }))\n }),\n ),\n ),\n )\n if (socket.data.closed) {\n yield* Fiber.interrupt(attachment)\n return yield* Effect.fail(\n new ControllerDisconnectedError({ message: \"Drive controller disconnected during attachment\" }),\n )\n }\n socket.data.attachment = attachment\n yield* Ref.set(activeController, attachment)\n return { attached: true }\n }),\n )\n case \"llm.chunk\":\n return driver.push(request.params.id, request.params.items).pipe(Effect.as({ ok: true }))\n case \"llm.finish\":\n return driver.finish(request.params.id, request.params.reason).pipe(Effect.as({ ok: true }))\n case \"llm.disconnect\":\n return driver.disconnect(request.params.id).pipe(Effect.as({ ok: true }))\n case \"llm.pending\":\n return driver.pending().pipe(Effect.map((invocations) => ({ invocations })))\n }\n}\n\nfunction releaseController(\n activeController: Ref.Ref<Fiber.Fiber<void> | undefined>,\n controllerLock: Semaphore.Semaphore,\n socket: ControlSocket,\n) {\n return controllerLock.withPermit(\n Effect.gen(function* () {\n const attachment = socket.data.attachment\n if (!attachment) return\n yield* Fiber.interrupt(attachment)\n yield* Ref.update(activeController, (active) => (active === attachment ? undefined : active))\n }),\n )\n}\n\nexport * as SimulatedProvider from \"./simulated-provider\"\n", | ||
| "import { LayerNode } from \"@opencode-ai/core/effect/layer-node\"\nimport { httpClient } from \"@opencode-ai/core/effect/app-node-platform\"\nimport { Config, Effect, Layer } from \"effect\"\nimport { HttpClient } from \"effect/unstable/http\"\nimport { DriveManifest } from \"../manifest\"\nimport { SimulationNetwork } from \"./network\"\nimport { SimulationOpenAI } from \"./openai\"\nimport { SimulatedProvider } from \"./simulated-provider\"\n\n/**\n * Layer replacements applied when the server is built in simulation mode.\n *\n * The server merges these into the app node build when `OPENCODE_SIMULATE`\n * is enabled, via a dynamic import so this module is never loaded eagerly.\n *\n * - Network: all outbound HTTP resolves against the simulated route table;\n * unknown destinations are denied. The driver-answered OpenAI endpoint is\n * registered here as the first route.\n *\n */\n\nexport const simulationReplacements = Effect.fn(\"Simulation.replacements\")(function* () {\n // ModelsDev dies when its catalog fetch fails, so simulation answers it with\n // an empty catalog; providers come from seeded config instead.\n const models = SimulationNetwork.json(\"GET\", \"https://models.dev/api.json\", {})\n const drive = yield* Config.string(\"OPENCODE_DRIVE\").pipe(Config.withDefault(undefined))\n if (!drive) return [[httpClient, SimulationNetwork.layer([models])]] satisfies LayerNode.Replacements\n\n const manifest = yield* DriveManifest.resolve()\n const networkLayer = Layer.effect(\n HttpClient.HttpClient,\n Effect.gen(function* () {\n const provider = yield* SimulatedProvider.Service\n const network = yield* SimulationNetwork.make([SimulationOpenAI.route(provider), models])\n return network.client\n }),\n ).pipe(\n Layer.provide(\n SimulatedProvider.layerDrive({\n endpoint: manifest.endpoints.backend,\n }),\n ),\n )\n return [[httpClient, networkLayer]] satisfies LayerNode.Replacements\n})\n\nexport * as Simulation from \"./index\"\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "E0E01370DE31E3E164756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/migrate.ts"], | ||
| "sourcesContent": [ | ||
| "import { Effect } from \"effect\"\nimport { Commands } from \"../commands\"\nimport { Runtime } from \"../../framework/runtime\"\n\nexport default Runtime.handler(Commands.commands.migrate, (_input) => Effect.log(\"No migrations to run.\"))\n" | ||
| ], | ||
| "mappings": ";+sBAIA,SAAe,SAAQ,aAAQ,OAAS,cAAS,aAAS,MAAC,SAAW,OAAO,SAAI,4BAAuB,MAAC", | ||
| "debugId": "0CDCF3045C0170C664756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/services/service-config.ts"], | ||
| "sourcesContent": [ | ||
| "import { Global } from \"@opencode-ai/core/global\"\nimport { InstallationChannel, InstallationVersion } from \"@opencode-ai/core/installation/version\"\nimport { Hash } from \"@opencode-ai/core/util/hash\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { Effect, FileSystem, Option, Schema } from \"effect\"\nimport { randomBytes } from \"crypto\"\nimport path from \"path\"\n\n// The CLI's service configuration file, plus the Service.EnsureOptions binding that\n// points the client package's service operations at this CLI: which\n// registration file (by channel), which version, and how to spawn opencode.\n\nexport const Info = Schema.Struct({\n hostname: Schema.optional(Schema.String),\n port: Schema.optional(Schema.Int.check(Schema.isGreaterThanOrEqualTo(1), Schema.isLessThanOrEqualTo(65_535))),\n password: Schema.optional(Schema.String),\n})\nexport type Info = typeof Info.Type\n\nconst keys = [\"hostname\", \"port\", \"password\"] as const\ntype Key = (typeof keys)[number]\n\nconst decodeInfo = Schema.decodeUnknownEffect(Schema.fromJsonString(Info))\nconst decodeRegistration = Schema.decodeUnknownEffect(Schema.fromJsonString(Service.Info))\n\nexport function filename(channel = InstallationChannel) {\n if (channel === \"latest\") return \"service.json\"\n if (channel === \"local\") return \"service-local.json\"\n return `service-${Hash.fast(channel)}.json`\n}\n\nexport function versionBelongsToChannel(\n version: string | undefined,\n channel = InstallationChannel,\n installedVersion = InstallationVersion,\n) {\n if (version === undefined) return false\n if (version === installedVersion) return true\n const prefix = `0.0.0-${channel}-`\n if (!version.startsWith(prefix)) return false\n return /^\\d+(?:\\.\\d+)?$/.test(version.slice(prefix.length))\n}\n\nexport const migrateRegistration = Effect.fnUntraced(function* (\n legacy: string,\n file: string,\n channel = InstallationChannel,\n installedVersion = InstallationVersion,\n) {\n if (channel === \"latest\" || channel === \"local\") return\n const fs = yield* FileSystem.FileSystem\n const text = yield* fs.readFileString(legacy).pipe(Effect.option)\n if (Option.isNone(text)) return\n const registration = yield* decodeRegistration(text.value).pipe(Effect.option)\n if (Option.isNone(registration)) return\n if (!versionBelongsToChannel(registration.value.version, channel, installedVersion)) return\n yield* fs.writeFileString(file, text.value, { flag: \"wx\", mode: 0o600 }).pipe(Effect.ignore)\n})\n\nfunction configKey(key: string): Key {\n if (key === \"hostname\" || key === \"port\" || key === \"password\") return key\n throw new Error(`Unknown service config key: ${key}`)\n}\n\nconst paths = Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem\n const global = yield* Global.Service\n const name = filename()\n const file = path.join(global.state, name)\n return {\n fs,\n file,\n legacyFile: path.join(global.state, \"service.json\"),\n configFile: path.join(global.config, name),\n }\n})\n\nexport const options = Effect.fnUntraced(function* () {\n const { file, legacyFile } = yield* paths\n yield* migrateRegistration(legacyFile, file)\n const compiled = path.basename(process.execPath).replace(/\\.exe$/, \"\") !== \"bun\"\n const entrypoint = compiled ? undefined : process.argv[1]\n if (!compiled && entrypoint === undefined) return yield* Effect.fail(new Error(\"Failed to resolve CLI entrypoint\"))\n return {\n file,\n version: InstallationVersion,\n command: [process.execPath, ...(entrypoint ? [entrypoint] : []), \"serve\", \"--service\"],\n }\n})\n\nexport const read = Effect.fn(\"cli.service-config.read\")(function* () {\n const { fs, configFile } = yield* paths\n return yield* fs.readFileString(configFile).pipe(\n Effect.flatMap(decodeInfo),\n Effect.catch(() => Effect.succeed({} as Info)),\n )\n})\n\nconst write = Effect.fn(\"cli.service-config.write\")(function* (value: Info) {\n const { fs, configFile } = yield* paths\n const temp = configFile + \".tmp\"\n yield* fs.makeDirectory(path.dirname(configFile), { recursive: true })\n yield* fs.writeFileString(temp, JSON.stringify(value, null, 2) + \"\\n\", { mode: 0o600 })\n yield* fs.rename(temp, configFile)\n})\n\nexport const password = Effect.fn(\"cli.service-config.password\")(function* (value?: string) {\n const existing = yield* read()\n if (value === undefined && existing.password) return existing.password\n const next = value ?? randomBytes(32).toString(\"base64url\")\n\n // Keep one private credential across server restarts so discovered clients\n // can reconnect without exposing a password flag or environment variable.\n yield* write({ ...existing, password: next })\n return next\n})\n\nexport const get = Effect.fn(\"cli.service-config.get\")(function* (key?: string) {\n if (key === undefined) {\n const { password: _password, ...safe } = yield* read()\n return JSON.stringify(safe, null, 2)\n }\n switch (configKey(key)) {\n case \"hostname\": {\n return (yield* read()).hostname ?? \"\"\n }\n case \"port\": {\n const port = (yield* read()).port\n return port === undefined ? \"\" : String(port)\n }\n case \"password\": {\n return yield* password()\n }\n }\n throw new Error(`Unknown service config key: ${key}`)\n})\n\nexport const set = Effect.fn(\"cli.service-config.set\")(function* (key: string, value: string) {\n switch (configKey(key)) {\n case \"hostname\": {\n yield* Service.stop(yield* options())\n yield* write({ ...(yield* read()), hostname: value })\n return\n }\n case \"port\": {\n const port = Number(value)\n if (!Number.isInteger(port) || port < 1 || port > 65_535) throw new Error(\"Port must be between 1 and 65535\")\n yield* Service.stop(yield* options())\n yield* write({ ...(yield* read()), port })\n return\n }\n case \"password\": {\n yield* Service.stop(yield* options())\n yield* password(value)\n return\n }\n }\n})\n\nexport const unset = Effect.fn(\"cli.service-config.unset\")(function* (key: string) {\n switch (configKey(key)) {\n case \"hostname\": {\n yield* Service.stop(yield* options())\n const { hostname: _hostname, ...next } = yield* read()\n yield* write(next)\n return\n }\n case \"port\": {\n yield* Service.stop(yield* options())\n const { port: _port, ...next } = yield* read()\n yield* write(next)\n return\n }\n case \"password\": {\n yield* Service.stop(yield* options())\n const { password: _password, ...next } = yield* read()\n yield* write(next)\n return\n }\n }\n})\n\nexport * as ServiceConfig from \"./service-config\"\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "342C32E4F719ABAB64756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/service/set.ts"], | ||
| "sourcesContent": [ | ||
| "import { Effect } from \"effect\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { ServiceConfig } from \"../../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.service.commands.set,\n Effect.fn(\"cli.service.set\")(function* (input) {\n yield* ServiceConfig.set(input.key, input.value)\n }),\n)\n" | ||
| ], | ||
| "mappings": ";k0BAKA,SAAe,SAAQ,aACrB,OAAS,cAAS,aAAQ,cAAS,SACnC,OAAO,QAAG,sBAAiB,OAAE,cAAU,MAAC,OAAO,MAC7C,WAAO,OAAc,SAAI,OAAM,SAAK,OAAM,KAAK,EAChD,CACH", | ||
| "debugId": "C5CA3C33CCAFADF464756E2164756E21", | ||
| "names": [] | ||
| } |
Sorry, the diff of this file is too big to display
| { | ||
| "version": 3, | ||
| "sources": ["src/ui/timeline.tsx", "src/commands/handlers/console/login.ts"], | ||
| "sourcesContent": [ | ||
| "import { createComponent as _$createComponent } from \"@opentui/solid\";\nimport { effect as _$effect } from \"@opentui/solid\";\nimport { createTextNode as _$createTextNode } from \"@opentui/solid\";\nimport { insertNode as _$insertNode } from \"@opentui/solid\";\nimport { insert as _$insert } from \"@opentui/solid\";\nimport { setProp as _$setProp } from \"@opentui/solid\";\nimport { createElement as _$createElement } from \"@opentui/solid\";\n/** @jsxImportSource @opentui/solid */\nimport { createCliRenderer, RGBA } from \"@opentui/core\";\nimport { createScrollbackWriter, render, useKeyboard } from \"@opentui/solid\";\nimport { registerOpencodeSpinner } from \"@opencode-ai/tui/component/register-spinner\";\nimport { Show, createSignal } from \"solid-js\";\nregisterOpencodeSpinner();\nconst SPINNER_FRAMES = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\nconst IDLE_TIMEOUT = 1_000;\nconst COLORS = {\n accent: RGBA.fromIndex(6),\n error: RGBA.fromIndex(1),\n foreground: RGBA.defaultForeground(),\n muted: RGBA.fromIndex(8),\n success: RGBA.fromIndex(2)\n};\nconst ROWS = {\n intro: {\n marker: \"┌\",\n color: COLORS.muted,\n connector: true\n },\n item: {\n marker: \"●\",\n color: COLORS.accent,\n connector: true\n },\n success: {\n marker: \"◇\",\n color: COLORS.success,\n connector: true\n },\n failure: {\n marker: \"■\",\n color: COLORS.error,\n connector: false\n },\n outro: {\n marker: \"└\",\n color: COLORS.muted,\n connector: false\n }\n};\nfunction row(kind, value) {\n const style = ROWS[kind];\n return createScrollbackWriter(() => (() => {\n var _el$ = _$createElement(\"box\"),\n _el$2 = _$createElement(\"box\"),\n _el$3 = _$createElement(\"text\"),\n _el$4 = _$createElement(\"text\");\n _$insertNode(_el$, _el$2);\n _$setProp(_el$, \"width\", \"100%\");\n _$setProp(_el$, \"minHeight\", 1);\n _$setProp(_el$, \"flexDirection\", \"column\");\n _$insertNode(_el$2, _el$3);\n _$insertNode(_el$2, _el$4);\n _$setProp(_el$2, \"width\", \"100%\");\n _$setProp(_el$2, \"minHeight\", 1);\n _$setProp(_el$2, \"flexDirection\", \"row\");\n _$setProp(_el$2, \"gap\", 1);\n _$setProp(_el$3, \"flexShrink\", 0);\n _$insert(_el$3, () => style.marker);\n _$setProp(_el$4, \"wrapMode\", \"word\");\n _$insert(_el$4, value);\n _$insert(_el$, _$createComponent(Show, {\n get when() {\n return style.connector;\n },\n get children() {\n var _el$5 = _$createElement(\"text\");\n _$insertNode(_el$5, _$createTextNode(`│`));\n _$effect(_$p => _$setProp(_el$5, \"fg\", COLORS.muted, _$p));\n return _el$5;\n }\n }), null);\n _$effect(_p$ => {\n var _v$ = style.color,\n _v$2 = COLORS.foreground;\n _v$ !== _p$.e && (_p$.e = _$setProp(_el$3, \"fg\", _v$, _p$.e));\n _v$2 !== _p$.t && (_p$.t = _$setProp(_el$4, \"fg\", _v$2, _p$.t));\n return _p$;\n }, {\n e: undefined,\n t: undefined\n });\n return _el$;\n })(), {\n startOnNewLine: true,\n trailingNewline: !style.connector\n });\n}\nfunction TimelineFooter(props) {\n useKeyboard(event => {\n if (event.name !== \"escape\" && !(event.ctrl && event.name === \"c\")) return;\n event.preventDefault();\n props.cancel();\n });\n return (() => {\n var _el$7 = _$createElement(\"box\");\n _$setProp(_el$7, \"width\", \"100%\");\n _$setProp(_el$7, \"height\", 1);\n _$setProp(_el$7, \"flexDirection\", \"row\");\n _$setProp(_el$7, \"gap\", 1);\n _$insert(_el$7, _$createComponent(Show, {\n get when() {\n return props.pending();\n },\n children: text => [(() => {\n var _el$8 = _$createElement(\"spinner\");\n _$setProp(_el$8, \"frames\", SPINNER_FRAMES);\n _$setProp(_el$8, \"interval\", 80);\n _$effect(_$p => _$setProp(_el$8, \"color\", COLORS.accent, _$p));\n return _el$8;\n })(), (() => {\n var _el$9 = _$createElement(\"text\");\n _$setProp(_el$9, \"wrapMode\", \"none\");\n _$setProp(_el$9, \"truncate\", true);\n _$insert(_el$9, text);\n _$effect(_$p => _$setProp(_el$9, \"fg\", COLORS.foreground, _$p));\n return _el$9;\n })()]\n }));\n return _el$7;\n })();\n}\nfunction bounded(task) {\n return new Promise(resolve => {\n const timer = setTimeout(resolve, IDLE_TIMEOUT);\n timer.unref();\n const finish = () => {\n clearTimeout(timer);\n resolve();\n };\n void task.then(finish, finish);\n });\n}\nasync function shutdown(renderer) {\n await bounded(renderer.idle());\n try {\n renderer.externalOutputMode = \"passthrough\";\n } finally {\n try {\n renderer.screenMode = \"main-screen\";\n } finally {\n if (!renderer.isDestroyed) renderer.destroy();\n }\n }\n}\nexport async function createTimelineHost() {\n const stdout = process.stdout;\n const controller = new AbortController();\n const signals = [\"SIGINT\", \"SIGHUP\", \"SIGQUIT\"];\n const cancel = () => {\n if (!controller.signal.aborted) controller.abort();\n };\n signals.forEach(signal => process.on(signal, cancel));\n if (!stdout.isTTY || !process.stdin.isTTY) {\n let closed = false;\n let writing = false;\n let active;\n let closeTask;\n const write = async (kind, text) => {\n if (closed) throw new Error(\"timeline closed\");\n if (writing) throw new Error(\"timeline write already in progress\");\n writing = true;\n try {\n const style = kind === \"pending\" ? undefined : ROWS[kind];\n const marker = kind === \"pending\" ? \".\" : ROWS[kind].marker;\n const connector = style?.connector ? \"│\\n\" : \"\";\n active = new Promise((resolve, reject) => {\n stdout.write(`${marker} ${text}\\n${connector}`, error => error ? reject(error) : resolve());\n });\n await active;\n } finally {\n writing = false;\n active = undefined;\n }\n };\n const close = () => {\n if (closeTask) return closeTask;\n closed = true;\n closeTask = (async () => {\n await active?.catch(() => {});\n signals.forEach(signal => process.off(signal, cancel));\n })();\n return closeTask;\n };\n return {\n signal: controller.signal,\n intro: text => write(\"intro\", text),\n item: text => write(\"item\", text),\n pending: text => write(\"pending\", text),\n success: text => write(\"success\", text),\n failure: text => write(\"failure\", text),\n outro: text => write(\"outro\", text),\n close\n };\n }\n let renderer;\n try {\n // Start on a fresh row so delayed SSH cursor reports cannot make\n // split-footer overwrite the shell command.\n process.stdout.write(\"\\n\");\n renderer = await createCliRenderer({\n stdin: process.stdin,\n useMouse: false,\n autoFocus: false,\n openConsoleOnError: false,\n exitOnCtrlC: false,\n exitSignals: [],\n screenMode: \"split-footer\",\n footerHeight: 1,\n externalOutputMode: \"capture-stdout\",\n consoleMode: \"disabled\",\n clearOnShutdown: false\n });\n const activeRenderer = renderer;\n const [pending, setPending] = createSignal();\n const renderTask = render(() => _$createComponent(TimelineFooter, {\n pending: pending,\n cancel: cancel\n }), activeRenderer);\n void renderTask.catch(cancel);\n await bounded(activeRenderer.idle());\n let closed = false;\n let writing = false;\n let active;\n let closeTask;\n const write = (kind, text) => {\n if (closed) return Promise.reject(new Error(\"timeline closed\"));\n if (writing) return Promise.reject(new Error(\"timeline write already in progress\"));\n writing = true;\n active = (async () => {\n if (kind === \"pending\") {\n setPending(text);\n activeRenderer.requestRender();\n } else {\n if (kind === \"success\" || kind === \"failure\" || kind === \"outro\") setPending(undefined);\n activeRenderer.writeToScrollback(row(kind, text));\n activeRenderer.requestRender();\n }\n await bounded(activeRenderer.idle());\n })().finally(() => {\n writing = false;\n active = undefined;\n });\n return active;\n };\n const close = () => {\n if (closeTask) return closeTask;\n closed = true;\n closeTask = (async () => {\n await active?.catch(() => {});\n try {\n await shutdown(activeRenderer);\n await bounded(renderTask);\n } finally {\n signals.forEach(signal => process.off(signal, cancel));\n }\n })();\n return closeTask;\n };\n return {\n signal: controller.signal,\n intro: text => write(\"intro\", text),\n item: text => write(\"item\", text),\n pending: text => write(\"pending\", text),\n success: text => write(\"success\", text),\n failure: text => write(\"failure\", text),\n outro: text => write(\"outro\", text),\n close\n };\n } catch (error) {\n try {\n if (renderer) await shutdown(renderer);\n } finally {\n signals.forEach(signal => process.off(signal, cancel));\n }\n throw error;\n }\n}", | ||
| "import { Cause, Effect, Exit, Option } from \"effect\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { OpenCode, type OpenCodeClient } from \"@opencode-ai/client/promise\"\nimport { AppProcess } from \"@opencode-ai/core/process\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { ServiceConfig } from \"../../../services/service-config\"\nimport { createTimelineHost, type TimelineHost } from \"../../../ui/timeline\"\n\nconst integrationID = \"opencode\"\nconst location = { directory: process.cwd() }\n\nexport default Runtime.handler(\n Commands.commands.console.commands.login,\n Effect.fn(\"cli.console.login\")(function* (input) {\n const timeline = yield* Effect.acquireRelease(\n Effect.promise(() => createTimelineHost()),\n (value) => request(() => value.close()).pipe(Effect.ignore),\n )\n const exit = yield* login(timeline, Option.getOrUndefined(input.url)).pipe(\n Effect.raceFirst(AppProcess.waitForAbort(timeline.signal)),\n Effect.exit,\n )\n if (Exit.isSuccess(exit)) return\n\n const cancelled = timeline.signal.aborted\n yield* request(() => timeline.failure(cancelled ? \"Authorization cancelled\" : errorMessage(exit.cause))).pipe(\n Effect.ignore,\n )\n process.exitCode = cancelled ? 130 : 1\n }),\n)\n\nconst login = Effect.fn(\"cli.console.login.run\")(function* (timeline: TimelineHost, server?: string) {\n yield* request(() => timeline.intro(\"Log in\"))\n yield* request(() => timeline.pending(\"Connecting to OpenCode...\"))\n\n const endpoint = yield* Service.ensure(yield* ServiceConfig.options())\n const client = OpenCode.make({ baseUrl: endpoint.url, headers: Service.headers(endpoint) })\n const found = yield* request((signal) => client.integration.get({ integrationID, location }, { signal }))\n const integration = yield* required(found.data, \"OpenCode Console integration is unavailable\")\n const method = yield* required(\n integration.methods.find((candidate) => candidate.type === \"oauth\"),\n \"OpenCode Console login is unavailable\",\n )\n\n yield* request(() => timeline.pending(\"Starting authorization...\"))\n const started = yield* request((signal) =>\n client.integration.connect.oauth(\n {\n integrationID,\n methodID: method.id,\n inputs: server ? { server } : {},\n location,\n },\n { signal },\n ),\n )\n const attempt = started.data\n yield* Effect.addFinalizer(() =>\n request(() =>\n client.integration.attempt.cancel(\n { attemptID: attempt.attemptID, location },\n { signal: AbortSignal.timeout(5_000) },\n ),\n ).pipe(Effect.ignore),\n )\n if (attempt.mode !== \"auto\") yield* Effect.fail(new Error(\"OpenCode Console requires a device login\"))\n\n yield* request(() => timeline.item(`Go to: ${attempt.url}`))\n yield* request(() => timeline.item(attempt.instructions))\n yield* request(async () => {\n const { default: open } = await import(\"open\")\n await open(attempt.url)\n }).pipe(Effect.ignore)\n yield* request(() => timeline.pending(\"Waiting for authorization...\"))\n\n const status = yield* waitForConsoleLogin(client, attempt.attemptID)\n if (status.status === \"failed\") yield* Effect.fail(new Error(status.message))\n if (status.status === \"expired\") yield* Effect.fail(new Error(\"Device code expired\"))\n\n yield* request(() => timeline.success(\"Connected to OpenCode Console\"))\n yield* request(() => timeline.outro(\"Done\"))\n})\n\nconst waitForConsoleLogin = Effect.fn(\"cli.console.login.wait\")(function* (\n client: OpenCodeClient,\n attemptID: string,\n) {\n while (true) {\n const response = yield* request((signal) =>\n client.integration.attempt.status({ attemptID, location }, { signal }),\n )\n if (response.data.status !== \"pending\") return response.data\n yield* Effect.sleep(500)\n }\n})\n\nfunction request<A>(task: (signal: AbortSignal) => Promise<A>) {\n return Effect.tryPromise({\n try: task,\n catch: (cause) => cause,\n })\n}\n\nfunction required<A>(value: A | null | undefined, message: string) {\n return value === null || value === undefined ? Effect.fail(new Error(message)) : Effect.succeed(value)\n}\n\nfunction errorMessage(cause: Cause.Cause<unknown>) {\n const error = Cause.squash(cause)\n if (error instanceof Error) return error.message\n if (typeof error === \"object\" && error !== null && \"message\" in error && typeof error.message === \"string\") {\n return error.message\n }\n return String(error)\n}\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "E1A1193D9AFE5BE364756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/mcp/add.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"node:os\"\nimport path from \"node:path\"\nimport { Effect, Option } from \"effect\"\nimport { applyEdits, modify } from \"jsonc-parser\"\nimport { Global } from \"@opencode-ai/core/global\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\n\nexport default Runtime.handler(\n Commands.commands.mcp.commands.add,\n Effect.fn(\"cli.mcp.add\")(function* (input) {\n const url = Option.getOrUndefined(input.url)\n const headers = Option.getOrUndefined(input.header)\n const environment = Option.getOrUndefined(input.env)\n // The CLI framework strands `--` operands on the root command, so read the local server command\n // straight from argv after `--`. This also lets the command carry its own flags (e.g. `npx -y`).\n const dash = process.argv.indexOf(\"--\")\n const command = dash === -1 ? [...input.command] : process.argv.slice(dash + 1)\n\n const hasCommand = command.length > 0\n if (url && hasCommand)\n return yield* Effect.fail(new Error(\"Provide either --url <url> or a command after --, not both\"))\n if (!url && !hasCommand) return yield* Effect.fail(new Error(\"Provide either --url <url> or a command after --\"))\n if (url && !URL.canParse(url)) return yield* Effect.fail(new Error(`Invalid URL: ${url}`))\n if (url && environment) return yield* Effect.fail(new Error(\"--env is only valid for local MCP servers\"))\n if (hasCommand && headers) return yield* Effect.fail(new Error(\"--header is only valid for remote MCP servers\"))\n\n const server = url\n ? { type: \"remote\" as const, url, ...(headers ? { headers } : {}) }\n : { type: \"local\" as const, command, ...(environment ? { environment } : {}) }\n\n const configPath = yield* Effect.promise(() => resolveConfigPath(input.global ? Global.Path.config : process.cwd()))\n yield* Effect.promise(() => write(configPath, input.name, server))\n process.stdout.write(`MCP server \"${input.name}\" added to ${configPath}` + EOL)\n }),\n)\n\nasync function resolveConfigPath(directory: string) {\n const candidates = [\n path.join(directory, \"opencode.json\"),\n path.join(directory, \"opencode.jsonc\"),\n path.join(directory, \".opencode\", \"opencode.json\"),\n path.join(directory, \".opencode\", \"opencode.jsonc\"),\n ]\n for (const candidate of candidates) {\n if (await Bun.file(candidate).exists()) return candidate\n }\n return candidates[0]\n}\n\nasync function write(configPath: string, name: string, server: unknown) {\n const file = Bun.file(configPath)\n const text = (await file.exists()) ? await file.text() : \"{}\"\n const edits = modify(text, [\"mcp\", \"servers\", name], server, {\n formattingOptions: { tabSize: 2, insertSpaces: true },\n })\n await Bun.write(configPath, applyEdits(text, edits))\n}\n" | ||
| ], | ||
| "mappings": ";yvBAAA,mBAAS,gBACT,yBAOA,SAAe,SAAQ,aACrB,OAAS,cAAS,SAAI,cAAS,SAC/B,OAAO,QAAG,kBAAa,OAAE,cAAU,MAAC,OAAO,MACzC,IAAM,EAAM,EAAO,eAAe,EAAM,GAAG,EACrC,EAAU,EAAO,eAAe,EAAM,MAAM,EAC5C,EAAc,EAAO,eAAe,EAAM,GAAG,EAG7C,EAAO,QAAQ,KAAK,QAAQ,IAAI,EAChC,EAAU,IAAS,GAAK,CAAC,GAAG,EAAM,OAAO,EAAI,QAAQ,KAAK,MAAM,EAAO,CAAC,EAExE,EAAa,EAAQ,OAAS,EACpC,GAAI,GAAO,EACT,OAAO,MAAO,EAAO,KAAS,MAAM,4DAA4D,CAAC,EACnG,GAAI,CAAC,GAAO,CAAC,EAAY,OAAO,MAAO,EAAO,KAAS,MAAM,kDAAkD,CAAC,EAChH,GAAI,GAAO,CAAC,IAAI,SAAS,CAAG,EAAG,OAAO,MAAO,EAAO,KAAS,MAAM,gBAAgB,GAAK,CAAC,EACzF,GAAI,GAAO,EAAa,OAAO,MAAO,EAAO,KAAS,MAAM,2CAA2C,CAAC,EACxG,GAAI,GAAc,EAAS,OAAO,MAAO,EAAO,KAAS,MAAM,+CAA+C,CAAC,EAE/G,IAAM,EAAS,EACX,CAAE,KAAM,SAAmB,SAAS,EAAU,CAAE,SAAQ,EAAI,CAAC,CAAG,EAChE,CAAE,KAAM,QAAkB,aAAa,EAAc,CAAE,aAAY,EAAI,CAAC,CAAG,EAEzE,EAAa,MAAO,EAAO,QAAQ,IAAM,EAAkB,EAAM,OAAS,EAAO,KAAK,OAAS,QAAQ,IAAI,CAAC,CAAC,EACnH,MAAO,EAAO,QAAQ,IAAM,EAAM,EAAY,EAAM,KAAM,CAAM,CAAC,EACjE,QAAQ,OAAO,MAAM,eAAe,EAAM,kBAAkB,IAAe,CAAG,EAC/E,CACH,EAEA,eAAe,CAAiB,CAAC,EAAmB,CAClD,IAAM,EAAa,CACjB,EAAK,KAAK,EAAW,eAAe,EACpC,EAAK,KAAK,EAAW,gBAAgB,EACrC,EAAK,KAAK,EAAW,YAAa,eAAe,EACjD,EAAK,KAAK,EAAW,YAAa,gBAAgB,CACpD,EACA,QAAW,KAAa,EACtB,GAAI,MAAM,IAAI,KAAK,CAAS,EAAE,OAAO,EAAG,OAAO,EAEjD,OAAO,EAAW,GAGpB,eAAe,CAAK,CAAC,EAAoB,EAAc,EAAiB,CACtE,IAAM,EAAO,IAAI,KAAK,CAAU,EAC1B,EAAQ,MAAM,EAAK,OAAO,EAAK,MAAM,EAAK,KAAK,EAAI,KACnD,EAAQ,EAAO,EAAM,CAAC,MAAO,UAAW,CAAI,EAAG,EAAQ,CAC3D,kBAAmB,CAAE,QAAS,EAAG,aAAc,EAAK,CACtD,CAAC,EACD,MAAM,IAAI,MAAM,EAAY,EAAW,EAAM,CAAK,CAAC", | ||
| "debugId": "2F63DD6101EF281264756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["../../node_modules/.bun/mime-types@3.0.2/node_modules/mime-types/mimeScore.js", "../core/src/fs-util.ts", "../../node_modules/.bun/mime-types@3.0.2/node_modules/mime-types/index.js", "../core/src/effect/service-use.ts"], | ||
| "sourcesContent": [ | ||
| "// 'mime-score' back-ported to CommonJS\n\n// Score RFC facets (see https://tools.ietf.org/html/rfc6838#section-3)\nvar FACET_SCORES = {\n 'prs.': 100,\n 'x-': 200,\n 'x.': 300,\n 'vnd.': 400,\n default: 900\n}\n\n// Score mime source (Logic originally from `jshttp/mime-types` module)\nvar SOURCE_SCORES = {\n nginx: 10,\n apache: 20,\n iana: 40,\n default: 30 // definitions added by `jshttp/mime-db` project?\n}\n\nvar TYPE_SCORES = {\n // prefer application/xml over text/xml\n // prefer application/rtf over text/rtf\n application: 1,\n\n // prefer font/woff over application/font-woff\n font: 2,\n\n // prefer video/mp4 over audio/mp4 over application/mp4\n // See https://www.rfc-editor.org/rfc/rfc4337.html#section-2\n audio: 2,\n video: 3,\n\n default: 0\n}\n\n/**\n * Get each component of the score for a mime type. The sum of these is the\n * total score. The higher the score, the more \"official\" the type.\n */\nmodule.exports = function mimeScore (mimeType, source = 'default') {\n if (mimeType === 'application/octet-stream') {\n return 0\n }\n\n const [type, subtype] = mimeType.split('/')\n\n const facet = subtype.replace(/(\\.|x-).*/, '$1')\n\n const facetScore = FACET_SCORES[facet] || FACET_SCORES.default\n const sourceScore = SOURCE_SCORES[source] || SOURCE_SCORES.default\n const typeScore = TYPE_SCORES[type] || TYPE_SCORES.default\n\n // All else being equal prefer shorter types\n const lengthScore = 1 - mimeType.length / 100\n\n return facetScore + sourceScore + typeScore + lengthScore\n}\n", | ||
| "import { NodeFileSystem } from \"@effect/platform-node\"\nimport path, { dirname, isAbsolute, join, relative, sep } from \"path\"\nimport { realpathSync } from \"fs\"\nimport { readdir } from \"fs/promises\"\nimport { lookup } from \"mime-types\"\nimport { Context, Effect, FileSystem, Layer, Schema } from \"effect\"\nimport type { PlatformError } from \"effect/PlatformError\"\nimport { Glob } from \"./util/glob\"\nimport { serviceUse } from \"./effect/service-use\"\nimport { makeGlobalNode } from \"./effect/app-node\"\nimport { filesystem } from \"./effect/app-node-platform\"\n\nexport namespace FSUtil {\n export class FileSystemError extends Schema.TaggedErrorClass<FileSystemError>()(\"FileSystemError\", {\n method: Schema.String,\n cause: Schema.optional(Schema.Defect()),\n }) {\n override get message() {\n const detail = this.cause instanceof Error ? this.cause.message : this.cause && String(this.cause)\n return `Filesystem operation failed: ${this.method}${detail ? `: ${detail}` : \"\"}`\n }\n }\n\n export type Error = PlatformError | FileSystemError\n\n export interface DirEntry {\n readonly name: string\n readonly type: \"file\" | \"directory\" | \"symlink\" | \"other\"\n }\n\n export interface Interface extends FileSystem.FileSystem {\n readonly isDir: (path: string) => Effect.Effect<boolean>\n readonly isFile: (path: string) => Effect.Effect<boolean>\n readonly existsSafe: (path: string) => Effect.Effect<boolean>\n readonly readFileStringSafe: (path: string) => Effect.Effect<string | undefined, Error>\n readonly readJson: (path: string) => Effect.Effect<unknown, Error>\n readonly writeJson: (path: string, data: unknown, mode?: number) => Effect.Effect<void, Error>\n readonly ensureDir: (path: string) => Effect.Effect<void, Error>\n readonly writeWithDirs: (path: string, content: string | Uint8Array, mode?: number) => Effect.Effect<void, Error>\n readonly readDirectoryEntries: (path: string) => Effect.Effect<DirEntry[], Error>\n readonly resolve: (path: string) => Effect.Effect<string>\n readonly findUp: (target: string, start: string, stop?: string) => Effect.Effect<string[], Error>\n readonly up: (options: { targets: string[]; start: string; stop?: string }) => Effect.Effect<string[], Error>\n readonly globUp: (pattern: string, start: string, stop?: string) => Effect.Effect<string[], Error>\n readonly glob: (pattern: string, options?: Glob.Options) => Effect.Effect<string[], Error>\n readonly globMatch: (pattern: string, filepath: string) => boolean\n }\n\n export class Service extends Context.Service<Service, Interface>()(\"@opencode/FileSystem\") {}\n\n export const use = serviceUse(Service)\n\n // Exported so simulation can wrap this layer and override the methods that\n // bypass the injected FileSystem (readDirectoryEntries, glob, globUp).\n export const layer = Layer.effect(\n Service,\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem\n\n const existsSafe = Effect.fn(\"FileSystem.existsSafe\")(function* (path: string) {\n return yield* fs.exists(path).pipe(Effect.orElseSucceed(() => false))\n })\n\n const readFileStringSafe = Effect.fn(\"FileSystem.readFileStringSafe\")(function* (path: string) {\n return yield* fs.readFileString(path).pipe(\n Effect.catchReason(\"PlatformError\", \"NotFound\", () => Effect.succeed(undefined)),\n Effect.catchReason(\"PlatformError\", \"PermissionDenied\", () => Effect.succeed(undefined)),\n )\n })\n\n const isDir = Effect.fn(\"FileSystem.isDir\")(function* (path: string) {\n const info = yield* fs.stat(path).pipe(Effect.catch(() => Effect.void))\n return info?.type === \"Directory\"\n })\n\n const isFile = Effect.fn(\"FileSystem.isFile\")(function* (path: string) {\n const info = yield* fs.stat(path).pipe(Effect.catch(() => Effect.void))\n return info?.type === \"File\"\n })\n\n const readDirectoryEntries = Effect.fn(\"FileSystem.readDirectoryEntries\")(function* (dirPath: string) {\n return yield* Effect.tryPromise({\n try: async () => {\n const entries = await readdir(dirPath, { withFileTypes: true })\n return entries.map(\n (e): DirEntry => ({\n name: e.name,\n type: e.isDirectory() ? \"directory\" : e.isSymbolicLink() ? \"symlink\" : e.isFile() ? \"file\" : \"other\",\n }),\n )\n },\n catch: (cause) => new FileSystemError({ method: \"readDirectoryEntries\", cause }),\n })\n })\n\n const resolve = Effect.fn(\"FileSystem.resolve\")(function* (input: string) {\n const resolved = path.resolve(windowsPath(input))\n return yield* fs.realPath(resolved).pipe(\n Effect.catchReason(\"PlatformError\", \"NotFound\", () => Effect.succeed(resolved)),\n Effect.orDie,\n )\n })\n\n const readJson = Effect.fn(\"FileSystem.readJson\")(function* (path: string) {\n const text = yield* fs.readFileString(path)\n return yield* Effect.try({\n try: () => JSON.parse(text),\n catch: (cause) => new FileSystemError({ method: \"readJson\", cause }),\n })\n })\n\n const writeJson = Effect.fn(\"FileSystem.writeJson\")(function* (path: string, data: unknown, mode?: number) {\n const content = JSON.stringify(data, null, 2)\n yield* fs.writeFileString(path, content)\n if (mode) yield* fs.chmod(path, mode)\n })\n\n const ensureDir = Effect.fn(\"FileSystem.ensureDir\")(function* (path: string) {\n yield* fs.makeDirectory(path, { recursive: true })\n })\n\n const writeWithDirs = Effect.fn(\"FileSystem.writeWithDirs\")(function* (\n path: string,\n content: string | Uint8Array,\n mode?: number,\n ) {\n const write = typeof content === \"string\" ? fs.writeFileString(path, content) : fs.writeFile(path, content)\n\n yield* write.pipe(\n Effect.catchIf(\n (e) => e.reason._tag === \"NotFound\",\n () =>\n Effect.gen(function* () {\n yield* fs.makeDirectory(dirname(path), { recursive: true })\n yield* write\n }),\n ),\n )\n if (mode) yield* fs.chmod(path, mode)\n })\n\n const glob = Effect.fn(\"FileSystem.glob\")(function* (pattern: string, options?: Glob.Options) {\n return yield* Effect.tryPromise({\n try: () => Glob.scan(pattern, options),\n catch: (cause) => new FileSystemError({ method: \"glob\", cause }),\n })\n })\n\n const findUp = Effect.fn(\"FileSystem.findUp\")(function* (target: string, start: string, stop?: string) {\n const result: string[] = []\n let current = start\n while (true) {\n const search = join(current, target)\n if (yield* fs.exists(search)) result.push(search)\n if (stop === current) break\n const parent = dirname(current)\n if (parent === current) break\n current = parent\n }\n return result\n })\n\n const up = Effect.fn(\"FileSystem.up\")(function* (options: { targets: string[]; start: string; stop?: string }) {\n const result: string[] = []\n let current = options.start\n while (true) {\n for (const target of options.targets) {\n const search = join(current, target)\n if (yield* fs.exists(search)) result.push(search)\n }\n if (options.stop === current) break\n const parent = dirname(current)\n if (parent === current) break\n current = parent\n }\n return result\n })\n\n const globUp = Effect.fn(\"FileSystem.globUp\")(function* (pattern: string, start: string, stop?: string) {\n const result: string[] = []\n let current = start\n while (true) {\n const matches = yield* glob(pattern, { cwd: current, absolute: true, include: \"file\", dot: true }).pipe(\n Effect.catch(() => Effect.succeed([] as string[])),\n )\n result.push(...matches)\n if (stop === current) break\n const parent = dirname(current)\n if (parent === current) break\n current = parent\n }\n return result\n })\n\n return Service.of({\n ...fs,\n existsSafe,\n readFileStringSafe,\n isDir,\n isFile,\n readDirectoryEntries,\n resolve,\n readJson,\n writeJson,\n ensureDir,\n writeWithDirs,\n findUp,\n up,\n globUp,\n glob,\n globMatch: Glob.match,\n })\n }),\n )\n\n export const node = makeGlobalNode({ service: Service, layer: layer, deps: [filesystem] })\n\n // Pure helpers that don't need Effect (path manipulation, sync operations)\n export function mimeType(p: string): string {\n return lookup(p) || \"application/octet-stream\"\n }\n\n export function normalizePath(p: string): string {\n if (process.platform !== \"win32\") return p\n const resolved = path.resolve(windowsPath(p))\n try {\n return realpathSync.native(resolved)\n } catch {\n return resolved\n }\n }\n\n export function normalizePathPattern(p: string): string {\n if (process.platform !== \"win32\") return p\n if (p === \"*\") return p\n const match = p.match(/^(.*)[\\\\/]\\*$/)\n if (!match) return normalizePath(p)\n const dir = /^[A-Za-z]:$/.test(match[1]) ? match[1] + \"\\\\\" : match[1]\n return join(normalizePath(dir), \"*\")\n }\n\n export function resolve(p: string): string {\n const resolved = path.resolve(windowsPath(p))\n try {\n return normalizePath(realpathSync(resolved))\n } catch (e: any) {\n if (e?.code === \"ENOENT\") return normalizePath(resolved)\n throw e\n }\n }\n\n export function windowsPath(p: string): string {\n if (process.platform !== \"win32\") return p\n return p\n .replace(/^\\/([a-zA-Z]):(?:[\\\\/]|$)/, (_, drive) => `${drive.toUpperCase()}:/`)\n .replace(/^\\/([a-zA-Z])(?:\\/|$)/, (_, drive) => `${drive.toUpperCase()}:/`)\n .replace(/^\\/cygdrive\\/([a-zA-Z])(?:\\/|$)/, (_, drive) => `${drive.toUpperCase()}:/`)\n .replace(/^\\/mnt\\/([a-zA-Z])(?:\\/|$)/, (_, drive) => `${drive.toUpperCase()}:/`)\n }\n\n export function overlaps(a: string, b: string) {\n return contains(a, b) || contains(b, a)\n }\n\n export function contains(parent: string, child: string) {\n const result = relative(parent, child)\n return result === \"\" || (!isAbsolute(result) && result !== \"..\" && !result.startsWith(`..${sep}`))\n }\n}\n", | ||
| "/*!\n * mime-types\n * Copyright(c) 2014 Jonathan Ong\n * Copyright(c) 2015 Douglas Christopher Wilson\n * MIT Licensed\n */\n\n'use strict'\n\n/**\n * Module dependencies.\n * @private\n */\n\nvar db = require('mime-db')\nvar extname = require('path').extname\nvar mimeScore = require('./mimeScore')\n\n/**\n * Module variables.\n * @private\n */\n\nvar EXTRACT_TYPE_REGEXP = /^\\s*([^;\\s]*)(?:;|\\s|$)/\nvar TEXT_TYPE_REGEXP = /^text\\//i\n\n/**\n * Module exports.\n * @public\n */\n\nexports.charset = charset\nexports.charsets = { lookup: charset }\nexports.contentType = contentType\nexports.extension = extension\nexports.extensions = Object.create(null)\nexports.lookup = lookup\nexports.types = Object.create(null)\nexports._extensionConflicts = []\n\n// Populate the extensions/types maps\npopulateMaps(exports.extensions, exports.types)\n\n/**\n * Get the default charset for a MIME type.\n *\n * @param {string} type\n * @return {false|string}\n */\n\nfunction charset (type) {\n if (!type || typeof type !== 'string') {\n return false\n }\n\n // TODO: use media-typer\n var match = EXTRACT_TYPE_REGEXP.exec(type)\n var mime = match && db[match[1].toLowerCase()]\n\n if (mime && mime.charset) {\n return mime.charset\n }\n\n // default text/* to utf-8\n if (match && TEXT_TYPE_REGEXP.test(match[1])) {\n return 'UTF-8'\n }\n\n return false\n}\n\n/**\n * Create a full Content-Type header given a MIME type or extension.\n *\n * @param {string} str\n * @return {false|string}\n */\n\nfunction contentType (str) {\n // TODO: should this even be in this module?\n if (!str || typeof str !== 'string') {\n return false\n }\n\n var mime = str.indexOf('/') === -1 ? exports.lookup(str) : str\n\n if (!mime) {\n return false\n }\n\n // TODO: use content-type or other module\n if (mime.indexOf('charset') === -1) {\n var charset = exports.charset(mime)\n if (charset) mime += '; charset=' + charset.toLowerCase()\n }\n\n return mime\n}\n\n/**\n * Get the default extension for a MIME type.\n *\n * @param {string} type\n * @return {false|string}\n */\n\nfunction extension (type) {\n if (!type || typeof type !== 'string') {\n return false\n }\n\n // TODO: use media-typer\n var match = EXTRACT_TYPE_REGEXP.exec(type)\n\n // get extensions\n var exts = match && exports.extensions[match[1].toLowerCase()]\n\n if (!exts || !exts.length) {\n return false\n }\n\n return exts[0]\n}\n\n/**\n * Lookup the MIME type for a file path/extension.\n *\n * @param {string} path\n * @return {false|string}\n */\n\nfunction lookup (path) {\n if (!path || typeof path !== 'string') {\n return false\n }\n\n // get the extension (\"ext\" or \".ext\" or full path)\n var extension = extname('x.' + path)\n .toLowerCase()\n .slice(1)\n\n if (!extension) {\n return false\n }\n\n return exports.types[extension] || false\n}\n\n/**\n * Populate the extensions and types maps.\n * @private\n */\n\nfunction populateMaps (extensions, types) {\n Object.keys(db).forEach(function forEachMimeType (type) {\n var mime = db[type]\n var exts = mime.extensions\n\n if (!exts || !exts.length) {\n return\n }\n\n // mime -> extensions\n extensions[type] = exts\n\n // extension -> mime\n for (var i = 0; i < exts.length; i++) {\n var extension = exts[i]\n types[extension] = _preferredType(extension, types[extension], type)\n\n // DELETE (eventually): Capture extension->type maps that change as a\n // result of switching to mime-score. This is just to help make reviewing\n // PR #119 easier, and can be removed once that PR is approved.\n const legacyType = _preferredTypeLegacy(\n extension,\n types[extension],\n type\n )\n if (legacyType !== types[extension]) {\n exports._extensionConflicts.push([extension, legacyType, types[extension]])\n }\n }\n })\n}\n\n// Resolve type conflict using mime-score\nfunction _preferredType (ext, type0, type1) {\n var score0 = type0 ? mimeScore(type0, db[type0].source) : 0\n var score1 = type1 ? mimeScore(type1, db[type1].source) : 0\n\n return score0 > score1 ? type0 : type1\n}\n\n// Resolve type conflict using pre-mime-score logic\nfunction _preferredTypeLegacy (ext, type0, type1) {\n var SOURCE_RANK = ['nginx', 'apache', undefined, 'iana']\n\n var score0 = type0 ? SOURCE_RANK.indexOf(db[type0].source) : 0\n var score1 = type1 ? SOURCE_RANK.indexOf(db[type1].source) : 0\n\n if (\n exports.types[extension] !== 'application/octet-stream' &&\n (score0 > score1 ||\n (score0 === score1 &&\n exports.types[extension]?.slice(0, 12) === 'application/'))\n ) {\n return type0\n }\n\n return score0 > score1 ? type0 : type1\n}\n", | ||
| "import { Context, Effect } from \"effect\"\n\ntype EffectMethod = (...args: ReadonlyArray<never>) => Effect.Effect<unknown, unknown, unknown>\n\ntype ServiceUse<Identifier, Shape> = {\n readonly [Key in keyof Shape as Shape[Key] extends EffectMethod ? Key : never]: Shape[Key] extends (\n ...args: infer Args\n ) => infer Return\n ? Args extends ReadonlyArray<unknown>\n ? Return extends Effect.Effect<infer A, infer E, infer R>\n ? (...args: Args) => Effect.Effect<A, E, R | Identifier>\n : never\n : never\n : never\n}\n\nexport const serviceUse = <Identifier, Shape>(tag: Context.Service<Identifier, Shape>) => {\n const cache = new Map<string, (...args: unknown[]) => Effect.Effect<unknown, unknown, unknown>>()\n // This is the only dynamic boundary: TypeScript knows the accessor shape,\n // but Proxy property names are runtime values.\n const access = new Proxy(\n {},\n {\n get: (_, key) => {\n if (typeof key !== \"string\") return undefined\n const cached = cache.get(key)\n if (cached) return cached\n const accessor = (...args: unknown[]) =>\n tag.use((service) => {\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- Proxy keys are checked at runtime.\n const method = service[key as keyof Shape]\n if (typeof method !== \"function\") return Effect.die(new Error(`Service method not found: ${key}`))\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- ServiceUse exposes only Effect-returning methods.\n return (method as (...args: unknown[]) => Effect.Effect<unknown, unknown, unknown>)(...args)\n })\n cache.set(key, accessor)\n return accessor\n },\n },\n )\n // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- Proxy implements the mapped accessor surface lazily.\n return access as ServiceUse<Identifier, Shape>\n}\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "0F1065248EFB2F8064756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/service/start.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"os\"\nimport { Effect } from \"effect\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { ServiceConfig } from \"../../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.service.commands.start,\n Effect.fn(\"cli.service.start\")(function* () {\n const transport = yield* Service.ensure(yield* ServiceConfig.options())\n process.stdout.write(transport.url + EOL)\n }),\n)\n" | ||
| ], | ||
| "mappings": ";+0BAAA,mBAAS,gBAOT,SAAe,SAAQ,aACrB,OAAS,cAAS,aAAQ,cAAS,WACnC,OAAO,QAAG,wBAAmB,OAAE,cAAU,OAAG,MAC1C,SAAM,OAAY,WAAO,OAAQ,YAAO,MAAO,EAAc,QAAQ,CAAC,EACtE,QAAQ,OAAO,MAAM,EAAU,IAAM,CAAG,EACzC,CACH", | ||
| "debugId": "2DBF0C40A4BDE07064756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["../core/src/image/photon.ts"], | ||
| "sourcesContent": [ | ||
| "// @ts-ignore Bun's static file import is embedded by `bun build --compile`; some consumers also declare *.wasm.\nimport photonWasm from \"@silvia-odwyer/photon-node/photon_rs_bg.wasm\" with { type: \"file\" }\nimport { Effect } from \"effect\"\nimport path from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\nimport { FileSystem } from \"../filesystem\"\nimport { DecodeError, ResizerUnavailableError, SizeError } from \"../image\"\n\nconst JPEG_QUALITIES = [80, 85, 70, 55, 40]\n\nexport const make = Effect.gen(function* () {\n ;(globalThis as typeof globalThis & { __OPENCODE_PHOTON_WASM_PATH?: string }).__OPENCODE_PHOTON_WASM_PATH =\n path.isAbsolute(photonWasm) ? photonWasm : fileURLToPath(new URL(photonWasm, import.meta.url))\n const loadPhoton = yield* Effect.cached(\n Effect.tryPromise({\n try: () => import(\"@silvia-odwyer/photon-node\"),\n catch: () => new ResizerUnavailableError(),\n }),\n )\n return Effect.fn(\"Image.Photon.normalize\")(function* (\n resource: string,\n content: FileSystem.Content & { readonly encoding: \"base64\" },\n limits: {\n readonly autoResize: boolean\n readonly maxWidth: number\n readonly maxHeight: number\n readonly maxBase64Bytes: number\n },\n ) {\n const photon = yield* loadPhoton\n const decoded = yield* Effect.try({\n try: () => photon.PhotonImage.new_from_byteslice(Buffer.from(content.content, \"base64\")),\n catch: () => new DecodeError({ resource }),\n })\n try {\n const width = decoded.get_width()\n const height = decoded.get_height()\n const bytes = Buffer.byteLength(content.content, \"utf-8\")\n if (width <= limits.maxWidth && height <= limits.maxHeight && bytes <= limits.maxBase64Bytes) return content\n if (!limits.autoResize)\n return yield* new SizeError({\n resource,\n width,\n height,\n bytes,\n maxWidth: limits.maxWidth,\n maxHeight: limits.maxHeight,\n maxBytes: limits.maxBase64Bytes,\n })\n const scale = Math.min(1, limits.maxWidth / width, limits.maxHeight / height)\n const sizes = Array.from({ length: 32 }).reduce<Array<{ width: number; height: number }>>((acc) => {\n const previous = acc.at(-1) ?? {\n width: Math.max(1, Math.round(width * scale)),\n height: Math.max(1, Math.round(height * scale)),\n }\n const next =\n acc.length === 0\n ? previous\n : {\n width: previous.width === 1 ? 1 : Math.max(1, Math.floor(previous.width * 0.75)),\n height: previous.height === 1 ? 1 : Math.max(1, Math.floor(previous.height * 0.75)),\n }\n return acc.some((item) => item.width === next.width && item.height === next.height) ? acc : [...acc, next]\n }, [])\n for (const size of sizes) {\n const resized = photon.resize(decoded, size.width, size.height, photon.SamplingFilter.Lanczos3)\n try {\n const encoders: Array<readonly [mime: string, encode: () => Uint8Array]> = [\n [\"image/png\", () => resized.get_bytes()],\n ...JPEG_QUALITIES.map((quality) => [\"image/jpeg\", () => resized.get_bytes_jpeg(quality)] as const),\n ]\n for (const [mime, encode] of encoders) {\n const candidate = Buffer.from(encode()).toString(\"base64\")\n if (Buffer.byteLength(candidate, \"utf-8\") <= limits.maxBase64Bytes)\n return { ...content, content: candidate, encoding: \"base64\" as const, mime }\n }\n } finally {\n resized.free()\n }\n }\n return yield* new SizeError({\n resource,\n width,\n height,\n bytes,\n maxWidth: limits.maxWidth,\n maxHeight: limits.maxHeight,\n maxBytes: limits.maxBase64Bytes,\n })\n } finally {\n decoded.free()\n }\n })\n})\n" | ||
| ], | ||
| "mappings": ";yvBAGA,yBACA,6BAAS,iBAIT,SAAM,OAAiB,MAAC,QAAI,QAAI,QAAI,QAAI,OAAE,OAE7B,OAAO,OAAO,SAAI,cAAU,OAAG,MACxC,gBAA4E,0CAC5E,EAAK,WAAW,CAAU,EAAI,EAAa,EAAc,IAAI,IAAI,EAAY,YAAY,GAAG,CAAC,EAC/F,IAAM,EAAa,MAAO,EAAO,OAC/B,EAAO,WAAW,CAChB,IAAK,IAAa,yCAClB,MAAO,IAAM,IAAI,CACnB,CAAC,CACH,EACA,OAAO,EAAO,GAAG,wBAAwB,EAAE,SAAU,CACnD,EACA,EACA,EAMA,CACA,IAAM,EAAS,MAAO,EAChB,EAAU,MAAO,EAAO,IAAI,CAChC,IAAK,IAAM,EAAO,YAAY,mBAAmB,OAAO,KAAK,EAAQ,QAAS,QAAQ,CAAC,EACvF,MAAO,IAAM,IAAI,EAAY,CAAE,UAAS,CAAC,CAC3C,CAAC,EACD,GAAI,CACF,IAAM,EAAQ,EAAQ,UAAU,EAC1B,EAAS,EAAQ,WAAW,EAC5B,EAAQ,OAAO,WAAW,EAAQ,QAAS,OAAO,EACxD,GAAI,GAAS,EAAO,UAAY,GAAU,EAAO,WAAa,GAAS,EAAO,eAAgB,OAAO,EACrG,GAAI,CAAC,EAAO,WACV,OAAO,MAAO,IAAI,EAAU,CAC1B,WACA,QACA,SACA,QACA,SAAU,EAAO,SACjB,UAAW,EAAO,UAClB,SAAU,EAAO,cACnB,CAAC,EACH,IAAM,EAAQ,KAAK,IAAI,EAAG,EAAO,SAAW,EAAO,EAAO,UAAY,CAAM,EACtE,EAAQ,MAAM,KAAK,CAAE,OAAQ,EAAG,CAAC,EAAE,OAAiD,CAAC,IAAQ,CACjG,IAAM,EAAW,EAAI,GAAG,EAAE,GAAK,CAC7B,MAAO,KAAK,IAAI,EAAG,KAAK,MAAM,EAAQ,CAAK,CAAC,EAC5C,OAAQ,KAAK,IAAI,EAAG,KAAK,MAAM,EAAS,CAAK,CAAC,CAChD,EACM,EACJ,EAAI,SAAW,EACX,EACA,CACE,MAAO,EAAS,QAAU,EAAI,EAAI,KAAK,IAAI,EAAG,KAAK,MAAM,EAAS,MAAQ,IAAI,CAAC,EAC/E,OAAQ,EAAS,SAAW,EAAI,EAAI,KAAK,IAAI,EAAG,KAAK,MAAM,EAAS,OAAS,IAAI,CAAC,CACpF,EACN,OAAO,EAAI,KAAK,CAAC,IAAS,EAAK,QAAU,EAAK,OAAS,EAAK,SAAW,EAAK,MAAM,EAAI,EAAM,CAAC,GAAG,EAAK,CAAI,GACxG,CAAC,CAAC,EACL,QAAW,KAAQ,EAAO,CACxB,IAAM,EAAU,EAAO,OAAO,EAAS,EAAK,MAAO,EAAK,OAAQ,EAAO,eAAe,QAAQ,EAC9F,GAAI,CACF,IAAM,EAAqE,CACzE,CAAC,YAAa,IAAM,EAAQ,UAAU,CAAC,EACvC,GAAG,EAAe,IAAI,CAAC,IAAY,CAAC,aAAc,IAAM,EAAQ,eAAe,CAAO,CAAC,CAAU,CACnG,EACA,QAAY,EAAM,KAAW,EAAU,CACrC,IAAM,EAAY,OAAO,KAAK,EAAO,CAAC,EAAE,SAAS,QAAQ,EACzD,GAAI,OAAO,WAAW,EAAW,OAAO,GAAK,EAAO,eAClD,MAAO,IAAK,EAAS,QAAS,EAAW,SAAU,SAAmB,MAAK,UAE/E,CACA,EAAQ,KAAK,GAGjB,OAAO,MAAO,IAAI,EAAU,CAC1B,WACA,QACA,SACA,QACA,SAAU,EAAO,SACjB,UAAW,EAAO,UAClB,SAAU,EAAO,cACnB,CAAC,SACD,CACA,EAAQ,KAAK,GAEhB,EACF", | ||
| "debugId": "40613DB8D830CC1B64756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/service/status.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"os\"\nimport { Effect } from \"effect\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { ServiceConfig } from \"../../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.service.commands.status,\n Effect.fn(\"cli.service.status\")(function* () {\n const options = yield* ServiceConfig.options()\n const found = yield* Service.discover({ ...options, version: undefined })\n process.stdout.write((found?.url ?? \"stopped\") + EOL)\n }),\n)\n" | ||
| ], | ||
| "mappings": ";+0BAAA,mBAAS,gBAOT,SAAe,SAAQ,aACrB,OAAS,cAAS,aAAQ,cAAS,YACnC,OAAO,QAAG,yBAAoB,OAAE,cAAU,OAAG,MAC3C,SAAM,OAAU,WAAO,OAAc,aAAQ,EACvC,EAAQ,MAAO,EAAQ,SAAS,IAAK,EAAS,QAAS,MAAU,CAAC,EACxE,QAAQ,OAAO,OAAO,GAAO,KAAO,WAAa,CAAG,EACrD,CACH", | ||
| "debugId": "5FF059D372C6D11E64756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["../llm/src/protocols/utils/openai-options.ts", "../llm/src/protocols/utils/lifecycle.ts", "../llm/src/protocols/utils/gemini-tool-schema.ts", "../llm/src/protocols/utils/tool-schema.ts", "../llm/src/protocols/utils/tool-stream.ts", "../llm/src/protocols/openai-chat.ts"], | ||
| "sourcesContent": [ | ||
| "import { Schema } from \"effect\"\nimport type { LLMRequest, TextVerbosity as TextVerbosityValue } from \"../../schema\"\nimport { ReasoningEfforts, TextVerbosity } from \"../../schema\"\n\nexport const OpenAIReasoningEfforts = ReasoningEfforts\nexport type OpenAIReasoningEffort = string\n\n// Mirrors OpenAI's `ResponseIncludable` union from the official SDK. Keep this\n// in lockstep with `openai-node/src/resources/responses/responses.ts`.\nexport const OpenAIResponseIncludables = [\n \"file_search_call.results\",\n \"web_search_call.results\",\n \"web_search_call.action.sources\",\n \"message.input_image.image_url\",\n \"computer_call_output.output.image_url\",\n \"code_interpreter_call.outputs\",\n \"reasoning.encrypted_content\",\n \"message.output_text.logprobs\",\n] as const\nexport type OpenAIResponseIncludable = (typeof OpenAIResponseIncludables)[number]\nexport const OpenAIServiceTiers = [\"auto\", \"default\", \"flex\", \"priority\"] as const\nexport type OpenAIServiceTier = (typeof OpenAIServiceTiers)[number]\n\nconst TEXT_VERBOSITY = new Set<string>([\"low\", \"medium\", \"high\"])\nconst INCLUDABLES = new Set<string>(OpenAIResponseIncludables)\nconst SERVICE_TIERS = new Set<string>(OpenAIServiceTiers)\n\nexport const OpenAIReasoningEffort = Schema.String\nexport const OpenAITextVerbosity = TextVerbosity\nexport const OpenAIResponseIncludable = Schema.Literals(OpenAIResponseIncludables)\nexport const OpenAIServiceTier = Schema.Literals(OpenAIServiceTiers)\n\nexport const isReasoningEffort = (effort: unknown): effort is OpenAIReasoningEffort => typeof effort === \"string\"\n\nconst isTextVerbosity = (value: unknown): value is TextVerbosityValue =>\n typeof value === \"string\" && TEXT_VERBOSITY.has(value)\n\nconst options = (request: LLMRequest) => request.providerOptions?.openai\n\nexport const store = (request: LLMRequest): boolean | undefined => {\n const value = options(request)?.store\n return typeof value === \"boolean\" ? value : undefined\n}\n\nexport const reasoningEffort = (request: LLMRequest): string | undefined => {\n const value = options(request)?.reasoningEffort\n return typeof value === \"string\" ? value : undefined\n}\n\nexport const reasoningSummary = (request: LLMRequest): \"auto\" | undefined =>\n options(request)?.reasoningSummary === \"auto\" ? \"auto\" : undefined\n\n// Resolve the OpenAI Responses `include` field. Filters out unknown\n// includable values defensively so a typo in upstream config drops the\n// invalid entry instead of poisoning the wire body. An empty array (either\n// passed directly or produced by filtering) is treated as \"no include\" and\n// returns undefined so the request body omits the field entirely.\nexport const include = (request: LLMRequest): ReadonlyArray<OpenAIResponseIncludable> | undefined => {\n const value = options(request)?.include\n if (!Array.isArray(value)) return undefined\n const filtered = value.filter((entry): entry is OpenAIResponseIncludable => INCLUDABLES.has(entry))\n return filtered.length > 0 ? filtered : undefined\n}\n\nexport const promptCacheKey = (request: LLMRequest) => {\n const value = options(request)?.promptCacheKey\n return typeof value === \"string\" ? value : undefined\n}\n\nexport const textVerbosity = (request: LLMRequest) => {\n const value = options(request)?.textVerbosity\n return isTextVerbosity(value) ? value : undefined\n}\n\nexport const serviceTier = (request: LLMRequest) => {\n const value = options(request)?.serviceTier\n return typeof value === \"string\" && SERVICE_TIERS.has(value) ? (value as OpenAIServiceTier) : undefined\n}\n\nexport const instructions = (request: LLMRequest) => {\n const value = options(request)?.instructions\n return typeof value === \"string\" ? value : undefined\n}\n\nexport * as OpenAIOptions from \"./openai-options\"\n", | ||
| "import { LLMEvent, type FinishReason, type ProviderMetadata, type Usage } from \"../../schema\"\n\nexport interface State {\n readonly stepStarted: boolean\n readonly text: ReadonlySet<string>\n readonly reasoning: ReadonlySet<string>\n}\n\nexport const initial = (): State => ({ stepStarted: false, text: new Set(), reasoning: new Set() })\n\nexport const stepStart = (state: State, events: LLMEvent[]): State => {\n if (state.stepStarted) return state\n events.push(LLMEvent.stepStart({ index: 0 }))\n return { ...state, stepStarted: true }\n}\n\nexport const textDelta = (state: State, events: LLMEvent[], id: string, text: string): State => {\n const stepped = stepStart(state, events)\n if (stepped.text.has(id)) {\n events.push(LLMEvent.textDelta({ id, text }))\n return stepped\n }\n events.push(LLMEvent.textStart({ id }), LLMEvent.textDelta({ id, text }))\n return { ...stepped, text: new Set([...stepped.text, id]) }\n}\n\nexport const reasoningStart = (\n state: State,\n events: LLMEvent[],\n id: string,\n providerMetadata?: ProviderMetadata,\n): State => {\n if (state.reasoning.has(id)) return state\n const stepped = stepStart(state, events)\n events.push(LLMEvent.reasoningStart({ id, providerMetadata }))\n return { ...stepped, reasoning: new Set([...stepped.reasoning, id]) }\n}\n\nexport const reasoningDelta = (\n state: State,\n events: LLMEvent[],\n id: string,\n text: string,\n providerMetadata?: ProviderMetadata,\n): State => {\n const started = reasoningStart(state, events, id, providerMetadata)\n events.push(LLMEvent.reasoningDelta({ id, text }))\n return started\n}\n\nexport const reasoningEnd = (\n state: State,\n events: LLMEvent[],\n id: string,\n providerMetadata?: ProviderMetadata,\n): State => {\n if (!state.reasoning.has(id)) return state\n const stepped = stepStart(state, events)\n events.push(LLMEvent.reasoningEnd({ id, providerMetadata }))\n const reasoning = new Set(stepped.reasoning)\n reasoning.delete(id)\n return { ...stepped, reasoning }\n}\n\nexport const textEnd = (state: State, events: LLMEvent[], id: string, providerMetadata?: ProviderMetadata): State => {\n if (!state.text.has(id)) return state\n const stepped = stepStart(state, events)\n events.push(LLMEvent.textEnd({ id, providerMetadata }))\n const text = new Set(stepped.text)\n text.delete(id)\n return { ...stepped, text }\n}\n\nconst closeOpenBlocks = (state: State, events: LLMEvent[]): State => {\n for (const id of state.reasoning) events.push(LLMEvent.reasoningEnd({ id }))\n for (const id of state.text) events.push(LLMEvent.textEnd({ id }))\n return { ...state, text: new Set(), reasoning: new Set() }\n}\n\nexport const finish = (\n state: State,\n events: LLMEvent[],\n input: {\n readonly reason: FinishReason\n readonly usage?: Usage\n readonly providerMetadata?: ProviderMetadata\n },\n): State => {\n const stepped = closeOpenBlocks(stepStart(state, events), events)\n events.push(\n LLMEvent.stepFinish({\n index: 0,\n reason: input.reason,\n usage: input.usage,\n providerMetadata: input.providerMetadata,\n }),\n LLMEvent.finish(input),\n )\n return { ...stepped, stepStarted: false }\n}\n\nexport * as Lifecycle from \"./lifecycle\"\n", | ||
| "import { isRecord } from \"../../utils/record\"\n\n// Gemini accepts a JSON Schema-like dialect for tool parameters, but rejects a\n// handful of common JSON Schema shapes. Keep this projection isolated so the\n// Gemini protocol file still reads like the other protocol modules.\nconst SCHEMA_INTENT_KEYS = [\n \"type\",\n \"properties\",\n \"items\",\n \"prefixItems\",\n \"enum\",\n \"const\",\n \"$ref\",\n \"additionalProperties\",\n \"patternProperties\",\n \"required\",\n \"not\",\n \"if\",\n \"then\",\n \"else\",\n]\n\nconst hasCombiner = (schema: unknown) =>\n isRecord(schema) && (Array.isArray(schema.anyOf) || Array.isArray(schema.oneOf) || Array.isArray(schema.allOf))\n\nconst hasSchemaIntent = (schema: unknown) =>\n isRecord(schema) && (hasCombiner(schema) || SCHEMA_INTENT_KEYS.some((key) => key in schema))\n\nconst sanitizeNode = (schema: unknown): unknown => {\n if (!isRecord(schema)) return Array.isArray(schema) ? schema.map(sanitizeNode) : schema\n\n const result: Record<string, unknown> = Object.fromEntries(\n Object.entries(schema).map(([key, value]) => [\n key,\n key === \"enum\" && Array.isArray(value) ? value.map(String) : sanitizeNode(value),\n ]),\n )\n\n if (Array.isArray(result.enum) && (result.type === \"integer\" || result.type === \"number\")) result.type = \"string\"\n\n const properties = result.properties\n if (result.type === \"object\" && isRecord(properties) && Array.isArray(result.required)) {\n result.required = result.required.filter((field) => typeof field === \"string\" && field in properties)\n }\n\n if (result.type === \"array\" && !hasCombiner(result)) {\n result.items = result.items ?? {}\n if (isRecord(result.items) && !hasSchemaIntent(result.items)) result.items = { ...result.items, type: \"string\" }\n }\n\n if (typeof result.type === \"string\" && result.type !== \"object\" && !hasCombiner(result)) {\n delete result.properties\n delete result.required\n }\n\n return result\n}\n\nconst emptyObjectSchema = (schema: Record<string, unknown>) =>\n schema.type === \"object\" &&\n (!isRecord(schema.properties) || Object.keys(schema.properties).length === 0) &&\n !schema.additionalProperties\n\nconst projectNode = (schema: unknown): Record<string, unknown> | undefined => {\n if (!isRecord(schema)) return undefined\n if (emptyObjectSchema(schema)) return undefined\n return Object.fromEntries(\n [\n [\"description\", schema.description],\n [\"required\", schema.required],\n [\"format\", schema.format],\n [\"type\", Array.isArray(schema.type) ? schema.type.filter((type) => type !== \"null\")[0] : schema.type],\n [\"nullable\", Array.isArray(schema.type) && schema.type.includes(\"null\") ? true : undefined],\n [\"enum\", schema.const !== undefined ? [schema.const] : schema.enum],\n [\n \"properties\",\n isRecord(schema.properties)\n ? Object.fromEntries(Object.entries(schema.properties).map(([key, value]) => [key, projectNode(value)]))\n : undefined,\n ],\n [\n \"items\",\n Array.isArray(schema.items)\n ? schema.items.map(projectNode)\n : schema.items === undefined\n ? undefined\n : projectNode(schema.items),\n ],\n [\"allOf\", Array.isArray(schema.allOf) ? schema.allOf.map(projectNode) : undefined],\n [\"anyOf\", Array.isArray(schema.anyOf) ? schema.anyOf.map(projectNode) : undefined],\n [\"oneOf\", Array.isArray(schema.oneOf) ? schema.oneOf.map(projectNode) : undefined],\n [\"minLength\", schema.minLength],\n ].filter((entry) => entry[1] !== undefined),\n )\n}\n\nexport const convert = (schema: unknown) => projectNode(sanitizeNode(schema))\n\nexport * as GeminiToolSchema from \"./gemini-tool-schema\"\n", | ||
| "import type { JsonSchema, ModelToolSchemaCompatibility } from \"../../schema\"\nimport { isRecord } from \"../../utils/record\"\nimport { GeminiToolSchema } from \"./gemini-tool-schema\"\n\nconst removeNullSchemas = (value: unknown): unknown => {\n if (Array.isArray(value)) return value.map(removeNullSchemas)\n if (!isRecord(value)) return value\n const fields = Object.fromEntries(\n Object.entries(value)\n .filter(([key]) => key !== \"anyOf\")\n .map(([key, field]) => [key, removeNullSchemas(field)]),\n )\n if (!Array.isArray(value.anyOf)) return fields\n const variants = value.anyOf.filter((variant) => !isRecord(variant) || variant.type !== \"null\").map(removeNullSchemas)\n if (variants.length === 1 && isRecord(variants[0])) return { ...fields, ...variants[0] }\n return { ...fields, anyOf: variants }\n}\n\nconst tupleItemsSchema = (items: ReadonlyArray<unknown>) => {\n const projected = items.map(moonshotNode)\n if (projected.length === 0) return {}\n if (projected.length === 1) return projected[0]\n return { anyOf: projected }\n}\n\nconst moonshotNode = (schema: unknown): unknown => {\n if (Array.isArray(schema)) return schema.map(moonshotNode)\n if (!isRecord(schema)) return schema\n if (typeof schema.$ref === \"string\") return { $ref: schema.$ref }\n return Object.fromEntries(\n Object.entries(schema).flatMap(([key, value]) => {\n if (key === \"items\" && Array.isArray(value)) return [[key, tupleItemsSchema(value)]]\n if (key === \"prefixItems\") {\n if (\"items\" in schema) return []\n return [[\"items\", tupleItemsSchema(Array.isArray(value) ? value : [])]]\n }\n if (key === \"unevaluatedItems\") return []\n return [[key, moonshotNode(value)]]\n }),\n )\n}\n\nconst moonshot = (schema: JsonSchema): JsonSchema => {\n const projected = moonshotNode(schema)\n return isRecord(projected) ? projected : {}\n}\n\nconst openAI = (schema: JsonSchema): JsonSchema => {\n const variants = Array.isArray(schema.anyOf) ? schema.anyOf.filter(isRecord) : []\n const flattened =\n variants.length === 0\n ? { ...schema, type: \"object\" }\n : {\n ...Object.fromEntries(Object.entries(schema).filter(([key]) => key !== \"anyOf\")),\n type: \"object\",\n properties: variants.reduce(\n (properties, variant) => ({ ...(isRecord(variant.properties) ? variant.properties : {}), ...properties }),\n {},\n ),\n additionalProperties: false,\n }\n const normalized = removeNullSchemas(flattened)\n return isRecord(normalized) ? normalized : { type: \"object\" }\n}\n\nconst gemini = (schema: JsonSchema): JsonSchema => GeminiToolSchema.convert(schema) ?? {}\n\nconst modelCompatibility = (\n schema: JsonSchema,\n compatibility: ModelToolSchemaCompatibility | undefined,\n): JsonSchema => {\n if (compatibility === undefined) return schema\n switch (compatibility) {\n case \"gemini\":\n return gemini(schema)\n case \"moonshot\":\n return moonshot(schema)\n }\n}\n\nexport const ToolSchemaProjection = {\n gemini,\n modelCompatibility,\n moonshot,\n openAI,\n} as const\n", | ||
| "import { Effect } from \"effect\"\nimport { LLMError, LLMEvent, type ProviderMetadata, type ToolCall } from \"../../schema\"\nimport { eventError, parseToolInput, type ToolAccumulator } from \"../shared\"\n\ntype StreamKey = string | number\n\n/**\n * One pending streamed tool call. Providers emit the tool identity and JSON\n * argument text across separate chunks; `input` is the raw JSON string collected\n * so far, not the parsed object.\n */\nexport interface PendingTool extends ToolAccumulator {\n readonly providerExecuted?: boolean\n readonly providerMetadata?: ProviderMetadata\n}\n\n/**\n * Sparse parser state keyed by the provider's stream-local tool identifier.\n *\n * This key is not the final tool-call id (`call_...`). It is the id/index the\n * provider uses while streaming a partial call: OpenAI Chat / Anthropic /\n * Bedrock use numeric content indexes, while OpenAI Responses uses string\n * `item_id`s. The generic keeps each protocol internally consistent.\n */\nexport type State<K extends StreamKey> = Partial<Record<K, PendingTool>>\n\n/**\n * Result of adding argument text to one pending tool call. It returns both the\n * next `tools` state and the updated `tool` because parsers often need the\n * current id/name immediately. `events` contains lifecycle and delta events\n * produced by the append; metadata-only deltas update identity without output.\n */\nexport interface AppendOutcome<K extends StreamKey> {\n readonly tools: State<K>\n readonly tool: PendingTool\n readonly events: ReadonlyArray<LLMEvent>\n}\n\n/** Create empty accumulator state for one provider stream. */\nexport const empty = <K extends StreamKey>(): State<K> => ({})\n\nconst withTool = <K extends StreamKey>(tools: State<K>, key: K, tool: PendingTool): State<K> => {\n return { ...tools, [key]: tool }\n}\n\nconst withoutTool = <K extends StreamKey>(tools: State<K>, key: K): State<K> => {\n const next = { ...tools }\n delete next[key]\n return next\n}\n\nconst inputStart = (tool: PendingTool) =>\n LLMEvent.toolInputStart({\n id: tool.id,\n name: tool.name,\n providerMetadata: tool.providerMetadata,\n })\n\nconst inputDelta = (tool: PendingTool, text: string) =>\n LLMEvent.toolInputDelta({\n id: tool.id,\n name: tool.name,\n text,\n })\n\nconst toolCall = (route: string, tool: PendingTool, inputOverride?: string) =>\n parseToolInput(route, tool.name, inputOverride ?? tool.input).pipe(\n Effect.map(\n (input): ToolCall =>\n LLMEvent.toolCall({\n id: tool.id,\n name: tool.name,\n input,\n providerExecuted: tool.providerExecuted ? true : undefined,\n providerMetadata: tool.providerMetadata,\n }),\n ),\n )\n\n/** Store the updated tool and produce the optional public delta event. */\nconst appendTool = <K extends StreamKey>(\n tools: State<K>,\n key: K,\n tool: PendingTool,\n text: string,\n): AppendOutcome<K> => {\n const events: LLMEvent[] = []\n if (!tools[key]) events.push(inputStart(tool))\n if (text.length > 0) events.push(inputDelta(tool, text))\n return {\n tools: withTool(tools, key, tool),\n tool,\n events,\n }\n}\n\nexport const isError = <K extends StreamKey>(result: AppendOutcome<K> | LLMError): result is LLMError =>\n result instanceof LLMError\n\n/**\n * Register a tool call whose start event arrived before any argument deltas.\n * Used by Anthropic `content_block_start`, Bedrock `contentBlockStart`, and\n * OpenAI Responses `response.output_item.added`.\n */\nexport const start = <K extends StreamKey>(\n tools: State<K>,\n key: K,\n tool: Omit<PendingTool, \"input\"> & { readonly input?: string },\n) => withTool(tools, key, { ...tool, input: tool.input ?? \"\" })\n\n/**\n * Append a streamed argument delta, starting the tool if this provider encodes\n * identity on the first delta instead of a separate start event. OpenAI Chat has\n * this shape: `tool_calls[].index` is the stream key, and `id` / `name` may only\n * appear on the first delta for that index.\n */\nexport const appendOrStart = <K extends StreamKey>(\n route: string,\n tools: State<K>,\n key: K,\n delta: { readonly id?: string; readonly name?: string; readonly text: string },\n missingToolMessage: string,\n): AppendOutcome<K> | LLMError => {\n const current = tools[key]\n const id = delta.id ?? current?.id\n const name = delta.name ?? current?.name\n if (!id || !name) return eventError(route, missingToolMessage)\n\n const tool = {\n id,\n name,\n input: `${current?.input ?? \"\"}${delta.text}`,\n providerExecuted: current?.providerExecuted,\n providerMetadata: current?.providerMetadata,\n }\n if (current && delta.text.length === 0 && current.id === id && current.name === name)\n return { tools, tool: current, events: [] }\n return appendTool(tools, key, tool, delta.text)\n}\n\n/**\n * Append argument text to a tool that must already have been started. This keeps\n * protocols honest when their stream grammar promises a start event before any\n * argument delta.\n */\nexport const appendExisting = <K extends StreamKey>(\n route: string,\n tools: State<K>,\n key: K,\n text: string,\n missingToolMessage: string,\n): AppendOutcome<K> | LLMError => {\n const current = tools[key]\n if (!current) return eventError(route, missingToolMessage)\n if (text.length === 0) return { tools, tool: current, events: [] }\n return appendTool(tools, key, { ...current, input: `${current.input}${text}` }, text)\n}\n\n/**\n * Finalize one pending tool call: parse the accumulated raw JSON, remove it\n * from state, and return the optional public `tool-call` event. Missing keys are\n * a no-op because some providers emit stop events for non-tool content blocks.\n */\nexport const finish = <K extends StreamKey>(route: string, tools: State<K>, key: K) =>\n Effect.gen(function* () {\n const tool = tools[key]\n if (!tool) return { tools }\n return {\n tools: withoutTool(tools, key),\n events: [\n LLMEvent.toolInputEnd({ id: tool.id, name: tool.name, providerMetadata: tool.providerMetadata }),\n yield* toolCall(route, tool),\n ],\n }\n })\n\n/**\n * Finalize one pending tool call with an authoritative final input string.\n * OpenAI Responses can send accumulated deltas and then repeat the completed\n * arguments on `response.output_item.done`; the final value wins.\n */\nexport const finishWithInput = <K extends StreamKey>(route: string, tools: State<K>, key: K, input: string) =>\n Effect.gen(function* () {\n const tool = tools[key]\n if (!tool) return { tools }\n return {\n tools: withoutTool(tools, key),\n events: [\n LLMEvent.toolInputEnd({ id: tool.id, name: tool.name, providerMetadata: tool.providerMetadata }),\n yield* toolCall(route, tool, input),\n ],\n }\n })\n\n/**\n * Finalize every pending tool call at once. OpenAI Chat has this shape: it does\n * not emit per-tool stop events, so all accumulated calls finish when the choice\n * receives a terminal `finish_reason`.\n */\nexport const finishAll = <K extends StreamKey>(route: string, tools: State<K>) =>\n Effect.gen(function* () {\n const pending = Object.values<PendingTool | undefined>(tools).filter(\n (tool): tool is PendingTool => tool !== undefined,\n )\n return {\n tools: empty<K>(),\n events: yield* Effect.forEach(pending, (tool) =>\n toolCall(route, tool).pipe(\n Effect.map((call) => [\n LLMEvent.toolInputEnd({ id: tool.id, name: tool.name, providerMetadata: tool.providerMetadata }),\n call,\n ]),\n ),\n ).pipe(Effect.map((events) => events.flat())),\n }\n })\n\nexport * as ToolStream from \"./tool-stream\"\n", | ||
| "import { Effect, Schema } from \"effect\"\nimport { Route } from \"../route/client\"\nimport { Auth } from \"../route/auth\"\nimport { Endpoint } from \"../route/endpoint\"\nimport { HttpTransport } from \"../route/transport\"\nimport { Protocol } from \"../route/protocol\"\nimport {\n LLMEvent,\n Usage,\n type FinishReason,\n type JsonSchema,\n type LLMRequest,\n type MediaPart,\n type ReasoningPart,\n type TextPart,\n type ToolCallPart,\n type ToolDefinition,\n type ToolContent,\n} from \"../schema\"\nimport { isRecord, JsonObject, optionalArray, optionalNull, ProviderShared } from \"./shared\"\nimport { OpenAIOptions } from \"./utils/openai-options\"\nimport { Lifecycle } from \"./utils/lifecycle\"\nimport { ToolSchemaProjection } from \"./utils/tool-schema\"\nimport { ToolStream } from \"./utils/tool-stream\"\n\nconst ADAPTER = \"openai-chat\"\nconst IMAGE_MIMES = new Set<string>(ProviderShared.IMAGE_MIMES)\nexport const DEFAULT_BASE_URL = \"https://api.openai.com/v1\"\nexport const PATH = \"/chat/completions\"\n\n// =============================================================================\n// Request Body Schema\n// =============================================================================\n// The body schema is the provider-native JSON body. `fromRequest` below builds\n// this shape from the common `LLMRequest`, then `Route.make` validates and\n// JSON-encodes it before transport.\nconst OpenAIChatFunction = Schema.Struct({\n name: Schema.String,\n description: Schema.String,\n parameters: JsonObject,\n})\n\nconst OpenAIChatTool = Schema.Struct({\n type: Schema.tag(\"function\"),\n function: OpenAIChatFunction,\n})\ntype OpenAIChatTool = Schema.Schema.Type<typeof OpenAIChatTool>\n\nconst OpenAIChatAssistantToolCall = Schema.Struct({\n id: Schema.String,\n type: Schema.tag(\"function\"),\n function: Schema.Struct({\n name: Schema.String,\n arguments: Schema.String,\n }),\n})\ntype OpenAIChatAssistantToolCall = Schema.Schema.Type<typeof OpenAIChatAssistantToolCall>\n\nconst OpenAIChatUserContent = Schema.Union([\n Schema.Struct({ type: Schema.Literal(\"text\"), text: Schema.String }),\n Schema.Struct({\n type: Schema.Literal(\"image_url\"),\n image_url: Schema.Struct({ url: Schema.String }),\n }),\n])\n\nconst OpenAIChatMessage = Schema.Union([\n Schema.Struct({ role: Schema.Literal(\"system\"), content: Schema.String }),\n Schema.Struct({\n role: Schema.Literal(\"user\"),\n content: Schema.Union([Schema.String, Schema.Array(OpenAIChatUserContent)]),\n }),\n Schema.Struct({\n role: Schema.Literal(\"assistant\"),\n content: Schema.NullOr(Schema.String),\n tool_calls: optionalArray(OpenAIChatAssistantToolCall),\n reasoning_content: Schema.optional(Schema.String),\n }),\n Schema.Struct({ role: Schema.Literal(\"tool\"), tool_call_id: Schema.String, content: Schema.String }),\n]).pipe(Schema.toTaggedUnion(\"role\"))\ntype OpenAIChatMessage = Schema.Schema.Type<typeof OpenAIChatMessage>\n\nconst OpenAIChatToolChoice = Schema.Union([\n Schema.Literals([\"auto\", \"none\", \"required\"]),\n Schema.Struct({\n type: Schema.tag(\"function\"),\n function: Schema.Struct({ name: Schema.String }),\n }),\n])\n\nexport const bodyFields = {\n model: Schema.String,\n messages: Schema.Array(OpenAIChatMessage),\n tools: optionalArray(OpenAIChatTool),\n tool_choice: Schema.optional(OpenAIChatToolChoice),\n stream: Schema.Literal(true),\n stream_options: Schema.optional(Schema.Struct({ include_usage: Schema.Boolean })),\n store: Schema.optional(Schema.Boolean),\n reasoning_effort: Schema.optional(OpenAIOptions.OpenAIReasoningEffort),\n max_tokens: Schema.optional(Schema.Number),\n temperature: Schema.optional(Schema.Number),\n top_p: Schema.optional(Schema.Number),\n frequency_penalty: Schema.optional(Schema.Number),\n presence_penalty: Schema.optional(Schema.Number),\n seed: Schema.optional(Schema.Number),\n stop: optionalArray(Schema.String),\n}\nconst OpenAIChatBody = Schema.Struct(bodyFields)\nexport type OpenAIChatBody = Schema.Schema.Type<typeof OpenAIChatBody>\n\n// =============================================================================\n// Streaming Event Schema\n// =============================================================================\n// The event schema is one decoded SSE `data:` payload. `Framing.sse` splits the\n// byte stream into strings, then `Protocol.jsonEvent` decodes each string into\n// this provider-native event shape.\nconst OpenAIChatUsage = Schema.Struct({\n prompt_tokens: Schema.optional(Schema.Number),\n completion_tokens: Schema.optional(Schema.Number),\n total_tokens: Schema.optional(Schema.Number),\n prompt_tokens_details: optionalNull(\n Schema.Struct({\n cached_tokens: Schema.optional(Schema.Number),\n }),\n ),\n completion_tokens_details: optionalNull(\n Schema.Struct({\n reasoning_tokens: Schema.optional(Schema.Number),\n }),\n ),\n})\n\nconst OpenAIChatToolCallDeltaFunction = Schema.Struct({\n name: optionalNull(Schema.String),\n arguments: optionalNull(Schema.String),\n})\n\nconst OpenAIChatToolCallDelta = Schema.Struct({\n index: Schema.Number,\n id: optionalNull(Schema.String),\n function: optionalNull(OpenAIChatToolCallDeltaFunction),\n})\ntype OpenAIChatToolCallDelta = Schema.Schema.Type<typeof OpenAIChatToolCallDelta>\n\nconst OpenAIChatDelta = Schema.Struct({\n content: optionalNull(Schema.String),\n reasoning_content: optionalNull(Schema.String),\n tool_calls: optionalNull(Schema.Array(OpenAIChatToolCallDelta)),\n})\n\nconst OpenAIChatChoice = Schema.Struct({\n delta: optionalNull(OpenAIChatDelta),\n finish_reason: optionalNull(Schema.String),\n})\n\nexport const OpenAIChatEvent = Schema.Struct({\n choices: Schema.Array(OpenAIChatChoice),\n usage: optionalNull(OpenAIChatUsage),\n})\nexport type OpenAIChatEvent = Schema.Schema.Type<typeof OpenAIChatEvent>\ntype OpenAIChatRequestMessage = LLMRequest[\"messages\"][number]\n\ninterface ParserState {\n readonly tools: ToolStream.State<number>\n readonly toolCallEvents: ReadonlyArray<LLMEvent>\n readonly usage?: Usage\n readonly finishReason?: FinishReason\n readonly lifecycle: Lifecycle.State\n}\n\n// =============================================================================\n// Request Lowering\n// =============================================================================\n// Lowering is the only place that knows how common LLM messages map onto the\n// OpenAI Chat wire format. Keep provider quirks here instead of leaking native\n// fields into `LLMRequest`.\nconst lowerTool = (tool: ToolDefinition, inputSchema: JsonSchema): OpenAIChatTool => ({\n type: \"function\",\n function: {\n name: tool.name,\n description: tool.description,\n parameters: ToolSchemaProjection.openAI(inputSchema),\n },\n})\n\nconst lowerToolChoice = (toolChoice: NonNullable<LLMRequest[\"toolChoice\"]>) =>\n ProviderShared.matchToolChoice(\"OpenAI Chat\", toolChoice, {\n auto: () => \"auto\" as const,\n none: () => \"none\" as const,\n required: () => \"required\" as const,\n tool: (name) => ({ type: \"function\" as const, function: { name } }),\n })\n\nconst lowerToolCall = (part: ToolCallPart): OpenAIChatAssistantToolCall => ({\n id: part.id,\n type: \"function\",\n function: {\n name: part.name,\n arguments: ProviderShared.encodeJson(part.input),\n },\n})\n\nconst lowerMedia = Effect.fn(\"OpenAIChat.lowerMedia\")(function* (part: MediaPart) {\n const media = yield* ProviderShared.validateMedia(\"OpenAI Chat\", part, IMAGE_MIMES)\n return { type: \"image_url\" as const, image_url: { url: media.dataUrl } }\n})\n\nconst openAICompatibleReasoningContent = (native: unknown) =>\n isRecord(native) && typeof native.reasoning_content === \"string\" ? native.reasoning_content : undefined\n\nconst lowerUserMessage = Effect.fn(\"OpenAIChat.lowerUserMessage\")(function* (message: OpenAIChatRequestMessage) {\n const content: Array<Schema.Schema.Type<typeof OpenAIChatUserContent>> = []\n for (const part of message.content) {\n if (part.type === \"text\") {\n content.push({ type: \"text\", text: part.text })\n continue\n }\n if (part.type === \"media\") {\n content.push(yield* lowerMedia(part))\n continue\n }\n return yield* ProviderShared.unsupportedContent(\"OpenAI Chat\", \"user\", [\"text\", \"media\"])\n }\n if (content.every((part) => part.type === \"text\"))\n return { role: \"user\" as const, content: content.map((part) => part.text).join(\"\") }\n return { role: \"user\" as const, content }\n})\n\nconst lowerAssistantMessage = Effect.fn(\"OpenAIChat.lowerAssistantMessage\")(function* (\n message: OpenAIChatRequestMessage,\n) {\n const content: TextPart[] = []\n const reasoning: ReasoningPart[] = []\n const toolCalls: OpenAIChatAssistantToolCall[] = []\n for (const part of message.content) {\n if (!ProviderShared.supportsContent(part, [\"text\", \"reasoning\", \"tool-call\"]))\n return yield* ProviderShared.unsupportedContent(\"OpenAI Chat\", \"assistant\", [\"text\", \"reasoning\", \"tool-call\"])\n if (part.type === \"text\") {\n content.push(part)\n continue\n }\n if (part.type === \"reasoning\") {\n reasoning.push(part)\n continue\n }\n if (part.type === \"tool-call\") {\n toolCalls.push(lowerToolCall(part))\n continue\n }\n }\n return {\n role: \"assistant\" as const,\n content: content.length === 0 ? null : ProviderShared.joinText(content),\n tool_calls: toolCalls.length === 0 ? undefined : toolCalls,\n reasoning_content:\n reasoning.length > 0\n ? reasoning.map((part) => part.text).join(\"\")\n : openAICompatibleReasoningContent(message.native?.openaiCompatible),\n }\n})\n\nconst lowerToolMessages = Effect.fn(\"OpenAIChat.lowerToolMessages\")(function* (message: OpenAIChatRequestMessage) {\n const messages: OpenAIChatMessage[] = []\n const images: Array<Schema.Schema.Type<typeof OpenAIChatUserContent>> = []\n for (const part of message.content) {\n if (!ProviderShared.supportsContent(part, [\"tool-result\"]))\n return yield* ProviderShared.unsupportedContent(\"OpenAI Chat\", \"tool\", [\"tool-result\"])\n if (part.result.type !== \"content\") {\n messages.push({ role: \"tool\", tool_call_id: part.id, content: ProviderShared.toolResultText(part) })\n continue\n }\n const content: ReadonlyArray<ToolContent> = part.result.value\n const text = content.filter((item) => item.type === \"text\").map((item) => item.text)\n messages.push({ role: \"tool\", tool_call_id: part.id, content: text.join(\"\\n\") })\n const files = content.filter((item) => item.type === \"file\")\n images.push(\n ...(yield* Effect.forEach(files, (item) =>\n lowerMedia({ type: \"media\", mediaType: item.mime, data: item.uri, filename: item.name }),\n )),\n )\n }\n return { messages, images }\n})\n\nconst lowerMessage = Effect.fn(\"OpenAIChat.lowerMessage\")(function* (message: OpenAIChatRequestMessage) {\n if (message.role === \"user\") return [yield* lowerUserMessage(message)]\n if (message.role === \"assistant\") return [yield* lowerAssistantMessage(message)]\n return (yield* lowerToolMessages(message)).messages\n})\n\nconst lowerMessages = Effect.fn(\"OpenAIChat.lowerMessages\")(function* (request: LLMRequest) {\n const system: OpenAIChatMessage[] =\n request.system.length === 0 ? [] : [{ role: \"system\", content: ProviderShared.joinText(request.system) }]\n const messages = [...system]\n const pendingImages: Array<Schema.Schema.Type<typeof OpenAIChatUserContent>> = []\n const flushImages = () => {\n if (pendingImages.length === 0) return\n messages.push({ role: \"user\", content: pendingImages.splice(0) })\n }\n for (const message of request.messages) {\n if (message.role === \"system\") {\n const part = yield* ProviderShared.wrappedSystemUpdate(\"OpenAI Chat\", message)\n if (pendingImages.length > 0) {\n messages.push({ role: \"user\", content: [...pendingImages.splice(0), { type: \"text\", text: part.text }] })\n continue\n }\n const previous = messages.at(-1)\n if (previous?.role === \"user\" && typeof previous.content === \"string\")\n messages[messages.length - 1] = { role: \"user\", content: `${previous.content}\\n${part.text}` }\n else if (previous?.role === \"user\" && Array.isArray(previous.content))\n messages[messages.length - 1] = {\n role: \"user\",\n content: [...previous.content, { type: \"text\", text: part.text }],\n }\n else messages.push({ role: \"user\", content: part.text })\n continue\n }\n if (message.role === \"tool\") {\n const lowered = yield* lowerToolMessages(message)\n messages.push(...lowered.messages)\n pendingImages.push(...lowered.images)\n continue\n }\n flushImages()\n messages.push(...(yield* lowerMessage(message)))\n }\n flushImages()\n return messages\n})\n\nconst lowerOptions = Effect.fn(\"OpenAIChat.lowerOptions\")(function* (request: LLMRequest) {\n const store = OpenAIOptions.store(request)\n const reasoningEffort = OpenAIOptions.reasoningEffort(request)\n return {\n ...(store !== undefined ? { store } : {}),\n ...(reasoningEffort ? { reasoning_effort: reasoningEffort } : {}),\n }\n})\n\nconst fromRequest = Effect.fn(\"OpenAIChat.fromRequest\")(function* (request: LLMRequest) {\n // `fromRequest` returns the provider body only. Endpoint, auth, framing,\n // validation, and HTTP execution are composed by `Route.make`.\n const generation = request.generation\n const toolSchemaCompatibility = request.model.compatibility?.toolSchema\n return {\n model: request.model.id,\n messages: yield* lowerMessages(request),\n tools:\n request.tools.length === 0\n ? undefined\n : request.tools.map((tool) =>\n lowerTool(tool, ToolSchemaProjection.modelCompatibility(tool.inputSchema, toolSchemaCompatibility)),\n ),\n tool_choice: request.toolChoice ? yield* lowerToolChoice(request.toolChoice) : undefined,\n stream: true as const,\n stream_options: { include_usage: true },\n max_tokens: generation?.maxTokens,\n temperature: generation?.temperature,\n top_p: generation?.topP,\n frequency_penalty: generation?.frequencyPenalty,\n presence_penalty: generation?.presencePenalty,\n seed: generation?.seed,\n stop: generation?.stop,\n ...(yield* lowerOptions(request)),\n }\n})\n\n// =============================================================================\n// Stream Parsing\n// =============================================================================\n// Streaming parsers are small state machines: every event returns a new state\n// plus the common `LLMEvent`s produced by that event. Tool calls are accumulated\n// because OpenAI streams JSON arguments across multiple deltas.\nconst mapFinishReason = (reason: string | null | undefined): FinishReason => {\n if (reason === \"stop\") return \"stop\"\n if (reason === \"length\") return \"length\"\n if (reason === \"content_filter\") return \"content-filter\"\n if (reason === \"function_call\" || reason === \"tool_calls\") return \"tool-calls\"\n return \"unknown\"\n}\n\n// OpenAI Chat reports `prompt_tokens` (inclusive total) with a\n// `cached_tokens` subset, and `completion_tokens` (inclusive total) with\n// a `reasoning_tokens` subset. We pass the inclusive totals through and\n// derive the non-cached breakdown so the `LLM.Usage` contract is\n// satisfied on both sides.\nconst mapUsage = (usage: OpenAIChatEvent[\"usage\"]): Usage | undefined => {\n if (!usage) return undefined\n const cached = usage.prompt_tokens_details?.cached_tokens\n const reasoning = usage.completion_tokens_details?.reasoning_tokens\n const nonCached = ProviderShared.subtractTokens(usage.prompt_tokens, cached)\n return new Usage({\n inputTokens: usage.prompt_tokens,\n outputTokens: usage.completion_tokens,\n nonCachedInputTokens: nonCached,\n cacheReadInputTokens: cached,\n reasoningTokens: reasoning,\n totalTokens: ProviderShared.totalTokens(usage.prompt_tokens, usage.completion_tokens, usage.total_tokens),\n providerMetadata: { openai: usage },\n })\n}\n\nconst step = (state: ParserState, event: OpenAIChatEvent) =>\n Effect.gen(function* () {\n const events: LLMEvent[] = []\n const usage = mapUsage(event.usage) ?? state.usage\n const choice = event.choices[0]\n const finishReason = choice?.finish_reason ? mapFinishReason(choice.finish_reason) : state.finishReason\n const delta = choice?.delta\n const toolDeltas = delta?.tool_calls ?? []\n let tools = state.tools\n\n let lifecycle = state.lifecycle\n\n if (delta?.reasoning_content)\n lifecycle = Lifecycle.reasoningDelta(lifecycle, events, \"reasoning-0\", delta.reasoning_content)\n\n if (delta?.content) {\n lifecycle = Lifecycle.reasoningEnd(lifecycle, events, \"reasoning-0\")\n lifecycle = Lifecycle.textDelta(lifecycle, events, \"text-0\", delta.content)\n }\n\n if (toolDeltas.length) lifecycle = Lifecycle.reasoningEnd(lifecycle, events, \"reasoning-0\")\n\n for (const tool of toolDeltas) {\n const result = ToolStream.appendOrStart(\n ADAPTER,\n tools,\n tool.index,\n { id: tool.id ?? undefined, name: tool.function?.name ?? undefined, text: tool.function?.arguments ?? \"\" },\n \"OpenAI Chat tool call delta is missing id or name\",\n )\n if (ToolStream.isError(result)) return yield* result\n tools = result.tools\n if (result.events.length) lifecycle = Lifecycle.stepStart(lifecycle, events)\n events.push(...result.events)\n }\n\n // Finalize accumulated tool inputs eagerly when finish_reason arrives so\n // JSON parse failures fail the stream at the boundary rather than at halt.\n const finished =\n finishReason !== undefined && state.finishReason === undefined && Object.keys(tools).length > 0\n ? yield* ToolStream.finishAll(ADAPTER, tools)\n : undefined\n\n return [\n {\n tools: finished?.tools ?? tools,\n toolCallEvents: finished?.events ?? state.toolCallEvents,\n usage,\n finishReason,\n lifecycle,\n },\n events,\n ] as const\n })\n\nconst finishEvents = (state: ParserState): ReadonlyArray<LLMEvent> => {\n const events: LLMEvent[] = []\n const hasToolCalls = state.toolCallEvents.length > 0\n const reason = state.finishReason === \"stop\" && hasToolCalls ? \"tool-calls\" : state.finishReason\n const lifecycle = state.toolCallEvents.length ? Lifecycle.stepStart(state.lifecycle, events) : state.lifecycle\n events.push(...state.toolCallEvents)\n if (reason) Lifecycle.finish(lifecycle, events, { reason, usage: state.usage })\n return events\n}\n\n// =============================================================================\n// Protocol And OpenAI Route\n// =============================================================================\n/**\n * The OpenAI Chat protocol — request body construction, body schema, and the\n * streaming-event state machine. Reused by every route that speaks OpenAI Chat\n * over HTTP+SSE: native OpenAI, DeepSeek, TogetherAI, Cerebras, Baseten,\n * Fireworks, DeepInfra, and (once added) Azure OpenAI Chat.\n */\nexport const protocol = Protocol.make({\n id: ADAPTER,\n body: {\n schema: OpenAIChatBody,\n from: fromRequest,\n },\n stream: {\n event: Protocol.jsonEvent(OpenAIChatEvent),\n initial: () => ({ tools: ToolStream.empty<number>(), toolCallEvents: [], lifecycle: Lifecycle.initial() }),\n step,\n onHalt: finishEvents,\n },\n})\n\nexport const httpTransport = HttpTransport.sseJson.with<OpenAIChatBody>()\n\nexport const route = Route.make({\n id: ADAPTER,\n provider: \"openai\",\n providerMetadataKey: \"openai\",\n protocol,\n endpoint: Endpoint.path(PATH, { baseURL: DEFAULT_BASE_URL }),\n auth: Auth.none,\n transport: httpTransport,\n})\n\nexport * as OpenAIChat from \"./openai-chat\"\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "FB1D999DCAC2B76264756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/service/unset.ts"], | ||
| "sourcesContent": [ | ||
| "import { Effect } from \"effect\"\nimport { Commands } from \"../../commands\"\nimport { Runtime } from \"../../../framework/runtime\"\nimport { ServiceConfig } from \"../../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.service.commands.unset,\n Effect.fn(\"cli.service.unset\")(function* (input) {\n yield* ServiceConfig.unset(input.key)\n }),\n)\n" | ||
| ], | ||
| "mappings": ";k0BAKA,SAAe,SAAQ,aACrB,OAAS,cAAS,aAAQ,cAAS,WACnC,OAAO,QAAG,wBAAmB,OAAE,cAAU,MAAC,OAAO,MAC/C,WAAO,OAAc,WAAM,OAAM,QAAG,OACrC,CACH", | ||
| "debugId": "32D692CA46C9E83964756E2164756E21", | ||
| "names": [] | ||
| } |
| { | ||
| "version": 3, | ||
| "sources": ["src/commands/handlers/pair.ts"], | ||
| "sourcesContent": [ | ||
| "import { EOL } from \"os\"\nimport { Effect } from \"effect\"\nimport { Service } from \"@opencode-ai/client/effect/service\"\nimport { OpenCode } from \"@opencode-ai/client/promise\"\nimport { renderUnicodeCompact } from \"uqr\"\nimport { Commands } from \"../commands\"\nimport { Runtime } from \"../../framework/runtime\"\nimport { ServiceConfig } from \"../../services/service-config\"\n\nexport default Runtime.handler(\n Commands.commands.pair,\n Effect.fn(\"cli.pair\")(function* () {\n const endpoint = yield* Service.ensure(yield* ServiceConfig.options())\n const password = yield* ServiceConfig.password()\n const server = yield* Effect.tryPromise(() =>\n OpenCode.make({ baseUrl: endpoint.url, headers: Service.headers(endpoint) }).server.get(),\n )\n const info = { urls: server.urls, username: \"opencode\", password }\n process.stdout.write(\n [\n \"\",\n ` URLs ${info.urls[0] ?? \"(none)\"}`,\n ...info.urls.slice(1).map((url) => ` ${url}`),\n ` Username ${info.username}`,\n ` Password ${info.password}`,\n \"\",\n \" Scan to pair\",\n \"\",\n renderUnicodeCompact(JSON.stringify(info), { border: 2 })\n .split(EOL)\n .map((line) => \" \" + line)\n .join(EOL),\n \"\",\n ].join(EOL) + EOL,\n )\n\n const hostname = new URL(endpoint.url).hostname\n if (![\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(hostname)) return\n process.stderr.write(\n ` Run \\`opencode service set hostname 0.0.0.0\\` to access the service remotely.${EOL}${EOL}`,\n )\n }),\n)\n" | ||
| ], | ||
| "mappings": ";46BAAA,mBAAS,gBAST,SAAe,SAAQ,aACrB,OAAS,cAAS,UAClB,OAAO,QAAG,eAAU,OAAE,cAAU,OAAG,MACjC,SAAM,OAAW,WAAO,OAAQ,YAAO,WAAO,OAAc,aAAQ,MAAC,EAC/D,EAAW,MAAO,EAAc,SAAS,EAIzC,EAAO,CAAE,MAHA,MAAO,EAAO,WAAW,IACtC,EAAS,KAAK,CAAE,QAAS,EAAS,IAAK,QAAS,EAAQ,QAAQ,CAAQ,CAAE,CAAC,EAAE,OAAO,IAAI,CAC1F,GAC4B,KAAM,SAAU,WAAY,UAAS,EACjE,QAAQ,OAAO,MACb,CACE,GACA,eAAe,EAAK,KAAK,IAAM,WAC/B,GAAG,EAAK,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,IAAQ,eAAe,GAAK,EACvD,eAAe,EAAK,WACpB,eAAe,EAAK,WACpB,GACA,iBACA,GACA,EAAqB,KAAK,UAAU,CAAI,EAAG,CAAE,OAAQ,CAAE,CAAC,EACrD,MAAM,CAAG,EACT,IAAI,CAAC,IAAS,KAAO,CAAI,EACzB,KAAK,CAAG,EACX,EACF,EAAE,KAAK,CAAG,EAAI,CAChB,EAEA,IAAM,EAAW,IAAI,IAAI,EAAS,GAAG,EAAE,SACvC,GAAI,CAAC,CAAC,YAAa,YAAa,OAAO,EAAE,SAAS,CAAQ,EAAG,OAC7D,QAAQ,OAAO,MACb,kFAAkF,IAAM,GAC1F,EACD,CACH", | ||
| "debugId": "9E845DD8991BA77364756E2164756E21", | ||
| "names": [] | ||
| } |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
257001883
0