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 @@...@@ -1,5 +1,5 @@
1import * as NodeServices from "@effect/platform-node/NodeServices";1import * as NodeServices from "@effect/platform-node/NodeServices";
2import { Effect, FileSystem, Layer } from "effect";2import { Effect, FileSystem, Layer, Path } from "effect";
3import * as SqlClient from "effect/unstable/sql/SqlClient";3import * as SqlClient from "effect/unstable/sql/SqlClient";
44
5import { CheckpointDiffQueryLive } from "./checkpointing/Layers/CheckpointDiffQuery";5import { CheckpointDiffQueryLive } from "./checkpointing/Layers/CheckpointDiffQuery";
...@@ -32,10 +32,26 @@ import { GitCoreLive } from "./git/Layers/GitCore";...@@ -32,10 +32,26 @@ import { GitCoreLive } from "./git/Layers/GitCore";
32import { GitHubCliLive } from "./git/Layers/GitHubCli";32import { GitHubCliLive } from "./git/Layers/GitHubCli";
33import { CodexTextGenerationLive } from "./git/Layers/CodexTextGeneration";33import { CodexTextGenerationLive } from "./git/Layers/CodexTextGeneration";
34import { GitServiceLive } from "./git/Layers/GitService";34import { GitServiceLive } from "./git/Layers/GitService";
35import { BunPtyAdapterLive } from "./terminal/Layers/BunPTY";35import { PtyAdapter } from "./terminal/Services/PTY";
36import { NodePtyAdapterLive } from "./terminal/Layers/NodePTY";
37import { AnalyticsService } from "./telemetry/Services/AnalyticsService";36import { 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
39export function makeServerProviderLayer(): Layer.Layer<55export function makeServerProviderLayer(): Layer.Layer<
40 ProviderService,56 ProviderService,
41 ProviderUnsupportedError,57 ProviderUnsupportedError,
...@@ -108,13 +124,7 @@ export function makeServerRuntimeServicesLayer() {...@@ -108,13 +124,7 @@ export function makeServerRuntimeServicesLayer() {
108 Layer.provideMerge(checkpointReactorLayer),124 Layer.provideMerge(checkpointReactorLayer),
109 );125 );
110126
111 const terminalLayer = TerminalManagerLive.pipe(127 const terminalLayer = TerminalManagerLive.pipe(Layer.provide(makeRuntimePtyAdapterLayer()));
112 Layer.provide(
113 typeof Bun !== "undefined" && process.platform !== "win32"
114 ? BunPtyAdapterLive
115 : NodePtyAdapterLive,
116 ),
117 );
118128
119 const gitManagerLayer = GitManagerLive.pipe(129 const gitManagerLayer = GitManagerLive.pipe(
120 Layer.provideMerge(gitCoreLayer),130 Layer.provideMerge(gitCoreLayer),
apps/server/src/terminal/Layers/BunPTY.ts+4-2
...@@ -86,11 +86,13 @@ class BunPtyProcess implements PtyProcess {...@@ -86,11 +86,13 @@ class BunPtyProcess implements PtyProcess {
86 }86 }
87}87}
8888
89export const BunPtyAdapterLive = Layer.effect(89export const layer = Layer.effect(
90 PtyAdapter,90 PtyAdapter,
91 Effect.gen(function* () {91 Effect.gen(function* () {
92 if (process.platform === "win32") {92 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 );
94 }96 }
95 return {97 return {
96 spawn: (input) =>98 spawn: (input) =>
apps/server/src/terminal/Layers/NodePTY.ts+1-1
...@@ -84,7 +84,7 @@ class NodePtyProcess implements PtyProcess {...@@ -84,7 +84,7 @@ class NodePtyProcess implements PtyProcess {
84 }84 }
85}85}
8686
87export const NodePtyAdapterLive = Layer.effect(87export const layer = Layer.effect(
88 PtyAdapter,88 PtyAdapter,
89 Effect.gen(function* () {89 Effect.gen(function* () {
90 const fs = yield* FileSystem.FileSystem;90 const fs = yield* FileSystem.FileSystem;