diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index efa98c546..7b2781242 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,6 +1,7 @@
import java.util.Properties
import java.io.FileInputStream
import org.gradle.internal.os.OperatingSystem
+import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
id("com.android.application")
@@ -113,10 +114,6 @@ android {
targetCompatibility = JavaVersion.VERSION_17
}
- kotlinOptions {
- jvmTarget = "17"
- }
-
testOptions {
// JVM unit tests run against a stubbed android.jar whose methods throw
// "Method ... not mocked" by default. MarketplaceFetcher.fetchIndex() calls
@@ -129,6 +126,17 @@ android {
}
}
+// Kotlin JVM target. This used to be `android { kotlinOptions { jvmTarget = "17" } }`,
+// which Kotlin 2.4 removed from the Gradle plugin (deprecated since 2.0), so the
+// build script stopped compiling on the dependabot bump. `compilerOptions` is the
+// replacement DSL; it lives at the top level, not inside `android {}`. Keep this
+// in step with compileOptions.sourceCompatibility/targetCompatibility above.
+kotlin {
+ compilerOptions {
+ jvmTarget.set(JvmTarget.JVM_17)
+ }
+}
+
// Auto-bundle the React UI into Android assets before APK packaging.
//
// Why: app/src/main/assets/web/ is gitignored except for index.html. The actual
@@ -227,7 +235,7 @@ dependencies {
implementation("com.github.luben:zstd-jni:1.5.7-11")
// Markdown parsing for chat view
- implementation("org.commonmark:commonmark:0.29.0")
+ implementation("org.commonmark:commonmark:0.30.0")
// WebSocket server for React UI bridge
implementation("com.squareup.okhttp3:okhttp:4.12.0")
diff --git a/app/src/test/kotlin/com/youcoded/app/skills/LocalSkillProviderInstalledTest.kt b/app/src/test/kotlin/com/youcoded/app/skills/LocalSkillProviderInstalledTest.kt
index 68d4ee7b6..ef83d8ae2 100644
--- a/app/src/test/kotlin/com/youcoded/app/skills/LocalSkillProviderInstalledTest.kt
+++ b/app/src/test/kotlin/com/youcoded/app/skills/LocalSkillProviderInstalledTest.kt
@@ -10,6 +10,10 @@ import org.mockito.Mockito.mock
import org.mockito.Mockito.`when`
import java.io.ByteArrayInputStream
import java.io.File
+// Kotlin 2.4 made kotlin.io.createTempDir() a compile ERROR (it was deprecated
+// for creating world-readable temp dirs); this is the replacement the stdlib
+// points at, and what PluginInstallerUpgradeTest already uses.
+import kotlin.io.path.createTempDirectory
/**
* Tests LocalSkillProvider.getInstalled() backfill behavior — specifically the
@@ -30,7 +34,7 @@ class LocalSkillProviderInstalledTest {
@Before
fun setUp() {
- tmpHome = createTempDir(prefix = "youcoded-localprov-")
+ tmpHome = createTempDirectory(prefix = "youcoded-localprov-").toFile()
context = mock(Context::class.java)
val assets = mock(AssetManager::class.java)
`when`(context.assets).thenReturn(assets)
diff --git a/app/src/test/kotlin/com/youcoded/app/skills/SkillConfigStoreChipsTest.kt b/app/src/test/kotlin/com/youcoded/app/skills/SkillConfigStoreChipsTest.kt
index 00e6b6b8f..9ee5b5ca7 100644
--- a/app/src/test/kotlin/com/youcoded/app/skills/SkillConfigStoreChipsTest.kt
+++ b/app/src/test/kotlin/com/youcoded/app/skills/SkillConfigStoreChipsTest.kt
@@ -7,6 +7,10 @@ import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
import java.io.File
+// Kotlin 2.4 made kotlin.io.createTempDir() a compile ERROR (it was deprecated
+// for creating world-readable temp dirs); this is the replacement the stdlib
+// points at, and what PluginInstallerUpgradeTest already uses.
+import kotlin.io.path.createTempDirectory
/**
* Regression coverage for the Android-only "uninstalling a plugin wipes every
@@ -52,7 +56,7 @@ class SkillConfigStoreChipsTest {
private fun store() = SkillConfigStore(tmpHome).apply { load() }
@Before
- fun setUp() { tmpHome = createTempDir(prefix = "youcoded-chips-") }
+ fun setUp() { tmpHome = createTempDirectory(prefix = "youcoded-chips-").toFile() }
@After
fun tearDown() { tmpHome.deleteRecursively() }
diff --git a/app/src/test/kotlin/com/youcoded/app/skills/SkillScannerTest.kt b/app/src/test/kotlin/com/youcoded/app/skills/SkillScannerTest.kt
index 5364d5add..59c5da9a4 100644
--- a/app/src/test/kotlin/com/youcoded/app/skills/SkillScannerTest.kt
+++ b/app/src/test/kotlin/com/youcoded/app/skills/SkillScannerTest.kt
@@ -10,6 +10,10 @@ import org.mockito.Mockito.mock
import org.mockito.Mockito.`when`
import java.io.ByteArrayInputStream
import java.io.File
+// Kotlin 2.4 made kotlin.io.createTempDir() a compile ERROR (it was deprecated
+// for creating world-readable temp dirs); this is the replacement the stdlib
+// points at, and what PluginInstallerUpgradeTest already uses.
+import kotlin.io.path.createTempDirectory
/**
* Tests SkillScanner Pass 1 (top-level plugin scan) and Pass 2 (installed_plugins.json).
@@ -26,7 +30,7 @@ class SkillScannerTest {
@Before
fun setUp() {
- tmpHome = createTempDir(prefix = "youcoded-scanner-")
+ tmpHome = createTempDirectory(prefix = "youcoded-scanner-").toFile()
context = mock(Context::class.java)
val assets = mock(android.content.res.AssetManager::class.java)
`when`(context.assets).thenReturn(assets)
diff --git a/build.gradle.kts b/build.gradle.kts
index 955a84c29..2b55befef 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,5 +1,5 @@
plugins {
id("com.android.application") version "8.7.0" apply false
- id("org.jetbrains.kotlin.android") version "2.1.0" apply false
- id("org.jetbrains.kotlin.plugin.compose") version "2.1.0" apply false
+ id("org.jetbrains.kotlin.android") version "2.4.10" apply false
+ id("org.jetbrains.kotlin.plugin.compose") version "2.4.10" apply false
}
diff --git a/desktop/knip.jsonc b/desktop/knip.jsonc
index 61395d405..72b732f10 100644
--- a/desktop/knip.jsonc
+++ b/desktop/knip.jsonc
@@ -6,14 +6,14 @@
// JSONC (not .json) specifically so the ignore rationale below can live next
// to the ignores. Every entry here is a VERIFIED false positive, not a
// silenced real finding.
- "$schema": "https://unpkg.com/knip@5/schema.json",
+ "$schema": "https://unpkg.com/knip@6/schema.json",
+ // main.ts, renderer/index.tsx and vite.config.ts are NOT listed: knip 6's
+ // vite/electron plugins derive them from package.json + vite.config.ts and
+ // flag a hand-written copy as a redundant entry pattern.
"entry": [
- "src/main/main.ts",
"src/main/preload.ts",
"src/main/pty-worker.js",
- "src/renderer/index.tsx",
- "vite.config.ts",
"scripts/*.js",
"src/**/*.test.ts",
"src/**/*.test.tsx",
@@ -28,17 +28,36 @@
"test-engine/**/*.mjs"
],
- "project": ["src/**/*.{ts,tsx}"],
- // The old `src/renderer/dev/fixtures/**` ignore is gone: those fixtures moved
- // under dev/workbench/ and are DELIBERATELY left unignored. Workbench fixture
- // modules are ordinary imports, so knip catching an unused one is the point —
- // it is what flagged a models.ts that existed only "for symmetry".
- "ignore": ["dist/**"],
+ // .css is in `project` so knip follows CSS `@import "tailwindcss"` etc. —
+ // knip 6 hints that a compiled extension left out of `project` means those
+ // imports are silently not followed. Nothing is reported for CSS files today;
+ // it is what lets tailwindcss be seen as a real dependency (below).
+ "project": ["src/**/*.{ts,tsx,css}"],
+ // No `ignore` block: the old `dist/**` entry is redundant (knip 6 never scans
+ // build output that isn't under `project`, and hints to remove it), and the
+ // older `src/renderer/dev/fixtures/**` ignore is gone on purpose — workbench
+ // fixture modules are ordinary imports, so knip catching an unused one is the
+ // point; it is what flagged a models.ts that existed only "for symmetry".
+
+ // OS-level tools the main process shells out to. knip 6 started reading the
+ // command name out of child_process execFile/spawn calls and reports any
+ // that no dependency provides ("unlisted binary"). None of these is, or could
+ // be, an npm package — each is VERIFIED below — so they are listed here and
+ // the `binaries` category stays at its default (error), so a NEW unlisted
+ // binary still fails CI.
+ "ignoreBinaries": [
+ // Linux socket-stats tool, engine-supervisor.ts: which process holds the port.
+ "ss",
+ // Windows process lister, sync-service.ts: is this sync PID still alive.
+ "tasklist",
+ // The Drive/cloud sync transport, sync-service.ts — users install it themselves.
+ "rclone"
+ ],
"ignoreDependencies": [
- // Peer of @tailwindcss/postcss, wired through postcss.config.js rather
- // than imported. Removing it breaks the CSS build with no import to trace.
- "tailwindcss",
+ // tailwindcss is NOT listed any more: with .css in `project`, knip resolves
+ // the `@import "tailwindcss"` in the stylesheet itself and hints that the
+ // old ignore is redundant.
// Spawned as a subprocess by scripts/run-dev.js:52
// (`spawn(npx, ['wait-on', viteUrl])`), so no static import exists.
"wait-on",
@@ -50,11 +69,14 @@
// Gate on the categories that are CLEAN today, so CI ratchets (nothing new
// rots in) without demanding a big-bang cleanup first. The noisy-but-real
// categories report as warnings and are tracked in ROADMAP instead:
- // - types (262): dominated by src/shared/types.ts, a deliberate shared
- // type surface consumed structurally. Erroring here would be wrong.
- // - exports (10) / unlisted (4): real findings, but deleting an export or
- // re-pinning a transitive dep is a reviewed change, not a lint autofix.
+ // - types (172 under knip 6; 379 under knip 5): dominated by
+ // components/ui/index.ts and src/shared/types.ts, deliberate shared type
+ // surfaces consumed structurally. Erroring here would be wrong.
+ // - exports (77): real findings, but deleting an export or re-pinning a
+ // transitive dep is a reviewed change, not a lint autofix.
// Tighten these to "error" as each category is driven to zero.
+ // `classMembers` is not listed: knip 6 dropped that issue type (it relied on
+ // a TypeScript API that goes away in TS 6), and an unknown key only warns.
"rules": {
"files": "error",
"unresolved": "error",
@@ -63,7 +85,6 @@
"unlisted": "warn",
"exports": "warn",
"types": "warn",
- "enumMembers": "warn",
- "classMembers": "warn"
+ "enumMembers": "warn"
}
}
diff --git a/desktop/package-lock.json b/desktop/package-lock.json
index 09eb310a7..b515ec775 100644
--- a/desktop/package-lock.json
+++ b/desktop/package-lock.json
@@ -68,8 +68,8 @@
"electron-builder": "^26.15.3",
"eslint": "^9.39.5",
"eslint-plugin-react-hooks": "^6.1.1",
- "jsdom": "^29.1.1",
- "knip": "^5.88.1",
+ "jsdom": "^30.0.1",
+ "knip": "^6.32.2",
"postcss": "^8.5.26",
"tailwindcss": "^4.2.2",
"typescript": "^5.9.3",
@@ -213,56 +213,58 @@
}
},
"node_modules/@asamuzakjp/css-color": {
- "version": "5.1.11",
- "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.1.11.tgz",
- "integrity": "sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==",
+ "version": "6.0.7",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-6.0.7.tgz",
+ "integrity": "sha512-vC/bk1Lz7Tn/EfU9/apOTBk80/8dyGyWMowPoV1tJ52muDGsDqt2HPT2klrFUiY60MQmQv9q8yIht15JnBgDGw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@asamuzakjp/generational-cache": "^1.0.1",
- "@csstools/css-calc": "^3.2.0",
- "@csstools/css-color-parser": "^4.1.0",
+ "@csstools/css-calc": "^3.3.0",
+ "@csstools/css-color-parser": "^4.1.10",
"@csstools/css-parser-algorithms": "^4.0.0",
- "@csstools/css-tokenizer": "^4.0.0"
+ "@csstools/css-tokenizer": "^4.0.0",
+ "lru-cache": "^11.5.2"
},
"engines": {
- "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
+ "node": "^22.13.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": {
+ "version": "11.5.2",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz",
+ "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": "20 || >=22"
}
},
"node_modules/@asamuzakjp/dom-selector": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-7.1.1.tgz",
- "integrity": "sha512-67RZDnYRc8H/8MLDgQCDE//zoqVFwajkepHZgmXrbwybzXOEwOWGPYGmALYl9J2DOLfFPPs6kKCqmbzV895hTQ==",
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-8.3.2.tgz",
+ "integrity": "sha512-93Z1N+BQNXysodoicpOIyNh2drHfz/CTf9nnT0FEx72GJcIiwgydD7tGAr78j41LsYn3hlRn+LdGPuBLn1Bl8Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@asamuzakjp/generational-cache": "^1.0.1",
- "@asamuzakjp/nwsapi": "^2.3.9",
"bidi-js": "^1.0.3",
"css-tree": "^3.2.1",
- "is-potential-custom-element-name": "^1.0.1"
+ "is-potential-custom-element-name": "^1.0.1",
+ "lru-cache": "^11.5.2"
},
"engines": {
- "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
+ "node": "^22.13.0 || >=24.0.0"
}
},
- "node_modules/@asamuzakjp/generational-cache": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@asamuzakjp/generational-cache/-/generational-cache-1.0.1.tgz",
- "integrity": "sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==",
+ "node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": {
+ "version": "11.5.2",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz",
+ "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==",
"dev": true,
- "license": "MIT",
+ "license": "BlueOak-1.0.0",
"engines": {
- "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
+ "node": "20 || >=22"
}
},
- "node_modules/@asamuzakjp/nwsapi": {
- "version": "2.3.9",
- "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz",
- "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/@babel/code-frame": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
@@ -965,9 +967,9 @@
}
},
"node_modules/@csstools/color-helpers": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.1.0.tgz",
- "integrity": "sha512-064IFJdjTfUqnjpCVpMOdbr8FLQBhinbZj6yRv2An2E41O/pLEXqfFRWqGq/SxlE5PEUYTlvWsG2r8MswAVvkg==",
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.1.1.tgz",
+ "integrity": "sha512-gLNsunvwf3mCi5u5o46/Z/JcJMnhbHSaZ69rkgPzNM3J4s8hWwpPUQB6/tt0EDFyCiWzxANlx+2LJwpYj4zS1w==",
"dev": true,
"funding": [
{
@@ -1009,9 +1011,9 @@
}
},
"node_modules/@csstools/css-color-parser": {
- "version": "4.1.10",
- "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.1.10.tgz",
- "integrity": "sha512-UZhQLIUyJaaMepqehrCODwCg2KW25vFvLWBmqYFaPclYvvxzj/sG8LBOhBFCp11i9uE7t1EyS+RAoV9tztPFyw==",
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.2.2.tgz",
+ "integrity": "sha512-3QKjR/vxyjcSXBLgb6lP0S3MGdvwbmqSsvLPbYdVORqPDc8FX1HAJ0Spk38bxaRXgvENTA47tlhhbb5Z2e8hEg==",
"dev": true,
"funding": [
{
@@ -1025,7 +1027,7 @@
],
"license": "MIT",
"dependencies": {
- "@csstools/color-helpers": "^6.1.0",
+ "@csstools/color-helpers": "^6.1.1",
"@csstools/css-calc": "^3.3.0"
},
"engines": {
@@ -1060,9 +1062,9 @@
}
},
"node_modules/@csstools/css-syntax-patches-for-csstree": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.3.tgz",
- "integrity": "sha512-SH60bMfrRCJF3morcdk57WklujF4Jr/EsQUzqkarfHXEFcAR1gg7fS/chAE922Sehgzc1/+Tz5H3Ypa1HiEKrg==",
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.12.tgz",
+ "integrity": "sha512-3vLQK+dXxhBMR2Wx99PTCifE+vHtW2ndZWyla8yK813ev6oGhyn8Lja8jCyGAWTJ+LEYZK7EVtJxrDj8ztevJw==",
"dev": true,
"funding": [
{
@@ -1701,9 +1703,9 @@
}
},
"node_modules/@exodus/bytes": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.0.tgz",
- "integrity": "sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==",
+ "version": "1.15.1",
+ "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.1.tgz",
+ "integrity": "sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2544,42 +2546,351 @@
"url": "https://paulmillr.com/funding/"
}
},
- "node_modules/@nodelib/fs.scandir": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
- "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "node_modules/@oxc-parser/binding-android-arm-eabi": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm-eabi/-/binding-android-arm-eabi-0.143.0.tgz",
+ "integrity": "sha512-n9uozULWflPqBtdmI8lAabLqGKNgLVNN0ZH8HfgCwpKGNtzRzauB76jTiW/3YLkcA7N1zskpi9GdVnZuu1SAvg==",
+ "cpu": [
+ "arm"
+ ],
"dev": true,
"license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
- },
+ "optional": true,
+ "os": [
+ "android"
+ ],
"engines": {
- "node": ">= 8"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@nodelib/fs.stat": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "node_modules/@oxc-parser/binding-android-arm64": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.143.0.tgz",
+ "integrity": "sha512-9BbdjHETk6O3zH/DDid9IgBtF0GlpLabNKN231uraXpRDSfY+iiZxTP5bk1Z63GBownVdhdINFIeddmMz4MzpQ==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
"license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
"engines": {
- "node": ">= 8"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@nodelib/fs.walk": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
- "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "node_modules/@oxc-parser/binding-darwin-arm64": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.143.0.tgz",
+ "integrity": "sha512-gh+6ecoHUy4/sUcolBl/1qPXKBbYNxFY0Pk0ujgQvINTMSftJY7o4yb8gOkDJPeZeB8+a+u7xTe6umoP8N5HFA==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
"license": "MIT",
- "dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
- },
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
"engines": {
- "node": ">= 8"
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-darwin-x64": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.143.0.tgz",
+ "integrity": "sha512-qd1hl2d+lXgHv/VQ/M9qm8TrMC5T4RqDBwtOnl+1D0QMjwcz+8AaB4JSg8STgeag0GP6a6L74XEGAsrTSJWNzQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-freebsd-x64": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.143.0.tgz",
+ "integrity": "sha512-M5XXcNa7aOqLPKTR41msfghKu2yQ4xWvCm11/gwU0JzOzHNk5sgW//rVEjJ+LO48+VDAMzXTSzurUVxIDKwozw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-arm-gnueabihf": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.143.0.tgz",
+ "integrity": "sha512-T/GXusuOkPNQhCQCSBbcU/N8j0rAypuDBl1IyFK+lyYT594XsVz80clPC/OtbSSpBGyJxj8uYEfctxVuxVYoww==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-arm-musleabihf": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.143.0.tgz",
+ "integrity": "sha512-oKu4RcBlXSqo3OC62dp6YTnQaZIurNDpCX3BnAM3+bJxt7s8J2TJKMnC0UYer1qhlRaDCg6wkTaTw+2IlsZ12w==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-arm64-gnu": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.143.0.tgz",
+ "integrity": "sha512-WJBbD186AZmMGaSIhlktC+rPl8L3peCTXAh88Ih9uEvK0en2mPojGyCGYiL6mHtV1RPV3JyfJW5t6n5hh0lXhA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-arm64-musl": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.143.0.tgz",
+ "integrity": "sha512-t1AcYOwEzgceadT4v5e+vaCCb0AncCA3v5AyzfBAz/tMq11qzVccXKzNHtkWdjBsgvTKwRkaUF3QvT4kot8vcQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-ppc64-gnu": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.143.0.tgz",
+ "integrity": "sha512-RsnO/NoD8376LMJq8JS8TwI0ieNaFRTuNe2GVJntQg6gwZNMENZsEbknHdVwjpOmxdGLGodcwaGSbAeRr5Bgjw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-riscv64-gnu": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.143.0.tgz",
+ "integrity": "sha512-48fSVfR9TZi5CASZFyv0VC6z6BCoeihFsX031mAD/oSH7d9PYsPgIqza7d9mjP7Z2KTEpTFyH6SIu0Ui6R1vdg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-riscv64-musl": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.143.0.tgz",
+ "integrity": "sha512-T8CpdD+SfE01DnIOD4HpVxu0ZJOfMJ/VhCvikKfaXAxkZ+9veyLM/D2hpi7Y2hFUyPmVQO3FNZHmYzV/WlVR4g==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-s390x-gnu": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.143.0.tgz",
+ "integrity": "sha512-QLdeMsCcacenPEFsfxnBUDF1y6opyz5+fmOz9bfD5Y7fiGCMupUCuB3KTPQhNwshIG1P9fPqar9MHxuBDd4bwQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-x64-gnu": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.143.0.tgz",
+ "integrity": "sha512-659ujfqLy6k7cuH3sbzhd8b+ztSq+i6E2E9pG78Q0BmHjAExfGIdgc8cGgMdwAozDXeZFHkJ+LXYJdWsaGdgyw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-x64-musl": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.143.0.tgz",
+ "integrity": "sha512-/Mw/9j4TfZcnKphPrzOE6t4MMknXadcAAuVUlDRTF/ETWB5xOgQvOJV2Mh9We/bWxZdoxaGAdc+hy4GuYwQ2yQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-openharmony-arm64": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-openharmony-arm64/-/binding-openharmony-arm64-0.143.0.tgz",
+ "integrity": "sha512-8rIKWR2BFuifbIK/1XB9wTaSdtuJ25dlE7ZQYDnEwj/2xH2vHsxnvIjHT3ZjSVuLLwGGlSslIG/fbOJ8TV8rTw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-win32-arm64-msvc": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.143.0.tgz",
+ "integrity": "sha512-5U9kQYMfRRI6Zq7KDxgbIP0RMnKrfn3gLepRMgJuRkPSUALTiRCk9d/uyhb4lGDjUdzwK7mBkKqhLgzBPCmLpQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-win32-ia32-msvc": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.143.0.tgz",
+ "integrity": "sha512-25P7AaHk4R88Yv2XH4gToDVmh0cOu+bEURQU10CRrmvgabfRArSGAP5osmwUKeSUHj0VS50upbpbRWWW/m7mHA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-win32-x64-msvc": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.143.0.tgz",
+ "integrity": "sha512-ORMh3JE1s6V7ySicdRK7vgaDQnn5o+UHg9ct989PlWHbel8O9ARrmWXM6kZjrBMtNucxNayQ8g69G0VfWzhANw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxc-project/types": {
@@ -5260,19 +5571,6 @@
"node": "20 || >=22"
}
},
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/browserslist": {
"version": "4.28.7",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.7.tgz",
@@ -7195,23 +7493,6 @@
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"license": "MIT"
},
- "node_modules/fast-glob": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
- "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "^2.0.2",
- "@nodelib/fs.walk": "^1.2.3",
- "glob-parent": "^5.1.2",
- "merge2": "^1.3.0",
- "micromatch": "^4.0.8"
- },
- "engines": {
- "node": ">=8.6.0"
- }
- },
"node_modules/fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -7242,16 +7523,6 @@
],
"license": "BSD-3-Clause"
},
- "node_modules/fastq": {
- "version": "1.20.1",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
- "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "reusify": "^1.0.4"
- }
- },
"node_modules/fd-package-json": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/fd-package-json/-/fd-package-json-2.0.0.tgz",
@@ -7333,19 +7604,6 @@
"node": ">=10"
}
},
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/finalhandler": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
@@ -7617,6 +7875,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/get-tsconfig": {
+ "version": "4.14.1",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.1.tgz",
+ "integrity": "sha512-Dz/6HxkrxgNehhxLVeyv8sad9UzF2xBVeaKBQNDfJ5XiSXmp2gTR0eO0RWiT2NCKS5aGP9jjkOMggTN90qU50A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
"node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@@ -7638,19 +7909,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/glob/node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -8340,16 +8598,6 @@
"url": "https://github.com/sponsors/wooorm"
}
},
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.12.0"
- }
- },
"node_modules/is-plain-obj": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
@@ -8491,39 +8739,39 @@
}
},
"node_modules/jsdom": {
- "version": "29.1.1",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-29.1.1.tgz",
- "integrity": "sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q==",
+ "version": "30.0.1",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-30.0.1.tgz",
+ "integrity": "sha512-52v7mUVUfNQVYYqE1lcdaymWL0njO7lTLUog6ZvW2U5KsbiLk/GnZlVJ+qx0xfNJZ6Gn+KSpPNE52vurbxZwrA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@asamuzakjp/css-color": "^5.1.11",
- "@asamuzakjp/dom-selector": "^7.1.1",
+ "@asamuzakjp/css-color": "^6.0.5",
+ "@asamuzakjp/dom-selector": "^8.3.0",
"@bramus/specificity": "^2.4.2",
- "@csstools/css-syntax-patches-for-csstree": "^1.1.3",
- "@exodus/bytes": "^1.15.0",
+ "@csstools/css-syntax-patches-for-csstree": "^1.1.7",
+ "@exodus/bytes": "^1.15.1",
"css-tree": "^3.2.1",
"data-urls": "^7.0.0",
"decimal.js": "^10.6.0",
"html-encoding-sniffer": "^6.0.0",
"is-potential-custom-element-name": "^1.0.1",
- "lru-cache": "^11.3.5",
+ "lru-cache": "^11.5.2",
"parse5": "^8.0.1",
"saxes": "^6.0.0",
"symbol-tree": "^3.2.4",
- "tough-cookie": "^6.0.1",
- "undici": "^7.25.0",
+ "tough-cookie": "^6.0.2",
+ "undici": "^8.9.0",
"w3c-xmlserializer": "^5.0.0",
"webidl-conversions": "^8.0.1",
"whatwg-mimetype": "^5.0.0",
- "whatwg-url": "^16.0.1",
+ "whatwg-url": "^17.1.0",
"xml-name-validator": "^5.0.0"
},
"engines": {
- "node": "^20.19.0 || ^22.13.0 || >=24.0.0"
+ "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
},
"peerDependencies": {
- "canvas": "^3.0.0"
+ "canvas": "^3.2.3"
},
"peerDependenciesMeta": {
"canvas": {
@@ -8541,6 +8789,31 @@
"node": "20 || >=22"
}
},
+ "node_modules/jsdom/node_modules/undici": {
+ "version": "8.10.1",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-8.10.1.tgz",
+ "integrity": "sha512-YQ3WlbqjYMmNpdvDH64jAgLjxuAR9+649calDWhbshYaeQGO2bR4nI94ORJmwI3J9YhoKQnpyGOK+0zlWS5N5Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=22.19.0"
+ }
+ },
+ "node_modules/jsdom/node_modules/whatwg-url": {
+ "version": "17.1.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-17.1.0.tgz",
+ "integrity": "sha512-3GeworPmc2ZfEEHP7lEbUfBX/L75wdEsi0rLNhXcXxnoN5jyq0SL5gCy06SGW2cyTIZdTvWIDQNQoza++vKeaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@exodus/bytes": "^1.15.1",
+ "tr46": "^6.0.0",
+ "webidl-conversions": "^8.0.1"
+ },
+ "engines": {
+ "node": "^22.14.0 || >=24.0.0"
+ }
+ },
"node_modules/jsesc": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
@@ -8673,9 +8946,9 @@
}
},
"node_modules/knip": {
- "version": "5.88.1",
- "resolved": "https://registry.npmjs.org/knip/-/knip-5.88.1.tgz",
- "integrity": "sha512-tpy5o7zu1MjawVkLPuahymVJekYY3kYjvzcoInhIchgePxTlo+api90tBv2KfhAIe5uXh+mez1tAfmbv8/TiZg==",
+ "version": "6.32.2",
+ "resolved": "https://registry.npmjs.org/knip/-/knip-6.32.2.tgz",
+ "integrity": "sha512-WXTXbmocrw7gqm1A1TQvFN0OgJ7hUSU6E1g6SPRIzzHFogUBhXByc7cYeOFVtJ2uODg7DP4VbESYBYnfbtBYsg==",
"dev": true,
"funding": [
{
@@ -8689,30 +8962,26 @@
],
"license": "ISC",
"dependencies": {
- "@nodelib/fs.walk": "^1.2.3",
- "fast-glob": "^3.3.3",
+ "fdir": "^6.5.0",
"formatly": "^0.3.0",
- "jiti": "^2.6.0",
- "minimist": "^1.2.8",
- "oxc-resolver": "^11.19.1",
- "picocolors": "^1.1.1",
- "picomatch": "^4.0.1",
- "smol-toml": "^1.5.2",
+ "get-tsconfig": "4.14.1",
+ "jiti": "^2.7.0",
+ "oxc-parser": "^0.143.0",
+ "oxc-resolver": "11.24.2",
+ "picomatch": "^4.0.5",
+ "smol-toml": "^1.7.1",
"strip-json-comments": "5.0.3",
- "unbash": "^2.2.0",
- "yaml": "^2.8.2",
- "zod": "^4.1.11"
+ "tinyglobby": "^0.2.17",
+ "unbash": "^4.0.9",
+ "yaml": "^2.9.0",
+ "zod": "^4.4.3"
},
"bin": {
"knip": "bin/knip.js",
"knip-bun": "bin/knip-bun.js"
},
"engines": {
- "node": ">=18.18.0"
- },
- "peerDependencies": {
- "@types/node": ">=18",
- "typescript": ">=5.0.4 <7"
+ "node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/koffi": {
@@ -9684,16 +9953,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
"node_modules/micromark": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz",
@@ -10257,33 +10516,6 @@
],
"license": "MIT"
},
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/micromatch/node_modules/picomatch": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
- "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
"node_modules/mime": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
@@ -10706,6 +10938,53 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/oxc-parser": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.143.0.tgz",
+ "integrity": "sha512-ov0NzaDCOInknS7mP1cwKdJERt3utPW8ldjtdUXQ8Ty0GEFD08wk422vCUN0d7pST6kqtV7dxoI9w1Zi0l/9TA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@oxc-project/types": "^0.143.0"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/Boshen"
+ },
+ "optionalDependencies": {
+ "@oxc-parser/binding-android-arm-eabi": "0.143.0",
+ "@oxc-parser/binding-android-arm64": "0.143.0",
+ "@oxc-parser/binding-darwin-arm64": "0.143.0",
+ "@oxc-parser/binding-darwin-x64": "0.143.0",
+ "@oxc-parser/binding-freebsd-x64": "0.143.0",
+ "@oxc-parser/binding-linux-arm-gnueabihf": "0.143.0",
+ "@oxc-parser/binding-linux-arm-musleabihf": "0.143.0",
+ "@oxc-parser/binding-linux-arm64-gnu": "0.143.0",
+ "@oxc-parser/binding-linux-arm64-musl": "0.143.0",
+ "@oxc-parser/binding-linux-ppc64-gnu": "0.143.0",
+ "@oxc-parser/binding-linux-riscv64-gnu": "0.143.0",
+ "@oxc-parser/binding-linux-riscv64-musl": "0.143.0",
+ "@oxc-parser/binding-linux-s390x-gnu": "0.143.0",
+ "@oxc-parser/binding-linux-x64-gnu": "0.143.0",
+ "@oxc-parser/binding-linux-x64-musl": "0.143.0",
+ "@oxc-parser/binding-openharmony-arm64": "0.143.0",
+ "@oxc-parser/binding-win32-arm64-msvc": "0.143.0",
+ "@oxc-parser/binding-win32-ia32-msvc": "0.143.0",
+ "@oxc-parser/binding-win32-x64-msvc": "0.143.0"
+ }
+ },
+ "node_modules/oxc-parser/node_modules/@oxc-project/types": {
+ "version": "0.143.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.143.0.tgz",
+ "integrity": "sha512-u6JZdLBTLotrNC9Vd6vPssINdzcCzleKAH6EJKImQb7GtYvX5keN2dxkoK44stCc4tffE6QQRtZTXVSzsLUlWA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/Boshen"
+ }
+ },
"node_modules/oxc-resolver": {
"version": "11.24.2",
"resolved": "https://registry.npmjs.org/oxc-resolver/-/oxc-resolver-11.24.2.tgz",
@@ -10942,9 +11221,9 @@
"license": "ISC"
},
"node_modules/picomatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
- "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz",
+ "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -11259,27 +11538,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/queue-microtask": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
"node_modules/quick-lru": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
@@ -11604,6 +11862,16 @@
"node": ">=4"
}
},
+ "node_modules/resolve-pkg-maps": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+ }
+ },
"node_modules/responselike": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz",
@@ -11627,17 +11895,6 @@
"node": ">= 4"
}
},
- "node_modules/reusify": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
- "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "iojs": ">=1.0.0",
- "node": ">=0.10.0"
- }
- },
"node_modules/rimraf": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
@@ -11720,30 +11977,6 @@
"node": ">= 18"
}
},
- "node_modules/run-parallel": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
- "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "queue-microtask": "^1.2.2"
- }
- },
"node_modules/rxjs": {
"version": "7.8.2",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
@@ -12060,9 +12293,9 @@
}
},
"node_modules/smol-toml": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.7.1.tgz",
- "integrity": "sha512-PPlsspAZ4jbMBu5DMFhfUGDQLu/vrL4SyBROVS37x8ynnVmFIs1VPBz1Co8Xks3TvpIaZXmU85y4DrQ+UyVFoQ==",
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.8.0.tgz",
+ "integrity": "sha512-kCZr2V3ch9i00x8zXRhjUNVcjG9ijES5dDudkXvUVCT5QlJNQWElSJdZqyPemffHoLNUYwOcou0Fy+ojN0uHSQ==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
@@ -12443,22 +12676,22 @@
}
},
"node_modules/tldts": {
- "version": "7.0.28",
- "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.28.tgz",
- "integrity": "sha512-+Zg3vWhRUv8B1maGSTFdev9mjoo8Etn2Ayfs4cnjlD3CsGkxXX4QyW3j2WJ0wdjYcYmy7Lx2RDsZMhgCWafKIw==",
+ "version": "7.4.11",
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.11.tgz",
+ "integrity": "sha512-aBiNayCfTQxuIJBm06M+xR14cYaYlDlSXZbgsnKzKNxDKUVq7KFwTjwBSsb7m9Y5xO8WfPnBc63WaYFMTGlvqw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "tldts-core": "^7.0.28"
+ "tldts-core": "^7.4.11"
},
"bin": {
"tldts": "bin/cli.js"
}
},
"node_modules/tldts-core": {
- "version": "7.0.28",
- "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.28.tgz",
- "integrity": "sha512-7W5Efjhsc3chVdFhqtaU0KtK32J37Zcr9RKtID54nG+tIpcY79CQK/veYPODxtD/LJ4Lue66jvrQzIX2Z2/pUQ==",
+ "version": "7.4.11",
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.11.tgz",
+ "integrity": "sha512-CW3WN2rIIE/Of21mulhgnGOwoDyEFNygyIBOONSdyAuSATgMMUCpLeUlB+E8sAwA5xRV9hYPl+kyZ9citHCaKg==",
"dev": true,
"license": "MIT"
},
@@ -12481,19 +12714,6 @@
"tmp": "^0.2.0"
}
},
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
"node_modules/toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
@@ -12504,9 +12724,9 @@
}
},
"node_modules/tough-cookie": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.1.tgz",
- "integrity": "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.2.tgz",
+ "integrity": "sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -12738,9 +12958,9 @@
}
},
"node_modules/unbash": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/unbash/-/unbash-2.2.0.tgz",
- "integrity": "sha512-X2wH19RAPZE3+ldGicOkoj/SIA83OIxcJ6Cuaw23hf8Xc6fQpvZXY0SftE2JgS0QhYLUG4uwodSI3R53keyh7w==",
+ "version": "4.0.11",
+ "resolved": "https://registry.npmjs.org/unbash/-/unbash-4.0.11.tgz",
+ "integrity": "sha512-FoSOKV7NEofQSkAefMVHam4ZPKYMxjAydxiV72UFEDNV/YofxjGfiZ2A9pZjdL/lRJzTjcu4PABo1JYJX8N5iQ==",
"dev": true,
"license": "ISC",
"engines": {
diff --git a/desktop/package.json b/desktop/package.json
index c6f16dc6b..3358c3532 100644
--- a/desktop/package.json
+++ b/desktop/package.json
@@ -79,8 +79,8 @@
"electron-builder": "^26.15.3",
"eslint": "^9.39.5",
"eslint-plugin-react-hooks": "^6.1.1",
- "jsdom": "^29.1.1",
- "knip": "^5.88.1",
+ "jsdom": "^30.0.1",
+ "knip": "^6.32.2",
"postcss": "^8.5.26",
"tailwindcss": "^4.2.2",
"typescript": "^5.9.3",
diff --git a/desktop/tests/dialog-shell.test.tsx b/desktop/tests/dialog-shell.test.tsx
index 09f0c91de..e9be5963d 100644
--- a/desktop/tests/dialog-shell.test.tsx
+++ b/desktop/tests/dialog-shell.test.tsx
@@ -100,9 +100,23 @@ describe('Dialog shell', () => {
}
});
+ // jsdom's CSSOM re-serializes math functions on the way in — since jsdom 30,
+ // `min(476px, calc(100vh - 6rem))` reads back as `min(476px, -6rem + 100vh)`
+ // (jsdom 29 echoed the source text). Comparing the panel's style to the raw
+ // constant therefore pins jsdom's spelling, not the Dialog's behaviour. So:
+ // round-trip the constant through the SAME CSSOM and compare against that.
+ // The non-empty check keeps this honest — if a future jsdom silently drops
+ // the value (jsdom 29 did exactly that for `height`), '' === '' must not pass.
+ function cssSerialized(prop: 'height' | 'maxHeight', value: string): string {
+ const probe = document.createElement('div');
+ probe.style[prop] = value;
+ expect(probe.style[prop], `jsdom dropped ${prop}: ${value}`).not.toBe('');
+ return probe.style[prop];
+ }
+
it('applies the cap for its own size and hugs content by default', () => {
render();
- expect(panel().style.maxHeight).toBe(DIALOG_MAX_HEIGHTS.prompt);
+ expect(panel().style.maxHeight).toBe(cssSerialized('maxHeight', DIALOG_MAX_HEIGHTS.prompt));
expect(panel().getAttribute('style')).not.toContain(`; height:`);
});
@@ -110,11 +124,8 @@ describe('Dialog shell', () => {
// Appearance and Remote Access swap between an index and a detail view and
// would otherwise resize under the cursor. "Always maximum" is the honest
// version of the invented pixel height they used to set.
- // Read the style ATTRIBUTE, not .style.height: jsdom's cssstyle has a strict
- // parser for `height` that drops min()/calc() values, though it accepts the
- // same string for `max-height`. The attribute is what actually ships.
render();
- expect(panel().getAttribute('style')).toContain(`height: ${DIALOG_MAX_HEIGHTS.panel}`);
+ expect(panel().style.height).toBe(cssSerialized('height', DIALOG_MAX_HEIGHTS.panel));
});
});
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index b1b8ef56b..eddabd2ee 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index a351597e6..c42672d95 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME