Compare commits

..

1 Commits

Author SHA1 Message Date
minori 780228992b deps: update @tailwindcss/vite to 4.2.2
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 1m28s
CI / Lint & Test (pull_request) Successful in 20m8s
CI / Build Linux (pull_request) Successful in 26m11s
CI / Build Windows (cross-compile) (pull_request) Successful in 39m58s
2026-03-29 07:02:37 -07:00
21 changed files with 164 additions and 1211 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "hikari-desktop", "name": "hikari-desktop",
"version": "1.14.0", "version": "1.13.0",
"description": "", "description": "",
"type": "module", "type": "module",
"scripts": { "scripts": {
@@ -72,7 +72,7 @@
"@sveltejs/adapter-static": "3.0.10", "@sveltejs/adapter-static": "3.0.10",
"@sveltejs/kit": "2.53.2", "@sveltejs/kit": "2.53.2",
"@sveltejs/vite-plugin-svelte": "5.1.1", "@sveltejs/vite-plugin-svelte": "5.1.1",
"@tailwindcss/vite": "4.2.1", "@tailwindcss/vite": "4.2.2",
"@tauri-apps/cli": "2.10.0", "@tauri-apps/cli": "2.10.0",
"@testing-library/jest-dom": "6.9.1", "@testing-library/jest-dom": "6.9.1",
"@testing-library/svelte": "5.3.1", "@testing-library/svelte": "5.3.1",
+151 -146
View File
@@ -131,16 +131,16 @@ importers:
version: 9.39.3 version: 9.39.3
'@sveltejs/adapter-static': '@sveltejs/adapter-static':
specifier: 3.0.10 specifier: 3.0.10
version: 3.0.10(@sveltejs/kit@2.53.2(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1)))(svelte@5.53.5)(typescript@5.9.3)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1))) version: 3.0.10(@sveltejs/kit@2.53.2(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0)))(svelte@5.53.5)(typescript@5.9.3)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0)))
'@sveltejs/kit': '@sveltejs/kit':
specifier: 2.53.2 specifier: 2.53.2
version: 2.53.2(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1)))(svelte@5.53.5)(typescript@5.9.3)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1)) version: 2.53.2(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0)))(svelte@5.53.5)(typescript@5.9.3)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0))
'@sveltejs/vite-plugin-svelte': '@sveltejs/vite-plugin-svelte':
specifier: 5.1.1 specifier: 5.1.1
version: 5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1)) version: 5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0))
'@tailwindcss/vite': '@tailwindcss/vite':
specifier: 4.2.1 specifier: 4.2.2
version: 4.2.1(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1)) version: 4.2.2(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0))
'@tauri-apps/cli': '@tauri-apps/cli':
specifier: 2.10.0 specifier: 2.10.0
version: 2.10.0 version: 2.10.0
@@ -149,10 +149,10 @@ importers:
version: 6.9.1 version: 6.9.1
'@testing-library/svelte': '@testing-library/svelte':
specifier: 5.3.1 specifier: 5.3.1
version: 5.3.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1))(vitest@4.0.18(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.31.1)) version: 5.3.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0))(vitest@4.0.18(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.32.0))
'@vitest/coverage-v8': '@vitest/coverage-v8':
specifier: 4.0.18 specifier: 4.0.18
version: 4.0.18(vitest@4.0.18(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.31.1)) version: 4.0.18(vitest@4.0.18(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.32.0))
eslint: eslint:
specifier: 9.39.3 specifier: 9.39.3
version: 9.39.3(jiti@2.6.1) version: 9.39.3(jiti@2.6.1)
@@ -191,10 +191,10 @@ importers:
version: 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) version: 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)
vite: vite:
specifier: 6.4.1 specifier: 6.4.1
version: 6.4.1(jiti@2.6.1)(lightningcss@1.31.1) version: 6.4.1(jiti@2.6.1)(lightningcss@1.32.0)
vitest: vitest:
specifier: 4.0.18 specifier: 4.0.18
version: 4.0.18(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.31.1) version: 4.0.18(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.32.0)
packages: packages:
@@ -823,65 +823,65 @@ packages:
svelte: ^5.0.0 svelte: ^5.0.0
vite: ^6.0.0 vite: ^6.0.0
'@tailwindcss/node@4.2.1': '@tailwindcss/node@4.2.2':
resolution: {integrity: sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==} resolution: {integrity: sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==}
'@tailwindcss/oxide-android-arm64@4.2.1': '@tailwindcss/oxide-android-arm64@4.2.2':
resolution: {integrity: sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==} resolution: {integrity: sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==}
engines: {node: '>= 20'} engines: {node: '>= 20'}
cpu: [arm64] cpu: [arm64]
os: [android] os: [android]
'@tailwindcss/oxide-darwin-arm64@4.2.1': '@tailwindcss/oxide-darwin-arm64@4.2.2':
resolution: {integrity: sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==} resolution: {integrity: sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==}
engines: {node: '>= 20'} engines: {node: '>= 20'}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
'@tailwindcss/oxide-darwin-x64@4.2.1': '@tailwindcss/oxide-darwin-x64@4.2.2':
resolution: {integrity: sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==} resolution: {integrity: sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==}
engines: {node: '>= 20'} engines: {node: '>= 20'}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
'@tailwindcss/oxide-freebsd-x64@4.2.1': '@tailwindcss/oxide-freebsd-x64@4.2.2':
resolution: {integrity: sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==} resolution: {integrity: sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==}
engines: {node: '>= 20'} engines: {node: '>= 20'}
cpu: [x64] cpu: [x64]
os: [freebsd] os: [freebsd]
'@tailwindcss/oxide-linux-arm-gnueabihf@4.2.1': '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2':
resolution: {integrity: sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==} resolution: {integrity: sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==}
engines: {node: '>= 20'} engines: {node: '>= 20'}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
'@tailwindcss/oxide-linux-arm64-gnu@4.2.1': '@tailwindcss/oxide-linux-arm64-gnu@4.2.2':
resolution: {integrity: sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==} resolution: {integrity: sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==}
engines: {node: '>= 20'} engines: {node: '>= 20'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@tailwindcss/oxide-linux-arm64-musl@4.2.1': '@tailwindcss/oxide-linux-arm64-musl@4.2.2':
resolution: {integrity: sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==} resolution: {integrity: sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==}
engines: {node: '>= 20'} engines: {node: '>= 20'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@tailwindcss/oxide-linux-x64-gnu@4.2.1': '@tailwindcss/oxide-linux-x64-gnu@4.2.2':
resolution: {integrity: sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==} resolution: {integrity: sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==}
engines: {node: '>= 20'} engines: {node: '>= 20'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@tailwindcss/oxide-linux-x64-musl@4.2.1': '@tailwindcss/oxide-linux-x64-musl@4.2.2':
resolution: {integrity: sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==} resolution: {integrity: sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==}
engines: {node: '>= 20'} engines: {node: '>= 20'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@tailwindcss/oxide-wasm32-wasi@4.2.1': '@tailwindcss/oxide-wasm32-wasi@4.2.2':
resolution: {integrity: sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==} resolution: {integrity: sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
cpu: [wasm32] cpu: [wasm32]
bundledDependencies: bundledDependencies:
@@ -892,26 +892,26 @@ packages:
- '@emnapi/wasi-threads' - '@emnapi/wasi-threads'
- tslib - tslib
'@tailwindcss/oxide-win32-arm64-msvc@4.2.1': '@tailwindcss/oxide-win32-arm64-msvc@4.2.2':
resolution: {integrity: sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==} resolution: {integrity: sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==}
engines: {node: '>= 20'} engines: {node: '>= 20'}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
'@tailwindcss/oxide-win32-x64-msvc@4.2.1': '@tailwindcss/oxide-win32-x64-msvc@4.2.2':
resolution: {integrity: sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==} resolution: {integrity: sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==}
engines: {node: '>= 20'} engines: {node: '>= 20'}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@tailwindcss/oxide@4.2.1': '@tailwindcss/oxide@4.2.2':
resolution: {integrity: sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==} resolution: {integrity: sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==}
engines: {node: '>= 20'} engines: {node: '>= 20'}
'@tailwindcss/vite@4.2.1': '@tailwindcss/vite@4.2.2':
resolution: {integrity: sha512-TBf2sJjYeb28jD2U/OhwdW0bbOsxkWPwQ7SrqGf9sVcoYwZj7rkXljroBO9wKBut9XnmQLXanuDUeqQK0lGg/w==} resolution: {integrity: sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w==}
peerDependencies: peerDependencies:
vite: ^5.2.0 || ^6 || ^7 vite: ^5.2.0 || ^6 || ^7 || ^8
'@tauri-apps/api@2.10.1': '@tauri-apps/api@2.10.1':
resolution: {integrity: sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw==} resolution: {integrity: sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw==}
@@ -1597,74 +1597,74 @@ packages:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
lightningcss-android-arm64@1.31.1: lightningcss-android-arm64@1.32.0:
resolution: {integrity: sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==} resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [arm64] cpu: [arm64]
os: [android] os: [android]
lightningcss-darwin-arm64@1.31.1: lightningcss-darwin-arm64@1.32.0:
resolution: {integrity: sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==} resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
lightningcss-darwin-x64@1.31.1: lightningcss-darwin-x64@1.32.0:
resolution: {integrity: sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==} resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
lightningcss-freebsd-x64@1.31.1: lightningcss-freebsd-x64@1.32.0:
resolution: {integrity: sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==} resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [x64] cpu: [x64]
os: [freebsd] os: [freebsd]
lightningcss-linux-arm-gnueabihf@1.31.1: lightningcss-linux-arm-gnueabihf@1.32.0:
resolution: {integrity: sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==} resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
lightningcss-linux-arm64-gnu@1.31.1: lightningcss-linux-arm64-gnu@1.32.0:
resolution: {integrity: sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==} resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
lightningcss-linux-arm64-musl@1.31.1: lightningcss-linux-arm64-musl@1.32.0:
resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==} resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
lightningcss-linux-x64-gnu@1.31.1: lightningcss-linux-x64-gnu@1.32.0:
resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==} resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
lightningcss-linux-x64-musl@1.31.1: lightningcss-linux-x64-musl@1.32.0:
resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==} resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
lightningcss-win32-arm64-msvc@1.31.1: lightningcss-win32-arm64-msvc@1.32.0:
resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==} resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
lightningcss-win32-x64-msvc@1.31.1: lightningcss-win32-x64-msvc@1.32.0:
resolution: {integrity: sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==} resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
lightningcss@1.31.1: lightningcss@1.32.0:
resolution: {integrity: sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==} resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
lilconfig@2.1.0: lilconfig@2.1.0:
@@ -1944,6 +1944,9 @@ packages:
tailwindcss@4.2.1: tailwindcss@4.2.1:
resolution: {integrity: sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==} resolution: {integrity: sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==}
tailwindcss@4.2.2:
resolution: {integrity: sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==}
tapable@2.3.0: tapable@2.3.0:
resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==}
engines: {node: '>=6'} engines: {node: '>=6'}
@@ -2764,15 +2767,15 @@ snapshots:
dependencies: dependencies:
acorn: 8.15.0 acorn: 8.15.0
'@sveltejs/adapter-static@3.0.10(@sveltejs/kit@2.53.2(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1)))(svelte@5.53.5)(typescript@5.9.3)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1)))': '@sveltejs/adapter-static@3.0.10(@sveltejs/kit@2.53.2(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0)))(svelte@5.53.5)(typescript@5.9.3)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0)))':
dependencies: dependencies:
'@sveltejs/kit': 2.53.2(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1)))(svelte@5.53.5)(typescript@5.9.3)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1)) '@sveltejs/kit': 2.53.2(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0)))(svelte@5.53.5)(typescript@5.9.3)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0))
'@sveltejs/kit@2.53.2(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1)))(svelte@5.53.5)(typescript@5.9.3)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1))': '@sveltejs/kit@2.53.2(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0)))(svelte@5.53.5)(typescript@5.9.3)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0))':
dependencies: dependencies:
'@standard-schema/spec': 1.1.0 '@standard-schema/spec': 1.1.0
'@sveltejs/acorn-typescript': 1.0.8(acorn@8.15.0) '@sveltejs/acorn-typescript': 1.0.8(acorn@8.15.0)
'@sveltejs/vite-plugin-svelte': 5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1)) '@sveltejs/vite-plugin-svelte': 5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0))
'@types/cookie': 0.6.0 '@types/cookie': 0.6.0
acorn: 8.15.0 acorn: 8.15.0
cookie: 0.6.0 cookie: 0.6.0
@@ -2784,99 +2787,99 @@ snapshots:
set-cookie-parser: 3.0.1 set-cookie-parser: 3.0.1
sirv: 3.0.2 sirv: 3.0.2
svelte: 5.53.5 svelte: 5.53.5
vite: 6.4.1(jiti@2.6.1)(lightningcss@1.31.1) vite: 6.4.1(jiti@2.6.1)(lightningcss@1.32.0)
optionalDependencies: optionalDependencies:
typescript: 5.9.3 typescript: 5.9.3
'@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1)))(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1))': '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0)))(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0))':
dependencies: dependencies:
'@sveltejs/vite-plugin-svelte': 5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1)) '@sveltejs/vite-plugin-svelte': 5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0))
debug: 4.4.3 debug: 4.4.3
svelte: 5.53.5 svelte: 5.53.5
vite: 6.4.1(jiti@2.6.1)(lightningcss@1.31.1) vite: 6.4.1(jiti@2.6.1)(lightningcss@1.32.0)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1))': '@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0))':
dependencies: dependencies:
'@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1)))(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1)) '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0)))(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0))
debug: 4.4.3 debug: 4.4.3
deepmerge: 4.3.1 deepmerge: 4.3.1
kleur: 4.1.5 kleur: 4.1.5
magic-string: 0.30.21 magic-string: 0.30.21
svelte: 5.53.5 svelte: 5.53.5
vite: 6.4.1(jiti@2.6.1)(lightningcss@1.31.1) vite: 6.4.1(jiti@2.6.1)(lightningcss@1.32.0)
vitefu: 1.1.1(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1)) vitefu: 1.1.1(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0))
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@tailwindcss/node@4.2.1': '@tailwindcss/node@4.2.2':
dependencies: dependencies:
'@jridgewell/remapping': 2.3.5 '@jridgewell/remapping': 2.3.5
enhanced-resolve: 5.19.0 enhanced-resolve: 5.19.0
jiti: 2.6.1 jiti: 2.6.1
lightningcss: 1.31.1 lightningcss: 1.32.0
magic-string: 0.30.21 magic-string: 0.30.21
source-map-js: 1.2.1 source-map-js: 1.2.1
tailwindcss: 4.2.1 tailwindcss: 4.2.2
'@tailwindcss/oxide-android-arm64@4.2.1': '@tailwindcss/oxide-android-arm64@4.2.2':
optional: true optional: true
'@tailwindcss/oxide-darwin-arm64@4.2.1': '@tailwindcss/oxide-darwin-arm64@4.2.2':
optional: true optional: true
'@tailwindcss/oxide-darwin-x64@4.2.1': '@tailwindcss/oxide-darwin-x64@4.2.2':
optional: true optional: true
'@tailwindcss/oxide-freebsd-x64@4.2.1': '@tailwindcss/oxide-freebsd-x64@4.2.2':
optional: true optional: true
'@tailwindcss/oxide-linux-arm-gnueabihf@4.2.1': '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2':
optional: true optional: true
'@tailwindcss/oxide-linux-arm64-gnu@4.2.1': '@tailwindcss/oxide-linux-arm64-gnu@4.2.2':
optional: true optional: true
'@tailwindcss/oxide-linux-arm64-musl@4.2.1': '@tailwindcss/oxide-linux-arm64-musl@4.2.2':
optional: true optional: true
'@tailwindcss/oxide-linux-x64-gnu@4.2.1': '@tailwindcss/oxide-linux-x64-gnu@4.2.2':
optional: true optional: true
'@tailwindcss/oxide-linux-x64-musl@4.2.1': '@tailwindcss/oxide-linux-x64-musl@4.2.2':
optional: true optional: true
'@tailwindcss/oxide-wasm32-wasi@4.2.1': '@tailwindcss/oxide-wasm32-wasi@4.2.2':
optional: true optional: true
'@tailwindcss/oxide-win32-arm64-msvc@4.2.1': '@tailwindcss/oxide-win32-arm64-msvc@4.2.2':
optional: true optional: true
'@tailwindcss/oxide-win32-x64-msvc@4.2.1': '@tailwindcss/oxide-win32-x64-msvc@4.2.2':
optional: true optional: true
'@tailwindcss/oxide@4.2.1': '@tailwindcss/oxide@4.2.2':
optionalDependencies: optionalDependencies:
'@tailwindcss/oxide-android-arm64': 4.2.1 '@tailwindcss/oxide-android-arm64': 4.2.2
'@tailwindcss/oxide-darwin-arm64': 4.2.1 '@tailwindcss/oxide-darwin-arm64': 4.2.2
'@tailwindcss/oxide-darwin-x64': 4.2.1 '@tailwindcss/oxide-darwin-x64': 4.2.2
'@tailwindcss/oxide-freebsd-x64': 4.2.1 '@tailwindcss/oxide-freebsd-x64': 4.2.2
'@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.1 '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.2
'@tailwindcss/oxide-linux-arm64-gnu': 4.2.1 '@tailwindcss/oxide-linux-arm64-gnu': 4.2.2
'@tailwindcss/oxide-linux-arm64-musl': 4.2.1 '@tailwindcss/oxide-linux-arm64-musl': 4.2.2
'@tailwindcss/oxide-linux-x64-gnu': 4.2.1 '@tailwindcss/oxide-linux-x64-gnu': 4.2.2
'@tailwindcss/oxide-linux-x64-musl': 4.2.1 '@tailwindcss/oxide-linux-x64-musl': 4.2.2
'@tailwindcss/oxide-wasm32-wasi': 4.2.1 '@tailwindcss/oxide-wasm32-wasi': 4.2.2
'@tailwindcss/oxide-win32-arm64-msvc': 4.2.1 '@tailwindcss/oxide-win32-arm64-msvc': 4.2.2
'@tailwindcss/oxide-win32-x64-msvc': 4.2.1 '@tailwindcss/oxide-win32-x64-msvc': 4.2.2
'@tailwindcss/vite@4.2.1(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1))': '@tailwindcss/vite@4.2.2(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0))':
dependencies: dependencies:
'@tailwindcss/node': 4.2.1 '@tailwindcss/node': 4.2.2
'@tailwindcss/oxide': 4.2.1 '@tailwindcss/oxide': 4.2.2
tailwindcss: 4.2.1 tailwindcss: 4.2.2
vite: 6.4.1(jiti@2.6.1)(lightningcss@1.31.1) vite: 6.4.1(jiti@2.6.1)(lightningcss@1.32.0)
'@tauri-apps/api@2.10.1': {} '@tauri-apps/api@2.10.1': {}
@@ -2983,14 +2986,14 @@ snapshots:
dependencies: dependencies:
svelte: 5.53.5 svelte: 5.53.5
'@testing-library/svelte@5.3.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1))(vitest@4.0.18(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.31.1))': '@testing-library/svelte@5.3.1(svelte@5.53.5)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0))(vitest@4.0.18(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.32.0))':
dependencies: dependencies:
'@testing-library/dom': 10.4.1 '@testing-library/dom': 10.4.1
'@testing-library/svelte-core': 1.0.0(svelte@5.53.5) '@testing-library/svelte-core': 1.0.0(svelte@5.53.5)
svelte: 5.53.5 svelte: 5.53.5
optionalDependencies: optionalDependencies:
vite: 6.4.1(jiti@2.6.1)(lightningcss@1.31.1) vite: 6.4.1(jiti@2.6.1)(lightningcss@1.32.0)
vitest: 4.0.18(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.31.1) vitest: 4.0.18(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.32.0)
'@types/aria-query@5.0.4': {} '@types/aria-query@5.0.4': {}
@@ -3100,7 +3103,7 @@ snapshots:
'@typescript-eslint/types': 8.56.1 '@typescript-eslint/types': 8.56.1
eslint-visitor-keys: 5.0.1 eslint-visitor-keys: 5.0.1
'@vitest/coverage-v8@4.0.18(vitest@4.0.18(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.31.1))': '@vitest/coverage-v8@4.0.18(vitest@4.0.18(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.32.0))':
dependencies: dependencies:
'@bcoe/v8-coverage': 1.0.2 '@bcoe/v8-coverage': 1.0.2
'@vitest/utils': 4.0.18 '@vitest/utils': 4.0.18
@@ -3112,7 +3115,7 @@ snapshots:
obug: 2.1.1 obug: 2.1.1
std-env: 3.10.0 std-env: 3.10.0
tinyrainbow: 3.0.3 tinyrainbow: 3.0.3
vitest: 4.0.18(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.31.1) vitest: 4.0.18(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.32.0)
'@vitest/expect@4.0.18': '@vitest/expect@4.0.18':
dependencies: dependencies:
@@ -3123,13 +3126,13 @@ snapshots:
chai: 6.2.2 chai: 6.2.2
tinyrainbow: 3.0.3 tinyrainbow: 3.0.3
'@vitest/mocker@4.0.18(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1))': '@vitest/mocker@4.0.18(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0))':
dependencies: dependencies:
'@vitest/spy': 4.0.18 '@vitest/spy': 4.0.18
estree-walker: 3.0.3 estree-walker: 3.0.3
magic-string: 0.30.21 magic-string: 0.30.21
optionalDependencies: optionalDependencies:
vite: 6.4.1(jiti@2.6.1)(lightningcss@1.31.1) vite: 6.4.1(jiti@2.6.1)(lightningcss@1.32.0)
'@vitest/pretty-format@4.0.18': '@vitest/pretty-format@4.0.18':
dependencies: dependencies:
@@ -3606,54 +3609,54 @@ snapshots:
prelude-ls: 1.2.1 prelude-ls: 1.2.1
type-check: 0.4.0 type-check: 0.4.0
lightningcss-android-arm64@1.31.1: lightningcss-android-arm64@1.32.0:
optional: true optional: true
lightningcss-darwin-arm64@1.31.1: lightningcss-darwin-arm64@1.32.0:
optional: true optional: true
lightningcss-darwin-x64@1.31.1: lightningcss-darwin-x64@1.32.0:
optional: true optional: true
lightningcss-freebsd-x64@1.31.1: lightningcss-freebsd-x64@1.32.0:
optional: true optional: true
lightningcss-linux-arm-gnueabihf@1.31.1: lightningcss-linux-arm-gnueabihf@1.32.0:
optional: true optional: true
lightningcss-linux-arm64-gnu@1.31.1: lightningcss-linux-arm64-gnu@1.32.0:
optional: true optional: true
lightningcss-linux-arm64-musl@1.31.1: lightningcss-linux-arm64-musl@1.32.0:
optional: true optional: true
lightningcss-linux-x64-gnu@1.31.1: lightningcss-linux-x64-gnu@1.32.0:
optional: true optional: true
lightningcss-linux-x64-musl@1.31.1: lightningcss-linux-x64-musl@1.32.0:
optional: true optional: true
lightningcss-win32-arm64-msvc@1.31.1: lightningcss-win32-arm64-msvc@1.32.0:
optional: true optional: true
lightningcss-win32-x64-msvc@1.31.1: lightningcss-win32-x64-msvc@1.32.0:
optional: true optional: true
lightningcss@1.31.1: lightningcss@1.32.0:
dependencies: dependencies:
detect-libc: 2.1.2 detect-libc: 2.1.2
optionalDependencies: optionalDependencies:
lightningcss-android-arm64: 1.31.1 lightningcss-android-arm64: 1.32.0
lightningcss-darwin-arm64: 1.31.1 lightningcss-darwin-arm64: 1.32.0
lightningcss-darwin-x64: 1.31.1 lightningcss-darwin-x64: 1.32.0
lightningcss-freebsd-x64: 1.31.1 lightningcss-freebsd-x64: 1.32.0
lightningcss-linux-arm-gnueabihf: 1.31.1 lightningcss-linux-arm-gnueabihf: 1.32.0
lightningcss-linux-arm64-gnu: 1.31.1 lightningcss-linux-arm64-gnu: 1.32.0
lightningcss-linux-arm64-musl: 1.31.1 lightningcss-linux-arm64-musl: 1.32.0
lightningcss-linux-x64-gnu: 1.31.1 lightningcss-linux-x64-gnu: 1.32.0
lightningcss-linux-x64-musl: 1.31.1 lightningcss-linux-x64-musl: 1.32.0
lightningcss-win32-arm64-msvc: 1.31.1 lightningcss-win32-arm64-msvc: 1.32.0
lightningcss-win32-x64-msvc: 1.31.1 lightningcss-win32-x64-msvc: 1.32.0
lilconfig@2.1.0: {} lilconfig@2.1.0: {}
@@ -3925,6 +3928,8 @@ snapshots:
tailwindcss@4.2.1: {} tailwindcss@4.2.1: {}
tailwindcss@4.2.2: {}
tapable@2.3.0: {} tapable@2.3.0: {}
tinybench@2.9.0: {} tinybench@2.9.0: {}
@@ -3983,7 +3988,7 @@ snapshots:
util-deprecate@1.0.2: {} util-deprecate@1.0.2: {}
vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1): vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0):
dependencies: dependencies:
esbuild: 0.25.12 esbuild: 0.25.12
fdir: 6.5.0(picomatch@4.0.3) fdir: 6.5.0(picomatch@4.0.3)
@@ -3994,16 +3999,16 @@ snapshots:
optionalDependencies: optionalDependencies:
fsevents: 2.3.3 fsevents: 2.3.3
jiti: 2.6.1 jiti: 2.6.1
lightningcss: 1.31.1 lightningcss: 1.32.0
vitefu@1.1.1(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1)): vitefu@1.1.1(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0)):
optionalDependencies: optionalDependencies:
vite: 6.4.1(jiti@2.6.1)(lightningcss@1.31.1) vite: 6.4.1(jiti@2.6.1)(lightningcss@1.32.0)
vitest@4.0.18(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.31.1): vitest@4.0.18(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.32.0):
dependencies: dependencies:
'@vitest/expect': 4.0.18 '@vitest/expect': 4.0.18
'@vitest/mocker': 4.0.18(vite@6.4.1(jiti@2.6.1)(lightningcss@1.31.1)) '@vitest/mocker': 4.0.18(vite@6.4.1(jiti@2.6.1)(lightningcss@1.32.0))
'@vitest/pretty-format': 4.0.18 '@vitest/pretty-format': 4.0.18
'@vitest/runner': 4.0.18 '@vitest/runner': 4.0.18
'@vitest/snapshot': 4.0.18 '@vitest/snapshot': 4.0.18
@@ -4020,7 +4025,7 @@ snapshots:
tinyexec: 1.0.2 tinyexec: 1.0.2
tinyglobby: 0.2.15 tinyglobby: 0.2.15
tinyrainbow: 3.0.3 tinyrainbow: 3.0.3
vite: 6.4.1(jiti@2.6.1)(lightningcss@1.31.1) vite: 6.4.1(jiti@2.6.1)(lightningcss@1.32.0)
why-is-node-running: 2.3.0 why-is-node-running: 2.3.0
optionalDependencies: optionalDependencies:
jsdom: 28.1.0 jsdom: 28.1.0
+1 -1
View File
@@ -1648,7 +1648,7 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]] [[package]]
name = "hikari-desktop" name = "hikari-desktop"
version = "1.14.0" version = "1.13.0"
dependencies = [ dependencies = [
"chrono", "chrono",
"dirs 5.0.1", "dirs 5.0.1",
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "hikari-desktop" name = "hikari-desktop"
version = "1.14.0" version = "1.13.0"
description = "Hikari - Claude Code Visual Assistant" description = "Hikari - Claude Code Visual Assistant"
authors = ["Naomi Carrigan"] authors = ["Naomi Carrigan"]
edition = "2021" edition = "2021"
-115
View File
@@ -2618,103 +2618,6 @@ pub async fn open_binary_file(app: AppHandle, path: String) -> Result<(), String
} }
} }
/// Read `~/.claude/CLAUDE.md` via WSL (for Windows).
/// Returns an empty string if the file does not exist.
#[cfg(target_os = "windows")]
async fn get_global_claude_md_via_wsl() -> Result<String, String> {
use std::process::Command;
let output = Command::new("wsl")
.hide_window()
.args(["-e", "bash", "-l", "-c", "cat ~/.claude/CLAUDE.md 2>/dev/null || true"])
.output()
.map_err(|e| format!("Failed to execute WSL command: {}", e))?;
Ok(String::from_utf8_lossy(&output.stdout).to_string())
}
/// Write content to `~/.claude/CLAUDE.md` via WSL (for Windows).
/// Creates the file (and `~/.claude/` directory) if they do not exist.
#[cfg(target_os = "windows")]
async fn save_global_claude_md_via_wsl(content: String) -> Result<(), String> {
use std::io::Write;
use std::process::{Command, Stdio};
let mut child = Command::new("wsl")
.hide_window()
.args([
"-e",
"bash",
"-l",
"-c",
"mkdir -p ~/.claude && cat > ~/.claude/CLAUDE.md",
])
.stdin(Stdio::piped())
.spawn()
.map_err(|e| format!("Failed to execute WSL command: {}", e))?;
if let Some(stdin) = child.stdin.as_mut() {
stdin
.write_all(content.as_bytes())
.map_err(|e| format!("Failed to write content to WSL stdin: {}", e))?;
}
let status = child
.wait()
.map_err(|e| format!("Failed to wait for WSL command: {}", e))?;
if !status.success() {
return Err("Failed to save CLAUDE.md via WSL".to_string());
}
Ok(())
}
/// Read the contents of `~/.claude/CLAUDE.md`.
/// Returns an empty string if the file does not exist.
#[tauri::command]
pub async fn get_global_claude_md() -> Result<String, String> {
#[cfg(target_os = "windows")]
return get_global_claude_md_via_wsl().await;
#[cfg(not(target_os = "windows"))]
{
let path = dirs::home_dir()
.ok_or_else(|| "Could not determine home directory".to_string())?
.join(".claude")
.join("CLAUDE.md");
if !path.exists() {
return Ok(String::new());
}
std::fs::read_to_string(&path).map_err(|e| format!("Failed to read CLAUDE.md: {}", e))
}
}
/// Write content to `~/.claude/CLAUDE.md`.
/// Creates the file (and `~/.claude/` directory) if they do not exist.
#[tauri::command]
pub async fn save_global_claude_md(content: String) -> Result<(), String> {
#[cfg(target_os = "windows")]
return save_global_claude_md_via_wsl(content).await;
#[cfg(not(target_os = "windows"))]
{
let claude_dir = dirs::home_dir()
.ok_or_else(|| "Could not determine home directory".to_string())?
.join(".claude");
if !claude_dir.exists() {
std::fs::create_dir_all(&claude_dir)
.map_err(|e| format!("Failed to create ~/.claude directory: {}", e))?;
}
let path = claude_dir.join("CLAUDE.md");
std::fs::write(&path, content).map_err(|e| format!("Failed to write CLAUDE.md: {}", e))
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@@ -3464,22 +3367,4 @@ gitea: gitea-mcp -t stdio (STDIO) - âś“ Connected"#;
let (_, args) = build_wslpath_command(path); let (_, args) = build_wslpath_command(path);
assert_eq!(args[2], path); assert_eq!(args[2], path);
} }
#[test]
fn test_get_global_claude_md_path_construction() {
// Verify that home_dir() resolves successfully on the test platform
let home = dirs::home_dir();
assert!(home.is_some(), "home_dir() should be available in test environment");
let expected = home.unwrap().join(".claude").join("CLAUDE.md");
assert!(expected.to_string_lossy().contains(".claude"));
assert!(expected.to_string_lossy().ends_with("CLAUDE.md"));
}
#[test]
fn test_save_global_claude_md_dir_path_construction() {
let home = dirs::home_dir();
assert!(home.is_some());
let dir = home.unwrap().join(".claude");
assert!(dir.to_string_lossy().contains(".claude"));
}
} }
-49
View File
@@ -54,22 +54,6 @@ pub struct ClaudeStartOptions {
#[serde(default)] #[serde(default)]
pub session_name: Option<String>, pub session_name: Option<String>,
#[serde(default)]
pub disable_skill_shell_execution: bool,
/// Pass `--bare` flag to suppress UI chrome, useful for scripted headless `-p` calls (v2.1.81+).
#[serde(default)]
pub bare_mode: bool,
/// Controls `showClearContextOnPlanAccept` in `--settings` (v2.1.81+).
/// Defaults to true (matching CLI default). Set to false to suppress the dialog.
#[serde(default = "default_show_clear_context")]
pub show_clear_context_on_plan_accept: bool,
/// Sets `ANTHROPIC_CUSTOM_MODEL_OPTION` env var for custom model providers (v2.1.81+).
#[serde(default)]
pub custom_model_option: Option<String>,
} }
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
@@ -219,23 +203,6 @@ pub struct HikariConfig {
#[serde(default)] #[serde(default)]
pub model_overrides: Option<HashMap<String, String>>, pub model_overrides: Option<HashMap<String, String>>,
/// Prevents skill scripts from executing shell commands (Claude Code v2.1.91+).
/// Passes `"disableSkillShellExecution": true` via the `--settings` flag.
#[serde(default)]
pub disable_skill_shell_execution: bool,
/// Pass `--bare` flag to suppress UI chrome, useful for scripted headless `-p` calls (v2.1.81+).
#[serde(default)]
pub bare_mode: bool,
/// Controls `showClearContextOnPlanAccept` in `--settings` (v2.1.81+).
#[serde(default = "default_show_clear_context")]
pub show_clear_context_on_plan_accept: bool,
/// Sets `ANTHROPIC_CUSTOM_MODEL_OPTION` env var for custom model providers (v2.1.81+).
#[serde(default)]
pub custom_model_option: Option<String>,
} }
impl Default for HikariConfig { impl Default for HikariConfig {
@@ -287,10 +254,6 @@ impl Default for HikariConfig {
enable_claudeai_mcp_servers: true, enable_claudeai_mcp_servers: true,
auto_memory_directory: None, auto_memory_directory: None,
model_overrides: None, model_overrides: None,
disable_skill_shell_execution: false,
bare_mode: false,
show_clear_context_on_plan_accept: true,
custom_model_option: None,
} }
} }
} }
@@ -343,10 +306,6 @@ fn default_enable_claudeai_mcp_servers() -> bool {
true true
} }
fn default_show_clear_context() -> bool {
true
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)] #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]
pub enum BudgetAction { pub enum BudgetAction {
@@ -446,10 +405,6 @@ mod tests {
assert!(config.enable_claudeai_mcp_servers); assert!(config.enable_claudeai_mcp_servers);
assert!(config.auto_memory_directory.is_none()); assert!(config.auto_memory_directory.is_none());
assert!(config.model_overrides.is_none()); assert!(config.model_overrides.is_none());
assert!(!config.disable_skill_shell_execution);
assert!(!config.bare_mode);
assert!(config.show_clear_context_on_plan_accept);
assert!(config.custom_model_option.is_none());
} }
#[test] #[test]
@@ -504,10 +459,6 @@ mod tests {
"claude-opus-4-6".to_string(), "claude-opus-4-6".to_string(),
"arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-opus-4-6-v1".to_string(), "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-opus-4-6-v1".to_string(),
)])), )])),
disable_skill_shell_execution: true,
bare_mode: false,
show_clear_context_on_plan_accept: true,
custom_model_option: None,
}; };
let json = serde_json::to_string(&config).unwrap(); let json = serde_json::to_string(&config).unwrap();
-2
View File
@@ -224,8 +224,6 @@ pub fn run() {
delete_all_drafts, delete_all_drafts,
scan_project, scan_project,
open_binary_file, open_binary_file,
get_global_claude_md,
save_global_claude_md,
]) ])
.run(tauri::generate_context!()) .run(tauri::generate_context!())
.expect("error while running tauri application"); .expect("error while running tauri application");
-244
View File
@@ -95,9 +95,6 @@ pub enum ClaudeMessage {
cwd: Option<String>, cwd: Option<String>,
#[serde(default)] #[serde(default)]
tools: Option<Vec<String>>, tools: Option<Vec<String>>,
/// Output style hint from Claude Code (v2.1.81+). Informational only.
#[serde(default)]
output_style: Option<String>,
}, },
#[serde(rename = "assistant")] #[serde(rename = "assistant")]
Assistant { Assistant {
@@ -122,15 +119,6 @@ pub enum ClaudeMessage {
permission_denials: Option<Vec<PermissionDenial>>, permission_denials: Option<Vec<PermissionDenial>>,
#[serde(default)] #[serde(default)]
usage: Option<UsageInfo>, usage: Option<UsageInfo>,
/// Fast mode state from Claude Code v2.1.81+. Values: "default" | "enabled" | "disabled".
#[serde(default)]
fast_mode_state: Option<String>,
/// Per-model usage breakdown from Claude Code v2.1.81+.
#[serde(default)]
model_usage: Option<serde_json::Value>,
/// Authoritative total cost in USD reported by Claude Code v2.1.81+.
#[serde(default)]
total_cost_usd: Option<f64>,
}, },
#[serde(rename = "rate_limit_event")] #[serde(rename = "rate_limit_event")]
RateLimitEvent { RateLimitEvent {
@@ -330,42 +318,6 @@ pub struct PostCompactEvent {
pub conversation_id: Option<String>, pub conversation_id: Option<String>,
} }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CwdChangedEvent {
pub cwd: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub conversation_id: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileChangedEvent {
pub file: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub conversation_id: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskCreatedEvent {
#[serde(skip_serializing_if = "Option::is_none")]
pub task_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub parent_tool_use_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub conversation_id: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PermissionDeniedEvent {
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reason: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub conversation_id: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AgentStartEvent { pub struct AgentStartEvent {
pub tool_use_id: String, pub tool_use_id: String,
@@ -789,200 +741,4 @@ mod tests {
assert!(serialized.contains("\"session_id\":\"sess-xyz\"")); assert!(serialized.contains("\"session_id\":\"sess-xyz\""));
assert!(!serialized.contains("conversation_id")); assert!(!serialized.contains("conversation_id"));
} }
#[test]
fn test_cwd_changed_event_serialization() {
let event = CwdChangedEvent {
cwd: "/home/naomi/code/my-project".to_string(),
conversation_id: Some("conv-abc".to_string()),
};
let serialized = serde_json::to_string(&event).unwrap();
assert!(serialized.contains("\"cwd\":\"/home/naomi/code/my-project\""));
assert!(serialized.contains("\"conversation_id\":\"conv-abc\""));
}
#[test]
fn test_cwd_changed_event_omits_none_fields() {
let event = CwdChangedEvent {
cwd: "/tmp/workspace".to_string(),
conversation_id: None,
};
let serialized = serde_json::to_string(&event).unwrap();
assert!(serialized.contains("\"cwd\":\"/tmp/workspace\""));
assert!(!serialized.contains("conversation_id"));
}
#[test]
fn test_file_changed_event_serialization() {
let event = FileChangedEvent {
file: "/home/naomi/code/my-project/src/main.rs".to_string(),
conversation_id: Some("conv-abc".to_string()),
};
let serialized = serde_json::to_string(&event).unwrap();
assert!(serialized.contains("\"file\":\"/home/naomi/code/my-project/src/main.rs\""));
assert!(serialized.contains("\"conversation_id\":\"conv-abc\""));
}
#[test]
fn test_file_changed_event_omits_none_fields() {
let event = FileChangedEvent {
file: "/tmp/test.txt".to_string(),
conversation_id: None,
};
let serialized = serde_json::to_string(&event).unwrap();
assert!(serialized.contains("\"file\":\"/tmp/test.txt\""));
assert!(!serialized.contains("conversation_id"));
}
#[test]
fn test_task_created_event_serialization() {
let event = TaskCreatedEvent {
task_id: Some("task-abc123".to_string()),
description: Some("Explore the codebase".to_string()),
parent_tool_use_id: Some("toolu_xyz".to_string()),
conversation_id: Some("conv-abc".to_string()),
};
let serialized = serde_json::to_string(&event).unwrap();
assert!(serialized.contains("\"task_id\":\"task-abc123\""));
assert!(serialized.contains("\"description\":\"Explore the codebase\""));
assert!(serialized.contains("\"parent_tool_use_id\":\"toolu_xyz\""));
assert!(serialized.contains("\"conversation_id\":\"conv-abc\""));
}
#[test]
fn test_task_created_event_omits_none_fields() {
let event = TaskCreatedEvent {
task_id: None,
description: None,
parent_tool_use_id: None,
conversation_id: None,
};
let serialized = serde_json::to_string(&event).unwrap();
assert_eq!(serialized, "{}");
}
#[test]
fn test_task_created_event_partial_fields() {
let event = TaskCreatedEvent {
task_id: Some("task-001".to_string()),
description: None,
parent_tool_use_id: None,
conversation_id: None,
};
let serialized = serde_json::to_string(&event).unwrap();
assert!(serialized.contains("\"task_id\":\"task-001\""));
assert!(!serialized.contains("description"));
assert!(!serialized.contains("parent_tool_use_id"));
assert!(!serialized.contains("conversation_id"));
}
#[test]
fn test_permission_denied_event_serialization() {
let event = PermissionDeniedEvent {
tool_name: Some("Bash".to_string()),
reason: Some("Tool not in allow list".to_string()),
conversation_id: Some("conv-abc".to_string()),
};
let serialized = serde_json::to_string(&event).unwrap();
assert!(serialized.contains("\"tool_name\":\"Bash\""));
assert!(serialized.contains("\"reason\":\"Tool not in allow list\""));
assert!(serialized.contains("\"conversation_id\":\"conv-abc\""));
}
#[test]
fn test_permission_denied_event_omits_none_fields() {
let event = PermissionDeniedEvent {
tool_name: None,
reason: None,
conversation_id: None,
};
let serialized = serde_json::to_string(&event).unwrap();
assert_eq!(serialized, "{}");
}
#[test]
fn test_permission_denied_event_partial_fields() {
let event = PermissionDeniedEvent {
tool_name: Some("Edit".to_string()),
reason: None,
conversation_id: None,
};
let serialized = serde_json::to_string(&event).unwrap();
assert!(serialized.contains("\"tool_name\":\"Edit\""));
assert!(!serialized.contains("reason"));
assert!(!serialized.contains("conversation_id"));
}
#[test]
fn test_system_init_with_output_style() {
let json = r#"{"type":"system","subtype":"init","session_id":"sess-1","output_style":"auto"}"#;
let msg: ClaudeMessage = serde_json::from_str(json).unwrap();
if let ClaudeMessage::System { output_style, .. } = msg {
assert_eq!(output_style, Some("auto".to_string()));
} else {
panic!("Expected System variant");
}
}
#[test]
fn test_system_init_without_output_style() {
let json = r#"{"type":"system","subtype":"init","session_id":"sess-1"}"#;
let msg: ClaudeMessage = serde_json::from_str(json).unwrap();
if let ClaudeMessage::System { output_style, .. } = msg {
assert!(output_style.is_none());
} else {
panic!("Expected System variant");
}
}
#[test]
fn test_result_message_with_fast_mode_state() {
let json = r#"{"type":"result","subtype":"success","fast_mode_state":"enabled"}"#;
let msg: ClaudeMessage = serde_json::from_str(json).unwrap();
if let ClaudeMessage::Result { fast_mode_state, .. } = msg {
assert_eq!(fast_mode_state, Some("enabled".to_string()));
} else {
panic!("Expected Result variant");
}
}
#[test]
fn test_result_message_with_total_cost_usd() {
let json = r#"{"type":"result","subtype":"success","total_cost_usd":0.05}"#;
let msg: ClaudeMessage = serde_json::from_str(json).unwrap();
if let ClaudeMessage::Result { total_cost_usd, .. } = msg {
assert!((total_cost_usd.unwrap() - 0.05).abs() < f64::EPSILON);
} else {
panic!("Expected Result variant");
}
}
#[test]
fn test_result_message_without_new_fields() {
let json = r#"{"type":"result","subtype":"success"}"#;
let msg: ClaudeMessage = serde_json::from_str(json).unwrap();
if let ClaudeMessage::Result {
fast_mode_state,
model_usage,
total_cost_usd,
..
} = msg
{
assert!(fast_mode_state.is_none());
assert!(model_usage.is_none());
assert!(total_cost_usd.is_none());
} else {
panic!("Expected Result variant");
}
}
} }
+7 -430
View File
@@ -15,11 +15,10 @@ use crate::process_ext::HideWindow;
use crate::stats::{calculate_cost, StatsUpdateEvent, UsageStats}; use crate::stats::{calculate_cost, StatsUpdateEvent, UsageStats};
use crate::types::{ use crate::types::{
AgentEndEvent, AgentStartEvent, CharacterState, ClaudeMessage, ConnectionEvent, AgentEndEvent, AgentStartEvent, CharacterState, ClaudeMessage, ConnectionEvent,
ConnectionStatus, ContentBlock, CwdChangedEvent, ElicitationEvent, ElicitationResultEvent, ConnectionStatus, ContentBlock, ElicitationEvent, ElicitationResultEvent, MessageCost,
FileChangedEvent, MessageCost, OutputEvent, PermissionDeniedEvent, PermissionPromptEvent, OutputEvent, PermissionPromptEvent, PermissionPromptEventItem, QuestionOption, SessionEvent,
PermissionPromptEventItem, PostCompactEvent, QuestionOption, SessionEvent, StateChangeEvent, PostCompactEvent, StateChangeEvent, StopFailureEvent, TodoItem, TodoUpdateEvent,
StopFailureEvent, TaskCreatedEvent, TodoItem, TodoUpdateEvent, UserQuestionEvent, UserQuestionEvent, WorkingDirectoryEvent, WorktreeEvent, WorktreeInfo,
WorkingDirectoryEvent, WorktreeEvent, WorktreeInfo,
}; };
use parking_lot::RwLock; use parking_lot::RwLock;
use std::cell::RefCell; use std::cell::RefCell;
@@ -37,10 +36,7 @@ struct PendingToolUse {
tool_input: serde_json::Value, tool_input: serde_json::Value,
} }
// "Monitor" added in Claude Code v2.1.98 — it streams events and is observational in nature, const SEARCH_TOOLS: [&str; 5] = ["Read", "Glob", "Grep", "WebSearch", "WebFetch"];
// so it maps to the Searching character state. It may appear as name "Monitor" in tool_use
// blocks (confirmed by CLI source inspection; it is a local_bash with kind="monitor" internally).
const SEARCH_TOOLS: [&str; 6] = ["Read", "Glob", "Grep", "WebSearch", "WebFetch", "Monitor"];
const CODING_TOOLS: [&str; 3] = ["Edit", "Write", "NotebookEdit"]; const CODING_TOOLS: [&str; 3] = ["Edit", "Write", "NotebookEdit"];
fn detect_wsl() -> bool { fn detect_wsl() -> bool {
@@ -303,11 +299,6 @@ impl WslBridge {
cmd.arg("--worktree"); cmd.arg("--worktree");
} }
// Add bare flag if requested (v2.1.81+)
if options.bare_mode {
cmd.arg("--bare");
}
// Pass combined settings via --settings flag if any settings are specified // Pass combined settings via --settings flag if any settings are specified
{ {
let has_memory_dir = options let has_memory_dir = options
@@ -320,13 +311,8 @@ impl WslBridge {
.as_ref() .as_ref()
.map(|m| !m.is_empty()) .map(|m| !m.is_empty())
.unwrap_or(false); .unwrap_or(false);
let suppress_clear_context = !options.show_clear_context_on_plan_accept;
if has_memory_dir if has_memory_dir || has_overrides {
|| has_overrides
|| options.disable_skill_shell_execution
|| suppress_clear_context
{
let mut settings = serde_json::Map::new(); let mut settings = serde_json::Map::new();
if let Some(ref dir) = options.auto_memory_directory { if let Some(ref dir) = options.auto_memory_directory {
if !dir.is_empty() { if !dir.is_empty() {
@@ -343,18 +329,6 @@ impl WslBridge {
} }
} }
} }
if options.disable_skill_shell_execution {
settings.insert(
"disableSkillShellExecution".to_string(),
serde_json::Value::Bool(true),
);
}
if suppress_clear_context {
settings.insert(
"showClearContextOnPlanAccept".to_string(),
serde_json::Value::Bool(false),
);
}
if let Ok(settings_json) = serde_json::to_string(&settings) { if let Ok(settings_json) = serde_json::to_string(&settings) {
cmd.args(["--settings", &settings_json]); cmd.args(["--settings", &settings_json]);
} }
@@ -395,13 +369,6 @@ impl WslBridge {
cmd.env("ENABLE_CLAUDEAI_MCP_SERVERS", "false"); cmd.env("ENABLE_CLAUDEAI_MCP_SERVERS", "false");
} }
// Set custom model option if specified (v2.1.81+)
if let Some(ref custom_opt) = options.custom_model_option {
if !custom_opt.is_empty() {
cmd.env("ANTHROPIC_CUSTOM_MODEL_OPTION", custom_opt);
}
}
cmd cmd
} else { } else {
// Running on Windows - use wsl with bash login shell to ensure PATH is loaded // Running on Windows - use wsl with bash login shell to ensure PATH is loaded
@@ -469,14 +436,6 @@ impl WslBridge {
claude_cmd.push_str("ENABLE_CLAUDEAI_MCP_SERVERS=false "); claude_cmd.push_str("ENABLE_CLAUDEAI_MCP_SERVERS=false ");
} }
// Set custom model option if specified (v2.1.81+)
if let Some(ref custom_opt) = options.custom_model_option {
if !custom_opt.is_empty() {
let escaped = custom_opt.replace('\'', "'\\''");
claude_cmd.push_str(&format!("ANTHROPIC_CUSTOM_MODEL_OPTION='{}' ", escaped));
}
}
claude_cmd.push_str( claude_cmd.push_str(
"claude --output-format stream-json --input-format stream-json --verbose", "claude --output-format stream-json --input-format stream-json --verbose",
); );
@@ -527,11 +486,6 @@ impl WslBridge {
claude_cmd.push_str(" --worktree"); claude_cmd.push_str(" --worktree");
} }
// Add bare flag if requested (v2.1.81+)
if options.bare_mode {
claude_cmd.push_str(" --bare");
}
// Pass combined settings via --settings flag if any settings are specified // Pass combined settings via --settings flag if any settings are specified
{ {
let has_memory_dir = options let has_memory_dir = options
@@ -544,13 +498,8 @@ impl WslBridge {
.as_ref() .as_ref()
.map(|m| !m.is_empty()) .map(|m| !m.is_empty())
.unwrap_or(false); .unwrap_or(false);
let suppress_clear_context = !options.show_clear_context_on_plan_accept;
if has_memory_dir if has_memory_dir || has_overrides {
|| has_overrides
|| options.disable_skill_shell_execution
|| suppress_clear_context
{
let mut settings = serde_json::Map::new(); let mut settings = serde_json::Map::new();
if let Some(ref dir) = options.auto_memory_directory { if let Some(ref dir) = options.auto_memory_directory {
if !dir.is_empty() { if !dir.is_empty() {
@@ -567,18 +516,6 @@ impl WslBridge {
} }
} }
} }
if options.disable_skill_shell_execution {
settings.insert(
"disableSkillShellExecution".to_string(),
serde_json::Value::Bool(true),
);
}
if suppress_clear_context {
settings.insert(
"showClearContextOnPlanAccept".to_string(),
serde_json::Value::Bool(false),
);
}
if let Ok(settings_json) = serde_json::to_string(&settings) { if let Ok(settings_json) = serde_json::to_string(&settings) {
let escaped = settings_json.replace('\'', "'\\''"); let escaped = settings_json.replace('\'', "'\\''");
claude_cmd.push_str(&format!(" --settings '{}'", escaped)); claude_cmd.push_str(&format!(" --settings '{}'", escaped));
@@ -1141,10 +1078,6 @@ fn handle_stderr(
let is_elicitation_result = line.contains("[ElicitationResult Hook]"); let is_elicitation_result = line.contains("[ElicitationResult Hook]");
let is_stop_failure = line.contains("[StopFailure Hook]"); let is_stop_failure = line.contains("[StopFailure Hook]");
let is_post_compact = line.contains("[PostCompact Hook]"); let is_post_compact = line.contains("[PostCompact Hook]");
let is_cwd_changed = line.contains("[CwdChanged Hook]");
let is_file_changed = line.contains("[FileChanged Hook]");
let is_task_created = line.contains("[TaskCreated Hook]");
let is_permission_denied = line.contains("[PermissionDenied Hook]");
let line_type = if is_worktree_create || is_worktree_remove { let line_type = if is_worktree_create || is_worktree_remove {
"worktree" "worktree"
@@ -1156,14 +1089,6 @@ fn handle_stderr(
"error" "error"
} else if is_post_compact { } else if is_post_compact {
"compact-prompt" "compact-prompt"
} else if is_cwd_changed {
"cwd-changed"
} else if is_file_changed {
"file-changed"
} else if is_task_created {
"task-created"
} else if is_permission_denied {
"permission-denied"
} else { } else {
"error" "error"
}; };
@@ -1302,124 +1227,6 @@ fn handle_stderr(
parent_tool_use_id: None, parent_tool_use_id: None,
}, },
); );
} else if is_cwd_changed {
let data = parse_cwd_changed_hook(&line);
let friendly_content =
format!("Working directory changed to: {}", data.cwd);
let _ = app.emit(
"claude:cwd-changed",
CwdChangedEvent {
cwd: data.cwd,
conversation_id: conversation_id.clone(),
},
);
let _ = app.emit(
"claude:output",
OutputEvent {
line_type: "cwd-changed".to_string(),
content: friendly_content,
tool_name: None,
conversation_id: conversation_id.clone(),
cost: None,
parent_tool_use_id: None,
},
);
} else if is_file_changed {
let data = parse_file_changed_hook(&line);
let friendly_content = if data.file.is_empty() {
"File changed".to_string()
} else {
format!("File changed: {}", data.file)
};
let _ = app.emit(
"claude:file-changed",
FileChangedEvent {
file: data.file,
conversation_id: conversation_id.clone(),
},
);
let _ = app.emit(
"claude:output",
OutputEvent {
line_type: "file-changed".to_string(),
content: friendly_content,
tool_name: None,
conversation_id: conversation_id.clone(),
cost: None,
parent_tool_use_id: None,
},
);
} else if is_task_created {
let data = parse_task_created_hook(&line);
let friendly_content = match data.description.as_deref() {
Some(desc) if !desc.is_empty() => format!("Task created: {}", desc),
_ => "Task created".to_string(),
};
let _ = app.emit(
"claude:task-created",
TaskCreatedEvent {
task_id: data.task_id,
description: data.description,
parent_tool_use_id: data.parent_tool_use_id,
conversation_id: conversation_id.clone(),
},
);
let _ = app.emit(
"claude:output",
OutputEvent {
line_type: "task-created".to_string(),
content: friendly_content,
tool_name: None,
conversation_id: conversation_id.clone(),
cost: None,
parent_tool_use_id: None,
},
);
} else if is_permission_denied {
let data = parse_permission_denied_hook(&line);
let friendly_content = match (data.tool_name.as_deref(), data.reason.as_deref()) {
(Some(tool), Some(reason)) => {
format!("Permission denied for {}: {}", tool, reason)
}
(Some(tool), None) => format!("Permission denied for {}", tool),
_ => "Permission denied".to_string(),
};
let _ = app.emit(
"claude:state-change",
StateChangeEvent {
state: CharacterState::Permission,
tool_name: data.tool_name.clone(),
conversation_id: conversation_id.clone(),
},
);
let _ = app.emit(
"claude:permission-denied",
PermissionDeniedEvent {
tool_name: data.tool_name,
reason: data.reason,
conversation_id: conversation_id.clone(),
},
);
let _ = app.emit(
"claude:output",
OutputEvent {
line_type: "permission-denied".to_string(),
content: friendly_content,
tool_name: None,
conversation_id: conversation_id.clone(),
cost: None,
parent_tool_use_id: None,
},
);
} else { } else {
let _ = app.emit( let _ = app.emit(
"claude:output", "claude:output",
@@ -1633,85 +1440,6 @@ fn parse_post_compact_hook(line: &str) -> PostCompactData {
PostCompactData { session_id } PostCompactData { session_id }
} }
#[derive(Debug)]
struct CwdChangedData {
cwd: String,
}
fn parse_cwd_changed_hook(line: &str) -> CwdChangedData {
let cwd = extract_quoted_value(line, "cwd")
.or_else(|| extract_quoted_value(line, "path"))
.or_else(|| {
line.split("[CwdChanged Hook]")
.nth(1)
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
})
.unwrap_or_default();
CwdChangedData { cwd }
}
#[derive(Debug)]
struct FileChangedData {
file: String,
}
fn parse_file_changed_hook(line: &str) -> FileChangedData {
let file = extract_quoted_value(line, "file")
.or_else(|| extract_quoted_value(line, "path"))
.or_else(|| {
line.split("[FileChanged Hook]")
.nth(1)
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
})
.unwrap_or_default();
FileChangedData { file }
}
#[derive(Debug)]
struct TaskCreatedData {
task_id: Option<String>,
description: Option<String>,
parent_tool_use_id: Option<String>,
}
fn parse_task_created_hook(line: &str) -> TaskCreatedData {
let task_id = extract_debug_string_value(line, "task_id")
.or_else(|| extract_quoted_value(line, "task_id"));
let description = extract_quoted_value(line, "description")
.or_else(|| extract_quoted_value(line, "prompt"));
let parent_tool_use_id = if line.contains("parent_tool_use_id=Some") {
line.split("parent_tool_use_id=Some(\"")
.nth(1)
.and_then(|s| s.split('"').next())
.map(|s| s.to_string())
} else {
None
};
TaskCreatedData { task_id, description, parent_tool_use_id }
}
#[derive(Debug)]
struct PermissionDeniedData {
tool_name: Option<String>,
reason: Option<String>,
}
fn parse_permission_denied_hook(line: &str) -> PermissionDeniedData {
let tool_name = extract_quoted_value(line, "tool_name")
.or_else(|| extract_quoted_value(line, "tool"))
.or_else(|| extract_debug_string_value(line, "tool_name"));
let reason = extract_quoted_value(line, "reason")
.or_else(|| extract_quoted_value(line, "message"));
PermissionDeniedData { tool_name, reason }
}
/// Extracts a double-quoted string value from a `key="value"` pair in a hook line. /// Extracts a double-quoted string value from a `key="value"` pair in a hook line.
/// Handles escape sequences within the quoted value. /// Handles escape sequences within the quoted value.
fn extract_quoted_value(line: &str, key: &str) -> Option<String> { fn extract_quoted_value(line: &str, key: &str) -> Option<String> {
@@ -2169,9 +1897,6 @@ fn process_json_line(
usage, usage,
duration_ms, duration_ms,
num_turns, num_turns,
fast_mode_state,
model_usage,
total_cost_usd,
} => { } => {
tracing::info!( tracing::info!(
"Received Result message: subtype={}, has_denials={}, denial_count={:?}", "Received Result message: subtype={}, has_denials={}, denial_count={:?}",
@@ -2256,25 +1981,6 @@ fn process_json_line(
}); });
} }
// Log fast mode state if present (v2.1.81+)
if let Some(ref state) = fast_mode_state {
tracing::debug!("Fast mode state: {}", state);
}
// Log per-model usage if available (v2.1.81+)
if let Some(ref model_usage_val) = model_usage {
if let Some(map) = model_usage_val.as_object() {
for (model_name, _usage_val) in map {
tracing::debug!("Per-model usage logged for: {}", model_name);
}
}
}
// Log authoritative cost from Claude Code if available (v2.1.81+)
if let Some(auth_cost) = total_cost_usd {
tracing::debug!("Authoritative total cost from Claude Code: ${:.6}", auth_cost);
}
// Clear tracking fields since request completed successfully // Clear tracking fields since request completed successfully
{ {
let mut stats_guard = stats.write(); let mut stats_guard = stats.write();
@@ -2840,11 +2546,6 @@ mod tests {
get_tool_state("WebFetch"), get_tool_state("WebFetch"),
CharacterState::Searching CharacterState::Searching
)); ));
// Monitor tool added in v2.1.98 — observational/streaming, maps to Searching
assert!(matches!(
get_tool_state("Monitor"),
CharacterState::Searching
));
} }
#[test] #[test]
@@ -3887,130 +3588,6 @@ mod tests {
assert_eq!(data.session_id, None); assert_eq!(data.session_id, None);
} }
#[test]
fn test_parse_cwd_changed_hook_with_cwd_key() {
let line = r#"[CwdChanged Hook] cwd="/home/naomi/code/my-project""#;
let data = parse_cwd_changed_hook(line);
assert_eq!(data.cwd, "/home/naomi/code/my-project");
}
#[test]
fn test_parse_cwd_changed_hook_with_path_key() {
let line = r#"[CwdChanged Hook] path="/tmp/workspace""#;
let data = parse_cwd_changed_hook(line);
assert_eq!(data.cwd, "/tmp/workspace");
}
#[test]
fn test_parse_cwd_changed_hook_bare_path_fallback() {
let line = "[CwdChanged Hook] /home/naomi/code/project";
let data = parse_cwd_changed_hook(line);
assert_eq!(data.cwd, "/home/naomi/code/project");
}
#[test]
fn test_parse_cwd_changed_hook_empty_line() {
let line = "[CwdChanged Hook]";
let data = parse_cwd_changed_hook(line);
assert_eq!(data.cwd, "");
}
#[test]
fn test_parse_file_changed_hook_with_file_key() {
let line = r#"[FileChanged Hook] file="/home/naomi/code/project/src/main.rs""#;
let data = parse_file_changed_hook(line);
assert_eq!(data.file, "/home/naomi/code/project/src/main.rs");
}
#[test]
fn test_parse_file_changed_hook_with_path_key() {
let line = r#"[FileChanged Hook] path="/tmp/test.txt""#;
let data = parse_file_changed_hook(line);
assert_eq!(data.file, "/tmp/test.txt");
}
#[test]
fn test_parse_file_changed_hook_bare_path_fallback() {
let line = "[FileChanged Hook] /home/naomi/code/project/README.md";
let data = parse_file_changed_hook(line);
assert_eq!(data.file, "/home/naomi/code/project/README.md");
}
#[test]
fn test_parse_file_changed_hook_empty_line() {
let line = "[FileChanged Hook]";
let data = parse_file_changed_hook(line);
assert_eq!(data.file, "");
}
#[test]
fn test_parse_task_created_hook_with_all_fields() {
let line = r#"[TaskCreated Hook] task_id=Some("task-abc123"), description="Explore the codebase", parent_tool_use_id=Some("toolu_xyz")"#;
let data = parse_task_created_hook(line);
assert_eq!(data.task_id, Some("task-abc123".to_string()));
assert_eq!(data.description, Some("Explore the codebase".to_string()));
assert_eq!(data.parent_tool_use_id, Some("toolu_xyz".to_string()));
}
#[test]
fn test_parse_task_created_hook_with_description_only() {
let line = r#"[TaskCreated Hook] description="Search for relevant files""#;
let data = parse_task_created_hook(line);
assert_eq!(data.description, Some("Search for relevant files".to_string()));
assert_eq!(data.task_id, None);
assert_eq!(data.parent_tool_use_id, None);
}
#[test]
fn test_parse_task_created_hook_no_parent() {
let line = r#"[TaskCreated Hook] task_id=Some("task-001"), description="Run tests""#;
let data = parse_task_created_hook(line);
assert_eq!(data.task_id, Some("task-001".to_string()));
assert_eq!(data.description, Some("Run tests".to_string()));
assert_eq!(data.parent_tool_use_id, None);
}
#[test]
fn test_parse_task_created_hook_empty_line() {
let line = "[TaskCreated Hook]";
let data = parse_task_created_hook(line);
assert_eq!(data.task_id, None);
assert_eq!(data.description, None);
assert_eq!(data.parent_tool_use_id, None);
}
#[test]
fn test_parse_permission_denied_hook_with_all_fields() {
let line = r#"[PermissionDenied Hook] tool_name="Bash", reason="Tool not in allow list""#;
let data = parse_permission_denied_hook(line);
assert_eq!(data.tool_name, Some("Bash".to_string()));
assert_eq!(data.reason, Some("Tool not in allow list".to_string()));
}
#[test]
fn test_parse_permission_denied_hook_tool_only() {
let line = r#"[PermissionDenied Hook] tool_name="Edit""#;
let data = parse_permission_denied_hook(line);
assert_eq!(data.tool_name, Some("Edit".to_string()));
assert_eq!(data.reason, None);
}
#[test]
fn test_parse_permission_denied_hook_tool_key_alias() {
let line = r#"[PermissionDenied Hook] tool="Write", reason="Workspace not trusted""#;
let data = parse_permission_denied_hook(line);
assert_eq!(data.tool_name, Some("Write".to_string()));
assert_eq!(data.reason, Some("Workspace not trusted".to_string()));
}
#[test]
fn test_parse_permission_denied_hook_empty_line() {
let line = "[PermissionDenied Hook]";
let data = parse_permission_denied_hook(line);
assert_eq!(data.tool_name, None);
assert_eq!(data.reason, None);
}
#[test] #[test]
fn test_build_stop_failure_message_no_fields() { fn test_build_stop_failure_message_no_fields() {
let data = StopFailureData { let data = StopFailureData {
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "hikari-desktop", "productName": "hikari-desktop",
"version": "1.14.0", "version": "1.13.0",
"identifier": "com.naomi.hikari-desktop", "identifier": "com.naomi.hikari-desktop",
"build": { "build": {
"beforeDevCommand": "pnpm dev", "beforeDevCommand": "pnpm dev",
-10
View File
@@ -67,16 +67,11 @@ async function changeDirectory(path: string): Promise<void> {
use_worktree: config.use_worktree ?? false, use_worktree: config.use_worktree ?? false,
disable_1m_context: config.disable_1m_context ?? false, disable_1m_context: config.disable_1m_context ?? false,
max_output_tokens: config.max_output_tokens ?? null, max_output_tokens: config.max_output_tokens ?? null,
disable_cron: config.disable_cron ?? false,
disable_skill_shell_execution: config.disable_skill_shell_execution ?? false,
include_git_instructions: config.include_git_instructions ?? true, include_git_instructions: config.include_git_instructions ?? true,
enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true, enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true,
auto_memory_directory: config.auto_memory_directory || null, auto_memory_directory: config.auto_memory_directory || null,
model_overrides: config.model_overrides || null, model_overrides: config.model_overrides || null,
session_name: null, session_name: null,
bare_mode: config.bare_mode ?? false,
show_clear_context_on_plan_accept: config.show_clear_context_on_plan_accept ?? true,
custom_model_option: config.custom_model_option || null,
}, },
}); });
@@ -154,16 +149,11 @@ async function startNewConversation(): Promise<void> {
use_worktree: config.use_worktree ?? false, use_worktree: config.use_worktree ?? false,
disable_1m_context: config.disable_1m_context ?? false, disable_1m_context: config.disable_1m_context ?? false,
max_output_tokens: config.max_output_tokens ?? null, max_output_tokens: config.max_output_tokens ?? null,
disable_cron: config.disable_cron ?? false,
disable_skill_shell_execution: config.disable_skill_shell_execution ?? false,
include_git_instructions: config.include_git_instructions ?? true, include_git_instructions: config.include_git_instructions ?? true,
enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true, enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true,
auto_memory_directory: config.auto_memory_directory || null, auto_memory_directory: config.auto_memory_directory || null,
model_overrides: config.model_overrides || null, model_overrides: config.model_overrides || null,
session_name: null, session_name: null,
bare_mode: config.bare_mode ?? false,
show_clear_context_on_plan_accept: config.show_clear_context_on_plan_accept ?? true,
custom_model_option: config.custom_model_option || null,
}, },
}); });
+1 -1
View File
@@ -2,7 +2,7 @@
import { invoke } from "@tauri-apps/api/core"; import { invoke } from "@tauri-apps/api/core";
import { onMount } from "svelte"; import { onMount } from "svelte";
const SUPPORTED_CLI_VERSION = "2.1.104"; const SUPPORTED_CLI_VERSION = "2.1.80";
let installedVersion = $state("Loading..."); let installedVersion = $state("Loading...");
let latestNpmVersion = $state<string | null>(null); let latestNpmVersion = $state<string | null>(null);
-144
View File
@@ -63,10 +63,6 @@
enable_claudeai_mcp_servers: true, enable_claudeai_mcp_servers: true,
auto_memory_directory: null, auto_memory_directory: null,
model_overrides: null, model_overrides: null,
disable_skill_shell_execution: false,
bare_mode: false,
show_clear_context_on_plan_accept: true,
custom_model_option: null,
max_output_tokens: null, max_output_tokens: null,
trusted_workspaces: [], trusted_workspaces: [],
background_image_path: null, background_image_path: null,
@@ -89,9 +85,6 @@
let customUiFontStatus: string | null = $state(null); let customUiFontStatus: string | null = $state(null);
let modelOverridesJson = $state(""); let modelOverridesJson = $state("");
let modelOverridesError: string | null = $state(null); let modelOverridesError: string | null = $state(null);
let globalClaudeMd = $state("");
let globalClaudeMdSaving = $state(false);
let globalClaudeMdSaveStatus: string | null = $state(null);
interface AuthStatus { interface AuthStatus {
is_logged_in: boolean; is_logged_in: boolean;
@@ -129,9 +122,6 @@
if (open && authStatus === null) { if (open && authStatus === null) {
void refreshAuthStatus(); void refreshAuthStatus();
} }
if (open) {
void loadGlobalClaudeMd();
}
}); });
configStore.saveError.subscribe((error) => { configStore.saveError.subscribe((error) => {
@@ -207,30 +197,6 @@
} }
} }
async function loadGlobalClaudeMd() {
try {
globalClaudeMd = await invoke<string>("get_global_claude_md");
} catch (error) {
console.error("Failed to load global CLAUDE.md:", error);
}
}
async function saveGlobalClaudeMd() {
globalClaudeMdSaving = true;
globalClaudeMdSaveStatus = null;
try {
await invoke("save_global_claude_md", { content: globalClaudeMd });
globalClaudeMdSaveStatus = "Saved!";
setTimeout(() => {
globalClaudeMdSaveStatus = null;
}, 2000);
} catch (error) {
globalClaudeMdSaveStatus = `Error: ${error}`;
} finally {
globalClaudeMdSaving = false;
}
}
async function handleSave() { async function handleSave() {
isSaving = true; isSaving = true;
saveError = null; saveError = null;
@@ -619,22 +585,6 @@
</p> </p>
</div> </div>
<!-- Disable Skill Shell Execution -->
<div class="mb-4">
<label class="flex items-center gap-3 cursor-pointer">
<input
type="checkbox"
bind:checked={config.disable_skill_shell_execution}
class="w-4 h-4 rounded border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--accent-primary)] focus:ring-[var(--accent-primary)]"
/>
<span class="text-sm text-[var(--text-primary)]">Disable skill shell execution</span>
</label>
<p class="text-xs text-[var(--text-tertiary)] mt-1 ml-7">
Passes <code class="font-mono">disableSkillShellExecution: true</code> to prevent skill scripts
from executing shell commands (requires Claude Code v2.1.91+)
</p>
</div>
<!-- Include Git Instructions --> <!-- Include Git Instructions -->
<div class="mb-4"> <div class="mb-4">
<label class="flex items-center gap-3 cursor-pointer"> <label class="flex items-center gap-3 cursor-pointer">
@@ -712,59 +662,6 @@
defaults. defaults.
</p> </p>
</div> </div>
<!-- Bare Mode -->
<div class="mb-4">
<label class="flex items-center gap-3 cursor-pointer">
<input
type="checkbox"
bind:checked={config.bare_mode}
class="w-4 h-4 rounded border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--accent-primary)] focus:ring-[var(--accent-primary)]"
/>
<span class="text-sm text-[var(--text-primary)]">Bare mode</span>
</label>
<p class="text-xs text-[var(--text-tertiary)] mt-1 ml-7">
Passes <code class="font-mono">--bare</code> to suppress UI chrome — useful for scripted
headless <code class="font-mono">-p</code> calls (requires Claude Code v2.1.81+)
</p>
</div>
<!-- Show Clear Context on Plan Accept -->
<div class="mb-4">
<label class="flex items-center gap-3 cursor-pointer">
<input
type="checkbox"
bind:checked={config.show_clear_context_on_plan_accept}
class="w-4 h-4 rounded border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--accent-primary)] focus:ring-[var(--accent-primary)]"
/>
<span class="text-sm text-[var(--text-primary)]"
>Show clear context prompt on plan accept</span
>
</label>
<p class="text-xs text-[var(--text-tertiary)] mt-1 ml-7">
When enabled, prompts to clear context when accepting a plan. Passes
<code class="font-mono">showClearContextOnPlanAccept: false</code> in
<code class="font-mono">--settings</code> when disabled (requires Claude Code v2.1.81+)
</p>
</div>
<!-- Custom Model Option -->
<div class="mb-4">
<label for="custom-model-option" class="block text-sm text-[var(--text-primary)] mb-1">
Custom model option <span class="text-[var(--text-tertiary)]">(optional)</span>
</label>
<input
id="custom-model-option"
type="text"
placeholder="Leave blank to use default"
bind:value={config.custom_model_option}
class="w-full px-3 py-2 text-sm bg-[var(--bg-primary)] border border-[var(--border-color)] rounded text-[var(--text-primary)] placeholder-[var(--text-tertiary)] focus:outline-none focus:border-[var(--accent-primary)]"
/>
<p class="text-xs text-[var(--text-tertiary)] mt-1">
Sets <code class="font-mono">ANTHROPIC_CUSTOM_MODEL_OPTION</code> environment variable for custom
model providers (requires Claude Code v2.1.81+)
</p>
</div>
</section> </section>
<!-- Greeting Section --> <!-- Greeting Section -->
@@ -805,47 +702,6 @@
{/if} {/if}
</section> </section>
<!-- Global Instructions Section -->
<section class="mb-6">
<h3 class="text-sm font-medium text-[var(--accent-primary)] uppercase tracking-wider mb-3">
Global Instructions
</h3>
<div class="mb-2">
<label for="global-claude-md" class="block text-sm text-[var(--text-secondary)] mb-1">
~/.claude/CLAUDE.md
</label>
<textarea
id="global-claude-md"
bind:value={globalClaudeMd}
rows="12"
placeholder="Add persistent instructions for all Claude Code sessions..."
class="w-full px-3 py-2 bg-[var(--bg-primary)] border border-[var(--border-color)] rounded-lg text-[var(--text-primary)] font-mono text-sm focus:outline-none focus:border-[var(--accent-primary)] resize-y"
></textarea>
</div>
<div class="flex items-center gap-2">
<button
onclick={saveGlobalClaudeMd}
disabled={globalClaudeMdSaving}
class="px-3 py-1.5 text-sm bg-[var(--accent-primary)] text-white rounded hover:opacity-90 disabled:opacity-50 disabled:cursor-not-allowed"
>
{globalClaudeMdSaving ? "Saving..." : "Save"}
</button>
{#if globalClaudeMdSaveStatus}
<span
class="text-xs {globalClaudeMdSaveStatus.startsWith('Error')
? 'text-red-500'
: 'text-green-500'}"
>
{globalClaudeMdSaveStatus}
</span>
{/if}
</div>
<p class="text-xs text-[var(--text-tertiary)] mt-2">
Persistent instructions applied to all Claude Code sessions. Changes take effect on the next
session start.
</p>
</section>
<!-- MCP Servers Section --> <!-- MCP Servers Section -->
<section class="mb-6"> <section class="mb-6">
<h3 class="text-sm font-medium text-[var(--accent-primary)] uppercase tracking-wider mb-3"> <h3 class="text-sm font-medium text-[var(--accent-primary)] uppercase tracking-wider mb-3">
@@ -68,16 +68,11 @@
allowed_tools: grantedToolsList, allowed_tools: grantedToolsList,
use_worktree: config.use_worktree ?? false, use_worktree: config.use_worktree ?? false,
disable_1m_context: config.disable_1m_context ?? false, disable_1m_context: config.disable_1m_context ?? false,
disable_cron: config.disable_cron ?? false,
disable_skill_shell_execution: config.disable_skill_shell_execution ?? false,
include_git_instructions: config.include_git_instructions ?? true, include_git_instructions: config.include_git_instructions ?? true,
enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true, enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true,
auto_memory_directory: config.auto_memory_directory || null, auto_memory_directory: config.auto_memory_directory || null,
model_overrides: config.model_overrides || null, model_overrides: config.model_overrides || null,
session_name: null, session_name: null,
bare_mode: config.bare_mode ?? false,
show_clear_context_on_plan_accept: config.show_clear_context_on_plan_accept ?? true,
custom_model_option: config.custom_model_option || null,
}, },
}); });
-5
View File
@@ -402,16 +402,11 @@ User: ${formattedMessage}`;
allowed_tools: allAllowedTools, allowed_tools: allAllowedTools,
use_worktree: config.use_worktree ?? false, use_worktree: config.use_worktree ?? false,
disable_1m_context: config.disable_1m_context ?? false, disable_1m_context: config.disable_1m_context ?? false,
disable_cron: config.disable_cron ?? false,
disable_skill_shell_execution: config.disable_skill_shell_execution ?? false,
include_git_instructions: config.include_git_instructions ?? true, include_git_instructions: config.include_git_instructions ?? true,
enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true, enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true,
auto_memory_directory: config.auto_memory_directory || null, auto_memory_directory: config.auto_memory_directory || null,
model_overrides: config.model_overrides || null, model_overrides: config.model_overrides || null,
session_name: null, session_name: null,
bare_mode: config.bare_mode ?? false,
show_clear_context_on_plan_accept: config.show_clear_context_on_plan_accept ?? true,
custom_model_option: config.custom_model_option || null,
}, },
}); });
@@ -89,16 +89,11 @@
allowed_tools: [...new Set([...newGrantedTools, ...config.auto_granted_tools])], allowed_tools: [...new Set([...newGrantedTools, ...config.auto_granted_tools])],
use_worktree: config.use_worktree ?? false, use_worktree: config.use_worktree ?? false,
disable_1m_context: config.disable_1m_context ?? false, disable_1m_context: config.disable_1m_context ?? false,
disable_cron: config.disable_cron ?? false,
disable_skill_shell_execution: config.disable_skill_shell_execution ?? false,
include_git_instructions: config.include_git_instructions ?? true, include_git_instructions: config.include_git_instructions ?? true,
enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true, enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true,
auto_memory_directory: config.auto_memory_directory || null, auto_memory_directory: config.auto_memory_directory || null,
model_overrides: config.model_overrides || null, model_overrides: config.model_overrides || null,
session_name: null, session_name: null,
bare_mode: config.bare_mode ?? false,
show_clear_context_on_plan_accept: config.show_clear_context_on_plan_accept ?? true,
custom_model_option: config.custom_model_option || null,
}, },
}); });
-16
View File
@@ -93,10 +93,6 @@
enable_claudeai_mcp_servers: true, enable_claudeai_mcp_servers: true,
auto_memory_directory: null, auto_memory_directory: null,
model_overrides: null, model_overrides: null,
disable_skill_shell_execution: false,
bare_mode: false,
show_clear_context_on_plan_accept: true,
custom_model_option: null,
}); });
let streamerModeActive = $state(false); let streamerModeActive = $state(false);
@@ -178,17 +174,11 @@
use_worktree: currentConfig.use_worktree ?? false, use_worktree: currentConfig.use_worktree ?? false,
disable_1m_context: currentConfig.disable_1m_context ?? false, disable_1m_context: currentConfig.disable_1m_context ?? false,
max_output_tokens: currentConfig.max_output_tokens ?? null, max_output_tokens: currentConfig.max_output_tokens ?? null,
disable_cron: currentConfig.disable_cron ?? false,
disable_skill_shell_execution: currentConfig.disable_skill_shell_execution ?? false,
include_git_instructions: currentConfig.include_git_instructions ?? true, include_git_instructions: currentConfig.include_git_instructions ?? true,
enable_claudeai_mcp_servers: currentConfig.enable_claudeai_mcp_servers ?? true, enable_claudeai_mcp_servers: currentConfig.enable_claudeai_mcp_servers ?? true,
auto_memory_directory: currentConfig.auto_memory_directory || null, auto_memory_directory: currentConfig.auto_memory_directory || null,
model_overrides: currentConfig.model_overrides || null, model_overrides: currentConfig.model_overrides || null,
session_name: activeConversationForName?.name || null, session_name: activeConversationForName?.name || null,
bare_mode: currentConfig.bare_mode ?? false,
show_clear_context_on_plan_accept:
currentConfig.show_clear_context_on_plan_accept ?? true,
custom_model_option: currentConfig.custom_model_option || null,
}, },
}); });
@@ -346,17 +336,11 @@
use_worktree: currentConfig.use_worktree ?? false, use_worktree: currentConfig.use_worktree ?? false,
disable_1m_context: currentConfig.disable_1m_context ?? false, disable_1m_context: currentConfig.disable_1m_context ?? false,
max_output_tokens: currentConfig.max_output_tokens ?? null, max_output_tokens: currentConfig.max_output_tokens ?? null,
disable_cron: currentConfig.disable_cron ?? false,
disable_skill_shell_execution: currentConfig.disable_skill_shell_execution ?? false,
include_git_instructions: currentConfig.include_git_instructions ?? true, include_git_instructions: currentConfig.include_git_instructions ?? true,
enable_claudeai_mcp_servers: currentConfig.enable_claudeai_mcp_servers ?? true, enable_claudeai_mcp_servers: currentConfig.enable_claudeai_mcp_servers ?? true,
auto_memory_directory: currentConfig.auto_memory_directory || null, auto_memory_directory: currentConfig.auto_memory_directory || null,
model_overrides: currentConfig.model_overrides || null, model_overrides: currentConfig.model_overrides || null,
session_name: null, session_name: null,
bare_mode: currentConfig.bare_mode ?? false,
show_clear_context_on_plan_accept:
currentConfig.show_clear_context_on_plan_accept ?? true,
custom_model_option: currentConfig.custom_model_option || null,
}, },
}); });
-5
View File
@@ -218,16 +218,11 @@
use_worktree: cfg.use_worktree ?? false, use_worktree: cfg.use_worktree ?? false,
disable_1m_context: cfg.disable_1m_context ?? false, disable_1m_context: cfg.disable_1m_context ?? false,
max_output_tokens: cfg.max_output_tokens ?? null, max_output_tokens: cfg.max_output_tokens ?? null,
disable_cron: cfg.disable_cron ?? false,
disable_skill_shell_execution: cfg.disable_skill_shell_execution ?? false,
include_git_instructions: cfg.include_git_instructions ?? true, include_git_instructions: cfg.include_git_instructions ?? true,
enable_claudeai_mcp_servers: cfg.enable_claudeai_mcp_servers ?? true, enable_claudeai_mcp_servers: cfg.enable_claudeai_mcp_servers ?? true,
auto_memory_directory: cfg.auto_memory_directory || null, auto_memory_directory: cfg.auto_memory_directory || null,
model_overrides: cfg.model_overrides || null, model_overrides: cfg.model_overrides || null,
session_name: null, session_name: null,
bare_mode: cfg.bare_mode ?? false,
show_clear_context_on_plan_accept: cfg.show_clear_context_on_plan_accept ?? true,
custom_model_option: cfg.custom_model_option || null,
}, },
}); });
} catch (error) { } catch (error) {
@@ -108,16 +108,11 @@
allowed_tools: grantedToolsList, allowed_tools: grantedToolsList,
use_worktree: config.use_worktree ?? false, use_worktree: config.use_worktree ?? false,
disable_1m_context: config.disable_1m_context ?? false, disable_1m_context: config.disable_1m_context ?? false,
disable_cron: config.disable_cron ?? false,
disable_skill_shell_execution: config.disable_skill_shell_execution ?? false,
include_git_instructions: config.include_git_instructions ?? true, include_git_instructions: config.include_git_instructions ?? true,
enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true, enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true,
auto_memory_directory: config.auto_memory_directory || null, auto_memory_directory: config.auto_memory_directory || null,
model_overrides: config.model_overrides || null, model_overrides: config.model_overrides || null,
session_name: null, session_name: null,
bare_mode: config.bare_mode ?? false,
show_clear_context_on_plan_accept: config.show_clear_context_on_plan_accept ?? true,
custom_model_option: config.custom_model_option || null,
}, },
}); });
-12
View File
@@ -225,10 +225,6 @@ describe("config store", () => {
enable_claudeai_mcp_servers: true, enable_claudeai_mcp_servers: true,
auto_memory_directory: null, auto_memory_directory: null,
model_overrides: null, model_overrides: null,
disable_skill_shell_execution: false,
bare_mode: false,
show_clear_context_on_plan_accept: true,
custom_model_option: null,
}; };
expect(config.model).toBe("claude-sonnet-4"); expect(config.model).toBe("claude-sonnet-4");
@@ -293,10 +289,6 @@ describe("config store", () => {
enable_claudeai_mcp_servers: true, enable_claudeai_mcp_servers: true,
auto_memory_directory: null, auto_memory_directory: null,
model_overrides: null, model_overrides: null,
disable_skill_shell_execution: false,
bare_mode: false,
show_clear_context_on_plan_accept: true,
custom_model_option: null,
}; };
expect(config.model).toBeNull(); expect(config.model).toBeNull();
@@ -916,10 +908,6 @@ describe("config store", () => {
enable_claudeai_mcp_servers: true, enable_claudeai_mcp_servers: true,
auto_memory_directory: null, auto_memory_directory: null,
model_overrides: null, model_overrides: null,
disable_skill_shell_execution: false,
bare_mode: false,
show_clear_context_on_plan_accept: true,
custom_model_option: null,
}; };
const mockInvokeImpl = vi.mocked(invoke); const mockInvokeImpl = vi.mocked(invoke);
-12
View File
@@ -91,14 +91,6 @@ export interface HikariConfig {
auto_memory_directory: string | null; auto_memory_directory: string | null;
// Model overrides for provider-specific model IDs (AWS Bedrock, Google Vertex, etc.) // Model overrides for provider-specific model IDs (AWS Bedrock, Google Vertex, etc.)
model_overrides: Record<string, string> | null; model_overrides: Record<string, string> | null;
// Prevents skill scripts from executing shell commands (Claude Code v2.1.91+)
disable_skill_shell_execution: boolean;
// Bare mode — suppress UI chrome for scripted headless -p calls (v2.1.81+)
bare_mode: boolean;
// Show clear context dialog when accepting a plan (v2.1.81+)
show_clear_context_on_plan_accept: boolean;
// Custom model option env var (v2.1.81+)
custom_model_option: string | null;
} }
const defaultConfig: HikariConfig = { const defaultConfig: HikariConfig = {
@@ -157,10 +149,6 @@ const defaultConfig: HikariConfig = {
enable_claudeai_mcp_servers: true, enable_claudeai_mcp_servers: true,
auto_memory_directory: null, auto_memory_directory: null,
model_overrides: null, model_overrides: null,
disable_skill_shell_execution: false,
bare_mode: false,
show_clear_context_on_plan_accept: true,
custom_model_option: null,
}; };
function createConfigStore() { function createConfigStore() {