Skip to content

Commit b01528a

Browse files
committed
chore(deps): drift updates from #630 — pnpm catalog + scripts
- 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.
1 parent 455bda5 commit b01528a

8 files changed

Lines changed: 365 additions & 42 deletions

File tree

external-tools.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
},
2323
"pnpm": {
2424
"description": "pnpm — the fleet's package manager.",
25-
"version": "11.0.0-rc.5",
25+
"version": "11.0.0",
2626
"packageManager": "pnpm",
2727
"repository": "github:pnpm/pnpm",
2828
"release": "asset",
@@ -34,27 +34,27 @@
3434
"checksums": {
3535
"darwin-arm64": {
3636
"asset": "pnpm-darwin-arm64.tar.gz",
37-
"sha256": "32a50710ccacfdcf14e6d5995d5368298eec913b0ce3903b9e09b6555f06f4e5"
37+
"sha256": "3620a0fcaf81ecd3aaeccd5965919d90dbc913f4d07a96e11e7cafc2c785054b"
3838
},
3939
"darwin-x64": {
4040
"asset": "pnpm-darwin-x64.tar.gz",
41-
"sha256": "71dca33f4275da6b43bf1eb40bdc4d876f59a116716eacbf01079c3d985ff85d"
41+
"sha256": "1701748b75187f1333a9c616827943ff84ff46cc42becc156ff6864b9bd0f948"
4242
},
4343
"linux-arm64": {
4444
"asset": "pnpm-linux-arm64.tar.gz",
45-
"sha256": "2dd04127ff10b1f9dd20bae248b779c77a8ec67e3afa35e7256e5f94abddd493"
45+
"sha256": "1e6d87ebfd7ff169966ff5b3ad71b780b883c68d3e59987df1096dfd8853df75"
4646
},
4747
"linux-x64": {
4848
"asset": "pnpm-linux-x64.tar.gz",
49-
"sha256": "7ebef4b616ba41fb0d54a207b36508fae3346723283a088b43fc1e038ee6fed0"
49+
"sha256": "9b44acc77ada40fc41b665fde1d57367a5ebec31bd4b1b00598daed195da3e17"
5050
},
5151
"win-arm64": {
5252
"asset": "pnpm-win32-arm64.zip",
53-
"sha256": "e4a39ad4c251db5e34b18b98561ef25bab5506ad65cad2fa3602af58d1972667"
53+
"sha256": "0746be8e98ca183078d0747559f0cbbd30a13a53eb177f67474eb3c52dc21bc8"
5454
},
5555
"win-x64": {
5656
"asset": "pnpm-win32-x64.zip",
57-
"sha256": "147485ae2f38c3d1ccf2f5db00d0244416bcd22b9114c02388e6a78f41538fc4"
57+
"sha256": "581e222e622cd0cc4f0ac5f85dd0db76b65117e3b17507979d89e63fdc68edca"
5858
}
5959
}
6060
},

package.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
"description": "SDK for the Socket API client",
55
"homepage": "https://github.com/SocketDev/socket-sdk-js",
66
"license": "MIT",
7+
"publishConfig": {
8+
"access": "public",
9+
"provenance": true
10+
},
711
"author": {
812
"name": "Socket Inc",
913
"email": "eng@socket.dev",
@@ -73,7 +77,7 @@
7377
"@babel/traverse": "7.26.4",
7478
"@babel/types": "7.26.3",
7579
"@oxlint/migrate": "1.52.0",
76-
"@socketsecurity/lib": "5.25.1",
80+
"@socketsecurity/lib": "5.26.1",
7781
"@sveltejs/acorn-typescript": "1.0.8",
7882
"@types/babel__traverse": "7.28.0",
7983
"@types/node": "24.9.2",
@@ -111,7 +115,7 @@
111115
},
112116
"engines": {
113117
"node": ">=18.20.8",
114-
"pnpm": ">=11.0.0-rc.0"
118+
"pnpm": ">=11.0.0"
115119
},
116-
"packageManager": "pnpm@11.0.0-rc.5"
120+
"packageManager": "pnpm@11.0.0"
117121
}

