Socket's @socketaddon/* npm packages are published from this repo.
The GitHub Actions workflow here is the one authorized to push new
versions to npm. The native .node binaries themselves are built in
socket-btm; this repo only
takes finished binaries, verifies them, and publishes them.
The npm registry has a feature called trusted publishing: instead
of storing a long-lived npm token in CI secrets (which can leak), you
tell npm "the GitHub Actions workflow at <owner>/<repo> is allowed
to publish package X." When that workflow runs, it asks GitHub for a
short-lived OIDC token, presents it to npm, and npm verifies it
before accepting the publish.
Because trust is bound to one repo, we split build from publish:
- socket-btm builds NAPI addons and uploads them to GitHub Releases, with embedded SHA-256 checksums.
- socket-addon (this repo) downloads those binaries, verifies the
hashes, and is the only repo allowed to push to npm under the
@socketaddon/*scope.
Sister repo: socket-bin
does the same for @socketbin/* SEA-packed standalone binaries.
packages/
build-infra/ # shared helpers
lib/release-checksums/
core.mts # parse + hash + verify
consumer.mts # download from sibling GH releases
release-assets.json # which release tag we're on + per-asset SHA-256
release-assets.schema.json # JSON Schema validating the .json above
<tool>/ # umbrella package on npm (per tool)
<tool>-<platform>-<arch>/ # per-platform shims (per tool)
scripts/
publish.mts # orchestrator, driven by tools.json
tools.json # which tools to publish + their conventions
tools.schema.json # JSON Schema validating tools.json
For per-platform NAPI binaries, the umbrella + N per-platform packages
pattern is how Node-native modules ship: the umbrella declares each
per-platform package as optionalDependencies with os + cpu
constraints, and npm installs only the matching one. Consumers run
npm install @socketaddon/<tool> and get exactly the right binary.
release-checksums/ is the consumer half of a fleet-wide helper
trio (core + consumer + producer). The producer half lives in
socket-btm — it generates checksums.txt at build time. We only
need the consumer half here. The canonical copies are in
socket-wheelhouse;
sync-scaffolding flags drift.
tools.json is the registry of what this repo knows how to publish.
Adding a new tool: drop a new entry in tools.json, add a matching
block to packages/build-infra/release-assets.json, create the
per-platform package dirs under packages/. Removing one: delete
the key + matching dirs + (optionally) deprecate on npm via
npm deprecate <pkg>@"*" "<msg>".
-
socket-btm finishes a build and cuts a GitHub Release like
<tool>-YYYYMMDD-<short-sha>. The release contains N.nodebinaries (one per platform) plus achecksums.txtlisting the SHA-256 of each. -
Someone here updates
packages/build-infra/release-assets.jsonwith the new tag and the new per-asset SHA-256s. (The$schemapointer in that file makes editors autocomplete + flag typos.) -
Someone triggers the GitHub Actions workflow at
.github/workflows/provenance.yml. The workflow runsscripts/publish.mts, which:- Reads
tools.jsonto discover which tools to ship. - For each tool: reads the embedded SHA-256s from
release-assets.json. - Downloads each
.nodefrom socket-btm's GH Release. - Hashes the downloaded file and compares against the embedded SHA-256. Mismatch = abort the whole run, no packages published.
- Stages the per-platform package in
os.tmpdir()(so the working tree is never mutated), drops the verified.nodeinto the stage, and runspnpm publishfrom there. - Repeats per-platform across all tools, then publishes the
umbrella packages last (each umbrella's
optionalDependenciesreferences the per-platforms by exact version, so they have to land on npm first).
- Reads
If a checksum doesn't match, nothing publishes — fail-loudly.
tools.json is empty after the iocraft retirement. opentui,
ultraviolet, yoga-layout, and onnxruntime are slated to fill it as
socket-btm starts shipping releases for those. Adding each is a
mechanical follow-up:
- Drop a new entry in
tools.jsonfor the tool's shape. - Bump
packages/build-infra/release-assets.jsonwith the new tag + per-asset checksums. - Create the per-platform package directories under
packages/. - Open a PR; CI validates the schemas; once merged, dispatch the publish workflow.
pnpm install # install dependencies + run husky setup
pnpm run check # lint + type check
pnpm run lint # lint files modified vs HEAD
pnpm run lint --all # lint the whole workspace
pnpm run fix # auto-fix lint + format
pnpm run test # run vitest scoped to changes
pnpm run test --all # full vitest suite
pnpm run cover # vitest with coverage
pnpm run security # AgentShield + zizmor scans
pnpm run setup # download zizmor + sfw with sha256 verification
pnpm run update # bump dependencies (taze)
pnpm run publish:dry # stage + verify, but don't actually publish
pnpm run publish:ci # full publish — CI only, requires OIDC
pnpm run clean # remove caches
Several files in this repo are required to be byte-identical to their
counterparts in
socket-wheelhouse.
That includes our git hooks, Claude Code hooks + skills, lint config,
and the release-checksums/ files mentioned above.
To check drift:
node ../socket-wheelhouse/scripts/sync-scaffolding.mts --target . # socket-hook: allow cross-repo
To auto-fix drift:
node ../socket-wheelhouse/scripts/sync-scaffolding.mts --target . --fix # socket-hook: allow cross-repo
MIT (per published package).