mirror of
https://github.com/block/goose.git
synced 2026-07-17 12:56:20 +02:00
trying ngrok instead
This commit is contained in:
Generated
+243
-173
@@ -12,6 +12,7 @@
|
||||
"@ai-sdk/openai": "^2.0.14",
|
||||
"@ai-sdk/ui-utils": "^1.2.11",
|
||||
"@mcp-ui/client": "^5.9.0",
|
||||
"@ngrok/ngrok": "^1.5.2",
|
||||
"@radix-ui/react-accordion": "^1.2.12",
|
||||
"@radix-ui/react-avatar": "^1.1.10",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
@@ -39,7 +40,6 @@
|
||||
"electron-window-state": "^5.0.3",
|
||||
"express": "^5.1.0",
|
||||
"gsap": "^3.13.0",
|
||||
"localtunnel": "^2.0.2",
|
||||
"lodash": "^4.17.21",
|
||||
"lucide-react": "^0.539.0",
|
||||
"qrcode": "^1.5.4",
|
||||
@@ -87,6 +87,7 @@
|
||||
"@types/electron-squirrel-startup": "^1.0.2",
|
||||
"@types/express": "^5.0.3",
|
||||
"@types/lodash": "^4.17.20",
|
||||
"@types/qrcode": "^1.5.5",
|
||||
"@types/react": "^19.1.10",
|
||||
"@types/react-dom": "^19.1.7",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
@@ -2689,6 +2690,235 @@
|
||||
"@tybys/wasm-util": "^0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrok/ngrok": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@ngrok/ngrok/-/ngrok-1.5.2.tgz",
|
||||
"integrity": "sha512-gN7KKdLTKer+wBSk9s9eDx53MUFdcnXNHsXxiC5sJLLD5HY9JRMSn6UzcCqnk7IgeIgCgw5h1k6YDqhjx6lmtg==",
|
||||
"license": "(MIT OR Apache-2.0)",
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@ngrok/ngrok-android-arm64": "1.5.2",
|
||||
"@ngrok/ngrok-darwin-arm64": "1.5.2",
|
||||
"@ngrok/ngrok-darwin-universal": "1.5.2",
|
||||
"@ngrok/ngrok-darwin-x64": "1.5.2",
|
||||
"@ngrok/ngrok-freebsd-x64": "1.5.2",
|
||||
"@ngrok/ngrok-linux-arm-gnueabihf": "1.5.2",
|
||||
"@ngrok/ngrok-linux-arm64-gnu": "1.5.2",
|
||||
"@ngrok/ngrok-linux-arm64-musl": "1.5.2",
|
||||
"@ngrok/ngrok-linux-x64-gnu": "1.5.2",
|
||||
"@ngrok/ngrok-linux-x64-musl": "1.5.2",
|
||||
"@ngrok/ngrok-win32-arm64-msvc": "1.5.2",
|
||||
"@ngrok/ngrok-win32-ia32-msvc": "1.5.2",
|
||||
"@ngrok/ngrok-win32-x64-msvc": "1.5.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrok/ngrok-android-arm64": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@ngrok/ngrok-android-arm64/-/ngrok-android-arm64-1.5.2.tgz",
|
||||
"integrity": "sha512-v81VbxxAgg2W7jbjhEcn8K9R2aUf0h1AuTx+8tDlw3L4H1YEmbmllIpBAGgMjHRBxLZKOo5GBi0k7oS+VRM5TA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrok/ngrok-darwin-arm64": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@ngrok/ngrok-darwin-arm64/-/ngrok-darwin-arm64-1.5.2.tgz",
|
||||
"integrity": "sha512-8CVzS9AveYpNhWbydm7cJ6XqmVg29/VRKF15l4kJ2djlNoJxuGSibgM9A627dWRdnJyj5uhmU3VzsgeU8t+/3g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrok/ngrok-darwin-universal": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@ngrok/ngrok-darwin-universal/-/ngrok-darwin-universal-1.5.2.tgz",
|
||||
"integrity": "sha512-mEMH1OxN6RxnqRSWb4xY9RqbtdlCpv+WlRKxq4lVy8JVsxEyFNnzVQ0jn+iuiy981jCXjokctzJeGMvECuSQBQ==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrok/ngrok-darwin-x64": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@ngrok/ngrok-darwin-x64/-/ngrok-darwin-x64-1.5.2.tgz",
|
||||
"integrity": "sha512-rGdcADw4NtMSU7SHUTly7uvMVYX6eMeMCppKyL5g3CSlEQntKf3AWs/89ah2TBWJA2WVl0UgGLkXp4xs1tg9eQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrok/ngrok-freebsd-x64": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@ngrok/ngrok-freebsd-x64/-/ngrok-freebsd-x64-1.5.2.tgz",
|
||||
"integrity": "sha512-WgY54qUekaUGa5+lFvzYUMjlzf22IEXuZHhxnzJM2/gMqa7gjU8N5W4U8XNDjVW/oz6DekrzIjuoAEPO+2icDg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrok/ngrok-linux-arm-gnueabihf": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@ngrok/ngrok-linux-arm-gnueabihf/-/ngrok-linux-arm-gnueabihf-1.5.2.tgz",
|
||||
"integrity": "sha512-azMxr/TGEeFU4JAUbSu5MO2aZEvdq+TzcxiLw6d+yhdEtNAjDW9TOyCczTrIZPOG5fP8G3lcCd8TP7mVIWdOnw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrok/ngrok-linux-arm64-gnu": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@ngrok/ngrok-linux-arm64-gnu/-/ngrok-linux-arm64-gnu-1.5.2.tgz",
|
||||
"integrity": "sha512-79eFCxio4rM0ICRBXx/CVvbXDeWk1Jxr7szkezEYWtHaL+gXivrtS1QjtMnJpGY1GJlLTQL+49w2lGydqPOJQA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrok/ngrok-linux-arm64-musl": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@ngrok/ngrok-linux-arm64-musl/-/ngrok-linux-arm64-musl-1.5.2.tgz",
|
||||
"integrity": "sha512-ou9Z7iPQJIQ0RX5bdBhb3y7GwYRt+X0G9tenyRzKLXXvs0XfUUcg/23aBP61hmdRvBq7xpliV1PnvEVBgUIYMg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrok/ngrok-linux-x64-gnu": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@ngrok/ngrok-linux-x64-gnu/-/ngrok-linux-x64-gnu-1.5.2.tgz",
|
||||
"integrity": "sha512-VI1mmtl3Ie5uXTVAR9thPiMNMsCWeqkjBUbHAyk2vZ2OXR4Vs2DGjOPXK+wTl/hjF29FXoxunjhMy6caF9ht0Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrok/ngrok-linux-x64-musl": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@ngrok/ngrok-linux-x64-musl/-/ngrok-linux-x64-musl-1.5.2.tgz",
|
||||
"integrity": "sha512-F4j9EyC/0R3IgYSd+OER4bC8bxuBubvj33e24GvQnRF/IQaKhpybkvQbz54fnvsL7y0j2BB42NAIm2CFtk7tCw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrok/ngrok-win32-arm64-msvc": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@ngrok/ngrok-win32-arm64-msvc/-/ngrok-win32-arm64-msvc-1.5.2.tgz",
|
||||
"integrity": "sha512-0OMXNjWElM1MQX7lMBnpRtafS9+3ybauqGD4m2dZcIm6hFvexsJFwNgx0mCa5aKxe2mQ4zNarEUd+SqG2Aa4/g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrok/ngrok-win32-ia32-msvc": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@ngrok/ngrok-win32-ia32-msvc/-/ngrok-win32-ia32-msvc-1.5.2.tgz",
|
||||
"integrity": "sha512-hdvhnr7Br4XhUblpW67v5XP6FyoQwJ2xSbwas4KW4hZ3F4cw0m6sqXpssRfmqg3/5HJony1H5B2jLi0x4J7uOw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngrok/ngrok-win32-x64-msvc": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@ngrok/ngrok-win32-x64-msvc/-/ngrok-win32-x64-msvc-1.5.2.tgz",
|
||||
"integrity": "sha512-aHuMiRti9Taow9DlYLGVmu9CXtXD/v4CBQWpZlmt7VGuK1KsTWWLaGIBFVp6UXnyW87b0A+KC69Kn/Xjylw+sg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
@@ -5928,6 +6158,16 @@
|
||||
"integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/qrcode": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.5.5.tgz",
|
||||
"integrity": "sha512-CdfBi/e3Qk+3Z/fXYShipBT13OJ2fDO2Q2w5CIP5anLTLIndQG9z6P1cnm+8zCWSpm5dnxMFd/uREtb0EXuQzg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/qs": {
|
||||
"version": "6.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
|
||||
@@ -6962,15 +7202,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "0.21.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
|
||||
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-macros": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
|
||||
@@ -9539,6 +9770,7 @@
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
@@ -10336,26 +10568,6 @@
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.11",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
|
||||
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/for-each": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
|
||||
@@ -13004,143 +13216,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/localtunnel": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-2.0.2.tgz",
|
||||
"integrity": "sha512-n418Cn5ynvJd7m/N1d9WVJISLJF/ellZnfsLnx8WBWGzxv/ntNcFkJ1o6se5quUhCplfLGBNL5tYHiq5WF3Nug==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"axios": "0.21.4",
|
||||
"debug": "4.3.2",
|
||||
"openurl": "1.1.1",
|
||||
"yargs": "17.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"lt": "bin/lt.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/localtunnel/node_modules/cliui": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
||||
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/localtunnel/node_modules/debug": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
|
||||
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/localtunnel/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/localtunnel/node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/localtunnel/node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/localtunnel/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/localtunnel/node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/localtunnel/node_modules/wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/localtunnel/node_modules/yargs": {
|
||||
"version": "17.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.1.1.tgz",
|
||||
"integrity": "sha512-c2k48R0PwKIqKhPMWjeiF6y2xY/gPMUlro0sgxqXpbOIohWiLNXWslsootttv7E1e73QPAMQSg5FeySbVcpsPQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cliui": "^7.0.2",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.0",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^20.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/localtunnel/node_modules/yargs-parser": {
|
||||
"version": "20.2.9",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
|
||||
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/locate-path": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
||||
@@ -15117,12 +15192,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/openurl": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz",
|
||||
"integrity": "sha512-d/gTkTb1i1GKz5k3XE3XFV/PxQ1k45zDqGP2OA7YhgsaLoqm6qRvARAZOFer1fcXritWlGBRCu/UgeS4HAnXAA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/optionator": {
|
||||
"version": "0.9.4",
|
||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
|
||||
@@ -19785,6 +19854,7 @@
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
"@ai-sdk/openai": "^2.0.14",
|
||||
"@ai-sdk/ui-utils": "^1.2.11",
|
||||
"@mcp-ui/client": "^5.9.0",
|
||||
"@ngrok/ngrok": "^1.5.2",
|
||||
"@radix-ui/react-accordion": "^1.2.12",
|
||||
"@radix-ui/react-avatar": "^1.1.10",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
@@ -69,7 +70,6 @@
|
||||
"electron-window-state": "^5.0.3",
|
||||
"express": "^5.1.0",
|
||||
"gsap": "^3.13.0",
|
||||
"localtunnel": "^2.0.2",
|
||||
"lodash": "^4.17.21",
|
||||
"lucide-react": "^0.539.0",
|
||||
"qrcode": "^1.5.4",
|
||||
@@ -117,6 +117,7 @@
|
||||
"@types/electron-squirrel-startup": "^1.0.2",
|
||||
"@types/express": "^5.0.3",
|
||||
"@types/lodash": "^4.17.20",
|
||||
"@types/qrcode": "^1.5.5",
|
||||
"@types/react": "^19.1.10",
|
||||
"@types/react-dom": "^19.1.7",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
|
||||
@@ -2192,9 +2192,10 @@ async function appMain() {
|
||||
});
|
||||
|
||||
// Tunnel IPC handlers
|
||||
ipcMain.handle('tunnel-start', async (_event, port: number, secret?: string) => {
|
||||
ipcMain.handle('tunnel-start', async (_event, port: number) => {
|
||||
try {
|
||||
const tunnelInfo = await startTunnel(port, secret);
|
||||
// Use the same secret that goosed was launched with
|
||||
const tunnelInfo = await startTunnel(port, SERVER_SECRET);
|
||||
log.info('Tunnel started:', tunnelInfo.url);
|
||||
|
||||
// Open QR code image
|
||||
@@ -2209,9 +2210,9 @@ async function appMain() {
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('tunnel-stop', () => {
|
||||
ipcMain.handle('tunnel-stop', async () => {
|
||||
try {
|
||||
stopTunnel();
|
||||
await stopTunnel();
|
||||
log.info('Tunnel stopped');
|
||||
return true;
|
||||
} catch (error) {
|
||||
|
||||
@@ -115,7 +115,7 @@ type ElectronAPI = {
|
||||
recordRecipeHash: (recipeConfig: Recipe) => Promise<boolean>;
|
||||
openDirectoryInExplorer: (directoryPath: string) => Promise<boolean>;
|
||||
// Tunnel functions
|
||||
tunnelStart: (port: number, secret?: string) => Promise<any>;
|
||||
tunnelStart: (port: number) => Promise<any>;
|
||||
tunnelStop: () => Promise<boolean>;
|
||||
tunnelStatus: () => Promise<any>;
|
||||
tunnelShowQr: () => Promise<boolean>;
|
||||
@@ -243,7 +243,7 @@ const electronAPI: ElectronAPI = {
|
||||
ipcRenderer.invoke('record-recipe-hash', recipeConfig),
|
||||
openDirectoryInExplorer: (directoryPath: string) =>
|
||||
ipcRenderer.invoke('open-directory-in-explorer', directoryPath),
|
||||
tunnelStart: (port: number, secret?: string) => ipcRenderer.invoke('tunnel-start', port, secret),
|
||||
tunnelStart: (port: number) => ipcRenderer.invoke('tunnel-start', port),
|
||||
tunnelStop: () => ipcRenderer.invoke('tunnel-stop'),
|
||||
tunnelStatus: () => ipcRenderer.invoke('tunnel-status'),
|
||||
tunnelShowQr: () => ipcRenderer.invoke('tunnel-show-qr'),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { spawn, ChildProcess } from 'child_process';
|
||||
import * as ngrok from '@ngrok/ngrok';
|
||||
import * as QRCode from 'qrcode';
|
||||
import * as crypto from 'crypto';
|
||||
import { Buffer } from 'node:buffer';
|
||||
@@ -24,7 +24,7 @@ export interface TunnelConnectionInfo {
|
||||
}
|
||||
|
||||
export class TunnelManager {
|
||||
private tunnelProcess: ChildProcess | null = null;
|
||||
private ngrokListener: any | null = null;
|
||||
private config: TunnelConfig | null = null;
|
||||
private isStarting = false;
|
||||
private tunnelUrl: string | null = null;
|
||||
@@ -32,10 +32,10 @@ export class TunnelManager {
|
||||
constructor() {}
|
||||
|
||||
/**
|
||||
* Start a localtunnel for the given port with a secret
|
||||
* Start an ngrok tunnel for the given port with a secret
|
||||
*/
|
||||
async start(port: number, secret?: string): Promise<TunnelConnectionInfo> {
|
||||
if (this.tunnelProcess) {
|
||||
async start(port: number, secret: string): Promise<TunnelConnectionInfo> {
|
||||
if (this.ngrokListener) {
|
||||
throw new Error('Tunnel is already running');
|
||||
}
|
||||
|
||||
@@ -46,17 +46,17 @@ export class TunnelManager {
|
||||
this.isStarting = true;
|
||||
|
||||
try {
|
||||
// Generate secret if not provided
|
||||
const tunnelSecret = secret || crypto.randomBytes(24).toString('base64');
|
||||
// Use the provided secret (from goosed)
|
||||
const tunnelSecret = secret;
|
||||
|
||||
this.config = {
|
||||
port,
|
||||
secret: tunnelSecret,
|
||||
};
|
||||
|
||||
// Start localtunnel
|
||||
log.info(`Starting localtunnel on port ${port}`);
|
||||
this.tunnelUrl = await this.startLocaltunnel(port);
|
||||
// Start ngrok tunnel
|
||||
log.info(`Starting ngrok tunnel on port ${port}`);
|
||||
this.tunnelUrl = await this.startNgrokTunnel(port);
|
||||
|
||||
if (!this.tunnelUrl) {
|
||||
throw new Error('Failed to get tunnel URL');
|
||||
@@ -106,68 +106,38 @@ export class TunnelManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Start localtunnel process and capture the URL
|
||||
* Start ngrok tunnel and return the URL
|
||||
*/
|
||||
private startLocaltunnel(port: number): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const lt = spawn('npx', ['localtunnel', '--port', port.toString()], {
|
||||
shell: true,
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
private async startNgrokTunnel(port: number): Promise<string> {
|
||||
try {
|
||||
// Get ngrok auth token from environment
|
||||
const authToken = process.env.NGROK_AUTHTOKEN;
|
||||
if (authToken) {
|
||||
await ngrok.authtoken(authToken);
|
||||
}
|
||||
|
||||
// Connect to ngrok with the specified port
|
||||
this.ngrokListener = await ngrok.forward({
|
||||
addr: port,
|
||||
authtoken: authToken,
|
||||
});
|
||||
|
||||
this.tunnelProcess = lt;
|
||||
// Get the URL from the listener
|
||||
const url = this.ngrokListener.url();
|
||||
|
||||
let output = '';
|
||||
let errorOutput = '';
|
||||
let urlFound = false;
|
||||
const timeout = setTimeout(() => {
|
||||
if (!urlFound) {
|
||||
this.stop();
|
||||
reject(new Error('Timeout waiting for tunnel URL'));
|
||||
}
|
||||
}, 30000); // 30 second timeout
|
||||
if (!url) {
|
||||
throw new Error('Failed to get ngrok URL');
|
||||
}
|
||||
|
||||
lt.stdout?.on('data', (data) => {
|
||||
const text = data.toString();
|
||||
output += text;
|
||||
log.info('localtunnel stdout:', text);
|
||||
this.tunnelUrl = url;
|
||||
log.info(`Ngrok tunnel established: ${url}`);
|
||||
|
||||
// Look for the URL in the output
|
||||
const urlMatch = text.match(/your url is: (https:\/\/.*\.loca\.lt)/);
|
||||
if (urlMatch && !urlFound) {
|
||||
urlFound = true;
|
||||
clearTimeout(timeout);
|
||||
this.tunnelUrl = urlMatch[1];
|
||||
resolve(urlMatch[1]);
|
||||
}
|
||||
});
|
||||
|
||||
lt.stderr?.on('data', (data) => {
|
||||
errorOutput += data.toString();
|
||||
log.error('localtunnel stderr:', data.toString());
|
||||
});
|
||||
|
||||
lt.on('error', (error) => {
|
||||
clearTimeout(timeout);
|
||||
log.error('Failed to start localtunnel:', error);
|
||||
this.tunnelProcess = null;
|
||||
reject(error);
|
||||
});
|
||||
|
||||
lt.on('close', (code) => {
|
||||
clearTimeout(timeout);
|
||||
log.info(`localtunnel process exited with code ${code}`);
|
||||
this.tunnelProcess = null;
|
||||
|
||||
if (!urlFound) {
|
||||
reject(
|
||||
new Error(
|
||||
`Localtunnel exited without providing URL. Output: ${output}, Error: ${errorOutput}`
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
return url;
|
||||
} catch (error) {
|
||||
log.error('Failed to start ngrok tunnel:', error);
|
||||
this.ngrokListener = null;
|
||||
throw new Error(`Failed to start ngrok tunnel: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,15 +191,15 @@ export class TunnelManager {
|
||||
/**
|
||||
* Stop the tunnel
|
||||
*/
|
||||
stop(): void {
|
||||
if (this.tunnelProcess) {
|
||||
log.info('Stopping localtunnel');
|
||||
async stop(): Promise<void> {
|
||||
if (this.ngrokListener) {
|
||||
log.info('Stopping ngrok tunnel');
|
||||
try {
|
||||
this.tunnelProcess.kill();
|
||||
await this.ngrokListener.close();
|
||||
} catch (error) {
|
||||
log.error('Error stopping tunnel:', error);
|
||||
log.error('Error stopping ngrok tunnel:', error);
|
||||
}
|
||||
this.tunnelProcess = null;
|
||||
this.ngrokListener = null;
|
||||
}
|
||||
|
||||
this.config = null;
|
||||
@@ -240,7 +210,7 @@ export class TunnelManager {
|
||||
* Get current tunnel status
|
||||
*/
|
||||
isRunning(): boolean {
|
||||
return this.tunnelProcess !== null;
|
||||
return this.ngrokListener !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -288,7 +258,7 @@ export function getTunnelManager(): TunnelManager {
|
||||
/**
|
||||
* Start a tunnel for the given port
|
||||
*/
|
||||
export async function startTunnel(port: number, secret?: string): Promise<TunnelConnectionInfo> {
|
||||
export async function startTunnel(port: number, secret: string): Promise<TunnelConnectionInfo> {
|
||||
const manager = getTunnelManager();
|
||||
return manager.start(port, secret);
|
||||
}
|
||||
@@ -296,9 +266,9 @@ export async function startTunnel(port: number, secret?: string): Promise<Tunnel
|
||||
/**
|
||||
* Stop the current tunnel
|
||||
*/
|
||||
export function stopTunnel(): void {
|
||||
export async function stopTunnel(): Promise<void> {
|
||||
const manager = getTunnelManager();
|
||||
manager.stop();
|
||||
await manager.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -322,6 +292,6 @@ export function getTunnelConfig(): TunnelConfig | null {
|
||||
*/
|
||||
export async function cleanupTunnel(): Promise<void> {
|
||||
const manager = getTunnelManager();
|
||||
manager.stop();
|
||||
await manager.stop();
|
||||
await manager.cleanupQRCodes();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { defineConfig } from 'vite';
|
||||
export default defineConfig({
|
||||
build: {
|
||||
rollupOptions: {
|
||||
external: ['qrcode', 'localtunnel'],
|
||||
external: ['qrcode', '@ngrok/ngrok'],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user