Compare commits

..

No commits in common. "b75779f9aab330e2cadeab1c6c49a0e1afc081bd" and "57efab97f875381f9d3c07f5511599a71afa1405" have entirely different histories.

13 changed files with 149 additions and 214 deletions

View file

@ -8,7 +8,6 @@
- **Never create tests, docs, or GitHub workflows** - **Never create tests, docs, or GitHub workflows**
- **Never add comments** — code should be self-explanatory; no inline comments, no block comments - **Never add comments** — code should be self-explanatory; no inline comments, no block comments
- **Move helper functions** out of component files into `src/utils/` - **Move helper functions** out of component files into `src/utils/`
- **Keep commit messages short** — one line, no bullet points, no essay
## What Gerbil Is ## What Gerbil Is

2
.npmrc Normal file
View file

@ -0,0 +1,2 @@
# Disable pnpm supply-chain security checks
pnpm.minimumReleaseAge=0

View file

@ -1,6 +1,6 @@
{ {
"name": "gerbil", "name": "gerbil",
"version": "1.25.1", "version": "1.25.0",
"description": "Run Large Language Models locally", "description": "Run Large Language Models locally",
"keywords": [ "keywords": [
"ai", "ai",
@ -38,7 +38,7 @@
"systeminformation": "^5.31.7", "systeminformation": "^5.31.7",
"winston": "^3.19.0", "winston": "^3.19.0",
"winston-daily-rotate-file": "^5.0.0", "winston-daily-rotate-file": "^5.0.0",
"yauzl": "^3.3.2" "yauzl": "^3.3.1"
}, },
"devDependencies": { "devDependencies": {
"@codemirror/commands": "^6.10.3", "@codemirror/commands": "^6.10.3",
@ -76,7 +76,7 @@
"remark-gfm": "^4.0.1", "remark-gfm": "^4.0.1",
"rollup-plugin-visualizer": "^7.0.1", "rollup-plugin-visualizer": "^7.0.1",
"typescript": "^6.0.3", "typescript": "^6.0.3",
"vite": "^8.0.15", "vite": "^8.0.14",
"zustand": "^5.0.14" "zustand": "^5.0.14"
}, },
"engines": { "engines": {

215
pnpm-lock.yaml generated
View file

@ -30,8 +30,8 @@ importers:
specifier: ^5.0.0 specifier: ^5.0.0
version: 5.0.0(winston@3.19.0) version: 5.0.0(winston@3.19.0)
yauzl: yauzl:
specifier: ^3.3.2 specifier: ^3.3.1
version: 3.3.2 version: 3.3.1
devDependencies: devDependencies:
'@codemirror/commands': '@codemirror/commands':
specifier: ^6.10.3 specifier: ^6.10.3
@ -80,7 +80,7 @@ importers:
version: 4.25.10(@babel/runtime@7.29.7)(@codemirror/autocomplete@6.20.2)(@codemirror/language@6.12.3)(@codemirror/lint@6.9.6)(@codemirror/search@6.7.0)(@codemirror/state@6.6.0)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.43.0)(codemirror@6.0.2)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) version: 4.25.10(@babel/runtime@7.29.7)(@codemirror/autocomplete@6.20.2)(@codemirror/language@6.12.3)(@codemirror/lint@6.9.6)(@codemirror/search@6.7.0)(@codemirror/state@6.6.0)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.43.0)(codemirror@6.0.2)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
'@vitejs/plugin-react': '@vitejs/plugin-react':
specifier: ^6.0.2 specifier: ^6.0.2
version: 6.0.2(vite@8.0.15(@types/node@25.9.1)(jiti@2.7.0)) version: 6.0.2(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0))
cross-env: cross-env:
specifier: ^10.1.0 specifier: ^10.1.0
version: 10.1.0 version: 10.1.0
@ -92,7 +92,7 @@ importers:
version: 26.8.1(electron-builder-squirrel-windows@26.8.1) version: 26.8.1(electron-builder-squirrel-windows@26.8.1)
electron-vite: electron-vite:
specifier: ^5.0.0 specifier: ^5.0.0
version: 5.0.0(vite@8.0.15(@types/node@25.9.1)(jiti@2.7.0)) version: 5.0.0(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0))
jiti: jiti:
specifier: ^2.7.0 specifier: ^2.7.0
version: 2.7.0 version: 2.7.0
@ -134,13 +134,13 @@ importers:
version: 4.0.1 version: 4.0.1
rollup-plugin-visualizer: rollup-plugin-visualizer:
specifier: ^7.0.1 specifier: ^7.0.1
version: 7.0.1(rolldown@1.0.3) version: 7.0.1(rolldown@1.0.2)
typescript: typescript:
specifier: ^6.0.3 specifier: ^6.0.3
version: 6.0.3 version: 6.0.3
vite: vite:
specifier: ^8.0.15 specifier: ^8.0.14
version: 8.0.15(@types/node@25.9.1)(jiti@2.7.0) version: 8.0.14(@types/node@25.9.1)(jiti@2.7.0)
zustand: zustand:
specifier: ^5.0.14 specifier: ^5.0.14
version: 5.0.14(@types/react@19.2.15)(react@19.2.6) version: 5.0.14(@types/react@19.2.15)(react@19.2.6)
@ -567,8 +567,8 @@ packages:
'@emnapi/core': ^1.7.1 '@emnapi/core': ^1.7.1
'@emnapi/runtime': ^1.7.1 '@emnapi/runtime': ^1.7.1
'@oxc-project/types@0.133.0': '@oxc-project/types@0.132.0':
resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==} resolution: {integrity: sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ==}
'@oxfmt/binding-android-arm-eabi@0.52.0': '@oxfmt/binding-android-arm-eabi@0.52.0':
resolution: {integrity: sha512-17EMSJnQ9g+upVHrAUYDMfH5lvRKQ9Nvg8WtEoH72oDr1VpWz+7/o3tD97U1EToen2YAQ/68JmtDYkQUi20dfQ==} resolution: {integrity: sha512-17EMSJnQ9g+upVHrAUYDMfH5lvRKQ9Nvg8WtEoH72oDr1VpWz+7/o3tD97U1EToen2YAQ/68JmtDYkQUi20dfQ==}
@ -844,97 +844,97 @@ packages:
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@rolldown/binding-android-arm64@1.0.3': '@rolldown/binding-android-arm64@1.0.2':
resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==} resolution: {integrity: sha512-ZS4D1JPGn/MYQN/SYDWftIE/nVsM8j/AFOYEzAoOE2O3NktQOZru+/vYXGbR/qtdLdIfGCP0lcoJiYVzsEz+iQ==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64] cpu: [arm64]
os: [android] os: [android]
'@rolldown/binding-darwin-arm64@1.0.3': '@rolldown/binding-darwin-arm64@1.0.2':
resolution: {integrity: sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==} resolution: {integrity: sha512-vdFA9+C/rekyGce7WqHs/xoT0ioZEWaOFyZLIV1mEeNFaFDUQrPIo8Vs2GvJ6eetb3rzDUtUBgzto3ExpXJB3w==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
'@rolldown/binding-darwin-x64@1.0.3': '@rolldown/binding-darwin-x64@1.0.2':
resolution: {integrity: sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==} resolution: {integrity: sha512-BewSOwTHazv77DTYiAZXSqqKZ4KP/KonFisDMVU7PImxoWfB2aepnPhd2E4SWz3zDzYgDNbs6jBmTdgNnF02GA==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
'@rolldown/binding-freebsd-x64@1.0.3': '@rolldown/binding-freebsd-x64@1.0.2':
resolution: {integrity: sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==} resolution: {integrity: sha512-m41o7M0YWtUdqk61Tb+jnKb2rN++iRdIASlExkUoKfIAH30DOHCB8fVLzSUpbWHHU8esmEioY62PxzexE8MBuA==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64] cpu: [x64]
os: [freebsd] os: [freebsd]
'@rolldown/binding-linux-arm-gnueabihf@1.0.3': '@rolldown/binding-linux-arm-gnueabihf@1.0.2':
resolution: {integrity: sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==} resolution: {integrity: sha512-jcojB9H7W/jS29pMKWAK1N+fU99vXodHDTatS3b3y/XSOCiHo0kkA74pL3jJmkoQtYpOCxDvaKs1fo2Ij/1X5w==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
'@rolldown/binding-linux-arm64-gnu@1.0.3': '@rolldown/binding-linux-arm64-gnu@1.0.2':
resolution: {integrity: sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==} resolution: {integrity: sha512-1jn6qDU5iiOgFgygDzKUuKP0maTi0/f1+sBLgvij/76C77Nm3ts6ufz9Bjg5q5dduxiUIxtq86JIoBvo1xQ4Ig==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc] libc: [glibc]
'@rolldown/binding-linux-arm64-musl@1.0.3': '@rolldown/binding-linux-arm64-musl@1.0.2':
resolution: {integrity: sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==} resolution: {integrity: sha512-QVLO/czFMdoMFSqlX3bcswcJNm/23r+qoa/jgtmFc/qEp6/jXmIkDjF/XIo8dPfGaiwy1xfQn8o77L79GeXFgw==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl] libc: [musl]
'@rolldown/binding-linux-ppc64-gnu@1.0.3': '@rolldown/binding-linux-ppc64-gnu@1.0.2':
resolution: {integrity: sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==} resolution: {integrity: sha512-hgO5Abm0w5UL6FEa2iFnZqo2KlK7TQ5QhV5x09hujBf7t5KzHQ1VmfPuTpqRy/rNlSxua3eWH374xxiVrP+lcA==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64] cpu: [ppc64]
os: [linux] os: [linux]
libc: [glibc] libc: [glibc]
'@rolldown/binding-linux-s390x-gnu@1.0.3': '@rolldown/binding-linux-s390x-gnu@1.0.2':
resolution: {integrity: sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==} resolution: {integrity: sha512-fy8rXxuYEu602abC8MUNaPjYLIFzReOaEIEMKMUa0rFEUxNpVXhs15KSSQ4qlqSaM7B6rcj9rDZgADh/IGDzLQ==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x] cpu: [s390x]
os: [linux] os: [linux]
libc: [glibc] libc: [glibc]
'@rolldown/binding-linux-x64-gnu@1.0.3': '@rolldown/binding-linux-x64-gnu@1.0.2':
resolution: {integrity: sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==} resolution: {integrity: sha512-0+bOkiQ779+r1WpoHOWHqncvyySci0vKph+myNDYb+im6meJAzHQXay6oEgnkHuUGouM1LKTZwqKpBow6Kj7CQ==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc] libc: [glibc]
'@rolldown/binding-linux-x64-musl@1.0.3': '@rolldown/binding-linux-x64-musl@1.0.2':
resolution: {integrity: sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==} resolution: {integrity: sha512-mjSkrzZK5Qsl0a9d1JgILOiuZOSDTVdKENcSXBoqbzSrspLR/4/IRVDo5wd2GgZjNss/viBFJdeq+j7qH2nypw==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl] libc: [musl]
'@rolldown/binding-openharmony-arm64@1.0.3': '@rolldown/binding-openharmony-arm64@1.0.2':
resolution: {integrity: sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==} resolution: {integrity: sha512-1v5vHasdfQAZoEHakBV72LIFAC9JjnymsiKxp+GEr/ma3+NJCPSaYK+qavInOovJkgwFrs7GccX2d6IgDA3Z5w==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64] cpu: [arm64]
os: [openharmony] os: [openharmony]
'@rolldown/binding-wasm32-wasi@1.0.3': '@rolldown/binding-wasm32-wasi@1.0.2':
resolution: {integrity: sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==} resolution: {integrity: sha512-mb1VobWn6NheziTk5/WEaR6AKVbrwT5sOi6C7zk3gy/pD1qtJfU1j4PgTo2NJnOtbL9Dl3Aeei8w9jJ7qC2jZQ==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
cpu: [wasm32] cpu: [wasm32]
'@rolldown/binding-win32-arm64-msvc@1.0.3': '@rolldown/binding-win32-arm64-msvc@1.0.2':
resolution: {integrity: sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==} resolution: {integrity: sha512-SqKonF56vA/L2yHwHYcEp2P34URpOZ7d1fS635cTkpDnUtEGdUbhI6NzsPdqeSWvAAeGDrxjWjNmibDIdFf9/A==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
'@rolldown/binding-win32-x64-msvc@1.0.3': '@rolldown/binding-win32-x64-msvc@1.0.2':
resolution: {integrity: sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==} resolution: {integrity: sha512-v7qRI7gXLRINcOGXt+7YmAZ6iFuyZVMIoXAxhd8oP+DR9dLfL9GfNIx7PLMxmhZdvq8waUJBQiWN9EKNy+TRBQ==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
@ -1157,8 +1157,8 @@ packages:
base64-js@1.5.1: base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
baseline-browser-mapping@2.10.33: baseline-browser-mapping@2.10.32:
resolution: {integrity: sha512-bA6+tcSLpz2tIEdDXZPpPTIuxBcC4+w6SieaYyfigIa4h8GlFxbA17v22Vx3JUtuZQj9SgOsnbK+aTBzyDyEuw==} resolution: {integrity: sha512-wbPvpyjJPC0zdfdKXxqEL3Ea+bOMD/87X4lftiJkkaBiuG6ALQy1SLmEd7BSmVCuwCQsBrCamgBoLyfFDD1EPg==}
engines: {node: '>=6.0.0'} engines: {node: '>=6.0.0'}
hasBin: true hasBin: true
@ -1859,8 +1859,8 @@ packages:
js-tokens@4.0.0: js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
js-yaml@4.2.0: js-yaml@4.1.1:
resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==} resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
hasBin: true hasBin: true
jsesc@3.1.0: jsesc@3.1.0:
@ -2509,8 +2509,8 @@ packages:
resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==} resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==}
engines: {node: '>=8.0'} engines: {node: '>=8.0'}
rolldown@1.0.3: rolldown@1.0.2:
resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==} resolution: {integrity: sha512-oZx5zVDtVB44AW3eaifgDml1gWRDZGvjcfdxonE4swNPG98PrrXjaO/KrnUjzlMnztCCRVlUueA1kCXhARGk6g==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true hasBin: true
@ -2707,8 +2707,8 @@ packages:
tiny-typed-emitter@2.1.0: tiny-typed-emitter@2.1.0:
resolution: {integrity: sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==} resolution: {integrity: sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==}
tinyglobby@0.2.17: tinyglobby@0.2.16:
resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==}
engines: {node: '>=12.0.0'} engines: {node: '>=12.0.0'}
tinypool@2.1.0: tinypool@2.1.0:
@ -2742,8 +2742,8 @@ packages:
resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==}
engines: {node: '>=10'} engines: {node: '>=10'}
type-fest@5.7.0: type-fest@5.6.0:
resolution: {integrity: sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg==} resolution: {integrity: sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==}
engines: {node: '>=20'} engines: {node: '>=20'}
typescript@6.0.3: typescript@6.0.3:
@ -2843,8 +2843,8 @@ packages:
vfile@6.0.3: vfile@6.0.3:
resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
vite@8.0.15: vite@8.0.14:
resolution: {integrity: sha512-qpgllRxrLqwsMAGRdLhsEr9bepaOQk1rxH1xT2coBXLaEB/bfkqQj1j7RMxwMfnYrvO1ZnFMiwX+wBVgnsyn0g==} resolution: {integrity: sha512-s4BJJ+5y1pYL6Otw51FHhVJQhPnuRinKig64g/1+EUNaJsd3gCKdD31IPFvswUgW9/60QT9oFHbZHbQK5imcxw==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@ -2973,8 +2973,8 @@ packages:
yauzl@2.10.0: yauzl@2.10.0:
resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==}
yauzl@3.3.2: yauzl@3.3.1:
resolution: {integrity: sha512-Md9ankxxN23wncAN8s7+Tn3Co52zLUPMtnrLAbVCnfG5d2tKBFfmygYSgXlqFgXObtzIgqkx7aNgDBpso9+4qA==} resolution: {integrity: sha512-RNPCUkiE/ZgO4w8i9U5yDQVHaFDdnzaFANElRvpJteCspvmv2VqrRb9lvS6odVD+jqI/zDsxAHJVsafpcheVQQ==}
engines: {node: '>=12'} engines: {node: '>=12'}
yocto-queue@0.1.0: yocto-queue@0.1.0:
@ -3463,7 +3463,7 @@ snapshots:
react-dom: 19.2.6(react@19.2.6) react-dom: 19.2.6(react@19.2.6)
react-number-format: 5.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) react-number-format: 5.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
react-remove-scroll: 2.7.2(@types/react@19.2.15)(react@19.2.6) react-remove-scroll: 2.7.2(@types/react@19.2.15)(react@19.2.6)
type-fest: 5.7.0 type-fest: 5.6.0
transitivePeerDependencies: transitivePeerDependencies:
- '@types/react' - '@types/react'
@ -3480,7 +3480,7 @@ snapshots:
'@tybys/wasm-util': 0.10.2 '@tybys/wasm-util': 0.10.2
optional: true optional: true
'@oxc-project/types@0.133.0': {} '@oxc-project/types@0.132.0': {}
'@oxfmt/binding-android-arm-eabi@0.52.0': '@oxfmt/binding-android-arm-eabi@0.52.0':
optional: true optional: true
@ -3614,53 +3614,53 @@ snapshots:
'@oxlint/binding-win32-x64-msvc@1.67.0': '@oxlint/binding-win32-x64-msvc@1.67.0':
optional: true optional: true
'@rolldown/binding-android-arm64@1.0.3': '@rolldown/binding-android-arm64@1.0.2':
optional: true optional: true
'@rolldown/binding-darwin-arm64@1.0.3': '@rolldown/binding-darwin-arm64@1.0.2':
optional: true optional: true
'@rolldown/binding-darwin-x64@1.0.3': '@rolldown/binding-darwin-x64@1.0.2':
optional: true optional: true
'@rolldown/binding-freebsd-x64@1.0.3': '@rolldown/binding-freebsd-x64@1.0.2':
optional: true optional: true
'@rolldown/binding-linux-arm-gnueabihf@1.0.3': '@rolldown/binding-linux-arm-gnueabihf@1.0.2':
optional: true optional: true
'@rolldown/binding-linux-arm64-gnu@1.0.3': '@rolldown/binding-linux-arm64-gnu@1.0.2':
optional: true optional: true
'@rolldown/binding-linux-arm64-musl@1.0.3': '@rolldown/binding-linux-arm64-musl@1.0.2':
optional: true optional: true
'@rolldown/binding-linux-ppc64-gnu@1.0.3': '@rolldown/binding-linux-ppc64-gnu@1.0.2':
optional: true optional: true
'@rolldown/binding-linux-s390x-gnu@1.0.3': '@rolldown/binding-linux-s390x-gnu@1.0.2':
optional: true optional: true
'@rolldown/binding-linux-x64-gnu@1.0.3': '@rolldown/binding-linux-x64-gnu@1.0.2':
optional: true optional: true
'@rolldown/binding-linux-x64-musl@1.0.3': '@rolldown/binding-linux-x64-musl@1.0.2':
optional: true optional: true
'@rolldown/binding-openharmony-arm64@1.0.3': '@rolldown/binding-openharmony-arm64@1.0.2':
optional: true optional: true
'@rolldown/binding-wasm32-wasi@1.0.3': '@rolldown/binding-wasm32-wasi@1.0.2':
dependencies: dependencies:
'@emnapi/core': 1.10.0 '@emnapi/core': 1.10.0
'@emnapi/runtime': 1.10.0 '@emnapi/runtime': 1.10.0
'@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)
optional: true optional: true
'@rolldown/binding-win32-arm64-msvc@1.0.3': '@rolldown/binding-win32-arm64-msvc@1.0.2':
optional: true optional: true
'@rolldown/binding-win32-x64-msvc@1.0.3': '@rolldown/binding-win32-x64-msvc@1.0.2':
optional: true optional: true
'@rolldown/pluginutils@1.0.1': {} '@rolldown/pluginutils@1.0.1': {}
@ -3792,10 +3792,10 @@ snapshots:
'@ungap/structured-clone@1.3.1': {} '@ungap/structured-clone@1.3.1': {}
'@vitejs/plugin-react@6.0.2(vite@8.0.15(@types/node@25.9.1)(jiti@2.7.0))': '@vitejs/plugin-react@6.0.2(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0))':
dependencies: dependencies:
'@rolldown/pluginutils': 1.0.1 '@rolldown/pluginutils': 1.0.1
vite: 8.0.15(@types/node@25.9.1)(jiti@2.7.0) vite: 8.0.14(@types/node@25.9.1)(jiti@2.7.0)
'@xmldom/xmldom@0.8.13': {} '@xmldom/xmldom@0.8.13': {}
@ -3857,7 +3857,7 @@ snapshots:
hosted-git-info: 4.1.0 hosted-git-info: 4.1.0
isbinaryfile: 5.0.7 isbinaryfile: 5.0.7
jiti: 2.7.0 jiti: 2.7.0
js-yaml: 4.2.0 js-yaml: 4.1.1
json5: 2.2.3 json5: 2.2.3
lazy-val: 1.0.5 lazy-val: 1.0.5
minimatch: 10.2.5 minimatch: 10.2.5
@ -3896,7 +3896,7 @@ snapshots:
base64-js@1.5.1: {} base64-js@1.5.1: {}
baseline-browser-mapping@2.10.33: {} baseline-browser-mapping@2.10.32: {}
boolean@3.2.0: boolean@3.2.0:
optional: true optional: true
@ -3916,7 +3916,7 @@ snapshots:
browserslist@4.28.2: browserslist@4.28.2:
dependencies: dependencies:
baseline-browser-mapping: 2.10.33 baseline-browser-mapping: 2.10.32
caniuse-lite: 1.0.30001793 caniuse-lite: 1.0.30001793
electron-to-chromium: 1.5.364 electron-to-chromium: 1.5.364
node-releases: 2.0.46 node-releases: 2.0.46
@ -3951,7 +3951,7 @@ snapshots:
fs-extra: 10.1.0 fs-extra: 10.1.0
http-proxy-agent: 7.0.2 http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.6 https-proxy-agent: 7.0.6
js-yaml: 4.2.0 js-yaml: 4.1.1
sanitize-filename: 1.6.4 sanitize-filename: 1.6.4
source-map-support: 0.5.21 source-map-support: 0.5.21
stat-mode: 1.0.0 stat-mode: 1.0.0
@ -4169,7 +4169,7 @@ snapshots:
builder-util: 26.8.1 builder-util: 26.8.1
fs-extra: 10.1.0 fs-extra: 10.1.0
iconv-lite: 0.6.3 iconv-lite: 0.6.3
js-yaml: 4.2.0 js-yaml: 4.1.1
optionalDependencies: optionalDependencies:
dmg-license: 1.0.11 dmg-license: 1.0.11
transitivePeerDependencies: transitivePeerDependencies:
@ -4248,7 +4248,7 @@ snapshots:
dependencies: dependencies:
builder-util-runtime: 9.5.1 builder-util-runtime: 9.5.1
fs-extra: 10.1.0 fs-extra: 10.1.0
js-yaml: 4.2.0 js-yaml: 4.1.1
lazy-val: 1.0.5 lazy-val: 1.0.5
lodash.escaperegexp: 4.1.2 lodash.escaperegexp: 4.1.2
lodash.isequal: 4.5.0 lodash.isequal: 4.5.0
@ -4257,7 +4257,7 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
electron-vite@5.0.0(vite@8.0.15(@types/node@25.9.1)(jiti@2.7.0)): electron-vite@5.0.0(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0)):
dependencies: dependencies:
'@babel/core': 7.29.7 '@babel/core': 7.29.7
'@babel/plugin-transform-arrow-functions': 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-arrow-functions': 7.29.7(@babel/core@7.29.7)
@ -4265,7 +4265,7 @@ snapshots:
esbuild: 0.25.12 esbuild: 0.25.12
magic-string: 0.30.21 magic-string: 0.30.21
picocolors: 1.1.1 picocolors: 1.1.1
vite: 8.0.15(@types/node@25.9.1)(jiti@2.7.0) vite: 8.0.14(@types/node@25.9.1)(jiti@2.7.0)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -4749,7 +4749,7 @@ snapshots:
js-tokens@4.0.0: {} js-tokens@4.0.0: {}
js-yaml@4.2.0: js-yaml@4.1.1:
dependencies: dependencies:
argparse: 2.0.1 argparse: 2.0.1
@ -5291,7 +5291,7 @@ snapshots:
proc-log: 6.1.0 proc-log: 6.1.0
semver: 7.7.4 semver: 7.7.4
tar: 7.5.15 tar: 7.5.15
tinyglobby: 0.2.17 tinyglobby: 0.2.16
undici: 6.26.0 undici: 6.26.0
which: 6.0.1 which: 6.0.1
@ -5628,35 +5628,35 @@ snapshots:
sprintf-js: 1.1.3 sprintf-js: 1.1.3
optional: true optional: true
rolldown@1.0.3: rolldown@1.0.2:
dependencies: dependencies:
'@oxc-project/types': 0.133.0 '@oxc-project/types': 0.132.0
'@rolldown/pluginutils': 1.0.1 '@rolldown/pluginutils': 1.0.1
optionalDependencies: optionalDependencies:
'@rolldown/binding-android-arm64': 1.0.3 '@rolldown/binding-android-arm64': 1.0.2
'@rolldown/binding-darwin-arm64': 1.0.3 '@rolldown/binding-darwin-arm64': 1.0.2
'@rolldown/binding-darwin-x64': 1.0.3 '@rolldown/binding-darwin-x64': 1.0.2
'@rolldown/binding-freebsd-x64': 1.0.3 '@rolldown/binding-freebsd-x64': 1.0.2
'@rolldown/binding-linux-arm-gnueabihf': 1.0.3 '@rolldown/binding-linux-arm-gnueabihf': 1.0.2
'@rolldown/binding-linux-arm64-gnu': 1.0.3 '@rolldown/binding-linux-arm64-gnu': 1.0.2
'@rolldown/binding-linux-arm64-musl': 1.0.3 '@rolldown/binding-linux-arm64-musl': 1.0.2
'@rolldown/binding-linux-ppc64-gnu': 1.0.3 '@rolldown/binding-linux-ppc64-gnu': 1.0.2
'@rolldown/binding-linux-s390x-gnu': 1.0.3 '@rolldown/binding-linux-s390x-gnu': 1.0.2
'@rolldown/binding-linux-x64-gnu': 1.0.3 '@rolldown/binding-linux-x64-gnu': 1.0.2
'@rolldown/binding-linux-x64-musl': 1.0.3 '@rolldown/binding-linux-x64-musl': 1.0.2
'@rolldown/binding-openharmony-arm64': 1.0.3 '@rolldown/binding-openharmony-arm64': 1.0.2
'@rolldown/binding-wasm32-wasi': 1.0.3 '@rolldown/binding-wasm32-wasi': 1.0.2
'@rolldown/binding-win32-arm64-msvc': 1.0.3 '@rolldown/binding-win32-arm64-msvc': 1.0.2
'@rolldown/binding-win32-x64-msvc': 1.0.3 '@rolldown/binding-win32-x64-msvc': 1.0.2
rollup-plugin-visualizer@7.0.1(rolldown@1.0.3): rollup-plugin-visualizer@7.0.1(rolldown@1.0.2):
dependencies: dependencies:
open: 11.0.0 open: 11.0.0
picomatch: 4.0.4 picomatch: 4.0.4
source-map: 0.7.6 source-map: 0.7.6
yargs: 18.0.0 yargs: 18.0.0
optionalDependencies: optionalDependencies:
rolldown: 1.0.3 rolldown: 1.0.2
run-applescript@7.1.0: {} run-applescript@7.1.0: {}
@ -5817,7 +5817,7 @@ snapshots:
tiny-typed-emitter@2.1.0: {} tiny-typed-emitter@2.1.0: {}
tinyglobby@0.2.17: tinyglobby@0.2.16:
dependencies: dependencies:
fdir: 6.5.0(picomatch@4.0.4) fdir: 6.5.0(picomatch@4.0.4)
picomatch: 4.0.4 picomatch: 4.0.4
@ -5845,7 +5845,7 @@ snapshots:
type-fest@0.13.1: type-fest@0.13.1:
optional: true optional: true
type-fest@5.7.0: type-fest@5.6.0:
dependencies: dependencies:
tagged-tag: 1.0.0 tagged-tag: 1.0.0
@ -5950,13 +5950,13 @@ snapshots:
'@types/unist': 3.0.3 '@types/unist': 3.0.3
vfile-message: 4.0.3 vfile-message: 4.0.3
vite@8.0.15(@types/node@25.9.1)(jiti@2.7.0): vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0):
dependencies: dependencies:
lightningcss: 1.32.0 lightningcss: 1.32.0
picomatch: 4.0.4 picomatch: 4.0.4
postcss: 8.5.15 postcss: 8.5.15
rolldown: 1.0.3 rolldown: 1.0.2
tinyglobby: 0.2.17 tinyglobby: 0.2.16
optionalDependencies: optionalDependencies:
'@types/node': 25.9.1 '@types/node': 25.9.1
fsevents: 2.3.3 fsevents: 2.3.3
@ -6063,8 +6063,9 @@ snapshots:
buffer-crc32: 0.2.13 buffer-crc32: 0.2.13
fd-slicer: 1.1.0 fd-slicer: 1.1.0
yauzl@3.3.2: yauzl@3.3.1:
dependencies: dependencies:
buffer-crc32: 0.2.13
pend: 1.2.0 pend: 1.2.0
yocto-queue@0.1.0: {} yocto-queue@0.1.0: {}

