chore: raise the node floor to 22, make the libsodium step cross-platform and fail-loud, address dependency advisories

Regenerating the lockfile picked up a newer @cardano-sdk/crypto release that
dropped its errant npm-CLI runtime dependency, clearing the critical tar
advisory and 42 other advisories that traced back to it (44 -> 1, the
remainder a dev-only esbuild low). A defensive overrides pin on tar and
brace-expansion is retained per plan but is empirically not what resolved
this - documented honestly in README.md and the task report.

engines.node raised to >=22 everywhere (root + all three packages), matching
the CI workflow's node-version and the Dockerfile's node:22-alpine base
(both already agreed; no discrepancy to reconcile).

postinstall no longer symlinks libsodium with `ln -sf ... || true`, which
silently no-opped on Windows and left a runtime ERR_MODULE_NOT_FOUND.
scripts/link-libsodium.mjs copies the file cross-platform instead, logs one
line, and exits non-zero on genuine failure.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
FilipBl4gojevic
2026-07-31 17:21:17 +02:00
parent 5f229d3ccd
commit 949a56312a
7 changed files with 1334 additions and 3776 deletions

View File

@@ -170,11 +170,27 @@ Example non-custodial flow for a registry op: `vector_build_register_agent` →
### 1. Install and build ### 1. Install and build
Requires Node.js >= 22 (matches `engines` in every `package.json` and the Dockerfile's
`node:22-alpine` base).
```bash ```bash
npm install npm install
npm run build npm run build
``` ```
**Dependency advisories.** `npm audit` currently reports 1 low-severity advisory: an `esbuild`
arbitrary-file-read issue that only triggers via its own Windows dev server, reachable solely
through `tsup` (a build-time-only dependency, absent from the production image, which installs
with `npm ci --omit=dev`). As of 2026-07-31 this tree carried 44 advisories, including 1
critical (`tar`, GHSA-23hp-3jrh-7fpw) that arrived because `@cardano-sdk/crypto` - pulled in
transitively through `@lucid-evolution/lucid` - declared the entire `npm` CLI package as a
runtime dependency. That dependency was dead weight: `@cardano-sdk/crypto`'s own published code
never requires `npm`, and neither `npm` nor `tar` appears anywhere in this server's built
bundle. Regenerating the lockfile picked up a newer `@cardano-sdk/crypto` release that dropped
the stray dependency outright, clearing all 43 of those advisories without any override needed;
`package.json` also carries a defensive `overrides` pin on `tar` and `brace-expansion` against
future regressions, though it is not what resolved this one.
### 2. Configure environment (optional) ### 2. Configure environment (optional)
```bash ```bash

5026
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@
"type": "module", "type": "module",
"workspaces": ["packages/*"], "workspaces": ["packages/*"],
"scripts": { "scripts": {
"postinstall": "ln -sf ../../../libsodium-sumo/dist/modules-sumo-esm/libsodium-sumo.mjs node_modules/libsodium-wrappers-sumo/dist/modules-sumo-esm/libsodium-sumo.mjs 2>/dev/null || true", "postinstall": "node scripts/link-libsodium.mjs",
"clean": "rm -rf packages/*/build", "clean": "rm -rf packages/*/build",
"build": "npm run build --workspace=@apexfusion/vector-mcp-builder && npm run build --workspace=@apexfusion/vector-mcp-signer", "build": "npm run build --workspace=@apexfusion/vector-mcp-builder && npm run build --workspace=@apexfusion/vector-mcp-signer",
"typecheck": "tsc --noEmit -p packages/shared && tsc --noEmit -p packages/builder && tsc --noEmit -p packages/signer", "typecheck": "tsc --noEmit -p packages/shared && tsc --noEmit -p packages/builder && tsc --noEmit -p packages/signer",
@@ -24,8 +24,12 @@
"tsx": "^4.21.0", "tsx": "^4.21.0",
"typescript": "^5.7.3" "typescript": "^5.7.3"
}, },
"overrides": {
"tar": "^7.5.21",
"brace-expansion": "^2.0.2"
},
"engines": { "engines": {
"node": ">=22.0.0" "node": ">=22"
}, },
"license": "ISC", "license": "ISC",
"author": "Apex Fusion", "author": "Apex Fusion",

View File

@@ -25,5 +25,8 @@
}, },
"devDependencies": { "devDependencies": {
"@apexfusion/vector-mcp-shared": "*" "@apexfusion/vector-mcp-shared": "*"
},
"engines": {
"node": ">=22"
} }
} }

View File

@@ -13,5 +13,8 @@
"@lucid-evolution/lucid": "^0.4.29", "@lucid-evolution/lucid": "^0.4.29",
"@noble/hashes": "^1.7.1", "@noble/hashes": "^1.7.1",
"cross-fetch": "^4.0.0" "cross-fetch": "^4.0.0"
},
"engines": {
"node": ">=22"
} }
} }

View File

@@ -17,5 +17,8 @@
}, },
"devDependencies": { "devDependencies": {
"@apexfusion/vector-mcp-shared": "*" "@apexfusion/vector-mcp-shared": "*"
},
"engines": {
"node": ">=22"
} }
} }

View File

@@ -0,0 +1,51 @@
#!/usr/bin/env node
/**
* Cross-platform replacement for the old postinstall one-liner:
*
* ln -sf ../../../libsodium-sumo/dist/modules-sumo-esm/libsodium-sumo.mjs \
* node_modules/libsodium-wrappers-sumo/dist/modules-sumo-esm/libsodium-sumo.mjs \
* 2>/dev/null || true
*
* `ln -sf` has no reliable equivalent on stock Windows (symlinks need an elevated
* privilege Windows does not grant by default), and the trailing `|| true` swallowed
* that failure silently - `npm install` reported success while leaving a dangling
* ESM import that only surfaces later as ERR_MODULE_NOT_FOUND at runtime, far from
* the install step that actually caused it. This script COPIES the file instead
* (identical result on every platform) and never swallows a genuine failure: it
* exits non-zero and prints why whenever it cannot leave the tree in a working
* state.
*/
import { copyFileSync, existsSync, readFileSync } from 'node:fs';
import { dirname } from 'node:path';
const SOURCE = 'node_modules/libsodium-sumo/dist/modules-sumo-esm/libsodium-sumo.mjs';
const DEST = 'node_modules/libsodium-wrappers-sumo/dist/modules-sumo-esm/libsodium-sumo.mjs';
if (!existsSync(SOURCE)) {
console.error(
`link-libsodium: source missing at "${SOURCE}" - is libsodium-sumo installed? Run npm install.`
);
process.exit(1);
}
if (existsSync(DEST) && readFileSync(DEST).equals(readFileSync(SOURCE))) {
console.log(`link-libsodium: "${DEST}" already matches the source, nothing to do.`);
process.exit(0);
}
if (!existsSync(dirname(DEST))) {
console.error(
`link-libsodium: destination directory missing at "${dirname(DEST)}" - is libsodium-wrappers-sumo installed correctly? Run npm install.`
);
process.exit(1);
}
try {
copyFileSync(SOURCE, DEST);
} catch (err) {
console.error(`link-libsodium: failed to copy "${SOURCE}" to "${DEST}": ${err.message}`);
process.exit(1);
}
console.log(`link-libsodium: copied "${SOURCE}" to "${DEST}".`);