pnpm-lock.yaml

Lines changed: 42 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
loglevel: error
22
trustPolicy: no-downgrade
33

4+
# Catalog: shared dependency versions referenced as "catalog:" in
5+
# package.json. Hooks under .claude/hooks/* declare their deps via
6+
# `catalog:` so they stay in lockstep with the root workspace.
7+
catalog:
8+
'@socketsecurity/lib': 5.25.1
9+
'@types/node': 24.9.2
10+
411
# Register .claude/hooks/* as workspace packages so taze (run via
512
# `pnpm run update`) sees and bumps their package.json manifests
613
# alongside the root. Keeps hook deps in lockstep with the main tree.
@@ -38,6 +45,15 @@ minimumReleaseAgeExclude:
3845
- '@socketregistry/*'
3946
- '@socketsecurity/*'
4047

48+
# Refuse transitive dependencies declared via git/tarball/local-tarball
49+
# specs — an npm package shouldn't be allowed to drag in a git URL we
50+
# don't control (bypasses npm registry validation, no provenance, no
51+
# soak window). Direct git deps are still allowed (the test suite at
52+
# pnpm/pkg-manager/core/test/install/blockExoticSubdeps.ts confirms
53+
# this). pnpm's current default is `false`; declared explicitly so a
54+
# future flip can't silently change install behavior.
55+
blockExoticSubdeps: true
56+
4157
# Pin exact versions on `pnpm add`. Catalog and overrides should
4258
# also be exact pins (5.24.0, not ^5.24.0).
4359
saveExact: true

