1import * as Console from "effect/Console";
2import * as Effect from "effect/Effect";
3import { ChildProcess, ChildProcessSpawner } from "effect/process";
4
5import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
6import * as NodeServices from "@effect/platform-node/NodeServices";
7
8import * as CodexClient from "../../src/client.ts";
9
10const codexBin = process.env.CODEX_BIN ?? "codex";
11
12const program = Effect.gen(function* () {
13 const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
14 const handle = yield* spawner.spawn(
15 ChildProcess.make(codexBin, ["app-server"], {
16 cwd: process.cwd(),
17 shell: false,
18 }),
19 );
20 const layerCodex = CodexClient.layerChildProcess(handle, {
21 logIncoming: true,
22 logOutgoing: true,
23 });
24
25 yield* Effect.gen(function* () {
26 const client = yield* CodexClient.CodexAppServerClient;
27
28 yield* client.handleServerRequest("item/tool/requestUserInput", (payload) =>
29 Effect.succeed({
30 answers: Object.fromEntries(
31 payload.questions.map((question) => [
32 question.id,
33 {
34 answers:
35 question.options && question.options.length > 0
36 ? [question.options[0]!.label]
37 : ["ok"],
38 },
39 ]),
40 ),
41 }),
42 );
43
44 const initialized = yield* client.request("initialize", {
45 clientInfo: {
46 name: "effect-codex-app-server-probe",
47 title: "Effect Codex App Server Probe",
48 version: "0.0.0",
49 },
50 capabilities: {
51 experimentalApi: true,
52 optOutNotificationMethods: null,
53 },
54 });
55 yield* Console.log("initialize", initialized);
56
57 yield* client.notify("initialized", undefined);
58
59 const account = yield* client.request("account/read", {});
60 yield* Console.log("account/read", account);
61
62 const skills = yield* client.request("skills/list", {
63 cwds: [process.cwd()],
64 });
65 yield* Console.log("skills/list", skills);
66 }).pipe(Effect.provide(layerCodex));
67});
68
69program.pipe(Effect.scoped, Effect.provide(NodeServices.layer), NodeRuntime.runMain);