View file

@ -3,7 +3,8 @@ allowBuilds:
electron-winstaller: true electron-winstaller: true
esbuild: true esbuild: true
minimumReleaseAge: 0 minimumReleaseAgeExclude:
- systeminformation@5.31.7
overrides: overrides:
'@codemirror/view': '^6.43.0' '@codemirror/view': '^6.43.0'

View file

@ -76,7 +76,7 @@ export const DownloadCard = ({
); );
} }
if (backend.hasUpdate && !backend.isLocal && onUpdate) { if (backend.hasUpdate && onUpdate) {
buttons.push( buttons.push(
<Button <Button
key="update" key="update"
@ -99,7 +99,7 @@ export const DownloadCard = ({
); );
} }
if (hasVersionMismatch && !backend.isLocal && onRedownload) { if (hasVersionMismatch && onRedownload) {
buttons.push( buttons.push(
<Button <Button
key="redownload" key="redownload"
@ -177,11 +177,6 @@ export const DownloadCard = ({
Update Available Update Available
</Badge> </Badge>
)} )}
{backend.isLocal && (
<Badge variant="light" color="violet" size="sm">
Local
</Badge>
)}
{isWindowsROCmBuild(backend.name) && ( {isWindowsROCmBuild(backend.name) && (
<Badge variant="light" color="yellow" size="sm"> <Badge variant="light" color="yellow" size="sm">
Experimental Experimental

View file

@ -70,30 +70,20 @@ export const BackendsTab = () => {
availableDownloads.forEach((download) => { availableDownloads.forEach((download) => {
const downloadBaseName = stripAssetExtensions(download.name); const downloadBaseName = stripAssetExtensions(download.name);
const matchingBackends = installedBackends.filter((b) => { const installedBackend = installedBackends.find((b) => {
const displayName = getDisplayNameFromPath(b); const displayName = getDisplayNameFromPath(b);
return displayName === downloadBaseName; return displayName === downloadBaseName;
}); });
if (matchingBackends.length > 0) {
const downloadVersion = download.version ?? 'unknown';
const hasMultipleVersions = new Set(matchingBackends.map((b) => b.version)).size > 1;
matchingBackends.forEach((installedBackend) => {
processedInstalled.add(installedBackend.path);
const isCurrent = Boolean( const isCurrent = Boolean(
currentBackend && currentBackend.path === installedBackend.path, installedBackend && currentBackend && currentBackend.path === installedBackend.path,
); );
const isLocal = if (installedBackend) {
installedBackend.source === 'local' || processedInstalled.add(installedBackend.path);
(hasMultipleVersions &&
installedBackend.version !== downloadVersion &&
installedBackend.source !== 'local');
const hasUpdate = const hasUpdate =
!isLocal && compareVersions(downloadVersion, installedBackend.version) > 0; compareVersions(download.version ?? 'unknown', installedBackend.version) > 0;
backends.push({ backends.push({
actualVersion: installedBackend.actualVersion, actualVersion: installedBackend.actualVersion,
@ -102,13 +92,11 @@ export const BackendsTab = () => {
installedPath: installedBackend.path, installedPath: installedBackend.path,
isCurrent, isCurrent,
isInstalled: true, isInstalled: true,
isLocal,
name: download.name, name: download.name,
newerVersion: hasUpdate ? download.version : undefined, newerVersion: hasUpdate ? download.version : undefined,
size: undefined, size: undefined,
version: installedBackend.version, version: installedBackend.version,
}); });
});
} else { } else {
backends.push({ backends.push({
downloadUrl: download.url, downloadUrl: download.url,
@ -131,7 +119,6 @@ export const BackendsTab = () => {
installedPath: installed.path, installedPath: installed.path,
isCurrent, isCurrent,
isInstalled: true, isInstalled: true,
isLocal: installed.source === 'local',
name: displayName, name: displayName,
size: undefined, size: undefined,
version: installed.version, version: installed.version,

View file

@ -48,11 +48,6 @@ export const useUpdateChecker = () => {
return; return;
} }
if (currentBackend.source === 'local') {
setIsChecking(false);
return;
}
const availableDownloads: DownloadItem[] = [...releases]; const availableDownloads: DownloadItem[] = [...releases];
if (rocmDownload) { if (rocmDownload) {
availableDownloads.push(rocmDownload); availableDownloads.push(rocmDownload);
@ -69,18 +64,6 @@ export const useUpdateChecker = () => {
const hasUpdate = compareVersions(matchingDownload.version, currentBackend.version) > 0; const hasUpdate = compareVersions(matchingDownload.version, currentBackend.version) > 0;
if (hasUpdate) { if (hasUpdate) {
const installedBackends = await window.electronAPI.kobold.getInstalledBackends();
const sameNameBackends = installedBackends.filter(
(b) => getDisplayNameFromPath(b) === currentDisplayName,
);
const hasMultipleVersions = new Set(sameNameBackends.map((b) => b.version)).size > 1;
const looksLocal =
hasMultipleVersions && currentBackend.version !== matchingDownload.version;
if (!looksLocal) {
const isUpdateDismissed = dismissedUpdates.some( const isUpdateDismissed = dismissedUpdates.some(
(dismissedUpdate) => (dismissedUpdate) =>
dismissedUpdate.currentBackendPath === currentBackend.path && dismissedUpdate.currentBackendPath === currentBackend.path &&
@ -96,7 +79,6 @@ export const useUpdateChecker = () => {
} }
} }
} }
}
setIsChecking(false); setIsChecking(false);
}, [dismissedUpdates, releases, loadingRemote]); }, [dismissedUpdates, releases, loadingRemote]);

View file

@ -39,7 +39,6 @@ interface AppConfig {
notepad?: SavedNotepadState; notepad?: SavedNotepadState;
enableSystemTray?: boolean; enableSystemTray?: boolean;
startMinimizedToTray?: boolean; startMinimizedToTray?: boolean;
localBackendPaths?: string[];
} }
let config: AppConfig = {}; let config: AppConfig = {};

View file

@ -8,13 +8,7 @@ import { pathExists } from '@/utils/node/fs';
import { logError } from '@/utils/node/logging'; import { logError } from '@/utils/node/logging';
import { getLauncherPath } from '@/utils/node/path'; import { getLauncherPath } from '@/utils/node/path';
import { import { getCurrentKoboldBinary, getInstallDir, setCurrentKoboldBinary } from '../config';
get as getAppConfig,
getCurrentKoboldBinary,
getInstallDir,
set as setAppConfig,
setCurrentKoboldBinary,
} from '../config';
import { sendToRenderer } from '../window'; import { sendToRenderer } from '../window';
const backendVersionCache = new Map<string, { version: string; actualVersion?: string } | null>(); const backendVersionCache = new Map<string, { version: string; actualVersion?: string } | null>();
@ -63,14 +57,11 @@ export async function getInstalledBackends() {
return null; return null;
} }
const localPaths = getAppConfig('localBackendPaths') ?? [];
return { return {
actualVersion: versionInfo.actualVersion, actualVersion: versionInfo.actualVersion,
filename: launcher.filename, filename: launcher.filename,
path: launcher.path, path: launcher.path,
size: launcher.size, size: launcher.size,
source: localPaths.includes(launcher.path) ? ('local' as const) : undefined,
version: versionInfo.version, version: versionInfo.version,
} as InstalledBackend; } as InstalledBackend;
} catch (error) { } catch (error) {
@ -159,15 +150,6 @@ export async function deleteRelease(binaryPath: string) {
await rm(releaseDir, { force: true, recursive: true }); await rm(releaseDir, { force: true, recursive: true });
clearBackendVersionCache(binaryPath); clearBackendVersionCache(binaryPath);
const localPaths = getAppConfig('localBackendPaths') ?? [];
if (localPaths.includes(binaryPath)) {
await setAppConfig(
'localBackendPaths',
localPaths.filter((p: string) => p !== binaryPath),
);
}
sendToRenderer('versions-updated'); sendToRenderer('versions-updated');
return { success: true }; return { success: true };

View file

@ -12,13 +12,7 @@ import { logError } from '@/utils/node/logging';
import { getLauncherPath } from '@/utils/node/path'; import { getLauncherPath } from '@/utils/node/path';
import { stripAssetExtensions } from '@/utils/version'; import { stripAssetExtensions } from '@/utils/version';
import { import { getCurrentKoboldBinary, getInstallDir, setCurrentKoboldBinary } from '../config';
get as getAppConfig,
getCurrentKoboldBinary,
getInstallDir,
set as setAppConfig,
setCurrentKoboldBinary,
} from '../config';
import { getMainWindow, sendToRenderer } from '../window'; import { getMainWindow, sendToRenderer } from '../window';
import { clearBackendVersionCache, getVersionFromBinary } from './backend'; import { clearBackendVersionCache, getVersionFromBinary } from './backend';
import { isKoboldRunning } from './launcher'; import { isKoboldRunning } from './launcher';
@ -272,17 +266,12 @@ export async function importLocalBackend() {
await copyFile(selectedPath, packedFilePath); await copyFile(selectedPath, packedFilePath);
const launcherPath = await installBackend({ await installBackend({
packedFilePath, packedFilePath,
skipUnpackError: true, skipUnpackError: true,
unpackedDirPath: installDir, unpackedDirPath: installDir,
}); });
const existingPaths = getAppConfig('localBackendPaths') ?? [];
if (!existingPaths.includes(launcherPath)) {
await setAppConfig('localBackendPaths', [...existingPaths, launcherPath]);
}
return { success: true }; return { success: true };
} catch (error) { } catch (error) {
logError('Failed to import local backend:', error as Error); logError('Failed to import local backend:', error as Error);

View file

@ -62,7 +62,6 @@ export interface InstalledBackend {
filename: string; filename: string;
size?: number; size?: number;
actualVersion?: string; actualVersion?: string;
source?: 'local';
} }
export interface DownloadItem { export interface DownloadItem {

View file

@ -68,7 +68,6 @@ export interface BackendInfo {
size?: number; size?: number;
isInstalled: boolean; isInstalled: boolean;
isCurrent: boolean; isCurrent: boolean;
isLocal?: boolean;
downloadUrl?: string; downloadUrl?: string;
installedPath?: string; installedPath?: string;
hasUpdate?: boolean; hasUpdate?: boolean;