Feature Request: Focus/Activate Tab by WT_SESSION
The Problem
There's no way for an external process to programmatically switch to a specific Windows Terminal tab.
When a process running inside a terminal tab needs to bring the user back to that exact tab (not just the window), it's currently impossible. The wt.exe CLI can open new tabs and target windows, but cannot activate an existing tab by its session identifier.
Why This Matters Now: The AI Agent Era
2024-2025 has seen an explosion of AI coding agents that run in the terminal:
| Agent |
Vendor |
Typical Task Duration |
| Claude Code |
Anthropic |
30 sec - 10+ min |
| GitHub Copilot CLI |
GitHub/Microsoft |
10 sec - 5 min |
| Gemini CLI |
Google |
10 sec - 5 min |
| Aider |
Open Source |
30 sec - 10 min |
| Cursor |
Anysphere |
Variable |
These agents run autonomously—refactoring code, running tests, fixing bugs across multiple files. Users naturally alt-tab away while waiting. When the agent finishes:
- A notification appears ("Claude finished refactoring")
- User clicks the notification
- Windows Terminal comes to foreground...
- ❌ But the user is on the wrong tab and has to hunt for where the agent was running
With 5-10 tabs open across different projects, this is a real friction point.
Prior Art: Every Other Major Terminal Has This
tmux (Gold Standard)
# Direct tab/pane targeting by session ID
tmux select-window -t mysession:2
tmux select-pane -t mysession:2.3
# Query all sessions, windows, panes
tmux list-sessions
tmux list-windows -t <session>
tmux list-panes -t <session:window>
iTerm2 (macOS)
# Full Python API for programmatic control
import iterm2
async def main(connection):
app = await iterm2.async_get_app(connection)
window = app.current_terminal_window
target_tab = window.tabs[2]
await window.async_select_tab(target_tab) # ← This is what we need
iterm2.run_until_complete(main)
Also supports AppleScript:
tell application "iTerm2"
tell current window
select tab 2
end tell
end tell
Kitty (Linux/macOS)
# IPC via Unix socket - can focus tabs by index or match criteria
kitty @ focus-tab --match index:2
kitty @ focus-window --match title:myproject
# Query state
kitty @ ls # Returns JSON of all windows, tabs, panes
Windows Terminal: The Gap
# We can do this:
wt.exe -w 0 nt # New tab in MRU window
wt.exe -w 2 split-pane # Split in window 2
# We cannot do this:
wt.exe --focus-session $env:WT_SESSION # ❌ Doesn't exist
wt.exe -w 0 focus-tab --index 3 # ❌ Doesn't exist
wt.exe --query-sessions # ❌ Doesn't exist
Technical Context
What Already Exists (The Building Blocks)
-
WT_SESSION environment variable - Already set per tab/pane, unique GUID like 5720ee6d-6474-47b0-88db-fa7e10e60d37
-
WT_PROFILE_ID environment variable - Profile GUID, useful but not unique per tab
-
Window targeting via -w - Can target windows by ID or name, just not tabs within them
-
Shell integration OSC sequences - Terminal already has rich bidirectional communication:
OSC 133;A ST - Start of prompt
OSC 133;B ST - Start of command input
OSC 133;C ST - Command executed
OSC 133;D;N ST - Command finished with exit code N
OSC 9;9;CWD ST - Current working directory
-
Internal tab management - Terminal obviously tracks tabs internally; just not exposed externally
Current Workarounds (All Fragile)
UI Automation - Enumerate TabItem elements, match by title, call SelectionItemPattern.Select():
// This works but is fragile
CComPtr<IUIAutomationElement> tabItem;
automation->CreatePropertyCondition(UIA_NamePropertyId, tabTitle, &condition);
terminalElement->FindFirst(TreeScope_Descendants, condition, &tabItem);
// Problem: Tab titles change, can be duplicated, user can rename
Keyboard simulation - Send Ctrl+Tab repeatedly:
// Extremely fragile, timing-dependent
keybd_event(VK_CONTROL, 0, 0, 0);
keybd_event(VK_TAB, 0, 0, 0);
// Problem: No way to know when you've reached the right tab
Title matching via console API:
wchar_t title[1024];
GetConsoleTitleW(title, 1024);
// Problem: Title ≠ Tab identity, changes with CWD, can be duplicated
Proposed Solution
Option A: New focus-tab Subcommand with Session Targeting
# Focus tab by its WT_SESSION GUID (most robust)
wt.exe focus-tab --session 5720ee6d-6474-47b0-88db-fa7e10e60d37
# Focus tab by index in current/specified window
wt.exe focus-tab --index 2
wt.exe -w 0 focus-tab --index 2
Option B: Extend -w to Accept Session References
# Session becomes a first-class window/tab identifier
wt.exe -w session:5720ee6d-6474-47b0-88db-fa7e10e60d37 focus-tab
This aligns with @zadjii-msft's comment in #17963:
"I do have plans to have -w 0 do The Smart Thing, and figure out the right window ID based on the current WT_SESSION_ID"
Option C: Query Command (Enables Advanced Scenarios)
# Get structured info about sessions
wt.exe query --session 5720ee6d-6474-47b0-88db-fa7e10e60d37
# Output: {"window_id": 2, "tab_index": 3, "title": "pwsh - myproject"}
# List all sessions (tmux-style)
wt.exe query --list-sessions
# Output: [{"session": "5720ee6d-...", "window_id": 2, "tab_index": 3}, ...]
Real-World Use Case: Toasty Notification Tool
I'm building Toasty, a Windows toast notification CLI for AI coding agents. The workflow:
┌─────────────────────────────────────────────────────────────────┐
│ 1. Claude Code runs in Tab 3, user alt-tabs to browser │
│ 2. Claude finishes → triggers hook → toasty shows toast │
│ 3. Toasty captures WT_SESSION="5720ee6d-..." at invocation │
│ 4. User clicks toast notification │
│ 5. Toasty calls: wt.exe focus-tab --session 5720ee6d-... │
│ 6. ✓ User lands exactly in Tab 3 where Claude was running │
└─────────────────────────────────────────────────────────────────┘
Current broken flow: Step 5 doesn't exist, so users land on whatever tab was last active and have to manually find their agent.
Hook Configuration (Already Supported)
Claude Code (~/.claude/settings.json):
{
"hooks": {
"Stop": [{
"hooks": [{
"type": "command",
"command": "toasty.exe \"Claude finished\" --session %WT_SESSION%"
}]
}]
}
}
GitHub Copilot (.github/hooks/toasty.json):
{
"hooks": {
"sessionEnd": [{
"type": "command",
"powershell": "toasty.exe 'Copilot finished' --session $env:WT_SESSION"
}]
}
}
Related Issues & Discussions
| Reference |
Status |
Relevance |
| #17963 |
Open Discussion |
WT_WINDOWID request; @zadjii-msft mentioned plans for session-aware -w 0 |
| #10561 |
Open |
-w 0 not finding right window from quake mode |
| #16568 |
Open |
General programmatic API request (iTerm2-style) |
| #13006 |
Open |
WT_SESSION not set when Terminal is default terminal |
| #10708 |
Open |
Ability to identify pane IDs |
Implementation Considerations
-
Session → Window/Tab mapping - Terminal already maintains this internally for tab management
-
Cross-process communication - Could use existing named pipe/COM infrastructure that wt.exe uses for -w targeting
-
Focus stealing - Windows has restrictions; but Terminal already handles this for -w commands
-
Backward compatibility - New subcommand/flag, no breaking changes
Summary
| Terminal |
Focus Specific Tab? |
Query Sessions? |
API Maturity |
| tmux |
✅ select-window -t |
✅ list-sessions |
Production |
| iTerm2 |
✅ Python API |
✅ Full introspection |
Production |
| Kitty |
✅ kitty @ focus-tab |
✅ kitty @ ls |
Production |
| Windows Terminal |
❌ |
❌ |
Gap |
Windows Terminal has all the internal machinery (WT_SESSION, window management, shell integration). The missing piece is exposing tab activation to external processes.
This feature would make Windows Terminal a first-class citizen for the emerging AI agent workflow—and close a gap that every other major terminal has already solved.
I'm Happy to Help
I'd be glad to:
- Test preview builds
- Provide detailed feedback
- Contribute to implementation if pointed in the right direction
- Help document the feature
Environment: Windows 11 24H2, Windows Terminal 1.21+, C++/WinRT
cc @crutkas
Feature Request: Focus/Activate Tab by WT_SESSION
The Problem
There's no way for an external process to programmatically switch to a specific Windows Terminal tab.
When a process running inside a terminal tab needs to bring the user back to that exact tab (not just the window), it's currently impossible. The
wt.exeCLI can open new tabs and target windows, but cannot activate an existing tab by its session identifier.Why This Matters Now: The AI Agent Era
2024-2025 has seen an explosion of AI coding agents that run in the terminal:
These agents run autonomously—refactoring code, running tests, fixing bugs across multiple files. Users naturally alt-tab away while waiting. When the agent finishes:
With 5-10 tabs open across different projects, this is a real friction point.
Prior Art: Every Other Major Terminal Has This
tmux (Gold Standard)
iTerm2 (macOS)
Also supports AppleScript:
Kitty (Linux/macOS)
Windows Terminal: The Gap
Technical Context
What Already Exists (The Building Blocks)
WT_SESSIONenvironment variable - Already set per tab/pane, unique GUID like5720ee6d-6474-47b0-88db-fa7e10e60d37WT_PROFILE_IDenvironment variable - Profile GUID, useful but not unique per tabWindow targeting via
-w- Can target windows by ID or name, just not tabs within themShell integration OSC sequences - Terminal already has rich bidirectional communication:
Internal tab management - Terminal obviously tracks tabs internally; just not exposed externally
Current Workarounds (All Fragile)
UI Automation - Enumerate TabItem elements, match by title, call
SelectionItemPattern.Select():Keyboard simulation - Send Ctrl+Tab repeatedly:
Title matching via console API:
Proposed Solution
Option A: New
focus-tabSubcommand with Session TargetingOption B: Extend
-wto Accept Session ReferencesThis aligns with @zadjii-msft's comment in #17963:
Option C: Query Command (Enables Advanced Scenarios)
Real-World Use Case: Toasty Notification Tool
I'm building Toasty, a Windows toast notification CLI for AI coding agents. The workflow:
Current broken flow: Step 5 doesn't exist, so users land on whatever tab was last active and have to manually find their agent.
Hook Configuration (Already Supported)
Claude Code (
~/.claude/settings.json):{ "hooks": { "Stop": [{ "hooks": [{ "type": "command", "command": "toasty.exe \"Claude finished\" --session %WT_SESSION%" }] }] } }GitHub Copilot (
.github/hooks/toasty.json):{ "hooks": { "sessionEnd": [{ "type": "command", "powershell": "toasty.exe 'Copilot finished' --session $env:WT_SESSION" }] } }Related Issues & Discussions
WT_WINDOWIDrequest; @zadjii-msft mentioned plans for session-aware-w 0-w 0not finding right window from quake modeWT_SESSIONnot set when Terminal is default terminalImplementation Considerations
Session → Window/Tab mapping - Terminal already maintains this internally for tab management
Cross-process communication - Could use existing named pipe/COM infrastructure that
wt.exeuses for-wtargetingFocus stealing - Windows has restrictions; but Terminal already handles this for
-wcommandsBackward compatibility - New subcommand/flag, no breaking changes
Summary
select-window -tlist-sessionskitty @ focus-tabkitty @ lsWindows Terminal has all the internal machinery (
WT_SESSION, window management, shell integration). The missing piece is exposing tab activation to external processes.This feature would make Windows Terminal a first-class citizen for the emerging AI agent workflow—and close a gap that every other major terminal has already solved.
I'm Happy to Help
I'd be glad to:
Environment: Windows 11 24H2, Windows Terminal 1.21+, C++/WinRT
cc @crutkas