@codeworksh/cli 0.5.0-canary.88.1.g2a3bcb6e → 0.5.0-canary.90.1.gec09b058
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{acp-BZmK36Ci.mjs → acp-BeDi6jEL.mjs} +2 -2
- package/{acp-BZmK36Ci.mjs.map → acp-BeDi6jEL.mjs.map} +1 -1
- package/{identity-CJLpWsM7.mjs → identity-CQBhON8m.mjs} +2 -2
- package/{identity-CJLpWsM7.mjs.map → identity-CQBhON8m.mjs.map} +1 -1
- package/index.mjs +8 -8
- package/package-C0VOpey-.mjs +6 -0
- package/package-C0VOpey-.mjs.map +1 -0
- package/package.json +4 -4
- package/{restart-Chw99bo9.mjs → restart-YOXYSZ_i.mjs} +2 -2
- package/{restart-Chw99bo9.mjs.map → restart-YOXYSZ_i.mjs.map} +1 -1
- package/{serve-C_RqXAJO.mjs → serve-Ce8hdWM6.mjs} +2 -2
- package/{serve-C_RqXAJO.mjs.map → serve-Ce8hdWM6.mjs.map} +1 -1
- package/{service-Bka-Vghv.mjs → service-BQdaO_Ap.mjs} +2 -2
- package/{service-Bka-Vghv.mjs.map → service-BQdaO_Ap.mjs.map} +1 -1
- package/{start-145_LsQ-.mjs → start-hJJLd1ap.mjs} +2 -2
- package/{start-145_LsQ-.mjs.map → start-hJJLd1ap.mjs.map} +1 -1
- package/{status-C9AqfRiL.mjs → status-Bp8vjjW9.mjs} +2 -2
- package/{status-C9AqfRiL.mjs.map → status-Bp8vjjW9.mjs.map} +1 -1
- package/{stop-BtUFqcoN.mjs → stop-C2PWKdVX.mjs} +2 -2
- package/{stop-BtUFqcoN.mjs.map → stop-C2PWKdVX.mjs.map} +1 -1
- package/{tui-OhQviPBX.mjs → tui-CGVqTA8q.mjs} +3 -3
- package/{tui-OhQviPBX.mjs.map → tui-CGVqTA8q.mjs.map} +1 -1
- package/package-SPg0ayR-.mjs +0 -6
- package/package-SPg0ayR-.mjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as version } from "./package-
|
|
1
|
+
import { t as version } from "./package-C0VOpey-.mjs";
|
|
2
2
|
import { i as Cmd, t as handler } from "./runtime-CwoLsQy7.mjs";
|
|
3
3
|
import { i as reportFailure } from "./error-BVSfzBzb.mjs";
|
|
4
4
|
import { t as harnessOptions } from "./harness-6d8TlAVk.mjs";
|
|
@@ -541,4 +541,4 @@ var acp_default = handler(Cmd.commands.acp, Effect.fn("CLI.acp", { level: "Info"
|
|
|
541
541
|
//#endregion
|
|
542
542
|
export { acp_default as default };
|
|
543
543
|
|
|
544
|
-
//# sourceMappingURL=acp-
|
|
544
|
+
//# sourceMappingURL=acp-BeDi6jEL.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acp-BZmK36Ci.mjs","names":["serve","Agent.RequestError","pkg.version","Config.options","Feed.replay","Config.parseModel","Config.known","Config.isThinkingLevel","update","Feed.update","notice","Feed.notice","Feed.noticeUpdate","Handlers.make","Agent.serve","Runtime.handler","Server.serve"],"sources":["../../src/acp/agent.ts","../../src/acp/config.ts","../../src/acp/feed.ts","../../src/acp/handlers.ts","../../src/acp/server.ts","../../src/cli/cmd/handlers/acp.ts"],"sourcesContent":["import * as Acp from \"@agentclientprotocol/sdk\";\nimport { Cause, Deferred, Effect, Exit, Option, Schema, type Scope, type Stdio, Stream } from \"effect\";\n\n/** A JSON-RPC error a handler answers a request with. */\nexport class RequestError extends Schema.TaggedError<RequestError>()(\"AcpRequestError\", {\n\tcode: Schema.Int,\n\tmessage: Schema.String,\n}) {\n\tstatic invalidRequest = (message: string) => new RequestError({ code: -32600, message });\n\tstatic invalidParams = (message: string) => new RequestError({ code: -32602, message });\n\tstatic internalError = (message: string) => new RequestError({ code: -32603, message });\n\tstatic resourceNotFound = (message: string) => new RequestError({ code: -32002, message });\n}\n\ntype Handler<Request, Response> = (request: Request) => Effect.Effect<Response, RequestError>;\n\n/** Calls the agent makes to the connected client. */\nexport interface Client {\n\treadonly sessionUpdate: (notification: Acp.SessionNotification) => Effect.Effect<void, RequestError>;\n}\n\nexport interface Handlers {\n\treadonly initialize: Handler<Acp.InitializeRequest, Acp.InitializeResponse>;\n\treadonly newSession: Handler<Acp.NewSessionRequest, Acp.NewSessionResponse>;\n\t/** Must replay the session's history through `Client.sessionUpdate` before it returns. */\n\treadonly loadSession: Handler<Acp.LoadSessionRequest, Acp.LoadSessionResponse>;\n\treadonly listSessions: Handler<Acp.ListSessionsRequest, Acp.ListSessionsResponse>;\n\treadonly forkSession: Handler<Acp.ForkSessionRequest, Acp.ForkSessionResponse>;\n\treadonly setConfigOption: Handler<Acp.SetSessionConfigOptionRequest, Acp.SetSessionConfigOptionResponse>;\n\treadonly prompt: Handler<Acp.PromptRequest, Acp.PromptResponse>;\n\treadonly cancel: (notification: Acp.CancelNotification) => Effect.Effect<void>;\n}\n\n/**\n * Serves an ACP agent over `stdio` until the client closes its end.\n *\n * Handlers run as fibers on this effect's services; a request the client cancels, or the\n * connection closing, interrupts its fiber.\n */\nexport const serve = Effect.fn(\"ACP.serve\")(function* (\n\tstdio: Stdio.Stdio,\n\tmakeHandlers: (client: Client) => Handlers,\n): Effect.fn.Return<void, never, Scope.Scope> {\n\tconst context = yield* Effect.context<never>();\n\tconst runExit = Effect.runPromiseExitWith(context);\n\tconst opened = yield* Deferred.make<Acp.AgentConnection>();\n\n\tconst handlers = makeHandlers({\n\t\tsessionUpdate: (notification) =>\n\t\t\tDeferred.await(opened).pipe(\n\t\t\t\tEffect.flatMap((connection) =>\n\t\t\t\t\tEffect.tryPromise({\n\t\t\t\t\t\ttry: () => connection.client.notify(Acp.methods.client.session.update, notification),\n\t\t\t\t\t\tcatch: (error) => RequestError.internalError(`Failed to send session/update: ${String(error)}`),\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t),\n\t});\n\n\t// A JSON-RPC answer for a handler that didn't succeed; the SDK sends what `handle` throws.\n\tconst toWire = (cause: Cause.Cause<RequestError>): Acp.RequestError => {\n\t\tconst error = Cause.findErrorOption(cause);\n\t\tif (Option.isSome(error)) return new Acp.RequestError(error.value.code, error.value.message);\n\t\tif (Cause.hasInterruptsOnly(cause)) return Acp.RequestError.requestCancelled();\n\t\treturn Acp.RequestError.internalError(undefined, String(Cause.squash(cause)));\n\t};\n\tconst handle =\n\t\t<Params, A>(handler: (params: Params) => Effect.Effect<A, RequestError>) =>\n\t\t({ params, signal }: { readonly params: Params; readonly signal: AbortSignal }): Promise<A> =>\n\t\t\trunExit(handler(params), { signal }).then((exit) => {\n\t\t\t\tif (Exit.isSuccess(exit)) return exit.value;\n\t\t\t\tthrow toWire(exit.cause);\n\t\t\t});\n\n\tconst input = yield* Stream.toReadableStreamEffect(stdio.stdin);\n\tconst output = new WritableStream<Uint8Array>({\n\t\twrite: (chunk) => Effect.runPromiseWith(context)(Stream.run(Stream.make(chunk), stdio.stdout())),\n\t});\n\n\tconst connection = Acp.agent({ name: \"codework\" })\n\t\t.onRequest(\"initialize\", handle(handlers.initialize))\n\t\t.onRequest(\"session/new\", handle(handlers.newSession))\n\t\t.onRequest(\"session/load\", handle(handlers.loadSession))\n\t\t.onRequest(\"session/list\", handle(handlers.listSessions))\n\t\t.onRequest(\"session/fork\", handle(handlers.forkSession))\n\t\t.onRequest(\"session/set_config_option\", handle(handlers.setConfigOption))\n\t\t.onRequest(\"session/prompt\", handle(handlers.prompt))\n\t\t.onNotification(\"session/cancel\", handle(handlers.cancel))\n\t\t.connect(Acp.ndJsonStream(output, input));\n\tyield* Deferred.succeed(opened, connection);\n\tyield* Effect.addFinalizer(() => Effect.sync(() => connection.close()));\n\tyield* Effect.promise(() => connection.closed);\n});\n\nexport * as Agent from \"./agent.ts\";\n","import type * as Acp from \"@agentclientprotocol/sdk\";\nimport { Model } from \"@codeworksh/aikit\";\nimport { ModelCatalog, Settings, type State } from \"@codeworksh/harness/effect\";\nimport { Effect, Option } from \"effect\";\n\nexport const MODEL = \"model\";\nexport const THOUGHT_LEVEL = \"thought_level\";\n\nconst thinkingLabels: Record<Model.ThinkingLevel, string> = {\n\toff: \"Off\",\n\tminimal: \"Minimal\",\n\tlow: \"Low\",\n\tmedium: \"Medium\",\n\thigh: \"High\",\n\txhigh: \"Extra High\",\n\tmax: \"Max\",\n};\n\nexport const isThinkingLevel = (value: string): value is Model.ThinkingLevel => Object.hasOwn(thinkingLabels, value);\n\n/** Splits a `provider/model` option value on its first slash; model ids may contain more. */\nexport const parseModel = (value: string): Option.Option<{ readonly provider: string; readonly id: string }> => {\n\tconst slash = value.indexOf(\"/\");\n\tif (slash <= 0 || slash === value.length - 1) return Option.none();\n\treturn Option.some({ provider: value.slice(0, slash), id: value.slice(slash + 1) });\n};\n\n/** The catalog a session in `hostDir` sees: generated entries plus its settings' `models`. */\nconst catalogFor = (hostDir: string | undefined) =>\n\tEffect.gen(function* () {\n\t\tconst settings = yield* Settings.Service;\n\t\treturn yield* ModelCatalog.effective((yield* settings.load(hostDir)).models);\n\t}).pipe(Effect.orElseSucceed((): Model.BuiltInModels => ({})));\n\n/** The `model` and `thought_level` selectors for a session's current configuration. */\nexport const options = Effect.fn(\"ACP.config.options\")(function* (\n\tselection: State.Configuration,\n\thostDir: string | undefined,\n) {\n\tconst catalog = yield* catalogFor(hostDir);\n\t// Providers the harness has credentials for; the current model stays selectable even if not.\n\tconst providers = yield* ModelCatalog.available(hostDir === undefined ? {} : { hostDir }).pipe(\n\t\tEffect.orElseSucceed(() => []),\n\t);\n\n\tconst current = `${selection.provider}/${selection.model}`;\n\tconst models = providers.flatMap((provider) =>\n\t\tObject.entries(provider.models).map(([id, info]) => ({\n\t\t\tvalue: `${provider.id}/${id}`,\n\t\t\tname: `${info.provider.name}: ${info.name}`,\n\t\t})),\n\t);\n\tif (!models.some((option) => option.value === current)) models.unshift({ value: current, name: current });\n\n\tconst result: Array<Acp.SessionConfigOption> = [\n\t\t{ id: MODEL, name: \"Model\", category: \"model\", type: \"select\", currentValue: current, options: models },\n\t];\n\n\tconst info = catalog[selection.provider]?.[selection.model];\n\tconst levels = info === undefined ? [] : Model.getSupportedThinkingLevels(info);\n\tif (levels.some((level) => level !== \"off\")) {\n\t\tresult.push({\n\t\t\tid: THOUGHT_LEVEL,\n\t\t\tname: \"Thinking Effort\",\n\t\t\tcategory: \"thought_level\",\n\t\t\ttype: \"select\",\n\t\t\tcurrentValue: selection.thinkingLevel,\n\t\t\toptions: levels.map((level) => ({ value: level, name: thinkingLabels[level] })),\n\t\t});\n\t}\n\treturn result;\n});\n\n/** Whether a model is in the catalog a session in `hostDir` sees. */\nexport const known = Effect.fn(\"ACP.config.known\")(function* (\n\tmodel: { readonly provider: string; readonly id: string },\n\thostDir: string | undefined,\n) {\n\tconst catalog = yield* catalogFor(hostDir);\n\treturn catalog[model.provider]?.[model.id] !== undefined;\n});\n\nexport * as Config from \"./config.ts\";\n","import type * as Acp from \"@agentclientprotocol/sdk\";\nimport { EventList, type EventSchema, type ThreadStore } from \"@codeworksh/harness/effect\";\nimport { Option, Schema } from \"effect\";\n\nconst isTextDelta = Schema.is(EventList.LLMTextDelta);\nconst isThinkingDelta = Schema.is(EventList.LLMThinkingDelta);\nconst isToolStarted = Schema.is(EventList.ToolStarted);\nconst isToolSettled = Schema.is(EventList.ToolSettled);\nconst isPluginUpdated = Schema.is(EventList.PluginUpdated);\n\nconst TextContent = Schema.Struct({ type: Schema.Literal(\"text\"), text: Schema.String });\nconst ImageContent = Schema.Struct({ type: Schema.Literal(\"image\"), data: Schema.String, mimeType: Schema.String });\nconst ToolResult = Schema.Struct({\n\tcontent: Schema.Array(Schema.Union([TextContent, Schema.Struct({ type: Schema.Literal(\"image\") })])),\n\tisError: Schema.Boolean,\n});\nconst ToolCall = Schema.Struct({\n\ttype: Schema.Literal(\"toolCall\"),\n\tcallID: Schema.String,\n\tname: Schema.String,\n\targuments: Schema.Record(Schema.String, Schema.Json),\n\tstatus: Schema.String,\n\tresult: Schema.optional(ToolResult),\n});\nconst StoredPart = Schema.Union([\n\tTextContent,\n\tImageContent,\n\tSchema.Struct({ type: Schema.Literal(\"thinking\"), thinking: Schema.String }),\n\tToolCall,\n]);\nconst decodePart = Schema.decodeUnknownOption(Schema.fromJsonString(StoredPart));\n\ntype ToolCall = typeof ToolCall.Type;\n\nconst text = (value: string): Acp.ContentBlock => ({ type: \"text\", text: value });\n\n// The kind comes from the tool's name. Only `bash` ships built in; plugin tools report `other`.\nconst kind = (name: string): Acp.ToolKind => (name === \"bash\" ? \"execute\" : \"other\");\n\n/** The command for `bash`, otherwise the tool's label or name. */\nconst title = (name: string, args: Readonly<Record<string, unknown>>, label?: string): string =>\n\tname === \"bash\" && typeof args.command === \"string\" ? args.command : (label ?? name);\n\nconst settled = (call: Pick<ToolCall, \"callID\" | \"name\" | \"arguments\" | \"status\" | \"result\">): Acp.SessionUpdate => {\n\tconst output = call.result?.content.flatMap((block) => (block.type === \"text\" ? [block.text] : [])).join(\"\\n\");\n\treturn {\n\t\tsessionUpdate: \"tool_call_update\",\n\t\ttoolCallId: call.callID,\n\t\tkind: kind(call.name),\n\t\tstatus: call.status === \"completed\" ? \"completed\" : \"failed\",\n\t\trawInput: call.arguments,\n\t\t...(call.result === undefined ? {} : { rawOutput: call.result }),\n\t\t...(output ? { content: [{ type: \"content\", content: text(output) }] } : {}),\n\t};\n};\n\n/** The live `session/update` for a harness event, if the client should see one. */\nexport const update = (event: EventSchema.Payload): Option.Option<Acp.SessionUpdate> => {\n\tif (isTextDelta(event)) {\n\t\treturn Option.some({ sessionUpdate: \"agent_message_chunk\", content: text(event.data.delta) });\n\t}\n\tif (isThinkingDelta(event)) {\n\t\treturn Option.some({ sessionUpdate: \"agent_thought_chunk\", content: text(event.data.delta) });\n\t}\n\tif (isToolStarted(event)) {\n\t\treturn Option.some({\n\t\t\tsessionUpdate: \"tool_call\",\n\t\t\ttoolCallId: event.data.callID,\n\t\t\ttitle: title(event.data.name, event.data.arguments, event.data.label),\n\t\t\tkind: kind(event.data.name),\n\t\t\tstatus: \"in_progress\",\n\t\t\trawInput: event.data.arguments,\n\t\t});\n\t}\n\tif (isToolSettled(event)) return Option.some(settled(event.data.part));\n\treturn Option.none();\n};\n\n/**\n * Text for the user about a plugin that failed to load, such as one configured but not installed.\n * It belongs in the conversation because the user may never see this process's logs.\n */\nexport const notice = (event: EventSchema.Payload): Option.Option<string> =>\n\tisPluginUpdated(event) && event.data.status === \"failed\" && event.data.error !== undefined\n\t\t? Option.some(event.data.error)\n\t\t: Option.none();\n\n/** A notice shown to the user in the agent's message. */\nexport const noticeUpdate = (notice: string): Acp.SessionUpdate => ({\n\tsessionUpdate: \"agent_message_chunk\",\n\tcontent: text(`> ⚠ ${notice}\\n\\n`),\n});\n\n/** The `session/update`s that replay one stored entry during `session/load`. */\nexport const replay = ({ entry, parts }: ThreadStore.HydratedEntry): ReadonlyArray<Acp.SessionUpdate> => {\n\tif (entry.type !== \"user\" && entry.type !== \"assistant\") return [];\n\treturn parts.flatMap((row): ReadonlyArray<Acp.SessionUpdate> => {\n\t\tconst part = decodePart(row.data);\n\t\tif (Option.isNone(part)) return [];\n\t\tswitch (part.value.type) {\n\t\t\tcase \"text\":\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tsessionUpdate: entry.type === \"user\" ? \"user_message_chunk\" : \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: text(part.value.text),\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\tcase \"image\":\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tsessionUpdate: entry.type === \"user\" ? \"user_message_chunk\" : \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"image\", data: part.value.data, mimeType: part.value.mimeType },\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\tcase \"thinking\":\n\t\t\t\treturn [{ sessionUpdate: \"agent_thought_chunk\", content: text(part.value.thinking) }];\n\t\t\tcase \"toolCall\":\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tsessionUpdate: \"tool_call\",\n\t\t\t\t\t\ttoolCallId: part.value.callID,\n\t\t\t\t\t\ttitle: title(part.value.name, part.value.arguments),\n\t\t\t\t\t\tkind: kind(part.value.name),\n\t\t\t\t\t\tstatus: \"in_progress\",\n\t\t\t\t\t\trawInput: part.value.arguments,\n\t\t\t\t\t},\n\t\t\t\t\tsettled(part.value),\n\t\t\t\t];\n\t\t}\n\t});\n};\n\nexport * as Feed from \"./feed.ts\";\n","import type * as Acp from \"@agentclientprotocol/sdk\";\nimport {\n\tControl,\n\tEventList,\n\ttype EventSchema,\n\ttype Harness,\n\tPromptSchema,\n\tSession,\n\tSessionStore,\n\tThreadStore,\n} from \"@codeworksh/harness/effect\";\nimport { DateTime, Effect, Fiber, type Layer, Option, Schema, Stream } from \"effect\";\nimport pkg from \"../../package.json\" with { type: \"json\" };\nimport { Agent } from \"./agent.ts\";\nimport { Config } from \"./config.ts\";\nimport { Feed } from \"./feed.ts\";\n\nconst PAGE_SIZE = 50;\n\nconst isRequestError = Schema.is(Agent.RequestError);\nconst isNotFound = Schema.is(SessionStore.SessionNotFoundError);\nconst isConflict = Schema.is(Control.PromptConflictError);\nconst isInvalidPrompt = Schema.is(PromptSchema.InvalidPromptError);\nconst isLLMEnded = Schema.is(EventList.LLMEnded);\nconst isSucceeded = Schema.is(EventList.ExecutionSucceeded);\nconst isFailed = Schema.is(EventList.ExecutionFailed);\nconst isInterrupted = Schema.is(EventList.ExecutionInterrupted);\nconst isSettled = (event: EventSchema.Payload) => isSucceeded(event) || isFailed(event) || isInterrupted(event);\n\n/** Harness failures as JSON-RPC errors; handlers raise protocol-level ones directly. */\nconst toRequestError = (error: { readonly message: string }): Agent.RequestError => {\n\tif (isRequestError(error)) return error;\n\tif (isNotFound(error)) return Agent.RequestError.resourceNotFound(`Session not found: ${error.sessionId}`);\n\tif (isConflict(error)) return Agent.RequestError.invalidRequest(error.message);\n\tif (isInvalidPrompt(error)) return Agent.RequestError.invalidParams(error.message);\n\treturn Agent.RequestError.internalError(error.message);\n};\n\n/**\n * Prompt content as harness prompt parts, in order. Text, embedded context and images are\n * advertised; anything else is rejected. Adjacent text joins into one part. The harness checks\n * the images.\n */\nconst promptParts = Effect.fnUntraced(function* (blocks: ReadonlyArray<Acp.ContentBlock>) {\n\tconst parts: Array<PromptSchema.Part> = [];\n\tconst add = (part: PromptSchema.Part) => {\n\t\tconst last = parts.at(-1);\n\t\tif (part.type === \"text\" && last?.type === \"text\")\n\t\t\tparts[parts.length - 1] = { ...last, text: `${last.text}\\n\\n${part.text}` };\n\t\telse parts.push(part);\n\t};\n\tfor (const block of blocks) {\n\t\tswitch (block.type) {\n\t\t\tcase \"text\":\n\t\t\t\tadd({ type: \"text\", text: block.text });\n\t\t\t\tbreak;\n\t\t\tcase \"resource_link\":\n\t\t\t\tadd({ type: \"text\", text: `[${block.name}](${block.uri})` });\n\t\t\t\tbreak;\n\t\t\tcase \"image\":\n\t\t\t\tadd({ type: \"image\", data: block.data, mimeType: block.mimeType });\n\t\t\t\tbreak;\n\t\t\tcase \"resource\":\n\t\t\t\tif (\"text\" in block.resource) {\n\t\t\t\t\tadd({ type: \"text\", text: `\\`\\`\\`${block.resource.uri}\\n${block.resource.text}\\n\\`\\`\\`` });\n\t\t\t\t} else if (block.resource.mimeType?.startsWith(\"image/\")) {\n\t\t\t\t\tadd({ type: \"image\", data: block.resource.blob, mimeType: block.resource.mimeType });\n\t\t\t\t} else {\n\t\t\t\t\treturn yield* Agent.RequestError.invalidParams(`Unsupported binary resource: ${block.resource.uri}`);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn yield* Agent.RequestError.invalidParams(`Unsupported prompt content: ${block.type}`);\n\t\t}\n\t}\n\treturn parts;\n});\n\nconst threadId = (id: string) => Session.ThreadSchema.ID.make(id);\n\ntype Services = Layer.Success<ReturnType<typeof Harness.layer>>;\n\nexport const make = Effect.gen(function* () {\n\tconst control = yield* Control.Service;\n\tconst sessions = yield* SessionStore.Service;\n\tconst threads = yield* ThreadStore.Service;\n\t// Handlers run on the agent's fibers, outside this layer; they carry the harness with them.\n\tconst context = yield* Effect.context<Services>();\n\n\tconst running = new Set<string>();\n\n\t// Every thread is an ACP session of its own. The main thread keeps the CodeWork session's id,\n\t// so a session an editor knew before it had forks still loads; any other thread goes by its id.\n\tconst acpId = (thread: { readonly originKind: string; readonly sessionId: string; readonly id: string }) =>\n\t\tthread.originKind === \"main\" ? thread.sessionId : thread.id;\n\n\t/** The CodeWork session and thread an ACP session id names. */\n\tconst resolve = Effect.fn(\"ACP.resolve\")(function* (id: string) {\n\t\tconst session = yield* sessions.get(id);\n\t\tif (Option.isSome(session)) {\n\t\t\tconst main = yield* threads.main(session.value.id);\n\t\t\tif (Option.isSome(main)) return { session: session.value, threadId: threadId(main.value.id) };\n\t\t}\n\t\tconst thread = yield* threads.get(id);\n\t\tif (Option.isSome(thread)) {\n\t\t\tconst owner = yield* sessions.get(thread.value.sessionId);\n\t\t\tif (Option.isSome(owner)) return { session: owner.value, threadId: threadId(thread.value.id) };\n\t\t}\n\t\treturn yield* new SessionStore.SessionNotFoundError({ sessionId: id });\n\t});\n\n\tconst attach = Effect.fn(\"ACP.attach\")(function* (id: string) {\n\t\tconst { session, threadId } = yield* resolve(id);\n\t\tconst thread = yield* Session.attach({ sessionId: session.id, threadId });\n\t\treturn { thread, hostDir: Option.getOrUndefined(session.hostDir) };\n\t});\n\n\treturn (client: Agent.Client): Agent.Handlers => {\n\t\tconst run = <A, E extends { readonly message: string }>(effect: Effect.Effect<A, E, Services>) =>\n\t\t\teffect.pipe(Effect.provide(context), Effect.mapError(toRequestError));\n\n\t\treturn {\n\t\t\tinitialize: () =>\n\t\t\t\tEffect.succeed({\n\t\t\t\t\tprotocolVersion: 1,\n\t\t\t\t\tagentInfo: { name: \"codework\", version: pkg.version },\n\t\t\t\t\tagentCapabilities: {\n\t\t\t\t\t\tloadSession: true,\n\t\t\t\t\t\tpromptCapabilities: { embeddedContext: true, image: true },\n\t\t\t\t\t\tsessionCapabilities: { list: {}, fork: {} },\n\t\t\t\t\t},\n\t\t\t\t}),\n\n\t\t\tnewSession: ({ cwd }) =>\n\t\t\t\trun(\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tconst handle = yield* Session.create({ directory: cwd, hostDir: cwd });\n\t\t\t\t\t\tconst current = yield* Session.configuration(handle.main.id);\n\t\t\t\t\t\treturn { sessionId: handle.id, configOptions: yield* Config.options(current, cwd) };\n\t\t\t\t\t}),\n\t\t\t\t),\n\n\t\t\tloadSession: ({ sessionId: id }) =>\n\t\t\t\trun(\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tconst { thread, hostDir } = yield* attach(id);\n\t\t\t\t\t\tconst current = yield* Session.configuration(thread.id);\n\t\t\t\t\t\t// A fork replays its whole line, the part it inherits included.\n\t\t\t\t\t\tfor (const entry of yield* thread.history()) {\n\t\t\t\t\t\t\tfor (const update of Feed.replay(entry)) {\n\t\t\t\t\t\t\t\tyield* client.sessionUpdate({ sessionId: id, update });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn { configOptions: yield* Config.options(current, hostDir) };\n\t\t\t\t\t}),\n\t\t\t\t),\n\n\t\t\tlistSessions: ({ cwd, cursor }) =>\n\t\t\t\trun(\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tconst owners = new Map((yield* sessions.list()).map((row) => [row.id, row]));\n\t\t\t\t\t\tconst all = yield* threads.list();\n\t\t\t\t\t\tconst titles = new Map(all.map((thread) => [thread.id, Option.getOrUndefined(thread.title)]));\n\t\t\t\t\t\tconst rows = all\n\t\t\t\t\t\t\t.flatMap((thread) => {\n\t\t\t\t\t\t\t\tconst session = owners.get(thread.sessionId);\n\t\t\t\t\t\t\t\treturn session === undefined ? [] : [{ thread, session }];\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.filter(({ session }) => cwd == null || Option.getOrUndefined(session.hostDir) === cwd)\n\t\t\t\t\t\t\t.sort((a, b) =>\n\t\t\t\t\t\t\t\tDateTime.Order(\n\t\t\t\t\t\t\t\t\tb.thread.updatedAt ?? b.thread.createdAt,\n\t\t\t\t\t\t\t\t\ta.thread.updatedAt ?? a.thread.createdAt,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\tconst offset = cursor == null ? 0 : Number(cursor);\n\t\t\t\t\t\tif (!Number.isSafeInteger(offset) || offset < 0) {\n\t\t\t\t\t\t\treturn yield* Agent.RequestError.invalidParams(`Invalid cursor: ${cursor}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst next = offset + PAGE_SIZE;\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tsessions: rows.slice(offset, next).map(({ thread, session }) => ({\n\t\t\t\t\t\t\t\tsessionId: acpId(thread),\n\t\t\t\t\t\t\t\tcwd: Option.getOrElse(session.hostDir, () => session.directory),\n\t\t\t\t\t\t\t\t// A fork is untitled until its own first prompt; it reads as its source until then.\n\t\t\t\t\t\t\t\ttitle:\n\t\t\t\t\t\t\t\t\ttitles.get(thread.id) ??\n\t\t\t\t\t\t\t\t\tOption.match(thread.originThreadId, {\n\t\t\t\t\t\t\t\t\t\tonNone: () => undefined,\n\t\t\t\t\t\t\t\t\t\tonSome: (origin) => titles.get(origin),\n\t\t\t\t\t\t\t\t\t}) ??\n\t\t\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t\tupdatedAt: DateTime.formatIso(thread.updatedAt ?? thread.createdAt),\n\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t...(next < rows.length ? { nextCursor: String(next) } : {}),\n\t\t\t\t\t\t};\n\t\t\t\t\t}),\n\t\t\t\t),\n\n\t\t\tforkSession: ({ sessionId: id }) =>\n\t\t\t\trun(\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tconst { thread, hostDir } = yield* attach(id);\n\t\t\t\t\t\t// ACP forks the conversation as it stands: at its last committed entry, of any type, so\n\t\t\t\t\t\t// a trailing tool result or compaction comes along.\n\t\t\t\t\t\tconst last = (yield* thread.history()).findLast(({ entry }) => entry.state === \"committed\");\n\t\t\t\t\t\tif (last === undefined) {\n\t\t\t\t\t\t\treturn yield* Agent.RequestError.invalidRequest(\n\t\t\t\t\t\t\t\t\"Nothing to fork yet: the session has no messages\",\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst forked = yield* thread.fork({ entryId: last.entry.id });\n\t\t\t\t\t\tconst current = yield* Session.configuration(forked.thread.id);\n\t\t\t\t\t\treturn { sessionId: forked.thread.id, configOptions: yield* Config.options(current, hostDir) };\n\t\t\t\t\t}),\n\t\t\t\t),\n\n\t\t\tsetConfigOption: (request) =>\n\t\t\t\trun(\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tconst { session, threadId } = yield* resolve(request.sessionId);\n\t\t\t\t\t\tconst hostDir = Option.getOrUndefined(session.hostDir);\n\t\t\t\t\t\tconst value = String(request.value);\n\t\t\t\t\t\tlet runtime: Session.RuntimeInput;\n\t\t\t\t\t\tif (request.configId === Config.MODEL) {\n\t\t\t\t\t\t\tconst model = Option.getOrUndefined(Config.parseModel(value));\n\t\t\t\t\t\t\tif (model === undefined || !(yield* Config.known(model, hostDir))) {\n\t\t\t\t\t\t\t\treturn yield* Agent.RequestError.invalidParams(`Unknown model: ${value}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\truntime = { model };\n\t\t\t\t\t\t} else if (request.configId === Config.THOUGHT_LEVEL) {\n\t\t\t\t\t\t\tif (!Config.isThinkingLevel(value)) {\n\t\t\t\t\t\t\t\treturn yield* Agent.RequestError.invalidParams(`Unknown thinking level: ${value}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\truntime = { thinkingLevel: value };\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn yield* Agent.RequestError.invalidParams(`Unknown config option: ${request.configId}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst thread = yield* Session.attach({ sessionId: session.id, threadId, ...runtime });\n\t\t\t\t\t\treturn { configOptions: yield* Config.options(yield* Session.configuration(thread.id), hostDir) };\n\t\t\t\t\t}),\n\t\t\t\t),\n\n\t\t\tprompt: ({ sessionId: id, prompt }) =>\n\t\t\t\trun(\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tconst parts = yield* promptParts(prompt);\n\t\t\t\t\t\tconst { thread: handle } = yield* attach(id);\n\t\t\t\t\t\t// Keyed by thread: main answers to its session id and its own thread id alike.\n\t\t\t\t\t\tif (running.has(handle.id)) {\n\t\t\t\t\t\t\treturn yield* Agent.RequestError.invalidRequest(\"A prompt is already running for this session\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\trunning.add(handle.id);\n\t\t\t\t\t\tyield* Effect.addFinalizer(() => Effect.sync(() => running.delete(handle.id)));\n\n\t\t\t\t\t\t// Forward this execution's updates until it settles; the settling event decides the answer.\n\t\t\t\t\t\tlet reason: EventList.LLMEnded[\"data\"][\"reason\"] | undefined;\n\t\t\t\t\t\t// Plugins are checked every exchange; tell the user about each failure once per prompt.\n\t\t\t\t\t\tconst notices = new Set<string>();\n\t\t\t\t\t\tconst settled = yield* handle.events().pipe(\n\t\t\t\t\t\t\tStream.tap((event) => {\n\t\t\t\t\t\t\t\tif (isLLMEnded(event)) reason = event.data.reason;\n\t\t\t\t\t\t\t\tlet update = Feed.update(event);\n\t\t\t\t\t\t\t\tconst notice = Feed.notice(event);\n\t\t\t\t\t\t\t\tif (Option.isSome(notice) && !notices.has(notice.value)) {\n\t\t\t\t\t\t\t\t\tnotices.add(notice.value);\n\t\t\t\t\t\t\t\t\tupdate = Option.some(Feed.noticeUpdate(notice.value));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn Option.match(update, {\n\t\t\t\t\t\t\t\t\tonNone: () => Effect.void,\n\t\t\t\t\t\t\t\t\tonSome: (update) => client.sessionUpdate({ sessionId: id, update }).pipe(Effect.ignore),\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tStream.filter(isSettled),\n\t\t\t\t\t\t\tStream.runHead,\n\t\t\t\t\t\t\tEffect.forkScoped({ startImmediately: true }),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst before = (yield* handle.info).title;\n\t\t\t\t\t\tyield* handle.run({ parts });\n\t\t\t\t\t\tconst end = yield* Fiber.join(settled);\n\n\t\t\t\t\t\t// The harness titles a thread from its first prompt; tell the editor.\n\t\t\t\t\t\tconst { title } = yield* handle.info;\n\t\t\t\t\t\tif (title !== undefined && title !== before) {\n\t\t\t\t\t\t\tyield* client\n\t\t\t\t\t\t\t\t.sessionUpdate({ sessionId: id, update: { sessionUpdate: \"session_info_update\", title } })\n\t\t\t\t\t\t\t\t.pipe(Effect.ignore);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (Option.isNone(end) || isInterrupted(end.value)) return { stopReason: \"cancelled\" as const };\n\t\t\t\t\t\tif (isFailed(end.value)) return yield* Agent.RequestError.internalError(end.value.data.error.message);\n\t\t\t\t\t\treturn { stopReason: reason === \"length\" ? (\"max_tokens\" as const) : (\"end_turn\" as const) };\n\t\t\t\t\t}).pipe(Effect.scoped),\n\t\t\t\t),\n\n\t\t\tcancel: ({ sessionId: id }) =>\n\t\t\t\tresolve(id).pipe(\n\t\t\t\t\tEffect.flatMap((found) => control.interrupt(found.threadId, { reason: \"user\" })),\n\t\t\t\t\tEffect.ignore,\n\t\t\t\t\tEffect.provide(context),\n\t\t\t\t),\n\t\t};\n\t};\n});\n\nexport * as Handlers from \"./handlers.ts\";\n","import { Control, Harness, Sandbox } from \"@codeworksh/harness/effect\";\nimport { Effect, Logger, Stdio } from \"effect\";\nimport { Agent } from \"./agent.ts\";\nimport { Handlers } from \"./handlers.ts\";\n\n// Sessions and managed sandboxes outlive any single request; the connection's end is what stops them.\nconst shutdown = Effect.gen(function* () {\n\tconst control = yield* Control.Service;\n\tyield* Effect.forEach(\n\t\tyield* control.active,\n\t\t(id) =>\n\t\t\tcontrol\n\t\t\t\t.interrupt(id, { reason: \"shutdown\", awaitSettlement: true })\n\t\t\t\t.pipe(Effect.timeout(\"10 seconds\"), Effect.ignore),\n\t\t{ concurrency: \"unbounded\", discard: true },\n\t);\n\tconst managed = (yield* Sandbox.list()).filter((info) => info.ownership === \"managed\");\n\tyield* Effect.forEach(\n\t\tmanaged,\n\t\t(info) =>\n\t\t\tSandbox.stop(info.id).pipe(\n\t\t\t\tEffect.timeout(\"10 seconds\"),\n\t\t\t\tEffect.catchCause((cause) =>\n\t\t\t\t\tEffect.logError(\"Failed to stop managed sandbox during ACP shutdown\", cause).pipe(\n\t\t\t\t\t\tEffect.annotateLogs({ sandboxInstanceId: info.id }),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t),\n\t\t{ concurrency: \"unbounded\", discard: true },\n\t);\n});\n\n/**\n * Serves ACP v1 on stdio until the client disconnects.\n *\n * stdout carries the protocol, so logs go to stderr. The reference is set outside the harness layer\n * so the fibers it forks (turns, plugin loads) inherit it too.\n */\nexport const serve = (options: Harness.Options) =>\n\tEffect.gen(function* () {\n\t\tyield* Effect.addFinalizer(() => shutdown.pipe(Effect.ignore));\n\t\tconst handlers = yield* Handlers.make;\n\t\tyield* Agent.serve(yield* Stdio.Stdio, handlers);\n\t}).pipe(Effect.scoped, Effect.provide(Harness.layer(options)), Effect.provideService(Logger.LogToStderr, true));\n\nexport * as Server from \"./server.ts\";\n","import { Effect } from \"effect\";\nimport { Server } from \"../../../acp/server.ts\";\nimport { Runtime } from \"../../../framework/runtime.ts\";\nimport { reportFailure } from \"../../error.ts\";\nimport { harnessOptions } from \"../../harness.ts\";\nimport { Cmd } from \"../cmd.ts\";\n\nexport default Runtime.handler(\n\tCmd.commands.acp,\n\tEffect.fn(\"CLI.acp\", { level: \"Info\" })(function* () {\n\t\tconst shared = yield* Cmd.spec;\n\t\treturn yield* Server.serve(harnessOptions(shared)).pipe(Effect.catch(reportFailure));\n\t}),\n);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"acp-BeDi6jEL.mjs","names":["serve","Agent.RequestError","pkg.version","Config.options","Feed.replay","Config.parseModel","Config.known","Config.isThinkingLevel","update","Feed.update","notice","Feed.notice","Feed.noticeUpdate","Handlers.make","Agent.serve","Runtime.handler","Server.serve"],"sources":["../../src/acp/agent.ts","../../src/acp/config.ts","../../src/acp/feed.ts","../../src/acp/handlers.ts","../../src/acp/server.ts","../../src/cli/cmd/handlers/acp.ts"],"sourcesContent":["import * as Acp from \"@agentclientprotocol/sdk\";\nimport { Cause, Deferred, Effect, Exit, Option, Schema, type Scope, type Stdio, Stream } from \"effect\";\n\n/** A JSON-RPC error a handler answers a request with. */\nexport class RequestError extends Schema.TaggedError<RequestError>()(\"AcpRequestError\", {\n\tcode: Schema.Int,\n\tmessage: Schema.String,\n}) {\n\tstatic invalidRequest = (message: string) => new RequestError({ code: -32600, message });\n\tstatic invalidParams = (message: string) => new RequestError({ code: -32602, message });\n\tstatic internalError = (message: string) => new RequestError({ code: -32603, message });\n\tstatic resourceNotFound = (message: string) => new RequestError({ code: -32002, message });\n}\n\ntype Handler<Request, Response> = (request: Request) => Effect.Effect<Response, RequestError>;\n\n/** Calls the agent makes to the connected client. */\nexport interface Client {\n\treadonly sessionUpdate: (notification: Acp.SessionNotification) => Effect.Effect<void, RequestError>;\n}\n\nexport interface Handlers {\n\treadonly initialize: Handler<Acp.InitializeRequest, Acp.InitializeResponse>;\n\treadonly newSession: Handler<Acp.NewSessionRequest, Acp.NewSessionResponse>;\n\t/** Must replay the session's history through `Client.sessionUpdate` before it returns. */\n\treadonly loadSession: Handler<Acp.LoadSessionRequest, Acp.LoadSessionResponse>;\n\treadonly listSessions: Handler<Acp.ListSessionsRequest, Acp.ListSessionsResponse>;\n\treadonly forkSession: Handler<Acp.ForkSessionRequest, Acp.ForkSessionResponse>;\n\treadonly setConfigOption: Handler<Acp.SetSessionConfigOptionRequest, Acp.SetSessionConfigOptionResponse>;\n\treadonly prompt: Handler<Acp.PromptRequest, Acp.PromptResponse>;\n\treadonly cancel: (notification: Acp.CancelNotification) => Effect.Effect<void>;\n}\n\n/**\n * Serves an ACP agent over `stdio` until the client closes its end.\n *\n * Handlers run as fibers on this effect's services; a request the client cancels, or the\n * connection closing, interrupts its fiber.\n */\nexport const serve = Effect.fn(\"ACP.serve\")(function* (\n\tstdio: Stdio.Stdio,\n\tmakeHandlers: (client: Client) => Handlers,\n): Effect.fn.Return<void, never, Scope.Scope> {\n\tconst context = yield* Effect.context<never>();\n\tconst runExit = Effect.runPromiseExitWith(context);\n\tconst opened = yield* Deferred.make<Acp.AgentConnection>();\n\n\tconst handlers = makeHandlers({\n\t\tsessionUpdate: (notification) =>\n\t\t\tDeferred.await(opened).pipe(\n\t\t\t\tEffect.flatMap((connection) =>\n\t\t\t\t\tEffect.tryPromise({\n\t\t\t\t\t\ttry: () => connection.client.notify(Acp.methods.client.session.update, notification),\n\t\t\t\t\t\tcatch: (error) => RequestError.internalError(`Failed to send session/update: ${String(error)}`),\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t),\n\t});\n\n\t// A JSON-RPC answer for a handler that didn't succeed; the SDK sends what `handle` throws.\n\tconst toWire = (cause: Cause.Cause<RequestError>): Acp.RequestError => {\n\t\tconst error = Cause.findErrorOption(cause);\n\t\tif (Option.isSome(error)) return new Acp.RequestError(error.value.code, error.value.message);\n\t\tif (Cause.hasInterruptsOnly(cause)) return Acp.RequestError.requestCancelled();\n\t\treturn Acp.RequestError.internalError(undefined, String(Cause.squash(cause)));\n\t};\n\tconst handle =\n\t\t<Params, A>(handler: (params: Params) => Effect.Effect<A, RequestError>) =>\n\t\t({ params, signal }: { readonly params: Params; readonly signal: AbortSignal }): Promise<A> =>\n\t\t\trunExit(handler(params), { signal }).then((exit) => {\n\t\t\t\tif (Exit.isSuccess(exit)) return exit.value;\n\t\t\t\tthrow toWire(exit.cause);\n\t\t\t});\n\n\tconst input = yield* Stream.toReadableStreamEffect(stdio.stdin);\n\tconst output = new WritableStream<Uint8Array>({\n\t\twrite: (chunk) => Effect.runPromiseWith(context)(Stream.run(Stream.make(chunk), stdio.stdout())),\n\t});\n\n\tconst connection = Acp.agent({ name: \"codework\" })\n\t\t.onRequest(\"initialize\", handle(handlers.initialize))\n\t\t.onRequest(\"session/new\", handle(handlers.newSession))\n\t\t.onRequest(\"session/load\", handle(handlers.loadSession))\n\t\t.onRequest(\"session/list\", handle(handlers.listSessions))\n\t\t.onRequest(\"session/fork\", handle(handlers.forkSession))\n\t\t.onRequest(\"session/set_config_option\", handle(handlers.setConfigOption))\n\t\t.onRequest(\"session/prompt\", handle(handlers.prompt))\n\t\t.onNotification(\"session/cancel\", handle(handlers.cancel))\n\t\t.connect(Acp.ndJsonStream(output, input));\n\tyield* Deferred.succeed(opened, connection);\n\tyield* Effect.addFinalizer(() => Effect.sync(() => connection.close()));\n\tyield* Effect.promise(() => connection.closed);\n});\n\nexport * as Agent from \"./agent.ts\";\n","import type * as Acp from \"@agentclientprotocol/sdk\";\nimport { Model } from \"@codeworksh/aikit\";\nimport { ModelCatalog, Settings, type State } from \"@codeworksh/harness/effect\";\nimport { Effect, Option } from \"effect\";\n\nexport const MODEL = \"model\";\nexport const THOUGHT_LEVEL = \"thought_level\";\n\nconst thinkingLabels: Record<Model.ThinkingLevel, string> = {\n\toff: \"Off\",\n\tminimal: \"Minimal\",\n\tlow: \"Low\",\n\tmedium: \"Medium\",\n\thigh: \"High\",\n\txhigh: \"Extra High\",\n\tmax: \"Max\",\n};\n\nexport const isThinkingLevel = (value: string): value is Model.ThinkingLevel => Object.hasOwn(thinkingLabels, value);\n\n/** Splits a `provider/model` option value on its first slash; model ids may contain more. */\nexport const parseModel = (value: string): Option.Option<{ readonly provider: string; readonly id: string }> => {\n\tconst slash = value.indexOf(\"/\");\n\tif (slash <= 0 || slash === value.length - 1) return Option.none();\n\treturn Option.some({ provider: value.slice(0, slash), id: value.slice(slash + 1) });\n};\n\n/** The catalog a session in `hostDir` sees: generated entries plus its settings' `models`. */\nconst catalogFor = (hostDir: string | undefined) =>\n\tEffect.gen(function* () {\n\t\tconst settings = yield* Settings.Service;\n\t\treturn yield* ModelCatalog.effective((yield* settings.load(hostDir)).models);\n\t}).pipe(Effect.orElseSucceed((): Model.BuiltInModels => ({})));\n\n/** The `model` and `thought_level` selectors for a session's current configuration. */\nexport const options = Effect.fn(\"ACP.config.options\")(function* (\n\tselection: State.Configuration,\n\thostDir: string | undefined,\n) {\n\tconst catalog = yield* catalogFor(hostDir);\n\t// Providers the harness has credentials for; the current model stays selectable even if not.\n\tconst providers = yield* ModelCatalog.available(hostDir === undefined ? {} : { hostDir }).pipe(\n\t\tEffect.orElseSucceed(() => []),\n\t);\n\n\tconst current = `${selection.provider}/${selection.model}`;\n\tconst models = providers.flatMap((provider) =>\n\t\tObject.entries(provider.models).map(([id, info]) => ({\n\t\t\tvalue: `${provider.id}/${id}`,\n\t\t\tname: `${info.provider.name}: ${info.name}`,\n\t\t})),\n\t);\n\tif (!models.some((option) => option.value === current)) models.unshift({ value: current, name: current });\n\n\tconst result: Array<Acp.SessionConfigOption> = [\n\t\t{ id: MODEL, name: \"Model\", category: \"model\", type: \"select\", currentValue: current, options: models },\n\t];\n\n\tconst info = catalog[selection.provider]?.[selection.model];\n\tconst levels = info === undefined ? [] : Model.getSupportedThinkingLevels(info);\n\tif (levels.some((level) => level !== \"off\")) {\n\t\tresult.push({\n\t\t\tid: THOUGHT_LEVEL,\n\t\t\tname: \"Thinking Effort\",\n\t\t\tcategory: \"thought_level\",\n\t\t\ttype: \"select\",\n\t\t\tcurrentValue: selection.thinkingLevel,\n\t\t\toptions: levels.map((level) => ({ value: level, name: thinkingLabels[level] })),\n\t\t});\n\t}\n\treturn result;\n});\n\n/** Whether a model is in the catalog a session in `hostDir` sees. */\nexport const known = Effect.fn(\"ACP.config.known\")(function* (\n\tmodel: { readonly provider: string; readonly id: string },\n\thostDir: string | undefined,\n) {\n\tconst catalog = yield* catalogFor(hostDir);\n\treturn catalog[model.provider]?.[model.id] !== undefined;\n});\n\nexport * as Config from \"./config.ts\";\n","import type * as Acp from \"@agentclientprotocol/sdk\";\nimport { EventList, type EventSchema, type ThreadStore } from \"@codeworksh/harness/effect\";\nimport { Option, Schema } from \"effect\";\n\nconst isTextDelta = Schema.is(EventList.LLMTextDelta);\nconst isThinkingDelta = Schema.is(EventList.LLMThinkingDelta);\nconst isToolStarted = Schema.is(EventList.ToolStarted);\nconst isToolSettled = Schema.is(EventList.ToolSettled);\nconst isPluginUpdated = Schema.is(EventList.PluginUpdated);\n\nconst TextContent = Schema.Struct({ type: Schema.Literal(\"text\"), text: Schema.String });\nconst ImageContent = Schema.Struct({ type: Schema.Literal(\"image\"), data: Schema.String, mimeType: Schema.String });\nconst ToolResult = Schema.Struct({\n\tcontent: Schema.Array(Schema.Union([TextContent, Schema.Struct({ type: Schema.Literal(\"image\") })])),\n\tisError: Schema.Boolean,\n});\nconst ToolCall = Schema.Struct({\n\ttype: Schema.Literal(\"toolCall\"),\n\tcallID: Schema.String,\n\tname: Schema.String,\n\targuments: Schema.Record(Schema.String, Schema.Json),\n\tstatus: Schema.String,\n\tresult: Schema.optional(ToolResult),\n});\nconst StoredPart = Schema.Union([\n\tTextContent,\n\tImageContent,\n\tSchema.Struct({ type: Schema.Literal(\"thinking\"), thinking: Schema.String }),\n\tToolCall,\n]);\nconst decodePart = Schema.decodeUnknownOption(Schema.fromJsonString(StoredPart));\n\ntype ToolCall = typeof ToolCall.Type;\n\nconst text = (value: string): Acp.ContentBlock => ({ type: \"text\", text: value });\n\n// The kind comes from the tool's name. Only `bash` ships built in; plugin tools report `other`.\nconst kind = (name: string): Acp.ToolKind => (name === \"bash\" ? \"execute\" : \"other\");\n\n/** The command for `bash`, otherwise the tool's label or name. */\nconst title = (name: string, args: Readonly<Record<string, unknown>>, label?: string): string =>\n\tname === \"bash\" && typeof args.command === \"string\" ? args.command : (label ?? name);\n\nconst settled = (call: Pick<ToolCall, \"callID\" | \"name\" | \"arguments\" | \"status\" | \"result\">): Acp.SessionUpdate => {\n\tconst output = call.result?.content.flatMap((block) => (block.type === \"text\" ? [block.text] : [])).join(\"\\n\");\n\treturn {\n\t\tsessionUpdate: \"tool_call_update\",\n\t\ttoolCallId: call.callID,\n\t\tkind: kind(call.name),\n\t\tstatus: call.status === \"completed\" ? \"completed\" : \"failed\",\n\t\trawInput: call.arguments,\n\t\t...(call.result === undefined ? {} : { rawOutput: call.result }),\n\t\t...(output ? { content: [{ type: \"content\", content: text(output) }] } : {}),\n\t};\n};\n\n/** The live `session/update` for a harness event, if the client should see one. */\nexport const update = (event: EventSchema.Payload): Option.Option<Acp.SessionUpdate> => {\n\tif (isTextDelta(event)) {\n\t\treturn Option.some({ sessionUpdate: \"agent_message_chunk\", content: text(event.data.delta) });\n\t}\n\tif (isThinkingDelta(event)) {\n\t\treturn Option.some({ sessionUpdate: \"agent_thought_chunk\", content: text(event.data.delta) });\n\t}\n\tif (isToolStarted(event)) {\n\t\treturn Option.some({\n\t\t\tsessionUpdate: \"tool_call\",\n\t\t\ttoolCallId: event.data.callID,\n\t\t\ttitle: title(event.data.name, event.data.arguments, event.data.label),\n\t\t\tkind: kind(event.data.name),\n\t\t\tstatus: \"in_progress\",\n\t\t\trawInput: event.data.arguments,\n\t\t});\n\t}\n\tif (isToolSettled(event)) return Option.some(settled(event.data.part));\n\treturn Option.none();\n};\n\n/**\n * Text for the user about a plugin that failed to load, such as one configured but not installed.\n * It belongs in the conversation because the user may never see this process's logs.\n */\nexport const notice = (event: EventSchema.Payload): Option.Option<string> =>\n\tisPluginUpdated(event) && event.data.status === \"failed\" && event.data.error !== undefined\n\t\t? Option.some(event.data.error)\n\t\t: Option.none();\n\n/** A notice shown to the user in the agent's message. */\nexport const noticeUpdate = (notice: string): Acp.SessionUpdate => ({\n\tsessionUpdate: \"agent_message_chunk\",\n\tcontent: text(`> ⚠ ${notice}\\n\\n`),\n});\n\n/** The `session/update`s that replay one stored entry during `session/load`. */\nexport const replay = ({ entry, parts }: ThreadStore.HydratedEntry): ReadonlyArray<Acp.SessionUpdate> => {\n\tif (entry.type !== \"user\" && entry.type !== \"assistant\") return [];\n\treturn parts.flatMap((row): ReadonlyArray<Acp.SessionUpdate> => {\n\t\tconst part = decodePart(row.data);\n\t\tif (Option.isNone(part)) return [];\n\t\tswitch (part.value.type) {\n\t\t\tcase \"text\":\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tsessionUpdate: entry.type === \"user\" ? \"user_message_chunk\" : \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: text(part.value.text),\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\tcase \"image\":\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tsessionUpdate: entry.type === \"user\" ? \"user_message_chunk\" : \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"image\", data: part.value.data, mimeType: part.value.mimeType },\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\tcase \"thinking\":\n\t\t\t\treturn [{ sessionUpdate: \"agent_thought_chunk\", content: text(part.value.thinking) }];\n\t\t\tcase \"toolCall\":\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tsessionUpdate: \"tool_call\",\n\t\t\t\t\t\ttoolCallId: part.value.callID,\n\t\t\t\t\t\ttitle: title(part.value.name, part.value.arguments),\n\t\t\t\t\t\tkind: kind(part.value.name),\n\t\t\t\t\t\tstatus: \"in_progress\",\n\t\t\t\t\t\trawInput: part.value.arguments,\n\t\t\t\t\t},\n\t\t\t\t\tsettled(part.value),\n\t\t\t\t];\n\t\t}\n\t});\n};\n\nexport * as Feed from \"./feed.ts\";\n","import type * as Acp from \"@agentclientprotocol/sdk\";\nimport {\n\tControl,\n\tEventList,\n\ttype EventSchema,\n\ttype Harness,\n\tPromptSchema,\n\tSession,\n\tSessionStore,\n\tThreadStore,\n} from \"@codeworksh/harness/effect\";\nimport { DateTime, Effect, Fiber, type Layer, Option, Schema, Stream } from \"effect\";\nimport pkg from \"../../package.json\" with { type: \"json\" };\nimport { Agent } from \"./agent.ts\";\nimport { Config } from \"./config.ts\";\nimport { Feed } from \"./feed.ts\";\n\nconst PAGE_SIZE = 50;\n\nconst isRequestError = Schema.is(Agent.RequestError);\nconst isNotFound = Schema.is(SessionStore.SessionNotFoundError);\nconst isConflict = Schema.is(Control.PromptConflictError);\nconst isInvalidPrompt = Schema.is(PromptSchema.InvalidPromptError);\nconst isLLMEnded = Schema.is(EventList.LLMEnded);\nconst isSucceeded = Schema.is(EventList.ExecutionSucceeded);\nconst isFailed = Schema.is(EventList.ExecutionFailed);\nconst isInterrupted = Schema.is(EventList.ExecutionInterrupted);\nconst isSettled = (event: EventSchema.Payload) => isSucceeded(event) || isFailed(event) || isInterrupted(event);\n\n/** Harness failures as JSON-RPC errors; handlers raise protocol-level ones directly. */\nconst toRequestError = (error: { readonly message: string }): Agent.RequestError => {\n\tif (isRequestError(error)) return error;\n\tif (isNotFound(error)) return Agent.RequestError.resourceNotFound(`Session not found: ${error.sessionId}`);\n\tif (isConflict(error)) return Agent.RequestError.invalidRequest(error.message);\n\tif (isInvalidPrompt(error)) return Agent.RequestError.invalidParams(error.message);\n\treturn Agent.RequestError.internalError(error.message);\n};\n\n/**\n * Prompt content as harness prompt parts, in order. Text, embedded context and images are\n * advertised; anything else is rejected. Adjacent text joins into one part. The harness checks\n * the images.\n */\nconst promptParts = Effect.fnUntraced(function* (blocks: ReadonlyArray<Acp.ContentBlock>) {\n\tconst parts: Array<PromptSchema.Part> = [];\n\tconst add = (part: PromptSchema.Part) => {\n\t\tconst last = parts.at(-1);\n\t\tif (part.type === \"text\" && last?.type === \"text\")\n\t\t\tparts[parts.length - 1] = { ...last, text: `${last.text}\\n\\n${part.text}` };\n\t\telse parts.push(part);\n\t};\n\tfor (const block of blocks) {\n\t\tswitch (block.type) {\n\t\t\tcase \"text\":\n\t\t\t\tadd({ type: \"text\", text: block.text });\n\t\t\t\tbreak;\n\t\t\tcase \"resource_link\":\n\t\t\t\tadd({ type: \"text\", text: `[${block.name}](${block.uri})` });\n\t\t\t\tbreak;\n\t\t\tcase \"image\":\n\t\t\t\tadd({ type: \"image\", data: block.data, mimeType: block.mimeType });\n\t\t\t\tbreak;\n\t\t\tcase \"resource\":\n\t\t\t\tif (\"text\" in block.resource) {\n\t\t\t\t\tadd({ type: \"text\", text: `\\`\\`\\`${block.resource.uri}\\n${block.resource.text}\\n\\`\\`\\`` });\n\t\t\t\t} else if (block.resource.mimeType?.startsWith(\"image/\")) {\n\t\t\t\t\tadd({ type: \"image\", data: block.resource.blob, mimeType: block.resource.mimeType });\n\t\t\t\t} else {\n\t\t\t\t\treturn yield* Agent.RequestError.invalidParams(`Unsupported binary resource: ${block.resource.uri}`);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn yield* Agent.RequestError.invalidParams(`Unsupported prompt content: ${block.type}`);\n\t\t}\n\t}\n\treturn parts;\n});\n\nconst threadId = (id: string) => Session.ThreadSchema.ID.make(id);\n\ntype Services = Layer.Success<ReturnType<typeof Harness.layer>>;\n\nexport const make = Effect.gen(function* () {\n\tconst control = yield* Control.Service;\n\tconst sessions = yield* SessionStore.Service;\n\tconst threads = yield* ThreadStore.Service;\n\t// Handlers run on the agent's fibers, outside this layer; they carry the harness with them.\n\tconst context = yield* Effect.context<Services>();\n\n\tconst running = new Set<string>();\n\n\t// Every thread is an ACP session of its own. The main thread keeps the CodeWork session's id,\n\t// so a session an editor knew before it had forks still loads; any other thread goes by its id.\n\tconst acpId = (thread: { readonly originKind: string; readonly sessionId: string; readonly id: string }) =>\n\t\tthread.originKind === \"main\" ? thread.sessionId : thread.id;\n\n\t/** The CodeWork session and thread an ACP session id names. */\n\tconst resolve = Effect.fn(\"ACP.resolve\")(function* (id: string) {\n\t\tconst session = yield* sessions.get(id);\n\t\tif (Option.isSome(session)) {\n\t\t\tconst main = yield* threads.main(session.value.id);\n\t\t\tif (Option.isSome(main)) return { session: session.value, threadId: threadId(main.value.id) };\n\t\t}\n\t\tconst thread = yield* threads.get(id);\n\t\tif (Option.isSome(thread)) {\n\t\t\tconst owner = yield* sessions.get(thread.value.sessionId);\n\t\t\tif (Option.isSome(owner)) return { session: owner.value, threadId: threadId(thread.value.id) };\n\t\t}\n\t\treturn yield* new SessionStore.SessionNotFoundError({ sessionId: id });\n\t});\n\n\tconst attach = Effect.fn(\"ACP.attach\")(function* (id: string) {\n\t\tconst { session, threadId } = yield* resolve(id);\n\t\tconst thread = yield* Session.attach({ sessionId: session.id, threadId });\n\t\treturn { thread, hostDir: Option.getOrUndefined(session.hostDir) };\n\t});\n\n\treturn (client: Agent.Client): Agent.Handlers => {\n\t\tconst run = <A, E extends { readonly message: string }>(effect: Effect.Effect<A, E, Services>) =>\n\t\t\teffect.pipe(Effect.provide(context), Effect.mapError(toRequestError));\n\n\t\treturn {\n\t\t\tinitialize: () =>\n\t\t\t\tEffect.succeed({\n\t\t\t\t\tprotocolVersion: 1,\n\t\t\t\t\tagentInfo: { name: \"codework\", version: pkg.version },\n\t\t\t\t\tagentCapabilities: {\n\t\t\t\t\t\tloadSession: true,\n\t\t\t\t\t\tpromptCapabilities: { embeddedContext: true, image: true },\n\t\t\t\t\t\tsessionCapabilities: { list: {}, fork: {} },\n\t\t\t\t\t},\n\t\t\t\t}),\n\n\t\t\tnewSession: ({ cwd }) =>\n\t\t\t\trun(\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tconst handle = yield* Session.create({ directory: cwd, hostDir: cwd });\n\t\t\t\t\t\tconst current = yield* Session.configuration(handle.main.id);\n\t\t\t\t\t\treturn { sessionId: handle.id, configOptions: yield* Config.options(current, cwd) };\n\t\t\t\t\t}),\n\t\t\t\t),\n\n\t\t\tloadSession: ({ sessionId: id }) =>\n\t\t\t\trun(\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tconst { thread, hostDir } = yield* attach(id);\n\t\t\t\t\t\tconst current = yield* Session.configuration(thread.id);\n\t\t\t\t\t\t// A fork replays its whole line, the part it inherits included.\n\t\t\t\t\t\tfor (const entry of yield* thread.history()) {\n\t\t\t\t\t\t\tfor (const update of Feed.replay(entry)) {\n\t\t\t\t\t\t\t\tyield* client.sessionUpdate({ sessionId: id, update });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn { configOptions: yield* Config.options(current, hostDir) };\n\t\t\t\t\t}),\n\t\t\t\t),\n\n\t\t\tlistSessions: ({ cwd, cursor }) =>\n\t\t\t\trun(\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tconst owners = new Map((yield* sessions.list()).map((row) => [row.id, row]));\n\t\t\t\t\t\tconst all = yield* threads.list();\n\t\t\t\t\t\tconst titles = new Map(all.map((thread) => [thread.id, Option.getOrUndefined(thread.title)]));\n\t\t\t\t\t\tconst rows = all\n\t\t\t\t\t\t\t.flatMap((thread) => {\n\t\t\t\t\t\t\t\tconst session = owners.get(thread.sessionId);\n\t\t\t\t\t\t\t\treturn session === undefined ? [] : [{ thread, session }];\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.filter(({ session }) => cwd == null || Option.getOrUndefined(session.hostDir) === cwd)\n\t\t\t\t\t\t\t.sort((a, b) =>\n\t\t\t\t\t\t\t\tDateTime.Order(\n\t\t\t\t\t\t\t\t\tb.thread.updatedAt ?? b.thread.createdAt,\n\t\t\t\t\t\t\t\t\ta.thread.updatedAt ?? a.thread.createdAt,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\tconst offset = cursor == null ? 0 : Number(cursor);\n\t\t\t\t\t\tif (!Number.isSafeInteger(offset) || offset < 0) {\n\t\t\t\t\t\t\treturn yield* Agent.RequestError.invalidParams(`Invalid cursor: ${cursor}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst next = offset + PAGE_SIZE;\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tsessions: rows.slice(offset, next).map(({ thread, session }) => ({\n\t\t\t\t\t\t\t\tsessionId: acpId(thread),\n\t\t\t\t\t\t\t\tcwd: Option.getOrElse(session.hostDir, () => session.directory),\n\t\t\t\t\t\t\t\t// A fork is untitled until its own first prompt; it reads as its source until then.\n\t\t\t\t\t\t\t\ttitle:\n\t\t\t\t\t\t\t\t\ttitles.get(thread.id) ??\n\t\t\t\t\t\t\t\t\tOption.match(thread.originThreadId, {\n\t\t\t\t\t\t\t\t\t\tonNone: () => undefined,\n\t\t\t\t\t\t\t\t\t\tonSome: (origin) => titles.get(origin),\n\t\t\t\t\t\t\t\t\t}) ??\n\t\t\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t\tupdatedAt: DateTime.formatIso(thread.updatedAt ?? thread.createdAt),\n\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t...(next < rows.length ? { nextCursor: String(next) } : {}),\n\t\t\t\t\t\t};\n\t\t\t\t\t}),\n\t\t\t\t),\n\n\t\t\tforkSession: ({ sessionId: id }) =>\n\t\t\t\trun(\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tconst { thread, hostDir } = yield* attach(id);\n\t\t\t\t\t\t// ACP forks the conversation as it stands: at its last committed entry, of any type, so\n\t\t\t\t\t\t// a trailing tool result or compaction comes along.\n\t\t\t\t\t\tconst last = (yield* thread.history()).findLast(({ entry }) => entry.state === \"committed\");\n\t\t\t\t\t\tif (last === undefined) {\n\t\t\t\t\t\t\treturn yield* Agent.RequestError.invalidRequest(\n\t\t\t\t\t\t\t\t\"Nothing to fork yet: the session has no messages\",\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst forked = yield* thread.fork({ entryId: last.entry.id });\n\t\t\t\t\t\tconst current = yield* Session.configuration(forked.thread.id);\n\t\t\t\t\t\treturn { sessionId: forked.thread.id, configOptions: yield* Config.options(current, hostDir) };\n\t\t\t\t\t}),\n\t\t\t\t),\n\n\t\t\tsetConfigOption: (request) =>\n\t\t\t\trun(\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tconst { session, threadId } = yield* resolve(request.sessionId);\n\t\t\t\t\t\tconst hostDir = Option.getOrUndefined(session.hostDir);\n\t\t\t\t\t\tconst value = String(request.value);\n\t\t\t\t\t\tlet runtime: Session.RuntimeInput;\n\t\t\t\t\t\tif (request.configId === Config.MODEL) {\n\t\t\t\t\t\t\tconst model = Option.getOrUndefined(Config.parseModel(value));\n\t\t\t\t\t\t\tif (model === undefined || !(yield* Config.known(model, hostDir))) {\n\t\t\t\t\t\t\t\treturn yield* Agent.RequestError.invalidParams(`Unknown model: ${value}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\truntime = { model };\n\t\t\t\t\t\t} else if (request.configId === Config.THOUGHT_LEVEL) {\n\t\t\t\t\t\t\tif (!Config.isThinkingLevel(value)) {\n\t\t\t\t\t\t\t\treturn yield* Agent.RequestError.invalidParams(`Unknown thinking level: ${value}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\truntime = { thinkingLevel: value };\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn yield* Agent.RequestError.invalidParams(`Unknown config option: ${request.configId}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst thread = yield* Session.attach({ sessionId: session.id, threadId, ...runtime });\n\t\t\t\t\t\treturn { configOptions: yield* Config.options(yield* Session.configuration(thread.id), hostDir) };\n\t\t\t\t\t}),\n\t\t\t\t),\n\n\t\t\tprompt: ({ sessionId: id, prompt }) =>\n\t\t\t\trun(\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tconst parts = yield* promptParts(prompt);\n\t\t\t\t\t\tconst { thread: handle } = yield* attach(id);\n\t\t\t\t\t\t// Keyed by thread: main answers to its session id and its own thread id alike.\n\t\t\t\t\t\tif (running.has(handle.id)) {\n\t\t\t\t\t\t\treturn yield* Agent.RequestError.invalidRequest(\"A prompt is already running for this session\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\trunning.add(handle.id);\n\t\t\t\t\t\tyield* Effect.addFinalizer(() => Effect.sync(() => running.delete(handle.id)));\n\n\t\t\t\t\t\t// Forward this execution's updates until it settles; the settling event decides the answer.\n\t\t\t\t\t\tlet reason: EventList.LLMEnded[\"data\"][\"reason\"] | undefined;\n\t\t\t\t\t\t// Plugins are checked every exchange; tell the user about each failure once per prompt.\n\t\t\t\t\t\tconst notices = new Set<string>();\n\t\t\t\t\t\tconst settled = yield* handle.events().pipe(\n\t\t\t\t\t\t\tStream.tap((event) => {\n\t\t\t\t\t\t\t\tif (isLLMEnded(event)) reason = event.data.reason;\n\t\t\t\t\t\t\t\tlet update = Feed.update(event);\n\t\t\t\t\t\t\t\tconst notice = Feed.notice(event);\n\t\t\t\t\t\t\t\tif (Option.isSome(notice) && !notices.has(notice.value)) {\n\t\t\t\t\t\t\t\t\tnotices.add(notice.value);\n\t\t\t\t\t\t\t\t\tupdate = Option.some(Feed.noticeUpdate(notice.value));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn Option.match(update, {\n\t\t\t\t\t\t\t\t\tonNone: () => Effect.void,\n\t\t\t\t\t\t\t\t\tonSome: (update) => client.sessionUpdate({ sessionId: id, update }).pipe(Effect.ignore),\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tStream.filter(isSettled),\n\t\t\t\t\t\t\tStream.runHead,\n\t\t\t\t\t\t\tEffect.forkScoped({ startImmediately: true }),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst before = (yield* handle.info).title;\n\t\t\t\t\t\tyield* handle.run({ parts });\n\t\t\t\t\t\tconst end = yield* Fiber.join(settled);\n\n\t\t\t\t\t\t// The harness titles a thread from its first prompt; tell the editor.\n\t\t\t\t\t\tconst { title } = yield* handle.info;\n\t\t\t\t\t\tif (title !== undefined && title !== before) {\n\t\t\t\t\t\t\tyield* client\n\t\t\t\t\t\t\t\t.sessionUpdate({ sessionId: id, update: { sessionUpdate: \"session_info_update\", title } })\n\t\t\t\t\t\t\t\t.pipe(Effect.ignore);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (Option.isNone(end) || isInterrupted(end.value)) return { stopReason: \"cancelled\" as const };\n\t\t\t\t\t\tif (isFailed(end.value)) return yield* Agent.RequestError.internalError(end.value.data.error.message);\n\t\t\t\t\t\treturn { stopReason: reason === \"length\" ? (\"max_tokens\" as const) : (\"end_turn\" as const) };\n\t\t\t\t\t}).pipe(Effect.scoped),\n\t\t\t\t),\n\n\t\t\tcancel: ({ sessionId: id }) =>\n\t\t\t\tresolve(id).pipe(\n\t\t\t\t\tEffect.flatMap((found) => control.interrupt(found.threadId, { reason: \"user\" })),\n\t\t\t\t\tEffect.ignore,\n\t\t\t\t\tEffect.provide(context),\n\t\t\t\t),\n\t\t};\n\t};\n});\n\nexport * as Handlers from \"./handlers.ts\";\n","import { Control, Harness, Sandbox } from \"@codeworksh/harness/effect\";\nimport { Effect, Logger, Stdio } from \"effect\";\nimport { Agent } from \"./agent.ts\";\nimport { Handlers } from \"./handlers.ts\";\n\n// Sessions and managed sandboxes outlive any single request; the connection's end is what stops them.\nconst shutdown = Effect.gen(function* () {\n\tconst control = yield* Control.Service;\n\tyield* Effect.forEach(\n\t\tyield* control.active,\n\t\t(id) =>\n\t\t\tcontrol\n\t\t\t\t.interrupt(id, { reason: \"shutdown\", awaitSettlement: true })\n\t\t\t\t.pipe(Effect.timeout(\"10 seconds\"), Effect.ignore),\n\t\t{ concurrency: \"unbounded\", discard: true },\n\t);\n\tconst managed = (yield* Sandbox.list()).filter((info) => info.ownership === \"managed\");\n\tyield* Effect.forEach(\n\t\tmanaged,\n\t\t(info) =>\n\t\t\tSandbox.stop(info.id).pipe(\n\t\t\t\tEffect.timeout(\"10 seconds\"),\n\t\t\t\tEffect.catchCause((cause) =>\n\t\t\t\t\tEffect.logError(\"Failed to stop managed sandbox during ACP shutdown\", cause).pipe(\n\t\t\t\t\t\tEffect.annotateLogs({ sandboxInstanceId: info.id }),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t),\n\t\t{ concurrency: \"unbounded\", discard: true },\n\t);\n});\n\n/**\n * Serves ACP v1 on stdio until the client disconnects.\n *\n * stdout carries the protocol, so logs go to stderr. The reference is set outside the harness layer\n * so the fibers it forks (turns, plugin loads) inherit it too.\n */\nexport const serve = (options: Harness.Options) =>\n\tEffect.gen(function* () {\n\t\tyield* Effect.addFinalizer(() => shutdown.pipe(Effect.ignore));\n\t\tconst handlers = yield* Handlers.make;\n\t\tyield* Agent.serve(yield* Stdio.Stdio, handlers);\n\t}).pipe(Effect.scoped, Effect.provide(Harness.layer(options)), Effect.provideService(Logger.LogToStderr, true));\n\nexport * as Server from \"./server.ts\";\n","import { Effect } from \"effect\";\nimport { Server } from \"../../../acp/server.ts\";\nimport { Runtime } from \"../../../framework/runtime.ts\";\nimport { reportFailure } from \"../../error.ts\";\nimport { harnessOptions } from \"../../harness.ts\";\nimport { Cmd } from \"../cmd.ts\";\n\nexport default Runtime.handler(\n\tCmd.commands.acp,\n\tEffect.fn(\"CLI.acp\", { level: \"Info\" })(function* () {\n\t\tconst shared = yield* Cmd.spec;\n\t\treturn yield* Server.serve(harnessOptions(shared)).pipe(Effect.catch(reportFailure));\n\t}),\n);\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as version } from "./package-
|
|
1
|
+
import { t as version } from "./package-C0VOpey-.mjs";
|
|
2
2
|
import { Context, Effect, FileSystem, Layer, Option, Path, Schedule, Schema } from "effect";
|
|
3
3
|
import { isSea } from "node:sea";
|
|
4
4
|
//#region src/server/registration.ts
|
|
@@ -89,4 +89,4 @@ const layer = Layer.succeed(Service, Service.of(current));
|
|
|
89
89
|
//#endregion
|
|
90
90
|
export { file as a, register as c, command as i, current as n, infoJson as o, layer as r, log as s, Service as t };
|
|
91
91
|
|
|
92
|
-
//# sourceMappingURL=identity-
|
|
92
|
+
//# sourceMappingURL=identity-CQBhON8m.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity-
|
|
1
|
+
{"version":3,"file":"identity-CQBhON8m.mjs","names":["pkg.version"],"sources":["../../src/server/registration.ts","../../src/server/identity.ts"],"sourcesContent":["import { Effect, FileSystem, Layer, Option, Path, Schedule, Schema } from \"effect\";\nimport { isSea } from \"node:sea\";\n\n/**\n * How a running server advertises itself so later invocations can find it\n * without scanning ports or the process table.\n *\n * The file is a discovery hint, never proof: a caller reads it for the endpoint,\n * then asks the endpoint `server.info` and believes the answer only when the\n * live pid and version match the ones on file. A crashed server leaves a\n * registration behind; the failed probe is what retires it.\n */\nexport const Info = Schema.Struct({\n\t/** Operating system process identifier of the server that wrote this. */\n\tpid: Schema.Int,\n\t/** The build serving this endpoint; a mismatch means a different binary. */\n\tversion: Schema.String,\n\t/** The `ws://host:port/rpc/v1` endpoint a client connects to. */\n\turl: Schema.String,\n\t/** The TCP port the server bound, for a caller that would rather reuse it than default. */\n\tport: Schema.Int,\n});\nexport type Info = typeof Info.Type;\n\nexport const infoJson = Schema.fromJsonString(Info);\n\n/** The registration file for a CodeWork home: `<home>/service.json`. */\nexport const file = (home: string) => `${home}/service.json`;\n\n/** Where a background (`serve --service`) server writes its log: `<log>/server.log`, truncated per start. */\nexport const log = (logDir: string) => `${logDir}/server.log`;\n\nconst decode = Schema.decodeUnknownEffect(infoJson);\n\nexport const write = Effect.fn(\"ServerRegistration.write\")(function* (path: string, info: Info) {\n\tconst fs = yield* FileSystem.FileSystem;\n\tconst paths = yield* Path.Path;\n\tyield* fs.makeDirectory(paths.dirname(path), { recursive: true });\n\tconst encoded = yield* Schema.encodeEffect(infoJson)(info);\n\t// Write beside the target and rename, so a reader never sees a half-written\n\t// file. 0600 because a future registration may carry a credential.\n\tconst temp = `${path}.${info.pid}.tmp`;\n\tyield* fs.writeFileString(temp, encoded, { mode: 0o600 });\n\tyield* fs.rename(temp, path);\n});\n\n/**\n * Publishes a registration for as long as this server lives, removing it on the\n * way out if it is still the one on file. A file left by a crash is overwritten\n * by the next server to start, and retired by a probe that cannot confirm it.\n *\n * One home has one discoverable server. Every few seconds the file is checked:\n * a missing or unreadable file is written again, and a file naming another\n * server means this one lost discovery for good, so it shuts down rather than\n * run on where nothing can find or stop it.\n */\nexport const register = (options: { readonly home: string; readonly info: Info }) =>\n\tLayer.effectDiscard(\n\t\tEffect.gen(function* () {\n\t\t\tconst path = file(options.home);\n\t\t\tconst fs = yield* FileSystem.FileSystem;\n\t\t\tconst current = fs.readFileString(path).pipe(Effect.flatMap(decode), Effect.option);\n\t\t\tconst owns = (found: Info) => found.pid === options.info.pid && found.url === options.info.url;\n\n\t\t\tyield* write(path, options.info);\n\t\t\tyield* Effect.addFinalizer(() =>\n\t\t\t\tcurrent.pipe(\n\t\t\t\t\tEffect.flatMap((found) => (Option.isSome(found) && owns(found.value) ? fs.remove(path) : Effect.void)),\n\t\t\t\t\tEffect.ignore,\n\t\t\t\t),\n\t\t\t);\n\t\t\t// Forked after the finalizer, so shutdown stops the watch before the file is removed.\n\t\t\tyield* current.pipe(\n\t\t\t\tEffect.flatMap((found) =>\n\t\t\t\t\tOption.isNone(found)\n\t\t\t\t\t\t? write(path, options.info).pipe(Effect.ignore, Effect.as(true))\n\t\t\t\t\t\t: Effect.succeed(owns(found.value)),\n\t\t\t\t),\n\t\t\t\tEffect.repeat({ while: (ours) => ours, schedule: Schedule.spaced(\"5 seconds\") }),\n\t\t\t\tEffect.andThen(Effect.logWarning(`${path} names another server; shutting down`)),\n\t\t\t\t// The same graceful path `codework service stop` takes.\n\t\t\t\tEffect.andThen(Effect.sync(() => process.kill(process.pid, \"SIGTERM\"))),\n\t\t\t\tEffect.forkScoped,\n\t\t\t);\n\t\t}),\n\t);\n\n/**\n * The launcher command for a managed server: this same CLI, asked to serve.\n *\n * A packaged install runs `dist/pack/index.mjs`; under `--conditions=development`\n * the entry is TypeScript, and `process.execArgv` carries the conditions forward\n * so a managed server resolves workspace sources the same way this process did.\n * The standalone binary is its own entry.\n */\nexport const command = (): ReadonlyArray<string> => {\n\tif (isSea()) return [process.execPath];\n\tconst entry = process.argv[1];\n\tif (entry === undefined) return [process.execPath];\n\tconst runtime = import.meta.url.endsWith(\".ts\") ? process.execArgv : [];\n\treturn [process.execPath, ...runtime, entry];\n};\n\nexport * as Registration from \"./registration.ts\";\n","import { Context, Layer } from \"effect\";\nimport pkg from \"../../package.json\" with { type: \"json\" };\n\n/**\n * What a running server is, as its clients need to know it.\n *\n * A discovery registration names the pid and version it wrote; `server.info`\n * answers with the live ones so a caller can tell the process it reached is the\n * one that registered rather than a different server that took the same port.\n */\nexport interface Interface {\n\treadonly pid: number;\n\treadonly version: string;\n}\n\nexport class Service extends Context.Service<Service, Interface>()(\"@codeworksh/cli/server/identity/Service\") {}\n\n/** This process: a server answers with it, a client compares a server's version against it. */\nexport const current: Interface = { pid: process.pid, version: pkg.version };\n\nexport const layer = Layer.succeed(Service, Service.of(current));\n\nexport * as Identity from \"./identity.ts\";\n"],"mappings":";;;;;;;;;;;;;AAYA,MAAa,OAAO,OAAO,OAAO;;CAEjC,KAAK,OAAO;;CAEZ,SAAS,OAAO;;CAEhB,KAAK,OAAO;;CAEZ,MAAM,OAAO;AACd,CAAC;AAGD,MAAa,WAAW,OAAO,eAAe,IAAI;;AAGlD,MAAa,QAAQ,SAAiB,GAAG,KAAK;;AAG9C,MAAa,OAAO,WAAmB,GAAG,OAAO;AAEjD,MAAM,SAAS,OAAO,oBAAoB,QAAQ;AAElD,MAAa,QAAQ,OAAO,GAAG,0BAA0B,CAAC,CAAC,WAAW,MAAc,MAAY;CAC/F,MAAM,KAAK,OAAO,WAAW;CAC7B,MAAM,QAAQ,OAAO,KAAK;CAC1B,OAAO,GAAG,cAAc,MAAM,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;CAChE,MAAM,UAAU,OAAO,OAAO,aAAa,QAAQ,CAAC,CAAC,IAAI;CAGzD,MAAM,OAAO,GAAG,KAAK,GAAG,KAAK,IAAI;CACjC,OAAO,GAAG,gBAAgB,MAAM,SAAS,EAAE,MAAM,IAAM,CAAC;CACxD,OAAO,GAAG,OAAO,MAAM,IAAI;AAC5B,CAAC;;;;;;;;;;;AAYD,MAAa,YAAY,YACxB,MAAM,cACL,OAAO,IAAI,aAAa;CACvB,MAAM,OAAO,KAAK,QAAQ,IAAI;CAC9B,MAAM,KAAK,OAAO,WAAW;CAC7B,MAAM,UAAU,GAAG,eAAe,IAAI,CAAC,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG,OAAO,MAAM;CAClF,MAAM,QAAQ,UAAgB,MAAM,QAAQ,QAAQ,KAAK,OAAO,MAAM,QAAQ,QAAQ,KAAK;CAE3F,OAAO,MAAM,MAAM,QAAQ,IAAI;CAC/B,OAAO,OAAO,mBACb,QAAQ,KACP,OAAO,SAAS,UAAW,OAAO,OAAO,KAAK,KAAK,KAAK,MAAM,KAAK,IAAI,GAAG,OAAO,IAAI,IAAI,OAAO,IAAK,GACrG,OAAO,MACR,CACD;CAEA,OAAO,QAAQ,KACd,OAAO,SAAS,UACf,OAAO,OAAO,KAAK,IAChB,MAAM,MAAM,QAAQ,IAAI,CAAC,CAAC,KAAK,OAAO,QAAQ,OAAO,GAAG,IAAI,CAAC,IAC7D,OAAO,QAAQ,KAAK,MAAM,KAAK,CAAC,CACpC,GACA,OAAO,OAAO;EAAE,QAAQ,SAAS;EAAM,UAAU,SAAS,OAAO,WAAW;CAAE,CAAC,GAC/E,OAAO,QAAQ,OAAO,WAAW,GAAG,KAAK,qCAAqC,CAAC,GAE/E,OAAO,QAAQ,OAAO,WAAW,QAAQ,KAAK,QAAQ,KAAK,SAAS,CAAC,CAAC,GACtE,OAAO,UACR;AACD,CAAC,CACF;;;;;;;;;AAUD,MAAa,gBAAuC;CACnD,IAAI,MAAM,GAAG,OAAO,CAAC,QAAQ,QAAQ;CACrC,MAAM,QAAQ,QAAQ,KAAK;CAC3B,IAAI,UAAU,KAAA,GAAW,OAAO,CAAC,QAAQ,QAAQ;CACjD,MAAM,UAAU,YAAY,IAAI,SAAS,KAAK,IAAI,QAAQ,WAAW,CAAC;CACtE,OAAO;EAAC,QAAQ;EAAU,GAAG;EAAS;CAAK;AAC5C;;;ACtFA,IAAa,UAAb,cAA6B,QAAQ,QAA4B,CAAC,CAAC,yCAAyC,CAAC,CAAC,CAAC;;AAG/G,MAAa,UAAqB;CAAE,KAAK,QAAQ;CAAcA;AAAY;AAE3E,MAAa,QAAQ,MAAM,QAAQ,SAAS,QAAQ,GAAG,OAAO,CAAC"}
|
package/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as version } from "./package-
|
|
2
|
+
import { t as version } from "./package-C0VOpey-.mjs";
|
|
3
3
|
import { i as Cmd, n as handlers, r as run } from "./runtime-CwoLsQy7.mjs";
|
|
4
4
|
import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
|
|
5
5
|
import * as NodeServices from "@effect/platform-node/NodeServices";
|
|
@@ -22,13 +22,13 @@ const Handlers = handlers(Cmd, {
|
|
|
22
22
|
disconnect: () => import("./disconnect-Dpt7LKVl.mjs")
|
|
23
23
|
},
|
|
24
24
|
run: () => import("./run-B3acSsVy.mjs"),
|
|
25
|
-
tui: () => import("./tui-
|
|
26
|
-
serve: () => import("./serve-
|
|
25
|
+
tui: () => import("./tui-CGVqTA8q.mjs"),
|
|
26
|
+
serve: () => import("./serve-Ce8hdWM6.mjs"),
|
|
27
27
|
service: {
|
|
28
|
-
start: () => import("./start-
|
|
29
|
-
restart: () => import("./restart-
|
|
30
|
-
status: () => import("./status-
|
|
31
|
-
stop: () => import("./stop-
|
|
28
|
+
start: () => import("./start-hJJLd1ap.mjs"),
|
|
29
|
+
restart: () => import("./restart-YOXYSZ_i.mjs"),
|
|
30
|
+
status: () => import("./status-Bp8vjjW9.mjs"),
|
|
31
|
+
stop: () => import("./stop-C2PWKdVX.mjs")
|
|
32
32
|
},
|
|
33
33
|
session: {
|
|
34
34
|
link: () => import("./link-BilIb5jN.mjs"),
|
|
@@ -38,7 +38,7 @@ const Handlers = handlers(Cmd, {
|
|
|
38
38
|
list: () => import("./list-BdMdlBjQ.mjs"),
|
|
39
39
|
fork: () => import("./fork-BtL-68qs.mjs")
|
|
40
40
|
},
|
|
41
|
-
acp: () => import("./acp-
|
|
41
|
+
acp: () => import("./acp-BeDi6jEL.mjs"),
|
|
42
42
|
plugin: {
|
|
43
43
|
add: () => import("./add-fJlj0O2v.mjs"),
|
|
44
44
|
check: () => import("./check-7oL3UVdX.mjs"),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-C0VOpey-.mjs","names":[],"sources":["../../package.json"],"sourcesContent":[""],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codeworksh/cli",
|
|
3
|
-
"version": "0.5.0-canary.
|
|
3
|
+
"version": "0.5.0-canary.90.1.gec09b058",
|
|
4
4
|
"description": "CLI for running CodeWork coding agent harness.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@agentclientprotocol/sdk": "1.5.1",
|
|
43
|
-
"@codeworksh/aikit": "0.12.1-canary.
|
|
44
|
-
"@codeworksh/harness": "0.5.0-canary.
|
|
45
|
-
"@codeworksh/tui": "0.1.0-canary.
|
|
43
|
+
"@codeworksh/aikit": "0.12.1-canary.90.1.gec09b058",
|
|
44
|
+
"@codeworksh/harness": "0.5.0-canary.90.1.gec09b058",
|
|
45
|
+
"@codeworksh/tui": "0.1.0-canary.90.1.gec09b058",
|
|
46
46
|
"@effect/platform-node": "4.0.5",
|
|
47
47
|
"@effect/platform-node-shared": "4.0.5",
|
|
48
48
|
"effect": "4.0.5",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i as Cmd, t as handler } from "./runtime-CwoLsQy7.mjs";
|
|
2
2
|
import { f as writeOut, i as reportFailure } from "./error-BVSfzBzb.mjs";
|
|
3
|
-
import { i as ensure, n as options, o as stop } from "./service-
|
|
3
|
+
import { i as ensure, n as options, o as stop } from "./service-BQdaO_Ap.mjs";
|
|
4
4
|
import { Effect } from "effect";
|
|
5
5
|
//#region src/cli/cmd/handlers/service/restart.ts
|
|
6
6
|
var restart_default = handler(Cmd.commands.service.commands.restart, Effect.fn("CLI.service.restart")(function* ({ host, port }) {
|
|
@@ -18,4 +18,4 @@ var restart_default = handler(Cmd.commands.service.commands.restart, Effect.fn("
|
|
|
18
18
|
//#endregion
|
|
19
19
|
export { restart_default as default };
|
|
20
20
|
|
|
21
|
-
//# sourceMappingURL=restart-
|
|
21
|
+
//# sourceMappingURL=restart-YOXYSZ_i.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"restart-
|
|
1
|
+
{"version":3,"file":"restart-YOXYSZ_i.mjs","names":["Runtime.handler","options","Service.options","Discovery.stop","Discovery.ensure"],"sources":["../../src/cli/cmd/handlers/service/restart.ts"],"sourcesContent":["import { Effect } from \"effect\";\nimport { Runtime } from \"../../../../framework/runtime.ts\";\nimport { Discovery } from \"../../../../server/discovery.ts\";\nimport { reportFailure } from \"../../../error.ts\";\nimport { writeOut } from \"../../../output.ts\";\nimport { Service } from \"../../../service.ts\";\nimport { Cmd } from \"../../cmd.ts\";\n\nexport default Runtime.handler(\n\tCmd.commands.service.commands.restart,\n\tEffect.fn(\"CLI.service.restart\")(function* ({ host, port }) {\n\t\tconst options = yield* Service.options(yield* Cmd.spec, { host, port });\n\t\tyield* Discovery.stop(options.home);\n\t\tconst server = yield* Discovery.ensure({ ...options, replace: true });\n\t\tyield* writeOut(`${server.url}\\n`);\n\t}, Effect.catch(reportFailure)),\n);\n"],"mappings":";;;;;AAQA,IAAA,kBAAeA,QACd,IAAI,SAAS,QAAQ,SAAS,SAC9B,OAAO,GAAG,qBAAqB,CAAC,CAAC,WAAW,EAAE,MAAM,QAAQ;CAC3D,MAAMC,YAAU,OAAOC,QAAgB,OAAO,IAAI,MAAM;EAAE;EAAM;CAAK,CAAC;CACtE,OAAOC,KAAeF,UAAQ,IAAI;CAClC,MAAM,SAAS,OAAOG,OAAiB;EAAE,GAAGH;EAAS,SAAS;CAAK,CAAC;CACpE,OAAO,SAAS,GAAG,OAAO,IAAI,GAAG;AAClC,GAAG,OAAO,MAAM,aAAa,CAAC,CAC/B"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { i as Cmd, t as handler } from "./runtime-CwoLsQy7.mjs";
|
|
2
2
|
import { C as encode, S as Core, _ as OAuthError, b as decode, g as Api, r as renderError, u as writeError, w as ofThread, x as Connected, y as path } from "./error-BVSfzBzb.mjs";
|
|
3
3
|
import { t as harnessOptions } from "./harness-6d8TlAVk.mjs";
|
|
4
|
-
import { c as register, r as layer$4, s as log, t as Service$2 } from "./identity-
|
|
4
|
+
import { c as register, r as layer$4, s as log, t as Service$2 } from "./identity-CQBhON8m.mjs";
|
|
5
5
|
import { Cause, Context, DateTime, Effect, FileSystem, Layer, Logger, Option, Queue, Schema, Stream } from "effect";
|
|
6
6
|
import { Model } from "@codeworksh/aikit";
|
|
7
7
|
import { HttpRouter, HttpServer } from "effect/http";
|
|
@@ -485,4 +485,4 @@ var serve_default = handler(Cmd.commands.serve, Effect.fn("CLI.serve", { level:
|
|
|
485
485
|
//#endregion
|
|
486
486
|
export { serve_default as default };
|
|
487
487
|
|
|
488
|
-
//# sourceMappingURL=serve-
|
|
488
|
+
//# sourceMappingURL=serve-Ce8hdWM6.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve-C_RqXAJO.mjs","names":["Service","Envelope.Core","Envelope.encode","layer","layer","Contract.OAuthError","Envelope.encode","layer","EventFeed.Service","OAuth.Service","Identity.Service","Envelope.ofThread","MessagePart.decode","Identity.Service","Contract.path","Registration.register","Contract.Api","EventFeed.layer","OAuth.layer","Identity.layer","Runtime.handler","Server.layer","Registration.log"],"sources":["../../src/server/feed.ts","../../src/server/oauth.ts","../../src/server/handlers.ts","../../src/server/server.ts","../../src/cli/cmd/handlers/serve.ts"],"sourcesContent":["import { Event, EventRegistry, EventSchema } from \"@codeworksh/harness/effect\";\nimport { Cause, Context, Effect, Layer, Queue, Scope, Stream } from \"effect\";\nimport { EncodingError, type EventEnvelope, Envelope } from \"./envelope.ts\";\n\nexport const SubscriberCapacity = 4096;\n\nexport type Error = Event.SubscriptionOverflowError | EncodingError;\n\nexport interface Interface {\n\t/** A live envelope stream for one client; releasing the scope unregisters it. */\n\treadonly subscribe: Effect.Effect<Stream.Stream<EventEnvelope, Error>, never, Scope.Scope>;\n}\n\nexport class Service extends Context.Service<Service, Interface>()(\"@codeworksh/cli/server/feed/Service\") {}\n\n/**\n * Fan-out for `event.subscribe`. One listener on the event bus encodes each\n * event once and hands the same envelope to every client, rather than every\n * client re-encoding the same payload.\n *\n * Failure is per-cause, not per-feed: a client that cannot keep up fails alone\n * with its own overflow, while an event that cannot be encoded is a server bug\n * that disconnects everyone currently attached -- the feed stays usable for\n * whoever connects next. Types outside the server's registry are dropped\n * before they can consume a client's capacity.\n */\nexport const make = Effect.fn(\"EventFeed.make\")(function* (\n\tlisten: (subscriber: Event.Subscriber) => Effect.Effect<Event.Unsubscribe>,\n\toptions?: { readonly capacity?: number; readonly registry?: Envelope.Registry },\n) {\n\tconst capacity = options?.capacity ?? SubscriberCapacity;\n\t// Whatever this server knows how to describe, plugin registrations included.\n\tconst registry = options?.registry ?? Envelope.Core;\n\tconst subscribers = new Set<Queue.Queue<EventEnvelope, Error>>();\n\n\tconst failAll = (error: Error) =>\n\t\tEffect.sync(() => {\n\t\t\tconst current = Array.from(subscribers);\n\t\t\tsubscribers.clear();\n\t\t\tfor (const subscriber of current) Queue.failCauseUnsafe(subscriber, Cause.fail(error));\n\t\t});\n\n\tconst deliver = Effect.fnUntraced(function* (event: EventSchema.Payload) {\n\t\tif (subscribers.size === 0) return;\n\t\t// Dropped here rather than after the queue: a burst of events this server\n\t\t// cannot describe must not spend a client's capacity on its way to nowhere.\n\t\tif (registry(event.type) === undefined) return;\n\t\tconst envelope = yield* Envelope.encode(event, registry);\n\t\tfor (const subscriber of subscribers) {\n\t\t\tif (Queue.offerUnsafe(subscriber, envelope)) continue;\n\t\t\tsubscribers.delete(subscriber);\n\t\t\tQueue.failCauseUnsafe(subscriber, Cause.fail(new Event.SubscriptionOverflowError({ capacity })));\n\t\t}\n\t});\n\n\tconst publish = (event: EventSchema.Payload) =>\n\t\tdeliver(event).pipe(\n\t\t\tEffect.catchTags({\n\t\t\t\tEventEncodingError: (error) =>\n\t\t\t\t\tEffect.logError(\"Failed to encode public event\", { type: error.type, cause: error.cause }).pipe(\n\t\t\t\t\t\tEffect.andThen(failAll(error)),\n\t\t\t\t\t),\n\t\t\t\t// The registry guard in `deliver` already returned for unknown types.\n\t\t\t\tUnknownEventTypeError: Effect.die,\n\t\t\t}),\n\t\t);\n\n\tconst unsubscribe = yield* listen(publish);\n\tyield* Effect.addFinalizer(() => unsubscribe);\n\n\treturn Service.of({\n\t\tsubscribe: Effect.acquireRelease(\n\t\t\tQueue.dropping<EventEnvelope, Error>(capacity).pipe(\n\t\t\t\tEffect.tap((queue) => Effect.sync(() => subscribers.add(queue))),\n\t\t\t),\n\t\t\t(queue) => Effect.sync(() => subscribers.delete(queue)).pipe(Effect.andThen(Queue.shutdown(queue))),\n\t\t).pipe(Effect.map(Stream.fromQueue)),\n\t});\n});\n\nexport const layer = Layer.effect(\n\tService,\n\tEffect.gen(function* () {\n\t\tconst events = yield* Event.Service;\n\t\tconst registered = yield* EventRegistry.Service;\n\t\treturn yield* make(events.listen, { registry: registered.get });\n\t}),\n);\n\nexport * as EventFeed from \"./feed.ts\";\n","/**\n * Server-side OAuth credential storage.\n *\n * The CLI runs the interactive part of every login locally — a browser\n * callback or a device code cannot travel over RPC — and sends the resulting\n * credentials here, so this service only ever reads, writes, refreshes and\n * clears the server home's `auth.json`.\n */\nimport {\n\tGitHubCopilotOAuthClient,\n\tJsonGitHubCopilotAuthStorage,\n\ttype GitHubCopilotOAuthCredentials,\n} from \"@codeworksh/aikit/oauth/github/copilot\";\nimport {\n\tJsonOpenAICodexAuthStorage,\n\tOpenAICodexOAuthClient,\n\ttype OpenAICodexOAuthCredentials,\n} from \"@codeworksh/aikit/oauth/openai/codex\";\nimport { summarizeGitHubCopilot, summarizeOpenAICodex } from \"@codeworksh/aikit/oauth/summary\";\nimport { Global } from \"@codeworksh/harness/effect\";\nimport { Context, Effect, Layer } from \"effect\";\nimport { Contract } from \"./contract.ts\";\n\ninterface Interface {\n\treadonly save: (credentials: Contract.OAuthCredentials) => Effect.Effect<Contract.OAuthInfo, Contract.OAuthError>;\n\treadonly status: (provider: Contract.OAuthProvider) => Effect.Effect<Contract.OAuthInfo | null, Contract.OAuthError>;\n\treadonly refresh: (\n\t\tprovider: Contract.OAuthProvider,\n\t) => Effect.Effect<Contract.OAuthInfo | null, Contract.OAuthError>;\n\treadonly logout: (provider: Contract.OAuthProvider) => Effect.Effect<void, Contract.OAuthError>;\n}\n\nexport class Service extends Context.Service<Service, Interface>()(\"@codeworksh/cli/server/oauth/Service\") {}\n\nconst message = (cause: unknown): string =>\n\tcause instanceof Error && cause.message.trim().length > 0 ? cause.message : String(cause);\n\n/**\n * Re-exported so the server, the CLI and aikit all describe a login the same\n * way; `Contract.OAuthInfo` is the wire shape of {@link OAuthSummary}.\n */\nexport const codexInfo = summarizeOpenAICodex;\nexport const copilotInfo = summarizeGitHubCopilot;\n\nexport const layer = (options: { readonly home?: string | undefined } = {}) =>\n\tLayer.effect(\n\t\tService,\n\t\tEffect.gen(function* () {\n\t\t\tconst global = yield* Global.Service;\n\t\t\tconst authFile = Global.authFile(options.home === undefined ? undefined : global.home);\n\t\t\tconst file = authFile === undefined ? {} : { path: authFile };\n\t\t\tconst codex = new OpenAICodexOAuthClient({ storage: new JsonOpenAICodexAuthStorage(file) });\n\t\t\tconst copilot = new GitHubCopilotOAuthClient({ storage: new JsonGitHubCopilotAuthStorage(file) });\n\t\t\tconst attempt = <A>(run: () => Promise<A>) =>\n\t\t\t\tEffect.tryPromise({\n\t\t\t\t\ttry: run,\n\t\t\t\t\tcatch: (cause) => new Contract.OAuthError({ message: message(cause) }),\n\t\t\t\t});\n\t\t\tconst optional = <A>(run: () => Promise<A | undefined>, info: (value: A) => Contract.OAuthInfo) =>\n\t\t\t\tattempt(run).pipe(Effect.map((value) => (value === undefined ? null : info(value))));\n\n\t\t\treturn Service.of({\n\t\t\t\t// The `provider` tag is routing, not a credential: it never reaches disk.\n\t\t\t\tsave: (wire) => {\n\t\t\t\t\tif (wire.provider === \"openai-codex\") {\n\t\t\t\t\t\tconst credentials: OpenAICodexOAuthCredentials = {\n\t\t\t\t\t\t\taccess: wire.access,\n\t\t\t\t\t\t\trefresh: wire.refresh,\n\t\t\t\t\t\t\texpires: wire.expires,\n\t\t\t\t\t\t\taccountId: wire.accountId,\n\t\t\t\t\t\t};\n\t\t\t\t\t\treturn attempt(() => codex.storage.set(credentials)).pipe(Effect.as(codexInfo(credentials)));\n\t\t\t\t\t}\n\t\t\t\t\tconst credentials: GitHubCopilotOAuthCredentials = {\n\t\t\t\t\t\taccess: wire.access,\n\t\t\t\t\t\trefresh: wire.refresh,\n\t\t\t\t\t\texpires: wire.expires,\n\t\t\t\t\t\t...(wire.enterpriseUrl === undefined ? {} : { enterpriseUrl: wire.enterpriseUrl }),\n\t\t\t\t\t\t...(wire.apiEndpoint === undefined ? {} : { apiEndpoint: wire.apiEndpoint }),\n\t\t\t\t\t\t...(wire.availableModelIds === undefined ? {} : { availableModelIds: [...wire.availableModelIds] }),\n\t\t\t\t\t};\n\t\t\t\t\treturn attempt(() => copilot.storage.set(credentials)).pipe(Effect.as(copilotInfo(credentials)));\n\t\t\t\t},\n\t\t\t\tstatus: (provider) =>\n\t\t\t\t\tprovider === \"openai-codex\"\n\t\t\t\t\t\t? optional(() => codex.storage.get(), codexInfo)\n\t\t\t\t\t\t: optional(() => copilot.storage.get(), copilotInfo),\n\t\t\t\t// GitHub OAuth tokens never expire, so a Copilot \"refresh\" is a read.\n\t\t\t\trefresh: (provider) =>\n\t\t\t\t\tprovider === \"openai-codex\"\n\t\t\t\t\t\t? optional(() => codex.getCredentials(), codexInfo)\n\t\t\t\t\t\t: optional(() => copilot.getCredentials(), copilotInfo),\n\t\t\t\tlogout: (provider) => attempt(() => (provider === \"openai-codex\" ? codex.logout() : copilot.logout())),\n\t\t\t});\n\t\t}),\n\t);\n\nexport * as OAuth from \"./oauth.ts\";\n","import { Model } from \"@codeworksh/aikit\";\nimport {\n\tControl,\n\tEvent,\n\tEventList,\n\tEventRegistry,\n\tEventSchema,\n\tMcp,\n\tModelCatalog,\n\tProject,\n\tPromptSchema,\n\tSandbox,\n\tSession,\n\tSessionStore,\n\tSettings,\n\tState,\n\tThreadSchema,\n\tThreadStore,\n} from \"@codeworksh/harness/effect\";\nimport { DateTime, Effect, Option, Schema, Stream } from \"effect\";\nimport {\n\tContract,\n\ttype HistoryEntry,\n\ttype LogSynced,\n\ttype RuntimeConfig,\n\ttype SandboxInfo,\n\ttype SessionInfo,\n\ttype ThreadInfo,\n} from \"./contract.ts\";\nimport { type EncodingError, Envelope, type EventEnvelope } from \"./envelope.ts\";\nimport { EventFeed } from \"./feed.ts\";\nimport { Identity } from \"./identity.ts\";\nimport { OAuth } from \"./oauth.ts\";\nimport { MessagePart } from \"./part.ts\";\n\nconst toSandboxInfo = (info: Sandbox.Info): SandboxInfo => ({\n\tid: info.id,\n\tdriver: info.driver,\n\tkind: info.kind,\n\tproviderResourceId: info.providerResourceId,\n\townership: info.ownership,\n\tstatus: info.status,\n\tusage: info.usage,\n\trefCount: info.refCount,\n\tcreatedAt: info.createdAt,\n\tupdatedAt: info.updatedAt,\n});\n\nconst toSessionInfo = (info: Session.Info): SessionInfo => ({\n\tid: info.id,\n\tdirectory: info.directory,\n\t...(info.hostDir === undefined ? {} : { hostDir: info.hostDir }),\n\t...(info.sandbox === undefined ? {} : { sandbox: toSandboxInfo(info.sandbox) }),\n\t...(info.project === undefined ? {} : { project: info.project }),\n\tupdatedAt: info.updatedAt,\n\tmainThreadId: info.mainThreadId,\n});\n\nconst toThreadInfo = (info: Session.ThreadInfo): ThreadInfo => ({\n\tid: info.id,\n\torigin: info.origin,\n\t...(info.title === undefined ? {} : { title: info.title }),\n\tupdatedAt: info.updatedAt,\n\t...(info.model === undefined ? {} : { model: info.model }),\n\t...(info.thinkingLevel === undefined ? {} : { thinkingLevel: info.thinkingLevel }),\n\t...(info.foundation === undefined ? {} : { foundation: info.foundation }),\n\t...(info.placement === undefined ? {} : { placement: info.placement }),\n\tusage: info.usage,\n\tsession: toSessionInfo(info.session),\n});\n\n// Wire configs name only the keys they set, so `undefined` never reaches the harness under\n// exactOptionalPropertyTypes. Creating takes choices only; `null` clears nothing there.\nconst runtimeInput = (runtime: RuntimeConfig | undefined): Session.RuntimeInput => ({\n\t...(runtime?.model == null ? {} : { model: runtime.model }),\n\t...(runtime?.thinkingLevel == null ? {} : { thinkingLevel: runtime.thinkingLevel }),\n\t...(runtime?.foundation == null ? {} : { foundation: runtime.foundation }),\n});\n\n// A failed reply's envelope keeps the provider's reason; it reads as the live failure does.\nconst decodeFailedReply = Schema.decodeUnknownOption(\n\tSchema.fromJsonString(\n\t\tSchema.Struct({\n\t\t\tstopReason: Schema.Literal(\"error\"),\n\t\t\terrorMessage: Schema.String,\n\t\t\tprovider: Schema.Struct({ id: Schema.String }),\n\t\t\tmodel: Schema.String,\n\t\t}),\n\t),\n);\nconst replyError = (data: string) =>\n\tOption.map(decodeFailedReply(data), (reply) => `${reply.provider.id}/${reply.model}: ${reply.errorMessage}`);\n\nconst threadInfo = (threadId: ThreadSchema.ID) => Session.threadInfo(threadId).pipe(Effect.map(toThreadInfo));\n\n// RpcServer's request span has no level, so it is Debug and drops every Info span under it.\n// Provisioning a sandbox is worth exporting, so it starts a trace of its own.\nconst exported = <A, E, R>(name: string, self: Effect.Effect<A, E, R>) =>\n\tself.pipe(Effect.withSpan(name, { level: \"Info\", root: true }));\n\nconst releaseOnFailure = (selection: Effect.Success<ReturnType<typeof Sandbox.resolve>> | undefined) =>\n\tselection?.created && selection.info !== undefined\n\t\t? Sandbox.stop(selection.info.id).pipe(Effect.catchCause(Effect.logError))\n\t\t: Effect.void;\n\n/** A `session.log` item for the wire: a stored event as its envelope, or the replay marker. */\nconst toLogItem =\n\t(registry: Envelope.Registry) =>\n\t(item: Event.LogItem): Effect.Effect<EventEnvelope | LogSynced, EncodingError> =>\n\t\tEvent.isSynced(item)\n\t\t\t? Effect.succeed(item)\n\t\t\t: Envelope.encode(item, registry).pipe(\n\t\t\t\t\t// Every stored type is a kernel durable one, which the registry always knows.\n\t\t\t\t\tEffect.catchTag(\"UnknownEventTypeError\", Effect.die),\n\t\t\t\t);\n\nexport const layer = Contract.Api.toLayer(\n\tEffect.gen(function* () {\n\t\tconst control = yield* Control.Service;\n\t\tconst feed = yield* EventFeed.Service;\n\t\tconst sessions = yield* SessionStore.Service;\n\t\tconst threads = yield* ThreadStore.Service;\n\t\tconst resolve = (ref: Control.ThreadRef) =>\n\t\t\tcontrol.resolve(ref).pipe(Effect.map((thread) => ThreadSchema.ID.make(thread.id)));\n\t\tconst state = yield* State.Service;\n\t\tconst oauth = yield* OAuth.Service;\n\t\tconst identity = yield* Identity.Service;\n\t\tconst events = yield* Event.Service;\n\t\tconst registry = yield* EventRegistry.Service;\n\t\tconst mcp = yield* Mcp.Service;\n\t\tconst mcpControl = (operation: \"connect\" | \"disconnect\") =>\n\t\t\tEffect.fnUntraced(function* ({ server, ...ref }: Control.ThreadRef & { readonly server: string }) {\n\t\t\t\treturn yield* mcp[operation](yield* resolve(ref), server);\n\t\t\t});\n\n\t\treturn Contract.Api.of({\n\t\t\t\"server.info\": () => Effect.succeed({ pid: identity.pid, version: identity.version }),\n\t\t\t\"auth.save\": ({ credentials }) => oauth.save(credentials),\n\t\t\t\"auth.status\": ({ provider }) => oauth.status(provider),\n\t\t\t\"auth.refresh\": ({ provider }) => oauth.refresh(provider),\n\t\t\t\"auth.logout\": ({ provider }) => oauth.logout(provider),\n\t\t\t\"session.create\": Effect.fnUntraced(function* ({ title, directory, hostDir, sandbox, runtime, project }) {\n\t\t\t\tconst selection =\n\t\t\t\t\tsandbox === undefined ? undefined : yield* exported(\"Server.session.create\", Sandbox.resolve(sandbox));\n\t\t\t\tconst selected = selection?.info;\n\t\t\t\tconst handle = yield* Session.create({\n\t\t\t\t\t...(title === undefined ? {} : { title }),\n\t\t\t\t\t...(directory === undefined ? {} : { directory }),\n\t\t\t\t\t// Passed through as given, never defaulted to the server's own directory: a\n\t\t\t\t\t// session the client did not place has no project, which is a normal state.\n\t\t\t\t\t...(hostDir === undefined ? {} : { hostDir }),\n\t\t\t\t\t...(selected === undefined ? {} : { sandbox: selected }),\n\t\t\t\t\t...(project === undefined ? {} : { project }),\n\t\t\t\t\t...runtimeInput(runtime),\n\t\t\t\t}).pipe(Effect.onError(() => releaseOnFailure(selection)));\n\t\t\t\treturn toThreadInfo(yield* handle.main.info);\n\t\t\t}),\n\t\t\t\"model.list\": Effect.fnUntraced(function* ({ hostDir }) {\n\t\t\t\tconst filter = hostDir === undefined ? {} : { hostDir };\n\t\t\t\tconst settings = yield* Settings.Service;\n\t\t\t\tconst loaded = yield* settings.load(hostDir);\n\t\t\t\tconst { model } = loaded;\n\t\t\t\tconst providers = yield* ModelCatalog.available(filter);\n\t\t\t\t// Named from the whole catalog, so a default without credentials still reads as itself.\n\t\t\t\tconst entry = (yield* ModelCatalog.effective(loaded.models))[model.provider]?.[model.id];\n\t\t\t\treturn {\n\t\t\t\t\tproviders: providers.flatMap((provider) => {\n\t\t\t\t\t\tconst models = Object.values(provider.models);\n\t\t\t\t\t\tconst first = models[0];\n\t\t\t\t\t\treturn first === undefined\n\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tid: provider.id,\n\t\t\t\t\t\t\t\t\t\tname: first.provider.name,\n\t\t\t\t\t\t\t\t\t\tmodels: models.map((info) => ({\n\t\t\t\t\t\t\t\t\t\t\tid: info.id,\n\t\t\t\t\t\t\t\t\t\t\tname: info.name,\n\t\t\t\t\t\t\t\t\t\t\tthinkingLevels: Model.getSupportedThinkingLevels(info),\n\t\t\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t];\n\t\t\t\t\t}),\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tprovider: model.provider,\n\t\t\t\t\t\tid: model.id,\n\t\t\t\t\t\tthinkingLevel: model.thinkingLevel,\n\t\t\t\t\t\t...(entry === undefined ? {} : { name: entry.name, providerName: entry.provider.name }),\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}),\n\t\t\t\"project.rename\": Effect.fnUntraced(function* ({ projectId, name }) {\n\t\t\t\tconst renamed = yield* Project.rename({ projectId, name });\n\t\t\t\treturn { id: renamed.id, name: renamed.name };\n\t\t\t}),\n\t\t\t\"plugin.reload\": Effect.fnUntraced(function* () {\n\t\t\t\treturn yield* state.reload;\n\t\t\t}),\n\t\t\t\"session.link\": Effect.fnUntraced(function* ({ sessionId, hostDir }) {\n\t\t\t\tconst handle = yield* Session.link({ sessionId, hostDir: hostDir ?? null });\n\t\t\t\treturn toSessionInfo(yield* handle.info);\n\t\t\t}),\n\t\t\t\"session.relink\": Effect.fnUntraced(function* ({ sessionId, threadId, sandbox, directory }) {\n\t\t\t\tconst selection =\n\t\t\t\t\tsandbox === undefined ? undefined : yield* exported(\"Server.session.relink\", Sandbox.resolve(sandbox));\n\t\t\t\tconst selected = selection?.info;\n\t\t\t\tconst handle = yield* Session.relink({\n\t\t\t\t\tsessionId,\n\t\t\t\t\t...(threadId === undefined ? {} : { threadId }),\n\t\t\t\t\t...(selected === undefined ? {} : { sandbox: selected }),\n\t\t\t\t\t...(directory === undefined ? {} : { directory }),\n\t\t\t\t}).pipe(Effect.onError(() => releaseOnFailure(selection)));\n\t\t\t\tconst thread = yield* handle.thread(threadId ?? ThreadSchema.MAIN);\n\t\t\t\treturn toThreadInfo(yield* thread.info);\n\t\t\t}),\n\t\t\t\"session.delete\": Effect.fnUntraced(function* ({ sessionId }) {\n\t\t\t\treturn { deleted: yield* Session.remove(sessionId) };\n\t\t\t}),\n\t\t\t\"session.interrupt\": Effect.fnUntraced(function* ({ sessionId }) {\n\t\t\t\t// Ack only: the wire answers \"was there work to stop\", and the caller\n\t\t\t\t// uses `thread.wait` when it needs cleanup to have finished.\n\t\t\t\treturn { interrupted: yield* control.interruptSession(sessionId, { reason: \"user\" }) };\n\t\t\t}),\n\t\t\t\"session.log\": ({ sessionId, threadId, after, follow }) =>\n\t\t\t\tStream.unwrap(\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tif (Option.isNone(yield* sessions.get(sessionId))) {\n\t\t\t\t\t\t\treturn yield* new SessionStore.SessionNotFoundError({ sessionId });\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn events\n\t\t\t\t\t\t\t.log({\n\t\t\t\t\t\t\t\taggregateId: sessionId,\n\t\t\t\t\t\t\t\tfollow: follow ?? false,\n\t\t\t\t\t\t\t\t...(after === undefined ? {} : { after }),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\tStream.filter(\n\t\t\t\t\t\t\t\t\t(item) =>\n\t\t\t\t\t\t\t\t\t\tthreadId === undefined || Event.isSynced(item) || Envelope.ofThread(threadId)(item),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tStream.mapEffect(toLogItem(registry.get)),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\"thread.list\": Effect.fnUntraced(function* ({ sessionId }) {\n\t\t\t\tconst rows = yield* threads.list(sessionId);\n\t\t\t\treturn yield* Effect.forEach(rows, (row) => threadInfo(ThreadSchema.ID.make(row.id)).pipe(Effect.orDie));\n\t\t\t}),\n\t\t\t\"thread.info\": Effect.fnUntraced(function* (ref) {\n\t\t\t\treturn yield* threadInfo(yield* resolve(ref));\n\t\t\t}),\n\t\t\t\"thread.configure\": Effect.fnUntraced(function* ({ runtime, ...ref }) {\n\t\t\t\tconst threadId = yield* resolve(ref);\n\t\t\t\tconst change = {\n\t\t\t\t\t...(runtime.model === undefined ? {} : { model: runtime.model }),\n\t\t\t\t\t...(runtime.thinkingLevel === undefined ? {} : { thinkingLevel: runtime.thinkingLevel }),\n\t\t\t\t\t...(runtime.foundation === undefined ? {} : { foundation: runtime.foundation }),\n\t\t\t\t};\n\t\t\t\tif (Object.keys(change).length > 0) {\n\t\t\t\t\tyield* events.publish(EventList.ThreadConfigured, {\n\t\t\t\t\t\tsessionId: ref.sessionId,\n\t\t\t\t\t\tthreadId,\n\t\t\t\t\t\ttimestamp: yield* DateTime.now,\n\t\t\t\t\t\tchange,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn yield* threadInfo(threadId);\n\t\t\t}),\n\t\t\t\"thread.fork\": Effect.fnUntraced(function* ({ entryId, mode, ...ref }) {\n\t\t\t\tconst forked = yield* threads.fork({\n\t\t\t\t\tthreadId: yield* resolve(ref),\n\t\t\t\t\tentryId,\n\t\t\t\t\t...(mode === undefined ? {} : { mode }),\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\tthread: yield* threadInfo(ThreadSchema.ID.make(forked.thread.id)),\n\t\t\t\t\t...(forked.text === undefined ? {} : { text: forked.text }),\n\t\t\t\t};\n\t\t\t}),\n\t\t\t\"thread.history\": Effect.fnUntraced(function* (ref) {\n\t\t\t\tconst line = yield* threads.line(yield* resolve(ref));\n\t\t\t\tconst entries = line.flatMap(({ entry, parts }): ReadonlyArray<HistoryEntry> =>\n\t\t\t\t\tentry.type === \"user\" || entry.type === \"assistant\"\n\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tid: entry.id,\n\t\t\t\t\t\t\t\t\tthreadId: entry.threadId,\n\t\t\t\t\t\t\t\t\tseq: entry.seq,\n\t\t\t\t\t\t\t\t\trole: entry.type,\n\t\t\t\t\t\t\t\t\tstate: entry.state,\n\t\t\t\t\t\t\t\t\tcreatedAt: DateTime.toEpochMillis(entry.createdAt),\n\t\t\t\t\t\t\t\t\tupdatedAt: DateTime.toEpochMillis(entry.updatedAt),\n\t\t\t\t\t\t\t\t\t// A part this schema does not render (a future aikit type) is skipped, not fatal.\n\t\t\t\t\t\t\t\t\tparts: parts.flatMap((part) => Option.toArray(MessagePart.decode(part.data))),\n\t\t\t\t\t\t\t\t\t...Option.match(entry.type === \"assistant\" ? replyError(entry.data) : Option.none(), {\n\t\t\t\t\t\t\t\t\t\tonNone: () => ({}),\n\t\t\t\t\t\t\t\t\t\tonSome: (error) => ({ error }),\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t: [],\n\t\t\t\t);\n\t\t\t\treturn { entries };\n\t\t\t}),\n\t\t\t\"thread.queue\": Effect.fnUntraced(function* (ref) {\n\t\t\t\tconst pending = yield* control.pending(yield* resolve(ref));\n\t\t\t\treturn {\n\t\t\t\t\tentries: pending.map((input) => ({\n\t\t\t\t\t\tid: input.id,\n\t\t\t\t\t\tdelivery: input.delivery,\n\t\t\t\t\t\ttext: PromptSchema.Prompt.text(input.prompt),\n\t\t\t\t\t\tcreatedAt: DateTime.toEpochMillis(input.timeCreated),\n\t\t\t\t\t})),\n\t\t\t\t};\n\t\t\t}),\n\t\t\t\"thread.prompt\": Effect.fnUntraced(function* ({ text, delivery, id, ...ref }) {\n\t\t\t\tconst admitted = yield* control.prompt({\n\t\t\t\t\t...ref,\n\t\t\t\t\tprompt: PromptSchema.Prompt.fromText(text),\n\t\t\t\t\t...(delivery === undefined ? {} : { delivery }),\n\t\t\t\t\t...(id === undefined ? {} : { id }),\n\t\t\t\t});\n\t\t\t\treturn { threadId: admitted.threadId };\n\t\t\t}),\n\t\t\t\"thread.interrupt\": Effect.fnUntraced(function* (ref) {\n\t\t\t\t// Ack only: the wire answers \"was there work to stop\", and the caller\n\t\t\t\t// uses `thread.wait` when it needs cleanup to have finished.\n\t\t\t\treturn { interrupted: yield* control.interrupt(yield* resolve(ref), { reason: \"user\" }) };\n\t\t\t}),\n\t\t\t\"thread.cancel\": Effect.fnUntraced(function* ({ messageId, ...ref }) {\n\t\t\t\treturn { cancelled: yield* control.cancel(yield* resolve(ref), messageId) };\n\t\t\t}),\n\t\t\t\"thread.update\": Effect.fnUntraced(function* ({ messageId, delivery, text, ...ref }) {\n\t\t\t\tconst updated = yield* control.update(yield* resolve(ref), messageId, {\n\t\t\t\t\t...(delivery === undefined ? {} : { delivery }),\n\t\t\t\t\t...(text === undefined ? {} : { prompt: PromptSchema.Prompt.fromText(text) }),\n\t\t\t\t});\n\t\t\t\treturn { updated };\n\t\t\t}),\n\t\t\t\"thread.message\": Effect.fnUntraced(function* ({ messageId, ...ref }) {\n\t\t\t\t// Scoped to the thread's line: an entry id is global, and a client should not learn\n\t\t\t\t// about conversations it did not ask for. An inherited prompt is in the thread's.\n\t\t\t\tconst line = yield* threads.line(yield* resolve(ref));\n\t\t\t\treturn { found: line.some(({ entry }) => entry.id === messageId) };\n\t\t\t}),\n\t\t\t\"thread.wait\": Effect.fnUntraced(function* (ref) {\n\t\t\t\tyield* control.wait(yield* resolve(ref));\n\t\t\t}),\n\t\t\t\"mcp.connect\": mcpControl(\"connect\"),\n\t\t\t\"mcp.disconnect\": mcpControl(\"disconnect\"),\n\t\t\t\"sandbox.drivers\": Effect.fnUntraced(function* () {\n\t\t\t\tconst drivers = yield* Sandbox.drivers();\n\t\t\t\treturn drivers.map(({ name, kind }) => ({ name, kind }));\n\t\t\t}),\n\t\t\t\"sandbox.list\": Effect.fnUntraced(function* () {\n\t\t\t\treturn (yield* Sandbox.list()).map(toSandboxInfo);\n\t\t\t}),\n\t\t\t\"sandbox.create\": Effect.fnUntraced(function* ({ driver }) {\n\t\t\t\treturn toSandboxInfo(yield* exported(\"Server.sandbox.create\", Sandbox.create({ driver })));\n\t\t\t}),\n\t\t\t\"sandbox.register\": Effect.fnUntraced(function* ({ driver, providerResourceId }) {\n\t\t\t\treturn toSandboxInfo(yield* Sandbox.register({ driver, providerResourceId }));\n\t\t\t}),\n\t\t\t\"sandbox.stop\": Effect.fnUntraced(function* ({ sandboxId }) {\n\t\t\t\tyield* Sandbox.stop(sandboxId);\n\t\t\t}),\n\t\t\t// Acquiring the feed subscription is the readiness barrier: `server.connected`\n\t\t\t// is only emitted once this client is registered, so a prompt admitted after\n\t\t\t// it cannot land in the gap.\n\t\t\t\"event.subscribe\": ({ threadId }) =>\n\t\t\t\tStream.unwrap(\n\t\t\t\t\tfeed.subscribe.pipe(\n\t\t\t\t\t\tEffect.map((events) =>\n\t\t\t\t\t\t\tStream.make({ id: EventSchema.ID.create(), type: Envelope.Connected.type, data: {} }).pipe(\n\t\t\t\t\t\t\t\tStream.concat(\n\t\t\t\t\t\t\t\t\tthreadId === undefined ? events : events.pipe(Stream.filter(Envelope.ofThread(threadId))),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t});\n\t}),\n);\n\nexport * as Handlers from \"./handlers.ts\";\n","import { Control, Global, Harness, Sandbox } from \"@codeworksh/harness/effect\";\nimport { NodeHttpServer } from \"@effect/platform-node\";\nimport { Effect, Layer } from \"effect\";\nimport { HttpRouter, HttpServer } from \"effect/http\";\nimport * as NetAddress from \"effect/net/NetAddress\";\nimport { RpcSerialization, RpcServer } from \"effect/rpc\";\n/* @effect-diagnostics nodeBuiltinImport:off -- the RPC listener needs a raw node server. */\nimport { createServer } from \"node:http\";\nimport { Contract } from \"./contract.ts\";\nimport { EventFeed } from \"./feed.ts\";\nimport { Handlers } from \"./handlers.ts\";\nimport { Identity } from \"./identity.ts\";\nimport { OAuth } from \"./oauth.ts\";\nimport { Registration } from \"./registration.ts\";\n\n// Managed instances outlive any single RPC; the serve scope is what stops them.\nconst managedShutdown = Layer.unwrap(\n\tEffect.gen(function* () {\n\t\tconst control = yield* Control.Service;\n\t\tyield* Effect.addFinalizer(() =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\t// Release drain leases before stopping the server's managed sandboxes.\n\t\t\t\t// Both phases are best effort and bounded so a provider cannot prevent\n\t\t\t\t// process shutdown; an interrupted stop is persisted as faulted and can\n\t\t\t\t// recover the next time that sandbox is mounted.\n\t\t\t\tyield* Effect.forEach(\n\t\t\t\t\tyield* control.active,\n\t\t\t\t\t(id) =>\n\t\t\t\t\t\tcontrol\n\t\t\t\t\t\t\t.interrupt(id, { reason: \"shutdown\", awaitSettlement: true })\n\t\t\t\t\t\t\t.pipe(Effect.timeout(\"10 seconds\"), Effect.ignore),\n\t\t\t\t\t{ concurrency: \"unbounded\", discard: true },\n\t\t\t\t);\n\t\t\t\tconst infos = yield* Sandbox.list();\n\t\t\t\tyield* Effect.forEach(\n\t\t\t\t\tinfos.filter((info) => info.ownership === \"managed\"),\n\t\t\t\t\t(info) =>\n\t\t\t\t\t\tSandbox.stop(info.id).pipe(\n\t\t\t\t\t\t\tEffect.timeout(\"10 seconds\"),\n\t\t\t\t\t\t\tEffect.catchCause((cause) =>\n\t\t\t\t\t\t\t\tEffect.logError(\"Failed to stop managed sandbox during shutdown\", cause).pipe(\n\t\t\t\t\t\t\t\t\tEffect.annotateLogs({ sandboxInstanceId: info.id }),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t{ concurrency: \"unbounded\", discard: true },\n\t\t\t\t);\n\t\t\t}),\n\t\t);\n\t\treturn Layer.empty;\n\t}),\n);\n\n/**\n * Resumes the runs the last server left unfinished, whether it crashed or shut down: the session\n * table records them as they start, so this needs nothing from the previous process.\n */\nconst resumeUnfinished = Layer.effectDiscard(\n\tEffect.gen(function* () {\n\t\tconst control = yield* Control.Service;\n\t\tyield* Effect.forkScoped(control.resumeUnfinished);\n\t}),\n);\n\n/**\n * Advertises the listener once it has an address: logs the endpoint and files\n * the registration later invocations discover it through.\n */\nconst announce = Layer.unwrap(\n\tEffect.gen(function* () {\n\t\tconst server = yield* HttpServer.HttpServer;\n\t\tconst global = yield* Global.Service;\n\t\tconst identity = yield* Identity.Service;\n\t\t// A ws server always binds TCP; the guard keeps the logger honest if that ever changes.\n\t\tconst address = server.address;\n\t\tconst url = `${NetAddress.formatUrlUnsafe(address, \"ws\")}${Contract.path}`;\n\t\tyield* Effect.log(`codework serve listening on ${url}`);\n\t\tif (!NetAddress.isInetAddress(address)) return Layer.empty;\n\t\treturn Registration.register({\n\t\t\thome: global.home,\n\t\t\tinfo: { pid: identity.pid, version: identity.version, url, port: address.port },\n\t\t});\n\t}),\n);\n\nexport const layer = (options: { host: string; port: number; harness: Harness.Options }) => {\n\tconst rpc = RpcServer.layerHttp({ group: Contract.Api, path: Contract.path, protocol: \"websocket\" }).pipe(\n\t\tLayer.provide(Handlers.layer.pipe(Layer.provide(EventFeed.layer))),\n\t);\n\tconst app = HttpRouter.serve(rpc, { disableListenLog: true }).pipe(\n\t\tLayer.provideMerge(managedShutdown),\n\t\tLayer.provideMerge(resumeUnfinished),\n\t\tLayer.provide(OAuth.layer(options.harness.home === undefined ? {} : { home: options.harness.home })),\n\t);\n\treturn app.pipe(\n\t\tLayer.provideMerge(announce),\n\t\tLayer.provideMerge(NodeHttpServer.layer(createServer, { host: options.host, port: options.port })),\n\t\tLayer.provide(RpcSerialization.layerNdjson),\n\t\tLayer.provide(Identity.layer),\n\t\tLayer.provide(Harness.layer(options.harness)),\n\t);\n};\n\nexport * as Server from \"./server.ts\";\n","import { Global } from \"@codeworksh/harness/effect\";\nimport { Effect, FileSystem, Layer, Logger } from \"effect\";\nimport { Runtime } from \"../../../framework/runtime.ts\";\nimport { Registration } from \"../../../server/registration.ts\";\nimport { Server } from \"../../../server/server.ts\";\nimport { renderError } from \"../../error.ts\";\nimport { harnessOptions } from \"../../harness.ts\";\nimport { writeError } from \"../../output.ts\";\nimport { Cmd } from \"../cmd.ts\";\n\nconst failed = Effect.sync(() => {\n\tprocess.exitCode = 1;\n});\n\nconst report = (error: unknown) => writeError(renderError(error)).pipe(Effect.andThen(failed));\n\nexport default Runtime.handler(\n\tCmd.commands.serve,\n\tEffect.fn(\"CLI.serve\", { level: \"Info\" })(function* ({ host, port, service }) {\n\t\tconst shared = yield* Cmd.spec;\n\t\tconst harness = { ...harnessOptions(shared), watchModels: true };\n\t\tconst serve = Layer.launch(Server.layer({ host, port, harness }));\n\t\tif (!service) return yield* serve.pipe(Effect.catch(report));\n\n\t\t// A background server has no terminal: its log, and the reason it stopped, go to a\n\t\t// file the CLI that started it reads back when startup fails.\n\t\tconst background = Effect.gen(function* () {\n\t\t\tconst paths = yield* Global.resolve(harness.home === undefined ? {} : { home: harness.home });\n\t\t\tconst fs = yield* FileSystem.FileSystem;\n\t\t\tyield* fs.makeDirectory(paths.log, { recursive: true });\n\t\t\tconst logger = Logger.formatSimple.pipe(Logger.toFile(Registration.log(paths.log), { flag: \"w\" }));\n\t\t\tyield* serve.pipe(\n\t\t\t\tEffect.catch((error) => Effect.logError(renderError(error).trim()).pipe(Effect.andThen(failed))),\n\t\t\t\tEffect.provide(Logger.layer([logger])),\n\t\t\t);\n\t\t});\n\t\tyield* background.pipe(Effect.catch(report));\n\t}),\n);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"serve-Ce8hdWM6.mjs","names":["Service","Envelope.Core","Envelope.encode","layer","layer","Contract.OAuthError","Envelope.encode","layer","EventFeed.Service","OAuth.Service","Identity.Service","Envelope.ofThread","MessagePart.decode","Identity.Service","Contract.path","Registration.register","Contract.Api","EventFeed.layer","OAuth.layer","Identity.layer","Runtime.handler","Server.layer","Registration.log"],"sources":["../../src/server/feed.ts","../../src/server/oauth.ts","../../src/server/handlers.ts","../../src/server/server.ts","../../src/cli/cmd/handlers/serve.ts"],"sourcesContent":["import { Event, EventRegistry, EventSchema } from \"@codeworksh/harness/effect\";\nimport { Cause, Context, Effect, Layer, Queue, Scope, Stream } from \"effect\";\nimport { EncodingError, type EventEnvelope, Envelope } from \"./envelope.ts\";\n\nexport const SubscriberCapacity = 4096;\n\nexport type Error = Event.SubscriptionOverflowError | EncodingError;\n\nexport interface Interface {\n\t/** A live envelope stream for one client; releasing the scope unregisters it. */\n\treadonly subscribe: Effect.Effect<Stream.Stream<EventEnvelope, Error>, never, Scope.Scope>;\n}\n\nexport class Service extends Context.Service<Service, Interface>()(\"@codeworksh/cli/server/feed/Service\") {}\n\n/**\n * Fan-out for `event.subscribe`. One listener on the event bus encodes each\n * event once and hands the same envelope to every client, rather than every\n * client re-encoding the same payload.\n *\n * Failure is per-cause, not per-feed: a client that cannot keep up fails alone\n * with its own overflow, while an event that cannot be encoded is a server bug\n * that disconnects everyone currently attached -- the feed stays usable for\n * whoever connects next. Types outside the server's registry are dropped\n * before they can consume a client's capacity.\n */\nexport const make = Effect.fn(\"EventFeed.make\")(function* (\n\tlisten: (subscriber: Event.Subscriber) => Effect.Effect<Event.Unsubscribe>,\n\toptions?: { readonly capacity?: number; readonly registry?: Envelope.Registry },\n) {\n\tconst capacity = options?.capacity ?? SubscriberCapacity;\n\t// Whatever this server knows how to describe, plugin registrations included.\n\tconst registry = options?.registry ?? Envelope.Core;\n\tconst subscribers = new Set<Queue.Queue<EventEnvelope, Error>>();\n\n\tconst failAll = (error: Error) =>\n\t\tEffect.sync(() => {\n\t\t\tconst current = Array.from(subscribers);\n\t\t\tsubscribers.clear();\n\t\t\tfor (const subscriber of current) Queue.failCauseUnsafe(subscriber, Cause.fail(error));\n\t\t});\n\n\tconst deliver = Effect.fnUntraced(function* (event: EventSchema.Payload) {\n\t\tif (subscribers.size === 0) return;\n\t\t// Dropped here rather than after the queue: a burst of events this server\n\t\t// cannot describe must not spend a client's capacity on its way to nowhere.\n\t\tif (registry(event.type) === undefined) return;\n\t\tconst envelope = yield* Envelope.encode(event, registry);\n\t\tfor (const subscriber of subscribers) {\n\t\t\tif (Queue.offerUnsafe(subscriber, envelope)) continue;\n\t\t\tsubscribers.delete(subscriber);\n\t\t\tQueue.failCauseUnsafe(subscriber, Cause.fail(new Event.SubscriptionOverflowError({ capacity })));\n\t\t}\n\t});\n\n\tconst publish = (event: EventSchema.Payload) =>\n\t\tdeliver(event).pipe(\n\t\t\tEffect.catchTags({\n\t\t\t\tEventEncodingError: (error) =>\n\t\t\t\t\tEffect.logError(\"Failed to encode public event\", { type: error.type, cause: error.cause }).pipe(\n\t\t\t\t\t\tEffect.andThen(failAll(error)),\n\t\t\t\t\t),\n\t\t\t\t// The registry guard in `deliver` already returned for unknown types.\n\t\t\t\tUnknownEventTypeError: Effect.die,\n\t\t\t}),\n\t\t);\n\n\tconst unsubscribe = yield* listen(publish);\n\tyield* Effect.addFinalizer(() => unsubscribe);\n\n\treturn Service.of({\n\t\tsubscribe: Effect.acquireRelease(\n\t\t\tQueue.dropping<EventEnvelope, Error>(capacity).pipe(\n\t\t\t\tEffect.tap((queue) => Effect.sync(() => subscribers.add(queue))),\n\t\t\t),\n\t\t\t(queue) => Effect.sync(() => subscribers.delete(queue)).pipe(Effect.andThen(Queue.shutdown(queue))),\n\t\t).pipe(Effect.map(Stream.fromQueue)),\n\t});\n});\n\nexport const layer = Layer.effect(\n\tService,\n\tEffect.gen(function* () {\n\t\tconst events = yield* Event.Service;\n\t\tconst registered = yield* EventRegistry.Service;\n\t\treturn yield* make(events.listen, { registry: registered.get });\n\t}),\n);\n\nexport * as EventFeed from \"./feed.ts\";\n","/**\n * Server-side OAuth credential storage.\n *\n * The CLI runs the interactive part of every login locally — a browser\n * callback or a device code cannot travel over RPC — and sends the resulting\n * credentials here, so this service only ever reads, writes, refreshes and\n * clears the server home's `auth.json`.\n */\nimport {\n\tGitHubCopilotOAuthClient,\n\tJsonGitHubCopilotAuthStorage,\n\ttype GitHubCopilotOAuthCredentials,\n} from \"@codeworksh/aikit/oauth/github/copilot\";\nimport {\n\tJsonOpenAICodexAuthStorage,\n\tOpenAICodexOAuthClient,\n\ttype OpenAICodexOAuthCredentials,\n} from \"@codeworksh/aikit/oauth/openai/codex\";\nimport { summarizeGitHubCopilot, summarizeOpenAICodex } from \"@codeworksh/aikit/oauth/summary\";\nimport { Global } from \"@codeworksh/harness/effect\";\nimport { Context, Effect, Layer } from \"effect\";\nimport { Contract } from \"./contract.ts\";\n\ninterface Interface {\n\treadonly save: (credentials: Contract.OAuthCredentials) => Effect.Effect<Contract.OAuthInfo, Contract.OAuthError>;\n\treadonly status: (provider: Contract.OAuthProvider) => Effect.Effect<Contract.OAuthInfo | null, Contract.OAuthError>;\n\treadonly refresh: (\n\t\tprovider: Contract.OAuthProvider,\n\t) => Effect.Effect<Contract.OAuthInfo | null, Contract.OAuthError>;\n\treadonly logout: (provider: Contract.OAuthProvider) => Effect.Effect<void, Contract.OAuthError>;\n}\n\nexport class Service extends Context.Service<Service, Interface>()(\"@codeworksh/cli/server/oauth/Service\") {}\n\nconst message = (cause: unknown): string =>\n\tcause instanceof Error && cause.message.trim().length > 0 ? cause.message : String(cause);\n\n/**\n * Re-exported so the server, the CLI and aikit all describe a login the same\n * way; `Contract.OAuthInfo` is the wire shape of {@link OAuthSummary}.\n */\nexport const codexInfo = summarizeOpenAICodex;\nexport const copilotInfo = summarizeGitHubCopilot;\n\nexport const layer = (options: { readonly home?: string | undefined } = {}) =>\n\tLayer.effect(\n\t\tService,\n\t\tEffect.gen(function* () {\n\t\t\tconst global = yield* Global.Service;\n\t\t\tconst authFile = Global.authFile(options.home === undefined ? undefined : global.home);\n\t\t\tconst file = authFile === undefined ? {} : { path: authFile };\n\t\t\tconst codex = new OpenAICodexOAuthClient({ storage: new JsonOpenAICodexAuthStorage(file) });\n\t\t\tconst copilot = new GitHubCopilotOAuthClient({ storage: new JsonGitHubCopilotAuthStorage(file) });\n\t\t\tconst attempt = <A>(run: () => Promise<A>) =>\n\t\t\t\tEffect.tryPromise({\n\t\t\t\t\ttry: run,\n\t\t\t\t\tcatch: (cause) => new Contract.OAuthError({ message: message(cause) }),\n\t\t\t\t});\n\t\t\tconst optional = <A>(run: () => Promise<A | undefined>, info: (value: A) => Contract.OAuthInfo) =>\n\t\t\t\tattempt(run).pipe(Effect.map((value) => (value === undefined ? null : info(value))));\n\n\t\t\treturn Service.of({\n\t\t\t\t// The `provider` tag is routing, not a credential: it never reaches disk.\n\t\t\t\tsave: (wire) => {\n\t\t\t\t\tif (wire.provider === \"openai-codex\") {\n\t\t\t\t\t\tconst credentials: OpenAICodexOAuthCredentials = {\n\t\t\t\t\t\t\taccess: wire.access,\n\t\t\t\t\t\t\trefresh: wire.refresh,\n\t\t\t\t\t\t\texpires: wire.expires,\n\t\t\t\t\t\t\taccountId: wire.accountId,\n\t\t\t\t\t\t};\n\t\t\t\t\t\treturn attempt(() => codex.storage.set(credentials)).pipe(Effect.as(codexInfo(credentials)));\n\t\t\t\t\t}\n\t\t\t\t\tconst credentials: GitHubCopilotOAuthCredentials = {\n\t\t\t\t\t\taccess: wire.access,\n\t\t\t\t\t\trefresh: wire.refresh,\n\t\t\t\t\t\texpires: wire.expires,\n\t\t\t\t\t\t...(wire.enterpriseUrl === undefined ? {} : { enterpriseUrl: wire.enterpriseUrl }),\n\t\t\t\t\t\t...(wire.apiEndpoint === undefined ? {} : { apiEndpoint: wire.apiEndpoint }),\n\t\t\t\t\t\t...(wire.availableModelIds === undefined ? {} : { availableModelIds: [...wire.availableModelIds] }),\n\t\t\t\t\t};\n\t\t\t\t\treturn attempt(() => copilot.storage.set(credentials)).pipe(Effect.as(copilotInfo(credentials)));\n\t\t\t\t},\n\t\t\t\tstatus: (provider) =>\n\t\t\t\t\tprovider === \"openai-codex\"\n\t\t\t\t\t\t? optional(() => codex.storage.get(), codexInfo)\n\t\t\t\t\t\t: optional(() => copilot.storage.get(), copilotInfo),\n\t\t\t\t// GitHub OAuth tokens never expire, so a Copilot \"refresh\" is a read.\n\t\t\t\trefresh: (provider) =>\n\t\t\t\t\tprovider === \"openai-codex\"\n\t\t\t\t\t\t? optional(() => codex.getCredentials(), codexInfo)\n\t\t\t\t\t\t: optional(() => copilot.getCredentials(), copilotInfo),\n\t\t\t\tlogout: (provider) => attempt(() => (provider === \"openai-codex\" ? codex.logout() : copilot.logout())),\n\t\t\t});\n\t\t}),\n\t);\n\nexport * as OAuth from \"./oauth.ts\";\n","import { Model } from \"@codeworksh/aikit\";\nimport {\n\tControl,\n\tEvent,\n\tEventList,\n\tEventRegistry,\n\tEventSchema,\n\tMcp,\n\tModelCatalog,\n\tProject,\n\tPromptSchema,\n\tSandbox,\n\tSession,\n\tSessionStore,\n\tSettings,\n\tState,\n\tThreadSchema,\n\tThreadStore,\n} from \"@codeworksh/harness/effect\";\nimport { DateTime, Effect, Option, Schema, Stream } from \"effect\";\nimport {\n\tContract,\n\ttype HistoryEntry,\n\ttype LogSynced,\n\ttype RuntimeConfig,\n\ttype SandboxInfo,\n\ttype SessionInfo,\n\ttype ThreadInfo,\n} from \"./contract.ts\";\nimport { type EncodingError, Envelope, type EventEnvelope } from \"./envelope.ts\";\nimport { EventFeed } from \"./feed.ts\";\nimport { Identity } from \"./identity.ts\";\nimport { OAuth } from \"./oauth.ts\";\nimport { MessagePart } from \"./part.ts\";\n\nconst toSandboxInfo = (info: Sandbox.Info): SandboxInfo => ({\n\tid: info.id,\n\tdriver: info.driver,\n\tkind: info.kind,\n\tproviderResourceId: info.providerResourceId,\n\townership: info.ownership,\n\tstatus: info.status,\n\tusage: info.usage,\n\trefCount: info.refCount,\n\tcreatedAt: info.createdAt,\n\tupdatedAt: info.updatedAt,\n});\n\nconst toSessionInfo = (info: Session.Info): SessionInfo => ({\n\tid: info.id,\n\tdirectory: info.directory,\n\t...(info.hostDir === undefined ? {} : { hostDir: info.hostDir }),\n\t...(info.sandbox === undefined ? {} : { sandbox: toSandboxInfo(info.sandbox) }),\n\t...(info.project === undefined ? {} : { project: info.project }),\n\tupdatedAt: info.updatedAt,\n\tmainThreadId: info.mainThreadId,\n});\n\nconst toThreadInfo = (info: Session.ThreadInfo): ThreadInfo => ({\n\tid: info.id,\n\torigin: info.origin,\n\t...(info.title === undefined ? {} : { title: info.title }),\n\tupdatedAt: info.updatedAt,\n\t...(info.model === undefined ? {} : { model: info.model }),\n\t...(info.thinkingLevel === undefined ? {} : { thinkingLevel: info.thinkingLevel }),\n\t...(info.foundation === undefined ? {} : { foundation: info.foundation }),\n\t...(info.placement === undefined ? {} : { placement: info.placement }),\n\tusage: info.usage,\n\tsession: toSessionInfo(info.session),\n});\n\n// Wire configs name only the keys they set, so `undefined` never reaches the harness under\n// exactOptionalPropertyTypes. Creating takes choices only; `null` clears nothing there.\nconst runtimeInput = (runtime: RuntimeConfig | undefined): Session.RuntimeInput => ({\n\t...(runtime?.model == null ? {} : { model: runtime.model }),\n\t...(runtime?.thinkingLevel == null ? {} : { thinkingLevel: runtime.thinkingLevel }),\n\t...(runtime?.foundation == null ? {} : { foundation: runtime.foundation }),\n});\n\n// A failed reply's envelope keeps the provider's reason; it reads as the live failure does.\nconst decodeFailedReply = Schema.decodeUnknownOption(\n\tSchema.fromJsonString(\n\t\tSchema.Struct({\n\t\t\tstopReason: Schema.Literal(\"error\"),\n\t\t\terrorMessage: Schema.String,\n\t\t\tprovider: Schema.Struct({ id: Schema.String }),\n\t\t\tmodel: Schema.String,\n\t\t}),\n\t),\n);\nconst replyError = (data: string) =>\n\tOption.map(decodeFailedReply(data), (reply) => `${reply.provider.id}/${reply.model}: ${reply.errorMessage}`);\n\nconst threadInfo = (threadId: ThreadSchema.ID) => Session.threadInfo(threadId).pipe(Effect.map(toThreadInfo));\n\n// RpcServer's request span has no level, so it is Debug and drops every Info span under it.\n// Provisioning a sandbox is worth exporting, so it starts a trace of its own.\nconst exported = <A, E, R>(name: string, self: Effect.Effect<A, E, R>) =>\n\tself.pipe(Effect.withSpan(name, { level: \"Info\", root: true }));\n\nconst releaseOnFailure = (selection: Effect.Success<ReturnType<typeof Sandbox.resolve>> | undefined) =>\n\tselection?.created && selection.info !== undefined\n\t\t? Sandbox.stop(selection.info.id).pipe(Effect.catchCause(Effect.logError))\n\t\t: Effect.void;\n\n/** A `session.log` item for the wire: a stored event as its envelope, or the replay marker. */\nconst toLogItem =\n\t(registry: Envelope.Registry) =>\n\t(item: Event.LogItem): Effect.Effect<EventEnvelope | LogSynced, EncodingError> =>\n\t\tEvent.isSynced(item)\n\t\t\t? Effect.succeed(item)\n\t\t\t: Envelope.encode(item, registry).pipe(\n\t\t\t\t\t// Every stored type is a kernel durable one, which the registry always knows.\n\t\t\t\t\tEffect.catchTag(\"UnknownEventTypeError\", Effect.die),\n\t\t\t\t);\n\nexport const layer = Contract.Api.toLayer(\n\tEffect.gen(function* () {\n\t\tconst control = yield* Control.Service;\n\t\tconst feed = yield* EventFeed.Service;\n\t\tconst sessions = yield* SessionStore.Service;\n\t\tconst threads = yield* ThreadStore.Service;\n\t\tconst resolve = (ref: Control.ThreadRef) =>\n\t\t\tcontrol.resolve(ref).pipe(Effect.map((thread) => ThreadSchema.ID.make(thread.id)));\n\t\tconst state = yield* State.Service;\n\t\tconst oauth = yield* OAuth.Service;\n\t\tconst identity = yield* Identity.Service;\n\t\tconst events = yield* Event.Service;\n\t\tconst registry = yield* EventRegistry.Service;\n\t\tconst mcp = yield* Mcp.Service;\n\t\tconst mcpControl = (operation: \"connect\" | \"disconnect\") =>\n\t\t\tEffect.fnUntraced(function* ({ server, ...ref }: Control.ThreadRef & { readonly server: string }) {\n\t\t\t\treturn yield* mcp[operation](yield* resolve(ref), server);\n\t\t\t});\n\n\t\treturn Contract.Api.of({\n\t\t\t\"server.info\": () => Effect.succeed({ pid: identity.pid, version: identity.version }),\n\t\t\t\"auth.save\": ({ credentials }) => oauth.save(credentials),\n\t\t\t\"auth.status\": ({ provider }) => oauth.status(provider),\n\t\t\t\"auth.refresh\": ({ provider }) => oauth.refresh(provider),\n\t\t\t\"auth.logout\": ({ provider }) => oauth.logout(provider),\n\t\t\t\"session.create\": Effect.fnUntraced(function* ({ title, directory, hostDir, sandbox, runtime, project }) {\n\t\t\t\tconst selection =\n\t\t\t\t\tsandbox === undefined ? undefined : yield* exported(\"Server.session.create\", Sandbox.resolve(sandbox));\n\t\t\t\tconst selected = selection?.info;\n\t\t\t\tconst handle = yield* Session.create({\n\t\t\t\t\t...(title === undefined ? {} : { title }),\n\t\t\t\t\t...(directory === undefined ? {} : { directory }),\n\t\t\t\t\t// Passed through as given, never defaulted to the server's own directory: a\n\t\t\t\t\t// session the client did not place has no project, which is a normal state.\n\t\t\t\t\t...(hostDir === undefined ? {} : { hostDir }),\n\t\t\t\t\t...(selected === undefined ? {} : { sandbox: selected }),\n\t\t\t\t\t...(project === undefined ? {} : { project }),\n\t\t\t\t\t...runtimeInput(runtime),\n\t\t\t\t}).pipe(Effect.onError(() => releaseOnFailure(selection)));\n\t\t\t\treturn toThreadInfo(yield* handle.main.info);\n\t\t\t}),\n\t\t\t\"model.list\": Effect.fnUntraced(function* ({ hostDir }) {\n\t\t\t\tconst filter = hostDir === undefined ? {} : { hostDir };\n\t\t\t\tconst settings = yield* Settings.Service;\n\t\t\t\tconst loaded = yield* settings.load(hostDir);\n\t\t\t\tconst { model } = loaded;\n\t\t\t\tconst providers = yield* ModelCatalog.available(filter);\n\t\t\t\t// Named from the whole catalog, so a default without credentials still reads as itself.\n\t\t\t\tconst entry = (yield* ModelCatalog.effective(loaded.models))[model.provider]?.[model.id];\n\t\t\t\treturn {\n\t\t\t\t\tproviders: providers.flatMap((provider) => {\n\t\t\t\t\t\tconst models = Object.values(provider.models);\n\t\t\t\t\t\tconst first = models[0];\n\t\t\t\t\t\treturn first === undefined\n\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tid: provider.id,\n\t\t\t\t\t\t\t\t\t\tname: first.provider.name,\n\t\t\t\t\t\t\t\t\t\tmodels: models.map((info) => ({\n\t\t\t\t\t\t\t\t\t\t\tid: info.id,\n\t\t\t\t\t\t\t\t\t\t\tname: info.name,\n\t\t\t\t\t\t\t\t\t\t\tthinkingLevels: Model.getSupportedThinkingLevels(info),\n\t\t\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t];\n\t\t\t\t\t}),\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tprovider: model.provider,\n\t\t\t\t\t\tid: model.id,\n\t\t\t\t\t\tthinkingLevel: model.thinkingLevel,\n\t\t\t\t\t\t...(entry === undefined ? {} : { name: entry.name, providerName: entry.provider.name }),\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}),\n\t\t\t\"project.rename\": Effect.fnUntraced(function* ({ projectId, name }) {\n\t\t\t\tconst renamed = yield* Project.rename({ projectId, name });\n\t\t\t\treturn { id: renamed.id, name: renamed.name };\n\t\t\t}),\n\t\t\t\"plugin.reload\": Effect.fnUntraced(function* () {\n\t\t\t\treturn yield* state.reload;\n\t\t\t}),\n\t\t\t\"session.link\": Effect.fnUntraced(function* ({ sessionId, hostDir }) {\n\t\t\t\tconst handle = yield* Session.link({ sessionId, hostDir: hostDir ?? null });\n\t\t\t\treturn toSessionInfo(yield* handle.info);\n\t\t\t}),\n\t\t\t\"session.relink\": Effect.fnUntraced(function* ({ sessionId, threadId, sandbox, directory }) {\n\t\t\t\tconst selection =\n\t\t\t\t\tsandbox === undefined ? undefined : yield* exported(\"Server.session.relink\", Sandbox.resolve(sandbox));\n\t\t\t\tconst selected = selection?.info;\n\t\t\t\tconst handle = yield* Session.relink({\n\t\t\t\t\tsessionId,\n\t\t\t\t\t...(threadId === undefined ? {} : { threadId }),\n\t\t\t\t\t...(selected === undefined ? {} : { sandbox: selected }),\n\t\t\t\t\t...(directory === undefined ? {} : { directory }),\n\t\t\t\t}).pipe(Effect.onError(() => releaseOnFailure(selection)));\n\t\t\t\tconst thread = yield* handle.thread(threadId ?? ThreadSchema.MAIN);\n\t\t\t\treturn toThreadInfo(yield* thread.info);\n\t\t\t}),\n\t\t\t\"session.delete\": Effect.fnUntraced(function* ({ sessionId }) {\n\t\t\t\treturn { deleted: yield* Session.remove(sessionId) };\n\t\t\t}),\n\t\t\t\"session.interrupt\": Effect.fnUntraced(function* ({ sessionId }) {\n\t\t\t\t// Ack only: the wire answers \"was there work to stop\", and the caller\n\t\t\t\t// uses `thread.wait` when it needs cleanup to have finished.\n\t\t\t\treturn { interrupted: yield* control.interruptSession(sessionId, { reason: \"user\" }) };\n\t\t\t}),\n\t\t\t\"session.log\": ({ sessionId, threadId, after, follow }) =>\n\t\t\t\tStream.unwrap(\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tif (Option.isNone(yield* sessions.get(sessionId))) {\n\t\t\t\t\t\t\treturn yield* new SessionStore.SessionNotFoundError({ sessionId });\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn events\n\t\t\t\t\t\t\t.log({\n\t\t\t\t\t\t\t\taggregateId: sessionId,\n\t\t\t\t\t\t\t\tfollow: follow ?? false,\n\t\t\t\t\t\t\t\t...(after === undefined ? {} : { after }),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\tStream.filter(\n\t\t\t\t\t\t\t\t\t(item) =>\n\t\t\t\t\t\t\t\t\t\tthreadId === undefined || Event.isSynced(item) || Envelope.ofThread(threadId)(item),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tStream.mapEffect(toLogItem(registry.get)),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\"thread.list\": Effect.fnUntraced(function* ({ sessionId }) {\n\t\t\t\tconst rows = yield* threads.list(sessionId);\n\t\t\t\treturn yield* Effect.forEach(rows, (row) => threadInfo(ThreadSchema.ID.make(row.id)).pipe(Effect.orDie));\n\t\t\t}),\n\t\t\t\"thread.info\": Effect.fnUntraced(function* (ref) {\n\t\t\t\treturn yield* threadInfo(yield* resolve(ref));\n\t\t\t}),\n\t\t\t\"thread.configure\": Effect.fnUntraced(function* ({ runtime, ...ref }) {\n\t\t\t\tconst threadId = yield* resolve(ref);\n\t\t\t\tconst change = {\n\t\t\t\t\t...(runtime.model === undefined ? {} : { model: runtime.model }),\n\t\t\t\t\t...(runtime.thinkingLevel === undefined ? {} : { thinkingLevel: runtime.thinkingLevel }),\n\t\t\t\t\t...(runtime.foundation === undefined ? {} : { foundation: runtime.foundation }),\n\t\t\t\t};\n\t\t\t\tif (Object.keys(change).length > 0) {\n\t\t\t\t\tyield* events.publish(EventList.ThreadConfigured, {\n\t\t\t\t\t\tsessionId: ref.sessionId,\n\t\t\t\t\t\tthreadId,\n\t\t\t\t\t\ttimestamp: yield* DateTime.now,\n\t\t\t\t\t\tchange,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn yield* threadInfo(threadId);\n\t\t\t}),\n\t\t\t\"thread.fork\": Effect.fnUntraced(function* ({ entryId, mode, ...ref }) {\n\t\t\t\tconst forked = yield* threads.fork({\n\t\t\t\t\tthreadId: yield* resolve(ref),\n\t\t\t\t\tentryId,\n\t\t\t\t\t...(mode === undefined ? {} : { mode }),\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\tthread: yield* threadInfo(ThreadSchema.ID.make(forked.thread.id)),\n\t\t\t\t\t...(forked.text === undefined ? {} : { text: forked.text }),\n\t\t\t\t};\n\t\t\t}),\n\t\t\t\"thread.history\": Effect.fnUntraced(function* (ref) {\n\t\t\t\tconst line = yield* threads.line(yield* resolve(ref));\n\t\t\t\tconst entries = line.flatMap(({ entry, parts }): ReadonlyArray<HistoryEntry> =>\n\t\t\t\t\tentry.type === \"user\" || entry.type === \"assistant\"\n\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tid: entry.id,\n\t\t\t\t\t\t\t\t\tthreadId: entry.threadId,\n\t\t\t\t\t\t\t\t\tseq: entry.seq,\n\t\t\t\t\t\t\t\t\trole: entry.type,\n\t\t\t\t\t\t\t\t\tstate: entry.state,\n\t\t\t\t\t\t\t\t\tcreatedAt: DateTime.toEpochMillis(entry.createdAt),\n\t\t\t\t\t\t\t\t\tupdatedAt: DateTime.toEpochMillis(entry.updatedAt),\n\t\t\t\t\t\t\t\t\t// A part this schema does not render (a future aikit type) is skipped, not fatal.\n\t\t\t\t\t\t\t\t\tparts: parts.flatMap((part) => Option.toArray(MessagePart.decode(part.data))),\n\t\t\t\t\t\t\t\t\t...Option.match(entry.type === \"assistant\" ? replyError(entry.data) : Option.none(), {\n\t\t\t\t\t\t\t\t\t\tonNone: () => ({}),\n\t\t\t\t\t\t\t\t\t\tonSome: (error) => ({ error }),\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t: [],\n\t\t\t\t);\n\t\t\t\treturn { entries };\n\t\t\t}),\n\t\t\t\"thread.queue\": Effect.fnUntraced(function* (ref) {\n\t\t\t\tconst pending = yield* control.pending(yield* resolve(ref));\n\t\t\t\treturn {\n\t\t\t\t\tentries: pending.map((input) => ({\n\t\t\t\t\t\tid: input.id,\n\t\t\t\t\t\tdelivery: input.delivery,\n\t\t\t\t\t\ttext: PromptSchema.Prompt.text(input.prompt),\n\t\t\t\t\t\tcreatedAt: DateTime.toEpochMillis(input.timeCreated),\n\t\t\t\t\t})),\n\t\t\t\t};\n\t\t\t}),\n\t\t\t\"thread.prompt\": Effect.fnUntraced(function* ({ text, delivery, id, ...ref }) {\n\t\t\t\tconst admitted = yield* control.prompt({\n\t\t\t\t\t...ref,\n\t\t\t\t\tprompt: PromptSchema.Prompt.fromText(text),\n\t\t\t\t\t...(delivery === undefined ? {} : { delivery }),\n\t\t\t\t\t...(id === undefined ? {} : { id }),\n\t\t\t\t});\n\t\t\t\treturn { threadId: admitted.threadId };\n\t\t\t}),\n\t\t\t\"thread.interrupt\": Effect.fnUntraced(function* (ref) {\n\t\t\t\t// Ack only: the wire answers \"was there work to stop\", and the caller\n\t\t\t\t// uses `thread.wait` when it needs cleanup to have finished.\n\t\t\t\treturn { interrupted: yield* control.interrupt(yield* resolve(ref), { reason: \"user\" }) };\n\t\t\t}),\n\t\t\t\"thread.cancel\": Effect.fnUntraced(function* ({ messageId, ...ref }) {\n\t\t\t\treturn { cancelled: yield* control.cancel(yield* resolve(ref), messageId) };\n\t\t\t}),\n\t\t\t\"thread.update\": Effect.fnUntraced(function* ({ messageId, delivery, text, ...ref }) {\n\t\t\t\tconst updated = yield* control.update(yield* resolve(ref), messageId, {\n\t\t\t\t\t...(delivery === undefined ? {} : { delivery }),\n\t\t\t\t\t...(text === undefined ? {} : { prompt: PromptSchema.Prompt.fromText(text) }),\n\t\t\t\t});\n\t\t\t\treturn { updated };\n\t\t\t}),\n\t\t\t\"thread.message\": Effect.fnUntraced(function* ({ messageId, ...ref }) {\n\t\t\t\t// Scoped to the thread's line: an entry id is global, and a client should not learn\n\t\t\t\t// about conversations it did not ask for. An inherited prompt is in the thread's.\n\t\t\t\tconst line = yield* threads.line(yield* resolve(ref));\n\t\t\t\treturn { found: line.some(({ entry }) => entry.id === messageId) };\n\t\t\t}),\n\t\t\t\"thread.wait\": Effect.fnUntraced(function* (ref) {\n\t\t\t\tyield* control.wait(yield* resolve(ref));\n\t\t\t}),\n\t\t\t\"mcp.connect\": mcpControl(\"connect\"),\n\t\t\t\"mcp.disconnect\": mcpControl(\"disconnect\"),\n\t\t\t\"sandbox.drivers\": Effect.fnUntraced(function* () {\n\t\t\t\tconst drivers = yield* Sandbox.drivers();\n\t\t\t\treturn drivers.map(({ name, kind }) => ({ name, kind }));\n\t\t\t}),\n\t\t\t\"sandbox.list\": Effect.fnUntraced(function* () {\n\t\t\t\treturn (yield* Sandbox.list()).map(toSandboxInfo);\n\t\t\t}),\n\t\t\t\"sandbox.create\": Effect.fnUntraced(function* ({ driver }) {\n\t\t\t\treturn toSandboxInfo(yield* exported(\"Server.sandbox.create\", Sandbox.create({ driver })));\n\t\t\t}),\n\t\t\t\"sandbox.register\": Effect.fnUntraced(function* ({ driver, providerResourceId }) {\n\t\t\t\treturn toSandboxInfo(yield* Sandbox.register({ driver, providerResourceId }));\n\t\t\t}),\n\t\t\t\"sandbox.stop\": Effect.fnUntraced(function* ({ sandboxId }) {\n\t\t\t\tyield* Sandbox.stop(sandboxId);\n\t\t\t}),\n\t\t\t// Acquiring the feed subscription is the readiness barrier: `server.connected`\n\t\t\t// is only emitted once this client is registered, so a prompt admitted after\n\t\t\t// it cannot land in the gap.\n\t\t\t\"event.subscribe\": ({ threadId }) =>\n\t\t\t\tStream.unwrap(\n\t\t\t\t\tfeed.subscribe.pipe(\n\t\t\t\t\t\tEffect.map((events) =>\n\t\t\t\t\t\t\tStream.make({ id: EventSchema.ID.create(), type: Envelope.Connected.type, data: {} }).pipe(\n\t\t\t\t\t\t\t\tStream.concat(\n\t\t\t\t\t\t\t\t\tthreadId === undefined ? events : events.pipe(Stream.filter(Envelope.ofThread(threadId))),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t});\n\t}),\n);\n\nexport * as Handlers from \"./handlers.ts\";\n","import { Control, Global, Harness, Sandbox } from \"@codeworksh/harness/effect\";\nimport { NodeHttpServer } from \"@effect/platform-node\";\nimport { Effect, Layer } from \"effect\";\nimport { HttpRouter, HttpServer } from \"effect/http\";\nimport * as NetAddress from \"effect/net/NetAddress\";\nimport { RpcSerialization, RpcServer } from \"effect/rpc\";\n/* @effect-diagnostics nodeBuiltinImport:off -- the RPC listener needs a raw node server. */\nimport { createServer } from \"node:http\";\nimport { Contract } from \"./contract.ts\";\nimport { EventFeed } from \"./feed.ts\";\nimport { Handlers } from \"./handlers.ts\";\nimport { Identity } from \"./identity.ts\";\nimport { OAuth } from \"./oauth.ts\";\nimport { Registration } from \"./registration.ts\";\n\n// Managed instances outlive any single RPC; the serve scope is what stops them.\nconst managedShutdown = Layer.unwrap(\n\tEffect.gen(function* () {\n\t\tconst control = yield* Control.Service;\n\t\tyield* Effect.addFinalizer(() =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\t// Release drain leases before stopping the server's managed sandboxes.\n\t\t\t\t// Both phases are best effort and bounded so a provider cannot prevent\n\t\t\t\t// process shutdown; an interrupted stop is persisted as faulted and can\n\t\t\t\t// recover the next time that sandbox is mounted.\n\t\t\t\tyield* Effect.forEach(\n\t\t\t\t\tyield* control.active,\n\t\t\t\t\t(id) =>\n\t\t\t\t\t\tcontrol\n\t\t\t\t\t\t\t.interrupt(id, { reason: \"shutdown\", awaitSettlement: true })\n\t\t\t\t\t\t\t.pipe(Effect.timeout(\"10 seconds\"), Effect.ignore),\n\t\t\t\t\t{ concurrency: \"unbounded\", discard: true },\n\t\t\t\t);\n\t\t\t\tconst infos = yield* Sandbox.list();\n\t\t\t\tyield* Effect.forEach(\n\t\t\t\t\tinfos.filter((info) => info.ownership === \"managed\"),\n\t\t\t\t\t(info) =>\n\t\t\t\t\t\tSandbox.stop(info.id).pipe(\n\t\t\t\t\t\t\tEffect.timeout(\"10 seconds\"),\n\t\t\t\t\t\t\tEffect.catchCause((cause) =>\n\t\t\t\t\t\t\t\tEffect.logError(\"Failed to stop managed sandbox during shutdown\", cause).pipe(\n\t\t\t\t\t\t\t\t\tEffect.annotateLogs({ sandboxInstanceId: info.id }),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t{ concurrency: \"unbounded\", discard: true },\n\t\t\t\t);\n\t\t\t}),\n\t\t);\n\t\treturn Layer.empty;\n\t}),\n);\n\n/**\n * Resumes the runs the last server left unfinished, whether it crashed or shut down: the session\n * table records them as they start, so this needs nothing from the previous process.\n */\nconst resumeUnfinished = Layer.effectDiscard(\n\tEffect.gen(function* () {\n\t\tconst control = yield* Control.Service;\n\t\tyield* Effect.forkScoped(control.resumeUnfinished);\n\t}),\n);\n\n/**\n * Advertises the listener once it has an address: logs the endpoint and files\n * the registration later invocations discover it through.\n */\nconst announce = Layer.unwrap(\n\tEffect.gen(function* () {\n\t\tconst server = yield* HttpServer.HttpServer;\n\t\tconst global = yield* Global.Service;\n\t\tconst identity = yield* Identity.Service;\n\t\t// A ws server always binds TCP; the guard keeps the logger honest if that ever changes.\n\t\tconst address = server.address;\n\t\tconst url = `${NetAddress.formatUrlUnsafe(address, \"ws\")}${Contract.path}`;\n\t\tyield* Effect.log(`codework serve listening on ${url}`);\n\t\tif (!NetAddress.isInetAddress(address)) return Layer.empty;\n\t\treturn Registration.register({\n\t\t\thome: global.home,\n\t\t\tinfo: { pid: identity.pid, version: identity.version, url, port: address.port },\n\t\t});\n\t}),\n);\n\nexport const layer = (options: { host: string; port: number; harness: Harness.Options }) => {\n\tconst rpc = RpcServer.layerHttp({ group: Contract.Api, path: Contract.path, protocol: \"websocket\" }).pipe(\n\t\tLayer.provide(Handlers.layer.pipe(Layer.provide(EventFeed.layer))),\n\t);\n\tconst app = HttpRouter.serve(rpc, { disableListenLog: true }).pipe(\n\t\tLayer.provideMerge(managedShutdown),\n\t\tLayer.provideMerge(resumeUnfinished),\n\t\tLayer.provide(OAuth.layer(options.harness.home === undefined ? {} : { home: options.harness.home })),\n\t);\n\treturn app.pipe(\n\t\tLayer.provideMerge(announce),\n\t\tLayer.provideMerge(NodeHttpServer.layer(createServer, { host: options.host, port: options.port })),\n\t\tLayer.provide(RpcSerialization.layerNdjson),\n\t\tLayer.provide(Identity.layer),\n\t\tLayer.provide(Harness.layer(options.harness)),\n\t);\n};\n\nexport * as Server from \"./server.ts\";\n","import { Global } from \"@codeworksh/harness/effect\";\nimport { Effect, FileSystem, Layer, Logger } from \"effect\";\nimport { Runtime } from \"../../../framework/runtime.ts\";\nimport { Registration } from \"../../../server/registration.ts\";\nimport { Server } from \"../../../server/server.ts\";\nimport { renderError } from \"../../error.ts\";\nimport { harnessOptions } from \"../../harness.ts\";\nimport { writeError } from \"../../output.ts\";\nimport { Cmd } from \"../cmd.ts\";\n\nconst failed = Effect.sync(() => {\n\tprocess.exitCode = 1;\n});\n\nconst report = (error: unknown) => writeError(renderError(error)).pipe(Effect.andThen(failed));\n\nexport default Runtime.handler(\n\tCmd.commands.serve,\n\tEffect.fn(\"CLI.serve\", { level: \"Info\" })(function* ({ host, port, service }) {\n\t\tconst shared = yield* Cmd.spec;\n\t\tconst harness = { ...harnessOptions(shared), watchModels: true };\n\t\tconst serve = Layer.launch(Server.layer({ host, port, harness }));\n\t\tif (!service) return yield* serve.pipe(Effect.catch(report));\n\n\t\t// A background server has no terminal: its log, and the reason it stopped, go to a\n\t\t// file the CLI that started it reads back when startup fails.\n\t\tconst background = Effect.gen(function* () {\n\t\t\tconst paths = yield* Global.resolve(harness.home === undefined ? {} : { home: harness.home });\n\t\t\tconst fs = yield* FileSystem.FileSystem;\n\t\t\tyield* fs.makeDirectory(paths.log, { recursive: true });\n\t\t\tconst logger = Logger.formatSimple.pipe(Logger.toFile(Registration.log(paths.log), { flag: \"w\" }));\n\t\t\tyield* serve.pipe(\n\t\t\t\tEffect.catch((error) => Effect.logError(renderError(error).trim()).pipe(Effect.andThen(failed))),\n\t\t\t\tEffect.provide(Logger.layer([logger])),\n\t\t\t);\n\t\t});\n\t\tyield* background.pipe(Effect.catch(report));\n\t}),\n);\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { m as make, p as layer } from "./error-BVSfzBzb.mjs";
|
|
2
|
-
import { a as file, i as command, n as current, o as infoJson, s as log } from "./identity-
|
|
2
|
+
import { a as file, i as command, n as current, o as infoJson, s as log } from "./identity-CQBhON8m.mjs";
|
|
3
3
|
import { Effect, FileSystem, Layer, Option, Ref, Schedule, Schema } from "effect";
|
|
4
4
|
import { Global } from "@codeworksh/harness/effect";
|
|
5
5
|
import { ChildProcess, ChildProcessSpawner } from "effect/process";
|
|
@@ -219,4 +219,4 @@ const options = (shared, server) => home(shared).pipe(Effect.map((paths) => ({
|
|
|
219
219
|
//#endregion
|
|
220
220
|
export { keepAlive as a, ensure as i, options as n, stop as o, discover as r, probe as s, home as t };
|
|
221
221
|
|
|
222
|
-
//# sourceMappingURL=service-
|
|
222
|
+
//# sourceMappingURL=service-BQdaO_Ap.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-Bka-Vghv.mjs","names":["Client.layer","Client.make","Registration.infoJson","Health.probe","Registration.file","log","Registration.log","Registration.command"],"sources":["../../src/server/health.ts","../../src/server/discovery.ts","../../src/cli/service.ts"],"sourcesContent":["import { Effect, Layer } from \"effect\";\nimport { Client } from \"./client.ts\";\n\n/**\n * One `server.info` call, with the answer normalized to `undefined` for every\n * way a server can fail to answer: unreachable, slow, or speaking a different\n * protocol. A health check that throws where it should say \"no\" would make\n * every caller wrap it in a catch.\n */\nexport const probe = (url: string) =>\n\tEffect.gen(function* () {\n\t\tconst context = yield* Layer.build(Client.layer(url)).pipe(Effect.orElseSucceed(() => undefined));\n\t\tif (context === undefined) return undefined;\n\t\treturn yield* Effect.gen(function* () {\n\t\t\tconst rpc = yield* Client.make;\n\t\t\treturn yield* rpc[\"server.info\"]({}).pipe(Effect.timeout(\"1 second\"));\n\t\t}).pipe(\n\t\t\tEffect.provideContext(context),\n\t\t\tEffect.orElseSucceed(() => undefined),\n\t\t);\n\t}).pipe(Effect.scoped);\n\nexport * as Health from \"./health.ts\";\n","import { type Duration, Effect, FileSystem, Option, Ref, Schedule, Schema } from \"effect\";\nimport { ChildProcess, ChildProcessSpawner } from \"effect/process\";\nimport { Health } from \"./health.ts\";\nimport { Identity } from \"./identity.ts\";\nimport { Registration } from \"./registration.ts\";\n\n/** A server a client can connect to, and the process and port behind it. */\nexport interface Endpoint {\n\treadonly url: string;\n\treadonly pid: number;\n\treadonly port: number;\n}\n\n/** A managed server could not be produced, in the words the CLI prints. */\nexport class ServerStartError extends Schema.TaggedError<ServerStartError>()(\"Discovery.ServerStartError\", {\n\tmessage: Schema.String,\n}) {}\n\nexport interface Options {\n\t/** The CodeWork home whose `service.json` names the server. */\n\treadonly home: string;\n\t/** The home's log directory, where a background server writes `server.log`. */\n\treadonly log: string;\n\treadonly host: string;\n\treadonly port: number;\n\t/** Server-owned flags placed before `serve`. */\n\treadonly args: ReadonlyArray<string>;\n}\n\nconst START_TIMEOUT = \"20 seconds\";\nconst RACE_GRACE = \"2 seconds\";\nconst STOP_TIMEOUT = \"5 seconds\";\n\nconst decode = Schema.decodeUnknownEffect(Registration.infoJson);\n\nconst read = (path: string) =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\tconst text = yield* fs.readFileString(path).pipe(Effect.option);\n\t\tif (Option.isNone(text)) return undefined;\n\t\treturn yield* decode(text.value).pipe(Effect.option, Effect.map(Option.getOrUndefined));\n\t});\n\nconst remove = (path: string) =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\tyield* fs.remove(path);\n\t}).pipe(Effect.ignore);\n\n/** Whether `pid` is a running process. EPERM means it exists but belongs to someone else. */\nconst alive = (pid: number) =>\n\tEffect.try({ try: () => process.kill(pid, 0), catch: (error) => (error as NodeJS.ErrnoException).code }).pipe(\n\t\tEffect.as(true),\n\t\tEffect.catch((code) => Effect.succeed(code === \"EPERM\")),\n\t);\n\n/** Whether `pid` exits within `timeout`. */\nconst exits = (pid: number, timeout: typeof STOP_TIMEOUT) =>\n\talive(pid).pipe(\n\t\tEffect.repeat({ while: (running) => running, schedule: Schedule.spaced(\"50 millis\") }),\n\t\tEffect.timeoutOption(timeout),\n\t\tEffect.map(Option.isSome),\n\t);\n\n/**\n * The registered server, with `live` set when the process answering its endpoint\n * is the one that registered. The file is a hint, never proof: a different server\n * on a reused port must not pass for it.\n */\nconst registered = (path: string) =>\n\tEffect.gen(function* () {\n\t\tconst info = yield* read(path);\n\t\tif (info === undefined) return undefined;\n\t\tconst live = yield* Health.probe(info.url);\n\t\treturn { info, live: live?.pid === info.pid ? live : undefined };\n\t});\n\nconst endpoint = (info: Registration.Info): Endpoint => ({ url: info.url, pid: info.pid, port: info.port });\n\n/** The running server registered for `home`, with the build it reports. */\nexport const discover = (home: string) =>\n\tregistered(Registration.file(home)).pipe(\n\t\tEffect.map((found) =>\n\t\t\tfound?.live === undefined ? undefined : { ...endpoint(found.info), version: found.live.version },\n\t\t),\n\t);\n\n/**\n * Stop the server registered for `home`, returning it, or undefined when none\n * answers. Only a server that confirms it is the registrant is signalled: a pid\n * on file may since have been reused by an unrelated process.\n */\nexport const stop = (home: string) =>\n\tEffect.gen(function* () {\n\t\tconst path = Registration.file(home);\n\t\tconst found = yield* registered(path);\n\t\tif (found === undefined) return undefined;\n\t\tif (found.live === undefined) {\n\t\t\tif (!(yield* alive(found.info.pid))) yield* remove(path);\n\t\t\treturn undefined;\n\t\t}\n\t\tyield* terminate(path, found.info.pid);\n\t\treturn endpoint(found.info);\n\t});\n\n/**\n * Ensure a healthy local server for `home`: reuse the registered one, replace it\n * when `replace` is set and it runs a different build, or start a background one.\n *\n * The background server is detached and outlives this caller, so the next\n * invocation reuses it. When two callers race, only the contender that binds the\n * port registers; the loser exits and both adopt the winner, because a caller\n * only ever believes a registration it can confirm over the wire.\n */\nexport const ensure = (\n\toptions: Options & {\n\t\treadonly replace: boolean;\n\t\treadonly onStart?: (reason: \"missing\" | \"version-mismatch\") => void;\n\t},\n) =>\n\tEffect.gen(function* () {\n\t\tconst path = Registration.file(options.home);\n\t\tconst found = yield* registered(path);\n\t\tif (found?.live !== undefined) {\n\t\t\tif (!options.replace || found.live.version === Identity.current.version) return endpoint(found.info);\n\t\t\tyield* Effect.sync(() => options.onStart?.(\"version-mismatch\"));\n\t\t\tyield* terminate(path, found.info.pid);\n\t\t} else {\n\t\t\t// A file nothing answers for, left by a crash, must not mislead the next caller.\n\t\t\tif (found !== undefined && !(yield* alive(found.info.pid))) yield* remove(path);\n\t\t\tyield* Effect.sync(() => options.onStart?.(\"missing\"));\n\t\t}\n\t\treturn yield* start(path, options);\n\t});\n\n/** The registered server once it answers, polled every 200ms for up to `timeout`. */\nconst ready = (path: string, timeout: Duration.Input, pending: Effect.Effect<boolean>) =>\n\tEffect.gen(function* () {\n\t\tconst next = yield* registered(path);\n\t\tif (next?.live !== undefined) return Option.some(endpoint(next.info));\n\t\t// A live registrant that does not answer yet is another caller's server starting up.\n\t\tconst waiting = (yield* pending) || (next !== undefined && (yield* alive(next.info.pid)));\n\t\treturn waiting ? Option.none() : yield* Effect.fail(\"exited\" as const);\n\t}).pipe(\n\t\tEffect.repeat({ until: Option.isSome, schedule: Schedule.spaced(\"200 millis\") }),\n\t\tEffect.timeoutOption(timeout),\n\t\tEffect.map(Option.flatten),\n\t\tEffect.orElseSucceed(() => Option.none<Endpoint>()),\n\t);\n\n/**\n * Start a background server and wait for it to register, quoting the reason\n * from its log when it cannot.\n *\n * The contender stays tied to this scope until it is the server adopted: a\n * timeout, an interrupt, or another caller winning the race stops it rather than\n * leaving an unmanaged server behind.\n */\nconst start = (path: string, options: Options) =>\n\tEffect.gen(function* () {\n\t\tconst contender = yield* spawn(options);\n\t\tconst won = yield* ready(path, START_TIMEOUT, contender.isRunning.pipe(Effect.orElseSucceed(() => false)));\n\t\t// A contender that lost the bind race exits before the winner may have filed its\n\t\t// registration; give the winner a moment before calling the start a failure.\n\t\tconst server = Option.isSome(won) ? won : yield* ready(path, RACE_GRACE, Effect.succeed(true));\n\t\tif (Option.isSome(server)) {\n\t\t\tif (server.value.pid === contender.pid) yield* contender.unref.pipe(Effect.asVoid);\n\t\t\treturn server.value;\n\t\t}\n\n\t\tconst log = Registration.log(options.log);\n\t\tconst reason = yield* lastLine(log);\n\t\treturn yield* new ServerStartError({\n\t\t\tmessage: [\n\t\t\t\t`could not start a CodeWork server on ${options.host}:${options.port}`,\n\t\t\t\t...(reason === undefined ? [] : [`reason: ${reason}`]),\n\t\t\t\t`log: ${log}`,\n\t\t\t\t\"hint: pass --port to use another port, or point `codework tui --server` at a running server\",\n\t\t\t].join(\"\\n\"),\n\t\t});\n\t}).pipe(Effect.scoped);\n\n/**\n * Keep the session's server running for as long as the caller lives.\n *\n * The TUI only reconnects; it cannot start a server. If the one it uses goes\n * away, this brings one back on the same port so the reconnect lands. It never\n * replaces a running server: another invocation may have just upgraded it.\n */\nexport const keepAlive = (initial: Endpoint, options: Options) =>\n\tEffect.gen(function* () {\n\t\tconst current = yield* Ref.make(initial);\n\t\tyield* Effect.gen(function* () {\n\t\t\tconst server = yield* Ref.get(current);\n\t\t\tif (yield* alive(server.pid)) return;\n\t\t\tconst next = yield* ensure({ ...options, port: server.port, replace: false }).pipe(\n\t\t\t\tEffect.orElseSucceed(() => server),\n\t\t\t);\n\t\t\tyield* Ref.set(current, next);\n\t\t}).pipe(Effect.repeat(Schedule.spaced(\"1 second\")));\n\t});\n\n/** Ask `pid` to shut down, escalating to SIGKILL, and retire its registration. */\nconst terminate = (path: string, pid: number) =>\n\tEffect.gen(function* () {\n\t\tconst signal = (name: NodeJS.Signals) => Effect.try(() => process.kill(pid, name)).pipe(Effect.ignore);\n\t\tyield* signal(\"SIGTERM\");\n\t\tif (!(yield* exits(pid, STOP_TIMEOUT))) {\n\t\t\tyield* signal(\"SIGKILL\");\n\t\t\tyield* exits(pid, STOP_TIMEOUT);\n\t\t}\n\t\t// A server removes its own file on a clean exit; this covers the SIGKILL path.\n\t\tconst info = yield* read(path);\n\t\tif (info?.pid === pid) yield* remove(path);\n\t});\n\nconst lastLine = (path: string) =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\tconst text = yield* fs.readFileString(path).pipe(Effect.orElseSucceed(() => \"\"));\n\t\treturn text\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => line.trim())\n\t\t\t.findLast((line) => line.length > 0);\n\t});\n\n/**\n * Spawn `codework serve --service` detached, inheriting this environment so it\n * resolves the same home, catalog and credentials. It writes its own log, so no\n * stdio is tied to this short-lived caller. It stays referenced, and so stopped\n * with the scope, until `start` adopts it.\n */\nconst spawn = (options: Options) =>\n\tEffect.gen(function* () {\n\t\tconst [file, ...base] = Registration.command();\n\t\tif (file === undefined) return yield* Effect.die(new Error(\"could not resolve the codework entrypoint\"));\n\t\tconst spawner = yield* ChildProcessSpawner.ChildProcessSpawner;\n\t\tconst handle = yield* spawner.spawn(\n\t\t\tChildProcess.make(\n\t\t\t\tfile,\n\t\t\t\t[...base, ...options.args, \"serve\", \"--service\", \"--host\", options.host, \"--port\", String(options.port)],\n\t\t\t\t{ detached: true, stdin: \"ignore\", stdout: \"ignore\", stderr: \"ignore\" },\n\t\t\t),\n\t\t);\n\t\treturn handle;\n\t});\n\nexport * as Discovery from \"./discovery.ts\";\n","import { Global } from \"@codeworksh/harness/effect\";\nimport { Effect, Option } from \"effect\";\nimport type { Discovery } from \"../server/discovery.ts\";\n\ninterface Shared {\n\treadonly userConfigDir: Option.Option<string>;\n\treadonly home: Option.Option<string>;\n\treadonly database: Option.Option<string>;\n}\n\n/** The CodeWork home the shared flags name, resolved the way the harness resolves it. */\nexport const home = (shared: Shared) => Global.resolve(Option.isSome(shared.home) ? { home: shared.home.value } : {});\n\n/**\n * How `tui` and `service` find or start the background server: the home whose\n * `service.json` names it, and the server-owned flags it is started with, in the\n * order `serve` parses them.\n */\nexport const options = (shared: Shared, server: { readonly host: string; readonly port: number }) =>\n\thome(shared).pipe(\n\t\tEffect.map((paths): Discovery.Options => ({\n\t\t\thome: paths.home,\n\t\t\tlog: paths.log,\n\t\t\t...server,\n\t\t\targs: [\n\t\t\t\t...(Option.isSome(shared.home) ? [\"--home\", shared.home.value] : []),\n\t\t\t\t...(Option.isSome(shared.database) ? [\"--database\", shared.database.value] : []),\n\t\t\t\t...(Option.isSome(shared.userConfigDir) ? [\"--user-config-dir\", shared.userConfigDir.value] : []),\n\t\t\t],\n\t\t})),\n\t);\n\nexport * as Service from \"./service.ts\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service-BQdaO_Ap.mjs","names":["Client.layer","Client.make","Registration.infoJson","Health.probe","Registration.file","log","Registration.log","Registration.command"],"sources":["../../src/server/health.ts","../../src/server/discovery.ts","../../src/cli/service.ts"],"sourcesContent":["import { Effect, Layer } from \"effect\";\nimport { Client } from \"./client.ts\";\n\n/**\n * One `server.info` call, with the answer normalized to `undefined` for every\n * way a server can fail to answer: unreachable, slow, or speaking a different\n * protocol. A health check that throws where it should say \"no\" would make\n * every caller wrap it in a catch.\n */\nexport const probe = (url: string) =>\n\tEffect.gen(function* () {\n\t\tconst context = yield* Layer.build(Client.layer(url)).pipe(Effect.orElseSucceed(() => undefined));\n\t\tif (context === undefined) return undefined;\n\t\treturn yield* Effect.gen(function* () {\n\t\t\tconst rpc = yield* Client.make;\n\t\t\treturn yield* rpc[\"server.info\"]({}).pipe(Effect.timeout(\"1 second\"));\n\t\t}).pipe(\n\t\t\tEffect.provideContext(context),\n\t\t\tEffect.orElseSucceed(() => undefined),\n\t\t);\n\t}).pipe(Effect.scoped);\n\nexport * as Health from \"./health.ts\";\n","import { type Duration, Effect, FileSystem, Option, Ref, Schedule, Schema } from \"effect\";\nimport { ChildProcess, ChildProcessSpawner } from \"effect/process\";\nimport { Health } from \"./health.ts\";\nimport { Identity } from \"./identity.ts\";\nimport { Registration } from \"./registration.ts\";\n\n/** A server a client can connect to, and the process and port behind it. */\nexport interface Endpoint {\n\treadonly url: string;\n\treadonly pid: number;\n\treadonly port: number;\n}\n\n/** A managed server could not be produced, in the words the CLI prints. */\nexport class ServerStartError extends Schema.TaggedError<ServerStartError>()(\"Discovery.ServerStartError\", {\n\tmessage: Schema.String,\n}) {}\n\nexport interface Options {\n\t/** The CodeWork home whose `service.json` names the server. */\n\treadonly home: string;\n\t/** The home's log directory, where a background server writes `server.log`. */\n\treadonly log: string;\n\treadonly host: string;\n\treadonly port: number;\n\t/** Server-owned flags placed before `serve`. */\n\treadonly args: ReadonlyArray<string>;\n}\n\nconst START_TIMEOUT = \"20 seconds\";\nconst RACE_GRACE = \"2 seconds\";\nconst STOP_TIMEOUT = \"5 seconds\";\n\nconst decode = Schema.decodeUnknownEffect(Registration.infoJson);\n\nconst read = (path: string) =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\tconst text = yield* fs.readFileString(path).pipe(Effect.option);\n\t\tif (Option.isNone(text)) return undefined;\n\t\treturn yield* decode(text.value).pipe(Effect.option, Effect.map(Option.getOrUndefined));\n\t});\n\nconst remove = (path: string) =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\tyield* fs.remove(path);\n\t}).pipe(Effect.ignore);\n\n/** Whether `pid` is a running process. EPERM means it exists but belongs to someone else. */\nconst alive = (pid: number) =>\n\tEffect.try({ try: () => process.kill(pid, 0), catch: (error) => (error as NodeJS.ErrnoException).code }).pipe(\n\t\tEffect.as(true),\n\t\tEffect.catch((code) => Effect.succeed(code === \"EPERM\")),\n\t);\n\n/** Whether `pid` exits within `timeout`. */\nconst exits = (pid: number, timeout: typeof STOP_TIMEOUT) =>\n\talive(pid).pipe(\n\t\tEffect.repeat({ while: (running) => running, schedule: Schedule.spaced(\"50 millis\") }),\n\t\tEffect.timeoutOption(timeout),\n\t\tEffect.map(Option.isSome),\n\t);\n\n/**\n * The registered server, with `live` set when the process answering its endpoint\n * is the one that registered. The file is a hint, never proof: a different server\n * on a reused port must not pass for it.\n */\nconst registered = (path: string) =>\n\tEffect.gen(function* () {\n\t\tconst info = yield* read(path);\n\t\tif (info === undefined) return undefined;\n\t\tconst live = yield* Health.probe(info.url);\n\t\treturn { info, live: live?.pid === info.pid ? live : undefined };\n\t});\n\nconst endpoint = (info: Registration.Info): Endpoint => ({ url: info.url, pid: info.pid, port: info.port });\n\n/** The running server registered for `home`, with the build it reports. */\nexport const discover = (home: string) =>\n\tregistered(Registration.file(home)).pipe(\n\t\tEffect.map((found) =>\n\t\t\tfound?.live === undefined ? undefined : { ...endpoint(found.info), version: found.live.version },\n\t\t),\n\t);\n\n/**\n * Stop the server registered for `home`, returning it, or undefined when none\n * answers. Only a server that confirms it is the registrant is signalled: a pid\n * on file may since have been reused by an unrelated process.\n */\nexport const stop = (home: string) =>\n\tEffect.gen(function* () {\n\t\tconst path = Registration.file(home);\n\t\tconst found = yield* registered(path);\n\t\tif (found === undefined) return undefined;\n\t\tif (found.live === undefined) {\n\t\t\tif (!(yield* alive(found.info.pid))) yield* remove(path);\n\t\t\treturn undefined;\n\t\t}\n\t\tyield* terminate(path, found.info.pid);\n\t\treturn endpoint(found.info);\n\t});\n\n/**\n * Ensure a healthy local server for `home`: reuse the registered one, replace it\n * when `replace` is set and it runs a different build, or start a background one.\n *\n * The background server is detached and outlives this caller, so the next\n * invocation reuses it. When two callers race, only the contender that binds the\n * port registers; the loser exits and both adopt the winner, because a caller\n * only ever believes a registration it can confirm over the wire.\n */\nexport const ensure = (\n\toptions: Options & {\n\t\treadonly replace: boolean;\n\t\treadonly onStart?: (reason: \"missing\" | \"version-mismatch\") => void;\n\t},\n) =>\n\tEffect.gen(function* () {\n\t\tconst path = Registration.file(options.home);\n\t\tconst found = yield* registered(path);\n\t\tif (found?.live !== undefined) {\n\t\t\tif (!options.replace || found.live.version === Identity.current.version) return endpoint(found.info);\n\t\t\tyield* Effect.sync(() => options.onStart?.(\"version-mismatch\"));\n\t\t\tyield* terminate(path, found.info.pid);\n\t\t} else {\n\t\t\t// A file nothing answers for, left by a crash, must not mislead the next caller.\n\t\t\tif (found !== undefined && !(yield* alive(found.info.pid))) yield* remove(path);\n\t\t\tyield* Effect.sync(() => options.onStart?.(\"missing\"));\n\t\t}\n\t\treturn yield* start(path, options);\n\t});\n\n/** The registered server once it answers, polled every 200ms for up to `timeout`. */\nconst ready = (path: string, timeout: Duration.Input, pending: Effect.Effect<boolean>) =>\n\tEffect.gen(function* () {\n\t\tconst next = yield* registered(path);\n\t\tif (next?.live !== undefined) return Option.some(endpoint(next.info));\n\t\t// A live registrant that does not answer yet is another caller's server starting up.\n\t\tconst waiting = (yield* pending) || (next !== undefined && (yield* alive(next.info.pid)));\n\t\treturn waiting ? Option.none() : yield* Effect.fail(\"exited\" as const);\n\t}).pipe(\n\t\tEffect.repeat({ until: Option.isSome, schedule: Schedule.spaced(\"200 millis\") }),\n\t\tEffect.timeoutOption(timeout),\n\t\tEffect.map(Option.flatten),\n\t\tEffect.orElseSucceed(() => Option.none<Endpoint>()),\n\t);\n\n/**\n * Start a background server and wait for it to register, quoting the reason\n * from its log when it cannot.\n *\n * The contender stays tied to this scope until it is the server adopted: a\n * timeout, an interrupt, or another caller winning the race stops it rather than\n * leaving an unmanaged server behind.\n */\nconst start = (path: string, options: Options) =>\n\tEffect.gen(function* () {\n\t\tconst contender = yield* spawn(options);\n\t\tconst won = yield* ready(path, START_TIMEOUT, contender.isRunning.pipe(Effect.orElseSucceed(() => false)));\n\t\t// A contender that lost the bind race exits before the winner may have filed its\n\t\t// registration; give the winner a moment before calling the start a failure.\n\t\tconst server = Option.isSome(won) ? won : yield* ready(path, RACE_GRACE, Effect.succeed(true));\n\t\tif (Option.isSome(server)) {\n\t\t\tif (server.value.pid === contender.pid) yield* contender.unref.pipe(Effect.asVoid);\n\t\t\treturn server.value;\n\t\t}\n\n\t\tconst log = Registration.log(options.log);\n\t\tconst reason = yield* lastLine(log);\n\t\treturn yield* new ServerStartError({\n\t\t\tmessage: [\n\t\t\t\t`could not start a CodeWork server on ${options.host}:${options.port}`,\n\t\t\t\t...(reason === undefined ? [] : [`reason: ${reason}`]),\n\t\t\t\t`log: ${log}`,\n\t\t\t\t\"hint: pass --port to use another port, or point `codework tui --server` at a running server\",\n\t\t\t].join(\"\\n\"),\n\t\t});\n\t}).pipe(Effect.scoped);\n\n/**\n * Keep the session's server running for as long as the caller lives.\n *\n * The TUI only reconnects; it cannot start a server. If the one it uses goes\n * away, this brings one back on the same port so the reconnect lands. It never\n * replaces a running server: another invocation may have just upgraded it.\n */\nexport const keepAlive = (initial: Endpoint, options: Options) =>\n\tEffect.gen(function* () {\n\t\tconst current = yield* Ref.make(initial);\n\t\tyield* Effect.gen(function* () {\n\t\t\tconst server = yield* Ref.get(current);\n\t\t\tif (yield* alive(server.pid)) return;\n\t\t\tconst next = yield* ensure({ ...options, port: server.port, replace: false }).pipe(\n\t\t\t\tEffect.orElseSucceed(() => server),\n\t\t\t);\n\t\t\tyield* Ref.set(current, next);\n\t\t}).pipe(Effect.repeat(Schedule.spaced(\"1 second\")));\n\t});\n\n/** Ask `pid` to shut down, escalating to SIGKILL, and retire its registration. */\nconst terminate = (path: string, pid: number) =>\n\tEffect.gen(function* () {\n\t\tconst signal = (name: NodeJS.Signals) => Effect.try(() => process.kill(pid, name)).pipe(Effect.ignore);\n\t\tyield* signal(\"SIGTERM\");\n\t\tif (!(yield* exits(pid, STOP_TIMEOUT))) {\n\t\t\tyield* signal(\"SIGKILL\");\n\t\t\tyield* exits(pid, STOP_TIMEOUT);\n\t\t}\n\t\t// A server removes its own file on a clean exit; this covers the SIGKILL path.\n\t\tconst info = yield* read(path);\n\t\tif (info?.pid === pid) yield* remove(path);\n\t});\n\nconst lastLine = (path: string) =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\tconst text = yield* fs.readFileString(path).pipe(Effect.orElseSucceed(() => \"\"));\n\t\treturn text\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => line.trim())\n\t\t\t.findLast((line) => line.length > 0);\n\t});\n\n/**\n * Spawn `codework serve --service` detached, inheriting this environment so it\n * resolves the same home, catalog and credentials. It writes its own log, so no\n * stdio is tied to this short-lived caller. It stays referenced, and so stopped\n * with the scope, until `start` adopts it.\n */\nconst spawn = (options: Options) =>\n\tEffect.gen(function* () {\n\t\tconst [file, ...base] = Registration.command();\n\t\tif (file === undefined) return yield* Effect.die(new Error(\"could not resolve the codework entrypoint\"));\n\t\tconst spawner = yield* ChildProcessSpawner.ChildProcessSpawner;\n\t\tconst handle = yield* spawner.spawn(\n\t\t\tChildProcess.make(\n\t\t\t\tfile,\n\t\t\t\t[...base, ...options.args, \"serve\", \"--service\", \"--host\", options.host, \"--port\", String(options.port)],\n\t\t\t\t{ detached: true, stdin: \"ignore\", stdout: \"ignore\", stderr: \"ignore\" },\n\t\t\t),\n\t\t);\n\t\treturn handle;\n\t});\n\nexport * as Discovery from \"./discovery.ts\";\n","import { Global } from \"@codeworksh/harness/effect\";\nimport { Effect, Option } from \"effect\";\nimport type { Discovery } from \"../server/discovery.ts\";\n\ninterface Shared {\n\treadonly userConfigDir: Option.Option<string>;\n\treadonly home: Option.Option<string>;\n\treadonly database: Option.Option<string>;\n}\n\n/** The CodeWork home the shared flags name, resolved the way the harness resolves it. */\nexport const home = (shared: Shared) => Global.resolve(Option.isSome(shared.home) ? { home: shared.home.value } : {});\n\n/**\n * How `tui` and `service` find or start the background server: the home whose\n * `service.json` names it, and the server-owned flags it is started with, in the\n * order `serve` parses them.\n */\nexport const options = (shared: Shared, server: { readonly host: string; readonly port: number }) =>\n\thome(shared).pipe(\n\t\tEffect.map((paths): Discovery.Options => ({\n\t\t\thome: paths.home,\n\t\t\tlog: paths.log,\n\t\t\t...server,\n\t\t\targs: [\n\t\t\t\t...(Option.isSome(shared.home) ? [\"--home\", shared.home.value] : []),\n\t\t\t\t...(Option.isSome(shared.database) ? [\"--database\", shared.database.value] : []),\n\t\t\t\t...(Option.isSome(shared.userConfigDir) ? [\"--user-config-dir\", shared.userConfigDir.value] : []),\n\t\t\t],\n\t\t})),\n\t);\n\nexport * as Service from \"./service.ts\";\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i as Cmd, t as handler } from "./runtime-CwoLsQy7.mjs";
|
|
2
2
|
import { f as writeOut, i as reportFailure } from "./error-BVSfzBzb.mjs";
|
|
3
|
-
import { i as ensure, n as options } from "./service-
|
|
3
|
+
import { i as ensure, n as options } from "./service-BQdaO_Ap.mjs";
|
|
4
4
|
import { Effect } from "effect";
|
|
5
5
|
//#region src/cli/cmd/handlers/service/start.ts
|
|
6
6
|
var start_default = handler(Cmd.commands.service.commands.start, Effect.fn("CLI.service.start")(function* ({ host, port }) {
|
|
@@ -17,4 +17,4 @@ var start_default = handler(Cmd.commands.service.commands.start, Effect.fn("CLI.
|
|
|
17
17
|
//#endregion
|
|
18
18
|
export { start_default as default };
|
|
19
19
|
|
|
20
|
-
//# sourceMappingURL=start-
|
|
20
|
+
//# sourceMappingURL=start-hJJLd1ap.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-
|
|
1
|
+
{"version":3,"file":"start-hJJLd1ap.mjs","names":["Runtime.handler","options","Service.options","Discovery.ensure"],"sources":["../../src/cli/cmd/handlers/service/start.ts"],"sourcesContent":["import { Effect } from \"effect\";\nimport { Runtime } from \"../../../../framework/runtime.ts\";\nimport { Discovery } from \"../../../../server/discovery.ts\";\nimport { reportFailure } from \"../../../error.ts\";\nimport { writeOut } from \"../../../output.ts\";\nimport { Service } from \"../../../service.ts\";\nimport { Cmd } from \"../../cmd.ts\";\n\nexport default Runtime.handler(\n\tCmd.commands.service.commands.start,\n\tEffect.fn(\"CLI.service.start\")(function* ({ host, port }) {\n\t\tconst options = yield* Service.options(yield* Cmd.spec, { host, port });\n\t\tconst server = yield* Discovery.ensure({ ...options, replace: true });\n\t\tyield* writeOut(`${server.url}\\n`);\n\t}, Effect.catch(reportFailure)),\n);\n"],"mappings":";;;;;AAQA,IAAA,gBAAeA,QACd,IAAI,SAAS,QAAQ,SAAS,OAC9B,OAAO,GAAG,mBAAmB,CAAC,CAAC,WAAW,EAAE,MAAM,QAAQ;CACzD,MAAMC,YAAU,OAAOC,QAAgB,OAAO,IAAI,MAAM;EAAE;EAAM;CAAK,CAAC;CACtE,MAAM,SAAS,OAAOC,OAAiB;EAAE,GAAGF;EAAS,SAAS;CAAK,CAAC;CACpE,OAAO,SAAS,GAAG,OAAO,IAAI,GAAG;AAClC,GAAG,OAAO,MAAM,aAAa,CAAC,CAC/B"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i as Cmd, t as handler } from "./runtime-CwoLsQy7.mjs";
|
|
2
2
|
import { f as writeOut, i as reportFailure } from "./error-BVSfzBzb.mjs";
|
|
3
|
-
import { r as discover, t as home } from "./service-
|
|
3
|
+
import { r as discover, t as home } from "./service-BQdaO_Ap.mjs";
|
|
4
4
|
import { Effect } from "effect";
|
|
5
5
|
//#region src/cli/cmd/handlers/service/status.ts
|
|
6
6
|
var status_default = handler(Cmd.commands.service.commands.status, Effect.fn("CLI.service.status")(function* () {
|
|
@@ -11,4 +11,4 @@ var status_default = handler(Cmd.commands.service.commands.status, Effect.fn("CL
|
|
|
11
11
|
//#endregion
|
|
12
12
|
export { status_default as default };
|
|
13
13
|
|
|
14
|
-
//# sourceMappingURL=status-
|
|
14
|
+
//# sourceMappingURL=status-Bp8vjjW9.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status-
|
|
1
|
+
{"version":3,"file":"status-Bp8vjjW9.mjs","names":["Runtime.handler","Service.home","Discovery.discover"],"sources":["../../src/cli/cmd/handlers/service/status.ts"],"sourcesContent":["import { Effect } from \"effect\";\nimport { Runtime } from \"../../../../framework/runtime.ts\";\nimport { Discovery } from \"../../../../server/discovery.ts\";\nimport { reportFailure } from \"../../../error.ts\";\nimport { writeOut } from \"../../../output.ts\";\nimport { Service } from \"../../../service.ts\";\nimport { Cmd } from \"../../cmd.ts\";\n\nexport default Runtime.handler(\n\tCmd.commands.service.commands.status,\n\tEffect.fn(\"CLI.service.status\")(function* () {\n\t\tconst paths = yield* Service.home(yield* Cmd.spec);\n\t\tconst server = yield* Discovery.discover(paths.home);\n\t\tyield* writeOut(`${server?.url ?? \"stopped\"}\\n`);\n\t}, Effect.catch(reportFailure)),\n);\n"],"mappings":";;;;;AAQA,IAAA,iBAAeA,QACd,IAAI,SAAS,QAAQ,SAAS,QAC9B,OAAO,GAAG,oBAAoB,CAAC,CAAC,aAAa;CAC5C,MAAM,QAAQ,OAAOC,KAAa,OAAO,IAAI,IAAI;CACjD,MAAM,SAAS,OAAOC,SAAmB,MAAM,IAAI;CACnD,OAAO,SAAS,GAAG,QAAQ,OAAO,UAAU,GAAG;AAChD,GAAG,OAAO,MAAM,aAAa,CAAC,CAC/B"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i as Cmd, t as handler } from "./runtime-CwoLsQy7.mjs";
|
|
2
2
|
import { i as reportFailure } from "./error-BVSfzBzb.mjs";
|
|
3
|
-
import { o as stop, t as home } from "./service-
|
|
3
|
+
import { o as stop, t as home } from "./service-BQdaO_Ap.mjs";
|
|
4
4
|
import { Effect } from "effect";
|
|
5
5
|
//#region src/cli/cmd/handlers/service/stop.ts
|
|
6
6
|
var stop_default = handler(Cmd.commands.service.commands.stop, Effect.fn("CLI.service.stop")(function* () {
|
|
@@ -10,4 +10,4 @@ var stop_default = handler(Cmd.commands.service.commands.stop, Effect.fn("CLI.se
|
|
|
10
10
|
//#endregion
|
|
11
11
|
export { stop_default as default };
|
|
12
12
|
|
|
13
|
-
//# sourceMappingURL=stop-
|
|
13
|
+
//# sourceMappingURL=stop-C2PWKdVX.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stop-
|
|
1
|
+
{"version":3,"file":"stop-C2PWKdVX.mjs","names":["Runtime.handler","Service.home","Discovery.stop"],"sources":["../../src/cli/cmd/handlers/service/stop.ts"],"sourcesContent":["import { Effect } from \"effect\";\nimport { Runtime } from \"../../../../framework/runtime.ts\";\nimport { Discovery } from \"../../../../server/discovery.ts\";\nimport { reportFailure } from \"../../../error.ts\";\nimport { Service } from \"../../../service.ts\";\nimport { Cmd } from \"../../cmd.ts\";\n\nexport default Runtime.handler(\n\tCmd.commands.service.commands.stop,\n\tEffect.fn(\"CLI.service.stop\")(function* () {\n\t\tconst paths = yield* Service.home(yield* Cmd.spec);\n\t\tyield* Discovery.stop(paths.home);\n\t}, Effect.catch(reportFailure)),\n);\n"],"mappings":";;;;;AAOA,IAAA,eAAeA,QACd,IAAI,SAAS,QAAQ,SAAS,MAC9B,OAAO,GAAG,kBAAkB,CAAC,CAAC,aAAa;CAC1C,MAAM,QAAQ,OAAOC,KAAa,OAAO,IAAI,IAAI;CACjD,OAAOC,KAAe,MAAM,IAAI;AACjC,GAAG,OAAO,MAAM,aAAa,CAAC,CAC/B"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { i as Cmd, t as handler } from "./runtime-CwoLsQy7.mjs";
|
|
2
2
|
import { r as renderError, t as InvalidInputError, u as writeError } from "./error-BVSfzBzb.mjs";
|
|
3
|
-
import { n as current } from "./identity-
|
|
4
|
-
import { a as keepAlive, i as ensure, n as options, s as probe } from "./service-
|
|
3
|
+
import { n as current } from "./identity-CQBhON8m.mjs";
|
|
4
|
+
import { a as keepAlive, i as ensure, n as options, s as probe } from "./service-BQdaO_Ap.mjs";
|
|
5
5
|
import { Effect, Option } from "effect";
|
|
6
6
|
import { ChildProcess, ChildProcessSpawner } from "effect/process";
|
|
7
7
|
//#region src/cli/cmd/handlers/tui.ts
|
|
@@ -73,4 +73,4 @@ var tui_default = handler(Cmd.commands.tui, Effect.fn("CLI.tui", { level: "Info"
|
|
|
73
73
|
//#endregion
|
|
74
74
|
export { tui_default as default };
|
|
75
75
|
|
|
76
|
-
//# sourceMappingURL=tui-
|
|
76
|
+
//# sourceMappingURL=tui-CGVqTA8q.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tui-
|
|
1
|
+
{"version":3,"file":"tui-CGVqTA8q.mjs","names":["Health.probe","Discovery.ensure","Discovery.keepAlive","Runtime.handler","options","Service.options"],"sources":["../../src/cli/cmd/handlers/tui.ts"],"sourcesContent":["import { Effect, Option } from \"effect\";\nimport { ChildProcess, ChildProcessSpawner } from \"effect/process\";\nimport { Runtime } from \"../../../framework/runtime.ts\";\nimport { Discovery } from \"../../../server/discovery.ts\";\nimport { Health } from \"../../../server/health.ts\";\nimport { Identity } from \"../../../server/identity.ts\";\nimport { InvalidInputError, renderError } from \"../../error.ts\";\nimport { writeError } from \"../../output.ts\";\nimport { Service } from \"../../service.ts\";\nimport { Cmd } from \"../cmd.ts\";\n\n/**\n * Adopt a server the user started, only if it answers `server.info`: the UI must\n * never launch against an endpoint that is not a CodeWork server. A different\n * build is allowed, with a warning, because the user chose it.\n */\nconst attach = (url: string) =>\n\tEffect.gen(function* () {\n\t\tconst info = yield* Health.probe(url);\n\t\tif (info === undefined) return yield* new InvalidInputError({ message: `no CodeWork server answered at ${url}` });\n\t\tif (info.version !== Identity.current.version) {\n\t\t\tyield* Effect.sync(() =>\n\t\t\t\tprocess.stderr.write(\n\t\t\t\t\t`warning: server at ${url} runs ${info.version}; this client is ${Identity.current.version}\\n`,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\treturn url;\n\t});\n\n/** Start or reuse the local server, and keep it up while the TUI runs. */\nconst managed = (options: Discovery.Options) =>\n\tEffect.gen(function* () {\n\t\tconst resolved = yield* Discovery.ensure({\n\t\t\t...options,\n\t\t\t// An upgraded CLI must not drive a server from an older build.\n\t\t\treplace: true,\n\t\t\tonStart: (reason) =>\n\t\t\t\tvoid process.stderr.write(\n\t\t\t\t\treason === \"version-mismatch\"\n\t\t\t\t\t\t? \"Restarting CodeWork server (version mismatch)...\\n\"\n\t\t\t\t\t\t: `Starting CodeWork server on ${options.host}:${options.port}...\\n`,\n\t\t\t\t),\n\t\t});\n\t\t// The TUI only reconnects; restoring a server that dies under it is ours to do.\n\t\tyield* Discovery.keepAlive(resolved, options).pipe(Effect.forkScoped);\n\t\treturn resolved.url;\n\t});\n\n/**\n * Run the TUI in the foreground, on this terminal, for as long as this command\n * runs. It stays in this process group (`detached: false`) so it keeps the\n * terminal; stdio is inherited because it draws and reads raw keys itself. The\n * scope is what ties their lifetimes: when this command is interrupted (SIGINT,\n * SIGTERM), closing it terminates the TUI rather than leaving it on the screen.\n */\nconst run = (binary: string, args: ReadonlyArray<string>, env: Record<string, string>) =>\n\tEffect.gen(function* () {\n\t\tconst spawner = yield* ChildProcessSpawner.ChildProcessSpawner;\n\t\tconst tui = yield* spawner.spawn(\n\t\t\tChildProcess.make(binary, [...args], {\n\t\t\t\tenv,\n\t\t\t\textendEnv: true,\n\t\t\t\tdetached: false,\n\t\t\t\tstdin: \"inherit\",\n\t\t\t\tstdout: \"inherit\",\n\t\t\t\tstderr: \"inherit\",\n\t\t\t}),\n\t\t);\n\t\t// A TUI killed by a signal has no exit code; it still must not read as success.\n\t\treturn yield* tui.exitCode.pipe(Effect.orElseSucceed(() => 1));\n\t}).pipe(Effect.scoped);\n\nexport default Runtime.handler(\n\tCmd.commands.tui,\n\tEffect.fn(\"CLI.tui\", { level: \"Info\" })(function* ({ server, host, port, args }) {\n\t\tconst shared = yield* Cmd.spec;\n\n\t\tconst program = Effect.gen(function* () {\n\t\t\tif (Option.isSome(server) && [shared.home, shared.database, shared.userConfigDir].some(Option.isSome)) {\n\t\t\t\treturn yield* new InvalidInputError({\n\t\t\t\t\tmessage: \"--home, --database, and --user-config-dir belong on codework serve when using --server\",\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst options = yield* Service.options(shared, { host, port });\n\t\t\tconst url = yield* Option.isSome(server) ? attach(server.value) : managed(options);\n\n\t\t\t// Imported lazily: binary resolution must stay off the path of every other command.\n\t\t\tconst launcher = yield* Effect.promise(() => import(\"@codeworksh/tui\"));\n\t\t\tconst binary = yield* Effect.try({\n\t\t\t\ttry: () => launcher.resolveBinary(),\n\t\t\t\tcatch: (error) => new InvalidInputError({ message: (error as Error).message }),\n\t\t\t});\n\t\t\treturn yield* run(binary, args, {\n\t\t\t\t[launcher.ENV_SERVER]: url,\n\t\t\t\t// The TUI reads its own config and credentials, so it must resolve the same home\n\t\t\t\t// the server uses; otherwise the UI would show a different installation.\n\t\t\t\tCODEWORK_HOME_DIR: options.home,\n\t\t\t});\n\t\t});\n\n\t\tconst code = yield* program.pipe(\n\t\t\tEffect.scoped,\n\t\t\tEffect.catch((error) => writeError(renderError(error)).pipe(Effect.as(1))),\n\t\t);\n\t\tyield* Effect.sync(() => {\n\t\t\tprocess.exitCode = code;\n\t\t});\n\t}),\n);\n"],"mappings":";;;;;;;;;;;;AAgBA,MAAM,UAAU,QACf,OAAO,IAAI,aAAa;CACvB,MAAM,OAAO,OAAOA,MAAa,GAAG;CACpC,IAAI,SAAS,KAAA,GAAW,OAAO,OAAO,IAAI,kBAAkB,EAAE,SAAS,kCAAkC,MAAM,CAAC;CAChH,IAAI,KAAK,YAAA,QAA6B,SACrC,OAAO,OAAO,WACb,QAAQ,OAAO,MACd,sBAAsB,IAAI,QAAQ,KAAK,QAAQ,mBAAA,QAAoC,QAAQ,GAC5F,CACD;CAED,OAAO;AACR,CAAC;;AAGF,MAAM,WAAW,YAChB,OAAO,IAAI,aAAa;CACvB,MAAM,WAAW,OAAOC,OAAiB;EACxC,GAAG;EAEH,SAAS;EACT,UAAU,WACT,KAAK,QAAQ,OAAO,MACnB,WAAW,qBACR,uDACA,+BAA+B,QAAQ,KAAK,GAAG,QAAQ,KAAK,MAChE;CACF,CAAC;CAED,OAAOC,UAAoB,UAAU,OAAO,CAAC,CAAC,KAAK,OAAO,UAAU;CACpE,OAAO,SAAS;AACjB,CAAC;;;;;;;;AASF,MAAM,OAAO,QAAgB,MAA6B,QACzD,OAAO,IAAI,aAAa;CAavB,OAAO,QAAO,QAXK,OADI,oBAAoB,oBAAA,CAChB,MAC1B,aAAa,KAAK,QAAQ,CAAC,GAAG,IAAI,GAAG;EACpC;EACA,WAAW;EACX,UAAU;EACV,OAAO;EACP,QAAQ;EACR,QAAQ;CACT,CAAC,CACF,EAAA,CAEkB,SAAS,KAAK,OAAO,oBAAoB,CAAC,CAAC;AAC9D,CAAC,CAAC,CAAC,KAAK,OAAO,MAAM;AAEtB,IAAA,cAAeC,QACd,IAAI,SAAS,KACb,OAAO,GAAG,WAAW,EAAE,OAAO,OAAO,CAAC,CAAC,CAAC,WAAW,EAAE,QAAQ,MAAM,MAAM,QAAQ;CAChF,MAAM,SAAS,OAAO,IAAI;CA0B1B,MAAM,OAAO,OAxBG,OAAO,IAAI,aAAa;EACvC,IAAI,OAAO,OAAO,MAAM,KAAK;GAAC,OAAO;GAAM,OAAO;GAAU,OAAO;EAAa,CAAC,CAAC,KAAK,OAAO,MAAM,GACnG,OAAO,OAAO,IAAI,kBAAkB,EACnC,SAAS,yFACV,CAAC;EAGF,MAAMC,YAAU,OAAOC,QAAgB,QAAQ;GAAE;GAAM;EAAK,CAAC;EAC7D,MAAM,MAAM,OAAO,OAAO,OAAO,MAAM,IAAI,OAAO,OAAO,KAAK,IAAI,QAAQD,SAAO;EAGjF,MAAM,WAAW,OAAO,OAAO,cAAc,OAAO,kBAAkB;EACtE,MAAM,SAAS,OAAO,OAAO,IAAI;GAChC,WAAW,SAAS,cAAc;GAClC,QAAQ,UAAU,IAAI,kBAAkB,EAAE,SAAU,MAAgB,QAAQ,CAAC;EAC9E,CAAC;EACD,OAAO,OAAO,IAAI,QAAQ,MAAM;IAC9B,SAAS,aAAa;GAGvB,mBAAmBA,UAAQ;EAC5B,CAAC;CACF,CAE0B,CAAC,CAAC,KAC3B,OAAO,QACP,OAAO,OAAO,UAAU,WAAW,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC,CAC1E;CACA,OAAO,OAAO,WAAW;EACxB,QAAQ,WAAW;CACpB,CAAC;AACF,CAAC,CACF"}
|
package/package-SPg0ayR-.mjs
DELETED
package/package-SPg0ayR-.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"package-SPg0ayR-.mjs","names":[],"sources":["../../package.json"],"sourcesContent":[""],"mappings":""}
|