Repository navigation
Implement wtcli, an application to query details about an existing Terminal instance - #20461
PankajBhojwani wants to merge 23 commits into
Conversation
There was a problem hiding this comment.
check-spelling found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Leonard Hecker (lhecker)
left a comment
There was a problem hiding this comment.
BTW if we plan to just upstream this existing (?) code, I'm fine with just noting down some nits. Otherwise, I have some ideas how to improve it, like the STA/MTA thing.
|
|
||
| // Derive a per-install-path CLSID using the same v5 UUID formula as the server, | ||
| // so that unpackaged/portable clients find the correct matching server instance. | ||
| static GUID _portableClsid(const GUID& brandClsid) |
There was a problem hiding this comment.
Should we put these functions into src/types? We got CreateV5Uuid there already and we could link wtcli with it.
Unless you want to keep it portable of course.
There was a problem hiding this comment.
I'd prefer to have it be standalone if possible! But if there's strong feelings in the other direction I'm alright to change it
|
|
||
| // Register the COM class factory on a dedicated MTA thread so that | ||
| // incoming COM calls are dispatched to MTA worker threads rather than | ||
| // the STA/UI thread. This keeps long-running calls off the UI thread — |
There was a problem hiding this comment.
Ah here's the answer. But ...long-running? What calls do we foresee to be computationally expensive?
There was a problem hiding this comment.
Updated the comment, previous one was outdated. The COM methods call .get() and that's the actual reason for the MTA thread.
It's mostly existing, I just stripped the stuff that we don't need here that are more agent CLI specific. Happy to hear about the improvements though! And maybe I can bring those downstream too. |
| // LOAD BEARING (same discipline as ITerminalHandoff): OpenConsoleProxy.dll is a | ||
| // single shared proxy/stub DLL. Never change or reuse the UUIDs below. | ||
|
|
||
| // Terminal protocol — implemented by WindowsTerminal.exe, activated by the |


Summary of the Pull Request
Implements
wtcli, a new command-line client for Windows Terminal Protocol: a local COM control surface that lets external processes inspect and drive a running Windows Terminal instance. It provides a tmux-style command vocabulary for the terminal.wtclicurrently exposes 10 commands:list-windows(lsw),list-tabs(lst),list-panes(
lsp),active-pane,pane-statuscapture-pane(capturep), including--last-prompttograb the most recent completed shell command via OSC 133 shell integration
new-tab(neww),split-pane(splitw),kill-pane(
killp),focus-pane(focusp)Every command supports
--jsonfor machine-readable output, otherwise results are rendered as human-readable tables.References and Relevant Issues
Detailed Description of the Pull Request / Additional comments
A client activates the server directly with
CoCreateInstanceusing a per-brand CLSID (Release/Preview/Canary/Dev, selected at compile time), and issues typed commands.Components:
1.
wtcli.exe: the CLI client (src/tools/wtcli/)The user-facing tool. Parses subcommands, activates the protocol server via
WT_COM_CLSID, and calls the interface methods.2.
ITerminalProtocol: the classic-COM interface (src/host/proxy/ITerminalProtocol.idl)The contract between client and Terminal. A classic-COM interface marshaled by the MIDL proxy/stub in
OpenConsoleProxy.dll(registered per-brand in the app manifests). Scalar arguments stay typed; every complex result crosses the boundary as a JSONBSTR.3.
TerminalProtocolComServer: the in-proc server (src/cascadia/WindowsTerminal/)Implements
ITerminalProtocolinsideWindowsTerminal.exe.4.
TerminalPageprotocol bridge (src/cascadia/TerminalApp/TerminalPage.Protocol.cpp)The UI-thread methods that actually query and mutate live terminal state (windows, tabs, panes, process status, pane output) and return typed results.
5.
TerminalProtocolshared library (src/cascadia/TerminalProtocol/)Hosts the shared WinRT struct types (
WindowInfo,TabInfo,PaneInfo, etc) consumed in-process by both the page bridge and the server. Also providesProtocolParsing.h, a header of parsing helpers (ParseSplitDirection,ClassifyPaneOutputSource) shared by the server and the fuzzer.6. Protocol fuzzer (
src/cascadia/TerminalProtocol/ft_fuzzer/)A LibFuzzer harness targeting the parsing functions (
ParseSplitDirection,ClassifyPaneOutputSource).Validation Steps Performed
In a dev build of terminal, all 10 of the commands work
PR Checklist