From 455bda53e897b48e68a1d739519ed71f3d47dd8d Mon Sep 17 00:00:00 2001 From: jdalton Date: Tue, 5 May 2026 15:15:42 -0700 Subject: [PATCH 1/4] chore(ci): cascade socket-registry pin to 51f34ffb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the four workflow files (ci.yml, generate.yml, provenance.yml, weekly-update.yml) to socket-registry@51f34ffb. That commit includes: - 4c4b12cc — pnpm 11.0.6 GA + Rust toolchain pin for Node 26 Temporal + SRI integrity migration in external-tools.json - e5f83c31 — wire updating-xport into the umbrella drift flow - 51f34ffb — release-workflow-guard quote-mask false-positive fix Bumps from main's @85a2fc0d, skipping the @4c4b12cc step since the sdk hadn't cascaded since. --- .github/workflows/ci.yml | 2 +- .github/workflows/generate.yml | 6 +++--- .github/workflows/provenance.yml | 2 +- .github/workflows/weekly-update.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b430cd4b..d635821f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,6 +21,6 @@ concurrency: jobs: ci: name: Run CI Pipeline - uses: SocketDev/socket-registry/.github/workflows/ci.yml@85a2fc0d33af6304246620365de3e7f053035a8d # main + uses: SocketDev/socket-registry/.github/workflows/ci.yml@51f34ffb69c5d38614a16078793af662b0cea38d # main with: test-script: 'pnpm run test --all --skip-build' diff --git a/.github/workflows/generate.yml b/.github/workflows/generate.yml index b4534c3e..b47fc003 100644 --- a/.github/workflows/generate.yml +++ b/.github/workflows/generate.yml @@ -46,14 +46,14 @@ jobs: echo "Sleeping for $delay seconds..." sleep $delay - - uses: SocketDev/socket-registry/.github/actions/setup-and-install@85a2fc0d33af6304246620365de3e7f053035a8d # main + - uses: SocketDev/socket-registry/.github/actions/setup-and-install@51f34ffb69c5d38614a16078793af662b0cea38d # main - name: Configure push credentials env: GH_TOKEN: ${{ github.token }} run: git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git" - - uses: SocketDev/socket-registry/.github/actions/setup-git-signing@85a2fc0d33af6304246620365de3e7f053035a8d # main + - uses: SocketDev/socket-registry/.github/actions/setup-git-signing@51f34ffb69c5d38614a16078793af662b0cea38d # main with: gpg-private-key: ${{ secrets.BOT_GPG_PRIVATE_KEY }} @@ -145,5 +145,5 @@ jobs: > \`\`\` EOF - - uses: SocketDev/socket-registry/.github/actions/cleanup-git-signing@85a2fc0d33af6304246620365de3e7f053035a8d # main + - uses: SocketDev/socket-registry/.github/actions/cleanup-git-signing@51f34ffb69c5d38614a16078793af662b0cea38d # main if: always() diff --git a/.github/workflows/provenance.yml b/.github/workflows/provenance.yml index ecf5df13..d0a626c2 100644 --- a/.github/workflows/provenance.yml +++ b/.github/workflows/provenance.yml @@ -25,7 +25,7 @@ jobs: permissions: contents: write # To create GitHub releases id-token: write # For npm trusted publishing via OIDC - uses: SocketDev/socket-registry/.github/workflows/provenance.yml@85a2fc0d33af6304246620365de3e7f053035a8d # main + uses: SocketDev/socket-registry/.github/workflows/provenance.yml@51f34ffb69c5d38614a16078793af662b0cea38d # main with: debug: ${{ inputs.debug }} dist-tag: ${{ inputs.dist-tag }} diff --git a/.github/workflows/weekly-update.yml b/.github/workflows/weekly-update.yml index 1112eaed..9448e220 100644 --- a/.github/workflows/weekly-update.yml +++ b/.github/workflows/weekly-update.yml @@ -10,7 +10,7 @@ permissions: jobs: weekly-update: - uses: SocketDev/socket-registry/.github/workflows/weekly-update.yml@85a2fc0d33af6304246620365de3e7f053035a8d # main + uses: SocketDev/socket-registry/.github/workflows/weekly-update.yml@51f34ffb69c5d38614a16078793af662b0cea38d # main with: test-setup-script: 'pnpm run build' test-script: 'pnpm test' From b01528aea81bdc78d8bd4f21cbd044dc08e17319 Mon Sep 17 00:00:00 2001 From: jdalton Date: Tue, 5 May 2026 15:16:01 -0700 Subject: [PATCH 2/4] =?UTF-8?q?chore(deps):=20drift=20updates=20from=20#63?= =?UTF-8?q?0=20=E2=80=94=20pnpm=20catalog=20+=20scripts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - external-tools.json — SRI integrity migration (sha256 → integrity) matches socket-registry's external-tools schema - package.json + pnpm-lock.yaml + pnpm-workspace.yaml — catalog alignment with @socketsecurity/lib + @socketregistry/* fleet - scripts/power-state.mts — fleet-canonical helper sync from socket-repo-template@c23dfef - scripts/publish.mts — pnpm-publish + --ignore-scripts staged-copy + os.tmpdir() staging refresh - scripts/xport-{schema,emit-schema}.mts — drift sync Splits content out of #630, paired with the cascade SHA bump in the commit before this one. --- external-tools.json | 14 +-- package.json | 10 ++- pnpm-lock.yaml | 44 ++++++++- pnpm-workspace.yaml | 16 ++++ scripts/power-state.mts | 165 ++++++++++++++++++++++++++++++++++ scripts/publish.mts | 144 +++++++++++++++++++++++------ scripts/xport-emit-schema.mts | 12 +++ scripts/xport-schema.mts | 2 +- 8 files changed, 365 insertions(+), 42 deletions(-) create mode 100644 scripts/power-state.mts diff --git a/external-tools.json b/external-tools.json index 06ef8a73..a3c36c59 100644 --- a/external-tools.json +++ b/external-tools.json @@ -22,7 +22,7 @@ }, "pnpm": { "description": "pnpm — the fleet's package manager.", - "version": "11.0.0-rc.5", + "version": "11.0.0", "packageManager": "pnpm", "repository": "github:pnpm/pnpm", "release": "asset", @@ -34,27 +34,27 @@ "checksums": { "darwin-arm64": { "asset": "pnpm-darwin-arm64.tar.gz", - "sha256": "32a50710ccacfdcf14e6d5995d5368298eec913b0ce3903b9e09b6555f06f4e5" + "sha256": "3620a0fcaf81ecd3aaeccd5965919d90dbc913f4d07a96e11e7cafc2c785054b" }, "darwin-x64": { "asset": "pnpm-darwin-x64.tar.gz", - "sha256": "71dca33f4275da6b43bf1eb40bdc4d876f59a116716eacbf01079c3d985ff85d" + "sha256": "1701748b75187f1333a9c616827943ff84ff46cc42becc156ff6864b9bd0f948" }, "linux-arm64": { "asset": "pnpm-linux-arm64.tar.gz", - "sha256": "2dd04127ff10b1f9dd20bae248b779c77a8ec67e3afa35e7256e5f94abddd493" + "sha256": "1e6d87ebfd7ff169966ff5b3ad71b780b883c68d3e59987df1096dfd8853df75" }, "linux-x64": { "asset": "pnpm-linux-x64.tar.gz", - "sha256": "7ebef4b616ba41fb0d54a207b36508fae3346723283a088b43fc1e038ee6fed0" + "sha256": "9b44acc77ada40fc41b665fde1d57367a5ebec31bd4b1b00598daed195da3e17" }, "win-arm64": { "asset": "pnpm-win32-arm64.zip", - "sha256": "e4a39ad4c251db5e34b18b98561ef25bab5506ad65cad2fa3602af58d1972667" + "sha256": "0746be8e98ca183078d0747559f0cbbd30a13a53eb177f67474eb3c52dc21bc8" }, "win-x64": { "asset": "pnpm-win32-x64.zip", - "sha256": "147485ae2f38c3d1ccf2f5db00d0244416bcd22b9114c02388e6a78f41538fc4" + "sha256": "581e222e622cd0cc4f0ac5f85dd0db76b65117e3b17507979d89e63fdc68edca" } } }, diff --git a/package.json b/package.json index 586274d1..55721e56 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,10 @@ "description": "SDK for the Socket API client", "homepage": "https://github.com/SocketDev/socket-sdk-js", "license": "MIT", + "publishConfig": { + "access": "public", + "provenance": true + }, "author": { "name": "Socket Inc", "email": "eng@socket.dev", @@ -73,7 +77,7 @@ "@babel/traverse": "7.26.4", "@babel/types": "7.26.3", "@oxlint/migrate": "1.52.0", - "@socketsecurity/lib": "5.25.1", + "@socketsecurity/lib": "5.26.1", "@sveltejs/acorn-typescript": "1.0.8", "@types/babel__traverse": "7.28.0", "@types/node": "24.9.2", @@ -111,7 +115,7 @@ }, "engines": { "node": ">=18.20.8", - "pnpm": ">=11.0.0-rc.0" + "pnpm": ">=11.0.0" }, - "packageManager": "pnpm@11.0.0-rc.5" + "packageManager": "pnpm@11.0.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d33e9e50..e7e73631 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -52,6 +52,15 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +catalogs: + default: + '@socketsecurity/lib': + specifier: 5.25.1 + version: 5.25.1 + '@types/node': + specifier: 24.9.2 + version: 24.9.2 + overrides: defu: '>=6.1.7' vite: 7.3.2 @@ -82,8 +91,8 @@ importers: specifier: 0.34.49 version: 0.34.49 '@socketsecurity/lib': - specifier: 5.25.1 - version: 5.25.1(typescript@5.9.3) + specifier: 5.26.1 + version: 5.26.1(typescript@5.9.3) '@sveltejs/acorn-typescript': specifier: 1.0.8 version: 1.0.8(acorn@8.15.0) @@ -154,6 +163,16 @@ importers: specifier: 4.0.3 version: 4.0.3(@types/node@24.9.2)(jiti@2.6.1)(yaml@2.8.3) + .claude/hooks/auth-rotation-reminder: + dependencies: + '@socketsecurity/lib': + specifier: 'catalog:' + version: 5.25.1(typescript@5.9.3) + devDependencies: + '@types/node': + specifier: 'catalog:' + version: 24.9.2 + .claude/hooks/check-new-deps: dependencies: '@socketregistry/packageurl-js': @@ -170,6 +189,12 @@ importers: specifier: 24.9.2 version: 24.9.2 + .claude/hooks/logger-guard: + devDependencies: + '@types/node': + specifier: 'catalog:' + version: 24.9.2 + .claude/hooks/path-guard: {} .claude/hooks/private-name-guard: @@ -190,6 +215,8 @@ importers: specifier: 24.9.2 version: 24.9.2 + .claude/hooks/stale-process-sweeper: {} + .claude/hooks/token-guard: {} packages: @@ -1273,6 +1300,15 @@ packages: typescript: optional: true + '@socketsecurity/lib@5.26.1': + resolution: {integrity: sha512-ppyhOC/vPBY0gZVRtzNpmf/8nodILERmNV8J62pzVo7GvAB9S1q0/k/vSF2tor2NJEDtim+m6N+J5qtQ0mR99A==} + engines: {node: '>=22', pnpm: '>=11.0.0-rc.0'} + peerDependencies: + typescript: '>=5.0.0' + peerDependenciesMeta: + typescript: + optional: true + '@socketsecurity/sdk@4.0.1': resolution: {integrity: sha512-fe3DQp2dFwhc0G6Za36GIMSV+QaPAP5L96K3ZOtywt9nhbwxc9IQwqzdOVztdn5Rbez3t9EHU9Esj24/hWdP0g==} engines: {node: '>=18.20.8', pnpm: '>=11.0.0-rc.0'} @@ -3001,6 +3037,10 @@ snapshots: optionalDependencies: typescript: 5.9.3 + '@socketsecurity/lib@5.26.1(typescript@5.9.3)': + optionalDependencies: + typescript: 5.9.3 + '@socketsecurity/sdk@4.0.1': {} '@standard-schema/spec@1.1.0': {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index b8a1c8ba..5a73c388 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,6 +1,13 @@ loglevel: error trustPolicy: no-downgrade +# Catalog: shared dependency versions referenced as "catalog:" in +# package.json. Hooks under .claude/hooks/* declare their deps via +# `catalog:` so they stay in lockstep with the root workspace. +catalog: + '@socketsecurity/lib': 5.25.1 + '@types/node': 24.9.2 + # Register .claude/hooks/* as workspace packages so taze (run via # `pnpm run update`) sees and bumps their package.json manifests # alongside the root. Keeps hook deps in lockstep with the main tree. @@ -38,6 +45,15 @@ minimumReleaseAgeExclude: - '@socketregistry/*' - '@socketsecurity/*' +# Refuse transitive dependencies declared via git/tarball/local-tarball +# specs — an npm package shouldn't be allowed to drag in a git URL we +# don't control (bypasses npm registry validation, no provenance, no +# soak window). Direct git deps are still allowed (the test suite at +# pnpm/pkg-manager/core/test/install/blockExoticSubdeps.ts confirms +# this). pnpm's current default is `false`; declared explicitly so a +# future flip can't silently change install behavior. +blockExoticSubdeps: true + # Pin exact versions on `pnpm add`. Catalog and overrides should # also be exact pins (5.24.0, not ^5.24.0). saveExact: true diff --git a/scripts/power-state.mts b/scripts/power-state.mts new file mode 100644 index 00000000..2d327006 --- /dev/null +++ b/scripts/power-state.mts @@ -0,0 +1,165 @@ +/** + * @fileoverview Detect whether the host is currently on AC power + * (vs battery). Used by long-running build/test scripts to size + * timeouts adaptively — laptops on battery throttle CPU hard + * (especially macOS), and a static timeout that fits AC will kill + * an otherwise-healthy run on battery. + * + * Two paths, in priority order: + * + * 1. `node:smol-power` — when running inside a node-smol binary + * that ships the smol_power native binding (socket-btm's custom + * Node distribution). Pure C++ syscalls, sub-millisecond. + * + * 2. Shellout fallback — system Node doesn't have node:smol-power. + * Each platform has a different mechanism: + * * macOS: `pmset -g batt` parses "AC Power" / "Battery Power" + * * Linux: reads /sys/class/power_supply//online + * (no shellout, just open/read syscalls) + * * Windows: PowerShell `Get-CimInstance Win32_Battery` + * + * On detection failure we conservatively assume AC — the downstream + * timeout becomes the shorter / more aggressive value, which is + * appropriate for build servers and headless CI (those environments + * are expected to run at full speed). + * + * Returns a Promise so callers don't block the event loop on shellout + * paths. + * + * Byte-identical across the fleet via socket-repo-template's + * sync-scaffolding (IDENTICAL_FILES). + */ + +import { existsSync, promises as fs } from 'node:fs' +import path from 'node:path' +import process from 'node:process' + +import { spawn } from '@socketsecurity/lib/spawn' + +// Probe for node:smol-power. Lives in socket-btm's node-smol binary. +// Wrapped in try/catch so this file is safe to import on system Node +// where the module doesn't exist. +let _smolPower: { isOnAcPower: () => boolean } | undefined +async function getSmolPower(): Promise { + if (_smolPower !== undefined) { + return _smolPower + } + try { + const mod = await import('node:smol-power') + _smolPower = mod + return _smolPower + } catch { + _smolPower = undefined + return undefined + } +} + +async function detectMacOs(): Promise { + try { + // `pmset -g batt` on macOS prints lines like + // Now drawing from 'AC Power' + // Now drawing from 'Battery Power' + // Match the AC variant; everything else (battery, unknown) is + // treated as not-AC. + const result = await spawn('pmset', ['-g', 'batt'], { + stdio: ['ignore', 'pipe', 'ignore'], + }) + return /AC Power/.test(result.stdout || '') + } catch { + return true + } +} + +async function detectLinux(): Promise { + // Linux exposes power state under /sys/class/power_supply. Each + // AC adapter is its own dir (`AC`, `ADP1`, `AC0`, `ACAD`, …) + // with an `online` file holding "1" when power is connected. + // Containers and headless servers often have no power_supply + // tree at all — treat that as AC since those environments are + // expected to run at full speed. + const psDir = '/sys/class/power_supply' + if (!existsSync(psDir)) { + return true + } + try { + const entries = await fs.readdir(psDir) + for (const entry of entries) { + const onlineFile = path.join(psDir, entry, 'online') + if (!existsSync(onlineFile)) { + continue + } + try { + const value = await fs.readFile(onlineFile, 'utf8') + if (value.trim() === '1') { + return true + } + } catch { + // Unreadable entry — skip; another entry may report. + } + } + } catch { + // Directory enumeration failed — fall through to AC. + return true + } + return false +} + +async function detectWindows(): Promise { + try { + // Windows: query the battery status via PowerShell + CIM. + // `Win32_Battery.BatteryStatus`: + // 1 = Discharging (battery) + // 2 = On AC, not charging or fully charged + // 3..5 = Various battery states + // 6 = AC + charging + // Desktops with no battery return an empty result; treat as AC. + const result = await spawn( + 'powershell.exe', + [ + '-NoProfile', + '-Command', + '(Get-CimInstance -ClassName Win32_Battery).BatteryStatus', + ], + { stdio: ['ignore', 'pipe', 'ignore'] }, + ) + const trimmed = (result.stdout || '').trim() + if (trimmed === '') { + return true + } + const status = Number.parseInt(trimmed, 10) + if (Number.isNaN(status)) { + return true + } + return status === 2 || status === 6 + } catch { + return true + } +} + +/** + * Returns `true` if the host is on AC power. Conservative on + * detection failure (returns `true`) — callers using this for + * timeout sizing prefer a longer timeout to a too-short one. + * + * Prefers the native binding (`node:smol-power`) when running + * inside a node-smol binary; falls back to a per-platform path + * (shellout on macOS / Windows, direct sysfs reads on Linux) on + * system Node. + */ +export async function isOnAcPower(): Promise { + const native = await getSmolPower() + if (native) { + return native.isOnAcPower() + } + if (process.platform === 'darwin') { + return await detectMacOs() + } + if (process.platform === 'linux') { + return await detectLinux() + } + if (process.platform === 'win32') { + return await detectWindows() + } + // Unsupported platform; conservative default. + return true +} diff --git a/scripts/publish.mts b/scripts/publish.mts index a4a880bd..8c61e49f 100644 --- a/scripts/publish.mts +++ b/scripts/publish.mts @@ -6,11 +6,13 @@ import { spawn } from 'node:child_process' import { existsSync, promises as fs } from 'node:fs' +import os from 'node:os' import path from 'node:path' import process from 'node:process' import { fileURLToPath } from 'node:url' import { parseArgs } from '@socketsecurity/lib/argv/parse' +import { safeDelete, safeDeleteSync } from '@socketsecurity/lib/fs' import { getDefaultLogger } from '@socketsecurity/lib/logger' const logger = getDefaultLogger() @@ -244,6 +246,41 @@ interface PublishOptions { tag?: string } +/** + * Stage the publishable files into a fresh os.tmpdir() subdir and + * return its path. The staged copy is what `npm publish` is invoked + * against — the working tree is never mutated. Cleanup is the + * caller's responsibility (use `safeDelete()` in a finally block; + * SIGINT/SIGTERM handlers should `safeDeleteSync()`). + * + * The filter respects the package's `files` array implicitly by + * letting `npm publish` itself enforce inclusion — staging copies + * everything except node_modules/lockfile/dotfile noise. npm reads + * the staged package.json's `files` field for the actual publish + * manifest. + */ +async function stageForPublish(): Promise { + const stageRoot = await fs.mkdtemp( + path.join(os.tmpdir(), `socket-sdk-publish-${process.pid}-`), + ) + await fs.cp(rootPath, stageRoot, { + recursive: true, + dereference: true, + filter: src => { + const base = path.basename(src) + return ( + base !== 'node_modules' && + base !== '.git' && + base !== '.gitignore' && + base !== '.gitkeep' && + !base.startsWith('.pnpm') && + base !== 'pnpm-lock.yaml' + ) + }, + }) + return stageRoot +} + /** * Publish a single package. */ @@ -267,42 +304,91 @@ async function publishPackage(options: PublishOptions = {}): Promise { } log.done('Version check complete') - // Prepare publish args. - const publishArgs = ['publish', '--access', access, '--tag', tag] - - // Add provenance attestation in CI only. `npm publish --provenance` - // requires the GitHub Actions OIDC id-token endpoint; running locally - // fails with "Provenance generation in GitHub Actions requires - // 'id-token: write' permission". Gated so local non-dry-run publishes - // (emergency cases) still work. - if (!dryRun && process.env['GITHUB_ACTIONS'] === 'true') { - publishArgs.push('--provenance') + // Stage to os.tmpdir() so the working tree never mutates during + // publish. If a hook (or the operator's signal) interrupts mid- + // publish, `git status` stays clean and the tmpdir is reaped on + // the next exit. + log.progress('Staging package contents') + const stageRoot = await stageForPublish() + + // SIGINT/SIGTERM handlers reap the staging dir synchronously + // because the Node event loop unwinds before async work settles + // when terminating. Idempotent — multiple registrations are fine. + const cleanup = (): void => { + try { + safeDeleteSync(stageRoot) + } catch { + /* swallow during teardown */ + } } + process.once('SIGINT', () => { + log.warn('SIGINT — cleaning up staging root') + cleanup() + process.exit(130) + }) + process.once('SIGTERM', () => { + log.warn('SIGTERM — cleaning up staging root') + cleanup() + process.exit(143) + }) + log.done(`Staged to ${stageRoot}`) - if (dryRun) { - publishArgs.push('--dry-run') - } + try { + // Prepare publish args. + const publishArgs = [ + 'publish', + '--access', + access, + '--tag', + tag, + // The staged tmpdir has no git history; --no-git-checks tells + // pnpm not to require a clean working tree there. + '--no-git-checks', + // The staged copy is what we're authorizing to ship; the + // prepublishOnly guard in package.json is meant to refuse + // *direct* `pnpm publish` runs from the working tree, not + // this orchestrated tmpdir publish. + '--ignore-scripts', + ] + + // Add provenance attestation in CI only. `pnpm publish + // --provenance` requires the GitHub Actions OIDC id-token + // endpoint; running locally fails with "Provenance generation in + // GitHub Actions requires 'id-token: write' permission". Gated + // so local non-dry-run publishes (emergency cases) still work. + if (!dryRun && process.env['GITHUB_ACTIONS'] === 'true') { + publishArgs.push('--provenance') + } - if (otp) { - publishArgs.push('--otp', otp) - } + if (dryRun) { + publishArgs.push('--dry-run') + } - // Publish. - log.progress(dryRun ? 'Running dry-run publish' : 'Publishing to npm') - const publishCode = await runCommand('npm', publishArgs) + if (otp) { + publishArgs.push('--otp', otp) + } - if (publishCode !== 0) { - log.failed('Publish failed') - return false - } + // Publish from the staged copy, not the working tree. + log.progress(dryRun ? 'Running dry-run publish' : 'Publishing to npm') + const publishCode = await runCommand('pnpm', publishArgs, { + cwd: stageRoot, + }) - if (dryRun) { - log.done('Dry-run publish complete') - } else { - log.done(`Published ${packageName}@${version} to npm`) - } + if (publishCode !== 0) { + log.failed('Publish failed') + return false + } - return true + if (dryRun) { + log.done('Dry-run publish complete') + } else { + log.done(`Published ${packageName}@${version} to npm`) + } + + return true + } finally { + await safeDelete(stageRoot) + } } interface PushTagOptions { diff --git a/scripts/xport-emit-schema.mts b/scripts/xport-emit-schema.mts index 5bc6a1e6..a0d4e93b 100644 --- a/scripts/xport-emit-schema.mts +++ b/scripts/xport-emit-schema.mts @@ -12,6 +12,7 @@ import { writeFileSync } from 'node:fs' import path from 'node:path' import { fileURLToPath } from 'node:url' +import { spawn } from '@socketsecurity/lib/spawn' import { getDefaultLogger } from '@socketsecurity/lib/logger' import { XportManifestSchema } from './xport-schema.mts' @@ -34,4 +35,15 @@ const enriched = { } writeFileSync(outPath, JSON.stringify(enriched, null, 2) + '\n', 'utf8') + +// Run oxfmt on the output so the file matches what oxfmt would +// produce. Without this, `pnpm run check --all` (which runs oxfmt +// over the tree) would flag the emitted schema as drifted on every +// repo that re-emits it. The schema is in IDENTICAL_FILES, so the +// formatted form is the byte-canonical form fleet-wide. +await spawn('pnpm', ['exec', 'oxfmt', outPath], { + cwd: rootDir, + stdio: 'inherit', +}) + logger.success(`wrote ${path.relative(rootDir, outPath)}`) diff --git a/scripts/xport-schema.mts b/scripts/xport-schema.mts index aa6c0d04..f063a0d6 100644 --- a/scripts/xport-schema.mts +++ b/scripts/xport-schema.mts @@ -10,7 +10,7 @@ * `@socketsecurity/lib/validation/validate-schema` * * Byte-identical across socket-tui / socket-btm / socket-sdxgen / ultrathink / - * socket-registry / socket-repo-template via sync-scaffolding.mjs. + * socket-registry / socket-repo-template via sync-scaffolding.mts. */ import { Type, type Static } from '@sinclair/typebox' From 3963e9e69c7747d71fd7e297741481810c4e8458 Mon Sep 17 00:00:00 2001 From: jdalton Date: Tue, 5 May 2026 15:49:28 -0700 Subject: [PATCH 3/4] chore(pnpm): bump packageManager + engines.pnpm to 11.0.6 The cascade bump in this PR pulls socket-registry@51f34ffb's setup-and-install action, which installs pnpm 11.0.6 from external-tools.json. Without this matching package.json bump, pnpm refuses to run with a version-mismatch error. Independent of #631's wider Node-26 / pnpm bundle. This PR only sets the integrity-checked packageManager string and widens engines.pnpm to >=11.0.6. --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 55721e56..545391dd 100644 --- a/package.json +++ b/package.json @@ -115,7 +115,7 @@ }, "engines": { "node": ">=18.20.8", - "pnpm": ">=11.0.0" + "pnpm": ">=11.0.6" }, - "packageManager": "pnpm@11.0.0" + "packageManager": "pnpm@11.0.6+sha512.97f906e1da2bedac3df83cadae04b4753a130092dd49d55cd36825ad3e623e9df3f97754f8f259e699172a360fac569acf2f908e7732bdae3eddb2dcf7e121fd" } From f777e7325674966522cac768e990f65b52a7698c Mon Sep 17 00:00:00 2001 From: jdalton Date: Tue, 5 May 2026 16:08:15 -0700 Subject: [PATCH 4/4] chore(deps): regenerate pnpm-lock.yaml for catalog drift --- pnpm-lock.yaml | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e7e73631..1dccd58c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -52,15 +52,6 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false -catalogs: - default: - '@socketsecurity/lib': - specifier: 5.25.1 - version: 5.25.1 - '@types/node': - specifier: 24.9.2 - version: 24.9.2 - overrides: defu: '>=6.1.7' vite: 7.3.2 @@ -163,16 +154,6 @@ importers: specifier: 4.0.3 version: 4.0.3(@types/node@24.9.2)(jiti@2.6.1)(yaml@2.8.3) - .claude/hooks/auth-rotation-reminder: - dependencies: - '@socketsecurity/lib': - specifier: 'catalog:' - version: 5.25.1(typescript@5.9.3) - devDependencies: - '@types/node': - specifier: 'catalog:' - version: 24.9.2 - .claude/hooks/check-new-deps: dependencies: '@socketregistry/packageurl-js': @@ -189,12 +170,6 @@ importers: specifier: 24.9.2 version: 24.9.2 - .claude/hooks/logger-guard: - devDependencies: - '@types/node': - specifier: 'catalog:' - version: 24.9.2 - .claude/hooks/path-guard: {} .claude/hooks/private-name-guard: @@ -215,8 +190,6 @@ importers: specifier: 24.9.2 version: 24.9.2 - .claude/hooks/stale-process-sweeper: {} - .claude/hooks/token-guard: {} packages: @@ -1291,15 +1264,6 @@ packages: typescript: optional: true - '@socketsecurity/lib@5.25.1': - resolution: {integrity: sha512-I/sXk5FDOF7FVstzYn8tKtCvRe97KU/hl4p0e3OI1O9gma2uYypDiJT/n3axvtkqOyNFxWICWuXfy8Hnzeaw6Q==} - engines: {node: '>=22', pnpm: '>=11.0.0-rc.0'} - peerDependencies: - typescript: '>=5.0.0' - peerDependenciesMeta: - typescript: - optional: true - '@socketsecurity/lib@5.26.1': resolution: {integrity: sha512-ppyhOC/vPBY0gZVRtzNpmf/8nodILERmNV8J62pzVo7GvAB9S1q0/k/vSF2tor2NJEDtim+m6N+J5qtQ0mR99A==} engines: {node: '>=22', pnpm: '>=11.0.0-rc.0'} @@ -3033,10 +2997,6 @@ snapshots: optionalDependencies: typescript: 5.9.3 - '@socketsecurity/lib@5.25.1(typescript@5.9.3)': - optionalDependencies: - typescript: 5.9.3 - '@socketsecurity/lib@5.26.1(typescript@5.9.3)': optionalDependencies: typescript: 5.9.3