@codeworksh/cli 0.0.1-dev.20260918040208

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.
@@ -0,0 +1,35 @@
1
+ import { d as writeOut, i as reportFailure, n as ModelgenError, u as writeError } from "./error-Cr8LvfEq.mjs";
2
+ import { i as Cmd, t as handler } from "./runtime-DuL-GGrx.mjs";
3
+ import { Effect, FileSystem, Option, Path } from "effect";
4
+ import { generateModels } from "@codeworksh/aikit/modelgen";
5
+ //#region src/cli/cmd/handlers/models/generate.ts
6
+ const DEFAULT_FILENAME = "models.gen.json";
7
+ const resolveTarget = Effect.fn("CLI.models.resolveTarget")(function* (inputPath) {
8
+ if (Option.isNone(inputPath)) return Option.none();
9
+ const path = yield* Path.Path;
10
+ const fs = yield* FileSystem.FileSystem;
11
+ const raw = inputPath.value.trim();
12
+ const asDirectory = raw === "." || raw === ".." || raw.endsWith("/") || raw.endsWith("\\");
13
+ const resolved = path.resolve(raw);
14
+ if (asDirectory) return Option.some(path.join(resolved, DEFAULT_FILENAME));
15
+ const directory = yield* fs.stat(resolved).pipe(Effect.map((stat) => stat.type === "Directory"), Effect.orElseSucceed(() => false));
16
+ return Option.some(directory ? path.join(resolved, DEFAULT_FILENAME) : resolved);
17
+ });
18
+ var generate_default = handler(Cmd.commands.models.commands.generate, Effect.fn("CLI.models.generate")(function* ({ path }) {
19
+ return yield* Effect.gen(function* () {
20
+ const targetPath = yield* resolveTarget(path);
21
+ const generated = yield* Effect.tryPromise({
22
+ try: () => generateModels(Option.match(targetPath, {
23
+ onNone: () => ({}),
24
+ onSome: (value) => ({ path: value })
25
+ })),
26
+ catch: (cause) => new ModelgenError({ cause })
27
+ });
28
+ yield* writeError(`Generated model catalog at ${generated}\n`);
29
+ yield* writeOut(`${generated}\n`);
30
+ }).pipe(Effect.catch(reportFailure));
31
+ }));
32
+ //#endregion
33
+ export { generate_default as default };
34
+
35
+ //# sourceMappingURL=generate-BMJEbGEP.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-BMJEbGEP.mjs","names":["Runtime.handler"],"sources":["../../src/cli/cmd/handlers/models/generate.ts"],"sourcesContent":["import { generateModels } from \"@codeworksh/aikit/modelgen\";\nimport { Effect, FileSystem, Option, Path } from \"effect\";\nimport { Runtime } from \"../../../../framework/runtime.ts\";\nimport { ModelgenError, reportFailure } from \"../../../error.ts\";\nimport { writeError, writeOut } from \"../../../output.ts\";\nimport { Cmd } from \"../../cmd.ts\";\n\nconst DEFAULT_FILENAME = \"models.gen.json\";\n\nconst resolveTarget = Effect.fn(\"CLI.models.resolveTarget\")(function* (inputPath: Option.Option<string>) {\n\tif (Option.isNone(inputPath)) return Option.none<string>();\n\n\tconst path = yield* Path.Path;\n\tconst fs = yield* FileSystem.FileSystem;\n\tconst raw = inputPath.value.trim();\n\tconst asDirectory = raw === \".\" || raw === \"..\" || raw.endsWith(\"/\") || raw.endsWith(\"\\\\\");\n\tconst resolved = path.resolve(raw);\n\tif (asDirectory) return Option.some(path.join(resolved, DEFAULT_FILENAME));\n\n\tconst directory = yield* fs.stat(resolved).pipe(\n\t\tEffect.map((stat) => stat.type === \"Directory\"),\n\t\tEffect.orElseSucceed(() => false),\n\t);\n\treturn Option.some(directory ? path.join(resolved, DEFAULT_FILENAME) : resolved);\n});\n\nexport default Runtime.handler(\n\tCmd.commands.models.commands.generate,\n\tEffect.fn(\"CLI.models.generate\")(function* ({ path }) {\n\t\tconst program = Effect.gen(function* () {\n\t\t\tconst targetPath = yield* resolveTarget(path);\n\t\t\tconst generated = yield* Effect.tryPromise({\n\t\t\t\ttry: () =>\n\t\t\t\t\tgenerateModels(Option.match(targetPath, { onNone: () => ({}), onSome: (value) => ({ path: value }) })),\n\t\t\t\tcatch: (cause) => new ModelgenError({ cause }),\n\t\t\t});\n\t\t\tyield* writeError(`Generated model catalog at ${generated}\\n`);\n\t\t\tyield* writeOut(`${generated}\\n`);\n\t\t});\n\n\t\treturn yield* program.pipe(Effect.catch(reportFailure));\n\t}),\n);\n"],"mappings":";;;;;AAOA,MAAM,mBAAmB;AAEzB,MAAM,gBAAgB,OAAO,GAAG,0BAA0B,CAAC,CAAC,WAAW,WAAkC;CACxG,IAAI,OAAO,OAAO,SAAS,GAAG,OAAO,OAAO,KAAa;CAEzD,MAAM,OAAO,OAAO,KAAK;CACzB,MAAM,KAAK,OAAO,WAAW;CAC7B,MAAM,MAAM,UAAU,MAAM,KAAK;CACjC,MAAM,cAAc,QAAQ,OAAO,QAAQ,QAAQ,IAAI,SAAS,GAAG,KAAK,IAAI,SAAS,IAAI;CACzF,MAAM,WAAW,KAAK,QAAQ,GAAG;CACjC,IAAI,aAAa,OAAO,OAAO,KAAK,KAAK,KAAK,UAAU,gBAAgB,CAAC;CAEzE,MAAM,YAAY,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,KAC1C,OAAO,KAAK,SAAS,KAAK,SAAS,WAAW,GAC9C,OAAO,oBAAoB,KAAK,CACjC;CACA,OAAO,OAAO,KAAK,YAAY,KAAK,KAAK,UAAU,gBAAgB,IAAI,QAAQ;AAChF,CAAC;AAED,IAAA,mBAAeA,QACd,IAAI,SAAS,OAAO,SAAS,UAC7B,OAAO,GAAG,qBAAqB,CAAC,CAAC,WAAW,EAAE,QAAQ;CAYrD,OAAO,OAXS,OAAO,IAAI,aAAa;EACvC,MAAM,aAAa,OAAO,cAAc,IAAI;EAC5C,MAAM,YAAY,OAAO,OAAO,WAAW;GAC1C,WACC,eAAe,OAAO,MAAM,YAAY;IAAE,eAAe,CAAC;IAAI,SAAS,WAAW,EAAE,MAAM,MAAM;GAAG,CAAC,CAAC;GACtG,QAAQ,UAAU,IAAI,cAAc,EAAE,MAAM,CAAC;EAC9C,CAAC;EACD,OAAO,WAAW,8BAA8B,UAAU,GAAG;EAC7D,OAAO,SAAS,GAAG,UAAU,GAAG;CACjC,CAEoB,CAAC,CAAC,KAAK,OAAO,MAAM,aAAa,CAAC;AACvD,CAAC,CACF"}
@@ -0,0 +1,18 @@
1
+ import { N as sandbox$1, P as sandbox } from "./error-Cr8LvfEq.mjs";
2
+ import { Option } from "effect";
3
+ //#region src/cli/harness.ts
4
+ /**
5
+ * The harness boot options every local-harness command builds from the shared
6
+ * flags. `run` and `serve` must agree on the data directory and driver set --
7
+ * a session created by one is expected to be readable by the other.
8
+ */
9
+ const harnessOptions = (shared) => ({
10
+ ...Option.isNone(shared.userConfigDir) ? {} : { userConfigDir: shared.userConfigDir.value },
11
+ ...Option.isNone(shared.home) ? {} : { home: shared.home.value },
12
+ ...Option.isNone(shared.database) ? {} : { database: shared.database.value },
13
+ sandboxes: [sandbox.make({}), sandbox$1.make({})]
14
+ });
15
+ //#endregion
16
+ export { harnessOptions as t };
17
+
18
+ //# sourceMappingURL=harness-hle7yBVs.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness-hle7yBVs.mjs","names":["DaytonaSandbox","VercelSandbox"],"sources":["../../src/cli/harness.ts"],"sourcesContent":["import type { Harness } from \"@codeworksh/harness/effect\";\nimport DaytonaSandbox from \"@codeworksh/harness/sandboxes/daytona\";\nimport VercelSandbox from \"@codeworksh/harness/sandboxes/vercel\";\nimport { Option } from \"effect\";\n\ninterface Shared {\n\treadonly userConfigDir: Option.Option<string>;\n\treadonly home: Option.Option<string>;\n\treadonly database: Option.Option<string>;\n}\n\n/**\n * The harness boot options every local-harness command builds from the shared\n * flags. `run` and `serve` must agree on the data directory and driver set --\n * a session created by one is expected to be readable by the other.\n */\nexport const harnessOptions = (shared: Shared): Harness.Options => ({\n\t...(Option.isNone(shared.userConfigDir) ? {} : { userConfigDir: shared.userConfigDir.value }),\n\t...(Option.isNone(shared.home) ? {} : { home: shared.home.value }),\n\t...(Option.isNone(shared.database) ? {} : { database: shared.database.value }),\n\tsandboxes: [DaytonaSandbox.make({}), VercelSandbox.make({})],\n});\n"],"mappings":";;;;;;;;AAgBA,MAAa,kBAAkB,YAAqC;CACnE,GAAI,OAAO,OAAO,OAAO,aAAa,IAAI,CAAC,IAAI,EAAE,eAAe,OAAO,cAAc,MAAM;CAC3F,GAAI,OAAO,OAAO,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,MAAM,OAAO,KAAK,MAAM;CAChE,GAAI,OAAO,OAAO,OAAO,QAAQ,IAAI,CAAC,IAAI,EAAE,UAAU,OAAO,SAAS,MAAM;CAC5E,WAAW,CAACA,QAAe,KAAK,CAAC,CAAC,GAAGC,UAAc,KAAK,CAAC,CAAC,CAAC;AAC5D"}
package/index.d.mts ADDED
@@ -0,0 +1,23 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { CliError } from "effect/unstable/cli";
3
+ //#region src/cli/error.d.ts
4
+ declare const InvalidInputError_base: Schema.Class<InvalidInputError, Schema.TaggedStruct<"CLI.InvalidInputError", {
5
+ readonly message: Schema.String;
6
+ }>, import("effect/Cause").YieldableError>;
7
+ /** Bad flag or argument combinations the parser cannot express on its own. */
8
+ declare class InvalidInputError extends InvalidInputError_base {}
9
+ declare const ModelgenError_base: Schema.Class<ModelgenError, Schema.TaggedStruct<"CLI.ModelgenError", {
10
+ readonly cause: Schema.Defect;
11
+ }>, import("effect/Cause").YieldableError>;
12
+ declare class ModelgenError extends ModelgenError_base {}
13
+ /**
14
+ * Every failure a command handler may surface to the runtime. Harness failures are
15
+ * rendered inside the handler that owns them, so only the CLI's own errors reach
16
+ * the top-level renderer.
17
+ */
18
+ type CommandError = InvalidInputError | ModelgenError;
19
+ //#endregion
20
+ //#region src/index.d.ts
21
+ export declare const main: Effect.Effect<void, CommandError | CliError.CliError>;
22
+ //#endregion
23
+ //# sourceMappingURL=index.d.mts.map
package/index.mjs ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ import { i as Cmd, n as handlers, r as run } from "./runtime-DuL-GGrx.mjs";
3
+ import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
4
+ import * as NodeServices from "@effect/platform-node/NodeServices";
5
+ import { Effect } from "effect";
6
+ //#region package.json
7
+ var version = "0.0.1";
8
+ //#endregion
9
+ //#region src/index.ts
10
+ const Handlers = handlers(Cmd, {
11
+ run: () => import("./run-B4mqUQsS.mjs"),
12
+ serve: () => import("./serve-CRUpKDkt.mjs"),
13
+ models: {
14
+ $: () => import("./list-crXAfyCe.mjs"),
15
+ providers: () => import("./providers-BcJ_s8zf.mjs"),
16
+ generate: () => import("./generate-BMJEbGEP.mjs")
17
+ }
18
+ });
19
+ const main = run(Cmd, Handlers, { version }).pipe(Effect.provide(NodeServices.layer));
20
+ NodeRuntime.runMain(main);
21
+ //#endregion
22
+ export { main };
23
+
24
+ //# sourceMappingURL=index.mjs.map
package/index.mjs.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["Runtime.handlers","Runtime.run","pkg.version"],"sources":["../../package.json","../../src/index.ts"],"sourcesContent":["","#!/usr/bin/env node\n\nimport * as NodeRuntime from \"@effect/platform-node/NodeRuntime\";\nimport * as NodeServices from \"@effect/platform-node/NodeServices\";\nimport { Effect } from \"effect\";\nimport type { CliError } from \"effect/unstable/cli\";\nimport pkg from \"../package.json\" with { type: \"json\" };\nimport { Cmd } from \"./cli/cmd/cmd.ts\";\nimport type { CommandError } from \"./cli/error.ts\";\nimport { Runtime } from \"./framework/runtime.ts\";\n\nconst Handlers = Runtime.handlers(Cmd, {\n\trun: () => import(\"./cli/cmd/handlers/run.ts\"),\n\tserve: () => import(\"./cli/cmd/handlers/serve.ts\"),\n\tmodels: {\n\t\t$: () => import(\"./cli/cmd/handlers/models/list.ts\"),\n\t\tproviders: () => import(\"./cli/cmd/handlers/models/providers.ts\"),\n\t\tgenerate: () => import(\"./cli/cmd/handlers/models/generate.ts\"),\n\t},\n});\n\nexport const main: Effect.Effect<void, CommandError | CliError.CliError> = Runtime.run(Cmd, Handlers, {\n\tversion: pkg.version,\n}).pipe(Effect.provide(NodeServices.layer));\n\nNodeRuntime.runMain(main);\n"],"mappings":";;;;;;;;;ACWA,MAAM,WAAWA,SAAiB,KAAK;CACtC,WAAW,OAAO;CAClB,aAAa,OAAO;CACpB,QAAQ;EACP,SAAS,OAAO;EAChB,iBAAiB,OAAO;EACxB,gBAAgB,OAAO;CACxB;AACD,CAAC;AAED,MAAa,OAA8DC,IAAY,KAAK,UAAU,EAC5FC,QACV,CAAC,CAAC,CAAC,KAAK,OAAO,QAAQ,aAAa,KAAK,CAAC;AAE1C,YAAY,QAAQ,IAAI"}
@@ -0,0 +1,28 @@
1
+ import { d as writeOut, i as reportFailure, t as InvalidInputError } from "./error-Cr8LvfEq.mjs";
2
+ import { i as Cmd, t as handler } from "./runtime-DuL-GGrx.mjs";
3
+ import { t as loadCatalog } from "./catalog-DobwC9tt.mjs";
4
+ import { Effect, Option } from "effect";
5
+ //#region src/cli/cmd/handlers/models/list.ts
6
+ var list_default = handler(Cmd.commands.models, Effect.fn("CLI.models.list")(function* ({ provider }) {
7
+ return yield* Effect.gen(function* () {
8
+ const catalog = yield* loadCatalog;
9
+ if (Option.isSome(provider)) {
10
+ const providerId = provider.value;
11
+ if (!Object.hasOwn(catalog, providerId)) return yield* new InvalidInputError({ message: `provider "${providerId}" is not in the catalog\nhint: run \`codework models providers\`` });
12
+ const sorted = Object.keys(catalog[providerId] ?? {}).sort((a, b) => a.localeCompare(b));
13
+ yield* writeOut(sorted.map((modelId) => `${providerId}/${modelId}\n`).join(""));
14
+ return;
15
+ }
16
+ const lines = [];
17
+ const providers = Object.keys(catalog).sort((a, b) => a.localeCompare(b));
18
+ for (const providerId of providers) {
19
+ const providerModels = Object.keys(catalog[providerId] ?? {}).sort((a, b) => a.localeCompare(b));
20
+ for (const modelId of providerModels) lines.push(`${providerId}/${modelId}\n`);
21
+ }
22
+ yield* writeOut(lines.join(""));
23
+ }).pipe(Effect.catch(reportFailure));
24
+ }));
25
+ //#endregion
26
+ export { list_default as default };
27
+
28
+ //# sourceMappingURL=list-crXAfyCe.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-crXAfyCe.mjs","names":["Runtime.handler"],"sources":["../../src/cli/cmd/handlers/models/list.ts"],"sourcesContent":["import { Effect, Option } from \"effect\";\nimport { Runtime } from \"../../../../framework/runtime.ts\";\nimport { InvalidInputError, reportFailure } from \"../../../error.ts\";\nimport { writeOut } from \"../../../output.ts\";\nimport { Cmd } from \"../../cmd.ts\";\nimport { loadCatalog } from \"./catalog.ts\";\n\nexport default Runtime.handler(\n\tCmd.commands.models,\n\tEffect.fn(\"CLI.models.list\")(function* ({ provider }) {\n\t\tconst program = Effect.gen(function* () {\n\t\t\tconst catalog = yield* loadCatalog;\n\t\t\tif (Option.isSome(provider)) {\n\t\t\t\tconst providerId = provider.value;\n\t\t\t\tif (!Object.hasOwn(catalog, providerId)) {\n\t\t\t\t\treturn yield* new InvalidInputError({\n\t\t\t\t\t\tmessage: `provider \"${providerId}\" is not in the catalog\\nhint: run \\`codework models providers\\``,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst sorted = Object.keys(catalog[providerId] ?? {}).sort((a, b) => a.localeCompare(b));\n\t\t\t\tyield* writeOut(sorted.map((modelId) => `${providerId}/${modelId}\\n`).join(\"\"));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst lines: string[] = [];\n\t\t\tconst providers = Object.keys(catalog).sort((a, b) => a.localeCompare(b));\n\t\t\tfor (const providerId of providers) {\n\t\t\t\tconst providerModels = Object.keys(catalog[providerId] ?? {}).sort((a, b) => a.localeCompare(b));\n\t\t\t\tfor (const modelId of providerModels) {\n\t\t\t\t\tlines.push(`${providerId}/${modelId}\\n`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tyield* writeOut(lines.join(\"\"));\n\t\t});\n\n\t\treturn yield* program.pipe(Effect.catch(reportFailure));\n\t}),\n);\n"],"mappings":";;;;;AAOA,IAAA,eAAeA,QACd,IAAI,SAAS,QACb,OAAO,GAAG,iBAAiB,CAAC,CAAC,WAAW,EAAE,YAAY;CA0BrD,OAAO,OAzBS,OAAO,IAAI,aAAa;EACvC,MAAM,UAAU,OAAO;EACvB,IAAI,OAAO,OAAO,QAAQ,GAAG;GAC5B,MAAM,aAAa,SAAS;GAC5B,IAAI,CAAC,OAAO,OAAO,SAAS,UAAU,GACrC,OAAO,OAAO,IAAI,kBAAkB,EACnC,SAAS,aAAa,WAAW,kEAClC,CAAC;GAEF,MAAM,SAAS,OAAO,KAAK,QAAQ,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;GACvF,OAAO,SAAS,OAAO,KAAK,YAAY,GAAG,WAAW,GAAG,QAAQ,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC;GAC9E;EACD;EAEA,MAAM,QAAkB,CAAC;EACzB,MAAM,YAAY,OAAO,KAAK,OAAO,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;EACxE,KAAK,MAAM,cAAc,WAAW;GACnC,MAAM,iBAAiB,OAAO,KAAK,QAAQ,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;GAC/F,KAAK,MAAM,WAAW,gBACrB,MAAM,KAAK,GAAG,WAAW,GAAG,QAAQ,GAAG;EAEzC;EACA,OAAO,SAAS,MAAM,KAAK,EAAE,CAAC;CAC/B,CAEoB,CAAC,CAAC,KAAK,OAAO,MAAM,aAAa,CAAC;AACvD,CAAC,CACF"}
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@codeworksh/cli",
3
+ "version": "0.0.1-dev.20260918040208",
4
+ "description": "CLI for running CodeWork coding-agent sessions.",
5
+ "keywords": [
6
+ "agent",
7
+ "ai",
8
+ "cli",
9
+ "codework",
10
+ "coding-agent",
11
+ "typescript"
12
+ ],
13
+ "homepage": "https://github.com/codeworksh/codework/tree/main/packages/codework",
14
+ "bugs": {
15
+ "url": "https://github.com/codeworksh/codework/issues"
16
+ },
17
+ "license": "MIT",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/codeworksh/codework.git",
21
+ "directory": "packages/codework"
22
+ },
23
+ "type": "module",
24
+ "types": "./index.d.mts",
25
+ "bin": {
26
+ "codework": "index.mjs"
27
+ },
28
+ "exports": {
29
+ ".": {
30
+ "development": "./src/index.ts",
31
+ "types": "./index.d.mts",
32
+ "import": "./index.mjs",
33
+ "default": "./index.mjs"
34
+ },
35
+ "./package.json": "./package.json"
36
+ },
37
+ "files": [
38
+ "**/*",
39
+ "README.md",
40
+ "LICENSE"
41
+ ],
42
+ "publishConfig": {
43
+ "access": "public"
44
+ },
45
+ "engines": {
46
+ "node": ">=24.14.1"
47
+ },
48
+ "dependencies": {
49
+ "@codeworksh/aikit": "0.8.0",
50
+ "@effect/platform-node": "4.0.0-rc.115",
51
+ "@effect/sql-sqlite-node": "4.0.0-rc.115",
52
+ "@platformatic/vfs": "^0.4.0",
53
+ "effect": "4.0.0-rc.115",
54
+ "just-bash": "^3.4.2",
55
+ "tslib": "^2.8.1",
56
+ "typebox": "^1.3.30",
57
+ "uuid": "^14.0.2",
58
+ "uuidv7": "^1.2.1"
59
+ },
60
+ "peerDependencies": {
61
+ "@daytona/sdk": "*",
62
+ "@vercel/sandbox": "*"
63
+ },
64
+ "peerDependenciesMeta": {
65
+ "@daytona/sdk": {
66
+ "optional": true
67
+ },
68
+ "@vercel/sandbox": {
69
+ "optional": true
70
+ }
71
+ }
72
+ }
@@ -0,0 +1,15 @@
1
+ import { d as writeOut, i as reportFailure } from "./error-Cr8LvfEq.mjs";
2
+ import { i as Cmd, t as handler } from "./runtime-DuL-GGrx.mjs";
3
+ import { n as loadProviders } from "./catalog-DobwC9tt.mjs";
4
+ import { Effect } from "effect";
5
+ //#region src/cli/cmd/handlers/models/providers.ts
6
+ var providers_default = handler(Cmd.commands.models.commands.providers, Effect.fn("CLI.models.providers")(function* () {
7
+ return yield* Effect.gen(function* () {
8
+ const sorted = [...yield* loadProviders].sort((a, b) => a.localeCompare(b));
9
+ yield* writeOut(sorted.map((providerId) => `${providerId}\n`).join(""));
10
+ }).pipe(Effect.catch(reportFailure));
11
+ }));
12
+ //#endregion
13
+ export { providers_default as default };
14
+
15
+ //# sourceMappingURL=providers-BcJ_s8zf.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers-BcJ_s8zf.mjs","names":["Runtime.handler"],"sources":["../../src/cli/cmd/handlers/models/providers.ts"],"sourcesContent":["import { Effect } from \"effect\";\nimport { Runtime } from \"../../../../framework/runtime.ts\";\nimport { reportFailure } from \"../../../error.ts\";\nimport { writeOut } from \"../../../output.ts\";\nimport { Cmd } from \"../../cmd.ts\";\nimport { loadProviders } from \"./catalog.ts\";\n\nexport default Runtime.handler(\n\tCmd.commands.models.commands.providers,\n\tEffect.fn(\"CLI.models.providers\")(function* () {\n\t\tconst program = Effect.gen(function* () {\n\t\t\tconst providers = yield* loadProviders;\n\t\t\tconst sorted = [...providers].sort((a, b) => a.localeCompare(b));\n\t\t\tyield* writeOut(sorted.map((providerId) => `${providerId}\\n`).join(\"\"));\n\t\t});\n\n\t\treturn yield* program.pipe(Effect.catch(reportFailure));\n\t}),\n);\n"],"mappings":";;;;;AAOA,IAAA,oBAAeA,QACd,IAAI,SAAS,OAAO,SAAS,WAC7B,OAAO,GAAG,sBAAsB,CAAC,CAAC,aAAa;CAO9C,OAAO,OANS,OAAO,IAAI,aAAa;EAEvC,MAAM,SAAS,CAAC,GAAG,OADM,aACG,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;EAC/D,OAAO,SAAS,OAAO,KAAK,eAAe,GAAG,WAAW,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC;CACvE,CAEoB,CAAC,CAAC,KAAK,OAAO,MAAM,aAAa,CAAC;AACvD,CAAC,CACF"}
@@ -0,0 +1,144 @@
1
+ import { B as LLMTextDelta, D as resolve, G as ID$1, O as stop, U as ID, V as TurnEnded, a as addUsage, b as create, c as terminalColumns, d as writeOut, f as layer, k as layer$1, l as usage, m as run, o as emptyUsage, p as make, r as renderError, s as header, t as InvalidInputError, u as writeError, y as attach, z as LLMEnded } from "./error-Cr8LvfEq.mjs";
2
+ import { i as Cmd, t as handler } from "./runtime-DuL-GGrx.mjs";
3
+ import { t as harnessOptions } from "./harness-hle7yBVs.mjs";
4
+ import { Effect, Exit, Fiber, Option, Queue, Ref, Schema, Stream } from "effect";
5
+ //#region src/cli/cmd/handlers/run.ts
6
+ const initialRenderState = {
7
+ usage: emptyUsage,
8
+ textSeen: false,
9
+ textEndsWithNewline: false
10
+ };
11
+ const isTextDelta = Schema.is(LLMTextDelta);
12
+ const isLLMEnded = Schema.is(LLMEnded);
13
+ const isTurnEnded = Schema.is(TurnEnded);
14
+ const render = (state, ended) => Effect.fn("CLI.render")(function* (event) {
15
+ if (isTextDelta(event)) {
16
+ yield* writeOut(event.data.delta);
17
+ if (event.data.delta.length > 0) yield* Ref.update(state, (current) => ({
18
+ ...current,
19
+ textSeen: true,
20
+ textEndsWithNewline: event.data.delta.endsWith("\n")
21
+ }));
22
+ return;
23
+ }
24
+ if (isLLMEnded(event)) {
25
+ yield* Ref.update(state, (current) => ({
26
+ ...current,
27
+ usage: addUsage(current.usage, event.data.message)
28
+ }));
29
+ return;
30
+ }
31
+ if (ended !== void 0 && isTurnEnded(event)) yield* Queue.offer(ended, event.data.messageId);
32
+ });
33
+ const finish = Effect.fn("CLI.finish")(function* (state, columns) {
34
+ const rendered = yield* Ref.get(state);
35
+ if (rendered.textSeen && !rendered.textEndsWithNewline) yield* writeOut("\n");
36
+ yield* writeError(usage(rendered.usage, columns));
37
+ });
38
+ const awaitMessage = Effect.fn("CLI.awaitMessage")(function* (ended, messageId) {
39
+ while ((yield* Queue.take(ended)) !== messageId);
40
+ });
41
+ const selectSandbox = Effect.fn("CLI.selectSandbox")(function* (input) {
42
+ const selection = yield* resolve(input);
43
+ if (selection.created && selection.info !== void 0) {
44
+ const id = selection.info.id;
45
+ yield* Effect.addFinalizer(() => Effect.ignore(stop(id)));
46
+ }
47
+ return selection.info;
48
+ });
49
+ var run_default = handler(Cmd.commands.run, Effect.fn("CLI.run")(function* ({ prompt, session, cwd, sandboxDriver, sandboxProviderId, sandboxId, provider, model, thinking, server }) {
50
+ const shared = yield* Cmd.spec;
51
+ if (Option.isSome(session) && (Option.isSome(cwd) || Option.isSome(sandboxDriver) || Option.isSome(sandboxProviderId) || Option.isSome(sandboxId))) return yield* new InvalidInputError({ message: "--cwd, --sandbox-driver, --sandbox-id, and --sandbox-provider-id can only be used when creating a new session" });
52
+ if (Option.isSome(provider) !== Option.isSome(model)) return yield* new InvalidInputError({ message: "--provider and --model must be provided together" });
53
+ if (Option.isSome(sandboxProviderId) && Option.isNone(sandboxDriver)) return yield* new InvalidInputError({ message: "--sandbox-provider-id requires a remote --sandbox-driver" });
54
+ if (Option.isSome(server) && [
55
+ shared.home,
56
+ shared.database,
57
+ shared.userConfigDir
58
+ ].some(Option.isSome)) return yield* new InvalidInputError({ message: "--home, --database, and --user-config-dir belong on codework serve when using --server" });
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) } : {
61
+ driver: Option.getOrElse(sandboxDriver, () => "local"),
62
+ ...Option.isNone(sandboxProviderId) ? {} : { providerResourceId: sandboxProviderId.value }
63
+ };
64
+ const runtime = {
65
+ ...Option.isNone(provider) || Option.isNone(model) ? {} : { model: {
66
+ provider: provider.value,
67
+ id: model.value
68
+ } },
69
+ ...Option.isNone(thinking) ? {} : { thinkingLevel: thinking.value }
70
+ };
71
+ const remote = Effect.gen(function* () {
72
+ const rpc = yield* make;
73
+ const info = Option.isSome(session) ? yield* rpc["session.configure"]({
74
+ sessionId: ID$1.make(session.value),
75
+ runtime
76
+ }) : yield* rpc["session.create"]({
77
+ title: "CLI",
78
+ runtime,
79
+ ...Option.isNone(cwd) ? {} : { directory: cwd.value },
80
+ sandbox: selection
81
+ });
82
+ const state = yield* Ref.make(initialRenderState);
83
+ const columns = terminalColumns();
84
+ yield* writeError(header({
85
+ sessionId: info.id,
86
+ sandbox: info.sandbox?.driver ?? "local",
87
+ directory: info.directory,
88
+ columns
89
+ }));
90
+ if (info.sandbox !== void 0) yield* writeError(`sandbox-id: ${info.sandbox.id}\n`);
91
+ yield* run(rpc, {
92
+ sessionId: info.id,
93
+ text: prompt
94
+ }, render(state)).pipe(Effect.onInterrupt(() => rpc["session.interrupt"]({ sessionId: info.id }).pipe(Effect.timeout("5 seconds"), Effect.ignore)));
95
+ yield* finish(state, columns);
96
+ });
97
+ const program = Effect.gen(function* () {
98
+ let handle;
99
+ if (Option.isSome(session)) handle = yield* attach({
100
+ sessionId: ID$1.make(session.value),
101
+ ...runtime
102
+ });
103
+ else {
104
+ const selected = yield* selectSandbox(selection);
105
+ handle = yield* create({
106
+ title: "CLI",
107
+ ...runtime,
108
+ ...selected === void 0 ? {} : { sandbox: selected },
109
+ ...Option.isNone(cwd) ? {} : { directory: cwd.value }
110
+ });
111
+ }
112
+ const ended = yield* Queue.unbounded();
113
+ const renderState = yield* Ref.make(initialRenderState);
114
+ const printer = yield* handle.events().pipe(Stream.runForEach(render(renderState, ended)), Effect.forkScoped({ startImmediately: true }));
115
+ const info = yield* handle.info;
116
+ const columns = terminalColumns();
117
+ yield* writeError(header({
118
+ sessionId: handle.id,
119
+ sandbox: info.sandbox?.driver ?? "local",
120
+ directory: info.directory,
121
+ columns
122
+ }));
123
+ const execution = yield* handle.prompt({
124
+ text: prompt,
125
+ delivery: "followUp"
126
+ }).pipe(Effect.andThen(handle.resume()), Effect.exit);
127
+ yield* handle.wait();
128
+ if (Exit.isFailure(execution)) return yield* Effect.failCause(execution.cause);
129
+ const leaf = (yield* handle.path()).at(-1);
130
+ if (leaf !== void 0) yield* awaitMessage(ended, leaf.entry.id);
131
+ yield* Fiber.interrupt(printer);
132
+ yield* finish(renderState, columns);
133
+ });
134
+ return yield* Effect.gen(function* () {
135
+ if (Option.isSome(server)) return yield* remote.pipe(Effect.provide(layer(server.value)));
136
+ return yield* program.pipe(Effect.provide(layer$1(harnessOptions(shared))));
137
+ }).pipe(Effect.scoped, Effect.catch((error) => writeError(renderError(error)).pipe(Effect.andThen(Effect.sync(() => {
138
+ process.exitCode = 1;
139
+ })))));
140
+ }));
141
+ //#endregion
142
+ export { run_default as default };
143
+
144
+ //# sourceMappingURL=run-B4mqUQsS.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-B4mqUQsS.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\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\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});\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,163 @@
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
+ const Cmd = make("codework", {
23
+ description: "CodeWork Command Line Interface",
24
+ shared: {
25
+ userConfigDir: Flag.String("user-config-dir").pipe(Flag.withDescription("Directory containing user config overrides (e.g. settings.json)"), Flag.optional),
26
+ home: Flag.String("home").pipe(Flag.withDescription("CodeWork data directory (default: ~/.codework)"), Flag.optional),
27
+ database: Flag.String("database").pipe(Flag.withDescription("SQLite database path or :memory:"), Flag.optional)
28
+ },
29
+ commands: [
30
+ make("run", {
31
+ description: "Start or continue an agent session",
32
+ params: {
33
+ server: Flag.String("server").pipe(Flag.withDescription("RPC server URL (ws://host:port/rpc)"), Flag.optional),
34
+ prompt: Argument.String("prompt").pipe(Argument.withDescription("Prompt for the agent")),
35
+ session: Flag.String("session").pipe(Flag.withAlias("s"), Flag.withDescription("Continue an existing session"), Flag.optional),
36
+ cwd: Flag.String("cwd").pipe(Flag.withAlias("C"), Flag.withDescription("Working directory for a new session"), Flag.optional),
37
+ sandboxDriver: Flag.String("sandbox-driver").pipe(Flag.withDescription("Sandbox driver for a new session (default: local)"), Flag.optional),
38
+ sandboxId: Flag.String("sandbox-id").pipe(Flag.withDescription("Reuse an existing sandbox instance"), Flag.optional),
39
+ sandboxProviderId: Flag.String("sandbox-provider-id").pipe(Flag.withDescription("Provider ID of an existing remote sandbox"), Flag.optional),
40
+ provider: Flag.String("provider").pipe(Flag.withDescription("Model catalog provider ID"), Flag.optional),
41
+ model: Flag.String("model").pipe(Flag.withDescription("Model ID"), Flag.optional),
42
+ thinking: Flag.Literals("thinking", thinkingLevels).pipe(Flag.withDescription("Reasoning effort the model uses before answering"), Flag.optional)
43
+ },
44
+ examples: [
45
+ {
46
+ command: "codework run \"Inspect the failing tests\"",
47
+ description: "Create a session"
48
+ },
49
+ {
50
+ command: "codework run --provider openai --model gpt-5.5 --thinking high \"Inspect the failing tests\"",
51
+ description: "Create a session with an explicit model"
52
+ },
53
+ {
54
+ command: "codework run --sandbox-driver daytona \"Inspect the repository\"",
55
+ description: "Create a Daytona sandbox and session"
56
+ },
57
+ {
58
+ command: "codework run --sandbox-driver daytona --sandbox-provider-id <id> \"Inspect the repository\"",
59
+ description: "Use an existing remote sandbox"
60
+ },
61
+ {
62
+ command: "codework run --session <id> --provider openai --model gpt-5.6-luna \"Now fix them\"",
63
+ description: "Continue a session with explicit model bindings"
64
+ }
65
+ ]
66
+ }),
67
+ make("serve", {
68
+ description: "Start the CodeWork RPC server",
69
+ params: {
70
+ host: Flag.String("host").pipe(Flag.withDescription("Host interface to bind"), Flag.withDefault("127.0.0.1")),
71
+ port: Flag.Int("port").pipe(Flag.withSchema(Schema.Int.check(Schema.isBetween({
72
+ minimum: 0,
73
+ maximum: 65535
74
+ }))), Flag.withDescription("Port to listen on (0 for an ephemeral port)"), Flag.withDefault(7433))
75
+ },
76
+ examples: [{
77
+ command: "codework serve",
78
+ description: "Start the RPC server on 127.0.0.1:7433"
79
+ }, {
80
+ command: "codework serve --port 0",
81
+ description: "Choose an available local port"
82
+ }]
83
+ }),
84
+ make("models", {
85
+ description: "List or generate the model catalog",
86
+ params: { provider: Flag.String("provider").pipe(Flag.withDescription("Model catalog provider ID"), Flag.optional) },
87
+ examples: [
88
+ {
89
+ command: "codework models",
90
+ description: "List all models from all providers"
91
+ },
92
+ {
93
+ command: "codework models --provider openai",
94
+ description: "List models for a specific provider"
95
+ },
96
+ {
97
+ command: "codework models providers",
98
+ description: "List all available provider IDs"
99
+ }
100
+ ],
101
+ commands: [make("providers", { description: "List available model providers in the catalog" }), make("generate", {
102
+ description: "Generate or update the model catalog",
103
+ params: { path: Argument.String("path").pipe(Argument.withDescription("Output file or directory; defaults to CODEWORK_MODELS_FILE or ./models.gen.json"), Argument.optional) },
104
+ examples: [
105
+ {
106
+ command: "codework models generate",
107
+ description: "Generate models.gen.json"
108
+ },
109
+ {
110
+ command: "codework models generate .",
111
+ description: "Generate models.gen.json in the current directory"
112
+ },
113
+ {
114
+ command: "codework models generate /path/to/models.gen.json",
115
+ description: "Generate the catalog at an explicit path"
116
+ }
117
+ ]
118
+ })]
119
+ })
120
+ ]
121
+ });
122
+ //#endregion
123
+ //#region src/framework/runtime.ts
124
+ /** Type-checks a handler against the spec node it implements. */
125
+ function handler(_node, run) {
126
+ return run;
127
+ }
128
+ function handlers(root, handlers) {
129
+ const result = [];
130
+ function add(node, value) {
131
+ if (typeof value === "function") {
132
+ result.push({
133
+ spec: node.spec,
134
+ load: value
135
+ });
136
+ return;
137
+ }
138
+ if (value.$ !== void 0) result.push({
139
+ spec: node.spec,
140
+ load: value.$
141
+ });
142
+ for (const [name, child] of Object.entries(node.commands)) {
143
+ const nested = value[name];
144
+ if (nested !== void 0) add(child, nested);
145
+ }
146
+ }
147
+ add(root, handlers);
148
+ return result;
149
+ }
150
+ function run(root, handlers, options) {
151
+ return Command.run(provide(root, handlers), options);
152
+ }
153
+ function provide(node, handlers) {
154
+ const found = handlers.find((entry) => entry.spec === node.spec);
155
+ const spec = found ? node.spec.pipe(Command.withHandler((input) => Effect.promise(found.load).pipe(Effect.flatMap((module) => module.default(input))))) : node.spec;
156
+ const children = Object.values(node.commands);
157
+ if (children.length === 0) return spec;
158
+ return spec.pipe(Command.withSubcommands(children.map((child) => provide(child, handlers))));
159
+ }
160
+ //#endregion
161
+ export { Cmd as i, handlers as n, run as r, handler as t };
162
+
163
+ //# sourceMappingURL=runtime-DuL-GGrx.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-DuL-GGrx.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\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(\"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(\"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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"}