diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index deca74d0b..2958b1a46 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,4 +27,4 @@ jobs: run: bun test - name: Build - run: bun run build + run: bun run build:vite diff --git a/bun.lock b/bun.lock index f6621ad24..38d490689 100644 --- a/bun.lock +++ b/bun.lock @@ -118,6 +118,7 @@ "react": "^19.2.4", "react-compiler-runtime": "^1.0.0", "react-reconciler": "^0.33.0", + "rollup": "^4.60.1", "semver": "^7.7.4", "sharp": "^0.34.5", "shell-quote": "^1.8.3", @@ -132,6 +133,7 @@ "undici": "^7.24.6", "url-handler-napi": "workspace:*", "usehooks-ts": "^3.1.1", + "vite": "^8.0.8", "vscode-jsonrpc": "^8.2.1", "vscode-languageserver-protocol": "^3.17.5", "vscode-languageserver-types": "^3.17.5", @@ -842,6 +844,36 @@ "@protobufjs/utf8": ["@protobufjs/utf8@1.1.0", "https://registry.npmmirror.com/@protobufjs/utf8/-/utf8-1.1.0.tgz", {}, "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="], + "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.15.tgz", { "os": "android", "cpu": "arm64" }, "sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA=="], + + "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.15.tgz", { "os": "darwin", "cpu": "arm64" }, "sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg=="], + + "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.15.tgz", { "os": "darwin", "cpu": "x64" }, "sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw=="], + + "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.15.tgz", { "os": "freebsd", "cpu": "x64" }, "sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw=="], + + "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.15.tgz", { "os": "linux", "cpu": "arm" }, "sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA=="], + + "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.15.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w=="], + + "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.15.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ=="], + + "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.15.tgz", { "os": "linux", "cpu": "ppc64" }, "sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ=="], + + "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.15.tgz", { "os": "linux", "cpu": "s390x" }, "sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ=="], + + "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.15.tgz", { "os": "linux", "cpu": "x64" }, "sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA=="], + + "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.15.tgz", { "os": "linux", "cpu": "x64" }, "sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw=="], + + "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.15.tgz", { "os": "none", "cpu": "arm64" }, "sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg=="], + + "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.15.tgz", { "dependencies": { "@emnapi/core": "1.9.2", "@emnapi/runtime": "1.9.2", "@napi-rs/wasm-runtime": "^1.1.3" }, "cpu": "none" }, "sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q=="], + + "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.15.tgz", { "os": "win32", "cpu": "arm64" }, "sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA=="], + + "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.15.tgz", { "os": "win32", "cpu": "x64" }, "sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g=="], + "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.27", "https://registry.npmmirror.com/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", {}, "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA=="], "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.60.1", "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz", { "os": "android", "cpu": "arm" }, "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA=="], @@ -1754,6 +1786,8 @@ "rfdc": ["rfdc@1.4.1", "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], + "rolldown": ["rolldown@1.0.0-rc.15", "https://registry.npmmirror.com/rolldown/-/rolldown-1.0.0-rc.15.tgz", { "dependencies": { "@oxc-project/types": "=0.124.0", "@rolldown/pluginutils": "1.0.0-rc.15" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.15", "@rolldown/binding-darwin-arm64": "1.0.0-rc.15", "@rolldown/binding-darwin-x64": "1.0.0-rc.15", "@rolldown/binding-freebsd-x64": "1.0.0-rc.15", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.15", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.15", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.15", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.15", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.15", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.15", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.15" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g=="], + "rollup": ["rollup@4.60.1", "https://registry.npmmirror.com/rollup/-/rollup-4.60.1.tgz", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.60.1", "@rollup/rollup-android-arm64": "4.60.1", "@rollup/rollup-darwin-arm64": "4.60.1", "@rollup/rollup-darwin-x64": "4.60.1", "@rollup/rollup-freebsd-arm64": "4.60.1", "@rollup/rollup-freebsd-x64": "4.60.1", "@rollup/rollup-linux-arm-gnueabihf": "4.60.1", "@rollup/rollup-linux-arm-musleabihf": "4.60.1", "@rollup/rollup-linux-arm64-gnu": "4.60.1", "@rollup/rollup-linux-arm64-musl": "4.60.1", "@rollup/rollup-linux-loong64-gnu": "4.60.1", "@rollup/rollup-linux-loong64-musl": "4.60.1", "@rollup/rollup-linux-ppc64-gnu": "4.60.1", "@rollup/rollup-linux-ppc64-musl": "4.60.1", "@rollup/rollup-linux-riscv64-gnu": "4.60.1", "@rollup/rollup-linux-riscv64-musl": "4.60.1", "@rollup/rollup-linux-s390x-gnu": "4.60.1", "@rollup/rollup-linux-x64-gnu": "4.60.1", "@rollup/rollup-linux-x64-musl": "4.60.1", "@rollup/rollup-openbsd-x64": "4.60.1", "@rollup/rollup-openharmony-arm64": "4.60.1", "@rollup/rollup-win32-arm64-msvc": "4.60.1", "@rollup/rollup-win32-ia32-msvc": "4.60.1", "@rollup/rollup-win32-x64-gnu": "4.60.1", "@rollup/rollup-win32-x64-msvc": "4.60.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w=="], "router": ["router@2.2.0", "https://registry.npmmirror.com/router/-/router-2.2.0.tgz", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="], @@ -1894,7 +1928,7 @@ "vary": ["vary@1.1.2", "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], - "vite": ["vite@6.4.2", "https://registry.npmmirror.com/vite/-/vite-6.4.2.tgz", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ=="], + "vite": ["vite@8.0.8", "https://registry.npmmirror.com/vite/-/vite-8.0.8.tgz", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.8", "rolldown": "1.0.0-rc.15", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw=="], "vscode-jsonrpc": ["vscode-jsonrpc@8.2.1", "https://registry.npmmirror.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.1.tgz", {}, "sha512-kdjOSJ2lLIn7r1rtrMbbNCHjyMPfRnowdKjBQ+mGq6NAW5QY2bEZC/khaC5OR8svbbjvLEaIXkOq45e2X9BIbQ=="], @@ -1962,6 +1996,8 @@ "@anthropic/remote-control-server/typescript": ["typescript@5.9.3", "https://registry.npmmirror.com/typescript/-/typescript-5.9.3.tgz", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + "@anthropic/remote-control-server/vite": ["vite@6.4.2", "https://registry.npmmirror.com/vite/-/vite-6.4.2.tgz", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ=="], + "@aws-crypto/crc32/@aws-crypto/util": ["@aws-crypto/util@5.2.0", "https://registry.npmmirror.com/@aws-crypto/util/-/util-5.2.0.tgz", { "dependencies": { "@aws-sdk/types": "^3.222.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ=="], "@aws-crypto/sha256-browser/@aws-crypto/sha256-js": ["@aws-crypto/sha256-js@5.2.0", "https://registry.npmmirror.com/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA=="], @@ -2314,6 +2350,10 @@ "qrcode/yargs": ["yargs@15.4.1", "https://registry.npmmirror.com/yargs/-/yargs-15.4.1.tgz", { "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^18.1.2" } }, "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A=="], + "rolldown/@oxc-project/types": ["@oxc-project/types@0.124.0", "https://registry.npmmirror.com/@oxc-project/types/-/types-0.124.0.tgz", {}, "sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg=="], + + "rolldown/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.15", "https://registry.npmmirror.com/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.15.tgz", {}, "sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g=="], + "vscode-languageserver-protocol/vscode-jsonrpc": ["vscode-jsonrpc@8.2.0", "https://registry.npmmirror.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", {}, "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="], "xss/commander": ["commander@2.20.3", "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], diff --git a/package.json b/package.json index 8e147791c..fb5d641cd 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,9 @@ ], "scripts": { "build": "bun run build.ts", + "build:vite": "vite build && bun run scripts/post-build.ts", + "build:vite:only": "vite build", + "build:bun": "bun run build.ts", "dev": "bun run scripts/dev.ts", "dev:inspect": "bun run scripts/dev-debug.ts", "prepublishOnly": "bun run build", @@ -169,6 +172,7 @@ "react": "^19.2.4", "react-compiler-runtime": "^1.0.0", "react-reconciler": "^0.33.0", + "rollup": "^4.60.1", "semver": "^7.7.4", "sharp": "^0.34.5", "shell-quote": "^1.8.3", @@ -183,6 +187,7 @@ "undici": "^7.24.6", "url-handler-napi": "workspace:*", "usehooks-ts": "^3.1.1", + "vite": "^8.0.8", "vscode-jsonrpc": "^8.2.1", "vscode-languageserver-protocol": "^3.17.5", "vscode-languageserver-types": "^3.17.5", diff --git a/scripts/post-build.ts b/scripts/post-build.ts new file mode 100644 index 000000000..9f3c4793a --- /dev/null +++ b/scripts/post-build.ts @@ -0,0 +1,90 @@ +#!/usr/bin/env bun +/** + * Post-build processing for Vite build output. + * + * 1. Patch globalThis.Bun destructuring in third-party deps for Node.js compat + * 2. Copy native addon files + * 3. Bundle standalone scripts (download-ripgrep) + * 4. Generate dual entry points (cli-bun.js, cli-node.js) + */ +import { readdir, readFile, writeFile, cp } from "node:fs/promises"; +import { chmodSync } from "node:fs"; +import { join } from "node:path"; +import { execSync } from "node:child_process"; + +const outdir = "dist"; + +async function postBuild() { + // Step 1: Patch globalThis.Bun destructuring from third-party deps + const files = await readdir(outdir, { recursive: true }); + const BUN_DESTRUCTURE = /var \{([^}]+)\} = globalThis\.Bun;?/g; + const BUN_DESTRUCTURE_SAFE = + 'var {$1} = typeof globalThis.Bun !== "undefined" ? globalThis.Bun : {};'; + + let bunPatched = 0; + for (const file of files) { + const filePath = join(outdir, file); + if (typeof file !== "string" || !file.endsWith(".js")) continue; + const content = await readFile(filePath, "utf-8"); + if (BUN_DESTRUCTURE.test(content)) { + await writeFile( + filePath, + content.replace(BUN_DESTRUCTURE, BUN_DESTRUCTURE_SAFE), + ); + bunPatched++; + } + BUN_DESTRUCTURE.lastIndex = 0; + } + + // Step 2: Copy native addon files + const vendorDir = join(outdir, "vendor", "audio-capture"); + await cp("vendor/audio-capture", vendorDir, { recursive: true } as never); + console.log(`Copied vendor/audio-capture/ → ${vendorDir}/`); + + // Step 3: Bundle standalone scripts via Bun.build (kept for simplicity) + try { + const { default: Bun } = await import("bun"); + const rgScript = await Bun.build({ + entrypoints: ["scripts/download-ripgrep.ts"], + outdir, + target: "node", + }); + if (rgScript.success) { + console.log(`Bundled download-ripgrep script to ${outdir}/`); + } else { + console.warn("Failed to bundle download-ripgrep script (non-fatal)"); + } + } catch { + // Bun not available — try esbuild fallback + try { + execSync( + `npx esbuild scripts/download-ripgrep.ts --bundle --platform=node --outfile=${outdir}/download-ripgrep.js --format=esm`, + { stdio: "inherit" }, + ); + console.log(`Bundled download-ripgrep script via esbuild to ${outdir}/`); + } catch { + console.warn( + "Failed to bundle download-ripgrep script — skipping (non-fatal)", + ); + } + } + + // Step 4: Generate dual entry points + const cliBun = join(outdir, "cli-bun.js"); + const cliNode = join(outdir, "cli-node.js"); + + await writeFile(cliBun, '#!/usr/bin/env bun\nimport "./cli.js"\n'); + await writeFile(cliNode, '#!/usr/bin/env node\nimport "./cli.js"\n'); + + chmodSync(cliBun, 0o755); + chmodSync(cliNode, 0o755); + + console.log( + `Post-build complete: patched ${bunPatched} Bun destructure, generated entry points`, + ); +} + +postBuild().catch((err) => { + console.error("Post-build failed:", err); + process.exit(1); +}); diff --git a/scripts/vite-plugin-feature-flags.ts b/scripts/vite-plugin-feature-flags.ts new file mode 100644 index 000000000..3769a57de --- /dev/null +++ b/scripts/vite-plugin-feature-flags.ts @@ -0,0 +1,118 @@ +import type { Plugin } from "rollup"; + +/** + * Default features that match the official CLI build. + * Additional features can be enabled via FEATURE_=1 env vars. + */ +const DEFAULT_BUILD_FEATURES = [ + "AGENT_TRIGGERS_REMOTE", + "CHICAGO_MCP", + "VOICE_MODE", + "SHOT_STATS", + "PROMPT_CACHE_BREAK_DETECTION", + "TOKEN_BUDGET", + // P0: local features + "AGENT_TRIGGERS", + "ULTRATHINK", + "BUILTIN_EXPLORE_PLAN_AGENTS", + "LODESTONE", + // P1: API-dependent features + "EXTRACT_MEMORIES", + "VERIFICATION_AGENT", + "KAIROS_BRIEF", + "AWAY_SUMMARY", + "ULTRAPLAN", + // P2: daemon + remote control server + "DAEMON", + // PR-package restored features + "WORKFLOW_SCRIPTS", + "HISTORY_SNIP", + "CONTEXT_COLLAPSE", + "MONITOR_TOOL", + "FORK_SUBAGENT", + "KAIROS", + "COORDINATOR_MODE", + "LAN_PIPES", + // P3: poor mode + "POOR", +]; + +/** + * Collect enabled feature flags from defaults + env vars. + */ +export function getEnabledFeatures(): Set { + const envFeatures = Object.keys(process.env) + .filter((k) => k.startsWith("FEATURE_")) + .map((k) => k.replace("FEATURE_", "")); + return new Set([...DEFAULT_BUILD_FEATURES, ...envFeatures]); +} + +// Regex to match feature('FLAG_NAME') calls with string literal arguments +const FEATURE_CALL_RE = /feature\s*\(\s*['"]([\w]+)['"]\s*\)/g; + +/** + * Vite/Rollup plugin that replaces `feature('X')` calls with boolean literals + * at the transform stage, BEFORE the bundler resolves imports. + * + * This approach is necessary because some feature-gated code blocks contain + * require() calls to files that don't exist (e.g. hunter.js inside + * feature('REVIEW_ARTIFACT')). The bundler must see these as dead code + * (`if (false) { ... }`) before attempting import resolution. + * + * Also resolves `import { feature } from 'bun:bundle'` as a virtual module + * to prevent "module not found" errors. + */ +export default function featureFlagsPlugin(): Plugin { + const features = getEnabledFeatures(); + + const virtualModuleId = "bun:bundle"; + const resolvedVirtualModuleId = "\0" + virtualModuleId; + + return { + name: "feature-flags", + + // Resolve bun:bundle as a virtual module (prevents "module not found") + resolveId(id) { + if (id === virtualModuleId) { + return resolvedVirtualModuleId; + } + }, + + // Provide a stub export for bun:bundle (unused at runtime after transform) + load(id) { + if (id === resolvedVirtualModuleId) { + return "export function feature(name) { return false; }"; + } + }, + + // Replace feature('X') calls with true/false literals at transform time, + // and transpile `using` declarations for Node.js compatibility. + transform(code, id) { + // Skip node_modules + if (id.includes("node_modules")) return null; + + let modified = false; + + // 1. Replace feature('X') calls with boolean literals + let matchCount = 0; + let transformed = code.replace(FEATURE_CALL_RE, (match, flagName) => { + matchCount++; + return features.has(flagName) ? "true" : "false"; + }); + if (matchCount > 0) modified = true; + + // 2. Transpile `using _ = expr;` to `const _ = expr;` for Node.js compat. + // Node.js v22 does not support `using` declarations (Explicit Resource Management). + // Safe because: SLOW_OPERATION_LOGGING is not enabled, so slowLogging returns + // a no-op disposable whose [Symbol.dispose]() is empty. + if (transformed.includes("using _")) { + transformed = transformed.replace(/\busing\s+(_\w*)\s*=/g, "const $1 ="); + modified = true; + } + + if (!modified) return null; + + return { code: transformed, map: null }; + }, + }; +} diff --git a/scripts/vite-plugin-import-meta-require.ts b/scripts/vite-plugin-import-meta-require.ts new file mode 100644 index 000000000..d05033c9b --- /dev/null +++ b/scripts/vite-plugin-import-meta-require.ts @@ -0,0 +1,25 @@ +import type { Plugin } from "rollup"; + +/** + * Rollup plugin that replaces `var __require = import.meta.require;` + * with a Node.js compatible version that falls back to createRequire + * when import.meta.require is not available (e.g. in Node.js runtime). + * + * This replicates the post-processing done in the original build.ts. + */ +export default function importMetaRequirePlugin(): Plugin { + return { + name: "import-meta-require", + + renderChunk(code) { + const pattern = "var __require = import.meta.require;"; + const replacement = + 'var __require = typeof import.meta.require === "function" ? import.meta.require : (await import("module")).createRequire(import.meta.url);'; + + if (code.includes(pattern)) { + return code.replace(pattern, replacement); + } + return null; + }, + }; +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 000000000..0aef1a91e --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,100 @@ +import { defineConfig, type Plugin } from "vite"; +import { resolve, dirname } from "path"; +import { readFileSync } from "fs"; +import { getMacroDefines } from "./scripts/defines"; +import featureFlagsPlugin from "./scripts/vite-plugin-feature-flags"; +import importMetaRequirePlugin from "./scripts/vite-plugin-import-meta-require"; + +const projectRoot = dirname(new URL(import.meta.url).pathname); + +/** + * Plugin to import .md files as raw strings (Bun's text loader behavior). + */ +function rawAssetPlugin(extensions: string[]): Plugin { + return { + name: "raw-asset", + enforce: "pre", + resolveId(id, importer) { + if (extensions.some((ext) => id.endsWith(ext))) { + // Resolve to actual file path + return this.resolve(id, importer, { skipSelf: true }); + } + return null; + }, + load(id) { + if (extensions.some((ext) => id.endsWith(ext))) { + const content = readFileSync(id, "utf-8"); + return `export default ${JSON.stringify(content)}`; + } + return null; + }, + }; +} + +export default defineConfig({ + // CLI tool — no browser features needed + appType: "custom", + + // Tell Vite this is a Node.js build, not browser. + // Prevents externalization of Node.js builtins (fs, path, etc.) + ssr: { + target: "node", + noExternal: true, + }, + + build: { + emptyOutDir: true, + outDir: "dist", + target: "esnext", + copyPublicDir: false, + sourcemap: false, + minify: false, + + // SSR build mode — uses Rollup with Node.js target + ssr: true, + + rollupOptions: { + input: resolve(projectRoot, "src/entrypoints/cli.tsx"), + + output: { + format: "es", + dir: "dist", + entryFileNames: "cli.js", + chunkFileNames: "chunks/[name]-[hash].js", + }, + + // Externalize native addon packages (they contain .node binaries) + external: [ + /audio-capture-napi/, + /color-diff-napi/, + /image-processor-napi/, + /modifiers-napi/, + /url-handler-napi/, + ], + + plugins: [ + rawAssetPlugin([".md", ".txt", ".html", ".css"]), + featureFlagsPlugin(), + importMetaRequirePlugin(), + ], + }, + + cssCodeSplit: false, + }, + + // Compile-time constant replacement (MACRO.* defines) + define: { + ...getMacroDefines(), + }, + + resolve: { + alias: { + // src/* path alias (mirrors tsconfig paths) + "src/": resolve(projectRoot, "src/"), + }, + // Ensure workspace packages share a single copy of these + dedupe: ["react", "react-reconciler", "react-compiler-runtime"], + // Resolve .js imports to .ts files (Bun does this automatically) + extensions: [".ts", ".tsx", ".js", ".jsx", ".json"], + }, +});