diff --git a/bun.lock b/bun.lock index b7b7927d3..855e4050b 100644 --- a/bun.lock +++ b/bun.lock @@ -410,8 +410,8 @@ "@openauthjs/openauth": "0.0.0-20250322224806", "@pierre/precision-diffs": "0.4.4", "@solidjs/meta": "0.29.4", - "@solidjs/router": "0.15.3", - "@solidjs/start": "1.1.0", + "@solidjs/router": "0.15.4", + "@solidjs/start": "1.2.0", "@tailwindcss/vite": "4.1.11", "@tsconfig/bun": "1.0.9", "@tsconfig/node22": "22.0.2", @@ -425,14 +425,14 @@ "hono-openapi": "1.1.1", "luxon": "3.6.1", "remeda": "2.26.0", - "solid-js": "1.9.9", + "solid-js": "1.9.10", "solid-list": "0.3.0", "tailwindcss": "4.1.11", "typescript": "5.8.2", "ulid": "3.0.1", "virtua": "0.42.3", "vite": "7.1.4", - "vite-plugin-solid": "2.11.8", + "vite-plugin-solid": "2.11.10", "zod": "4.1.8", }, "packages": { @@ -1418,9 +1418,9 @@ "@solidjs/meta": ["@solidjs/meta@0.29.4", "", { "peerDependencies": { "solid-js": ">=1.8.4" } }, "sha512-zdIWBGpR9zGx1p1bzIPqF5Gs+Ks/BH8R6fWhmUa/dcK1L2rUC8BAcZJzNRYBQv74kScf1TSOs0EY//Vd/I0V8g=="], - "@solidjs/router": ["@solidjs/router@0.15.3", "", { "peerDependencies": { "solid-js": "^1.8.6" } }, "sha512-iEbW8UKok2Oio7o6Y4VTzLj+KFCmQPGEpm1fS3xixwFBdclFVBvaQVeibl1jys4cujfAK5Kn6+uG2uBm3lxOMw=="], + "@solidjs/router": ["@solidjs/router@0.15.4", "", { "peerDependencies": { "solid-js": "^1.8.6" } }, "sha512-WOpgg9a9T638cR+5FGbFi/IV4l2FpmBs1GpIMSPa0Ce9vyJN7Wts+X2PqMf9IYn0zUj2MlSJtm1gp7/HI/n5TQ=="], - "@solidjs/start": ["@solidjs/start@1.1.0", "", { "dependencies": { "@tanstack/server-functions-plugin": "^1.99.5", "@vinxi/plugin-directives": "^0.5.0", "@vinxi/server-components": "^0.5.0", "defu": "^6.1.2", "error-stack-parser": "^2.1.4", "html-to-image": "^1.11.11", "radix3": "^1.1.0", "seroval": "^1.0.2", "seroval-plugins": "^1.0.2", "shiki": "^1.26.1", "source-map-js": "^1.0.2", "terracotta": "^1.0.4", "tinyglobby": "^0.2.2", "vite-plugin-solid": "^2.11.1" }, "peerDependencies": { "vinxi": "^0.5.3" } }, "sha512-7MNhNVt8uF7tdvLkvJhj4357vg3Ha+yqJP8XhQ6IbSZbsyk/xMkYmfc1h6w4GWiWZ5tn1DvS1uqGXjLFbKRy6g=="], + "@solidjs/start": ["@solidjs/start@1.2.0", "", { "dependencies": { "@tanstack/server-functions-plugin": "1.121.21", "@vinxi/plugin-directives": "^0.5.0", "@vinxi/server-components": "^0.5.0", "cookie-es": "^2.0.0", "defu": "^6.1.2", "error-stack-parser": "^2.1.4", "html-to-image": "^1.11.11", "radix3": "^1.1.0", "seroval": "^1.0.2", "seroval-plugins": "^1.0.2", "shiki": "^1.26.1", "source-map-js": "^1.0.2", "terracotta": "^1.0.4", "tinyglobby": "^0.2.2", "vite-plugin-solid": "^2.11.1" }, "peerDependencies": { "vinxi": "^0.5.7" } }, "sha512-SRv1g3R+4sxZnxCBPK1IedtLKsPhPJ7W/Yv4xEHjM4jJGPWi3ed35/yd0D5zhRK0C7zJIkZKbhnR/S3g8JUD5w=="], "@speed-highlight/core": ["@speed-highlight/core@1.2.12", "", {}, "sha512-uilwrK0Ygyri5dToHYdZSjcvpS2ZwX0w5aSt3GCEN9hrjxWCoeV4Z2DTXuxjwbntaLQIEEAlCeNQss5SoHvAEA=="], @@ -1462,11 +1462,11 @@ "@tailwindcss/vite": ["@tailwindcss/vite@4.1.11", "", { "dependencies": { "@tailwindcss/node": "4.1.11", "@tailwindcss/oxide": "4.1.11", "tailwindcss": "4.1.11" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-RHYhrR3hku0MJFRV+fN2gNbDNEh3dwKvY8XJvTxCSXeMOsCRSr+uKvDWQcbizrHgjML6ZmTE5OwMrl5wKcujCw=="], - "@tanstack/directive-functions-plugin": ["@tanstack/directive-functions-plugin@1.139.0", "", { "dependencies": { "@babel/code-frame": "7.27.1", "@babel/core": "^7.27.7", "@babel/traverse": "^7.27.7", "@babel/types": "^7.27.7", "@tanstack/router-utils": "1.139.0", "babel-dead-code-elimination": "^1.0.10", "pathe": "^2.0.3", "tiny-invariant": "^1.3.3" }, "peerDependencies": { "vite": ">=6.0.0 || >=7.0.0" } }, "sha512-qLGxldnWa0pp/siZEFEYDU+eB/j40bd1V3IuTzP0sFnrYi11Ldx1yVkOruDKUbO1WM0o+OlPhp22Q1h+LMdDMA=="], + "@tanstack/directive-functions-plugin": ["@tanstack/directive-functions-plugin@1.121.21", "", { "dependencies": { "@babel/code-frame": "7.26.2", "@babel/core": "^7.26.8", "@babel/traverse": "^7.26.8", "@babel/types": "^7.26.8", "@tanstack/router-utils": "^1.121.21", "babel-dead-code-elimination": "^1.0.10", "tiny-invariant": "^1.3.3" }, "peerDependencies": { "vite": ">=6.0.0" } }, "sha512-B9z/HbF7gJBaRHieyX7f2uQ4LpLLAVAEutBZipH6w+CYD6RHRJvSVPzECGHF7icFhNWTiJQL2QR6K07s59yzEw=="], "@tanstack/router-utils": ["@tanstack/router-utils@1.139.0", "", { "dependencies": { "@babel/core": "^7.27.4", "@babel/generator": "^7.27.5", "@babel/parser": "^7.27.5", "@babel/preset-typescript": "^7.27.1", "ansis": "^4.1.0", "diff": "^8.0.2", "pathe": "^2.0.3", "tinyglobby": "^0.2.15" } }, "sha512-jT7D6NimWqoFSkid4vCno8gvTyfL1+NHpgm3es0B2UNhKKRV3LngOGilm1m6v8Qvk/gy6Fh/tvB+s+hBl6GhOg=="], - "@tanstack/server-functions-plugin": ["@tanstack/server-functions-plugin@1.139.0", "", { "dependencies": { "@babel/code-frame": "7.27.1", "@babel/core": "^7.27.7", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/template": "^7.27.2", "@babel/traverse": "^7.27.7", "@babel/types": "^7.27.7", "@tanstack/directive-functions-plugin": "1.139.0", "babel-dead-code-elimination": "^1.0.9", "tiny-invariant": "^1.3.3" } }, "sha512-IpNFiCoy2YU6gY/4lCKIVlFyU67ltlcUMGcdnrevqOgq20AbMyeLbbBVo9tAA3TkHK9F+9Hd7DqGXsup2pmBLg=="], + "@tanstack/server-functions-plugin": ["@tanstack/server-functions-plugin@1.121.21", "", { "dependencies": { "@babel/code-frame": "7.26.2", "@babel/core": "^7.26.8", "@babel/plugin-syntax-jsx": "^7.25.9", "@babel/plugin-syntax-typescript": "^7.25.9", "@babel/template": "^7.26.8", "@babel/traverse": "^7.26.8", "@babel/types": "^7.26.8", "@tanstack/directive-functions-plugin": "1.121.21", "babel-dead-code-elimination": "^1.0.9", "tiny-invariant": "^1.3.3" } }, "sha512-a05fzK+jBGacsSAc1vE8an7lpBh4H0PyIEcivtEyHLomgSeElAJxm9E2It/0nYRZ5Lh23m0okbhzJNaYWZpAOg=="], "@thisbeyond/solid-dnd": ["@thisbeyond/solid-dnd@0.7.5", "", { "peerDependencies": { "solid-js": "^1.5" } }, "sha512-DfI5ff+yYGpK9M21LhYwIPlbP2msKxN2ARwuu6GF8tT1GgNVDTI8VCQvH4TJFoVApP9d44izmAcTh/iTCH2UUw=="], @@ -1552,7 +1552,7 @@ "@types/scheduler": ["@types/scheduler@0.26.0", "", {}, "sha512-WFHp9YUJQ6CKshqoC37iOlHnQSmxNc795UhB26CyBBttrN9svdIrUjl/NjnNmfcwtncN0h/0PPAFWv9ovP8mLA=="], - "@types/send": ["@types/send@1.2.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ=="], + "@types/send": ["@types/send@0.17.6", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og=="], "@types/serve-static": ["@types/serve-static@1.15.10", "", { "dependencies": { "@types/http-errors": "*", "@types/node": "*", "@types/send": "<1" } }, "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw=="], @@ -1898,7 +1898,7 @@ "cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="], - "cookie-es": ["cookie-es@1.2.2", "", {}, "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg=="], + "cookie-es": ["cookie-es@2.0.0", "", {}, "sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg=="], "cookie-signature": ["cookie-signature@1.0.6", "", {}, "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="], @@ -3274,7 +3274,7 @@ "smol-toml": ["smol-toml@1.5.2", "", {}, "sha512-QlaZEqcAH3/RtNyet1IPIYPsEWAaYyXXv1Krsi+1L/QHppjX4Ifm8MQsBISz9vE8cHicIq3clogsheili5vhaQ=="], - "solid-js": ["solid-js@1.9.9", "", { "dependencies": { "csstype": "^3.1.0", "seroval": "~1.3.0", "seroval-plugins": "~1.3.0" } }, "sha512-A0ZBPJQldAeGCTW0YRYJmt7RCeh5rbFfPZ2aOttgYnctHE7HgKeHCBB/PVc2P7eOfmNXqMFFFoYYdm3S4dcbkA=="], + "solid-js": ["solid-js@1.9.10", "", { "dependencies": { "csstype": "^3.1.0", "seroval": "~1.3.0", "seroval-plugins": "~1.3.0" } }, "sha512-Coz956cos/EPDlhs6+jsdTxKuJDPT7B5SVIWgABwROyxjY7Xbr8wkzD68Et+NxnV7DLJ3nJdAC2r9InuV/4Jew=="], "solid-list": ["solid-list@0.3.0", "", { "dependencies": { "@corvu/utils": "~0.4.0" }, "peerDependencies": { "solid-js": "^1.8" } }, "sha512-t4hx/F/l8Vmq+ib9HtZYl7Z9F1eKxq3eKJTXlvcm7P7yI4Z8O7QSOOEVHb/K6DD7M0RxzVRobK/BS5aSfLRwKg=="], @@ -3590,7 +3590,7 @@ "vite-plugin-icons-spritesheet": ["vite-plugin-icons-spritesheet@3.0.1", "", { "dependencies": { "chalk": "^5.4.1", "glob": "^11.0.1", "node-html-parser": "^7.0.1", "tinyexec": "^0.3.2" }, "peerDependencies": { "vite": ">=5.2.0" } }, "sha512-Cr0+Z6wRMwSwKisWW9PHeTjqmQFv0jwRQQMc3YgAhAgZEe03j21el0P/CA31KN/L5eiL1LhR14VTXl96LetonA=="], - "vite-plugin-solid": ["vite-plugin-solid@2.11.8", "", { "dependencies": { "@babel/core": "^7.23.3", "@types/babel__core": "^7.20.4", "babel-preset-solid": "^1.8.4", "merge-anything": "^5.1.7", "solid-refresh": "^0.6.3", "vitefu": "^1.0.4" }, "peerDependencies": { "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", "solid-js": "^1.7.2", "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["@testing-library/jest-dom"] }, "sha512-hFrCxBfv3B1BmFqnJF4JOCYpjrmi/zwyeKjcomQ0khh8HFyQ8SbuBWQ7zGojfrz6HUOBFrJBNySDi/JgAHytWg=="], + "vite-plugin-solid": ["vite-plugin-solid@2.11.10", "", { "dependencies": { "@babel/core": "^7.23.3", "@types/babel__core": "^7.20.4", "babel-preset-solid": "^1.8.4", "merge-anything": "^5.1.7", "solid-refresh": "^0.6.3", "vitefu": "^1.0.4" }, "peerDependencies": { "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", "solid-js": "^1.7.2", "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["@testing-library/jest-dom"] }, "sha512-Yr1dQybmtDtDAHkii6hXuc1oVH9CPcS/Zb2jN/P36qqcrkNnVPsMTzQ06jyzFPFjj3U1IYKMVt/9ZqcwGCEbjw=="], "vitefu": ["vitefu@1.1.1", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ=="], @@ -3924,11 +3924,11 @@ "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@tanstack/directive-functions-plugin/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + "@tanstack/directive-functions-plugin/@babel/code-frame": ["@babel/code-frame@7.26.2", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.25.9", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" } }, "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ=="], "@tanstack/router-utils/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], - "@types/serve-static/@types/send": ["@types/send@0.17.6", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og=="], + "@tanstack/server-functions-plugin/@babel/code-frame": ["@babel/code-frame@7.26.2", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.25.9", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" } }, "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ=="], "@vercel/nft/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], @@ -4048,6 +4048,8 @@ "gray-matter/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], + "h3/cookie-es": ["cookie-es@1.2.2", "", {}, "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg=="], + "handlebars/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], "hast-util-to-parse5/property-information": ["property-information@6.5.0", "", {}, "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig=="], @@ -4092,8 +4094,6 @@ "nitropack/c12": ["c12@3.3.2", "", { "dependencies": { "chokidar": "^4.0.3", "confbox": "^0.2.2", "defu": "^6.1.4", "dotenv": "^17.2.3", "exsolve": "^1.0.8", "giget": "^2.0.0", "jiti": "^2.6.1", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^2.0.0", "pkg-types": "^2.3.0", "rc9": "^2.1.2" }, "peerDependencies": { "magicast": "*" }, "optionalPeers": ["magicast"] }, "sha512-QkikB2X5voO1okL3QsES0N690Sn/K9WokXqUsDQsWy5SnYb+psYQFGA10iy1bZHj3fjISKsI67Q90gruvWWM3A=="], - "nitropack/cookie-es": ["cookie-es@2.0.0", "", {}, "sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg=="], - "nitropack/globby": ["globby@15.0.0", "", { "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "fast-glob": "^3.3.3", "ignore": "^7.0.5", "path-type": "^6.0.0", "slash": "^5.1.0", "unicorn-magic": "^0.3.0" } }, "sha512-oB4vkQGqlMl682wL1IlWd02tXCbquGWM4voPEI85QmNKCaw8zGTm1f1rubFgkg3Eli2PtKlFgrnmUqasbQWlkw=="], "nitropack/h3": ["h3@1.15.4", "", { "dependencies": { "cookie-es": "^1.2.2", "crossws": "^0.3.5", "defu": "^6.1.4", "destr": "^2.0.5", "iron-webcrypto": "^1.2.1", "node-mock-http": "^1.0.2", "radix3": "^1.1.2", "ufo": "^1.6.1", "uncrypto": "^0.1.3" } }, "sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ=="], @@ -4256,8 +4256,6 @@ "yargs/yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="], - "youch/cookie-es": ["cookie-es@2.0.0", "", {}, "sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg=="], - "zod-to-json-schema/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], "zod-to-ts/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], @@ -4664,6 +4662,8 @@ "listhen/@parcel/watcher-wasm/napi-wasm": ["napi-wasm@1.1.3", "", { "bundled": true }, "sha512-h/4nMGsHjZDCYmQVNODIrYACVJ+I9KItbG+0si6W/jSjdA9JbWDoU4LLeMXVcEQGHjttI2tuXqDrbGF7qkUHHg=="], + "listhen/h3/cookie-es": ["cookie-es@1.2.2", "", {}, "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg=="], + "miniflare/sharp/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], "mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], @@ -4722,6 +4722,8 @@ "type-is/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + "unstorage/h3/cookie-es": ["cookie-es@1.2.2", "", {}, "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg=="], + "wrangler/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q=="], "wrangler/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.4", "", { "os": "android", "cpu": "arm" }, "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ=="], diff --git a/package.json b/package.json index d0e78f80f..6b5409131 100644 --- a/package.json +++ b/package.json @@ -29,9 +29,6 @@ "@cloudflare/workers-types": "4.20251008.0", "@openauthjs/openauth": "0.0.0-20250322224806", "@pierre/precision-diffs": "0.4.4", - "@solidjs/meta": "0.29.4", - "@solidjs/router": "0.15.3", - "@solidjs/start": "1.1.0", "@tailwindcss/vite": "4.1.11", "diff": "8.0.2", "ai": "5.0.97", @@ -43,12 +40,15 @@ "@typescript/native-preview": "7.0.0-dev.20251014.1", "zod": "4.1.8", "remeda": "2.26.0", - "solid-js": "1.9.9", "solid-list": "0.3.0", "tailwindcss": "4.1.11", "virtua": "0.42.3", "vite": "7.1.4", - "vite-plugin-solid": "2.11.8" + "@solidjs/meta": "0.29.4", + "@solidjs/router": "0.15.4", + "@solidjs/start": "1.2.0", + "solid-js": "1.9.10", + "vite-plugin-solid": "2.11.10" } }, "devDependencies": { diff --git a/packages/desktop/src/components/file-tree.tsx b/packages/desktop/src/components/file-tree.tsx index 9544bc965..f3729a8d3 100644 --- a/packages/desktop/src/components/file-tree.tsx +++ b/packages/desktop/src/components/file-tree.tsx @@ -1,6 +1,7 @@ import { useLocal, type LocalFile } from "@/context/local" -import { FileIcon, Tooltip } from "@opencode-ai/ui" import { Collapsible } from "@/ui" +import { FileIcon } from "@opencode-ai/ui/file-icon" +import { Tooltip } from "@opencode-ai/ui/tooltip" import { For, Match, Switch, Show, type ComponentProps, type ParentProps } from "solid-js" import { Dynamic } from "solid-js/web" diff --git a/packages/desktop/src/components/prompt-input.tsx b/packages/desktop/src/components/prompt-input.tsx index 958b5e4d1..3ed334cf4 100644 --- a/packages/desktop/src/components/prompt-input.tsx +++ b/packages/desktop/src/components/prompt-input.tsx @@ -1,4 +1,3 @@ -import { Button, FileIcon, Icon, IconButton, Select, SelectDialog, Tooltip } from "@opencode-ai/ui" import { useFilteredList } from "@opencode-ai/ui/hooks" import { createEffect, on, Component, Show, For, onMount, onCleanup, Switch, Match } from "solid-js" import { createStore } from "solid-js/store" @@ -10,6 +9,13 @@ import { ContentPart, DEFAULT_PROMPT, isPromptEqual, Prompt, useSession } from " import { useSDK } from "@/context/sdk" import { useNavigate } from "@solidjs/router" import { useSync } from "@/context/sync" +import { FileIcon } from "@opencode-ai/ui/file-icon" +import { SelectDialog } from "@opencode-ai/ui/select-dialog" +import { Button } from "@opencode-ai/ui/button" +import { Icon } from "@opencode-ai/ui/icon" +import { Tooltip } from "@opencode-ai/ui/tooltip" +import { IconButton } from "@opencode-ai/ui/icon-button" +import { Select } from "@opencode-ai/ui/select" interface PromptInputProps { class?: string @@ -183,8 +189,8 @@ export const PromptInput: Component = (props) => { const range = selection.getRangeAt(0) if (atMatch) { - let node: Node | null = range.startContainer - let offset = range.startOffset + // let node: Node | null = range.startContainer + // let offset = range.startOffset let runningLength = 0 const walker = document.createTreeWalker(editorRef, NodeFilter.SHOW_TEXT, null) diff --git a/packages/desktop/src/index.tsx b/packages/desktop/src/index.tsx index f35600895..43168a021 100644 --- a/packages/desktop/src/index.tsx +++ b/packages/desktop/src/index.tsx @@ -3,7 +3,8 @@ import "@/index.css" import { render } from "solid-js/web" import { Router, Route, Navigate } from "@solidjs/router" import { MetaProvider } from "@solidjs/meta" -import { Fonts, MarkedProvider } from "@opencode-ai/ui" +import { Fonts } from "@opencode-ai/ui/fonts" +import { MarkedProvider } from "@opencode-ai/ui/context/marked" import { GlobalSyncProvider, useGlobalSync } from "./context/global-sync" import Layout from "@/pages/layout" import DirectoryLayout from "@/pages/directory-layout" diff --git a/packages/desktop/src/pages/home.tsx b/packages/desktop/src/pages/home.tsx index e2f99afa8..e773fff57 100644 --- a/packages/desktop/src/pages/home.tsx +++ b/packages/desktop/src/pages/home.tsx @@ -2,7 +2,7 @@ import { useGlobalSync } from "@/context/global-sync" import { base64Encode, getFilename } from "@/utils" import { For } from "solid-js" import { A } from "@solidjs/router" -import { Button } from "@opencode-ai/ui" +import { Button } from "@opencode-ai/ui/button" export default function Home() { const sync = useGlobalSync() diff --git a/packages/desktop/src/pages/layout.tsx b/packages/desktop/src/pages/layout.tsx index d882f7905..c9bb559d8 100644 --- a/packages/desktop/src/pages/layout.tsx +++ b/packages/desktop/src/pages/layout.tsx @@ -1,10 +1,16 @@ -import { Button, Tooltip, DiffChanges, IconButton, Mark, Icon, Collapsible } from "@opencode-ai/ui" import { createMemo, For, ParentProps, Show } from "solid-js" import { DateTime } from "luxon" import { A, useParams } from "@solidjs/router" import { useLayout } from "@/context/layout" import { useGlobalSync } from "@/context/global-sync" import { base64Encode, getFilename } from "@/utils" +import { Mark } from "@opencode-ai/ui/logo" +import { Button } from "@opencode-ai/ui/button" +import { Icon } from "@opencode-ai/ui/icon" +import { IconButton } from "@opencode-ai/ui/icon-button" +import { Tooltip } from "@opencode-ai/ui/tooltip" +import { Collapsible } from "@opencode-ai/ui/collapsible" +import { DiffChanges } from "@opencode-ai/ui/diff-changes" export default function Layout(props: ParentProps) { const params = useParams() diff --git a/packages/desktop/src/pages/session.tsx b/packages/desktop/src/pages/session.tsx index 3c6b92f57..8d166cd37 100644 --- a/packages/desktop/src/pages/session.tsx +++ b/packages/desktop/src/pages/session.tsx @@ -1,39 +1,20 @@ -import { - SelectDialog, - IconButton, - Tabs, - Icon, - Accordion, - Diff, - Collapsible, - DiffChanges, - Message, - Typewriter, - Card, - Code, - Tooltip, - ProgressCircle, - FileIcon, - SessionReview, - MessageProgress, -} from "@opencode-ai/ui" -import { - For, - onCleanup, - onMount, - Show, - Match, - Switch, - createSignal, - createEffect, - createMemo, - createResource, -} from "solid-js" +import { For, onCleanup, onMount, Show, Match, Switch, createResource } from "solid-js" import { useLocal, type LocalFile } from "@/context/local" import { createStore } from "solid-js/store" import { getDirectory, getFilename } from "@/utils" import { PromptInput } from "@/components/prompt-input" import { DateTime } from "luxon" +import { FileIcon } from "@opencode-ai/ui/file-icon" +import { IconButton } from "@opencode-ai/ui/icon-button" +import { Icon } from "@opencode-ai/ui/icon" +import { Tooltip } from "@opencode-ai/ui/tooltip" +import { DiffChanges } from "@opencode-ai/ui/diff-changes" +import { ProgressCircle } from "@opencode-ai/ui/progress-circle" +import { Tabs } from "@opencode-ai/ui/tabs" +import { Code } from "@opencode-ai/ui/code" +import { SessionTimeline } from "@opencode-ai/ui/session-timeline" +import { SessionReview } from "@opencode-ai/ui/session-review" +import { SelectDialog } from "@opencode-ai/ui/select-dialog" import { DragDropProvider, DragDropSensors, @@ -46,11 +27,8 @@ import { import type { DragEvent, Transformer } from "@thisbeyond/solid-dnd" import type { JSX } from "solid-js" import { useSync } from "@/context/sync" -import { type AssistantMessage as AssistantMessageType } from "@opencode-ai/sdk" -import { Markdown, Spinner, StickyAccordionHeader } from "@opencode-ai/ui" import { useSession } from "@/context/session" import { useLayout } from "@/context/layout" -import { createSessionSeen } from "@/hooks/create-session-seen" export default function Page() { const layout = useLayout() @@ -63,7 +41,6 @@ export default function Page() { activeDraggable: undefined as string | undefined, }) let inputRef!: HTMLDivElement - let messageScrollElement!: HTMLDivElement const MOD = typeof navigator === "object" && /(Mac|iPod|iPhone|iPad)/.test(navigator.platform) ? "Meta" : "Control" @@ -356,284 +333,10 @@ export default function Page() {
-
- 1}> - {(_) => { - const expanded = createMemo(() => layout.review.state() === "tab" || !session.diffs().length) - - return ( -
    - - {(message) => { - const working = createMemo( - () => message.id === session.messages.last()?.id && session.working(), - ) - const handleClick = () => session.messages.setActive(message.id) - - return ( -
  • - - - {message.summary?.title} -
- } - > - - - - - ) - }} - - - ) - }} - -
- - {(message) => { - const isActive = createMemo(() => session.messages.active()?.id === message.id) - const titleSeen = createSessionSeen(`message-title-${message.id}`) - const contentSeen = createSessionSeen(`message-content-${message.id}`) - const [titled, setTitled] = createSignal(titleSeen()) - const assistantMessages = createMemo(() => { - if (!session.id) return [] - return sync.data.message[session.id]?.filter( - (m) => m.role === "assistant" && m.parentID == message.id, - ) as AssistantMessageType[] - }) - const error = createMemo(() => assistantMessages().find((m) => m?.error)?.error) - const [detailsExpanded, setDetailsExpanded] = createSignal(false) - const parts = createMemo(() => sync.data.part[message.id]) - const hasToolPart = createMemo(() => - assistantMessages() - ?.flatMap((m) => sync.data.part[m.id]) - .some((p) => p?.type === "tool"), - ) - const working = createMemo( - () => message.id === session.messages.last()?.id && session.working(), - ) - const initialCompleted = !(message.id === session.messages.last()?.id && session.working()) - const [completed, setCompleted] = createSignal(initialCompleted) - - // allowing time for the animations to finish - createEffect(() => { - if (titleSeen()) return - const title = message.summary?.title - if (title) setTimeout(() => setTitled(true), 10_000) - }) - createEffect(() => { - const completed = !working() - setTimeout(() => setCompleted(completed), 1200) - }) - - return ( - -
- {/* Title */} -
-
- - } - > -

- {message.summary?.title} -

-
-
-
- - {/* Summary */} - -
-
-

- - Summary - Response - -

- - {(summary) => ( - *]:fade-up-text": !message.summary?.diffs?.length && !contentSeen(), - }} - text={summary()} - /> - )} - -
- - - {(diff) => ( - - - -
-
- -
- - - {getDirectory(diff.file)}‎ - - - - {getFilename(diff.file)} - -
-
-
- - -
-
-
-
- - - -
- )} -
-
-
-
- - - {error()?.data?.message as string} - - - {/* Response */} -
- - - - - - - -
-
- - Hide details - Show details - -
- -
-
- -
- - {(assistantMessage) => { - const parts = createMemo(() => sync.data.part[assistantMessage.id]) - return - }} - - - - {error()?.data?.message as string} - - -
-
-
-
-
-
-
-
- ) - }} -
-
-
+
diff --git a/packages/desktop/src/ui/collapsible.tsx b/packages/desktop/src/ui/collapsible.tsx index fbc6fcbfe..5fbb6c7a4 100644 --- a/packages/desktop/src/ui/collapsible.tsx +++ b/packages/desktop/src/ui/collapsible.tsx @@ -1,7 +1,7 @@ import { Collapsible as KobalteCollapsible } from "@kobalte/core/collapsible" +import { Icon, IconProps } from "@opencode-ai/ui/icon" import { splitProps } from "solid-js" import type { ComponentProps, ParentProps } from "solid-js" -import { Icon, type IconProps } from "@opencode-ai/ui" export interface CollapsibleProps extends ComponentProps {} export interface CollapsibleTriggerProps extends ComponentProps {} diff --git a/packages/desktop/vite.config.ts b/packages/desktop/vite.config.ts index d3c394bcb..8e43b9835 100644 --- a/packages/desktop/vite.config.ts +++ b/packages/desktop/vite.config.ts @@ -12,6 +12,7 @@ export default defineConfig({ plugins: [tailwindcss(), solidPlugin()], server: { host: "0.0.0.0", + allowedHosts: true, port: 3000, }, build: { diff --git a/packages/enterprise/app.config.ts b/packages/enterprise/app.config.ts index 2909c7939..1feaf9c0e 100644 --- a/packages/enterprise/app.config.ts +++ b/packages/enterprise/app.config.ts @@ -4,5 +4,9 @@ import tailwindcss from "@tailwindcss/vite" export default defineConfig({ vite: { plugins: [tailwindcss() as any], + server: { + host: "0.0.0.0", + allowedHosts: true, + }, }, }) diff --git a/packages/enterprise/src/app.tsx b/packages/enterprise/src/app.tsx index 8ed7dd27b..fd10899f2 100644 --- a/packages/enterprise/src/app.tsx +++ b/packages/enterprise/src/app.tsx @@ -3,6 +3,7 @@ import { FileRoutes } from "@solidjs/start/router" import { Suspense } from "solid-js" import { Fonts } from "@opencode-ai/ui/fonts" import { MetaProvider } from "@solidjs/meta" +import { MarkedProvider } from "@opencode-ai/ui/context/marked" import "./app.css" export default function App() { @@ -11,10 +12,12 @@ export default function App() { root={(props) => ( <> - - - {props.children} - + + + + {props.children} + + )} diff --git a/packages/enterprise/src/core/share.ts b/packages/enterprise/src/core/share.ts index b8b36a048..4e2fe9f2a 100644 --- a/packages/enterprise/src/core/share.ts +++ b/packages/enterprise/src/core/share.ts @@ -1,4 +1,4 @@ -import { FileDiff, Message, Part, Session } from "@opencode-ai/sdk" +import { FileDiff, Message, Part, Session, SessionStatus } from "@opencode-ai/sdk" import { fn } from "@opencode-ai/util/fn" import { iife } from "@opencode-ai/util/iife" import z from "zod" @@ -28,6 +28,10 @@ export namespace Share { type: z.literal("session_diff"), data: z.custom(), }), + z.object({ + type: z.literal("session_status"), + data: z.custom(), + }), ]) export type Data = z.infer @@ -92,6 +96,9 @@ export namespace Share { case "session_diff": await Storage.write(["share_data", input.share.id, "session_diff"], item.data) break + case "session_status": + await Storage.write(["share_data", input.share.id, "session_status"], item.data) + break } }), ) diff --git a/packages/enterprise/src/routes/share/[sessionID].tsx b/packages/enterprise/src/routes/share/[sessionID].tsx index fbf94f694..28df1ff90 100644 --- a/packages/enterprise/src/routes/share/[sessionID].tsx +++ b/packages/enterprise/src/routes/share/[sessionID].tsx @@ -1,5 +1,9 @@ -import { FileDiff, Message, Part, Session } from "@opencode-ai/sdk" +import { FileDiff, Message, Part, Session, SessionStatus } from "@opencode-ai/sdk" +import { SessionTimeline } from "@opencode-ai/ui/session-timeline" +import { SessionReview } from "@opencode-ai/ui/session-review" +import { DataProvider } from "@opencode-ai/ui/context" import { createAsync, query, RouteDefinition, useParams } from "@solidjs/router" +import { Show } from "solid-js" import { Share } from "~/core/share" const getData = query(async (sessionID) => { @@ -9,6 +13,9 @@ const getData = query(async (sessionID) => { session_diff: { [sessionID: string]: FileDiff[] } + session_status: { + [sessionID: string]: SessionStatus + } message: { [sessionID: string]: Message[] } @@ -20,6 +27,11 @@ const getData = query(async (sessionID) => { session_diff: { [sessionID]: [], }, + session_status: { + [sessionID]: { + type: "idle", + }, + }, message: {}, part: {}, } @@ -32,6 +44,9 @@ const getData = query(async (sessionID) => { case "session_diff": result.session_diff[sessionID] = item.data break + case "session_status": + result.session_status[sessionID] = item.data + break case "message": result.message[item.data.sessionID] = result.message[item.data.sessionID] ?? [] result.message[item.data.sessionID].push(item.data) @@ -55,5 +70,26 @@ export default function () { if (!params.sessionID) return return getData(params.sessionID) }) - return
{JSON.stringify(data(), null, 2)}
+ return ( + + {(data) => ( + +
+
+
+
+ +
+ +
+ +
+
+
+
+
+
+ )} +
+ ) } diff --git a/packages/ui/package.json b/packages/ui/package.json index d7be24552..c12f16bfb 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -3,11 +3,10 @@ "version": "1.0.85", "type": "module", "exports": { - ".": "./src/components/index.ts", "./*": "./src/components/*.tsx", "./hooks": "./src/hooks/index.ts", "./context": "./src/context/index.ts", - "./context/*": "./src/context/*", + "./context/*": "./src/context/*.tsx", "./styles": "./src/styles/index.css", "./styles/tailwind": "./src/styles/tailwind/index.css", "./fonts/*": "./src/assets/fonts/*" diff --git a/packages/ui/src/components/diff.tsx b/packages/ui/src/components/diff.tsx index d0d427499..8743be290 100644 --- a/packages/ui/src/components/diff.tsx +++ b/packages/ui/src/components/diff.tsx @@ -4,8 +4,6 @@ import { type DiffLineAnnotation, type HunkData, FileDiffOptions, - registerCustomTheme, - ThemeRegistrationResolved, } from "@pierre/precision-diffs" import { ComponentProps, createEffect, splitProps } from "solid-js" @@ -173,373 +171,3 @@ export function Diff(props: DiffProps) { /> ) } - -registerCustomTheme("OpenCode", () => { - return Promise.resolve({ - name: "OpenCode", - colors: { - "editor.background": "transparent", - "editor.foreground": "var(--text-base)", - "gitDecoration.addedResourceForeground": "var(--syntax-diff-add)", - "gitDecoration.deletedResourceForeground": "var(--syntax-diff-delete)", - // "gitDecoration.conflictingResourceForeground": "#ffca00", - // "gitDecoration.modifiedResourceForeground": "#1a76d4", - // "gitDecoration.untrackedResourceForeground": "#00cab1", - // "gitDecoration.ignoredResourceForeground": "#84848A", - // "terminal.titleForeground": "#adadb1", - // "terminal.titleInactiveForeground": "#84848A", - // "terminal.background": "#141415", - // "terminal.foreground": "#adadb1", - // "terminal.ansiBlack": "#141415", - // "terminal.ansiRed": "#ff2e3f", - // "terminal.ansiGreen": "#0dbe4e", - // "terminal.ansiYellow": "#ffca00", - // "terminal.ansiBlue": "#008cff", - // "terminal.ansiMagenta": "#c635e4", - // "terminal.ansiCyan": "#08c0ef", - // "terminal.ansiWhite": "#c6c6c8", - // "terminal.ansiBrightBlack": "#141415", - // "terminal.ansiBrightRed": "#ff2e3f", - // "terminal.ansiBrightGreen": "#0dbe4e", - // "terminal.ansiBrightYellow": "#ffca00", - // "terminal.ansiBrightBlue": "#008cff", - // "terminal.ansiBrightMagenta": "#c635e4", - // "terminal.ansiBrightCyan": "#08c0ef", - // "terminal.ansiBrightWhite": "#c6c6c8", - }, - tokenColors: [ - { - scope: ["comment", "punctuation.definition.comment", "string.comment"], - settings: { - foreground: "var(--syntax-comment)", - }, - }, - { - scope: ["entity.other.attribute-name"], - settings: { - foreground: "var(--syntax-property)", // maybe attribute - }, - }, - { - scope: ["constant", "entity.name.constant", "variable.other.constant", "variable.language", "entity"], - settings: { - foreground: "var(--syntax-constant)", - }, - }, - { - scope: ["entity.name", "meta.export.default", "meta.definition.variable"], - settings: { - foreground: "var(--syntax-type)", - }, - }, - { - scope: ["meta.object.member"], - settings: { - foreground: "var(--syntax-primitive)", - }, - }, - { - scope: [ - "variable.parameter.function", - "meta.jsx.children", - "meta.block", - "meta.tag.attributes", - "entity.name.constant", - "meta.embedded.expression", - "meta.template.expression", - "string.other.begin.yaml", - "string.other.end.yaml", - ], - settings: { - foreground: "var(--syntax-punctuation)", - }, - }, - { - scope: ["entity.name.function", "support.type.primitive"], - settings: { - foreground: "var(--syntax-primitive)", - }, - }, - { - scope: ["support.class.component"], - settings: { - foreground: "var(--syntax-type)", - }, - }, - { - scope: "keyword", - settings: { - foreground: "var(--syntax-keyword)", - }, - }, - { - scope: [ - "keyword.operator", - "storage.type.function.arrow", - "punctuation.separator.key-value.css", - "entity.name.tag.yaml", - "punctuation.separator.key-value.mapping.yaml", - ], - settings: { - foreground: "var(--syntax-operator)", - }, - }, - { - scope: ["storage", "storage.type"], - settings: { - foreground: "var(--syntax-keyword)", - }, - }, - { - scope: ["storage.modifier.package", "storage.modifier.import", "storage.type.java"], - settings: { - foreground: "var(--syntax-primitive)", - }, - }, - { - scope: [ - "string", - "punctuation.definition.string", - "string punctuation.section.embedded source", - "entity.name.tag", - ], - settings: { - foreground: "var(--syntax-string)", - }, - }, - { - scope: "support", - settings: { - foreground: "var(--syntax-primitive)", - }, - }, - { - scope: ["support.type.object.module", "variable.other.object", "support.type.property-name.css"], - settings: { - foreground: "var(--syntax-object)", - }, - }, - { - scope: "meta.property-name", - settings: { - foreground: "var(--syntax-property)", - }, - }, - { - scope: "variable", - settings: { - foreground: "var(--syntax-variable)", - }, - }, - { - scope: "variable.other", - settings: { - foreground: "var(--syntax-variable)", - }, - }, - { - scope: [ - "invalid.broken", - "invalid.illegal", - "invalid.unimplemented", - "invalid.deprecated", - "message.error", - "markup.deleted", - "meta.diff.header.from-file", - "punctuation.definition.deleted", - "brackethighlighter.unmatched", - "token.error-token", - ], - settings: { - foreground: "var(--syntax-critical)", - }, - }, - { - scope: "carriage-return", - settings: { - foreground: "var(--syntax-keyword)", - }, - }, - { - scope: "string source", - settings: { - foreground: "var(--syntax-variable)", - }, - }, - { - scope: "string variable", - settings: { - foreground: "var(--syntax-constant)", - }, - }, - { - scope: [ - "source.regexp", - "string.regexp", - "string.regexp.character-class", - "string.regexp constant.character.escape", - "string.regexp source.ruby.embedded", - "string.regexp string.regexp.arbitrary-repitition", - "string.regexp constant.character.escape", - ], - settings: { - foreground: "var(--syntax-regexp)", - }, - }, - { - scope: "support.constant", - settings: { - foreground: "var(--syntax-primitive)", - }, - }, - { - scope: "support.variable", - settings: { - foreground: "var(--syntax-variable)", - }, - }, - { - scope: "meta.module-reference", - settings: { - foreground: "var(--syntax-info)", - }, - }, - { - scope: "punctuation.definition.list.begin.markdown", - settings: { - foreground: "var(--syntax-punctuation)", - }, - }, - { - scope: ["markup.heading", "markup.heading entity.name"], - settings: { - fontStyle: "bold", - foreground: "var(--syntax-info)", - }, - }, - { - scope: "markup.quote", - settings: { - foreground: "var(--syntax-info)", - }, - }, - { - scope: "markup.italic", - settings: { - fontStyle: "italic", - // foreground: "", - }, - }, - { - scope: "markup.bold", - settings: { - fontStyle: "bold", - foreground: "var(--text-strong)", - }, - }, - { - scope: [ - "markup.raw", - "markup.inserted", - "meta.diff.header.to-file", - "punctuation.definition.inserted", - "markup.changed", - "punctuation.definition.changed", - "markup.ignored", - "markup.untracked", - ], - settings: { - foreground: "var(--text-base)", - }, - }, - { - scope: "meta.diff.range", - settings: { - fontStyle: "bold", - foreground: "var(--syntax-unknown)", - }, - }, - { - scope: "meta.diff.header", - settings: { - foreground: "var(--syntax-unknown)", - }, - }, - { - scope: "meta.separator", - settings: { - fontStyle: "bold", - foreground: "var(--syntax-unknown)", - }, - }, - { - scope: "meta.output", - settings: { - foreground: "var(--syntax-unknown)", - }, - }, - { - scope: "meta.export.default", - settings: { - foreground: "var(--syntax-unknown)", - }, - }, - { - scope: [ - "brackethighlighter.tag", - "brackethighlighter.curly", - "brackethighlighter.round", - "brackethighlighter.square", - "brackethighlighter.angle", - "brackethighlighter.quote", - ], - settings: { - foreground: "var(--syntax-unknown)", - }, - }, - { - scope: ["constant.other.reference.link", "string.other.link"], - settings: { - fontStyle: "underline", - foreground: "var(--syntax-unknown)", - }, - }, - { - scope: "token.info-token", - settings: { - foreground: "var(--syntax-info)", - }, - }, - { - scope: "token.warn-token", - settings: { - foreground: "var(--syntax-warning)", - }, - }, - { - scope: "token.debug-token", - settings: { - foreground: "var(--syntax-info)", - }, - }, - ], - semanticTokenColors: { - comment: "var(--syntax-comment)", - string: "var(--syntax-string)", - number: "var(--syntax-constant)", - regexp: "var(--syntax-regexp)", - keyword: "var(--syntax-keyword)", - variable: "var(--syntax-variable)", - parameter: "var(--syntax-variable)", - property: "var(--syntax-property)", - function: "var(--syntax-primitive)", - method: "var(--syntax-primitive)", - type: "var(--syntax-type)", - class: "var(--syntax-type)", - namespace: "var(--syntax-type)", - enumMember: "var(--syntax-primitive)", - "variable.constant": "var(--syntax-constant)", - "variable.defaultLibrary": "var(--syntax-unknown)", - }, - } as unknown as ThemeRegistrationResolved) -}) diff --git a/packages/ui/src/components/index.ts b/packages/ui/src/components/index.ts deleted file mode 100644 index f63619ea9..000000000 --- a/packages/ui/src/components/index.ts +++ /dev/null @@ -1,33 +0,0 @@ -export * from "./accordion" -export * from "./button" -export * from "./card" -export * from "./checkbox" -export * from "./code" -export * from "./collapsible" -export * from "./dialog" -export * from "./diff" -export * from "./diff-changes" -export * from "./icon" -export * from "./icon-button" -export * from "./input" -export * from "./favicon" -export * from "./fonts" -export * from "./list" -export * from "./logo" -export * from "./markdown" -export * from "./message-part" -export * from "./message-progress" -export * from "./progress-circle" -export * from "./select" -export * from "./select-dialog" -export * from "./spinner" -export * from "./sticky-accordion-header" -export * from "./tabs" -export * from "./basic-tool" -export * from "./file-icon" -export * from "./tooltip" -export * from "./typewriter" -export * from "./session-review" - -export * from "../context/helper" -export * from "../context/marked" diff --git a/packages/ui/src/components/list.css b/packages/ui/src/components/list.css deleted file mode 100644 index 2136c4f92..000000000 --- a/packages/ui/src/components/list.css +++ /dev/null @@ -1,30 +0,0 @@ -[data-component="list"] { - /* overflow-y: auto; */ - - /* Hide scrollbar */ - &::-webkit-scrollbar { - display: none; - } - -ms-overflow-style: none; - scrollbar-width: none; - - [data-slot="item"] { - width: 100%; - margin-bottom: 6px; - padding: 4px 12px; - text-align: left; - - border-radius: var(--radius-md); - transition: background-color 0.2s ease-in-out; - - &[data-active="true"] { - background-color: var(--surface-raised-base-hover); - } - &:hover { - background-color: var(--surface-raised-base-hover); - } - &:focus { - outline: none; - } - } -} diff --git a/packages/ui/src/components/list.tsx b/packages/ui/src/components/list.tsx deleted file mode 100644 index aaba61fdf..000000000 --- a/packages/ui/src/components/list.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import { ComponentProps, createEffect, createSignal, type JSX } from "solid-js" -import { VirtualizerHandle, VList } from "virtua/solid" -import { createList } from "solid-list" -import { createStore } from "solid-js/store" - -export interface ListProps { - data: T[] - children: (x: T) => JSX.Element - key: (x: T) => string - current?: T - onSelect?: (value: T | undefined) => void - onHover?: (value: T | undefined) => void - class?: ComponentProps<"div">["class"] -} - -export function List(props: ListProps) { - const [virtualizer, setVirtualizer] = createSignal(undefined) - const [store, setStore] = createStore({ - mouseActive: false, - }) - const list = createList({ - items: () => props.data.map(props.key), - initialActive: props.current ? props.key(props.current) : undefined, - loop: true, - }) - - createEffect(() => { - if (props.current) list.setActive(props.key(props.current)) - }) - // const resetSelection = () => { - // if (props.data.length === 0) return - // list.setActive(props.key(props.data[0])) - // } - const handleSelect = (item: T) => { - props.onSelect?.(item) - list.setActive(props.key(item)) - } - - const handleKey = (e: KeyboardEvent) => { - setStore("mouseActive", false) - - if (e.key === "Enter") { - e.preventDefault() - const selected = props.data.find((x) => props.key(x) === list.active()) - if (selected) handleSelect(selected) - } else { - list.onKeyDown(e) - } - } - - createEffect(() => { - if (store.mouseActive || props.data.length === 0) return - const index = props.data.findIndex((x) => props.key(x) === list.active()) - props.onHover?.(props.data[index]) - if (index === 0) { - virtualizer()?.scrollTo(0) - return - } - // virtualizer()?.scrollTo(list.active()) - // const element = virtualizer()?.querySelector(`[data-key="${list.active()}"]`) - // element?.scrollIntoView({ block: "nearest", behavior: "smooth" }) - }) - - return ( - - {(item) => ( - - )} - - ) -} diff --git a/packages/ui/src/components/select-dialog.tsx b/packages/ui/src/components/select-dialog.tsx index 63fad13ec..489432fbb 100644 --- a/packages/ui/src/components/select-dialog.tsx +++ b/packages/ui/src/components/select-dialog.tsx @@ -1,7 +1,10 @@ import { createEffect, Show, For, type JSX, splitProps } from "solid-js" -import { Dialog, DialogProps, Icon, IconButton, Input } from "@opencode-ai/ui" import { createStore } from "solid-js/store" import { FilteredListProps, useFilteredList } from "@opencode-ai/ui/hooks" +import { Dialog, DialogProps } from "./dialog" +import { Icon } from "./icon" +import { Input } from "./input" +import { IconButton } from "./icon-button" interface SelectDialogProps extends FilteredListProps, diff --git a/packages/ui/src/components/select.tsx b/packages/ui/src/components/select.tsx index dea6743ee..d2ac93c03 100644 --- a/packages/ui/src/components/select.tsx +++ b/packages/ui/src/components/select.tsx @@ -1,7 +1,8 @@ import { Select as Kobalte } from "@kobalte/core/select" import { createMemo, type ComponentProps } from "solid-js" -import { Icon, Button, type ButtonProps } from "@opencode-ai/ui" import { pipe, groupBy, entries, map } from "remeda" +import { Button, ButtonProps } from "./button" +import { Icon } from "./icon" export interface SelectProps { placeholder?: string diff --git a/packages/ui/src/components/session-timeline.css b/packages/ui/src/components/session-timeline.css new file mode 100644 index 000000000..7bb0c1601 --- /dev/null +++ b/packages/ui/src/components/session-timeline.css @@ -0,0 +1,325 @@ +[data-component="session-timeline"] { + flex: 1; + min-height: 0; + padding-bottom: 80px; + display: flex; + align-items: flex-start; + justify-content: flex-start; + + [data-slot="timeline-list"] { + margin-right: 32px; + flex-shrink: 0; + display: flex; + flex-direction: column; + align-items: flex-start; + margin-top: 12px; + + &[data-expanded="true"] { + position: absolute; + right: 100%; + width: 240px; + margin-top: 12px; + + @media (min-width: 80rem) { + gap: 8px; + margin-top: 4px; + } + } + } + + [data-slot="timeline-item"] { + display: flex; + align-items: center; + align-self: stretch; + justify-content: flex-end; + + &[data-expanded="true"] { + @media (min-width: 80rem) { + justify-content: flex-start; + } + } + } + + [data-slot="tick-button"] { + display: flex; + align-items: center; + justify-content: flex-start; + height: 8px; + width: 32px; + margin-right: -12px; + cursor: pointer; + border: none; + background: none; + padding: 0; + + &[data-active="true"] [data-slot="tick-line"] { + background-color: var(--icon-strong-base); + width: 100%; + } + + &[data-expanded="true"] { + @media (min-width: 80rem) { + display: none; + } + } + } + + [data-slot="tick-line"] { + height: 1px; + width: 20px; + background-color: var(--icon-base); + transition: + width 0.2s, + background-color 0.2s; + } + + [data-slot="tick-button"]:hover [data-slot="tick-line"] { + width: 100%; + background-color: var(--icon-strong-base); + } + + [data-slot="message-button"] { + display: none; + align-items: center; + align-self: stretch; + width: 100%; + column-gap: 8px; + cursor: default; + border: none; + background: none; + padding: 0; + + &[data-expanded="true"] { + @media (min-width: 80rem) { + display: flex; + } + } + } + + .spinner { + color: var(--text-base); + flex-shrink: 0; + width: 18px; + aspect-ratio: 1; + } + + [data-slot="message-title-preview"] { + font-size: 14px; /* text-14-regular */ + color: var(--text-weak); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + min-width: 0; + text-align: left; + + &[data-active="true"] { + color: var(--text-strong); + } + } + + [data-slot="timeline-item"]:hover [data-slot="message-title-preview"] { + color: var(--text-base); + } + + [data-slot="content"] { + flex-grow: 1; + width: 100%; + height: 100%; + min-width: 0; + overflow-y: auto; + scrollbar-width: none; + } + + [data-slot="content"]::-webkit-scrollbar { + display: none; + } + + [data-slot="message-container"] { + display: flex; + flex-direction: column; + align-items: flex-start; + align-self: stretch; + gap: 32px; + padding-bottom: 80px; + } + + [data-slot="message-header"] { + display: flex; + align-items: center; + gap: 8px; + align-self: stretch; + position: sticky; + top: 0; + background-color: var(--background-stronger); + z-index: 20; + height: 32px; + } + + [data-slot="message-title"] { + width: 100%; + font-size: 14px; /* text-14-medium */ + font-weight: 500; + color: var(--text-strong); + overflow: hidden; + text-overflow: ellipsis; + min-width: 0; + white-space: nowrap; + } + + [data-slot="message-title"] h1 { + overflow: hidden; + text-overflow: ellipsis; + min-width: 0; + white-space: nowrap; + font-size: inherit; + font-weight: inherit; + } + + [data-slot="summary-section"] { + width: 100%; + display: flex; + flex-direction: column; + gap: 24px; + align-items: flex-start; + align-self: stretch; + } + + [data-slot="summary-header"] { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 4px; + align-self: stretch; + } + + [data-slot="summary-title"] { + font-size: 12px; /* text-12-medium */ + font-weight: 500; + color: var(--text-weak); + } + + [data-slot="markdown"] { + &[data-diffs="true"] { + font-size: 14px; /* text-14-regular */ + } + + &[data-fade="true"] > * { + animation: fade-up-text 0.3s ease-out forwards; + } + } + + [data-slot="accordion"] { + width: 100%; + } + + [data-slot="sticky-header"] { + top: 40px; /* top-10 */ + + &::before { + top: -40px; /* -top-10 */ + } + } + + [data-slot="accordion-trigger-content"] { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + gap: 20px; + } + + [data-slot="file-info"] { + flex-grow: 1; + display: flex; + align-items: center; + gap: 20px; + min-width: 0; + } + + [data-slot="file-icon"] { + flex-shrink: 0; + width: 16px; + height: 16px; + } + + [data-slot="file-path"] { + display: flex; + flex-grow: 1; + min-width: 0; + } + + [data-slot="directory"] { + color: var(--text-base); + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + direction: rtl; + text-align: left; + } + + [data-slot="filename"] { + color: var(--text-strong); + flex-shrink: 0; + } + + [data-slot="accordion-actions"] { + flex-shrink: 0; + display: flex; + gap: 16px; + align-items: center; + justify-content: flex-end; + } + + [data-slot="accordion-content"] { + max-height: 240px; /* max-h-60 */ + overflow-y: auto; + scrollbar-width: none; + } + + [data-slot="accordion-content"]::-webkit-scrollbar { + display: none; + } + + [data-slot="response-section"] { + width: 100%; + } + + [data-slot="collapsible-trigger"] { + color: var(--text-weak); + cursor: pointer; + background: none; + border: none; + padding: 0; + display: flex; + align-items: center; + + &:hover { + color: var(--text-strong); + } + } + + [data-slot="collapsible-trigger-content"] { + display: flex; + align-items: center; + gap: 4px; + align-self: stretch; + } + + [data-slot="details-text"] { + font-size: 12px; /* text-12-medium */ + font-weight: 500; + } + + .error-card { + color: var(--text-on-critical-base); + } + + [data-slot="collapsible-content-inner"] { + width: 100%; + display: flex; + flex-direction: column; + align-items: flex-start; + align-self: stretch; + gap: 12px; + } +} diff --git a/packages/ui/src/components/session-timeline.tsx b/packages/ui/src/components/session-timeline.tsx new file mode 100644 index 000000000..4ff43427f --- /dev/null +++ b/packages/ui/src/components/session-timeline.tsx @@ -0,0 +1,265 @@ +import { createSeen } from "../hooks/create-seen" +import { AssistantMessage } from "@opencode-ai/sdk" +import { useData } from "../context" +import { Binary } from "@opencode-ai/util/binary" +import { getDirectory, getFilename } from "@opencode-ai/util/path" +import { createEffect, createMemo, createSignal, For, Match, Show, Switch } from "solid-js" +import { createStore } from "solid-js/store" +import { DiffChanges } from "./diff-changes" +import { Spinner } from "./spinner" +import { Typewriter } from "./typewriter" +import { Message } from "./message-part" +import { Markdown } from "./markdown" +import { Accordion } from "./accordion" +import { StickyAccordionHeader } from "./sticky-accordion-header" +import { FileIcon } from "./file-icon" +import { Icon } from "./icon" +import { Diff } from "./diff" +import { Card } from "./card" +import { MessageProgress } from "./message-progress" +import { Collapsible } from "./collapsible" + +export function SessionTimeline(props: { sessionID: string; expanded?: boolean }) { + const data = useData() + const [store, setStore] = createStore({ + messageId: undefined as string | undefined, + }) + const match = Binary.search(data.session, props.sessionID, (s) => s.id) + if (!match.found) throw new Error(`Session ${props.sessionID} not found`) + + // const info = createMemo(() => data.session[match.index]) + const messages = createMemo(() => (props.sessionID ? (data.message[props.sessionID] ?? []) : [])) + const userMessages = createMemo(() => + messages() + .filter((m) => m.role === "user") + .sort((a, b) => b.id.localeCompare(a.id)), + ) + const lastUserMessage = createMemo(() => { + return userMessages()?.at(0) + }) + const activeMessage = createMemo(() => { + if (!store.messageId) return lastUserMessage() + return userMessages()?.find((m) => m.id === store.messageId) + }) + const status = createMemo( + () => + data.session_status[props.sessionID] ?? { + type: "idle", + }, + ) + const working = createMemo(() => status()?.type !== "idle") + + return ( +
+ 1}> +
    + + {(message) => { + const messageWorking = createMemo(() => message.id === lastUserMessage()?.id && working()) + const handleClick = () => setStore("messageId", message.id) + + return ( +
  • + + +
  • + ) + }} +
    +
+
+
+ + {(message) => { + const isActive = createMemo(() => activeMessage()?.id === message.id) + const titleSeen = createMemo(() => true) + const contentSeen = createMemo(() => true) + { + /* const titleSeen = createSeen(`message-title-${message.id}`) */ + } + { + /* const contentSeen = createSeen(`message-content-${message.id}`) */ + } + const [titled, setTitled] = createSignal(titleSeen()) + const assistantMessages = createMemo(() => { + return messages()?.filter((m) => m.role === "assistant" && m.parentID == message.id) as AssistantMessage[] + }) + const error = createMemo(() => assistantMessages().find((m) => m?.error)?.error) + const [detailsExpanded, setDetailsExpanded] = createSignal(false) + const parts = createMemo(() => data.part[message.id]) + const hasToolPart = createMemo(() => + assistantMessages() + ?.flatMap((m) => data.part[m.id]) + .some((p) => p?.type === "tool"), + ) + const messageWorking = createMemo(() => message.id === lastUserMessage()?.id && working()) + const initialCompleted = !(message.id === lastUserMessage()?.id && working()) + const [completed, setCompleted] = createSignal(initialCompleted) + + // allowing time for the animations to finish + createEffect(() => { + if (titleSeen()) return + const title = message.summary?.title + if (title) setTimeout(() => setTitled(true), 10_000) + }) + createEffect(() => { + const completed = !messageWorking() + setTimeout(() => setCompleted(completed), 1200) + }) + + return ( + +
+ {/* Title */} +
+
+ + } + > +

{message.summary?.title}

+
+
+
+ + {/* Summary */} + +
+
+

+ + Summary + Response + +

+ + {(summary) => ( + + )} + +
+ + + {(diff) => ( + + + +
+
+ +
+ + {getDirectory(diff.file)}‎ + + {getFilename(diff.file)} +
+
+
+ + +
+
+
+
+ + + +
+ )} +
+
+
+
+ + + {error()?.data?.message as string} + + + {/* Response */} +
+ + + + + + + +
+
+ + Hide details + Show details + +
+ +
+
+ +
+ + {(assistantMessage) => { + const parts = createMemo(() => data.part[assistantMessage.id]) + return + }} + + + + {error()?.data?.message as string} + + +
+
+
+
+
+
+
+
+ ) + }} +
+
+
+ ) +} diff --git a/packages/ui/src/components/tooltip.tsx b/packages/ui/src/components/tooltip.tsx index 663dc12e6..0b8a150b3 100644 --- a/packages/ui/src/components/tooltip.tsx +++ b/packages/ui/src/components/tooltip.tsx @@ -1,5 +1,5 @@ import { Tooltip as KobalteTooltip } from "@kobalte/core/tooltip" -import { children, createEffect, createSignal, Match, splitProps, Switch, type JSX } from "solid-js" +import { children, createSignal, Match, onMount, splitProps, Switch, type JSX } from "solid-js" import type { ComponentProps } from "solid-js" export interface TooltipProps extends ComponentProps { @@ -14,7 +14,7 @@ export function Tooltip(props: TooltipProps) { const c = children(() => local.children) - createEffect(() => { + onMount(() => { const childElements = c() if (childElements instanceof HTMLElement) { childElements.addEventListener("focus", () => setOpen(true)) diff --git a/packages/ui/src/context/marked.tsx b/packages/ui/src/context/marked.tsx index 804d449c5..0d9c44758 100644 --- a/packages/ui/src/context/marked.tsx +++ b/packages/ui/src/context/marked.tsx @@ -2,9 +2,377 @@ import { marked } from "marked" import markedShiki from "marked-shiki" import { bundledLanguages, type BundledLanguage } from "shiki" import { createSimpleContext } from "./helper" -import { getSharedHighlighter } from "@pierre/precision-diffs" +import { getSharedHighlighter, registerCustomTheme, ThemeRegistrationResolved } from "@pierre/precision-diffs" -const highlighter = await getSharedHighlighter({ themes: ["OpenCode"], langs: [] }) +registerCustomTheme("OpenCode", () => { + return Promise.resolve({ + name: "OpenCode", + colors: { + "editor.background": "transparent", + "editor.foreground": "var(--text-base)", + "gitDecoration.addedResourceForeground": "var(--syntax-diff-add)", + "gitDecoration.deletedResourceForeground": "var(--syntax-diff-delete)", + // "gitDecoration.conflictingResourceForeground": "#ffca00", + // "gitDecoration.modifiedResourceForeground": "#1a76d4", + // "gitDecoration.untrackedResourceForeground": "#00cab1", + // "gitDecoration.ignoredResourceForeground": "#84848A", + // "terminal.titleForeground": "#adadb1", + // "terminal.titleInactiveForeground": "#84848A", + // "terminal.background": "#141415", + // "terminal.foreground": "#adadb1", + // "terminal.ansiBlack": "#141415", + // "terminal.ansiRed": "#ff2e3f", + // "terminal.ansiGreen": "#0dbe4e", + // "terminal.ansiYellow": "#ffca00", + // "terminal.ansiBlue": "#008cff", + // "terminal.ansiMagenta": "#c635e4", + // "terminal.ansiCyan": "#08c0ef", + // "terminal.ansiWhite": "#c6c6c8", + // "terminal.ansiBrightBlack": "#141415", + // "terminal.ansiBrightRed": "#ff2e3f", + // "terminal.ansiBrightGreen": "#0dbe4e", + // "terminal.ansiBrightYellow": "#ffca00", + // "terminal.ansiBrightBlue": "#008cff", + // "terminal.ansiBrightMagenta": "#c635e4", + // "terminal.ansiBrightCyan": "#08c0ef", + // "terminal.ansiBrightWhite": "#c6c6c8", + }, + tokenColors: [ + { + scope: ["comment", "punctuation.definition.comment", "string.comment"], + settings: { + foreground: "var(--syntax-comment)", + }, + }, + { + scope: ["entity.other.attribute-name"], + settings: { + foreground: "var(--syntax-property)", // maybe attribute + }, + }, + { + scope: ["constant", "entity.name.constant", "variable.other.constant", "variable.language", "entity"], + settings: { + foreground: "var(--syntax-constant)", + }, + }, + { + scope: ["entity.name", "meta.export.default", "meta.definition.variable"], + settings: { + foreground: "var(--syntax-type)", + }, + }, + { + scope: ["meta.object.member"], + settings: { + foreground: "var(--syntax-primitive)", + }, + }, + { + scope: [ + "variable.parameter.function", + "meta.jsx.children", + "meta.block", + "meta.tag.attributes", + "entity.name.constant", + "meta.embedded.expression", + "meta.template.expression", + "string.other.begin.yaml", + "string.other.end.yaml", + ], + settings: { + foreground: "var(--syntax-punctuation)", + }, + }, + { + scope: ["entity.name.function", "support.type.primitive"], + settings: { + foreground: "var(--syntax-primitive)", + }, + }, + { + scope: ["support.class.component"], + settings: { + foreground: "var(--syntax-type)", + }, + }, + { + scope: "keyword", + settings: { + foreground: "var(--syntax-keyword)", + }, + }, + { + scope: [ + "keyword.operator", + "storage.type.function.arrow", + "punctuation.separator.key-value.css", + "entity.name.tag.yaml", + "punctuation.separator.key-value.mapping.yaml", + ], + settings: { + foreground: "var(--syntax-operator)", + }, + }, + { + scope: ["storage", "storage.type"], + settings: { + foreground: "var(--syntax-keyword)", + }, + }, + { + scope: ["storage.modifier.package", "storage.modifier.import", "storage.type.java"], + settings: { + foreground: "var(--syntax-primitive)", + }, + }, + { + scope: [ + "string", + "punctuation.definition.string", + "string punctuation.section.embedded source", + "entity.name.tag", + ], + settings: { + foreground: "var(--syntax-string)", + }, + }, + { + scope: "support", + settings: { + foreground: "var(--syntax-primitive)", + }, + }, + { + scope: ["support.type.object.module", "variable.other.object", "support.type.property-name.css"], + settings: { + foreground: "var(--syntax-object)", + }, + }, + { + scope: "meta.property-name", + settings: { + foreground: "var(--syntax-property)", + }, + }, + { + scope: "variable", + settings: { + foreground: "var(--syntax-variable)", + }, + }, + { + scope: "variable.other", + settings: { + foreground: "var(--syntax-variable)", + }, + }, + { + scope: [ + "invalid.broken", + "invalid.illegal", + "invalid.unimplemented", + "invalid.deprecated", + "message.error", + "markup.deleted", + "meta.diff.header.from-file", + "punctuation.definition.deleted", + "brackethighlighter.unmatched", + "token.error-token", + ], + settings: { + foreground: "var(--syntax-critical)", + }, + }, + { + scope: "carriage-return", + settings: { + foreground: "var(--syntax-keyword)", + }, + }, + { + scope: "string source", + settings: { + foreground: "var(--syntax-variable)", + }, + }, + { + scope: "string variable", + settings: { + foreground: "var(--syntax-constant)", + }, + }, + { + scope: [ + "source.regexp", + "string.regexp", + "string.regexp.character-class", + "string.regexp constant.character.escape", + "string.regexp source.ruby.embedded", + "string.regexp string.regexp.arbitrary-repitition", + "string.regexp constant.character.escape", + ], + settings: { + foreground: "var(--syntax-regexp)", + }, + }, + { + scope: "support.constant", + settings: { + foreground: "var(--syntax-primitive)", + }, + }, + { + scope: "support.variable", + settings: { + foreground: "var(--syntax-variable)", + }, + }, + { + scope: "meta.module-reference", + settings: { + foreground: "var(--syntax-info)", + }, + }, + { + scope: "punctuation.definition.list.begin.markdown", + settings: { + foreground: "var(--syntax-punctuation)", + }, + }, + { + scope: ["markup.heading", "markup.heading entity.name"], + settings: { + fontStyle: "bold", + foreground: "var(--syntax-info)", + }, + }, + { + scope: "markup.quote", + settings: { + foreground: "var(--syntax-info)", + }, + }, + { + scope: "markup.italic", + settings: { + fontStyle: "italic", + // foreground: "", + }, + }, + { + scope: "markup.bold", + settings: { + fontStyle: "bold", + foreground: "var(--text-strong)", + }, + }, + { + scope: [ + "markup.raw", + "markup.inserted", + "meta.diff.header.to-file", + "punctuation.definition.inserted", + "markup.changed", + "punctuation.definition.changed", + "markup.ignored", + "markup.untracked", + ], + settings: { + foreground: "var(--text-base)", + }, + }, + { + scope: "meta.diff.range", + settings: { + fontStyle: "bold", + foreground: "var(--syntax-unknown)", + }, + }, + { + scope: "meta.diff.header", + settings: { + foreground: "var(--syntax-unknown)", + }, + }, + { + scope: "meta.separator", + settings: { + fontStyle: "bold", + foreground: "var(--syntax-unknown)", + }, + }, + { + scope: "meta.output", + settings: { + foreground: "var(--syntax-unknown)", + }, + }, + { + scope: "meta.export.default", + settings: { + foreground: "var(--syntax-unknown)", + }, + }, + { + scope: [ + "brackethighlighter.tag", + "brackethighlighter.curly", + "brackethighlighter.round", + "brackethighlighter.square", + "brackethighlighter.angle", + "brackethighlighter.quote", + ], + settings: { + foreground: "var(--syntax-unknown)", + }, + }, + { + scope: ["constant.other.reference.link", "string.other.link"], + settings: { + fontStyle: "underline", + foreground: "var(--syntax-unknown)", + }, + }, + { + scope: "token.info-token", + settings: { + foreground: "var(--syntax-info)", + }, + }, + { + scope: "token.warn-token", + settings: { + foreground: "var(--syntax-warning)", + }, + }, + { + scope: "token.debug-token", + settings: { + foreground: "var(--syntax-info)", + }, + }, + ], + semanticTokenColors: { + comment: "var(--syntax-comment)", + string: "var(--syntax-string)", + number: "var(--syntax-constant)", + regexp: "var(--syntax-regexp)", + keyword: "var(--syntax-keyword)", + variable: "var(--syntax-variable)", + parameter: "var(--syntax-variable)", + property: "var(--syntax-property)", + function: "var(--syntax-primitive)", + method: "var(--syntax-primitive)", + type: "var(--syntax-type)", + class: "var(--syntax-type)", + namespace: "var(--syntax-type)", + enumMember: "var(--syntax-primitive)", + "variable.constant": "var(--syntax-constant)", + "variable.defaultLibrary": "var(--syntax-unknown)", + }, + } as unknown as ThemeRegistrationResolved) +}) export const { use: useMarked, provider: MarkedProvider } = createSimpleContext({ name: "Marked", @@ -12,6 +380,7 @@ export const { use: useMarked, provider: MarkedProvider } = createSimpleContext( return marked.use( markedShiki({ async highlight(code, lang) { + const highlighter = await getSharedHighlighter({ themes: ["OpenCode"], langs: [] }) if (!(lang in bundledLanguages)) { lang = "text" } diff --git a/packages/ui/src/demo.tsx b/packages/ui/src/demo.tsx index 96579c999..1f2eca7d4 100644 --- a/packages/ui/src/demo.tsx +++ b/packages/ui/src/demo.tsx @@ -8,7 +8,6 @@ import { Tabs, Tooltip, Fonts, - List, Dialog, Icon, IconButton, @@ -131,11 +130,6 @@ const Demo: Component = () => {

List

-
- x}> - {(x) =>
{x}
} -
-

Input