Claude Code skill (VS Code: Windows, Remote-SSH Linux): image previews and open buttons under file paths in the chat, clickable local links, a context ring and your own composer buttons
Claude names a file, and the chat shows it: a preview card right under the path with Open, Default app and Show in folder, a viewer to zoom in, and a Mark mode that hands Claude numbered boxes in the image's own pixels.
The chat has no API for any of this: the skill inserts code into the installed Claude Code extension, keeps the pristine files beside it, and --revert puts them back byte for byte.
Installation · Usage · How it works · Limitations
Unofficial: not affiliated with or endorsed by Anthropic. No Anthropic code is distributed here; the skill edits the copy of the Claude Code extension already installed on your machine.
Claude names a file, and a card with a preview and open buttons appears right under the path.
In the stock Claude Code chat a path in an answer is text. To see the screenshot Claude just made you copy the path, switch to Explorer and dig for the file; to show Claude which part of it is wrong you describe it in words and hope. This skill patches the chat so the file comes to you:
-
A card under every path. An absolute Windows path in an answer (in a Remote-SSH window also a Linux path, see Limitations) gets a card by kind: an image a preview with Open (a VS Code tab), Default app and Show in folder; a
.psda Photoshop button (only where Photoshop is installed); a folder Open folder; other files Open and Show in folder, or only the latter for PDFs, Office files and archives; Open on an.htmlpage shows it in VS Code's Integrated Browser. Markdown links and images that point atC:\...work too, where the stock chat drops them. So does avscode://anthropic.claude-code/open?prompt=...link: a click opens a new chat tab with the prompt typed in and not sent, for example a prompt Claude wrote for you to start the next session with. A quote in an answer gets the copy button code blocks have. -
A viewer. Click a preview: the wheel zooms at the cursor, drag pans, double-click fits, Esc closes.
-
Mark. Draw numbered boxes on the image, press Done, and the prompt box gets the path, the image size and one line per box in the file's own pixels, ready for a word after each colon:
C:\Users\example\shots\checkout.png (1920x1080), regions [x1,y1,x2,y2] in source image pixels: 1 [412,88,760,140]: 2 [1210,640,1580,712]:Insert path puts the bare path at the cursor instead: a path, not an
@mention, so the image is not loaded into the context until Claude decides to read it.
-
The files panel. A folder button at the top right of the chat lists every file this chat has shown: images as thumbnails, then folders, then other files, newest first. A click acts like the card's buttons.
-
The context ring. How full this chat's context is, right after the composer's
/button: a ring and the count (184k), green until 256k tokens or 60% of the window, clay orange past either. A click runs/context.
And one add-on, offered once the setup is done:
-
Your own composer buttons. Up to five, each running a slash command, sending a fixed message or inserting a line into the prompt box: one click for what you now type. A button shows an icon or a short label of up to three characters (the
1-2below inserts a line). Your agent can propose them from the commands and skills you actually have.
Experimental, off by default (--enable chat-attention): a contents list of the chat that collects
the agent's lines starting with ❓ (a question), 👀 (look at this) or ⚠ (a warning); a click scrolls
to the line. The list stays empty until your agent is told to start such lines with these marks.
| At a glance | |
|---|---|
| What it does | cards with previews and open buttons under file paths in the chat |
| Also in the base install | image viewer, Mark and Insert path, local links, chat files panel, context ring |
| Add-on | up to five composer buttons of your own |
| Where it works | Windows, VS Code with the Claude Code extension; a Linux server in a VS Code Remote-SSH window |
| Survives extension updates | yes, a SessionStart hook re-applies it |
| When an update breaks a part | that part is left out, the rest keep working, your agent repairs it |
| Undo | --revert, byte for byte from the pristine copy |
| Labels | English or Russian |
| Requires API keys | no |
| External dependency | Node.js 16.9+, no npm packages |
| License | MIT |
What it changes on your machine. Read this before you install.
- Two files of the installed Claude Code extension, edited in place:
webview/index.js(the chat window) andextension.js(the extension host, which is what can read an image from disk and open it). The pristine copy of each stays beside it as<file>.orig, and one command,--revert, puts both back byte for byte. - The composer's stock context counter is switched off: the ring takes its place, and the
counter's click, which compacted the chat on the spot, goes with it (
/compactstill works typed). Ask your agent to turn the ring off and the stock counter is back after a window reload. - One SessionStart hook in
~/.claude/settings.json, so the patch comes back after every extension update. The file is copied once tosettings.json.ccp.bakbefore the first write and saved back as plain 2-space-indented JSON (your own formatting of it is not kept), other hooks are left alone, and--uninstall-hookremoves exactly this entry. - One rule in your
CLAUDE.md, and only if you say yes: how Claude should write file paths so that cards appear under them. Appended, never rewritten. - Its own state in
%USERPROFILE%\.claude\vscode-claude-code-patch.*: config, a ledger of pristine checksums, a fingerprint cache, a lock. - Only if your agent repairs a part after an extension update: a staging copy of the skill, a copy
of the new build's two bundles to test against, and the fix as a diff, all in
%LOCALAPPDATA%\vscode-claude-code-patch. They stay there for the next repair. - In a Remote-SSH window all of this happens on the server, not on your local machine: the two
files under
~/.vscode-server/extensions/anthropic.claude-code-*-linux-*, the hook in the server's~/.claude/settings.json, the state in~/.claude/, a repair's files in${XDG_STATE_HOME:-~/.local/state}/vscode-claude-code-patch.--revertand--uninstall-hookundo them there.
Nothing else is written. The patch makes no network calls; a repair is offered to this repository as an issue only on your yes.
- A path in an answer is dead text. Claude says the render is at
C:\...\hero.png, and seeing it means copying, switching windows and navigating. Many times a session. - Pointing at part of an image is guesswork. "The button at the top right" is read by a model that sees the picture at its own scale. A box in the file's own pixels leaves nothing to guess.
- Files scroll away. The image from an hour ago is forty screens up. The files panel keeps every one the chat has shown in one place.
- Every extension update wipes a patch. Claude Code ships a new build every day or two, each into a fresh folder. The hook puts the patch back at the next session start, before you notice it went.
- There is no supported route. The extension offers no extension point for its chat, and neither does VS Code. Without patching the bundles none of this can exist.
One command, and the skill is available as /vscode-claude-code-patch:
npx skills@latest add warodan/vscode-claude-code-patch -gAfter it installs, restart your agent — skills are read at startup.
Install it globally, with -g. The SessionStart hook lives in your user-wide
~/.claude/settings.json and points at the skill's folder. A project install would tie it to that
one project, and moving or deleting the project would leave every session with a broken hook. Found
inside a project, the skill says so and recommends the global install before it writes anything.
The skills.sh installer asks which agents to install it for. Node.js is needed for that command, and the skill uses the same Node (see Requirements).
Expect the installer to flag this skill as high risk, and it would not be wrong. skills.sh runs
third-party security scanners on every install; for this skill's predecessor they reported
Med Risk / Critical Risk, and this one edits more. The skill's entire job is to change files inside
an extension you already have. What it changes is listed above, How it
works shows every guard, and Limitations says plainly what can go
wrong. Read those before you install it.
Installing the skill changes nothing in VS Code. Setting it up is a second step, and you ask for it. The skill is instructions for your agent, not an installer. Once the agent has restarted, tell it:
install the Claude Code chat patch
It checks for the predecessor skill and runs a preflight that writes nothing, then tells you in a few
lines what it is about to change and waits for your yes. Only then does it build the base parts
and install the SessionStart hook. Then it reads your CLAUDE.md files for a rule on
how paths are written, since cards appear only under paths written a certain way; if there is none it
explains that in two lines and offers to append one, only on your yes. It asks you to reload the VS
Code window and confirm that a card shows and the ring is in place, and finally offers composer
buttons fitted to your own commands and skills.
The labels are English or Russian. For Russian from the start, say so in the same request:
install the Claude Code chat patch with Russian labels
If you write to your agent in Russian, it picks Russian by itself and says so in the message that asks for your yes. The language can be switched at any time later.
Working in a VS Code Remote-SSH window to a Linux server? That window loads its Claude Code chat
from the server, so the skill goes there. Open a terminal in that window (it runs on the server), run
the same npx command, restart the agent and ask for the setup the same way. Node.js must be
installed on the server. A local install does not reach that chat, and the server's install does not
touch your local VS Code; use both if you work in both.
No terminal of your own, no flags to choose. Open Claude Code and paste this to it:
Install the vscode-claude-code-patch skill for me. Run in the terminal:
npx skills@latest add warodan/vscode-claude-code-patch -g -y -a claude-code
If npx is not found, give me a link to download Node.js and wait.
Do not install anything else.
When you are done, tell me in one line that it is ready and that I need to restart the session.
The agent does the rest. This is the first install; updating is a different command, below. For a Remote-SSH server, paste it into the Claude Code chat of that Remote-SSH window.
npx skills@latest update -g vscode-claude-code-patch
npx skills@latest remove -g vscode-claude-code-patchFor a Remote-SSH server, run them in a terminal of that window, on the server.
After an update there is nothing to re-run: the hook sees that the skill's own files changed and rebuilds the patch with the new code at the next session start, then tells you to reload the window.
Removing the skill? Take the patch and the hook out first. The hook calls a script inside the skill
folder, and remove deletes that folder without touching your settings, so every session would start
with a hook that fails. Ask your agent to undo the patch and remove the hook (it runs --revert and
--uninstall-hook), reload the window, then run remove. It also offers to take the paths rule out of
CLAUDE.md if it added one.
What stays after remove: the state files %USERPROFILE%\.claude\vscode-claude-code-patch.*, the
backup %USERPROFILE%\.claude\settings.json.ccp.bak, and %LOCALAPPDATA%\vscode-claude-code-patch if a
repair ever ran (on a Linux server: the same files in ~/.claude/, and
${XDG_STATE_HOME:-~/.local/state}/vscode-claude-code-patch). Nothing uses them any more; delete them by hand if you
want them gone.
This skill replaces vscode-claude-chat-context-meter.
Its ring is part of this skill's base install (context-meter), drawn the same way, and its custom buttons can be
recreated as buttons that, unlike there, survive extension updates.
The two cannot run side by side: both rebuild the same webview/index.js from the same
index.js.orig, each from its own hook, and would erase each other at every update. So while the old
skill's hook is in your settings.json, this one refuses to build or to install its own hook, and
names the exact commands that clear the way.
You do not have to do the move by hand. Install this skill and ask for the setup as above: it finds the old one, shows you four steps (remove its hook, undo its patch, remove its folder, then set this one up) and runs the old skill's commands only after your yes. The steps and the button mapping: migrate-from-v1.md.
After the setup there is nothing to call. Any answer with a path written the way the rule asks gets a card, and the folder button at the top right of the chat opens the files panel. The skill is picked up on its own when you ask for something it covers:
install the Claude Code chat patch
First run, described in Installation.
switch the chat patch labels to Russian
Every label, tooltip and the text Mark puts into the prompt box. Say English to switch back.
add a button that runs /usage
propose composer buttons for how I work
One read-only subagent reads the frontmatter of your commands, skills and plugins and the headings of
your CLAUDE.md (never session transcripts, .env files or memory), and you get a table of up to
five suggestions to pick from and edit. The buttons live in the config, so the hook rebuilds them after
every extension update.
fix the Claude Code chat patch
For the day the hook reports a part as UNSAFE after an extension update. The agent repairs it in a
staging copy, tests it, and only then replaces the installed skill; see How it works.
check whether the patch is still safe on this version
The read-only preflight: every enabled part built and parsed in memory, SAFE TO PATCH or exactly
what did not match, nothing written. If a part is UNSAFE, the agent tells you and offers the repair;
it starts only on your yes.
undo the patch, I want the extension back the way it was
--revert restores both files from their pristine copies, and the hook re-applies nothing until you
ask for a build again.
Or call it explicitly:
/vscode-claude-code-patch install the chat patch with Russian labels
If no Claude Code chat opens at all, Claude is not there to fix it. Run this in any PowerShell window (the path is where a global install puts the skill), then Developer: Reload Window. It loads no part of the patch, so it works even when a skill file is broken:
node "$env:USERPROFILE\.claude\skills\vscode-claude-code-patch\claude_code_patch.mjs" --revertIn a Remote-SSH window, run it in a terminal of that window, on the server:
node ~/.claude/skills/vscode-claude-code-patch/claude_code_patch.mjs --revertIf that fails too: Extensions → Claude Code → Uninstall, then Install. Settings and sessions survive.
flowchart LR
A["--verify<br/>nothing written"] --> B["build from the<br/>pristine .orig"]
B --> C["insertions only,<br/>each one marked"]
C --> D["parse, then<br/>atomic write"]
D --> E["reload window"]
- Two files, found where VS Code keeps them. Under
%USERPROFILE%\.vscode\extensions, everyanthropic.claude-code-*folder (on a Remote-SSH Linux server: the-linux-ones under~/.vscode-server/extensions):webview/index.js, the ~5 MB minified bundle behind every Claude Code chat (sidebar, editor tab, separate window), andextension.js, the extension host. Only the cards touch the host; the viewer, Mark, the files panel, the ring and the buttons live in the webview. - Preflight first.
--verifyruns the whole build with writing switched off and answers per part:SAFE TO PATCH, orUNSAFE: <part>/<target>: <what did not match>. - Derived, not hardcoded. Minified names change with every build, so each part re-derives them
from anchors that must occur exactly once, and refuses rather than guesses. Every edit is an
insertion marked
/*CC-...*/, and every build starts from the pristine copy, never from a patched file. - Parse before writing, write atomically. Each assembled file is parsed; if one does not parse,
nothing is written anywhere. The pristine copy is saved as
.origfirst, then each file goes to a temporary copy that is read back, checked by sha1 and renamed over the original. A ledger keeps the pristine sha1 of each extension version, and a "pristine" copy that disagrees is refused. - A broken part is left out, not forced. When a new extension build moves code one part depends
on, that part is
UNSAFEand skipped; the others are built and keep working. - Self-repair, tested before it is applied. Your agent repairs the part in a staging copy under
%LOCALAPPDATA%(on a Linux server${XDG_STATE_HOME:-~/.local/state}), runs the skill's suite of about 280 tests against a copy of the new build, checks--verify, and only then replaces the installed skill. It saves the diff and offers to send it here as an issue, so the fix reaches everyone; nothing is sent without your yes.
--install-hook writes one SessionStart hook into ~/.claude/settings.json that runs --ensure in
the background. On the everyday path it compares a few file fingerprints and exits without opening a
bundle. It rebuilds when the extension version changed, when your config changed, or when the skill's
own files changed, which is how an npx skills update or a repair takes effect at the next session
start. When it has something to say, it sends one message your agent sees: rebuilt, reload the window;
or a part is UNSAFE, ask Claude to fix the chat patch. A lock keeps two windows starting at once from
writing the same file, and the hook never fails a session start. After --revert it stays silent and
re-applies nothing until you build again. A restored patch appears at the next window reload; the
update asks for one anyway.
| Requirement | Details |
|---|---|
| Windows, or a Linux server reached by VS Code Remote-SSH | on macOS, and on any other platform, every command but --help stops with Windows and Linux only for now. On Linux only the server copy of the extension that Remote-SSH installs is patched, not a desktop VS Code |
| VS Code with the Claude Code extension | anthropic.claude-code, installed in the standard %USERPROFILE%\.vscode\extensions (Linux: ~/.vscode-server/extensions, -linux- folders only, so not Alpine's -alpine- ones). VS Code Insiders, Cursor, Windsurf and VSCodium are not searched; WSL and Dev Containers keep the same ~/.vscode-server layout but were not tried |
| Claude Code as the agent | it is Claude Code's chat that gets patched, and the self-heal is a Claude Code SessionStart hook |
| Node.js 16.9 or newer, on PATH | runs the patcher; no npm packages. For Remote-SSH, on the server. The hook records the absolute path of the node binary, so after Node moves to another folder ask your agent to reinstall the hook. The self-repair test suite needs Node 20.10 or newer |
| Write access to the extension folder | the patch edits two files there and keeps their pristine copies beside them |
| Photoshop (optional, Windows) | only for the Photoshop button on .psd and .psb cards; without it the button is not shown |
vscode-claude-code-patch/ # the repository
├── skills/vscode-claude-code-patch/ # ← the only thing that gets installed
│ ├── SKILL.md # the skill: setup, commands, reading the output, known limits
│ ├── claude_code_patch.mjs # the engine and CLI, Node built-ins only
│ ├── lib/layout.mjs # finds the composer panel in the minified bundle
│ ├── parts/ # one module per part: chat-media, chat-mark, chat-files,
│ │ # context-meter, chat-icons, chat-attention (experimental)
│ ├── assets/ # the code the parts insert: webview helpers, host snippets
│ ├── references/
│ │ ├── composer-addons.md # the context ring and your own buttons
│ │ ├── migrate-from-v1.md # moving from vscode-claude-chat-context-meter
│ │ ├── self-repair.md # fixing a part an extension update broke
│ │ ├── layout-recovery.md # finding the anchors a new build moved
│ │ ├── remote-ssh.md # a VS Code Remote-SSH window on a Linux server
│ │ └── internals.md # every edit, guard and state file
│ ├── tools/mirror.mjs # exact copy with a sha1 check, used by self-repair
│ ├── tests/ # the suite self-repair runs before applying a fix
│ └── LICENSE
├── assets/ # the screenshots this README shows
├── LICENSE
└── README.md
- Windows and VS Code only, plus a Remote-SSH Linux server. Only
%USERPROFILE%\.vscode\extensions(Linux:~/.vscode-server/extensions) is searched, so Insiders, Cursor, Windsurf, VSCodium and desktop VS Code on Linux or macOS are not patched; on Linux the build has run only on a linux-x64 server reached by Remote-SSH from Windows (a linux-arm64 server is untried; an Alpine server's-alpine-extension folders are not found at all). A Remote-SSH window loads the chat from the server, so the server needs its own install of the skill (the same command, run there), its own build and its own hook; there Default app and Photoshop are not offered, Show in folder selects the file in VS Code's Explorer (inside the window's folders) instead of a file manager (not yet tried in a live Remote-SSH window, nor is Open on an.htmlpage there), and any/a/btext alone in a code block, a URL path such as/api/v1/usersincluded, gets a card whose buttons find no file. - It patches an installed extension, and that is a real risk. A broken
extension.jsmeans no Claude Code chat opens in that window. The engine writes it only when the trial build parses and only by renaming a complete, verified copy over it, and--revertabove works from any terminal. But the honest summary is: this is a patch, not an integration. - Cards appear only under paths written a certain way: an absolute Windows path alone in a fenced
code block, or a markdown image or link to a drive path (on a Remote-SSH server also an absolute
/a/b...path,file:///included). By default the extension tells Claude to write workspace-relative links, which get no card. That is what theCLAUDE.mdrule is for. - An extension update can take a part out until it is repaired. A build that moves code a part
depends on makes that part
UNSAFE; the rest keep working. A repair lives in your installed copy until it is published here, and annpx skills updateto a version without it brings theUNSAFEback. - Every change shows after Developer: Reload Window. The chat is already loaded by the time a session starts, so the hook cannot put a restored patch into a window that is open.
- Any image path Claude writes is previewed without a click: read only, image files up to 100 MB; nothing is launched without a click. Past 100 MB there is no preview, the buttons still work.
- The files panel sees what the chat window keeps in memory, about the last 500 records, and only what the main agent showed: files touched only by subagents are not in it.
- Default app and Open folder hand the path to Explorer, which treats commas in a name specially: a planted file whose name holds commas might open another item than the one clicked (not verified).
- Open on an
.htmlfile loads the page in the Integrated Browser, scripts and all, as afile://address; it needs the browser's open command (VS Code 1.140 has it), elsewhere the page opens as text. A new-chat link fills the prompt box with text Claude wrote: read it before you send. - Other patches of the extension are not supported. The predecessor skill is refused while its hook is present; another tool's patch is refused or dropped by the next build.
| Situation | What to do instead |
|---|---|
| You use VS Code on macOS or desktop Linux (not a Remote-SSH window), or Cursor, Windsurf or Insiders, and want the context ring | vscode-claude-chat-context-meter, the predecessor: the ring alone, on any platform and in those editors |
| You may not modify installed extensions (a managed or shared machine) | nothing equivalent; ask Claude to run code <path>, which opens a file in a VS Code tab |
MIT — see LICENSE. © 2026 Daniel Orr.
An unofficial, independent project, not affiliated with or endorsed by Anthropic. "Claude" and "Claude Code" are Anthropic's marks; the extension this skill patches is theirs. No Anthropic code is distributed: the skill edits the copy already installed on your machine, keeps the original beside it, and the repository holds only short search patterns that find where to insert.
The composer button icons are glyphs of Codicons by Microsoft, licensed under CC BY 4.0, converted to SVG paths.
