No project description provided
Project description
uVSCEM
uVSCEM is a VS Code extension installer for restricted environments.
It helps when normal extension installation fails because of proxy issues, controlled outbound access, or air-gapped workflows. It can also export and import offline extension bundles.
What it does
- Reads extension IDs from your
devcontainer.json. - Downloads VSIX packages and marketplace signatures.
- Verifies extension signatures using
vsce-sign. - Installs extensions in a DevContainer-compatible way.
- Supports offline bundles (
exportandimport).
Requirements
- Python
3.10+ - VS Code CLI (
code) available in your environment - Access to your
devcontainer.json
Platform support
uVSCEM auto-detects common VS Code runtime environments and can fall back to local CLI discovery on macOS and Windows.
The primary tested target is still Linux, especially DevContainer and VS Code Remote (.vscode-server) environments.
Install
Pre-built binaries (since v1.0.4)
Self-contained binaries compiled with Nuitka with no Python requirement are available on the Releases page for the following platforms:
| Platform | File |
|---|---|
| Linux x64 | uvscem-linux-x64 |
| Linux arm64 | uvscem-linux-arm64 |
| macOS arm64 | uvscem-macos-arm64 |
| Windows x64 | uvscem-windows-x64 |
Download the binary for your platform, make it executable, and run it directly:
# Linux / macOS
chmod +x ./uvscem
./uvscem install --config-name ./devcontainer.json
macOS note: The binary is not code-signed. To remove the quarantine flag after downloading:
xattr -d com.apple.quarantine ./uvscem
Verifying binary integrity
Each release includes a checksums.sha256 file and per-binary Sigstore bundles (e.g. uvscem-linux-x64.bundle).
Verify the checksum:
sha256sum -c checksums.sha256 --ignore-missing
Verify the Sigstore signature (requires cosign):
cosign verify-blob \
--bundle uvscem-linux-x64.bundle \
--certificate-identity-regexp "https://github.com/macgeneral/uVSCEM/.*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
uvscem-linux-x64
Python package
pip install uvscem
You can also use uv or pipx if you prefer.
Quick start (DevContainer)
Add uVSCEM to your container image, then call it from postAttachCommand:
{
"postAttachCommand": "uvscem install --config-name /path/to/devcontainer.json"
}
This installs (and updates) extensions listed in your config each time the container is attached.
Commands
Install extensions directly:
uvscem install --config-name ./devcontainer.json
Pinning is supported in devcontainer.json using publisher.extension@version:
{
"customizations": {
"vscode": {
"extensions": [
"dbaeumer.vscode-eslint@3.0.10"
]
}
}
}
Export an offline bundle:
uvscem export --config-name ./devcontainer.json --bundle-path ./uvscem-offline-bundle
By default the bundle includes the vsce-sign binary for the current platform only. To bundle binaries for all platforms (useful when sharing the bundle across machines):
uvscem export --config-name ./devcontainer.json --vsce-sign-targets all
Or specify individual targets:
uvscem export --config-name ./devcontainer.json --vsce-sign-targets linux-x64,linux-arm64,darwin-arm64,win32-x64
Supported --vsce-sign-targets values: current (default), all, or a comma-separated list of linux-x64, linux-arm64, linux-arm, alpine-x64, alpine-arm64, darwin-x64, darwin-arm64, win32-x64, win32-arm64.
Import an offline bundle without network access:
uvscem import --bundle-path ./uvscem-offline-bundle --strict-offline
Optional manifest authenticity checks:
uvscem export --config-name ./devcontainer.json --manifest-signing-key YOUR_GPG_KEY_ID
uvscem import --bundle-path ./uvscem-offline-bundle --verify-manifest-signature
Proxy note
uVSCEM follows standard proxy environment variables such as HTTP_PROXY, HTTPS_PROXY, and NO_PROXY.
Environment variables
| Variable | Description |
|---|---|
UVSCEM_VSCODE_ROOT |
Override the VS Code data root (where extensions/ and extensions.json live). Useful when auto-detection resolves the wrong path on macOS or Windows. |
UVSCEM_RUNTIME |
Override the detected runtime environment. Accepted values: local, vscode-server, vscode-remote. |
HTTP_PROXY / HTTPS_PROXY / NO_PROXY |
Standard proxy variables respected by all HTTP requests. |
Example:
UVSCEM_VSCODE_ROOT="$HOME/.vscode" uvscem install --config-name ./devcontainer.json
Why this exists
uVSCEM is a practical workaround for known VS Code proxy/devcontainer limitations, including:
- https://github.com/microsoft/vscode/issues/12588
- https://github.com/microsoft/vscode/issues/29910
- https://github.com/orgs/devcontainers/discussions/94
Contributing
Development setup, testing, and release details are in CONTRIBUTING.md.
A big thank you to the following people
- Jossef Harush Kadouri for this GitHub Gist on how to query the undocumented VisualStudio Code Marketplace API, which I used as blueprint for
marketplace.py. - Ian McKellar for his blog post "VSCode Remote and the command line" (notable mention: Lazy Ren@Stackoverflow for this answer pointing me in this direction).
- Michael Petrov for this answer on StackOverflow on how to test if a socket is closed in python.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file uvscem-1.0.5.tar.gz.
File metadata
- Download URL: uvscem-1.0.5.tar.gz
- Upload date:
- Size: 97.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a87ebf6ef45c8a97a52b740fdac963528b80d376859f2b848fa9acf75dae8927
|
|
| MD5 |
233e1593c9d9dd70b8514af5ac4f9f7d
|
|
| BLAKE2b-256 |
0331cf6d6757efe58923b8ec6d30e6a60261745e88535d3898b76dc6624c4c8f
|
Provenance
The following attestation bundles were made for uvscem-1.0.5.tar.gz:
Publisher:
publish.yml on macgeneral/uVSCEM
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uvscem-1.0.5.tar.gz -
Subject digest:
a87ebf6ef45c8a97a52b740fdac963528b80d376859f2b848fa9acf75dae8927 - Sigstore transparency entry: 995767643
- Sigstore integration time:
-
Permalink:
macgeneral/uVSCEM@b4f98849f6e8b1243fb390beda29ef6396dae422 -
Branch / Tag:
refs/tags/v1.0.5 - Owner: https://github.com/macgeneral
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b4f98849f6e8b1243fb390beda29ef6396dae422 -
Trigger Event:
push
-
Statement type:
File details
Details for the file uvscem-1.0.5-py3-none-any.whl.
File metadata
- Download URL: uvscem-1.0.5-py3-none-any.whl
- Upload date:
- Size: 26.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
71ec1cb6b1197a752e00101782ef85907bfa3e395b71a2982ed98055f7747b1d
|
|
| MD5 |
e51154e412b550c35ec5022e57bb4cb6
|
|
| BLAKE2b-256 |
264979e37cef33ddaa652d10447735e349b6f9db52dea339799b15ea59c03434
|
Provenance
The following attestation bundles were made for uvscem-1.0.5-py3-none-any.whl:
Publisher:
publish.yml on macgeneral/uVSCEM
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uvscem-1.0.5-py3-none-any.whl -
Subject digest:
71ec1cb6b1197a752e00101782ef85907bfa3e395b71a2982ed98055f7747b1d - Sigstore transparency entry: 995767645
- Sigstore integration time:
-
Permalink:
macgeneral/uVSCEM@b4f98849f6e8b1243fb390beda29ef6396dae422 -
Branch / Tag:
refs/tags/v1.0.5 - Owner: https://github.com/macgeneral
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b4f98849f6e8b1243fb390beda29ef6396dae422 -
Trigger Event:
push
-
Statement type: