skills/air-gapped/vscode/vscode-make-offline-installer/SKILL.md
Build a VS Code air-gapped "offline kit" for Remote-SSH: desktop VS Code installers/archives for Windows/macOS/Linux, matching VS Code Server+CLI tarballs for headless Linux (commit-aligned), and pinned extension .vsix bundles for both local (client) and remote (server) sides. Use when you need a reproducible offline deployment, or when you want to mirror the VS Code release+extensions currently installed on a host.
npx skillsauth add igamenovoer/magic-context vscode-make-offline-installerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Prepare an offline, reproducible bundle that lets:
This skill assumes Microsoft VS Code + Remote-SSH (not Coder "code-server").
This skill must be triggered manually by skill name (for example: vscode-make-offline-installer).
Do not auto-trigger this workflow based on “similar” requests; ask the user to explicitly invoke it.
CHANNEL (stable or insider), and COMMIT (required), plus optional VERSION, orTARGET_RELEASE=local-installed (agent discovers CHANNEL, VERSION, COMMIT, and local extensions)~/.vscode-server/.../Stable-<COMMIT>). If you target CHANNEL=insider, confirm the expected server paths for Insiders and adjust scripts/paths as needed.win32-x64-user, darwin-universal, linux-deb-x64)x64, arm64)--user <username> and defaults to the executing user.extensions_local: extension IDs + pinned versionsextensions_remote: extension IDs + pinned versionsextensions_local must include ms-vscode-remote.remote-sshusername@ip / username@hostname, or an SSH config host alias (e.g. myserver from ~/.ssh/config).bin/code-server) without needing any internet access.scripts/server/*.sh flow and sanity-check the extracted VS Code Server bin/code-server + remote extension installs.code-server or remote-side extension installs unless the user explicitly provides a testing environment (SSH host or Docker image/container) for this task.tar is available on the Linux server.COMMIT (build hash).ms-vscode-remote.remote-ssh to be installed locally from a .vsix.Remote-SSH boots a VS Code Server on the remote host. If the server for this exact
COMMITis missing, it normally downloads and extracts it during the first connection. In an air-gapped environment that download fails, so you must pre-place the tarballs/marker files and extracted server under~/.vscode-server/for the target user (the providedscripts/server/install-vscode-server-cache.shdoes this).
~/.vscode-server/vscode-cli-<COMMIT>.tar.gz.done~/.vscode-server/vscode-server.tar.gz~/.vscode-server/cli/servers/Stable-<COMMIT>/server/ extracted contentscode --install-extension <file.vsix>~/.vscode-server/.../bin/code-server --install-extension <file.vsix>Create a single folder you can copy via USB/NAS:
vscode-airgap-kit/
README.md # installation instructions for the selected client/server platforms (generated)
manifest/ # metadata + inventories (what this kit contains)
vscode.json # commit/channel + downloaded artifacts + sha256
vscode.local.json # optional: discovery export from a host (channel/version/commit)
extensions.local.txt # local-side extension id@version pins
extensions.remote.txt # remote-side extension id@version pins
clients/ # VS Code desktop installers/archives grouped by <os>-<arch>
win32-x64/ # Windows installers/archives (x64)
win32-arm64/ # Windows installers/archives (arm64)
darwin-universal/ # macOS packages (universal)
darwin-arm64/ # macOS packages (arm64)
linux-x64/ # Linux packages (x64): .deb/.rpm/.tar.gz
linux-arm64/ # Linux packages (arm64): .deb/.rpm/.tar.gz
server/ # VS Code Server + CLI artifacts for air-gapped Remote-SSH
linux-x64/ # vscode-server-linux-x64-<COMMIT>.tar.gz
linux-arm64/ # vscode-server-linux-arm64-<COMMIT>.tar.gz
alpine-x64/ # vscode-cli-alpine-x64-<COMMIT>.tar.gz
alpine-arm64/ # vscode-cli-alpine-arm64-<COMMIT>.tar.gz
extensions/ # offline extension bundles (.vsix)
local-win32-x64/ # local/UI side (Windows x64)
local-win32-arm64/ # local/UI side (Windows arm64)
local-darwin-universal/ # local/UI side (macOS universal)
local-darwin-arm64/ # local/UI side (macOS arm64)
local-linux-x64/ # local/UI side (Linux x64)
local-linux-arm64/ # local/UI side (Linux arm64)
remote-linux-x64/ # remote/extension-host side (Linux x64 servers)
remote-linux-arm64/ # remote/extension-host side (Linux arm64 servers)
scripts/ # helper install/config scripts to run in each environment
wan/ # run on WAN-connected prep host
client/ # run on air-gapped desktop client
server/ # copy+run on air-gapped headless Linux server
Manifest example: references/vscode-airgap-manifest.example.json
This skill ships scripts in 3 groups:
scripts/wan/discover-local-vscode.ps1 — detect installed VS Code channel/version/commit and export the local extension inventory.scripts/wan/download-vscode-artifacts.ps1 — download commit-pinned VS Code client installers/archives and the matching server+CLI tarballs into the kit, plus SHA256s.scripts/wan/download-vsix-bundle.ps1 — download pinned extension .vsix files for offline install (Open VSX first, Marketplace fallback) and write a report. Supports platform targeting (best-effort) via -TargetPlatform and skips extensions that have no compatible VSIX for that platform.scripts/wan/export-kit-readme-context.ps1 — export manifest/readme.context.json (inventory + snippets) to help the agent fill the kit README.md template manually; also stages scripts/client/ + scripts/server/ into the kit by default (disable via -NoStageScripts). This script does not generate the final README.md.aria2c is available on the host, the WAN download scripts prefer it for resumable downloads; otherwise they fall back to PowerShell HTTP downloads.scripts/client/install-vscode-client.ps1 — launch the offline installer (interactive by default; -Silent best-effort).scripts/client/install-vscode-client.sh — install the offline .deb via dpkg (recommended: a .deb in clients/linux-<arch>/).scripts/client/install-vscode-client-extensions.ps1scripts/client/install-vscode-client-extensions.shremote.SSH.localServerDownload):
scripts/client/configure-vscode-client.ps1scripts/client/configure-vscode-client.shscripts/client/cleanup-vscode-client.ps1scripts/client/cleanup-vscode-client.shscripts/server/install-vscode-server-cache.sh — pre-place the server/CLI cache files and extract the server for the target COMMIT.scripts/server/configure-vscode-server.sh — create data/Machine/settings.json (optional override) and touch the .ready marker.scripts/server/install-vscode-server-extensions.sh — install all .vsix in a folder into the remote extension host via code-server.scripts/server/cleanup-vscode-server.sh — remove cache tarballs and/or old extracted servers once you’ve verified Remote-SSH works.Default behavior (recommended): the install scripts accept explicit path/commit arguments, but those arguments are optional. When omitted, they auto-discover the kit root relative to the script location and use the default kit layout (clients/, extensions/, manifest/, server/). For Linux server scripts, --user defaults to the executing user.
Installation, configuration, and cleanup are intentionally split because they have different purposes and options.
When preparing vscode-airgap-kit/, copy the relevant script folders from this skill into vscode-airgap-kit/scripts/ so they travel with the offline packages.
Windows note (agent vs user):
.ps1, use one-off execution policy bypass, e.g. pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -File <script.ps1> ... (do not ask the user to change global ExecutionPolicy)..bat launcher next to each .ps1 so end users can run it without dealing with ExecutionPolicy/permission issues.If the user says to target the release currently used by the host, discover it first (do not guess).
Windows (PowerShell):
scripts/wan/discover-local-vscode.ps1 to export VERSION, COMMIT, and the local extension list:
pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -File scripts\\wan\\discover-local-vscode.ps1 -OutDir .\\manifestscripts\\wan\\discover-local-vscode.bat -OutDir .\\manifest.\\manifest\\vscode.local.json.\\manifest\\extensions.local.txtms-vscode-remote.remote-ssh is installed locally before exporting if the offline client must use Remote-SSH.macOS (Terminal):
/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code --version/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/bin/code-insiders --versioncode --list-extensions --show-versions > extensions.local.txtLinux (Terminal):
code --version (or code-insiders --version)code --list-extensions --show-versions > extensions.local.txtDerive CHANNEL from which binary is used (code = stable, code-insiders = insider). Keep COMMIT as the compatibility key for server downloads.
If the user does not specify client targets, assume the client target matches the host OS family + arch (even if the host is currently headless).
VERSION and COMMIT (match everything to COMMIT)On any machine that can install VS Code with internet, install the exact VS Code build you intend to deploy, then record:
code --version
Keep:
VERSION (example: 1.106.2)COMMIT (example: 1e3c50d64110be466c0b4a45222e81d2c9352888)If you must "standardize" across multiple client OSes, standardize on COMMIT (it is the real compatibility key for the server).
Download from the Microsoft update endpoint (commit-pinned):
https://update.code.visualstudio.com/commit:<COMMIT>/<PLATFORM>/<CHANNEL>
Common PLATFORM values:
win32-x64-user, win32-arm64-userdarwin-universal (recommended), darwin-arm64linux-x64, linux-arm64linux-deb-x64, linux-deb-arm64linux-rpm-x64, linux-rpm-arm64Save the downloaded files under clients/<os>-<arch>/ and record SHA256 hashes in manifest/vscode.json.
Suggested mapping (download platform → kit folder):
win32-x64-* → clients/win32-x64/win32-arm64-* → clients/win32-arm64/darwin-universal → clients/darwin-universal/darwin-arm64 → clients/darwin-arm64/linux-*-x64 → clients/linux-x64/linux-*-arm64 → clients/linux-arm64/Optional helper (WAN prep) to download commit-pinned artifacts and write manifest/vscode.json:
pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -File scripts\\wan\\download-vscode-artifacts.ps1 `
-Commit "<COMMIT>" -Channel stable -OutDir .\\vscode-airgap-kit `
-ClientPlatforms @("win32-x64-user","linux-deb-x64") `
-ServerArch @("x64","arm64")
Download the server tarballs (commit-pinned):
https://update.code.visualstudio.com/commit:<COMMIT>/server-linux-x64/<CHANNEL>
https://update.code.visualstudio.com/commit:<COMMIT>/server-linux-arm64/<CHANNEL>
Download the CLI tarballs (commit-pinned):
https://update.code.visualstudio.com/commit:<COMMIT>/cli-alpine-x64/<CHANNEL>
https://update.code.visualstudio.com/commit:<COMMIT>/cli-alpine-arm64/<CHANNEL>
Put them under:
server/linux-x64/ and server/linux-arm64/server/alpine-x64/ and server/alpine-arm64/.vsixPin versions first, then download the matching .vsix files.
Required client extension for SSH remote development:
ms-vscode-remote.remote-ssh (do not skip)Export the exact client-side extension versions:
code --list-extensions --show-versions > extensions.local.txtPlace downloaded .vsix files into:
extensions/local-<TARGET>/ (examples: extensions/local-win32-x64/, extensions/local-linux-x64/)If the user provided a testing environment for this task, prefer using it to produce extensions.remote.txt (this captures what actually ends up running remotely).
Option A (recommended): use the provided test environment to generate extensions.remote.txt
ssh <host> "~/.vscode-server/cli/servers/Stable-<COMMIT>/server/bin/code-server --list-extensions --show-versions" > extensions.remote.txt~/.vscode-server/cli/servers/Stable-<COMMIT>/server/bin/code-server --list-extensions --show-versions > extensions.remote.txtOption B (fallback): no test environment provided
id@version cannot be downloaded as a .vsix from Open VSX or Marketplace, pick the nearest older version than the local pin:
< the local version (semantic-version compare).scripts/wan/download-vsix-bundle.ps1, and when an item fails, decrement to the next older published version and retry until it succeeds.Place downloaded .vsix files into:
extensions/remote-linux-<arch>/ (examples: extensions/remote-linux-x64/, extensions/remote-linux-arm64/).vsix files (applies to both local + remote lists)Recommended pinning flow (do this on an online staging environment):
COMMIT) on a desktop staging machine.extensions.local.txt (client) and extensions.remote.txt (server).Downloading .vsix (preferred order):
ovsx get publisher.extension@<version> -o <file>.vsixscripts/wan/download-vsix-bundle.ps1):
https://marketplace.visualstudio.com/_apis/public/gallery/publishers/<publisher>/vsextensions/<name>/<version>/vspackagehttps://marketplace.visualstudio.com/_apis/public/gallery/publishers/<publisher>/vsextensions/<name>/<version>/vspackage?targetPlatform=<TARGET><TARGET> values: linux-x64, linux-arm64, win32-x64, win32-arm64, darwin-x64, darwin-arm64.Optional helper (Windows-friendly) to download pinned VSIX in bulk:
# Local (client/UI side), per target platform (best-effort; skips VSIX that don't exist for that platform):
pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -File scripts\\wan\\download-vsix-bundle.ps1 -InputList .\\manifest\\extensions.local.txt -OutDir .\\extensions\\local-win32-x64 -TargetPlatform win32-x64
pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -File scripts\\wan\\download-vsix-bundle.ps1 -InputList .\\manifest\\extensions.local.txt -OutDir .\\extensions\\local-linux-x64 -TargetPlatform linux-x64
# Remote (server/extension-host side), per target platform (Linux only):
pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -File scripts\\wan\\download-vsix-bundle.ps1 -InputList .\\manifest\\extensions.remote.txt -OutDir .\\extensions\\remote-linux-x64 -TargetPlatform linux-x64 -RequiredIds @()
Validate every .vsix is a ZIP (fast corruption check):
unzip -t file.vsix (Linux/macOS) orpython -c "import zipfile; zipfile.ZipFile('file.vsix').testzip()" (any)README.md template (recommended)Keep detailed install/runbook instructions in the kit output (not in this SKILL.md). This skill ships a Markdown template that the agent fills in as part of the run (no auto-generated final README).
Template:
references/kit-readme.template.md (edit this template to customize wording)Recommended workflow:
README.md.{{...}} placeholders using:
CHANNEL/COMMIT (and optional VERSION),clients/, server/, extensions/, and the staged scripts/ folder if included),manifest/ (for example vscode.json, vscode.local.json, extensions.*.txt, and VSIX download reports).<KitDir>/manifest/readme.context.json:pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -File scripts\\wan\\export-kit-readme-context.ps1 -KitDir .\\vscode-airgap-kit
Notes:
export-kit-readme-context.ps1 does not generate the final README.md; it only exports context to help fill the template and (by default) stages scripts/client/ and scripts/server/ into <KitDir>/scripts/. Use -NoStageScripts to skip staging.Only do verification if the user explicitly provided a test environment (SSH host or Docker image/container). Stage 1 is fully headless; Stage 2 (optional) is a user-driven VS Code GUI check performed while offline.
Verification stages:
Goal: prove the kit’s VS Code Server artifacts can be installed/extracted and the server-side code-server binary runs and can manage extensions.
scripts/server/install-vscode-server-cache.sh (cache placement + extraction)scripts/server/configure-vscode-server.sh (settings + readiness marker)scripts/server/install-vscode-server-extensions.sh (auto-detects from ./extensions/remote-linux-<arch>/ when present)<COMMIT>):COMMIT="<COMMIT>"
SERVER_BIN="$HOME/.vscode-server/cli/servers/Stable-$COMMIT/server/bin/code-server"
EXT_DIR="$HOME/.vscode-server/extensions"
test -x "$SERVER_BIN"
"$SERVER_BIN" -h
"$SERVER_BIN" --list-extensions --show-versions --extensions-dir "$EXT_DIR"
"$SERVER_BIN" --install-extension "/path/to/kit/extensions/remote-linux-<arch>/<some>.vsix" --force --extensions-dir "$EXT_DIR"
"$SERVER_BIN" --list-extensions --show-versions --extensions-dir "$EXT_DIR"
"$SERVER_BIN" -h to discover the correct flags, bind to 127.0.0.1, then probe with curl -I (or use SSH port-forwarding). Keep it on localhost and do not expose it publicly.Goal: validate the full Remote-SSH experience with the user’s VS Code desktop app, while the internet is disconnected (so any attempted downloads fail fast and are visible).
Agent preparation (do before asking the user to test):
code-server is runnable for the target COMMIT.ssh <host> 'echo ok' succeeds (from the user’s desktop if possible).username@host:port (and any key/password) needed to connect.scripts/server/install-vscode-server-extensions.sh using the kit’s ./extensions/remote-linux-<arch>/.User instructions (GUI-driven, but offline):
ms-vscode-remote.remote-ssh from ./extensions/local-<TARGET>/), and apply the kit’s client config (disable auto-updates + set remote.SSH.localServerDownload to off).COMMIT and does not attempt to download server bits.When you need to update VS Code (new COMMIT) and/or extension versions:
On the WAN prep host:
scripts/wan/download-vscode-artifacts.ps1 for the new commit and overwrite the kit (or produce a new kit folder).scripts/wan/download-vsix-bundle.ps1 for updated pinned extension lists.On the air-gapped client:
scripts/client/install-vscode-client.ps1 (Windows) or scripts/client/install-vscode-client.sh (Linux). If the kit layout is intact, you can omit the installer path and the script will auto-locate it relative to the script location.scripts/client/configure-vscode-client.ps1 or scripts/client/configure-vscode-client.sh (idempotent).scripts/client/install-vscode-client-extensions.ps1 or scripts/client/install-vscode-client-extensions.sh. If the kit layout is intact, you can omit the extensions dir and it will auto-detect ./extensions/local-<TARGET>/ relative to the script location (forces install).On the headless server:
scripts/server/install-vscode-server-cache.sh (keeps old extracted servers unless you later clean up). If the kit layout is intact, you can omit --commit and tarball paths and it will auto-detect from ./manifest/ and ./server/ relative to the script location.scripts/server/configure-vscode-server.sh (can auto-detect --commit from ./manifest/).scripts/server/install-vscode-server-extensions.sh (can auto-detect --commit, and defaults --extensions-dir to ./extensions/remote-linux-<arch>/ when present).scripts/server/cleanup-vscode-server.sh after verification.This section is based on real-world friction observed while mirroring a Windows host into an air-gapped kit.
aria2c (if installed): the WAN download scripts will automatically use it for resumable downloads; verify with Get-Command aria2c.*.tmp, *.part, *.aria2) and retries behave oddly, stop any stray pwsh processes that might still be downloading, then re-run with -Force (where supported).download-vscode-artifacts.ps1 errors: A positional parameter cannot be found that accepts argument 'arm64'pwsh -Command "& 'scripts\\wan\\download-vscode-artifacts.ps1' ... -ServerArch @('x64','arm64')" (so PowerShell parses the array expression reliably), or run it directly inside an interactive PowerShell session.Symptoms:
.vsix files but install fails or the script reports bad_file / required_bad_file.Actions:
%APPDATA%\\Code\\CachedExtensionVSIXs), if present.%USERPROFILE%\\.vscode\\extensions\\....Symptoms:
ms-vscode.cpptools, ms-dotnettools.csharp, charliermarsh.ruff).Actions:
pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -File scripts\\wan\\download-vsix-bundle.ps1 -InputList .\\manifest\\extensions.remote.txt -OutDir .\\extensions\\remote-linux-x64 -TargetPlatform linux-x64 -RequiredIds @()linux-arm64 for ARM servers.extension.vsixmanifest TargetPlatform and exclude win32-* / darwin-* when building extensions/remote-linux-<arch>/ for Linux.Symptoms:
code-server --install-extension ... takes a very long time.Actions:
extensions/remote-linux-<arch>/ from VSIX metadata (manifest-based), and reserve full remote installs for small validation sets or explicitly requested end-to-end verification.docker logs / docker top rather than complex shell pipelines./dev/null, grep, true) when running docker exec ... bash -lc "..."bash -lc "..." string.bash -lc command strings with nested quoting from PowerShell; prefer multiple smaller docker exec ... calls or write outputs to files under a bind-mounted kit directory.data-ai
Create readable Mermaid diagrams inside Markdown files. Use for flowcharts and sequence diagrams that must render cleanly in common Markdown renderers (e.g., GitHub) without horizontal scrolling. Covers fenced mermaid blocks, init/theme styling, label wrapping with <br/>, and sequenceDiagram layout rules (short IDs, wrapped labels, don’t break identifiers).
development
Manual invocation only; use only when the user explicitly requests `make-program-tutorial` by exact name, OR when the user asks to use a skill to create an SDK/API/library tutorial. Create a clear, reproducible, step-by-step tutorial for a specific API/SDK/library (or a set of functions/classes), with runnable examples, expected outputs, and basic troubleshooting.
testing
Use when the user wants to create a self-hosted, offline-installable Conda channel (mirror) containing a specific subset of packages using Pixi.
tools
Guides the agent to setup a new or existing Pixi environment for compiling C++ and CUDA code. It ensures the correct compilers, toolkits, and CMake configurations are in place for a robust user-space build.