nestweaver 9.0.5 → 9.2.0

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/README.md CHANGED
@@ -3,22 +3,45 @@
3
3
  Code knowledge graph for AI agents — 42 MCP tools, 32 languages, graph
4
4
  visualization.
5
5
 
6
- This package is a thin wrapper. Its `postinstall` downloads the NestWeaver
7
- binary matching this package's version from the project's GitHub Releases,
8
- verifies it against the SHA-256 published alongside the archive, and puts a
9
- `nestweaver` executable on your PATH.
6
+ This package is a thin wrapper with **no install-time (`postinstall`) script**.
7
+ It ships one prebuilt-binary package per platform —
8
+ `nestweaver-darwin-arm64`, `nestweaver-darwin-x64`, `nestweaver-linux-arm64`,
9
+ `nestweaver-linux-x64` — as an `optionalDependencies` entry, the same pattern
10
+ esbuild, swc, and Rollup use. npm, pnpm, and Yarn each install only the one
11
+ matching your machine's `os`/`cpu` through their own ordinary dependency
12
+ resolution; the `nestweaver` executable on your PATH resolves and runs
13
+ whichever one actually landed, at invocation time.
14
+
15
+ **No lifecycle scripts to allow.** There is nothing for
16
+ `npm install --ignore-scripts` to skip, and pnpm 10+'s default block on
17
+ lifecycle scripts (which used to leave a wrapper with no binary and no
18
+ `pnpm.onlyBuiltDependencies` clue why) no longer applies — there is no script
19
+ to block.
20
+
21
+ If your package manager skipped optional dependencies entirely
22
+ (`--omit=optional`, `--no-optional`, or a lockfile resolved without one),
23
+ `nestweaver` exits 1 and names the exact optional package to install instead
24
+ of silently doing nothing. If your organisation disallows this platform
25
+ package entirely, install a release archive from GitHub or build from source
26
+ (`cargo install --locked --path .`) instead.
10
27
 
11
28
  ## Platforms
12
29
 
13
- macOS and Linux, on x86_64 and arm64. On any other platform the install step
14
- exits without failing and prints the supported targets; use a release archive
15
- or a source build instead.
30
+ macOS and Linux, on x86_64 and arm64. Every other platform has no published
31
+ optional package, so `nestweaver` FAILS with the supported-targets list at
32
+ invocation time rather than leaving you with a wrapper that silently cannot
33
+ run; use a release archive or a source build instead. The two Linux platform
34
+ packages additionally declare `libc: ["glibc"]` (musl/Alpine is not
35
+ currently supported). Declaring `libc` is safe on a Linux-only package; it was
36
+ not safe on the earlier combined macOS+Linux wrapper, where it made npm reject
37
+ every macOS install with `EBADPLATFORM` because `libc` is not a concept on
38
+ macOS. The field itself was never the problem — the package it sat on was.
16
39
 
17
40
  Linux builds target **glibc 2.35**, which covers Ubuntu 22.04 LTS and newer and
18
- Debian 12. The archive includes the GCC 13 runtime LadybugDB needs and the npm
19
- installer preserves it beside the binary. Check your glibc with `ldd --version`;
20
- on anything older the binary will not start and the error names a missing
21
- `GLIBC_` symbol. macOS builds target **13.3**.
41
+ Debian 12. The platform package includes the GCC 13 runtime LadybugDB needs
42
+ beside the binary. Check your glibc with `ldd --version`; on anything older
43
+ the binary will not start and the error names a missing `GLIBC_` symbol.
44
+ macOS builds target **13.3**.
22
45
 
23
46
  ## Upgrading an existing graph
24
47
 
package/bin/nestweaver CHANGED
@@ -1,11 +1,172 @@
1
- #!/usr/bin/env bash
2
- set -e
3
- DIR="$(cd "$(dirname "$0")/.." && pwd)"
4
- BINARY="$DIR/.nestweaver-bin/nestweaver"
1
+ #!/usr/bin/env node
2
+ "use strict";
5
3
 
6
- if [ ! -x "$BINARY" ]; then
7
- echo "NestWeaver binary not found. Install a verified GitHub Release archive, or from a source checkout run: cargo install --locked --path ." >&2
8
- exit 1
9
- fi
4
+ const path = require("path");
10
5
 
