@threadbase-sh/streamer 1.86.0 → 1.86.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@threadbase-sh/streamer",
|
|
3
|
-
"version": "1.86.
|
|
3
|
+
"version": "1.86.1",
|
|
4
4
|
"description": "PTY session management, WebSocket streaming, and REST API server for Claude Code conversations",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ronen Mars",
|
|
@@ -37,7 +37,9 @@
|
|
|
37
37
|
}
|
|
38
38
|
},
|
|
39
39
|
"files": [
|
|
40
|
-
"dist"
|
|
40
|
+
"dist",
|
|
41
|
+
"scripts/check-node-version.mjs",
|
|
42
|
+
"scripts/check-native-abi.mjs"
|
|
41
43
|
],
|
|
42
44
|
"publishConfig": {
|
|
43
45
|
"access": "public"
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Guards against a stale `better-sqlite3` native binary — one compiled for a
|
|
2
|
+
// different Node ABI / OS / arch than the one running now (moved repo, upgraded
|
|
3
|
+
// Node). Such a binary fails at require-time with a cryptic NODE_MODULE_VERSION
|
|
4
|
+
// error deep in the server; this surfaces it up front with the fix command.
|
|
5
|
+
//
|
|
6
|
+
// Wired into `preinstall` (catch a no-op install that leaves a stale binary)
|
|
7
|
+
// and `pretest` (fail fast instead of paying an unconditional rebuild).
|
|
8
|
+
//
|
|
9
|
+
// ponytail: only better-sqlite3 is checked. node-pty ships N-API prebuilds
|
|
10
|
+
// (node-addon-api, .node files selected by platform-arch, ABI-stable across
|
|
11
|
+
// Node versions) so it can't hit a NODE_MODULE_VERSION mismatch.
|
|
12
|
+
import { spawnSync } from "node:child_process";
|
|
13
|
+
import { existsSync } from "node:fs";
|
|
14
|
+
import { dirname, join } from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
|
|
17
|
+
// --warn downgrades the failure to a notice. Used by `preinstall`, because
|
|
18
|
+
// `npm install` is one of the two remedies this check recommends — failing the
|
|
19
|
+
// install hard makes the guard block its own fix, and the only escape becomes
|
|
20
|
+
// `rm -rf node_modules` (the guard exits 0 when no binary exists at all).
|
|
21
|
+
const warnOnly = process.argv.includes("--warn");
|
|
22
|
+
|
|
23
|
+
const PKG = "better-sqlite3";
|
|
24
|
+
const root = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
25
|
+
const binary = join(root, "node_modules", PKG, "build", "Release", "better_sqlite3.node");
|
|
26
|
+
|
|
27
|
+
// Fresh install (no node_modules yet, or package not installed): nothing to
|
|
28
|
+
// compare against — a real install/rebuild will produce a matching binary.
|
|
29
|
+
if (!existsSync(binary)) process.exit(0);
|
|
30
|
+
|
|
31
|
+
// The authoritative test is whether *this* Node can dlopen the binary. A child
|
|
32
|
+
// process isolates the (possibly fatal) load. dlopen failing on a binary that
|
|
33
|
+
// exists means an ABI/OS/arch mismatch (NODE_MODULE_VERSION, wrong mach-o/ELF)
|
|
34
|
+
// — exactly what this guard is for. exit 3 = dlopen threw; anything else (spawn
|
|
35
|
+
// failure, unrelated crash) shouldn't block install/test.
|
|
36
|
+
const probe = `try { process.dlopen({ exports: {} }, ${JSON.stringify(binary)}); }
|
|
37
|
+
catch (e) { process.stderr.write(String(e && e.message || e)); process.exit(3); }`;
|
|
38
|
+
const res = spawnSync(process.execPath, ["-e", probe], { encoding: "utf8" });
|
|
39
|
+
|
|
40
|
+
if (res.status !== 3) process.exit(0);
|
|
41
|
+
|
|
42
|
+
const err = (res.stderr || "").trim();
|
|
43
|
+
console.error(`
|
|
44
|
+
${warnOnly ? "⚠" : "✖"} ${PKG} native binary is incompatible with this Node.
|
|
45
|
+
|
|
46
|
+
Expected: Node ABI ${process.versions.modules} ${process.platform}/${process.arch} (node ${process.version})
|
|
47
|
+
Binary: ${binary}
|
|
48
|
+
Loader error: ${err.replace(/\s+/g, " ").slice(0, 300)}
|
|
49
|
+
|
|
50
|
+
The compiled binary was built for a different Node version, OS, or CPU arch.
|
|
51
|
+
Fix it with one of:
|
|
52
|
+
|
|
53
|
+
npm rebuild ${PKG}
|
|
54
|
+
rm -rf node_modules && npm install
|
|
55
|
+
`);
|
|
56
|
+
process.exit(warnOnly ? 0 : 1);
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Guards against running a build, test or deploy under a Node outside the
|
|
2
|
+
// range this repo supports.
|
|
3
|
+
//
|
|
4
|
+
// The authority is `engines.node` in package.json — the same declaration npm
|
|
5
|
+
// checks — because that is the range CI actually exercises. `.nvmrc` is the
|
|
6
|
+
// exact version to develop against and is quoted as the suggestion, but it is
|
|
7
|
+
// deliberately NOT the test: CI runs the matrix on several supported majors,
|
|
8
|
+
// and a guard keyed to the single pinned version would reject them.
|
|
9
|
+
//
|
|
10
|
+
// Why this exists when `engines` already exists: npm only enforces it when the
|
|
11
|
+
// consumer opts into `engine-strict`, and it never enforces it for a bare
|
|
12
|
+
// `node scripts/…` invocation. `scripts/deploy.sh` runs in a subshell that does
|
|
13
|
+
// not load nvm's lazy-init function, so its `node` is whatever the system
|
|
14
|
+
// provides — which is how a deploy ends up building native modules for an ABI
|
|
15
|
+
// the service cannot load, then "fixing" it with a rebuild that breaks the
|
|
16
|
+
// other side. See docs/troubleshooting.md, "Native modules / ABI mismatches".
|
|
17
|
+
//
|
|
18
|
+
// ponytail: major-only bounds parsed from `>=A <B`, no semver dependency. Every
|
|
19
|
+
// ABI break this guards against is a major change. If the range is ever written
|
|
20
|
+
// in a shape this cannot parse, the check disables itself rather than guessing
|
|
21
|
+
// — its absence is the status quo, a wrong verdict is not.
|
|
22
|
+
import { readFileSync } from "node:fs";
|
|
23
|
+
import { dirname, join } from "node:path";
|
|
24
|
+
import { fileURLToPath } from "node:url";
|
|
25
|
+
|
|
26
|
+
const warnOnly = process.argv.includes("--warn");
|
|
27
|
+
const root = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
28
|
+
|
|
29
|
+
const read = (file) => {
|
|
30
|
+
try {
|
|
31
|
+
return readFileSync(join(root, file), "utf8");
|
|
32
|
+
} catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const pkg = read("package.json");
|
|
38
|
+
const range = pkg ? (JSON.parse(pkg).engines?.node ?? "") : "";
|
|
39
|
+
const min = range.match(/>=\s*(\d+)/)?.[1];
|
|
40
|
+
const max = range.match(/<\s*(\d+)/)?.[1];
|
|
41
|
+
if (!min && !max) process.exit(0); // Unparseable or absent — nothing to enforce.
|
|
42
|
+
|
|
43
|
+
const major = Number(process.versions.node.split(".")[0]);
|
|
44
|
+
if ((!min || major >= Number(min)) && (!max || major < Number(max))) process.exit(0);
|
|
45
|
+
|
|
46
|
+
const suggested = read(".nvmrc")?.trim().replace(/^v/, "");
|
|
47
|
+
console.error(`
|
|
48
|
+
${warnOnly ? "⚠" : "✖"} Node ${process.version} is outside the range this repo supports (${range}).
|
|
49
|
+
|
|
50
|
+
Running: ${process.execPath}
|
|
51
|
+
Develop against: ${suggested ? `v${suggested} (.nvmrc)` : `Node ${min ?? "?"}.x`}
|
|
52
|
+
|
|
53
|
+
Native modules are compiled per Node ABI, so building or deploying here produces
|
|
54
|
+
binaries the supported Node cannot load — and the reverse. Switch before continuing:
|
|
55
|
+
|
|
56
|
+
nvm use # or: fnm use / asdf install
|
|
57
|
+
nvm-windows: nvm use ${suggested?.split(".")[0] ?? min} (no auto-cd hook — it must be explicit)
|
|
58
|
+
`);
|
|
59
|
+
|
|
60
|
+
process.exit(warnOnly ? 0 : 1);
|