Skip to content

Commit beda3de

Browse files
committed
fix(contracts): align terminal restart input type across IPC, WS, and server
The NativeApi IPC interface and server TerminalManagerShape both typed the `restart` method with `TerminalOpenInput` (optional cols/rows, includes terminalId), while the WebSocket schema validated against `TerminalRestartInput` (required cols/rows, no terminalId). This corrects the mismatch by: 1. Adding `terminalId` (with decoding default) to `TerminalRestartInput` so it matches the server's actual usage of `input.terminalId`. 2. Updating the IPC `NativeApi.terminal.restart` to accept `TerminalRestartInput`, communicating that cols/rows are required. 3. Updating the server `TerminalManagerShape` and `TerminalManagerRuntime` to accept and decode `TerminalRestartInput` consistently. The change is backward-compatible on the wire since `terminalId` uses `withDecodingDefault` and defaults to `"default"` when omitted.
1 parent 1c43bad commit beda3de

5 files changed

Lines changed: 22 additions & 6 deletions

File tree

apps/server/src/terminal/Layers/Manager.test.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
DEFAULT_TERMINAL_ID,
77
type TerminalEvent,
88
type TerminalOpenInput,
9+
type TerminalRestartInput,
910
} from "@t3tools/contracts";
1011
import { afterEach, describe, expect, it } from "vitest";
1112

@@ -134,6 +135,16 @@ function openInput(overrides: Partial<TerminalOpenInput> = {}): TerminalOpenInpu
134135
};
135136
}
136137

138+
function restartInput(overrides: Partial<TerminalRestartInput> = {}): TerminalRestartInput {
139+
return {
140+
threadId: "thread-1",
141+
cwd: process.cwd(),
142+
cols: 100,
143+
rows: 24,
144+
...overrides,
145+
};
146+
}
147+
137148
function historyLogName(threadId: string): string {
138149
return `terminal_${Encoding.encodeBase64Url(threadId)}.log`;
139150
}
@@ -361,7 +372,7 @@ describe("TerminalManager", () => {
361372
firstProcess.emitData("before restart\n");
362373
await waitFor(() => fs.existsSync(historyLogPath(logsDir)));
363374

364-
const snapshot = await manager.restart(openInput());
375+
const snapshot = await manager.restart(restartInput());
365376
expect(snapshot.history).toBe("");
366377
expect(snapshot.status).toBe("running");
367378
expect(ptyAdapter.spawnInputs).toHaveLength(2);

apps/server/src/terminal/Layers/Manager.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
TerminalCloseInput,
99
TerminalOpenInput,
1010
TerminalResizeInput,
11+
TerminalRestartInput,
1112
TerminalWriteInput,
1213
type TerminalEvent,
1314
type TerminalSessionSnapshot,
@@ -37,6 +38,7 @@ const DEFAULT_OPEN_ROWS = 30;
3738
const TERMINAL_ENV_BLOCKLIST = new Set(["PORT", "ELECTRON_RENDERER_PORT", "ELECTRON_RUN_AS_NODE"]);
3839

3940
const decodeTerminalOpenInput = Schema.decodeUnknownSync(TerminalOpenInput);
41+
const decodeTerminalRestartInput = Schema.decodeUnknownSync(TerminalRestartInput);
4042
const decodeTerminalWriteInput = Schema.decodeUnknownSync(TerminalWriteInput);
4143
const decodeTerminalResizeInput = Schema.decodeUnknownSync(TerminalResizeInput);
4244
const decodeTerminalClearInput = Schema.decodeUnknownSync(TerminalClearInput);
@@ -478,8 +480,8 @@ export class TerminalManagerRuntime extends EventEmitter<TerminalManagerEvents>
478480
});
479481
}
480482

481-
async restart(raw: TerminalOpenInput): Promise<TerminalSessionSnapshot> {
482-
const input = decodeTerminalOpenInput(raw);
483+
async restart(raw: TerminalRestartInput): Promise<TerminalSessionSnapshot> {
484+
const input = decodeTerminalRestartInput(raw);
483485
return this.runWithThreadLock(input.threadId, async () => {
484486
await this.assertValidCwd(input.cwd);
485487

apps/server/src/terminal/Services/Manager.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
TerminalEvent,
1313
TerminalOpenInput,
1414
TerminalResizeInput,
15+
TerminalRestartInput,
1516
TerminalSessionSnapshot,
1617
TerminalSessionStatus,
1718
TerminalWriteInput,
@@ -88,7 +89,7 @@ export interface TerminalManagerShape {
8889
* Always resets history before spawning the new process.
8990
*/
9091
readonly restart: (
91-
input: TerminalOpenInput,
92+
input: TerminalRestartInput,
9293
) => Effect.Effect<TerminalSessionSnapshot, TerminalError>;
9394

9495
/**

packages/contracts/src/ipc.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import type {
2727
TerminalEvent,
2828
TerminalOpenInput,
2929
TerminalResizeInput,
30+
TerminalRestartInput,
3031
TerminalSessionSnapshot,
3132
TerminalWriteInput,
3233
} from "./terminal";
@@ -103,7 +104,7 @@ export interface NativeApi {
103104
write: (input: TerminalWriteInput) => Promise<void>;
104105
resize: (input: TerminalResizeInput) => Promise<void>;
105106
clear: (input: TerminalClearInput) => Promise<void>;
106-
restart: (input: TerminalOpenInput) => Promise<TerminalSessionSnapshot>;
107+
restart: (input: TerminalRestartInput) => Promise<TerminalSessionSnapshot>;
107108
close: (input: TerminalCloseInput) => Promise<void>;
108109
onEvent: (callback: (event: TerminalEvent) => void) => () => void;
109110
};

packages/contracts/src/terminal.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,13 @@ export const TerminalClearInput = TerminalSessionInput;
6060
export type TerminalClearInput = Schema.Codec.Encoded<typeof TerminalClearInput>;
6161

6262
export const TerminalRestartInput = Schema.Struct({
63-
...TerminalThreadInput.fields,
63+
...TerminalSessionInput.fields,
6464
cwd: TrimmedNonEmptyStringSchema,
6565
cols: TerminalColsSchema,
6666
rows: TerminalRowsSchema,
6767
env: Schema.optional(TerminalEnvSchema),
6868
});
69+
export type TerminalRestartInput = Schema.Codec.Encoded<typeof TerminalRestartInput>;
6970

7071
export const TerminalCloseInput = Schema.Struct({
7172
...TerminalThreadInput.fields,

0 commit comments

Comments
 (0)