11
- exec "$BINARY" "$@"
6
+ // ── Decision logic ──────────────────────────────────────────────────────
7
+ // Pure, exported, and covered by nestweaver.test.js. Everything below the
8
+ // `main()` boundary does I/O (module resolution, process spawn) and is not
9
+ // directly testable; keeping the judgements out here is what makes the
10
+ // launcher assertable at all.
11
+ //
12
+ // nw-425 / nw-433: this package used to have a `postinstall` that downloaded
13
+ // the matching GitHub Release archive at install time. pnpm 10+ blocks
14
+ // lifecycle scripts by default, so `pnpm add nestweaver` silently produced a
15
+ // wrapper with no binary and no indication why -- the documented workaround
16
+ // (`"pnpm": {"onlyBuiltDependencies": ["nestweaver"]}`) required knowing the
17
+ // failure existed in the first place. There is now no lifecycle script at
18
+ // all. Each supported platform ships as its own optionalDependency (the
19
+ // esbuild/@rollup/swc pattern): npm/pnpm/yarn install ONLY the one whose
20
+ // package.json `os`/`cpu` match the current machine, entirely through their
21
+ // own normal dependency resolution -- nothing here runs at install time.
22
+ // This file is what runs at INVOCATION time: it resolves which platform
23
+ // package actually landed and execs its binary.
24
+
25
+ const PLATFORM_PACKAGES = {
26
+ "darwin-x64": "nestweaver-darwin-x64",
27
+ "darwin-arm64": "nestweaver-darwin-arm64",
28
+ "linux-x64": "nestweaver-linux-x64",
29
+ "linux-arm64": "nestweaver-linux-arm64",
30
+ };
31
+
32
+ function platformKey(platform, arch) {
33
+ return `${platform}-${arch}`;
34
+ }
35
+
36
+ /// Which optional platform package this machine should have installed, or
37
+ /// `null` if none is published for it.
38
+ function platformPackageName(platform, arch) {
39
+ return PLATFORM_PACKAGES[platformKey(platform, arch)] || null;
40
+ }
41
+
42
+ /// Whether the running system is musl (Alpine and similar), not glibc.
43
+ ///
44
+ /// Ported from the retired install.js unchanged (nw-433): `glibcVersionRuntime`
45
+ /// is populated by Node's own `process.report` only when Node itself is linked
46
+ /// against glibc, so a musl-linked Node (Alpine's system Node, every
47
+ /// `node:*-alpine`/`node:*-musl` image) never has it. THREE states, not two:
48
+ /// `reportAvailable` is separate from `glibcVersionRuntime` so "the report
49
+ /// could not be produced at all" (sandboxed container, unusual build) and
50
+ /// "the report WAS produced and shows no glibc" (genuine musl) cannot
51
+ /// collapse into the same `undefined` -- that collapse would refuse a working
52
+ /// glibc-Linux box whenever the report merely couldn't be read. An
53
+ /// unavailable report fails OPEN (false, i.e. "not musl, proceed"); only a
54
+ /// report that was actually read and shows no glibc fails closed.
55
+ function isMuslLinux(platform, glibcVersionRuntime, reportAvailable) {
56
+ if (platform !== "linux" || !reportAvailable) {
57
+ return false;
58
+ }
59
+ return !glibcVersionRuntime;
60
+ }
61
+
62
+ function unsupportedPlatformMessage(platform, arch) {
63
+ return [
64
+ `Unsupported platform: ${platform}-${arch}`,
65
+ "Supported: darwin-x64, darwin-arm64, linux-x64, linux-arm64",
66
+ "Install from a source checkout instead: cargo install --locked --path .",
67
+ ].join("\n");
68
+ }
69
+
70
+ function muslMessage(platform, arch) {
71
+ return [
72
+ `Unsupported platform: ${platform}-${arch} (musl libc)`,
73
+ "NestWeaver's published Linux packages are glibc-only (nestweaver-linux-x64, nestweaver-linux-arm64). musl/Alpine is not currently supported.",
74
+ "Build from a source checkout instead: cargo install --locked --path .",
75
+ ].join("\n");
76
+ }
77
+
78
+ /// Why `require.resolve` on the platform package's binary failed. This is
79
+ /// reached only when `platformPackageName` already matched a real target --
80
+ /// the package manager should have installed it -- so the likely causes are
81
+ /// operator-controlled (optional dependencies were explicitly skipped) rather
82
+ /// than "wrong platform", and the message says so instead of guessing.
83
+ function missingPlatformPackageMessage(pkgName, version) {
84
+ return [
85
+ `NestWeaver binary not found: optional dependency "${pkgName}@${version}" is not installed.`,
86
+ "This usually means your package manager skipped optional dependencies",
87
+ "(npm/yarn --omit=optional or --no-optional, or a lockfile resolved without it).",
88
+ `Install it explicitly: npm install ${pkgName}@${version}`,
89
+ "Or install from a source checkout instead: cargo install --locked --path .",
90
+ ].join("\n");
91
+ }
92
+
93
+ /// Resolve the platform package's binary via Node's own module resolution
94
+ /// (`resolveFn`, ordinarily `require.resolve`) rather than constructing a
95
+ /// path by hand. Module resolution is what makes this correct under every
96
+ /// package manager's node_modules layout -- including pnpm's strict,
97
+ /// symlinked store, which is exactly the layout a hand-built relative path
98
+ /// would get wrong and the reason nw-425 existed. Takes `resolveFn` as a
99
+ /// parameter so this is testable without a real installed dependency tree.
100
+ function resolveBinaryPath(pkgName, resolveFn) {
101
+ try {
102
+ return { binaryPath: resolveFn(`${pkgName}/bin/nestweaver`), error: null };
103
+ } catch (err) {
104
+ return { binaryPath: null, error: err };
105
+ }
106
+ }
107
+
108
+ module.exports = {
109
+ PLATFORM_PACKAGES,
110
+ platformKey,
111
+ platformPackageName,
112
+ isMuslLinux,
113
+ unsupportedPlatformMessage,
114
+ muslMessage,
115
+ missingPlatformPackageMessage,
116
+ resolveBinaryPath,
117
+ };
118
+
119
+ // ── Execution ────────────────────────────────────────────────────────────
120
+
121
+ function main() {
122
+ const { spawnSync } = require("child_process");
123
+ const platform = process.platform;
124
+ const arch = process.arch;
125
+
126
+ if (platform === "linux") {
127
+ let glibcVersionRuntime;
128
+ let reportAvailable = false;
129
+ try {
130
+ if (process.report && typeof process.report.getReport === "function") {
131
+ glibcVersionRuntime = process.report.getReport().header.glibcVersionRuntime;
132
+ reportAvailable = true;
133
+ }
134
+ } catch {
135
+ reportAvailable = false;
136
+ }
137
+ if (isMuslLinux(platform, glibcVersionRuntime, reportAvailable)) {
138
+ console.error(muslMessage(platform, arch));
139
+ process.exit(1);
140
+ }
141
+ }
142
+
143
+ const pkgName = platformPackageName(platform, arch);
144
+ if (!pkgName) {
145
+ console.error(unsupportedPlatformMessage(platform, arch));
146
+ process.exit(1);
147
+ }
148
+
149
+ const version = require(path.join(__dirname, "..", "package.json")).version;
150
+ const { binaryPath, error } = resolveBinaryPath(pkgName, (specifier) =>
151
+ require.resolve(specifier),
152
+ );
153
+ if (error) {
154
+ console.error(missingPlatformPackageMessage(pkgName, version));
155
+ process.exit(1);
156
+ }
157
+
158
+ const result = spawnSync(binaryPath, process.argv.slice(2), { stdio: "inherit" });
159
+ if (result.error) {
160
+ console.error(
161
+ `Failed to execute NestWeaver binary at ${binaryPath}: ${result.error.message}`,
162
+ );
163
+ process.exit(1);
164
+ }
165
+ process.exit(result.status === null ? 1 : result.status);
166
+ }
167
+
168
+ // Only run when executed as the npm bin entry point; `require` must be free
169
+ // of side effects so the decision logic above can be tested at all.
170
+ if (require.main === module) {
171
+ main();
172
+ }
package/package.json CHANGED
@@ -1,18 +1,14 @@
1
1
  {
2
2
  "name": "nestweaver",
3
- "version": "9.0.5",
3
+ "version": "9.2.0",
4
4
  "description": "Code knowledge graph for AI agents — 42 MCP tools, 32 languages, graph visualization",
5
5
  "bin": {
6
6
  "nestweaver": "bin/nestweaver"
7
7
  },
8
8
  "files": [
9
9
  "bin/",
10
- "install.js",
11
10
  "README.md"
12
11
  ],
13
- "scripts": {
14
- "postinstall": "node install.js"
15
- },
16
12
  "os": [
17
13
  "darwin",
18
14
  "linux"
@@ -21,6 +17,15 @@
21
17
  "x64",
22
18
  "arm64"
23
19
  ],
20
+ "engines": {
21
+ "node": ">=18"
22
+ },
23
+ "optionalDependencies": {
24
+ "nestweaver-darwin-arm64": "9.2.0",
25
+ "nestweaver-darwin-x64": "9.2.0",
26
+ "nestweaver-linux-arm64": "9.2.0",
27
+ "nestweaver-linux-x64": "9.2.0"
28
+ },
24
29
  "keywords": [
25
30
  "mcp",
26
31
  "code-graph",
package/install.js DELETED
@@ -1,82 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const { execSync } = require("child_process");
4
- const fs = require("fs");
5
- const path = require("path");
6
-
7
- const PLATFORM_MAP = {
8
- "darwin-x64": "x86_64-apple-darwin",
9
- "darwin-arm64": "aarch64-apple-darwin",
10
- "linux-x64": "x86_64-unknown-linux-gnu",
11
- "linux-arm64": "aarch64-unknown-linux-gnu",
12
- };
13
-
14
- const key = `${process.platform}-${process.arch}`;
15
- const target = PLATFORM_MAP[key];
16
-
17
- if (!target) {
18
- console.warn(`Unsupported platform: ${key}`);
19
- console.warn("Supported: darwin-x64, darwin-arm64, linux-x64, linux-arm64");
20
- console.warn(
21
- "Unsupported platform. Install a verified GitHub Release archive for a supported target, or from a source checkout: cargo install --locked --path .",
22
- );
23
- process.exit(0); // Don't break npm install
24
- }
25
-
26
- const version = require("./package.json").version;
27
- const repo = "Kehl-io/nestweaver";
28
- // Release tags are `v<version>` (release-please config: include-component-in-tag
29
- // false) and assets are `nestweaver-v<version>-<target>.tar.gz` (see the
30
- // `build` job in .github/workflows/release-please.yml). Keep these in sync.
31
- const tag = `v${version}`;
32
- const archive = `nestweaver-${tag}-${target}.tar.gz`;
33
- const base = `https://github.com/${repo}/releases/download/${tag}`;
34
- const url = `${base}/${archive}`;
35
-
36
- const binDir = path.join(__dirname, ".nestweaver-bin");
37
- fs.mkdirSync(binDir, { recursive: true });
38
- const archivePath = path.join(binDir, archive);
39
-
40
- console.log(`Downloading NestWeaver v${version} for ${target}...`);
41
-
42
- try {
43
- execSync(`curl -fsSL "${url}" -o "${archivePath}"`, { stdio: "inherit" });
44
-
45
- // Verify the SHA-256 the release ships alongside the archive — a mismatch
46
- // means a corrupted or tampered download, which must fail loudly.
47
- try {
48
- const expected = execSync(`curl -fsSL "${url}.sha256"`)
49
- .toString()
50
- .trim()
51
- .split(/\s+/)[0];
52
- const actual = execSync(`shasum -a 256 "${archivePath}"`)
53
- .toString()
54
- .trim()
55
- .split(/\s+/)[0];
56
- if (expected && actual && expected !== actual) {
57
- throw new Error(
58
- `checksum mismatch: expected ${expected}, got ${actual}`,
59
- );
60
- }
61
- } catch (checksumErr) {
62
- if (String(checksumErr.message || "").includes("checksum mismatch")) {
63
- throw checksumErr; // integrity failure — do not install
64
- }
65
- // Missing/unreadable .sha256 is not fatal; proceed with the download.
66
- }
67
-
68
- execSync(`tar xz -C "${binDir}" -f "${archivePath}"`, { stdio: "inherit" });
69
- fs.rmSync(archivePath, { force: true });
70
- fs.chmodSync(path.join(binDir, "nestweaver"), 0o755);
71
- console.log("NestWeaver installed successfully.");
72
- console.log(
73
- "Upgrading an existing pre-publication brain? Stop its daemon and run `nestweaver publication rebuild --config /path/to/instance.toml`; the incumbent remains recoverable until validated cutover.",
74
- );
75
- } catch (err) {
76
- console.warn(`Failed to install NestWeaver binary: ${err.message}`);
77
- console.warn(` URL: ${url}`);
78
- console.warn(
79
- "Download a verified GitHub Release archive, or build from a source checkout: cargo install --locked --path .",
80
- );
81
- process.exit(0); // Don't break npm install on transient/network failures
82
- }