diff --git a/base-images/frameworks/next.js/v16/Dockerfile b/base-images/frameworks/next.js/v16/Dockerfile
new file mode 100644
index 00000000..f800858b
--- /dev/null
+++ b/base-images/frameworks/next.js/v16/Dockerfile
@@ -0,0 +1,20 @@
+# These ARGs can be overridden at build time to customize the image
+ARG REPO=labring-actions/devbox-base-images
+ARG REGISTRY=ghcr.io
+ARG L10N=en_US
+ARG L10N_NORMALIZED=en-us
+
+# These ARGs are not recommended to be overridden at build time.
+# Instead, update the Dockerfile directly for consistent builds,
+# and release new versions as needed.
+ARG NODE_IMAGE_VERSION=v0.0.1-alpha.1-${L10N_NORMALIZED}
+
+FROM ${REGISTRY}/${REPO}/node.js-20:${NODE_IMAGE_VERSION}
+ARG L10N
+LABEL org.opencontainers.image.authors="The Devbox Authors"
+ENV L10N=${L10N}
+# Add build script and execute it
+COPY build.sh /build.sh
+RUN chmod +x /build.sh && \
+ /build.sh && \
+ rm -f /build.sh
diff --git a/base-images/frameworks/next.js/v16/build.sh b/base-images/frameworks/next.js/v16/build.sh
new file mode 100644
index 00000000..e97c7658
--- /dev/null
+++ b/base-images/frameworks/next.js/v16/build.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+NEXT_VERSION=${NEXT_VERSION:-16.2.6}
+
+# Install the Next.js project scaffolding CLI globally for convenience.
+npm install -g "create-next-app@${NEXT_VERSION}"
diff --git a/runtime-images/frameworks/next.js/v16/Dockerfile b/runtime-images/frameworks/next.js/v16/Dockerfile
new file mode 100644
index 00000000..a5b99d65
--- /dev/null
+++ b/runtime-images/frameworks/next.js/v16/Dockerfile
@@ -0,0 +1,24 @@
+# These ARGs can be overridden at build time to customize the image
+ARG REPO=labring-actions/devbox-base-images
+ARG REGISTRY=ghcr.io
+ARG L10N=en_US
+ARG L10N_NORMALIZED=en-us
+
+# These ARGs are not recommended to be overridden at build time.
+# Instead, update the Dockerfile directly for consistent builds,
+# and release new versions as needed.
+ARG RUNTIME_IMAGE_VERSION=v0.0.1-alpha.1-${L10N_NORMALIZED}
+
+FROM ${REGISTRY}/${REPO}/next.js-v16:${RUNTIME_IMAGE_VERSION}
+ARG L10N
+LABEL org.opencontainers.image.authors="The Devbox Authors"
+ENV L10N=${L10N}
+ENV PROJECT_TEMPLATE_DIR=/project-template
+COPY ./project-template ${PROJECT_TEMPLATE_DIR}
+COPY ./build.sh /build.sh
+RUN chmod +x /build.sh && \
+ /build.sh && \
+ rm -f /build.sh && \
+ rm -rf ${PROJECT_TEMPLATE_DIR}
+# Set the working directory to the default devbox user's project directory
+WORKDIR /home/${DEFAULT_DEVBOX_USER}/project
diff --git a/runtime-images/frameworks/next.js/v16/build.sh b/runtime-images/frameworks/next.js/v16/build.sh
new file mode 100644
index 00000000..c729217f
--- /dev/null
+++ b/runtime-images/frameworks/next.js/v16/build.sh
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+L10N=${L10N:-en_US}
+DEFAULT_DEVBOX_USER=${DEFAULT_DEVBOX_USER:-devbox}
+PROJECT_TEMPLATE_DIR=${PROJECT_TEMPLATE_DIR:-/project-template}
+
+if ! id -u "$DEFAULT_DEVBOX_USER" &>/dev/null; then
+ echo "User $DEFAULT_DEVBOX_USER does not exist"
+ exit 1
+fi
+
+TARGET_DIR="/home/$DEFAULT_DEVBOX_USER/project"
+mkdir -p "$TARGET_DIR"
+
+if [ -f "$PROJECT_TEMPLATE_DIR/README.$L10N.md" ]; then
+ echo "README $PROJECT_TEMPLATE_DIR/README.$L10N.md exists. Copying to $TARGET_DIR/README.md"
+ cp "$PROJECT_TEMPLATE_DIR/README.$L10N.md" "$TARGET_DIR/README.md"
+else
+ echo "README $PROJECT_TEMPLATE_DIR/README.$L10N.md does not exist. Skipping copy."
+fi
+
+DOCS_DIR=${DOCS_DIR:-/usr/share/devbox/docs}
+if [ -f "$DOCS_DIR/README.s6-user-guide.$L10N.md" ]; then
+ cp "$DOCS_DIR/README.s6-user-guide.$L10N.md" "$TARGET_DIR/README.s6-user-guide.md"
+elif [ -f "$DOCS_DIR/README.s6-user-guide.en_US.md" ]; then
+ cp "$DOCS_DIR/README.s6-user-guide.en_US.md" "$TARGET_DIR/README.s6-user-guide.md"
+fi
+
+# Copy project template contents (except localized readmes handled above).
+# Using `/.` keeps hidden files/dirs if present.
+cp -R "${PROJECT_TEMPLATE_DIR}/." "$TARGET_DIR/"
+
+# If we wrote a localized README.md, remove the localized variants to keep the
+# project dir clean (optional; safe if they don't exist).
+rm -f "$TARGET_DIR/README.en_US.md" "$TARGET_DIR/README.zh_CN.md" || true
+
+# Ensure entrypoint is executable if present.
+if [ -f "$TARGET_DIR/entrypoint.sh" ]; then
+ chmod +x "$TARGET_DIR/entrypoint.sh"
+fi
+
+# Install dependencies and build the Next.js project.
+cd "$TARGET_DIR"
+npm install
+npm run build
+
+# Set ownership to default devbox user
+chown -R "$DEFAULT_DEVBOX_USER:$DEFAULT_DEVBOX_USER" "$TARGET_DIR"
diff --git a/runtime-images/frameworks/next.js/v16/project-template/.gitignore b/runtime-images/frameworks/next.js/v16/project-template/.gitignore
new file mode 100644
index 00000000..6be16910
--- /dev/null
+++ b/runtime-images/frameworks/next.js/v16/project-template/.gitignore
@@ -0,0 +1,25 @@
+# dependencies
+/node_modules
+
+# Next.js
+/.next
+/out
+
+# production
+/build
+
+# logs
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# environment
+.env*.local
+
+# editor
+.idea
+.vscode
+
+# system
+.DS_Store
diff --git a/runtime-images/frameworks/next.js/v16/project-template/README.en_US.md b/runtime-images/frameworks/next.js/v16/project-template/README.en_US.md
new file mode 100644
index 00000000..ee288c5a
--- /dev/null
+++ b/runtime-images/frameworks/next.js/v16/project-template/README.en_US.md
@@ -0,0 +1,58 @@
+# Next.js v16 Runtime Template
+
+This template provides a React web application runtime powered by **Next.js 16** using the App Router and TypeScript.
+
+## Runtime Summary
+
+- Framework/runtime version: `Next.js 16`
+- Base runtime image: `next.js-v16`
+- Entrypoint script: `entrypoint.sh`
+- Default service port: `3000`
+
+## Template Files
+
+- `app/layout.tsx`: root layout and page metadata
+- `app/page.tsx`: default homepage rendered by the App Router
+- `app/globals.css`: shared application styles
+- `next.config.ts`: Next.js configuration
+- `tsconfig.json`: TypeScript compiler configuration
+- `entrypoint.sh`: starts Next.js in dev or production mode
+
+## Run in DevBox
+
+Run commands from `/home/devbox/project`.
+
+### Development mode
+
+```bash
+bash entrypoint.sh
+```
+
+Behavior:
+- Runs `npm install` to ensure dependencies are up to date.
+- Starts `next dev` on `0.0.0.0:3000` for hot reloading.
+
+### Production mode
+
+```bash
+bash entrypoint.sh production
+```
+
+Behavior:
+- Installs dependencies needed for the production build.
+- Builds the project with `npm run build`.
+- Prunes development dependencies after the build.
+- Starts `next start` on `0.0.0.0:3000`.
+
+## Verify Service
+
+```bash
+curl http://127.0.0.1:3000
+```
+
+## Customization
+
+- Edit `app/page.tsx` to change the default page.
+- Add routes by creating folders under `app/`.
+- Update `app/globals.css` for shared styling.
+- Modify `next.config.ts` for framework options such as image domains or build output.
diff --git a/runtime-images/frameworks/next.js/v16/project-template/README.zh_CN.md b/runtime-images/frameworks/next.js/v16/project-template/README.zh_CN.md
new file mode 100644
index 00000000..609f9097
--- /dev/null
+++ b/runtime-images/frameworks/next.js/v16/project-template/README.zh_CN.md
@@ -0,0 +1,58 @@
+# Next.js v16 运行时模板
+
+该模板提供一个基于 **Next.js 16** 的 React Web 应用运行时,使用 App Router 和 TypeScript。
+
+## 运行时概览
+
+- 框架/运行时版本:`Next.js 16`
+- 基础运行时镜像:`next.js-v16`
+- 启动脚本:`entrypoint.sh`
+- 默认服务端口:`3000`
+
+## 模板文件
+
+- `app/layout.tsx`:根布局和页面元数据
+- `app/page.tsx`:由 App Router 渲染的默认首页
+- `app/globals.css`:应用共享样式
+- `next.config.ts`:Next.js 配置
+- `tsconfig.json`:TypeScript 编译配置
+- `entrypoint.sh`:以开发或生产模式启动 Next.js
+
+## 在 DevBox 中运行
+
+以下命令在 `/home/devbox/project` 目录执行。
+
+### 开发模式
+
+```bash
+bash entrypoint.sh
+```
+
+行为说明:
+- 执行 `npm install` 确保依赖已安装。
+- 以 `next dev` 启动,监听 `0.0.0.0:3000` 并支持热重载。
+
+### 生产模式
+
+```bash
+bash entrypoint.sh production
+```
+
+行为说明:
+- 安装生产构建所需依赖。
+- 执行 `npm run build` 构建项目。
+- 构建完成后裁剪开发依赖。
+- 以 `next start` 启动,监听 `0.0.0.0:3000`。
+
+## 验证服务
+
+```bash
+curl http://127.0.0.1:3000
+```
+
+## 自定义建议
+
+- 修改 `app/page.tsx` 调整默认页面。
+- 在 `app/` 下创建目录以添加路由。
+- 修改 `app/globals.css` 调整全局样式。
+- 修改 `next.config.ts` 配置图片域名、构建输出等框架选项。
diff --git a/runtime-images/frameworks/next.js/v16/project-template/app/globals.css b/runtime-images/frameworks/next.js/v16/project-template/app/globals.css
new file mode 100644
index 00000000..9e7d14d0
--- /dev/null
+++ b/runtime-images/frameworks/next.js/v16/project-template/app/globals.css
@@ -0,0 +1,135 @@
+:root {
+ color-scheme: light;
+ --background: #f8fafc;
+ --foreground: #172033;
+ --muted: #5f6c7b;
+ --panel: #ffffff;
+ --border: #d9e2ec;
+ --accent: #0f766e;
+ --accent-strong: #115e59;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html,
+body {
+ margin: 0;
+ min-height: 100%;
+}
+
+body {
+ background: var(--background);
+ color: var(--foreground);
+ font-family: Arial, Helvetica, sans-serif;
+}
+
+a {
+ color: inherit;
+}
+
+.page {
+ min-height: 100vh;
+ display: grid;
+ place-items: center;
+ padding: 48px 20px;
+}
+
+.shell {
+ width: min(880px, 100%);
+ display: grid;
+ gap: 28px;
+}
+
+.intro {
+ display: grid;
+ gap: 18px;
+}
+
+.eyebrow {
+ margin: 0;
+ color: var(--accent-strong);
+ font-size: 0.85rem;
+ font-weight: 700;
+ letter-spacing: 0;
+ text-transform: uppercase;
+}
+
+h1 {
+ margin: 0;
+ max-width: 760px;
+ font-size: clamp(2.25rem, 7vw, 4.75rem);
+ line-height: 1;
+ letter-spacing: 0;
+}
+
+.summary {
+ margin: 0;
+ max-width: 660px;
+ color: var(--muted);
+ font-size: 1.08rem;
+ line-height: 1.7;
+}
+
+.actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 12px;
+}
+
+.button {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-height: 44px;
+ padding: 0 18px;
+ border: 1px solid var(--accent);
+ border-radius: 6px;
+ background: var(--accent);
+ color: #ffffff;
+ font-size: 0.95rem;
+ font-weight: 700;
+ text-decoration: none;
+}
+
+.button.secondary {
+ background: transparent;
+ color: var(--accent-strong);
+}
+
+.details {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 12px;
+}
+
+.detail {
+ min-height: 112px;
+ padding: 18px;
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ background: var(--panel);
+}
+
+.detail h2 {
+ margin: 0 0 10px;
+ font-size: 0.95rem;
+}
+
+.detail p {
+ margin: 0;
+ color: var(--muted);
+ font-size: 0.92rem;
+ line-height: 1.55;
+}
+
+@media (max-width: 720px) {
+ .page {
+ place-items: start;
+ }
+
+ .details {
+ grid-template-columns: 1fr;
+ }
+}
diff --git a/runtime-images/frameworks/next.js/v16/project-template/app/layout.tsx b/runtime-images/frameworks/next.js/v16/project-template/app/layout.tsx
new file mode 100644
index 00000000..0ebbea24
--- /dev/null
+++ b/runtime-images/frameworks/next.js/v16/project-template/app/layout.tsx
@@ -0,0 +1,19 @@
+import type { Metadata } from 'next';
+import './globals.css';
+
+export const metadata: Metadata = {
+ title: 'Next.js DevBox Template',
+ description: 'A Next.js runtime template for Sealos DevBox.',
+};
+
+export default function RootLayout({
+ children,
+}: Readonly<{
+ children: React.ReactNode;
+}>) {
+ return (
+
+
{children}
+
+ );
+}
diff --git a/runtime-images/frameworks/next.js/v16/project-template/app/page.tsx b/runtime-images/frameworks/next.js/v16/project-template/app/page.tsx
new file mode 100644
index 00000000..cac0e118
--- /dev/null
+++ b/runtime-images/frameworks/next.js/v16/project-template/app/page.tsx
@@ -0,0 +1,39 @@
+export default function Home() {
+ return (
+
+
+
+
DevBox runtime
+
Next.js is ready.
+
+ Build routes in the App Router, iterate with hot reload, and switch
+ to the production server when your app is ready to ship.
+
+
+
+
+
+
+ App Router
+ Create pages, layouts, and loading states under the app folder.
+
+
+ TypeScript
+ Template files are typed by default for confident iteration.
+
+
+ Port 3000
+ The entrypoint binds to all interfaces for DevBox access.
+
+
+
+
+ );
+}
diff --git a/runtime-images/frameworks/next.js/v16/project-template/entrypoint.sh b/runtime-images/frameworks/next.js/v16/project-template/entrypoint.sh
new file mode 100644
index 00000000..d395dc05
--- /dev/null
+++ b/runtime-images/frameworks/next.js/v16/project-template/entrypoint.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+set -euo pipefail
+
+if [ "$(id -u)" -eq 0 ] && [ "${DEVBOX_ENTRYPOINT_AS_DEVBOX:-1}" = "1" ] && id devbox >/dev/null 2>&1; then
+ export DEVBOX_ENTRYPOINT_AS_DEVBOX=0
+ SCRIPT_PATH=$(readlink -f "$0")
+ exec runuser -u devbox -- bash "$SCRIPT_PATH" "$@"
+fi
+
+app_env=${1:-development}
+export HOME=${HOME:-/home/devbox}
+export HOST=${HOST:-0.0.0.0}
+export PORT=${PORT:-3000}
+export npm_config_cache=${npm_config_cache:-$HOME/.npm}
+mkdir -p "$npm_config_cache"
+
+dev_commands() {
+ echo "Running Next.js development environment..."
+ npm install
+ npm run dev -- --hostname "$HOST" --port "$PORT"
+}
+
+prod_commands() {
+ echo "Running Next.js production environment..."
+ npm install
+ npm run build
+ npm prune --omit=dev
+ npm run start -- --hostname "$HOST" --port "$PORT"
+}
+
+if [ "$app_env" = "production" ] || [ "$app_env" = "prod" ] ; then
+ echo "Production environment detected"
+ prod_commands
+else
+ echo "Development environment detected"
+ dev_commands
+fi
diff --git a/runtime-images/frameworks/next.js/v16/project-template/next-env.d.ts b/runtime-images/frameworks/next.js/v16/project-template/next-env.d.ts
new file mode 100644
index 00000000..9edff1c7
--- /dev/null
+++ b/runtime-images/frameworks/next.js/v16/project-template/next-env.d.ts
@@ -0,0 +1,6 @@
+///
+///
+import "./.next/types/routes.d.ts";
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
diff --git a/runtime-images/frameworks/next.js/v16/project-template/next.config.ts b/runtime-images/frameworks/next.js/v16/project-template/next.config.ts
new file mode 100644
index 00000000..b22af960
--- /dev/null
+++ b/runtime-images/frameworks/next.js/v16/project-template/next.config.ts
@@ -0,0 +1,5 @@
+import type { NextConfig } from 'next';
+
+const nextConfig: NextConfig = {};
+
+export default nextConfig;
diff --git a/runtime-images/frameworks/next.js/v16/project-template/package-lock.json b/runtime-images/frameworks/next.js/v16/project-template/package-lock.json
new file mode 100644
index 00000000..03ad97a9
--- /dev/null
+++ b/runtime-images/frameworks/next.js/v16/project-template/package-lock.json
@@ -0,0 +1,1041 @@
+{
+ "name": "next-devbox-template",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "next-devbox-template",
+ "version": "1.0.0",
+ "license": "MIT",
+ "dependencies": {
+ "next": "16.2.6",
+ "react": "19.2.7",
+ "react-dom": "19.2.7"
+ },
+ "devDependencies": {
+ "@types/node": "24.12.4",
+ "@types/react": "19.2.16",
+ "@types/react-dom": "^19.2.3",
+ "typescript": "5.9.3"
+ },
+ "engines": {
+ "node": ">=20.9.0",
+ "npm": ">=10.0.0"
+ }
+ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
+ "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@img/colour": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",
+ "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@img/sharp-darwin-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz",
+ "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-arm64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-darwin-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz",
+ "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-x64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-libvips-darwin-arm64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz",
+ "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-darwin-x64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz",
+ "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-arm": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz",
+ "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==",
+ "cpu": [
+ "arm"
+ ],
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-arm64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz",
+ "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==",
+ "cpu": [
+ "arm64"
+ ],
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-ppc64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz",
+ "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-riscv64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz",
+ "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-s390x": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz",
+ "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-x64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz",
+ "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==",
+ "cpu": [
+ "x64"
+ ],
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz",
+ "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==",
+ "cpu": [
+ "arm64"
+ ],
+ "libc": [
+ "musl"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-x64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz",
+ "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==",
+ "cpu": [
+ "x64"
+ ],
+ "libc": [
+ "musl"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz",
+ "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==",
+ "cpu": [
+ "arm"
+ ],
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz",
+ "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==",
+ "cpu": [
+ "arm64"
+ ],
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-ppc64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz",
+ "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-ppc64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-riscv64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz",
+ "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-riscv64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-s390x": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz",
+ "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==",
+ "cpu": [
+ "s390x"
+ ],
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-s390x": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz",
+ "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==",
+ "cpu": [
+ "x64"
+ ],
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-x64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz",
+ "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==",
+ "cpu": [
+ "arm64"
+ ],
+ "libc": [
+ "musl"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-arm64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz",
+ "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==",
+ "cpu": [
+ "x64"
+ ],
+ "libc": [
+ "musl"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-x64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-wasm32": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz",
+ "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==",
+ "cpu": [
+ "wasm32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/runtime": "^1.7.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz",
+ "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-ia32": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz",
+ "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz",
+ "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@next/env": {
+ "version": "16.2.6",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.6.tgz",
+ "integrity": "sha512-gd8HoHN4ufj73WmR3JmVolrpJR47ILK6LouP5xElPglaVxir6e1a7VzvTvDWkOoPXT9rkkTzyCxBu4yeZfZwcw==",
+ "license": "MIT"
+ },
+ "node_modules/@next/swc-darwin-arm64": {
+ "version": "16.2.6",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.6.tgz",
+ "integrity": "sha512-ZJGkkcNfYgrrMkqOdZ7zoLa1TOy0qpcMfk/z4Mh/FKUz40gVO+HNQWqmLxf67Z5WB64DRp0dhEbyHfel+6sJUg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-darwin-x64": {
+ "version": "16.2.6",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.6.tgz",
+ "integrity": "sha512-v/YLBHIY132Ced3puBJ7YJKw1lqsCrgcNo2aRJlCEyQrrCeRJlvGlnmxhPxNQI3KE3N1DN5r9TPNPvka3nq5RQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-arm64-gnu": {
+ "version": "16.2.6",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.6.tgz",
+ "integrity": "sha512-RPOvqlYBbcQjkz9VQQDZ2T2bARIjXZV1KFlt+V2Mr6SW/e4I9fcKsaA0hdyf2FHoTlsV2xnBd5Y912rP/1Ce6w==",
+ "cpu": [
+ "arm64"
+ ],
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-arm64-musl": {
+ "version": "16.2.6",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.6.tgz",
+ "integrity": "sha512-URUTu1+dMkxJsPFgm+OeEvq9wf5sujw0EvgYy80TDGHTSLTnIHeqb0Eu8A3sC95IRgjejQL+kC4mw+4yPxiAXA==",
+ "cpu": [
+ "arm64"
+ ],
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-x64-gnu": {
+ "version": "16.2.6",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.6.tgz",
+ "integrity": "sha512-DOj182mPV8G3UkrayLoREM5YEYI+Dk5wv7Ox9xl1fFibAELEsFD0lDPfHIeILlutMMfdyhlzYPELG3peuKaurw==",
+ "cpu": [
+ "x64"
+ ],
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-x64-musl": {
+ "version": "16.2.6",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.6.tgz",
+ "integrity": "sha512-HKQ5SP/V/ub73UvF7n/zeJlxk2kLmtL7Wzrg4WfmkjmNos5onJ2tKu7yZOPdL18A6Svfn3max29ym+ry7NkK4g==",
+ "cpu": [
+ "x64"
+ ],
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-arm64-msvc": {
+ "version": "16.2.6",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.6.tgz",
+ "integrity": "sha512-LZXpTlPyS5v7HhSmnvsLGP3iIYgYOBnc8r8ArlT55sGHV89bR2HlDdBjWQ+PY6SJMmk8TuVGFuxalnP3k/0Dwg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-x64-msvc": {
+ "version": "16.2.6",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.6.tgz",
+ "integrity": "sha512-F0+4i0h9J6C4eE3EAPWsoCk7UW/dbzOjyzxY0qnDUOYFu6FFmdZ6l97/XdV3/Nz3VYyO7UWjyEJUXkGqcoXfMA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@swc/helpers": {
+ "version": "0.5.15",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
+ "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@types/node": {
+ "version": "24.12.4",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.4.tgz",
+ "integrity": "sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~7.16.0"
+ }
+ },
+ "node_modules/@types/react": {
+ "version": "19.2.16",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.16.tgz",
+ "integrity": "sha512-esJiCAnl0kfpNdE69f3So4WJUXy95dLZydX0KwK46riIHDzHM7O9Vtf9xCHW0PXIqvgqNrswl522kA/5yx+F4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "csstype": "^3.2.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "19.2.3",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
+ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^19.2.0"
+ }
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.10.33",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.33.tgz",
+ "integrity": "sha512-bA6+tcSLpz2tIEdDXZPpPTIuxBcC4+w6SieaYyfigIa4h8GlFxbA17v22Vx3JUtuZQj9SgOsnbK+aTBzyDyEuw==",
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.cjs"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001793",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001793.tgz",
+ "integrity": "sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/client-only": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
+ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
+ "license": "MIT"
+ },
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.12",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
+ "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/next": {
+ "version": "16.2.6",
+ "resolved": "https://registry.npmjs.org/next/-/next-16.2.6.tgz",
+ "integrity": "sha512-qOVgKJg1+At15NpeUP+eJgCHvTCgXsogweq87Ri/Ix7PkqQHg4sdaXmSFqKlgaIXE4kW0g25LE68W87UANlHtw==",
+ "license": "MIT",
+ "dependencies": {
+ "@next/env": "16.2.6",
+ "@swc/helpers": "0.5.15",
+ "baseline-browser-mapping": "^2.9.19",
+ "caniuse-lite": "^1.0.30001579",
+ "postcss": "8.4.31",
+ "styled-jsx": "5.1.6"
+ },
+ "bin": {
+ "next": "dist/bin/next"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "optionalDependencies": {
+ "@next/swc-darwin-arm64": "16.2.6",
+ "@next/swc-darwin-x64": "16.2.6",
+ "@next/swc-linux-arm64-gnu": "16.2.6",
+ "@next/swc-linux-arm64-musl": "16.2.6",
+ "@next/swc-linux-x64-gnu": "16.2.6",
+ "@next/swc-linux-x64-musl": "16.2.6",
+ "@next/swc-win32-arm64-msvc": "16.2.6",
+ "@next/swc-win32-x64-msvc": "16.2.6",
+ "sharp": "^0.34.5"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.1.0",
+ "@playwright/test": "^1.51.1",
+ "babel-plugin-react-compiler": "*",
+ "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
+ "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
+ "sass": "^1.3.0"
+ },
+ "peerDependenciesMeta": {
+ "@opentelemetry/api": {
+ "optional": true
+ },
+ "@playwright/test": {
+ "optional": true
+ },
+ "babel-plugin-react-compiler": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/postcss": {
+ "version": "8.5.15",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz",
+ "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.12",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/react": {
+ "version": "19.2.7",
+ "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz",
+ "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "19.2.7",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz",
+ "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==",
+ "license": "MIT",
+ "dependencies": {
+ "scheduler": "^0.27.0"
+ },
+ "peerDependencies": {
+ "react": "^19.2.7"
+ }
+ },
+ "node_modules/scheduler": {
+ "version": "0.27.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
+ "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "7.8.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz",
+ "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==",
+ "license": "ISC",
+ "optional": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/sharp": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz",
+ "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "@img/colour": "^1.0.0",
+ "detect-libc": "^2.1.2",
+ "semver": "^7.7.3"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-darwin-arm64": "0.34.5",
+ "@img/sharp-darwin-x64": "0.34.5",
+ "@img/sharp-libvips-darwin-arm64": "1.2.4",
+ "@img/sharp-libvips-darwin-x64": "1.2.4",
+ "@img/sharp-libvips-linux-arm": "1.2.4",
+ "@img/sharp-libvips-linux-arm64": "1.2.4",
+ "@img/sharp-libvips-linux-ppc64": "1.2.4",
+ "@img/sharp-libvips-linux-riscv64": "1.2.4",
+ "@img/sharp-libvips-linux-s390x": "1.2.4",
+ "@img/sharp-libvips-linux-x64": "1.2.4",
+ "@img/sharp-libvips-linuxmusl-arm64": "1.2.4",
+ "@img/sharp-libvips-linuxmusl-x64": "1.2.4",
+ "@img/sharp-linux-arm": "0.34.5",
+ "@img/sharp-linux-arm64": "0.34.5",
+ "@img/sharp-linux-ppc64": "0.34.5",
+ "@img/sharp-linux-riscv64": "0.34.5",
+ "@img/sharp-linux-s390x": "0.34.5",
+ "@img/sharp-linux-x64": "0.34.5",
+ "@img/sharp-linuxmusl-arm64": "0.34.5",
+ "@img/sharp-linuxmusl-x64": "0.34.5",
+ "@img/sharp-wasm32": "0.34.5",
+ "@img/sharp-win32-arm64": "0.34.5",
+ "@img/sharp-win32-ia32": "0.34.5",
+ "@img/sharp-win32-x64": "0.34.5"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/styled-jsx": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz",
+ "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==",
+ "license": "MIT",
+ "dependencies": {
+ "client-only": "0.0.1"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "peerDependencies": {
+ "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "@babel/core": {
+ "optional": true
+ },
+ "babel-plugin-macros": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
+ },
+ "node_modules/typescript": {
+ "version": "5.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "7.16.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
+ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
+ "dev": true,
+ "license": "MIT"
+ }
+ }
+}
diff --git a/runtime-images/frameworks/next.js/v16/project-template/package.json b/runtime-images/frameworks/next.js/v16/project-template/package.json
new file mode 100644
index 00000000..a52d8fe3
--- /dev/null
+++ b/runtime-images/frameworks/next.js/v16/project-template/package.json
@@ -0,0 +1,30 @@
+{
+ "name": "next-devbox-template",
+ "private": true,
+ "version": "1.0.0",
+ "description": "Next.js DevBox runtime template",
+ "license": "MIT",
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start"
+ },
+ "engines": {
+ "node": ">=20.9.0",
+ "npm": ">=10.0.0"
+ },
+ "dependencies": {
+ "next": "16.2.6",
+ "react": "19.2.7",
+ "react-dom": "19.2.7"
+ },
+ "devDependencies": {
+ "@types/node": "24.12.4",
+ "@types/react": "19.2.16",
+ "@types/react-dom": "^19.2.3",
+ "typescript": "5.9.3"
+ },
+ "overrides": {
+ "postcss": "8.5.15"
+ }
+}
diff --git a/runtime-images/frameworks/next.js/v16/project-template/tsconfig.json b/runtime-images/frameworks/next.js/v16/project-template/tsconfig.json
new file mode 100644
index 00000000..d73edcae
--- /dev/null
+++ b/runtime-images/frameworks/next.js/v16/project-template/tsconfig.json
@@ -0,0 +1,30 @@
+{
+ "compilerOptions": {
+ "target": "ES2017",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "react-jsx",
+ "incremental": true,
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ]
+ },
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx",
+ ".next/types/**/*.ts",
+ ".next/dev/types/**/*.ts"
+ ],
+ "exclude": ["node_modules"]
+}
diff --git a/tests/runtime-conformance/README.md b/tests/runtime-conformance/README.md
index dda9c426..d79fb6c1 100644
--- a/tests/runtime-conformance/README.md
+++ b/tests/runtime-conformance/README.md
@@ -53,6 +53,7 @@ Runtime-specific checks:
| `languages/python/3.12` | Python 3.12, pip, pip mirror for `zh_CN`, root/devbox entrypoint order |
| `languages/rust/1.81.0` | Rust/Cargo 1.81.0, Cargo mirror for `zh_CN`, Cargo template, prebuilt release binary, root/devbox entrypoint order |
| `frameworks/nest.js/v11` | Node 20, Nest CLI, npm mirror for `zh_CN`, build output, root/devbox entrypoint order |
+| `frameworks/next.js/v16` | Node 20, create-next-app, npm mirror for `zh_CN`, Next.js build output, root/devbox entrypoint order |
| `frameworks/nginx/1.22.1` | Nginx 1.22.1, config test, `/tmp/nginx-devbox` runtime paths, no distro default include pollution, root/devbox entrypoint order |
| `frameworks/openclaw/latest` | Node 22, OpenClaw, Clawhub, Bun, npm mirror for `zh_CN`, safe `.env.example`, root/devbox entrypoint order |
| `frameworks/sandbox/v1` | workspace ownership, codex-gateway, Codex CLI, Node/npm, Python/pip, kubectl, helm, bun, ripgrep, bubblewrap, npm/pip mirrors for `zh_CN` |
diff --git a/tests/runtime-conformance/run.sh b/tests/runtime-conformance/run.sh
index 276d52e2..8f00bc5c 100755
--- a/tests/runtime-conformance/run.sh
+++ b/tests/runtime-conformance/run.sh
@@ -196,7 +196,7 @@ check_no_root_owned_project_files() {
http_port_for_runtime() {
case "$RUNTIME_PATH" in
- frameworks/nest.js/v11)
+ frameworks/nest.js/v11 | frameworks/next.js/v16)
printf '3000'
;;
frameworks/openclaw/latest | frameworks/sandbox/*)
@@ -210,7 +210,7 @@ http_port_for_runtime() {
http_timeout_for_runtime() {
case "$RUNTIME_PATH" in
- frameworks/nest.js/v11 | languages/net/*)
+ frameworks/nest.js/v11 | frameworks/next.js/v16 | languages/net/*)
printf '120'
;;
languages/rust/*)
@@ -525,6 +525,18 @@ check_nest_runtime() {
assert_file "$PROJECT_DIR/dist/main.js"
}
+check_next_runtime() {
+ check_node_runtime 20
+ assert_command create-next-app
+ assert_file "$PROJECT_DIR/package.json"
+ assert_file "$PROJECT_DIR/package-lock.json"
+ assert_file "$PROJECT_DIR/next.config.ts"
+ assert_file "$PROJECT_DIR/tsconfig.json"
+ assert_file "$PROJECT_DIR/app/page.tsx"
+ assert_file "$PROJECT_DIR/app/layout.tsx"
+ assert_dir "$PROJECT_DIR/.next"
+}
+
check_openclaw_runtime() {
check_node_runtime 22
assert_command openclaw
@@ -642,6 +654,9 @@ check_runtime_specifics() {
frameworks/nest.js/v11)
check_nest_runtime
;;
+ frameworks/next.js/v16)
+ check_next_runtime
+ ;;
frameworks/nginx/1.22.1)
check_nginx_runtime
;;
diff --git a/tests/runtime-smoke/frameworks/next.js/v16/smoke.sh b/tests/runtime-smoke/frameworks/next.js/v16/smoke.sh
new file mode 100644
index 00000000..e61479f5
--- /dev/null
+++ b/tests/runtime-smoke/frameworks/next.js/v16/smoke.sh
@@ -0,0 +1,94 @@
+#!/bin/bash
+set -eu
+
+project_dir=/home/devbox/project
+
+if [ ! -d "$project_dir" ]; then
+ echo "Missing project dir: $project_dir" >&2
+ exit 1
+fi
+
+# load profile env (best effort)
+set +u
+[ -f /etc/profile ] && . /etc/profile || true
+if [ -d /etc/profile.d ]; then
+ for f in /etc/profile.d/*.sh; do
+ [ -r "$f" ] && . "$f" || true
+ done
+fi
+[ -f /home/devbox/.bashrc ] && . /home/devbox/.bashrc || true
+set -u
+
+if [ "${SMOKE_DEBUG:-}" = "1" ]; then
+ echo "SMOKE_DEBUG=1"
+ echo "user=$(id -un) uid=$(id -u) gid=$(id -g)"
+ echo "HOME=$HOME"
+ echo "SHELL=${SHELL:-}"
+ echo "PATH=$PATH"
+ for cmd in node npm yarn pnpm npx create-next-app; do
+ if command -v "$cmd" >/dev/null 2>&1; then
+ echo "cmd:$cmd=$(command -v "$cmd")"
+ else
+ echo "cmd:$cmd=missing"
+ fi
+ done
+fi
+
+cd "$project_dir"
+
+node -e 'process.exit(process.versions.node.split(".")[0]==="20"?0:1)'
+
+for file in package.json package-lock.json next.config.ts tsconfig.json app/page.tsx app/layout.tsx README.md; do
+ if [ ! -f "$project_dir/$file" ]; then
+ echo "Missing $file in $project_dir" >&2
+ exit 1
+ fi
+done
+
+if [ ! -d "$project_dir/.next" ]; then
+ echo "Missing prebuilt .next output in $project_dir" >&2
+ exit 1
+fi
+
+entrypoint="$project_dir/entrypoint.sh"
+if [ ! -x "$entrypoint" ]; then
+ echo "Missing executable entrypoint.sh in $project_dir" >&2
+ exit 1
+fi
+
+stop_entrypoint() {
+ pid="$1"
+ kill -TERM "-$pid" >/dev/null 2>&1 || kill -TERM "$pid" >/dev/null 2>&1 || true
+ sleep 1
+ kill -KILL "-$pid" >/dev/null 2>&1 || kill -KILL "$pid" >/dev/null 2>&1 || true
+ wait "$pid" >/dev/null 2>&1 || true
+}
+
+if ! command -v setsid >/dev/null 2>&1; then
+ echo "setsid not found" >&2
+ exit 1
+fi
+
+setsid bash -lc "cd '$project_dir' && bash '$entrypoint' production" >/tmp/entrypoint.log 2>&1 &
+pid=$!
+for _ in $(seq 1 60); do
+ if curl -fsS --max-time 2 http://127.0.0.1:3000/ >/tmp/next-smoke.html 2>/tmp/next-smoke.err; then
+ stop_entrypoint "$pid"
+ grep -q "Next.js is ready" /tmp/next-smoke.html
+ echo "ok"
+ exit 0
+ fi
+ if ! kill -0 "$pid" >/dev/null 2>&1; then
+ echo "entrypoint exited early" >&2
+ echo "---- entrypoint log ----" >&2
+ cat /tmp/entrypoint.log >&2 || true
+ exit 1
+ fi
+ sleep 2
+done
+
+echo "entrypoint did not serve HTTP on port 3000" >&2
+echo "---- entrypoint log ----" >&2
+cat /tmp/entrypoint.log >&2 || true
+stop_entrypoint "$pid"
+exit 1
diff --git a/tests/runtime-smoke/operating-systems/anolis/23.4/smoke.sh b/tests/runtime-smoke/operating-systems/anolis/23.4/smoke.sh
index 8bea20a5..7b84ae0f 100644
--- a/tests/runtime-smoke/operating-systems/anolis/23.4/smoke.sh
+++ b/tests/runtime-smoke/operating-systems/anolis/23.4/smoke.sh
@@ -69,6 +69,13 @@ if [ ! -x /usr/sbin/sshd ]; then
exit 1
fi
+for nologin_file in /run/nologin /etc/nologin; do
+ if [ -e "$nologin_file" ]; then
+ echo "$nologin_file blocks non-root SSH logins" >&2
+ exit 1
+ fi
+done
+
if ! /usr/sbin/sshd -T | grep -qx 'allowtcpforwarding yes'; then
echo "sshd AllowTcpForwarding is not enabled" >&2
exit 1
diff --git a/tests/runtime-smoke/operating-systems/kylin/v10-sp3/smoke.sh b/tests/runtime-smoke/operating-systems/kylin/v10-sp3/smoke.sh
index 3ba0dc1e..4c280db2 100644
--- a/tests/runtime-smoke/operating-systems/kylin/v10-sp3/smoke.sh
+++ b/tests/runtime-smoke/operating-systems/kylin/v10-sp3/smoke.sh
@@ -69,6 +69,13 @@ if [ ! -x /usr/sbin/sshd ]; then
exit 1
fi
+for nologin_file in /run/nologin /etc/nologin; do
+ if [ -e "$nologin_file" ]; then
+ echo "$nologin_file blocks non-root SSH logins" >&2
+ exit 1
+ fi
+done
+
if ! /usr/sbin/sshd -T | grep -qx 'allowtcpforwarding yes'; then
echo "sshd AllowTcpForwarding is not enabled" >&2
exit 1
diff --git a/tooling/scripts/svc/configure-sshd.sh b/tooling/scripts/svc/configure-sshd.sh
index 1acbc546..c7fbb087 100644
--- a/tooling/scripts/svc/configure-sshd.sh
+++ b/tooling/scripts/svc/configure-sshd.sh
@@ -43,6 +43,7 @@ exec 2>&1
mkdir -p /run/sshd
chmod 755 /run/sshd
+rm -f /run/nologin /etc/nologin
if ! ls /etc/ssh/ssh_host_*_key >/dev/null 2>&1; then
if ! command -v ssh-keygen >/dev/null 2>&1; then