RPDI
Back to Blog

How to Read Open Editor Tabs Programmatically in VS Code: The tabGroups API Deep Dive

TL;DR

Before VS Code 1.67, there was no official API to read which tabs a developer had open. Extensions had to use undocumented internal APIs or guess based on document events. The tabGroups API (introduced in VS Code 1.67) provides clean, documented access to the complete tab state. This tutorial covers the API surface, common patterns, gotchas, and production implementations for AI context tools.

Before tabGroups: The Dark Ages

Before VS Code 1.67, reading open tabs required one of three hacky approaches: (1) tracking every document open/close event and maintaining your own list (fragile — misses tabs with non-text inputs), (2) accessing undocumented internal APIs through the vscode module (breaks between versions), or (3) reading VS Code's internal state files from disk (extremely fragile, timing-dependent).

The tabGroups API eliminated all of these hacks. One clean API call gives you every open tab's file path, position, and state.

The tabGroups API Surface

The complete tabGroups API consists of three key objects:

// Reading All Open Tabs:

const allTabs = vscode.window.tabGroups.all

.flatMap(group => group.tabs);

// allTabs now contains every open tab across all groups

// Filtering to Text File Tabs:

const fileTabs = allTabs

.filter(tab => tab.input instanceof vscode.TabInputText)

.map(tab => ({

path: (tab.input as vscode.TabInputText).uri.fsPath,

isActive: tab.isActive,

isPinned: tab.isPinned,

groupId: tab.group.viewColumn

}));

Production Patterns

Here are the three most useful patterns for AI context tools:

Step 01

Get the Working Set

All text file tabs = the developer's explicit working set. Filter tab.input for TabInputText instances (ignoring diff views, terminal tabs, settings tabs). This gives you exactly the files the developer considers relevant.

Step 02

Track Tab Changes

vscode.window.tabGroups.onDidChangeTabs fires with a TabChangeEvent containing: opened tabs, closed tabs, and changed tabs. Use this to incrementally update your working set without full recomputation.

Step 03

Prioritize by Tab Position

The active tab (tab.isActive) is the highest-priority context file. Pinned tabs (tab.isPinned) indicate long-term reference files. Recently opened tabs (tracked via onDidChangeTabs timing) indicate short-term working context.

Build Context Tools with This API.

The tabGroups API is the foundation of deterministic context assembly. Open tabs = working set. Working set = context. Context = better AI completions.

🔧 Context Snipe uses tabGroups as its primary context signal.

Every file in your open tabs feeds into Context Snipe's deterministic context engine. The tabGroups API provides the working set. Context Snipe resolves imports and serves everything via MCP. Start free — no credit card →