scripts/power-state.mts

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/**
2+
* @fileoverview Detect whether the host is currently on AC power
3+
* (vs battery). Used by long-running build/test scripts to size
4+
* timeouts adaptively — laptops on battery throttle CPU hard
5+
* (especially macOS), and a static timeout that fits AC will kill
6+
* an otherwise-healthy run on battery.
7+
*
8+
* Two paths, in priority order:
9+
*
10+
* 1. `node:smol-power` — when running inside a node-smol binary
11+
* that ships the smol_power native binding (socket-btm's custom
12+
* Node distribution). Pure C++ syscalls, sub-millisecond.
13+
*
14+
* 2. Shellout fallback — system Node doesn't have node:smol-power.
15+
* Each platform has a different mechanism:
16+
* * macOS: `pmset -g batt` parses "AC Power" / "Battery Power"
17+
* * Linux: reads /sys/class/power_supply/<entry>/online
18+
* (no shellout, just open/read syscalls)
19+
* * Windows: PowerShell `Get-CimInstance Win32_Battery`
20+
*
21+
* On detection failure we conservatively assume AC — the downstream
22+
* timeout becomes the shorter / more aggressive value, which is
23+
* appropriate for build servers and headless CI (those environments
24+
* are expected to run at full speed).
25+
*
26+
* Returns a Promise so callers don't block the event loop on shellout
27+
* paths.
28+
*
29+
* Byte-identical across the fleet via socket-repo-template's
30+
* sync-scaffolding (IDENTICAL_FILES).
31+
*/
32+
33+
import { existsSync, promises as fs } from 'node:fs'
34+
import path from 'node:path'
35+
import process from 'node:process'
36+
37+
import { spawn } from '@socketsecurity/lib/spawn'
38+
39+
// Probe for node:smol-power. Lives in socket-btm's node-smol binary.
40+
// Wrapped in try/catch so this file is safe to import on system Node
41+
// where the module doesn't exist.
42+
let _smolPower: { isOnAcPower: () => boolean } | undefined
43+
async function getSmolPower(): Promise<typeof _smolPower> {
44+
if (_smolPower !== undefined) {
45+
return _smolPower
46+
}
47+
try {
48+
const mod = await import('node:smol-power')
49+
_smolPower = mod
50+
return _smolPower
51+
} catch {
52+
_smolPower = undefined
53+
return undefined
54+
}
55+
}
56+
57+
async function detectMacOs(): Promise<boolean> {
58+
try {
59+
// `pmset -g batt` on macOS prints lines like
60+
// Now drawing from 'AC Power'
61+
// Now drawing from 'Battery Power'
62+
// Match the AC variant; everything else (battery, unknown) is
63+
// treated as not-AC.
64+
const result = await spawn('pmset', ['-g', 'batt'], {
65+
stdio: ['ignore', 'pipe', 'ignore'],
66+
})
67+
return /AC Power/.test(result.stdout || '')
68+
} catch {
69+
return true
70+
}
71+
}
72+
73+
async function detectLinux(): Promise<boolean> {
74+
// Linux exposes power state under /sys/class/power_supply. Each
75+
// AC adapter is its own dir (`AC`, `ADP1`, `AC0`, `ACAD`, …)
76+
// with an `online` file holding "1" when power is connected.
77+
// Containers and headless servers often have no power_supply
78+
// tree at all — treat that as AC since those environments are
79+
// expected to run at full speed.
80+
const psDir = '/sys/class/power_supply'
81+
if (!existsSync(psDir)) {
82+
return true
83+
}
84+
try {
85+
const entries = await fs.readdir(psDir)
86+
for (const entry of entries) {
87+
const onlineFile = path.join(psDir, entry, 'online')
88+
if (!existsSync(onlineFile)) {
89+
continue
90+
}
91+
try {
92+
const value = await fs.readFile(onlineFile, 'utf8')
93+
if (value.trim() === '1') {
94+
return true
95+
}
96+
} catch {
97+
// Unreadable entry — skip; another entry may report.
98+
}
99+
}
100+
} catch {
101+
// Directory enumeration failed — fall through to AC.
102+
return true
103+
}
104+
return false
105+
}
106+
107+
async function detectWindows(): Promise<boolean> {
108+
try {
109+
// Windows: query the battery status via PowerShell + CIM.
110+
// `Win32_Battery.BatteryStatus`:
111+
// 1 = Discharging (battery)
112+
// 2 = On AC, not charging or fully charged
113+
// 3..5 = Various battery states
114+
// 6 = AC + charging
115+
// Desktops with no battery return an empty result; treat as AC.
116+
const result = await spawn(
117+
'powershell.exe',
118+
[
119+
'-NoProfile',
120+
'-Command',
121+
'(Get-CimInstance -ClassName Win32_Battery).BatteryStatus',
122+
],
123+
{ stdio: ['ignore', 'pipe', 'ignore'] },
124+
)
125+
const trimmed = (result.stdout || '').trim()
126+
if (trimmed === '') {
127+
return true
128+
}
129+
const status = Number.parseInt(trimmed, 10)
130+
if (Number.isNaN(status)) {
131+
return true
132+
}
133+
return status === 2 || status === 6
134+
} catch {
135+
return true
136+
}
137+
}
138+
139+
/**
140+
* Returns `true` if the host is on AC power. Conservative on
141+
* detection failure (returns `true`) — callers using this for
142+
* timeout sizing prefer a longer timeout to a too-short one.
143+
*
144+
* Prefers the native binding (`node:smol-power`) when running
145+
* inside a node-smol binary; falls back to a per-platform path
146+
* (shellout on macOS / Windows, direct sysfs reads on Linux) on
147+
* system Node.
148+
*/
149+
export async function isOnAcPower(): Promise<boolean> {
150+
const native = await getSmolPower()
151+
if (native) {
152+
return native.isOnAcPower()
153+
}
154+
if (process.platform === 'darwin') {
155+
return await detectMacOs()
156+
}
157+
if (process.platform === 'linux') {
158+
return await detectLinux()
159+
}
160+
if (process.platform === 'win32') {
161+
return await detectWindows()
162+
}
163+
// Unsupported platform; conservative default.
164+
return true
165+
}

0 commit comments

Comments
 (0)