@codeworksh/cli 0.0.1-dev.20260918042316 → 0.0.1-dev.20260922183613
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/README.md +94 -0
- package/add--i7mPR73.mjs +81 -0
- package/add--i7mPR73.mjs.map +1 -0
- package/{catalog-Cv1zoZ5S.mjs → catalog-DJxy_lne.mjs} +2 -2
- package/{catalog-Cv1zoZ5S.mjs.map → catalog-DJxy_lne.mjs.map} +1 -1
- package/check-Dq2WOgap.mjs +47 -0
- package/check-Dq2WOgap.mjs.map +1 -0
- package/commonjs-BDiLMfFF.mjs +160 -0
- package/commonjs-BDiLMfFF.mjs.map +1 -0
- package/definitions-Dfwyyv_K.mjs +3348 -0
- package/definitions-Dfwyyv_K.mjs.map +1 -0
- package/entries-Gfsq7U4P.mjs +48 -0
- package/entries-Gfsq7U4P.mjs.map +1 -0
- package/{error-zJGKAF4a.mjs → error-BrbT9_4g.mjs} +2470 -1853
- package/error-BrbT9_4g.mjs.map +1 -0
- package/{generate-DdscbX3w.mjs → generate-DrGYpD3l.mjs} +3 -3
- package/{generate-DdscbX3w.mjs.map → generate-DrGYpD3l.mjs.map} +1 -1
- package/{harness-BBTdWdhx.mjs → harness-Bgvrr0ZB.mjs} +2 -2
- package/{harness-BBTdWdhx.mjs.map → harness-Bgvrr0ZB.mjs.map} +1 -1
- package/index.d.mts +6 -1
- package/index.mjs +22 -6
- package/index.mjs.map +1 -1
- package/install-DoO4D3fk.mjs +53 -0
- package/install-DoO4D3fk.mjs.map +1 -0
- package/lib-BkWR53Bz.mjs +37659 -0
- package/lib-BkWR53Bz.mjs.map +1 -0
- package/lib-CyynPpjH.mjs +846 -0
- package/lib-CyynPpjH.mjs.map +1 -0
- package/lib-Dw7R2suc.mjs +16078 -0
- package/lib-Dw7R2suc.mjs.map +1 -0
- package/lib-JQygPqgO.mjs +10868 -0
- package/lib-JQygPqgO.mjs.map +1 -0
- package/link-B1zfETsS.mjs +40 -0
- package/link-B1zfETsS.mjs.map +1 -0
- package/list-3OR68HpY.mjs +76 -0
- package/list-3OR68HpY.mjs.map +1 -0
- package/{list-C6BrwuV-.mjs → list-CfPfmfe0.mjs} +4 -4
- package/{list-C6BrwuV-.mjs.map → list-CfPfmfe0.mjs.map} +1 -1
- package/login-GFV3Z9f2.mjs +45 -0
- package/login-GFV3Z9f2.mjs.map +1 -0
- package/logout-D17TQUfo.mjs +29 -0
- package/logout-D17TQUfo.mjs.map +1 -0
- package/p-map-C2WSUhyP.mjs +116 -0
- package/p-map-C2WSUhyP.mjs.map +1 -0
- package/package.json +12 -9
- package/{providers-fO-GJuXn.mjs → providers-DLXs9aWZ.mjs} +4 -4
- package/{providers-fO-GJuXn.mjs.map → providers-DLXs9aWZ.mjs.map} +1 -1
- package/refresh-BTNuP1zL.mjs +35 -0
- package/refresh-BTNuP1zL.mjs.map +1 -0
- package/reload-BzwsCBQq.mjs +26 -0
- package/reload-BzwsCBQq.mjs.map +1 -0
- package/remove-DgB3l5JL.mjs +36 -0
- package/remove-DgB3l5JL.mjs.map +1 -0
- package/{run-CgPOJ-wJ.mjs → run-BVo4XsL6.mjs} +11 -8
- package/run-BVo4XsL6.mjs.map +1 -0
- package/runtime-Dl621FOp.mjs +345 -0
- package/runtime-Dl621FOp.mjs.map +1 -0
- package/{serve-Du6luqoi.mjs → serve-Dpep18-A.mjs} +93 -17
- package/serve-Dpep18-A.mjs.map +1 -0
- package/settings-C52IrA72.mjs +215 -0
- package/settings-C52IrA72.mjs.map +1 -0
- package/shared-Uwjcofff.mjs +115 -0
- package/shared-Uwjcofff.mjs.map +1 -0
- package/status-DPYq2Sx4.mjs +31 -0
- package/status-DPYq2Sx4.mjs.map +1 -0
- package/type-defs-BZxrtlVD.mjs +538 -0
- package/type-defs-BZxrtlVD.mjs.map +1 -0
- package/update-CJrBbHwq.mjs +44 -0
- package/update-CJrBbHwq.mjs.map +1 -0
- package/valid-BWgW_TUl.mjs +354 -0
- package/valid-BWgW_TUl.mjs.map +1 -0
- package/error-zJGKAF4a.mjs.map +0 -1
- package/run-CgPOJ-wJ.mjs.map +0 -1
- package/runtime-DuL-GGrx.mjs +0 -163
- package/runtime-DuL-GGrx.mjs.map +0 -1
- package/serve-Du6luqoi.mjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { i as
|
|
2
|
-
import {
|
|
3
|
-
import { t as harnessOptions } from "./harness-
|
|
1
|
+
import { A as resolve, M as layer$1, S as create, St as schema_exports, c as header, d as writeError, dt as LLMTextDelta, f as writeOut, ft as TurnEnded, h as run, i as renderError, j as stop, l as terminalColumns, m as make, mt as instance_exports, o as addUsage, p as layer, s as emptyUsage, t as InvalidInputError, u as usage, ut as LLMEnded, x as attach, xt as ID } from "./error-BrbT9_4g.mjs";
|
|
2
|
+
import { i as Cmd, t as handler } from "./runtime-Dl621FOp.mjs";
|
|
3
|
+
import { t as harnessOptions } from "./harness-Bgvrr0ZB.mjs";
|
|
4
4
|
import { Effect, Exit, Fiber, Option, Queue, Ref, Schema, Stream } from "effect";
|
|
5
5
|
//#region src/cli/cmd/handlers/run.ts
|
|
6
6
|
const initialRenderState = {
|
|
@@ -57,10 +57,11 @@ var run_default = handler(Cmd.commands.run, Effect.fn("CLI.run")(function* ({ pr
|
|
|
57
57
|
shared.userConfigDir
|
|
58
58
|
].some(Option.isSome)) return yield* new InvalidInputError({ message: "--home, --database, and --user-config-dir belong on codework serve when using --server" });
|
|
59
59
|
if (Option.isSome(sandboxId) && (Option.isSome(sandboxDriver) || Option.isSome(sandboxProviderId))) return yield* new InvalidInputError({ message: "--sandbox-id cannot be combined with --sandbox-driver or --sandbox-provider-id" });
|
|
60
|
-
const selection = Option.isSome(sandboxId) ? { id: ID.make(sandboxId.value) } : {
|
|
60
|
+
const selection = Option.isSome(sandboxId) ? { id: instance_exports.SandboxInstance.ID.make(sandboxId.value) } : {
|
|
61
61
|
driver: Option.getOrElse(sandboxDriver, () => "local"),
|
|
62
62
|
...Option.isNone(sandboxProviderId) ? {} : { providerResourceId: sandboxProviderId.value }
|
|
63
63
|
};
|
|
64
|
+
const hostDir = schema_exports.AbsolutePath.make(process.cwd());
|
|
64
65
|
const runtime = {
|
|
65
66
|
...Option.isNone(provider) || Option.isNone(model) ? {} : { model: {
|
|
66
67
|
provider: provider.value,
|
|
@@ -71,12 +72,13 @@ var run_default = handler(Cmd.commands.run, Effect.fn("CLI.run")(function* ({ pr
|
|
|
71
72
|
const remote = Effect.gen(function* () {
|
|
72
73
|
const rpc = yield* make;
|
|
73
74
|
const info = Option.isSome(session) ? yield* rpc["session.configure"]({
|
|
74
|
-
sessionId: ID
|
|
75
|
+
sessionId: ID.make(session.value),
|
|
75
76
|
runtime
|
|
76
77
|
}) : yield* rpc["session.create"]({
|
|
77
78
|
title: "CLI",
|
|
78
79
|
runtime,
|
|
79
80
|
...Option.isNone(cwd) ? {} : { directory: cwd.value },
|
|
81
|
+
hostDir,
|
|
80
82
|
sandbox: selection
|
|
81
83
|
});
|
|
82
84
|
const state = yield* Ref.make(initialRenderState);
|
|
@@ -97,7 +99,7 @@ var run_default = handler(Cmd.commands.run, Effect.fn("CLI.run")(function* ({ pr
|
|
|
97
99
|
const program = Effect.gen(function* () {
|
|
98
100
|
let handle;
|
|
99
101
|
if (Option.isSome(session)) handle = yield* attach({
|
|
100
|
-
sessionId: ID
|
|
102
|
+
sessionId: ID.make(session.value),
|
|
101
103
|
...runtime
|
|
102
104
|
});
|
|
103
105
|
else {
|
|
@@ -106,7 +108,8 @@ var run_default = handler(Cmd.commands.run, Effect.fn("CLI.run")(function* ({ pr
|
|
|
106
108
|
title: "CLI",
|
|
107
109
|
...runtime,
|
|
108
110
|
...selected === void 0 ? {} : { sandbox: selected },
|
|
109
|
-
...Option.isNone(cwd) ? {} : { directory: cwd.value }
|
|
111
|
+
...Option.isNone(cwd) ? {} : { directory: cwd.value },
|
|
112
|
+
hostDir
|
|
110
113
|
});
|
|
111
114
|
}
|
|
112
115
|
const ended = yield* Queue.unbounded();
|
|
@@ -141,4 +144,4 @@ var run_default = handler(Cmd.commands.run, Effect.fn("CLI.run")(function* ({ pr
|
|
|
141
144
|
//#endregion
|
|
142
145
|
export { run_default as default };
|
|
143
146
|
|
|
144
|
-
//# sourceMappingURL=run-
|
|
147
|
+
//# sourceMappingURL=run-BVo4XsL6.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-BVo4XsL6.mjs","names":["EventList.LLMTextDelta","EventList.LLMEnded","EventList.TurnEnded","Sandbox.resolve","Sandbox.stop","Runtime.handler","Client.make","Client.run","Session.attach","Session.create","Client.layer","Harness.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\ttitle: \"CLI\",\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\ttitle: \"CLI\",\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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"}
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import { Model } from "@codeworksh/aikit";
|
|
3
|
+
import { Argument, Command, Flag } from "effect/unstable/cli";
|
|
4
|
+
//#region src/framework/spec.ts
|
|
5
|
+
function make(name, options = {}) {
|
|
6
|
+
let spec = Command.make(name, options.params ?? {}).pipe(Command.withSharedFlags(options.shared ?? {}));
|
|
7
|
+
if (options.description !== void 0) spec = spec.pipe(Command.withDescription(options.description));
|
|
8
|
+
if (options.examples !== void 0) spec = spec.pipe(Command.withExamples(options.examples));
|
|
9
|
+
return {
|
|
10
|
+
name,
|
|
11
|
+
spec,
|
|
12
|
+
commands: Object.fromEntries((options.commands ?? []).map((command) => [command.name, command]))
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/cli/cmd/cmd.ts
|
|
17
|
+
/**
|
|
18
|
+
* The full command surface of the `codework` CLI. Declarations only -- each
|
|
19
|
+
* command's behaviour lives in `./handlers`, wired up in `src/index.ts`.
|
|
20
|
+
*/
|
|
21
|
+
const thinkingLevels = Object.values(Model.ThinkingLevelEnum);
|
|
22
|
+
/**
|
|
23
|
+
* Every `auth` subcommand answers the same three questions: which provider,
|
|
24
|
+
* whose credentials, and where they live. Only `login` needs anything more.
|
|
25
|
+
*/
|
|
26
|
+
const AuthParams = {
|
|
27
|
+
openaiCodex: Flag.Boolean("openai-codex").pipe(Flag.withDescription("Use OpenAI Codex OAuth"), Flag.withDefault(false)),
|
|
28
|
+
githubCopilot: Flag.Boolean("github-copilot").pipe(Flag.withDescription("Use GitHub Copilot OAuth (device flow)"), Flag.withDefault(false)),
|
|
29
|
+
server: Flag.String("server").pipe(Flag.withDescription("RPC server URL (ws://host:port/rpc)"), Flag.optional),
|
|
30
|
+
authFile: Flag.String("auth-file").pipe(Flag.withDescription("Credential file (defaults to <home>/aikit/auth.json)"), Flag.optional)
|
|
31
|
+
};
|
|
32
|
+
const JsonFlag = Flag.Boolean("json").pipe(Flag.withDescription("Print machine-readable output"), Flag.withDefault(false));
|
|
33
|
+
const Cmd = make("codework", {
|
|
34
|
+
description: "CodeWork Command Line Interface",
|
|
35
|
+
shared: {
|
|
36
|
+
userConfigDir: Flag.String("user-config-dir").pipe(Flag.withDescription("Directory containing user config overrides (e.g. settings.json)"), Flag.optional),
|
|
37
|
+
home: Flag.String("home").pipe(Flag.withDescription("CodeWork data directory (default: ~/.codework)"), Flag.optional),
|
|
38
|
+
database: Flag.String("database").pipe(Flag.withDescription("SQLite database path or :memory:"), Flag.optional)
|
|
39
|
+
},
|
|
40
|
+
commands: [
|
|
41
|
+
make("auth", {
|
|
42
|
+
description: "Manage OAuth credentials",
|
|
43
|
+
commands: [
|
|
44
|
+
make("login", {
|
|
45
|
+
description: "Sign in to a provider",
|
|
46
|
+
params: {
|
|
47
|
+
...AuthParams,
|
|
48
|
+
browser: Flag.Boolean("browser").pipe(Flag.withDescription("Open the authorization URL in the default browser"), Flag.withDefault(true)),
|
|
49
|
+
device: Flag.Boolean("device").pipe(Flag.withDescription("Use the device-code flow instead of a localhost browser callback"), Flag.withDefault(false)),
|
|
50
|
+
enterprise: Flag.String("enterprise").pipe(Flag.withDescription("GitHub Enterprise domain for GitHub Copilot login"), Flag.optional),
|
|
51
|
+
enableModels: Flag.Boolean("enable-models").pipe(Flag.withDescription("Enable unconfigured Copilot catalog models after login"), Flag.withDefault(false)),
|
|
52
|
+
json: JsonFlag
|
|
53
|
+
},
|
|
54
|
+
examples: [
|
|
55
|
+
{
|
|
56
|
+
command: "codework auth login --openai-codex",
|
|
57
|
+
description: "Sign in with ChatGPT"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
command: "codework auth login --github-copilot",
|
|
61
|
+
description: "Sign in with GitHub Copilot"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
command: "codework auth login --openai-codex --device",
|
|
65
|
+
description: "Sign in with a device code, no local port"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
command: "codework auth login --openai-codex --server ws://127.0.0.1:7433/rpc",
|
|
69
|
+
description: "Sign in the running server"
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
}),
|
|
73
|
+
make("status", {
|
|
74
|
+
description: "Show a stored login without refreshing it",
|
|
75
|
+
params: {
|
|
76
|
+
...AuthParams,
|
|
77
|
+
json: JsonFlag
|
|
78
|
+
},
|
|
79
|
+
examples: [{
|
|
80
|
+
command: "codework auth status --openai-codex",
|
|
81
|
+
description: "Show the stored login"
|
|
82
|
+
}]
|
|
83
|
+
}),
|
|
84
|
+
make("refresh", {
|
|
85
|
+
description: "Refresh a stored login if it has expired",
|
|
86
|
+
params: {
|
|
87
|
+
...AuthParams,
|
|
88
|
+
json: JsonFlag
|
|
89
|
+
},
|
|
90
|
+
examples: [{
|
|
91
|
+
command: "codework auth refresh --openai-codex",
|
|
92
|
+
description: "Renew an expired login"
|
|
93
|
+
}]
|
|
94
|
+
}),
|
|
95
|
+
make("logout", {
|
|
96
|
+
description: "Clear a stored login",
|
|
97
|
+
params: AuthParams,
|
|
98
|
+
examples: [{
|
|
99
|
+
command: "codework auth logout --github-copilot",
|
|
100
|
+
description: "Clear the stored login"
|
|
101
|
+
}]
|
|
102
|
+
})
|
|
103
|
+
]
|
|
104
|
+
}),
|
|
105
|
+
make("run", {
|
|
106
|
+
description: "Start or continue an agent session",
|
|
107
|
+
params: {
|
|
108
|
+
server: Flag.String("server").pipe(Flag.withDescription("RPC server URL (ws://host:port/rpc)"), Flag.optional),
|
|
109
|
+
prompt: Argument.String("prompt").pipe(Argument.withDescription("Prompt for the agent")),
|
|
110
|
+
session: Flag.String("session").pipe(Flag.withAlias("s"), Flag.withDescription("Continue an existing session"), Flag.optional),
|
|
111
|
+
cwd: Flag.String("cwd").pipe(Flag.withAlias("C"), Flag.withDescription("Working directory for a new session"), Flag.optional),
|
|
112
|
+
sandboxDriver: Flag.String("sandbox-driver").pipe(Flag.withDescription("Sandbox driver for a new session (default: local)"), Flag.optional),
|
|
113
|
+
sandboxId: Flag.String("sandbox-id").pipe(Flag.withDescription("Reuse an existing sandbox instance"), Flag.optional),
|
|
114
|
+
sandboxProviderId: Flag.String("sandbox-provider-id").pipe(Flag.withDescription("Provider ID of an existing remote sandbox"), Flag.optional),
|
|
115
|
+
provider: Flag.String("provider").pipe(Flag.withDescription("Model catalog provider ID"), Flag.optional),
|
|
116
|
+
model: Flag.String("model").pipe(Flag.withDescription("Model ID"), Flag.optional),
|
|
117
|
+
thinking: Flag.Literals("thinking", thinkingLevels).pipe(Flag.withDescription("Reasoning effort the model uses before answering"), Flag.optional)
|
|
118
|
+
},
|
|
119
|
+
examples: [
|
|
120
|
+
{
|
|
121
|
+
command: "codework run \"Inspect the failing tests\"",
|
|
122
|
+
description: "Create a session"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
command: "codework run --provider openai --model gpt-5.5 --thinking high \"Inspect the failing tests\"",
|
|
126
|
+
description: "Create a session with an explicit model"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
command: "codework run --sandbox-driver daytona \"Inspect the repository\"",
|
|
130
|
+
description: "Create a Daytona sandbox and session"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
command: "codework run --sandbox-driver daytona --sandbox-provider-id <id> \"Inspect the repository\"",
|
|
134
|
+
description: "Use an existing remote sandbox"
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
command: "codework run --session <id> --provider openai --model gpt-5.6-luna \"Now fix them\"",
|
|
138
|
+
description: "Continue a session with explicit model bindings"
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
}),
|
|
142
|
+
make("serve", {
|
|
143
|
+
description: "Start the CodeWork RPC server",
|
|
144
|
+
params: {
|
|
145
|
+
host: Flag.String("host").pipe(Flag.withDescription("Host interface to bind"), Flag.withDefault("127.0.0.1")),
|
|
146
|
+
port: Flag.Int("port").pipe(Flag.withSchema(Schema.Int.check(Schema.isBetween({
|
|
147
|
+
minimum: 0,
|
|
148
|
+
maximum: 65535
|
|
149
|
+
}))), Flag.withDescription("Port to listen on (0 for an ephemeral port)"), Flag.withDefault(7433))
|
|
150
|
+
},
|
|
151
|
+
examples: [{
|
|
152
|
+
command: "codework serve",
|
|
153
|
+
description: "Start the RPC server on 127.0.0.1:7433"
|
|
154
|
+
}, {
|
|
155
|
+
command: "codework serve --port 0",
|
|
156
|
+
description: "Choose an available local port"
|
|
157
|
+
}]
|
|
158
|
+
}),
|
|
159
|
+
make("session", {
|
|
160
|
+
description: "Manage sessions",
|
|
161
|
+
commands: [make("link", {
|
|
162
|
+
description: "Anchor a session to a host directory",
|
|
163
|
+
params: {
|
|
164
|
+
session: Argument.String("session-id").pipe(Argument.withDescription("The session to link")),
|
|
165
|
+
path: Argument.String("path").pipe(Argument.withDescription("Host directory to anchor to — typically the directory holding your .codework configuration; defaults to the shell's"), Argument.optional),
|
|
166
|
+
unlink: Flag.Boolean("unlink").pipe(Flag.withDescription("Clear the anchor, leaving the session with no host directory"), Flag.withDefault(false)),
|
|
167
|
+
server: Flag.String("server").pipe(Flag.withDescription("Base URL of the running codework server"), Flag.withDefault("http://127.0.0.1:7433"))
|
|
168
|
+
},
|
|
169
|
+
examples: [
|
|
170
|
+
{
|
|
171
|
+
command: "codework session link ses_01h9",
|
|
172
|
+
description: "Link it to the directory you are standing in"
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
command: "codework session link ses_01h9 ~/work/api",
|
|
176
|
+
description: "Link it to a project elsewhere on this machine"
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
command: "codework session link ses_01h9 --unlink",
|
|
180
|
+
description: "Clear the anchor"
|
|
181
|
+
}
|
|
182
|
+
]
|
|
183
|
+
})]
|
|
184
|
+
}),
|
|
185
|
+
make("plugin", {
|
|
186
|
+
description: "Manage plugins",
|
|
187
|
+
commands: [
|
|
188
|
+
make("add", {
|
|
189
|
+
description: "Install a plugin and add it to a settings file",
|
|
190
|
+
params: {
|
|
191
|
+
package: Argument.String("package").pipe(Argument.withDescription("Package spec, path, or file: URL")),
|
|
192
|
+
global: Flag.Boolean("global").pipe(Flag.withAlias("g"), Flag.withDescription("Write the user-wide settings file instead of this project's"), Flag.withDefault(false)),
|
|
193
|
+
session: Flag.String("session").pipe(Flag.withDescription("Write the project a session is linked to, rather than this directory's"), Flag.optional)
|
|
194
|
+
},
|
|
195
|
+
examples: [
|
|
196
|
+
{
|
|
197
|
+
command: "codework plugin add @acme/codework-tool-proc@1.2.0",
|
|
198
|
+
description: "Install a published plugin into this project's settings"
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
command: "codework plugin add @acme/codework-tool-proc --session ses_01h9",
|
|
202
|
+
description: "Write the project that session is linked to, from anywhere"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
command: "codework plugin add @acme/codework-tool-proc -g",
|
|
206
|
+
description: "Install it for every project this user runs"
|
|
207
|
+
}
|
|
208
|
+
]
|
|
209
|
+
}),
|
|
210
|
+
make("install", {
|
|
211
|
+
description: "Install every plugin the settings files name",
|
|
212
|
+
params: {},
|
|
213
|
+
examples: [{
|
|
214
|
+
command: "codework plugin install",
|
|
215
|
+
description: "Materialise what a fresh checkout already declares"
|
|
216
|
+
}]
|
|
217
|
+
}),
|
|
218
|
+
make("list", {
|
|
219
|
+
description: "List configured plugins and what each one resolved to",
|
|
220
|
+
params: { verbose: Flag.Boolean("verbose").pipe(Flag.withDescription("Show the message behind a failure, not only its reason"), Flag.withDefault(false)) },
|
|
221
|
+
examples: [{
|
|
222
|
+
command: "codework plugin list",
|
|
223
|
+
description: "Show every configured plugin"
|
|
224
|
+
}]
|
|
225
|
+
}),
|
|
226
|
+
make("check", {
|
|
227
|
+
description: "Report which configured plugins have a newer revision available",
|
|
228
|
+
params: { refresh: Flag.Boolean("refresh").pipe(Flag.withDescription("Ask the remote again instead of reusing a recent answer"), Flag.withDefault(false)) },
|
|
229
|
+
examples: [{
|
|
230
|
+
command: "codework plugin check",
|
|
231
|
+
description: "Ask the registry what has moved"
|
|
232
|
+
}, {
|
|
233
|
+
command: "codework plugin check --refresh",
|
|
234
|
+
description: "Ignore the cached answer, after pushing a plugin"
|
|
235
|
+
}]
|
|
236
|
+
}),
|
|
237
|
+
make("update", {
|
|
238
|
+
description: "Fetch a newer revision of every plugin that has one",
|
|
239
|
+
params: {},
|
|
240
|
+
examples: [{
|
|
241
|
+
command: "codework plugin update",
|
|
242
|
+
description: "Take whatever `check` found"
|
|
243
|
+
}]
|
|
244
|
+
}),
|
|
245
|
+
make("reload", {
|
|
246
|
+
description: "Re-import configured plugins in a running server",
|
|
247
|
+
params: { server: Flag.String("server").pipe(Flag.withDescription("Base URL of the running codework server"), Flag.withDefault("http://127.0.0.1:7433")) },
|
|
248
|
+
examples: [{
|
|
249
|
+
command: "codework plugin reload",
|
|
250
|
+
description: "Pick up edits to a local plugin without restarting"
|
|
251
|
+
}]
|
|
252
|
+
}),
|
|
253
|
+
make("remove", {
|
|
254
|
+
description: "Remove a plugin from a settings file",
|
|
255
|
+
params: {
|
|
256
|
+
package: Argument.String("package").pipe(Argument.withDescription("Configured package spec, path, or plugin ID")),
|
|
257
|
+
global: Flag.Boolean("global").pipe(Flag.withAlias("g"), Flag.withDescription("Edit the user-wide settings file instead of this project's"), Flag.withDefault(false))
|
|
258
|
+
},
|
|
259
|
+
examples: [{
|
|
260
|
+
command: "codework plugin remove @acme/codework-tool-proc",
|
|
261
|
+
description: "Drop a plugin and any configuration written against it"
|
|
262
|
+
}]
|
|
263
|
+
})
|
|
264
|
+
]
|
|
265
|
+
}),
|
|
266
|
+
make("models", {
|
|
267
|
+
description: "List or generate the model catalog",
|
|
268
|
+
params: { provider: Flag.String("provider").pipe(Flag.withDescription("Model catalog provider ID"), Flag.optional) },
|
|
269
|
+
examples: [
|
|
270
|
+
{
|
|
271
|
+
command: "codework models",
|
|
272
|
+
description: "List all models from all providers"
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
command: "codework models --provider openai",
|
|
276
|
+
description: "List models for a specific provider"
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
command: "codework models providers",
|
|
280
|
+
description: "List all available provider IDs"
|
|
281
|
+
}
|
|
282
|
+
],
|
|
283
|
+
commands: [make("providers", { description: "List available model providers in the catalog" }), make("generate", {
|
|
284
|
+
description: "Generate or update the model catalog",
|
|
285
|
+
params: { path: Argument.String("path").pipe(Argument.withDescription("Output file or directory; defaults to CODEWORK_MODELS_FILE or ./models.gen.json"), Argument.optional) },
|
|
286
|
+
examples: [
|
|
287
|
+
{
|
|
288
|
+
command: "codework models generate",
|
|
289
|
+
description: "Generate models.gen.json"
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
command: "codework models generate .",
|
|
293
|
+
description: "Generate models.gen.json in the current directory"
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
command: "codework models generate /path/to/models.gen.json",
|
|
297
|
+
description: "Generate the catalog at an explicit path"
|
|
298
|
+
}
|
|
299
|
+
]
|
|
300
|
+
})]
|
|
301
|
+
})
|
|
302
|
+
]
|
|
303
|
+
});
|
|
304
|
+
//#endregion
|
|
305
|
+
//#region src/framework/runtime.ts
|
|
306
|
+
/** Type-checks a handler against the spec node it implements. */
|
|
307
|
+
function handler(_node, run) {
|
|
308
|
+
return run;
|
|
309
|
+
}
|
|
310
|
+
function handlers(root, handlers) {
|
|
311
|
+
const result = [];
|
|
312
|
+
function add(node, value) {
|
|
313
|
+
if (typeof value === "function") {
|
|
314
|
+
result.push({
|
|
315
|
+
spec: node.spec,
|
|
316
|
+
load: value
|
|
317
|
+
});
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
if (value.$ !== void 0) result.push({
|
|
321
|
+
spec: node.spec,
|
|
322
|
+
load: value.$
|
|
323
|
+
});
|
|
324
|
+
for (const [name, child] of Object.entries(node.commands)) {
|
|
325
|
+
const nested = value[name];
|
|
326
|
+
if (nested !== void 0) add(child, nested);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
add(root, handlers);
|
|
330
|
+
return result;
|
|
331
|
+
}
|
|
332
|
+
function run(root, handlers, options) {
|
|
333
|
+
return Command.run(provide(root, handlers), options);
|
|
334
|
+
}
|
|
335
|
+
function provide(node, handlers) {
|
|
336
|
+
const found = handlers.find((entry) => entry.spec === node.spec);
|
|
337
|
+
const spec = found ? node.spec.pipe(Command.withHandler((input) => Effect.promise(found.load).pipe(Effect.flatMap((module) => module.default(input))))) : node.spec;
|
|
338
|
+
const children = Object.values(node.commands);
|
|
339
|
+
if (children.length === 0) return spec;
|
|
340
|
+
return spec.pipe(Command.withSubcommands(children.map((child) => provide(child, handlers))));
|
|
341
|
+
}
|
|
342
|
+
//#endregion
|
|
343
|
+
export { Cmd as i, handlers as n, run as r, handler as t };
|
|
344
|
+
|
|
345
|
+
//# sourceMappingURL=runtime-Dl621FOp.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-Dl621FOp.mjs","names":["Spec.make"],"sources":["../../src/framework/spec.ts","../../src/cli/cmd/cmd.ts","../../src/framework/runtime.ts"],"sourcesContent":["import { Command } from \"effect/unstable/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 { Schema } from \"effect\";\nimport { Model } from \"@codeworksh/aikit\";\nimport { Argument, Flag } from \"effect/unstable/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)\"), 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\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 containing user config overrides (e.g. settings.json)\"),\n\t\t\tFlag.optional,\n\t\t),\n\t\thome: Flag.String(\"home\").pipe(\n\t\t\tFlag.withDescription(\"CodeWork data directory (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\",\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)\"),\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(\"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},\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(\"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\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{\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\texamples: [{ command: \"codework plugin update\", description: \"Take whatever `check` found\" }],\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 generate 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(\"generate\", {\n\t\t\t\t\tdescription: \"Generate or update the model catalog\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tpath: Argument.String(\"path\").pipe(\n\t\t\t\t\t\t\tArgument.withDescription(\n\t\t\t\t\t\t\t\t\"Output file or directory; defaults to CODEWORK_MODELS_FILE or ./models.gen.json\",\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},\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t{ command: \"codework models generate\", description: \"Generate models.gen.json\" },\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework models generate .\",\n\t\t\t\t\t\t\tdescription: \"Generate models.gen.json in the current directory\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework models generate /path/to/models.gen.json\",\n\t\t\t\t\t\t\tdescription: \"Generate the catalog at an explicit path\",\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","import { Effect } from \"effect\";\nimport { Command } from \"effect/unstable/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":"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"}
|