authorgravatar for 91240327+shivamhwp@users.noreply.github.comshivam <91240327+shivamhwp@users.noreply.github.com> 2026-03-23 23:10:51+05:30
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-03-23 10:40:51-07:00
log754cded24abe6eff74e18a7e741a25c20cfb981d
treeec219753fffca287c1f0e27d4d2cbd4d58702350
parent2b6640af1e6e058f2c7206409d92bf5332fc9e90
signature Signed by PGP key B5690EEEBB952194

Load PTY adapter at runtime (#1311)

Co-authored-by: Julius Marminge <julius0216@outlook.com>

3 files changed, 25 insertions(+), 13 deletions(-)

apps/server/src/serverLayers.ts+20-10
......@@ -1,5 +1,5 @@
11import * as NodeServices from "@effect/platform-node/NodeServices";
2import { Effect, FileSystem, Layer } from "effect";
2import { Effect, FileSystem, Layer, Path } from "effect";
33import * as SqlClient from "effect/unstable/sql/SqlClient";
44
55import { CheckpointDiffQueryLive } from "./checkpointing/Layers/CheckpointDiffQuery";
......@@ -32,10 +32,26 @@ import { GitCoreLive } from "./git/Layers/GitCore";
3232import { GitHubCliLive } from "./git/Layers/GitHubCli";
3333import { CodexTextGenerationLive } from "./git/Layers/CodexTextGeneration";
3434import { GitServiceLive } from "./git/Layers/GitService";
35import { BunPtyAdapterLive } from "./terminal/Layers/BunPTY";
36import { NodePtyAdapterLive } from "./terminal/Layers/NodePTY";
35import { PtyAdapter } from "./terminal/Services/PTY";
3736import { AnalyticsService } from "./telemetry/Services/AnalyticsService";
3837
38type RuntimePtyAdapterLoader = {
39 layer: Layer.Layer<PtyAdapter, never, FileSystem.FileSystem | Path.Path>;
40};
41
42const runtimePtyAdapterLoaders = {
43 bun: () => import("./terminal/Layers/BunPTY"),
44 node: () => import("./terminal/Layers/NodePTY"),
45} satisfies Record<string, () => Promise<RuntimePtyAdapterLoader>>;
46
47const makeRuntimePtyAdapterLayer = () =>
48 Effect.gen(function* () {
49 const runtime = process.versions.bun !== undefined ? "bun" : "node";
50 const loader = runtimePtyAdapterLoaders[runtime];
51 const ptyAdapterModule = yield* Effect.promise<RuntimePtyAdapterLoader>(loader);
52 return ptyAdapterModule.layer;
53 }).pipe(Layer.unwrap);
54
3955export function makeServerProviderLayer(): Layer.Layer<
4056 ProviderService,
4157 ProviderUnsupportedError,
......@@ -108,13 +124,7 @@ export function makeServerRuntimeServicesLayer() {
108124 Layer.provideMerge(checkpointReactorLayer),
109125 );
110126
111 const terminalLayer = TerminalManagerLive.pipe(
112 Layer.provide(
113 typeof Bun !== "undefined" && process.platform !== "win32"
114 ? BunPtyAdapterLive
115 : NodePtyAdapterLive,
116 ),
117 );
127 const terminalLayer = TerminalManagerLive.pipe(Layer.provide(makeRuntimePtyAdapterLayer()));
118128
119129 const gitManagerLayer = GitManagerLive.pipe(
120130 Layer.provideMerge(gitCoreLayer),
apps/server/src/terminal/Layers/BunPTY.ts+4-2
......@@ -86,11 +86,13 @@ class BunPtyProcess implements PtyProcess {
8686 }
8787}
8888
89export const BunPtyAdapterLive = Layer.effect(
89export const layer = Layer.effect(
9090 PtyAdapter,
9191 Effect.gen(function* () {
9292 if (process.platform === "win32") {
93 return yield* Effect.die("Bun PTY terminal support is unavailable on Windows.");
93 return yield* Effect.die(
94 "Bun PTY terminal support is unavailable on Windows. Please use Node.js (e.g. by running `npx t3`) instead.",
95 );
9496 }
9597 return {
9698 spawn: (input) =>
apps/server/src/terminal/Layers/NodePTY.ts+1-1
......@@ -84,7 +84,7 @@ class NodePtyProcess implements PtyProcess {
8484 }
8585}
8686
87export const NodePtyAdapterLive = Layer.effect(
87export const layer = Layer.effect(
8888 PtyAdapter,
8989 Effect.gen(function* () {
9090 const fs = yield* FileSystem.FileSystem;