Resolvers for external binary tools that Socket products call out to —
JREs, Bazel, Trivy, TruffleHog, cdxgen, and friends. Each tool gets its own
subdirectory exposing a resolveX() entry point that figures out where the
tool lives on this machine and hands back a typed pointer.
Socket products run on three kinds of hosts:
- Stock Node: the user installed our CLI from npm; nothing is bundled.
- smol Node: our SEA binary with a VFS payload carrying pre-staged tools.
- CI: a container with some tools on
PATHand others missing.
Every consumer used to hand-roll its own "find java" / "find bazel" code,
and got the precedence wrong in subtle ways (e.g. preferring PATH over the
bundled VFS copy, causing version drift). This module centralizes the search
order so every tool resolution behaves consistently.
Every resolver tries each source in order and returns the first that hits.
The lowercase token in parentheses is the value of source on the returned
Resolved<Tool> object — useful for telemetry and conditional logic.
- VFS (
'vfs') — bundled inside the smol Node binary's SEA payload. Always wins when present; the bytes were sealed at build time. Not all tools have a VFS tier — Bazel skips it because the right version is per-project (driven by.bazelversion), and a bundled global pin would always be wrong for someone. - Environment pointer (
'java-home'for JRE only) —JAVA_HOME-style env var pointing at a manually-installed copy. Only the JRE has one. - PATH (
'path') —which <tool>on the system PATH. Cheapest non-VFS tier; covers most CI containers. - Download (
'download') — fetch from upstream (GitHub release or official mirror). Opt-in: the caller passesdownloadIfMissingtoresolveX(). Without it, the resolver stops at PATH and returnsundefinedif nothing matches.
If every tier misses, resolveX() resolves to undefined. There are no
throws on "not found" — finding the absence is a valid outcome.
Every tool's directory holds the same five-file template:
| File | Purpose |
|---|---|
types.ts |
ResolvedX shape + XSource union |
asset-names.ts |
Per-platform release asset map + URL builder |
from-vfs.ts |
Tier 1 — extracts from smol binary's VFS |
from-path.ts |
Tier 3 — which <tool> |
from-download.ts |
Tier 4 — GitHub release fetch (per-tool wrapper around shared from-download.ts) |
resolve.ts |
Orchestrator: tries tiers in order, memoizes per option shape |
The JRE adds from-java-home.ts (tier 2) and detect-platform-arch.ts.
Bazel adds read-bazel-version-file.ts + resolve-asset-url.ts +
resolve-bazel-version.ts for .bazelversion lookup.
from-download.ts(this directory) —downloadToolArchive()anddownloadAndExtractTool(). Every per-toolfrom-download.tsis a thin wrapper around these. Returnsintegrity(SRIsha512-<base64>) on every call for trust-on-first-use pinning.manifest.ts— reader forexternal-tools.json(Socket's hand-maintained pin file). Used by CI workflows + sync scaffolding; the per-tool resolvers don't read it directly — callers pick which version/ integrity to pass intodownloadIfMissing.ResolvedToolIntegritytype — the canonical doc for theintegrity?field that appears on everyResolved<Tool>. Lives infrom-download.tsto keep the contract in one place.
resolveX() memoizes by option shape. Calling with no options and then
again with downloadIfMissing produces two distinct cache entries, so the
second call can fall through to the download tier even if the first
returned undefined. The cache is a process-lifetime Map; call
resetXResolution() to clear it (used by tests).
If a Socket product needs to shell out to a binary that isn't here yet:
- Copy any existing subdir (uv is a clean recent example) and rename.
- Wire the asset names in
asset-names.ts— point at the upstream release. - Decide whether VFS makes sense (project-pinned tools generally don't).
- Add an entry to
external-tools.jsonin each consuming repo. - Add a package.json export for each new source file (one export per file — the build's tree-shake-friendly default).
- Write a
README.mdfollowing the template in any sibling subdir.
dlx/binary-download— the actual download + integrity-verify primitive.archives/extract— the post-download untar/unzip step.smol/vfs— the SEA VFS binding (getSmolVfs()).