diff --git a/README.md b/README.md index f4d3c290..a4311c33 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ mosaic wizard # Full guided setup (gateway install → verify) ### Requirements -- Node.js ≥ 20 +- Node.js ≥ 22 - npm (for global @mosaicstack/mosaic install) - One or more runtimes: [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [Codex](https://github.com/openai/codex), [OpenCode](https://opencode.ai), or [Pi](https://github.com/mariozechner/pi-coding-agent) @@ -200,7 +200,7 @@ Consent state is persisted in config. Remote upload is a no-op until you run `mo ### Prerequisites -- Node.js ≥ 20 +- Node.js ≥ 22 - pnpm 10.6+ - Docker & Docker Compose diff --git a/tools/install-next-lane.test.sh b/tools/install-next-lane.test.sh index 4dee1340..1d017106 100755 --- a/tools/install-next-lane.test.sh +++ b/tools/install-next-lane.test.sh @@ -12,6 +12,23 @@ MOSAIC_HOME="$TMP/mosaic" STATE="$TMP/state" LOG="$TMP/npm.log" mkdir -p "$FAKE_BIN" "$HOME_DIR" "$STATE" +REAL_NODE="$(command -v node)" +export MOSAIC_TEST_REAL_NODE="$REAL_NODE" + +cat > "$FAKE_BIN/node" <<'FAKE_NODE' +#!/usr/bin/env bash +set -euo pipefail +if [[ "$*" == *'process.versions.node.split'* ]]; then + printf '%s' "${MOSAIC_TEST_NODE_MAJOR:-22}" + exit 0 +fi +if [[ "${1:-}" == "--version" ]]; then + printf 'v%s.0.0\n' "${MOSAIC_TEST_NODE_MAJOR:-22}" + exit 0 +fi +exec "${MOSAIC_TEST_REAL_NODE:?}" "$@" +FAKE_NODE +chmod +x "$FAKE_BIN/node" cat > "$FAKE_BIN/npm" <<'FAKE_NPM' #!/usr/bin/env bash @@ -135,6 +152,20 @@ reset_state() { rm -f "$STATE"/* } +reset_state +echo "[test] --next rejects Node 20 before any install action" +if OUTPUT="$( + HOME="$HOME_DIR" MOSAIC_HOME="$MOSAIC_HOME" MOSAIC_PREFIX="$PREFIX" MOSAIC_NO_COLOR=1 \ + MOSAIC_TEST_NPM_LOG="$LOG" MOSAIC_TEST_STATE="$STATE" MOSAIC_TEST_REAL_NODE="$REAL_NODE" \ + MOSAIC_TEST_NODE_MAJOR=20 PATH="$FAKE_BIN:$PATH" \ + bash "$ROOT/tools/install.sh" --cli --next --yes --no-auto-launch 2>&1 +)"; then + echo "expected Node 20 next-lane install to fail" >&2 + exit 1 +fi +grep -qF 'Node.js >= 22 required for the --next lane' <<<"$OUTPUT" +[[ ! -s "$LOG" ]] || { echo "Node 20 gate ran npm actions" >&2; exit 1; } + reset_state echo "[test] --next fast path pins resolved package versions" OUTPUT="$( diff --git a/tools/install.sh b/tools/install.sh index 96c9ad49..123e9159 100755 --- a/tools/install.sh +++ b/tools/install.sh @@ -526,6 +526,10 @@ if [[ "$NODE_MAJOR" -lt 20 ]]; then fail "Node.js >= 20 required (found v$(node --version))" exit 1 fi +if [[ "$FLAG_NEXT" == "true" && "$NODE_MAJOR" -lt 22 ]]; then + fail "Node.js >= 22 required for the --next lane (found v$(node --version))" + exit 1 +fi echo "" echo "${BOLD}Mosaic Stack Installer${RESET}"