From bef8ff5130e0eea81c573eb6a10b8384a94282f0 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 19 Jul 2026 07:00:15 +0000 Subject: [PATCH 1/7] Drop Node 22 support, require Node 24+ Remove Node 22 from the CI test matrix and raise the minimum supported Node.js version to 24 across package.json engines and the documentation (README, CLAUDE.md, copilot instructions). --- .github/copilot-instructions.md | 2 +- .github/workflows/ci.yml | 2 +- CLAUDE.md | 2 +- README.md | 4 ++-- package-lock.json | 2 +- package.json | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index d29a16d..55458d5 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -2,7 +2,7 @@ ## Build, test, and lint commands -- Use **Node.js 22+** (`package.json` enforces `node >=22`). +- Use **Node.js 24+** (`package.json` enforces `node >=24`). - Install dependencies with `npm install`. - Run the type check with `npm run typecheck`. - Run the production build with `npm run build`. This already runs `npm run typecheck`, bundles `src/server/index.ts` and `src/client/main.ts` with esbuild, recreates `dist/`, and copies `index.html`, `styles.css`, and the SVG assets into `dist/client`. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7bcb743..f59c9c4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [22, 24, 26] + node-version: [24, 26] steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 diff --git a/CLAUDE.md b/CLAUDE.md index 03ff52c..fe6fb77 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,7 +2,7 @@ ## Build, test, and lint commands -- Use **Node.js 22+** (`package.json` enforces `node >=22`). +- Use **Node.js 24+** (`package.json` enforces `node >=24`). - Install dependencies with `npm install`. - Run the type check with `npm run typecheck`. - Run the production build with `npm run build`. This already runs `npm run typecheck`, bundles `src/server/index.ts` and `src/client/main.ts` with esbuild, recreates `dist/`, and copies `index.html`, `styles.css`, and the SVG assets into `dist/client`. diff --git a/README.md b/README.md index 5e26d39..eaa98e6 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ npm run start The application is then available at `http://localhost:9001`. -Run the test suite (requires Node.js 22+): +Run the test suite (requires Node.js 24+): ```bash npm test @@ -143,7 +143,7 @@ This section is a complete walkthrough for running the viewer as a background se ### Prerequisites - A Linux host with **systemd** (the default on Debian, Ubuntu, Raspberry Pi OS, Fedora, etc.). -- **Node.js 20 or newer** installed on the target host. Check with `node --version`. Because the server is bundled into a single `dist/server/index.cjs` file, this is the only runtime dependency — you do **not** need to run `npm install` on the target host. +- **Node.js 24 or newer** installed on the target host. Check with `node --version`. Because the server is bundled into a single `dist/server/index.cjs` file, this is the only runtime dependency — you do **not** need to run `npm install` on the target host. - The `openhab` user. On a standard openHAB installation it already exists and owns the log files. If it does not exist, create a dedicated service user: ```bash diff --git a/package-lock.json b/package-lock.json index 98c150c..8719b97 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "typescript": "^7.0.2" }, "engines": { - "node": ">=22" + "node": ">=24" } }, "node_modules/@asamuzakjp/css-color": { diff --git a/package.json b/package.json index 64a360a..35b27a5 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "description": "Live web viewer for openHAB events.log and openhab.log", "license": "MIT", "engines": { - "node": ">=22" + "node": ">=24" }, "scripts": { "typecheck": "tsc --build", From 18bf42f046495eb025a16d16ed17a8a21170629a Mon Sep 17 00:00:00 2001 From: Lars Laskowski <26182282+LarsLaskowski@users.noreply.github.com> Date: Sun, 19 Jul 2026 09:03:26 +0200 Subject: [PATCH 2/7] Update Node.js requirement to 24+ in AGENTS.md --- AGENTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index bbd1e2f..db79855 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ ## Build, test, and lint commands -- Use **Node.js 22+** (`package.json` enforces `node >=22`). +- Use **Node.js 24+** (`package.json` enforces `node >=24`). - Install dependencies with `npm install`. - Run the type check with `npm run typecheck`. - Run the production build with `npm run build`. This already runs `npm run typecheck`, bundles `src/server/index.ts` and `src/client/main.ts` with esbuild, recreates `dist/`, and copies `index.html`, `styles.css`, and the SVG assets into `dist/client`. From 5e521941bbcc4049f43d3cfcddb7cdd9e2f71bb7 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 19 Jul 2026 07:08:51 +0000 Subject: [PATCH 3/7] Publish separate release assets per supported Node.js version Build and package the release once each for Node.js 24 and Node.js 26, producing openhab-log-viewer--node24 and -node26 archives instead of a single unversioned asset. --- .github/workflows/release.yml | 56 +++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 70bba6e..f4fd466 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -71,31 +71,59 @@ jobs: ref: ${{ steps.tag.outputs.tag }} fetch-depth: 0 # full history needed for generated release notes - - name: Setup Node.js + - name: Align package.json to tag version + run: | + set -euo pipefail + # Keep the packaged package.json in sync with the release tag. + # --no-git-tag-version only edits the files; --allow-same-version + # avoids failing when the version already matches the tag. + npm version "${{ steps.tag.outputs.version }}" \ + --no-git-tag-version --allow-same-version + + # The app is bundled into a single dependency-free dist/server/index.cjs, so + # the two builds below produce functionally identical output regardless of + # which Node.js version built them. Building and packaging once per + # supported Node.js version still validates the build against each + # supported runtime and gives users a per-version asset to download. + - name: Setup Node.js 24 uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: 24 cache: npm - - name: Install dependencies + - name: Install dependencies (Node.js 24) run: npm ci - - name: Align package.json to tag version + - name: Build (Node.js 24) + run: npm run build + + - name: Package build output (Node.js 24) run: | set -euo pipefail - # Keep the packaged package.json in sync with the release tag. - # --no-git-tag-version only edits the files; --allow-same-version - # avoids failing when the version already matches the tag. - npm version "${{ steps.tag.outputs.version }}" \ - --no-git-tag-version --allow-same-version + PKG_NAME="openhab-log-viewer-${{ steps.tag.outputs.tag }}-node24" + mkdir -p "release/${PKG_NAME}" + cp -r dist "release/${PKG_NAME}/dist" + cp -r deploy "release/${PKG_NAME}/deploy" + cp "${GITHUB_WORKSPACE}/package.json" README.md "release/${PKG_NAME}/" + tar -czf "${PKG_NAME}.tar.gz" -C release "${PKG_NAME}" + (cd release && zip -r "../${PKG_NAME}.zip" "${PKG_NAME}") + + - name: Setup Node.js 26 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 26 + cache: npm + + - name: Install dependencies (Node.js 26) + run: npm ci - - name: Build + - name: Build (Node.js 26) run: npm run build - - name: Package build output + - name: Package build output (Node.js 26) run: | set -euo pipefail - PKG_NAME="openhab-log-viewer-${{ steps.tag.outputs.tag }}" + PKG_NAME="openhab-log-viewer-${{ steps.tag.outputs.tag }}-node26" mkdir -p "release/${PKG_NAME}" cp -r dist "release/${PKG_NAME}/dist" cp -r deploy "release/${PKG_NAME}/deploy" @@ -110,5 +138,7 @@ jobs: name: ${{ steps.tag.outputs.tag }} generate_release_notes: true files: | - openhab-log-viewer-*.tar.gz - openhab-log-viewer-*.zip + openhab-log-viewer-*-node24.tar.gz + openhab-log-viewer-*-node24.zip + openhab-log-viewer-*-node26.tar.gz + openhab-log-viewer-*-node26.zip From 9ff053aa60a44fae051e063356e8954e12fa4960 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 19 Jul 2026 07:10:17 +0000 Subject: [PATCH 4/7] Raise server bundle esbuild target to node24 The server build's esbuild target was still pinned to node20 even though the minimum supported runtime is now Node.js 24. Align it so the bundle isn't down-leveled below the actually supported baseline. --- scripts/build.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build.mjs b/scripts/build.mjs index 7f8a3cf..ddf356d 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -21,7 +21,7 @@ await build({ bundle: true, platform: 'node', format: 'cjs', - target: 'node20', + target: 'node24', sourcemap: true, logLevel: 'info' }); From 733eea217910a46d81a0f4fc8dbb87932e2fef90 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 19 Jul 2026 07:19:42 +0000 Subject: [PATCH 5/7] Target each release package's esbuild output at its own Node.js version scripts/build.mjs now reads the server bundle's esbuild target from ESBUILD_SERVER_TARGET (default node24). The release workflow sets it to node24/node26 for the matching build step, so each per-version package's bundle is actually targeted at the Node.js version it was built for, instead of both being capped at node24 regardless of which runtime built them. --- .github/workflows/release.yml | 13 ++++++++----- scripts/build.mjs | 3 ++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f4fd466..10dd072 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -80,11 +80,10 @@ jobs: npm version "${{ steps.tag.outputs.version }}" \ --no-git-tag-version --allow-same-version - # The app is bundled into a single dependency-free dist/server/index.cjs, so - # the two builds below produce functionally identical output regardless of - # which Node.js version built them. Building and packaging once per - # supported Node.js version still validates the build against each - # supported runtime and gives users a per-version asset to download. + # Building and packaging once per supported Node.js version validates the + # build against each supported runtime and gives users a per-version + # asset to download. ESBUILD_SERVER_TARGET is set to match, so each + # package's bundle is targeted at the Node.js version it was built for. - name: Setup Node.js 24 uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: @@ -96,6 +95,8 @@ jobs: - name: Build (Node.js 24) run: npm run build + env: + ESBUILD_SERVER_TARGET: node24 - name: Package build output (Node.js 24) run: | @@ -119,6 +120,8 @@ jobs: - name: Build (Node.js 26) run: npm run build + env: + ESBUILD_SERVER_TARGET: node26 - name: Package build output (Node.js 26) run: | diff --git a/scripts/build.mjs b/scripts/build.mjs index ddf356d..a2acc02 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -9,6 +9,7 @@ const clientDistDir = path.join(distDir, 'client'); const serverDistDir = path.join(distDir, 'server'); const clientAssetsDir = path.join(clientDistDir, 'assets'); const packageJson = JSON.parse(await readFile(path.join(rootDir, 'package.json'), 'utf8')); +const serverTarget = process.env.ESBUILD_SERVER_TARGET ?? 'node24'; await rm(distDir, { recursive: true, force: true }); await mkdir(clientDistDir, { recursive: true }); @@ -21,7 +22,7 @@ await build({ bundle: true, platform: 'node', format: 'cjs', - target: 'node24', + target: serverTarget, sourcemap: true, logLevel: 'info' }); From bd5a9daa46354b6e2fa7eeac75c2904a0139e5d2 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 19 Jul 2026 07:34:10 +0000 Subject: [PATCH 6/7] Revert Node.js minimum version bump, keep Node 22 support Node 22 is still in Maintenance LTS, so there is no need to drop it. Restores engines.node, the CI matrix, and all documentation (README, CLAUDE.md, copilot-instructions.md, AGENTS.md) to the Node.js 22+ baseline, and reverts the esbuild target and dual node24/node26 release packaging back to a single build. The release workflow now builds with Node.js 22 instead of Node.js 24: building with the oldest supported runtime keeps the bundle's esbuild target maximally conservative, so the single published artifact stays compatible with Node.js 22, 24, and 26 hosts. --- .github/copilot-instructions.md | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 64 +++++++++------------------------ AGENTS.md | 2 +- CLAUDE.md | 2 +- README.md | 4 +-- package-lock.json | 2 +- package.json | 2 +- scripts/build.mjs | 3 +- 9 files changed, 26 insertions(+), 57 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 55458d5..d29a16d 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -2,7 +2,7 @@ ## Build, test, and lint commands -- Use **Node.js 24+** (`package.json` enforces `node >=24`). +- Use **Node.js 22+** (`package.json` enforces `node >=22`). - Install dependencies with `npm install`. - Run the type check with `npm run typecheck`. - Run the production build with `npm run build`. This already runs `npm run typecheck`, bundles `src/server/index.ts` and `src/client/main.ts` with esbuild, recreates `dist/`, and copies `index.html`, `styles.css`, and the SVG assets into `dist/client`. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f59c9c4..7bcb743 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [24, 26] + node-version: [22, 24, 26] steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 10dd072..6d08488 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -71,62 +71,34 @@ jobs: ref: ${{ steps.tag.outputs.tag }} fetch-depth: 0 # full history needed for generated release notes - - name: Align package.json to tag version - run: | - set -euo pipefail - # Keep the packaged package.json in sync with the release tag. - # --no-git-tag-version only edits the files; --allow-same-version - # avoids failing when the version already matches the tag. - npm version "${{ steps.tag.outputs.version }}" \ - --no-git-tag-version --allow-same-version - - # Building and packaging once per supported Node.js version validates the - # build against each supported runtime and gives users a per-version - # asset to download. ESBUILD_SERVER_TARGET is set to match, so each - # package's bundle is targeted at the Node.js version it was built for. - - name: Setup Node.js 24 + # Building the release with the oldest supported Node.js version (22) + # keeps the bundle's esbuild target maximally conservative, so the same + # single artifact stays compatible with Node.js 22, 24, and 26 hosts. + - name: Setup Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: 24 + node-version: 22 cache: npm - - name: Install dependencies (Node.js 24) + - name: Install dependencies run: npm ci - - name: Build (Node.js 24) - run: npm run build - env: - ESBUILD_SERVER_TARGET: node24 - - - name: Package build output (Node.js 24) + - name: Align package.json to tag version run: | set -euo pipefail - PKG_NAME="openhab-log-viewer-${{ steps.tag.outputs.tag }}-node24" - mkdir -p "release/${PKG_NAME}" - cp -r dist "release/${PKG_NAME}/dist" - cp -r deploy "release/${PKG_NAME}/deploy" - cp "${GITHUB_WORKSPACE}/package.json" README.md "release/${PKG_NAME}/" - tar -czf "${PKG_NAME}.tar.gz" -C release "${PKG_NAME}" - (cd release && zip -r "../${PKG_NAME}.zip" "${PKG_NAME}") - - - name: Setup Node.js 26 - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version: 26 - cache: npm - - - name: Install dependencies (Node.js 26) - run: npm ci + # Keep the packaged package.json in sync with the release tag. + # --no-git-tag-version only edits the files; --allow-same-version + # avoids failing when the version already matches the tag. + npm version "${{ steps.tag.outputs.version }}" \ + --no-git-tag-version --allow-same-version - - name: Build (Node.js 26) + - name: Build run: npm run build - env: - ESBUILD_SERVER_TARGET: node26 - - name: Package build output (Node.js 26) + - name: Package build output run: | set -euo pipefail - PKG_NAME="openhab-log-viewer-${{ steps.tag.outputs.tag }}-node26" + PKG_NAME="openhab-log-viewer-${{ steps.tag.outputs.tag }}" mkdir -p "release/${PKG_NAME}" cp -r dist "release/${PKG_NAME}/dist" cp -r deploy "release/${PKG_NAME}/deploy" @@ -141,7 +113,5 @@ jobs: name: ${{ steps.tag.outputs.tag }} generate_release_notes: true files: | - openhab-log-viewer-*-node24.tar.gz - openhab-log-viewer-*-node24.zip - openhab-log-viewer-*-node26.tar.gz - openhab-log-viewer-*-node26.zip + openhab-log-viewer-*.tar.gz + openhab-log-viewer-*.zip diff --git a/AGENTS.md b/AGENTS.md index db79855..bbd1e2f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ ## Build, test, and lint commands -- Use **Node.js 24+** (`package.json` enforces `node >=24`). +- Use **Node.js 22+** (`package.json` enforces `node >=22`). - Install dependencies with `npm install`. - Run the type check with `npm run typecheck`. - Run the production build with `npm run build`. This already runs `npm run typecheck`, bundles `src/server/index.ts` and `src/client/main.ts` with esbuild, recreates `dist/`, and copies `index.html`, `styles.css`, and the SVG assets into `dist/client`. diff --git a/CLAUDE.md b/CLAUDE.md index fe6fb77..03ff52c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,7 +2,7 @@ ## Build, test, and lint commands -- Use **Node.js 24+** (`package.json` enforces `node >=24`). +- Use **Node.js 22+** (`package.json` enforces `node >=22`). - Install dependencies with `npm install`. - Run the type check with `npm run typecheck`. - Run the production build with `npm run build`. This already runs `npm run typecheck`, bundles `src/server/index.ts` and `src/client/main.ts` with esbuild, recreates `dist/`, and copies `index.html`, `styles.css`, and the SVG assets into `dist/client`. diff --git a/README.md b/README.md index eaa98e6..5e26d39 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ npm run start The application is then available at `http://localhost:9001`. -Run the test suite (requires Node.js 24+): +Run the test suite (requires Node.js 22+): ```bash npm test @@ -143,7 +143,7 @@ This section is a complete walkthrough for running the viewer as a background se ### Prerequisites - A Linux host with **systemd** (the default on Debian, Ubuntu, Raspberry Pi OS, Fedora, etc.). -- **Node.js 24 or newer** installed on the target host. Check with `node --version`. Because the server is bundled into a single `dist/server/index.cjs` file, this is the only runtime dependency — you do **not** need to run `npm install` on the target host. +- **Node.js 20 or newer** installed on the target host. Check with `node --version`. Because the server is bundled into a single `dist/server/index.cjs` file, this is the only runtime dependency — you do **not** need to run `npm install` on the target host. - The `openhab` user. On a standard openHAB installation it already exists and owns the log files. If it does not exist, create a dedicated service user: ```bash diff --git a/package-lock.json b/package-lock.json index 8719b97..98c150c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "typescript": "^7.0.2" }, "engines": { - "node": ">=24" + "node": ">=22" } }, "node_modules/@asamuzakjp/css-color": { diff --git a/package.json b/package.json index 35b27a5..64a360a 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "description": "Live web viewer for openHAB events.log and openhab.log", "license": "MIT", "engines": { - "node": ">=24" + "node": ">=22" }, "scripts": { "typecheck": "tsc --build", diff --git a/scripts/build.mjs b/scripts/build.mjs index a2acc02..7f8a3cf 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -9,7 +9,6 @@ const clientDistDir = path.join(distDir, 'client'); const serverDistDir = path.join(distDir, 'server'); const clientAssetsDir = path.join(clientDistDir, 'assets'); const packageJson = JSON.parse(await readFile(path.join(rootDir, 'package.json'), 'utf8')); -const serverTarget = process.env.ESBUILD_SERVER_TARGET ?? 'node24'; await rm(distDir, { recursive: true, force: true }); await mkdir(clientDistDir, { recursive: true }); @@ -22,7 +21,7 @@ await build({ bundle: true, platform: 'node', format: 'cjs', - target: serverTarget, + target: 'node20', sourcemap: true, logLevel: 'info' }); From 159f68587c63a6394c71f6a96180e5715bf7269a Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 19 Jul 2026 07:36:50 +0000 Subject: [PATCH 7/7] Align systemd prerequisite and esbuild target with Node 22 baseline The README's systemd deployment prerequisite still said Node.js 20, inconsistent with the package.json engines >=22 requirement. The server bundle's esbuild target was similarly at node20. Both now match the actual documented minimum of Node.js 22. --- README.md | 2 +- scripts/build.mjs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5e26d39..939726c 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ This section is a complete walkthrough for running the viewer as a background se ### Prerequisites - A Linux host with **systemd** (the default on Debian, Ubuntu, Raspberry Pi OS, Fedora, etc.). -- **Node.js 20 or newer** installed on the target host. Check with `node --version`. Because the server is bundled into a single `dist/server/index.cjs` file, this is the only runtime dependency — you do **not** need to run `npm install` on the target host. +- **Node.js 22 or newer** installed on the target host. Check with `node --version`. Because the server is bundled into a single `dist/server/index.cjs` file, this is the only runtime dependency — you do **not** need to run `npm install` on the target host. - The `openhab` user. On a standard openHAB installation it already exists and owns the log files. If it does not exist, create a dedicated service user: ```bash diff --git a/scripts/build.mjs b/scripts/build.mjs index 7f8a3cf..a7214ac 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -21,7 +21,7 @@ await build({ bundle: true, platform: 'node', format: 'cjs', - target: 'node20', + target: 'node22', sourcemap: true, logLevel: 'info' });