generated from nhcarrigan/template
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 648743b862 |
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hikari-desktop",
|
||||
"version": "1.6.0",
|
||||
"version": "1.5.1",
|
||||
"description": "",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -77,7 +77,7 @@
|
||||
"@testing-library/jest-dom": "^6.9.1",
|
||||
"@testing-library/svelte": "^5.3.1",
|
||||
"@vitest/coverage-v8": "^4.0.18",
|
||||
"eslint": "^9.39.2",
|
||||
"eslint": "10.0.0",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-svelte": "^3.14.0",
|
||||
"globals": "^17.0.0",
|
||||
|
||||
Generated
+132
-193
@@ -154,14 +154,14 @@ importers:
|
||||
specifier: ^4.0.18
|
||||
version: 4.0.18(vitest@4.0.17(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2))
|
||||
eslint:
|
||||
specifier: ^9.39.2
|
||||
version: 9.39.2(jiti@2.6.1)
|
||||
specifier: 10.0.0
|
||||
version: 10.0.0(jiti@2.6.1)
|
||||
eslint-config-prettier:
|
||||
specifier: ^10.1.8
|
||||
version: 10.1.8(eslint@9.39.2(jiti@2.6.1))
|
||||
version: 10.1.8(eslint@10.0.0(jiti@2.6.1))
|
||||
eslint-plugin-svelte:
|
||||
specifier: ^3.14.0
|
||||
version: 3.14.0(eslint@9.39.2(jiti@2.6.1))(svelte@5.46.3)
|
||||
version: 3.14.0(eslint@10.0.0(jiti@2.6.1))(svelte@5.46.3)
|
||||
globals:
|
||||
specifier: ^17.0.0
|
||||
version: 17.0.0
|
||||
@@ -188,7 +188,7 @@ importers:
|
||||
version: 5.6.3
|
||||
typescript-eslint:
|
||||
specifier: ^8.53.0
|
||||
version: 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3)
|
||||
version: 8.53.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.6.3)
|
||||
vite:
|
||||
specifier: ^6.0.3
|
||||
version: 6.4.1(jiti@2.6.1)(lightningcss@1.30.2)
|
||||
@@ -524,33 +524,29 @@ packages:
|
||||
resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
|
||||
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
|
||||
|
||||
'@eslint/config-array@0.21.1':
|
||||
resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
'@eslint/config-array@0.23.1':
|
||||
resolution: {integrity: sha512-uVSdg/V4dfQmTjJzR0szNczjOH/J+FyUMMjYtr07xFRXR7EDf9i1qdxrD0VusZH9knj1/ecxzCQQxyic5NzAiA==}
|
||||
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
|
||||
|
||||
'@eslint/config-helpers@0.4.2':
|
||||
resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
'@eslint/config-helpers@0.5.2':
|
||||
resolution: {integrity: sha512-a5MxrdDXEvqnIq+LisyCX6tQMPF/dSJpCfBgBauY+pNZ28yCtSsTvyTYrMhaI+LK26bVyCJfJkT0u8KIj2i1dQ==}
|
||||
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
|
||||
|
||||
'@eslint/core@0.17.0':
|
||||
resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@eslint/eslintrc@3.3.3':
|
||||
resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
'@eslint/core@1.1.0':
|
||||
resolution: {integrity: sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw==}
|
||||
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
|
||||
|
||||
'@eslint/js@9.39.2':
|
||||
resolution: {integrity: sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@eslint/object-schema@2.1.7':
|
||||
resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
'@eslint/object-schema@3.0.1':
|
||||
resolution: {integrity: sha512-P9cq2dpr+LU8j3qbLygLcSZrl2/ds/pUpfnHNNuk5HW7mnngHs+6WSq5C9mO3rqRX8A1poxqLTC9cu0KOyJlBg==}
|
||||
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
|
||||
|
||||
'@eslint/plugin-kit@0.4.1':
|
||||
resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
'@eslint/plugin-kit@0.6.0':
|
||||
resolution: {integrity: sha512-bIZEUzOI1jkhviX2cp5vNyXQc6olzb2ohewQubuYlMXZ2Q/XjBO0x0XhGPvc9fjSIiUN0vw+0hq53BJ4eQSJKQ==}
|
||||
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
|
||||
|
||||
'@exodus/bytes@1.8.0':
|
||||
resolution: {integrity: sha512-8JPn18Bcp8Uo1T82gR8lh2guEOa5KKU/IEKvvdp0sgmi7coPBWf1Doi1EXsGZb2ehc8ym/StJCjffYV+ne7sXQ==}
|
||||
@@ -577,6 +573,10 @@ packages:
|
||||
resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
|
||||
engines: {node: '>=18.18'}
|
||||
|
||||
'@isaacs/cliui@9.0.0':
|
||||
resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@jridgewell/gen-mapping@0.3.13':
|
||||
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
|
||||
|
||||
@@ -1046,6 +1046,9 @@ packages:
|
||||
'@types/deep-eql@4.0.2':
|
||||
resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
|
||||
|
||||
'@types/esrecurse@4.3.1':
|
||||
resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==}
|
||||
|
||||
'@types/estree@1.0.8':
|
||||
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
|
||||
|
||||
@@ -1176,17 +1179,10 @@ packages:
|
||||
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
ansi-styles@4.3.0:
|
||||
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
ansi-styles@5.2.0:
|
||||
resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
argparse@2.0.1:
|
||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||
|
||||
aria-query@5.3.0:
|
||||
resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==}
|
||||
|
||||
@@ -1208,27 +1204,24 @@ packages:
|
||||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
|
||||
balanced-match@4.0.2:
|
||||
resolution: {integrity: sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
bidi-js@1.0.3:
|
||||
resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==}
|
||||
|
||||
brace-expansion@1.1.12:
|
||||
resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==}
|
||||
|
||||
brace-expansion@2.0.2:
|
||||
resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
|
||||
|
||||
callsites@3.1.0:
|
||||
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
|
||||
engines: {node: '>=6'}
|
||||
brace-expansion@5.0.2:
|
||||
resolution: {integrity: sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
chai@6.2.2:
|
||||
resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
chalk@4.1.2:
|
||||
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
chokidar@4.0.3:
|
||||
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
|
||||
engines: {node: '>= 14.16.0'}
|
||||
@@ -1240,16 +1233,6 @@ packages:
|
||||
codemirror@6.0.2:
|
||||
resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==}
|
||||
|
||||
color-convert@2.0.1:
|
||||
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
||||
engines: {node: '>=7.0.0'}
|
||||
|
||||
color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
|
||||
concat-map@0.0.1:
|
||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||
|
||||
cookie@0.6.0:
|
||||
resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
@@ -1357,6 +1340,10 @@ packages:
|
||||
resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
eslint-scope@9.1.0:
|
||||
resolution: {integrity: sha512-CkWE42hOJsNj9FJRaoMX9waUFYhqY4jmyLFdAdzZr6VaCg3ynLYx4WnOdkaIifGfH4gsUcBTn4OZbHXkpLD0FQ==}
|
||||
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
|
||||
|
||||
eslint-visitor-keys@3.4.3:
|
||||
resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
@@ -1365,9 +1352,13 @@ packages:
|
||||
resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
eslint@9.39.2:
|
||||
resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
eslint-visitor-keys@5.0.0:
|
||||
resolution: {integrity: sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==}
|
||||
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
|
||||
|
||||
eslint@10.0.0:
|
||||
resolution: {integrity: sha512-O0piBKY36YSJhlFSG8p9VUdPV/SxxS4FYDWVpr/9GJuMaepzwlf4J8I4ov1b+ySQfDTPhc3DtLaxcT1fN0yqCg==}
|
||||
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
jiti: '*'
|
||||
@@ -1382,6 +1373,10 @@ packages:
|
||||
resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
espree@11.1.0:
|
||||
resolution: {integrity: sha512-WFWYhO1fV4iYkqOOvq8FbqIhr2pYfoDY0kCotMkDeNtGpiGGkZ1iov2u8ydjtgM8yF8rzK7oaTbw2NAzbAbehw==}
|
||||
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
|
||||
|
||||
esquery@1.7.0:
|
||||
resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==}
|
||||
engines: {node: '>=0.10'}
|
||||
@@ -1450,10 +1445,6 @@ packages:
|
||||
resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
|
||||
globals@14.0.0:
|
||||
resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
globals@16.5.0:
|
||||
resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==}
|
||||
engines: {node: '>=18'}
|
||||
@@ -1496,10 +1487,6 @@ packages:
|
||||
resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==}
|
||||
engines: {node: '>= 4'}
|
||||
|
||||
import-fresh@3.3.1:
|
||||
resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
imurmurhash@0.1.4:
|
||||
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
|
||||
engines: {node: '>=0.8.19'}
|
||||
@@ -1537,6 +1524,10 @@ packages:
|
||||
resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
jackspeak@4.2.3:
|
||||
resolution: {integrity: sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
jiti@2.6.1:
|
||||
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
|
||||
hasBin: true
|
||||
@@ -1547,10 +1538,6 @@ packages:
|
||||
js-tokens@9.0.1:
|
||||
resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==}
|
||||
|
||||
js-yaml@4.1.1:
|
||||
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
|
||||
hasBin: true
|
||||
|
||||
jsdom@27.4.0:
|
||||
resolution: {integrity: sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==}
|
||||
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
|
||||
@@ -1664,9 +1651,6 @@ packages:
|
||||
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
lodash.merge@4.6.2:
|
||||
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
||||
|
||||
lru-cache@11.2.4:
|
||||
resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==}
|
||||
engines: {node: 20 || >=22}
|
||||
@@ -1702,8 +1686,9 @@ packages:
|
||||
resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
minimatch@3.1.2:
|
||||
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
||||
minimatch@10.2.1:
|
||||
resolution: {integrity: sha512-MClCe8IL5nRRmawL6ib/eT4oLyeKMGCghibcDWK+J0hh0Q8kqSdia6BvbRMVk6mPa6WqUa5uR2oxt6C5jd533A==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
minimatch@9.0.5:
|
||||
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
|
||||
@@ -1743,10 +1728,6 @@ packages:
|
||||
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
parent-module@1.0.1:
|
||||
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
parse5@8.0.0:
|
||||
resolution: {integrity: sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==}
|
||||
|
||||
@@ -1838,10 +1819,6 @@ packages:
|
||||
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
resolve-from@4.0.0:
|
||||
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
rollup@4.55.1:
|
||||
resolution: {integrity: sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==}
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
@@ -1892,10 +1869,6 @@ packages:
|
||||
resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
strip-json-comments@3.1.1:
|
||||
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
style-mod@4.1.3:
|
||||
resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==}
|
||||
|
||||
@@ -2498,50 +2471,36 @@ snapshots:
|
||||
'@esbuild/win32-x64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@eslint-community/eslint-utils@4.9.1(eslint@9.39.2(jiti@2.6.1))':
|
||||
'@eslint-community/eslint-utils@4.9.1(eslint@10.0.0(jiti@2.6.1))':
|
||||
dependencies:
|
||||
eslint: 9.39.2(jiti@2.6.1)
|
||||
eslint: 10.0.0(jiti@2.6.1)
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
'@eslint-community/regexpp@4.12.2': {}
|
||||
|
||||
'@eslint/config-array@0.21.1':
|
||||
'@eslint/config-array@0.23.1':
|
||||
dependencies:
|
||||
'@eslint/object-schema': 2.1.7
|
||||
'@eslint/object-schema': 3.0.1
|
||||
debug: 4.4.3
|
||||
minimatch: 3.1.2
|
||||
minimatch: 10.2.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@eslint/config-helpers@0.4.2':
|
||||
'@eslint/config-helpers@0.5.2':
|
||||
dependencies:
|
||||
'@eslint/core': 0.17.0
|
||||
'@eslint/core': 1.1.0
|
||||
|
||||
'@eslint/core@0.17.0':
|
||||
'@eslint/core@1.1.0':
|
||||
dependencies:
|
||||
'@types/json-schema': 7.0.15
|
||||
|
||||
'@eslint/eslintrc@3.3.3':
|
||||
dependencies:
|
||||
ajv: 6.12.6
|
||||
debug: 4.4.3
|
||||
espree: 10.4.0
|
||||
globals: 14.0.0
|
||||
ignore: 5.3.2
|
||||
import-fresh: 3.3.1
|
||||
js-yaml: 4.1.1
|
||||
minimatch: 3.1.2
|
||||
strip-json-comments: 3.1.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@eslint/js@9.39.2': {}
|
||||
|
||||
'@eslint/object-schema@2.1.7': {}
|
||||
'@eslint/object-schema@3.0.1': {}
|
||||
|
||||
'@eslint/plugin-kit@0.4.1':
|
||||
'@eslint/plugin-kit@0.6.0':
|
||||
dependencies:
|
||||
'@eslint/core': 0.17.0
|
||||
'@eslint/core': 1.1.0
|
||||
levn: 0.4.1
|
||||
|
||||
'@exodus/bytes@1.8.0': {}
|
||||
@@ -2557,6 +2516,8 @@ snapshots:
|
||||
|
||||
'@humanwhocodes/retry@0.4.3': {}
|
||||
|
||||
'@isaacs/cliui@9.0.0': {}
|
||||
|
||||
'@jridgewell/gen-mapping@0.3.13':
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
@@ -2994,19 +2955,21 @@ snapshots:
|
||||
|
||||
'@types/deep-eql@4.0.2': {}
|
||||
|
||||
'@types/esrecurse@4.3.1': {}
|
||||
|
||||
'@types/estree@1.0.8': {}
|
||||
|
||||
'@types/json-schema@7.0.15': {}
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3)':
|
||||
'@typescript-eslint/eslint-plugin@8.53.0(@typescript-eslint/parser@8.53.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.6.3))(eslint@10.0.0(jiti@2.6.1))(typescript@5.6.3)':
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.12.2
|
||||
'@typescript-eslint/parser': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3)
|
||||
'@typescript-eslint/parser': 8.53.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.6.3)
|
||||
'@typescript-eslint/scope-manager': 8.53.0
|
||||
'@typescript-eslint/type-utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3)
|
||||
'@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3)
|
||||
'@typescript-eslint/type-utils': 8.53.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.6.3)
|
||||
'@typescript-eslint/utils': 8.53.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.6.3)
|
||||
'@typescript-eslint/visitor-keys': 8.53.0
|
||||
eslint: 9.39.2(jiti@2.6.1)
|
||||
eslint: 10.0.0(jiti@2.6.1)
|
||||
ignore: 7.0.5
|
||||
natural-compare: 1.4.0
|
||||
ts-api-utils: 2.4.0(typescript@5.6.3)
|
||||
@@ -3014,14 +2977,14 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3)':
|
||||
'@typescript-eslint/parser@8.53.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.6.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 8.53.0
|
||||
'@typescript-eslint/types': 8.53.0
|
||||
'@typescript-eslint/typescript-estree': 8.53.0(typescript@5.6.3)
|
||||
'@typescript-eslint/visitor-keys': 8.53.0
|
||||
debug: 4.4.3
|
||||
eslint: 9.39.2(jiti@2.6.1)
|
||||
eslint: 10.0.0(jiti@2.6.1)
|
||||
typescript: 5.6.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -3044,13 +3007,13 @@ snapshots:
|
||||
dependencies:
|
||||
typescript: 5.6.3
|
||||
|
||||
'@typescript-eslint/type-utils@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3)':
|
||||
'@typescript-eslint/type-utils@8.53.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.6.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.53.0
|
||||
'@typescript-eslint/typescript-estree': 8.53.0(typescript@5.6.3)
|
||||
'@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3)
|
||||
'@typescript-eslint/utils': 8.53.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.6.3)
|
||||
debug: 4.4.3
|
||||
eslint: 9.39.2(jiti@2.6.1)
|
||||
eslint: 10.0.0(jiti@2.6.1)
|
||||
ts-api-utils: 2.4.0(typescript@5.6.3)
|
||||
typescript: 5.6.3
|
||||
transitivePeerDependencies:
|
||||
@@ -3073,13 +3036,13 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/utils@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3)':
|
||||
'@typescript-eslint/utils@8.53.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.6.3)':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1))
|
||||
'@eslint-community/eslint-utils': 4.9.1(eslint@10.0.0(jiti@2.6.1))
|
||||
'@typescript-eslint/scope-manager': 8.53.0
|
||||
'@typescript-eslint/types': 8.53.0
|
||||
'@typescript-eslint/typescript-estree': 8.53.0(typescript@5.6.3)
|
||||
eslint: 9.39.2(jiti@2.6.1)
|
||||
eslint: 10.0.0(jiti@2.6.1)
|
||||
typescript: 5.6.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -3168,14 +3131,8 @@ snapshots:
|
||||
|
||||
ansi-regex@5.0.1: {}
|
||||
|
||||
ansi-styles@4.3.0:
|
||||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
|
||||
ansi-styles@5.2.0: {}
|
||||
|
||||
argparse@2.0.1: {}
|
||||
|
||||
aria-query@5.3.0:
|
||||
dependencies:
|
||||
dequal: 2.0.3
|
||||
@@ -3194,28 +3151,24 @@ snapshots:
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
balanced-match@4.0.2:
|
||||
dependencies:
|
||||
jackspeak: 4.2.3
|
||||
|
||||
bidi-js@1.0.3:
|
||||
dependencies:
|
||||
require-from-string: 2.0.2
|
||||
|
||||
brace-expansion@1.1.12:
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
concat-map: 0.0.1
|
||||
|
||||
brace-expansion@2.0.2:
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
|
||||
callsites@3.1.0: {}
|
||||
brace-expansion@5.0.2:
|
||||
dependencies:
|
||||
balanced-match: 4.0.2
|
||||
|
||||
chai@6.2.2: {}
|
||||
|
||||
chalk@4.1.2:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
supports-color: 7.2.0
|
||||
|
||||
chokidar@4.0.3:
|
||||
dependencies:
|
||||
readdirp: 4.1.2
|
||||
@@ -3232,14 +3185,6 @@ snapshots:
|
||||
'@codemirror/state': 6.5.4
|
||||
'@codemirror/view': 6.39.11
|
||||
|
||||
color-convert@2.0.1:
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
|
||||
color-name@1.1.4: {}
|
||||
|
||||
concat-map@0.0.1: {}
|
||||
|
||||
cookie@0.6.0: {}
|
||||
|
||||
crelt@1.0.6: {}
|
||||
@@ -3331,15 +3276,15 @@ snapshots:
|
||||
|
||||
escape-string-regexp@4.0.0: {}
|
||||
|
||||
eslint-config-prettier@10.1.8(eslint@9.39.2(jiti@2.6.1)):
|
||||
eslint-config-prettier@10.1.8(eslint@10.0.0(jiti@2.6.1)):
|
||||
dependencies:
|
||||
eslint: 9.39.2(jiti@2.6.1)
|
||||
eslint: 10.0.0(jiti@2.6.1)
|
||||
|
||||
eslint-plugin-svelte@3.14.0(eslint@9.39.2(jiti@2.6.1))(svelte@5.46.3):
|
||||
eslint-plugin-svelte@3.14.0(eslint@10.0.0(jiti@2.6.1))(svelte@5.46.3):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1))
|
||||
'@eslint-community/eslint-utils': 4.9.1(eslint@10.0.0(jiti@2.6.1))
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
eslint: 9.39.2(jiti@2.6.1)
|
||||
eslint: 10.0.0(jiti@2.6.1)
|
||||
esutils: 2.0.3
|
||||
globals: 16.5.0
|
||||
known-css-properties: 0.37.0
|
||||
@@ -3358,32 +3303,38 @@ snapshots:
|
||||
esrecurse: 4.3.0
|
||||
estraverse: 5.3.0
|
||||
|
||||
eslint-scope@9.1.0:
|
||||
dependencies:
|
||||
'@types/esrecurse': 4.3.1
|
||||
'@types/estree': 1.0.8
|
||||
esrecurse: 4.3.0
|
||||
estraverse: 5.3.0
|
||||
|
||||
eslint-visitor-keys@3.4.3: {}
|
||||
|
||||
eslint-visitor-keys@4.2.1: {}
|
||||
|
||||
eslint@9.39.2(jiti@2.6.1):
|
||||
eslint-visitor-keys@5.0.0: {}
|
||||
|
||||
eslint@10.0.0(jiti@2.6.1):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1))
|
||||
'@eslint-community/eslint-utils': 4.9.1(eslint@10.0.0(jiti@2.6.1))
|
||||
'@eslint-community/regexpp': 4.12.2
|
||||
'@eslint/config-array': 0.21.1
|
||||
'@eslint/config-helpers': 0.4.2
|
||||
'@eslint/core': 0.17.0
|
||||
'@eslint/eslintrc': 3.3.3
|
||||
'@eslint/js': 9.39.2
|
||||
'@eslint/plugin-kit': 0.4.1
|
||||
'@eslint/config-array': 0.23.1
|
||||
'@eslint/config-helpers': 0.5.2
|
||||
'@eslint/core': 1.1.0
|
||||
'@eslint/plugin-kit': 0.6.0
|
||||
'@humanfs/node': 0.16.7
|
||||
'@humanwhocodes/module-importer': 1.0.1
|
||||
'@humanwhocodes/retry': 0.4.3
|
||||
'@types/estree': 1.0.8
|
||||
ajv: 6.12.6
|
||||
chalk: 4.1.2
|
||||
cross-spawn: 7.0.6
|
||||
debug: 4.4.3
|
||||
escape-string-regexp: 4.0.0
|
||||
eslint-scope: 8.4.0
|
||||
eslint-visitor-keys: 4.2.1
|
||||
espree: 10.4.0
|
||||
eslint-scope: 9.1.0
|
||||
eslint-visitor-keys: 5.0.0
|
||||
espree: 11.1.0
|
||||
esquery: 1.7.0
|
||||
esutils: 2.0.3
|
||||
fast-deep-equal: 3.1.3
|
||||
@@ -3394,8 +3345,7 @@ snapshots:
|
||||
imurmurhash: 0.1.4
|
||||
is-glob: 4.0.3
|
||||
json-stable-stringify-without-jsonify: 1.0.1
|
||||
lodash.merge: 4.6.2
|
||||
minimatch: 3.1.2
|
||||
minimatch: 10.2.1
|
||||
natural-compare: 1.4.0
|
||||
optionator: 0.9.4
|
||||
optionalDependencies:
|
||||
@@ -3411,6 +3361,12 @@ snapshots:
|
||||
acorn-jsx: 5.3.2(acorn@8.15.0)
|
||||
eslint-visitor-keys: 4.2.1
|
||||
|
||||
espree@11.1.0:
|
||||
dependencies:
|
||||
acorn: 8.15.0
|
||||
acorn-jsx: 5.3.2(acorn@8.15.0)
|
||||
eslint-visitor-keys: 5.0.0
|
||||
|
||||
esquery@1.7.0:
|
||||
dependencies:
|
||||
estraverse: 5.3.0
|
||||
@@ -3466,8 +3422,6 @@ snapshots:
|
||||
dependencies:
|
||||
is-glob: 4.0.3
|
||||
|
||||
globals@14.0.0: {}
|
||||
|
||||
globals@16.5.0: {}
|
||||
|
||||
globals@17.0.0: {}
|
||||
@@ -3504,11 +3458,6 @@ snapshots:
|
||||
|
||||
ignore@7.0.5: {}
|
||||
|
||||
import-fresh@3.3.1:
|
||||
dependencies:
|
||||
parent-module: 1.0.1
|
||||
resolve-from: 4.0.0
|
||||
|
||||
imurmurhash@0.1.4: {}
|
||||
|
||||
indent-string@4.0.0: {}
|
||||
@@ -3540,16 +3489,16 @@ snapshots:
|
||||
html-escaper: 2.0.2
|
||||
istanbul-lib-report: 3.0.1
|
||||
|
||||
jackspeak@4.2.3:
|
||||
dependencies:
|
||||
'@isaacs/cliui': 9.0.0
|
||||
|
||||
jiti@2.6.1: {}
|
||||
|
||||
js-tokens@4.0.0: {}
|
||||
|
||||
js-tokens@9.0.1: {}
|
||||
|
||||
js-yaml@4.1.1:
|
||||
dependencies:
|
||||
argparse: 2.0.1
|
||||
|
||||
jsdom@27.4.0:
|
||||
dependencies:
|
||||
'@acemir/cssom': 0.9.31
|
||||
@@ -3654,8 +3603,6 @@ snapshots:
|
||||
dependencies:
|
||||
p-locate: 5.0.0
|
||||
|
||||
lodash.merge@4.6.2: {}
|
||||
|
||||
lru-cache@11.2.4: {}
|
||||
|
||||
lucide-svelte@0.563.0(svelte@5.46.3):
|
||||
@@ -3684,9 +3631,9 @@ snapshots:
|
||||
|
||||
min-indent@1.0.1: {}
|
||||
|
||||
minimatch@3.1.2:
|
||||
minimatch@10.2.1:
|
||||
dependencies:
|
||||
brace-expansion: 1.1.12
|
||||
brace-expansion: 5.0.2
|
||||
|
||||
minimatch@9.0.5:
|
||||
dependencies:
|
||||
@@ -3721,10 +3668,6 @@ snapshots:
|
||||
dependencies:
|
||||
p-limit: 3.1.0
|
||||
|
||||
parent-module@1.0.1:
|
||||
dependencies:
|
||||
callsites: 3.1.0
|
||||
|
||||
parse5@8.0.0:
|
||||
dependencies:
|
||||
entities: 6.0.1
|
||||
@@ -3793,8 +3736,6 @@ snapshots:
|
||||
|
||||
require-from-string@2.0.2: {}
|
||||
|
||||
resolve-from@4.0.0: {}
|
||||
|
||||
rollup@4.55.1:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
@@ -3862,8 +3803,6 @@ snapshots:
|
||||
dependencies:
|
||||
min-indent: 1.0.1
|
||||
|
||||
strip-json-comments@3.1.1: {}
|
||||
|
||||
style-mod@4.1.3: {}
|
||||
|
||||
supports-color@7.2.0:
|
||||
@@ -3952,13 +3891,13 @@ snapshots:
|
||||
dependencies:
|
||||
prelude-ls: 1.2.1
|
||||
|
||||
typescript-eslint@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3):
|
||||
typescript-eslint@8.53.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.6.3):
|
||||
dependencies:
|
||||
'@typescript-eslint/eslint-plugin': 8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3)
|
||||
'@typescript-eslint/parser': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3)
|
||||
'@typescript-eslint/eslint-plugin': 8.53.0(@typescript-eslint/parser@8.53.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.6.3))(eslint@10.0.0(jiti@2.6.1))(typescript@5.6.3)
|
||||
'@typescript-eslint/parser': 8.53.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.6.3)
|
||||
'@typescript-eslint/typescript-estree': 8.53.0(typescript@5.6.3)
|
||||
'@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3)
|
||||
eslint: 9.39.2(jiti@2.6.1)
|
||||
'@typescript-eslint/utils': 8.53.0(eslint@10.0.0(jiti@2.6.1))(typescript@5.6.3)
|
||||
eslint: 10.0.0(jiti@2.6.1)
|
||||
typescript: 5.6.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
Generated
+1
-1
@@ -1636,7 +1636,7 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "hikari-desktop"
|
||||
version = "1.6.0"
|
||||
version = "1.5.1"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"dirs 5.0.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "hikari-desktop"
|
||||
version = "1.6.0"
|
||||
version = "1.5.1"
|
||||
description = "Hikari - Claude Code Visual Assistant"
|
||||
authors = ["Naomi Carrigan"]
|
||||
edition = "2021"
|
||||
|
||||
@@ -86,9 +86,8 @@ impl ContextWarning {
|
||||
/// Get the context window limit (in tokens) for a given model
|
||||
fn get_context_window_limit(model: &str) -> u64 {
|
||||
match model {
|
||||
// Claude 4.6 family
|
||||
// Claude 4.6 family - 200K standard (1M beta available via header)
|
||||
"claude-opus-4-6" => 200_000,
|
||||
"claude-sonnet-4-6" => 1_000_000, // 1M token context window
|
||||
// Claude 4.5 family - 200K standard context
|
||||
"claude-opus-4-5-20251101"
|
||||
| "claude-sonnet-4-5-20250929"
|
||||
@@ -503,7 +502,6 @@ pub fn calculate_cost(
|
||||
let (input_price_per_million, output_price_per_million) = match model {
|
||||
// Current generation (Claude 4.6)
|
||||
"claude-opus-4-6" => (5.0, 25.0),
|
||||
"claude-sonnet-4-6" => (3.0, 15.0),
|
||||
|
||||
// Previous generation (Claude 4.5)
|
||||
"claude-opus-4-5-20251101" => (5.0, 25.0),
|
||||
|
||||
+28
-115
@@ -39,12 +39,6 @@ const SEARCH_TOOLS: [&str; 5] = ["Read", "Glob", "Grep", "WebSearch", "WebFetch"
|
||||
const CODING_TOOLS: [&str; 3] = ["Edit", "Write", "NotebookEdit"];
|
||||
|
||||
fn detect_wsl() -> bool {
|
||||
// A native Windows binary is never running inside WSL, even if launched from a WSL
|
||||
// terminal that has WSL_DISTRO_NAME set in its environment.
|
||||
if cfg!(target_os = "windows") {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check /proc/version for WSL indicators
|
||||
if let Ok(version) = std::fs::read_to_string("/proc/version") {
|
||||
let version_lower = version.to_lowercase();
|
||||
@@ -67,29 +61,23 @@ fn detect_wsl() -> bool {
|
||||
}
|
||||
|
||||
fn find_claude_binary() -> Option<String> {
|
||||
// Check common installation locations for claude (when HOME is available)
|
||||
if let Ok(home) = std::env::var("HOME") {
|
||||
let paths_to_check = [
|
||||
format!("{}/.local/bin/claude", home),
|
||||
format!("{}/.claude/local/claude", home),
|
||||
];
|
||||
for path in &paths_to_check {
|
||||
if std::path::Path::new(path).exists() {
|
||||
return Some(path.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check common installation locations for claude
|
||||
let home = std::env::var("HOME").ok()?;
|
||||
let paths_to_check = [
|
||||
format!("{}/.local/bin/claude", home),
|
||||
format!("{}/.claude/local/claude", home),
|
||||
"/usr/local/bin/claude".to_string(),
|
||||
"/usr/bin/claude".to_string(),
|
||||
];
|
||||
|
||||
// Check system-wide locations
|
||||
for path in &["/usr/local/bin/claude", "/usr/bin/claude"] {
|
||||
for path in &paths_to_check {
|
||||
if std::path::Path::new(path).exists() {
|
||||
return Some((*path).to_string());
|
||||
return Some(path.clone());
|
||||
}
|
||||
}
|
||||
|
||||
// Use a login shell to resolve claude via the user's PATH - GUI apps don't
|
||||
// inherit shell PATH, so bare `which` may miss ~/.local/bin entries
|
||||
if let Ok(output) = Command::new("bash").args(["-lc", "which claude"]).output() {
|
||||
// Fall back to checking PATH via which
|
||||
if let Ok(output) = Command::new("which").arg("claude").output() {
|
||||
if output.status.success() {
|
||||
let path = String::from_utf8_lossy(&output.stdout).trim().to_string();
|
||||
if !path.is_empty() {
|
||||
@@ -137,19 +125,15 @@ impl WslBridge {
|
||||
}
|
||||
|
||||
pub fn start(&mut self, app: AppHandle, options: ClaudeStartOptions) -> Result<(), String> {
|
||||
// If a process handle exists but the process has already exited (e.g. due to a
|
||||
// failed working directory), clean up the stale handle so we can restart cleanly.
|
||||
if let Some(ref mut process) = self.process {
|
||||
if process.try_wait().map(|s| s.is_some()).unwrap_or(false) {
|
||||
self.process = None;
|
||||
self.stdin = None;
|
||||
}
|
||||
}
|
||||
|
||||
if self.process.is_some() {
|
||||
return Err("Process already running".to_string());
|
||||
}
|
||||
|
||||
// Check if Claude binary is installed before attempting to start
|
||||
if Command::new("which").arg("claude").output().ok().is_none_or(|output| !output.status.success()) {
|
||||
return Err("Claude Code is not installed. Please install it using:\n\ncurl -fsSL https://claude.ai/install.sh | bash".to_string());
|
||||
}
|
||||
|
||||
// Load saved achievements and stats when starting a new session
|
||||
let app_clone = app.clone();
|
||||
let stats = self.stats.clone();
|
||||
@@ -278,30 +262,6 @@ impl WslBridge {
|
||||
} else {
|
||||
// Running on Windows - use wsl with bash login shell to ensure PATH is loaded
|
||||
tracing::debug!("Windows path - using wsl");
|
||||
|
||||
// Check if Claude binary is installed inside WSL
|
||||
let binary_check = Command::new("wsl")
|
||||
.args(["-e", "bash", "-lc", "which claude"])
|
||||
.output();
|
||||
if let Ok(output) = binary_check {
|
||||
if !output.status.success() {
|
||||
return Err("Claude Code is not installed. Please install it using:\n\ncurl -fsSL https://claude.ai/install.sh | bash".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the working directory exists inside WSL before spawning
|
||||
let dir_check = Command::new("wsl")
|
||||
.args(["-e", "test", "-d", working_dir])
|
||||
.output();
|
||||
if let Ok(output) = dir_check {
|
||||
if !output.status.success() {
|
||||
return Err(format!(
|
||||
"Working directory does not exist: {}",
|
||||
working_dir
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let mut cmd = Command::new("wsl");
|
||||
|
||||
// Build the claude command with all arguments
|
||||
@@ -1914,66 +1874,19 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stale_process_detection_with_try_wait() {
|
||||
// Spawn a real process that exits immediately so we can verify try_wait detects it
|
||||
let mut child = Command::new("true").spawn().expect("Failed to spawn 'true'");
|
||||
fn test_claude_binary_check_command_structure() {
|
||||
// Test that we're using the correct command to check for Claude binary
|
||||
let output = Command::new("which").arg("claude").output();
|
||||
|
||||
// Wait for it to exit
|
||||
let _ = child.wait();
|
||||
// The command should execute successfully (even if claude is not found)
|
||||
// We're just verifying the command structure is valid
|
||||
assert!(output.is_ok(), "which command should execute without error");
|
||||
|
||||
// try_wait on an already-exited process should return Some(_)
|
||||
let status = child.try_wait();
|
||||
assert!(
|
||||
status.is_ok(),
|
||||
"try_wait should not error on an exited process"
|
||||
);
|
||||
// The process has already been waited on, so try_wait might return None or Some
|
||||
// depending on the OS - what matters is that the call succeeds
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stale_process_is_some_after_exit() {
|
||||
// Verify the logic used in start(): a process that has exited is detected
|
||||
// and the handle is cleaned up so start() can proceed
|
||||
let mut child = Command::new("true").spawn().expect("Failed to spawn 'true'");
|
||||
|
||||
// Let it exit
|
||||
let _ = child.wait();
|
||||
|
||||
// This mirrors the check in start()
|
||||
let has_exited = child
|
||||
.try_wait()
|
||||
.map(|s| s.is_some())
|
||||
.unwrap_or(false);
|
||||
|
||||
// After wait(), try_wait() returns None (already reaped), which means
|
||||
// unwrap_or(false) → false. The important thing is the call doesn't panic
|
||||
// and the control flow logic compiles and runs correctly.
|
||||
let _ = has_exited; // suppress unused warning
|
||||
}
|
||||
|
||||
/// Build the WSL binary check command structure without executing it (for testing)
|
||||
#[cfg(test)]
|
||||
fn build_wsl_binary_check_args() -> Vec<&'static str> {
|
||||
vec!["-e", "bash", "-lc", "which claude"]
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wsl_binary_check_command_structure() {
|
||||
// Windows path: verify Claude is detected inside WSL via `wsl -e bash -lc "which claude"`
|
||||
let args = build_wsl_binary_check_args();
|
||||
assert_eq!(args[0], "-e");
|
||||
assert_eq!(args[1], "bash");
|
||||
assert_eq!(args[2], "-lc");
|
||||
assert_eq!(args[3], "which claude");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_linux_binary_check_does_not_panic() {
|
||||
// Linux/WSL path: find_claude_binary() searches Linux filesystem paths.
|
||||
// We just verify it runs without panicking; whether it returns Some depends
|
||||
// on whether Claude is actually installed in this environment.
|
||||
let _result = find_claude_binary();
|
||||
// Verify the check logic returns a boolean
|
||||
// This is the same logic used in start() to check if claude is installed
|
||||
let _result = output.ok().is_none_or(|o| !o.status.success());
|
||||
// If claude is not installed, _result will be true (show error)
|
||||
// If claude is installed, _result will be false (proceed with connection)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "hikari-desktop",
|
||||
"version": "1.6.0",
|
||||
"version": "1.5.1",
|
||||
"identifier": "com.naomi.hikari-desktop",
|
||||
"build": {
|
||||
"beforeDevCommand": "pnpm dev",
|
||||
|
||||
@@ -270,14 +270,6 @@
|
||||
/>
|
||||
</svg>
|
||||
{/if}
|
||||
<img
|
||||
src={agent.characterAvatar}
|
||||
alt={agent.characterName}
|
||||
class="w-5 h-5 rounded-full object-cover"
|
||||
/>
|
||||
<span class="text-[10px] font-medium text-[var(--text-primary)]">
|
||||
{agent.characterName}
|
||||
</span>
|
||||
<span
|
||||
class="px-1.5 py-0.5 text-[10px] rounded border {getStatusBadgeClass(
|
||||
agent.status
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { CHARACTER_POOL } from "$lib/utils/agentCharacters";
|
||||
|
||||
interface Props {
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
const { onClose }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center p-4"
|
||||
onclick={onClose}
|
||||
role="button"
|
||||
tabindex="0"
|
||||
onkeydown={(e) => e.key === "Escape" && onClose()}
|
||||
>
|
||||
<div
|
||||
class="bg-[var(--bg-primary)] border border-[var(--border-color)] rounded-lg shadow-xl max-w-2xl w-full p-6 max-h-[90vh] overflow-y-auto"
|
||||
onclick={(e) => e.stopPropagation()}
|
||||
onkeydown={(e) => e.stopPropagation()}
|
||||
role="dialog"
|
||||
aria-labelledby="cast-title"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h2 id="cast-title" class="text-xl font-semibold text-[var(--text-primary)]">
|
||||
Meet the Team
|
||||
</h2>
|
||||
<button
|
||||
onclick={onClose}
|
||||
class="p-1 text-[var(--text-secondary)] hover:text-[var(--text-primary)] transition-colors"
|
||||
aria-label="Close"
|
||||
>
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M6 18L18 6M6 6l12 12"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Principal cast: Hikari + Naomi -->
|
||||
<div class="grid grid-cols-1 gap-3 mb-6 sm:grid-cols-2">
|
||||
<div
|
||||
class="flex items-center gap-3 p-4 rounded-lg bg-[var(--bg-secondary)] border border-[var(--accent-primary)]/40"
|
||||
>
|
||||
<img
|
||||
src="https://cdn.nhcarrigan.com/hikari.png"
|
||||
alt="Hikari"
|
||||
class="w-16 h-16 object-cover rounded-full border-2 border-[var(--border-color)] shrink-0"
|
||||
/>
|
||||
<div>
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<span class="font-semibold text-[var(--text-primary)]">Hikari</span>
|
||||
<span
|
||||
class="text-xs px-2 py-0.5 rounded-full bg-[var(--accent-primary)]/20 text-[var(--accent-primary)] font-medium"
|
||||
>
|
||||
Chief Operating Officer
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-xs text-[var(--text-secondary)]">
|
||||
Holds the line so the others don't have to. Never without her clipboard — or her
|
||||
glasses.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center gap-3 p-4 rounded-lg bg-[var(--bg-secondary)] border border-[var(--accent-primary)]/40"
|
||||
>
|
||||
<img
|
||||
src="https://cdn.nhcarrigan.com/profile.png"
|
||||
alt="Naomi"
|
||||
class="w-16 h-16 object-cover rounded-full border-2 border-[var(--border-color)] shrink-0"
|
||||
/>
|
||||
<div>
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<span class="font-semibold text-[var(--text-primary)]">Naomi</span>
|
||||
<span
|
||||
class="text-xs px-2 py-0.5 rounded-full bg-[var(--accent-primary)]/20 text-[var(--accent-primary)] font-medium"
|
||||
>
|
||||
Chief hEx-ecutive Officer
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-xs text-[var(--text-secondary)]">
|
||||
A 525-year-old vampire running a tech company from behind a VTuber avatar. Fixes server
|
||||
crashes at 4 AM.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Subagent girls grid -->
|
||||
<div>
|
||||
<h3 class="text-sm font-medium text-[var(--text-secondary)] uppercase tracking-wider mb-3">
|
||||
Subagent Squad
|
||||
</h3>
|
||||
<div class="grid grid-cols-2 gap-3 sm:grid-cols-3">
|
||||
{#each CHARACTER_POOL as character (character.name)}
|
||||
<div
|
||||
class="flex flex-col items-center gap-2 p-3 rounded-lg bg-[var(--bg-secondary)] border border-[var(--border-color)] text-center"
|
||||
>
|
||||
<img
|
||||
src={character.avatar}
|
||||
alt={character.name}
|
||||
class="w-14 h-14 object-cover rounded-full border-2 border-[var(--border-color)]"
|
||||
/>
|
||||
<span class="text-sm font-medium text-[var(--text-primary)]">{character.name}</span>
|
||||
<span
|
||||
class="text-xs px-2 py-0.5 rounded-full bg-[var(--accent-primary)]/20 text-[var(--accent-primary)] font-medium"
|
||||
>
|
||||
{character.title}
|
||||
</span>
|
||||
<p class="text-xs text-[var(--text-secondary)] leading-snug">{character.description}</p>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
[role="dialog"] {
|
||||
animation: slideIn 0.2s ease-out;
|
||||
}
|
||||
|
||||
@keyframes slideIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.95);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -83,9 +83,8 @@
|
||||
{ value: "", label: "Default (from ~/.claude)" },
|
||||
// Current generation (Claude 4.6)
|
||||
{ value: "claude-opus-4-6", label: "Claude Opus 4.6 (Most Capable)" },
|
||||
{ value: "claude-sonnet-4-6", label: "Claude Sonnet 4.6 (Recommended)" },
|
||||
// Previous generation (Claude 4.5)
|
||||
{ value: "claude-sonnet-4-5-20250929", label: "Claude Sonnet 4.5" },
|
||||
{ value: "claude-sonnet-4-5-20250929", label: "Claude Sonnet 4.5 (Recommended)" },
|
||||
{ value: "claude-haiku-4-5-20251001", label: "Claude Haiku 4.5 (Fast & Cheap)" },
|
||||
{ value: "claude-opus-4-5-20251101", label: "Claude Opus 4.5" },
|
||||
// Previous generation (Claude 4.x)
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
import GitPanel from "./GitPanel.svelte";
|
||||
import ProfilePanel from "./ProfilePanel.svelte";
|
||||
import AgentMonitorPanel from "./AgentMonitorPanel.svelte";
|
||||
import CastPanel from "./CastPanel.svelte";
|
||||
import PluginManagementPanel from "./PluginManagementPanel.svelte";
|
||||
import McpManagementPanel from "./McpManagementPanel.svelte";
|
||||
import { conversationsStore } from "$lib/stores/conversations";
|
||||
@@ -57,7 +56,6 @@
|
||||
let showGitPanel = $state(false);
|
||||
let showProfile = $state(false);
|
||||
let showAgentMonitor = $state(false);
|
||||
let showCastPanel = $state(false);
|
||||
let showPluginPanel = $state(false);
|
||||
let showMcpPanel = $state(false);
|
||||
let isSummarising = $state(false);
|
||||
@@ -521,20 +519,6 @@
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
onclick={() => (showCastPanel = true)}
|
||||
class="p-1 text-gray-500 icon-trans-hover"
|
||||
title="Meet the Team"
|
||||
>
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
onclick={() => (showAgentMonitor = !showAgentMonitor)}
|
||||
class="p-1 text-gray-500 icon-trans-hover relative {showAgentMonitor
|
||||
@@ -753,10 +737,6 @@
|
||||
<AgentMonitorPanel isOpen={showAgentMonitor} onClose={() => (showAgentMonitor = false)} />
|
||||
{/if}
|
||||
|
||||
{#if showCastPanel}
|
||||
<CastPanel onClose={() => (showCastPanel = false)} />
|
||||
{/if}
|
||||
|
||||
{#if showPluginPanel}
|
||||
<PluginManagementPanel onClose={() => (showPluginPanel = false)} />
|
||||
{/if}
|
||||
|
||||
@@ -2,15 +2,12 @@ import { describe, it, expect, beforeEach } from "vitest";
|
||||
import { agentStore, getAgentsForConversation, runningAgentCount } from "./agents";
|
||||
import { get } from "svelte/store";
|
||||
import type { AgentInfo } from "$lib/types/agents";
|
||||
import { CHARACTER_POOL } from "$lib/utils/agentCharacters";
|
||||
|
||||
describe("agents store", () => {
|
||||
const conversationId = "test-conversation-1";
|
||||
const otherConversationId = "test-conversation-2";
|
||||
|
||||
type AgentInput = Omit<AgentInfo, "characterName" | "characterAvatar">;
|
||||
|
||||
const createMockAgent = (overrides?: Partial<AgentInput>): AgentInput => ({
|
||||
const createMockAgent = (overrides?: Partial<AgentInfo>): AgentInfo => ({
|
||||
toolUseId: "toolu_test123",
|
||||
description: "Test agent",
|
||||
subagentType: "Explore",
|
||||
@@ -40,29 +37,7 @@ describe("agents store", () => {
|
||||
|
||||
const agents = get(getAgentsForConversation(conversationId));
|
||||
expect(agents).toHaveLength(1);
|
||||
expect(agents[0]).toMatchObject(agent);
|
||||
});
|
||||
|
||||
it("assigns a character name and avatar to added agents", () => {
|
||||
const agent = createMockAgent();
|
||||
agentStore.addAgent(conversationId, agent);
|
||||
|
||||
const agents = get(getAgentsForConversation(conversationId));
|
||||
const validNames = CHARACTER_POOL.map((c) => c.name);
|
||||
expect(validNames).toContain(agents[0].characterName);
|
||||
expect(agents[0].characterAvatar).toMatch(/^https:\/\//u);
|
||||
});
|
||||
|
||||
it("avoids duplicate character names across agents when possible", () => {
|
||||
// Add 6 agents - each should ideally get a unique character
|
||||
for (let i = 0; i < 6; i++) {
|
||||
agentStore.addAgent(conversationId, createMockAgent({ toolUseId: `tool${i.toString()}` }));
|
||||
}
|
||||
|
||||
const agents = get(getAgentsForConversation(conversationId));
|
||||
const names = agents.map((a) => a.characterName);
|
||||
const uniqueNames = new Set(names);
|
||||
expect(uniqueNames.size).toBe(6);
|
||||
expect(agents[0]).toEqual(agent);
|
||||
});
|
||||
|
||||
it("adds multiple agents to the same conversation", () => {
|
||||
@@ -74,8 +49,8 @@ describe("agents store", () => {
|
||||
|
||||
const agents = get(getAgentsForConversation(conversationId));
|
||||
expect(agents).toHaveLength(2);
|
||||
expect(agents[0]).toMatchObject(agent1);
|
||||
expect(agents[1]).toMatchObject(agent2);
|
||||
expect(agents[0]).toEqual(agent1);
|
||||
expect(agents[1]).toEqual(agent2);
|
||||
});
|
||||
|
||||
it("keeps agents in different conversations separate", () => {
|
||||
@@ -90,8 +65,8 @@ describe("agents store", () => {
|
||||
|
||||
expect(agents1).toHaveLength(1);
|
||||
expect(agents2).toHaveLength(1);
|
||||
expect(agents1[0]).toMatchObject(agent1);
|
||||
expect(agents2[0]).toMatchObject(agent2);
|
||||
expect(agents1[0]).toEqual(agent1);
|
||||
expect(agents2[0]).toEqual(agent2);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -281,7 +256,7 @@ describe("agents store", () => {
|
||||
|
||||
expect(agents1).toHaveLength(0);
|
||||
expect(agents2).toHaveLength(1);
|
||||
expect(agents2[0]).toMatchObject(agent2);
|
||||
expect(agents2[0]).toEqual(agent2);
|
||||
});
|
||||
|
||||
it("does nothing if conversation doesn't exist", () => {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { writable, derived } from "svelte/store";
|
||||
import type { AgentInfo } from "$lib/types/agents";
|
||||
import { assignCharacter } from "$lib/utils/agentCharacters";
|
||||
|
||||
// Map of conversation ID -> agents in that conversation
|
||||
const agentsByConversation = writable<Record<string, AgentInfo[]>>({});
|
||||
@@ -9,17 +8,12 @@ function createAgentStore() {
|
||||
return {
|
||||
subscribe: agentsByConversation.subscribe,
|
||||
|
||||
addAgent(conversationId: string, agent: Omit<AgentInfo, "characterName" | "characterAvatar">) {
|
||||
addAgent(conversationId: string, agent: AgentInfo) {
|
||||
agentsByConversation.update((state) => {
|
||||
const existing = state[conversationId] || [];
|
||||
const activeNames = existing.map((a) => a.characterName);
|
||||
const character = assignCharacter(activeNames);
|
||||
return {
|
||||
...state,
|
||||
[conversationId]: [
|
||||
...existing,
|
||||
{ ...agent, characterName: character.name, characterAvatar: character.avatar },
|
||||
],
|
||||
[conversationId]: [...existing, agent],
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
@@ -12,7 +12,6 @@ export type BudgetType = "token" | "cost";
|
||||
export const MODEL_PRICING: Record<string, { input: number; output: number }> = {
|
||||
// Current generation (Claude 4.6)
|
||||
"claude-opus-4-6": { input: 5.0, output: 25.0 },
|
||||
"claude-sonnet-4-6": { input: 3.0, output: 15.0 },
|
||||
// Previous generation (Claude 4.5)
|
||||
"claude-opus-4-5-20251101": { input: 5.0, output: 25.0 },
|
||||
"claude-sonnet-4-5-20250929": { input: 3.0, output: 15.0 },
|
||||
|
||||
@@ -10,8 +10,6 @@ export interface AgentInfo {
|
||||
status: AgentStatus;
|
||||
parentToolUseId?: string;
|
||||
durationMs?: number;
|
||||
characterName: string;
|
||||
characterAvatar: string;
|
||||
}
|
||||
|
||||
export interface AgentStartPayload {
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { CHARACTER_POOL, assignCharacter } from "./agentCharacters";
|
||||
|
||||
describe("agentCharacters", () => {
|
||||
describe("CHARACTER_POOL", () => {
|
||||
it("contains exactly 6 characters", () => {
|
||||
expect(CHARACTER_POOL).toHaveLength(6);
|
||||
});
|
||||
|
||||
it("each character has a name, avatar, title, and description", () => {
|
||||
for (const character of CHARACTER_POOL) {
|
||||
expect(character.name).toBeTruthy();
|
||||
expect(character.avatar).toBeTruthy();
|
||||
expect(character.avatar).toMatch(/^https:\/\//u);
|
||||
expect(character.title).toBeTruthy();
|
||||
expect(character.description).toBeTruthy();
|
||||
}
|
||||
});
|
||||
|
||||
it("all names are unique", () => {
|
||||
const names = CHARACTER_POOL.map((c) => c.name);
|
||||
const uniqueNames = new Set(names);
|
||||
expect(uniqueNames.size).toBe(CHARACTER_POOL.length);
|
||||
});
|
||||
});
|
||||
|
||||
describe("assignCharacter", () => {
|
||||
it("returns a character from the pool", () => {
|
||||
const character = assignCharacter([]);
|
||||
const names = CHARACTER_POOL.map((c) => c.name);
|
||||
expect(names).toContain(character.name);
|
||||
});
|
||||
|
||||
it("avoids names already in use when possible", () => {
|
||||
const takenNames = ["Amari", "Keiko", "Minori", "Reina", "Tatsumi"];
|
||||
// Run many times to confirm we never get a taken name
|
||||
for (let i = 0; i < 50; i++) {
|
||||
const character = assignCharacter(takenNames);
|
||||
expect(takenNames).not.toContain(character.name);
|
||||
expect(character.name).toBe("Yumiko");
|
||||
}
|
||||
});
|
||||
|
||||
it("picks from the full pool when all 6 names are taken", () => {
|
||||
const allNames = CHARACTER_POOL.map((c) => c.name);
|
||||
const seen = new Set<string>();
|
||||
// Run enough times that we'd statistically see variety
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const character = assignCharacter(allNames);
|
||||
seen.add(character.name);
|
||||
}
|
||||
// Should still pick valid characters
|
||||
for (const name of seen) {
|
||||
expect(allNames).toContain(name);
|
||||
}
|
||||
// With 100 runs and 6 characters, we should see at least 2 distinct names
|
||||
expect(seen.size).toBeGreaterThan(1);
|
||||
});
|
||||
|
||||
it("returns a character with name, avatar, title, and description", () => {
|
||||
const character = assignCharacter([]);
|
||||
expect(character.name).toBeTruthy();
|
||||
expect(character.avatar).toBeTruthy();
|
||||
expect(character.title).toBeTruthy();
|
||||
expect(character.description).toBeTruthy();
|
||||
});
|
||||
|
||||
it("works when the active list is empty", () => {
|
||||
const character = assignCharacter([]);
|
||||
expect(character).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,61 +0,0 @@
|
||||
export interface AgentCharacter {
|
||||
name: string;
|
||||
avatar: string;
|
||||
title: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export const CHARACTER_POOL: readonly AgentCharacter[] = [
|
||||
{
|
||||
name: "Amari",
|
||||
avatar: "https://cdn.nhcarrigan.com/amari.png",
|
||||
title: "Executive Assistant",
|
||||
description:
|
||||
"Fey-blooded PA and healer of the team. She always knows when you need a break — and makes sure you take one.",
|
||||
},
|
||||
{
|
||||
name: "Keiko",
|
||||
avatar: "https://cdn.nhcarrigan.com/keiko.png",
|
||||
title: "Chief Security Officer",
|
||||
description:
|
||||
"Bodyguard and shadow of the family. Conceals blades beneath evening gowns; always watching from the dark.",
|
||||
},
|
||||
{
|
||||
name: "Minori",
|
||||
avatar: "https://cdn.nhcarrigan.com/minori.png",
|
||||
title: "Chief Compliance Officer",
|
||||
description:
|
||||
"An ancient Automaton built to guard the Great Library. Perfect memory, perfect logic, perfect dedication.",
|
||||
},
|
||||
{
|
||||
name: "Reina",
|
||||
avatar: "https://cdn.nhcarrigan.com/reina.png",
|
||||
title: "Chief Legal Officer",
|
||||
description:
|
||||
"Demon of the Crossroads turned corporate lawyer. Her binding contracts have held for millennia.",
|
||||
},
|
||||
{
|
||||
name: "Tatsumi",
|
||||
avatar: "https://cdn.nhcarrigan.com/tatsumi.png",
|
||||
title: "Chief Design Officer",
|
||||
description:
|
||||
"A Siren who traded the ocean for a stylus. Uses her glamour to make every interface welcoming and beautiful.",
|
||||
},
|
||||
{
|
||||
name: "Yumiko",
|
||||
avatar: "https://cdn.nhcarrigan.com/yumiko.png",
|
||||
title: "Chief Technology Officer",
|
||||
description:
|
||||
"Technomancer and machine whisperer. She communes with machine spirits and keeps the digital world running.",
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Picks a character for a new subagent.
|
||||
* Avoids names already assigned to active agents unless all six are taken.
|
||||
*/
|
||||
export function assignCharacter(activeNames: readonly string[]): AgentCharacter {
|
||||
const available = CHARACTER_POOL.filter((c) => !activeNames.includes(c.name));
|
||||
const pool = available.length > 0 ? available : [...CHARACTER_POOL];
|
||||
return pool[Math.floor(Math.random() * pool.length)];
|
||||
}
|
||||
Reference in New Issue
Block a user