Skip to content

Commit c99ccbe

Browse files
fix(Mountain): Return integer id from localPty:createProcess
The VS Code terminal workbench expects `IPtyService.createProcess` to return a `Promise<number>` (the integer terminal id). However, Mountain was returning the full `{id, name, pid}` object. The workbench then keys its internal `_ptys` map by that object, so every `_ptys.get(<integer>)` lookup from `onProcessData`/`onProcessReady` returns `undefined`. This causes xterm to receive zero bytes even though Mountain's PTY reader emits data continuously—resulting in blank terminal panels. Split the terminal handler into three distinct paths: - `localPty:spawn`: Preserves full response for Cocoon's Sky bridge - `localPty:createProcess`: Returns only the integer id per VS Code contract - `localPty:start`: No-op for eager-spawn pattern (shell already started during createProcess) This fixes the terminal rendering while maintaining backward compatibility with existing spawn callers.
1 parent db5f0f7 commit c99ccbe

1 file changed

Lines changed: 48 additions & 1 deletion

File tree

  • Source/IPC/WindServiceHandlers

Source/IPC/WindServiceHandlers/mod.rs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1572,10 +1572,57 @@ pub async fn mountain_ipc_invoke(app_handle:AppHandle, command:String, args:Vec<
15721572
// Tauri-side `terminal:*` handlers so PTY lifecycle stays identical
15731573
// regardless of whether the request came from Sky (Wind) or from an
15741574
// extension (Cocoon → Wind channel bridge).
1575-
"localPty:spawn" | "localPty:createProcess" | "localPty:start" => {
1575+
//
1576+
// CONTRACT NOTE: `IPtyService.createProcess` is typed
1577+
// `Promise<number>` (see `vs/platform/terminal/common/terminal.ts:
1578+
// 316`). The workbench then does `new LocalPty(id, ...)` and
1579+
// `this._ptys.set(id, pty)`. If we return the full
1580+
// `{id,name,pid}` object the renderer keys `_ptys` by that
1581+
// object, every `_ptys.get(<integer>)` lookup from
1582+
// `onProcessData`/`onProcessReady` returns `undefined`, and
1583+
// xterm receives zero bytes - the terminal panel renders
1584+
// blank even though Mountain's PTY reader emits data
1585+
// continuously. Strip down to the integer id here.
1586+
"localPty:spawn" => {
1587+
// `localPty:spawn` is Cocoon's Sky bridge path; preserve
1588+
// the full `{id, name, pid}` shape because the older Wind
1589+
// callers expect it. New `localPty:createProcess` and
1590+
// `localPty:start` follow VS Code's typed contract below.
15761591
dev_log!("terminal", "{}", command);
15771592
handle_terminal_create(runtime.clone(), args).await
15781593
},
1594+
"localPty:createProcess" => {
1595+
dev_log!("terminal", "{}", command);
1596+
match handle_terminal_create(runtime.clone(), args).await {
1597+
Ok(Response) => {
1598+
// Extract the integer id - this is what
1599+
// `IPtyService.createProcess` is contractually
1600+
// required to return.
1601+
let TerminalId = Response
1602+
.get("id")
1603+
.and_then(serde_json::Value::as_u64)
1604+
.unwrap_or(0);
1605+
Ok(serde_json::json!(TerminalId))
1606+
},
1607+
Err(Error) => Err(Error),
1608+
}
1609+
},
1610+
"localPty:start" => {
1611+
// Eager-spawn pattern: `TerminalProvider::CreateTerminal`
1612+
// already started the shell and reader task during
1613+
// `localPty:createProcess`. `start` is a no-op that just
1614+
// completes the workbench's launch promise. Returning
1615+
// `Value::Null` matches `IPtyService.start`'s
1616+
// `Promise<ITerminalLaunchError | ITerminalLaunchResult |
1617+
// undefined>` (`undefined` branch). Routing this back
1618+
// through `handle_terminal_create` would spawn a SECOND
1619+
// PTY for the same workbench terminal - the user-visible
1620+
// pane is bound to id=1 from `createProcess`, but a
1621+
// shadow PTY (id=2) starts and streams data nobody
1622+
// renders.
1623+
dev_log!("terminal", "{} no-op (eager-spawn)", command);
1624+
Ok(Value::Null)
1625+
},
15791626
"localPty:input" | "localPty:write" => {
15801627
dev_log!("terminal", "{}", command);
15811628
handle_terminal_send_text(runtime.clone(), args).await

0 commit comments

Comments
 (0)