Chat TagsColour-code, categorise and annotate VS Code chat sessions. Thirty chats down that sidebar. Every single one grey. Every single one named after whatever half-arsed shit you typed at eleven at night before you knew what the job actually was. One of them is holding the thing you care about. The rest are dead. They look identical. Chat Tags gives them colours, categories, a second line of text, and somewhere to bury the corpses.
Why this is a separate view instead of just fixing the real oneBecause you can't fix the real one. The surface isn't fucking there, hacks and proposed APIs included. This got checked against the shipped workbench before a line was written:
The session model has Not an oversight. It just wasn't a thing anyone needed until you had thirty chats open and no bloody idea which was which. So this sits next to the real list, reads the same files off disk, and draws them the way you wanted them in the first place. It's a second opinion. The first one was shit. What the colours meanTwo signals. They never fight, because they're on different axes. That's basically the whole design.
The left border means exactly one thing: something happened in that session since you last opened it. Attention rows also get max wash, a full-strength dot with a halo, and a heavier title. Nothing else in the view draws a left border, so it can never mean two things at once. Open the session and it clears. Mark all read turns up in the toolbar only while there's something to mark, because a button that does nothing is just decoration. First run stamps a baseline timestamp. Without it every session you've ever opened lights up as unread on install day, which is a hell of a way to say hello. Colour attaches to the category, not the chat. Inside a webview colours are plain CSS, which answers to nobody's palette rules. Twelve curated ones plus a custom hex field. Which sessions can run things without askingVS Code lets you set a permission level per chat. Most people set it once, forget which chats they set it on, and then wonder why one of them is merrily running commands. A row that isn't on the default level gets a small pill next to its title. That's it. Nothing shows on the default level, because a badge that appears on every row is wallpaper.
The pill reads the level out of the session file, so it costs nothing and it's right even for chats you set up months ago and haven't opened since. There's a second pill, Auto-approving, for the other way a chat ends up running commands unattended: the Allow All Commands in this Session button in a terminal prompt. That one is worth calling out because VS Code keeps it nowhere — it lives in memory, it vanishes when the window reloads, and nothing on disk says it was switched off. Chat Tags works it out by watching what the chat actually does: a command that ran without asking puts the pill up, and the next one that had to ask takes it down. If your machine has the auto-approve permission levels locked out by policy, that button is the only route left, and this pill is the only warning you get. One honest limit: it shows what the next message in that chat will run as, not what the old ones ran as. Change the level today and the pill changes today, even though yesterday's messages ran under the old one. Ordering and groupingTwo orders, in the sort menu:
Both newest first. And they are not the same bloody list — across 23 real sessions barely a third land in the same place under both, because a chat you started in July and picked up yesterday sits at opposite ends of them. Group by category puts a heading above each category's sessions, in the order you defined them, with everything unassigned dumped under Uncategorised at the bottom. Point a session at a category you deleted and it lands there too. Where else would it go. Archiving and deletingTwo completely different things. They work differently on purpose.
Archive is oursArchived sessions drop out of the list into a section at the bottom, shown only when Show archived is on. Until then a footer counts them — because a hidden session with no visible count is how you end up absolutely certain something ate your chat. VS Code has its own archived flag. Archived sessions get skipped by the automatic subtitle sweep and don't count towards the unread badge. Something you've put away doesn't get to spend your money or ask for your attention. Delete goes through VS CodeNever by deleting the file. The session index lives in workspace storage, and the workbench's own delete returns early on an id it doesn't recognise. Rip the file out from under it and the index keeps an entry pointing at nothing, which is a worse mess than the one you started with. So delete hands the job to the workbench. It clears any open widget, removes the history entry, deletes both files it knows about, and rewrites the index. It runs its own confirmation dialog — names the session, tells you it can't be undone — so Chat Tags doesn't stack a second one on top of it like some kind of idiot. The command resolves whether you confirmed or cancelled, so the file on disk is the only honest evidence of what happened. That goes to the log, and Chat Tags only forgets the session's metadata once the file has actually gone. Generated subtitlesA language model can write the second line for you. It can write the title too. Three buttons on every row, and the same three sit in the Command Palette under Chat Tags. What comes back is a status line, not an essay. "Waiting for API key." "Retrying after request errors." That's it. That's the whole feature. Three things it can write
Status decays. Right for something you're still working. Task summary doesn't decay, so it's right for the one you'll come back to in a week and stare at like a stranger's grocery list. Every message the model sees goes through a boilerplate filter first, so When the end of a session is nothing but noise, the prompt carries no last request at all. A missing line beats a misleading one. Feed a model Overwriting something you wroteA generate button sitting over text you typed yourself is dimmer than the others, and it takes two clicks. The first arms it — lights up, stays visible whether or not you're hovering, tooltip flips to You have customised this subtitle already, confirm regenerate? The second one fires. It disarms itself after six seconds. Only hand-written text is guarded. The armed state lives in the view, not in the session record, so a repaint from the file watcher can't quietly disarm a decision you're halfway through making. Renaming a sessionChat Tags never writes to the session file. VS Code holds it open and appends to it. A record written underneath gets clobbered on the next flush, and a half-written line takes the whole session with it. Not worth it for a rename, or for anything else. So titles live in extension state and get drawn over the top, whether you wrote it or the model did. A dotted underline marks a title as ours rather than the session's own. Clear the field and it drops. The native Chat list carries on showing the original either way — no API to change it, same wall the colours hit. Which modelThe pane lists whatever your window actually offers and defaults to Automatic: no selector, then the cheapest family on the table — Pin one and its id goes in No models, or consent declined, and the explicit path says so once. The automatic path shuts up for the rest of the window rather than nagging you every sweep. What it costsOff by default. Every generation is a real billable request against whatever provider your window has. Real money. Yours.
The scope rule does the heavy lifting. Without it, flicking Manual always wins. Edit a generated subtitle and it's yours — A subtitle also remembers which kind it is. Generate a status line and it stays a status line, even where What leaves your machineA prompt is not the same as a tool call. Running the command is what you asked for. Handing whatever it touched to a model provider is a second thing entirely, and session files are absolutely full of shit that was never meant to travel. One real session had a live Vaultwarden token sitting in its tool activity and a password as its last request. Both would have gone out verbatim, to a third party, because a sidebar wanted to write four words about it. So credentials get masked on the way in:
Deliberately small. A stop on the obvious shapes, not a scanner, and it runs on the finished prompt so nothing added later slips past it. What it catches becomes This is not a claim that nothing else leaks. Prose you typed is sent as prose you typed. If a session is full of things you wouldn't paste into a stranger's window, leave Starting and opening sessionsThe Clicking a session can rearrange your window. Three modes, in the pane under When a session is clicked:
A new chat lands exactly where a clicked one would, so the A new chat joins the list when you send its first message. VS Code keeps an untouched chat in memory and writes nothing to disk, and this pane reads files off disk — so there is nothing to draw until you type. When the row does appear it takes the selection, so the list matches the chat you are looking at. Open something else while you are typing and your selection stays where you put it.
Sessions and chat in one paneThe built-in Chat view sets Drag the Chat view's title onto the Chat Tags container, or Command Palette → View: Move View → Chat → Chat Tags. What you can't do is render the chat conversation inside this extension's webview. Webviews are sandboxed iframes and workbench UI doesn't project into one. Sharing a container is the actual mechanism, and it's your move to make, not something the extension can declare on your behalf. SettingsEverything lives in the pane. The view title bar and the Settings UI get nothing. Buttons across the header, one panel open at a time:
Order and grouping get their own menu instead of a row of radio buttons behind the gear. You flip those several times a session. The stuff behind the gear you set once and forget about. Whichever panel is open, its button stays lit until you click it again. That's the only way to close it, so it has to read as pressed rather than merely hovered. The Titles and subtitles get edited through their pencils, or by double-clicking the title. Neither is a click target — the whole row opens the session, and an edit affordance covering half the row turned that into a coin flip. Clearing the title field restores the session's own.
Every one is a real VS Code setting, so the pane and the Settings UI are two windows onto one stored value rather than two stores having an argument about it. Edit either. Install
The Chat Tags icon shows up in the activity bar. Every activation writes where it found your sessions to ContributingBuild steps, the probes, the read model internals and every gotcha worth knowing are in CONTRIBUTING.md. LicenceGPL-3.0-or-later. See LICENSE. Copyright © 2026 WulffTech. Do what you like with it. Ship a modified version and the source goes with it — that is the whole deal. |
