weztermcp 0.1.0 → 0.1.2
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 +11 -3
- package/build/exec_async.js +4 -0
- package/build/exec_async.js.map +1 -0
- package/build/index.js +53 -12
- package/build/index.js.map +1 -1
- package/build/send_control_character.js +16 -18
- package/build/send_control_character.js.map +1 -1
- package/build/wezterm_check.js +2 -4
- package/build/wezterm_check.js.map +1 -1
- package/build/wezterm_executor.js +109 -23
- package/build/wezterm_executor.js.map +1 -1
- package/build/wezterm_output_reader.js +6 -44
- package/build/wezterm_output_reader.js.map +1 -1
- package/package.json +1 -2
- package/build/index.d.ts +0 -3
- package/build/index.d.ts.map +0 -1
- package/build/send_control_character.d.ts +0 -8
- package/build/send_control_character.d.ts.map +0 -1
- package/build/wezterm_check.d.ts +0 -6
- package/build/wezterm_check.d.ts.map +0 -1
- package/build/wezterm_executor.d.ts +0 -20
- package/build/wezterm_executor.d.ts.map +0 -1
- package/build/wezterm_output_reader.d.ts +0 -11
- package/build/wezterm_output_reader.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -10,12 +10,20 @@ It allows you to control WezTerm from Claude Desktop and other MCP clients.
|
|
|
10
10
|
| Tool | Required Args | Optional Args | Description |
|
|
11
11
|
|---|---|---|---|
|
|
12
12
|
| `wezterm_pane_write` | `command: string`, `pane_id: number` | — | Writes text or runs a command in the specified pane |
|
|
13
|
-
| `wezterm_pane_read` |
|
|
13
|
+
| `wezterm_pane_read` | `pane_id: number` | `lines: number` (default 50) | Reads output from a pane's scrollback buffer |
|
|
14
14
|
| `wezterm_pane_send_key` | `character: string`, `pane_id: number` | — | Sends a control character to the specified pane (e.g. `"c"` for Ctrl+C) |
|
|
15
|
-
| `wezterm_pane_list` | — |
|
|
15
|
+
| `wezterm_pane_list` | — | `window_id: number`, `tab_id: number` | Lists panes, scoped to the active window/tab by default |
|
|
16
16
|
| `wezterm_pane_switch` | `pane_id: number` | — | Switches focus to the specified pane |
|
|
17
17
|
| `wezterm_pane_close` | `pane_id: number` | — | Closes the specified pane |
|
|
18
|
-
| `wezterm_pane_split` | `
|
|
18
|
+
| `wezterm_pane_split` | `direction: "Right"\|"Left"\|"Top"\|"Bottom"` | `pane_id: number`, `window_id: number`, `tab_id: number` | Splits a pane and returns the new pane ID |
|
|
19
|
+
|
|
20
|
+
## Multi-window and multi-tab support
|
|
21
|
+
|
|
22
|
+
`pane_id` is globally unique across all of WezTerm's windows and tabs, so most tools (`wezterm_pane_write`, `wezterm_pane_read`, `wezterm_pane_send_key`, `wezterm_pane_switch`, `wezterm_pane_close`) don't need window/tab scoping — they just target the pane directly.
|
|
23
|
+
|
|
24
|
+
`wezterm_pane_list` and `wezterm_pane_split` are the exceptions, since they need to know *which* window/tab to operate on when a specific pane isn't given:
|
|
25
|
+
- `wezterm_pane_list` defaults to listing only the panes in the currently focused window and tab. Pass `window_id` and/or `tab_id` to list panes elsewhere.
|
|
26
|
+
- `wezterm_pane_split` defaults to splitting the currently focused pane. If `pane_id` is omitted, pass `window_id`/`tab_id` to split the focused pane within that window/tab instead.
|
|
19
27
|
|
|
20
28
|
## Security
|
|
21
29
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec_async.js","sourceRoot":"","sources":["../src/exec_async.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEjC,MAAM,CAAC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC"}
|
package/build/index.js
CHANGED
|
@@ -7,12 +7,22 @@ import WeztermOutputReader from "./wezterm_output_reader.js";
|
|
|
7
7
|
import SendControlCharacter from "./send_control_character.js";
|
|
8
8
|
const server = new Server({
|
|
9
9
|
name: "weztermcp",
|
|
10
|
-
|
|
10
|
+
title: "WezTerm MCP Server",
|
|
11
|
+
version: "0.1.2",
|
|
12
|
+
description: "Control WezTerm panes, tabs, and windows from an MCP client via the WezTerm CLI.",
|
|
13
|
+
websiteUrl: "https://github.com/ajmarkow/weztermcp",
|
|
11
14
|
}, {
|
|
12
15
|
capabilities: {
|
|
13
16
|
tools: {},
|
|
14
17
|
},
|
|
18
|
+
instructions: "wezterm_pane_write does not return command output — follow it with wezterm_pane_read to see results. " +
|
|
19
|
+
"For a long-running command, wezterm_pane_read is a snapshot, not a wait — call it again after some time to check progress rather than assuming one read captures the final output. " +
|
|
20
|
+
"Call wezterm_pane_list first to discover valid pane_id values before targeting a pane with any other tool. " +
|
|
21
|
+
"wezterm_pane_close is destructive and irreversible; confirm with the user before closing a pane.",
|
|
15
22
|
});
|
|
23
|
+
const executor = new WeztermExecutor();
|
|
24
|
+
const outputReader = new WeztermOutputReader();
|
|
25
|
+
const controlCharSender = new SendControlCharacter();
|
|
16
26
|
// Tool definitions
|
|
17
27
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
18
28
|
return {
|
|
@@ -49,9 +59,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
49
59
|
},
|
|
50
60
|
pane_id: {
|
|
51
61
|
type: "number",
|
|
52
|
-
description: "Integer ID of the pane to read from.
|
|
62
|
+
description: "Integer ID of the pane to read from. Obtain valid IDs from wezterm_pane_list.",
|
|
53
63
|
},
|
|
54
64
|
},
|
|
65
|
+
required: ["pane_id"],
|
|
55
66
|
},
|
|
56
67
|
},
|
|
57
68
|
{
|
|
@@ -76,10 +87,19 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
76
87
|
{
|
|
77
88
|
name: "wezterm_pane_list",
|
|
78
89
|
title: "List WezTerm Panes",
|
|
79
|
-
description: "EXECUTION TOOL. Enumerates
|
|
90
|
+
description: "EXECUTION TOOL. Enumerates open panes, returning pane IDs, window/tab IDs, and titles. WHEN: 'what panes are open', 'show pane list', 'which pane is active', 'find pane ID'. Default (no window_id/tab_id): scoped to the currently active/focused window and tab only, not every pane across every window. Pass window_id and/or tab_id to list panes elsewhere. Does NOT switch focus or read pane content. Use returned pane_id values with other tools. Example: call before wezterm_pane_write to discover the target pane_id.",
|
|
80
91
|
inputSchema: {
|
|
81
92
|
type: "object",
|
|
82
|
-
properties: {
|
|
93
|
+
properties: {
|
|
94
|
+
window_id: {
|
|
95
|
+
type: "number",
|
|
96
|
+
description: "Integer ID of the window to scope the listing to. Default: the window containing the currently focused pane. Combine with wezterm_pane_list (no args) to discover window_id values.",
|
|
97
|
+
},
|
|
98
|
+
tab_id: {
|
|
99
|
+
type: "number",
|
|
100
|
+
description: "Integer ID of the tab to scope the listing to. Default: the tab containing the currently focused pane. Combine with wezterm_pane_list (no args) to discover tab_id values.",
|
|
101
|
+
},
|
|
102
|
+
},
|
|
83
103
|
},
|
|
84
104
|
},
|
|
85
105
|
{
|
|
@@ -121,7 +141,15 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
121
141
|
properties: {
|
|
122
142
|
pane_id: {
|
|
123
143
|
type: "number",
|
|
124
|
-
description: "Integer ID of the pane to split. Obtain valid IDs from wezterm_pane_list. The existing pane retains its content; the new pane opens a fresh shell.",
|
|
144
|
+
description: "Integer ID of the pane to split. Obtain valid IDs from wezterm_pane_list. The existing pane retains its content; the new pane opens a fresh shell. Default: the currently focused pane, optionally narrowed by window_id/tab_id.",
|
|
145
|
+
},
|
|
146
|
+
window_id: {
|
|
147
|
+
type: "number",
|
|
148
|
+
description: "Only used when pane_id is omitted. Scopes which window's focused pane is split. Default: the window containing the currently focused pane.",
|
|
149
|
+
},
|
|
150
|
+
tab_id: {
|
|
151
|
+
type: "number",
|
|
152
|
+
description: "Only used when pane_id is omitted. Scopes which tab's focused pane is split. Default: the tab containing the currently focused pane.",
|
|
125
153
|
},
|
|
126
154
|
direction: {
|
|
127
155
|
type: "string",
|
|
@@ -129,7 +157,21 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
129
157
|
description: "Direction in which to create the new pane relative to the existing one. 'Right' and 'Left' split vertically (side by side); 'Top' and 'Bottom' split horizontally (stacked). Must be exactly one of: Right, Left, Top, Bottom (case-sensitive).",
|
|
130
158
|
},
|
|
131
159
|
},
|
|
132
|
-
required: ["
|
|
160
|
+
required: ["direction"],
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: "wezterm_window_spawn",
|
|
165
|
+
title: "Spawn WezTerm Window",
|
|
166
|
+
description: "EXECUTION TOOL. Opens a brand new WezTerm window with a fresh shell, using `wezterm cli spawn --new-window`. WHEN: 'open a new window', 'spawn a window', 'create a separate WezTerm window'. Panes are the primary entity for most work — prefer wezterm_pane_split for a new pane within the current window/tab. Use this only when a genuinely separate top-level window is needed. Returns the new pane's ID (the initial pane of the new window) — store it to target subsequent commands. Example: spawn a new window, then wezterm_pane_write to the returned pane ID.",
|
|
167
|
+
inputSchema: {
|
|
168
|
+
type: "object",
|
|
169
|
+
properties: {
|
|
170
|
+
cwd: {
|
|
171
|
+
type: "string",
|
|
172
|
+
description: "Absolute path to start the new window's shell in. Default: WezTerm's default working directory (typically the user's home directory or the directory of the currently focused pane, depending on configuration).",
|
|
173
|
+
},
|
|
174
|
+
},
|
|
133
175
|
},
|
|
134
176
|
},
|
|
135
177
|
],
|
|
@@ -137,26 +179,25 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
137
179
|
});
|
|
138
180
|
// Tool execution
|
|
139
181
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
140
|
-
const executor = new WeztermExecutor();
|
|
141
|
-
const outputReader = new WeztermOutputReader();
|
|
142
|
-
const controlCharSender = new SendControlCharacter();
|
|
143
182
|
switch (request.params.name) {
|
|
144
183
|
case "wezterm_pane_write":
|
|
145
184
|
return await executor.writeToTerminal(request.params.arguments.command, request.params.arguments.pane_id);
|
|
146
185
|
case "wezterm_pane_read":
|
|
147
186
|
const lines = request.params.arguments.lines || 50;
|
|
148
187
|
const paneId = request.params.arguments.pane_id;
|
|
149
|
-
return await outputReader.readOutput(
|
|
188
|
+
return await outputReader.readOutput(paneId, lines);
|
|
150
189
|
case "wezterm_pane_send_key":
|
|
151
190
|
return await controlCharSender.send(request.params.arguments.character, request.params.arguments.pane_id);
|
|
152
191
|
case "wezterm_pane_list":
|
|
153
|
-
return await executor.listPanes();
|
|
192
|
+
return await executor.listPanes(request.params.arguments.window_id, request.params.arguments.tab_id);
|
|
154
193
|
case "wezterm_pane_switch":
|
|
155
194
|
return await executor.switchPane(request.params.arguments.pane_id);
|
|
156
195
|
case "wezterm_pane_close":
|
|
157
196
|
return await executor.closePane(request.params.arguments.pane_id);
|
|
158
197
|
case "wezterm_pane_split":
|
|
159
|
-
return await executor.splitPane(request.params.arguments.pane_id, request.params.arguments.direction);
|
|
198
|
+
return await executor.splitPane(request.params.arguments.pane_id, request.params.arguments.direction, request.params.arguments.window_id, request.params.arguments.tab_id);
|
|
199
|
+
case "wezterm_window_spawn":
|
|
200
|
+
return await executor.spawnWindow(request.params.arguments?.cwd);
|
|
160
201
|
default:
|
|
161
202
|
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
162
203
|
}
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,eAAe,MAAM,uBAAuB,CAAC;AACpD,OAAO,mBAAmB,MAAM,4BAA4B,CAAC;AAC7D,OAAO,oBAAoB,MAAM,6BAA6B,CAAC;AAE/D,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;IACE,IAAI,EAAE,WAAW;IACjB,OAAO,EAAE,OAAO;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,34 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { promisify } from "util";
|
|
1
|
+
import { execFileAsync } from "./exec_async.js";
|
|
3
2
|
import { assertWeztermInstalled, notInstalledResult } from "./wezterm_check.js";
|
|
4
|
-
const execAsync = promisify(exec);
|
|
5
3
|
export default class SendControlCharacter {
|
|
6
|
-
weztermCli;
|
|
7
|
-
constructor() {
|
|
8
|
-
this.weztermCli = "wezterm cli";
|
|
9
|
-
}
|
|
10
4
|
async send(character, paneId) {
|
|
11
5
|
const err = await assertWeztermInstalled();
|
|
12
6
|
if (err)
|
|
13
7
|
return notInstalledResult();
|
|
14
8
|
try {
|
|
15
9
|
const controlMap = {
|
|
16
|
-
c: "
|
|
17
|
-
d: "
|
|
18
|
-
z: "
|
|
19
|
-
l: "
|
|
20
|
-
a: "
|
|
21
|
-
e: "
|
|
22
|
-
k: "
|
|
23
|
-
u: "
|
|
24
|
-
w: "
|
|
10
|
+
c: "\x03", // Ctrl+C
|
|
11
|
+
d: "\x04", // Ctrl+D
|
|
12
|
+
z: "\x1a", // Ctrl+Z
|
|
13
|
+
l: "\x0c", // Ctrl+L
|
|
14
|
+
a: "\x01", // Ctrl+A
|
|
15
|
+
e: "\x05", // Ctrl+E
|
|
16
|
+
k: "\x0b", // Ctrl+K
|
|
17
|
+
u: "\x15", // Ctrl+U
|
|
18
|
+
w: "\x17", // Ctrl+W
|
|
25
19
|
};
|
|
26
20
|
const controlSeq = controlMap[character.toLowerCase()];
|
|
27
21
|
if (!controlSeq) {
|
|
28
22
|
throw new Error(`Unknown control character: ${character}`);
|
|
29
23
|
}
|
|
30
|
-
const
|
|
31
|
-
|
|
24
|
+
const args = ["cli", "send-text"];
|
|
25
|
+
if (paneId !== undefined) {
|
|
26
|
+
args.push("--pane-id", String(paneId));
|
|
27
|
+
}
|
|
28
|
+
args.push(controlSeq);
|
|
29
|
+
await execFileAsync("wezterm", args);
|
|
32
30
|
return {
|
|
33
31
|
content: [
|
|
34
32
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send_control_character.js","sourceRoot":"","sources":["../src/send_control_character.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"send_control_character.js","sourceRoot":"","sources":["../src/send_control_character.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAEhF,MAAM,CAAC,OAAO,OAAO,oBAAoB;IACvC,KAAK,CAAC,IAAI,CAAC,SAAiB,EAAE,MAAe;QAC3C,MAAM,GAAG,GAAG,MAAM,sBAAsB,EAAE,CAAC;QAC3C,IAAI,GAAG;YAAE,OAAO,kBAAkB,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,UAAU,GAA8B;gBAC5C,CAAC,EAAE,MAAM,EAAE,SAAS;gBACpB,CAAC,EAAE,MAAM,EAAE,SAAS;gBACpB,CAAC,EAAE,MAAM,EAAE,SAAS;gBACpB,CAAC,EAAE,MAAM,EAAE,SAAS;gBACpB,CAAC,EAAE,MAAM,EAAE,SAAS;gBACpB,CAAC,EAAE,MAAM,EAAE,SAAS;gBACpB,CAAC,EAAE,MAAM,EAAE,SAAS;gBACpB,CAAC,EAAE,MAAM,EAAE,SAAS;gBACpB,CAAC,EAAE,MAAM,EAAE,SAAS;aACrB,CAAC;YAEF,MAAM,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;YACvD,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,MAAM,IAAI,KAAK,CAAC,8BAA8B,SAAS,EAAE,CAAC,CAAC;YAC7D,CAAC;YAED,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YAClC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;YACzC,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAEtB,MAAM,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAErC,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,gCAAgC,SAAS,CAAC,WAAW,EAAE,EAAE;qBAChE;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,qCAAqC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;CACF"}
|
package/build/wezterm_check.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { promisify } from "util";
|
|
3
|
-
const execAsync = promisify(exec);
|
|
1
|
+
import { execFileAsync } from "./exec_async.js";
|
|
4
2
|
export const NOT_INSTALLED_MSG = "WezTerm is not installed or not on PATH. Install it from https://wezfurlong.org/wezterm/ and ensure 'wezterm' is accessible.";
|
|
5
3
|
export async function assertWeztermInstalled() {
|
|
6
4
|
try {
|
|
7
|
-
const { stdout } = await
|
|
5
|
+
const { stdout } = await execFileAsync("wezterm", ["--version"]);
|
|
8
6
|
if (!stdout.trim()) {
|
|
9
7
|
return NOT_INSTALLED_MSG;
|
|
10
8
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wezterm_check.js","sourceRoot":"","sources":["../src/wezterm_check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"wezterm_check.js","sourceRoot":"","sources":["../src/wezterm_check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,CAAC,MAAM,iBAAiB,GAC5B,8HAA8H,CAAC;AAEjI,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,SAAS,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;QACjE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YACnB,OAAO,iBAAiB,CAAC;QAC3B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,iBAAiB,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC;AAClE,CAAC"}
|
|
@@ -1,19 +1,50 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { promisify } from "util";
|
|
1
|
+
import { execFileAsync } from "./exec_async.js";
|
|
3
2
|
import { assertWeztermInstalled, notInstalledResult } from "./wezterm_check.js";
|
|
4
|
-
const execAsync = promisify(exec);
|
|
5
3
|
export default class WeztermExecutor {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
async listAllPanes() {
|
|
5
|
+
const { stdout } = await execFileAsync("wezterm", ["cli", "list", "--format", "json"]);
|
|
6
|
+
return JSON.parse(stdout);
|
|
7
|
+
}
|
|
8
|
+
async getFocusedPaneId() {
|
|
9
|
+
const { stdout } = await execFileAsync("wezterm", [
|
|
10
|
+
"cli",
|
|
11
|
+
"list-clients",
|
|
12
|
+
"--format",
|
|
13
|
+
"json",
|
|
14
|
+
]);
|
|
15
|
+
const clients = JSON.parse(stdout);
|
|
16
|
+
return clients[0]?.focused_pane_id;
|
|
17
|
+
}
|
|
18
|
+
async getFocusedPane(panes) {
|
|
19
|
+
const focusedPaneId = await this.getFocusedPaneId();
|
|
20
|
+
return panes.find((p) => p.pane_id === focusedPaneId);
|
|
21
|
+
}
|
|
22
|
+
async resolveTargetPaneId(windowId, tabId) {
|
|
23
|
+
if (windowId === undefined && tabId === undefined) {
|
|
24
|
+
return this.getFocusedPaneId();
|
|
25
|
+
}
|
|
26
|
+
const panes = await this.listAllPanes();
|
|
27
|
+
const focusedPane = await this.getFocusedPane(panes);
|
|
28
|
+
const inScope = (p) => (windowId === undefined || p.window_id === windowId) &&
|
|
29
|
+
(tabId === undefined || p.tab_id === tabId);
|
|
30
|
+
if (focusedPane && inScope(focusedPane)) {
|
|
31
|
+
return focusedPane.pane_id;
|
|
32
|
+
}
|
|
33
|
+
return panes.find(inScope)?.pane_id;
|
|
9
34
|
}
|
|
10
35
|
async writeToTerminal(command, paneId) {
|
|
11
36
|
const err = await assertWeztermInstalled();
|
|
12
37
|
if (err)
|
|
13
38
|
return notInstalledResult();
|
|
14
39
|
try {
|
|
15
|
-
|
|
16
|
-
|
|
40
|
+
await execFileAsync("wezterm", [
|
|
41
|
+
"cli",
|
|
42
|
+
"send-text",
|
|
43
|
+
"--pane-id",
|
|
44
|
+
String(paneId),
|
|
45
|
+
"--no-paste",
|
|
46
|
+
`${command}\n`,
|
|
47
|
+
]);
|
|
17
48
|
return {
|
|
18
49
|
content: [
|
|
19
50
|
{
|
|
@@ -34,20 +65,29 @@ export default class WeztermExecutor {
|
|
|
34
65
|
};
|
|
35
66
|
}
|
|
36
67
|
}
|
|
37
|
-
async listPanes() {
|
|
68
|
+
async listPanes(windowId, tabId) {
|
|
38
69
|
const err = await assertWeztermInstalled();
|
|
39
70
|
if (err)
|
|
40
71
|
return notInstalledResult();
|
|
41
72
|
try {
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
73
|
+
const panes = await this.listAllPanes();
|
|
74
|
+
let scopedWindowId = windowId;
|
|
75
|
+
let scopedTabId = tabId;
|
|
76
|
+
if (scopedWindowId === undefined && scopedTabId === undefined) {
|
|
77
|
+
const focusedPane = await this.getFocusedPane(panes);
|
|
78
|
+
if (focusedPane) {
|
|
79
|
+
scopedWindowId = focusedPane.window_id;
|
|
80
|
+
scopedTabId = focusedPane.tab_id;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const filtered = panes.filter((p) => (scopedWindowId === undefined || p.window_id === scopedWindowId) &&
|
|
84
|
+
(scopedTabId === undefined || p.tab_id === scopedTabId));
|
|
85
|
+
const text = filtered.length
|
|
86
|
+
? filtered
|
|
87
|
+
.map((p) => `pane_id=${p.pane_id} window_id=${p.window_id} tab_id=${p.tab_id} title="${p.title}"`)
|
|
88
|
+
.join("\n")
|
|
89
|
+
: "(no panes found)";
|
|
90
|
+
return { content: [{ type: "text", text }] };
|
|
51
91
|
}
|
|
52
92
|
catch (error) {
|
|
53
93
|
return {
|
|
@@ -65,7 +105,7 @@ export default class WeztermExecutor {
|
|
|
65
105
|
if (err)
|
|
66
106
|
return notInstalledResult();
|
|
67
107
|
try {
|
|
68
|
-
await
|
|
108
|
+
await execFileAsync("wezterm", ["cli", "activate-pane", "--pane-id", String(paneId)]);
|
|
69
109
|
return {
|
|
70
110
|
content: [
|
|
71
111
|
{
|
|
@@ -91,7 +131,7 @@ export default class WeztermExecutor {
|
|
|
91
131
|
if (err)
|
|
92
132
|
return notInstalledResult();
|
|
93
133
|
try {
|
|
94
|
-
await
|
|
134
|
+
await execFileAsync("wezterm", ["cli", "kill-pane", "--pane-id", String(paneId)]);
|
|
95
135
|
return {
|
|
96
136
|
content: [{ type: "text", text: `Closed pane ${paneId}` }],
|
|
97
137
|
};
|
|
@@ -102,18 +142,35 @@ export default class WeztermExecutor {
|
|
|
102
142
|
};
|
|
103
143
|
}
|
|
104
144
|
}
|
|
105
|
-
async splitPane(paneId, direction) {
|
|
145
|
+
async splitPane(paneId, direction, windowId, tabId) {
|
|
106
146
|
const err = await assertWeztermInstalled();
|
|
107
147
|
if (err)
|
|
108
148
|
return notInstalledResult();
|
|
109
149
|
const dirFlag = `--${direction.toLowerCase()}`;
|
|
110
150
|
try {
|
|
111
|
-
const
|
|
151
|
+
const targetPaneId = paneId !== undefined ? paneId : await this.resolveTargetPaneId(windowId, tabId);
|
|
152
|
+
if (targetPaneId === undefined) {
|
|
153
|
+
return {
|
|
154
|
+
content: [
|
|
155
|
+
{
|
|
156
|
+
type: "text",
|
|
157
|
+
text: "Failed to split pane: could not resolve a target pane. Specify pane_id explicitly, or ensure a WezTerm window/tab is focused.",
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
const { stdout } = await execFileAsync("wezterm", [
|
|
163
|
+
"cli",
|
|
164
|
+
"split-pane",
|
|
165
|
+
"--pane-id",
|
|
166
|
+
String(targetPaneId),
|
|
167
|
+
dirFlag,
|
|
168
|
+
]);
|
|
112
169
|
return {
|
|
113
170
|
content: [
|
|
114
171
|
{
|
|
115
172
|
type: "text",
|
|
116
|
-
text: `Split pane ${
|
|
173
|
+
text: `Split pane ${targetPaneId} ${direction}. New pane id: ${stdout.trim()}`,
|
|
117
174
|
},
|
|
118
175
|
],
|
|
119
176
|
};
|
|
@@ -129,5 +186,34 @@ export default class WeztermExecutor {
|
|
|
129
186
|
};
|
|
130
187
|
}
|
|
131
188
|
}
|
|
189
|
+
async spawnWindow(cwd) {
|
|
190
|
+
const err = await assertWeztermInstalled();
|
|
191
|
+
if (err)
|
|
192
|
+
return notInstalledResult();
|
|
193
|
+
try {
|
|
194
|
+
const args = ["cli", "spawn", "--new-window"];
|
|
195
|
+
if (cwd)
|
|
196
|
+
args.push("--cwd", cwd);
|
|
197
|
+
const { stdout } = await execFileAsync("wezterm", args);
|
|
198
|
+
return {
|
|
199
|
+
content: [
|
|
200
|
+
{
|
|
201
|
+
type: "text",
|
|
202
|
+
text: `Spawned new window. New pane id: ${stdout.trim()}`,
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
return {
|
|
209
|
+
content: [
|
|
210
|
+
{
|
|
211
|
+
type: "text",
|
|
212
|
+
text: `Failed to spawn window: ${error.message}`,
|
|
213
|
+
},
|
|
214
|
+
],
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
}
|
|
132
218
|
}
|
|
133
219
|
//# sourceMappingURL=wezterm_executor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wezterm_executor.js","sourceRoot":"","sources":["../src/wezterm_executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"wezterm_executor.js","sourceRoot":"","sources":["../src/wezterm_executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,27 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { promisify } from "util";
|
|
1
|
+
import { execFileAsync } from "./exec_async.js";
|
|
3
2
|
import { assertWeztermInstalled, notInstalledResult } from "./wezterm_check.js";
|
|
4
|
-
const execAsync = promisify(exec);
|
|
5
3
|
export default class WeztermOutputReader {
|
|
6
|
-
|
|
7
|
-
constructor() {
|
|
8
|
-
this.weztermCli = "wezterm cli";
|
|
9
|
-
}
|
|
10
|
-
async readOutput(lines = 50, paneId) {
|
|
4
|
+
async readOutput(paneId, lines = 50) {
|
|
11
5
|
const err = await assertWeztermInstalled();
|
|
12
6
|
if (err)
|
|
13
7
|
return notInstalledResult();
|
|
14
8
|
try {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
command = `${this.weztermCli} get-text --escapes${paneOption}`;
|
|
19
|
-
}
|
|
20
|
-
else {
|
|
21
|
-
const startLine = -lines;
|
|
22
|
-
command = `${this.weztermCli} get-text --escapes --start-line ${startLine}${paneOption}`;
|
|
9
|
+
const args = ["cli", "get-text", "--escapes", "--pane-id", String(paneId)];
|
|
10
|
+
if (lines > 0) {
|
|
11
|
+
args.push("--start-line", String(-lines));
|
|
23
12
|
}
|
|
24
|
-
const { stdout } = await
|
|
13
|
+
const { stdout } = await execFileAsync("wezterm", args);
|
|
25
14
|
return {
|
|
26
15
|
content: [
|
|
27
16
|
{
|
|
@@ -42,32 +31,5 @@ export default class WeztermOutputReader {
|
|
|
42
31
|
};
|
|
43
32
|
}
|
|
44
33
|
}
|
|
45
|
-
async readCurrentScreen(paneId) {
|
|
46
|
-
const err = await assertWeztermInstalled();
|
|
47
|
-
if (err)
|
|
48
|
-
return notInstalledResult();
|
|
49
|
-
try {
|
|
50
|
-
const paneOption = paneId !== undefined ? ` --pane-id ${paneId}` : '';
|
|
51
|
-
const { stdout } = await execAsync(`${this.weztermCli} get-text --escapes${paneOption}`);
|
|
52
|
-
return {
|
|
53
|
-
content: [
|
|
54
|
-
{
|
|
55
|
-
type: "text",
|
|
56
|
-
text: stdout || "(empty output)",
|
|
57
|
-
},
|
|
58
|
-
],
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
catch (error) {
|
|
62
|
-
return {
|
|
63
|
-
content: [
|
|
64
|
-
{
|
|
65
|
-
type: "text",
|
|
66
|
-
text: `Failed to read current screen: ${error.message}`,
|
|
67
|
-
},
|
|
68
|
-
],
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
34
|
}
|
|
73
35
|
//# sourceMappingURL=wezterm_output_reader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wezterm_output_reader.js","sourceRoot":"","sources":["../src/wezterm_output_reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"wezterm_output_reader.js","sourceRoot":"","sources":["../src/wezterm_output_reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAEhF,MAAM,CAAC,OAAO,OAAO,mBAAmB;IACtC,KAAK,CAAC,UAAU,CAAC,MAAc,EAAE,QAAgB,EAAE;QACjD,MAAM,GAAG,GAAG,MAAM,sBAAsB,EAAE,CAAC;QAC3C,IAAI,GAAG;YAAE,OAAO,kBAAkB,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;YAC3E,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;gBACd,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YAC5C,CAAC;YAED,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAExD,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,MAAM,IAAI,gBAAgB;qBACjC;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,mCAAmC,KAAK,CAAC,OAAO,8FAA8F;qBACrJ;iBACF;aACF,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "weztermcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "mcp server for wezterm ",
|
|
5
5
|
"homepage": "https://github.com/ajmarkow/weztermcp#readme",
|
|
6
6
|
"repository": {
|
|
@@ -36,7 +36,6 @@
|
|
|
36
36
|
"@types/node": "^22.15.23",
|
|
37
37
|
"jest": "^29.7.0",
|
|
38
38
|
"ts-jest": "^29.4.11",
|
|
39
|
-
"ts-node": "^10.9.2",
|
|
40
39
|
"typescript": "^5.8.3"
|
|
41
40
|
}
|
|
42
41
|
}
|
package/build/index.d.ts
DELETED
package/build/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"send_control_character.d.ts","sourceRoot":"","sources":["../src/send_control_character.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,OAAO,OAAO,oBAAoB;IACvC,OAAO,CAAC,UAAU,CAAS;;IAMrB,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC;CAoC5E"}
|
package/build/wezterm_check.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export declare const NOT_INSTALLED_MSG = "WezTerm is not installed or not on PATH. Install it from https://wezfurlong.org/wezterm/ and ensure 'wezterm' is accessible.";
|
|
2
|
-
export declare function assertWeztermInstalled(): Promise<string | null>;
|
|
3
|
-
export declare function notInstalledResult(): {
|
|
4
|
-
content: any[];
|
|
5
|
-
};
|
|
6
|
-
//# sourceMappingURL=wezterm_check.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wezterm_check.d.ts","sourceRoot":"","sources":["../src/wezterm_check.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,iBAAiB,iIACkG,CAAC;AAEjI,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAUrE;AAED,wBAAgB,kBAAkB,IAAI;IAAE,OAAO,EAAE,GAAG,EAAE,CAAA;CAAE,CAEvD"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export default class WeztermExecutor {
|
|
2
|
-
private weztermCli;
|
|
3
|
-
constructor();
|
|
4
|
-
writeToTerminal(command: string, paneId: number): Promise<{
|
|
5
|
-
content: any[];
|
|
6
|
-
}>;
|
|
7
|
-
listPanes(): Promise<{
|
|
8
|
-
content: any[];
|
|
9
|
-
}>;
|
|
10
|
-
switchPane(paneId: number): Promise<{
|
|
11
|
-
content: any[];
|
|
12
|
-
}>;
|
|
13
|
-
closePane(paneId: number): Promise<{
|
|
14
|
-
content: any[];
|
|
15
|
-
}>;
|
|
16
|
-
splitPane(paneId: number, direction: "Right" | "Left" | "Top" | "Bottom"): Promise<{
|
|
17
|
-
content: any[];
|
|
18
|
-
}>;
|
|
19
|
-
}
|
|
20
|
-
//# sourceMappingURL=wezterm_executor.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wezterm_executor.d.ts","sourceRoot":"","sources":["../src/wezterm_executor.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,OAAO,OAAO,eAAe;IAClC,OAAO,CAAC,UAAU,CAAS;;IAMrB,eAAe,CACnB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC;IA4BxB,SAAS,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC;IAyBxC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC;IAyBvD,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC;IAetD,SAAS,CACb,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAC7C,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC;CA2B/B"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export default class WeztermOutputReader {
|
|
2
|
-
private weztermCli;
|
|
3
|
-
constructor();
|
|
4
|
-
readOutput(lines?: number, paneId?: number): Promise<{
|
|
5
|
-
content: any[];
|
|
6
|
-
}>;
|
|
7
|
-
readCurrentScreen(paneId?: number): Promise<{
|
|
8
|
-
content: any[];
|
|
9
|
-
}>;
|
|
10
|
-
}
|
|
11
|
-
//# sourceMappingURL=wezterm_output_reader.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wezterm_output_reader.d.ts","sourceRoot":"","sources":["../src/wezterm_output_reader.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,OAAO,OAAO,mBAAmB;IACtC,OAAO,CAAC,UAAU,CAAS;;IAMrB,UAAU,CAAC,KAAK,GAAE,MAAW,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC;IAoC5E,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC;CA4BtE"}
|