| author | |
| committer | |
| log | c14bcca1035895edca5ebd8d65faea5fe788a825 |
| tree | 1c3bd5856859c8637cc7b25189c9c27b06c0ee08 |
| parent | 1fa315ea93f24e6f72455e234fa84a97de28492b |
| signature | Signed by PGP key B5690EEEBB952194 |
2 files changed, 39 insertions(+), 4 deletions(-)
apps/server/src/terminal/NodePtyAdapter.test.ts+30-2| ... | ... | @@ -33,6 +33,7 @@ const testLayer = NodePtyAdapter.layer.pipe( |
| 33 | 33 | |
| 34 | 34 | it.effect("spawns through the public adapter with the provided host references", () => |
| 35 | 35 | Effect.gen(function* () { |
| 36 | spawn.mockClear(); | |
| 36 | 37 | const adapter = yield* PtyAdapter.PtyAdapter; |
| 37 | 38 | const process = yield* adapter.spawn({ |
| 38 | 39 | shell: "powershell.exe", |
| ... | ... | @@ -52,8 +53,35 @@ it.effect("spawns through the public adapter with the provided host references", |
| 52 | 53 | cwd: "C:\\workspace", |
| 53 | 54 | cols: 120, |
| 54 | 55 | rows: 40, |
| 55 | env: {}, | |
| 56 | name: "xterm-color", | |
| 56 | env: { TERM: "xterm-256color" }, | |
| 57 | name: "xterm-256color", | |
| 58 | }, | |
| 59 | ]); | |
| 60 | }).pipe(Effect.provide(testLayer)), | |
| 61 | ); | |
| 62 | ||
| 63 | it.effect("preserves a caller-provided TERM in the spawn env on win32", () => | |
| 64 | Effect.gen(function* () { | |
| 65 | spawn.mockClear(); | |
| 66 | const adapter = yield* PtyAdapter.PtyAdapter; | |
| 67 | yield* adapter.spawn({ | |
| 68 | shell: "powershell.exe", | |
| 69 | cwd: "C:\\workspace", | |
| 70 | cols: 80, | |
| 71 | rows: 24, | |
| 72 | env: { TERM: "xterm-direct" }, | |
| 73 | }); | |
| 74 | ||
| 75 | assert.equal(spawn.mock.calls.length, 1); | |
| 76 | assert.deepEqual(spawn.mock.calls[0], [ | |
| 77 | "powershell.exe", | |
| 78 | [], | |
| 79 | { | |
| 80 | cwd: "C:\\workspace", | |
| 81 | cols: 80, | |
| 82 | rows: 24, | |
| 83 | env: { TERM: "xterm-direct" }, | |
| 84 | name: "xterm-256color", | |
| 57 | 85 | }, |
| 58 | 86 | ]); |
| 59 | 87 | }).pipe(Effect.provide(testLayer)), |
apps/server/src/terminal/NodePtyAdapter.ts+9-2| ... | ... | @@ -141,14 +141,21 @@ export const make = Effect.fn("NodePtyAdapter.make")(function* ( |
| 141 | 141 | return PtyAdapter.PtyAdapter.of({ |
| 142 | 142 | spawn: Effect.fn("NodePtyAdapter.spawn")(function* (input) { |
| 143 | 143 | yield* ensureNodePtySpawnHelperExecutableCached; |
| 144 | // node-pty only writes `name` into the child's TERM on the Unix path; | |
| 145 | // the ConPTY path leaves the environment untouched, so Windows children | |
| 146 | // inherit a missing or 16-color TERM unless it is set here. | |
| 147 | const env = | |
| 148 | platform === "win32" && input.env["TERM"] === undefined | |
| 149 | ? { ...input.env, TERM: "xterm-256color" } | |
| 150 | : input.env; | |
| 144 | 151 | const ptyProcess = yield* Effect.try({ |
| 145 | 152 | try: () => |
| 146 | 153 | nodePty.spawn(input.shell, input.args ?? [], { |
| 147 | 154 | cwd: input.cwd, |
| 148 | 155 | cols: input.cols, |
| 149 | 156 | rows: input.rows, |
| 150 | env: input.env, | |
| 151 | name: platform === "win32" ? "xterm-color" : "xterm-256color", | |
| 157 | env, | |
| 158 | name: "xterm-256color", | |
| 152 | 159 | }), |
| 153 | 160 | catch: (cause) => |
| 154 | 161 | new PtyAdapter.PtySpawnError({ |