terminal-pilot 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,416 @@
1
+ # @poe-code/terminal-pilot
2
+
3
+ `terminal-pilot` is a Playwright-like SDK and MCP server for automating interactive CLI apps through a real pseudoterminal (PTY).
4
+
5
+ Use it when plain stdio is not enough: menus, prompts, arrow-key navigation, confirmations, and terminal redraws such as `poe-code configure`.
6
+
7
+ For design rationale and scope, see `docs/plans/terminal-pilot.md`.
8
+
9
+ ## What it includes
10
+
11
+ - **SDK:** `TerminalPilot` → `TerminalSession` → `TerminalScreen`
12
+ - **MCP server:** 10 tools for AI-driven CLI automation
13
+ - **Real PTY execution:** works with interactive CLIs that expect a terminal
14
+ - **Headless by default:** optional `observe: true` mirrors PTY output for debugging
15
+
16
+ ## Entry points
17
+
18
+ ```ts
19
+ import { TerminalPilot } from "@poe-code/terminal-pilot";
20
+ ```
21
+
22
+ ```ts
23
+ import { createTerminalPilotMcpServer, main } from "@poe-code/terminal-pilot/mcp";
24
+ ```
25
+
26
+ CLI bin:
27
+
28
+ ```sh
29
+ terminal-pilot-mcp
30
+ ```
31
+
32
+ Development entry point in this repo:
33
+
34
+ ```sh
35
+ npx tsx packages/terminal-pilot/src/mcp-server.ts
36
+ ```
37
+
38
+ ## SDK API
39
+
40
+ ### `TerminalPilot`
41
+
42
+ Creates and tracks active terminal sessions.
43
+
44
+ ```ts
45
+ import { TerminalPilot } from "@poe-code/terminal-pilot";
46
+
47
+ const pilot = await TerminalPilot.launch();
48
+
49
+ const session = await pilot.newSession({
50
+ command: "poe-code",
51
+ args: ["configure"],
52
+ cwd: process.cwd(),
53
+ env: process.env,
54
+ cols: 120,
55
+ rows: 40,
56
+ observe: false
57
+ });
58
+
59
+ console.log(session.id, session.pid);
60
+ console.log(pilot.sessions().map(({ id, pid }) => ({ id, pid })));
61
+
62
+ await pilot.close();
63
+ ```
64
+
65
+ ```ts
66
+ type NewSessionOptions = {
67
+ command: string;
68
+ args?: string[];
69
+ cwd?: string;
70
+ env?: Record<string, string>;
71
+ cols?: number; // default: 120
72
+ rows?: number; // default: 40
73
+ observe?: boolean; // default: false
74
+ };
75
+
76
+ class TerminalPilot {
77
+ static launch(): Promise<TerminalPilot>;
78
+ newSession(options: NewSessionOptions): Promise<TerminalSession>;
79
+ getSession(id: string): TerminalSession; // throws if missing
80
+ sessions(): TerminalSession[]; // active sessions only
81
+ close(): Promise<void>;
82
+ }
83
+ ```
84
+
85
+ ### `TerminalSession`
86
+
87
+ Represents one PTY-backed CLI process.
88
+
89
+ ```ts
90
+ await session.waitFor(/Pick an agent to configure:/);
91
+ await session.press("ArrowDown");
92
+ await session.press("Enter");
93
+
94
+ await session.waitFor(/Waiting for authorization|default model|configured/i);
95
+
96
+ const screen = await session.screen();
97
+ const history = await session.history({ last: 20 });
98
+
99
+ console.log(screen.text);
100
+ console.log(history.join("\n"));
101
+
102
+ await session.resize(100, 30);
103
+ await session.signal("SIGINT");
104
+ await session.close();
105
+ ```
106
+
107
+ ```ts
108
+ type WaitForOptions = {
109
+ timeout?: number; // default: 10000
110
+ };
111
+
112
+ type HistoryOptions = {
113
+ last?: number;
114
+ };
115
+
116
+ type TerminalKey =
117
+ | "Enter"
118
+ | "Tab"
119
+ | "Escape"
120
+ | "Backspace"
121
+ | "Delete"
122
+ | "ArrowUp"
123
+ | "ArrowDown"
124
+ | "ArrowLeft"
125
+ | "ArrowRight"
126
+ | "Home"
127
+ | "End"
128
+ | "PageUp"
129
+ | "PageDown"
130
+ | "Space"
131
+ | `Control+${string}`
132
+ | `Alt+${string}`;
133
+
134
+ class TerminalSession {
135
+ readonly id: string;
136
+ readonly command: string;
137
+ readonly pid: number;
138
+ exitCode: number | null;
139
+
140
+ type(text: string): Promise<void>; // character-by-character
141
+ fill(text: string): Promise<void>; // bulk write
142
+ press(key: TerminalKey): Promise<void>;
143
+ send(raw: string): Promise<void>; // raw bytes / escape sequences
144
+ signal(signal: string): Promise<void>;
145
+ waitFor(pattern: string | RegExp, options?: WaitForOptions): Promise<string>;
146
+ waitForQuiet(ms: number): Promise<void>;
147
+ screen(): Promise<TerminalScreen>;
148
+ history(options?: HistoryOptions): Promise<string[]>;
149
+ resize(cols: number, rows: number): Promise<void>;
150
+ close(): Promise<number>;
151
+ on(event: "exit", cb: (code: number) => void): void;
152
+ }
153
+ ```
154
+
155
+ Common key names:
156
+
157
+ - Navigation: `ArrowUp`, `ArrowDown`, `ArrowLeft`, `ArrowRight`, `Home`, `End`
158
+ - Editing: `Enter`, `Tab`, `Backspace`, `Delete`, `Space`
159
+ - Control/meta: `Control+c`, `Control+d`, `Alt+x`
160
+
161
+ ### `TerminalScreen`
162
+
163
+ Normalized visible terminal state.
164
+
165
+ ```ts
166
+ const screen = await session.screen();
167
+
168
+ screen.lines; // ANSI-stripped visible lines
169
+ screen.rawLines; // raw visible lines
170
+ screen.cursor; // { row, col }
171
+ screen.size; // { rows, cols }
172
+ screen.text; // lines joined with \n
173
+ screen.contains("Configured");
174
+ screen.line(0);
175
+ screen.line(-1);
176
+ ```
177
+
178
+ ```ts
179
+ class TerminalScreen {
180
+ readonly lines: readonly string[];
181
+ readonly rawLines: readonly string[];
182
+ readonly cursor: { row: number; col: number };
183
+ readonly size: { rows: number; cols: number };
184
+
185
+ get text(): string;
186
+ contains(substring: string): boolean;
187
+ line(index: number): string; // negative indexes supported
188
+ }
189
+ ```
190
+
191
+ ## MCP server
192
+
193
+ The MCP server holds one in-memory `TerminalPilot` instance and exposes terminal automation over stdio.
194
+
195
+ ### Run it
196
+
197
+ Development:
198
+
199
+ ```sh
200
+ npx tsx packages/terminal-pilot/src/mcp-server.ts
201
+ ```
202
+
203
+ Built / installed package:
204
+
205
+ ```sh
206
+ terminal-pilot-mcp
207
+ ```
208
+
209
+ Programmatic:
210
+
211
+ ```ts
212
+ import { main } from "@poe-code/terminal-pilot/mcp";
213
+
214
+ await main();
215
+ ```
216
+
217
+ ### Connect to an MCP client
218
+
219
+ Install the package globally from a local build:
220
+
221
+ ```sh
222
+ cd packages/terminal-pilot
223
+ npm pack --pack-destination /tmp && npm install -g /tmp/poe-code-terminal-pilot-*.tgz && rm /tmp/poe-code-terminal-pilot-*.tgz
224
+ ```
225
+
226
+ This makes the `terminal-pilot-mcp` bin available globally.
227
+
228
+ **Claude Code** (`~/.claude.json` or project `.mcp.json`):
229
+
230
+ ```json
231
+ {
232
+ "mcpServers": {
233
+ "terminal-pilot": {
234
+ "command": "terminal-pilot-mcp"
235
+ }
236
+ }
237
+ }
238
+ ```
239
+
240
+ **Claude Desktop** (`claude_desktop_config.json`):
241
+
242
+ ```json
243
+ {
244
+ "mcpServers": {
245
+ "terminal-pilot": {
246
+ "command": "terminal-pilot-mcp"
247
+ }
248
+ }
249
+ }
250
+ ```
251
+
252
+ **Cursor** (`.cursor/mcp.json`):
253
+
254
+ ```json
255
+ {
256
+ "mcpServers": {
257
+ "terminal-pilot": {
258
+ "command": "terminal-pilot-mcp"
259
+ }
260
+ }
261
+ }
262
+ ```
263
+
264
+ ### Tools
265
+
266
+ `void` means the tool returns no payload.
267
+
268
+ | Tool | Input | Output |
269
+ | --- | --- | --- |
270
+ | `terminal_create_session` | `{ command: string, args?: string[], cwd?: string, cols?: number, rows?: number, observe?: boolean }` | `{ sessionId: string, pid: number }` |
271
+ | `terminal_type` | `{ sessionId: string, text: string }` | `void` |
272
+ | `terminal_press_key` | `{ sessionId: string, key: TerminalKey }` | `void` |
273
+ | `terminal_send_signal` | `{ sessionId: string, signal: string }` | `void` |
274
+ | `terminal_wait_for` | `{ sessionId: string, pattern: string, timeout?: number }` | `{ matched: true, output: string }` |
275
+ | `terminal_read_screen` | `{ sessionId: string }` | `{ lines: string[], cursor: { row: number, col: number }, size: { rows: number, cols: number } }` |
276
+ | `terminal_read_history` | `{ sessionId: string, last?: number }` | `{ lines: string[] }` |
277
+ | `terminal_resize` | `{ sessionId: string, cols: number, rows: number }` | `void` |
278
+ | `terminal_close_session` | `{ sessionId: string }` | `{ exitCode: number }` |
279
+ | `terminal_list_sessions` | `{}` | `{ sessions: Array<{ id: string, command: string, pid: number }> }` |
280
+
281
+ Practical notes:
282
+
283
+ - `terminal_wait_for.pattern` is compiled as a JavaScript `RegExp` on the server.
284
+ - `terminal_type` maps to `session.fill(...)` for bulk text entry.
285
+ - `terminal_read_screen` returns the **current visible screen**, not scrollback.
286
+ - `terminal_read_history` returns ANSI-stripped output since session start.
287
+ - `terminal_list_sessions` returns **active** sessions only.
288
+ - `observe: true` mirrors PTY output to `stderr`, which is useful when debugging MCP-driven runs.
289
+
290
+ Minimal MCP flow:
291
+
292
+ ```json
293
+ {"tool":"terminal_create_session","arguments":{"command":"poe-code","args":["configure"]}}
294
+ {"tool":"terminal_wait_for","arguments":{"sessionId":"<id>","pattern":"Pick an agent to configure:"}}
295
+ {"tool":"terminal_press_key","arguments":{"sessionId":"<id>","key":"Enter"}}
296
+ {"tool":"terminal_read_screen","arguments":{"sessionId":"<id>"}}
297
+ {"tool":"terminal_close_session","arguments":{"sessionId":"<id>"}}
298
+ ```
299
+
300
+ ## Environment variables
301
+
302
+ There are **no terminal-pilot-specific environment variables**.
303
+
304
+ Runtime environment is controlled per session:
305
+
306
+ - SDK: `newSession({ env })`
307
+ - MCP server: spawned commands inherit the MCP server process environment unless you override it in your command wrapper
308
+
309
+ There are also **no package-level config files or config options** beyond the per-session options above.
310
+
311
+ ## Testing
312
+
313
+ Interactive fixtures live under `packages/terminal-pilot/src/testing/`:
314
+
315
+ - `test-cli.ts` - prompt + text entry fixture
316
+ - `menu-cli.ts` - arrow-key menu fixture
317
+ - `fixtures.test.ts` - examples of driving both fixtures
318
+
319
+ Run just the fixture tests:
320
+
321
+ ```sh
322
+ npx vitest run packages/terminal-pilot/src/testing/fixtures.test.ts
323
+ ```
324
+
325
+ Run the whole package test suite:
326
+
327
+ ```sh
328
+ npx vitest run packages/terminal-pilot/src
329
+ ```
330
+
331
+ Typical fixture workflow:
332
+
333
+ 1. Spawn the fixture in a `TerminalSession`
334
+ 2. `waitFor(...)` the prompt
335
+ 3. `type(...)`, `fill(...)`, `press(...)`, or `signal(...)`
336
+ 4. Assert with `screen()` or `history()`
337
+ 5. `close()` the session
338
+
339
+ Example fixture-based test:
340
+
341
+ ```ts
342
+ import path from "node:path";
343
+ import { TerminalPilot } from "@poe-code/terminal-pilot";
344
+
345
+ const pilot = await TerminalPilot.launch();
346
+ const tsxPath = path.join(process.cwd(), "node_modules", ".bin", "tsx");
347
+ const fixturePath = path.join(process.cwd(), "packages/terminal-pilot/src/testing/menu-cli.ts");
348
+
349
+ try {
350
+ const session = await pilot.newSession({
351
+ command: tsxPath,
352
+ args: [fixturePath]
353
+ });
354
+
355
+ await session.waitFor("Select an option:");
356
+ await session.press("ArrowDown");
357
+ await session.press("ArrowDown");
358
+ await session.press("Enter");
359
+
360
+ await session.waitFor("You selected: Option 3");
361
+ } finally {
362
+ await pilot.close();
363
+ }
364
+ ```
365
+
366
+ ## Example: test `poe-code configure`
367
+
368
+ Use a temporary home directory so you do not touch your real config while testing the interactive flow.
369
+
370
+ ```ts
371
+ import { mkdtempSync, rmSync } from "node:fs";
372
+ import os from "node:os";
373
+ import path from "node:path";
374
+ import { TerminalPilot } from "@poe-code/terminal-pilot";
375
+
376
+ const tmpHome = mkdtempSync(path.join(os.tmpdir(), "poe-configure-test-"));
377
+ const pilot = await TerminalPilot.launch();
378
+
379
+ try {
380
+ const session = await pilot.newSession({
381
+ command: "npm",
382
+ args: ["run", "dev", "--silent", "--", "configure"],
383
+ cwd: process.cwd(),
384
+ env: {
385
+ ...process.env,
386
+ HOME: tmpHome,
387
+ XDG_CONFIG_HOME: path.join(tmpHome, ".config"),
388
+ XDG_DATA_HOME: path.join(tmpHome, ".local", "share")
389
+ },
390
+ cols: 120,
391
+ rows: 40
392
+ });
393
+
394
+ await session.waitFor(/Pick an agent to configure:/);
395
+ await session.press("ArrowDown"); // choose Codex, Kimi, etc.
396
+ await session.press("Enter");
397
+
398
+ await session.waitFor(/Waiting for authorization|default model|configured/i, {
399
+ timeout: 15000
400
+ });
401
+
402
+ const screen = await session.screen();
403
+ const history = await session.history({ last: 40 });
404
+
405
+ console.log(screen.text);
406
+ console.log(history.join("\n"));
407
+
408
+ await session.signal("SIGINT");
409
+ await session.close();
410
+ } finally {
411
+ await pilot.close();
412
+ rmSync(tmpHome, { recursive: true, force: true });
413
+ }
414
+ ```
415
+
416
+ That gives you a real end-to-end test of the interactive `configure` handoff. If the selected provider requires OAuth or API-key input, keep the temp environment and continue the flow with additional `type(...)`, `press(...)`, and `waitFor(...)` calls.
package/dist/ansi.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare function stripAnsi(input: string): string;
package/dist/ansi.js ADDED
@@ -0,0 +1,71 @@
1
+ const ESC = 0x1b;
2
+ const BEL = 0x07;
3
+ const ST = 0x9c;
4
+ const CSI = 0x9b;
5
+ const OSC = 0x9d;
6
+ const DCS = 0x90;
7
+ const SOS = 0x98;
8
+ const PM = 0x9e;
9
+ const APC = 0x9f;
10
+ export function stripAnsi(input) {
11
+ let output = "";
12
+ for (let index = 0; index < input.length; index += 1) {
13
+ const code = input.charCodeAt(index);
14
+ if (code === ESC) {
15
+ const nextCode = input.charCodeAt(index + 1);
16
+ if (nextCode === 0x5b) {
17
+ index = consumeCsi(input, index + 2);
18
+ continue;
19
+ }
20
+ if (nextCode === 0x5d) {
21
+ index = consumeTerminatedString(input, index + 2, true);
22
+ continue;
23
+ }
24
+ if (nextCode === 0x50 || nextCode === 0x58 || nextCode === 0x5e || nextCode === 0x5f) {
25
+ index = consumeTerminatedString(input, index + 2, false);
26
+ continue;
27
+ }
28
+ if (!Number.isNaN(nextCode)) {
29
+ index += 1;
30
+ }
31
+ continue;
32
+ }
33
+ if (code === CSI) {
34
+ index = consumeCsi(input, index + 1);
35
+ continue;
36
+ }
37
+ if (code === OSC) {
38
+ index = consumeTerminatedString(input, index + 1, true);
39
+ continue;
40
+ }
41
+ if (code === DCS || code === SOS || code === PM || code === APC) {
42
+ index = consumeTerminatedString(input, index + 1, false);
43
+ continue;
44
+ }
45
+ output += input[index];
46
+ }
47
+ return output;
48
+ }
49
+ function consumeCsi(input, index) {
50
+ while (index < input.length) {
51
+ const code = input.charCodeAt(index);
52
+ if (code >= 0x40 && code <= 0x7e) {
53
+ return index;
54
+ }
55
+ index += 1;
56
+ }
57
+ return input.length;
58
+ }
59
+ function consumeTerminatedString(input, index, allowBellTerminator) {
60
+ while (index < input.length) {
61
+ const code = input.charCodeAt(index);
62
+ if (code === ST || (allowBellTerminator && code === BEL)) {
63
+ return index;
64
+ }
65
+ if (code === ESC && input.charCodeAt(index + 1) === 0x5c) {
66
+ return index + 1;
67
+ }
68
+ index += 1;
69
+ }
70
+ return input.length;
71
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ export { stripAnsi } from "./ansi.js";
2
+ export { keyToSequence, type TerminalKey } from "./keys.js";
3
+ export { TerminalScreen } from "./terminal-screen.js";
4
+ export { TerminalSession, type HistoryOptions, type WaitForOptions } from "./terminal-session.js";
5
+ export { TerminalPilot, type NewSessionOptions } from "./terminal-pilot.js";
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { stripAnsi } from "./ansi.js";
2
+ export { keyToSequence } from "./keys.js";
3
+ export { TerminalScreen } from "./terminal-screen.js";
4
+ export { TerminalSession } from "./terminal-session.js";
5
+ export { TerminalPilot } from "./terminal-pilot.js";
package/dist/keys.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export type TerminalKey = "Enter" | "Tab" | "Escape" | "Backspace" | "Delete" | "ArrowUp" | "ArrowDown" | "ArrowLeft" | "ArrowRight" | "Home" | "End" | "PageUp" | "PageDown" | "Space" | `Control+${string}` | `Alt+${string}`;
2
+ export declare function keyToSequence(key: TerminalKey): string;
package/dist/keys.js ADDED
@@ -0,0 +1,53 @@
1
+ const NAMED_KEY_SEQUENCES = {
2
+ Enter: "\r",
3
+ Tab: "\t",
4
+ Escape: "\x1b",
5
+ Backspace: "\x7f",
6
+ Delete: "\x1b[3~",
7
+ ArrowUp: "\x1b[A",
8
+ ArrowDown: "\x1b[B",
9
+ ArrowRight: "\x1b[C",
10
+ ArrowLeft: "\x1b[D",
11
+ Home: "\x1b[H",
12
+ End: "\x1b[F",
13
+ PageUp: "\x1b[5~",
14
+ PageDown: "\x1b[6~",
15
+ Space: " "
16
+ };
17
+ export function keyToSequence(key) {
18
+ const namedSequence = NAMED_KEY_SEQUENCES[key];
19
+ if (namedSequence !== undefined) {
20
+ return namedSequence;
21
+ }
22
+ if (key.startsWith("Control+")) {
23
+ return controlKeyToSequence(key);
24
+ }
25
+ if (key.startsWith("Alt+")) {
26
+ const nestedKey = key.slice("Alt+".length);
27
+ if (nestedKey.length === 0) {
28
+ throw new Error(`Unknown terminal key: ${key}`);
29
+ }
30
+ if (nestedKey.length === 1) {
31
+ return "\x1b" + nestedKey;
32
+ }
33
+ try {
34
+ return "\x1b" + keyToSequence(nestedKey);
35
+ }
36
+ catch {
37
+ throw new Error(`Unknown terminal key: ${key}`);
38
+ }
39
+ }
40
+ throw new Error(`Unknown terminal key: ${key}`);
41
+ }
42
+ function controlKeyToSequence(key) {
43
+ const controlKey = key.slice("Control+".length);
44
+ if (controlKey.length !== 1) {
45
+ throw new Error(`Unknown terminal key: ${key}`);
46
+ }
47
+ const uppercaseLetter = controlKey.toUpperCase();
48
+ const charCode = uppercaseLetter.charCodeAt(0);
49
+ if (charCode < 65 || charCode > 90) {
50
+ throw new Error(`Unknown terminal key: ${key}`);
51
+ }
52
+ return String.fromCharCode(charCode - 64);
53
+ }
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import { type Server } from "tiny-stdio-mcp-server";
3
+ import { TerminalPilot } from "./terminal-pilot.js";
4
+ type RuntimeProcess = Pick<typeof process, "on" | "off">;
5
+ export declare function createTerminalPilotMcpServer(agent: TerminalPilot): Server;
6
+ export declare function main({ launchAgent, createMcpServer, runtimeProcess }?: {
7
+ launchAgent?: typeof TerminalPilot.launch;
8
+ createMcpServer?: (agent: TerminalPilot) => Server;
9
+ runtimeProcess?: RuntimeProcess;
10
+ }): Promise<void>;
11
+ export {};
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+ import packageJson from "../package.json" with { type: "json" };
3
+ import { createServer } from "tiny-stdio-mcp-server";
4
+ import { terminalPilotMcpTools } from "./mcp-tools.js";
5
+ import { TerminalPilot } from "./terminal-pilot.js";
6
+ export function createTerminalPilotMcpServer(agent) {
7
+ const server = createServer({
8
+ name: "terminal-pilot",
9
+ version: packageJson.version
10
+ });
11
+ for (const tool of terminalPilotMcpTools(agent)) {
12
+ server.tool(tool.name, tool.description, tool.inputSchema, tool.handler);
13
+ }
14
+ return server;
15
+ }
16
+ export async function main({ launchAgent = TerminalPilot.launch, createMcpServer = createTerminalPilotMcpServer, runtimeProcess = process } = {}) {
17
+ const agent = await launchAgent();
18
+ let closed = false;
19
+ const closeAgent = async () => {
20
+ if (closed) {
21
+ return;
22
+ }
23
+ closed = true;
24
+ await agent.close();
25
+ };
26
+ const handleExit = () => {
27
+ void closeAgent();
28
+ };
29
+ runtimeProcess.on("exit", handleExit);
30
+ try {
31
+ await createMcpServer(agent).listen();
32
+ }
33
+ finally {
34
+ runtimeProcess.off("exit", handleExit);
35
+ await closeAgent();
36
+ }
37
+ }
38
+ if (import.meta.url === `file://${process.argv[1]}`) {
39
+ void main();
40
+ }
@@ -0,0 +1,46 @@
1
+ import { type ToolDefinition } from "tiny-stdio-mcp-server";
2
+ import type { TerminalKey } from "./keys.js";
3
+ import type { TerminalPilot } from "./terminal-pilot.js";
4
+ export type TerminalPilotMcpTool<T = Record<string, unknown>> = ToolDefinition<T>;
5
+ export declare function terminalCreateSessionTool(agent: TerminalPilot): TerminalPilotMcpTool<{
6
+ command: string;
7
+ args?: string[];
8
+ cwd?: string;
9
+ cols?: number;
10
+ rows?: number;
11
+ observe?: boolean;
12
+ }>;
13
+ export declare function terminalTypeTool(agent: TerminalPilot): TerminalPilotMcpTool<{
14
+ sessionId: string;
15
+ text: string;
16
+ }>;
17
+ export declare function terminalPressKeyTool(agent: TerminalPilot): TerminalPilotMcpTool<{
18
+ sessionId: string;
19
+ key: TerminalKey;
20
+ }>;
21
+ export declare function terminalSendSignalTool(agent: TerminalPilot): TerminalPilotMcpTool<{
22
+ sessionId: string;
23
+ signal: string;
24
+ }>;
25
+ export declare function terminalWaitForTool(agent: TerminalPilot): TerminalPilotMcpTool<{
26
+ sessionId: string;
27
+ pattern: string;
28
+ timeout?: number;
29
+ }>;
30
+ export declare function terminalReadScreenTool(agent: TerminalPilot): TerminalPilotMcpTool<{
31
+ sessionId: string;
32
+ }>;
33
+ export declare function terminalReadHistoryTool(agent: TerminalPilot): TerminalPilotMcpTool<{
34
+ sessionId: string;
35
+ last?: number;
36
+ }>;
37
+ export declare function terminalResizeTool(agent: TerminalPilot): TerminalPilotMcpTool<{
38
+ sessionId: string;
39
+ cols: number;
40
+ rows: number;
41
+ }>;
42
+ export declare function terminalCloseSessionTool(agent: TerminalPilot): TerminalPilotMcpTool<{
43
+ sessionId: string;
44
+ }>;
45
+ export declare function terminalPilotMcpTools(agent: TerminalPilot): Array<TerminalPilotMcpTool<any>>;
46
+ export declare function terminalListSessionsTool(agent: TerminalPilot): TerminalPilotMcpTool<Record<string, never>>;