Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 74 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,50 @@ into the new version's section — see docs/releasing.md.

## [Unreleased]

### Removed (BREAKING — lands in v4.0)
## [4.0.0] — 2026-08-20

v4.0 is the three-modes release. What began as an agent-style tool that
patches installed packages in place now offers three deployment modes,
selected with `scan --mode <agent|vendored|hosted>` (each mode's detailed
entries follow below; per-ecosystem mechanics live in `docs/ecosystems.md`):

- **Agent mode** (the default, and the original behavior): `apply` patches
installed packages in place on the current machine — `node_modules/`,
site-packages, the cargo registry cache, and so on — tracked in the local
`.socket/` manifest and re-applied after installs by the hooks `setup`
configures. Requires socket-patch (and Socket API access, or pre-fetched
blobs) on every machine that installs dependencies.

- **Vendored mode** (`vendor`, or `scan --mode vendored`): ejects each
patched package into a committed
`.socket/vendor/<ecosystem>/<patch-uuid>/<artifact>` and rewires the
ecosystem's lockfile so the project consumes the vendored copy. After
committing, a fresh checkout builds with the patched dependency on
machines with no socket-patch installed and no Socket API access — fully
offline/airgap-friendly, and the strictest install flags (`npm ci`,
`--frozen-lockfile`, `--locked`, `--deploy`, …) verify the vendored
artifact like any other. A committed ledger records the verbatim original
lockfile fragments, so `vendor --revert` restores them byte-exactly.
Covered in v4.0: the whole npm family (npm, yarn classic, yarn berry
node-modules, pnpm, bun), pypi (uv, requirements, poetry, pdm, pipenv),
cargo, go, composer, gem, maven, and nuget.

- **Hosted mode** (`scan --mode hosted`, new in v4.0): rewrites lockfiles /
registry configs so ONLY the patched dependencies resolve to
Socket-hosted, integrity-pinned artifacts on patch.socket.dev — no
artifact bytes land in the repo and no CI changes are needed. The package
manager's own integrity checking pins the patched bytes (tamper fails the
native install), and re-runs are idempotent. Covered in v4.0: the npm
family (package-lock/shrinkwrap, pnpm — including Rush monorepos — yarn
classic, yarn berry, bun), pypi (requirements, uv), cargo, composer, gem,
nuget, maven (fail-closed version suffixing + Trusted Checksums), and
golang for references carrying a `goproxy` registry override (free tier;
otherwise Go stays vendored — see the documented NO-GO analysis).

All three modes feed VEX attestation, with a provenance marker per mode:
plain (agent), `(vendored)`, and `(redirected)` (hosted).

### Removed (BREAKING)

- **The `unlock` subcommand.** Folded into `repair`, which now deletes the
leftover `<.socket>/apply.lock` file as its final housekeeping step (skipped
Expand All @@ -40,13 +83,24 @@ into the new version's section — see docs/releasing.md.
always empty). The `lock_held` stderr hint now advises waiting /
`--lock-timeout` instead of pointing at the removed commands.

### Changed (BREAKING — lands in v4.0)
### Changed (BREAKING)

- **`--help` command order** is now workflow-first: `scan`, `apply`, `vex`,
`vendor`, `setup`, then `rollback`, `get`, `list`, `remove`, `repair`.

### Added

- **`get --mode <hosted|vendored|agent>` — per-advisory hosted/vendored
patching.** `get` (fetch/apply a single patch by CVE/GHSA id, patch UUID,
or package name) now honors the same mode selector as `scan`: hosted
rewrites lockfiles for just the selected patches through scan's redirect
engine verbatim; vendored routes through scan's vendor step with scan's
save-only download posture. CVE/GHSA fan-outs are narrowed to versions
actually installed (disk ∪ manifest, plus the lockfile inventory and
vendor ledger in hosted/vendored modes); when narrowing leaves nothing,
the new additive `not_installed` status reports it at exit 0. Exempt from
narrowing: UUID ids, exact-versioned purls, `--save-only`,
`--all-releases`, and the package-name path.
- **Hosted mode for Go (free tier).** `scan --mode hosted` now redirects
golang dependencies when the reference carries a `goproxy` registry
override: a fork-style
Expand Down Expand Up @@ -432,6 +486,24 @@ into the new version's section — see docs/releasing.md.

