From 5217f8570b908fffbe4c7ca51d33fbc7f3b5a790 Mon Sep 17 00:00:00 2001 From: Jaw <53564781+jaw52@users.noreply.github.com> Date: Thu, 29 Oct 2026 23:21:56 +0800 Subject: [PATCH] chore: add knip and remove the dead code it reports (#247) Adds knip (pnpm knip, knip.ts covering src, scripts, perf and e2e) and runs it in the CI frontend job. Removes what it reported: the unused codemirror and @types/dompurify dependencies, exports and test hooks used nowhere (AppLogo, Tooltip, barrel re-exports, duplicate default exports of lazily loaded settings pages), the unused iterateAll helper, and the zh entry for a deleted notification. rustfmt (used by lint-staged) is ignored as a toolchain binary. Co-authored-by: jaw52 <53564781+jaw52@users.noreply.github.com> --- .github/workflows/ci.yml | 1 + knip.ts | 15 + package.json | 4 +- pnpm-lock.yaml | 600 ++++++++++++++++-- src/editor/core/backend.ts | 5 - src/editor/core/cm/editing.ts | 13 - src/editor/core/cm/smartKeys.test.ts | 4 +- src/editor/core/cm/smartKeys.ts | 2 +- src/editor/core/cm/stickyScroll.ts | 4 +- src/editor/core/controller.ts | 5 - src/editor/core/model/tabs.ts | 13 - src/editor/navigation/lineMarkers.ts | 3 - src/editor/refactor/index.ts | 15 +- src/editor/structure/index.ts | 3 - src/features/app/closeGuard.ts | 6 - .../debugger/breakpoints/languages.ts | 5 - src/features/debugger/breakpoints/store.ts | 7 - src/features/debugger/state.ts | 6 - src/features/http-client/spring/request.ts | 2 - src/features/plugins/PluginsPage.tsx | 2 - src/features/plugins/store.ts | 3 - src/features/project-tree/model.ts | 5 - src/features/project-tree/store.ts | 4 - src/features/run/EditConfigsDialog.tsx | 2 - src/features/run/configs.ts | 19 - src/features/run/goModules.ts | 4 - src/features/run/store.ts | 4 - src/features/run/testing/index.ts | 4 +- src/features/run/types.ts | 11 +- src/features/services/store.ts | 6 - src/features/services/tree.ts | 9 - .../languages/ProjectStructurePage.tsx | 2 - .../languages/PythonInterpreterPage.tsx | 2 - src/features/settings/pages/builtins.tsx | 2 - src/features/templates/editor.ts | 2 +- src/features/templates/index.ts | 2 - src/features/templates/live/store.ts | 9 - src/features/tools/LanguageServersPage.tsx | 2 - src/features/vcs/branchOps.ts | 4 - src/features/vcs/comparison/iterables.ts | 17 - src/features/vcs/logStore.ts | 3 - src/features/vcs/model.ts | 11 - src/platform/colorScheme.ts | 5 - src/platform/i18n.ts | 6 - src/platform/languageSettings.ts | 10 - src/platform/locales/text/zh.json | 1 - src/platform/virtualDocs.ts | 5 - src/ui/AppLogo.module.css | 6 - src/ui/AppLogo.tsx | 26 - src/ui/Menu.tsx | 12 - src/ui/Splitter.tsx | 3 - src/ui/Tooltip.tsx | 14 +- src/ui/index.ts | 7 +- tsconfig.node.json | 2 +- 54 files changed, 588 insertions(+), 351 deletions(-) create mode 100644 knip.ts delete mode 100644 src/ui/AppLogo.module.css delete mode 100644 src/ui/AppLogo.tsx diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5aed379e..0866d227 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -82,6 +82,7 @@ jobs: - run: pnpm typecheck - run: pnpm lint - run: pnpm format:check + - run: pnpm knip - run: pnpm test - run: pnpm build diff --git a/knip.ts b/knip.ts new file mode 100644 index 00000000..a341b687 --- /dev/null +++ b/knip.ts @@ -0,0 +1,15 @@ +import type { KnipConfig } from "knip"; + +const config: KnipConfig = { + // Entries come from the Vite (index.html), Vitest, Playwright and package.json script plugins. + project: ["src/**/*.{ts,tsx,css}", "scripts/**/*.ts", "perf/**/*.ts", "e2e/**/*.ts"], + ignoreExportsUsedInFile: true, + // lint-staged formats Rust files with the toolchain's rustfmt. + ignoreBinaries: ["rustfmt"], + compilers: { + // Fonts come in through `@import` in global.css. + css: (text: string) => [...text.matchAll(/(?<=@)import[^;]+/g)].join("\n"), + }, +}; + +export default config; diff --git a/package.json b/package.json index 85865833..1ec1289e 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "lint": "oxlint", "format": "oxfmt", "format:check": "oxfmt --check", + "knip": "knip", "typecheck": "tsrs --noEmit && tsrs -p tsconfig.node.json --noEmit && tsrs -p perf --noEmit && tsrs -p scripts --noEmit", "gen:bindings": "cargo test -p openidea --test export_bindings", "gen:theme-docs": "node scripts/theme/gen-docs.ts", @@ -57,7 +58,6 @@ "@xterm/xterm": "^6.0.0", "anser": "^2.3.5", "clsx": "^2.1.1", - "codemirror": "^6.0.2", "dompurify": "^3.4.17", "emmet": "2.4.11", "immer": "^11.1.21", @@ -74,12 +74,12 @@ "@testing-library/jest-dom": "^7.0.1", "@testing-library/react": "^16.3.3", "@testing-library/user-event": "^14.6.8", - "@types/dompurify": "^3.2.0", "@types/node": "^26.6.5", "@types/react": "^19.1.8", "@types/react-dom": "^19.1.6", "@vitejs/plugin-react": "^6.0.2", "jsdom": "^30.1.3", + "knip": "^6.43.0", "lint-staged": "^17.6.0", "oxfmt": "^0.74.0", "oxlint": "^1.89.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d2c577df..b75c6245 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -77,9 +77,6 @@ importers: clsx: specifier: ^2.1.1 version: 2.1.1 - codemirror: - specifier: ^6.0.2 - version: 6.0.2 dompurify: specifier: ^3.4.17 version: 3.4.17 @@ -116,16 +113,13 @@ importers: version: 2.12.3 '@testing-library/jest-dom': specifier: ^7.0.1 - version: 7.0.1(@testing-library/dom@10.4.2)(vitest@5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1))) + version: 7.0.1(@testing-library/dom@10.4.2)(vitest@5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))) '@testing-library/react': specifier: ^16.3.3 version: 16.3.3(@testing-library/dom@10.4.2)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1) '@testing-library/user-event': specifier: ^14.6.8 version: 14.6.8(@testing-library/dom@10.4.2) - '@types/dompurify': - specifier: ^3.2.0 - version: 3.2.0 '@types/node': specifier: ^26.6.5 version: 26.6.5 @@ -137,10 +131,13 @@ importers: version: 19.3.0(@types/react@19.3.0) '@vitejs/plugin-react': specifier: ^6.0.2 - version: 6.1.2(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1)) + version: 6.1.2(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1)) jsdom: specifier: ^30.1.3 version: 30.1.3 + knip: + specifier: ^6.43.0 + version: 6.43.0 lint-staged: specifier: ^17.6.0 version: 17.6.0 @@ -161,10 +158,10 @@ importers: version: 6.0.3 vite: specifier: ^8.0.16 - version: 8.3.4(@types/node@26.6.5)(yaml@2.9.1) + version: 8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1) vitest: specifier: ^5.0.5 - version: 5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1)) + version: 5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1)) packages: @@ -357,6 +354,15 @@ packages: '@emmetio/scanner@1.0.4': resolution: {integrity: sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==} + '@emnapi/core@1.11.2': + resolution: {integrity: sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==} + + '@emnapi/runtime@1.11.2': + resolution: {integrity: sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==} + + '@emnapi/wasi-threads@1.2.2': + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} + '@exodus/bytes@1.16.0': resolution: {integrity: sha512-IcpW84uEn3N7ETtNZMlxKhfl6Pec8rUNGOTBtWbK1FKhJxIFAptZyVrvVRVBimAJxJCgc3PxepxkdWWG4DVzfA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} @@ -461,9 +467,244 @@ packages: resolution: {integrity: sha512-j37dj/h6p6pots1L7pLPPNuABEEu9WP4OYg9pW1g+nYG331j0+3canE9OagtYdytYvdSAMG+2fKU5cxep6LgjA==} engines: {node: '>=22.12.0'} + '@napi-rs/wasm-runtime@1.2.6': + resolution: {integrity: sha512-mRyDmEw9/fCDXCGfL1sbgIw/GUK0PVxRW4YwgPN61F3LQ+fSyoBFarJVzgGyhF6kRzEQZ0FejDqm4WLXSeqQmw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} + peerDependencies: + '@emnapi/core': ^1.7.1 || 2.0.0-beta.2 + '@emnapi/runtime': ^1.7.1 || 2.0.0-beta.2 + + '@oxc-parser/binding-android-arm-eabi@0.155.0': + resolution: {integrity: sha512-A6xv7hDtnTm+xlZ7utn6rRQpRMJHRhVr3gjRGqlx0RUX84mNk0pAsy6YN/wWhuOTkaZhRrrzaLxf0NfbH77j2w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxc-parser/binding-android-arm64@0.155.0': + resolution: {integrity: sha512-T1wWwH9/JI5g7Z4kEQwDOwhToxdDhRyOTklH+uuNpJ16m3MZFmGl+l2rKc0NHQdbVRG2LTOBsNjpW3h1BWytPA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxc-parser/binding-darwin-arm64@0.155.0': + resolution: {integrity: sha512-ZoRB3qJxJ8DWA41jHja+YeB0lLfjBy4T+Kr15vnN1k65X3zbJt3rPZftEwN4Ju4tmA4K/T9dWWD7Z8ewQLnrVA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxc-parser/binding-darwin-x64@0.155.0': + resolution: {integrity: sha512-vxtL86BtM+IgrpejA86nbTk5j0HKTIMeuaJ1fQciw6p9RfavPtIPjI7gN34owap0yG9txXBaAWpGdxokNwdqIw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxc-parser/binding-freebsd-x64@0.155.0': + resolution: {integrity: sha512-tN6Ru5e0UVnWaIuiH8jEwnvxuxg7FvhWwSd3oe5oDhOD4ObsSr9/N6WfHLjilUWlPPj65ptwrSDH0Y7lzwTzmw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxc-parser/binding-linux-arm-gnueabihf@0.155.0': + resolution: {integrity: sha512-h4ozA5n6L6lwolsz9iwunEhKWnIVbmFRots5QxEix0H6nJ5ICpuDa7PuShuhfpIDFe3+Qvyscioyiv+9g+4Syg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm-musleabihf@0.155.0': + resolution: {integrity: sha512-058/+LardpfuUlsKIvBGk/CYoakEVcMgqYx8GgyUZeOxFWTojYLlCc1Gb60/y21v3esDhHidgiY/Zbq9LpBhaQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm64-gnu@0.155.0': + resolution: {integrity: sha512-nrOt2Y3xIAzu+lSPzH0864ieO+iCCXgoo9qFlGANE8Xh0cQ+RP8Wstfp+/wXN2YCyb98cAGzX0VruKYw7it/jw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-arm64-musl@0.155.0': + resolution: {integrity: sha512-KYAayyN5hQbJPtGKtRxlyc8XYmyntOplyXSQzTDrmbz7l/GCrzQbSswvyJFBTH1LGtsZrbXOAfN52i/Kz6kLKg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-ppc64-gnu@0.155.0': + resolution: {integrity: sha512-CSuSY5hfjtsBnHXydOj8jiNfS1qHbdPZuPz1YL1cSgK7VmNYP+QlZIbG0BBYYBgX/vYEgZwbG9mBdW4YairZ5w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-riscv64-gnu@0.155.0': + resolution: {integrity: sha512-7KCfOQm+Nz2N8trAXbQkal4TQ5756WVEmhm35y816YHvyFnEfVsICsiV5k0pEszNf/fRm4cm2i6i18SJ6/iCWg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-riscv64-musl@0.155.0': + resolution: {integrity: sha512-JSlhgoK+/g1TGJI5NuADx2+6syhxnQNLCWLXyO5QLFyetomcr/vIxSdiNlmyAv963YXUzCuwAwRG6npZ5xyJ1A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-s390x-gnu@0.155.0': + resolution: {integrity: sha512-WFIX+dPokWp64mi434Md3U3lJaTwNxAphvGjpltoyQjGUsdXavOIRrnp9dOS34Hd75HOAwDxAI+YwWOwqmJbtg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-x64-gnu@0.155.0': + resolution: {integrity: sha512-g6xSDC/JpbnVOz5uafMGyK3txBVRFMQTx8opv/yHXGxqV3ZMVl3bf7W8XrSnF68dmy3gM4dgReNryuE53+WkeQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-x64-musl@0.155.0': + resolution: {integrity: sha512-6/4xlxKlZJWrQ0uwDFPc0H9+xLu7068CKhX3vIDW3SbvP/lVgnVuT5v6dyugeWskWpuxqF/WJ4WKwhxjU3pG2w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-openharmony-arm64@0.155.0': + resolution: {integrity: sha512-tltklL0J0XjDxIRTBXWOBhvc2mitcmES45pIxhwDWfxRyqz7Vkeu0NekTZEIxGE4f/lXgq3vZcjjffteQOVorg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-parser/binding-win32-arm64-msvc@0.155.0': + resolution: {integrity: sha512-alAb9TzjatUEsOeoncAziUnfdTDxfyswhalFZ9sC6plUgATIUx2NIZ0+bMn6aJ28AduS1OpG/OAisr/YISn4Ig==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxc-parser/binding-win32-ia32-msvc@0.155.0': + resolution: {integrity: sha512-yc5cbSfcGmRv/KpxDFuyk8adEBaWd/9HilWvBbQ4bFbus1V2PUh2mGB2Cfq9rqZTqLeiMT8x0skV+LKp9hOMgQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxc-parser/binding-win32-x64-msvc@0.155.0': + resolution: {integrity: sha512-8heq6jGq+rfpTDRDjoQiBHw0maQZf3IXkS99pdHQZPoTL5kyF5qyPS0RidUlSdnWDIqxXb5nux7GBD9cT+imUw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + '@oxc-project/types@0.154.0': resolution: {integrity: sha512-KYOUGQFlLWR+s4QMV2Q9ko38TZm7EdO87Qm7rvZLqk/webse/cDjtyxKhg/47l0byCbs/k46LT8qc4PKjAikzA==} + '@oxc-project/types@0.155.0': + resolution: {integrity: sha512-SeE8JPwW1xs1tHeNycjUtUBdhorRa8o4jlvjwk49R7/Z291i+4DQa7JJIgOm/TaYQZx+QrPQbVJ/9c8dMIZN8Q==} + + '@oxc-resolver/binding-android-arm-eabi@11.24.2': + resolution: {integrity: sha512-y09e0L0SRI2OA2tUIrjBgoV3eH5hvUKXNkJqXmNo5V2WxIjyC7I7aJfRLMEVpA8yi95f90gFDvO0VMgrDw+vwA==} + cpu: [arm] + os: [android] + + '@oxc-resolver/binding-android-arm64@11.24.2': + resolution: {integrity: sha512-cl4icWaZFnLdg8m6qtnh5rBMuGbxc/ptStFHLeCNwr+2cZjkjNwQu/jYRS0CHlnPecOJMpuS5M6/BH+0J/YkEg==} + cpu: [arm64] + os: [android] + + '@oxc-resolver/binding-darwin-arm64@11.24.2': + resolution: {integrity: sha512-At29QEMF6HajbQvgY8K6OXnHD1x9rad74xBEfmCB6ZqCGsdq75aK7tOYcTbOanMy8qdIBrfL3SMr3p/lfSlb9w==} + cpu: [arm64] + os: [darwin] + + '@oxc-resolver/binding-darwin-x64@11.24.2': + resolution: {integrity: sha512-A5Kqr1EUj4oIL5CF4WRssq/o5P0Y11cwoFouMRmQ7YnC/A8V93nv1nb7aSU8HwcgmXropjLNkVTl4MN87cu28Q==} + cpu: [x64] + os: [darwin] + + '@oxc-resolver/binding-freebsd-x64@11.24.2': + resolution: {integrity: sha512-R5xkRBRRz7ceH/P5Jrc6G7FmdUdgpLYyESFAUDVTNQ9K0sGPxcp4ljiwEwEqsvNcQ4sYbMRrWcHHBCu7ksAJVw==} + cpu: [x64] + os: [freebsd] + + '@oxc-resolver/binding-linux-arm-gnueabihf@11.24.2': + resolution: {integrity: sha512-k/RuYL4L/R58IBn3wT5ma3Wh4k62bp1eYCFRWCmMsasUOqL+H6sW0VGFadEzKWXFFlz+2uIMoeMk9ySSZJHgbg==} + cpu: [arm] + os: [linux] + + '@oxc-resolver/binding-linux-arm-musleabihf@11.24.2': + resolution: {integrity: sha512-bnHAak3ujYfH5pKk4NieFNbvYvernfoQDgwLddbZ3OtMYrem87/qjlA+u+aKG0oZcqSLGCful/6/CEA+aeAgaA==} + cpu: [arm] + os: [linux] + + '@oxc-resolver/binding-linux-arm64-gnu@11.24.2': + resolution: {integrity: sha512-vDT3KHgzYp47gmtNOqL2VNhCyl5Zv643eyxm//A68J8DeUGXrvD1pZFiaT4jSfe+RInfnn1R2yVHye4enx6RnA==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-arm64-musl@11.24.2': + resolution: {integrity: sha512-+kMlQvbzfyEYtu5FcjE4p+ttBLpKW4d/AsAsuE69BxV6V4twZJeIQZFfD8gh/wqglY0MkPSezWXQH0jBV13MUw==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-linux-ppc64-gnu@11.24.2': + resolution: {integrity: sha512-shjfMhmZ3gq9fv/w7bi3PnZlgOPG+2QAOFf0BJF0EgBSIGZ6PMLN2zbGEblTUYB/NKVDRyYhE2ff3dJ1QqNPkA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-riscv64-gnu@11.24.2': + resolution: {integrity: sha512-zGelwFR5oRo+b69k8Lrzun86DyUHzfKN6cnjbR9l7Z7NIRznOE/2ZvPa1IUKqAL2PzAXOdwkfVqNvO1H2RlpAw==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-riscv64-musl@11.24.2': + resolution: {integrity: sha512-qxZ1SWCXJY0eyhAlP6Lmo9F2Nrtx7EkYj9oCgL8apDPCwXwCEDA2U697bbT81JIc2IrVjxO4KX6WU2N+oN9Z4w==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-linux-s390x-gnu@11.24.2': + resolution: {integrity: sha512-sGCecF3cx2DFlH4t/z7ApnOnXqN48p5p5mlHDEnHTAukQa2P+qMVE4CwyWE9W+q/m3QJ7kKfGrIjax31f44oFQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-x64-gnu@11.24.2': + resolution: {integrity: sha512-k/VlMMcSzMlahb3/fENM4rTlsJ0s3fFROA0KXPBmKggqmTSaE383sl8F3KCOXPLmVsYfW6hCitMhXCEtNeZxxg==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-x64-musl@11.24.2': + resolution: {integrity: sha512-8hbnZyNi97b/8wapYaIF9+t9GmZKBW2vunaOc3h9HGJptH7b7XpvZqOTBSm/MpTjr7H497BlgOaSfLUdhmy2bw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-openharmony-arm64@11.24.2': + resolution: {integrity: sha512-MvyGik3a6pVgZ0t/kWlbmFxFLmXQJwgLsY2eYFHLpy0wGwRbfzeIGgDwQ3kXqE30z+kSXennRkCrT7TUvkptNg==} + cpu: [arm64] + os: [openharmony] + + '@oxc-resolver/binding-wasm32-wasi@11.24.2': + resolution: {integrity: sha512-vHcssMPwO08RTvj/c0iOBz90attxyG3wQJ0dTcyEQK43LRpcdLWZlV5feBhv6Isn6ahbQIzHbCgfa81+RiML0Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-resolver/binding-win32-arm64-msvc@11.24.2': + resolution: {integrity: sha512-uokJqro2iBqkFvJdKQLP7d8/BUmFwESQFVmIJUQKj1Xn1a/LysJoe1vmeECLF5b3jsV8CAL5sEMJXX6SdK9Nhg==} + cpu: [arm64] + os: [win32] + + '@oxc-resolver/binding-win32-x64-msvc@11.24.2': + resolution: {integrity: sha512-UqGPmo56KDfLlfXFAFIrNflHT8tFxWGEivWg3Zeyp4Uy2NlKN1FGPr6/BxcLGG3+kZ6Wp14g5Uj+n71boqZfiw==} + cpu: [x64] + os: [win32] + '@oxfmt/binding-android-arm-eabi@0.74.0': resolution: {integrity: sha512-xxQwrf5EPI5zxvuCTW8r6tzCTjPQ+h6+HqJ0iRKRy2zS1yBllt/xLVjoIyUc+FnR7g0a5g1SZv2yyDYhTItLbA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -999,6 +1240,9 @@ packages: cpu: [x64] os: [win32] + '@tybys/wasm-util@0.10.4': + resolution: {integrity: sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==} + '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} @@ -1101,10 +1345,6 @@ packages: '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - '@types/dompurify@3.2.0': - resolution: {integrity: sha512-Fgg31wv9QbLDA0SpTOXO3MaxySc4DKGLi8sna4/Utjo4r3ZRPdCt4UQee8BWr+Q5z21yifghREPJGYaEOEIACg==} - deprecated: This is a stub types definition. dompurify provides its own type definitions, so you do not need this installed. - '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} @@ -1204,9 +1444,6 @@ packages: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} - codemirror@6.0.2: - resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==} - commander@7.2.0: resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} engines: {node: '>= 10'} @@ -1443,6 +1680,9 @@ packages: resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} engines: {node: '>=12.0.0'} + fd-package-json@2.0.0: + resolution: {integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==} + fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -1452,11 +1692,19 @@ packages: picomatch: optional: true + formatly@0.11.4: + resolution: {integrity: sha512-TeCC10lP8KCgoX+Fe5lryILIT0/Dy+nP0OSVnsuB5CwXoLuOdqxCYlPFF1inR8S/zTy1ec7TjhS2TeRKWzzImA==} + engines: {node: '>=18.14.0'} + hasBin: true + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + get-tsconfig@4.14.3: + resolution: {integrity: sha512-++QEw4DIY7WGoukz+/+A/8dGYPT9l9yIadnmSgZ8Rjr3YVSVDipQSO9CdnJo9ePqFqUUqh+wk9uIaoiAwsiPkA==} + hachure-fill@0.5.2: resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} @@ -1488,6 +1736,10 @@ packages: is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} + hasBin: true + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1507,6 +1759,11 @@ packages: khroma@2.1.0: resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} + knip@6.43.0: + resolution: {integrity: sha512-8l3cCOg/EXoILO0qcSoMra49yQM91+lEIR4fu5Ko8rrArGX8xKdKZiGI9psPiY6rhLmfLERcMfFEByF0wli5CA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + layout-base@1.0.2: resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} @@ -1636,6 +1893,13 @@ packages: resolution: {integrity: sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==} engines: {node: '>=12.20.0'} + oxc-parser@0.155.0: + resolution: {integrity: sha512-C/ReSf1JUFukK/zvk6jhcNibSssvas5+ktIzK7fbKVd3CedWe59C3QwHEOrEZj/4Rt9+xg0Jeis/Jv1F/KM1mw==} + engines: {node: ^20.19.0 || >=22.12.0} + + oxc-resolver@11.24.2: + resolution: {integrity: sha512-FY91FiDBj7ls5MsFS9jN3tjz2o0/zsdSsymlakySaBwVJZorHhkWyICLZMKxlu1R9vYo+sd3z1jwb4J8x7bNDw==} + oxfmt@0.74.0: resolution: {integrity: sha512-G4OP7FgwGYZR5ttRpCOOfJdyRsSyvtn34vSXnjDq6Oqed5Dufg5mB44mank+51nAdHOKuTJ0lj0mksY7L+N61A==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1735,6 +1999,9 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + robust-predicates@3.0.3: resolution: {integrity: sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==} @@ -1763,6 +2030,10 @@ packages: resolution: {integrity: sha512-kkTORPAuxQz2g1QUuN0J8yGWT28tjGBfPOdJ4xT7Vbeu30veKUZQIoID2qGgCDAakaQn59UeZJJ4cFGB8PVP2A==} hasBin: true + smol-toml@1.9.1: + resolution: {integrity: sha512-j7WyPdf0CJoutMzMoPLF/bVXHtKZIT9Rb4eGeEbWw8X2t5oirjPgpL+OpaENZrILYaXqYwnVH+qgUwVbl+pUJQ==} + engines: {node: '>= 18'} + source-map-js@1.2.2: resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==} engines: {node: '>=0.10.0'} @@ -1778,6 +2049,10 @@ packages: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} + strip-json-comments@5.0.3: + resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} + engines: {node: '>=14.16'} + style-mod@4.1.4: resolution: {integrity: sha512-XXWIQt633/EpAFx8aZDOTjBzrCaGmhvEQlQo6MVPfa2OzO2cWo+4hV9h+6UkHYlXGfy+ODXKUdP7Pthmcu5ATw==} @@ -1819,6 +2094,9 @@ packages: resolution: {integrity: sha512-JfJeIHke7y2egdGGgRAvpCwYFUsHlM2gPcrVOxFkznt/4uzQ7HFmvE63iFHVLBJNDuyDOQgijDK/tXH/f6Msjg==} engines: {node: '>=6.10'} + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsrs@0.20.0-ts7.1.0-beta: resolution: {integrity: sha512-8NifAn2tcna3t/nluu1yFvp0fYE28vElDpnD4jiWik69+MDjiHgxdjH8sUYUEFmf/2hl6QIE5ExVGpJzQbBDPw==} engines: {node: '>=16.20.0'} @@ -1829,6 +2107,10 @@ packages: engines: {node: '>=14.17'} hasBin: true + unbash@6.0.1: + resolution: {integrity: sha512-0db9eS5iqybux41zLkX69nk90KTci7F7eZ+gXzEG/Q7E0tAqEBhRh5fkZvk1N7jT7QkGWqq34i8SFGPFEe1V8A==} + engines: {node: '>=14'} + undici-types@8.9.0: resolution: {integrity: sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==} @@ -1931,6 +2213,10 @@ packages: resolution: {integrity: sha512-4Nsy8K5Tr6SPDH9jhKJOHf7ChDrc1zufZTVSF7x72hwuEXBqxqk9G6cK+K2NRUtB3iELRJqjXb4JPDMBjMTl2Q==} engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} + walk-up-path@4.0.0: + resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==} + engines: {node: 20 || >=22} + webidl-conversions@8.0.1: resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==} engines: {node: '>=20'} @@ -1960,6 +2246,9 @@ packages: engines: {node: '>= 14.6'} hasBin: true + zod@4.6.7: + resolution: {integrity: sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==} + zustand@5.0.15: resolution: {integrity: sha512-MpSEjRiBkA9crSYeOUH32rJC7SVqAbm0Fqcqge/bUi2PPoLcBWKOsG+C8mevmpr8TwXHBVkChbbJiyvkE+i/3A==} engines: {node: '>=12.20.0'} @@ -2329,6 +2618,22 @@ snapshots: '@emmetio/scanner@1.0.4': {} + '@emnapi/core@1.11.2': + dependencies: + '@emnapi/wasi-threads': 1.2.2 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.11.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.2': + dependencies: + tslib: 2.8.1 + optional: true + '@exodus/bytes@1.16.0': {} '@floating-ui/core@1.8.0': @@ -2468,8 +2773,135 @@ snapshots: dependencies: '@chevrotain/types': 13.2.0 + '@napi-rs/wasm-runtime@1.2.6(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2)': + dependencies: + '@emnapi/core': 1.11.2 + '@emnapi/runtime': 1.11.2 + '@tybys/wasm-util': 0.10.4 + optional: true + + '@oxc-parser/binding-android-arm-eabi@0.155.0': + optional: true + + '@oxc-parser/binding-android-arm64@0.155.0': + optional: true + + '@oxc-parser/binding-darwin-arm64@0.155.0': + optional: true + + '@oxc-parser/binding-darwin-x64@0.155.0': + optional: true + + '@oxc-parser/binding-freebsd-x64@0.155.0': + optional: true + + '@oxc-parser/binding-linux-arm-gnueabihf@0.155.0': + optional: true + + '@oxc-parser/binding-linux-arm-musleabihf@0.155.0': + optional: true + + '@oxc-parser/binding-linux-arm64-gnu@0.155.0': + optional: true + + '@oxc-parser/binding-linux-arm64-musl@0.155.0': + optional: true + + '@oxc-parser/binding-linux-ppc64-gnu@0.155.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-gnu@0.155.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-musl@0.155.0': + optional: true + + '@oxc-parser/binding-linux-s390x-gnu@0.155.0': + optional: true + + '@oxc-parser/binding-linux-x64-gnu@0.155.0': + optional: true + + '@oxc-parser/binding-linux-x64-musl@0.155.0': + optional: true + + '@oxc-parser/binding-openharmony-arm64@0.155.0': + optional: true + + '@oxc-parser/binding-win32-arm64-msvc@0.155.0': + optional: true + + '@oxc-parser/binding-win32-ia32-msvc@0.155.0': + optional: true + + '@oxc-parser/binding-win32-x64-msvc@0.155.0': + optional: true + '@oxc-project/types@0.154.0': {} + '@oxc-project/types@0.155.0': {} + + '@oxc-resolver/binding-android-arm-eabi@11.24.2': + optional: true + + '@oxc-resolver/binding-android-arm64@11.24.2': + optional: true + + '@oxc-resolver/binding-darwin-arm64@11.24.2': + optional: true + + '@oxc-resolver/binding-darwin-x64@11.24.2': + optional: true + + '@oxc-resolver/binding-freebsd-x64@11.24.2': + optional: true + + '@oxc-resolver/binding-linux-arm-gnueabihf@11.24.2': + optional: true + + '@oxc-resolver/binding-linux-arm-musleabihf@11.24.2': + optional: true + + '@oxc-resolver/binding-linux-arm64-gnu@11.24.2': + optional: true + + '@oxc-resolver/binding-linux-arm64-musl@11.24.2': + optional: true + + '@oxc-resolver/binding-linux-ppc64-gnu@11.24.2': + optional: true + + '@oxc-resolver/binding-linux-riscv64-gnu@11.24.2': + optional: true + + '@oxc-resolver/binding-linux-riscv64-musl@11.24.2': + optional: true + + '@oxc-resolver/binding-linux-s390x-gnu@11.24.2': + optional: true + + '@oxc-resolver/binding-linux-x64-gnu@11.24.2': + optional: true + + '@oxc-resolver/binding-linux-x64-musl@11.24.2': + optional: true + + '@oxc-resolver/binding-openharmony-arm64@11.24.2': + optional: true + + '@oxc-resolver/binding-wasm32-wasi@11.24.2': + dependencies: + '@emnapi/core': 1.11.2 + '@emnapi/runtime': 1.11.2 + '@napi-rs/wasm-runtime': 1.2.6(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2) + optional: true + + '@oxc-resolver/binding-win32-arm64-msvc@11.24.2': + optional: true + + '@oxc-resolver/binding-win32-x64-msvc@11.24.2': + optional: true + '@oxfmt/binding-android-arm-eabi@0.74.0': optional: true @@ -2722,7 +3154,7 @@ snapshots: picocolors: 1.1.1 pretty-format: 27.5.1 - '@testing-library/jest-dom@7.0.1(@testing-library/dom@10.4.2)(vitest@5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1)))': + '@testing-library/jest-dom@7.0.1(@testing-library/dom@10.4.2)(vitest@5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1)))': dependencies: '@adobe/css-tools': 4.5.0 '@testing-library/dom': 10.4.2 @@ -2732,7 +3164,7 @@ snapshots: picocolors: 1.1.1 redent: 3.0.0 optionalDependencies: - vitest: 5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1)) + vitest: 5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1)) '@testing-library/react@16.3.3(@testing-library/dom@10.4.2)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': dependencies: @@ -2769,6 +3201,11 @@ snapshots: '@tsrs/win32-x64@0.20.0-ts7.1.0-beta': optional: true + '@tybys/wasm-util@0.10.4': + dependencies: + tslib: 2.8.1 + optional: true + '@types/aria-query@5.0.4': {} '@types/chai@5.2.3': @@ -2895,10 +3332,6 @@ snapshots: '@types/deep-eql@4.0.2': {} - '@types/dompurify@3.2.0': - dependencies: - dompurify: 3.4.17 - '@types/estree@1.0.9': {} '@types/geojson@7946.0.16': {} @@ -2923,19 +3356,19 @@ snapshots: d3-selection: 3.0.0 d3-transition: 3.0.1(d3-selection@3.0.0) - '@vitejs/plugin-react@6.1.2(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1))': + '@vitejs/plugin-react@6.1.2(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))': dependencies: '@rolldown/pluginutils': 1.0.1 - vite: 8.3.4(@types/node@26.6.5)(yaml@2.9.1) + vite: 8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1) - '@vitest/mocker@5.0.5(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1))': + '@vitest/mocker@5.0.5(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))': dependencies: '@jridgewell/trace-mapping': 0.3.31 '@vitest/spy': 5.0.5 estree-walker: 3.0.3 magic-string: 1.4.3 optionalDependencies: - vite: 8.3.4(@types/node@26.6.5)(yaml@2.9.1) + vite: 8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1) '@vitest/spy@5.0.5': {} @@ -2975,16 +3408,6 @@ snapshots: clsx@2.1.1: {} - codemirror@6.0.2: - dependencies: - '@codemirror/autocomplete': 6.20.3 - '@codemirror/commands': 6.11.1 - '@codemirror/language': 6.13.1 - '@codemirror/lint': 6.9.7 - '@codemirror/search': 6.7.2 - '@codemirror/state': 6.7.6 - '@codemirror/view': 6.43.14 - commander@7.2.0: {} commander@8.3.0: {} @@ -3238,13 +3661,26 @@ snapshots: expect-type@1.4.0: {} + fd-package-json@2.0.0: + dependencies: + walk-up-path: 4.0.0 + fdir@6.5.0(picomatch@4.0.7): optionalDependencies: picomatch: 4.0.7 + formatly@0.11.4: + dependencies: + fd-package-json: 2.0.0 + package-manager-detector: 1.9.0 + fsevents@2.3.3: optional: true + get-tsconfig@4.14.3: + dependencies: + resolve-pkg-maps: 1.0.0 + hachure-fill@0.5.2: {} html-encoding-sniffer@7.0.0: @@ -3269,6 +3705,8 @@ snapshots: is-potential-custom-element-name@1.0.1: {} + jiti@2.7.0: {} + js-tokens@4.0.0: {} jsdom@30.1.3: @@ -3302,6 +3740,21 @@ snapshots: khroma@2.1.0: {} + knip@6.43.0: + dependencies: + formatly: 0.11.4 + get-tsconfig: 4.14.3 + jiti: 2.7.0 + oxc-parser: 0.155.0 + oxc-resolver: 11.24.2 + picomatch: 4.0.7 + smol-toml: 1.9.1 + strip-json-comments: 5.0.3 + tinyglobby: 0.2.17 + unbash: 6.0.1 + yaml: 2.9.1 + zod: 4.6.7 + layout-base@1.0.2: {} layout-base@2.0.1: {} @@ -3411,6 +3864,52 @@ snapshots: obug@3.0.0: {} + oxc-parser@0.155.0: + dependencies: + '@oxc-project/types': 0.155.0 + optionalDependencies: + '@oxc-parser/binding-android-arm-eabi': 0.155.0 + '@oxc-parser/binding-android-arm64': 0.155.0 + '@oxc-parser/binding-darwin-arm64': 0.155.0 + '@oxc-parser/binding-darwin-x64': 0.155.0 + '@oxc-parser/binding-freebsd-x64': 0.155.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.155.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.155.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.155.0 + '@oxc-parser/binding-linux-arm64-musl': 0.155.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.155.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.155.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.155.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.155.0 + '@oxc-parser/binding-linux-x64-gnu': 0.155.0 + '@oxc-parser/binding-linux-x64-musl': 0.155.0 + '@oxc-parser/binding-openharmony-arm64': 0.155.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.155.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.155.0 + '@oxc-parser/binding-win32-x64-msvc': 0.155.0 + + oxc-resolver@11.24.2: + optionalDependencies: + '@oxc-resolver/binding-android-arm-eabi': 11.24.2 + '@oxc-resolver/binding-android-arm64': 11.24.2 + '@oxc-resolver/binding-darwin-arm64': 11.24.2 + '@oxc-resolver/binding-darwin-x64': 11.24.2 + '@oxc-resolver/binding-freebsd-x64': 11.24.2 + '@oxc-resolver/binding-linux-arm-gnueabihf': 11.24.2 + '@oxc-resolver/binding-linux-arm-musleabihf': 11.24.2 + '@oxc-resolver/binding-linux-arm64-gnu': 11.24.2 + '@oxc-resolver/binding-linux-arm64-musl': 11.24.2 + '@oxc-resolver/binding-linux-ppc64-gnu': 11.24.2 + '@oxc-resolver/binding-linux-riscv64-gnu': 11.24.2 + '@oxc-resolver/binding-linux-riscv64-musl': 11.24.2 + '@oxc-resolver/binding-linux-s390x-gnu': 11.24.2 + '@oxc-resolver/binding-linux-x64-gnu': 11.24.2 + '@oxc-resolver/binding-linux-x64-musl': 11.24.2 + '@oxc-resolver/binding-openharmony-arm64': 11.24.2 + '@oxc-resolver/binding-wasm32-wasi': 11.24.2 + '@oxc-resolver/binding-win32-arm64-msvc': 11.24.2 + '@oxc-resolver/binding-win32-x64-msvc': 11.24.2 + oxfmt@0.74.0: dependencies: tinypool: 2.2.0 @@ -3517,6 +4016,8 @@ snapshots: require-from-string@2.0.2: {} + resolve-pkg-maps@1.0.0: {} + robust-predicates@3.0.3: {} rolldown@1.2.14: @@ -3559,6 +4060,8 @@ snapshots: simple-git-hooks@2.14.0: {} + smol-toml@1.9.1: {} + source-map-js@1.2.2: {} std-env@4.3.0: {} @@ -3569,6 +4072,8 @@ snapshots: dependencies: min-indent: 1.0.1 + strip-json-comments@5.0.3: {} + style-mod@4.1.4: {} stylis@4.4.0: {} @@ -3600,6 +4105,9 @@ snapshots: ts-dedent@2.3.0: {} + tslib@2.8.1: + optional: true + tsrs@0.20.0-ts7.1.0-beta: optionalDependencies: '@tsrs/darwin-arm64': 0.20.0-ts7.1.0-beta @@ -3612,13 +4120,15 @@ snapshots: typescript@6.0.3: {} + unbash@6.0.1: {} + undici-types@8.9.0: {} undici@8.12.2: {} uuid@14.0.3: {} - vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1): + vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1): dependencies: lightningcss: 1.33.0 picomatch: 4.0.7 @@ -3628,12 +4138,13 @@ snapshots: optionalDependencies: '@types/node': 26.6.5 fsevents: 2.3.3 + jiti: 2.7.0 yaml: 2.9.1 - vitest@5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1)): + vitest@5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1)): dependencies: '@types/chai': 5.2.3 - '@vitest/mocker': 5.0.5(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1)) + '@vitest/mocker': 5.0.5(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1)) chai: 6.3.0 es-module-lexer: 2.3.2 expect-type: 1.4.0 @@ -3644,7 +4155,7 @@ snapshots: tinybench: 6.2.2 tinyexec: 1.3.1 tinyglobby: 0.2.17 - vite: 8.3.4(@types/node@26.6.5)(yaml@2.9.1) + vite: 8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1) why-is-node-running: 3.2.1 optionalDependencies: '@types/node': 26.6.5 @@ -3658,6 +4169,8 @@ snapshots: dependencies: xml-name-validator: 5.0.0 + walk-up-path@4.0.0: {} + webidl-conversions@8.0.1: {} whatwg-mimetype@5.0.0: {} @@ -3676,8 +4189,9 @@ snapshots: xmlchars@2.2.0: {} - yaml@2.9.1: - optional: true + yaml@2.9.1: {} + + zod@4.6.7: {} zustand@5.0.15(@types/react@19.3.0)(immer@11.1.21)(react@19.3.1): optionalDependencies: diff --git a/src/editor/core/backend.ts b/src/editor/core/backend.ts index d03481bb..c93be8dd 100644 --- a/src/editor/core/backend.ts +++ b/src/editor/core/backend.ts @@ -528,8 +528,3 @@ let current: DocBackend | null = null; export function docBackend(): DocBackend { return (current ??= isTauri() ? ipcBackend : createMemoryBackend()); } - -/** Test hook. */ -export function _setDocBackend(b: DocBackend | null) { - current = b; -} diff --git a/src/editor/core/cm/editing.ts b/src/editor/core/cm/editing.ts index 452547f6..69594bc4 100644 --- a/src/editor/core/cm/editing.ts +++ b/src/editor/core/cm/editing.ts @@ -287,8 +287,6 @@ export function nextOccurrence(view: EditorView): "selected" | "added" | "notFou return "added"; } -export const addCaretNextOccurrence: Command = (view) => nextOccurrence(view) !== "none"; - /** ⌃⌘G: select every occurrence of the selection, or of the word at the caret (whole words). */ export const selectAllOccurrences: Command = (view) => { const { state } = view; @@ -658,17 +656,6 @@ export function completeStatement(language: string): Command { }; } -// --- helpers ------------------------------------------------------------------- - -export function selectRange(view: EditorView, range: SelectionRange | { from: number; to: number }, center = true) { - view.dispatch({ - selection: EditorSelection.single(range.from, range.to), - effects: center ? EditorView.scrollIntoView(range.from, { y: "center" }) : undefined, - scrollIntoView: !center, - userEvent: "select", - }); -} - // --- comments ------------------------------------------------------------------------ export { commentLine } from "./comments"; diff --git a/src/editor/core/cm/smartKeys.test.ts b/src/editor/core/cm/smartKeys.test.ts index a5844dee..a99b33f9 100644 --- a/src/editor/core/cm/smartKeys.test.ts +++ b/src/editor/core/cm/smartKeys.test.ts @@ -8,8 +8,8 @@ import { insertTab, smartBackspace, smartBackspaceApplies, + tabOut, tabOutOfScope, - tabOutScopes, } from "./smartKeys"; /** One unit (2) deeper after a (non-blank) line ending in `{`, one less on a line starting with `}`. */ @@ -137,7 +137,7 @@ describe("smart backspace", () => { }); describe("tab out of pairs", () => { - const ext = [closeBrackets(), tabOutScopes]; + const ext = [closeBrackets(), tabOut]; const type = (v: EditorView, ch: string) => { const tr = insertBracket(v.state, ch); if (tr) v.dispatch(tr); diff --git a/src/editor/core/cm/smartKeys.ts b/src/editor/core/cm/smartKeys.ts index 5bcd3b70..5c128121 100644 --- a/src/editor/core/cm/smartKeys.ts +++ b/src/editor/core/cm/smartKeys.ts @@ -105,7 +105,7 @@ interface Scope { const leaveScopes = StateEffect.define(); /** Inside each pair the editor inserted itself; Tab at a scope's end steps over the closing character. */ -export const tabOutScopes = StateField.define({ +const tabOutScopes = StateField.define({ create: () => [], update(scopes, tr) { for (const e of tr.effects) if (e.is(leaveScopes)) scopes = scopes.filter((s) => !e.value.includes(s.to)); diff --git a/src/editor/core/cm/stickyScroll.ts b/src/editor/core/cm/stickyScroll.ts index 6e7fffa7..7bb8b4aa 100644 --- a/src/editor/core/cm/stickyScroll.ts +++ b/src/editor/core/cm/stickyScroll.ts @@ -4,7 +4,7 @@ * backend folding ranges, or from the syntax tree when there are none. * Clicking a sticky line scrolls to it, the caret where it was clicked. */ -import { Compartment, EditorSelection, Facet, type EditorState, type Extension } from "@codemirror/state"; +import { EditorSelection, Facet, type EditorState, type Extension } from "@codemirror/state"; import { EditorView, ViewPlugin, type ViewUpdate } from "@codemirror/view"; import { foldNodeProp, syntaxTree } from "@codemirror/language"; import { highlightTree } from "@lezer/highlight"; @@ -250,6 +250,4 @@ class StickyScroll { this.dom.remove(); } } - -export const stickyScrollCompartment = new Compartment(); export const stickyScroll: Extension = ViewPlugin.fromClass(StickyScroll); diff --git a/src/editor/core/controller.ts b/src/editor/core/controller.ts index 39e758f6..40cbba52 100644 --- a/src/editor/core/controller.ts +++ b/src/editor/core/controller.ts @@ -1350,11 +1350,6 @@ export function editorController(): EditorController { return (controller ??= new EditorController()); } -/** Test hook. */ -export function _setEditorController(c: EditorController | null) { - controller = c; -} - /** "Finder" / "Explorer" / "Files", like IDEA's Open In submenu. */ function revealLabel(): string { const os = usePlatform.getState().os; diff --git a/src/editor/core/model/tabs.ts b/src/editor/core/model/tabs.ts index 2dcb9ee6..dc58c9c4 100644 --- a/src/editor/core/model/tabs.ts +++ b/src/editor/core/model/tabs.ts @@ -69,11 +69,6 @@ export function paneOf(s: TabsState, paneId: string): Pane { return p; } -export function activeTab(s: TabsState, paneId = s.activePane): Tab | null { - const p = s.panes[paneId]; - return p?.tabs.find((t) => t.id === p.active) ?? null; -} - export function findTab(s: TabsState, key: string, paneId?: string): { paneId: string; tab: Tab } | null { const order = paneId ? [paneId, ...paneIds(s).filter((p) => p !== paneId)] : paneIds(s); for (const id of order) { @@ -298,14 +293,6 @@ export function closeKey(s: TabsState, key: string): TabsState { return next; } -/** Re-keys tabs after a rename / move. */ -export function rekey(s: TabsState, fromKey: string, input: EditorInput): TabsState { - const panes: Record = {}; - for (const [id, p] of Object.entries(s.panes)) - panes[id] = { ...p, tabs: p.tabs.map((t) => (t.input.key === fromKey ? { ...t, input } : t)) }; - return { ...s, panes }; -} - export function reopenClosed(s: TabsState): { state: TabsState; tabId: string; paneId: string } | null { const openNow = openKeys(s); const closed = [...s.closed]; diff --git a/src/editor/navigation/lineMarkers.ts b/src/editor/navigation/lineMarkers.ts index 5ab67dae..b52da96f 100644 --- a/src/editor/navigation/lineMarkers.ts +++ b/src/editor/navigation/lineMarkers.ts @@ -14,9 +14,6 @@ export type MarkerKind = "implemented" | "overridden" | "implementing" | "overri /** Settings › Gutter Icons groups: ↓ markers and ↑ markers. */ export type MarkerGroup = "inheritors" | "supers"; -export const markerGroup = (kind: MarkerKind): MarkerGroup => - kind === "implemented" || kind === "overridden" ? "inheritors" : "supers"; - export const MARKER_ICONS: Record = { implemented: "gutter-implemented", overridden: "gutter-overridden", diff --git a/src/editor/refactor/index.ts b/src/editor/refactor/index.ts index 1d8fd77e..00c2a85a 100644 --- a/src/editor/refactor/index.ts +++ b/src/editor/refactor/index.ts @@ -1,15 +1,2 @@ -/** - * Refactorings: Refactor This and the Refactor menu over LSP code actions, - * Safe Delete, and the syntax-based fallbacks used when the language server - * is not usable (see `@/editor/structure`). - */ -export { introduceFallback, type FallbackReason, type IntroduceKind } from "./introduce"; export { refactorThis, runRefactoring, showNothingHere } from "./refactorThis"; -export { - askUsagesDetected, - fileUsages, - safeDelete, - viewUsages, - type FileUsages, - type UsagesAnswer, -} from "./safeDelete"; +export { askUsagesDetected, fileUsages, safeDelete, viewUsages } from "./safeDelete"; diff --git a/src/editor/structure/index.ts b/src/editor/structure/index.ts index c7858311..129bb558 100644 --- a/src/editor/structure/index.ts +++ b/src/editor/structure/index.ts @@ -43,12 +43,9 @@ export type { Locals, LocalSymbol, NodeAt, - NotLocalReason, StructuralRanges, StructureSupport, - SyntaxError, SyntaxErrors, - SyntaxNode, } from "@/bindings"; export interface QueryOptions { diff --git a/src/features/app/closeGuard.ts b/src/features/app/closeGuard.ts index b2257fc1..28f894eb 100644 --- a/src/features/app/closeGuard.ts +++ b/src/features/app/closeGuard.ts @@ -169,9 +169,3 @@ export function installCloseGuard(deps: CloseDeps = defaultDeps): () => void { unsubs.forEach((u) => u()); }; } - -/** Tests only. */ -export function _setDirtyForTests(ids: number[]) { - dirtyDocs.clear(); - ids.forEach((i) => dirtyDocs.add(i)); -} diff --git a/src/features/debugger/breakpoints/languages.ts b/src/features/debugger/breakpoints/languages.ts index 7de4e7bd..1496645d 100644 --- a/src/features/debugger/breakpoints/languages.ts +++ b/src/features/debugger/breakpoints/languages.ts @@ -21,11 +21,6 @@ function load() { .finally(() => (loading = false)); } -/** For tests: languages that have a debugger (`null` = unknown, allow everything). */ -export function _setDebuggableLanguages(ids: Iterable | null) { - debuggable = ids ? new Set(ids) : null; -} - /** Whether a new breakpoint may be placed in a file of `language`. */ export function canPlaceBreakpoint(language: string): boolean { if (workflowSettings().debugger.breakpointsAnyFile) return true; diff --git a/src/features/debugger/breakpoints/store.ts b/src/features/debugger/breakpoints/store.ts index 60881aef..fcb0bf37 100644 --- a/src/features/debugger/breakpoints/store.ts +++ b/src/features/debugger/breakpoints/store.ts @@ -229,10 +229,3 @@ export function setMuted(muted: boolean) { persist(); for (const path of Object.keys(useBreakpoints.getState().byFile)) scheduleSync(path); } - -export function allBreakpoints(): Array<{ path: string; bp: BreakpointEntry }> { - const { byFile } = useBreakpoints.getState(); - return Object.keys(byFile) - .sort() - .flatMap((path) => byFile[path]!.map((bp) => ({ path, bp }))); -} diff --git a/src/features/debugger/state.ts b/src/features/debugger/state.ts index 32f34de0..336c9eb5 100644 --- a/src/features/debugger/state.ts +++ b/src/features/debugger/state.ts @@ -62,12 +62,6 @@ export interface ConsoleLine { spans: Span[]; } -export interface WatchResult { - expression: string; - result: Variable | null; - error: string | null; -} - interface DebugState { sessions: Record; /** Session shown in the Debug tool window / title bar. */ diff --git a/src/features/http-client/spring/request.ts b/src/features/http-client/spring/request.ts index 6678a6b6..7686e39a 100644 --- a/src/features/http-client/spring/request.ts +++ b/src/features/http-client/spring/request.ts @@ -6,8 +6,6 @@ import type { Endpoint } from "./endpoints"; import { allClasses, parseSource, type ClassDecl, type SourceFile } from "./source"; -export const DEFAULT_HOST = "http://localhost:8080"; - /** Flat `key → value` of a `.properties` file (`=`, `:` or space separated; `#` / `!` comments). */ export function parseProperties(text: string): Map { const out = new Map(); diff --git a/src/features/plugins/PluginsPage.tsx b/src/features/plugins/PluginsPage.tsx index 7eff0053..8d496a3f 100644 --- a/src/features/plugins/PluginsPage.tsx +++ b/src/features/plugins/PluginsPage.tsx @@ -678,5 +678,3 @@ export function PluginsPage() { ); } - -export default PluginsPage; diff --git a/src/features/plugins/store.ts b/src/features/plugins/store.ts index e210ade3..01913365 100644 --- a/src/features/plugins/store.ts +++ b/src/features/plugins/store.ts @@ -183,6 +183,3 @@ export async function runPluginCommand(pluginId: string, commandId: string, arg: return null; } } - -/** Plugins whose contributions are live (enabled and running, or contribution-only). */ -export const isLive = (p: PluginInfo) => p.status === "active" || p.status === "static"; diff --git a/src/features/project-tree/model.ts b/src/features/project-tree/model.ts index 02eba182..4dc77bfd 100644 --- a/src/features/project-tree/model.ts +++ b/src/features/project-tree/model.ts @@ -568,8 +568,3 @@ export function dropListings(listings: Map, dirs: if (!dirs.length) return; for (const key of [...listings.keys()]) if (dirs.some((d) => isSameOrInside(key, d))) listings.delete(key); } - -/** Label for a node path used in dialogs: the file name, or the compacted label. */ -export function displayName(node: ProjectNode): string { - return node.root ? node.label : nameOf(node.path); -} diff --git a/src/features/project-tree/store.ts b/src/features/project-tree/store.ts index a3cfe17f..9fad9fc8 100644 --- a/src/features/project-tree/store.ts +++ b/src/features/project-tree/store.ts @@ -404,10 +404,6 @@ export function loadDir(path: string, force = false): Promise { return p; } -export function isLoading(path: string): boolean { - return inflight.has(path); -} - /** Applies a backend `fsChanged` event: reloads affected loaded folders only. */ export async function applyFsChange(event: { created: string[]; modified: string[]; removed: string[] }) { const s = get(); diff --git a/src/features/run/EditConfigsDialog.tsx b/src/features/run/EditConfigsDialog.tsx index a6c54e70..0f331609 100644 --- a/src/features/run/EditConfigsDialog.tsx +++ b/src/features/run/EditConfigsDialog.tsx @@ -32,8 +32,6 @@ import { blankTemplate, COMPOUND, missingParams, newConfigOfType, templateId, ty import styles from "./Run.module.css"; import { tx } from "@/platform/i18n"; -export { envFromRows } from "./EnvDialog"; - export function EditConfigsOverlay() { const open = useRun((s) => s.editorOpen); if (!open) return null; diff --git a/src/features/run/configs.ts b/src/features/run/configs.ts index fd5161ed..82b2dd7c 100644 --- a/src/features/run/configs.ts +++ b/src/features/run/configs.ts @@ -159,25 +159,6 @@ export function mergeConfigs(detected: readonly RunConfig[], user: readonly RunC return [...detected.filter((d) => !ids.has(d.id)), ...user]; } -export function configsEqual(a: RunConfig, b: RunConfig): boolean { - return ( - a.id === b.id && - a.name === b.name && - a.kind === b.kind && - a.command === b.command && - a.args.join("\u0000") === b.args.join("\u0000") && - (a.cwd ?? "") === (b.cwd ?? "") && - JSON.stringify(sortedEnv(a.env)) === JSON.stringify(sortedEnv(b.env)) && - a.isTest === b.isTest && - (a.debugAdapter ?? "") === (b.debugAdapter ?? "") && - a.detected === b.detected - ); -} - -function sortedEnv(env: RunConfig["env"]) { - return Object.entries(env).sort(([a], [b]) => a.localeCompare(b)); -} - let counter = 0; export function uid(): string { const rnd = diff --git a/src/features/run/goModules.ts b/src/features/run/goModules.ts index 4b7f6d80..5b55a99f 100644 --- a/src/features/run/goModules.ts +++ b/src/features/run/goModules.ts @@ -34,7 +34,3 @@ export async function loadGoModules(root: string | null, configs: readonly RunCo }), ); } - -export function clearGoModules() { - known.clear(); -} diff --git a/src/features/run/store.ts b/src/features/run/store.ts index 44119de2..b3fe9099 100644 --- a/src/features/run/store.ts +++ b/src/features/run/store.ts @@ -245,10 +245,6 @@ function persistTemporary() { ); } -export function isTemporary(id: string | null | undefined): boolean { - return !!id && useRun.getState().temporary.includes(id); -} - /** * Selects the configuration for a gutter / context run: a saved or detected * configuration with the same id is reused, otherwise `config` becomes a diff --git a/src/features/run/testing/index.ts b/src/features/run/testing/index.ts index 0a7e6cbe..0409ea1c 100644 --- a/src/features/run/testing/index.ts +++ b/src/features/run/testing/index.ts @@ -7,9 +7,9 @@ import { jvmParser } from "./jvm"; import { pytestParser } from "./pytest"; import type { TestEvent, TestOutputParser } from "./types"; -export type { TestEvent, TestOutputParser, TestLocation, TestStatus } from "./types"; +export type { TestEvent, TestOutputParser, TestStatus } from "./types"; export { parseDuration } from "./types"; -export { TestResults, nodeStatus, type TestNode, type TestCounts } from "./results"; +export { TestResults, nodeStatus, type TestNode } from "./results"; export { cargoParser, goParser, jsParser, jvmParser, pytestParser }; /** Runs several parsers side by side (unknown tool: e.g. `make test`). */ diff --git a/src/features/run/types.ts b/src/features/run/types.ts index d685482c..98527960 100644 --- a/src/features/run/types.ts +++ b/src/features/run/types.ts @@ -4,12 +4,7 @@ * command line. Other features contribute types with `registerRunConfigType`. */ import type { RunConfig } from "@/platform/ipc"; -import { - registerRunConfigType, - runConfigTypes, - useRunConfigTypes, - type RunConfigTypeContribution, -} from "@/workbench/contributions"; +import { registerRunConfigType, useRunConfigTypes, type RunConfigTypeContribution } from "@/workbench/contributions"; import { formatArgs, parseArgs, uid, uniqueName } from "./configs"; import { applicationType, @@ -322,10 +317,6 @@ export function typeFor(kind: string): RunConfigTypeContribution | undefined { return useRunConfigTypes.getState().types.get(kind); } -export { runConfigTypes }; - -export const isCompound = (c: Pick) => c.kind === COMPOUND; - /** Only Debug applies to `c` (Remote JVM Debug, Go Remote…): it attaches and launches no process. */ export const isDebugOnly = (c: Pick, type = typeFor(c.kind)) => !!type?.debugOnly; diff --git a/src/features/services/store.ts b/src/features/services/store.ts index 9534fe59..7b51c2e9 100644 --- a/src/features/services/store.ts +++ b/src/features/services/store.ts @@ -69,12 +69,6 @@ export function endpointOf(connId: string): DockerEndpoint { return connections().find((c) => c.id === connId)?.endpoint ?? { kind: "default" }; } -/** The docker executable (for run configurations and terminals), from any snapshot. */ -export function dockerExecutable(): string { - for (const c of Object.values(useServices.getState().conns)) if (c.snapshot?.executable) return c.snapshot.executable; - return "docker"; -} - function patchConn(id: string, patch: Partial) { useServices.setState((s) => ({ conns: { ...s.conns, [id]: { ...connectionState(id, s), ...patch } } })); } diff --git a/src/features/services/tree.ts b/src/features/services/tree.ts index 1bd11a45..ad635ba1 100644 --- a/src/features/services/tree.ts +++ b/src/features/services/tree.ts @@ -93,12 +93,3 @@ export function addServiceMenu(providers = serviceProviders()): MenuItem[] { const groups = providers.map((p) => p.addMenu?.() ?? []).filter((g) => g.length > 0); return groups.flatMap((g, i) => (i === 0 ? g : [{ kind: "separator" } as MenuItem, ...g])); } - -/** The selected node and its provider. */ -export function selectedService(): (Located & { contribution: ServiceProviderContribution | undefined }) | null { - const { roots, selectedKey } = useServicesTree.getState(); - if (!selectedKey) return null; - const found = indexTree(roots).get(selectedKey); - if (!found) return null; - return { ...found, contribution: serviceProviders().find((p) => p.id === found.provider) }; -} diff --git a/src/features/settings/languages/ProjectStructurePage.tsx b/src/features/settings/languages/ProjectStructurePage.tsx index e637de0e..1bb59691 100644 --- a/src/features/settings/languages/ProjectStructurePage.tsx +++ b/src/features/settings/languages/ProjectStructurePage.tsx @@ -339,5 +339,3 @@ export function ProjectStructurePage() { ); } - -export default ProjectStructurePage; diff --git a/src/features/settings/languages/PythonInterpreterPage.tsx b/src/features/settings/languages/PythonInterpreterPage.tsx index c2960b17..ed5fdb4e 100644 --- a/src/features/settings/languages/PythonInterpreterPage.tsx +++ b/src/features/settings/languages/PythonInterpreterPage.tsx @@ -330,5 +330,3 @@ export function PythonInterpreterPage() { ); } - -export default PythonInterpreterPage; diff --git a/src/features/settings/pages/builtins.tsx b/src/features/settings/pages/builtins.tsx index 3904f2a5..645000c4 100644 --- a/src/features/settings/pages/builtins.tsx +++ b/src/features/settings/pages/builtins.tsx @@ -4,8 +4,6 @@ import { useSetting } from "../components/context"; import { KeymapPage, keymapSearchLabels } from "../keymap/KeymapPage"; import { RecognizedFileTypes } from "./FileTypes"; import type { PageSpec } from "./spec"; - -export { APPEARANCE_GROUP } from "./behavior"; export const EDITOR_GROUP = "Editor"; function ExcludeRow() { diff --git a/src/features/templates/editor.ts b/src/features/templates/editor.ts index 1ff51930..d4e432a5 100644 --- a/src/features/templates/editor.ts +++ b/src/features/templates/editor.ts @@ -64,7 +64,7 @@ export const templateDoc = Facet.define({ * The LSP completion uses `override`, so it must merge sources found under * this key (`state.languageDataAt(EXTRA_COMPLETION_KEY, pos)`). */ -export const EXTRA_COMPLETION_KEY = "openideaCompletion"; +const EXTRA_COMPLETION_KEY = "openideaCompletion"; /** * Language-data key for a lookup restricted to one source: `(state) => diff --git a/src/features/templates/index.ts b/src/features/templates/index.ts index daf9e4e8..de5b3ca0 100644 --- a/src/features/templates/index.ts +++ b/src/features/templates/index.ts @@ -24,8 +24,6 @@ import { tagAtCaret, updateTag } from "./emmet/editor"; import { promptAbbreviation, UpdateTagDialogHost } from "./emmet/UpdateTagDialog"; import { tx } from "@/platform/i18n"; -export { EXTRA_COMPLETION_KEY } from "./editor"; - const EDITOR_WHEN = "textEditorActive && !editorReadOnly && (editorFocus || popupOpen || !toolWindowFocus)"; const MARKUP_PATH = /\.(html?|xhtml|shtml|vue|svelte|xml)$/i; diff --git a/src/features/templates/live/store.ts b/src/features/templates/live/store.ts index 3790d0f5..e048d919 100644 --- a/src/features/templates/live/store.ts +++ b/src/features/templates/live/store.ts @@ -65,15 +65,6 @@ export function resetTemplate(id: string) { commit({ templates, deleted: c.deleted.filter((d) => d !== id) }); } -export function resetAllTemplates() { - commit({ - templates: Object.fromEntries( - Object.entries(useLiveTemplates.getState().custom.templates).filter(([id]) => !BUILTIN_IDS.has(id)), - ), - deleted: [], - }); -} - export function isModifiedBuiltin(id: string): boolean { return BUILTIN_IDS.has(id) && id in useLiveTemplates.getState().custom.templates; } diff --git a/src/features/tools/LanguageServersPage.tsx b/src/features/tools/LanguageServersPage.tsx index 509d3725..6b0d722c 100644 --- a/src/features/tools/LanguageServersPage.tsx +++ b/src/features/tools/LanguageServersPage.tsx @@ -444,5 +444,3 @@ export function LanguageServersPage() { ); } - -export default LanguageServersPage; diff --git a/src/features/vcs/branchOps.ts b/src/features/vcs/branchOps.ts index 07c15ca3..b26dc251 100644 --- a/src/features/vcs/branchOps.ts +++ b/src/features/vcs/branchOps.ts @@ -468,7 +468,3 @@ export function toggleFavoriteBranch(b: Branch) { // Favorites last for the session only. } } - -export function notifyNotGit() { - notifications().notify({ group: "vcs", level: "warning", title: "The project is not under Git version control" }); -} diff --git a/src/features/vcs/comparison/iterables.ts b/src/features/vcs/comparison/iterables.ts index ad3699df..25432227 100644 --- a/src/features/vcs/comparison/iterables.ts +++ b/src/features/vcs/comparison/iterables.ts @@ -45,23 +45,6 @@ export const invert = (it: DiffIterable): DiffIterable => create(unchanged(it), export const createUnchanged = (ranges: readonly Range[], length1: number, length2: number) => invert(create(ranges, length1, length2)); -/** Both changed and unchanged ranges in order, without empty ones (DiffIterableUtil.iterateAll). */ -export function iterateAll(it: DiffIterable): [Range, boolean][] { - const out: [Range, boolean][] = []; - let last1 = 0; - let last2 = 0; - for (const c of it.changes) { - const gap = range(last1, c.start1, last2, c.start2); - if (!isEmptyRange(gap)) out.push([gap, true]); - out.push([c, false]); - last1 = c.end1; - last2 = c.end2; - } - const tail = range(last1, it.length1, last2, it.length2); - if (!isEmptyRange(tail)) out.push([tail, true]); - return out; -} - /** Changes of sequences of keys compared by equality (DiffIterableUtil.diff). */ export const diffSequences = (a: readonly T[], b: readonly T[]): DiffIterable => create(diffKeys(a, b), a.length, b.length); diff --git a/src/features/vcs/logStore.ts b/src/features/vcs/logStore.ts index 8a34fdaa..04c66e44 100644 --- a/src/features/vcs/logStore.ts +++ b/src/features/vcs/logStore.ts @@ -64,9 +64,6 @@ interface LogState { generation: number; } -/** Fixed content tabs of the Git tool window. */ -export type GitTab = "changes" | "shelf" | "stashes" | "log" | "console" | "worktrees"; - /** A log tab of its own (IDEA's "History: file" / "Log: branch" tabs): its own filters and view. */ export interface LogTab { id: string; diff --git a/src/features/vcs/model.ts b/src/features/vcs/model.ts index 43cb0e6c..b39b112b 100644 --- a/src/features/vcs/model.ts +++ b/src/features/vcs/model.ts @@ -78,17 +78,6 @@ export function statusDecorations(status: readonly FileStatus[], propagate = tru return new Map(entries.map(([p, d]) => [p, d])); } -/** Short letter for change lists ("M", "A", "D", "R", "U", "C"). */ -export const KIND_LETTER: Record = { - modified: "M", - renamed: "R", - added: "A", - deleted: "D", - untracked: "U", - ignored: "I", - conflicted: "C", -}; - export function relTo(root: string, path: string): string { return path.startsWith(root + "/") ? path.slice(root.length + 1) : path; } diff --git a/src/platform/colorScheme.ts b/src/platform/colorScheme.ts index 8ba950c8..3da62ea9 100644 --- a/src/platform/colorScheme.ts +++ b/src/platform/colorScheme.ts @@ -268,11 +268,6 @@ export function themeScheme( return root.dataset.contrast === "high" || root.dataset.theme === "dark-hc" ? "dark-hc" : "dark"; } -/** Base value of an attribute variable in a scheme. */ -export function schemeValue(id: SchemeId, cssVar: string): string | undefined { - return schemeTokens(id).get(cssVar); -} - /** An explicit Bold / regular attribute: the editor's configured bold or main weight. */ export function boldWeight(bold: boolean): string { return bold ? "var(--fw-code-bold, 700)" : "var(--fw-code, 400)"; diff --git a/src/platform/i18n.ts b/src/platform/i18n.ts index 8e477b29..d4e6b6ff 100644 --- a/src/platform/i18n.ts +++ b/src/platform/i18n.ts @@ -36,8 +36,6 @@ export const DEFAULT_LOCALE = "en"; export const SUPPORTED_LOCALES = ["en", "zh"] as const; export type Locale = (typeof SUPPORTED_LOCALES)[number]; -const LOCALE_NAMES: Record = { en: "English", zh: "中文" }; - const loaders = import.meta.glob(["./locales/*.json", "!./locales/en.json"], { import: "default" }); const textLoaders = import.meta.glob("./locales/text/*.json", { import: "default" }); @@ -65,10 +63,6 @@ export function resolveLocale(input: string | null | undefined): Locale { return (SUPPORTED_LOCALES as readonly string[]).includes(base) ? (base as Locale) : DEFAULT_LOCALE; } -export function localeDisplayName(locale: Locale): string { - return LOCALE_NAMES[locale]; -} - let fallbackCache: Catalog | null = null; function fallback(): Catalog { diff --git a/src/platform/languageSettings.ts b/src/platform/languageSettings.ts index 08ceaab4..d0729e63 100644 --- a/src/platform/languageSettings.ts +++ b/src/platform/languageSettings.ts @@ -157,14 +157,6 @@ export function validateProjectStructure(raw: unknown): ProjectStructureValid { }; } -/** The "Exclude files" name patterns (`*.log;tmp*`). */ -export function excludeFilePatterns(excludeFiles: string): string[] { - return excludeFiles - .split(";") - .map((p) => p.trim()) - .filter(Boolean); -} - /** Root kinds, as in IDEA's Project Structure (`ide-workspace::roots::RootKind`). */ export type FolderRole = "source" | "test" | "resources" | "testResources" | "excluded"; @@ -283,8 +275,6 @@ export function restoreDetected(ps: ProjectStructureValid, detected: readonly Ro return { ...ps, unmarked: ps.unmarked.filter((p) => !detected.some((d) => d.path === folderKey(p))) }; } -export const PROJECT_STRUCTURE_KEY = (role: FolderRole) => `projectStructure.${ROLE_KEYS[role]}`; - /** Settings keys of `ProjectStructureValid`, in a stable order. */ export const PROJECT_STRUCTURE_KEYS = [ "sourceRoots", diff --git a/src/platform/locales/text/zh.json b/src/platform/locales/text/zh.json index 633ca3fd..1569f5ac 100644 --- a/src/platform/locales/text/zh.json +++ b/src/platform/locales/text/zh.json @@ -2073,7 +2073,6 @@ "The clipboard does not contain a patch": "剪贴板中没有补丁", "The patch file is empty": "补丁文件为空", "The project is not a Git repository.": "该项目不是 Git 仓库。", - "The project is not under Git version control": "项目不受 Git 版本控制", "The project path is always shown in the status bar navigation bar.": "项目路径始终显示在状态栏导航栏中。", "The remote contains commits that are not in your branch. Update the branch, then push again.": "远程包含您的分支中没有的提交。请更新分支,然后再次推送。", "The report covers no files": "报告未覆盖任何文件", diff --git a/src/platform/virtualDocs.ts b/src/platform/virtualDocs.ts index 1baa20af..8a31ef0e 100644 --- a/src/platform/virtualDocs.ts +++ b/src/platform/virtualDocs.ts @@ -64,8 +64,3 @@ export function virtualDocument(uri: string): Promise { } return p; } - -/** Test hook. */ -export function _clearVirtualDocuments() { - cache.clear(); -} diff --git a/src/ui/AppLogo.module.css b/src/ui/AppLogo.module.css deleted file mode 100644 index 4f3c1676..00000000 --- a/src/ui/AppLogo.module.css +++ /dev/null @@ -1,6 +0,0 @@ -.logo { - flex: none; - display: block; - -webkit-user-drag: none; - user-select: none; -} diff --git a/src/ui/AppLogo.tsx b/src/ui/AppLogo.tsx deleted file mode 100644 index 1e884c89..00000000 --- a/src/ui/AppLogo.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import clsx from "clsx"; -import markUrl from "../../src-tauri/icons/source/openidea-mark.svg"; -import styles from "./AppLogo.module.css"; - -export interface AppLogoProps { - /** Rendered edge length in CSS pixels. */ - size?: number; - /** Accessible name; omit when the product name is shown next to the logo. */ - label?: string; - className?: string; -} - -/** The product mark (full-bleed tile variant, legible down to 16px). */ -export function AppLogo({ size = 32, label, className }: AppLogoProps) { - return ( - {label - ); -} diff --git a/src/ui/Menu.tsx b/src/ui/Menu.tsx index 7647b8eb..dfa141ca 100644 --- a/src/ui/Menu.tsx +++ b/src/ui/Menu.tsx @@ -10,7 +10,6 @@ import { useRef, useState, type KeyboardEvent as ReactKeyboardEvent, - type MouseEvent as ReactMouseEvent, } from "react"; import clsx from "clsx"; import { create } from "zustand"; @@ -325,17 +324,6 @@ export function hideContextMenu() { useContextMenuStore.setState({ menu: null }); } -/** Returns an `onContextMenu` handler showing `items` (or the result of `items(e)`). */ -export function useContextMenu(items: MenuItem[] | ((e: ReactMouseEvent) => MenuItem[] | null)) { - return (e: ReactMouseEvent) => { - const list = typeof items === "function" ? items(e) : items; - if (!list || !list.length) return; - e.preventDefault(); - e.stopPropagation(); - showContextMenu(e, list); - }; -} - /** Renders the active context menu; mount once (the workbench does). */ export function ContextMenuHost() { const menu = useContextMenuStore((s) => s.menu); diff --git a/src/ui/Splitter.tsx b/src/ui/Splitter.tsx index c74530e7..8c71a47f 100644 --- a/src/ui/Splitter.tsx +++ b/src/ui/Splitter.tsx @@ -6,9 +6,6 @@ import { Group, Panel, Separator, type GroupProps, type PanelProps, type Separat import clsx from "clsx"; import styles from "./Splitter.module.css"; -export type { PanelImperativeHandle, Layout } from "react-resizable-panels"; -export { usePanelRef, useGroupRef } from "react-resizable-panels"; - export function SplitGroup({ className, ...rest }: GroupProps) { return ; } diff --git a/src/ui/Tooltip.tsx b/src/ui/Tooltip.tsx index cbf9c8f8..893e2b54 100644 --- a/src/ui/Tooltip.tsx +++ b/src/ui/Tooltip.tsx @@ -3,7 +3,7 @@ * `data-tooltip-shortcut`) gets one, shown by the single `` after * 600ms of hover. Hidden on scroll, key press, pointer down or leave. */ -import { cloneElement, isValidElement, useEffect, useRef, useState, type ReactElement } from "react"; +import { useEffect, useRef, useState } from "react"; import { createPortal } from "react-dom"; import { computePosition, flip, offset, shift } from "@floating-ui/react-dom"; import styles from "./Tooltip.module.css"; @@ -19,18 +19,6 @@ export function tooltipAttrs(text: string | undefined, shortcut?: string): Recor return attrs; } -export interface TooltipProps { - content: string; - shortcut?: string; - children: ReactElement; -} - -/** Attaches a tooltip to its single child element. */ -export function Tooltip({ content, shortcut, children }: TooltipProps) { - if (!isValidElement(children)) return children; - return cloneElement(children, tooltipAttrs(content, shortcut)); -} - interface Shown { text: string; shortcut?: string; diff --git a/src/ui/index.ts b/src/ui/index.ts index 05accd68..51362d81 100644 --- a/src/ui/index.ts +++ b/src/ui/index.ts @@ -13,9 +13,7 @@ export { registerDropTarget, setDragRequiresAlt, startPointerDrag, - type DragData, type DragSession, - type DropTarget, } from "./pointerDrag"; export * from "./Tree"; export * from "./List"; @@ -26,11 +24,10 @@ export * from "./Splitter"; export * from "./SourcePreview"; export * from "./Feedback"; export * from "./HighlightedText"; -export { fuzzyMatch, indexRuns, wordMatch } from "./match"; +export { fuzzyMatch, wordMatch } from "./match"; export { badgeKind } from "./symbolKind"; -export { acquirePopup, isPopupOpen, openLayer } from "./popupState"; +export { acquirePopup, isPopupOpen } from "./popupState"; export * from "./BarButton"; -export * from "./AppLogo"; export { lazyComponent, prefetchLazyComponents } from "./lazy"; export { T } from "./T"; export { selectableText, copyMenuFor, copyText } from "./selectableText"; diff --git a/tsconfig.node.json b/tsconfig.node.json index 31cef4be..6858004e 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -6,5 +6,5 @@ "allowSyntheticDefaultImports": true, "types": ["node"] }, - "include": ["vite.config.ts"] + "include": ["vite.config.ts", "knip.ts"] }