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