### Fixed

- **bun 1.4 lockfiles are accepted again.** bun 1.4.0 bumped `bun.lock`
`lockfileVersion` to 2 while leaving the emitted grammar unchanged; the
shared version gate refused everything but 1, so hosted and vendored
modes refused every lock written by bun ≥ 1.4
(`redirect_bun_lock_unsupported` / `vendor_lockfile_version_unsupported`).
The gate now accepts versions 1 and 2 and keeps failing closed on
anything else; new shared golden fixture `npm/bun/lock-v2` (the depscan
TS twin needs the matching acceptance + fixture sync).
- **gem: every coexisting installed copy is patched.** Bundler's scoped
`<engine>/<abi>/gems` and flat `gems/` stores can coexist under one
`BUNDLE_PATH` root, each holding a real copy of the same gem@version;
first-wins resolution patched one store and reported success while the
other bundler loaded pristine (vulnerable) bytes. `apply` now fans out
per copy (per-copy `Applied` events, each counted in `summary.applied`),
bundle-path roots are crawled in bundler precedence order, and
config-sourced roots are contained. The `gem_bundle_config_path_ignored`
warning also prints the skipped path verbatim instead of
backslash-escaped.
- **npm `@socketsecurity/socket-patch`: the `./schema` export is now built
at publish.** The subpath pointed at a gitignored `dist/` directory that
nothing built during release, so it shipped broken; a `prepack` script
Expand Down
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ members = [
resolver = "2"

[workspace.package]
version = "3.3.0"
version = "4.0.0"
edition = "2021"
license = "MIT"
repository = "https://github.com/SocketDev/socket-patch"

[workspace.dependencies]
socket-patch-core = { path = "crates/socket-patch-core", version = "=3.3.0" }
socket-patch-core = { path = "crates/socket-patch-core", version = "=4.0.0" }
clap = { version = "=4.5.60", features = ["derive", "env"] }
serde = { version = "=1.0.228", features = ["derive"] }
serde_json = { version = "=1.0.149", features = ["preserve_order"] }
Expand Down
13 changes: 12 additions & 1 deletion crates/socket-patch-cli/tests/e2e_hosted_production.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
//! | npm | `pkg:npm/minimist@1.2.2` | `80630680-4da6-45f9-bba8-b888e0ffd58c` | GHSA-xvch-5gv4-984h (CVE-2021-44906) |
//! | PyPI | `pkg:pypi/urllib3@1.26.18` | *any of three* (see [`PYPI_UUIDS`]) | GHSA-gm62-xv2j-4w53 &co |
//! | Cargo | `pkg:cargo/traitobject@0.1.1` | `cf2e6f58-d9fa-4096-9151-c34afa717f89` | GHSA-pp8r-vv2j-9j5v |
//! | gem | `pkg:gem/activestorage@6.0.3` | *any of* [`GEM_UUIDS`] (two today) | GHSA-m42x-37p3-fv5w (CVE-2020-8162), GHSA-w749-p3v6-hccq (CVE-2022-21831) |
//! | gem | `pkg:gem/activestorage@6.0.3` | *any of* [`GEM_UUIDS`] (four today) | GHSA-m42x-37p3-fv5w (CVE-2020-8162), GHSA-w749-p3v6-hccq (CVE-2022-21831), GHSA-9xrj-h377-fr87 (CVE-2026-33195), GHSA-r4mg-4433-c7g3 (CVE-2025-24293) |
//!
//! `docs/testing/hosted-production-e2e.md` explains how these were chosen and
//! how to re-pick one if it is ever withdrawn.
Expand Down Expand Up @@ -155,6 +155,17 @@ const GEM_UUIDS: &[&str] = &[
// checksum, carries the Socket patch header in the transformer, and every
// other file is byte-identical to stock rubygems 6.0.3.
"6c4141c5-1535-4fd2-9db1-b5f8e4834bdb",
// GHSA-9xrj-h377-fr87 / CVE-2026-33195 (disk_service.rb +
// disk_controller.rb + errors.rb), published 2026-08-20T16:14Z when
// production extended 6.0.3 with a third advisory. /patch/view blobs
// live-verified 2026-08-20: every touched file carries the Socket
// Community Patch header.
"eeb6bf9f-96c0-4963-a0f1-2e88f91f8b1a",
// GHSA-r4mg-4433-c7g3 / CVE-2025-24293 (image_processing_transformer.rb),
// published 2026-08-20T20:31Z — the fourth advisory, and the one the
// server-ranked selection now wires. /patch/view blobs live-verified
// 2026-08-20: carries the Socket Community Patch header.
"c1a1cd3c-b670-4e44-b4fa-1a63ecd42db6",
];

/// Header the patch service injects into patched npm / PyPI source files.
Expand Down
77 changes: 68 additions & 9 deletions crates/socket-patch-cli/tests/e2e_vendored_production.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
//! | npm | `pkg:npm/minimist@1.2.2` | `80630680-4da6-45f9-bba8-b888e0ffd58c` | `Socket Community Patch` header |
//! | PyPI | `pkg:pypi/urllib3@1.26.18` | *any of three* (see [`PYPI_UUIDS`]) | `Socket Community Patch` header |
//! | Cargo | `pkg:cargo/traitobject@0.1.1` | `cf2e6f58-d9fa-4096-9151-c34afa717f89` | advisory id `GHSA-pp8r-vv2j-9j5v` |
//! | gem | `pkg:gem/activestorage@6.0.3` | `15e960b5-f432-4b6c-b8aa-534a2b419323` | `Socket Community Patch` header |
//! | gem | `pkg:gem/activestorage@6.0.3` | *any of* [`GEM_PATCHES`] | `Socket Community Patch` header |
//!
//! # Ecosystem coverage notes (gaps, and one resolved gap)
//!
Expand Down Expand Up @@ -159,7 +159,40 @@ const CARGO_MARKER: &str = "GHSA-pp8r-vv2j-9j5v";
const GEM_PURL: &str = "pkg:gem/activestorage@6.0.3";
const GEM_NAME: &str = "activestorage";
const GEM_VERSION: &str = "6.0.3";
const GEM_UUID: &str = "15e960b5-f432-4b6c-b8aa-534a2b419323";
/// Any-of pin set for the gem leg: `(patch uuid, the file its diff marks)`.
/// Production has published several distinct free 6.0.3 patches (one per
/// advisory), the manifest holds one patch per PURL, and which one the
/// server-ranked resolver returns is a server-side ordering detail — so the
/// leg accepts any pinned patch and probes the marker file that PATCH
/// actually touches. When production publishes another acceptable 6.0.3
/// patch, verify its `/patch/view` blobs carry the marker and append it here
/// (and to the hosted suite's `GEM_UUIDS`).
const GEM_PATCHES: &[(&str, &str)] = &[
// GHSA-m42x-37p3-fv5w / CVE-2020-8162, from the 2026-08-18 catalog
// republish.
(
"15e960b5-f432-4b6c-b8aa-534a2b419323",
"lib/active_storage/service/s3_service.rb",
),
// GHSA-w749-p3v6-hccq / CVE-2022-21831, published 2026-08-19T21:19Z.
(
"6c4141c5-1535-4fd2-9db1-b5f8e4834bdb",
"lib/active_storage/transformers/image_processing_transformer.rb",
),
// GHSA-9xrj-h377-fr87 / CVE-2026-33195, published 2026-08-20T16:14Z
// (also touches disk_controller.rb + errors.rb; the service file is the
// marker probe).
(
"eeb6bf9f-96c0-4963-a0f1-2e88f91f8b1a",
"lib/active_storage/service/disk_service.rb",
),
// GHSA-r4mg-4433-c7g3 / CVE-2025-24293, published 2026-08-20T20:31Z —
// the one the server-ranked selection wires as of 2026-08-20.
(
"c1a1cd3c-b670-4e44-b4fa-1a63ecd42db6",
"lib/active_storage/transformers/image_processing_transformer.rb",
),
];

/// Header the patch service injects into patched npm / PyPI source files.
const PATCH_MARKER: &str = "Socket Community Patch";
Expand Down Expand Up @@ -706,7 +739,7 @@ async fn preflight_required_patches_are_published() {
(NPM_PURL, vec![NPM_UUID]),
(PYPI_PURL, PYPI_UUIDS.to_vec()),
(CARGO_PURL, vec![CARGO_UUID]),
(GEM_PURL, vec![GEM_UUID]),
(GEM_PURL, GEM_PATCHES.iter().map(|(u, _)| *u).collect()),
];

let mut failures: Vec<String> = Vec::new();
Expand Down Expand Up @@ -1828,14 +1861,40 @@ fn gem_bundler_vendored_install_proof() {
dump(&info)
);
let installed_dir = PathBuf::from(String::from_utf8_lossy(&info.stdout).trim());
let patched_file_rel = "lib/active_storage/service/s3_service.rb";
assert_pristine(&installed_dir.join(patched_file_rel), PATCH_MARKER, LEG);
let pristine = std::fs::read(installed_dir.join(patched_file_rel)).unwrap();
// Anti-vacuity over EVERY pinned patch's marker file: whichever patch the
// server-ranked resolver wires below, its target must start pristine.
// Capture the pristine bytes now, keyed by file, for the post-install
// byte-inequality probe.
let mut pristine_by_file = std::collections::HashMap::new();
for (_, file) in GEM_PATCHES {
assert_pristine(&installed_dir.join(file), PATCH_MARKER, LEG);
pristine_by_file
.entry(*file)
.or_insert_with(|| std::fs::read(installed_dir.join(file)).unwrap());
}
let gemfile_before = std::fs::read(proj.join("Gemfile")).unwrap();
let lock_before = std::fs::read(proj.join("Gemfile.lock")).unwrap();

let env_json = scan_vendored(&proj, &[]);
assert_download_uuid(&env_json, &[GEM_UUID], LEG);
let gem_uuids: Vec<&str> = GEM_PATCHES.iter().map(|(u, _)| *u).collect();
assert_download_uuid(&env_json, &gem_uuids, LEG);
// Which pinned patch did the resolver wire? The marker probes below are
// per-patch — each advisory's diff marks a different file.
let wired_uuid = env_json["download"]["patches"]
.as_array()
.cloned()
.unwrap_or_default()
.iter()
.filter_map(|p| p["uuid"].as_str())
.find(|u| gem_uuids.contains(u))
.expect("assert_download_uuid guarantees a pinned uuid is downloaded")
.to_string();
let patched_file_rel = GEM_PATCHES
.iter()
.find(|(u, _)| *u == wired_uuid)
.map(|(_, f)| *f)
.unwrap();
let pristine = pristine_by_file[patched_file_rel].clone();
assert_eq!(
env_json["download"]["failed"].as_u64().unwrap_or(99),
0,
Expand Down Expand Up @@ -1875,11 +1934,11 @@ fn gem_bundler_vendored_install_proof() {
);

// The committable artifact + the mandatory pair edit.
let copy_rel = format!(".socket/vendor/gem/{GEM_UUID}/{GEM_NAME}-{GEM_VERSION}");
let copy_rel = format!(".socket/vendor/gem/{wired_uuid}/{GEM_NAME}-{GEM_VERSION}");
assert_patched(
&proj
.join(&copy_rel)
.join("lib/active_storage/service/s3_service.rb"),
.join(patched_file_rel),
PATCH_MARKER,
LEG,
);
Expand Down
2 changes: 1 addition & 1 deletion docs/testing/hosted-production-e2e.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ from the child environment.
| npm | `pkg:npm/minimist@1.2.2` | `80630680-4da6-45f9-bba8-b888e0ffd58c` | GHSA-xvch-5gv4-984h / CVE-2021-44906 | all five npm-family legs |
| PyPI | `pkg:pypi/urllib3@1.26.18` | `de58c8b8-796c-4b6d-8a48-539b5563db76`, `26242e35-f867-4da8-8789-f0d2ea49e0f1`, `e828efa5-5c6d-43f3-9909-03f5ac232b98` | GHSA-38jv-5279-wg99, GHSA-2xpw-w6gg-jr37, GHSA-gm62-xv2j-4w53 | requirements.txt, uv.lock |
| Cargo | `pkg:cargo/traitobject@0.1.1` | `cf2e6f58-d9fa-4096-9151-c34afa717f89` | GHSA-pp8r-vv2j-9j5v | cargo sparse-registry leg |
| RubyGems | `pkg:gem/activestorage@6.0.3` | any of `15e960b5-f432-4b6c-b8aa-534a2b419323` (GHSA-m42x-37p3-fv5w / CVE-2020-8162), `6c4141c5-1535-4fd2-9db1-b5f8e4834bdb` (GHSA-w749-p3v6-hccq / CVE-2022-21831, published 2026-08-19) | see UUID column | bundler leg |
| RubyGems | `pkg:gem/activestorage@6.0.3` | any of `15e960b5-f432-4b6c-b8aa-534a2b419323` (GHSA-m42x-37p3-fv5w / CVE-2020-8162), `6c4141c5-1535-4fd2-9db1-b5f8e4834bdb` (GHSA-w749-p3v6-hccq / CVE-2022-21831, published 2026-08-19), `eeb6bf9f-96c0-4963-a0f1-2e88f91f8b1a` (GHSA-9xrj-h377-fr87 / CVE-2026-33195, published 2026-08-20), `c1a1cd3c-b670-4e44-b4fa-1a63ecd42db6` (GHSA-r4mg-4433-c7g3 / CVE-2025-24293, published 2026-08-20) | see UUID column | bundler leg |

urllib3 1.26.18 carries **three** distinct free patches, one per advisory. Which
one the resolver returns is a server-side ordering detail, so the suite accepts
Expand Down
2 changes: 1 addition & 1 deletion docs/testing/vendored-production-e2e.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ four every run and fails first with the offending PURL named.
| npm | `pkg:npm/minimist@1.2.2` | `80630680-4da6-45f9-bba8-b888e0ffd58c` | `Socket Community Patch` header |
| PyPI | `pkg:pypi/urllib3@1.26.18` | one of three (server-ordered) | `Socket Community Patch` header |
| Cargo | `pkg:cargo/traitobject@0.1.1` | `cf2e6f58-d9fa-4096-9151-c34afa717f89` | advisory id `GHSA-pp8r-vv2j-9j5v` |
| RubyGems | `pkg:gem/activestorage@6.0.3` | `15e960b5-f432-4b6c-b8aa-534a2b419323` | `Socket Community Patch` header |
| RubyGems | `pkg:gem/activestorage@6.0.3` | any of the `GEM_PATCHES` table (4 as of 2026-08-20 — see the hosted doc's UUID list; each patch marks a different file) | `Socket Community Patch` header |

If a required patch is withdrawn, update the catalog constants at the top of
`e2e_vendored_production.rs` **and** the table above (same procedure as the
Expand Down
2 changes: 1 addition & 1 deletion gem/socket-patch-bundler/socket-patch-bundler.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# sync with the workspace by `scripts/version-sync.sh`.
Gem::Specification.new do |s|
s.name = "socket-patch-bundler"
s.version = "3.3.0"
s.version = "4.0.0"
s.summary = "Bundler plugin that keeps socket-patch gem patches applied on every bundle install."
s.description = "Re-applies the gem patches recorded in a project's .socket/manifest.json on " \
"every `bundle install` (cached and fresh) by invoking the socket-patch CLI. " \
Expand Down
2 changes: 1 addition & 1 deletion gem/socket-patch/lib/socket_patch/launcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module Launcher
# Fallback version, used ONLY when the installed gem's version can't be read
# (e.g. running this file from a checkout). In a real `gem install` the
# download uses the installed gem's own version — see `version`.
VERSION = "3.3.0"
VERSION = "4.0.0"
REPO = "SocketDev/socket-patch"
BINARY = "socket-patch"

Expand Down
2 changes: 1 addition & 1 deletion gem/socket-patch/socket-patch.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# `scripts/version-sync.sh`.
Gem::Specification.new do |s|
s.name = "socket-patch"
s.version = "3.3.0"
s.version = "4.0.0"
s.summary = "CLI tool for applying security patches to dependencies."
s.description = "Launcher gem for the socket-patch CLI: downloads the prebuilt binary for the " \
"host platform from the matching GitHub release, verifies its SHA-256, caches " \
Expand Down
2 changes: 1 addition & 1 deletion npm/socket-patch-android-arm64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@socketsecurity/socket-patch-android-arm64",
"version": "3.3.0",
"version": "4.0.0",
"description": "socket-patch binary for Android ARM64",
"os": [
"android"
Expand Down
2 changes: 1 addition & 1 deletion npm/socket-patch-darwin-arm64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@socketsecurity/socket-patch-darwin-arm64",
"version": "3.3.0",
"version": "4.0.0",
"description": "socket-patch binary for macOS ARM64",
"os": [
"darwin"
Expand Down
2 changes: 1 addition & 1 deletion npm/socket-patch-darwin-x64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@socketsecurity/socket-patch-darwin-x64",
"version": "3.3.0",
"version": "4.0.0",
"description": "socket-patch binary for macOS x64",
"os": [
"darwin"
Expand Down
2 changes: 1 addition & 1 deletion npm/socket-patch-linux-arm-gnu/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@socketsecurity/socket-patch-linux-arm-gnu",
"version": "3.3.0",
"version": "4.0.0",
"description": "socket-patch binary for Linux ARM (glibc)",
"os": [
"linux"
Expand Down
2 changes: 1 addition & 1 deletion npm/socket-patch-linux-arm-musl/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@socketsecurity/socket-patch-linux-arm-musl",
"version": "3.3.0",
"version": "4.0.0",
"description": "socket-patch binary for Linux ARM (musl)",
"os": [
"linux"
Expand Down
2 changes: 1 addition & 1 deletion npm/socket-patch-linux-arm64-gnu/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@socketsecurity/socket-patch-linux-arm64-gnu",
"version": "3.3.0",
"version": "4.0.0",
"description": "socket-patch binary for Linux ARM64 (glibc)",
"os": [
"linux"
Expand Down
2 changes: 1 addition & 1 deletion npm/socket-patch-linux-arm64-musl/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@socketsecurity/socket-patch-linux-arm64-musl",
"version": "3.3.0",
"version": "4.0.0",
"description": "socket-patch binary for Linux ARM64 (musl)",
"os": [
"linux"
Expand Down
2 changes: 1 addition & 1 deletion npm/socket-patch-linux-ia32-gnu/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@socketsecurity/socket-patch-linux-ia32-gnu",
"version": "3.3.0",
"version": "4.0.0",
"description": "socket-patch binary for Linux ia32 (glibc)",
"os": [
"linux"
Expand Down
2 changes: 1 addition & 1 deletion npm/socket-patch-linux-ia32-musl/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@socketsecurity/socket-patch-linux-ia32-musl",
"version": "3.3.0",
"version": "4.0.0",
"description": "socket-patch binary for Linux ia32 (musl)",
"os": [
"linux"
Expand Down
Loading
Loading