@codeworksh/cli 0.2.0 → 0.3.0-canary.28.1.geeda473b
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-B-1079QI.mjs → acp-SwI9XMFw.mjs} +4 -4
- package/{acp-B-1079QI.mjs.map → acp-SwI9XMFw.mjs.map} +1 -1
- package/{add-DlwSE-gO.mjs → add-Cih66f0Z.mjs} +2 -2
- package/{add-DlwSE-gO.mjs.map → add-Cih66f0Z.mjs.map} +1 -1
- package/{catalog-BDSnGfE_.mjs → catalog-C1G3pzHZ.mjs} +2 -2
- package/{catalog-BDSnGfE_.mjs.map → catalog-C1G3pzHZ.mjs.map} +1 -1
- package/{check-CpZTFCDq.mjs → check-CWXDjuC1.mjs} +2 -2
- package/{check-CpZTFCDq.mjs.map → check-CWXDjuC1.mjs.map} +1 -1
- package/{identity-bEvmiNcL.mjs → identity-CG81jeBw.mjs} +5 -2
- package/identity-CG81jeBw.mjs.map +1 -0
- package/index.mjs +25 -25
- package/{install-CNWMNyaf.mjs → install-CRGaL_bc.mjs} +2 -2
- package/{install-CNWMNyaf.mjs.map → install-CRGaL_bc.mjs.map} +1 -1
- package/{link-oTpS3aUc.mjs → link-BiwLQTXW.mjs} +2 -2
- package/{link-oTpS3aUc.mjs.map → link-BiwLQTXW.mjs.map} +1 -1
- package/{list-CmHTTB8Z.mjs → list-BvBVZtHt.mjs} +3 -3
- package/{list-CmHTTB8Z.mjs.map → list-BvBVZtHt.mjs.map} +1 -1
- package/{list-DhdnHHJ5.mjs → list-Daq_zh4E.mjs} +2 -2
- package/{list-DhdnHHJ5.mjs.map → list-Daq_zh4E.mjs.map} +1 -1
- package/{login-DPJbdjAY.mjs → login-lsagcqp6.mjs} +3 -3
- package/{login-DPJbdjAY.mjs.map → login-lsagcqp6.mjs.map} +1 -1
- package/{logout-CL5CN_af.mjs → logout-DdkYEWM6.mjs} +3 -3
- package/{logout-CL5CN_af.mjs.map → logout-DdkYEWM6.mjs.map} +1 -1
- package/package-BJvYPszA.mjs +6 -0
- package/package-BJvYPszA.mjs.map +1 -0
- package/package.json +5 -4
- package/{providers-Dg8UlU_O.mjs → providers-CZmPKpb_.mjs} +3 -3
- package/{providers-Dg8UlU_O.mjs.map → providers-CZmPKpb_.mjs.map} +1 -1
- package/{refresh-OsgI6DYK.mjs → refresh-BFxZjrH1.mjs} +3 -3
- package/{refresh-OsgI6DYK.mjs.map → refresh-BFxZjrH1.mjs.map} +1 -1
- package/{refresh-TK948P0j.mjs → refresh-Cbq-iY3f.mjs} +3 -3
- package/{refresh-TK948P0j.mjs.map → refresh-Cbq-iY3f.mjs.map} +1 -1
- package/{reload-_hDmESKE.mjs → reload-C6c48hBY.mjs} +2 -2
- package/{reload-_hDmESKE.mjs.map → reload-C6c48hBY.mjs.map} +1 -1
- package/{remove-DjBJe09T.mjs → remove-lig66J-D.mjs} +2 -2
- package/{remove-DjBJe09T.mjs.map → remove-lig66J-D.mjs.map} +1 -1
- package/{restart-DloUFDBG.mjs → restart-GSXbXKxj.mjs} +3 -3
- package/{restart-DloUFDBG.mjs.map → restart-GSXbXKxj.mjs.map} +1 -1
- package/{run-BpiW8Wxp.mjs → run-DIFNYGN-.mjs} +8 -8
- package/run-DIFNYGN-.mjs.map +1 -0
- package/{runtime-CIBm_3RX.mjs → runtime-B43doHjV.mjs} +69 -6
- package/runtime-B43doHjV.mjs.map +1 -0
- package/{serve-fKFLZdgJ.mjs → serve-C93t1HEt.mjs} +12 -8
- package/serve-C93t1HEt.mjs.map +1 -0
- package/{service-BkUgYkJy.mjs → service-Bovk9vB0.mjs} +2 -2
- package/{service-BkUgYkJy.mjs.map → service-Bovk9vB0.mjs.map} +1 -1
- package/{shared-DjyUhNsi.mjs → shared-wNZoC017.mjs} +2 -2
- package/{shared-DjyUhNsi.mjs.map → shared-wNZoC017.mjs.map} +1 -1
- package/{start-B3ZXEhpi.mjs → start-GrSc5P1a.mjs} +3 -3
- package/{start-B3ZXEhpi.mjs.map → start-GrSc5P1a.mjs.map} +1 -1
- package/{status-B3dsaXWB.mjs → status-BKTDBJk8.mjs} +3 -3
- package/{status-B3dsaXWB.mjs.map → status-BKTDBJk8.mjs.map} +1 -1
- package/{status-BTCqpq7x.mjs → status-CQHqU7_7.mjs} +3 -3
- package/{status-BTCqpq7x.mjs.map → status-CQHqU7_7.mjs.map} +1 -1
- package/{stop-vB5455wM.mjs → stop-BWkQ358A.mjs} +3 -3
- package/{stop-vB5455wM.mjs.map → stop-BWkQ358A.mjs.map} +1 -1
- package/{tui-DJk6oQru.mjs → tui-BEbb9_xS.mjs} +5 -5
- package/tui-BEbb9_xS.mjs.map +1 -0
- package/{update-6Fn2_4fJ.mjs → update-CfrkcWoW.mjs} +2 -2
- package/{update-6Fn2_4fJ.mjs.map → update-CfrkcWoW.mjs.map} +1 -1
- package/identity-bEvmiNcL.mjs.map +0 -1
- package/package-OcWG7JAW.mjs +0 -6
- package/package-OcWG7JAW.mjs.map +0 -1
- package/run-BpiW8Wxp.mjs.map +0 -1
- package/runtime-CIBm_3RX.mjs.map +0 -1
- package/serve-fKFLZdgJ.mjs.map +0 -1
- package/tui-DJk6oQru.mjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as Cmd, t as handler } from "./runtime-
|
|
1
|
+
import { i as Cmd, t as handler } from "./runtime-B43doHjV.mjs";
|
|
2
2
|
import { d as writeOut, i as reportFailure } from "./error-CzUxh0Q9.mjs";
|
|
3
3
|
import { a as targeted, i as read, n as local, r as probe, t as fetchable } from "./entries-8LFGwy4n.mjs";
|
|
4
4
|
import { Effect, Option } from "effect";
|
|
@@ -48,4 +48,4 @@ var update_default = handler(Cmd.commands.plugin.commands.update, Effect.fn("CLI
|
|
|
48
48
|
//#endregion
|
|
49
49
|
export { update_default as default };
|
|
50
50
|
|
|
51
|
-
//# sourceMappingURL=update-
|
|
51
|
+
//# sourceMappingURL=update-CfrkcWoW.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-
|
|
1
|
+
{"version":3,"file":"update-CfrkcWoW.mjs","names":["Runtime.handler"],"sources":["../../src/cli/cmd/handlers/plugin/update.ts"],"sourcesContent":["import { Plugin } from \"@codeworksh/harness/effect\";\nimport { Effect, Option } from \"effect\";\nimport { Runtime } from \"../../../../framework/runtime.ts\";\nimport { reportFailure } from \"../../../error.ts\";\nimport { writeOut } from \"../../../output.ts\";\nimport { Cmd } from \"../../cmd.ts\";\nimport { fetchable, local, probe, read, targeted } from \"./entries.ts\";\n\n/**\n * Take whatever `check` found.\n *\n * Only a plugin that is **already installed** is refreshed: \"not installed\" is not \"outdated\", and\n * `plugin install` is the verb for that. Each refresh publishes a new generation, which a running\n * session picks up at its next exchange -- so this command never has to reach into a server.\n */\nexport default Runtime.handler(\n\tCmd.commands.plugin.commands.update,\n\tEffect.fn(\"CLI.plugin.update\")(function* ({ spec }) {\n\t\tconst program = Effect.gen(function* () {\n\t\t\tconst shared = yield* Cmd.spec;\n\t\t\tconst { entries, cache, hostDir } = yield* read(shared);\n\t\t\tconst selected = yield* targeted(entries, spec, hostDir);\n\t\t\tif (selected.length === 0 && Option.isSome(spec)) return;\n\n\t\t\tlet updated = 0;\n\t\t\tlet failed = 0;\n\t\t\tfor (const entry of selected) {\n\t\t\t\tconst target = fetchable(entry.target);\n\t\t\t\t// A local plugin has no revision to compare and is never copied into the store.\n\t\t\t\tif (target === undefined) {\n\t\t\t\t\tyield* local(entry, spec);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst result = yield* Plugin.update(target, cache, {\n\t\t\t\t\tprobe: probe(cache, entry.from),\n\t\t\t\t\tfrom: entry.from,\n\t\t\t\t\t// Validated while staged, so a refresh that fetches something broken leaves\n\t\t\t\t\t// the generation already in use as the answer. Preserve the loader's reason:\n\t\t\t\t\t// an import failure or invalid definition is not a missing entrypoint.\n\t\t\t\t\tvalidate: (fetched) => Plugin.definition(fetched.entrypoint, entry.reference).pipe(Effect.asVoid),\n\t\t\t\t}).pipe(Effect.result);\n\n\t\t\t\tif (result._tag === \"Failure\") {\n\t\t\t\t\tfailed += 1;\n\t\t\t\t\tyield* writeOut(`${entry.reference} error[${result.failure.reason}]: ${result.failure.message}\\n`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (result.success._tag === \"updated\") {\n\t\t\t\t\tupdated += 1;\n\t\t\t\t\tyield* writeOut(`Updated ${entry.reference} to ${result.success.entry.revision ?? \"a new revision\"}\\n`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// A spec that named only local plugins compared nothing, so there is nothing to sum up.\n\t\t\tif (Option.isSome(spec) && selected.every((entry) => fetchable(entry.target) === undefined)) return;\n\t\t\tyield* writeOut(updated === 0 ? \"Nothing to update.\\n\" : `${updated} updated.\\n`);\n\t\t\tif (failed > 0) process.exitCode = 1;\n\t\t});\n\n\t\treturn yield* program.pipe(Effect.catch(reportFailure));\n\t}),\n);\n"],"mappings":";;;;;;;;;;;;;AAeA,IAAA,iBAAeA,QACd,IAAI,SAAS,OAAO,SAAS,QAC7B,OAAO,GAAG,mBAAmB,CAAC,CAAC,WAAW,EAAE,QAAQ;CA2CnD,OAAO,OA1CS,OAAO,IAAI,aAAa;EACvC,MAAM,SAAS,OAAO,IAAI;EAC1B,MAAM,EAAE,SAAS,OAAO,YAAY,OAAO,KAAK,MAAM;EACtD,MAAM,WAAW,OAAO,SAAS,SAAS,MAAM,OAAO;EACvD,IAAI,SAAS,WAAW,KAAK,OAAO,OAAO,IAAI,GAAG;EAElD,IAAI,UAAU;EACd,IAAI,SAAS;EACb,KAAK,MAAM,SAAS,UAAU;GAC7B,MAAM,SAAS,UAAU,MAAM,MAAM;GAErC,IAAI,WAAW,KAAA,GAAW;IACzB,OAAO,MAAM,OAAO,IAAI;IACxB;GACD;GAEA,MAAM,SAAS,OAAO,OAAO,OAAO,QAAQ,OAAO;IAClD,OAAO,MAAM,OAAO,MAAM,IAAI;IAC9B,MAAM,MAAM;IAIZ,WAAW,YAAY,OAAO,WAAW,QAAQ,YAAY,MAAM,SAAS,CAAC,CAAC,KAAK,OAAO,MAAM;GACjG,CAAC,CAAC,CAAC,KAAK,OAAO,MAAM;GAErB,IAAI,OAAO,SAAS,WAAW;IAC9B,UAAU;IACV,OAAO,SAAS,GAAG,MAAM,UAAU,UAAU,OAAO,QAAQ,OAAO,KAAK,OAAO,QAAQ,QAAQ,GAAG;IAClG;GACD;GACA,IAAI,OAAO,QAAQ,SAAS,WAAW;IACtC,WAAW;IACX,OAAO,SAAS,WAAW,MAAM,UAAU,MAAM,OAAO,QAAQ,MAAM,YAAY,iBAAiB,GAAG;GACvG;EACD;EAGA,IAAI,OAAO,OAAO,IAAI,KAAK,SAAS,OAAO,UAAU,UAAU,MAAM,MAAM,MAAM,KAAA,CAAS,GAAG;EAC7F,OAAO,SAAS,YAAY,IAAI,yBAAyB,GAAG,QAAQ,YAAY;EAChF,IAAI,SAAS,GAAG,QAAQ,WAAW;CACpC,CAEoB,CAAC,CAAC,KAAK,OAAO,MAAM,aAAa,CAAC;AACvD,CAAC,CACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"identity-bEvmiNcL.mjs","names":["pkg.version"],"sources":["../../src/server/registration.ts","../../src/server/identity.ts"],"sourcesContent":["import { Effect, FileSystem, Layer, Option, Path, Schedule, Schema } from \"effect\";\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 */\nexport const command = (): ReadonlyArray<string> => {\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":";;;;;;;;;;;;AAWA,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;;;;;;;;AASD,MAAa,gBAAuC;CACnD,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;;;ACnFA,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/package-OcWG7JAW.mjs
DELETED
package/package-OcWG7JAW.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"package-OcWG7JAW.mjs","names":[],"sources":["../../package.json"],"sourcesContent":[""],"mappings":""}
|
package/run-BpiW8Wxp.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"run-BpiW8Wxp.mjs","names":["Runtime.handler","Client.make","Client.run","Client.layer"],"sources":["../../src/cli/cmd/handlers/run.ts"],"sourcesContent":["import { EventList, type EventSchema, Harness, Sandbox, Session } from \"@codeworksh/harness/effect\";\nimport { Effect, Exit, Fiber, Option, Queue, Ref, Schema, Stream } from \"effect\";\nimport { Runtime } from \"../../../framework/runtime.ts\";\nimport { Client } from \"../../../server/client.ts\";\nimport { InvalidInputError, renderError } from \"../../error.ts\";\nimport { harnessOptions } from \"../../harness.ts\";\nimport {\n\taddUsage,\n\temptyUsage,\n\theader,\n\tterminalColumns,\n\tusage,\n\ttype UsageSummary,\n\twriteError,\n\twriteOut,\n} from \"../../output.ts\";\nimport { Cmd } from \"../cmd.ts\";\n\ninterface RenderState {\n\treadonly usage: UsageSummary;\n\treadonly textSeen: boolean;\n\treadonly textEndsWithNewline: boolean;\n}\n\nconst initialRenderState: RenderState = {\n\tusage: emptyUsage,\n\ttextSeen: false,\n\ttextEndsWithNewline: false,\n};\n\nconst isTextDelta = Schema.is(EventList.LLMTextDelta);\nconst isLLMEnded = Schema.is(EventList.LLMEnded);\nconst isTurnEnded = Schema.is(EventList.TurnEnded);\n\nconst render = (state: Ref.Ref<RenderState>, ended?: Queue.Queue<string>) =>\n\tEffect.fn(\"CLI.render\")(function* (event: EventSchema.Payload) {\n\t\tif (isTextDelta(event)) {\n\t\t\tyield* writeOut(event.data.delta);\n\t\t\tif (event.data.delta.length > 0) {\n\t\t\t\tyield* Ref.update(state, (current) => ({\n\t\t\t\t\t...current,\n\t\t\t\t\ttextSeen: true,\n\t\t\t\t\ttextEndsWithNewline: event.data.delta.endsWith(\"\\n\"),\n\t\t\t\t}));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (isLLMEnded(event)) {\n\t\t\tyield* Ref.update(state, (current) => ({ ...current, usage: addUsage(current.usage, event.data.message) }));\n\t\t\treturn;\n\t\t}\n\t\tif (ended !== undefined && isTurnEnded(event)) {\n\t\t\tyield* Queue.offer(ended, event.data.messageId);\n\t\t}\n\t});\n\nconst finish = Effect.fn(\"CLI.finish\")(function* (state: Ref.Ref<RenderState>, columns: number) {\n\tconst rendered = yield* Ref.get(state);\n\tif (rendered.textSeen && !rendered.textEndsWithNewline) yield* writeOut(\"\\n\");\n\tyield* writeError(usage(rendered.usage, columns));\n});\n\nconst awaitMessage = Effect.fn(\"CLI.awaitMessage\")(function* (ended: Queue.Queue<string>, messageId: string) {\n\twhile ((yield* Queue.take(ended)) !== messageId) {\n\t\t// Earlier turns in the same drain are expected when a tool call continues.\n\t}\n});\n\nconst selectSandbox = Effect.fn(\"CLI.selectSandbox\")(function* (input: Sandbox.Selection) {\n\tconst selection = yield* Sandbox.resolve(input);\n\tif (selection.created && selection.info !== undefined) {\n\t\tconst id = selection.info.id;\n\t\tyield* Effect.addFinalizer(() => Effect.ignore(Sandbox.stop(id)));\n\t}\n\treturn selection.info;\n});\n\nexport default Runtime.handler(\n\tCmd.commands.run,\n\tEffect.fn(\"CLI.run\")(function* ({\n\t\tprompt,\n\t\tsession,\n\t\tcwd,\n\t\tsandboxDriver,\n\t\tsandboxProviderId,\n\t\tsandboxId,\n\t\tprovider,\n\t\tmodel,\n\t\tthinking,\n\t\tserver,\n\t}) {\n\t\tconst shared = yield* Cmd.spec;\n\t\tif (\n\t\t\tOption.isSome(session) &&\n\t\t\t(Option.isSome(cwd) ||\n\t\t\t\tOption.isSome(sandboxDriver) ||\n\t\t\t\tOption.isSome(sandboxProviderId) ||\n\t\t\t\tOption.isSome(sandboxId))\n\t\t) {\n\t\t\treturn yield* new InvalidInputError({\n\t\t\t\tmessage:\n\t\t\t\t\t\"--cwd, --sandbox-driver, --sandbox-id, and --sandbox-provider-id can only be used when creating a new session\",\n\t\t\t});\n\t\t}\n\t\tif (Option.isSome(provider) !== Option.isSome(model)) {\n\t\t\treturn yield* new InvalidInputError({ message: \"--provider and --model must be provided together\" });\n\t\t}\n\t\tif (Option.isSome(sandboxProviderId) && Option.isNone(sandboxDriver)) {\n\t\t\treturn yield* new InvalidInputError({\n\t\t\t\tmessage: \"--sandbox-provider-id requires a remote --sandbox-driver\",\n\t\t\t});\n\t\t}\n\t\tif (Option.isSome(server) && [shared.home, shared.database, shared.userConfigDir].some(Option.isSome)) {\n\t\t\treturn yield* new InvalidInputError({\n\t\t\t\tmessage: \"--home, --database, and --user-config-dir belong on codework serve when using --server\",\n\t\t\t});\n\t\t}\n\n\t\tif (Option.isSome(sandboxId) && (Option.isSome(sandboxDriver) || Option.isSome(sandboxProviderId))) {\n\t\t\treturn yield* new InvalidInputError({\n\t\t\t\tmessage: \"--sandbox-id cannot be combined with --sandbox-driver or --sandbox-provider-id\",\n\t\t\t});\n\t\t}\n\t\tconst selection: Sandbox.Selection = Option.isSome(sandboxId)\n\t\t\t? { id: Sandbox.SandboxInstance.ID.make(sandboxId.value) }\n\t\t\t: {\n\t\t\t\t\tdriver: Option.getOrElse(sandboxDriver, () => \"local\"),\n\t\t\t\t\t...(Option.isNone(sandboxProviderId) ? {} : { providerResourceId: sandboxProviderId.value }),\n\t\t\t\t};\n\n\t\t// The session's host directory, with no flag to set it: a person running a command is always\n\t\t// somewhere, and that somewhere is what they mean by \"this project\". `--cwd` is a different\n\t\t// thing entirely -- where the work runs inside the session's space, which may be a sandbox\n\t\t// on another machine.\n\t\tconst hostDir = Session.AbsolutePath.make(process.cwd());\n\n\t\tconst runtime = {\n\t\t\t...(Option.isNone(provider) || Option.isNone(model)\n\t\t\t\t? {}\n\t\t\t\t: { model: { provider: provider.value, id: model.value } }),\n\t\t\t...(Option.isNone(thinking) ? {} : { thinkingLevel: thinking.value }),\n\t\t};\n\t\tconst remote = Effect.gen(function* () {\n\t\t\tconst rpc = yield* Client.make;\n\t\t\tconst info = Option.isSome(session)\n\t\t\t\t? yield* rpc[\"session.configure\"]({ sessionId: Session.SessionSchema.ID.make(session.value), runtime })\n\t\t\t\t: yield* rpc[\"session.create\"]({\n\t\t\t\t\t\truntime,\n\t\t\t\t\t\t...(Option.isNone(cwd) ? {} : { directory: cwd.value }),\n\t\t\t\t\t\thostDir,\n\t\t\t\t\t\tsandbox: selection,\n\t\t\t\t\t});\n\t\t\tconst state = yield* Ref.make(initialRenderState);\n\t\t\tconst columns = terminalColumns();\n\t\t\tyield* writeError(\n\t\t\t\theader({\n\t\t\t\t\tsessionId: info.id,\n\t\t\t\t\tsandbox: info.sandbox?.driver ?? \"local\",\n\t\t\t\t\tdirectory: info.directory,\n\t\t\t\t\tcolumns,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tif (info.sandbox !== undefined) yield* writeError(`sandbox-id: ${info.sandbox.id}\\n`);\n\t\t\tyield* Client.run(rpc, { sessionId: info.id, text: prompt }, render(state)).pipe(\n\t\t\t\tEffect.onInterrupt(() =>\n\t\t\t\t\trpc[\"session.interrupt\"]({ sessionId: info.id }).pipe(Effect.timeout(\"5 seconds\"), Effect.ignore),\n\t\t\t\t),\n\t\t\t);\n\t\t\tyield* finish(state, columns);\n\t\t});\n\t\tconst program = Effect.gen(function* () {\n\t\t\tlet handle: Session.Handle;\n\t\t\tif (Option.isSome(session)) {\n\t\t\t\thandle = yield* Session.attach({ sessionId: Session.SessionSchema.ID.make(session.value), ...runtime });\n\t\t\t} else {\n\t\t\t\tconst selected = yield* selectSandbox(selection);\n\t\t\t\thandle = yield* Session.create({\n\t\t\t\t\t...runtime,\n\t\t\t\t\t...(selected === undefined ? {} : { sandbox: selected }),\n\t\t\t\t\t...(Option.isNone(cwd) ? {} : { directory: cwd.value }),\n\t\t\t\t\thostDir,\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst ended = yield* Queue.unbounded<string>();\n\t\t\tconst renderState = yield* Ref.make(initialRenderState);\n\t\t\tconst printer = yield* handle\n\t\t\t\t.events()\n\t\t\t\t.pipe(Stream.runForEach(render(renderState, ended)), Effect.forkScoped({ startImmediately: true }));\n\n\t\t\tconst info = yield* handle.info;\n\t\t\tconst columns = terminalColumns();\n\t\t\tyield* writeError(\n\t\t\t\theader({\n\t\t\t\t\tsessionId: handle.id,\n\t\t\t\t\tsandbox: info.sandbox?.driver ?? \"local\",\n\t\t\t\t\tdirectory: info.directory,\n\t\t\t\t\tcolumns,\n\t\t\t\t}),\n\t\t\t);\n\t\t\t// The local command joins execution to retain typed error details.\n\t\t\tconst execution = yield* handle\n\t\t\t\t.prompt({ text: prompt, delivery: \"followUp\" })\n\t\t\t\t.pipe(Effect.andThen(handle.resume()), Effect.exit);\n\t\t\tyield* handle.wait();\n\t\t\tif (Exit.isFailure(execution)) return yield* Effect.failCause(execution.cause);\n\t\t\tconst path = yield* handle.path();\n\t\t\tconst leaf = path.at(-1);\n\t\t\tif (leaf !== undefined) yield* awaitMessage(ended, leaf.entry.id);\n\t\t\tyield* Fiber.interrupt(printer);\n\t\t\tyield* finish(renderState, columns);\n\t\t});\n\n\t\tconst execute = Effect.gen(function* () {\n\t\t\tif (Option.isSome(server)) return yield* remote.pipe(Effect.provide(Client.layer(server.value)));\n\t\t\treturn yield* program.pipe(Effect.provide(Harness.layer(harnessOptions(shared))));\n\t\t});\n\t\treturn yield* execute.pipe(\n\t\t\tEffect.scoped,\n\t\t\tEffect.catch((error) =>\n\t\t\t\twriteError(renderError(error)).pipe(\n\t\t\t\t\tEffect.andThen(\n\t\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\t}),\n);\n"],"mappings":"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"}
|
package/runtime-CIBm_3RX.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-CIBm_3RX.mjs","names":["Spec.make"],"sources":["../../src/framework/spec.ts","../../src/cli/cmd/cmd.ts","../../src/framework/runtime.ts"],"sourcesContent":["import { Command } from \"effect/cli\";\n\n/**\n * A declarative command tree. Specs carry only the shape of a command -- its\n * name, parameters, description, and children -- so the whole CLI surface can\n * be read in one file. Handlers are attached separately by {@link Runtime}, which\n * keeps their imports (and the harness they pull in) off the startup path.\n */\n\nexport interface Example {\n\treadonly command: string;\n\treadonly description: string;\n}\n\ninterface Options<\n\tConfig extends Command.Command.Config,\n\tShared extends Command.Command.FlagConfig,\n\tCommands extends ReadonlyArray<Any>,\n> {\n\treadonly description?: string;\n\treadonly params?: Config;\n\t/** Flags declared here are also parsed by every descendant command. */\n\treadonly shared?: Shared;\n\treadonly examples?: ReadonlyArray<Example>;\n\treadonly commands?: Commands;\n}\n\nexport interface Node<\n\tName extends string,\n\t// The tree is heterogeneous, so a node has to accept any command shape here.\n\t// Concrete types are recovered per-command through `Runtime.Input`.\n\t// biome-ignore lint/suspicious/noExplicitAny: heterogeneous command tree\n\tSpec extends Command.Command<Name, any, any, any, any>,\n\tCommands extends Children,\n> {\n\treadonly name: Name;\n\treadonly spec: Spec;\n\treadonly commands: Commands;\n}\n\n// The command name is invariant on `Command`, so the erased node type has to\n// admit any name for concrete nodes to be assignable to it.\n// biome-ignore lint/suspicious/noExplicitAny: heterogeneous command tree\nexport type Any = Node<string, Command.Command<any, any, any, any, any>, Children>;\nexport type Children = Readonly<Record<string, Any>>;\n\ntype ChildrenOf<Commands extends ReadonlyArray<Any>> = {\n\treadonly [Node in Commands[number] as Node[\"name\"]]: Node;\n};\n\nexport function make<\n\tconst Name extends string,\n\tconst Config extends Command.Command.Config = {},\n\tconst Shared extends Command.Command.FlagConfig = {},\n\tconst Commands extends ReadonlyArray<Any> = [],\n>(name: Name, options: Options<Config, Shared, Commands> = {}) {\n\tlet spec = Command.make(name, options.params ?? ({} as Config)).pipe(\n\t\tCommand.withSharedFlags(options.shared ?? ({} as Shared)),\n\t);\n\tif (options.description !== undefined) spec = spec.pipe(Command.withDescription(options.description));\n\tif (options.examples !== undefined) spec = spec.pipe(Command.withExamples(options.examples));\n\treturn {\n\t\tname,\n\t\tspec,\n\t\tcommands: Object.fromEntries(\n\t\t\t(options.commands ?? []).map((command) => [command.name, command]),\n\t\t) as ChildrenOf<Commands>,\n\t};\n}\n\nexport * as Spec from \"./spec.ts\";\n","import { Model } from \"@codeworksh/aikit\";\nimport { Schema } from \"effect\";\nimport { Argument, Flag } from \"effect/cli\";\nimport { Spec } from \"../../framework/spec.ts\";\n\n/**\n * The full command surface of the `codework` CLI. Declarations only -- each\n * command's behaviour lives in `./handlers`, wired up in `src/index.ts`.\n */\n\nexport const thinkingLevels = Object.values(Model.ThinkingLevelEnum);\n\n/**\n * Every `auth` subcommand answers the same three questions: which provider,\n * whose credentials, and where they live. Only `login` needs anything more.\n */\nconst AuthParams = {\n\topenaiCodex: Flag.Boolean(\"openai-codex\").pipe(\n\t\tFlag.withDescription(\"Use OpenAI Codex OAuth\"),\n\t\tFlag.withDefault(false),\n\t),\n\tgithubCopilot: Flag.Boolean(\"github-copilot\").pipe(\n\t\tFlag.withDescription(\"Use GitHub Copilot OAuth (device flow)\"),\n\t\tFlag.withDefault(false),\n\t),\n\tserver: Flag.String(\"server\").pipe(Flag.withDescription(\"RPC server URL (ws://host:port/rpc/v1)\"), Flag.optional),\n\tauthFile: Flag.String(\"auth-file\").pipe(\n\t\tFlag.withDescription(\"Credential file (defaults to <home>/aikit/auth.json)\"),\n\t\tFlag.optional,\n\t),\n};\n\n/** Where the background server binds when `tui` or `service` has to start one. */\nconst ServerAddress = {\n\thost: Flag.String(\"host\").pipe(\n\t\tFlag.withDescription(\"Host interface the background server binds\"),\n\t\tFlag.withDefault(\"127.0.0.1\"),\n\t),\n\tport: Flag.Int(\"port\").pipe(\n\t\tFlag.withSchema(Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: 65535 }))),\n\t\tFlag.withDescription(\"Port the background server listens on\"),\n\t\tFlag.withDefault(7433),\n\t),\n};\n\nconst JsonFlag = Flag.Boolean(\"json\").pipe(\n\tFlag.withDescription(\"Print machine-readable output\"),\n\tFlag.withDefault(false),\n);\n\nexport const Cmd = Spec.make(\"codework\", {\n\tdescription: \"CodeWork Command Line Interface\",\n\tshared: {\n\t\tuserConfigDir: Flag.String(\"user-config-dir\").pipe(\n\t\t\tFlag.withDescription(\"Directory whose settings.jsonc replaces the user settings in --home\"),\n\t\t\tFlag.optional,\n\t\t),\n\t\thome: Flag.String(\"home\").pipe(\n\t\t\tFlag.withDescription(\"CodeWork home: user settings, credentials, cache and data (default: ~/.codework)\"),\n\t\t\tFlag.optional,\n\t\t),\n\t\tdatabase: Flag.String(\"database\").pipe(Flag.withDescription(\"SQLite database path or :memory:\"), Flag.optional),\n\t},\n\tcommands: [\n\t\tSpec.make(\"auth\", {\n\t\t\tdescription: \"Manage OAuth credentials\",\n\t\t\tcommands: [\n\t\t\t\tSpec.make(\"login\", {\n\t\t\t\t\tdescription: \"Sign in to a provider\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\t...AuthParams,\n\t\t\t\t\t\tbrowser: Flag.Boolean(\"browser\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Open the authorization URL in the default browser\"),\n\t\t\t\t\t\t\tFlag.withDefault(true),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tdevice: Flag.Boolean(\"device\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Use the device-code flow instead of a localhost browser callback\"),\n\t\t\t\t\t\t\tFlag.withDefault(false),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tenterprise: Flag.String(\"enterprise\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"GitHub Enterprise domain for GitHub Copilot login\"),\n\t\t\t\t\t\t\tFlag.optional,\n\t\t\t\t\t\t),\n\t\t\t\t\t\tenableModels: Flag.Boolean(\"enable-models\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Enable unconfigured Copilot catalog models after login\"),\n\t\t\t\t\t\t\tFlag.withDefault(false),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tjson: JsonFlag,\n\t\t\t\t\t},\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t{ command: \"codework auth login --openai-codex\", description: \"Sign in with ChatGPT\" },\n\t\t\t\t\t\t{ command: \"codework auth login --github-copilot\", description: \"Sign in with GitHub Copilot\" },\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework auth login --openai-codex --device\",\n\t\t\t\t\t\t\tdescription: \"Sign in with a device code, no local port\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework auth login --openai-codex --server ws://127.0.0.1:7433/rpc/v1\",\n\t\t\t\t\t\t\tdescription: \"Sign in the running server\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"status\", {\n\t\t\t\t\tdescription: \"Show a stored login without refreshing it\",\n\t\t\t\t\tparams: { ...AuthParams, json: JsonFlag },\n\t\t\t\t\texamples: [{ command: \"codework auth status --openai-codex\", description: \"Show the stored login\" }],\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"refresh\", {\n\t\t\t\t\tdescription: \"Refresh a stored login if it has expired\",\n\t\t\t\t\tparams: { ...AuthParams, json: JsonFlag },\n\t\t\t\t\texamples: [{ command: \"codework auth refresh --openai-codex\", description: \"Renew an expired login\" }],\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"logout\", {\n\t\t\t\t\tdescription: \"Clear a stored login\",\n\t\t\t\t\tparams: AuthParams,\n\t\t\t\t\texamples: [{ command: \"codework auth logout --github-copilot\", description: \"Clear the stored login\" }],\n\t\t\t\t}),\n\t\t\t],\n\t\t}),\n\t\tSpec.make(\"run\", {\n\t\t\tdescription: \"Start or continue an agent session\",\n\t\t\tparams: {\n\t\t\t\tserver: Flag.String(\"server\").pipe(\n\t\t\t\t\tFlag.withDescription(\"RPC server URL (ws://host:port/rpc/v1)\"),\n\t\t\t\t\tFlag.optional,\n\t\t\t\t),\n\t\t\t\tprompt: Argument.String(\"prompt\").pipe(Argument.withDescription(\"Prompt for the agent\")),\n\t\t\t\tsession: Flag.String(\"session\").pipe(\n\t\t\t\t\tFlag.withAlias(\"s\"),\n\t\t\t\t\tFlag.withDescription(\"Continue an existing session\"),\n\t\t\t\t\tFlag.optional,\n\t\t\t\t),\n\t\t\t\tcwd: Flag.String(\"cwd\").pipe(\n\t\t\t\t\tFlag.withAlias(\"C\"),\n\t\t\t\t\tFlag.withDescription(\"Working directory for a new session\"),\n\t\t\t\t\tFlag.optional,\n\t\t\t\t),\n\t\t\t\tsandboxDriver: Flag.String(\"sandbox-driver\").pipe(\n\t\t\t\t\tFlag.withDescription(\"Sandbox driver for a new session (default: local)\"),\n\t\t\t\t\tFlag.optional,\n\t\t\t\t),\n\t\t\t\tsandboxId: Flag.String(\"sandbox-id\").pipe(\n\t\t\t\t\tFlag.withDescription(\"Reuse an existing sandbox instance\"),\n\t\t\t\t\tFlag.optional,\n\t\t\t\t),\n\t\t\t\tsandboxProviderId: Flag.String(\"sandbox-provider-id\").pipe(\n\t\t\t\t\tFlag.withDescription(\"Provider ID of an existing remote sandbox\"),\n\t\t\t\t\tFlag.optional,\n\t\t\t\t),\n\t\t\t\tprovider: Flag.String(\"provider\").pipe(Flag.withDescription(\"Model catalog provider ID\"), Flag.optional),\n\t\t\t\tmodel: Flag.String(\"model\").pipe(Flag.withDescription(\"Model ID\"), Flag.optional),\n\t\t\t\tthinking: Flag.Literals(\"thinking\", thinkingLevels).pipe(\n\t\t\t\t\tFlag.withDescription(\"Reasoning effort the model uses before answering\"),\n\t\t\t\t\tFlag.optional,\n\t\t\t\t),\n\t\t\t},\n\t\t\texamples: [\n\t\t\t\t{ command: 'codework run \"Inspect the failing tests\"', description: \"Create a session\" },\n\t\t\t\t{\n\t\t\t\t\tcommand: 'codework run --provider openai --model gpt-5.5 --thinking high \"Inspect the failing tests\"',\n\t\t\t\t\tdescription: \"Create a session with an explicit model\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tcommand: 'codework run --sandbox-driver daytona \"Inspect the repository\"',\n\t\t\t\t\tdescription: \"Create a Daytona sandbox and session\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tcommand: 'codework run --sandbox-driver daytona --sandbox-provider-id <id> \"Inspect the repository\"',\n\t\t\t\t\tdescription: \"Use an existing remote sandbox\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tcommand: 'codework run --session <id> --provider openai --model gpt-5.6-luna \"Now fix them\"',\n\t\t\t\t\tdescription: \"Continue a session with explicit model bindings\",\n\t\t\t\t},\n\t\t\t],\n\t\t}),\n\t\tSpec.make(\"tui\", {\n\t\t\tdescription: \"Launch the CodeWork terminal UI against the background server\",\n\t\t\tparams: {\n\t\t\t\tserver: Flag.String(\"server\").pipe(\n\t\t\t\t\tFlag.withDescription(\"RPC server URL to use instead of the background server (ws://host:port/rpc/v1)\"),\n\t\t\t\t\tFlag.optional,\n\t\t\t\t),\n\t\t\t\t...ServerAddress,\n\t\t\t\targs: Argument.variadic(\n\t\t\t\t\tArgument.String(\"args\").pipe(Argument.withDescription(\"Arguments forwarded to the terminal UI\")),\n\t\t\t\t),\n\t\t\t},\n\t\t\texamples: [\n\t\t\t\t{ command: \"codework tui\", description: \"Start or reuse the local server and open the terminal UI\" },\n\t\t\t\t{\n\t\t\t\t\tcommand: \"codework tui --server ws://127.0.0.1:7433/rpc/v1\",\n\t\t\t\t\tdescription: \"Attach the terminal UI to a server you started yourself\",\n\t\t\t\t},\n\t\t\t],\n\t\t}),\n\t\tSpec.make(\"serve\", {\n\t\t\tdescription: \"Start the CodeWork RPC server\",\n\t\t\tparams: {\n\t\t\t\thost: Flag.String(\"host\").pipe(\n\t\t\t\t\tFlag.withDescription(\"Host interface to bind\"),\n\t\t\t\t\tFlag.withDefault(\"127.0.0.1\"),\n\t\t\t\t),\n\t\t\t\tport: Flag.Int(\"port\").pipe(\n\t\t\t\t\tFlag.withSchema(Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: 65535 }))),\n\t\t\t\t\tFlag.withDescription(\"Port to listen on (0 for an ephemeral port)\"),\n\t\t\t\t\tFlag.withDefault(7433),\n\t\t\t\t),\n\t\t\t\tservice: Flag.Boolean(\"service\").pipe(\n\t\t\t\t\tFlag.withDescription(\n\t\t\t\t\t\t\"Run as the background server `codework tui` manages, logging to <home>/log/server.log\",\n\t\t\t\t\t),\n\t\t\t\t\tFlag.withDefault(false),\n\t\t\t\t),\n\t\t\t},\n\t\t\texamples: [\n\t\t\t\t{ command: \"codework serve\", description: \"Start the RPC server on 127.0.0.1:7433\" },\n\t\t\t\t{ command: \"codework serve --port 0\", description: \"Choose an available local port\" },\n\t\t\t],\n\t\t}),\n\t\tSpec.make(\"service\", {\n\t\t\tdescription: \"Manage the background server\",\n\t\t\tcommands: [\n\t\t\t\tSpec.make(\"start\", { description: \"Start the background server\", params: ServerAddress }),\n\t\t\t\tSpec.make(\"restart\", { description: \"Restart the background server\", params: ServerAddress }),\n\t\t\t\tSpec.make(\"status\", { description: \"Show background server status\" }),\n\t\t\t\tSpec.make(\"stop\", { description: \"Stop the background server\" }),\n\t\t\t],\n\t\t}),\n\t\tSpec.make(\"session\", {\n\t\t\tdescription: \"Manage sessions\",\n\t\t\tcommands: [\n\t\t\t\tSpec.make(\"link\", {\n\t\t\t\t\tdescription: \"Anchor a session to a host directory\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tsession: Argument.String(\"session-id\").pipe(Argument.withDescription(\"The session to link\")),\n\t\t\t\t\t\tpath: Argument.String(\"path\").pipe(\n\t\t\t\t\t\t\t// The anchor is not a configuration mechanism, but `.codework` is the landmark\n\t\t\t\t\t\t\t// a person recognises, so the help names it to make the directory concrete.\n\t\t\t\t\t\t\tArgument.withDescription(\n\t\t\t\t\t\t\t\t\"Host directory to anchor to — typically the directory holding your .codework configuration; defaults to the shell's\",\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tArgument.optional,\n\t\t\t\t\t\t),\n\t\t\t\t\t\tunlink: Flag.Boolean(\"unlink\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Clear the anchor, leaving the session with no host directory\"),\n\t\t\t\t\t\t\tFlag.withDefault(false),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tserver: Flag.String(\"server\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Base URL of the running codework server\"),\n\t\t\t\t\t\t\tFlag.withDefault(\"http://127.0.0.1:7433\"),\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework session link ses_01h9\",\n\t\t\t\t\t\t\tdescription: \"Link it to the directory you are standing in\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework session link ses_01h9 ~/work/api\",\n\t\t\t\t\t\t\tdescription: \"Link it to a project elsewhere on this machine\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework session link ses_01h9 --unlink\",\n\t\t\t\t\t\t\tdescription: \"Clear the anchor\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t],\n\t\t}),\n\t\tSpec.make(\"plugin\", {\n\t\t\tdescription: \"Manage plugins\",\n\t\t\tcommands: [\n\t\t\t\tSpec.make(\"add\", {\n\t\t\t\t\tdescription: \"Install a plugin and add it to a settings file\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tpackage: Argument.String(\"package\").pipe(\n\t\t\t\t\t\t\tArgument.withDescription(\"Package spec, path, or file: URL\"),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tglobal: Flag.Boolean(\"global\").pipe(\n\t\t\t\t\t\t\tFlag.withAlias(\"g\"),\n\t\t\t\t\t\t\tFlag.withDescription(\"Write the user-wide settings file instead of this project's\"),\n\t\t\t\t\t\t\tFlag.withDefault(false),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tsession: Flag.String(\"session\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Write the project a session is linked to, rather than this directory's\"),\n\t\t\t\t\t\t\tFlag.optional,\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework plugin add @acme/codework-tool-proc@1.2.0\",\n\t\t\t\t\t\t\tdescription: \"Install a published plugin into this project's settings\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework plugin add @acme/codework-tool-proc --session ses_01h9\",\n\t\t\t\t\t\t\tdescription: \"Write the project that session is linked to, from anywhere\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework plugin add @acme/codework-tool-proc -g\",\n\t\t\t\t\t\t\tdescription: \"Install it for every project this user runs\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"install\", {\n\t\t\t\t\tdescription: \"Install every plugin the settings files name\",\n\t\t\t\t\tparams: {},\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework plugin install\",\n\t\t\t\t\t\t\tdescription: \"Materialise what a fresh checkout already declares\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"list\", {\n\t\t\t\t\tdescription: \"List configured plugins and what each one resolved to\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tverbose: Flag.Boolean(\"verbose\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Show the message behind a failure, not only its reason\"),\n\t\t\t\t\t\t\tFlag.withDefault(false),\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\texamples: [{ command: \"codework plugin list\", description: \"Show every configured plugin\" }],\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"check\", {\n\t\t\t\t\tdescription: \"Report which configured plugins have a newer revision available\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tspec: Argument.String(\"spec\").pipe(\n\t\t\t\t\t\t\tArgument.withDescription(\"Only this configured plugin: a package name or spec, git spec, or path\"),\n\t\t\t\t\t\t\tArgument.optional,\n\t\t\t\t\t\t),\n\t\t\t\t\t\t// An answer is reused for an hour, which is right for a command someone may\n\t\t\t\t\t\t// run repeatedly and wrong for the minute after they pushed a plugin. Without\n\t\t\t\t\t\t// this there is no way to say \"ask again\", and `check` reports a moving branch\n\t\t\t\t\t\t// as current while `update` — which always refreshes — moves it.\n\t\t\t\t\t\trefresh: Flag.Boolean(\"refresh\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Ask the remote again instead of reusing a recent answer\"),\n\t\t\t\t\t\t\tFlag.withDefault(false),\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t{ command: \"codework plugin check\", description: \"Ask the registry what has moved\" },\n\t\t\t\t\t\t{ command: \"codework plugin check @acme/codework-tool-proc\", description: \"Ask about one plugin\" },\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework plugin check --refresh\",\n\t\t\t\t\t\t\tdescription: \"Ignore the cached answer, after pushing a plugin\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"update\", {\n\t\t\t\t\tdescription: \"Fetch a newer revision of every plugin that has one\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tspec: Argument.String(\"spec\").pipe(\n\t\t\t\t\t\t\tArgument.withDescription(\"Only this configured plugin: a package name or spec, git spec, or path\"),\n\t\t\t\t\t\t\tArgument.optional,\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t{ command: \"codework plugin update\", description: \"Take whatever `check` found\" },\n\t\t\t\t\t\t{ command: \"codework plugin update @acme/codework-tool-proc\", description: \"Update one plugin\" },\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"reload\", {\n\t\t\t\t\tdescription: \"Re-import configured plugins in a running server\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tserver: Flag.String(\"server\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Base URL of the running codework server\"),\n\t\t\t\t\t\t\tFlag.withDefault(\"http://127.0.0.1:7433\"),\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework plugin reload\",\n\t\t\t\t\t\t\tdescription: \"Pick up edits to a local plugin without restarting\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"remove\", {\n\t\t\t\t\tdescription: \"Remove a plugin from a settings file\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tpackage: Argument.String(\"package\").pipe(\n\t\t\t\t\t\t\tArgument.withDescription(\"Configured package spec, path, or plugin ID\"),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tglobal: Flag.Boolean(\"global\").pipe(\n\t\t\t\t\t\t\tFlag.withAlias(\"g\"),\n\t\t\t\t\t\t\tFlag.withDescription(\"Edit the user-wide settings file instead of this project's\"),\n\t\t\t\t\t\t\tFlag.withDefault(false),\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework plugin remove @acme/codework-tool-proc\",\n\t\t\t\t\t\t\tdescription: \"Drop a plugin and any configuration written against it\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t],\n\t\t}),\n\t\tSpec.make(\"models\", {\n\t\t\tdescription: \"List or refresh the model catalog\",\n\t\t\tparams: {\n\t\t\t\tprovider: Flag.String(\"provider\").pipe(Flag.withDescription(\"Model catalog provider ID\"), Flag.optional),\n\t\t\t},\n\t\t\texamples: [\n\t\t\t\t{ command: \"codework models\", description: \"List all models from all providers\" },\n\t\t\t\t{\n\t\t\t\t\tcommand: \"codework models --provider openai\",\n\t\t\t\t\tdescription: \"List models for a specific provider\",\n\t\t\t\t},\n\t\t\t\t{ command: \"codework models providers\", description: \"List all available provider IDs\" },\n\t\t\t],\n\t\t\tcommands: [\n\t\t\t\tSpec.make(\"providers\", {\n\t\t\t\t\tdescription: \"List available model providers in the catalog\",\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"refresh\", {\n\t\t\t\t\tdescription: \"Download the model catalog into the home if it is stale\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tforce: Flag.Boolean(\"force\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Download it even if it is still fresh\"),\n\t\t\t\t\t\t\tFlag.withDefault(false),\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t{ command: \"codework models refresh\", description: \"Refresh a catalog older than 15 minutes\" },\n\t\t\t\t\t\t{ command: \"codework models refresh --force\", description: \"Download the catalog now\" },\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t],\n\t\t}),\n\t\tSpec.make(\"acp\", {\n\t\t\tdescription: \"Start the CodeWork Agent Client Protocol (ACP) server over stdio\",\n\t\t\texamples: [{ command: \"codework acp\", description: \"Start the ACP server on stdio\" }],\n\t\t}),\n\t],\n});\n","import { Effect } from \"effect\";\nimport { Command } from \"effect/cli\";\nimport type { CommandError } from \"../cli/error.ts\";\nimport { Spec } from \"./spec.ts\";\n\n/**\n * Binds handlers to a {@link Spec} tree. Handlers are loaded through dynamic\n * imports so that starting the process -- or printing `--help` -- never pulls in\n * the harness, its sandbox drivers, or the model catalog.\n */\n\n/** Recovers the parsed input type of a spec node, for typing its handler. */\nexport type Input<Value> =\n\tValue extends Spec.Node<infer _Name, infer Spec, infer _Commands>\n\t\t? Input<Spec>\n\t\t: Value extends Command.Command<infer _Name, infer Parsed, infer _Context, infer _Error, infer _Requirements>\n\t\t\t? Parsed\n\t\t\t: never;\n\n/**\n * A handler may yield an ancestor's spec to read its shared flags, which shows up\n * as a `CommandContext` requirement; `withSubcommands` discharges it when the tree\n * is assembled.\n */\ntype Requirements = Command.Environment | Command.CommandContext<string>;\ntype Run<Parsed> = (input: Parsed) => Effect.Effect<void, CommandError, Requirements>;\ntype Loader<Node extends Spec.Any> = () => Promise<{ readonly default: Run<Input<Node>> }>;\n\n/**\n * The handler registry for a spec tree: a loader per leaf, mirroring the shape of\n * the tree. A parent with children takes its own handler under `$`.\n */\nexport type Handlers<Node extends Spec.Any> = keyof Node[\"commands\"] extends never\n\t? Loader<Node>\n\t: { readonly $?: Loader<Node> } & { readonly [Key in keyof Node[\"commands\"]]: Handlers<Node[\"commands\"][Key]> };\n\ninterface LazyHandler {\n\treadonly spec: Command.Command.Any;\n\t// biome-ignore lint/suspicious/noExplicitAny: input is recovered per-command by `Input`\n\treadonly load: () => Promise<{ readonly default: Run<any> }>;\n}\n\ntype LazyHandlers = LazyHandler[\"load\"] | { readonly [key: string]: LazyHandlers | undefined };\n\ntype ProvidedCommand = Command.Command<string, unknown, unknown, CommandError, Command.Environment>;\n\n/** Type-checks a handler against the spec node it implements. */\nexport function handler<const Node extends Spec.Any>(_node: Node, run: Run<Input<Node>>) {\n\treturn run;\n}\n\nexport function handlers<const Root extends Spec.Any>(\n\troot: Root,\n\thandlers: Handlers<Root>,\n): ReadonlyArray<LazyHandler> {\n\tconst result: LazyHandler[] = [];\n\n\tfunction add(node: Spec.Any, value: LazyHandlers) {\n\t\tif (typeof value === \"function\") {\n\t\t\tresult.push({ spec: node.spec, load: value });\n\t\t\treturn;\n\t\t}\n\t\tif (value.$ !== undefined) result.push({ spec: node.spec, load: value.$ as LazyHandler[\"load\"] });\n\t\tfor (const [name, child] of Object.entries(node.commands)) {\n\t\t\tconst nested = value[name];\n\t\t\tif (nested !== undefined) add(child, nested);\n\t\t}\n\t}\n\n\tadd(root, handlers as LazyHandlers);\n\treturn result;\n}\n\nexport function run(root: Spec.Any, handlers: ReadonlyArray<LazyHandler>, options: { readonly version: string }) {\n\treturn Command.run(provide(root, handlers), options);\n}\n\nfunction provide(node: Spec.Any, handlers: ReadonlyArray<LazyHandler>): ProvidedCommand {\n\tconst found = handlers.find((entry) => entry.spec === node.spec);\n\tconst spec = found\n\t\t? node.spec.pipe(\n\t\t\t\tCommand.withHandler((input) =>\n\t\t\t\t\tEffect.promise(found.load).pipe(Effect.flatMap((module) => module.default(input))),\n\t\t\t\t),\n\t\t\t)\n\t\t: node.spec;\n\tconst children = Object.values(node.commands);\n\tif (children.length === 0) return spec as ProvidedCommand;\n\treturn spec.pipe(Command.withSubcommands(children.map((child) => provide(child, handlers)))) as ProvidedCommand;\n}\n\nexport * as Runtime from \"./runtime.ts\";\n"],"mappings":";;;;AAkDA,SAAgB,KAKd,MAAY,UAA6C,CAAC,GAAG;CAC9D,IAAI,OAAO,QAAQ,KAAK,MAAM,QAAQ,UAAW,CAAC,CAAY,CAAC,CAAC,KAC/D,QAAQ,gBAAgB,QAAQ,UAAW,CAAC,CAAY,CACzD;CACA,IAAI,QAAQ,gBAAgB,KAAA,GAAW,OAAO,KAAK,KAAK,QAAQ,gBAAgB,QAAQ,WAAW,CAAC;CACpG,IAAI,QAAQ,aAAa,KAAA,GAAW,OAAO,KAAK,KAAK,QAAQ,aAAa,QAAQ,QAAQ,CAAC;CAC3F,OAAO;EACN;EACA;EACA,UAAU,OAAO,aACf,QAAQ,YAAY,CAAC,EAAA,CAAG,KAAK,YAAY,CAAC,QAAQ,MAAM,OAAO,CAAC,CAClE;CACD;AACD;;;;;;;AC1DA,MAAa,iBAAiB,OAAO,OAAO,MAAM,iBAAiB;;;;;AAMnE,MAAM,aAAa;CAClB,aAAa,KAAK,QAAQ,cAAc,CAAC,CAAC,KACzC,KAAK,gBAAgB,wBAAwB,GAC7C,KAAK,YAAY,KAAK,CACvB;CACA,eAAe,KAAK,QAAQ,gBAAgB,CAAC,CAAC,KAC7C,KAAK,gBAAgB,wCAAwC,GAC7D,KAAK,YAAY,KAAK,CACvB;CACA,QAAQ,KAAK,OAAO,QAAQ,CAAC,CAAC,KAAK,KAAK,gBAAgB,wCAAwC,GAAG,KAAK,QAAQ;CAChH,UAAU,KAAK,OAAO,WAAW,CAAC,CAAC,KAClC,KAAK,gBAAgB,sDAAsD,GAC3E,KAAK,QACN;AACD;;AAGA,MAAM,gBAAgB;CACrB,MAAM,KAAK,OAAO,MAAM,CAAC,CAAC,KACzB,KAAK,gBAAgB,4CAA4C,GACjE,KAAK,YAAY,WAAW,CAC7B;CACA,MAAM,KAAK,IAAI,MAAM,CAAC,CAAC,KACtB,KAAK,WAAW,OAAO,IAAI,MAAM,OAAO,UAAU;EAAE,SAAS;EAAG,SAAS;CAAM,CAAC,CAAC,CAAC,GAClF,KAAK,gBAAgB,uCAAuC,GAC5D,KAAK,YAAY,IAAI,CACtB;AACD;AAEA,MAAM,WAAW,KAAK,QAAQ,MAAM,CAAC,CAAC,KACrC,KAAK,gBAAgB,+BAA+B,GACpD,KAAK,YAAY,KAAK,CACvB;AAEA,MAAa,MAAMA,KAAU,YAAY;CACxC,aAAa;CACb,QAAQ;EACP,eAAe,KAAK,OAAO,iBAAiB,CAAC,CAAC,KAC7C,KAAK,gBAAgB,qEAAqE,GAC1F,KAAK,QACN;EACA,MAAM,KAAK,OAAO,MAAM,CAAC,CAAC,KACzB,KAAK,gBAAgB,kFAAkF,GACvG,KAAK,QACN;EACA,UAAU,KAAK,OAAO,UAAU,CAAC,CAAC,KAAK,KAAK,gBAAgB,kCAAkC,GAAG,KAAK,QAAQ;CAC/G;CACA,UAAU;EACTA,KAAU,QAAQ;GACjB,aAAa;GACb,UAAU;IACTA,KAAU,SAAS;KAClB,aAAa;KACb,QAAQ;MACP,GAAG;MACH,SAAS,KAAK,QAAQ,SAAS,CAAC,CAAC,KAChC,KAAK,gBAAgB,mDAAmD,GACxE,KAAK,YAAY,IAAI,CACtB;MACA,QAAQ,KAAK,QAAQ,QAAQ,CAAC,CAAC,KAC9B,KAAK,gBAAgB,kEAAkE,GACvF,KAAK,YAAY,KAAK,CACvB;MACA,YAAY,KAAK,OAAO,YAAY,CAAC,CAAC,KACrC,KAAK,gBAAgB,mDAAmD,GACxE,KAAK,QACN;MACA,cAAc,KAAK,QAAQ,eAAe,CAAC,CAAC,KAC3C,KAAK,gBAAgB,wDAAwD,GAC7E,KAAK,YAAY,KAAK,CACvB;MACA,MAAM;KACP;KACA,UAAU;MACT;OAAE,SAAS;OAAsC,aAAa;MAAuB;MACrF;OAAE,SAAS;OAAwC,aAAa;MAA8B;MAC9F;OACC,SAAS;OACT,aAAa;MACd;MACA;OACC,SAAS;OACT,aAAa;MACd;KACD;IACD,CAAC;IACDA,KAAU,UAAU;KACnB,aAAa;KACb,QAAQ;MAAE,GAAG;MAAY,MAAM;KAAS;KACxC,UAAU,CAAC;MAAE,SAAS;MAAuC,aAAa;KAAwB,CAAC;IACpG,CAAC;IACDA,KAAU,WAAW;KACpB,aAAa;KACb,QAAQ;MAAE,GAAG;MAAY,MAAM;KAAS;KACxC,UAAU,CAAC;MAAE,SAAS;MAAwC,aAAa;KAAyB,CAAC;IACtG,CAAC;IACDA,KAAU,UAAU;KACnB,aAAa;KACb,QAAQ;KACR,UAAU,CAAC;MAAE,SAAS;MAAyC,aAAa;KAAyB,CAAC;IACvG,CAAC;GACF;EACD,CAAC;EACDA,KAAU,OAAO;GAChB,aAAa;GACb,QAAQ;IACP,QAAQ,KAAK,OAAO,QAAQ,CAAC,CAAC,KAC7B,KAAK,gBAAgB,wCAAwC,GAC7D,KAAK,QACN;IACA,QAAQ,SAAS,OAAO,QAAQ,CAAC,CAAC,KAAK,SAAS,gBAAgB,sBAAsB,CAAC;IACvF,SAAS,KAAK,OAAO,SAAS,CAAC,CAAC,KAC/B,KAAK,UAAU,GAAG,GAClB,KAAK,gBAAgB,8BAA8B,GACnD,KAAK,QACN;IACA,KAAK,KAAK,OAAO,KAAK,CAAC,CAAC,KACvB,KAAK,UAAU,GAAG,GAClB,KAAK,gBAAgB,qCAAqC,GAC1D,KAAK,QACN;IACA,eAAe,KAAK,OAAO,gBAAgB,CAAC,CAAC,KAC5C,KAAK,gBAAgB,mDAAmD,GACxE,KAAK,QACN;IACA,WAAW,KAAK,OAAO,YAAY,CAAC,CAAC,KACpC,KAAK,gBAAgB,oCAAoC,GACzD,KAAK,QACN;IACA,mBAAmB,KAAK,OAAO,qBAAqB,CAAC,CAAC,KACrD,KAAK,gBAAgB,2CAA2C,GAChE,KAAK,QACN;IACA,UAAU,KAAK,OAAO,UAAU,CAAC,CAAC,KAAK,KAAK,gBAAgB,2BAA2B,GAAG,KAAK,QAAQ;IACvG,OAAO,KAAK,OAAO,OAAO,CAAC,CAAC,KAAK,KAAK,gBAAgB,UAAU,GAAG,KAAK,QAAQ;IAChF,UAAU,KAAK,SAAS,YAAY,cAAc,CAAC,CAAC,KACnD,KAAK,gBAAgB,kDAAkD,GACvE,KAAK,QACN;GACD;GACA,UAAU;IACT;KAAE,SAAS;KAA4C,aAAa;IAAmB;IACvF;KACC,SAAS;KACT,aAAa;IACd;IACA;KACC,SAAS;KACT,aAAa;IACd;IACA;KACC,SAAS;KACT,aAAa;IACd;IACA;KACC,SAAS;KACT,aAAa;IACd;GACD;EACD,CAAC;EACDA,KAAU,OAAO;GAChB,aAAa;GACb,QAAQ;IACP,QAAQ,KAAK,OAAO,QAAQ,CAAC,CAAC,KAC7B,KAAK,gBAAgB,gFAAgF,GACrG,KAAK,QACN;IACA,GAAG;IACH,MAAM,SAAS,SACd,SAAS,OAAO,MAAM,CAAC,CAAC,KAAK,SAAS,gBAAgB,wCAAwC,CAAC,CAChG;GACD;GACA,UAAU,CACT;IAAE,SAAS;IAAgB,aAAa;GAA2D,GACnG;IACC,SAAS;IACT,aAAa;GACd,CACD;EACD,CAAC;EACDA,KAAU,SAAS;GAClB,aAAa;GACb,QAAQ;IACP,MAAM,KAAK,OAAO,MAAM,CAAC,CAAC,KACzB,KAAK,gBAAgB,wBAAwB,GAC7C,KAAK,YAAY,WAAW,CAC7B;IACA,MAAM,KAAK,IAAI,MAAM,CAAC,CAAC,KACtB,KAAK,WAAW,OAAO,IAAI,MAAM,OAAO,UAAU;KAAE,SAAS;KAAG,SAAS;IAAM,CAAC,CAAC,CAAC,GAClF,KAAK,gBAAgB,6CAA6C,GAClE,KAAK,YAAY,IAAI,CACtB;IACA,SAAS,KAAK,QAAQ,SAAS,CAAC,CAAC,KAChC,KAAK,gBACJ,uFACD,GACA,KAAK,YAAY,KAAK,CACvB;GACD;GACA,UAAU,CACT;IAAE,SAAS;IAAkB,aAAa;GAAyC,GACnF;IAAE,SAAS;IAA2B,aAAa;GAAiC,CACrF;EACD,CAAC;EACDA,KAAU,WAAW;GACpB,aAAa;GACb,UAAU;IACTA,KAAU,SAAS;KAAE,aAAa;KAA+B,QAAQ;IAAc,CAAC;IACxFA,KAAU,WAAW;KAAE,aAAa;KAAiC,QAAQ;IAAc,CAAC;IAC5FA,KAAU,UAAU,EAAE,aAAa,gCAAgC,CAAC;IACpEA,KAAU,QAAQ,EAAE,aAAa,6BAA6B,CAAC;GAChE;EACD,CAAC;EACDA,KAAU,WAAW;GACpB,aAAa;GACb,UAAU,CACTA,KAAU,QAAQ;IACjB,aAAa;IACb,QAAQ;KACP,SAAS,SAAS,OAAO,YAAY,CAAC,CAAC,KAAK,SAAS,gBAAgB,qBAAqB,CAAC;KAC3F,MAAM,SAAS,OAAO,MAAM,CAAC,CAAC,KAG7B,SAAS,gBACR,qHACD,GACA,SAAS,QACV;KACA,QAAQ,KAAK,QAAQ,QAAQ,CAAC,CAAC,KAC9B,KAAK,gBAAgB,8DAA8D,GACnF,KAAK,YAAY,KAAK,CACvB;KACA,QAAQ,KAAK,OAAO,QAAQ,CAAC,CAAC,KAC7B,KAAK,gBAAgB,yCAAyC,GAC9D,KAAK,YAAY,uBAAuB,CACzC;IACD;IACA,UAAU;KACT;MACC,SAAS;MACT,aAAa;KACd;KACA;MACC,SAAS;MACT,aAAa;KACd;KACA;MACC,SAAS;MACT,aAAa;KACd;IACD;GACD,CAAC,CACF;EACD,CAAC;EACDA,KAAU,UAAU;GACnB,aAAa;GACb,UAAU;IACTA,KAAU,OAAO;KAChB,aAAa;KACb,QAAQ;MACP,SAAS,SAAS,OAAO,SAAS,CAAC,CAAC,KACnC,SAAS,gBAAgB,kCAAkC,CAC5D;MACA,QAAQ,KAAK,QAAQ,QAAQ,CAAC,CAAC,KAC9B,KAAK,UAAU,GAAG,GAClB,KAAK,gBAAgB,6DAA6D,GAClF,KAAK,YAAY,KAAK,CACvB;MACA,SAAS,KAAK,OAAO,SAAS,CAAC,CAAC,KAC/B,KAAK,gBAAgB,wEAAwE,GAC7F,KAAK,QACN;KACD;KACA,UAAU;MACT;OACC,SAAS;OACT,aAAa;MACd;MACA;OACC,SAAS;OACT,aAAa;MACd;MACA;OACC,SAAS;OACT,aAAa;MACd;KACD;IACD,CAAC;IACDA,KAAU,WAAW;KACpB,aAAa;KACb,QAAQ,CAAC;KACT,UAAU,CACT;MACC,SAAS;MACT,aAAa;KACd,CACD;IACD,CAAC;IACDA,KAAU,QAAQ;KACjB,aAAa;KACb,QAAQ,EACP,SAAS,KAAK,QAAQ,SAAS,CAAC,CAAC,KAChC,KAAK,gBAAgB,wDAAwD,GAC7E,KAAK,YAAY,KAAK,CACvB,EACD;KACA,UAAU,CAAC;MAAE,SAAS;MAAwB,aAAa;KAA+B,CAAC;IAC5F,CAAC;IACDA,KAAU,SAAS;KAClB,aAAa;KACb,QAAQ;MACP,MAAM,SAAS,OAAO,MAAM,CAAC,CAAC,KAC7B,SAAS,gBAAgB,wEAAwE,GACjG,SAAS,QACV;MAKA,SAAS,KAAK,QAAQ,SAAS,CAAC,CAAC,KAChC,KAAK,gBAAgB,yDAAyD,GAC9E,KAAK,YAAY,KAAK,CACvB;KACD;KACA,UAAU;MACT;OAAE,SAAS;OAAyB,aAAa;MAAkC;MACnF;OAAE,SAAS;OAAkD,aAAa;MAAuB;MACjG;OACC,SAAS;OACT,aAAa;MACd;KACD;IACD,CAAC;IACDA,KAAU,UAAU;KACnB,aAAa;KACb,QAAQ,EACP,MAAM,SAAS,OAAO,MAAM,CAAC,CAAC,KAC7B,SAAS,gBAAgB,wEAAwE,GACjG,SAAS,QACV,EACD;KACA,UAAU,CACT;MAAE,SAAS;MAA0B,aAAa;KAA8B,GAChF;MAAE,SAAS;MAAmD,aAAa;KAAoB,CAChG;IACD,CAAC;IACDA,KAAU,UAAU;KACnB,aAAa;KACb,QAAQ,EACP,QAAQ,KAAK,OAAO,QAAQ,CAAC,CAAC,KAC7B,KAAK,gBAAgB,yCAAyC,GAC9D,KAAK,YAAY,uBAAuB,CACzC,EACD;KACA,UAAU,CACT;MACC,SAAS;MACT,aAAa;KACd,CACD;IACD,CAAC;IACDA,KAAU,UAAU;KACnB,aAAa;KACb,QAAQ;MACP,SAAS,SAAS,OAAO,SAAS,CAAC,CAAC,KACnC,SAAS,gBAAgB,6CAA6C,CACvE;MACA,QAAQ,KAAK,QAAQ,QAAQ,CAAC,CAAC,KAC9B,KAAK,UAAU,GAAG,GAClB,KAAK,gBAAgB,4DAA4D,GACjF,KAAK,YAAY,KAAK,CACvB;KACD;KACA,UAAU,CACT;MACC,SAAS;MACT,aAAa;KACd,CACD;IACD,CAAC;GACF;EACD,CAAC;EACDA,KAAU,UAAU;GACnB,aAAa;GACb,QAAQ,EACP,UAAU,KAAK,OAAO,UAAU,CAAC,CAAC,KAAK,KAAK,gBAAgB,2BAA2B,GAAG,KAAK,QAAQ,EACxG;GACA,UAAU;IACT;KAAE,SAAS;KAAmB,aAAa;IAAqC;IAChF;KACC,SAAS;KACT,aAAa;IACd;IACA;KAAE,SAAS;KAA6B,aAAa;IAAkC;GACxF;GACA,UAAU,CACTA,KAAU,aAAa,EACtB,aAAa,gDACd,CAAC,GACDA,KAAU,WAAW;IACpB,aAAa;IACb,QAAQ,EACP,OAAO,KAAK,QAAQ,OAAO,CAAC,CAAC,KAC5B,KAAK,gBAAgB,uCAAuC,GAC5D,KAAK,YAAY,KAAK,CACvB,EACD;IACA,UAAU,CACT;KAAE,SAAS;KAA2B,aAAa;IAA0C,GAC7F;KAAE,SAAS;KAAmC,aAAa;IAA2B,CACvF;GACD,CAAC,CACF;EACD,CAAC;EACDA,KAAU,OAAO;GAChB,aAAa;GACb,UAAU,CAAC;IAAE,SAAS;IAAgB,aAAa;GAAgC,CAAC;EACrF,CAAC;CACF;AACD,CAAC;;;;ACpYD,SAAgB,QAAqC,OAAa,KAAuB;CACxF,OAAO;AACR;AAEA,SAAgB,SACf,MACA,UAC6B;CAC7B,MAAM,SAAwB,CAAC;CAE/B,SAAS,IAAI,MAAgB,OAAqB;EACjD,IAAI,OAAO,UAAU,YAAY;GAChC,OAAO,KAAK;IAAE,MAAM,KAAK;IAAM,MAAM;GAAM,CAAC;GAC5C;EACD;EACA,IAAI,MAAM,MAAM,KAAA,GAAW,OAAO,KAAK;GAAE,MAAM,KAAK;GAAM,MAAM,MAAM;EAAyB,CAAC;EAChG,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,KAAK,QAAQ,GAAG;GAC1D,MAAM,SAAS,MAAM;GACrB,IAAI,WAAW,KAAA,GAAW,IAAI,OAAO,MAAM;EAC5C;CACD;CAEA,IAAI,MAAM,QAAwB;CAClC,OAAO;AACR;AAEA,SAAgB,IAAI,MAAgB,UAAsC,SAAuC;CAChH,OAAO,QAAQ,IAAI,QAAQ,MAAM,QAAQ,GAAG,OAAO;AACpD;AAEA,SAAS,QAAQ,MAAgB,UAAuD;CACvF,MAAM,QAAQ,SAAS,MAAM,UAAU,MAAM,SAAS,KAAK,IAAI;CAC/D,MAAM,OAAO,QACV,KAAK,KAAK,KACV,QAAQ,aAAa,UACpB,OAAO,QAAQ,MAAM,IAAI,CAAC,CAAC,KAAK,OAAO,SAAS,WAAW,OAAO,QAAQ,KAAK,CAAC,CAAC,CAClF,CACD,IACC,KAAK;CACR,MAAM,WAAW,OAAO,OAAO,KAAK,QAAQ;CAC5C,IAAI,SAAS,WAAW,GAAG,OAAO;CAClC,OAAO,KAAK,KAAK,QAAQ,gBAAgB,SAAS,KAAK,UAAU,QAAQ,OAAO,QAAQ,CAAC,CAAC,CAAC;AAC5F"}
|
package/serve-fKFLZdgJ.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"serve-fKFLZdgJ.mjs","names":["Service","Envelope.Core","Envelope.encode","layer","layer","Contract.OAuthError","layer","EventFeed.Service","OAuth.Service","Identity.Service","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 { Control, EventSchema, PromptSchema, Sandbox, Session, SessionStore, State } from \"@codeworksh/harness/effect\";\nimport { Effect, Option, Stream } from \"effect\";\nimport { Contract, type RuntimeConfig, type SandboxInfo, type SessionInfo } from \"./contract.ts\";\nimport { Envelope } from \"./envelope.ts\";\nimport { EventFeed } from \"./feed.ts\";\nimport { Identity } from \"./identity.ts\";\nimport { OAuth } from \"./oauth.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\ttitle: info.title,\n\tdirectory: info.directory,\n\t...(info.hostDir === undefined ? {} : { hostDir: info.hostDir }),\n\t...(info.sandbox === undefined ? {} : { sandbox: toSandboxInfo(info.sandbox) }),\n});\n\n// Wire configs name only the keys they set, so `undefined` never reaches the\n// harness inputs under exactOptionalPropertyTypes.\nconst runtimeInput = (runtime: RuntimeConfig | undefined): Session.RuntimeInput => ({\n\t...(runtime?.model === undefined ? {} : { model: runtime.model }),\n\t...(runtime?.thinkingLevel === undefined ? {} : { thinkingLevel: runtime.thinkingLevel }),\n});\n\nconst sessionInfo = Effect.fn(\"Server.sessionInfo\")(function* (sessionId: Session.SessionSchema.ID) {\n\tconst found = yield* Session.get(sessionId);\n\tif (Option.isNone(found)) return yield* new SessionStore.SessionNotFoundError({ sessionId });\n\treturn toSessionInfo(yield* found.value.info);\n});\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\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 state = yield* State.Service;\n\t\tconst oauth = yield* OAuth.Service;\n\t\tconst identity = yield* Identity.Service;\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 }) {\n\t\t\t\tconst selection = sandbox === undefined ? undefined : yield* 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...runtimeInput(runtime),\n\t\t\t\t}).pipe(Effect.onError(() => releaseOnFailure(selection)));\n\t\t\t\treturn toSessionInfo(yield* handle.info);\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.list\": Effect.fnUntraced(function* () {\n\t\t\t\tconst rows = yield* sessions.list();\n\t\t\t\treturn yield* Effect.forEach(rows, (row) => sessionInfo(row.id).pipe(Effect.orDie));\n\t\t\t}),\n\t\t\t\"session.configure\": Effect.fnUntraced(function* ({ sessionId, runtime }) {\n\t\t\t\tconst handle = yield* Session.attach({ sessionId, ...runtimeInput(runtime) });\n\t\t\t\treturn toSessionInfo(yield* handle.info);\n\t\t\t}),\n\t\t\t\"session.info\": Effect.fnUntraced(function* ({ sessionId }) {\n\t\t\t\treturn yield* sessionInfo(sessionId);\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, sandbox, directory }) {\n\t\t\t\tconst selection = sandbox === undefined ? undefined : yield* 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...(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\treturn toSessionInfo(yield* handle.info);\n\t\t\t}),\n\t\t\t\"session.prompt\": Effect.fnUntraced(function* ({ sessionId, text, delivery, id }) {\n\t\t\t\tyield* control.prompt({\n\t\t\t\t\tsessionId,\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}),\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 `session.wait` when it needs cleanup to have finished.\n\t\t\t\treturn { interrupted: yield* control.interrupt(sessionId, { reason: \"user\" }) };\n\t\t\t}),\n\t\t\t\"session.message\": Effect.fnUntraced(function* ({ sessionId, messageId }) {\n\t\t\t\tconst found = yield* sessions.entry(messageId);\n\t\t\t\t// Scoped to the session the caller named: an entry id is global, and a\n\t\t\t\t// client should not learn about conversations it did not ask for.\n\t\t\t\treturn { found: Option.isSome(found) && found.value.entry.sessionId === sessionId };\n\t\t\t}),\n\t\t\t\"session.wait\": Effect.fnUntraced(function* ({ sessionId }) {\n\t\t\t\tyield* control.wait(sessionId);\n\t\t\t}),\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* 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\": () =>\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(events),\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 * 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.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\")(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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"}
|
package/tui-DJk6oQru.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tui-DJk6oQru.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\")(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,SAAS,CAAC,CAAC,WAAW,EAAE,QAAQ,MAAM,MAAM,QAAQ;CAC7D,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"}
|