diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml
index 4da6060..b05506a 100644
--- a/.github/workflows/docker-publish.yml
+++ b/.github/workflows/docker-publish.yml
@@ -14,9 +14,9 @@ env:
DOCKERHUB_IMAGE: coderluii/holycode
GHCR_IMAGE: ghcr.io/coderluii/holycode
CANDIDATE_IMAGE: ghcr.io/coderluii/holycode
- PREVIOUS_IMAGE: coderluii/holycode:1.1.4@sha256:56756701a8b7468e1929b956950edb06ba8e0f0c87c5796aa57bde1389f82a91
- PREVIOUS_VERSION: v1.1.4
- RELEASE_VERSION: v1.1.5
+ PREVIOUS_IMAGE: coderluii/holycode:1.1.5@sha256:804ec668b97466dba9a26ded8af258fabc2d778047b7c8aebdaab7bccd9a3ae8
+ PREVIOUS_VERSION: v1.1.5
+ RELEASE_VERSION: v1.1.6
# Required secrets:
# DOCKERHUB_USERNAME - Docker Hub username with access to coderluii/holycode.
@@ -74,7 +74,7 @@ jobs:
- name: Set up Node for Renovate validation
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
- node-version: 24.18.0
+ node-version: 24.19.0
- name: Static release validation
run: |
@@ -87,7 +87,7 @@ jobs:
ruby -e 'require "yaml"; Dir[".github/workflows/*.yml"].each { |path| YAML.load_file(path) }'
docker compose -f docker-compose.yaml config --no-interpolate >/tmp/docker-compose.yaml
docker compose -f docker-compose.full.yaml config --no-interpolate >/tmp/docker-compose.full.yaml
- bash scripts/validate_renovate_extraction.sh 44.2.3
+ bash scripts/validate_renovate_extraction.sh 44.24.2
- name: Free up disk space
run: |
@@ -151,12 +151,12 @@ jobs:
suffix: amd64
runner: ubuntu-24.04
scout_arch: amd64
- scout_sha256: 0f778f9d833f28bc6cccff95e33039849c0afcecafa38d9f46fe74bfd0915714
+ scout_sha256: f4e2814bd61040365153d5b964b144cb2dc6ee536a68b5bac4cadf00fc0ec34b
- platform: linux/arm64
suffix: arm64
runner: ubuntu-24.04-arm
scout_arch: arm64
- scout_sha256: 88eecb7273f19bd18300d70e6f85b2e7d784e9e4f3cbb4a2b400db6b8355a52a
+ scout_sha256: 8b21594c72d4d9403a82a49e9dbdfc04c27c6a21933906f1eefbb0beabe22d58
permissions:
contents: read
packages: read
@@ -202,7 +202,7 @@ jobs:
- name: Generate SPDX SBOM for Docker Scout
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
- version: v0.72.0
+ version: v0.73.0
image-ref: holycode-protected-validation:${{ matrix.suffix }}
format: spdx-json
output: holycode-${{ matrix.suffix }}.spdx.json
@@ -210,7 +210,7 @@ jobs:
- name: Install Docker Scout CLI
env:
SCOUT_SHA256: ${{ matrix.scout_sha256 }}
- SCOUT_VERSION: 1.23.1
+ SCOUT_VERSION: 1.24.0
run: |
set -euo pipefail
@@ -282,7 +282,7 @@ jobs:
- name: Trivy vulnerability report
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
- version: v0.72.0
+ version: v0.73.0
image-ref: holycode-protected-validation:${{ matrix.suffix }}
format: json
scanners: vuln,secret
@@ -293,7 +293,7 @@ jobs:
- name: Trivy fixable critical and high gate
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
- version: v0.72.0
+ version: v0.73.0
image-ref: holycode-protected-validation:${{ matrix.suffix }}
format: json
scanners: vuln,secret
diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml
index 8cdeca0..7d47506 100644
--- a/.github/workflows/pr-validation.yml
+++ b/.github/workflows/pr-validation.yml
@@ -20,7 +20,7 @@ jobs:
- name: Set up Node for Renovate validation
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
- node-version: 24.18.0
+ node-version: 24.19.0
- name: Python version policy tests
run: python -m unittest discover -s tests
@@ -48,11 +48,21 @@ jobs:
fi
- name: Renovate configuration
- run: bash scripts/validate_renovate_extraction.sh 44.2.3
+ run: bash scripts/validate_renovate_extraction.sh 44.24.2
build-and-smoke-test:
needs: static-validation
- runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - runner: ubuntu-24.04
+ platform: linux/amd64
+ suffix: amd64
+ - runner: ubuntu-24.04-arm
+ platform: linux/arm64
+ suffix: arm64
+ runs-on: ${{ matrix.runner }}
permissions:
contents: read
@@ -61,14 +71,14 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Build image
- run: docker build -t holycode-pr-test .
+ run: docker build --platform "${{ matrix.platform }}" -t "holycode-pr-test:${{ matrix.suffix }}" .
- name: Smoke test image tools and secret hygiene
- run: bash scripts/smoke_image.sh holycode-pr-test
+ run: bash scripts/smoke_image.sh "holycode-pr-test:${{ matrix.suffix }}"
- name: Validate Drizzle esbuild remediation
run: |
- docker run --rm --entrypoint sh holycode-pr-test -lc '
+ docker run --rm --entrypoint sh "holycode-pr-test:${{ matrix.suffix }}" -lc '
set -eu
test ! -e /usr/local/lib/node_modules/drizzle-kit/node_modules/@esbuild-kit
jq -e ".version == \"0.28.1\"" /usr/local/lib/node_modules/drizzle-kit/node_modules/esbuild/package.json >/dev/null
@@ -77,13 +87,13 @@ jobs:
'
- name: Validate plugin pin modes
- run: bash scripts/test_plugin_modes.sh holycode-pr-test
+ run: bash scripts/test_plugin_modes.sh "holycode-pr-test:${{ matrix.suffix }}"
- name: Smoke test Paperclip skills catalog
run: |
set -eu
- docker run --rm --entrypoint sh holycode-pr-test -lc "
+ docker run --rm --entrypoint sh "holycode-pr-test:${{ matrix.suffix }}" -lc "
set -eu
test -f /usr/local/lib/node_modules/paperclipai/node_modules/@paperclipai/skills-catalog/generated/catalog.json
node --input-type=module -e '
@@ -102,7 +112,7 @@ jobs:
docker run -d --name holycode-paperclip-test \
-e ENABLE_PAPERCLIP=true \
- holycode-pr-test
+ "holycode-pr-test:${{ matrix.suffix }}"
cleanup() {
docker logs holycode-paperclip-test || true
@@ -151,15 +161,15 @@ jobs:
docker volume create holycode-hermes-data >/dev/null
trap 'docker volume rm holycode-hermes-data >/dev/null 2>&1 || true' EXIT
- docker run --rm --entrypoint sh -v holycode-hermes-data:/home/opencode holycode-pr-test \
+ docker run --rm --entrypoint sh -v holycode-hermes-data:/home/opencode "holycode-pr-test:${{ matrix.suffix }}" \
-lc 'mkdir -p /home/opencode/.hermes && touch /home/opencode/.hermes/preserved'
if docker run --rm -v holycode-hermes-data:/home/opencode \
- -e ENABLE_HERMES=true holycode-pr-test >/tmp/holycode-hermes.log 2>&1; then
+ -e ENABLE_HERMES=true "holycode-pr-test:${{ matrix.suffix }}" >/tmp/holycode-hermes.log 2>&1; then
echo "ENABLE_HERMES=true unexpectedly started the removed bundled service" >&2
exit 1
fi
grep -F "bundled Hermes is temporarily unavailable" /tmp/holycode-hermes.log
grep -F "/home/opencode/.hermes is preserved" /tmp/holycode-hermes.log
docker run --rm --entrypoint test -v holycode-hermes-data:/home/opencode \
- holycode-pr-test -f /home/opencode/.hermes/preserved
+ "holycode-pr-test:${{ matrix.suffix }}" -f /home/opencode/.hermes/preserved
diff --git a/Dockerfile b/Dockerfile
index d2037d0..4253a08 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -4,31 +4,28 @@
# ==============================================================================
# renovate: datasource=github-releases depName=cli/cli
-ARG GITHUB_CLI_VERSION=2.96.0
-ARG GITHUB_CLI_REF=b300f2ec7ec9dc9addc39b2ad88c54097ded7ca0
+ARG GITHUB_CLI_VERSION=2.97.0
+ARG GITHUB_CLI_REF=55dbb4dc6b7edb10b48e3d7fc5bccd32318d1b55
# renovate: datasource=github-releases depName=junegunn/fzf
-ARG FZF_VERSION=0.74.1
-ARG FZF_REF=eae8d9d27eaeffc777699c01bf8f8b8c071908c1
+ARG FZF_VERSION=0.74.2
+ARG FZF_REF=3337be9d450cd349e99273a2d3985ceaf5f3753f
# renovate: datasource=github-releases depName=jesseduffield/lazygit
-ARG LAZYGIT_VERSION=0.63.1
-ARG LAZYGIT_REF=aafe61082e7ed383d318fd40e48f85645e6afc7b
+ARG LAZYGIT_VERSION=0.64.0
+ARG LAZYGIT_REF=aee0e40ec1235476e9328678f0f3e2462576b9ae
# Rebuild exact release sources with reviewed dependency fixes.
-FROM --platform=$BUILDPLATFORM golang:1.26.5-trixie@sha256:4ee9ffa999b4583ce281939cdff828763083610292f252279a0cee77473bd9a7 AS github-cli-builder
+FROM --platform=$BUILDPLATFORM golang:1.26.5-trixie@sha256:98988b42f3293b627bf07c884ff17181a59501769cd8c06c7ba901e0ce2c9853 AS github-cli-builder
ARG GITHUB_CLI_VERSION
ARG GITHUB_CLI_REF
ARG TARGETARCH
-COPY patches/github-cli-modules.patch /tmp/github-cli-modules.patch
RUN git clone --branch "v${GITHUB_CLI_VERSION}" --depth 1 \
https://github.com/cli/cli.git /src && \
cd /src && \
test "$(git rev-parse HEAD)" = "${GITHUB_CLI_REF}" && \
test "$(git describe --tags --exact-match HEAD)" = "v${GITHUB_CLI_VERSION}" && \
- git apply --check /tmp/github-cli-modules.patch && \
- git apply /tmp/github-cli-modules.patch && \
test "$(go list -m -f '{{.Version}}' google.golang.org/grpc)" = "v1.82.1" && \
- test "$(go list -m -f '{{.Version}}' golang.org/x/text)" = "v0.39.0" && \
- test "$(go list -m -f '{{.Version}}' github.com/klauspost/compress)" = "v1.18.7" && \
+ test "$(go list -m -f '{{.Version}}' golang.org/x/text)" = "v0.40.0" && \
+ test "$(go list -m -f '{{.Version}}' github.com/klauspost/compress)" = "v1.19.1" && \
go mod verify && \
mkdir -p /tmp/gh-test && \
chown -R nobody:nogroup /src /tmp/gh-test && \
@@ -41,10 +38,10 @@ RUN git clone --branch "v${GITHUB_CLI_VERSION}" --depth 1 \
GOOS=linux GOARCH="${GH_GOARCH}" CGO_ENABLED=0 && \
install -D -m 0755 bin/gh /out/gh && \
go version -m /out/gh | grep -F "go1.26.5" && \
- go version -m /out/gh | grep -E 'github.com/klauspost/compress[[:space:]]+v1\.18\.7' && \
- go version -m /out/gh | grep -E 'golang.org/x/text[[:space:]]+v0\.39\.0'
+ go version -m /out/gh | grep -E 'github.com/klauspost/compress[[:space:]]+v1\.19\.1' && \
+ go version -m /out/gh | grep -E 'golang.org/x/text[[:space:]]+v0\.40\.0'
-FROM --platform=$BUILDPLATFORM golang:1.26.5-trixie@sha256:4ee9ffa999b4583ce281939cdff828763083610292f252279a0cee77473bd9a7 AS fzf-builder
+FROM --platform=$BUILDPLATFORM golang:1.26.5-trixie@sha256:98988b42f3293b627bf07c884ff17181a59501769cd8c06c7ba901e0ce2c9853 AS fzf-builder
ARG FZF_VERSION
ARG FZF_REF
ARG TARGETARCH
@@ -70,20 +67,17 @@ RUN git clone --branch "v${FZF_VERSION}" --depth 1 \
-o /out/fzf && \
go version -m /out/fzf | grep -E 'golang.org/x/sys[[:space:]]+v0\.44\.0'
-FROM --platform=$BUILDPLATFORM golang:1.26.5-trixie@sha256:4ee9ffa999b4583ce281939cdff828763083610292f252279a0cee77473bd9a7 AS lazygit-builder
+FROM --platform=$BUILDPLATFORM golang:1.26.5-trixie@sha256:98988b42f3293b627bf07c884ff17181a59501769cd8c06c7ba901e0ce2c9853 AS lazygit-builder
ARG LAZYGIT_VERSION
ARG LAZYGIT_REF
ARG TARGETARCH
-COPY patches/lazygit-x-text-0.39.0.patch /tmp/lazygit-x-text-0.39.0.patch
RUN git clone --branch "v${LAZYGIT_VERSION}" --depth 1 \
https://github.com/jesseduffield/lazygit.git /src && \
cd /src && \
test "$(git rev-parse HEAD)" = "${LAZYGIT_REF}" && \
test "$(git describe --tags --exact-match HEAD)" = "v${LAZYGIT_VERSION}" && \
- git apply --check /tmp/lazygit-x-text-0.39.0.patch && \
- git apply /tmp/lazygit-x-text-0.39.0.patch && \
export GOFLAGS=-mod=mod && \
- test "$(go list -m -f '{{.Version}}' golang.org/x/text)" = "v0.39.0" && \
+ test "$(go list -m -f '{{.Version}}' golang.org/x/text)" = "v0.40.0" && \
go mod verify && \
LAZYGIT_MODULE_FILES_SHA256="$(sha256sum go.mod go.sum)" && \
go mod vendor && \
@@ -96,9 +90,9 @@ RUN git clone --branch "v${LAZYGIT_VERSION}" --depth 1 \
GOOS=linux GOARCH="${LAZYGIT_GOARCH}" CGO_ENABLED=0 go build -trimpath \
-ldflags "-s -w -X main.version=${LAZYGIT_VERSION} -X main.commit=${LAZYGIT_REF} -X main.date=${BUILD_DATE} -X main.buildSource=binaryRelease" \
-o /out/lazygit && \
- go version -m /out/lazygit | grep -E 'golang.org/x/text[[:space:]]+v0\.39\.0'
+ go version -m /out/lazygit | grep -E 'golang.org/x/text[[:space:]]+v0\.40\.0'
-FROM node:24.18.0-trixie-slim@sha256:ae91dcc111a68c9d2d81ff2a17bda61be126426176fde6fe7d08ab13b7f50573
+FROM node:24.19.0-trixie-slim@sha256:0711b541c1c33a8a530ac4f0d391baa9a15b3d804695b1b24a47daa5fb60e74d
# ---------- Build args ----------
ARG GITHUB_CLI_VERSION
@@ -111,29 +105,29 @@ ARG DELTA_VERSION=0.19.2
# renovate: datasource=github-releases depName=eza-community/eza
ARG EZA_VERSION=0.23.5
# renovate: datasource=npm depName=opencode-ai
-ARG OPENCODE_VERSION=1.18.9
+ARG OPENCODE_VERSION=1.18.16
# renovate: datasource=npm depName=@anthropic-ai/claude-code
-ARG CLAUDE_CODE_VERSION=2.1.220
+ARG CLAUDE_CODE_VERSION=2.1.228
# renovate: datasource=npm depName=paperclipai
ARG PAPERCLIP_VERSION=2026.722.0
# renovate: datasource=npm depName=undici
ARG PAPERCLIP_UNDICI_VERSION=6.28.0
# renovate: datasource=npm depName=opencode-claude-auth
-ARG CLAUDE_AUTH_PLUGIN_VERSION=2.1.5
+ARG CLAUDE_AUTH_PLUGIN_VERSION=2.1.6
# renovate: datasource=npm depName=typescript
ARG TYPESCRIPT_VERSION=6.0.3
# renovate: datasource=npm depName=npm
ARG NPM_VERSION=12.0.2
# renovate: datasource=npm depName=brace-expansion
-ARG NPM_BRACE_EXPANSION_VERSION=5.0.8
+ARG NPM_BRACE_EXPANSION_VERSION=5.0.9
# renovate: datasource=npm depName=tar
ARG NPM_TAR_VERSION=7.5.22
# renovate: datasource=npm depName=tsx
-ARG TSX_VERSION=4.23.1
+ARG TSX_VERSION=4.23.12
# renovate: datasource=npm depName=pnpm
-ARG PNPM_VERSION=11.18.0
+ARG PNPM_VERSION=11.21.0
# renovate: datasource=npm depName=vite
-ARG VITE_VERSION=8.1.5
+ARG VITE_VERSION=8.2.1
# renovate: datasource=npm depName=prettier
ARG PRETTIER_VERSION=3.9.6
# renovate: datasource=npm depName=prisma
@@ -141,13 +135,13 @@ ARG PRISMA_VERSION=7.9.1
# renovate: datasource=npm depName=lighthouse
ARG LIGHTHOUSE_VERSION=13.4.1
# renovate: datasource=npm depName=wrangler
-ARG WRANGLER_VERSION=4.115.0
+ARG WRANGLER_VERSION=4.121.0
# renovate: datasource=npm depName=eslint
-ARG ESLINT_VERSION=10.8.0
+ARG ESLINT_VERSION=10.8.1
# renovate: datasource=pypi depName=numpy
-ARG NUMPY_VERSION=2.5.1
+ARG NUMPY_VERSION=2.5.2
# renovate: datasource=pypi depName=pip
-ARG PIP_VERSION=26.2
+ARG PIP_VERSION=26.2.1
# renovate: datasource=pypi depName=msgpack
ARG PIP_VENDOR_MSGPACK_VERSION=1.2.1
ARG PIP_VENDOR_MSGPACK_SHA256=04c721c2c7448767e9e3f2520a475663d8ee0f09c31890f6d2bd70fd636a9647
@@ -156,7 +150,7 @@ ARG PIP_VENDOR_PKG_RESOURCES_VERSION=80.9.0
ARG PIP_VENDOR_PKG_RESOURCES_SHA256=f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c
# renovate: datasource=pypi depName=setuptools
ARG SETUPTOOLS_VERSION=83.0.0
-ARG RELEASE_APT_REFRESH=2026-08-02
+ARG RELEASE_APT_REFRESH=2026-08-11
ARG TARGETARCH
LABEL org.opencontainers.image.source=https://github.com/CoderLuii/HolyCode \
@@ -356,7 +350,7 @@ RUN npm install -g --ignore-scripts "npm@${NPM_VERSION}" && \
test "$(npm --version)" = "${NPM_VERSION}" && \
rm -rf /root/.npm
RUN test "$(npm view "brace-expansion@${NPM_BRACE_EXPANSION_VERSION}" dist.integrity)" = \
- "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==" && \
+ "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==" && \
BRACE_TARBALL=$(npm pack --silent --pack-destination /tmp \
"brace-expansion@${NPM_BRACE_EXPANSION_VERSION}") && \
BRACE_DIR=/usr/local/lib/node_modules/npm/node_modules/brace-expansion && \
@@ -436,7 +430,7 @@ RUN test "$(npm view "undici@${PAPERCLIP_UNDICI_VERSION}" dist.integrity)" = \
rm -rf /root/.npm
# Package the supported Claude Auth plugin for network-free startup.
RUN test "$(npm view "opencode-claude-auth@${CLAUDE_AUTH_PLUGIN_VERSION}" dist.integrity)" = \
- "sha512-rRZ3aZJEbgHsXzox1vkXY3sIrE3Z6c5ya/hEJJb2/XavuPufvTLI9dN2VHfvhFTl6eZPbs10hlSirfGnyLr46Q==" && \
+ "sha512-PVHMBoGms/e2cRDXi1gMx4N8UK4ZSBaviNO7UfheXm5mEW+PnFe7H1brXK5pDjvm1naGn9AntWUNIhOeJnyhvA==" && \
CLAUDE_AUTH_TARBALL=$(npm pack --silent --pack-destination /tmp \
"opencode-claude-auth@${CLAUDE_AUTH_PLUGIN_VERSION}") && \
CLAUDE_AUTH_DIR=/usr/local/share/holycode/plugins/opencode-claude-auth && \
diff --git a/README.md b/README.md
index 04a4196..906118d 100644
--- a/README.md
+++ b/README.md
@@ -464,7 +464,7 @@ Prefer Podman? HolyCode uses the same container image there too. The Podman guid
| Runtime | Version |
|---------|---------|
-| Node.js | 24.18.0 (LTS) |
+| Node.js | 24.19.0 (LTS) |
| npm | 12.0.2 |
| Python | 3.13 (Trixie) |
| pip | Bundled with Python 3.13 |
@@ -472,40 +472,40 @@ Prefer Podman? HolyCode uses the same container image there too. The Podman guid
-v1.1.4 release pins
+v1.1.6 release pins
| Component | Version |
|-----------|---------|
-| OpenCode | 1.18.9 |
+| OpenCode | 1.18.16 |
| Paperclip | 2026.722.0 with reviewed Undici 6.28.0 replacement |
| Hermes | Bundled service temporarily removed; existing `.hermes` data is preserved |
| CLIProxyAPI | Bundled sidecar removed; external endpoints remain supported |
| s6-overlay | 3.2.3.2 |
| eza | 0.23.5 |
-| fzf | 0.74.1 |
-| lazygit | 0.63.1 |
-| pnpm | 11.18.0 |
-| Vite | 8.1.5 |
-| ESLint | 10.8.0 |
+| fzf | 0.74.2 |
+| lazygit | 0.64.0 |
+| pnpm | 11.21.0 |
+| Vite | 8.2.1 |
+| ESLint | 10.8.1 |
| Prettier | 3.9.6 |
-| Wrangler | 4.115.0; legacy service environments are not supported |
+| Wrangler | 4.121.0; legacy service environments are not supported |
| Prisma | 7.9.1 |
| Lighthouse | 13.4.1 |
| Netlify CLI and `serve` | Removed |
| Hermes, Vercel, sharp-cli, concurrently, LHCI | Removed because their current dependency trees contain unresolved or fixable security findings |
| tqdm | 4.70.0 |
-| FastAPI / Uvicorn | 0.141.1 / 0.52.0 |
-| Claude stable | 2.1.220 |
-| tsx | 4.23.1 |
+| FastAPI / Uvicorn | 0.141.1 / 0.52.1 |
+| Claude stable | 2.1.228 |
+| tsx | 4.23.12 |
| TypeScript | 6.0.3, held until TypeScript 7 exposes the stable toolchain APIs this image needs |
-| NumPy | 2.5.1 on Python 3.13 |
+| NumPy | 2.5.2 on Python 3.13 |
| json-server | 0.17.4, held on the stable release instead of the 1.0 beta |
-| opencode-claude-auth default | 2.1.5, integrity-verified and installed from the image |
+| opencode-claude-auth default | 2.1.6, integrity-verified and installed from the image |
| oh-my-openagent | HolyCode-managed installation suspended; legacy active entry disabled once while settings, skills, and cache remain |
Release assets use digests, checksums, and action SHAs for hardening. npm lifecycle scripts are installed disabled, then their exact package version, integrity, architecture, and script body are validated before the approved scripts run. HolyCode also publishes per-platform SBOM and provenance attestations and runs per-platform vulnerability scans, but it does not claim universal freshness or that future rebuilds will retain the same scanner result.
-The dated adoption, hold, removal, exception, and scanner decisions are in the [v1.1.4 dependency audit](docs/dependency-audit-v1.1.4.md).
+The dated adoption, hold, removal, exception, and scanner decisions are in the [v1.1.6 dependency audit](docs/dependency-audit-v1.1.6.md).
diff --git a/config/npm-global-script-policy.json b/config/npm-global-script-policy.json
index ec30d07..53d4e4c 100644
--- a/config/npm-global-script-policy.json
+++ b/config/npm-global-script-policy.json
@@ -2,15 +2,15 @@
"npmVersion": "12.0.2",
"mode": "deny-by-default",
"allowScripts": {
- "@anthropic-ai/claude-code@2.1.220": {
+ "@anthropic-ai/claude-code@2.1.228": {
"architectures": ["amd64", "arm64"],
- "integrity": "sha512-ogBrvwkqF9f8okmnXKxmRNHuvtFxFEffe5pWdqOV3iQDxlUOKirFqnyWC7NGXXnDA4WkkbPH8pvSbwyCR2Auyw==",
+ "integrity": "sha512-S3Iy+c6ZuFjswQOekbVgXA+RxAuU8H2ae2nxFynqmvR5r3Gm9oyFV19XgiuatYRFKKjxP0K3i5vvvelPDgx12g==",
"scripts": { "postinstall": "node install.cjs" },
"reason": "Claude Code uses this script to install its pinned platform-native binary."
},
- "opencode-ai@1.18.9": {
+ "opencode-ai@1.18.16": {
"architectures": ["amd64", "arm64"],
- "integrity": "sha512-tqvu/hJ26c2dBj/V/uTHaQI3bMSpLck0hIgGXO2z7b11s5mYfnaq+K1CBjsg8Pp6EirfzwUYGzi85K/SvOgkKg==",
+ "integrity": "sha512-l4nUfoucuw8u5WYU9my9Yz7lYpBI649i/ppgL0BGTjp/HC3p2jN50i331YpcGbKfGTEv9VG6mxU1+QZyaR5hxA==",
"scripts": { "postinstall": "node ./postinstall.mjs" },
"reason": "OpenCode uses this script to hydrate its pinned platform CLI and refuses to start without it."
},
diff --git a/config/python-requirements.in b/config/python-requirements.in
index ffef8fc..f284cb1 100644
--- a/config/python-requirements.in
+++ b/config/python-requirements.in
@@ -1,7 +1,7 @@
-playwright==1.61.0
-packaging==26.2
+playwright==1.62.0
+packaging==26.3
wheel==0.47.0
-setuptools==83.0.0
+setuptools==84.0.0
requests==2.34.2
httpx==0.28.1
beautifulsoup4==4.15.0
@@ -10,7 +10,7 @@ Pillow==12.3.0
openpyxl==3.1.5
python-docx==1.2.0
pandas==3.0.5
-numpy==2.5.1
+numpy==2.5.2
matplotlib==3.11.1
seaborn==0.13.2
rich==15.0.0
@@ -20,6 +20,6 @@ apprise==1.12.0
jinja2==3.1.6
pyyaml==6.0.3
python-dotenv==1.2.2
-markdown==3.10.2
+markdown==3.10.3
fastapi==0.141.1
-uvicorn==0.52.0
+uvicorn==0.52.1
diff --git a/config/python-requirements.lock b/config/python-requirements.lock
index e876d2e..2e3029e 100644
--- a/config/python-requirements.lock
+++ b/config/python-requirements.lock
@@ -643,9 +643,9 @@ lxml==6.1.1 \
# via
# -r config/python-requirements.in
# python-docx
-markdown==3.10.2 \
- --hash=sha256:994d51325d25ad8aa7ce4ebaec003febcce822c3f8c911e3b17c52f7f589f950 \
- --hash=sha256:e91464b71ae3ee7afd3017d9f358ef0baf158fd9a298db92f1d4761133824c36
+markdown==3.10.3 \
+ --hash=sha256:3589362618f743188b4d955b874402bc814f4f83f544dc207719f4baa7d9c45f \
+ --hash=sha256:fa6c92a00a4a3c98b22728c64a935ae1928250ae65058a6ded814d2cc29a4cea
# via
# -r config/python-requirements.in
# apprise
@@ -798,51 +798,73 @@ mdurl==0.1.2 \
--hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \
--hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba
# via markdown-it-py
-numpy==2.5.1 \
- --hash=sha256:08d60c810432eb83360958dea0999ac4cfb94531ea8efcbf0b7f277c2068aeb2 \
- --hash=sha256:09e9bfd8d2cf479c7d174804fb3811c53a8e9f20a37444008606b57d6b7a826d \
- --hash=sha256:0bfebd8695f9863592fe744be833a258120b14a9f39da255e8aa8fade2c0ddd1 \
- --hash=sha256:17a25e09640602e10bc8de0e6fa2b3fd68eedd84ba6d7842dc8f32f9ab87bd0b \
- --hash=sha256:1c6759f538fb912fc46de0a6b1758ccf7b57bc7c7ebebc23974fdac3de8db0cd \
- --hash=sha256:224ca51130ef7da85bea2191625181cb4f337f9cb64b471f10c1a12aa8b60077 \
- --hash=sha256:24d0eb82c0541d3415a33425db64ae439dffccd7b4dbcb30e7c35120205c506a \
- --hash=sha256:2ae0ca40bcb22d6ba59c1dfd5446f49940b0f2d821fde133f10dda11f816b84e \
- --hash=sha256:2c889b56fe48b1018f764b0eec8df59ab654e9148aa91faa12596043500de277 \
- --hash=sha256:30b44a6b53a7ae63c54c089a8726e5563ed302716c5b7ccc85afade40b0e7ff6 \
- --hash=sha256:32985c896d897419ef8da6917872d80b78ad0ea26d85b23245c7366ffde76d75 \
- --hash=sha256:3935f3b419b244a02732676fa5317a9193cc596a4c0646db07e5b421229ac9f7 \
- --hash=sha256:4939237038ada79308dda3204ac6462df056b5672b2e25db1149cf873668b3e1 \
- --hash=sha256:4b4ff1608417eb7a59da7b967bbb798cacfe071d2caf526a24281cd562072ed9 \
- --hash=sha256:54ad769f17bc2d833b620851989f62054fb9ab93c969d9e1dc3c8e3d56beea21 \
- --hash=sha256:59fda5e192b570217ec2580c96f00e9a7e12ef6866a900eb089b62c1a32545ca \
- --hash=sha256:5a4c988b38d261deeeaad9954e3deb091ad905c94e8bb6708654ef1d97f286b0 \
- --hash=sha256:5a6db61f9aaa57e369905c67d852045d3c4f7126405b29d09b19dec118e9c9cb \
- --hash=sha256:6165343f81b56ef8f514f396989e529b61d9dc709b99421b07e9f3e698e2287d \
- --hash=sha256:61ac47e772e6b8ea489e1d2f441a34c5c3ac17327e7ce294cbdf535795ad4e75 \
- --hash=sha256:6c3fe51bc6a16453d452997053454f309e8e0ed7b42d6b361ce4ac8c32913d74 \
- --hash=sha256:6eab239876581b2b3c5a242281b6007bbdbcd1c7085d7709bb57c5929b11e6bf \
- --hash=sha256:78798bd5b9ad744056af8efa90e3b9ddaa53272a0848a483084a1cc0a13b2dc0 \
- --hash=sha256:7c786fe9a5bbe360022e584c5a34cf6b54265c71bd7ec8ac3d8fec38968071f8 \
- --hash=sha256:83ce9c80d5b521b0d77ddcbe5447c218d247929b6cc056ca5351342accfff0af \
- --hash=sha256:9726558e8db4a5bf7929a70ae50f63abda4daf0efe810e3bfbab95976f75fc1a \
- --hash=sha256:99d5095fa265a0c4152e7bb12759e14381ef5496152f1ce58f44bdf55c44beb4 \
- --hash=sha256:a33276be12fa045805f477f22482088b66bb758ffbe89a9d21457de863a32e22 \
- --hash=sha256:a48a113e6afea91f5608793bafa7ef2ad481fefbda87ec5069f483de61cb9fa3 \
- --hash=sha256:ab451b59c5643c570974c43aef780703ef1d3b4965d2be07afd530615a9358d1 \
- --hash=sha256:ab84dc6b074fa881cae55bea94cc4f68e285181ba7f32497bf7dee6b1496165b \
- --hash=sha256:ab87a91b3cc3382b8956095bd8f95e00cf679bb81554339be1a2ba404a1473c1 \
- --hash=sha256:c12afb53450fa976d4c681c50a7423729a4c51c0465ed9f32b8a9cabbc472373 \
- --hash=sha256:caf3e317d33d60c37986b452613f4ab51246d0691350c03d0cb4a898627f4a95 \
- --hash=sha256:dc932a65ded7ce9013d120845a2514dcccb1a67bfc8deb8d37633762951904a6 \
- --hash=sha256:e68d8dd1e7eba712948f2053a29ec86917bc70ba1358df869d9f06649ef9cf09 \
- --hash=sha256:e824c2acf8862052246be5a44c15da1777940c60d010dd2aab897824d9c430f9 \
- --hash=sha256:e8c11c405efc5ff6816d5983c96cdfa215bab3428961243af3ff59b228490438 \
- --hash=sha256:efd736408cc97c79b9e6917338dfc8f06013b2274f992e96b1d9a81a71e2a2c2 \
- --hash=sha256:f089d7b00756190aacf1f5d34bdf38c3c430ac82b4f868f8cede73380460fce7 \
- --hash=sha256:f2479a47f8d5932d1718168a681ad6e536a9df484c83cfcf9de365e164537ace \
- --hash=sha256:f7119ebff1a9829e9f431a4f9d28e703023bb6b9fe7c8f724467dbfc27c94ab3 \
- --hash=sha256:f7d60026c0bdb1380e83bfa7a0419c4577ee4b9a08880afcb6dadeb74c649fa2 \
- --hash=sha256:f7feb014281029e628ba2d5a007407443b06e418b6fe451d1e2adcbc8eba0107
+numpy==2.5.2 \
+ --hash=sha256:0090ccdd57ec2703e9b49d0bf554767370581c1dd0a6b2bb2b2d9def317d042a \
+ --hash=sha256:078f9b027b478c9379b9677babbf0f8b8f1ecfada27636d7b9a93990c638739f \
+ --hash=sha256:07d4e89f3a9ab0a9ba24264ccdb642b3dd951b2281e8883a5481a4aa79cc31a7 \
+ --hash=sha256:0a4035ae1129ff8777f08bfbd44f1e5d8e9c049ce0c2dd78fc0d92c13e7251c0 \
+ --hash=sha256:0aadf13b60048d501e05fa699efaf7734e2494f3498a4c2a5521d822640324f3 \
+ --hash=sha256:14e373cfc6387177e8409dac3c7159be8eb05cd77096cd7c950268b86f62831c \
+ --hash=sha256:1ab3d4a901f844ea836c3e80bf463c6a27d7f3c14e8e292fcf28d348b25b9bce \
+ --hash=sha256:24b9dc2e3d84aa58523798805194e23e736f3f6ce2d1a5b92583ae734e6dbda8 \
+ --hash=sha256:27650bb0e7140fa3d37b9923b4803645e0b125d190f326eecfd3f4dad8e8ade1 \
+ --hash=sha256:28ac63476ec7651484215ee7fa15a1f78b57c14621f01e392afe17b9a1390ce4 \
+ --hash=sha256:29b86ff8a6cc556b47ec6b64b194815cc80e6bf5eedcc6cddfd65318cb0b4eee \
+ --hash=sha256:29d81e97f668489cba8ebfd796b9bdd453525d35dd9e162e2daec94bf3fc7740 \
+ --hash=sha256:2cc779226e476d1e1f08c74068c419e60f41a9e0e069c92f6671d31d5c985e98 \
+ --hash=sha256:2ffa7bacab3e2ee1b19ed31766bb60bb380b68c23f051e199c5cc598afd68710 \
+ --hash=sha256:318b9a4c845dbea06708a29c84ee429cc3065048db34cdb799047643492050ee \
+ --hash=sha256:34c319e2963be042673fb46570501b2f06c41924e17e3563d58646b4380dfb68 \
+ --hash=sha256:3a2f061cebd9e3d23bdcfaaded5e2293a4c6a5b60fa42df85d410a725ce621bf \
+ --hash=sha256:3cdec01fa790a186d430433fdd4d4ffb70eed6f0eeb4bf05c8dbe2dce0a9bcb8 \
+ --hash=sha256:3e4c367352d3747784248a227fbec218e193b56f7e6692e3b64fc805478ecfdf \
+ --hash=sha256:40f4d451aed46a8046a1aae41c4e55fb3612273df9c502480135e1501576a34b \
+ --hash=sha256:44ef9675d908e65f9953063837c3277730f3f4437615a4cdab67b366cabaf884 \
+ --hash=sha256:4bbd96c833ecc8cc069ce518078fc8c60cb9cbfb0fea5b7a803ad65035596d03 \
+ --hash=sha256:4ec954036759bcee3aa484f8603bd9c14f3e776293b85578b8734c2d72777c69 \
+ --hash=sha256:4f9744f9fbdcea0bc552e8f19e1f141f811a3f9bc2be2cc6e86d982cab23e3f4 \
+ --hash=sha256:50a68f4bacd8a2b33d8da3d2269d0d78500f86ea582e4786dc10f5ef2c2c6842 \
+ --hash=sha256:50e500dc868e9313530ce12ba470fe50ff3afe3d62993ed6eff652dacd555b65 \
+ --hash=sha256:52c808f96484f5571a5cc863775ce50247c17dfb3b0361f8ed6b4b0456f80080 \
+ --hash=sha256:5f8e00be2ec6f45f4e8a41a527f68d44a7d96fee92a650e4d8b1326f77f61e6e \
+ --hash=sha256:60e902ac295855348a5ca2ea4c89108989a9f5fddfad3dfc0a8f36b10358567e \
+ --hash=sha256:65f188481f1669e26f62b701e8205d19e460fa4a9b52a1414ba382330e4a3414 \
+ --hash=sha256:6950c4b7dd562453090548ba7f5da7e59f57f85663f15d5dcc60e249192f7e59 \
+ --hash=sha256:6a9bb119fb8dd21ba30b3f0e555b7e2b081bd9883af21ec9c1c633d161cda3a8 \
+ --hash=sha256:6b588cc8f902d6bff201c19fd00c43ab8545671e3554d014e12e14139e5e8617 \
+ --hash=sha256:6df895598c0edcb41030126c89e0f353b07d93238116143b7405e937359736c4 \
+ --hash=sha256:6e8172ddfcf5cf74b811d372b570b83c60bd2de87a6fbfbebdadb4a9bd9c6cbb \
+ --hash=sha256:7354826bc6f8f69402e9b7fe28d15fcd34feebd74f856f111585c5b0c9fb0251 \
+ --hash=sha256:7587f53dfbd5edc0f7b87c6217b4c6d2d1f2ef9c3da70bc1315e7db5f8d7ec9d \
+ --hash=sha256:77843ca236b777e67f8d6b3660ea116e499612703a0ecd7093f316201eb9d8e2 \
+ --hash=sha256:7999d4ddb0c4025018373fd787510d46e04c769467af22869707b3c1cfd459ab \
+ --hash=sha256:85aaccb24182c25df891ad0ec333585967e115269d5f1b17f2c9ae005bc96657 \
+ --hash=sha256:8e4cb9a754c8a0c62eaa88273a5fba3391f4a610d1dee893c0755da31c083f15 \
+ --hash=sha256:8ee9c4eeb8454b3660a8b53493563c3e121c2fc94fbd72b848ef814ed7b676a9 \
+ --hash=sha256:9a0731745a72a184490a582fb4af2533512bd071ace67785b5fdffc0ae58dce8 \
+ --hash=sha256:9e9413326d726c2545bfa65d2c0876871e8d8386e77f992c1d426e180bbd4323 \
+ --hash=sha256:a610dc7e3c52edd39c2bc2375ff9c3fd59cb3ad00e4472d36f83bc1457145788 \
+ --hash=sha256:a839318485284a6fb31be4f8f2c91c8f2cb22f4543c4a8903f12b0671ffe07cc \
+ --hash=sha256:afb3f0632d6b2e3ba04dbce8d1e48d321b369138b73830b5ca371a0e8d479d56 \
+ --hash=sha256:b879fb674276e331513fb136b78dbc6bd3c848309e0d841cfd63be3896c4cfc1 \
+ --hash=sha256:b9727f472d2f3888053b8a75ab0cb94745a9de224bb5846dbadc0092101bc71d \
+ --hash=sha256:ba0a474801b8dc67b66bf465548abc90e82b44d2611b5770f33008dcabffe8ec \
+ --hash=sha256:bd68ece1553d2023c09a4226d9e41c586ad2d20594d1a456186c33513d2cb3f2 \
+ --hash=sha256:c081cbe16ba1ab53078e5ff29013621e33c509eedab055775d956427712c236e \
+ --hash=sha256:c1f017dc0875c9209d219f97feceb7d54c2661bb243deb4114478e1295808af7 \
+ --hash=sha256:cebc2d6dbb605a7703d59751dea4bd6b0ab127a5a4338a6f432df1936fef8b26 \
+ --hash=sha256:cf7de32f486e4ac9e2d93b810f9e9ac72a728dd46a32a0bb403222f27f653514 \
+ --hash=sha256:d482d171c406ae88c5b19cad3b6a1c4c5209f886ab74bc44c2c865c23f52d860 \
+ --hash=sha256:d6a48072864e3324e194a8fbb3c657bcc5b5c869dbc64c9537b1d5c862572c0a \
+ --hash=sha256:d787cf769c3baeb5f6235e778edb52c08dfa923789b5958f28e6450f96107cb1 \
+ --hash=sha256:dc649493697006bc90614a5f0bbc8cb3cb1866715c474e473694968d7e6b99ab \
+ --hash=sha256:ddf47472af2e4280d79bac82304f5e80150211f1b9e614b760061d5fdfbb6eba \
+ --hash=sha256:e5651f3f87add730ee6608d915009e19c911fba0cb000c7e3ea994b7d768eb12 \
+ --hash=sha256:e79aba74ffaf5f78a050d777c184cddf8fdffabab38acf5f3ef1fecbc17895d6 \
+ --hash=sha256:eaa088384c46f519dacb93b7ec483a6d6b19a4a2085ae4f25ab9b1c43d387d1e \
+ --hash=sha256:eaca7ff36f0f52e2111ec71f169d8fd3e889e7ddc0d2592e0d703fd8d3ce8fac \
+ --hash=sha256:f06571a052127dc1b4e8b83029b4d1b20daa2b64a31cdd181fc6bc774e9000eb \
+ --hash=sha256:fd0d703772bba096843785bd38371e31bb4a0c1151497ad5739d182114a73f7f
# via
# -r config/python-requirements.in
# contourpy
@@ -857,9 +879,9 @@ openpyxl==3.1.5 \
--hash=sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2 \
--hash=sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050
# via -r config/python-requirements.in
-packaging==26.2 \
- --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \
- --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661
+packaging==26.3 \
+ --hash=sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79 \
+ --hash=sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c
# via
# -r config/python-requirements.in
# matplotlib
@@ -1001,15 +1023,15 @@ pillow==12.3.0 \
# via
# -r config/python-requirements.in
# matplotlib
-playwright==1.61.0 \
- --hash=sha256:009588c2a7e499bc5a8b425b61fa65490968bbda9cd69e0cf2cff10f8304659a \
- --hash=sha256:35c6cc4589a5d00964a59d7b3e59641e0aac0c02f15479a7af77d20f6bc79597 \
- --hash=sha256:372d55a6f1248fa1dd47599686980cb8fb5bbe6fcda59eab793eb657c11d8a9b \
- --hash=sha256:54f3b39f6eab832e33458c1dd7da0b5682aedab3b09ae731b5c59fa12fd2024e \
- --hash=sha256:93454322ade8c11d5d6c211bfd91bdfb9ffb4810e3e026371bcbc4bec1b7ee4c \
- --hash=sha256:9f7de4536088d12037c13a52b7ea34b59270b78926bb56935070597ffac6b1af \
- --hash=sha256:e9fcbffcf557a8620fdedd92491eb59a32d18e23d6f3b4f6214b952be324fe51 \
- --hash=sha256:ff138c3a604f69911e9d42fd036e55c2a171e5616edf04c1e7f60a2a285540b0
+playwright==1.62.0 \
+ --hash=sha256:5108bd5b3e87169ddf269feee097da5893af7f8aea4634dfc840518d64c1f1da \
+ --hash=sha256:92c0d98ed04eb35af557b709875edba415b1f548bdb22ddb5bb3e1e6c835c2f1 \
+ --hash=sha256:ba33bae6a13b3d9d354c751cb618af357d20fe1d57767cbcce52079bbef17ad3 \
+ --hash=sha256:d8da938f3748841a8754f2e1f0216902c1c8f8ae3720de8b32ccf8e6913a7c4f \
+ --hash=sha256:db2d76613a57ad844362ce42f7d0c2fa26b19a4f7a46d4f76b891c631e6e5aff \
+ --hash=sha256:db755ab27db21a04186f1fe8169888e42356086e439b1059b923ef417f0b6034 \
+ --hash=sha256:e5614fa89355d7081457680324bb219f79f69c423c5cb6fa250e30b0d8aebf1c \
+ --hash=sha256:ea8d3055aa9d5a9f1832ac82517bd8b42c78fac7ebcbebb0107116735c8cb6a1
# via -r config/python-requirements.in
pydantic==2.13.4 \
--hash=sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba \
@@ -1304,9 +1326,9 @@ urllib3==2.7.0 \
--hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \
--hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897
# via requests
-uvicorn==0.52.0 \
- --hash=sha256:3d887809810b89ed33501bcf0a9aba469b06ecd608158efce04bd6b48d8c9b08 \
- --hash=sha256:ca8876ad6c1983f394157c168b39d52f6dd56dabf5602fa0982751cffc2293ae
+uvicorn==0.52.1 \
+ --hash=sha256:112ec661814189acbccd3f7b86460147cc065fc92c0821afa78918780e4354dd \
+ --hash=sha256:e4403f9d93188cf9d1088e9f40e3acd12630e2df8675316704379a7fc20fff6a
# via -r config/python-requirements.in
wheel==0.47.0 \
--hash=sha256:212281cab4dff978f6cedd499cd893e1f620791ca6ff7107cf270781e587eced \
@@ -1314,7 +1336,7 @@ wheel==0.47.0 \
# via -r config/python-requirements.in
# The following packages are considered to be unsafe in a requirements file:
-setuptools==83.0.0 \
- --hash=sha256:025bccbbf0fa05b6192bc64ae1e7b16e001fd6d6d4d5de03c97b1c1ade523bef \
- --hash=sha256:29b23c360f22f414dc7336bb39178cc7bcbf6021ed2733cde173f09dba19abb3
+setuptools==84.0.0 \
+ --hash=sha256:51a52592b3b99e102b609654876bd65f19f999935166d1352678931132b0c670 \
+ --hash=sha256:f4695c21257f0d9b537ec2692c941d02ee143b7cc1276941349a546573b2ef73
# via -r config/python-requirements.in
diff --git a/config/python-seed-requirements.in b/config/python-seed-requirements.in
index 5193464..f73c7f9 100644
--- a/config/python-seed-requirements.in
+++ b/config/python-seed-requirements.in
@@ -1,4 +1,4 @@
-pip==26.2
-setuptools==83.0.0
-packaging==26.2
+pip==26.2.1
+setuptools==84.0.0
+packaging==26.3
wheel==0.47.0
diff --git a/config/python-seed-requirements.lock b/config/python-seed-requirements.lock
index fe44cb5..3f0b696 100644
--- a/config/python-seed-requirements.lock
+++ b/config/python-seed-requirements.lock
@@ -1,12 +1,12 @@
#
-# This file is autogenerated by pip-compile with Python 3.13
+# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --allow-unsafe --generate-hashes --output-file=config/python-seed-requirements.lock --strip-extras config/python-seed-requirements.in
#
-packaging==26.2 \
- --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \
- --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661
+packaging==26.3 \
+ --hash=sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79 \
+ --hash=sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c
# via
# -r config/python-seed-requirements.in
# wheel
@@ -16,11 +16,11 @@ wheel==0.47.0 \
# via -r config/python-seed-requirements.in
# The following packages are considered to be unsafe in a requirements file:
-pip==26.2 \
- --hash=sha256:2d8542afcc84cdd8e846c2b36b2861fad1da376dd98f8e7113e9108a3c331690 \
- --hash=sha256:931c303696af6fa3417112103b1cad26890e5a07eccb5b99783700e33f2b8aad
+pip==26.2.1 \
+ --hash=sha256:71138adf1f4ca900cdb7d289c21b7494329f2332b6d85f0e1c42108c0384ed3e \
+ --hash=sha256:f6ad667e89a1fe78046c8f13232b247200f5258d7828f3f7883d660878e0813f
# via -r config/python-seed-requirements.in
-setuptools==83.0.0 \
- --hash=sha256:025bccbbf0fa05b6192bc64ae1e7b16e001fd6d6d4d5de03c97b1c1ade523bef \
- --hash=sha256:29b23c360f22f414dc7336bb39178cc7bcbf6021ed2733cde173f09dba19abb3
+setuptools==84.0.0 \
+ --hash=sha256:51a52592b3b99e102b609654876bd65f19f999935166d1352678931132b0c670 \
+ --hash=sha256:f4695c21257f0d9b537ec2692c941d02ee143b7cc1276941349a546573b2ef73
# via -r config/python-seed-requirements.in
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index a239467..997a3ad 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -4,6 +4,19 @@ All notable changes to HolyCode will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
+## [1.1.6] - 08/11/2026
+
+### Changed
+
+- Refresh Node.js to 24.19.0, GitHub CLI to 2.97.0, fzf to 0.74.2, lazygit to 0.64.0, OpenCode to 1.18.16, Claude Code to 2.1.228, and Claude Auth to 2.1.6
+- Refresh pnpm to 11.21.0, tsx to 4.23.12, Vite to 8.2.1, Wrangler to 4.121.0, ESLint to 10.8.1, and the protected Renovate validator to 44.24.2
+- Refresh the hash-locked Python set with Playwright 1.62.0, NumPy 2.5.2, Packaging 26.3, setuptools 84.0.0, Markdown 3.10.3, Uvicorn 0.52.1, and pip 26.2.1
+
+### Security
+
+- Run pull-request image builds and smoke tests natively on both AMD64 and ARM64
+- Refresh Docker Scout to 1.24.0 and Trivy to 0.73.0 while keeping fixable critical and high findings fail-closed
+
## [1.1.5] - 08/02/2026
### Changed
diff --git a/docs/dependency-audit-v1.1.6.md b/docs/dependency-audit-v1.1.6.md
new file mode 100644
index 0000000..65fb4c8
--- /dev/null
+++ b/docs/dependency-audit-v1.1.6.md
@@ -0,0 +1,30 @@
+# HolyCode v1.1.6 Dependency Audit
+
+This release starts from Git commit `038e4ac1d2c47a48237245877618d28299e256d6` and predecessor image `coderluii/holycode:1.1.5@sha256:804ec668b97466dba9a26ded8af258fabc2d778047b7c8aebdaab7bccd9a3ae8`.
+
+## Accepted updates
+
+| Component | Version | Release control |
+|---|---:|---|
+| Node.js | 24.19.0 | Official image pinned by digest |
+| GitHub CLI | 2.97.0 | Exact upstream tag and commit |
+| fzf | 0.74.2 | Exact upstream tag and commit |
+| lazygit | 0.64.0 | Exact upstream tag and commit |
+| OpenCode | 1.18.16 | npm integrity and lifecycle-script policy |
+| Claude Code | 2.1.228 | npm integrity and lifecycle-script policy |
+| Claude Auth | 2.1.6 | Integrity-verified offline payload |
+| pnpm / tsx / Vite | 11.21.0 / 4.23.12 / 8.2.1 | Exact npm pins |
+| Wrangler / ESLint | 4.121.0 / 10.8.1 | Exact npm pins |
+| Playwright / NumPy | 1.62.0 / 2.5.2 | Hash-locked Python requirements |
+| Packaging / setuptools / pip | 26.3 / 84.0.0 / 26.2.1 | Hash-locked runtime and offline seed |
+| Docker Scout / Trivy | 1.24.0 / 0.73.0 | Exact release checksums and workflow pins |
+
+Paperclip remains at `2026.722.0` with its reviewed Undici `6.28.0` replacement. pip keeps vendored msgpack `1.2.1` and pkg_resources from setuptools `80.9.0`.
+
+## Deferred update
+
+TypeScript 7.0.2 is deferred. HolyCode retains TypeScript 6.0.3 because the 7.x programmatic toolchain compatibility gate is not established for every bundled consumer. This hold does not block the independently validated updates above.
+
+## Architecture and scanner gates
+
+Pull requests build and smoke-test native `linux/amd64` and `linux/arm64` images. The tagged-release workflow regenerates per-platform SBOMs and runs current Docker Scout and Trivy data against the exact candidate digest. Scanner databases can change after this audit, so the remote fail-closed result remains authoritative.
diff --git a/docs/dockerhub-description.md b/docs/dockerhub-description.md
index 6682f3f..9900450 100644
--- a/docs/dockerhub-description.md
+++ b/docs/dockerhub-description.md
@@ -4,7 +4,7 @@
OpenCode AI coding agent with built-in web UI, Claude subscription support, 50+ dev tools, a sandboxed headless browser, optional Paperclip, and external CLIProxyAPI endpoint support. Use your existing Claude Max/Pro plan. No separate API key needed.
-v1.1.5 rebuilds the image with current Debian Trixie security packages, including Chromium 151.0.7922.71. It keeps the OpenCode, Claude Code, Paperclip, and compatible tool pins from v1.1.4.
+v1.1.6 refreshes Node.js 24.19.0, OpenCode 1.18.16, Claude Code 2.1.228, Claude Auth 2.1.6, and the compatible development toolchain. Native AMD64 and ARM64 pull-request jobs build and smoke-test the image.
[](https://hub.docker.com/r/coderluii/holycode)
[](https://github.com/CoderLuii/HolyCode)
diff --git a/patches/fzf-x-sys-0.44.0.patch b/patches/fzf-x-sys-0.44.0.patch
index 7e32558..77bd9b0 100644
--- a/patches/fzf-x-sys-0.44.0.patch
+++ b/patches/fzf-x-sys-0.44.0.patch
@@ -4,7 +4,7 @@ index 0b6e308..a62e3c3 100644
+++ b/go.mod
@@ -6,7 +6,7 @@ require (
github.com/junegunn/go-shellwords v0.0.0-20250127100254-2aa3b3277741
- github.com/mattn/go-isatty v0.0.22
+ github.com/mattn/go-isatty v0.0.24
github.com/rivo/uniseg v0.4.7
- golang.org/x/sys v0.35.0
+ golang.org/x/sys v0.44.0
diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh
index ce98667..35350ab 100644
--- a/scripts/entrypoint.sh
+++ b/scripts/entrypoint.sh
@@ -11,7 +11,7 @@ OC_USER="opencode"
OC_HOME="/home/opencode"
WORKSPACE_DIR="/workspace"
CLAUDE_AUTH_PLUGIN_NAME="opencode-claude-auth"
-CLAUDE_AUTH_PLUGIN_VERSION="2.1.5"
+CLAUDE_AUTH_PLUGIN_VERSION="2.1.6"
CLAUDE_AUTH_PLUGIN_SOURCE="/usr/local/share/holycode/plugins/opencode-claude-auth"
sync_shipped_skills() {
diff --git a/scripts/smoke_image.sh b/scripts/smoke_image.sh
index a59a403..a2cb6f5 100755
--- a/scripts/smoke_image.sh
+++ b/scripts/smoke_image.sh
@@ -130,7 +130,7 @@ PY
python3 -m venv /tmp/holycode-python-seed
/tmp/holycode-python-seed/bin/python -m pip install --no-index \
--find-links /usr/local/share/holycode/python-seed \
- pip==26.2 setuptools==83.0.0 packaging==26.2 wheel==0.47.0
+ pip==26.2.1 setuptools==84.0.0 packaging==26.3 wheel==0.47.0
/tmp/holycode-python-seed/bin/python - < list[str]:
for required_text in (
"runner: ubuntu-24.04",
"runner: ubuntu-24.04-arm",
- "SCOUT_VERSION: 1.23.1",
- "scout_sha256: 0f778f9d833f28bc6cccff95e33039849c0afcecafa38d9f46fe74bfd0915714",
- "scout_sha256: 88eecb7273f19bd18300d70e6f85b2e7d784e9e4f3cbb4a2b400db6b8355a52a",
+ "SCOUT_VERSION: 1.24.0",
+ "scout_sha256: f4e2814bd61040365153d5b964b144cb2dc6ee536a68b5bac4cadf00fc0ec34b",
+ "scout_sha256: 8b21594c72d4d9403a82a49e9dbdfc04c27c6a21933906f1eefbb0beabe22d58",
"docker/scout-cli/releases/download/v${SCOUT_VERSION}",
'docker-scout cves "sbom://$SCOUT_SBOM"',
- "version: v0.72.0",
- "PREVIOUS_IMAGE: coderluii/holycode:1.1.4@sha256:56756701a8b7468e1929b956950edb06ba8e0f0c87c5796aa57bde1389f82a91",
- "PREVIOUS_VERSION: v1.1.4",
- "RELEASE_VERSION: v1.1.5",
+ "version: v0.73.0",
+ "PREVIOUS_IMAGE: coderluii/holycode:1.1.5@sha256:804ec668b97466dba9a26ded8af258fabc2d778047b7c8aebdaab7bccd9a3ae8",
+ "PREVIOUS_VERSION: v1.1.5",
+ "RELEASE_VERSION: v1.1.6",
"python -m unittest discover -s tests",
"python scripts/validate_workflow_pins.py",
"python scripts/validate_chromium_seccomp.py",
- "bash scripts/validate_renovate_extraction.sh 44.2.3",
+ "bash scripts/validate_renovate_extraction.sh 44.24.2",
"scripts/validate_scanner_findings.py",
"bash scripts/test_plugin_modes.sh",
'ref: ${{ github.sha }}',
@@ -113,7 +113,17 @@ def collect_errors() -> list[str]:
pr_validation = WORKFLOWS / "pr-validation.yml"
pr_text = pr_validation.read_text(encoding="utf-8")
- if "bash scripts/validate_renovate_extraction.sh 44.2.3" not in pr_text:
+ for required_text in (
+ "runner: ubuntu-24.04",
+ "runner: ubuntu-24.04-arm",
+ "platform: linux/amd64",
+ "platform: linux/arm64",
+ "bash scripts/smoke_image.sh",
+ "bash scripts/test_plugin_modes.sh",
+ ):
+ if required_text not in pr_text:
+ errors.append(f"pr-validation.yml must contain {required_text!r}")
+ if "bash scripts/validate_renovate_extraction.sh 44.24.2" not in pr_text:
errors.append("pr-validation.yml must validate Renovate extraction with the audited pin")
return errors
diff --git a/tests/test_release_contract.py b/tests/test_release_contract.py
index 13d06b4..aba1d0c 100644
--- a/tests/test_release_contract.py
+++ b/tests/test_release_contract.py
@@ -51,21 +51,27 @@ def test_executable_scripts_use_lf_shebangs(self):
def test_release_dependency_pins(self):
expected = (
"ARG S6_OVERLAY_VERSION=3.2.3.2",
- "ARG FZF_VERSION=0.74.1",
- "ARG OPENCODE_VERSION=1.18.9",
- "ARG CLAUDE_CODE_VERSION=2.1.220",
+ "ARG GITHUB_CLI_VERSION=2.97.0",
+ "ARG FZF_VERSION=0.74.2",
+ "ARG LAZYGIT_VERSION=0.64.0",
+ "ARG OPENCODE_VERSION=1.18.16",
+ "ARG CLAUDE_CODE_VERSION=2.1.228",
"ARG PAPERCLIP_VERSION=2026.722.0",
+ "ARG PAPERCLIP_UNDICI_VERSION=6.28.0",
+ "ARG CLAUDE_AUTH_PLUGIN_VERSION=2.1.6",
"ARG NPM_VERSION=12.0.2",
- "ARG NPM_BRACE_EXPANSION_VERSION=5.0.8",
+ "ARG NPM_BRACE_EXPANSION_VERSION=5.0.9",
"ARG NPM_TAR_VERSION=7.5.22",
"ARG PIP_VENDOR_MSGPACK_VERSION=1.2.1",
"ARG PIP_VENDOR_PKG_RESOURCES_VERSION=80.9.0",
- "ARG PNPM_VERSION=11.18.0",
- "ARG VITE_VERSION=8.1.5",
+ "ARG TSX_VERSION=4.23.12",
+ "ARG PNPM_VERSION=11.21.0",
+ "ARG VITE_VERSION=8.2.1",
"ARG PRETTIER_VERSION=3.9.6",
"ARG PRISMA_VERSION=7.9.1",
"ARG LIGHTHOUSE_VERSION=13.4.1",
- "ARG WRANGLER_VERSION=4.115.0",
+ "ARG WRANGLER_VERSION=4.121.0",
+ "ARG ESLINT_VERSION=10.8.1",
"requests==2.34.2",
"pillow==12.3.0",
"postgresql-client-17 redis-tools sqlite3",
@@ -73,8 +79,12 @@ def test_release_dependency_pins(self):
"pandas==3.0.5",
"tqdm==4.70.0",
"fastapi==0.141.1",
- "uvicorn==0.52.0",
- "packaging==26.2",
+ "playwright==1.62.0",
+ "uvicorn==0.52.1",
+ "packaging==26.3",
+ "setuptools==84.0.0",
+ "numpy==2.5.2",
+ "markdown==3.10.3",
"wheel==0.47.0",
"rich==15.0.0",
)
@@ -131,25 +141,31 @@ def test_each_root_npm_layer_removes_its_cache(self):
def test_github_cli_is_rebuilt_with_fixed_go_toolchain(self):
self.assertIn(
"FROM --platform=$BUILDPLATFORM golang:1.26.5-trixie@sha256:"
- "4ee9ffa999b4583ce281939cdff828763083610292f252279a0cee77473bd9a7 "
+ "98988b42f3293b627bf07c884ff17181a59501769cd8c06c7ba901e0ce2c9853 "
"AS github-cli-builder",
self.dockerfile,
)
- self.assertIn("ARG GITHUB_CLI_VERSION=2.96.0", self.dockerfile)
+ self.assertIn("ARG GITHUB_CLI_VERSION=2.97.0", self.dockerfile)
self.assertIn(
- "ARG GITHUB_CLI_REF=b300f2ec7ec9dc9addc39b2ad88c54097ded7ca0",
+ "ARG GITHUB_CLI_REF=55dbb4dc6b7edb10b48e3d7fc5bccd32318d1b55",
self.dockerfile,
)
self.assertIn('test "$(git rev-parse HEAD)" = "${GITHUB_CLI_REF}"', self.dockerfile)
self.assertIn('go version -m /out/gh | grep -F "go1.26.5"', self.dockerfile)
self.assertIn(
"go version -m /out/gh | grep -E "
- "'github.com/klauspost/compress[[:space:]]+v1\\.18\\.7'",
+ "'github.com/klauspost/compress[[:space:]]+v1\\.19\\.1'",
self.dockerfile,
)
self.assertIn(
"go version -m /out/gh | grep -E "
- "'golang.org/x/text[[:space:]]+v0\\.39\\.0'",
+ "'golang.org/x/text[[:space:]]+v0\\.40\\.0'",
+ self.dockerfile,
+ )
+ self.assertNotIn("github-cli-modules.patch", self.dockerfile)
+ self.assertIn(
+ "FROM node:24.19.0-trixie-slim@sha256:"
+ "0711b541c1c33a8a530ac4f0d391baa9a15b3d804695b1b24a47daa5fb60e74d",
self.dockerfile,
)
self.assertIn("COPY --from=github-cli-builder /out/gh /usr/local/bin/gh", self.dockerfile)
@@ -161,11 +177,11 @@ def test_github_cli_is_rebuilt_with_fixed_go_toolchain(self):
def test_fzf_and_lazygit_are_rebuilt_from_exact_release_sources(self):
self.assertIn(
- "ARG FZF_REF=eae8d9d27eaeffc777699c01bf8f8b8c071908c1",
+ "ARG FZF_REF=3337be9d450cd349e99273a2d3985ceaf5f3753f",
self.dockerfile,
)
self.assertIn(
- "ARG LAZYGIT_REF=aafe61082e7ed383d318fd40e48f85645e6afc7b",
+ "ARG LAZYGIT_REF=aee0e40ec1235476e9328678f0f3e2462576b9ae",
self.dockerfile,
)
self.assertIn(
@@ -175,9 +191,10 @@ def test_fzf_and_lazygit_are_rebuilt_from_exact_release_sources(self):
)
self.assertIn(
"go version -m /out/lazygit | grep -E "
- "'golang.org/x/text[[:space:]]+v0\\.39\\.0'",
+ "'golang.org/x/text[[:space:]]+v0\\.40\\.0'",
self.dockerfile,
)
+ self.assertNotIn("lazygit-x-text-0.39.0.patch", self.dockerfile)
self.assertIn(
'LAZYGIT_MODULE_FILES_SHA256="$(sha256sum go.mod go.sum)"',
self.dockerfile,
@@ -242,7 +259,7 @@ def test_scanner_remediations_are_pinned(self):
"--require-hashes -r /usr/local/share/holycode/python-seed-requirements.lock",
self.dockerfile,
)
- for package in ("pip==26.2", "setuptools==83.0.0", "packaging==26.2", "wheel==0.47.0"):
+ for package in ("pip==26.2.1", "setuptools==84.0.0", "packaging==26.3", "wheel==0.47.0"):
with self.subTest(package=package):
self.assertIn(package, self.python_seed_lock)
self.assertIn("undici@${PAPERCLIP_UNDICI_VERSION}", self.dockerfile)
@@ -261,16 +278,16 @@ def test_scanner_remediations_are_pinned(self):
self.assertIn("cursor_cloud_api_key_missing", self.smoke)
def test_claude_auth_is_installed_from_verified_offline_payload(self):
- self.assertIn("ARG CLAUDE_AUTH_PLUGIN_VERSION=2.1.5", self.dockerfile)
+ self.assertIn("ARG CLAUDE_AUTH_PLUGIN_VERSION=2.1.6", self.dockerfile)
self.assertIn(
- "sha512-rRZ3aZJEbgHsXzox1vkXY3sIrE3Z6c5ya/hEJJb2/XavuPufvTLI9dN2VHfvhFTl"
- "6eZPbs10hlSirfGnyLr46Q==",
+ "sha512-PVHMBoGms/e2cRDXi1gMx4N8UK4ZSBaviNO7UfheXm5mEW+PnFe7H1brXK5pDjvm1na"
+ "Gn9AntWUNIhOeJnyhvA==",
self.dockerfile,
)
self.assertIn('dist.integrity)" =', self.dockerfile)
self.assertIn("npm pack --silent --pack-destination /tmp", self.dockerfile)
self.assertIn("/usr/local/share/holycode/plugins/opencode-claude-auth", self.dockerfile)
- self.assertIn('CLAUDE_AUTH_PLUGIN_VERSION="2.1.5"', self.entrypoint)
+ self.assertIn('CLAUDE_AUTH_PLUGIN_VERSION="2.1.6"', self.entrypoint)
self.assertIn("install_offline_claude_auth", self.entrypoint)
self.assertNotIn('opencode plugin "$plugin_spec" -g -f', self.entrypoint)
self.assertIn("claude auth status --json", self.smoke)
@@ -318,11 +335,11 @@ def test_protected_validation_uses_native_architecture_runners(self):
self.assertIn("chromium-sandbox", self.dockerfile)
self.assertIn("test -u /usr/lib/chromium/chrome-sandbox", self.dockerfile)
- def test_release_workflow_uses_v1_1_4_predecessor(self):
- self.assertIn("RELEASE_VERSION: v1.1.5", self.protected)
- self.assertIn("PREVIOUS_VERSION: v1.1.4", self.protected)
+ def test_release_workflow_uses_v1_1_5_predecessor(self):
+ self.assertIn("RELEASE_VERSION: v1.1.6", self.protected)
+ self.assertIn("PREVIOUS_VERSION: v1.1.5", self.protected)
self.assertIn(
- "coderluii/holycode:1.1.4@sha256:56756701a8b7468e1929b956950edb06ba8e0f0c87c5796aa57bde1389f82a91",
+ "coderluii/holycode:1.1.5@sha256:804ec668b97466dba9a26ded8af258fabc2d778047b7c8aebdaab7bccd9a3ae8",
self.protected,
)
self.assertIn("needs: protected-validation", self.publish)
@@ -390,11 +407,11 @@ def test_workflow_dependency_and_security_pins(self):
self.assertIn(checkout, self.protected)
self.assertIn(checkout, self.pr_validation)
self.assertIn(
- "bash scripts/validate_renovate_extraction.sh 44.2.3",
+ "bash scripts/validate_renovate_extraction.sh 44.24.2",
self.pr_validation,
)
self.assertIn(
- "bash scripts/validate_renovate_extraction.sh 44.2.3",
+ "bash scripts/validate_renovate_extraction.sh 44.24.2",
self.protected,
)
setup_node = (
@@ -402,8 +419,8 @@ def test_workflow_dependency_and_security_pins(self):
)
self.assertIn(setup_node, self.pr_validation)
self.assertIn(setup_node, self.protected)
- self.assertIn("node-version: 24.18.0", self.pr_validation)
- self.assertIn("node-version: 24.18.0", self.protected)
+ self.assertIn("node-version: 24.19.0", self.pr_validation)
+ self.assertIn("node-version: 24.19.0", self.protected)
self.assertIn(
"docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0",
self.publish,
@@ -419,6 +436,14 @@ def test_workflow_dependency_and_security_pins(self):
self.assertIn("format: json", self.protected)
self.assertIn("trivy-fixable.json", self.protected)
+ def test_pr_validation_covers_both_native_architectures(self):
+ self.assertIn("runner: ubuntu-24.04", self.pr_validation)
+ self.assertIn("runner: ubuntu-24.04-arm", self.pr_validation)
+ self.assertIn("platform: linux/amd64", self.pr_validation)
+ self.assertIn("platform: linux/arm64", self.pr_validation)
+ self.assertIn("bash scripts/smoke_image.sh", self.pr_validation)
+ self.assertIn("bash scripts/test_plugin_modes.sh", self.pr_validation)
+
def test_renovate_regenerates_the_hash_locked_python_requirements(self):
self.assertIn("pip-compile", self.renovate["enabledManagers"])
self.assertNotIn("pip_requirements", self.renovate["enabledManagers"])
@@ -436,8 +461,8 @@ def test_chromium_seccomp_profile_is_forced_to_lf(self):
def test_lifecycle_policy_matches_release(self):
policy = json.loads((ROOT / "config" / "npm-global-script-policy.json").read_text(encoding="utf-8"))
self.assertEqual(policy["npmVersion"], "12.0.2")
- self.assertIn("@anthropic-ai/claude-code@2.1.220", policy["allowScripts"])
- self.assertIn("opencode-ai@1.18.9", policy["allowScripts"])
+ self.assertIn("@anthropic-ai/claude-code@2.1.228", policy["allowScripts"])
+ self.assertIn("opencode-ai@1.18.16", policy["allowScripts"])
self.assertIn("prisma@7.9.1", policy["blockedScripts"])
self.assertIn("@prisma/engines@7.9.1", policy["blockedScripts"])
self.assertNotIn("netlify-cli@26.2.0", policy["blockedScripts"])
diff --git a/tests/test_validate_version.py b/tests/test_validate_version.py
index 4f9d7ed..dd7fb12 100644
--- a/tests/test_validate_version.py
+++ b/tests/test_validate_version.py
@@ -17,6 +17,7 @@ def test_accepts_v1_1_0_with_legacy_flag(self):
def test_accepts_standard_rollovers(self):
cases = [
("v1.1.4", "v1.1.5"),
+ ("v1.1.5", "v1.1.6"),
("v1.0.9", "v1.1.0"),
("v1.1.9", "v1.2.0"),
("v1.9.9", "v2.0.0"),